summaryrefslogtreecommitdiff
path: root/graphics/asymptote
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/asymptote
Initial commit
Diffstat (limited to 'graphics/asymptote')
-rw-r--r--graphics/asymptote/BUGS6
-rw-r--r--graphics/asymptote/ChangeLog44327
-rw-r--r--graphics/asymptote/Delaunay.cc212
-rw-r--r--graphics/asymptote/Delaunay.h29
-rwxr-xr-xgraphics/asymptote/EnvVarUpdate.nsh327
-rw-r--r--graphics/asymptote/GL/glew.c28581
-rw-r--r--graphics/asymptote/GL/glew.h23686
-rw-r--r--graphics/asymptote/GL/glxew.h1775
-rw-r--r--graphics/asymptote/GL/wglew.h1447
-rw-r--r--graphics/asymptote/GUI/CustMatTransform.py102
-rw-r--r--graphics/asymptote/GUI/DebugFlags.py6
-rw-r--r--graphics/asymptote/GUI/GuidesManager.py52
-rw-r--r--graphics/asymptote/GUI/InplaceAddObj.py356
-rw-r--r--graphics/asymptote/GUI/PrimitiveShape.py66
-rw-r--r--graphics/asymptote/GUI/SetCustomAnchor.py44
-rwxr-xr-xgraphics/asymptote/GUI/UndoRedoStack.py132
-rw-r--r--graphics/asymptote/GUI/Widg_addLabel.py96
-rw-r--r--graphics/asymptote/GUI/Widg_addPolyOpt.py31
-rw-r--r--graphics/asymptote/GUI/Widg_editBezier.py53
-rw-r--r--graphics/asymptote/GUI/Window1.py1900
-rw-r--r--graphics/asymptote/GUI/__init__.py1
-rw-r--r--graphics/asymptote/GUI/configs/__init__.py1
-rw-r--r--graphics/asymptote/GUI/configs/xasyconfig.cson62
-rw-r--r--graphics/asymptote/GUI/configs/xasykeymap.cson24
-rw-r--r--graphics/asymptote/GUI/icon-list.txt1
-rw-r--r--graphics/asymptote/GUI/icons_rc.py2680
-rw-r--r--graphics/asymptote/GUI/labelEditor.py154
-rw-r--r--graphics/asymptote/GUI/locale/th/LC_MESSAGES/base.po24
-rw-r--r--graphics/asymptote/GUI/pyUIClass/custMatTransform.py173
-rw-r--r--graphics/asymptote/GUI/pyUIClass/labelTextEditor.py119
-rw-r--r--graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py55
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widg_addLabel.py140
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py48
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widg_editBezier.py94
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py96
-rw-r--r--graphics/asymptote/GUI/pyUIClass/window1.py930
-rw-r--r--graphics/asymptote/GUI/requirements.txt4
-rw-r--r--graphics/asymptote/GUI/res/icons.qrc45
-rw-r--r--graphics/asymptote/GUI/res/icons/anchor.svg1
-rw-r--r--graphics/asymptote/GUI/res/icons/android-arrow-back.svg11
-rw-r--r--graphics/asymptote/GUI/res/icons/android-arrow-forward.svg11
-rw-r--r--graphics/asymptote/GUI/res/icons/android-camera.svg12
-rw-r--r--graphics/asymptote/GUI/res/icons/android-close.svg12
-rw-r--r--graphics/asymptote/GUI/res/icons/android-color-palette.svg17
-rw-r--r--graphics/asymptote/GUI/res/icons/android-delete.svg10
-rw-r--r--graphics/asymptote/GUI/res/icons/android-done.svg13
-rw-r--r--graphics/asymptote/GUI/res/icons/android-expand.svg12
-rw-r--r--graphics/asymptote/GUI/res/icons/android-folder-open.svg10
-rw-r--r--graphics/asymptote/GUI/res/icons/android-hand.svg15
-rw-r--r--graphics/asymptote/GUI/res/icons/android-locate.svg16
-rw-r--r--graphics/asymptote/GUI/res/icons/android-radio-button-off.svg12
-rw-r--r--graphics/asymptote/GUI/res/icons/android-radio-button-on.svg13
-rw-r--r--graphics/asymptote/GUI/res/icons/android-refresh.svg11
-rw-r--r--graphics/asymptote/GUI/res/icons/arrow-move.svg8
-rw-r--r--graphics/asymptote/GUI/res/icons/arrow-resize.svg8
-rw-r--r--graphics/asymptote/GUI/res/icons/bucket.asy28
-rw-r--r--graphics/asymptote/GUI/res/icons/bucket.svg14
-rw-r--r--graphics/asymptote/GUI/res/icons/center.asy9
-rw-r--r--graphics/asymptote/GUI/res/icons/center.svg11
-rw-r--r--graphics/asymptote/GUI/res/icons/centerorigin.asy7
-rw-r--r--graphics/asymptote/GUI/res/icons/centerorigin.svg14
-rw-r--r--graphics/asymptote/GUI/res/icons/check.svg9
-rw-r--r--graphics/asymptote/GUI/res/icons/chevron-with-circle-left.svg11
-rw-r--r--graphics/asymptote/GUI/res/icons/chevron-with-circle-right.svg11
-rw-r--r--graphics/asymptote/GUI/res/icons/circle.svg9
-rw-r--r--graphics/asymptote/GUI/res/icons/close-round.svg9
-rw-r--r--graphics/asymptote/GUI/res/icons/closedcurve.asy7
-rw-r--r--graphics/asymptote/GUI/res/icons/closedcurve.svg20
-rw-r--r--graphics/asymptote/GUI/res/icons/closedpolygon.asy7
-rw-r--r--graphics/asymptote/GUI/res/icons/closedpolygon.svg20
-rw-r--r--graphics/asymptote/GUI/res/icons/code.svg13
-rw-r--r--graphics/asymptote/GUI/res/icons/edit.svg13
-rw-r--r--graphics/asymptote/GUI/res/icons/eye.svg15
-rw-r--r--graphics/asymptote/GUI/res/icons/filledbucket.svg17
-rw-r--r--graphics/asymptote/GUI/res/icons/grid.svg32
-rw-r--r--graphics/asymptote/GUI/res/icons/magnifying-glass.svg11
-rw-r--r--graphics/asymptote/GUI/res/icons/opencurve.asy7
-rw-r--r--graphics/asymptote/GUI/res/icons/opencurve.svg20
-rw-r--r--graphics/asymptote/GUI/res/icons/openpolygon.asy7
-rw-r--r--graphics/asymptote/GUI/res/icons/openpolygon.svg20
-rw-r--r--graphics/asymptote/GUI/res/icons/plus-round.svg9
-rw-r--r--graphics/asymptote/GUI/res/icons/save.svg8
-rw-r--r--graphics/asymptote/GUI/res/icons/social-python.svg21
-rw-r--r--graphics/asymptote/GUI/res/icons/subdirectory-left.svg1
-rw-r--r--graphics/asymptote/GUI/res/icons/text.svg3
-rw-r--r--graphics/asymptote/GUI/res/icons/triangle-stroked-15.svg12
-rw-r--r--graphics/asymptote/GUI/setup.py13
-rw-r--r--graphics/asymptote/GUI/windows/custMatTransform.ui356
-rw-r--r--graphics/asymptote/GUI/windows/labelTextEditor.ui230
-rw-r--r--graphics/asymptote/GUI/windows/setCustomAnchor.ui109
-rw-r--r--graphics/asymptote/GUI/windows/widg_addLabel.ui287
-rw-r--r--graphics/asymptote/GUI/windows/widg_addPolyOpt.ui91
-rw-r--r--graphics/asymptote/GUI/windows/widg_editBezier.ui170
-rw-r--r--graphics/asymptote/GUI/windows/widgetPointEditor.ui150
-rw-r--r--graphics/asymptote/GUI/windows/window1.ui2000
-rwxr-xr-xgraphics/asymptote/GUI/xasy.py16
-rwxr-xr-xgraphics/asymptote/GUI/xasy2asy.py1407
-rw-r--r--graphics/asymptote/GUI/xasyArgs.py23
-rw-r--r--graphics/asymptote/GUI/xasyBezierInterface.py375
-rwxr-xr-xgraphics/asymptote/GUI/xasyFile.py83
-rwxr-xr-xgraphics/asymptote/GUI/xasyOptions.py159
-rw-r--r--graphics/asymptote/GUI/xasyStrings.py23
-rw-r--r--graphics/asymptote/GUI/xasySvg.py22
-rw-r--r--graphics/asymptote/GUI/xasyTransform.py24
-rw-r--r--graphics/asymptote/GUI/xasyUtils.py50
-rw-r--r--graphics/asymptote/GUI/xasyValidator.py13
-rw-r--r--graphics/asymptote/INSTALL275
-rw-r--r--graphics/asymptote/LICENSE674
-rw-r--r--graphics/asymptote/LICENSE.LESSER165
-rw-r--r--graphics/asymptote/Makefile.in383
-rw-r--r--graphics/asymptote/Pipfile11
-rw-r--r--graphics/asymptote/README66
-rw-r--r--graphics/asymptote/ReleaseNotes2114
-rw-r--r--graphics/asymptote/TODO37
-rw-r--r--graphics/asymptote/absyn.cc30
-rw-r--r--graphics/asymptote/absyn.h65
-rw-r--r--graphics/asymptote/access.cc163
-rw-r--r--graphics/asymptote/access.h135
-rw-r--r--graphics/asymptote/algebra3.cc1610
-rw-r--r--graphics/asymptote/algebra3.h480
-rw-r--r--graphics/asymptote/align.h123
-rw-r--r--graphics/asymptote/angle.h49
-rw-r--r--graphics/asymptote/application.cc711
-rw-r--r--graphics/asymptote/application.h313
-rw-r--r--graphics/asymptote/arcball.cc237
-rw-r--r--graphics/asymptote/arcball.h95
-rw-r--r--graphics/asymptote/array.cc188
-rw-r--r--graphics/asymptote/array.h105
-rw-r--r--graphics/asymptote/arrayop.h592
-rw-r--r--graphics/asymptote/aspy.py355
-rw-r--r--graphics/asymptote/asy-keywords.el17
-rwxr-xr-xgraphics/asymptote/asy-list.pl106
-rw-r--r--graphics/asymptote/asy.icobin0 -> 4286 bytes
-rw-r--r--graphics/asymptote/asy.list3934
-rw-r--r--graphics/asymptote/asy.rc26
-rw-r--r--graphics/asymptote/asymptote.nsi180
-rw-r--r--graphics/asymptote/asymptote.spec109
-rwxr-xr-xgraphics/asymptote/autogen.sh3
-rw-r--r--graphics/asymptote/ax_pthread.m4309
-rw-r--r--graphics/asymptote/base/CAD.asy367
-rw-r--r--graphics/asymptote/base/animate.asy3
-rw-r--r--graphics/asymptote/base/animation.asy188
-rw-r--r--graphics/asymptote/base/annotate.asy16
-rw-r--r--graphics/asymptote/base/asy-init.el4
-rw-r--r--graphics/asymptote/base/asy-kate.sh146
-rw-r--r--graphics/asymptote/base/asy-mode.el1600
-rw-r--r--graphics/asymptote/base/asy.vim202
-rw-r--r--graphics/asymptote/base/asy_filetype.vim3
-rwxr-xr-xgraphics/asymptote/base/asymptote.py50
-rw-r--r--graphics/asymptote/base/babel.asy4
-rw-r--r--graphics/asymptote/base/bezulate.asy310
-rw-r--r--graphics/asymptote/base/binarytree.asy383
-rw-r--r--graphics/asymptote/base/bsp.asy209
-rw-r--r--graphics/asymptote/base/colormap.asy3890
-rw-r--r--graphics/asymptote/base/contour.asy682
-rw-r--r--graphics/asymptote/base/contour3.asy479
-rw-r--r--graphics/asymptote/base/drawtree.asy101
-rw-r--r--graphics/asymptote/base/embed.asy37
-rw-r--r--graphics/asymptote/base/external.asy37
-rw-r--r--graphics/asymptote/base/feynman.asy622
-rw-r--r--graphics/asymptote/base/flowchart.asy526
-rw-r--r--graphics/asymptote/base/fontsize.asy1
-rw-r--r--graphics/asymptote/base/geometry.asy7192
-rw-r--r--graphics/asymptote/base/graph.asy2243
-rw-r--r--graphics/asymptote/base/graph3.asy2044
-rw-r--r--graphics/asymptote/base/graph_settings.asy18
-rw-r--r--graphics/asymptote/base/graph_splinetype.asy264
-rw-r--r--graphics/asymptote/base/grid3.asy412
-rw-r--r--graphics/asymptote/base/interpolate.asy140
-rw-r--r--graphics/asymptote/base/labelpath.asy28
-rw-r--r--graphics/asymptote/base/labelpath3.asy83
-rw-r--r--graphics/asymptote/base/latin1.asy2
-rw-r--r--graphics/asymptote/base/lmfit.asy881
-rw-r--r--graphics/asymptote/base/markers.asy218
-rw-r--r--graphics/asymptote/base/math.asy451
-rw-r--r--graphics/asymptote/base/metapost.asy19
-rw-r--r--graphics/asymptote/base/nopapersize.ps3
-rw-r--r--graphics/asymptote/base/obj.asy113
-rw-r--r--graphics/asymptote/base/ode.asy457
-rw-r--r--graphics/asymptote/base/palette.asy530
-rw-r--r--graphics/asymptote/base/patterns.asy102
-rw-r--r--graphics/asymptote/base/plain.asy302
-rw-r--r--graphics/asymptote/base/plain_Label.asy691
-rw-r--r--graphics/asymptote/base/plain_arcs.asy44
-rw-r--r--graphics/asymptote/base/plain_arrows.asy631
-rw-r--r--graphics/asymptote/base/plain_bounds.asy788
-rw-r--r--graphics/asymptote/base/plain_boxes.asy139
-rw-r--r--graphics/asymptote/base/plain_constants.asy169
-rw-r--r--graphics/asymptote/base/plain_debugger.asy86
-rw-r--r--graphics/asymptote/base/plain_filldraw.asy248
-rw-r--r--graphics/asymptote/base/plain_margins.asy99
-rw-r--r--graphics/asymptote/base/plain_markers.asy401
-rw-r--r--graphics/asymptote/base/plain_paths.asy397
-rw-r--r--graphics/asymptote/base/plain_pens.asy368
-rw-r--r--graphics/asymptote/base/plain_picture.asy1694
-rw-r--r--graphics/asymptote/base/plain_prethree.asy216
-rw-r--r--graphics/asymptote/base/plain_scaling.asy258
-rw-r--r--graphics/asymptote/base/plain_shipout.asy145
-rw-r--r--graphics/asymptote/base/plain_strings.asy264
-rw-r--r--graphics/asymptote/base/pstoedit.asy18
-rw-r--r--graphics/asymptote/base/rational.asy269
-rw-r--r--graphics/asymptote/base/rationalSimplex.asy362
-rw-r--r--graphics/asymptote/base/reload.js23
-rw-r--r--graphics/asymptote/base/res/notes.txt7
-rw-r--r--graphics/asymptote/base/roundedpath.asy84
-rw-r--r--graphics/asymptote/base/shaders/fragment.glsl237
-rw-r--r--graphics/asymptote/base/shaders/vertex.glsl49
-rw-r--r--graphics/asymptote/base/simplex.asy329
-rw-r--r--graphics/asymptote/base/size10.asy12
-rw-r--r--graphics/asymptote/base/size11.asy12
-rw-r--r--graphics/asymptote/base/slide.asy620
-rw-r--r--graphics/asymptote/base/slopefield.asy87
-rw-r--r--graphics/asymptote/base/smoothcontour3.asy1582
-rw-r--r--graphics/asymptote/base/solids.asy412
-rw-r--r--graphics/asymptote/base/stats.asy292
-rw-r--r--graphics/asymptote/base/syzygy.asy926
-rw-r--r--graphics/asymptote/base/texcolors.asy68
-rw-r--r--graphics/asymptote/base/three.asy3251
-rw-r--r--graphics/asymptote/base/three_arrows.asy723
-rw-r--r--graphics/asymptote/base/three_light.asy133
-rw-r--r--graphics/asymptote/base/three_margins.asy104
-rw-r--r--graphics/asymptote/base/three_surface.asy2455
-rw-r--r--graphics/asymptote/base/three_tube.asy426
-rw-r--r--graphics/asymptote/base/tree.asy86
-rw-r--r--graphics/asymptote/base/trembling.asy199
-rw-r--r--graphics/asymptote/base/tube.asy167
-rw-r--r--graphics/asymptote/base/unicode.asy2
-rw-r--r--graphics/asymptote/base/x11colors.asy145
-rw-r--r--graphics/asymptote/bbox.h244
-rw-r--r--graphics/asymptote/bbox3.h191
-rw-r--r--graphics/asymptote/beziercurve.cc181
-rw-r--r--graphics/asymptote/beziercurve.h137
-rw-r--r--graphics/asymptote/bezierpatch.cc1107
-rw-r--r--graphics/asymptote/bezierpatch.h315
-rw-r--r--graphics/asymptote/binaries/i386-windows/README66
-rwxr-xr-xgraphics/asymptote/binaries/i386-windows/cygwin1.dllbin0 -> 3002325 bytes
-rw-r--r--graphics/asymptote/binaries/i386-windows/texlive/README5
-rw-r--r--graphics/asymptote/binaries/x86_64-windows/README66
-rw-r--r--graphics/asymptote/binaries/x86_64-windows/cygwin1.dllbin0 -> 3339661 bytes
-rw-r--r--graphics/asymptote/binaries/x86_64-windows/texlive/README5
-rw-r--r--graphics/asymptote/build-scripts/HOWTO-MSWindows63
-rw-r--r--graphics/asymptote/build-scripts/README-binaries5
-rwxr-xr-xgraphics/asymptote/build-scripts/build-asymptote74
-rwxr-xr-xgraphics/asymptote/build-scripts/build-asymptote.dos97
-rwxr-xr-xgraphics/asymptote/build-scripts/build-freeglut22
-rw-r--r--graphics/asymptote/builtin.cc966
-rw-r--r--graphics/asymptote/builtin.h60
-rw-r--r--graphics/asymptote/callable.cc75
-rw-r--r--graphics/asymptote/callable.h91
-rw-r--r--graphics/asymptote/camp.l444
-rw-r--r--graphics/asymptote/camp.tab.cc3404
-rw-r--r--graphics/asymptote/camp.tab.h171
-rw-r--r--graphics/asymptote/camp.y652
-rw-r--r--graphics/asymptote/camperror.cc64
-rw-r--r--graphics/asymptote/camperror.h34
-rw-r--r--graphics/asymptote/castop.h216
-rw-r--r--graphics/asymptote/coder.cc376
-rw-r--r--graphics/asymptote/coder.h428
-rw-r--r--graphics/asymptote/coenv.cc47
-rw-r--r--graphics/asymptote/coenv.h40
-rw-r--r--graphics/asymptote/common.h86
-rw-r--r--graphics/asymptote/config.guess1476
-rw-r--r--graphics/asymptote/config.h.in249
-rw-r--r--graphics/asymptote/config.sub1801
-rwxr-xr-xgraphics/asymptote/configure9841
-rw-r--r--graphics/asymptote/configure.ac455
-rw-r--r--graphics/asymptote/constructor.cc143
-rw-r--r--graphics/asymptote/dec.cc909
-rw-r--r--graphics/asymptote/dec.h662
-rw-r--r--graphics/asymptote/doc/Bode.asy27
-rw-r--r--graphics/asymptote/doc/CAD.pdfbin0 -> 67528 bytes
-rw-r--r--graphics/asymptote/doc/CAD.tex256
-rw-r--r--graphics/asymptote/doc/CAD1.asy43
-rw-r--r--graphics/asymptote/doc/CDlabel.asy14
-rw-r--r--graphics/asymptote/doc/FAQ/Makefile40
-rw-r--r--graphics/asymptote/doc/FAQ/asy-faq.bfnn1287
-rw-r--r--graphics/asymptote/doc/FAQ/asy-faq.info1671
-rwxr-xr-xgraphics/asymptote/doc/FAQ/bfnnconv.pl298
-rwxr-xr-xgraphics/asymptote/doc/FAQ/install-sh520
-rw-r--r--graphics/asymptote/doc/FAQ/m-ascii.pl189
-rw-r--r--graphics/asymptote/doc/FAQ/m-html.pl341
-rw-r--r--graphics/asymptote/doc/FAQ/m-info.pl226
-rw-r--r--graphics/asymptote/doc/FAQ/m-lout.pl242
-rw-r--r--graphics/asymptote/doc/FAQ/m-post.pl189
-rw-r--r--graphics/asymptote/doc/GaussianSurface.asy21
-rw-r--r--graphics/asymptote/doc/HermiteSpline.asy14
-rw-r--r--graphics/asymptote/doc/Hobbycontrol.asy20
-rw-r--r--graphics/asymptote/doc/Hobbydir.asy21
-rw-r--r--graphics/asymptote/doc/Makefile.in135
-rw-r--r--graphics/asymptote/doc/TeXShopAndAsymptote.pdfbin0 -> 31566 bytes
-rw-r--r--graphics/asymptote/doc/TeXShopAndAsymptote.tex94
-rw-r--r--graphics/asymptote/doc/asy-latex.dtx715
-rw-r--r--graphics/asymptote/doc/asy-latex.pdfbin0 -> 194549 bytes
-rw-r--r--graphics/asymptote/doc/asy.1309
-rw-r--r--graphics/asymptote/doc/asy.1.begin32
-rw-r--r--graphics/asymptote/doc/asy.1.end10
-rw-r--r--graphics/asymptote/doc/asyRefCard.pdfbin0 -> 53680 bytes
-rw-r--r--graphics/asymptote/doc/asyRefCard.tex558
-rw-r--r--graphics/asymptote/doc/asycolors.sty72
-rw-r--r--graphics/asymptote/doc/asymptote.pdfbin0 -> 1290552 bytes
-rw-r--r--graphics/asymptote/doc/asymptote.sty405
-rw-r--r--graphics/asymptote/doc/asymptote.texi9954
-rw-r--r--graphics/asymptote/doc/axis3.asy12
-rw-r--r--graphics/asymptote/doc/bezier.asy1
-rw-r--r--graphics/asymptote/doc/bezier2.asy21
-rw-r--r--graphics/asymptote/doc/beziercurve.asy12
-rw-r--r--graphics/asymptote/doc/bigdiagonal.asy2
-rw-r--r--graphics/asymptote/doc/binarytreetest.asy13
-rw-r--r--graphics/asymptote/doc/brokenaxis.asy25
-rw-r--r--graphics/asymptote/doc/colo-asy.tex84
-rw-r--r--graphics/asymptote/doc/colons.asy1
-rw-r--r--graphics/asymptote/doc/colors.asy115
-rw-r--r--graphics/asymptote/doc/cube.asy15
-rw-r--r--graphics/asymptote/doc/cylinderskeleton.asy6
-rw-r--r--graphics/asymptote/doc/datagraph.asy12
-rw-r--r--graphics/asymptote/doc/diagonal.asy1
-rw-r--r--graphics/asymptote/doc/diatom.asy129
-rw-r--r--graphics/asymptote/doc/diatom.csv28
-rw-r--r--graphics/asymptote/doc/dots.asy1
-rw-r--r--graphics/asymptote/doc/eetomumu.asy60
-rw-r--r--graphics/asymptote/doc/elliptic.asy115
-rw-r--r--graphics/asymptote/doc/errorbars.asy42
-rw-r--r--graphics/asymptote/doc/exp.asy14
-rw-r--r--graphics/asymptote/doc/external-proposal.html415
-rw-r--r--graphics/asymptote/doc/externalprc.tex13
-rw-r--r--graphics/asymptote/doc/extra/intro.asy959
-rw-r--r--graphics/asymptote/doc/filegraph.asy15
-rw-r--r--graphics/asymptote/doc/filegraph.dat4
-rw-r--r--graphics/asymptote/doc/flow.asy31
-rw-r--r--graphics/asymptote/doc/flowchartdemo.asy27
-rw-r--r--graphics/asymptote/doc/generalaxis.asy11
-rw-r--r--graphics/asymptote/doc/generalaxis3.asy13
-rw-r--r--graphics/asymptote/doc/graphmarkers.asy37
-rw-r--r--graphics/asymptote/doc/grid3xyz.asy17
-rw-r--r--graphics/asymptote/doc/hatch.asy11
-rw-r--r--graphics/asymptote/doc/helix.asy20
-rw-r--r--graphics/asymptote/doc/histogram.asy19
-rw-r--r--graphics/asymptote/doc/icon.asy22
-rw-r--r--graphics/asymptote/doc/image.asy21
-rw-r--r--graphics/asymptote/doc/imagecontour.asy38
-rwxr-xr-xgraphics/asymptote/doc/install-sh520
-rw-r--r--graphics/asymptote/doc/irregularcontour.asy21
-rw-r--r--graphics/asymptote/doc/join.asy15
-rw-r--r--graphics/asymptote/doc/join3.asy21
-rw-r--r--graphics/asymptote/doc/knots.asy27
-rw-r--r--graphics/asymptote/doc/labelsquare.asy6
-rw-r--r--graphics/asymptote/doc/latexmkrc4
-rw-r--r--graphics/asymptote/doc/latexmkrc_asydir4
-rw-r--r--graphics/asymptote/doc/latexusage.tex119
-rw-r--r--graphics/asymptote/doc/leastsquares.asy55
-rw-r--r--graphics/asymptote/doc/leastsquares.dat882
-rw-r--r--graphics/asymptote/doc/legend.asy15
-rw-r--r--graphics/asymptote/doc/lineargraph.asy16
-rw-r--r--graphics/asymptote/doc/lineargraph0.asy16
-rw-r--r--graphics/asymptote/doc/linetype.asy13
-rw-r--r--graphics/asymptote/doc/log2graph.asy17
-rw-r--r--graphics/asymptote/doc/loggraph.asy17
-rw-r--r--graphics/asymptote/doc/loggrid.asy13
-rw-r--r--graphics/asymptote/doc/logimage.asy22
-rw-r--r--graphics/asymptote/doc/logo.asy28
-rw-r--r--graphics/asymptote/doc/logticks.asy11
-rw-r--r--graphics/asymptote/doc/makepen.asy9
-rw-r--r--graphics/asymptote/doc/markers1.asy102
-rw-r--r--graphics/asymptote/doc/markers2.asy34
-rw-r--r--graphics/asymptote/doc/mexicanhat.asy22
-rw-r--r--graphics/asymptote/doc/monthaxis.asy17
-rw-r--r--graphics/asymptote/doc/multicontour.asy19
-rw-r--r--graphics/asymptote/doc/ocg.sty130
-rw-r--r--graphics/asymptote/doc/onecontour.asy5
-rw-r--r--graphics/asymptote/doc/parametricgraph.asy15
-rw-r--r--graphics/asymptote/doc/penfunctionimage.asy27
-rw-r--r--graphics/asymptote/doc/penimage.asy14
-rw-r--r--graphics/asymptote/doc/pixel.pdfbin0 -> 2771 bytes
-rw-r--r--graphics/asymptote/doc/planes.asy18
-rw-r--r--graphics/asymptote/doc/png/Makefile.in57
-rw-r--r--graphics/asymptote/doc/png/asymptote.info10265
-rw-r--r--graphics/asymptote/doc/quartercircle.asy2
-rw-r--r--graphics/asymptote/doc/reloadpdf.tex11
-rw-r--r--graphics/asymptote/doc/saddle.asy7
-rw-r--r--graphics/asymptote/doc/scaledgraph.asy15
-rw-r--r--graphics/asymptote/doc/secondaryaxis.asy32
-rw-r--r--graphics/asymptote/doc/secondaryaxis.csv1003
-rw-r--r--graphics/asymptote/doc/shadedtiling.asy12
-rw-r--r--graphics/asymptote/doc/slopefield1.asy9
-rw-r--r--graphics/asymptote/doc/square.asy2
-rw-r--r--graphics/asymptote/doc/subpictures.asy20
-rw-r--r--graphics/asymptote/doc/superpath.asy5
-rw-r--r--graphics/asymptote/doc/tile.asy13
-rw-r--r--graphics/asymptote/doc/triangulate.asy19
-rw-r--r--graphics/asymptote/doc/unitcircle3.asy9
-rw-r--r--graphics/asymptote/doc/vectorfield.asy9
-rw-r--r--graphics/asymptote/doc/westnile.asy64
-rw-r--r--graphics/asymptote/doc/westnile.csv402
-rw-r--r--graphics/asymptote/doc/xasy.1x27
-rw-r--r--graphics/asymptote/drawclipbegin.h92
-rw-r--r--graphics/asymptote/drawclipend.h66
-rw-r--r--graphics/asymptote/drawelement.h436
-rw-r--r--graphics/asymptote/drawfill.cc176
-rw-r--r--graphics/asymptote/drawfill.h256
-rw-r--r--graphics/asymptote/drawgrestore.h35
-rw-r--r--graphics/asymptote/drawgroup.h116
-rw-r--r--graphics/asymptote/drawgsave.h35
-rw-r--r--graphics/asymptote/drawimage.h128
-rw-r--r--graphics/asymptote/drawlabel.cc271
-rw-r--r--graphics/asymptote/drawlabel.h90
-rw-r--r--graphics/asymptote/drawlayer.h45
-rw-r--r--graphics/asymptote/drawpath.cc165
-rw-r--r--graphics/asymptote/drawpath.h37
-rw-r--r--graphics/asymptote/drawpath3.cc289
-rw-r--r--graphics/asymptote/drawpath3.h206
-rw-r--r--graphics/asymptote/drawsurface.cc953
-rw-r--r--graphics/asymptote/drawsurface.h655
-rw-r--r--graphics/asymptote/drawverbatim.h63
-rw-r--r--graphics/asymptote/entry.cc873
-rw-r--r--graphics/asymptote/entry.h535
-rw-r--r--graphics/asymptote/env.cc217
-rw-r--r--graphics/asymptote/env.h187
-rw-r--r--graphics/asymptote/envcompleter.cc58
-rw-r--r--graphics/asymptote/envcompleter.h41
-rw-r--r--graphics/asymptote/errormsg.cc110
-rw-r--r--graphics/asymptote/errormsg.h233
-rw-r--r--graphics/asymptote/errors157
-rw-r--r--graphics/asymptote/errortest.asy514
-rw-r--r--graphics/asymptote/examples/100d.views21
-rw-r--r--graphics/asymptote/examples/1overx.asy17
-rw-r--r--graphics/asymptote/examples/BezierPatch.asy14
-rw-r--r--graphics/asymptote/examples/BezierSaddle.asy29
-rw-r--r--graphics/asymptote/examples/BezierSurface.asy42
-rw-r--r--graphics/asymptote/examples/BezierTriangle.asy10
-rw-r--r--graphics/asymptote/examples/Coons.asy6
-rw-r--r--graphics/asymptote/examples/Gouraud.asy18
-rw-r--r--graphics/asymptote/examples/Gouraudcontour.asy31
-rw-r--r--graphics/asymptote/examples/Klein.asy51
-rw-r--r--graphics/asymptote/examples/NURBScurve.asy33
-rw-r--r--graphics/asymptote/examples/NURBSsphere.asy46
-rw-r--r--graphics/asymptote/examples/NURBSsurface.asy62
-rw-r--r--graphics/asymptote/examples/Pythagoras.asy22
-rw-r--r--graphics/asymptote/examples/PythagoreanTree.asy20
-rw-r--r--graphics/asymptote/examples/RiemannSphere.asy47
-rw-r--r--graphics/asymptote/examples/RiemannSurface.asy13
-rw-r--r--graphics/asymptote/examples/RiemannSurfaceRoot.asy16
-rw-r--r--graphics/asymptote/examples/Sierpinski.asy17
-rw-r--r--graphics/asymptote/examples/SierpinskiGasket.asy31
-rw-r--r--graphics/asymptote/examples/SierpinskiSponge.asy99
-rw-r--r--graphics/asymptote/examples/advection.asy87
-rw-r--r--graphics/asymptote/examples/alignbox.asy9
-rw-r--r--graphics/asymptote/examples/alignedaxis.asy107
-rw-r--r--graphics/asymptote/examples/animations/cube.asy46
-rw-r--r--graphics/asymptote/examples/animations/dice.u3dbin0 -> 160672 bytes
-rw-r--r--graphics/asymptote/examples/animations/earthmoon.asy78
-rw-r--r--graphics/asymptote/examples/animations/embeddedmovie.asy19
-rw-r--r--graphics/asymptote/examples/animations/embeddedu3d.asy8
-rw-r--r--graphics/asymptote/examples/animations/externalmovie.asy16
-rw-r--r--graphics/asymptote/examples/animations/glmovie.asy21
-rw-r--r--graphics/asymptote/examples/animations/heatequation.asy76
-rw-r--r--graphics/asymptote/examples/animations/inlinemovie.tex55
-rw-r--r--graphics/asymptote/examples/animations/inlinemovie3.tex44
-rw-r--r--graphics/asymptote/examples/animations/pdfmovie.asy20
-rw-r--r--graphics/asymptote/examples/animations/slidemovies.asy44
-rw-r--r--graphics/asymptote/examples/animations/sphere.asy42
-rw-r--r--graphics/asymptote/examples/animations/torusanimation.asy43
-rw-r--r--graphics/asymptote/examples/animations/wavepacket.asy86
-rw-r--r--graphics/asymptote/examples/animations/wheel.asy63
-rw-r--r--graphics/asymptote/examples/annotation.asy13
-rw-r--r--graphics/asymptote/examples/arrows3.asy22
-rw-r--r--graphics/asymptote/examples/bars3.asy22
-rw-r--r--graphics/asymptote/examples/basealign.asy44
-rw-r--r--graphics/asymptote/examples/billboard.asy10
-rw-r--r--graphics/asymptote/examples/buildcycle.asy22
-rw-r--r--graphics/asymptote/examples/cardioid.asy15
-rw-r--r--graphics/asymptote/examples/cards.asy26
-rw-r--r--graphics/asymptote/examples/centroidfg.asy38
-rw-r--r--graphics/asymptote/examples/cheese.asy15
-rw-r--r--graphics/asymptote/examples/circles.asy33
-rw-r--r--graphics/asymptote/examples/circumcircle.asy9
-rw-r--r--graphics/asymptote/examples/clockarray.asy39
-rw-r--r--graphics/asymptote/examples/coag.asy16
-rw-r--r--graphics/asymptote/examples/colorpatch.asy18
-rw-r--r--graphics/asymptote/examples/colorplanes.asy22
-rw-r--r--graphics/asymptote/examples/condor.asy32
-rw-r--r--graphics/asymptote/examples/cones.asy18
-rw-r--r--graphics/asymptote/examples/conicurv.asy49
-rw-r--r--graphics/asymptote/examples/contextfonts.asy10
-rw-r--r--graphics/asymptote/examples/controlsystem.asy25
-rw-r--r--graphics/asymptote/examples/cos2theta.asy15
-rw-r--r--graphics/asymptote/examples/cos3.asy25
-rw-r--r--graphics/asymptote/examples/cosaddition.asy26
-rw-r--r--graphics/asymptote/examples/cpkcolors.asy259
-rw-r--r--graphics/asymptote/examples/curvedlabel.asy4
-rw-r--r--graphics/asymptote/examples/curvedlabel3.asy17
-rw-r--r--graphics/asymptote/examples/cyclohexane.asy80
-rw-r--r--graphics/asymptote/examples/cylinder.asy8
-rw-r--r--graphics/asymptote/examples/delu.asy29
-rw-r--r--graphics/asymptote/examples/dimension.asy23
-rw-r--r--graphics/asymptote/examples/dragon.asy66
-rw-r--r--graphics/asymptote/examples/electromagnetic.asy47
-rw-r--r--graphics/asymptote/examples/elevation.asy17
-rw-r--r--graphics/asymptote/examples/epix.asy14
-rw-r--r--graphics/asymptote/examples/equilateral.asy12
-rw-r--r--graphics/asymptote/examples/equilchord.asy21
-rw-r--r--graphics/asymptote/examples/exp3.asy22
-rw-r--r--graphics/asymptote/examples/extrudedcontour.asy26
-rw-r--r--graphics/asymptote/examples/fano.asy28
-rw-r--r--graphics/asymptote/examples/fequlogo.asy40
-rw-r--r--graphics/asymptote/examples/fermi.asy40
-rw-r--r--graphics/asymptote/examples/filesurface.asy45
-rw-r--r--graphics/asymptote/examples/filesurface.dat12
-rw-r--r--graphics/asymptote/examples/fillcontour.asy29
-rw-r--r--graphics/asymptote/examples/fin.asy152
-rw-r--r--graphics/asymptote/examples/fjortoft.asy27
-rw-r--r--graphics/asymptote/examples/floatingdisk.asy26
-rw-r--r--graphics/asymptote/examples/floor.asy28
-rw-r--r--graphics/asymptote/examples/fractaltree.asy27
-rw-r--r--graphics/asymptote/examples/functionshading.asy31
-rw-r--r--graphics/asymptote/examples/galleon.asy14
-rw-r--r--graphics/asymptote/examples/gamma.asy24
-rw-r--r--graphics/asymptote/examples/gamma3.asy33
-rw-r--r--graphics/asymptote/examples/genusthree.asy23
-rw-r--r--graphics/asymptote/examples/genustwo.asy36
-rw-r--r--graphics/asymptote/examples/grid.asy7
-rw-r--r--graphics/asymptote/examples/hierarchy.asy9
-rw-r--r--graphics/asymptote/examples/hyperboloid.asy8
-rw-r--r--graphics/asymptote/examples/hyperboloidsilhouette.asy9
-rw-r--r--graphics/asymptote/examples/imagehistogram.asy47
-rw-r--r--graphics/asymptote/examples/impact.asy29
-rw-r--r--graphics/asymptote/examples/integraltest.asy38
-rw-r--r--graphics/asymptote/examples/interpolate1.asy226
-rw-r--r--graphics/asymptote/examples/jump.asy14
-rw-r--r--graphics/asymptote/examples/label3.asy7
-rw-r--r--graphics/asymptote/examples/label3ribbon.asy6
-rw-r--r--graphics/asymptote/examples/label3solid.asy6
-rw-r--r--graphics/asymptote/examples/label3zoom.asy16
-rw-r--r--graphics/asymptote/examples/labelbox.asy11
-rw-r--r--graphics/asymptote/examples/laserlattice.asy44
-rw-r--r--graphics/asymptote/examples/latticeshading.asy7
-rw-r--r--graphics/asymptote/examples/layers.asy44
-rw-r--r--graphics/asymptote/examples/lever.asy23
-rw-r--r--graphics/asymptote/examples/limit.asy28
-rw-r--r--graphics/asymptote/examples/linearregression.asy64
-rw-r--r--graphics/asymptote/examples/lines.asy10
-rw-r--r--graphics/asymptote/examples/lmfit1.asy37
-rw-r--r--graphics/asymptote/examples/log.asy14
-rw-r--r--graphics/asymptote/examples/logdown.asy13
-rw-r--r--graphics/asymptote/examples/logo3.asy41
-rw-r--r--graphics/asymptote/examples/lowint.asy11
-rw-r--r--graphics/asymptote/examples/lowupint.asy31
-rw-r--r--graphics/asymptote/examples/magnetic.asy18
-rw-r--r--graphics/asymptote/examples/markregular.asy26
-rw-r--r--graphics/asymptote/examples/mergeExample.asy77
-rw-r--r--graphics/asymptote/examples/mosaic.asy165
-rw-r--r--graphics/asymptote/examples/mosquito.asy82
-rw-r--r--graphics/asymptote/examples/near_earth.asy56
-rw-r--r--graphics/asymptote/examples/odetest.asy43
-rw-r--r--graphics/asymptote/examples/oneoverx.asy17
-rw-r--r--graphics/asymptote/examples/orthocenter.asy40
-rw-r--r--graphics/asymptote/examples/p-orbital.asy31
-rw-r--r--graphics/asymptote/examples/parametricelevation.asy10
-rw-r--r--graphics/asymptote/examples/parametricsurface.asy23
-rw-r--r--graphics/asymptote/examples/partialsurface.asy29
-rw-r--r--graphics/asymptote/examples/partitionExample.asy27
-rw-r--r--graphics/asymptote/examples/pathintersectsurface.asy20
-rw-r--r--graphics/asymptote/examples/pdb.asy164
-rw-r--r--graphics/asymptote/examples/phase.asy18
-rw-r--r--graphics/asymptote/examples/piicon.eps1135
-rw-r--r--graphics/asymptote/examples/pipeintersection.asy13
-rw-r--r--graphics/asymptote/examples/pipes.asy140
-rw-r--r--graphics/asymptote/examples/planeproject.asy18
-rw-r--r--graphics/asymptote/examples/polararea.asy38
-rw-r--r--graphics/asymptote/examples/polarcircle.asy30
-rw-r--r--graphics/asymptote/examples/polardatagraph.asy17
-rw-r--r--graphics/asymptote/examples/poster.asy33
-rw-r--r--graphics/asymptote/examples/progrid.asy1
-rw-r--r--graphics/asymptote/examples/projectelevation.asy17
-rw-r--r--graphics/asymptote/examples/projectrevolution.asy17
-rw-r--r--graphics/asymptote/examples/pseudosphere.asy33
-rw-r--r--graphics/asymptote/examples/quilt.asy44
-rw-r--r--graphics/asymptote/examples/rainbow.asy12
-rw-r--r--graphics/asymptote/examples/randompath3.asy4
-rw-r--r--graphics/asymptote/examples/refs.bib55
-rw-r--r--graphics/asymptote/examples/ring.asy4
-rw-r--r--graphics/asymptote/examples/roll.asy10
-rw-r--r--graphics/asymptote/examples/roundpath.asy32
-rw-r--r--graphics/asymptote/examples/sacone.asy23
-rw-r--r--graphics/asymptote/examples/sacone3D.asy14
-rw-r--r--graphics/asymptote/examples/sacylinder.asy26
-rw-r--r--graphics/asymptote/examples/sacylinder3D.asy14
-rw-r--r--graphics/asymptote/examples/shade.asy3
-rw-r--r--graphics/asymptote/examples/shadestroke.asy5
-rw-r--r--graphics/asymptote/examples/shellmethod.asy41
-rw-r--r--graphics/asymptote/examples/shellsqrtx01.asy36
-rw-r--r--graphics/asymptote/examples/sin1x.asy16
-rw-r--r--graphics/asymptote/examples/sin3.asy22
-rw-r--r--graphics/asymptote/examples/sinc.asy24
-rw-r--r--graphics/asymptote/examples/sinxlex.asy24
-rw-r--r--graphics/asymptote/examples/slidedemo.asy118
-rw-r--r--graphics/asymptote/examples/slidedemo_.bbl13
-rw-r--r--graphics/asymptote/examples/slope.asy83
-rw-r--r--graphics/asymptote/examples/smoothelevation.asy26
-rw-r--r--graphics/asymptote/examples/soccerball.asy90
-rw-r--r--graphics/asymptote/examples/spectrum.asy79
-rw-r--r--graphics/asymptote/examples/sphere.asy6
-rw-r--r--graphics/asymptote/examples/spheresilhouette.asy9
-rw-r--r--graphics/asymptote/examples/sphereskeleton.asy9
-rw-r--r--graphics/asymptote/examples/sphericalharmonic.asy14
-rw-r--r--graphics/asymptote/examples/spiral.asy12
-rw-r--r--graphics/asymptote/examples/spiral3.asy20
-rw-r--r--graphics/asymptote/examples/spline.asy25
-rw-r--r--graphics/asymptote/examples/splitpatch.asy87
-rw-r--r--graphics/asymptote/examples/spring.asy33
-rw-r--r--graphics/asymptote/examples/spring0.asy4
-rw-r--r--graphics/asymptote/examples/spring2.asy4
-rw-r--r--graphics/asymptote/examples/sqrtx01.asy25
-rw-r--r--graphics/asymptote/examples/sqrtx01y1.asy22
-rw-r--r--graphics/asymptote/examples/star.asy13
-rw-r--r--graphics/asymptote/examples/stereoscopic.asy11
-rw-r--r--graphics/asymptote/examples/stroke3.asy4
-rw-r--r--graphics/asymptote/examples/strokepath.asy17
-rw-r--r--graphics/asymptote/examples/strokeshade.asy4
-rw-r--r--graphics/asymptote/examples/tanh.asy13
-rw-r--r--graphics/asymptote/examples/teapot.asy172
-rw-r--r--graphics/asymptote/examples/tensor.asy9
-rw-r--r--graphics/asymptote/examples/tetra.asy12
-rw-r--r--graphics/asymptote/examples/textpath.asy10
-rw-r--r--graphics/asymptote/examples/thermodynamics.asy131
-rw-r--r--graphics/asymptote/examples/threeviews.asy26
-rw-r--r--graphics/asymptote/examples/torus.asy20
-rw-r--r--graphics/asymptote/examples/transparency.asy10
-rw-r--r--graphics/asymptote/examples/treetest.asy22
-rw-r--r--graphics/asymptote/examples/trefoilknot.asy23
-rw-r--r--graphics/asymptote/examples/triads.asy52
-rw-r--r--graphics/asymptote/examples/triangle.asy12
-rw-r--r--graphics/asymptote/examples/triangles.asy20
-rw-r--r--graphics/asymptote/examples/triceratops.asy9
-rw-r--r--graphics/asymptote/examples/trumpet.asy12
-rw-r--r--graphics/asymptote/examples/truncatedIcosahedron.asy68
-rw-r--r--graphics/asymptote/examples/tvgen.asy1480
-rw-r--r--graphics/asymptote/examples/twistedtubes.asy30
-rw-r--r--graphics/asymptote/examples/unitcircle.asy14
-rw-r--r--graphics/asymptote/examples/unitoctant.asy35
-rw-r--r--graphics/asymptote/examples/upint.asy13
-rw-r--r--graphics/asymptote/examples/vectorfield3.asy26
-rw-r--r--graphics/asymptote/examples/vectorfieldsphere.asy17
-rw-r--r--graphics/asymptote/examples/venn.asy36
-rw-r--r--graphics/asymptote/examples/venn3.asy50
-rw-r--r--graphics/asymptote/examples/vertexshading.asy14
-rw-r--r--graphics/asymptote/examples/washer.asy14
-rw-r--r--graphics/asymptote/examples/washermethod.asy43
-rw-r--r--graphics/asymptote/examples/wedge.asy23
-rw-r--r--graphics/asymptote/examples/workcone.asy42
-rw-r--r--graphics/asymptote/examples/worksheet.asy49
-rw-r--r--graphics/asymptote/examples/worldmap.asy87
-rw-r--r--graphics/asymptote/examples/xsin1x.asy24
-rw-r--r--graphics/asymptote/examples/xstitch.asy170
-rw-r--r--graphics/asymptote/examples/xxsq01.asy30
-rw-r--r--graphics/asymptote/examples/xxsq01x-1.asy35
-rw-r--r--graphics/asymptote/examples/xxsq01y.asy34
-rw-r--r--graphics/asymptote/examples/yingyang.asy7
-rw-r--r--graphics/asymptote/exp.cc1496
-rw-r--r--graphics/asymptote/exp.h1101
-rw-r--r--graphics/asymptote/fftw++.cc75
-rw-r--r--graphics/asymptote/fftw++.h1551
-rw-r--r--graphics/asymptote/fftw++asy.cc9
-rw-r--r--graphics/asymptote/fileio.cc180
-rw-r--r--graphics/asymptote/fileio.h814
-rwxr-xr-xgraphics/asymptote/findsym.pl53
-rw-r--r--graphics/asymptote/flatguide.cc53
-rw-r--r--graphics/asymptote/flatguide.h190
-rw-r--r--graphics/asymptote/fpu.h41
-rw-r--r--graphics/asymptote/frame.h98
-rw-r--r--graphics/asymptote/fundec.cc318
-rw-r--r--graphics/asymptote/fundec.h173
-rw-r--r--graphics/asymptote/genv.cc134
-rw-r--r--graphics/asymptote/genv.h61
-rw-r--r--graphics/asymptote/getopt.c1055
-rw-r--r--graphics/asymptote/getopt.h180
-rw-r--r--graphics/asymptote/getopt1.c188
-rw-r--r--graphics/asymptote/glew.c7
-rw-r--r--graphics/asymptote/glrender.cc1789
-rw-r--r--graphics/asymptote/glrender.h180
-rw-r--r--graphics/asymptote/gsl.cc1489
-rw-r--r--graphics/asymptote/guide.cc53
-rw-r--r--graphics/asymptote/guide.h319
-rw-r--r--graphics/asymptote/guideflags.h20
-rw-r--r--graphics/asymptote/impdatum.cc615
-rw-r--r--graphics/asymptote/inst.h78
-rwxr-xr-xgraphics/asymptote/install-sh520
-rw-r--r--graphics/asymptote/interact.cc231
-rw-r--r--graphics/asymptote/interact.h54
-rw-r--r--graphics/asymptote/item.h315
-rw-r--r--graphics/asymptote/keywords.cc46
-rwxr-xr-xgraphics/asymptote/keywords.pl60
-rw-r--r--graphics/asymptote/knot.cc840
-rw-r--r--graphics/asymptote/knot.h533
-rw-r--r--graphics/asymptote/lex.yy.cc3265
-rw-r--r--graphics/asymptote/lexical.h23
-rw-r--r--graphics/asymptote/lnkX64IconFix.nsh74
-rw-r--r--graphics/asymptote/locate.cc102
-rw-r--r--graphics/asymptote/locate.h31
-rw-r--r--graphics/asymptote/main.cc250
-rw-r--r--graphics/asymptote/material.h66
-rw-r--r--graphics/asymptote/mathop.h328
-rw-r--r--graphics/asymptote/memory.h201
-rw-r--r--graphics/asymptote/mod.h41
-rw-r--r--graphics/asymptote/modifier.h41
-rw-r--r--graphics/asymptote/name.cc326
-rw-r--r--graphics/asymptote/name.h170
-rw-r--r--graphics/asymptote/newexp.cc185
-rw-r--r--graphics/asymptote/newexp.h60
-rw-r--r--graphics/asymptote/opcodes.h46
-rwxr-xr-xgraphics/asymptote/opsymbols.pl50
-rw-r--r--graphics/asymptote/pair.h235
-rw-r--r--graphics/asymptote/parser.cc180
-rw-r--r--graphics/asymptote/parser.h29
-rw-r--r--graphics/asymptote/patches/README23
-rw-r--r--graphics/asymptote/patches/bison.patch206
-rw-r--r--graphics/asymptote/patches/cygwin_freeglut-3.0.0.patch48
-rwxr-xr-xgraphics/asymptote/patches/dvipdf54
-rw-r--r--graphics/asymptote/patches/fixmem.reg4
-rw-r--r--graphics/asymptote/patches/flex.patch50
-rw-r--r--graphics/asymptote/patches/gc-7.0nomem.patch21
-rw-r--r--graphics/asymptote/patches/gc6.8_AIX.patch7
-rw-r--r--graphics/asymptote/patches/gcc3.3.2curses.patch7
-rw-r--r--graphics/asymptote/path.cc1355
-rw-r--r--graphics/asymptote/path.h460
-rw-r--r--graphics/asymptote/path3.cc1447
-rw-r--r--graphics/asymptote/path3.h392
-rw-r--r--graphics/asymptote/pen.cc46
-rw-r--r--graphics/asymptote/pen.h970
-rw-r--r--graphics/asymptote/picture.cc1425
-rw-r--r--graphics/asymptote/picture.h128
-rw-r--r--graphics/asymptote/pipestream.cc211
-rw-r--r--graphics/asymptote/pipestream.h105
-rw-r--r--graphics/asymptote/policy.h83
-rw-r--r--graphics/asymptote/prc/Makefile42
-rw-r--r--graphics/asymptote/prc/PRC.h512
-rw-r--r--graphics/asymptote/prc/PRCTools/Makefile48
-rw-r--r--graphics/asymptote/prc/PRCTools/bitData.cc258
-rw-r--r--graphics/asymptote/prc/PRCTools/bitData.h62
-rw-r--r--graphics/asymptote/prc/PRCTools/bitSearchDouble.cc67
-rw-r--r--graphics/asymptote/prc/PRCTools/bitSearchUI.cc65
-rw-r--r--graphics/asymptote/prc/PRCTools/describeMain.cc45
-rw-r--r--graphics/asymptote/prc/PRCTools/describePRC.cc2272
-rw-r--r--graphics/asymptote/prc/PRCTools/describePRC.h117
-rw-r--r--graphics/asymptote/prc/PRCTools/extractSections.cc46
-rw-r--r--graphics/asymptote/prc/PRCTools/iPRCFile.cc220
-rw-r--r--graphics/asymptote/prc/PRCTools/iPRCFile.h88
-rw-r--r--graphics/asymptote/prc/PRCTools/inflation.cc90
-rw-r--r--graphics/asymptote/prc/PRCTools/inflation.h31
-rw-r--r--graphics/asymptote/prc/PRCTools/inflationMain.cc55
-rw-r--r--graphics/asymptote/prc/PRCTools/makePRC.cc187
-rw-r--r--graphics/asymptote/prc/PRCbitStream.cc404
-rw-r--r--graphics/asymptote/prc/PRCbitStream.h87
-rw-r--r--graphics/asymptote/prc/PRCdouble.cc2121
-rw-r--r--graphics/asymptote/prc/PRCdouble.h140
-rw-r--r--graphics/asymptote/prc/oPRCFile.cc1921
-rw-r--r--graphics/asymptote/prc/oPRCFile.h1364
-rw-r--r--graphics/asymptote/prc/test.asy5
-rw-r--r--graphics/asymptote/prc/test.cc954
-rw-r--r--graphics/asymptote/prc/writePRC.cc2085
-rw-r--r--graphics/asymptote/prc/writePRC.h1472
-rw-r--r--graphics/asymptote/prcfile.h30
-rw-r--r--graphics/asymptote/predicates.cc2784
-rw-r--r--graphics/asymptote/predicates.h22
-rw-r--r--graphics/asymptote/primitives.h41
-rw-r--r--graphics/asymptote/process.cc1008
-rw-r--r--graphics/asymptote/process.h130
-rw-r--r--graphics/asymptote/profile.py96
-rw-r--r--graphics/asymptote/profiler.h434
-rw-r--r--graphics/asymptote/program.cc172
-rw-r--r--graphics/asymptote/program.h101
-rw-r--r--graphics/asymptote/psfile.cc719
-rw-r--r--graphics/asymptote/psfile.h380
-rw-r--r--graphics/asymptote/quaternion.cc246
-rw-r--r--graphics/asymptote/quaternion.h114
-rw-r--r--graphics/asymptote/record.cc80
-rw-r--r--graphics/asymptote/record.h128
-rw-r--r--graphics/asymptote/refaccess.cc57
-rw-r--r--graphics/asymptote/refaccess.h90
-rw-r--r--graphics/asymptote/revision.cc1
-rw-r--r--graphics/asymptote/rounding.h87
-rw-r--r--graphics/asymptote/runarray.cc2550
-rw-r--r--graphics/asymptote/runarray.h48
-rw-r--r--graphics/asymptote/runarray.in1991
-rw-r--r--graphics/asymptote/runbacktrace.cc117
-rw-r--r--graphics/asymptote/runbacktrace.h8
-rw-r--r--graphics/asymptote/runbacktrace.in35
-rw-r--r--graphics/asymptote/runfile.cc688
-rw-r--r--graphics/asymptote/runfile.h34
-rw-r--r--graphics/asymptote/runfile.in361
-rw-r--r--graphics/asymptote/runhistory.cc321
-rw-r--r--graphics/asymptote/runhistory.h8
-rw-r--r--graphics/asymptote/runhistory.in224
-rw-r--r--graphics/asymptote/runlabel.cc591
-rw-r--r--graphics/asymptote/runlabel.h8
-rw-r--r--graphics/asymptote/runlabel.in484
-rw-r--r--graphics/asymptote/runmath.cc785
-rw-r--r--graphics/asymptote/runmath.h12
-rw-r--r--graphics/asymptote/runmath.in451
-rw-r--r--graphics/asymptote/runpair.cc567
-rw-r--r--graphics/asymptote/runpair.h13
-rw-r--r--graphics/asymptote/runpair.in263
-rw-r--r--graphics/asymptote/runpath.cc846
-rw-r--r--graphics/asymptote/runpath.h9
-rw-r--r--graphics/asymptote/runpath.in445
-rw-r--r--graphics/asymptote/runpath3d.cc767
-rw-r--r--graphics/asymptote/runpath3d.h9
-rw-r--r--graphics/asymptote/runpath3d.in396
-rw-r--r--graphics/asymptote/runpicture.cc1318
-rw-r--r--graphics/asymptote/runpicture.h9
-rw-r--r--graphics/asymptote/runpicture.in724
-rw-r--r--graphics/asymptote/runstring.cc660
-rw-r--r--graphics/asymptote/runstring.h9
-rw-r--r--graphics/asymptote/runstring.in453
-rw-r--r--graphics/asymptote/runsystem.cc453
-rw-r--r--graphics/asymptote/runsystem.h8
-rw-r--r--graphics/asymptote/runsystem.in256
-rw-r--r--graphics/asymptote/runtime.cc2120
-rw-r--r--graphics/asymptote/runtime.h38
-rw-r--r--graphics/asymptote/runtime.in1212
-rwxr-xr-xgraphics/asymptote/runtime.pl294
-rw-r--r--graphics/asymptote/runtimebase.in64
-rw-r--r--graphics/asymptote/runtriple.cc422
-rw-r--r--graphics/asymptote/runtriple.h13
-rw-r--r--graphics/asymptote/runtriple.in162
-rw-r--r--graphics/asymptote/seconds.h100
-rw-r--r--graphics/asymptote/settings.cc1695
-rw-r--r--graphics/asymptote/settings.h127
-rw-r--r--graphics/asymptote/shaders.cc109
-rw-r--r--graphics/asymptote/shaders.h34
-rw-r--r--graphics/asymptote/simpson.cc221
-rw-r--r--graphics/asymptote/stack.cc674
-rw-r--r--graphics/asymptote/stack.h167
-rw-r--r--graphics/asymptote/statistics.h51
-rw-r--r--graphics/asymptote/stm.cc504
-rw-r--r--graphics/asymptote/stm.h232
-rw-r--r--graphics/asymptote/symbol.cc345
-rw-r--r--graphics/asymptote/symbol.h120
-rw-r--r--graphics/asymptote/table.h128
-rw-r--r--graphics/asymptote/tests/Makefile24
-rw-r--r--graphics/asymptote/tests/TestLib.asy15
-rw-r--r--graphics/asymptote/tests/arith/integer.asy23
-rw-r--r--graphics/asymptote/tests/arith/pair.asy20
-rw-r--r--graphics/asymptote/tests/arith/random.asy11
-rw-r--r--graphics/asymptote/tests/arith/real.asy18
-rw-r--r--graphics/asymptote/tests/arith/roots.asy96
-rw-r--r--graphics/asymptote/tests/arith/transform.asy25
-rw-r--r--graphics/asymptote/tests/arith/triple.asy11
-rw-r--r--graphics/asymptote/tests/array/array.asy49
-rw-r--r--graphics/asymptote/tests/array/delete.asy41
-rw-r--r--graphics/asymptote/tests/array/determinant.asy18
-rw-r--r--graphics/asymptote/tests/array/fields.asy103
-rw-r--r--graphics/asymptote/tests/array/slice.asy232
-rw-r--r--graphics/asymptote/tests/array/solve.asy35
-rw-r--r--graphics/asymptote/tests/array/sort.asy39
-rw-r--r--graphics/asymptote/tests/array/transpose.asy55
-rw-r--r--graphics/asymptote/tests/bench/6000circles.asy17
-rw-r--r--graphics/asymptote/tests/frames/loop.asy196
-rw-r--r--graphics/asymptote/tests/frames/stat.asy14
-rw-r--r--graphics/asymptote/tests/frames/stat2.asy17
-rw-r--r--graphics/asymptote/tests/gc/array.asy5
-rw-r--r--graphics/asymptote/tests/gc/file.asy7
-rw-r--r--graphics/asymptote/tests/gc/funcall.asy6
-rw-r--r--graphics/asymptote/tests/gc/guide.asy5
-rw-r--r--graphics/asymptote/tests/gc/label.asy8
-rw-r--r--graphics/asymptote/tests/gc/path.asy8
-rw-r--r--graphics/asymptote/tests/gc/pen.asy4
-rw-r--r--graphics/asymptote/tests/gc/shipout.asy11
-rw-r--r--graphics/asymptote/tests/gc/string.asy6
-rw-r--r--graphics/asymptote/tests/gc/struct.asy7
-rw-r--r--graphics/asymptote/tests/gc/transform.asy6
-rw-r--r--graphics/asymptote/tests/gs/ghostscript.asy14
-rw-r--r--graphics/asymptote/tests/gsl/random.asy338
-rw-r--r--graphics/asymptote/tests/imp/unravel.asy95
-rw-r--r--graphics/asymptote/tests/output/Makefile41
-rw-r--r--graphics/asymptote/tests/output/circle.asy1
-rw-r--r--graphics/asymptote/tests/output/line.asy1
-rw-r--r--graphics/asymptote/tests/pic/trans.asy75
-rw-r--r--graphics/asymptote/tests/string/erase.asy9
-rw-r--r--graphics/asymptote/tests/string/find.asy8
-rw-r--r--graphics/asymptote/tests/string/insert.asy5
-rw-r--r--graphics/asymptote/tests/string/length.asy6
-rw-r--r--graphics/asymptote/tests/string/rfind.asy8
-rw-r--r--graphics/asymptote/tests/string/substr.asy6
-rw-r--r--graphics/asymptote/tests/types/cast.asy13
-rw-r--r--graphics/asymptote/tests/types/constructor.asy380
-rw-r--r--graphics/asymptote/tests/types/ecast.asy11
-rw-r--r--graphics/asymptote/tests/types/guide.asy160
-rw-r--r--graphics/asymptote/tests/types/init.asy17
-rw-r--r--graphics/asymptote/tests/types/keyword.asy190
-rw-r--r--graphics/asymptote/tests/types/order.asy165
-rw-r--r--graphics/asymptote/tests/types/resolve.asy157
-rw-r--r--graphics/asymptote/tests/types/shadow.asy17
-rw-r--r--graphics/asymptote/tests/types/spec.asy61
-rw-r--r--graphics/asymptote/tests/types/var.asy86
-rw-r--r--graphics/asymptote/texfile.cc735
-rw-r--r--graphics/asymptote/texfile.h383
-rw-r--r--graphics/asymptote/tr.cc438
-rw-r--r--graphics/asymptote/tr.h167
-rw-r--r--graphics/asymptote/transform.h256
-rw-r--r--graphics/asymptote/triple.h365
-rw-r--r--graphics/asymptote/types.cc556
-rw-r--r--graphics/asymptote/types.h655
-rw-r--r--graphics/asymptote/util.cc444
-rw-r--r--graphics/asymptote/util.h163
-rw-r--r--graphics/asymptote/varinit.cc80
-rw-r--r--graphics/asymptote/varinit.h87
-rw-r--r--graphics/asymptote/virtualfieldaccess.cc45
-rw-r--r--graphics/asymptote/virtualfieldaccess.h62
-rw-r--r--graphics/asymptote/vm.h39
-rwxr-xr-xgraphics/asymptote/wce11
-rw-r--r--graphics/asymptote/webgl/WebGLfooter.html17
-rw-r--r--graphics/asymptote/webgl/WebGLheader.html172
-rw-r--r--graphics/asymptote/webgl/arcball-0.01.js67
-rw-r--r--graphics/asymptote/webgl/arcball-min-0.01.js1
-rw-r--r--graphics/asymptote/webgl/arcball.js67
-rw-r--r--graphics/asymptote/webgl/data.js47
-rw-r--r--graphics/asymptote/webgl/gl-0.01.js738
-rw-r--r--graphics/asymptote/webgl/gl-matrix-min-2.3.2.js29
-rw-r--r--graphics/asymptote/webgl/gl.js922
-rw-r--r--graphics/asymptote/webgl/glm-js-min-2.2.2.js273
-rw-r--r--graphics/asymptote/xstream.h260
921 files changed, 333908 insertions, 0 deletions
diff --git a/graphics/asymptote/BUGS b/graphics/asymptote/BUGS
new file mode 100644
index 0000000000..06febe85d4
--- /dev/null
+++ b/graphics/asymptote/BUGS
@@ -0,0 +1,6 @@
+If you find a bug in Asymptote, please check (if possible) whether the bug
+is still present in the latest git developmental code before submitting a
+bug report.
+
+New bugs can be submitted using the Bug Tracking System at
+http://asymptote.sourceforge.net/
diff --git a/graphics/asymptote/ChangeLog b/graphics/asymptote/ChangeLog
new file mode 100644
index 0000000000..e329086041
--- /dev/null
+++ b/graphics/asymptote/ChangeLog
@@ -0,0 +1,44327 @@
+commit 35867d43297d07045d52916bcd3d906f62f7b023
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 20 22:50:54 2019 -0600
+
+ Update example.
+
+commit 6570978b49f65c708ea8921ca5fd95a1dab0954b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 20 22:06:06 2019 -0600
+
+ Improve diagnostic about unimplemented feature.
+
+commit d741dd1701c53b6ab697b75bc280ced837611669
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 20 16:49:25 2019 -0600
+
+ Fix memory leak.
+
+commit 767b059789cd375336d6f2ad42f5c49a9b7d387e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 20 14:52:15 2019 -0600
+
+ Check for lgamma instead of gamma, in both libm and libc.
+
+commit d12068ef272111b0831187f2906fecaca1b5fa9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 20 14:10:23 2019 -0600
+
+ Use gc_allocator_ignore_off_page.
+
+commit ea6ec5dc839626629062044ae9291f1289875aeb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 20 14:03:43 2019 -0600
+
+ Only initialize glew once.
+
+commit 437acdd38d4c73eaabf8b52f3cec77247b58fe91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 20 12:44:19 2019 -0600
+
+ Update gc tests.
+
+commit f01f7ed4f10ee092be2208e8e3fd63f11d1cd6ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 19 03:33:53 2019 -0600
+
+ Fix gc struct test.
+
+commit bd88b6dcd02dd442a9765195f28502ee9255490c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 15 23:22:19 2019 -0600
+
+ Disable bulky and leaky OpenImageIO library by default.
+
+commit d84dd8cb79c8b0b85211643427eaa6ad1dba0a99
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 14 12:15:13 2019 -0600
+
+ Add in development WebGL version.
+
+commit 94ac15f88e5723e38d4e4f3231944b538d8c17ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 14 01:36:04 2019 -0600
+
+ Fix operator *(transform, revolution).
+
+commit fbef675f843d99f46475fbe92a01fe214a03d146
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 14 00:39:44 2019 -0600
+
+ Fix skeletons of transformed solids of revolution.
+
+commit f4ac68fd0660655a055c3bc41115e8f8a7752d8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 13 19:29:04 2019 -0600
+
+ Fix documentation.
+
+commit c694474b38ecb4057cb6380441732a6a2bb6018d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 13 18:02:47 2019 -0600
+
+ Add border to OpenGL tiles to remove antialiasing artifacts.
+
+commit 74172faf075afc446556df90acf3966931e82679
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 13 10:24:29 2019 -0600
+
+ Remove obsolete MacOS X workaround.
+
+commit 05f68ab80e7caa521c967b32ba672fa58bcaae3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 12 00:49:22 2019 -0600
+
+ Fix DEFINE calls in configure.ac; simplify compilation under CYGWIN.
+
+commit 38280e0f75fedc2fe9e9cc1b3e5336d05bba6e56
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 11 23:56:34 2019 -0600
+
+ Prioritize tr/unorderedmap over unorderedmap (for Centos 7).
+
+commit 64121726ecd13cda057699758020d7e94c289465
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 11 23:08:15 2019 -0600
+
+ Handle oblique projections as orthographic projections in PRC.
+
+commit 557ff750b0043c3bce5fc998bf601211c7bcafa5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 11 00:37:06 2019 -0600
+
+ Simplify code.
+
+commit 7c4367160de72d618382f5a164078a11d9d07edc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 03:30:03 2019 -0600
+
+ Increment version to 2.53.
+
+commit c1db74235565570e829b865756794a0c5ab0f5fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 02:23:28 2019 -0600
+
+ Fix xasy permissions; update old code.
+
+commit b14c49397f59c29929cd21a9da855b1f89b5566a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 01:44:11 2019 -0600
+
+ Fix spelling of default.
+
+commit 6506b94d5b6d97191ce9e26018c414d4d010e6fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 01:36:02 2019 -0600
+
+ Revert "Prevent xasy menubar from disappearing under MacOS X."
+
+ This reverts commit 40407fc4644a21e04ad77680939ab48281ad34d8.
+
+commit 27d51ec09bb95fe5c18181a807174b65ebbdd487
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 01:33:44 2019 -0600
+
+ Support VISUAL, EDITOR, and os-specific xasy editor overrides.
+
+commit deebce8021396aa35fb95786099e55c0ee24072c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 01:31:17 2019 -0600
+
+ Update documentation.
+
+commit b7586ef668e8701b5358da1a1d5ab29e226525fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 01:30:40 2019 -0600
+
+ Use open as default PostScript previewer under MacOS X.
+
+commit 40407fc4644a21e04ad77680939ab48281ad34d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 9 01:04:54 2019 -0600
+
+ Prevent xasy menubar from disappearing under MacOS X.
+
+commit 4f11b34a79a5a95ee6df1cc160502eca1d80ac04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 8 19:50:11 2019 -0600
+
+ Fix spelling of hexadecimal.
+
+commit c79584995e095c4736fae67060618577285f253d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 8 18:45:05 2019 -0600
+
+ Fix GLSL shader initialization on MacOS X.
+
+commit 03f7b5ac9e6a814bb5dd720209f68c5eb76933a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 8 18:18:05 2019 -0600
+
+ Remove obsolete code.
+
+commit 887964b07bc000c7d840d18370cded3561bdd263
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 7 10:38:46 2019 -0600
+
+ Don't attempt to install GUI files if unavailable (due to lack of pyuic5 and pyrcc5).
+
+commit c258b9a21580aeb09e68b9109977ee1382b2b3ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 6 23:58:18 2019 -0600
+
+ Remove obsolete assignment.
+
+commit 8a4f415210836d1893e9eb51b0afeebc37c63711
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 6 19:24:18 2019 -0600
+
+ Request OpenGL core profile under MacOS X.
+
+commit 6ee0cb2f03140555c09d5a0d9af62c51acd21d33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 6 06:00:03 2019 -0600
+
+ Remove obsolete code from tr.cc.
+
+commit e36a9fc91abe8e9fd55997c86a26d68f16084c03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 17:02:26 2019 -0600
+
+ Increment version to 2.52.
+
+commit e0b0d417fb075bc210ce7ddc9f192912e8bab4dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 16:05:15 2019 -0600
+
+ Fix warning messages during MSDOS glew build.
+
+commit 5aca47b4bf18d804339f3179680ff564161ec0a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 15:37:31 2019 -0600
+
+ Update documentation.
+
+commit 18385f310b42ae623c16445c6d9fd0cb3d04b986
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 15:06:20 2019 -0600
+
+ Pass CPPFLAGS to glew compilation.
+
+commit 9427bc84b0bc526a7243a878c4177e7d3d68abfc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 14:25:58 2019 -0600
+
+ LONG_LONG_MAX is now called LLONG_MAX.
+
+commit 68d5e6143a5a79c1b1f8ec3489cb826ca9a263cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 14:02:28 2019 -0600
+
+ Conditionally compile glew.c without modifying original source.
+
+commit 514c2c899382e17095a1fcda124400da6f539d7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 13:57:41 2019 -0600
+
+ Revert "Conditionally compile glew.c."
+
+ This reverts commit 2c499e90ee421b20dd2a53382396bcb4dc8818f1.
+
+commit 50546458facf5c8d09f3fbf41ddfd2d3e5b6bef2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 13:57:28 2019 -0600
+
+ Upgrade CTAN version to -std=c++11.
+
+commit 2c499e90ee421b20dd2a53382396bcb4dc8818f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 12:14:31 2019 -0600
+
+ Conditionally compile glew.c.
+
+commit 0f332f7a20509a269f5037e74973803079d72714
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 11:51:47 2019 -0600
+
+ Fix glew compilation.
+
+commit 04bce42baea1592ecd8a7155915bc4cf5176a267
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 5 11:41:08 2019 -0600
+
+ Add further portability tweaks.
+
+commit 0054ed2dc46f367a6c5f516d2b472c92107fb0d5
+Author: Mojca Miklavec <mojca@macports.org>
+Date: Mon Aug 5 18:14:46 2019 +0200
+
+ Allow overriding binaries in Makefile (#106)
+
+commit 45b349053b50d2f7478599b1a81724d0a8974edb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 4 12:13:03 2019 -0600
+
+ Simplify code.
+
+commit ce79ba79dc84aa6a5f31ce8fb0239b3ea302f35f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 4 12:02:55 2019 -0600
+
+ Fix OpenImageIO configuration.
+
+commit 4c4de50a1dd5fa6e07d0a7893b4bc93719bedf3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 4 02:26:07 2019 -0600
+
+ Increment version to 2.51.
+
+commit a1c421bbf65f1443829a422a8fe2dc329fba7072
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 4 01:26:38 2019 -0600
+
+ Add support for OpenGL under 32-bit MSWindows.
+
+commit 85db520f0e8b0bc1ed6d2cad21e8b94c33b001ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 4 00:09:18 2019 -0600
+
+ Remove unused code.
+
+commit 9a473b89f9131170c3c403f16a351083ad8f7e1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 23:58:56 2019 -0600
+
+ Remove ambientpen from example.
+
+commit 1720b45b628b0b8ae49370ac27a260317dddf009
+Author: Ivan Kokan <ivan.kokan@gmail.com>
+Date: Sun Aug 4 07:41:34 2019 +0200
+
+ Configurable filltype for dot (#43)
+
+ Add global dotfilltype; update documentation.
+
+commit ae3f32685507a92dc1cd26f6d154500a30cd38e7
+Author: Ivan Kokan <ivan.kokan@gmail.com>
+Date: Sun Aug 4 07:39:09 2019 +0200
+
+ Dot rendering details (#55)
+
+ Handle zero-sized dot radii.
+
+commit a98cceebf82a2cee9a3526a909fc1435888e81bc
+Merge: 69218e14 4bfc7889
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 21:10:42 2019 -0600
+
+ Merge pull request #86 from fahasch/master
+
+ Palettes from matplotlib
+
+commit 69218e14b92b8070f87ec9460f982673c8974c65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 13:57:23 2019 -0600
+
+ Fix typo.
+
+commit 781e34f265e0b47ca4a3a3444cf01d2e669db833
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 13:49:44 2019 -0600
+
+ Port to CYGWIN.
+
+commit b4ae8b40c452cad712f1ffbf9f00751a48fa77db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 13:12:12 2019 -0600
+
+ Add glm-devel dependency.
+
+commit fe965b2a2e81c778a5d0c11b9dfdd0c180796922
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 13:10:08 2019 -0600
+
+ Check for pow but don't provide a subsittute.
+
+commit 1748a5633a987093f2d410199eebfd2cd999cdf3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 13:08:27 2019 -0600
+
+ Remove spurious diagnostic.
+
+commit 2be1ec77c239257f8ccf3a7fa7013dabec4d5b63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 13:05:44 2019 -0600
+
+ Remove incomplete pow substitute.
+
+commit 78a4b62302fa4386560c3b3968cabb15c7585a0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 12:15:54 2019 -0600
+
+ Make GC_ATTR_EXPLICIT work around conditional on clang not FreeBSD.
+
+commit 743334a0dedbd5b6c8e743cb0c54545fb30c4bfb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 10:07:14 2019 -0600
+
+ Work around Boehm gc issue 273 under FreeBSD.
+
+commit 359b90a299cc19fcb3c503c3d593e0f2dc5aa4e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 02:43:00 2019 -0600
+
+ Remove unused code.
+
+commit 9d8e1801af9cb433ac179de5462609f1a34922fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 02:42:13 2019 -0600
+
+ Workaround gc and signal issues on FreeBSD.
+
+commit ca40beada902c965d53badfb33bd99b1f5459f9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 02:18:33 2019 -0600
+
+ Fix interactive mode.
+
+commit a10490793d6c0baffd8dd1fcd8718f45b4158d64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 21:36:34 2019 -0600
+
+ Missing glm header now triggers lack of OpenGL configuration notification.
+
+commit 3261c4bd2ea33923376d14611394921d799e2368
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 20:18:29 2019 -0600
+
+ Fix pow workaround.
+
+commit 059db65f5b5c756fcad8ddf1ad8332358ae41c1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 3 10:26:27 2019 +1000
+
+ Configuring with --enable-static first tests to see if static library is available.
+
+commit cebae1a87628c7ee4f619c9e0e2df85895d98fd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 17:02:29 2019 +1000
+
+ Remove dependency on glew-devel.
+
+commit 06c1776ad3d58440af99aac0e2cc7aaf515aaa13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 17:00:13 2019 +1000
+
+ Add missing GL/glxew.h header.
+
+commit f65ed736157ecf58bf395fb622fefd5ca0a0924b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 16:47:51 2019 +1000
+
+ Update glew.h references.
+
+commit 05a21753fe720d24dc55396e93a3d64a650ae59e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 00:43:57 2019 -0600
+
+ Fix glew header location.
+
+commit fa1e8192e86b2f364d3d320e144fb1fcde2631cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 00:23:13 2019 -0600
+
+ Add missing glew dependency.
+
+commit 5158adb4045d55e72fc0fb3fc99953a688d2f07d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 00:14:24 2019 -0600
+
+ Fix detection of glut library.
+
+commit fc3d2d13dad21602bddb1bd172113589f50d9f3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 2 00:12:22 2019 -0600
+
+ Ship version 2.1.0 of glew with asy.
+
+commit 2e9bda8a8c6a9b625d73262d1adbc60c6df33054
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 1 00:28:02 2019 -0600
+
+ Fix typo.
+
+commit ea5fe75642a3c1a929b70fc1507f628b7c62ab41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 1 00:21:40 2019 -0600
+
+ Fix missing config.h symbols.
+
+commit 273442954154c540bd73d7c906e9a4fed05629b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 31 12:31:31 2019 -0600
+
+ Enable static linking of libGLEW.
+
+commit 8300225a30975fe61b6ef43c29e8b56b400cfe09
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 31 12:12:27 2019 -0600
+
+ Add option for linking against certain static libraries.
+
+commit 3a87ccaf58bc2d3c3875f687fa0725d51d0ee89b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 30 09:37:25 2019 -0600
+
+ Fix confusing signature.
+
+commit 714371587643f770febae01cd9a81f87818e28e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 29 23:32:29 2019 -0600
+
+ Remove obsolete ambient parameter.
+
+commit 2aad7c815d6712bc1c617600c48bfb57f7ae2b8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 29 22:39:33 2019 -0600
+
+ Fix portability issues.
+
+commit 22a23a6c4acb1105653f2b140be20eb5e57a16c6
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 29 19:44:51 2019 -0600
+
+ Fix fragment shader.
+
+commit 486071f481eb83fc1f93cff9d2c3d0b97bc4df8e
+Merge: ffd8ced7 37ca4019
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 29 19:30:14 2019 -0600
+
+ Merge in glpbr.
+
+commit 37ca40193bf67f729e0d95a0cdf8b7d5747a98e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 30 11:08:43 2019 +1000
+
+ Simplify code.
+
+commit 48ef58767aa980cf9fe609c7e2fe14b4b6e8ee6f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 30 11:04:34 2019 +1000
+
+ Implement pixel shader.
+
+commit c0584280340c6c7ec1809827246ede7e04b12cd5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 30 10:23:48 2019 +1000
+
+ Add NORMAL option to shaders.
+
+commit 9ceffe0a758b07ace814256a3ee8eeafb7b0de1d
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 26 19:31:36 2019 -0600
+
+ Clean up shaders (from b18d965e22d159346c6454f18e80f00ea72418fc).
+
+commit 2363fce1f65c43d3c28674ad157a027b8d65a51e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 30 09:20:21 2019 +1000
+
+ Simplify shaders.
+
+commit 21016830d75d4313c62cafd972cbe6c6317ceed0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 27 17:53:03 2019 -0600
+
+ Batch multiple pixels.
+
+commit a6494727f7a7f7f8cc371b16d94f7179871325c5
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 26 20:19:21 2019 -0600
+
+ Remesh when reshape.
+
+commit ec62821d7b599cc405400893ca245815a111343c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 27 09:15:10 2019 +1000
+
+ Remesh only when needed.
+
+commit bc17bfd12f778ec540ea1374506394b226878b2d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 27 09:13:55 2019 +1000
+
+ Update URL.
+
+commit 077e196557106919b5926e8753abda2541b83d3a
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 22 14:55:42 2019 -0600
+
+ Set explicit ambient and emissive to zero.
+
+commit ecd523060fa7c09ea40226ccb322d1cd0c804ca2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 19 15:39:32 2019 -0600
+
+ Make FPS diagnostic display running mean and standard deviation.
+
+commit 76c05aae9ae5f551578d9fd9dea909f025b55527
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 28 09:38:52 2019 -0600
+
+ Remove unused code.
+
+commit 42d66ed8c0873583f555cb9c34c3eb741fa9ec48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 27 00:27:48 2019 -0600
+
+ Fix vertex shading.
+
+commit 26e629266fbd885ea86566c2a346e8adc9ce6cd0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 27 00:23:24 2019 -0600
+
+ Move normMat back to vertex.glsl.
+
+commit ffd8ced79178129cf9f463ff96c046d15f0162f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 27 00:18:52 2019 -0600
+
+ Move normMat back to vertex.glsl.
+
+commit bcbb081d26b4d865cf694edf36147947f21f3f9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 26 18:08:01 2019 -0600
+
+ Improve numerical precision of normal calculation.
+
+commit d75eece8df0b13903d5f544a95ee35638773ac41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 26 17:36:22 2019 -0600
+
+ Improve numerical precision of normal calculation.
+
+commit 7fa7340544d8611647e482b8dbf1209cf9027838
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 22 14:36:51 2019 -0600
+
+ Add outline shaders.
+
+commit a31a2e97e9377e87d4a310877f66388a02b235ad
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 22 13:37:02 2019 -0600
+
+ Use twosided checking on fragment shader.
+
+commit a98ee44c0e9ab87f2a3cb8cc420ca98f856b3d9a
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 22 13:15:21 2019 -0600
+
+ Add basic geometry shader.
+
+commit bdbadd2a72ca8816932c235f49f4c574cba2dd05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 14 08:24:53 2019 -0600
+
+ Avoid duplicate definition of RANDOM_MAX.
+
+commit b8f24cec48954a3d6ecddf67cfbd3579a4700102
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 10 08:48:16 2019 -0600
+
+ Fix typo in configure.ac.
+
+commit df9b9879723ddf19b5c60cb8c7f33cacb80429da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 7 14:39:18 2019 -0600
+
+ Increase default shininess.
+
+commit 9548fca8a3209525e7e2aa3f9b2f5569df0a4137
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 4 18:19:24 2019 -0600
+
+ Re-enable transparency.
+
+commit 5ccced67c49c7bee57bf794fd1c643b8b7ce3604
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 4 18:10:08 2019 -0600
+
+ Update fragment shader material.
+
+commit 76ec999c4bf3606cbccfa1721ebc20a2ab4f8a04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 4 17:57:55 2019 -0600
+
+ Simplify code.
+
+commit a20bfae054ca67b1567531de952a80608955d777
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 4 17:47:49 2019 -0600
+
+ Pack material floats in a vec4.
+
+commit 8fd7f10e9590568224daffcff34abee98d8cc0f2
+Merge: 81bba72d 549c3665
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jun 4 17:46:18 2019 -0600
+
+ Merge branch 'glupdate' of github.com:vectorgraphics/asymptote into glupdate
+
+commit 81bba72df18e0c389b97da1543956295f67692be
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jun 4 17:45:52 2019 -0600
+
+ Fix material color argument order.
+
+commit 549c3665c073877d5a619d4d82b57a3695e6ab1b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 4 17:07:58 2019 -0600
+
+ Fix padding.
+
+commit 356e8d01b8066ef014e777c9ec0e41a0997995e8
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 1 14:58:22 2019 -0600
+
+ Minor updates; tried Beckmann NDF.
+
+commit 24ccec91a0632d1b8799572339f8805065472f55
+Merge: ea6f3787 71f10dc1
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 28 14:43:14 2019 -0600
+
+ Merge pull request #97 from vectorgraphics/master.
+
+ Update glupdate branch from master.
+
+commit ea6f3787c17b1fa600093edc27b5823e682d6924
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 28 13:34:17 2019 -0600
+
+ Update todo.
+
+commit 63213532057c29df34b022cdbf2951e8364b9345
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 27 20:03:58 2019 -0600
+
+ Add in metallic/F0 option.
+
+commit 71f10dc1f8ebd3e696f87c220c3e9918ff3b80c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 26 22:56:21 2019 +1000
+
+ Detect gamma instead of sqrt function in libm.
+
+commit cc9be83022f3506b4adfc2c8face25532f40880f
+Merge: f4784eac b4884e1a
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 25 15:43:46 2019 -0600
+
+ Fix merge.
+
+commit f4784eac5f2a6da00a0d7d9b573eedbf836a8fa1
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 25 15:35:07 2019 -0600
+
+ Minor fix on ndef.
+
+commit b4884e1a06b14803332d771fda79d1724ede5882
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 25 15:40:13 2019 -0600
+
+ Fix matching braces.
+
+commit 848beeeaaf30a4323f250113c88bfbdcdc45875b
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 25 15:35:07 2019 -0600
+
+ Make environment map explicit.
+
+commit b66b16a184fe1177b2f66b8fbcd9626e2f8858c6
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 25 15:22:56 2019 -0600
+
+ Minor fixes in OIIO.
+
+commit fbc06f15929c395b3714323a67e0e5311e10682b
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 25 15:17:16 2019 -0600
+
+ Enable checking texture flag and experimental IBL.
+
+commit 5fcefde8e8d991c74f7d5962776d4a8fc1b9bee9
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 18 16:30:22 2019 -0600
+
+ Add usegl4 option.
+
+commit 06e51e8299f101628d1662fa363cd128a5fb7482
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 18 15:22:03 2019 -0600
+
+ Add in some notes on image files.
+
+commit a2092901986f6453aed451d2849107ad912f9e86
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 18 14:56:22 2019 -0600
+
+ Add the correct angle formula.
+
+commit b61333827cc39a20de3f1abbb032dd3b832c76c2
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun May 12 15:31:12 2019 -0600
+
+ Add loading texture.
+
+commit 1a35d3c9b5bd8ad9c5f3e74e9da91e9eab4593e3
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun May 12 14:51:25 2019 -0600
+
+ Add OpenImageIO library.
+
+commit b642331477ce96d38a0cb7b212acbcf2c7291c1a
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun May 12 14:35:20 2019 -0600
+
+ Add C++ property settings.
+
+commit 271020803bbea7704e4325cc618723d4381ef472
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun May 12 14:34:25 2019 -0600
+
+ Modify settings.
+
+commit d8d814cb6e54dc45532c8c1a896bfe797ca097e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 9 22:10:26 2019 -0600
+
+ Remove unused code.
+
+commit 5e9613851a98037de0317b2d5dd30680a594eb55
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 7 19:36:56 2019 -0600
+
+ Change metallic back to 0.
+
+commit ef4d2df309af70ac30e9c4a5659a2bdf9594cd84
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 7 19:35:53 2019 -0600
+
+ Fix normal flip in double-sided rendering.
+
+commit 7767056d25e35bf70f437d1134d5a52e64a81d3e
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 6 20:59:02 2019 -0600
+
+ Add some notes on material changes.
+
+commit 29369d96d32424b1bd16f1f0a60e4d883e82c45f
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 6 20:49:30 2019 -0600
+
+ Remove some variables.
+
+commit ab452eb2b668f22509c2ff57674c0bc286cbb8aa
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 6 20:44:14 2019 -0600
+
+ Add first version of PBR.
+
+commit e02cdd23128913a992e996cc2a7b7070568bc618
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat May 4 23:35:07 2019 -0600
+
+ Add debug configuration.
+
+commit e37826c1f792a6ba04254eeff56fe63258e293c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 2 16:38:07 2019 -0600
+
+ Fix warning messages.
+
+commit 6c6b5c8b02278de815b4351a18d99393b78bd16a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 2 16:35:25 2019 -0600
+
+ Fix warning messages.
+
+commit 7382b5a8016981d5503a3d3442903ac9ddf17e6f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 2 16:28:45 2019 -0600
+
+ Update fftw++; fix warning message.
+
+commit 8f641c83362c04460251f884493b1c3536274192
+Merge: abd3f761 43b43ae8
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Apr 26 12:35:50 2019 -0600
+
+ Merge pull request #94 from vectorgraphics/master
+
+ Merge master branch into glupdate.
+
+commit 43b43ae8fe3b4558a9086bd8343b490502acde4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 11 08:28:47 2019 -0600
+
+ Improve missing garbage collector instructions.
+
+commit 9eed805451ffaff7833ca86bd4a5dbea92cdf9d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 5 06:58:06 2019 -0600
+
+ Simplify code.
+
+commit 649e87c9a6ad587bf92c6aaf6bd16f2a2153a182
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 4 18:07:56 2019 -0600
+
+ Update GLEW and OSMesa paths for MacOSX.
+
+commit 1c8809563ba9f92f560f8da3284994a26c9c6c51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 2 11:39:43 2019 -0600
+
+ Update build script.
+
+commit ead3d5e9ae1e325738606d9f2420b39dfe48e4e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 2 11:11:56 2019 -0600
+
+ Increment version to 2.50.
+
+commit c53b4ef0bb51b4c022c580f912bbdfe3f2cb7c0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 2 10:01:46 2019 -0600
+
+ Update build script.
+
+commit 74dc51a9d28eefcc1d628aa580da443ceed015c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 2 09:54:01 2019 -0600
+
+ Fix fuzz and soccerball example.
+
+commit 1f92dbaf87bf93635fdb67f83e57268893707cec
+Merge: 211c791b 6fad4a32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 31 23:48:48 2019 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 211c791b7d64ff6c6c3060519b3a8d151835acc8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 31 13:10:44 2019 -0600
+
+ Update to Boehm gc-8.0.4.
+
+commit 6fad4a32d4b786782504b3368d0aa1ce13fbd4d5
+Merge: 819de76a d1d56093
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 31 10:23:57 2019 -0600
+
+ Merge pull request #92 from mojca/whitespace
+
+ Convert tabs to spaces in configure.ac.
+
+commit 819de76a7e70a382320efa7d0e3f32ee9255c3f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 31 10:08:27 2019 -0600
+
+ Remove unused code.
+
+commit 2df557185b5b5b335cc7a87cce3dd379cbfcf79a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 30 10:46:15 2019 -0600
+
+ Fix portablity issues; remove unused code.
+
+commit d1d560934374c253363567c8f36f2694cd3126c7
+Author: Mojca Miklavec <mojca.miklavec.lists@gmail.com>
+Date: Fri Mar 29 21:21:40 2019 +0100
+
+ Convert tabs to spaces in configure.ac.
+
+commit 404eda801e7f182649a37879c3aa2b7e60b2f143
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 28 13:26:04 2019 -0600
+
+ Address portability issue.
+
+commit 6d26cbff78572fe2cb4236eb57f65d59b6c44f31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 28 12:53:54 2019 -0600
+
+ Fix portabiliity issues.
+
+commit ecc393f7e8929beced0d903ca07c12262d27fbaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 27 01:33:28 2019 -0600
+
+ Increment version to 2.49.
+
+commit 54570f91bb95d024cd1ba37e46593f909edf0c62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 27 00:35:12 2019 -0600
+
+ Update examples.
+
+commit 7250a9576345bf7c1abac146871a18e1eaf9b06d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 27 00:28:18 2019 -0600
+
+ Fix fuzz usage.
+
+commit cc5346e91bbfa7f81178e04d22d9771157ed189b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 26 22:11:24 2019 -0600
+
+ Apply further workaround for broken MSWindows drivers for Intel GPU.
+
+commit f66446d81dd2aa529ed8eb8a8c164e7f7ad4a478
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 26 20:34:57 2019 -0600
+
+ Fix portability issues.
+
+commit 8f8011e03b60829a75a5aff6fe0348a07cb318ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 25 02:27:16 2019 -0600
+
+ Fix Makefile.
+
+commit 78eb88e287cb9e7897146c259920ac3832553612
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 24 15:43:55 2019 -0600
+
+ Support --disable-gc again.
+
+commit fd5b45ad85d63886f3b72540997acb8bf05f99a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 24 15:30:48 2019 -0600
+
+ Document material buffer sizes.
+
+commit 26a677733ff91348219775e89542c65130cdf200
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 24 15:16:17 2019 -0600
+
+ Reduce number of shader recompilations.
+
+commit 6539c75e327241401bcd532be89250d96179a47b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 24 15:09:55 2019 -0600
+
+ Rename shader files.
+
+commit 1833dcf8a1e8c80c27c64a975a23f9b06278105d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 24 12:22:50 2019 -0600
+
+ Fix lighting and material limits.
+
+commit 92ab2cf7bbf55e16c4e64cf0c67bb5bd12bff3f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 23 10:38:42 2019 -0600
+
+ Fix segmentation fault.
+
+commit 5ccc69edaae8b06db323a7db5d4812d89310ed1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 22 16:43:38 2019 -0600
+
+ Improve example.
+
+commit 6e2f7c547a6a0c634e55f7508b4ea4d5325aab72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 21 16:52:13 2019 -0600
+
+ Fix bug in f82e7672184f0b0ff91efd57a74a60269cd43ca2: update fuzz-dependent quantities.
+
+commit 4997b77e6d00dda91adef3741574b7bb41e09d87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 24 11:37:54 2019 -0700
+
+ Simplify code.
+
+commit 1cf5fcb7316084d1d71d12719d75364a0474bc9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 8 23:15:37 2019 -0700
+
+ Fix deletion of artifical variables; always use Bland's rule.
+
+commit a30061c913e099879a1c5250bc65cd7e718bcbce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 5 06:36:35 2019 +1100
+
+ Workaround broken MSWindows drivers for Intel GPU.
+
+commit 126a405dccfa51e6c1f1158c2f0084d54013ddc2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 5 06:33:02 2019 +1100
+
+ Fix drawpath3.
+
+commit 649ae913c25ee87dc0ce6226146e063703ddfc9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 5 02:02:40 2019 +1100
+
+ Place temporary cap on Nmaterials.
+
+commit d306a51bb1732cc420b9f1bdea0bc5a75ce820e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 3 19:25:24 2019 -0700
+
+ Fix MSDOS configuration.
+
+commit f8f4c113dd5ea56c1a3b47b3ad8926fda1792dd6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 3 00:26:23 2019 -0700
+
+ Implement maxvertices for working around OpenGL queueing limitations.
+
+commit b644f8df7bf867991fba1b4bfea3460db564affb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 2 12:01:17 2019 -0700
+
+ Simplify code.
+
+commit fe761482993f4c6e0dc22e68a8bb5e8cea553f23
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 2 11:39:15 2019 -0700
+
+ Simplify code.
+
+commit 4bfc78893a05e83d6698b349b24c3390872e903d
+Author: fahasch <fahasch@yahoo.de>
+Date: Sat Feb 2 12:02:42 2019 +0100
+
+ Palettes from matplotlib
+
+ For high quality density plots it is very important to have many well designed colormaps at hand. This module offer over 50 new colormaps. It has sequential colormaps, diverging colormaps, and cyclic colormaps.
+
+commit f82e7672184f0b0ff91efd57a74a60269cd43ca2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 27 22:08:40 2019 -0700
+
+ Speed up min, max, minratio, maxratio, and intersection calculations by increasing fuzz as depth decreases.
+
+commit e4283310b3fc84b838f233ee06b0c2b301264cc4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 27 20:45:15 2019 -0700
+
+ Fix Nmaterials.
+
+commit f8cd7d09dd1d3b6a0215338a71909deac4deecc2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 27 14:52:01 2019 -0700
+
+ Clear material buffer before it reaches GL_MAX_UNIFORM_BLOCK_SIZE.
+
+commit 0d057d35cb30d52f33db9f155c880ed8f8a1d7d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 27 14:49:57 2019 -0700
+
+ Suppress spurious SIGTERM.
+
+commit 8a2f965e64db8d2368abdb9ccd0a176b657b0c76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 21:21:36 2019 -0700
+
+ Restore examples.
+
+commit 2a69ec434b6924ef42b2338563b391e763b13ff0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 21:17:54 2019 -0700
+
+ Fix tiling.
+
+commit e7519239b74773e1757acf277df9a4f00c50880a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 20:48:41 2019 -0700
+
+ Integrate tesselation into batch drawing routine.
+
+commit 6673503f8b31a7d0ae9d840176d9a5dbe6dc7248
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 17:22:40 2019 -0700
+
+ Sort and draw transparent triangles in one batch.
+
+commit 20dd8537d4a48b966c3b81367beaf098e2ce277e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 14:13:57 2019 -0700
+
+ Pack explicit shader colors.
+
+commit ce1afeef0b1b6ce824ab81a50c1d3a6679fd5285
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 08:51:28 2019 -0700
+
+ Implement material index.
+
+commit 4fd60c4218faca42ae38fab86b50d56a0ff021a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 23 23:48:50 2019 -0700
+
+ Simplify code.
+
+commit d27ff2af8eabf82418005a24d5f07fffb502355b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 23 23:38:25 2019 -0700
+
+ Remove hard-coded number of lights.
+
+commit a0f18816ee21a814ef8b16e0b0f717c72a37f327
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 23 22:15:21 2019 -0700
+
+ Remove GL_ARB_gpu_shader5 requirement.
+
+commit 786f615ea087e0f542f9697c20ad460d5a0fac5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 23 20:46:19 2019 -0700
+
+ Downgrade to GLSL 1.30.
+
+commit 8506a29977e9437851759a59087b433a39f1c44a
+Merge: 1eb6fd84 f106987c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 23 19:30:40 2019 -0700
+
+ Merge branch 'master' into gl330.
+
+commit f106987c917bcb2f8b34cfc912fee88112b09bfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 23 19:25:23 2019 -0700
+
+ Port to MSDOS.
+
+commit da5f9d09aa48aabc16ac3aa9c3b5c5632805339d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 22 20:19:13 2019 -0700
+
+ Require OpenGL 4.30.
+
+commit 1eb6fd84f009dc32af52802d0445a4442a54a709
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 22 13:02:50 2019 -0700
+
+ Backport to OpenGL 3.3.
+
+commit a56ab24fb1fd8092bd67aaf03b29763045bfc19e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 21 22:35:22 2019 -0700
+
+ Update build-asymptote.dos.
+
+commit 26e6e567dd6a6d56538e76a1bc426f33ed29d20c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 21 22:11:51 2019 -0700
+
+ Add CYGWIN freeglut-3.0.0 patch.
+
+commit f66a3427010389d31135ef0e12a2c11f90952c7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 21 21:34:47 2019 -0700
+
+ Install and check for shaders.
+
+commit fdaeeb5d054b9c9faca7718fd5f695c1baeec722
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 21 06:40:16 2019 -0700
+
+ Port shader to MSDOS.
+
+commit 8393599bed33a1063411b9eeffb63b91898a468a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 21 00:03:42 2019 -0700
+
+ Port to MSDOS.
+
+commit 8b7207a65f759e98d9b6001aab3660e6670099ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 20 23:01:52 2019 -0500
+
+ Port to MSDOS.
+
+commit 59d7b37b61e628a9daa33dc9d79a74cceee40193
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 19 10:33:58 2019 -0700
+
+ Check for GLEW library during configuration.
+
+commit 37943204fdbbcefc995d7d6340e0bd17a3681c84
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 22:45:01 2019 -0700
+
+ More portability fixes.
+
+commit 652fb33c5c603caf77c9003d7badab95398e30dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 21:47:06 2019 -0700
+
+ Require only c++-11.
+
+commit 45edbf3b4a7fcece700576a00f5c46d275154c34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 17:51:58 2019 -0700
+
+ Remove unused code.
+
+commit b2b77e004ab3784e6ecc6dbefdeffa50eccb55e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 17:40:51 2019 -0700
+
+ Remove unused code.
+
+commit c9a6a08e1821480670fd8748b91f827c87af2e75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 17:36:24 2019 -0700
+
+ Remove unused include.
+
+commit 6ee6e8a6640158b7c85da16ea82e852e0fccebc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 15:26:45 2019 -0700
+
+ Update asymptote.spec.
+
+commit 9b1407e65518be9e8493dfe1a802b18d3052bfdb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 13:17:24 2019 -0700
+
+ Update build scripts to Boehm gc 8.0.2.
+
+commit 12b3a085dc52b79da46fa9cd6fb7b843980a4a32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 15 13:14:02 2019 -0700
+
+ Update to Boehm gc 8.0.2.
+
+commit abd3f7616ff00e5cc19fb9ebee0ed7f11d4c4367
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 13 22:00:48 2019 -0700
+
+ Use static attributes.
+
+commit b7c3a5ec50cf30be6edfc87bfafd1815fd7f16f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 13 21:40:47 2019 -0700
+
+ Fix lighting model. Specify all lights in viewport frame. Remove unused code.
+
+commit a2fb848f5944c8acca7a3425a5c14d1eaf3526fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 13 14:50:08 2019 -0700
+
+ Remove dependence on deprecated GLU library.
+
+commit ca9a12aac5107ffb21901569289a4e45fa8ff6c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 13 11:13:31 2019 -0700
+
+ Implement tesellation (many triangles) in new shader.
+
+commit cf60d572922a9708443683b8ffa610063bbca800
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 12 20:43:02 2019 -0700
+
+ Move lighting code out of setUniforms.
+
+commit 5126dd3e6eb1432ba0b60214b4a26de7f379e69e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 12 19:55:08 2019 -0700
+
+ Simplify code.
+
+commit 16213b13921e57381a87fd2f047c7e1c59458387
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 12 19:41:29 2019 -0700
+
+ Simplify code.
+
+commit c95d3ea1deed86a9b0af8db7b9ff81facab00d4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 12 19:09:35 2019 -0700
+
+ Remove arbitrary limit on number of lights.
+
+commit 2caa67789a014fd206bc55fab2587be538f739e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 10 21:06:14 2019 -0700
+
+ Fix pixel object.
+
+commit 52267dc8b614bbb8138ae6195efb4ceeba1e2e66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 9 23:38:04 2019 -0700
+
+ Port pixel to new shader.
+
+commit 8eacd6dc8b15fe1db7d1fb914f80d6887d9a74df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 9 21:26:13 2019 -0700
+
+ Fix segmentation fault.
+
+commit 626521dbed9479d9db083a0b6671acf8c8418282
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 9 21:16:58 2019 -0700
+
+ Move pixel code to drawpath3.
+
+commit db3a151d0b71d26c7134b604d972b095ff28adfb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 9 20:20:23 2019 -0700
+
+ Delete buffers on clear.
+
+commit 079c558a1f93f6cbff44fe80dfe57b1f4b7e4750
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 9 15:56:48 2019 -0700
+
+ Fix transparency.
+
+commit 9d9a790b03f5f276c5241503f2644942e6bc24b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 7 21:22:31 2019 -0700
+
+ Remove unused code.
+
+commit 0f58cdd6947cffce536a1aa2a96160baf3ea3aca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 7 21:17:07 2019 -0700
+
+ Simplify code.
+
+commit e26920c6ac62d6f335daae081428ff334a720c4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 7 21:11:49 2019 -0700
+
+ Remove unused code.
+
+commit 1048f4d87638aaca0793bb8a5c20be1cd630de54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 7 20:41:23 2019 -0700
+
+ Simplify code.
+
+commit ddeca77682ea6ef4da0fddbe7295c11e26b5286b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 22:53:28 2019 -0700
+
+ Use Phong-Blinn lighting model in shader.
+
+commit 0f43602199fca48d353477504f881acfdb1f426e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 22:52:07 2019 -0700
+
+ Update documentation.
+
+commit 29f0d3ccfbbbf8d7b0bc1bf81aa95859593288cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 16:34:20 2019 -0700
+
+ Remove unused code.
+
+commit 9671ef6f9c6d2ad6f78dc2c0e276fe5012c9509d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 20:11:00 2019 -0700
+
+ Remove menu due to incompatibility with new shader.
+
+commit d4048f9224de194a6587908b2fb3f01912e0d8ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 18:49:55 2019 -0700
+
+ Port Bezier curves to new shader.
+
+commit e13aa6c6c840e6cd45b2e39dace8bba8528a7714
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 12:37:38 2019 -0700
+
+ Reinstate sorting of transparent triangles.
+
+commit eb8fe25a71efa3ec8cba807bfd1d30078bdc85c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 08:44:26 2019 -0700
+
+ Update documentation.
+
+commit 28bfc3a3b786de71c0e93069f0d2f3c18d2e7324
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 07:26:00 2019 -0700
+
+ Fix tiling.
+
+commit 7b1fe1f3f4c173029f1759a5b1c337540e85437f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 07:00:07 2019 -0700
+
+ Remove remaining GL_MODELVIEW_MATRIX usages.
+
+commit 67873c000568b82a1caa4df5c748dc57bafa878b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 3 21:04:43 2019 -0700
+
+ Remove unused code.
+
+commit 6836efe332e30b94c8c41e63899fac3a319a2f16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 3 20:57:21 2019 -0700
+
+ Do camera calculations in double precision.
+
+commit 60d2c0e07174e2050af00236e286bdfac9c191ca
+Merge: 6d6a6535 aa08fb34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 1 21:32:41 2019 -0700
+
+ Merge branch 'master' into glupdate.
+
+commit aa08fb34573824b7fa939cfaeddce802d8990e03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 1 21:27:40 2019 -0700
+
+ Disable experimental offscreen rendering by default due to NVIDIA conflicts.
+
+commit 44f31905cdaafd6cd64d94be4a487eb4d24b401c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 28 02:20:16 2018 -0700
+
+ Fix ghostscript arguments.
+
+commit 60acb54ca61ba808d64aa0e28c1c64c853380083
+Merge: d98f3793 5fb1fecb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 28 01:40:44 2018 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote.
+
+commit d98f3793c4df96dcae238312aac889502912872d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 28 01:40:11 2018 -0700
+
+ Implement workaround for Ghostscript transparency extension -dSAFER bug.
+
+commit 5fb1fecb5fa11508c216d2fa39cf4eac247f5254
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Dec 24 16:44:56 2018 -0700
+
+ Add EOL marker.
+
+commit 6d6a65354125d6beef1e7115b4f9127f09ee559c
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Dec 21 15:45:15 2018 -0700
+
+ Fix last commit on struct data.
+
+commit 5655f851d3762a80c559078bba9c9899c37f9c90
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Dec 21 15:44:52 2018 -0700
+
+ Centralize render data exchange.
+
+commit 25ccee4d0fb257c223f786bfd151583a32c1aa2b
+Merge: 25668b72 924bd6b1
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Dec 21 15:15:25 2018 -0700
+
+ Merge branch 'glupdate' of github.com:vectorgraphics/asymptote into glupdate
+
+commit 25668b728a8b77c54fa428fb23ceec106e6c2562
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Dec 21 15:15:21 2018 -0700
+
+ Update modelViewMatrix linkage.
+
+commit 924bd6b1d9586ff8c2ce15a070826c20a1660be4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 21 13:12:43 2018 -0700
+
+ Use standard asy search path to locate shaders.
+
+commit 0a42fbde8f86592dc888ecc58abf37c4c4d3bc3b
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Dec 20 17:03:58 2018 -0700
+
+ Fix ModelView Matrix.
+
+commit d1fbe2c9df2b00d7556309a8fd53866fa75a9e8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 20 16:15:00 2018 -0700
+
+ Fix dual simplex exit conditions.
+
+commit 32b00922c75c6c4221b58ed91ff50a2f7ae1cbd0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 15 19:10:04 2018 -0700
+
+ Add missing dual argument.
+
+commit 4da31b4727444458a041c36e9e36ad772614b87c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 15 19:09:09 2018 -0700
+
+ Fix phase1=false and dual modes.
+
+commit 634f7476ea373a8dac95c537436fbcf73c7cfdbd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 15 10:32:46 2018 -0700
+
+ Fix phase1=false optimization. Add support for dual simplex method.
+
+commit 64f568fe2ef00b8873ff06405d708502a6273d19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 13 20:31:27 2018 -0700
+
+ Improve diagnostics.
+
+commit 3c6736096056c8c26d092c5d71d0987a17b66b41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 13 15:38:20 2018 -0700
+
+ Fix position of diagnostic.
+
+commit 280d717c9c870cf66f01f324472d2de1424aeeab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 14 07:52:02 2018 +1100
+
+ Drive artificial variables out of basis.
+
+commit 2113adb6f8ba236eb7ce08d76a464f52e3b3bb3b
+Merge: 494cf1d0 f3da29c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 4 15:58:18 2018 -0700
+
+ Merge branch 'glupdate' of github.com:vectorgraphics/asymptote into glupdate
+
+commit f3da29c7a4ab507d998fdb2977956ecdb764c22f
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Dec 4 15:49:49 2018 -0700
+
+ Remove glext.h and add GLEW library.
+
+commit ffabb72fdf2df5753e9d60535a9eb13fe23534f8
+Merge: 0dbed3fc 632607db
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Dec 2 14:17:53 2018 -0700
+
+ Merge branch 'master' into glupdate.
+
+commit 494cf1d0dc9f567d758377a1dab6f93617d63d10
+Merge: 0dbed3fc c69fb7d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 14:12:14 2018 -0700
+
+ Merge branch 'master' into glupdate.
+
+commit 0dbed3fc839e868febbecc278ef0d4672aa92314
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 22 17:18:40 2018 -0700
+
+ Reinstate Rotate matrix.
+
+commit c69fb7d6f4f9d058c18996b5fb4c6d9f3212b94c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 14 13:30:52 2018 -0700
+
+ Add pivot diagnostics support in rationalSimplex.asy.
+
+commit 632607db0ce948d3502d75274e8a12014f0e8aa1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 6 10:46:11 2018 -0700
+
+ Add diagnostics to rationalSimplex; use Bland's rule.
+
+commit 85000d2ee926bae8dbfd79d6b2daa11231fd112f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 09:17:42 2018 -0700
+
+ Fix phase1=false for standard-form interface.
+
+commit 4867651a75934de3a664acf4ffe14b34d4ee19e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 00:48:37 2018 -0600
+
+ Update documentation.
+
+commit 8e109fe1136926bc48f81a6ea3f44b96e9602967
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 00:46:18 2018 -0600
+
+ Fix and re-enable phase1 optimization; add missing rational operators.
+
+commit 38a59370dc5ac720c29e1424614a10f7384b943f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 3 07:24:39 2018 -0600
+
+ Port to gc-7.6.8.
+
+commit 743dcbd36624b682958c6e6fa5de808b0c871bd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 27 17:16:32 2018 -0600
+
+ Fix stroke=true bug.
+
+commit 5379d0cec0d774b532bd389c6268711adf2067a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 27 16:25:36 2018 -0600
+
+ Minor documentation edits.
+
+commit d9ee7b4bfe23f5355f9d62701599af00b242bc79
+Merge: c172ffeb 1b22b181
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 26 08:12:35 2018 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit c172ffeb32e1dad161688bac45fd96fe927dafa5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 26 08:12:24 2018 -0600
+
+ Handle zero counts.
+
+commit 1b22b1813f11bb9f9a2a9de7b70ad61eaffd136b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Sep 12 22:09:19 2018 -0600
+
+ Fix latexmkrc for Windows and add author's name.
+
+commit e86ee4696b6fb87c3e2cb8da76138867da789409
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Sep 8 17:39:14 2018 -0600
+
+ Fix latexmkrc URL.
+
+commit c2e37f99ab05001964c0271c9e693ac86fe88f54
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Sep 3 19:42:14 2018 -0600
+
+ Remove transformations from light direction.
+
+commit cf3f4d1e199cd8a9a460f9614446d2675b7fcbbe
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Sep 3 19:20:22 2018 -0600
+
+ Add basic blinn/phong model.
+
+commit c0640d76ee67f3266a2347e5b2f2bf142a4705e3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Sep 3 16:53:03 2018 -0600
+
+ Pass in material to GLSL.
+
+commit 427ff0d076dbc3f2edd6755d7b667c266a48d35b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Sep 2 19:35:08 2018 -0600
+
+ Add material struct.
+
+commit f52101d84f23e7111fc104f77f4e39213ce3a27c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Sep 2 18:47:27 2018 -0600
+
+ Fix trace ignore.
+
+commit b335d897196d24aaccdde3e99723e8d212c0d356
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Sep 1 22:26:17 2018 -0600
+
+ Finally add VAO as a requirement.
+
+commit d2996cbcac12ed9f5299e25f317d968c0c6e2e3e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Sep 1 21:27:38 2018 -0600
+
+ Fix VBO/EBO binding.
+
+commit 1fd9c7d384475bec22098a8e9fac39cb77e43f56
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Sep 1 17:16:25 2018 -0600
+
+ Allow for proper buffer data transfer.
+
+commit adbb32fdd380304839cb401c76ea2ab662edfe65
+Merge: 23c4bd2d df015058
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 17:57:46 2018 -0600
+
+ Merge branch 'webgl'.
+
+commit df015058a329bc2c50898673fb77ab63cb684239
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 17:56:58 2018 -0600
+
+ Rename webgl files.
+
+commit 23c4bd2d53cdc577eeed0cac28d73439eb4f3e84
+Merge: c41bc347 48fc03cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 17:33:40 2018 -0600
+
+ Merge branch 'webgl'.
+
+commit c41bc347ba6303190d0f5293507640eff7cc7a62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 17:28:21 2018 -0600
+
+ Create index.html
+
+commit 48fc03cf2cd9bb8d12de45fdc414daf9dc1e0ca0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 17:20:41 2018 -0600
+
+ Add WebGL files.
+
+commit a08121dc7deeda1a1cd3cbacbe52f95deba69ce0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 12:23:44 2018 -0600
+
+ Work around dvisvgm bound box lower threshold.
+
+commit fd66ec5e916f1c750ef7cfa7c40fda372fd1ab53
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 30 17:50:24 2018 -0600
+
+ Make rotation use glm::matx.
+
+commit 28ea1444cbe53b6e8be16597cb424f76b8a7d131
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Aug 30 00:35:00 2018 -0600
+
+ Get basic shader working.
+
+commit 1753e2fcf110add939514c4a743b7612045827bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 31 00:47:07 2018 +0200
+
+ Increment version to 2.48.
+
+commit 67f0c4b2d24adc346d7b616b13298903433c5910
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 23:23:47 2018 +0200
+
+ Minor optimization.
+
+commit 541b4014c2ad7fd63d845c3ffb6a33a6459c12eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 23:07:55 2018 +0200
+
+ Fix scaling (allow second variable in Simplex method to be negative).
+
+commit 28bc9c75a1393cceb0cb719881804615ec09f05f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 11:23:04 2018 +0200
+
+ Generate EPS only for single-page documents.
+
+commit 89d2c88c2945096e5d765e3d9fe76163f8f553e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 10:02:53 2018 +0200
+
+ Remove .vscode from releases.
+
+commit 39454327d81d169aa48fc25f6397afa0bba83be4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 09:57:43 2018 +0200
+
+ Remove unused files.
+
+commit 2157692a4b640473b188cdee545a431fea67e15b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 05:42:26 2018 +0200
+
+ Fix uptodate flag; remove spurious directory.
+
+commit aba57e58c0292a3298bc132298671814aeb67fc4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 04:42:23 2018 +0200
+
+ Fix URL in README.
+
+commit fa2aa36e9cea341aad6ab0e3bf49db93001069c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 04:33:10 2018 +0200
+
+ Fix bsp module.
+
+commit 22d2b8d37da35bf1d0d6a1ddf75e1db32885ede0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 13:22:04 2018 -0600
+
+ Increment version to 2.47.
+
+commit 4eee33bc01e444c03242eefbce091bed40d3f835
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 11:29:27 2018 -0600
+
+ Fix relative alignment under picture rotation.
+
+commit 9edc023b2c37d0ea50972c1ab784ee9e1e100d55
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 01:42:29 2018 -0600
+
+ Fix commit 451a260ae50d02867c1e54726a68d8af2c55761d.
+
+commit 451a260ae50d02867c1e54726a68d8af2c55761d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 28 09:35:16 2018 -0600
+
+ Fix shipout issues.
+
+commit ae6d9d312ab21212216960f56122ffe8e0c7fa2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 28 06:24:46 2018 -0600
+
+ Account for pen width in bbox.
+
+commit 3ea27282e2a79139cd5600ee31b8e1b451eb2d03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 02:02:17 2018 -0600
+
+ Don't use defaultGhostscriptLibrary location in MSWindows registry since TeXLive dvisvgm requires 32-bit version, even on 64-bit platforms.
+
+commit 3b49296799c14832747db90150d23067f946683a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 21 18:00:11 2018 -0600
+
+ Increment version to 2.46.
+
+commit 19dd6cc8027597d5e2ca25b07db2851d9771f03c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 21 15:37:27 2018 -0600
+
+ Revert "Update path."
+
+ This reverts commit f63df996a86c935c51e09c47fe9c0aa2a8d7dc2d.
+
+commit f63df996a86c935c51e09c47fe9c0aa2a8d7dc2d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 20 23:09:03 2018 -0600
+
+ Update path.
+
+commit 1734e7af6a018f27240fddd4e7bf14f569a09522
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 20 21:33:54 2018 -0600
+
+ Improve error message when rsvg-convert is missing.
+
+commit abd6347aea2faaa2862e3ebe34c7f85dd820c77d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 15:10:59 2018 -0600
+
+ Remove obsolete uuid code.
+
+commit b46eed584fea0e625f2cde3dab23c2522d3d2486
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 15:09:10 2018 -0600
+
+ Fix saveLocation.
+
+commit 87c39ea72263c68d5548da4941eda639f37fce22
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 14:59:32 2018 -0600
+
+ Use class instead of instance on item not existing.
+
+commit 721cc5cc84abe2351211262670f5091e66f33b7c
+Merge: ec53a266 5f95aa82
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 14:56:15 2018 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit ec53a266a170edcd94c8a070f4d5b4a028eba964
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 14:56:11 2018 -0600
+
+ Revert venn.
+
+commit b88d3d9df356db299150e59d4ee0ef0f5adf82bb
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 14:55:10 2018 -0600
+
+ Fix script not updating.
+
+commit 5f95aa8246f7976dfc17a522b66da4a4179833c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 14:52:25 2018 -0600
+
+ Simplify build script.
+
+commit 779b1b60d7b7fcfa35d48a946fa421db1be54a82
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 14:37:25 2018 -0600
+
+ Only write transformation if the rest of transf is not Id.
+
+commit 63f054012ad1716c8c0de04521ac0e66b81afadb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 14:28:51 2018 -0600
+
+ Remove 'x' key prefix.
+
+commit 0e351c95efca60034ec5d9397ab7924bf415f6ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 14:13:42 2018 -0600
+
+ Don't apply xmap without an explicit corresponding key.
+
+commit a7026b70bb0793696075d53f1a0dd683073acf82
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 14:01:43 2018 -0600
+
+ Update xasy documentation.
+
+commit 7e9954d1ab1043f03b5082266b1cef7a44091c89
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 13:58:41 2018 -0600
+
+ Fix zooming sign inversion.
+
+commit bd333b65cf24379797188e00c961cda229727e0e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 13:39:10 2018 -0600
+
+ Add zooming on arrow keys.
+
+commit 183b47c0f305f829cacaff28222bd1cf40523130
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 19 13:10:15 2018 -0600
+
+ Hook up/down to selection.
+
+commit 7a49eda58677c8d26fa8efbd8f946d80ac560c1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 14:58:59 2018 -0600
+
+ Transform directly from asy to image coordinates.
+
+commit 65f66b98a91f4dff78c1f6e769005c20b53e926c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 16 15:01:00 2018 -0600
+
+ Disable fill on open curve.
+
+commit 98d364235fdf5073c1dcf2f51c478f21e492de56
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 16 14:26:53 2018 -0600
+
+ Fix repeated asyfying.
+
+commit 0ad7327a11094d336057f6d21d99e1385e685c6c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 22:30:36 2018 -0600
+
+ Fix line shift by xmap.
+
+commit 360e165e00f0c304600a2371af6b5ffefeff89f8
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 21:00:02 2018 -0600
+
+ Revert venn.
+
+commit 42b192057a798825b8e1f5cf0939072cb4f2c116
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 20:58:31 2018 -0600
+
+ Only do change of basis if transform is not Id.
+
+commit ef89f277409805f8a7e65ba7b735b9ddb9bee93d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 20:49:13 2018 -0600
+
+ Fix transf on different basis.
+
+commit 76d1e66db7ecc1a550c73326b4ea34e65a2e4630
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 20:40:36 2018 -0600
+
+ Fix key load bug.
+
+commit 574c0d96364ccbea81810fcda44cff5b68a35dc6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 20:23:50 2018 -0600
+
+ Fix add label not working.
+
+commit 7d6cff54d91e978bd700188d09af2e3da1d66ead
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 17:20:15 2018 -0600
+
+ Force cleanup asy.
+
+commit 815e72d73eaa2af714ce157dc8cbc3363ad92cd5
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 15 17:14:41 2018 -0600
+
+ Fix duplicate key problem.
+
+commit b85a7d3b9e8ab18806ceb0ef39cc4f983a55f348
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 15 14:28:34 2018 -0600
+
+ Fix array bounds.
+
+commit 2c15d93e8ca19ea73ed1fb4186b3b3fc93520050
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 15 14:28:16 2018 -0600
+
+ Remove duplicate option.
+
+commit a070e8a6f9e3a3bef91a09fb0b9e192541a2a6bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 15 12:33:42 2018 -0600
+
+ Force dvisvgm to be silent.
+
+commit a8a7fea89b9ad8f7dbd02dac898301cfb0592257
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 14 11:31:58 2018 -0600
+
+ Don't resize 3D pictures.
+
+commit c928c92f88c8b3b0942dc9c12bc8244233045e11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 14 10:38:34 2018 -0600
+
+ Finish xasy port to MSDOS.
+
+commit cd700b4bb9db2b80f77aae8a316a99dd3476c7b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 14 10:38:06 2018 -0600
+
+ Redirect cerr to cout again when outpipe=2.
+
+commit f0bc292dd796329fdd39679b1852a6bff1159335
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 14 10:34:17 2018 -0600
+
+ Fix segmentation fault.
+
+commit e1f68286465d275a5677860950e266288ade44a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 12 15:13:59 2018 -0600
+
+ Port xasy to MSDOS.
+
+commit 7133ef53816e97ddb3b8e0870ffbfba9b95423b7
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 17:05:36 2018 -0600
+
+ Enable cycle control points.
+
+commit 1c444f8695301ae16bd8beb20778bd7fc14cc9cf
+Merge: 92d1e727 93a679de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 11 16:13:33 2018 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 93a679de2f2902618546bf86884217c4e8da9041
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 16:13:20 2018 -0600
+
+ Set line width inversely proportional to mag.
+
+commit 92d1e7272842f751bd3952f13efb365e2d100121
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 11 16:12:30 2018 -0600
+
+ Rename config files and commandPalette default keymap.
+
+commit cc93cbe1e79774062ab9fd741469c41e39600959
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 16:04:13 2018 -0600
+
+ Correctly fixes scaling with zoom.
+
+commit afad348e03eaf2e73cd606e4f008d7316bc52627
+Merge: 7f2a28a6 ad6faf30
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 16:02:35 2018 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 7f2a28a6042a401e314b2d865a16d03f02e91687
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 16:02:32 2018 -0600
+
+ Make selection scale with magnification.
+
+commit ad6faf30e81d3ea2f58c92536b967f8d7491c4e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 11 15:55:52 2018 -0600
+
+ Fix spelling.
+
+commit 1f383b4b5301c358b4867b692a26a2c3076e6268
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 15:51:31 2018 -0600
+
+ Fix typo again.
+
+commit 893f7fc2ee2e044395ead6215e1e53f195c8d82a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 15:51:20 2018 -0600
+
+ Fix spelling error.
+
+commit 38f428fa9fe837bca5a00df56b94dbf2f842c235
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 15:49:34 2018 -0600
+
+ Make filename a little more clear.
+
+commit a3f98621376f1c45988dff32191e6da5ad1b53b7
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 15:37:32 2018 -0600
+
+ Fix segfault again (?).
+
+commit ecb5b2db65438e7ba9c626014925ac291f5c1941
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 15:33:59 2018 -0600
+
+ Fix segfault (?).
+
+commit ab12f523ac4e6e52e312cd66e9f869c762779e46
+Merge: 2d24c9aa feefafd6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 11 15:29:04 2018 -0600
+
+ Merge in changes.
+
+commit feefafd64fdd5abdff99fdbdad523a1687ca34f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 11 13:55:32 2018 -0600
+
+ Fix asymptote.spec.
+
+commit 935f81064cf10fa83ad49303b0d74ad50cf9856b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 11 13:49:33 2018 -0600
+
+ Fix asymptote.spec.
+
+commit e65e004ca8c75e168c6c1ac3a44c609a34754f73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 11 13:45:59 2018 -0600
+
+ Use install-notexhash for building RPMs.
+
+commit bb1cf672f4d99dc1ecdad8826adefd916f1cc9f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 11 12:09:12 2018 -0600
+
+ Clean up icons; fix installation problems; port asymptote.py to Python 3.
+
+commit 2d24c9aadb12e6a35e7a840b07f20ced68c8e4a6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jul 10 14:34:39 2018 -0600
+
+ Remove even more unnessecary code.
+
+commit 3cd990f8d5f9bea582c34cb36eaf8da538046ab0
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jul 10 14:19:08 2018 -0600
+
+ Generate -- instead of.. when using polygon.
+
+commit 7edcc2f34fcb7551d23a272d7f1bd0b03d940ee7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 10 00:56:06 2018 -0600
+
+ Fix duplicate QPainter warning.
+
+commit d1dfb2a8af1c4c5a186a5e622cdc2e2fd9c0b90e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 9 17:29:42 2018 -0600
+
+ Reset fileChanged on erase.
+
+commit bff496158e93e677e7839e056f5da52129e11e55
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 9 17:19:43 2018 -0600
+
+ Add check before reopening file.
+
+commit 2ecb76750fe0ebc120684a076ac3a5b4ab9ce810
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 21:32:22 2018 -0600
+
+ Fix asymptote.spec.
+
+commit d67ec7242352fd97059022795846394ae36f5cbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 21:09:06 2018 -0600
+
+ Specify python3 explicitly.
+
+commit a2f95654b4deb7cbf779e8068090f201aa3468b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 20:46:48 2018 -0600
+
+ Read in xasy version.
+
+commit 94d4cd52647d433b1d13e5a96641c89f07203ebe
+Merge: de430749 770eea72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 17:06:00 2018 -0600
+
+ Merge branch 'qthup'.
+
+commit 770eea7237d039ee13b9f4b5adaa4a61e8e9297f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 15:27:45 2018 -0600
+
+ Erase canvas before opening new file.
+
+commit 6dba36575965266b3783f5a2bde8f5a65ab32451
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 8 13:06:47 2018 -0600
+
+ Automatically determine recomputation mode.
+
+commit 869d617084192cf799f0ec033b9ea31f74d6e07a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 8 12:59:14 2018 -0600
+
+ Preserve Edit Bezier Mode.
+
+commit e8bc45d003f489ccc50fc4461aa19d56da314421
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 8 12:55:02 2018 -0600
+
+ Update .gitignore
+
+commit eed85abcd5e3c2347d4ad1ab86a3d8e550cd3f72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 12:40:09 2018 -0600
+
+ Improve informational messages.
+
+commit d5de0e972bf7242d2572c2a5a7ff0ded40f85a1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 11:08:24 2018 -0600
+
+ Remove unused code.
+
+commit 63be5fe78ea461d3350277799528a78d01069189
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 11:01:25 2018 -0600
+
+ Standardize labels.
+
+commit 618439764c892c9b9b3b0ecbfc52358d3e0a2646
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 02:39:58 2018 -0600
+
+ Add missing actions; remove obsolete code; adjust layout.
+
+commit c2a3daa2e8a95ce104f7a8d828a4237274bd0188
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 00:11:27 2018 -0600
+
+ Add remaining icons.
+
+commit 2f894a654d48bf5479331dfb7b176605b8df0eb5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 7 17:30:04 2018 -0600
+
+ Add fill bucket icons.
+
+commit ae34291ff7f91f19a5b29e8d145600096c1d186f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 7 10:49:30 2018 -0600
+
+ Rerender only when dpi exceeds previous maximum dpi.
+
+commit 326766200c3deffe4392d737a92dadbf9591b0d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 6 16:38:38 2018 -0600
+
+ Fix clip flag.
+
+commit 1797d5f89eaa554d94d34d908e86858ae0d0fdb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 6 16:29:02 2018 -0600
+
+ Make rsvg-convert read directly from file.
+
+commit 4fdad9b276f93f32164d1ff4da30164720e97b11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 6 15:54:11 2018 -0600
+
+ Remove unused code.
+
+commit cde402ba0d3a491f235b75390fa6232d019eaada
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 6 15:47:13 2018 -0600
+
+ Switch from cairo to rsvg.
+
+commit 365189781fe14a3b74662a24d7c37424648893f2
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 6 15:16:39 2018 -0600
+
+ Reset current position when click.
+
+commit 8d89b3ad95c45507ab958eee08e50cb7a71d6de1
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 6 14:25:35 2018 -0600
+
+ Add more icons.
+
+commit e52e4040874c315a50baeaee22858527197e758e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 21:02:59 2018 -0600
+
+ Fix recenter not recognizing magnification.
+
+commit 54ad8477ed4821a59a8cd08eac741554152f124e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 20:53:48 2018 -0600
+
+ Fix zooming transform.
+
+commit 9f52c34396577ced844734728ac67278ea2dd21e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 5 17:18:41 2018 -0600
+
+ Fix tooltips.
+
+commit c961cabc5ec05e7b0475d54557f298feae6b8dca
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 17:00:26 2018 -0600
+
+ Remove add widget upon addmode deletion.
+
+commit 8543e26542f78f2d334b0eb6580d80cca3bca45e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 16:55:29 2018 -0600
+
+ Add remaining icons.
+
+commit 2ac5c23f2e1b32103ab49eae7b6797aaa5017512
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 15:32:49 2018 -0600
+
+ Enable pan-sensitive zooming.
+
+commit bf3cc0b9f763f4bf40cdc569db4d61d3f96a4f35
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 14:51:07 2018 -0600
+
+ Enables math mode detection in label.
+
+commit b8c2663e0fa1f0b0dc4c6cf41aec6af7aa9cc89e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 14:34:54 2018 -0600
+
+ Add centering pan.
+
+commit 388907330408dae455768900739219e4a9b3b42f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 5 13:48:16 2018 -0600
+
+ Add svg files.
+
+commit 7e9efcd61dcbe7cd0f45f437610e376fa9b4e2f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 4 19:36:24 2018 -0600
+
+ Add index entries integral and integration.
+
+commit 405ee9a7bc6eb61e0268fc23177eacbcf6563154
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 23:40:02 2018 -0600
+
+ Enable centering pan option.
+
+commit 046b50a837798f4fa406adb434e2794f5c260a5f
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 23:33:57 2018 -0600
+
+ Add fuzz to small bounding boxes.
+
+commit 15e7d80a69049825de0a8e0c5f88e0aac2076462
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 23:24:57 2018 -0600
+
+ Copy text to advanced editor.
+
+commit ddc3fd7c15507fa42a9aea8ef0ea4a5d95776b6c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 3 16:40:36 2018 -0600
+
+ Improve and enable Cairo clip-path bug workaround.
+
+commit af49fa9dd676f2453ed65aefe6fa6106eab2de9e
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 15:08:38 2018 -0600
+
+ Round points to 10e6 precision.
+
+commit a1086f1f2141a0ed5ca1ee23c0c982cca50d0a50
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 14:58:15 2018 -0600
+
+ Add fontsize for label.
+
+commit ccc3b79d26559b18d86a95e5bcf02478c1051f33
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 14:24:51 2018 -0600
+
+ Enable removal of unneeded clips.
+
+commit b6a25e25e9f586a39d9af6b287b0373a4b703dd1
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 14:01:18 2018 -0600
+
+ Remove unnessecary braces from label editor.
+
+commit b0b8525c6e71cb2643e0c3a96aaea35f2df6ed1d
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jul 3 13:57:46 2018 -0600
+
+ Improve scaling on small labels.
+
+commit d21d7c005dee4968a3af58a1de68bb26e0e4ead6
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jul 2 15:21:02 2018 -0600
+
+ Only insert non-identity keys.
+
+commit bd259097ea0c45835110d7d627a0eea174c0d38a
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jul 2 14:59:31 2018 -0600
+
+ Fix label location and more QoL improvments.
+
+commit a8c22de51d598fff1b008b8b89ae702d8e0dfd15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 2 11:35:44 2018 -0600
+
+ Switch xmap to asy coordinates.
+
+commit 9ec81262cff36972c91e523dfdc0fdc5a529e3c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 2 08:52:24 2018 -0600
+
+ Fix comment.
+
+commit 5a0588a23082a406cd718a71c6267d78cb9b4a0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 21:33:03 2018 -0600
+
+ Fix missing KEYs.
+
+commit 89ecbf116ccee69453179cdab48b0b633a5ff8bb
+Merge: 4463b94c 67c86cd4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 19:08:33 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 4463b94c5c887de3f8c1f269c33d2bc60dfa1979
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 17:12:32 2018 -0600
+
+ Resize to initial xasy transform.
+
+commit 67c86cd4113f13b275c87d890f5ab48f457808a7
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sun Jul 1 14:11:25 2018 -0600
+
+ Should fix key not writing.
+
+commit 716f8065bfb6d5ce0f0b52f3956df0f92787bb99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 10:38:24 2018 -0600
+
+ Make SaveAs default to current directory. Add Save action.
+
+commit 9763a3e172d35b1cb7c093695fcaededd29ca391
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 10:38:24 2018 -0600
+
+ Make SaveAs default to current directory. Add Save action.
+
+commit 7a2ff7f7017abf753579216bfa1ecd4b429e6576
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 02:52:17 2018 -0600
+
+ Handle empty objects.
+
+commit 1f35ec3deb126f3e3d4e4b7bbea823336ecd958e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 02:43:25 2018 -0600
+
+ Remove obsolete redirection.
+
+commit 81d9ab652ce2eb7fb052d0a96f9ea63acc55d21a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 02:39:26 2018 -0600
+
+ Update bsp.
+
+commit 44ba3d7a149ff97144335ef13a53741a51107272
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 02:30:33 2018 -0600
+
+ Handle null simplex problems.
+
+commit 943110ab88bb0af227c85cc906777908876888c0
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 30 21:10:45 2018 -0600
+
+ More QoL fixes.
+
+commit 6701d59cda39aba6ac5e228401e31b8e2879ab91
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sat Jun 30 21:07:07 2018 -0600
+
+ Delete Icon
+
+commit 5077b81969160b377b0af26f711350531ef19edf
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sat Jun 30 21:06:59 2018 -0600
+
+ Delete Icon
+
+commit 97f26873569db365d0f9e5127d362580bbcdabb3
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sat Jun 30 21:06:50 2018 -0600
+
+ Delete Icon
+
+commit be93a35d25f89a4ca801527912a6b21bb24759bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 30 20:16:41 2018 -0600
+
+ Suppress dvisvgm warnings; use dvisvgm --pdf when available.
+
+commit 3bbab66ea27fe2aeecca64b53abd150ab787dee1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 30 18:22:54 2018 -0600
+
+ Use direct conversion to svg for proper bounding box.
+
+commit 92d74369e228512b2270616f79562741856e0b85
+Merge: ea4fed15 25fab655
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 30 15:42:20 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 25fab655437d0128451bae9506d15052fb9a2394
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Sat Jun 30 14:39:58 2018 -0600
+
+ Enable right clicking for ending curve.
+
+commit c911d8acd1eb4bb21c452838f3ee7249c80b0e63
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Sat Jun 30 13:53:16 2018 -0600
+
+ Fix Undo/Redo buttons not consistent.
+
+commit 11ba4c2c0bcd2938aea757afc10ea5056745f2e4
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Sat Jun 30 13:48:32 2018 -0600
+
+ Update mouse coordinate label unconditionally.
+
+commit f92a2da0266970f12e785e07f27a4add2f067850
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Sat Jun 30 13:45:06 2018 -0600
+
+ Hide anchor when not using custom anchor.
+
+commit ea4fed159acd44095bce42fc306e64550a42eac6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 30 12:30:59 2018 -0600
+
+ Remove obsolete code.
+
+commit bdb83475c13af0e41909f97af0389148757558b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 30 09:46:40 2018 -0600
+
+ Rename _fout to _outpipe and move declaration to plain_shipout.asy.
+
+commit 2d49cb19dbbbd5cac38260a32c2df75cd4d2fd10
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Fri Jun 29 22:21:51 2018 -0600
+
+ Fix bezier edit not resetting.
+
+commit ede9f4906ed0c82e39833f9d57562c3c9c8b6d25
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Fri Jun 29 22:08:11 2018 -0600
+
+ Save file with asy coords.
+
+commit 79c2ce6d847f470760faa70fd5a2e211dcfd5033
+Merge: f0d35d4f 731251c7
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Fri Jun 29 21:57:28 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 731251c7301c1f65f4daa50e75e69aec75a150a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 29 18:32:13 2018 -0600
+
+ Use ctrl-D to terminate xasy-to-asy communication.
+
+commit f0d35d4fbbf46572baf776b2667e7856c87c8d25
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Fri Jun 29 17:39:53 2018 -0600
+
+ Fix key count missing.
+
+commit 14a9a432836617d7282cd6f4aff7b7bb883d35dd
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Fri Jun 29 17:35:49 2018 -0600
+
+ Other QoL improvements.
+
+commit a8c22c228fdd82347c55a260b38a56ca97d26159
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Fri Jun 29 17:12:35 2018 -0600
+
+ Save file as asy coords instead of postscript.
+
+commit 21981780fa0e5237b1b92b7ec39ac8da8f8711ea
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 28 15:45:55 2018 -0600
+
+ Add option for editing settings.
+
+commit 00347340d591d11e386bf42eadc3496b5d5b2b53
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 28 15:06:10 2018 -0600
+
+ Add experimental antialiasing (may not work at all).
+
+commit 36df0f26c942fa3aa994541b6e6c0fdc2748eef0
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 28 14:33:37 2018 -0600
+
+ Add legacy xasy bezier mode.
+
+commit 905f58f2c64703371a72641d78465179671c919a
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 28 14:07:24 2018 -0600
+
+ Fix cairo dpi bug.
+
+commit f2601b75e126b6ee659b75cdd78f12d369d51b7a
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 28 13:53:02 2018 -0600
+
+ Make the default linewidth 0.5.
+
+commit de430749dfa385b81ad457ed8a3390dad28cf952
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 28 12:46:35 2018 -0600
+
+ Avoid modifying input arrays in rationalSimplex.asy.
+
+commit 06aee1b86106f39835889a72a2248ab7c02d3cd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 28 12:45:39 2018 -0600
+
+ Overload operator !=.
+
+commit 1e39a91779ea25645acb1f6fc20f2b1480e5c8e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 28 11:22:33 2018 -0600
+
+ Avoid modifying input arrays.
+
+commit ee333cb2e837962b26305dc9e65e306e232c9d3f
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Wed Jun 27 17:30:26 2018 -0600
+
+ Add workaround for bounding box flip.
+
+commit 6e91ddbe19f4b01649b33dfb4a05c36e029f57a6
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Wed Jun 27 17:20:51 2018 -0600
+
+ Change clip detection to asy.
+
+commit 1dedb3885815058ee3067f6402529b6b93a4e0a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 16:57:25 2018 -0600
+
+ Detect clip; invert images.
+
+commit 1b55335147fc4eebe9676c864c9e5e2937c57d67
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Wed Jun 27 16:28:25 2018 -0600
+
+ Enable DPI checking for magnification.
+
+commit bfbfafbc406d8e93166468f1058e57a8a7891086
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Wed Jun 27 13:14:17 2018 -0600
+
+ Add custom dpi support.
+
+commit b1d540c919da0ec7cb53616e22f84f3de723f997
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Wed Jun 27 12:43:26 2018 -0600
+
+ Add temporary workaround for svg noclip.
+
+commit 6c12f7777edb0a2064ae206ea37661461e96a0ec
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Wed Jun 27 02:08:51 2018 -0600
+
+ Remove debug messages.
+
+commit 999210c14c41ba6737ea31fa03a7c7e003940997
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Wed Jun 27 02:07:47 2018 -0600
+
+ Add svg support dependent on QtSvg.
+
+commit 19efab230370f14552d1d17930dd33373f59220d
+Merge: 96031ea2 50fb809f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 00:19:54 2018 -0600
+
+ Merge branch 'master' into qthup.
+
+commit 50fb809fdaf2383385f09884174262964a046156
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 00:17:35 2018 -0600
+
+ Use system ghostscript library by default for dvisvgm.
+
+commit 96031ea2614dee2a470525ba87d921fbe0291056
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 26 17:56:19 2018 -0600
+
+ Deconstruct to svg format.
+
+commit f07fc294bfcf278d72c4cbe14ee95b9c13e22768
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jun 26 15:23:09 2018 -0600
+
+ Add scrolling functionality.
+
+commit c27d0994645a395185aad3cdeb85579e830f45c0
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Tue Jun 26 13:50:31 2018 -0600
+
+ Terminate asy on exit.
+
+commit e1f540d4a86fc432b091cff538703a4e2d1eb180
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 17:37:55 2018 -0600
+
+ No longer uses asy for zoom.
+
+commit a13447f744ec9677e62e5ec09626ec84865068c8
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 16:49:42 2018 -0600
+
+ Fix Custom Anchor inconsistency.
+
+commit 91c0c648ea8e2384be530380836edd6a0fc563ae
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 14:37:10 2018 -0600
+
+ Add undo for object creation.
+
+commit 4fe6ebb5f7b263aa97358a11d9f24d5f0c6432ac
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 12:52:11 2018 -0600
+
+ Add Scale mode to bezier editing.
+
+commit 0c1a59da64db42d1d961210f9e464cab24ebd6b9
+Merge: 4b55a597 cf2e8c9d
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 12:12:57 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 4b55a597110461af90b9082a8e1a1caa1dd40b7b
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 12:12:54 2018 -0600
+
+ More QoL improvements for bezier editor.
+
+commit db447ef6ae109bd7c6f3f6b8c74d0513fec7969d
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 12:12:43 2018 -0600
+
+ Simplify string management.
+
+commit cf2e8c9df1b1665b48b85815028b8990d2cc97f3
+Merge: 5e612b5d b757219e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 11:19:56 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 5e612b5dc66928fa4c9f5152e3a47d3544ed1196
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 11:19:51 2018 -0600
+
+ Remove unused prompt.
+
+commit b757219e235127134448516c47ad3104e86dc100
+Merge: f01a9f11 aa4ee7b7
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 11:03:26 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup.
+
+commit f01a9f11564532c05d21ac131d4ada7bfff723e1
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Mon Jun 25 11:00:26 2018 -0600
+
+ Change spacing to one for each object.
+
+commit aa4ee7b78186e49b35a3a1ed0417f2695be88c1a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 23 16:11:02 2018 -0600
+
+ Delete unneeded files.
+
+commit bf52e9ef5c6b2d2bfc34b7f4a3d86d9e4895a6b5
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 23 16:10:54 2018 -0600
+
+ Add early bezier editing mode button.
+
+commit 92c3d17e2a059014ddb13ce8ef50a626f396bfe7
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 23 16:10:25 2018 -0600
+
+ Add setup.py file.
+
+commit 068d75ce11365caf064cc5e2c8a76e7a3c7a15bf
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 23 15:24:24 2018 -0600
+
+ Edit some build files.
+
+commit 8f7217ac8df4d721127b6f7487874396f5843c6f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jun 23 15:24:15 2018 -0600
+
+ Add icon files for easier editing.
+
+commit e70d99640450c984344c605a35dae157a58ed264
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 23 01:33:36 2018 -0600
+
+ Remove bounding box in example until xasy support is implemented.
+
+commit 3abe5e672a6f9255f382a09b16ed1ee29769ccdd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 23 01:21:36 2018 -0600
+
+ Detect xasy with settings.xasy; reinstate bounding box in example.
+
+commit 401cf60f89dcddfb6993f7bd25a86b144ec5f3ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 23 00:33:18 2018 -0600
+
+ Replace restricted simplex method with general simplex solver.
+
+commit 77c3c2bbc8496a1b53bf3b0e5af27501be05b50c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 16:48:33 2018 -0600
+
+ Fix xasy mode and keys.
+
+commit 0e31fa8c29737941d559bf4e42162212f5f85bb5
+Merge: 10d30131 60a35767
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 15:04:58 2018 -0600
+
+ Merge branch 'master' into qthup.
+
+commit 5ff20563472ab9361826bea32cd4a2635a346550
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 14:53:17 2018 -0600
+
+ Force make clean to remove GSL symbols.
+
+commit 10d30131851c3e8936f4c0fe62097d6dccaa3b64
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Fri Jun 22 13:59:59 2018 -0600
+
+ Allow for new key replacement.
+
+commit febc76cb94e3de54b8f3d01da29f6eb71bf76e25
+Merge: 8aeec7ce 69aaf4fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 11:36:36 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 8aeec7ce7debb2469d2e21efd237123e9943c3b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 11:09:14 2018 -0600
+
+ Implement interactive xasy mode.
+
+commit 728f50856129f4cdcc8f2d30b253aeee243ed6ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 08:31:54 2018 -0600
+
+ Test new xasy mode.
+
+commit 69aaf4fca1d01254a43d78b9bed4755990c052a7
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 21 22:47:48 2018 -0600
+
+ Add more bezier editing features.
+
+commit a890ec75dd31b8aacc4adcea8f138fafe0b9d504
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 21 16:51:19 2018 -0600
+
+ Add control point editing.
+
+commit 7ce567731e2eab843ef2ea5789435d82dc65c69c
+Author: Supakorn <rassamee@ualberta.ca>
+Date: Thu Jun 21 16:26:57 2018 -0600
+
+ Allow saving of edited beziers.
+
+commit 60a35767c5becaf6f8a5fcd72584a9d3d316b028
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 21 00:42:08 2018 -0600
+
+ Force dvips to respect EPS requirements.
+
+commit d36d513b7e060ad476208f2ab9552b4323c45a05
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 20 15:49:30 2018 -0600
+
+ Add early bezier editing.
+
+commit b2c25d8ae46ce3ccf9c5e9689dc682ec647780ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 19 13:13:49 2018 -0600
+
+ Update keydata.
+
+commit c6b4d4b1ef81305d4973e3848673f2a77e476c4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 19 11:20:11 2018 -0600
+
+ Add a flag to identify a user-specified key.
+
+commit 88de674b7daeb9efc3e59a1300e4cd3928f22ceb
+Merge: 3040e29d 74393725
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 23:41:42 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 743937250a7c67dc414ddbd60ee8e2f59c62147d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 23:41:30 2018 -0600
+
+ Revert to using interactive mode for xasy.
+
+commit 0f044019bdc7c7947c6f58db9ba7d34703c49048
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 18 23:24:59 2018 -0600
+
+ Remove unnessecary icon residues.
+
+commit 3040e29d15c97e526faeba5bbbad00f1ec436c17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 17:05:05 2018 -0600
+
+ Revert "Remove obsolete code."
+
+ This reverts commit 28e91cfec416a135e1a9ba5a32486507e59bf5ec.
+
+commit 97ab025569e6cc765d7c4f88a96e49f2628d2930
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 18 15:21:37 2018 -0600
+
+ Unify asymptote process.
+
+commit 5e2123d1358e2e34a3149d3d281365c2e43c8dec
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 18 13:37:01 2018 -0600
+
+ Add initial bezier curve detailed view.
+
+commit c049ce0c2f21c4c9eb86ffaa7bb5b6b163cbc0a8
+Merge: e4a169a5 9d0f460a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 18 12:50:47 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit e4a169a5a79b7e6499b61ecc852551246a38869e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 18 12:45:44 2018 -0600
+
+ Fix moveMove.
+
+commit 9d0f460a251cbad4a2a5ebebf33ebc68633ffcac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 15 18:25:34 2018 -0600
+
+ Fix mouse interaction.
+
+commit 3f6584a1fe2f71c754f2e5b8f34f1f2db9b81f24
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 15 16:44:55 2018 -0600
+
+ Minor type hinting.
+
+commit 91410b0bb179411ca1245f3f82056f1b4e3eae0f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 15 16:18:28 2018 -0600
+
+ Move export option to menu.
+
+commit 8be30f41855c222604a20e771b16d737e907c279
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 15 15:02:19 2018 -0600
+
+ Set fill to disable open buttons.
+
+commit 8369f1d2552ca0739444b071804c55d4930d497b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 15 14:55:46 2018 -0600
+
+ Add More modes.
+
+commit 2feb57922220320c2167f42cb6194b6fb4daaea6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 15 14:21:27 2018 -0600
+
+ Fix labels adding.
+
+commit fa522058317c2a685b4983dc243319c6a87b33a5
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 15 13:33:47 2018 -0600
+
+ Fix anchor not updating.
+
+commit 1fc16f12cabf5a3cec16a6899676b5fd1ead61f0
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 17:52:09 2018 -0600
+
+ Add custom anchor.
+
+commit bbfb89044d5e4b2e8d5d86e1bddac594e35e72ad
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 17:04:12 2018 -0600
+
+ Check for mouse down first.
+
+commit 6fb39b6dac1ea61f053d98273cf1dd11e984f74a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 16:53:04 2018 -0600
+
+ Add hover delete.
+
+commit c106bffce3b1c034a251b6a53745b16ddb7bc431
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 16:46:27 2018 -0600
+
+ Add hover deletion.
+
+commit 2cffe89eaff1b30b797dac3e267b65c60cca94c8
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 16:34:51 2018 -0600
+
+ Even more xasy changes.
+
+commit ad33e4b69f848af0e4cbaaacfe81b9006a3fd5cb
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 15:44:47 2018 -0600
+
+ Recompute control points for all nodes.
+
+commit 01ac796f6a9ff2ae89622e3faa050c8bcb386549
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 14:04:53 2018 -0600
+
+ Other minor bug changes.
+
+commit eeba4902c2fc1425351d6a53bd129c67c616fb6c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 14 13:39:15 2018 -0600
+
+ Add more anchor mode.
+
+commit 6df104d6060fe5400e9d7618462026f11767bbd8
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 18:13:56 2018 -0600
+
+ Add support for hard deletion undo.
+
+commit 100ac43d7b9d762e7c5f2b732f7fb47529e666b2
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 16:57:17 2018 -0600
+
+ Remove closed path option.
+
+commit 0c2b40391218e0923f145d50aacc834fd575fde5
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 16:45:00 2018 -0600
+
+ Add some bezier keymaps.
+
+commit d6c70960f272c439d6f8e2220e12756194878875
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 15:55:39 2018 -0600
+
+ Make code objects a little more informative.
+
+commit 86b8a207600a33d509002f6cae016e5551316e53
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 15:42:35 2018 -0600
+
+ Update Editor argument system.
+
+commit ddb1a2c604eacd69509685e228d4e487ffe48a4e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 15:05:20 2018 -0600
+
+ Restore venn.
+
+commit c74ca307377f24073973137830bfbb064125ee67
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 15:05:00 2018 -0600
+
+ Put back shipout.
+
+commit 19e31f55e7f12bcee0b584d21d47e3e4b3e52243
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 15:04:22 2018 -0600
+
+ Change arguments to old xasy.
+
+commit c8d73f5f33c4c94ccee4397a876906c8eb1558cf
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 14:52:33 2018 -0600
+
+ Bind delete to delete object.
+
+commit b9f5e41419d978c5084870beed3efa21a2a9e09d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 14:43:10 2018 -0600
+
+ Update .gitignore
+
+commit 9d59dca9b470251e336d63f6df7fa7a2d64603f9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 13 14:42:26 2018 -0600
+
+ Revamp options system.
+
+commit c2827f039043d9077aed43d15604d451a0f79b81
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jun 12 22:51:09 2018 -0600
+
+ Change deletion mode.
+
+commit bd6d4cf68a80d4e335274b2caa32f7045f7591c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 16:59:37 2018 -0600
+
+ Omit deleted objects on deconstruction.
+
+commit 8fcb2b769bf595380360ad7a3aebe1680da53ef1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 15:37:58 2018 -0600
+
+ Ignore EINTR on read from pipe.
+
+commit 97f7d0ca87d4d2db1c522a59532cc2b0f7758630
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 11 18:16:23 2018 -0600
+
+ Optimize deletion and options.
+
+commit 5a7a08e173fff7a77727aa3236b323a5069c2af3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 11 16:39:36 2018 -0600
+
+ Add CSON support and basic deletion.
+
+commit c639a6b9b0142e5bea61d087a9c22a7eb38bb335
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 9 13:33:22 2018 -0600
+
+ Update three and slide modules.
+
+commit ae8f7b0bc3a001fb6dc8a72598f4342979117eb8
+Merge: 6cb432ef de2c27e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 8 22:23:39 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit 6cb432ef307bb52184196bc95a386f960a392aa5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 8 22:23:32 2018 -0600
+
+ Rename map to xmap.
+
+commit de2c27e042780e860e4848995241484b2c255602
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 8 22:15:53 2018 -0600
+
+ Allow for top-layer draw for selected objects.
+
+commit 55b9c779cf36d7757eb145f2028bb8c328a4ce1e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 8 17:25:34 2018 -0600
+
+ Add map/xmap switching and key counter.
+
+commit f54e57e5b8a05da8ddfa1b5a8eb4aa1f939768f9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 8 16:42:57 2018 -0600
+
+ Add mouse wheel selection modifying.
+
+commit 01db5e39b2969fb10142a3b9b9e90c1a9f8826d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 8 15:15:10 2018 -0600
+
+ Add identity and zero transform constants.
+
+commit 9b065e65c5b42b9fb0aba00ff2874e92d2ae368f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 8 14:38:16 2018 -0600
+
+ Implement RGB(int,int,int) function.
+
+commit e3dc24a6810bf35c7a5ae1fb176961b873ed92fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 7 21:42:37 2018 -0600
+
+ Renenable object deletion.
+
+commit 018e17a2e1caeec6552eefd94737b1e24715ee5f
+Merge: 7b06be2c 594473ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 7 21:20:50 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup.
+
+commit 7b06be2c7e0334081b5540e80e29248afa81cfd3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 7 21:20:44 2018 -0600
+
+ Support bbox in xasy mode again.
+
+commit 594473ef65e616be969e0e212f7c24b201c9aec2
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jun 7 14:28:38 2018 -0600
+
+ Remove writing of identity transformations.
+
+commit dab676e5a6d8182e8958e8d705ce01f90d542d6f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 21:03:56 2018 -0600
+
+ Fix KEY order.
+
+commit b2197a0e1c094e16b7d06c5cd1492b5898af57ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 19:16:34 2018 -0600
+
+ Remove unwanted spaces.
+
+commit 7cef83b715c5dca65178b6f64c717a066c45f981
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 6 16:25:50 2018 -0600
+
+ Cleanup code and add terminal option.
+
+commit 027cfb6ebdeeb4af66567a06d2490ce3ae506d27
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 6 15:42:35 2018 -0600
+
+ Change mapping behavior when save.
+
+commit 356ec304168863f178e37314cbcca272d8eb3f0e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 14:21:32 2018 -0600
+
+ Add default transform to map.
+
+commit 9f4c4c60239faa7da04fa177f5dd5e3ec97974a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 14:04:12 2018 -0600
+
+ Draw xasy objects onto currentpicture in PostScript coordinates.
+
+commit 0645b41d5f88085b16f0ba1814e85dd60dce445c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 11:04:22 2018 -0600
+
+ Draw xasy objects on a separate frame.
+
+commit 8b006fb0b29c6a9da2ac0bc53c03fdd51223f634
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jun 5 17:14:43 2018 -0600
+
+ Add support for exporting files and other changes.
+
+commit 30bd410fad4be3b71ab26e4eddbc64f39b49773f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 4 17:26:19 2018 -0600
+
+ Add early magnification support.
+
+commit 41613fa98512a44487c6b5ac687b88f3852e9102
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 4 13:44:57 2018 -0600
+
+ Fix selection issue.
+
+commit 3d1ca05ccaaf934a42df038e5b8c5ab098a299b8
+Merge: cf276195 93f367bb
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 4 13:32:05 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit cf27619534b2f5eec07fda1ec58110ea2d8c11a9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 4 13:31:04 2018 -0600
+
+ Move transforms to dict[list] model.
+
+commit 93f367bba491d01706e656821ccb748067ad2773
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 3 20:32:07 2018 -0600
+
+ Finish passing KEY to transformed elements.
+
+commit 34ce667325ce323de441d0bea58b47c0f05751d2
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 31 19:31:45 2018 -0600
+
+ Show key in status bar message (for debug).
+
+commit 75397a5488c0ec3de9d9d24f75e8479b91cc3a14
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 31 19:28:01 2018 -0600
+
+ Groups objects with the same key.
+
+commit 761e3f3275da938a83c7c2ff4c6cd164dd47b134
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 17:50:19 2018 -0600
+
+ Begin passing KEY to transformed elements.
+
+commit 221fda26e204542d88a2df73f4392adbaec29f54
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 31 16:49:38 2018 -0600
+
+ Fix tuple loading of xasy2asy.
+
+commit 771bd937375c8a6888873c0acb68b337bea744f9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 31 14:44:31 2018 -0600
+
+ Add more functionality for toggle visibility, code adding.
+
+commit 308fceb60033262814b6fa843a46f3580f2a4d02
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 30 17:27:51 2018 -0600
+
+ Add functionality for delete, change order.
+
+commit 0a05fccf9e9035568247d3e628d373d9b245ccc0
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 30 16:45:42 2018 -0600
+
+ Update add bezier mode and file loading.
+
+commit 0b08348102fd6be4c4a2b62945b17c46aeb5f978
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 13:13:07 2018 -0600
+
+ Add key support on asy side.
+
+commit aed03a1f8db344aa133b3abd7a7d6a386e6f31f3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 29 11:17:10 2018 -0600
+
+ Add more bezier options.
+
+commit d10a4f89efc4c3a7cf2552425a19cb62a1861491
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 28 16:00:55 2018 -0600
+
+ Add in-place bezier curve interface.
+
+commit 90f82d4a91d7eabf3e13bd034a95df14cfd85fa9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 28 15:32:19 2018 -0600
+
+ Update .gitignore.
+
+commit 99155d3edc967ce06cfbd7c6c8d892502b2eee82
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 28 12:52:57 2018 -0600
+
+ Add filling to circles and polygons.
+
+commit d04cac4bf67abb52bde752204d76cecec1f3a422
+Merge: c489474d 560f683d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 25 18:52:52 2018 -0600
+
+ Merge branch 'qthup' of github.com:vectorgraphics/asymptote into qthup
+
+commit c489474da753207bad06b414df2a36d41efa62c3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 25 18:52:39 2018 -0600
+
+ Modify xasyFillShape for qt.
+
+commit 560f683d7d089a25ea21bb9b240f7cb34650d878
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 17:12:47 2018 -0600
+
+ Remove obsolete code.
+
+commit 17c40ba170f7c359fd6ae3943b6d2a17b4baffd6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 25 14:44:52 2018 -0600
+
+ Fix add shape transform bug.
+
+commit ac69fc4d0deab73dbfeef21fb88a6e0007b2fec1
+Merge: baf37589 f01b1baf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 14:24:58 2018 -0600
+
+ Merge branch 'master' into qthup.
+
+commit f01b1baf546ed20bf49e5fd56aac4b43b4a1a5e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 14:24:19 2018 -0600
+
+ Fix quiet flag.
+
+commit baf37589eed095c896099e7cd51e4dfdc1c916a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 04:27:17 2018 -0600
+
+ Fix outpipe communication by turning off quiet mode.
+
+commit 4deafa3b4a9368d2a8463917eb009bd29b5d5658
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 24 18:09:46 2018 -0600
+
+ Handshake via pipe.
+
+commit 5016356832b2b5939bd45711ae48b95113f27489
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 24 16:58:31 2018 -0600
+
+ Clean up initial hand shake.
+
+commit f78ac62b79949992271c7f893f559ce4b7b77f39
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 24 15:38:44 2018 -0600
+
+ Change drawing backend to use ordered lists.
+
+commit 4f947b99fe88f5e0fc2fed4b42d73a5f914c2a7e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 23 15:06:54 2018 -0600
+
+ Manually add back labelEditor changes.
+
+commit 0bd402f7ffc30fc1f3dd4979965ced0b36c29499
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 23 14:22:59 2018 -0600
+
+ Manually merge back xasy2asy.py.
+
+commit 5caafee6c63ee66473663038ed2bea655dc304b3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 23 14:02:22 2018 -0600
+
+ Add back xasyUtils.py.
+
+commit fe3482ec33738e7f6d89fda409082d05f6b585cc
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 23 12:58:33 2018 -0600
+
+ Get xasy to wait for asy to start.
+
+commit 82cb3f48c6ed3c81af5d62e870adbc6cda27e9d5
+Merge: fb2bd13e 4425e5c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 23 11:22:07 2018 -0600
+
+ Merge branch 'master' into qthup.
+
+commit fb2bd13e326e9a040bc578b533a36f23b64ed33c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 21 15:09:11 2018 -0600
+
+ Remove obsolete code.
+
+commit 2d72f98a9316dc49cd55737e8a9b23fc91d5736d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 20 22:27:42 2018 -0600
+
+ Implement xasyKEY for 3D objects.
+
+commit b137bfb6c542ecc1d0341475511e02b8a67849ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 20 22:17:09 2018 -0600
+
+ Fix key generation.
+
+commit b3e1dc3c0d5fe2bd19936fe1f25e815c0203d2ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 20 10:57:05 2018 -0600
+
+ Simplify code.
+
+commit 4425e5c5aca12f87fc3f90151913733f8b771834
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 23:44:45 2018 -0600
+
+ Transition from rpc to tirpc library.
+
+commit 1c46c6547e63006cfaa49ad9b70846a12b44ea8e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 11:36:12 2018 -0600
+
+ Inhibit exit on pipe EOF only when inpipe is specified (for xasy).
+
+commit 28e91cfec416a135e1a9ba5a32486507e59bf5ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 11:26:34 2018 -0600
+
+ Remove obsolete code.
+
+commit a0b453d97991205a8b9a78b0f44b2aa9c10c63b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 06:00:26 2018 -0600
+
+ Simplify code.
+
+commit 697537dee813ce9523382e4b44a6941b7d55f091
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 05:57:49 2018 -0600
+
+ Use SIGHUP to signal EOF.
+
+commit 8c982663371957021be663d6796bbf0db52317c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 18 23:48:49 2018 -0600
+
+ Use a direct pipe read for xasy instead of interactive mode.
+
+commit 6082601320a25abd0a9976550707b9eaf67cf9c6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 18 13:48:29 2018 -0600
+
+ Preserve pan translation in resize.
+
+commit df4c903e109a9ef2a812605526bb93d118921f03
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 18 12:30:34 2018 -0600
+
+ Allow for flexible resizing.
+
+commit a05bdea1a260b0fe86c46e55731ed561d7f6eaae
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 17 19:27:54 2018 -0600
+
+ Fix a critical output dir bug.
+
+commit ff19d78558783ec53ac2ba2aaacd0d3916866dbc
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 17 17:19:33 2018 -0600
+
+ Add early label editor preview.
+
+commit 442a81ca4147a98535507b097e38bc587bb34ce4
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 17 12:46:59 2018 -0600
+
+ Migrate asymptote process engine to a contained class.
+
+commit 6a6bb0e1126dd02ac45603a75db1f642570d7c48
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 17 12:18:01 2018 -0600
+
+ Add early translation foundation.
+
+commit 0971e4dd2d12705bf92adff52e326246fa65a4cf
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 16 15:27:07 2018 -0600
+
+ Fix align mode in label widget.
+
+commit f698e26621b500d06d46731dc8c9865b06a247c2
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 16 14:50:17 2018 -0600
+
+ Add advanced label editor.
+
+commit d03660d2fbcff4dc1ed48b99ea1353db2c3e1db3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 15 17:34:23 2018 -0600
+
+ Optimize string concatenation to use mutable string.
+
+commit 46b7b040f0a0d00f99da26718f7d3cc797826e05
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 15 16:09:59 2018 -0600
+
+ Add early label adding.
+
+commit d0860eb41adf13170079ae0f60da21f9f0ea58e4
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 15 14:34:03 2018 -0600
+
+ Add test label support.
+
+commit 14e8314dd7425874f36780e4109626cec2589b72
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 14 18:56:13 2018 -0600
+
+ Early migration to key-based transform (incomplete).
+
+commit cb034388031e39a6e7aeb07f31fb8744a5406b74
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 11 16:15:10 2018 -0600
+
+ Add argument support.
+
+commit 37f670816e7fc8ba23ea041d7ce18ebf16d35d8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 11 14:43:37 2018 -0600
+
+ Disable startScript and endScript.
+
+commit 436b50fe3b73a5191f0679a9666d899da35697d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 11 14:41:26 2018 -0600
+
+ Revert test code.
+
+commit 4acdd9ab9a524ec148c7fa8d75edf3652f354de4
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 11 13:51:41 2018 -0600
+
+ Update .gitignore.
+
+commit 05287cec1a12e77fd35a58a7dc534798add32735
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 11 13:51:06 2018 -0600
+
+ Remove asydev.
+
+commit 872ceac1642c01f3fe9370170bdaee654c1113cc
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 11 13:50:15 2018 -0600
+
+ Update .gitignore.
+
+commit de30993530af475d8fde3484d5bbe4f7c1dce339
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 11 13:42:44 2018 -0600
+
+ Remove unwanted file.
+
+commit 198d8589a70618071340969ae76d0c2c9534ea12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 11 00:38:26 2018 -0600
+
+ Simplify code; move global variables to processDataStruct.
+
+commit f718e5eaaeca1a0938068b0dcfc97af2bc5cc912
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 10 16:52:51 2018 -0600
+
+ Adding some testing flags.
+
+commit fae1d6192b61f3c5a2e5dca553d5b45dd240e030
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 10 16:03:15 2018 -0600
+
+ Add preliminary trasnform migration to key.
+
+commit f0d593d9953ee3fa69f3fee6a2336a56a5cd02e9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 10 15:21:01 2018 -0600
+
+ Add basic key recognition.
+
+commit 9ebbcfaa7cc3f57d18432ef11c6746569f057754
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 19:19:01 2018 -0600
+
+ Write KEY to outpipe.
+
+commit db66c57b242c83541abea7eb0201f87d13a648dc
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 9 17:34:09 2018 -0600
+
+ Add preliminary key support (Still a hot mess...)
+
+commit c46f5b3886e0285a5eb535ffa2d3ebf44644dd89
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 14:44:05 2018 -0600
+
+ Add virtual KEY argument to all functions for xasy.
+
+commit 0103b665ebdca12c348886c18eafd751fe6901b4
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 7 16:35:13 2018 -0600
+
+ More Quality of life improvements for color dialog.
+
+commit 345ba41986af818577cf60dc61e8aeb26a35bc1b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 7 15:30:11 2018 -0600
+
+ Update gitignore.
+
+commit 67cbfd41508f79b79a91f2fca693e1ec5cdd95e0
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 7 15:19:20 2018 -0600
+
+ Add pen support.
+
+commit ab412a711d8836fb47399fd4380665288502de8f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 7 14:52:21 2018 -0600
+
+ Add color support.
+
+commit b52cf9dc210c9d48fd1d20182d667a11dc013c47
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 7 13:26:33 2018 -0600
+
+ Fix inscribed polygon mode.
+
+commit d86e0ad3ec666f2d0516b97d72c0b5e7710dd3ca
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 4 18:24:35 2018 -0600
+
+ Add preliminary options for Polygon adding.
+
+commit 234483ccc8a13b8d318b7d09c3e38dfe353f696f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 4 15:27:08 2018 -0600
+
+ Update UI for more options.
+
+commit 82cdb14e492e428b3e83c3aa489a448f31a8a746
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 4 14:56:44 2018 -0600
+
+ Add in-place preliminary polygon adding.
+
+commit 51bd11364219e7503622704ae297e3f7f0643cac
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 3 16:39:23 2018 -0600
+
+ Add interface for polygon adding.
+
+commit 3b1f8f08d7404b2143015468b0b0bcdd51bae93b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 3 15:38:11 2018 -0600
+
+ Add preliminary in-screen object creation.
+
+commit 003d2fa4b41bb1c12c9de1503083267395d4ff5e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 2 16:25:43 2018 -0600
+
+ Add exscribed (right word?) polygon handling
+
+commit 27470ffb04cc5b446e906e327dab976713c94309
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 2 15:43:09 2018 -0600
+
+ Add support for primtive polygons.
+
+commit 34a182db3e5f611f794319ef6c2485594f3487a6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 2 15:10:29 2018 -0600
+
+ Add adding circles.
+
+commit 8258bb93752a2d888e583f307d13bb4ef727aee6
+Merge: 7c18f2ea d09e7fce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 2 08:28:05 2018 -0600
+
+ Merge pull request #70 from rgxgr/patch-1
+
+ Correct words order to avoid confusing
+
+commit d09e7fce20722e2e7d65692b915c4cef9a33bb2c
+Author: rgxgr <33611071+rgxgr@users.noreply.github.com>
+Date: Wed May 2 20:08:14 2018 +0800
+
+ Correct words order to avoid confusing
+
+commit 7f758672b3c9d39707379d030f9d8c7bc33a48cc
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 1 17:09:33 2018 -0600
+
+ Merge settings management into original Shardt code.
+
+commit b9754484ce5ef55fb9415731512362615a431778
+Merge: 75b22704 7c18f2ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 1 12:03:43 2018 -0600
+
+ Merge branch 'master' into qt.
+
+commit 7c18f2ea15c289fbdd6e4f91c69110f5a0c159b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 28 12:08:11 2018 -0600
+
+ Rename i386 to i386_32 to give preference to 64-bit binary.
+
+commit 9079934b3424157942736bbe1a15afd1dbf5836c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 28 11:39:48 2018 -0600
+
+ Do not modify system path.
+
+commit 799bf2dfc67869606056633c3a8ce4313b45d058
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 28 11:10:47 2018 -0600
+
+ Revert "Workaround NSIS EnvVarUpdate bug that truncates long paths."
+
+ This reverts commit 8e932eb10a822d4e927b3b9dbecb313e135ee267.
+
+commit 8e932eb10a822d4e927b3b9dbecb313e135ee267
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 27 16:22:08 2018 -0600
+
+ Workaround NSIS EnvVarUpdate bug that truncates long paths.
+
+commit 21e497260a55dbe4e4b111198aa26115564669ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 14 08:31:47 2018 -0600
+
+ Fix sort.
+
+commit 2bfec3147f4308fa6e206ec624574e3156f43fd2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 13 10:11:31 2018 -0600
+
+ Add option to use unstable sort in favour of less(T i, T j) ordering.
+
+commit 20ff31c0444c901c2b0486127f3c4df2b9832df8
+Merge: 1a50ee63 2fd03c66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 11 17:51:11 2018 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 1a50ee634cb58dbb4d9395ba90d7a795e63512d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 11 17:49:52 2018 -0600
+
+ Update README
+
+commit 2fd03c6695627387db19f993ac93e926b9b63eb7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 12:26:42 2018 -0600
+
+ Fix uninitialized counter.
+
+commit 4d0771442074af020b7fc929e929629e0bcbbdee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 23:51:06 2018 -0600
+
+ Increment version to 2.45.
+
+commit 878f944b9ee540c77c83f2cc61d6a97c22298553
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 20:56:45 2018 -0600
+
+ Fix portability issues.
+
+commit 1879deff46664834bad1a6bce926ce9d58baabbb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 20:49:47 2018 -0600
+
+ Fix CLZ bug on CYGWIN.
+
+commit 2c70c1d965fb0b9fa92f97db2484d3ba4c184f40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 20:23:08 2018 -0600
+
+ Disable trapping of floating point exceptions under CYGWIN due to strtod bug with real x=121645100408832000.0."
+
+commit 994052a59795255dc87882a3d71f4104dd041f70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 6 17:19:45 2018 -0600
+
+ Improve usleep declaration.
+
+commit 6b974b3df56cd81b2960774441dd2e647bdf52da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 6 17:18:50 2018 -0600
+
+ Make POSIX definition conditional to CYGWIN.
+
+commit e81df002635e1391bb540fd751cd019041e8e314
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 6 16:53:21 2018 -0600
+
+ Disable unused code. Redirect "make test".
+
+commit 633813249c393938f2a8ca6d3715638f83710d74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 22:32:04 2018 -0600
+
+ Remove unused code.
+
+commit 052fd69055b077537a0701711387d4005ef6cd3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 22:27:48 2018 -0600
+
+ Increment version to 2.44.
+
+commit f91ccd81f6f33f927f88724e23afb75988c56692
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 21:21:39 2018 -0600
+
+ Replace symbolic link; update copyright.
+
+commit 69c6d33934672d86f94469325327e7e0862e4c72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 20:29:03 2018 -0600
+
+ Fix MSWindows build script.
+
+commit 1ad3fcca0a38fdf6020ba9a00d9a09a12a0dea31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 18:49:09 2018 -0600
+
+ Update build scripts.
+
+commit 66327ad373064731bcbda74a2873353a77f6eaf7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 16:48:54 2018 -0600
+
+ Fix configure.ac.
+
+commit a4331d136126548b86d84ac59617f2a1374d9cc7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 16:31:15 2018 -0600
+
+ Update build scripts.
+
+commit e1507613166785005f6f0c59ccc23df1340b9c2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 08:55:50 2018 -0600
+
+ Update config.sub and config.guess.
+
+commit 92056e30dd6222eee72088de94c16cce22080104
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 08:55:48 2018 -0600
+
+ Update config.sub and config.guess.
+
+commit 42faee86b22ba0e051aba4d3df08da670dbe02d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 5 08:53:51 2018 -0600
+
+ Rename 64-bit linux binary.
+
+commit fcbfb4633bb13103fcf9cf1b399dc917c7a70763
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 4 16:37:24 2018 -0600
+
+ Revert to Boehm GC 7.6.0 due to map compilation issues under MacOS X.
+
+commit 125fadda71d2ff4be2c5533a22a18e1f72c336a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 4 09:44:07 2018 -0600
+
+ Update to latest Boehm garbage collector.
+
+commit d412f0e76cee49975f77849997707399a5719fb1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 4 00:59:24 2018 -0600
+
+ Support vector svg output for PDF tex engines.
+
+commit 986b329d6e3628c768646f2217fa444f4be08ed8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 3 21:50:48 2018 -0600
+
+ Implement temporary workaround for github Issue #29.
+
+commit ce6d0daa38fb334ff23f190b74ba10d0aa241acd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 3 19:47:40 2018 -0600
+
+ Fix real modulo operator.
+
+commit 3cdb10262d48640b9ce217896c3da595dd9ab805
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 3 02:16:30 2018 -0600
+
+ Increment version to 2.43.
+
+commit 4d0f6ba1b9c6ea2609b145f42ec9a39023e60706
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 3 00:12:12 2018 -0600
+
+ Revert to centroid depth sorting of transparent triangles until splitting code is complete.
+
+commit 355b585791bba490a8c0847dc104ef3504180353
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 23:44:04 2018 -0600
+
+ Revert to nativeformat EPS for MSWindows.
+
+commit ab9623e7777ff1e85f72f326b6ad9771f84290af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 23:37:05 2018 -0600
+
+ Fix ode integrator output.
+
+commit 440a4e23f492556b6671ad713c92507c4da91d94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 23:31:44 2018 -0600
+
+ Add implementation of rational arithmetic.
+
+commit fb83e1d71bad988d081d308dc9a9d1f385871bdc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 23:20:23 2018 -0600
+
+ Improve missing texi2vi workaround.
+
+commit f10affaa88f9680576f541ff351a3996e502a135
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 22:49:03 2018 -0600
+
+ Specify current directory.
+
+commit d8d976aee0234524ab5794a75d61f9ea9c9e6d72
+Merge: dc276c11 67b844ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 21:42:51 2018 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit dc276c116e40ef1e485fa456d75d26411d6ac1f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 21:36:48 2018 -0600
+
+ Check for feenableexcept.
+
+commit 67b844aecc03a4b08ff8e9a8152d7cf324b4db22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 21:36:48 2018 -0600
+
+ Check for feenableexcept.
+
+commit 13d9a1ec1cf6f6f1478cc4f590f728b0f0561725
+Merge: edf06016 bed300cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 21:14:51 2018 -0600
+
+ Merge pull request #54 from ivankokan/perpendicularmark
+
+ Properly implemented "square + pen" semantics within perpendicularmark
+
+commit edf060165f9014d9aeb23673bf214b5e7b983049
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 20:54:44 2018 -0600
+
+ Fix transparent depth test.
+
+commit d75d007c08b19787bc59b3efad1337f18b8a1bde
+Merge: e0dba9d6 6ce2d6f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 13:31:16 2018 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit e0dba9d6b5b00154d08c4eec793ab7cffba96cce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 13:30:59 2018 -0600
+
+ Fix missing 3D underline.
+
+commit 6ce2d6f6c07e0492a222ec22a78bf7c60f75fd96
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 28 17:46:50 2018 -0600
+
+ Fix issue #62 (invalid string acces).
+
+commit afd2d56d1a74a9fbd27c93f79a48947fe33bfd94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 24 17:05:23 2018 -0600
+
+ Force make clean to clear symbols.
+
+commit fc0cc036f6b3733fba8b43bf5068b009fddb6bdc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 16 12:33:25 2018 -0700
+
+ Improve diagnostic.
+
+commit 63b2310edefaef37192f596a2b6cfd97d5ce60d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 19 20:18:17 2018 -0700
+
+ Inline call to intbits().
+
+commit 5f5a678fcb4d40fe312c511eb32189c410269a73
+Merge: c2ca99da e9906f89
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 19 01:06:50 2018 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit c2ca99da1f5587e077cd0e7c367b49d5eae7a172
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 19 01:05:11 2018 -0700
+
+ Fix asymmetry in angle(transform t), so that angle(yscale(-1))=0.
+
+commit 9bdc5755535489b81c6fea146aa60463de9cbcc3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 12 15:56:37 2018 -0700
+
+ Fix path.
+
+commit e9906f89fe021471c9f7d7bd375c823ee0ea45d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 12 15:56:37 2018 -0700
+
+ Fix path.
+
+commit f9cd516793b5d98aba083f2ef79891ccb2319adf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 12 15:43:28 2018 -0700
+
+ Rename directory.
+
+commit b0ba7e598eae625ec5d57a214682fe41907c2500
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 12 15:40:58 2018 -0700
+
+ Fix typo.
+
+commit a8b346777b7404c480c7f9aa144239ef11288164
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 12 15:39:04 2018 -0700
+
+ Fix HOWTO-MSWindows maintainer documentation.
+
+commit bb3eb235fd4da44f56f1eb563ff6c65f48a22606
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 12 15:38:15 2018 -0700
+
+ Update HOWTO-MSWindows maintainer documentation.
+
+commit d069591eb886db59bf1bf764b3916e6b907cafd4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 12 15:22:10 2018 -0700
+
+ Add maintainer build scripts.
+
+commit 1e1e6cbbcfe65b58ead8e04d5e2b302ed011acd8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 11 14:00:22 2018 -0700
+
+ Fix integer division bug (due to overflow).
+
+commit 0d172a96ebb5d0c11679dd98af0fa542ff2211b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 9 09:51:04 2018 -0700
+
+ Make nativeformat PDF under MSWindows.
+
+commit 127affbfc8938f5a7ac835d8f7fb59797b852cb0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 9 09:28:25 2018 -0700
+
+ Build 64-bit MSWindows binaries.
+
+commit eff28605bf5844b3570f43ad4264446c75b1e78c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 5 15:27:07 2018 -0700
+
+ Workaround broken CYGWIN xdr headers.
+
+commit bed300ccb079c06c66eee8ff4dd38d4e522bf027
+Author: ivankokan <ivan.kokan@gmail.com>
+Date: Fri Jan 5 18:55:49 2018 +0100
+
+ perpendicularmark: properly implemented "square + pen" semantics
+
+commit 952dec232e3ea77e820297f38f338fab360186fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 5 09:02:49 2018 -0700
+
+ Update Boehm garbage collector.
+
+commit 715c523b3019a59259c48a0b7f9852ce17b6128a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 4 22:30:21 2018 -0700
+
+ Update CYGWIN port for 64-bit build.
+
+commit 75b227048bf39a8f2bd9288d1a4e076119d0e612
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jan 4 15:07:17 2018 -0700
+
+ Add Polar Grid Form.
+
+commit 77ba04a37dd8affd267a267df256326fb42f6f1b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jan 2 15:03:01 2018 -0700
+
+ Add basic guide drawing system.
+
+commit 109a43611f3e2f9da5f5dae5502d8a5b8b299a6a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Dec 29 21:10:25 2017 -0700
+
+ Add basic grid snapping.
+
+commit aefccb8c568f772feb2bc59f009da9da3e8a3ff3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Dec 29 16:13:31 2017 -0700
+
+ Add basic grid toggling
+
+commit 0fa0e5ca0c3709c3d3e0722c35ae45a412ea10d4
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Dec 27 16:53:51 2017 -0700
+
+ Add basic grid rendering.
+
+commit 6f6b6b1f7ef8393096a57c8c0b370275c11b2270
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Dec 27 15:22:28 2017 -0700
+
+ Update deletion of Bezier points.
+
+commit 187e6113e92669d0cb724971694eaa8d7768178e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Dec 22 21:44:13 2017 -0700
+
+ Fix rotationBug - xasy2 now checks if custom anchor is defined or not.
+
+commit 005aef0a8c45c8625910363e1159fedcd9fa31b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 18 14:51:43 2017 -0700
+
+ Fix segmentation fault.
+
+commit f791e93a9d258f03d4cf218f19772c91df4b8b35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 8 00:07:19 2017 -0700
+
+ Make Bitreverse array static.
+
+commit 2f76e4922df68ca7f5c625637cde3d8b6de00801
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 5 00:30:03 2017 -0700
+
+ Update documentation.
+
+commit 4d8d83abb664f21e941ded491fe9c99ed605d4a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 4 21:47:35 2017 -0700
+
+ Make CLZ(0) return width of int type.
+
+commit 732551d1071b8e660fd44974002b5c0fb4dde574
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 3 11:21:39 2017 -0700
+
+ Extend bitreverse and CLZ to long long integers.
+
+commit 6dfcb97eb80d384371cbba095ce5e0289ff649f5
+Merge: 5709f8fc 1e314cf9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 23 15:33:58 2017 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 5709f8fc6f1800de36d50e636332355a71d924ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 23 15:21:55 2017 -0700
+
+ Add forcemath option to format for typesetting within an existing math mode.
+
+commit 1e314cf9b58e60b3a4b0fa930d5fe69e3e78653d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 18 11:13:21 2017 -0700
+
+ Remove extraneous declaration.
+
+commit 07604b6d32201acbb236b254240f66da167e1a49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 16 20:32:08 2017 -0700
+
+ Port to latest CYGWIN.
+
+commit bdb0c70c984316552298396d0ec75f7b1c40a971
+Merge: 9db9467d 51ababda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 13:33:10 2017 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 9db9467d4cc2c7cc2b1b09b2f9bda4ae85a7b188
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 13:25:07 2017 -0600
+
+ Implement 32-bit bit reverse.
+
+commit 51ababdae0bb1b3b94e87bd4a005af6f4d417b59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 26 09:09:57 2017 -0600
+
+ Fix offscreen rendering initialization.
+
+commit 4e391ced23627e0ba9a318485f20c58d99545f27
+Author: prramazi <p.ramazi@gmail.com>
+Date: Fri Oct 13 17:08:45 2017 -0600
+
+ Fix int type.
+
+commit febfdec12079aa673d8f0c66580529c208f3cedb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 11 11:20:53 2017 -0600
+
+ Fix gitignore.
+
+commit 41e6e15d4313c7ba02d947ff33d74238304c7033
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 29 14:00:58 2017 -0600
+
+ Correct comment.
+
+commit fa3de734be166afe63d0d47cdf546932f7531a5a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 29 11:39:07 2017 -0600
+
+ Implement string[] array(string s) and string operator +(...string[] a).
+
+commit 41d41c503c4119638baf7480c189149f6c244628
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 27 16:47:24 2017 -0600
+
+ Add operator <>.
+
+commit 21f5e431ff233c8af387e305301f12cfd235c636
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 25 17:14:37 2017 -0600
+
+ Implement int popcount(int) and use it to build a 64-bit int CTZ(int).
+
+commit 66fc685efa9a161b70e67c9f319d9030b2d2eea9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 22 15:20:17 2017 -0600
+
+ Implement findall.
+
+commit 1d87c4b421c6e1950280eb26681ad229fe98313c
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Mon Sep 4 16:23:21 2017 -0600
+
+ Add preliminary keymap & settings support.
+
+commit 8e8a2349800a1d245779e023ecc5ede7da38b239
+Merge: c4aa7ded e9584ed2
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Sep 1 15:28:23 2017 -0600
+
+ Merge branch 'qt' of github.com:vectorgraphics/asymptote into qt
+
+commit c4aa7dedffc4a7782a75416c787dc7f607a308ea
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Sep 1 15:28:18 2017 -0600
+
+ Fix Beizer -> Bezier spelling
+
+commit e9584ed2fbaa6ba2bbf98fe78166c4e91a139da4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 1 15:27:42 2017 -0600
+
+ Update Makefile.
+
+commit e76d689c599a22a4441ae7111164bae7ac8f4f60
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 1 15:27:11 2017 -0600
+
+ Update GUI.
+
+commit c5e57f4d961d136c4b547ea63026795790bd125e
+Merge: 355f99d4 15fe0eb7
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Sep 1 15:26:49 2017 -0600
+
+ Merge branch 'qt' of github.com:vectorgraphics/asymptote into qt
+
+commit 355f99d469f725e0086313bb27ab66b66d4d48cd
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Sep 1 15:26:43 2017 -0600
+
+ Fix merge conflict.
+
+commit 15fe0eb716b5f0d92ab8fe7063ca55124a623260
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 1 15:16:29 2017 -0600
+
+ Update.
+
+commit 65e540f590ae0a9b552d31fec8eef5980e0f59c9
+Merge: 7be28a23 093568e2
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Sep 1 15:09:10 2017 -0600
+
+ Fix merge conflict.
+
+commit 7be28a23c991a0356792adf6304a5e58e0d8f492
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Sep 1 15:06:29 2017 -0600
+
+ Add Point Editor.
+
+commit 093568e25e61c860b896497264b19ea4f078c0ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 1 15:04:39 2017 -0600
+
+ Fix spelling.
+
+commit fa2c10cf89b3b2564ee53bc48d46dd6919ba6105
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 1 14:33:27 2017 -0600
+
+ Remove obsolete file.
+
+commit 7404f0bca98908521bccdfe9fe5fc84582869deb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 1 14:31:47 2017 -0600
+
+ Add ui entry.
+
+commit 0ea7b7aca30f5f0b2e0c17bac97093c797ff3397
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 29 13:00:50 2017 -0600
+
+ Add Beizer Curve Editor.
+
+commit 8fde617cc64cdfe44f61e6cc5ef6197ef2cc633c
+Merge: d664d887 f1092a70
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 29 13:00:01 2017 -0600
+
+ Merge remote-tracking branch 'origin/qt' into qt
+
+commit d664d887042bdbf4fd0a38d34834c6d4282acfd3
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 29 12:59:42 2017 -0600
+
+ Add undo/redo stack.
+
+commit f1092a70a211994ddf6bafe488427628e71341a0
+Merge: 1ed21e9e 1eafa765
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 23:39:00 2017 -0600
+
+ Merge branch 'qt' of github.com:vectorgraphics/asymptote into qt
+
+commit 1ed21e9e55effe8fb917d4a3c9903f07cdd6e228
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 23:38:43 2017 -0600
+
+ Add pyUIClass support to Makefile.
+
+commit 1eafa765e69ddb869237532ec7e9e828b30993c6
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sat Aug 26 23:14:43 2017 -0600
+
+ Add Custom Anchor dialog.
+
+commit d4e29b99c50c481bd67a46de08da95598730c72f
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sat Aug 26 23:13:24 2017 -0600
+
+ Add panning, added screen transformation layer, custom commands
+ input dialog.
+
+commit ade0b6c36cbca1bce9bfc51edefc7657e46d31c6
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Aug 25 12:58:54 2017 -0600
+
+ De-Asyfy transformation, fix local coordinates (temporary),
+ updated matrix dialog.
+
+commit 477fdd587d86bb57d8a8080a5a89401f80e6e128
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Wed Aug 23 14:16:58 2017 -0600
+
+ Add icon resource files, Matrix Transform Dialog.
+
+commit c460dce5689f9c992e0a80b150b2c67238a39c2e
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 22 17:10:59 2017 -0600
+
+ Add quick rendering, toggling of grids, more tooltips.
+
+commit 64d74954ef499b36329c5fb958dab4a38c932b52
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 22 15:54:52 2017 -0600
+
+ Add custom Transformation.
+
+commit 2f9674524c1d2231b58252b4daafd14aee478b27
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Mon Aug 21 16:45:27 2017 -0600
+
+ Fix translation & Update README.
+
+commit fd330a08614549c1497bd969f230837abcec8d7e
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Mon Aug 21 16:40:56 2017 -0600
+
+ Transition to final UI, add basic translation, scaling, rotation.
+
+commit ab2c346a05cd13fcc6e5c36ec2e9b0a100779e23
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sat Aug 19 16:40:07 2017 -0600
+
+ Move to new, Final User interface.
+
+commit efc9a0013f20fcc39872bbf42b8b1cbdbec91d35
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sat Aug 19 15:32:34 2017 -0600
+
+ Temporarily remove preCanvasPixmap (as mainCanvas
+ transparency is not wokring for some reason), add grid outline.
+
+commit 8988458f8d4f14bfb7b5e85074e7dd18d90fdc31
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Fri Aug 18 21:32:58 2017 -0600
+
+ Add mouse detection, drag translation & deferred buffers.
+
+commit f7231be3e560fa40f43e298e4b69b5c03ca0a141
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 18 14:31:44 2017 -0600
+
+ Remove redundant vbox.
+
+commit 7c5ba009606fe64da1757bdfebed51f0776a9941
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Wed Aug 16 15:42:29 2017 -0600
+
+ Change PIL to QImage.
+
+commit b69b6093485c4b42f03c26134099f54f02b497f8
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 15 14:42:19 2017 -0600
+
+ Rename xasyQt to xasy and original xasy to xasyTk.
+
+commit 52b8a33a6129219acb608abcc36248f27596965e
+Merge: fd134d02 67fe29eb
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 15 14:40:50 2017 -0600
+
+ Merge branch 'qt' of github.com:vectorgraphics/asymptote into qt
+
+commit fd134d02224c30893fc99a993643b641a6025999
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 15 14:40:44 2017 -0600
+
+ added final ui draft
+
+commit 27beaff43db806d9169f27ad0e10dd41f2a61299
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Mon Aug 14 01:00:36 2017 -0600
+
+ Add generalized Affine Transform.
+
+commit 67fe29eb902d87a6f34b6fbdd01c2a302a6b028c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 13 21:51:17 2017 -0600
+
+ Fix xasyQt.
+
+commit c66360fc91837ac6b226ccef33c5bb95bff31bc3
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sun Aug 13 16:31:59 2017 -0600
+
+ Refractor to have the raw image flipped (for native asy coordinates).
+
+commit ad49f711ce684ef85b260cb02c0f51b0558e55ec
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Sun Aug 13 15:56:30 2017 -0600
+
+ Add rotation and translation.
+
+commit 81434d3f20caec72ebad1ac758958c3ca2d13481
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Wed Aug 9 00:11:55 2017 -0600
+
+ Update .gitignore and move generated files to a separate folder
+
+commit 03617244274132af1cad89cf8c3b1617cd2d1f91
+Author: Supakorn Rassameemasmuang <mistersupakorn@gmail.com>
+Date: Tue Aug 8 16:06:18 2017 -0600
+
+ Add initial qt xasy.
+
+commit 84f4ea3ff0a564698282af8eeb1afae14907e2fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 4 15:33:03 2017 -0600
+
+ Improve equation support in module slide.
+
+commit da7e0f8adee99fadb59623bc3065acae4c523e9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 4 16:25:15 2017 -0600
+
+ Test of Qt5.
+
+commit 1b9692fae4a4f7bd58ea09f37178f7ed598f277d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 15:40:12 2017 -0600
+
+ Simplify example.
+
+commit 467e7c47c96da5c28aca1713b02bcecf75e7e166
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 15:38:54 2017 -0600
+
+ Remove broken empty flag.
+
+commit 5ec14a9d6f1f507b616db450896a7f275dd7ff3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 6 11:01:23 2017 -0600
+
+ Work around quote mangling bug when viewing asymptote.pdf in certain PDF
+ readers.
+
+commit 45f532f7b10565f05ff82c6f7b6833ef33a20712
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 22 02:29:15 2017 -0600
+
+ Increment version to 2.42.
+
+commit 40f27e1424f6c63aa362f16f3c65b9f3d1d6e723
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 22 01:56:17 2017 -0600
+
+ Always use epsdriver.
+
+commit ee57aa9c533e4a71fc20151928e5cf418d4effc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 22 00:29:27 2017 -0600
+
+ Update bug reporting URL in README.
+
+commit 207695a78f697be391991f5c943543ebeccf4e87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 21 23:34:36 2017 -0600
+
+ Remove temporary ConTeXt log file.
+
+commit a981ce85db27372750fd19aec9d4456d3bc0b21a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 21 23:19:22 2017 -0600
+
+ Support eps output with all TeX engines.
+
+ Work around Imagemagick black background bug in jpg output.
+
+commit 3e42b17ffde9941bf0ad6e24a05f73c788d755b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 20 23:05:31 2017 -0600
+
+ Remove temporary pbsdat file.
+
+commit dacbf47554b36d0571394b3c4d747405e53f2708
+Merge: f34a52df c2e4bd59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 17 01:48:29 2017 -0600
+
+ Merge pull request #38 from ivankokan/master
+
+ Add improvements for perpendicular marks.
+
+commit f34a52dfbebee7100a0d853edda78c99f1e5f2c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 17 01:20:43 2017 -0600
+
+ Use different rendering constants for Bezier patches and triangles.
+ Improve flatness test for Bezier triangles.
+
+commit 0b59b3b2b2432b3c715eb80f0305c454bd7a9e00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 5 14:17:40 2017 -0700
+
+ Fix previous commit.
+
+commit 9a2b4810156bf34c4257f08dc12595aed9867147
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 4 18:32:36 2017 -0700
+
+ Make perl look in FAQ directory.
+
+commit b3322131bebd3a506add235d25ae7ca53ab2efcd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 2 15:41:45 2017 -0700
+
+ Reduce rendering constant back to 0.5.
+
+commit 00716297f257c464e97bb0bd6b747c4034bcb97e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 2 15:10:37 2017 -0700
+
+ Remove unused variable.
+
+commit 05b6d931d5546359b061e3959817ff8d4936672a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 2 09:57:58 2017 -0700
+
+ Remove out-of-date opengl32.dll and glu32.dll libraries on install.
+
+commit 585c158ee53e4d202f1ceda5c12782a06aec57e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 2 00:18:05 2017 -0700
+
+ Increment version to 2.41.
+
+commit 5a6d3626f3589f7fdc7193dea97ae335ad70b242
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 1 23:43:49 2017 -0700
+
+ Increase adaptive rendering constant to 1.0.
+
+commit 35a65e91254f9326e70fcca3c334cc40cb5cb867
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 1 22:18:51 2017 -0700
+
+ Update to more recent system versions of glu32.dll and opengl32.dll libraries,
+ so that UNIX subdivision crack fix also works under MSDOS.
+
+commit f846f1d090b8ef8910a891a62b7ddfb945ec8280
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 1 22:09:50 2017 -0700
+
+ Fix multisample detection; remove MSDOS workarounds (tested with
+ freeglut-2.8.1).
+
+commit c2e4bd5990b9f3e6963ea80da2eb20d3a48c7a82
+Author: ivankokan <ivan.kokan@gmail.com>
+Date: Wed Mar 1 17:37:51 2017 +0100
+
+ markrightangle: margin manipulation removed (it resulted with blank area between the perpendicular mark and a line thinner than currentpen), perpendicular mark now always starts from the "middle" of lines
+
+commit 7636977c5c744ba28df9ae21c3dd7530d1beaa5f
+Author: ivankokan <ivan.kokan@gmail.com>
+Date: Wed Mar 1 17:37:51 2017 +0100
+
+ perpendicularmark: miterjoin added (aesthetic improvement and alignment with existing squarecap)
+
+commit 8de2b9cae38a5bdfc29bbe6ee8bec9def0515c5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 25 01:45:58 2017 -0700
+
+ Use Straightness also for Bezier triangles.
+
+commit d4330f044f54bce7122052a8b2e860a39944f58d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 25 01:31:01 2017 -0700
+
+ Optimize Straightness function.
+
+commit 8e6fb2dc64f2a7cf43a13f97752f2c5d902f381a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 24 10:54:48 2017 -0700
+
+ Fix straightness test.
+
+commit f72338e8be394ab6716a7b488f016bbf7d3123d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 20 11:50:43 2017 -0700
+
+ Fix CFLAGS.
+
+commit 12af4538ad099cd597c9f6b3c816823fdc0ca7d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 19 11:44:53 2017 -0700
+
+ Localize declarations.
+
+commit 23a14592eb04fd15a7d062ccc693b225e927a0fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 19 11:37:30 2017 -0700
+
+ Force draw on color change.
+
+commit 6d5ef929f22eb9d7b4f82fe2d828eb6a6b39395f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 18 20:03:01 2017 -0700
+
+ Move compare function to bezierpatch.cc.
+
+commit 5da211a76c91fc77111e4ffff2849c14846f95fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 15 18:25:34 2017 -0700
+
+ Update credits and example.
+
+commit 322fba942949338ce0b2a15e6f8a38c5c7f95ff1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 15 15:19:55 2017 -0700
+
+ Simplify code.
+
+commit 9a0372b48f142f6429015f80a18071ee77b796da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 15 07:52:52 2017 -0700
+
+ Revert "Detect material change also for specified vertex colors."
+
+ This reverts commit c7878da529adde75a929a755dae7a42b2e9a3486.
+
+commit c7878da529adde75a929a755dae7a42b2e9a3486
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 15 07:45:14 2017 -0700
+
+ Detect material change also for specified vertex colors.
+
+commit af2b9b1592e3849c5e5c986fd92c745076eedb22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 14 23:30:51 2017 -0700
+
+ Derive drawBezierPatch and drawBezierTriangle from drawSurface.
+
+commit 6036e20c654c10dc4514cc95162378578f5f15d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 14 23:29:17 2017 -0700
+
+ Don't override command-line CFLAGS.
+
+commit 53cd8fef6985ff057380289b58ba721c0bcbe4b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 14 16:52:42 2017 -0700
+
+ Work around broken CYGWIN headers.
+
+commit 5d2776ee98f73db470c4c02eb8dbb2cf02e01618
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 14 16:48:15 2017 -0700
+
+ Improve subdivision crack filling for Bezier triangles.
+
+commit f181de0b91d7fe3d0f009b096e12741fa10ebde2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 14 09:27:51 2017 -0700
+
+ Update comments.
+
+commit 97881b9e66a053fcbec8298f3cd4c47549f1fbc1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 14:12:20 2017 -0700
+
+ Fix warning message.
+
+commit 846025fa2fb7293558825b23eff3c87ad9f22e84
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 13:49:42 2017 -0700
+
+ Implement transparency workaround also for Bezier triangles.
+
+commit 064ad7478a319f0c98aaae524c72b5d068c1b359
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 11:33:35 2017 -0700
+
+ Implement transparency workaround also for Bezier triangles.
+
+commit 1c8b95b6e6f9bd0773861d233f880ff553f72ed1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 03:56:02 2017 -0700
+
+ Remove unused code.
+
+commit f2de95a07077aaf2e4c812f0cd2706be14e4f3b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 03:54:10 2017 -0700
+
+ Test empty flag in BezierPatch::draw().
+
+commit 64134306851cc52f0fc134a7c6933f79f60149da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 03:45:36 2017 -0700
+
+ Simplify code; update example.
+
+commit 42ef8903cabfc20ceef8971025d71e5a91458700
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 03:39:20 2017 -0700
+
+ Remove unused variable.
+
+commit f2964231df4f5220c07db04faccd99d05ac73580
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 13 03:36:51 2017 -0700
+
+ Simplify code.
+
+commit e209592e78c8fd8da53ee343768931a6ed23c89b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 12 23:01:31 2017 -0700
+
+ Fix example.
+
+commit 0e09443aec3a961b46dc86b1c0a388d203a1f6bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 12 22:59:39 2017 -0700
+
+ Fix example.
+
+commit e9face7d68b591bcd39a0c2a8eddc458bb6910b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 12 22:46:06 2017 -0700
+
+ Update examples.
+
+commit 31c6630d550fab51331756a4d78bc6f199b226ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 12 14:59:39 2017 -0700
+
+ Partially work around OpenGL transparency bug by sorting transparent triangles
+ by their centroid depth.
+
+commit ca09f95435e91eefcffd15050657e53debc1f829
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 12 14:52:21 2017 -0700
+
+ Fix segmentation fault.
+
+commit 8388a6050b59764a1669bd7f56aa8864c4261dfc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 11 19:49:58 2017 -0700
+
+ Update to gc-7.6.0.
+
+commit 0eb3950fd75f3ce45617a83ad1f8e30778e14d3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 8 12:21:48 2017 -0700
+
+ Fix stride.
+
+commit 7161eef9c86df2124549a42c0723610ca9e1acee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 6 16:35:21 2017 -0700
+
+ Support compilation without OpenGL.
+
+commit 723495103fb4d189f6d1ec1349ecdd01275b89b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 27 14:23:35 2017 -0700
+
+ Fix post-release version number.
+
+commit 0c0164bdaba74be22c294aebdb880c6798ab6bbc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 25 00:17:22 2017 -0700
+
+ Increment version to 2.40.
+
+commit 6895ed3fb866609fae46b01bd6e44b2f2bcf281f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 22:43:43 2017 -0700
+
+ Update asymptote.py.
+
+commit 51cb6d02c8ce6599ce9975e315308ec99af60d7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 20:20:11 2017 -0700
+
+ Remove unwanted extension from shipout prefix.
+
+commit 80b4d2b25e304a4b11c60a28082130d1a17d44dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 14:24:59 2017 -0700
+
+ Use pdf 3D label processor also for luatex and lualatex tex engines.
+
+commit e793d86adc45d3738b9b69ad20212f5c9c18c364
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 13:50:47 2017 -0700
+
+ Reduce tubegranularity.
+
+commit 9366137351acf3cf45cf7c7de563f13d5a39bb95
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 13:37:02 2017 -0700
+
+ Make invalid string casts return an uninitialized variable.
+
+ Add bool initialized(T) function for basic types T.
+
+commit 4c744193cc8fdd51d277e9566a114a589772ae4d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 09:28:10 2017 -0700
+
+ Move lualatex test into TeX code.
+
+commit 9a8586b5f6c9581eb7cb93fe9775e1756de3c5c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 09:01:40 2017 -0700
+
+ Revert "Remove requirement to call nosetpagesize() when changing to lualatex engine."
+
+ This reverts commit 70fccdee30727275b3b1cab79da18287837601e2.
+
+commit 70fccdee30727275b3b1cab79da18287837601e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 24 08:44:36 2017 -0700
+
+ Remove requirement to call nosetpagesize() when changing to lualatex engine.
+
+commit 7d9b49adf9e555e13dcea584e74bcd12f9636a49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 21 16:59:00 2017 -0700
+
+ Reinstate patch outline mode.
+
+commit a96ffbbfba55fc69b27b1c6052545bbf99ee23f8
+Merge: 0be6f556 16ae9ee4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 21 15:45:27 2017 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 0be6f55679c4b6cb0f7fe14c22b1f4b676e54d5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 21 15:45:17 2017 -0700
+
+ Add missing file.
+
+commit 1d32440f4abd08287e4b9672c98e41139540607c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 21 15:43:00 2017 -0700
+
+ Split BezierCurver render and draw operations.
+
+commit 16ae9ee4892076ca4f1ba20581cfd8001459f4fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 21 15:43:00 2017 -0700
+
+ Split BezierCurver render and draw operations.
+
+commit ee78ea2311ce61048b7e559b6a3f510eb98387c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 21 11:24:49 2017 -0700
+
+ Implement Bezier curver renderer.
+
+commit fee686ab993af55e63a877c438d2fa233059f079
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 20 23:25:26 2017 -0700
+
+ Fix offscreen array sizes.
+
+commit 56326208e7a3f341556bd3d964fffeb8e9cba0a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 20 19:28:07 2017 -0700
+
+ Optimize billboard mode.
+
+commit eb0da243e2cd1d6738efbad9e549dad8c2bfafc2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 18 00:41:22 2017 -0700
+
+ Cull offscreen Bezier triangles.
+
+commit b57705207c7b62a68ef90dacdfd5919248197135
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 18 00:20:12 2017 -0700
+
+ Cull offscreen subpatches.
+
+commit 189c89074852706cc3d8f6648dd30517465e9445
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 8 14:27:49 2017 -0700
+
+ Fix flatness test.
+
+commit a524000c1352b11fe4e3aa7d1335cc393841d29e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 7 21:04:34 2017 -0700
+
+ Fix flatness test.
+
+commit 168b1f284139482deb8044c4328a10e57fbfec47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 7 21:03:13 2017 -0700
+
+ Simplify code.
+
+commit 12363c3ba5048faca607ab2656e19d26b402b5cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 7 19:28:32 2017 -0700
+
+ Improve flatness test; simply code.
+
+commit 01f66ecfb744df300c04c760d81475b4d1e5450c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 7 19:18:01 2017 -0700
+
+ Fix typo.
+
+commit adc9c3a165b8e74ed2728ec0203ce68234629ff3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 7 19:16:44 2017 -0700
+
+ Add deepyellow synonym for olive color.
+
+commit 1cc7f83d73cbe2ece3e7e4f0e7640b2ec5cbe684
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 26 10:56:46 2016 -0700
+
+ Remove requirement to call nosetpagesize() after changing TeX engine.
+
+commit 33ed6c683a960b0a29951d3c7f8efbb15f64aaaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 25 16:50:06 2016 -0700
+
+ Implement robust workaround for graphicx.sty bug.
+
+commit 967f09a6fd79b84b8803fca8d9871c7f11f4942a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 14 11:53:44 2016 -0700
+
+ Update asymptote.sty to force nosetpagesize also with xelatex TeX engine.
+
+commit 988530d0daf78c580ed305d07d0d23e140b2b52d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 10:00:05 2016 -0700
+
+ Workaround setpagesize graphicx side effect when using asymptote.sty.
+
+commit 866ef9c47bedec14d1584b443bbcf02ba5be5b60
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 01:15:57 2016 -0700
+
+ Portably fix graphicx setpagesize bug.
+
+commit 27948832401841f1fd4c1ec6fa3f71e5a246dcc0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 7 21:49:54 2016 -0700
+
+ Fix principalBranch.
+
+commit 529bc76b4f31e59332383c3068ef4b5e41c49865
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 1 00:19:20 2016 -0600
+
+ Minor optimization.
+
+commit 4aa1ffb19dfac6705a728f6b3ddeda353dee1868
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 30 02:46:17 2016 -0600
+
+ Minor optimization.
+
+commit 4e1d019889f5609205ecc2856afacb867ed8b66d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 26 22:57:10 2016 -0600
+
+ Add paletteticks NoTicks option.
+
+commit 0a0f231cd247d3341f188fad28f00d29813cdee6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 24 23:33:49 2016 -0600
+
+ Avoid empty axis labels.
+
+commit bd70d164fb84e06f0ff8aa5cb03b08d8adbf688b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 4 22:06:31 2016 -0600
+
+ Implement improved workaround to recent graphicx incompatibilities, which
+ also works with inline TeX mode.
+
+commit 2f209f9ed847db0068c0ac85fa6c98571eeb9462
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 28 23:36:02 2016 -0600
+
+ Implement general workarounds for recently introduced graphicx and lualatex
+ backwards incompatibilities.
+
+commit afb95149c62f8c27605fc01ae75b9ce1bf678431
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 26 00:31:58 2016 -0600
+
+ Add patched version of plain.asy for TL2016 only.
+
+commit 758d08612b2895663947a31f68341caaceaf8a20
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 23 03:26:28 2016 -0600
+
+ Revert "Revert "Revert "Workaround pdflatex pdfpagewidth and pageheight bug in TeXLive 2016."""
+
+ This reverts commit 896202ca85c76a5e09c1c68193b3459600586127.
+
+commit fe2510c2d5696fa8f259e535b022cae86938c735
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 15 14:12:30 2016 -0600
+
+ Revert "Add gl-matrix javascript library."
+
+ This reverts commit 9878b4dc4358da80777666dc9cf80e351a80f937.
+
+commit 9878b4dc4358da80777666dc9cf80e351a80f937
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 15 10:20:27 2016 -0600
+
+ Add gl-matrix javascript library.
+
+commit 896202ca85c76a5e09c1c68193b3459600586127
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 4 00:07:00 2016 -0400
+
+ Revert "Revert "Workaround pdflatex pdfpagewidth and pageheight bug in TeXLive 2016.""
+
+ This reverts commit b8ef9a8ae04ac345188cb31eab591945cd2a2abf.
+
+commit 421b733a96996452bd474b80988741fdb2ece342
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 4 00:06:29 2016 -0400
+
+ Revert "Implement alternative workaround for graphicx pagesize bug."
+
+ This reverts commit 545f2b55cca742e6df16df2362fba18702171d50.
+
+commit 545f2b55cca742e6df16df2362fba18702171d50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 3 23:10:17 2016 -0400
+
+ Implement alternative workaround for graphicx pagesize bug.
+
+commit b8ef9a8ae04ac345188cb31eab591945cd2a2abf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 3 23:09:25 2016 -0400
+
+ Revert "Workaround pdflatex pdfpagewidth and pageheight bug in TeXLive 2016."
+
+ This reverts commit 61cfa1e299de53c12a6ce08305383aac18ad9216.
+
+commit 61cfa1e299de53c12a6ce08305383aac18ad9216
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 2 23:23:01 2016 -0400
+
+ Workaround pdflatex pdfpagewidth and pageheight bug in TeXLive 2016.
+
+commit d76f6754b1552eb02dca5ab53ea4836c287c3e53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 27 05:35:57 2016 -0600
+
+ Generalize palette(real[][], pen[]) to handle nonsquare arrays.
+
+commit ff41f2060c00278a13512dd66ca7424d697342c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 4 20:45:28 2016 -0600
+
+ Increase overlapedges scaling.
+
+commit 689fb9ebecdc859d438808178beb7151a0229698
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 4 20:03:11 2016 -0600
+
+ Revert "Remove obsolete overlapedges flag."
+
+ This reverts commit 154c47b6962a23404857ada45d3d7b0752f4817e.
+
+commit d0c97bff49e5bc2c89ad0b48552b971d163414a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 4 20:00:48 2016 -0600
+
+ Fix typo.
+
+commit 7ecaf8f43931d728eaf4154092cefaa4d0d0c201
+Merge: 692051a2 154c47b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 23:11:58 2016 -0600
+
+ Merge branch 'patch'.
+
+commit 154c47b6962a23404857ada45d3d7b0752f4817e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 22:59:14 2016 -0600
+
+ Remove obsolete overlapedges flag.
+
+commit 928af116df130df1e75d308c8722682e36b391b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 22:57:44 2016 -0600
+
+ Standardize flatness tests.
+
+commit 3f409fa5c904b82266ca576aa6372493b654dedf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 15:13:17 2016 -0600
+
+ Relax flatness test.
+
+commit 5dece5cdcd7bad955f1e0836664fe3f572fd75f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 13:57:03 2016 -0600
+
+ Fix flatness test.
+
+commit 12238c7d03bd61aaffcfa5ab47b51d56acadb286
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 12:42:44 2016 -0600
+
+ Fix remaining normals.
+
+commit 826469f06a43a86fdc56999a88b7fe657797ee1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 03:16:42 2016 -0600
+
+ Fix color order.
+
+commit def2d72ac3e8472c5997fada88004765bb581a41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 03:04:18 2016 -0600
+
+ Fix straight case.
+
+commit 2323c592d5a2e8fd800ce1e0b9288027dd89c88a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 02:29:19 2016 -0600
+
+ Remove unused code.
+
+commit 0bdfab4a98dd496fb0f3187edb92bc47e551a423
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 2 02:02:47 2016 -0600
+
+ Simplify code.
+
+commit f03dc5c7e6e3007cf9cc8c628daf93f6ff2fe33f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 1 13:47:31 2016 -0600
+
+ Fix subdivion cracks and zero normals.
+
+commit fdb20f62a69b5e8244f71025f349baf411e49332
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 18 15:08:42 2016 -0600
+
+ Add vertex shading.
+
+commit 31ba48ca76e1a118fde5812137366ecabca1d3e7
+Author: Andrew Bernakevitch <andrewbernakevitch@gmail.com>
+Date: Wed May 18 14:35:47 2016 -0600
+
+ Add ASCII diagrams of the Bezier patch, including a diagram of the patch and one of the key points on the patch.
+
+commit 692051a2849fa4ae074ab565319b2af22a5fc828
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 17 10:16:53 2016 -0600
+
+ Fix formatting.
+
+commit f67594a5df27ec9862c7953c13522f16e8a59387
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 03:23:35 2016 -0600
+
+ Increment version to 2.39.
+
+commit 3f044f05ca7f3d30d3f61edcf1d991bd6ccc69dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 02:16:25 2016 -0600
+
+ Move bug tracking to github.
+
+commit b9ca1650f3086a265eb9d39649261680fe032ba5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 02:05:12 2016 -0600
+
+ Require ncurses library only with --enable-readline.
+ Implement --disable-sigsegv configuration option.
+
+commit 4c1ac9da70652934fadfef75181aab7191845327
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 01:14:03 2016 -0600
+
+ Begin implementation of bezier patch renderer.
+
+commit da2c3f8c7af68645c6cff8c04f555676413e47ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 01:08:40 2016 -0600
+
+ Minor optimization.
+
+commit 8a956632265c5b540b21249d8411216788812e30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 11 08:55:31 2016 -0600
+
+ Use # operator for integer division.
+
+commit 11f06b200a9ca5382e2c15d251140e44902f0f04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 13:55:55 2016 -0600
+
+ Update CXXFLAGS and LDFLAGS documentation.
+
+commit 563d53bf8eba994e903e460361f30d93f6a5da14
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 8 22:19:25 2016 -0600
+
+ Port Makefile.in to Bourne shell.
+
+commit 04b86da8e09ed0772d46520e43e4875878aff4f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 20:34:12 2016 -0600
+
+ Fix longitudinal splitting in revolution.
+
+commit 0d7435b299f721fbe4d788edc3f5334f8bddabb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 6 20:49:46 2016 -0600
+
+ Pass CC and CXX to gc configure.
+
+commit a40b6c087091bdc15ffe44d00c51ca15cb1d4877
+Merge: 656cf976 0f1f6d1c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 6 09:45:34 2016 -0600
+
+ Merge pull request #21 from mojca/posix-test
+
+ Makefile.in: replace 'test ! -e' => 'test ! -s'
+
+commit 0f1f6d1c73ebc6b494fc23d76a1f00966de9f5fb
+Author: Mojca Miklavec <mojca.miklavec.lists@gmail.com>
+Date: Fri May 6 16:49:41 2016 +0200
+
+ Makefile.in: replace 'test ! -e' => 'test ! -s'
+ for compatibility with older shell (on systems like Solaris)
+
+commit 656cf9764dc937aa12bd50fe8dc2e0354c7c5e64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 18 16:42:22 2016 -0600
+
+ Minor optimization.
+
+commit ee9839887c7006a4e5138afe8b039669082c904a
+Author: Orest Shardt <shardtor@gmail.com>
+Date: Tue Mar 15 15:14:38 2016 -0400
+
+ correct parsing of control points
+
+commit 1032cd60aedd0dec0f376410e5fdf525eda65f39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 17:11:21 2016 -0600
+
+ Update copyright and FSF address.
+
+commit 24628251a11faf6d4e4ed0034c716cc6b4289cb6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 01:09:15 2016 -0600
+
+ Increment version to 2.38.
+
+commit 0240be5ed61de2394cc5cc614a9c4b480f2f51d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 13 23:31:54 2016 -0600
+
+ Add missing variable.
+
+commit a33a69444b667675706f42653c3620da583e0130
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 13 21:05:19 2016 -0600
+
+ Update diagnostic.
+
+commit 3a8360af8637891ad54a6d756026780286c44ea8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 13 20:57:00 2016 -0600
+
+ Merge port of xasy to Python3, courtesy of Mojca and Orest.
+
+commit 48e84c5bc8d62b7f06528682e8fd7275828345e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 13 20:45:07 2016 -0600
+
+ Add -P arguments to pngalpha ghostscript driver calls.
+
+commit d789c4df72983f70934f702a9ee3ee80fd82b81f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 12 21:59:02 2016 -0700
+
+ Make quiet suppress output unless verbosity > 1.
+
+commit 740c8c1df8127012ff983fe9979a096d0f71e81e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 12 21:26:01 2016 -0700
+
+ Make settings.quiet suppress noninteractive standard output when verbose=0.
+ Add progress function.
+
+commit bcbf941fdd0fa9db5c3b77d7a3477fa358a291ac
+Merge: 97f3b6c3 ae0af708
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 22:33:57 2016 -0700
+
+ Merge branch 'trianglewithnormals'
+
+commit 97f3b6c3958028f16e130af9a76d404b91289a0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 21:16:03 2016 -0700
+
+ Don't require kpsewhich in make check for TeXLive version.
+
+commit 121bef8befae717eb00bc550a4e94e05b73a9202
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 21:12:26 2016 -0700
+
+ Look for kpsewhich first in the same directory as the asy executable.
+
+commit ae0af708d12981318936697c7c289fe71723dabe
+Merge: 815b7381 6fc23e01
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Mar 6 20:07:38 2016 -0800
+
+ Merge branch 'master' into trianglewithnormals
+
+commit 815b7381ec98e7bd8fff428145c4ff37f4c6ef42
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Mar 6 20:04:10 2016 -0800
+
+ Revise comments on smoothcontour3 for bezier triangles.
+
+commit 6fc23e01ac254e6e016fa2ce37f190a9b3c027c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 20:07:15 2016 -0700
+
+ Improve script portability.
+
+commit ab000e7a922e6f21dc6aabad21e6dfed864acf2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 18:34:57 2016 -0700
+
+ Move compile-time check for epsdriver into environment variable
+ ASYMPTOTE_EPSDRIVER.
+
+commit 3cf0adc19ab1ca13ca70dc6e700c6386ccf73e37
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 14:20:31 2016 -0700
+
+ Add EPSWRITE compiler flag to support ghostscript versions older than 9.14.
+
+commit cbb7e37c1a8ed7168bdfb61b5c48ef775b9dd668
+Merge: 90041839 6c1ad05b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 10:04:21 2016 -0700
+
+ Merge branch 'trianglewithnormals'
+
+commit 900418390224e6f56ed33a5df55c0b47e418e1f0
+Merge: ce19f613 9a36fe85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 09:45:19 2016 -0700
+
+ Merge branch 'improverootfinder'
+
+commit ce19f613e620c3fd953417301a7d9fd1e4db3a70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 09:40:49 2016 -0700
+
+ Port xasy integer division to Python 3.
+
+commit dc788693ea22f5a6bd990a21b357af605f179e27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 6 09:36:23 2016 -0700
+
+ Port xasy color handling to Python 3.
+
+commit c16b1d2a6e320e197d41a8df8698e49810737473
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 4 23:15:13 2016 -0700
+
+ Change CFLAGS to CXXFLAGS in documentation.
+
+commit 9a36fe85944c15cbb67c5f1cf777b0bf7e5bd581
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 28 23:53:11 2016 -0700
+
+ Remove default values of fa and fb from _findroot; force margin to (b-a)*1e-3.
+
+commit 6c1ad05b445578368eec7d54842f5ae46cac1213
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 28 22:17:37 2016 -0800
+
+ Correct spacing in smoothcontour3.asy. Replace tabs by spaces for consistent spacing across editors.
+
+commit 4502339c241f74eaf2f02c9315c378f90b44e6a3
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 28 22:03:59 2016 -0800
+
+ Document usetriangles option for smoothcontour3.
+
+commit 29832acfab74cadeb749926b2db3d3ac5f965515
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 28 21:55:51 2016 -0800
+
+ Add smoothcontour3 option to use bezier triangles (default) or not.
+
+commit 50b1420e4d9e46982ab124f7319b30bc7e57b358
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 28 20:09:07 2016 -0800
+
+ Simplify reversing cyclic array.
+
+commit becf736defe152799976999c6ede67e40e5975fd
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 28 19:27:19 2016 -0800
+
+ Change adaptive rendering constant for bezier triangles.
+
+commit fc81a2ed70019cca10eed52b2caa3bff713d0d7f
+Merge: cd9f8755 e78de7f9
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 28 19:23:17 2016 -0800
+
+ Merge remote-tracking branch 'origin' into trianglewithnormals
+
+commit 184bea914c95dd92c32380bce6001916607d2482
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 24 20:56:21 2016 -0700
+
+ Move rootfinder interface to math.asy.
+
+commit e92e7571479c2024522a882b3ee95a99120c09a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 24 20:40:10 2016 -0700
+
+ Reorder tolerance parameter as in original asy code and allow user control of default value.
+
+commit e435513b1a4faa461e3ce4387461653374eecf7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 23 23:20:56 2016 -0700
+
+ Port findroot to C++ code, but reorder tolerance parameter to end of
+ signature, to agree with argument order in calls from smoothcontour3.
+
+commit e78de7f99a7b94876805b6eea9b15c7a0c164c96
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 23 20:40:48 2016 -0700
+
+ Implement minor rendering optimization.
+
+commit 87c6ee109e9a615a51ebc76d4ea92b959ea4c20d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 23 19:00:20 2016 -0700
+
+ Fix bug #219 Asymptote forks in an uncontrolled way.
+
+commit cd9f8755715b8ce7e5b239ecd77fdff4d336411a
+Merge: e6454cb2 344698e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 16 17:41:59 2016 -0700
+
+ Merge branch 'master' into trianglewithnormals
+
+commit 344698e2cf2f16379139e8473c4a0970433689e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 16 17:41:21 2016 -0700
+
+ Fix epsilon.
+
+commit e6454cb2370e412699d467f451519ab89efd3f40
+Merge: e5394afc 75ce9969
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 16 17:29:10 2016 -0700
+
+ Merge branch 'master' into trianglewithnormals
+
+commit c3099c59cc61721fa9d08e1cd7ab22ddb0026bb5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 16 09:32:10 2016 -0700
+
+ Fix epsilon.
+
+commit e5394afc350161459e7b78c28fd025f390a2f60e
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 14 22:16:08 2016 -0800
+
+ Fix overlapedges for triangular patches.
+
+commit aa8a94e605e42c9742b880c50a62cf6432309d32
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 14 22:10:49 2016 -0800
+
+ Subdivide triangles with bad normals.
+
+commit f4f03e779e9e0d7143c98ca7a4f82e41ec3c2d6e
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 14 21:57:12 2016 -0800
+
+ Make array reversal consistent with path reversal
+
+commit 58852de50bba1ee05eef4c7cd1042131006e711d
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 14 21:09:17 2016 -0800
+
+ Make the orientation of the patches consistent.
+
+commit 652f8bbc027dd78d1d2be0f5cb8af24496fea2e5
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 14 17:09:01 2016 -0800
+
+ Use quadratic interpolation for rootfinder
+
+commit 75ce99693e881bc87a25ee1a57a90e2c8a88c95c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 12 16:13:26 2016 -0700
+
+ Fix bug #217 Reversion of one point guides.
+
+commit 213d56942fe5b9ef605e0ccf545527833319348d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 12 14:43:37 2016 -0700
+
+ Fix bug #218 Core dump in subpath routine.
+
+commit b7bcfe1c90e491e8fc284ea8e746af85495fb087
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 10 01:29:02 2016 -0700
+
+ Fix str().c_str() bugs.
+
+commit 2aed7cc04bb0ab928aa6a7086b977dc90c078a5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 9 22:27:30 2016 -0700
+
+ Move \ASYdimen to asymptote.sty (version 1.30 now required).
+ Remove support for obsolete media 9 package from 2013.
+
+commit 8d0eef70c60ce380f8919f8aa8d45467f2d9c3bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 9 18:12:40 2016 -0700
+
+ Increase maxrefinements in bezulate.
+
+commit 25617a38c05e1cf7e5c0322c3cdb0b53c5f3a909
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 9 16:50:13 2016 -0700
+
+ Fix bug #215 Line adjustment won't work with scaled pens.
+
+commit 9ee82946a46323ca939a6ae10d666231486127df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 23:19:06 2016 -0700
+
+ Document in the manual that example file names link to the PDF output whereas
+ their .asy extensions link to the corresponding Asymptote code.
+
+commit 760fddca0f402acc49894b8cc81056b4b97759be
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Feb 7 17:06:50 2016 -0800
+
+ Non compiling: start maketriangle function.
+
+commit 57d9d51c1bc79c2efe55087e291c35f51790b842
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 17:00:05 2016 -0700
+
+ Update copyright date.
+
+commit 691e8ef9241001b18dd3e3ad6f667f73da76c41e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 16:57:54 2016 -0700
+
+ Fix links in documentation.
+
+commit 2ad4f66eda6e71aaf24b15e67c5a1eb5c15332ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 16:46:58 2016 -0700
+
+ Fix links in documentation.
+
+commit 7c33a39dbf1b41e29f251a81778019f722a38497
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 16:21:01 2016 -0700
+
+ Add links to documentation examples.
+
+commit d422d99bd9d22bfa57013fdf8de5d33aa637a71e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 11:12:47 2016 -0700
+
+ Fix bug #214 Minor bug in 'format'.
+
+commit 4c3480c2e5ae04e644382ceb9fa871206bcfee51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 6 23:19:05 2016 -0700
+
+ Support --disable-gl again.
+
+commit afbd271363fde72afe17f54d5c5a408d24931437
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 6 17:06:42 2016 -0700
+
+ Improve comments in beziertriangle.cc.
+
+commit 5569c8d4fd3d84f121362aa18966eb8114cbe88d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 5 17:47:36 2016 -0700
+
+ Simplify code.
+
+commit b2d975013dfec4c2163b66286eacb8e6b9a71b56
+Merge: a2dc3010 ce719ebe
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Fri Feb 5 08:34:14 2016 -0800
+
+ Merge branch 'trianglewithnormals' of github.com:vectorgraphics/asymptote into trianglewithnormals
+
+commit ce719ebe712ae40a4fd31dc5e59b6c1f382cdfca
+Merge: 30d63a35 9b9e8f57
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 23:18:11 2016 -0700
+
+ Merge branch 'master' into trianglewithnormals
+
+commit 9b9e8f579e58ce016754626275d9c03b1dc1cf11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 23:05:28 2016 -0700
+
+ Simplify code.
+
+commit ab2042f994b6dd71c204ddaa59124b7f3644ee58
+Merge: 5d97e7d7 a873617b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 23:03:06 2016 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 5d97e7d70965fefa3814f09911be2e1a74cf1979
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 22:31:31 2016 -0700
+
+ Handle degeneracy in Bezier triangle normal calculation for render=0.
+
+commit a2dc30108b3979adb818333771fed8e278bd697c
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Thu Feb 4 21:31:58 2016 -0800
+
+ Amend one comment.
+
+commit 8ec9865cc3fd4bc2cbded6e754ad4670e1920730
+Merge: 6ca10836 a873617b
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Thu Feb 4 21:20:20 2016 -0800
+
+ Merge branch 'master' into trianglewithnormals to incorporate bug fix for meshpen with bezier triangles.
+
+commit 6ca10836bade3c2540ebfbe4dc0c27ff782ad2f8
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Thu Feb 4 21:15:39 2016 -0800
+
+ Add comments documenting the trianglewithnormals function.
+
+commit b2efab65fb612318202964ae6fb80b50c925d315
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Thu Feb 4 21:11:31 2016 -0800
+
+ Simpler names for normals in trianglewithnormals parameters.
+
+commit a873617b4e481ea90c2ebce361932212b4c70df1
+Author: Orest Shardt <shardtor@gmail.com>
+Date: Thu Feb 4 16:35:35 2016 -0500
+
+ Fix hex representation of colours
+
+commit 26629e8a350204d9fbd9095e5c59ca4bda35f6d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 13:24:27 2016 -0700
+
+ Fix planar Bezier triangles under render=0.
+
+commit 64e1d1ad3777e898febba132ac0aae152882c52d
+Merge: 03a2310b 29806bc7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 01:37:46 2016 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 03a2310b72610252698115ba3d1ec44b0aba16a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 01:34:24 2016 -0700
+
+ Use git suffix for development tags and no suffix for release tags.
+
+commit 29806bc76d22752c59df49fb776f0a2f935d4331
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 4 01:34:24 2016 -0700
+
+ Use git suffix for development tags and no suffix for release tags.
+
+commit 30d63a35b8903e0a7fe45828c62bb4c1a0e0524a
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Thu Feb 4 00:04:31 2016 -0800
+
+ Modify smoothcontour3 to use bezier triangles when convenient.
+
+commit 48b96a7f01add22951ac01806d22de912f9524bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 3 16:53:47 2016 -0700
+
+ Add "git" suffix to version number for out-of-git builds to avoid confusion
+ with official releases. Simplify Makefile.
+
+commit 12d4161bd25c0eda0d95a37437ba774b04a1eacb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 3 02:44:53 2016 -0700
+
+ Increment version to 2.37.
+
+commit e469422d232659d27a70527ddffc7f106be89698
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 3 01:12:14 2016 -0700
+
+ Tune subdivision crack correction under MSDOS.
+
+commit aa11277764072052888151cd3b0f61e4bf8cfbe1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 3 00:36:18 2016 -0700
+
+ Fix segmentation faults in tab completion. Disable interrupts during input.
+
+commit d4f43f97de2f5f27d6de73c031f89404ecc0c4cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 23:31:57 2016 -0700
+
+ Fix typo.
+
+commit 68a30fa19dbb2bd921cb33acc7e8c596372101af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 22:42:03 2016 -0700
+
+ Fix typo.
+
+commit 69d2e8de9cfb1757de8e731dfb7d9cce00047982
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 22:38:24 2016 -0700
+
+ Fix syntax.
+
+commit 076c074783d62f9a3215d7fec197c93f1c9b0ba2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 22:31:31 2016 -0700
+
+ Force linking with static termcap library under MSDOS.
+
+commit 4584a9d97228811e6799752ff5a2a7b17246f4af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 10:14:02 2016 -0700
+
+ Simplify Makefile.
+
+commit 51ad22b3d66a3a75cc3034f49faf367320ec2a16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 10:06:28 2016 -0700
+
+ Fix bug #213 glmovie.asy won't autoplay.
+
+commit 93d5b9af857e0ad80e606c7d63dbce32447cc892
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 01:59:10 2016 -0700
+
+ Simplify exit handler.
+
+commit d5e86339507734fd79f4748e9b3545bda20331b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 2 00:19:13 2016 -0700
+
+ Support out-of-git builds.
+
+commit cd2e963a3df5edbc4637c93cc4af4d643a490ce3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 1 17:04:37 2016 -0700
+
+ Avoid glutLeaveMainLoop for portability.
+
+commit af5a253b6fdebd3c5994ccfee2c9ed9381c40a43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 1 01:41:57 2016 -0700
+
+ Fix asy version generation.
+
+commit 927b4826c4d3590fe0c98eb9e704a834923a41aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 23:42:31 2016 -0700
+
+ Move the genustwo image out of the documentation in case rendering isn't
+ available.
+
+commit a637f3da094105154df8d36edb8aa46183d5fb5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 23:39:22 2016 -0700
+
+ Use glutLeaveMainLoop to cleanly exit the renderer.
+
+commit 92985cc19f11946fc71648695fdc14efa7af8321
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 22:21:51 2016 -0700
+
+ Add OpenGL exit handler. Reinitialize autoplay on re-entry.
+
+commit f2b9fb741b4da18224d7ae276348902da6b71595
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 19:17:01 2016 -0700
+
+ Allow out-of-git builds.
+
+commit c0c7399cbdba43b8a77c2309e62b625371f8efcf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 19:01:34 2016 -0700
+
+ Fix revision generation.
+
+commit 100a73c67789448b909f4fcb36030d9a945849fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 18:10:34 2016 -0700
+
+ Fix revision generation.
+
+commit 0a653376ee359d6854c1a470d40387859cf1eff9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 17:37:18 2016 -0700
+
+ Fix segmentation fault due to zero normals.
+
+commit d9038241476195cb30aea8d3d6929c9d9b0e1b15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 15:50:38 2016 -0700
+
+ Move PRC api functions into a new namespace prc.
+
+commit 6692b64b6eb470c948dade9e6a58e51b13096021
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 13:19:48 2016 -0700
+
+ Add convenience function graphicscale for using graphic with the conTeXt
+ tex engine.
+
+commit b1d7e6d6d931b25e226df93cf5a123cd501a06f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 12:56:32 2016 -0700
+
+ Fix typo in 89fee36fec8a6d04d9c650e35f0170fba3f9ba4d.
+
+commit c3805bc4e3efaadec13911839200526734bcb809
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 11:10:04 2016 -0700
+
+ Do not override -render command-line option.
+
+commit 5909c90c67d3c5ba60de0397aac979ed8bbd6c83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 11:05:33 2016 -0700
+
+ Display GLUT display after batch export.
+
+commit 699cf57921476f59b5ba2318c55f639da74717ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 10:58:00 2016 -0700
+
+ Don't use threads in batch mode, except under MacOS X.
+
+commit e1eb284ff09fefc23d0eea83d79792bd6d2842e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 02:07:16 2016 -0700
+
+ Fix build issues.
+
+commit 2369d49a178d124d4d46ff0f8194b12ececac9e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 01:12:41 2016 -0700
+
+ Retain revision.cc.
+
+commit 89fee36fec8a6d04d9c650e35f0170fba3f9ba4d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 00:17:34 2016 -0700
+
+ Fix bounds calculation for straight nonplanar Bezier patches.
+ Implement a degenerate patch representation, tensor(patch), to support
+ render=0 for Bezier triangles.
+ Optimize straight Bezier triangle bounds computation.
+ Implement remaining Bezier triangle support functions for normals and colors.
+ Keep local work arrays on stack.
+
+commit 7c172e08b045497718dd883120c160790c313435
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 31 00:14:47 2016 -0700
+
+ Update dependency documentation.
+
+commit c7771bb49a8037ac23d8cc6f6b6cc7fb4fb0fdda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 23:18:35 2016 -0700
+
+ Suppress getline compiler warning.
+
+commit 504d3e865985f30bbbb3b82cc3da7d1c50a758c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 17:32:07 2016 -0700
+
+ Fix missing double backslash in asy-mode.el.
+
+commit f87cbf83b1ac2c815d9d88e7c79b7e3a33992fb3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 16:51:13 2016 -0700
+
+ Partially revert unintentional global changes in
+ fc3ef0ec22b36083ace789436004ef88452a1feb regarding structure initialization.
+
+commit 9259e447295ead5927e4970a0b894e8eb70702c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 16:30:09 2016 -0700
+
+ Fix bug #208 Quotations are broken.
+
+commit 04d236c8d4ff9669ab98f829d278bcba4784584b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 15:44:45 2016 -0700
+
+ Fix #207 Infinite loop while reading files with trailing comments.
+
+commit 352441c0e661a3d1c9a4f7ff1f17f4c817481530
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 15:32:08 2016 -0700
+
+ Respect relevant explicit file dimensions only.
+
+commit 37ad3354d905a5fdde964e43a6306642d764b6c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 15:25:32 2016 -0700
+
+ Respect explicit file dimensions.
+
+commit 76a143bf9386df4f26095872f729fe8f23043edc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 11:50:40 2016 -0700
+
+ Optimize straight planar Bezier triangles.
+
+commit 21ec47af64f6fc0d895f6468a8148e59d3239a06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 11:09:29 2016 -0700
+
+ Fix glrender quit function.
+
+commit 92615dd93332698574e6ab583907a3e495ddc554
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 10:27:41 2016 -0700
+
+ Fix #206 Bug while reading twodimensional data from file.
+
+commit d5a1cdf144ce152ccc520515ace87ca7c22c216e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 29 22:32:13 2016 -0700
+
+ Fix intermittent segmentation fault after export under threads.
+
+commit 4650f6153e2722630d177f9a6293e9f49c8ec0aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 29 19:26:04 2016 -0700
+
+ Fix floating point exception in glrender.
+ Don't iconify window in interactive mode.
+
+commit 1625eaca2240a7d04f12f07a456c1c1adea9c641
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 29 01:24:36 2016 -0700
+
+ Fix bug in rest argument signature equivalence.
+
+commit e59d44b1f641743f7eea53b18286f8ae71f7ad42
+Merge: 3fcb8827 d70ce121
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 29 00:58:56 2016 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit 3fcb88277e987140fda7d01b8dc886c2ba55ea2d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 29 00:57:41 2016 -0700
+
+ Implement Bezier triangle vertex shading; simplify notation.
+
+commit d70ce12140bcee8f60cf4b14d86345ea1a597d24
+Merge: 9a859296 4cca8cba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 28 19:45:53 2016 -0700
+
+ Merge pull request #9 from syohex/fix-package
+
+ Fix package format
+
+commit 9a85929623975d23856c6462efaf66c1b645337e
+Merge: fec79bd9 daa7b97d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 28 19:45:10 2016 -0700
+
+ Merge pull request #10 from purcell/patch-1
+
+ [asy-mode.el] Use "Major mode" rather than "Emacs mode"
+
+commit daa7b97df59ff24aaef230389c630dfdfa6a34dd
+Author: Steve Purcell <steve@sanityinc.com>
+Date: Fri Jan 29 14:21:18 2016 +1300
+
+ [asy-mode.el] Use "Major mode" rather than "Emacs mode"
+
+ Using the work "Emacs" is redundant here. Better to describe this as what it is: a major mode.
+
+commit fec79bd94f87e1532ab8f90c46ebeffa8ef68a34
+Merge: af459e8a 799d62d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 28 18:06:22 2016 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit af459e8a8919f67e38894c6430d35bc325c7ba10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 28 18:04:36 2016 -0700
+
+ Implement billboard interaction for Bezier triangles. Update documentation.
+
+commit 799d62d722ba943216dafb4db1f5a89ee9d1ffdc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 28 18:04:36 2016 -0700
+
+ Implement billboard interaction for Bezier triangles. Update documentation.
+
+commit 4cca8cbac3aae1b6fc70e3826b1cfafd55353270
+Author: Syohei YOSHIDA <syohex@gmail.com>
+Date: Thu Jan 28 08:01:22 2016 +0900
+
+ Fix package format
+
+ - Fix footer format
+ - Add missing colon at 'Version' header
+
+commit 3bae7f04bc68992f96f1c56f291940946f71d3f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 08:22:51 2016 -0700
+
+ Rename NaN to more standard nan, consistent with inf.
+
+commit 40222e2f183510bbc3e7642ab58abaae107837d7
+Merge: 6d148e9d e6a9c8c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 01:44:30 2016 -0700
+
+ Merge pull request #8 from PythonNut/master
+
+ Fix asy-mode.el headers for use with package.el
+
+commit 6d148e9d4cb76e7a62b38cd7917f13f7e6b14241
+Merge: 120804c1 b4f5fd7f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 01:32:44 2016 -0700
+
+ Merge branch 'tpatch'
+
+commit 120804c135338ad70ed74c37f6391cf2bd31143b
+Merge: eeb634e5 dda2736d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 01:32:37 2016 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit b4f5fd7f3d7dc8c296e01e21b229f1e80e5e4a9e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 01:32:11 2016 -0700
+
+ Remove obsolete comment.
+
+commit dda2736d7adc54b42fb063ad04d9818c4dac1cad
+Merge: e86faf9a 37a30365
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 01:28:31 2016 -0700
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit e86faf9a90abe8546db543ba1decb3db4709a7af
+Merge: 4243c5af bb9a29b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 01:28:01 2016 -0700
+
+ Merge branch 'NaNconstant'
+
+commit 4abd683e6bcf1c03254a05d0f80dac2da49b796e
+Merge: 62f540f3 eeb634e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 00:53:10 2016 -0700
+
+ Merge branch 'master' into tpatch.
+
+commit eeb634e5a0b9eabcc17e04166be66ba536e8f165
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 00:41:18 2016 -0700
+
+ Remove unused normal code.
+
+commit 37a30365560aa79a4aac37850774fee8c55a526a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 00:20:15 2016 -0700
+
+ Move AtA routine to C++ code and matrix leastsquares routine to math.asy.
+ Remove unused code.
+
+commit ca322df57721accecf9ae154b68a52700549b15d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 00:18:08 2016 -0700
+
+ Fix clang warning regarding std::abs.
+
+commit 81a216c7d9d5b7e42782baa7d663f0296ee1aa3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 00:17:23 2016 -0700
+
+ Fix undefined variable.
+
+commit 1d3691a096c830a8d9729797bded0432346a80d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 27 00:12:31 2016 -0700
+
+ Fix memory deallocation in copyTriples.
+
+commit 4243c5afadb408d3f4b2c3dc39ae3648724de812
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 26 23:58:04 2016 -0700
+
+ Use fabs instead of abs in page alignment code. Optimize copyTransform3.
+
+commit 46e8944d7118204a3fdfd93df6ab13574ed4817b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 26 23:28:51 2016 -0700
+
+ Work around floating point division bug in clang 3.7.0.
+
+commit bb418555390c49b393e5377f695468651f93d6df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 26 19:48:19 2016 -0700
+
+ Fix segmentation fault due to accessing "this" at top level.
+
+commit bbd447f3c277a1ebc55163c187bfd223eee93bad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 25 22:27:01 2016 -0700
+
+ Remove fixed outformat and render settings from example.
+
+commit 62f540f32b879fac92863909de8eec7fcd911b27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 24 23:21:13 2016 -0700
+
+ Don't subdivide straight segments.
+
+commit bb9a29b0449ec8b7a3a993e45981ea2930a8e07d
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Jan 24 19:06:22 2016 -0800
+
+ Add constant NaN for quiet real satisfying isnan(NaN)
+
+commit 76ee4365d32fd976117768a6b3db5f33d3284225
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 24 12:26:06 2016 -0700
+
+ Fix index entry in documentation.
+
+commit cd447e1479be3a9f30f6c476ce5fcb13a03b9cfa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 24 04:40:39 2016 -0700
+
+ Fix segmentation fault on glrender quit after export.
+
+commit b585ccab275b35b363382670d2d6a837fc699707
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 23 21:10:09 2016 -0700
+
+ Revert "Allow a user-specified normal function for rendering a bezier triangle."
+
+ This reverts commit 83d8788e40b091142617e08e9840f2cb95e2147f.
+
+commit 8b25b245c67870f5414fe0f2c07295c5b95c8704
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 23 20:54:44 2016 -0700
+
+ Express Bezier triangle as a degenerate Bezier patch.
+
+commit e6a9c8c33caf317806ad73d057d9806aef505c48
+Author: PythonNut <PythonNut@users.noreply.github.com>
+Date: Sat Jan 2 17:20:29 2016 +0000
+
+ Fix asy-mode.el headers for use with package.el
+
+commit 2d94de48d0567f29f07646b523e1be30cf5e248b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 7 00:42:20 2015 -0700
+
+ Define PERL.
+
+commit 2292b4e20cec169b8e49ffd90c266fe0c481280c
+Merge: 83d8788e 2f0e11d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 5 11:59:38 2015 -0700
+
+ Merge branch 'master' into tpatch
+
+commit 2f0e11d1dba5117c9b912713c0ea728e546ca2db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 5 11:56:51 2015 -0700
+
+ Replace perl by $(PERL).
+
+commit 098bb7af2fa3b8856942e61d911f29607597ffd8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 5 11:49:06 2015 -0700
+
+ Fix animations by running LaTeX twice.
+
+commit 83d8788e40b091142617e08e9840f2cb95e2147f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 18 04:02:03 2015 -0700
+
+ Allow a user-specified normal function for rendering a bezier triangle.
+
+commit 0819e0f712c330016b99b5e41ef44c315da82ea6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 13:27:01 2015 -0700
+
+ Remove remaining instances of Triple type (except one instance in glrender).
+
+commit bf3be19f7f1daf5730dabbf5c89e8a4f0f451a7d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 10:56:50 2015 -0700
+
+ Remove Triple type from Bezier patches.
+
+commit 454d3ff4526b775f4a70de6056d94134c535e070
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 00:50:01 2015 -0700
+
+ Begin removal of Triples type.
+
+commit 88cb6ae530ae29bd527ccb74d57734ad0f0b45e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 16 00:00:44 2015 -0700
+
+ Fix Bezier triangle bounds calculation.
+
+commit 78c5a4dc967871262371bc09a752c4f7c3a0982e
+Merge: 3bdb0da5 71ff9e76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 15 11:47:01 2015 -0700
+
+ Merge branch 'master' into tpatch
+
+commit 71ff9e769ba5d9995b367201f0d41b7a8dedab9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 14 01:25:56 2015 -0700
+
+ Support GSL 2.0.
+
+commit 3bdb0da5d7762bdc3509cbbd3aadfea392065729
+Merge: 342bd39a d7d0920c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 13 15:22:31 2015 -0700
+
+ Merge branch 'master' into tpatch
+
+commit d7d0920cfd14460443e9b7324a2f4565803eb882
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 8 14:01:03 2015 -0700
+
+ Update FFTW++ files.
+
+commit d98ea127a2e5406695f565b32f0ca108f5d7d652
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 20 16:49:54 2015 -0600
+
+ Sort patches by projected distance.
+
+commit 27ff6755e9aa215897582437ffdec4fab802439e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 18 09:21:25 2015 -0600
+
+ Only create initdir if localhistory=false.
+
+commit e46e8fde24b98a5ef21e4987c9658eda173c7bcf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 12 10:32:37 2015 -0600
+
+ Fix numerical precision bug in smoothcontour3.
+
+commit 342bd39a699140df5a3f14778e8650a674968980
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 3 02:02:23 2015 -0600
+
+ Implement bezier triangles in surfaces.
+
+commit ca9e11656fbf984095574d831b7e04a01881c3be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 2 13:42:10 2015 -0600
+
+ Implement patch member functions for Bezier triangles.
+
+commit 45fff990d00b3dee968203b10e2cb8515f7a3662
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 28 18:18:42 2015 -0600
+
+ Implement preliminary Bezier triangle constructor.
+
+commit 583fa290fc5eedb0a2913d132ad3dc6ea1284672
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 28 17:51:09 2015 -0600
+
+ Use unnormalized normal in degeneracy test.
+
+commit 16375adac6c947afa34d6626e40a7872a636bea6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 28 17:00:01 2015 -0600
+
+ Optimize degenerate normal computations.
+
+commit c27701a82588751d407f6558664caa89f520cf44
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Fri Aug 28 15:22:57 2015 -0600
+
+ Optimizations for degenerate normal computations of Bézier triangles.
+
+commit e8232ba4732836b3b12b552d6e2517730d479079
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Thu Aug 27 14:49:08 2015 -0600
+
+ Add higher-order normal computations for degenerate Bézier triangles.
+
+ - Depending on the magnitude of the computed normal, higher order
+ derivatives are used as needed.
+ - Normals are now computed relative to the central sub-triangle, which
+ aligns better with the symmetry and (seems to) avoid degeneracies.
+
+commit 9607b89ce3b1dd6f41905b3ca7225304a78a4236
+Merge: b186e65a e660681e
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Tue Aug 18 10:56:13 2015 -0600
+
+ Merge branch 'master' into tpatch
+
+commit e660681ebbbd374ce253ac4acfeeb35c915e9681
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Tue Aug 18 10:13:02 2015 -0600
+
+ Update ignore file to include .dSYM files.
+
+commit df296910c6f09b5c32ed6ed21f6a95f6abf31a82
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Aug 16 18:58:58 2015 -0700
+
+ Give read-only git command in documentation.
+
+commit 6a4cc1c35b18138e29bc1f4adb877479840bea1a
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Aug 16 18:21:46 2015 -0700
+
+ Remove extraneous import in doc/genustwo.asy.
+
+commit acfd5cf8d54dec2bd76eedce85aa1c95c397b25e
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sun Aug 16 18:16:23 2015 -0700
+
+ Rename example lemniscate.asy to genusthree.asy and add explanatory comments.
+
+commit b186e65abfe84163c2f25a785186998d539b3980
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Thu Aug 13 17:34:20 2015 -0600
+
+ Simplify test for flatness of a Bezier triangle.
+
+ Also minor formatting changes and performance optimizations.
+
+commit 619e46ba9a321182b6766661b7c17c72036eb55a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 13 13:45:48 2015 -0600
+
+ Fix size3 computation. Use alternative shift for removing subdivision cracks.
+
+commit 0f412644c1e3a0a802a3b69b1e23ebbe352dcd55
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Wed Aug 12 16:44:28 2015 -0600
+
+ Subdivision cracks are only filled when necessary; clean up comments.
+
+ Only when an edge of a sub-patch transitions from non-flat to flat is
+ the middle vertex shifted to cover the potential crack.
+
+commit 6f39592e491ba315065a66d329fa5c9936763e16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 11 13:37:18 2015 -0600
+
+ Simplify and optimize straightness and flatness tests.
+
+commit a5148efe0fcc8ccedc46537c697c2131bb9de356
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Tue Aug 11 11:06:29 2015 -0600
+
+ Added non-adaptive renderer for Bezier triangles (testing).
+
+commit f2dad19906c350e45ea746b363f5b38cacdba51f
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Sat Aug 8 10:38:56 2015 -0700
+
+ Add documentation for the smoothcontour3 module.
+
+commit 75d296d045d374f74a5a55daba15fe0caeed5966
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 7 14:49:02 2015 -0600
+
+ Use vector container for bezier triangle vertices and normals.
+
+commit bf4fd0d0e0719295e97ea8befaa4def2cd197dfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 6 18:03:19 2015 -0600
+
+ Condense code.
+
+commit afc9bb50d32bc30a60e8ec14130f459ee3d07324
+Merge: 83115611 6d640996
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 6 16:59:34 2015 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote.
+
+commit 8791d101a628f7e3d16398f2302f21853d522d2a
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Thu Aug 6 16:01:54 2015 -0600
+
+ Remove old, unused comments.
+
+ - The function renderBisec() is now gone, as it is severely outdated
+ (and its output mesh does not look as good as render()'s).
+ - Other old commented out tests are removed.
+
+commit 83115611436bd41a611ee316e03eeaaae31e0f0a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 6 00:26:15 2015 -0600
+
+ Fix readline and gc configuration.
+
+commit 611ecadfcfad2df353278388b99a96521227f8d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 6 15:40:24 2015 -0600
+
+ Simplify code.
+
+commit 9a719d5a367ea6bb04ccc7d43d1b9d9ef8461ccf
+Merge: 10b58e6f 6d640996
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 6 15:03:39 2015 -0600
+
+ Merge branch 'master' into tpatch.
+
+ Conflicts:
+ configure.ac
+
+commit 10b58e6fb9c66b725c78afa5b18c356deeaa5d70
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Thu Aug 6 13:23:20 2015 -0600
+
+ Move the computation of normals to reduce redundant computation.
+
+ Before, normals were computed as triangles were pushed to the indices
+ array. However, this caused the same normals to be needlessly recomputed
+ (up to six times, half of which we cannot avoid without a major
+ overhaul).
+ By moving the normal calculation to occur at the same time as the
+ vertices are added to the buffer, most of the redundant normal
+ computations have been removed.
+
+commit 6d6409960d4e1c558fe29e008849354cced4dee4
+Author: John Bowman <bowman@cascade.math.ualberta.ca>
+Date: Thu Aug 6 00:26:15 2015 -0600
+
+ Fix readline and gc configuration.
+
+commit f98f52f1a9f5e235d7d7803d167cdfe02618a8e4
+Author: John Bowman <bowman@cascade.math.ualberta.ca>
+Date: Wed Aug 5 23:43:41 2015 -0600
+
+ Fix configure.
+
+commit b742f1cea57be805f7480bcba9702d33d85c29d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 5 14:08:40 2015 -0600
+
+ Fix configure --enable-gc.
+
+commit e13974901f1b3fca83f1424056c42a150e03aaf3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 5 14:08:40 2015 -0600
+
+ Fix configure --enable-gc.
+
+commit 36e902acfbee47560473e4a66c4ae921f969bc6e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 5 12:39:15 2015 -0600
+
+ Update to latest beziertriangle.cc.
+
+commit f27143b2c09b588397d2a357b6663f9872ab1526
+Merge: ce5d022f 8f3274d4
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Wed Aug 5 12:35:30 2015 -0600
+
+ Merge branch tpatch of github.com:vectorgraphics/asymptote into tpatch.
+
+commit ce5d022f62ed7f836a20832bd502726b6c38f816
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Wed Aug 5 12:27:33 2015 -0600
+
+ Add missing file beziertriangle.cc; improve bounds checking.
+
+ The implementation for Bezier triangles now compiles.
+
+commit 8f3274d4b9fea2c5afbce309019779c71874f387
+Merge: 6510a213 b1041ff1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 5 12:20:34 2015 -0600
+
+ Merge branch 'master' into tpatch.
+
+commit b1041ff1ac39490a5729e3851f760d3a8afc8e54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 5 12:19:11 2015 -0600
+
+ Update ignored files.
+
+commit 18942d691550eeb37826c1fc06e46b7ad361a3c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 5 12:18:11 2015 -0600
+
+ Add example.
+
+commit 0c9443bed41f84d8c38deac9df0be0c62474ebf4
+Merge: 6510a213 421cd19d
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Wed Aug 5 10:28:02 2015 -0600
+
+ Merge changes in master branch to tpatch.
+
+commit 421cd19d01577dab0f3b92d89eaf1e1edf6487c2
+Merge: ecae5ee6 94fb5fb6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 4 18:01:02 2015 -0600
+
+ Merge branch 'master' of github.com:vectorgraphics/asymptote
+
+commit ecae5ee663aab1a18f4e7ba22c3943df68729f54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 4 17:54:37 2015 -0600
+
+ Update INSTALL.
+
+commit 6510a213c1796ca03fce1c190300be98f2ddc208
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 4 17:54:37 2015 -0600
+
+ Update INSTALL.
+
+commit 94fb5fb6792662366f0d0d9587bb2504a71c77bd
+Merge: 2cb41a4e 86920ebf
+Author: johncbowman <bowman@ualberta.ca>
+Date: Tue Aug 4 17:14:19 2015 -0600
+
+ Merge pull request #1 from phro/ignore
+
+ Update list of ignore files to include the FAQ.
+
+commit 86920ebf9df177045cceaaf77245eefb6d037790
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Tue Aug 4 11:52:45 2015 -0600
+
+ Update list of ignore files to include the FAQ.
+
+commit 5f133444335014674347e56e5bc55f817c3b3cab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 4 14:19:49 2015 -0600
+
+ Implement preliminary Bezier triangle rendering.
+
+commit 2cb41a4e63d839fe2588ec08a8f46038cdc7253a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 3 10:16:26 2015 -0600
+
+ Remove unused code; update list of ignored files.
+
+commit 535e8daeb3e6c555dca9fc85281dc42f4ac5f74a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 1 20:46:22 2015 -0600
+
+ Convert remaining subversion references to git.
+
+commit 651884410a8a408f5d6e3e09c191b51f318d182e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 1 20:35:58 2015 -0600
+
+ Update documentation for git.
+ # doc/png/LaTeX-usage.html
+
+commit ce373e1267e1980aca6aefd86822c7daf92cc6d8
+Author: Jesse Frohlich <jesse.frohlich@ualberta.ca>
+Date: Mon Jul 27 14:49:26 2015 -0600
+
+ Modified version checking for the conversion of repository to git.
+
+ - Added a .gitignore for untracked files
+ - Version checking now uses `git describe` instead of `svn info`
+ - Removed references to SVN (except in the documentation).
+
+commit 19935165f3617e48f129c5d4f29bca8b4891a885
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 21 20:12:50 2015 -0600
+
+ Fix bug #192.
+
+commit 9dc3510333a92b71d735ed8ed47f33ac7becb368
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 20 17:18:25 2015 -0600
+
+ Revert 2.35-2.
+
+commit ee5e0e6b05d98db0896c5507870d8d5b74fdc294
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 20 17:17:48 2015 -0600
+
+ Close input file before deleting it.
+
+commit 4b00bd5297ad91a56af7c74e59a1854865749e8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 18:25:19 2015 -0600
+
+ Increment version to 2.36svn.
+
+commit 4d0f494686133e553744bf7224e8de9e71a9fe66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 16:19:23 2015 -0600
+
+ Update documentation.
+
+commit 84499463e395a2953059b659afe614a9f207c083
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 15:43:15 2015 -0600
+
+ Work around eps2write bug that forces all postscript to first page,
+ breaking multiple 3D xelatex and context labels.
+
+commit 9c773c0f665eaeee061ce44e2bf76b43419b9c24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 14:31:06 2015 -0600
+
+ Replace duplicate files with symbolic links.
+
+commit eb674d6156054584fcc2a462ff4291fb45b65813
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 13:51:02 2015 -0600
+
+ Support rendered 3D context images.
+
+commit f77d4b0755136d8cbe09cd4ef6eb4bc34bf1ab79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 11:04:51 2015 -0600
+
+ Increment version to 2.35svn.
+
+commit 58a66182ae47112741ec73b2d6e0f61c9e4f51a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 16 12:41:33 2015 -0600
+
+ Update ghostscript URL.
+
+commit ffc1bc4ddbd6b9480e050db5f617f57dfe46f806
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 00:45:17 2015 -0600
+
+ Improve readability of named pen colors documentation.
+
+commit a4fd4d552fde1ee9ecdd973d2936439ff4c3585d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 00:39:39 2015 -0600
+
+ Add surface cone(path3 base, triple vertex) to construct an approximate
+ cone over an arbitrary base, courtesy of Charles Staats.
+
+commit c09d358301e167f872bcf75c12745a40706c21bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 00:07:11 2015 -0600
+
+ Update documentation; remove obsolete cygwin patch.
+
+commit 4c769e62cd6d96c3f9f67e1c66796325a3513614
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 13 09:00:23 2015 -0600
+
+ Add test for Ghostscript 9.14 or later.
+
+commit ceca1ed11db34ac423d58dbc41a2dddc55872700
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 10 23:45:09 2015 -0600
+
+ Increment version to 2.34svn.
+
+commit a8811fb8386f782a5774a3b102892efc13347a88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 10 22:35:32 2015 -0600
+
+ Enable progress reporting if verbose > 1.
+
+commit 22bd2d4f493b5afc4d8dc3667995d71194cec4db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 10 22:09:46 2015 -0600
+
+ Update to gc-7.4.2.
+
+commit 48de4019eb5d5539d8bccd9626b93b4e84414656
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 10 21:30:56 2015 -0600
+
+ Implement aligndir option for aligning picture to arbitrary point of page
+ boundary.
+
+commit 6c0219cdba0907038cd935b764cc28159071f685
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 10 17:50:49 2015 -0600
+
+ Fix default.
+
+commit 1ab06dabc6aa79b4a9c7dd0068dbe73076965598
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 10 17:47:40 2015 -0600
+
+ Add \def\asylatexdir{DIR} option to support pdflatex -output-directory=DIR.
+
+commit fd33ea8828db5e2f5bc4b374fed9810b3d5f16f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 12:43:31 2015 -0600
+
+ Added Charles Staats' smoothcontour3 module, with example.
+
+commit b5c417139db78281c926a91713c418b681b915f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 11:42:00 2015 -0600
+
+ Fix definition of SimpleHead.
+
+commit 2a34461017a2d05d95e2d1a8768fb248a97487f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 09:01:42 2015 -0600
+
+ Remove outdated comments.
+
+commit d6b39082b10ff1ca98ff3a32e75734a00f26a467
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 08:52:49 2015 -0600
+
+ Fix image dimensions.
+
+commit 87d6aa316273693cc4550c59bc6f31118f6b67d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 08:42:04 2015 -0600
+
+ Change default meshlight to nolight so that mesh lines with positive width
+ appear consistent with default single pixel width mesh lines.
+
+commit 387f777b59014fbe2dbddcb53767f3413fb30121
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 7 19:00:00 2015 -0600
+
+ Fix cond handling in parametric surfaces.
+
+commit e5a05d458b74767054aa510eeb721ff652243d33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 7 12:25:16 2015 -0600
+
+ Fix sign.
+
+commit e310c0f312936d878cea4633726a649bbbba5f7f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 7 12:22:07 2015 -0600
+
+ Fix path arc(pair B, pair A, pair C, real r).
+
+commit faa0033acfb6724a7cc1aaa56a0658fbc86a01be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 26 20:03:36 2015 -0600
+
+ Work around backwards incompatible dvisvgm pt to bp unit change on 2014-04-09.
+
+commit 9040319f6f982a400450d10f4aff01016a745940
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 8 16:55:28 2015 -0600
+
+ Force deconstruct to use the C locale.
+
+commit bc6e637938ef8f55f8e6f4947cc0d3d8c09f6400
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 23:07:04 2015 -0600
+
+ Fix mismatched array delete operator.
+
+commit 8815ffb186bf0b4237449b4b7a1277abf5751d6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 18:18:26 2015 -0600
+
+ Work around missing epswrite driver in ghostscript-9.15.
+
+commit c54a574d1651409338755f5b8053bc5df65f487d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 26 15:01:22 2015 -0600
+
+ Remove obsolete workaround for an Adobe Reader transparency artifact.
+
+commit 71be140eb57bd5fdc78184f70085cfc59fd224d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 10 10:29:51 2014 -0600
+
+ Fix inline option when importing asymptote.sty with xelatex.
+
+commit f96c6012571c7730d8e2f27c25bebe76200a8108
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 10 10:09:16 2014 -0600
+
+ Fix documentation and example.
+
+commit d1b3c93701690dadbb6860d4a4ae6aa9cec4bef4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 10 10:08:50 2014 -0600
+
+ Rename function argument of integrate in ode.asy to correspond to documentation.
+
+commit 837732414bad047f36c6bb5f90865f2e369cdb02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 10 10:01:12 2014 -0600
+
+ Simplify code.
+
+commit 5951acaf37553526e3791312b88dfd30d9444bf1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 24 15:20:00 2014 -0600
+
+ Remove ambiguity from min(guide) and max(guide).
+
+commit 3008a5d5e97a17d17f62d14bf415312e9b9bece1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 24 14:43:54 2014 -0600
+
+ Indexed figures should always be stepped.
+
+commit dcaac67c5c1321b8f4d5d60b6333b74908ffe2d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 16:44:23 2014 -0600
+
+ Fix overlap fuzz parameter.
+
+commit 26bd9c01a123125af867a0a9f05d395cd82ed383
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 14:51:28 2014 -0600
+
+ Implement and document intersect(path, surface).
+
+commit 5264dc6549a4b970494268a9b9e1fc7aad9599db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 6 16:59:31 2014 -0600
+
+ Fix zoom/menu button.
+
+ Fix play option.
+
+commit 5acad030c52fed21506a03dba862e3e703ae2db7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 26 10:57:02 2014 -0600
+
+ Implement 2D scalar cross product.
+
+ Improve documentation of orient and insphere functions.
+
+commit 3bb879f344ba646c59666804f665ca2ad1c37f76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 23 00:39:03 2014 -0600
+
+ Increment version to 2.33svn.
+
+commit aab6ce9a7b4cbb5acd388341e7ed18c93eec447b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 22 09:40:58 2014 -0600
+
+ Allow overriding CXXFLAGS with CFLAGS so that make CFLAGS="-g" disables
+ optimization (for debugging).
+
+commit 673f282372345e1b16afa56621f05c80c90f60cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 22 01:12:56 2014 -0600
+
+ Rename side(pair,pair,pair) to orient(pair,pair,pair).
+ Also provide interfaces to orient(triple,triple,triple,triple) and
+ insphere(triple,triple,triple,triple,triple).
+ Fix and update documentation of orient, incircle, and insphere.
+
+commit e5cfca855b2103b44863ad14680eba3ffa8e4c50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 19 13:16:29 2014 -0600
+
+ Use gs instead of convert to generate latexusage.png.
+
+commit 43d4956ed3e03a9eb692f218cddcf590597c0194
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 19 08:27:39 2014 -0600
+
+ Guard agains random() returning a 16-bit result.
+
+commit 887886fda5397d80f841bdc18055a3eba3c9147f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 19 00:53:09 2014 -0600
+
+ Use random() instead of rand() everywhere.
+
+commit e5884384ba49856467921fccee133505007e3024
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 19 00:44:20 2014 -0600
+
+ Use RANDOM_MAX rather than nonportable RAND_MAX.
+
+commit 43e146ccb44494e6ff41a273264d457982a2d4b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 19 00:43:14 2014 -0600
+
+ Fix version mismatches when releases are imported via svn.
+
+commit 815c23058dedee81fff90b9703d5470da568999f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 18 15:19:31 2014 -0600
+
+ Test that unitrand is in [0,1].
+
+commit 35bc98ccc26a9631bfe0c0e803421dac32aff46a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 18 12:14:26 2014 -0600
+
+ Remove obsolete test for texi2dvi4a2ps.
+
+commit 6ce8f7be7c4188702832936aad1963fa43f86bd8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 18 11:16:55 2014 -0600
+
+ Suppress compiler warnings.
+
+commit c74a6fa979efc2faa65d3a825d8d8dbbdb8e2bce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 17 13:24:35 2014 -0600
+
+ Document context tex engine.
+
+commit cf658a84fa4f9559881f25dbeb52615c63dbaf48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 17 09:54:46 2014 -0600
+
+ Enable libc++ workaround also for FreeBSD.
+
+commit 1fda160c4ec958643b1db59e5a5ac267fe1fd8cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 17 02:43:23 2014 -0600
+
+ Fix segment(bool[] b).
+
+commit 906ed8354d900fce7a773918f63cfcc2716eb791
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 17 02:02:09 2014 -0600
+
+ Increment version to 2.32svn.
+
+commit a35298302fafdd633be3684e2206823f584214ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 16 23:32:06 2014 -0600
+
+ Fix hangs in 3D font generation and the "none" tex engine.
+ Disable the MacOS 10.9 libc++ workaround on other platforms.
+
+commit 8bb07a22fecfb7a45c7263cb3ddc59e696378b1b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 16 18:59:29 2014 -0600
+
+ Increment version to 2.31svn.
+
+commit f3b4f36a04b7811d2da33915a911d8b2d91d4101
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 16 16:45:44 2014 -0600
+
+ Fix zoom/menu button.
+
+commit 1ff6bfaffecd392400c967ced8b099c41e1786e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 16 15:15:33 2014 -0600
+
+ Workaround broken stringstream in MacOS 10.9 libc++.
+
+commit 116aed3e51ebc40e616ab8be671b6b546ad6c9ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 16 10:00:52 2014 -0600
+
+ Remove optional space.
+
+commit d7cf1c526194a0ad4e6302dcd0502bb6f97b1f21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 16 09:45:21 2014 -0600
+
+ Add CXXFLAGS.
+
+commit 40191b8489e7d0a7353ae095a42def96783a0a6c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 16 00:11:20 2014 -0600
+
+ Use blocking reads by default.
+
+commit ef53cfa578c42f47dba80865b0e55ad490b78f34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 22:15:21 2014 -0600
+
+ Simplify code.
+
+commit 153786ecdf9663ffb8bd81d7740c5b6c54f270ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 22:13:58 2014 -0600
+
+ Revert temporary division by 0 in transform of a triple workaround.
+
+commit 4506f002e141a10036b643bd8fc5148d0a165c09
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 14:16:42 2014 -0600
+
+ Support 3D for all texengines (but prc only for latex texengines).
+
+commit f91f293cf477235d1de48237263ebb2e0f4a9354
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 10:56:24 2014 -0600
+
+ Improve TeX pipe interaction.
+
+commit 72d872d6e72a8511595179a59b0f01804c5e29ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 09:28:22 2014 -0600
+
+ Suppress warning messages.
+
+commit 2215a2cfd706dbd24fb2094aa3380cb035724fd6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 09:09:25 2014 -0600
+
+ Fix typo.
+
+commit ff2712d3618f318bf6db02e4c648bcc3cb184eb7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 08:34:10 2014 -0600
+
+ Use standard STL include.
+
+commit 8fd6bbe57cf7e66f2c83fc10e074fea292336683
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 03:22:27 2014 -0600
+
+ Increment version to 2.30svn.
+
+commit 2e960e254b94517748900132fbc2000eef0bb5f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 15 01:52:40 2014 -0600
+
+ Enable page breaks and 3D OpenGL with ConTeXt TeX engine.
+
+commit 5d075b9a5b11339805274fce6f8e2c19281ea4df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 23:28:38 2014 -0600
+
+ Fix inlineimage.
+
+commit e5eaf4cff2216fbff79fd8fd0ce3851baaf50e86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 22:54:25 2014 -0600
+
+ Fix inlinetex.
+
+commit 3be75974318793c71bf8ded449200db2c4da40ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 19:02:41 2014 -0600
+
+ Try to recover from division by 0 in transform of a triple.
+
+commit 05dda17c86f49194e00e4a69d1feb43928cda860
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 18:16:01 2014 -0600
+
+ Use list unconditionally.
+
+commit d9c4961a64b6dd3de6afe133077121a46aefc7f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 18:03:50 2014 -0600
+
+ Fix typos.
+
+commit 4158adf56fe355f719357a6bdd96911092265180
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 17:34:17 2014 -0600
+
+ More portability tweaks.
+
+commit e4276c4bf1b6c901e92b3c9178639c7446225128
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 16:44:10 2014 -0600
+
+ More portability tweaks.
+
+commit f39be071dfe433f17f2320dc696a54de76f1a08c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 15:49:17 2014 -0600
+
+ Simplify code.
+
+commit 39595952a0fa67fd389321f31abedf77d09f59a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 15:43:56 2014 -0600
+
+ Update reference card.
+
+commit 1a0b7b7f7f6ce640645d7425c5a852d2628b76c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 14 00:06:11 2014 -0600
+
+ Remove duplicate variable.
+
+commit 6f907f069ad9afe6e196ff3409ad4b77629ddb3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 13 22:51:12 2014 -0600
+
+ Reinstate tailequals to support MSDOS in bidirectional tex pipe.
+
+commit aa55151ab18c1ae55a6db2cf02438fd3f72fe695
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 13 21:04:05 2014 -0600
+
+ Improve bidirectional pipe; re-enable context tex engine.
+
+commit 1b358479976b72db51759ea295d7195c5fdc641a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 13 00:23:51 2014 -0600
+
+ Remove support for the ConTeXT tex engine since piping is broken in the
+ latest (mkiv) version.
+
+ Add support for luatex and lualatex.
+
+commit a25e92d4aad28aa4c2e0c9cf3379e8c93b061077
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 12 19:38:09 2014 -0600
+
+ Update ConTeX support.
+
+commit c67f96b85e7ffd05caeb3c2cbc593d553fbfca25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 12 18:59:22 2014 -0600
+
+ Portability tweak.
+
+commit 539e4b1a6ab1c7adfee52e5d08630ee57df7428a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 12 14:12:43 2014 -0600
+
+ Remove dependency on \put (contributed by Mojca Miklavec).
+
+commit 1b8c235a646a33c38915424adefe7d671e2a07aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 11 17:27:29 2014 -0600
+
+ Increment version to 2.29svn.
+
+commit a21ae576230fe42f202576d4702337b1e6cb4813
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 11 14:56:56 2014 -0600
+
+ Reduce number of allowed bezulate refinements to maxrefinements (default 7).
+
+commit 4d62b40e408a110bc6aee8b0c536c8244681c2b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 11 14:55:52 2014 -0600
+
+ Avoid numerical overflow in quadraticroots and cubicroots.
+
+commit 359e481bae444a08d7b5e3a2899c427b15e477ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 11 10:22:34 2014 -0600
+
+ Update splitpatch example.
+
+commit 14c8b1ff484d05b023e933de08d0c21db97e4dd0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 10 20:09:33 2014 -0600
+
+ Install refs.bib with slidedemo.asy.
+
+commit 245f3baeac8ffc6f0988936787f96deab71da748
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 10 17:32:43 2014 -0600
+
+ Fix locale bug.
+
+commit 7acc6ad91a663cfdf7aa8b94541495e7a60ab60e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 9 08:52:54 2014 -0600
+
+ Remove minimum window constraints (use viewportsize instead).
+
+commit 904beb18cea5434833b4e2793102eb83291c726a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 8 11:25:35 2014 -0600
+
+ Fix discussion of new T.
+
+commit a03fd01057e07e258733190f89045e6bacabac70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 8 00:24:42 2014 -0600
+
+ Update links.
+
+commit aee5114c91da4eda46ecf6ff679b604ffb834ae8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 8 00:15:03 2014 -0600
+
+ Work around PRC viewport issue.
+
+ Simplify OpenGL minsize code.
+
+commit 636f9b9ae471dda6dfb2d24192948f0702adc1d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 8 00:14:01 2014 -0600
+
+ Update link.
+
+commit 641f0087ca7e984264b1604e77826cc5013ab5f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 7 11:02:33 2014 -0600
+
+ Fix calculation of minimum width and height for OpenGL window.
+
+commit 884dbe2975df61c02b1702a8eb1d136f5eb76230
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 6 19:26:10 2014 -0600
+
+ Fix transform(u,v,O).
+
+commit f843adbcf329e75a71f0c3b9feb05ec6bddd0c70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 5 09:58:15 2014 -0600
+
+ Add optional parameters to hsplit and vsplit.
+
+commit 3e3cf1484ea8838ab1577d9541346e9ca8cb00d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 28 12:10:05 2014 -0600
+
+ Increment version to 2.28svn.
+
+commit 47b4f65c1723103f158a7d6c93b996007e05975c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 28 09:46:10 2014 -0600
+
+ Move Adobe transparency workaround to C++ code to allow use of texpreamble
+ again with the pdflatex tex engine.
+
+commit f6e34a476966f6ef173078f97e9de6b22ec38339
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 26 13:40:55 2014 -0600
+
+ Increment version to 2.27svn.
+
+commit ebd0f3956cce6452f03be38f3d8895493b638fef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 26 10:59:00 2014 -0600
+
+ Update flex patch.
+
+commit dcdd417934a8cb30186e75cdc4a0bc28c6c0e7e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 26 10:24:56 2014 -0600
+
+ Don't test for an svn release if special file svnrevision is missing, so that
+ release code imported via svn still uses the official release version.
+
+commit 1b3a42c12d3f0f1b3e5c2338a84e78ccccb27230
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 25 20:58:03 2014 -0600
+
+ Test for POSIX 2008.
+
+commit 07156b7672da2a75cca1f2ffe51a794d0651e15b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 25 20:57:06 2014 -0600
+
+ Address portability issue.
+
+commit edb7d9e4dead125cfafc12eb9aedfbf4112dd99a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 25 20:52:07 2014 -0600
+
+ Support c++11.
+
+commit a0795aee061ca38f664e44ee0812792ee8e7e20e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 25 09:58:48 2014 -0600
+
+ Use unordered_map if __GNUC_PREREQ is not set.
+
+commit eae6b2f4e3a0a1924d0f5a9ce4e4812fe14da6e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 22 10:36:57 2014 -0600
+
+ Update documentation.
+
+commit 68d1882e82485dc25e9ed4d70ee18a1a5393d6e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 22 08:57:14 2014 -0600
+
+ Fix degenerate HookHead and SimpleHead arrows.
+
+commit 9d3365092484d3b47b770361a33d1e333675f7ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 21 22:56:24 2014 -0600
+
+ Remove unused files; update references.
+
+commit 841020fba6f2052b53e2c7b0781ef23ba4a1f19b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 21 14:24:14 2014 -0600
+
+ Make xasy terminate asy process upon exit.
+
+ Use winpad as the default code editor under MSWindows.
+
+commit b31b715597cf052fec0cdd0fd13eaa2a33a517b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 21 11:08:02 2014 -0600
+
+ Fix xasy code editor under MSWindows.
+
+commit a498cbda30967e2858db55a499aa7351b9d688f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 20 13:06:53 2014 -0600
+
+ Miscellaneous CTAN updates.
+
+commit b26e75cd2c6f8e167d182c5ff2ced81988cb594b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 20 02:57:11 2014 -0600
+
+ Increment version to 2.26svn.
+
+commit 78a0104496fa647a67847923ee8a05d3fb6d7dd5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 20 00:12:08 2014 -0600
+
+ Update SVG documentation.
+
+commit c1a7c777bea03d4aa17a6759c0a70aa48bc98a56
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 14:21:13 2014 -0600
+
+ Fix Boehm gc compatibility issue with compact option.
+
+commit 7251dffa726b6747616f18fd1a8f25f4be3ded6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 14:19:12 2014 -0600
+
+ Add brace routine contributed by Charles Staats.
+
+commit 9dce9523d3b9f21c95a94c21ec3c55fa74661cfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 14:12:19 2014 -0600
+
+ Allow code editor command line options.
+
+commit d183f721ec1db229bd5ee8bc0d77f73b1c5fdef8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 11:13:02 2014 -0600
+
+ Apply noplaybutton workaround only to new versions of media9.
+
+ Add link to the excellent tutorial written by Charles Staats.
+
+commit 61814f95a498757e6fcbb212a1a39a865c5d2ad8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 09:50:38 2014 -0600
+
+ Fix numerical precision issue in makepen.
+
+commit 5b6990c4a62afd01161b5cc79489dd8c5f55b93e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 09:26:31 2014 -0600
+
+ Re-enable mesh lines.
+
+commit b5b752b55ffe4954262faf1efe3e11508efb8217
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 01:32:45 2014 -0600
+
+ Update cygwin GLU patch.
+
+commit 8eb656d49d49e6a83227e22245864727c023df34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 19 00:14:11 2014 -0600
+
+ Acknowledge Michail Vidiassov's extensive contributions to the PRC code.
+
+commit 925f182004ae3373cfc1165c1f3312beea4dc522
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 13:25:55 2014 -0600
+
+ Sort vector patches to work around opacity artifacts in many rendering engines.
+
+commit 12b305cc49fc1d5f5ff61649040df4e819d2078e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 11:43:49 2014 -0600
+
+ Support raw PRC output with outformat="prc".
+
+commit e42598ff80e479e2be07b77091ca7e3639772880
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 10:46:40 2014 -0600
+
+ Improve diagnostic when texi2dvi is missing.
+
+commit 6e2a9d80b6b3e920a5c2cec24fc1f6d619828b2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 10:45:43 2014 -0600
+
+ Fix inlineimage under pdflatex.
+
+commit 3bb80f0dd96f888188435508ca7efba9c25a401c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 09:15:18 2014 -0600
+
+ Implement workarounds for Adobe Reader transparency artifact.
+
+commit 8554c29a6bd705bd6a974d14ff3bae2051b16394
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 02:04:26 2014 -0600
+
+ Update FFT support file.
+
+commit fc3ef0ec22b36083ace789436004ef88452a1feb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 01:00:19 2014 -0600
+
+ Update documentation.
+
+commit 9723f73b960f8be41e47650770cc9efa37275aa9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 00:30:23 2014 -0600
+
+ Update FAQ about changing default arrow size.
+
+commit 44d4866109ca922d2a702c634c9e5c5cf6719422
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 18 00:01:09 2014 -0600
+
+ Avoid unwanted play button starting with media9 version 0.35.
+
+commit c732e82d4205bb9e14218fc9e309aa0e539a4166
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 17 23:29:00 2014 -0600
+
+ Update fftw++ header file.
+
+commit e8d013cfd3e98da6c7f1d5ce14b37b45488f1a8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 17 13:32:16 2014 -0600
+
+ Revert to version 1.91-39 of contour.asy until paraboloid version is fixed.
+
+commit d5ef55a3925c20f18b130599906597270af13d86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 16 16:34:54 2014 -0600
+
+ Update to Boehm garbage collector gc 7.4.0.
+
+commit ae24b1e9aa87ede80a8292730a6a128344b01ca3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 16 14:42:22 2014 -0600
+
+ Under MSWindows, look for ghostscript library in both 32 bit and 64 bit registries.
+
+commit d07dd349ea7dbb3d358ff322e782134fd4ea3ba1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 16 14:40:45 2014 -0600
+
+ Update examples and documentation.
+
+commit b95d4e0d2e968245cf549eb669efe2f2e85c7111
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 16 14:31:36 2014 -0600
+
+ Test that printout is nonnull.
+
+commit f9e2147930ae52b83459afeedd55ce3e9d811272
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Dec 29 17:25:58 2013 -0600
+
+ Fix an exact match bug.
+
+commit 97c2ede0976dd5a81882555097822b2b0e6176cf
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Dec 28 17:13:18 2013 -0600
+
+ Change multiguide to avoid deep trees in normal use.
+
+commit 1f6fcb0caf77259d58c5f513337bb5add23da425
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 12 12:55:49 2013 -0600
+
+ Increment version to 2.25svn.
+
+commit 5cc1c36be3f86c9bce5fdf416656561d5b6e7a42
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 12 10:07:05 2013 -0600
+
+ Fix typos in documentation.
+
+commit b32749046a796117e1de5eff7756f908aec9225c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 12 10:06:47 2013 -0600
+
+ Fix segmentation fault in drawSphere.
+
+commit a9d404fa81617e78363b8c2c44f912be277d061b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 31 02:07:49 2013 -0600
+
+ Add examples.
+
+commit 8100327bca4cb899ef203b47c195232678f91680
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 30 15:53:24 2013 -0600
+
+ Update link to forum.
+
+commit 6f23cbbab14c2463efbb52e6dbc63120798be12d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 30 14:32:04 2013 -0600
+
+ Add latexmkrc example file that stores figures in a subdirectory.
+
+commit 96dbe43981d399c7ad5a72d191ae536308e17884
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 30 14:30:38 2013 -0600
+
+ Document new SVN repository URL.
+
+commit cae60d3655e4b1861793a427528cbf2eded0f498
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 30 13:51:33 2013 -0600
+
+ Remove explicit libglapi dependency.
+
+commit 773ee63dd79b67fac004d6840a7448a52adcd869
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 27 19:57:17 2013 -0600
+
+ Simplify readpipeline (requires POSIX 2008) again.
+
+commit 623fa5662c4faa9bdb78d6e8f8deca4ad464c692
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 27 19:52:26 2013 -0600
+
+ Restore function pointer to allow recursive calls to simpson.
+
+commit 2bedd4ed018f1a144baa299752537a4f05a2238f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 27 19:51:11 2013 -0600
+
+ Support make -n.
+
+commit a5d7e94f6cf4ec32c27b2715f2ef303bf21c317b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 20 10:20:59 2013 -0600
+
+ Increment version to 2.24svn.
+
+commit 8888e9c4e49c59b1aecf89c602ef3294ccd60682
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 18 22:38:07 2013 -0600
+
+ Allow compilation without fftw again.
+
+ Revert to previous wisdom file name (.wisdom).
+
+ Update copyright.
+
+commit f01acbf6c75a0ae093790e3303ece0c9c9eaae36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 15 03:10:39 2013 -0600
+
+ Increment version to 2.23svn.
+
+commit 3e655c3534f42b0782f875636715a6f35eecc1b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 15 02:33:47 2013 -0600
+
+ Fix dependencies.
+
+commit d5a39be02b8c2b3008f8fec9c00eef770988dcc7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 14 21:38:27 2013 -0600
+
+ Update FFTW header.
+
+commit 54876ada4deb700608de1f129ec6d75ba7d99436
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 14 21:37:25 2013 -0600
+
+ Update documentation.
+
+commit c5f20303c569847859b0c4815b2aa46ab199694a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 14 21:06:24 2013 -0600
+
+ Expose Postscript extend qualifiers for axial and radial shading
+ (setting extend=false can work around certain PDF reader bugs).
+
+commit 44d071b5cba3afea9a6285eb3852bca2a18fdcd6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 14 14:39:28 2013 -0600
+
+ Fix transformation of normal vectors.
+
+ Revert back to usual row-major matrix format.
+
+commit 0da7a9d5db0f71d4281d5992170afe68797b9501
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 13 11:04:57 2013 -0600
+
+ Make use of --pipe to enter context interactive mode.
+
+commit e21b39b5cb5bc003536d91a8e46eeea92be30a66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 13 09:07:53 2013 -0600
+
+ Support Fedora migration from python-imaging to python-pillow.
+
+commit 670a1e5a5c918a5bbb2ad92f511728de16a4287b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 13 08:16:32 2013 -0600
+
+ Fix documentation of irregular contour routine.
+
+commit 2e012ef1cb24337a9a80721bcb75ede09ab0da8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 8 13:57:50 2013 -0600
+
+ Support vertex-colored triangles in Adobe XI.
+
+ Remove reference to out-of-date trembling examples.
+
+commit ebdd5e9f0795cc53a4f44e0f852cdc7a35c4e368
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 8 13:46:04 2013 -0600
+
+ Use TEXMFMAN to find TeXLive sysdir.
+
+commit 9a7ea3d064131b8a0bbc7f5eab82a3af52c13181
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 4 16:16:19 2013 -0600
+
+ Temporarily revert 5440 for TeXLive 2013 build systems without Posix 2008.
+
+commit 6352888896501bbbe696e737e31f78baaa6a869b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Apr 4 03:10:22 2013 -0600
+
+ Add clarification on 2.. versus 2 ..
+
+commit fbfa6bd92b6c4901236970f91aa34a42db0c9a1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 3 11:29:11 2013 -0600
+
+ Make portability tweak.
+
+commit 6109a10f5bdf3a19b7683fe9f293e587e4dcba83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 1 11:12:12 2013 -0600
+
+ Qualify isnan (for solaris).
+
+commit 0870b3458fc99f919315a3e4efc77a10a4e9e18b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 23 06:29:51 2013 -0600
+
+ Avoid unnecessary buffering.
+
+commit 164de7fbfa01109df9bc4124d739acbb2c734976
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 23 06:26:04 2013 -0600
+
+ Update FFTW++ file.
+
+commit ae248b7f0740554792bc9b847352042affdbffe1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 23 06:19:12 2013 -0600
+
+ Express segment(bool[]) in terms of more efficient segmentlimits(bool[]) function.
+
+commit de3d95ba8225bd1b954cb215524e7944de6b83d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 23 06:17:20 2013 -0600
+
+ Update FFTW++ headers.
+
+commit 41623ead53639d5007bd14ab89d585e29e351169
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 8 15:18:10 2013 -0600
+
+ Recommend freeglut 2.6.0 due to broken menu feature in the 2.8.0 release
+ (and modifier bugs in various patches for this problem).
+
+commit 571f18674c41d73b019f03a0acbaa37bd07d069d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 6 10:42:17 2013 -0600
+
+ Remove unused code.
+
+ Update documentation.
+
+commit 3e215b79190c59f73456472454c30677300c891c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 09:09:16 2013 -0600
+
+ Allow self-defined unary operators.
+
+commit caa6b862447d6fcc71c2714e8c462e33bdba2600
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 31 09:27:13 2012 -0600
+
+ Compare formatted strings instead of real values in OmitFormat.
+
+commit c7c4367b58304fc8504c72e5bedb88247917bd05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 24 12:33:07 2012 -0600
+
+ Update example.
+
+commit 54fe52b1e641ef72dac702f8af80182490bcdb8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 20 16:32:57 2012 -0600
+
+ Use C locale for svn info.
+
+commit b52dfbf684b9ee80f4cfa8a505080d49e40d3d83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 17 20:11:03 2012 -0600
+
+ Temporarily revert to using tan(radians(a)) in numerically unstable arclength
+ calculation in geometry module (note 2.17-29).
+
+commit a87a1304c86c659e806749d0e41fba808dc49b43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 10 12:20:47 2012 -0600
+
+ Increment version to 2.22svn.
+
+commit c2d660762e8124689df3cccd179770a3bb785491
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 7 06:33:22 2012 -0600
+
+ Fix typo.
+
+commit 6e9e7aef19a11c397a6158b64aaa522ea70620c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 6 00:38:24 2012 -0600
+
+ Fix history recall bug.
+
+commit 169b5123d6930b64641b898d88feec61e5664bee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 4 11:53:09 2012 -0600
+
+ Add extend parameter to axes (default true) and axes3 (default false) routines.
+
+commit 98f645d4563ae9bdd787edc8b27270cdfcf8ce72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 30 21:14:47 2012 -0600
+
+ Fix alignment point of OpenGL billboard labels.
+
+commit 78b66a7f2759a9df1302c25518e34c4424c390b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 27 23:37:22 2012 -0600
+
+ Reinstate billboard rotation for explicitly transformed labels.
+
+ Don't request bbox only in label(frame,Label,triple).
+
+commit bd02c41760684d21d1f5664acc7f5fc317fad89e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 27 17:03:39 2012 -0600
+
+ Increment version to 2.21svn.
+
+commit c5aa009966d6e1e9d8c30c548260197ae5b3d678
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 27 15:45:43 2012 -0600
+
+ Work around dvipdfmx bug.
+
+commit cf498cba13b9c46cefb4394d7651c24a5fcaf6a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 27 12:19:08 2012 -0600
+
+ Disable billboard rotation for explicitly transformed labels.
+
+commit 3d9cbef946b70536d13c51cf20915ae72deb3f43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 25 09:18:30 2012 -0600
+
+ Increment version to 2.20svn.
+
+commit 194c5091a3e22c107a8c001c34385da562c99e2d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 25 08:31:54 2012 -0600
+
+ Update example.
+
+commit e72c486b7f9247b2678905c2b47080e3113d97b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 25 04:49:46 2012 -0600
+
+ Fix warning messages.
+
+commit a1c622b6b4cc50c4b08d6002fd9e7aac65bd7a77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 25 04:30:00 2012 -0600
+
+ Pass inverse of modelview matrix directly to media9 to work around numerical
+ resolution issues.
+
+ Fix PRC viewportshift.
+
+commit a9aa1323336d287c24680e5e65895cfb328542dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 20 01:58:07 2012 -0600
+
+ Fix lighting of NURBS surfaces.
+
+commit 61503c988fae7ead6743e2c15ad3ae8c059b5b31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 20 00:13:48 2012 -0600
+
+ Increment version to 2.19svn.
+
+commit 82e909f710a60909610f9b5071e7761ff987c035
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 19 19:18:37 2012 -0600
+
+ Set secondary picture size (so that, for example, markthin works properly).
+
+commit 462b7ecee606e5b73cf46ebc6372ea28952866a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 19 19:13:46 2012 -0600
+
+ Move include.
+
+commit 7cf9c7a91df2d57128d38c23c3eb0248e43c27e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 19 01:47:10 2012 -0600
+
+ Update example to mp4.
+
+commit 5f7a2a4f564b0b5dd1d644ca7a6b97584dce36d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 20:31:13 2012 -0600
+
+ Increment version to 2.18svn.
+
+commit 07fbb54d9eba448911e475baa05c05fb32dca5c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 19:10:38 2012 -0600
+
+ Handle 3D degenerate arrows.
+
+commit 72b318bc2eec2dab05bd790434924d630b83128b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 13:37:36 2012 -0600
+
+ Fix warning message.
+
+commit 4a97fee29abc0138e152a87c462d713963de656a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 13:27:25 2012 -0600
+
+ Fix warning message.
+
+commit afc04ee36aaf1993cdf4c4e1963983aa7768f24e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 13:25:39 2012 -0600
+
+ Remove obsolete file reference.
+
+commit a6a1ec9e28e58089665ef014c58011e9f3914790
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 13:07:43 2012 -0600
+
+ Make tessellation normals optional.
+
+ Add example and documentation for tessellations.
+
+commit 485f28de3f4031d0bed70b122df335c4f6e95676
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 12:56:16 2012 -0600
+
+ Add missing -P options to dvipdf (required for media9 support).
+
+commit 02a83be7738afbaec3b88291b07c3508917f5d87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 08:38:11 2012 -0600
+
+ Implement improved workaround for media9 preview bug, as suggested by
+ Alexander Grahn.
+
+commit 46e0c431344e0aebd48d4714ea83222758b2235d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 02:44:29 2012 -0600
+
+ Implement efficient 3D routine for drawing many triangles, with specified
+ vertices and normals and optional vertex colors.
+
+commit fb63ec153a6ce50bdf7d13961c44cec1bfec11dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 02:39:06 2012 -0600
+
+ Workaround media9 blank poster image bug under latex+dvips.
+
+commit 8e607d1c6b06eb6157d3e44183880474c2809141
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 17 07:39:11 2012 -0600
+
+ Fix warning message.
+
+commit 3ca8304aec7b78b01c57d185fa838cd899113acf
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 17 00:49:14 2012 -0600
+
+ Include stddef for ptrdiff_t.
+
+commit 74ff857dd8e876c27f4c704f5f8fcf351a6866ed
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 17 00:30:52 2012 -0600
+
+ Fix asymptote.so dependencies.
+
+commit 3b284903224957834326f7b1323ad62a57ddded5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 13 23:49:20 2012 -0600
+
+ Add simple vim ftdetect file that set asy filetype for *.asy files.
+
+commit f3f87d6a628cde8f2f1164591d929ed9ecb5adea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 13 23:42:03 2012 -0600
+
+ Add condensed binarytree mode (contributed by Gerasimos Dimitriadis).
+
+commit 2bfd526b3e68bcf0855f9cd96a8387f38074c205
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 13 23:23:27 2012 -0600
+
+ Add global macros to find the number of a PDF OCG object.
+
+commit 4c0a89dc61a79aedbf568acf3f2cd0dd3fdb6a28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 13 12:21:09 2012 -0600
+
+ Omit redundant billboard group name.
+
+commit 35113393aeea57bb6b3640f04771552b24da7184
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 13 11:04:58 2012 -0600
+
+ Fix degenerate arrows (partially revert 1.38-27).
+
+commit 961efd0bbfa636ace7093b34367cf94aec58ff94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 13 07:40:24 2012 -0600
+
+ Mention that media9 v0.13 is required (to support the default 3Dmenu option and
+ billboard labels).
+
+commit 6db4bd675805fe732d07027a066d94d6bbde7571
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 11 13:11:46 2012 -0600
+
+ Fix PRC linecap for draw(unitsquare3).
+
+commit 759c324ed9426ff3b422d27bcd93144e506a8c13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 11 11:09:24 2012 -0600
+
+ Fix lighting; consolidate duplicate code.
+
+commit 81117f85753d1e69bc32b9a8886d4564f7e9337d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 11 10:32:35 2012 -0600
+
+ Make PRC and OpenGL lighting consistent.
+
+ Remove asylabels.js (now included in media9 verion 0.12).
+
+commit 5d66bf4894766881c08f06b6e05d1aee94d60b93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 10 08:58:07 2012 -0600
+
+ Simplify media9 inclusion (now that version 0.12 is required).
+
+commit f8fa10e6e09c5c441b49cc4d4a27338016e673f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 10 08:49:18 2012 -0600
+
+ Make use of 3Dortho and asylabels.js facilities included in version 0.12 of
+ media9.
+
+commit 2e877821d1858577c6e780b935d2679eb740c968
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 10 07:26:03 2012 -0600
+
+ Upgrade to media9 version 0.12.
+
+commit cee7440cfc1abedad4c91287e4683fe16f2256d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 9 09:17:35 2012 -0600
+
+ Add missing file.
+
+commit 38eb29960cfd20c550d3e08f44be1bc26a16806e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 9 04:12:41 2012 -0600
+
+ Restore lighting effects for vertex shading.
+
+commit f25cd165ecaefdc96b963420a5886c58b6186e46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 9 03:43:27 2012 -0600
+
+ Fix vertex shading lighting.
+
+commit 950367a4dd7aba862951cc87f098b2c53c354e7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 8 14:46:13 2012 -0600
+
+ Add updated asylabels.js file and future hook.
+
+commit c1f70301a20c33fb142c537d6e12b3a1a52184d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 8 14:32:33 2012 -0600
+
+ Simplify code.
+
+commit f765ea5970eff9960eedbaeb7ae0a65c391bac98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 8 10:58:09 2012 -0600
+
+ Update FFTW++.
+
+commit 5edc7a9350fe1ef6375e5096a911c609a03b5bc7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 8 10:15:52 2012 -0600
+
+ Consolidate and standardize min(path[]) and max(path[]) functions.
+
+commit 3b392b22d785ea9cb4b8d57e074af39cb5619afa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 7 12:47:56 2012 -0600
+
+ Improved media9 patch, thanks to Alexander Grahn.
+
+commit 1903b6b5d7496baaaf40fa1fe695bd228c5d56cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 29 10:47:45 2012 -0600
+
+ Fix Makefile dependencies.
+
+commit a070dd5293b14b74f05f0ed6a9f900db017fff62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 29 10:46:54 2012 -0600
+
+ Add settings.axes3 to control visibility of PRC axis.
+
+commit 3a4ff80115e364bc26662e53018bd49e9f4900ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 28 09:09:17 2012 -0600
+
+ Provide interim media9 bigfile patch.
+
+ Don't require media9 bigfile support for pdf tex engines.
+
+commit 893bda7dd8b5b1a9f4eaeac46020d20ccf939d7d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 13:28:14 2012 -0600
+
+ Support prune=false again.
+
+commit 6cca962e4b2d6c4e21596f3075754c26ec5f97cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 13:16:21 2012 -0600
+
+ Fix split(" ").
+
+commit e295ef3899bd3ff3d05c9ca8854cd965082cc5dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 03:16:16 2012 -0600
+
+ Initialize ASYprefix with output directory.
+
+commit 2841f55449b6127d64dd69deea8b046ccc0741a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 03:15:15 2012 -0600
+
+ Tolerate missing inline option on 3D content embedded within latex files.
+
+ Cleanup intermediate media9 files.
+
+commit 640aead8666318650a79a81549692ba50972377d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 03:10:13 2012 -0600
+
+ Cleanly handle missing files.
+
+commit 4f23d0888f40ec6d3b0497a95671716cc8d8f5f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 03:09:14 2012 -0600
+
+ Remove newlines from texpath labels for xasy.
+
+commit 1e3776595b93cddd393f635003f1497fa43eb43b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 24 00:31:17 2012 -0600
+
+ Improve formatting.
+
+commit 2b16074a5c7352a8557fa039230d60d69b24a0e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 24 00:30:52 2012 -0600
+
+ Use prefix for media9 label to avoid duplicate label warnings.
+
+ Run ghostscript for texpath in the output directory.
+
+commit a553e970a3252eff5af1b5f8dd41c14ea1297eeb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 24 00:27:29 2012 -0600
+
+ Add -DSAFER -P default options to improved dvipdf script.
+
+commit 25493e086f2277fac51de26ac0c8fbf539ee1761
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 20 08:45:07 2012 -0600
+
+ Fix orthoshift.
+
+commit 81189f4950eca8130ed6ce943a9f56f26a38483c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 19 14:53:13 2012 -0600
+
+ Further lighting fixes.
+
+commit d7f2a26a8182c3eef3dac187a9a7aa265f156d1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 19 14:40:51 2012 -0600
+
+ Fix lighting.
+
+commit 9d0c4bab62c2c63c80c610199fb088cc3839795c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 18 07:40:50 2012 -0600
+
+ Look for history_list (which seems to be missing from editline) when checking
+ for GNU readline.
+
+commit 96d2dce72cb9dae5c357a1ee01f2778e6d317158
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 17 12:41:23 2012 -0600
+
+ Choose a wider connection when searching near the connecting line
+ (patch contributed by Orest).
+
+commit fa17cf1e5e0bd2645d937d10abd8a1e0a32d29d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 17 08:07:21 2012 -0600
+
+ Update to gc-7.2d.
+
+commit ed07190869efe328fa890fef5a9e3dfe06a7ef68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 17 08:06:43 2012 -0600
+
+ Rename displacement routines.
+
+commit 85667a7b7d5459f5202da2975442cc5b60d4be7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 15 09:04:24 2012 -0600
+
+ Change defaultrender.defaultnames to true.
+
+commit dd9d644810f4d40e21762e4b4121a5edd66619d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 15 07:53:45 2012 -0600
+
+ Tweak special trigonometric cases to improve PRC compression.
+
+commit b58a0817fb572cbd1a373eca07b68e705f9ffa03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 15 07:52:54 2012 -0600
+
+ Don't autogenerate RPC part names by default.
+
+commit d325d11882ce6ba4e511c9b5e52b7025e8b61ea9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 15 05:14:26 2012 -0600
+
+ Use limits rather than separate xlimits and ylimits commands in examples.
+
+commit cd2bc23e0f03be679698d1eec0f6741abe1a8d52
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 14 19:55:56 2012 -0600
+
+ Add missing render argument.
+
+commit 07e58c133ace0af75dda15b5a12b1f42b42ece88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 14 19:00:45 2012 -0600
+
+ Add missing factor to arrowheads.
+
+commit aa508f2198ed94dece058fcbc93237334f4cceff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 14 17:51:38 2012 -0600
+
+ Support large PRC files (requires media9 version dated 10 August 2012).
+
+commit 5cab138712fe69f06af75a9bb69df29cc440585d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 10 05:56:58 2012 -0600
+
+ Address clang compiler warning.
+
+commit 764f6c88d6d75bf927cb79cd5ac49a7fa49c3ee7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 10 05:40:09 2012 -0600
+
+ Restore label grouping.
+
+commit b2faafa9d236db8d96fc669d675e310b6a5422fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 9 19:38:52 2012 -0600
+
+ Update copyright of reference card.
+
+commit 6abad841b8e40df73b0e5c083d26b0146974f8f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 9 10:05:37 2012 -0600
+
+ Fix garbage collection issues.
+
+commit 0dd753b567c72d1e1c19fb08b29b38b49a8f0684
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 9 03:41:55 2012 -0600
+
+ Work around LaTeX limitation.
+
+commit f976570a2b4af01853995f1deb14db7eb4c873d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 9 02:36:28 2012 -0600
+
+ Update U3D example.
+
+commit f041106d7df65604625260ee98be6142bbcc016e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 8 22:34:01 2012 -0600
+
+ Add simplified version of Michail's local coordinate patch.
+
+commit c54405e2889a4f19c6595963eaff5a0c3e3fd1cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 8 10:55:30 2012 -0600
+
+ Improve support for none TeX engines.
+
+commit bbc092255015ac822f298b22ae2c676b4b39e384
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 31 09:55:09 2012 -0600
+
+ Remove unnecessary xelatex detection.
+
+commit 2cf8ac929cf7dcecd2fc918d7fda40297c1d977d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 30 09:58:52 2012 -0600
+
+ Remove spurious code.
+
+commit f164efc2e27284c87ec8a16c698f24d7fa94ff3e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 23:46:15 2012 -0600
+
+ Remove obsolete movie15 patches.
+
+commit 92725277aa6c2a7a798bf318dfbee947d37efa4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 23:44:19 2012 -0600
+
+ Remove duplicate code.
+
+commit 0fc6f5179d5d60dbb9cae839faed27b169f2443d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 14:46:18 2012 -0600
+
+ Upgrade from movie15 to media9 LaTeX style file.
+
+commit e3f867dddcd728104d2327d7750a8a3fab392c75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 28 00:53:19 2012 -0600
+
+ Compile with offscreen rendering if and only if both libOSMesa and libglapi
+ are available. Make settings.offscreen default to false.
+
+commit 2d8d5251b15c75efc2d7cca14aafaa7776122900
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 23:45:26 2012 -0600
+
+ Support OSMesa version 8 (which allows offscreen and non-offscreen
+ rendering in a single binary).
+
+commit d23dfa4f311e79d4f993bfdcd386cb904a20c3fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 22:59:28 2012 -0600
+
+ Fix string length type.
+
+commit 8a16ecec4049f1c4fb289a6230173daaf2315e67
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 16:26:37 2012 -0600
+
+ Fix typo.
+
+commit 1dfbe359691c2d3115702ae22f3cf8a82778debf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 19 23:47:52 2012 -0600
+
+ Fix autoscale3.
+
+commit 0cbad923919b8d51a8ec25ac8236315f10eaca66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 19 22:42:00 2012 -0600
+
+ Partially revert 2.10-2 (which broke autoscaled logarithmic axes).
+
+commit 925da6af8b86c303366c47562eb553c3af69f271
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 4 05:44:19 2012 -0600
+
+ Propogate -m64 flag to the linker to fix solaris 64 bit builds (will cause
+ a clang warning message, though).
+
+commit 529536b10bcd237cfbc314c8c10b36e3ccf55033
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 1 10:33:18 2012 -0600
+
+ Simplify code.
+
+commit 675129797d1260953312d62fb6435172c1414cb8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 21:34:02 2012 -0600
+
+ Declare strlen.
+
+commit 4665de488b0f7dfa0f3fc0f6084564429f633c45
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 11:24:27 2012 -0600
+
+ Fix bug with non-square pen function images.
+
+commit c6275331534575aebaa2e5012585548c44e9dfe0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 09:46:34 2012 -0600
+
+ Increment version to 2.17svn.
+
+commit 6cd9addeacb0a9e4ecaf0b780547b059896c8e58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 09:41:14 2012 -0600
+
+ Revert last commit.
+
+commit 54f73bf431250f99e32352dddc905cf18ae8d7e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 07:38:33 2012 -0600
+
+ Fix bug with non-square pen function images.
+
+commit 0ce955f05eb5e62a79c375534dcc452e260d97a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 13:45:48 2012 -0600
+
+ Work around Windows Python bug.
+
+commit 7b4a7e8558c528ce20a65c34c193d001bdd57384
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 11:53:45 2012 -0600
+
+ Replace xinput by input(mode="xdr") and xoutput by input(mode="xdr").
+ Replace binput by input(mode="binary") and xoutput by input(mode="binary").
+
+commit 4b2b3eadba1e359d65d50947a712015cac6096ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 10:35:57 2012 -0600
+
+ Update setting.
+
+commit e59ad4dfb8a5d513ddf2d3b059d208ea5d8afb74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 10:24:17 2012 -0600
+
+ Workaround limited pipe support in cygwin.
+
+commit 895885884808ec83658588d690920bbd8f1c07f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 23:06:58 2012 -0600
+
+ Fix type in conditional.
+
+commit ec1650e5a37e69af75d8b85dc553d5e9d6893225
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 10:02:48 2012 -0600
+
+ Update diagnostics and documentation.
+
+commit c6db7d004b42d3ebb37ab49bb6195dd1960bd371
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 07:20:20 2012 -0600
+
+ Support compilation of native CYGWIN binaries.
+
+commit ac67889ea1721b08044cc3c902225cbbb540b0c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 06:12:56 2012 -0600
+
+ Fix pair and triple pipe output.
+
+commit 5d562c7e4c3db6476f72c191ef55363d06283667
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 06:09:25 2012 -0600
+
+ Simplify opipe formatting.
+
+commit 58740141a125132dc1e7927686866f897189fc1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 04:30:35 2012 -0600
+
+ Work around compiler bug.
+
+commit 82e58e812176532fbda581426f0fcf7d443e2e11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 03:34:25 2012 -0600
+
+ Fix makefile.
+
+commit c8f2f7c3b8716787f7cf27854e160fa9d7b0ac01
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 02:24:29 2012 -0600
+
+ Improve msdos build.
+
+commit c11f6ae188aeb29182894e0b33484c87ffef4993
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 02:19:52 2012 -0600
+
+ Fix MSDOS makefile dependencies.
+
+commit 632ea52a6b16063f1147d1e40a5ef941138db575
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 00:03:06 2012 -0600
+
+ Fix CYGWIN build.
+
+commit a4440a1f3a313bd1fdd67df46c57150d3c12a482
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 23:58:08 2012 -0600
+
+ Reinstate -fno-var-tracking option for older compilers.
+
+commit f17b8b5b943feda8851978374c1261d07dda9a49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 22:42:37 2012 -0600
+
+ Support arbitrarily long input lines in xasy.
+
+commit 197f07d29b0340ddce9683758876a356de01a1a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 17:29:40 2012 -0600
+
+ Remove broken asy path validation code.
+
+commit f72e142f5bb7a5c24f166e46d779f9f32b4ccce1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 16:30:26 2012 -0600
+
+ Fix warning messages.
+
+commit 7e073061e95aafa31ada2661524f61fb0a708df7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 14:52:16 2012 -0600
+
+ Fix portability issues.
+
+commit 9a2ee2bc11d2b6d229de97cc2b1b0f3cebbdc330
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 09:47:51 2012 -0600
+
+ Use pipes for xasy communication.
+
+commit f7572e5fc91332f6254877b4ba191e7b12a5c3e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 09:04:06 2012 -0600
+
+ Improve example.
+
+commit 5280aaf5b9f41ab5010cef240e852fe4a7e5d2f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 09:02:15 2012 -0600
+
+ Fix division by zero.
+
+commit 4760b91ab9e467f1dac0ce4248ecd5d7babc92ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 09:00:56 2012 -0600
+
+ Don't autoscale ticks when N is specified and autoscale is false.
+
+commit a2c299f175bd766d48c0963aab7d6c311ab281b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 25 08:57:08 2012 -0600
+
+ Add new new routine for computing camera positions.
+
+commit 65cabae5d0fe4cd36b112879a4dbb0b9ae59d708
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 24 22:38:45 2012 -0600
+
+ Update to gc-7.2b.
+
+commit d281011095af600eaffd39b7b6bec994bc36917d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 24 15:49:39 2012 -0600
+
+ Respect straight flag in external().
+
+ Add partialu and partialv derivatives for patches.
+
+ Add a general split function.
+
+ Move split structure into splitpatch example.
+
+commit d0269b9d990cbf5677e67d43e9b85a969ef03bb8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 22:51:47 2012 -0600
+
+ Fix palette range (bug 3487991).
+
+commit aebbf37c073de90619b6abf77a129228d18fa3a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 14:38:43 2012 -0600
+
+ Remove obsolete --no-var-tracking compilation option.
+
+commit 5278d4408c07fdce76a163745279d2e4167fe267
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 13:44:58 2012 -0600
+
+ Remove unused value.
+
+commit 7f56277a8a94e0840d4e1f8d4dadd47278c1a4f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 13:21:30 2012 -0600
+
+ Block SIGCHLD.
+
+commit 6db9f3d39623474f0b21c0bec9945493fb241aff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 13:20:12 2012 -0600
+
+ Force assert to be active.
+
+commit 098f9995970cedcb056cbd438c3ad3d100c44107
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 10:55:16 2012 -0600
+
+ Fix manual tick scaling.
+
+commit 146ea188fd77609436b3fd8bf56f7c13c6a893a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 09:40:33 2012 -0600
+
+ Use currentpen rather than nullpen so that current value of currentpen is
+ respected.
+
+commit 6aa2ab11ba05e81c7d9718d0714275ff2ad91bf1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 05:54:54 2012 -0600
+
+ Add missing file.
+
+commit 3ac2531850eb5ab0cc4a7f1fb83a98f9466add34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 05:50:40 2012 -0600
+
+ Add missing file.
+
+commit 0b08ac0f02b38e8e460709b772155841d6b68d1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 05:36:47 2012 -0600
+
+ Add missing file.
+
+commit 898a29e16b50bb77a485cc2dad980ba29172f6c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 05:28:40 2012 -0600
+
+ Update POSIX thread support.
+
+commit bbe3a92496ff77625e376ef97d748c8fc373ef2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 03:49:45 2012 -0600
+
+ Fix warning message.
+
+commit 92a3e49b5d51348876ec8dbadd0455de4f31187c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 03:08:30 2012 -0600
+
+ Update to gc-7.2.
+
+ Simplify makefile; fix shared library version.
+
+commit 95c12bcf39c54fcf1467d5e3291c07046091e0fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 18:06:16 2012 -0600
+
+ Fix the erase command so it behaves as documented (no reset).
+
+commit 63edda802e6b7102fb239b10bb75a5d84a5ab0d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 15:54:47 2012 -0600
+
+ Don't force a default viewportwidth.
+
+commit 336fca44455b9a23f0300de0360f05ff872e98a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 15:47:54 2012 -0600
+
+ Improve wheel.asy example to allow pdf animations.
+
+commit af090550e3e9fdd53e0645631b44e459c6535690
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 15:27:32 2012 -0600
+
+ Fix split structure.
+
+commit 55e19362d20a7e6d34abc034579421f477833dc6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 13:24:12 2012 -0600
+
+ Add NSIS support files.
+
+commit f79b31b1cdcc96bbf99863c2f3930eae80ed3650
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 12:51:37 2012 -0600
+
+ Fix icon directory on 64-bit MSWindows systems.
+
+commit ac138f0766bf2580e63e147ef682057e548e0b26
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 12:42:42 2012 -0600
+
+ Remove obsolete constructor; update examples.
+
+commit d2ff5a4b54ecbb598c6701640dc69e475b2c25d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 12:40:29 2012 -0600
+
+ Update documentation.
+
+commit 36b874c9bf949602c86d2373399559bf204d86a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 3 19:39:30 2012 -0600
+
+ Make split compute subpatches for each input patch.
+
+commit afa172f0b94dfa159afb88049cd70639ebf927ca
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Mar 28 20:36:39 2012 -0600
+
+ Add picture bounds test.
+
+commit 59226ae03dc03ecb85ffe412169946b675ecc2b6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Mar 28 20:35:51 2012 -0600
+
+ Changed name of class to avoid confusion.
+
+commit d7b28f36a0ab6c506f62480d125991a802afc32a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Mar 28 18:48:45 2012 -0600
+
+ Fix translated bound error.
+
+commit bc5c461aee6e3e9e7d8e2cb44ff824b67af70eeb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 26 10:09:57 2012 -0600
+
+ Fix numerical underflow.
+
+commit 96720fd56603cc08aba9a2d32614413e3c2d6226
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Dec 28 15:08:25 2011 -0600
+
+ Allow named arguments after rest arguments.
+
+commit f064b2c18eb998eabb7f6734e3d622f076f2d054
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Dec 28 15:08:00 2011 -0600
+
+ Nicer debug output with COMPACT flag.
+
+commit 1ba8c8e27540d30d2c07bf94d6ad05255f79e9ea
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Dec 28 15:07:37 2011 -0600
+
+ Refactor vm::frame allocation.
+
+commit 36cfb1471d9dfc76038d7cb8e600178cacd72d1e
+Author: Will Robertson <wspr81@gmail.com>
+Date: Sun Dec 18 01:07:26 2011 -0600
+
+ fix \CatchFileDef fallback command
+
+commit 5584bf2e9c7667776c17261506c4c95ebdc525ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 16 02:05:37 2011 -0600
+
+ Fix trailing zero removal.
+
+commit 36df17bffa1ce7df583b5498e49c25b8e660ed84
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 11 22:46:58 2011 -0600
+
+ Make format more consistent with fprintf; add a defaultseparator argument
+ for typesetting scientific notation.
+
+commit 607d1c6a8aa64349ee8222e0d4fb7e51ea1108e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 19 17:08:57 2011 -0600
+
+ Work around quote translation problem.
+
+commit bd420f563ee8f73ec0d83dc625b7eedf31c4e10f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 19:37:09 2011 -0600
+
+ Increment version to 2.16svn.
+
+commit 0373fcedf737e0eb031c3b7c0d6249a0365fb8e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 15:35:43 2011 -0600
+
+ Add missing isnan declaration for MacOS X.
+
+commit f45773ebfae0421654c44ff749b4abb5473bb9b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 02:55:41 2011 -0600
+
+ Increment version to 2.15svn.
+
+commit d5f96fa6c1887a0b5ef172b020c33008ab89bc5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 01:58:35 2011 -0600
+
+ Add missing CYGWIN declarations.
+
+commit f3a7eab7acf2330bd0db9954965cee63157fe608
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 00:20:57 2011 -0600
+
+ Update examples.
+
+commit d1910745143903e81841776b1839aae3d3679d8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 15:23:53 2011 -0600
+
+ Fix typo.
+
+commit 1bcac6740b1440cc8bf32efd9a8e7e4e2386b721
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 15:18:41 2011 -0600
+
+ Move obsolete rotate(explicit pair dir) routine to geometry module.
+
+ Add quick reference card.
+
+commit 519ed6392af531d644338021ad1da7dcca1458fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 15:17:39 2011 -0600
+
+ Fix render=0 bugs.
+
+commit 7b3e45ff00039a5d64629a52f69d8c9826062b4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 14:04:28 2011 -0600
+
+ Implement Jacobi elliptic function sndncn(real u, real m), which returns
+ real[] {sn,dn,cn}.
+
+commit e65f6c73db51d22c4af1a3ebd647102c7afe811f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 13:36:33 2011 -0600
+
+ Implement int ascii(string s).
+
+commit f980e86fa2ddb6bc958cc6e6dede75800ba77c2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 13:27:56 2011 -0600
+
+ Added manpage target to build man page only.
+
+commit ca0950021320f587a98111af6770910e2fd6392c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 12:45:15 2011 -0600
+
+ Add bool isnan(real).
+
+commit 61d15d09a399b12373ff3dd8ad472dbd96e0a9bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 02:45:48 2011 -0600
+
+ Fix preview surfaces with render=0.
+
+commit fd39ba1b61df82917abef4fd1a5c882895e9f6a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 00:55:06 2011 -0600
+
+ Fix string reads from binary files.
+
+commit e384bc1d78d8d7bb055d47eac5357094e653982b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 00:53:24 2011 -0600
+
+ Blank lines are not allowed after \begin{asy}.
+
+commit 815254b51b059a8e5cd648731970c6f6b76431ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 00:00:27 2011 -0600
+
+ Generate missing preview images for fitted pictures.
+
+commit 2a699d60716d5359aff5c682402778325a8dafa5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 14 17:52:20 2011 -0600
+
+ Fix draw(revolution).
+
+commit 23cba8ca5597ff5ae97e131d6e182edab7b0674d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 10 18:07:05 2011 -0600
+
+ Fix axis bug introduced in 2.14-32.
+
+commit b181ebf5775ba5d599b226c89b4445123801b000
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 30 08:23:17 2011 -0600
+
+ Portability fixes.
+
+commit b60fabf38153ed38f982c6e0fb7b31ae63444c72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 22:14:23 2011 -0600
+
+ Move lastpen to the end of pen.cc so that it is initialized last.
+
+commit 3f33984706db09eccb1911d29f17a09a86b4fa4c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Sep 29 13:32:22 2011 -0600
+
+ Change Int to int_typ in policy.h
+
+commit 9c18bdd86d9097815f8c25fb48f7dc7cead40cc9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 08:38:53 2011 -0600
+
+ Avoid compiler warnings about virtual function overloading.
+
+commit adb2f5a6093f309f71476b390502786fc92f6b24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 07:54:09 2011 -0600
+
+ Avoid further static initialization issues (courtesy of Michail Vidiassov).
+
+commit 93e9862311b092b464ab596ea12f37ed1f604e87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 07:50:13 2011 -0600
+
+ Remove extraneous comparison.
+
+commit 905b605e3a2ca6ca3d15af85e0b41c058548ab16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 07:42:10 2011 -0600
+
+ Avoid unused function warning message.
+
+commit abc896516d0fab7e2cd3324bd5c21633c97852a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 07:04:03 2011 -0600
+
+ Fix warning messages.
+
+commit 454f9b2a5e94451fa2954263a1e0e672d985c195
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 06:25:04 2011 -0600
+
+ Fix extended axes.
+
+commit c405b32f3f48f7cb881c4438f46aac04c562bf45
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 11:51:42 2011 -0600
+
+ Work around static initialization fiasco.
+
+commit 835df463a4ff6e50a1bb963a749c6e99a949b437
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 11:17:50 2011 -0600
+
+ Fix typo.
+
+commit e93d341f5eaf37535e1d1a98cb49ab981a6360ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 10:49:33 2011 -0600
+
+ Update documentation.
+
+commit 5200611daa0aa3ee5184200fefa65c68977a0618
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 10:44:41 2011 -0600
+
+ Remove unused member.
+
+commit 4b7b3d2ab698953f8d8b78d06d12dd43b2606d65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 10:24:10 2011 -0600
+
+ Fix comparison.
+
+commit 933d551e410216bb3c8b380a029f6ffea120fb56
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 10:16:20 2011 -0600
+
+ Remove extraneous comparisons.
+
+commit 863887edfc40854ff581b2cd8788a963516d0fc9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 10:12:33 2011 -0600
+
+ Fix comparison.
+
+commit 5e1847bd221ec8b6df63ee9cc20a6f06eaf7f080
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 19 21:18:30 2011 -0600
+
+ TRANSJUMP no longer an option.
+
+commit 6955d093e68636e943db4e866a26fa037f2e8f8a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Sep 15 16:15:35 2011 -0600
+
+ Add 'operator tuple' via EXTRASYMBOL command.
+
+commit e2599a170b41495ca9239a3430e0bc9884944a70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 15 09:23:55 2011 -0600
+
+ Fix build.
+
+commit 4e072133999da0c7c4d2323c67a503d6c7a2e227
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Sep 7 20:39:57 2011 -0600
+
+ Add operator overloading to aspy.
+
+commit 88be1715a04f52c0c98d8836f926e6ea2cd97c92
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Sep 7 18:29:08 2011 -0600
+
+ Add 'operator tuple'.
+
+commit 2f65f96732ab7045006bea36f95dd030fbf2e6bf
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 5 18:01:39 2011 -0600
+
+ Can compile Asymptote as a shared library.
+
+commit 314c32df054e8e94fdb7e4a3ab36d63b3dfcf630
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 30 16:10:39 2011 -0600
+
+ Generalize copy, map, and sequence functions to arbitrary depths.
+
+ Add locale string to format(string,int).
+
+commit f60d7128a92318a68ea52d72e98f2f020a50851b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 22 10:46:31 2011 -0600
+
+ Improve nullpath handling.
+
+commit 7f4aa4dc2cd0bfb309318136062a4368257275a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 22 09:22:55 2011 -0600
+
+ Allow draw(nullpath) again.
+
+commit 035e97166c51d992fb7821bba57500ebf96c9b5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 21 18:31:43 2011 -0600
+
+ Update version number.
+
+commit 1d46e62d7302e1944634462f1293cb5da3e297d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 21 16:09:54 2011 -0600
+
+ Remove portability tweak for MIPS.
+
+commit 19376a278ff54761ec08cf7fce188a7412a1a9b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 21 15:09:03 2011 -0600
+
+ Specify arbitrary size if MAXPATHLEN is undefined.
+
+commit 169a01aa7008f1904ba90620e9dbf3a30b814cef
+Author: Will Robertson <wspr81@gmail.com>
+Date: Wed Aug 17 02:51:20 2011 -0600
+
+ some missing comment chars in \asyinclude
+
+ also bumped the version number of the .sty by a minor increment (hope this is okay)
+
+commit 99cccab66045a397288043008c16e2661760b321
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 13 02:50:17 2011 -0600
+
+ Build Mark and MarkFill from MarkPath.
+
+commit 66e4b3128fef46f9947ba9a377becd0dff2e94ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 12 23:50:06 2011 -0600
+
+ Implement markthin(path) marker with opacity thinning.
+
+commit dc796a6644aa43520df731e9dc5a0c7d8efad14d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 4 21:48:05 2011 -0600
+
+ Update link to cygwin1.dll source code.
+
+commit b49f13fdc4e89c6d68a9b2661bb003beb62ef87b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 12 08:35:36 2011 -0600
+
+ Disable billboard interaction for offscreen rendering.
+
+commit e91377a416df875948307c281eabe3253e6c8540
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Jun 29 10:09:51 2011 -0600
+
+ Fix double drawing of path when showing triangle in geometry.asy
+
+commit 0810f9341fefd6a9640d885548e43f4eff317ff8
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Jun 27 16:35:42 2011 -0600
+
+ remove trailing char
+
+commit c81825912d945d231483dd5514253d78c8c2f797
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Jun 27 11:04:13 2011 -0600
+
+ Fix arc orientation in arcfromcenter
+ Enable again arcfromcenter for line (with explicit constraint)
+ Cleaning and improving code
+
+commit 56823e66001d1737e46789a0a092f4021c50d603
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Jun 23 08:58:15 2011 -0600
+
+ Remove previous modification in geometry.asy
+
+commit 96bb297e1528c0587cbdf784d42746820104b4c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 22 20:55:18 2011 -0600
+
+ Prebuilt target should not rebuild asy-keywords.el.
+
+commit 9793f56e065ba4d9746351f24be21be20ebd75a0
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Jun 20 14:56:04 2011 -0600
+
+ Fix inverse(real, point, point) in geometry.asy
+
+commit a24beb6a7ff925034b170c9678ce83cc5653af20
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 19 17:29:55 2011 -0600
+
+ Print version number with -vv.
+
+commit dc8bf8804a4abee244e0c60cc05025d85092d797
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 19 13:34:43 2011 -0600
+
+ Increment version to 2.14svn.
+
+commit f8e0a8e91ce17902d1a63e1648867a42ab40c422
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 19 07:40:51 2011 -0600
+
+ Autodetect memrchr.
+
+commit f901f8836f3066777f1724cfe7c9286f4238c06b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 19 07:31:50 2011 -0600
+
+ Make install-prebuilt also install asy-keywords.el.
+
+commit d69d4b0f9e9983964a1530aeb8f90e568d283138
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 20:03:42 2011 -0600
+
+ Increment version to 2.13svn.
+
+commit f9789265ae0f8ed6d09f7c2403121233bbaa8184
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 17:29:56 2011 -0600
+
+ Support --disable-gl again.
+
+commit bd8211eabbbbbfa98721af242184314d41fa15d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 10:55:00 2011 -0600
+
+ Include cstring instead of string.h.
+
+commit be2e4fdd53804a8efe5a1bb6882da0c855fc1348
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 10:50:11 2011 -0600
+
+ Add missing include.
+
+commit cd4215443c2e68eebe65e41dd38f06c1d3be33bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 01:55:15 2011 -0600
+
+ Increment version to 2.12svn.
+
+commit ecae684548f36119f4216029716ebef377378a3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 00:40:24 2011 -0600
+
+ Update README.
+
+commit 1274ea3bdefa8a0feeb5cb9e715b1af4e7958e8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 00:39:21 2011 -0600
+
+ Update copyright.
+
+commit 5683c1169105e8d2d4fc6bfa3f9ef8f8c61c9dc3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 00:35:24 2011 -0600
+
+ Add missing install-prebuilt dependency.
+
+commit 4c1e1c3ef2654ae238dfa1560b1cfc724d6d5f43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 17:27:04 2011 -0600
+
+ Remove unwanted preprocessor conditionals.
+
+commit 0e5e96dd67755957dbb878a7ac16b7c96695d6f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 11:50:18 2011 -0600
+
+ Fix diagnostic.
+
+commit ea082454a2dba0cee29b9a3a442be584b1bdecb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 01:56:37 2011 -0600
+
+ Fix preprocessor conditional.
+
+commit d6d2c9539b55493e5af6f6bb5dd0d9db74c14bc4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 01:44:31 2011 -0600
+
+ Support compilation without GLUT library.
+
+commit 48c7204e3b32767ca26e247efb362cc0079d3dde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 01:04:36 2011 -0600
+
+ Disable offscreen rendering support by default.
+
+commit 5b49d89be10da47f31081cb11c3126f429f4ef9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 16 14:25:20 2011 -0600
+
+ Don't require LIBGLUT for thread support.
+
+commit a1692fce8acc26d53113cd10b987232802856188
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 16 14:19:21 2011 -0600
+
+ Remove unused include.
+
+commit 27baaf4d761a1e6ee9c19328a63acc25e5fda05e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 16 13:13:15 2011 -0600
+
+ Add preprocessor conditional for CYGWIN.
+
+commit 31be7f0e4cd4bb52846d67e1f1dd8ecf20a54eeb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 16 00:13:01 2011 -0600
+
+ Allow offscreen rendering to be toggled at runtime.
+
+commit 372affdfe0543bc92e87ea3413e059b80a058d40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 15 15:39:19 2011 -0600
+
+ Fix pen shift bounds.
+
+commit 99d807b7007f4a902cedd9e1a015f32394247e67
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 14 16:45:08 2011 -0600
+
+ Update README.
+
+commit 1fa461a73b642cea346f32ffb9beee5a3677a336
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 14 16:44:35 2011 -0600
+
+ Enable offscreen rendering; address autoconf warning messages.
+
+commit 1f34e235228e80d1c7ee1356c902bcfcbfdb50f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 14 13:01:48 2011 -0600
+
+ Use tirpc library under CYGWIN.
+
+commit 695dbafa436bc1e825ea38afe6d67b9017dd8582
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 13 15:42:24 2011 -0600
+
+ Fix handling of whitespace in word mode.
+
+commit 0c3dbafa9226f58f7cd1730ec8ea37dabde36495
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 13 11:01:30 2011 -0600
+
+ Fix implementation of data transpose.
+
+commit f6dae43413a31c8dca3136db9092463ec88e12b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 10 04:19:55 2011 -0600
+
+ Implement transpose option more efficiently.
+
+commit 4ea4c394a4db464247e5118c9c5380b46cac8893
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 10 03:51:30 2011 -0600
+
+ Implement transpose argument for pen function images.
+
+commit a1ad1a73b65cdafab966b5f3c05f0400b7e7bebd
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Jun 9 16:10:37 2011 -0600
+
+ Fix coding style
+
+commit aa0c48c1d950aa8752af0734208fe562890a6f32
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Jun 9 11:36:27 2011 -0600
+
+ Fix limit calculation of parabola and hyperbola
+
+commit 5d76dfbe4f3d772306c18d4ed8d36002461f66e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 30 09:51:41 2011 -0600
+
+ Remove extraneous declaration.
+
+commit 892558151c915760ed98d071685c8d7bb35fb025
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 27 17:14:44 2011 -0600
+
+ Add Orest Shardt's offscreen rendering patch (currently implemented and
+ tested only for UNIX).
+
+commit 09f908316f03378cf5ef395359b45d5acebacf64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 27 01:56:19 2011 -0600
+
+ Increment version to 2.11svn.
+
+commit d9e3abb8c9d6ff909d11180945111a531b9964b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 23:29:46 2011 -0600
+
+ Speed up example.
+
+commit 0631cca53d0723120b1c88b477ab18f5aa3c27e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 23:25:08 2011 -0600
+
+ Use complete userMax/userMin functions.
+
+commit 753eb653bfe539e392f1c36f07f1df789a438138
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 19:43:31 2011 -0600
+
+ Fix rendered preview images.
+
+commit f1c974625225af462e334d1bd43484508021a6e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 18:21:42 2011 -0600
+
+ Increment version to 2.10svn.
+
+commit fbb587cbf5578a2695664467a38362dfb524e71b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 14:06:11 2011 -0600
+
+ Add missing index entries.
+
+commit dbfd411c9ba5003351c93c86d9fc2f17b78f9391
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 12:37:41 2011 -0600
+
+ Implement
+ void pixel(picture pic=currentpicture, triple v, pen p=currentpen,
+ real width=1);
+
+commit 1541a42227d14700cdbdf19a8dfa4946a9aaaf9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 02:58:37 2011 -0600
+
+ Map [0,1] uniformly to [0,255].
+
+commit 4a2ccb7b31b79862d77cf80b62ea22373b4ab4bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 02:50:51 2011 -0600
+
+ Don't apply picture transform when computing limits of hyperbola.
+
+commit 6ee64567251b6fd3f9cce2eccfc9cf2440a5f1cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 01:28:15 2011 -0600
+
+ Check that arrays passed to the image routines are rectangular.
+
+ Implement general pen image routine, along with an example:
+
+ void image(picture pic=currentpicture, pen f(int,int), int width, int height,
+ pair initial, pair final, bool antialias=false);
+
+commit c2c919b3866afd8495640f47989527452d16ad8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 01:22:42 2011 -0600
+
+ Fix validity test in simplex.asy.
+
+commit 8311285017e676b718db670ece10dd55f292aa99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 25 14:46:20 2011 -0600
+
+ Simplify code.
+
+commit 4595377da618c41abfd1225b2e7c36b0b5441615
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 25 14:19:16 2011 -0600
+
+ Fix bug in optimized sizing routines.
+
+commit 6dce8552f95e7e5bef49becbe3b581ca0e5252cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 25 08:07:29 2011 -0600
+
+ Add Michail's recent PRC enhancements.
+
+ Implement PRC vertex-shading for straight patches.
+
+commit 34379b9e3c1913b57db5c87734830f630a833d1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 16 00:06:31 2011 -0600
+
+ Eliminate gcc warning about unused yyunput routine.
+
+commit e5d3ab2639f3f3b5832ca34893c562dc539befac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 15 10:29:31 2011 -0600
+
+ Implement keepAspect keyval option in asymptote.sty.
+
+commit e5865544385122605c2b031f1a7ca5ef28924fdb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 15 08:54:13 2011 -0600
+
+ Test for null Label in arrow().
+
+commit c653749f805ad1e5f2fa5f639d45f184941a544c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 14 00:52:04 2011 -0600
+
+ Check translation table size.
+
+commit 48ab45c2229b0eefc131ab54d566c4e9d4cf282f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 13 02:51:05 2011 -0600
+
+ Don't strip directory for .js and .prc file names.
+
+commit 3846842566cd886a8462bd1453d544b6a4865a41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 13 01:45:05 2011 -0600
+
+ Support PDF TeX engines in xasy.
+
+commit cf93f465fcf39048334c40ca96051c8d97402abd
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Apr 13 21:49:11 2011 -0600
+
+ Removed old rules.
+
+commit 26af240cbcaac8ee9b8225e1496205ec6907d21b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 6 20:49:10 2011 -0600
+
+ Remove unused code.
+
+commit cbc4996ce1aef5f513ffeedf838c14608b2fe07a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 30 09:24:10 2011 -0600
+
+ Increment asymptote.sty version.
+
+commit 86a45fa5d0aa5196a257b988902ac9bfa2a30033
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 30 09:21:48 2011 -0600
+
+ Allow leading spaces before \end{asy}.
+
+commit 619a38cae78e5fb60291972baa5d175f7888f4cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 30 09:07:07 2011 -0600
+
+ Add step option to indexedfigure.
+
+commit 09fbbf7c7b754cad11c5b2b35c7e196d13bded12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 30 09:00:57 2011 -0600
+
+ Simplify item casts.
+
+commit 2b3821e83fab71b9719a636c62cdb10e61970397
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 11 01:19:33 2011 -0600
+
+ Update TeXShopAndAsymptote instructions.
+
+commit 55dcb2872bd2b364bc0fde9122e428a1b8705116
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Mar 6 09:18:26 2011 -0600
+
+ Add documentation for keyword-only arguments.
+
+commit de48fd80cef132745608b6081e19e6b9812b770c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Mar 6 08:58:46 2011 -0600
+
+ Add keyword only formals.
+
+commit e28db8033261fd944648944918a57497aa080de8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 25 00:04:21 2011 -0600
+
+ Update example.
+
+commit 2a5c7a0b3d54cb3643ab77ca718a1ab9202489b6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Feb 24 17:17:48 2011 -0600
+
+ Fixed assert on array assignment.
+
+commit fe1724e28088f72b4f6845240259b8a511d461f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 22 17:45:01 2011 -0600
+
+ Avoid overloading built-in circle and ellipse functions.
+
+ Remove unused code.
+
+ Fix transform bug in drawline.
+
+commit 5a035149cc6b82bc53e867fa7dbb5670113c3bc1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 22 17:34:59 2011 -0600
+
+ Fix transform bug in drawline.
+
+commit 0f6d6d16a04877e8133f8692e766270f2d45bb00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 22 17:34:03 2011 -0600
+
+ Improve interface to trembling routine.
+
+commit 46ff6379757c102758e7c527eb038466d34549ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 12 09:28:39 2011 -0600
+
+ Remove unused member of drawBegin3.
+
+commit 6042454ca398acea0efbfc47d09c300ddb895bc7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 6 17:42:39 2011 -0600
+
+ Move unit constant into constructor.
+
+commit 7c2613352fe970f3ed1e780114db08c5ee389a6e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 27 13:38:09 2011 -0600
+
+ Speed up long long integer multiplication.
+
+commit 345eb851c2e49b2017620f34c6e1306abba09df9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 25 09:19:29 2011 -0600
+
+ Change Int to int.
+
+commit d486f3fee70be67c7660d68eb93a730bf78404bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 20 08:54:32 2011 -0600
+
+ Always output preamble definitions.
+
+commit a0d8db72b45ccb2514d0eeb4cd4a10bb57caee49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 8 18:08:39 2011 -0600
+
+ Update examples.
+
+commit 9d8586ba41a6fb37b2515bf4009788aea0a7e8a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 8 16:36:57 2011 -0600
+
+ Enable Andy's new sizing routines.
+
+commit a07d4ee6172b69d69bbe5348dfa8530212ccd233
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 30 23:58:29 2010 -0600
+
+ Update refactored files.
+
+commit 448c94a01985e6152dc7f62c3417efc733cad0d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 19:50:38 2010 -0600
+
+ Use a temporary expression for self operators to avoid side effects, as
+ suggested by Orest.
+
+commit 306f0d9603d3eb97bb0c373597b7b427103a2060
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 22 06:40:48 2010 -0600
+
+ It is no longer necessary to append to an existing preamble.
+
+commit d43df1261b0fe3f53dcdee5f0c401fff837ce20c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Nov 30 07:34:19 2010 -0600
+
+ Add commented out code in bsp for new sizing routines.
+
+commit 5c45929cbd618acca4f76d1f048df99e72c9504b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Nov 30 06:55:53 2010 -0600
+
+ No error on userMin of empty data.
+
+commit f47e22e7ad395eef6030bed302b035baa21849fe
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Nov 29 16:02:26 2010 -0600
+
+ Fix merge typo.
+
+commit c571692aeb21dfbc7ccdae540645705659604b86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 28 11:41:26 2010 -0600
+
+ Move limits commands to after draw commands to work with recoded picture
+ sizing routines.
+
+commit 2d72b2c0b3c059df0d26ee371c5f185eefd5cd5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 28 11:37:44 2010 -0600
+
+ Begin to port graph, graph3, and three to use recoded picture sizing routines.
+
+commit d9965fbc15ae03569d9639a2731d12cebf1b34a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 28 11:07:58 2010 -0600
+
+ Fix unused value warnings.
+
+commit c75147a6a0f4bdd9bdca113dd3a91d2e9cca9e4d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Nov 22 19:33:07 2010 -0600
+
+ Fix userMin calculation.
+
+commit 81579ddd9d1c29b379be8fbd12198f5b8f0e206b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Nov 22 06:41:12 2010 -0600
+
+ Add fill paths to userMin calculation.
+
+commit 6265d4a32aa110f6eb2d82d3a88bfade0f26e442
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 10:29:59 2010 -0600
+
+ Fix definition of heavygrey.
+
+commit 8fd4d7688b9c8315d4275996108c051f4550443a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Nov 15 21:17:37 2010 -0600
+
+ Emulate old userMin/Max behaviour after transform.
+
+commit 815fe39946921fdc7ab677bf02155dd8f6193429
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Nov 15 20:38:23 2010 -0600
+
+ Changes to userMin/userMax interface for graph.
+
+commit d55f36264e0ed8c14c024dee791fbf91020354dc
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Nov 15 20:36:57 2010 -0600
+
+ Re-implement userMin/userMax in repicture.
+
+commit d4be1ba2e67c506a3bf6af0f94a9a558e648d1b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 15 19:10:19 2010 -0600
+
+ Fix horizontal and vertical lines in Drawline.
+
+commit 91d758fe53e4b896028553eade4e20c4471bf4b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 11:43:27 2010 -0600
+
+ Update FAQ.
+
+ Add integer version of partialsum routines.
+
+commit 87ea96ebf5e48282434745bfc9e615ebbcd4de8f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Nov 6 07:19:07 2010 -0600
+
+ Fix SIMPLE_FRAME flags.
+
+commit d6b0775041f54e4afbe9c060e7cffb553c005977
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 3 21:22:25 2010 -0600
+
+ Increment version to 2.09svn.
+
+commit b3951daf804b0e7285f91cdfab2f802d27ef5aa9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 2 22:50:12 2010 -0600
+
+ Fix incorrect marker optimization in 2.05-45.
+
+commit 2de1d3071edf164d188ca6abf1962bde777149ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 21:40:15 2010 -0600
+
+ Increment version to 2.08svn.
+
+commit a2c1fe84f6ca6c7184ed790df9093433a2bb63e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 19:20:47 2010 -0600
+
+ Work around missing CYGWIN prototype.
+
+commit 1e4dcd556029147596dd58892fb289353cb13dc3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 30 12:53:00 2010 -0600
+
+ Test while and do loops.
+
+commit 9d91b1617ac13f994865701b85d18f8ac401d535
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 30 12:43:15 2010 -0600
+
+ Fix loop ordering.
+
+commit 396cbf6e8b3e6e83d2731f8af8cc949540ed58dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 08:56:41 2010 -0600
+
+ Implement string mktemp(string).
+
+commit 2ea6d9965a38c28021e221832473283c5c19bee0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 08:53:08 2010 -0600
+
+ Improve asyinclude so that asy source file is not required by publisher;
+ make .asy extension optional.
+
+commit bdd8423abe94b67360faafce2c51b2c442071f00
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 30 08:00:30 2010 -0600
+
+ Experimental closure implementation.
+
+commit bf515db31600ef29579f5b4ddff865a86a5ddd11
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 30 06:01:39 2010 -0600
+
+ Refactoring of variable access.
+
+commit aaf081410074fdddb3ff3e94c62dba6a37f75a9d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Oct 27 18:44:51 2010 -0600
+
+ Removes inst::alloc.
+
+commit e72cce136c1791711d91098995f3a07dbd3dab7d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 27 16:51:40 2010 -0600
+
+ Add -P option required by gs 9.00.
+
+commit 2ba1eecfc8f34a3e784c34d68832fa290a1f6466
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Oct 27 16:30:35 2010 -0600
+
+ Allocates closures only when needed.
+
+commit 1ece08094f88644a790bd049a46dff9d6304dbf2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Oct 26 17:35:37 2010 -0600
+
+ Don't push a frame on every loop iteration.
+
+commit 12e387dd2efd2c88870aad3a4960d0adc6b9e0d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 26 10:36:51 2010 -0600
+
+ Make limits work with reversed axes.
+
+commit 3ced6d47c7b36dbf6da4a5f5a957d9dce564e648
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Oct 26 08:23:51 2010 -0600
+
+ Defines opcodes in a header.
+
+commit ba35f6b8ecfabdeefbc5608951c971a6dcff300a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Oct 26 07:40:00 2010 -0600
+
+ Additional for loop testing.
+
+commit b7f599201df55456545371f0973b1b36aef1fd1c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Oct 25 20:31:29 2010 -0600
+
+ Refactoring of texpipe queries.
+
+commit 4f8f61d5d5eb32945700a6dad40fffc71a7370f9
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Oct 25 19:53:13 2010 -0600
+
+ Removes dead code.
+
+commit 4dba0c6d5143633c1071941b6ae6d62a7576ab27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 19:11:32 2010 -0600
+
+ Increment version to 2.07svn.
+
+commit a9ff63643fc70a1c0af2c02b582e846241474cf2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 16:14:41 2010 -0600
+
+ Force generation of asymptote.sty when building documentation.
+
+commit 6a0189334e67f49427f0bc7e074ef30fe74e5994
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 19 08:07:30 2010 -0600
+
+ Add missing CONST qualifier.
+
+commit 0242f30701e0b32525f63a838dbf851ab4076c4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 18 19:08:41 2010 -0600
+
+ Add missing sty targets.
+
+commit 79c6efb8ddb219deeb3c7596cd101f23b98831ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 18 02:17:25 2010 -0600
+
+ Increment version to 2.06svn.
+
+commit 7cabf7209638d0462b3d13f6753cf8d50054c932
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 17 23:58:30 2010 -0600
+
+ Replace asymptote.sty with auto-generated version 1.21 contributed by Will
+ Robertson, with a new latexmk-compatible asyinclude feature.
+
+commit 9f0071ef25bc9ee8650f0a9cb947e8b32930f366
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 17 21:44:20 2010 -0600
+
+ In inlinetex mode, avoid interference from pre-existing aux file.
+
+commit 4bccec139811be55a82e004cebf40094143f0c1b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Oct 10 08:31:10 2010 -0600
+
+ Faster texprocess string matching.
+
+commit 78df14ffdfcf926e9e97f658a5fbb27652947489
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 27 20:59:34 2010 -0600
+
+ Remove quotes from textattachfile.
+
+commit fd7d89a12f2bc4a79940b60404c5111a4366045d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 27 01:50:25 2010 -0600
+
+ Allow spaces in file names.
+
+ Support attaching of eps files when using dvips driver.
+
+commit 9b2a87833be4c40e39e936e904305686b677d8b3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 25 22:43:34 2010 -0600
+
+ Re-implement label system in coder.
+
+commit a6ebf8d91f6f3a4b7088a1c93019d16b6ef2b770
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 16:43:08 2010 -0600
+
+ Faster fields test.
+
+commit 455357f859ad27e19dc8d2726fc490ca9bfda599
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 16:42:13 2010 -0600
+
+ Optimizations in plain_repicture.
+
+commit c75cd8e741ccb1c477ca9116e53dcae4c2b89977
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 10:12:24 2010 -0600
+
+ Handles default draw calls more efficiently.
+
+commit ae1b0856e1390fe5a9e55439b1e0e45ec812b8dc
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 09:06:05 2010 -0600
+
+ Avoid calling xasy commands during shipout.
+
+commit 4a3fc4de1f43b6e57852da5400099d6b244ef487
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 08:59:21 2010 -0600
+
+ Crazy optimizations for plain_bounds.
+
+commit ac181cb08d1177dcbb4ba2de39493cc9f76f4800
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 08:49:59 2010 -0600
+
+ Adds printBytecode function.
+
+commit 2f36994507b83ab59c7af94cc4b8fc8cc60dcc5a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 08:33:57 2010 -0600
+
+ Opcodes for default arguments.
+
+commit 6627bacb1282178d1db6844de3fa95d968b4a866
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 08:32:42 2010 -0600
+
+ Terse position info output by profiler.
+
+commit 9f12219807c2f415463e70b0487e42bf6acf7cf3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 24 08:29:48 2010 -0600
+
+ Profiler improvements.
+
+ Adds timing of builtin function. Now gives output directly readable by
+ kcachegrind.
+
+commit ef13d4a9ac4dfcb7ddd020c67f4464d5e0e6e13b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 20 09:26:06 2010 -0600
+
+ Use old, deprecated timer for profiling for compatibility.
+
+commit ceff1a2df9ddfca7c9ae36028bd190964497d451
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 20 08:36:00 2010 -0600
+
+ Change NullLabel to just null.
+
+commit 74e42795dbc169747ae792f951d9db5d679e1028
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 20 08:12:23 2010 -0600
+
+ Test for clock_gettime support.
+
+commit d941ae286429e3e39337cce5ee21ea1f07cb71b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 19 20:20:43 2010 -0600
+
+ Handle above argument.
+
+commit 26c4c6b2535edd0f2498e8807a78248480cad281
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Sep 19 18:45:23 2010 -0600
+
+ Re-implement userMin/userMax.
+
+commit d35bbef720993d5dd209415dc16080b4f9e781d0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Sep 19 17:56:37 2010 -0600
+
+ Renamed smartBounds to just bounds.
+
+commit 362d4475c79a97d1af12dbe5ba209519045c1855
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Sep 19 17:47:48 2010 -0600
+
+ Sizing of transformed path arrays handled in C++.
+
+commit 2cdae67be942ea7aa38bcee182fc730c2479476b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Sep 19 17:34:34 2010 -0600
+
+ Use NullLabel to avoid Label instantiation.
+
+commit 9d8c1c4818957a3460175a80ec95bb4807863d56
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Sep 19 17:04:56 2010 -0600
+
+ Add nanosecond counter to profiler.
+
+commit 8ea5d15b5f191c0359eb25aa93ac11531fc31ee4
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Sep 19 16:12:17 2010 -0600
+
+ Calculate bounds of path arrays in C++.
+
+commit a1468cc0d6f8fd946111f13931bfe4076e3a1ab2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 18 17:51:11 2010 -0600
+
+ More efficient calculation of extremes.
+
+commit 22c2481b1d549c1730083db70ba4ff6eeaffceca
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 18 17:08:14 2010 -0600
+
+ Avoid creating arrays of celltype error.
+
+commit 7140cd8a66595e42dc68f7b884b3149c37791f95
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 18 16:29:25 2010 -0600
+
+ Adds calculation of extremal bounds.
+
+commit 6f3e85c39e7785cb0f65d30b531a33e00d3532ce
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 17 19:03:15 2010 -0600
+
+ Stores paths for sizing data.
+
+commit 146a0d496cba471523aea8abdfc30897e78cbb96
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 17 18:21:16 2010 -0600
+
+ Reimplementation of transforms of pictures.
+
+commit 57a349e72797cbe8b317356040667046f078e44e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 17 18:20:27 2010 -0600
+
+ Dump profile to a file.
+
+commit cd2c1384e779b5b244ead0b82979a5462d71ee4a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Sep 15 17:41:34 2010 -0600
+
+ Adds transformedBounds.
+
+commit 5a783605c08bac2a2d1766362c757ca15caf419a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Sep 15 15:52:30 2010 -0600
+
+ Adds freezableBounds.
+
+commit e95b926afc34136e4a19dcbbac259002b17aa730
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Sep 14 08:34:57 2010 -0600
+
+ More sizing refactoring.
+
+commit c9d6db1074e8c8b14d31c109ebc79329e0a26d41
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Sep 14 07:43:00 2010 -0600
+
+ Minor refactoring.
+
+commit d3d14e5aff62f15ae524a93077020a0dea9c40c1
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Sep 14 07:21:37 2010 -0600
+
+ Start of refactoring of plain_picture.
+
+commit 1495983b9fdb95982df14c7b058d225279d4a46e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 16:21:45 2010 -0600
+
+ PRESYM is no longer an option.
+
+commit 74e0946ad0bcc12e7794d9d4e21958e0b8d9ef28
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 16:07:45 2010 -0600
+
+ NO_FUNC_OPS is no longer an option.
+
+commit e9bedf1ce945afa3ef54a748ffeea0b508d03e84
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 16:01:33 2010 -0600
+
+ TEST_ADDED_OPS no longer an option.
+
+commit 9e31c2c70428c5b9cb466754c5fb537f3408950f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 15:54:55 2010 -0600
+
+ EXACT_MATCH is no longer an option.
+
+commit f062fd5dc49099c581a3cb377e212c603d4f941b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 15:49:22 2010 -0600
+
+ CALLEE_SEARCH is no longer an option.
+
+commit ae118ffa5e19de397071dd191f974feedce172c4
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 15:31:32 2010 -0600
+
+ FASTCAST no longer an option.
+
+commit a4968efea19ceb48b2c1575f30b6f6b94bd5f24a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 14:50:43 2010 -0600
+
+ Avoid false positives in output testing.
+
+commit 632c5f8348d9da9934c49b57d107e2afc6c05035
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 11 14:48:52 2010 -0600
+
+ Remove inappropriate comment.
+
+commit 9406ca4b9bfebbdab8a230f16c37cd7eef041611
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 28 09:42:09 2010 -0600
+
+ Update documentation.
+
+commit 6d62b2bdb1727d7b56b1cdb3401e0454be88c2a4
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 21:39:49 2010 -0600
+
+ A nascant profiler.
+
+commit 6662e7316a3db521d3e0f6e20f4f6c762d19b3c8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 21:36:43 2010 -0600
+
+ Also needed for arbitrary depth array constructors.
+
+commit 2ba49e0e5a7da7287b7b46c34a29271987cc08fb
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 21:35:28 2010 -0600
+
+ Re-implement arbitrary depth array constructors.
+
+commit 4a72a1c8a4584804ed46edc7239d31131f1d288a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 21:34:39 2010 -0600
+
+ Implement callableAccess.
+
+commit a8138ee42767e9b1649a13c47fe6fe1d757352a5
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 21:34:08 2010 -0600
+
+ Re-implement item printing.
+
+commit 9bb04c479be057af191a5686f92c20a881521f44
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 16:28:35 2010 -0600
+
+ Remove TODO items we have no plans to implement.
+
+commit e3962c6fc1f73b44ba66eb846779b4401f3aff98
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 16:11:52 2010 -0600
+
+ Add TODO item.
+
+commit cbf8d06f86ec17a7718d50c226757cdfeea08db2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 27 11:46:45 2010 -0600
+
+ Add TODO item.
+
+commit 1cac46da6a8b2f3df3e547a7540bb9c64d777843
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 20 16:48:08 2010 -0600
+
+ Increment version to 2.05svn.
+
+commit 0f659e41a2e644c23bed47aa30a88520313275b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 20 00:26:35 2010 -0600
+
+ Fix jobname extraction.
+
+commit 2c5d9a2a024712f726cf77e390052076ac465289
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 20 00:25:24 2010 -0600
+
+ Avoid hyperref/fp conflicts.
+
+commit fd15dba79900ba4d2f5f427575447ebb87c64ad5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 19 14:17:55 2010 -0600
+
+ Work around MikTeX jobname bug.
+
+commit 202e76f8e57b572cf6d7af199af8a1a721a67ac2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 19 09:42:38 2010 -0600
+
+ Use \jobname in generated TeX files in inlinetex mode (to allow renaming
+ of files).
+
+commit bd3ab978ce8f7d88c8005cb3be2fe434286756d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 17 07:14:43 2010 -0600
+
+ Make asyprefix work with obsolete versions of graphicx package.
+
+commit 41f82fa65bc9929fc3d0c5624e23814199912027
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 17 06:12:53 2010 -0600
+
+ Suppress messages from FP package.
+
+commit 461253a561ba8c6dc43c680488c77767632f1f3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 13 06:05:44 2010 -0600
+
+ Fix documentation of render.merge=default.
+
+commit 69335bb2a494fd3ab0d40e8091712681521a6134
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 13 06:04:46 2010 -0600
+
+ Do not fill subdivision cracks in transparent labels.
+
+commit d4dba39de0514e82f86b456316fabe6756e1b848
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 10 13:37:07 2010 -0600
+
+ Revert last commit.
+
+commit 49a0247274e67d43fc3b6d940154dd1d84d25882
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 10 13:27:42 2010 -0600
+
+ Work around quoting problems with obsolete versions of graphicx.sty.
+
+commit f32271c511a95dbfd4ca451fde08d7ca44d642a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 13:57:53 2010 -0600
+
+ Fix man page.
+
+commit 652bdd01d7bf512bd3a3ab96071d54f550327297
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 03:23:38 2010 -0600
+
+ Add DOSendl and DOSnewl line xterminators.
+
+commit 36c0268bece291c00797a65221e55cb51a5369b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 4 14:56:21 2010 -0600
+
+ Handle MSDOS line terminators.
+
+commit 86aff539c9d093d0c51b7460e9ca889e4a2b7f68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 3 13:10:10 2010 -0600
+
+ Increment version to 2.04svn.
+
+commit 7c7f66fb477566418d9f45f55c9863068b4e5385
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 3 06:14:46 2010 -0600
+
+ Fix blank 3D labels.
+
+commit eb7e475b6b5686bd3d85bcbac24e4bfa56e11a36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 3 06:07:51 2010 -0600
+
+ Add world map example, courtesy of Jens Schwaiger.
+
+commit e5b8f62d73bcd6259fb2dc3efefb00f3a8fb1bda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 3 02:54:52 2010 -0600
+
+ Add latexusage \asydir support for putting asy files in a subdirectory
+ (within which one then runs asy latexusage-*.asy).
+
+commit c8ef9049c17281ae495f3de25a65c3f0a2ef5cf1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 2 21:28:08 2010 -0600
+
+ Fix inlineimage option.
+
+commit 102c273d071842d51a2b3036a07aa0af7a9377cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 1 01:42:17 2010 -0600
+
+ Use $(MAKE) everywhere.
+
+commit f304126618eea4c501ec9c014ed9a4e3a82e00c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 1 01:08:42 2010 -0600
+
+ Clean up auto-generated files.
+
+commit 320f0c323efc4514a746aff1878d708e1e66cdae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 06:26:17 2010 -0600
+
+ Add missing pen and margin parameters to blockconnector function calls.
+
+commit fd56cadd4fc9075bf2ea95b13b679e321443f1a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 26 11:45:32 2010 -0600
+
+ Improve definition of Dotted.
+
+commit cf4732530cf046b7a4f0e63109eed5e7f64cb659
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Jul 25 06:48:26 2010 -0600
+
+ Implement fix of Olivier
+
+commit fb45aa2a5664199f278a62911e1205aa21370dce
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Jul 25 06:33:27 2010 -0600
+
+ Remove trailing code
+
+commit 40d3075aeec88fc1402a0b2948200b01cc810c05
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Jul 25 05:41:48 2010 -0600
+
+ Fix casting degenerated ellipse to path
+
+commit 365f1a297d9b7275ab282742ee9c25a847d19dba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 24 00:09:39 2010 -0600
+
+ Add missing arguments.
+
+commit d0117f4f6844837362ea62b7bb40e7e7e37db16a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 22 23:30:17 2010 -0600
+
+ Fix typo in asymptote.sty.
+
+commit d068ce357b537c9322d5072cdab771a8b2b4e5ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 22 11:32:23 2010 -0600
+
+ Remove unwanted blank lines from asymptote.sty; support XeLaTeX again.
+
+commit 5fac5e86473523db335119bffc3a5a4e0ce96783
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 17 21:24:51 2010 -0600
+
+ Support nonrendered preview images via render=0.
+
+commit c3f3b373cc80f9886d2ba4fa415b81da22bd0cb9
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 17 13:36:06 2010 -0600
+
+ Optimize virtual methods.
+
+commit c73e9affc027e1c864c280bb3542ed7de9ccd3ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 15 14:36:44 2010 -0600
+
+ Fix man page.
+
+commit 35039790021f0abe456342d830e55914075ba93f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 15 14:27:57 2010 -0600
+
+ Improve documentation.
+
+commit b293b2a70405ead60e25e812419b85f429235c75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 13 13:40:55 2010 -0600
+
+ Update documentation.
+
+commit 49b6a721d1b8a57b74534ba4c51c4fc6cada4142
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 13 11:29:26 2010 -0600
+
+ Update MSWindows documentation on setting environment variables.
+
+commit 18e31bb1e82ff8046a79106d3324f5af7d6c846c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 13 11:24:33 2010 -0600
+
+ Automatically add Asymptote installation directory to MSWindows path.
+
+commit ab5d13c370add6eb69fab571919836c1a49348cf
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Jul 12 16:23:41 2010 -0600
+
+ Fix directions with arcs in geometry.asy module
+
+commit 9287c8c7bd6bc4265a0b5567acac28788d1e1ae8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 12 01:52:22 2010 -0600
+
+ Add output test to make check-all.
+
+commit 6a71afc7f41faa3cad79a0600c6e66cea3e4abe8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 12 01:11:22 2010 -0600
+
+ Fix latexusage Makefile dependencies.
+
+commit feeb4ded2faedf174c97be5d540f4395803784c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 11 23:33:06 2010 -0600
+
+ Fix makefile dependency.
+
+commit 35c37874431d99b5b11f8bedad70fbe19469d37c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 11 22:54:35 2010 -0600
+
+ Remove perl dependence from source tarball.
+
+commit 4a06ca3d336219fca95c010061b0730b4c09c756
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 11 09:52:09 2010 -0600
+
+ Increment version to 2.03svn.
+
+commit 3dd9ad77a525aa8608eeeb44cc18aa3f118d3271
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 11 01:42:54 2010 -0600
+
+ Quote file argument.
+
+commit a047e05141ace0ac49176a466a13b6f292ed6bb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 11 00:38:31 2010 -0600
+
+ Fix typo.
+
+commit ad2403665c0e9decb1a5370c1738e86d9f08a216
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 10 16:33:22 2010 -0600
+
+ Changed extended for statement errors.
+
+commit e9018da9ba4fa25596fb42396a525a94172a39f5
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 10 15:06:05 2010 -0600
+
+ Better error reporting for extended for statement.
+
+commit 0f7ef36f919ccad768f447c58dce846860817e93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 10 12:03:58 2010 -0600
+
+ Add latexmk custom dependency for EPS files.
+
+commit 5e4adcf20d3fdae99de2c2565667ed1ea455b9c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 10 10:52:15 2010 -0600
+
+ Fix makefile dependency; clean up files.
+
+commit b2486208672d373faf72463bda65bd9aa84fc165
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 10 02:19:57 2010 -0600
+
+ Fix asy() command.
+
+ Delete duplicate example.
+
+commit d1f1afa0eb8f348d2ff9e85d8bf2fd3eb8ed8deb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 10 01:17:53 2010 -0600
+
+ Rename *_.pre preamble files to *.pre.
+
+ In inlinetex mode, rename *_.tex files to *.tex.
+
+ Allow the inline option to be specified for every figure.
+
+ Implement a global attach default option.
+
+ Do not generate a global latexusage.asy file along with the individual
+ latexusage-*.asy files (this is a backwards incompatible change).
+
+ Add latexmk support for compiling individually only those figures that have
+ changed.
+
+commit 06191baaae190da09f18894b01fe70c574534d98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 9 08:41:10 2010 -0600
+
+ Fix example.
+
+commit e0bc424b13aba48adbfaafaa91f3e2b684bdf05e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 8 12:01:55 2010 -0600
+
+ Minor simplification.
+
+commit 82bf92094ef0dc187075253682eb76c6468b0859
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 8 11:56:43 2010 -0600
+
+ Simplify texpath.
+
+commit d6b02f1be32ff3de9eafbe52e41c8b0e7db87fcf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 8 10:54:27 2010 -0600
+
+ Fix multiple fraction bar bug.
+
+commit 5ae9a888f9e3e2955c87684412d3deb1edabc8bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 8 10:46:59 2010 -0600
+
+ Fix texpath("\relax").
+
+commit 451ed2fa9b8443d3021984c0a698d854c0a3a9b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 7 09:54:38 2010 -0600
+
+ More portability fixes.
+
+commit 5a8986dd5c9a27cf45c80315ad0e2dec0315a321
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 7 09:05:00 2010 -0600
+
+ Define __GNUC_PREREQ if undefined.
+
+commit 6c9ec4ee269de9e2a8299a22580090154e51bd08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 7 08:58:43 2010 -0600
+
+ More portability fixes.
+
+commit 6c47fd14b11a9f429be5196b7b1ac7319541d27e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jul 7 07:22:38 2010 -0600
+
+ Re-implemented sanity checks in venv.
+
+commit 55557c59c13a6c289e17e3ebe6a9e809ae89fb58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 6 23:45:57 2010 -0600
+
+ Fix warning messages/portability issues.
+
+commit 8cc169b9e14b775e235eee5c95f0a3bf5dec3fd9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 6 15:22:58 2010 -0600
+
+ Remove obsolete infinite coordinates.
+
+commit 5b9962cd664a61a753b92ce7d771d3495c3be6f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 6 14:57:47 2010 -0600
+
+ Revert 1.97-23 for frames.
+
+commit d5ae51b2ef75de6ce0d408bf94ce5cf85832602a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 6 11:57:08 2010 -0600
+
+ Fix conflict between asymptote.sty and changebar package.
+
+commit a0361fb3ebe1f78e44d8d07f7c24f161f2c6b829
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 5 14:30:12 2010 -0600
+
+ Minimized the impact of the NOHASH directive.
+
+commit bc7a7f8e7c803f6ea6a42d71892014b5cd42bec8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 5 13:56:17 2010 -0600
+
+ Common sub-expression elimination.
+
+commit c979f0b1d691e9035c978cc7a188a91dfda1bc22
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 5 13:53:15 2010 -0600
+
+ Removed 'key' class from venv.
+
+commit 0f509e143738a758eb31cba0f6c3e1b4979da49d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 5 13:35:19 2010 -0600
+
+ Removed dead code.
+
+commit 27400cbb97c9454f150a8f05237adcb15daf265e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 5 11:46:23 2010 -0600
+
+ Custom hash table in venv.
+
+commit 33148865baed677644ec9206e24b751364ab9be1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 5 02:44:07 2010 -0600
+
+ Support xelatex animations.
+
+commit 7205ed148d4663e1a0de4e2f994afd338d3b6a7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 5 02:27:26 2010 -0600
+
+ Increment version to 2.02svn.
+
+commit de30983cb5f4be395ef392096cec503de7433d54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 5 01:23:04 2010 -0600
+
+ Remove invalid option.
+
+commit 26ae5e989036159e6bbb5569be53b30318aed567
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 5 01:12:29 2010 -0600
+
+ Support individual processing of each figure within a LaTeX document.
+
+commit c4c98d4a896e3207fd43a815252dbce55bcb7799
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 5 01:03:52 2010 -0600
+
+ Update talk.
+
+commit 66c05e3a5bbf6563b3a0c51119853311227987dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 5 00:22:55 2010 -0600
+
+ Revert to type1cm.sty since fix-cm.sty does not work as advertised.
+
+commit a79a7f5d52cbff70be05bf432cb50af1dbda4c64
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 3 16:56:38 2010 -0600
+
+ For loop and var documentation.
+
+commit 63c28745e65efa3e49a1e91df04baca5d4d7d562
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 3 16:52:23 2010 -0600
+
+ Allow var in extended for statement.
+
+commit 4b097c00549c6e67fc3e52fa88c58885b454825a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 3 01:37:08 2010 -0600
+
+ Delete old aux file.
+
+commit 8282862ccef850c116aced9748f299effd73f573
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 3 01:32:58 2010 -0600
+
+ Use settings.outname().
+
+commit 0ebd3ceefce3fedee8e6405af46ab2ff284d2ce8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 1 17:05:34 2010 -0600
+
+ Enabled transConditionalJump.
+
+commit 282c8a98337af10de3ce40133dbe0a1b334638f2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 1 17:04:30 2010 -0600
+
+ Slightly more optimized bytecode.
+
+commit c9202c71ecdc432901d86f7608f8e2be7faa607e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 30 09:24:59 2010 -0600
+
+ Update example.
+
+commit ad2e01d9abc82576b4b6690c2ae84489400dadea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 30 03:51:04 2010 -0600
+
+ Update lecture.
+
+commit 594c0929596014b567855bfcb27120fedd3c64dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 30 02:50:12 2010 -0600
+
+ Fix normal vector for perspective projections.
+
+commit 2fcb49b537e443ec0a1e9cd0ca70d05687e2aa3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 30 02:43:26 2010 -0600
+
+ Revert 2.01-7.
+
+commit e3a210c6c8f490d66fe951998d583dabe1108cba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 30 02:20:14 2010 -0600
+
+ Add new examples.
+
+commit 0482f1e30ad4f3cf5a95f1341f974632c84b0f7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 29 23:55:45 2010 -0600
+
+ Revert docdir changes since they break rpmbuild.
+
+commit b8828810887628ff47be1c8b82113458dc315f2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 29 23:39:30 2010 -0600
+
+ Fix docdir.
+
+commit 4f9236b06747902a8ed07cf8d862905294570f18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 29 22:53:02 2010 -0600
+
+ Use PenMargin in drawing a binarytree.
+
+commit 154b2cc14f0d405afd1c88645a6de8e890819072
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 29 22:49:17 2010 -0600
+
+ Check for \r as well as \n terminator.
+
+commit ac465c8dbcd10bc76db0b9bd107dd50d98c4b2d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 28 18:45:05 2010 -0600
+
+ Support docdir.
+
+commit 31785de3fb7ecc03427a8d1280d9348facb32d7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 28 08:44:34 2010 -0600
+
+ Improve example.
+
+commit ce3da01f8c4ae0368a381a38eb1fecbbc02ca4b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 28 08:29:15 2010 -0600
+
+ Improve example.
+
+commit 9e2af753ee8bb420bd1e8590f72001804c049822
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 27 17:57:33 2010 -0600
+
+ Use values for BoolTruthValue and BoolFalseValue less likely confused with
+ another type.
+
+commit faf789e220b79d61046567ecdfa54cadee29d400
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 27 16:46:03 2010 -0600
+
+ Add quasi-type checking for bools.
+
+ Clear uninitialized item bits.
+
+commit ccb5ec5ec57e599454e1c12a5a0be113f185f2f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 21:44:33 2010 -0600
+
+ Update example.
+
+commit 1f8c956bee25307951b95384b40f0f2e00ee645f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 16:29:44 2010 -0600
+
+ Increment version to 2.01svn.
+
+commit 8c7aad3f741b646e0d779f2df57853123a07c1c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 13:27:05 2010 -0600
+
+ Fix warning message.
+
+commit 5696f65ccdf5c48c09806b172b7d9fde4aa47826
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 12:57:35 2010 -0600
+
+ Port to CYGWIN.
+
+commit 04da58c5cc915a34d75b5efb73df340345b73348
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 12:09:33 2010 -0600
+
+ Add 3D bar graph example.
+
+commit 54cca96e42935334c966a78f35994291f2fe546c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 11:49:46 2010 -0600
+
+ Update examples.
+
+commit f887acf5613925b857b2bc232cdf41c0b9ccecdb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 11:44:08 2010 -0600
+
+ Fix viewportmargin.
+
+commit d590f18c1ee65fa58abb24490611c9cb0de4d6b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 11:14:09 2010 -0600
+
+ Fix orthographic sizing.
+
+commit 121b68177e60e59716f78d28b8a808f7aad77433
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 02:32:04 2010 -0600
+
+ Rename GSL test.
+
+commit 10bc45c70c46fb13558e3996e0c5f60972fd1f95
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 02:25:11 2010 -0600
+
+ Fix displayed PRC units.
+
+commit 92e69381d148da6e6c1daae18d9d278994065264
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 01:08:24 2010 -0600
+
+ Remove unused array.
+
+commit 6e10720e4a06c53822a01240ea5108df19dbfbfb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 24 17:01:12 2010 -0600
+
+ Fix drawing of 3D thick lines of length 0.
+
+commit 13f4f6d20babb1c373b1c479dea510d1886f2f5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 24 00:57:58 2010 -0600
+
+ Make lexorder in math.asy a strict partial order.
+
+ Implement int search(T[] a, T key, bool less(T i, T j)).
+
+ Batch 3D TeX labels.
+
+commit b8a4afd8ebfe8af6cb10025fb6d8a6d070dc62da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 23 00:09:35 2010 -0600
+
+ Remove unused code.
+
+commit 0ae9d0b1bc726142f2e5be4524756327371f91f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 21 08:54:34 2010 -0600
+
+ Suppress plain TeX page numbers.
+
+commit a50979917974199334c1173a4e02650ae38e2882
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 20 12:32:46 2010 -0600
+
+ Disable nonportable GSL tests.
+
+commit 511739b7fd0f39b51a959bd2da94d85683829bc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 20 12:20:46 2010 -0600
+
+ Make gsl optional by moving it to make check-all.
+
+commit ccdcbcdbf1bda211a1b2266c77ea2b0e13db9473
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 20 11:54:27 2010 -0600
+
+ More GSL portability fixes.
+
+commit 54763841fd01c553679f2894ad57f44c3a629e7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 20 09:15:43 2010 -0600
+
+ Fix GSL typos; add tests.
+
+ Restrict make check to a single processor.
+
+commit d92c2b5d6f7f2241ea7c296f85e54087d3f40018
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 19 22:25:10 2010 -0600
+
+ Fix preprocessor conditional.
+
+commit a1c4f8af41d44d2062e90742d49e21bfc606e603
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 19 22:16:51 2010 -0600
+
+ Fix typo.
+
+commit d4feaa7568704870cd449c402de0099c4f544418
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 19 22:16:08 2010 -0600
+
+ Move GSL functions to gsl.cc; implement Elmar's contributed GSL functions.
+
+ Invoke the C preprocessor in pretranslating symbols.
+
+commit 690cfcf0aa780f5981e46360319bd2cfb27219da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 19 21:51:07 2010 -0600
+
+ Add unsigned int constructors.
+
+commit 088f6dfe2609b4311b5b04fba4fc600779029f7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 19 09:08:34 2010 -0600
+
+ Update example.
+
+commit a29f0ae6edc9bef2348c6b8a2ef29a0cc7283f15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 18 02:44:57 2010 -0600
+
+ Increment version to 2.00svn.
+
+commit 38c4c0eabbd3036a4e521f9499a51b5d01eef3f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 18 02:07:40 2010 -0600
+
+ Fix warning message.
+
+commit 06886a79e81b86dabe7154810d4b777e41909222
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 18 01:01:53 2010 -0600
+
+ Update test.
+
+commit 4f9950396d0db4476343d9ebe52618a54317fbda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 18 00:56:06 2010 -0600
+
+ Reduce example output.
+
+commit 2f4c7ccdd761c3cf94f72e33d0eb43d9300a423d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 18 00:43:38 2010 -0600
+
+ Fix bug in bezulate containmentTree.
+
+commit b1e65fac4ecc7602f23553bf41393c2cf036b803
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 17 14:04:11 2010 -0600
+
+ Optimize parametric surface generation.
+
+commit 9c0d3c750499848367823e9959e8f5e83d2fad51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 17 13:39:00 2010 -0600
+
+ Remove --no-var-tracking for major g++ versions < 4.
+
+commit 5db587a903d7c2b08079fda22c7d514b07e0e04e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 16 18:11:49 2010 -0600
+
+ Fix perspective animations; update example.
+
+commit 9521ce051a606c89cf7333bd476a70cea055e8df
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 16 17:08:10 2010 -0600
+
+ Removed TODOs in venv that don't need doing.
+
+commit 5400903a52273381c371f443d4f24071d95104fd
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 16 17:03:56 2010 -0600
+
+ Removed value allocation in venv.
+
+commit d59254fdc8a40d9483ee81fbf2378ba9e9367230
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 16 16:39:03 2010 -0600
+
+ Removed stack of hash tables from venv.
+
+commit 7ed665aac3d52908d22eadae8e81a7854282e93f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 16 16:25:59 2010 -0600
+
+ Added test based on previous bug.
+
+commit 375d5cbeb14fdc63180a2aff83730d5510cf58d6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 16 16:23:05 2010 -0600
+
+ Eliminated string copying in knot.cc.
+
+commit 5a994f89782b6b9b1d07b8949c773ddb5f35b362
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 16 16:21:11 2010 -0600
+
+ Fixed bug in equalityExp.
+
+commit d34affd98f7c402b3a6700390ac6df7eb37d7aa3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 16 01:48:07 2010 -0600
+
+ Add settings.framedelay for working around OpenGL rendering buffer overflows.
+
+commit cae878ae959de8dadcf88e591ceeadb91be24a4e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 15 11:37:52 2010 -0600
+
+ Added a (crucial) semi-colon.
+
+commit 2a0a9b985da818f5fc4703d42210e623371a2295
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 15 08:59:21 2010 -0600
+
+ Simplify code.
+
+commit 2a0b163cc572b5e51f86c8b5772d2e5f331e718c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 15 08:56:55 2010 -0600
+
+ Add example.
+
+commit a785cd197d6659dfb8b753d740c75655d25b98f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 14 18:16:05 2010 -0600
+
+ Fix segmentation fault.
+
+commit 20c67a102647d98789e225d701009d22457d2795
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jun 14 17:10:17 2010 -0600
+
+ Avoid allocating in venv::key.
+
+commit 40c16a659eeae1ea6ce8e5dd43275813b6f43396
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jun 14 17:00:42 2010 -0600
+
+ More optimizations.
+
+commit 63fd9dd9abe669707d6f3b4df33bd30631d60ed9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 14 03:43:38 2010 -0600
+
+ Increment version to 1.99svn.
+
+commit 4a92fc6fb380f5d1d45d2f00d588dd716dafc8b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 14 02:39:57 2010 -0600
+
+ On C99-compliant machines with 64 bit integers, use compact items for
+ the virtual machine, relying on Asymptote's internal type checking (compile
+ with -DCOMPACT=0 to re-enable the type_info data field). This change required
+ restricting T[] array(int n, T value, int depth=intMax) to 0, 1, or 2
+ dimensional arrays.
+
+commit 2d0f355e605d2fb39b0d335c6839a8bc44b1d3e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 14 00:43:24 2010 -0600
+
+ Fix definition of undefined.
+
+commit dfabcf0c75c88425b46aa49f9288aab2e56dc964
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 13 16:47:27 2010 -0600
+
+ Rename tube to pipe.
+
+commit fe9e1ce6dcc9d8b8b867ff4f26dfcccdc8f011e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 13 16:11:19 2010 -0600
+
+ Work around bug in gs 8.71: discard noncyclic stokepaths.
+
+commit f4ab39b112ff2a8556cb4902b7ec850ed6e09c1c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jun 13 10:56:15 2010 -0600
+
+ Half-exact function matching.
+
+commit 1903265f72dbc64945a3521546294a3f8a39d2f6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jun 13 10:55:44 2010 -0600
+
+ Handle function equality specially.
+
+commit a5687d5012cebcbd136e380b4925b5073e69e763
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 13 10:03:39 2010 -0600
+
+ Improve example.
+
+commit 6dc39e598c7d266e2d71299f9dd178c35a5e6649
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 13 09:24:04 2010 -0600
+
+ Make heap_chunk_in_mb a multiple of 256MB.
+
+commit b0cc9e91e09476eb9cf4674afbabfe1ab6884122
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 12 12:14:19 2010 -0600
+
+ Revert 1.97-6 to 1.97-8.
+
+commit d7a18fb86278bd7e41893d4e674d97fdc4a497ba
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jun 12 12:06:29 2010 -0600
+
+ Overloading resolution optimizations.
+
+commit 5495d822f34c74f1cee29d2c602ba2b66a293203
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 12 01:24:50 2010 -0600
+
+ Improve example.
+
+commit 0c380fabf2ab302d854901b1e35a1008c79af990
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 12 01:15:54 2010 -0600
+
+ Align labels with rotational instead of shiftless part of transform.
+
+commit 270a7d8f272447c2b129f5d6300acaeac321abb4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 12 01:14:29 2010 -0600
+
+ Update example.
+
+commit d15029ac56688e735505745e832b5383f587aed7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 23:47:28 2010 -0600
+
+ Fix example.
+
+commit 42e8e417479615febe47aab2ad38085448fee146
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 23:46:51 2010 -0600
+
+ Increment version to 1.98svn.
+
+commit 8c440807b7dd480e211a9da99f24a36ed46a8707
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 22:19:24 2010 -0600
+
+ Replace M_PI by pi for portability.
+
+commit e5a8bbd84e1e16565db23cfedaffe4ed17fe71db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 21:47:41 2010 -0600
+
+ Fix warning message.
+
+commit 86a090c9e17b835a62e2b420360e4eb5dd9cbe0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 21:27:14 2010 -0600
+
+ Fix typo.
+
+commit 4ef4f7fa338d00c22670cfb64ac19c652f432061
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 17:26:38 2010 -0600
+
+ Remove tr1 includes.
+
+ Improve local gc detection.
+
+commit 24edeea48989b6754e960c1d5603cee5036135d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 14:59:59 2010 -0600
+
+ Rename log2 to Log2.
+
+commit 47239d2d7bf2ff0a06b40eebbde17bd5e875cb96
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 14:54:47 2010 -0600
+
+ Update examples to use merge=true for surfaces.
+
+commit 2a13ae2d20c397ebabee66007bd6078dda726116
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 14:53:22 2010 -0600
+
+ Remove unused preprocessor conditionals.
+
+commit e7d1f1b41b6836782737ddac6243ff85da692135
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 11:51:54 2010 -0600
+
+ Fix more memory leaks.
+
+commit 1688b329403a4b0feafb6d2668eefabe51437527
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 02:15:51 2010 -0600
+
+ Fix more memory leaks.
+
+commit b2c5a64ec4a70e12f164b4506f352ac1d561dfa2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 11 01:48:05 2010 -0600
+
+ Fix PRC memory leak.
+
+commit 92959476779f23223923e1f40bee2b094049a288
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 10 17:09:05 2010 -0600
+
+ Remove tr1 (gcc-4.3) dependence, courtesy of Michail.
+
+commit 4d9baf01e9f28dcd183bc5b65e4c8faf318d69e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 10 10:24:59 2010 -0600
+
+ Add option (default true) to fill subdivision cracks in unlighted labels.
+
+ Update examples.
+
+commit 5841cbfcbd7a8322b6f3fe7f135341613911d562
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 10 09:28:59 2010 -0600
+
+ Add patch to fix MSWindows memory limit.
+
+commit 28a24879a57cdb9dc45c05e8cb71a7eb26412d5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 10 09:24:16 2010 -0600
+
+ Add missing include.
+
+commit f63c3894ad06e7ac3b2b3a9f43683c43258980ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 9 23:08:24 2010 -0600
+
+ Fix typename of symbol.
+
+commit 5e4b712e6f785868bc262e723dabd7c2cfdbc300
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 9 22:00:22 2010 -0600
+
+ Add billboard support for Bezier curves.
+
+ Fix OpenGL zoom flicker.
+
+commit c7c24cfe02221ff9794c510128cfab6e314bef9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 9 21:01:46 2010 -0600
+
+ Update location of heap_chunk_in_mb in Windows registry.
+
+commit 833dbe2779e4f348e04bb3b7f0af00216fcdb618
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 9 16:25:20 2010 -0600
+
+ Use a portable integer log2 function.
+
+commit b024be7f16ebe43bf7d167c3b89180534801b6be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 9 16:22:08 2010 -0600
+
+ Work around missing readline include.
+
+commit 9342ef26ffac0aa70ee49a9f894a36fd95b01c81
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 9 11:39:07 2010 -0600
+
+ Don't print non-printable characters.
+
+commit 79408482ecc8ca3186596ff40901b10c77699518
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 9 11:02:20 2010 -0600
+
+ Fix offscreen detection (broken in 1.86-1).
+
+commit 231eefe4d099f831716ca28c0c44246279fc8310
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 9 08:57:03 2010 -0600
+
+ Fix __GNU_PREREQ.
+
+commit 44a0ca929e6b4a198a9e56df226245bc94eb9e64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 8 21:38:12 2010 -0600
+
+ Require tr1/unordered_map on systems without __GNUC_PREREQ.
+
+commit 80b5cc128a5b6396d494eec5e80750040f537c8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 8 21:26:55 2010 -0600
+
+ Support older g++ compilers.
+
+commit 417b376f2a42fa04fd92e26e488f0925f1b17539
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 8 14:50:38 2010 -0600
+
+ Avoid g++ informational message and speed up compilation.
+
+commit d5521a7fe9f3c0493a3e5466fc43debe89dbe878
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 8 11:39:49 2010 -0600
+
+ Replaced symbol table with custom hash table.
+
+commit 6ecbd76f3655d8bf238a97ada0f8d33806e51ffe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 7 11:29:30 2010 -0600
+
+ Emphasize that version 9.0 of Adobe Reader is now required.
+
+commit ed089dab2f0fc162aa2dc260d5146e435e5d746f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 7 10:05:16 2010 -0600
+
+ Update grouping.
+
+commit 64689d70232b0de6b06b3b454b4bc0e27782864d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 7 07:55:14 2010 -0600
+
+ Acknowledge contributions of Michail Vidiassov (coauthor with Orest Shardt of
+ current PRC driver).
+
+commit b1d3c5ddb34cafadf4ed591c67708659262cb640
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 6 09:58:38 2010 -0600
+
+ Increment version to 1.97svn.
+
+commit 6f7690585672ce25a358d0e6fc73b254a0a5adf4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 6 08:19:42 2010 -0600
+
+ Remove M_PI.
+
+commit 5f8a121a42bc7e96b339766432f606d6d57c4e74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 6 07:40:50 2010 -0600
+
+ Update viewpoint, views, and examples.
+
+commit c04d65fe48b193db87d533f070b0a886a82e751b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 5 19:23:09 2010 -0600
+
+ Increment version to 1.96svn.
+
+commit 1cf0d1c166c74d02dc7b8245903e61cfd6ecb602
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 5 17:20:23 2010 -0600
+
+ Define M_PI.
+
+commit ca5899b50fa2590deb9310b29a57f7d76e0ac826
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 5 11:20:07 2010 -0600
+
+ Reformat.
+
+commit b5bc276002512428f88dc9e4c553fa74d1400086
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 5 10:25:26 2010 -0600
+
+ Improve interace to render options.
+
+commit e339b59145fec3386fa438d069de8a182d409268
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 5 02:12:43 2010 -0600
+
+ Remove tubesectors; simplify tube construction.
+
+commit 3e7be8212399aa9ec34f477b581a41aa41317d51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 5 01:46:06 2010 -0600
+
+ Implement render structure containing PRC rendering parameters.
+
+ Use begingroup3/endgroup3 consistently for both 3D pictures and frames,
+ respective default rendering parameters.
+
+ Add render(merge=true) to pipeintersection.asy to improve rendering speed.
+
+ Improve PRC line capping. Use spheres for curved joints and roundcap.
+ Use a higher resolution disk for squarecap/extendcap.
+
+commit fe3832771be157f636227aa7cca3dd9698e2c731
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 4 21:41:47 2010 -0600
+
+ Fix zoom.
+
+commit af08815dc768f9f6113ce74a2f9244ab39653dad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 4 16:46:49 2010 -0600
+
+ Expose granularity.
+
+commit 9b780a4258761a42ac41f30ca9c0a8f845451fac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 4 14:53:45 2010 -0600
+
+ Remove linesectors.
+
+commit 174c0c580925b67bd45d96de7ee1ec7281e342b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 4 14:52:15 2010 -0600
+
+ Implement Circular spline type corresponding to Bezier unitcircle approximation.
+
+ Rename linesectors to tubesectors and change default value to 4.
+
+commit fa351463be16edea7e3916acd150f46fc51a59fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 4 12:58:16 2010 -0600
+
+ Optimize tube spline routines.
+
+commit 3b874749207089960c0cc0652cf8278179512b89
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 4 01:35:59 2010 -0600
+
+ Improve group naming.
+
+commit f89f165458ba21b2dbc2e1f8b4f4c0ad144527b8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 2 19:51:22 2010 -0600
+
+ Added pre-translation of runtime symbols.
+
+commit f5f9bf24b41d0697f8eb8ab12129c3d7413d3069
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 2 15:53:23 2010 -0600
+
+ Use pre-translated operator symbols in runtime files.
+
+commit aed4b49a60475e53c500e3821e4914c2fdc32d34
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 2 15:38:52 2010 -0600
+
+ Use pre-translated operator symbols in builtin.cc.
+
+commit e0d130c1b655d159d93d20a4091916138e9eff38
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 2 15:35:23 2010 -0600
+
+ Added var documentation.
+
+commit f9807d1b253f4070e5324a59d6d4346cf3dcc163
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 2 15:25:28 2010 -0600
+
+ Pre-translate operator symbols.
+
+commit ba1d886ba1e9d6f1b1a238206daa8c9002d46670
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 2 15:23:49 2010 -0600
+
+ Update errors for ambiguous cast to error.
+
+commit bd19d89d0d5cee238c40fc015c131d1c20132d6b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 2 15:09:17 2010 -0600
+
+ Added a (disabled) experimental function resolution optimization.
+
+commit 83ed08e46e7e8332118817cea888160800048d27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 2 13:48:16 2010 -0600
+
+ Improve 3D line capping.
+
+ Improve tube center calculation.
+
+ Remove PRCtube setting.
+
+commit 3a9f74da824e24b89d520ef3aa47862042918e50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 2 09:59:36 2010 -0600
+
+ Use half sphere for PRC tube connectors.
+
+ Revert to NURBSsphere again now that the rendering problems have been fixed
+ (by using a nonzero granularity).
+
+commit ea0c762eb51e9578a61a080acb70e1d31051f35e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 2 02:51:24 2010 -0600
+
+ Complete last revision.
+
+commit c60bda8157d04f934526cdd1a37e1bda190f8f4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 2 02:45:37 2010 -0600
+
+ Expose PRCoptions via begingroup.
+
+commit 56d84a0d913c6fffeb4b612cae31329f366556d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 2 01:39:39 2010 -0600
+
+ Reduce PDF loading time without sacrificing quality by setting granularity=1.0.
+
+commit acf90f95b1e682b25590267be59e45930e088c9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 2 01:38:18 2010 -0600
+
+ Make PRCsphere the default until numerical transform issues with NURBSsphere
+ are resolved.
+
+ Add half=false option to PRCsphere.
+
+ Implement PRCcylinder, PRCdisk, and PRCtube primitives.
+
+ Use PRC primitives for drawing thick lines. PRC tubes (which may contain
+ cracks) are drawn for curved lines only if PRCtube=true (the default).
+
+commit beed6b05dde975d183d865246304c0174086d800
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 1 14:12:34 2010 -0600
+
+ Update errors.
+
+commit 6ce405bc4fe399588749de0a04dd5a0058edf8b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 1 14:04:40 2010 -0600
+
+ Simplify code.
+
+commit a0807779f50bf6494a571bf3a70247dd9dfdff11
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 1 11:39:32 2010 -0600
+
+ Added more overloading resolution tests.
+
+commit 5398bf7d0f767160dbea5b4143407b87779d1930
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 1 11:30:59 2010 -0600
+
+ Added experimental inferred variable types.
+
+commit da50aa0fac52e0ece080daf0eb02375c98c6f9aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 1 01:59:35 2010 -0600
+
+ Fix grouping.
+
+ Make part names and compression group properties.
+
+commit 010aa8a113585cd5ae15d09c6c1c1e4e04fa957a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 31 14:28:30 2010 -0600
+
+ Remove context list.
+
+commit 4b98073813a448c0d45fbdd109e2ee1bf40232e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 30 21:07:52 2010 -0600
+
+ Disable 384MB Cygwin memory limit.
+
+commit fc372ba261454e2d54764c1b1d2ff043e1f25c78
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 30 02:17:21 2010 -0600
+
+ Implement optimized PRCsphere and NURBsphere.
+
+commit e11d0d6f70a0240c9a5e547f977a4a76097ae4dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 29 21:39:38 2010 -0600
+
+ Replace SIGQUIT by SIGTERM.
+
+commit 0af63e2ebc43d50e1ce6cef40639760ecc0b6dc0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 22 22:24:32 2010 -0600
+
+ Fix invalid memory access.
+
+commit 6ed0fc18676adf59d62d4563abd46889780a4efc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 19 23:48:25 2010 -0600
+
+ Fix example.
+
+commit 395fdda98745710d3e1c89ebeefd1a61af3fe7b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 19 22:00:44 2010 -0600
+
+ Remove granularity setting.
+
+commit b7cfa372079fef97b2ed446a67ea2f763d403f5a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 19 13:23:56 2010 -0600
+
+ Prune duplicate 3D dots.
+
+ Implement new functions unique and lexorder in math.asy.
+
+commit 261b190f196623d8387fe1e660c66c6164bd7ed4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 18 12:35:45 2010 -0600
+
+ Add embedder for PRC test.
+
+commit cd66b4f1998cc32d3712d984573d50733f31b4a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 18 12:30:07 2010 -0600
+
+ Fix prc dependency.
+
+commit 5eb109a6f8b2dd8b7c0c4c2a71e8f13c1f8471f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 18 10:48:08 2010 -0600
+
+ Remove debugging comments.
+
+commit c2a82f5e315ac93deb7365978f99207f24efd9fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 17 22:53:48 2010 -0600
+
+ Fix compression limit.
+
+commit 151e2af3eef2d3843d9b4f4899594651649859bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 17 10:47:00 2010 -0600
+
+ Update URLs.
+
+commit defd88d9592315ec2e74e914eb6ab8607229e391
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 17 08:55:40 2010 -0600
+
+ Use Adobe compression factor.
+
+commit bf629a87ab69dbec909a922da3b3dd5f6b3f4031
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 17 00:46:27 2010 -0600
+
+ Distinguish again between the 3D begingroup3/endgroup3 and the 2D
+ begingroup/endgroup pairs.
+
+commit ac17585ecdf1084b4e5b2c7035974ee4f10220a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 16 23:52:15 2010 -0600
+
+ Update hyperref comment.
+
+commit 99db989fb8c21a62fdbbb3b24554e52917c48171
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 16 21:33:37 2010 -0600
+
+ Add example of using rendermargin to avoid rendering residue in included 3D
+ images.
+
+commit 20cf63692fc6346c3e8d19e0edf111de5313d0d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 16 19:11:42 2010 -0600
+
+ Adjust default tubegranularity; remove spurious line.
+
+commit a00cefae26ec2a759bc6cb5d0ff962af596f0f19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 16 17:52:09 2010 -0600
+
+ Use a reduced tubegranularity for constructing tubes.
+
+commit 749d3510510b36436c90a80e2f82ccf059d87e11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 16 17:24:07 2010 -0600
+
+ Fix floating point exception in PRC compression routines.
+
+commit 543074437b2d40a122daf6164203058d2d9edfe7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 16 02:50:12 2010 -0600
+
+ Add some of Michail's PRC enhancements, including lossy compression of
+ surfaces.
+
+commit 2bcd6522db306dd86fafb52b1181c1d33cf742fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 13 21:03:06 2010 -0600
+
+ Fix portability issue.
+
+commit f0e1ebfba330a539c89ea21cb7931186a7a2dc7f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 13 12:46:21 2010 -0600
+
+ Remove space.
+
+commit 223f3af025bd3bc45521f2b3d47eb795a08e5e43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 12 23:17:46 2010 -0600
+
+ Only quote filenames where necessary (e.g. to support obsolete versions of asymptote.sty).
+
+commit d25b6c80eb6ac903729b1c5ffd3dbb0966a7b6c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 12 11:31:23 2010 -0600
+
+ Always use 256 bytes for random state array.
+
+commit 3bf7af6acb0a932b2efc94265955d1703a9966d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 8 23:17:36 2010 -0600
+
+ Remove unused file.
+
+commit 4e69ea886625688e8f31496ea50feed6e4520d92
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 7 14:32:28 2010 -0600
+
+ Use fftwpp namespace.
+
+commit 027f83fd2f98c77ba2a7a3e4aff1625b179a20cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 7 00:43:32 2010 -0600
+
+ Update fftw++.h to v1.06.
+
+commit 5824e9ad1be409898af11ae9d79668863a89ee33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 4 16:53:28 2010 -0600
+
+ Increment version to 1.95svn.
+
+commit 86c3c8b10e750576f6faf8bd1e395a73c9656242
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 4 14:47:23 2010 -0600
+
+ Predefine a default docdir for MSWindows.
+
+commit 67f05e202eed106e489f487b2e13dc6f3ce920d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 4 12:54:30 2010 -0600
+
+ Update CYGWIN xdr patch.
+
+commit 1b61f7e2d4c5a9938a805eaa9c0de028b284d885
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 4 11:18:57 2010 -0600
+
+ Document fit3() and remove restriction on projection.center.
+
+commit 4b8ddfdb2a838c2f86dbbc1602e29bd100c1af5a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 4 01:33:17 2010 -0600
+
+ Add missing CYGWIN declarations.
+
+commit af4e3100d2fe307cfea6eb656c0245b1f2bd17dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 3 22:52:36 2010 -0600
+
+ Document pair dir(path, path).
+
+commit 0821c51418077505a97e764e0785a08f10465ba6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 3 22:43:55 2010 -0600
+
+ Update documentation of math module.
+
+commit 0557500331a5d6077290eb8f6f431a6fdd15aa2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 3 22:08:46 2010 -0600
+
+ Use outprefix().
+
+commit 3509d303e536735d2ff415f821786dc7f2ca1960
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 3 21:40:17 2010 -0600
+
+ Implement matrix negation for arithmetic types.
+
+commit acf80ae7b563a67c1de8215b024a62439c32114f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 3 14:45:00 2010 -0600
+
+ Move pair[][] operator * (pair[][] a, pair[][] b) to C++.
+
+commit caaf88c123017e63a52fe4be8c4ddcb0df9d3639
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 3 01:56:45 2010 -0600
+
+ Add make cleaner target that runs make clean in the doc directory and make
+ distclean everywhere else.
+
+ Change make clean in doc directory so that it no longer removes asymptote.pdf
+ and CAD.pdf.
+
+commit 71d827d19419e8cee54d084dec6da95e54671503
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 3 01:52:36 2010 -0600
+
+ Add picture.fit3(projection P=currentprojection) and
+ add(picture dest=currentpicture, frame src, triple position) routines.
+
+commit a96c644ba6a820bc19018883848db5ce6f97fe90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 2 23:05:10 2010 -0600
+
+ Avoid redundant mismatched version warnings.
+
+commit cc6fd22c81285fc7af9570658e384f2e204b0a2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 2 22:52:40 2010 -0600
+
+ Fix guide bug intoduced in 1.55-2.
+
+commit de1591fe4ee05499e0d6b09b74ed5469525cf282
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 2 17:22:14 2010 -0600
+
+ Use a larger table for generating random numbers.
+
+commit 0e1811c2d95aac1bad23bd77d54ced726dff6c48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 2 01:03:23 2010 -0600
+
+ Use accurate roots of unity in FFT shift.
+
+commit 6896be2016d9367d0321b9fdf3ef4eb7ef3ada6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 1 10:14:10 2010 -0600
+
+ Fix fftNormalize.
+
+commit d7931ac1f3385ee4cd6fc713b6745cafb8d47a5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 1 08:21:08 2010 -0600
+
+ Update documentation of addViews.
+
+commit 58dd0e82177b811876ab6266c55407fc54d7d883
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 29 02:30:10 2010 -0600
+
+ Improve fftw interface.
+
+commit d846b15bc5d8467814fb258ae93b139759baceb0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 27 22:19:50 2010 -0600
+
+ Make local variables private.
+
+commit 7a1d259bd798091d09ff96e0f9aa1097482c3ad4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 26 11:31:24 2010 -0600
+
+ Make pair dir(path,path) return a unit vector.
+
+commit dbff2e25683dcfdf2edf0c69d5f48870a147c6de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 26 11:28:15 2010 -0600
+
+ Fix return type of dot(pair,pair).
+
+commit 9556b5b0c17683511d021f766f82ac5e2f848608
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 25 22:05:00 2010 -0600
+
+ Implement pair dot(pair[] a, pair[] b).
+
+commit 1482e3940a184157b05308a4f6f8b160e1544c5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 20 10:02:39 2010 -0600
+
+ Work around MSWindows registry problems.
+
+commit fcf1b66c5d7a33de4fd8f7648f4572b21208acd0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 20 09:21:34 2010 -0600
+
+ Work around empty docdir.
+
+commit 5b874eeb8be118f5264bff3e36bdd040212ddba6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 18 10:21:14 2010 -0600
+
+ Move shift variable to Execute.
+
+commit 6013f494ee9bd39606dc91e2a573e7548787b160
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 18 08:43:11 2010 -0600
+
+ Fix SimpleHead.
+
+commit 0d0240ee0398f3e1b267ce2610cc1820c5078bf0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 17 23:20:54 2010 -0600
+
+ Move basic matrix operators from math.asy to C++ code and implement int
+ and pair versions.
+
+ Add vector and matrix conjugate operations.
+
+commit 6f5c4f6eb7f95524478c4698f77f7d293d357f3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 17 17:39:05 2010 -0600
+
+ Add casts from int[][] to real[][], int[][] to pair[][], and real[][] to
+ pair[][].
+
+ Implement int[][] diagonal(int[]) and pair[][] diagonal(pair[]).
+
+commit dec5637db7b47695cc7861a6fa4e44c0facfe3d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 17 16:37:44 2010 -0600
+
+ Implement a RadialShadeDraw filltype.
+
+commit eb9a39511d09cb90459a73edc3e9eec4538b5d39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 17 09:33:56 2010 -0600
+
+ Increment version to 1.94svn.
+
+commit 1bab031382a4efe3d4ca689b66ac99fb81ce5ff0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 20:13:15 2010 -0600
+
+ Expose outname() to asy.
+
+ Revert revision 1.93-16 for strings containing spaces.
+
+ Fix tex(picture).
+
+ Add deactivatequote and activatequote functions for Babel users.
+
+commit 1a5d2311e66293c4050005c31c398bc739d561b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 20:00:30 2010 -0600
+
+ Redraw screen after export (for MSWindows).
+
+commit e63686d696ac00453dc79e14bf8979466d631b3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 14:00:51 2010 -0600
+
+ Move backslash conversion into asy.
+
+commit f03e3a5a7150ba3fcdff5a6b4c18e5c49ff7d24a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 13:54:22 2010 -0600
+
+ Fix GUI export under MSWindows.
+
+commit 9ba6ab15f1b7722d6ab19c533b98a97485605601
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 11:58:48 2010 -0600
+
+ Improve camera position.
+
+commit 1018a5d12afdc254a364c052fb772d0fce772fa1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 11:47:15 2010 -0600
+
+ Set size.
+
+commit 1694cc39454b2f92a3fa72ac24384cec6f9787d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 11:06:15 2010 -0600
+
+ Fix poster size.
+
+commit c178c191b01142455027304b0c3590a1b233acf3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 10:46:48 2010 -0600
+
+ Revert unintended removal of inline option.
+
+commit b6952633aefb155e0fc3b1853b3d0c16c627f9c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 09:42:26 2010 -0600
+
+ Require user to double quote graphics file names containing spaces.
+
+commit bc3ae56dab8e42c56641860d38be78a44217ad91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 09:31:29 2010 -0600
+
+ Ensure double quote character is inactive.
+
+commit 916180f64f9767fff8ebb6face6d45352952cfe1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 08:49:27 2010 -0600
+
+ Clean up files even after errors.
+
+commit 979c9a3c2ce462c9ad2f3cf069b711fca556b99a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 01:00:40 2010 -0600
+
+ Fix latticeshading with -svgemulation.
+
+commit e7187eccf529ff914af7ead76e4fb6d8b3d85b23
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 00:37:58 2010 -0600
+
+ Fix SVG emulation.
+
+commit 0f5a9dd4bf43c704d585359260d11668507e0e99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 16 00:17:49 2010 -0600
+
+ Fix initial SVG pen.
+
+commit a58312d7d39b9ff692f76a6273ae56dcaae7426c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 15 23:44:32 2010 -0600
+
+ Fix GUI export; add SVG export.
+
+commit d5749daff98e436018e252807041934aceded359
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 15 23:32:29 2010 -0600
+
+ Revert outname construction.
+
+commit 0c068d371412591c5beefc6db8ff830cd491a509
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 15 15:42:29 2010 -0600
+
+ Allow spaces in output directory name.
+
+ All output files are written to the directory part of settings.outname;
+ if this is empty, the current directory is used.
+
+ Allow cd to other directories, preserving the output directory.
+
+commit 2af5f453b921965d21f4574bfd6594f910fafa53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 15 00:58:42 2010 -0600
+
+ Remove obsolete bug workaround.
+
+commit c9f8e9b47015b9ab998125e0c51a57789b82d18a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 14 16:45:50 2010 -0600
+
+ Remove misleading deep qualifier.
+
+commit 4a9779a086e1611995265cf8de911ae15b32db95
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 14 14:28:06 2010 -0600
+
+ Add parallelogram block to flowchart module.
+
+commit 5737d8b20f5c45b06171b9da96ef443340416ca5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 14 12:12:07 2010 -0600
+
+ Check for LIBGL on MacOSX.
+
+commit c8f5322cc6aecef2401add3effa45d97a22fdff4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 13 10:20:24 2010 -0600
+
+ Fix preprocessor conditional.
+
+commit 418f6ac0683264c1a09d12998973c1f30fcb2a5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 13 01:16:51 2010 -0600
+
+ Fix latticeshade stroke bounds.
+
+commit 42c40bca696b23287533ba39bc68ad7d43335188
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 12 22:22:29 2010 -0600
+
+ Support old versions of gcc again.
+
+commit d27450e2e7863586c7735ec233cc226804e457b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 12 01:55:34 2010 -0600
+
+ Increment version to 1.93svn.
+
+commit f8f609b8bdfcbde84de936d800cad37c063b8fb3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 11 09:41:33 2010 -0600
+
+ Call init_readline only once.
+
+ Remove obsolete CYGWIN readline initialization code.
+
+commit d035c7bb2e1060d11544e0d2e13143f5eed7793e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 11 09:34:01 2010 -0600
+
+ Fix typo.
+
+commit df7fb6ee773ecdd7a8b4a6b42d36944175638225
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 11 02:26:26 2010 -0600
+
+ Fix -lGL detection.
+
+commit bd5ac5a5358ddb735d147900bde91359a70db63a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 11 00:51:59 2010 -0600
+
+ More CYGWIN portability changes.
+
+commit 89f0c054f4b48540e7871e8be71ff26002ed3169
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 10 12:43:11 2010 -0600
+
+ Fix CYGWIN portability issues.
+
+commit 232d920b517418d211825e4b44ace7ed1be7e8da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 10 11:12:46 2010 -0600
+
+ Improve tr1 test.
+
+commit c5c85163ff1780a04acfca69983c939b2568656a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 7 21:19:31 2010 -0600
+
+ Add autorotate argument to yaxis.
+
+ Document assert(bool, string).
+
+commit 9810c0fe06212adb96e6596f36bb3acc95432fc3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 7 21:15:42 2010 -0600
+
+ Fix aspect ratio.
+
+commit bd9b2b7bcd7d9ad3664ced34e4914af2bbe7a828
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 7 16:18:14 2010 -0600
+
+ Add projection.normal to represent the normal to the projection plane,
+ which differs from projection.vector() for oblique projections.
+
+commit 386bea2ad1f1297bf779f57021a69ca555a80588
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 7 13:32:07 2010 -0600
+
+ Make oblique projections work with billboard labels.
+
+commit 73dbd37642d26d5df9d7aaa6bc3a9367f3a0116e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 7 11:22:14 2010 -0600
+
+ Fix latticeshading.
+
+commit 503487818fecab50384aae143ac8a5170ddb9465
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 5 17:56:20 2010 -0600
+
+ Fix normal and true Circle calculations.
+
+commit 62d120909d49c8fd2f2fdd5eecfeaf9b0f372235
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 3 17:31:30 2010 -0600
+
+ Remove unwanted template.
+
+commit cf589ff765402ba5c2b320ffd159b01755e5716d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 23 21:05:38 2010 -0600
+
+ Fix typo.
+
+commit 4e6bbf0db6b0bacb3da05bf50a8d4e6a698fdc45
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 23 20:44:50 2010 -0600
+
+ Ignore null 3D paths.
+
+commit 25bd144b7fd648fba7275de6679fbfbb19931d24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 22 23:03:58 2010 -0600
+
+ Fix revision 1.92-28.
+
+commit d853172f1a23d32abc709789d253854cf1356e65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 21 22:35:06 2010 -0600
+
+ Add more predefined tick modifiers.
+
+commit 2c3c2a79a16220ac18d64cc3241b6538ccd6cd5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 21 19:46:07 2010 -0600
+
+ Fix last change.
+
+commit fe4953f2f5c077f5b2b8e49e41d5ed94d8541b36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 21 19:43:27 2010 -0600
+
+ Fix incorrect pt scaling.
+
+commit 01721697c8da4d855c560101bdc31e58be40e9b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 20 23:19:37 2010 -0600
+
+ Make integrate routines return structure including sampled time values.
+
+ Enable dynamic timestepping for solveBVP.
+
+commit 7227e4f9134b4c3343da4f3a8635abc0671c6e19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 19 09:36:21 2010 -0600
+
+ Configure Boehm gc with --enable-large-config by default.
+
+commit e55618a3367b32ae278c43818caa7f9c83814503
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 16 17:40:26 2010 -0600
+
+ Fix url.
+
+commit 282c78e96f3583800368c4b9b793407794084b81
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 7 10:48:36 2010 -0600
+
+ Rename FFTWdelete to deleteAlign.
+
+commit 02c9a6b01ef6f2c66f12c70a3740e09a37fc4d46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 7 10:45:27 2010 -0600
+
+ Rename FFTWComplex to ComplexAlign.
+
+commit f498746961e4b72dd85b3296b71d626689f74449
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 4 13:59:27 2010 -0600
+
+ Fix array index.
+
+commit 3f4262148bfb4be6514dcc80ff1f4c8e3127439e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 1 10:07:51 2010 -0600
+
+ Make CLZ and CTZ portable.
+
+commit 1fad80aed5c6c19cf3ee3aa073992de8bae92729
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 28 22:54:54 2010 -0600
+
+ Implement CLZ and CTZ bit functions.
+
+commit a1ee8663ea8a51dad88d7d5dc4710bd34718226c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 25 16:52:27 2010 -0600
+
+ Ignore negative dxmax.
+
+commit 155b66150ff2b70f0ab8a54a33f1bfe4c3d0a8dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 25 16:50:04 2010 -0600
+
+ Fix simpson for a > b and f decreasing.
+
+commit 455a749a478ea4ab86832a08de2e7465027a2e1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 23 23:14:27 2010 -0600
+
+ Fix compilation on systems without OpenGL.
+
+commit 22c00b08408f19342212cf17e8bc1dd57468010d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 23 19:21:35 2010 -0600
+
+ Use portable definition of M_PI.
+
+commit c8144319f0d38661f859f0da5d5409863fd8f526
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 20 17:20:15 2010 -0600
+
+ Add missing arguments.
+
+commit 045941d441e7f37478a1756b836573a0f1116904
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 19 15:57:19 2010 -0600
+
+ Avoid implicit linking of libGL.
+
+commit 1bba3a3b88b0c73f4c80e92847e9f804e3520075
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 18 15:01:16 2010 -0600
+
+ Fix odd sized shifts in fftw++.h.
+
+commit ef008d597001d57eb0b0c1dc75084123754d9cab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 15 01:02:06 2010 -0600
+
+ Expose Shift functions.
+
+commit dad1fab51e6585e6e805c1784dc0bacdd7451db8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 13 17:09:35 2010 -0600
+
+ Remove ambiguous constructor.
+
+commit df3d6aa4983f560ff92408be0f9fd139af831276
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Feb 10 08:14:26 2010 -0600
+
+ Minor change to comment.
+
+commit 417c566fd0ff23522987844de06c7013173c46b1
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Feb 10 08:13:54 2010 -0600
+
+ Changed alignment of slashes in macro.
+
+commit ff66cb16cd0fec709507fe54110e34444c8ffede
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 16:21:17 2010 -0600
+
+ Fix compilation errors.
+
+commit baf491e809673492c975a2ad56c06e9501b4eb8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 16:13:15 2010 -0600
+
+ Fix part names.
+
+commit 19bfed1a417bc86969786f91a814b4a941625935
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 7 12:34:19 2010 -0600
+
+ Update test code.
+
+commit 21911866dd8da04d3bf8b0b79763c38b9a1dec7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 5 09:39:23 2010 -0600
+
+ Open oPRCFile in binary mode.
+
+commit 4bfb8ab6df3a871600411d79aebabd0c7f7b1f89
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 3 22:03:27 2010 -0600
+
+ Fix formatting.
+
+commit 03bc073aaff1d1c58247156dc5212617cd535aa6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 30 22:04:48 2010 -0600
+
+ Fix typo in documentation of singlereal.
+
+commit ea2f9a3fe502d818d6d6efb17fa6d8923b3429bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 25 21:33:52 2010 -0600
+
+ Make FFTW wisdom file name and effort flag public.
+
+commit c514c3c99dad4eb2e6c07f6888c8dd7de10344cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 25 10:58:39 2010 -0600
+
+ Update documentation of fftw++ header file.
+
+commit 5a0a7c84a20086416aa66766faf394efd32c7b0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 23 12:09:50 2010 -0600
+
+ Fix non-pdf output from PDF tex engines.
+
+commit fc548df7dbe7df930ca1520d57c3e8dd586cb682
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 19 22:12:07 2010 -0600
+
+ Improve diagnostic.
+
+commit 7254feea0ccde20412db7b4d640c941bc866ef46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 19 03:50:50 2010 -0600
+
+ Remove implicit cast in favour of block constructor.
+
+commit 1c0664c196454994b1afa811f84efe1ab1320e9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 12 15:31:13 2010 -0600
+
+ Improve example.
+
+commit 882c2548c71795338e7e14257c6a3e4c7ebd1d32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 11 11:41:52 2010 -0600
+
+ Fix transformed Label alignment.
+
+commit a6deb333bb7da7ab635c1b9bd3b4795d364adf33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 9 23:08:23 2010 -0600
+
+ Fix typo.
+
+commit f6615df2d1e4bfb913f36ab1501495700af940c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 9 23:06:11 2010 -0600
+
+ Fix conflicts.
+
+commit 784b52a16b58d1c154578229b41772206a5634a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 9 15:40:13 2010 -0600
+
+ Avoid uninitialized variable warning.
+
+commit 65adeb47bfb8b1779e73028a01d483a35a6aa8e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 9 15:38:02 2010 -0600
+
+ Upgrade to latest version of fftw++.h.
+
+commit efa08460ee77d46eb51c6f00f61a5820109292e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 9 15:34:31 2010 -0600
+
+ Simplify code.
+
+commit 295b27aa2a890594af18831f1fa4eb0b5aa27181
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 31 07:28:23 2009 -0600
+
+ Increment version to 1.92svn.
+
+commit 6bc9a2023414f230f92959f48c9d4baae6012050
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 30 23:05:07 2009 -0600
+
+ Remove obsolete freeglut patch.
+
+commit 19a0ff86a453d6676f1e945394a8ed2b0387dce4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 30 14:27:38 2009 -0600
+
+ Set default font after \begin{document}.
+
+commit 6209c0b018c4ae8d1c3553c8bce67df8cbb1c3cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 30 13:46:09 2009 -0600
+
+ Support transformations in lattice shading.
+
+commit d2e2ea24fc879cb10f4f9f6e5f9b950391086e77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 30 13:31:21 2009 -0600
+
+ Update links.
+
+commit ad664e609896c95d5cd28f1831ce5e301e356247
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 19 09:18:46 2009 -0600
+
+ Untabify.
+
+commit be464a2252117e5c40bc95c395c2aec1557703f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 19 09:18:03 2009 -0600
+
+ Increase epsilon.
+
+commit 7e1e1a3dc2642c96f9ed814e36a961e6e4411ba3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 12 12:33:40 2009 -0600
+
+ Replace "nonselfintersecting" by more standard term "simple".
+
+commit 44fbd7151a135685d2c894e01107397cd27e92b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 11 18:34:20 2009 -0600
+
+ Use a more robust contour algorithm based on approximating the function as
+ a paraboloid, courtesy of Chris Savage.
+
+commit 6f69480a190ae9f049b94f644ec6a4825082aef0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 11 17:21:04 2009 -0600
+
+ Avoid casting to path[] in write(guide[]).
+
+commit 733f624a1287b8c74c506b3bd59c77368e8219c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 6 00:13:51 2009 -0600
+
+ More example updates.
+
+commit 3bab1b8e5f417e4c10f363415997f520b0281bdf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 5 23:55:34 2009 -0600
+
+ Minor example updates.
+
+commit e74e417ed8f85648dc9ae54edb4b3c1399f49809
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 5 23:35:57 2009 -0600
+
+ Implement operator --(block, block) to simplify flowchart syntax.
+
+commit 2b0109e94a472b70f698b91ffa812ecb9766d285
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 5 13:40:40 2009 -0600
+
+ Add change missed in previous revision.
+
+commit 583bd0f3d3df48a3ae8cb15cb7a9976508548011
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 5 13:39:48 2009 -0600
+
+ Improve precision of minratio and maxratio routines.
+
+commit ce7b617314c9166c582adaf4efed415774e42b73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 2 22:50:16 2009 -0600
+
+ Fix transformed 3D labels under -render=0.
+
+commit f6eb7355fb4a362ab97dcd0e5a370f93440408db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 2 12:14:49 2009 -0600
+
+ Revert last revision.
+
+commit b38ca30bf706db72a78d0fe00c4295885cb115d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 2 12:10:16 2009 -0600
+
+ Retune HookHead2.
+
+commit de56960ac36ea7e5ce2b39e38a569ae007d4b91a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 2 12:00:26 2009 -0600
+
+ Fix 3D planar arrowhead gap.
+
+commit d266b2c68c4b14631bb54ac1b9f24195fb9d32a1
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Tue Dec 1 11:13:58 2009 -0600
+
+ Fix ellispe arc defined by abscesses when angle of ellispe is not zero.
+
+commit e17f928c56c2a92f4da55cbc961b245fc96ebe47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 1 01:50:44 2009 -0600
+
+ Remove duplicate arrow angle scale factor.
+
+commit 21ab8e75dae93f012bec82b02b382aced39ad538
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 1 01:49:20 2009 -0600
+
+ Fix offset in transformed 3D labels with render=0.
+
+commit f26e5a96e68d1b598c6b06753f6733c30f22b19a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 29 22:21:35 2009 -0600
+
+ Revert 1.91-23.
+
+commit f1b58b43b3c051303d426f4e66f52361df3bcb3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 29 13:17:32 2009 -0600
+
+ Fix pen size contributions to box and ellipse.
+
+commit ad867668187d1da48dee070b4445a057e7fdbedc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 29 12:59:29 2009 -0600
+
+ Update inlinetex support for xelatex.
+
+ Load hyperref before patches/movie15_dvipdfmx.sty (renamed to movie.sty)
+ under xelatex.
+
+commit bba661d24028af3e17488c3bc003dd3e854cd06e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 28 13:10:12 2009 -0600
+
+commit 08a2b148c05d41f903ac401f83f6689b38c9525e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 27 17:50:55 2009 -0600
+
+ Move convert options before geometry.
+
+commit b771b0d77e280d8a16cdb0e2c590cc30cae718c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 27 12:10:41 2009 -0600
+
+ Remove -alpha Off default convert option in favour of
+ convertOptions="-alpha Off".
+
+commit a751e0f8ba88956ca209ec9ca2f7bf540c17b020
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 27 11:45:11 2009 -0600
+
+ Use pngalpha driver only if antialias=2.
+
+ Fix size of pngalpha images.
+
+commit e6a98e36c1a747f04ae2e442c53c70f14c7c31be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 26 18:32:36 2009 -0600
+
+ Add 3D examples.
+
+commit cb81e0a6d5ca377fa5e0f176a6efbcf12a7a1180
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 26 10:09:58 2009 -0600
+
+ Use hypersetup to avoid hyperref option clashes.
+
+commit 4958bc1628d5ab089b38a6fa804e396795bc37c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 26 09:31:15 2009 -0600
+
+ Reduce memory usage of example.
+
+commit a6105bc960e8ff69fb312cfc8ec2dd042c0faf0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 26 09:27:20 2009 -0600
+
+ Fix braces.
+
+commit 3d67fe1cf5ca34f521cbc2b7a65992455fe35522
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 26 01:55:46 2009 -0600
+
+ Improve 3D logo.
+
+commit 2eaa852c0148cc9d1234930855a1e76b4a383b71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 25 14:21:37 2009 -0600
+
+ Change colorslinks to pdfborder={0 0 0} in hyperrefOptions.
+
+commit ce77532c7d40b9e354bee36d115d407a19de900b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 25 10:17:37 2009 -0600
+
+ Reduce conflicts by renaming the Bessel functions J and Y to Jn and Yn.
+
+commit adbbdbdf423482b977aabe318b471464fdb149ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 25 09:56:22 2009 -0600
+
+ Add colorlinks to settings.hyperrefOptions.
+
+commit 261348d1ccc2094841cca8e1873f9d09173c9f66
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Nov 18 22:38:56 2009 -0600
+
+ Added % for the last answer on the interactive prompt.
+
+commit 2484f7016690e242356dfa81b1178873825981dc
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Nov 18 05:31:57 2009 -0600
+
+ Fix horizontal & vertical lines
+
+commit 9f3a29d8323c8cc50ed8bed536d610154b8ef5a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 12:46:36 2009 -0600
+
+ Rename example.
+
+commit 9f2225f1aa08a3a153077907d7eddad0d4b31a0e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 12:45:18 2009 -0600
+
+ Add example of a polar graph produced from discrete data.
+
+commit 5c2fe7c11396ec23328a9bb43f9ad5d360db97f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 12:38:24 2009 -0600
+
+ Implement operator ..(tensionSpecifier t) and join3(tensionSpecifier t).
+
+commit 9b5fa939349b94a7cde0e7eb84f1a274fdcf4360
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 12:12:18 2009 -0600
+
+ Implement polargraph(picture pic=currentpicture, real[] r, real[] theta,
+ interpolate join=operator--).
+
+commit c8a62c7395f1a48f5c5b6b68c53c47b60beeeaa8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 17 11:08:04 2009 -0600
+
+ Add Sierpinksi examples, courtesy of the cvgmt group.
+
+commit d4c786480b4d9f93b5fec598d164ca2aabc51e34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 14 00:59:23 2009 -0600
+
+ Improve example.
+
+commit dd619b1378bfbb217d50007794a6591c811f6ebf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 14 00:53:02 2009 -0600
+
+ Add example.
+
+commit f39aa1796dd3acd99d7ffb873d80d4b310c2d8ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 14 00:19:52 2009 -0600
+
+ Add check that parametric array for spline interpolation is increasing.
+
+commit c7ee92332c676d56eb5b1a5197c218fd5bbc42b6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Nov 12 22:54:00 2009 -0600
+
+ Removed unused lookInTopScope methods.
+
+commit 3d58516911511dfab639a321afd7e5e26bb85dd9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 9 14:12:20 2009 -0600
+
+ Increment version to 1.91svn.
+
+commit 77e42713c6bbe652511319b8b373bacafacfa6d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 9 11:02:46 2009 -0600
+
+ Document SVG output.
+
+commit a00bc7781bee6c2f39e4d9096a571ea3bc8f0b44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 9 09:16:15 2009 -0600
+
+ Remove preprocessor symbol in preparation for upcoming dvisvgm-0.8.7 release.
+
+commit fdfd0d00a8e791f7b4d9cd765cb58cb8769f54fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 9 08:57:29 2009 -0600
+
+ Fix SVG axial, radial, and emulated tensor-patch shading.
+
+commit 8e628ad269ae1d0f921e1ebd11cefde0d61aef8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 9 02:36:31 2009 -0600
+
+ Increment version to 1.90svn.
+
+commit 87d2f40f639d69a126e5ea9385ae582ef143f02e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 9 01:26:17 2009 -0600
+
+ Fix timer argument.
+
+commit bd1af45298cbacb90ecc22a4d9c2358212164ed6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 9 01:13:46 2009 -0600
+
+ Check for uninitialized shading pens.
+
+commit 0134dfdf3b3f8c0338f3120c1559b07388cbd188
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 8 23:14:03 2009 -0600
+
+ Implement emulation of Gouraud shading in SVG.
+
+commit 396f32a9acea190fe1ac4edbf8a98d894adf2ae2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 8 23:12:33 2009 -0600
+
+ Add routine that returns the intersection time of the point on the line
+ through p and q that is closest to z.
+
+commit 9bc23dcee01574f5e18548de44f795834f049eb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 6 12:55:09 2009 -0600
+
+ Improve missing fft diagnostic.
+
+commit f3d623e7dea46f3e93ea6f0a8007c21e0b80c64d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 5 18:08:27 2009 -0600
+
+ Reduce PRC NURBS memory usage.
+
+commit 61e0a584d00a4b8cf0310e819309d9d669f9cce1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 5 17:50:29 2009 -0600
+
+ Fix rational NURBS curves; add example.
+
+commit 7835fffdbd04dadb20132b830fce0fe60c6072ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 4 05:54:57 2009 -0600
+
+ Reduce maxangleiterations.
+
+commit 6d6b217bc8c6a942def28f2172df23bf978cb5cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 4 05:49:55 2009 -0600
+
+ Revert to previous value of fuzz in ratio.
+
+commit f46da67ff8116f94f667cc746d161b2f17ad75db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 3 14:29:46 2009 -0600
+
+ Port recent changes to CYGWIN
+
+commit c5e55a514d847442cf3964f9d5b054ad26b277ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 2 22:39:31 2009 -0600
+
+ Always generate at least NColors.
+
+commit c0a54c9bde7af034c1d9fad7ceb08a048dfc2e8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 29 20:17:04 2009 -0600
+
+ Implement path3 unstraighten(path3).
+
+ Increase fuzz in ratio.
+
+commit 99338b8ddf43f3d1378c1c550d6f4390d78fd0d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 29 10:16:17 2009 -0600
+
+ Add support for NURBS curves.
+
+commit 67157c7e7a9daa746fba5f2918e7ce844497554e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 28 23:44:27 2009 -0600
+
+ For SVG output, explicitly draw a circle instead of a length 0 path.
+
+commit 0848be7129602a33b549b7580cd4b2f4f31db984
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 28 02:36:35 2009 -0600
+
+ Avoid unnecessary copying of linetype structure.
+
+commit 34c8a0e8c0513b2337bec7974b26499b4028ec79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 27 10:04:54 2009 -0600
+
+ Avoid negative dash patterns.
+
+commit beaddd303da81161cfb48fc171e6ef563981bcfc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 27 02:32:34 2009 -0600
+
+ Change linetype pattern from a string to an array of reals: a string is
+ still accepted (for backwards compatibility), but the return type of
+ linetype(pen) is now real[] instead of string (backwards incompatible).
+
+ Implement native SVG path output (still requires dvisvgm-0.8.6).
+
+ Implement SVG emulation of tensor patch shading (for a single patch).
+
+ Change split so that an empty delimiter splits on spaces, discarding
+ duplicate spaces.
+
+ Add fillrule argument to draw(pic, path[], pen[]).
+
+ Implement missing add routines.
+
+ Implement 2D FFT.
+
+commit 00e952a57e9f9bbda96353de3373f0d6e5526dde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 27 01:46:53 2009 -0600
+
+ Minor optimization.
+
+commit 96fd0fe7e05563cc256fba6c895e064826efd558
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 26 10:54:05 2009 -0600
+
+ Generalize example.
+
+commit 05a17fddf40670c0435bea7cce5d82db2b8f1923
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 26 10:46:27 2009 -0600
+
+ Improve example.
+
+commit 0dfac9e96a027b8677f8aa708155aa2faea6af25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 26 10:44:23 2009 -0600
+
+ Simplify example.
+
+commit 0380e389da6be2a056ece5e8586985aadf481286
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 26 10:32:44 2009 -0600
+
+ Improve inset graph.
+
+commit 37da15cebb919bc42c1ad7c3bc6f14b0470c43d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 23 00:10:48 2009 -0600
+
+ Fix rational NURBS sizing; add example.
+
+commit 57ebc8ffefa5ac6c3735ec8115fd98ded085dd75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 22 23:41:37 2009 -0600
+
+ Fix control point normalization of rational NURBS surfaces.
+
+commit 0211934ae5bf87c192a68ecac2339d511529812b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 22 00:29:30 2009 -0600
+
+ Enable workaround for dvisvgm bounding box bug (requires dvisvgm-0.8.6).
+
+commit 6c63d91654cbe7b929a0750f92749ae71b4c6331
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 19 14:14:52 2009 -0600
+
+ Fix typo.
+
+commit 1852ebbdf6968606424c611eba5609abd5dc9107
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 19 14:13:51 2009 -0600
+
+ Fix inlinemovie3.
+
+commit 54551fedfb8047a3ca3ca50f0bbfda07a119b85a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 12 14:44:03 2009 -0600
+
+ Resolve ambiguity in arc.
+
+commit 1b2b1d9d1de46d07d2cb16ab92ba0dad431985fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 12 10:12:13 2009 -0600
+
+ Don't garbage collect PRC entities.
+
+commit aca4826183e96d9f193883a1373447e59318ab28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 11 08:39:19 2009 -0600
+
+ Improve colours.
+
+commit 2f57f3013c38bce184d9f822fff740155a059292
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Oct 10 15:04:06 2009 -0600
+
+ Do not compute vector at (0,0); use a instead.
+
+commit 11d22f73ce385277021a7f5aa1dd0acc1d9af68b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 9 02:13:23 2009 -0600
+
+ Convert labelpath to png for svg output.
+
+commit 36f156597d65d8381c26fe5c975f0503d88eba68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 8 16:28:27 2009 -0600
+
+ Add support for passing bbox to dvisvgm (currently disabled; this requires
+ dvisvgm-0.8.6 from http://dvisvgm.hg.sourceforge.net/hgweb/dvisvgm).
+
+ Fix erase when outputting SVG graphics.
+
+commit f480bb7082de70848628ff6bcb6b113a2a24a958
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 8 14:17:12 2009 -0600
+
+ Fix formatting of error messages.
+
+commit 4a7cbd42478c92051c16f084f33a949480614f11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 7 21:12:37 2009 -0600
+
+ Use ghostscript pngalpha driver to produce transparent png files.
+
+ Produce transparent png files for unsupported SVG elements.
+
+commit 9fe5af671b62c0be5dee2c3fc5c65c803b0282be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 6 21:59:53 2009 -0600
+
+ Fix surface and path3 garbage collection.
+
+commit 6e1823d47ca88b8f2f7dbc0047134a2f6d108f73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 6 21:06:44 2009 -0600
+
+ Improve garbage collection.
+
+commit 8eb8dd4dd23a2f01cfb83dc13c104ed1f4d63482
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 5 23:21:23 2009 -0600
+
+ Force pdfformat when using a pdflatex texengine with an alternative output
+ format.
+
+ Force settings.align="B" for non-EPS output formats.
+
+commit 039d69203c0c6fa63d33482853450003f5d41dfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 3 15:45:21 2009 -0600
+
+ Workaround broken curses.h header file on i386-solaris.
+
+commit aaf46eaa973bb4574fecfab4b6920435a4cdc556
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 2 15:54:31 2009 -0600
+
+ Fix center table compression under optimization.
+
+commit de78b4ca31253167f2f7bf427566342126880513
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 2 09:03:23 2009 -0600
+
+ Document Billboard and Embedded labels (see the example billboard.asy).
+
+commit e59a608e691ab1b829843808ba4355428428e334
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 2 02:51:30 2009 -0600
+
+ Add code for removed file.
+
+commit c0fc62ca6d83523cdf0e82e41925c1fe54d1b5d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 2 02:50:40 2009 -0600
+
+ Increment version to 1.89svn.
+
+commit 3d506c981417015fad8b50c58f1c7ae8c5515166
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 2 01:25:43 2009 -0600
+
+ Remove obsolete part name code.
+
+commit f771a8671cdfa4caf9effb46f86e44f76465b422
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 1 21:52:36 2009 -0600
+
+ Add Arrow to tutorial example.
+
+commit 1a7944b9c943c2488edd366c322b8866a1ee7248
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 1 21:45:34 2009 -0600
+
+ Store center values in a lookup table.
+
+commit f016bed702c2b32a3e1351eec8f322c30e7923b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 1 17:37:30 2009 -0600
+
+ Implement PRC billboard labels.
+
+ Rename settings.billboard to settings.autobillboard.
+
+ Make settings.autobillboard=true by default.
+
+commit 3cd6f39dcd3340cdc936c6a2cbe70c642dd402d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 29 17:09:51 2009 -0600
+
+ Improve tutorial.
+
+commit 83d1250ec4df70d30b3b113e0fb656bb2f7b6682
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 29 14:59:26 2009 -0600
+
+ Improve tutorial.
+
+commit 28ec8495d0062c18dea0b6902cffdaa3661f794c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 29 10:07:11 2009 -0600
+
+ Add examples.
+
+commit 476b4de0787becd2e1f4ce567b8ea01e637abd61
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 19:42:07 2009 -0600
+
+ Fix compilation under -disable-gl.
+
+ Fix billboard size computation.
+
+commit 40e003e12fba455444cf863bafc4f916036e20a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 14:27:52 2009 -0600
+
+ Add example of arbitrary 3D background plane.
+
+commit 956766e1ab552e8ad330f41703728a2539693b29
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 14:21:07 2009 -0600
+
+ Cache meshpen, knot, weight, and color arrays.
+
+ Change bottom=false argument to bottom=true.
+
+commit c72533006097421745e15983fd5bd3ad090d2363
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 13:39:58 2009 -0600
+
+ Clean up auxiliary dvi file when producing SVG.
+
+commit a2aa7a0b9be009c587b5fd6bae57962f53184b03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 10:16:08 2009 -0600
+
+ Add operator * (transform3, obj).
+
+commit b3d646dfef5d4326a3aa5bff4745ae713ca5223a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 03:39:58 2009 -0600
+
+ Increment version to 1.88svn.
+
+commit f13df983c7f9a4db3b2498dcbe56f2a61e1df596
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 01:57:28 2009 -0600
+
+ Simplify code.
+
+commit 5700ba631f979a809a7b685cbc495f9035725ca8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 01:30:36 2009 -0600
+
+ Implement settings.hyperrefOptions.
+
+commit a251ed7aee647f84007449515bf186d241d2ed4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 28 01:13:24 2009 -0600
+
+ Implement billboard labels in OpenGL renderer (not yet implemented for PRC).
+
+commit bff9ef341c1595388e2049760f58a0ab5385b197
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 27 14:54:59 2009 -0600
+
+ Implement framerate option for OpenGL movies.
+
+commit f5b6d19deaed77f141de84d40912cd68ec752550
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 27 14:31:34 2009 -0600
+
+ Fix OpenGL animations.
+
+commit d571f0bb2a62f666fb46d3c6d82df51c98ab02e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 26 22:50:38 2009 -0600
+
+ Implement a projection() function that returns the interactive camera parameters
+ as a projection.
+
+commit 0ed8cb015056d1ce22944ca82abf4655420440ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 26 22:21:39 2009 -0600
+
+ Fix premature memory deallocation bug.
+
+commit 28c90d0ce6ece4ef15c31b9b8cb077c3b4d2c7fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 26 10:05:26 2009 -0600
+
+ Simplify transform3.
+
+ Add additional functions for inverting paths to 3D.
+
+commit 68a46d3ff504f6235e5a2b04f7bb8b4117a13de5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 25 14:47:37 2009 -0600
+
+ Improve tutorial.
+
+commit 005b5d7da149db0da8cb3de5a000e87596a31919
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 25 11:17:02 2009 -0600
+
+ Fix erase.
+
+commit 47fdd56f0895eca33d282b2db950df4040051635
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 25 00:51:29 2009 -0600
+
+ Minor documentation improvements.
+
+commit 158761286236e4c3ed3493930d0fed5679c8a87a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 25 00:29:33 2009 -0600
+
+ Resize 3D example.
+
+commit 93b4686d2ff546fc2dcf705b9c4af5c40a54e8ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 25 00:27:33 2009 -0600
+
+ Don't modify settings.
+
+commit 6b54c2fde17460fd58d1cd08194a92fa174cec18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 25 00:08:10 2009 -0600
+
+ Fix viewportsize bug.
+
+commit 0831668a76a53c0a62e8b49fa69977e4c10b7387
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 24 23:04:19 2009 -0600
+
+ Improve tutorial.
+
+commit 413d037c5d3de6e905e0ce13eb711c2eaaaa8f2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 24 22:59:37 2009 -0600
+
+ Make erase() clear the PostScript canvas again.
+
+ Implement an interactive erase commmand that does not require parenthesis.
+
+commit e99368945ae28cc10e0065912bbf0345e9d060da
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Sep 24 17:29:07 2009 -0600
+
+ Add support for master tex file to asy-mode.el
+
+commit ec61cada1c64452fe97ac0ffd6d0785fabe115c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 24 16:33:47 2009 -0600
+
+ Set ucyclic and vcyclic only for surfaces described by a full matrix.
+
+commit 6345c5afffd670d231aee5e05ced5662bcea905d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 23 10:55:31 2009 -0600
+
+ Move miniltx path parsing patch into C++ code.
+
+commit 970f70cf4fab1dee495bbf9f95c0bfcd077b85d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 22 15:29:30 2009 -0600
+
+ Simplify interaction of -outname and prefix argument of shipout.
+
+commit 83689ba1321c3019c0af56e8b15304b602ba6ee5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 21 21:17:44 2009 -0600
+
+ Add patched graphicx.tex file.
+
+commit 95dde9cbab250b9e20adb69f1d92f32a2370d5ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 21 13:19:12 2009 -0600
+
+ Improve indexedfigure API.
+
+commit 7fe28533c9d2775911ee9da568fb69d29e9e9d9e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 20 08:59:36 2009 -0600
+
+ Generalize OmitTick to omit both major and minor ticks.
+
+commit 4e2c341347215e7aed1d002b169ec176ca1da8b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 19 23:28:23 2009 -0600
+
+ Simplify ENDIAN test: avoid redundant flags and support ACTION-IF-UNIVERSAL.
+
+commit c7bc6f7711db47756997888d70846b65724787d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 19 23:18:31 2009 -0600
+
+ Remove spurious spaces from example.
+
+commit 15471a4ff31ff7ae8b8e17c36f92fd44d41b4500
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat Sep 19 04:18:26 2009 -0600
+
+ Add links to licence
+
+commit 99a99b9a5750d3a72ee8ec4641f13c6d0d3df863
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 18 23:07:43 2009 -0600
+
+ Update example.
+
+commit 28d308a229977054f066af360635027f500a0f1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 18 23:01:27 2009 -0600
+
+ Generalize addViews to handle any layout; change the default from
+ ThreeViewsFR to SixViewsUS.
+
+commit d20c0989d6f7914f839d67760fa7fa7157dfb012
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 18 15:48:06 2009 -0600
+
+ Increase dvisvgm verbosity level.
+
+commit 57254a17d7bfd6f7daa4a948215435ebe7116eef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 17 23:29:55 2009 -0600
+
+ Allow PRC node names for labels and dots.
+
+commit 84e20dc1912c59b45231828be24d9b5ef2fdd373
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 17 22:13:04 2009 -0600
+
+ Add stereoscopic example.
+
+commit 0e6d64647683c0e8ec650c6ede27f2bfe2fc4a9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 17 11:48:06 2009 -0600
+
+ Implement addStereoViews.
+
+commit 06988fdcfc225a82fa57b85e5763c433e14cad32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 17 09:51:24 2009 -0600
+
+ Remove obsolete patch.
+
+commit 79e893678011406031dcdadc7f903710e17aba16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 16 21:38:30 2009 -0600
+
+ Add reverse and step actions for OpenGL movies.
+
+commit 620b86903c7e0416295ddd4cb0c4210187360d87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 16 20:43:51 2009 -0600
+
+ Make stop pause animation.
+
+commit ccdc35f8f4e3504943d62f3fca7dba701ae0c910
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 16 13:52:14 2009 -0600
+
+ Add support for svg output; this requires a DVI-based TeX engine and
+ (preferably patched version of) dvisvgm-0.8.3 from
+ http://dvisvgm.sourceforge.net/
+
+commit b0ba757a3acd232a4b7d604e4d3a6a7976e4bf97
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 15 21:12:04 2009 -0600
+
+ Update links.
+
+commit d52ed585466957d4a26c67d06690861b99f9f0da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 15 13:42:16 2009 -0600
+
+ Handle a degenerate axis range.
+
+commit c66d26028097560e9e56c88ec96c2c7704df1a6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 15 13:18:06 2009 -0600
+
+ Handle degenerate palette ranges.
+
+commit f9242094efa6d9f49c3b36fd8f4106202d47613f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 15 04:04:45 2009 -0600
+
+ Remove obsolete pstoedit patch, now that pstoedit-3.50 has been released.
+
+commit bf8510a58161029ac28abfc8ef02964ae06511d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 6 13:08:25 2009 -0600
+
+ Increment version to 1.87svn.
+
+commit 1294be62b09d75a8af7c5583d7d31ff7ec1a1d3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 5 13:34:57 2009 -0600
+
+ Fix uninitialized variable.
+
+ Add missing name arguments.
+
+commit 44dea257993a1d0b8b85dbf8ebee7b92594a2208
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 5 01:17:23 2009 -0600
+
+ Fix string ambiguity.
+
+commit e76df5392dfc3f00dc25a901d6251b91d9220161
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 15:36:17 2009 -0600
+
+ Remove spurious argument.
+
+commit 436701369ae2f53c4573fdaad99d55ec1527ab3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 15:35:24 2009 -0600
+
+ Move begingroup and endgroup to oPRCFile class.
+
+commit 2539dc4db71731e27766310f0fdc9dad7e9a52c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 15:28:31 2009 -0600
+
+ Remove spurious brace.
+
+commit 132a6294bc632deb35417c7b5cc6246316d1b886
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 15:27:09 2009 -0600
+
+ Add PRC model name support to begingroup3 and endgroup3.
+
+commit 4ef5eb3cdce70a1eb8c383444b9efd3c01b5d45d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 10:28:47 2009 -0600
+
+ Support naming of PRC parts.
+
+commit 8fabefee19a41ea9735b4ec98de1e9385553e9f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 05:28:59 2009 -0600
+
+ Check for correct version of readline library.
+
+commit fbb620ff0ee3a9c5d0a33b4983dd0d51ee732c30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 05:13:50 2009 -0600
+
+ Add -lreadline to $LIBS.
+
+commit b89417fbb590c3a3d1645f8fc0d09cb99b0c7623
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 05:06:33 2009 -0600
+
+ Fix readline test.
+
+commit 9a6132abdb8d529587ee7edb28b5d185c8beead3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 4 04:39:43 2009 -0600
+
+ Improve GNU readline test.
+
+commit 7c7246361d8378fbe01997a1d978a3ea2de20e3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 3 12:35:35 2009 -0600
+
+ Fix typo.
+
+commit 2e2f756209acc727ea0bb95e70c2935da3b74cdf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 3 12:34:12 2009 -0600
+
+ Fix radius of curvature at nodes.
+
+commit 262d7c7f6f95b1986fe6a97366fcd3a30611ae84
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 2 16:39:30 2009 -0600
+
+ Reduce NURBS memory usage in polynomial case.
+
+commit 240415803877c72d83513e5d70a83559153809a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 2 16:36:06 2009 -0600
+
+ Fix NURBS sizing.
+
+commit 4f525cec551be4f68f1c2b50cb734ec86d9795de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 31 02:00:43 2009 -0600
+
+ Optimize PRC polygons.
+
+ Reduce surface memory usage.
+
+commit c90bfe48427c48edf00eb6f5d7baddfd7340ae5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 21 17:45:52 2009 -0600
+
+ Increment version to 1.86svn.
+
+commit 6a73c6c84f03bf801c2a3e3e21fd14d96d6086ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 21 15:22:51 2009 -0600
+
+ Fix typo.
+
+commit 6d98b59a38857d7f9e0f5c52cd2514f03eb3ead0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 21 15:22:10 2009 -0600
+
+ Move remaining picture operations.
+
+commit f47a7155eaa39e2218d25563a989246a96e23f92
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 21 15:21:36 2009 -0600
+
+ Rename labelsurface to surface; extend also to surfaces containing a single
+ patch.
+
+commit be47838d06af021d2074aa8d09580e2bf19fb965
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 20 23:08:28 2009 -0600
+
+ Add missing pen dimensions to sizing routine.
+
+commit e86466c814c27abddcdde8ba534c6b8dd0144fe0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 20 22:15:10 2009 -0600
+
+ Fix compilation on platforms that lack OpenGL.
+
+commit 9bc8505e57fbbb496b4231ad75218e369c91f249
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 20 08:39:20 2009 -0600
+
+ Increment version to 1.85svn.
+
+commit 0f99c085bd848e8ea759e8027938d7234b83c62d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 20 00:47:14 2009 -0600
+
+ Fix readline conditionals.
+
+commit 78dfab9cb0667c2c7e0907d1393c8223acacfded
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 20 00:26:46 2009 -0600
+
+ Split runtime further.
+
+commit d2af5f1ac81c368f813006f8dda2f7cff88ff046
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 19 22:18:19 2009 -0600
+
+ Split runtime further.
+
+commit fb91344ff828361d467468ab012ad8ce5be3c779
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 19 22:06:02 2009 -0600
+
+ Split runtime.in further.
+
+commit 6543e81a99fa39d9b2737f805eb918c36a37681a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 19 17:23:45 2009 -0600
+
+ Start splitting runtime.in.
+
+commit 224a0cabc2a2571be7c4e9e82a22c0e14b8cce63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 19 07:52:08 2009 -0600
+
+ Rename example.
+
+commit 79e9aea7b99386a7f939bb820a2d7cdba4ff4ed6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 19 01:12:04 2009 -0600
+
+ Move new example to examples directory.
+
+commit 0ec04f08aa90a6b60d51108d4048299a62b7ebb3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 19 01:08:56 2009 -0600
+
+ Extend NURBS interface.
+
+commit 17363b9b3fbcbaaf91137cc3aa2a3308f8159d35
+Author: Andrei Catuneanu <acatunea@physics.utoronto.ca>
+Date: Tue Aug 18 22:08:55 2009 -0600
+
+ Added structure pertaining to recursive subdivision of patches. Added example of use in surfacesplit.asy.
+
+commit d358b2232f83cc0708aa5670098d938e1d21ea57
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 18 10:30:30 2009 -0600
+
+ Remove obsolete function.
+
+commit 1b39ef88f10a730c9233ec8d9abeaf53b90d3d12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 17 00:16:29 2009 -0600
+
+ Move approximate NURBS bounds to C++ code.
+
+commit 7f5652be5d1c3df6ab5deabebc66ab60daf4519b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 16 15:50:08 2009 -0600
+
+ Remove inline qualifier.
+
+commit c23f68334ca0a21c236498c806a958bb1731b851
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 16 15:44:05 2009 -0600
+
+ Fix perspective PRC viewportmargin.
+
+commit 785cbe47263c17d355184a247e64c8de0224aa9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 16 14:57:48 2009 -0600
+
+ Enable rational NURBS.
+
+commit a7bf3625b440fad36f9fb89eee5ce651bdee580d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 16 14:46:04 2009 -0600
+
+ For clarity, use single quotes instead of double quotes.
+
+commit 690c54d98e06da6ee8931fb47ad20ad06028a017
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 16 11:08:20 2009 -0600
+
+ Compare to control point bounding box rather than patch bounding box.
+
+commit ff6c5bcc60187796e21ef5dc89f7bfde0b7c2e52
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 16 10:06:11 2009 -0600
+
+ Fix comment.
+
+commit 9ef12ec3ca7f52064ef0471748ba24c80329e595
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 16 01:19:43 2009 -0600
+
+ Add preliminary NURBS support (so far only implemented for PRC).
+
+commit 099ec542b77e480fdbb604222051b7396242ac57
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 15 20:53:15 2009 -0600
+
+ Clarify asymptote.sty license.
+
+commit de6005b749685dc44b8ceda243cb22f7be27068f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 15 09:38:41 2009 -0600
+
+ Remove unwanted spaces in asymptote.sty.
+
+commit 972dda4fa1cb6f8c816797f06da6c3c5911c8dd9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 15 03:01:42 2009 -0600
+
+ Increment version to 1.84svn.
+
+commit 6634bb81d4d89ee1f824064af635a69215f226d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 15 01:16:08 2009 -0600
+
+ Fix dependency.
+
+commit 9c1a615f4b4ac132f0bb5c2e68bff26269c46d6e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 15 00:28:59 2009 -0600
+
+ Embed parametric equations on Klein bottle.
+
+ Add new example.
+
+commit 19f934368489b7223888adb889015611188a4f9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 15 00:17:32 2009 -0600
+
+ Improve diagnostics for missing libz library or texi2dvi program.
+
+commit e4b876f284c2df9de310df65112847402748d73b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 23:25:57 2009 -0600
+
+ Add light argument to fit() and shipout().
+
+commit 01c20bad45364434a4b532c03f255f5dfde46e33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 22:36:55 2009 -0600
+
+ Remove redundant angle arguments.
+
+commit 801972e733d768a3f7bccd0f8a3835b28a7b485b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 21:57:06 2009 -0600
+
+ Remove unwanted quotes from LaTeX jobname.
+
+commit 76e4f53bb7104026a12e8e2aef525a3ed2d2b27f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 17:05:07 2009 -0600
+
+ Fix display of generated file names with spaces.
+
+commit 204d3a3d6ad00203b843161aeda0d8f871145ce1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 09:05:32 2009 -0600
+
+ Check only primitive types for virtual file mode members.
+
+commit 63535fdc7dc4245437aaef5b88a07ea74ad1dd79
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Aug 14 08:50:49 2009 -0600
+
+ Removing duplicated text of license
+
+commit f945cbfd799439d8af6b5cd26a4246e15598b108
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 04:19:54 2009 -0600
+
+ Restrict file modes to ty_file.
+
+commit d8203d9c0b8a4084b36a0b7c9cdc304a731f622a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 04:02:48 2009 -0600
+
+ Update tests.
+
+commit 31794c39134751f2697bf84eaa42c2019dc13e05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 14 03:41:41 2009 -0600
+
+ Make file mode functions virtual members; this backwards incompatibility
+ requires that line(file f) be changed to f.line(), etc.
+
+commit 4e479144f8f21f35b97ab322c32dd31a82e98d62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 13 22:36:05 2009 -0600
+
+ Remove obsolete cyclicflag and void cyclic(bool) functions now that the
+ cyclic member of an array is writeable.
+
+commit 3b4595b6f31ca06107f589f58b558727135bce96
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 13 22:06:27 2009 -0600
+
+ Don't overwrite viewportmargin.
+
+commit 7b97ed0aebb30591dddb10057d198a429e6712bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 12 17:33:31 2009 -0600
+
+ Check ASYMPTOTE_HOME instead of ~/.asy in search path.
+
+commit 761284a25d0f2b2de505d9bfb9decedfe4a278ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 12 16:12:31 2009 -0600
+
+ Fix texpath initialization.
+
+commit 4e5ed7ce97044102c22c48bfd0cce001ae976dca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 11 01:32:50 2009 -0600
+
+ Increase linegranularity.
+
+commit 6ddc1c963bea6ab9ffd5a367f61b3c3d183c3983
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 10 23:38:34 2009 -0600
+
+ Fix splitting indices.
+
+commit 1606e9a7dc40147924b4378ca982d79e1ec2defe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 10 22:28:47 2009 -0600
+
+ Fix definition of normal in regularize.
+
+commit 6d9797048c32dfdfed6f73c225f014f1eee4989f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 10 21:27:22 2009 -0600
+
+ Improve example.
+
+commit feb14e5db7ef6a3a4188c4581e06de0e091b9778
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 10 21:21:17 2009 -0600
+
+ Use splined parametric surfaces to implement smooth thick lines.
+
+commit 076761589b35f8dc9e9117b97cbd746d36704a4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 10 11:28:37 2009 -0600
+
+ Don't nest picture environments used for TeX clipping (not used for ConTeXt
+ since the \beginpicture...\endpicture environment is still broken; this
+ only affects the clipping of labels outside the bounding box.).
+
+commit 47a5dfc993cdc6f2905315787ad520d091f3b73d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 9 15:47:06 2009 -0600
+
+ Remove private qualifier from rmf.
+
+commit 145f90a3130752c459dbc9f66773e3bed3221a02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 9 01:34:45 2009 -0600
+
+ Copy transformation T in projection.copy().
+
+commit 0b2ab9915bfa3f189a049cd1572859769a49f6fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 9 00:49:51 2009 -0600
+
+ Construct patches with the usual orientation for a counterclockwise
+ external path; update tensor product shading to be consistent with this
+ more sensible convention (rather than the reversed format described in the
+ Postscript Language Reference Manual).
+
+ Make the default currentlight=Headlamp for consistency with Adobe Reader;
+ the previous currentlight is now called Viewport.
+
+ Fix uequals, vequals, and surface indices; implement ucyclic() and vcyclic().
+
+ Add rendermargin parameter.
+
+ Add triple dir(explicit triple) function for consistency.
+
+commit a969e6d7692d5007580b988c396d3fcdc7dced5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 8 13:00:47 2009 -0600
+
+ Tune Headlamp.
+
+commit 6c8eb4afb4c8061d820e7a5be87ae7713d24768c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 6 20:38:26 2009 -0600
+
+ Add labelsurface function.
+
+ Add min(frame, projection) and max(frame, projection).
+
+commit cf6cba7dc2ab278123e56c7277f6539340618da5
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Aug 4 11:17:53 2009 -0600
+
+ Added more error-checking to runtime.pl.
+
+commit 0b5837ac2166cf8175fc3e36da0b2fc81dc8cbf0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 4 00:35:17 2009 -0600
+
+ Fix projected bounding box calculation and angle calculation.
+
+ Remove viewportfactor and anglefactor; increase angleprecision.
+
+ Cache modelview matrix.
+
+commit b75fcd0159de28b45e51f0bd96a27ec5388bb110
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Aug 3 13:48:16 2009 -0600
+
+ Refactored pushing and popping processData.
+
+commit 7ad2c2ef9501444d77fa59c83edbe1d61ef0dfd0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 1 14:03:12 2009 -0600
+
+ Simplify example.
+
+commit 864166dbc8de454da1707813df8b1e61851a1b42
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 31 10:39:57 2009 -0600
+
+ Removed TODO items I no longer feel like doing.
+
+commit 71d08ceee7cb423100f202635aacaa934b27aa8a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 30 14:22:52 2009 -0600
+
+ Removed menv.
+
+commit e1c2a656deb5ad0eb2641f3e7cc0b26e47bc880f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 30 13:19:42 2009 -0600
+
+ Added support for splitting runtime.in into several files.
+
+commit 20d37a73fddd374ac4c7da3387023b3650ba46a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 30 08:44:44 2009 -0600
+
+ Rename splinetype.asy to graph_splinetype.asy.
+
+commit 4bd1bb0a4e0146ce62e4e295da5178b3a8db29d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 29 00:36:18 2009 -0600
+
+ Add uequals and vequals functions for indexed surfaces.
+
+commit 694920eee2c4bf681573f2d6fd8636b9650eaa90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 29 00:35:28 2009 -0600
+
+ Enable getstring with --interactive even if not a tty.
+
+commit b077254e708b9c5e15fa7bcdabaa06d2b69ae280
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 28 01:17:37 2009 -0600
+
+ Add surface indices.
+
+ Add nonuniform parametric surface routine.
+
+commit 206cc9c77018c8b1375415b9d9267aecd3bee926
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 27 14:53:25 2009 -0600
+
+ Fix formatting.
+
+commit 3408c1abb864c973e888ef8dc0e05a6e0c283fad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 27 14:25:07 2009 -0600
+
+ Separate code to split a path into nondegenerate Coons patches out of
+ surface constructor.
+
+commit 8b3cb0c0f8611dda5d4f30496ea5bbbc59a59b3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 27 10:17:48 2009 -0600
+
+ Generalize extrude.
+
+commit fa43efac07167bb002a08313f04e88c7eb287941
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 27 00:24:19 2009 -0600
+
+ Removed finished TODO item.
+
+commit ca891da0ff3b8208b18a49faedd373fd01087fa8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 27 00:23:45 2009 -0600
+
+ Made more compact bytecode for pushing defualt arguments onto the stack.
+
+commit 3767fd75669d72611ea43fff12052c67a9b94470
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jul 26 23:55:06 2009 -0600
+
+ Added detailed output for debugging bytecode.
+
+commit 9c2f666980851fa0ef43ded88eaee9b69a5783b2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jul 26 14:26:02 2009 -0600
+
+ Changed debugging output for DEBUG_STACK.
+
+commit 7a6043078e6d0e3a694d396c06a40f4c76bd0a10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 25 23:35:36 2009 -0600
+
+ Fix typo.
+
+commit c76e1b0bb19ce13de0ef2ec895fd7cc1838cd461
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 25 16:39:31 2009 -0600
+
+ Implement empirical translation between OpenGL and PRC shininess.
+
+commit 569235a9a37a12341c1753f620ee5bf3d5181672
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 25 10:31:06 2009 -0600
+
+ Added preprocessor option to print names of bltin functions.
+
+commit db669441b7bbaa6c00365b0731eaba597eeb53a2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 25 10:12:38 2009 -0600
+
+ Changed formatting of interactive write for overloaded variables.
+
+commit e89331ee4b555dffa54b40b7afbcb536439ce00a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 25 10:11:39 2009 -0600
+
+ Automated definition of IntArray, etc.
+
+commit 16d362253bf942ea57a2e03afb19cc8414163df6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 25 09:58:38 2009 -0600
+
+ Fix viewportshift flicker.
+
+commit bce50c71cb98440f42fc015253ea917cde3de926
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 25 02:05:50 2009 -0600
+
+ Embed 2D frame.
+
+ Improve OpenGL movie generation.
+
+commit 884e85d4e6e1a7bb3beca73e40631f8c0fb345bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 25 00:41:07 2009 -0600
+
+ Remove diagnostic.
+
+commit ce79a2da755a5a841ea55d69506fa888f46fdb4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 25 00:01:06 2009 -0600
+
+ Update documentation on suppressing warnings.
+
+commit 0adc924c1215e27b947a5a46d7e047fb77ec490d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 24 23:57:15 2009 -0600
+
+ Allow asy warnings to be disabled.
+
+commit a9719315fbce2bf647e957a8f411fc1280d44478
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 24 23:54:43 2009 -0600
+
+ Delete intermediate files.
+
+commit 365a52b459701fd79b56ef8be55bb15d5c3795ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 24 19:55:40 2009 -0600
+
+ Add missing typedef.
+
+commit 376acc56e739bc1a0515cbdf582566e71548333b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 24 02:07:57 2009 -0600
+
+ Write type info for variables on the interactive prompt.
+
+commit c6e1933634f8c31fe56ae22304c5b9df1dd078e4
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 24 01:45:10 2009 -0600
+
+ Made overloaded warning for interactive write less scary.
+
+commit db2f127e4687928cb72eee8466e5820382a8099f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 24 01:42:07 2009 -0600
+
+ Minor changes to virtual fields.
+
+commit 603782425a4038c412769400e5a57bcf84c32e4c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 23 19:24:46 2009 -0600
+
+ Add automated testing of array virtual fields.
+
+commit 6f0cc2df4ffe672177464e483b84bb28fd168a45
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 23 19:20:22 2009 -0600
+
+ Implemented writing to virtual fields.
+
+commit a5720dbc46b31e1c5449cd9c4b5174609e238ee9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 23 11:04:54 2009 -0600
+
+ Resolve ambiguity.
+
+commit 8bce737332a755c3a5faf42a3c9c5a3472c5dbcb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 23 01:20:35 2009 -0600
+
+ Add support for OpenGL animations (illustrated in glmovie.asy), including
+ new autoplay and loop settings.
+
+ Implement a portable Signal function based on sigaction.
+
+ Add example of inset graph to xsin1x.asy.
+
+ Improve animation fitting to guarantee a single transformation for all pictures.
+
+commit 493cef04561098dd7e4c2b59af5ba706cd2e84f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 21 10:59:05 2009 -0600
+
+ Extend embed(frame).
+
+commit 7e9a0f1ed063d4960784f2680a3ae52e356f7063
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 21 01:10:31 2009 -0600
+
+ Factor 3D fitting routine.
+
+commit 818cfaa9fdd0c2ab99ee13f68ac081a7e5d8c049
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 21 00:14:50 2009 -0600
+
+ Remove extra comma.
+
+commit 715a347291775ebb0798740c045ee3fd6f57a09d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 20 21:44:59 2009 -0600
+
+ Add missing picture sizing.
+
+commit ee449186aadfed17713f23da356f2e08fc87ae6a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 20 15:12:11 2009 -0600
+
+ Added routines for stepping through external animations in slides.
+
+commit 454f559a21b8f13cab72bbb3a08db18fd0e5fffc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 20 00:35:29 2009 -0600
+
+ Increment version to 1.83svn.
+
+commit 4b0abd49ecae0d4b588b0f833c96b0fb18fbe05c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 19 22:57:37 2009 -0600
+
+ Use a consistent approximation for drawing tube centers.
+
+commit 01e4df92d03651d9d1ddca4a0418e097a7d2245d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 19 21:35:45 2009 -0600
+
+ Fix threaded exports.
+
+commit d65cc05bce215c8f2c526c1258a61964f7de06e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 18 15:26:12 2009 -0600
+
+ Respect -gray and -bw in PRC output.
+
+commit cdc39ade33395032d0450092fc54b9e6dfd46edc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 17 23:35:20 2009 -0600
+
+ Add default argument to transform3(projection).
+
+commit 26b7e01c3c7b1a2cdccc87d21c3feee46c164dcf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 17 22:19:35 2009 -0600
+
+ Fix texpath fontsize with PDF tex engines.
+
+commit e02c92524691931d63e66ce02d06e0f65cdb5dd6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 17 19:55:57 2009 -0600
+
+ Add missing pt units.
+
+commit c5e192a6c46139a14e32209bd5167f486f82300f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 14 00:22:41 2009 -0600
+
+ Increment version to 1.82svn.
+
+commit d12953b58156403fdaf97b7e0051fb572f937ed9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 22:36:37 2009 -0600
+
+ Fix initial angle calculation.
+
+commit 51ced8f17f84f0b445cdf828ea5b8d108239d5ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 21:18:26 2009 -0600
+
+ Improve motion detection.
+
+commit e5f571b23a3439d0c7384004ca08bb7d16c6ee92
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 21:02:58 2009 -0600
+
+ Reinstate doubleclick motion detection.
+
+commit 5b086e6f82a2fa3b410131fe0ce297ee0c88b43d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 20:05:06 2009 -0600
+
+ Approximate off-axis projections (viewportshift) in PRC.
+
+commit 617b958952c3bab45d4b9d4ea36f3718b03c86ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 18:55:52 2009 -0600
+
+ Remove unused include.
+
+commit eec81e59e37eee6ddc766df5d130d4b4ea4a84d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 18:51:32 2009 -0600
+
+ Fix lineskip units.
+
+commit 6f9cd42f8184241f0bbfe7d63f9e64efb25f7a28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 18:41:39 2009 -0600
+
+ Rename minbound(triple[][], triple) to minbezier, etc.
+
+commit 10640da89ad9f2909257973207bae3e9643d0adf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 18:02:14 2009 -0600
+
+ Remove unused format argument from xasy.
+
+commit 75d7edb107496906a76167f8a8139050faef72e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 17:50:26 2009 -0600
+
+ Remove obsolete GIF deconstruction format and xformat setting.
+
+commit ee8e73b0935e740d6eda00b1652bf1730b5475c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 13 17:37:20 2009 -0600
+
+ Allow single quotation marks in filenames.
+
+commit 97e09e03f3b642361649a8a1a5a6149ff190e321
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 12 22:47:17 2009 -0600
+
+ Simplify code.
+
+commit d98d421602cd75c211e8a29a877806fb57ce89eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 12 22:31:56 2009 -0600
+
+ Simplify code; remove cstdarg dependency.
+
+commit ac0c23a7f68737023039908e62a3ebe0c4bf122b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 12 16:31:02 2009 -0600
+
+ Add other missing path3 functions.
+
+commit 9c5c9495118edbc521c5c2c2297ea5c729dbf0cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 12 14:48:40 2009 -0600
+
+ Set executable flag on PostScript files under MSDOS, to allow psviewer="cmd".
+
+commit dcf7e30049b9dc61ec6e8d50e01284814d585f88
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jul 12 12:30:14 2009 -0600
+
+ Added beginpoint and endpoint for path3.
+
+commit 469e960021b292c2dbd647efc9b4a26c6b13db3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 11 00:00:43 2009 -0600
+
+ Use "cmd" to request the default MSDOS file association.
+
+ Change default file association for pdfviewer, display, and animate to cmd.
+
+commit d63e6e7da81ab3586cf6b31547f0e2bdd7b7458a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 10 15:24:29 2009 -0600
+
+ Improve illustration of ConTeXT font bug workaround.
+
+commit 4974258e557e4c720a4e8d8cabb622cd5b03da63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 10 15:22:23 2009 -0600
+
+ Fix font units.
+
+ Add example of ConTeXT bug workaround for fonts smaller than 12pt.
+
+commit ed90d4412e83ffee109d532ae2a641a57f57e9a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 9 12:28:50 2009 -0600
+
+ Fix doubleclick type.
+
+commit dd9dbab9779fc495d312a0cd5b382c2ad023ee73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 9 12:25:46 2009 -0600
+
+ Change doubleclick setting to an int.
+
+commit a613f67ff82583b7363631353ed8559f11ccd478
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 9 12:20:40 2009 -0600
+
+ Use a portable doubleclick timeout.
+
+commit df1d4756de58eca4bc639664001f8b17413474aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 8 09:33:37 2009 -0600
+
+ Add example of lmfit.
+
+commit 3b41314ac270ea39a7eac4aaade91407e2bad2e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 7 17:43:32 2009 -0600
+
+ Adjust camera again as part of 2D resizing.
+
+ Respect keepAspect flag.
+
+ Respect projection.autoadjust.
+
+commit 5988fd3e14da597c14892b37f6a2b0acba9c2f86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 7 09:26:05 2009 -0600
+
+ Fix targetsize.
+
+commit 454dceb00c1e0257e8176f52b32a36a0c1f7bf9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 7 09:24:59 2009 -0600
+
+ Fix 3D labels.
+
+commit a8134f0235c78bcfd5e0ee33c29ea83435f03ff7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 7 08:17:31 2009 -0600
+
+ Add bool targetsize=true to 3D label routines; this forces labels to be
+ drawn with the size they would have on the target plane.
+
+commit 300c6a5cae091d3d2a19bff1281e427d7a63ea1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 6 21:35:38 2009 -0600
+
+ Increment version to 1.81svn.
+
+commit 298d4a4c0f6977f75156b1fa1cc193f98acfcd8b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 6 18:06:06 2009 -0600
+
+ Reinstate missing prototypes under CYGWIN
+
+commit a6c3aa3f6efc2a7763af915820c4d685d86a9f0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 6 17:56:40 2009 -0600
+
+ Work around missing RPC definition under CYGWIN.
+
+commit 7a144376d3b59c86200bde80aece8ef030628c5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 6 17:23:08 2009 -0600
+
+ Simplify code.
+
+commit f1e5195414fa122338f7f5b6a0a46802e381e9d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 6 15:29:09 2009 -0600
+
+ Update asymptote.info in install-prebuilt because of version.texi dependency.
+
+commit 209f0b28ac03cac92aeafe3cc364ed1f4c2a7d4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 6 14:49:09 2009 -0600
+
+ Optionally inform user how to ignore a warning.
+
+commit 364b416c18b21fd577e120049b7fab653789614d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 6 13:43:30 2009 -0600
+
+ Make array.default(j=n) delete only entry j.
+
+ Add warn(string) and nowarn(string) functions, along with settings.warnings
+
+ Change "PATH" to "LOCATION" in error message.
+
+commit bf38d58f02109603cde2ec398855503336524ec7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 5 23:02:24 2009 -0600
+
+ Mention psview as a better (and free) alternative to gsview for MSDOS users.
+
+ Update documentation.
+
+commit 61ee4dd906defef1def9c318c63029f73b0949c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 5 22:05:56 2009 -0600
+
+ Remove obsolete CYGWIN code.
+
+commit 166d080355b2116e9166f35082e38afc0ad2bb2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 5 19:49:35 2009 -0600
+
+ Work around u_quad_t conversion conflict.
+
+commit 97282a7e1a0124bba438ebfd1c4a1b81000bde50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 5 10:29:05 2009 -0600
+
+ Add virtual fields name, mode, line, csv, word, singlereal, singleint,
+ signed to files.
+
+ Simplify single precision and signed interface routines.
+
+commit 9344391260559032440ba5fa38921766990b4365
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 5 10:10:35 2009 -0600
+
+ Add comments.
+
+commit 0446ed011f40775e2e9010cff77dfa3935faf765
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 20:39:50 2009 -0600
+
+ Fix animations with global=false.
+
+commit 1673555daff75b238c2c976afa2666eb08dceb2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 15:39:12 2009 -0600
+
+ Use pthread_join instead of pthread_kill.
+
+commit 4d6b4a43ac76fb1c65c073aa3243ad7c15cda627
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 14:29:24 2009 -0600
+
+ Minor simplifications.
+
+commit 24120285fa1793f743b133edd415adb838a21634
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 13:05:54 2009 -0600
+
+ Update to version 1.04.
+
+commit 5263c5d789b346f0ba21b70635fd36858f107cd9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 12:20:09 2009 -0600
+
+ Initialize lighting only in home().
+
+commit 577619db29e83abffb14066047d4e1c07666d75d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 12:08:30 2009 -0600
+
+ Don't use POSIX timers by default due to portability issues.
+
+ Call home() before quit to return to idle state and reset parameters.
+
+commit 04ca8cf39cd39719e2e2c2763de50d31547e486c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 12:05:07 2009 -0600
+
+ Exit GUI gracefully.
+
+commit 900998e8de5169fe4b34171d0c35e25e24188d40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 01:53:43 2009 -0600
+
+ Force zoom/menu to be unmodified.
+
+ Update documentation.
+
+commit 5cbbe2af3a21be9c53bfba6e53d9965635571fd6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 4 01:32:54 2009 -0600
+
+ Fix left-button zoom/menu binding bug.
+
+ Add new settings zoomfactor, zoomstep, spinstep, arcballradius, resizestep,
+ and doubleclick.
+
+ Improve doubleclick emulation by adding a timeout (default 200ms).
+
+ Re-instate default zoom/menu right-button assignment.
+
+commit b4a6fb7ee8a9762a4943bf36b271945ce9f4ea93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 3 16:43:19 2009 -0600
+
+ Enable all warnings when debugging.
+
+commit b27871b40d04c6f0432d463605f068322797cd07
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 3 16:28:54 2009 -0600
+
+ Add setting warn that allows one to enable or disable warnings like
+ writeoverloaded.
+
+commit d86192bf3218ef996b1332c5f677d9b33d9f7561
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 3 01:39:13 2009 -0600
+
+ Improve interace to routines for setting single precision mode: remove the
+ unused x argument, distinguishing the integer case with a new bool signedint
+ argument before the file.
+
+commit 54ec4309d401e90f8e745fc4507c965e46a438e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 2 11:39:13 2009 -0600
+
+ Fix TeXLive docdir.
+
+commit 7ff6aeba07712c52a90a1f0a1d43f52226cc3b34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 2 01:54:52 2009 -0600
+
+ Increment version to 1.80svn.
+
+commit 42a9cf3fef6c93a45d7d29d9ec9a47afeee9b05c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 2 00:26:57 2009 -0600
+
+ Change default right mouse button assignment from zoom/menu to zoom.
+
+commit d8f72fba757ac4c79e0477456758eff09255f5cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 22:00:57 2009 -0600
+
+ Fix docdir under TeXLive.
+
+commit 294dfcc007f8c2ac7aabd6291fe7f470e59dae27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 18:23:47 2009 -0600
+
+ Remove unused code.
+
+commit 02a790536fcc5096f092e727b3b06588e8520bc1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 16:32:52 2009 -0600
+
+ Add viewportshift support for orthographic projections.
+
+commit 819d97e9d7c772bdb813738091a62e80e4c96786
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 02:49:09 2009 -0600
+
+ Improve lighting.
+
+commit 2209e0017ac6de0a2c360cf1aa4968b15c9be702
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 02:31:58 2009 -0600
+
+ Revert orthographic projection and lastzoom changes.
+
+commit 8f194513a8e34ebd05a69e46bc3e51e1a16b1560
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 01:06:52 2009 -0600
+
+ Don't exit on keystroke-initiated export.
+
+ Invert internal zoom variable.
+
+ Add pan (in addition to viewportshift) action to native OpenGL renderer.
+
+ Output all camera settings as a projection, including mouse actions (pan,
+ rotate, zoom, viewportshift).
+
+ For convenience, add a zoom argument to perspective and orthographic
+ projections.
+
+ Add < (shrink) and > (expand) keystrokes.
+
+ Remove unused code.
+
+ Remove viewportpadding in favour of viewportmargin.
+
+commit 3f698d4ed49b08345dcbacece53fd49c01d97c97
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 00:41:37 2009 -0600
+
+ Add operator != for 2D arithmetic arrays.
+
+commit 92538e0221579d5c0de78c6042821228116231ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 1 00:32:48 2009 -0600
+
+ Change integrate routines to output all computed values.
+
+commit 6ec413ee850ab4265101513015c1e273df83cff1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 27 01:01:04 2009 -0600
+
+ Fix perp vector calculation.
+
+commit e0cb104ae79f0a46cf76d9d5ec7809d306639629
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 26 19:21:52 2009 -0600
+
+ Reset mouse motion function.
+
+commit 82c867354368193d5c3608ae445a8b5c5789d2d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 26 15:52:42 2009 -0600
+
+ Fix segmentation fault in operator == (real[][], real[][]).
+
+ Add operator == (T[][], T[][]) for all builtin arithmetic types.
+
+commit d6342c43770749cf0bce45d9d3b5cb281eb99f84
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 26 00:19:00 2009 -0600
+
+ Use $TEXMFCONFIG/asymptote for configuration directory under TeXLive.
+
+commit 1745a978c038676dbc229c8c77d3e4b62be7ce5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 25 23:42:49 2009 -0600
+
+ Remove unused code.
+
+commit b6aeddce1a4a386d0409c82b740676ac69deff69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 25 02:51:31 2009 -0600
+
+ Remove etc/fstab kludge for cygwin 1.7 since it is no longer needed.
+
+commit baa70f8bb1dc3c4eab341e7146ade449107fc261
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 25 01:27:33 2009 -0600
+
+ Add E_RK2, E_PC, E_RK3BS exponential integrators.
+
+ Fix dynamic timestepping; simplify logic.
+
+commit 0ebf258b96ffcbbafbdff7523e76fc87831fb3eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 16:03:23 2009 -0600
+
+ Increment version to 1.79svn.
+
+commit 5f8b5d48f01b08a8a9d4b5023fdf3aa42f41a1b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 13:16:28 2009 -0600
+
+ Fix title message (assuming zoom/menu button is unmodified).
+
+commit e603921a16b1811549054a010a13f69290411539
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 12:26:15 2009 -0600
+
+ Fix align.
+
+commit 654514e6bdaf56f21c36339256a6d07dcd504b54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 12:11:02 2009 -0600
+
+ Update documentation.
+
+commit 22de6a78ac81daa6ef71fb3f2ed9a4642d7f291c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 11:24:54 2009 -0600
+
+ Add support for generating syntax highlighting for the KDE editor Kate.
+
+commit 6a083b4d39be153629958a5ff55a3c767f5733af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 11:17:55 2009 -0600
+
+ Remove redundant redundancy.
+
+commit 36067c1c8840510dc685b4e2582b20e6b645a9e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 11:04:49 2009 -0600
+
+ Change exit to exit /b (end currently executing batch file).
+
+commit ed4b675bce60a1342259cc7c76c67c2c4863f5c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 24 01:54:43 2009 -0600
+
+ Implement customizable mouse bindings.
+
+commit 1bf2cc08b2c6fca676d231f19e12047c330af170
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 23 10:15:33 2009 -0600
+
+ Use --no-warn option for portability.
+
+commit 5441bf90562e8bd0893187540b7d9c838d9485d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 23 03:12:03 2009 -0600
+
+ Fix interactive exports.
+
+commit b2096edd14a4c809c5092c3256a9c21a53ad158c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 22 21:23:59 2009 -0600
+
+ Increase textwidth and textheight.
+
+commit 0151aeea0ad3e944cb2a85a98f10410136f6b7e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 22 13:31:48 2009 -0600
+
+ Fix configure --disable-gc.
+
+commit 94d5833448064e77a56eadaa5e9a7d70db93682d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 22 11:48:21 2009 -0600
+
+ Fix thread locking.
+
+commit 32b9f044fe320f369fab6298993d58f7a01b123a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 22 07:59:23 2009 -0600
+
+ Make the install-prebuilt target omit texhash.
+
+commit 018a27c40169212efd9a5edaaa0f2ab571dc355e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 22 01:27:24 2009 -0600
+
+ Clean up patch.
+
+commit d4080b995a74b931500406776d4f4d4432973156
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 22 01:21:28 2009 -0600
+
+ Add patch to allow version 2.6.0-rc1 of freeglut.dll to be built under CYGWIN.
+
+commit 50b871d00e47490ecbf785c4db1ab712f063bbce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 22 00:08:19 2009 -0600
+
+ Update xasy for Python 2.6.2 and Imaging-1.1.7b1 (which requires no
+ alpha support patches).
+
+ Remove obsolete patches.
+
+ Delete obsolete _imagingtk.pyd file.
+
+commit 047ceae3c82d49179c08c1ee323d055952c33af5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 21 21:24:26 2009 -0600
+
+ Prebuilt png files are not included in the CTAN distribution.
+
+commit 922d180aa5b5a3ed56cb850007918f2efc1fe3a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 21 12:26:28 2009 -0600
+
+ Add missing miterlimit defaults.
+
+commit 4aa9693a0386de7f1580d454d460704a98fd9238
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 17:00:10 2009 -0600
+
+ Fix mesh mode.
+
+commit e34f3e923ba80aa782451d911fbf7ae4f84c307e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 14:39:49 2009 -0600
+
+ Add constructors to derived class example.
+
+commit 41766c990e17098a8cddfef307378b78614b66e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 14:38:37 2009 -0600
+
+ Turn off fsal when dynamic=false.
+
+ Implement E_Euler.
+
+commit 990cd520d39bc752ddcac2113d73896385d888a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 09:42:23 2009 -0600
+
+ Respect linegranularity.
+
+commit 14b88602c73f89f0e6a1a2a812836e52e1e0c04c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 09:41:23 2009 -0600
+
+ Swap patch and wireframe modes.
+
+commit d7c0e9cf1059d90b2c299b27a3d5e3dd2bacc9d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 02:37:44 2009 -0600
+
+ Increment version to 1.78svn.
+
+commit 0c7c91aff000df37072d06044eae2a4fbfdeb56a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 00:53:54 2009 -0600
+
+ Document the ode module.
+
+commit d1487e6a488f103fd1ff8c86374e58ef1fd4a253
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 00:47:08 2009 -0600
+
+ Set viewportmargin=(1,1) in asymptote.sty.
+
+ Reinstate ceil.
+
+commit ba9b67360690d9740adec086c7403ebbf553c095
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 19 00:45:07 2009 -0600
+
+ Update examples.
+
+commit d09775d77bf8817ff575d5a26846fbe2110dd50e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 18 23:30:24 2009 -0600
+
+ Implement splined parametric surfaces, based on contribution of Olivier Guibe.
+
+commit ce0ad38b305467f0be86836f251d05b0e725a813
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 18 22:14:48 2009 -0600
+
+ Move SIGQUIT earlier.
+
+commit ba2a10e95110ee21b2ec273f6e818cc3c0d3a9a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 18 13:48:59 2009 -0600
+
+ Remove periodicity check.
+
+commit 21b8d67ce07068b361b5abde7107e68304c8e90d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 18 13:47:22 2009 -0600
+
+ Allow different splinetypes in x and y directions.
+
+commit 3d3cda1c67371d74998e7df82eb20c4a531be575
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 18 13:41:12 2009 -0600
+
+ Implement FSAL.
+
+commit b04da8ad640e088b45cda90625ddf627d644dfdd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 18 11:28:41 2009 -0600
+
+ Implement dynamic time stepping in ode solver.
+
+commit 37a0bd8edd843af4e5f8a0fd21ee7ccd37aa6393
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 17 21:01:13 2009 -0600
+
+ Rename --enable-tetex-build to --enable-texlive-build.
+
+commit 33fc6ac3ac7e4ad765857c90a3249317a5a26727
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 17 11:48:42 2009 -0600
+
+ Fix autoformat.
+
+commit 9612543cc986922931b5a9c8e7bce1c9f048e85f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 15 05:06:13 2009 -0600
+
+ Simplify sysdir code.
+
+commit 60a13352e45a5fc394fecea4ba3084b6046e98b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 13 20:54:06 2009 -0600
+
+ Strip both LF and CR from kpsewhich
+
+commit 6bb98b13f6c2ae4fbadcae8fd2e33754e5351d15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 11 20:04:26 2009 -0600
+
+ Reinstate viewportfactor.
+
+commit 5673458038d38cca8a78acd20b7d7925a44a33b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 11 19:57:21 2009 -0600
+
+ Autogenerate default steps.
+
+commit 311820988be14d9768e51e62481b06a21d1a605f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 10 23:41:31 2009 -0600
+
+ Set default viewportmargin back to (0,0).
+
+commit 2ed3a262adfb64aa2e0a8ef76b78df1e8ffeb186
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 10 22:45:06 2009 -0600
+
+ Rename textoutputtype to textoutformat for consistency.
+
+commit bfef6452bad58edfcb2ec41d2bf6d115d5f338e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 10 22:43:53 2009 -0600
+
+ Fix reference sizing.
+
+commit d05eaaa0ada2d34baeb6a95971206d8dff7fbae6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 10 09:42:13 2009 -0600
+
+ Fix path3 label alignment.
+
+commit 4ee8e0a4d442b6a3ff44fb26776700c5896ec9e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 10 08:04:35 2009 -0600
+
+ Fix path3 label alignment.
+
+commit ad3568f30b3c97a178095abbf1bff15d1733ce21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 9 22:16:39 2009 -0600
+
+ Package asy-faq.info.gz.
+
+commit 505e12fc8c3bc083f7b52e4c1fc63da6738a5c61
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 9 21:59:58 2009 -0600
+
+ Fix typo.
+
+commit e525233fe9a8ee7f0b85b67b50a431cd7a0e7d50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 9 21:37:17 2009 -0600
+
+ Fix Jacobian.
+
+commit 2774d683cc021bad58908387673e54e74ac5570c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 9 21:18:19 2009 -0600
+
+ Move real[]*real[][] to C++ code.
+
+ Simplify ode module.
+
+commit 8a7825f0c4aaae85c01afde00b44a45bd027dde7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 9 15:12:29 2009 -0600
+
+ Update ode module; extract example.
+
+commit 915c133a834355d84847c12360d23bfd01a260bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 9 15:10:59 2009 -0600
+
+ Fix bug found by Olivier in surface(real[][] f, real[] x, real[] y).
+
+commit 22661b59d1018e9b0e6e3d0e730300028377448d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 21:53:40 2009 -0600
+
+ Uninstall asy-keywords.el.
+
+ Update slidedemo.
+
+commit 25e8d964eb1cf998cc4c98ff83dcb4ece29707ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 21:32:37 2009 -0600
+
+ Fix build error.
+
+commit 159bd8ffceef0180106cef6990bca3276933571e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 20:53:31 2009 -0600
+
+ Fix spec file.
+
+commit d094315883306c562b7f750dc25010156cad487e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 20:36:06 2009 -0600
+
+ Update info location.
+
+commit ecb90813a16f7b4a58a7bed4d601848832595e2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 20:11:06 2009 -0600
+
+ Clean up info installation: make install installs info files without png
+ images, make install-all installs info files with png files.
+
+commit 06062a8fc1853f82e73e013ac1e18f57f6a48bd5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 16:51:01 2009 -0600
+
+ Install png files with asymptote.info in directory info/asymptote.
+
+commit ad20ea83e4eab6b5b25bb80bb8e47031522d90be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 14:36:36 2009 -0600
+
+ Install asymptote.info before asy-faq.info so that info asy accesses
+ asymptote.info.
+
+commit 40087a5149d47d3e8c2be6e1c47bfc6c88cf8ef4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 07:52:49 2009 -0600
+
+ Resolve ambiguity.
+
+commit cd1b5851efd15b8dd7d3cd356bf1d718e0dfa430
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 07:31:41 2009 -0600
+
+ Fix mintimes and maxtimes for arbitrary length paths.
+
+commit 03075fc3e8a82616ec1bb37798886f38e5cba18e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 07:11:07 2009 -0600
+
+ Make format return TeX compatible output only in math mode.
+
+commit 57ec1bdc6a61f1f22cafe24b083e410d8eaa3a32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 06:18:43 2009 -0600
+
+ Add Levenberg-Marquardt nonlinear fitting routine, contributed by Philipp
+ Stephani.
+
+commit 54db4707a1384f7c0213ca8cce72c0ecca8c19b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 7 06:10:56 2009 -0600
+
+ Fix maxtimes for paths where maximum occurs at the endpoint.
+
+commit 529869410ebcf3f2f739905d29fc8609055350b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 6 19:09:43 2009 -0600
+
+ Improve viewport padding.
+
+commit ce41184dee54dc485233ca5c1d4419312bdc5b6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 6 09:26:30 2009 -0600
+
+ Add links to manual in error message.
+
+commit 2e9b064755c3100618bc250ec3b9c370d4a5f917
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 6 07:52:40 2009 -0600
+
+ Add preliminary ode module (untested).
+
+commit 1efc68359d7b866f90fba010d2d0fa128de447f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 5 23:47:42 2009 -0600
+
+ Increment version to 1.77svn.
+
+commit 30fbcf86352e77111c8945011c6bd4bac6ea5a9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 5 21:23:37 2009 -0600
+
+ Remove texunits (not required).
+
+commit af97e49cf8ba73773b2b046529a087179d0d1651
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 5 21:06:43 2009 -0600
+
+ Don't split info files.
+
+commit c1a37b437ed1d69d54a1a220be9ea6abb8ac77fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 5 20:45:25 2009 -0600
+
+ Fix bezulate bug: determine the number of intersections of a path with a
+ line segment directly from the intersections routine.
+
+commit c55988dc43897d11d1dc946d23f2c1feb28406b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 5 07:36:55 2009 -0600
+
+ Fix typo.
+
+commit de2e5ed576d69cfc05ce24b0b8409d2deb21fa8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 5 07:06:37 2009 -0600
+
+ Restore example.
+
+commit dca1b761f0da78fa587725c9f7b9fd2b1782714d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 4 10:42:35 2009 -0600
+
+ Rename inside(int,pen) to interior(int,pen).
+
+commit 951e4508787b46b77a53977092ac68203d43eb04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 4 10:41:19 2009 -0600
+
+ Suppress "cannot find an interior point" warning for degenerate paths.
+
+commit bb3f9003a5dd35c528661cb9af8d0aabea64ae47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 23:19:05 2009 -0600
+
+ Implement addAllViews function to exhibit all six standard 3D views.
+
+commit 67330fd087eeff0f55154ff4a76e7dc42b19f3c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 21:36:49 2009 -0600
+
+ Rename adobe light to White; update parameters to agree with PDF32000-1:2008.
+
+ Add ambient light to Headlamp (other parameters in PDF32000-1:2008 appear to be
+ incorrect).
+
+commit a0f189d40ebb7ca2b5e6d8a6e234f3cacf2583ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 12:55:50 2009 -0600
+
+ Turn off light in certain examples to avoid confusion.
+
+commit 1b2cfce2ef63671c968f410cf09595e765fd4f49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 12:48:50 2009 -0600
+
+ Fix filename for attach=true mode.
+
+ Add hiresbb option to includegraphics.
+
+commit 688c7c03a9b2a3fa1a4df1091c876cbb6abf3b7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 12:21:11 2009 -0600
+
+ Improve texpath resolution by preshifting.
+
+commit d63b55ee4d35163c186d82a686c129c6bac564c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 12:02:54 2009 -0600
+
+ Make fontsize package conditional on latex().
+
+commit 590f94b98bd139a090dc44116f7aaa783ede1fbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 12:02:29 2009 -0600
+
+ Improve texpath caching.
+
+commit 151f07527b00cf79ebb87088d2322dccf1940a69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 12:01:42 2009 -0600
+
+ Fix degenerate transform3.
+
+commit 30479826115232ebca80f5fb15fed4186889e443
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 01:50:28 2009 -0600
+
+ Add real[] texsize(string, pen=currentpen) command returning raw TeX
+ dimensions {width,height,depth}.
+
+commit f75bbab5748fa346edc8c667d02a150ed1b6e0eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 01:46:42 2009 -0600
+
+ Add missing ps2tex scaling.
+
+commit 69ab0d6f5d9f0ec4dada3b38ca109e498ee97b0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 01:45:14 2009 -0600
+
+ Make texpath aware of baseline for PDF tex engines.
+
+commit 2de4ef194157962c1deedd5617f95dd25b926e69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 3 01:42:23 2009 -0600
+
+ Simplify alignment.
+
+commit e546aac7b42fcac76b3ab656a227642c57517831
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 2 12:02:03 2009 -0600
+
+ Remove unwanted assignments.
+
+commit fd784f824ab52137ccc868762c3c23d6f271d4ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 2 11:33:59 2009 -0600
+
+ Tune headlamp parameters.
+
+commit 01e9e6105d2e0c05890a0d3580ce7169657e781e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 2 11:33:38 2009 -0600
+
+ Tune alignment between rendered and PRC images for perspective projections.
+
+ Fix angle for absolute projection rendering.
+
+commit f88101c29df7754a09d0ecc8ee38306032f9fc90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 2 10:26:20 2009 -0600
+
+ Add headlamp light that approximates 3Dlights=Headlamp.
+
+commit 5dd7890aea6db356e0dec4ef687a34dde0d19087
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 2 01:28:17 2009 -0600
+
+ Add hiresbb option to graphic.
+
+ Remove 2 pixel offset.
+
+commit 4dcddca90a911b349f0b8fa3c543cd1adc2282fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 2 00:37:23 2009 -0600
+
+ Improve rendered and PRC alignment.
+
+commit 50388eca0e09c1824b0c134e074a669a9a3d9fa0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 1 21:57:28 2009 -0600
+
+ Handle holes in surface constructor for superpaths when planar=true.
+
+commit 8181e3eebc72966d7e53aa0eb954d53800c25329
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 1 17:18:19 2009 -0600
+
+ Add support for OCG layers.
+
+commit eedc3f6fd635d411e871a006356e23e6f90b3866
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 1 02:43:51 2009 -0600
+
+ Increment version to 1.76svn.
+
+commit 3566c16a88c716b8f890720759369535a285568c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 1 00:04:03 2009 -0600
+
+ Fix target.
+
+commit 32bc3480d0dafe6d475bc5fcb903e07f2e7929ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 23:35:47 2009 -0600
+
+ Update example.
+
+commit c1779f47cb6199df3ea6ba88ef12f3d5c8f4ed53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 23:06:06 2009 -0600
+
+ Add install-prebuilt target for CTAN distribution.
+
+commit f824133509041975553fbe67bf2576b850eb6e5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 13:15:28 2009 -0600
+
+ Increase fuzz.
+
+commit 7122c68b5919d0df45897d20ef6c438a9dc5352e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 12:01:15 2009 -0600
+
+ Revert inadvertent commit.
+
+commit d8db8f2edc64c08980988ff6b6edfb783a0a3011
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 11:59:17 2009 -0600
+
+ Fix missing documentclass when texpath is used in inlinetex mode.
+
+commit e6cdcb7915197c4cbf1b58855fe76b2d7bcf4f02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 11:11:40 2009 -0600
+
+ Workaround missing -output-directory option in ConTeXt (current directory
+ must be writeable).
+
+commit 6de2ae1ddd58a49734914c967c1d5977ea717cfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 10:20:19 2009 -0600
+
+ Implement alternative workaround, suggested by Hans Hagen, for ConTeXt
+ switchtobodyfont alignment bug in TeXLive 2008.
+
+commit 93e3d78fe71baf37b0fe4d0ae2c716151420af19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 10:09:14 2009 -0600
+
+ Add --disable-readline and --disable-fftw.
+
+commit 285d415e65b9c7c7d79c157d663bb694e286fb75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 09:59:40 2009 -0600
+
+ Remove font encodings by default.
+
+commit 75d01e891bd976179c94a5185d1d8662c1ed5215
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 01:25:55 2009 -0600
+
+ Remove troublesome --purgeall context option (ignored in TeXLive 2008;
+ leads to bad argument #1 to 'match' error with ConTeXT Minimals).
+
+commit 9f679ed5eaf47ddb46a546ee4714cbf1634472db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 01:14:21 2009 -0600
+
+ Clean up epilogue.
+
+commit bd97f792724d80ed2c53bef9258ce8b31c2c2208
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 01:13:23 2009 -0600
+
+ Fix aspect ratio calculation; tighten anglefactor.
+
+ Improve viewportmargin handling.
+
+commit 0fa9327d407c403447e55b032116c65d25671ce3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 00:46:12 2009 -0600
+
+ Remove GCLIB_CHECK.
+
+commit f06c75435421cee3d1faa1e188fbcb7dc2fc5ad0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 31 00:33:09 2009 -0600
+
+ Handle cusps.
+
+commit 298d8aa536f119456adb7d9aacab28c81383048d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 30 21:54:39 2009 -0600
+
+ Remove unused file.
+
+commit 8237ff1025cbcd4ac4c60248d8419dfdf01c97a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 30 10:47:00 2009 -0600
+
+ Return a sorted array from intersections(path3, surface).
+
+ Add intersectionpoints(path3, patch) routine.
+
+commit 17c2e0d5cd9f62e569f86292d54c19c932df9014
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 30 10:37:10 2009 -0600
+
+ Fix intrapatch duplicate point removal in intersections(path,surface).
+
+commit 0e14bb76c839af345f01f53d03b69815cab68dd1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 29 09:20:50 2009 -0600
+
+ Remove unused interface.
+
+commit 957ccc0b6b052f2f86e1957565b7b58cbcf6b96a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 29 09:14:39 2009 -0600
+
+ Add usetypescript[modern] to texpath.
+
+ Adjust anglefactor.
+
+commit d5509c68aa53526375b640b9a24f271e0f966111
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 28 22:36:28 2009 -0600
+
+ Add missing brace for context miniprologue used by texpath.
+
+commit ad7435c09d8c7e2df18578e5f9f90d33b8827d7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 28 03:26:53 2009 -0600
+
+ Increment version to 1.75svn.
+
+commit b9d350961270dc36ce7ab75592d4bfe490c071cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 28 01:57:37 2009 -0600
+
+ Fix help command under MSWindows
+
+commit 43c90a558d3a412fae71a0415d301561907409c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 28 00:56:30 2009 -0600
+
+ Improve appearance of cube example.
+
+commit 64adc5adecdcbae9502cb8d38001b2c2ae2db935
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 28 00:33:43 2009 -0600
+
+ Increase anglefactor.
+
+commit be0e2eba11df9da38e068ed6e204677b201b148c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 28 00:14:35 2009 -0600
+
+ Fix assert; increase fuzz.
+
+commit e7fffb6e11f4b61fd3f773cc50db58aa200a8ed3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 28 00:00:27 2009 -0600
+
+ Disable PRC output when using ConTeXt engine (due to lack of movie15
+ equivalent).
+
+commit 60223b2f21e367183929a06cea8d11070e302420
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 27 23:37:13 2009 -0600
+
+ Fix incorrect auxiliary control point in surface bounding box routines.
+
+ Add path/surface intersections and intersectionpoints routines.
+
+commit b8a100ec8889686eaaf69f40ea233d3553903754
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 27 10:16:32 2009 -0600
+
+ Fix packaging.
+
+commit ea25f68f0f294a2568a906ca87832e258c9c1e82
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 27 09:47:32 2009 -0600
+
+ Package conTeXt files.
+
+commit d359199885c11fcea6782cba8fa0d36fb42e47b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 27 09:30:15 2009 -0600
+
+ Revert 1.74-15; ensure consistency of circle and arc.
+
+commit 8c8046a93712185098c044acddac237195dcc4d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 27 08:44:56 2009 -0600
+
+ Fix RPM build.
+
+commit b4e1016d05067f31015761b7adb00906ef3adeef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 23:21:51 2009 -0600
+
+ Fix diagnostics.
+
+commit fa41eae215f40b4938920a1e95b779a2297c6894
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 22:56:39 2009 -0600
+
+ Remove ambiguity in font commands.
+
+commit 5b38029712b4a67a372b523f3d9a67fc18fc806d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 22:55:34 2009 -0600
+
+ Increase duplicate fuzz to work around font errors.
+
+commit 812e5a12484ed78bb6044716e6aea84c033b3f97
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 17:57:11 2009 -0600
+
+ Add portability fix.
+
+commit 51d2a997b312453016f6884b19b2d7bea980c2cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 17:46:56 2009 -0600
+
+ Remove unused enums.
+
+commit dc714bd68848faec6f421b88b7da89bd5020f447
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 08:23:49 2009 -0600
+
+ Fix enum.
+
+commit c22bce6986019495a36f2e49be622fd38a1e5161
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 08:21:02 2009 -0600
+
+ Fix preprocessor command.
+
+commit 2cf616475d6267d764e0d7debc9fd836139b9f10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 02:52:25 2009 -0600
+
+ Enable non-PRC 3D context support.
+
+commit 71ba0d87410db1ecf377b60f231783759e8cee40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 02:25:39 2009 -0600
+
+ Support context engine in _texpath; clean up files.
+
+commit 1d10efc8ee0c9818eb00d4a46bb46fb023329483
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 01:30:46 2009 -0600
+
+ Cleanup temporary context files.
+
+commit c5f46b343da8ea10be2bee947c89a30e962cf793
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 01:12:05 2009 -0600
+
+ Normalize direction.
+
+commit 353cf76c084a812c558ef67460009cc5e818e1a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 26 00:16:53 2009 -0600
+
+ Workaround possibly broken header file on i386-solaris with g++ 3.4.3.
+
+commit f9494ca94993529747ced00a109516b16dfd159d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 25 23:58:24 2009 -0600
+
+ Force child to exit when pipe is closed.
+
+commit cdadd335d339ff8f9e0140ff5bb20a6aa9a918c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 25 11:01:50 2009 -0600
+
+ Prevent double waiting in pipeclose().
+
+ Support PDF tex engines in texpath.
+
+commit de43da1d463274e3d8cac3e32b25ed159fabf72b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 25 07:18:45 2009 -0600
+
+ Don't issue \usemodule[pictex] in inlinetex mode.
+
+commit 090c0c4ae9cb651aac3897930554703d610d6504
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 24 22:25:12 2009 -0600
+
+ Handle zombies in pipestream without using a wrapper, so that one can detect
+ whether the child process has terminated.
+
+ Simplify, _texpath, textpath, and _strokepath.
+
+commit 6015d4b9944ca08604ec775dbbf92f2b4e0fd0b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 23 22:47:30 2009 -0600
+
+ Fix initial context pen.
+
+ Add usetypescript convenience function.
+
+ Protect context switchtobodyfont with gsave/grestore to prevent
+ misalignment if font is not found.
+
+ Improve description of -v option.
+
+commit 95a573ec7fe5269f21b844bcd06d710f05172e09
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 23 22:44:43 2009 -0600
+
+ Fix ylabel rotation.
+
+commit cf29666c9accb9fc112877b066d251e7b4e20d0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 23 21:07:40 2009 -0600
+
+ Implement a better workaround for lack of a context interactive mode that
+ does not rely on the existence of a null.tex file.
+
+ Use context-style command-line options.
+
+commit 8e1ea31d005c1ab1075befa5f631a7f7dda171c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 23 11:18:01 2009 -0600
+
+ Fix man page generator.
+
+commit 0c4c6ee7d904d48e7d22d421c37e2ca920793c1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 23 08:11:52 2009 -0600
+
+ Add colo-asy.tex file (contributed by Mojca Miklavec).
+
+ Remove base/asy-keywords.el in favour of asy-keywords.el.
+
+commit f45daa6be9a492d5eed7429d007eff5cde05d4fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 22 18:24:14 2009 -0600
+
+ Add unitoctant example.
+
+commit b2d3c2f5205169dbbb4200bcb343f0cef4ca3472
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 22 14:20:05 2009 -0600
+
+ Allow draw(nullpath3,linewidth(0)).
+
+commit f45dc9b07cb323314e7ceed18fff87b2a2b185b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 22 14:09:15 2009 -0600
+
+ Use only 2 nodes for arcs of no more than 90 degress.
+
+commit 33b2d5403b74c7574e68eaf04ad5b23c1ff2cd3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 22 09:05:16 2009 -0600
+
+ Remove unneeded \bye in context support.
+
+commit 16ca066028ac8beb816f71d79ce36224f697c285
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 21 13:40:02 2009 -0600
+
+ Add LeftView, RightView, FrontView, BackView, BottomView, TopView, along
+ with addViews function.
+
+commit f3bfaf748a3c0c78faef4cc4728a2b58fa8cd084
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 21 01:01:24 2009 -0600
+
+ Add example of baseline alignment.
+
+commit 90447658740c8e3e3f2dee522cc8b40f6ea0eb64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 21 00:32:14 2009 -0600
+
+ Add support for ConTeXt tex engine.
+
+commit 558d0dc299421448f3c766ef6bba6b232fad900e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 20 19:24:38 2009 -0600
+
+ Updates to facilitate TeXLive builds.
+
+commit d31c84a64a6fe3dfbb382146a3bc3da22a40e57f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 20 00:48:02 2009 -0600
+
+ Update example.
+
+commit 24544283d531ef68ec5e60f00f106a787f6f7c06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 20 00:03:34 2009 -0600
+
+ Add example showing how to render multiple views of the same picture.
+
+commit 86b24f2d4bfc4fbda1ce380030333643257bf2f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 23:53:39 2009 -0600
+
+ Simplify code.
+
+commit 59e65e542e7ec1f41cb53901e70e775f497327c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 23:49:09 2009 -0600
+
+ Remove dependence on currentprojection in label(Label, path3).
+
+commit 0b05f066e9754a6f541eaa504d09ef74f0d8d29a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 23:36:08 2009 -0600
+
+ Fix another BUILD problem.
+
+commit 2602e4b69e66d6f6965c0b9bd9b615bb5ba7713c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 22:50:14 2009 -0600
+
+ Fix build problem.
+
+commit 116046ccd5021691f08ae7ccddb76fc8532d8a3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 19 21:29:58 2009 -0600
+
+ Remove symbolic links from source distribution.
+
+commit 9dd0993b5ad92887deb26496feaef22a6f67d590
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 23:08:58 2009 -0600
+
+ Add enable-gsl[=yes] and enable-gl[=yes] options.
+
+ Use AS_HELP_STRING.
+
+commit afa93385a431d6e72638f2f57f04d2b6c2ee3506
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 22:47:55 2009 -0600
+
+ Fix distclean.
+
+commit 8adcdf72dec255e5e274695e507ba8b31a84336c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 11:08:59 2009 -0600
+
+ Increment version to 1.74svn.
+
+commit 4da7a1c804c037540abd25ef486a64dee62a1f25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 11:08:23 2009 -0600
+
+ Revert last change.
+
+commit b9d6c02e6b78638ff4fe7fedb7a2fa065188bfe8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 11:06:44 2009 -0600
+
+ Fix version number.
+
+commit bbe2c51e864af5644239ad84154105f578bca363
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 02:02:35 2009 -0600
+
+ Allow sysdir to be overridden on the command line.
+
+commit 4ace450116e7a640bb3af9a63cde979a336c380b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 18 00:52:28 2009 -0600
+
+ Fix texlive build under MSWindows
+
+commit 9b6a907ccafb7302f1359292216d397b1d070118
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 23:10:36 2009 -0600
+
+ Support user-specified background color in OpenGL renderer via light
+ constructor.
+
+commit 8dab38cc5bfe6e3e9432dc703cd029fc1f362710
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 21:18:17 2009 -0600
+
+ Add textinitialfont environment variable.
+
+commit fe2963bd48d61b8e25678fff009ee1e6e345e963
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 11:41:49 2009 -0600
+
+ Call reportFatal in psfile.close().
+
+commit 36a3a976a948d7bd0fa1b80892c43c27ed3370d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 11:22:56 2009 -0600
+
+ Don't return after reportError.
+
+commit 3a3c79a4ff96d642d776958a562722e3770e73be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 11:08:10 2009 -0600
+
+ Add warn=true arguments to polar, azimuth, colatitude, and latitude.
+
+commit dd275da9bd3518b49dd7ac6ecfadb711c5cdf333
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 01:18:07 2009 -0600
+
+ Set default font to groff 12pt Times Roman when settings.tex="none".
+
+commit 7a468b6214aa524c6d6039b04f020c750b29ee11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 00:52:19 2009 -0600
+
+ Add pen support to textpath and example.
+
+commit 89c81090b6adbfd7042b48c9890a305a4f4fcc29
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 17 00:49:39 2009 -0600
+
+ Fix segmentation fault after mode error.
+
+commit 5d7c2961040fb175ac01a159a6d86a9f0ef005de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 16 23:10:29 2009 -0600
+
+ Add textpath command, contributed by Michail Vidiassov.
+
+commit f7cbb093bdcd366d04f80896c158971b75a4ecd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 16 15:21:49 2009 -0600
+
+ Update links.
+
+commit de1e093f4893ba663f0b309c8684cfdea1cf86c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 16 10:16:47 2009 -0600
+
+ Restore example.
+
+commit 3ffc18a55c28366bbbe0e955a24d0858eb1da9d8
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat May 16 08:04:32 2009 -0600
+
+ trembling.asy: change licence GPL to LGPL.
+
+commit 50267997b1e79f1e73026d6e22d735702518e589
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat May 16 05:07:49 2009 -0600
+
+ geometry.asy: put the compatibility routines
+
+commit 37f8df82bea245b18f31a1d742183658313d93ec
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat May 16 04:52:59 2009 -0600
+
+ Fix minor bugs in geometry.asy. Change licence GPL to LGPL.
+
+commit 9250b2cb1117934330629dde9bd798898ead99de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 16 01:23:23 2009 -0600
+
+ Use center=false by default again for orthographic projections.
+
+ Improve vectorfield routines.
+
+ Update documentation and FAQ.
+
+commit bfa1eaa3e77972c199c5edfd75d410e94d35545d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 15 14:32:28 2009 -0600
+
+ Respect autoadjust=false.
+
+ Remove autoadjust parameter from orthographic projections.
+
+ Center target by default, unless autoadjust=false.
+
+commit 3f85494877f2c44aa49fe86f97de42f90bd4b31e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 15 08:55:36 2009 -0600
+
+ Update documentation of shipout.
+
+commit 9ac317ffb071d94af2c82b37225dd18497cdda86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 15 08:31:21 2009 -0600
+
+ Increment version to 1.73svn.
+
+commit 1f773a2f0aaf702a423adf7eccf893d62a04eac9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 17:26:51 2009 -0600
+
+ Increment version to 1.73svn.
+
+commit 9ce9d03912c53e9f69d99585f95d268924070724
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 16:03:48 2009 -0600
+
+ Increment version to 1.72svn.
+
+commit 2fee527c6fff0b94db64e4bbea30c97cd229b355
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 15:59:18 2009 -0600
+
+ Re-introduce portable zombie-free fork.
+
+commit af459ca9ae85b53b88b2ba5c902fe265ae64d95e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 15:05:21 2009 -0600
+
+ Detect degenerate paths.
+
+commit e09844d2c619aa73bcb76897ae878063bb80448a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 15:04:56 2009 -0600
+
+ Fix ambiguity in extrude.
+
+commit 909baef375e0e6c773ec1743f4348833af304a98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 12:52:03 2009 -0600
+
+ Force HAVE_LIBGLUT on darwin.
+
+commit 70d0c0ffd3a03c1bf8d7ac38ebe0248f2d5dac89
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 11:57:53 2009 -0600
+
+ Add patch to workaround problem that shows up in the 2009/03/23 version of
+ movie15.sty.
+
+commit e626f36eda7f3693920cc67eeae01d54da45fed7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 10:17:15 2009 -0600
+
+ Fix spurious zooms due to menu interaction.
+
+commit 6fde3ae29fc3a667e2de795b6b4f3dade51a36dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 09:33:06 2009 -0600
+
+ Detect libGLU.
+
+commit d891aabf4a749b753caee840258e57d5451048cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 01:47:25 2009 -0600
+
+ Change label3 to a routine extrude that returns a surface.
+
+commit 142dff3335feed312d6544a9be844c84ad66f2ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 01:19:29 2009 -0600
+
+ Work around old LGPLv2 license covering tr.h and tr.cc.
+
+commit 1b958edc2bebdac4a991d08e6fc7cf4793f586b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 14 01:00:37 2009 -0600
+
+ Report up and target camera parameters.
+
+commit 789466cd680580ec92a3bf6fe9fcacc909cb20fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 13 23:21:33 2009 -0600
+
+ Generalize extrude.
+
+ Implement label3 for drawing 3D solid labels (illustrated in label3solid.asy).
+
+ Remove extra call to bezulate.
+
+commit d5f7fe9131eea9cbf0191f77397b711e7855c1f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 13 23:18:57 2009 -0600
+
+ Define mantissaBits.
+
+commit 24708486fecbb134a0d42005ad59af4374c01089
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 13 23:17:50 2009 -0600
+
+ Limit recursion.
+
+commit a4f0012e806f96086581871d1d8aa2759d7191e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 13 11:40:56 2009 -0600
+
+ Add menu item (c) Camera to output camera position.
+
+commit 6133b9b3dfedab877b8d06458dd316711b514b13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 14:24:34 2009 -0600
+
+ Make asy.bat respect all command-line arguments.
+
+commit 34c82634698f14f0aed162575c652163518fcc06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 14:07:54 2009 -0600
+
+ Fix axis label alignment.
+
+commit 0a71bbd7ac01725fe76ecf1384fe010228d4e4e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 11:21:38 2009 -0600
+
+ Update call to ticks.
+
+commit 8ea2631aa1767ebfbaab0e4c19859a6a792268d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 11:15:49 2009 -0600
+
+ Support optional margins for axes arrows.
+
+commit 6cf99cebcdbbad787b7682eb40ca51f1be3b811f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 10:49:58 2009 -0600
+
+ Add trembling module, courtesy of Philippe Ivaldi.
+
+commit 99332ce8cad09a9f1862421df940339ddf9a9782
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 10:44:28 2009 -0600
+
+ Fix rotated path label alignments.
+
+commit 357799e128c9f3c9c5d7c9607632206cf8681239
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 02:17:46 2009 -0600
+
+ Update comments.
+
+commit 7b2ac914dcdf7132ab44b6e45d09a5a9411979ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 12 02:01:22 2009 -0600
+
+ Merge in Philippe Ivaldi's geometry module.
+
+commit 726157a28e859aa65bdd3e83ca13bf171058eb1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 11 22:28:04 2009 -0600
+
+ Update license.
+
+commit 1ac2d7244c04ac002cfeb9bccf3173ec923444d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 11 15:37:12 2009 -0600
+
+ Respect store argument of saveline.
+
+commit e767385e299dcd779839eccbbb2cef377bee0f57
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 11 12:59:15 2009 -0600
+
+ Update Ticks3.
+
+commit fbcf28b59f70f4125edfd81195fbfb7e22bfa05f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 11 12:55:54 2009 -0600
+
+ Implement signedtrailingzero.
+
+ Fix left-justified trailingzero alignment.
+
+commit 9430fd06095e2feffb090f4fe7436be1e1259d80
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 11 11:39:52 2009 -0600
+
+ Resolve ambiguity.
+
+commit dbccc13c1b525540ab6c85f6cb91eff11140f1cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 11 10:39:04 2009 -0600
+
+ Implement PostScript calculcator function shading and example.
+
+ Add default fillrule arguments to frame shading routines.
+
+commit 182d0b51797762c5a56358f210ad48fe28584439
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 03:12:28 2009 -0600
+
+ Continue splitting when radius of curvature is zero.
+
+commit 1f8185d17208adcc64f531f0721c4b8b4848ebc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 02:59:30 2009 -0600
+
+ Add Philipp Stephani's GSL updates.
+
+commit c705bfc40bdce539c7eddbcf85b2b648ad9b3b1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 02:11:46 2009 -0600
+
+ Fix link; add missing index entries.
+
+commit 3f47835f5813a1270a4de872216d54c1fff68903
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 8 01:22:22 2009 -0600
+
+ Fix endpoint detection.
+
+commit a80b2a2822feb137a416ed65e96a63fd8070302e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 5 15:44:20 2009 -0600
+
+ Fix write(pen).
+
+commit 07d8045cc034bd193a25e1ad0f16729cc2428379
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 1 14:42:31 2009 -0600
+
+ Improve documentation of shipout.
+
+commit 313d85edc3a132e9453fa221f9e55e353a0af08b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 30 11:52:51 2009 -0600
+
+ Fix bounds.
+
+commit 2f5229f927702f7486ddaa1081d484540ef47aba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 30 11:46:33 2009 -0600
+
+ Fix comment.
+
+commit 61b65cfc1056f40028333c8d358eefcb2fd9889e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 30 11:45:51 2009 -0600
+
+ Improve example.
+
+commit ad4bef7f9cc5a2b81bf51f43481251b82581d4dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 30 11:44:10 2009 -0600
+
+ Add strokepath example.
+
+commit c8d5ef4c808d829628757f12f9183badba8eee82
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 30 09:32:36 2009 -0600
+
+ Add twisted tubes example.
+
+commit 6e5c3b36b25df3a8d34b4b4ab9cd353cb9deb333
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 29 16:44:55 2009 -0600
+
+ Implement functionshade primitive.
+
+commit 647887338fa1d03c1c1a66651f7e0d5b589dc232
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 27 22:14:04 2009 -0600
+
+ Fix numerical resolution problem in label alignment.
+
+commit c632ee4a0d60debeb8dcbf6e2d8501b93278d5eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 27 19:13:42 2009 -0600
+
+ Add sysdir setting.
+
+ Support automatic determination of sysdir from kpsewhich, if sysdir="".
+
+ Add configure option --enable-tetex-build to force sysdir="".
+
+commit cca905863568c79558f4ba515c4ff330347ea79e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 27 11:42:19 2009 -0600
+
+ Fix effective camera positions for oblique projections.
+
+commit 1c4272247ecacabe1c0a75e99c5962ad466b0e41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 24 11:41:49 2009 -0600
+
+ Abort on write to pipe failed error.
+
+commit 3ce25f46d059ba3d4a8cf459da93ce83a901dc3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 24 10:55:49 2009 -0600
+
+ Generate wheel.mpg earlier.
+
+commit 90945287b2d6e9927e916791f93687b97db3ff98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 24 10:25:53 2009 -0600
+
+ Explicitly check for libGLU.
+
+commit 706a6325d723c4c1be10617066fcef573579d1ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 24 01:59:54 2009 -0600
+
+ Minor optimizations.
+
+commit 823b5039b87fa7e6f2e81d482be64d3d97033a45
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 24 01:52:12 2009 -0600
+
+ Simplify dealiasing code.
+
+commit 97650dfc4f7abc5ad59211c950af12814ac5b5bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 24 00:35:32 2009 -0600
+
+ Optimize dealiasing of 3D rendered non-RGB images.
+
+commit f165ec0afefae7ecea4e37c9af29fa0a37c9c1be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 22 11:42:32 2009 -0600
+
+ Rename test member function.
+
+commit 6a4117c34454fcea9ae36deb1deb8e414671cc6b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 22 11:33:48 2009 -0600
+
+ Add example of defining a builtin asy struct.
+
+commit 2619bcb22197f775969cf74592fa7cb8e4ff6be6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 22 10:52:30 2009 -0600
+
+ Implement value-based addVariable routine.
+
+commit 9c8f589aa2d86b1aff40c6728c83e9aaf43f5958
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 19 13:56:00 2009 -0600
+
+ Check recursion depth.
+
+commit eb431fe8e6ed67671cc1e3eacfae2de03c2486a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 19 10:34:12 2009 -0600
+
+ Continue subdivision tests if zero radius of curvature is encountered.
+
+commit 9d592def12e244517181d829faca2adc5cd0b44b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 18 23:52:51 2009 -0600
+
+ Change basealign so that "ace" and "acg" are always typeset at the same
+ location.
+
+commit 3744427dbe7812dee4a61d0d0252f699934b12c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 18 16:57:05 2009 -0600
+
+ Handle more degenerate cases.
+
+commit 8306a21151548caaa0b1ba61af3a989005d2b941
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 18 15:42:21 2009 -0600
+
+ Handle degenerate paths.
+
+commit b4bc71fa46ceacf2e234512a90e0bb7eecada7b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 18 15:28:41 2009 -0600
+
+ Improve adaptive algorithm used for rendering thick lines and tubes.
+
+commit c379f3146746b44906b954321758b806ec6d30af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 18 06:56:28 2009 -0600
+
+ Fix circle ambiguity.
+
+commit 8b80557caaa9dd6b97db1374d6a064d0b0b1aa70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 17 22:15:06 2009 -0600
+
+ Change perspective.
+
+commit b413e18e35ca518d0a017110ba285ef55923755b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 17 22:07:43 2009 -0600
+
+ Fix URL.
+
+commit b72747f967b0d802b64c8a0c2c51589c7bb59c51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 17 22:05:46 2009 -0600
+
+ Use parametric mesh.
+
+commit 7a10ae1569c2546669841317edcac32ec81ff215
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 17 21:28:45 2009 -0600
+
+ Rename example; use smooth coloring.
+
+commit 5254c9cebe241339b2a58944a66974c8680348b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 15 23:35:07 2009 -0600
+
+ Add example.
+
+commit 6d1a060fb1d619965b0ccc6897232bb24eb282a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 15 23:28:57 2009 -0600
+
+ Make boolean condition suppress function evaluation for linearly
+ interpolated surfaces.
+
+commit 527ec35a4f884dc8f4f3db61a24a87c24c0e4f85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 13 08:48:38 2009 -0600
+
+ Add operator +(pen, pen[]) and operator +(pen[], pen) and example.
+
+commit 056aa9ccdb8a865d2b90b33eaba2007d0fe65dfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 12 23:04:57 2009 -0600
+
+ Generate mpg file.
+
+commit 757885c24fcc69bb74ae3e1b4f0e2192675b05d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 12 21:32:34 2009 -0600
+
+ Produce an animated gif rather than an inline PDF movie (about 1/4 as big).
+
+commit 4fe5f1b0e6ec434224996a426351e52049e34cb6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 12 17:11:56 2009 -0600
+
+ Avoid nullpath3 has no points error when label is given nullpath3.
+
+commit 0f936bf8f955acd4aebdd2a952c86a18320d44a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 11 01:32:31 2009 -0600
+
+ Set dotgranularity=0 in cube example to force dots to be rendered as spheres.
+
+commit 9cf2b91fa3c126cb9fb884e3d57a6ce726c45993
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 22:03:19 2009 -0600
+
+ Improve example to use a better (smooth) approximation to a torus.
+
+commit 522ed7412ad11b90fcff13eafc39d02c8a351125
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 15:10:27 2009 -0600
+
+ Increment version to 1.71svn.
+
+commit 3b34b09b00bc857702b2daf751f81905ca6d4858
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 12:57:02 2009 -0600
+
+ Add node.
+
+commit c7dc01717e31922693fda55e61791cf673068458
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 11:35:11 2009 -0600
+
+ Optimize and improve valid range of choose(int n, int k).
+
+commit 8309c1f5916ec1e97a77f0a4c4f95e62857e79f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 10:48:31 2009 -0600
+
+ Update example.
+
+commit 58b97e553f6289842ec696ad9651939b50fd5e05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 09:52:28 2009 -0600
+
+ Handle spaces in incoming prefix.
+
+ Add prefix arguments to fit function.
+
+commit bf4d3adb2d37c7ba52677f65cfcc8fd60c398e88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 09:40:07 2009 -0600
+
+ Handle spaces in filenames when using pdflatex.
+
+commit a2f84e9d58da5b279e8040134757b447cc280726
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 10 00:27:03 2009 -0600
+
+ Work around animation problems with spaces in filenames.
+
+commit 785dea67b0655ccc4f8742e9cbb68efc5119d4c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 9 23:57:44 2009 -0600
+
+ Add PenMargin2, etc., for planar arrowhead types like DefaultHead2.
+
+commit ddd85786d17a6b9a2cae12774a682982a38db7a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 9 17:57:52 2009 -0600
+
+ Add labelpath3 module for typesetting curved labels in 3D and example,
+ courtesy of Jens Schwaiger.
+
+commit 11e92513bfe3522596bb6679b6cf2239e40f82f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 9 16:32:17 2009 -0600
+
+ Center target of teapot.
+
+commit e42cfe2edbcfcd564419d8d86af10f9122746667
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 9 16:30:01 2009 -0600
+
+ Add bool center=false parameter to projections to allow one to
+ automatically center the target within the bounding volume.
+
+commit 4606c09664ef8f7144529d3c78831c92160de3eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 7 21:05:53 2009 -0600
+
+ Fix clipping example.
+
+commit 2ccddae8a2610c9e84dc098708a9cc7794190355
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 7 16:02:10 2009 -0600
+
+ Minor update.
+
+commit f1fa0d1eeef5508d9e4fa54b281e3d7d4dfe4368
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 7 16:00:46 2009 -0600
+
+ Use locale.
+
+commit fd783acf33724de96f7aa6ee71d719341d1779ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 7 15:46:44 2009 -0600
+
+ More updates.
+
+commit 5f329206530828a782bd4b0d078232b9387dc250
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 7 15:41:08 2009 -0600
+
+ Fix typos.
+
+commit 4fd4bd5bfa094a0ea7e2caa78d0b58c9f59a2cbc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 15:55:08 2009 -0600
+
+ Reserve surface(triple[][] P) for graphing a surface described by a matrix;
+ use surface(patch(P)) instead.
+
+commit 58b990d3824d09a231c8a747ac651713146ca122
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 03:39:14 2009 -0600
+
+ Work around old compiler bug.
+
+commit 5b2a0b5fea94b7852d546799ab2b119e2abe0379
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 03:37:42 2009 -0600
+
+ Increment version to 1.70svn.
+
+commit 3df96eddb725d40fa18157197e6645109209db8b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 02:02:44 2009 -0600
+
+ Add torus animation.
+
+commit 751007ecbd03b344dca139eaf9d89767a1e090ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 01:53:38 2009 -0600
+
+ Reduce memory usage.
+
+commit d20badd0879006dca0107bd44d1eefc8def4caa5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 01:07:52 2009 -0600
+
+ Force outformat="pdf" when producing PDF animations.
+
+commit 91fba1067f0cb496ac6ab02c66247f1bb88bc5b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 6 00:30:10 2009 -0600
+
+ Change - delimiter to + for animation frames and preview images.
+
+commit 9f143ecebab158f28117bbd9e2496541cda147f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 5 23:36:07 2009 -0600
+
+ Move extension routine and infinity constant to C++ code.
+
+commit dce7d4684b60fbd49411678e41acd91fe2aae518
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 5 22:50:15 2009 -0600
+
+ Work around hyperref option clash.
+
+commit b5c792a1ef897cb3541fbbbfb89a5c72d1f6ae1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 5 21:26:41 2009 -0600
+
+ Catch handled_errors (e.g. from ~psfile()) during throw handled_error().
+
+commit 4e9be4d6c89ad820c73fc42a231eb10fa4ef2910
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 5 17:08:33 2009 -0600
+
+ Fix more animation prefix issues.
+
+commit 9e4c35e7de336022485ae806b38740cd926068ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 5 14:19:38 2009 -0600
+
+ Keep keep flag.
+
+commit 22ae02a38ed6e3ffe30dc921ba51b21612cadeda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 5 13:21:13 2009 -0600
+
+ Move 3D code out of animation.asy.
+
+commit a52a6633d81fc3d7d04d14b485d593cd20cf0a35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 5 12:02:17 2009 -0600
+
+ Fix inline pdf animations with multipage=false.
+
+ Fix global scaling of 3D animations.
+
+ Add heatequation and earthmoon examples.
+
+commit 443cc79149c736d66ce4d47db1a4a84ab594b101
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 14:26:55 2009 -0600
+
+ Minor optimization.
+
+commit 152f712891e81f1fecbaa91cc499364d0487cd85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 14:24:31 2009 -0600
+
+ Use a lookup table to compute factorial(int n).
+
+commit 2f93f82b0b032cd2c8996c1d28737173a2ab175d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 12:50:14 2009 -0600
+
+ Implement miterlimit.
+
+commit a41cc4546b6313f99be1b65573182e44318f1093
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 11:26:43 2009 -0600
+
+ Fix use of baseline.
+
+commit 4eaf887ab95fe68fa9ccf39b94bc1d10c0db0478
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 10:44:00 2009 -0600
+
+ Disable old lights for multiple exports.
+
+commit fd244ea8555fc0fdb92c87f3388e5c3946f781a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 08:44:15 2009 -0600
+
+ Fix warning message.
+
+commit 7046900634a2fc8d5f5f609175f16b8edc195a1c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 08:41:58 2009 -0600
+
+ Add missing conditional.
+
+commit 612728718a6fa71065a7dbc3757d772847410e44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 00:31:39 2009 -0600
+
+ Improve example.
+
+commit f930ee18a50667ee5b3655a8eda1be651d5006df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 00:24:39 2009 -0600
+
+ Remove unnecessary parameter.
+
+commit d248a41b7792d2d70167d4b6d3d0495c0989b861
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 4 00:22:37 2009 -0600
+
+ Fix type conflict by replacing settings.divisor with purge(divisor=0);
+ divisor=0 means to use the previously set divisor (which defaults to 2, or the
+ value specified on the command line with the -divisor option).
+
+commit 5e50b840f02bf29da1730c72df3d65954afa90e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 3 22:06:22 2009 -0600
+
+ Increase orthographic viewportfactor.
+
+commit e0963eaad05890f3fda42a3bbbaaa1f65b53db08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 2 00:05:50 2009 -0600
+
+ Add missing 3D add function.
+
+ Increase nsamples to 32.
+
+ Remove nonselfintersecting restriction.
+
+commit fccd5702d3caef79ceda7e05806e1a68139a6920
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 1 02:38:09 2009 -0600
+
+ Fix splitting.
+
+commit 8cee60600708d3947f899b578400c8a626e0c2e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 20:31:48 2009 -0600
+
+ Increase fuzz; use static dxmin.
+
+commit bb8cbc4f3a32442b4453f8b32a5dafa585a0fde6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 17:32:16 2009 -0600
+
+ Reorder tests.
+
+commit 9970a0a8a174f9172cba01cbcb1cc81a94e287e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 17:27:53 2009 -0600
+
+ Check for triangles first.
+
+commit be4fc623d49613c243c098cc38bf8854e83794d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 16:54:09 2009 -0600
+
+ Split randomly to avoid returning a degenerate patch.
+
+commit f53b1dd96ad99531902c70c0a8753b07953c6057
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 16:21:13 2009 -0600
+
+ Fix interactive rendering.
+
+commit 72ce918958da2a16be791ee2e1d70fd9d83c15f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 02:32:14 2009 -0600
+
+ Once an internal degeneracy is found, don't check any more boundary cases.
+
+commit 069759abc268c4fa3f0c871b141582afd76788ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 01:45:23 2009 -0600
+
+ Increase nsamples.
+
+commit 1afb44a8645d304ce33144e2271fc75ba02633c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 31 00:39:32 2009 -0600
+
+ Split at the worst boundary degeneracy.
+
+commit 82e73caf64ea5ccd2a9b718a67a4323fe5168966
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 30 12:29:10 2009 -0600
+
+ Add unicode option to make new versions of hyperref happy.
+
+commit e683a4d1cfd75925b27ff38361e7c7806e84f072
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 30 08:44:30 2009 -0600
+
+ Pass animate the correct file name.
+
+commit 1ba731b25bbbe2b5a161e75be0dda0395e795166
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 23:39:56 2009 -0600
+
+ Fix floating point exception caused by attempt to split paths of length 0.
+
+commit 1a124b08ec44272e3d8591081bfd196bab64c338
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 23:07:13 2009 -0600
+
+ Move inside(path, pen fillrule=currentpen) to plain_paths.asy.
+
+commit e13cec520205c06c787dfa1a390c07a85e7245de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 20:57:00 2009 -0600
+
+ Fix defaultpen(evenodd).
+
+commit 180fb560a67a14747113ad4ab033fb348d544390
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 17:00:07 2009 -0600
+
+ Fix spurious "undefined" (on curve) return values from windingnumber;
+ optimize handling of straight segments.
+
+commit a575a6fc1b88edb18a01616bcf473695c429999c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 14:45:08 2009 -0600
+
+ Always define glthread.
+
+commit d8f464fc32c76929510f34d41de82117564a8723
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 10:06:33 2009 -0600
+
+ Release version 1.06 of asymptote.sty to fix undefined \ASYbox bug.
+
+commit 5b996b037bcf7d0f23a1e7e0fe8e161849f85f06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 00:30:53 2009 -0600
+
+ Automatically apply bezulate to path arrays. Surfaces should now be
+ constructed directly from paths (and paths arrays), without first calling
+ bezulate. An array of independent surfaces can still be constructed from a
+ path array using a loop.
+
+commit b80b2d3074dcaf68f82fd51571c4475e73548f43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 29 00:05:54 2009 -0600
+
+ Fix inside(path,pen).
+
+commit 6f4f738fb32e1a44cf43c80905308b77aa040c50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 23:35:26 2009 -0600
+
+ Add Orest's connect patch to fix nesting.
+
+commit a646731fad5a118d1464a6b62e366b8dffdd956a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 23:11:34 2009 -0600
+
+ Specify zerowindingnumber rule.
+
+commit 622937c19c1bd66f9c97771f105be7b73e6b33b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 23:09:13 2009 -0600
+
+ Improve inside(pair); add fillrule argument.
+
+commit 9fa25db9be336cf6019063dfea7e959d21a772e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 14:21:05 2009 -0600
+
+ Remove internal patch degeneracies by splitting.
+
+ Compute subpatches directly from control points.
+
+commit 195cbd6b9daab589520bf8f4319c04f42982a01c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 12:24:17 2009 -0600
+
+ Implement factorial and choose functions.
+
+commit 6447f273d215e1d4f488650b468de3c250bc7732
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 12:18:16 2009 -0600
+
+ Rename example; use orthographic projection.
+
+commit 78b068ae1390a2c89329281dfd668595ae9b03f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 12:15:09 2009 -0600
+
+ Make path(path3, pair(triple)) preserve straight flag.
+
+commit 2cb79dbf9585a541058e23047f79c09dd8af150d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 12:08:55 2009 -0600
+
+ Fix quit deadlock.
+
+commit d8125e4fa7af606cf6fcd7398b3a07b9aa41bad9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 28 00:11:09 2009 -0600
+
+ Increase fuzz to accomodate italic "k".
+
+commit 3a1f5a20fec2b085364dd4da3295f84ab3d52475
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Mar 27 21:56:17 2009 -0600
+
+ Fix connect() to ensure that removed regions do not contain an inner curve. Add fuzz to intersections().
+
+commit d4f6dddb855703ed9c11070c985c7bd735bd04be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 24 21:47:57 2009 -0600
+
+ Add surface constructor for multiple surfaces.
+
+commit 850b0ed10f2eed93e617b918269739136fc6281f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 24 21:32:54 2009 -0600
+
+ Add intersecting pipes example.
+
+ Update FAQ.
+
+commit ef5e8e4054b63c12b29352c930445d1bbfa59dbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 23 03:23:19 2009 -0600
+
+ Increment version to 1.69svn.
+
+commit e9bd6706f9bedf66c3d997b07707dd54a9eefde7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 23 02:07:01 2009 -0600
+
+ Update example.
+
+commit d73f25a4baa11d6d85364a2fd419f423f09cd032
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 23 01:45:58 2009 -0600
+
+ Illustrate automated camera and target computation.
+
+commit d777a813382fac58535de2c8223c80c84dd98bb0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 23 01:37:23 2009 -0600
+
+ Remove unnecessary index.
+
+commit f84b490d11d0cb509d778299a8f180a1ab579264
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 23 01:34:42 2009 -0600
+
+ Add support for and example of generating a 3D inline pdf movie.
+
+ Remove hyphen from animation file prefix for compatibility with animategraphics.
+
+ Force multipage=true in inlinetex mode.
+
+ Update definition of ASYanimategraphics.
+
+commit e10b91934bf65fa81f5e8edc34aaf0c720b3152b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 23 00:31:06 2009 -0600
+
+ Fix export deadlock.
+
+commit 587aa4f5bb4fb8f2afe4246e7e4d7bce78aa9904
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 22 21:42:52 2009 -0600
+
+ Don't automatically move camera with target.
+
+commit ace730baa7577af882835379f5bd4fbe937f9c17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 22 12:12:52 2009 -0600
+
+ Update example.
+
+commit d6667c3934ef2cd795037dd81c2301340520abef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 22 12:11:41 2009 -0600
+
+ Fix camera adjustment.
+
+commit d9d5da76552aac77955fbc5066296f8a998eaa72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 21 23:54:54 2009 -0600
+
+ Allow \par in a label.
+
+commit 1e4f2fe939058c6b832bc22903bca649638c665b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 21 23:49:23 2009 -0600
+
+ Update documentation.
+
+commit 9cd5a0fe84a5e068af1488f50c39d2b2720fc06d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 21 23:07:42 2009 -0600
+
+ Improve and generalize baseline.
+
+commit 74f9e6f899b075ad53f1ebcb6edd01bc57f2f107
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 20 23:26:20 2009 -0600
+
+ Look for exact intersections also when fuzz=0.
+
+commit 0638cdbfeabb2a803b09b82dd1471c1ea0876d49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 20 22:42:10 2009 -0600
+
+ Suppress spurious space.
+
+commit 04ae9df43413d6956ed3fbc97cc1e6c8751f48cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 20 22:28:18 2009 -0600
+
+ Standardize sqrtEpsilon.
+
+commit f16441c237fbfa983d69a569fad449d782a8770e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 20 22:15:40 2009 -0600
+
+ Remove unused line.
+
+commit 7c3732148f30c6d9f9fa888e6b7f780aa490dc08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 20 22:14:19 2009 -0600
+
+ Improve handling of intersection fuzz.
+
+commit 789ab1c54c66973fcd061dbccdb6b4c397b5bb69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 20 14:57:34 2009 -0600
+
+ Handle invisible material.
+
+commit 5e3b8fdec620ed0e7ed38e01e193269dd97d6fe2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 20 14:28:23 2009 -0600
+
+ Respect user-specified step value.
+
+commit 05b16339d6790f96f0657b38dc194efe1d01f662
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 19 02:59:14 2009 -0600
+
+ Increment version to 1.68svn.
+
+commit b8c188a2ff0c6d8acd87da23c27bad9ebb0b42bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 19 01:33:53 2009 -0600
+
+ Fix 3D animations with render > 0.
+
+commit 823eb84ed3fe32c0188596227f1c56c573b46f72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 19 00:40:40 2009 -0600
+
+ Don't force C:\Documents and Settings\bowman in asy.bat
+
+commit 87a2b41240328f478ca8bf3b256e6789930a3abe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 18 14:18:11 2009 -0600
+
+ Remove normal fuzz.
+
+commit ce6df332a9c0f9010ccf9d1c9f6e7083b7f539b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 18 02:51:53 2009 -0600
+
+ Fix overlap detection internal control points for short paths.
+
+commit a8cc7c427cac46ace2db0070645385718a09028f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 18 01:23:56 2009 -0600
+
+ Add file missed from last revision.
+
+commit e6766a83c38ada605086a98cf3f06b71eb2b29cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 18 01:01:08 2009 -0600
+
+ Make intersection routines respect fuzz.
+
+commit 9b3a5104ccc45a972fbd776a589f13d8e42f5bde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 15 17:20:04 2009 -0600
+
+ Simplify normal calculation slightly.
+
+commit 460b9eed16912fcaa5753bf84679620335c8ca5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 15 15:32:07 2009 -0600
+
+ Reduce Fuzz.
+
+commit 30566f000cf574ac193f65f1a9846d4ebc5f5f39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 15 15:01:04 2009 -0600
+
+ Allow prc output if render > 0.
+
+commit 4cb2f03752fb95986e981e558be71f8d0db7d5a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 15 00:09:54 2009 -0600
+
+ Implement settings.auto3D (default true) so that one can disable the poster
+ option of movie15.sty.
+
+commit c026e07e6a9067e1b1047f4027849305ae6dbc02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 15 00:05:14 2009 -0600
+
+ Increase fuzz.
+
+commit 594a12ce972e648dc8b66c295fad2d330f6c1444
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 14 23:23:00 2009 -0600
+
+ Detect and fix remaining cases of patch overlap due to normal reversal,
+ using Rolle's theorem and a quartic root solve.
+
+commit 3b2700c4a800e6de2eb6ab08e0a7de93e1d38069
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 14 23:09:29 2009 -0600
+
+ Detect numerical roots at infinity; increase Fuzz.
+
+commit 8279587db2c825391fc51c85b22db684b3ef1fb7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 14 23:00:31 2009 -0600
+
+ Make subpath preserve straight flag; optimize splitCubic for straight segments.
+
+ Fix handling of straight flag in operator &(path,cycleToken); do nothing if
+ path is already cyclic.
+
+ Implement pair versions of Bezier functions.
+
+commit 8361c768a73d9dc693e71b9372db2de0b5c20f7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 14 15:25:45 2009 -0600
+
+ Fix segmentation faults with operations on guide g=cycle.
+
+commit db843913d4afd6861ee0649456ff8008928f506f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Mar 14 11:49:45 2009 -0600
+
+ Speed up curve sorting.
+
+commit 26c1aa3481dd6878716e8d46f3924b5137f61fce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 13 15:02:45 2009 -0600
+
+ Fix buildcycle endpoints.
+
+commit cfe2ab7253439844c47bb0f45a2bfff4b4831df6
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Mar 11 21:44:52 2009 -0600
+
+ Use bounding box size to determine whether points are duplicates.
+
+commit 110ab7d63f8346830c11276b1c0d4133f5bc825b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 11 01:47:57 2009 -0600
+
+ Force planar flag for arrow construction.
+
+commit 2511368422abcb3be6500d2fcc8bea79e031ed12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 11 01:33:51 2009 -0600
+
+ Remove another degenerate segment.
+
+commit e1cf02273301e2a7342006b9aeb6cbf41544d842
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 11 01:25:36 2009 -0600
+
+ Work around bezulate bug by removing degeneracy.
+
+commit 42fa995edf293de9162db70a15c3bd3368a79ea9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 11 00:18:34 2009 -0600
+
+ Fix planar surfaces.
+
+commit ad59550839cb6c72c56a6716a94943119db54928
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 10 23:45:25 2009 -0600
+
+ Simplify surface constructors; update documentation.
+
+commit f75e88bde5cf608232940a708263d3272b4b3d37
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 10 22:23:19 2009 -0600
+
+ Update examples.
+
+commit 374fe5ba6ec9c625e879adcbd4ac575c62001860
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 10 22:06:09 2009 -0600
+
+ Enable poster mode only when there is no rendered preview image.
+
+commit e54a57e797193f26b69165636a686337259c7f9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 10 21:34:37 2009 -0600
+
+ Add termination tests.
+
+commit 619a3195f7b333f91189349f8b19a7fabe08a7d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 10 21:34:12 2009 -0600
+
+ Increase bezulate fuzz; add termination tests.
+
+commit db838100431fe50516bf3ba17b7ccf9d7b7409c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 10 14:04:32 2009 -0600
+
+ Add Align constant.
+
+commit e12fcc1ca69c59d1d49446c6fa2b91d458634512
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 10 02:54:16 2009 -0600
+
+ Fix most instances of selfoverlapping patches.
+
+commit 9cb3e7a170ea796feda2023fc9a9aaa69daf27d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 9 21:38:52 2009 -0600
+
+ Make axial and radial shading respect -gray, etc.
+
+commit 9e40719812e31103ec3f4a5e39b06148270cc2df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 9 00:07:48 2009 -0600
+
+ Fix texpath control points for cyclic segments; respect straight flag.
+
+commit db6f45dc098f8b24df43b0586e4438f241afedeb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 8 16:11:51 2009 -0600
+
+ Slightly simplify normal calculation.
+
+commit 71e1c95735a2ba23c19e092415baff80edf4d514
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 8 12:03:26 2009 -0600
+
+ Make default viewportwidth \the\linewidth in inline mode and 0 in attached mode.
+
+ Document asy environment options in asymptote.sty version 1.04.
+
+commit a06740433ebde75644e27f3e9466468c5e1d90a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 8 09:23:09 2009 -0600
+
+ Simplify tick calculation.
+
+commit 83d2fa180a2bdca1ef8c7ac05a345caa71753215
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 8 02:18:52 2009 -0600
+
+ Improve tick selection.
+
+commit f1e40619a13f3ab6a19a0acb8e2f8b1cc75a1577
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 8 01:02:42 2009 -0600
+
+ Colorize example.
+
+commit c2c2eb092db44f4e3cbbc5b59c62298d639d0d1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 21:17:56 2009 -0600
+
+ Reinstate original views.
+
+commit 81fce38d02dc3158eb728636c8007cd7d8ff9dca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 21:10:03 2009 -0600
+
+ Fix camera adjustment.
+
+commit 02eb5bcfcca0d0378e385f4137226e8946b2b8ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 16:23:58 2009 -0600
+
+ Support keyval options width, height, viewportwidth, viewportheight, and
+ attach in asy environment asymptote.sty.
+
+ Remove obsolete asyattach environment.
+
+ Move viewportsize to plain_picture.asy to support asymptote.sty.
+
+commit 24e9b23a742650c682357ecdd303bd10fd57d390
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 12:14:05 2009 -0600
+
+ Better fix for unextended axes limits.
+
+commit 78581b7e40528f7eb1a42a0517690368931d999f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 10:10:37 2009 -0600
+
+ Update documentation of crop.
+
+commit c01d0084a1d3156957c997c89100d4d5b57ec8f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 02:46:18 2009 -0600
+
+ Add example of a surface drawn using irregular data read from a file.
+
+commit 9c01ec16add18b92fd50bb4674cbadde10329bb6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 02:23:39 2009 -0600
+
+ Revert last change.
+
+commit 47aa02a0fd237e6267d018ddab025fcdb408d3b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 01:07:03 2009 -0600
+
+ Fix unextended axes limits and tick generation.
+
+commit ea3cf29d5dc68f65db8f3c0835c7a7275b035969
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 00:45:35 2009 -0600
+
+ Avoid redundant camera adjustment messages.
+
+ Increase camerafactor to 2 again.
+
+commit 38dc72be7a5d0b19888e15e5b64a54efae1d957a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 7 00:19:49 2009 -0600
+
+ Check crop argument.
+
+commit 82a5510bd196c1bd13e176ceac37f5a3d52e7d0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 6 23:52:12 2009 -0600
+
+ Improve automatic camera adjustment: relocate target to the center of
+ the bounding box, if it lies outside, and reposition camera when aspect
+ ratio is not preserved.
+
+commit 2311c16d538c5e25467da6aa029a05dbfffe4854
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 6 01:14:45 2009 -0600
+
+ Allow the user to specify a minimum viewportsize.
+
+commit 688371c4a8696f5dcc83215f9de890adf14de341
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 6 01:06:16 2009 -0600
+
+ Use a single call to clip in limits.
+
+commit 0026ea88a43ca42d078daaf271a611a6fca599be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 6 00:56:25 2009 -0600
+
+ Fix behaviour of xlimits(Crop) and ylimits(Crop) under picture transformation.
+
+commit 70429fc62beac0c19e61982cd9bf676db905753d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 4 03:44:31 2009 -0600
+
+ Increase camerafactor.
+
+commit ce2861d0882f816900ec6893aedea46a5541899c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 4 03:18:49 2009 -0600
+
+ Improve automatic camera adjustment.
+
+commit 729c7308c0db8806392b48506da22d6e9989a459
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 4 02:09:19 2009 -0600
+
+ Work around intermittent hang on exit.
+
+commit 0902c55dc095a0147b7a9feb32b20cdfb74f347d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 3 02:19:52 2009 -0600
+
+ Make attached images printable.
+
+commit 8c4f30913cf60f1b963fa6b4c34b045d23783a39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 2 19:03:03 2009 -0600
+
+ Turn poster off when we have our own preview image.
+
+ Fix viewportmargin.
+
+ Remove unwanted camera rescaling.
+
+commit 990b6ee4eba7a1b9033d87489f15e284de5b823d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 2 18:49:36 2009 -0600
+
+ Fix spurious annotation question marks and print preview problems
+ by removing workaround for BBox bug in obsolete 2008/01/16 version of
+ movie15.sty. The now widely available 2008/10/08 version of movie15.sty is
+ now compulsory.
+
+commit 5ad2d615fa2da167e76a7bd784fcd57e8af41bef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 2 15:45:00 2009 -0600
+
+ Fix slanted ticks.
+
+commit 9316b6e0aba874d635db72cf538d1cf718741b5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 1 23:58:58 2009 -0600
+
+ Fix animation prefix.
+
+commit ae5315ac620c3aa15e47e16db87cc7b234aec103
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 1 17:32:54 2009 -0600
+
+ Fix planar arrows for 2D projections.
+
+commit 30f6e7f858cf09de210fe6d56dae2752c3698c5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 1 17:01:58 2009 -0600
+
+ Allow one to disable poster option.
+
+commit 09782ec523dd2e89001cfc9b2a3ff24b8db314bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 27 17:32:54 2009 -0600
+
+ Resize example.
+
+commit 6556c592c360ab5ab045004a37cc4cf40ebe6bca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 27 15:43:51 2009 -0600
+
+ Don't hide convert errors.
+
+commit 2ca31a4e8eaeadcfa8c513fb2b03bc8271a97892
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 26 23:09:51 2009 -0600
+
+ Add example (contributed by Orest Shardt).
+
+commit 88ca0f83d5a114a730aa65578e3e19d067771d74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 26 17:23:44 2009 -0600
+
+ Increment version to 1.67svn.
+
+commit dae4c85870f84c1ed6dd1c139d3408d2cac88b34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 26 16:00:38 2009 -0600
+
+ Fix outprefix.
+
+commit 6a5de0c624a8638930b1216b5695886bce86a18f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 26 10:01:58 2009 -0600
+
+ Remove animation optimization by default.
+
+ Under MSWindows, suppress call to animate since it requires XWindows.
+
+commit 99ea30e4d2f14fcbdef3246301c2010e6e1872cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 26 08:50:25 2009 -0600
+
+ Add optional direction argument to three-dimensional bars.
+
+commit a9d59eb9158368824e68c96f5988f279f7dda53e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 26 08:45:58 2009 -0600
+
+ Avoid division by zero when NColors=1.
+
+commit 69192fae67050b8588203e1c60b3ab06f86fe26e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 26 06:45:26 2009 -0600
+
+ Fix alignment bug under pdflatex due to missing %.
+
+commit 6bb6ecb0218cdf77f474df10bf763c3a89ec111e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 25 23:04:31 2009 -0600
+
+ Change guides into paths; update to LGPL.
+
+commit c48ca48643148db89071d9446c8d0a1bc0ef0ef2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 25 17:21:27 2009 -0600
+
+ Use integer division.
+
+commit ee3c6b650e1a91aff74ecba6996da5987af09db7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 25 17:07:20 2009 -0600
+
+ Remove "named argument may be mistaken for assignment" debugging warning as
+ it discourages the use of named arguments and detracts from the usefulness of
+ the -d option.
+
+commit 389c5fb20a8aa07ef5eead1a95832fb657070105
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 25 16:06:21 2009 -0600
+
+ Revert to interpolating function at midpoints.
+
+commit 6cc5fc9f62876be9fc734340932fa4fa229808b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 24 10:51:11 2009 -0600
+
+ Add optional normal argument to DefaultHead2, HookHead2, and TeXHead2.
+
+commit bdbd01b5c6fe36d7e03aa516da5e9880a85ce4b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 24 01:47:00 2009 -0600
+
+ Fix Arrow3(TeXHead2).
+
+commit 1321c2fd18a8868b4c968ba89dff10858a8879ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 24 01:35:08 2009 -0600
+
+ Fix alignment of DefaultHead2, HookHead2, and TeXHead2 arrowheads.
+
+commit d42d0e22364585fb5f034b151adf3a7b17085c14
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 23 01:36:02 2009 -0600
+
+ Improve thin 3D arrow handling.
+
+commit ac890dbbd19be365d45a4b46038ee04fb50dc54c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 23 00:01:42 2009 -0600
+
+ Make filltype a structure to allow extraction of type and pen parameters.
+
+ Improve the appearance of DefaultHead2, HookHead2, and TeXHead2 (particularly
+ with curved paths); standardize their usage with their 2D counterparts.
+
+ Fix MidArcArrow(TeXHead) sizing.
+
+commit 04c4806b61f68cf9f3df17ce8a6232a33909bca6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 22 21:32:38 2009 -0600
+
+ Untabify.
+
+commit 43e22d83c2f82739550b7b943770a3f30934b1d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 21:30:41 2009 -0600
+
+ Upgrade license to LPGL, as per email from Philippe.
+
+commit 31e799c42b85817afd1eb468269fc7b86dc0fb22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 17:39:27 2009 -0600
+
+ Retune 3D arrow parameters.
+
+commit b0667031a8755d08adea8132ddb143d538c7b2bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 17:03:22 2009 -0600
+
+ Upgrade global license from GPL to LPGL (except as noted within individual
+ files).
+
+commit 5523eb20c73989293429387cae06319c96e5c5b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 16:37:09 2009 -0600
+
+ Remove obsolete featpost3D.asy module.
+
+commit 64757f0b6dd69ed1e837c0d08ece5877f87af700
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 15:56:33 2009 -0600
+
+ Add bool autoadjust=true argument to perspective projection constructors.
+
+commit e6f290616e09b9aa44a0b55b9b74299f99eefe4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 13:26:15 2009 -0600
+
+ Fix TeXHead alignment for curved arrows along with endpoint appearance.
+
+commit b57f0e9ad0898cfdec851911fbac70ed1c4f5324
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 11:46:29 2009 -0600
+
+ Add autoadjust flag to projections to disable automatic camera adjustment
+ (for experts only).
+
+commit 431e0a5ec4fddc168199226dd41564e3fdf41a62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 11:28:25 2009 -0600
+
+ Fix transverse vs. longitudinal typo.
+
+ Add slight hysteresis to camera adjustment.
+
+ Always notify user if camera is moved, as transverse and longitudinal
+ slices will have to be (manually) recomputed using the new camera position.
+
+commit a4e964c92b8dd447c1146e7382b5b3ec72557dd5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 04:05:32 2009 -0600
+
+ Add 3D arrows example.
+
+commit fd67a7961ae8a339ca75d8cdbea2ceebef5552ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 21 03:21:58 2009 -0600
+
+ Fix appearance of TeXHead3 on curved paths.
+
+ Fix alignment of DefaultHead2, HookHead2, and TeXHead2 arrows.
+
+ Pass arrowheadpen to 2D arrow routines when settings.render=0.
+
+commit 00bc1d73f58646e2f23f5f4cf0149d157c52defd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 20 18:30:32 2009 -0600
+
+ Use abs(camera-target) rather than just the z component for camera adjustment.
+
+ Add showtarget parameter to projections.
+
+commit 014a1d03c801fa803bb5e297279483b097925ca3
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Feb 19 21:14:42 2009 -0600
+
+ Improve selecton of perpendicular vector.
+
+commit 5b846e76f5ac0313a81dea335d7600710743f482
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 19 17:46:20 2009 -0600
+
+ Fix typo.
+
+commit 902f2734304e84a1597f5215a929c20733ba2888
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 19 12:00:11 2009 -0600
+
+ Increment version to 1.66svn.
+
+commit 709ad6bb870e69511fa3b402a3477b1f2178e73b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 19 10:33:22 2009 -0600
+
+ Fix pdflatex output.
+
+ Implement xelatex engine.
+
+ Fix xelatex alignment.
+
+commit 9e19c35fde997a1a4d1a5705469fcbdc415b6fed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 19 02:19:28 2009 -0600
+
+ Increment version to 1.65svn
+
+commit 5e85772d82e096c8bc6df52d6f7fff900e60d665
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 19 01:24:03 2009 -0600
+
+ Force shipped=true also for pictures.
+
+ Install *.view files.
+
+commit 844b91404ec12d951246fdf05c3a8998669dbf44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 19 00:13:31 2009 -0600
+
+ Change default value of ysize parameter of asyinclude.
+
+commit 9625ea38a5e8c89861a31cae6ef63ef0b4dc2cdf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 19 00:08:44 2009 -0600
+
+ Add Protein Data Bank example that illustrates how to set predefined views.
+
+commit 5cc82637149d0952582edf6849451575fba35f3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 23:13:48 2009 -0600
+
+ Change dots to underscores in movie15.sty file names.
+
+commit 9dbbac7fdab37f6967232dda8e299b96b0adc3fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 22:03:22 2009 -0600
+
+ Add text of LGPL license for PRC code; LICENSE is in parent directory.
+
+commit a09d1c1a35352d51ab4906aa904a153bce91a10c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 22:01:08 2009 -0600
+
+ Upgrade license of PRC code from GPL to LGPL (agreed to by Orest).
+
+commit 6f376fee744b97dd4e75672304ed265f145edd79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 21:27:47 2009 -0600
+
+ Update FAQ.
+
+commit 1d9c28b6f19f5d762b6aad2e81e4792ce5c311a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 20:38:33 2009 -0600
+
+ Fix file path.
+
+commit 8944f939542c801fd26b986de5593c4c846491d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 20:32:41 2009 -0600
+
+ Add interactive 3D examples to intro.asy.
+
+ Make GaussianSurface smooth.
+
+commit 9bd9020de556be40f447c0dccc592be0e8965f3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 16:06:16 2009 -0600
+
+ Strip directory from animation prefix.
+
+ Don't delete generated animation.pdf file.
+
+commit e3151ea29894774140164fd929258085db87e513
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 08:58:32 2009 -0600
+
+ Add support for xelatex pdf specials, using the "literal" keyword.
+
+commit 17dc9dbf0c34cadde1425947ce0417a5ff03b4f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 18 08:38:48 2009 -0600
+
+ Generate PythagoreanTree if needed.
+
+commit f4fd594c8f0ef695d457ba6cf262d55edcea8b91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 17 22:34:10 2009 -0600
+
+ Don't force target to be part of control volume for absolute projections.
+
+commit 66fd72aecc79a00cf89a6e1f7b990e3b3f667a60
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 17 22:25:41 2009 -0600
+
+ Increment version to 1.64svn.
+
+commit 4300efa1d0b99432dfcdc47cc5345bd491478706
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 17 20:51:20 2009 -0600
+
+ Force the target position to be inside the bounding volume.
+
+ Remove duplicate definition of rectify(triple).
+
+commit e3cc6bf9d4d8fa34e2755d0ddaf2636cafc6192a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 17 17:37:06 2009 -0600
+
+ Fix handling of invisible surfaces.
+
+commit 26e310e850ea3c9bd5ece5faf3df72217e89b75c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 17 10:07:42 2009 -0600
+
+ Fix synchronization of interactive rendering.
+
+commit b797cbbe7c0f43e7bf054acd484110259737abc0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 17 02:05:33 2009 -0600
+
+ Avoid spurious xelatex warning messages due to null (placeholder) graphics
+ files.
+
+ Add patched version of movie15.sty for xelatex users' convenience.
+
+ Simplify embed.asy.
+
+commit 6dfbfac2d7e8f1c5234e4bc3d5fda906fb8efe2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 17 01:30:54 2009 -0600
+
+ Improve guide collection for non-midpoint case.
+
+commit 333afac78848c4bddfe2aa42cb2656fa521eec9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 15 13:20:10 2009 -0600
+
+ Generalize definition of middle to arbitrary quadrilaterals.
+
+ Avoid need for interpolating function at cell midpoint; use 2 triangles instead.
+
+ Use nmesh instead of (poorly named) ncell parameter for 3D contours.
+
+commit 743db1d76b55182cb33edc23fece8466b85212f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 15 13:13:24 2009 -0600
+
+ Handle degenerate and nondegenerate rendering consistently.
+
+commit c5fd7b5465551828e93a812e8d07fcba1e5b3396
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 14 12:22:48 2009 -0600
+
+ Implement complex gamma function in C++ code.
+
+ Add interactive 3D surface of revolution example to slidedemo.
+
+commit 85ed3b5790ddf7d44af6bde3000df7d142c7256b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 14 10:58:01 2009 -0600
+
+ Disable graphic generation when view=true.
+
+commit 52149357e57a56ecbaee9e594d574bda4749a60e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 13 01:10:23 2009 -0600
+
+ Add 3D (and other multimedia) support for xelatex.
+
+commit 1f7c14ac96ae1faa0ea06106b5af567c1593fed0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 13 00:54:37 2009 -0600
+
+ Improve pdf format detection.
+
+commit f394d80486877735f35a21cf17aad38fbbfe1f6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 13 00:49:37 2009 -0600
+
+ Fix preview generation.
+
+commit 2b1016f627b45298cb776e1480eb9adfe60fb7b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 12 23:42:05 2009 -0600
+
+ Automatically include rendered images when fitting nonprc pictures.
+
+commit 41b476d67efadc14a2ab16e17e0d1ce8b773b326
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 12 00:24:54 2009 -0600
+
+ Patch compilation errors in pstoedit-3.45.
+
+commit 78ec096135b4c6a2680c01ac70b890b53654642a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 12 00:16:52 2009 -0600
+
+ Replace old-style constructors with operator init.
+
+commit 6136dc64cf325d025f1c26559b1dd327b4d12b83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 11 23:01:19 2009 -0600
+
+ Add electromagnetic spectrum.
+
+ Make minor ticks work properly with custom logarithmic axes.
+
+commit 137677e8aa6e9763002d2bbdb0bca9d883b99339
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 11 17:17:38 2009 -0600
+
+ Don't report error on eof after reading 0 values from file.
+
+commit a6e6b4ed261bfc1146fc9245d3cc77085e26b2c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 11 16:55:26 2009 -0600
+
+ Handle one-column legends correctly (patch contributed by Martin Wiebusch).
+
+commit bc9f784dff27f6bffd20941b64594f4f5cfc58e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 11 16:33:45 2009 -0600
+
+ Fix pstoedit support: remove duplicate beginclip/endclip functions.
+
+commit 6b5a85386c4bb8987f7ce9ead2aa542e84383e76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 11 01:29:52 2009 -0600
+
+ Update unicode documentation.
+
+commit e48449c3a41cdbc148fa817dd408f90f9dbb8b68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 11 00:22:23 2009 -0600
+
+ Support xelatex again. Note that this experimental tex engine does not yet
+ support pdf specials (required for label clipping and label transforms)
+ or the movie15 package (required for 3D PDF files).
+
+commit 57fb0bf9cb05e70bafe2b8f1a61f226fa66813b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 9 01:16:59 2009 -0600
+
+ Increment version to 1.63svn.
+
+commit 05b8f1cdfce4ddd6f7fb064e353720388a8ad314
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 9 00:00:12 2009 -0600
+
+ Implement a pen rgb(string s) routine that returns a pen corresponding to a
+ given 6-character RGB hexidecimal string.
+
+commit a68637e6c82f5ce5171931a5c1a5359bb329e86d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 8 23:14:02 2009 -0600
+
+ Reformat C++ files.
+
+commit 46c4f8d767fda269a6965fd4594ae938254b9d76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 8 22:22:15 2009 -0600
+
+ Reformat and untabify base files.
+
+commit 5f3974b82a5e114737827bc4fdd9f0cbe405b968
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 8 11:19:04 2009 -0600
+
+ Add Label arguments to more of the dot routines.
+
+commit 301c79a5b6c68ca6bc7de0e7ae88177ddbce9f71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 7 14:08:26 2009 -0600
+
+ Add parametric version of markuniform.
+
+commit b08d2bd76c59e4f21bf7f0e9c80ee5b1cd8b8c2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 7 00:41:46 2009 -0600
+
+ Implement int hex(string s) function that casts a hexidecimal string to an
+ integer.
+
+commit 77595bbb56fc7489ccfa2123c3d33b19a43de9a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 6 20:04:56 2009 -0600
+
+ Add default picture argument.
+
+commit a5f6409777ceb4b76df34caa9d35aedef99ac5f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 5 03:38:31 2009 -0600
+
+ Fix asy -f pdf -o temp/venn.
+
+commit 1b3d770eb47e9a4fcce6b51aeb9d2ecc08bf8664
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 5 03:36:16 2009 -0600
+
+ Increment version to 1.62svn.
+
+commit bdfa3acd0bacbbbb11066c92504369f92e1f5c33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 5 02:35:32 2009 -0600
+
+ Prevent multiple shipouts in venn example.
+
+commit 8a08bc6ad839d86769c40d52fad154afd7f2db9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 23:43:29 2009 -0600
+
+ Change nopapersize.ps to use letterSize/a4size to work with the current
+ MiKTeX version of dvips, which does not support the DVIPSRC environment
+ variable.
+
+commit 8e7aebbb838904760d4d728b11818c3c5fa0e761
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 23:14:53 2009 -0600
+
+ Indent.
+
+commit 530aa12cdb6f173f18653d7ffd99b27bff870efd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 23:13:24 2009 -0600
+
+ Fix aspect ratio on re-entry.
+
+commit dfd1d4874c066e411710829a0eee9eaa6ffa3c74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 20:04:07 2009 -0600
+
+ Add Pentype function to return a pen of increasing colour and linetype.
+
+commit 9bae8efdc88b2842d4dbf27bbc516ed42a306f27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 18:50:25 2009 -0600
+
+ Fix typo in URL.
+
+commit b5118109e681c6a3fc30f53a1445ec938bc86dbe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 09:57:55 2009 -0600
+
+ Re-enable freeglut extensions to support user-specified multisampling again.
+
+commit cf2107e5fc31f77c688d0f3e2b54786ddc2c3559
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 09:47:24 2009 -0600
+
+ Destroy any existing export window before entering View mode.
+
+commit 871271ee9d21c2f90442a2d6bacb632079832488
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 00:46:20 2009 -0600
+
+ Remove spurious \phantom{+}.
+
+commit ae4540d47733b206d1de70982125423cc4dde4eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 4 00:33:34 2009 -0600
+
+ Fix asydir(); under CYGWIN.
+
+ Add missing CYGWIN prototype.
+
+commit 3a9e92a066756fb8ad252fd1935d955054943d37
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 3 23:53:23 2009 -0600
+
+ Remove -P pdf as this breaks file attachments.
+
+commit 810f6f845a864d4cddc2dc0d9e7502f6012e678a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 3 23:32:40 2009 -0600
+
+ Fix segmentation fault due to spurious window creation in export loop.
+
+commit ee48135b6016801872fd526b8ce26bb843807aa8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 3 23:27:54 2009 -0600
+
+ Add string[] to int[] ecast.
+
+commit 0e66e1673cac08a8bd71ebf49392a7f739a3f010
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 31 12:49:19 2009 -0600
+
+ Fix dvipsOptions.
+
+ Don't allow dvipsOptions to override -tnopapersize.
+
+commit 0cb84fd14cddaf20e930acc24cae3a2f7ee56b28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 31 11:18:22 2009 -0600
+
+ Update dvipdf to correspond to the latest ghostscript svn source.
+
+commit 6e67b82c4e07bfcd7c2ba9ceb26b3a797a2d5e4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 31 09:29:42 2009 -0600
+
+ Warn that silhouette routine is intended only for 2d projections.
+
+commit 764f7f92b8711a5c7da62797d5f3b3c75413a7c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 31 00:22:51 2009 -0600
+
+ Enforce the same zerowinding fillrule used by dvips.
+
+commit 54342b62220f756c79ec1716bf31c275a4cbeef2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 31 00:07:10 2009 -0600
+
+ Rename nosize to nopapersize for clarity.
+
+commit d0d1e6094c87254a93efd85363a38d95200f4f6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 30 23:58:28 2009 -0600
+
+ Workaround dvips misconfiguration in TeXlive 2008 (and possibly other new TeX
+ distributions) that introduces unwanted %%BeginPaperSize commands into the
+ EPS output.
+
+commit 0200020ab140143bedc07cf27baf8d2c47e3dba7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 30 17:26:56 2009 -0600
+
+ Reinstate -q (-quiet) option.
+
+ Update asymptote.py to use -interactive option.
+
+commit 93bcf2e4d0bec3afc58066273aeb9f5c2f90fda0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 27 15:38:53 2009 -0600
+
+ Work around dvips configuration errors on some systems by enforcing no
+ paper type comments.
+
+commit 80e59335e7ed42f326c06612f456a904d4acf327
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 27 09:40:48 2009 -0600
+
+ Rename file.
+
+commit aae56cc06b6d59a4c1b5dada20b29b739ac93b05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 23:17:28 2009 -0600
+
+ Increment version to 1.61svn.
+
+commit f13663d2bf1b956068f6d290284b3c38372a291a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 22:01:00 2009 -0600
+
+ Fix surface condition type.
+
+commit ac29281656284dd3687db1f6a93b82bae89ec239
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 18:58:00 2009 -0600
+
+ Simplify notation.
+
+commit 3b01508d946b86c3692173d844b7a9941f47880a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 18:12:17 2009 -0600
+
+ Remove diagnostics.
+
+commit 4520d29d9414c0dcaf479193c28f48e31184c943
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 18:11:23 2009 -0600
+
+ Improved marker alignment.
+
+commit faaefc8bccd2ecd01b0e9f0b3e8d4a63f5f512a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 17:48:24 2009 -0600
+
+ Force a new guide after omitting points in conditional graphs; avoid
+ spurious empty guides.
+
+commit caa1af28ceab79157c53a0c758accdd595ee30f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 17:00:49 2009 -0600
+
+ Improve axis label.
+
+commit 101ee3595eeefb53f2ecd6a117019d03ae9db5a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 16:59:40 2009 -0600
+
+ Simplify example.
+
+commit 4c8f0feb77e877116952cba3e86c2afb3a654584
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 16:56:55 2009 -0600
+
+ Add floor example.
+
+commit 758a700ec3a46e5382e4d95560ec6fdccedd1280
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 13:54:20 2009 -0600
+
+ Fix read from pipe failed error under MSDOS.
+
+commit 7a24e4671880b20b56e03feb491fb3ce779cd1ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 26 00:18:19 2009 -0600
+
+ Allow xasy to be run from a write-protected directory under UNIX again
+ by implementing broken (8.3) format tempdir workaround only for MSWindows.
+
+commit 5ff176eebba9c7cf103a0aa37f70bf45d8af81ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 25 09:58:27 2009 -0600
+
+ Catch out of memory errors.
+
+commit ecbd15211297bf751e7b42745d6f5b6de475c661
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 22:05:45 2009 -0600
+
+ Remove LocalWords from FAQ.
+
+commit 2eae4b4154364c1ae70a80a43fedd36f5efa40e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 18:46:47 2009 -0600
+
+ Recommend svn version of freeglut only for UNIX systems with graphics cards
+ that support multisampling.
+
+commit 8b2834aa4ba6d98806f5a723e801d17b0fcc4865
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 18:29:36 2009 -0600
+
+ Catch unhandled exception when exporting to write-protected directory.
+
+commit 9e307c6e5c7b27a8e2c7545e9034ab377cc7f990
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 16:21:27 2009 -0600
+
+ Modify yum instructions for obtaining most recent version of Asymptote.
+
+commit 52669b851dcf713cc2f117f1ecdfd674b0c062f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 15:57:49 2009 -0600
+
+ Use default for bool3 initializer.
+
+ Change condition array for graphs to bool3[].
+
+ Add more bool3 support functions.
+
+ Reformat base files.
+
+commit 50b00f2ce388f9a963744b8110b20fd71debd1e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 13:34:04 2009 -0600
+
+ Work around inability of movie15.sty package to handle spaces in filenames.
+
+commit 23298930e7cdbeee504ef3adb2f06dabd0a52e53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 12:07:14 2009 -0600
+
+ Add gettriple routine.
+
+commit 1ee716c8a7303a7e2d2c06ce171948121511b96c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 12:04:57 2009 -0600
+
+ Don't regenerate asy-keywords.el with make install-asy.
+
+commit 8e884245f07062d284c0248b436fa362567d640a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 11:30:30 2009 -0600
+
+ Emphasize that settings.outformat="pdf" must be set before three.asy (or
+ graph3.asy) is imported.
+
+commit d8fdc5bc766f7f73cd5c8353be662caaea1504c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 24 11:05:21 2009 -0600
+
+ Document and standardize usage of bool3 type.
+
+commit df0dc74326a7f04826e91d13a2faa75e76a1e7d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 23 23:38:32 2009 -0600
+
+ Simplify and document graph interface routines.
+
+ Make cond argument of graph a bool3(real) function, to allow one to
+ distinguish between points that should not be plotted and points belonging
+ to a new branch of the graph.
+
+commit 2c817b9ca4fe5f5d83cd881bc176e148b2617e5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 22 11:13:15 2009 -0600
+
+ Simplify example.
+
+commit 18db9ab6ace1d69723eae0b738f3da438bb6dc7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 22 11:06:32 2009 -0600
+
+ Improve branch test.
+
+commit 468ba41e50b90e332cd0ee5ac9d854e582996456
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 22 00:00:55 2009 -0600
+
+ Make graph routines return a guide[].
+
+ Add casts from guide and path arrays of length 1 to guides and paths,
+ respectively.
+
+ Add 1/x disconnected graph example.
+
+commit 1614388547aaeaba32fb73f2a48ba37314f47a31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 21 22:31:18 2009 -0600
+
+ Avoid warning message.
+
+commit 0c249ad98ae12767a82245b312ae20d80cdc0f51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 21 22:24:26 2009 -0600
+
+ Use cmyk function.
+
+commit 67c42e5be801b4b9c41f39a6aae1942afe2887ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 21 22:22:08 2009 -0600
+
+ Fix default condition arguments.
+
+commit 8ed9d79ad3fc64010518c71afcf44c099e7479fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 21 20:26:12 2009 -0600
+
+ Remove obsolete +cmyk construct.
+
+commit 1456301b60008d69b16d81d27e3bbb12cd1fcd76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 21 18:33:26 2009 -0600
+
+ Improve stack overflow diagnostics.
+
+commit 3aea38afad9ce32a7c69fcc7b7071f3717abdd0e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 21 13:42:46 2009 -0600
+
+ In interp, first promote pens to the same colorspace.
+
+commit 5f7181d05ce0428db888ab025b1428e7e6b625a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 20 01:06:34 2009 -0600
+
+ Add optional bool cond(real)=null to 2D and 3D graph routines for functions.
+
+commit 92218def6d5a2441e8dea3616ac38c8ec1d57ef4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 19 01:08:52 2009 -0600
+
+ Increment version to 1.60svn.
+
+commit f236aa4d54edf39380f4728a05a48da895a22a76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 18 23:40:04 2009 -0600
+
+ Clean up aux files.
+
+ Fix aux conflicts in slide.asy.
+
+commit 9c29f49996676b34d6e03f172d507d87fb5db1de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 18 23:05:29 2009 -0600
+
+ Unlink texput files from proper directory.
+
+ Remove any old texput.aux file before creating TeX pipe.
+
+commit bb5215873b3c7bd55202b36a00734ee916ee311c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 18 22:20:57 2009 -0600
+
+ Fix defaultfilename in asy(string).
+
+commit 1c0a03c7affcd5c71ec3b8f972852af0366ecfc8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 18 16:59:34 2009 -0600
+
+ Handle nonintersecting paths.
+
+commit 001a95cb112128ee6dc26fc6d26a18318a03f85f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 18 15:54:15 2009 -0600
+
+ Add missing final long_opt entry.
+
+commit ca6b80ba33c0921714cdc7c8f78b9660f0dfbaea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 18 13:59:10 2009 -0600
+
+ Fix mixed export/View rendering.
+
+ Wait for pid to finish with -nothreads.
+
+commit f03e2bda783aec28a216674f59c5fb08924105c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 17 13:33:51 2009 -0600
+
+ Simplify example.
+
+commit aaf6df33fa78329e2a12156923c7f59e89a3cde1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 17 12:39:15 2009 -0600
+
+ Fix plain tex font scaling.
+
+commit 86fe7241b7e8f15fa23cc3e0fc0a3027569fa246
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 13 09:25:51 2009 -0600
+
+ Fix typo in manual.
+
+commit b71578ce10460a1795aafbc2de6f22f8c9811dd8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 13 09:23:56 2009 -0600
+
+ Transform margin paths.
+
+commit 0b4d1a83478d15f4e7c4c63573d67c3e4751b181
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 13 09:14:11 2009 -0600
+
+ Add missing filltype option for projected 2D arrowheads.
+
+commit 059133273986ee197b1a0e05200931e238e7ae6b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 12 01:49:48 2009 -0600
+
+ Clean up html files.
+
+commit c56d94c948042b03849953a5ca5b6105e018c87a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 12 01:48:36 2009 -0600
+
+ Generate html files into doc/png.
+
+commit 99ce03a0fe5ee871ce058451fe4ec6382bde51d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 12 01:09:38 2009 -0600
+
+ Set "Start in" directory for xasy to %USERPROFILE%.
+
+commit d32ba1c815176d6686059f51080721fce2bc2671
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 12 01:02:03 2009 -0600
+
+ Increment version to 1.59svn.
+
+commit cc304c7d54383cfe52410c0bbdd998086b90eab2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 23:38:42 2009 -0600
+
+ Draw 2D arrowheads when projecting to 2D.
+
+commit 516aae17ec5c5ee067e2131bc092431c5042cba9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 19:06:17 2009 -0600
+
+ Cache asy.list.
+
+commit c383fdf7bae0d30006a8e825fc1ef7430360e16f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 18:55:54 2009 -0600
+
+ Fix include order.
+
+commit 5ce54e657c3ff5da1fc6b49cf1722eb009c7f041
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 18:30:14 2009 -0600
+
+ Work around incompatibility of latex with DOS directory names.
+
+commit 048dccd54fc396f3714ad0f64909dde004d3e56e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 14:00:17 2009 -0600
+
+ Port to latest version of CYGWIN glut.h header file.
+
+commit 1802826d41afa5ef171a198d120dc36f34119a17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 11:14:54 2009 -0600
+
+ Disable PRC for silhouette examples.
+
+commit 747bf389a75a1b072c2a586205da071974137f51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 11:03:18 2009 -0600
+
+ Remove temporary asyinclude file.
+
+commit ffff57d132fa5ad68244c301c6a254a01eab29cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 09:42:47 2009 -0600
+
+ Draw a central transverse slice when m=1.
+
+ Simplify spheresilhouette example.
+
+commit 5c7374c594922feab7918007c64934683c727288
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 00:11:57 2009 -0600
+
+ Increase example size.
+
+commit 6861fffd47dfec4a14b861584a4f5cef5cde1cf3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 11 00:09:42 2009 -0600
+
+ Add silhouette examples.
+
+commit 0047253a56043d6719589ce072cf3096974fdb36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 10 19:06:20 2009 -0600
+
+ Fix silhouette routine.
+
+commit 002ae3d953e36891bec8823e9808ebf120b061aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 10 17:08:00 2009 -0600
+
+ Fix magnitude of pair axes label alignments.
+
+commit 563e3aac0e32cc00f8dc174d74f89078df2d3587
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 10 12:32:02 2009 -0600
+
+ Remove broken axis label alignment adjustment code.
+
+commit f0ea749693a65015ada26d0ea5e0b63a29dd65d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 9 23:43:57 2009 -0600
+
+ Address nullpath issues.
+
+commit 8748b682068b7f19ef11fbcb4fd59777a7e0e4bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 8 23:31:58 2009 -0600
+
+ Indicate real values with red.
+
+commit 17082621236c24715f37e1388468a1c79226bb16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 8 23:00:07 2009 -0600
+
+ Add Wheel palette and example of complex Gamma function.
+
+commit ac4ecce121491bde69d145c85905e7b027f1ec63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 8 01:14:48 2009 -0600
+
+ Fix conflict with breqn package.
+
+commit 6f3303e24634254458f68f64e19b5defe29c5537
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 6 23:02:00 2009 -0600
+
+ Implement ArcArrow3, etc.
+
+commit 1ee69c6f1852ff257e5355fdf99bf5d1f12ae4ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 5 23:09:35 2009 -0600
+
+ Fix interp(pen,pen,real) by reverting to standard pen addition.
+
+ Fix cmyk(rgb(black)).
+
+commit ed6391bbf8700ec50b151f140f52b6c8a0176a59
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jan 4 14:47:12 2009 -0600
+
+ Report errors of arguments in illegal function call.
+
+commit c8b92ebe85b4982c8651fe90ba103e08041ab3b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 1 12:34:19 2009 -0600
+
+ Add missing file.
+
+commit 033502b10640b65185b78cc1e66d54a8562f230e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Dec 31 22:44:59 2008 -0600
+
+ Added support for open function signatures.
+
+commit 5e34a64ae2238eea776cafb0ec404ea91cb2f67c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 31 17:29:27 2008 -0600
+
+ Exit interactive mode on EOF, unless exitonEOF=false.
+
+commit a010f63aeeec0dc8fccf7ae6e885304ba4ae25bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 31 16:10:39 2008 -0600
+
+ Add copy constructor TODO entry.
+
+commit e24c735878e98185646dd22b5404dd142befa5db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 31 11:01:44 2008 -0600
+
+ Add example of factoring out an axis scaling.
+
+commit 9e4ba2ebf3374ddaa133355da4ab660a5ca52ee1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 31 10:32:10 2008 -0600
+
+ Change VERSION from a function to a constant.
+
+commit d31f008822443a6438ed7db1913a271629c54b3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 31 09:19:16 2008 -0600
+
+ Allow compilation without HAVE_LIBGLUT.
+
+commit 8d8b497afe39a27026af173f1147fa6704def4d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 30 23:19:29 2008 -0600
+
+ Clean up texput files.
+
+commit 112eb1d8a921e53d67839aa574eb7d0c27282f98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 30 23:10:19 2008 -0600
+
+ Revert previous pen changes; make operator + on grayscale pens a maximum
+ operator.
+
+commit 93bd6e0aaa83534744a3e5a60f3997afcf67278d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 30 17:46:26 2008 -0600
+
+ Add missing file.
+
+commit df1440968b940455e6e8266ae0a6fc963f0e5089
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 30 17:43:13 2008 -0600
+
+ Add dependency.
+
+commit 25f258f4c94edebbf063c871a78494b5dea5bf83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 30 17:31:36 2008 -0600
+
+ Fix pen addition involving colorless pens.
+
+commit e811594daaf4cd72706fb3b4989ccbcc9f06bac0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 30 17:13:45 2008 -0600
+
+ Build png images for manual in a separate directory so that they don't take
+ precedence over pdf files.
+
+ Center images in manual.
+
+ Update modified dvipdf.
+
+commit c33928376291116ee0b3d27971432a27ffae8a2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 30 09:37:34 2008 -0600
+
+ Make pen arithmetic consistent across colorspaces.
+
+commit 2b16cde3092731214c2734c132375b3400c69b4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 26 15:29:53 2008 -0600
+
+ Fix error message.
+
+commit a7e96860e96b83d42b7f0abe9f1a61c59761a640
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 14 22:07:10 2008 -0600
+
+ Improve tick adjustment.
+
+commit f48785900c46a4f7f73f0e5bd38bf18b3c9e4294
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 14 01:17:54 2008 -0600
+
+ Increment version to 1.58svn.
+
+commit 69b9c3a90fc92df531cd5b0f0efc821d95e2b376
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 14 00:53:35 2008 -0600
+
+ Use asy.bat instead of asy.exe in MSWindows start menu link.
+
+commit a15d3d019d82e1e734ee6961a6adb4a8079f0524
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 14 00:01:18 2008 -0600
+
+ Resolve ambiguity.
+
+commit 414f39ea34aa3d2b59bbc69118085f7720c0b03e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 13 23:50:31 2008 -0600
+
+ Fix picture sizing with beginclip/endclip.
+
+commit 7acff952eac90aae634e9e341c88e17b53140d78
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 13 23:12:21 2008 -0600
+
+ Add beginclip(picture) and endclip(picture) functions.
+
+commit 51c65ed4fc2dfc8890e5e3230975c5da31581f9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 13 22:55:58 2008 -0600
+
+ Allow clipping across page boundaries.
+
+commit 51fa23a6c1f5a1ce9a14ab0fe7021c95a0af45c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 13 13:04:41 2008 -0600
+
+ Simplify example.
+
+commit 5d68758dec150b173b861bed935b9b007cfda2d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 13 13:02:09 2008 -0600
+
+ Add example of aligned objects and envelopes.
+
+commit 181fb85c90758a5ba14b73fefbf4fd349e317213
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 13 13:00:20 2008 -0600
+
+ Add object(Label, envelope, ...) constructor.
+
+ Support object transformation and alignment.
+
+commit 89516fc6a26ca4b4ae205810e780d10a66336180
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 12 22:31:00 2008 -0600
+
+ Fix plain tex font size.
+
+commit f42c1047ba0cc6b48252e071f52acc33eb6774d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 11 23:19:17 2008 -0600
+
+ Improve axis coverage calculation.
+
+commit 2a95e16eedfe2f3efff147d5619df51607573b4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 10 11:02:14 2008 -0600
+
+ Simplify font(string name, real size).
+
+commit 354e080d458273533b809bc143d22783f6d9ec3c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Dec 10 10:43:09 2008 -0600
+
+ Handle empty history in get/setLastHistoryLine.
+
+commit 40d2017d22e98ceee80e5cfbbaa81974fcd8e565
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 9 03:06:46 2008 -0600
+
+ Use defaultfilename in asy(string).
+
+commit 45f64bb4bac96f96bae81a74362ab81604911d27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 9 02:19:06 2008 -0600
+
+ All temporary files are now generated in the directory specified by the
+ -outname command-line option.
+
+ Make outname a read-only setting.
+
+ Check if the output directory is writeable.
+
+commit f99d9edfe6982095376094b01117fe0a6761bb2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 8 21:44:52 2008 -0600
+
+ Add diagnostic.
+
+commit ecf8129b3978ab5589eb1568bbc471df0c4d6554
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 8 21:44:17 2008 -0600
+
+ Make default MSDOS "start-in" directory %USERPROFILE%.
+
+commit 0dffc47a3e72fb3d33d1e4da8ae69135f0143bce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 8 21:43:28 2008 -0600
+
+ Fix diagnostic.
+
+commit 8b84cbd701e587bcb0cfda2323cb323b04df5140
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 8 20:47:47 2008 -0600
+
+ Add optional basesize parameter to font.
+
+commit bac13dc46d28516dd12bfa067566322a6ae4e65e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 8 18:15:06 2008 -0600
+
+ Fix pdflatex texengine; abandon xelatex support since xelatex does not
+ support pdf specials anyway.
+
+commit 9d79a394539ff8bf6044e14878851a2792cda419
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Dec 8 16:44:46 2008 -0600
+
+ Handle failure to lauch external editor cleanly.
+
+commit c3d171565ecb5af926d0db6922394821928d78ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 7 14:57:02 2008 -0600
+
+ Update link.
+
+commit 28ceef2c78e55bb3a89b3b19dd6c5224583468d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 6 23:28:51 2008 -0600
+
+ Update documentation of xasy installation.
+
+commit 34260991dd4b8712ccb7393c17762440d15ed9a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 5 22:46:08 2008 -0600
+
+ Increment version to 1.57svn.
+
+commit 9f29de60f80817e9471bdf3c80889b324d5e339b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 5 19:33:56 2008 -0600
+
+ Fix documentation of grid3.
+
+commit af5bb7c379246be9b734d152addfaeca6623b729
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 5 19:24:27 2008 -0600
+
+ Add examples of using grid3 with scale(true).
+
+commit 805c95c531aeabdd1749e53c00b943b448bffc8e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 5 19:24:04 2008 -0600
+
+ Fix bounding box bug by clearing \ASYbox dimensions for latex as well as for
+ pdflatex.
+
+commit aae84baab6437781971ab08cf395156f2d749f9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 5 19:21:06 2008 -0600
+
+ Round font scaling to the nearest integer.
+
+commit 60a22d13ecea048aa51b9abcba6d80a859db3d4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 5 11:27:49 2008 -0600
+
+ Add asyinclude function for including 3D PRC graphs in slides.
+
+ Update grid3 documentation.
+
+commit 5b0bc1727b53df6b08e724866a8e9a24f5bbc3fb
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Dec 5 03:45:16 2008 -0600
+
+ Fix version
+
+commit 369a2bc503053e27eafa9d368a80c7f2b17d00e1
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Dec 5 03:36:20 2008 -0600
+
+ Fix handling the environment asydef within lasy-mode.
+
+commit 3a808696c835bfa983096a26d35fd927b146a3ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 4 10:26:58 2008 -0600
+
+ Fix shipout(wait=true).
+
+commit 89505a37e705405424566f8d6015ee77db0ae55e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 2 04:24:02 2008 -0600
+
+ Increment version to 1.56svn.
+
+commit 9354191a7fa1fa719121f331264c931afae0a544
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 2 01:15:16 2008 -0600
+
+ Remove obsolete field of view factor.
+
+commit ba00ab847d6f56929a55ca0d87b7c770e8511973
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 2 01:03:58 2008 -0600
+
+ Add user=true argument to 3D point(picture) and size3(picture) routines;
+ add truepoint routine.
+
+ Add triple invert(pair z, projection P=currentprojection) routine that
+ inverts a pair z onto the projection plane.
+
+commit d40482868635407bc38cd7ef6c1c5d49ed2ce38a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 2 00:41:41 2008 -0600
+
+ Fix more guide to path problems.
+
+ Update guide tests.
+
+commit 4aab933ee9204bd7b3436f8db5c402f4e5ba42fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 1 12:47:38 2008 -0600
+
+ Fix drawing of paths of length 0.
+
+commit 97cfcb1a33c55b34161cc2a4896c63fa7edd757d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 30 21:00:12 2008 -0600
+
+ Increment version to 1.55svn.
+
+commit f6246129093e76b83e1d69827d44e89aa5f0e56b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 30 18:19:15 2008 -0600
+
+ Document need to remove latexusage_.pre along with latexusage-* and
+ latexusage.aux when switching between latex and pdflatex usage.
+
+commit f3be75761c0c5c38bd057278606e433d9292abaa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 30 17:42:36 2008 -0600
+
+ Fix final specifiers in guide examination routines and reverse(guide).
+
+ Fix reverse(guide3).
+
+ Control points should trump direction specifiers.
+
+commit e1b7c0f1647b7a0036e3d7ea7f58c67ef627599f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 30 15:07:10 2008 -0600
+
+ Add threads setting (default is true except under MSDOS).
+
+commit 37c74f79c4c1459f670c509126c10d66b076f8af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 30 01:17:47 2008 -0600
+
+ Fix curved cyclic paths of size 1.
+
+commit 7aae1e50d141c77004a71d09b2f8789951c7b558
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 30 00:46:09 2008 -0600
+
+ Add time argument to curlSpecifier to allow access to all curl specifiers.
+
+ Fix reverse(guide).
+
+ Add reverse(guide3).
+
+commit fd2cd01f27ec1fc5d395524afc805556681de6d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 29 12:51:20 2008 -0600
+
+ Fix multiple file batch mode under MSWindows: only query the MSWindows
+ registry once.
+
+commit fa4ce6f5ed2cda23b745505ba8da83cbf19a3b03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 29 12:50:09 2008 -0600
+
+ Fix compilation without HAVE_LIBPTHREAD.
+
+ Call HideWindow under MSWindows when View=false.
+
+commit 0683943b11b4c0aa9b64c9db5f84b16b730c1f5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 28 00:51:31 2008 -0600
+
+ Respect 3D Label filltype when render=0.
+
+commit 61780ff0823f211a56f75df624376eea1aad1b49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 27 16:08:09 2008 -0600
+
+ Clarify that the native glut library is used instead of freeglut under MacOSX.
+
+commit 4b0b143f3f74af43c1dc119e565932382a8e7ba7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 27 13:49:29 2008 -0600
+
+ Increment version to 1.54svn.
+
+commit a19f7125b6a2f9545b2c8d7684efb7c15abd8f9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 27 12:39:54 2008 -0600
+
+ Set environment variable CYGWIN=nodosfilewarning if it is undefined or empty.
+ Note: this doesn't get uninstalled since it is the "right" default anyway.
+
+ Rename asy-console.bat to asy.bat.
+
+commit b592f16ae13af694ce16a8cbebfde4a8a23e79eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 27 01:14:49 2008 -0600
+
+ Force CFLAGS="-g -O3" default again.
+
+commit fd2a0d22e825647c7405941bd9263473eef2b692
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 27 01:01:41 2008 -0600
+
+ Output diagnostics only if verbose > 1.
+
+commit eee37b6bcc222486d7be5e51f23035d48594588f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 27 00:58:03 2008 -0600
+
+ Add minblockwidth, minblockheight, and mincirclediameter parameters.
+
+ Change Horizontal and Vertical to a nonboolean type flowdir.
+
+commit 3e9a71cdaa387f5d0ecdf0f36c41772b6865bc3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 26 23:31:46 2008 -0600
+
+ Fix PRC projection sizing when up != Z.
+
+commit 950302f8a2a4d01d5043a0e9bed644e006b0ca0d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 26 22:15:36 2008 -0600
+
+ Add missing wait.
+
+ Fix aspect ratio in interactive mode.
+
+commit 6b36a704765f6c88d80e3c6232330a8755e9f1d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 26 20:33:53 2008 -0600
+
+ Fix rendering logic.
+
+commit 3c8a346ab315a8aa57af642ad36788832a441ce5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 26 15:46:04 2008 -0600
+
+ Minor optimizations.
+
+commit 86cea1a75de520b35f6eaf1bc8c8ce0f7c1eb668
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 26 00:26:30 2008 -0600
+
+ Change cyclic flag in the routine where the array is actually constructed.
+
+ Make minor edits to tube documentation.
+
+commit b6f0403bc6809f96add2af2fdfda140a13ebe8a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 23:27:21 2008 -0600
+
+ Enable the toolbar by default within the asyattach environment.
+
+commit 70c5bdd9e6711620c1fb16d4c8553db42c1ffc55
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 22:13:39 2008 -0600
+
+ Set CYGWIN=nodosfilewarning in asy rather than in a batch file.
+
+commit 4210144b34da47dbe8faa22136d14aef5e5d574d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 22:12:13 2008 -0600
+
+ Don't hang on exit from "Cannot execute latex" error.
+
+commit 01972838df01c726b045fcc30d4419c102cf928e
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Tue Nov 25 17:02:34 2008 -0600
+
+ Replace step to relstep in tube.asy, add example of tube, document the package tube.asy
+
+commit cda1746f22599bfc912392c9bda0ed9a7f6a5b54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 15:20:36 2008 -0600
+
+ Distinguish between defaulttransform and defaulttransform3, so that
+ label(scale(10)*"text",O) is projected onto the initial viewing plane.
+
+commit d19c0bec2c319d5c6f435419788f8ea94980c1da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 14:44:44 2008 -0600
+
+ Simplify freeglut svn-761 installation instructions.
+
+commit 07819114b9060175fde5b0414222d525a340577b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 13:16:48 2008 -0600
+
+ Catch out-of-memory errors in OpenGL renderer.
+
+commit e3c10fc46b23f259921c3d4a169e953e3521f6be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 10:09:56 2008 -0600
+
+ Disable DOS path syntax warning in version 20080327 of cygwin.dll (which
+ supports pthreads).
+
+commit 6f7d32223b5ec3dcbcb75ae20fc358f9e265af5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 05:06:31 2008 -0600
+
+ Increment version to 1.53svn
+
+commit 2826efca8dc76e59d4ba70192dce69c84668ed9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 01:02:46 2008 -0600
+
+ Use _exit instead of exit after fork as recommended by man page.
+
+ Remove remaining piece of old fork wrapper code.
+
+commit 35877ed7f1df1410f78ae2fc19dc79fc76449905
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 25 00:09:26 2008 -0600
+
+ Make antialias an integer parameter (default 2). Values bigger than 2 are
+ currently respected only when converting from EPS or PDF formats.
+
+commit b6cda52e4df8063b5c0bb12ff3bab9c0850a2626
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 24 23:30:57 2008 -0600
+
+ Don't call fitscreen() during interactive updates.
+
+ Simplify forking in pipestream.h.
+
+commit 4019ae275efaea77130d93ae82568def5a5111c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 24 03:16:55 2008 -0600
+
+ Fix multiple file aspect ratio issues.
+
+commit 3ccc70e985a7b42a992e89a27e0ef2f71f6e53a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 24 02:57:28 2008 -0600
+
+ Fix exporting with -noV.
+
+ Support machines without working POSIX threads.
+
+commit fcad51ead250de2f47b067407fb8829d2932475f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 23 18:19:34 2008 -0600
+
+ Define standard symbol WORDS_BIG_ENDIAN or WORDS_LITTLE_ENDIAN, as appropriate.
+
+ Add Orest's patch to support PRC output on bigendian machines.
+
+commit 2aec609cefdfe288e01d02a76f2fc1ff77fa9151
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 23 16:47:28 2008 -0600
+
+ Use gl::wait routine for thread synchronization.
+
+commit 61dbf2a011d73ef468358542909fe2fbde7aa3a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 23 03:00:14 2008 -0600
+
+ Support compilation again on systems without glut.
+
+commit 4a8226975e5845b0c75b1339f935ec7bec604971
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 23 01:53:41 2008 -0600
+
+ Conditionally include config.h.
+
+commit 1665f78ca7e201cc4172435aa6ca2e2c9da9cd05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 23 01:53:05 2008 -0600
+
+ Rename BIG_ENDIAN to IS_BIG_ENDIAN.
+
+commit 4f1141861f7f15050d94baf847f43915c0c7ac0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 23 01:43:57 2008 -0600
+
+ Add preliminary support for bigendian machines (PRC output is not yet
+ working though).
+
+commit 1a589effdc9db55543060fe489c4ef38f1f20fcd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 23 01:12:57 2008 -0600
+
+ Use the main thread for OpenGL rendering to make MacOS happy; run asy in a
+ secondary thread.
+
+commit 95f09626b1c294ff4c0d0f480c66e49cc6192965
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 22 13:29:20 2008 -0600
+
+ Add assert.
+
+commit 62607706159b5e583cdb034e58229ae7719bce0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 22 12:03:14 2008 -0600
+
+ Update SVN instructions to not require SSL support.
+
+commit d0dc7b89f83820cb783d6aa454904af338da5dc0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 22 12:00:27 2008 -0600
+
+ Fix bus error.
+
+commit 0ae0ab31d39f9c989f9b1cf160f3b5cef1790c44
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Nov 21 17:13:24 2008 -0600
+
+ Fix calculation of angle.
+
+commit aed1181edf6d26e924fc394baa139ed0f6766244
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Nov 21 08:29:02 2008 -0600
+
+ asy-mode.el: define asy keywords properly.
+
+commit eaf21ba2f2de354718ea9e460cf79fb0f80bbe0a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 21 01:55:51 2008 -0600
+
+ Add Philippe's tube module.
+
+commit f8dda08ef26195f1c9fda68460c0610313b5eaa6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 21 01:20:14 2008 -0600
+
+ Improve thread synchronization and diagonistics.
+
+ Remove freeglut-2.4.0-svn759.patch in favour of fixed svn 761.
+
+commit a1619e9d4754fd750dc18d26c3d7c05cb6cdc2f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 20 02:40:24 2008 -0600
+
+ Implement robust thread locking.
+
+ Update installation instructions to use the system GC by default, now that we
+ require a multithreaded version.
+
+commit cb8a4dfda6950bd6580bf7d8d679dcbf4af767d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 19 19:59:56 2008 -0600
+
+ Revert most of 1.52-22 due to a reported segmentation fault and since
+ glutGetModeValues isn't implemented for MSWindows anyway.
+
+commit 3903344a1ccb4e74db0f0e30d2b434738dbbe105
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 19 17:35:07 2008 -0600
+
+ Revert 1.52-21.
+
+commit 9770f5a89b126bbe256245d3282d186547e35433
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 19 10:12:32 2008 -0600
+
+ Add television test pattern example.
+
+commit 41e39c1c8bb087a7bafc400a8175e1eca5a2de8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 19 01:19:29 2008 -0600
+
+ Simplify multisample negotiation by using glutGetModeValues.
+
+ Backport code to freeglut-2.4.0.
+
+commit 4cbda4d70a31d92544b0a294c881e39a77753f4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 19 00:20:29 2008 -0600
+
+ Hide window again when View=false, even if iconify=false;
+
+commit a97fee3070084e12ca4c38b4c196a7d378cc5485
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 19 00:08:27 2008 -0600
+
+ Add bool3 type that takes on one of the values true, false, or default.
+
+ Add planar argument to surface.
+
+commit b691580fe5c1039f503c64abf410e07958b9ef5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 18 23:15:37 2008 -0600
+
+ Fix vertex shading order in planar case.
+
+commit 94e67f10f05c4c03f0bf8749e57b14993f1938dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 18 22:43:51 2008 -0600
+
+ Avoid POSIX thread deadlock.
+
+ Fix rpm latex install directory.
+
+commit eb5a9628772285778a7ec869455378c0b65db0a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 18 14:46:51 2008 -0600
+
+ Work around nonstandardized signature of gluNurbsCallback on various MacOS
+ platforms.
+
+commit 62302ae390ff875904680efef03ea8c264933b66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 18 11:46:00 2008 -0600
+
+ Use POSIX threads instead of fork in OpenGL renderer.
+
+ Make multisample an integer; if freeglut is used this parameter controls
+ the multisampling width for screen images.
+
+commit a1a69888cbf8616b5d50b8c17286c929b08b59a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 18 08:58:27 2008 -0600
+
+ Remove obsolete patch.
+
+commit 1bbf033f0430294fcbef2c4f9072251a810c2a8e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 17 13:12:46 2008 -0600
+
+ Install asymptote.sty and asycolors.sty in $TEXMFLOCAL/tex/latex.
+
+commit b68290520bd99f33046fe48de39bd63797a2e339
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 16 18:08:46 2008 -0600
+
+ Fix indentation after struct.
+
+commit f4598c25e85557a11adda85150e3165fe10b6464
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 16 17:36:38 2008 -0600
+
+ Remove dependency on cc-mode.el source.
+
+ Allow asy-mode.el to load even without asy-keywords.el.
+
+commit debfed2b43a8846d5cfa45c6807cc24585485e24
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat Nov 15 13:01:48 2008 -0600
+
+ fix markangle orientation.
+
+commit 178f9004c67cd5c5e0ff09bb95e36bb8396ea10c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 15 10:28:48 2008 -0600
+
+ Add missing sentence.
+
+commit 95882c60c7e43c4f50912eb2e7a90e6431d1e97e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 15 10:14:20 2008 -0600
+
+ Add optional user=false argument to min(picture), max(picture), and
+ size(picture).
+
+commit 5c776e96d56817d3d9804af5592f17daac509d60
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 13 02:28:01 2008 -0600
+
+ Fix degenerate thick line caps.
+
+commit bffba97a1bcc64dc2100fa0ab36c9359a44e7b5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 12 17:51:01 2008 -0600
+
+ Don't discard 2D size constraints in draw.
+
+commit b34d0cad11f9710f33905394b9e74a0dca4c7edd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 12 14:59:16 2008 -0600
+
+ Reinstate freeglut-2.4.0-svn759.patch which to fix multisampling bugs.
+
+commit c22422f84f5b69980179324fb09e209f81a10afd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 20:24:50 2008 -0600
+
+ Hide window only if iconify is true.
+
+commit 21c68e1ee445763474ceb9e79e2d0ced9ece5475
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 17:09:29 2008 -0600
+
+ Fix logic in 1.52-3.
+
+commit 9141009fd026462c8fd2a8e3dc863efc6877687e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 17:05:01 2008 -0600
+
+ Combine both _GLUfuncptr MacOSX workarounds.
+
+commit 4654e4193e6662ca07ad7b9e30eba7a75fe9266a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 13:45:14 2008 -0600
+
+ Fix _GLUfuncptr detection.
+
+commit 1dcf8cd27103dcf0196718b59d5614b6a0de21b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 11:42:51 2008 -0600
+
+ Support compilation under MacOSX 10.5.
+
+commit 991a86171d82c1a6fc61f9eb30dd5bcfd6591dd1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 04:31:25 2008 -0600
+
+ Increment version to 1.52svn.
+
+commit e91483639c4758e9710eac68b397da75e907fefb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 03:34:18 2008 -0600
+
+ Wait for completion of rendering.
+
+commit 11e8fb881b48ae97f6fa5148dbf6f54c7f44b96e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 02:26:45 2008 -0600
+
+ Remove obsolete patches.
+
+commit a8b3e58351a07e3303ebc11ee3293e2839ab36d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 02:25:59 2008 -0600
+
+ Use a more robust patch to enable multisampling in freeglut-2.4.0.
+
+commit 144be10c4af5e9927aadce7dc83b6223546595ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 02:03:48 2008 -0600
+
+ Fix warning message.
+
+commit 05729b9d81a782ecfbc89603b12e56b725cde318
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 02:00:49 2008 -0600
+
+ Change references to freeglut to glut.
+
+commit eacbd60287f66505a86f1c1fe949c8c47c055606
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 01:57:27 2008 -0600
+
+ Improve memory performance and reduce rendering conflicts by always forking;
+ remove last dependence on freeglut.
+
+ Don't solicit bug reports for segmentation faults caused by graphics driver
+ bugs (e.g. on memory exhaustion).
+
+commit 7892f714e5eac1a29733c0788482dff4b1798b1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 11 00:53:34 2008 -0600
+
+ Prevent multiple glInit calls.
+
+ Use a separate multisample setting to control screen antialiasing.
+
+commit 7429c3c359094d7af8bf556e8b45427870b6d656
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 10 21:31:57 2008 -0600
+
+ Turn multisampling on only when View is true.
+
+commit 2152eadef3a913a0ca76545887f7b9c0425526c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 10 21:15:07 2008 -0600
+
+ Increment version to 1.51svn.
+
+commit d06765ccc2605e7c49b262790d7118ddd3ef586f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 10 20:06:43 2008 -0600
+
+ Add multisampling patch for freeglut-2.4.0 under CYGWIN.
+
+commit 0568dc2f66e5318978d08368708267f6d027f324
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 10 18:39:40 2008 -0600
+
+ Update CYGWIN port.
+
+commit c002f91cb9345bafae361ec1f317addff487d894
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 10 00:46:21 2008 -0600
+
+ Control multisampling with antialias flag.
+
+ Add patch to bring freeglut-2.4.0 up to date, with multisampling support.
+
+commit ebfd53b97f08f5033991e3f3ef3638f6e31a1c0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 9 16:22:45 2008 -0600
+
+ Support multisampling; this requires the latest svn version of freeglut.
+
+ Support -iconic and mouse wheel with the latest svn version of freeglut.
+
+commit e884aecf09f6b77ff59327736d59b43901aa3f30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 9 11:05:55 2008 -0600
+
+ Don't allow tile size to exceed current window size.
+
+commit 6996717e07631160568564c746bb4ef5e9cfe14c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 9 02:02:17 2008 -0600
+
+ Set default value of settings.render in asymptote.sty to 4.
+
+commit aa7257237a93f790a8609e053590fb0dda01e595
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 9 02:00:15 2008 -0600
+
+ Illustrate the use of viewportmargin in latexusage.tex.
+
+ Set the default value of settings.render in asymptote.sty to 4.
+
+ Update documentation.
+
+commit 0d091afa43a93ee525d4af643aa4186e27affd1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 9 01:21:06 2008 -0600
+
+ Add viewportmargin parameter.
+
+commit 429feedf2ba8a6580cb749ca0dc0c2abb8117799
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 8 18:41:51 2008 -0600
+
+ Change Makefile.in to remove latexusage-* instead of latexusage_*.
+
+ Change put=Above to above=true and put=Below to above=false.
+
+ Remove constants Above and Below.
+
+commit 2e1a65d0a6273ce47712b55b68e8d18c75a71350
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 8 17:37:34 2008 -0600
+
+ Add embed option (default true) to allow one to suppress the embedding of a
+ rendered preview image.
+
+ Support file attachments in asymptote.sty; this is provides a better method
+ for embedding 3D PRC files in a LaTeX document.
+
+ Add iconify option.
+
+commit 7eff5652e202e7c937a000aa5beb0c1b8c2ad580
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 17:49:58 2008 -0600
+
+ Set default maxtile to (0,0).
+
+commit 1a18bbcbe2b0b7adff2698498ed3871e5e4eff74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 16:42:12 2008 -0600
+
+ Fix camera roll.
+
+ Fix divide by zero error.
+
+commit 9df48c1fd385adcf6cbe3c4d287be3e7c3404282
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 15:06:46 2008 -0600
+
+ Fix rendering with -nofitscreen.
+
+commit 7ea8229d843fc2026ad6fb259e15479fab09bfa8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 10:10:11 2008 -0600
+
+ Fix PRC up vector.
+
+commit 95a5d718046b7a72949cbc64b4759614331910b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 07:26:34 2008 -0600
+
+ Fix glut.h path under MacOS.
+
+commit af473745f283e163f72c9251767f8f06cd731b8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 07:17:41 2008 -0600
+
+ Fix detection of MacOS.
+
+commit 1ee53f746794377380a867022367a08568422a21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 06:59:21 2008 -0600
+
+ Improve documentation of add(picture).
+
+commit 2849d018b4c33f66f2fd28541c55d1b3f08c12b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 7 00:51:09 2008 -0600
+
+ Add glut compilation support for MacOSX.
+
+commit 38c16362fd77cdaa325f9ac9f316e1ad46600fd6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 16:18:18 2008 -0600
+
+ Initialize window to the maximum tile dimensions again.
+
+commit ffab9fcaa21a0758ce42242e63ad6d6d5ce26bc6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 16:07:51 2008 -0600
+
+ Change default value of maxtile to (800,800).
+
+commit 48c91000d1284b74366c1c02db3ab2ccea70961e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 11:59:16 2008 -0600
+
+ Recommend glOptions += " -iconic" for UNIX systems that support this.
+
+commit a1d87f3d2af798cc89359c24e9f18260b396e4fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 11:36:15 2008 -0600
+
+ Add interface to runtime view() function.
+
+ Document use of glOptions=-iconic for UNIX systems.
+
+commit 1bea8e8b1790afb55c7899bd3a505dd3dcfca22c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 11:05:59 2008 -0600
+
+ Support -glOptions=-iconic for drivers that allow this.
+
+commit e766302cdd096972819105b96407d73d06b20e5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 10:27:46 2008 -0600
+
+ Avoid rendering problems caused by iconic option.
+
+commit 44f693bf85e7a8c25557d2b1e1510617a2c2c72c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 09:17:16 2008 -0600
+
+ Change default value of maxtile to (0,0), which now means to use the screen
+ dimensions.
+
+commit 02585cec9a5da7f348c2d9f764396d12edb3b4c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 6 08:52:25 2008 -0600
+
+ Use opaque value in glClearColor.
+
+commit 2016f42fba27487193258ca2f10392d61220f4cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 5 23:00:49 2008 -0600
+
+ Add PenMargin3 to example.
+
+commit 5c1d8867bffeea5d1600ca80c8f4d0d1755e80fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 5 18:21:12 2008 -0600
+
+ With -noV, initialize the window to maxtile.
+
+commit efeee19d9ffd6e65d3dd86d96d49770c76c3adc1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 5 01:43:18 2008 -0600
+
+ Avoid glDisable(GL_LIGHTING) due to race condition.
+
+ Improve Margin3.
+
+commit ff627450e4c48ea211403be0bcfb3f80f71c3d77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 5 00:07:04 2008 -0600
+
+ Add support for three-dimensional dimension bars.
+
+commit 9516507db876721489f9f91736db9a4e2f38f79d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 4 23:58:18 2008 -0600
+
+ Simplify window initialization code.
+
+commit 8f650920cb66b2f5e56b3bb7801a72f2fe5a436d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 4 16:43:44 2008 -0600
+
+ Fix PenMargin3 and DotMargin3.
+
+ Make dotsize consistent for pictures and frames.
+
+ Reinstate wedge example.
+
+commit 7eb648da6642d894776564de2c9a8bfd9da2c304
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 4 14:34:48 2008 -0600
+
+ Update hyperref documentation.
+
+commit e830469751fcfd89cb4395cb891dfb5258f2956b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 4 12:40:54 2008 -0600
+
+ Standardize triple perp(triple); fix numerical precision issue.
+
+commit ca8a5b45a2db729d65c2532a2691b490e166a59d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 4 00:50:49 2008 -0600
+
+ Fix more normal problems.
+
+commit a8b7919a2d2f9cae4be11aeb4702d4d3893b5709
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 4 00:17:51 2008 -0600
+
+ Use right-handed transformation.
+
+commit c3283a0676baa2893490028da3697d674097bf58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 3 03:25:16 2008 -0600
+
+ Decrement version to 1.50svn.
+
+commit 43f9a40080aa0f92d7c0a3f2edf6774e00550a4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 3 03:15:44 2008 -0600
+
+ Increment version to 1.51svn.
+
+commit 7c35f506cafce37ef53d3c9d74873bee14bc0fd5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 3 02:12:27 2008 -0600
+
+ Make example look better with render=0.
+
+commit 71f88287c1f0c9593d7a9cdacd67d0c79ef16915
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 3 02:10:44 2008 -0600
+
+ Fix example; texpath currently only handles standard font sizes.
+
+ Fix handling of keep flag in texpath and strokepath.
+
+commit 98d0bac42932a98ef39ba65e9347e6a7399b9bd6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 3 01:43:59 2008 -0600
+
+ Improve example.
+
+commit a2d5e32a404f9614564f8382edb6e8ea30176aa5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 3 01:38:07 2008 -0600
+
+ Fix surface normal calculation.
+
+ Add patch reverse(patch) function.
+
+ Improve normal(path3); add normal(triple[]) for polygons.
+
+commit cd6f6f555e6ebfef4b5c525c47449670db984eaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 19:52:42 2008 -0600
+
+ Add missing transform of normal vector.
+
+commit 6da5b5ed0730a5f4f0a06b093672068d0438686c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 14:50:09 2008 -0600
+
+ Document glOptions=-indirect.
+
+commit a0ec9291b25648bcf541cca112664054ae9bbadf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 11:17:56 2008 -0600
+
+ Change mean(pen[]) to take a more useful opacity function.
+
+ Add opacity argument to mean(pen[][]).
+
+commit 4ac8b16285c8d8c0206d12d6113605ed5c2884cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 10:33:08 2008 -0600
+
+ Reinstate cornermean.
+
+ Make mean(pen[]) return by default an interpolated pen with the minimum
+ opacity of all given pens.
+
+commit 1f468a931dac3a0cc2b2e1a377e54ca7db61993c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 01:45:39 2008 -0600
+
+ Use vertex shading.
+
+commit 0c429c99b1073a8ce6b694c14024318095a52cbb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 01:33:49 2008 -0600
+
+ Update examples.
+
+commit 6e170c72fad9f673b8bfb63d420768e4ad7f37c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 01:20:19 2008 -0600
+
+ Fix example.
+
+commit 4a56fe6a909bce1e60ee46dc445e9a7791c17b71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 2 01:15:59 2008 -0600
+
+ Increment version to 1.49svn.
+
+commit a219ddb14baff290277499dd68ad88e11a2ab124
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 23:49:11 2008 -0600
+
+ Document how to draw surfaces with patch-dependent or vertex-dependent colors.
+
+commit a59df140afed1a63cb1218c7ff492b8d38f20821
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 22:44:33 2008 -0600
+
+ Remove old fitscreen code.
+
+commit 98d281fb1bf0928779ba66773a671d7a45630f24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 22:24:42 2008 -0600
+
+ Document surface tube(path3 g, real width).
+
+commit 0bc94259935834b3f758ae12ced619451664a9c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 22:15:11 2008 -0600
+
+ Fix incorrect precontrol output in write(path) introduced in 1.91-23.
+
+commit 01d8cbea25650200b3372a05fed040cc20de158f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 21:54:00 2008 -0600
+
+ Account for perspective scaling in planar test.
+
+commit 9f18a4df21d708ecc1b853d815f8a0b8b6419c16
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Nov 1 14:52:41 2008 -0600
+
+ Use unstraighten() to obtain control points of straight segments.
+
+commit a963ce1eebd5c8a7480fe21ae5e62e8a7cdfa376
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 14:13:16 2008 -0600
+
+ Implement path unstraighten(path), which returns a copy of the path with
+ the straight flag turned off.
+
+commit 39211adfeab65d1efa31067ac2f4b9c7b9baac11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 13:36:29 2008 -0600
+
+ Specify an angle precision for centering perspective drawings.
+
+commit df226e66b5169a42195ada8750aa2a565d6c1839
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 11:52:48 2008 -0600
+
+ Increase angleiterations to 4.
+
+commit d7e1465437bcd26f21aa19eeb26f224c952806fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 11:35:33 2008 -0600
+
+ Allow odd sized tiles again.
+
+commit 48f6d409b7ff5ff23f3667b8e28db1639cabb107
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 10:47:26 2008 -0600
+
+ Set surface normals whenever light is on.
+
+commit 55ec3b5227b1a32d807217dca0787988352af385
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 10:02:28 2008 -0600
+
+ Transpose surface.corners() and surface.map().
+
+ Use mean corner pen for patch shading.
+
+commit 2378aa429188a396191e49b411907f98e366b06c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 08:58:09 2008 -0600
+
+ Increase angleiterations.
+
+commit d5865412c18a4cb1835ef7235f583d50dce439c0
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat Nov 1 03:43:57 2008 -0600
+
+ update examples/projectelevation.asy
+
+commit c7ff9b62861a294d57b200b05184414acdab857f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 02:29:24 2008 -0600
+
+ Rename cornermap to map and cornermean to mapmean.
+
+ Add triple[][] corner() and triple[] cornermean().
+
+commit 40905d1a35e5d96c4fd48aad8f04ba161da740d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 1 01:39:32 2008 -0600
+
+ Support lighting with vertex shading.
+
+ Fix surface lighting with render=0.
+
+ Fix normal(path3).
+
+ Move rgba pen packing and unpacking functions to plain_pens.asy.
+
+ Implement pen mean(pen[]).
+
+commit b2f7f73429c6bb9bcd70124e3c949e737225eb6f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 31 21:48:25 2008 -0600
+
+ Force tile size to be even.
+
+commit 096a399768b73f223951d18a554bc99a589e4872
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 31 17:48:33 2008 -0600
+
+ Make maxviewport and maxtile pairs.
+
+commit 4c870db4d37abb95ee7501107dcddea637cc21b7
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Oct 31 17:29:36 2008 -0600
+
+ asy-mode: warn cc-mode.el dependency.
+
+commit 401638c5ae34cc9f46ea916a2601cedf390c2c8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 31 17:18:14 2008 -0600
+
+ Support compilation under standard glut for systems without freeglut.
+
+commit 00366cc59b2e2ed5a0fa03fc3a80581233e41283
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 31 15:39:00 2008 -0600
+
+ Fix fitscreen toggling.
+
+commit 424de2df6076c686c8a8d0ee06c18d5572f151f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 31 15:34:07 2008 -0600
+
+ Add tilesize parameter to limit the maximum rendering tile size.
+
+commit 4deb82228a5bdfc655cb4b79be27298ffd22a6be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 31 08:48:04 2008 -0600
+
+ Revert last change, which breaks tabbing after struct{}.
+
+commit cf324b77f8d2a431235e46c1799c2e27fbe1ba2b
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Oct 31 07:36:39 2008 -0600
+
+ asy-mode: fix cc-mode code source dependency.
+
+commit cb1eeb3561d1cfd47c6724bc2d9962319a12ba80
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 31 01:12:53 2008 -0600
+
+ Simplify construction of elevation-colored surfaces.
+
+ Add facility for vertex-shaded elevation surfaces.
+
+commit 913151d6867b93bb76ea24bcdb717a18a1e39483
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 30 23:42:55 2008 -0600
+
+ Fix initialization and translation issues.
+
+ Remove unneeded CYGWIN restrictions.
+
+commit 277cad8a6b3ee0dc3cefc21c5e72b9a3b407e0c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 30 22:04:53 2008 -0600
+
+ Fix orthographic exports.
+
+commit 06c7940dbfaa3ca0dcbb8220e5bb4db3a38f19ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 30 21:48:52 2008 -0600
+
+ Use Brian Paul's tr-1.3 package to support high-resolution OpenGL tiled
+ rendering.
+
+ Add antialias setting (default true).
+
+ Change convert to use default antialias setting.
+
+commit f75488ec21d55232acfcbc86f165b56078a0600b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 30 21:16:31 2008 -0600
+
+ Add roundbox envelope routine.
+
+commit 3b430cd073da9000dff6e358dfa15483cac61ab9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 29 22:22:06 2008 -0600
+
+ Turn on straight flag only for piecewise straight planar paths.
+
+ Force straight flag for all obj faces to avoid subdivision cracks.
+
+ Make normal(path3) return immediately for nonplanar paths.
+
+commit ea2035f4d10d6ad2d4958f3264060bb6c19f1101
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 29 19:39:28 2008 -0600
+
+ Change signature of point to pair point(picture, pair, bool user=true) to
+ allow a return value in PostScript coordinates.
+
+ Remove framepoint in favour of truepoint(picture, pair, user=false).
+
+commit a9d36f14667ee3f01ded31a1682b056e99b45080
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 29 17:10:25 2008 -0600
+
+ Add maxheight, hstretch, and vstretch parameters to legend.
+
+commit 08d8d9d54b14b50cc18e40c6fe0b39175f14c742
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 29 11:48:12 2008 -0600
+
+ Add defaultbackpen.
+
+commit 5e73c1c8753fbaa886e8d14740d1fb54c67d0cb3
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Oct 29 03:42:28 2008 -0600
+
+ Add TeX versioning
+
+commit b295681be3eadad9b41da9cad9f335c555884dac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 29 01:28:12 2008 -0600
+
+ Support transparency in vertex shading.
+
+commit addf84f034546239f5a536ea13aa30f473888ece
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 29 00:50:50 2008 -0600
+
+ Support vertex shading in OpenGL renderer.
+
+commit 30614123cb946a0fe0bd3eb2906dffcd725d11ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 28 17:40:42 2008 -0600
+
+ Use centroid rather than the first vertex for splitting surfaces.
+
+ Rename unpack to real[] rgba(pen) and add inverse function pen rgb(real[]).
+
+commit 7701a82ac9563b95bfbbdd5b6752cb3e855c7913
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 28 01:42:51 2008 -0600
+
+ Add a more versatile and more efficient surface constructor for convex and
+ "piecewise-convex" three-dimensional paths; the planar(path3) constructor
+ should now only be used for nonconvex paths.
+
+ Update examples.
+
+commit 90aa53c7cc7b38519cdc75657347e4829f39f565
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 28 00:53:18 2008 -0600
+
+ Implement DefaultHead2(filltype filltype=Fill).
+
+ Add optional filltype argument to HookHead2.
+
+ Reduce adaptive thick line constant.
+
+commit 5aece89072f9c13499c4e5c209d001a91b56a50b
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Oct 27 07:32:59 2008 -0600
+
+ add size to parametricelevation.asy
+
+commit 36da4de5e2b52e0846ed10d3535f46fa1f1f169b
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Oct 26 17:53:47 2008 -0600
+
+ revert wrong commit of glrender.cc
+
+commit 5888260287059b73d61c68c9d2d19c6a1e028321
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Oct 26 17:46:53 2008 -0600
+
+ add size to sphericalharmonic.asy.
+
+commit 0598c725bca4e3613bd5d96bfe9f92b99636e6a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 26 17:37:14 2008 -0600
+
+ Further adaptive thick line improvements.
+
+commit b9c7577bf0d9f2b1f464046f91e9bb30f0ca303c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 26 15:52:26 2008 -0600
+
+ Improve thick line adaptive step routine.
+
+commit 0d4fa1edfcaf22f6d0682712488343624e19bf72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 26 14:35:58 2008 -0600
+
+ Increase 3D margins.
+
+commit 9461bf3f0b905d2d2580e2993ec3f6ffaacf4f04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 25 22:46:42 2008 -0600
+
+ Work around Adobe Reader rendering bugs.
+
+commit d26a98ae53cfc26724584790f75d48fc5d54ce9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 25 21:57:23 2008 -0600
+
+ Support 2D alignment of 3D axis labels.
+
+ Use more efficient size(pic) routine in legend().
+
+commit 99ded514151ae96c2f969eabc726e91cd5d358e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 25 13:01:28 2008 -0600
+
+ Resolve ambiguity in draw(surface).
+
+ Add Gradient palette that varies linearly over a specified range of pens.
+
+ Add spherical harmonic example.
+
+commit aa912c8197993f03628145caa23915a618718145
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 25 11:16:48 2008 -0600
+
+ Standardize argument names of dir and expi.
+
+ Add parametric surface with elevation-dependent colouring and no light effects.
+
+commit 3ef96452b28a2e2ced13a7e3ad7be52754279268
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 24 08:31:50 2008 -0600
+
+ Fix a numerical precision issue.
+
+commit aa83d5256ee460261387c3560d00816d86778675
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 23 02:18:43 2008 -0600
+
+ Increment version to 1.48svn.
+
+commit 75578118cf5bc705113c1ae240ff3c19e75bcf04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 23 00:48:28 2008 -0600
+
+ Add another draw routine for surfaces.
+
+commit fdc1eed6b5c60f0dafe7722dc5b1846d85a858db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 23 00:39:14 2008 -0600
+
+ Implement a more robust version of normal(path), returning O if the path is
+ nonplanar.
+
+ Handle nonplanar obj faces.
+
+ Add triceratops example.
+
+commit 65903677e85e923709ecf9a1b57df596d062f73e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 22 17:40:56 2008 -0600
+
+ Re-enable high-resolution rendering.
+
+commit 73ab9efcba8340a762e97c1e1c82e9e847931eaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 22 16:59:21 2008 -0600
+
+ Remove diagnostic.
+
+commit aa8cc010d4a318c68e892c49567ce069abc18a30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 22 14:52:20 2008 -0600
+
+ Fix strokepath(nullpath).
+
+commit f40ae1db9ac65ad4b358ca15ddf829a8277a629c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 22 14:49:43 2008 -0600
+
+ Fix strokepath.
+
+commit 17a1189c97f29a63fc1dfba82e2fe6305948e04e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 22 01:55:06 2008 -0600
+
+ Bypass bezulate for paths of length 4.
+
+commit c0caed7e85641f07acd04c36ef8aeb2989432045
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 21:05:17 2008 -0600
+
+ Use unit normal in planar.
+
+commit 4b1f6636bef4a86b158e6d6571761b25c7b672e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 20:50:31 2008 -0600
+
+ Fix cyclic path bugs in write(path) and write(path3) introduced in 1.45-34.
+
+commit caa4444ddc2e242d903c6eef2c33b811d0e1438f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 17:49:30 2008 -0600
+
+ Implement HookHead2 and TeXHead2 arrowheads. These are 2D arrowheads
+ lifted to 3D space and aligned according to the initial viewpoint.
+
+ Add missing angle parameter in HooHead3.
+
+ Simplify planar.
+
+ Move arrowheadlight parameter out of Arrow3 and into arrow commands, so
+ that the correct value of currentlight is used.
+
+ Use tighter values for the margin parameters viewportfactor and anglefactor.
+
+ Reduce angleiterations to 2.
+
+commit c03df01eb051081f035ecc4fdbfa9d88e76dae39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 13:36:45 2008 -0600
+
+ Fit to screen by default.
+
+commit 72ee07959783cd6238303cbf614c02287b53fc1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 11:52:54 2008 -0600
+
+ Don't generate spurious "camera too close" errors for projections from infinity.
+
+ Always use currentlight by default for drawing arrowheads.
+
+commit 628f27c4054948ae3b0e83f43334860380a72378
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 09:02:46 2008 -0600
+
+ Change text on sample CD label to something more Asymptote related.
+
+commit 43251826a66e5d59b537245f03402ee220ef643d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 01:52:33 2008 -0600
+
+ Add missing file.
+
+commit db6b14e4304b767e2d9f701946e75421a5e5dcbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 21 01:22:40 2008 -0600
+
+ Add module for reading obj files and example.
+
+commit c5c589ecc6513d890c48fb9810d9900b0b543681
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 20 23:05:56 2008 -0600
+
+ Allow an array of meshpens when drawing surfaces.
+
+ Update documentation.
+
+commit ad2f7da5d4b350d624c4de6f79eaf48d4f363443
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 20 21:48:12 2008 -0600
+
+ Move path length tests to surface constructor.
+
+ Add bool warn=true to planar and normal(path3).
+
+ Check incoming width and height parameters.
+
+commit f0cd7a28153ae2a5c1af3b4000c5e76fc4a2b023
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 20 16:31:26 2008 -0600
+
+ Fix prefix again.
+
+commit 7d37902efc2d7bdf386eba8bdc5829ff090fdc65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 20 16:19:41 2008 -0600
+
+ Implement 3D margins.
+
+commit 0bd329a544d339e46112e6a8604f2c9fbc4c21db
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Oct 20 12:25:25 2008 -0600
+
+ Fixed watch() and unwatch() to use atupdate().
+
+commit 56311b858724cb98c83957efd304795106431fdd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 20 01:36:47 2008 -0600
+
+ Add surface constructors for triangles.
+
+commit d0de328928b73dc533bf58c905bfd9996275f05c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 20:54:46 2008 -0600
+
+ Add missing transform for projected 3D mesh lines.
+
+commit baf1e366451674409dbbf282217dc8c18008878d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 19:47:40 2008 -0600
+
+ Use cornermean instead of center.
+
+commit 111691e9df8d41241f77121f0ce3ebf8ad1cb692
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 19:26:02 2008 -0600
+
+ Add missing put argument.
+
+commit f5779a58acced80e808dff0cf15ac79c8b0c7c7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 17:43:03 2008 -0600
+
+ Fix range check in both places; consolidate PostScript code.
+
+commit e137c77e2a32a206713a3f7443d688b1e4cd82f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 17:27:37 2008 -0600
+
+ Fix range check in strokepath (and potentially texpath).
+
+commit 7fbd94c2ecd14edd2a913d6688cf89eb1cb2e29a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 16:32:44 2008 -0600
+
+ Implement functions that construct a pen array from a given function and
+ palette.
+
+ Add elevation example.
+
+commit a5184d084df93f6298baccf0ce70f69bae24afc1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 15:22:09 2008 -0600
+
+ Add support for using a different surfacepen for each patch.
+
+commit 6009d4388f7454fb311d7decc947436c9566f733
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 13:17:34 2008 -0600
+
+ Document default pen argument of strokepath.
+
+commit 1360af6abbce73279628714c4c3ff048976d79a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 19 10:31:51 2008 -0600
+
+ Implement path[] strokepath(path g, pen p), which returns the path array that
+ PostScript would fill in drawing path g with pen p.
+
+commit 2740298fede8465a7642bc2a18dea281021d9df6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 13:53:43 2008 -0600
+
+ Increment version to 1.47svn.
+
+commit 9bb668cc88ca35249be96f355cbc7b75c45b6d68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 12:36:00 2008 -0600
+
+ Allow one to disable embedding of inline PRC files within LaTeX.
+
+commit 84cf6bbf3325e893e010a53c21274357985ead03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 11:48:45 2008 -0600
+
+ Try to produce a preview image of latexusage for the manual.
+
+commit 568f4e34ba370328955aee1bc4e8eafb48c861f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 11:01:22 2008 -0600
+
+ Signal an error if the user tries to render an image without freeglut.
+
+ Support embedding of 3D PRC files when -render=0.
+
+commit 5118c4d0066843a6ba900ae7f956bd822fdbb2bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 02:48:43 2008 -0600
+
+ Update examples.
+
+commit 4c7b3ff91a370dac01708dfe0a8c0922d1d6d457
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 02:35:15 2008 -0600
+
+ Update example.
+
+commit e722dc5cd0da79515c7463cfeb0773a49419939a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 02:30:53 2008 -0600
+
+ Increment version to 1.46svn.
+
+commit a08904f2e1b719095530bb6586ce57b9bb51f4d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 18 00:46:29 2008 -0600
+
+ Add planeproject routines, courtesy of Philippe Ivaldi.
+
+commit d01ca3e35f5b66b5adff25cd45aaf760bf4b993e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 23:44:47 2008 -0600
+
+ Documentation updates.
+
+commit eb9fb24438bc8553b4a5b0adb3c1cc014e4bb0f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 21:12:11 2008 -0600
+
+ Fix fitting issues.
+
+commit 5ae120c2b28d950c09df3b4b4fe3540168bb1d78
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 16:55:36 2008 -0600
+
+ Fix handling of minimumsize.
+
+commit 450be86ce3a140bbc7e013518e48e29d68ad8631
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 16:07:48 2008 -0600
+
+ Increase tolerance of normal(path3).
+
+commit 3bb03bf62429777e16aabbb40357ffada91a2aec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 14:11:32 2008 -0600
+
+ Standardize embed options; fix labels.
+
+commit 918322f8395ac985874b5d0417766e31feed1ba9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 13:25:17 2008 -0600
+
+ Add link to PRC specification.
+
+commit 2a794557026dd10ea67fd140a79d8ef9155612c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 11:52:14 2008 -0600
+
+ Fix dir normalizations.
+
+ Ignore spurious warnings from degrees.
+
+commit 434b5d12403d6b61afba453fe17dbe1366853821
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 11:20:47 2008 -0600
+
+ Illustrate use of global TeX macro.
+
+commit 7f25fea2532f514f4e2cd0eabc7a7e4cac68f0e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 01:26:45 2008 -0600
+
+ Document direction invert routine.
+
+commit 7d845ac8dfd8a4ce5d23c1363509f5e194abee03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 17 01:19:46 2008 -0600
+
+ Fix DefaultHead3 size.
+
+ Update documentation.
+
+commit b787b05159710e06c3487a7ce6047dc8a1272006
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 16 22:32:10 2008 -0600
+
+ Add 2D versions of accel and radius of curvature functions.
+
+commit bacaedc1bd39ca476fb99b10ab078778851a1bae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 16 21:48:08 2008 -0600
+
+ Fix radius and non-normalized dir functions.
+
+commit 23731a6187fa578d96593694e7e8e2b15044533f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 16 11:37:26 2008 -0600
+
+ Fix numerical resolution issue.
+
+commit ae5229645dc61337e71c72a53204d0c8c5251147
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 16 01:08:49 2008 -0600
+
+ Add a routine to compute the radius of curvature of a path3 at a point.
+
+ Improve adaptive thick line algorithm.
+
+ Add option to suppress normalization of dir functions.
+
+ Remove secondary camera adjustment call.
+
+commit 53437664816df95947bd6b22e7047ca433046498
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 15 18:12:14 2008 -0600
+
+ Minor optimization.
+
+commit 1e5ad6e703157c922b9b020c30d2e58c288c9a03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 15 18:03:05 2008 -0600
+
+ Fix arrow3 sizing.
+
+commit 932d58b7843a368a112847c2e166c244c92d3373
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 15 00:14:19 2008 -0600
+
+ Implement triple invert(pair dir, triple v, projection P=currentprojection).
+
+ Add a 3D arrow routine that accepts a pair direction.
+
+commit d39eaeeda70a4bc3973d328897e1b0796d295efb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 14 23:42:35 2008 -0600
+
+ Add HookHead3 and TeXHead3 arrowhead styles.
+
+commit 14aaabac9f0337624ee86c74f36b5b2ad7e5442b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 14 17:16:17 2008 -0600
+
+ Optimize 2D arclength calculation for straight segments.
+
+commit fe419cd7baea414ffd6f92a17d24afccfb426fdf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 14 17:15:31 2008 -0600
+
+ Fix degenerate perp vector workaround.
+
+commit 72c86d263469f4451fc0d3abe803c0d9f15a141c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 14 17:14:27 2008 -0600
+
+ Optimize arclength calculation for straight segments.
+
+commit 738a2255ebe0c5a8a2014fdb4fff9e6ec1ab9c43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 14 15:24:08 2008 -0600
+
+ Fix degenerate perp vectors.
+
+commit 3388c706edcf4159ae87503bee618befe94090f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 14 14:21:57 2008 -0600
+
+ Fix nullpath and nullpath3 issues.
+
+ Use user coordinates in camera diagnostics.
+
+commit e2d10ddde7df0b81d5ad81c67f9f351865ceafc3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 14 11:01:52 2008 -0600
+
+ Move surface constructor for surfaces of rotation from solids to three_surfaces.
+
+ Add surface constructor planar(path3).
+
+ Add path(path3, pair P(triple)=xypart) constructor.
+
+commit fec16d215047435adfa9111632f46c893fcb7d1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 13 22:40:10 2008 -0600
+
+ Fix degenerate perp vectors.
+
+commit b469972c200c0c7c56e89450be844725ee140af0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 13 21:49:53 2008 -0600
+
+ Improve automatic camera adjustment.
+
+commit 47ef47556935f1b4d3aa9165cd8e86103cd7c689
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 13 20:36:06 2008 -0600
+
+ Fix transition between rendering algorithms.
+
+ Fix handling of currentlight=nolight.
+
+ Change default light for mesh lines to surface light.
+
+commit b7033d26e5e86717787c3d7759d58a696d30246e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 13 13:28:07 2008 -0600
+
+ Fix window sizing problems.
+
+ Tweak constant.
+
+commit 3a01cf4c74883209b8f9b9831715c3491a813bb4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 13 10:00:22 2008 -0600
+
+ Install externalprc.tex.
+
+commit baae1e504001f309073a01c13aeab4856af2fbe3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 13 01:26:29 2008 -0600
+
+ Avoid cracks in thick lines.
+
+ Add connector sphere for cyclic paths.
+
+commit f94d0b4e62f3360e2a00a9a56384d9972ef9270d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 13 00:44:45 2008 -0600
+
+ Enable linetype offset.
+
+commit e7a0ad4062b13b04c2436c45c797ca18dc779a89
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 12 23:39:48 2008 -0600
+
+ Transform computed surface normals.
+
+ Reduce planar normal constant for accurate rendering.
+
+commit c6379e473d1ef3581558b211757da30fd24c71dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 12 21:13:04 2008 -0600
+
+ Add Orest's patch to make short connections before longer ones.
+
+commit 1ebe7b45b06798b414e70cb105f2cf87a502dfb1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 12 13:35:26 2008 -0600
+
+ Fix rendering of planar surfaces.
+
+commit c90bf5333a69acb9349fdd1536c9942189e98151
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 12 11:33:24 2008 -0600
+
+ Fix settings.render=0.
+
+commit ff63393e73591bf3b466f8b9bc40da50423d376c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 12 00:29:13 2008 -0600
+
+ Fix freeglut dependency.
+
+commit d345f631455b8af7748a32595f61f209b4343c72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 11 23:59:50 2008 -0600
+
+ Remove texhash dependency from RPM spec file.
+
+commit b88d4ff8e42f94497f711834bd636cd051ed7591
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 11 23:10:17 2008 -0600
+
+ Speed up rendering of straight surfaces.
+
+commit 81db85450d667bcbfa0cee08f8b7b7a0f4c4da87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 11 22:02:50 2008 -0600
+
+ Treat duplicate nodes as straight segments.
+
+ Make write(path) indicate straight segments, consistent with write(path3).
+
+commit 2503ca4d1ad2ce82ab46b741f4f5826f577aa56f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 11 14:48:32 2008 -0600
+
+ Size 2D and 3D objects consistently when render=0.
+
+commit 62ad2e45a245997657b1a48797fe7aa5dd559191
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 11 11:09:55 2008 -0600
+
+ Respect prefix and format arguments.
+
+commit 5caa2cc71777b1bb4da0fddc03e0571a6eb5c360
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 11 00:14:43 2008 -0600
+
+ Fix normal for degenerate paths.
+
+commit e0197dd54d4529cfa67ccd52e344f913bdec06b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 23:38:12 2008 -0600
+
+ Resolve ambiguity.
+
+ Optimize normal.
+
+commit b852780739cd4bb22af63989e38acc517730843d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 23:09:04 2008 -0600
+
+ Fix straightness test.
+
+ Draw a sphere if path3 has length 0 with roundcap but not squarecap or
+ extendcap, consistent with the behaviour of PostScript in 2D.
+
+commit e62b0e605a8180dc79da3924b7689cc917eba92a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 21:40:24 2008 -0600
+
+ Remove -unsafe option in favour of -nosafe setting.
+
+ Remove unused code.
+
+commit 0497d1c36a9804d5d4cd7ef9dcfb5dd14599d2a8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 10 19:47:52 2008 -0600
+
+ Added testing of permissions.
+
+commit 78f09201a89f87fa42e569870f1a204046eb92de
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 10 18:47:43 2008 -0600
+
+ Added secure options as read-only settings.
+
+commit 7b8f87e5a582f369b7ced78f5f1385982e06e8c3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 10 17:42:54 2008 -0600
+
+ Added optional tests to audit the type and application caching.
+
+commit 8ccab01d6fe468e730d2a79d32f75df4a1b94f18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 17:35:57 2008 -0600
+
+ Document texpath.
+
+ Standardize write(path3) formatting.
+
+commit 34290dca518ad649093ec17e0bc2cf699b2e9279
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 09:27:34 2008 -0600
+
+ Fix example.
+
+commit 05daf2ea53e09caaceaf8234cc0258a9fa1fa16e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 09:24:00 2008 -0600
+
+ Fix compilation error.
+
+commit a0e55c7d1ceb54cde843700161902b663b943abb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 09:22:09 2008 -0600
+
+ Add missing return value.
+
+commit 60d1a1051c405c20214b8eeb74d37b5ea5cc68a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 09:10:00 2008 -0600
+
+ Document convert, animate, and system; add args option to animate.
+
+ Fix segmentation fault in system.
+
+commit 575edaeefd1daa8877ff91d3b3c38ffb7823e8dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 08:18:48 2008 -0600
+
+ Add files missing from last revision.
+
+commit 4b34812c6222d7639176cb150c4ce0cb61a62197
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 02:45:32 2008 -0600
+
+ Make default surface color black now that lighting is on by default
+ (otherwise planar surfaces might not be visible).
+
+ Add unithemisphere.
+
+ Draw hemispheres rather than spheres at joints.
+
+ Simplify linecap code.
+
+ Use linecap(0) by default for meshlines.
+
+ Don't draw thin line if opacity of pen is less than 1.
+
+commit 63785292a8872eea4482057643ca8d4e313484f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 00:58:16 2008 -0600
+
+ Add min and max arguments to axes and axes3.
+
+commit 19aa769f07f3552b8fcaa172abe2fc3315945bb0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 10 00:52:48 2008 -0600
+
+ Simplify paths.
+
+commit 86afa75132b7408133e32953a1182b2877381534
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 9 22:12:26 2008 -0600
+
+ Allow the specification of fuzz=0 in intersection routines (the new
+ default, fuzz=-1, specifies a fixed multiple of the machine precision).
+
+commit 770063a8564a3caeeda2b5daa9d1c5c53c70f08d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 9 21:34:15 2008 -0600
+
+ Fix division by zero error.
+
+commit 19c3e714f4aa541026e7f8ce54cf49511d2a3336
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Oct 9 19:23:43 2008 -0600
+
+ Improve splitting of triangular patches.
+
+commit bb431ae8b39aa8c66bae401438839f4e9e1d259b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 9 01:23:49 2008 -0600
+
+ Fix longitudinal lines in solids.asy.
+
+ Split longitudinal curves into front and back pieces; add
+ longintudinalpen=frontpen and longintudinalbackpen=backpen.
+
+ Use longitudinalpen=nullpen instead of longitudinal=false.
+
+ Make dash lengths in solids.asy consistent between different rendering modes.
+
+ Fix OpenGL opacity calculation (only for settings.render=0).
+
+ Set P.ninterpolate to 1 for projections from infinity.
+
+ Fix 3D dashed lines for degenerate cyclic paths.
+
+ Increase fuzz in 3D arc and Arc routines.
+
+ Update cone radix in solids.asy.
+
+commit a879e30890cc04c2e386415857144c1260ace1dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 8 21:57:16 2008 -0600
+
+ Fix arctime for cyclic paths of zero arclength.
+
+commit 246b189492f41e694ce067bcc139af0cc2d77332
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 7 15:50:10 2008 -0600
+
+ Reduce number of patches in unitcone.
+
+ Rename solidcone to unitsolidcone.
+
+ Improve appearance of straight arrows.
+
+ Increase fuzz in arrow end tests.
+
+commit 7d47f3d7e53f6999ec8ba5e463cd5533c999adf0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 7 14:27:36 2008 -0600
+
+ Add arrow to NoTicks.
+
+commit 2350e092e97f564193df1afa0241b13ab1b8fad1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 7 13:57:30 2008 -0600
+
+ Fix transverse slices.
+
+commit 236f3d2e2acbc367c991d4614deefa37a2063bbc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 7 12:00:47 2008 -0600
+
+ Give user control over slice Arc accuracy.
+
+commit 6d460c3889480d4fd88a6e3f3567b0fc27a13566
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 7 11:32:08 2008 -0600
+
+ Increase longitudinal epsilon.
+
+commit 0626509ce02f1c0473fcfd481f089c2e6824fd2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 16:49:30 2008 -0600
+
+ Document need for version 2008/01/16 or later of the movie15 package.
+
+commit adfd8d95fb575a4e7511cde1170150fc5cccea0e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 16:19:50 2008 -0600
+
+ Fix incorrect cast.
+
+ Resolve ambiguities.
+
+commit 691fdeba886be97a0b7fc5c44ebfa0cd73dd48d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 12:26:16 2008 -0600
+
+ Update documentation.
+
+commit bbd1c8040d2e7d645227a729cc923133d9cdf96f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 12:05:43 2008 -0600
+
+ Add utility for forcing Adobe Reader to update all currently loaded documents.
+
+commit e47173ba27d35777b1edd1d30e95f839901f42e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 11:24:49 2008 -0600
+
+ Use NUL instead of /dev/null under MSWindows.
+
+commit b6e12abbc219dfaf582b24788bd6d11f65183dcd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 05:36:07 2008 -0600
+
+ Increment version to 1.45svn.
+
+commit 9c86cdd6a32142cca7fe4a443bc36192cba2e098
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 03:48:54 2008 -0600
+
+ Update documentation.
+
+commit 01ed46270df994548349be0f2e6b112b2f5b9644
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 6 01:09:53 2008 -0600
+
+ Remove settings.tex="pdflatex" from embed.asy and move contents of
+ embedding.asy into this file.
+
+ Generalize movie15 patch to pdflatex; restore @ catcode to its previous value.
+
+ Reduce size of manual.
+
+commit 987faf990fb1adec72aaf3f72b9176e9ca034cff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 5 21:20:57 2008 -0600
+
+ Fix missing BBox bug in movie15 version 2008/01/16.
+
+commit a245d161df6b5603452b42d10a198ffa31666167
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 5 03:33:08 2008 -0600
+
+ Handle degenerate scaling.
+
+ Fix manual build problems.
+
+ Update examples and documentation.
+
+commit 9c9c3fadd3a230f6d2ecefdd85a6f935ca9e9934
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 23:13:48 2008 -0600
+
+ Fix absolute viewpoints.
+
+commit d38da2db56425068f34003393540912efc22ab16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 19:18:49 2008 -0600
+
+ Fix example.
+
+commit 5662f10ca793475007c144f8e15edb4d7cb9cd8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 18:18:00 2008 -0600
+
+ Fix examples.
+
+commit 1e3bbb896eca8318e3c450502f46ca0035713496
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 17:12:05 2008 -0600
+
+ Add file missing from last revision.
+
+commit 75d1a9ebd17d7a737756dceafdc7def97cb17ed0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 17:11:37 2008 -0600
+
+ Improve definition of unitcone.
+
+ Make xasy work again with 3D pictures.
+
+commit f600479daf9a0ebddfaf68714df208444d76cf4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 14:53:47 2008 -0600
+
+ Remove interp(int,int,real).
+
+commit 4aa519732f652230ecaedc8e54cd52fb609a6eda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 11:45:14 2008 -0600
+
+ Handle degenerate point in cone.
+
+ Tweak parameter in thick lines.
+
+commit 355a989ef64871ef160394f74f36abb71d79508a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 4 01:15:46 2008 -0600
+
+ Fix cracks in thick lines.
+
+ Fix projection and clipping.
+
+ Fix 3D animations.
+
+commit 2e9ccd5d05b774d3e21a4b799536510c2b440a95
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 3 17:21:00 2008 -0600
+
+ Force -noprc during documentation builds.
+
+commit 8365dfbfa96fd6d787cc7a9a4f2a710a2b3dbc5c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 3 17:07:00 2008 -0600
+
+ Fixed matching of defaults for functions with rest arguments.
+
+commit dfed4bfb80e49c5fe703a93dded72ccfaa0df450
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 3 16:32:10 2008 -0600
+
+ Make latexusage produce a rendered image by default.
+
+commit d53e950205d309c69c2f4558351cf133addf8b12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 3 15:49:34 2008 -0600
+
+ Respect -noprc.
+
+commit f6022f259b33bfe692f0291b7cd4a32f17e609a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 3 04:09:58 2008 -0600
+
+ Remove references to obsolete modules.
+
+commit 2ce92f4ebdf01e44843b7ad281430135c319a4e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 3 03:43:53 2008 -0600
+
+ Restore symmetric clipping planes.
+
+ Fix embed ambiguity.
+
+ Update examples.
+
+ Make preliminary documentation updates.
+
+commit bd1cd3509b9156cc0addfe043a5a3e9a33185384
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 3 01:01:09 2008 -0600
+
+ Use a better default for tick and axis label selection.
+
+commit 8ce64fdbab5ce351116d5526b5c8e2836a41510c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 3 00:02:26 2008 -0600
+
+ Return a zero scaling when unbounded (revert 1.44-252); see generalaxis3.
+
+ Rename LeftTicks3 to InTicks, RightTicks3 to OutTicks, and Ticks3 to InOutTicks.
+
+commit 2506b0faf7f20bf480fdf5796d5aa37de880d3b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 2 16:47:12 2008 -0600
+
+ Remove unused code.
+
+commit fbf60a9cd7a93e4ec4f71634f81a009b2eba1e67
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 2 16:43:22 2008 -0600
+
+ Support PRC images even when inlinetex=false.
+
+commit 9812fa6d9e85f2c117c9e764e237fc08b9a931a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 2 02:40:10 2008 -0600
+
+ Support PRC, with optional rendered preview, in inlinetex mode.
+
+commit 3780d2fdfd74873a0a41e92c763992d72b911df3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 1 23:50:15 2008 -0600
+
+ Work around degenerate up vectors.
+
+commit 59235a64322e4d9af3aacf87d82605821486979e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 1 22:45:06 2008 -0600
+
+ Fix perspective projections and clipping.
+
+commit 6c4d4326ea56ef3164a4757b533ad7a49eca5724
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 1 21:34:38 2008 -0600
+
+ Fix reference vector indices.
+
+commit e18c8f9739b31ce0d8716dd4d34a4affdadc71a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 1 20:56:14 2008 -0600
+
+ Support prc with pdflatex.
+
+ Fix light transforms.
+
+ Use sequence for array loops.
+
+commit d90fb9cab118ea3761dd2c2eca5fc5a9df7864db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 1 14:07:53 2008 -0600
+
+ Support texpath in inlinetex mode.
+
+commit 4840f25bc8cc76d5b008baff72b31301c35d97cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 1 03:45:46 2008 -0600
+
+ Fix sizing of perspective projections by usingd an accurate subdivison
+ algorithm to calculate the optimal field of view angle.
+
+ Use an accurate projected path3 bound for picture sizing.
+
+ Optimize projection routines.
+
+commit 9b9bf22e4c751ecc7b2405c4028fcafb1b52a7d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 30 11:58:22 2008 -0600
+
+ Don't cache projected bounds.
+
+commit 889b91cee23aee5799618c789bc8b4daf5fd83bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 30 10:59:03 2008 -0600
+
+ Fix rendering from an absolute viewpoint.
+
+commit 7b811cdad3343f270edbb96afc40c57291aca5f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 30 03:53:15 2008 -0600
+
+ Fix picture sizing and clipping plane.
+
+commit d0a1de8b34ba2ed05cd1fc0b8a1c0538d17665ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 30 02:14:12 2008 -0600
+
+ Use a separate frame for preview rendering.
+
+commit 4977cb85f158f2e643f2958a7ca1a0e907e31b0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 29 19:01:39 2008 -0600
+
+ Minor optimizations.
+
+commit 12c7b6a47985ae0aa110ca39c575ec87a9a5a6df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 29 03:39:09 2008 -0600
+
+ Limit window to physical screen size under MSWindows due to OS limitations.
+
+commit ae0ab2d344985ca2027a223fb009fd67085f66b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 29 02:08:52 2008 -0600
+
+ Fix window size checks.
+
+commit 51819e119ff82a0e29daaceb67f75a1bba0c5a58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 29 01:41:25 2008 -0600
+
+ Use gluEndCurve not gluEndSurface.
+
+commit 9075f472590c9760a94c247cf5d7d12b162b7e81
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 29 01:09:16 2008 -0600
+
+ Allocate image rather than putting it on the stack.
+
+commit 10b0cbf91b825294005d095f37084cf93c30e896
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 29 00:47:41 2008 -0600
+
+ Optimize solids.asy.
+
+commit 04e54c5eaaf34b67f3f7054689503c8e4e2e1131
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 23:01:01 2008 -0600
+
+ Fix shrink (- or _) and expand (+ or =) keys.
+
+commit d168f5736ad199d1b0b7decee1e5a88314639289
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 22:25:20 2008 -0600
+
+ Remove unneeded bzero.
+
+commit 85d1559a9d219a17ab1ea1676f3771fff60b8675
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 22:22:19 2008 -0600
+
+ Port to cygwin.
+
+commit c39a492a8574f1d5ab3ab7518466820e110976c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 21:46:48 2008 -0600
+
+ Fix cygwin configuration.
+
+commit 27ef19ce3571c07f47ae25a8547faf10f40f590c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 12:58:51 2008 -0600
+
+ Support CYGWIN freeglut configuration.
+
+commit 966268d31497e4778bdb659aa180399390fceb88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 11:56:33 2008 -0600
+
+ Avoid redundant transformation for infinite projections.
+
+commit 953ad71d6dfd10a0ddafa7ee8540ea6dc7df3fb4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 11:47:50 2008 -0600
+
+ Preserve aspect ratio on export.
+
+ Work around viewport size driver bugs.
+
+commit 5fbdf27645360c0a1effc27dd325d384301e3009
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 28 03:27:07 2008 -0600
+
+ Port to cygwin.
+
+ Wait until menu disappears before exporting.
+
+ Right button without motion, in addition to middle button, now brings up menu.
+
+ Fix export segmentation fault.
+
+ Fix mesh mode.
+
+commit 7edb1c93d655cddc5562dc38ebff6cbdb8736e62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 27 10:37:38 2008 -0600
+
+ Add missing 2D Arc routiones.
+
+ Remove unusual handling of negative radii.
+
+ Update arc and Arc documentation.
+
+commit 6abd91a066dbe564210c7c1c4185cc26e782aba9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 27 03:17:06 2008 -0600
+
+ Render at requested size in interactive mode.
+
+ Fix transverse slices of solids of revolution.
+
+ Simplify arc and Arc routines.
+
+ Check for invalid normal vectors in 3D arc and Arc.
+
+commit 36999977922c983da159e435d3f302efd001401b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 27 00:29:16 2008 -0600
+
+ Preliminary changes to support CYGWIN.
+
+commit 9314d7e7887d1eb9be676e6a0582e671323bee31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 27 00:18:48 2008 -0600
+
+ Remove psimage code.
+
+commit b449661b1b3f3043852f3a6ce690105425c3aabc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 26 23:38:00 2008 -0600
+
+ Remove obsolete psimage feature (use -render=n instead).
+
+commit 8e814f5d9ff6876292ad53206bf47e2e05cb35c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 26 23:33:09 2008 -0600
+
+ Fix path3 rendering.
+
+ Add meshlight option to surface routines.
+
+ Improve glrender mesh mode.
+
+ Simplify light constructors.
+
+ Clean up code.
+
+ Remove OpenGL license from glrender.cc as the original code has been
+ completely replaced by our own code.
+
+ Update examples.
+
+ Remove unused lights.js file.
+
+commit b5f168b67aa737a7f11c0a7da3e9546672450255
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 26 12:53:55 2008 -0600
+
+ Make object argument optional in flowchart routines.
+
+commit a1cb3ff0719f028623e9a28fe3b21e0ef35ef512
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 25 00:31:50 2008 -0600
+
+ Standardize lightmodel with openGL; support multiple lights.
+
+ Add viewport option to light to force lights to be fixed in the viewport frame.
+
+ Communicate non-viewport lights to embedded PRC files.
+
+ Add +/- expand/shrink keyboard shortcuts.
+
+commit 3183cd3346d88442a0f34e86b7092d614faed252
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 24 03:34:35 2008 -0600
+
+ Replace the light model with the one used by openGL.
+
+ Use nurb routine whenever the surface is not straight and the light is on.
+
+ Add -nothin option to force pen thin to be set to the initial defaultpen.
+
+ Support custom embedded javascript files via a script option to shipout;
+ add lights.js example.
+
+commit d310ac530844a01f943e63a42fe488fdf3e81d1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 24 03:25:34 2008 -0600
+
+ Set the opacity of the sum of two pens to be the larger of the two
+ opacities, adopting the blending mode of the second pen.
+
+commit 900a2509e7e48eeeecfb9244742664462c32d40c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 23 02:18:57 2008 -0600
+
+ Fix more material vs. pen problems.
+
+ Improve degenerate normal test.
+
+commit 19f717837954a62b9b6f5bc133dabddd929c2da8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 23:16:10 2008 -0600
+
+ If the render value is negative, use 4 times its absolute value for rendering
+ eps and pdf formats and 2 times its absolute value for rendering other formats.
+
+ Turn light off for drawing meshes.
+
+ Specify light coordinates in viewport frame.
+
+ Fix line colors.
+
+ Provide an optimized patch constructor for quadrilaterals.
+
+commit 46b54b99f4060c19d23fc9cb5814dc1391324628
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 17:24:11 2008 -0600
+
+ Remove preview option in favour of render=n > 0.
+
+ Fix line material defaults.
+
+ Viewer is no longer updated by erase() since we don't know whether the
+ original picture was 2D or 3D and reloading acroread is slow.
+
+ Spurious shipouts arising from cameralink are now suppressed.
+
+commit c9f40fcc55c2c9354330749bf8208ceb3640b595
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 14:51:56 2008 -0600
+
+ Add option -preview to render 3D preview image.
+
+commit fac8c870a1e483c08963f7d794936f4f99ed6b3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 11:52:56 2008 -0600
+
+ Remove obsolete outward flag.
+
+commit 790ac4aecde366b2f22c77aab5f9540c2ce6a236
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 09:05:17 2008 -0600
+
+ Revert last change.
+
+commit d9f599e28adbf465adb9fd685e467da4a53e8be0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 09:03:50 2008 -0600
+
+ Suppress another unnecessary warning.
+
+commit 8106ef18917d33c053c69d885417e76c1b30c7ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 08:45:44 2008 -0600
+
+ Suppress unnecessary warnings from automatic picture sizing.
+
+commit f03f00939aba56d9e4fe4f58d61ac3d74f6a3bbd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 22 03:05:03 2008 -0600
+
+ Support orthographic projections in PRC.
+
+ Fix definition of emissive.
+
+ Transform currentlight correctly in shipout3.
+
+commit 6b10a32eacf8291eca8e3bbfb60a7abfac24a847
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 21 14:43:48 2008 -0600
+
+ Fix orthographic and oblique clipping.
+
+commit cd2ead2066972765f47086fd2d169954230f0ae9
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sun Sep 21 14:10:34 2008 -0600
+
+ Fix z rotation.
+
+commit b8662acce03a7f8f6f663705b6ee264e31ec490d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 21 13:34:37 2008 -0600
+
+ Support compilation without freeglut.
+
+commit 34ee9b3a14f79efb2524e63929d3585450bb6854
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 21 11:33:45 2008 -0600
+
+ Fix normal0.
+
+commit f79f8e84dec627eb3f1adcad2b0cb520d87d8924
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 21 11:32:55 2008 -0600
+
+ Add optimized vertex normal routines.
+
+ Add fuzz to arrow position test.
+
+commit 6c368a1e776dd57fcc89b986d4dccf9d219ade4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 21 00:57:00 2008 -0600
+
+ Fix includes.
+
+commit 356eaf53fb4cb3f795185b8b5bb431f0a5af903d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 21 00:52:01 2008 -0600
+
+ Fix glOrtho parameters.
+
+commit 1a022b26985d53b7be158756fdfe1dc610fe4a7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 20 23:59:37 2008 -0600
+
+ Improve surface culling.
+
+ Use GLUnurb for rendering a path3 (unless it is piecewise straight).
+
+commit af0b8965ea4d0a46eaf0efdb032e8090607de630
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Sep 20 14:20:06 2008 -0600
+
+ Undo renaming of slidemovies.asy.
+
+commit f4acd62482a50ef7ec3a614a3e4262d11b0034a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 22:55:58 2008 -0600
+
+ Adjust rendering constants.
+
+commit e51d2f144c16a99b6e65eb08aa52654877b98109
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 22:36:16 2008 -0600
+
+ Update convert options; add convertOptions setting.
+
+commit de8c612435501b4bfd160adc6213b83602eb9703
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 14:58:20 2008 -0600
+
+ Allow compilation without freeglut library.
+
+ Fix width and height sizing.
+
+commit 512c14d4c3aad03906ef62376ed7bea0106c92fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 13:36:35 2008 -0600
+
+ Use render setting for convert.
+
+commit c2c5ad1d9043daae40db4df06295ae4405eca4c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 13:08:14 2008 -0600
+
+ Add antialias=false option to image routines.
+
+commit 5c675ac18ab4fbddc1233f8395ed3da286d12bba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 12:44:53 2008 -0600
+
+ Improve configuration diagnostics.
+
+commit e5a0f320946b4efdaa1e5f19ab961e3892fec445
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 01:59:23 2008 -0600
+
+ Don't dealias last column of pixels.
+
+commit e072aff3638f8f23a30feb3ef7b2dd9b5430bb2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 01:55:18 2008 -0600
+
+ Fix segmentation fault: don't dealias the top row of pixels.
+
+commit 8c29b6213d34ac0113a7804b84dafe9923eb6c99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 01:20:05 2008 -0600
+
+ Support antialiasing of all images.
+
+commit 9186b72c973070bc2479f036a4a29e1e359975ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 19 01:10:51 2008 -0600
+
+ Support inline antialiasing.
+
+commit 18d37540940bee3fb91146a53fdce9be60893840
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 18 23:18:41 2008 -0600
+
+ Improve rendering options.
+
+commit b438f03c022db3d669be8f6b4a04f45e04183808
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 18 12:25:57 2008 -0600
+
+ Antialias export images.
+
+commit 429d37d34f8e8b6cb1356afabeb85df36316fe6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 18 12:11:57 2008 -0600
+
+ Fix export.
+
+commit 6e62cb14a4c1001e0412ac439d8a5e0be46d2828
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 18 03:47:05 2008 -0600
+
+ Simplify and optimize surface rendering.
+
+commit d86c200e1a646282a44582c6a392918aecf53b21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 18 02:23:07 2008 -0600
+
+ Always use nurb rendering algorithm (with callback) for degenerate patches
+ when the light is on.
+
+commit b0edb45297df294e72a11e8a9a046d072a069520
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 18 00:17:53 2008 -0600
+
+ Fix rendering artifacts at degenerate control points.
+
+ Improve unitcone.
+
+commit 474f0747c777b9f1ebc921df4261adbe1a26d57e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 17 08:55:44 2008 -0600
+
+ Add a maxviewport setting for working around direct rendering driver bugs.
+
+commit d848274e3bbfab5cb07c6f81eac43c4076c5b27c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 23:47:20 2008 -0600
+
+ Retune rendering parameters.
+
+commit a4b88696b58eb0bbc59bd8e84626368e94a92b5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 22:28:11 2008 -0600
+
+ Add mesh mode menu.
+
+commit c46b8b39cbb403c4134c8ce3174f479eb7803bbc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 19:34:29 2008 -0600
+
+ Force a minimum rendering window size.
+
+commit d939ff4ee61b9d3d3ac69c355a52626ef3b87e16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 19:06:42 2008 -0600
+
+ Allow explicit surface normals to be specified (currently only respected
+ when render=0).
+
+commit a4c7d2fcd4cb0886b00743677bf390077490cea2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 17:42:33 2008 -0600
+
+ Work around direct rendering segmentation faults.
+
+ Improve full screen mode.
+
+commit d8252c49470d6ad0ada0562d47aac8838ac8781e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 13:29:55 2008 -0600
+
+ Use fullscreen rendering by default.
+
+commit 8af536b3f4f210ced538d0ffdc0cb10afb811f17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 09:21:24 2008 -0600
+
+ Remove broken bounding box test optimization.
+
+commit 579686b62eba7c13f3b9f9cea06f99dd70507b93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 16 02:08:38 2008 -0600
+
+ Use hybrid EvalMesh2/NurbSurface rendering algorithm for better speed &
+ accuracy.
+
+ Remove localsub option.
+
+ Rename int path3quality back to bool thick.
+
+commit 7db8eefb7fef904c05bc958868e25daf62933840
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 15 23:13:09 2008 -0600
+
+ Add toggle fullscreen menu option.
+
+ Add further keycodes.
+
+commit 3cb3b04554dbed6087519ed330b0aca4e422f853
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 15 17:31:58 2008 -0600
+
+ Initialize timer before spinning.
+
+commit 6ca3a4020e8d5ca9c8bc45e0e2e6f36a28b49542
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 15 17:21:28 2008 -0600
+
+ Improve spin/arcball interaction.
+
+ Make the Home menu item reset the zoom.
+
+commit 10939a78da05590a21afa5fbcf6a5e9378098f01
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 15 08:49:52 2008 -0600
+
+ Use -render=0 instead of -norender.
+
+commit 082dd13f4d48af08c451532f1c128dc75599ecb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 14 22:03:32 2008 -0600
+
+ Use a better reference value in path and path3 dir functions.
+
+ Fix zoom/rotate synchronization.
+
+commit 64b7a1dca9805837643a1d50557bd170ffcdb487
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 14 20:53:45 2008 -0600
+
+ Simplify dir(path, real) and dir(path3, real) computations.
+
+ Fix accel(path3, real).
+
+commit 7a28d7c623e781bc4c094b1578d60fd3dd0d0114
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 14 09:56:50 2008 -0600
+
+ Add position parameter to specify initial rendering screen position
+ (negative components indicate relative to screen width or height).
+
+commit 54059bba3420f566dbde12d28ba47fd45828d8e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 14 09:23:08 2008 -0600
+
+ Add Export and Quit menu items.
+
+commit 08c2c32d2ccf4529ce90034d5d87d902c1ea7519
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 14 03:05:29 2008 -0600
+
+ Remove remaining scale3D factor; retune adaptive constants.
+
+commit 27254d610032645a3876f7ea35e04540f59378d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 14 02:44:01 2008 -0600
+
+ Move PRC cm scaling to a more sensible place.
+
+commit 83febd4929fd9d8a49b1d7fa5e254989537b4742
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 14 01:10:13 2008 -0600
+
+ Fix oblique transformations.
+
+ Rename linequality to path3quality.
+
+commit 194182305179b22ee098a99f94cbb0b1ba7f6f7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 13 22:18:15 2008 -0600
+
+ Add menu (middle mouse button) with Home and Spin options.
+
+commit 7bf3f93c0c2e1c297a9738724ca8e8229ddcc22b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 13 17:57:35 2008 -0600
+
+ Support interactive rendering.
+
+ Remove obsolete Wait and NoWait keywords.
+
+commit ec3bccb1adea541766b4ee11ac3839ba53035120
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 13 13:14:55 2008 -0600
+
+ Add linequality and twosided settings.
+
+commit 58df06a1991ea331a0fb6eb42f5144ec52eebd0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 13 09:43:03 2008 -0600
+
+ Compute surface bounds for transformed frames correctly.
+
+ Speed up rendering by drawing only the surfaces and paths within the field
+ of view.
+
+commit a87f2cd1a8d4366040d840542c7834de386ed3ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 12 21:48:33 2008 -0600
+
+ Fix mouse button zoom.
+
+ Improve mouse bindings.
+
+commit f34bc01af1562c829bef378a1ea983a470777e58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 12 17:04:16 2008 -0600
+
+ More zoom improvements.
+
+commit 1d70efd24bc6b655b7dde06ebe7e8149b413a7c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 12 16:23:47 2008 -0600
+
+ Zoom on center of window; improve resizing.
+
+commit e0d7d872299e724140c941cc6209b8c30ed0d63d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 12 00:42:43 2008 -0600
+
+ Account for field of view factor of 0.6 (from javascript).
+
+commit 1306945bedc1d5c7af28498b69be3f1e069ff1d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 10 01:45:00 2008 -0600
+
+ Compress all images and encode them with ASCII85.
+
+commit bd2d8423cdef245203d3b22a6c135f026f4aef8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 9 10:56:31 2008 -0600
+
+ Force use of new c-lang-defconst for proper indentation after struct.
+
+commit 134e9e374555b88b0f9f70318d87dcab43d12d43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 9 02:57:38 2008 -0600
+
+ Fix add.
+
+commit 53105d5aa0782312daee014be542fd9f6c8d0f43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 9 02:38:47 2008 -0600
+
+ Compress rendered images with zlib.
+
+commit 027634cd45f7170a67372e488bb386e89cfdd352
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 9 00:42:32 2008 -0600
+
+ Support rendering into other colorspaces.
+
+commit e9c85db11e45ee1bf7d14426790031c82c370013
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 8 23:51:16 2008 -0600
+
+ Fix zoom-dependence of arcball radius.
+
+ Fix rendering problems with mixed 2D+3D drawings (ignore 2D drawing).
+
+commit a5412018d8c485ead475553bdcb10730fa7df778
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 8 23:19:00 2008 -0600
+
+ Fix segmentation fault if renderer ends abnormally.
+
+ Use color instead of material for path3 rendering, just as for prc.
+
+ Add thicklocalsub parameter.
+
+ Use two-sided lighting model.
+
+ Fix handling of transparency.
+
+commit d6014b1524b34260afcca32d05ad03998b33484e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 8 02:54:29 2008 -0600
+
+ Disable rendering during builds.
+
+commit 7c59158cdfb005b0f6a41b3d63cd5893b8cdfa4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 8 02:14:24 2008 -0600
+
+ Implement openGL-based adaptive-mesh renderer.
+
+commit f155070f4befcf23d0ac69ee23a8aa92c497a17c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 4 22:57:07 2008 -0600
+
+ Fix surface orientations.
+
+ Optimizations array references.
+
+commit febc21e3943d082cf131ae39237b6da734a47de5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 21:53:57 2008 -0600
+
+ Allow 2D drawings under 3D drawings.
+
+commit a2670bc60d6510d22c015d0726e44be46232d29a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 20:17:36 2008 -0600
+
+ Use consistent notation for control points.
+
+commit a5ce25ee5cf3e515e1128ec256ad6eb92151d385
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 20:16:18 2008 -0600
+
+ Turn off default graph autoscaling.
+
+ Set extend=false by default for 3D axes.
+
+commit f75a43432db7d9737aa380335e4673435c894dcf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 20:14:29 2008 -0600
+
+ Rename Bezier/BezierP to bezier/bezierP.
+
+commit 3191bd7cfe5f54c04e30b85d086d18cf788abcbb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 12:36:21 2008 -0600
+
+ Don't allow curve to reach surface of tube.
+
+commit 5f981eaa8ff78e640e37b7e366e56e21faa2053c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 12:35:00 2008 -0600
+
+ Fix overflow problem.
+
+commit 1e2357150b3fd6ef4242d4b2cd1d7c35014f2880
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 10:12:37 2008 -0600
+
+ Re-enable adjustdash for paths.
+
+commit f3088a65374528b445033c75f22b6e54782dbf8e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 01:50:34 2008 -0600
+
+ Implement add(picture,picture,triple) for adding fixed sized 3D pictures
+ about a point.
+
+ Simplify arrow definition.
+
+ Move supplementary 3D routines from plain_picture.asy to three.asy.
+
+commit 30d00119bdab6aae028a93248dad91fff9bd7e3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 01:02:27 2008 -0600
+
+ Add pen bounds to arrow routine.
+
+commit 4af79abbf8ef1653a58445cdc47d6cbec5c992b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 29 00:54:30 2008 -0600
+
+ Uninstall pixel.pdf.
+
+commit 0a43bfd1418565080f517542b84989a12ae5e2d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 28 09:00:49 2008 -0600
+
+ Fix typo
+
+commit edce2abbabdfe99dadb63f1fa681d2e0eae8c4e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 28 09:00:30 2008 -0600
+
+ Fix file location.
+
+commit f57ae914e78fde268ebe3b1d38720704139dd82d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 28 01:13:22 2008 -0600
+
+ Add missing 3D arrow and dot functions.
+
+ Workaround singular matrices in align routines.
+
+ Fix conditional drawing of surfaces.
+
+ Update examples.
+
+ Delete gc-7.1FreeBSD.patch as it isn't required any more under 7.0-RELEASE-p2.
+
+commit ea94efef01cf69c849c44ed1d9b5c5ebf9a6124e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 23:11:31 2008 -0600
+
+ Fix segmentation fault.
+
+commit d2cdbdda93b4b675eb31e4fc08d0f516dd05798b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 21:58:08 2008 -0600
+
+ Rename dir parameter of axes to align.
+
+ Check that the sum of all dash lengths is positive.
+
+ Install pixel.pdf in examples directory.
+
+ Install silentPrint.js and reload.js in base directory.
+
+commit 0f790770ffaeaa8508c85f322745e8c2405abb87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 21:28:11 2008 -0600
+
+ Add surface bicubic spline code (based on code contributed by Oliver Guibe
+ and the method use in Scilab).
+
+commit a3aa4c22df9c0bfbd1626379f4a603d70849ea17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 16:35:04 2008 -0600
+
+ Improve the appearance of arrows on cyclic paths.
+
+commit 601472905ec1e702f89871b49cf25d3f401c3808
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 16:28:11 2008 -0600
+
+ Implement more accurate and efficient version of accel(path3, double).
+
+ Add missing begingroup3/endgroup3.
+
+ Fix texengine vs. texcommand confusion.
+
+commit 53c8910437384382e8de02f0bd5ba9200a82627f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 15:39:43 2008 -0600
+
+ Check for division by 0.
+
+commit 4a23a12d76899c342d29e1d0452c7be1b76a90cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 15:11:48 2008 -0600
+
+ Return a unit scaling again when unbounded.
+
+commit e37fb5caca7c78b9e88f530caec04e9a41ece07c
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Aug 27 14:38:39 2008 -0600
+
+ Add header for uint32_t.
+
+commit 0444796dae93a99cb289672a23dd2a743ab549a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 02:44:35 2008 -0600
+
+ Optimize projection routines.
+
+ Update cube animation.
+
+commit efab54ed6c6673db8df6c9af565f70d733f3dbdc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 01:43:40 2008 -0600
+
+ Rename keyword.
+
+commit 71b99a925bf23a452730458dacd533807ae3591c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 01:32:48 2008 -0600
+
+ Update examples.
+
+commit b74b79798a55dc0cf45c4cc78c1af1de46f2d763
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 27 00:59:16 2008 -0600
+
+ Try to draw labelled axes on the front boundary.
+
+ Fix tick directions.
+
+ Set axis types explicitly since axis members are volatile.
+
+commit 63d1e620824e48be38c1cddb7327ea0693be211d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 19:36:34 2008 -0600
+
+ Fix path labels.
+
+ Remove filltype argument from 3D functions.
+
+commit 8f8205af5b56fd18077cbbb1bb8e4a5bd659508b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 18:48:43 2008 -0600
+
+ Implement 3D dash length adjustment.
+
+commit a2d8888a8c56da0288ded34098ee0df6783bf10f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 17:20:16 2008 -0600
+
+ Fix granularity; add arrowheadlight().
+
+commit d97cb5a320b7306428c51d410eecd81016df68c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 17:18:35 2008 -0600
+
+ Make arrowheadlight=nolight by default for non-PRC drawings.
+
+commit 761a85828165acffaab4470a86b9b865fc11c283
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 13:41:28 2008 -0600
+
+ Move operator * (transform3, triple) to C++ code.
+
+ Remove align in favour of transpose(transform3); rename transform3 to align.
+
+ Make arrowhead pen a material.
+
+ Add arrowheadlight.
+
+ Add light to PRC draw functions.
+
+ Check all array pointers.
+
+ Add operators == and != for pen arrays.
+
+commit e4729be39b09068788bb91ce4f02f4dd08cc03f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 09:08:01 2008 -0600
+
+ Turn off prc flag for documentation builds.
+
+commit dac52652851c2e82fc783d4f4a7c0c809976991e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 08:52:08 2008 -0600
+
+ Set settings.prc=true by default.
+
+ Update examples.
+
+ Check for nullsurface in three_arrows.
+
+commit 1a20041faad2f518344cbce7f1a83a43118cdf69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 08:15:38 2008 -0600
+
+ Update example.
+
+commit 92d4174af52853cafe91dd47ac44e6b02c1afec1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 08:00:19 2008 -0600
+
+ Add missing file.
+
+commit 74c9bb56087292ba86bfd06289c7df288b1f2a26
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 02:07:26 2008 -0600
+
+ Speed up 3D graphics by moving path3 to C++ code.
+
+ Fix 3D bounding box bugs.
+
+ Remove remaining references to obsolete bbox3 structure.
+
+commit 311eecdc5c30b6eb727c8a36c39067d7d1ad1291
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 26 01:38:13 2008 -0600
+
+ Check all three coordinates in path3.bounds().
+
+commit 24e1ad77890db772dbcb88f6beaef7ac24d57a7c
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Aug 25 20:45:07 2008 -0600
+
+ Add cyclohexane example.
+
+commit 86c756d14b4153ab9f706e0b808ba5238a8f2723
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 25 13:52:20 2008 -0600
+
+ Initialize cycle flag.
+
+commit e883b0a5b5b3b53a4dc2e63441a05bef682f4a48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 25 10:58:46 2008 -0600
+
+ Remove duplicate file.
+
+commit ade7318c47381953d61941422dc8c3a65a8b01e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 25 10:04:46 2008 -0600
+
+ Add settings.thick option for rendering thick PRC lines (default is true).
+
+ Don't force a mesh to be drawn when nolight is specified.
+
+ Add Orest's 3D implementation of the Asymptote logo.
+
+commit 1eddbf05c1b440abe403a922df18e0302a573854
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 25 10:01:38 2008 -0600
+
+ Use truepoint to attach legend in lineargraph.asy.
+
+commit 1b0cfa7dd067ac5a64c8bbd969b60bf38adc2b4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 25 03:01:16 2008 -0600
+
+ Set both axis types; use symbolic values.
+
+commit b1859212d229e190dbca01f94a3427bb53e80f6c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 25 01:59:44 2008 -0600
+
+ Update grid3 to handle Arrow3.
+
+ Use limits in grid3xyz.
+
+commit 738cc4b59239d0f8ab8bc773c777bc127a59f8b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 25 01:11:07 2008 -0600
+
+ Use all control points to compute normal vector of surfaces.
+
+commit 055eb28cec633c0cdd2f3076a109af7b0fbceb54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 24 20:28:36 2008 -0600
+
+ Remove unused code.
+
+commit 4456085abb8e068d31266ae50ac0cae4485f816e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 24 14:44:13 2008 -0600
+
+ Improve arrow bounding box calculation.
+
+ Fix 3D arrow positioning.
+
+ Retune anglefactor for RPC angle calculation.
+
+ Pass the correct size information to scale and scale3 when resizing.
+
+commit 98d4cfccd4abc5a1516e4c0d5f11e0c3f1760831
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 23 13:58:27 2008 -0600
+
+ Implement unitdisk and linecap(0) and linecap(2).
+
+commit f8cbc466a67238c45d1917efb200156b896adf35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 23 12:21:52 2008 -0600
+
+ Support linecap(1) in 3D.
+
+ Fix PRC mode.
+
+commit ef8a94774f4620dde9cfa7605768cbc4491d2c27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 23 03:46:16 2008 -0600
+
+ Add support for 3D arrows.
+
+ Set uptodate=false in picture.add.
+
+ Implement better workaround for missing movie15.sty.
+
+commit 01229d149a8e23e88a4ef0ca47f49943f6c06afd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 23 00:51:45 2008 -0600
+
+ Update example.
+
+commit f675c8d5343a34eae81c87f68c0c6a35d5fbd145
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 23 00:46:57 2008 -0600
+
+ Implement better workaround to allow nonPRC 3D output in the absence of the
+ movie15.sty package.
+
+ Rename unitcube to unitbox.
+
+ Define surfaces unitplane and unitcube.
+
+commit a11ac7d619bf15c9ade7661519814172df3119c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 22 23:59:35 2008 -0600
+
+ Define pen thin=linewidth(0).
+
+ Use thin pen by default for mesh lines and skeletons.
+
+ Generalize revolution constructor based on a graph.
+
+ Use operator .. in hyperboloid example.
+
+commit 207f2d6bf5be358f2949bbdc5fca55db4f535266
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Aug 22 17:47:12 2008 -0600
+
+ Fix logo3.
+
+commit f7573e67c6c3d1b65551f3b291216481afb8bcfa
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Aug 22 17:44:20 2008 -0600
+
+ Fix logo3.
+
+commit c870f00968b792a0c61a688d2972d8a48d74d9b7
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Aug 22 15:44:28 2008 -0600
+
+ Add 3D logo.
+
+commit 92df46fa4db0237c2511f627ee2cfa69ce1eba53
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Aug 22 14:21:48 2008 -0600
+
+ Improve debugging output.
+
+commit 6ebe46c87e42ef22c1e88aa2d04ccbdf9910e18c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 22 12:35:50 2008 -0600
+
+ Use curved slices in solids; reduce the default value of nslice to 12.
+
+ Standardize solids interface.
+
+ Fix determinant of align and transform3.
+
+ Use larger sphere fuzz in tube.
+
+commit 83f125398f6f857054569db99512ba0d3f9d7fd2
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Aug 22 08:28:54 2008 -0600
+
+ grid3.asy: set default value axis in routine (x/y/z)axis3.
+
+commit 7fca21059f9d2d9a2d89778f6eacea74b1de88f3
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Aug 22 08:18:27 2008 -0600
+
+ grid3.asy: Renames (Left/Right)Ticks (Left/Right)Ticks3 for consistency.
+ Remove an unnecessary parameter.
+
+commit c8146e82c886e7e5691b6842466f436a5b1a8e83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 22 01:40:52 2008 -0600
+
+ Fix yaxis3 placement.
+
+ Fix 3D Arc and Circle.
+
+commit 7db52703cde3155efa2ce2eed0f8a524f2b4ad90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 21 21:09:26 2008 -0600
+
+ Add PRCVersion.
+
+ Work around compiler bug in gcc-3.3.5.
+
+commit d62fb8642129bb4d34844728cd1dbc8f21bc9b77
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Aug 21 18:54:51 2008 -0600
+
+ Add test for straightness.
+
+commit 21ba9cf29583e4baa406cb01e94a2f7ad5603d7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 21 09:54:29 2008 -0600
+
+ Use unit normals in circle and Circle.
+
+commit 661565780cc9b816aa5785e1f7da8408e0c5cc25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 21 09:44:34 2008 -0600
+
+ Suppress page numbers for TeX engine; also suppress hoffset and voffset
+ in inlinetex mode.
+
+commit c86a28332ca26f76ac47abc85a1f2a041952803f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 21 09:43:15 2008 -0600
+
+ Set straight only if no internal patch points are given.
+
+commit 902ec3ab6901d6b365edf4b4d2659aa6a1523194
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 21 03:48:06 2008 -0600
+
+ Increase Fuzz to sqrtFuzz in min(surface) and max(surface) C++ routine.
+
+ Expose granularity parameter to PRC surface drawing routines.
+
+ Put PRC surface pens and parameters in a material structure.
+
+ Add straight flag to surface.
+
+ Speed up thick line drawing by optimizing straight case.
+
+ Optimize align(triple) and implement its inverse, called transform3(triple).
+
+commit bf1a4f5d240e06f134f746d324e47e6cf548c4e7
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Aug 20 22:12:16 2008 -0600
+
+ Add check for -X direction.
+
+commit e3d6c0b0a8e7862826b6fc85185eb266ee71cf9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 20 20:31:24 2008 -0600
+
+ Add hook for thick line PRC support.
+
+commit c41b0dd60bc8ff3baf506028769117f33f7b47f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 20 17:30:04 2008 -0600
+
+ Make linewidth(0) draw the thinnest line supported by the output device.
+
+ Redefine nullpen to linewidth(0)+invisible.
+
+ Remove duplicate code.
+
+commit 883cb57bca8fbc8f1b7b42543c495c5494cf2f67
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 20 15:45:25 2008 -0600
+
+ Remove extra node from Circle.
+
+ Add additional surface constructors.
+
+ Fix transverse skeleton when angle2-angle1 < 360.
+
+ Make contour3 return a surface.
+
+commit 2d191394180b19a0065f7bb3e9dc5f5575bf2bbe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 20 10:06:35 2008 -0600
+
+ Fix Circle and Arc so that they are consistent with circle and arc.
+
+commit f558c14315daf2e7fe4181f1751ea8a0362dc4f1
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Aug 20 09:50:53 2008 -0600
+
+ Add 3d support for thick lines and arrows.
+
+commit 1205eab243d14b10b0ec06e934d836e499e24066
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 20 03:52:42 2008 -0600
+
+ Remove implicit casts from 3D to 2D objects (call project explicitly instead).
+
+ Overhaul graph3 and grid3 to draw directly in 3D, keeping track of the
+ picture bounds with an interface analogous to the graph2 routines (backwards
+ incompatible).
+
+ Update contour3 and solids to use new PRC-compatible surface drawing routines.
+
+ Fix and optimize 3D fitting routines.
+
+ Fix label bounds.
+
+ Add functions XY(), etc., to force labels to be upright.
+
+ Fix invert routine by adding missing shift terms.
+
+ Make uptodate apply only to currentpicture.
+
+ Add warn=true argument to solve routines.
+
+ Simplify flowchartdemo deferred drawing.
+
+ Move binary space partition code out of three.asy and into bsp.asy.
+
+ Add operators == and != for real[][] and path3.
+
+commit 3ee40d06b68b7082d3f0bd190339eacbc0d398d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 18 01:39:15 2008 -0600
+
+ Fix align.is3D flag.
+
+commit e0dc3ef17525bfaf071a43826d8d8d52b80c4bee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 18 01:03:08 2008 -0600
+
+ Fix Label diagnostic.
+
+commit 4afeb46e9c984b712cbefb568c5b1020bbff0c02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 16 12:43:32 2008 -0600
+
+ Use settings::outname instead of "out".
+
+commit 69507f82fb36dc8a4590e203297b344c53266a47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 15 15:08:27 2008 -0600
+
+ Fix 3D label sizing.
+
+commit 0b5fc01e8e8f65f6a39f42301fc0e0e28045e81d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 15 14:57:09 2008 -0600
+
+ Add operators == and != for path3.
+
+commit a76c0951b5de7b43451814fc4f5b9faad55a5dec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 15 01:13:17 2008 -0600
+
+ Use currentprojection by default in min3(picture) and max3(picture).
+
+commit ee9b80648f19ae5a9f6b5b206a17b7876857ddfa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 15 01:02:58 2008 -0600
+
+ Remove width and height parameters from embed(picture).
+
+ In embed(picture), avoid unused 2D bounding box calculation in final call
+ to pic.fit3().
+
+ Add embed options to shipout.
+
+commit ea9694079a050e7d830d741945d5ab77e6cb2359
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 14 12:12:57 2008 -0600
+
+ Add drawer3 routine that works with pictures instead of frames.
+
+ Make randompath(n) return a path of length n.
+
+ Fix and optimize camera transforms.
+
+commit 655af38609bfaf91e61e71874138e5037e5b905d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 14 01:42:05 2008 -0600
+
+ Remove remaining "camera too close" messages (no longer needed).
+
+commit 2deae6857ebd44ab0b9a43c9849b1d41b49e6b71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 14 01:28:15 2008 -0600
+
+ Reinstate add(drawer d) function.
+
+commit 5a6a1a5c9115b8b8b6785290d9084af15d78996a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 14 01:12:24 2008 -0600
+
+ Add path3 copy constructor.
+
+ Automatically adjust camera so that entire picture is in front of camera.
+
+ Add projection argument to shipout.
+
+ Add min3(pic) and max3(pic) functions.
+
+commit 8f2da013574b71990d98eb06778fcfdda372f532
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 13 08:32:00 2008 -0600
+
+ Move projection and picture argument (for double deferred drawing) to drawer3.
+
+ Fix duplicate calls to tensorshade.
+
+ Re-enable surface transparency.
+
+commit 6cdca45ed0dd7312015b6e60eaa0fe8b15975458
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Aug 12 12:47:25 2008 -0600
+
+ Optimize 3d reflection routine.
+
+commit be63e490786a206c62cdb4af30e09bf41da300e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 12 09:50:14 2008 -0600
+
+ Add realmult(triple,triple).
+
+ Remove "camera too close" checks.
+
+ Fix randompath; add randompath3.
+
+ Add draw(frame,surface) routine.
+
+ Allow align parameter of Label to be a triple.
+
+ Make size(picture) return max(pic)-min(pic), as with frames.
+
+commit 222a3cab12ff9114fa52a227ed3faaa0409424d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 10 10:48:32 2008 -0600
+
+ Add general T[] sort(T[] a, bool compare(T i, T j)) function.
+
+commit 573e37cb623310e272858a2f65128b325e71de11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 9 08:40:53 2008 -0600
+
+ Don't call surface mesh if meshpen == invisible.
+
+commit 0f23f79e9d07cbcde959199a6aeff9c88c2d1142
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 9 00:04:52 2008 -0600
+
+ Increase fuzz in min(surface,projection) routine.
+
+commit 767e21e544b3fe7352d398e39fb7f387a1ea2416
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 8 20:01:30 2008 -0600
+
+ Fix picture min/max functions.
+
+commit 3f8c1151ef1273b72d6ea8d27fd54c151fffcd62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 8 19:53:22 2008 -0600
+
+ Fix PRC angle computation.
+
+ Rename reload to pdfreload (now disabled by default); add pdfreloadOptions.
+
+ Fix empty picture check in max/min.
+
+ Move default 3d embedding settings to defaultembed3options variable.
+
+commit b0ec65b473aa24a1ffabbb82902bcefb99ea7292
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 8 02:24:25 2008 -0600
+
+ Fix empty tests in picture min and max routines.
+
+ Fix projection in draw(surface).
+
+commit 93bcfd14f694222d414d8a4d26b8321284067479
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 8 01:57:04 2008 -0600
+
+ Compute PRC lens angle based on projected picture size.
+
+ Support lens angle in viewpoint.
+
+ Simplify embedprc options.
+
+commit 3759de7b679583a31118894d55075a46981581ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 8 01:40:15 2008 -0600
+
+ Fix handling of null deliminted entries in split.
+
+commit 84a6f609c8e0e67fb037cace6fe194132e0cd9d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 7 23:28:33 2008 -0600
+
+ Fix scale and scale3.
+
+commit f42c1b7739e338f8ccb21d5df852ca180b23e7e5
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Aug 7 11:54:41 2008 -0600
+
+ Optimize routine for rotation of axes.
+
+commit 2c9ed33e906d3cf5e0aa57445790e466e387b5b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 14:55:45 2008 -0600
+
+ Support meshpen in PRC mode.
+
+ Avoid duplicate drawing due to inexact bounds.
+
+commit 01c5a0080e83e611a0cb5debf81c0907d6d42ab4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 12:46:50 2008 -0600
+
+ Fix supplementary scaling routines.
+
+commit 4e64395903561ef7486ec179682b75f29ffb0914
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 12:45:43 2008 -0600
+
+ Fix projection transformations.
+
+commit 0b72327d31993adc1efe88955facfc1463f5805f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Aug 6 09:53:23 2008 -0600
+
+ Fix uint32_t cast.
+
+commit daedf0162e1c4ea3829a1b8e616fd718e67b00cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 08:51:30 2008 -0600
+
+ Cache return values of texpath.
+
+commit 0f4ea94250d087680f10a7a4d0b86e2aaf8a5341
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 08:16:37 2008 -0600
+
+ Apply submitted drawtree patches (Bug IDs 2031338,2031368, and 2031511).
+
+commit 714ae4d089cb954f0bc6bd0980a9c48a8f0a8ea0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 00:57:49 2008 -0600
+
+ Remove obsolete call to aspect.
+
+commit 5b47296cd82f9f65497b67217ec2e57ec201286a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 00:47:52 2008 -0600
+
+ Temporarily revert change to allow svn builds.
+
+commit ecb402bacf5601c42ebd518501164228b6f7027b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 6 00:36:59 2008 -0600
+
+ Remove obsolete aspect ratio support from projection routines (use size3
+ instead).
+
+ Move diagonal(... real[] a) to runtime code.
+
+ Add support for alternative PRC materials in surface routines.
+
+ By default draw 3D labels without lighting effects.
+
+ Add extra options string to PRC embed functions.
+
+ Add min3(pen) and max3(pen) functions (only a spherical pen nib is currenty
+ allowed).
+
+ Remove unused cap functions from plain_picture.
+
+ Fully implement drawerBound3 routines.
+
+ Fix transform3 initialization in Label.
+
+commit 9de76b20a8db18d9ea9f60ee74891c64bf3d0feb
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Aug 5 19:09:40 2008 -0600
+
+ Add support for materials in prc.
+
+commit 488767e5f7b07a89e6be170a0b5b8ad64c689c0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 5 11:12:08 2008 -0600
+
+ Make reload load the document if not already active.
+
+ Improve documentation.
+
+commit 901d4f700ef6f5e185cf331b09ad88ee5379f01e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 5 10:48:27 2008 -0600
+
+ Avoid arbitrary default values; set line width to zero since that appears to
+ be the only value implemented by Adobe Reader 8.1.2 and 9.0.
+
+commit 309998ffdd956d628adc06785202738d63fd60b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 3 19:50:06 2008 -0600
+
+ Support ASYbase in texpath.
+
+commit 0ffc48041c612ce5d2e56557ecb69b66f38308c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 3 01:26:56 2008 -0600
+
+ Remove quotes from viewerOptions.
+
+ Optimize piecewisestraight.
+
+commit e007b5a8754e64932088592e9f64d576c792d329
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 2 22:49:09 2008 -0600
+
+ Fix straight flag in drawprc.
+
+commit e07d8cc9d55e09a26e121fbb918eccd2d3348274
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 2 22:37:56 2008 -0600
+
+ Set straight flag on transformation.
+
+commit 1187a1667ce9cf1608e622b8883160d08cce0389
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 2 20:34:36 2008 -0600
+
+ Automatically embed option defaults into descriptions.
+
+commit 6e8b02403e60c611139434cfa5b149bb15757f73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 2 18:01:40 2008 -0600
+
+ Only attempt reload if acroread process is already running; add reloaddelay
+ parameter.
+
+commit 8d276fe6595dc91f0d0a0e62c2df506f9df7d25b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 2 16:18:12 2008 -0600
+
+ Add unitcylinder.
+
+commit 414782b6cd41885dd4cc39c2dacc4ff581b92f21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 2 14:19:23 2008 -0600
+
+ Add code to automatically reload pdf files in viewer if
+ settings.reload=true (requires manual installation of reload.js in
+ ~/.adobe/Acrobat/x.x/JavaScripts/).
+
+ Add psviewerOptions and pdfviewerOptions.
+
+commit 160a605a243191fca83ee05c870f7b8a643f0fd0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 2 14:11:23 2008 -0600
+
+ Simplify solid line pattern.
+
+commit 4ed6ac0aac1d82ecb84678a769694ec38367c0cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 1 16:59:59 2008 -0600
+
+ Fix -psimage -tex pdflatex.
+
+commit 21a5a0672220c4743065507eb33e95cb165b7d77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 1 15:10:30 2008 -0600
+
+ Remove interfering comments; change psimage timeout to 60 seconds.
+
+commit c5141442715a3aadfd754fc5448d531d7867ed35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 1 10:36:55 2008 -0600
+
+ Rename print.js to silentPrint.js; move all other Javascript commands to
+ asy code.
+
+ Check whether silentPrint is defined.
+
+ Fix texengine(true).
+
+commit 046a88b4bd37306e0d0ecebbe429dd213a3ca51c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 1 01:58:03 2008 -0600
+
+ Add print.js; this should be put in ~/.adobe/Acrobat/8.0/JavaScripts/.
+
+ Make -psimage give up on waiting for Adobe Reader to finish after 30 seconds.
+
+commit b78d73947601327af0a11e92bdd382f8396a6b18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 1 01:43:50 2008 -0600
+
+ Add -psimage option to dump rasterized postscript image of PRC scene.
+
+ Force texpath to use latex/tex engine even with -tex pdflatex and -tex pdftex;
+ add texdvicommand to specify an alternative latex/tex to dvi program.
+
+ Use correct output prefix for intermediate PRC files.
+
+commit 7fc7a09c48a5144cc52481165eaf5ebe73f6de30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 31 22:23:29 2008 -0600
+
+ Remove bulge from unitcube.
+
+ Implement nolight with boolean variable.
+
+ Fix sizing of transformed 3D pictures.
+
+commit 8fd6b0873e9fbcc1576b9a6bf1241c5cdcd9f5af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 30 13:14:02 2008 -0600
+
+ Use portable constructor for BooleanVar.
+
+commit 25ef61001ed9899ec67d813f2d9fb3ceb478e3db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 30 12:59:23 2008 -0600
+
+ Move xasy.conf into ~/.asy directory.
+
+commit 22e5cc8c9eaffdd4d7d75e87c9d75fc101597353
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 30 11:02:46 2008 -0600
+
+ Allow separate 2D and 3D picture sizes.
+
+ Use double deferred drawing for 3D projection to allow control of the 3D aspect
+ ratio and also the width and height of the final projected picture.
+
+ Remove obsolete cycle3 variable.
+
+commit 3bb43749d5c5ca8a475b98f51cff2fbe93d89410
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 29 16:56:42 2008 -0600
+
+ Typeset 3D labels onto projection plane by default.
+
+ Fix roll computation.
+
+ Add transform3(triple u, triple v) that maps (X,Y) to (u,v).
+
+ Add solidcone.
+
+commit 323f2d45bd37156a4b4abdf240f001026925947f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 29 14:47:55 2008 -0600
+
+ Use cleaner icons.
+
+commit 41dc906cbf1b9cdaabcae254a1c44c03539849e1
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 29 12:40:49 2008 -0600
+
+ Fix typo.
+
+commit 5973e480d9fa04eaff3c8d0b6427672a04f60ea3
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 29 12:38:40 2008 -0600
+
+ Describe scene display parameters.
+
+commit e6cf737d99947537e211a0ded7ff33ee85feec10
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 29 10:30:42 2008 -0600
+
+ Do not freeze while waiting for external editor to close.
+
+commit 58725ca2426ded56c568739c3c19df9e6c44655f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 28 23:53:30 2008 -0600
+
+ Fix hang in surface bbox routines.
+
+commit e33a8771b9b2d14c1297c68d58f749bea56e8dca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 28 23:04:58 2008 -0600
+
+ Add unit cone.
+
+commit 1d18572e5681a912ccad4d8a26b05c0595b4f4a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 28 07:47:31 2008 -0600
+
+ Add support for path3 Labels.
+
+commit 8ea1129b09d97c7dc2256bc73a91cb1f0822f3ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 27 23:09:39 2008 -0600
+
+ Fix generation of asy-keywords.el.
+
+commit 33386b3f64bb669c90a01e6e617c070c60b97e4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 27 22:57:25 2008 -0600
+
+ Defer projection of 3D (non-prc) pictures until drawing time.
+
+ Express currentprojection in terms of user (picture) coordinates.
+
+ Add missing tensorshade functions.
+
+ Add casts from object to label and object to frame.
+
+commit 02caeaea31659c23bd37b7ad7d43b3d949eba863
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 27 21:30:54 2008 -0600
+
+ Add locale() function to query/set current locale.
+
+ Add locale string to format(string s, real x).
+
+ Add string(int) function.
+
+ Fix locale issues.
+
+commit d5d14abe253106269ddfc14c47364ca593572533
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 27 16:02:26 2008 -0600
+
+ Make string(real, int digits=realDigits) use fixed notation.
+
+commit ee69ce258d507924f18dd0e7563b7ebfd3f6122c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 27 00:12:38 2008 -0600
+
+ Add three-dimensional Label support.
+
+ Support adding a three-dimensional frame to a picture (positioned at the
+ origin).
+
+ Remove three-dimensional add functions in favour of embed.
+
+commit d283edb251ce48f1ae6e725315125b72f0976794
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 26 18:22:39 2008 -0600
+
+ Rename surface.asy to three_surface.asy and light.asy to three_light.asy.
+
+commit 6876aae1ec52058ff36530fc225880132314cdba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 26 18:15:03 2008 -0600
+
+ Move surface max and min functions to C++ code.
+
+ Fix three-dimensional label functions.
+
+ Implement unitsphere as an 8-patch Bezier approximation.
+
+ Add three-dimensional dot functions.
+
+ Include surface.asy and light.asy in three.asy.
+
+ Remove casts from triple to pair and triple[][] to patch.
+
+ Fix surface normals.
+
+commit f76993c733c494f63052fee8650f2a0325a8388d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Jul 26 08:14:27 2008 -0600
+
+ Preserve original path's direction for each new region created.
+
+commit 2df9113fb0760d067135027d79d0da53aefa30db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 25 16:53:29 2008 -0600
+
+ Fix removeDuplicates.
+
+ Simplify uncycle.
+
+commit 7fc100ae6a07e36590bdc40fc58b896a3899c5cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 25 15:38:43 2008 -0600
+
+ Use DBL_MANT_DIG for recursion depth limit.
+
+commit e7394489eec585a15358f2a1942233ec42a3d6af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 23 02:16:40 2008 -0600
+
+ Generalize picture to handle 3D objects.
+
+ Rename surface to patch; implement a surface structure to hold an array of
+ patches.
+
+ Implement simpler, faster surface bounding box routines.
+
+ Add -prc setting (temporarily set to false) to enable prc output.
+
+commit ad0b2823a741e2bdc1ff2ad0cecb92ba16c8f979
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 23 02:09:52 2008 -0600
+
+ Add randompath function.
+
+commit 80f81d13ed3bb8984183e431020ada1c7c2229eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 23 02:02:59 2008 -0600
+
+ Fix height and width units.
+
+commit 20076a17a54128ea455d608a52a83cda9acb823c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 7 00:43:29 2008 -0600
+
+ Use bounding box rather than less efficient convex hull test in inside.
+
+commit cb11a56fdc8982ab5e88dfa24bdd13e3e74b4fb5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 6 22:52:29 2008 -0600
+
+ Remove obsolete file.
+
+commit 8df94eb01841188da1e38f77073168c8dbe42683
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 6 17:23:42 2008 -0600
+
+ Support compilation of gc-7.1 with gcc-4.3.1 on FreeBSD 4.10-RELEASE-p2.
+
+commit 78ad79d4c0038a286eab64e138fd38ba65207ee7
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Jul 6 14:40:28 2008 -0600
+
+ Fix the documentation of quarticroots.
+
+commit 35a635d26382f0ccb9b552fc7bb824cb343c5233
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 22:21:50 2008 -0600
+
+ Minor optimization.
+
+commit 367e8ebd63efd180493a68a44eb56ec53c8c071c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 22:11:36 2008 -0600
+
+ Remove HAVE_TRIANGLE configuration.
+
+commit d5547e4ec09ec39499bcdc8300c226ed9307d524
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 22:05:42 2008 -0600
+
+ Port prc code to cygwin.
+
+commit 404a75f09df81099bdb9e973dd306111a636f0c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 14:11:53 2008 -0600
+
+ Port version changes to msdos.
+
+commit 31e3f4fafe9fae62ed71b74f3994eb8be7643bac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 13:47:51 2008 -0600
+
+ More version fixes.
+
+commit 14369b9cfc2fbc21951d3bcc41e14411cccc6e18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 13:32:18 2008 -0600
+
+ Fix version.texi; cleanup temporary files.
+
+commit e04d51ef715883a69e1eae296e899f2da8c0a1d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 12:54:47 2008 -0600
+
+ Add prc dependency.
+
+commit bfdc8376f8e2b22b6cb58fa43b3cc71af5f1b084
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 12:52:54 2008 -0600
+
+ Create empty svnrevision.cc by default to force update.
+
+commit 2f80208862aa04acc1b869ba6be16466d3e4c0cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 12:42:22 2008 -0600
+
+ Remove support for external triangle.shar.gz package now that Delaunay.cc
+ is fixed.
+
+commit 1578efdf744d9881bc40a676bac6b848885e156d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 12:26:50 2008 -0600
+
+ Include svn revision in version strings.
+
+commit cd52c344b783552066e47d77855f1ba0e225cd8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 11:08:28 2008 -0600
+
+ Fix supertriangle computation.
+
+commit 3a600d47091011a1a396cbbe73865685a03674ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 01:32:21 2008 -0600
+
+ Add bezier triangulation routines (developed by Orest Shardt).
+
+ Add support for filled fonts.
+
+commit 8422b776c2a1bb3b6e99ffd09eed39a57fad68b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 5 00:37:42 2008 -0600
+
+ Fix surface constructor to handle all four intersection cases.
+
+commit c2839ecad3c5bb6dea5450bc6765a99fc19eda04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 4 15:35:03 2008 -0600
+
+ Generalize planar surface constructor to handle a single interior intersection.
+
+commit c5e611c89317048f58c01c6fca08420f5cd9c189
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 4 11:29:01 2008 -0600
+
+ Fix check in windingnumber for points on path.
+
+commit a4a9a9696f4460a31a0fc817873e72e6098cbc2d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 4 09:56:19 2008 -0600
+
+ Fix parameterization interval of PRCline.
+
+commit 3866af07751efe3def9fd837c80439b45e0778a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 4 01:09:09 2008 -0600
+
+ Add constructor for a (possibly) nonconvex cyclic path that returns an array of
+ surfaces.
+
+commit ccb28f918c69c71aa3ea116690974a917add785f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 3 23:55:01 2008 -0600
+
+ Suppress output by size when picture is empty.
+
+commit 2a5ea45ee0b656e87e4d71b8ca5185a4fb2fbaf0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 3 23:25:31 2008 -0600
+
+ Check for coincident subpaths in path.cc to avoid infinite loops.
+
+ Define restricted int undefined to the the largest odd integer (returned by
+ windingnumber for points on the path).
+
+ Update documentation.
+
+commit 982ba5c059237d9cea33e4b10a699c85384498ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 3 15:46:32 2008 -0600
+
+ Make windingnumber(g,z) return the largest odd integer when z lies on path g.
+
+ Make inside return true for points on the boundary.
+
+commit 5b165379ca3eaba5cbcbc1be79de33d162d88440
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 2 15:03:55 2008 -0600
+
+ Revert to original version of cubicroots to handle the case where one of the
+ first two roots is near zero.
+
+commit 9db5f20ac51580e1246da314b548940486db8c32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 2 12:57:21 2008 -0600
+
+ Update example.
+
+commit ef2aed565e623ce114dc3b95b0e27f5012eabbfa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 1 22:29:10 2008 -0600
+
+ Minor simplification.
+
+commit 7f6e70feef498ff8850c3170ca092ce67948ff76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 1 20:27:06 2008 -0600
+
+ Fix AsyPDF flag.
+
+commit a7ae860cfccad51f5ea1b68f41797c37b43ebc4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 1 20:11:33 2008 -0600
+
+ Support clipping with tex and pdftex TeX engines again (broken since 1.34-26).
+
+commit fc997e3d2e29aff462512e06fe045ed3372e1c66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 1 20:08:52 2008 -0600
+
+ Support xelatex.
+
+commit 019c0793143aa77f80ebaa7238b521bf7a614909
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 1 00:19:54 2008 -0600
+
+ Leave cubic root refinement to the user, to avoid potential root
+ interchange problems.
+
+commit 9183d9faeb41cb12332b0e63c8d47a83060f60e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 30 22:27:13 2008 -0600
+
+ Implement robust inside algorithm based on conditional subdivision and
+ robust orient2d predicate.
+
+commit 0ee41c80a2f20c06ac36ceec99df87f8c1b59439
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 30 17:51:39 2008 -0600
+
+ Add option to force PDF output.
+
+commit 24dbc91d612d00bea406763efba85f802ea3ee33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 30 08:51:03 2008 -0600
+
+ Add side and incircle functions.
+
+commit ad7a5ca602f3ff77da61d8ecc6dd9b7af30b16b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 29 17:57:25 2008 -0600
+
+ Minor optimizations.
+
+commit d57cce192cc1c5a390d58c68bf7e3a07901844b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 29 16:33:57 2008 -0600
+
+ Correct typo.
+
+commit 8aeb44ff5525fdf55e4143b9b77205112b036e59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 29 16:30:53 2008 -0600
+
+ Fix segmentation fault in default Delaunay triangulation routine.
+
+ Use Shewcuk's exact predicates in Delaunay triangulation.
+
+commit b8d7d2e8f2ea5e5dfefade3caab02bb53d78b7fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 28 23:16:00 2008 -0600
+
+ Fix incorrect array size documentation of Delaunay.cc that can lead to a
+ segmentation fault.
+
+commit c9952eb8c85cc44da35821610563601c6289f6c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 26 00:01:50 2008 -0600
+
+ Minor optimization.
+
+commit 0ee04f17646c1de38a0ff508303f2c4d1b2a87e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 25 23:19:25 2008 -0600
+
+ Try to refine calculated cubic roots with Newton-Raphson iteration.
+
+commit 2ad1cec486027bc80ae21d1ba0b5b3f13b8f70dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 25 22:40:12 2008 -0600
+
+ Simplify cubicroots.
+
+commit 4a7b065aa93db97935627739c00326760e7d4a58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 25 17:00:22 2008 -0600
+
+ Replace ytimes by real[] mintimes(path) and real[] maxtimes(path).
+
+commit 9642646492c918276ac2f318c44e07e4c359288a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 25 16:24:22 2008 -0600
+
+ Generalize last fix to an arbitrary axis.
+
+commit e2610105e22d30b816c9bb381e411ca323405f93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 25 15:04:03 2008 -0600
+
+ Handle degenerate cases.
+
+commit f06bc755f427058119162f162f1043e6363b67d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 25 00:38:12 2008 -0600
+
+ Increase fuzz.
+
+commit 473e70480321251eac19268682b7125cf06556b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 25 00:27:11 2008 -0600
+
+ Fix numerical resolution problem in windingnumber.
+
+commit dfe3717ab63b45d9417603fa1ed12c41ba57e745
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 24 23:45:50 2008 -0600
+
+ Fix relative vs. absolute fuzz.
+
+commit cc289caf34ad10914fed9c4d8e6fa4fed9e1fc41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 24 23:03:37 2008 -0600
+
+ Adjust fuzz to fix remaining resolutions problems in windingnumber.
+
+commit bb8f1d22492b52bc0d67781556563402bbcc1053
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 24 22:36:22 2008 -0600
+
+ Reinstate deleted function.
+
+commit c13dd963a9146bfb4c185c3aea5ebe3f5314daec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 24 22:31:12 2008 -0600
+
+ Remove dir(path,real,int) since it is only needed internally.
+
+commit fdcf601224198de809d246db57de6c07d144ec76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 24 22:20:09 2008 -0600
+
+ Reinstate old inside function.
+
+commit a207300ee6c5fe5ba269c3b32cca7b97df7d25e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 24 17:53:38 2008 -0600
+
+ Use lineintersections routine to implement inside.
+
+commit bf30f081e382e7c8be0a21aa7740efb40255ef41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 24 10:35:12 2008 -0600
+
+ Fix windingnumber by using robust predir and postdir functions.
+
+ Expose dir(path,real,int).
+
+commit d063ba0e8ec6ee997f97f6d7fd3d16e726437cd4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 23:42:18 2008 -0600
+
+ Add real[] ytimes(path g) function to return times at which path g reaches its
+ minimum and maximum y extents.
+
+commit 68dba699cbba078b15ac7eb7a019da3adb65715f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 22:40:14 2008 -0600
+
+ Consolidate bounding box code.
+
+commit ecf2d58e5f9978e892ce839ef76ba9b16cd4e696
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jun 23 18:04:57 2008 -0600
+
+ Correct handling of uncompressed files. Add enums to PRC.h
+
+commit 42788226294536aeacb5ad384b3dbf0c6eed2eab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 17:48:23 2008 -0600
+
+ Increase minimal fuzz in intersections.
+
+commit cca5841adf415573f09131f10bfca3cd59e5dd54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 15:03:49 2008 -0600
+
+ Increase fuzz to improve detection of roots at numerical infinity.
+
+commit d372e260f74e03df30e5d06f5f5f33330598471c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 11:18:40 2008 -0600
+
+ User -dSAFER also for deconstruction into png format.
+
+commit 407a627a5d18b773739a9535b486b8a177dd7c49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 11:00:40 2008 -0600
+
+ By default run gs with -dSAFER.
+
+commit 450e6baca04165268c9a3d6201fb9b7b67e162ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 00:41:43 2008 -0600
+
+ Fix typo.
+
+commit c6b4740c7cae67a452bc2587106948668d648525
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 23 00:31:13 2008 -0600
+
+ Update link.
+
+commit 176d2bf970fcdb8b84c74c730b68176a8d433ff6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 22 23:26:30 2008 -0600
+
+ Merge C++ intersect and intersection routines.
+
+ Optimize intersection routines for paths containing straight segments.
+
+ Add function real[] intersections(path p, pair a, pair b, real fuzz=0)
+ to return all intersection times of path p with the (infinite) line
+ through points a and b.
+
+commit 3cebe7e04213749fd8aff24514b71a98e2c38ce1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 21 19:24:45 2008 -0600
+
+ Fix -listvariables.
+
+commit 54f25c1c47cf57223211c9a6cde1067ef3275275
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 21 14:46:23 2008 -0600
+
+ Use new intersection routines; handle degenerate cases.
+
+commit ba91a4a0fbca4fe8b013ff96b2796737a1133bdb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 21 14:36:53 2008 -0600
+
+ Use a process-specific currentpen.
+
+commit fb9a1be407eb4530c7a0522cf8e376bec91b858d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 21 12:24:39 2008 -0600
+
+ Update example.
+
+commit 7e3bc9afe99559d02e62060cc32b2eff8e520c90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 22:49:58 2008 -0600
+
+ Fix roll parameter.
+
+commit a3a9791aaa03745c4d330db56aa68b8f618da00a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 19:34:56 2008 -0600
+
+ Rename intersectionsline to lineintersections.
+
+commit 7405937a0cbcb22ab0126eafa9fdd01851e96334
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 16:56:05 2008 -0600
+
+ Fix and standardize new intersection routines.
+
+commit 39b5991682267b647a5be9167f0da08b64f1269b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 16:12:09 2008 -0600
+
+ Improve intersection routines.
+
+commit 8e67614b18abf8d494d9c0059a03462d264e3744
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 12:04:45 2008 -0600
+
+ Fix front/back detection when rotating about a point.
+
+commit 0ce01dce66c71ef19576aa32a300d2564e764b6e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 10:41:31 2008 -0600
+
+ Move unitrand to C++ code to avoid dependency on stats.asy.
+
+commit 756229ed2e7a006a86858fa05bf4d14b9d507a22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 10:23:21 2008 -0600
+
+ Implement improved version of intersections(point, pair p, pair q)
+ that returns all intersection times with the (infinite) line through p and q.
+
+commit d0e1e48d8e3e4af0851d12df372b1a93cdede51c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 01:44:26 2008 -0600
+
+ Add routine to compute the intersection times of a path and a line segment.
+
+commit 2232265c4efb975d48af1abf1d4e49fb4326c863
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 00:38:55 2008 -0600
+
+ Distinguish between updatefunction (used for interactive mode) and
+ exitfunction (used to clean up intermediate files).
+
+ Don't force settings.outformat="pdf" in three.asy.
+
+commit 9abfe35d19f00a082d74c4203f4df401ecdbca32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 20 00:07:38 2008 -0600
+
+ Simplify nodes(int).
+
+commit e08fa80e0385404c4aa369bb64721f86974e217c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 19 23:42:32 2008 -0600
+
+ Change path3 lift(path) to a constructor.
+
+ Add constructors to surface.asy.
+
+ Add example of 3D extruded label contributed by Philippe Ivaldi.
+
+commit ee1b7f936d02a0b940d7b8a3c9264f416a0efb3e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 19 22:38:42 2008 -0600
+
+ Remove granularity for improved rendering.
+
+commit e40f114bb061d80671e602500523e4f6063a08e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 19 15:43:45 2008 -0600
+
+ Replace axis call by explicit draw commands.
+
+commit 9bf478014f7a15d042c7c6c7e1132bd52047cce8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Jun 19 15:04:04 2008 -0600
+
+ Fix PRCbitStream::getSize().
+
+commit 92647e99c1ded29b5b6e18d559bd344776ad4096
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Jun 19 14:33:11 2008 -0600
+
+ Fix decompress().
+
+commit a32f6380b98eb6fedc9e3025b5b6e9a4a75709c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 19 00:24:51 2008 -0600
+
+ Fix prc file count issue.
+
+ Add preliminary support for 3d fonts.
+
+commit dee96c003870d0042deb3a35260fed64575971fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 22:31:55 2008 -0600
+
+ Fix projection units.
+
+commit 33decaa2420313cb96d2138c11eab92cd6b3f0e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 22:12:40 2008 -0600
+
+ Add texpath support for alignment and transforms.
+
+commit c60cc1ee9480c8c4ddd38fcfb05a705796a09450
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 22:10:43 2008 -0600
+
+ Simplify reset.
+
+commit 8988b282978699b49e88a25d75b5eb6b81c096f2
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jun 18 21:00:40 2008 -0600
+
+ Fix teapot example
+
+commit b9f123de9a79311321d49a08e5a97101e97104ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 15:17:02 2008 -0600
+
+ Avoid opening up an X11 window in texpath; use epswrite device instead.
+
+commit 3e4f4446091d06df048b77fc6928a8f4bb029efb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 14:56:22 2008 -0600
+
+ Add erase(frame) function.
+
+commit ce7f60c6873d3284b1b506d69f06ee604328db47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 13:02:13 2008 -0600
+
+ Make texpath work also with sqrt, fractions, and arrows.
+
+ Add pen argument to texpath.
+
+commit bdae929ff7456f6f140dde137b230a5fcd1520f8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jun 18 12:51:32 2008 -0600
+
+ Use cm as units of camera properties.
+
+commit 32f251b38f548db605b824523050b902c880f367
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jun 18 11:05:14 2008 -0600
+
+ In PRC, always write at least 1 bit of user data.
+
+commit cae80ffcdeaec5cbe768a9621e2832c8573d795a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 10:20:19 2008 -0600
+
+ Fix formatting.
+
+commit c29cb9fd2b4053f46c77cfffe2385a798cd9fc91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 10:18:11 2008 -0600
+
+ Add example of custom mark routine.
+
+commit 019788a364d8b80a1c84e284d7f9c37095319d82
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 18 09:45:35 2008 -0600
+
+ Move default currentpen argument to C++ code.
+
+commit 37fe2e5767e953bf39d434c7c09d271ee28e5c05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 17 22:45:59 2008 -0600
+
+ Add boolean stroke parameter to shading (and clipping) routines to shading of
+ (and clipping to) stroked paths.
+
+commit a73b07b29768d8e8922cb9d54d52d75efc311c55
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 17 22:08:40 2008 -0600
+
+ Add routine projection perspective(string s) routine to extract current camera
+ parameters from cameralink (Viewpoint).
+
+commit a0e14768dac1463db30549ef4faaf39ebbe33985
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jun 17 13:02:33 2008 -0600
+
+ Resize and give the teapot a bottom.
+
+commit d0a4e60f6c1e15371d8880b367d377ae178a4fd7
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jun 17 12:09:30 2008 -0600
+
+ Use external editor to edit code.
+
+commit f2bf37a0f66d216009c542b2b308b289342ce69e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jun 16 17:21:07 2008 -0600
+
+ Remove unnecessary casts.
+
+commit 74e73921e42bfc6a2e71d49e5195be8855cdedf8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jun 16 17:19:44 2008 -0600
+
+ Remove unnecessary casts.
+
+commit 3aebb8fdcb5fbd809b96168d45d6df20cb4fa077
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 16 13:29:25 2008 -0600
+
+ Fix and simplify texpath.
+
+commit 7e81e79113a8a0519b96b43ade388f9f8fc7015e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 16 11:11:55 2008 -0600
+
+ Use C locale for formatting embed arguments.
+
+commit 1fe8dbbf9792d601a4c10ef53032dc99a6f1ea59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 16 11:08:31 2008 -0600
+
+ Add path[][] texpath(string s) routine to convert string into the paths
+ that TeX would fill.
+
+commit c111c6a7272ce192e277b82a588912d8ab576ef3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 16 11:06:41 2008 -0600
+
+ Add camera view link.
+
+commit 1972a971927ebe07efcebc12fe7b599c78bf3dab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 16 01:12:34 2008 -0600
+
+ Implement better fix for basealign bounding box bug.
+
+commit 0a1ef51442178feb8601dd5883c5de6632b4e53f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 15 17:08:11 2008 -0600
+
+ Fix bounding box with basealign pen.
+
+commit 4614dd3a78731786032ce032edfa6a70ddc56834
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 15 10:32:44 2008 -0600
+
+ Use static constant.
+
+commit 41c8952597ce8e1bd4a03710548564d7937990be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 15 10:30:17 2008 -0600
+
+ For orthographic/oblique projections, move camera further from origin.
+
+commit 8ba6d29ded55164d280c533d56f8554e21aff6ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 14 10:12:59 2008 -0600
+
+ Minor diagnostic improvements.
+
+commit 917a8159772c3655f9a30b78d0abe35f8d386233
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 14 10:04:27 2008 -0600
+
+ Avoid dereferencing null function.
+
+commit 0d589b66ab74255064c2944dd8a679724acfb719
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 14 09:34:00 2008 -0600
+
+ Fix bug in face routines for orthographic and oblique projections.
+
+commit f3de3580086911764db9398e9b515573bc1b3bb8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jun 13 17:54:42 2008 -0600
+
+ Fix IDs in PRC files.
+
+commit 0d1c41d959478fba4160627e30e1082d413c7f8b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 13 16:12:17 2008 -0600
+
+ Get PRC initial camera settings from projection.
+
+commit 9776ccfc40c6182d02447c1b934614593bf6e0e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 13 08:15:38 2008 -0600
+
+ Clean up temporary files.
+
+commit 8eff0d15bca50fe0c914c4cf7b1af4341ae5ccd0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jun 13 00:16:39 2008 -0600
+
+ Added semicolons.
+
+commit a9bb0091a5be8d6da421e80c0316c6dfaced0a0d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jun 12 22:56:47 2008 -0600
+
+ Test access of shadowed variables by higher-order functions.
+
+commit 768a9ce6987778508cc84e4e9205b01ff2c6b05f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 22:53:27 2008 -0600
+
+ Add support for basic PRC operations (drawpath3 and drawsurface).
+
+commit 7a563a4026f3977cbba6d1b829a7211751afa952
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 22:50:22 2008 -0600
+
+ Wait for pdfviewer to exit before restarting it.
+
+commit 1878b4a8c01e7f846a0218c2bbd10a0596f8e5ec
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Jun 12 21:01:36 2008 -0600
+
+ Import code that implements support for saving 3D content to PRC files.
+
+commit c65204f2e7fe258b244b769f6911065fe1986e0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 18:10:31 2008 -0600
+
+ Since Adobe Acrobat doesn't yet have a file-watching capability,
+ kill a running pdfviewer so that a file can be redrawn in interactive mode.
+
+commit f7b8cd27b9cb8765d71b8fcf1d6057875269b0f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 10:00:47 2008 -0600
+
+ Make asymptote.sty work with the hebrew babel package.
+
+commit 2d7fea22b1f0985fe436087b9086e6c9c86cd5fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 09:16:07 2008 -0600
+
+ Add example of downward-pointing logarithmic axis.
+
+commit 5f7145480ea60fd683c6c8bf3799042572d5a16e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 03:23:19 2008 -0600
+
+ Increment version to 1.44svn.
+
+commit fb06937f6dba11a658a56771153fd8986d62ab1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 01:26:49 2008 -0600
+
+ Use international inch also in C++ code.
+
+commit a2159fe25921e7dec91b57c630d313698954bdb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 00:54:14 2008 -0600
+
+ Fix potential segmentation fault in store_history.
+
+ Move uptodate=true back to the beginning of shipout to avoid a race condition.
+
+commit d719abe5c028f2aff2d2b4735bb470228cc1e171
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 12 00:14:14 2008 -0600
+
+ Add modules to redefine LaTeX named fontsizes to correspond to
+ \documentclass[10pt]{article} and \documentclass[11pt]{article}, respectively.
+
+commit bf00af247e9d89e4425d66594eb4685231472348
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 11 15:45:16 2008 -0600
+
+ Use international inch conversion factor.
+
+commit ea890c4d3874b09bc617088a00ee228a6a9b5c60
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 10 08:14:59 2008 -0600
+
+ Add missing path3[] operator * (transform3 t, path3[] p).
+
+commit dc67938febe8c4317574b568fd02f6ac3c7419ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 9 00:59:31 2008 -0600
+
+ Add optional support for Jonathan Shewchuk's more robust triangulation routines.
+
+commit 9474ea5ae10eb7a13cbce94be37de60c6ca07316
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 8 22:56:41 2008 -0600
+
+ Add interface for drawing contours on arbitrary nonoverlapping meshes.
+
+commit be71e97dd3937cbff0f077fffe1c0f287bf3ace2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 7 22:36:27 2008 -0600
+
+ Remove transform return value from add functions in favour of user-supplied
+ add routine.
+
+commit 957acf66cd561bcd3bb36f53583a8358b2153ec5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 7 10:49:54 2008 -0600
+
+ Move draw(path[], pen[]) to plain_picture.asy.
+
+commit 29e7f51ffab71cb8cd31f3df70c35ec415b3cb27
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat Jun 7 10:02:20 2008 -0600
+
+ asy-mode.el: add asy to regexp matching environments with indentation at col 0 for begin/end.
+
+commit d195ed234f5abd683c8801f819d48b6827012c41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 6 12:18:07 2008 -0600
+
+ Remove "paths in concatenation do not meet" also from three.asy.
+
+commit c440bcb17349caf9383c7e3240ddb90eb7928b19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 6 10:59:22 2008 -0600
+
+ Return the transform that maps source coordinates to destination
+ coordinates in add and attach.
+
+commit 23ec1d32da754c400c706e8ea6d2c7770ee27992
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 6 10:56:10 2008 -0600
+
+ Move uptodate=true to runtime.
+
+ Improve diagnostics about incompatible array lengths.
+
+commit 6f84918ef12c6f710d71c6bdf7af794b3692b780
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 6 09:52:43 2008 -0600
+
+ Make interrupts set uptodate=true to avoid spurious shipouts.
+
+commit 339e753c2f3d351c1ef372c5661a9c7411351641
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 6 09:51:37 2008 -0600
+
+ Fix secondary axis tick selection when automin=false.
+
+commit 1027a630c04d8242f270fbffe681dc8bb0c7d43e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jun 5 15:45:47 2008 -0600
+
+ A preliminary proposal for how to defined Asymptote modules in C++.
+
+commit 0d4a0eeb383510e60b3b9ac9232113e2eee45702
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 5 08:58:18 2008 -0600
+
+ Allow precision setting to be queried.
+
+ Write paths to the specified precision setting for a file.
+
+commit 3b5a173a2f18ffd46d224702d7041cfa9fb41fad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 5 08:35:35 2008 -0600
+
+ Add expm1 function.
+
+commit d7b09d6ccc177c046eb40729cea64852d93d0aa0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 5 08:34:21 2008 -0600
+
+ Add labels to example.
+
+commit 9f514e148d9ad4e771e95fc8474689f7296902e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 4 22:28:22 2008 -0600
+
+ Always draw 2D axes below picture by default.
+
+commit 23687784eb8136c680bc575e5faaa031c43b2e7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 4 21:00:36 2008 -0600
+
+ Simplify font variable definitions.
+
+commit b1ecdea289fe45a884bf9d62174e33169dd04a69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 4 20:34:59 2008 -0600
+
+ Restore to correct initial font.
+
+commit d154fe783f4b8a0e68246d1c981983108fea48eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 4 14:50:26 2008 -0600
+
+ Add missing # sign.
+
+commit 352b95fbcbde83c2100873428333c42833b96400
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 3 21:54:04 2008 -0600
+
+ Removed matchCache entirely.
+
+commit 7049c58edd05e29d05a420e5863c0f813930afc1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 3 20:14:07 2008 -0600
+
+ Handle undefined __GNU_C_PREREQ macros.
+
+commit d05f4d6b8db474012a020cadef63c05048c115b5
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat May 31 05:55:05 2008 -0600
+
+ Disabled matchCaching dur to improperly handled cases.
+
+commit 9fa7f2b46ab2a4d2182b284fa2478392be786099
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat May 31 05:54:24 2008 -0600
+
+ Ideas about unicode.
+
+commit 8e5a96428b9aad50a2a5f26bb7c7aad7fc128751
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 27 00:36:08 2008 -0600
+
+ Work around broken gcc-4.1.2 tr1 headers.
+
+commit f11c1186fa36c01c5bbe8f17ac7d53fa47022cca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 26 23:41:28 2008 -0600
+
+ Port to gcc-4.3.0.
+
+commit 1134015c605aeaa9c716e300bdaaa00781297872
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 26 15:09:53 2008 -0600
+
+ Add beginnings of an ode package.
+
+commit 54612197435b4c944be06179afd96f855d650705
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 22 01:02:23 2008 -0600
+
+ Make partialsum return an array of the same length as its argument
+ (this is a backwards incompatible change).
+
+commit 4151c0858ef89f677f105a5cd62024ecc241aeb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 7 22:52:35 2008 -0600
+
+ Update to gc-7.1.
+
+commit 3d0927284d1feba4d7ebf1a1c6ec4d6b7d21cdbc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 7 22:50:36 2008 -0600
+
+ Return immediately for negative sleep arguments.
+
+commit 28729a6593b608c87ff01bc4abebe997716fdaa1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 7 22:49:52 2008 -0600
+
+ Fix spelling of cardioid.
+
+commit 47ba791ced24f6f4b0a53d261f7565577f33082c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 7 22:49:21 2008 -0600
+
+ Update URL.
+
+commit 33a78d50b57103d1799c2b95ab2b8ff5d24b7dac
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Apr 28 17:39:58 2008 -0600
+
+ Update links to TeX resources.
+
+commit cdca5636da68747c65fdbf4a1ad5b13497ebb9b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:18:30 2008 -0600
+
+ Temporary fix for tick directions.
+
+commit aeb5c5a9c889d60ddd2dc3ac0fef63b534d5bc46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:17:47 2008 -0600
+
+ Add missing index entry for array.
+
+commit 253ddb3249b9f7e85bc7035cca787874e513be0a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:10:46 2008 -0600
+
+ Simplfify examples.
+
+commit 1dbb7d413f5c5059d01ddc874b158753ce8cdcb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:08:57 2008 -0600
+
+ Improve bad string cast diagnostics.
+
+commit 973ea83a562502f902836cc07293aea9e902141a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:08:34 2008 -0600
+
+ Add drawing routines for guide[] g.
+
+commit f5b8a5fde57dbb1916a68b104de7c4f586ff0d6b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:06:54 2008 -0600
+
+ Add path[] operator cast(guide[] g) cast.
+
+commit a23bee0a918c2e49facf005c2c94f1c482d6e10c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:06:20 2008 -0600
+
+ Add draw(frame f, guide[] g, pen p=currentpen) routine.
+
+commit bcef90c405e0bd4eadef1cae4e41b3fe0cceac7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:04:45 2008 -0600
+
+ Simplify definition of endl.
+
+commit 5e1ced1a1a427f102db12b1af9ef66cca091281f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:03:50 2008 -0600
+
+ Move title down slightly.
+
+commit 57f08e7a99c24f095155c4a0bf74e97ffd9cc40c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 17:02:59 2008 -0600
+
+ Add void beep() function; document flush output suffix.
+
+commit 210a2779be4611f9854b6b48f07c0d32bf47b96e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 29 16:59:31 2008 -0600
+
+ Add real[] operator ecast(string[] a).
+
+commit bdf817fc6daa43cab0399f03438983b95d77367b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 26 21:35:28 2008 -0600
+
+ Make tickmin a multiple of Step when automin=false.
+
+ Don't override put=Above default for extended axes.
+
+commit 3df525c36624064a784a2dae7b32e4a3a533a115
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Mar 21 21:45:32 2008 -0600
+
+ Added array(n, value) function for making arrays of duplicates.
+
+commit efdeedfa21d989c7ec6e249105739af76b1407d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 21 09:56:10 2008 -0600
+
+ Force the default -D 600 dvips setting for proper label alignment (should
+ have no other effect since we are not using bitmapped fonts).
+
+commit 3ba23cae223de6eda4bc3be6975e52c64bb5d578
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Mar 11 21:58:22 2008 -0600
+
+ Fix handling of undo/redo while in bezier editing mode.
+
+commit e5c96b0445050e3894d40bc13102a8b91075357a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 11 08:45:01 2008 -0600
+
+ Force setdash when offset changes.
+
+commit d39b6bf8ffeaed671183ed633253c9292b6ebc37
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 2 17:19:55 2008 -0600
+
+ Make C-c C-c automatically kill a previous running Asymptote process without
+ second-guessing user's intentions.
+
+ Remove erroneous "Compilation errors,..." message generated by killed processes.
+
+commit 96134a7138bb45deb16ebeea24130a93c044375d
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Mar 2 05:29:55 2008 -0600
+
+ Remove useless code in penimage.asy
+
+commit 4e3af91ce1ddcc1853c022f3e7cbfaaaab564b7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 2 00:55:37 2008 -0600
+
+ Fix gradient.
+
+commit 1487f75fbb79143a2ae24c0db4a51fe63d971982
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 2 00:53:08 2008 -0600
+
+ Remove unused import.
+
+commit 1301e8134a26abe9727308e39ecc415d2be20171
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 2 00:49:23 2008 -0600
+
+ Improve one-dimensional vector field interface (this change is backwards
+ incompatible).
+
+ Support two-dimensional and three-dimensional vector fields.
+
+commit b4ba032503c86cb8292b34f41c81b0bc8ae7f30e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 1 18:14:38 2008 -0600
+
+ Add example of conditional surface and transparent splitting plane.
+
+commit f3d9bf2e97ac2271cca37f21a2bdda47842d964f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 1 16:38:14 2008 -0600
+
+ Implement conditional drawing of surfaces meshes over box(a,b).
+
+commit 66eebddd231e21da865cf0e9df34ed5169fa5f82
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Feb 28 05:42:32 2008 -0600
+
+ Update asy-mode-version value.
+
+commit 342b84ef3a0807ab5ce3fe18df0faf3483f55231
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Feb 28 05:40:49 2008 -0600
+
+ Fix critical bug in asy-mode.el:
+ a new Asymptote compilation when a process was running erased the contents of some buffers.
+
+commit 027b52858861556cc5e12037c1ff2c9443cc5b85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 27 01:25:25 2008 -0600
+
+ Increment version to 1.43svn.
+
+commit 1447cc01adb0a414ebf6c2182ffc67261e41844b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 26 23:57:08 2008 -0600
+
+ Project labels onto cube faces.
+
+commit 8d56775de2013b8977c6e91d157d9ea7e080d179
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 24 10:32:50 2008 -0600
+
+ Don't set sticky bit when creating ~/.asy directory.
+
+commit 9fbabd22a74377a0368373ff1830eea8430df812
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 24 02:18:00 2008 -0600
+
+ Add optional arrows to slopefield routines.
+
+commit 71660d1deb2a0b127d19057d6e171a2a601de2aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 22 15:47:40 2008 -0600
+
+ Add routines pairs(real[] x, real[] y) and triples(real[] x, real[] y,
+ real[] z) as a replacement for the obsolete routine
+ dot(picture pic=currentpicture, pair[] x, pair[] y, pen p=currentpen,
+ filltype filltype=Fill);
+
+commit fae5c47b53c181310f48923c84a7432a93dda1e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 22 15:11:07 2008 -0600
+
+ Remove ambiguity in scale.
+
+commit 7eaba4a7e73881f4ad8c6fb6b2efa8758b6f4441
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 22 13:12:12 2008 -0600
+
+ Use the exact derivative of the projection map to project a Label onto a
+ given plane.
+
+ Remove routine dot(picture pic=currentpicture, pair[] x, pair[] y,
+ pen p=currentpen, filltype filltype=Fill);
+
+ Add dot(real[] a, real[] b) routine returning the dot product of two vectors.
+
+ Update documentation.
+
+commit 8b4b5f556068b8dc1c358e2380023cdf36fe71ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 20 14:35:14 2008 -0600
+
+ More guide to path changes.
+
+commit 1b0837cc9fd6c26c2c073ea7942f7e9c0ad2290a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 20 14:30:54 2008 -0600
+
+ Minor optimization.
+
+commit 66f028e3ddb30f53da918a34665e97f652132e6f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 20 11:05:24 2008 -0600
+
+ Minor optimization.
+
+commit 2c30348bc4c5c690bb8100aeb6d35181d9023e4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 20 10:53:48 2008 -0600
+
+ Simplify code.
+
+commit 0596ae2e0e671c999ba530f78ee3b0b27a8cd18c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 18 14:19:42 2008 -0600
+
+ Add fit argument also for nonglobal animations.
+
+commit 43c452a4cf07327afc3fd0e9f8c26ea334deedcb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 18 12:07:11 2008 -0600
+
+ Add fit argument to animation routines for adding an optionally filled
+ bounding box to each movie frame.
+
+ Add newpage(frame) function.
+
+commit b93fe4a70c9017ff184f1a53ebc205d436e1a468
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 18 10:54:28 2008 -0600
+
+ Remove unused shipout predeclaration.
+
+commit 7d96e60c78920b01057ed98fec08de69e1244f7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 17 23:29:37 2008 -0600
+
+ Add missing explicit qualifier.
+
+commit 69f2ced5ccf41357f53c02e60b71e81ff9a27bde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 17 23:22:15 2008 -0600
+
+ Move definition of currentpen to C++ code.
+
+ Add int inside(path p, path q, pen fillrule=currentpen) routine.
+
+commit cb2994e001b117a4a4e59592041ddb68ec7d7341
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 16 23:17:40 2008 -0600
+
+ Add routine for projecting a Label onto a given plane.
+
+commit 1a9da2027d2a553c9da08e29c369791400269024
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 15 10:43:04 2008 -0600
+
+ Fix missing ASYbase declaration.
+
+commit 8fd647e96c77710d904dbcd5ea6132c42a05114c
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Feb 13 20:21:00 2008 -0600
+
+ Fix bug in cancellation of text addition.
+
+commit 853850265626e15fd01330a794bc82ec8d58073d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 13 16:24:27 2008 -0600
+
+ Output TeX headers only when needed.
+
+commit 84d386a4ce6844c74fdc632b0ad0b21da419106e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 13 16:21:32 2008 -0600
+
+ Mention that transforms can also be applied to Labels.
+
+commit d6d464b64985bdb24a0efe48c4bc508ed3eff762
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 11 15:19:08 2008 -0600
+
+ Update two arrow example.
+
+commit 9b3ac4667a40ddb9278ff1c1e288327cec8481cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 11 14:49:15 2008 -0600
+
+ Update documentation of arrowhead styles.
+
+ Change guides to paths.
+
+commit a1df8af391ff6d0e4026fa6c3a3add30726f397a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 11 14:15:19 2008 -0600
+
+ Move documentation of colorless(pen) to a better place.
+
+commit f36f2b8361c7223233adf56f4cee046d1f3bb472
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 11 04:14:56 2008 -0600
+
+ Simply and generalize contour value selection code.
+
+commit f391e1cb59dc5038024a0c9f5e1eeae96e488458
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 8 22:58:31 2008 -0600
+
+ Make OmitTick do nothing when there are no major ticks.
+
+commit accc7ed704192adf8d5a529c40f4a85d9cf410fb
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Feb 5 19:25:23 2008 -0600
+
+ Fixed typo in slice documentation.
+
+commit 89dba98f9ec82d098a5879730fadea5d74a80e3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 5 10:01:26 2008 -0600
+
+ Avoid division by zero in uniform.
+
+commit 3321d9455ef90ee97f768938562ff22c15a875bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 3 17:19:39 2008 -0600
+
+ Update documentation regarding ImageMagick convert.
+
+commit 849d9b02838570b95aa701399bd2f2ce636c93e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 3 17:13:17 2008 -0600
+
+ Make movie generate multipage pdf animations when format="pdf" and global=true.
+
+ Insist on pdflatex in animation.pdf().
+
+commit ad06a8362db44fa8157339841e327bc4b4177b55
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 3 17:08:56 2008 -0600
+
+ Catch bad casts.
+
+commit 1009155106bfb79fbf920c5a9a1b1913d6ec0c48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 2 11:23:44 2008 -0600
+
+ Add casts between hsv structure and pens; reduce angle to [0,360).
+
+commit f5ecdd38a3a4cf7f6cde0082b9a68d99645ebab2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 2 03:07:55 2008 -0600
+
+ Increment version to 1.42svn.
+
+commit 270d45cc07ed6be202740548e3460cf16a5a905d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 2 02:12:22 2008 -0600
+
+ Fix type conflict.
+
+commit b0d85d8859acb4dd6f7514f96269b1d33c3d5d23
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 2 01:05:46 2008 -0600
+
+ Add support for HSV colorspace.
+
+commit 621f260edc533f9ced6fc4984cd908a385fcfd28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 31 21:21:25 2008 -0600
+
+ Minor edits.
+
+commit 075c48e7483fbaab787b4bff3be8d8ab1c45b959
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jan 30 19:42:11 2008 -0600
+
+ Documented slices.
+
+commit f003b14f41ee970266a527ddf8255eee6b79c2ae
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jan 30 14:28:01 2008 -0600
+
+ Disallow A[5:2] and, for non-cyclic A, A[-1:] to play it safe.
+
+commit 609d55caaefb95be16383fdca5bc7e4a46f1530d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 30 13:24:17 2008 -0600
+
+ Change write to output nothing for uninitialized values instead of
+ producing an error.
+
+commit 1fd3159d68d7afb253c6b44cc4c8ee50cd9c5f75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 30 12:19:58 2008 -0600
+
+ Add uniform(real a, real b, int n), which returns a uniform partition of
+ [a,b] into n subintervals.
+
+ Fix comment.
+
+commit 75fbbe945ba00a7207c3816e8d7fd73dac11f73a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 29 18:53:40 2008 -0600
+
+ Store history line immediately after input (as well at exit, after stifling).
+
+commit 7fb3c67120d0191ff5b6071fa045491317f24133
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 29 09:23:30 2008 -0600
+
+ Add interface to simpson.
+
+commit 0665d10b2d3fe34f7243f2a3db1c087b30609c2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 28 13:12:37 2008 -0600
+
+ Format.
+
+commit 0901dca35916a1a85d935b0f888eaa70396d32f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 28 13:11:43 2008 -0600
+
+ Move numerical routines to Mathematical functions section.
+
+commit 424dd7052001b15f6f57b0da35ee1268bf22435d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 28 12:38:09 2008 -0600
+
+ Make buildcycle return nullpath if less than two paths are specified.
+
+commit dcf34ff2cc982064b00dc5e673a9a2126f99660d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 28 11:56:44 2008 -0600
+
+ Fix typo in documentation of complement.
+
+commit f7d9ddabc9ef80d009e5f880d8a4de2f33dcc0af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 28 11:35:52 2008 -0600
+
+ Fix formatting.
+
+commit 18586c705f74c214f4d60b44d9f564212c80632d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jan 27 12:05:40 2008 -0600
+
+ Implemented assignment to slices.
+
+commit 392074ca90dc8bc379b86e39840620c5ca31e7fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 17:11:28 2008 -0600
+
+ Shred TeX transcripts after each call to drawLabel::wait.
+
+commit 3c04ace2e3285c356ee91fc03faecc4379532de0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 16:57:21 2008 -0600
+
+ Output complete TeX diagnostics.
+
+commit 3434e16d2ea4b2fc32ede6c4710cfca7b5efea83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 16:30:24 2008 -0600
+
+ Add blank lines between tests.
+
+commit 5f1be847debfa4a549ec961bb00996c00ee5264f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jan 26 16:02:48 2008 -0600
+
+ Added null check for array slices.
+
+commit 5bcb67c87c7960dda4e3bc8ae3e446719b052d11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 15:57:19 2008 -0600
+
+ Add array.
+
+commit cd1f0d3f6fa288b44391233d4b43932ca7967764
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 15:52:05 2008 -0600
+
+ Define complex exp, log, sin, and cos functions.
+
+commit 2d2c077d551cca549d04295eea745a5b0f7f657c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jan 26 15:13:57 2008 -0600
+
+ Added array slices.
+
+commit 45d39c3a8d9332915ece4513d6a03b98872c8f08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 11:19:22 2008 -0600
+
+ Fix file paths.
+
+commit fa4d57f8b5f26cb8fb7cfbd9df00efc2e155bbff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 26 11:14:03 2008 -0600
+
+ Remove dependence of non-PDF animations on animate.sty package by renaming
+ animate.sty to animation.sty (PDF animations still need to import animate.sty).
+
+commit 2917d9cd47a4caa2ec96ab77a90287709310729c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jan 26 10:18:56 2008 -0600
+
+ Report on error for rest args with default arguments.
+
+commit 3b3d6627a6cfba38e11e39830153d1f96978b14d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jan 26 10:07:52 2008 -0600
+
+ Added virtual field A.keys for arrays. concat now take a rest arg.
+
+commit 5f88126092e73363d852ff8573d03cac61761d51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 25 23:47:18 2008 -0600
+
+ Make xasy respect transparency with png xformat.
+
+commit 11cfe8261e6a9cd45e922a2a694b28f70ae3eb52
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 25 20:51:26 2008 -0600
+
+ Add drawpen argument to FillDraw.
+
+ Handle nullpen when drawing arrows.
+
+commit f419e0fc124a1487b98e4c36c79831ada12ce073
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 20 12:58:45 2008 -0600
+
+ Store and make use of the bounding path in the object structure to allow
+ connections to noncardinal boundary points.
+
+ Add constructors to the object structure.
+
+ Remove obsolete function for drawing boxes on pictures in favour of
+ draw(Label,box).
+
+ Add dir(explicit pair z) function so that dir(E) is a synonym for E.
+
+ Update documentation.
+
+commit fb19c361b7e1185d22c63079502b9f1863ca452e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 19 22:28:43 2008 -0600
+
+ Add gamma function example.
+
+commit 864e65e94d727444a0c3123478b099a132b9a42a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 19 19:03:13 2008 -0600
+
+ Fix typo.
+
+commit 91199463ea13f80fa065d66f2194fbda6f28a8e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 19 19:02:16 2008 -0600
+
+ Improve buildcycle algorithm.
+
+ Avoid numerical resolution issues by removing the "paths in concatenation
+ do not meet" error.
+
+commit 04e020e6605b64d606d91b26446b8319325a7a27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 17 17:29:08 2008 -0600
+
+ Add intersection count to node and value routines.
+
+commit a19be6b36b0293565e5be8316fdf516ab0470e43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 17 17:24:27 2008 -0600
+
+ Update example to show how to specify all pen colours.
+
+commit ae1481f9b930d27f05564a2dedf4ffdf6012014a
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat Jan 12 11:53:17 2008 -0600
+
+ Fix typo
+
+commit 98e2c3eb93ca70fd24329774cfb664dd521f9092
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 11 22:59:03 2008 -0600
+
+ Determine whether unsplit slices are should be drawn as front or back slices.
+
+commit b770b4ff836330c71d1dac7038caed808fd588e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 12:59:42 2008 -0600
+
+ Increment version to 1.41svn.
+
+commit fca863691dd2a7cba64c4aaf2cd4e456b70b07d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 12:02:27 2008 -0600
+
+ Fix nurb-related bug in solid shading.
+
+commit 842a3f1261d30bdad98e0bcf8c4a3198beaf2042
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 11:40:31 2008 -0600
+
+ Fix PDF hatch width by disabling dynamics line width adjustment when
+ producing pdf format.
+
+commit 969bea071468a36ef3a707c81c2d14bdeb0009bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 5 10:50:59 2008 -0600
+
+ Omit control panel for second movie.
+
+commit 204640fad71c60e20420c0c7868e3f15960dc1fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 22:08:35 2008 -0600
+
+ Increment version to 1.40svn.
+
+commit 325350659a2678ed008d5a4ebb72b37f5b75e47b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 20:48:57 2008 -0600
+
+ Fix inline embedded PDF animations.
+
+commit 356ab0f2172a5ae8130443f1c2647295cabb220e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 20:28:04 2008 -0600
+
+ Delete intermediate animation file unless keep=true.
+
+commit f48f0cc7f09236e5775871c39030bee58560940c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 18:53:32 2008 -0600
+
+ Use constructor to initialize animation.
+
+commit d02f55428e29bb44d1b06d79c6ad8afb02916165
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 18:23:54 2008 -0600
+
+ Increment version to 1.39svn.
+
+commit 96b57a131d19deebc84f85a1a6dcd2049823450a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 14:09:26 2008 -0600
+
+ Patch to support gcc-4.3.
+
+commit 7475cb84d621c8a61982db333e125823fb0bbb33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 13:53:56 2008 -0600
+
+ Move inlinemove.tex to animations directory.
+
+commit 1a9d7aff510255ddf0f26c5f310912cd71fe8647
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 4 13:52:04 2008 -0600
+
+ Add argument global to animate constructor.
+
+ Fix and illustrate inline animations.
+
+commit 26cf61ebcfbd55c922c2dde34e694f72846e7f25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 3 22:13:31 2008 -0600
+
+ Fix ambiguous call to dot(triple[]).
+
+commit d43650f6d16d9fb3e4d0ddc50744869fa78ce1ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 3 21:15:16 2008 -0600
+
+ Support and illustrate embedding of inline pdf files even in absence of
+ [inline] asymptote.sty option.
+
+ Use multipage mode by default in animate.pdf().
+
+commit c7893eeb3a59a57448864986646b44bfa30437bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 3 18:06:40 2008 -0600
+
+ Add constructor for animate.
+
+ Update inline pdf movie documentation.
+
+commit 766fd6bf08b41aa47f0573ab64dbd25b103ebfbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 3 17:44:30 2008 -0600
+
+ Support multipage and inline pdf movies.
+
+commit 1454b4566b4aea12277185e3bf95d373bd563b1e
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Jan 3 07:59:26 2008 -0600
+
+ Fix TeXHead path.
+
+commit 1bf4a24c69724b7c2036187e9bf10c67cd2b746f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 3 00:17:36 2008 -0600
+
+ Document arrowhead styles.
+
+ Rename arrowheadT to arrowhead.
+
+ Add defaultfilltype to arrowhead.
+
+ Fix direction bug in TeXhead.
+
+commit 1067c1e94097c7b80391998a0428994cfa78f731
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Jan 2 20:12:25 2008 -0600
+
+ Provide Computer Modern arrow head.
+
+commit 7662c29a905b31ff907910fb114f0d200c4715ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 1 16:17:29 2008 -0600
+
+ Fix degenerate arrows.
+
+commit 6ef4751c7a67f389651557bbd4e2b59397676527
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 31 00:57:24 2007 -0600
+
+ Add arrowhookfactor.
+
+commit 3995f096e44ed51ef5fc3a398167bdf6aafcd232
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 31 00:50:21 2007 -0600
+
+ Support alternative arrowhead styles.
+
+ Add SimpleHead and HookHead arrow styles (courtesy of Philippe Ivaldi).
+
+commit 94e73b59ec29229fdfcbab31f6fbf28ac65c4ed3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 31 00:46:56 2007 -0600
+
+ Automatically reduce FillDraw to Draw for noncyclic paths.
+
+commit e48152f9ab707d255a31e094f6cae8d132eba8ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 29 11:37:13 2007 -0600
+
+ Approximate nonuniform rational B-splines (nurbs) by adding additonal
+ control points to Bezier curves (not yet optimal).
+
+ Add operator &(path p, cycleToken tok).
+
+ Update constructors in three.asy.
+
+commit e6cf05117c5c832bf234ac9f4acfe5c0155552ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 28 12:20:30 2007 -0600
+
+ In autoformat, try to add an extra digit of precision.
+
+commit ad790766a21e1f85d924c7cd27ddb6256d1f1c17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 24 10:42:05 2007 -0600
+
+ Handle output from xasy scripts.
+
+commit 85d94404c8867f790204a64445a115fbdd4fb07b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 24 10:06:39 2007 -0600
+
+ Have Makefile create symbolic link xasy.
+
+commit c0d837d3b193e411db8195007e481dd49433fadb
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Dec 22 21:34:02 2007 -0600
+
+ Remove need for access to GUI widgets from threads other than main thread.
+
+commit 319c53aa393f6f187d5994fd4f47eaa300ab69e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 11 20:01:47 2007 -0600
+
+ Add missing figures; remove duplicate line.
+
+commit 5db58c2ab9b5db1059eff00dd6e39b8bb6c3552a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Dec 10 12:29:34 2007 -0600
+
+ Clear the matchCatch after translating a module, for a modest speed-up.
+
+commit 8504b2b12ce9028d8146491f6375e87185b524fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 9 23:37:42 2007 -0600
+
+ Add optional xlabel and ylabel arguments to axes.
+
+ Make default xlabel, ylabel, and zlabel arguments of 3D axes routines empty
+ strings.
+
+ Document axes.
+
+ Untabify graph3.asy and graph.asy.
+
+commit 021b820e636812a8f10cc986a689b4ee196dcb2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 9 21:25:55 2007 -0600
+
+ Remove unused import.
+
+commit 7d109fd4de56e9eb9e5be7e0fe84e07e76e56203
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 9 17:47:07 2007 -0600
+
+ Improve graph and interpolation array length diagnostics.
+
+commit 51aeda2f2b10a981416760373819ea77723276f5
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Dec 9 15:10:02 2007 -0600
+
+ Resolve ambiguous expressions during interactiveWrite (with a warning).
+
+commit 8706cd7cb1cbc7bf5d5214a8004312924a296d04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 9 13:15:32 2007 -0600
+
+ Implement -c (command) option and exit() command.
+
+commit f9d4dd9fd35dba1bc3a8af6fbc38ee92580e61b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 9 11:49:08 2007 -0600
+
+ Make read1, read2, and read3 effective only for the current array read.
+
+commit fc7724984928fcb5438c804c93f4d1f4547e26e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 8 20:22:01 2007 -0600
+
+ Output deconstruction errors to Asymptote Console window.
+
+commit 3743326dfa4517531e6830c780c3ad1218b652f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 8 19:16:19 2007 -0600
+
+ Handle unclosed begingroups in deconstruct.
+
+commit e7ec47ddc06f49296bfd7cdb3ce0266eb05baf43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 8 17:37:22 2007 -0600
+
+ Add patch to fix several problems with Asymptote backend for pstoedit-3.45.
+
+commit 9a8a21225594ea559e60a5ffcdc189dce0f72fe3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 8 15:17:13 2007 -0600
+
+ Ignore unclosed begingroups (to work around pstoedit problems).
+
+commit 3fa9cfc8cfc9398c532a66696177e99f804a66aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 8 15:13:07 2007 -0600
+
+ Fix empty clipping bbox.
+
+commit 01c074e794942e9e7f6d99939cb9be8fedf273a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 8 11:43:45 2007 -0600
+
+ Show how to put a header on every page.
+
+commit a945de6cdff5da619b67a0da1361f84e520ea201
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 2 17:29:34 2007 -0600
+
+ Improve system gc detection.
+
+commit 7982bb03903011ef9d815663b9be57b0a4c7c43d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 2 11:58:15 2007 -0600
+
+ Document \\ -> \\ mapping of double-quoted strings.
+
+commit f3c872398182865ab86f8d539407116e6bf97f85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 1 16:30:13 2007 -0600
+
+ Add default value of (0,0) to center.
+
+commit 751ef26e6441331a20c733c2ede1e93ca9e48129
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 1 16:24:03 2007 -0600
+
+ Add pen arguments to flowchart block routines.
+
+commit 53353a7061cb3a14bbe29748e2f0b0a84bff52cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 28 02:28:22 2007 -0600
+
+ Increment version to 1.38svn.
+
+commit dbfb3b087153beead06ba3bb7aaaa96202279698
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 28 01:37:17 2007 -0600
+
+ Final Windows tweaks.
+
+commit f887aa3b30820f117a5eedb2c03ab6af54a86d39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 28 00:05:09 2007 -0600
+
+ Remove min since intersections returns a sorted array.
+
+commit d22fe9b61925276c50f1d02e795d9eaa387a5063
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 23:41:59 2007 -0600
+
+ Document the -x option of xasy.
+
+commit 9447249d3b473e643fdd4c1940bc8dba0cb1fa70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 23:30:09 2007 -0600
+
+ Remove debugging test modification.
+
+commit 10ed8b40ffe426fa310f8b95dc5116feafe0f2b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 23:28:13 2007 -0600
+
+ Update GUI installation documentation.
+
+commit 3694a2d73a5acd069a1cc2d760e4903600db4ac5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 23:17:19 2007 -0600
+
+ Require Python 2.5 for MSWindows.
+
+commit 8a304ea770d0353e64e55807df90977cb459f285
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 23:10:43 2007 -0600
+
+ Add version of PIL-1.1.6 patch used for MSDOS.
+
+commit bf8152019b302c20f8004f2737f31dad216b66c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 22:51:27 2007 -0600
+
+ Output diagnostics from Asymptote in separate Tk window.
+
+commit d93ac8e965bb7043f8b0ded28dba9e170068d382
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 22:50:28 2007 -0600
+
+ Fix active Color button foreground.
+
+commit e550c42efb019bb8dc01a3a1469ffce47355541f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Nov 27 18:16:40 2007 -0600
+
+ Correct acquisition of lock for colour change.
+
+commit 0a49d1c30af474856658ea7b10e94eb75f66354b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 17:23:59 2007 -0600
+
+ Add 's' scrolling option.
+
+commit aa640e61e64e607504d8059a3e6d7b5bbce8a4de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 02:01:27 2007 -0600
+
+ Configure xasy version.
+
+commit facbc7d3edab62e709daff555032af4e915aaad5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 27 02:00:47 2007 -0600
+
+ Turn off scrolling when not a tty.
+
+commit 561fe4db56c52dd4777ddf72818d02eef7380f6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 26 23:22:08 2007 -0600
+
+ Add function to calculate "optimal" number of histogram bins.
+
+commit e14fabf18e6241a76fd6b4545abc5093a063f8bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 26 18:54:59 2007 -0600
+
+ Force outformat="pdf".
+
+commit 24e7460045ec96dbff4b3fe4c464ecde0d663009
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 26 18:54:03 2007 -0600
+
+ When determining base points of arrows, always choose the closest
+ intersection points (in terms of arclength) to the apex.
+
+commit a3029de1fd8eddec158958869cfdb8281f4a08ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 25 22:47:55 2007 -0600
+
+ Use a separate flag in indexedTransform to indicate GUI deletion, instead of
+ zeroing out the transform. This produces clearer .asy output and
+ allows deletion of objects to be undone, preserving the image transform,
+ even after a deconstruct() (or by manual editing of the output code).
+
+ Show asy diagnostics in console window.
+
+commit ae4301c408fa50d866a5c58a13254f63fa001e93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 25 00:23:19 2007 -0600
+
+ Fix scrolling.
+
+commit d5a1e13305ec2ef5476f22ad68642ba95f779771
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 25 00:03:07 2007 -0600
+
+ Improve 3d tick default directions.
+
+commit 9e5878b08af4d44af61190cb5aa1b510721f3283
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 24 07:42:14 2007 -0600
+
+ Return empty secondary axis picture without warning.
+
+commit 8b6d1977cf10a5fb8f895d32ef1673aaffcb4ebb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 22 09:57:42 2007 -0600
+
+ Use unsigned long constant.
+
+commit 18fe2570cdb6e6d6faa7398e2d06665dfe5804c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 21 23:03:02 2007 -0600
+
+ Move existing releaseLock code, catching exceptions.
+
+commit c48aaeec7d7ef98ce4d9cffd750cb817bf9a59db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 21 18:56:01 2007 -0600
+
+ Add transform scale(real x, real y).
+
+ Add marker dot(pen p=currentpen, filltype filltype=Fill).
+
+ Add comma terminator.
+
+ Fix dot(frame f, pair z, pen p=currentpen, filltype filltype=Fill).
+
+ Update documentation.
+
+commit 80b0016f88662ea88a22e152c51a174ed7c68923
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 21 00:09:32 2007 -0600
+
+ Work around ghostscript limitations.
+
+commit c9114aaa6633625cd23259716b9c36258b338a9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 20 23:42:11 2007 -0600
+
+ Ensure originalImage is always defined.
+
+commit b5ba12a2bb8b78cb5e0f70caea30d1487fada0f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 20 23:41:00 2007 -0600
+
+ Release lock before quitting to allow saving.
+
+commit f0f301ee37674d8df4d508139765b63387feec42
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Nov 20 18:52:46 2007 -0600
+
+ Switch to selection mode after adding script item.
+
+commit a396ba6638109d04ab42594429185eff1705c9a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 20 11:26:25 2007 -0600
+
+ Re-enable local directory output check.
+
+commit 45066fe4d8bd4f398483a7e401fbade2fb88db92
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 20 00:00:56 2007 -0600
+
+ Fix output(s,update=true) and boutput(s,update=true).
+
+ Fix segmentation faults for attempted operations on closed files.
+
+commit b31f66caad49ff668f0c22d523496e269d8e54c8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Nov 19 22:00:18 2007 -0600
+
+ Change zoom selection method to an OptionMenu
+
+commit c01836f9ec61bd0217d9d42649f6c916d9224242
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 19 21:34:47 2007 -0600
+
+ Escape ^.
+
+commit fbafcbe0c9cd0622107a25d10329fd3e354307c3
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Nov 19 21:19:13 2007 -0600
+
+ Account for magnification during undo/redo of translations
+
+commit 192ab586ab9caa2a2d24f99ad98995213e0ef06e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 19 11:59:03 2007 -0600
+
+ Fix typo.
+
+commit 33aed5e78b70ef12e3d6a2d0a5c25fc41ab59c9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 19 01:22:35 2007 -0600
+
+ Move xasy temporary directory deletion code into GUI.
+
+ Avoid creating a second asy process if one already exists.
+
+ Ignore ctrl-c interrupts from console.
+
+ Move image file removal up one function level to avoid busy error under
+ MSWindows.
+
+commit 2d1e6478e973e9e0bf2868cbcf8f25def7c16ed7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 19 00:25:22 2007 -0600
+
+ Add Orest's latest fixes.
+
+commit 41fc3423e0284e049f3da096b7e71e87246114b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 18 20:29:19 2007 -0600
+
+ Add informational message about use of system gc version.
+
+commit 6ea171f7207998d6d24cfb82324cb40bad0aa0ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 18 18:41:19 2007 -0600
+
+ Make configure use a system version of Boehm GC if recommended local version
+ of gc isn't present.
+
+commit 5d98ffd60c7b8a57f7749cc51f7484a25f1d14f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 18 18:28:22 2007 -0600
+
+ Append generic configure instructions to INSTALL.
+
+commit 666d5a2a12a4c5f8097536a1f958d6e068e4bd40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 18 11:02:49 2007 -0600
+
+ Put deconstructed files in a temporary directory (removed on exit).
+
+commit 47aaf8cba0f64678b56f08a408310dc66234b9eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 18 09:54:43 2007 -0600
+
+ Move workaround for broken curses.h file to proper place.
+
+commit 748c5401c34ff4485c8f3f2133b03e79a9ae4808
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 17 23:59:59 2007 -0600
+
+ Fix secondary axis bugs.
+
+commit 0424ec5a5dceb6fc66d7b4ed0e110d32cfc4b51b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 17 18:03:34 2007 -0600
+
+ Fix ctrl-c.
+
+commit d19e7442ef512674980b4aa336ca07dfdf24624f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Nov 17 12:47:31 2007 -0600
+
+ Provide a way to quickly close xasy from the command line.
+
+commit 66f3fc046aa9cdb7b7fd3e25bdbaed726ee30f8e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Nov 17 12:24:42 2007 -0600
+
+ Fix bezier editor. Optimize undeletion of items from a script.
+
+commit e5a11867c05c469519bd1413ae7a95099ecaf2a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 17 00:12:28 2007 -0600
+
+ xasy scripts should put temporary files in current directory, just like asy.
+
+commit 994971d0a1ce209668104f8641bc3d88427c51b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 17 00:11:56 2007 -0600
+
+ Remove temporary image files.
+
+commit fd7bde8d9175b34d41eb26361b2148d5c6c00dc9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 16 23:20:39 2007 -0600
+
+ Limit maximum number of command-line arguments to ghostscript; render in blocks.
+
+commit 24d7c2712f50789d7d76517eeaf056dee159d5ed
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Nov 14 22:10:57 2007 -0600
+
+ Improve handling of zoom slider.
+
+commit af154d06aa4d103cc2219480afcf9123c41e7468
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 14 21:25:31 2007 -0600
+
+ Move declarations.
+
+commit 4dd797153e256e8f9557fbfed0385d841f24d1cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 14 18:52:35 2007 -0600
+
+ Remove unnecessary Tk_PhotoBlank call.
+
+commit 8b4fa52a9b8ba5b7ef079eaf12f866bb740d4440
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 14 00:53:42 2007 -0600
+
+ Add PIL_BACKGROUND and PIL_MAX_ALPHA_AREA environment variables for efficient
+ alpha channel rendering.
+
+commit 49283a682e943ac7ede746d9afe8f51d58f6b4fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 13 21:03:45 2007 -0600
+
+ Enable full alpha channel support only for objects of area < 10000 pixels,
+ due to slow Tk alpha channel rendering.
+
+commit 07f0b56ae3b969af39abf5fee1c43d5abded1e58
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Nov 13 12:48:04 2007 -0600
+
+ Prevent redraw of canvas when zoom handler is invoked but magnification is not changed.
+
+commit 23e83f68d846bc4548cd253a9e994c19196c8539
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 13 02:20:36 2007 -0600
+
+ A much better fix for PIL antialiasing and transparency that renders quickly.
+
+commit ca627126bd89f96989de930a3049cf89fed87fc0
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Nov 12 18:57:08 2007 -0600
+
+ Fix rotation to take into consideration the current magnification
+
+commit c36784996337c369338e441633c4205345fa9b7e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Nov 12 16:22:05 2007 -0600
+
+ Fix error in handling of magnification in scripts
+
+commit fb07c1c3e38daaff5997700abbbee199c160b2f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 12 15:50:58 2007 -0600
+
+ Use full precision constants.
+
+commit c444b66488de9511b74edbc4649173c984237e39
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Nov 12 15:35:20 2007 -0600
+
+ Implement magnification option and zoom feature
+
+commit e7cf5e4432837cb3e16daf991a9f4a121f2f43de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 12 01:28:55 2007 -0600
+
+ Replace locale-dependent call to atof() with locale-independent lexical::cast().
+
+commit edb09b23d5688abb9653ca1cf47fa866fd8d34f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 11 23:37:20 2007 -0600
+
+ Speed up GUI deconstruction.
+
+ Make "png" the default value of xformat.
+
+commit f691c77aad9bd09ef9835c8f6871b600d29c6864
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sun Nov 11 21:54:28 2007 -0600
+
+ Removed debugging information
+
+commit b8ee25d1d087cc339f194f3c685a3c524e770421
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 7 23:01:26 2007 -0600
+
+ Update intersectionspoints.
+
+commit 7ba2d08022f92e24275b4a19425bc44f923269d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 7 23:00:15 2007 -0600
+
+ Update documentation.
+
+commit 9583ff94f4abdbe20a9e57964875baad58b9fe41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 7 22:35:19 2007 -0600
+
+ Fix bug in intersections.
+
+ Add optional fuzz parameter to intersections and intersectionpoints.
+
+commit dc0ab50b96d1e8853fd81bcd150cf712c59d2352
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 7 22:03:14 2007 -0600
+
+ Add string[] split(string s, string delimiter).
+
+commit 4cfbb87b4627726d2c9cb82f0343e266015f7704
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 22:25:35 2007 -0600
+
+ Disable readline history when reading from a pipe.
+
+commit aabfeb99010b1b561e7c73cfa846b60d0b92d25d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 21:23:02 2007 -0600
+
+ Update discussion of MSWindows configuration variables.
+
+commit 1c56cdb459bdb211056748e4e3473b0a650ac4a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 21:13:34 2007 -0600
+
+ More windows installation fixes.
+
+commit 905cad8c932a8788a7611181d31ae042a0679a10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 16:52:41 2007 -0600
+
+ Make interactive mode exit with a zero return code.
+
+commit c88c34591ffa6bc397987914885b8e5e20e7490f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 16:27:28 2007 -0600
+
+ Fix Windows uninstall.
+
+ Remove hard-wired path.
+
+commit 97abc8fe2152ef82a5d807722d702e91891522cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 4 10:48:27 2007 -0600
+
+ Add missing function.
+
+commit e92745417a027f1cdb46d165fb70fd2bad94788d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 3 16:50:29 2007 -0600
+
+ Add real[] abs(pair[]) and real[] abs(triple[]) functions.
+
+commit c4d2af3505ee392b9d0ad6871904dd93921a0102
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Nov 3 12:24:00 2007 -0600
+
+ Revert change to example.
+
+commit 94876755d955c4dd32f37559c678f17e366c75bc
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat Nov 3 12:05:23 2007 -0600
+
+ Prompt user before opening a file if current document was modified.
+
+commit 0e6b2b3e7f6f014a1f78bd176f815b87f4bd5c59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 2 23:09:45 2007 -0600
+
+ Add windows installation fixes.
+
+commit 0d2e36675751c0a8db71e65f9e369cf55c8e3fd4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 2 16:13:23 2007 -0600
+
+ Windows installation tweaks.
+
+commit 74e0d0cd5df704c7fd8ab03f349e562014246108
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 2 10:48:05 2007 -0600
+
+ Handle degenerate reference vectors.
+
+commit 0075ad14c3ab42375654663c4d657a233d39cf94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 28 13:31:35 2007 -0600
+
+ Project all reference contributions in direction of maximum contribution,
+ for numerical robustness.
+
+commit 72017f7c16e38929719fe4dcfaf87660b3925947
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 28 12:16:24 2007 -0600
+
+ Improve reference vector calculation.
+
+commit fb19b1223ae572d421e694d4241c6c65c985943a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 26 11:29:19 2007 -0600
+
+ Respect comments and double quotation marks in whitespace mode (just like
+ cvs mode).
+
+commit e8cc7a2e8360cf3a51a579911760b836ea92fe6a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Oct 25 22:19:32 2007 -0600
+
+ Test for invalid defvals in rest parameters.
+
+commit e4162e78e3184911849a9d8187c430eedaa9670e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Oct 25 22:01:21 2007 -0600
+
+ Removed unused code.
+
+commit 9157206842acd8ede6c6290a098ed64561fcb0f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 22 10:38:21 2007 -0600
+
+ Re-enable automatic logarithmic axis coverage routine.
+
+commit 3a92d0fac132773d86f66f1213925b4aedef6d7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 19 22:55:13 2007 -0600
+
+ Exit more gracefully under MSDOS when execvp fails.
+
+commit b5e41991c0a31687e8b750d0fdfff149e48044c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 19 21:34:04 2007 -0600
+
+ Implement firstcut and lastcut reliably in terms of a general cut(path p, path
+ knife, int n) routine based on intersections.
+
+ Increase the duplicate point detection fuzz.
+
+ Automatically sort the array returned by intersections.
+
+commit f831060dd4cfef9b767dee05c3d5689937a2c116
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 18 15:03:38 2007 -0600
+
+ Add patch to avoid segmentation fault with gc-7.0 on out-of-memory error.
+
+commit f14d0b6e7448e8567e1c066f0eff7ef37835045e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 18 14:15:53 2007 -0600
+
+ Make history() return the entire stored interactive history.
+
+commit 6faa52d45246ff681560085b9d3f0bb42a1e2495
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Oct 17 20:04:02 2007 -0600
+
+ Fix adding of automatic semicolons to the history.
+
+commit 3ce0333e8749d984db50549f1cd2f54ee4a72d9a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Oct 17 19:59:11 2007 -0600
+
+ Fix default args for rest args.
+
+commit 8d273ded65db953c1f0830061e5fdea6f798959a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 16 22:05:12 2007 -0600
+
+ Add a routine history(int n=1) that returns the interactive history.
+
+ Store auto-terminated lines in the interactive history.
+
+commit 3e82c2c50fa292781a2befc3c46afa35987409b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 15 09:42:00 2007 -0600
+
+ Try to use a smaller Step adjustment.
+
+commit a3451647eec45a5d2b4823663f8283cf1dbbaae2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 15 00:12:30 2007 -0600
+
+ Fix Asymptote path for MSWindows.
+
+ Make uninstall remove Xasy start menu shortcut.
+
+commit a186cc7f9dd113c2fabe9edd3c98cb16b3328a2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 14 22:43:33 2007 -0600
+
+ Add Nullsoft installation script for MSWindows.
+
+commit 32db9170f83b5cf74589febea822cbc3310910e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 14 22:35:13 2007 -0600
+
+ Under MSWindows, look for asy files in installation path instead of in
+ uninstall path.
+
+commit 6da69898626799d3bfad1e472665db3766418cb8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 14 22:24:27 2007 -0600
+
+ Try to use at least two major ticks.
+
+commit c94d19a62f184771312678070421a6a0a13a9190
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 14 21:15:41 2007 -0600
+
+ Fix title("").
+
+commit f1e3b46122846bb495c02d26c3d391b8c5c13681
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 11 12:22:12 2007 -0600
+
+ Increment version to 1.37svn.
+
+commit b87392a79cac3176f047387893845cb5c02179c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 11 11:31:34 2007 -0600
+
+ Fix bugs in tex(), postscript(), gsave(), and grestore() commands.
+
+commit 4a1e9077f30dd1017819d1d5e2ecd3488a3f7c7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 11 03:15:48 2007 -0600
+
+ Increment version to 1.36svn.
+
+commit 2cc3a721455f91fdca5ae6042490c1e6aa0d941f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 11 02:21:31 2007 -0600
+
+ Fix numeric formatting of setdash arguments.
+
+commit 48cfbe4d7f99da1836d6fea1911ad3c8bf65d507
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 11 01:21:58 2007 -0600
+
+ Work around hang in intersect for nearly identical paths by adding some fuzz.
+
+commit 788117602481a0a89e5c159704bfef4e16e4a0ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 11 00:44:58 2007 -0600
+
+ Increment version to 1.35svn.
+
+commit 03ef1f2dd0e9b79fc36772d4c2e860972f25e12d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 10 22:44:16 2007 -0600
+
+ Add Cygwin fixes.
+
+commit 31eefd4d3857b0fc9eeb34ee36dd362d6b0e5a6b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 10 15:17:31 2007 -0600
+
+ Update GUI documentation.
+
+commit 6275cee1287a0dfd35311d6276a519bc582a4495
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 10 10:59:03 2007 -0600
+
+ Make xasy a relative symbolic link.
+
+commit 7cd198607408c819e09bfa652ea2909f671dfe83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 10 09:00:51 2007 -0600
+
+ Update xasy file name.
+
+commit f763966f44b977c17f78cc6a8b16a5187bd33d87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 10 08:42:59 2007 -0600
+
+ Fix typo.
+
+commit fc3662f7c79eab71825c995fb96e15bdedb3b7de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 10 08:36:32 2007 -0600
+
+ Install xasy and associated files.
+
+commit ababea1854fe43a1d165a003b0a4251ea187357e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 9 22:12:51 2007 -0600
+
+ Update xasy location.
+
+commit 4f4ded526e6099b8b2408190591d4fd287d003cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 9 22:00:32 2007 -0600
+
+ Remove obsolete reference to settings.deconstruct.
+
+commit 955c47c6d859c7a857147ce76d482fa53653281e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 9 21:43:53 2007 -0600
+
+ Replace opendot with filltype argument of UnFill to dot routines.
+
+commit 4884a568746d707dd424b3dfcf0b9c1e1344df25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 9 15:51:51 2007 -0600
+
+ Remove intermediate eps files in inline pdf mode.
+
+commit 376a4be0b81b3fcea6a7a0d9c8ee07ec41c17eeb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 9 15:05:23 2007 -0600
+
+ Implement an improved, robust version of intersect.
+
+ Implement intersectionpoints in terms of a new more efficient and robust
+ intersections routine.
+
+commit 345de32960a08aef94f76e11bfc0239a172f421f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 9 15:01:41 2007 -0600
+
+ Add trailingzero tick format.
+
+commit 80d8ba197e620411729aec8e6ae6e2988508799d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 7 11:00:47 2007 -0600
+
+ Make 1.34-26 changes work with deconstruct.
+
+commit 5a47d0a9714054d19b8e774f0407e0f2eb220cc4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 5 21:03:57 2007 -0600
+
+ Adjust defaultformat for axes to make tick labels unique.
+
+ Add general trailingzero format string; update examples.
+
+commit 5db97dd5e0806f0550a03f36c6dca5403b92365c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 3 14:22:52 2007 -0600
+
+ Improve autoscaling of graphs for close minimum and maximum values.
+
+commit 0149f463202c63f414bd5f0144d0f1a7daebeb2c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 28 12:31:44 2007 -0600
+
+ Add example of opendot.
+
+commit 30bd682dde07cd1b3eb5b871c530e90ef53e214e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 28 12:19:18 2007 -0600
+
+ Add opendot routines.
+
+commit c899e161bc16fe731e9515aa4ba1929acaf14177
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 24 21:11:00 2007 -0600
+
+ Changed global.back()-> to processData().
+
+commit 4eaa1727e9a7e4e72fbffb36bf3618555da00c06
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Sep 24 11:20:27 2007 -0600
+
+ Defer hard coded commands and options to variables.
+
+commit b306d9c7ae185bf62931d835282e814c7c1204ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 23 10:45:41 2007 -0600
+
+ Fix shipout bug.
+
+commit 9c0ad5c96e8c5cf06233b0e7d2432e214d10c2c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 21 10:17:43 2007 -0600
+
+ Remove obsolete -q option.
+
+commit ea214d26275c2038153b723368c82de1c5ca277a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 20 22:27:59 2007 -0600
+
+ Change default LaTeX font to package-dependent setting.
+
+commit 49a976c00b8eba6912cd07d08bbfa85f9932802e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 19 21:46:56 2007 -0600
+
+ Add modification of ncurses patch from mvid.
+
+commit 9a633a15cd6a196735c2dd70c42326e49158b145
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 18 00:10:58 2007 -0600
+
+ Avoid nesting capacity overflows in arctime.
+
+commit 98fbe3b5a82db6ac64b90b4c9011fe1628ebb1e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 16 20:57:35 2007 -0600
+
+ Add new magnification argument to shipout.
+
+commit c8254ef8e6546640a8bf2dbd8696572168bcc9d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 16 20:48:23 2007 -0600
+
+ Make reportWarning generate a warning message only.
+
+commit 4bf55cacf7cea227d314cc0addacb3b59a8ace9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 16 20:42:53 2007 -0600
+
+ Ignore spurious final blank line when reading strings.
+
+commit 2b6f1ed2e728e3019b7d7fe51a2cc46f70a7a958
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 16 11:44:00 2007 -0600
+
+ Fix string csv reads.
+
+commit 1babff1085b49a6d234498d80024f13376a95f0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 15 22:12:21 2007 -0600
+
+ Another comment fix for reading strings.
+
+commit 8c4b46cbe8576444eb9239b89322531169970281
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 15 02:42:12 2007 -0600
+
+ Fix example.
+
+commit 5f24bb57d0d77aa469d3dc322ec68a0f358df338
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 15 02:40:06 2007 -0600
+
+ Fix typo.
+
+commit 192b449209ca8a72ec1890ef029a448085354450
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 15 02:38:23 2007 -0600
+
+ Fix errors in documentation and FAQ.
+
+commit e51365a16cc03474c179cfe191008087cccd2b83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 14 16:09:19 2007 -0600
+
+ Support comments when reading strings in cvs mode.
+
+ Remove unused file.
+
+commit ab9eb1daf63ee6670390a3c937222870dfa32382
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 12 19:42:40 2007 -0600
+
+ Improve description of interativeWrite.
+
+commit 94a55d20dfde26954484b9da157f838c38ded005
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 8 11:48:06 2007 -0600
+
+ Fixed syntax to allow expressions such as (x);
+
+ Based on a patch by Orest Shardt.
+
+commit 2d320faddc0f743c7bc8bf26f309de70869a686f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Sep 5 16:53:51 2007 -0600
+
+ Added interactiveWrite option.
+
+commit 3b37adefe45a0fe16882cc5e21bc35f3997803e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 4 21:15:41 2007 -0600
+
+ Remove --enable-cplusplus option.
+
+ Remove unused quiet option.
+
+commit 74cd6de443c34c6a37cce5d25f599890f04982e8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Sep 3 12:01:42 2007 -0600
+
+ Implement pen validation
+
+commit 3baf769670c61f611e2f6bdfd56755eaaf58bc5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 2 23:36:10 2007 -0600
+
+ Make deconstruct close bboxout file.
+
+commit 3a91e4b10a34161daff8aa042e79c4d682f8d416
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 2 23:21:29 2007 -0600
+
+ Use indexedTransform constructor.
+
+commit 5fe7064890f65e40a5b19c25e43329d501fb994b
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sun Sep 2 21:01:09 2007 -0600
+
+ Make various bug fixes and improvements.
+
+commit 377a44d7fca914f6116cb0c6655f223876ce547b
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sun Sep 2 18:07:55 2007 -0600
+
+ Fix documentation request.
+
+commit 5911d1ee65db0187c4aa5ddb369175429e8a789d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sun Sep 2 17:59:21 2007 -0600
+
+ Temporarily remove zoom control until feature is implemented.
+
+commit 75064e5ff4b5d22382b6ca82d71f48ba037ca8ab
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sun Sep 2 17:46:34 2007 -0600
+
+ Improved text in dialogs.
+ Made the loading and saving of files specified on the command line consistent.
+
+commit 7e6381b9a659a56db2d9dabe1e2bc516ce0005bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 1 22:34:02 2007 -0600
+
+ Standardize fillrule argument name.
+
+ Add support for magnification.
+
+ Remove unused code.
+
+commit f5a10edefe53c276e7fa1546f9e05c6f32c48d11
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 31 20:16:17 2007 -0600
+
+ Fixed bug regarding permission lists of types.
+
+commit 9e8c5d63e7aba58dc7439fd272b3656d8b08e0e1
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 31 20:15:41 2007 -0600
+
+ Corrected documentation.
+
+commit 343d697bc89fc2df9d5cce3bfe316918e52e0376
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 31 20:15:16 2007 -0600
+
+ Made parameter name more descriptive.
+
+commit 0abbb7453f977e5e689a4363fca2d6bf2fb508d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 31 08:35:08 2007 -0600
+
+ Use unique keys.
+
+commit 08e24d5b904996f5a4d44906129423d024dab66e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 30 20:15:48 2007 -0600
+
+ Check for libcurses only if libncurses is not found.
+
+commit c2e2738b9148bbeb5ed91b041a149d06e33b75a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 29 13:56:57 2007 -0600
+
+ Use constructor for indexedTransform.
+
+commit 8a5bf5734476d80f7092185a5c49c06785fb1343
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 29 11:22:33 2007 -0600
+
+ Fix shipout when inXasyMode is true.
+
+commit 351668ee2daa92336da7ed7715a190a612576c2f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Aug 29 09:15:31 2007 -0600
+
+ Fix logic for recognizing modified files.
+ Correct the logic for querying user about exporting modified files.
+
+commit a264e87e1a9787f4d5b87a8b57bed3878852fd1a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 29 08:54:00 2007 -0600
+
+ Revert to gsave/grestore instead of clipsave/cliprestore due to pen caching
+ assumptions.
+
+commit a626ac307bbfcb755732809dcec0cd38a5cf9c90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 28 09:30:26 2007 -0600
+
+ Enclose tex clip within picture environment to avoid unwanted page breaks.
+
+commit 0aa8af84e3f16d0ee7c2cd0769c9a8f015083a75
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Aug 27 15:48:38 2007 -0600
+
+ Prevent switching editing mode during incomplete drawing operation.
+ Search for file with .asy extension if no .asy extension provided.
+
+commit 3a4df7dabf437b5d076402180c0f7db8ad78a2d8
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Aug 27 15:33:06 2007 -0600
+
+ markers.asy: compute golden mean in a static variable.
+
+commit 0387fb5da5f095d833108ddd14d0685ab18b9451
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Aug 27 15:23:17 2007 -0600
+
+ Remove unneeded whitespace.
+
+commit 489f494bcea9bcfa324c9f2e32c852f1a307e5e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 27 11:56:33 2007 -0600
+
+ Rename patterns to currentpatterns.
+
+ Remove preamble option from shipout for consistency with xasy.
+
+ Make explicit shipouts with options work with xasy.
+
+commit cf6c8f2248e6ae21ea6a8ae826f9d0474d495387
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 27 10:33:40 2007 -0600
+
+ Rename xasy.py to xasy.
+
+commit b21e623118dd4113638aafe1e3f746a1f7436bbc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 27 10:24:23 2007 -0600
+
+ Update example.
+
+commit 5508f52a286ec4d49da60fd84d5c15490c3c26a3
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Aug 26 19:13:14 2007 -0600
+
+ marker.asy: uniformize marker sizes and notation.
+
+commit 516ff363207c9dd8d2cd5c478c27880b388379f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 15:40:25 2007 -0600
+
+ Explain how map is a special case of sequence.
+
+commit b08fb71bde104e3c1274a4b008f6fbda1713a6a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 26 13:28:09 2007 -0600
+
+ Fix documentation of map.
+
+commit 3e7ea0f51ddd4619c4cad9d6b5efb34dd68acac3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 24 11:00:05 2007 -0600
+
+ Simplify logic.
+
+commit e704d1a6d00a5486093d2cca45c47d983246557f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 24 10:59:42 2007 -0600
+
+ Make asy -o /dir/ file.asy output to /dir/file.eps.
+
+commit f25c6597ee533083af25b199ad54f6c1b1493f86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 16 08:23:05 2007 -0600
+
+ Add discussion of 3D generalization of Hobby's algorithm.
+
+commit 19b53099bb5583c7192e61a8d88e4913ea68b640
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 14 04:39:42 2007 -0600
+
+ Avoid evaluating function outside of [a,b] (due to finite numerical precision).
+
+commit c0abe1380e8aa2e9fa17037a88c00f39eb3c1a9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 14 02:15:00 2007 -0600
+
+ Fix accent.
+
+commit dff77b74cee87bf917f14232b130accdc0a3d62c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 11 04:01:15 2007 -0600
+
+ Use \PackageWarning instead of \message.
+
+ Update list of contributors.
+
+commit dc32ed7b66b6f1c588df49457e7e714164e1779f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Aug 9 12:13:42 2007 -0600
+
+ Use askopenfilename() instead of askopenfile()
+ Use asksaveasfilename() instead of asksaveasfile()
+
+commit ff037a273b0a8da0e30a31d6e3f6c0c5ef21b4f0
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Aug 9 11:00:42 2007 -0600
+
+ Disabled tear-offs for improved crossplatform look and feel
+ User is now asked about saving changes when closing a modified file
+
+commit c429589301537c5e49c95cf9c811cfff831bf766
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 9 02:59:28 2007 -0600
+
+ Remove old GUI transform support.
+
+commit 865d848b082faac6d4f00cdc0913d92615441c9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 9 02:34:50 2007 -0600
+
+ Add -level option to specify PostScript level (default 3).
+
+ Use more efficient clipsave/cliprestore commands with -level 3.
+
+ Optimize printer stack use by pruning unneeded clipsave/cliprestore commands.
+
+ Avoid nesting of clipsave/cliprestore commands when using UnFill.
+
+commit 8d07a22aa46ddf814cdaa633c448d2433d56436d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Aug 7 11:26:04 2007 -0600
+
+ Changing the current pen's properties affects selected items
+
+commit 40048c0fe0b6bd391463ab84f3570638c9f4c107
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 7 03:24:10 2007 -0600
+
+ Compute pair^int by repeated multiplication, just like real^int.
+
+commit 06b5949d2cc85d70e3cfd0811cf705d8afcf8eba
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Aug 1 09:39:08 2007 -0600
+
+ Removed signals for xasy
+ Switched from GUIop to xformStack in shipout()
+
+commit 5c7478245556a81d678b66e2ee49a180353112bf
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 31 15:05:37 2007 -0600
+
+ Fixed bugs in undo/redo
+ Allowed nested begin/end actionGroups in UndoRedoStack
+ Added forceAddition option to drawOnCanvas
+ Added exitXasyMode() to end of files
+ Implemented undo/redo for single item in a script
+ Implemented undo/redo for clearing of an item's transforms
+ Implemented undo/redo for drawing and deletion of a drawn item
+ Implemented undo/redo for modification of a drawn item
+
+commit 8f0fdd8dbb4443da7c31ae8e8c06af8b83774da3
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 30 15:09:11 2007 -0600
+
+ Added undo/redo for creation and editing of script items
+ Added undo/redo for raising and lowering of items
+
+commit e663da444b6bc1a3f94c7db8277671921a7c8ccd
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 30 12:12:29 2007 -0600
+
+ Updated headers
+ Modified method for storing undo/redo information for translations
+ Implemented undo/redo for addition and modification of labels
+
+commit 93322a02dd16526537f5eaecef606225f0de45df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 17:22:45 2007 -0600
+
+ Increment version to 1.34svn.
+
+commit 4d5a18c811ee847867902d4553290c4925c3ce5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 10:25:12 2007 -0600
+
+ Fix interactive viewing.
+
+commit 2c5bf17ed0f4a2d805b84a946dcae789f78899af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 03:29:03 2007 -0600
+
+ Remove extraneous preprocessor definitions.
+
+commit a671404751ce001ef2ca619d7ae01d18dac048a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 29 02:36:43 2007 -0600
+
+ Add large file support.
+
+commit 9099bc38057450a5e1183e942d24ada30431d970
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 28 13:41:50 2007 -0600
+
+ Update list of contributors.
+
+commit f39eb8d3113030a3777abab069b17971651db7a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 28 09:53:06 2007 -0600
+
+ Open input files in input-only mode.
+
+commit e6c2ef521c795f58273d873dfad405ed7f78133e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 28 09:19:07 2007 -0600
+
+ Allow multiple invocations of labelpath.
+
+commit ca808b0649e3cff006e73fdae534097766f5848b
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 27 14:57:14 2007 -0600
+
+ Handle case of script that produces no images.
+ Remove keyboard bindings for main window when using script editor.
+
+commit 7c5db3faa9b555a50cd81755816bfe58ff96519d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 27 14:38:23 2007 -0600
+
+ Raising and lowering of script items preserves drawing order of all items in script
+
+commit ff64471302290d06a56d9e579e93d94a5c69be2e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 27 14:23:57 2007 -0600
+
+ Fixed handling of deleted items.
+
+commit 342434d25d682a7a8cad1bf139d2088e35ef3f76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 14:05:08 2007 -0600
+
+ Work around old broken compilers.
+
+commit 44596544b2f62896a2d60a046e4eef1b96877ba5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 13:13:41 2007 -0600
+
+ Fix conditional.
+
+commit 8a48b748d74dc52d5860f403414a0313251b1c9e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 27 11:45:34 2007 -0600
+
+ Improved handling of missing asymptote executable on windows
+
+commit fa8771204c3378f71da1fa2513cad7e15debfcdd
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 27 10:37:56 2007 -0600
+
+ Error fixed
+
+commit 3f084166c5dea652fb4dccb97315d9134a7d2161
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 27 10:23:52 2007 -0600
+
+ Check registry to find asy installation on windows.
+ Add browse button for asy path selection
+
+commit ccfe23837d0759e2e726103fffd05b26f147df68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 10:02:28 2007 -0600
+
+ Restrict projection bounding box recursion to a depth of 16.
+
+ Add teapot example.
+
+commit 2ae916421017adc0b6654c1a6b98e9ae42596b6d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 27 09:46:58 2007 -0600
+
+ Syntax fix
+
+commit 585d78bfbd3b3db5ce1bd630bc9e2e75ff3f4748
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 05:24:13 2007 -0600
+
+ Upgrade licence to GPL-3.0.
+
+commit 1086bf459bc045c664f277d7c8d52432f1c724af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 03:50:46 2007 -0600
+
+ Add complex version of quadraticroots.
+
+ Add quartic solver.
+
+ Improve accuracy of cubicroots in degenerate cases.
+
+commit f22f92962a269614ea7e166caba5fefb082aab8b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 01:26:24 2007 -0600
+
+ Make min and max return (0,0) for an empty picture.
+
+commit 049160b1567c4a50a7dfec4535a793bed456d349
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 01:07:31 2007 -0600
+
+ Add cast; standardize formatting.
+
+commit 1a2c4145835825f5133f9b08e1e1224b9ee57122
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 01:06:24 2007 -0600
+
+ Add pair sqrt(pair) function (principal branch).
+
+commit ed0d195c14e24f155b1bcf8bcfc8cf072ec7b91e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 27 01:05:35 2007 -0600
+
+ Fix picture scaling.
+
+commit 4b00fbe6270ba161ee1481b38e7ff1b63f19dcb8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 26 09:17:38 2007 -0600
+
+ Edited comments.
+
+commit ef2ce85c3258b5ef011574f6afa9044c30489fe7
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 25 14:41:31 2007 -0600
+
+ Removed unneeded message
+
+commit ef44082e820bea38a8f346342a07ad8fdd082d2b
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 25 12:50:30 2007 -0600
+
+ Fixed rotation of multiple objects
+
+commit 8bdee6a20399fef2cb5adf638a096143faf9364f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 25 12:43:59 2007 -0600
+
+ Corrected divide-by-zero handling
+
+commit c56d3c762babdee25f974634f9d3a2a2094a6636
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 25 12:27:37 2007 -0600
+
+ Fixed button width
+
+commit 59352469e407a869f3b3525d41370d505704a8d1
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 25 11:11:13 2007 -0600
+
+ Fixes for Windows support
+
+commit a5de675808ae3b699fe0c1d2d5825942cabd0e8b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 25 03:28:31 2007 -0600
+
+ Remove deconstruct() and gui() in favour of settings.deconstruct.
+
+ Rename deconstructpic to deconstruct; standardize arguments.
+
+commit b268da28048455fa93a62489ce17d496c5ec7161
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 25 03:07:20 2007 -0600
+
+ Revert 1.33-91; update documentation.
+
+commit 73af8f210b428dfab4763067ef5f5964894e9965
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 24 15:24:08 2007 -0600
+
+ catch unnecessary exception
+
+commit 93fde433d8f8716cdd5e3043ea0df51a4eb26309
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 24 14:53:55 2007 -0600
+
+ Implemented undo and redo for shifts and rotations
+
+commit cd3e162381ba234aad44fd60c093ec68314d303e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 24 11:59:29 2007 -0600
+
+ Added skeleton for undo/redo operations
+
+commit b22ac1ebe39f1eb4c171e389ed68efaf765186ac
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 24 11:58:58 2007 -0600
+
+ Added accelerators for menu items
+
+commit fa6cd244ae11b082dadb513698dc97b981d350f8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 24 09:37:47 2007 -0600
+
+ Removed unneeded code; fixed export command
+
+commit 6dc7ffd7b5f6e59fc67ac892663e743a37a16a4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 24 08:40:27 2007 -0600
+
+ Turn off readline editing when reading from a pipe.
+
+commit bb3f9064985651c2244413744ef56cb2fc4615ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 24 03:51:06 2007 -0600
+
+ List multiple cubic roots individually in all cases.
+
+commit 8e30d4bd07cccbab8615291d904bb43b390c1180
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 23 14:08:12 2007 -0600
+
+ Additional parts for implementation of new deconstruction method
+
+commit be4bd6e4e13e79793a7c0f1576855b919d013bcc
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 23 14:07:03 2007 -0600
+
+ Implemented rotation of drawn and scripted items
+
+commit 394a24db69248fdd56bc1db737b8dd45b5bfaf23
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 23 14:06:28 2007 -0600
+
+ Better parsing for script items
+
+commit eed3dc18f4761f37e8a967db84ab0385f81865b5
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 23 14:05:38 2007 -0600
+
+ Implemented new, cross-platform image deconstruction method
+
+commit acfeb6d23f030cc4b9e6ec416bfaf9528a4d1eec
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 23 14:03:34 2007 -0600
+
+ Added deconstructpic() for image deconstruction by GUI
+
+commit 23d4ce1589592d9b19d1638d471b83c835085b4e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 23 10:31:28 2007 -0600
+
+ Various improvements
+
+commit 196e50571ea05191713c52a9318ece8bb51b9c45
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 23 10:23:31 2007 -0600
+
+ Removed commented out code.
+
+commit 4a96f66c911483b536677803ac7a1d24dd2b7a4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 23 04:06:01 2007 -0600
+
+ Change order of tests.
+
+commit bc8702d081b5d08b5533edc18a6e411358ddc603
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 23 04:04:25 2007 -0600
+
+ Detect roots near zero in cubicroots.
+
+commit b28193efbfc40b05c5f07a9c82dc75144ae5ce24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 21 06:19:10 2007 -0600
+
+ Add Radoslav's bbox and bbox3 code for surfaces.
+
+commit 99700051cef605c1a6620e6c397cc0492aed1eec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 16:30:26 2007 -0600
+
+ Avoid potential uninitialized warnings with -finline-limit=400.
+
+commit 9edb7ce84ff4ca2ec7552f617db32ada59fbe30e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 19 15:13:18 2007 -0600
+
+ Removed erroneous GC_DECLARE_PTRFREE specifiers.
+
+commit d0d35f2c8d4d2f22a2086d988022a63175b2e6c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 03:09:39 2007 -0600
+
+ Fix cxx errors.
+
+commit 9aa0935babeafd92da4e63764be00aa365a9a99d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 02:51:23 2007 -0600
+
+ Workaround broken texi2dvi installations.
+
+commit 484ba07ac520d8b1add27cf6c96305ac7cca0e1c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 19 02:17:03 2007 -0600
+
+ Trap quotient(intMin,-1).
+
+commit 40d6c962a759685d21f8cd70f1001bd90c84cb9c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jul 18 22:28:58 2007 -0600
+
+ Made the NOHASH venv interface compatible with the optimized hashtable venv.
+
+commit 37425660c088766be9625f55b69e4c67f8b1cffb
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jul 18 21:37:52 2007 -0600
+
+ Added match caching and hashtable presizing optimizations.
+
+commit 04b9e380275f804d9dfa8bc65e3c7d06ac4adf41
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jul 18 21:35:20 2007 -0600
+
+ Removed old code.
+
+commit 7495bd931d9d30fe73d8dfaffda6b1f64cd3092b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 17:13:02 2007 -0600
+
+ Fix page numbering of slide presentations with -u stepping=true.
+
+commit c2a76d97a4cca4325b00ff7a2ebf62260d688828
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 17:01:58 2007 -0600
+
+ Minor optimization.
+
+commit 4035590d60193fc98b0bfec1db8ebfc9d22dd8e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 16:39:08 2007 -0600
+
+ Remove further duplicate config.h imports.
+
+commit b6d3558daf474eb865fb7240bc87fb1267c0cb41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 16:21:52 2007 -0600
+
+ Eliminate multiple config.h includes.
+
+commit 67462e2c08283dea13ff469a440f97c5db90e0a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 15:52:01 2007 -0600
+
+ More cxx fixes.
+
+commit df5f4bfbfa7b2d55ba1b0028b8668cd1d198aa5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 15:42:41 2007 -0600
+
+ Fix cxx warnings.
+
+commit 6bfe300676c319119e106e3db0b703eb42b2836b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 15:18:25 2007 -0600
+
+ Work around missing definitions of LONG_LONG_MAX, etc.
+
+commit 53f618d8d624d926fa81cfa99052940ec32e860e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 14:41:30 2007 -0600
+
+ Move climits to proper place.
+
+commit c6aa8fba639f14657b79508906eee0f5bc346f20
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jul 18 14:04:29 2007 -0600
+
+ Removed unused OP token.
+
+commit f09110dbb915f38232bfa0ba49f4d1d7167c4fed
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jul 18 13:29:57 2007 -0600
+
+ Changed arrowsize typos in documentation.
+
+commit 02536038d7f6513ac143b7d5a78be273a22190e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 07:37:15 2007 -0600
+
+ Avoid conflict with definitions in types.h.
+
+commit 684c472b6dd0913327d0b3ca39841c83415d8d21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 07:25:15 2007 -0600
+
+ Work around quad_t vs. long long conflict on 64 bit machines.
+
+commit 3221c225a505b699ec36c3c168007bb1b98d5150
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 06:50:47 2007 -0600
+
+ Use LONG_LONG_MAX instead of LLONG_MAX.
+
+ Add instructions for working around problems with old broken compilers.
+
+commit c01737efeb4ef95ca23c2adf54f50198ecfc6350
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 06:21:48 2007 -0600
+
+ Further portability fixes.
+
+commit c9b909e1e3be56888d7dec5a89538c3f360b78fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 06:14:24 2007 -0600
+
+ Portability fixes.
+
+commit b2ca155dcc5e6e279c666f47832e67db2c0b063b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 05:50:11 2007 -0600
+
+ Change integer type to Int, which is set default in common.h to long long
+ (typically a 64 bit integer).
+
+ Add support for reading and writing 64 bit integers in binary and XDR modes.
+
+commit fe42bb6368110b595cf3de0f3ff3dc8005d21061
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 05:09:44 2007 -0600
+
+ Don't call locateFile with an empty file name.
+
+commit cc9594c8d01aded6aed8bb2fa408ce51ed1d9595
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 18 04:47:45 2007 -0600
+
+ Fix code for Bezier example.
+
+commit 4ab42cfa3da32e91ea28c6565445eabc9528618c
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Tue Jul 17 15:18:50 2007 -0600
+
+ grid3.asy: bug fix with perspective projection.
+
+commit f52e82d497ee1fde912586a887d48f9a810e03b2
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 16 09:35:44 2007 -0600
+
+ Fixed itemEdit index computation
+
+commit cd9388368834c6fccb78fb518df21932b4385410
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 13 17:50:11 2007 -0600
+
+ Change search path order: directories specified by the dir configuration
+ variable are now examined before the directory .asy in the user's home
+ directory.
+
+ Ignore user configuration files during installation.
+
+commit 9f5593d688f356e2d7b53b1b4558b340ef39ff3d
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Jul 13 09:03:59 2007 -0600
+
+ Bug fix in lasy-tags routine.
+
+commit ab212166f4effcd1a052b9e3f1efd1742a229b40
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Jul 11 12:30:03 2007 -0600
+
+ Defer the copy of LaTeX-mode-map to lasy-mode-map after all personal configurations was loaded.
+
+commit d81fee990b21f1f1ebe96bfb532ea00f66afe67e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 11 12:07:48 2007 -0600
+
+ Fixed verification of asy pipe creationy
+
+commit 20fa659d51a9290e117c7887a0d7a99125f4a59f
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Jul 11 08:25:31 2007 -0600
+
+ Provide real syntax highlighting support with two-mode-mode for lasy-mode
+
+commit e12aeddf054965eaa9e2756cdbcc5c1a773dd2d8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 9 15:42:28 2007 -0600
+
+ Implemented pen parsing for label commands
+
+commit 315431b2180215d1910c6a88d53f1a62bcc2efcb
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 9 11:55:18 2007 -0600
+
+ Implemented raising and lowering of items
+
+commit d119a013aeb71c19731a508c5e236d946023956e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 9 09:54:01 2007 -0600
+
+ Remove unneeded module
+
+commit a215f07bc66eb0456b7d25b9cb9297ea1cfacb61
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jul 9 09:31:46 2007 -0600
+
+ Fix interrupted system call error
+
+commit be592ced5c326c5c99f7189c7ffc0d53a23b5b3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 9 01:29:17 2007 -0600
+
+ Fix texstream destructor so that texput files are removed.
+
+commit 49d64b85ad9aded9a7f28ca48a2c57759884ac8b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 9 00:51:17 2007 -0600
+
+ Fix memory allocation incompatibility in workaround for old, broken
+ readline libraries.
+
+commit e58ad2c2fd23da91fac3b74f5164808a198e11ab
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sun Jul 8 16:31:16 2007 -0600
+
+ Fixed horizontal and vertical motion.
+
+commit 08b2d63738cafda319c8a84811c3adf28cba9e5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 16:02:53 2007 -0600
+
+ Add rainbow example.
+
+commit b97aad94f3a1ed3e8999c1446d0d2b857eef6ae9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 13:30:11 2007 -0600
+
+ Standardize argument names.
+
+commit 6388bfe15c7fe4f40a7a4db3c5aa3ab26a6bad0a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 13:28:58 2007 -0600
+
+ Make framepoint (and truepoint) work even when an exact picture size
+ estimate is unavailable.
+
+ Add boolean argument to deferred drawing routines to allow optimization in cases
+ where an exact picture size estimate is available.
+
+commit 1b843fa5045e0b9f58587e4a909444d8635e8875
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 8 10:22:17 2007 -0600
+
+ Allow writing to file specified with -o /dir/file.eps again.
+
+commit 98718bd22185b3e9775d9ddca9e63e41dbc6039d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 7 11:09:58 2007 -0600
+
+ Don't reset options after reading configuration file.
+
+commit a363cb5945ab03c6ec1abbb5612adf3d32e84939
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 6 21:38:51 2007 -0600
+
+ Improved selection mechanism
+
+commit b22eabeb71ea04c83cf2fae16015fc1e64d4dbd8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 6 20:40:09 2007 -0600
+
+ Shipouts inside a script no longer interfere with the rest of the document
+
+commit 24b4733a6668551fce6c5fc5ea1876bee99b4a2b
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 6 18:23:04 2007 -0600
+
+ Rename menu entries.
+
+commit 2ba6de8350fe44a3440d743c7cf9d752701fd42a
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jul 6 11:10:24 2007 -0600
+
+ All labels now deconstructed. Dialogs improved. Fixed duplicate image reception.
+
+commit 4e356218f9024fa295da285f3284cf6618f840c3
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Jul 5 15:59:40 2007 -0600
+
+ Various improvements
+
+commit 4c16dfe7042d9213c66d5fd76bb5a39567c38b68
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Jul 5 15:58:43 2007 -0600
+
+ Implemented validation for asy path
+
+commit d252319b12998c08f414dc87290ff7b86243db93
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Jul 5 08:36:39 2007 -0600
+
+ Minor edit.
+
+commit 31f2ac1f97ad807bb7b7bcdea8104bc51feaf757
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Jul 5 07:51:32 2007 -0600
+
+ asydef environment content routine uses region instead regexp matcher.
+ Cleaning code.
+
+commit cc49a3d40add05bfeca684a75594218fb319f205
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 4 21:47:39 2007 -0600
+
+ Add configuration file loading diagostic.
+
+commit 4c9f54802278b6c6e346f69ad384973ed527c979
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 4 18:59:22 2007 -0600
+
+ Improved handling of default pen
+
+commit ddc78730447e8f34399fc33b0d69282656bd396f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 4 15:49:27 2007 -0600
+
+ Fixed docstring
+
+commit b8509259097fd3d187a74b0ad41afa5ccd291d1f
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jul 4 15:48:42 2007 -0600
+
+ Implemented storage and retrieval of user preferences
+
+commit b625d6c5eb5553c9d422c0cc65a280e447249afd
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Jul 4 15:36:24 2007 -0600
+
+ Write temporary file with region instead of regexp matcher to
+ avoid Stack overflow when compiling a long file within lasy-mode.
+
+commit 88ee7632e70b6417a6da160f12266bc6344fa62b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 4 06:44:17 2007 -0600
+
+ Remove completed item.
+
+commit db4efd57c4a00f3d4a75cd34ccec83fe44e50115
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 3 16:02:32 2007 -0600
+
+ Selecting an item clears the highlight box
+
+commit b69d4d409b31f9a84f769c976799764d88bae816
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 3 16:00:01 2007 -0600
+
+ Improved handling of already-transformed shapes
+
+commit e0da8a2bfdbcaa619973c77df9e3cde2b40f592e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 3 15:25:22 2007 -0600
+
+ Fixed incorrect entry in xasyColorPicker
+
+commit 30e27ea65ca173679f1e05684bde707134e53f2a
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 3 15:21:36 2007 -0600
+
+ Improved bezier editing and integration with xasyMainWin
+
+commit da060b79e4da279c7daa9d9e8847c344677ccc4e
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 3 14:39:42 2007 -0600
+
+ Added ability to graphically edit the nodes and control points of a bezier curve
+
+commit d6b2e473af81f366e95aa6009f782468c61e18be
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jul 3 14:38:15 2007 -0600
+
+ Faster computation of an upper bound for the bezier width
+
+commit 2cc213ba2b5e92343acf2a221c029ecae8c53032
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 3 10:25:49 2007 -0600
+
+ Fix --enable-gc-full-debug.
+
+commit 795688843fc5d97c3437703614729730823b072f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 3 10:13:53 2007 -0600
+
+ Update to gc-7.0.
+
+commit 4efb99a8788ce81891fbba42c073fd4a4099ab82
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 3 10:06:04 2007 -0600
+
+ Add reference to Java-style array iteration.
+
+commit d47bfa5fa7c4d1fa08fc196c2be964a5598c6359
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 3 09:56:07 2007 -0600
+
+ Minor edits.
+
+commit 85ba69f4073c0cefdee314140060c00737c2c1e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 3 02:24:02 2007 -0600
+
+ Minor simplification.
+
+commit 65efdbd70eea2c161314e1aa02c3defd83b52b44
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 2 18:32:57 2007 -0600
+
+ Added brief comment on extended for loops.
+
+commit b0c6f948c5fd6e86731ff30ed93d44bbc1544964
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 2 17:27:53 2007 -0600
+
+ Minor solve optimizations.
+
+commit 969a375d079222a94c255fb671d06b73da5cd4f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 2 12:14:51 2007 -0600
+
+ Fix memory leak in matrix multiply.
+
+commit b985420945a305dd23b762001212a2d8b6510dec
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 2 07:11:48 2007 -0600
+
+ Simplify extended for loop syntax.
+
+commit 47b56663f6d6c385be48df9315af508ba2ef7061
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 1 23:57:51 2007 -0600
+
+ Update to gv-3.6.3.
+
+commit 74c83940069561695b0d37f57e963fc689af5297
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 30 01:11:04 2007 -0600
+
+ More garbage collection improvements.
+
+commit 77c7be3d5cf9946f4980895261264a8581c55201
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jun 29 15:37:09 2007 -0600
+
+ Fixed syntax
+
+commit 32447a8674d2ee71f2bbb8425abbf71f2a31a59a
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jun 29 15:30:29 2007 -0600
+
+ Checkin the code for the new GUI that is under development.
+
+commit 949ac77506fd75762ff8140f13a84be0e4cbec2c
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jun 29 15:29:21 2007 -0600
+
+ Improved the xformStack implementation
+
+commit 5a0555f8b830f8cb1ca6286f00e333fc958beccb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 29 12:45:00 2007 -0600
+
+ Fix segmentation fault in complement.
+
+commit 6e680f0fbdb18f0982f69a37d8bd8c4329268801
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 29 02:00:20 2007 -0600
+
+ Increment version to 1.33svn.
+
+commit a6c037374d3727f1edc772235c47edafe892d3ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 29 00:42:03 2007 -0600
+
+ More garbage collection tweaks.
+
+commit 637178c4f88c3bb2c7768043978af52bb5e5bad3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 29 00:23:03 2007 -0600
+
+ Fix dependency.
+
+commit 6e795c1214befc7d2dfe4135ad9455a81e77c392
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 29 00:04:58 2007 -0600
+
+ Fix make install-all.
+
+commit df0fbfe97c5f78c301958e0c1bf6baf3731bafc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 28 23:15:34 2007 -0600
+
+ Declare drawverbatim to be atomic.
+
+commit 793d631c85af140f16fe907ae87c141d8cf0e351
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 28 17:20:22 2007 -0600
+
+ Fix bug in subpath.
+
+commit 0a3a730ae4c6bc87066fa453442c4a1c22eec1e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 28 12:13:02 2007 -0600
+
+ Allow cd() and cd("") even if globalwrite is false.
+
+ Don't write cd path twice in interactive mode.
+
+ Update diagnostics and documentation.
+
+commit 7184ae69bfa3e5848ef1c038105647ce538445cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 12:09:17 2007 -0600
+
+ Fix GC debugging.
+
+commit 2c73d879f45bab5cdb1b9fdea0a86b04c5820461
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 11:22:17 2007 -0600
+
+ More garbage collection tweaks/leak fixes.
+
+commit c5ef7778a8995e21ea5465b4c21bae3d9fffd44e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 02:19:14 2007 -0600
+
+ Increment version to 1.32svn.
+
+commit 45724947378bcc555730acd7feea73739ef10174
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 00:47:19 2007 -0600
+
+ Fix segmentation fault in options processing.
+
+commit 5ab07e3d6e08376814a8d8379bca4f4629185c47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 00:31:52 2007 -0600
+
+ Reinstate gc check.
+
+commit a9e498e514d7e5e215066a46856e27e8ea7340fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 27 00:28:06 2007 -0600
+
+ Avoid makefile loops.
+
+commit 919890ae6a354669dcb69cc10d38db4965af6ec3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 26 23:57:15 2007 -0600
+
+ Fix g++ warning.
+
+commit efd1d7983cfe16c00edac28321c2187406382f21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 26 15:35:03 2007 -0600
+
+ Fix cxx warnings.
+
+commit 7f2ba53927bfce875c1ed0978eb53ef11de3037f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 26 15:20:11 2007 -0600
+
+ Fix nullpath3 min/max bugs.
+
+commit f4bac25045a05b4e8550aa65c8e772128fc1ddfa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 26 15:17:14 2007 -0600
+
+ Fix nullpath max/min bugs.
+
+commit b65d874d3d71b488af98e919cd5e5b5e3e79b6c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 26 14:49:05 2007 -0600
+
+ Minor path optimizations.
+
+commit 9c7a14e42f9187cdd8dc6a221503bf4fdf8e0002
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 26 14:18:05 2007 -0600
+
+ Further garbage collection improvements: move pointers out of pen class.
+
+ Add bool ==(path,path) operator.
+
+ Move defaultpen into global; changes to defaultpen in config.asy will no
+ longer be remembered (use the autoimport mechanism instead).
+
+ Make the identity transform a constant.
+
+commit 587d7b6d67c5df5f9a5e2571d36fd55e97bde981
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 17:20:00 2007 -0600
+
+ Avoid using a pointer in path class so that it can be allocated atomically
+ by the garbage collector; this dramatically reduces memory usage.
+
+commit 70618a0a6877c1408315d47e22d0ee78295c047a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 16:57:22 2007 -0600
+
+ Fixed typo.
+
+commit 604854663ab4e8277281b836a8935712d7edc95d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 16:41:37 2007 -0600
+
+ Fix runaway asy process that occurs when tex pipe cannnot start tex engine.
+
+commit 42aeb1f1f09ed1caf2e10e581c84e7bd3d399c94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 13:41:06 2007 -0600
+
+ Fix time without HAVE_STRFTIME.
+
+commit f802e0ec54590b9857d87a4d50fb9b34cfe1c446
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 13:39:30 2007 -0600
+
+ Fix default time and opacity arguments.
+
+commit b10fad39a2e46ff83dc8a3373d71dd907f208a9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 11:21:36 2007 -0600
+
+ Fix minor typos.
+
+commit f9330564f1f442e87fe94ee4910847a4a40aceab
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jun 25 09:49:15 2007 -0600
+
+ Added Java-style abbreviation for iterating over arrays.
+
+ Arrays of functions still not fully supported.
+
+commit 6f0502df0e18f330fb9945ba3df1aa0261b4b2e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 01:46:20 2007 -0600
+
+ Further garbage collection tweaks.
+
+commit 6fa70cec93fbbf3a86cef64120cbad8646e8f491
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 01:37:20 2007 -0600
+
+ Remove virtual destructor introduced in 1.31-44 due to performance penalty.
+
+commit 141515a3a661b9abc373344dc90e6f49745440a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 01:28:48 2007 -0600
+
+ Simplify arrayDeleteHelper, removing unused variable.
+
+commit a4a8a7d09534ce8a1cf0fc829047efb74dd5776c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 01:16:49 2007 -0600
+
+ Fix --disable-gc.
+
+commit 0794504fcf6bfbf5fe96465b9f199b1ad3c82960
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 01:05:39 2007 -0600
+
+ Fix warning messages.
+
+commit 9ccfc2613c2a1ede2102c83456d13a0214c3e2fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 25 00:18:53 2007 -0600
+
+ Add header for isatty.
+
+commit 7d1c381346c387f9bf9adffecb2411cf9746a653
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 22:19:44 2007 -0600
+
+ Revert last commit.
+
+commit 22cee29708a566d13fb2baac91f3e3926aa14483
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 22:16:40 2007 -0600
+
+ Improve tex diagnostics.
+
+commit 816b1fbfe98cbd4210802f063209681a462e10b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 21:24:46 2007 -0600
+
+ Leave deletion of string last to the garbage collector.
+
+ Omit spurious call to background();
+
+commit 4f56d5aa58c769e422f48bdcdb651d5a36c99281
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 13:43:20 2007 -0600
+
+ Avoid warning messages with -d.
+
+commit fcf281b7e249166b8401d8a90ab87be4eea5826a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 13:36:33 2007 -0600
+
+ Fix GC preprocessor directives.
+
+commit 843c7bba85a7c2a6ad77607547a7e49a3295faaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 01:55:10 2007 -0600
+
+ Further garbage collection tweaks; reinstate no_GCwarn.
+
+commit e4de07e434fd3b02c37b464e9851d00bdeda5098
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 01:03:20 2007 -0600
+
+ Fix dependencies.
+
+commit 29cddf4623d842eb65639d81b06d778cf78444c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 00:43:45 2007 -0600
+
+ Don't link with libgccpp.a to increase speed, now that garbage collection
+ has been carefully addressed.
+
+commit d207452495d83bd9bb36df2c43d28a2b745b6c51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 00:26:18 2007 -0600
+
+ Support ./configure --disable-gc again.
+
+commit 24332ff82a2e628a3bfee9d440e5ec3b926393da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 24 00:08:47 2007 -0600
+
+ Re-enable GC_gcollect under MacOS.
+
+ Update to gc-7.0alpha9 since this yields faster execution times.
+
+ Change configure --enable-gc=VERSION so that VERSION now must include the
+ "gc" prefix.
+
+ Remove genv from gc.
+
+commit 185554bd03f47f93586410d0a7904f9b12a6358e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 23 23:03:28 2007 -0600
+
+ Move ShipoutNumber into globalData.
+
+commit 473ba88ae7fea8b0736e29b506db442937a0cc5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 23 16:45:58 2007 -0600
+
+ Use separate global variables for each process.
+
+commit 513822dceef7052ca9efe81e587821896925914e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 23 12:42:05 2007 -0600
+
+ Deconstruct files on termination.
+
+ Improve support for garbage collection debugging.
+
+commit d8b0ff7f98543fbb573a44a1442931e2964fe782
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 23 00:58:28 2007 -0600
+
+ Close any open files automatically at the end of each asy process (without
+ relying on a finalizer).
+
+commit e0c2e7f923b320a04a036527ce675bd885aceb78
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 16:58:19 2007 -0600
+
+ Fix segmentation fault introduced in 1.31-23.
+
+commit e28133f38f295fc0fde922bb331b2392b7731e83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 22 01:23:46 2007 -0600
+
+ Improve garbage collection by using GC_DECLARE_PTRFREE statements; use
+ vectors instead of deques everywhere.
+
+ Change nullPos() to nullPos.
+
+commit 9dd6708f1844ca303278016ff1936a1875ac97e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 21 23:41:19 2007 -0600
+
+ Document how arbitrary files can be imported in the configuration file.
+
+commit 52b24d47a94c2a1e7ad751ae95d7961c9a891fc7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 21 23:08:18 2007 -0600
+
+ Improve LaTeX diagnostics.
+
+commit dcbed2c557ecc629d6e9f84a61358f4c36ee0f35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 20 23:14:46 2007 -0600
+
+ Remove unused variable.
+
+commit 0e26979cc46959684fe2f39527a5ef9883a217a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 20 17:52:58 2007 -0600
+
+ Use GC_malloc_ignore_off_page to fix major memory leak in garbage
+ collection of STL containers.
+
+ Fix minor memory leaks.
+
+ Make em an errorstream rather than a pointer to one.
+
+commit 417f2582667c1d8851e8bcb86aa19ea6b51c62c7
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed Jun 20 17:25:31 2007 -0600
+
+ Added a new option to enable interactive mode on non-tty input streams. Made the signal option only affect the sending of signals without the side-effect of controlling interactive mode.
+
+commit 18b1cd9a00b7080ecea53589b3336ae9d4201b8a
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue Jun 19 09:55:10 2007 -0600
+
+ Modified signal mechanism to send signals for each shipout and at end of each
+ operation.
+
+ Modified handling of items deleted by GUI: bbox scaled by 0, file deleted, and
+ signal sent.
+
+commit c7163f9d5ed3bcf1eeb017f7e5112c38450bcb78
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 19 09:43:25 2007 -0600
+
+ Resolve purge ambiguity.
+
+commit dc2b4a56ad79e263e097e5cdeed3e7e07f53b490
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Tue Jun 19 03:44:43 2007 -0600
+
+ Fix the filling path according to the margin in the routine markangle.
+
+commit a0408c585ec05a353ca2e15066781663033d7ec5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 22:27:00 2007 -0600
+
+ Make the delete virtual member of arrays with no arguments delete all
+ elements of the array (not called clear to avoid the need for adding
+ yet another type-dependent virtual function).
+
+commit 4f0e48f95d301a5630af28c16ec925e0c3cc1c06
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Jun 18 16:44:27 2007 -0600
+
+ fix typo.
+
+commit 5cb4b64e129d881818262c767afff7d45e01947d
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Jun 18 16:41:03 2007 -0600
+
+ Add option filltype to markangle.
+
+commit 89f331e05e66b120fd670442900884efd354073f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 16:01:22 2007 -0600
+
+ Handle exceptions in doUnrestirctedList.
+
+commit 7f37372c405f4fd80361bad001ef02f37e3b842c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 15:45:57 2007 -0600
+
+ Declare shipout before importing plain_xasy.
+
+commit 5690b60c62de62d98f6e3c1e0482334e1d12bcfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 12:18:22 2007 -0600
+
+ Change the return type of the array virtual member delete to void.
+
+ Allow A.delete(0,A.length-1) on empty arrays.
+
+commit 65c979a50262609e5fca031dc4cdd6c14b3cf285
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 18 11:59:33 2007 -0600
+
+ Make A.initialized(int n) return false when n is out of bounds, without any
+ warning message.
+
+ Use A.delete(0,A.length-1) to clear arrays in base files, to help the
+ garbage collector.
+
+ Add options -compact and -divisor to give the user more control over
+ garbage collection.
+
+ Implement a purge() function that forces a garbage collection.
+
+commit 25c637e4cb5d99d7dcbd8ab3288a51ad98c9aaf4
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Mon Jun 18 11:10:53 2007 -0600
+
+ Updated to use Python's subprocess module.
+
+commit 146fc1cd81244154daecda352cc895a2011ae3ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 17 22:37:33 2007 -0600
+
+ Implement better workaround for uninitialized 'this.130' gcc-4.1.2 warning
+ message (cf. 1.22-56).
+
+commit 79b2f5a07fd457182ad22f21b40e25e2224f8aa8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 14 17:47:22 2007 -0600
+
+ Fix typo.
+
+commit 3512f0d737398b3ce742ec72d71208f986a54448
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 14 17:39:46 2007 -0600
+
+ Add pen[][] interpolate(real[][] f, pen[] palette) routine for use with
+ latticeshade.
+
+ Rename palette argument range to bounds to avoid confusion.
+
+ Use an implicit bounds constructor.
+
+commit 2f7b23fa999ea2fb39cc1ca60f0aca67fdc77a7d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu Jun 14 15:05:19 2007 -0600
+
+ Changed transform push(transform); to void push(transform); to remove output when called in interactive mode.
+
+commit 8dcaa58177fff6dd258a74c25408e739388f7aa0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 14 14:19:13 2007 -0600
+
+ Resolve ambiguity.
+
+commit ef75012b02a751b346e56d8a28e46a6160e77b2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 14 13:16:25 2007 -0600
+
+ Don't call GC_collect under MacOS X, as this can cause bus errors and it
+ doesn't seem to be necessary anyway on this platform.
+
+commit 27f248929ad55ecb5d2889d2ab67164605c1bd0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 14 11:32:20 2007 -0600
+
+ Remove unused line.
+
+ Add reference.
+
+commit c9fca9768ad6b8e2b59870cb0a58e3c49c9af15c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 13 19:47:16 2007 -0600
+
+ Minor changes to comments.
+
+commit 4e70e1300642aa779d3fe45da0d55e14f13231aa
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 13 15:57:37 2007 -0600
+
+ Fixed addOps to add fields when possible.
+
+commit f54e2aebafa9d46e05e02051c1a3e1885caf7b10
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Jun 13 03:10:21 2007 -0600
+
+ Suppress useless code.
+
+commit 66c61efa8f470b0663ccba532266ecddaf5c7d84
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 13 01:42:21 2007 -0600
+
+ Increment version to 1.31svn.
+
+commit afa57fd86437f39163b3f6e4013ee1e342faafaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 23:30:11 2007 -0600
+
+ Add copy argument to allow one to disable data buffering.
+
+commit 6857471c33699c8bac355f7dac013adbdb161692
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 22:42:44 2007 -0600
+
+ Add segment routine.
+
+ Optimize conditional graphs.
+
+ Add modified sphere animation, courtesy of Olivier Guibe and Philippe Ivaldi.
+
+commit bef55d64cd1ac2cd8e853db70915438d6ce7ad93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 16:56:48 2007 -0600
+
+ Remove unused filename.
+
+commit 6f932d116ca4c4b8d03866e24e5accf6bfeda7e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 16:50:45 2007 -0600
+
+ Fix dependency.
+
+commit 69b77ebd49abaef1873eee4a7e37db180e0fdb07
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 16:25:57 2007 -0600
+
+ Make the implicit initializer for file variables null.
+
+commit 9d0fc6bf18efe32d2c6831b964e8af52e61a6127
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 15:57:18 2007 -0600
+
+ Use a single box file.
+
+commit a946e3cc8a9aa8158670bdb83e2b340e7a130e62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 15:51:18 2007 -0600
+
+ Remove unused box file entry.
+
+commit 335e4ee9be80d0a97939d486341131931184f9de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 15:07:24 2007 -0600
+
+ Communicate to xasy via a single signal (SIGINT) and status file.
+
+commit f7c65d49a1f59f752311ac0e3b3640e19837886d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 12 13:52:42 2007 -0600
+
+ Fixed bug introduced by previous bug fix.
+
+commit 32c2800ea35bfe896c7f48a7718e59792ca78e2a
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Tue Jun 12 13:42:19 2007 -0600
+
+ Update documentation.
+
+commit e241156d089b9d735b13f9bf6cb3bb6c279d9379
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 11:14:03 2007 -0600
+
+ Move definition of interpolate to graph_settings.
+
+commit 1bdbf421d7c6bfe13099526295781e6341280878
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 02:23:08 2007 -0600
+
+ Add cast of triple[] to guide3[].
+
+commit 33a23676f0ca1d1afba511962752dcf08b9235de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 01:42:32 2007 -0600
+
+ Fix shipout format.
+
+ Remove old PDFanim_temp_Guide references.
+
+ Fix cxx errors.
+
+ Document reverse(guide).
+
+commit 79c54067909f345fe01096e620384023c518c1cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 12 00:08:25 2007 -0600
+
+ Simplify shipout signature (to support xasy development).
+
+ Support internal cycles in guide examination routines.
+
+ Add reverse(guide).
+
+ Fix guide tests.
+
+commit 6b1c2ed1c24d9cb03a27b0ceba6b40b3e658f1ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 11 23:49:48 2007 -0600
+
+ Fix typos.
+
+commit fd356f45ac4615c71510ec6a150943339de3a435
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 11 13:18:47 2007 -0600
+
+ Exit interactive mode on eof when stdin is not a tty.
+
+ If -signal is not set and stdin is not a tty, don't use interactive mode.
+
+commit 1458d017b58902acfd78b701295ad859b19da36a
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Jun 11 08:01:51 2007 -0600
+
+ Expand lasy-mode errors management (with Emacs 22 only).
+ Defer all shell redirection to Emacs for supporting most shell.
+ Compatibility running Windows.
+
+commit 7aa37aa0845c03e4b37e7a6c811c159491a352d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 10 18:09:37 2007 -0600
+
+ Update triangle example to use new simplified constructors.
+
+commit f5cbf4d90e602cfb7d3f1cfd9313a5b6e14316e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 10 17:26:31 2007 -0600
+
+ Minor edits.
+
+commit 89bfca7eabfea4f560ff28a7d7888ed81ff24cab
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jun 10 12:56:11 2007 -0600
+
+ Added implicit constructors.
+
+ Fixed bug with permissions in static methods.
+
+commit 0df0e0bf25d565bf41c5a1199a9520c6808b5c3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 10 08:01:22 2007 -0600
+
+ Add test for newton root solver; fix diagnostics.
+
+commit 5a36b41ea5052e2bbc342672ab80206e5e810864
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 10 07:20:12 2007 -0600
+
+ Optimize join.
+
+commit 256c7154f067526bf3f934bf44adbbe35b073902
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 10 00:12:13 2007 -0600
+
+ Give preference to GPL over AFPL Ghostscript.
+
+commit 99e825675e3b909070d74569af6cafbfce511eff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 9 23:25:19 2007 -0600
+
+ Add Philippe's lasy-mode fixes, including support for tcsh.
+
+commit 5b36cb1f2db85f87a749ee601cd9e1edc3c00202
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 9 12:29:29 2007 -0600
+
+ Add bool copy=true argument to picture routines that buffer data.
+
+commit 5b2b0bc4b7dfad18d539d1f3a193c23d507e23c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 9 04:10:23 2007 -0600
+
+ Improve garbage handling of multiple-file runs.
+
+commit 05baac943e890facf204004e80431ef0654bc30b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 9 02:57:12 2007 -0600
+
+ Remove default initializer for files.
+
+commit 0c996d014c98728580e98f7725067e55fca3d070
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jun 8 15:05:15 2007 -0600
+
+ switched xformStack from LIFO to FIFO
+
+commit e114be63575847d34e2a7d3faf8b4bc4b5389fb4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 13:09:28 2007 -0600
+
+ Revert spurious asy-mode.el commit.
+
+commit 37f51484712b4abb246e557115525f4b7137295f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 13:01:46 2007 -0600
+
+ Split readline functionality into readline and saveline.
+
+commit 881ffa21f9b210d495d78b8d4038d4f4507243ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 6 00:38:24 2007 -0600
+
+ Allow xformat to be any format supported by convert.
+
+commit d2efef6547f3ef83b632940a3c8b076b786ff26e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 4 22:42:05 2007 -0600
+
+ Fix parallel bison and lex processing.
+
+commit 763168a3f63580424432841fe379fba929d8b1f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 4 14:53:35 2007 -0600
+
+ Rename xasy.asy to plain_xasy.asy and revert other 1.30-48 changes.
+
+commit aa19a01eb70f11a9722e43238df6c9372909c61b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 3 22:15:09 2007 -0600
+
+ Improve documentation.
+
+commit ba6b456058e0c054b2cf7684b794dc196b1232a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 3 22:10:34 2007 -0600
+
+ Add Newton-Raphson iteration and Newton-Raphosn bisection routines.
+
+commit d7eec6237db5226eb68b4aae1d81dab759ac98cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 3 17:07:52 2007 -0600
+
+ Add support for new GUI xformStack (under development).
+
+commit bbc47a2c3b1046f405984710b5cc53a837080eaa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 3 10:33:17 2007 -0600
+
+ Require version 2007/05/24 or later of animate.sty package; remove
+ file name padding workaround.
+
+commit 3a780fa6f67832a65a0f082a345c2f585fd65217
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 2 23:20:55 2007 -0600
+
+ Generalize history to return an array of the n most recent history values.
+
+commit a7bee1f37cbd70a0c8b0c950681ed04d45187fc9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 2 22:39:49 2007 -0600
+
+ Add gsOptions configuration variable.
+
+ Force embedding of all fonts in eps files.
+
+commit 0c9baa4c098bea8f3d6ad8fddaa7fe972ef2d1db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 2 17:11:22 2007 -0600
+
+ Force all fonts to be embedded in pdf files.
+
+commit e91898e61889ad55a7798653056983cefe186d7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 2 12:00:40 2007 -0600
+
+ Force fixed format for compatibility with pdflatex.
+
+commit a183626cf3e2f804378ee2990e4d891c871e037a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 2 01:30:15 2007 -0600
+
+ Fix indentation when byte-compiled cc-mode.elc is used.
+
+commit 2baf201ecce79107e5f587f47f3b100b75d4c364
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 1 18:08:13 2007 -0600
+
+ Allow array insert to insert an array of the same type at a given index;
+ insert now returns void.
+
+ Allow delete to accept an index range and return the last item deleted.
+
+ Add initialized(int n) array virtual member to detect whether element n is
+ initialized.
+
+commit dd65fda0826f2f552d15e8e4ee907090844f046a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 1 11:04:43 2007 -0600
+
+ Split readline functionality into two routines: readline (with argument
+ order now consistent with getstring) and history(string).
+
+commit ab4774286f87ec5ca78a2f056566b772afd40e64
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri Jun 1 11:01:58 2007 -0600
+
+ Fixed typo
+
+commit 8096bb5fdf640778ed9715a64a16d89f40788ba5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 1 10:01:28 2007 -0600
+
+ Implement NoZero and NoZeroFormat with more general OmitTick and OmitFormat
+ routines.
+
+commit bf65e98df0c439c14d92cd68260981d935bd0380
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 14:17:57 2007 -0600
+
+ Avoid need to defer linewidth by moving setpen to the proper place.
+
+commit 3eaa60ba9b30082526d2d54d755ecf023e599c35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 13:53:57 2007 -0600
+
+ Omit identity concat commands.
+
+ Put dynamic linewidth code in /Setlinewidth.
+
+commit 7fe4be91e8b7cb1de9424dea14ef4221421aa903
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 02:21:50 2007 -0600
+
+ Fix linewidth.
+
+ Fix division by zero.
+
+commit 74a45e155bfd00a4515f527c27856f9c0b14e527
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 31 01:51:14 2007 -0600
+
+ Simplify linewidth deferral.
+
+commit 193bf8325dbcad9b36fb4cee380d51f66f0aa556
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 23:25:59 2007 -0600
+
+ Defer dynamic linewidth until stroke time in case currentmatrix changes.
+
+ Improve accuracy of dynamic linewidth calculation.
+
+commit f66e8527ba4dc2fcab6b99e2f9bc6f22eb69bc62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 23:18:10 2007 -0600
+
+ Rename zerotick to zerotickfuzz for clarity.
+
+commit a6791aefc4759ebadf7f17503dda4d5138692586
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 17:53:52 2007 -0600
+
+ Make zero detection robust.
+
+commit c28626c2078f8c17fed4c5053b0c03fc5caf95e4
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed May 30 13:48:10 2007 -0600
+
+ Fix numerical precision in the routine NoZero
+
+commit e00a7b8073d6dc8bcd86eb764ebee05218bd5a26
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 13:04:08 2007 -0600
+
+ Fix orientation code.
+
+commit 88e1d52a06ad38bbf37511a14f2e48a63957b60c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 12:37:44 2007 -0600
+
+ Simplify and optimize normal calculation.
+
+commit 9f8598a130268cf74d7ce1ce2ad25be62a0104aa
+Author: Radoslav Marinov <rtm907>
+Date: Wed May 30 11:37:58 2007 -0600
+
+ Changed the shading approach in base/contour3.asy .
+
+commit fe95f910e8de681b23e83f95165302efb4751e72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 30 01:32:47 2007 -0600
+
+ Implement simplified (and slightly more efficient) gouraudshade interface.
+
+ Reduce memory and CPU usage by avoiding duplicate buffering of picture data.
+
+commit f76232575f29b9a8d2ca0f010868581751a6d7b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 22:04:36 2007 -0600
+
+ Add tickmodifier NoZero and ticklabel format NoZeroFormat.
+
+commit 46f6ea1bc3b46c75b82edf3d32a3765ce8e86e40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 16:27:53 2007 -0600
+
+ New test routines.
+
+commit 77d1dd8f3ee01f0e22a61ae5089b7cd4a3edee4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 16:08:06 2007 -0600
+
+ Move real[][] identity(int n) from math.asy to C++ code; add documentation.
+
+ Avoid use of loops with join operator.
+
+commit b592bc60b2bcbc3c402d58a20090888786ffe65f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 16:04:44 2007 -0600
+
+ Minor optimization.
+
+commit 1adc55ad64b08356aa4b98895649d95d7e6c8e90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 29 15:54:23 2007 -0600
+
+ Cleaner optimization.
+
+commit befaf187a250eaf67d6b435244bd0a7462e265bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 18:14:29 2007 -0600
+
+ Remove extra loop variable.
+
+commit 63980fd23d2cba1835e8bdd76b3f41331ae30bcd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 18:11:05 2007 -0600
+
+ Further optimizations.
+
+commit 2e40007fb1e89ac0c5ba843043ae9d54dc810556
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 16:44:44 2007 -0600
+
+ Optimize number of calls to project; change return type of contour.
+
+commit 485f5ec8238cb2ad76ff5dc709e5a60f6aebe4fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 14:41:27 2007 -0600
+
+ Catch unhandled quit exception.
+
+ Reset scroll lines to zero.
+
+ Don't exit on interrupt during module load in interactive mode.
+
+commit 81dc9114a4f185d3188069048426c11f1d186df5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 14:14:22 2007 -0600
+
+ Renamed particle to object.
+
+ Minor optimization.
+
+commit 3c46482e8cdd28a52d9c27d620b8c1f605b40b93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 28 11:14:18 2007 -0600
+
+ Implement optimized real multdiagonal(real[][] a, real[]b).
+
+ Speed up project slightly by changing aspect from real[][] to real[].
+
+ Make cputime().change return parent+child times.
+
+ Add write(cputime).
+
+commit bfaf0370fc33d5dc9c23305a4fdfa26652aafb9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 27 22:29:01 2007 -0600
+
+ Added change.user and change.system fields to cputime().
+
+commit 948490a418a6dfda24c8ffb1e5ca7147e644bdfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 27 22:25:31 2007 -0600
+
+ Optimize real[][] * real[].
+
+commit d4803b09765b84dbc7e5cb75d6eb5bd0e30005b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 27 09:53:28 2007 -0600
+
+ Speed up 3D projection by moving matrix-matrix multipy to C++ code.
+
+commit cffe5e23420dbd5c84666fbe9f476c814c5f090a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 27 01:08:58 2007 -0600
+
+ Minor clarification.
+
+commit 26d3b69c93b217e6a6381bfef4b9e7a61c01e117
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 27 01:03:03 2007 -0600
+
+ Simplify, document, and port guide examination routines to three.asy.
+
+commit ab9070048364e614a86625a51838ee0d5a44a306
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 26 10:13:48 2007 -0600
+
+ Fix potential uninitialized variable.
+
+commit 270b67554e47b3894a8ae94f4c16e3825dc40a30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 24 02:07:53 2007 -0600
+
+ Add bool cyclic(guide) routine.
+
+commit a1fd6cd823ff17ed834191d21d98c27bdeddbe2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 24 01:53:03 2007 -0600
+
+ Add routines to allow access to guide components.
+
+ Add upcase and downcase routines.
+
+commit 01e48f273dbbd9058a803a8ac6267eb0e4477291
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 23 22:48:23 2007 -0600
+
+ Document bibtex usage.
+
+commit e6a7d6a3938e63411e98be86dec5d048e11ddb49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 23 22:47:47 2007 -0600
+
+ Install intro.asy.
+
+commit ab8b21e65692d7a75ee9cc8919edd84525ee44e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 23 22:47:32 2007 -0600
+
+ Remove pdf() restriction.
+
+commit 10a79c6c34636a7be292c25359cba859e274041d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed May 23 15:43:59 2007 -0600
+
+ Fixed docs about base64
+
+commit 0958687accac67e691a83e0954d482cf7e8d04d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 21 21:16:42 2007 -0600
+
+ Use projection P; reduce number of calls to project.
+
+commit e9c0b6c842d44ada09d14f4307264a3148c60d03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 14:16:43 2007 -0600
+
+ Reduce resolution.
+
+commit 8b490c2e53c7ac1a6e7526c41567151857b4a0f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 14:05:36 2007 -0600
+
+ Increment version to 1.30svn.
+
+commit ceea165b52e0a38618fbbf9041e04dc1b2f1af69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 11:25:04 2007 -0600
+
+ Update LocalWords.
+
+commit 9b797abba10a36e61a019b6ace4525dbdf4d88cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 11:16:54 2007 -0600
+
+ Improve description of contour3.
+
+commit 9651f6c97ac631429cee38fd736756c73ff25b00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 11:08:13 2007 -0600
+
+ Speed up tick handler.
+
+commit 4f3842489f2a4f21c08385b3e708374633c63752
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 10:44:24 2007 -0600
+
+ Reinstate abbreviation q for quit, unless there exists a top-level variable of
+ this name.
+
+commit 8fc806cbe73f7c4b609085e010916b93bc4d0e98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 02:02:28 2007 -0600
+
+ Use easier-to-use animate.sty package instead of interim pdfanim_temp.sty
+ package for generating pdf animations.
+
+commit 2aab5e1bf0488aeefa98a35dbb041dbb7c343665
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 00:48:09 2007 -0600
+
+ Add support for drawing zero-level sets of functions from R^3 to R.
+
+commit cb1882390a636614705b1e2d36f6da944d3b429f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 00:37:10 2007 -0600
+
+ Fill in potential gaps between histogram bars when bars=false.
+
+commit 99e519ccc5459da7fecff7de3acb1b131d951e78
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 00:11:06 2007 -0600
+
+ Simplify histogram interface.
+
+commit 5954c902a8b87765ae93d615bf79bbe011bbdc03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 19 00:09:42 2007 -0600
+
+ Fix FillDraw pens.
+
+commit d04ada5f9ce0252c0805ff6fe7dd7c462be417ea
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri May 18 13:35:20 2007 -0600
+
+ Minor refactoring.
+
+commit b15d658f724fc64c216437821dd086e1b75b99d0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri May 18 13:34:40 2007 -0600
+
+ Got rid of annoying "no default init for <error>" message.
+ Fix a boolean flag mixup.
+
+commit b5d5b2480a1df2751c8abe7ba4cb8106afd8aadf
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri May 18 11:08:24 2007 -0600
+
+ Acknowledged source of Imaging-1.1.6 patch
+
+commit 586bd648c5669f31bf60adb2664d720f7ca0c10d
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Fri May 18 11:07:33 2007 -0600
+
+ Documented the enabling of PNG format in xasy
+
+commit 26b715066b394320c125c417b0d14026e0f47c54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 17 21:51:53 2007 -0600
+
+ Remove unused directory.
+
+commit 62f5876939694c9ada532324caecacc47a10ad91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 17 21:48:50 2007 -0600
+
+ Add default argument.
+
+commit 4c752c5186524d5c7bbe4b837f672d193f204d82
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu May 17 14:47:36 2007 -0600
+
+ Documented use of base64
+
+commit 4eca9e53e681b998fc5a725ccf5e4ba33fdcab04
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu May 17 13:45:12 2007 -0600
+
+ Provided ability to draw a selection box to select all items in the box. Added item scroll up/down feature. Embedded the toolbar icon images into the source code.
+
+commit 05b3142d75defeef2015d7ff241ddfeb7e66ff00
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Thu May 17 13:42:01 2007 -0600
+
+ Arrows in icons are now the same style as Asymptote arrows. Transparency of text.gif fixed.
+
+commit ef70123f8dec5984ab5e27abaa461663d5c4cbbd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 17 09:19:11 2007 -0600
+
+ Added support for fillpen, drawpen, and legend entries to histogram.
+
+commit 5543f622b8f8087a6ad25ef71ef482ac50c045a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 17 09:12:11 2007 -0600
+
+ Adjust legendline length to account for marker size.
+
+commit 594ecf17fc8c156d9135c94463d4e4407d9591f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 17 09:10:53 2007 -0600
+
+ Minor optimization.
+
+commit 7e5078686cf17cdfb27f8182a7cf3db6dcb57ebb
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed May 16 17:28:12 2007 -0600
+
+ Improved handling of highlighting when mouse enters and leaves an item.
+
+commit ecaabcbbe2937b3f4b4777a1706973ae1820d063
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed May 16 15:09:06 2007 -0600
+
+ Various improvements to xasy3 made including ability to select and move multiple objects, and fixed the ability to open additional files.
+
+commit d1c63b6cd9c1399de497b9cda1d2be0587baade9
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed May 16 15:04:29 2007 -0600
+
+ Added new icon for xasy3 toolbar.
+
+commit 8dcf6de5f2db342913bdeea12f3483495c03d54a
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Wed May 16 15:02:55 2007 -0600
+
+ Updated Imaging-1.1.6 patch to adhere to conventions of other patches.
+
+commit 960b9890f5ce8e944fffa328e950dfc4db529cac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 16 07:29:59 2007 -0600
+
+ Speed up tickHandler; use default asy xformat.
+
+commit 2ca9d106ae96f6a79f7b9f75f204174aeed2146b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 23:14:35 2007 -0600
+
+ Optionally support transparent png deconstruction.
+
+ Work around half-pixel bounding box bug in Ghostscript pngalpha driver.
+
+commit a72b2a6966040de1948eafac30c0b2bed4701ddf
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Tue May 15 15:04:55 2007 -0600
+
+ Provided a patch to allow better alpha support in the PIL's ImageTk for the new GUI
+
+commit 5ce11724695458712b0a013b43d24c3119296b54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 15:00:09 2007 -0600
+
+ Fix typo.
+
+commit fe83e56c0dc3062414a50681305da9bf2fbdcec9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 10:37:32 2007 -0600
+
+ Fix typo.
+
+commit 0ed2fee6c78497a81fa73c24c4414d688db39950
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 10:36:47 2007 -0600
+
+ Fixed comment.
+
+commit 763d005d05d17ed653f6a0f61fc29a3b1fb92c0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 09:13:34 2007 -0600
+
+ Fix increasing(real[],true).
+
+commit d38d613d9fddd77ae1787d63518ab0326dd6dc77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 15 08:53:40 2007 -0600
+
+ Check that array x is strictly increasing.
+
+commit 90a313b01c7db33b5b9d0ea942df6b562d9b34d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 14 13:20:48 2007 -0600
+
+ Implement bidirectional signal handling to new GUI (under development).
+
+commit ee9a0615abb8b2da27829ee677a78a0370c2d5da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 13 10:07:35 2007 -0600
+
+ Generate begin and end figure comments.
+
+ Documentation updates.
+
+commit f252fe5dcd7a4a20aded818080dcd9fdffb72f24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 12 23:02:04 2007 -0600
+
+ Explicitly close EPS output file to avoid race condition with gv.
+
+commit ce8740b700536e06400f99cd381572621dfe57f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 12 17:12:57 2007 -0600
+
+ Increase arctime precision.
+
+commit e9f6461ad86397b18b593f3c815fa4d7680252c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 12 11:59:20 2007 -0600
+
+ Fix remaining numerical resolution problems with dir.
+
+ Avoid arctime error when goal == L.
+
+commit 1bb0f379df706ae156c7023e2f66a6fd16bf60a8
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat May 12 09:34:16 2007 -0600
+
+ Fixed images for xasy3
+
+commit e1a7b970ce10b948aff74c333edf4bc90caacb50
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat May 12 09:31:20 2007 -0600
+
+ Images for xasy3
+
+commit 8edbb37bd7e49d1cb2b976f314535d89a4bcd772
+Author: Orest Shardt <oshardt@princeton.edu>
+Date: Sat May 12 09:25:40 2007 -0600
+
+ Added xasy3 - a new GUI
+
+commit 551c851330c0456cf299939923164241f57df5a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 11 17:23:02 2007 -0600
+
+ Documentation updates.
+
+commit 4b3131bef0f47d97fcee17473e02ea11a3f97cd1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 11 07:05:05 2007 -0600
+
+ Suppress extra newline on standard EOF reads in absence of readline library.
+
+commit 60af1069ee62875c165dad1e53e1c6b00d0ff9f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 22:37:15 2007 -0600
+
+ Fix standard input of strings.
+
+commit e1c445ed7b053f5c9693bf60cff47610ab44b799
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 14:45:56 2007 -0600
+
+ Change SIGUSR to SIGINT and output a final box file to indicate end-of-sequence.
+
+commit 79197fc7fae5145c4e9662a47072143279af9789
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 14:44:57 2007 -0600
+
+ Remove "q" as abbreviation for interactive "quit" command now that
+ "write(q)" at the prompt can be written simply as "q".
+
+commit 4ce98eea4007a0fe7cf5802622ef719f5afbf528
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 07:18:45 2007 -0600
+
+ Document dot(picture,real[],real[],pen);
+
+commit e0993a89087f39b647d2328cc6f18127565fc7f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 10 07:10:00 2007 -0600
+
+ Add piecewise monotonic spline type and example.
+
+commit a46a851de05f1b753534b143b19934d2f42c1932
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 23:05:15 2007 -0600
+
+ Use subpath to implement robust dir(path, real) function.
+
+commit 3a2e0d8ad1ae707b7d6dfb1d0de8dc4a1db143d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 20:02:21 2007 -0600
+
+ Fix endpoint dir(path, real) calculation.
+
+commit ef66c2b368d5067eac92ed0da0dddb3b5176df53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 18:16:54 2007 -0600
+
+ Use datarootdir.
+
+commit 1cb07a0c9253787ad9dcf381411767d8bf40bed1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 18:15:43 2007 -0600
+
+ Support --enable-gc=PREFIX.
+
+commit 2a7208768685774e29e9bb0ab8e3b103a49bae28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 12:41:48 2007 -0600
+
+ When settings.signal=true, write a separate .box file for each object.
+
+commit d44ed6462ca2754968dc0fdadb2869f80a95162e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 9 11:58:15 2007 -0600
+
+ Port 2D dir changes to 3D.
+
+ Standardize argument names for point, precontrol, postcontrol, dir, and subpath.
+
+ Avoid numerical overflows in three.asy solver.
+
+commit dfacf1bfc1124c5776c12d2ba683ab1222204bdb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 8 22:06:12 2007 -0600
+
+ Fix definition of dir.
+
+ Add optional final argument to dir specify incoming and outgoing directions.
+
+commit c1244c0331a8731e0c9397c38f9800a488c57854
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 8 13:10:09 2007 -0600
+
+ Swap xasy signals.
+
+commit a0f8582e216ff3816b07b0c077b0be2e3b3d69b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 8 13:06:40 2007 -0600
+
+ Fix URL formatting.
+
+commit 7227dc2d4c4956d9d10de01d0f4cbc26d2b97667
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 8 04:08:38 2007 -0600
+
+ Increment version to 1.29svn
+
+commit 8089f96bfc42626f1e7619ff0d7d5e6e4100b173
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 8 03:16:55 2007 -0600
+
+ Force uptodate to be true just before call to C++ shipout routine.
+
+commit c62958d6773ef46f2694ab5efbed4ce8509cb8cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 8 03:09:49 2007 -0600
+
+ Swap gc library load order.
+
+commit 01c9abc9c59f02bc295960881b71ee91e396181e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 23:38:33 2007 -0600
+
+ Purge standard input after reading in interactive mode.
+
+commit 198580292c624fd5cbbecc672a8ca1646cf011bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 18:03:27 2007 -0600
+
+ Fix segmentation fault in readline() and runaway process on reading EOF from
+ standard input in absence of readline library.
+
+commit 044ccbd7b71d7337e043e41b53a8de9c1db3a3f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 17:32:17 2007 -0600
+
+ Add GCPPLIB target.
+
+commit 928c90747003c115ebef7553151b1e512bc842fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 15:21:27 2007 -0600
+
+ Support parallel builds.
+
+commit 25ca9066d7e2ff60f849f823799967e8105ab5d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 14:36:53 2007 -0600
+
+ Use SIGUSR1 and SIGUSR2 to communicate with new version of xasy.
+
+commit 62aff1b7496cf0f280670af7e032800bc85ae256
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 11:51:01 2007 -0600
+
+ Simplify and optimize xstream header.
+
+commit 9eeb41f829539b54e43b9eaaf23c1d2d22482058
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 02:04:59 2007 -0600
+
+ Add dvipsOptions configuration variable.
+
+commit a030a61bb2abf39ec2ef3a6f9aa2d175ebdac7b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 7 01:32:37 2007 -0600
+
+ Fix bug in xinput.
+
+commit 3f66b4b2165b32bca62e86a965895812c19294ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 22:49:39 2007 -0600
+
+ Further parallel documentation build improvements.
+
+commit 824ad21409ec9d7015a57d921d9cab8ca1a69ac8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 22:39:54 2007 -0600
+
+ Improve support for parallel documentation builds.
+
+commit e9704d91c1c8f7046fc6d76115edd0e48284078b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 22:03:35 2007 -0600
+
+ Support nonglobal animations, where each frame is scaled and written to a
+ file separately.
+
+commit 9aa7a3056a6d64fa7736bdd9e4b05fa9b879a10d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 21:38:48 2007 -0600
+
+ Support gcc version 4.3.
+
+commit 449ec2841903aa398eb87f801fbac43c174a1cb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 14:10:08 2007 -0600
+
+ Documentation updates.
+
+commit adb06d900490737193efc05e339b0291be3aa2b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 13:53:36 2007 -0600
+
+ Support parallel documentation builds.
+
+commit 6c6fae56f8facec0a0ca8a2e2ee238588b6c56a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 12:03:58 2007 -0600
+
+ Remove intro target to avoid problems under Fedora Core 5.
+
+commit 0fb4d6f9254d8932a266af94c48a63a041098558
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 6 11:31:08 2007 -0600
+
+ Improve TeX error handling.
+
+commit af3cdf75576976aa5c39d97d329448b0b7937628
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 21:53:16 2007 -0600
+
+ Minor makefile edits.
+
+commit bdf7fe2fa5bbfbc4d77cde52d3db7ab7517accfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 10:54:13 2007 -0600
+
+ Update URL.
+
+commit bfed005bb05306b76abd3f61951e467eaf12ebff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 03:01:44 2007 -0600
+
+ Clean up generated files.
+
+commit 5e281cf59111b1b3aa7f165bc606164bae4de682
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 03:00:52 2007 -0600
+
+ Increment version to 1.28svn.
+
+commit 4445d7145c63c04e73f1cd8d19bc17954ec7548e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 01:49:44 2007 -0600
+
+ Fix warning messages.
+
+commit b7d4b1dab520178724f8addb903be4eb910a6e5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 01:35:45 2007 -0600
+
+ Fix warning messages.
+
+commit 198b794abc6a48114e126a23bbac209e5a0b14f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 00:47:58 2007 -0600
+
+ Add example showing Hermite spline interpolation and filled cyclic crosses.
+
+ Fix formatting.
+
+commit 2917092e1a17e71124a9abb37b9fefbc2a1934ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 5 00:07:03 2007 -0600
+
+ Optimize palette loops.
+
+commit febdf53e4e8f7e338d1aca53d9bced32b4ca0eec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 4 23:43:14 2007 -0600
+
+ Fix data cropping/scaling.
+
+commit b1c9f2af191f12847edca78f8247ad6520309e94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 4 23:37:08 2007 -0600
+
+ Add modified version of Stefan Knorr's unit n-point cyclic cross, with optional
+ end rounding.
+
+commit 91b02a7743013213ec5708a102fbc8a675cbbc59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 4 19:36:04 2007 -0600
+
+ Add remaining fix for MSWindows version of TeXLive 2007.
+
+commit d7c903686fa3b56ed717f3d22a9a80566365c68f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 4 17:35:06 2007 -0600
+
+ Work around jobname bug in MiKTeX 2.5 and 2.6: turn stars in file names
+ (resulting from spaces, etc.) into underscores.
+
+commit f96e2c68e92fea5054048daa55197975d1d07cc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 4 10:39:03 2007 -0600
+
+ Simplify tex pipe handshaking and improve error detection.
+
+ Support TeXLive 2007 under MSWindows.
+
+commit f69a3cd29fd1a62bd5896075f68d3758fe555307
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 3 23:01:43 2007 -0600
+
+ Don't allow rotation about the zero vector.
+
+ Ensure align always returns a right-handed transform (a rotation).
+
+ Fix longitudinal skeleton detection when axis=-Z.
+
+commit 0adaa7180dfd822a832085978313ccdff8f0f8d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 3 21:47:55 2007 -0600
+
+ Add routine to return a diagonal matrix.
+
+commit a6e4c818bc820067f4ac3d23f94f03ba31dda98e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu May 3 10:22:29 2007 -0600
+
+ Removed finished item.
+
+commit 3a920b81235d9e48db94758a173640f0e57788ba
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu May 3 10:15:03 2007 -0600
+
+ Fixed typo.
+
+commit 97c6d8898719ed96b4297197eb0886a7dfd3dca7
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu May 3 10:11:22 2007 -0600
+
+ Assign expression are no longer written at the prompt.
+
+commit 4166ef82a9eabfbc16d27c9023d55a5dca9d768b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 2 18:02:32 2007 -0600
+
+ Add -signal option for signalling completion of shipout to xasy.
+
+commit 8dbd3e086f6a23de3b50b0b80442e0e405bb661a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 2 09:57:30 2007 -0600
+
+ Simplify use of join operator.
+
+commit feb0b3261b735876333a812f7a69acb39557270a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 2 09:56:36 2007 -0600
+
+ Change return type of contour routines back to guide[][] both for backwards
+ compatibility and in case user wants to connect smoothly to external
+ noncyclic contours.
+
+commit 9069d1c14e2ce94f3819f6c93d7ee075b3850ad1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 2 01:45:46 2007 -0600
+
+ Add Hermite spline graph interpolate type for smoothly joining sampled
+ functions.
+
+ Change return type of contour routines to path[][].
+
+ Move splinetype routines to new file splinetype.asy.
+
+ Add bool increasing(real[] x) routine to math.asy.
+
+ Optimize image scaling.
+
+commit 2afa9d4becfb09f442b9d483c2962bdbb17c5126
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 2 01:38:41 2007 -0600
+
+ Make guide precision consistent with path precision in diagnostics.
+
+commit 96e6c7831a825f65d68e4c451e50976a8213195e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue May 1 18:52:48 2007 -0600
+
+ Added curlSpecifier. Removed curl3.
+
+commit 2767fe88faa931e1a874d7c5c345a63b49c5b126
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue May 1 11:37:51 2007 -0600
+
+ Added the tensionSpecifier type. Removed tension3.
+
+commit 150a86b8b7e7c0517decd116ef158c4dcf409597
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 30 21:18:41 2007 -0600
+
+ Updated documentation regarding change from cycle3 to cycle.
+
+commit 5d3c433407d975022fb01b00c61e5e15ed62a934
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Apr 30 00:22:30 2007 -0600
+
+ Test for the cycle keyword.
+
+commit 13f9a9bb60b14e3b85253e98eb3bcbf86a6720c8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Apr 29 22:47:46 2007 -0600
+
+ Added the cycleToken type. Changed cycle3 to cycle.
+
+commit 1999876bb4ec9930ee59ef6d0c1817edbd55e468
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Apr 29 15:05:21 2007 -0600
+
+ Use an C Preprocessor X-Macro to create new primitive types.
+
+commit 3077361d259b777bcd6292481e2f00bf97868363
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Apr 28 15:56:59 2007 -0600
+
+ Remove old, unused source file.
+
+commit 9c10a8626a0f6a318bbcc6004d733799f1adcefb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 28 11:39:37 2007 -0600
+
+ Make Bezier curve solid and control lines dashed.
+
+commit 2443ceab7a8b6b9c6c6af2cc554f260bddb06ccd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 28 01:15:13 2007 -0600
+
+ Minor optimizations.
+
+commit c5f7661b9ce35af5bc2474c6debac680c4b25936
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 28 00:37:32 2007 -0600
+
+ Remove unused array.
+
+commit 81e44094a62541c243b2cc9901ce35af6179e692
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 28 00:34:47 2007 -0600
+
+ Use a simpler argument list for clamped splines.
+
+commit 5e2e7caad209a5c38576331d8015b3ae98c6ae44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 27 20:59:35 2007 -0600
+
+ Don't try to build intro.pdf with default install (due to eforms dependency).
+
+commit bc2debbdad6e48b58275f98c1142c46ccb9f9348
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Apr 27 08:26:54 2007 -0600
+
+ This file hasn't been used in ages
+
+commit 53b44dad2fc449bf2326b7c1bb5dd15b260adc10
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Apr 26 07:03:57 2007 -0600
+
+ Removed primArray. arrays are not primitive, and the type could only be only
+ erroneously.
+
+commit b84e53ba1d2caefd8ce83719ef073eff207d8f1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 23 11:09:51 2007 -0600
+
+ Rename "append=false" argument of output, boutput, and xoutput to
+ "update=false" and make it allow both reads and writes to the data file.
+
+ Negative arguments to seek are relative to end of file.
+
+ Add seekeof(file) to position file pointer to end-of-file.
+
+commit 6a31b86036ec819885ad7157669867d0cf4a2ca2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 21 21:38:16 2007 -0600
+
+ Fix dependencies.
+
+commit cc68406e9143ff04ab91d9b48ccdaf3824120e3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 21 19:41:32 2007 -0600
+
+ Distribute pixel.pdf rather than pixel.ps.
+
+commit 857de182af365683ec14ac86b23bbda5c4d8a323
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 21 18:00:10 2007 -0600
+
+ Add ability to load pdf animations from an external file (one frame/page).
+
+commit 0f052e45fb2b3da45a7b07472a244b4686183d6f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 21 14:20:48 2007 -0600
+
+ Make filloutside work with paths that extend beyond the current boundary.
+
+commit 1d86d57b95501aaee0bb025623ca0dace214dc1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 21 10:55:14 2007 -0600
+
+ Fix formatting.
+
+commit 1a55cbee13565c5b01899832c780dd008afd0fa1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 21 10:44:18 2007 -0600
+
+ Fix top level indentation of braces.
+
+commit ea8ca0f021d2c2986b8be72a4a884b3684714d79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 20 23:01:52 2007 -0600
+
+ Simplify control panel.
+
+commit 05f4d02e471c2f44eb88442085c091eb941e3e36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 20 22:51:17 2007 -0600
+
+ Added PDF rolling wheel animation.
+
+commit debce269ae9cd43e8cc214d1539466982320ddc1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 20 22:50:13 2007 -0600
+
+ Delete temporary .aux file.
+
+commit 858cf4e2c0f46142a8b9a6c7ba6015db3d1b7d58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 19 22:53:07 2007 -0600
+
+ Increment version to 1.27svn.
+
+commit e9bc191d312bde63e038828dbaa89173d1fa063b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 19 21:36:54 2007 -0600
+
+ Rename source and UNIX binary files for compatibility with releaseforge.
+
+commit 9a5852c7644742505ed12c8d94a0fcd8d54ca57c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 19 18:22:10 2007 -0600
+
+ Use a better camera-independent reference value for resolving path3 orientation.
+
+ Check for negative curl values.
+
+commit 0d3e6b78a14b0d1f02ca7fe35ce55de72047305d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 18 18:58:56 2007 -0600
+
+ Added patch to gv-3.6.2 to make redisplay work properly (and fix gv
+ security hole).
+
+ Removed --nowatch option from call to gv.
+
+commit d9292e4fbd36a22e00dd09095316c6ce197d6fef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 15 18:25:39 2007 -0600
+
+ Remove unused (and unmatched) %%EndProlog line.
+
+commit 7f8db6a7f07ac51a007315a71380e2c53d6480f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 14 10:56:19 2007 -0600
+
+ Remove unneeded access settings.
+
+commit 8e3086531898dc2fe69f1cbe25163b6d9ad91b7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 13 16:48:52 2007 -0600
+
+ Support pdflatex texengine.
+
+commit 6fb84927ebdc6c0e042ca0b812612abec957f3b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 13 07:46:54 2007 -0600
+
+ Improve example.
+
+commit 7223247bf194f2d1b077bad907cb773034aa6071
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 13 07:46:38 2007 -0600
+
+ Fix front/back transverse skeleton detection.
+
+commit 15be2bfe0c909747b52e12d015227f50b8a53418
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 12 06:16:58 2007 -0600
+
+ New item.
+
+commit 9446698168d19e677cd5a2b80c20c36dc7bd8c5a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 11 21:21:57 2007 -0600
+
+ New item.
+
+commit 31496173b22bded7a5dfa2443d23046581d891cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 10 17:30:34 2007 -0600
+
+ Speed up detection code for old versions of gv.
+
+commit 84bfb07a6af8defec0ed240c66b3ed0e144b2d69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 10 13:44:56 2007 -0600
+
+ Add link to online example.
+
+commit afe2f1fb251940fbbb3c645c7fb033aaff55007a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 10 13:29:11 2007 -0600
+
+ Add acsc, asec, and acot functions.
+
+commit f9a981f384e777b70f9f687a337f98526d20731d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 10 13:27:09 2007 -0600
+
+ Fixed typo.
+
+commit a1aaecbeadf18bedc200705f1d5333fa5bf8e9b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 10 13:14:17 2007 -0600
+
+ Implement Break tickmodifier to allow broken axes to work with automatic
+ tick generation.
+
+ Support broken logarithmic axes.
+
+commit 0ae96277f78f70fb940c43ab7d4e9bcf5e301843
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 10 09:29:12 2007 -0600
+
+ Autogenerate tick values.
+
+commit 34119036d472900f516599c0057b0f5d40836eff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 23:11:29 2007 -0600
+
+ Update FAQ.
+
+commit 5f65ee1cd809620c5c2b6f28b7c3aca7cd490052
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 23:02:39 2007 -0600
+
+ Add aligned axes example.
+
+commit ac3cca963cfe3d4b8da8c4482703741471066763
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 19:26:46 2007 -0600
+
+ Increment version to 1.26svn.
+
+commit 800b9ecf2f7db512f1403b7ee5ba9b3f135a2836
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 16:43:17 2007 -0600
+
+ Untabified and standardized indentation of base files.
+
+commit 6f5c1bc025be78de3a8b7697720d4f65117dd4f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 14:34:45 2007 -0600
+
+ Update documentation.
+
+commit 978a35b1855f746833c92c6f42cb68cbfd4678c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 14:27:36 2007 -0600
+
+ Added spline interpolation routines.
+
+commit f45ad4098c648fef4889d649ebe701d47a8a0c56
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 11:41:35 2007 -0600
+
+ Add Olivier Guibe's interpolation module and example.
+
+ Remove long examples from the documentation.
+
+commit 986a448e0cb005a22c5eadc5570abb757a217432
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 09:45:10 2007 -0600
+
+ Document syzygy module.
+
+commit e80ec64fb44ba22c33a46961e8334ddb07dc4c21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 09:35:49 2007 -0600
+
+ Remove default initializers.
+
+commit 1eeeb6a07e44f8331e54665ad7b92b6df3b2581d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 09:30:08 2007 -0600
+
+ Fix surface lighting.
+
+commit e613138e71f008bea5167a34aa5e9e014de676ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 00:27:58 2007 -0600
+
+ Update documentation.
+
+commit 10a32373996329021cbf79ceef6e0b8b53805822
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 9 00:26:01 2007 -0600
+
+ For parameterized surfaces, rename bool oriented=true to bool outward=false.
+
+commit 0544dc63934c2a48bf7647e3ae033f8e881c471a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 23:54:01 2007 -0600
+
+ Improve discussion of surface orientation.
+
+commit b4ddf284949a3b45c9284de6a70b8a9f350658f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 23:27:13 2007 -0600
+
+ Document oriented option for drawing surfaces.
+
+commit e38a112f2f848020fb656fe0ba122b624e3bf943
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 22:52:43 2007 -0600
+
+ Choose locally outward surface normal only for nonorientable surfaces.
+
+commit 1eb940f8367a1dfaa27f8b0ce6a54ef9be61622d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 21:41:35 2007 -0600
+
+ Make ^^ return a path3[] instead of a guide3[] for consistency with the 2D
+ routines.
+
+ Remove spurious specifier when writing a guide3.
+
+commit 2102439b301dad154e7a0bfb3b1acf67e76e03b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 17:43:53 2007 -0600
+
+ Document string array reads under line mode.
+
+commit eb31e3b3bfd1289bdbb23b307abfb82cf0e40dbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 17:31:00 2007 -0600
+
+ Add white-space string delimiter mode word(file, bool b=true).
+
+commit 134e8461c07f07602882ba0a8f0345ddd9f50997
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 8 12:25:39 2007 -0600
+
+ Explicitly write EPSF in output header rather than relying on dvips -E option
+ (which doesn't work for even the first page of multipage documents).
+
+commit a146939bda5fbfacffbc62ea05e2fe538e318c8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 23:21:51 2007 -0600
+
+ More guide3 to path3 changes.
+
+commit 3fef11043aa5c73e2005076490e32aab76f8a9f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 19:40:01 2007 -0600
+
+ Revert csv comment changes.
+
+commit d190952a8ee8b4009ce39fd1317452d1e196262e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 19:37:09 2007 -0600
+
+ Remove spurious diagnostic.
+
+commit ddcfae950a3b57e7e732adffe9073f9a08104d13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 18:43:10 2007 -0600
+
+ Standardize path vs. guide.
+
+commit 0a2ff0aecd3a54ddc3d83670684860d8962bea4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 18:42:27 2007 -0600
+
+ Update fixed graph size documentation.
+
+commit c002cc241415f7f20c12eae447ae7b6108465c65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 18:41:29 2007 -0600
+
+ Added header comment line.
+
+commit 034f0ba8b413d7e75cd5929c9116a67cf2f9782b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 18:40:09 2007 -0600
+
+ Standardized indentation.
+
+commit 3d286f1ad28dfeb14995285e612f6dc1b0b2d330
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 18:38:28 2007 -0600
+
+ Allow escaping of comment character in strings.
+
+ Disable comment character when reading raw characters with getc(file).
+
+commit 8bb86ef5431af89f942bfb99596cc39f225e02ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 7 02:10:49 2007 -0600
+
+ Added -E option to dvips to force it to denote the file as EPSF
+ (we nevertheless discard the computed dvips bounding box information).
+
+commit c24dd3e68d82f70181d174d5fa7577c5698731e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 6 16:25:57 2007 -0600
+
+ Document reltime, relpoint, and midpoint routines.
+
+ Add 3D midpoint routine.
+
+ Standardize path arguments names.
+
+commit 389a7ed6ce7db8b3aadd86617076a9d107cefb03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 6 00:31:29 2007 -0600
+
+ Clean up _slide*_.aux files.
+
+commit d8963113b0f5387409812cc06c85ad6d911cc73c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 6 00:19:31 2007 -0600
+
+ Updated intro.asy to Andy's talk at the University of Alberta.
+
+ Addded syzygy module and knots.asy example.
+
+commit a68182f723175d7d1d6e11f64b449358934db02a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 4 09:16:45 2007 -0600
+
+ Choose correct surface normal when calculating lighting.
+
+ Added Klein bottle example.
+
+commit 44c51f23f44b0a2f9853b917cad53d1ae54e06c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 3 23:14:18 2007 -0600
+
+ Removed unused sign.
+
+commit fcfc8dff3345a7c64404f699c5faf1e99babedaa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 3 09:22:21 2007 -0600
+
+ Remove unused dependency on LaTeX "rotating" package.
+
+commit 1144f27dbba5d4734ad8746ebd2e6b227b752973
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 2 11:29:48 2007 -0600
+
+ Clarify nonroot install instructions.
+
+commit 112c4a2ae2e4da7d2e88a0cf59b7d14831cfb025
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 13:48:00 2007 -0600
+
+ Allow one to control the minimum width and height of flowchart blocks
+ separately.
+
+commit 6976bf5a630648ce63974c1d4bcae61e81580d33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 03:16:23 2007 -0600
+
+ Incremented version to 1.25svn.
+
+commit eb0466e26e50f623a19e92d6d684e7c2771f533f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 02:37:10 2007 -0600
+
+ Fix formatting.
+
+commit d90199bc8d3066e009bc306a9983fd1ce6c2791d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 02:33:59 2007 -0600
+
+ Simplify makefile.
+
+commit 0794098153d3c097dd9be059912e8658b4e28aa6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 02:24:24 2007 -0600
+
+ Fix backslash.
+
+commit 3a142a13eb12dee1253557ff936b960e018b9fe8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 01:57:57 2007 -0600
+
+ Fixed typo.
+
+commit 38ef4f4978789996ca500ba495f2b4c1be857f76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 01:51:53 2007 -0600
+
+ Fix __CYGWIN__ preprocessor test.
+
+commit 77d574f2d4fdc16254540a407a5d1629ec98a6dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 1 01:36:06 2007 -0600
+
+ Fix binary space partition camera positioning.
+
+commit a34cfc8fb00166570506ded46b3d024c95ca7223
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 22:19:34 2007 -0600
+
+ Added 3D version of intersectionpoints routine.
+
+commit b0c9a79c7c500a149f7c780827aa75fc072c9083
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 20:00:15 2007 -0600
+
+ Add optional fixed block size specifiers.
+
+commit 40802aaae2756ff7e6668921e6698fa61be9c13c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 13:49:01 2007 -0600
+
+ Remove workarounds for real[1][] bug fixed in 1.24-37.
+
+commit 57e77ec4271d174065bb0bfdf82b2c6bcc821421
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 13:43:59 2007 -0600
+
+ Reimplement display.
+
+commit 9799ea22f5867510164c10a54ca80cc63715e9c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 10:40:17 2007 -0600
+
+ Change && to &.
+
+commit 94fd36e90228618768848c0162bab480d14e9c2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 10:39:02 2007 -0600
+
+ Change && to &.
+
+commit 33de1657b03bc42320c5eb86c98b1e9e11c45881
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 10:35:47 2007 -0600
+
+ Change && to &.
+
+commit b71d943ae2d9dcd130b67933eafa2428c078bbac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 31 10:33:03 2007 -0600
+
+ Update fontsize to use fix-cm.sty instead of type1cm.sty.
+
+commit 6d18e0cef3231caebc862301faf802311ecb1c40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 29 11:37:29 2007 -0600
+
+ Clear errors encountered via debugging _eval.
+
+commit b882d4513c2afe98f2e0ca3f2b93af3d38969cdc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 28 12:57:14 2007 -0600
+
+ Fix default y tick values.
+
+commit 2454bf7bca0d52ee0c11ab9476d50227e176eb70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 28 08:52:23 2007 -0600
+
+ Update MacOS X binary URL.
+
+commit 2b12ce9878dbd75656f6fc8553d82f0b7769b8d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 28 08:07:49 2007 -0600
+
+ Make angle(rotate(x)) always return x (mod 360).
+
+commit 8ee58e155eec492326e076bff8d8f027eb59c96f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 27 12:17:00 2007 -0600
+
+ Remove spurious line break after syntax errors.
+
+commit 6d1584acca30bccab6be9e94670bae9a0daf5d50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 27 09:41:53 2007 -0600
+
+ Update URL.
+
+commit 8506d3604012b3ad4f3e6dea7ae975885427fea6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 27 09:34:58 2007 -0600
+
+ Fix segmentation fault in Dumoulin's C++ port of Burke's Triangulation routine.
+
+commit f14aae102619fb51eadfb85a752f0d397e5dd257
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 27 08:05:53 2007 -0600
+
+ Fixed new real[1][] bug.
+
+commit e5c50a3081ca75bfb3a53abbe035c088d35cb565
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 27 07:36:38 2007 -0600
+
+ Added bitwise NOT function.
+
+commit c87a4702b5a22089740bca982354de10372f7ea9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 27 06:54:12 2007 -0600
+
+ Rename intersect arguments to correspond to documentation.
+
+commit 24999ddf3c831ed9826e84de4b03d52caea257d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 27 06:53:31 2007 -0600
+
+ Fix segmentation fault given real[n][0] data array.
+
+commit aaacb7bb0e0b6bc0cdd1f7f07fc1790b58799b2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 26 13:28:28 2007 -0600
+
+ Added missing tensorshade picture arguments.
+
+ Fixed ambiguity with "asy plain_picture.asy" test.
+
+commit 35554fb9280a9c780d69737f512aabfedcb10a44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 26 13:21:56 2007 -0600
+
+ Change array op && to &.
+
+commit 94c5fb19f5f155d33b121d136a8d7474e4c94420
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 26 07:41:10 2007 -0600
+
+ Use hard-wired postscript-to-tex scaling for clipping, rather than
+ calculating it from defaultmatrix, to support explicit post-scaling of eps
+ figures (e.g. with \includegraphics).
+
+commit c08a992e5e0347f07b5683e6bd4984704abaf8c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 26 05:52:05 2007 -0600
+
+ Document multidimensional array initialization.
+
+commit 075bdcdcee1b2265977c57a9cde43760e1b3b273
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Mar 25 22:56:55 2007 -0600
+
+commit 8ec594d671d9ee9ab1413338acdde4267f09fc30
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Mar 25 22:10:05 2007 -0600
+
+ Removed array checking from && and ||.
+
+commit 075f7a044afe33940236a9c4c214cfeaad3f17c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 25 01:24:51 2007 -0600
+
+ Revert 1.24-20.
+
+commit ee2164a96b22a92cf9ed7d619f91715269150189
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 25 01:05:02 2007 -0600
+
+ Document null instances of structures.
+
+commit 3b60ad1a87c5abc1ef0787af4aa5451e5a0fd169
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 25 00:53:13 2007 -0600
+
+ Use null initializer for binarytreeNode.
+
+commit 34f6924ccfa298c0d26b33db8dba9da749c3a8d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 25 00:23:46 2007 -0600
+
+ Added & and | boolean operators which work like && and || except that they
+ always evaluate both arguments.
+
+ Renamed array boolean operators && and || to & and |.
+
+ Added AND, OR, and XOR bitwise functions of two integers.
+
+commit 9e706d5ee15c8dbf9819b5312822fc7520a01937
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 24 12:19:48 2007 -0600
+
+ Fix intro.pdf target.
+
+commit c873f8f32bd379219745c525ece0ca1958d51563
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 24 11:28:46 2007 -0600
+
+ Simplify and improve implementation of figure().
+
+commit 72bbad4b5a7824d4289c68048e7bcd989509c6e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 24 11:28:08 2007 -0600
+
+ Use invisible figuremattpen for Asymptote logo.
+
+commit 9612c0baa049b7cee97da93edcc6ea2ecbeb3400
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 24 11:27:25 2007 -0600
+
+ Enclose PostScript clipping code with gsave and grestore.
+
+commit 343e5997cffbdbfca15be8f76860383c8215f6b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 24 11:25:52 2007 -0600
+
+ Move camera for infinite projections.
+
+commit 0e54a478c8a5493836cb768177361c27c81b13e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 22 21:41:41 2007 -0600
+
+ Allow | as binary operator. Remove || and && from list as they always expand to
+ a ? true : b and a ? b : false.
+
+commit 9747370ce3fd2fa51fdf797a8d77e3d63d8a0d44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 22 01:34:13 2007 -0600
+
+ For infinite projections, move camera to outside of bounding box.
+
+commit 93dec9da6affa79af424914424ebcec1653398fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 21 06:42:18 2007 -0600
+
+ Fix binary space partitioning for projections from infinity (oblique and
+ orthographic).
+
+ Generalize perspective projection to allow any target point.
+
+commit d7a1ebcc32a4f23eb799c49edea0cd80c58948c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 19 01:23:53 2007 -0600
+
+ Use local projection consistently in binary space partition splitting.
+
+commit edd4e9b3041869b5dc0009e5cb362d6e33a066af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 18 06:33:03 2007 -0600
+
+ Check for tension < 0.75.
+
+commit dfd1fe22894aaa0f0b187355e5b2ae3522abc585
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 14 22:18:10 2007 -0600
+
+ Update documentation of the implicit initializer for structures.
+
+ Remove operator init() initializers that are no longer needed.
+
+ Initialize Tension in three.asy with sensible defaults.
+
+commit 0ecb68b4f3b77fd1209fd7216de26a8ea18a43b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 14 00:47:33 2007 -0600
+
+ Support multiple pdf animations in inlinetex mode.
+
+commit 3a448743613ea1c0d3b76d3b198277862933777e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 14 00:46:44 2007 -0600
+
+ Minor reorganization.
+
+commit a79dad027e794ce6c1ce6bf45e48d667c6292694
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 14 00:44:28 2007 -0600
+
+ Format.
+
+commit f37633940d041d83ba87555b72b14448d93c8594
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Mar 13 21:48:12 2007 -0600
+
+ Add automatic record initializers after the records are defined.
+
+commit 945347dfb0a151559683d2de6d9bb43f32d6a1f0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Mar 13 21:37:27 2007 -0600
+
+ Added note about loop translation.
+
+commit 65d305d1d6c8bf8f4c3901abb9a62301d406a55c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 13 01:23:43 2007 -0600
+
+ Input LaTeX preamble only in inline mode.
+
+commit bc2eb60aef3d9eb856754d0fb5f78ea39a698c3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 13 01:14:55 2007 -0600
+
+ Work around pdflatex bug.
+
+commit a00caf67c40dc0a3aac245cb48e0570ebb7ef23e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 13 00:34:06 2007 -0600
+
+ In inlinetex mode, communicate the asy texpreamble to TeX via \jobname_.pre.
+
+ Remove asypreamble environment; corresponding Asymptote commands should now
+ be put in the asydef environment.
+
+commit b81e30903180f8e7484a71d3a5bd1b4747f2e4ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 11 17:49:13 2007 -0600
+
+ Minor updates.
+
+commit 5bad764fa7566f1ffd55e21b8d3b21375789a6ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 11 12:23:17 2007 -0600
+
+ Make Ghostscript dependency explict for MSWindows.
+
+ Check for GPL Ghostscript as well as AFPL Ghostscript.
+
+commit 7f0756bea504dd1757cd36786b24cbf9c77f39c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 11 11:15:00 2007 -0600
+
+ Minor clarifications.
+
+commit 50f44e45dad41a856c3761a46b32c806bc6a9d56
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 11 10:30:10 2007 -0600
+
+ Simplify MSWindows registry lookup.
+
+commit 0f83019e080aa3e30ef15265510874c35566a9ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 10 01:52:49 2007 -0600
+
+ Incremented version to 1.24svn.
+
+commit 41136ee276c09cbebf2adbe85f17b5a2a59c958d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 10 01:13:56 2007 -0600
+
+ Fix cxx warning.
+
+commit 48deb18c78765d5d568fe118af97dd32d94296aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 10 00:56:52 2007 -0600
+
+ Autoconfigure under MSWindows by querying the registry, so that Asymptote
+ and the applications it depends on may now be installed in any location.
+
+commit e72fbc666cfe970f1e6f9071282cffd9c0e21839
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 10 00:52:43 2007 -0600
+
+ Check if hint is set before accessing it.
+
+commit ef4585636df941aebbcc644da75bf0efe864c0b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 10 00:18:41 2007 -0600
+
+ Fix import gsl under MSWindows.
+
+commit 96516a2f3962a449794e32c55df6ab829cc39607
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 8 23:35:13 2007 -0600
+
+ Simplify implementation of texpreamble environment.
+
+commit 8409e9082abae2880c6b34d6aadc3dbc94b066e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 8 23:03:33 2007 -0600
+
+ Fix typo.
+
+commit 45214f111b7624a440ce0c06c433473c6d8aadd3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 8 22:59:11 2007 -0600
+
+ Add empty postenvironment definitions.
+
+commit 1ae539fa6b5086c888ffe7ec867f9ae8dc747239
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 8 22:35:25 2007 -0600
+
+ Add texpreamble environment to contain the LaTeX preamble for both LaTeX
+ and Asymptote.
+
+commit 7c35840227fb6ed47caaca66151a7c7580aa0558
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 8 12:44:25 2007 -0600
+
+ Remove unused line.
+
+commit 3fb97fb770706084c7f861439c4022ed33edc879
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 8 00:43:48 2007 -0600
+
+ Add autoimport option.
+
+commit 9067d6a86f046363dcf0866c6c8cf4995da6296f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 6 12:17:22 2007 -0600
+
+ Allow shipout to write to other directories if and only if -global is true.
+
+commit d51027228f2c19d7ed6105965ba9ceef86e47feb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 6 01:25:30 2007 -0600
+
+ Ensure colon is catcode other (12) so that TeX includes like
+ \usepackage[frenchb]{babel} don't break inlinetex mode.
+
+commit 719b2629105273aee7e305c14c525f490916a69c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 16:05:53 2007 -0600
+
+ Fix background picture sizing.
+
+commit 5e7740180fd2443186313e1d3ca75f24756fe9a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 15:58:47 2007 -0600
+
+ Set background size.
+
+commit 4e53202a7842f7b70c98b7e9d261b6876b0795a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 03:51:51 2007 -0600
+
+ Incremented version to 1.23svn.
+
+commit e51ba11fadb17a7143209a488946b0afd8022734
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 03:01:16 2007 -0600
+
+ Added missing header.
+
+commit 43f28e4087ee950538d510d9a0ed3202afaad9d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 02:33:43 2007 -0600
+
+ Support legends in both forms of 3D contour drawing routines.
+
+commit 569ae970d8db7d95d58fdfce5712cf4c23316f41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 02:31:49 2007 -0600
+
+ Support legends in 3D contour drawing routines.
+
+commit 2afb1187ff55ec41489dbbb1ea5ae2bbf52b2b0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 01:58:37 2007 -0600
+
+ Add discussion of icomma package.
+
+commit e7dff4a2871bac88f3eca8092d03fd0d824e4ee4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 01:44:32 2007 -0600
+
+ Fix format(-0.5) under locales with nonperiod decimal separator.
+
+commit 1f32d4f244925636cdc8e3a4ee7bc81e33247757
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 5 01:17:12 2007 -0600
+
+ Mention link page, including user-written Asymptote tutorial.
+
+commit 1efe402b1f06f8324bb28baef1afdb5f7ae5fe87
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 13:17:33 2007 -0600
+
+ Add predefined markers.
+
+commit 8cf34dbca37b1a0591cfd1ab8b25e86d3f6da30f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 12:18:45 2007 -0600
+
+ Minor edits.
+
+commit 00c3be6095cb906455e9add45fd09a62c2db8bc2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 12:10:23 2007 -0600
+
+ Renamed markuniform(int n, frame center, bool rotated=false) to
+ markinterval(int n=1, frame f, bool rotated=false), which now centers n copies
+ of frame f within uniformly space intervals in arclength along the path,
+ optionally rotated by the angle of the local tangent.
+
+commit 6d64c0e317ac554dc59ab485f397a0c35c5f3dc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 11:16:14 2007 -0600
+
+ Explicitly list intro.asy dependencies.
+
+commit 295ef5c7c5d9446ef413ab8c8fdc7c7ccc2670f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 01:59:30 2007 -0600
+
+ Updated marker documentation.
+
+commit 110dcddb82504ce175127fa710e8374fb2812c04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 01:53:21 2007 -0600
+
+ Simplified/standardized markers interface.
+
+commit 80159d48f46ea3901eec293db16cae9bc4420fcc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 01:47:51 2007 -0600
+
+ Formatting.
+
+commit 962832601f3e9e90b6eb8c095387eb870a4a727a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 01:47:38 2007 -0600
+
+ Remove bibliography page numbers.
+
+ Add Asymptote logo to intro.asy.
+
+ Change clearpage to eject to avoid extra page.
+
+commit f8bc8a7b1fb503c436af8186535600ff17be0ec0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 4 01:45:34 2007 -0600
+
+ Draw minor ticks below palette box.
+
+commit a6a66a28cf1e8c392535cfbd6ff6c04da4b72f03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 22:08:48 2007 -0600
+
+ Add short description of slide presentation package.
+
+commit 5c84f25b91ffe0e4314f1b964874ad5c05d59d09
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 20:33:03 2007 -0600
+
+ Remove directory qualifier.
+
+commit 53f814b6cb83a889bdd308363c2d1f9f40872c95
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 20:32:42 2007 -0600
+
+ Import pdfanim.
+
+commit 737c32260dac29c8bde3515febbed216a644afb3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 20:31:52 2007 -0600
+
+ Check incoming array bounds.
+
+commit 6de5f36de58ea78b64c0b8a0d37ea43eb330055a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 18:48:39 2007 -0600
+
+ Show page numbers on subsequent bibliography pages.
+
+commit ed62ed3343292791f5477d367afdd82e57a0b6f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 15:46:09 2007 -0600
+
+ Number last page before bibliography.
+
+commit e716a018114ce9598ff41ccbd9c0f822d8f8d802
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 15:45:49 2007 -0600
+
+ Revert temporary patch.
+
+commit 24b6ad1e65d8f31c070120c9d4fd58bdc6b4ca8e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 14:37:29 2007 -0600
+
+ Add implicit pen initializer defaultpen.
+
+commit 79440c76a089e66c9414a69e53ffa4114c6ac846
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 14:02:54 2007 -0600
+
+ Fix concatentation of nullpaths.
+
+commit b36b0ff2a8500b758c7eb6e74b0420fb6619d71a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 3 13:32:32 2007 -0600
+
+ Make seconds return -1 instead of 0 on failure, for consistency with UNIX
+ mktime routine.
+
+ Document workarounds for unimplemented "%Z" time zone specifier to seconds.
+
+ Improve diagnostic.
+
+commit 9d009d9cd6f24e8718bb070443cfb5a5548c99aa
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Mar 2 16:06:35 2007 -0600
+
+ Minor changes/updates.
+
+commit cef22845c934ef9ce1d3b3283a716da51cc1d105
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Fri Mar 2 13:43:16 2007 -0600
+
+ Replacing the parameter 'frame markerframe=newframe' by 'marker marker=nomarker'
+ in the routine 'markangle' of 'markers.asy'.
+
+commit 14770fb363a0e22d8567bbf2cd12e07317459579
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 2 01:16:21 2007 -0600
+
+ Don't output texpreamble in inline mode.
+
+commit 6bf22cd5c542932bcc16a4bd2eb13dc0c4924164
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Mar 1 16:28:33 2007 -0600
+
+ Correct typo.
+
+commit bbb56abd6df169c548416d28fbacabb496b122a8
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Mar 1 16:15:58 2007 -0600
+
+ Documentation of the package markers.asy.
+
+commit c51dfc0ef6f4f9a6bb4b0763a8468dbaeee081a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 1 10:01:41 2007 -0600
+
+ Added routines to facilitate drawing 3d contours.
+
+commit aeb93083ebf797ae7ea89fd8603fe1bc86ce8e04
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Mar 1 09:37:30 2007 -0600
+
+ Examples about the modules markers.asy
+
+commit 7e9811263c6e476a8319b267e2628d00c4e55aaf
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Mar 1 09:12:30 2007 -0600
+
+ Others mark routines and markers.
+
+commit 5f357b465b01ad8453669cdd0e68cda959a2fe50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 23:55:57 2007 -0600
+
+ Implemented binput and boutput functions for reading and writing in the native
+ (nonportable) machine binary format.
+
+commit 619e0eb074bd696e477f554ad39e05a1e2abba59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 18:54:28 2007 -0600
+
+ Document local installation.
+
+commit 5abac133b9a2e39f7de51b3e78d7ec2264844c79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 18:29:42 2007 -0600
+
+ Fix uninitialized 'this.130' warning message from gcc 4.1.1 and 4.1.2.
+
+commit 589714ecf3020dbd8343d30e2f2b563b4cfcb2a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 14:56:44 2007 -0600
+
+ Fix bool latex() and pdf().
+
+ Remove lscape dependency and need for autorotation in slide.asy.
+
+commit a2b08e65ba2025acfd9a783b11228a7e9b9ad033
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 13:40:49 2007 -0600
+
+ Reactive begingroup.
+
+commit 8346e1f95f11c3bc8eddca970b98d97fc82314d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 01:35:32 2007 -0600
+
+ Fix cxx errors.
+
+commit 5a91b91d46484cabb85106964da62a8474e56124
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 01:28:39 2007 -0600
+
+ Remove unused configuration variable AC_HEADER_STDBOOL.
+
+commit d90520bc7ce05c294cb459fc7de59aeb7f6ff72e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 01:17:09 2007 -0600
+
+ Fix cxx errors.
+
+commit 00286c95eb86c6ca13b928d6e896284f4b40e090
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 00:58:30 2007 -0600
+
+ Move mem::list out of common.h due to ambiguities under old cxx compiler.
+
+commit 4605357c6055cf45d3dcef9ffc22abdaa3ad227f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 28 00:09:49 2007 -0600
+
+ Impose -finline-limit=400 on old (< 4.0.0) compilers to greatly speed up
+ compilation.
+
+commit 94461d882cc2220b0a3f1cf90be4266e776efa6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 27 21:00:26 2007 -0600
+
+ Put global name space qualifications in new common.h file.
+
+commit 09c9b3fa75c27d24b1b5c878ac4b168cefbda878
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 27 11:08:33 2007 -0600
+
+ Make tex pipe aware of a previously generated aux file.
+
+commit cb136567a0559ceb1e03cbbda415fc09730b92b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 27 09:58:53 2007 -0600
+
+ Fix makefile dependencies.
+
+commit cd0a6ca21f10584d53ce99755d1b1d613b8e6750
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Feb 27 08:42:56 2007 -0600
+
+ Fixed inTranslation to handle frames for loops.
+
+commit 3be97ec517574378d66b17fdd56fffa648f4c4b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 27 01:10:31 2007 -0600
+
+ Temporarily fix svn builds.
+
+commit 1b0ecce40c2506006f6cc50a02c4e627eae7f375
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 27 00:50:54 2007 -0600
+
+ Temporarily disable aux file input.
+
+commit 19cbe577536297a610ab82d0594cf319790f8f10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 27 00:40:30 2007 -0600
+
+ Fix further memory leaks.
+
+commit e9d3303233bca786e89f4e93e350ae47bf7d745c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 26 23:10:23 2007 -0600
+
+ Fixed segmentation fault.
+
+commit 958c6cef19c04de0233b8c74f225b92622a96832
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 26 22:53:35 2007 -0600
+
+ Possible workaround for Makefile problem on Debian.
+
+commit 8d5616d89c2ee990f99f41cd77f09ae0c3033340
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 26 22:37:06 2007 -0600
+
+ Fix memory leaks by using mem::string, mem::istringstream,
+ mem::ostringstream, and mem::stringbuf everywhere.
+
+commit c1c5d708a113372efded3d150becdaaf448939e6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Feb 26 20:03:46 2007 -0600
+
+ Explained lifetime of loop variables.
+
+commit 0f5fdcb427cb50132a5fd75fcc3ea66afd6c339e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 26 18:22:21 2007 -0600
+
+ Update discussion of local variable allocation in loops.
+
+commit 8fa2bbc07e668d81994fe7c5a175785e2c846625
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Feb 26 10:07:53 2007 -0600
+
+ Added documentation on static qualifiers in loops.
+
+commit 24ebb6ed94fc72834fc65c5810bfb32fc86cb70d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Feb 26 09:41:28 2007 -0600
+
+ Removed completed TODO item.
+
+commit 1e853994a00f8f03ff38224f72c45938fc5341a6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Feb 26 09:40:41 2007 -0600
+
+ Allocate variables in a loop iteration in their own frame.
+
+commit b02f3e9e89a9a238776865964130c6f59acc81b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 26 01:36:35 2007 -0600
+
+ Force outputformat to "pdf".
+
+commit 9774670154436e67834ffa5aa1bbc318e08e19be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 26 01:35:40 2007 -0600
+
+ Set outformat to pdf.
+
+commit aa62a61b2cfd4bbd17921f16efd87361bed9f7d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 26 01:34:34 2007 -0600
+
+ Remove unwanted texput.pdf file.
+
+commit 1f79220f7fabf8fa77bc793ff6496fd13f3b8ad0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 25 12:22:00 2007 -0600
+
+ Load color package even for TeX pipe.
+
+commit 4704954e697f43814036a265aa24167a44094110
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 25 12:12:13 2007 -0600
+
+ Formatted.
+
+commit a22b8a5f2ed5c58ecb71011b002aea4bb18f6cf4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 25 12:01:12 2007 -0600
+
+ Avoid duplicate .aux file inclusion (and duplicate labels).
+
+commit 8457c22a764d521431306d6e5f2ee35f696bfeb1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 25 10:54:30 2007 -0600
+
+ Removed extra blank lines in tex pipe diagnostics.
+
+commit bcd456adaa56865795a56fd79e30c06035eb3906
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Feb 25 09:08:43 2007 -0600
+
+ Improve the function 'perpendicular' of geometry.asy.
+ Add operator +(margin,margin) in plain_magin.asy.
+
+commit 7e615740d62fb8a03a860096dbe171a24629ad26
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 25 09:02:11 2007 -0600
+
+ Simplified bullet command.
+
+commit 39ebe210dbaf2d88b8718f2c133e67b30a3b2976
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 24 20:47:11 2007 -0600
+
+ Load correct base files.
+
+commit dd1c4f3889bcf345d3ecc51c073a943cf2e18fb3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 24 18:23:36 2007 -0600
+
+ Simplify skeleton routine interface.
+
+commit a3bef6031cc2d11cacaa9591384e5944e34a5f22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 24 18:15:39 2007 -0600
+
+ Split skeleton routines to provide finer control.
+
+commit 6c5626ec4b4ddfd42d290201f7380d6fced6697a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 24 10:52:09 2007 -0600
+
+ Turn off setlocale warnings when not debugging.
+
+commit eb64a46e3c5258f2ab2961806137d68432cff2f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 24 10:51:43 2007 -0600
+
+ Use namespace setitings.
+
+commit 0e186293fc0ef7e9f1f225a3eeb9352befef0a47
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat Feb 24 04:52:50 2007 -0600
+
+ Correction of ps/pdf-view-command documentation.
+
+commit f04de4b85808c9ea00408d5980193a6c4131e399
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 14:21:01 2007 -0600
+
+ Fix hyphens and formatting in man page.
+
+commit 87be657999a27707a9f350d12af9c5bc397ffbdd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 14:06:48 2007 -0600
+
+ Change autorotation to true.
+
+commit 7b0e270e5d124a8461eef2e0bf16358ce23e5704
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 13:49:10 2007 -0600
+
+ Updated Debian binary site.
+
+commit 7250ad829c9c7ff62af5f6b7becf6e9b87f0831f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 01:36:59 2007 -0600
+
+ Generate more missing files.
+
+commit 2838d55fb10875f0b1e3a5507a5d56ed5a3fda01
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 01:34:49 2007 -0600
+
+ Autogenerate missing files.
+
+commit 89d1e10b78ece25ee7d849842c3d1b67d0d21a24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 01:17:06 2007 -0600
+
+ Make eof set fail bit.
+
+commit dd617e23ff042a645799765c026d957a26174abb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 01:14:51 2007 -0600
+
+ Make eof set fail().
+
+commit c8ef33f8c97613f20661d59e66e8adb203dd3298
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 00:45:12 2007 -0600
+
+ Removed duplicate sentence.
+
+commit 2d3e33840a04de9dfe992aa7e6918bc2123c0233
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 22 00:43:07 2007 -0600
+
+ Added introductory Asymptote slide presentation (intro.pdf).
+
+ Added keepaux option to keep intermediate LaTeX aux files.
+
+ Added example filegraph.asy of graphing columns of data from a file.
+
+commit 6d3d08232d56387bf8bf380dd2276e00f5dbca82
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 21 22:40:34 2007 -0600
+
+ Fix logarithmic tick labels near the machine epsilon.
+
+commit 7cb527aa0f797fac93c55361a73b681520d79b1a
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Feb 21 11:29:15 2007 -0600
+
+ typo correction.
+
+commit a99f04bf33f835cd01e18992f017c054ecd23a65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 21 10:56:54 2007 -0600
+
+ Remove alien to deb conversion documentation.
+
+commit 38901d8c23decbfa17f315764c8df364bed9b0d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 21 10:47:55 2007 -0600
+
+ Support slide bibliography under pdflatex.
+
+ Add string file(string) which reads file as a string, and verbatim
+ typesetting command.
+
+commit d55d529c634b42bbdfb154599846e194077931e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 20 22:52:11 2007 -0600
+
+ Added missing space.
+
+commit 0db3c87ea569656db60ae7b6c9c14c34d26a9278
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 20 00:01:03 2007 -0600
+
+ Fix typo.
+
+commit 67315f9b3532b56be11642bb4658c40bcc8d0660
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 23:52:40 2007 -0600
+
+ Added backgroundcolor and foregroundcolor.
+
+commit aab77966ac5949fe473ff6ba8283c013f405adbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 23:51:23 2007 -0600
+
+ Implement colorspace command for extracting colorspace of pens.
+
+commit e3d25c1625df9a46f7931ca4ee11785cbfa40fef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 23:50:50 2007 -0600
+
+ Implement verbatim command.
+
+commit 29f7efe9c211530c3644174e85a615802390af83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 10:58:21 2007 -0600
+
+ Incremented version to 1.22svn.
+
+commit 530cee38deab33c6bb6f258343780dd50f115064
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 10:08:21 2007 -0600
+
+ Fixed cxx warning.
+
+commit 71299d099650766e53d29a402955fe21dd802e91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 09:56:20 2007 -0600
+
+ Fixed typo.
+
+commit 3d95261cbf08da1f78eeae90649f139955bf0d1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 09:18:14 2007 -0600
+
+ Allow DEFCOLOR when promoting colorspaces.
+
+commit 1648096a4682a22040b6b5d25ffcfcc3ae8e9b8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 01:54:23 2007 -0600
+
+ Automatically promote colors to highest colorspace in shading and image
+ routines.
+
+ Fix grayscale and cmyk latticeshading.
+
+ Significantly increase speed of image processing by caching bw, gray, rgb,
+ and cmyk settings in a global variable.
+
+commit 060ec7b110baba9ce843160f0496e3374d74bbfb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 01:51:41 2007 -0600
+
+ Update documentation of Linear scaling type.
+
+commit 739e7799707acc2b40df1bdde077f161e3c36212
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 01:50:14 2007 -0600
+
+ Check array bounds.
+
+commit 68a728cd54aa6f5a2938385a7cadaa978eb55e63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 01:49:34 2007 -0600
+
+ Collect double-vertex contours.
+
+ Increase epsilon.
+
+ Fix contour fill routine.
+
+ Separate contour fill routine from palette computation.
+
+commit 8e88b7bece6699bf201b38c3b9014c17b64a9d6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 19 01:42:43 2007 -0600
+
+ Added Philippe's improved show-function-at-point fix.
+
+commit 3296b1030ef1efdcdf4aef9f98a9c8a146356b25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 18 13:58:55 2007 -0600
+
+ Delete any existing *asy-help* buffer in asy-show-function-at-point.
+
+commit b077b3cc360fdd8db29b7000f313cfb06ce657be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 17 10:37:26 2007 -0600
+
+ Improve tick calculation when Step > 0.
+
+commit bc65ba3bfa7df77f6595c01157b7c17f8cba7b0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 17 09:47:45 2007 -0600
+
+ Fix tick calculation.
+
+ Improve zero detection.
+
+commit 7ad2d1586877b6f20100d015ef5eb635774a5c44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 17 04:48:15 2007 -0600
+
+ Fix tick label scaling.
+
+commit c4c4905a39c572319effb6827fcbf9aefba011d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 16 22:19:34 2007 -0600
+
+ Remove vv from settings module.
+
+commit 8329e569bc7165fa1e527de6b6f7ad1373a27aa7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 16 10:23:29 2007 -0600
+
+ Resolve -vv ambiguity.
+
+commit 09b37eb90a3ac72ce0bcb9961a15f7896d5684d8
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Thu Feb 15 05:00:02 2007 -0600
+
+ Fix typo.
+
+commit 998c2fa3deac0139446767d0f9f65d274935419a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 15 00:37:14 2007 -0600
+
+ Fix spurious vertical shifting of bullets.
+
+ Reimplemented figuremattpen.
+
+ Make bibliography visible in reverse video.
+
+commit 9e6233395b63bbc959ffaacd6f319164db6703cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 14 15:02:00 2007 -0600
+
+ Added --version option.
+
+commit c030c15fbca03914b0210fab3470799af5af718c
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Wed Feb 14 05:51:45 2007 -0600
+
+ bug fix in asy-show-function-at-point
+
+commit 9aa9f39611d0e229b6ac79942e73896168ea51e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 14 00:56:41 2007 -0600
+
+ Resolve ambiguity in intersectionpoints.
+
+commit bec36677558ed0cafb33667d4f0f1a6bafdd4f21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 13 23:41:42 2007 -0600
+
+ Add rotated option to mark_uniform to rotate marker frames by angle of
+ local tangent.
+
+commit 0c4f5d2faeaedf7d632b90520a7bb18df8434632
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 13 23:40:33 2007 -0600
+
+ Ignore empty picture bounds when adding pictures; simplify userBox and userClip.
+
+commit d0f942ed145abf11fde2fa9d8477bee8e23d06f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 13 16:08:01 2007 -0600
+
+ Update to latest autoconf install-sh and patch it to ignore -p option.
+
+commit 98607cc485eaeee9eb2d4c0302472ed7a1c9644e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 12 22:44:06 2007 -0600
+
+ Add an ASYMPTOTE_SITEDIR environment variable listing additional
+ directories to use for generating asy-mode.el keywords.
+
+commit aa2f07afb124f788a8907694b27eca8d4e6b3d8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 12 22:19:14 2007 -0600
+
+ Document new interactive calculator feature: expressions entered at the
+ interactive prompt are automatically evaluated and written to stdout
+ (provided a corresponding write method is defined).
+
+commit 4567f5d9838154710e983302f326abe95b76a8d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 12 21:47:36 2007 -0600
+
+ Add patch to fix an incorrect Boehm garbage collector prototype in the file
+ gc6.8/include/gc.h (version 6.8).
+
+commit 22d41dda2545b641c1a2832345a92b0d391ace23
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 12 15:53:52 2007 -0600
+
+ Added texcommand to allow one to override the tex engine command name.
+
+commit 1c62d3d8c1bb514fb97eacf3b07333b80d304ce1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 12 13:54:38 2007 -0600
+
+ Apply gc6.8 GC_INIT patch for AIX systems.
+
+ Document gcc3.3.2curses.patch.
+
+commit c90f96075d63fbc599687077100c6418a7395710
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Feb 12 09:11:48 2007 -0600
+
+ Minor edit.
+
+commit c388257e763a4f2ae366b5d744f7779f5fa70429
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Mon Feb 12 08:51:18 2007 -0600
+
+ Add brief documentation of lasy-mode, typing correction.
+
+commit 37491da9333a05505bbc8e0bbb0f78ba7fa08ddc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 12 00:04:47 2007 -0600
+
+ Fixed cxx warning message.
+
+commit fe1ac1c604b6a40966bf995547555fd2e9ec6245
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 11 23:51:14 2007 -0600
+
+ Fix compilation under -DNOHASH.
+
+commit e8fe41e5a84de4de2cc1bf3c5246afacf3cddb48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 11 23:36:38 2007 -0600
+
+ Portability tweaks.
+
+commit 1a97f4303dd1bd63c322cb10d755d7dba573cc36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 11 22:58:27 2007 -0600
+
+ Use more portable context patch.
+
+commit 6d0b90232ea1539b61a780bdb8e3235ea63719fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 11 22:47:20 2007 -0600
+
+ Make patch more portable.
+
+commit 0bbc03244b2fa3a5c4793db2f3f7601617fe41e3
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Feb 11 20:07:13 2007 -0600
+
+ add (require 'wid-edit)
+
+commit 9c7416d268c126574b1e00969e3c49decb5a5f00
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Feb 11 19:55:37 2007 -0600
+
+ Links pointing to the files are added when one shows for the command at the cursor by the key binding C-c ? within asy-mode.
+
+commit 6da0c5ac38364b2038385d0dc288ea99c24caf38
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 11 15:32:47 2007 -0600
+
+ Add Andy's patch to store positions of definitions in entry class.
+
+ Add a --where option to make --listvariables show where global functions
+ and variables are declared.
+
+commit f7b7688158acd70cdfc1c3f3c32563716fa9c63c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Feb 11 11:32:21 2007 -0600
+
+ Fixed typo.
+
+commit 4c19d68b2e0e5fff7cf4b5b0f010aa058de60fd8
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sun Feb 11 08:42:07 2007 -0600
+
+ Allow to type when viewing compilation result within lasy-mode.
+
+commit 6d12264abfcc6c1dfa3326b9aec75c74bf113e8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 10 22:57:26 2007 -0600
+
+ Fixed typo.
+
+commit b1e2adb3b5dc60d570cf8297cd7add44362efb7a
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Sat Feb 10 10:28:02 2007 -0600
+
+ Support of the options of the environment asy and better management of the errors within lasy-mode.
+
+commit bdb5876f7d51333e90292bab9acb70970a5927ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 10 00:36:57 2007 -0600
+
+ Revert to gc6.8.tar.gz due to rpmbuild segmentation fault.
+
+commit fd4329a37e509b7f47342d4eba7e1f91c1d9d032
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 23:42:54 2007 -0600
+
+ Added surface operator * (transform3 t, surface s).
+
+commit abd9551f6272a590b9109fddb6c662fa7ec8cb32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 23:24:08 2007 -0600
+
+ Check for out of bounds mesh size and array indices.
+
+ Use size(frame) function for max(frame)-min(frame).
+
+commit 3312cca7b3d00b4902f45347fdd55dd2b0285d7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 23:18:43 2007 -0600
+
+ Check for attempts to create negative-length arrays.
+
+commit 769c4d4bd69f1ff1d0d9cf18dc53161e1f40347f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 22:08:29 2007 -0600
+
+ Removed unused line.
+
+commit c9afe9d8c76477e6bbbb197167584b759e63ab36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 20:53:22 2007 -0600
+
+ Implement an interface for drawing an arbitrary binary tree.
+
+commit fba9e659a0cf5f0d916c038ab496888da351f84e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 16:55:23 2007 -0600
+
+ Document GNU make requirement.
+
+commit 5f58b7ce5a7f53a42a1ae3f32f5728f8debb7a95
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 16:54:18 2007 -0600
+
+ Changed capitalization.
+
+commit 1ecec67510e605f657c87377ad9cfdd7dee79b2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 16:46:39 2007 -0600
+
+ Ensure curses routines are declared with "C" linkage.
+
+commit dc38dd518284ac9e386a2f88cba8e179945c8dab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 15:57:52 2007 -0600
+
+ Work around broken curses.h files.
+
+commit b1606ac1b54a3bfeae1a50f2e857e9bf0678b236
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 13:37:34 2007 -0600
+
+ Renamed patch since this apparently affects both AIX and SGI systems.
+
+commit 8c0137405e6e96d01f315f3ac5b15c6764e42cb6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 9 01:27:54 2007 -0600
+
+ Fixed bounding box computations of paths drawn with transformed pen nibs.
+
+ Implemented optional labelpath interface to PSTricks pstextpath macro for
+ drawing curved labels along paths.
+
+ Updated to gc-7.0alpha7.
+
+commit bcf82b8e9feaebcb73dbc0d7068fe6ec276d8368
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 8 18:26:46 2007 -0600
+
+ Revert premature changes.
+
+commit 35040851ca57497a1dadd0536e6e7cb4e4426e30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 8 10:48:07 2007 -0600
+
+ Added wait option that waits for all child processes to terminate (to work
+ around emacs child-killing bug).
+
+commit 6743274ad35977ff9363d146c5558f8aa707b19a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 6 14:57:37 2007 -0600
+
+ Minor edits.
+
+commit 320742785a08abb9fb6b78db95835a2b1abbd9c6
+Author: Philippe Ivaldi <pivaldi@sfr.fr>
+Date: Tue Feb 6 11:16:33 2007 -0600
+
+ Cleaning code, resolution conflict math-mode/lasy-mode, add options for compilation and management of errors.
+
+commit 2290dec816dc2a6232f21f30c9317121c7e1ef0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 5 08:08:03 2007 -0600
+
+ Added patch for old broken gcc3.3.2 curses.h file under AIX.
+
+commit 4042666bd1a4988a825ec1849c5677cc230e363b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 4 19:26:12 2007 -0600
+
+ Optimize intersectionpoints.
+
+commit 5502059281016c7de55403e44f99d89fe231b2d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 4 19:08:11 2007 -0600
+
+ Added routine intersectionpoints(path p, path q) that returns an array of
+ all intersection points of paths p and q.
+
+commit 460e2d1f6182b2d97242490eb2adda04a425eb9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 4 18:50:53 2007 -0600
+
+ Fill squares.
+
+commit bb2c743ee8d20e0e30b52670c48b7d18f1dffe10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 4 11:21:53 2007 -0600
+
+ New items.
+
+commit a8f23e8c889e9f1893512712626af44609567d61
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 3 22:48:07 2007 -0600
+
+ Make the user-specified tick functions work consistently with the
+ auto-generated tick routines; the actual tick value is now passed to the
+ ticklabel formatting routine, even in the case of logarithmic axes.
+
+ Separate the tick generation and drawing routines and add a tickmodifier
+ routine to give users complete control over which of the auto-generated ticks
+ actually get drawn.
+
+commit 5622457a7f048fad5382ff935ee48c1226537a5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 3 16:38:42 2007 -0600
+
+ Add bibliography example to slidedemo.
+
+commit 0b89cd153c13bde0ce630345f1e701104bf7570f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 3 12:48:57 2007 -0600
+
+ Add fuzz to textwidth and textheight to avoid overfull vbox.
+
+commit ddc5436324f83a005af69b9cd3da9168d293accc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 3 03:33:38 2007 -0600
+
+ Implement slide presentation BibTeX citations and reference list.
+
+commit ed82d85f4cc623545ffa56b84960140f180b9eca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 1 00:41:43 2007 -0600
+
+ Set autorotate in PDF landscape mode, rather than forcing pdflatex.
+
+commit e0a2cfc3e4f1f843e0b091251262dacc535a80db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 30 11:35:17 2007 -0600
+
+ Leave the pair to angle conversion to dirSpec.
+
+commit d0bf991ec29c0f64e674144ad712c71035f377c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 30 03:12:58 2007 -0600
+
+ Document skeleton structure.
+
+commit a5dbc91b7d38d4a00fd3ac8058d3791295a2f68f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 30 02:59:34 2007 -0600
+
+ Mention Imagemagick dependency in Windows installation notes.
+
+commit 9cfcdfd2373f4cecdfc0e14c3094ec2676eca8ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 28 20:00:41 2007 -0600
+
+ Added Tobias' binary tree module.
+
+commit af67f65d329659d8f09f72ddc6e4a0c86bfabbc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 28 15:51:04 2007 -0600
+
+ Added Philippe's grid3 contribution for drawing 3D grids.
+
+commit 2183fd2b95de35f28ae290475098b348c7393f8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 28 12:59:14 2007 -0600
+
+ CYGWIN updates.
+
+commit bff9813318d27712c88d95b3644c6cbbb3422e91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 28 11:29:02 2007 -0600
+
+ Make definition of pair I=(0,1) explicit.
+
+commit 0676c7ca4c969ea1e5c2a00715bc927e404be527
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 20 15:15:16 2007 -0600
+
+ In inline latex usage, do not scale picture by default. Use
+ \begin{asy}[\the\linewidth]
+ to recover previous default of scaling to line width.
+
+commit e1c6822967164b7f84ef8138731f643beea685af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 18 23:28:21 2007 -0600
+
+ Implement transparency for shading and image objects.
+
+ Allow one to disable Gouraud shading when nsub=1.
+
+ Allow draw(nullpath3..cycle3).
+
+commit 8e6c49af4cc0152189c19102b6af9450b2e38f8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 18 04:44:16 2007 -0600
+
+ Minor improvements.
+
+commit 21d936a6f39423cd9dad1306b64ae505f81b691d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jan 16 22:00:37 2007 -0600
+
+ Automatically write expression statements at the prompt.
+
+commit a3ed3d9f8f860be6b58e55aed37301b20834e28f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 10 18:39:03 2007 -0600
+
+ Added missing tickmin and tickmax bounds.
+
+commit fe6f7fa300b309fc6a9efac47edb7b58fc227b3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 5 15:27:17 2007 -0600
+
+ Removed unused code.
+
+commit 942c58e014617c5aa10f371666aff13cd62ea820
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 28 23:56:30 2006 -0600
+
+ Incremented version to 1.21svn.
+
+commit e93e77fbf5760e54dac1e34a272eaf8e68995cfc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 28 23:16:22 2006 -0600
+
+ Fixed cxx warnings.
+
+commit b149b00628a00c8997c83ba17028123f6706ea9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 28 22:42:55 2006 -0600
+
+ Cleaned up cd diagnostics.
+
+commit 0484808a98b46807b50a356938d768156571144f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 28 22:22:32 2006 -0600
+
+ Simplified example.
+
+commit f948d9fd2a2e58af5ea2777d795a846efe28e5fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 28 22:19:01 2006 -0600
+
+ Fixed incorrect offset in palette.
+
+ Added routine to fill cyclic contours and example.
+
+commit fd3d40f61129392f0a95b2ef983b2ec0d30bb6fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 28 11:01:47 2006 -0600
+
+ Added command-line option to set current directory.
+
+commit 57e3dc524f51a3e99872048372017ec97d5c2c15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 28 09:55:13 2006 -0600
+
+ Generalized example.
+
+commit d93a8963d04f5dee344fab4a80d77cb53fbdf75e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 25 07:15:20 2006 -0600
+
+ Updated FAQ.
+
+commit e9d78222d9e0718942fb4a68728c73302063e395
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 25 06:31:43 2006 -0600
+
+ Clean up Getenv code.
+
+commit fc08f980d32c8ac4ce0ade1571a0542b81a5f417
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 23 16:51:41 2006 -0600
+
+ Fixed texpath and diagnostics under MSWINDOWS.
+
+commit 3c0eecc0ed831ffe777369bb4bb091cb94220fe1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 17 10:45:04 2006 -0600
+
+ Remove texmathp stuff since this duplicates features in >= AUCTeX 11.82.
+
+commit feb9da7b8257ef209e3278b2f87b41c59ec2cd52
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 16 15:44:50 2006 -0600
+
+ Make asy-mode respect TeX-electric-sub-and-superscript.
+
+commit 0082575ea324c018b1ab5f74db63c9e02b38c9cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 14 11:42:16 2006 -0600
+
+ Improve loading/including diagnostics.
+
+commit 50ac54c6ef5594ab8f8773f6d12a153c7dadc0cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 14 10:54:15 2006 -0600
+
+ Fixed defaulttransform (e.g. to allow forcing of yaxis label angle).
+
+commit a56b9a2c982ddee6627d3b8d547acd4583504096
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 14 02:32:35 2006 -0600
+
+ Optimize real argument point, postcontrol, and precontrol functions.
+
+commit d975c6f1f6fd2bcd4c5ae71a892eddb4725763c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 13 16:16:24 2006 -0600
+
+ Simplify example.
+
+commit 5fe5f889e7f3b60d28f743938f0078a60e51ea2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 13 13:06:37 2006 -0600
+
+ Improve discussion of Bezier curve subdivision.
+
+commit 77e618b22206cc463b4b992cf06214c04b53553b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 13 02:36:09 2006 -0600
+
+ Slow down wheel animation.
+
+commit aac2e48a515a1eaacdb8002f8c7653dfd3eb1f24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 13 01:18:33 2006 -0600
+
+ Incremented version to 1.20svn.
+
+commit d7890f4c911721a8888a48dfd2defa9ca322f726
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 19:11:44 2006 -0600
+
+ Emphasize that multiline mode is a setting that can be turned on and off
+ within interactive mode.
+
+commit 2ae5f0146df9bdb5253ccb392bf56bf20e8e72f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 17:17:30 2006 -0600
+
+ Minor documentation updates.
+
+commit ba0d38fb3bc7f70abafe5f7567177d8d0dc71c20
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 13:01:14 2006 -0600
+
+ Make cd() reset path to program startup value.
+
+commit 799f9abedc6066e2ffa5d2ef160309808e6ed55e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 12:47:29 2006 -0600
+
+ Updated documentation; fixed cd argument renaming.
+
+commit 592297a5493a9988cdf9333e37694e731d1e119f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 12:17:43 2006 -0600
+
+ Interactive reset should not reset current path.
+
+commit 6a918d048a7eb6fb6cc5dc0951c4541de2f04ad0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 04:05:00 2006 -0600
+
+ Shift cylinder so that axis is c--c+h*unit(axis) for consistency with cone
+ and generalized cylinder routine. This change is backwards incompatible.
+
+commit 4d3f02e34615f1b18b2e14d065ea5fd392e4cb51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 03:29:45 2006 -0600
+
+ Updated svn instructions.
+
+commit 4b2793891d4bde829ede86a2cb802f6fab97b823
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 03:25:22 2006 -0600
+
+ Implemented preliminary Bezier surface package.
+
+commit 3cbdc8e412cfecab2c25378692dd8bb743c7a461
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 12 03:09:10 2006 -0600
+
+ Require Common Lisp extensions.
+
+commit 0be9332591649e2d31655440295b9a4f9d2b3d53
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Dec 8 19:59:58 2006 -0600
+
+ Added support for meaningless slashes at ends of lines.
+
+commit 75f727b5e8009f1735d22e30d67e25de44e2abd1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 8 12:06:02 2006 -0600
+
+ Fixed cxx errors.
+
+commit 3a3c973590cdc283b9999a06b1a861371ef75550
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 8 11:12:41 2006 -0600
+
+ Andy's port to nonbash shells.
+
+commit d04d9e3e929fd00402740e1c2ce40b746da9581b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 8 03:02:12 2006 -0600
+
+ Fix epstopdf conversion of empty or tiny files.
+
+commit 087e28c569c90006b21984f3beb45766c1a9778a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 8 02:46:52 2006 -0600
+
+ Improve tex error handling.
+
+commit 77bb38ecd311f9df362cde2a070d64bdbb914399
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 8 02:05:47 2006 -0600
+
+ Fix clipping in inline tex mode.
+
+commit 082f53960ca57b5dd2624d0362db130cb4742f0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 8 01:49:43 2006 -0600
+
+ Fixed clipping.
+
+commit 1147cc2d94edfd43f5c3a74989558c4bf7be4b24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 7 22:41:18 2006 -0600
+
+ Fixed inlinetex mode.
+
+commit 2482b4e78091adfe4bb41c0346e37dbbd41f2067
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 6 23:45:16 2006 -0600
+
+ Repair tex pipe on missing math mode error.
+
+commit 359e08078ca660615441f4bbda493f07ed54aa71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 5 15:13:45 2006 -0600
+
+ Use path instead of a guide.
+
+commit 3f35adc02e203e38bcaf0c1eb809e7da2467c8d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 5 15:13:19 2006 -0600
+
+ Remove explicit internal control points.
+
+commit 62992e7115c828486cacdd129b501c5280c4edfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 5 15:12:37 2006 -0600
+
+ Remove bashism.
+
+commit 31d267c642b285b910c10ac7c7d36270642bbc6b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 4 12:38:44 2006 -0600
+
+ Standardize flowchart argument names.
+
+commit edf855ad0f9cc5b443dd2a2537ade28fad528a88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 4 01:37:40 2006 -0600
+
+ Simplify flowchart block size calculation.
+
+commit eca530722546fb201f7e2c36087668e55ff06f45
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 4 01:18:33 2006 -0600
+
+ Make flowchart routines work with pictures as well as frames.
+
+commit e280d4eb846978b79faf2c13072bd8fa42d997e0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Dec 3 22:57:16 2006 -0600
+
+ Added note on backslashes.
+
+commit 358cf9043de1378c8c18230b8e4da0d09a1670e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 3 11:46:53 2006 -0600
+
+ Renamed object constructor to draw.
+
+commit 3521ace7c8d3588a26cc4180731e53a6e14d116e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 3 11:33:49 2006 -0600
+
+ Implement add(picture pic=currentpicture, drawer d);
+
+commit 335405299efca708634efa1a8914e849e84f3ade
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 3 10:56:26 2006 -0600
+
+ Replace labelframe by existing object structure.
+
+commit be667c03682ade8d1a1f4ac5a29d6694c89c1870
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 3 00:00:26 2006 -0600
+
+ Renamed envelope to labelframe and container to envelope.
+
+commit 971e339c2404266220d1aa2b3a47937c044b3787
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 2 23:19:41 2006 -0600
+
+ Introduce an envelope structure for supporting picture scaling when drawing
+ boxes around labels.
+
+commit 9c6ec1a60ea1fc573b5350b58f2dc771db941c88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 2 23:17:56 2006 -0600
+
+ Updated to use new intersect routine.
+
+commit 1e1903f2ace7734b5f68aab18749129b45caf318
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 2 23:13:45 2006 -0600
+
+ Added fractral tree example.
+
+commit d4f5146c773422f65b7a7a652f1723eeb6301f69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 2 17:25:09 2006 -0600
+
+ Make intersect return an array of reals rather than a pair. In addition to
+ being more logical, this helps avoid confusion between intersect and
+ pair intersectionpoint().
+
+ Autogenerate usage info in manual and man page.
+
+commit 8f2688c4e68120ff8ed18a41bd28858d1ae9f1b8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Dec 1 23:10:09 2006 -0600
+
+ Backslash now continues a line on the interactive prompt.
+
+commit 0a4d35d81ba0ee6578c3d585c823762edc107297
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 1 21:52:09 2006 -0600
+
+ Minor diagnostic improvements.
+
+commit 80e67f1986502df4ff6f2bab7374dc220e7d4ccf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 1 18:33:22 2006 -0600
+
+ Fixed compilation failure without GC_DEBUG.
+
+commit fc53ce97a16a28720671a41425923a5473a6ff30
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Dec 1 10:08:14 2006 -0600
+
+ Added gc debug option.
+
+commit f3afd793ab03d434687d893ae74f234cfb177a3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 1 09:44:32 2006 -0600
+
+ Remove shift from transform in Rotate(pair).
+
+commit c6c6cfee767553835b1806317af54d3f63e9be22
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Nov 30 22:52:19 2006 -0600
+
+ Added multiline option for prompt.
+
+commit a9e4ee9ae1e6867146b34bc45e632947cf85d892
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 30 09:54:39 2006 -0600
+
+ Renamed pdfanim.sty to pdfanim_temp.sty pending 0.53 release of official pdfanim version.
+
+ Delete temporary image and multipage PDF files used for animations.
+
+commit 12f49ce5083e96e35689cc79586b760be46003b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 29 14:36:09 2006 -0600
+
+ Added Rotate(pair), fixed alignment positioning transformation.
+
+commit 97ce9f2b9fa5bc72ec0ba3e68adb036f88d355de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 29 14:04:47 2006 -0600
+
+ Changed pdfanim version to 0.52A.
+
+commit 3c187c1c591152b6416a8646513c1251e61cf454
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 29 13:00:23 2006 -0600
+
+ Split slidedemo.asy into slidedemo.asy and slidemovie.asy.
+ Minor diagnostic and documentation tweaks.
+
+commit bb418bf9a852bbf921008ecc37e365a430d97206
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 29 12:22:35 2006 -0600
+
+ Move settings.tex="pdflatex" earlier.
+
+commit 298720bfde77c8498325f0f26063be936e039838
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 29 00:15:49 2006 -0600
+
+ Added embedded U3D example.
+
+commit d86d918fda1ce14fdbddcca9af50940b3ba2525e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 28 19:08:46 2006 -0600
+
+ Support portable high-quality embedded PDF movies via pdfanim module and
+ portable external movies of other formats via external module. Included
+ enhanced version 0.53 of pdfanim.sty package, with updated documentation.
+
+ Abort pfdlatex runs with fatal errors and display error.
+
+ Add optional bounds arguments to verbatim postscript and tex commands.
+
+ Document how to produce Debian binaries from RPM binaries.
+
+ Fixed rescaling bug.
+
+ Allow writing to local directory only; added -global option to override.
+
+commit 9c4660b474c5449f69b76cd33ddfec1987469986
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Nov 26 22:50:21 2006 -0600
+
+ Free some of the cached data in the abstract syntax tree.
+
+commit 0f42d93dbc82bf23f6dec8adc37f7c9e8cad9184
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Nov 25 16:32:18 2006 -0600
+
+ Added collapseScope, so empty scopes won't pile up in runnable-at-a-time mode.
+
+commit 58ce427f069a2da3eda7d104e7197c02c632b14c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 17 17:12:36 2006 -0600
+
+ Turn off scrolling during debugging.
+
+ Fixed typo in debugging help.
+
+commit 03c6c6068fb90f61624a088a642e484dc0b627b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 17 01:22:16 2006 -0600
+
+ Added routine to return an arbitrary point inside a cyclic path g.
+
+commit 43c9f351fe406736b2dc2a275ba0283515dc1879
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 17 01:20:18 2006 -0600
+
+ Guard against duplicate nodes in inside().
+
+ Speed up inside() by testing for points outside of bounding box.
+
+commit 9a327866d951c4b3f6248280a8119c1d222a8034
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 16 23:24:45 2006 -0600
+
+ Fix numerical precision problem in windingnumber routine.
+
+commit 577f48d25e9fea4dfb08ba83090d27c753e9af5b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Nov 16 22:14:42 2006 -0600
+
+ Reformatted long lines in the code.
+
+commit 9a861bce4f1182b5edb00f6b02ae8423cb691b77
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Nov 16 22:03:17 2006 -0600
+
+ More string constant formatting.
+
+commit fcd109e8c508fb3712e9aa1c3db1e367751466de
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Nov 16 21:56:40 2006 -0600
+
+ Split string constant to fit on line. (minor)
+
+commit 05beb5f4b1648263f022cbdeed9ccf0d5ea690c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 15 18:57:34 2006 -0600
+
+ Added string(real x) function.
+
+ Removed unneeded public qualifiers from documentation.
+
+commit 25b8efc835806e797cf729f6717660d0eceef63c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 15 18:49:19 2006 -0600
+
+ Changed == to standard bash = syntax.
+
+commit 99174e500e9367159d46911880e6da68aea1f4ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 14 23:27:47 2006 -0600
+
+ Make winding number of a cyclic path relative to a point visible to users.
+
+commit 191093341f48d051baa6b887efa08857594c2049
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 14 15:40:00 2006 -0600
+
+ Added example of cropping to axis limits.
+
+commit e778954d5ea29b8874d5b9ac044fd45cf960bfc6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 14 15:37:16 2006 -0600
+
+ Minor updates.
+
+commit 0a71ee69bef119a3aadfe109cc6c8a1d2eb926cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 13 23:13:33 2006 -0600
+
+ Fixed recently introduced bugs with -o option.
+
+commit c87a8031cce6434635653de174e7f959935dec30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 13 20:52:15 2006 -0600
+
+ Updated examples.
+
+commit ee574752f72c6fb17f744fbb2ac2edc47c8af7cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 13 20:43:46 2006 -0600
+
+ Replace unitsize, xunitsize, and yunitsize arguments of shipout
+ with a independent call to
+ void unitsize(picture pic=currentpicture, real x, real y=x);
+
+commit 340f011002f0a7f4e0e047cfecb490702b64db4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 13 09:55:17 2006 -0600
+
+ Remove unused line.
+
+commit bfd594bbf7d80571c8424ad7c2e1267bc339b460
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 13 09:50:58 2006 -0600
+
+ Minor adjustment.
+
+commit 728ecea8357736c47a6be76c1c650a9c8dd71c81
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 13 09:46:54 2006 -0600
+
+ Make clipping set truesize coordinate to 0; updated CDlabel to illustrate
+ this fix.
+
+commit d851b730623e8c9609470b9e1b93cc4a21ba315c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 13 09:26:24 2006 -0600
+
+ Added umlauts again.
+
+commit 151849131a0265f5bcfcb3b1020815fda5ef5589
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 12 10:45:34 2006 -0600
+
+ Minor updates.
+
+commit b23fd6682b0e0cf7552d28f9a5ac963b82d988c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 11 23:03:27 2006 -0600
+
+ Automatically set the movie bounding box to the largest bounding box of all
+ pictures.
+
+ Support unitsize, xunitsize, and yunitsize in animations.
+
+commit 86e70cd693dca95e361478a3af2e24f77f19a1d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 9 16:00:00 2006 -0600
+
+ Update documentation.
+
+commit 8c31c2fe98deb2a907d4e00578325db7ea99ca95
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 9 15:59:31 2006 -0600
+
+ Fixed segmentation fault.
+
+ Add default argument to tensorshade signature.
+
+commit 637ed2e58e15704b3d18c5061836405b7c0f2b7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 8 23:10:20 2006 -0600
+
+ Make seconds() portable (e.g. under CYGWIN).
+
+commit 40de37c31ba1bcdce09a59c24a699277cbf1eb1b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 7 16:51:09 2006 -0600
+
+ Minor updates.
+
+commit 63259c12dda630e7f03f52e7a4799686245e5765
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 7 16:27:16 2006 -0600
+
+ Overload postRun in iprompt.
+
+commit d2e5f03234fae526e4f972b968b200ab536eefac
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Nov 7 11:48:58 2006 -0600
+
+ Changed a code example to use a variable inside the loop.
+
+commit fd27e593c4e00143e9ce10b986e9c339ff727998
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 7 00:13:11 2006 -0600
+
+ Implemented tensor and Coons shading.
+
+commit 9b5229cfe22e5deada90a0f3529a4e260e456229
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 5 03:26:36 2006 -0600
+
+ Incremented version to 1.19svn.
+
+commit d2680ea19de263f890f1ae59c742f80b48183197
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 5 01:24:17 2006 -0600
+
+ Added example showing interaction of fixed-sized and scaled coordinates.
+
+commit 78b54400036a821a936a6554585c98785f9d06f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 5 00:39:41 2006 -0600
+
+ Updated FAQ to include discussion of static variable allocation.
+
+commit 3838b48d09666a9cd61f3d51c517d3231d65fa2d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 4 23:38:10 2006 -0600
+
+ Make labelx, labely, xtick, and ytick respect graph (e.g. logarithmic) scaling.
+
+commit 520a1993a10d6d737022a452ec7f4c566b92fe10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 4 18:46:14 2006 -0600
+
+ Updated FAQ and documentation.
+
+commit 5565a9fca26af7fc9b6c1106e43181a64bcdb454
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 4 12:49:12 2006 -0600
+
+ Treat single reads just like array reads: in line mode, move position past any final eol.
+
+commit 26bfa9df7c61d8d2d9540322ed01d6fd65fd30a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 4 02:09:14 2006 -0600
+
+ Make bool pdf() and bool latex() visible at asy level.
+
+ Add string nativeformat().
+
+ Update asycolors to remove pstricks dependency.
+
+ Make slide package work with both latex and pdflatex; remove colordvi
+ dependency.
+
+ Check for latex mode in usepackage and minilatex.
+
+commit d5017510aea05674eb765398f28fb8383bacf077
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 23:25:12 2006 -0600
+
+ Fixed clipping (UnFill) problem by avoiding LaTeX \put.
+
+commit fef3da8755ee1763e41fb4fe766bcfbbacfb0a6e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 22:55:27 2006 -0600
+
+ Fixed pen caching problem.
+
+commit 4c522975795e85f99af44f46dc33f651ce3b426c
+Author: Chris Savage <chris@savage.name>
+Date: Fri Nov 3 17:14:45 2006 -0600
+
+ Updated palette documentation.
+
+commit 1dc32fd58eb9f250e9dc463f74e680425685fbb8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 09:51:19 2006 -0600
+
+ Cache a separate copy of pen for tex mode.
+
+commit 93b89ea4b2ac84828116cc56a4b2326a82bff2be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 01:59:03 2006 -0600
+
+ Fix max(empty array) error message.
+
+ Implement minbound and maxbound also for arrays of pairs and triples.
+
+commit 7210c8cbc06185017b72936fa3ad5bddf0674114
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 01:54:56 2006 -0600
+
+ Check for an existing viewer associated with the given outname.
+
+commit ae0d6a38b6235e3d12fe8bd22e2a34676851badf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 3 01:14:25 2006 -0600
+
+ Call cleanup, not exitFunction in interactive postRun. Don't tamper with
+ interactive flag: if exitFunction fails, interactive will not get reset and
+ cleanup will not get called at all.
+
+commit b40b33ad1de071e35559f1581383bb09878566fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 2 20:32:30 2006 -0600
+
+ Use bin centers for point array.
+
+commit 0f4f5380e1990b0af1dce9b43d63786e80a4177d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 2 11:43:32 2006 -0600
+
+ Added image histogram and contour example.
+
+commit da264a977c66ffa098e8dd654cf52724ac8b49ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 2 11:08:39 2006 -0600
+
+ Fixed drawing of mesh only.
+
+commit 7e68cc36102092161c1466d988c3991025d4c7d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 2 11:03:21 2006 -0600
+
+ Check for division by zero in scale.
+
+commit 8732a8a108ecab5246bbefc18164ba9d77e39dd2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 31 02:31:16 2006 -0600
+
+ Incremented version to 1.18svn.
+
+commit 546eb10956ca560a2342071cf9e02e86e65cb32a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 31 01:18:54 2006 -0600
+
+ Work around garbage collection bus error on MacOS X.
+
+ Call GC_Init during static initialization.
+
+commit 0e39bad178b3d4241d00d5ea2d71ca76f53b3d72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 30 13:22:37 2006 -0600
+
+ Added a uniform histogram routine.
+
+commit c8ec46631eb319c5f3968c94672f85ff39ab42c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 30 12:41:38 2006 -0600
+
+ Reverse order of arguments of nonuniform frequency routines for consistency
+ with other uniform frequency routines and image and graph routines.
+ This change is backwards incompatible.
+
+commit 1f9e001b45b26919731bba7e3669b7360dbf5de6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 28 19:37:26 2006 -0600
+
+ Reduce number of mem::string/std::string conversions.
+
+commit 4dedf096d6c403fd4b8e64bef059a4fa8c6907ae
+Author: Chris Savage <chris@savage.name>
+Date: Fri Oct 27 14:38:42 2006 -0600
+
+ Added 1d/2d frequency routines optimized for regular bin sizes.
+
+commit 4d258b71d8cc27a5a144a1d7cd587757f157a9c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 27 14:13:39 2006 -0600
+
+ Updated FAQ.
+
+commit d261c7748eb5a5d30fca3427f71ba6868ad8d82b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 26 22:27:54 2006 -0600
+
+ Improve optimization of 2d frequency routine.
+
+commit a315decc03c56ab1d40d2cbb7673980a91c3a918
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 26 22:13:46 2006 -0600
+
+ Declare fixed-sized arrays.
+
+commit c5ee060643af0e74301b06ba71f13554f8c68696
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 26 22:07:18 2006 -0600
+
+ Optimized 2d frequency routine.
+
+commit 01b0e16a50c45d973102d0a11dfc50ac024ec2d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 25 01:41:55 2006 -0600
+
+ Incremented version to 1.17svn.
+
+commit f956a35f74398fa0cd234bae657ac7adc92e75f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 25 00:26:11 2006 -0600
+
+ Removed page break.
+
+commit 358ec2ccaa552bfc4b81bfaefbd015fcad889139
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 24 23:50:16 2006 -0600
+
+ Use pic.scaling in graph.asy.
+
+commit 8cd5d1299e29c188a71c373056ddd1d458c7f837
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 24 23:43:12 2006 -0600
+
+ Move using std::string out of header file; pass references to strings.
+
+commit 382463c6c5de19741ac199085d96663020cc92b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 24 23:34:58 2006 -0600
+
+ Fixed memory leak.
+
+commit 3cd61be2f81b5c71ae39ef9e4f2df6fe8975ce29
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 24 21:50:49 2006 -0600
+
+ Updated credits.
+
+commit 202b9564ec5af67e301c2ac847e0cd656d511b3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 24 21:50:33 2006 -0600
+
+ Added 2d version of frequency binning routine.
+
+commit d18d193d55d3141e606378bce7a1e6308f9efb58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 24 11:28:01 2006 -0600
+
+ Added modified version of Mark Henning's multi-line legend routine.
+
+ Added legend example.
+
+ Renamed truepoint to framepoint; added truepoint function which works like
+ point but accounts for fixed-sized objects.
+
+ picture.calculateTransform now returns the actual transform used for
+ fitting in the case where only an approximate picture size was available.
+
+commit dd29994627aaa793bc99f5af386829077a581d07
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 23 12:31:55 2006 -0600
+
+ Changed ARCH to i386 since that is the only case that currently applies.
+
+commit 267e1456b08c492a1a3b95281e43a93461fe5a90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 23 12:30:33 2006 -0600
+
+ Fixed \usepackage[inline]{asymptote}.
+
+commit ba458755cab79370ecee05ae4b88c57ec0d13f66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 22 00:58:10 2006 -0600
+
+ Run latex 3 times on CAD.
+
+commit 23a246d3f41f6f8d90b4ad09c7c5ec1edc1de08a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 22 00:50:57 2006 -0600
+
+ Remove temporary CAD files.
+
+commit 0195e474c857a61ffbe9e31c247bacf085f77abd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 22 00:41:51 2006 -0600
+
+ Incremented version to 1.16svn.
+
+commit eb2267f0bde79c1643a9a497dcbc56399255c3c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 22:46:25 2006 -0600
+
+ Added Mark Henning's 2D CAD package (DIN 15).
+
+commit 86a9f3375abfc36e8c22d5a04afd1423254f2529
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 22:23:26 2006 -0600
+
+ Document restriction of annotations to tex and latex tex engines.
+
+commit e98c80f3bf13c68bc6961276ee095d36eed13c1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 22:20:13 2006 -0600
+
+ Make graphics labels work with tex and pdftex engines.
+
+commit e65635f731928541bf1644d4b14ca73abc9e1767
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 21:00:37 2006 -0600
+
+ Added CDlabel example to illustrate clipping of graphics.
+
+ Changed overfull slide error to warning.
+
+commit 0f1af03ee09bb4456504740171ef4c5a87af8cf7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 18:00:29 2006 -0600
+
+ Remove temporary pdf files.
+
+commit 385df746ac2083154dfcb7fd12690b7d7a0831b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 14:24:39 2006 -0600
+
+ Fixed cube animation.
+
+commit 41a628f6da76a87c739f60ddb86414d0c1bbb62e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 00:17:26 2006 -0600
+
+ Force unitlength=1pt in inline tex mode.
+
+commit a68585163e3c8e53b0b2134b5029180a094a5eb4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 21 00:00:53 2006 -0600
+
+ Added further determinant of singular matrix tests.
+
+commit 3c8ee5ecb928474319193fa3b55fdbb1a9d3a034
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 20 23:54:40 2006 -0600
+
+ Determinant of a singular matrix should return 0, not an error.
+
+commit 041322e8e38d3505b9b103b5659577b8a4256ca1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 19 23:56:09 2006 -0600
+
+ Use LaTeX color package for latex and pdflatex to keep latex informed of
+ current color.
+
+commit e78af7bae702d25262fc2b9156bed250e750d88e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 19 23:54:14 2006 -0600
+
+ Fixed label fuzz.
+
+commit d840b87cb8545bf129228c7281157cc84a14ca38
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 16 17:01:07 2006 -0600
+
+ Fixed incorrect path bounds in lattice shade.
+
+commit 2c376089985ff5965311e5e5faa7e826d94ba081
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 16 13:07:45 2006 -0600
+
+ Fixed typo.
+
+commit 2ffe53fe675079562255b7a0c36b9383c49771c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 16 07:52:33 2006 -0600
+
+ Another attempt at fixing compilation problem under MacOS X 10.3.9 (cf. 1.00-1).
+
+commit bd66d25af0ec692695d71970e6f59e01b05ee9f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 15 19:40:33 2006 -0600
+
+ Fixed compilation problem under MacOS X 10.3.9.
+
+ Rename configuation variable latex to texpath in documentation.
+
+commit 84f6f43b5f6e106c5c8feed712828f2acd74ab50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 15 17:00:58 2006 -0600
+
+ In cases like 2D graphs where only an approximate picture size estimate is
+ available, adjust the transform so that the fitted frame meets the
+ size specification. The pic.scale() routine (which scales the resulting
+ frame, including fonts and true size objects) can enforce even better
+ compliance in such cases, but should not normally be required.
+
+commit 3b07181bd01679b319489beb9f0881ab62ab4e5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 23:16:14 2006 -0600
+
+ Minor clarification.
+
+commit 6aafdea6991f4210b613af985ea3e71ceb239dca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 22:42:12 2006 -0600
+
+ Remove gv patches since these are all in the long-awaited gv-3.6.2 release.
+
+commit 78885a7129643cfa720be9c0e54fe84767164cbc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 22:21:17 2006 -0600
+
+ Incremented version to 1.15svn.
+
+commit 23589c9ace9c2563f12d5f17d2e5dd57a22649ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 19:50:30 2006 -0600
+
+ Adjusted example.
+
+commit d7c69078664b14734ea03564f5b7246918525754
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 19:23:21 2006 -0600
+
+ Updated FAQ.
+
+commit a5cc66d15032057a4201c26f2bebc957ff77ddce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 19:11:41 2006 -0600
+
+ Documented filloutside.
+
+commit d3465aa847b9e5fd750c39159ecd272e71130815
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 18:50:37 2006 -0600
+
+ Fixed cxx warnings.
+
+commit 638a43729ff7bb383be7806103ae1d92b94ca6d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 16:45:23 2006 -0600
+
+ Added missing space.
+
+commit e2d6e51171031947eea40fab2bdbdacecaa01abb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 16:40:18 2006 -0600
+
+ Support color fonts for pdftex and pdflatex.
+
+commit f544e103151c1d5ed9d06f46768b51fb1930a60b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 16:21:59 2006 -0600
+
+ Implement ability to draw images directly from a two-dimensional pen array.
+
+commit 9be13bc0a5f9e252a5359c4c3533f0f505a6c353
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 15:26:59 2006 -0600
+
+ Fixed label alignment transformation; implemented general scaleless routine.
+
+commit 216de7b26d13b939c878a66ddb5d0aabb788fd62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 14 02:03:40 2006 -0600
+
+ Fix readline test.
+
+commit fec76d69c87f40e1661c33824fbc0a67def44ea7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 13 23:03:41 2006 -0600
+
+ Fix test for readline 4.2.
+
+commit 7ac24a54e969bdf31643f6fa4a6776e0afa5cb8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 13 22:32:56 2006 -0600
+
+ Disable support for readline versions < 4.2.
+
+commit 80af472754be7d427e51b62973788afd8de69bf5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 13 16:50:51 2006 -0600
+
+ Scale label fuzz to height+depth not width.
+
+commit 1db6b1f47b1bbcc07b40eb08a51b51774753ecff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 12 18:01:22 2006 -0600
+
+ Define pdfoutput if necessary for older versions of latex.
+
+commit b037d295c1f679af879ce10f6be9d67cfa46e8e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 12 17:30:14 2006 -0600
+
+ Implement tex and pdftex TeX engines.
+
+commit 6fa776eb64ca27b159017315844647f3ad9da44c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 12 00:05:50 2006 -0600
+
+ Implemented more robust label fuzz calculation.
+
+commit 4f25e3051841654925b6a34ff1be0b848388bded
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 11 21:48:25 2006 -0600
+
+ Crop generated pdf files.
+
+ Fixed pdf label transforms.
+
+commit e2206d1c9d63a5645d7fa6f0326f7f4c8b890c21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 11 16:41:37 2006 -0600
+
+ Handle files with and without labels consistently under -tex=pdflatex.
+
+commit f7c4e4469d334240cd096492f0656ae4a6818972
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 11 08:43:27 2006 -0600
+
+ Added support for Emacs 21 (quickly tested with 21.4.1 only).
+
+commit 3201b9e05aa425408230fb4dad2ca670e5523b29
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 11 01:25:14 2006 -0600
+
+ Added support for alternate texengines (currently "latex", "pdflatex", "none").
+
+ Support \usepackage[inline]{asymptote} under both latex and pdflatex.
+
+ Clean up singleton path eps writes.
+
+commit 667c624a70cd45de64b3f9aad94f2278464e783f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 8 15:16:08 2006 -0600
+
+ Revert revisions 1.14-54 to 1.14-56
+
+commit 99d7cc9fd7754fd52b81796555b7e23ce5bf5d7f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 7 14:00:36 2006 -0600
+
+ Implemented general label clipping; removed evenoddoverlap and
+ zerowindingoverlap fill rules as this functionality can be achieved at a higher
+ level, using inside(path, pair, pen).
+
+ Changed bool scale argument of Label structure to Shift, Rotate, Slant, or
+ Scale, which indicates how the Label transforms with the embedding picture.
+
+commit 83fd3c1466b160e77dc917f9c4279293714ac2aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 6 04:39:26 2006 -0600
+
+ Reset x and y boundRoutines after processing.
+
+commit 2ea881bdd70f223918b196a2eea0229109914818
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 4 09:45:16 2006 -0600
+
+ Remove obsolete item.
+
+commit 591a6809b451364ae03a993f027037e038b2c77a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 3 22:15:25 2006 -0600
+
+ Remove further unneeded instantiations (as of last revision).
+
+commit 0c4e6e5cedb64d50e77fe622291688a72f2ce367
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Oct 3 18:53:50 2006 -0600
+
+ addOps now add operators as fields (so they can be imported).
+
+commit 555d40cc7189645f7c813285feef0a499ae100ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 3 17:47:39 2006 -0600
+
+ Allow use of UnFill in tick labels.
+
+commit 2fe33bde49a3094109de6b371c094445c1be49a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 3 17:30:14 2006 -0600
+
+ Simplify general axis routine.
+
+commit 510a57c843886458e69b79ab92fe2b23a1976ff4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 3 17:22:31 2006 -0600
+
+ Simplify call to ticks.
+
+commit c9ff5103304cffbd38307aad0e3f2aa9916e3e6b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 2 22:03:40 2006 -0600
+
+ Move Label shift member into transform member.
+
+commit 603fae58ba2d8f2a497c32e246d609492c41a077
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 1 18:12:11 2006 -0600
+
+ Implement general label transforms, including slant.
+
+ Added option to Label to allow labels to scale and slant with pictures and
+ frames.
+
+commit 91640a6cc5e16990bcef8b86ad2f3c06f050ef09
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 30 14:26:05 2006 -0600
+
+ Fixed "Cannot write to venn_.tex" error under Windows XP.
+
+commit fe6f54c378560c8d56721722195c3664e7ede25c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 30 10:56:10 2006 -0600
+
+ Fixed cxx errors and warnings.
+
+commit 025f86561c9729aae69bc805aef03e5c58dbabd9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 27 15:58:38 2006 -0600
+
+ Fixed transformation of label alignments.
+
+commit 67c45c5d79fa438a231d5f48d7c5cfa50a169d2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 27 00:22:53 2006 -0600
+
+ Make scale set automin and automax settings in autoscaleT.
+
+commit a03c2af28e987a3ebbcb07ca7ab7ec92d671c0a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 26 23:41:09 2006 -0600
+
+ Added boundRoutine[] bound to autoscaleT.
+
+commit 870716863c07e9fc93a7ea4ae38d1050c7103710
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 26 23:39:37 2006 -0600
+
+ Improved graph routines: added xaxis and yaxis bounds communication,
+ allow axes with ticks and unextended axes to be called on an empty picture.
+
+commit 55486b03449dc43e3f2e2f671372d7bcbe5b4c47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 26 22:18:06 2006 -0600
+
+ Simplified example.
+
+commit 3f84eb0e5329df55eedcd7816d246269b1acf9e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 25 06:03:16 2006 -0600
+
+ Allow for separate xunitsize and yunitsize scalings.
+
+commit d25faa5325ac7dd2edd8698a23cb0ac612882a0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 24 11:26:11 2006 -0600
+
+ Improved documentation of tick extend option.
+
+commit 0d8745187ea6224e507d01132176fc30c9e71adc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 24 09:40:22 2006 -0600
+
+ Removed axislabelmargin.
+
+commit 351e794c6bc6824c199bc368aff48edf7ac23205
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 24 00:59:08 2006 -0600
+
+ The axislabelmargin setting should only affect alignment perpendicular to
+ the axis.
+
+commit 8672a218c4874b5aaba6381dcc7e123b23ee67ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 24 00:38:54 2006 -0600
+
+ Adjust axis labels only in direction perpendicular to axis.
+
+commit 6858464ed091391a79112e8385177d0d24a6834d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 23 22:32:04 2006 -0600
+
+ Draw path label after drawing path.
+
+commit d48c0122032cc8591b9c3128f6e6cb117cd6920a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 21 12:28:57 2006 -0600
+
+ Allow Label(Label,pair).
+
+commit 55e07408be0540b1fd41119ed03fb92d2b840646
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 21 12:27:30 2006 -0600
+
+ Add partial support for xemacs.
+
+commit 833db88dba8d3477533ee8d1a510da2fd58a417a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 21 01:21:34 2006 -0600
+
+ Leave vertical mode before put.
+
+commit f1de4247df589333842495b8c675841a1e05c252
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 21 00:12:10 2006 -0600
+
+ Fixed grammatical error.
+
+commit 5c39ba9bcd34ab46ba9e62d113e9c7efbb1a11c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 21 00:08:42 2006 -0600
+
+ Added Mexican Hat (wavelet) example that nicely illustrates the distinction
+ between guides and paths.
+
+commit 627742e5a1accd9977fbef43253dd5f4aef3a0f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 20 08:50:13 2006 -0600
+
+ Removed dependency on rotate.tex.
+
+commit 59862d5927db13955c04ff0202acbc5174eaddb6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 19 23:08:34 2006 -0600
+
+ Removed dependence on pstricks.
+
+commit 4eca0a5c56aaac730963e3e49adb8dbe09c14434
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 19 22:12:31 2006 -0600
+
+ Added filloutside routines.
+
+commit f3d3e51caf55dcc5cd95699b486351eaf660793a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 18 16:00:15 2006 -0600
+
+ Ignore setlocale errors; improved discussion of setlocale in FAQ.
+
+commit 19f4c2d00b8b172fe6821cd9764eb7dea5e9c2d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 17 22:32:31 2006 -0600
+
+ Fix -aZ -f pdf.
+
+commit 76c3b469886016170897af7b9ca21f3e7bcc1918
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 17 22:18:06 2006 -0600
+
+ Standardized filltype definitions and added a Draw filltype (e.g. for drawing a
+ bounding box around a label).
+
+commit 3756452ae55dd4c74dec0832efb762b04501bebc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 22:18:03 2006 -0600
+
+ Fixed typos in comments.
+
+commit 979e5245c77168ad68b2105c07203099c1985fdf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 21:50:16 2006 -0600
+
+ Make -p option only effective in noninteractive mode.
+
+commit 6353224e8bc253e83b284cc9bdfc776997217d68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 15:39:41 2006 -0600
+
+ Accept ? as alternative to h (help).
+
+commit 2d3be54182cabece33b4fd21f18f6d67b688e19d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 15:38:37 2006 -0600
+
+ Quit (q) should turn off off debugging mode.
+
+commit e67a8fad923d927a19b8a5f725bc7234f04227ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 15:11:09 2006 -0600
+
+ Minor simplifications.
+
+commit c819d159f46d10b3446299d1bbdcc328bab67e83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 15:05:59 2006 -0600
+
+ Added irregular mesh image contour routines.
+
+ Fixed documentation regarding explicits image bounds.
+
+commit 2dc1f5f285691a0fb77438f3d0acefa96528fe27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 15:02:46 2006 -0600
+
+ Fixed numerical precision issues; minor optimizations.
+
+commit a717ad3169a34b96fed0e04b9ed103ff236ac0a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 12:18:45 2006 -0600
+
+ Minor optimization.
+
+commit a291fe8cbab32f8fb81f5af0a9ec833245b4d734
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 01:32:59 2006 -0600
+
+ Fixed docref.
+
+commit 31d0253ac49f2a57def70ff23c6a6b6037acc22e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 16 00:44:13 2006 -0600
+
+ Updated FAQ.
+
+ Improved Makefile.
+
+commit 940671ec82f0375f5d77828da85298699b756138
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 15 21:55:17 2006 -0600
+
+ Added contour wrapper for explicit x and y arrays.
+
+ Standardized contour argument names.
+
+commit 255e2305868febb31a1a9123008e451a88749db1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 13 20:56:26 2006 -0600
+
+ Fixed unhandled exception on startup.
+
+commit 348aff80582497d1629b73e8be47d7f2b6a7bcbc
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Sep 13 19:40:19 2006 -0600
+
+ Ignore keyboard interrupts during readline.
+
+commit 609e7ce533c3c383d43870a451a470e5222ee8e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 13 00:25:47 2006 -0600
+
+ Modified example.
+
+commit 95d6e55978fc10e863c93cce89292fb43ee84803
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 13 00:24:37 2006 -0600
+
+ Generalized axis alignment example.
+
+commit c076e75873eeeb081a32c068c4044db9dc9f3185
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 12 23:45:10 2006 -0600
+
+ Fixed axisMin.
+
+commit 711cbebdf9ffde7a3ab55fcc4631f0a684d21566
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 12 23:36:12 2006 -0600
+
+ Calculate, don't cache, axis userMin and userMax values.
+
+commit 48ac703bc5891cbea3f7645646cf6532a6441b62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 12 01:02:42 2006 -0600
+
+ Add PDF autorotate option; landscape slides now automatically turn this on.
+
+commit 4ba23a29c1915434076022e312479f5b2edf0f22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 11 22:24:22 2006 -0600
+
+ Added example of buildcycle.
+
+commit 27e2b021dc0609a58a6bfe4f15498977d665e258
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 11 22:20:23 2006 -0600
+
+ Port and document MetaPost buildcycle.
+
+ Document new behaviour of asy -l file...
+
+commit f6627a1a9f7d66f92eebdd8990ce2ed03d98b6d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 11 21:45:35 2006 -0600
+
+ Allow draw(nullpath) again.
+
+commit 19fbdfb19a5222e947593a5af55727b14bd8d1cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 10 13:33:24 2006 -0600
+
+ Fixed asy path and base directory.
+
+commit b8b3928f0b73660c2d7adcf7afcc4ddae3b7fa85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 9 21:55:55 2006 -0600
+
+ Added type highlighting list to asy-keywords.el and asy-mode.el.
+
+ Simplified building of asy-keywords.el.
+
+commit 034bcce15f75b967c32f10ff5227607818d5c039
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 9 12:26:29 2006 -0600
+
+ Refactored interactive prompt. Moved asy code processing from main.cc to
+ process.cc.
+
+commit 7f69344edb1918434afc53d5906348bc5f15ae2d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 8 12:40:18 2006 -0600
+
+ Fixed infinite loop on stdin EOF during scrolling.
+
+commit af30d135fb36c4f5c4a59808b63d76abd1a44f30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 7 21:59:28 2006 -0600
+
+ Make last workaround CYGWIN specific.
+
+commit 455b64c796b9972676e3e13fc03d2fcb2964e3f8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 7 07:56:04 2006 -0600
+
+ Work around missing ncurses/term.h symbolic link under CYGWIN.
+
+commit 900e00356b7814d4deddfa05ce2c9ab828cfb1c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 6 02:52:45 2006 -0600
+
+ Incremented version to 1.14svn.
+
+commit 22aa04ae69177659ab25e16dd859775909ebc643
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 5 22:47:22 2006 -0600
+
+ Added path qualifier.
+
+commit eff0b45d96d765f9bc81196953aa106b2f7445f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 5 21:17:34 2006 -0600
+
+ Standardized indentation of and untabify base files.
+
+commit 87a45971cbed4ae9debe673c81d282bb4e606a5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 5 10:24:50 2006 -0600
+
+ Updated documentation and FAQ.
+
+commit de7e13243c0599e4d2bf68faf2896e1f30ed6128
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 5 10:24:30 2006 -0600
+
+ Added html target for building html documentation from main directory.
+
+commit 65d163362a2fac264575e6b5159fef0419ae2482
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 5 00:24:39 2006 -0600
+
+ FAQ updates
+
+commit 17505d564a43e316c7db22b98d8de5466d25e2d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 23:13:53 2006 -0600
+
+ Explicitly load asy-mode.el in case an old compiled version exists.
+
+commit 9b4cc01e29cbaf9a4d83ceb9a2f8ccaceea31c02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 23:04:52 2006 -0600
+
+ Color name updates.
+
+commit 52c3d60b3d4e1f03d90ca5596c2f953134de28ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 22:29:45 2006 -0600
+
+ Project triple to align in call to label and Label.
+
+ Cast triple to position.
+
+commit a264f9641e882d8ee2ccfad8b671cd3fd30168b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 22:18:35 2006 -0600
+
+ Remove cast from triple to align.
+
+commit 7449971fee8995d1d79ce4d27af234385dffd53f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 22:12:03 2006 -0600
+
+ Make grep case-sensitive.
+
+commit 6f5bf62ecaba03d7fe486758c2362b5f45bbe38a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 01:40:35 2006 -0600
+
+ More FAQ updates.
+
+commit c9d4473fed4c535c26a7180eb2e62c17a4cbe1eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 01:36:16 2006 -0600
+
+ Updated FAQ.
+
+commit f68a35d2db180e3075316488aa782d88def7738c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 01:30:35 2006 -0600
+
+ Allow arrowhead to be called with a position type.
+
+commit c98c79d93af423d11026df9f646cf2162286b635
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 4 01:29:06 2006 -0600
+
+ Use pTick as default for ptick.
+
+commit ad45fdc38f515e56a61419cf508240e8926fdec9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 3 12:05:53 2006 -0600
+
+ Revert last change.
+
+commit adfe519f86f0c3663a65d066b93e54868ef97c19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 3 11:49:35 2006 -0600
+
+ Close fout immediately to avoid race condition with gv in interactive mode.
+
+commit fbb3d9ce12d3860ce18a50ac41c0a7a20c4daf16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 3 09:05:31 2006 -0600
+
+ Install asy-faq.info with make install-all.
+
+commit 297fb1620c281160d3c85a59dfbf3599ae822a46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 3 00:01:55 2006 -0600
+
+ Fixed cxx warning message.
+
+commit 0bfa85f15495c3fe8dedd656e168863f22180f3b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 2 23:45:44 2006 -0600
+
+ Removed ASYMPTOTE_DIR.
+
+commit 3f78d4518f580e535f06fd22d57b61494087fc5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 2 23:42:37 2006 -0600
+
+ Simplified Makefile.
+
+commit baeb51d7b703d1f754b75c2257f7039425fad588
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 2 23:35:46 2006 -0600
+
+ Distribute keywords.cc.
+
+commit 67fbb198d48c333c138909ff53211389d2ac3a42
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 2 23:29:35 2006 -0600
+
+ Make keywords.pl executable.
+
+commit 794538cc5900417ed36eddb1cd6a98a8552b8f5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 2 23:20:58 2006 -0600
+
+ Added Frequently Asked Questions (FAQ).
+
+commit 26f56cf05c6cea469da431248728ba726f347892
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 2 11:28:41 2006 -0600
+
+ Respect scroll setting only in interactive mode.
+
+commit c2b071c9fd91e2e54db1960fced5e9d7ae2029c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 2 11:21:14 2006 -0600
+
+ Add Philippe's changes to asy-mode.el, including menu and asy-insinuate-latex.
+
+ Handle shells other than bash in asy-mode.el.
+
+ Autogenerate asy-keywords.el.
+
+commit 1f96b552a2af9bc8f17700d1fca4e7fb7a7223a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 30 21:53:25 2006 -0600
+
+ Make annotations with frame transformation; cleaned up @defspecial code.
+
+ Check for successful PostScript writes.
+
+ Standardize "Can't" vs. "Cannot".
+
+commit e3ff8da6ad620ed763f68efd31c6cb550100649e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 30 21:48:31 2006 -0600
+
+ Simplified calculateTransform logic.
+
+commit ab8f9f3e55b9ac3218ae8bdbd0cdae87eae9283c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 30 21:46:56 2006 -0600
+
+ Improved example.
+
+commit a8a5186f6b75b1c9ba2baac9a1440744573463d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 30 21:44:46 2006 -0600
+
+ Disable magic () parenthesis.
+
+commit b82912094da7642a9ba64a51ee59d4d1b74eb150
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 30 16:35:02 2006 -0600
+
+ Prevent exponential notation in %%BoudingBox.
+
+commit 8873a0444096d60eec93aed956ff0eae1b94a7a0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Aug 30 13:11:11 2006 -0600
+
+ Test using a local version of asy.
+
+commit 587b1fe3d99f40525c5759823c2cc1dd5ed85121
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Aug 30 13:10:08 2006 -0600
+
+ Don't run "../asy output/*.asy" as this doesn't test the files properly.
+
+commit 0f9e63abbd46730ae29aafeb4ded2b205d222a24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 29 21:04:38 2006 -0600
+
+ Updated to use gc6.8.
+
+commit 993d2ec493e607efed0de08be6ed3823f362d80a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 29 15:47:24 2006 -0600
+
+ Reduce size of generated files.
+
+commit 2fb33cd414d9db9b472303954547aefe7c23bc8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 29 11:30:15 2006 -0600
+
+ More three-dimensional examples.
+
+commit 2e296a0cd8bee8936fdd995078fef50b2e5489d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 29 11:29:33 2006 -0600
+
+ Fixed definition and documentation of cone.
+
+ Added longitudinal pen to draw.
+
+commit c1b1f17f483abf63e58c9efaf3202062185d22cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 29 11:28:51 2006 -0600
+
+ Added cast from triple to align.
+
+commit 32a32c6b551379c64d93d1362f76c03519600e43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 28 22:35:39 2006 -0600
+
+ Added up argument to projection routines to specify camera orientation.
+
+commit 40b2e7eecec7ffb6cdd384f25dceaf15a7887350
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 27 20:58:32 2006 -0600
+
+ Minor optimization and documentation updates.
+
+commit 5caeb44bbe159e5b0474691923a4c1680cedeb37
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 27 18:53:20 2006 -0600
+
+ Cleaned up surface functions.
+
+commit c85824f701ac8682dbdee0fe0d24285625882a17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 27 18:42:43 2006 -0600
+
+ Avoid warning message under -d.
+
+commit 312f05fb764fa64334f90a1160aae5fdfbe4a8ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 27 14:08:51 2006 -0600
+
+ Moved documentation to beginning of file again.
+
+commit 5768a90fbe38fa2d72c0343ee49474d2ce712bc3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 27 13:44:12 2006 -0600
+
+ Disabled magic [] since this makes typing real[] awkward.
+
+commit 794ca7d4658dfc8d479b64abe73625edd9fcec7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 18:29:31 2006 -0600
+
+ Removed obsolete comment.
+
+commit aebc30038fe13e7e19186f8719dbff5af2eccb1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 15:44:33 2006 -0600
+
+ Don't indent after struct definition without optional ;
+
+commit 8f044468d9ddb1a07c41dc8f1742fa6b4c756260
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 12:06:44 2006 -0600
+
+ Disable magic {} as this makes grouping existing blocks of code (without
+ going to the trouble of selecting a region) inconvenient.
+
+commit 670b6dbe300a6899cb1d71abe669805b627156f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 12:01:32 2006 -0600
+
+ Fixed indentation of public/private permission modifiers.
+
+commit 0b90018f10f19db2a61c316146b05f187618b29f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 11:59:21 2006 -0600
+
+ Fixed indentation.
+
+commit 71b5a6d5c8f70a04c49bcfbec1ecaea740cd906a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 26 01:07:35 2006 -0600
+
+ Mention two-mode-mode recommended package also in online documentation.
+
+commit 00738d2135db51a0e4b2066473620d633d5db0b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 25 22:41:48 2006 -0600
+
+ Remove the strict requirement of the two-mode-mode package for minimal
+ functionality of asy-mode.el.
+
+commit af2ba24ede5a963d7cec28a301f71ee2560810c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 25 22:14:11 2006 -0600
+
+ Replaced asy-mode.el with slight improvement of Philippe Ivaldi's version.
+
+commit f662e32020195506b96d1a84ce2248323ff91dd9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 24 21:18:05 2006 -0600
+
+ Check path[] index.
+
+commit e0be7331a932a345d0330c0e331eb75f06fa7116
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 24 21:13:14 2006 -0600
+
+ Allow legends and markers when drawing superpaths.
+
+commit 6b81deefb1e8e0e1a888da8549a817ea9aa1fc50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 24 11:28:50 2006 -0600
+
+ Moved graph settings to separate module graph_settings.
+
+ Renamed nmesh to ngraph.
+
+commit e0c665a6c80a638cf987d01613b355eb7357df0e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 23 22:47:44 2006 -0600
+
+ Removed resolution arguments (nx and ny) from matrix contour routines;
+ instead calculate these from the matrix itself.
+
+commit 25db195ca85cdf10b81b0e658f11e28fe087329b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 22 09:00:55 2006 -0600
+
+ Simplify calculation of cyclic path bounding boxes.
+
+commit 2a727b5da017e16f669041fe33bce1cfa9b05995
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 21 22:30:45 2006 -0600
+
+ Check that root is in range in bounds().
+
+ Implemented general solution for pen padding/capping of paths.
+
+commit 1e3e71ddba40dd38a67f0d5a063f593928e29322
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 20 22:22:33 2006 -0600
+
+ Added link to externally contributed examples: http://home.tele2.fr/phivaldi/asymptote
+
+commit 1975cd1e4db32ab15af2e7cced813c9425d73aad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 20 21:56:22 2006 -0600
+
+ Account for pen cap contribution to bounding box.
+
+commit 0a78726e84976df4d77fd2669e3ed8c477503d28
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Aug 20 00:20:41 2006 -0600
+
+ Exclude module accesses (and imports) from listing.
+
+commit 2d33137292407d66f099001aeb6fe0a9c7bb7c0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 19 22:25:26 2006 -0600
+
+ Fixed image transposition.
+
+commit 620b0750d6a20baa7aa231ba7e3896cbaec37f5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 19 18:13:36 2006 -0600
+
+ Discard extra characters after scroll commands (q).
+ If scroll is negative, use one less than number of display lines.
+
+commit 331d19e858a08034c8b1f7182c8d8c0edb86dca7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 19 09:44:40 2006 -0600
+
+ Changed header.
+
+commit deeafec561e27c8f9c1cecf9651229670931bbad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 18 16:07:59 2006 -0600
+
+ Standardized image and contour conventions for matrices.
+
+commit 3ec15bc65ee01c347de9764251f7ed148c2d5c80
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 18 15:56:31 2006 -0600
+
+ Improved documentation of command-line arguments.
+
+commit 98ce04117d410dacd86caa0c155def36cbe0138d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 18 15:55:57 2006 -0600
+
+ Removed unneeded settings qualifiers.
+
+commit d637ff179718b8e833ecdfc56394e5c9ed8d1989
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 18 15:54:35 2006 -0600
+
+ Minor optimization.
+
+commit b7a92a3b4478fb944e11d1f59bc91585657df406
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 18 15:52:27 2006 -0600
+
+ Changed write without data arguments to work consistently with the forms
+ with data arguments:
+
+ write(suffix suffix=endl);
+ write(file fout, suffix suffix=none);
+
+commit 7bbab69b0cfed3ea636366a3ff30d406480dd6b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 18 14:46:47 2006 -0600
+
+ Remove spurious grestore; if no labels move grestore before showpage.
+
+commit 5f7cb91504b33716ac5e1c0cb64f3aecde55c2dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 17 14:29:46 2006 -0600
+
+ Move GCLIBS dependency before others.
+
+commit 946e289a36611ab5833be45f544ef9cf097c535a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 17 12:24:16 2006 -0600
+
+ Added missing brace.
+
+commit 385b0fcf92fef84a5b216b523885d9b66b81ba47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 17 11:41:33 2006 -0600
+
+ Added whereDefined() to entry class.
+
+ Implemented void list(string *s, bool imports=false); to list all
+ global functions and variables in a module named by string s.
+
+ Removed unneeded init_readline in readline() routine.
+
+commit ddcc3110a61f7878e884895b66710f1bd0bb226b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 16 16:16:45 2006 -0600
+
+ Fixed xtick default argument issue.
+
+ Added 3d tick routines.
+
+commit df02809984fd6f70cccb0de55f3139bdfabfb546
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 16 10:05:37 2006 -0600
+
+ Minor edits.
+
+commit 880c0f19ddd67a25df6519f5e2d3fd02a1cba7cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 16 09:54:54 2006 -0600
+
+ Truncate out-of-bounds position parameters in labelaxis.
+
+commit 6629405d8a24e54b0214194fefb3d41e191eb186
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Aug 10 00:39:19 2006 -0600
+
+ Partially undid last change.
+
+commit 5c19f2abc3c0b0965ee16af5cd4e9db0ac440a66
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Aug 10 00:32:54 2006 -0600
+
+ Added tabcompletion to documentation.
+
+commit ec6f7c14bbb6ee7a675d34e8728930436c28fda5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 9 08:21:11 2006 -0600
+
+ Simplified texprocess and postprocess signatures.
+
+ Removed diagnostic.
+
+commit c3fab02a80fcfd8e2ff78882050a411f176d6356
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 9 08:12:20 2006 -0600
+
+ Removed bounding box fuzz.
+
+commit d191737368a18127796b33fef94399e79ba9e8b0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Aug 8 15:41:53 2006 -0600
+
+ Added intelligent readline auto-completion based on the environment.
+
+commit af3d2395c4b72d7342ed0e68872846499fa7159c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 8 10:27:34 2006 -0600
+
+ Documented interp.
+
+commit 1be5c206bbf11397d38fb3f8a5dfb6bd396e7f7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 8 04:02:56 2006 -0600
+
+ Fixed page alignment.
+
+commit c70cf49e3504ee60eff3cdccdc4f9314975a55ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 7 20:20:15 2006 -0600
+
+ Added newl after gsave.
+
+commit e0bbdb825112966ffc84648379a4326e09122658
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 7 14:07:53 2006 -0600
+
+ Removed unused code.
+
+commit 7553c45742a1653bedcac99f67c8ad29f67aca0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 7 09:46:36 2006 -0600
+
+ Turn off tab completion after readline.
+
+commit 4e5b8682d2ed3405ac13e5a269516abcf0916aaa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 7 09:36:42 2006 -0600
+
+ Simplified interactive mode.
+
+commit 337bc7366624b9ece92a35b75e404286c6c52216
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 7 08:20:46 2006 -0600
+
+ Simplified page alignment: -a Z nolonger implies -notex,
+ annotation now works even with negative bounding box coordinates.
+
+commit 33092b49f26e37dba2d4f4e29ff3244a9f8eceb4
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Aug 5 00:03:41 2006 -0600
+
+ Removed accidentally added debugging output.
+
+commit 3c5d840478b8e7df5a7da4164df7921119ecb5c7
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Aug 4 23:56:57 2006 -0600
+
+ Fixed horizontal drawline bug.
+
+commit 8ff1804d6af0ab6c487d75d144c8be2363fd839a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 3 06:47:03 2006 -0600
+
+ Updated implicit scaling documentation.
+
+commit 1c00e823b1efef1b1a213697c8f804f8686e2c96
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 2 13:02:50 2006 -0600
+
+ Check for interrupts on for(;;).
+
+commit 15550ffe796c57d5d29ea5ec94590b424dd52954
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 2 12:46:17 2006 -0600
+
+ Removed unneeded %s.
+
+commit 6d32da25931610ecbd2a037dabc06daf590b9eb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 2 12:38:03 2006 -0600
+
+ Added support for Adobe Reader annotations.
+
+commit d29fe7bd1b866038c712a4a361b0bdec3d66f113
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Aug 1 13:17:50 2006 -0600
+
+ Improved highlighting of strings and scaling expressions.
+
+commit 0acd2b77382036350910ff18bae3df35e509d9db
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Aug 1 13:16:51 2006 -0600
+
+ Allow empty test expression in for loop.
+
+commit 8eeecfa50431a4ead2b53af641e55b841bc0f15c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Aug 1 13:16:21 2006 -0600
+
+ Clarified comments.
+
+commit 355c37958b6b948bd3590b032373f59872a939f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 1 08:40:11 2006 -0600
+
+ Incremented version to 1.13svn.
+
+commit 011ccae6de7ae9699aa841dd6bd985526766ca25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 1 06:46:11 2006 -0600
+
+ Fix cxx warning messages.
+
+commit 4c397bc7f375c2b585c69abb7cb51a9ece995994
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 1 06:32:23 2006 -0600
+
+ Use command-line version of ghostscript (gswin32c.exe) under MSDOS to avoid
+ spurious ghostscript window when producing pdf files.
+
+commit 83c37ae5865e042bb52b50f7ee8ab366891894e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 31 14:42:09 2006 -0600
+
+ Updated.
+
+commit 3155feb37eb0b7b66680faa49af3f3030c9d26a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 31 14:23:50 2006 -0600
+
+ Simplify pen constructors.
+
+commit e292493e7798b572a31cfdc7f9f60be9a5c03d55
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 31 14:12:33 2006 -0600
+
+ Implement transparency.
+
+ Handle DEFLINE correctly.
+
+ Change string to mem::string throughout pen class.
+
+commit e6704b4d1c7bb2ad26618f2587b1a46183d3a19a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 31 14:09:15 2006 -0600
+
+ Use heavygreen instead of green.
+
+commit b58d65ce754bddf6d826d99af97c9a8e7ae67c4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 31 14:07:33 2006 -0600
+
+ Added equations item.
+
+commit 09880dbab3c09f0ff6b6d06469049e1e03834f1f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Jul 30 00:22:40 2006 -0600
+
+ Delay call of getName, so that it is only called when the name is used.
+
+commit daf07650a774d77f1bc1b319ff2129f93343abab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 22 13:43:23 2006 -0600
+
+ Fixed label fuzz.
+
+commit c75cd4332190a6c80206864871c7f098260c815d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 22 01:10:50 2006 -0600
+
+ Minor additions to Help section.
+
+commit f95b2c761e1bb5ce5cc1d4194d0c08b0758db1b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 22 01:08:18 2006 -0600
+
+ Account for scale in label bounding box calculation.
+
+commit 662666896ceec7a86a8acc05bbf714ff017acdf1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 22 01:07:15 2006 -0600
+
+ Renamed interact() to interactive().
+
+commit 0a7ee04366c0250477d87cd72007e0fcc1cbeb6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 22 01:06:34 2006 -0600
+
+ Fix Step calculation (special case).
+
+commit eae2726d0ce3648e4c77d5d8286c8959e2fef919
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 22 00:59:44 2006 -0600
+
+ Interactive reset should call cleanup, not exitFunction, and set uptodate=true.
+
+commit 6083f7f734c0846261a701d3dd2d9aaac3541ece
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 11 15:52:29 2006 -0600
+
+ Updated.
+
+commit fb46edec56c5921e5ca6cfcb0ef107eb7d135df9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 11 15:41:51 2006 -0600
+
+ Added default pen argument to Dotted().
+
+commit c4bd8d894fa312bb63b8e4367156266977092b15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 9 21:16:08 2006 -0600
+
+ Add q option to scroll facility to allow one to terminate scrolled output
+ without causing an execution interrupt.
+
+ Make scroll a setting instead of a function call.
+
+commit 7c5bedb12ad977701955cbf1726782e88ae2f379
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 8 22:10:25 2006 -0600
+
+ Added prefix plain_ to internal plain includes.
+
+commit 7da6733491c9eca3c94cd043f288bf09dbe16ed9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 7 23:05:42 2006 -0600
+
+ Add missing clear() function to remove all breakpoints.
+
+commit 9dd7f96ec2a61fdb419445bcffa2a0884006b870
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 7 23:03:10 2006 -0600
+
+ Simplified partialsum.
+
+commit 36759e0b95e1af56c6c0d76d1bc11597db2fc5b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 7 11:10:28 2006 -0600
+
+ Removed page break.
+
+commit d6047df8c3e18d8e1e34788eddbecb97597dced3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 7 11:06:25 2006 -0600
+
+ Documented ellipse.
+
+commit 42c87dac055830e8c87eba709885e75d4d893edd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 7 10:41:38 2006 -0600
+
+ Moved "Drawing Commands" section to immediately follow tutorial.
+
+commit ac38dcb2af96edeb8acb95b81c3021499d574b5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 6 16:30:18 2006 -0600
+
+ Minor documentation improvements.
+
+commit c3f6db0826aec5be9bebbe809665c549e1fbe779
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 6 16:17:13 2006 -0600
+
+ Fixed documentation of periodic tridiagonal solver.
+
+ Minor edits to Bezier curve documentation.
+
+commit f64d12cbbd2d0d824653688be0930ecdcf181119
+Author: Radoslav Marinov <rtm907>
+Date: Thu Jul 6 14:05:53 2006 -0600
+
+ Added a bezier curves example - /doc/bezier2.asy .
+
+commit 7b0e702e928cb8f2f04332fed7e9f10df50eb2df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 6 10:55:47 2006 -0600
+
+ Replace double quotes with single quotes for compatibility with \usepackage{german}.
+
+commit 133164c761c28dc86ccdc63b7a12e546a939c7e1
+Author: Radoslav Marinov <rtm907>
+Date: Thu Jul 6 10:55:47 2006 -0600
+
+ Added some more information on Bezier curves.
+
+commit 4bc34df3158d155b2fe5beefa9ef9e0970755bf0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 6 01:05:00 2006 -0600
+
+ Incremented version to 1.12svn.
+
+commit f8478772f370fba4d278a7b2c3a165c7641819ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 6 00:10:14 2006 -0600
+
+ Support g++ 3.3.4.
+
+commit e9b952ce4ae5900c33584f1ef822d66d775b87c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 5 23:53:55 2006 -0600
+
+ Fixed cxx warning messages.
+
+commit e12b26bc7e3ff3ae0f7383f9ea69f3df080aef8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 5 22:39:14 2006 -0600
+
+ Added reference to graph3.
+
+commit 60cb8a05d80a51765b53f4d2219e177c4165ee98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 5 12:28:58 2006 -0600
+
+ Renamed locate to locatefile.
+
+commit b289c382769951d33a7d1e86b25a9c0aa1aab70a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 5 01:15:18 2006 -0600
+
+ Debugger enhancements and minor fixes, including conditional breakpoints;
+ renamed remove(string, int) to clear(string, int).
+
+ Define min(... int[] a) and max(... int[] a).
+
+ Moved realmult to runtime.
+
+commit eb3848d18bc8b2666b7756d0beb6bf53636a9418
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 1 03:05:34 2006 -0600
+
+ Removed spurious write.
+
+commit 406eb56dbd70bc4a193fa6418ab86e0ded006bc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 1 03:03:41 2006 -0600
+
+ Simplified debugger: removed step, renamed line to step, and make trace toggle.
+
+ Prune duplicate trace messages.
+
+commit 27f83cfb49ff4d0bff6ddaf0ee33875c501a0fd5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 1 01:20:21 2006 -0600
+
+ Make access settings global.
+
+ Added twice setting to resolve LaTeX references.
+
+ Improve embedded movie example.
+
+commit 5491a9ba3950418ec02f30c385b92374e8674eee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 30 11:09:49 2006 -0600
+
+ Generate wheel.mpg.
+
+ Suppress vbv_delay overflow messages during mpeg merge.
+
+commit 176ad41299376337a145e9b084fd1d12ed2303c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 30 10:34:52 2006 -0600
+
+ Use defaultformat again instead of empty format string.
+
+commit 846dfbf82f1d4a1757c0c20048b67710620605cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 30 10:27:19 2006 -0600
+
+ Improve discussion of stack overflow detection.
+
+commit 4fcdfd5f23e825c917fb3a7b5c958ec6d94d5ae9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 30 08:35:14 2006 -0600
+
+ Added missing file.
+
+commit 685c1ede9c52233c3cb2135ee12e986391e6d374
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 29 22:54:03 2006 -0600
+
+ Added 3D array transpose and copy.
+
+commit 2c20940ae36d496d660f04d4d360c4bdbe0ff558
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 29 22:37:03 2006 -0600
+
+ Prevent runtime errors and interrupts from resetting interactive environment.
+
+commit 6f8a184d15535e00803cb8ac6ffff182459a40ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 29 22:35:10 2006 -0600
+
+ Removed extra blank line at end of 3D array write.
+
+commit 1923d5f328df74f65f9c7cf7850a0d672c18ccb3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 29 17:10:05 2006 -0600
+
+ Moved introductory material into Tutorial section.
+
+commit 860b5da27d21101dc89322659afb376f7d28f1e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 29 11:37:38 2006 -0600
+
+ Added prompt and quiet settings.
+
+commit 5698e9e1a1cbf3073cc280dfd71eaac62be58313
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 29 06:20:33 2006 -0600
+
+ Don't exit if stack overflow or segmentation fault handlers fail (to
+ workaround broken libsigsegv-2.3; upgrading to libsigsegv-2.4 is recommended).
+
+commit 83b1ede25ffc9552e993a5d95613b76760b1130a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 28 21:59:26 2006 -0600
+
+ Renamed Examples section to Tutorial.
+
+commit 849359439f21d7b98bcb33eb0cb341a53180fcf5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 28 12:40:09 2006 -0600
+
+ Removed unused line.
+
+commit 194753aa5ef632bbdeda4bc54091b0327559e630
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 28 12:38:09 2006 -0600
+
+ Moved debugger into separate base file debugger.asy.
+
+ Added void stop(string file, string text); to stop at the first line in
+ file containing the string text.
+
+ Renamed q (quit) debugger command to x (exit); added q (quit) command that
+ quits debugger and ends execution.
+
+ Better fix for memory leak.
+
+commit 7f95d2aa8d456d4f4ac55fdf66bc1d380359df1c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 28 10:59:27 2006 -0600
+
+ Minor documentation updates.
+
+commit 6744bcf2123427cc4c488b9faa08a74c5c28286f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 28 01:24:15 2006 -0600
+
+ Ensured that the basis in lookAt() is orthonormal.
+
+commit 1e1d21359af6ac9ed84e8a655f85caa8dd15339b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 28 00:35:12 2006 -0600
+
+ Incremented version to 1.11svn.
+
+commit 9dedce2a8e0e8aad57168c928a43c4e21c848aaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 28 00:03:25 2006 -0600
+
+ Add support for spaces in Asymptote and output filenames.
+
+commit f4c9eb6456a12db6b0e0ced5d6c7d2baaa574274
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 27 22:51:10 2006 -0600
+
+ Added more quotes.
+
+commit 21cc31375595807ed07c4c16f0756c0c0914380a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 27 22:44:55 2006 -0600
+
+ Add more quotes for MSDOS users who like to use spaces in filenames.
+
+ Remove quotes in diagnostic messages.
+
+commit 9481a3783c06307af05591e38a5fdfde0808c5eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 27 13:30:09 2006 -0600
+
+ Cache source code in debugger.
+
+ Move debugger help message to immediately before prompt.
+
+commit 56a9d58ba74a24b05cea462018490512c164dfab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 27 12:42:03 2006 -0600
+
+ Extended and documented debugger.
+
+ Fixed string reads of lines containing only whitespace.
+
+commit b0c68db03af88951576f316333056c5d9b565acc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 27 01:47:31 2006 -0600
+
+ Fix drawpen.
+
+commit b4fa5baaf24bc1217c729461060e9aa5cde234f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 27 01:45:40 2006 -0600
+
+ Make default drawpen currentpen again.
+
+commit b042abc34e332e4b96fca5595320beb43392ab6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 27 01:31:48 2006 -0600
+
+ Work around atbreakpoint memory leak.
+
+commit ddafc5a4ed46a3f11e6944cf3d9c6d10d3c7708d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 26 23:25:54 2006 -0600
+
+ Make Fill and FillDraw work with markers and superpaths.
+
+ Minor formatting updates.
+
+commit 5e5eb1543ef6f855dd4fe7021ad2629af65efd09
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 26 22:23:17 2006 -0600
+
+ Suppress all errors when quiet=2.
+
+ Catch handled_error in configuration files.
+
+commit 7960b9d402a8e258d465c777ec0183b1d5457062
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 26 21:14:44 2006 -0600
+
+ Added parametric surface example.
+
+ Distinguish between distances in front of and behind camera.
+
+commit 6517027ce7911dfb196eac47ff129ed6e96e8e60
+Author: Chris Savage <chris@savage.name>
+Date: Mon Jun 26 18:02:59 2006 -0600
+
+ Implemented parametric surfaces. Surface fill/mesh is no longer drawn for nullpen arguments.
+
+commit 5ffd26cdb1c4cccd7de84fe4b6297d5a599dc058
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 26 16:04:47 2006 -0600
+
+ Fixed segmentation fault if atbreakpoint isn't defined.
+
+ Moved debugger.asy into plain.asy.
+
+commit 5c7f6e9573b220bd314fdabd7125837cb1472236
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 26 02:02:39 2006 -0600
+
+ Support compilation under g++-3.3.4.
+
+commit e8bd9c1cefa26e967527ea67557848c45c9e0e46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 26 01:18:44 2006 -0600
+
+ Debugger support.
+
+commit 9a1d8ebaeced74c8a153a8cfc4676852623544f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 25 22:13:21 2006 -0600
+
+ Implement rudimentary debugger.
+
+ Fix interrupts.
+
+commit e43db21f79abdef7e08101de0878690dbff29288
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 25 22:10:58 2006 -0600
+
+ Suppress stderr for gv workaround.
+
+commit 8ce72f2e5b1b30cb24fd00f98b9fb864a87a7dfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 25 22:10:14 2006 -0600
+
+ Suppress stderr only for gv workaround.
+
+commit e63b5160040dbd16a42d1ed523e3e0577530c911
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 25 19:20:24 2006 -0600
+
+ Work around file descriptor problem with MikTeX 2.5.
+
+commit dbd425d4bd359edf6c23148c7616ce0631090b4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 23 21:03:52 2006 -0600
+
+ Added Crop argument.
+
+commit fe386dfc9115d32344b5740960089de1fd6a58e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 23 21:02:52 2006 -0600
+
+ Added autoconf > 2.59 patch submitted by Chris.
+
+commit 146deafd826c99a659888fe7442932a769ed16c9
+Author: Chris Savage <chris@savage.name>
+Date: Fri Jun 23 18:06:33 2006 -0600
+
+ Added crop argument to limits to match xlimits.
+
+commit 4ba4b2c506db233267faab753776de776d4a43ab
+Author: Chris Savage <chris@savage.name>
+Date: Fri Jun 23 18:04:34 2006 -0600
+
+ Corrected default crop argument of xlimits.
+
+commit 547c1670099a308a0cc8a7775663a4538cd2514f
+Author: Chris Savage <chris@savage.name>
+Date: Fri Jun 23 17:08:52 2006 -0600
+
+ Added picture argument and use of picture scaling to graph(...) functions that did not previously do this.
+
+commit 8584e109743d459f49cb464afda3d3fe96e1636c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 23 06:12:58 2006 -0600
+
+ Changed Docdir to docdir; hopefully this won't conflict with next release
+ of autoconf.
+
+ Replaced GPL LICENSE with newer version (FSF forgot to bump the version
+ number!).
+
+commit 8d111c60d5c8fee35160dfc0a8e53fd62b2e40e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 22 16:35:05 2006 -0600
+
+ Incremented version to 1.10svn.
+
+commit eb0de75fc9217b6a6b982157fad091a0e3f60bb8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 22 13:52:31 2006 -0600
+
+ Make gv-3.6.1 bug workaround work with older versions like gv-3.5.8.
+
+commit 8ff9ab7deabaa2f6b7b117056fca0a0b8c50a8d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 22 00:19:45 2006 -0600
+
+ Updated to MSDOS gs8.54.
+
+commit a4d69da3b751629da5f08828082c7c466c079914
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 22 00:18:51 2006 -0600
+
+ Incremented version to 1.09svn.
+
+commit 0f24e94fcb206bece1df0307eb9c353c8e900a9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 21 22:36:17 2006 -0600
+
+ Documented int[][] triangulate(pair[] z); for creating a triangular mesh.
+
+commit 349ef2c3f789eb2c5da5cc8e8e34a2ecfeb83fe7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 21 21:46:43 2006 -0600
+
+ Fixed make distclean.
+
+commit 053152254fd41c1c83d83bfc1dd77623abf10d59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 21 21:15:32 2006 -0600
+
+ Clean up unneeded files.
+
+commit f6a46cd80c1f5d8a8c438368f67bdb1a7ff45d0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 21 18:13:50 2006 -0600
+
+ Fixed warning messages.
+
+commit 4eba8344080fd285665a7673788a5fba3559fa4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 21 16:41:19 2006 -0600
+
+ Removed unneeded public modifiers.
+
+commit b8a19d515820713230513415a8eba377a9f3fce2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 21 16:35:07 2006 -0600
+
+ Added pen colorless(pen) function that strips pen color attributes (useful for
+ avoiding color mixing).
+
+ Fixed stepping bugs in slide on overfull slide; added institution field to
+ titlepage.
+
+commit c026098e41f0ae6c8568bb41f6146592a730c298
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 20 21:40:06 2006 -0600
+
+ Removed AC_FUNC_MALLOC and AC_FUNC_REALLOC as they seem to cause more
+ problems than they solve.
+
+ Fix help command by reverting broken Docdir change.
+
+commit d940254ae30f0b9a5492adb74cf04417784d1eac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 20 13:12:52 2006 -0600
+
+ Increased epsilon to fix corner cases.
+
+ Suppress null labels.
+
+commit 5eb1c97104c77b32837f6e96d1ea96a9859bca3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 18 22:32:31 2006 -0600
+
+ Incremented version to 1.08svn.
+
+commit 1e60c4d32988a7983d208fa0289e71df8bb56bfb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 18 21:34:40 2006 -0600
+
+ Fixed gv workaround.
+
+commit b3983451193bb29fa2fe492d385f408d4e159182
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 18 20:51:25 2006 -0600
+
+ Fix cygwin build problems.
+
+commit d56acb49f9f969cb5a940a1c7c48a5de241110f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 18 10:39:54 2006 -0600
+
+ Add and document contour labels.
+
+commit 640ad149422053ee618a7be7bf5aa9636076b88a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 18 01:37:48 2006 -0600
+
+ Updated documentation regarding type-dependent array functions.
+
+ Fixed example.
+
+commit 84088bd182aa527acc3e8d0f0bfa6a56a97c2510
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 18 01:24:06 2006 -0600
+
+ Add imagecontour example.
+
+commit ff6887f2c5ab91209aba3956c4d25805f0ad6901
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 18 01:03:23 2006 -0600
+
+ Add improved and simplified version of Chris' palette modifications.
+
+commit fcbd8a3c0dcd0d6baa8e5ceaec1c65f823b8f65f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 17 16:53:00 2006 -0600
+
+ Fixed arcarrowsize.
+
+commit 7ef1b87ae9df597ccff3c44fd5d65ada8d2d86a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 17 16:49:51 2006 -0600
+
+ Fixed and simplified LU decomposition, solve, and determinant.
+
+commit 8f9a1b963c39eff23baa5f87d53d1317a780d145
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 17 04:56:37 2006 -0600
+
+ Simplified test.
+
+commit ceeda628c34eae8b29464876115aebc0aba7fc58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 16 20:09:40 2006 -0600
+
+ Optimized solve and inverse.
+
+commit f1129650fdf1e1b9a3b9a0d43b3d6979b7fbf501
+Author: Radoslav Marinov <rtm907>
+Date: Fri Jun 16 14:01:41 2006 -0600
+
+ Added LU decomposition instead of Gauss-Seidel method in solve. Gauss-Seidel method is still used for finding inverses. Added a test for both.
+
+commit 973bab339bb76e8373ad05c952946b826453f035
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 15 16:33:32 2006 -0600
+
+ Renamed Fill filltype to FillDraw and added Fill filltype that only does a fill.
+
+ Fixed arrowsize capping code and added arrowsizelimit.
+
+commit 3b257884e63a16d5f3c488d5ed774acb7f31d5a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 15 14:41:13 2006 -0600
+
+ Renamed readable to restricted.
+
+commit 651ae218ff630152e4d03bf44b6d5be20e6f47a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 14 15:55:06 2006 -0600
+
+ Fine-tune logo.
+
+commit 7f1cf6db7f42d205226c05742a347c09701ff4bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 14 00:15:22 2006 -0600
+
+ Change defaultformat argument of PaletteTicks to "".
+
+ Fix formatting issues.
+
+commit 3e2f27f3847471318a6568e6cda79c5e1b3e4188
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 13 17:23:58 2006 -0600
+
+ Added readable keyword, made public the default permission.
+
+commit 5dd1e7f9b4440e235a3d77d591c683b8a4c99b55
+Author: Radoslav Marinov <rtm907>
+Date: Tue Jun 13 14:49:16 2006 -0600
+
+ Updated documentation for contours.
+
+commit 5ef02318e225d6f75bbddb01866f7efe278b92cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 13:14:18 2006 -0600
+
+ Optimized postsorting of triangulate routine.
+
+ Simplified contour interface.
+
+ Added nonuniform contour mesh example.
+
+commit 9643e0dc524184c8285d73c2351976e5a98f5a11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 12:34:14 2006 -0600
+
+ Make arrowhead and arrowheadbbox public to allow them to be overloaded.
+
+commit 9ad6ed85d523118ea068a22769f72d587dda8d2a
+Author: Radoslav Marinov <rtm907>
+Date: Tue Jun 13 11:10:27 2006 -0600
+
+ Added non-regularly spaced contouring.
+
+commit f227e558df95e61472134119242ad9feadb93875
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 01:00:48 2006 -0600
+
+ Use random pair for overwrite moves when align=(0,0).
+
+commit b257abdab1f08e55f01aa5570a05e785dde0e40b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 00:59:12 2006 -0600
+
+ Formatting.
+
+commit 8684d471b3697c1630abc8b06bfb74506b49c9ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 00:54:17 2006 -0600
+
+ Fixed secondary logarithmic axes.
+
+commit 0346bdb77d0dc2da9d7cf7b8f660f5e487472951
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 00:34:56 2006 -0600
+
+ Fixed count computation (for endlabel=false).
+
+commit fc50cfec9594716a63f4d6708e3e6dadb75dabfa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 13 00:25:17 2006 -0600
+
+ Fixed alignment of rotated tick labels.
+
+commit 2823b5e4594cc35dbf382941754006bea86aa9c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 12 22:37:10 2006 -0600
+
+ Implemented more efficient guide collection algorithm.
+
+commit d3e000399ca900690fbe10cc7f99820c835f7bb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 12 20:33:17 2006 -0600
+
+ Added string option to assert.
+
+commit 1fd671831ef34a2e1114bf08a061ff9985c373e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 12 20:30:55 2006 -0600
+
+ Standardize "could not load module" error message.
+
+commit 51889939c120a4ca97af149784c217ceb7b06115
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 12 20:29:02 2006 -0600
+
+ Use most up-to-date verbose setting for traceback.
+
+commit f7f07a661d8b1f8401949d437dac738a7de61050
+Author: Radoslav Marinov <rtm907>
+Date: Mon Jun 12 10:23:59 2006 -0600
+
+ Removed copying of unused variable in triangulation routine.
+
+commit c80e76f924a4611e1ce9c9b6e11e3bcd7f92d58f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 11 14:05:28 2006 -0600
+
+ Removed executable flag.
+
+commit 59f5f5a6ae7a00dea7b006404c1e2881df118c93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 10 15:45:17 2006 -0600
+
+ Make currentprojection public.
+
+commit 29d5586ceb7a1aef6e782a4d124bf3bd672b5575
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 10 15:42:22 2006 -0600
+
+ Import three as public so that currentprojection can be overridden.
+
+commit 6ed73746146901f100fd6ecb07a3fe0c8ee549ee
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jun 10 13:55:29 2006 -0600
+
+ Added addSaveFunction to extend save and restore.
+ Moved projection code to three.asy.
+ Handle degenerate cases in lookAt().
+
+commit 82ecef1191a366ad0f0b0508663cc5ca013fe4b9
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jun 10 13:51:57 2006 -0600
+
+ Noted built-in modules.
+
+commit 25751222b9f06612b95690c9607aff0be31b8ce2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 9 22:16:41 2006 -0600
+
+ Removed unused subtraction.
+
+commit 9981e0a4273b280d7edf66ad2d121c3b7ec7d620
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 9 22:05:53 2006 -0600
+
+ Fix overhead/underhead views.
+
+commit d627684544274d7cf3670616a96cd687a80b05d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 9 16:49:33 2006 -0600
+
+ Added up argument to lookAt; remove lookAtOrigin in favour of lookAt(O,...).
+
+commit 4c9fc4ebfac5c393e8cbfa0c22a2ae32fab47d6b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 9 12:21:26 2006 -0600
+
+ Simply support for custom projections.
+
+ Reverse arguments of lookAt for clarity.
+
+commit f0648e6bf0a78e245f949a6aae289aef6b99b0bd
+Author: Radoslav Marinov <rtm907>
+Date: Thu Jun 8 13:49:56 2006 -0600
+
+ Fixed a problem with triangulation.
+
+commit fb2650817ca533532783708b22602a8b5b85c8d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 21:41:09 2006 -0600
+
+ Fixed typo in configuration instructions.
+
+commit 869f515dc87594e6b50fa2609847ffe4e4facff4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 17:00:16 2006 -0600
+
+ Add Delaunay.
+
+commit f200d75273e0bfb0f7ae0bdab84714c45a462ee2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 16:58:54 2006 -0600
+
+ Added Paul Bourke's Delaunay triangulation routine.
+
+ Removed unneeded copyArray from inside.
+
+commit 772fbb1edbde73c41403365263a2adf06b08a443
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 14:22:18 2006 -0600
+
+ Fixed typo regarding cone vertex.
+
+commit 88e0cf1bdfadaea42f1f660ea8a79fe43ce0695a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 14:02:03 2006 -0600
+
+ Fix configuration problems.
+
+commit 27e61ce6967c6650650287430cf37e5f6efbb5fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 03:25:06 2006 -0600
+
+ Remove docdir.
+
+commit b655d72e4a0551596632fbd31b5128322450b454
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 03:10:45 2006 -0600
+
+ Remove unused docdir operations.
+
+commit 9610dd75d92ba49c9e448425ea9aa66eef84f0a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 03:05:30 2006 -0600
+
+ Implement work around for backwards-incompatible command-line options of gv-3.6.1.
+
+commit 1c99f965ca672e7a581ad72cb440454e2328b0fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 02:47:32 2006 -0600
+
+ Make docdir if it doesn't exist.
+
+commit ea5049ca5be8b6fe15ad71804eaa69363b374320
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 02:27:37 2006 -0600
+
+ Fix default configure documentation directory setting.
+
+ Document inclusion of Asymptote in Fedora Core Extras project.
+
+commit db803d3c1d07e1494e24a197a02a6968e3bc5df1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 7 01:40:43 2006 -0600
+
+ Added --with-docdir=PATH configure option.
+
+commit 8cf4582ac520c17579da3f75c57b2e4001759b7b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 6 23:12:16 2006 -0600
+
+ Add object structure for handling frames and Labels on an equal footing.
+
+ Add a pack routine for building compound frames from a list of objects.
+
+ Simplify flowchart interface and example; fix frame/Label packing.
+
+commit cea422aaa3c107040e20983f2918ead70fb61293
+Author: Radoslav Marinov <rtm907>
+Date: Tue Jun 6 14:46:11 2006 -0600
+
+ Added slopefields module.
+
+commit 5e6f5135cc6c798defa0ef962b90bc44f120259a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 6 04:10:20 2006 -0600
+
+ Fixed alignment problems, standardized usage.
+
+commit 9b09a4901061fe9d5092a8ccb369d1f8b25450e7
+Author: Steve Melenchuk <smelenchuk@gmail.com>
+Date: Mon Jun 5 12:13:22 2006 -0600
+
+ Repair inconsistency in box height being used for vertically centering the header text in flowrectangle.
+
+commit 009f43ccc83a73ac803878ac83351593a2acc157
+Author: Steve Melenchuk <smelenchuk@gmail.com>
+Date: Mon Jun 5 11:52:27 2006 -0600
+
+ Tweak vertical margins on flowrectangle with header.
+
+commit eac4e8394435700da38568335cb6c3a9dfb7d8c9
+Author: Steve Melenchuk <smelenchuk@gmail.com>
+Date: Mon Jun 5 09:31:06 2006 -0600
+
+ Adjust margins on flowrectangle (both with header and without).
+
+commit 63a2536150751be2feafc4457d8e6402fbe29b58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 4 21:49:17 2006 -0600
+
+ Make makepen fill nodes; fix infinite loops.
+
+commit 844fd281ea372e25b043a6e899e8ee32ffa869ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 4 14:49:17 2006 -0600
+
+ Added missing pen arguments in calls to hatch.
+
+commit bd06d2617aa5c40b9a7b7e13eaa3cd6f2c35d24c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 3 08:04:31 2006 -0600
+
+ Fixed documentation of PaletteTicks.
+
+ Renamed ngraph argument to n for consistency.
+
+ Renamed straight(path) to piecewisestraight(path) and moved to runtime.in.
+
+commit 3aba60d261891a8a6aea2f45d1ba81411fea0470
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 2 16:20:34 2006 -0600
+
+ Draw on frame f.
+
+commit 45ce2b17d76b55a1612548fbaec345dc1b21b161
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed May 31 13:51:33 2006 -0600
+
+ Clarified the non-behaviour of top level static modifiers.
+
+commit a74dcf0f7b3e963af33e33071fc38c6afb2b30b3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed May 31 13:42:21 2006 -0600
+
+ Added warning for top-level static modifiers.
+
+commit 54baf1109570f092424b389f6059c87a1bb74310
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 12:45:50 2006 -0600
+
+ Added flowblock initializer; removed unneeded new picture initializers.
+ Added authors, improved indentation.
+
+commit d9198ced6bdf4ff2fab4bc8a58905656a93aa3f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 11:54:36 2006 -0600
+
+ Make cputime return a structure.
+
+commit 78e73f71620d81fc555f4c27158b75290cb409c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 11:53:38 2006 -0600
+
+ Removed unneeded CFLAGS.
+
+commit 07b2003ee31ecc0df02a550d0f9705524cc5466a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 10:34:10 2006 -0600
+
+ Fix texinfo dependency.
+
+commit d5597dbdbc87dd6f48a7e628eecde5cfb95c6463
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 10:21:34 2006 -0600
+
+ More info updates.
+
+commit 649b4aec2d15a36e686e98b30ef91fb7f774363a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 07:03:42 2006 -0600
+
+ Add cputime() function.
+
+commit f545c026d79b3cf8059a96200521bd73be1d1dd4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 06:24:26 2006 -0600
+
+ Use -O3 when building rpms.
+
+commit dbd641c869d86b02b6ba3153c41cbd625a13221a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 06:13:43 2006 -0600
+
+ Fix picture scaling computation in dimension example.
+
+commit a083bff3445bf9134c9cc5e4020c38f213a6b715
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 31 05:18:53 2006 -0600
+
+ Improve diagnostics.
+
+commit 7b20750384ac20389e1849e32a22c6c4c929f08d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 30 01:18:50 2006 -0600
+
+ Removed info dir entry in %files section; makedepend should respect cflags.
+
+commit 010f667be0917e8ea63c38bc0b894fc8ee8d82b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 30 00:53:41 2006 -0600
+
+ Use make install-all in rpm spec file to install info pages as well.
+
+commit 000cb4d5d8afababec8806b7b439143a0389a5ad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 30 00:53:15 2006 -0600
+
+ Fix make uninstall.
+
+commit 60cacc6f428142cb91f9c3e54ae1c4cc5b73d2d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 30 00:28:36 2006 -0600
+
+ Fix installation changes.
+
+commit 98f69f91a7c55ce3a90cdbe800365124e6137292
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 23:58:30 2006 -0600
+
+ Update example to use new mesh resolution names.
+
+commit aac6c630f447abcd6880c0ae38add2bb8c32e63f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 23:57:15 2006 -0600
+
+ Fix another relative path installation problem.
+
+commit 24e32f701448ae0abd7e332aab053bf60d5c062e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 23:47:36 2006 -0600
+
+ Fix installation of system asy files.
+
+commit 08b522ff4cabbdaaf70de0c14eddc61e12755b98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 23:40:00 2006 -0600
+
+ Fix cxx warning message.
+
+commit f620740a5af8135c70fbd4e81bd6361cfb64bdc0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 23:38:33 2006 -0600
+
+ Renamed contour examples.
+
+commit fcbd51eb488444cc34e8a967ee73d22b0f3554a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 23:33:18 2006 -0600
+
+ Simplified contour interfaces by implicitly casting pen to pen(real).
+
+commit 32a0c4c021e8faa02e52de3403d52b0fc4857ad6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 22:06:37 2006 -0600
+
+ Change package group; request texi2dvi; install asy-init.el.
+
+commit 12fbe90c8826f0a4bdd37d53051d1fcd7377e524
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 22:02:14 2006 -0600
+
+ Add emacs/xemacs init file for rpm installation.
+
+commit ca219dfe286fe14588199316b44a516aed97ebf2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 29 22:01:05 2006 -0600
+
+ Move include shipout earlier.
+
+commit 1f2e802856fabc690a106486a3ba4139963e7b57
+Author: Radoslav Marinov <rtm907>
+Date: Mon May 29 15:46:10 2006 -0600
+
+ Added new interfaces to contour.asy
+
+commit 04c13ec23cf6ab805a13097218c21860a571be28
+Author: Radoslav Marinov <rtm907>
+Date: Mon May 29 15:31:48 2006 -0600
+
+ Added basic documentation for contours.
+
+commit a03b794e15756e3e0459f4601851d2eef218bc0d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 28 22:40:13 2006 -0600
+
+ Minor optimizations; standardized mesh arguments (n -> nx, m -> ny).
+
+commit af0349baa883f68bdc064f5c20b921880ce4431f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 28 18:07:12 2006 -0600
+
+ Further optimizations obtained by sorting contour array.
+
+commit d5e04e1cee076e6fa542899344643ab02e63ae36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 28 13:12:14 2006 -0600
+
+ Optimize.
+
+commit 5956312549528c37d03ed6a6aa638f41d64cd72c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 26 22:19:37 2006 -0600
+
+ Add Jose's patch: list directories in %files section.
+
+commit 5bf4a571d99182f39cbf8c7089e13497c8a6e31d
+Author: Radoslav Marinov <rtm907>
+Date: Fri May 26 15:32:06 2006 -0600
+
+ Fixed a minor bug and added an additional interface option.
+
+commit 2dc5e703eafd44944c9056defebcb7f0d62cc4a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 26 15:12:37 2006 -0600
+
+ Make pen argument a function.
+
+commit 4aafdb65a959e771b184dc6ffd9ffdf58af6ac1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 26 15:02:09 2006 -0600
+
+ Standardized signatures; support contours of matrix data as well as functions.
+
+commit a05043c0414b96b2e277655e781c4468a7c012fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 26 11:36:37 2006 -0600
+
+ Make images and shading respect -gray, -rgb, -cmyk, and -bw.
+
+ Make palette.asy use grayscale with -gray.
+
+ Replace bool mono by settings.gray || settings.bw.
+
+commit 492d0924cd96e9fb43f5b7c42f7b42e6f7db8164
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 26 08:24:01 2006 -0600
+
+ Add date arithmetic routines:
+ time(int seconds, string format="");
+ seconds(string t="", string format="");
+ Make time() return the current time in the default UNIX format.
+
+commit 0d6b7c6cf6f5f120e7a06024eaf8186aa821c3ac
+Author: Radoslav Marinov <rtm907>
+Date: Thu May 25 15:35:50 2006 -0600
+
+ Inserted a space between operator and .. .
+
+commit 5f1fdbef839ebb2692ca7e7aa3b6cacfa1a2bc7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 14:50:32 2006 -0600
+
+ Changed 1.07cvs to 1.07svn.
+
+commit fb08ae2efca0b373fae51e0d835f9b45e8a8d2ca
+Author: Radoslav Marinov <rtm907>
+Date: Thu May 25 13:17:55 2006 -0600
+
+ Fixed a formatting issue and a minor bug.
+
+commit 18489c1c24083cb89668b9d64893301fb2dc6a2d
+Author: Radoslav Marinov <rtm907>
+Date: Thu May 25 11:29:03 2006 -0600
+
+ Contour.asy now can choose interpolation operator; default is --.
+
+commit eacb2efc49b51b090ce2164ff13c4801e75de347
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 10:43:46 2006 -0600
+
+ Added example of log2 graph.
+
+commit c7cccaf9c785a2d500880d5fc98a5f048602697d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 10:32:56 2006 -0600
+
+ Fixed bug in YZero.
+
+ Handle log graphs bases other than 10.
+
+commit 6d948eaee01351978780cd68c59885096bc01a02
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 05:00:23 2006 -0600
+
+ Rename array virtual pull function to delete; handle case with negative
+ argument.
+
+ Add virtual insert function for arrays.
+
+commit e8c13b250ffb7d76bad5771584f374c077d66aca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 04:20:44 2006 -0600
+
+ Added virtual pull function for arrays.
+
+commit 329a88e82d4993a278c8672b516fe9b035b7ffba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 03:44:18 2006 -0600
+
+ Fix currentpicture.empty() test.
+
+commit 0d0dac1cd60be60a0076b0be059bf10096ee2423
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 03:07:52 2006 -0600
+
+ Standardized argument names.
+
+commit 5a8131d6c2bc8bea7859c6cf58d6ba52966aa882
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 02:55:26 2006 -0600
+
+ Formatted.
+
+commit e4997b1c1f87258e77414236b182b99b3637f8d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 02:30:13 2006 -0600
+
+ Fixed longitudinal skeleton when c != O.
+
+commit fcd1d170401623022db843402ad7cb29a4bbd590
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 02:28:57 2006 -0600
+
+ Minor optimizations.
+
+commit d214a8ab29f6f395ae29b142f04f0bfaadbec9f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 02:27:52 2006 -0600
+
+ Check colorspace argument for all forms of shading.
+
+commit cf6077824d89ed8864496d545b6ce584ed8c0abe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 25 02:26:56 2006 -0600
+
+ Added 3d axes routine.
+
+commit 289d41c8ae0a0bcc24fd160a0f1663d2dc7ec5e1
+Author: Radoslav Marinov <rtm907>
+Date: Wed May 24 15:45:34 2006 -0600
+
+ Now uses arrays.
+
+commit 6c7e8af3ae2984f1cb20bece75a584bbffda3d5a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 24 15:08:08 2006 -0600
+
+ Handle subpath arguments beyond boundaries.
+
+commit 3d113075dbb9f217a024bf099a538b168b78accc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 24 11:25:27 2006 -0600
+
+ Added outline().
+
+commit 500936a35c334a1d9e7f196819a57462e2a7ae5d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 24 01:16:30 2006 -0600
+
+ Added reverse(triple[]).
+
+commit 072a649884bca1338c9cc74b147e7bee261f937e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 24 00:28:55 2006 -0600
+
+ Minor optimizations.
+
+commit 9ff513320c61a5d555c6844a206f7b7f095a5d11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 24 00:27:59 2006 -0600
+
+ Simplified code.
+
+commit f1429ac3504544b7d4786f6e6edd80ea656b7f74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 23 22:32:50 2006 -0600
+
+ Updated to mention Subversion instead of CVS.
+
+commit e4ee3b0940c364a5c241bc96dbfe4c6b7aaa51cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 23 22:27:31 2006 -0600
+
+ Updated documentation for Subversion.
+
+ Fixed list of autogenerated files in slidedemo.asy.
+
+ Added missing file.
+
+commit f1b30214cf29bcd231024f5f574991ddb7e0d5d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 23 16:36:20 2006 -0600
+
+ Clarified comment about duplicate guides.
+
+commit b79cd62cf321feb649d66c333e1a4b534b795625
+Author: Radoslav Marinov <rtm907>
+Date: Tue May 23 14:44:18 2006 -0600
+
+ basic .. routine
+
+commit e7706f3e6130165c7e777a4d52af33154143aff9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 23 11:33:30 2006 -0600
+
+ Improved formatting.
+
+commit eed452cd06ba19e12fd9a39b933578e654ac49ff
+Author: Radoslav Marinov <rtm907>
+Date: Tue May 23 11:26:18 2006 -0600
+
+ minor updates to contour.asy
+
+commit 5a36430d4a78004a93b423ae9aa40621226d926d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 23 10:46:50 2006 -0600
+
+ Fixed typo.
+
+commit 854961693a69d0cb1b415d03ea2606be4daa890b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 22 16:23:43 2006 -0600
+
+ Incremented version to 1.07cvs.
+
+commit 996168032abd9a766ce2d783be17354747617e5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 22 08:36:57 2006 -0600
+
+ Added figuremattpen optional argument.
+
+commit eea7a0e9ded8118d99fff985a24dc35445ed9e6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 22 08:36:14 2006 -0600
+
+ Fixed syntax.
+
+commit a8b82e25d7902945f2081705fb4b3081b1cb7f79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 22 00:17:35 2006 -0600
+
+ Renamed old flowchart.asy example to advection.asy.
+
+ Formatted flowchart.asy base file and example; standardized spellings, etc.
+
+commit 8dd6575b7756cc5f90a55f1b1dfadbd58d51cc0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 23:38:42 2006 -0600
+
+ Updated.
+
+commit 631c41e5ff3247612218189a5ccd2972e85ba48f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 23:38:05 2006 -0600
+
+ Restore TeXpipepreamble and TeXpreamble after eval(embedded=false).
+
+ Restore settings between multiple file runs.
+
+commit 7be85d3918e2a665b3723486f43b59e7274c4e1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 23:35:52 2006 -0600
+
+ More endl to newl changes.
+
+commit 4bc38d1758d0601ea5747592ec6b465ab388d492
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 23:34:29 2006 -0600
+
+ Allow alignment checking to be disabled with -DNO_CHECK_ALIGN.
+
+commit bea2825f47aa9136c29aa1cdf88ef0f75ccd4455
+Author: Steve Melenchuk <smelenchuk@gmail.com>
+Date: Sun May 21 14:00:13 2006 -0600
+
+ First version of the heavily-cleaned-up (originally externally contributed) flowchart module. A (very simple) demo has been added into examples and the documentation has a section on the module (could the docs be improved for it?).
+
+commit f84251f8cf64885ef16c1d3c10ec2ae74d5823cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 02:39:14 2006 -0600
+
+ Changed quiet=false option to view=true in shipout (backwards incompatible,
+ but rarely used).
+
+ Removed unused execute(string s, bool embedded=false) function.
+
+ Added void asy(bool overwrite=false ... string[] s)
+ to conditionally process each file name in array s in a new environment.
+ Moved margin argument of figure in slide.asy to just after options.
+
+ Make slidedemo.asy generate required files in case they don't exist.
+
+commit 5a2f592641f2a82b86b6b73a103ff2113bc39374
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 02:02:42 2006 -0600
+
+ Fixed segmentation fault with a future eval after an eval throws an exception.
+
+commit 9a8e1d66275b73f67d167b8f60105b2550df4461
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 00:38:22 2006 -0600
+
+ Make titlepage and title by default call newslide, unless the
+ currentpicture is empty.
+
+ Added reverse video option to slidedemo.asy.
+
+ Add an argument to newslide to allow stepping to be turned off for that slide.
+
+ Updated slidedemo example.
+
+commit a47eb26bec02902d3efcd94997b96e5a01fe701b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 00:34:16 2006 -0600
+
+ Add optional x and y margin arguments to Fill.
+
+commit 181ab2a6b5811ce4f76eb642be9337cd3fdd66fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 00:29:44 2006 -0600
+
+ Allow -u to be specified multiple times on command line.
+
+ Make "open" the default pdf viewer for MacOS.
+
+commit 38c9138c931e1f2c6808c54a078e1308be30da8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 00:28:15 2006 -0600
+
+ Added asycolors.sty package to make LaTeX aware of CMYK versions of
+ predefined Asymptote colours.
+
+commit f0ddb7b579a89d99e8dd649548e4de4c064247ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 21 00:24:42 2006 -0600
+
+ Fixed -outformat pdf for papersizes like a4 with nonintegral bp dimensions.
+
+ Improve performance by avoiding unnecessary flushing of output stream.
+
+commit c8dd84f63624e80aa56b358c21706ada90cc48a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 19 17:24:21 2006 -0600
+
+ Make fft(real[]) a nop when not configured with fftw.
+
+ Handle fft(new real[]) gracefully (returns an empty array).
+
+commit f9b882aa5d5545bed95c271067ed6422339a4543
+Author: Radoslav Marinov <rtm907>
+Date: Fri May 19 10:31:11 2006 -0600
+
+ contour.asy now with guides, supports dashed lines
+
+commit e9f6e6bbed1e61cc3a30f8b9164b8880e3a4a541
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 19 01:09:38 2006 -0600
+
+ Incremented version to 1.06cvs.
+
+commit c6deca9111977391e90151813a05cc2fef788649
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 22:42:16 2006 -0600
+
+ Reduced default authorpen fontsize.
+
+commit daf49b72e56d986b53fcc3ee11ffec4c6114b43c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 22:21:02 2006 -0600
+
+ Added normal argument to Arc.
+
+ Standardized arguments to revolution.
+
+ Updated documentation and examples.
+
+commit 79d6d9730dedab0fca16651ce2c0b1f61bc97405
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 13:43:12 2006 -0600
+
+ Added determinant test.
+
+commit 4aa6fc20712ea101dc4d5a34d359d2a0be19b83f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 13:04:15 2006 -0600
+
+ Removed unnormalized epsilon from determinant.
+
+commit 5eda890c8fc4f08d4fade2e20b773bf47cc9aa31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 12:48:10 2006 -0600
+
+ Updated documentation: real a[] now constructs internal functions of real[].
+
+commit 56f80f8eaa6efa7e5b313771197a6b8dd43a1da6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu May 18 12:17:29 2006 -0600
+
+ addOps for int x[] now implemented.
+
+commit 81e637b56a0bf064ade66eb783946ac464233fcd
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu May 18 11:55:07 2006 -0600
+
+ Now add operations for all variable declarations of new arrays and functions.
+ Removed old code.
+
+commit 1170b2cd6b0f1e2b5f4bbf6ab352a764a3aa32c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 04:14:06 2006 -0600
+
+ Explicitly document -u stepping=true.
+
+commit 2fda9b050cd48bed37c4e253c8ad4a1a6a7cb6d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 03:53:10 2006 -0600
+
+ Fixed cxx warning.
+
+commit 8dd3e7faa0ffc2beb933f5eb8bc2b9aa0b34ab0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 03:29:48 2006 -0600
+
+ Implemented revolution struct in solid.asy for constructing, drawing, and
+ filling surfaces of revolution.
+
+ Added surfaces of revolution examples.
+
+ Ported precontrol and postcontrol resolution fixes to three.asy.
+
+ Added 3D version of relpoint functions.
+
+ Fixed normal(path3).
+
+ Updated documentation.
+
+commit 08ebff5c9945585178e6a5a23648a297f9f8bb20
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 18 01:03:04 2006 -0600
+
+ Added example showing how to scale only selective dimensions.
+
+commit d9a8fc9d1ce7884a95320fe1fbcd8bf4f83dcddd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 17 23:44:26 2006 -0600
+
+ Documented how to call Asymptote from Python.
+
+commit 17e102d2ca2835dd8bfb691d4e483a4630288271
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 17 23:07:49 2006 -0600
+
+ Make location of slidedemo explicit.
+
+commit fbe3ea488a0e1f27effe2111057103dccd0d6052
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 17 22:46:32 2006 -0600
+
+ Reduce infinity to avoid floating point exceptions with --- operator.
+
+commit 93dcd881e5b4476ffe07fbf4e7a0ee9199dcf625
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 17 22:44:19 2006 -0600
+
+ Allow stepping to be enabled from the command line: -u stepping=true.
+
+commit 5967b8c34f40538a7aa760c7549eef2e2ae74aa1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 17 22:39:49 2006 -0600
+
+ Added y and z autoscale arguments to scale().
+
+commit 383ad013af16211ec6fabeb8c8538d0dd2516f9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 17 22:15:27 2006 -0600
+
+ Added example showing how to label an axis with an arbitrary string.
+
+commit 14eb8a4d6ecf031dd09ae712eab638dca6aa75fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 16 01:40:57 2006 -0600
+
+ Improved test diagnostics by using internal assert(bool) function.
+
+commit 1a68bcd0d76c42dc0e9aae4b9b94be57f1612e53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 16 01:37:55 2006 -0600
+
+ Added assert(bool) function.
+
+commit 6db26721184b3d768d88c67d81cda0483f69ea35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 16 01:36:19 2006 -0600
+
+ Fixed cubicroots when R=0.
+
+commit 1e633ec2b48093ddebc77de17300b12fcce7d01d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 16 01:34:48 2006 -0600
+
+ Flush output stream on errors.
+
+commit a0feb5badead646e4e5ced4b9ac5397fa1986f8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 15 00:45:38 2006 -0600
+
+ Added offset argument to linetype.
+
+commit 417c387ca3207020f2e6118773b2492f8ce62d62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 14 14:54:35 2006 -0600
+
+ Remove unused argument.
+
+commit 6eae114c9ac74bd8e154dc097c73e11ba5571b76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 14 14:48:42 2006 -0600
+
+ Move GSL functions into a separate module named gsl.
+
+commit f3c570f260ea6bdd68366d262203160d58d15394
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 14 14:37:04 2006 -0600
+
+ Formatting.
+
+commit 3d57dc5a3d4e2aacce91088294f13115b2e54d1f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 14 11:29:08 2006 -0600
+
+ Removed aclocal and autoconf since Asymptote is distributed with configure.
+
+commit c4a7ec511adaed6a1bc966de48503a10c943ba7e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat May 13 12:33:45 2006 -0600
+
+ Moved addOps for types to builtin.cc. Added support for builtin structures.
+
+commit 953b39d4f44cf9a23f623c0f01c26451b557aa95
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat May 13 09:52:19 2006 -0600
+
+ Fixed typo.
+
+commit b232db20cc3cc1a9aafcb1030f14ee86f1750de4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 13 00:53:22 2006 -0600
+
+ Removed quiet(bool) in favour of explicit setting.
+
+commit 44aa19ad3651fde5c45309d96f216d1a35020e13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 13 00:20:07 2006 -0600
+
+ Updated man page.
+
+commit 839c7735f217563d6e0a5e2d0c7a7ed493c30f64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 12 23:59:05 2006 -0600
+
+ Added RPM spec file, courtesy of Jose Pedro Oliveira.
+
+commit 45f04ae52790e8b3adc9a9e6f07a6d55c239f8e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 12 23:25:56 2006 -0600
+
+ Moved asy.vim and asy-mode.el back to /usr/local/share/asymptote, where they
+ really belong. Also put asymptote.py here.
+
+ Revert default asymptote documentation directory to
+ /usr/local/share/doc/asymptote (removed recently introduced version
+ dependency, which made no sense since the system directory doesn't depend
+ on a version number either: version checking is done in plain.asy).
+
+ Updated documentation (including new sourceforge cvs instructions).
+
+commit dfed1750cf52db95f0d38ed3e031565c37213bbb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 12 22:55:57 2006 -0600
+
+ Make Arc use degrees rather than radians.
+
+commit 411fe8ba53952d16e4d27d6de5d4325fd7d53872
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 12 22:54:38 2006 -0600
+
+ Fixed obliqueX and obliqueY camera positions.
+
+ Make obliqueZ a synonym for oblique.
+
+ Ignore spurious errors from longitude.
+
+ Added missing (optional) normal argument to arc call.
+
+commit e01588feebf9585c9da7fbfe791f0d395b8da16c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 12 22:47:41 2006 -0600
+
+ Added clipping margin to unfill.
+
+commit c273826c1a2281a543103d2f463b1fd72065552b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 12 22:46:54 2006 -0600
+
+ Added Andy's getApplication bug fix.
+
+commit a4d1dd6e26a7384fe0fb8b1d987cd6bf930f164b
+Author: Radoslav Marinov <rtm907>
+Date: Fri May 12 15:50:17 2006 -0600
+
+ lines of length <80. handles multiple contour lines at once for efficiency.
+
+commit 186767d6435ce06ef92b6fc0c119615d2ab6842e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 12 15:03:59 2006 -0600
+
+ Renamed pen argument.
+
+commit baa95c93a27afef3f53b527e2e5a62d5af3fa4cb
+Author: Radoslav Marinov <rtm907>
+Date: Fri May 12 13:05:34 2006 -0600
+
+ added basic contouring routine
+
+commit cd72b2da3607d98aed4546caa20d6d21d717cd31
+Author: Radoslav Marinov <rtm907>
+Date: Fri May 12 12:58:51 2006 -0600
+
+ added general determinant
+
+commit b1a94105507b3e256c7d9b0aef4bc41dc53bd6dc
+Author: Steve Melenchuk <smelenchuk@gmail.com>
+Date: Fri May 12 10:40:23 2006 -0600
+
+ More tests; these ones relate to transforms.
+
+commit 6d23e63e5dd82740f7865253f6262023ca7181a7
+Author: Steve Melenchuk <smelenchuk@gmail.com>
+Date: Fri May 12 10:19:44 2006 -0600
+
+ Beginning to expand the arithmetic test. Now classifying as related to what type of data the tests are working with; each file contains several tests related to that type of data.
+
+commit c5273d2efcbd68b4a733fc70856cf62bd2b55e92
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 8 02:33:45 2006 -0600
+
+ Fixed quiet(bool); improve settings diagnostic.
+
+commit 0a26a23c326f69e2edcec6c0afbb1b0e09187baf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 8 01:50:15 2006 -0600
+
+ Removed Degrees and Longitude in favour of degrees(warn=false) and Longitude(warn=false).
+
+ Moved Sin, Cos, Tan, aSin, aCos, and aTan to runtime.in.
+
+ Renamed double to real in runtime.in for compatibility with asy code.
+
+ Moved examples to subdirectory of documentation directory.
+
+ Don't automatically strip binary when installing.
+
+ Generalized DESTDIR support.
+
+ Documented optional packages in INSTALL.
+
+commit b0dbd1691f873f66d2219275b176928bebf5ec13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 8 01:36:48 2006 -0600
+
+ In dash adjustment, always respect scaling to penwidth (when requested)
+ and draw terminator if close to arclength.
+
+commit 759d070b0ebf96f1464095f835c531c946527e9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 6 21:39:22 2006 -0600
+
+ Improve ambiguous function signature diagnostics.
+
+commit 1241c3dc9554391c43910996334988d9e73816a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 6 21:35:50 2006 -0600
+
+ Turn of listvariables while reading config files.
+
+commit 41c68567f03d276a2dbacdc1c6cd389e9d3dc44b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 6 04:30:43 2006 -0600
+
+ Added Sierpinski gasket example.
+
+commit 8a12ce233a5ec25e336b04538ac1b60488e667b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 5 03:06:16 2006 -0600
+
+ Added obligueY projection.
+
+commit 5d68d40841e9d2f12fc0e1ea1287e5349b92a94c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 2 09:59:46 2006 -0600
+
+ Removed oneFileView setting in favour of a new setting multipleView, under
+ control of batchView.
+
+ Renamed pagewidth/pageheight to paperwidth/paperheight to agree with
+ documentation.
+
+ Handle cases where paperwidth or paperheight are smaller than corresponding
+ picture dimensions.
+
+ Handle nonstandard paper sizes when producing pdf files.
+
+commit 04789d6abd0fc17be052e915edb297d2341ec45b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 2 06:27:12 2006 -0600
+
+ Added realDigits (DBL_DIG).
+
+commit 86c2dd9a05adf698ab7a7095ac332511b5a8b3c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 1 21:50:09 2006 -0600
+
+ Added string string(real x, int digits) routine to cast a real to a string
+ using precision digits in the C locale.
+
+ Use string(real x, int digits) instead of the locale-dependent format
+ function for postscript patterns.
+
+commit c2508a8c0413f0ddaae21617f48867ae70c4f54c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 29 07:37:10 2006 -0600
+
+ Fixed rotate(real angle, triple u, triple v) when u != 0.
+
+commit 3b962333a9e1eb767ffdb611926a5078d381cd67
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 28 08:08:24 2006 -0600
+
+ Added obliqueX projection.
+
+commit 44d07a1770b97dffacbb7a7cf854e1e71c631500
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 28 07:51:59 2006 -0600
+
+ Moved fftw header check back to original location.
+
+commit 8e8d7c47f290721fde640401472f93ee17022a0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 28 06:51:52 2006 -0600
+
+ Added missing space after -lgc; moved fftw header checks to header section.
+
+commit b567c83e58107d42686526be3f9c7365535f1b52
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 25 19:29:36 2006 -0600
+
+ Apply dvips bounding box fuzz even when producing pdf format.
+
+commit 975d6a331bdb381b683cc2ce50a6130d69b2fc63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 25 19:24:53 2006 -0600
+
+ Fixed argument reversal in signature of one of the add routines.
+
+commit 8c636e3bb19e6e72178e35c44aa0e4f1f58f10ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 24 02:01:16 2006 -0600
+
+ Incremented version to 1.05cvs.
+
+commit f395220719b1e90ba1005e92f11c97ae43aa3bab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 24 00:42:48 2006 -0600
+
+ Fixed cxx warnings.
+
+commit 26f537049d2cc02c8e0db39d532c19806741b189
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 24 00:37:11 2006 -0600
+
+ Removed unused variable.
+
+commit d1b4f19de875de4a717f35670cf1c6ad95b61c06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 24 00:03:05 2006 -0600
+
+ Move missing file flowchart.asy to correct directory.
+
+commit b511ab40d7775365e2771c8222d568378dcda35d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 23 23:53:36 2006 -0600
+
+ Make wce work even if configured with GSL library.
+
+ Abort make if check fails.
+
+commit 7e1867eda3a4326131df1c34cb57ede404a4296a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 23 23:39:25 2006 -0600
+
+ Untabified.
+
+commit e22225fe83c49469134b3e57082d798d47060cce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 23 23:33:26 2006 -0600
+
+ Check also if first and second points are uncontrolled duplicates.
+
+commit 472aad1e896f59ec2e75b710412d2c08593b04e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 23 23:26:20 2006 -0600
+
+ Added parametric functions that accept an arbitrary sampling function.
+
+commit 959163958f72b505a48fc7c2a9b1f187384d4b01
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 23 11:56:09 2006 -0600
+
+ Updated poster example to use slide.asy.
+
+commit 95f24100042c4828f5dcb882d1f751f603cd91fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 23 10:27:25 2006 -0600
+
+ Change user variable to a string.
+
+ Document how arbitrary Asymptote code can be specified on the command line.
+
+commit 9dbf4485550c201dd3e81c96c74e90d329ca06ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 23 01:24:45 2006 -0600
+
+ Added optional background and multiple figures to slide package.
+
+ Updated documentation.
+
+commit 31b409d56aae03e957281fa004fbec0820f20796
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 22 23:35:38 2006 -0600
+
+ Replace infinities in userMax and userMin with boolean flags.
+
+commit 6314d3256681fd9e23db836413a4faa80d21b09c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 22 21:33:29 2006 -0600
+
+ Increased bounding box fuzz.
+
+commit 31b43d80995b29816e58a277e461b266e2c5d9fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 22 21:26:28 2006 -0600
+
+ Updated call to add in slide.asy.
+
+ Implemented fixedscaling(picture, pair min, pair max, pen) routine for
+ using a fixed scaling to map user coordinates in box(min,max) to the
+ desired picture size.
+
+ Added UpsideDown orientation.
+
+ Moved min and max of a real argument list to constants.asy.
+
+ Always pass explicit pageWidth and pageHeight arguments to dvips rather
+ than using the papertype.
+
+commit 6d070db2dbe5e1dd3b510d1542b391b68e205278
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 22 05:03:27 2006 -0600
+
+ Fixed dvips bounding box.
+
+ Added texreset function to reset tex environment.
+
+commit a8d0b5c21e918a3fecbc3ab3957685f64640cd88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 21 10:47:35 2006 -0600
+
+ Added general purpose real user command-line option.
+
+ Legend skip is now based on the actual legend entry height, rather than on the
+ fontsize.
+
+commit 7861589644a7a8180700b47f4e5f8630c99f6c99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 21 09:52:06 2006 -0600
+
+ Added and documented texcolors and x11colors.
+
+commit 6963a617979e355beb5096ac7aacb709fa77da15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 20 23:59:59 2006 -0600
+
+ Improved linetype adjustment to arclength for short segments.
+
+ Added optional boolean adjust argument to linetype to allow one to disable
+ linetype adjustment.
+
+commit 2821a5e49788fb4bf125b21f7994fdb066149144
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 20 20:48:40 2006 -0600
+
+ Documented pair Scale(picture pic=currentpicture, pair z) function for
+ plotting in unscaled (graph) coordinates.
+
+ Improved documentation of add for pictures and frames.
+
+commit a1a64c99b841d520289ff3ba05602ef4c9346c3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 19 23:19:03 2006 -0600
+
+ Changed add and attach to take arguments in the same order as label,
+ renaming "origin" to "position" and "dir" to "align".
+
+ Removed the align argument of legend, which really belongs in the
+ add/attach command.
+
+commit 6b07436f331c27ccf302e70b40d0cc6b3ae1644d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 19 22:54:16 2006 -0600
+
+ Fixed arrow alignment.
+
+commit ae71d0ff534aaa598eeecc4b2328f998e1bb3d12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 19 18:42:40 2006 -0600
+
+ Fixed alignment of postscript and tex layers by working around failure of
+ includegraphics command (from LaTeX graphicx package) to respect
+ HiResBoundingBox.
+
+commit 7e4cec0e907ae3018a629f29f68dacf583b92e75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 19 02:17:56 2006 -0600
+
+ Added Python module to allow access to Asymptote commands.
+
+commit d4133c9184e4d76ddb0a6ea683c00c83f61178a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 17 02:00:50 2006 -0600
+
+ Fixed clipping of remote labels near frame boundary by unfill.
+
+commit 67902a31a40b1959277d5087d6f67844d105d745
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 17 01:38:57 2006 -0600
+
+ Improved alignment of tex and postscript layers.
+
+commit 77a8a3526ebcaf4a06cace29826155cdaf383531
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Apr 16 16:10:47 2006 -0600
+
+ Added permission checking for types.
+
+commit a9d41b7349380bc7028e77a684f4d8515e45d782
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 14 15:19:52 2006 -0600
+
+ Make format="%" suppress tick labels for logarithmic axis.
+
+commit 9de768b204c984e75d21a5470f37fdcfef0e791d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 14 02:20:31 2006 -0600
+
+ Change standard name for salmon colour to lightred.
+
+commit 9ed799f848b51cb572112768198ce8282ed65ef6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 14 02:13:08 2006 -0600
+
+ Fixed tension atleast (broken in autogenerated code since 0.96).
+
+commit e414d6dd897dd359b2517e7868424f0c9a89cf17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 13 08:15:24 2006 -0600
+
+ Renamed "strong" colors to "heavy".
+
+commit 9537c34858bb44219b90550cf78e9b8a7c2a8c4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 13 01:12:55 2006 -0600
+
+ Display named colours.
+
+commit 3a46a1a959f6dca2eb3d3ba701a0f080655741d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 13 00:53:19 2006 -0600
+
+ Documented and systematized named colours.
+
+commit a61d435ad972ab673ce8338765a3a4d7ac434d13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 12 21:08:55 2006 -0600
+
+ Respect orientation.
+
+commit fe6173ecc4dc6b212b32e7443e1e59a67ed8ef7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 12 01:36:26 2006 -0600
+
+ Improved implementation of slide.asy.
+
+ Accept label(frame, Label).
+
+commit 2101d2a6059ac6c6333689662bbf2ebcdebd645f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 10 21:01:47 2006 -0600
+
+ Added subitem and automatic slide advance on overflow.
+
+commit c6ff6449ce3c1907f130d106a86fee9ec88ba74a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 10 16:15:55 2006 -0600
+
+ Slide presentation package.
+
+commit 1a2be9b262fa689fe39ed2fafbde8d8dd1f34c11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 10 15:42:51 2006 -0600
+
+ Added default orientation variable (initially set to Portrait).
+
+ Added custom pagewidth and pageheight settings.
+
+ Moved transforms to runtime.in and Label.asy.
+
+ Added tex usepackage(string) convenience routine.
+
+commit d7c889c669eb4bded0cec30ee293b336f500ef94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 10 15:38:02 2006 -0600
+
+ Indicated default option values in man page summary.
+
+commit 1a6d1d682d620f1d29bc53a0ee69f8ba6ef81b80
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 15:00:12 2006 -0600
+
+ Added DESTDIR support: make DESTDIR=DIR will prepend DIR to the
+ installation directories (intended as a temporary location to facilitate
+ the build process only).
+
+ Added -p option to install (and -m 755 to install asy and install xasy).
+
+commit 376cc0d3b0dc34f90d810be20a749dbb345ad88c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 14:51:32 2006 -0600
+
+ Fixed name of gsl header in message.
+
+commit 56c59eeb1698fdb88c28416048f0b6b47a924e0a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 10:13:40 2006 -0600
+
+ In tick bounds estimate, don't warn about unbounded picture scaling.
+
+commit 019fffe374c0564d5a640c7d0bd84f097486a2ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 01:10:31 2006 -0600
+
+ Added selected special functions from GNU scientific library, when
+ available (additional special functions can easily be added, on request).
+
+commit fed4cd36ff02754c21e628c4911ec5e0dc56cb6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 00:42:37 2006 -0600
+
+ Added Ticks specifier that draws ticks on both sides of path.
+
+ Fixed miscellaneous errors in the documentation.
+
+commit 763c0584aed043adc4439cbb479b37fe110b928c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 00:39:32 2006 -0600
+
+ Renamed zeta to unityroot for clarity (and to avoid confusion with Riemann
+ zeta function).
+
+commit fe98b1be9e75b114007f196618347a12159df32a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 00:37:42 2006 -0600
+
+ Moved newpage() routine to shipout().
+
+commit bc27d517da082381cd412dfffd7a0d0f2876bf1b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 00:36:59 2006 -0600
+
+ Added real lineskip() routine (returns lineskip of currentpen).
+
+commit e8233efdc79fcc794af3ef00caf0d452b60f79a1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 00:35:33 2006 -0600
+
+ Fix name of fontsize lineskip argument.
+
+commit 477a3f338e05e13d53302eeb2dcf7204e49dc85c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 9 00:34:30 2006 -0600
+
+ Remove reliance of replacement readline routine on strdup.
+
+commit ce6dcb4d7b09e071875afd1fc1862ad616debc26
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 6 08:05:17 2006 -0600
+
+ Use turn-on-font-lock for Xemacs.
+
+commit a4256b4b6849a2656787c5ae4a37717347f0405b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 5 21:29:56 2006 -0600
+
+ Make asy-mode.el ignore global-font-lock-mode for Xemacs.
+
+commit 1f6a7d9232e47d07585eef364e48588638f60511
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 5 21:24:09 2006 -0600
+
+ Added locale support and ', I, and F format specifiers.
+
+ Moved miscellaneous settings code from main.cc to settings.cc.
+
+ Added default settings to option summary; identity command-line only options.
+
+ Updated documentation.
+
+commit effc2ac2e06f4bce1a32771a206cea8a25b0fe60
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 5 21:20:58 2006 -0600
+
+ Improved picture sizing diagnostics.
+
+ Added max(picture pic=currentpicture) and min(picture pic=currentpicture)
+ functions.
+
+ Added pair truepoint(picture pic=currentpicture, pair dir) function that
+ works like point but uses the actual picture size instead of userMin and
+ userMax members.
+
+commit 1ca3b76cc03eeb6f6ce650efdcc05304b7acf096
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 5 21:18:34 2006 -0600
+
+ Replace identity() with better approximation pic.calculateTransform() in
+ axis picture bounds calculation.
+
+commit 2828a2fc752611197c8da2a888f7f9e163e423a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 5 21:17:03 2006 -0600
+
+ Make colorPen[] and monoPen[] public.
+
+commit 3d952fa6b146e227f8d603d75409ef5d86df95d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 5 21:16:10 2006 -0600
+
+ Fixed typos in comments.
+
+commit 0f448702572cd3980c3f235c1cca17a3e2124a68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 5 20:22:16 2006 -0600
+
+ Incremented version to 1.04cvs.
+
+commit 9c25ca1878971b9309e70501e5c6821f1cee9573
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 30 00:08:56 2006 -0600
+
+ Added Degrees function; like degrees(pair) but returns 0 for (0,0) argument.
+
+ Added minbound and maxbound functions for triples.
+
+ Moved minbound, maxbound, and Longitude functions to runtime code.
+
+ Added min(guide3[]) and max(guide3[]) functions.
+
+ For convenience added xaxis(triple,real) functions, etc.
+
+ Added solid geometry package with cylinder routines.
+
+ Updated documentation.
+
+commit e2d01d7b8bcaaea02991c16da1ef73008d31c862
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 29 23:27:11 2006 -0600
+
+ Added limit maxIntersectCount=100000 on maximum number of calls to
+ intersectcubics per cubic segment.
+
+commit ed639fd2d9e3514f3b9bec4640ddad84a74ef9e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 28 13:33:39 2006 -0600
+
+ Removed TODO item regarding extending runnable-at-a-time mode to inner
+ code levels as this is no longer needed.
+
+commit 0a94ea6be653be7815838c8027fb1be41aa8a818
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 27 02:13:26 2006 -0600
+
+ Fixed memory leak in interactive mode by using an implementation of reset
+ that is closer to the environment reset used between multiple file runs.
+
+commit 8d01320484ef94f77b7b93d8741742d6732558a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 25 23:15:50 2006 -0600
+
+ Fixed indentation.
+
+commit 141078fde83363b07a92b23f652f044aa2854779
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 25 23:14:21 2006 -0600
+
+ Fixed typos.
+
+commit 9e7ebe0d9210cae262a1f2baeb845f8b7e7e6d5c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 25 11:25:37 2006 -0600
+
+ Updated CJK documentation.
+
+commit 74c06d44469b037505371944dd4c3059b16859b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 24 22:38:01 2006 -0600
+
+ Added real fontsize() routine.
+
+ Documented real fontsize(pen p=currentpen).
+
+ Documented use of CJK fonts.
+
+commit 5eac404efdabd96157073d429bdf888a0a73ccd9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 20 22:48:46 2006 -0600
+
+ Implemented interactive mode (without command-line editing and history) even
+ in absence of readline library.
+
+ Made minor change to System diagnostic messages.
+
+ Changed invert: triple invert(pair z, triple normal, triple point) projects
+ onto the plane perpendicular to normal and passing through point.
+
+ Updated Debian URL.
+
+commit 80baab724a0b03a9582d20dfc4e081c1fea701b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 19 09:17:07 2006 -0600
+
+ Added function triple invert(pair v, real z, projection P=currentprojection)
+ to map v onto (x,y,z) by inverting the projection P onto a constant z plane.
+
+ Minor documentation updates.
+
+commit adf5582b62c1ce0dbda58ded884ff8e8ddc6bd03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 17 00:10:58 2006 -0600
+
+ Support compilation under gcc-4.1.0.
+
+commit ecc6ca00d162c18c264ce94307d6263fc0424d99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 14 22:36:32 2006 -0600
+
+ Fixed return type of three-dimensional intersectionpoint routines.
+
+commit 5ad4c367c698ffd46b95cfdd279472d27a50d32e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 12 14:21:27 2006 -0600
+
+ Incremented version to 1.03cvs.
+
+commit d2aa165bc9ed6ca59b0d3251ce36ab769abb59cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 12 12:27:03 2006 -0600
+
+ Fixed surface lighting colours; respect projection argument.
+
+ Removed test diagnostic.
+
+commit dce74caad4372be9f26b9c8460f1d38d705651e6
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Mar 12 12:17:32 2006 -0600
+
+ Added a .ls file to check the presence of large output files before they are
+ deleted.
+
+commit e3067cdb667a0c26476544c2454c3a602eb5f336
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 12 10:05:51 2006 -0600
+
+ Avoid need for single quotes around path settings in MSWINDOWS.
+
+ Fix configuration diagnostics.
+
+commit 9e4c90c4a873082d063e7d8ec4e9c762c36c8be9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 11 23:03:49 2006 -0600
+
+ Documented how to install in alternate locations under MSDOS.
+
+ Fixed typo in configuration instructions.
+
+commit 4b900d75f545a276a637568172024c292120e494
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 11 17:33:51 2006 -0600
+
+ Simplified example.
+
+commit 5479aac708d4e8b7ba7839da2bad6e2162b39de8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 11 17:16:25 2006 -0600
+
+ Implemented surface lighting and example of sinc function.
+
+ Changed signature of subsampled surface routine (argument nsub now preceeds
+ pairs a and b).
+
+ Changed light.init constructor into
+ light(triple source, shadefcn shade=defaultshade).
+
+ Added cast from triple to light.
+
+ Made currentlight public; added nolight variable.
+
+ Renamed projectXY to xypart.
+
+ Added XY() and XYZ() members to bbox3.
+
+commit 347ba3f77a171c46a4a47f86e9e355e6a51d86f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 11 16:39:34 2006 -0600
+
+ Fixed axis label alignment when sign=-1.
+
+commit 430f5c79d6160b8129e3dbc8110107b5d7abd5be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 10 22:18:54 2006 -0600
+
+ Removed pstoedit patches (included in pstoedit-3.44); updated documentation.
+
+commit 68bbdf1c1e0a8c77f16277ea5b1641fbaead5d4d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 10 13:19:57 2006 -0600
+
+ Allow make to inherit LDFLAGS from configure.
+
+ Allow and document installation without root privileges.
+
+ Document configuring to search for includes and libraries in nonstandard
+ locations.
+
+commit 7eeecf79bea1d6c776ec748a77f5b18175cd005f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 10 00:19:06 2006 -0600
+
+ Updated configuration file documentation.
+
+commit 4dd2aa63b26b60506a2be4e2979ede3b4d840361
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 9 21:54:33 2006 -0600
+
+ Catch errors thrown by parser while reading configuration file.
+
+ Recompute search path after reading configuration files and command-line
+ options in case dir was changed.
+
+ Move MSWindows .asy initialization directory to %USERPROFILE%.
+
+commit 3ae7effa9e304cb6fdc44d53e77d9b9b0929c507
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 7 13:37:44 2006 -0600
+
+ Fixed type of randMax.
+
+commit c0c45887b143899563cac08bf41ccd125e097b50
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 7 04:01:26 2006 -0600
+
+ Updated pstoedit patch.
+
+commit 24f8371b56dace63c14bb05de5f845041e70d657
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 6 20:29:18 2006 -0600
+
+ Incremented version to 1.02cvs.
+
+commit fff59e55f51bf1b131c0158612f0c14a9ccad237
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 6 18:23:18 2006 -0600
+
+ Fixed bug in surface plot of a matrix.
+
+commit 26a3c93d4252ffed2f35d77596236078638ef05c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 6 14:58:35 2006 -0600
+
+ Incremented version to 1.01cvs.
+
+commit 547ee643099012bca1840706696a6aafb34de4da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 6 10:33:54 2006 -0600
+
+ Workaround broken GNU readline/history library on MacOS.
+
+commit 11f8e47b6ca52d30122d5314030876436d493627
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 6 01:10:54 2006 -0600
+
+ Fixed cxx warning messages.
+
+commit 5405aad4557d43e550de77b5715c5fbd6b9a1d65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 6 00:19:09 2006 -0600
+
+ Moved detailed discussion of growing list of base modules closer to the end
+ of the documentation.
+
+commit 0958bf9aa26afda543a765aaea2ff7c519ea2b54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 5 23:52:10 2006 -0600
+
+ Updated to use gc6.7 by default.
+
+ Added RadialShade filltype.
+
+commit 5b4e1a2b86ad323af68a5419cebb6bf3a6f3b6b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 5 23:03:49 2006 -0600
+
+ Remove blank legend entries.
+
+commit 413031e4512016eba1ee554df33381d0d7a9ffa2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 5 22:46:24 2006 -0600
+
+ Fixed pen bounds (too large by a factor of 2).
+
+commit 77f0938b38433a0283f80604ec9aaa99efa076c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 5 21:37:48 2006 -0600
+
+ Fixed transformation of palette bar.
+
+commit f294a74a102e058defddf05bd3206fdb8de086fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 5 19:45:09 2006 -0600
+
+ Removed empty picture check in xlimits and ylimits.
+
+commit fc66e7bb009b8995b0d64a7393cbe0373e6466c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 5 19:02:27 2006 -0600
+
+ Moved linear solve and matrix inversion to C++ code; simplified memory
+ allocation in tridiagonal.
+
+ Added seek and tell functions for positioning input files.
+
+ Make images transform properly.
+
+ Make legend argument to draw a Label type (currently only the string and pen
+ members are used). Added length and skip arguments to frame legend(...).
+
+ Removed side effects from eol(file).
+
+commit b130fda35b1a52f235a195dd3de0dd7c4732aad9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 4 22:25:50 2006 -0600
+
+ Generate correct #line comments.
+
+commit 557106356ca05abe85095d699ee581925a5ed58e
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Mar 4 17:17:55 2006 -0600
+
+ Log the stdout and stderr of the asy process.
+
+ Changed the -inlinetex option to -keep so that the calls to external programs
+ (eg. latex and convert) can be diffed.
+
+commit 4d1efb04f2b068faf4bcad86e224ff3d762b547c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Mar 4 16:47:12 2006 -0600
+
+ Now delete texput.log when the pipe to the tex process is closed (to ensure its
+ deletion with the --inlinetex option). Also delete texput.aux.
+
+commit c16e8f35093571eadb9fc2ad97c8e122dcdf6051
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 3 09:56:54 2006 -0600
+
+ Fixed bug in pivot vectorization in solve.
+
+commit 2696a99ffefcb7e02e7f074ed271433d66053d8d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Mar 2 13:46:57 2006 -0600
+
+ Initial check-in of output testing.
+
+commit 1737069935134cd721162e02bd7ddf0026ca9677
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 1 13:02:39 2006 -0600
+
+ Added INCL for enable-gc=system.
+
+commit 4ef432c6b3a4a87c62d1830216944a29cffb107b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 27 01:54:06 2006 -0600
+
+ Renamed includegraphics to graphic.
+
+ Added embed module to interface with LaTeX movie15 package for embedding
+ movies, sounds and 3D objects into a PDF file.
+
+ Don't attempt to resize unbounded pictures.
+
+ Output LaTeX pipe diagnostics even when verbose <= 1.
+
+ Added \begin{document} to LaTeX pipe.
+
+commit fe1a3c9b71a9977eb5036bb6caa1e022d412bf0c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 26 22:59:42 2006 -0600
+
+ Added poster example.
+
+commit f1031a708321e2a4ee4cb9a977bd7eafd44ce656
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 19 20:59:50 2006 -0600
+
+ Add configuration dir to search path; search for configuration file in
+ standard search paths (in usual order).
+
+ Remember defaultpen set in configuration file.
+
+commit c65d1910f982db63917865e620b63ffedb60f817
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 19 11:03:00 2006 -0600
+
+ Always draw arrows with solid linetype.
+
+commit 22e1d9e8edfaf13b75397d582984e57d28673154
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 18 13:31:50 2006 -0600
+
+ Updated MSDOS default of gs8.51 to gs8.53.
+
+ Changed default for xlimits and ylimits to NoCrop.
+
+ Work around unused variable warning messages when XDR support is disabled.
+
+ Cleaned up error calls.
+
+ Updated documentation.
+
+commit 9121a897689e7a165f4d07d74791cf9065bae82f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 17 22:17:15 2006 -0600
+
+ Added missing $(GCLIBS) dependency.
+
+commit d1dd9491dfd9e1de33175474104cd258c855a4b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 17 20:57:33 2006 -0600
+
+ Added camp.tab.h entry again.
+
+commit 44592176ab6ea490b6263f0db7df1537739467ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 8 12:45:48 2006 -0600
+
+ Removed +solid from Fill and NoFill.
+
+commit 46e59ad7cc4837635c0139884318425958e7f31b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 8 10:06:36 2006 -0600
+
+ Added missing xpart, ypart, zpart functions for triples.
+
+commit 5160bfc61c05011c6faf32e68dc0c3d43c8abb01
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 7 23:13:08 2006 -0600
+
+ Fixed reversed image dimensions for colour density plots.
+
+commit e2d69c4df983d930fba6dedcef4cfcda33902415
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 7 23:06:39 2006 -0600
+
+ Added missing xpart and ypart functions.
+
+commit b267a7282f95034c91aafe770836c5bf5c1250b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 6 01:58:25 2006 -0600
+
+ Signal an error if write to final output file fails.
+
+ Removed "camp: " from camp error messages for brevity.
+
+commit cee2eadadeb9b24b390f6891d44b9b80b57b0654
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 28 22:32:32 2006 -0600
+
+ Added link to Dario Teixeira's Asymptote and LaTeX Integration Guide.
+
+commit d8f583f04cab7bf9f726240b4883765437c9aa64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 28 20:43:37 2006 -0600
+
+ Added file prefix option to animate and merge.
+
+commit 7d50f266a6f64308baf51883375b8a7d3f9e64eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 28 04:25:25 2006 -0600
+
+ Added index entries.
+
+commit 4a735cd696ce941e666a11ae057a32906a0a89d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 28 00:28:16 2006 -0600
+
+ Allow format("%",1).
+
+commit c24db86c95be49eb723e48bb6c941448a12452f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 28 00:04:49 2006 -0600
+
+ Set tickMin to a and tickMax to b if Step is 0.
+
+commit 04de94e2035c9de5222e4d4069922d2abc36da91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 17 14:17:27 2006 -0600
+
+ Added check for empty picture in xlimits and ylimits.
+
+commit 712b5eb0a930b2e8adc56a57319b324ee0d14199
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 17 14:12:17 2006 -0600
+
+ Better dependency tracking.
+
+ Removed MSDOS compiler flag in favour of __CYGWIN__. This will make cygwin
+ defaults identical with those under MSDOS (outside of cygwin).
+
+commit f3922a443674409b7f13bf7e29e0754750893b30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 17 01:36:01 2006 -0600
+
+ Fixed cxx warning.
+
+commit 4fc12570232e81d3ec0b574836a8b1f5dc664ebf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 17 00:45:28 2006 -0600
+
+ Added Tom's alternative way of making runtime.pl not update runtime.h.
+
+commit 70cb9010affefb9de6368c62e8c0d3c1a83237a9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 14 17:20:05 2006 -0600
+
+ Documented inlinetex mode.
+
+commit 04614dd4dfd09e73f5a43bdbb226de03793b96d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 14 17:10:11 2006 -0600
+
+ Updates to feyman.asy: improved photon line, use align structures.
+
+commit a4578b4562e08e4dbdeaf7cf1972170f3c3756c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 11 00:40:36 2006 -0600
+
+ Added #line directives in runtime.cc.
+
+commit c7e91dd947133af7dba43b3d9a5b71fe9c75c39f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 10 15:18:01 2006 -0600
+
+ Fixed segmentation fault when bad format string is given to format.
+
+ Fixed cast: (pair) "1".
+
+commit e231da91a761157ec0b86125bca4cbf99e5d5606
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jan 6 22:57:38 2006 -0600
+
+ Added transform3 multiplication (aliased from math).
+
+commit b5f5b26af6060cadd9d7a5f32eed69193300508c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 3 23:45:46 2006 -0600
+
+ Don't exit interactive mode on EOF (ctrl-d).
+
+ Added tab completion option and default prompt="" to readline.
+
+commit ae727f28ea4b40e5610c4dffa2b7d74b3e80c1be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 3 02:58:20 2006 -0600
+
+ Fixed cxx error.
+
+commit 2967f17cbcffb744634e099c161849a048d5de45
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 3 00:16:01 2006 -0600
+
+ Changed complement to int[] complement(int[] a, int n);
+ this returns the complement of the integer array a in {1,2,...,n}, so that
+ b[complement(a,b.length)] yields the complement of b[a].
+
+commit 169148ba22e45e28894dfb1b645b3b1f323cdc90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 3 00:13:52 2006 -0600
+
+ Removed unused line.
+
+commit 62e1a9441630b5330418480c365585328c08b243
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 2 19:52:58 2006 -0600
+
+ Added interface to GNU readline library to allow editing with history when
+ reading data from stdin. Updated getstring, getreal, etc. in strings.asy to
+ use this new readline function.
+
+ Added complement(int[] a, T[] b) function to return the complement of the
+ integer array a in {1,2,...,b.length}, so that b[complement(a,b)] yields the
+ complement of b[a].
+
+ Generated dataSettings from a templated struct; added intSetting.
+
+ Added historylines option (default is still 1000).
+
+ Added array check to arrayConditional.
+
+ Updated documentation.
+
+commit 11474f0b9840788544f626125735c948364e2341
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 2 19:25:08 2006 -0600
+
+ Formatted.
+
+commit 066db4c7a6e4a16d9b0f3158e56542d1fe479f43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 1 04:41:06 2006 -0600
+
+ Move more initialization code before setOptions.
+
+ Check em in signal handlers.
+
+commit c389e767206e0ab763316088c0703686c896b441
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 31 12:22:58 2005 -0600
+
+ Address compilation problem under MacOS X 10.3.9.
+
+commit 705a8a26aa03b2e8399ed01d357650dbd5b61e8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 31 00:19:29 2005 -0600
+
+ Incremented version to 1.00cvs.
+
+commit 84c319d06b4622c6e5a48b413e9b88ec944ce0c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 23:35:36 2005 -0600
+
+ Minor documentation updates.
+
+commit af29f78f7e05d7c62cbf8200a7e9870a0d76e028
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 23:05:36 2005 -0600
+
+ Added missing (mem::string).
+
+commit ac1ce219f9312b47c56838aff22f05c09776737c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 18:54:53 2005 -0600
+
+ Defer initialization of settingsModule to solve race condition.
+
+commit 12735254c64c16298956a5738284ea5577763068
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 13:21:12 2005 -0600
+
+ Fixed MacOS bus error by initializing GC before calling setOptions.
+
+commit 2c2226a75a8dcf2bd47d0ba0c88b91f8f59af4d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 13:11:10 2005 -0600
+
+ Don't stop running after first error in a runnable if -debug is set.
+
+ Updated wce.
+
+ Documented contributed MacOS X binary.
+
+commit ef8e3257d908ee6e362c52a8daf8345420b194d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 02:56:51 2005 -0600
+
+ Incremented version to 0.99cvs.
+
+commit 5c0a33a6bf4a3a7fc02e993593fb4711c01529cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 02:06:29 2005 -0600
+
+ Minor documentation updates.
+
+commit d2f60e6987dd3f8903161c2a4b5ffacf80ad0110
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 30 01:54:53 2005 -0600
+
+ Fixed compilation problem under g++-3.3.4.
+
+ Change addConstant to use item.
+
+ Search in usual paths for config.asy if ~/.asy/config.asy is not found.
+
+ Convert configuration variable names to lower case.
+
+ Update diagnostics and documentation: emphasize use of configuration
+ variables instead of system environment variables.
+
+commit 936918070c759c2acf207461088e58a98f2d8299
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 29 21:38:05 2005 -0600
+
+ Removed mention of obsolete -t option from documentation, which is no
+ longer required for inline tex mode.
+
+commit 5d8128865deb937def2ac52929df17694269380c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 29 19:52:38 2005 -0600
+
+ Fixed cxx errors.
+
+commit f90cbe0e5f312817be89fea6abb1a243e5e62e9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 29 17:40:42 2005 -0600
+
+ Suppress warning messages when shipping out an empty picture.
+
+commit a23f08d9f83d6c2119c1b0433678ab1a0b2586a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 29 13:01:06 2005 -0600
+
+ Implemented machine constants as variables rather than functions.
+
+ Added ASYMPTOTE_CONFIG environment variable.
+
+ Moved ASYMPTOTE_DIR environment variable to settings.
+
+ Do an initial read of command line in case CONFIG or DIR were specified.
+
+commit fd6fe905598d7c3edb14292f2dd69f8d7c0e9f25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 29 02:32:35 2005 -0600
+
+ Moved ASYMPTOTE_PAPERTYPE to settings.
+
+commit 4a498dd004bc95f45bc018a8c2350b357f48fb34
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Dec 29 01:49:29 2005 -0600
+
+ Moved argument parsing to avoid writing to memory between a fork and an exec.
+
+commit f864cde03b868ef11de14bc9231f0c926d82f737
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 29 01:24:38 2005 -0600
+
+ Moved environment variables into settings.
+
+ Call doConfig before reading command line options.
+
+commit bb0ef295a64fb0c2b0aa6f2ce7ba2ca7a0682f80
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 28 23:43:14 2005 -0600
+
+ Implemented addConstant and pi example.
+
+commit 36becc21b83833cebd9aa9a9d32635eee0847610
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 28 11:16:22 2005 -0600
+
+ Removed ~/.asy/options in favour of ~/.asy/config.asy.
+
+ Add "Including filename" diagostic.
+
+ Fixed localhistory.
+
+ Speed up initialization by turning off autoplain when reading configure file.
+
+ Rename position to align.
+
+ Updated documentation.
+
+commit 5834e1b2207381871eda5557aec935540da9aaf1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 28 01:15:07 2005 -0600
+
+ Fixed verbose flag.
+
+commit c421a124706aee98701afd47f71befae44f1720f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 28 01:10:28 2005 -0600
+
+ Removed -t option, which is no longer needed to produce inline tex code.
+
+ Removed unused settings code.
+
+ Added -nov option.
+
+ Improved formatting of option messages.
+
+ Hide oneFileView and inlinetex (formerly texmode) from help menu.
+
+commit bea64164b4c955599c2ec9c84568e7c73bc1d73c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 26 15:38:04 2005 -0600
+
+ Fixed tick computation in xaxis and yaxis when explicit limits are given.
+
+commit d5bd4bb1e99c842d5902fbce82e08df997ce8b43
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Dec 24 19:15:55 2005 -0600
+
+ Removed the -n, -no option in favour of -blah/-noblah style negations.
+
+commit fd6c9fcdfe15cd2ff5b0d41f9e62fe07918a009c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Dec 24 01:42:42 2005 -0600
+
+ Improved error reporting when parsing command line options
+ Autogenerate -help output.
+
+commit 89e1d51d872b6d47a8e004872d5f2ff47c5f95d8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Dec 23 23:39:56 2005 -0600
+
+ Added a settings module. Re-implemented command line options to modify
+ variables of the settings module. Added refaccess to access C++ variables as
+ Asymptote variables.
+
+commit 999686551a309da198af397405ba458aa344991e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 21 23:22:04 2005 -0600
+
+ Fixed string reads.
+
+commit a04661d02bcbc382904e7bf15548fe898ca45aee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 17 19:12:21 2005 -0600
+
+ Check for cvsmode in ignoreComment.
+
+commit 2bf654dc2f80c34112b47eab1ff3d44b7e793c7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 17 17:29:17 2005 -0600
+
+ Allow comments within 3d data blocks.
+
+commit aa7c73b6b20b5b37993021ea440ff1ac3a597707
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 17 15:26:22 2005 -0600
+
+ Removed writeP in favour of write.
+
+ Stop running after first error in a runnable.
+
+ Standardized write argument names.
+
+commit 8025f7ffdd8c5ef01a9db0112190026060c4bc66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 17 02:17:37 2005 -0600
+
+ Added fonts.
+
+commit 2b74c299f57b3960563c99ad06bd40ba1b15f45d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 17 02:11:45 2005 -0600
+
+ Fixed cxx errors and warning messages.
+
+commit f548d38f981609aacb0a6d48328e2c7c7a40bce1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 17 01:54:31 2005 -0600
+
+ Added type-dependent function and record operators to parent record.
+
+ Cleaned up builtin.cc.
+
+ Moved two- and three-dimensional array min and max functions to C++ code.
+
+ Split plain.asy into many subfiles (using include rather than import for speed).
+
+commit 301f9346339ea8900fa2a3f2cf25fdc00a786c54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 15 14:29:49 2005 -0600
+
+ Allow explicit keywords in autogenerated code.
+
+ Moved default arguments from plain.asy to runtime.in.
+
+ Respect currentpen nib.
+
+commit 96de56b84b0cd1d4d738a23765d299545dadd2ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 15 03:58:25 2005 -0600
+
+ Incremented version to 0.98cvs.
+
+commit 6f306d923970994666cc1a70396929acf74a17d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 15 03:07:14 2005 -0600
+
+ Fixed pen transform bug.
+
+commit 71c43cf70416c59c7912d75006044a5b82d2629b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 15 01:36:26 2005 -0600
+
+ Make recent readline startup changes compatible with readline-4.0 under UNIX.
+
+commit 72217f76828b49b4e0b98b1fbb142535fc1775d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 15 01:13:45 2005 -0600
+
+ Added missing names and fixed incorrect names for builtin function arguments.
+ Removed duplicate functions.
+
+commit f35731c6d4adab7814eaaed2b450362abbc01c37
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 14 23:29:34 2005 -0600
+
+ Workaround readline incompatibility under MacOS X 10.4.3.
+
+commit 499a84432fa5890f57c80b3bc2d564d3aa2b283e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 14 18:47:01 2005 -0600
+
+ Incremented version to 0.97cvs.
+
+commit d3aa6c3e78e7d22d0c94383670bcb040f2ecfe21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 14 18:08:33 2005 -0600
+
+ Make MSDOS binary work under both MSWINDOWS and CYGWIN.
+
+commit b87facc189c97cc1439b6c12cdf54a7691fd4d0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 14 02:22:10 2005 -0600
+
+ Fixed spelling.
+
+commit f4542712ae2f33fb6516d07366cc8542e0c08b34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 14 02:20:27 2005 -0600
+
+ Document that the -V option under MSDOS is the default only when a single
+ file is given.
+
+commit 3aaf0cf9cca1f7188b2d5d66d1255a19685e5bf6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 14 01:58:29 2005 -0600
+
+ Fixed cxx warning messages.
+
+commit 5a0d6af86d2fa6b35907d93c3e91b1d50090f01d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 14 01:52:52 2005 -0600
+
+ Allow explicit keyword in builtin function definitions.
+
+ Added write(file fout=stdout, string s="", explicit T[] x ... T[][]);
+ function for writing a list of vectors as columns.
+
+ Updated documentation of write routines.
+
+commit 1fffa6aaa334b966e563cf409015fbbbc9f65a93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 13 23:39:31 2005 -0600
+
+ Fix segmentation fault by checking for null arrays in dotsGuide,
+ dashesGuide, and 3d intersect.
+
+commit cfd2248d0406efd23f295eeb7b601cb904ca8343
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 13 16:50:41 2005 -0600
+
+ Fixed order of autogenerated newAppendedArray arguments.
+
+commit b32c4d54bfda1e3333f010b7ec668691d0765a32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 13 16:07:35 2005 -0600
+
+ Fixed cxx error and warning messages.
+
+ Make time(string) simply return format string on systems without strftime.
+
+ Removed generated files.
+
+commit f24b953708c91b82442fb2ed5c9e6c1549909de6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 13 14:21:58 2005 -0600
+
+ Autogenerate remaining runtime functions, producing runtime.cc and runtime.h.
+
+commit e277d1b83a43712c8d408e0b13e222d86514900d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 12 03:36:28 2005 -0600
+
+ Make default transform constructor the identity.
+
+ Allow operator keyword in autogenerated functions (optional, except for
+ operator *).
+
+ Autogenerate more runtime functions.
+
+commit 2465bb6cd34773be15915a88e5262ef4630dcf98
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 12 00:06:44 2005 -0600
+
+ Fixed comment handling of runtime.pl; added prototype comments.
+
+ Autogenerate remaining array functions.
+
+commit 48634f3dc5ae77e2fde057a969bc32d5722ff28a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 11 11:58:39 2005 -0600
+
+ Autogenerate runtime array operations.
+
+commit f65461ccca71521c637487e45edd5e508c0f6184
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 9 00:12:37 2005 -0600
+
+ Autogenerate more runtime functions.
+
+commit bacaf2c7b57f5157e763c2f74eea541d29c503fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 7 00:48:40 2005 -0600
+
+ Updated runtime.pl to generate named arguments and optional default values.
+
+ Auto-generate many more runtime routines.
+
+ Use transform and pen instead of transform* and pen* for consistency with other
+ types.
+
+commit 61d409c56dc3b07a2bc8de506a9e1126b5f87f9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 7 00:37:08 2005 -0600
+
+ Fixed recently-introduced memory leak.
+
+commit 6c28518f804853391b708d645a6c1d89b5107a25
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Dec 6 15:50:41 2005 -0600
+
+ Made brackets part of the syntax for 'quote'.
+
+commit e03aeac59aa29d06488bcc37a9dcd6a4dd61d307
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 6 10:09:49 2005 -0600
+
+ Formatting.
+
+commit 796aedc5c991f3c50763d596f91c230576e10580
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 6 01:38:54 2005 -0600
+
+ Implement named arguments for builtin functions.
+
+commit 94626fe6a780fc144aaddd52cb7a77f99f1377c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 6 01:00:26 2005 -0600
+
+ Make translate (-s option) work with eval (requires running codelets).
+
+commit 100ffff9ee654c8b180a3cb79cc2891d346427bd
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Dec 5 20:05:04 2005 -0600
+
+ Fixed sequenced evaluation of packed arguments.
+
+commit e28f4672575300ed653846be8ad54d5138fe7f53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 5 01:21:12 2005 -0600
+
+ Optimized isDefault test.
+
+ Implemented default function arguments for builtin functions.
+
+ Made write routines builtin functions.
+
+commit 9fef72899d1bfc8509d44f686a5890186da8f0f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 3 23:49:58 2005 -0600
+
+ Remove obsolete remark about default function arguments.
+
+commit ae200ee9cea5e8ec1d269f70ce7d46584d3db302
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 3 00:10:00 2005 -0600
+
+ Documented makepen, nib, Sin, Cos, Tan, aSin, aCos, aTan, and fontcommand.
+
+commit 9ca4e3f824349c79527e89ea95d55b631753a492
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 2 23:27:03 2005 -0600
+
+ Documented BeginPoint, MidPoint, EndPoint.
+
+commit 29ef02fceb6eb09421099a3cf49dced64dd66a10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 2 10:44:21 2005 -0600
+
+ Removed unneeded assignment.
+
+commit 9619df2a7117dbb20b93ce4bced704a8080e7c33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 2 10:14:28 2005 -0600
+
+ Replaced midarrow routine with generalized arrow routine.
+
+commit 461f6b1f8b70788fa80f687c62ebef51dfba00b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 2 05:00:36 2005 -0600
+
+ Do MidArrow and MidArcArrow size adjustment in PostScript rather than user
+ coordinates.
+
+commit 99008e82192e94f15c8dd24b762ca577b6d6765a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 2 00:19:21 2005 -0600
+
+ Added contributed examples and a routine to round the sharp corners of a
+ path.
+
+ Reordered the list of available modules.
+
+commit 8e0a2acb4fb53f752333324c1ab2e1474b429bcb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 1 21:46:26 2005 -0600
+
+ Handle angle(0,0) condition robustly.
+
+commit da6dee972819f677202846dc0c7c44890ea00487
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 1 17:10:59 2005 -0600
+
+ Ignore angle(0,0) errors in dirtime.
+
+ Preserve output precision when outputting paths of any length.
+
+ Fixed makepen draw routine (makedraw).
+
+commit e9932b5bef6de9c5f33357892c2005716c54408b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 1 00:48:00 2005 -0600
+
+ Minor optimization of makepen draw.
+
+commit f213452650c95e23eb1d4c4e240eb9ed8d042971
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 30 23:12:08 2005 -0600
+
+ Revert broken optimization of makepen draw.
+
+commit eddf45b679520b3705812b7f9c50b6235590f684
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 30 10:21:12 2005 -0600
+
+ Simplified makepen draw; extend to cyclic paths.
+
+commit 184116a5754b4c447648cef2987b94db8555fb39
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 30 02:41:52 2005 -0600
+
+ Added MetaPost-like makepen that works for any polygonal (possibly
+ nonconvex) cyclic path.
+
+commit 53453a6383207878891947e9e8fbd0193d6a8b08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 29 23:03:47 2005 -0600
+
+ Call purge after each interactive line to close any files that have gone
+ out of scope.
+
+ Suppress interactive update on exit.
+
+commit 8adaed3f92453ab3328a014020b0d25b1bec5df8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 28 19:37:48 2005 -0600
+
+ Make estack and sstack static local variables.
+
+commit cb82b57275ad49ed6714360f2ba332263536d752
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 28 19:03:56 2005 -0600
+
+ Added filltype to labeltick.
+
+commit 5278a780e8c778661eb978be0a27cddbcffadc36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 27 23:45:17 2005 -0600
+
+ Fix -o - with labels.
+
+commit e1062daaaf34b82440f5d1c1eee76f2b5a249d1b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 27 23:21:02 2005 -0600
+
+ Added example of 3d lighting effects for a sphere, using Gouraud shading.
+
+ When running MSDOS binary under CYGWIN, use UNIX line terminator.
+
+commit f41b5c3cbcab52de658277ea8df09ec05df50994
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 26 17:01:52 2005 -0600
+
+ Check for null binary space partition.
+
+ Move normal==O test to face.
+
+commit 461ea503545d77d9279c8066ab6d76c7ca3bdb06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 26 14:53:12 2005 -0600
+
+ Make -o - work without labels.
+
+ Document how to pass options to convert.
+
+commit e5f090df96cb7378f7f21d0e933d04f29d98b60d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 25 17:50:23 2005 -0600
+
+ Minor improvements.
+
+commit 3801d8d59c5e0bf670e1bc2f81ccb817d48a2cb3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 25 02:51:13 2005 -0600
+
+ Added unitsize argument to shipout command (makes user coordinates
+ represent multiples of unitsize).
+
+ Suppress final call to exitfunction when exiting interactive mode.
+
+commit 8eb2bcf4f65fc9897d5fed34ae591f88e358046a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 24 00:36:47 2005 -0600
+
+ Under MSDOS, turn off the default -V option if more than one file is
+ specified on the command line.
+
+ Under MSDOS, by default bind Delete and Insert keys to delete-char and
+ overwrite-mode, respectively.
+
+commit 23954c9562a97570b63650f5e3ee398741aac9ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 23 18:36:54 2005 -0600
+
+ Install *.dat and piicon.eps files.
+
+commit 61ca520831b2545ba2252dd920b56c8159d04eb1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 23 17:37:39 2005 -0600
+
+ Always destroy tex pipe at cleanup (e.g., in case a label contains a \gdef
+ command).
+
+commit 9e5c05fd948b94ed8ab9bd3d271b7c238b894c47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 23 17:35:02 2005 -0600
+
+ Unwrap wrapper.
+
+commit 2f5737d0b240632ac0081a4e10093f6c51bf1f92
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 23 14:06:56 2005 -0600
+
+ Fixed segmentation fault with unravel and from access in parse diagnostic.
+
+commit f41cff6dc7aebfcd7e696115948df31ca41d3229
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 23 09:53:43 2005 -0600
+
+ Documented ImageMagick convert dependency of GUI xasy.
+
+commit 7c8c9e83089654262c088b5656b288bc32466bba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 23:04:34 2005 -0600
+
+ Renamed -n option to -nV. Used -n (or -no) to negate next option.
+
+commit 2d9f17871e1419f6eaa0b8e4934ffc17e51b6974
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 16:25:52 2005 -0600
+
+ Use kpsewhich to help find default latex path.
+
+commit ee0107095feb9106e2f0155b73467715640f1de4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 15:29:47 2005 -0600
+
+ Improved diagnostics.
+
+commit 1880d2bc13025a7a64e8262d5bb8172ac763ed80
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 15:24:25 2005 -0600
+
+ Check for module recursion after call to parseFile.
+
+commit a46953c709f31a895cb2a3dcd970a2f48ffcccb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 14:31:44 2005 -0600
+
+ Removed incorrect (and unnecessary) addPoint call from xaxis and yaxis.
+
+ Made axisT readable outside of graph module. Made standard axis types public.
+
+ Document custom axis types.
+
+commit 777fbf6726d2027abaa18c9631a7b388d46b95d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 02:19:48 2005 -0600
+
+ Incremented version to 0.96cvs.
+
+commit 6fbf74f332f447fb6c31172ffa76ef0462472729
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 01:04:17 2005 -0600
+
+ Fixed indentation.
+
+commit 364126842df5a60686d9ea3b0b94f8d2c11e7f4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 00:54:03 2005 -0600
+
+ Reimplemented reset keyword in interactive mode to restore the environment
+ except for the setting of scroll().
+
+ Interactive input now does an automatic reset.
+
+ Added link to the GNU readline library documentation for customizing
+ interactive key bindings.
+
+ Fixed hang in scroll mode on EOF.
+
+commit 91eb7c8e328f43b81bedbe0bf9d984789a492e8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 22 00:33:20 2005 -0600
+
+ Move legend.append to appropriate place.
+
+commit dcc0fbe629e3f2372150a4ecdd0693911417b614
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 21 15:15:15 2005 -0600
+
+ Use scalebox only where necessary, to reduce LaTeX memory usage.
+
+commit 71c6655d3469e0ade3a93388c52999dc25cb1d2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 20 15:50:51 2005 -0600
+
+ Plugged remaining memory leak.
+
+commit fd9adc8c3a9d73d90c569025161cad7bcdf1d3cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 20 12:08:29 2005 -0600
+
+ Plug another memory leak.
+
+commit 2d466f2c5a379cb4efd0fa0100a6d5f58c0bf5b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 20 11:41:04 2005 -0600
+
+ Fixed memory leak.
+
+commit 0ae5de9fa205f811259ea403e14b91547358d703
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 19 12:00:13 2005 -0600
+
+ Put GC warnings under control of -d option.
+
+commit 26b1022143890e3c35a24e3a74f2af2ae19b4f36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 18 23:52:49 2005 -0600
+
+ Suppress GC warning messages (in particular: "Repeated allocation of very
+ large block").
+
+commit c3f015919bba9f40bb5bf9f0eacabf2a8f8562c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 18 23:46:59 2005 -0600
+
+ Make interactive input command reset the environment.
+
+commit 6ca8e3cbdcf189f4539c63b84e9700e7359c15b2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Nov 17 23:21:02 2005 -0600
+
+ Added testing for unravel.
+
+commit 3f4f57ca4f67f06bc3961b6c0bcde86eee3ffa77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 17 10:31:08 2005 -0600
+
+ Removed old documentation.
+
+commit d0a40a1fed53391f30dff0134b05b8f852668727
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 17 01:23:28 2005 -0600
+
+ Incremented version to 0.95cvs.
+
+commit 2d8ea5ffd849e487f0cefb89f559d387795328dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 17 00:14:51 2005 -0600
+
+ Changed import graph; to abbrevation for access graph; unravel graph.
+ Also: import graph as graph2d; means access graph as graph2d; unravel graph2d.
+
+ Updated documentation; removed descriptions of old import scheme.
+
+commit 22f1659bb206557ad37971f19040ea5b58b5ae62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 18:25:21 2005 -0600
+
+ Force quiet mode with running embedded latex files.
+
+commit ea0b9c27146e6726caf57e10423f8a481db6bd13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 17:51:06 2005 -0600
+
+ Reduce memory usage.
+
+commit ef4fae7cd964ab244cfb84fa5e514175e0d3b31d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 17:07:28 2005 -0600
+
+ Use a vector instead of a list for estack and sstack.
+
+commit 8381834a584566f533598bd2f6fa104fe2f688ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 15:31:07 2005 -0600
+
+ Reverse order of pstricks and graphicx also in asymptote.sty.
+
+ Fixed formatting.
+
+commit d30095a1a85ffa2765fad62d8d4fc9e6ef39df8c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Nov 16 15:05:25 2005 -0600
+
+ Slight refactoring.
+
+commit 9fc036102ca31b6a710e1d8d8eb2bc7fcb8c4149
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 14:32:30 2005 -0600
+
+ Workaround scalebox problem with old versions of pstricks.
+
+commit 900a230f59eb035da1e73243c7166e50672f829a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Nov 16 13:03:55 2005 -0600
+
+ Fixed frame loading issues with imported types.
+
+commit 491ba39a65ee7cedc1ae705130b79aaf930a28de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 03:31:20 2005 -0600
+
+ Incremented version to 0.94cvs.
+
+commit d2521d022132b4b565b1a23b2fba8ee33c640ab3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 03:06:51 2005 -0600
+
+ Fixed cygwin problem.
+
+commit 73dfcc6c2b8d89eae215103dcc2c0eed219ae44e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 02:36:10 2005 -0600
+
+ Added mkdir.
+
+commit 0f7098206d138babb0ee9b1aad6a420ca8ff88b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 02:27:04 2005 -0600
+
+ Revert to pstricks colors instead of color.sty due to problems under FreeBSD.
+
+commit 1fc8a6ebb4512fc41f3092c118aafbf2747999f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 02:14:50 2005 -0600
+
+ Workaround missing C99 gamma function under FreeBSD.
+
+commit b0988cec31ea4f7c7e5f1948c695e6498cfa33a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 01:31:40 2005 -0600
+
+ Documentation updates.
+
+commit df488ea835383a7ae9bce7d8275d199da678b24b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 01:24:03 2005 -0600
+
+ Added new keyword.
+
+commit 2f111570bc73f175c124d70c774186b707f8d67d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 01:12:02 2005 -0600
+
+ Fixed more cxx warnings.
+
+commit a532094aeeecc237a20ccbf3a2c7c0a9271889b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 01:09:16 2005 -0600
+
+ Fixed cxx errors and warnings.
+
+commit 863e8e9a52a68acd3ceb8ef6aa46d29c51b9849a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 01:01:34 2005 -0600
+
+ Version template.
+
+commit 896307cb58b63bae3d93b6cb1b993528c08acaae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 00:49:51 2005 -0600
+
+ Added version check to plain.asy.
+
+commit e5d83a5366f243d60e5aecb5c54b13629f1bfc49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 16 00:19:59 2005 -0600
+
+ Put history in ~/.asy/history by default unless -localhistory is specified.
+
+ Renamed ~/.asyrc to ~/.asy/options
+
+ Updated documentation.
+
+commit aca9bcc789be34e190316066e9b572030bb92ea3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 22:03:28 2005 -0600
+
+ Read command line style-parameters from $HOME/.asyrc
+
+commit f02c09ffb1bc5950237dc3df611a67a809d2bbc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 18:50:15 2005 -0600
+
+ Removed superfluous static modifiers.
+
+commit 978f33ffba7708b7d91c42ed3b271a511d9cb5e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 16:07:01 2005 -0600
+
+ Added surface graph of matrices.
+
+commit cc9ab56c7966061cbc71c97eb5ef2cc9f1c2e385
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 14:51:50 2005 -0600
+
+ Importing graph3 should publically import graph and three.
+
+commit 1a89f394735cec123b056ae429f290e57f5a078f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 15 13:06:59 2005 -0600
+
+ Implemented horizontal and vertical label scaling.
+
+ Cleaned up Label code in plain.asy.
+
+commit c260f4e541ad2b6ab880668c721565a8e3430ca4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 14 14:09:17 2005 -0600
+
+ Optimized integer overflow checks.
+
+commit 6ae2b69162667e165f20233aa048e5f97e23e142
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 14 02:16:15 2005 -0600
+
+ Added checks for integer overflow.
+
+commit f1a0872ddf61bf7dc88c0988382324b92cbe3123
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 14 01:57:47 2005 -0600
+
+ Handle parse errors.
+
+commit 236e42291a45e1c178982191ebd88b4b2c03b050
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Nov 13 22:47:56 2005 -0600
+
+ Minor edits.
+
+commit 44dba419cb16d17fd46c22ad4581bfc8d798d1f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 13 19:47:17 2005 -0600
+
+ Documented "from m unravel c as C;" syntax.
+
+commit 14bf01cac77e4d4e6a689a732f482976f62e3b6c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 13 19:34:03 2005 -0600
+
+ Minor update.
+
+commit 365ac4a73290985835a8672031aafd69f55696fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 13 19:30:54 2005 -0600
+
+ Documented unravel and include. Updated documentation of execute and eval.
+
+commit 0989b855c9c314798258d3bcb1695236c8f57a58
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Nov 13 16:29:51 2005 -0600
+
+ Describes new importing system.
+
+commit 956cf076a99ba742e11cd2157eb98f9c0739ed1c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 13 03:11:08 2005 -0600
+
+ Fixed memory leak.
+
+commit 2bc72e42522e99043b8051ad93d55c0c3da882dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 12 23:39:26 2005 -0600
+
+ Removed constructor added in error.
+
+commit 28e0bae4df0e9568617341e38c7b923d5f357f60
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 12 23:36:26 2005 -0600
+
+ Fixed cxx errors and warnings.
+
+commit 5f1ba64a2d4098953380c0d70186f75d27b8f6b0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Nov 12 16:47:06 2005 -0600
+
+ Added venv::add to NOHASH.
+
+commit d75a0bd6fd0b1cb4eff4b229875191fbd32b5152
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 12 16:18:24 2005 -0600
+
+ Another workaround for gcc 3.3.4 problems.
+
+commit e2e8ccb6f2f541217ec1f0a8d2a165e0471a9531
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 12 15:57:02 2005 -0600
+
+ Workaround problem with gcc-3.3.4.
+
+commit aeb6c990724852831ffff52b19b6e86b174093c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 12 15:22:28 2005 -0600
+
+ Added erf,erc, and gamma functions.
+
+commit 37df4f422e65e3913781aec833e38343605e4f63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 12 13:43:42 2005 -0600
+
+ Make quotient(int,int) consistent with %.
+
+commit b8d59fe592f7024714ec5a77136ff7a9d0023406
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 12 01:56:01 2005 -0600
+
+ Fix **.
+
+commit 7d071596999b5d45c79dc76375506edf3d9fb6b3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Nov 11 18:38:32 2005 -0600
+
+ Replaced std::string with mem::string for genv.
+ Moved error reporting associated with 'as'.
+
+commit 1b01a81f25eb73d213de73c94373cb3ed3cbe499
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 11 18:22:40 2005 -0600
+
+ Added missing delete.
+
+commit 3e9f0d27ede272fb0b4fd9d6180e9edcf4ca5579
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 11 01:14:34 2005 -0600
+
+ Make bounding box computation work with -o -.
+
+commit b312e379dcdb1dc5ebe0c9310086d4cb2ec44b91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 11 00:37:34 2005 -0600
+
+ Allow outputting to standard output with "-o -" command line option.
+
+commit 1c14fd2ec513bd332987dec787ad2e48fda7d048
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 10 23:59:13 2005 -0600
+
+ Set default pdf viewer to acroread under UNIX, just like under MSDOS.
+
+ Removed pdf fuzz (a workaround for a pdf-viewing problem only of gv, not
+ other pdf viewers).
+
+commit dc252e27f2dc18f99a09c598434b6ca0a28c6378
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Nov 10 10:02:55 2005 -0600
+
+ Refactored argument matching functions.
+
+commit acb62c269bc533b57f8db269b0bc843976d2f4b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 10 02:56:24 2005 -0600
+
+ Removed old interactive buffer flushing code.
+
+commit 49db56fcf5ae55a857fa9ebca24996f0492b513c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 10 01:58:13 2005 -0600
+
+ Choose more descriptive names latticeshade, axialshade, radialshade, and
+ gouraudshade for shading routines.
+
+commit 6c2f1163134a5ade41a8db9e221536221f2875c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 10 01:17:56 2005 -0600
+
+ Respect final null entry when reading data in cvs mode (fixed).
+
+commit 3a89127a1f73df1eae54cdc0cd70df341ab5be51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 9 23:53:32 2005 -0600
+
+ Flush input buffer every time we enter parser.
+
+commit 9e85d17616a91a523f65a239c16aaf229bbf105a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 9 20:49:29 2005 -0600
+
+ Added new keywords; fixed treetest.
+
+commit b78fd384f56f2a7e9e9fd0cfb26f1f06698ad8df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 9 20:35:22 2005 -0600
+
+ Documentation updates.
+
+commit cf629c85681f9975f907279087136664b9e540f2
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Nov 9 00:36:03 2005 -0600
+
+ Extended access and unravel syntax.
+
+commit 12a1791ded53de40f11fad39422b712c851e277e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 23:23:54 2005 -0600
+
+ Make embedded evals work within exitfunction.
+
+commit fb4c073d8a100376af5078d8e83a607545279936
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 23:05:11 2005 -0600
+
+ Reimplemented GUI support.
+
+commit a1b02245d9d163612c65ce76e25e41951fb9e54b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Nov 8 17:55:03 2005 -0600
+
+ Check for infinite recursion when loading modules.
+ Add position info (markTrans) for codelets.
+
+commit 8f85cfa41726a8039358d7699edbc2f7f27c5dd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 14:30:10 2005 -0600
+
+ Renamed defaultpen() to resetdefaultpen and getdefaultpen() to defaultpen().
+
+commit 9e9a8ceb1a95c2ec077c960dcad190c0c25f13bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 14:11:06 2005 -0600
+
+ Updated diagostics.
+
+commit 0d092a3d344734b958f5d3b231388c520478a3d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 12:58:07 2005 -0600
+
+ Re-implemented -p (parse) and -s (translate) options.
+
+commit a1ca000656cf8892d798b4fc8132e3835dff02da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 10:39:14 2005 -0600
+
+ Corrections from import merge.
+
+commit fd5fb6c0df0bbbec952ee8efdff3db1cdb304011
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 03:36:32 2005 -0600
+
+ Reimplemented import "file" syntax.
+
+ Interactive mode updates; reimplemented interactive "input" command.
+
+ Documented true interactive mode.
+
+commit a679f9db485a048f7a093f22d977d455094ff0eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 01:22:41 2005 -0600
+
+ Facilitate optional installation of documentation and examples to different
+ directories.
+
+commit 00ecbbcfc69ec7a3c48c5def887fc98a05f389a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 8 01:19:24 2005 -0600
+
+ Added missing picture arguments to graph.
+
+commit 18696c78fa467a579e6d6c0d9acece649522669a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 7 23:26:21 2005 -0600
+
+ Remaining import updates.
+
+commit 14735e983987b664738f9bbab29953a6cdeafd7d
+Merge: 0b62f703 9710028a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Nov 7 10:57:39 2005 -0600
+
+ Merged in changes from the import branch.
+
+commit 9710028ac2a4550f2494a79fcdb6e441ea28c274
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 7 00:44:35 2005 -0600
+
+ Renamed autonomous argument of eval to embedded.
+
+ Updated asymptote.sty.
+
+commit bd5b3c0031560966eaa9655e4d259b1c1f892544
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 6 23:01:22 2005 -0600
+
+ Optionally allow eval to run within current environment, rather than in an
+ autonomous (distinct) environment.
+
+commit 09816a50c49d05c02c7d4d2e0643a1a65963f9a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 6 17:57:25 2005 -0600
+
+ Fixed eval so that environment is properly reset.
+
+ Removed outnameStack.
+
+ Added animate.asy module to make animations easier.
+
+ Reimplemented -l (listvariables) option.
+
+commit 0b62f70388e8cbc7a7212fe76415f70ac1ffd723
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 6 17:36:58 2005 -0600
+
+ Fixed lexer error.
+
+commit fe3ac7ae1dd16b09b629339bda26cfea3be3c502
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Nov 6 10:57:54 2005 -0600
+
+ Checks permission of both the qualifier and the field for an unravelled field.
+ Inaccessible (eg. private) fields are not unravelled.
+ Added quote keyword and code type.
+ Refactored doIBatch.
+
+commit 36c564c5e4880445b452f486d95c0ff485013781
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 5 21:45:10 2005 -0600
+
+ Removed # and ## as admissible operators.
+
+commit 2720837802489b099d25586a32ce0451c9c6f1d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 3 11:44:07 2005 -0600
+
+ Temporarily deactive last change.
+
+commit cc10f38f1ce5bbe06a3c0cf7314646ffa0d17eb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 3 11:32:41 2005 -0600
+
+ Respect final null entry when reading data in cvs mode.
+
+commit c9ddd25d7e1c1249f95070d0c1190e40d0707ba6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 3 01:34:01 2005 -0600
+
+ Fixed memory handling and outname for line at a time mode.
+
+ Switch over to using line-at-a-time mode.
+
+commit af35dac4500855ebb9efbdec808595b3701a8a07
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 2 23:46:58 2005 -0600
+
+ Added infix operators << >> @ @@ $ $$ # ##.
+
+ New module fontsize.asy supports nonstandard fonts.
+
+commit 9fa2770e323fe9a2242a4733b8af3f46991069c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 2 13:00:16 2005 -0600
+
+ Reimplemented -laat mode.
+
+commit b4529048ec3618cec5a136f6672a8e5105ba0d01
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 2 01:39:54 2005 -0600
+
+ Merged eval with IBatch; removed laat mode.
+
+commit 58326a3eca7dfd5f809312c189338af8f2315a3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 1 23:41:04 2005 -0600
+
+ Reimplemented eval() and execute().
+
+ Added shipped flag to save() and restore().
+
+commit 45dd4837a78e3843b65e99b893b5f4f69ca9d173
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 1 13:28:51 2005 -0600
+
+ Fixed picture.empty().
+
+commit d40cf552d16cdca9693b025c1fb1deff1da7d92c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 1 11:40:11 2005 -0600
+
+ Set A=unravel, Q=access, U=import to allow testing until "import into" is
+ implemented.
+
+commit 7ea5da6eda5c4b2ae9d6e1d9a8e9444fb6cceaae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 1 02:06:27 2005 -0600
+
+ Gracefully handle errors in loading plain, etc.
+
+commit e2b4b9d50b69993f9cf9ccb340088f2b0a37d958
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 1 02:00:18 2005 -0600
+
+ Fixed interactive error handling.
+
+commit abeda671cf2e6ca69e45cc2d80df77a9bf1d759c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Oct 31 00:32:21 2005 -0600
+
+ Changed ignore permission modifiers to a warning for use with include.
+
+commit a43fe979f8a5ee720196d9cd2d7508ae78ebedf9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 30 14:27:53 2005 -0600
+
+ Minor code cleanup.
+
+commit ee6c32d83cc851eba02e78e65c48cdac864817cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 30 11:33:52 2005 -0600
+
+ In interactive mode, flush input on errors.
+
+commit edeb32b334dcbfe4b462f70fc4f93d0bd4ef297c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 30 04:41:06 2005 -0600
+
+ Allow expressions of the form (0,0,0){x,y,z}.
+
+commit 90fd95b0d77f94f426566cfe3dc7a1aa434fa74a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 30 04:34:35 2005 -0600
+
+ Removed operator symbols consisting of letters enclosed by colons.
+
+commit 7c9208f06dbbc91d397635c1b37f73c7a4a33dd5
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 29 23:14:11 2005 -0600
+
+ Added semicolon to include.
+
+commit b380e5feb4b448bdd20e5da0f908934df33c9f1c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 29 21:49:03 2005 -0600
+
+ Allow include file as well as include "file".
+
+commit 9fa4217964d07baf22ab715898e8f99bc666d8e3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 29 19:16:58 2005 -0600
+
+ Added include, which translates the parse tree of the given file in place.
+
+commit c1e9731d8bf713b00e41fe776b3aeed845f4701d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 29 14:03:21 2005 -0600
+
+ Added some form of autoloading.
+ Bad importing does not affect the genv dictionary in interactive mode.
+
+commit 90060607dfc7092dc72546df88b773d3e1d5f0bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 28 23:31:17 2005 -0600
+
+ Additional operator symbols can now be formed by enclosing any combination
+ of letters (including the underscore character) in colons.
+
+commit a67283022104a1b5accc43d556674afad9f700e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 28 21:56:53 2005 -0600
+
+ Re-added tension3 and curl3 operators.
+
+commit 9a78050799658c969ab432695f35c3f473132b78
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 28 17:50:38 2005 -0600
+
+ Autoplain for interactive mode.
+
+commit 56aec06506f45c100cf743c96935ec8f2b0af3cd
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 28 17:40:01 2005 -0600
+
+ Add environment rollback, for erroneous code in interactive mode.
+
+commit c8735012ac180cbdfba25d373bd370739c8a496e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 28 00:33:34 2005 -0600
+
+ Support interactive erase: outputting an empty picture produces an empty file.
+
+commit 3d8605ddb94514e5b53e0ac1b06116455d38ffb0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 27 22:08:47 2005 -0600
+
+ Documentation now refers to Datadir variable rather than /usr/local/share.
+
+commit a7b07c58cbc9150960d106cb2b39b1c9b3ce3546
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 26 22:43:12 2005 -0600
+
+ Uptodate flag now does a shipout() as needed.
+
+commit b2d73e276904b14b731eafee152f30b44715a34a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 26 12:28:04 2005 -0600
+
+ Fixed typo.
+
+commit bb131c1588b70376eece7d7cde471a2c75644430
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 26 00:38:51 2005 -0600
+
+ Removed unused includes.
+
+commit b94a3ec4ad8d2dd068cfb88e6fb3ea73f32b780b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 26 00:34:04 2005 -0600
+
+ Remove unused code.
+
+commit 19ba7e49064b8f68186cf1895bb08cb54f4b2b54
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 26 00:09:59 2005 -0600
+
+ Fixed interactive mode error handling.
+
+ Merged in return code fixes from the main branch.
+
+commit f334721ec9ac22dac7ac0d32e703eb4ccbce6ec4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 25 23:23:02 2005 -0600
+
+ [Import] Replaced virtual interactive mode with true interactive mode.
+
+commit 2399cd7f0f57dac01ac5532fa6b85313aa517b25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 25 11:27:30 2005 -0600
+
+ Fixed STL errors and virtual destructor warning.
+
+commit 2df11de94ed66efd5466dcba89823f431a6affe6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 24 22:54:56 2005 -0600
+
+ Return a definite return code (rather than an error count that overflows
+ after 256 errors). Also check for parse and translation errors.
+ A return code of 0 means successful; 1 means a user error occurred;
+ -1 signals a misconfiguration error (pipe, fork, or exec failed).
+
+commit d640705f9565091a774e248db1ab8b166418cdad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 24 22:02:19 2005 -0600
+
+ Set default put argument of box and ellipse functions to Above.
+
+ Use convert instead of dvipng in doc/Makefile.
+
+ Updated Debian URL.
+
+commit 16e5842f629b59e3917f21e6a3825a1206432a2d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Oct 23 21:25:28 2005 -0600
+
+ Added more changes in from the main trunk.
+
+commit cb193ddaa1db2bdfac90cc8a9522867cd8d5ac9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 23 02:15:00 2005 -0600
+
+ Incremented version to 0.93cvs.
+
+commit f8949272355544fe98b28ef870d503b9f5579e8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 23 01:48:50 2005 -0600
+
+ Fixed cd diagnostic.
+
+commit e91d10d96853361746e44bf87af763a90c99e94a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 23 00:50:35 2005 -0600
+
+ Fixed label bbox bug.
+
+commit ba22e55cc25e9fbbf1af7f0f70e64cd52e5e55b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 23:15:14 2005 -0600
+
+ Fixed intersect fuzz calculation.
+
+ Implemented means of adjusting 3d aspect ratio.
+
+commit 0307afc0e763fae832d552a70a5990d93867640a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 10:49:28 2005 -0600
+
+ Updated xasy to generate GUI(int) frames instead of gui(int).
+
+commit a2892cbacb27a4b2b353efe0025fce0c65a1b2cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 04:25:01 2005 -0600
+
+ Workaround missing round function under FreeBSD.
+
+commit fc2a9f4342f45a7a60f0fcdb1e4d8350e7b28565
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 03:41:04 2005 -0600
+
+ Fixed cxx errors.
+
+commit 288b512004959a3394b521c5acfd2fb07fe8f655
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Oct 22 02:54:15 2005 -0600
+
+ file brokenaxis.asy was added on branch import on 2005-10-24 03:25:28 +0000
+
+commit 06839af15a6bafcd7bbbfeb098fc7961ffd8bcf0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 02:54:14 2005 -0600
+
+ Fixed example.
+
+commit 8ddb128c9b7b2f448d4d377cc094b0859ff0b7f2
+Author: no-author <no-author>
+Date: Sat Oct 22 08:54:14 2005 +0000
+
+ This commit was manufactured by cvs2svn to create branch 'import'.
+
+commit ecbd779730fbdf6e262c93db163e27bb5ce3153a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 02:51:32 2005 -0600
+
+ Added missing example.
+
+commit e4be44933a2678abd007ebfd57bddf284492248b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 02:48:56 2005 -0600
+
+ Added scaleT Broken and example of broken x axis.
+
+commit f19cf665b8285f6e2df069d4cacffce341069dac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 01:45:58 2005 -0600
+
+ Moved dir argument of picture.fit() to add(frame,pair) and attach(frame,pair).
+
+ Added frame align(frame f, pair dir) for aligning frames.
+
+commit 51d89c20b4806ab6a1cce8cb480e261da1e9abb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 22 00:03:18 2005 -0600
+
+ Implemented a new struct marker to hold marker data, including a general
+ markroutine. Included both the default marknodes routine and a
+ markuniform(int n) routine which draws n markers at evenly spaced
+ intervals along the arclength of the path.
+
+commit 564aed3f7bc21cd4939b911f3371d058403e4f8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 21 02:12:29 2005 -0600
+
+ Don't strip directory from explicit output filenames.
+
+commit 6629c2f55134e6b92dc62c4c4eb5d4fccb30538f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 21 01:23:16 2005 -0600
+
+ Documentation updates.
+
+commit f47b325d3f0dbc419a08452a2027ccb2047c01c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 20 01:36:43 2005 -0600
+
+ Added CPPFLAGS option to configure.ac (equivalent to CFLAGS).
+
+ Fixed spurious overwrite messages.
+
+ Added fuzz to label clipping to retain labels exactly on boundary.
+
+ Moved intersectionpoint to plain.asy and added documentation.
+
+ Renamed intersection in math.asy to intersect to intersect.
+
+ Added UnFill filltype for clipping underneath frames, pictures, and labels,
+ with examples.
+
+ Make save/restore respect currentprojection.
+
+ Added 3d intersectionpoint routines to three.asy.
+
+ Added instructions for setting environment variables under MSWindows XP.
+
+ Removed ymargin=infinity in favour of ymargin=xmargin.
+
+ Documented use of Cyrillic fonts.
+
+ Documented that \end{asy} environment must appear on a line by itself.
+
+commit 32ad169f5b3542da1ec48e903da457639d8e6f97
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Oct 19 13:37:59 2005 -0600
+
+ use is now use=import+explode.
+
+commit 0628aa7bb95026a88ff36b26060260f8ed47c439
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Oct 18 17:53:23 2005 -0600
+
+ Got line-at-a-time working.
+
+commit c78464d5ff2a4a37b335bd09c5a70b57c3a2c389
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Oct 17 19:31:59 2005 -0600
+
+ Import can infer the filename. Filenames given as positions are actual files.
+
+commit 4e991f81346b0711e3c3c18f65f090f19156fc88
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Oct 17 18:01:27 2005 -0600
+
+ Added use declaration.
+
+commit 6559104a9581c0e532e291c4166755c451f4a2bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 15 03:14:38 2005 -0600
+
+ Fix precision errors at +/-1e-4; default format changes to scientific
+ notation here.
+
+commit 716e22941007220a14c57ab41e1c6700e01e724d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 14 22:07:16 2005 -0600
+
+ Fixed inside(path,pair).
+
+commit db0c6be308eadd2ae2d4b3f81a652c3920574e68
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 14 10:08:45 2005 -0600
+
+ Integrated changes from the main branch (tagged changes_for_import_oct_14).
+
+commit 7dbede8650a3b614f58004bae0f40332ba936980
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 14 01:16:49 2005 -0600
+
+ Implemented robust real cubic root solver.
+
+ Removed inside, quadratic solver, and intersect routines from math.asy in
+ place of internal C++ routines. Changed DOUBLE to TWO, etc., to avoid
+ confusion with double roots.
+
+ Implemented function bool inside(path g, pair z, pen p=currentpen);
+ to test whether a point is inside a cyclic path.
+
+ Implemented clipping of labels. Added two new fill rules to allow labels
+ centered within the clipped region to overlap the clipping boundary.
+
+ Clipping now clips all layers of a picture, not just the most recent one.
+
+ Fixed bug in precontrol and postcontrol.
+
+ Fixed floating point exception in complex powers when base is zero.
+
+ Added Floor, Ceil, and Round functions that don't produce floating point
+ exceptions.
+
+ Made the default axis for logarithmic scaling YEquals(1) and XEquals(1).
+
+ Made currentpicture the default picture in Scale(pair).
+
+ Added begingroup/endgroup pairs to filldraw.
+
+ Changed plane interface to return a representation of the plane through
+ point O with normal cross(u,v).
+
+ Draw over existing TeX layers when doing 3d hidden surface removal.
+
+ Added face labels to cube animation.
+
+ Updated installation instructions.
+
+commit 0db8a820cbd178de0f23e83b82f160eebb36ceca
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Oct 13 15:39:16 2005 -0600
+
+ Grouped common code between record and env into protoenv.
+
+commit 166c1812dc1b3f810d98995b463e9bfcc6ac9196
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Oct 13 13:04:36 2005 -0600
+
+ Fixed prettyprinting of joinExp.
+
+commit adb637f8f99ac50c6fc046819813c33d77ca159b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Oct 13 12:43:16 2005 -0600
+
+ More specific error message for casting.
+
+commit 72379c9945ccde7a915a2d6d43b8c74de882d651
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Oct 13 12:42:41 2005 -0600
+
+ Fixed indenting for parse output.
+
+commit 02fa43b7a893bcd08b0459dc4969e3727dd17113
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 13 09:01:13 2005 -0600
+
+ Fixed control point bug introduced by recent straight flag fix.
+
+commit 0f9db37a420570090e30b1e2f50c1ec841d505f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 12 16:29:21 2005 -0600
+
+ Make default value of picture.keepAspect true.
+
+commit a246176ea243b9fb0bff994cdfcdcfd8524f68dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 12 14:02:37 2005 -0600
+
+ Use picture defaults as default parameters in fit and size functions
+ (locally resolved default function arguments now allow this).
+
+commit 822d263fb2742e1347e028dd93a20c0c55ad080d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Oct 12 11:44:23 2005 -0600
+
+ Replace ty with tyEntry for type declarations. Allows types to be imported.
+
+commit 5e141104cc6d0addcc0f1698d153becd009faf5a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Oct 11 21:24:14 2005 -0600
+
+ Edited comment.
+
+commit 88ef0077d414e3d97ff769ab5a701e2086e47c0b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Oct 11 19:29:11 2005 -0600
+
+ Straight flags are preserved when using a path as part of a guide.
+
+commit 35c9020bb49d1076276e30d2ab29db9d9cb379d7
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Oct 7 21:57:39 2005 -0600
+
+ Default arguments are evaluated "out-of-order" like variable initializers.
+
+commit 0cec99e8ac52736ba80006e83c4885f519e1317b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 7 14:58:33 2005 -0600
+
+ Moved animations to animations subdirectory of examples directory.
+
+ plane(triple u, triple v, triple O=three.O) now returns the plane through
+ point O with normal cross(u,v)
+
+commit 4c88f42245a5c2719976c11f50c7c4ca2828921e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 7 02:22:25 2005 -0600
+
+ Simplified plane(triple, triple, triple).
+
+ Simplified Pen(int).
+
+ merge no longer waits for animation to complete.
+
+ Added rotating cube animation.
+
+commit bcba1612f92ef07994d8e5321ce01b138920b551
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 6 11:46:16 2005 -0600
+
+ Fixed formatting.
+
+commit 71e36c9d67813b9751474b9833c49c6059e19e9e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 6 11:17:13 2005 -0600
+
+ Added linewidth().
+
+commit 00b525d39bdfc8843306213c8c1b66fafc12e3c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 6 11:11:05 2005 -0600
+
+ Removed implicit cast from real to pen; added pen operator +(pen p, real w)
+ and defaultpen(real) instead.
+
+ To avoid confusion, a dot product now requires explicit pair arguments.
+
+commit b5898745ca2f7ac639850dfe8809f3e8fadc8094
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 6 10:05:56 2005 -0600
+
+ Added new 3d surface example.
+
+commit 8fae5a35ebe087e3ce13a40eef09a1c1651dd85c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 5 23:55:15 2005 -0600
+
+ Added example of reading column data from a file and a least squares fit.
+
+ Changed xsize and ysize arguments of size to simply x and y.
+
+commit 1b9472f0c0714569f7593412c17fcdd397837fa2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 5 19:51:32 2005 -0600
+
+ Added keepAspect=Aspect option to size(pic,real).
+
+commit ec325dcd7d9c40e9d6b7fa010bfff61103e8701c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 5 19:44:19 2005 -0600
+
+ Added colinearity checks to leastsquares.
+
+commit 43e1aa502818297f37cf4b3d0c6ccdcabcda7356
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 5 01:49:20 2005 -0600
+
+ Use local copy of ticklabel and Label context variables.
+
+commit 2291108072ebe06f75430eac98a867358ce9ea11
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Oct 5 00:12:20 2005 -0600
+
+ Reduce default axis coverage limit to 80%.
+
+commit 40026fc8e6c783b389cd59687f8e7ce7d9498689
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 4 21:48:00 2005 -0600
+
+ Minor documentation updates.
+
+commit ef0e9459d9b3b6ea84059cff63b508a71d0abcaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 4 16:13:55 2005 -0600
+
+ Fixed default location of python under MSDOS.
+
+ Improved ASYMPTOTE_PYTHON/ASYMPTOTE_XASY diagnostics.
+
+commit 14dff5e06fab759643bc6a3dcd3faf613ca687b6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 4 15:43:14 2005 -0600
+
+ Added Windows support for xasy, including an environment variable for
+ finding Python.
+
+ Allow GUI mode in interactive mode.
+
+ Added gui(real x=1) function to turn on GUI mode.
+
+commit 9754518eb38a59a3a254758587a18a2346c8be4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 4 11:27:41 2005 -0600
+
+ Remove intermediate gif files before viewing animation.
+
+commit 6d9748b7a805505a51dea16e7238fb96a4a6c60d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 4 11:20:56 2005 -0600
+
+ Added quiet option to override -V command line option, say for producing
+ animated gifs. If the -V option is given, gifmerge now calls animate.
+
+commit 6139176d9f0add3e1b59bfb0730a841abb92d851
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 4 00:30:27 2005 -0600
+
+ Incremented version to 0.92cvs.
+
+commit fc1dd1de6063a49253a225fdb4e59b793b80e369
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 3 23:39:06 2005 -0600
+
+ Fixed GUI transforms: grouping should not depend on deconstruct flag.
+
+commit 2173497579d327808a02fa2b6540324af8967755
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 3 23:06:24 2005 -0600
+
+ Incremented version to 0.91cvs.
+
+commit b594c603c24e875e358f0795ec6d2012b5af25fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 3 21:24:51 2005 -0600
+
+ Flush stdout immediately before calls to fork() to avoid duplicate output.
+
+commit 844cd96140044c3f36b98f0095545edc9b2a206d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 3 02:36:26 2005 -0600
+
+ Added Andy's changes to evaluate default function arguments in the defining
+ scope of the function, not in the scope of the caller.
+
+commit 459abeea181fd57e4a5f15e6b1951c9120197e53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 3 02:20:02 2005 -0600
+
+ Generalized write to handle an arbitrary number of data values; improved
+ documentation.
+
+ Generate standard casts via templates.
+
+ Added == and != for files.
+
+ Allow casting of null to file.
+
+commit 925ea8080438e0a43970bb23d2fd07f2288d25f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 3 01:08:44 2005 -0600
+
+ Readded depth limit to intersect routines to prevent stack overflow.
+
+commit c024d3bfcc295da26dbeddc15893550d50817a69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 2 15:42:30 2005 -0600
+
+ Enforce a minimum value of fuzz in intersect routines to prevent infinite
+ loops.
+
+commit f4910c0dd9c43a6ad10fc21f8e12d73a2eafbc05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 2 01:20:15 2005 -0600
+
+ Fixed depth handling of deferred TeX labels.
+
+ Fixed error in man page (-t option).
+
+ Fixed interaction of overwrite(Move) with "%" tick formats.
+
+ Improved 3d axis label positioning.
+
+ Added rotate(explicit pair dir) and rotate(explicit triple dir) for
+ rotating text along a line in the direction dir.
+
+ Updated helix example to illustrate rotated tick and axis labels.
+
+commit a4e788568370ce3dab091fc5040e263a7ad8965c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 30 23:40:32 2005 -0600
+
+ Incremented version to 0.90cvs.
+
+commit d066ac3daa6ffda6f0ed38c3440c47812f585155
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 30 22:42:16 2005 -0600
+
+ Documented min(frame) and max(frame).
+
+commit 3697afe04bc3125fe16db8a066e8c7e73df3f9f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 30 14:55:59 2005 -0600
+
+ Don't upscale logarithmic range when automax=false.
+
+commit 5f190e85df39833571eb810f5b849c626d3ab3ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 30 12:42:28 2005 -0600
+
+ Renamed temporary included PostScript file suffix from "ps" to "eps".
+
+ Removed all references to mailing list, as it is no longer in use.
+
+commit 31a4608e9b64f85824aa08b7c1e382c078848123
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 30 07:50:18 2005 -0600
+
+ Fixed .gui processing.
+
+ Added new example.
+
+commit 00afce892ce6bc08cf1da0b16c8d64792a385a3e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 19:53:03 2005 -0600
+
+ Allow overriding of ticklabel routine for logarithmic axis; added example.
+
+commit e8192130beb7536093032069631ba8c09c5247ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 18:04:46 2005 -0600
+
+ Standardized arguments to LeftTicks, etc.
+
+ Fixed user-specified logarithmic ticks.
+
+commit e0f43b3c6567023fb59e5f7d9ff8848b47c7b972
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 29 01:50:22 2005 -0600
+
+ Incremented version to 0.89cvs.
+
+commit 76ffd72cb6b21bb0022f0cb55c88edc59786291a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 23:53:39 2005 -0600
+
+ Only build required images.
+
+commit da1daa09d06cbeaa628cbf37ddef0e8286cfb473
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 23:37:23 2005 -0600
+
+ Minor documentation updates.
+
+commit 917f2f1f7027027039643ceba79cedd4b8ac489f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 18:01:47 2005 -0600
+
+ Fixed missing label on thinned logarithmic graphs.
+
+ Documented getstring and getreal.
+
+ Documented vectorfield and flow example.
+
+ Fixed cxx warning messages.
+
+commit 25e99790fe76f4e401885207dee8ac65637349da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 28 14:51:47 2005 -0600
+
+ Simplified, improved, and documented 3d axes routines.
+
+ Renamed tickspec to ticklocate. Documented ticklocate.
+
+ Removed unused symbols from camp.l.
+
+ Removed spurious nullpaths from :: and ---.
+
+ Documented deconstruction of guides.
+
+commit 0e7db2cd763308121b81cdd43ae3305b277df65d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 27 01:42:24 2005 -0600
+
+ Added a second optional string to Label to provide an estimate for the label
+ size when an undefined label is encountered with the -t option.
+
+ Fixed box(Label).
+
+commit f30bda16e795e11351bffc560b5898f268985bcb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 26 23:28:56 2005 -0600
+
+ Updated pstoedit patch to put brackets around rotated strings.
+
+commit 32ca492bf4247f2d27b132ecd11e0efc4067599d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 26 23:09:02 2005 -0600
+
+ Implemented data file comment character (# by default).
+
+commit abbfa2473bdc0f43d04ccf88c577b7d10f7cf59d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 26 09:05:45 2005 -0600
+
+ Used scaled epsilon to adjust right-hand axis limit.
+
+commit b8517154afba8da5c9722fe4a157459cc22f791b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 25 23:45:48 2005 -0600
+
+ Added fuzz parameter to intersect routines for finding intersections with
+ circular approximations, etc. Also fixed these routines for paths
+ consisting of a single point.
+
+ Moved 3d intersect routine to C++ for speed.
+
+ Cache 2d path bounding box.
+
+ Added 3d version of expi.
+
+ Increased accuracy of true Arc and Circle to approximately machine precision.
+
+ Added 3d true Arc and Circle.
+
+ Added 3d polargraph function.
+
+ Renamed triple.cc to path3.cc.
+
+ Added missing triple to path3 cast.
+
+ Added patch to pstoedit-3.42 to support PNG to EPS conversion.
+
+ Updated documentation.
+
+commit 43e16164cb7ec0d751c3fda881d5c9203edd4f80
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 25 21:56:47 2005 -0600
+
+ Fixed base alignment in new deferred TeX alignment scheme.
+
+commit fe5d5004425730bcc21219c5b11d67a2f535378b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 23 22:04:54 2005 -0600
+
+ Fixed shift(c) in 3d circle.
+
+commit 3265026ee25f6cd1305e8979e45e80e302ebac29
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 23 09:42:46 2005 -0600
+
+ Fixed "\\".
+
+commit 38a5b0c147988711a1c81c4add5c16014e63a0a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 23 01:15:56 2005 -0600
+
+ Added missing header.
+
+commit d1308e6a739f0adaf981ba90b2d318744afd6659
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 23 01:07:53 2005 -0600
+
+ Make merge use environment variable ASYMPTOTE_CONVERT.
+
+commit aedfd3263f31f033055e93799a651d7e11027069
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 23 01:02:48 2005 -0600
+
+ Added an environment variable for the location of every external command.
+
+commit 7e7027029f51071c7d3886ef32d34ff17f1445e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 22 23:54:43 2005 -0600
+
+ Added vectorfield routine and example.
+
+commit 3aa540f69ffce103a15046a8171dedaff62be26c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 22 23:23:39 2005 -0600
+
+ Added [inline] option to asymptote.sty to use inline LaTeX code instead of
+ eps files, making LaTeX symbols visible to the \begin{asy}...\end{asy}
+ environment. In this mode, Asymptote correctly aligns LaTeX symbols defined
+ outside of the \begin{asy}...\end{asy} environment, but treats their size
+ as zero.
+
+ Added -t option to asy to request inline LaTeX code to be generated.
+
+ Added modified dvipdf that accepts the dvips -z hyperdvi option.
+
+commit 5f8f76b720b722ddb20db9a99cf88c9ec7c18946
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 21 19:06:07 2005 -0600
+
+ Updated axis call.
+
+commit 10e4cb072c803e902938ed28f8e83a53cf85d411
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 21 17:58:34 2005 -0600
+
+ Replace system calls to rm/del by unlink().
+
+commit cc1a8fec276e41d87ec44bea9fd1a62a3b40d751
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 21 02:32:44 2005 -0600
+
+ Fixed segmentation fault in straight.
+
+ Fixed bug in setting straight flag in reverse.
+
+ Fixed axis label placement for slanted (but straight) axes.
+
+ Improved tick label positioning with slanted ticks.
+
+ Simplified 3d axis routines; added autolimits function to implement 3d
+ autoscaling.
+
+ Don't cache Ticksize and ticksize.
+
+ Standardized xaxis, yaxis, xequals, yequals calls (Label now appears
+ immediately after picture argument).
+
+ Check for empty pictures when drawing axes with ticks.
+
+ Updated documentation and examples.
+
+commit 50fb9a5e9d19d59b826469d2092f3bcb86f5273a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 20 02:39:57 2005 -0600
+
+ Overhaul and major clean up of 2d graph module; to support 3d axes,
+ partitioning is now done in tick value space rather than with respect to
+ arclength.
+
+ Added 3d graph axes (xaxis, yaxis, zaxis, and general axis) and generalaxis3
+ example.
+
+ Format "" is now treated as defaultformat (use "%" to suppress labels).
+
+ Updated gc to 6.6.
+
+ Under MSDOS, change "rm" to "del" in merge utility.
+
+ Don't print hints when there is no environment variable.
+
+commit da841cbe3ed981768a5b3a538c5034fe6b89b640
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Sep 19 22:53:49 2005 -0600
+
+ Added primitive import declaration.
+
+commit d1be7e398dbb104d9805583cfe4d3ab2a2e021f4
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Sep 18 13:11:25 2005 -0600
+
+ Removed menv from env.
+ Simplified genv.
+ Added load() to stack.
+
+commit c66d43934cafb628e4a901adba8feac35779b023
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Sep 16 09:36:50 2005 -0600
+
+ Fixed error reporting bug.
+
+commit af401fc11fe28f5eb6e9c1fbf8a8d97a94107c2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 14 07:46:33 2005 -0600
+
+ Changed make to $(MAKE) for portability.
+
+commit 37527fbd0b818ae1e318a406256c9f53cc1cb4de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 14 01:25:28 2005 -0600
+
+ Changed nullpath to nullpath3 to avoid ambiguities.
+
+ Set initial precontrol point and final postcontrol point of noncyclic paths
+ to the corresponding node.
+
+ Fixed the length of a cyclic path3.
+
+commit cc49900491763841bd0c518198e0994425bdc0cc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 14 01:17:44 2005 -0600
+
+ Added snprintf workaround for non-C99 compliant systems.
+
+commit c764e77e9f56e069c6025237580959db74c38bea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 13 09:49:18 2005 -0600
+
+ Added missing headers for Solaris/Sparc.
+
+commit cb492775d1aa6d57db89518d1b0195674d4c7577
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 12 19:47:44 2005 -0600
+
+ Fixed pair.z and triple.xx bugs.
+
+commit 765739db13af97ff1466278103aacaa6d753e1ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 12 17:11:54 2005 -0600
+
+ Added some comments to graph.asy.
+
+commit 16d1381fc2b3e4d6447c6a59690a4c73b583dc9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 12 13:40:40 2005 -0600
+
+ Optimized matrix times vector.
+
+commit 8398b1ea07e57578df9ddfd46c4bf9bd5627fa4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 12 11:35:34 2005 -0600
+
+ Standardized perpendicular.
+
+commit 0b3affcd778551a39888d7258413c01d39fa5ec2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 11 23:48:47 2005 -0600
+
+ Added 2d & 3d Metapost & operator (like --, but omits the duplicate point).
+
+commit 28f4d757bada480db359ee4d003ffe6cfe8b70fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 11 00:34:52 2005 -0600
+
+ Fixed resolution problems of png figures in html manual.
+
+commit 52f67bd463a575127be62eb01e1784e9118c2fba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 11 00:04:12 2005 -0600
+
+ Reorganized installation instructions.
+
+commit d70a5b9c9f49e30555ad329e8440eda2ee212db0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 10 23:33:39 2005 -0600
+
+ Handle errors due nonarray rest formals gracefully.
+
+ Improved formatting.
+
+commit e48861de344a6305262c59e498a2536d91b87c6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 10 16:10:36 2005 -0600
+
+ Updated list of errors.
+
+ Changed make test to make check.
+
+ "make all"/"make install" now build/install asy, asymptote.pdf, and man pages
+ but not asymptote.dvi, asymptote.info, or asymptote.html
+ (use make install-all if you want these too).
+
+ Documented workaround for broken pdftex installations.
+
+commit c4ae0090e4795ba225b32ec40a6182eb3dd04ff6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 10 00:38:55 2005 -0600
+
+ Removed scale(pair) in favour of scale(abs(z))*rotate(degrees(z)) to avoid
+ confusion with xscale(z.x)*yscale(z.y).
+
+commit 5bf75dd48ece31999e8ccdf8f43cfa8f9923c822
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 9 23:58:11 2005 -0600
+
+ Don't cache MidArrow and Bar sizes.
+
+commit 63d12a1b39b9e0a85f5bf1582b8f140023ab0560
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 8 22:24:26 2005 -0600
+
+ More intuitive interface: perpendicular(pair z, pair align) now uses an
+ alignment argument.
+
+ Documented virtual structure functions.
+
+ Updated documentation to emphasize that face is derived from picture.
+
+commit 07af5223c26d25a298cbc74b0f331e9fb0bfc00b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 8 10:38:27 2005 -0600
+
+ Updated Help section.
+
+commit 588d950082edb16d84e25be3cbe05e508a7b7752
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 7 12:13:36 2005 -0600
+
+ Updated documentation.
+
+commit 566985801e6c0016f03ade1e7db72b5dee3ae8e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 7 08:45:08 2005 -0600
+
+ Document structure inheritance.
+
+commit e4850df18d08b20a1a0031dc799a1da03d5791d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 7 02:22:17 2005 -0600
+
+ Fixed floating point exception problems in axes routines.
+
+ Check for negative linetype arguments.
+
+ Minor example updates.
+
+commit ee4a1841c89110ed62e8f397ac854e002a530da3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Sep 6 21:40:47 2005 -0600
+
+ Changed indenting.
+
+commit 02117670c8e92b45396d72f7d75a66302fd5ff36
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 6 01:42:51 2005 -0600
+
+ Incremented version to 0.88cvs.
+
+commit 7381eb69cad5fee52307ccee7f9f5bb09e76d0d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 6 01:01:17 2005 -0600
+
+ Minor documentation updates.
+
+commit 8426dac2922f320c9369e3c3c879d3c546e7fa66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 6 00:26:06 2005 -0600
+
+ Fixed cxx warning messages.
+
+commit bfa77f49f22c3c1a9905fc66f09218427754b879
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 5 23:59:01 2005 -0600
+
+ Added pen option to filltype to specify an interior pen distinct from the
+ boundary pen. Removed Filltype in patterns in favour of a deferred filltype.
+
+ Removed explicit size arguments from bbox (as done with shipout some time ago).
+
+ Updated filltype and 3d documentation.
+
+commit 029d2e662b47c387ebebc13fc90260674c9043d0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 5 22:01:25 2005 -0600
+
+ Implemented general hidden surface removal using a binary space partition.
+
+ Fixed perspective and orthographic when camera is below the XY plane.
+ Also added perspective(real,real,real) and orthographic(real,real,real)
+ functions.
+
+ Fixed draw((0,0,0)..(1,0,0)) and draw((0,0,0)).
+
+ Added convenient 3d circle and arc functions.
+
+ Added abs(triple) (equivalent to length(triple)).
+
+ Added Longitude(triple), which ignores errors along +/- Z axis.
+
+ Ported near_earth and conicurv examples from featpost3D.asy to three.asy.
+
+ Added == and != for structures (equivalent to alias and !alias, respectively).
+
+ For convenience, array push members now return the pushed element.
+
+ Added missing shift in Label.out(frame).
+
+ Updated documentation.
+
+commit 62289d14547a9a96b915e53bb87178dec28a8af5
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 3 20:33:09 2005 -0600
+
+ Added permissions back in.
+
+commit 89b48c38495c92ae2108c6fa93735932b5177815
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 3 14:05:22 2005 -0600
+
+ Added more testing.
+
+commit cc9711396b3d99f223d3ce58bb5bc2e3ea129dde
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Sep 3 14:04:15 2005 -0600
+
+ Refactoring!
+
+ - most #include "camp.tab.h" lines removed in favor of modifier.h
+ - access now uses actions (READ, WRITE, CALL) to control encoding
+ - fundef and newFunctionExp merged
+ - name refactor, and it also uses actions
+ - permission information moved to varEntry (but not in use yet)
+
+commit 8c465e2c865829415c1c60ddd084ec17e27dc73d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 1 15:26:50 2005 -0600
+
+ Moved surface to graph3.
+
+ Added 3d analogues of 2d graph functions.
+
+commit c336fc6032e8eb6146f635de4dc5c5abf32f1150
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 1 12:52:52 2005 -0600
+
+ Added numerically robust quadratic equation solver.
+
+ Added min(path3) and max(path3) functions.
+
+ Simplified and documented 3d arc (analogous to 2d arc).
+
+ Implemented path3 to guide3 cast.
+
+commit 72ab08a82b828d1868e45e295d12469115cf9529
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 1 02:12:51 2005 -0600
+
+ Added 3d intersect and dir functions.
+
+ Added 3d arc function that is consistent with the usual circle approximation.
+
+commit 26441f264c21d9376c26c103b4a00d7d1b3d8ccc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 31 18:26:04 2005 -0600
+
+ Removed diagnostic.
+
+commit 5599da98c47e89d4ba0058ff96f2ebf53477d13d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 31 18:23:57 2005 -0600
+
+ Documented constructors; changed triangle.asy to use a constructor.
+
+commit 360bcfc43026cf5dddbc1692ef35b17b9d6cb28e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 31 16:58:55 2005 -0600
+
+ Fixed permissions for static functions in structs.
+
+commit 5279f696adb7332aabb12a394e0b5fcac02eb0c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 31 11:24:46 2005 -0600
+
+ Simplified path3 constructor.
+
+ Added subpicture example.
+
+ Fixed datagraph example.
+
+ Minor documentation updates.
+
+commit 4f47e8440a219498412fce8e4721ea4f949c40a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 31 01:41:29 2005 -0600
+
+ Use same internal structure for path3 as for path, to facilitate port of
+ various path.cc functions to 3d.
+
+ Added subpath & associated functions.
+
+commit fcda858c92f5ca9c20a7ba421e94309fbf56691e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 30 00:07:16 2005 -0600
+
+ Expose Relative(pair) alignment function.
+
+ Use arclength rather than length for determining default label position on
+ paths.
+
+commit 43eb997c76185828eac94dfd1ad2498e2fc30fa9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 29 23:24:20 2005 -0600
+
+ Added path3 type. Separated project into path3 conversion and projection.
+
+ Added 3d arclength and arctime functions.
+
+commit cc0b4f16dd93c017221d7e082cf10bf012d1cb6c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 28 23:19:54 2005 -0600
+
+ For surface plots on a regular mesh, handle hidden surfaces from any camera
+ location.
+
+commit b47a093a96a40b4d58c5fdf86b26b24dda3c2ac6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 28 03:16:04 2005 -0600
+
+ Added Relative(real) and Relative(pair) functions for labelling paths
+ relative to the total arclength and local path direction.
+
+ Feynman updates (including new function texshipout); moved MidArrow and added
+ MidArcArrow to plain.asy.
+
+ Fixed optional position argument of BeginArrow, etc.
+
+ Update documentation; simplified Makefile.
+
+commit 7e30a5847d91c0e08bfed33bd1d0f763f3929302
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 14:44:40 2005 -0600
+
+ Incremented version to 0.87cvs.
+
+commit b33c29486e4f7697ac6ff8444ac5641f7b8caaa7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 11:43:04 2005 -0600
+
+ Fixed make clean.
+
+commit 5ce73d12c6f676e99e9dc392a00a9448c4a8ba77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 11:35:32 2005 -0600
+
+ Fixed problems with make man.
+
+commit b8e26eb32eafc8a674fe7e6806ff9656da1839c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 11:14:51 2005 -0600
+
+ Incremented version to 0.86cvs.
+
+commit 0c5f16e4dbde2c1209a417db0a404596396b8705
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 04:10:49 2005 -0600
+
+ Makefile tweaks.
+
+commit 658c1b7f623d01f6ff7e454f621a819b51442af2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 03:45:18 2005 -0600
+
+ Add hyperlinks to pdf manual; fixed margins.
+
+ Use imdisplay for ImageMagick display under MSDOS.
+
+commit bac5cf8a82384218a78e1743b14c645c2698498a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 01:55:51 2005 -0600
+
+ ASYMPTOTE_DIR can now be a list of directories (separated by : under UNIX
+ and ; under MSDOS).
+
+ Fixed size_t errors.
+
+commit 2157ec961f63928fd95ef2b04fa11f851cc1ca66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 25 00:38:31 2005 -0600
+
+ Added curl3 operator.
+
+ Implemented 3d generalization of Hobby's Metafont angle calculation
+ that is invariant to rotation and reduces to his 2d splines in the planar case.
+
+ Removed 3d direction specifiers (no longer required) from circle example in
+ surface.asy.
+
+ Merged and simplified tridiagonal solvers.
+
+ When writing paths, output direction angles in degrees.
+
+ Handle null cyclic arrays.
+
+ Added min() and max() members of picture to calculate the picture size to date.
+
+ Updated documentation.
+
+commit e685b2a806c0c2bb1c8beda7ead479ae675807f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 23 10:40:35 2005 -0600
+
+ Diable automatic rotation of pdf files "based on the predominant orientation
+ of the text on each page".
+
+commit 55914553c8440b7b4ac8e2423a5c080a22030948
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 18 20:24:56 2005 -0600
+
+ Include boundary conditions in solution of Dirichlet tridiagonal solver.
+
+commit 70a06b0b923c7911fa5fbf8427297b342b8ffa1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 18 03:01:56 2005 -0600
+
+ Fixed special case of periodic tridiagonal solver.
+
+commit 040f50da4445fad17611025aa46b4f5f52bf782b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 18 02:27:01 2005 -0600
+
+ Allow cyclic indices only on arrays with virtual cyclic flag set to true.
+
+ Added Dirichlet and periodic tridiagonal solvers.
+
+commit 94d5472306d9d06618fe428bb8f4c4af8d9566d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 17 01:33:03 2005 -0600
+
+ Reduce infinity for tension at least infinity on alpha platform.
+
+commit ed54c57b4095c29f9bce4658f313f8f1b23c08c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 17 01:10:37 2005 -0600
+
+ Make interactive help work in MSDOS.
+
+commit e7d2370d6993de8e00e153dc787cf0a3ab6f14be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 16 21:58:04 2005 -0600
+
+ Added online help option; exit is now a synonym for quit in
+ interactive mode.
+
+commit e621bd70a3c91d65c111824db2f36ffe547a314b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 16 11:21:25 2005 -0600
+
+ Improved icon.
+
+commit e285c4e78b5b64f4f5a0f80de0eaa1fcd4ef95f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 16 01:37:41 2005 -0600
+
+ Fixed MSDOS build; improved icon.
+
+commit c3b7054be1c1f937277ac5dcc6c501e776013221
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 16 00:46:23 2005 -0600
+
+ Windows resource template.
+
+commit f251f15b694eff9573d0d2da2e3d8214feed9266
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 16 00:45:31 2005 -0600
+
+ Improved configuration; added icon for Microsoft Windows.
+ Updated documentation.
+
+commit ef1855a10432ecd48f01762799ecb2044ced1085
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Aug 15 21:56:13 2005 -0600
+
+ Generalized bug fix in simplex.
+
+commit f2b4d285f723813d8a455af0ccd8145e1f56ece0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 13 20:05:49 2005 -0600
+
+ Incremented version to 0.85cvs.
+
+commit 7b11142da66ef38ec197aa6902196c423fe2270d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 13 16:04:24 2005 -0600
+
+ Added compilation option msdos for producing Microsoft binaries.
+
+commit b222335e2e00d5d009e397b0293aa613880df4c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 13 15:23:33 2005 -0600
+
+ Removed obsolete file.
+
+commit 8a1308cfa9c96aa34e3b0549c9e9aa84f552ddfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 13 14:29:43 2005 -0600
+
+ Workaround truesize=0 bug in simplex.asy.
+
+commit 8c3fb84711ff038d3cfdd98b660dc5fd0605261d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 13 02:14:40 2005 -0600
+
+ Added lattice gradient shading; check pen size in Gouraud shading to avoid
+ segmentation fault.
+
+ Copy data and palette arrays in palette.asy.
+
+commit 92d4165ebc6399b7e19ba73b0106714b55dc1a4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 12 22:06:54 2005 -0600
+
+ Added 3d reflections.
+
+ Swapped triple arguments of rotate(real,triple,triple) for consistency
+ with the 2d reflect(pair,pair) syntax.
+
+commit 458ddeb5d1b31bd2b4521db28f3e73fd35a6d040
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 12 18:58:04 2005 -0600
+
+ Removed (size_t) array.size() casts as they are no longer needed.
+
+commit 8fd359bbc24b543bb02812ce022f16e9098f6bcb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 12 17:43:09 2005 -0600
+
+ Added support for Gouraud shading.
+
+ Moved nullpath into plain.asy.
+
+commit d1124e20942c9936b8496aa81f556523578bd1ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 12 14:01:12 2005 -0600
+
+ Cleaned up autosize code; more pair to align changes.
+
+commit 5b6bcc41a9a5592baceac64eeaa70a9b94432dce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 12 01:22:26 2005 -0600
+
+ Updated example; removed extra instance of defaultformat.
+
+commit 2278332d804f2eaf243134bd1ec2fd70667ca657
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 12 01:04:45 2005 -0600
+
+ Put label parameters in a structure called Label, to which a string can be
+ cast, and which can be rotated and shifted (in Postscript coordinates).
+
+ Updated examples and documentation.
+
+ Fixed automatic sizing under picture transformation (particularly under
+ rotation) and handling of an unspecified size in one direction (denoted by
+ infinity).
+
+ Added size(real Size) function that ensures each dimension is no more than
+ Size.
+
+ Added scale(bool) function for enabling or disabling autoscaling in both
+ directions.
+
+ Simplified 2d graph and palette code.
+
+ Added begingroup/endgroup checks.
+
+ Added array append method.
+
+ Removed unused duplicate variable check code.
+
+ Added virtual transform components and transform 6-tuple notation.
+
+ Added pen and filltype to Legend.
+
+ Removed labeldot(z) in favour of dot(Label,z).
+ Removed labelbox and labelellipse in favour of box and ellipse.
+ Removed labelxtick and labelytick in favour of xtick and ytick.
+
+ Updated pstoedit support.
+
+commit 0712f98328d85a4b05e28ab7f8ec06fb826089c7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 6 22:49:23 2005 -0600
+
+ Used cast from path to path[] (superpath) to simply fill and clip code.
+
+commit 6b60cb1c02e933391fe6fe71f250fbf4f06b4c76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 6 09:18:40 2005 -0600
+
+ Remove .asy_input on exit.
+
+ Disable display (which requires Xwindows) under MSDOS.
+
+ Minor documentation updates.
+
+commit 471947f4346c6a081168c180d3860d0922f8ce35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 6 02:26:52 2005 -0600
+
+ Added simpler helix example.
+
+ Moved pticklabel to LeftTicks, etc., as the argument plabel. Added pTick and
+ ptick pen types for drawing big and small ticks with different sizes,
+ bool beginlabel and endlabel for suppressing first and last labels,
+ and extend for drawing ticks across the graph (useful for superimposing a grid
+ on the graph).
+
+ Improved optional first and last tick/label suppression.
+
+commit 2979a61075d1158ef648fe7eddb18661dfaef4a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 5 00:11:15 2005 -0600
+
+ MSDOS environment variable tweaks.
+
+commit 20ffd949b7ba98ff8d14140b05d69bf9abecd6c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 3 21:19:47 2005 -0600
+
+ Fixed MSDOS interactive mode: the postscript viewer child process should exit,
+ not return. Searching for an available postscript viewer is not possible in
+ general (but the desired viewer can be specified with the appropriate
+ environment variable).
+
+ Added environment variable ASYMPTOTE_GS and drag and drop support.
+
+ Make -V the default under MSDOS. Added -n (-noView) option.
+
+ Updated documentation.
+
+commit fb19d535f3e2a4b7f6584e0b87433b251e9fee82
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Aug 3 00:40:41 2005 -0600
+
+ ''
+
+commit 37e9bb19a8f7caa9e0ef71df2d60ab936617256f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 2 16:56:01 2005 -0600
+
+ Port to MSDOS (via CYGWIN).
+
+commit 1818887efb3cdb3e028b0f916e85f17b5bbe6e52
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 30 18:06:58 2005 -0600
+
+ Removed unused file.
+
+commit 6bd7333155bf70bb3bbdb693c94232edb82c2268
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 30 18:05:56 2005 -0600
+
+ Changed operator :: and operator --- to loops.
+
+ Simplified fill commands.
+
+commit b5520d7fa95220615fb9ef0b78d49ccbbf59b637
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 28 16:11:45 2005 -0600
+
+ Remove %%DocumentPaperSizes: comment inserted by dvips 5.95a.
+
+commit cea91fe4920c0a80d363ab8b9922f8a1bb6a8b08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 23 20:44:32 2005 -0600
+
+ Simplified graph routines.
+
+ Fixed nullguide3 problems.
+
+ Began graph3d construction.
+
+ Updated documentation and examples.
+
+commit 3b2bec7369e882e5503024872a5979ad911e63de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 19 01:21:19 2005 -0600
+
+ Updated menus.
+
+commit 914bb61f8d933fc7be05d8b3575332d8348abcde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 19 01:20:58 2005 -0600
+
+ Incremented version to 0.84cvs.
+
+commit e13ab6c7f082b61bb601f56fa8886aead6ec4e73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 19 01:09:04 2005 -0600
+
+ Updated error test.
+
+commit 63130f923bc2c7e60dc603ab1b96213485b626c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 19 00:20:13 2005 -0600
+
+ Changed default angle for oblique projection to 45 degrees.
+
+ Updated documentation.
+
+commit 2749b658316f1d55cabf53a1e04765f1a9f8cbc6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 19 00:09:44 2005 -0600
+
+ Used existing internal function relativedistance for control point
+ computations.
+
+ Renamed path3 to flatguide3.
+
+ Added tension3 specifier.
+
+ Standardized 3d angles, rotations, and scalings.
+
+ Added guide3 operator :: and ---.
+
+ Added write(path[]) and write(guide3[]).
+
+ Added helix example and updated documentation.
+
+commit 937788e4da1af9aea5db0b84b289d06b6513f2c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 18 12:17:33 2005 -0600
+
+ Determined correct signs in direction-to-control point calculation;
+ propagate directions across nodes.
+
+commit 870b952575d525561fef879d8275535164f45e79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 18 00:38:55 2005 -0600
+
+ Implement preliminary 3d direction to control point conversion.
+
+commit 1ded168026a740e8824a8bd26086cc5c9dbcb089
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 17 22:52:16 2005 -0600
+
+ Move math mode ($ delimiters) to within defaultformat string, to allow use of
+ non-math mode fonts in tick labels (by providing a nondefault format string).
+
+commit 2c3bb514f504827b901d46d3a94ef5ebad7f4df7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 17 19:20:33 2005 -0600
+
+ Fixed bug in string font(pen).
+
+ Changed Angle(pair) to degrees(pair).
+
+ Added Degrees(pair).
+
+commit 6f9dca898b83e9ff030ba468eddfcb1ac6965bae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 17 15:36:54 2005 -0600
+
+ Allow reading three-dimensional arrays in line mode by recognizing blank
+ lines as block delimiters.
+
+commit 7127bd4200705f9633e0ed6347ebb1021abbe74f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 17 00:56:24 2005 -0600
+
+ Added pticklabel option for drawing tick labels with a different pen.
+
+commit cc966acccd13aa156df004d167a1d06d14f08fe4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 17 00:02:10 2005 -0600
+
+ Added labelxtick and labelytick. Fixed tick size and shift in xtick.
+
+ Updated documentation; added examples.
+
+commit 70508236ecc0b0c0ae77808bf78c4d3b855154bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 16 19:25:01 2005 -0600
+
+ Fixed problems with autoscaling and unextended axes.
+
+commit 91bdd8bb360ed9e9e5a09865b3643cec1297582c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 16 16:11:52 2005 -0600
+
+ Renamed internal xequals and yequals routines to yaxisAt and xaxisAt.
+ For clarity, renamed xline and yline routines to xequals and yequals.
+ Added initializers.
+
+commit a6ee9fb43c363f80172e53212bc401986648ab90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 16 15:27:57 2005 -0600
+
+ Disabled -laat while line-at-a-time mode is under construction (due to
+ known segmentation fault).
+
+commit 5a6c23c6534033e74d0355aa973bdc6cca9383c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 16 15:25:11 2005 -0600
+
+ Added and documented remaining triple functions.
+
+ Renamed Dot to dot and Cross to cross.
+
+commit 48bdb985c239e446172110af446483c9c7c54070
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 15 23:24:33 2005 -0600
+
+ Simplified three.asy; added oblique projection and ^^ operator.
+
+ Added Metapost --- operator; allow :: to accept a direction specifier.
+
+ Allow user-defined ++ binary operator (for consistency with -- binary
+ operator).
+
+ Minor knot velocity optimizations.
+
+ Added surface example to documentation; updated cube example.
+
+ Updated documentation; fixed cxx warning messages.
+
+commit f55c3d8ce0124a606e60f5a9afc7c80c85129228
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 15 18:08:15 2005 -0600
+
+ Fixed crash caused by fixing previous crash.
+
+commit c9ee358dfb9c1d7d4649297684d3597b3a3cae38
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 14 23:55:20 2005 -0600
+
+ Handle tensions in straight sections of paths as MetaPost does.
+
+commit f400a194bc43e83e554339a6fd37da12c6d34155
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Jul 14 23:36:10 2005 -0600
+
+ Fixed controls versus direction specifiers crash.
+
+commit c4dcf1344fd4a9456d9046f003bf523f1a604abd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 13 23:49:56 2005 -0600
+
+ Added array pop function.
+
+ Give DIRTAG the same precedence as CONTROLS and TENSION.
+
+ Added replacement :: for Metapost ... joiner (which selects an
+ inflection-free path where possible).
+
+ Added 3d direction specifiers, pending 3d conversion to control points...
+
+ Added triple write and interp functions to plain.asy.
+
+commit 2199e1848a4967b147886dacc9ad31fa334092c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 13 12:43:04 2005 -0600
+
+ Formatting.
+
+commit 4c431fc643f1b1a7decc1cc4f4382f444bc37211
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 13 10:22:40 2005 -0600
+
+ Cleaned up controls.
+
+commit 3612779360607dc5917e9f4d02327d015c5e25ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 13 02:25:08 2005 -0600
+
+ Renamed cycle3 to cycle.
+
+commit ac6d8ef05a0d6d73d6fec93449040fe18d80023d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 13 02:18:10 2005 -0600
+
+ Renamed controls3 to controls.
+
+commit 75d7070454393e590e98bd198bda1c9e210adb53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 13 01:45:11 2005 -0600
+
+ Added controls3.
+
+commit 121f84f3c3e799a416d30c37275901945812d90d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 12 22:42:28 2005 -0600
+
+ Compute knot solving constants.
+
+commit 2b804bf9bd2b3d42cb81f2d97b5494fb99b55b83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 12 22:41:55 2005 -0600
+
+ Fixed write(guide).
+
+commit 487442b4497cc979d325312e3968ee3b0dbb3dbf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 12 17:54:48 2005 -0600
+
+ Allow operator ::.
+
+commit becfe77e7d0810f52d278c8f359b6f81e43d8c2c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 12 14:51:53 2005 -0600
+
+ Added explicit check for readline remove_history.
+
+commit d65281af33667616aa7fa507e0fb586b2f02de24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 12 14:29:30 2005 -0600
+
+ Readded installation hint about ancient readline versions.
+
+commit cea008852e9f7696fbf067f88ca61d4a212f98d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 12 01:33:20 2005 -0600
+
+ Fixed lookAtOrigin.
+
+commit 8873f0e6c0a6b6e000834b05aa2e40624fd4f34b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 11 23:40:32 2005 -0600
+
+ Updates to triple and three.asy.
+
+ Removed unused code.
+
+commit c4bb1e07b019f9d20ca4b45f5c3b30a594bf6ead
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 11 17:51:26 2005 -0600
+
+ Replaced vector by triple.
+
+commit ec576c536aa71d8f61ab36bbd4f70d9609dd71ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 11 13:40:51 2005 -0600
+
+ Fixed casting error message.
+
+commit 2fcfc38e0b95f9389006e17a4db7c5669109b23a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 11 09:03:05 2005 -0600
+
+ Added triple type.
+
+commit 8d3006e7e73ca5749593afda62137897b1813df9
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 8 18:07:10 2005 -0600
+
+ Graphing tests.
+
+commit df0b3e8906aea47212a01d8de43913cac4508eb4
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 8 16:19:37 2005 -0600
+
+ Moved laat diagnostic.
+
+commit 8482bd7fc31e98344535b1b255cdc4bb7d54a28d
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Jul 8 12:23:29 2005 -0600
+
+ Proof-of-concept code for true line-at-a-time mode.
+
+commit 5070a16600ca4489ebd6010252314d197bd52137
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 7 16:32:43 2005 -0600
+
+ Removed path to pair[] ecast.
+
+commit 85c5b9fbf6e1873dcbda8abee85821ef2bc7f1c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 7 14:51:54 2005 -0600
+
+ Updated example.
+
+commit 702b88ea4ed4a7c2774478ef6e2742de37d25891
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 7 14:51:10 2005 -0600
+
+ Removed explicit pair[] to guide casts in favour of operator --(...) and
+ operator ..(...).
+
+commit f12122d7d697977227a55006a6ec0fe7c9c67aaa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 7 10:40:14 2005 -0600
+
+ Fixed default CFLAGS.
+
+commit ec04162a4cc57c28005b546366116fbd6b5fff66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 7 09:42:18 2005 -0600
+
+ Fixed CFLAGS.
+
+commit 897655354414af0004023922f087b59e87359078
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 7 01:42:09 2005 -0600
+
+ Updated documentation.
+
+commit 96e8dcbefd26513ad7756819b82c620226afbe01
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 7 01:37:36 2005 -0600
+
+ Fixed error in CFLAGS.
+
+commit dc004fc8fc0e3827128b836efd9770149697f75e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 6 20:21:56 2005 -0600
+
+ Added implicit pair[] to guide and guide[] casts and explicit path to
+ pair[] casts.
+
+ Removed unnecessary guide=nullpath argument from graph calls.
+
+ Renamed LinearInterp to Straight, to correspond to straight(path).
+
+ Updated nullpath documentation to correspond to new solver.
+
+commit 435bc11e0ccd480cdd8e8d7777900a0188de1f2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 6 14:50:50 2005 -0600
+
+ Removed -version command-line option to avoid ambiguity with -verbose
+ (so that -vv, -vvv etc. will still work).
+
+commit 0e1511db2c1e2eb2c28ef6effc3843096c7c014c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jul 6 09:11:39 2005 -0600
+
+ Change NOHASH to use #ifdef.
+
+commit d308e9c9ff7ff074165aea3052dbb7aedd353675
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jul 5 21:26:42 2005 -0600
+
+ Three dimensional drawing routines (in development).
+
+commit 961c33b0a6cc451667a38b325a511817dc5f5524
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jul 5 14:25:56 2005 -0600
+
+ Join operators now use rest arguments.
+ Fixed a bug in solving empty guides.
+
+commit c8462c291d2bab76c1326b5eb6dbc3aaeb0f3d7f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jul 5 14:24:33 2005 -0600
+
+ Combined duplicate code for function defitions.
+
+commit 5fbc0b1206bda3f047061e003363da1258804277
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 4 16:36:50 2005 -0600
+
+ Minor documentation updates.
+
+commit 9b3476a73d77e000535e974dcdd12012ac1aff8c
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Jul 4 11:46:43 2005 -0600
+
+ Added back venv::list().
+
+commit b5cde48655d6783eb11682d4a4c93a5021004fcc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 3 10:16:43 2005 -0600
+
+ Added -version command line option.
+
+commit d683279f3e5644e1b32f308afc423577e6cfc0e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jul 3 00:12:58 2005 -0600
+
+ Incremented version to 0.83cvs.
+
+commit 36064f240706d61dce609de902b06784eb5078ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 23:02:03 2005 -0600
+
+ Updated man page.
+
+commit 747b96aed8fa04a140c571d59ef5af95aaca7cad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 22:51:28 2005 -0600
+
+ Fixed cxx warning messages.
+
+commit c67298c4406af9fa1911e77e25e125b86bb99125
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 22:16:17 2005 -0600
+
+ Added -d command-line option to produce extra debugging messages
+ (currently only "named argument may be mistaken for assignment" warning).
+
+commit 3d07163a7e068e678aa0cdc012cc69688fb1e0a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 21:39:27 2005 -0600
+
+ Added arrow option to axes routines.
+
+ Renamed xlabel and ylabel back to labelx and labely, respectively.
+
+commit 8615b39fd4b63a3f6e0e083feb68e2f061d2250c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 16:07:35 2005 -0600
+
+ Revert last changes.
+
+commit 5a0a45dbd3f057b31fd856b0022f3285ac0a004e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 15:46:09 2005 -0600
+
+ Fixed more cxx warning messages.
+
+commit 5a14e04b0be64ba665efaf985917eb0b889714f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 14:23:42 2005 -0600
+
+ Added configure option to detect ext/hash_map and set -DNOHASH accordingly.
+
+ Fixed cxx warning messages.
+
+commit 68032946b747b4dfd1b5e3913a77e33acce913a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 12:11:44 2005 -0600
+
+ Standardized xtick and ytick routines.
+ Renamed labelx to xlabel and labely to ylabel.
+
+commit f3eaf91cbf09737e1c02a6f63c442b03c6bbed0b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 2 11:45:31 2005 -0600
+
+ Added NOHASH option to compile on non-gcc compilers.
+
+commit 712ee95f04440fc4cea116da8859d056a7e7b6e1
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 2 09:55:32 2005 -0600
+
+ Excised from exp.h so that dec.h includes less.
+
+commit d41caf49827f36ba3bd2757b6b66a98102e5751b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Jul 2 09:49:23 2005 -0600
+
+ Allow dimensions for types in cast expression.
+
+commit 98392f1425dc4b258e1c6330d04ce408b0f44a72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 2 03:24:05 2005 -0600
+
+ Added ability to specify custom tick locations.
+
+commit 99ec8fe50925985c7af8f279ed5cfc0ac5b60ae9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 1 22:58:28 2005 -0600
+
+ Fix warning messages when XDR is disabled.
+
+commit 6cc9aff28f9f93fe8f0b7a186f0b0c151908be3f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 1 22:57:53 2005 -0600
+
+ Added more default initializers.
+
+commit 263a62cab3e21ffcadb3321b88e1e670ffdee4fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 1 18:30:30 2005 -0600
+
+ Allow explicit casts to any name. Documented general implicit and explicit
+ casts.
+
+commit 93c022eba77fe64edf81f3e1bf1ca6dff9a57edb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 30 22:57:13 2005 -0600
+
+ Documented named function arguments and rest parameters.
+
+commit 86ce95c91b1969c3dc687ca24c9c9ceeb17bc3a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 30 20:34:33 2005 -0600
+
+ Fixed warning messages; updated bison patch to bison-2.0a.
+
+commit d6c19397b1f035d6bc16efa94a8bf41065104b5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 30 16:45:32 2005 -0600
+
+ Fixed more warning messages.
+
+commit 69027f1cd60cee0999ce6bdc9ca17657ff383a85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 30 16:42:23 2005 -0600
+
+ Fixed cxx errors and warnings.
+
+commit a45db697f1d4628d213fc4a9966be95f1319b3e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 30 16:38:14 2005 -0600
+
+ Replaced strdup by strcpy.
+
+commit 324616f76ed6760212d89eb575aee654b58e4a99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 30 12:41:57 2005 -0600
+
+ Renamed nullframe to newframe.
+
+commit 973f076227f1f9feb36b6cfc10e5d3a66c8d4d76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 29 21:04:53 2005 -0600
+
+ Fixed memory leak and segmentation fault in fileio garbage collection.
+
+commit 65ba1202445428f21aa01072764d1331d581e231
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 29 20:58:11 2005 -0600
+
+ Renamed write function keywords.
+
+commit 7687aaf40c4c43f14f9b6a38fc347d9347759250
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 29 10:15:51 2005 -0600
+
+ Extend use of operator init().
+
+commit 7bbc7ffd8f0926263ebe3dcdf3bb533c4211b661
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 29 09:59:15 2005 -0600
+
+ Added default initializer to picture; removed "=new picture" from examples.
+ Documented operator init().
+
+commit 40f98c94b8eebb8d980e1e5a1cb91826b8f074f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 29 09:11:58 2005 -0600
+
+ Removed ticksT tag.
+
+commit 7f8a16c28ede11e3d766c0076388a9e83f083a9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 29 00:38:20 2005 -0600
+
+ Fixed memory leak in locateFile.
+
+commit 999724c552b1bc6decc328ef2bf7d5e6149e65ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 28 16:16:00 2005 -0600
+
+ Removed unnecessary semicolons.
+
+commit 6a7bafe452621d0d92af547a3d180c5eaf840734
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 28 15:56:58 2005 -0600
+
+ Added virtual destructor.
+
+commit 42c406e577ba81982d7cc1e73c1543b55e8d192f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 28 15:53:29 2005 -0600
+
+ Added virtual destructors.
+
+commit 06a72c88aae59f5fca97df49c883053519a0eec9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 28 14:49:30 2005 -0600
+
+ Remove xsize, ysize, and keepAspect from shipout, in favour of size().
+
+commit 6221960d98b1eaacaa0b62a11fa58671218afa15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 28 13:58:03 2005 -0600
+
+ Added -lgccpp also with --enable-gc=system.
+
+commit 0c8071fb5b46edc79cb7eac9b95137efe9c2b9cc
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 28 10:12:57 2005 -0600
+
+ Put reverse functions back in.
+
+commit ef73fd797e874069cb3bae12142687f5664b25bd
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 28 10:01:21 2005 -0600
+
+ Results of type overhaul:
+ - venv now uses a hashtable to quickly look up variable of a specific type
+ - initializers and casts are now functions in the environment
+ - matching arguments to signatures handled by application class
+ - (side-effects of) expressions are evaulated left-to-right
+ - exp::trans(e, target) split into transToType (which implicitly casts) and
+ transToType (which doesn't)
+ - added keyword and rest arguments
+ - added formal class to types
+
+commit 30360c059eb668792eede35aa7e70cc9795fc024
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 26 16:51:59 2005 -0600
+
+ Work around spurious uninitialized warning message under gcc 3.3.3.
+
+commit 1fab77145419b3a8c293886316cf0615aa479a31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 26 10:51:17 2005 -0600
+
+ Code cleanup.
+
+commit 7c1f4b8c287ed51690f8f58a72c21475c73e66e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 26 08:43:12 2005 -0600
+
+ Allow use of single quotes to prevent system command word splitting on spaces.
+
+commit e7d84297b6fa78065f7aec133561e091d4fb0dc9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 25 15:49:08 2005 -0600
+
+ Fixed bug in fill, due to a numerical precision issue, which shows up with
+ g++-4.00 under optimization.
+
+ Removed unused routine and declarations.
+
+commit b8c2076390a55d40feadb3582c36f6b58d0401b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 25 14:11:19 2005 -0600
+
+ Removed unused virtual destructor.
+
+commit e5e0222dc27968c1bc861bcf8eddb1824f058464
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 25 12:33:59 2005 -0600
+
+ Simplified tag handling.
+
+commit eb5c02ce2b1c8bedee35969a01ead70a9f1aad63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 25 00:14:38 2005 -0600
+
+ Replace OverwriteT with integer variables.
+
+commit 53be12a2dc5107723d622b2dbb5d0adeba1a02fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 24 18:58:34 2005 -0600
+
+ Simplified coding of endl and tab qualifiers.
+
+commit 786d08c54af70163a90e5b3c749ee9f66fafb2e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 23 16:34:34 2005 -0600
+
+ Incremented version to 0.82cvs.
+
+commit fc3936487524cb3f3b9c3db37dae58da1088be18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 23 16:08:48 2005 -0600
+
+ Fixed indentation.
+
+commit bf638882197f630bc059f313818257b5e55e3ba0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 23 15:55:47 2005 -0600
+
+ Fixed g++-4.0.0 warning messages.
+
+commit ce9963563164d53e3e56606107fc7ec2d8f8242b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 23 15:54:46 2005 -0600
+
+ Fixed cxx compilation error.
+
+commit 228fb9f82473fc672420fc8ad15818fc6002ca60
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Jun 23 00:45:25 2005 -0600
+
+ Cleanup headers.
+
+commit b0ce04a0381fd68e46b89e9640008521ed78d268
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Jun 22 23:53:11 2005 -0600
+
+ Maybe fix GC on darwin.
+
+commit 1aca5cb33094f702c4cbba83c8025b88a8db37c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 22 10:54:03 2005 -0600
+
+ Replaced writeP in favour of write; added writen entry points for pen,
+ guide, and transform.
+
+commit 4aad24ec76db0bcdf85c20c8853dd32d7faf21b8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Wed Jun 22 10:16:11 2005 -0600
+
+ Fixed solving bug.
+
+commit 9047174da0fda3e36f2e661e17bf2fb30e821440
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 21 22:27:52 2005 -0600
+
+ Allow graphs with just one data point.
+
+commit a4a3810378e465f5512a6b89ac1d248391203947
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 20 17:03:14 2005 -0600
+
+ Feynman updates.
+
+commit 0ff48d1cb5a153e4809622ca1c5ddd5d5c834550
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun Jun 19 23:18:55 2005 -0600
+
+ Split up inst.h.
+
+commit b3a216a59ca9b04ae5e0f6dbcf4071a9b52fe034
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun Jun 19 17:53:14 2005 -0600
+
+ gcc4 is more const.
+
+commit a5ef2fede293c3b425acae8925c611a25c5db257
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 19 14:16:22 2005 -0600
+
+ Incremented version to 0.81cvs.
+
+commit 7640c06a07aa590c86937edda50221b828d92fde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 19 12:08:27 2005 -0600
+
+ Upgrade to use Boehm gc6.5 garbage collector.
+
+commit 8b0c625a0bf30a0a6d3420408728b3efd9e028b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jun 19 11:43:34 2005 -0600
+
+ Tom's patch to pool segmentation fault.
+
+commit 0b4f978f5be4ce481bc36324ce3f9d576c387a9b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sat Jun 18 10:44:58 2005 -0600
+
+ Remove obsolete maxStackSize.
+
+commit 5ef2d397015ca2b23082eb3b21e20f3862cc7ff1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 10:27:49 2005 -0600
+
+ Deep copy all members of picture.
+
+commit 7ca2c12fb5c00511a1d6be5b068c7f74c94a5c06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 18 09:59:39 2005 -0600
+
+ Quick installation instructions.
+
+commit c8bab82babbbe7ca95ca0ebbbfafb8359bdcd87d
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sat Jun 18 00:28:36 2005 -0600
+
+ Tests.
+
+commit 5a3eb6b5360d49f43b8d3a9840117fb6a0457d3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 23:35:20 2005 -0600
+
+ Incremented version to 0.80cvs.
+
+commit 659f7d3d6a4e5876c2d7d60a229aa2ec240a2c49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 22:49:15 2005 -0600
+
+ Removed unused features.
+
+commit 3e206225f18b9cea342971f9d80cd49b87dad499
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 22:32:31 2005 -0600
+
+ Fixed cxx warning messages.
+
+commit ae029118e4eeb265e8e7ed33745b973a718c6a90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 17 22:06:19 2005 -0600
+
+ Check for empty picture in secondary axes routines; added another example
+ of a secondary axis.
+
+commit e991c4e70ea5cd8b054c959aab9d7f8fb80b5a40
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Jun 17 21:27:16 2005 -0600
+
+ Automate testing.
+
+commit 7170cdbcd547faac66e18d7338f5bc2ef3ecd5c6
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Jun 17 21:21:51 2005 -0600
+
+ Change vm::program to holds insts directly.
+
+commit 8d97404395b2f98c5e2c68c15b089d761b8b0d01
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Jun 17 21:20:48 2005 -0600
+
+ Compile genrun.cc seprately.
+
+commit 133bca6f546e881329dcedc281fbbe54e07657e5
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Jun 17 21:19:51 2005 -0600
+
+ Move vm interface to vm.h.
+
+commit 908662091c942dfdee84c686e122b3240fa4b13e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Jun 17 18:48:32 2005 -0600
+
+ Properly collect fileio.
+
+commit 7391769e36b96247ffa6ba708e7a4c76605032e0
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Jun 16 00:20:47 2005 -0600
+
+ item handles GC allocation.
+
+commit d03ea3fd7b84cb06f37cab421ea4c54c6e01ea94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 16 00:12:16 2005 -0600
+
+ Readded 2005-05-26 fix for substr bug.
+
+commit a5dd9570b514d7c944f2c29264a9c4b430a24561
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Jun 15 23:47:13 2005 -0600
+
+ Make evrything use GC (except fileio).
+
+commit 879010025056803e415fb28e6bcbe2cfb9180e20
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 14 22:33:17 2005 -0600
+
+ Don't allow a picture to be added to itself.
+
+commit 814f0cd08ae74f5621277a9e6a1683693fc3dc51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 14 20:30:06 2005 -0600
+
+ Backported recent castop.h change to g++ 3.3.4.
+
+commit 929a119630125233503a1aa11e335ea3013f8d9a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Jun 14 15:23:42 2005 -0600
+
+ Added getType caching.
+
+commit 5663c6136190c2ad9c1dd9037b6509fd1977d2dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jun 13 10:28:09 2005 -0600
+
+ Reverted gc/gc.h change back to gc.h.
+
+commit df6c338131f8dbc1aabbb47f3ba3e34ca55a9201
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sat Jun 11 14:04:12 2005 -0600
+
+ Test collecting pens.
+
+commit 666663e0b88bbfaffef0e1f37bfb4274a6d89b18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 4 13:51:44 2005 -0600
+
+ Document type1cm.
+
+commit b2a9d4f54135f117e09ddb79cbdc97180a0b6762
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 31 23:33:39 2005 -0600
+
+ Fixed autoscaling of scaled axes, e.g. Linear(x) with x != 1.
+
+commit c12f36fff471f47ccd94d6778f57c673426eeb42
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 29 10:06:31 2005 -0600
+
+ Added asymmetric Pythagorean tree example.
+
+commit 6c9ce87dee6a8700af83fda8b70dc1e78671f170
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 29 10:05:48 2005 -0600
+
+ Added aSin, aCos, aTan functions.
+
+commit 4fd7e3e1ab590d46384fb3e7e13d7bba5008165c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 27 16:33:21 2005 -0600
+
+ Changes for Debian port.
+
+commit 3688cbe0fcfe962cbdbb893b2161fcb293b04f88
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 27 15:41:56 2005 -0600
+
+ Fixed memory leaks.
+
+commit 4804e27a5a9ad3bca0830b384de9b59ed4337818
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 27 02:16:14 2005 -0600
+
+ Fixed memory leak.
+
+commit 4c22b96cea1ca707525c68d06399209dab20f701
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 27 00:44:19 2005 -0600
+
+ Added Tom's remaining garbage collection changes.
+
+commit 8b4e56cc1919f5bb9cc200880bf342710b7340c6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri May 27 00:09:58 2005 -0600
+
+ Garbage collect files on explicit closure and at exit.
+
+commit 1043dd6738f0854a18eb06ae2f23049170dafeb2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 26 09:55:30 2005 -0600
+
+ Fixed substr bug.
+
+commit 1d2aba32ccbe2ffe8d98e63f141aa9135fe3c84f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri May 20 10:48:54 2005 -0600
+
+ Changed wording in comments. Indenting.
+
+commit f78764d8575f157d65c3fb29a57402fdb0f84b3a
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu May 19 23:45:26 2005 -0600
+
+ Use mem::string during runtime.
+ Make encode(inst) private.
+ item.h calls new(UseGC).
+
+commit 44d7d2eb8118d63d6677640b93df55a686e15876
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 19 10:16:48 2005 -0600
+
+ Incremented version to 0.79cvs.
+
+commit 06ba32ea3cc72df31457fd4cf7251b84afdbb1bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 19 09:15:54 2005 -0600
+
+ Disable GC_STRING for now.
+
+commit 93e05817f8eacffccf61024f8184a1e174e61b70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 18 23:27:15 2005 -0600
+
+ Port to cygwin.
+
+commit 05ef90f1dc3f03dcbf91ed112b637ff8ef3b2ff5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 18 14:34:42 2005 -0600
+
+ Move file back under control of memory::managed to ensure deconstructor is
+ called.
+
+commit 732b7af7652ff7aadd0ff33d677c7991966a4c43
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed May 18 12:41:26 2005 -0600
+
+ Use item for everthing in inst.
+
+commit 2b9de84a90affbcca034cd53151e420ee22b68d2
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed May 18 12:37:44 2005 -0600
+
+ Define mem::string.
+
+commit 47eb80b05a3c6f3f2d8279dcca3bd44268412840
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed May 18 12:36:17 2005 -0600
+
+ Use coder::encode everywhere.
+
+commit 7ca4fa121bcc6842b5242c6fd021a9e26e1a5b0f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed May 18 10:50:31 2005 -0600
+
+ Cleanup memory.h.
+
+commit 2fb95aa9a09de3f07dca638d5075e2c9a875f15b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 18 09:17:32 2005 -0600
+
+ Changed index to strchr for cygwin port.
+
+commit ee106d42346f159b5c4a04f9479182ff967f4fc0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 18 09:17:09 2005 -0600
+
+ Fixed LIB.
+
+commit d0caf2dc14550c4cd0586c7ba95fea9a00cd5ff8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 14 22:29:43 2005 -0600
+
+ Check headers earlier.
+
+commit baf991ce70cf496154b3806d230714407d80480d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 14 22:26:46 2005 -0600
+
+ Make --enable-gc=system also check for gc.h.
+
+commit 89e15737ee45fd6b2a82a3b6903eb5398a2d11e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 15:56:27 2005 -0600
+
+ Workaround "GC Warning: Repeated allocation of very large block" messages.
+
+commit dd8ec509559e108b1195377e0cfba98618aff5e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 15:54:42 2005 -0600
+
+ Fix NaN handling.
+
+commit a6b8695d6aa652eb4185556bee518f8b145f4077
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 12 08:56:42 2005 -0600
+
+ Better checkaxis test.
+
+commit 3e04076b94e311a46ae4b3a0d1e22c2bc66bb273
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 11 22:07:40 2005 -0600
+
+ Added --enable-gc=system configuration option to use system libgc and libgccp.
+
+commit 52a42f6f9e35ea0f38222059e4ccfdbf66b0fe85
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 11 03:52:11 2005 -0600
+
+ Define traceable_allocator when garbage collection is disabled.
+
+commit edd6882d84f7f5b11ddc95614016c7d2f4619ea4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 10 21:52:35 2005 -0600
+
+ Added binary search routine.
+
+commit ab8884bd75e11e48bf10ce36008affb9202c5cce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 10 16:34:50 2005 -0600
+
+ Incremented version to 0.78cvs.
+
+commit 880ffa76cda64193d3999d076cfe05be83921d00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 10 14:56:30 2005 -0600
+
+ Recommitted changes: 2005-05-10 rtprince
+
+commit 81b45f905368cd0f8cc87f42d14e132a4154a7de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 10 13:56:23 2005 -0600
+
+ Revert broken changes: 2005-05-10 rtprince.
+
+commit aa6798bedb31788d8a41e5aef90a45e0fd45283f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue May 10 12:36:42 2005 -0600
+
+ Make CVS -lgccpp clean.
+
+commit 99948123780c9eddf2e553e818d116a3a5b20cd8
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue May 10 12:31:32 2005 -0600
+
+ Make item use new(UseGC).
+
+commit f283b6b03b888608633d18b169ad15ef749507e4
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue May 10 11:43:15 2005 -0600
+
+ Add some tests.
+
+commit f338d6ca188330b5a06160a0d393777fb63ae742
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 10 11:16:21 2005 -0600
+
+ Renamed example.
+
+commit 15e66f6f42b64b39deb1df4bffdeb8c4c1bd66ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 10 04:37:53 2005 -0600
+
+ Distribute Boehm GC as a separate package.
+
+commit 5c9d00f9e02c175e3db240726725e35ae5facf06
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 23:08:51 2005 -0600
+
+ Fixed error in map & multimap.
+
+commit d84ef94ce525b66d05d864e5bbe76c014962f520
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 22:49:00 2005 -0600
+
+ Fixed parser leak again.
+
+commit e4f9e737d32b0e29b61e29ee7144a0c305be8766
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 21:57:44 2005 -0600
+
+ Fixed broken draw call.
+
+commit cde542ef8dc261e00c389e94c4fe0703b89686d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 16:41:16 2005 -0600
+
+ More gc string updates.
+
+commit 915f14d3423c86ceb4f974b2254f23eddba0129b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 16:22:25 2005 -0600
+
+ Unused file.
+
+commit 2b6d60c72af8208812baa28d45c3fed5d03bb057
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 14:01:57 2005 -0600
+
+ Handle out of memory errors gracefully.
+
+commit 6cd09e17608cc0276c7106d4fb84f83642b1ca03
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon May 9 13:22:55 2005 -0600
+
+ list<decid *> is from mem::.
+
+commit a2ead4f31103e6e2bdabd1217e5a650bee12ecbf
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon May 9 13:17:32 2005 -0600
+
+ Make theStack be mem::deque.
+
+commit 5131270c76da87b1f7691b10716c3fde47172d2c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 10:25:33 2005 -0600
+
+ Fixed segmentation fault.
+
+commit e66a390c9622e6e64fb1e2a8e1f759afffec290a
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon May 9 05:24:22 2005 -0600
+
+ Dont gc non-heap string.
+
+commit 0827cba25c7b3504b0cd28b750fc22872757f14c
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon May 9 04:58:00 2005 -0600
+
+ Fix makefile. :-(
+
+commit e7ad2436de51081564fc88f024b777d693d0c325
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon May 9 04:56:30 2005 -0600
+
+ More gc fixes.
+
+commit 5638fbc8b10ad075f66c6bc4037167cf27a28253
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon May 9 04:34:48 2005 -0600
+
+ GC fixes. We dont need mempool.
+
+commit a6f50a5ffba0293743b22f668e29c3d52ff3214a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 03:10:23 2005 -0600
+
+ Fixed cxx errors.
+
+commit 90060506b1d924116630f43c068f353c43da0c44
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 9 02:58:55 2005 -0600
+
+ Fixed memory leak in parser and translator.
+
+ Cleaned up interface to the Boehm garbage collector.
+
+commit eff11626bd6dbdc7f4defa3c8597b0bca050592b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 8 23:06:28 2005 -0600
+
+ Revert 2005-05-09 and 2005-05-08 rtprince changes.
+
+commit df3f6816117919c0c9c6c80390956f79df6aad9b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 22:16:41 2005 -0600
+
+ Fix picture.
+
+commit 5770ab65dbc40a56339d22a45cfa6e6174241d78
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 21:24:28 2005 -0600
+
+ Fix item gc handling.
+
+commit 399af8081afc712686314e2ca99584d3fa158023
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 21:12:42 2005 -0600
+
+ Collect path.
+
+commit 6fcf5fda6460ff8048649146d1e92ba4f6306c04
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 20:35:08 2005 -0600
+
+ Collect transform.
+
+commit 8c2eff54bf17ac051dca66442c8b6cd61641e76b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 19:56:00 2005 -0600
+
+ Create gc_atomic, and make picture use it.
+
+commit bc9d351f1e202c481fca3135307ca5895a22e2d7
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 19:37:29 2005 -0600
+
+ Make pen garbage collected.
+
+commit a76ec0dcb389fc456cf186a06885898e1ec40002
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 19:34:56 2005 -0600
+
+ Make picture and drawElement garabage collected.
+
+commit f5980293fd7720f87bfd6184fa0b14e5c4665887
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 17:11:34 2005 -0600
+
+ Add gc for vm only. (untested)
+
+commit f222adf318f319d54cba8c227c5ae840411a021f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 17:01:19 2005 -0600
+
+ We don't want libgccpp.
+
+commit 2fceb9286c372d9123e41fc088664e444a5ea25a
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 16:57:11 2005 -0600
+
+ Re-add pool.h.
+
+commit f4ac27b3d7b9622db9e79a468fe24f97ef4df510
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun May 8 16:55:24 2005 -0600
+
+ Revert GC changes. (not tested)
+
+commit eb11d81ca9350019c9c895d9e69fe18c82523b5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 8 08:57:01 2005 -0600
+
+ Figure for Geometry.asy.
+
+commit fc9cbf860d9a0ca997ddba7275cef0d50a963154
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 8 00:29:32 2005 -0600
+
+ Minor fixes.
+
+commit 78245d3817e355c52638694eddf8eef22cdfead3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 8 00:17:30 2005 -0600
+
+ Workaround Makefile problem in gc6.3.
+
+commit 098e8a231fa9d33aaf9cf6f5483cf97e993b0b2c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 8 00:16:45 2005 -0600
+
+ Move trace/interrupt check to beginning of virtual machine loop.
+
+commit afc1adbc265bb2a53ad8f722f4b07d72fa248c47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun May 8 00:05:59 2005 -0600
+
+ Revert to distributing Boehm GC as tar.gz file.
+
+commit 1f663f24a9c43942ce06938a1c573058f1a74454
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 23:52:27 2005 -0600
+
+ Distribute Boehm GC as a tar file rather than tar.gz file.
+
+commit 9d56f25d6bdebf45f6b5130ebbfe66b6aa405f91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 23:40:14 2005 -0600
+
+ Added beginnings of a geometry module, including a triangle structure and
+ functions to draw interior arcs of triangles and perpendicular symbols.
+
+commit b40d10e76adcebb53560471b218dc68f869e39f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 21:31:23 2005 -0600
+
+ Distribute generated source files.
+
+commit 360ce3d468d93ff0a5fa1bdcceecb29359487a77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 21:30:48 2005 -0600
+
+ Fixed type of argument of dividebyzero.
+
+commit dc3a948a255cbabb1899e86bd4bc058f2a776bac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 21:05:28 2005 -0600
+
+ cxx updates.
+
+commit dc8d225183a1f02a9cebb3078bd770f645501a4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 20:35:51 2005 -0600
+
+ DEBUG_STACK updates.
+
+commit d08008cdab9cb06362df1f2ebf13cacd1fbdbc4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 20:07:39 2005 -0600
+
+ Minor garbage collection updates.
+
+commit 4d94ce88599400aa221991991f83c5ede8ce1709
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 11:56:54 2005 -0600
+
+ Autoconf backwards compatibility workaround.
+
+commit f56e28b3c3b9b297b80e10d42174b5244112dc25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 11:50:19 2005 -0600
+
+ Renamed COLLECT to USEGC.
+
+commit f31faf416554c7e209f36059355b16f01eb47007
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 11:49:25 2005 -0600
+
+ Added configuration to optionally disable garbage collection.
+
+commit 45c88ca08a3da13844ddfe0fb5b4a93f19e6f2b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 09:48:46 2005 -0600
+
+ Fixed Makefile dependencies.
+
+commit 30a705d20fefeece1687429e0cb8470d62919bd2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat May 7 01:38:08 2005 -0600
+
+ Implemented Boehm garbage collection.
+
+commit 9d7769ce6f88bc53a74d1372b9587e27f7f7fe84
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu May 5 22:32:22 2005 -0600
+
+ Fixed solveSection bug.
+
+commit 06f40e2f91f484b534961af38a5185a5d9d6b466
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 5 13:34:40 2005 -0600
+
+ Added missing comma.
+
+commit 82fa8089d032fbacb29c7973ef6bbf2cd97d467d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 5 13:32:53 2005 -0600
+
+ Addressed pen plabel vs p issues.
+
+commit d40592205063e8adf7f147a81d091c800b1c24cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 5 01:36:58 2005 -0600
+
+ Renamed eval(f(T), T[] A) to map(f(T), T[] A).
+
+ Documented eval(string) and make eval autoload plain.
+
+ Implemented T[] concat(T[] A, T[] B) to concatenate two arrays into a new one.
+
+commit 4db5971d0cd68808f77feec77f06ec1451a8a2ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 5 00:46:04 2005 -0600
+
+ Added pair exp(pair) and pair log(pair).
+
+commit 28baf58075cb9ca944dd0ce8458196d7944b1db8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 4 23:35:48 2005 -0600
+
+ Make int quotient(int,int) portable.
+
+ Updated base files to use quotient for integer division.
+
+commit db1823ffb4c94ea156aade89dbaa912ff8303d4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 4 23:19:03 2005 -0600
+
+ Make int/int return a real, as is normally desired; the new function
+ int quotient(int,int) returns an integer quotient.
+
+commit 0a78859e787da1b7e76cb10aa793aec5d3d32d26
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 4 21:55:59 2005 -0600
+
+ Updated TODO items.
+
+commit bbe4c843c51d04977a1bc6b9be897acb31feb5ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 4 21:55:18 2005 -0600
+
+ List iterator simplification.
+
+commit 3432a63496468bad1eadf3cdd6038e555b236f97
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 4 21:44:31 2005 -0600
+
+ Added reltime(path, real).
+
+commit 42610c12a7bcda076d4d18700f832eabaa629ae8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed May 4 21:40:58 2005 -0600
+
+ Make -l option list available global variables as well as functions.
+
+commit 10d1ef281f1d9d5d6eca395da7bb7060ca1de36d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 3 22:24:17 2005 -0600
+
+ Minor updates.
+
+commit dce883a43c8f916ff404af6662355727471522e2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 3 22:23:34 2005 -0600
+
+ For portability, explicitly check that input file isn't a directory on systems
+ with stat.
+
+commit d5c499a61651cf1621431c65c1524b650024b759
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 21:14:15 2005 -0600
+
+ Added example of a transformable triangle structure.
+
+commit 5aaecb40c9d5d75b170995775f3939c6bfd092f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 16:20:02 2005 -0600
+
+ Incremented version to 0.77cvs.
+
+commit 01495eba409e943a272c0e5458e926bf97d91bad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 15:27:57 2005 -0600
+
+ Added PenMargin.
+
+commit 98466a96d92665282ce339397a4aa0cc9c0f1c93
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 15:20:05 2005 -0600
+
+ Added -l option to list available global functions.
+
+ Documentation default structure constructors.
+
+commit 80a5b55488005bfb44bfadf5b1b543638bbe7d61
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 00:42:53 2005 -0600
+
+ Added missing plabel.
+
+commit 23072e44c1dab9402078ecabfc5ee1d88bbfb2f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 00:11:49 2005 -0600
+
+ Improved error handling in pipestream; wrap fork to avoid zombies.
+
+ TeX errors should force TeX pipe to be closed.
+
+commit 1f2d5b4722b7ac5bb030f149eeb166a99cc0f56b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 00:09:25 2005 -0600
+
+ Updated examples.
+
+commit 8f133f4fd77a30c58eca35355e3025e390950841
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 00:09:10 2005 -0600
+
+ Updated documentation.
+
+commit 46b5a8b9a9c3f89d7617e6cea768fa1b0d310011
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 00:08:38 2005 -0600
+
+ Don't push a final null entry when reading an array in line mode.
+
+commit 5119ce4ff2ddb922ed9c913a18a500e54ba72837
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 00:07:12 2005 -0600
+
+ Fixed grouping in add(pair,frame,frame,group).
+
+ Added put argument to pic.add, attach, etc.
+
+ Added plabel argument to draw to allow labels and legends to use a different
+ pen than the curve itself.
+
+ Rearranged plabel and p arguments in axis routines for consistency.
+
+ Added getstring and getreal functions.
+
+ Added Mark, MarkFill frame arrays and Mark(int) function.
+
+commit 9ce6ebd16ea51561bf969560568a00f3b5b59d28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 2 00:04:54 2005 -0600
+
+ Added node, value, and slope functions for paths.
+
+commit 2a5211c33c00af59ea8ec8b03a47b8ab056a6b9c
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sat Apr 30 22:38:32 2005 -0600
+
+ Make camperror throw instead of queuing.
+
+commit 1077eff9ad28f73d8c6fd3717d1de6c0eff7b31b
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Apr 30 20:31:09 2005 -0600
+
+ ''
+
+commit 445aabeee69dbdbb14d19231ff94845d5ed0c8da
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Apr 30 16:29:58 2005 -0600
+
+ Allowed more implicit scaling.
+
+commit a02314294b9d45c57be7bfcd98d834491f54c5e8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sat Apr 30 14:49:34 2005 -0600
+
+ Changed precedence for implicit scaling.
+
+commit ebadfa41910e30b009338d9254352d407b09c1ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 25 23:43:36 2005 -0600
+
+ Flush exited child processes (zombies) in batch mode.
+
+commit f2ddac66cf7bd60c6f789bd100e3bbdd027aaf5a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 25 23:41:46 2005 -0600
+
+ Workaround interactive mode bug introduced by recent changes to main.cc.
+
+ On multiple file runs, texpreamble should appear before any other commands.
+
+commit 9dd78b8a3bef3ead1114749f8e46d99b5269cf7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 25 22:21:57 2005 -0600
+
+ Added example of 3d featpost3d arc.
+
+commit 8bf045189f7f7a0a75871455d90dfaebba9ec547
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun Apr 24 21:04:01 2005 -0600
+
+ Make parseStdin() turn of lex debuging.
+
+commit b6c8be9df5782db786b484113d1daf803c5fae16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 24 10:44:05 2005 -0600
+
+ Added Dotted(pen) function which returns a dotted pen at double the linewidth.
+
+commit 1a97fed8e248625d9b902b514afd1eb4d70c9275
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 23 17:16:57 2005 -0600
+
+ Clear existing errors on reading from standard input.
+
+commit fc009e52440aad59836f5bda105555a61bca4f7c
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sat Apr 23 15:15:33 2005 -0600
+
+ Fix interrupt handling.
+
+commit 5cd7876fc7e960858f491fb2fa6b1d24803c2f1b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 22 11:56:07 2005 -0600
+
+ Cleanup.
+
+commit 4bdb5c64660e95962e9419a81bacb33fb4a2be4a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 22 08:43:55 2005 -0600
+
+ Fixed compilation error.
+
+commit 528a9eb7c36d3a33431b775aa9328c0d3bdcdb09
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 22 07:49:16 2005 -0600
+
+ Fix segfault.
+
+commit 95ad036c40755eea043b9421cf777b4ea7993fe2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 22 03:21:09 2005 -0600
+
+ Replaced boost::lexical_cast with lexical.h to remove last remaining
+ dependency on boost header files.
+
+commit a87c9886fd9fee971c0e9a8a68b599bcf047108a
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 22:51:44 2005 -0600
+
+ Cleanup.
+
+commit 582654800d5965700998478f02504c1ae6b5a5e6
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 22:47:56 2005 -0600
+
+ Refactoring main.cc.
+
+commit 95d2376fcf7bec7c8448a72b5355fc0de65d49c8
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 21:27:46 2005 -0600
+
+ More refactoring in main.cc
+
+commit fe8229b7f21ceb84165253cf9fac29a9f3086319
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 21:03:35 2005 -0600
+
+ findextension is used only to strip suffix. So strip it.
+
+commit 3125ff977fe4f233f964fd0c24031b68e2180971
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 13:38:38 2005 -0600
+
+ FIx interactive.
+
+commit 5a607d6d598487d1ce5b2b506e9c9ee5c6df5c5f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 00:59:52 2005 -0600
+
+ More main.cc cleanup.
+
+commit c75d9f85e2ae2cac80eb10729a8e49bd0bb63b0a
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 00:55:02 2005 -0600
+
+ Simplify error handling.
+
+commit d8509dc2a49f364a4d645689dfb4c29450b3820e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 00:33:24 2005 -0600
+
+ Start pulling appart main(), so it easier to
+ change and understand. Doesn't do much, but
+ gives a a place to start.
+
+commit 41c53e7bd2fb7e6b6038cc334aed8510fd12d880
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 21 00:07:46 2005 -0600
+
+ Update ./wce.
+
+commit bc6a93c7d9a48b957f287b8d9772804a47b6a7b1
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 20 23:40:57 2005 -0600
+
+ Remove warning about side-effects.
+
+commit cb5ae20890b4b381c3cf00ee755bb2aad0874eae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 23:17:54 2005 -0600
+
+ Incremented version to 0.76cvs.
+
+commit 307769f553ac965062a636ae87e7c2f61ea8f881
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 22:41:08 2005 -0600
+
+ Documented xline and yline.
+
+commit 1e2cdc58e3512a20d051d86f5db98b17165f4a4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 18:59:59 2005 -0600
+
+ More updates.
+
+commit 31f55d67bba1b306e55f51fb061548c390465b82
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 18:58:48 2005 -0600
+
+ Updated axis call.
+
+commit a67f7b32d7c394487f795e397b1c90d80724ff74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 16:03:54 2005 -0600
+
+ Updated binary installation instructions.
+
+commit 2807bb7d7d88aab29de67876839750836d4f76d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 14:03:36 2005 -0600
+
+ Update yaxis call.
+
+commit ee9e621e33a17428090bce4abda5eadcd372f461
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 11:53:41 2005 -0600
+
+ Consolidated autoload code.
+
+ Suppressed "could not load" error message in interactive mode.
+
+ Fixed gcc 3.2 warnings and error message.
+
+commit 26f006304e452f273eec22f9760ab372a61b90c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 11:51:58 2005 -0600
+
+ Added linear interpolation and binary search routines.
+
+commit 4fbb8d341cb219fbcbb06426fe4701cada86e41a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 11:49:16 2005 -0600
+
+ Moved put argument to axis routines to end of argument list, for
+ consistency with draw.
+
+ Added xline and yline interfaces to axis routines.
+
+commit 4b26843ed13d92b95faf3636add7ac8e61058ed1
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 20 11:38:23 2005 -0600
+
+ Change stack::run(lambda*) to a free function vm::run.
+
+commit c0c1159e73655fbb275c88042d696f7bc5ed95ee
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 20 11:18:23 2005 -0600
+
+ Fix handling of bad parse.
+
+commit a2bdb64165581bf56b8a3f296d3fa4c5e1c156cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 20 09:51:49 2005 -0600
+
+ ''
+
+commit f1a1b76217a093a1aef6256cca541fd64e507279
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 20 08:31:22 2005 -0600
+
+ Refactor doParse().
+
+commit ef94bc661d593da433e7ffefe62576e82ece224d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 19 22:56:48 2005 -0600
+
+ Fixed definition of correlation coefficient; added fit function to
+ linefit struct.
+
+commit 38c1a8600dd92883783c42b0903fa4a0e0673ba8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 19 19:59:25 2005 -0600
+
+ Implemented portable way of testing for directories (but not null files).
+
+commit c7bd80f606e4514e6e771255206becc9fb639a62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 19 14:55:14 2005 -0600
+
+ Fixed stdin handling of parser.cc.
+
+commit 461b1d0cf62e21d560a99181cac401f24d3f958e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 19 10:08:39 2005 -0600
+
+ *** empty log message ***
+
+commit 67231f89093d457e34144523f5df91ee9179d80a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 19 08:05:31 2005 -0600
+
+ Fixed more bugs associated with new parser.
+
+commit d89c1d9bd4147a4092c649c66385e7dffbc421df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 19 01:31:02 2005 -0600
+
+ filebuf should not be static; fixed error message.
+
+commit 1e1ab85794f8d88e80f177589caae6acac902cae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 19 01:25:18 2005 -0600
+
+ Interactive input command now checks for a directory or null file.
+ Print an error if input file can't be loaded.
+
+commit cda4516bea221edaa2339a64026e1a6553a26110
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 18 23:35:01 2005 -0600
+
+ Make execute() autoload plain (and any gui file) again.
+
+commit e195f1e0c091671f0febfee7de49600f40cb3313
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 18 23:28:58 2005 -0600
+
+ Re-added new parser, with fixes for standard input bugs (including a
+ segmentation fault with -p option).
+
+ Attempting to read a directory or a null file now returns
+ "error: could not load module" instead of generating an exception.
+
+commit 09533e92fde1b398234d49c3cf3ce417e2a0cc90
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 18 23:24:33 2005 -0600
+
+ Changed default value of axislabelmargin to 1.
+
+commit 0e2f1993a3e95a94ac377fe22a3a5b070bc3a656
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Apr 18 21:59:13 2005 -0600
+
+ Don't segfault on -p if we can't parse the file, but don't report an error.
+
+commit 3af70e113dcf07a2aa1c6d2fa7d9fa77b2104016
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 18 21:37:18 2005 -0600
+
+ Fixed cxx errors and and warnings; removed unused parser files.
+
+commit c8905be27a797dee9279c92d1c5caff98e362b62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 18 21:10:28 2005 -0600
+
+ Revert to old parser until bugs in new parser are fixed.
+
+commit 4aa0fdc1d4eae3d12d6a6272b0d238f7e41fa447
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 18 00:50:08 2005 -0600
+
+ Fixed bug in csv mode when line mode is not set.
+
+commit fe1917dfb06755fdc2b20abc72ea1b50946636b0
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 21:56:04 2005 -0600
+
+ runtime.pl updates. Actually use the generated code.
+
+commit 71b09f3e6517685436507d8aa2e383286dda1d7d
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 19:52:18 2005 -0600
+
+ Typos.
+
+commit b5dfef4fc8493cf776971b3a2b93c1739b576cfe
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 19:45:07 2005 -0600
+
+ inst.h cleanups.
+
+commit 4bad5844e10b0e5cb468b19f58fbdeaad3fb6c1e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 18:42:28 2005 -0600
+
+ Implement type query for vm::item.
+
+commit 37eba3e42671869e76f88b9335f073cc9637aa1c
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 18:24:59 2005 -0600
+
+ We use item to store string* in inst.
+
+commit 82d1da4d0d5420e0252417c1384d7408c269b2a5
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 17:21:55 2005 -0600
+
+ Fixes for runtime.pl script.
+
+commit 443ad0a35821d4d6ce45bca04df4272fe34c3499
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 16:00:18 2005 -0600
+
+ Fixes for runtime.pl script.
+
+commit 87fe09e70703c07c66eb0b811c2f0245d63bfd3b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Apr 15 15:36:25 2005 -0600
+
+ Initial runtime.pl script.
+
+commit 38f76e10894a6d8450762115e066c09385dc317e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 14 11:16:21 2005 -0600
+
+ Add eval.
+
+commit 18cb497cb2e9f488eaf8910d9c5dadf0d35f62ed
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Apr 14 11:06:44 2005 -0600
+
+ Move interactive logic out of genv to main.
+
+commit 5bac10bbd4d407eb506985b7af796dcab599d462
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Apr 14 07:40:55 2005 -0600
+
+ Interactive mode update.
+
+commit 60d2b0b790ac486e1952c53d6095e382c4a8194d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 21:43:07 2005 -0600
+
+ Incremented version to 0.75cvs.
+
+commit 316edfa9afeef1c80437dd321ab1d10cae708e5a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 21:10:38 2005 -0600
+
+ Removed figures with shading since from manual since many printers don't
+ understand PostScript 3.
+
+commit f90afa0a8d7e062798a95fed2f7b5126c5559263
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 20:42:00 2005 -0600
+
+ Reduced default number of colors in images to work around postscript/pdf
+ limitations (this prevented recent manuals from being printed).
+
+commit 5e4394905b9e0e82b2e6c605078a5b2e537c060e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 20:09:21 2005 -0600
+
+ Fixed segmentation fault in version 0.73.
+
+commit 7fe32aa7421f75d291fef1ad9c198648f3eedebe
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 13 18:48:48 2005 -0600
+
+ overloaded::simplify() handles allocation.
+
+commit 48c82ff272e05b3261f9400cedf5e1b6800107c2
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 13 17:57:38 2005 -0600
+
+ Make vm::frames extendable, and make function excplicitly allocate their
+ local variables. This might be a first step towards true interactive
+ support or caching modules from one run to another.
+
+commit 104205234175695f554c13863db24a3c70194eb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 11:07:58 2005 -0600
+
+ Incremented version to 0.74cvs.
+
+commit 8b10e5c0d5048747ab3d671896ad4169463631ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 11:00:39 2005 -0600
+
+ Make nullpath static.
+
+commit 000be41e1427bbcd86f1dcad074b91f2829bb91b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 09:58:55 2005 -0600
+
+ Minor updates.
+
+commit 3c6b9228e36e265a21d65a54ea86153b863a5848
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 09:44:54 2005 -0600
+
+ Push constructed objects as pointers.
+
+commit 3ac7a1842c014483bd0ce489a1176fa6b7106f7a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 09:04:07 2005 -0600
+
+ Fixed sign of virtual assembly code line numbers.
+
+commit ab5db84bedf07c340eefd9c0f72bf1782d836b5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 06:21:17 2005 -0600
+
+ Fixed more warning messages.
+
+commit f41dbb672fbe2f05bab43eb36f4f408e234dcf04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 13 05:36:59 2005 -0600
+
+ Accept cast of empty string to 0.
+
+ Use string.empty() everywhere.
+
+ Minor formatting changes.
+
+commit 0ae078e729359512169c0aa16b13a36aacfa1f3d
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 13 00:36:07 2005 -0600
+
+ Don't use boost iterator facade.
+
+commit 81641e23ec0ac8e8a022291f49b436e1f454e30e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 13 00:16:15 2005 -0600
+
+ vm::item doesn't need to be memory::managed,
+ since vm::frame is memory::managed_array.
+
+commit 3e39b59448d7c2b0d348ede3311879597100ce30
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 13 00:04:31 2005 -0600
+
+ Fix absolute filename handling.
+
+commit e2d07ca8b0f71aeb4f904295096fea23b8394c27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 12 23:41:53 2005 -0600
+
+ Fixed more cxx warnings.
+
+commit 5e9180ebefbfcf3d44264334874c4864c37db611
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 12 23:21:02 2005 -0600
+
+ Fixed cxx warning messages.
+
+commit c34996b55b48be33456a09b8e8bffef6eab6fbf5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 12 22:42:21 2005 -0600
+
+ Further minor optimizations.
+
+commit 33fea10d535c3369052e3078bef76ae00b218280
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 12 15:36:18 2005 -0600
+
+ Removed unused friend declaration.
+
+commit 9816dcbe2015e60696c5fe09405fe8bcbbb328ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 12 14:26:17 2005 -0600
+
+ Replaced boost::any with a much faster type-safe union.
+
+commit b4d16cc3936034e92f13d30a447d7502fcbeb36f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 12 14:17:09 2005 -0600
+
+ mathop's don't need vm::stack.
+
+commit d7e8f162b4a84765be14b3e606ee8fff5495fbcc
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 12 14:08:33 2005 -0600
+
+ Move curPos out of vm::stack.
+
+commit e2ece8085ce8d724a3083d2f1b6b0653e98928ba
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Apr 11 19:21:59 2005 -0600
+
+ Push empty item instead of (void*)0.
+
+commit 363e45400250312be8c1d279f3023d4ca92bbb45
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Apr 11 14:42:08 2005 -0600
+
+ Seperate parser code from camp.l and genv.cc into parser.{h,cc}.
+
+commit 2a34bbe4e752a24048c78ce70065f717097b0e7b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Apr 11 14:40:13 2005 -0600
+
+ Change ./ to . in searchPath to avoid .//file.asy in messages.
+
+commit bac1145753ebaec03fb6b3f5b2241c5654e94eb0
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Apr 11 14:28:03 2005 -0600
+
+ Reimplement locateFile using std::string.
+
+commit 96eb620a356c8ab272184a1c469ec2fd664479d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 9 21:20:51 2005 -0600
+
+ Fixed texpreamble for multiple files and latex asy environment.
+
+commit 38d3c03b695d85569badcfe9fb9aeb4610c56508
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 9 16:26:50 2005 -0600
+
+ Removed nonscalable fonts.
+
+commit a1eb8324978e3f0b33de9661a4f9dfb6a110fd94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 8 23:52:01 2005 -0600
+
+ box(frame), ellipse(frame), labelbox(frame), labelellipse(frame) now
+ return the boundary as a guide.
+
+ box(frame) and ellipse(frame) prepend to frame for filling with a
+ background colour, as illustrated in hierarchy.asy.
+
+commit 3d0f99fbb29df1712b89770aea609b48125722fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 8 14:54:13 2005 -0600
+
+ Example of labelellipse.
+
+commit 38150cacf871ccce9229949a2d554aef1961d2dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 8 14:52:47 2005 -0600
+
+ Added ellipse(frame) and labelellipse(frame,string,position).
+ Renamed bbox(frame) to box(frame) for consistency.
+
+commit bfe1bee3fb0c1517a66b579cdbea6f1e733585fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 8 14:34:04 2005 -0600
+
+ Workaround for bug in build 1671 of gcc (version 3.3 20030304) under Darwin
+ (MacOS).
+
+commit 1b488993fb4b2441b516b1f2751fa0fac0440df4
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 6 20:39:19 2005 -0600
+
+ Cache *ip as reference rather than pointer.
+
+commit e0db3be7f2b80020578b4635757f7c8f5d944dfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 6 15:46:08 2005 -0600
+
+ Added check to interrupt handler.
+
+commit 4354256eafa91c99d25dba3c69eca65e512547a8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 6 14:01:41 2005 -0600
+
+ Fixed cxx warning messages.
+
+commit 296d16b5e2ef1aa8ec4a4a49e7b318bc894b8707
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Apr 6 13:47:25 2005 -0600
+
+ Optimized main loop.
+
+commit c39ce074bb8014113bb9ec840940e614e42413e2
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Apr 6 00:20:40 2005 -0600
+
+ Use error from stack.cc instead of calling em->runtime directly.
+
+commit b6f76a0cdf5a809f9b1ea8d924fe28ed9938c148
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 5 22:53:43 2005 -0600
+
+ minor optimizations
+
+commit da6b2f87a556f0284e5f9809660702ad308f2797
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Apr 5 19:31:54 2005 -0600
+
+ Reformatted.
+
+commit 59fe028e67d4a3b84275fd9816158ba2516c31c1
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 5 11:46:44 2005 -0600
+
+ Operator precedence fix.
+
+commit e1d84cb8c07ca8562701bd2d6ff61286fb14f95e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 5 08:42:47 2005 -0600
+
+ We don't use stack:ip any more.
+
+commit 66fcbb23572787b34cc11179118b76d458ea0f70
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 5 08:39:25 2005 -0600
+
+ Reapply curPos patch.
+
+commit 59bedfb4736163ad1120e4eb920a3e10cf3383c2
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 5 08:38:12 2005 -0600
+
+ Fix interactive error reporting.
+
+commit 8bd8b52a44235a69ee721600aad0b333c862f364
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 5 01:15:37 2005 -0600
+
+ Track line numbers in position instead of fileinfo.
+
+commit 83faf517c935524837f4a50a1ad67b64b5babfce
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Apr 5 01:13:43 2005 -0600
+
+ Don't access program.encode directly.
+
+commit a9d21f618d29a440b461d9da1b97084990329c6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 4 14:22:06 2005 -0600
+
+ prepend should insert after beginning of layer
+
+commit caa47b3c4d394f7354307b1500d6086a05542b89
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 4 14:07:22 2005 -0600
+
+ Make empty() use nodes.empty() rather than nodes.size().
+
+ STL list portability fixes.
+
+commit 37bd8bfcf6ace390213d77ca1c584710c581b5f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 4 10:29:54 2005 -0600
+
+ Ignore crop() on an empty picture.
+
+commit 2ba6652285a4da64838decebe8a391b145a17b14
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Apr 4 00:21:02 2005 -0600
+
+ Incremented version to 0.73cvs.
+
+commit e148d97f5d334b8c9101cc5e712bfdf43378b791
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 3 23:32:55 2005 -0600
+
+ Removed spurious blank tracing lines.
+
+commit 36d887d4c3996d03601515d384a66b4a8e5851ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 3 23:06:37 2005 -0600
+
+ Revert fileposition changes again, due to segmentation fault with -vvvvv.
+
+ Moved line-number tracing code into main loop.
+
+ Avoid the need for the lastpos variable by moving stack s out of main loop
+ in main.cc.
+
+commit d6dc468977be2cb8d78ad3cc934ea6848297edde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 3 21:33:06 2005 -0600
+
+ Reinstated new file position code w/segmentation fault bug fixed.
+
+commit 5016c706f314fd3edae339e179a0aae3fa4e56ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Apr 3 20:18:15 2005 -0600
+
+ Backout 2005-03-17 runtime file position changes to avoid a segmentation fault.
+
+commit a662c972a14f054fb8020b901dda548395fb08b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 2 22:38:47 2005 -0600
+
+ Check for space format specifier as well as plus in format(string,real).
+
+commit fa2c52036aec09d39c41660d615bc8478ea7adee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 2 22:21:30 2005 -0600
+
+ Removed deconstruct flag from picture in favour of group option to picture
+ and frame add routines.
+
+ Updated documentation.
+
+commit e5e5b81d881e8330e0800c9ed4f7062ac4f06215
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 2 17:29:41 2005 -0600
+
+ Added missing file.
+
+commit 519fb5f6221bea0b6a25b307b53cfc61b87aedd0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Apr 2 17:17:16 2005 -0600
+
+ Reimplemented deconstruction at a lower level to allow both pictures and frames
+ to be deconstructed (or grouped with begingroup/endgroup). Deconstruction
+ now works properly with clipping and erasing.
+
+commit 2eba6f6c6a39ff2db84ae9ca2a8700250a90c47b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 1 22:22:03 2005 -0600
+
+ Check that drawLabel::bounds is called before drawLabel::write.
+
+ Remove unused setup code.
+
+commit 7c08dfff446cecac5832f32f94676ec2c565a33e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Apr 1 12:37:28 2005 -0600
+
+ Added attach(pair,picture,frame) to automatically increase the
+ picture size to accomodate adding a frame about a user coordinate.
+
+ Added warning about erasing deconstructed pictures.
+
+ Updated lineargraph and documentation to use attach.
+
+commit ec22ed8430fe48a777e50d0eabdd6068d2b97923
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 31 23:14:38 2005 -0600
+
+ Reset bounding box when prepending.
+
+commit 70a385b41d057ae2b2d4654d4443cd792c88cdb1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 31 22:47:16 2005 -0600
+
+ Fixed label alignment vs. positioning transformation problem.
+
+ Removed frame labelBox() in favour of void labelbox(frame); updated example.
+
+ Make logarithmic checks in autoscale conditional.
+
+ xlimits and ylimits now adjust deferred drawing bounds.
+
+ Simplified bboxstack handling.
+
+ Updated "errors" list.
+
+commit 218a1aec30e912b2163aa99d01b72e06f2884c71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 31 15:37:05 2005 -0600
+
+ Revert configuration to only require boost headers.
+
+commit 52ca63f613a70900b70ceceb7487a23ba2e1bf75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 31 13:15:17 2005 -0600
+
+ Backout boost fixes.
+
+commit 8f6948bbed2dec4684a2cc9250f4082703bf8340
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 31 13:08:04 2005 -0600
+
+ Revert boost::filesystem changes.
+
+commit eb6083d2e0151c7eb1744d2e331e37ecdf3b61d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 31 01:22:29 2005 -0600
+
+ Added explicit linear equation solver; used to handle general matrix inversion.
+
+ Fixed return type of real[][] * real[].
+
+ Hard coded 2x2 and 3x3 determinants.
+
+ Update documentation.
+
+commit aaed4d5294abe74371a37b7a553a2db7be5e55c1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 30 19:06:36 2005 -0600
+
+ Fixed cxx warning message.
+
+commit bf7b8df5f764ae59371c2aa91b77c07fa323a001
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 30 18:54:42 2005 -0600
+
+ Minor updates.
+
+commit 102a82598df9eebad1f7e92a59e5d2f2c0973704
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 30 18:15:06 2005 -0600
+
+ Added portable version of boost::filesystem for systems without boost
+ library, in particular for linux-alpha cxx compiler.
+
+commit 203e724f777b81f73cf16f49d4833c54573281bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 28 21:22:47 2005 -0600
+
+ Updated documentation.
+
+commit 26bfdbd489bd80c70c00d24d2b3eab19b5ad4e64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 28 21:06:24 2005 -0600
+
+ Allow compatibility with older versions of autoconf.
+
+commit e93fb2dd08b2ea3c6ef7510369f5837e7c0dc489
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 28 17:11:35 2005 -0600
+
+ Updated configuration and documentation regarding boost-1.32.0 library.
+
+ Improved format(string,real).
+
+ Generalized histogram and changed order of arguments of frequency and histogram
+ (bin boundaries are now given before the data).
+
+ Fixed problems with Log(false,false).
+
+commit ea08512c386ea0e3068a3fcbc69ebe610d05371a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 25 11:56:40 2005 -0600
+
+ Cache drawelement bbox contributions where possible.
+
+ Make bboxstack local to picture frame.
+
+commit 38b3478ce4eb79d069db1f492b937898c3b5b5dc
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 24 23:46:41 2005 -0600
+
+ We generate .png's.
+
+commit 36945d15e89b3f8799ebbc7e75d22bdf947de965
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 24 20:51:59 2005 -0600
+
+ Don't have symbolToFile anymore.
+
+commit 9142a4fb926e4fbf87925d46dd9d568487af9335
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 24 19:00:39 2005 -0600
+
+ Use boost::filesystem for find files to parse.
+ Move file locating logic to locate.{cc,h}.
+
+commit 93557aea87b06de332ab234a23b7aceeb32be86a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 24 18:34:14 2005 -0600
+
+ Simplified legend examples.
+
+commit 8bae1619df7f3e202d595eebce4b549bcc0691a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 24 08:35:06 2005 -0600
+
+ Workaround makeinfo indentation bug.
+
+commit a20cafa013be9b196bd9d0d16e3fb99ae455a1e0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 24 08:02:51 2005 -0600
+
+ Fixed typos.
+
+commit c3ba5df64f4fe77a8bc60a4e151da7a597832404
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 23 20:49:30 2005 -0600
+
+ Simplified example.
+
+commit 3638add962f94d5a7ab9b67836651af7cd9a8362
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Mar 23 20:13:13 2005 -0600
+
+ Have main load plain.asy and ${outname}.gui explicitly,
+ rather than doing it implicitly in genv::genv().
+
+commit be8225df1cfcc4b92d44e9fce54cd6562538f921
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 23 14:25:54 2005 -0600
+
+ optimized crop()
+
+commit d2e19f53b74698fc8711cfc20ca1940602998322
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Mar 23 11:14:24 2005 -0600
+
+ *** empty log message ***
+
+commit 3d72ae80c6a6ea6c1a2c58b5e5c086b8c920dd24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 23:27:53 2005 -0600
+
+ Incremented version to 0.72cvs.
+
+commit 9713361a9c50528eff627030657649e2e7693d7d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 23:03:18 2005 -0600
+
+ Document leastsquare routine.
+
+commit 82c080b20250de2b5065be142f890c7a7fa1409a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 22:50:22 2005 -0600
+
+ Removed obsolete files.
+
+commit dd5dbfceb01f48c9a1119b93469cad6c05b7e0ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 22:32:58 2005 -0600
+
+ Documented save() and restore(). Renamed linetest.asy to lines.asy.
+
+commit decbe43f004ee675a248521b2ffb487498541e74
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 21:51:41 2005 -0600
+
+ Added and documented Andy's drawline routine.
+
+commit 50858377e0e544f796e4ca2a5a8e87f090a03aa3
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Mar 22 21:43:51 2005 -0600
+
+ Added saving and restoring of the graphics state.
+
+commit c4a6cf35979b776be9c87ea2a94316662d90e5ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 21:14:57 2005 -0600
+
+ Cache picture bounds.
+
+commit 6c8f487edf8437f5b644b60ee966c6ccceb53fd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 17:30:09 2005 -0600
+
+ Reinstated crop; use current value of userMin/userMax in xlimits and ylimits.
+
+commit e287b942d25b5c25a33ddaca210d5d6cc1660a2c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 15:05:30 2005 -0600
+
+ Added further legend example.
+
+commit 2608c42e32a1e9d5231cec42cd0a1316ce6e17e3
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Mar 22 10:25:12 2005 -0600
+
+ cxx doesn't like const objects in containers.
+
+commit de8cfe019ed7d54db013879124b035faa48a975c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 09:21:43 2005 -0600
+
+ Document alternative for legend fitting.
+
+commit 17d2b4039eff53dc9a683c3b31ba3e62a1ac4153
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 22 00:10:38 2005 -0600
+
+ More cxx warnings fixed.
+
+commit 37dee37bf464d8f25ea1de2733a1bc78629b6b23
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 21 23:56:46 2005 -0600
+
+ Fixed g++ warning messages.
+
+commit 534a66210790997c8a37bca0f481dcdc62cbd651
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 21 23:54:01 2005 -0600
+
+ Fixed warnings/errors under cxx.
+
+commit 65e4f31b4647b63d4cdf6f4874c6aa9fb73b248e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Mar 21 23:37:08 2005 -0600
+
+ Move vm::item to its own file.
+
+commit d3363bdad6baecad5c1960e35f26b9fa7a72a57e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Mar 21 23:32:30 2005 -0600
+
+ Header file cleanup.
+
+commit 5efd8d91def53af4ac8c74fd53944d87ca2a9e77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 21 23:17:08 2005 -0600
+
+ Make legend a separate picture that can be positioned and aligned like any
+ other picture (see lineargraph.asy example). The legend must now be
+ explicitly added to the picture, for example, with add(point(E),legend(20E));
+
+ Palette also now returns a new picture.
+
+commit abde5ee31a1ee9014bf78832a4ebb6ad68db1f9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 21 22:02:56 2005 -0600
+
+ Updated move limits to be compatible with SW alignment.
+
+commit a89a01614b66946253fc2324154744bc5eb93a61
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Mar 21 17:28:54 2005 -0600
+
+ Use free function vm::pop instead of vm::stack::pop.
+
+commit 7337e906dec5de1d9dd59e13df99914e0492b690
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Mar 21 17:27:31 2005 -0600
+
+ std::equal is much faster than explicit iteration.
+
+commit 1100fa20b52c550cf8802943ec4e552c2e298fa7
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Mon Mar 21 13:31:47 2005 -0600
+
+ Replaced the implementation of solving guides into paths.
+
+ Refactored the abstract syntax of operators.
+
+commit f9ff6a61a29c8df50659f730f98be728830c3e22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 21 12:04:22 2005 -0600
+
+ Changed marker filltype default to NoFill.
+
+ Introduced Above/Below and Crop/NoCrop variables.
+
+commit 9e96f3aa2e744d9561c4d13d8cc3a9ef983a7200
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 21 12:03:57 2005 -0600
+
+ Code cleanup.
+
+commit 9e6f2a3f6c0099ec6642567d96932f63683cd836
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Mon Mar 21 11:06:20 2005 -0600
+
+ memory::insert(poolitem) was eating most of the runtime. Use std::deque instead of std::set.
+
+commit 4ad3c0531e5651b82d52ba87a77e9bd24c469b58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 21 03:23:10 2005 -0600
+
+ Prepend only nonextended axes in current layer.
+
+ Fixed xlimits and ylimits; removed obsolete crop() routine.
+
+ Updated documentation.
+
+commit 8d5dfdfef662e70079daca1ab2d7eacde8aa157a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 20 19:48:04 2005 -0600
+
+ Draw axis on top of cardiod.
+
+commit 9c65b619f46aafa4f1740a246d5822f2759fa478
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 20 18:33:14 2005 -0600
+
+ By default, draw axes before other objects in current layer.
+
+ Fixed frame alignment scaling.
+
+commit 50427ac154c38238346d706ca405a9c27fa94c3c
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun Mar 20 18:32:39 2005 -0600
+
+ Add include guards.
+
+commit 2559e39aa5e57726af10cbce4aa18fe4b072f3f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 20 18:12:50 2005 -0600
+
+ Added least-squares fit.
+
+commit d5790371c28c11ad3fb59e9639fa793d8774f897
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Sun Mar 20 18:03:45 2005 -0600
+
+ Use free function vm::pop instead of vm::stack::pop.
+
+commit 2f9c6d87b5cbcafbd133f2778c902b6946630047
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 19 02:26:51 2005 -0600
+
+ Added append boolean option to output and xoutput.
+
+ Omit "runtime" from error().
+
+ Added frame marker(path g, pen p=currentpen).
+
+commit 2930373bc264af10e3d75bd2e235f13c1a110cf8
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Mar 18 16:41:29 2005 -0600
+
+ Rename namespace mempool to memory.
+
+commit 6cc71345e7d4f8cee34a4dc04a64cc34c31a5b50
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Mar 18 16:23:24 2005 -0600
+
+ Add file headers to castop.h, mathop.h.
+
+commit 80e51aa8fea171856bab468c3e2da0ede814bbb1
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Mar 18 16:17:06 2005 -0600
+
+ Move all template runtime code into dedicated files castop.h and mathop.h.
+ Cleanup all refrences to stack.h, so it isn't needlessly included.
+
+commit b6bfe0819d57b214d867d97667cc136795c66c0f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Mar 18 15:33:24 2005 -0600
+
+ Header include cleanup.
+
+commit 80effa0d6bb808717f83af951713fefa158962cf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Mar 18 00:08:01 2005 -0600
+
+ Allow one to turn on autoscaling again with xlimits(infinity,infinity), etc.
+
+ Accept an overall scaling of frame alignment shifts.
+
+commit 51d64fc33109cb620b83f7ea178af6c087bff5c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 17 23:32:30 2005 -0600
+
+ Fixed interaction of new automin/automax scale flags with xlimits/ylimits.
+
+ Use a small tick by default for unlabelled intermediate decade ticks.
+
+commit 52e53208a208b0e56ff90abbbf3b9be38a2c02a7
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 17 17:41:41 2005 -0600
+
+ Remove UNALIAS, since it is no longer needed.
+
+commit 397d1bf1f4f50b93574cb180a183c960774997f9
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 17 17:33:16 2005 -0600
+
+ Simplify runtime file position reporting.
+
+commit 2e6f6c8542028bc6a00e040fbc2b86eb566d6cc9
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 17 16:26:35 2005 -0600
+
+ Start refactoring stack::run.
+
+commit e84e3416c48b1dcc8a721d9e2878232748196081
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 17 16:24:34 2005 -0600
+
+ Replace inst::alloc with inst::makefunc + inst::popcall.
+
+commit d7eba25b48d76a51b2b1b782304f6ef524dacf16
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Mar 17 16:16:44 2005 -0600
+
+ stack::globals is obsolete. Get rid of it.
+
+commit 20a985d093f7b8df432a47b88ee3cf7ef9e0b970
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Mar 16 23:38:04 2005 -0600
+
+ Fix return breakage.
+
+commit 0b5a5e6156eb4c79c6db84d48e2cf8c058a06586
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 16 23:09:05 2005 -0600
+
+ Don't draw logarithmic subticks by default when number of big ticks > 2.
+
+commit d5c5be3576859a1bbe7ed82d52cb1d8763c8c571
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 16 23:01:16 2005 -0600
+
+ Show 10 subticks by default for thinned logarithmic graphs.
+
+commit e10e7227dfc2f8207a0d50e08e6a30d7c874de78
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 16 22:17:20 2005 -0600
+
+ Fixed interactive line number reporting for files that are input.
+
+commit be0831999916b554453bb60f96d94adb69156270
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 16 16:32:31 2005 -0600
+
+ Fixed more cxx warning messages.
+
+commit 0b1916bf9c61187d2d9d2c5cbed0c4a49712443b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 16 15:52:12 2005 -0600
+
+ Fixed cxx unused variable warning messages.
+
+commit d4c280afadf164fe1539250a0dcdb1ca4e49ae63
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 16 15:35:40 2005 -0600
+
+ Added frame alignment (analogous to label alignment) for positioning frames
+ on picture.
+
+ Generalized and simplified palette bar interface by using frame alignment.
+
+ Renamed addabout to add, drawabout to draw, fillabout to fill, and
+ filldrawabout to filldraw.
+
+ Updated documentation; added examples of frame alignment and histograms.
+
+commit 1289a2376a96ec8ec157bb6a794dce806be47808
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Mar 16 13:12:31 2005 -0600
+
+ A record (and module) is just a function that allows you to access its
+ variables after it is done. Implement them this way.
+
+commit 062f45417029bba8694775bd9ca8450ec5c3b640
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Mar 16 11:44:40 2005 -0600
+
+ We don't use opcodes for functions any more, so remove instAccess.
+
+commit 5fb48426cf966b45cbd368c7f7cc5a0b40d23ff1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 15 23:39:30 2005 -0600
+
+ Documented bool empty(frame).
+
+commit bfe787b7e336948ca51c21277dfd5c472b772779
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 15 23:26:58 2005 -0600
+
+ Changed arithmetic opcodes to functions.
+
+commit ee5d5b58d89b0a31b66ffab6bb610beac948cdcf
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Mar 15 22:05:15 2005 -0600
+
+ We don't treat files specially, so get rid of class.
+
+commit 9db8586587d8c24499e0650400e4b90263c2c774
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 15 14:54:29 2005 -0600
+
+ Moved interrupt check into main loop.
+
+commit 6330fd67d2b69f53825b092e60afaaff12453044
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Mar 15 12:26:47 2005 -0600
+
+ The only symbols should be coming from symbol::trans().
+
+commit eadcc002fb7d0cd06ead3e3744077c461ce12912
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Mar 15 12:25:12 2005 -0600
+
+ Use get<>() instead of any_cast<>().
+
+commit afe9283bc03ed01aa5ed7987d3a5396ce045c72f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Mar 15 12:10:03 2005 -0600
+
+ Use $(OPTS) instead of $(OPT), which doesn't exsist.
+
+commit 4b10272ee1cecf6d708877603c95c8f107ff688d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 22:49:40 2005 -0600
+
+ Incremented version to 0.71cvs.
+
+commit 4dcca5a6ee04e4f29421bd24499152aa96fe4a40
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 22:33:12 2005 -0600
+
+ Added missing #endif.
+
+commit 383b26609aa5102f7d342736bfef372d4c21c6ce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 22:32:02 2005 -0600
+
+ Fixed preprocessor conditionals.
+
+commit 0e07ff07bb3f2137aa47507892c4ab24c168b0e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 22:18:31 2005 -0600
+
+ Fixed dummy fpu exception support for machines lacking C99 fenv routines.
+
+commit 2e0ab93f26d039a7cba2e13cd6464c747e9b3ea7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 21:48:27 2005 -0600
+
+ Removed reference to deleted xdr files.
+
+ Added gv sigint.patch to prevent interactive interrupts from closing the
+ gv window.
+
+commit 80ce8944a5b5832e3f1e1d4ffbf7fea40b54f33d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 21:46:14 2005 -0600
+
+ Added missing prototypes for cxx compiler.
+
+commit 63779cce323b91fa6281ba6bd068650097a3a762
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 14 21:31:12 2005 -0600
+
+ Improved error and interrupt (ctrl-c) handling in interactive mode.
+
+ Mask floating point errors by default in interactive mode.
+
+ By first issuing an explicit reset command, code can now be entered prior
+ to executing an interactive input commands.
+
+ Added scroll(int n) and string cd(string) commands.
+
+ Added Jn and Yn Bessel functions.
+
+commit ec1b3228b405a1a100345c0efe421798b096da6e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 13 22:38:38 2005 -0600
+
+ Fixed bug in extension with a robust (and faster) parametric solver.
+
+commit a7c355ff72ea19fd57cc3e1989875beb792ca9c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 12 05:25:01 2005 -0600
+
+ Added -bw option to convert all colors to black and white.
+
+ Removed double(file) in favour of single(file,false); also added
+ csv(file,false) and linemode(file,false).
+
+commit d0f6dd2c556dd61fa48a2eb28a531d9016a40cf5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 12 04:19:52 2005 -0600
+
+ Minor change to palette interface.
+
+ Replaced image.asy with more compact example to reduce distributed file sizes.
+
+commit efb59b62abef788b02fb99676f9d3fb79ef69d03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 12 02:22:59 2005 -0600
+
+ Removed textpen argument from image labels.
+
+commit c041cbd3576922d0756468e12bc919a6c346d724
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 12 01:57:32 2005 -0600
+
+ Fixed image support for pstoedit asy backend.
+
+commit 035fe65aa42f296fe516a61c46fbf25938bbb7ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 10 19:01:45 2005 -0600
+
+ Thin crowded logarithmic axis.
+
+commit 4d60967bba5f19dc2b2538cb02a42f4cfa8ad394
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 10 17:20:02 2005 -0600
+
+ Updated examples to use XEquals rather than xequals.
+
+commit 4d127046c1aeaf8bebc840ed2ed09893e006b96f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 10 17:12:52 2005 -0600
+
+ Generalized secondary axes to handle any scaling (e.g. logarithmic) and
+ removed the two bool options (no longer needed).
+
+ Improved tick divisor calculation when automin=false and automax=false.
+
+ Added and documented file double(file) to complement file single(file)
+ for setting the precision of real XDR reads and writes.
+
+ Cleaned up automin and automax in scaleT and autoscaleT.
+
+commit 6e65c7e185989b36577c5c93892e246c4795f246
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 10 08:21:59 2005 -0600
+
+ Removed unneeded -I- compilation flag.
+
+commit 595553923d62ae661cfb3d0aa2b40dccd6a1fe55
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 23:53:24 2005 -0600
+
+ Incremented version to 0.70cvs.
+
+commit 477df127590bb09da07214bcb04c7c1f84a9ca94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 23:34:58 2005 -0600
+
+ Install xdr image in examples directory.
+
+commit a235c2ad03054ff8c75e5386ac8c5e9f0b6fd5ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 23:21:56 2005 -0600
+
+ Fixed warning message.
+
+commit b049cd6f95bad9bb455aaae5e88778b2d83b39c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 22:53:55 2005 -0600
+
+ Fixed font.
+
+commit 004fbe06c5160327d3e0d57e285bceca1d4309db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 22:44:32 2005 -0600
+
+ Recommended use of XEquals and YEquals axes over internal xequals and
+ yequals routines.
+
+commit aed4ec201a50e40d2eb0215defb879fccab7dfde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 22:20:38 2005 -0600
+
+ Suppressed misleading warning message.
+
+commit 57fa041fe8d124e9e1dad7125ae5220686fa8a45
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 21:47:55 2005 -0600
+
+ New example.
+
+commit 143a26dcb567685d0ce5929e89dcb4b8b23f413d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 21:42:55 2005 -0600
+
+ Fixed numerical precision bug in extension (in math.asy, reported by Gao).
+
+commit 3c3f932905cf0868c195752793d10c6df1a03daa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Mar 9 21:07:45 2005 -0600
+
+ Fixed secondary axis tick selection;
+ Improved tick selection for crowded axis when automin or automax=false.
+ Added n-point unit cross routine.
+ Added Grayscale and Rainbow palettes.
+ Documented color density images, palettes, and mark option to draw routine,
+ with examples.
+
+commit 8b0eaeda7aaca5029fa1f0924520cd06fe30d303
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 8 23:34:28 2005 -0600
+
+ Slightly reduce default number of colors to workaround gs pdf limitations.
+
+commit 6d2e05fe3e90fdb73704ea448f7dbfd339f5bcfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 7 23:56:26 2005 -0600
+
+ Added missing file.
+
+commit 74f2191aa08dc4fdfb950d6d6f10e99cb1b1f72e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Mar 7 23:31:44 2005 -0600
+
+ Added support for generating image density plots and palettes.
+
+ Added support for data markers, including cross, plus, and polygon markers.
+
+ Added min and max functions for 2d and 3d arrays.
+
+ Fixed tick divisors in secondary axes.
+
+ Deep copy path arrays to avoid suprises.
+
+ Fixed limits() in graph.asy.
+
+ Respect "#" in format strings (allows trailing zeros).
+
+commit e9c130603cd14c2f9261748346df2ee80a32b3a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 5 13:16:18 2005 -0600
+
+ More general example of secondary axis.
+
+commit eef695ff4e84a60a0fa0d58cc0a818b9d2c33f7e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 5 13:14:54 2005 -0600
+
+ Fixed secondary axes bug;
+ xlimits, ylimits, and limits now use properly scaled user values.
+
+commit 1469b143e3743035b7ffe4304bfbba9c061de31e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 27 21:51:58 2005 -0600
+
+ Minor optimizations.
+
+commit 16be11de9bfed8e2983390a7d1707c7c8a5b2b8e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 27 12:40:32 2005 -0600
+
+ Adjusted margins so that arrows all have same length.
+
+commit 8940ceb61e0415275a2b7265b27a3fe34fcb7c6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 27 12:23:50 2005 -0600
+
+ Updates to support Microsoft Windows.
+
+commit dc010b20c1564f1a064b8cff721693a095136ece
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 27 10:49:10 2005 -0600
+
+ Fixed finite(pair).
+
+commit e2452b93245390c6864dd50a65a0fdbd2d24e361
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 27 06:29:47 2005 -0600
+
+ Incremented version to 0.69cvs.
+
+commit 284f5e02bf7f045ab6821cc1c26ba10ab7f0c0e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 27 05:59:56 2005 -0600
+
+ Added Andy's constraint removal code for even better simplex optimization.
+
+commit 9e276662765e27ac0b8f8bc53e9ea0885598edb7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 26 23:14:35 2005 -0600
+
+ Updated to use Margin rather than subpath.
+
+commit 9f1d95c1a9fa14497433f86fa5e523cae1d28b3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 26 23:00:33 2005 -0600
+
+ Incremented version to 0.68cvs.
+
+commit e1193e95f3a895b2436d75d50f8f73d69607de77
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 26 20:48:49 2005 -0600
+
+ Initialize font explicitly to ensure compatibility between tex pipe and
+ final latex processing and to ensure tex pipe font is properly reinitialized.
+
+ If picture cannot be fit to requested size, scale size by sqrt(2) and retry.
+
+ Added gv-3.6.1 patches; updated documentation.
+
+ Modified pstoedit patch to remove unneeded shipout().
+
+commit f1526a9885d8746dfbccefc4a3f3d48816535145
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 26 15:55:50 2005 -0600
+
+ arrowsize updates
+
+commit ba482f250756a7ee89fc7df79392230497bab022
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 26 02:23:43 2005 -0600
+
+ Removed superflous constraints before solving linear programming problem.
+
+commit aacb768217a0a0ddf10d7b2a55e9d8da8462bf75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 25 23:51:35 2005 -0600
+
+ Check that r.c >= 0 in selectVar (this guarantees that r.t[col] < 0).
+
+commit 68f312a4eaca8c4925e21ba8d3436c3126d3a79b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 25 21:31:21 2005 -0600
+
+ Optimized simplex pivoting.
+
+ Made global constants static.
+
+ Fixed recently introduced error in relative(picture, pair).
+
+commit 0abdc841e8ec1ad324258ab524cab6c7d80469e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 25 12:11:52 2005 -0600
+
+ Minor errorbar updates.
+
+commit 1913234e5ee42aa76300e99a70b0792902a8d2ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 25 12:11:20 2005 -0600
+
+ arrowsize updates
+
+commit df425036e10f798c76c6365bb24829756bbebf5f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 22 00:41:54 2005 -0600
+
+ Incremented version to 0.67cvs.
+
+commit 28f501a320b2177f7f89546088c3099dba9414eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 21 23:41:21 2005 -0600
+
+ Improved selection highlighting in GUI.
+
+commit 5c106d79c1aef1fd3bd9d9d91d93a1e0013d428d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 21 00:12:23 2005 -0600
+
+ Put quotes around outputted font command string.
+ Set camp::TeXcontaminated to false upon decontaminating.
+
+commit a861c5bd3d1d6333fcde9290442726b3b06bc538
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 22:57:04 2005 -0600
+
+ Moved interactive rejectline code back into main.cc.
+
+commit 16e08c8092a9c7e639629cd36870c407dcde1f1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 22:16:09 2005 -0600
+
+ Moved cleanup functions into exitFunction.
+
+commit 4c195053d81f69264b9421d77302fae11dbdb7bc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 21:41:20 2005 -0600
+
+ Added atexit function.
+
+ A shipout() command is added implicitly at file exit if no previous shipout
+ commands have been executed. The examples were updated to remove any
+ unnecessary shipout() calls.
+
+ Used atexit to clean up asymptote.sty and interactive mode.
+
+ Files with no drawing commands now work with -f pdf.
+
+commit 503dbcab8b4dc6b733411ef0e9ac21074ecffa48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 03:07:38 2005 -0600
+
+ Fixed (logarithmic and other) scalings of XEquals and YEquals axes and
+ errorbars.
+
+commit 7547285f427c4996be8f1dadc0dd5af8c1d7536c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 02:28:25 2005 -0600
+
+ Fixed typo.
+
+commit 604d36b68a3f98a069991f0983d6b31807cdbb9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 02:25:04 2005 -0600
+
+ Incremented version to 0.66cvs.
+
+commit ad29e30984369623437ef0fa56d92524a1288668
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 01:47:46 2005 -0600
+
+ Fixed location of latexusage.tex.
+
+commit 0558d6d8a9e537a64e6d9b7c831d7e0bd112faa5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 01:39:25 2005 -0600
+
+ Incremented version to 0.65cvs.
+
+commit cfcc1092d054a6061a4f73f9fd5143210e7b1941
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 00:28:21 2005 -0600
+
+ Fixed typos in example.
+
+commit e516236e2a4ffc85d6d0c090a80fd81ad672dec1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 00:19:39 2005 -0600
+
+ Updated examples.
+
+commit a59e528a1131c3a2907deed7ee227e0ef74d6f0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 20 00:00:14 2005 -0600
+
+ Linewidth change.
+
+commit ff81aec247f38be5090c29d298cfefeae69e157c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 19 23:57:01 2005 -0600
+
+ Added DotMargin margin qualifier.
+ Updated examples to use margins.
+
+commit 66f4587e49213cfd0cd2cbcbbef58655199716f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 19 22:40:42 2005 -0600
+
+ Added errorbar routines to graph.asy.
+
+ Changed arrowhead and dimension bar default size specifiers:
+ arrowsize to arrowsize(pen p=currentpen),
+ arcarrowsize to arcarrowsize(pen p=currentpen),
+ barsize to barsize(pen p=currentpen).
+
+commit 9fadc21370ae167e70248a450697484588319944
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 19 19:29:46 2005 -0600
+
+ Fixed bug in eval(f(T), T[] A).
+
+commit 8b4466afa40e9e7cc5e9db290adf4935989ca988
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 19 12:35:38 2005 -0600
+
+ Documented real[] A vs. real A[] issue.
+
+commit 67e6e3ceaabcbf04544194124c85ecd5c0a074e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 19 11:50:51 2005 -0600
+
+ Documented and improved margin routines.
+
+ Included correct latexusage file in documentation.
+
+commit 9498e0af1d4f38f833b52f3620ab24d089dee94c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 19 00:32:16 2005 -0600
+
+ Added Margin, PenMargin, and TrueMargin drawing qualifiers.
+
+ Fixed name conflicts between asymptote.sty and comment.sty.
+
+ Install latexusage.tex with examples.
+
+commit 38bb78c422e9bd2d3675046a467f6252ebd14678
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 16:07:55 2005 -0600
+
+ Fix diagnostic.
+
+commit 29aff167ca03ef67f70ac1b62d1b98c9dac71606
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 15:13:16 2005 -0600
+
+ Fixed segmentation fault in anonymous function diagnostic.
+
+commit 9047b90269425c9cfc3b9b5cde15fa9d77caec73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 03:32:37 2005 -0600
+
+ Incremented version to 0.64cvs.
+
+commit fcd9f40af610b0609d9c9f4cf6f41fa24e430a64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 02:54:40 2005 -0600
+
+ Reset lastpen on every call to texinit.
+
+commit e03473a1d037f7527a28bda91860a854fd41bfe0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 02:32:44 2005 -0600
+
+ Fixed harmless typo.
+
+commit debec9e2457a43185d6fd8eabd325bd73f609e21
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 02:28:13 2005 -0600
+
+ Incremented version to 0.63cvs.
+
+commit 8db8d6d2443535dc5767219c703b6df6ca66ec18
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 01:27:57 2005 -0600
+
+ Fixed shading colorspace & fillrule/baseline output strings;
+ removed unwanted space from gsave/grestore.
+
+commit 9bf7f08f84a6cade9d9fd51998411615b4afd1b9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 18 00:38:20 2005 -0600
+
+ Added basealign pen type to align labels using the TeX baseline, if
+ applicable, rather than using the full bounding box. (The default continues
+ to be nobasealign).
+
+ Documentation improved in several areas.
+
+commit 28a03b437f7c1e00608b6c2f907c60fe2f2ee616
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 17 08:57:51 2005 -0600
+
+ Added missing include.
+
+commit 6eef3163b0df65b4befb9c1d7e4e86c81ebf62cb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 17 01:02:35 2005 -0600
+
+ Simple example of label positioning.
+
+commit 8ffd567418105a39206bf034ea3ec903c5735278
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 17 00:56:21 2005 -0600
+
+ Corrected index entry.
+
+commit 5d3675110563d25e16b6f9c8079661425c1edfaf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 17 00:54:19 2005 -0600
+
+ Workaround broken cxx linux-alpha headers.
+
+commit 7f051aef9efdc4169d33bf295471e63d492d94a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 17 00:38:29 2005 -0600
+
+ EPS files (and other formats supported by \includegraphics) can now be
+ included and positioned just like any other LaTeX label (the include
+ function has been changed to return a string containing an includegraphics
+ command that can be used with label).
+
+ Added image support to pstoedit backend.
+
+ Fixed compilation problems under Solaris.
+
+ Updated documentation.
+
+commit fa4a2ff2a63cae4e99ba06d3aad15ab8b8033640
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Feb 16 11:43:22 2005 -0600
+
+ CFLAGS is already subst'd by AC_PROG_CC.
+ CXX defaults to g++ if it is available (AC_PROG_CXX).
+ Define CC in Makefile if we get it from AC_PROG_CC.
+
+commit 733007c5d36fa7bf65d9aef914e28b1a82152b2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 16 11:42:33 2005 -0600
+
+ Changed namespace absyn to absyntax to avoid conflicts with class of same
+ name under some compilers.
+
+commit b05b2ab708733bd5da94b3868e36d174deb55394
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 16 11:24:02 2005 -0600
+
+ Namespace as -> absyn.
+
+commit fe7b0ca63585732565f21c040bc2a6b266276c94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 16 11:18:44 2005 -0600
+
+ Namespace as -> absyn.
+
+commit 3778ce248900af52939f5baa8db7e9dd18593603
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 16 11:14:02 2005 -0600
+
+ Renamed namespace "as" to "absyn" to work around Solaris namespace pollution.
+ Added CXX=g++ to configure.ac and removed -DNDEBUG flag.
+
+commit 797f13b0fc7dd233f0248a7aaf4f9a6218f38abb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 15 22:23:14 2005 -0600
+
+ Clip should insert beginclip at beginning of current layer.
+
+commit 462f2955efdba755a3df16924dd41d216bbf2e62
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 15 17:46:32 2005 -0600
+
+ Reinstated underlying frame clipping for picture clipping (with transform
+ bug fix), allowing picture unfill to be properly implemented (using frame
+ unfill).
+
+ Moved beginclip, endclip, gsave, and grestore to pstoedit.asy.
+
+ Fixed remaining gsave/grestore bugs in Asymptote backend to pstoedit.
+
+commit 303435f4e3c52d1b38f5d31a32685dff9ea71a6e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 15 02:01:03 2005 -0600
+
+ Code clean up; added pair min(path[]) and max(path[]) functions.
+
+commit 6260496285c2a9c87e6d7891e8021c4134ab55b8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 14 23:25:28 2005 -0600
+
+ Incremented version to 0.62cvs.
+
+commit ed62a98eee707e36126ee3acc513bb11763c0b5e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 14 21:39:00 2005 -0600
+
+ New examples.
+
+commit b7b089209392247a58749f86a76e5e5c356589c9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 14 20:57:01 2005 -0600
+
+ Added PostScript grestore/gsave objects.
+
+commit 3a83a424a915fdf048da7ab98b60bd081a65696b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 14 20:54:11 2005 -0600
+
+ Fixed spelling and grammar.
+
+commit 8ac3bec8f6df31f5f83f22eb07b5eb55842b343f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Feb 14 19:01:27 2005 -0600
+
+ Added Asymptote backend and support for pstoedit, including native
+ clipping and subpaths.
+
+ Added Postscript font and scaled TeX font support.
+
+commit 7009ba7329eeca33c7dc4d176639ddc104e276f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 13 15:57:10 2005 -0600
+
+ Added warning message and documentation about clipping deconstructed objects.
+
+commit 6aa5b38b9a6e94362fc66fd753e6bf7a0a974138
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 13 15:36:46 2005 -0600
+
+ Added -gray option.
+
+commit df0db34958b4ec086fa2a317ecb7dd79306bf6fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 13 12:21:41 2005 -0600
+
+ Install documentation examples and data files in examples directory.
+
+commit ccc354b08dc5706fe0383ee6ea2b072f827bf975
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Feb 13 12:08:12 2005 -0600
+
+ Reimplemented picture clipping to fix transformation and layering of
+ clipped pictures.
+
+ Use correct font and fontsize for computing label bounding boxes.
+
+ Use -O0 for producing dependency data.
+
+commit e9464de788fc1d24dd60aae8937f41b855c322f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 12 03:26:46 2005 -0600
+
+ Added background variable.
+
+commit 22252bdf84499d5ecdf09809d857700722257cb1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 12 03:21:42 2005 -0600
+
+ Added drawing, filling, and clipping of compound paths built up with a pen
+ lift (moveto) operator ^^ instead of --.
+
+ Added functions to unfill a region to transparent background.
+
+ Added zerowinding and evenodd pen types for filling and clipping.
+
+ Introduced pen types squarecap, roundcap, extendcap, miterjoin,
+ roundjoin, beveljoin to replace linecap(Square) calls, etc.
+
+ Added checker pattern.
+
+ Added LaTeX NFSS and TeX fonts and ability to override default baselineskip.
+
+ Fixed bug in LaTeX rotation angle output format.
+
+ Added contributed tree drawing script and example.
+
+ Updated documentation.
+
+commit d367e8c404772a6dd98e54466742fe8b12fa8a12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 9 09:08:27 2005 -0600
+
+ Editing mode updates.
+
+commit 51dd70f15ee70c193ca5d9c6e9869fb2fcb553fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 9 08:40:20 2005 -0600
+
+ Renamed labelframe to labelBox; added labelbox(frame).
+
+commit 9716d767e81de011dd47e9ecfeb2273cd2777337
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 8 23:46:20 2005 -0600
+
+ added labelframe and point(frame,dir) routines.
+
+commit 83cd63b559666d92876804f3999e996a54ca0c2a
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Tue Feb 8 15:45:32 2005 -0600
+
+ Changed string highlighting to recognize double \ escapes.
+
+commit 9bfdac4ea0f8b8d539402178c609761977b5a374
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Feb 5 15:43:28 2005 -0600
+
+ Updated documentation and pattern examples.
+
+commit 673598b4cbfb40510d58a38fe50bdb9a222b9459
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 4 22:49:13 2005 -0600
+
+ Added brick pattern.
+
+commit 19ff72f4ba6f49669117bf4bad71b7427c25c9d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Feb 4 16:15:16 2005 -0600
+
+ Added bool option to linetype to disable automatic scaling of linetype
+ parameters with pen size. Fixed segmentation fault and float point
+ exception in adjust_dash in drawpath.cc.
+
+ Added bbox(Background) option for producing a nontransparent background.
+
+ Moved simplified pattern routines and builtin patterns hatch, crosshatch,
+ and tile to patterns.asy. Updated examples and documentation.
+
+commit 0a798b5693fd153883bd81789e8f7152a312cd71
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 3 21:05:37 2005 -0600
+
+ Fixed recently broken interact mode.
+
+commit d0302683ce91faa71fe83e1b9ce0021042916f2e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Feb 3 13:18:20 2005 -0600
+
+ Moved default CFLAGS into configure.ac
+
+commit 7d40090cb009bca42e096cf60ca2b0d974fab4d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 2 13:16:31 2005 -0600
+
+ Fixed optimization flags (revert last change).
+
+commit 13fb05dc4824fb5677f386db5ba37068ee6e41dc
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Feb 2 08:40:53 2005 -0600
+
+ Stanardize CFLAGS handling.
+
+commit fe1ee205fbe6928e6c9116fb5a6e7df5f253c823
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 2 06:16:25 2005 -0600
+
+ Fixed header problems under FreeBSD.
+
+commit 21def4fc8e07c0d718e73e1bb6cbf593a9823c34
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 2 00:54:33 2005 -0600
+
+ Incremented version to 0.61cvs.
+
+commit 3b6044c76830ccc27e5599c7f4184d5a050bc12f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 2 00:10:58 2005 -0600
+
+ Interactive mode automatically restarts ASYMPTOTE_PSVIEWER in case it exited.
+
+commit 597bcc238bdf57c1c5ee7b0be185a34d49c08304
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 2 00:07:24 2005 -0600
+
+ Added picture grid(int Nx, int Ny, pen p=currentpen) function for
+ generating square lattices.
+
+commit cc7582773ec89abf83d53951301b9a849f6c958e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Feb 2 00:04:57 2005 -0600
+
+ Simplified binary installation instructions; updated hatch.asy listing.
+
+commit c51f05c9af30d87e7f49f9a6ce27416e150a9327
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Feb 1 10:03:21 2005 -0600
+
+ Fix path solving. Strange place for a bug.
+
+commit 4046420fa38047ab48a6f9114d79f1b133844993
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 1 02:52:50 2005 -0600
+
+ Removed extra newline from diagnostic.
+
+commit d6c7d56a81c74dca0467f15941229101ceafaa28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 1 01:43:33 2005 -0600
+
+ Fixed namespace/function conflicts.
+
+commit c9e796e9e170a82bc486199ba7716c64db6b99f2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Feb 1 01:33:26 2005 -0600
+
+ Fixed interactive mode to suppress standard I/O also from static imports.
+
+commit 2566e42a9a29888574606c717e01b459515eb122
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 31 21:41:57 2005 -0600
+
+ Fix rfind(string s, string t) and update documentation of string functions.
+
+commit 81522814d5593ac2f99a96b1f6827684f56a740b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 31 18:42:04 2005 -0600
+
+ Add facility for checking to see if a file exists, using bool error(file).
+
+commit 2d7bc86ef31d922d01e19e7bd7323d8a0e36c48c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 31 16:15:48 2005 -0600
+
+ Fixed multiple interactive shipouts in graphs with legends.
+
+commit d5510487a847ffbe3270d74042c68de4c2c88dca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 31 00:21:33 2005 -0600
+
+ Interactive mode now supports inputting files with multiple shipouts.
+ Interactive mode disables deconstruction (xasy).
+
+commit c56e2e4c3b36897baa56333df2e5d8f481b20744
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 30 23:17:47 2005 -0600
+
+ Fixed endl and tab in plain.asy to produce C strings.
+ Fixed recently broken include command.
+ Renamed internal symbol ASYalign to more meaningful ASYbase in baseline.
+
+commit 872c389229301cfc209e2c0349503cf8d240d9b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 30 22:46:28 2005 -0600
+
+ Put file back into mempool by making typein and typeout variables rather
+ than pointers.
+
+commit 18b1fef96c161127ea53f9f4780b131d4e2b4942
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 30 18:44:14 2005 -0600
+
+ Updated examples to use math.arc routine.
+
+commit d41eb28ef472b8ba83c21468b0b48d808feaa39c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 30 16:55:47 2005 -0600
+
+ Allow optional Asymptote commands to be specified on the same line as
+ interactive input command.
+
+commit 5f5586572db63c8bc186ca36f5edc9b9dea978e9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 30 12:15:01 2005 -0600
+
+ Buffer stdin in interactive mode.
+ Changed Import to input, which includes code directly into Asymptote, so
+ that the user has access to the same environment that the code sees.
+ Cleaned up fileio and removed it from mempool due to conflict with iostream
+ routines.
+
+commit b1d64a589218c621786a1af426d581c009a9e207
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 28 21:04:41 2005 -0600
+
+ Add baseline TeX code back into texfile.h from plain.asy.
+
+commit c9a85dae7aa090f26d84e035128594d78c1385e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 28 03:54:10 2005 -0600
+
+ Incremented version to 0.60cvs.
+
+commit 82e18a2effb5642baa92e296f1be7fe4b9cf60ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 28 02:21:34 2005 -0600
+
+ Makedepend updates.
+
+commit e134133f3b4d137d42c842e3871e928c17e104a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 28 02:09:05 2005 -0600
+
+ More makefile tweaks.
+
+commit 71b7187f832f9726abd1f4ce7f7fa2402352e333
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 28 01:40:32 2005 -0600
+
+ Final makefile updates.
+
+commit 5ee54ce48e3536f51119f7ed27986f988558e4dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 28 01:15:07 2005 -0600
+
+ Automatically check for broken rpc/xdr headers.
+
+commit 5dd8676e496112918d515d521ac1e5d76e0a7e58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jan 28 00:01:20 2005 -0600
+
+ Fixed bounds to be consistent with behaviour of new quadratic solver.
+
+commit a6fae99ab1ab2214c4c0fb328d4248dd0ccd333b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 27 23:41:06 2005 -0600
+
+ Implemented robust, accurate quadratic equation solver (used in dirtime).
+
+commit 7deacc022138293f1b7ea337c6f3dadf15bd23d3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 27 17:20:26 2005 -0600
+
+ Added getopt for systems without full GNU getopt support (e.g. cygwin,
+ FreeBSD).
+
+ Use "make all/make install" to produce/install both asy and man pages.
+
+commit d907ef68414f53dccfaf4726944fa072c265ad61
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Jan 27 01:30:12 2005 -0600
+
+ Better? quadratic routine.
+
+commit 34e5884ceacd46acd76abcc6debf987fc12a9d83
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Jan 26 12:06:22 2005 -0600
+
+ Use solveQuadratic for path::bounds as well.
+
+commit 697e218e413621cb7b0a78378df21562a92020bd
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Jan 26 11:44:00 2005 -0600
+
+ Fix fuzz case in cubic dir.
+
+commit f8b8d7dab36c025d9d81714098c5d4fc6e992812
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Jan 26 11:37:55 2005 -0600
+
+ Duplicate code.
+
+commit e15a948eb7498d2ffa9c1c25fb65cdb617652e10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 26 10:47:50 2005 -0600
+
+ Added fuzz to fix dirtime(unitcircle,dir(-45)) bug under make OPT=-g.
+
+commit 12eae75206190bbeb7ea03e695888e13d1e29d9f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 26 02:14:32 2005 -0600
+
+ Implemented all ANSI C character string escape sequences for C strings.
+ Removed all escape sequences from TeX strings except for \", which maps to ".
+ Added support for LaTeX babel package.
+
+ Improved arc so that it coincides exactly with circle approximation for all
+ angles. Added triangle arc routine to math.asy.
+
+ Renamed gray to lightgray in the example files.
+
+commit ef94f1c7970998ed0489cb0ef1f071a37cf40df2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 25 10:02:15 2005 -0600
+
+ Fixed explicit keyword (broken in dec.cc 1.8 on 2005-01-19).
+
+commit f1463209178ca79e93fbb7cc03f98ad04da070b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 22 02:55:26 2005 -0600
+
+ Renamed gray to lightgray; gray now means gray(0.5).
+ Added colorPens and monoPens lists and boolean variable mono.
+
+commit a38f9e67b9ed8397b7404aad29d8213482dc185c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 22 01:14:42 2005 -0600
+
+ TRANSPARENT pen now has higher precedence that DEFCOLOR; also output
+ "invisible" for this pen color.
+
+commit c0e19513dd8c5bc30401fb4b46e32285fdba45fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 22 00:48:56 2005 -0600
+
+ Added checks on string position arguments.
+
+commit 6eb71920bb2d13c58629cd0c3edb21a3f4d4bc4e
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Jan 21 07:44:46 2005 -0600
+
+ Handle invalid numbers gracefully.
+
+commit 004abb085554db987aaa582ce22bd2576470aab6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 20 22:35:54 2005 -0600
+
+ Fixed cstring so that '\\' produces a backslash.
+
+commit aaaa207f4efee701f9e6455ef5faa481ad54888b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Thu Jan 20 16:35:38 2005 -0600
+
+ Add C-style strings delimited by '. (e.g. '\n' instead of "\\n").
+
+commit 53d04784fd7da27cb52c6b8e415a45ab1d893e2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 20 04:14:02 2005 -0600
+
+ More arc improvements.
+
+commit 25ecd5c73477c683e502ff7c975c22b18a61f943
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 20 02:19:33 2005 -0600
+
+ Pdf updates.
+ Added new arc routine and point/path utility functions.
+ Added new examples and updates to feynman.asy.
+
+commit 8d06235ab386b7d48d2fadae59784a0e0ec0be33
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 18 23:48:12 2005 -0600
+
+ *** empty log message ***
+
+commit f005d31b9780cbc30358ddbffc36c40e58f97348
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 18 23:44:26 2005 -0600
+
+ Get rid of as::defaultExp, and store varinit* in signature instead.
+
+commit ac31ba07570ebdd6ecad5b8afd3b2dabf590ec33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 18 23:38:39 2005 -0600
+
+ Minor bbox fuzz and alignment adjustments; fixed xasy alignment.
+
+commit e039fece159045e5d1bda711994fb98e06ddb0ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 18 21:49:33 2005 -0600
+
+ Implementation of explicit keyword.
+
+commit ddeaaa28a0f5c2e26a3c805be6c6b49b9e86ca6f
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 18 21:16:10 2005 -0600
+
+ Oops.
+
+commit 8330481475bd533d754e87dd1b8650edbb379322
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 18 21:14:34 2005 -0600
+
+ Fix makefile breakage.
+
+commit 9d18f68c3678138173cba1f115ec632a8e33a1be
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 18 21:07:13 2005 -0600
+
+ Don't rebuild asy if we don't need to.
+
+commit 61bb4a0506a9d7fa46840068bfd5b048b81d167b
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 18 19:33:16 2005 -0600
+
+ version.texi is autogenerated.
+
+commit 0b3dabb95ab57f0e71bf09251eddd761366f4a61
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 18 12:25:05 2005 -0600
+
+ Make explicit a keyword to detect breakage.
+
+commit d2bcab30bdcb21e576b010b96450d86a1988869f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 18 01:24:50 2005 -0600
+
+ Inhibit output of null labels.
+
+commit 807c48f5f8381756758ae06feeabb17a4f9a8464
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 17 18:30:20 2005 -0600
+
+ Fixed antialiasing and gv -watch problems.
+
+commit 843c617b2423d9135ecd84c9f3b2762b96529363
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 17 16:11:34 2005 -0600
+
+ Incremented version to 0.59cvs.
+
+commit 6324cafe2759553d86759a9a61e03c30eb4757da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 22:43:30 2005 -0600
+
+ Updated new examples.
+
+commit fc09c78aadca65c061ecdab83c86f9f1a9433f10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 22:35:30 2005 -0600
+
+ Fixed formatting.
+
+commit 696c6a83b7b0bd82b62220923f4f9c8b468da1a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 22:16:23 2005 -0600
+
+ Fixed warning message about unused variable.
+
+commit f7f31e8da553d0c4812d8cf548a1fa940597e61f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 21:54:49 2005 -0600
+
+ Added new entry.
+
+commit 5f23c77fa668e791364343dbb46ca120927c0beb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 21:45:57 2005 -0600
+
+ The default linetype, linewidth, fontsize, color, linecap, linejoin, and
+ overwrite mode can now all be changed with the routine defaultpen(pen).
+ Removed unused pen defaultpen() in favour of void defaultpen(), which
+ resets all pen default attributes to their startup values.
+
+commit e2ecafd9b096d7e4a75010fecd60c45d2a600806
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 01:26:46 2005 -0600
+
+ Added missing == and != operators for struct tree.
+
+commit 412e97c76d466ae84a4e56ec076ca29c00999ae0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 01:15:54 2005 -0600
+
+ Replaced defaultlinewidth and defaultfontsize commands with
+ defaultpen(pen). Moved reset() into plain.asy.
+
+commit 179dcd0adea6b670da41fe33f84bf11cd6e3e205
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 16 00:11:03 2005 -0600
+
+ Added configure option to detect xdr/rpc header files.
+
+commit f9a3b185bc891daa6fd7d66f6d3233b730f5a152
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jan 15 18:45:32 2005 -0600
+
+ Fixed 2d graph bugs 1102574 and 1102396 and related bugs.
+ Added XEquals and YEquals axis types.
+ Allow all axis types to optionally extend to dimensions of picture; updated
+ documentation.
+ Simplified routine for drawing perpendicular symbols in math.asy.
+
+commit 76ac05ba021c34a68832d247b270e01ce4220a24
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Fri Jan 14 15:30:51 2005 -0600
+
+ Store operands with opcode, rather than in the following inst.
+
+commit aef57d9197897694e6911f627c80a61d19080087
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Jan 12 12:45:37 2005 -0600
+
+ markTrans and markTransAsField are utility functions that don't need to be redefined.
+
+commit e1087baecb7ef73eff4d934cd25f027d6c4aed70
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Wed Jan 12 12:36:53 2005 -0600
+
+ Clean up header file dependencies.
+
+commit c724002d32be1004787b82212cacbe4582f19ef9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 12 11:17:35 2005 -0600
+
+ Made currentpen static.
+
+commit 1352343c1a7709c47e4fce15e68c521b1c22265f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 11 22:42:27 2005 -0600
+
+ Use $(MAKE) rather than make everywhere within Makefile.
+
+commit 5e84364254a41a0fe7d0a6cd12309885ee580beb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 11 22:14:09 2005 -0600
+
+ Increment version to 0.58cvs.
+
+commit 54eaa3dc057e3196c84465af73df75931ab6eee7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 11 21:52:01 2005 -0600
+
+ Removed direction(path, real) and direction(path, int) in favour of
+ dir(path, real t=1) and dir(path, int t=1). Added examples.
+
+commit c1a18de5cc1f5e30109c2ebe9712947c6420abc3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 11 17:29:22 2005 -0600
+
+ Made overwrite mode a pen attribute; updated documentation.
+
+commit a5ccb6bc1b3a58cb9b44ae349b42ac4888ebceb9
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 11 13:31:37 2005 -0600
+
+ symbol::trans accepts a std::string not a char*.
+
+commit 4d2e3f5c77081c4d761bae7df317606808b372f1
+Author: Tom Prince <rprince5@uwo.ca>
+Date: Tue Jan 11 13:30:26 2005 -0600
+
+ Fix typo in comment.
+
+commit 08c6e5a90e6d18b3dd4a9566ef9d61069bfa6e42
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 11 02:55:28 2005 -0600
+
+ Fixed infinite loop bug in overwrite mode.
+ Added synonym dir(path,int) for direction(path,int), etc.
+
+commit 0255eb36c53d59fb955edd23c57cd8003202de08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jan 10 22:04:30 2005 -0600
+
+ Fixed rgb to cmyk routine and added cmyk to rgb routine.
+ Added -cmyk and -rgb command options.
+ Made labelx and labely routines position labels consistently with axis
+ routines by default.
+ Generalized baseline routine and moved from texfile.cc into plain.asy.
+ Adjusted logo for new labeling system.
+
+commit 9db1f8cf0de5a928a03399df79b7e8316ba340f6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 9 18:10:02 2005 -0600
+
+ Increment version to 0.57cvs.
+
+commit c8cda1546a2579b1dbfd24b6d15abd49506e3bb9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 9 17:16:50 2005 -0600
+
+ Make PSViewer and PDFViewer search conform to documented behaviour.
+
+commit 94572dc2968e18d4572302af3f830a66c7af8620
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 9 15:43:21 2005 -0600
+
+ Implemented radial gradient shading; updated documentation.
+
+commit 0f7766c8f6779ad7c5468be9945f2887a8be5ab1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 9 12:35:09 2005 -0600
+
+ Make patterns work with xasy.
+ An explicit picture is now required in order to specify preamble to shipout.
+ Added scientific diagram and graphs to documentation to illustrate
+ the minipage function, secondary axes, and the drawabout function.
+ The new real[[] colors(pen) function returns the color components of a pen.
+
+commit cd537b6768ade3f2cdb7ba912ade0af6279021cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Jan 9 03:02:17 2005 -0600
+
+ Added tiling patterns and gradient shading.
+ Added linecap and linejoin pen specifiers.
+ Updated documentation with examples of new features.
+
+commit aaf64a2145422d16d037ee04b07ce2554ea79cfa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 6 21:47:04 2005 -0600
+
+ Minor interp and secondary axis updates.
+
+commit a373e2dcb2a74ee31114e131de29bfcb014e2541
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 6 16:28:55 2005 -0600
+
+ New postscript-coordinate shift option for label routines;
+ pictures added to pictures now transform properly; updated documentation.
+
+commit 82c0764670b6a7f37ace3f5dda4875ee7ad05cf6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 6 04:20:46 2005 -0600
+
+ Added secondary axis facility; fixed scaling bug.
+
+commit cf18a044a97393249e58865a01dbe5ed28308d56
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 6 04:19:12 2005 -0600
+
+ minor formatting.
+
+commit 0496fd3486693a313fe88a9a359839cfe21659db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jan 6 04:17:36 2005 -0600
+
+ Removed unused currentframe variable; updated documentation.
+
+commit 0c452d1f963e32f6e926bca7ec00fc396db2cb19
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 5 17:19:22 2005 -0600
+
+ Further csv and linemode updates.
+
+commit f14fd7bedf633f95bf0239e826dfbe5e5e380a58
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 5 10:21:16 2005 -0600
+
+ Fixed cvs+line mode bugs.
+
+commit 5ab4963be063b0f7d2dd775568187bde9ac900af
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 5 10:20:56 2005 -0600
+
+ label positioning update
+
+commit 19e601b4bea4a9f290fb14f843e643da29f8c863
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 5 10:20:26 2005 -0600
+
+ minor formatting.
+
+commit 62e16369244e6571bcd88a369506fc3f1d4ade76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 5 01:01:23 2005 -0600
+
+ Updated documentation.
+
+commit f63d68663956b533252bc0a78249e42d3696f20d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jan 5 00:38:08 2005 -0600
+
+ Fixed "label with arrow" routine. Removed outarrow in favour of drawabout.
+ Updated documentation regarding new optional position argument of path
+ labels (draw and drawabout).
+
+commit 40922670c83aac9b39075818d3bb7526cfd9f5d2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 4 22:00:13 2005 -0600
+
+ Align labels before adding label bounding box fuzz.
+
+commit 1caf33aa48700401e8dab5c1935e8371e9075974
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 4 21:58:24 2005 -0600
+
+ Use math italic axis labels.
+
+commit 6dde5903fd8d69da16ac521a882378962fb28355
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 4 13:07:41 2005 -0600
+
+ Updated.
+
+commit e6b8f714ddbcedc1ccec4f01ddc619d9c38ccc25
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 4 13:05:08 2005 -0600
+
+ Added function name to "cannot call...with" error messages.
+
+commit 4a3368cbfb9236718c1b1a7b230cf1edb71aa4f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 4 01:34:48 2005 -0600
+
+ Improved and tightened label bounding box calculation.
+
+commit c8261d01c8415dea7b1fea9889fbf944819d9481
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jan 4 01:32:19 2005 -0600
+
+ Made "cannot call type...with" diagnostic easier to read.
+
+commit b82e62c0d0854c00c26077d2385598fb04594b75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 28 09:21:41 2004 -0600
+
+ label and arrow adjustments
+
+commit 00d5f86a020491c3073e6dda1d230dcb0dd475fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 02:01:56 2004 -0600
+
+ Added minipage and outarrow routines.
+
+commit 9419fe6b15870e2957e644a3a9ee2d1f0299401b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 19:55:48 2004 -0600
+
+ Fixed TeX pipestream embedded newline & diagnostic problems.
+
+commit 561d061bf19dc2362472501129e1ebc015fabd26
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 14:20:02 2004 -0600
+
+ implement scaling of pic.userMin and pic.userMax.
+
+commit 64d80cf6a37510d81393daf0f942476fcd1dbadd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 22 23:01:33 2004 -0600
+
+ Added newpage() command.
+
+commit f9cdb946b50ac96b37efbc3b4dfaa68ae2fc590b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 22 19:16:14 2004 -0600
+
+ Improved and simplified label code.
+
+commit 892d597f69da58ba3ba5b67429e1235acb6d1afc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 22 15:06:19 2004 -0600
+
+ More label updates.
+
+commit 4659686d9b2805523740b67f193e5b3c37c7d0fa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 22 04:01:04 2004 -0600
+
+ Label updates.
+
+commit 2d7b642ffe65007488bfc592c1507b63e085aa6a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 21 02:07:25 2004 -0600
+
+ Improved label bounding boxes.
+
+commit 2ec3be9a1f88fb33e8eb9262ce8952023a3253a4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 22:00:22 2004 -0600
+
+ Account for depth in label alignment code.
+
+commit 5bdeee5c93e43828cd8aa635cb3b3569bc56e39d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 17 12:35:21 2004 -0600
+
+ Fine tuning of label offset (dependent on pdf/-B).
+
+commit 68795714227237c2a8b801c94655b17fd68aa3a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 22:17:16 2004 -0600
+
+ Increment version to 0.56cvs.
+
+commit c1848c51139c559fa78b22188ffeeca159159393
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 17:52:04 2004 -0600
+
+ Force use of bison (not yacc).
+
+commit 733caf46643c96adcf045194ace7a8e07d796740
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 17:32:16 2004 -0600
+
+ Fixed warning messages.
+
+commit 46d94ddec5bf8cae60d4fbefe41d22599cc75b8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 17:26:09 2004 -0600
+
+ ispell updates
+
+commit 16a8cb94f1d988c8c9c692d650969a41e4203f30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 17:21:08 2004 -0600
+
+ Documentation updates.
+
+commit 8d0c569a4a72ae24dfe71dea21bcb1d5ee008aa3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 17:05:14 2004 -0600
+
+ Improved latex diagnostics.
+
+commit 01c3773cac71bca3bb99dfb3f7d0b25d44d6bf7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 13:14:58 2004 -0600
+
+ Updated documentation.
+
+commit 14362d4f7e3ca6d9d0e40fab297a8ee5716ea04e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 12:45:54 2004 -0600
+
+ Contributed examples.
+
+commit 43708329adf0949d989844f64cc450b7fa7ac3e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 10:11:08 2004 -0600
+
+ Added cuttings global variable.
+
+commit 609ddb221c006700de7c30e4889adb8e7c0ed65e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 15 23:42:14 2004 -0600
+
+ Moved metapost compatibility routines to separate file.
+
+commit 9a92f1894780cec1d9534486c95e6efeb0372e3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 15 22:52:04 2004 -0600
+
+ Perhaps a more sensible alternative to Metapost cutbefore/cutafter/cuttings.
+
+commit b88706095832297bcd9e463186774609d0708e59
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 15 10:31:40 2004 -0600
+
+ updated coordinate
+
+commit ea0e02d149d6aece9779f489aad5786c6b259364
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 15 10:30:10 2004 -0600
+
+ Added translator name.
+
+commit 4bfe6a48fb575f02c0c98d856312f62620096158
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 15 10:26:31 2004 -0600
+
+ Added before(path,path) and after(path,path); documented cutbefore and
+ cutafter and changed them to work always according to these specificiations.
+
+commit 247f2c248f437b9379881e211a964ecafc232749
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 14 18:39:21 2004 -0600
+
+ Fixed bug [ 1084667 ] asydef environment.
+
+commit d4ef44de4281cca95cdb72f4dcb9922d2c4acd7f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 14 18:24:27 2004 -0600
+
+ Fixed bug [ 1084641 ] problem with defaultfontsize.
+
+commit a4e65629f8a48ea09e5e0cbbc7d062385eb1e66c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 14 13:02:12 2004 -0600
+
+ In texPreamble: replaced newlines with spaces as they can break
+ bidirectional TeX pipe.
+
+commit d6c73c7eaefcd11cb92cd75d52a30ee2d9e7651f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 13:01:12 2004 -0600
+
+ Simplified axis capping.
+
+commit fb95bf6850216bc1d903af28a9a8005853863128
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 11:30:01 2004 -0600
+
+ Fix override of axis label positioning.
+
+commit f1a5727ccfb4e9f723bf1acd11347d3fdaf79ad2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 00:55:30 2004 -0600
+
+ Fixed bug 1084016: error in bounding box computation.
+
+commit 23b64ac7a6602335900098e1640768dc0ed941f5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 12 18:05:09 2004 -0600
+
+ Partial port of featpost 3D package for MetaPost.
+
+commit 320e428228b01938b5e69ccd6b82d205ea6f52ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 12 18:04:06 2004 -0600
+
+ Added operator == and != for vector class.
+ Added interp routine for pairs, vectors, and pens.
+ Added pen background=white, unfill, cutbefore, and cutafter.
+ Documentation updates.
+
+commit 608a705714b209ca86cbf3621ac2194659ca4c99
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 12 17:59:33 2004 -0600
+
+ Changed default structure operator == to alias (as with arrays) to allow
+ user-defined == operators on structures. Also removed != in favour of !alias.
+
+commit 79a7f7cc6d694897096ad895e0ddf8efa86cb61c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 11 14:59:39 2004 -0600
+
+ Handle invalid operators cleanly.
+
+commit fdd1a3d7fa0609fdbea0b4909b6538c95e43f207
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 18:32:52 2004 -0600
+
+ Updated bug report address.
+
+commit 7a57e3d9ab684bcda09d72c5991246bb8bccbeae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 17:10:39 2004 -0600
+
+ Fixed nullpath bugs.
+
+commit 6e27209f37882761c0f6a74ae1a209a8a462baad
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 17:10:21 2004 -0600
+
+ Installation updates
+
+commit cbdb816fe0b86d3e4a7f071b15486be6429e402f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 12:17:20 2004 -0600
+
+ Make info and man directories if missing.
+
+commit f21a0af80d2556dda3c38ee9a0364330a42e2c15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 11:57:18 2004 -0600
+
+ Added missing include.
+
+commit c0e2fe27a9127d79235dcb0032dbefe077c20215
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 11:55:11 2004 -0600
+
+ Simplified configuration.
+
+commit 9496f9fa0cb6577c20b2ea25098cb0bb4fabfd0d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 9 23:32:49 2004 -0600
+
+ Documentation updates.
+
+commit 844078449f34d728658e81a22ac49dfb22239aa8
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Thu Dec 9 12:41:11 2004 -0600
+
+ Fixed tension atleast bug.
+
+commit 21a37d0bb0de1e76cebfed3b9fe787091cff8a9e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 12:32:56 2004 -0600
+
+ Improved axis label sizing.
+
+commit 57a8d747c34cd815620c43fb83f87c40c21cad04
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 12:31:11 2004 -0600
+
+ Remove signal(SIGCHLD, SIG_IGN): there are no remaining problems with
+ zombies, and it causes other problems with gv.
+
+commit 0082483b02988e1ef08d8a75006c59504bbd54fd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 11:38:47 2004 -0600
+
+ Fixed typo.
+
+commit d1d3ee0f2fcedbb0e03d2ce4e29c54c02f2dc247
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 04:26:52 2004 -0600
+
+ Increment version to 0.55cvs.
+
+commit e6ed67fbf2e30e2e96ddb7a3b974203f52d8858b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 03:19:43 2004 -0600
+
+ Fixed graph sizing routines; added legendsize routine (useful for
+ compensating for space taken up by external legend); the default width in
+ asymptote.sty is now the full line width.
+
+commit 19ff04b4ed6b980c753b803ce43a70c7d8d2a529
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 03:10:08 2004 -0600
+
+ Added missing mkdir.
+
+commit 65acc41943ca624b0459c6e7863b7f4ac002e2ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 17:07:57 2004 -0600
+
+ Center EPS figures on page by default. Added support for a4 paper as well as
+ letter.
+
+ Default postscript offset is now 0,0.
+ Option -B (-T) aligns to bottom (top) of page.
+
+commit d3b7d14ad20d9b156f56738034eef6fb5687e2ea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 15:15:09 2004 -0600
+
+ Applied Hubert Chan's installation patch for Debian.
+
+ Moved examples, asy.vim, and asy-mode.el to /usr/local/share/doc/asymptote/
+
+ asymptote/asymptote.sty is now installed in /usr/share/texmf/tex/latex/
+ (./configure --with-latex=PATH to override).
+
+ Fixed typos; updated documentation and changed documentation license
+ from GFDL to GPL in view of Debian position statement:
+ http://people.debian.org/~srivasta/Position_Statement.xhtml
+
+ Added man pages asy.1 and xasy.1x kindly provided by Hubert.
+
+commit 7d2f6d6fa49034e0598f05cac3e11ca86c509cfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 14:42:17 2004 -0600
+
+ Fixed -with-latex=PATH.
+
+commit c943ad90d0ac2f8fed5350309228bc5cc83390fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 14:03:09 2004 -0600
+
+ Added --with-latex=PATH configuration option.
+
+commit a30de76dc85ad5bf91bcb1a48798f4da3a2c81be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 00:15:57 2004 -0600
+
+ Implemented better estimate for graph axis space requirements for more
+ accurate graph sizing.
+
+ Added Portrait, Landscape, and Seascape shipout orientations.
+
+commit 2aec4bf868dc89eb7e06cc312fbf025c359ef275
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 3 12:15:14 2004 -0600
+
+ Bounding box & diagnostic tweaks.
+
+commit 285d1fe69feae78bb63d1f0381c808b51ac7db17
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 3 08:52:52 2004 -0600
+
+ Added missing header to make cxx compiler happy.
+
+commit cb5ef6cb8974e01b38d54df21cb67363faded74a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 3 08:31:00 2004 -0600
+
+ Reworked dvips and gs pdfwrite interface: do a post-bbox correction rather than
+ using dvips -E (which ignores postscript label rotation).
+
+ Align figures to top-left corner (unless the new -b option is given, in
+ which case the bottom-left corner is used), to allow for direct printing of
+ the generated EPS files. User can override default offset of 18bp.
+
+ Updated documentation.
+
+commit 81af3cccfbc4df4288150cc2610649fcd7cde843
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 3 08:23:35 2004 -0600
+
+ Adjusted label alignment.
+
+commit 4aaa2cdefca7c4e99f635baef5e613792a560889
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 12:54:48 2004 -0600
+
+ Reinstate label bounding box determination; xequals and yequals routines
+ will still work as expected if crop is called.
+
+commit 6edc66fadf3d00871d2ec0be1451af8c1fe35116
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 03:00:42 2004 -0600
+
+ Use dvips -E (encapsulation; this works now that bbox coordinates are
+ non-negative) instead of -T (pagesize) to fix compatibility problems in the
+ final postscript output. Made corresponding adjustments to printer offset code.
+
+ Added support and documentation for using Postscript viewers other than gv.
+
+ Fixed filename extension detection so that filenames containing ./ and ../
+ work correctly.
+
+commit 3a0267f4b9f5facd271d9106fe145fbfbe80bc4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 02:54:00 2004 -0600
+
+ Fixed typo.
+
+commit c09cb8a65f3eeb409285cae3c722938cf8debff0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 10:56:39 2004 -0600
+
+ Patches for bison, flex, and gv-3.5.8 now in patches directory.
+
+commit 92e5b28cd0bb6148653040bfc80d9acda90b8601
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 10:52:27 2004 -0600
+
+ Arrow and bars should always be drawn with solid linetype.
+
+commit db3c6e1299be872a321662d775e166ad9b751dd2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 30 18:50:49 2004 -0600
+
+ Changed dots(pair[]) to dot(pair[]); added graph(pair(real),real,real).
+
+commit e31faae2c7a1315c9a5de99a8599173cce784bfa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 30 15:03:29 2004 -0600
+
+ Fixed typo.
+
+commit 4bab7c466503339267efdc8e069e4f8a56a14d9e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 30 14:53:16 2004 -0600
+
+ Simplified dot drawing function, distinguished it from Dot product, and
+ updated documentation and examples.
+
+commit f9308bfd3717313c829d72d6656274cbcc2ddf00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 30 09:00:14 2004 -0600
+
+ Added array diagnostics.
+
+commit 98217e95781cfbd4e93190af5679f7ea8c783f73
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 29 02:29:29 2004 -0600
+
+ Added qualifier.
+
+commit 08f4525440924eaf85789f1dd36c47ea938bbfde
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 29 02:20:52 2004 -0600
+
+ Resolved infinite import recursion bug [24Nov04] by using libsigsegv to
+ distinguish between stack overflows and real segmentation violations
+ (due to C++ programming errors).
+
+commit 569040e16f23def486223a2f8a5f084ae76d8ea5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 28 17:22:15 2004 -0600
+
+ Deferred drawing should respect clipping bounds.
+
+commit 72ef182760c1e9578353dd694a726b762475853a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 28 16:01:11 2004 -0600
+
+ Removed obsolete label bbox code from xequals and yequals to make them work
+ correctly.
+
+commit c6b45485728c0e652cc1764479fa0c235c220fbb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 27 22:55:25 2004 -0600
+
+ Updated documentation.
+
+commit 02e65f5c0716c70809c8a95243a4cc2b2998a53b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 27 22:08:47 2004 -0600
+
+ Improved dot(): if dotsize not specified, use linewidth(pen)*dotfactor.
+
+commit d2cc042489e63ebb765ce7e6b3299e68a8ba1789
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 27 22:02:04 2004 -0600
+
+ Implement implicit cast from real to pen linewidth.
+
+commit fab6a02bf7945e31a431bc9d3a4d4cf51df44307
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 27 22:01:28 2004 -0600
+
+ Cleaned up pen code.
+
+commit 4205a65a204c8627acdd2b574c9930df98a409dd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 27 10:13:32 2004 -0600
+
+ tex() not layer() should force label processing.
+
+commit ea4fda59c7b4ff4c281379600f2b75c905fa1a30
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 26 19:23:49 2004 -0600
+
+ Increment version to 0.54.
+
+commit 21010d8460c5f1d5cc9e106592b087d92c9a7273
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 26 18:19:53 2004 -0600
+
+ Added preliminary 3d graphics routines & documentation.
+
+commit 497764f5fdbbf2012aaffc6606a0708c87309988
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 26 17:37:42 2004 -0600
+
+ Added Bug 24Nov04.
+
+commit 0b9c4a1496e99f3c592697c7d7b7b6ef6c6af41a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 26 17:01:19 2004 -0600
+
+ Fixed transform bug (yx->xy) reported by Jacques.
+
+commit c8b620eaa7f84e6ded045e55ae623dcc91db5b1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 26 13:44:02 2004 -0600
+
+ Makefile for doc directory.
+
+commit 3b421e3fab2572473a6636e6ec4fedfb1ddf09aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 26 12:58:25 2004 -0600
+
+ Math and documentation updates.
+
+commit af96406cc03aa4fe42509ded49e0c82a24861b12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 25 22:22:39 2004 -0600
+
+ Fixed intersect(vector,vector,vector,vector);
+
+commit 8dab8f056f0a2ceaa6f21956a98e451559ee8a53
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 25 13:00:37 2004 -0600
+
+ Handle out of bounds indices properly in straight(path,int).
+
+commit b19ec7c936c3fd765992e1157e491f643bf08de4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 25 10:31:25 2004 -0600
+
+ Fixed intersect(vector,vector,vector,vector).
+
+commit 131d60d368782480e5f767c0b8060b4373b0a70c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 24 23:21:41 2004 -0600
+
+ Avoid duplicate import messages when verbose > 1.
+
+commit 610c16529cea2a4ff77262c49e4404b0b4fef395
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 23 13:27:50 2004 -0600
+
+ Make layer() work also when there are no labels.
+
+commit 6fec2af78eeee9ccb6ceb6e2572ef371028bb5d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 23 12:41:35 2004 -0600
+
+ Fixed bbox function; added dot product for pairs and vectors.
+
+commit d058ed95ec698e5d29d7201f57018b166bad99f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 23 10:33:58 2004 -0600
+
+ Added missing xor boolean binary operator.
+
+commit 723d63cc3c14965550a0d4a1f8c24c0b57b9bb91
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 23 10:31:20 2004 -0600
+
+ add(picture, picture) now adjusts userMin and userMax.
+
+commit c5910e2d5349db115723dc52c67161d0a68d7621
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 17:31:02 2004 -0600
+
+ Ignore attempts to close stdin and stdout.
+
+commit 0a5e346e5552a7bc180051e67f3264c62ad9cc97
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 17:05:42 2004 -0600
+
+ Fixed nullFile.
+
+commit 8e66bee71948d945acb35aa2d573a9168a83adab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 12:19:31 2004 -0600
+
+ Simplified configuration; documented GNU_GETOPT_H.
+
+commit db7cd2366884368bf28a72e05047df64ea84fc0a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 11:41:27 2004 -0600
+
+ renamed camp::stdout to camp::Stdout to make FreeBSD happy.
+
+commit 6a4f52a0f03b9b9bf5e73358b0c39875046466d9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 11:10:22 2004 -0600
+
+ Added reference to mailing list.
+
+commit 0f135b435e70580b46aa8992faa19072c312be03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 11:05:10 2004 -0600
+
+ Removed email addresses.
+
+commit b9c2b04d177b4a8cf872be63603fc2505139f6c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 10:52:23 2004 -0600
+
+ Fixed formatting.
+
+commit 801eb67d0d9f69b0642f4a8955204aff00eb0b16
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 10:36:15 2004 -0600
+
+ updated distclean
+
+commit bc7d4f892bea91e37cd8771a74be6154324d6f68
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 02:39:36 2004 -0600
+
+ Fixed memory leaks.
+
+commit 84f8442033be2736dae165d29a711d783a13a41f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 02:03:42 2004 -0600
+
+ Fixed memory leak.
+
+commit 91ce66042763624421e9842d28ef71bc6af0e8e5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 00:29:49 2004 -0600
+
+ Readline library should be reasonably up-to-date (Version 4.3 and 5.0
+ have both been tested; asy won't even compile with very old versions).
+
+commit a9cf50c561bb4025ea970151a5b25e45e45e3425
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 00:20:56 2004 -0600
+
+ Template used to extract texinfo version from configure.ac.
+
+commit f2f566f48fcf2c153a6563726677f9a50f65469c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 00:19:58 2004 -0600
+
+ More FreeBSD tweaks.
+
+commit 1b62f5150641e6b7aca7359610d948d875aacb86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 00:19:17 2004 -0600
+
+ Revert stdout optimization.
+
+commit 7ce475cda9d27c16ff719db8a41f3cd1d23ef0b5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 21:22:59 2004 -0600
+
+ Fixed typo.
+
+commit cd879a5a3bfed30699894b2060ffd82f642e0c47
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 21:21:09 2004 -0600
+
+ make install-all now depends on all
+
+commit 5dc6a42dc07ee535bbb095baa92e704f36209337
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 19:46:41 2004 -0600
+
+ Port to FreeBSD 4.10-RELEASE-p2 with gcc34.
+
+commit a4107efb6bd1b449e1b8fcc0c63112f1da1cdea0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 15:51:57 2004 -0600
+
+ Patches for clean compilation under CXX and other compilers.
+
+commit 88d63e93cf27e0af8acd8f4c026ab709479660e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 12:51:31 2004 -0600
+
+ include tweaks
+
+commit fa8719f36c73bbca73ce75f857531e8d2db35348
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 12:00:20 2004 -0600
+
+ Menu updates.
+
+commit adc7d6279f193edad3d72a798a938214999a26c3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 11:36:52 2004 -0600
+
+ Fixed up discussion of static vs. dynamic
+
+commit f33671066cc96d5d95a098a5abe0656d9d8c5813
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 22:53:36 2004 -0600
+
+ Check if file is closed before doing any reads or writes.
+
+commit f6b7f7bc42965730d51de5c9aadf66b8d94e8075
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 22:53:29 2004 -0600
+
+ Added sentence about linetype-adjustment based on arclength of path.
+
+commit 12c0a82afdafc91e5c5170ffc4a53edf8c62f88a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 16:29:52 2004 -0600
+
+ Default width of figures included with asymptote.sty is now 0.9\linewidth.
+
+commit 878455b6e5d0c597921832e49d7136535ac13f3f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Nov 19 16:24:25 2004 -0600
+
+ *** empty log message ***
+
+commit 6eea86bfcd0adea30d3f86f77a9ede20aa1df0dc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 16:13:03 2004 -0600
+
+ Bug 2004-17-11 fixed.
+
+commit 36838d7981d3987c4e746559e0cce70a9225f95f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Nov 19 14:50:59 2004 -0600
+
+ New classes from the env -> env and coder split.
+
+commit fcb3de9fddd82fcb22fcdc53d5ba2e7bff56f08f
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Fri Nov 19 14:49:45 2004 -0600
+
+ Split the env class into env and coder, and added coenv.
+ Added "self-importing".
+
+commit 9d6ebe01c90e679a41471af70c9d7ed79c559655
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 13:29:35 2004 -0600
+
+ Figures included via asymptote.sty are now fully independent; updated documentation.
+
+commit 52cd2cc10e20913f21d2fa3584b96f5ba19a1f33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 09:18:14 2004 -0600
+
+ Remove dependency of graph.asy on math.asy;
+ added builtin real abs(pair) and int sgn(real) functions.
+
+commit 40eb013f88e09d3faee9450e4251e64815b98013
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 23:26:45 2004 -0600
+
+ Renamed includegraphics to include.
+
+commit f5364450443b6e5665eab99d3daa1702e2f74858
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 16:50:06 2004 -0600
+
+ Added BUGS file.
+
+commit 97160f4c77f2be1d111061ee47bd3e9800a245e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 14:09:11 2004 -0600
+
+ Added layer function.
+
+commit 576f5152045b83fe681e81e129b6bdcdc2405255
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 14:05:11 2004 -0600
+
+ Added layer and includegraphics functions.
+
+commit d0aac5aa876b29ac907e4979c830e9d9829f1405
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 14:04:01 2004 -0600
+
+ Added install-all target.
+
+commit 1362c4f2073bbd5f1dcc8dfadad51a44b30261ac
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 22:16:20 2004 -0600
+
+ Fixed typo.
+
+commit 985b1d486350fc6e2be207b6c718163ef11c5528
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 11:54:37 2004 -0600
+
+ Minor optimizations.
+
+commit 608bd681d814f599738c3d132afca3ceb2123012
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 23:32:01 2004 -0600
+
+ Removed unused dynamic keyword.
+
+commit 51ba77aac1c609ed242c6d68c36d3fd096f0edfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 16:25:06 2004 -0600
+
+ Fixed bug: (path) (nullpath--(0,0)--(100,0)--cycle) was missing final node.
+
+commit 418ee6a6c51185817ead6fcbc45fb02cf724ccae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 15 12:10:37 2004 -0600
+
+ Switched from jpg to png images.
+
+commit 5bac11e119d1fbffd620ee85e54819912543bded
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 15 00:23:59 2004 -0600
+
+ Make variables in file-level modules dynamic by default, like everywhere else.
+
+commit b71ff38c28b119ba7f758db7b5b0c1a775258062
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 23:52:36 2004 -0600
+
+ Support old versions of install-info.
+
+commit 31df852a681c3a7512a1f400ff160cad83201fa0
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Nov 14 20:17:32 2004 -0600
+
+ Changed error message for static vs. dynamic errors.
+
+commit b812243f2e2ec390c6d91bdba80ae5bd29055174
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 18:48:09 2004 -0600
+
+ Moved Legend[] legend inside picture structure; shipout(frame) now adds
+ gui() entries and legend; shipout always deconstructs its picture argument.
+
+commit 2f3ce72638f7345515478e7fd1239986cb7ef7bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 18:45:13 2004 -0600
+
+ Fixed compiler warning message if HAVE_LIBFFTW3 is undefined.
+
+commit d6329e24d8d9ef6fb4bced54ad2c0e0fa25f1504
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 18:43:30 2004 -0600
+
+ removed unnecessary vm:: qualifier
+
+commit ec3cc188f1f87ee29ff8fb8a03074c0afffa3680
+Author: Andy Hammerlindl <ahammerlindl@gmail.com>
+Date: Sun Nov 14 18:23:21 2004 -0600
+
+ Refactored the equivalent type function.
+
+commit 95180b35c3df1f18ee05fd66e02d1ae43d99c343
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 18:12:55 2004 -0600
+
+ Added unistd.h include.
+
+commit 47d1a0c525b4c8799b0e4443aa61949e9af32254
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 19:55:36 2004 -0600
+
+ Increment version.
+
+commit b0ed6c9b5514a5e02abfd3be9bf7ab26091169ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 16:19:44 2004 -0600
+
+ release: Version 0.52
+
+commit 616c4d1abc667a430d0768709949bebc24956790
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 15:59:54 2004 -0600
+
+ Made import graph local to each figure in latexusage.
+
+commit ba5d7f3060b087454a02bd2f7f79487ee2c4edf1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 15:03:05 2004 -0600
+
+ added call to crop
+
+commit 6a34a72588eb300f57f899f4ced21aa9b6f5d57b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 14:51:33 2004 -0600
+
+ Documentation updates
+
+commit 5470c04f907ab9f832734e96914662aed35b0c4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 12:54:34 2004 -0600
+
+ Allow qualification of variables in imported modules with (quoted)
+ nonalphanumeric names; added ISO 8859-1 support (latin1).
+
+commit 5d19c564436dd1f96d86293ec8fc9f439aa5fb94
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 01:19:36 2004 -0600
+
+ Improved xlimits, ylimits, limits routines. Added crop routine.
+
+commit 365495bb65ef64683118cede97ca47adcd56b3b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 00:18:59 2004 -0600
+
+ Fixed various graph scaling problems.
+
+commit 39820dcee67bcb5d1817c60bda996d00bc348152
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 10 11:49:27 2004 -0600
+
+ minor formatting changes
+
+commit 97ec1247f54a8a0b5357118b6734352eca9a34a0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 10 11:32:05 2004 -0600
+
+ Encapsulated global graph scaling variables within picture; updated documentation.
+
+commit 83b65356fb2a5b1f9d8c92c0762a3bc2f744fedc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 9 12:45:09 2004 -0600
+
+ fixed missing word on first page
+
+commit cd6c145e4a962015b614c18d939140d40f2b5dce
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 9 12:44:22 2004 -0600
+
+ Added dots(pair); fixed division by zero in arrowhead for degenerate paths.
+
+commit e699111cfa5bfbf41c9fb574bde171a093536809
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 9 01:55:45 2004 -0600
+
+ Increment version.
+
+commit 31c13bbe9d051c54aac6051cfda68612df499d33
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 9 00:08:08 2004 -0600
+
+ Missing description
+
+commit c62bec9c482884523ccadd379edd34f67c5e4d2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 23:54:35 2004 -0600
+
+ fixed missing @code
+
+commit d8ea0103c797070c787f5f890c4b2401690a2945
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 23:34:47 2004 -0600
+
+ moved to doc/
+
+commit 3ddefd4eff344e676e2a8a9f5e19cd32ed9aa0eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 23:28:34 2004 -0600
+
+ Fixed problems with installation of base files from cvs.
+
+commit da8c687ac5ec2be2c818d84c9e97e723f485a26a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 23:10:40 2004 -0600
+
+ updated cvsignore entries
+
+commit dba6643b3b853fce3f2de5e41e47ed8b71cf099b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 22:50:37 2004 -0600
+
+ Added optimization flags.
+
+commit 0436f92dcb74953fc3bb748230e5a29d0730fd1d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 22:50:04 2004 -0600
+
+ Added optimization flags.
+
+commit db450befc0d01549b9c53af8fc5646c6d110d574
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 22:37:03 2004 -0600
+
+ Added instructions for asy-mode.el and asy.vim.
+
+commit a0e9333119818dc1592791a5078676cae36eca2c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 18:48:55 2004 -0600
+
+ unicode updates
+
+commit d0f20f5cfc0e9d958ab4a0793e1e0cccbec31d65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 13:18:05 2004 -0600
+
+ Corrected local value of ASYMPTOTE_DIR
+
+commit b3857ef4fae8c20e1fbc4852c302fc44a1988cc2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 12:22:32 2004 -0600
+
+ Fixed warning messages.
+
+commit 2adbb10378f06aecb049da9b6da02ed9b23bd0fb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 12:11:03 2004 -0600
+
+ Update cvs version
+
+commit a83b4974fc41dde098be1a222b4240ce0ea8feaa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 12:06:53 2004 -0600
+
+ Asymptote logo
+
+commit b345871de175eed69610a6ac96996f67b1c07a8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 12:03:15 2004 -0600
+
+ Updated README and URL.
+
+commit 5c97b1a8b45f7ba5370f381ee53e948353a7daba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:52:02 2004 -0600
+
+ Example of latex usage.
+
+commit d71e3c7017fa75e11f4c0228caf1123553006cda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:39:13 2004 -0600
+
+ displayed equation example
+
+commit 7021ba702776cc5e337025f1625803e4067d376d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:35:58 2004 -0600
+
+ updates to localwords
+
+commit d4199ebd8601704b3e1e0b6f54d1fcdf3430b478
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:31:39 2004 -0600
+
+ typo fixed
+
+commit 377185edb2c7dca51b3b3f00504e72d065495b97
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:28:23 2004 -0600
+
+ Final documentation updates.
+
+commit 50806de05e5b6c19b0df9345e278c8259ebafeb0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:23:09 2004 -0600
+
+ make install-man no longer does a make man
+
+commit c751286c5070b8f4e40909cbf54bdc7266a49982
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:21:30 2004 -0600
+
+ Final tweaks before release.
+
+commit d113158cdd9b36e3c45a4db4d39dbc2b91144aa1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 00:24:38 2004 -0600
+
+ Updates to facilitate building info pages and figures.
+
+commit c3d8c3b7da2f6ceb84900a4e26618e8533092b08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 00:23:30 2004 -0600
+
+ Updated documentation.
+
+commit eef5bb1c1657e77885799591cf982d1dbd6ab608
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 23:22:17 2004 -0600
+
+ Updated documentation
+
+commit d09249b9dfed161600e6c1aa332721b9e8b0c6c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 23:05:05 2004 -0600
+
+ Fixed interactive mode.
+
+commit 93a889f31435adc3851b081cd0709f55e2031688
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 17:02:25 2004 -0600
+
+ Example of multiple data graphs with secondary axis.
+
+commit 87cef6cf1df4f16b971dc52eb4f5c52d39d49e9b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 16:32:44 2004 -0600
+
+ Fixed menus.
+
+commit 5a97218e8c5371f76d23d0304e8336dc62f07f79
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 16:31:19 2004 -0600
+
+ Added a reset() function to restore settings to startup defaults.
+
+commit 2c124d11951789640019cdb62fb9062f22700db2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 16:28:30 2004 -0600
+
+ Formatting of comments.
+
+commit 048da481e7e14b7d937a8db3e2349212c5864163
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 16:27:32 2004 -0600
+
+ Documentation updates.
+
+commit 0b26fa75ab89038ac2950312e78b95e68641205e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 7 01:08:29 2004 -0600
+
+ Added missing functions; removed pt from plain.asy; updated documentation
+
+commit 7803748c35eb80c46c1175517f31fb20cfc7ece7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 5 11:16:40 2004 -0600
+
+ Added GNU public LICENSE.
+
+commit 2b333b9b4907b6c2a9200e8ddc89b9a09d7d0e66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 5 11:13:47 2004 -0600
+
+ Documentation updates.
+
+commit 45357092d3ebf51f9b0c7d82e1a05610abf5f565
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 5 00:37:35 2004 -0600
+
+ Updated documentation.
+
+commit 82153ab432256c8e32d48ffc98e12b2bf41a7576
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 4 00:45:40 2004 -0600
+
+ Documentation updates.
+
+commit c9dd522eca27b074b3f04f5f2799e02c2adb7933
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 2 23:20:51 2004 -0600
+
+ Allow negative array indices in arrayIntArray as in arrayRead and arrayWrite.
+
+commit fec561b75b55c779d89eca9c9ea6dce758df8eb1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 2 23:13:26 2004 -0600
+
+ Allow assignment to array indices [-len,-1];
+ handle negative array indices in sequence routines.
+
+commit 962962b19d4ce3af442a461f5051f3eb856bd299
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 2 13:10:24 2004 -0600
+
+ Added missing pen transformation code.
+
+commit d3e2ac4b4a0af6bdeaee28bb5742844928f24026
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 1 11:23:54 2004 -0600
+
+ minor updates
+
+commit a1457afb992cf18a85a8cce07ff9306cae5a282f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 31 23:27:35 2004 -0600
+
+ Check for boost header files; updated documentation.
+
+commit fab31bbeb056e157742e94531443b8b82218d465
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 28 23:04:37 2004 -0600
+
+ Updated documentation.
+
+commit 7b66b69511f9b742bcc674e47101a71e9b670326
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 28 23:04:20 2004 -0600
+
+ Make -O work when dvips isn't used.
+
+commit 873b67e55dfad98287e13941e79984c0e64d688a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 28 15:26:57 2004 -0600
+
+ Sean Healy's logo implemented in Asymptote.
+
+commit 83660c66186bfc76ccdc858aafda6ab89d05cd08
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 26 09:05:04 2004 -0600
+
+ Initial version.
+
+commit 23e61146aa827a5faa4b94fa47506277a365005b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 26 07:38:06 2004 -0600
+
+ Removed unwanted cvs files.
+
+commit 35fdf59891ddb8786fe964d9f945f995088680cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 26 07:31:01 2004 -0600
+
+ Set version = 0.50.
+
+commit b0bf033492246c01f5262a7ec4a44255675127d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 26 07:29:34 2004 -0600
+
+ Fixed warning message if HAVE_STRTIME == 0
+
+commit c4702ee14e622bba47870ced5e25270f550d7c0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 26 07:27:12 2004 -0600
+
+ Initial revision.
+
+ [[This repository was converted from Subversion to git on 2015-07-27 by
+ Jesse Frohlich <jesse.frohlich@ualberta.ca>. Junk commits generated by
+ cvs2svn have been removed and commit references have been mapped into a
+ uniform VCS-independent syntax.]]
diff --git a/graphics/asymptote/Delaunay.cc b/graphics/asymptote/Delaunay.cc
new file mode 100644
index 0000000000..3e9e5507f2
--- /dev/null
+++ b/graphics/asymptote/Delaunay.cc
@@ -0,0 +1,212 @@
+// Robust version of Gilles Dumoulin's C++ port of Paul Bourke's
+// triangulation code available from
+// http://astronomy.swin.edu.au/~pbourke/papers/triangulate
+// Used with permission of Paul Bourke.
+// Segmentation fault and numerical robustness improvements by John C. Bowman
+
+#include <cassert>
+#include "Delaunay.h"
+#include "predicates.h"
+
+inline double max(double a, double b)
+{
+ return (a > b) ? a : b;
+}
+
+int XYZCompare(const void *v1, const void *v2)
+{
+ double x1=((XYZ*)v1)->p[0];
+ double x2=((XYZ*)v2)->p[0];
+ if(x1 < x2)
+ return(-1);
+ else if(x1 > x2)
+ return(1);
+ else
+ return(0);
+}
+
+inline double hypot2(double *x)
+{
+ return x[0]*x[0]+x[1]*x[1];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Triangulate():
+// Triangulation subroutine
+// Takes as input NV vertices in array pxyz
+// Returned is a list of ntri triangular faces in the array v
+// These triangles are arranged in a consistent clockwise order.
+// The triangle array v should be allocated to 4 * nv
+// The vertex array pxyz must be big enough to hold 3 additional points.
+// By default, the array pxyz is automatically presorted and postsorted.
+///////////////////////////////////////////////////////////////////////////////
+
+Int Triangulate(Int nv, XYZ pxyz[], ITRIANGLE v[], Int &ntri,
+ bool presort, bool postsort)
+{
+ Int emax = 200;
+
+ if(presort) qsort(pxyz,nv,sizeof(XYZ),XYZCompare);
+ else postsort=false;
+
+/* Allocate memory for the completeness list, flag for each triangle */
+ Int trimax = 4 * nv;
+ Int *complete = new Int[trimax];
+/* Allocate memory for the edge list */
+ IEDGE *edges = new IEDGE[emax];
+/*
+ Find the maximum and minimum vertex bounds.
+ This is to allow calculation of the bounding triangle
+*/
+ double xmin = pxyz[0].p[0];
+ double ymin = pxyz[0].p[1];
+ double xmax = xmin;
+ double ymax = ymin;
+ for(Int i = 1; i < nv; i++) {
+ XYZ *pxyzi=pxyz+i;
+ double x=pxyzi->p[0];
+ double y=pxyzi->p[1];
+ if (x < xmin) xmin = x;
+ if (x > xmax) xmax = x;
+ if (y < ymin) ymin = y;
+ if (y > ymax) ymax = y;
+ }
+ double dx = xmax - xmin;
+ double dy = ymax - ymin;
+/*
+ Set up the supertriangle.
+ This is a triangle which encompasses all the sample points.
+ The supertriangle coordinates are added to the end of the
+ vertex list. The supertriangle is the first triangle in
+ the triangle list.
+*/
+ static const double margin=0.01;
+ double xmargin=margin*dx;
+ double ymargin=margin*dy;
+ pxyz[nv+0].p[0] = xmin-xmargin;
+ pxyz[nv+0].p[1] = ymin-ymargin;
+ pxyz[nv+1].p[0] = xmin-xmargin;
+ pxyz[nv+1].p[1] = ymax+ymargin+dx;
+ pxyz[nv+2].p[0] = xmax+xmargin+dy;
+ pxyz[nv+2].p[1] = ymin-ymargin;
+ v->p1 = nv;
+ v->p2 = nv+1;
+ v->p3 = nv+2;
+ complete[0] = false;
+ ntri = 1;
+/*
+ Include each point one at a time into the existing mesh
+*/
+ for(Int i = 0; i < nv; i++) {
+ Int nedge = 0;
+ double *d=pxyz[i].p;
+/*
+ Set up the edge buffer.
+ If the point d lies inside the circumcircle then the
+ three edges of that triangle are added to the edge buffer
+ and that triangle is removed.
+*/
+ for(Int j = 0; j < ntri; j++) {
+ if(complete[j])
+ continue;
+ ITRIANGLE *vj=v+j;
+
+ double *a=pxyz[vj->p1].p;
+ double *b=pxyz[vj->p2].p;
+ double *c=pxyz[vj->p3].p;
+
+ if(incircle(a,b,c,d) <= 0.0) { // Point d is inside or on circumcircle
+/* Check that we haven't exceeded the edge list size */
+ if(nedge + 3 >= emax) {
+ emax += 100;
+ IEDGE *p_EdgeTemp = new IEDGE[emax];
+ for (Int i = 0; i < nedge; i++) {
+ p_EdgeTemp[i] = edges[i];
+ }
+ delete[] edges;
+ edges = p_EdgeTemp;
+ }
+ ITRIANGLE *vj=v+j;
+ Int p1=vj->p1;
+ Int p2=vj->p2;
+ Int p3=vj->p3;
+ edges[nedge].p1 = p1;
+ edges[nedge].p2 = p2;
+ edges[++nedge].p1 = p2;
+ edges[nedge].p2 = p3;
+ edges[++nedge].p1 = p3;
+ edges[nedge].p2 = p1;
+ ++nedge;
+ ntri--;
+ v[j] = v[ntri];
+ complete[j] = complete[ntri];
+ j--;
+ } else {
+ double A=hypot2(a);
+ double B=hypot2(b);
+ double C=hypot2(c);
+ double a0=orient2d(a,b,c);
+ // Is d[0] > xc+r for circumcircle abc of radius r about (xc,yc)?
+ if(d[0]*a0 < 0.5*orient2d(A,a[1],B,b[1],C,c[1]))
+ complete[j]=
+ incircle(a[0]*a0,a[1]*a0,b[0]*a0,b[1]*a0,c[0]*a0,c[1]*a0,
+ d[0]*a0,0.5*orient2d(a[0],A,b[0],B,c[0],C)) > 0.0;
+ }
+ }
+/*
+ Tag multiple edges
+ Note: if all triangles are specified anticlockwise then all
+ interior edges are opposite pointing in direction.
+*/
+ for(Int j = 0; j < nedge - 1; j++) {
+ for(Int k = j + 1; k < nedge; k++) {
+ if((edges[j].p1 == edges[k].p2) && (edges[j].p2 == edges[k].p1)) {
+ edges[j].p1 = -1;
+ edges[j].p2 = -1;
+ edges[k].p1 = -1;
+ edges[k].p2 = -1;
+ }
+ }
+ }
+/*
+ Form new triangles for the current point
+ Skipping over any tagged edges.
+ All edges are arranged in clockwise order.
+*/
+ for(Int j = 0; j < nedge; j++) {
+ if(edges[j].p1 < 0 || edges[j].p2 < 0)
+ continue;
+ v[ntri].p1 = edges[j].p1;
+ v[ntri].p2 = edges[j].p2;
+ v[ntri].p3 = i;
+ complete[ntri] = false;
+ ntri++;
+ assert(ntri < trimax);
+ }
+ }
+/*
+ Remove triangles with supertriangle vertices
+ These are triangles which have a vertex number greater than nv
+*/
+ for(Int i = 0; i < ntri; i++) {
+ ITRIANGLE *vi=v+i;
+ if(vi->p1 >= nv || vi->p2 >= nv || vi->p3 >= nv) {
+ ntri--;
+ *vi = v[ntri];
+ i--;
+ }
+ }
+ delete[] edges;
+ delete[] complete;
+
+ if(postsort) {
+ for(Int i = 0; i < ntri; i++) {
+ ITRIANGLE *vi=v+i;
+ vi->p1=pxyz[vi->p1].i;
+ vi->p2=pxyz[vi->p2].i;
+ vi->p3=pxyz[vi->p3].i;
+ }
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/Delaunay.h b/graphics/asymptote/Delaunay.h
new file mode 100644
index 0000000000..bc68565ef8
--- /dev/null
+++ b/graphics/asymptote/Delaunay.h
@@ -0,0 +1,29 @@
+#ifndef DELAUNAY_H
+#define DELAUNAY_H
+
+#include <iostream>
+#include <cstdlib>
+#include <cmath>
+#include <cfloat>
+
+#include "common.h"
+
+struct ITRIANGLE{
+ Int p1, p2, p3;
+};
+
+struct IEDGE{
+ Int p1, p2;
+};
+
+struct XYZ{
+ double p[2]; // {x,y}
+ Int i;
+};
+
+Int Triangulate(Int nv, XYZ pxyz[], ITRIANGLE v[], Int &ntri,
+ bool presort=true, bool postsort=true);
+
+#endif
+
+
diff --git a/graphics/asymptote/EnvVarUpdate.nsh b/graphics/asymptote/EnvVarUpdate.nsh
new file mode 100755
index 0000000000..839d6a0206
--- /dev/null
+++ b/graphics/asymptote/EnvVarUpdate.nsh
@@ -0,0 +1,327 @@
+/**
+ * EnvVarUpdate.nsh
+ * : Environmental Variables: append, prepend, and remove entries
+ *
+ * WARNING: If you use StrFunc.nsh header then include it before this file
+ * with all required definitions. This is to avoid conflicts
+ *
+ * Usage:
+ * ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString"
+ *
+ * Credits:
+ * Version 1.0
+ * * Cal Turney (turnec2)
+ * * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this
+ * function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar,
+ * WriteEnvStr, and un.DeleteEnvStr
+ * * Diego Pedroso (deguix) for StrTok
+ * * Kevin English (kenglish_hi) for StrContains
+ * * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry
+ * (dandaman32) for StrReplace
+ *
+ * Version 1.1 (compatibility with StrFunc.nsh)
+ * * techtonik
+ *
+ * http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries
+ *
+ */
+
+
+!ifndef ENVVARUPDATE_FUNCTION
+!define ENVVARUPDATE_FUNCTION
+!verbose push
+!verbose 3
+!include "LogicLib.nsh"
+!include "WinMessages.NSH"
+!include "StrFunc.nsh"
+
+; ---- Fix for conflict if StrFunc.nsh is already includes in main file -----------------------
+!macro _IncludeStrFunction StrFuncName
+ !ifndef ${StrFuncName}_INCLUDED
+ ${${StrFuncName}}
+ !endif
+ !ifndef Un${StrFuncName}_INCLUDED
+ ${Un${StrFuncName}}
+ !endif
+ !define un.${StrFuncName} "${Un${StrFuncName}}"
+!macroend
+
+!insertmacro _IncludeStrFunction StrTok
+!insertmacro _IncludeStrFunction StrStr
+!insertmacro _IncludeStrFunction StrRep
+
+; ---------------------------------- Macro Definitions ----------------------------------------
+!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
+ Push "${EnvVarName}"
+ Push "${Action}"
+ Push "${RegLoc}"
+ Push "${PathString}"
+ Call EnvVarUpdate
+ Pop "${ResultVar}"
+!macroend
+!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"'
+
+!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
+ Push "${EnvVarName}"
+ Push "${Action}"
+ Push "${RegLoc}"
+ Push "${PathString}"
+ Call un.EnvVarUpdate
+ Pop "${ResultVar}"
+!macroend
+!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"'
+; ---------------------------------- Macro Definitions end-------------------------------------
+
+;----------------------------------- EnvVarUpdate start----------------------------------------
+!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+!define hkcu_current_user 'HKCU "Environment"'
+
+!macro EnvVarUpdate UN
+
+Function ${UN}EnvVarUpdate
+
+ Push $0
+ Exch 4
+ Exch $1
+ Exch 3
+ Exch $2
+ Exch 2
+ Exch $3
+ Exch
+ Exch $4
+ Push $5
+ Push $6
+ Push $7
+ Push $8
+ Push $9
+ Push $R0
+
+ /* After this point:
+ -------------------------
+ $0 = ResultVar (returned)
+ $1 = EnvVarName (input)
+ $2 = Action (input)
+ $3 = RegLoc (input)
+ $4 = PathString (input)
+ $5 = Orig EnvVar (read from registry)
+ $6 = Len of $0 (temp)
+ $7 = tempstr1 (temp)
+ $8 = Entry counter (temp)
+ $9 = tempstr2 (temp)
+ $R0 = tempChar (temp) */
+
+ ; Step 1: Read contents of EnvVarName from RegLoc
+ ;
+ ; Check for empty EnvVarName
+ ${If} $1 == ""
+ SetErrors
+ DetailPrint "ERROR: EnvVarName is blank"
+ Goto EnvVarUpdate_Restore_Vars
+ ${EndIf}
+
+ ; Check for valid Action
+ ${If} $2 != "A"
+ ${AndIf} $2 != "P"
+ ${AndIf} $2 != "R"
+ SetErrors
+ DetailPrint "ERROR: Invalid Action - must be A, P, or R"
+ Goto EnvVarUpdate_Restore_Vars
+ ${EndIf}
+
+ ${If} $3 == HKLM
+ ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5
+ ${ElseIf} $3 == HKCU
+ ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5
+ ${Else}
+ SetErrors
+ DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"'
+ Goto EnvVarUpdate_Restore_Vars
+ ${EndIf}
+
+ ; Check for empty PathString
+ ${If} $4 == ""
+ SetErrors
+ DetailPrint "ERROR: PathString is blank"
+ Goto EnvVarUpdate_Restore_Vars
+ ${EndIf}
+
+ ; Make sure we've got some work to do
+ ${If} $5 == ""
+ ${AndIf} $2 == "R"
+ SetErrors
+ DetailPrint "$1 is empty - Nothing to remove"
+ Goto EnvVarUpdate_Restore_Vars
+ ${EndIf}
+
+ ; Step 2: Scrub EnvVar
+ ;
+ StrCpy $0 $5 ; Copy the contents to $0
+ ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or
+ ; after the last one are not removed here but instead in Step 3)
+ ${If} $0 != "" ; If EnvVar is not empty ...
+ ${Do}
+ ${${UN}StrStr} $7 $0 " ;"
+ ${If} $7 == ""
+ ${ExitDo}
+ ${EndIf}
+ ${${UN}StrRep} $0 $0 " ;" ";" ; Remove '<space>;'
+ ${Loop}
+ ${Do}
+ ${${UN}StrStr} $7 $0 "; "
+ ${If} $7 == ""
+ ${ExitDo}
+ ${EndIf}
+ ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';<space>'
+ ${Loop}
+ ${Do}
+ ${${UN}StrStr} $7 $0 ";;"
+ ${If} $7 == ""
+ ${ExitDo}
+ ${EndIf}
+ ${${UN}StrRep} $0 $0 ";;" ";"
+ ${Loop}
+
+ ; Remove a leading or trailing semicolon from EnvVar
+ StrCpy $7 $0 1 0
+ ${If} $7 == ";"
+ StrCpy $0 $0 "" 1 ; Change ';<EnvVar>' to '<EnvVar>'
+ ${EndIf}
+ StrLen $6 $0
+ IntOp $6 $6 - 1
+ StrCpy $7 $0 1 $6
+ ${If} $7 == ";"
+ StrCpy $0 $0 $6 ; Change ';<EnvVar>' to '<EnvVar>'
+ ${EndIf}
+ ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug
+ ${EndIf}
+
+ /* Step 3. Remove all instances of the target path/string (even if "A" or "P")
+ $6 = bool flag (1 = found and removed PathString)
+ $7 = a string (e.g. path) delimited by semicolon(s)
+ $8 = entry counter starting at 0
+ $9 = copy of $0
+ $R0 = tempChar */
+
+ ${If} $5 != "" ; If EnvVar is not empty ...
+ StrCpy $9 $0
+ StrCpy $0 ""
+ StrCpy $8 0
+ StrCpy $6 0
+
+ ${Do}
+ ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter
+
+ ${If} $7 == "" ; If we've run out of entries,
+ ${ExitDo} ; were done
+ ${EndIf} ;
+
+ ; Remove leading and trailing spaces from this entry (critical step for Action=Remove)
+ ${Do}
+ StrCpy $R0 $7 1
+ ${If} $R0 != " "
+ ${ExitDo}
+ ${EndIf}
+ StrCpy $7 $7 "" 1 ; Remove leading space
+ ${Loop}
+ ${Do}
+ StrCpy $R0 $7 1 -1
+ ${If} $R0 != " "
+ ${ExitDo}
+ ${EndIf}
+ StrCpy $7 $7 -1 ; Remove trailing space
+ ${Loop}
+ ${If} $7 == $4 ; If string matches, remove it by not appending it
+ StrCpy $6 1 ; Set 'found' flag
+ ${ElseIf} $7 != $4 ; If string does NOT match
+ ${AndIf} $0 == "" ; and the 1st string being added to $0,
+ StrCpy $0 $7 ; copy it to $0 without a prepended semicolon
+ ${ElseIf} $7 != $4 ; If string does NOT match
+ ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0,
+ StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon
+ ${EndIf} ;
+
+ IntOp $8 $8 + 1 ; Bump counter
+ ${Loop} ; Check for duplicates until we run out of paths
+ ${EndIf}
+
+ ; Step 4: Perform the requested Action
+ ;
+ ${If} $2 != "R" ; If Append or Prepend
+ ${If} $6 == 1 ; And if we found the target
+ DetailPrint "Target is already present in $1. It will be removed and"
+ ${EndIf}
+ ${If} $0 == "" ; If EnvVar is (now) empty
+ StrCpy $0 $4 ; just copy PathString to EnvVar
+ ${If} $6 == 0 ; If found flag is either 0
+ ${OrIf} $6 == "" ; or blank (if EnvVarName is empty)
+ DetailPrint "$1 was empty and has been updated with the target"
+ ${EndIf}
+ ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty),
+ StrCpy $0 $0;$4 ; append PathString
+ ${If} $6 == 1
+ DetailPrint "appended to $1"
+ ${Else}
+ DetailPrint "Target was appended to $1"
+ ${EndIf}
+ ${Else} ; If Prepend (and EnvVar is not empty),
+ StrCpy $0 $4;$0 ; prepend PathString
+ ${If} $6 == 1
+ DetailPrint "prepended to $1"
+ ${Else}
+ DetailPrint "Target was prepended to $1"
+ ${EndIf}
+ ${EndIf}
+ ${Else} ; If Action = Remove
+ ${If} $6 == 1 ; and we found the target
+ DetailPrint "Target was found and removed from $1"
+ ${Else}
+ DetailPrint "Target was NOT found in $1 (nothing to remove)"
+ ${EndIf}
+ ${If} $0 == ""
+ DetailPrint "$1 is now empty"
+ ${EndIf}
+ ${EndIf}
+
+ ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change
+ ;
+ ClearErrors
+ ${If} $3 == HKLM
+ WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section
+ ${ElseIf} $3 == HKCU
+ WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section
+ ${EndIf}
+
+ IfErrors 0 +4
+ MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3"
+ DetailPrint "Could not write updated $1 to $3"
+ Goto EnvVarUpdate_Restore_Vars
+
+ ; "Export" our change
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+ EnvVarUpdate_Restore_Vars:
+ ;
+ ; Restore the user's variables and return ResultVar
+ Pop $R0
+ Pop $9
+ Pop $8
+ Pop $7
+ Pop $6
+ Pop $5
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Push $0 ; Push my $0 (ResultVar)
+ Exch
+ Pop $0 ; Restore his $0
+
+FunctionEnd
+
+!macroend ; EnvVarUpdate UN
+!insertmacro EnvVarUpdate ""
+!insertmacro EnvVarUpdate "un."
+;----------------------------------- EnvVarUpdate end----------------------------------------
+
+!verbose pop
+!endif
diff --git a/graphics/asymptote/GL/glew.c b/graphics/asymptote/GL/glew.c
new file mode 100644
index 0000000000..18a2853da0
--- /dev/null
+++ b/graphics/asymptote/GL/glew.c
@@ -0,0 +1,28581 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2008-2017, Nigel Stewart <nigels[]users sourceforge net>
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef GLEW_INCLUDE
+#include <GL/glew.h>
+#else
+#include GLEW_INCLUDE
+#endif
+
+#if defined(GLEW_OSMESA)
+# define GLAPI extern
+# include <GL/osmesa.h>
+#elif defined(GLEW_EGL)
+# include <GL/eglew.h>
+#elif defined(_WIN32)
+/*
+ * If NOGDI is defined, wingdi.h won't be included by windows.h, and thus
+ * wglGetProcAddress won't be declared. It will instead be implicitly declared,
+ * potentially incorrectly, which we don't want.
+ */
+# if defined(NOGDI)
+# undef NOGDI
+# endif
+# include <GL/wglew.h>
+#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX))
+# include <GL/glxew.h>
+#endif
+
+#include <stddef.h> /* For size_t */
+
+#if defined(GLEW_EGL)
+#elif defined(GLEW_REGAL)
+
+/* In GLEW_REGAL mode we call direcly into the linked
+ libRegal.so glGetProcAddressREGAL for looking up
+ the GL function pointers. */
+
+# undef glGetProcAddressREGAL
+# ifdef WIN32
+extern void * __stdcall glGetProcAddressREGAL(const GLchar *name);
+static void * (__stdcall * regalGetProcAddress) (const GLchar *) = glGetProcAddressREGAL;
+# else
+extern void * glGetProcAddressREGAL(const GLchar *name);
+static void * (*regalGetProcAddress) (const GLchar *) = glGetProcAddressREGAL;
+# endif
+# define glGetProcAddressREGAL GLEW_GET_FUN(__glewGetProcAddressREGAL)
+
+#elif defined(__sgi) || defined (__sun) || defined(__HAIKU__) || defined(GLEW_APPLE_GLX)
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void* dlGetProcAddress (const GLubyte* name)
+{
+ static void* h = NULL;
+ static void* gpa;
+
+ if (h == NULL)
+ {
+ if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL;
+ gpa = dlsym(h, "glXGetProcAddress");
+ }
+
+ if (gpa != NULL)
+ return ((void*(*)(const GLubyte*))gpa)(name);
+ else
+ return dlsym(h, (const char*)name);
+}
+#endif /* __sgi || __sun || GLEW_APPLE_GLX */
+
+#if defined(__APPLE__)
+#include <stdlib.h>
+#include <string.h>
+#include <AvailabilityMacros.h>
+
+#ifdef MAC_OS_X_VERSION_10_3
+
+#include <dlfcn.h>
+
+void* NSGLGetProcAddress (const GLubyte *name)
+{
+ static void* image = NULL;
+ void* addr;
+ if (NULL == image)
+ {
+ image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
+ }
+ if( !image ) return NULL;
+ addr = dlsym(image, (const char*)name);
+ if( addr ) return addr;
+#ifdef GLEW_APPLE_GLX
+ return dlGetProcAddress( name ); // try next for glx symbols
+#else
+ return NULL;
+#endif
+}
+#else
+
+#include <mach-o/dyld.h>
+
+void* NSGLGetProcAddress (const GLubyte *name)
+{
+ static const struct mach_header* image = NULL;
+ NSSymbol symbol;
+ char* symbolName;
+ if (NULL == image)
+ {
+ image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+ }
+ /* prepend a '_' for the Unix C symbol mangling convention */
+ symbolName = malloc(strlen((const char*)name) + 2);
+ strcpy(symbolName+1, (const char*)name);
+ symbolName[0] = '_';
+ symbol = NULL;
+ /* if (NSIsSymbolNameDefined(symbolName))
+ symbol = NSLookupAndBindSymbol(symbolName); */
+ symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL;
+ free(symbolName);
+ if( symbol ) return NSAddressOfSymbol(symbol);
+#ifdef GLEW_APPLE_GLX
+ return dlGetProcAddress( name ); // try next for glx symbols
+#else
+ return NULL;
+#endif
+}
+#endif /* MAC_OS_X_VERSION_10_3 */
+#endif /* __APPLE__ */
+
+/*
+ * Define glewGetProcAddress.
+ */
+#if defined(GLEW_REGAL)
+# define glewGetProcAddress(name) regalGetProcAddress((const GLchar *)name)
+#elif defined(GLEW_OSMESA)
+# define glewGetProcAddress(name) OSMesaGetProcAddress((const char *)name)
+#elif defined(GLEW_EGL)
+# define glewGetProcAddress(name) eglGetProcAddress((const char *)name)
+#elif defined(_WIN32)
+# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name)
+#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX)
+# define glewGetProcAddress(name) NSGLGetProcAddress(name)
+#elif defined(__sgi) || defined(__sun) || defined(__HAIKU__)
+# define glewGetProcAddress(name) dlGetProcAddress(name)
+#elif defined(__ANDROID__)
+# define glewGetProcAddress(name) NULL /* TODO */
+#elif defined(__native_client__)
+# define glewGetProcAddress(name) NULL /* TODO */
+#else /* __linux */
+# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name)
+#endif
+
+/*
+ * Redefine GLEW_GET_VAR etc without const cast
+ */
+
+#undef GLEW_GET_VAR
+# define GLEW_GET_VAR(x) (x)
+
+#ifdef WGLEW_GET_VAR
+# undef WGLEW_GET_VAR
+# define WGLEW_GET_VAR(x) (x)
+#endif /* WGLEW_GET_VAR */
+
+#ifdef GLXEW_GET_VAR
+# undef GLXEW_GET_VAR
+# define GLXEW_GET_VAR(x) (x)
+#endif /* GLXEW_GET_VAR */
+
+#ifdef EGLEW_GET_VAR
+# undef EGLEW_GET_VAR
+# define EGLEW_GET_VAR(x) (x)
+#endif /* EGLEW_GET_VAR */
+
+/*
+ * GLEW, just like OpenGL or GLU, does not rely on the standard C library.
+ * These functions implement the functionality required in this file.
+ */
+
+static GLuint _glewStrLen (const GLubyte* s)
+{
+ GLuint i=0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0') i++;
+ return i;
+}
+
+static GLuint _glewStrCLen (const GLubyte* s, GLubyte c)
+{
+ GLuint i=0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0' && s[i] != c) i++;
+ return i;
+}
+
+static GLuint _glewStrCopy(char *d, const char *s, char c)
+{
+ GLuint i=0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0' && s[i] != c) { d[i] = s[i]; i++; }
+ d[i] = '\0';
+ return i;
+}
+
+#if !defined(GLEW_OSMESA)
+#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
+static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n)
+{
+ GLuint i=0;
+ if(a == NULL || b == NULL)
+ return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE;
+ while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++;
+ return i == n ? GL_TRUE : GL_FALSE;
+}
+#endif
+#endif
+
+static GLboolean _glewStrSame1 (const GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb)
+{
+ while (*na > 0 && (**a == ' ' || **a == '\n' || **a == '\r' || **a == '\t'))
+ {
+ (*a)++;
+ (*na)--;
+ }
+ if(*na >= nb)
+ {
+ GLuint i=0;
+ while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++;
+ if(i == nb)
+ {
+ *a = *a + nb;
+ *na = *na - nb;
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+}
+
+static GLboolean _glewStrSame2 (const GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb)
+{
+ if(*na >= nb)
+ {
+ GLuint i=0;
+ while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++;
+ if(i == nb)
+ {
+ *a = *a + nb;
+ *na = *na - nb;
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+}
+
+static GLboolean _glewStrSame3 (const GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb)
+{
+ if(*na >= nb)
+ {
+ GLuint i=0;
+ while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++;
+ if (i == nb && (*na == nb || (*a)[i] == ' ' || (*a)[i] == '\n' || (*a)[i] == '\r' || (*a)[i] == '\t'))
+ {
+ *a = *a + nb;
+ *na = *na - nb;
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+}
+
+/*
+ * Search for name in the extensions string. Use of strstr()
+ * is not sufficient because extension names can be prefixes of
+ * other extension names. Could use strtok() but the constant
+ * string returned by glGetString might be in read-only memory.
+ */
+#if !defined(GLEW_OSMESA)
+#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
+static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, const GLubyte *end)
+{
+ const GLubyte* p;
+ GLuint len = _glewStrLen((const GLubyte*)name);
+ p = start;
+ while (p < end)
+ {
+ GLuint n = _glewStrCLen(p, ' ');
+ if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE;
+ p += n+1;
+ }
+ return GL_FALSE;
+}
+#endif
+#endif
+
+PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL;
+PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL;
+PFNGLTEXIMAGE3DPROC __glewTexImage3D = NULL;
+PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D = NULL;
+
+PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL;
+PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture = NULL;
+PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D = NULL;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D = NULL;
+PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D = NULL;
+PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage = NULL;
+PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd = NULL;
+PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf = NULL;
+PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd = NULL;
+PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf = NULL;
+PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d = NULL;
+PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv = NULL;
+PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f = NULL;
+PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv = NULL;
+PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i = NULL;
+PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv = NULL;
+PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s = NULL;
+PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv = NULL;
+PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d = NULL;
+PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv = NULL;
+PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f = NULL;
+PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv = NULL;
+PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i = NULL;
+PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv = NULL;
+PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s = NULL;
+PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv = NULL;
+PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d = NULL;
+PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv = NULL;
+PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f = NULL;
+PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv = NULL;
+PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i = NULL;
+PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv = NULL;
+PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s = NULL;
+PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv = NULL;
+PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d = NULL;
+PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv = NULL;
+PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f = NULL;
+PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv = NULL;
+PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i = NULL;
+PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv = NULL;
+PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s = NULL;
+PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv = NULL;
+PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage = NULL;
+
+PFNGLBLENDCOLORPROC __glewBlendColor = NULL;
+PFNGLBLENDEQUATIONPROC __glewBlendEquation = NULL;
+PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate = NULL;
+PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer = NULL;
+PFNGLFOGCOORDDPROC __glewFogCoordd = NULL;
+PFNGLFOGCOORDDVPROC __glewFogCoorddv = NULL;
+PFNGLFOGCOORDFPROC __glewFogCoordf = NULL;
+PFNGLFOGCOORDFVPROC __glewFogCoordfv = NULL;
+PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays = NULL;
+PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements = NULL;
+PFNGLPOINTPARAMETERFPROC __glewPointParameterf = NULL;
+PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv = NULL;
+PFNGLPOINTPARAMETERIPROC __glewPointParameteri = NULL;
+PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv = NULL;
+PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b = NULL;
+PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv = NULL;
+PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d = NULL;
+PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv = NULL;
+PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f = NULL;
+PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv = NULL;
+PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i = NULL;
+PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv = NULL;
+PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s = NULL;
+PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv = NULL;
+PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub = NULL;
+PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv = NULL;
+PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui = NULL;
+PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv = NULL;
+PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us = NULL;
+PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv = NULL;
+PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer = NULL;
+PFNGLWINDOWPOS2DPROC __glewWindowPos2d = NULL;
+PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv = NULL;
+PFNGLWINDOWPOS2FPROC __glewWindowPos2f = NULL;
+PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv = NULL;
+PFNGLWINDOWPOS2IPROC __glewWindowPos2i = NULL;
+PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv = NULL;
+PFNGLWINDOWPOS2SPROC __glewWindowPos2s = NULL;
+PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv = NULL;
+PFNGLWINDOWPOS3DPROC __glewWindowPos3d = NULL;
+PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv = NULL;
+PFNGLWINDOWPOS3FPROC __glewWindowPos3f = NULL;
+PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv = NULL;
+PFNGLWINDOWPOS3IPROC __glewWindowPos3i = NULL;
+PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv = NULL;
+PFNGLWINDOWPOS3SPROC __glewWindowPos3s = NULL;
+PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv = NULL;
+
+PFNGLBEGINQUERYPROC __glewBeginQuery = NULL;
+PFNGLBINDBUFFERPROC __glewBindBuffer = NULL;
+PFNGLBUFFERDATAPROC __glewBufferData = NULL;
+PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL;
+PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL;
+PFNGLDELETEQUERIESPROC __glewDeleteQueries = NULL;
+PFNGLENDQUERYPROC __glewEndQuery = NULL;
+PFNGLGENBUFFERSPROC __glewGenBuffers = NULL;
+PFNGLGENQUERIESPROC __glewGenQueries = NULL;
+PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv = NULL;
+PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv = NULL;
+PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL;
+PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL;
+PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv = NULL;
+PFNGLGETQUERYIVPROC __glewGetQueryiv = NULL;
+PFNGLISBUFFERPROC __glewIsBuffer = NULL;
+PFNGLISQUERYPROC __glewIsQuery = NULL;
+PFNGLMAPBUFFERPROC __glewMapBuffer = NULL;
+PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL;
+
+PFNGLATTACHSHADERPROC __glewAttachShader = NULL;
+PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL;
+PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL;
+PFNGLCOMPILESHADERPROC __glewCompileShader = NULL;
+PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL;
+PFNGLCREATESHADERPROC __glewCreateShader = NULL;
+PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL;
+PFNGLDELETESHADERPROC __glewDeleteShader = NULL;
+PFNGLDETACHSHADERPROC __glewDetachShader = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL;
+PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL;
+PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL;
+PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL;
+PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL;
+PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL;
+PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL;
+PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL;
+PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL;
+PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL;
+PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL;
+PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL;
+PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL;
+PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL;
+PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL;
+PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL;
+PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL;
+PFNGLISPROGRAMPROC __glewIsProgram = NULL;
+PFNGLISSHADERPROC __glewIsShader = NULL;
+PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL;
+PFNGLSHADERSOURCEPROC __glewShaderSource = NULL;
+PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL;
+PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL;
+PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL;
+PFNGLUNIFORM1FPROC __glewUniform1f = NULL;
+PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL;
+PFNGLUNIFORM1IPROC __glewUniform1i = NULL;
+PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL;
+PFNGLUNIFORM2FPROC __glewUniform2f = NULL;
+PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL;
+PFNGLUNIFORM2IPROC __glewUniform2i = NULL;
+PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL;
+PFNGLUNIFORM3FPROC __glewUniform3f = NULL;
+PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL;
+PFNGLUNIFORM3IPROC __glewUniform3i = NULL;
+PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL;
+PFNGLUNIFORM4FPROC __glewUniform4f = NULL;
+PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL;
+PFNGLUNIFORM4IPROC __glewUniform4i = NULL;
+PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL;
+PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL;
+PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL;
+PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL;
+PFNGLUSEPROGRAMPROC __glewUseProgram = NULL;
+PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL;
+PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d = NULL;
+PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv = NULL;
+PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f = NULL;
+PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv = NULL;
+PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s = NULL;
+PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv = NULL;
+PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d = NULL;
+PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv = NULL;
+PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f = NULL;
+PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv = NULL;
+PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s = NULL;
+PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv = NULL;
+PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d = NULL;
+PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv = NULL;
+PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f = NULL;
+PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv = NULL;
+PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s = NULL;
+PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv = NULL;
+PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv = NULL;
+PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv = NULL;
+PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv = NULL;
+PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub = NULL;
+PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv = NULL;
+PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv = NULL;
+PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv = NULL;
+PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv = NULL;
+PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d = NULL;
+PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv = NULL;
+PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f = NULL;
+PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv = NULL;
+PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv = NULL;
+PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s = NULL;
+PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv = NULL;
+PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv = NULL;
+PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv = NULL;
+PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv = NULL;
+PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL;
+
+PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv = NULL;
+PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv = NULL;
+PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv = NULL;
+PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv = NULL;
+PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv = NULL;
+PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv = NULL;
+
+PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback = NULL;
+PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation = NULL;
+PFNGLCLAMPCOLORPROC __glewClampColor = NULL;
+PFNGLCLEARBUFFERFIPROC __glewClearBufferfi = NULL;
+PFNGLCLEARBUFFERFVPROC __glewClearBufferfv = NULL;
+PFNGLCLEARBUFFERIVPROC __glewClearBufferiv = NULL;
+PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv = NULL;
+PFNGLCOLORMASKIPROC __glewColorMaski = NULL;
+PFNGLDISABLEIPROC __glewDisablei = NULL;
+PFNGLENABLEIPROC __glewEnablei = NULL;
+PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback = NULL;
+PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v = NULL;
+PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation = NULL;
+PFNGLGETSTRINGIPROC __glewGetStringi = NULL;
+PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv = NULL;
+PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying = NULL;
+PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv = NULL;
+PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv = NULL;
+PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv = NULL;
+PFNGLISENABLEDIPROC __glewIsEnabledi = NULL;
+PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv = NULL;
+PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings = NULL;
+PFNGLUNIFORM1UIPROC __glewUniform1ui = NULL;
+PFNGLUNIFORM1UIVPROC __glewUniform1uiv = NULL;
+PFNGLUNIFORM2UIPROC __glewUniform2ui = NULL;
+PFNGLUNIFORM2UIVPROC __glewUniform2uiv = NULL;
+PFNGLUNIFORM3UIPROC __glewUniform3ui = NULL;
+PFNGLUNIFORM3UIVPROC __glewUniform3uiv = NULL;
+PFNGLUNIFORM4UIPROC __glewUniform4ui = NULL;
+PFNGLUNIFORM4UIVPROC __glewUniform4uiv = NULL;
+PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i = NULL;
+PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv = NULL;
+PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui = NULL;
+PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv = NULL;
+PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i = NULL;
+PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv = NULL;
+PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui = NULL;
+PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv = NULL;
+PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i = NULL;
+PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv = NULL;
+PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui = NULL;
+PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv = NULL;
+PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv = NULL;
+PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i = NULL;
+PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv = NULL;
+PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv = NULL;
+PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv = NULL;
+PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui = NULL;
+PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv = NULL;
+PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced = NULL;
+PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced = NULL;
+PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex = NULL;
+PFNGLTEXBUFFERPROC __glewTexBuffer = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture = NULL;
+PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v = NULL;
+PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v = NULL;
+
+PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor = NULL;
+
+PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei = NULL;
+PFNGLBLENDEQUATIONIPROC __glewBlendEquationi = NULL;
+PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei = NULL;
+PFNGLBLENDFUNCIPROC __glewBlendFunci = NULL;
+PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading = NULL;
+
+PFNGLGETGRAPHICSRESETSTATUSPROC __glewGetGraphicsResetStatus = NULL;
+PFNGLGETNCOMPRESSEDTEXIMAGEPROC __glewGetnCompressedTexImage = NULL;
+PFNGLGETNTEXIMAGEPROC __glewGetnTexImage = NULL;
+PFNGLGETNUNIFORMDVPROC __glewGetnUniformdv = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC __glewMultiDrawArraysIndirectCount = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC __glewMultiDrawElementsIndirectCount = NULL;
+PFNGLSPECIALIZESHADERPROC __glewSpecializeShader = NULL;
+
+PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL;
+
+PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD = NULL;
+PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD = NULL;
+PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD = NULL;
+PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD = NULL;
+
+PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD = NULL;
+PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD = NULL;
+PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD = NULL;
+PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD = NULL;
+
+PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewFramebufferSamplePositionsfvAMD = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC __glewGetFramebufferParameterfvAMD = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC __glewGetNamedFramebufferParameterfvAMD = NULL;
+PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewNamedFramebufferSamplePositionsfvAMD = NULL;
+
+PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD = NULL;
+
+PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD = NULL;
+PFNGLGENNAMESAMDPROC __glewGenNamesAMD = NULL;
+PFNGLISNAMEAMDPROC __glewIsNameAMD = NULL;
+
+PFNGLQUERYOBJECTPARAMETERUIAMDPROC __glewQueryObjectParameteruiAMD = NULL;
+
+PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD = NULL;
+PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD = NULL;
+PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD = NULL;
+PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD = NULL;
+PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD = NULL;
+PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD = NULL;
+PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD = NULL;
+
+PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD = NULL;
+
+PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD = NULL;
+PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD = NULL;
+
+PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD = NULL;
+
+PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD = NULL;
+PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD = NULL;
+
+PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE = NULL;
+PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE = NULL;
+PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE = NULL;
+
+PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE = NULL;
+PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE = NULL;
+PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE = NULL;
+PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE = NULL;
+PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE = NULL;
+PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE = NULL;
+PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE = NULL;
+PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE = NULL;
+PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE = NULL;
+PFNGLISQUERYANGLEPROC __glewIsQueryANGLE = NULL;
+PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE = NULL;
+
+PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE = NULL;
+
+PFNGLCOPYTEXTURELEVELSAPPLEPROC __glewCopyTextureLevelsAPPLE = NULL;
+
+PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL;
+PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL;
+PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL;
+PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE = NULL;
+PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE = NULL;
+
+PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE = NULL;
+PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE = NULL;
+PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE = NULL;
+PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE = NULL;
+PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE = NULL;
+PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE = NULL;
+PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE = NULL;
+PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE = NULL;
+
+PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE = NULL;
+PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC __glewRenderbufferStorageMultisampleAPPLE = NULL;
+PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC __glewResolveMultisampleFramebufferAPPLE = NULL;
+
+PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE = NULL;
+PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE = NULL;
+PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE = NULL;
+
+PFNGLCLIENTWAITSYNCAPPLEPROC __glewClientWaitSyncAPPLE = NULL;
+PFNGLDELETESYNCAPPLEPROC __glewDeleteSyncAPPLE = NULL;
+PFNGLFENCESYNCAPPLEPROC __glewFenceSyncAPPLE = NULL;
+PFNGLGETINTEGER64VAPPLEPROC __glewGetInteger64vAPPLE = NULL;
+PFNGLGETSYNCIVAPPLEPROC __glewGetSyncivAPPLE = NULL;
+PFNGLISSYNCAPPLEPROC __glewIsSyncAPPLE = NULL;
+PFNGLWAITSYNCAPPLEPROC __glewWaitSyncAPPLE = NULL;
+
+PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL;
+PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL;
+
+PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE = NULL;
+PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE = NULL;
+PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE = NULL;
+PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE = NULL;
+
+PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE = NULL;
+PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL;
+PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL;
+
+PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE = NULL;
+PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE = NULL;
+PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE = NULL;
+
+PFNGLCLEARDEPTHFPROC __glewClearDepthf = NULL;
+PFNGLDEPTHRANGEFPROC __glewDepthRangef = NULL;
+PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat = NULL;
+PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler = NULL;
+PFNGLSHADERBINARYPROC __glewShaderBinary = NULL;
+
+PFNGLMEMORYBARRIERBYREGIONPROC __glewMemoryBarrierByRegion = NULL;
+
+PFNGLPRIMITIVEBOUNDINGBOXARBPROC __glewPrimitiveBoundingBoxARB = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance = NULL;
+
+PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB = NULL;
+PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB = NULL;
+PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB = NULL;
+PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB = NULL;
+PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB = NULL;
+PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB = NULL;
+PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB = NULL;
+PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB = NULL;
+PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB = NULL;
+PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB = NULL;
+PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB = NULL;
+PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB = NULL;
+PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB = NULL;
+PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB = NULL;
+
+PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed = NULL;
+PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex = NULL;
+
+PFNGLBUFFERSTORAGEPROC __glewBufferStorage = NULL;
+
+PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB = NULL;
+
+PFNGLCLEARBUFFERDATAPROC __glewClearBufferData = NULL;
+PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData = NULL;
+PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT = NULL;
+PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT = NULL;
+
+PFNGLCLEARTEXIMAGEPROC __glewClearTexImage = NULL;
+PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage = NULL;
+
+PFNGLCLIPCONTROLPROC __glewClipControl = NULL;
+
+PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL;
+
+PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute = NULL;
+PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect = NULL;
+
+PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB = NULL;
+
+PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData = NULL;
+
+PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData = NULL;
+
+PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB = NULL;
+PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB = NULL;
+PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB = NULL;
+PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB = NULL;
+
+PFNGLBINDTEXTUREUNITPROC __glewBindTextureUnit = NULL;
+PFNGLBLITNAMEDFRAMEBUFFERPROC __glewBlitNamedFramebuffer = NULL;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC __glewCheckNamedFramebufferStatus = NULL;
+PFNGLCLEARNAMEDBUFFERDATAPROC __glewClearNamedBufferData = NULL;
+PFNGLCLEARNAMEDBUFFERSUBDATAPROC __glewClearNamedBufferSubData = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFIPROC __glewClearNamedFramebufferfi = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERFVPROC __glewClearNamedFramebufferfv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERIVPROC __glewClearNamedFramebufferiv = NULL;
+PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC __glewClearNamedFramebufferuiv = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC __glewCompressedTextureSubImage1D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC __glewCompressedTextureSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC __glewCompressedTextureSubImage3D = NULL;
+PFNGLCOPYNAMEDBUFFERSUBDATAPROC __glewCopyNamedBufferSubData = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DPROC __glewCopyTextureSubImage1D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DPROC __glewCopyTextureSubImage2D = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DPROC __glewCopyTextureSubImage3D = NULL;
+PFNGLCREATEBUFFERSPROC __glewCreateBuffers = NULL;
+PFNGLCREATEFRAMEBUFFERSPROC __glewCreateFramebuffers = NULL;
+PFNGLCREATEPROGRAMPIPELINESPROC __glewCreateProgramPipelines = NULL;
+PFNGLCREATEQUERIESPROC __glewCreateQueries = NULL;
+PFNGLCREATERENDERBUFFERSPROC __glewCreateRenderbuffers = NULL;
+PFNGLCREATESAMPLERSPROC __glewCreateSamplers = NULL;
+PFNGLCREATETEXTURESPROC __glewCreateTextures = NULL;
+PFNGLCREATETRANSFORMFEEDBACKSPROC __glewCreateTransformFeedbacks = NULL;
+PFNGLCREATEVERTEXARRAYSPROC __glewCreateVertexArrays = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBPROC __glewDisableVertexArrayAttrib = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBPROC __glewEnableVertexArrayAttrib = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC __glewFlushMappedNamedBufferRange = NULL;
+PFNGLGENERATETEXTUREMIPMAPPROC __glewGenerateTextureMipmap = NULL;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC __glewGetCompressedTextureImage = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERI64VPROC __glewGetNamedBufferParameteri64v = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERIVPROC __glewGetNamedBufferParameteriv = NULL;
+PFNGLGETNAMEDBUFFERPOINTERVPROC __glewGetNamedBufferPointerv = NULL;
+PFNGLGETNAMEDBUFFERSUBDATAPROC __glewGetNamedBufferSubData = NULL;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetNamedFramebufferAttachmentParameteriv = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC __glewGetNamedFramebufferParameteriv = NULL;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC __glewGetNamedRenderbufferParameteriv = NULL;
+PFNGLGETQUERYBUFFEROBJECTI64VPROC __glewGetQueryBufferObjecti64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTIVPROC __glewGetQueryBufferObjectiv = NULL;
+PFNGLGETQUERYBUFFEROBJECTUI64VPROC __glewGetQueryBufferObjectui64v = NULL;
+PFNGLGETQUERYBUFFEROBJECTUIVPROC __glewGetQueryBufferObjectuiv = NULL;
+PFNGLGETTEXTUREIMAGEPROC __glewGetTextureImage = NULL;
+PFNGLGETTEXTURELEVELPARAMETERFVPROC __glewGetTextureLevelParameterfv = NULL;
+PFNGLGETTEXTURELEVELPARAMETERIVPROC __glewGetTextureLevelParameteriv = NULL;
+PFNGLGETTEXTUREPARAMETERIIVPROC __glewGetTextureParameterIiv = NULL;
+PFNGLGETTEXTUREPARAMETERIUIVPROC __glewGetTextureParameterIuiv = NULL;
+PFNGLGETTEXTUREPARAMETERFVPROC __glewGetTextureParameterfv = NULL;
+PFNGLGETTEXTUREPARAMETERIVPROC __glewGetTextureParameteriv = NULL;
+PFNGLGETTRANSFORMFEEDBACKI64_VPROC __glewGetTransformFeedbacki64_v = NULL;
+PFNGLGETTRANSFORMFEEDBACKI_VPROC __glewGetTransformFeedbacki_v = NULL;
+PFNGLGETTRANSFORMFEEDBACKIVPROC __glewGetTransformFeedbackiv = NULL;
+PFNGLGETVERTEXARRAYINDEXED64IVPROC __glewGetVertexArrayIndexed64iv = NULL;
+PFNGLGETVERTEXARRAYINDEXEDIVPROC __glewGetVertexArrayIndexediv = NULL;
+PFNGLGETVERTEXARRAYIVPROC __glewGetVertexArrayiv = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC __glewInvalidateNamedFramebufferData = NULL;
+PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC __glewInvalidateNamedFramebufferSubData = NULL;
+PFNGLMAPNAMEDBUFFERPROC __glewMapNamedBuffer = NULL;
+PFNGLMAPNAMEDBUFFERRANGEPROC __glewMapNamedBufferRange = NULL;
+PFNGLNAMEDBUFFERDATAPROC __glewNamedBufferData = NULL;
+PFNGLNAMEDBUFFERSTORAGEPROC __glewNamedBufferStorage = NULL;
+PFNGLNAMEDBUFFERSUBDATAPROC __glewNamedBufferSubData = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC __glewNamedFramebufferDrawBuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC __glewNamedFramebufferDrawBuffers = NULL;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC __glewNamedFramebufferParameteri = NULL;
+PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC __glewNamedFramebufferReadBuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC __glewNamedFramebufferRenderbuffer = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREPROC __glewNamedFramebufferTexture = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC __glewNamedFramebufferTextureLayer = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEPROC __glewNamedRenderbufferStorage = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewNamedRenderbufferStorageMultisample = NULL;
+PFNGLTEXTUREBUFFERPROC __glewTextureBuffer = NULL;
+PFNGLTEXTUREBUFFERRANGEPROC __glewTextureBufferRange = NULL;
+PFNGLTEXTUREPARAMETERIIVPROC __glewTextureParameterIiv = NULL;
+PFNGLTEXTUREPARAMETERIUIVPROC __glewTextureParameterIuiv = NULL;
+PFNGLTEXTUREPARAMETERFPROC __glewTextureParameterf = NULL;
+PFNGLTEXTUREPARAMETERFVPROC __glewTextureParameterfv = NULL;
+PFNGLTEXTUREPARAMETERIPROC __glewTextureParameteri = NULL;
+PFNGLTEXTUREPARAMETERIVPROC __glewTextureParameteriv = NULL;
+PFNGLTEXTURESTORAGE1DPROC __glewTextureStorage1D = NULL;
+PFNGLTEXTURESTORAGE2DPROC __glewTextureStorage2D = NULL;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC __glewTextureStorage2DMultisample = NULL;
+PFNGLTEXTURESTORAGE3DPROC __glewTextureStorage3D = NULL;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC __glewTextureStorage3DMultisample = NULL;
+PFNGLTEXTURESUBIMAGE1DPROC __glewTextureSubImage1D = NULL;
+PFNGLTEXTURESUBIMAGE2DPROC __glewTextureSubImage2D = NULL;
+PFNGLTEXTURESUBIMAGE3DPROC __glewTextureSubImage3D = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC __glewTransformFeedbackBufferBase = NULL;
+PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC __glewTransformFeedbackBufferRange = NULL;
+PFNGLUNMAPNAMEDBUFFERPROC __glewUnmapNamedBuffer = NULL;
+PFNGLVERTEXARRAYATTRIBBINDINGPROC __glewVertexArrayAttribBinding = NULL;
+PFNGLVERTEXARRAYATTRIBFORMATPROC __glewVertexArrayAttribFormat = NULL;
+PFNGLVERTEXARRAYATTRIBIFORMATPROC __glewVertexArrayAttribIFormat = NULL;
+PFNGLVERTEXARRAYATTRIBLFORMATPROC __glewVertexArrayAttribLFormat = NULL;
+PFNGLVERTEXARRAYBINDINGDIVISORPROC __glewVertexArrayBindingDivisor = NULL;
+PFNGLVERTEXARRAYELEMENTBUFFERPROC __glewVertexArrayElementBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERPROC __glewVertexArrayVertexBuffer = NULL;
+PFNGLVERTEXARRAYVERTEXBUFFERSPROC __glewVertexArrayVertexBuffers = NULL;
+
+PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL;
+
+PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB = NULL;
+PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB = NULL;
+PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB = NULL;
+PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB = NULL;
+
+PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex = NULL;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex = NULL;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex = NULL;
+
+PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect = NULL;
+PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect = NULL;
+
+PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT = NULL;
+
+PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer = NULL;
+PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer = NULL;
+PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL;
+PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL;
+PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL;
+PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL;
+PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL;
+PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL;
+PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer = NULL;
+PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers = NULL;
+PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers = NULL;
+PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv = NULL;
+PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv = NULL;
+PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer = NULL;
+PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer = NULL;
+PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB = NULL;
+PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB = NULL;
+PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB = NULL;
+
+PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary = NULL;
+PFNGLPROGRAMBINARYPROC __glewProgramBinary = NULL;
+PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri = NULL;
+
+PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC __glewGetCompressedTextureSubImage = NULL;
+PFNGLGETTEXTURESUBIMAGEPROC __glewGetTextureSubImage = NULL;
+
+PFNGLSPECIALIZESHADERARBPROC __glewSpecializeShaderARB = NULL;
+
+PFNGLGETUNIFORMDVPROC __glewGetUniformdv = NULL;
+PFNGLUNIFORM1DPROC __glewUniform1d = NULL;
+PFNGLUNIFORM1DVPROC __glewUniform1dv = NULL;
+PFNGLUNIFORM2DPROC __glewUniform2d = NULL;
+PFNGLUNIFORM2DVPROC __glewUniform2dv = NULL;
+PFNGLUNIFORM3DPROC __glewUniform3d = NULL;
+PFNGLUNIFORM3DVPROC __glewUniform3dv = NULL;
+PFNGLUNIFORM4DPROC __glewUniform4d = NULL;
+PFNGLUNIFORM4DVPROC __glewUniform4dv = NULL;
+PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv = NULL;
+PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv = NULL;
+PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv = NULL;
+PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv = NULL;
+PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv = NULL;
+PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv = NULL;
+PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv = NULL;
+PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv = NULL;
+PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv = NULL;
+
+PFNGLGETUNIFORMI64VARBPROC __glewGetUniformi64vARB = NULL;
+PFNGLGETUNIFORMUI64VARBPROC __glewGetUniformui64vARB = NULL;
+PFNGLGETNUNIFORMI64VARBPROC __glewGetnUniformi64vARB = NULL;
+PFNGLGETNUNIFORMUI64VARBPROC __glewGetnUniformui64vARB = NULL;
+PFNGLPROGRAMUNIFORM1I64ARBPROC __glewProgramUniform1i64ARB = NULL;
+PFNGLPROGRAMUNIFORM1I64VARBPROC __glewProgramUniform1i64vARB = NULL;
+PFNGLPROGRAMUNIFORM1UI64ARBPROC __glewProgramUniform1ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM1UI64VARBPROC __glewProgramUniform1ui64vARB = NULL;
+PFNGLPROGRAMUNIFORM2I64ARBPROC __glewProgramUniform2i64ARB = NULL;
+PFNGLPROGRAMUNIFORM2I64VARBPROC __glewProgramUniform2i64vARB = NULL;
+PFNGLPROGRAMUNIFORM2UI64ARBPROC __glewProgramUniform2ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM2UI64VARBPROC __glewProgramUniform2ui64vARB = NULL;
+PFNGLPROGRAMUNIFORM3I64ARBPROC __glewProgramUniform3i64ARB = NULL;
+PFNGLPROGRAMUNIFORM3I64VARBPROC __glewProgramUniform3i64vARB = NULL;
+PFNGLPROGRAMUNIFORM3UI64ARBPROC __glewProgramUniform3ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM3UI64VARBPROC __glewProgramUniform3ui64vARB = NULL;
+PFNGLPROGRAMUNIFORM4I64ARBPROC __glewProgramUniform4i64ARB = NULL;
+PFNGLPROGRAMUNIFORM4I64VARBPROC __glewProgramUniform4i64vARB = NULL;
+PFNGLPROGRAMUNIFORM4UI64ARBPROC __glewProgramUniform4ui64ARB = NULL;
+PFNGLPROGRAMUNIFORM4UI64VARBPROC __glewProgramUniform4ui64vARB = NULL;
+PFNGLUNIFORM1I64ARBPROC __glewUniform1i64ARB = NULL;
+PFNGLUNIFORM1I64VARBPROC __glewUniform1i64vARB = NULL;
+PFNGLUNIFORM1UI64ARBPROC __glewUniform1ui64ARB = NULL;
+PFNGLUNIFORM1UI64VARBPROC __glewUniform1ui64vARB = NULL;
+PFNGLUNIFORM2I64ARBPROC __glewUniform2i64ARB = NULL;
+PFNGLUNIFORM2I64VARBPROC __glewUniform2i64vARB = NULL;
+PFNGLUNIFORM2UI64ARBPROC __glewUniform2ui64ARB = NULL;
+PFNGLUNIFORM2UI64VARBPROC __glewUniform2ui64vARB = NULL;
+PFNGLUNIFORM3I64ARBPROC __glewUniform3i64ARB = NULL;
+PFNGLUNIFORM3I64VARBPROC __glewUniform3i64vARB = NULL;
+PFNGLUNIFORM3UI64ARBPROC __glewUniform3ui64ARB = NULL;
+PFNGLUNIFORM3UI64VARBPROC __glewUniform3ui64vARB = NULL;
+PFNGLUNIFORM4I64ARBPROC __glewUniform4i64ARB = NULL;
+PFNGLUNIFORM4I64VARBPROC __glewUniform4i64vARB = NULL;
+PFNGLUNIFORM4UI64ARBPROC __glewUniform4ui64ARB = NULL;
+PFNGLUNIFORM4UI64VARBPROC __glewUniform4ui64vARB = NULL;
+
+PFNGLCOLORSUBTABLEPROC __glewColorSubTable = NULL;
+PFNGLCOLORTABLEPROC __glewColorTable = NULL;
+PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv = NULL;
+PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv = NULL;
+PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D = NULL;
+PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D = NULL;
+PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf = NULL;
+PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv = NULL;
+PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri = NULL;
+PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv = NULL;
+PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable = NULL;
+PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable = NULL;
+PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D = NULL;
+PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D = NULL;
+PFNGLGETCOLORTABLEPROC __glewGetColorTable = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv = NULL;
+PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter = NULL;
+PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv = NULL;
+PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv = NULL;
+PFNGLGETHISTOGRAMPROC __glewGetHistogram = NULL;
+PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv = NULL;
+PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv = NULL;
+PFNGLGETMINMAXPROC __glewGetMinmax = NULL;
+PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv = NULL;
+PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv = NULL;
+PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter = NULL;
+PFNGLHISTOGRAMPROC __glewHistogram = NULL;
+PFNGLMINMAXPROC __glewMinmax = NULL;
+PFNGLRESETHISTOGRAMPROC __glewResetHistogram = NULL;
+PFNGLRESETMINMAXPROC __glewResetMinmax = NULL;
+PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL;
+PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL;
+PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB = NULL;
+
+PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ = NULL;
+
+PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v = NULL;
+
+PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData = NULL;
+PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData = NULL;
+PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer = NULL;
+PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer = NULL;
+PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage = NULL;
+PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage = NULL;
+
+PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange = NULL;
+PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange = NULL;
+
+PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL;
+PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL;
+PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL;
+PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL;
+PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL;
+
+PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase = NULL;
+PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange = NULL;
+PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures = NULL;
+PFNGLBINDSAMPLERSPROC __glewBindSamplers = NULL;
+PFNGLBINDTEXTURESPROC __glewBindTextures = NULL;
+PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect = NULL;
+
+PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB = NULL;
+
+PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB = NULL;
+PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB = NULL;
+PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB = NULL;
+PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB = NULL;
+PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB = NULL;
+PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB = NULL;
+PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB = NULL;
+PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB = NULL;
+PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB = NULL;
+PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB = NULL;
+PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB = NULL;
+PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB = NULL;
+PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB = NULL;
+PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB = NULL;
+PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB = NULL;
+PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB = NULL;
+PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB = NULL;
+PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB = NULL;
+PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB = NULL;
+PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB = NULL;
+PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB = NULL;
+PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB = NULL;
+PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB = NULL;
+PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB = NULL;
+PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB = NULL;
+PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB = NULL;
+PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB = NULL;
+PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB = NULL;
+PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB = NULL;
+PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB = NULL;
+PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB = NULL;
+PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB = NULL;
+PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB = NULL;
+PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB = NULL;
+
+PFNGLBEGINQUERYARBPROC __glewBeginQueryARB = NULL;
+PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB = NULL;
+PFNGLENDQUERYARBPROC __glewEndQueryARB = NULL;
+PFNGLGENQUERIESARBPROC __glewGenQueriesARB = NULL;
+PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB = NULL;
+PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB = NULL;
+PFNGLGETQUERYIVARBPROC __glewGetQueryivARB = NULL;
+PFNGLISQUERYARBPROC __glewIsQueryARB = NULL;
+
+PFNGLMAXSHADERCOMPILERTHREADSARBPROC __glewMaxShaderCompilerThreadsARB = NULL;
+
+PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL;
+PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL;
+
+PFNGLPOLYGONOFFSETCLAMPPROC __glewPolygonOffsetClamp = NULL;
+
+PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv = NULL;
+PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex = NULL;
+PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName = NULL;
+PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv = NULL;
+
+PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex = NULL;
+
+PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB = NULL;
+PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB = NULL;
+PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB = NULL;
+PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB = NULL;
+PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB = NULL;
+PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB = NULL;
+PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB = NULL;
+PFNGLGETNMAPIVARBPROC __glewGetnMapivARB = NULL;
+PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB = NULL;
+PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB = NULL;
+PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB = NULL;
+PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB = NULL;
+PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB = NULL;
+PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB = NULL;
+PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB = NULL;
+PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB = NULL;
+PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB = NULL;
+PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB = NULL;
+PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB = NULL;
+PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB = NULL;
+
+PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewFramebufferSampleLocationsfvARB = NULL;
+PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewNamedFramebufferSampleLocationsfvARB = NULL;
+
+PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB = NULL;
+
+PFNGLBINDSAMPLERPROC __glewBindSampler = NULL;
+PFNGLDELETESAMPLERSPROC __glewDeleteSamplers = NULL;
+PFNGLGENSAMPLERSPROC __glewGenSamplers = NULL;
+PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv = NULL;
+PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv = NULL;
+PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv = NULL;
+PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv = NULL;
+PFNGLISSAMPLERPROC __glewIsSampler = NULL;
+PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv = NULL;
+PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv = NULL;
+PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf = NULL;
+PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv = NULL;
+PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri = NULL;
+PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv = NULL;
+
+PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram = NULL;
+PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline = NULL;
+PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv = NULL;
+PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines = NULL;
+PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines = NULL;
+PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog = NULL;
+PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv = NULL;
+PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline = NULL;
+PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d = NULL;
+PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv = NULL;
+PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f = NULL;
+PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv = NULL;
+PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i = NULL;
+PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv = NULL;
+PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui = NULL;
+PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv = NULL;
+PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d = NULL;
+PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv = NULL;
+PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f = NULL;
+PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv = NULL;
+PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i = NULL;
+PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv = NULL;
+PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui = NULL;
+PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv = NULL;
+PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d = NULL;
+PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv = NULL;
+PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f = NULL;
+PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv = NULL;
+PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i = NULL;
+PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv = NULL;
+PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui = NULL;
+PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv = NULL;
+PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d = NULL;
+PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv = NULL;
+PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f = NULL;
+PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv = NULL;
+PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i = NULL;
+PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv = NULL;
+PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui = NULL;
+PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv = NULL;
+PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages = NULL;
+PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline = NULL;
+
+PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv = NULL;
+
+PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture = NULL;
+PFNGLMEMORYBARRIERPROC __glewMemoryBarrier = NULL;
+
+PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL;
+PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL;
+PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL;
+PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB = NULL;
+PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB = NULL;
+PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB = NULL;
+PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB = NULL;
+PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB = NULL;
+PFNGLGETHANDLEARBPROC __glewGetHandleARB = NULL;
+PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB = NULL;
+PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB = NULL;
+PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB = NULL;
+PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB = NULL;
+PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB = NULL;
+PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB = NULL;
+PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB = NULL;
+PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB = NULL;
+PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB = NULL;
+PFNGLUNIFORM1FARBPROC __glewUniform1fARB = NULL;
+PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB = NULL;
+PFNGLUNIFORM1IARBPROC __glewUniform1iARB = NULL;
+PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB = NULL;
+PFNGLUNIFORM2FARBPROC __glewUniform2fARB = NULL;
+PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB = NULL;
+PFNGLUNIFORM2IARBPROC __glewUniform2iARB = NULL;
+PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB = NULL;
+PFNGLUNIFORM3FARBPROC __glewUniform3fARB = NULL;
+PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB = NULL;
+PFNGLUNIFORM3IARBPROC __glewUniform3iARB = NULL;
+PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB = NULL;
+PFNGLUNIFORM4FARBPROC __glewUniform4fARB = NULL;
+PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB = NULL;
+PFNGLUNIFORM4IARBPROC __glewUniform4iARB = NULL;
+PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB = NULL;
+PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB = NULL;
+PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB = NULL;
+PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB = NULL;
+PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL;
+PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL;
+
+PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding = NULL;
+
+PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv = NULL;
+PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv = NULL;
+PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex = NULL;
+PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation = NULL;
+PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv = NULL;
+PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv = NULL;
+
+PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB = NULL;
+PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB = NULL;
+PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB = NULL;
+PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB = NULL;
+PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB = NULL;
+PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB = NULL;
+
+PFNGLBUFFERPAGECOMMITMENTARBPROC __glewBufferPageCommitmentARB = NULL;
+
+PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB = NULL;
+
+PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync = NULL;
+PFNGLDELETESYNCPROC __glewDeleteSync = NULL;
+PFNGLFENCESYNCPROC __glewFenceSync = NULL;
+PFNGLGETINTEGER64VPROC __glewGetInteger64v = NULL;
+PFNGLGETSYNCIVPROC __glewGetSynciv = NULL;
+PFNGLISSYNCPROC __glewIsSync = NULL;
+PFNGLWAITSYNCPROC __glewWaitSync = NULL;
+
+PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv = NULL;
+PFNGLPATCHPARAMETERIPROC __glewPatchParameteri = NULL;
+
+PFNGLTEXTUREBARRIERPROC __glewTextureBarrier = NULL;
+
+PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL;
+
+PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange = NULL;
+PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT = NULL;
+
+PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL;
+PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL;
+PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL;
+PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL;
+
+PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv = NULL;
+PFNGLSAMPLEMASKIPROC __glewSampleMaski = NULL;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample = NULL;
+
+PFNGLTEXSTORAGE1DPROC __glewTexStorage1D = NULL;
+PFNGLTEXSTORAGE2DPROC __glewTexStorage2D = NULL;
+PFNGLTEXSTORAGE3DPROC __glewTexStorage3D = NULL;
+
+PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample = NULL;
+PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample = NULL;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT = NULL;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT = NULL;
+
+PFNGLTEXTUREVIEWPROC __glewTextureView = NULL;
+
+PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v = NULL;
+PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v = NULL;
+PFNGLQUERYCOUNTERPROC __glewQueryCounter = NULL;
+
+PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback = NULL;
+PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks = NULL;
+PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback = NULL;
+
+PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream = NULL;
+PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed = NULL;
+PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv = NULL;
+
+PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced = NULL;
+
+PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL;
+PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL;
+PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL;
+PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL;
+
+PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL;
+PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv = NULL;
+PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName = NULL;
+PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv = NULL;
+PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL;
+PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex = NULL;
+PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices = NULL;
+PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding = NULL;
+
+PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL;
+PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL;
+PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL;
+PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL;
+
+PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv = NULL;
+PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d = NULL;
+PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv = NULL;
+PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d = NULL;
+PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv = NULL;
+PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d = NULL;
+PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv = NULL;
+PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d = NULL;
+PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv = NULL;
+PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer = NULL;
+
+PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer = NULL;
+PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC __glewVertexArrayBindVertexBufferEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC __glewVertexArrayVertexAttribBindingEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC __glewVertexArrayVertexAttribFormatEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC __glewVertexArrayVertexAttribIFormatEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC __glewVertexArrayVertexAttribLFormatEXT = NULL;
+PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC __glewVertexArrayVertexBindingDivisorEXT = NULL;
+PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding = NULL;
+PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat = NULL;
+PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat = NULL;
+PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat = NULL;
+PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor = NULL;
+
+PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB = NULL;
+PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB = NULL;
+PFNGLWEIGHTBVARBPROC __glewWeightbvARB = NULL;
+PFNGLWEIGHTDVARBPROC __glewWeightdvARB = NULL;
+PFNGLWEIGHTFVARBPROC __glewWeightfvARB = NULL;
+PFNGLWEIGHTIVARBPROC __glewWeightivARB = NULL;
+PFNGLWEIGHTSVARBPROC __glewWeightsvARB = NULL;
+PFNGLWEIGHTUBVARBPROC __glewWeightubvARB = NULL;
+PFNGLWEIGHTUIVARBPROC __glewWeightuivARB = NULL;
+PFNGLWEIGHTUSVARBPROC __glewWeightusvARB = NULL;
+
+PFNGLBINDBUFFERARBPROC __glewBindBufferARB = NULL;
+PFNGLBUFFERDATAARBPROC __glewBufferDataARB = NULL;
+PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB = NULL;
+PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB = NULL;
+PFNGLGENBUFFERSARBPROC __glewGenBuffersARB = NULL;
+PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB = NULL;
+PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB = NULL;
+PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB = NULL;
+PFNGLISBUFFERARBPROC __glewIsBufferARB = NULL;
+PFNGLMAPBUFFERARBPROC __glewMapBufferARB = NULL;
+PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB = NULL;
+
+PFNGLBINDPROGRAMARBPROC __glewBindProgramARB = NULL;
+PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB = NULL;
+PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB = NULL;
+PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB = NULL;
+PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB = NULL;
+PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB = NULL;
+PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB = NULL;
+PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB = NULL;
+PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB = NULL;
+PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB = NULL;
+PFNGLISPROGRAMARBPROC __glewIsProgramARB = NULL;
+PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB = NULL;
+PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB = NULL;
+PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB = NULL;
+PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB = NULL;
+PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB = NULL;
+PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB = NULL;
+PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB = NULL;
+PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB = NULL;
+PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB = NULL;
+PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB = NULL;
+PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB = NULL;
+PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB = NULL;
+PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB = NULL;
+PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB = NULL;
+PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB = NULL;
+PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB = NULL;
+PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB = NULL;
+PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB = NULL;
+PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB = NULL;
+PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB = NULL;
+PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB = NULL;
+PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB = NULL;
+PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB = NULL;
+PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB = NULL;
+PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB = NULL;
+PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB = NULL;
+PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB = NULL;
+PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB = NULL;
+PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB = NULL;
+PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB = NULL;
+PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB = NULL;
+PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB = NULL;
+PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB = NULL;
+PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB = NULL;
+PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB = NULL;
+PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB = NULL;
+PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB = NULL;
+PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB = NULL;
+PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB = NULL;
+PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB = NULL;
+PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB = NULL;
+PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB = NULL;
+
+PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB = NULL;
+PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB = NULL;
+PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB = NULL;
+
+PFNGLCOLORP3UIPROC __glewColorP3ui = NULL;
+PFNGLCOLORP3UIVPROC __glewColorP3uiv = NULL;
+PFNGLCOLORP4UIPROC __glewColorP4ui = NULL;
+PFNGLCOLORP4UIVPROC __glewColorP4uiv = NULL;
+PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui = NULL;
+PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv = NULL;
+PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui = NULL;
+PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv = NULL;
+PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui = NULL;
+PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv = NULL;
+PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui = NULL;
+PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv = NULL;
+PFNGLNORMALP3UIPROC __glewNormalP3ui = NULL;
+PFNGLNORMALP3UIVPROC __glewNormalP3uiv = NULL;
+PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui = NULL;
+PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv = NULL;
+PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui = NULL;
+PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv = NULL;
+PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui = NULL;
+PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv = NULL;
+PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui = NULL;
+PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv = NULL;
+PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui = NULL;
+PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv = NULL;
+PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui = NULL;
+PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv = NULL;
+PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui = NULL;
+PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv = NULL;
+PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui = NULL;
+PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv = NULL;
+PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui = NULL;
+PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv = NULL;
+PFNGLVERTEXP2UIPROC __glewVertexP2ui = NULL;
+PFNGLVERTEXP2UIVPROC __glewVertexP2uiv = NULL;
+PFNGLVERTEXP3UIPROC __glewVertexP3ui = NULL;
+PFNGLVERTEXP3UIVPROC __glewVertexP3uiv = NULL;
+PFNGLVERTEXP4UIPROC __glewVertexP4ui = NULL;
+PFNGLVERTEXP4UIVPROC __glewVertexP4uiv = NULL;
+
+PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv = NULL;
+PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed = NULL;
+PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v = NULL;
+PFNGLGETFLOATI_VPROC __glewGetFloati_v = NULL;
+PFNGLSCISSORARRAYVPROC __glewScissorArrayv = NULL;
+PFNGLSCISSORINDEXEDPROC __glewScissorIndexed = NULL;
+PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv = NULL;
+PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv = NULL;
+PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf = NULL;
+PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv = NULL;
+
+PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB = NULL;
+PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB = NULL;
+PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB = NULL;
+PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB = NULL;
+PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB = NULL;
+PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB = NULL;
+PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB = NULL;
+PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB = NULL;
+PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB = NULL;
+PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB = NULL;
+PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB = NULL;
+PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB = NULL;
+PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB = NULL;
+PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB = NULL;
+PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB = NULL;
+PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB = NULL;
+
+PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI = NULL;
+
+PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI = NULL;
+PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI = NULL;
+PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI = NULL;
+
+PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI = NULL;
+PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI = NULL;
+PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI = NULL;
+PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI = NULL;
+
+PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI = NULL;
+PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI = NULL;
+PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI = NULL;
+PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI = NULL;
+PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI = NULL;
+PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI = NULL;
+PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI = NULL;
+PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI = NULL;
+PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI = NULL;
+PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI = NULL;
+PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI = NULL;
+PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI = NULL;
+PFNGLSAMPLEMAPATIPROC __glewSampleMapATI = NULL;
+PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI = NULL;
+
+PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI = NULL;
+PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI = NULL;
+
+PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI = NULL;
+PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI = NULL;
+
+PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI = NULL;
+PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI = NULL;
+
+PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI = NULL;
+PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI = NULL;
+PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI = NULL;
+PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI = NULL;
+PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI = NULL;
+PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI = NULL;
+PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI = NULL;
+PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI = NULL;
+PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI = NULL;
+PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI = NULL;
+PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI = NULL;
+PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI = NULL;
+
+PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI = NULL;
+PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI = NULL;
+PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI = NULL;
+
+PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI = NULL;
+PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI = NULL;
+PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI = NULL;
+PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI = NULL;
+PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI = NULL;
+PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI = NULL;
+PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI = NULL;
+PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI = NULL;
+PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI = NULL;
+PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI = NULL;
+PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI = NULL;
+PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI = NULL;
+PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI = NULL;
+PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI = NULL;
+PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI = NULL;
+PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI = NULL;
+PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI = NULL;
+PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI = NULL;
+PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI = NULL;
+PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI = NULL;
+PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI = NULL;
+PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI = NULL;
+PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI = NULL;
+PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI = NULL;
+PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI = NULL;
+PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI = NULL;
+PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI = NULL;
+PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI = NULL;
+PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI = NULL;
+PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI = NULL;
+PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI = NULL;
+PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI = NULL;
+PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI = NULL;
+PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI = NULL;
+PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI = NULL;
+PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI = NULL;
+PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI = NULL;
+PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI = NULL;
+PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI = NULL;
+PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI = NULL;
+PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI = NULL;
+PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI = NULL;
+PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI = NULL;
+PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI = NULL;
+PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC __glewDrawArraysInstancedBaseInstanceEXT = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseInstanceEXT = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseVertexBaseInstanceEXT = NULL;
+
+PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT = NULL;
+PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT = NULL;
+PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT = NULL;
+
+PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT = NULL;
+
+PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT = NULL;
+
+PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC __glewBindFragDataLocationIndexedEXT = NULL;
+PFNGLGETFRAGDATAINDEXEXTPROC __glewGetFragDataIndexEXT = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC __glewGetProgramResourceLocationIndexEXT = NULL;
+
+PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT = NULL;
+
+PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT = NULL;
+
+PFNGLBUFFERSTORAGEEXTPROC __glewBufferStorageEXT = NULL;
+PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT = NULL;
+
+PFNGLCLEARTEXIMAGEEXTPROC __glewClearTexImageEXT = NULL;
+PFNGLCLEARTEXSUBIMAGEEXTPROC __glewClearTexSubImageEXT = NULL;
+
+PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT = NULL;
+PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT = NULL;
+
+PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT = NULL;
+PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT = NULL;
+
+PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT = NULL;
+PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT = NULL;
+PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT = NULL;
+PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT = NULL;
+PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT = NULL;
+PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT = NULL;
+PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT = NULL;
+PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT = NULL;
+PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT = NULL;
+
+PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT = NULL;
+PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT = NULL;
+
+PFNGLCOPYIMAGESUBDATAEXTPROC __glewCopyImageSubDataEXT = NULL;
+
+PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT = NULL;
+PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT = NULL;
+
+PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT = NULL;
+PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT = NULL;
+
+PFNGLGETOBJECTLABELEXTPROC __glewGetObjectLabelEXT = NULL;
+PFNGLLABELOBJECTEXTPROC __glewLabelObjectEXT = NULL;
+
+PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT = NULL;
+PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT = NULL;
+PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT = NULL;
+
+PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT = NULL;
+
+PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT = NULL;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT = NULL;
+PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT = NULL;
+PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT = NULL;
+PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT = NULL;
+PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT = NULL;
+PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT = NULL;
+PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT = NULL;
+PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT = NULL;
+PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT = NULL;
+PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL;
+PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT = NULL;
+PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT = NULL;
+PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT = NULL;
+PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT = NULL;
+PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT = NULL;
+PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT = NULL;
+PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT = NULL;
+PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT = NULL;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT = NULL;
+PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT = NULL;
+PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT = NULL;
+PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL;
+PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT = NULL;
+PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT = NULL;
+PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT = NULL;
+PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT = NULL;
+PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT = NULL;
+PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT = NULL;
+PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT = NULL;
+PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT = NULL;
+PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT = NULL;
+PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT = NULL;
+PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT = NULL;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT = NULL;
+PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT = NULL;
+PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT = NULL;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT = NULL;
+PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT = NULL;
+PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT = NULL;
+PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL;
+PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL;
+PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT = NULL;
+PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL;
+PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT = NULL;
+PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT = NULL;
+PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT = NULL;
+PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT = NULL;
+PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT = NULL;
+PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT = NULL;
+PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT = NULL;
+PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT = NULL;
+PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT = NULL;
+PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT = NULL;
+PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT = NULL;
+PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT = NULL;
+PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT = NULL;
+PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT = NULL;
+PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT = NULL;
+PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT = NULL;
+PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT = NULL;
+PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT = NULL;
+PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT = NULL;
+PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT = NULL;
+PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT = NULL;
+PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT = NULL;
+PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT = NULL;
+PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT = NULL;
+PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT = NULL;
+PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT = NULL;
+PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT = NULL;
+PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT = NULL;
+PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT = NULL;
+PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT = NULL;
+PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT = NULL;
+PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT = NULL;
+PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT = NULL;
+PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT = NULL;
+PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT = NULL;
+PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT = NULL;
+PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT = NULL;
+PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT = NULL;
+PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT = NULL;
+PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT = NULL;
+PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT = NULL;
+PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT = NULL;
+PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT = NULL;
+PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT = NULL;
+PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT = NULL;
+PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT = NULL;
+PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT = NULL;
+PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT = NULL;
+PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT = NULL;
+PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT = NULL;
+PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT = NULL;
+PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT = NULL;
+PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT = NULL;
+PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT = NULL;
+PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT = NULL;
+PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT = NULL;
+PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT = NULL;
+PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT = NULL;
+PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT = NULL;
+PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT = NULL;
+PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT = NULL;
+PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT = NULL;
+PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT = NULL;
+PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT = NULL;
+PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT = NULL;
+PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT = NULL;
+PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT = NULL;
+PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT = NULL;
+PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT = NULL;
+PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT = NULL;
+PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT = NULL;
+PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT = NULL;
+PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT = NULL;
+PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT = NULL;
+PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT = NULL;
+PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT = NULL;
+PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT = NULL;
+PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT = NULL;
+PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT = NULL;
+PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT = NULL;
+PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT = NULL;
+PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT = NULL;
+PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT = NULL;
+PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT = NULL;
+PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT = NULL;
+PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT = NULL;
+PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT = NULL;
+PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT = NULL;
+PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT = NULL;
+PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT = NULL;
+PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC __glewVertexArrayVertexAttribDivisorEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT = NULL;
+
+PFNGLDISCARDFRAMEBUFFEREXTPROC __glewDiscardFramebufferEXT = NULL;
+
+PFNGLDRAWBUFFERSEXTPROC __glewDrawBuffersEXT = NULL;
+
+PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT = NULL;
+PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT = NULL;
+PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT = NULL;
+PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT = NULL;
+PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT = NULL;
+PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT = NULL;
+
+PFNGLBLENDEQUATIONSEPARATEIEXTPROC __glewBlendEquationSeparateiEXT = NULL;
+PFNGLBLENDEQUATIONIEXTPROC __glewBlendEquationiEXT = NULL;
+PFNGLBLENDFUNCSEPARATEIEXTPROC __glewBlendFuncSeparateiEXT = NULL;
+PFNGLBLENDFUNCIEXTPROC __glewBlendFunciEXT = NULL;
+PFNGLCOLORMASKIEXTPROC __glewColorMaskiEXT = NULL;
+PFNGLDISABLEIEXTPROC __glewDisableiEXT = NULL;
+PFNGLENABLEIEXTPROC __glewEnableiEXT = NULL;
+PFNGLISENABLEDIEXTPROC __glewIsEnablediEXT = NULL;
+
+PFNGLDRAWELEMENTSBASEVERTEXEXTPROC __glewDrawElementsBaseVertexEXT = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC __glewDrawElementsInstancedBaseVertexEXT = NULL;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC __glewDrawRangeElementsBaseVertexEXT = NULL;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC __glewMultiDrawElementsBaseVertexEXT = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT = NULL;
+PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT = NULL;
+
+PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT = NULL;
+
+PFNGLBUFFERSTORAGEEXTERNALEXTPROC __glewBufferStorageExternalEXT = NULL;
+PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC __glewNamedBufferStorageExternalEXT = NULL;
+
+PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT = NULL;
+PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT = NULL;
+PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT = NULL;
+PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT = NULL;
+PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT = NULL;
+
+PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT = NULL;
+PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT = NULL;
+PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT = NULL;
+PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT = NULL;
+PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT = NULL;
+PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT = NULL;
+PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT = NULL;
+PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT = NULL;
+PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT = NULL;
+PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT = NULL;
+PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT = NULL;
+PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT = NULL;
+PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT = NULL;
+PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT = NULL;
+
+PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT = NULL;
+
+PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT = NULL;
+PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT = NULL;
+PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT = NULL;
+PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT = NULL;
+PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT = NULL;
+PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT = NULL;
+PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT = NULL;
+PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT = NULL;
+PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT = NULL;
+PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT = NULL;
+PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT = NULL;
+PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT = NULL;
+PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT = NULL;
+PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT = NULL;
+
+PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT = NULL;
+PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT = NULL;
+
+PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT = NULL;
+PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT = NULL;
+PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT = NULL;
+PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT = NULL;
+PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT = NULL;
+PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT = NULL;
+PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT = NULL;
+PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT = NULL;
+PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT = NULL;
+PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT = NULL;
+PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT = NULL;
+PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT = NULL;
+PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT = NULL;
+PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT = NULL;
+PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT = NULL;
+PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT = NULL;
+PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT = NULL;
+PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT = NULL;
+PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT = NULL;
+PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT = NULL;
+PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT = NULL;
+PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT = NULL;
+PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT = NULL;
+PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT = NULL;
+PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT = NULL;
+PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT = NULL;
+PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT = NULL;
+PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT = NULL;
+PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT = NULL;
+PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT = NULL;
+PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT = NULL;
+PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT = NULL;
+PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT = NULL;
+PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT = NULL;
+
+PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT = NULL;
+PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT = NULL;
+PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT = NULL;
+PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT = NULL;
+PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT = NULL;
+PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT = NULL;
+PFNGLHISTOGRAMEXTPROC __glewHistogramEXT = NULL;
+PFNGLMINMAXEXTPROC __glewMinmaxEXT = NULL;
+PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT = NULL;
+PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT = NULL;
+
+PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT = NULL;
+
+PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT = NULL;
+
+PFNGLVERTEXATTRIBDIVISOREXTPROC __glewVertexAttribDivisorEXT = NULL;
+
+PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT = NULL;
+PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT = NULL;
+PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT = NULL;
+
+PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC __glewFlushMappedBufferRangeEXT = NULL;
+PFNGLMAPBUFFERRANGEEXTPROC __glewMapBufferRangeEXT = NULL;
+
+PFNGLBUFFERSTORAGEMEMEXTPROC __glewBufferStorageMemEXT = NULL;
+PFNGLCREATEMEMORYOBJECTSEXTPROC __glewCreateMemoryObjectsEXT = NULL;
+PFNGLDELETEMEMORYOBJECTSEXTPROC __glewDeleteMemoryObjectsEXT = NULL;
+PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC __glewGetMemoryObjectParameterivEXT = NULL;
+PFNGLGETUNSIGNEDBYTEI_VEXTPROC __glewGetUnsignedBytei_vEXT = NULL;
+PFNGLGETUNSIGNEDBYTEVEXTPROC __glewGetUnsignedBytevEXT = NULL;
+PFNGLISMEMORYOBJECTEXTPROC __glewIsMemoryObjectEXT = NULL;
+PFNGLMEMORYOBJECTPARAMETERIVEXTPROC __glewMemoryObjectParameterivEXT = NULL;
+PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC __glewNamedBufferStorageMemEXT = NULL;
+PFNGLTEXSTORAGEMEM1DEXTPROC __glewTexStorageMem1DEXT = NULL;
+PFNGLTEXSTORAGEMEM2DEXTPROC __glewTexStorageMem2DEXT = NULL;
+PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC __glewTexStorageMem2DMultisampleEXT = NULL;
+PFNGLTEXSTORAGEMEM3DEXTPROC __glewTexStorageMem3DEXT = NULL;
+PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC __glewTexStorageMem3DMultisampleEXT = NULL;
+PFNGLTEXTURESTORAGEMEM1DEXTPROC __glewTextureStorageMem1DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM2DEXTPROC __glewTextureStorageMem2DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC __glewTextureStorageMem2DMultisampleEXT = NULL;
+PFNGLTEXTURESTORAGEMEM3DEXTPROC __glewTextureStorageMem3DEXT = NULL;
+PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC __glewTextureStorageMem3DMultisampleEXT = NULL;
+
+PFNGLIMPORTMEMORYFDEXTPROC __glewImportMemoryFdEXT = NULL;
+
+PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC __glewImportMemoryWin32HandleEXT = NULL;
+PFNGLIMPORTMEMORYWIN32NAMEEXTPROC __glewImportMemoryWin32NameEXT = NULL;
+
+PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT = NULL;
+PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC __glewMultiDrawArraysIndirectEXT = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC __glewMultiDrawElementsIndirectEXT = NULL;
+
+PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT = NULL;
+PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT = NULL;
+
+PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC __glewFramebufferTexture2DMultisampleEXT = NULL;
+
+PFNGLDRAWBUFFERSINDEXEDEXTPROC __glewDrawBuffersIndexedEXT = NULL;
+PFNGLGETINTEGERI_VEXTPROC __glewGetIntegeri_vEXT = NULL;
+PFNGLREADBUFFERINDEXEDEXTPROC __glewReadBufferIndexedEXT = NULL;
+
+PFNGLCOLORTABLEEXTPROC __glewColorTableEXT = NULL;
+PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT = NULL;
+
+PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT = NULL;
+PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT = NULL;
+
+PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT = NULL;
+PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT = NULL;
+
+PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL;
+
+PFNGLPOLYGONOFFSETCLAMPEXTPROC __glewPolygonOffsetClampEXT = NULL;
+
+PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT = NULL;
+
+PFNGLCOVERAGEMODULATIONNVPROC __glewCoverageModulationNV = NULL;
+PFNGLCOVERAGEMODULATIONTABLENVPROC __glewCoverageModulationTableNV = NULL;
+PFNGLGETCOVERAGEMODULATIONTABLENVPROC __glewGetCoverageModulationTableNV = NULL;
+PFNGLRASTERSAMPLESEXTPROC __glewRasterSamplesEXT = NULL;
+
+PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL;
+PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL;
+
+PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT = NULL;
+PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT = NULL;
+PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT = NULL;
+PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT = NULL;
+PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT = NULL;
+PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT = NULL;
+PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT = NULL;
+PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT = NULL;
+PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT = NULL;
+PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT = NULL;
+PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT = NULL;
+PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT = NULL;
+PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT = NULL;
+PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT = NULL;
+PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT = NULL;
+PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL;
+PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL;
+
+PFNGLDELETESEMAPHORESEXTPROC __glewDeleteSemaphoresEXT = NULL;
+PFNGLGENSEMAPHORESEXTPROC __glewGenSemaphoresEXT = NULL;
+PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC __glewGetSemaphoreParameterui64vEXT = NULL;
+PFNGLISSEMAPHOREEXTPROC __glewIsSemaphoreEXT = NULL;
+PFNGLSEMAPHOREPARAMETERUI64VEXTPROC __glewSemaphoreParameterui64vEXT = NULL;
+PFNGLSIGNALSEMAPHOREEXTPROC __glewSignalSemaphoreEXT = NULL;
+PFNGLWAITSEMAPHOREEXTPROC __glewWaitSemaphoreEXT = NULL;
+
+PFNGLIMPORTSEMAPHOREFDEXTPROC __glewImportSemaphoreFdEXT = NULL;
+
+PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC __glewImportSemaphoreWin32HandleEXT = NULL;
+PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC __glewImportSemaphoreWin32NameEXT = NULL;
+
+PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT = NULL;
+PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT = NULL;
+PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT = NULL;
+
+PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT = NULL;
+PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT = NULL;
+
+PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC __glewClearPixelLocalStorageuiEXT = NULL;
+PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewFramebufferPixelLocalStorageSizeEXT = NULL;
+PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewGetFramebufferPixelLocalStorageSizeEXT = NULL;
+
+PFNGLTEXPAGECOMMITMENTEXTPROC __glewTexPageCommitmentEXT = NULL;
+PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT = NULL;
+
+PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL;
+
+PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL;
+PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL;
+PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL;
+
+PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL;
+
+PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT = NULL;
+
+PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT = NULL;
+
+PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT = NULL;
+PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT = NULL;
+PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT = NULL;
+PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT = NULL;
+PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT = NULL;
+PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT = NULL;
+
+PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT = NULL;
+PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT = NULL;
+PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT = NULL;
+PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT = NULL;
+PFNGLISTEXTUREEXTPROC __glewIsTextureEXT = NULL;
+PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT = NULL;
+
+PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT = NULL;
+
+PFNGLTEXSTORAGE1DEXTPROC __glewTexStorage1DEXT = NULL;
+PFNGLTEXSTORAGE2DEXTPROC __glewTexStorage2DEXT = NULL;
+PFNGLTEXSTORAGE3DEXTPROC __glewTexStorage3DEXT = NULL;
+PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT = NULL;
+PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT = NULL;
+PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT = NULL;
+
+PFNGLTEXTUREVIEWEXTPROC __glewTextureViewEXT = NULL;
+
+PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT = NULL;
+PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT = NULL;
+
+PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT = NULL;
+PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT = NULL;
+PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT = NULL;
+PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT = NULL;
+PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT = NULL;
+
+PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT = NULL;
+PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT = NULL;
+PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT = NULL;
+PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT = NULL;
+PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL;
+PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL;
+PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL;
+PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL;
+
+PFNGLBINDARRAYSETEXTPROC __glewBindArraySetEXT = NULL;
+PFNGLCREATEARRAYSETEXTPROC __glewCreateArraySetExt = NULL;
+PFNGLDELETEARRAYSETSEXTPROC __glewDeleteArraySetsEXT = NULL;
+
+PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT = NULL;
+PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT = NULL;
+PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT = NULL;
+PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT = NULL;
+PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT = NULL;
+PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT = NULL;
+PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT = NULL;
+PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT = NULL;
+PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT = NULL;
+PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT = NULL;
+
+PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT = NULL;
+PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT = NULL;
+PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT = NULL;
+PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT = NULL;
+PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT = NULL;
+PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT = NULL;
+PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT = NULL;
+PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT = NULL;
+PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT = NULL;
+PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT = NULL;
+PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT = NULL;
+PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT = NULL;
+PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT = NULL;
+PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT = NULL;
+PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT = NULL;
+PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT = NULL;
+PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT = NULL;
+PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT = NULL;
+PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT = NULL;
+PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT = NULL;
+PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT = NULL;
+PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT = NULL;
+PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT = NULL;
+PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT = NULL;
+PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT = NULL;
+PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT = NULL;
+PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT = NULL;
+PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT = NULL;
+PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT = NULL;
+PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT = NULL;
+PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT = NULL;
+PFNGLSWIZZLEEXTPROC __glewSwizzleEXT = NULL;
+PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT = NULL;
+PFNGLVARIANTBVEXTPROC __glewVariantbvEXT = NULL;
+PFNGLVARIANTDVEXTPROC __glewVariantdvEXT = NULL;
+PFNGLVARIANTFVEXTPROC __glewVariantfvEXT = NULL;
+PFNGLVARIANTIVEXTPROC __glewVariantivEXT = NULL;
+PFNGLVARIANTSVEXTPROC __glewVariantsvEXT = NULL;
+PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT = NULL;
+PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT = NULL;
+PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT = NULL;
+PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT = NULL;
+
+PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL;
+PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL;
+PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL;
+
+PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC __glewAcquireKeyedMutexWin32EXT = NULL;
+PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC __glewReleaseKeyedMutexWin32EXT = NULL;
+
+PFNGLWINDOWRECTANGLESEXTPROC __glewWindowRectanglesEXT = NULL;
+
+PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT = NULL;
+
+PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY = NULL;
+
+PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY = NULL;
+
+PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP = NULL;
+PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP = NULL;
+
+PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM = NULL;
+PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM = NULL;
+
+PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM = NULL;
+PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM = NULL;
+PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM = NULL;
+PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM = NULL;
+PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM = NULL;
+PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM = NULL;
+PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM = NULL;
+PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM = NULL;
+
+PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL = NULL;
+PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL = NULL;
+PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL = NULL;
+
+PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL;
+PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL;
+PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL;
+PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL;
+
+PFNGLBEGINPERFQUERYINTELPROC __glewBeginPerfQueryINTEL = NULL;
+PFNGLCREATEPERFQUERYINTELPROC __glewCreatePerfQueryINTEL = NULL;
+PFNGLDELETEPERFQUERYINTELPROC __glewDeletePerfQueryINTEL = NULL;
+PFNGLENDPERFQUERYINTELPROC __glewEndPerfQueryINTEL = NULL;
+PFNGLGETFIRSTPERFQUERYIDINTELPROC __glewGetFirstPerfQueryIdINTEL = NULL;
+PFNGLGETNEXTPERFQUERYIDINTELPROC __glewGetNextPerfQueryIdINTEL = NULL;
+PFNGLGETPERFCOUNTERINFOINTELPROC __glewGetPerfCounterInfoINTEL = NULL;
+PFNGLGETPERFQUERYDATAINTELPROC __glewGetPerfQueryDataINTEL = NULL;
+PFNGLGETPERFQUERYIDBYNAMEINTELPROC __glewGetPerfQueryIdByNameINTEL = NULL;
+PFNGLGETPERFQUERYINFOINTELPROC __glewGetPerfQueryInfoINTEL = NULL;
+
+PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL;
+PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL;
+
+PFNGLBLENDBARRIERKHRPROC __glewBlendBarrierKHR = NULL;
+
+PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback = NULL;
+PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl = NULL;
+PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert = NULL;
+PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog = NULL;
+PFNGLGETOBJECTLABELPROC __glewGetObjectLabel = NULL;
+PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel = NULL;
+PFNGLOBJECTLABELPROC __glewObjectLabel = NULL;
+PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel = NULL;
+PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup = NULL;
+PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup = NULL;
+
+PFNGLMAXSHADERCOMPILERTHREADSKHRPROC __glewMaxShaderCompilerThreadsKHR = NULL;
+
+PFNGLGETNUNIFORMFVPROC __glewGetnUniformfv = NULL;
+PFNGLGETNUNIFORMIVPROC __glewGetnUniformiv = NULL;
+PFNGLGETNUNIFORMUIVPROC __glewGetnUniformuiv = NULL;
+PFNGLREADNPIXELSPROC __glewReadnPixels = NULL;
+
+PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled = NULL;
+PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion = NULL;
+PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion = NULL;
+PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion = NULL;
+PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion = NULL;
+
+PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA = NULL;
+
+PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA = NULL;
+PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA = NULL;
+PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA = NULL;
+PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA = NULL;
+PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA = NULL;
+PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA = NULL;
+PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA = NULL;
+PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA = NULL;
+PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA = NULL;
+PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA = NULL;
+PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA = NULL;
+PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA = NULL;
+PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA = NULL;
+PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA = NULL;
+PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA = NULL;
+PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA = NULL;
+PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA = NULL;
+PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA = NULL;
+PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA = NULL;
+PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA = NULL;
+PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA = NULL;
+PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA = NULL;
+PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA = NULL;
+PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL;
+
+PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX = NULL;
+PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX = NULL;
+
+PFNGLLGPUCOPYIMAGESUBDATANVXPROC __glewLGPUCopyImageSubDataNVX = NULL;
+PFNGLLGPUINTERLOCKNVXPROC __glewLGPUInterlockNVX = NULL;
+PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC __glewLGPUNamedBufferSubDataNVX = NULL;
+
+PFNGLSTEREOPARAMETERFNVPROC __glewStereoParameterfNV = NULL;
+PFNGLSTEREOPARAMETERINVPROC __glewStereoParameteriNV = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawArraysIndirectBindlessCountNV = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawElementsIndirectBindlessCountNV = NULL;
+
+PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV = NULL;
+PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV = NULL;
+PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV = NULL;
+PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV = NULL;
+PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV = NULL;
+PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV = NULL;
+PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV = NULL;
+PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV = NULL;
+PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV = NULL;
+PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV = NULL;
+PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV = NULL;
+
+PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV = NULL;
+PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV = NULL;
+
+PFNGLVIEWPORTPOSITIONWSCALENVPROC __glewViewportPositionWScaleNV = NULL;
+
+PFNGLCALLCOMMANDLISTNVPROC __glewCallCommandListNV = NULL;
+PFNGLCOMMANDLISTSEGMENTSNVPROC __glewCommandListSegmentsNV = NULL;
+PFNGLCOMPILECOMMANDLISTNVPROC __glewCompileCommandListNV = NULL;
+PFNGLCREATECOMMANDLISTSNVPROC __glewCreateCommandListsNV = NULL;
+PFNGLCREATESTATESNVPROC __glewCreateStatesNV = NULL;
+PFNGLDELETECOMMANDLISTSNVPROC __glewDeleteCommandListsNV = NULL;
+PFNGLDELETESTATESNVPROC __glewDeleteStatesNV = NULL;
+PFNGLDRAWCOMMANDSADDRESSNVPROC __glewDrawCommandsAddressNV = NULL;
+PFNGLDRAWCOMMANDSNVPROC __glewDrawCommandsNV = NULL;
+PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC __glewDrawCommandsStatesAddressNV = NULL;
+PFNGLDRAWCOMMANDSSTATESNVPROC __glewDrawCommandsStatesNV = NULL;
+PFNGLGETCOMMANDHEADERNVPROC __glewGetCommandHeaderNV = NULL;
+PFNGLGETSTAGEINDEXNVPROC __glewGetStageIndexNV = NULL;
+PFNGLISCOMMANDLISTNVPROC __glewIsCommandListNV = NULL;
+PFNGLISSTATENVPROC __glewIsStateNV = NULL;
+PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC __glewListDrawCommandsStatesClientNV = NULL;
+PFNGLSTATECAPTURENVPROC __glewStateCaptureNV = NULL;
+
+PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL;
+PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL;
+
+PFNGLSUBPIXELPRECISIONBIASNVPROC __glewSubpixelPrecisionBiasNV = NULL;
+
+PFNGLCONSERVATIVERASTERPARAMETERFNVPROC __glewConservativeRasterParameterfNV = NULL;
+
+PFNGLCONSERVATIVERASTERPARAMETERINVPROC __glewConservativeRasterParameteriNV = NULL;
+
+PFNGLCOPYBUFFERSUBDATANVPROC __glewCopyBufferSubDataNV = NULL;
+
+PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV = NULL;
+
+PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL;
+PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL;
+PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL;
+
+PFNGLDRAWBUFFERSNVPROC __glewDrawBuffersNV = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDNVPROC __glewDrawArraysInstancedNV = NULL;
+PFNGLDRAWELEMENTSINSTANCEDNVPROC __glewDrawElementsInstancedNV = NULL;
+
+PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV = NULL;
+
+PFNGLDRAWVKIMAGENVPROC __glewDrawVkImageNV = NULL;
+PFNGLGETVKPROCADDRNVPROC __glewGetVkProcAddrNV = NULL;
+PFNGLSIGNALVKFENCENVPROC __glewSignalVkFenceNV = NULL;
+PFNGLSIGNALVKSEMAPHORENVPROC __glewSignalVkSemaphoreNV = NULL;
+PFNGLWAITVKSEMAPHORENVPROC __glewWaitVkSemaphoreNV = NULL;
+
+PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL;
+PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL;
+PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL;
+PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV = NULL;
+PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV = NULL;
+PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV = NULL;
+PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV = NULL;
+PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV = NULL;
+PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV = NULL;
+
+PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV = NULL;
+PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV = NULL;
+PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV = NULL;
+
+PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV = NULL;
+PFNGLFINISHFENCENVPROC __glewFinishFenceNV = NULL;
+PFNGLGENFENCESNVPROC __glewGenFencesNV = NULL;
+PFNGLGETFENCEIVNVPROC __glewGetFenceivNV = NULL;
+PFNGLISFENCENVPROC __glewIsFenceNV = NULL;
+PFNGLSETFENCENVPROC __glewSetFenceNV = NULL;
+PFNGLTESTFENCENVPROC __glewTestFenceNV = NULL;
+
+PFNGLFRAGMENTCOVERAGECOLORNVPROC __glewFragmentCoverageColorNV = NULL;
+
+PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV = NULL;
+PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV = NULL;
+
+PFNGLBLITFRAMEBUFFERNVPROC __glewBlitFramebufferNV = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC __glewRenderbufferStorageMultisampleNV = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV = NULL;
+
+PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV = NULL;
+
+PFNGLMULTICASTBARRIERNVPROC __glewMulticastBarrierNV = NULL;
+PFNGLMULTICASTBLITFRAMEBUFFERNVPROC __glewMulticastBlitFramebufferNV = NULL;
+PFNGLMULTICASTBUFFERSUBDATANVPROC __glewMulticastBufferSubDataNV = NULL;
+PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC __glewMulticastCopyBufferSubDataNV = NULL;
+PFNGLMULTICASTCOPYIMAGESUBDATANVPROC __glewMulticastCopyImageSubDataNV = NULL;
+PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewMulticastFramebufferSampleLocationsfvNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC __glewMulticastGetQueryObjecti64vNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTIVNVPROC __glewMulticastGetQueryObjectivNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC __glewMulticastGetQueryObjectui64vNV = NULL;
+PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC __glewMulticastGetQueryObjectuivNV = NULL;
+PFNGLMULTICASTWAITSYNCNVPROC __glewMulticastWaitSyncNV = NULL;
+PFNGLRENDERGPUMASKNVPROC __glewRenderGpuMaskNV = NULL;
+
+PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV = NULL;
+PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV = NULL;
+PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV = NULL;
+
+PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV = NULL;
+PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV = NULL;
+PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV = NULL;
+PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV = NULL;
+PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV = NULL;
+PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV = NULL;
+PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV = NULL;
+PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV = NULL;
+PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV = NULL;
+PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV = NULL;
+PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV = NULL;
+PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV = NULL;
+PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV = NULL;
+PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV = NULL;
+PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV = NULL;
+PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV = NULL;
+PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV = NULL;
+PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV = NULL;
+PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV = NULL;
+PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV = NULL;
+PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV = NULL;
+PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV = NULL;
+PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV = NULL;
+PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV = NULL;
+PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV = NULL;
+PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV = NULL;
+PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV = NULL;
+PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV = NULL;
+PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV = NULL;
+PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV = NULL;
+PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV = NULL;
+
+PFNGLCOLOR3HNVPROC __glewColor3hNV = NULL;
+PFNGLCOLOR3HVNVPROC __glewColor3hvNV = NULL;
+PFNGLCOLOR4HNVPROC __glewColor4hNV = NULL;
+PFNGLCOLOR4HVNVPROC __glewColor4hvNV = NULL;
+PFNGLFOGCOORDHNVPROC __glewFogCoordhNV = NULL;
+PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV = NULL;
+PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV = NULL;
+PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV = NULL;
+PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV = NULL;
+PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV = NULL;
+PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV = NULL;
+PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV = NULL;
+PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV = NULL;
+PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV = NULL;
+PFNGLNORMAL3HNVPROC __glewNormal3hNV = NULL;
+PFNGLNORMAL3HVNVPROC __glewNormal3hvNV = NULL;
+PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV = NULL;
+PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV = NULL;
+PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV = NULL;
+PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV = NULL;
+PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV = NULL;
+PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV = NULL;
+PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV = NULL;
+PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV = NULL;
+PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV = NULL;
+PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV = NULL;
+PFNGLVERTEX2HNVPROC __glewVertex2hNV = NULL;
+PFNGLVERTEX2HVNVPROC __glewVertex2hvNV = NULL;
+PFNGLVERTEX3HNVPROC __glewVertex3hNV = NULL;
+PFNGLVERTEX3HVNVPROC __glewVertex3hvNV = NULL;
+PFNGLVERTEX4HNVPROC __glewVertex4hNV = NULL;
+PFNGLVERTEX4HVNVPROC __glewVertex4hvNV = NULL;
+PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV = NULL;
+PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV = NULL;
+PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV = NULL;
+PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV = NULL;
+PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV = NULL;
+PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV = NULL;
+PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV = NULL;
+PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV = NULL;
+PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV = NULL;
+PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV = NULL;
+PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV = NULL;
+PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV = NULL;
+PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV = NULL;
+PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV = NULL;
+
+PFNGLVERTEXATTRIBDIVISORNVPROC __glewVertexAttribDivisorNV = NULL;
+
+PFNGLGETINTERNALFORMATSAMPLEIVNVPROC __glewGetInternalformatSampleivNV = NULL;
+
+PFNGLUNIFORMMATRIX2X3FVNVPROC __glewUniformMatrix2x3fvNV = NULL;
+PFNGLUNIFORMMATRIX2X4FVNVPROC __glewUniformMatrix2x4fvNV = NULL;
+PFNGLUNIFORMMATRIX3X2FVNVPROC __glewUniformMatrix3x2fvNV = NULL;
+PFNGLUNIFORMMATRIX3X4FVNVPROC __glewUniformMatrix3x4fvNV = NULL;
+PFNGLUNIFORMMATRIX4X2FVNVPROC __glewUniformMatrix4x2fvNV = NULL;
+PFNGLUNIFORMMATRIX4X3FVNVPROC __glewUniformMatrix4x3fvNV = NULL;
+
+PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV = NULL;
+PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV = NULL;
+PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV = NULL;
+PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV = NULL;
+PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV = NULL;
+PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV = NULL;
+PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV = NULL;
+
+PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV = NULL;
+PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV = NULL;
+PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV = NULL;
+
+PFNGLCOPYPATHNVPROC __glewCopyPathNV = NULL;
+PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV = NULL;
+PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV = NULL;
+PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV = NULL;
+PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV = NULL;
+PFNGLDELETEPATHSNVPROC __glewDeletePathsNV = NULL;
+PFNGLGENPATHSNVPROC __glewGenPathsNV = NULL;
+PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV = NULL;
+PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV = NULL;
+PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV = NULL;
+PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV = NULL;
+PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV = NULL;
+PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV = NULL;
+PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV = NULL;
+PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV = NULL;
+PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV = NULL;
+PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV = NULL;
+PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV = NULL;
+PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV = NULL;
+PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV = NULL;
+PFNGLGETPROGRAMRESOURCEFVNVPROC __glewGetProgramResourcefvNV = NULL;
+PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV = NULL;
+PFNGLISPATHNVPROC __glewIsPathNV = NULL;
+PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV = NULL;
+PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV = NULL;
+PFNGLMATRIXLOAD3X2FNVPROC __glewMatrixLoad3x2fNV = NULL;
+PFNGLMATRIXLOAD3X3FNVPROC __glewMatrixLoad3x3fNV = NULL;
+PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC __glewMatrixLoadTranspose3x3fNV = NULL;
+PFNGLMATRIXMULT3X2FNVPROC __glewMatrixMult3x2fNV = NULL;
+PFNGLMATRIXMULT3X3FNVPROC __glewMatrixMult3x3fNV = NULL;
+PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC __glewMatrixMultTranspose3x3fNV = NULL;
+PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV = NULL;
+PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV = NULL;
+PFNGLPATHCOORDSNVPROC __glewPathCoordsNV = NULL;
+PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV = NULL;
+PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV = NULL;
+PFNGLPATHFOGGENNVPROC __glewPathFogGenNV = NULL;
+PFNGLPATHGLYPHINDEXARRAYNVPROC __glewPathGlyphIndexArrayNV = NULL;
+PFNGLPATHGLYPHINDEXRANGENVPROC __glewPathGlyphIndexRangeNV = NULL;
+PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV = NULL;
+PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV = NULL;
+PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC __glewPathMemoryGlyphIndexArrayNV = NULL;
+PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV = NULL;
+PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV = NULL;
+PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV = NULL;
+PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV = NULL;
+PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV = NULL;
+PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV = NULL;
+PFNGLPATHSTRINGNVPROC __glewPathStringNV = NULL;
+PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV = NULL;
+PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV = NULL;
+PFNGLPATHTEXGENNVPROC __glewPathTexGenNV = NULL;
+PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV = NULL;
+PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC __glewProgramPathFragmentInputGenNV = NULL;
+PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV = NULL;
+PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV = NULL;
+PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV = NULL;
+PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV = NULL;
+PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC __glewStencilThenCoverFillPathInstancedNV = NULL;
+PFNGLSTENCILTHENCOVERFILLPATHNVPROC __glewStencilThenCoverFillPathNV = NULL;
+PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC __glewStencilThenCoverStrokePathInstancedNV = NULL;
+PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC __glewStencilThenCoverStrokePathNV = NULL;
+PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV = NULL;
+PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV = NULL;
+
+PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV = NULL;
+PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV = NULL;
+
+PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV = NULL;
+PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV = NULL;
+
+PFNGLPOLYGONMODENVPROC __glewPolygonModeNV = NULL;
+
+PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV = NULL;
+PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV = NULL;
+PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV = NULL;
+PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV = NULL;
+PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV = NULL;
+PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV = NULL;
+
+PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL;
+PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL;
+
+PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV = NULL;
+PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV = NULL;
+PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV = NULL;
+PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV = NULL;
+PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV = NULL;
+PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV = NULL;
+PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV = NULL;
+PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV = NULL;
+PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV = NULL;
+PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV = NULL;
+PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV = NULL;
+PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV = NULL;
+PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV = NULL;
+
+PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL;
+PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL;
+
+PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewFramebufferSampleLocationsfvNV = NULL;
+PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewNamedFramebufferSampleLocationsfvNV = NULL;
+
+PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV = NULL;
+PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV = NULL;
+PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV = NULL;
+PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV = NULL;
+PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV = NULL;
+PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV = NULL;
+PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV = NULL;
+PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV = NULL;
+PFNGLUNIFORMUI64NVPROC __glewUniformui64NV = NULL;
+PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV = NULL;
+
+PFNGLCOMPRESSEDTEXIMAGE3DNVPROC __glewCompressedTexImage3DNV = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC __glewCompressedTexSubImage3DNV = NULL;
+PFNGLCOPYTEXSUBIMAGE3DNVPROC __glewCopyTexSubImage3DNV = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERNVPROC __glewFramebufferTextureLayerNV = NULL;
+PFNGLTEXIMAGE3DNVPROC __glewTexImage3DNV = NULL;
+PFNGLTEXSUBIMAGE3DNVPROC __glewTexSubImage3DNV = NULL;
+
+PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV = NULL;
+
+PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV = NULL;
+PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV = NULL;
+
+PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV = NULL;
+PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV = NULL;
+PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV = NULL;
+PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV = NULL;
+PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV = NULL;
+PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV = NULL;
+PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV = NULL;
+PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV = NULL;
+
+PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV = NULL;
+PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV = NULL;
+PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV = NULL;
+
+PFNGLVDPAUFININVPROC __glewVDPAUFiniNV = NULL;
+PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV = NULL;
+PFNGLVDPAUINITNVPROC __glewVDPAUInitNV = NULL;
+PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV = NULL;
+PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV = NULL;
+PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV = NULL;
+PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV = NULL;
+PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV = NULL;
+PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV = NULL;
+PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV = NULL;
+
+PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL;
+PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL;
+
+PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV = NULL;
+PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV = NULL;
+PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV = NULL;
+PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV = NULL;
+PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV = NULL;
+PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV = NULL;
+PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV = NULL;
+PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV = NULL;
+PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV = NULL;
+PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV = NULL;
+PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV = NULL;
+PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV = NULL;
+PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV = NULL;
+PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV = NULL;
+PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV = NULL;
+PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV = NULL;
+PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV = NULL;
+PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV = NULL;
+PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV = NULL;
+
+PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV = NULL;
+PFNGLCOLORFORMATNVPROC __glewColorFormatNV = NULL;
+PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV = NULL;
+PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV = NULL;
+PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV = NULL;
+PFNGLINDEXFORMATNVPROC __glewIndexFormatNV = NULL;
+PFNGLNORMALFORMATNVPROC __glewNormalFormatNV = NULL;
+PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV = NULL;
+PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV = NULL;
+PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV = NULL;
+PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV = NULL;
+PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV = NULL;
+
+PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL;
+PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL;
+PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL;
+PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV = NULL;
+PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV = NULL;
+PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV = NULL;
+PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV = NULL;
+PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV = NULL;
+PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV = NULL;
+PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV = NULL;
+PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV = NULL;
+PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV = NULL;
+PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV = NULL;
+PFNGLISPROGRAMNVPROC __glewIsProgramNV = NULL;
+PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV = NULL;
+PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV = NULL;
+PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV = NULL;
+PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV = NULL;
+PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV = NULL;
+PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV = NULL;
+PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV = NULL;
+PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV = NULL;
+PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV = NULL;
+PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV = NULL;
+PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV = NULL;
+PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV = NULL;
+PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV = NULL;
+PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV = NULL;
+PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV = NULL;
+PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV = NULL;
+PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV = NULL;
+PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV = NULL;
+PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV = NULL;
+PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV = NULL;
+PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV = NULL;
+PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV = NULL;
+PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV = NULL;
+PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV = NULL;
+PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV = NULL;
+PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV = NULL;
+PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV = NULL;
+PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV = NULL;
+PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV = NULL;
+PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV = NULL;
+PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV = NULL;
+PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV = NULL;
+PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV = NULL;
+PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV = NULL;
+PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV = NULL;
+PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV = NULL;
+PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV = NULL;
+PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV = NULL;
+PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV = NULL;
+PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV = NULL;
+PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV = NULL;
+PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV = NULL;
+PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV = NULL;
+PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV = NULL;
+PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV = NULL;
+PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV = NULL;
+PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV = NULL;
+PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV = NULL;
+PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV = NULL;
+
+PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV = NULL;
+PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV = NULL;
+PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV = NULL;
+PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV = NULL;
+PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV = NULL;
+PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV = NULL;
+
+PFNGLDEPTHRANGEARRAYFVNVPROC __glewDepthRangeArrayfvNV = NULL;
+PFNGLDEPTHRANGEINDEXEDFNVPROC __glewDepthRangeIndexedfNV = NULL;
+PFNGLDISABLEINVPROC __glewDisableiNV = NULL;
+PFNGLENABLEINVPROC __glewEnableiNV = NULL;
+PFNGLGETFLOATI_VNVPROC __glewGetFloati_vNV = NULL;
+PFNGLISENABLEDINVPROC __glewIsEnablediNV = NULL;
+PFNGLSCISSORARRAYVNVPROC __glewScissorArrayvNV = NULL;
+PFNGLSCISSORINDEXEDNVPROC __glewScissorIndexedNV = NULL;
+PFNGLSCISSORINDEXEDVNVPROC __glewScissorIndexedvNV = NULL;
+PFNGLVIEWPORTARRAYVNVPROC __glewViewportArrayvNV = NULL;
+PFNGLVIEWPORTINDEXEDFNVPROC __glewViewportIndexedfNV = NULL;
+PFNGLVIEWPORTINDEXEDFVNVPROC __glewViewportIndexedfvNV = NULL;
+
+PFNGLVIEWPORTSWIZZLENVPROC __glewViewportSwizzleNV = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __glewFramebufferTextureMultiviewOVR = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC __glewFramebufferTextureMultisampleMultiviewOVR = NULL;
+
+PFNGLALPHAFUNCQCOMPROC __glewAlphaFuncQCOM = NULL;
+
+PFNGLDISABLEDRIVERCONTROLQCOMPROC __glewDisableDriverControlQCOM = NULL;
+PFNGLENABLEDRIVERCONTROLQCOMPROC __glewEnableDriverControlQCOM = NULL;
+PFNGLGETDRIVERCONTROLSTRINGQCOMPROC __glewGetDriverControlStringQCOM = NULL;
+PFNGLGETDRIVERCONTROLSQCOMPROC __glewGetDriverControlsQCOM = NULL;
+
+PFNGLEXTGETBUFFERPOINTERVQCOMPROC __glewExtGetBufferPointervQCOM = NULL;
+PFNGLEXTGETBUFFERSQCOMPROC __glewExtGetBuffersQCOM = NULL;
+PFNGLEXTGETFRAMEBUFFERSQCOMPROC __glewExtGetFramebuffersQCOM = NULL;
+PFNGLEXTGETRENDERBUFFERSQCOMPROC __glewExtGetRenderbuffersQCOM = NULL;
+PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC __glewExtGetTexLevelParameterivQCOM = NULL;
+PFNGLEXTGETTEXSUBIMAGEQCOMPROC __glewExtGetTexSubImageQCOM = NULL;
+PFNGLEXTGETTEXTURESQCOMPROC __glewExtGetTexturesQCOM = NULL;
+PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC __glewExtTexObjectStateOverrideiQCOM = NULL;
+
+PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC __glewExtGetProgramBinarySourceQCOM = NULL;
+PFNGLEXTGETPROGRAMSQCOMPROC __glewExtGetProgramsQCOM = NULL;
+PFNGLEXTGETSHADERSQCOMPROC __glewExtGetShadersQCOM = NULL;
+PFNGLEXTISPROGRAMBINARYQCOMPROC __glewExtIsProgramBinaryQCOM = NULL;
+
+PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC __glewFramebufferFoveationConfigQCOM = NULL;
+PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC __glewFramebufferFoveationParametersQCOM = NULL;
+
+PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC __glewFramebufferFetchBarrierQCOM = NULL;
+
+PFNGLENDTILINGQCOMPROC __glewEndTilingQCOM = NULL;
+PFNGLSTARTTILINGQCOMPROC __glewStartTilingQCOM = NULL;
+
+PFNGLALPHAFUNCXPROC __glewAlphaFuncx = NULL;
+PFNGLCLEARCOLORXPROC __glewClearColorx = NULL;
+PFNGLCLEARDEPTHXPROC __glewClearDepthx = NULL;
+PFNGLCOLOR4XPROC __glewColor4x = NULL;
+PFNGLDEPTHRANGEXPROC __glewDepthRangex = NULL;
+PFNGLFOGXPROC __glewFogx = NULL;
+PFNGLFOGXVPROC __glewFogxv = NULL;
+PFNGLFRUSTUMFPROC __glewFrustumf = NULL;
+PFNGLFRUSTUMXPROC __glewFrustumx = NULL;
+PFNGLLIGHTMODELXPROC __glewLightModelx = NULL;
+PFNGLLIGHTMODELXVPROC __glewLightModelxv = NULL;
+PFNGLLIGHTXPROC __glewLightx = NULL;
+PFNGLLIGHTXVPROC __glewLightxv = NULL;
+PFNGLLINEWIDTHXPROC __glewLineWidthx = NULL;
+PFNGLLOADMATRIXXPROC __glewLoadMatrixx = NULL;
+PFNGLMATERIALXPROC __glewMaterialx = NULL;
+PFNGLMATERIALXVPROC __glewMaterialxv = NULL;
+PFNGLMULTMATRIXXPROC __glewMultMatrixx = NULL;
+PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x = NULL;
+PFNGLNORMAL3XPROC __glewNormal3x = NULL;
+PFNGLORTHOFPROC __glewOrthof = NULL;
+PFNGLORTHOXPROC __glewOrthox = NULL;
+PFNGLPOINTSIZEXPROC __glewPointSizex = NULL;
+PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx = NULL;
+PFNGLROTATEXPROC __glewRotatex = NULL;
+PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex = NULL;
+PFNGLSCALEXPROC __glewScalex = NULL;
+PFNGLTEXENVXPROC __glewTexEnvx = NULL;
+PFNGLTEXENVXVPROC __glewTexEnvxv = NULL;
+PFNGLTEXPARAMETERXPROC __glewTexParameterx = NULL;
+PFNGLTRANSLATEXPROC __glewTranslatex = NULL;
+
+PFNGLCLIPPLANEFPROC __glewClipPlanef = NULL;
+PFNGLCLIPPLANEXPROC __glewClipPlanex = NULL;
+PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef = NULL;
+PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex = NULL;
+PFNGLGETFIXEDVPROC __glewGetFixedv = NULL;
+PFNGLGETLIGHTXVPROC __glewGetLightxv = NULL;
+PFNGLGETMATERIALXVPROC __glewGetMaterialxv = NULL;
+PFNGLGETTEXENVXVPROC __glewGetTexEnvxv = NULL;
+PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv = NULL;
+PFNGLPOINTPARAMETERXPROC __glewPointParameterx = NULL;
+PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv = NULL;
+PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES = NULL;
+PFNGLTEXPARAMETERXVPROC __glewTexParameterxv = NULL;
+
+PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL = NULL;
+
+PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL = NULL;
+PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL = NULL;
+
+PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL = NULL;
+
+PFNGLGETPROCADDRESSREGALPROC __glewGetProcAddressREGAL = NULL;
+
+PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS = NULL;
+PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS = NULL;
+
+PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS = NULL;
+PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS = NULL;
+
+PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS = NULL;
+PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS = NULL;
+
+PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC __glewInterleavedTextureCoordSetsSGIS = NULL;
+PFNGLSELECTTEXTURECOORDSETSGISPROC __glewSelectTextureCoordSetSGIS = NULL;
+PFNGLSELECTTEXTURESGISPROC __glewSelectTextureSGIS = NULL;
+PFNGLSELECTTEXTURETRANSFORMSGISPROC __glewSelectTextureTransformSGIS = NULL;
+
+PFNGLMULTISAMPLESUBRECTPOSSGISPROC __glewMultisampleSubRectPosSGIS = NULL;
+
+PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS = NULL;
+PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS = NULL;
+
+PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS = NULL;
+PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS = NULL;
+
+PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS = NULL;
+PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS = NULL;
+
+PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX = NULL;
+PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX = NULL;
+PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX = NULL;
+PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX = NULL;
+PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX = NULL;
+PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX = NULL;
+
+PFNGLADDRESSSPACEPROC __glewAddressSpace = NULL;
+PFNGLDATAPIPEPROC __glewDataPipe = NULL;
+
+PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX = NULL;
+
+PFNGLFOGLAYERSSGIXPROC __glewFogLayersSGIX = NULL;
+PFNGLGETFOGLAYERSSGIXPROC __glewGetFogLayersSGIX = NULL;
+
+PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX = NULL;
+
+PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX = NULL;
+PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX = NULL;
+PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX = NULL;
+PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX = NULL;
+PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX = NULL;
+PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX = NULL;
+PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX = NULL;
+PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX = NULL;
+PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX = NULL;
+PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX = NULL;
+PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX = NULL;
+PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX = NULL;
+PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX = NULL;
+
+PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX = NULL;
+
+PFNGLIGLOOINTERFACESGIXPROC __glewIglooInterfaceSGIX = NULL;
+
+PFNGLALLOCMPEGPREDICTORSSGIXPROC __glewAllocMPEGPredictorsSGIX = NULL;
+PFNGLDELETEMPEGPREDICTORSSGIXPROC __glewDeleteMPEGPredictorsSGIX = NULL;
+PFNGLGENMPEGPREDICTORSSGIXPROC __glewGenMPEGPredictorsSGIX = NULL;
+PFNGLGETMPEGPARAMETERFVSGIXPROC __glewGetMPEGParameterfvSGIX = NULL;
+PFNGLGETMPEGPARAMETERIVSGIXPROC __glewGetMPEGParameterivSGIX = NULL;
+PFNGLGETMPEGPREDICTORSGIXPROC __glewGetMPEGPredictorSGIX = NULL;
+PFNGLGETMPEGQUANTTABLEUBVPROC __glewGetMPEGQuantTableubv = NULL;
+PFNGLISMPEGPREDICTORSGIXPROC __glewIsMPEGPredictorSGIX = NULL;
+PFNGLMPEGPREDICTORSGIXPROC __glewMPEGPredictorSGIX = NULL;
+PFNGLMPEGQUANTTABLEUBVPROC __glewMPEGQuantTableubv = NULL;
+PFNGLSWAPMPEGPREDICTORSSGIXPROC __glewSwapMPEGPredictorsSGIX = NULL;
+
+PFNGLGETNONLINLIGHTFVSGIXPROC __glewGetNonlinLightfvSGIX = NULL;
+PFNGLGETNONLINMATERIALFVSGIXPROC __glewGetNonlinMaterialfvSGIX = NULL;
+PFNGLNONLINLIGHTFVSGIXPROC __glewNonlinLightfvSGIX = NULL;
+PFNGLNONLINMATERIALFVSGIXPROC __glewNonlinMaterialfvSGIX = NULL;
+
+PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX = NULL;
+
+PFNGLDEFORMSGIXPROC __glewDeformSGIX = NULL;
+PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC __glewLoadIdentityDeformationMapSGIX = NULL;
+
+PFNGLMESHBREADTHSGIXPROC __glewMeshBreadthSGIX = NULL;
+PFNGLMESHSTRIDESGIXPROC __glewMeshStrideSGIX = NULL;
+
+PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX = NULL;
+
+PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX = NULL;
+PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX = NULL;
+PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX = NULL;
+PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX = NULL;
+
+PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX = NULL;
+
+PFNGLGETVECTOROPERATIONSGIXPROC __glewGetVectorOperationSGIX = NULL;
+PFNGLVECTOROPERATIONSGIXPROC __glewVectorOperationSGIX = NULL;
+
+PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC __glewAreVertexArraysResidentSGIX = NULL;
+PFNGLBINDVERTEXARRAYSGIXPROC __glewBindVertexArraySGIX = NULL;
+PFNGLDELETEVERTEXARRAYSSGIXPROC __glewDeleteVertexArraysSGIX = NULL;
+PFNGLGENVERTEXARRAYSSGIXPROC __glewGenVertexArraysSGIX = NULL;
+PFNGLISVERTEXARRAYSGIXPROC __glewIsVertexArraySGIX = NULL;
+PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC __glewPrioritizeVertexArraysSGIX = NULL;
+
+PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI = NULL;
+PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI = NULL;
+PFNGLCOLORTABLESGIPROC __glewColorTableSGI = NULL;
+PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI = NULL;
+PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI = NULL;
+
+PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC __glewGetPixelTransformParameterfvSGI = NULL;
+PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC __glewGetPixelTransformParameterivSGI = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFSGIPROC __glewPixelTransformParameterfSGI = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC __glewPixelTransformParameterfvSGI = NULL;
+PFNGLPIXELTRANSFORMPARAMETERISGIPROC __glewPixelTransformParameteriSGI = NULL;
+PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC __glewPixelTransformParameterivSGI = NULL;
+PFNGLPIXELTRANSFORMSGIPROC __glewPixelTransformSGI = NULL;
+
+PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX = NULL;
+
+PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN = NULL;
+PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN = NULL;
+PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN = NULL;
+PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN = NULL;
+PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN = NULL;
+PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN = NULL;
+PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN = NULL;
+PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN = NULL;
+
+PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN = NULL;
+
+PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN = NULL;
+PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN = NULL;
+PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN = NULL;
+PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN = NULL;
+PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN = NULL;
+PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN = NULL;
+PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN = NULL;
+
+PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN = NULL;
+PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN = NULL;
+PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN = NULL;
+PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN = NULL;
+PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN = NULL;
+PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN = NULL;
+PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN = NULL;
+PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN = NULL;
+PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN = NULL;
+PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN = NULL;
+PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN = NULL;
+PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN = NULL;
+PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL;
+
+PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL;
+
+GLboolean __GLEW_VERSION_1_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_2 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_2_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_3 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_4 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_5 = GL_FALSE;
+GLboolean __GLEW_VERSION_2_0 = GL_FALSE;
+GLboolean __GLEW_VERSION_2_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_0 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_2 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_3 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_0 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_2 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_3 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_4 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_5 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_6 = GL_FALSE;
+GLboolean __GLEW_3DFX_multisample = GL_FALSE;
+GLboolean __GLEW_3DFX_tbuffer = GL_FALSE;
+GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE;
+GLboolean __GLEW_AMD_blend_minmax_factor = GL_FALSE;
+GLboolean __GLEW_AMD_compressed_3DC_texture = GL_FALSE;
+GLboolean __GLEW_AMD_compressed_ATC_texture = GL_FALSE;
+GLboolean __GLEW_AMD_conservative_depth = GL_FALSE;
+GLboolean __GLEW_AMD_debug_output = GL_FALSE;
+GLboolean __GLEW_AMD_depth_clamp_separate = GL_FALSE;
+GLboolean __GLEW_AMD_draw_buffers_blend = GL_FALSE;
+GLboolean __GLEW_AMD_framebuffer_sample_positions = GL_FALSE;
+GLboolean __GLEW_AMD_gcn_shader = GL_FALSE;
+GLboolean __GLEW_AMD_gpu_shader_half_float = GL_FALSE;
+GLboolean __GLEW_AMD_gpu_shader_int16 = GL_FALSE;
+GLboolean __GLEW_AMD_gpu_shader_int64 = GL_FALSE;
+GLboolean __GLEW_AMD_interleaved_elements = GL_FALSE;
+GLboolean __GLEW_AMD_multi_draw_indirect = GL_FALSE;
+GLboolean __GLEW_AMD_name_gen_delete = GL_FALSE;
+GLboolean __GLEW_AMD_occlusion_query_event = GL_FALSE;
+GLboolean __GLEW_AMD_performance_monitor = GL_FALSE;
+GLboolean __GLEW_AMD_pinned_memory = GL_FALSE;
+GLboolean __GLEW_AMD_program_binary_Z400 = GL_FALSE;
+GLboolean __GLEW_AMD_query_buffer_object = GL_FALSE;
+GLboolean __GLEW_AMD_sample_positions = GL_FALSE;
+GLboolean __GLEW_AMD_seamless_cubemap_per_texture = GL_FALSE;
+GLboolean __GLEW_AMD_shader_atomic_counter_ops = GL_FALSE;
+GLboolean __GLEW_AMD_shader_ballot = GL_FALSE;
+GLboolean __GLEW_AMD_shader_explicit_vertex_parameter = GL_FALSE;
+GLboolean __GLEW_AMD_shader_stencil_export = GL_FALSE;
+GLboolean __GLEW_AMD_shader_stencil_value_export = GL_FALSE;
+GLboolean __GLEW_AMD_shader_trinary_minmax = GL_FALSE;
+GLboolean __GLEW_AMD_sparse_texture = GL_FALSE;
+GLboolean __GLEW_AMD_stencil_operation_extended = GL_FALSE;
+GLboolean __GLEW_AMD_texture_gather_bias_lod = GL_FALSE;
+GLboolean __GLEW_AMD_texture_texture4 = GL_FALSE;
+GLboolean __GLEW_AMD_transform_feedback3_lines_triangles = GL_FALSE;
+GLboolean __GLEW_AMD_transform_feedback4 = GL_FALSE;
+GLboolean __GLEW_AMD_vertex_shader_layer = GL_FALSE;
+GLboolean __GLEW_AMD_vertex_shader_tessellator = GL_FALSE;
+GLboolean __GLEW_AMD_vertex_shader_viewport_index = GL_FALSE;
+GLboolean __GLEW_ANDROID_extension_pack_es31a = GL_FALSE;
+GLboolean __GLEW_ANGLE_depth_texture = GL_FALSE;
+GLboolean __GLEW_ANGLE_framebuffer_blit = GL_FALSE;
+GLboolean __GLEW_ANGLE_framebuffer_multisample = GL_FALSE;
+GLboolean __GLEW_ANGLE_instanced_arrays = GL_FALSE;
+GLboolean __GLEW_ANGLE_pack_reverse_row_order = GL_FALSE;
+GLboolean __GLEW_ANGLE_program_binary = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_compression_dxt1 = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_compression_dxt3 = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_compression_dxt5 = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_usage = GL_FALSE;
+GLboolean __GLEW_ANGLE_timer_query = GL_FALSE;
+GLboolean __GLEW_ANGLE_translated_shader_source = GL_FALSE;
+GLboolean __GLEW_APPLE_aux_depth_stencil = GL_FALSE;
+GLboolean __GLEW_APPLE_client_storage = GL_FALSE;
+GLboolean __GLEW_APPLE_clip_distance = GL_FALSE;
+GLboolean __GLEW_APPLE_color_buffer_packed_float = GL_FALSE;
+GLboolean __GLEW_APPLE_copy_texture_levels = GL_FALSE;
+GLboolean __GLEW_APPLE_element_array = GL_FALSE;
+GLboolean __GLEW_APPLE_fence = GL_FALSE;
+GLboolean __GLEW_APPLE_float_pixels = GL_FALSE;
+GLboolean __GLEW_APPLE_flush_buffer_range = GL_FALSE;
+GLboolean __GLEW_APPLE_framebuffer_multisample = GL_FALSE;
+GLboolean __GLEW_APPLE_object_purgeable = GL_FALSE;
+GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE;
+GLboolean __GLEW_APPLE_rgb_422 = GL_FALSE;
+GLboolean __GLEW_APPLE_row_bytes = GL_FALSE;
+GLboolean __GLEW_APPLE_specular_vector = GL_FALSE;
+GLboolean __GLEW_APPLE_sync = GL_FALSE;
+GLboolean __GLEW_APPLE_texture_2D_limited_npot = GL_FALSE;
+GLboolean __GLEW_APPLE_texture_format_BGRA8888 = GL_FALSE;
+GLboolean __GLEW_APPLE_texture_max_level = GL_FALSE;
+GLboolean __GLEW_APPLE_texture_packed_float = GL_FALSE;
+GLboolean __GLEW_APPLE_texture_range = GL_FALSE;
+GLboolean __GLEW_APPLE_transform_hint = GL_FALSE;
+GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE;
+GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE;
+GLboolean __GLEW_APPLE_vertex_program_evaluators = GL_FALSE;
+GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE;
+GLboolean __GLEW_ARB_ES2_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_ES3_1_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_ES3_2_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_ES3_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_arrays_of_arrays = GL_FALSE;
+GLboolean __GLEW_ARB_base_instance = GL_FALSE;
+GLboolean __GLEW_ARB_bindless_texture = GL_FALSE;
+GLboolean __GLEW_ARB_blend_func_extended = GL_FALSE;
+GLboolean __GLEW_ARB_buffer_storage = GL_FALSE;
+GLboolean __GLEW_ARB_cl_event = GL_FALSE;
+GLboolean __GLEW_ARB_clear_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_clear_texture = GL_FALSE;
+GLboolean __GLEW_ARB_clip_control = GL_FALSE;
+GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE;
+GLboolean __GLEW_ARB_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_compressed_texture_pixel_storage = GL_FALSE;
+GLboolean __GLEW_ARB_compute_shader = GL_FALSE;
+GLboolean __GLEW_ARB_compute_variable_group_size = GL_FALSE;
+GLboolean __GLEW_ARB_conditional_render_inverted = GL_FALSE;
+GLboolean __GLEW_ARB_conservative_depth = GL_FALSE;
+GLboolean __GLEW_ARB_copy_buffer = GL_FALSE;
+GLboolean __GLEW_ARB_copy_image = GL_FALSE;
+GLboolean __GLEW_ARB_cull_distance = GL_FALSE;
+GLboolean __GLEW_ARB_debug_output = GL_FALSE;
+GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE;
+GLboolean __GLEW_ARB_depth_clamp = GL_FALSE;
+GLboolean __GLEW_ARB_depth_texture = GL_FALSE;
+GLboolean __GLEW_ARB_derivative_control = GL_FALSE;
+GLboolean __GLEW_ARB_direct_state_access = GL_FALSE;
+GLboolean __GLEW_ARB_draw_buffers = GL_FALSE;
+GLboolean __GLEW_ARB_draw_buffers_blend = GL_FALSE;
+GLboolean __GLEW_ARB_draw_elements_base_vertex = GL_FALSE;
+GLboolean __GLEW_ARB_draw_indirect = GL_FALSE;
+GLboolean __GLEW_ARB_draw_instanced = GL_FALSE;
+GLboolean __GLEW_ARB_enhanced_layouts = GL_FALSE;
+GLboolean __GLEW_ARB_explicit_attrib_location = GL_FALSE;
+GLboolean __GLEW_ARB_explicit_uniform_location = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_coord_conventions = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_layer_viewport = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_program = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_shader = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_shader_interlock = GL_FALSE;
+GLboolean __GLEW_ARB_framebuffer_no_attachments = GL_FALSE;
+GLboolean __GLEW_ARB_framebuffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLEW_ARB_geometry_shader4 = GL_FALSE;
+GLboolean __GLEW_ARB_get_program_binary = GL_FALSE;
+GLboolean __GLEW_ARB_get_texture_sub_image = GL_FALSE;
+GLboolean __GLEW_ARB_gl_spirv = GL_FALSE;
+GLboolean __GLEW_ARB_gpu_shader5 = GL_FALSE;
+GLboolean __GLEW_ARB_gpu_shader_fp64 = GL_FALSE;
+GLboolean __GLEW_ARB_gpu_shader_int64 = GL_FALSE;
+GLboolean __GLEW_ARB_half_float_pixel = GL_FALSE;
+GLboolean __GLEW_ARB_half_float_vertex = GL_FALSE;
+GLboolean __GLEW_ARB_imaging = GL_FALSE;
+GLboolean __GLEW_ARB_indirect_parameters = GL_FALSE;
+GLboolean __GLEW_ARB_instanced_arrays = GL_FALSE;
+GLboolean __GLEW_ARB_internalformat_query = GL_FALSE;
+GLboolean __GLEW_ARB_internalformat_query2 = GL_FALSE;
+GLboolean __GLEW_ARB_invalidate_subdata = GL_FALSE;
+GLboolean __GLEW_ARB_map_buffer_alignment = GL_FALSE;
+GLboolean __GLEW_ARB_map_buffer_range = GL_FALSE;
+GLboolean __GLEW_ARB_matrix_palette = GL_FALSE;
+GLboolean __GLEW_ARB_multi_bind = GL_FALSE;
+GLboolean __GLEW_ARB_multi_draw_indirect = GL_FALSE;
+GLboolean __GLEW_ARB_multisample = GL_FALSE;
+GLboolean __GLEW_ARB_multitexture = GL_FALSE;
+GLboolean __GLEW_ARB_occlusion_query = GL_FALSE;
+GLboolean __GLEW_ARB_occlusion_query2 = GL_FALSE;
+GLboolean __GLEW_ARB_parallel_shader_compile = GL_FALSE;
+GLboolean __GLEW_ARB_pipeline_statistics_query = GL_FALSE;
+GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_point_parameters = GL_FALSE;
+GLboolean __GLEW_ARB_point_sprite = GL_FALSE;
+GLboolean __GLEW_ARB_polygon_offset_clamp = GL_FALSE;
+GLboolean __GLEW_ARB_post_depth_coverage = GL_FALSE;
+GLboolean __GLEW_ARB_program_interface_query = GL_FALSE;
+GLboolean __GLEW_ARB_provoking_vertex = GL_FALSE;
+GLboolean __GLEW_ARB_query_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_robust_buffer_access_behavior = GL_FALSE;
+GLboolean __GLEW_ARB_robustness = GL_FALSE;
+GLboolean __GLEW_ARB_robustness_application_isolation = GL_FALSE;
+GLboolean __GLEW_ARB_robustness_share_group_isolation = GL_FALSE;
+GLboolean __GLEW_ARB_sample_locations = GL_FALSE;
+GLboolean __GLEW_ARB_sample_shading = GL_FALSE;
+GLboolean __GLEW_ARB_sampler_objects = GL_FALSE;
+GLboolean __GLEW_ARB_seamless_cube_map = GL_FALSE;
+GLboolean __GLEW_ARB_seamless_cubemap_per_texture = GL_FALSE;
+GLboolean __GLEW_ARB_separate_shader_objects = GL_FALSE;
+GLboolean __GLEW_ARB_shader_atomic_counter_ops = GL_FALSE;
+GLboolean __GLEW_ARB_shader_atomic_counters = GL_FALSE;
+GLboolean __GLEW_ARB_shader_ballot = GL_FALSE;
+GLboolean __GLEW_ARB_shader_bit_encoding = GL_FALSE;
+GLboolean __GLEW_ARB_shader_clock = GL_FALSE;
+GLboolean __GLEW_ARB_shader_draw_parameters = GL_FALSE;
+GLboolean __GLEW_ARB_shader_group_vote = GL_FALSE;
+GLboolean __GLEW_ARB_shader_image_load_store = GL_FALSE;
+GLboolean __GLEW_ARB_shader_image_size = GL_FALSE;
+GLboolean __GLEW_ARB_shader_objects = GL_FALSE;
+GLboolean __GLEW_ARB_shader_precision = GL_FALSE;
+GLboolean __GLEW_ARB_shader_stencil_export = GL_FALSE;
+GLboolean __GLEW_ARB_shader_storage_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_shader_subroutine = GL_FALSE;
+GLboolean __GLEW_ARB_shader_texture_image_samples = GL_FALSE;
+GLboolean __GLEW_ARB_shader_texture_lod = GL_FALSE;
+GLboolean __GLEW_ARB_shader_viewport_layer_array = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_420pack = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_include = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_packing = GL_FALSE;
+GLboolean __GLEW_ARB_shadow = GL_FALSE;
+GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE;
+GLboolean __GLEW_ARB_sparse_buffer = GL_FALSE;
+GLboolean __GLEW_ARB_sparse_texture = GL_FALSE;
+GLboolean __GLEW_ARB_sparse_texture2 = GL_FALSE;
+GLboolean __GLEW_ARB_sparse_texture_clamp = GL_FALSE;
+GLboolean __GLEW_ARB_spirv_extensions = GL_FALSE;
+GLboolean __GLEW_ARB_stencil_texturing = GL_FALSE;
+GLboolean __GLEW_ARB_sync = GL_FALSE;
+GLboolean __GLEW_ARB_tessellation_shader = GL_FALSE;
+GLboolean __GLEW_ARB_texture_barrier = GL_FALSE;
+GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE;
+GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_texture_buffer_object_rgb32 = GL_FALSE;
+GLboolean __GLEW_ARB_texture_buffer_range = GL_FALSE;
+GLboolean __GLEW_ARB_texture_compression = GL_FALSE;
+GLboolean __GLEW_ARB_texture_compression_bptc = GL_FALSE;
+GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE;
+GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE;
+GLboolean __GLEW_ARB_texture_cube_map_array = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_add = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE;
+GLboolean __GLEW_ARB_texture_filter_anisotropic = GL_FALSE;
+GLboolean __GLEW_ARB_texture_filter_minmax = GL_FALSE;
+GLboolean __GLEW_ARB_texture_float = GL_FALSE;
+GLboolean __GLEW_ARB_texture_gather = GL_FALSE;
+GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge = GL_FALSE;
+GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE;
+GLboolean __GLEW_ARB_texture_multisample = GL_FALSE;
+GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE;
+GLboolean __GLEW_ARB_texture_query_levels = GL_FALSE;
+GLboolean __GLEW_ARB_texture_query_lod = GL_FALSE;
+GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE;
+GLboolean __GLEW_ARB_texture_rg = GL_FALSE;
+GLboolean __GLEW_ARB_texture_rgb10_a2ui = GL_FALSE;
+GLboolean __GLEW_ARB_texture_stencil8 = GL_FALSE;
+GLboolean __GLEW_ARB_texture_storage = GL_FALSE;
+GLboolean __GLEW_ARB_texture_storage_multisample = GL_FALSE;
+GLboolean __GLEW_ARB_texture_swizzle = GL_FALSE;
+GLboolean __GLEW_ARB_texture_view = GL_FALSE;
+GLboolean __GLEW_ARB_timer_query = GL_FALSE;
+GLboolean __GLEW_ARB_transform_feedback2 = GL_FALSE;
+GLboolean __GLEW_ARB_transform_feedback3 = GL_FALSE;
+GLboolean __GLEW_ARB_transform_feedback_instanced = GL_FALSE;
+GLboolean __GLEW_ARB_transform_feedback_overflow_query = GL_FALSE;
+GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE;
+GLboolean __GLEW_ARB_uniform_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_array_bgra = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_attrib_64bit = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_attrib_binding = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_blend = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_program = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_shader = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_type_10f_11f_11f_rev = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev = GL_FALSE;
+GLboolean __GLEW_ARB_viewport_array = GL_FALSE;
+GLboolean __GLEW_ARB_window_pos = GL_FALSE;
+GLboolean __GLEW_ARM_mali_program_binary = GL_FALSE;
+GLboolean __GLEW_ARM_mali_shader_binary = GL_FALSE;
+GLboolean __GLEW_ARM_rgba8 = GL_FALSE;
+GLboolean __GLEW_ARM_shader_framebuffer_fetch = GL_FALSE;
+GLboolean __GLEW_ARM_shader_framebuffer_fetch_depth_stencil = GL_FALSE;
+GLboolean __GLEW_ATIX_point_sprites = GL_FALSE;
+GLboolean __GLEW_ATIX_texture_env_combine3 = GL_FALSE;
+GLboolean __GLEW_ATIX_texture_env_route = GL_FALSE;
+GLboolean __GLEW_ATIX_vertex_shader_output_point_size = GL_FALSE;
+GLboolean __GLEW_ATI_draw_buffers = GL_FALSE;
+GLboolean __GLEW_ATI_element_array = GL_FALSE;
+GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE;
+GLboolean __GLEW_ATI_fragment_shader = GL_FALSE;
+GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE;
+GLboolean __GLEW_ATI_meminfo = GL_FALSE;
+GLboolean __GLEW_ATI_pn_triangles = GL_FALSE;
+GLboolean __GLEW_ATI_separate_stencil = GL_FALSE;
+GLboolean __GLEW_ATI_shader_texture_lod = GL_FALSE;
+GLboolean __GLEW_ATI_text_fragment_shader = GL_FALSE;
+GLboolean __GLEW_ATI_texture_compression_3dc = GL_FALSE;
+GLboolean __GLEW_ATI_texture_env_combine3 = GL_FALSE;
+GLboolean __GLEW_ATI_texture_float = GL_FALSE;
+GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE;
+GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE;
+GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE;
+GLboolean __GLEW_ATI_vertex_streams = GL_FALSE;
+GLboolean __GLEW_EGL_KHR_context_flush_control = GL_FALSE;
+GLboolean __GLEW_EGL_NV_robustness_video_memory_purge = GL_FALSE;
+GLboolean __GLEW_EXT_422_pixels = GL_FALSE;
+GLboolean __GLEW_EXT_Cg_shader = GL_FALSE;
+GLboolean __GLEW_EXT_EGL_image_array = GL_FALSE;
+GLboolean __GLEW_EXT_YUV_target = GL_FALSE;
+GLboolean __GLEW_EXT_abgr = GL_FALSE;
+GLboolean __GLEW_EXT_base_instance = GL_FALSE;
+GLboolean __GLEW_EXT_bgra = GL_FALSE;
+GLboolean __GLEW_EXT_bindable_uniform = GL_FALSE;
+GLboolean __GLEW_EXT_blend_color = GL_FALSE;
+GLboolean __GLEW_EXT_blend_equation_separate = GL_FALSE;
+GLboolean __GLEW_EXT_blend_func_extended = GL_FALSE;
+GLboolean __GLEW_EXT_blend_func_separate = GL_FALSE;
+GLboolean __GLEW_EXT_blend_logic_op = GL_FALSE;
+GLboolean __GLEW_EXT_blend_minmax = GL_FALSE;
+GLboolean __GLEW_EXT_blend_subtract = GL_FALSE;
+GLboolean __GLEW_EXT_buffer_storage = GL_FALSE;
+GLboolean __GLEW_EXT_clear_texture = GL_FALSE;
+GLboolean __GLEW_EXT_clip_cull_distance = GL_FALSE;
+GLboolean __GLEW_EXT_clip_volume_hint = GL_FALSE;
+GLboolean __GLEW_EXT_cmyka = GL_FALSE;
+GLboolean __GLEW_EXT_color_buffer_float = GL_FALSE;
+GLboolean __GLEW_EXT_color_buffer_half_float = GL_FALSE;
+GLboolean __GLEW_EXT_color_subtable = GL_FALSE;
+GLboolean __GLEW_EXT_compiled_vertex_array = GL_FALSE;
+GLboolean __GLEW_EXT_compressed_ETC1_RGB8_sub_texture = GL_FALSE;
+GLboolean __GLEW_EXT_conservative_depth = GL_FALSE;
+GLboolean __GLEW_EXT_convolution = GL_FALSE;
+GLboolean __GLEW_EXT_coordinate_frame = GL_FALSE;
+GLboolean __GLEW_EXT_copy_image = GL_FALSE;
+GLboolean __GLEW_EXT_copy_texture = GL_FALSE;
+GLboolean __GLEW_EXT_cull_vertex = GL_FALSE;
+GLboolean __GLEW_EXT_debug_label = GL_FALSE;
+GLboolean __GLEW_EXT_debug_marker = GL_FALSE;
+GLboolean __GLEW_EXT_depth_bounds_test = GL_FALSE;
+GLboolean __GLEW_EXT_direct_state_access = GL_FALSE;
+GLboolean __GLEW_EXT_discard_framebuffer = GL_FALSE;
+GLboolean __GLEW_EXT_draw_buffers = GL_FALSE;
+GLboolean __GLEW_EXT_draw_buffers2 = GL_FALSE;
+GLboolean __GLEW_EXT_draw_buffers_indexed = GL_FALSE;
+GLboolean __GLEW_EXT_draw_elements_base_vertex = GL_FALSE;
+GLboolean __GLEW_EXT_draw_instanced = GL_FALSE;
+GLboolean __GLEW_EXT_draw_range_elements = GL_FALSE;
+GLboolean __GLEW_EXT_external_buffer = GL_FALSE;
+GLboolean __GLEW_EXT_float_blend = GL_FALSE;
+GLboolean __GLEW_EXT_fog_coord = GL_FALSE;
+GLboolean __GLEW_EXT_frag_depth = GL_FALSE;
+GLboolean __GLEW_EXT_fragment_lighting = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_blit = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_multisample = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_multisample_blit_scaled = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_object = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLEW_EXT_geometry_point_size = GL_FALSE;
+GLboolean __GLEW_EXT_geometry_shader = GL_FALSE;
+GLboolean __GLEW_EXT_geometry_shader4 = GL_FALSE;
+GLboolean __GLEW_EXT_gpu_program_parameters = GL_FALSE;
+GLboolean __GLEW_EXT_gpu_shader4 = GL_FALSE;
+GLboolean __GLEW_EXT_gpu_shader5 = GL_FALSE;
+GLboolean __GLEW_EXT_histogram = GL_FALSE;
+GLboolean __GLEW_EXT_index_array_formats = GL_FALSE;
+GLboolean __GLEW_EXT_index_func = GL_FALSE;
+GLboolean __GLEW_EXT_index_material = GL_FALSE;
+GLboolean __GLEW_EXT_index_texture = GL_FALSE;
+GLboolean __GLEW_EXT_instanced_arrays = GL_FALSE;
+GLboolean __GLEW_EXT_light_texture = GL_FALSE;
+GLboolean __GLEW_EXT_map_buffer_range = GL_FALSE;
+GLboolean __GLEW_EXT_memory_object = GL_FALSE;
+GLboolean __GLEW_EXT_memory_object_fd = GL_FALSE;
+GLboolean __GLEW_EXT_memory_object_win32 = GL_FALSE;
+GLboolean __GLEW_EXT_misc_attribute = GL_FALSE;
+GLboolean __GLEW_EXT_multi_draw_arrays = GL_FALSE;
+GLboolean __GLEW_EXT_multi_draw_indirect = GL_FALSE;
+GLboolean __GLEW_EXT_multiple_textures = GL_FALSE;
+GLboolean __GLEW_EXT_multisample = GL_FALSE;
+GLboolean __GLEW_EXT_multisample_compatibility = GL_FALSE;
+GLboolean __GLEW_EXT_multisampled_render_to_texture = GL_FALSE;
+GLboolean __GLEW_EXT_multisampled_render_to_texture2 = GL_FALSE;
+GLboolean __GLEW_EXT_multiview_draw_buffers = GL_FALSE;
+GLboolean __GLEW_EXT_packed_depth_stencil = GL_FALSE;
+GLboolean __GLEW_EXT_packed_float = GL_FALSE;
+GLboolean __GLEW_EXT_packed_pixels = GL_FALSE;
+GLboolean __GLEW_EXT_paletted_texture = GL_FALSE;
+GLboolean __GLEW_EXT_pixel_buffer_object = GL_FALSE;
+GLboolean __GLEW_EXT_pixel_transform = GL_FALSE;
+GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE;
+GLboolean __GLEW_EXT_point_parameters = GL_FALSE;
+GLboolean __GLEW_EXT_polygon_offset = GL_FALSE;
+GLboolean __GLEW_EXT_polygon_offset_clamp = GL_FALSE;
+GLboolean __GLEW_EXT_post_depth_coverage = GL_FALSE;
+GLboolean __GLEW_EXT_provoking_vertex = GL_FALSE;
+GLboolean __GLEW_EXT_pvrtc_sRGB = GL_FALSE;
+GLboolean __GLEW_EXT_raster_multisample = GL_FALSE;
+GLboolean __GLEW_EXT_read_format_bgra = GL_FALSE;
+GLboolean __GLEW_EXT_render_snorm = GL_FALSE;
+GLboolean __GLEW_EXT_rescale_normal = GL_FALSE;
+GLboolean __GLEW_EXT_sRGB = GL_FALSE;
+GLboolean __GLEW_EXT_sRGB_write_control = GL_FALSE;
+GLboolean __GLEW_EXT_scene_marker = GL_FALSE;
+GLboolean __GLEW_EXT_secondary_color = GL_FALSE;
+GLboolean __GLEW_EXT_semaphore = GL_FALSE;
+GLboolean __GLEW_EXT_semaphore_fd = GL_FALSE;
+GLboolean __GLEW_EXT_semaphore_win32 = GL_FALSE;
+GLboolean __GLEW_EXT_separate_shader_objects = GL_FALSE;
+GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE;
+GLboolean __GLEW_EXT_shader_framebuffer_fetch = GL_FALSE;
+GLboolean __GLEW_EXT_shader_group_vote = GL_FALSE;
+GLboolean __GLEW_EXT_shader_image_load_formatted = GL_FALSE;
+GLboolean __GLEW_EXT_shader_image_load_store = GL_FALSE;
+GLboolean __GLEW_EXT_shader_implicit_conversions = GL_FALSE;
+GLboolean __GLEW_EXT_shader_integer_mix = GL_FALSE;
+GLboolean __GLEW_EXT_shader_io_blocks = GL_FALSE;
+GLboolean __GLEW_EXT_shader_non_constant_global_initializers = GL_FALSE;
+GLboolean __GLEW_EXT_shader_pixel_local_storage = GL_FALSE;
+GLboolean __GLEW_EXT_shader_pixel_local_storage2 = GL_FALSE;
+GLboolean __GLEW_EXT_shader_texture_lod = GL_FALSE;
+GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE;
+GLboolean __GLEW_EXT_shadow_samplers = GL_FALSE;
+GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE;
+GLboolean __GLEW_EXT_sparse_texture = GL_FALSE;
+GLboolean __GLEW_EXT_sparse_texture2 = GL_FALSE;
+GLboolean __GLEW_EXT_stencil_clear_tag = GL_FALSE;
+GLboolean __GLEW_EXT_stencil_two_side = GL_FALSE;
+GLboolean __GLEW_EXT_stencil_wrap = GL_FALSE;
+GLboolean __GLEW_EXT_subtexture = GL_FALSE;
+GLboolean __GLEW_EXT_texture = GL_FALSE;
+GLboolean __GLEW_EXT_texture3D = GL_FALSE;
+GLboolean __GLEW_EXT_texture_array = GL_FALSE;
+GLboolean __GLEW_EXT_texture_buffer_object = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_astc_decode_mode = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_bptc = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_dxt1 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_latc = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_rgtc = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_s3tc = GL_FALSE;
+GLboolean __GLEW_EXT_texture_cube_map = GL_FALSE;
+GLboolean __GLEW_EXT_texture_cube_map_array = GL_FALSE;
+GLboolean __GLEW_EXT_texture_edge_clamp = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env_add = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env_combine = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env_dot3 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_filter_anisotropic = GL_FALSE;
+GLboolean __GLEW_EXT_texture_filter_minmax = GL_FALSE;
+GLboolean __GLEW_EXT_texture_format_BGRA8888 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_integer = GL_FALSE;
+GLboolean __GLEW_EXT_texture_lod_bias = GL_FALSE;
+GLboolean __GLEW_EXT_texture_mirror_clamp = GL_FALSE;
+GLboolean __GLEW_EXT_texture_norm16 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_object = GL_FALSE;
+GLboolean __GLEW_EXT_texture_perturb_normal = GL_FALSE;
+GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE;
+GLboolean __GLEW_EXT_texture_rg = GL_FALSE;
+GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE;
+GLboolean __GLEW_EXT_texture_sRGB_R8 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_sRGB_RG8 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_sRGB_decode = GL_FALSE;
+GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE;
+GLboolean __GLEW_EXT_texture_snorm = GL_FALSE;
+GLboolean __GLEW_EXT_texture_storage = GL_FALSE;
+GLboolean __GLEW_EXT_texture_swizzle = GL_FALSE;
+GLboolean __GLEW_EXT_texture_type_2_10_10_10_REV = GL_FALSE;
+GLboolean __GLEW_EXT_texture_view = GL_FALSE;
+GLboolean __GLEW_EXT_timer_query = GL_FALSE;
+GLboolean __GLEW_EXT_transform_feedback = GL_FALSE;
+GLboolean __GLEW_EXT_unpack_subimage = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_array = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_array_bgra = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_array_setXXX = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_attrib_64bit = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_shader = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE;
+GLboolean __GLEW_EXT_win32_keyed_mutex = GL_FALSE;
+GLboolean __GLEW_EXT_window_rectangles = GL_FALSE;
+GLboolean __GLEW_EXT_x11_sync_object = GL_FALSE;
+GLboolean __GLEW_GREMEDY_frame_terminator = GL_FALSE;
+GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE;
+GLboolean __GLEW_HP_convolution_border_modes = GL_FALSE;
+GLboolean __GLEW_HP_image_transform = GL_FALSE;
+GLboolean __GLEW_HP_occlusion_test = GL_FALSE;
+GLboolean __GLEW_HP_texture_lighting = GL_FALSE;
+GLboolean __GLEW_IBM_cull_vertex = GL_FALSE;
+GLboolean __GLEW_IBM_multimode_draw_arrays = GL_FALSE;
+GLboolean __GLEW_IBM_rasterpos_clip = GL_FALSE;
+GLboolean __GLEW_IBM_static_data = GL_FALSE;
+GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE;
+GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE;
+GLboolean __GLEW_INGR_color_clamp = GL_FALSE;
+GLboolean __GLEW_INGR_interlace_read = GL_FALSE;
+GLboolean __GLEW_INTEL_conservative_rasterization = GL_FALSE;
+GLboolean __GLEW_INTEL_fragment_shader_ordering = GL_FALSE;
+GLboolean __GLEW_INTEL_framebuffer_CMAA = GL_FALSE;
+GLboolean __GLEW_INTEL_map_texture = GL_FALSE;
+GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE;
+GLboolean __GLEW_INTEL_performance_query = GL_FALSE;
+GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE;
+GLboolean __GLEW_KHR_blend_equation_advanced = GL_FALSE;
+GLboolean __GLEW_KHR_blend_equation_advanced_coherent = GL_FALSE;
+GLboolean __GLEW_KHR_context_flush_control = GL_FALSE;
+GLboolean __GLEW_KHR_debug = GL_FALSE;
+GLboolean __GLEW_KHR_no_error = GL_FALSE;
+GLboolean __GLEW_KHR_parallel_shader_compile = GL_FALSE;
+GLboolean __GLEW_KHR_robust_buffer_access_behavior = GL_FALSE;
+GLboolean __GLEW_KHR_robustness = GL_FALSE;
+GLboolean __GLEW_KHR_texture_compression_astc_hdr = GL_FALSE;
+GLboolean __GLEW_KHR_texture_compression_astc_ldr = GL_FALSE;
+GLboolean __GLEW_KHR_texture_compression_astc_sliced_3d = GL_FALSE;
+GLboolean __GLEW_KTX_buffer_region = GL_FALSE;
+GLboolean __GLEW_MESAX_texture_stack = GL_FALSE;
+GLboolean __GLEW_MESA_pack_invert = GL_FALSE;
+GLboolean __GLEW_MESA_resize_buffers = GL_FALSE;
+GLboolean __GLEW_MESA_shader_integer_functions = GL_FALSE;
+GLboolean __GLEW_MESA_window_pos = GL_FALSE;
+GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE;
+GLboolean __GLEW_NVX_blend_equation_advanced_multi_draw_buffers = GL_FALSE;
+GLboolean __GLEW_NVX_conditional_render = GL_FALSE;
+GLboolean __GLEW_NVX_gpu_memory_info = GL_FALSE;
+GLboolean __GLEW_NVX_linked_gpu_multicast = GL_FALSE;
+GLboolean __GLEW_NV_3dvision_settings = GL_FALSE;
+GLboolean __GLEW_NV_EGL_stream_consumer_external = GL_FALSE;
+GLboolean __GLEW_NV_alpha_to_coverage_dither_control = GL_FALSE;
+GLboolean __GLEW_NV_bgr = GL_FALSE;
+GLboolean __GLEW_NV_bindless_multi_draw_indirect = GL_FALSE;
+GLboolean __GLEW_NV_bindless_multi_draw_indirect_count = GL_FALSE;
+GLboolean __GLEW_NV_bindless_texture = GL_FALSE;
+GLboolean __GLEW_NV_blend_equation_advanced = GL_FALSE;
+GLboolean __GLEW_NV_blend_equation_advanced_coherent = GL_FALSE;
+GLboolean __GLEW_NV_blend_minmax_factor = GL_FALSE;
+GLboolean __GLEW_NV_blend_square = GL_FALSE;
+GLboolean __GLEW_NV_clip_space_w_scaling = GL_FALSE;
+GLboolean __GLEW_NV_command_list = GL_FALSE;
+GLboolean __GLEW_NV_compute_program5 = GL_FALSE;
+GLboolean __GLEW_NV_conditional_render = GL_FALSE;
+GLboolean __GLEW_NV_conservative_raster = GL_FALSE;
+GLboolean __GLEW_NV_conservative_raster_dilate = GL_FALSE;
+GLboolean __GLEW_NV_conservative_raster_pre_snap_triangles = GL_FALSE;
+GLboolean __GLEW_NV_copy_buffer = GL_FALSE;
+GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE;
+GLboolean __GLEW_NV_copy_image = GL_FALSE;
+GLboolean __GLEW_NV_deep_texture3D = GL_FALSE;
+GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE;
+GLboolean __GLEW_NV_depth_clamp = GL_FALSE;
+GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE;
+GLboolean __GLEW_NV_draw_buffers = GL_FALSE;
+GLboolean __GLEW_NV_draw_instanced = GL_FALSE;
+GLboolean __GLEW_NV_draw_texture = GL_FALSE;
+GLboolean __GLEW_NV_draw_vulkan_image = GL_FALSE;
+GLboolean __GLEW_NV_evaluators = GL_FALSE;
+GLboolean __GLEW_NV_explicit_attrib_location = GL_FALSE;
+GLboolean __GLEW_NV_explicit_multisample = GL_FALSE;
+GLboolean __GLEW_NV_fbo_color_attachments = GL_FALSE;
+GLboolean __GLEW_NV_fence = GL_FALSE;
+GLboolean __GLEW_NV_fill_rectangle = GL_FALSE;
+GLboolean __GLEW_NV_float_buffer = GL_FALSE;
+GLboolean __GLEW_NV_fog_distance = GL_FALSE;
+GLboolean __GLEW_NV_fragment_coverage_to_color = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program2 = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program4 = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program_option = GL_FALSE;
+GLboolean __GLEW_NV_fragment_shader_interlock = GL_FALSE;
+GLboolean __GLEW_NV_framebuffer_blit = GL_FALSE;
+GLboolean __GLEW_NV_framebuffer_mixed_samples = GL_FALSE;
+GLboolean __GLEW_NV_framebuffer_multisample = GL_FALSE;
+GLboolean __GLEW_NV_framebuffer_multisample_coverage = GL_FALSE;
+GLboolean __GLEW_NV_generate_mipmap_sRGB = GL_FALSE;
+GLboolean __GLEW_NV_geometry_program4 = GL_FALSE;
+GLboolean __GLEW_NV_geometry_shader4 = GL_FALSE;
+GLboolean __GLEW_NV_geometry_shader_passthrough = GL_FALSE;
+GLboolean __GLEW_NV_gpu_multicast = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program4 = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program5 = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program5_mem_extended = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program_fp64 = GL_FALSE;
+GLboolean __GLEW_NV_gpu_shader5 = GL_FALSE;
+GLboolean __GLEW_NV_half_float = GL_FALSE;
+GLboolean __GLEW_NV_image_formats = GL_FALSE;
+GLboolean __GLEW_NV_instanced_arrays = GL_FALSE;
+GLboolean __GLEW_NV_internalformat_sample_query = GL_FALSE;
+GLboolean __GLEW_NV_light_max_exponent = GL_FALSE;
+GLboolean __GLEW_NV_multisample_coverage = GL_FALSE;
+GLboolean __GLEW_NV_multisample_filter_hint = GL_FALSE;
+GLboolean __GLEW_NV_non_square_matrices = GL_FALSE;
+GLboolean __GLEW_NV_occlusion_query = GL_FALSE;
+GLboolean __GLEW_NV_pack_subimage = GL_FALSE;
+GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE;
+GLboolean __GLEW_NV_packed_float = GL_FALSE;
+GLboolean __GLEW_NV_packed_float_linear = GL_FALSE;
+GLboolean __GLEW_NV_parameter_buffer_object = GL_FALSE;
+GLboolean __GLEW_NV_parameter_buffer_object2 = GL_FALSE;
+GLboolean __GLEW_NV_path_rendering = GL_FALSE;
+GLboolean __GLEW_NV_path_rendering_shared_edge = GL_FALSE;
+GLboolean __GLEW_NV_pixel_buffer_object = GL_FALSE;
+GLboolean __GLEW_NV_pixel_data_range = GL_FALSE;
+GLboolean __GLEW_NV_platform_binary = GL_FALSE;
+GLboolean __GLEW_NV_point_sprite = GL_FALSE;
+GLboolean __GLEW_NV_polygon_mode = GL_FALSE;
+GLboolean __GLEW_NV_present_video = GL_FALSE;
+GLboolean __GLEW_NV_primitive_restart = GL_FALSE;
+GLboolean __GLEW_NV_read_depth = GL_FALSE;
+GLboolean __GLEW_NV_read_depth_stencil = GL_FALSE;
+GLboolean __GLEW_NV_read_stencil = GL_FALSE;
+GLboolean __GLEW_NV_register_combiners = GL_FALSE;
+GLboolean __GLEW_NV_register_combiners2 = GL_FALSE;
+GLboolean __GLEW_NV_robustness_video_memory_purge = GL_FALSE;
+GLboolean __GLEW_NV_sRGB_formats = GL_FALSE;
+GLboolean __GLEW_NV_sample_locations = GL_FALSE;
+GLboolean __GLEW_NV_sample_mask_override_coverage = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_counters = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_float = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_float64 = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_fp16_vector = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_int64 = GL_FALSE;
+GLboolean __GLEW_NV_shader_buffer_load = GL_FALSE;
+GLboolean __GLEW_NV_shader_noperspective_interpolation = GL_FALSE;
+GLboolean __GLEW_NV_shader_storage_buffer_object = GL_FALSE;
+GLboolean __GLEW_NV_shader_thread_group = GL_FALSE;
+GLboolean __GLEW_NV_shader_thread_shuffle = GL_FALSE;
+GLboolean __GLEW_NV_shadow_samplers_array = GL_FALSE;
+GLboolean __GLEW_NV_shadow_samplers_cube = GL_FALSE;
+GLboolean __GLEW_NV_stereo_view_rendering = GL_FALSE;
+GLboolean __GLEW_NV_tessellation_program5 = GL_FALSE;
+GLboolean __GLEW_NV_texgen_emboss = GL_FALSE;
+GLboolean __GLEW_NV_texgen_reflection = GL_FALSE;
+GLboolean __GLEW_NV_texture_array = GL_FALSE;
+GLboolean __GLEW_NV_texture_barrier = GL_FALSE;
+GLboolean __GLEW_NV_texture_border_clamp = GL_FALSE;
+GLboolean __GLEW_NV_texture_compression_latc = GL_FALSE;
+GLboolean __GLEW_NV_texture_compression_s3tc = GL_FALSE;
+GLboolean __GLEW_NV_texture_compression_s3tc_update = GL_FALSE;
+GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE;
+GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE;
+GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE;
+GLboolean __GLEW_NV_texture_multisample = GL_FALSE;
+GLboolean __GLEW_NV_texture_npot_2D_mipmap = GL_FALSE;
+GLboolean __GLEW_NV_texture_rectangle = GL_FALSE;
+GLboolean __GLEW_NV_texture_rectangle_compressed = GL_FALSE;
+GLboolean __GLEW_NV_texture_shader = GL_FALSE;
+GLboolean __GLEW_NV_texture_shader2 = GL_FALSE;
+GLboolean __GLEW_NV_texture_shader3 = GL_FALSE;
+GLboolean __GLEW_NV_transform_feedback = GL_FALSE;
+GLboolean __GLEW_NV_transform_feedback2 = GL_FALSE;
+GLboolean __GLEW_NV_uniform_buffer_unified_memory = GL_FALSE;
+GLboolean __GLEW_NV_vdpau_interop = GL_FALSE;
+GLboolean __GLEW_NV_vertex_array_range = GL_FALSE;
+GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_attrib_integer_64bit = GL_FALSE;
+GLboolean __GLEW_NV_vertex_buffer_unified_memory = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program2 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program2_option = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program3 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program4 = GL_FALSE;
+GLboolean __GLEW_NV_video_capture = GL_FALSE;
+GLboolean __GLEW_NV_viewport_array = GL_FALSE;
+GLboolean __GLEW_NV_viewport_array2 = GL_FALSE;
+GLboolean __GLEW_NV_viewport_swizzle = GL_FALSE;
+GLboolean __GLEW_OES_byte_coordinates = GL_FALSE;
+GLboolean __GLEW_OML_interlace = GL_FALSE;
+GLboolean __GLEW_OML_resample = GL_FALSE;
+GLboolean __GLEW_OML_subsample = GL_FALSE;
+GLboolean __GLEW_OVR_multiview = GL_FALSE;
+GLboolean __GLEW_OVR_multiview2 = GL_FALSE;
+GLboolean __GLEW_OVR_multiview_multisampled_render_to_texture = GL_FALSE;
+GLboolean __GLEW_PGI_misc_hints = GL_FALSE;
+GLboolean __GLEW_PGI_vertex_hints = GL_FALSE;
+GLboolean __GLEW_QCOM_alpha_test = GL_FALSE;
+GLboolean __GLEW_QCOM_binning_control = GL_FALSE;
+GLboolean __GLEW_QCOM_driver_control = GL_FALSE;
+GLboolean __GLEW_QCOM_extended_get = GL_FALSE;
+GLboolean __GLEW_QCOM_extended_get2 = GL_FALSE;
+GLboolean __GLEW_QCOM_framebuffer_foveated = GL_FALSE;
+GLboolean __GLEW_QCOM_perfmon_global_mode = GL_FALSE;
+GLboolean __GLEW_QCOM_shader_framebuffer_fetch_noncoherent = GL_FALSE;
+GLboolean __GLEW_QCOM_tiled_rendering = GL_FALSE;
+GLboolean __GLEW_QCOM_writeonly_rendering = GL_FALSE;
+GLboolean __GLEW_REGAL_ES1_0_compatibility = GL_FALSE;
+GLboolean __GLEW_REGAL_ES1_1_compatibility = GL_FALSE;
+GLboolean __GLEW_REGAL_enable = GL_FALSE;
+GLboolean __GLEW_REGAL_error_string = GL_FALSE;
+GLboolean __GLEW_REGAL_extension_query = GL_FALSE;
+GLboolean __GLEW_REGAL_log = GL_FALSE;
+GLboolean __GLEW_REGAL_proc_address = GL_FALSE;
+GLboolean __GLEW_REND_screen_coordinates = GL_FALSE;
+GLboolean __GLEW_S3_s3tc = GL_FALSE;
+GLboolean __GLEW_SGIS_clip_band_hint = GL_FALSE;
+GLboolean __GLEW_SGIS_color_range = GL_FALSE;
+GLboolean __GLEW_SGIS_detail_texture = GL_FALSE;
+GLboolean __GLEW_SGIS_fog_function = GL_FALSE;
+GLboolean __GLEW_SGIS_generate_mipmap = GL_FALSE;
+GLboolean __GLEW_SGIS_line_texgen = GL_FALSE;
+GLboolean __GLEW_SGIS_multisample = GL_FALSE;
+GLboolean __GLEW_SGIS_multitexture = GL_FALSE;
+GLboolean __GLEW_SGIS_pixel_texture = GL_FALSE;
+GLboolean __GLEW_SGIS_point_line_texgen = GL_FALSE;
+GLboolean __GLEW_SGIS_shared_multisample = GL_FALSE;
+GLboolean __GLEW_SGIS_sharpen_texture = GL_FALSE;
+GLboolean __GLEW_SGIS_texture4D = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_border_clamp = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_edge_clamp = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_filter4 = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_lod = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_select = GL_FALSE;
+GLboolean __GLEW_SGIX_async = GL_FALSE;
+GLboolean __GLEW_SGIX_async_histogram = GL_FALSE;
+GLboolean __GLEW_SGIX_async_pixel = GL_FALSE;
+GLboolean __GLEW_SGIX_bali_g_instruments = GL_FALSE;
+GLboolean __GLEW_SGIX_bali_r_instruments = GL_FALSE;
+GLboolean __GLEW_SGIX_bali_timer_instruments = GL_FALSE;
+GLboolean __GLEW_SGIX_blend_alpha_minmax = GL_FALSE;
+GLboolean __GLEW_SGIX_blend_cadd = GL_FALSE;
+GLboolean __GLEW_SGIX_blend_cmultiply = GL_FALSE;
+GLboolean __GLEW_SGIX_calligraphic_fragment = GL_FALSE;
+GLboolean __GLEW_SGIX_clipmap = GL_FALSE;
+GLboolean __GLEW_SGIX_color_matrix_accuracy = GL_FALSE;
+GLboolean __GLEW_SGIX_color_table_index_mode = GL_FALSE;
+GLboolean __GLEW_SGIX_complex_polar = GL_FALSE;
+GLboolean __GLEW_SGIX_convolution_accuracy = GL_FALSE;
+GLboolean __GLEW_SGIX_cube_map = GL_FALSE;
+GLboolean __GLEW_SGIX_cylinder_texgen = GL_FALSE;
+GLboolean __GLEW_SGIX_datapipe = GL_FALSE;
+GLboolean __GLEW_SGIX_decimation = GL_FALSE;
+GLboolean __GLEW_SGIX_depth_pass_instrument = GL_FALSE;
+GLboolean __GLEW_SGIX_depth_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_dvc = GL_FALSE;
+GLboolean __GLEW_SGIX_flush_raster = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_blend = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_factor_to_alpha = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_layers = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_offset = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_patchy = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_scale = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_fragment_lighting_space = GL_FALSE;
+GLboolean __GLEW_SGIX_fragment_specular_lighting = GL_FALSE;
+GLboolean __GLEW_SGIX_fragments_instrument = GL_FALSE;
+GLboolean __GLEW_SGIX_framezoom = GL_FALSE;
+GLboolean __GLEW_SGIX_icc_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_igloo_interface = GL_FALSE;
+GLboolean __GLEW_SGIX_image_compression = GL_FALSE;
+GLboolean __GLEW_SGIX_impact_pixel_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_instrument_error = GL_FALSE;
+GLboolean __GLEW_SGIX_interlace = GL_FALSE;
+GLboolean __GLEW_SGIX_ir_instrument1 = GL_FALSE;
+GLboolean __GLEW_SGIX_line_quality_hint = GL_FALSE;
+GLboolean __GLEW_SGIX_list_priority = GL_FALSE;
+GLboolean __GLEW_SGIX_mpeg1 = GL_FALSE;
+GLboolean __GLEW_SGIX_mpeg2 = GL_FALSE;
+GLboolean __GLEW_SGIX_nonlinear_lighting_pervertex = GL_FALSE;
+GLboolean __GLEW_SGIX_nurbs_eval = GL_FALSE;
+GLboolean __GLEW_SGIX_occlusion_instrument = GL_FALSE;
+GLboolean __GLEW_SGIX_packed_6bytes = GL_FALSE;
+GLboolean __GLEW_SGIX_pixel_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_pixel_texture_bits = GL_FALSE;
+GLboolean __GLEW_SGIX_pixel_texture_lod = GL_FALSE;
+GLboolean __GLEW_SGIX_pixel_tiles = GL_FALSE;
+GLboolean __GLEW_SGIX_polynomial_ffd = GL_FALSE;
+GLboolean __GLEW_SGIX_quad_mesh = GL_FALSE;
+GLboolean __GLEW_SGIX_reference_plane = GL_FALSE;
+GLboolean __GLEW_SGIX_resample = GL_FALSE;
+GLboolean __GLEW_SGIX_scalebias_hint = GL_FALSE;
+GLboolean __GLEW_SGIX_shadow = GL_FALSE;
+GLboolean __GLEW_SGIX_shadow_ambient = GL_FALSE;
+GLboolean __GLEW_SGIX_slim = GL_FALSE;
+GLboolean __GLEW_SGIX_spotlight_cutoff = GL_FALSE;
+GLboolean __GLEW_SGIX_sprite = GL_FALSE;
+GLboolean __GLEW_SGIX_subdiv_patch = GL_FALSE;
+GLboolean __GLEW_SGIX_subsample = GL_FALSE;
+GLboolean __GLEW_SGIX_tag_sample_buffer = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_add_env = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_coordinate_clamp = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_lod_bias = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_mipmap_anisotropic = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_multi_buffer = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_phase = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_range = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_scale_bias = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_supersample = GL_FALSE;
+GLboolean __GLEW_SGIX_vector_ops = GL_FALSE;
+GLboolean __GLEW_SGIX_vertex_array_object = GL_FALSE;
+GLboolean __GLEW_SGIX_vertex_preclip = GL_FALSE;
+GLboolean __GLEW_SGIX_vertex_preclip_hint = GL_FALSE;
+GLboolean __GLEW_SGIX_ycrcb = GL_FALSE;
+GLboolean __GLEW_SGIX_ycrcb_subsample = GL_FALSE;
+GLboolean __GLEW_SGIX_ycrcba = GL_FALSE;
+GLboolean __GLEW_SGI_color_matrix = GL_FALSE;
+GLboolean __GLEW_SGI_color_table = GL_FALSE;
+GLboolean __GLEW_SGI_complex = GL_FALSE;
+GLboolean __GLEW_SGI_complex_type = GL_FALSE;
+GLboolean __GLEW_SGI_fft = GL_FALSE;
+GLboolean __GLEW_SGI_texture_color_table = GL_FALSE;
+GLboolean __GLEW_SUNX_constant_data = GL_FALSE;
+GLboolean __GLEW_SUN_convolution_border_modes = GL_FALSE;
+GLboolean __GLEW_SUN_global_alpha = GL_FALSE;
+GLboolean __GLEW_SUN_mesh_array = GL_FALSE;
+GLboolean __GLEW_SUN_read_video_pixels = GL_FALSE;
+GLboolean __GLEW_SUN_slice_accum = GL_FALSE;
+GLboolean __GLEW_SUN_triangle_list = GL_FALSE;
+GLboolean __GLEW_SUN_vertex = GL_FALSE;
+GLboolean __GLEW_WIN_phong_shading = GL_FALSE;
+GLboolean __GLEW_WIN_scene_markerXXX = GL_FALSE;
+GLboolean __GLEW_WIN_specular_fog = GL_FALSE;
+GLboolean __GLEW_WIN_swap_hint = GL_FALSE;
+
+static const char * _glewExtensionLookup[] = {
+#ifdef GL_VERSION_1_2
+ "GL_VERSION_1_2",
+#endif
+#ifdef GL_VERSION_1_2_1
+ "GL_VERSION_1_2_1",
+#endif
+#ifdef GL_VERSION_1_3
+ "GL_VERSION_1_3",
+#endif
+#ifdef GL_VERSION_1_4
+ "GL_VERSION_1_4",
+#endif
+#ifdef GL_VERSION_1_5
+ "GL_VERSION_1_5",
+#endif
+#ifdef GL_VERSION_2_0
+ "GL_VERSION_2_0",
+#endif
+#ifdef GL_VERSION_2_1
+ "GL_VERSION_2_1",
+#endif
+#ifdef GL_VERSION_3_0
+ "GL_VERSION_3_0",
+#endif
+#ifdef GL_VERSION_3_1
+ "GL_VERSION_3_1",
+#endif
+#ifdef GL_VERSION_3_2
+ "GL_VERSION_3_2",
+#endif
+#ifdef GL_VERSION_3_3
+ "GL_VERSION_3_3",
+#endif
+#ifdef GL_VERSION_4_0
+ "GL_VERSION_4_0",
+#endif
+#ifdef GL_VERSION_4_1
+ "GL_VERSION_4_1",
+#endif
+#ifdef GL_VERSION_4_2
+ "GL_VERSION_4_2",
+#endif
+#ifdef GL_VERSION_4_3
+ "GL_VERSION_4_3",
+#endif
+#ifdef GL_VERSION_4_4
+ "GL_VERSION_4_4",
+#endif
+#ifdef GL_VERSION_4_5
+ "GL_VERSION_4_5",
+#endif
+#ifdef GL_VERSION_4_6
+ "GL_VERSION_4_6",
+#endif
+#ifdef GL_3DFX_multisample
+ "GL_3DFX_multisample",
+#endif
+#ifdef GL_3DFX_tbuffer
+ "GL_3DFX_tbuffer",
+#endif
+#ifdef GL_3DFX_texture_compression_FXT1
+ "GL_3DFX_texture_compression_FXT1",
+#endif
+#ifdef GL_AMD_blend_minmax_factor
+ "GL_AMD_blend_minmax_factor",
+#endif
+#ifdef GL_AMD_compressed_3DC_texture
+ "GL_AMD_compressed_3DC_texture",
+#endif
+#ifdef GL_AMD_compressed_ATC_texture
+ "GL_AMD_compressed_ATC_texture",
+#endif
+#ifdef GL_AMD_conservative_depth
+ "GL_AMD_conservative_depth",
+#endif
+#ifdef GL_AMD_debug_output
+ "GL_AMD_debug_output",
+#endif
+#ifdef GL_AMD_depth_clamp_separate
+ "GL_AMD_depth_clamp_separate",
+#endif
+#ifdef GL_AMD_draw_buffers_blend
+ "GL_AMD_draw_buffers_blend",
+#endif
+#ifdef GL_AMD_framebuffer_sample_positions
+ "GL_AMD_framebuffer_sample_positions",
+#endif
+#ifdef GL_AMD_gcn_shader
+ "GL_AMD_gcn_shader",
+#endif
+#ifdef GL_AMD_gpu_shader_half_float
+ "GL_AMD_gpu_shader_half_float",
+#endif
+#ifdef GL_AMD_gpu_shader_int16
+ "GL_AMD_gpu_shader_int16",
+#endif
+#ifdef GL_AMD_gpu_shader_int64
+ "GL_AMD_gpu_shader_int64",
+#endif
+#ifdef GL_AMD_interleaved_elements
+ "GL_AMD_interleaved_elements",
+#endif
+#ifdef GL_AMD_multi_draw_indirect
+ "GL_AMD_multi_draw_indirect",
+#endif
+#ifdef GL_AMD_name_gen_delete
+ "GL_AMD_name_gen_delete",
+#endif
+#ifdef GL_AMD_occlusion_query_event
+ "GL_AMD_occlusion_query_event",
+#endif
+#ifdef GL_AMD_performance_monitor
+ "GL_AMD_performance_monitor",
+#endif
+#ifdef GL_AMD_pinned_memory
+ "GL_AMD_pinned_memory",
+#endif
+#ifdef GL_AMD_program_binary_Z400
+ "GL_AMD_program_binary_Z400",
+#endif
+#ifdef GL_AMD_query_buffer_object
+ "GL_AMD_query_buffer_object",
+#endif
+#ifdef GL_AMD_sample_positions
+ "GL_AMD_sample_positions",
+#endif
+#ifdef GL_AMD_seamless_cubemap_per_texture
+ "GL_AMD_seamless_cubemap_per_texture",
+#endif
+#ifdef GL_AMD_shader_atomic_counter_ops
+ "GL_AMD_shader_atomic_counter_ops",
+#endif
+#ifdef GL_AMD_shader_ballot
+ "GL_AMD_shader_ballot",
+#endif
+#ifdef GL_AMD_shader_explicit_vertex_parameter
+ "GL_AMD_shader_explicit_vertex_parameter",
+#endif
+#ifdef GL_AMD_shader_stencil_export
+ "GL_AMD_shader_stencil_export",
+#endif
+#ifdef GL_AMD_shader_stencil_value_export
+ "GL_AMD_shader_stencil_value_export",
+#endif
+#ifdef GL_AMD_shader_trinary_minmax
+ "GL_AMD_shader_trinary_minmax",
+#endif
+#ifdef GL_AMD_sparse_texture
+ "GL_AMD_sparse_texture",
+#endif
+#ifdef GL_AMD_stencil_operation_extended
+ "GL_AMD_stencil_operation_extended",
+#endif
+#ifdef GL_AMD_texture_gather_bias_lod
+ "GL_AMD_texture_gather_bias_lod",
+#endif
+#ifdef GL_AMD_texture_texture4
+ "GL_AMD_texture_texture4",
+#endif
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+ "GL_AMD_transform_feedback3_lines_triangles",
+#endif
+#ifdef GL_AMD_transform_feedback4
+ "GL_AMD_transform_feedback4",
+#endif
+#ifdef GL_AMD_vertex_shader_layer
+ "GL_AMD_vertex_shader_layer",
+#endif
+#ifdef GL_AMD_vertex_shader_tessellator
+ "GL_AMD_vertex_shader_tessellator",
+#endif
+#ifdef GL_AMD_vertex_shader_viewport_index
+ "GL_AMD_vertex_shader_viewport_index",
+#endif
+#ifdef GL_ANDROID_extension_pack_es31a
+ "GL_ANDROID_extension_pack_es31a",
+#endif
+#ifdef GL_ANGLE_depth_texture
+ "GL_ANGLE_depth_texture",
+#endif
+#ifdef GL_ANGLE_framebuffer_blit
+ "GL_ANGLE_framebuffer_blit",
+#endif
+#ifdef GL_ANGLE_framebuffer_multisample
+ "GL_ANGLE_framebuffer_multisample",
+#endif
+#ifdef GL_ANGLE_instanced_arrays
+ "GL_ANGLE_instanced_arrays",
+#endif
+#ifdef GL_ANGLE_pack_reverse_row_order
+ "GL_ANGLE_pack_reverse_row_order",
+#endif
+#ifdef GL_ANGLE_program_binary
+ "GL_ANGLE_program_binary",
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt1
+ "GL_ANGLE_texture_compression_dxt1",
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt3
+ "GL_ANGLE_texture_compression_dxt3",
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt5
+ "GL_ANGLE_texture_compression_dxt5",
+#endif
+#ifdef GL_ANGLE_texture_usage
+ "GL_ANGLE_texture_usage",
+#endif
+#ifdef GL_ANGLE_timer_query
+ "GL_ANGLE_timer_query",
+#endif
+#ifdef GL_ANGLE_translated_shader_source
+ "GL_ANGLE_translated_shader_source",
+#endif
+#ifdef GL_APPLE_aux_depth_stencil
+ "GL_APPLE_aux_depth_stencil",
+#endif
+#ifdef GL_APPLE_client_storage
+ "GL_APPLE_client_storage",
+#endif
+#ifdef GL_APPLE_clip_distance
+ "GL_APPLE_clip_distance",
+#endif
+#ifdef GL_APPLE_color_buffer_packed_float
+ "GL_APPLE_color_buffer_packed_float",
+#endif
+#ifdef GL_APPLE_copy_texture_levels
+ "GL_APPLE_copy_texture_levels",
+#endif
+#ifdef GL_APPLE_element_array
+ "GL_APPLE_element_array",
+#endif
+#ifdef GL_APPLE_fence
+ "GL_APPLE_fence",
+#endif
+#ifdef GL_APPLE_float_pixels
+ "GL_APPLE_float_pixels",
+#endif
+#ifdef GL_APPLE_flush_buffer_range
+ "GL_APPLE_flush_buffer_range",
+#endif
+#ifdef GL_APPLE_framebuffer_multisample
+ "GL_APPLE_framebuffer_multisample",
+#endif
+#ifdef GL_APPLE_object_purgeable
+ "GL_APPLE_object_purgeable",
+#endif
+#ifdef GL_APPLE_pixel_buffer
+ "GL_APPLE_pixel_buffer",
+#endif
+#ifdef GL_APPLE_rgb_422
+ "GL_APPLE_rgb_422",
+#endif
+#ifdef GL_APPLE_row_bytes
+ "GL_APPLE_row_bytes",
+#endif
+#ifdef GL_APPLE_specular_vector
+ "GL_APPLE_specular_vector",
+#endif
+#ifdef GL_APPLE_sync
+ "GL_APPLE_sync",
+#endif
+#ifdef GL_APPLE_texture_2D_limited_npot
+ "GL_APPLE_texture_2D_limited_npot",
+#endif
+#ifdef GL_APPLE_texture_format_BGRA8888
+ "GL_APPLE_texture_format_BGRA8888",
+#endif
+#ifdef GL_APPLE_texture_max_level
+ "GL_APPLE_texture_max_level",
+#endif
+#ifdef GL_APPLE_texture_packed_float
+ "GL_APPLE_texture_packed_float",
+#endif
+#ifdef GL_APPLE_texture_range
+ "GL_APPLE_texture_range",
+#endif
+#ifdef GL_APPLE_transform_hint
+ "GL_APPLE_transform_hint",
+#endif
+#ifdef GL_APPLE_vertex_array_object
+ "GL_APPLE_vertex_array_object",
+#endif
+#ifdef GL_APPLE_vertex_array_range
+ "GL_APPLE_vertex_array_range",
+#endif
+#ifdef GL_APPLE_vertex_program_evaluators
+ "GL_APPLE_vertex_program_evaluators",
+#endif
+#ifdef GL_APPLE_ycbcr_422
+ "GL_APPLE_ycbcr_422",
+#endif
+#ifdef GL_ARB_ES2_compatibility
+ "GL_ARB_ES2_compatibility",
+#endif
+#ifdef GL_ARB_ES3_1_compatibility
+ "GL_ARB_ES3_1_compatibility",
+#endif
+#ifdef GL_ARB_ES3_2_compatibility
+ "GL_ARB_ES3_2_compatibility",
+#endif
+#ifdef GL_ARB_ES3_compatibility
+ "GL_ARB_ES3_compatibility",
+#endif
+#ifdef GL_ARB_arrays_of_arrays
+ "GL_ARB_arrays_of_arrays",
+#endif
+#ifdef GL_ARB_base_instance
+ "GL_ARB_base_instance",
+#endif
+#ifdef GL_ARB_bindless_texture
+ "GL_ARB_bindless_texture",
+#endif
+#ifdef GL_ARB_blend_func_extended
+ "GL_ARB_blend_func_extended",
+#endif
+#ifdef GL_ARB_buffer_storage
+ "GL_ARB_buffer_storage",
+#endif
+#ifdef GL_ARB_cl_event
+ "GL_ARB_cl_event",
+#endif
+#ifdef GL_ARB_clear_buffer_object
+ "GL_ARB_clear_buffer_object",
+#endif
+#ifdef GL_ARB_clear_texture
+ "GL_ARB_clear_texture",
+#endif
+#ifdef GL_ARB_clip_control
+ "GL_ARB_clip_control",
+#endif
+#ifdef GL_ARB_color_buffer_float
+ "GL_ARB_color_buffer_float",
+#endif
+#ifdef GL_ARB_compatibility
+ "GL_ARB_compatibility",
+#endif
+#ifdef GL_ARB_compressed_texture_pixel_storage
+ "GL_ARB_compressed_texture_pixel_storage",
+#endif
+#ifdef GL_ARB_compute_shader
+ "GL_ARB_compute_shader",
+#endif
+#ifdef GL_ARB_compute_variable_group_size
+ "GL_ARB_compute_variable_group_size",
+#endif
+#ifdef GL_ARB_conditional_render_inverted
+ "GL_ARB_conditional_render_inverted",
+#endif
+#ifdef GL_ARB_conservative_depth
+ "GL_ARB_conservative_depth",
+#endif
+#ifdef GL_ARB_copy_buffer
+ "GL_ARB_copy_buffer",
+#endif
+#ifdef GL_ARB_copy_image
+ "GL_ARB_copy_image",
+#endif
+#ifdef GL_ARB_cull_distance
+ "GL_ARB_cull_distance",
+#endif
+#ifdef GL_ARB_debug_output
+ "GL_ARB_debug_output",
+#endif
+#ifdef GL_ARB_depth_buffer_float
+ "GL_ARB_depth_buffer_float",
+#endif
+#ifdef GL_ARB_depth_clamp
+ "GL_ARB_depth_clamp",
+#endif
+#ifdef GL_ARB_depth_texture
+ "GL_ARB_depth_texture",
+#endif
+#ifdef GL_ARB_derivative_control
+ "GL_ARB_derivative_control",
+#endif
+#ifdef GL_ARB_direct_state_access
+ "GL_ARB_direct_state_access",
+#endif
+#ifdef GL_ARB_draw_buffers
+ "GL_ARB_draw_buffers",
+#endif
+#ifdef GL_ARB_draw_buffers_blend
+ "GL_ARB_draw_buffers_blend",
+#endif
+#ifdef GL_ARB_draw_elements_base_vertex
+ "GL_ARB_draw_elements_base_vertex",
+#endif
+#ifdef GL_ARB_draw_indirect
+ "GL_ARB_draw_indirect",
+#endif
+#ifdef GL_ARB_draw_instanced
+ "GL_ARB_draw_instanced",
+#endif
+#ifdef GL_ARB_enhanced_layouts
+ "GL_ARB_enhanced_layouts",
+#endif
+#ifdef GL_ARB_explicit_attrib_location
+ "GL_ARB_explicit_attrib_location",
+#endif
+#ifdef GL_ARB_explicit_uniform_location
+ "GL_ARB_explicit_uniform_location",
+#endif
+#ifdef GL_ARB_fragment_coord_conventions
+ "GL_ARB_fragment_coord_conventions",
+#endif
+#ifdef GL_ARB_fragment_layer_viewport
+ "GL_ARB_fragment_layer_viewport",
+#endif
+#ifdef GL_ARB_fragment_program
+ "GL_ARB_fragment_program",
+#endif
+#ifdef GL_ARB_fragment_program_shadow
+ "GL_ARB_fragment_program_shadow",
+#endif
+#ifdef GL_ARB_fragment_shader
+ "GL_ARB_fragment_shader",
+#endif
+#ifdef GL_ARB_fragment_shader_interlock
+ "GL_ARB_fragment_shader_interlock",
+#endif
+#ifdef GL_ARB_framebuffer_no_attachments
+ "GL_ARB_framebuffer_no_attachments",
+#endif
+#ifdef GL_ARB_framebuffer_object
+ "GL_ARB_framebuffer_object",
+#endif
+#ifdef GL_ARB_framebuffer_sRGB
+ "GL_ARB_framebuffer_sRGB",
+#endif
+#ifdef GL_ARB_geometry_shader4
+ "GL_ARB_geometry_shader4",
+#endif
+#ifdef GL_ARB_get_program_binary
+ "GL_ARB_get_program_binary",
+#endif
+#ifdef GL_ARB_get_texture_sub_image
+ "GL_ARB_get_texture_sub_image",
+#endif
+#ifdef GL_ARB_gl_spirv
+ "GL_ARB_gl_spirv",
+#endif
+#ifdef GL_ARB_gpu_shader5
+ "GL_ARB_gpu_shader5",
+#endif
+#ifdef GL_ARB_gpu_shader_fp64
+ "GL_ARB_gpu_shader_fp64",
+#endif
+#ifdef GL_ARB_gpu_shader_int64
+ "GL_ARB_gpu_shader_int64",
+#endif
+#ifdef GL_ARB_half_float_pixel
+ "GL_ARB_half_float_pixel",
+#endif
+#ifdef GL_ARB_half_float_vertex
+ "GL_ARB_half_float_vertex",
+#endif
+#ifdef GL_ARB_imaging
+ "GL_ARB_imaging",
+#endif
+#ifdef GL_ARB_indirect_parameters
+ "GL_ARB_indirect_parameters",
+#endif
+#ifdef GL_ARB_instanced_arrays
+ "GL_ARB_instanced_arrays",
+#endif
+#ifdef GL_ARB_internalformat_query
+ "GL_ARB_internalformat_query",
+#endif
+#ifdef GL_ARB_internalformat_query2
+ "GL_ARB_internalformat_query2",
+#endif
+#ifdef GL_ARB_invalidate_subdata
+ "GL_ARB_invalidate_subdata",
+#endif
+#ifdef GL_ARB_map_buffer_alignment
+ "GL_ARB_map_buffer_alignment",
+#endif
+#ifdef GL_ARB_map_buffer_range
+ "GL_ARB_map_buffer_range",
+#endif
+#ifdef GL_ARB_matrix_palette
+ "GL_ARB_matrix_palette",
+#endif
+#ifdef GL_ARB_multi_bind
+ "GL_ARB_multi_bind",
+#endif
+#ifdef GL_ARB_multi_draw_indirect
+ "GL_ARB_multi_draw_indirect",
+#endif
+#ifdef GL_ARB_multisample
+ "GL_ARB_multisample",
+#endif
+#ifdef GL_ARB_multitexture
+ "GL_ARB_multitexture",
+#endif
+#ifdef GL_ARB_occlusion_query
+ "GL_ARB_occlusion_query",
+#endif
+#ifdef GL_ARB_occlusion_query2
+ "GL_ARB_occlusion_query2",
+#endif
+#ifdef GL_ARB_parallel_shader_compile
+ "GL_ARB_parallel_shader_compile",
+#endif
+#ifdef GL_ARB_pipeline_statistics_query
+ "GL_ARB_pipeline_statistics_query",
+#endif
+#ifdef GL_ARB_pixel_buffer_object
+ "GL_ARB_pixel_buffer_object",
+#endif
+#ifdef GL_ARB_point_parameters
+ "GL_ARB_point_parameters",
+#endif
+#ifdef GL_ARB_point_sprite
+ "GL_ARB_point_sprite",
+#endif
+#ifdef GL_ARB_polygon_offset_clamp
+ "GL_ARB_polygon_offset_clamp",
+#endif
+#ifdef GL_ARB_post_depth_coverage
+ "GL_ARB_post_depth_coverage",
+#endif
+#ifdef GL_ARB_program_interface_query
+ "GL_ARB_program_interface_query",
+#endif
+#ifdef GL_ARB_provoking_vertex
+ "GL_ARB_provoking_vertex",
+#endif
+#ifdef GL_ARB_query_buffer_object
+ "GL_ARB_query_buffer_object",
+#endif
+#ifdef GL_ARB_robust_buffer_access_behavior
+ "GL_ARB_robust_buffer_access_behavior",
+#endif
+#ifdef GL_ARB_robustness
+ "GL_ARB_robustness",
+#endif
+#ifdef GL_ARB_robustness_application_isolation
+ "GL_ARB_robustness_application_isolation",
+#endif
+#ifdef GL_ARB_robustness_share_group_isolation
+ "GL_ARB_robustness_share_group_isolation",
+#endif
+#ifdef GL_ARB_sample_locations
+ "GL_ARB_sample_locations",
+#endif
+#ifdef GL_ARB_sample_shading
+ "GL_ARB_sample_shading",
+#endif
+#ifdef GL_ARB_sampler_objects
+ "GL_ARB_sampler_objects",
+#endif
+#ifdef GL_ARB_seamless_cube_map
+ "GL_ARB_seamless_cube_map",
+#endif
+#ifdef GL_ARB_seamless_cubemap_per_texture
+ "GL_ARB_seamless_cubemap_per_texture",
+#endif
+#ifdef GL_ARB_separate_shader_objects
+ "GL_ARB_separate_shader_objects",
+#endif
+#ifdef GL_ARB_shader_atomic_counter_ops
+ "GL_ARB_shader_atomic_counter_ops",
+#endif
+#ifdef GL_ARB_shader_atomic_counters
+ "GL_ARB_shader_atomic_counters",
+#endif
+#ifdef GL_ARB_shader_ballot
+ "GL_ARB_shader_ballot",
+#endif
+#ifdef GL_ARB_shader_bit_encoding
+ "GL_ARB_shader_bit_encoding",
+#endif
+#ifdef GL_ARB_shader_clock
+ "GL_ARB_shader_clock",
+#endif
+#ifdef GL_ARB_shader_draw_parameters
+ "GL_ARB_shader_draw_parameters",
+#endif
+#ifdef GL_ARB_shader_group_vote
+ "GL_ARB_shader_group_vote",
+#endif
+#ifdef GL_ARB_shader_image_load_store
+ "GL_ARB_shader_image_load_store",
+#endif
+#ifdef GL_ARB_shader_image_size
+ "GL_ARB_shader_image_size",
+#endif
+#ifdef GL_ARB_shader_objects
+ "GL_ARB_shader_objects",
+#endif
+#ifdef GL_ARB_shader_precision
+ "GL_ARB_shader_precision",
+#endif
+#ifdef GL_ARB_shader_stencil_export
+ "GL_ARB_shader_stencil_export",
+#endif
+#ifdef GL_ARB_shader_storage_buffer_object
+ "GL_ARB_shader_storage_buffer_object",
+#endif
+#ifdef GL_ARB_shader_subroutine
+ "GL_ARB_shader_subroutine",
+#endif
+#ifdef GL_ARB_shader_texture_image_samples
+ "GL_ARB_shader_texture_image_samples",
+#endif
+#ifdef GL_ARB_shader_texture_lod
+ "GL_ARB_shader_texture_lod",
+#endif
+#ifdef GL_ARB_shader_viewport_layer_array
+ "GL_ARB_shader_viewport_layer_array",
+#endif
+#ifdef GL_ARB_shading_language_100
+ "GL_ARB_shading_language_100",
+#endif
+#ifdef GL_ARB_shading_language_420pack
+ "GL_ARB_shading_language_420pack",
+#endif
+#ifdef GL_ARB_shading_language_include
+ "GL_ARB_shading_language_include",
+#endif
+#ifdef GL_ARB_shading_language_packing
+ "GL_ARB_shading_language_packing",
+#endif
+#ifdef GL_ARB_shadow
+ "GL_ARB_shadow",
+#endif
+#ifdef GL_ARB_shadow_ambient
+ "GL_ARB_shadow_ambient",
+#endif
+#ifdef GL_ARB_sparse_buffer
+ "GL_ARB_sparse_buffer",
+#endif
+#ifdef GL_ARB_sparse_texture
+ "GL_ARB_sparse_texture",
+#endif
+#ifdef GL_ARB_sparse_texture2
+ "GL_ARB_sparse_texture2",
+#endif
+#ifdef GL_ARB_sparse_texture_clamp
+ "GL_ARB_sparse_texture_clamp",
+#endif
+#ifdef GL_ARB_spirv_extensions
+ "GL_ARB_spirv_extensions",
+#endif
+#ifdef GL_ARB_stencil_texturing
+ "GL_ARB_stencil_texturing",
+#endif
+#ifdef GL_ARB_sync
+ "GL_ARB_sync",
+#endif
+#ifdef GL_ARB_tessellation_shader
+ "GL_ARB_tessellation_shader",
+#endif
+#ifdef GL_ARB_texture_barrier
+ "GL_ARB_texture_barrier",
+#endif
+#ifdef GL_ARB_texture_border_clamp
+ "GL_ARB_texture_border_clamp",
+#endif
+#ifdef GL_ARB_texture_buffer_object
+ "GL_ARB_texture_buffer_object",
+#endif
+#ifdef GL_ARB_texture_buffer_object_rgb32
+ "GL_ARB_texture_buffer_object_rgb32",
+#endif
+#ifdef GL_ARB_texture_buffer_range
+ "GL_ARB_texture_buffer_range",
+#endif
+#ifdef GL_ARB_texture_compression
+ "GL_ARB_texture_compression",
+#endif
+#ifdef GL_ARB_texture_compression_bptc
+ "GL_ARB_texture_compression_bptc",
+#endif
+#ifdef GL_ARB_texture_compression_rgtc
+ "GL_ARB_texture_compression_rgtc",
+#endif
+#ifdef GL_ARB_texture_cube_map
+ "GL_ARB_texture_cube_map",
+#endif
+#ifdef GL_ARB_texture_cube_map_array
+ "GL_ARB_texture_cube_map_array",
+#endif
+#ifdef GL_ARB_texture_env_add
+ "GL_ARB_texture_env_add",
+#endif
+#ifdef GL_ARB_texture_env_combine
+ "GL_ARB_texture_env_combine",
+#endif
+#ifdef GL_ARB_texture_env_crossbar
+ "GL_ARB_texture_env_crossbar",
+#endif
+#ifdef GL_ARB_texture_env_dot3
+ "GL_ARB_texture_env_dot3",
+#endif
+#ifdef GL_ARB_texture_filter_anisotropic
+ "GL_ARB_texture_filter_anisotropic",
+#endif
+#ifdef GL_ARB_texture_filter_minmax
+ "GL_ARB_texture_filter_minmax",
+#endif
+#ifdef GL_ARB_texture_float
+ "GL_ARB_texture_float",
+#endif
+#ifdef GL_ARB_texture_gather
+ "GL_ARB_texture_gather",
+#endif
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+ "GL_ARB_texture_mirror_clamp_to_edge",
+#endif
+#ifdef GL_ARB_texture_mirrored_repeat
+ "GL_ARB_texture_mirrored_repeat",
+#endif
+#ifdef GL_ARB_texture_multisample
+ "GL_ARB_texture_multisample",
+#endif
+#ifdef GL_ARB_texture_non_power_of_two
+ "GL_ARB_texture_non_power_of_two",
+#endif
+#ifdef GL_ARB_texture_query_levels
+ "GL_ARB_texture_query_levels",
+#endif
+#ifdef GL_ARB_texture_query_lod
+ "GL_ARB_texture_query_lod",
+#endif
+#ifdef GL_ARB_texture_rectangle
+ "GL_ARB_texture_rectangle",
+#endif
+#ifdef GL_ARB_texture_rg
+ "GL_ARB_texture_rg",
+#endif
+#ifdef GL_ARB_texture_rgb10_a2ui
+ "GL_ARB_texture_rgb10_a2ui",
+#endif
+#ifdef GL_ARB_texture_stencil8
+ "GL_ARB_texture_stencil8",
+#endif
+#ifdef GL_ARB_texture_storage
+ "GL_ARB_texture_storage",
+#endif
+#ifdef GL_ARB_texture_storage_multisample
+ "GL_ARB_texture_storage_multisample",
+#endif
+#ifdef GL_ARB_texture_swizzle
+ "GL_ARB_texture_swizzle",
+#endif
+#ifdef GL_ARB_texture_view
+ "GL_ARB_texture_view",
+#endif
+#ifdef GL_ARB_timer_query
+ "GL_ARB_timer_query",
+#endif
+#ifdef GL_ARB_transform_feedback2
+ "GL_ARB_transform_feedback2",
+#endif
+#ifdef GL_ARB_transform_feedback3
+ "GL_ARB_transform_feedback3",
+#endif
+#ifdef GL_ARB_transform_feedback_instanced
+ "GL_ARB_transform_feedback_instanced",
+#endif
+#ifdef GL_ARB_transform_feedback_overflow_query
+ "GL_ARB_transform_feedback_overflow_query",
+#endif
+#ifdef GL_ARB_transpose_matrix
+ "GL_ARB_transpose_matrix",
+#endif
+#ifdef GL_ARB_uniform_buffer_object
+ "GL_ARB_uniform_buffer_object",
+#endif
+#ifdef GL_ARB_vertex_array_bgra
+ "GL_ARB_vertex_array_bgra",
+#endif
+#ifdef GL_ARB_vertex_array_object
+ "GL_ARB_vertex_array_object",
+#endif
+#ifdef GL_ARB_vertex_attrib_64bit
+ "GL_ARB_vertex_attrib_64bit",
+#endif
+#ifdef GL_ARB_vertex_attrib_binding
+ "GL_ARB_vertex_attrib_binding",
+#endif
+#ifdef GL_ARB_vertex_blend
+ "GL_ARB_vertex_blend",
+#endif
+#ifdef GL_ARB_vertex_buffer_object
+ "GL_ARB_vertex_buffer_object",
+#endif
+#ifdef GL_ARB_vertex_program
+ "GL_ARB_vertex_program",
+#endif
+#ifdef GL_ARB_vertex_shader
+ "GL_ARB_vertex_shader",
+#endif
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+ "GL_ARB_vertex_type_10f_11f_11f_rev",
+#endif
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ "GL_ARB_vertex_type_2_10_10_10_rev",
+#endif
+#ifdef GL_ARB_viewport_array
+ "GL_ARB_viewport_array",
+#endif
+#ifdef GL_ARB_window_pos
+ "GL_ARB_window_pos",
+#endif
+#ifdef GL_ARM_mali_program_binary
+ "GL_ARM_mali_program_binary",
+#endif
+#ifdef GL_ARM_mali_shader_binary
+ "GL_ARM_mali_shader_binary",
+#endif
+#ifdef GL_ARM_rgba8
+ "GL_ARM_rgba8",
+#endif
+#ifdef GL_ARM_shader_framebuffer_fetch
+ "GL_ARM_shader_framebuffer_fetch",
+#endif
+#ifdef GL_ARM_shader_framebuffer_fetch_depth_stencil
+ "GL_ARM_shader_framebuffer_fetch_depth_stencil",
+#endif
+#ifdef GL_ATIX_point_sprites
+ "GL_ATIX_point_sprites",
+#endif
+#ifdef GL_ATIX_texture_env_combine3
+ "GL_ATIX_texture_env_combine3",
+#endif
+#ifdef GL_ATIX_texture_env_route
+ "GL_ATIX_texture_env_route",
+#endif
+#ifdef GL_ATIX_vertex_shader_output_point_size
+ "GL_ATIX_vertex_shader_output_point_size",
+#endif
+#ifdef GL_ATI_draw_buffers
+ "GL_ATI_draw_buffers",
+#endif
+#ifdef GL_ATI_element_array
+ "GL_ATI_element_array",
+#endif
+#ifdef GL_ATI_envmap_bumpmap
+ "GL_ATI_envmap_bumpmap",
+#endif
+#ifdef GL_ATI_fragment_shader
+ "GL_ATI_fragment_shader",
+#endif
+#ifdef GL_ATI_map_object_buffer
+ "GL_ATI_map_object_buffer",
+#endif
+#ifdef GL_ATI_meminfo
+ "GL_ATI_meminfo",
+#endif
+#ifdef GL_ATI_pn_triangles
+ "GL_ATI_pn_triangles",
+#endif
+#ifdef GL_ATI_separate_stencil
+ "GL_ATI_separate_stencil",
+#endif
+#ifdef GL_ATI_shader_texture_lod
+ "GL_ATI_shader_texture_lod",
+#endif
+#ifdef GL_ATI_text_fragment_shader
+ "GL_ATI_text_fragment_shader",
+#endif
+#ifdef GL_ATI_texture_compression_3dc
+ "GL_ATI_texture_compression_3dc",
+#endif
+#ifdef GL_ATI_texture_env_combine3
+ "GL_ATI_texture_env_combine3",
+#endif
+#ifdef GL_ATI_texture_float
+ "GL_ATI_texture_float",
+#endif
+#ifdef GL_ATI_texture_mirror_once
+ "GL_ATI_texture_mirror_once",
+#endif
+#ifdef GL_ATI_vertex_array_object
+ "GL_ATI_vertex_array_object",
+#endif
+#ifdef GL_ATI_vertex_attrib_array_object
+ "GL_ATI_vertex_attrib_array_object",
+#endif
+#ifdef GL_ATI_vertex_streams
+ "GL_ATI_vertex_streams",
+#endif
+#ifdef GL_EGL_KHR_context_flush_control
+ "GL_EGL_KHR_context_flush_control",
+#endif
+#ifdef GL_EGL_NV_robustness_video_memory_purge
+ "GL_EGL_NV_robustness_video_memory_purge",
+#endif
+#ifdef GL_EXT_422_pixels
+ "GL_EXT_422_pixels",
+#endif
+#ifdef GL_EXT_Cg_shader
+ "GL_EXT_Cg_shader",
+#endif
+#ifdef GL_EXT_EGL_image_array
+ "GL_EXT_EGL_image_array",
+#endif
+#ifdef GL_EXT_YUV_target
+ "GL_EXT_YUV_target",
+#endif
+#ifdef GL_EXT_abgr
+ "GL_EXT_abgr",
+#endif
+#ifdef GL_EXT_base_instance
+ "GL_EXT_base_instance",
+#endif
+#ifdef GL_EXT_bgra
+ "GL_EXT_bgra",
+#endif
+#ifdef GL_EXT_bindable_uniform
+ "GL_EXT_bindable_uniform",
+#endif
+#ifdef GL_EXT_blend_color
+ "GL_EXT_blend_color",
+#endif
+#ifdef GL_EXT_blend_equation_separate
+ "GL_EXT_blend_equation_separate",
+#endif
+#ifdef GL_EXT_blend_func_extended
+ "GL_EXT_blend_func_extended",
+#endif
+#ifdef GL_EXT_blend_func_separate
+ "GL_EXT_blend_func_separate",
+#endif
+#ifdef GL_EXT_blend_logic_op
+ "GL_EXT_blend_logic_op",
+#endif
+#ifdef GL_EXT_blend_minmax
+ "GL_EXT_blend_minmax",
+#endif
+#ifdef GL_EXT_blend_subtract
+ "GL_EXT_blend_subtract",
+#endif
+#ifdef GL_EXT_buffer_storage
+ "GL_EXT_buffer_storage",
+#endif
+#ifdef GL_EXT_clear_texture
+ "GL_EXT_clear_texture",
+#endif
+#ifdef GL_EXT_clip_cull_distance
+ "GL_EXT_clip_cull_distance",
+#endif
+#ifdef GL_EXT_clip_volume_hint
+ "GL_EXT_clip_volume_hint",
+#endif
+#ifdef GL_EXT_cmyka
+ "GL_EXT_cmyka",
+#endif
+#ifdef GL_EXT_color_buffer_float
+ "GL_EXT_color_buffer_float",
+#endif
+#ifdef GL_EXT_color_buffer_half_float
+ "GL_EXT_color_buffer_half_float",
+#endif
+#ifdef GL_EXT_color_subtable
+ "GL_EXT_color_subtable",
+#endif
+#ifdef GL_EXT_compiled_vertex_array
+ "GL_EXT_compiled_vertex_array",
+#endif
+#ifdef GL_EXT_compressed_ETC1_RGB8_sub_texture
+ "GL_EXT_compressed_ETC1_RGB8_sub_texture",
+#endif
+#ifdef GL_EXT_conservative_depth
+ "GL_EXT_conservative_depth",
+#endif
+#ifdef GL_EXT_convolution
+ "GL_EXT_convolution",
+#endif
+#ifdef GL_EXT_coordinate_frame
+ "GL_EXT_coordinate_frame",
+#endif
+#ifdef GL_EXT_copy_image
+ "GL_EXT_copy_image",
+#endif
+#ifdef GL_EXT_copy_texture
+ "GL_EXT_copy_texture",
+#endif
+#ifdef GL_EXT_cull_vertex
+ "GL_EXT_cull_vertex",
+#endif
+#ifdef GL_EXT_debug_label
+ "GL_EXT_debug_label",
+#endif
+#ifdef GL_EXT_debug_marker
+ "GL_EXT_debug_marker",
+#endif
+#ifdef GL_EXT_depth_bounds_test
+ "GL_EXT_depth_bounds_test",
+#endif
+#ifdef GL_EXT_direct_state_access
+ "GL_EXT_direct_state_access",
+#endif
+#ifdef GL_EXT_discard_framebuffer
+ "GL_EXT_discard_framebuffer",
+#endif
+#ifdef GL_EXT_draw_buffers
+ "GL_EXT_draw_buffers",
+#endif
+#ifdef GL_EXT_draw_buffers2
+ "GL_EXT_draw_buffers2",
+#endif
+#ifdef GL_EXT_draw_buffers_indexed
+ "GL_EXT_draw_buffers_indexed",
+#endif
+#ifdef GL_EXT_draw_elements_base_vertex
+ "GL_EXT_draw_elements_base_vertex",
+#endif
+#ifdef GL_EXT_draw_instanced
+ "GL_EXT_draw_instanced",
+#endif
+#ifdef GL_EXT_draw_range_elements
+ "GL_EXT_draw_range_elements",
+#endif
+#ifdef GL_EXT_external_buffer
+ "GL_EXT_external_buffer",
+#endif
+#ifdef GL_EXT_float_blend
+ "GL_EXT_float_blend",
+#endif
+#ifdef GL_EXT_fog_coord
+ "GL_EXT_fog_coord",
+#endif
+#ifdef GL_EXT_frag_depth
+ "GL_EXT_frag_depth",
+#endif
+#ifdef GL_EXT_fragment_lighting
+ "GL_EXT_fragment_lighting",
+#endif
+#ifdef GL_EXT_framebuffer_blit
+ "GL_EXT_framebuffer_blit",
+#endif
+#ifdef GL_EXT_framebuffer_multisample
+ "GL_EXT_framebuffer_multisample",
+#endif
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+ "GL_EXT_framebuffer_multisample_blit_scaled",
+#endif
+#ifdef GL_EXT_framebuffer_object
+ "GL_EXT_framebuffer_object",
+#endif
+#ifdef GL_EXT_framebuffer_sRGB
+ "GL_EXT_framebuffer_sRGB",
+#endif
+#ifdef GL_EXT_geometry_point_size
+ "GL_EXT_geometry_point_size",
+#endif
+#ifdef GL_EXT_geometry_shader
+ "GL_EXT_geometry_shader",
+#endif
+#ifdef GL_EXT_geometry_shader4
+ "GL_EXT_geometry_shader4",
+#endif
+#ifdef GL_EXT_gpu_program_parameters
+ "GL_EXT_gpu_program_parameters",
+#endif
+#ifdef GL_EXT_gpu_shader4
+ "GL_EXT_gpu_shader4",
+#endif
+#ifdef GL_EXT_gpu_shader5
+ "GL_EXT_gpu_shader5",
+#endif
+#ifdef GL_EXT_histogram
+ "GL_EXT_histogram",
+#endif
+#ifdef GL_EXT_index_array_formats
+ "GL_EXT_index_array_formats",
+#endif
+#ifdef GL_EXT_index_func
+ "GL_EXT_index_func",
+#endif
+#ifdef GL_EXT_index_material
+ "GL_EXT_index_material",
+#endif
+#ifdef GL_EXT_index_texture
+ "GL_EXT_index_texture",
+#endif
+#ifdef GL_EXT_instanced_arrays
+ "GL_EXT_instanced_arrays",
+#endif
+#ifdef GL_EXT_light_texture
+ "GL_EXT_light_texture",
+#endif
+#ifdef GL_EXT_map_buffer_range
+ "GL_EXT_map_buffer_range",
+#endif
+#ifdef GL_EXT_memory_object
+ "GL_EXT_memory_object",
+#endif
+#ifdef GL_EXT_memory_object_fd
+ "GL_EXT_memory_object_fd",
+#endif
+#ifdef GL_EXT_memory_object_win32
+ "GL_EXT_memory_object_win32",
+#endif
+#ifdef GL_EXT_misc_attribute
+ "GL_EXT_misc_attribute",
+#endif
+#ifdef GL_EXT_multi_draw_arrays
+ "GL_EXT_multi_draw_arrays",
+#endif
+#ifdef GL_EXT_multi_draw_indirect
+ "GL_EXT_multi_draw_indirect",
+#endif
+#ifdef GL_EXT_multiple_textures
+ "GL_EXT_multiple_textures",
+#endif
+#ifdef GL_EXT_multisample
+ "GL_EXT_multisample",
+#endif
+#ifdef GL_EXT_multisample_compatibility
+ "GL_EXT_multisample_compatibility",
+#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+ "GL_EXT_multisampled_render_to_texture",
+#endif
+#ifdef GL_EXT_multisampled_render_to_texture2
+ "GL_EXT_multisampled_render_to_texture2",
+#endif
+#ifdef GL_EXT_multiview_draw_buffers
+ "GL_EXT_multiview_draw_buffers",
+#endif
+#ifdef GL_EXT_packed_depth_stencil
+ "GL_EXT_packed_depth_stencil",
+#endif
+#ifdef GL_EXT_packed_float
+ "GL_EXT_packed_float",
+#endif
+#ifdef GL_EXT_packed_pixels
+ "GL_EXT_packed_pixels",
+#endif
+#ifdef GL_EXT_paletted_texture
+ "GL_EXT_paletted_texture",
+#endif
+#ifdef GL_EXT_pixel_buffer_object
+ "GL_EXT_pixel_buffer_object",
+#endif
+#ifdef GL_EXT_pixel_transform
+ "GL_EXT_pixel_transform",
+#endif
+#ifdef GL_EXT_pixel_transform_color_table
+ "GL_EXT_pixel_transform_color_table",
+#endif
+#ifdef GL_EXT_point_parameters
+ "GL_EXT_point_parameters",
+#endif
+#ifdef GL_EXT_polygon_offset
+ "GL_EXT_polygon_offset",
+#endif
+#ifdef GL_EXT_polygon_offset_clamp
+ "GL_EXT_polygon_offset_clamp",
+#endif
+#ifdef GL_EXT_post_depth_coverage
+ "GL_EXT_post_depth_coverage",
+#endif
+#ifdef GL_EXT_provoking_vertex
+ "GL_EXT_provoking_vertex",
+#endif
+#ifdef GL_EXT_pvrtc_sRGB
+ "GL_EXT_pvrtc_sRGB",
+#endif
+#ifdef GL_EXT_raster_multisample
+ "GL_EXT_raster_multisample",
+#endif
+#ifdef GL_EXT_read_format_bgra
+ "GL_EXT_read_format_bgra",
+#endif
+#ifdef GL_EXT_render_snorm
+ "GL_EXT_render_snorm",
+#endif
+#ifdef GL_EXT_rescale_normal
+ "GL_EXT_rescale_normal",
+#endif
+#ifdef GL_EXT_sRGB
+ "GL_EXT_sRGB",
+#endif
+#ifdef GL_EXT_sRGB_write_control
+ "GL_EXT_sRGB_write_control",
+#endif
+#ifdef GL_EXT_scene_marker
+ "GL_EXT_scene_marker",
+#endif
+#ifdef GL_EXT_secondary_color
+ "GL_EXT_secondary_color",
+#endif
+#ifdef GL_EXT_semaphore
+ "GL_EXT_semaphore",
+#endif
+#ifdef GL_EXT_semaphore_fd
+ "GL_EXT_semaphore_fd",
+#endif
+#ifdef GL_EXT_semaphore_win32
+ "GL_EXT_semaphore_win32",
+#endif
+#ifdef GL_EXT_separate_shader_objects
+ "GL_EXT_separate_shader_objects",
+#endif
+#ifdef GL_EXT_separate_specular_color
+ "GL_EXT_separate_specular_color",
+#endif
+#ifdef GL_EXT_shader_framebuffer_fetch
+ "GL_EXT_shader_framebuffer_fetch",
+#endif
+#ifdef GL_EXT_shader_group_vote
+ "GL_EXT_shader_group_vote",
+#endif
+#ifdef GL_EXT_shader_image_load_formatted
+ "GL_EXT_shader_image_load_formatted",
+#endif
+#ifdef GL_EXT_shader_image_load_store
+ "GL_EXT_shader_image_load_store",
+#endif
+#ifdef GL_EXT_shader_implicit_conversions
+ "GL_EXT_shader_implicit_conversions",
+#endif
+#ifdef GL_EXT_shader_integer_mix
+ "GL_EXT_shader_integer_mix",
+#endif
+#ifdef GL_EXT_shader_io_blocks
+ "GL_EXT_shader_io_blocks",
+#endif
+#ifdef GL_EXT_shader_non_constant_global_initializers
+ "GL_EXT_shader_non_constant_global_initializers",
+#endif
+#ifdef GL_EXT_shader_pixel_local_storage
+ "GL_EXT_shader_pixel_local_storage",
+#endif
+#ifdef GL_EXT_shader_pixel_local_storage2
+ "GL_EXT_shader_pixel_local_storage2",
+#endif
+#ifdef GL_EXT_shader_texture_lod
+ "GL_EXT_shader_texture_lod",
+#endif
+#ifdef GL_EXT_shadow_funcs
+ "GL_EXT_shadow_funcs",
+#endif
+#ifdef GL_EXT_shadow_samplers
+ "GL_EXT_shadow_samplers",
+#endif
+#ifdef GL_EXT_shared_texture_palette
+ "GL_EXT_shared_texture_palette",
+#endif
+#ifdef GL_EXT_sparse_texture
+ "GL_EXT_sparse_texture",
+#endif
+#ifdef GL_EXT_sparse_texture2
+ "GL_EXT_sparse_texture2",
+#endif
+#ifdef GL_EXT_stencil_clear_tag
+ "GL_EXT_stencil_clear_tag",
+#endif
+#ifdef GL_EXT_stencil_two_side
+ "GL_EXT_stencil_two_side",
+#endif
+#ifdef GL_EXT_stencil_wrap
+ "GL_EXT_stencil_wrap",
+#endif
+#ifdef GL_EXT_subtexture
+ "GL_EXT_subtexture",
+#endif
+#ifdef GL_EXT_texture
+ "GL_EXT_texture",
+#endif
+#ifdef GL_EXT_texture3D
+ "GL_EXT_texture3D",
+#endif
+#ifdef GL_EXT_texture_array
+ "GL_EXT_texture_array",
+#endif
+#ifdef GL_EXT_texture_buffer_object
+ "GL_EXT_texture_buffer_object",
+#endif
+#ifdef GL_EXT_texture_compression_astc_decode_mode
+ "GL_EXT_texture_compression_astc_decode_mode",
+#endif
+#ifdef GL_EXT_texture_compression_astc_decode_mode_rgb9e5
+ "GL_EXT_texture_compression_astc_decode_mode_rgb9e5",
+#endif
+#ifdef GL_EXT_texture_compression_bptc
+ "GL_EXT_texture_compression_bptc",
+#endif
+#ifdef GL_EXT_texture_compression_dxt1
+ "GL_EXT_texture_compression_dxt1",
+#endif
+#ifdef GL_EXT_texture_compression_latc
+ "GL_EXT_texture_compression_latc",
+#endif
+#ifdef GL_EXT_texture_compression_rgtc
+ "GL_EXT_texture_compression_rgtc",
+#endif
+#ifdef GL_EXT_texture_compression_s3tc
+ "GL_EXT_texture_compression_s3tc",
+#endif
+#ifdef GL_EXT_texture_cube_map
+ "GL_EXT_texture_cube_map",
+#endif
+#ifdef GL_EXT_texture_cube_map_array
+ "GL_EXT_texture_cube_map_array",
+#endif
+#ifdef GL_EXT_texture_edge_clamp
+ "GL_EXT_texture_edge_clamp",
+#endif
+#ifdef GL_EXT_texture_env
+ "GL_EXT_texture_env",
+#endif
+#ifdef GL_EXT_texture_env_add
+ "GL_EXT_texture_env_add",
+#endif
+#ifdef GL_EXT_texture_env_combine
+ "GL_EXT_texture_env_combine",
+#endif
+#ifdef GL_EXT_texture_env_dot3
+ "GL_EXT_texture_env_dot3",
+#endif
+#ifdef GL_EXT_texture_filter_anisotropic
+ "GL_EXT_texture_filter_anisotropic",
+#endif
+#ifdef GL_EXT_texture_filter_minmax
+ "GL_EXT_texture_filter_minmax",
+#endif
+#ifdef GL_EXT_texture_format_BGRA8888
+ "GL_EXT_texture_format_BGRA8888",
+#endif
+#ifdef GL_EXT_texture_integer
+ "GL_EXT_texture_integer",
+#endif
+#ifdef GL_EXT_texture_lod_bias
+ "GL_EXT_texture_lod_bias",
+#endif
+#ifdef GL_EXT_texture_mirror_clamp
+ "GL_EXT_texture_mirror_clamp",
+#endif
+#ifdef GL_EXT_texture_norm16
+ "GL_EXT_texture_norm16",
+#endif
+#ifdef GL_EXT_texture_object
+ "GL_EXT_texture_object",
+#endif
+#ifdef GL_EXT_texture_perturb_normal
+ "GL_EXT_texture_perturb_normal",
+#endif
+#ifdef GL_EXT_texture_rectangle
+ "GL_EXT_texture_rectangle",
+#endif
+#ifdef GL_EXT_texture_rg
+ "GL_EXT_texture_rg",
+#endif
+#ifdef GL_EXT_texture_sRGB
+ "GL_EXT_texture_sRGB",
+#endif
+#ifdef GL_EXT_texture_sRGB_R8
+ "GL_EXT_texture_sRGB_R8",
+#endif
+#ifdef GL_EXT_texture_sRGB_RG8
+ "GL_EXT_texture_sRGB_RG8",
+#endif
+#ifdef GL_EXT_texture_sRGB_decode
+ "GL_EXT_texture_sRGB_decode",
+#endif
+#ifdef GL_EXT_texture_shared_exponent
+ "GL_EXT_texture_shared_exponent",
+#endif
+#ifdef GL_EXT_texture_snorm
+ "GL_EXT_texture_snorm",
+#endif
+#ifdef GL_EXT_texture_storage
+ "GL_EXT_texture_storage",
+#endif
+#ifdef GL_EXT_texture_swizzle
+ "GL_EXT_texture_swizzle",
+#endif
+#ifdef GL_EXT_texture_type_2_10_10_10_REV
+ "GL_EXT_texture_type_2_10_10_10_REV",
+#endif
+#ifdef GL_EXT_texture_view
+ "GL_EXT_texture_view",
+#endif
+#ifdef GL_EXT_timer_query
+ "GL_EXT_timer_query",
+#endif
+#ifdef GL_EXT_transform_feedback
+ "GL_EXT_transform_feedback",
+#endif
+#ifdef GL_EXT_unpack_subimage
+ "GL_EXT_unpack_subimage",
+#endif
+#ifdef GL_EXT_vertex_array
+ "GL_EXT_vertex_array",
+#endif
+#ifdef GL_EXT_vertex_array_bgra
+ "GL_EXT_vertex_array_bgra",
+#endif
+#ifdef GL_EXT_vertex_array_setXXX
+ "GL_EXT_vertex_array_setXXX",
+#endif
+#ifdef GL_EXT_vertex_attrib_64bit
+ "GL_EXT_vertex_attrib_64bit",
+#endif
+#ifdef GL_EXT_vertex_shader
+ "GL_EXT_vertex_shader",
+#endif
+#ifdef GL_EXT_vertex_weighting
+ "GL_EXT_vertex_weighting",
+#endif
+#ifdef GL_EXT_win32_keyed_mutex
+ "GL_EXT_win32_keyed_mutex",
+#endif
+#ifdef GL_EXT_window_rectangles
+ "GL_EXT_window_rectangles",
+#endif
+#ifdef GL_EXT_x11_sync_object
+ "GL_EXT_x11_sync_object",
+#endif
+#ifdef GL_GREMEDY_frame_terminator
+ "GL_GREMEDY_frame_terminator",
+#endif
+#ifdef GL_GREMEDY_string_marker
+ "GL_GREMEDY_string_marker",
+#endif
+#ifdef GL_HP_convolution_border_modes
+ "GL_HP_convolution_border_modes",
+#endif
+#ifdef GL_HP_image_transform
+ "GL_HP_image_transform",
+#endif
+#ifdef GL_HP_occlusion_test
+ "GL_HP_occlusion_test",
+#endif
+#ifdef GL_HP_texture_lighting
+ "GL_HP_texture_lighting",
+#endif
+#ifdef GL_IBM_cull_vertex
+ "GL_IBM_cull_vertex",
+#endif
+#ifdef GL_IBM_multimode_draw_arrays
+ "GL_IBM_multimode_draw_arrays",
+#endif
+#ifdef GL_IBM_rasterpos_clip
+ "GL_IBM_rasterpos_clip",
+#endif
+#ifdef GL_IBM_static_data
+ "GL_IBM_static_data",
+#endif
+#ifdef GL_IBM_texture_mirrored_repeat
+ "GL_IBM_texture_mirrored_repeat",
+#endif
+#ifdef GL_IBM_vertex_array_lists
+ "GL_IBM_vertex_array_lists",
+#endif
+#ifdef GL_INGR_color_clamp
+ "GL_INGR_color_clamp",
+#endif
+#ifdef GL_INGR_interlace_read
+ "GL_INGR_interlace_read",
+#endif
+#ifdef GL_INTEL_conservative_rasterization
+ "GL_INTEL_conservative_rasterization",
+#endif
+#ifdef GL_INTEL_fragment_shader_ordering
+ "GL_INTEL_fragment_shader_ordering",
+#endif
+#ifdef GL_INTEL_framebuffer_CMAA
+ "GL_INTEL_framebuffer_CMAA",
+#endif
+#ifdef GL_INTEL_map_texture
+ "GL_INTEL_map_texture",
+#endif
+#ifdef GL_INTEL_parallel_arrays
+ "GL_INTEL_parallel_arrays",
+#endif
+#ifdef GL_INTEL_performance_query
+ "GL_INTEL_performance_query",
+#endif
+#ifdef GL_INTEL_texture_scissor
+ "GL_INTEL_texture_scissor",
+#endif
+#ifdef GL_KHR_blend_equation_advanced
+ "GL_KHR_blend_equation_advanced",
+#endif
+#ifdef GL_KHR_blend_equation_advanced_coherent
+ "GL_KHR_blend_equation_advanced_coherent",
+#endif
+#ifdef GL_KHR_context_flush_control
+ "GL_KHR_context_flush_control",
+#endif
+#ifdef GL_KHR_debug
+ "GL_KHR_debug",
+#endif
+#ifdef GL_KHR_no_error
+ "GL_KHR_no_error",
+#endif
+#ifdef GL_KHR_parallel_shader_compile
+ "GL_KHR_parallel_shader_compile",
+#endif
+#ifdef GL_KHR_robust_buffer_access_behavior
+ "GL_KHR_robust_buffer_access_behavior",
+#endif
+#ifdef GL_KHR_robustness
+ "GL_KHR_robustness",
+#endif
+#ifdef GL_KHR_texture_compression_astc_hdr
+ "GL_KHR_texture_compression_astc_hdr",
+#endif
+#ifdef GL_KHR_texture_compression_astc_ldr
+ "GL_KHR_texture_compression_astc_ldr",
+#endif
+#ifdef GL_KHR_texture_compression_astc_sliced_3d
+ "GL_KHR_texture_compression_astc_sliced_3d",
+#endif
+#ifdef GL_KTX_buffer_region
+ "GL_KTX_buffer_region",
+#endif
+#ifdef GL_MESAX_texture_stack
+ "GL_MESAX_texture_stack",
+#endif
+#ifdef GL_MESA_pack_invert
+ "GL_MESA_pack_invert",
+#endif
+#ifdef GL_MESA_resize_buffers
+ "GL_MESA_resize_buffers",
+#endif
+#ifdef GL_MESA_shader_integer_functions
+ "GL_MESA_shader_integer_functions",
+#endif
+#ifdef GL_MESA_window_pos
+ "GL_MESA_window_pos",
+#endif
+#ifdef GL_MESA_ycbcr_texture
+ "GL_MESA_ycbcr_texture",
+#endif
+#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers
+ "GL_NVX_blend_equation_advanced_multi_draw_buffers",
+#endif
+#ifdef GL_NVX_conditional_render
+ "GL_NVX_conditional_render",
+#endif
+#ifdef GL_NVX_gpu_memory_info
+ "GL_NVX_gpu_memory_info",
+#endif
+#ifdef GL_NVX_linked_gpu_multicast
+ "GL_NVX_linked_gpu_multicast",
+#endif
+#ifdef GL_NV_3dvision_settings
+ "GL_NV_3dvision_settings",
+#endif
+#ifdef GL_NV_EGL_stream_consumer_external
+ "GL_NV_EGL_stream_consumer_external",
+#endif
+#ifdef GL_NV_alpha_to_coverage_dither_control
+ "GL_NV_alpha_to_coverage_dither_control",
+#endif
+#ifdef GL_NV_bgr
+ "GL_NV_bgr",
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect
+ "GL_NV_bindless_multi_draw_indirect",
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect_count
+ "GL_NV_bindless_multi_draw_indirect_count",
+#endif
+#ifdef GL_NV_bindless_texture
+ "GL_NV_bindless_texture",
+#endif
+#ifdef GL_NV_blend_equation_advanced
+ "GL_NV_blend_equation_advanced",
+#endif
+#ifdef GL_NV_blend_equation_advanced_coherent
+ "GL_NV_blend_equation_advanced_coherent",
+#endif
+#ifdef GL_NV_blend_minmax_factor
+ "GL_NV_blend_minmax_factor",
+#endif
+#ifdef GL_NV_blend_square
+ "GL_NV_blend_square",
+#endif
+#ifdef GL_NV_clip_space_w_scaling
+ "GL_NV_clip_space_w_scaling",
+#endif
+#ifdef GL_NV_command_list
+ "GL_NV_command_list",
+#endif
+#ifdef GL_NV_compute_program5
+ "GL_NV_compute_program5",
+#endif
+#ifdef GL_NV_conditional_render
+ "GL_NV_conditional_render",
+#endif
+#ifdef GL_NV_conservative_raster
+ "GL_NV_conservative_raster",
+#endif
+#ifdef GL_NV_conservative_raster_dilate
+ "GL_NV_conservative_raster_dilate",
+#endif
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ "GL_NV_conservative_raster_pre_snap_triangles",
+#endif
+#ifdef GL_NV_copy_buffer
+ "GL_NV_copy_buffer",
+#endif
+#ifdef GL_NV_copy_depth_to_color
+ "GL_NV_copy_depth_to_color",
+#endif
+#ifdef GL_NV_copy_image
+ "GL_NV_copy_image",
+#endif
+#ifdef GL_NV_deep_texture3D
+ "GL_NV_deep_texture3D",
+#endif
+#ifdef GL_NV_depth_buffer_float
+ "GL_NV_depth_buffer_float",
+#endif
+#ifdef GL_NV_depth_clamp
+ "GL_NV_depth_clamp",
+#endif
+#ifdef GL_NV_depth_range_unclamped
+ "GL_NV_depth_range_unclamped",
+#endif
+#ifdef GL_NV_draw_buffers
+ "GL_NV_draw_buffers",
+#endif
+#ifdef GL_NV_draw_instanced
+ "GL_NV_draw_instanced",
+#endif
+#ifdef GL_NV_draw_texture
+ "GL_NV_draw_texture",
+#endif
+#ifdef GL_NV_draw_vulkan_image
+ "GL_NV_draw_vulkan_image",
+#endif
+#ifdef GL_NV_evaluators
+ "GL_NV_evaluators",
+#endif
+#ifdef GL_NV_explicit_attrib_location
+ "GL_NV_explicit_attrib_location",
+#endif
+#ifdef GL_NV_explicit_multisample
+ "GL_NV_explicit_multisample",
+#endif
+#ifdef GL_NV_fbo_color_attachments
+ "GL_NV_fbo_color_attachments",
+#endif
+#ifdef GL_NV_fence
+ "GL_NV_fence",
+#endif
+#ifdef GL_NV_fill_rectangle
+ "GL_NV_fill_rectangle",
+#endif
+#ifdef GL_NV_float_buffer
+ "GL_NV_float_buffer",
+#endif
+#ifdef GL_NV_fog_distance
+ "GL_NV_fog_distance",
+#endif
+#ifdef GL_NV_fragment_coverage_to_color
+ "GL_NV_fragment_coverage_to_color",
+#endif
+#ifdef GL_NV_fragment_program
+ "GL_NV_fragment_program",
+#endif
+#ifdef GL_NV_fragment_program2
+ "GL_NV_fragment_program2",
+#endif
+#ifdef GL_NV_fragment_program4
+ "GL_NV_fragment_program4",
+#endif
+#ifdef GL_NV_fragment_program_option
+ "GL_NV_fragment_program_option",
+#endif
+#ifdef GL_NV_fragment_shader_interlock
+ "GL_NV_fragment_shader_interlock",
+#endif
+#ifdef GL_NV_framebuffer_blit
+ "GL_NV_framebuffer_blit",
+#endif
+#ifdef GL_NV_framebuffer_mixed_samples
+ "GL_NV_framebuffer_mixed_samples",
+#endif
+#ifdef GL_NV_framebuffer_multisample
+ "GL_NV_framebuffer_multisample",
+#endif
+#ifdef GL_NV_framebuffer_multisample_coverage
+ "GL_NV_framebuffer_multisample_coverage",
+#endif
+#ifdef GL_NV_generate_mipmap_sRGB
+ "GL_NV_generate_mipmap_sRGB",
+#endif
+#ifdef GL_NV_geometry_program4
+ "GL_NV_geometry_program4",
+#endif
+#ifdef GL_NV_geometry_shader4
+ "GL_NV_geometry_shader4",
+#endif
+#ifdef GL_NV_geometry_shader_passthrough
+ "GL_NV_geometry_shader_passthrough",
+#endif
+#ifdef GL_NV_gpu_multicast
+ "GL_NV_gpu_multicast",
+#endif
+#ifdef GL_NV_gpu_program4
+ "GL_NV_gpu_program4",
+#endif
+#ifdef GL_NV_gpu_program5
+ "GL_NV_gpu_program5",
+#endif
+#ifdef GL_NV_gpu_program5_mem_extended
+ "GL_NV_gpu_program5_mem_extended",
+#endif
+#ifdef GL_NV_gpu_program_fp64
+ "GL_NV_gpu_program_fp64",
+#endif
+#ifdef GL_NV_gpu_shader5
+ "GL_NV_gpu_shader5",
+#endif
+#ifdef GL_NV_half_float
+ "GL_NV_half_float",
+#endif
+#ifdef GL_NV_image_formats
+ "GL_NV_image_formats",
+#endif
+#ifdef GL_NV_instanced_arrays
+ "GL_NV_instanced_arrays",
+#endif
+#ifdef GL_NV_internalformat_sample_query
+ "GL_NV_internalformat_sample_query",
+#endif
+#ifdef GL_NV_light_max_exponent
+ "GL_NV_light_max_exponent",
+#endif
+#ifdef GL_NV_multisample_coverage
+ "GL_NV_multisample_coverage",
+#endif
+#ifdef GL_NV_multisample_filter_hint
+ "GL_NV_multisample_filter_hint",
+#endif
+#ifdef GL_NV_non_square_matrices
+ "GL_NV_non_square_matrices",
+#endif
+#ifdef GL_NV_occlusion_query
+ "GL_NV_occlusion_query",
+#endif
+#ifdef GL_NV_pack_subimage
+ "GL_NV_pack_subimage",
+#endif
+#ifdef GL_NV_packed_depth_stencil
+ "GL_NV_packed_depth_stencil",
+#endif
+#ifdef GL_NV_packed_float
+ "GL_NV_packed_float",
+#endif
+#ifdef GL_NV_packed_float_linear
+ "GL_NV_packed_float_linear",
+#endif
+#ifdef GL_NV_parameter_buffer_object
+ "GL_NV_parameter_buffer_object",
+#endif
+#ifdef GL_NV_parameter_buffer_object2
+ "GL_NV_parameter_buffer_object2",
+#endif
+#ifdef GL_NV_path_rendering
+ "GL_NV_path_rendering",
+#endif
+#ifdef GL_NV_path_rendering_shared_edge
+ "GL_NV_path_rendering_shared_edge",
+#endif
+#ifdef GL_NV_pixel_buffer_object
+ "GL_NV_pixel_buffer_object",
+#endif
+#ifdef GL_NV_pixel_data_range
+ "GL_NV_pixel_data_range",
+#endif
+#ifdef GL_NV_platform_binary
+ "GL_NV_platform_binary",
+#endif
+#ifdef GL_NV_point_sprite
+ "GL_NV_point_sprite",
+#endif
+#ifdef GL_NV_polygon_mode
+ "GL_NV_polygon_mode",
+#endif
+#ifdef GL_NV_present_video
+ "GL_NV_present_video",
+#endif
+#ifdef GL_NV_primitive_restart
+ "GL_NV_primitive_restart",
+#endif
+#ifdef GL_NV_read_depth
+ "GL_NV_read_depth",
+#endif
+#ifdef GL_NV_read_depth_stencil
+ "GL_NV_read_depth_stencil",
+#endif
+#ifdef GL_NV_read_stencil
+ "GL_NV_read_stencil",
+#endif
+#ifdef GL_NV_register_combiners
+ "GL_NV_register_combiners",
+#endif
+#ifdef GL_NV_register_combiners2
+ "GL_NV_register_combiners2",
+#endif
+#ifdef GL_NV_robustness_video_memory_purge
+ "GL_NV_robustness_video_memory_purge",
+#endif
+#ifdef GL_NV_sRGB_formats
+ "GL_NV_sRGB_formats",
+#endif
+#ifdef GL_NV_sample_locations
+ "GL_NV_sample_locations",
+#endif
+#ifdef GL_NV_sample_mask_override_coverage
+ "GL_NV_sample_mask_override_coverage",
+#endif
+#ifdef GL_NV_shader_atomic_counters
+ "GL_NV_shader_atomic_counters",
+#endif
+#ifdef GL_NV_shader_atomic_float
+ "GL_NV_shader_atomic_float",
+#endif
+#ifdef GL_NV_shader_atomic_float64
+ "GL_NV_shader_atomic_float64",
+#endif
+#ifdef GL_NV_shader_atomic_fp16_vector
+ "GL_NV_shader_atomic_fp16_vector",
+#endif
+#ifdef GL_NV_shader_atomic_int64
+ "GL_NV_shader_atomic_int64",
+#endif
+#ifdef GL_NV_shader_buffer_load
+ "GL_NV_shader_buffer_load",
+#endif
+#ifdef GL_NV_shader_noperspective_interpolation
+ "GL_NV_shader_noperspective_interpolation",
+#endif
+#ifdef GL_NV_shader_storage_buffer_object
+ "GL_NV_shader_storage_buffer_object",
+#endif
+#ifdef GL_NV_shader_thread_group
+ "GL_NV_shader_thread_group",
+#endif
+#ifdef GL_NV_shader_thread_shuffle
+ "GL_NV_shader_thread_shuffle",
+#endif
+#ifdef GL_NV_shadow_samplers_array
+ "GL_NV_shadow_samplers_array",
+#endif
+#ifdef GL_NV_shadow_samplers_cube
+ "GL_NV_shadow_samplers_cube",
+#endif
+#ifdef GL_NV_stereo_view_rendering
+ "GL_NV_stereo_view_rendering",
+#endif
+#ifdef GL_NV_tessellation_program5
+ "GL_NV_tessellation_program5",
+#endif
+#ifdef GL_NV_texgen_emboss
+ "GL_NV_texgen_emboss",
+#endif
+#ifdef GL_NV_texgen_reflection
+ "GL_NV_texgen_reflection",
+#endif
+#ifdef GL_NV_texture_array
+ "GL_NV_texture_array",
+#endif
+#ifdef GL_NV_texture_barrier
+ "GL_NV_texture_barrier",
+#endif
+#ifdef GL_NV_texture_border_clamp
+ "GL_NV_texture_border_clamp",
+#endif
+#ifdef GL_NV_texture_compression_latc
+ "GL_NV_texture_compression_latc",
+#endif
+#ifdef GL_NV_texture_compression_s3tc
+ "GL_NV_texture_compression_s3tc",
+#endif
+#ifdef GL_NV_texture_compression_s3tc_update
+ "GL_NV_texture_compression_s3tc_update",
+#endif
+#ifdef GL_NV_texture_compression_vtc
+ "GL_NV_texture_compression_vtc",
+#endif
+#ifdef GL_NV_texture_env_combine4
+ "GL_NV_texture_env_combine4",
+#endif
+#ifdef GL_NV_texture_expand_normal
+ "GL_NV_texture_expand_normal",
+#endif
+#ifdef GL_NV_texture_multisample
+ "GL_NV_texture_multisample",
+#endif
+#ifdef GL_NV_texture_npot_2D_mipmap
+ "GL_NV_texture_npot_2D_mipmap",
+#endif
+#ifdef GL_NV_texture_rectangle
+ "GL_NV_texture_rectangle",
+#endif
+#ifdef GL_NV_texture_rectangle_compressed
+ "GL_NV_texture_rectangle_compressed",
+#endif
+#ifdef GL_NV_texture_shader
+ "GL_NV_texture_shader",
+#endif
+#ifdef GL_NV_texture_shader2
+ "GL_NV_texture_shader2",
+#endif
+#ifdef GL_NV_texture_shader3
+ "GL_NV_texture_shader3",
+#endif
+#ifdef GL_NV_transform_feedback
+ "GL_NV_transform_feedback",
+#endif
+#ifdef GL_NV_transform_feedback2
+ "GL_NV_transform_feedback2",
+#endif
+#ifdef GL_NV_uniform_buffer_unified_memory
+ "GL_NV_uniform_buffer_unified_memory",
+#endif
+#ifdef GL_NV_vdpau_interop
+ "GL_NV_vdpau_interop",
+#endif
+#ifdef GL_NV_vertex_array_range
+ "GL_NV_vertex_array_range",
+#endif
+#ifdef GL_NV_vertex_array_range2
+ "GL_NV_vertex_array_range2",
+#endif
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ "GL_NV_vertex_attrib_integer_64bit",
+#endif
+#ifdef GL_NV_vertex_buffer_unified_memory
+ "GL_NV_vertex_buffer_unified_memory",
+#endif
+#ifdef GL_NV_vertex_program
+ "GL_NV_vertex_program",
+#endif
+#ifdef GL_NV_vertex_program1_1
+ "GL_NV_vertex_program1_1",
+#endif
+#ifdef GL_NV_vertex_program2
+ "GL_NV_vertex_program2",
+#endif
+#ifdef GL_NV_vertex_program2_option
+ "GL_NV_vertex_program2_option",
+#endif
+#ifdef GL_NV_vertex_program3
+ "GL_NV_vertex_program3",
+#endif
+#ifdef GL_NV_vertex_program4
+ "GL_NV_vertex_program4",
+#endif
+#ifdef GL_NV_video_capture
+ "GL_NV_video_capture",
+#endif
+#ifdef GL_NV_viewport_array
+ "GL_NV_viewport_array",
+#endif
+#ifdef GL_NV_viewport_array2
+ "GL_NV_viewport_array2",
+#endif
+#ifdef GL_NV_viewport_swizzle
+ "GL_NV_viewport_swizzle",
+#endif
+#ifdef GL_OES_byte_coordinates
+ "GL_OES_byte_coordinates",
+#endif
+#ifdef GL_OML_interlace
+ "GL_OML_interlace",
+#endif
+#ifdef GL_OML_resample
+ "GL_OML_resample",
+#endif
+#ifdef GL_OML_subsample
+ "GL_OML_subsample",
+#endif
+#ifdef GL_OVR_multiview
+ "GL_OVR_multiview",
+#endif
+#ifdef GL_OVR_multiview2
+ "GL_OVR_multiview2",
+#endif
+#ifdef GL_OVR_multiview_multisampled_render_to_texture
+ "GL_OVR_multiview_multisampled_render_to_texture",
+#endif
+#ifdef GL_PGI_misc_hints
+ "GL_PGI_misc_hints",
+#endif
+#ifdef GL_PGI_vertex_hints
+ "GL_PGI_vertex_hints",
+#endif
+#ifdef GL_QCOM_alpha_test
+ "GL_QCOM_alpha_test",
+#endif
+#ifdef GL_QCOM_binning_control
+ "GL_QCOM_binning_control",
+#endif
+#ifdef GL_QCOM_driver_control
+ "GL_QCOM_driver_control",
+#endif
+#ifdef GL_QCOM_extended_get
+ "GL_QCOM_extended_get",
+#endif
+#ifdef GL_QCOM_extended_get2
+ "GL_QCOM_extended_get2",
+#endif
+#ifdef GL_QCOM_framebuffer_foveated
+ "GL_QCOM_framebuffer_foveated",
+#endif
+#ifdef GL_QCOM_perfmon_global_mode
+ "GL_QCOM_perfmon_global_mode",
+#endif
+#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent
+ "GL_QCOM_shader_framebuffer_fetch_noncoherent",
+#endif
+#ifdef GL_QCOM_tiled_rendering
+ "GL_QCOM_tiled_rendering",
+#endif
+#ifdef GL_QCOM_writeonly_rendering
+ "GL_QCOM_writeonly_rendering",
+#endif
+#ifdef GL_REGAL_ES1_0_compatibility
+ "GL_REGAL_ES1_0_compatibility",
+#endif
+#ifdef GL_REGAL_ES1_1_compatibility
+ "GL_REGAL_ES1_1_compatibility",
+#endif
+#ifdef GL_REGAL_enable
+ "GL_REGAL_enable",
+#endif
+#ifdef GL_REGAL_error_string
+ "GL_REGAL_error_string",
+#endif
+#ifdef GL_REGAL_extension_query
+ "GL_REGAL_extension_query",
+#endif
+#ifdef GL_REGAL_log
+ "GL_REGAL_log",
+#endif
+#ifdef GL_REGAL_proc_address
+ "GL_REGAL_proc_address",
+#endif
+#ifdef GL_REND_screen_coordinates
+ "GL_REND_screen_coordinates",
+#endif
+#ifdef GL_S3_s3tc
+ "GL_S3_s3tc",
+#endif
+#ifdef GL_SGIS_clip_band_hint
+ "GL_SGIS_clip_band_hint",
+#endif
+#ifdef GL_SGIS_color_range
+ "GL_SGIS_color_range",
+#endif
+#ifdef GL_SGIS_detail_texture
+ "GL_SGIS_detail_texture",
+#endif
+#ifdef GL_SGIS_fog_function
+ "GL_SGIS_fog_function",
+#endif
+#ifdef GL_SGIS_generate_mipmap
+ "GL_SGIS_generate_mipmap",
+#endif
+#ifdef GL_SGIS_line_texgen
+ "GL_SGIS_line_texgen",
+#endif
+#ifdef GL_SGIS_multisample
+ "GL_SGIS_multisample",
+#endif
+#ifdef GL_SGIS_multitexture
+ "GL_SGIS_multitexture",
+#endif
+#ifdef GL_SGIS_pixel_texture
+ "GL_SGIS_pixel_texture",
+#endif
+#ifdef GL_SGIS_point_line_texgen
+ "GL_SGIS_point_line_texgen",
+#endif
+#ifdef GL_SGIS_shared_multisample
+ "GL_SGIS_shared_multisample",
+#endif
+#ifdef GL_SGIS_sharpen_texture
+ "GL_SGIS_sharpen_texture",
+#endif
+#ifdef GL_SGIS_texture4D
+ "GL_SGIS_texture4D",
+#endif
+#ifdef GL_SGIS_texture_border_clamp
+ "GL_SGIS_texture_border_clamp",
+#endif
+#ifdef GL_SGIS_texture_edge_clamp
+ "GL_SGIS_texture_edge_clamp",
+#endif
+#ifdef GL_SGIS_texture_filter4
+ "GL_SGIS_texture_filter4",
+#endif
+#ifdef GL_SGIS_texture_lod
+ "GL_SGIS_texture_lod",
+#endif
+#ifdef GL_SGIS_texture_select
+ "GL_SGIS_texture_select",
+#endif
+#ifdef GL_SGIX_async
+ "GL_SGIX_async",
+#endif
+#ifdef GL_SGIX_async_histogram
+ "GL_SGIX_async_histogram",
+#endif
+#ifdef GL_SGIX_async_pixel
+ "GL_SGIX_async_pixel",
+#endif
+#ifdef GL_SGIX_bali_g_instruments
+ "GL_SGIX_bali_g_instruments",
+#endif
+#ifdef GL_SGIX_bali_r_instruments
+ "GL_SGIX_bali_r_instruments",
+#endif
+#ifdef GL_SGIX_bali_timer_instruments
+ "GL_SGIX_bali_timer_instruments",
+#endif
+#ifdef GL_SGIX_blend_alpha_minmax
+ "GL_SGIX_blend_alpha_minmax",
+#endif
+#ifdef GL_SGIX_blend_cadd
+ "GL_SGIX_blend_cadd",
+#endif
+#ifdef GL_SGIX_blend_cmultiply
+ "GL_SGIX_blend_cmultiply",
+#endif
+#ifdef GL_SGIX_calligraphic_fragment
+ "GL_SGIX_calligraphic_fragment",
+#endif
+#ifdef GL_SGIX_clipmap
+ "GL_SGIX_clipmap",
+#endif
+#ifdef GL_SGIX_color_matrix_accuracy
+ "GL_SGIX_color_matrix_accuracy",
+#endif
+#ifdef GL_SGIX_color_table_index_mode
+ "GL_SGIX_color_table_index_mode",
+#endif
+#ifdef GL_SGIX_complex_polar
+ "GL_SGIX_complex_polar",
+#endif
+#ifdef GL_SGIX_convolution_accuracy
+ "GL_SGIX_convolution_accuracy",
+#endif
+#ifdef GL_SGIX_cube_map
+ "GL_SGIX_cube_map",
+#endif
+#ifdef GL_SGIX_cylinder_texgen
+ "GL_SGIX_cylinder_texgen",
+#endif
+#ifdef GL_SGIX_datapipe
+ "GL_SGIX_datapipe",
+#endif
+#ifdef GL_SGIX_decimation
+ "GL_SGIX_decimation",
+#endif
+#ifdef GL_SGIX_depth_pass_instrument
+ "GL_SGIX_depth_pass_instrument",
+#endif
+#ifdef GL_SGIX_depth_texture
+ "GL_SGIX_depth_texture",
+#endif
+#ifdef GL_SGIX_dvc
+ "GL_SGIX_dvc",
+#endif
+#ifdef GL_SGIX_flush_raster
+ "GL_SGIX_flush_raster",
+#endif
+#ifdef GL_SGIX_fog_blend
+ "GL_SGIX_fog_blend",
+#endif
+#ifdef GL_SGIX_fog_factor_to_alpha
+ "GL_SGIX_fog_factor_to_alpha",
+#endif
+#ifdef GL_SGIX_fog_layers
+ "GL_SGIX_fog_layers",
+#endif
+#ifdef GL_SGIX_fog_offset
+ "GL_SGIX_fog_offset",
+#endif
+#ifdef GL_SGIX_fog_patchy
+ "GL_SGIX_fog_patchy",
+#endif
+#ifdef GL_SGIX_fog_scale
+ "GL_SGIX_fog_scale",
+#endif
+#ifdef GL_SGIX_fog_texture
+ "GL_SGIX_fog_texture",
+#endif
+#ifdef GL_SGIX_fragment_lighting_space
+ "GL_SGIX_fragment_lighting_space",
+#endif
+#ifdef GL_SGIX_fragment_specular_lighting
+ "GL_SGIX_fragment_specular_lighting",
+#endif
+#ifdef GL_SGIX_fragments_instrument
+ "GL_SGIX_fragments_instrument",
+#endif
+#ifdef GL_SGIX_framezoom
+ "GL_SGIX_framezoom",
+#endif
+#ifdef GL_SGIX_icc_texture
+ "GL_SGIX_icc_texture",
+#endif
+#ifdef GL_SGIX_igloo_interface
+ "GL_SGIX_igloo_interface",
+#endif
+#ifdef GL_SGIX_image_compression
+ "GL_SGIX_image_compression",
+#endif
+#ifdef GL_SGIX_impact_pixel_texture
+ "GL_SGIX_impact_pixel_texture",
+#endif
+#ifdef GL_SGIX_instrument_error
+ "GL_SGIX_instrument_error",
+#endif
+#ifdef GL_SGIX_interlace
+ "GL_SGIX_interlace",
+#endif
+#ifdef GL_SGIX_ir_instrument1
+ "GL_SGIX_ir_instrument1",
+#endif
+#ifdef GL_SGIX_line_quality_hint
+ "GL_SGIX_line_quality_hint",
+#endif
+#ifdef GL_SGIX_list_priority
+ "GL_SGIX_list_priority",
+#endif
+#ifdef GL_SGIX_mpeg1
+ "GL_SGIX_mpeg1",
+#endif
+#ifdef GL_SGIX_mpeg2
+ "GL_SGIX_mpeg2",
+#endif
+#ifdef GL_SGIX_nonlinear_lighting_pervertex
+ "GL_SGIX_nonlinear_lighting_pervertex",
+#endif
+#ifdef GL_SGIX_nurbs_eval
+ "GL_SGIX_nurbs_eval",
+#endif
+#ifdef GL_SGIX_occlusion_instrument
+ "GL_SGIX_occlusion_instrument",
+#endif
+#ifdef GL_SGIX_packed_6bytes
+ "GL_SGIX_packed_6bytes",
+#endif
+#ifdef GL_SGIX_pixel_texture
+ "GL_SGIX_pixel_texture",
+#endif
+#ifdef GL_SGIX_pixel_texture_bits
+ "GL_SGIX_pixel_texture_bits",
+#endif
+#ifdef GL_SGIX_pixel_texture_lod
+ "GL_SGIX_pixel_texture_lod",
+#endif
+#ifdef GL_SGIX_pixel_tiles
+ "GL_SGIX_pixel_tiles",
+#endif
+#ifdef GL_SGIX_polynomial_ffd
+ "GL_SGIX_polynomial_ffd",
+#endif
+#ifdef GL_SGIX_quad_mesh
+ "GL_SGIX_quad_mesh",
+#endif
+#ifdef GL_SGIX_reference_plane
+ "GL_SGIX_reference_plane",
+#endif
+#ifdef GL_SGIX_resample
+ "GL_SGIX_resample",
+#endif
+#ifdef GL_SGIX_scalebias_hint
+ "GL_SGIX_scalebias_hint",
+#endif
+#ifdef GL_SGIX_shadow
+ "GL_SGIX_shadow",
+#endif
+#ifdef GL_SGIX_shadow_ambient
+ "GL_SGIX_shadow_ambient",
+#endif
+#ifdef GL_SGIX_slim
+ "GL_SGIX_slim",
+#endif
+#ifdef GL_SGIX_spotlight_cutoff
+ "GL_SGIX_spotlight_cutoff",
+#endif
+#ifdef GL_SGIX_sprite
+ "GL_SGIX_sprite",
+#endif
+#ifdef GL_SGIX_subdiv_patch
+ "GL_SGIX_subdiv_patch",
+#endif
+#ifdef GL_SGIX_subsample
+ "GL_SGIX_subsample",
+#endif
+#ifdef GL_SGIX_tag_sample_buffer
+ "GL_SGIX_tag_sample_buffer",
+#endif
+#ifdef GL_SGIX_texture_add_env
+ "GL_SGIX_texture_add_env",
+#endif
+#ifdef GL_SGIX_texture_coordinate_clamp
+ "GL_SGIX_texture_coordinate_clamp",
+#endif
+#ifdef GL_SGIX_texture_lod_bias
+ "GL_SGIX_texture_lod_bias",
+#endif
+#ifdef GL_SGIX_texture_mipmap_anisotropic
+ "GL_SGIX_texture_mipmap_anisotropic",
+#endif
+#ifdef GL_SGIX_texture_multi_buffer
+ "GL_SGIX_texture_multi_buffer",
+#endif
+#ifdef GL_SGIX_texture_phase
+ "GL_SGIX_texture_phase",
+#endif
+#ifdef GL_SGIX_texture_range
+ "GL_SGIX_texture_range",
+#endif
+#ifdef GL_SGIX_texture_scale_bias
+ "GL_SGIX_texture_scale_bias",
+#endif
+#ifdef GL_SGIX_texture_supersample
+ "GL_SGIX_texture_supersample",
+#endif
+#ifdef GL_SGIX_vector_ops
+ "GL_SGIX_vector_ops",
+#endif
+#ifdef GL_SGIX_vertex_array_object
+ "GL_SGIX_vertex_array_object",
+#endif
+#ifdef GL_SGIX_vertex_preclip
+ "GL_SGIX_vertex_preclip",
+#endif
+#ifdef GL_SGIX_vertex_preclip_hint
+ "GL_SGIX_vertex_preclip_hint",
+#endif
+#ifdef GL_SGIX_ycrcb
+ "GL_SGIX_ycrcb",
+#endif
+#ifdef GL_SGIX_ycrcb_subsample
+ "GL_SGIX_ycrcb_subsample",
+#endif
+#ifdef GL_SGIX_ycrcba
+ "GL_SGIX_ycrcba",
+#endif
+#ifdef GL_SGI_color_matrix
+ "GL_SGI_color_matrix",
+#endif
+#ifdef GL_SGI_color_table
+ "GL_SGI_color_table",
+#endif
+#ifdef GL_SGI_complex
+ "GL_SGI_complex",
+#endif
+#ifdef GL_SGI_complex_type
+ "GL_SGI_complex_type",
+#endif
+#ifdef GL_SGI_fft
+ "GL_SGI_fft",
+#endif
+#ifdef GL_SGI_texture_color_table
+ "GL_SGI_texture_color_table",
+#endif
+#ifdef GL_SUNX_constant_data
+ "GL_SUNX_constant_data",
+#endif
+#ifdef GL_SUN_convolution_border_modes
+ "GL_SUN_convolution_border_modes",
+#endif
+#ifdef GL_SUN_global_alpha
+ "GL_SUN_global_alpha",
+#endif
+#ifdef GL_SUN_mesh_array
+ "GL_SUN_mesh_array",
+#endif
+#ifdef GL_SUN_read_video_pixels
+ "GL_SUN_read_video_pixels",
+#endif
+#ifdef GL_SUN_slice_accum
+ "GL_SUN_slice_accum",
+#endif
+#ifdef GL_SUN_triangle_list
+ "GL_SUN_triangle_list",
+#endif
+#ifdef GL_SUN_vertex
+ "GL_SUN_vertex",
+#endif
+#ifdef GL_WIN_phong_shading
+ "GL_WIN_phong_shading",
+#endif
+#ifdef GL_WIN_scene_markerXXX
+ "GL_WIN_scene_markerXXX",
+#endif
+#ifdef GL_WIN_specular_fog
+ "GL_WIN_specular_fog",
+#endif
+#ifdef GL_WIN_swap_hint
+ "GL_WIN_swap_hint",
+#endif
+ NULL
+};
+
+/* Detected in the extension string or strings */
+static GLboolean _glewExtensionString[801];
+/* Detected via extension string or experimental mode */
+static GLboolean* _glewExtensionEnabled[] = {
+#ifdef GL_VERSION_1_2
+ &__GLEW_VERSION_1_2,
+#endif
+#ifdef GL_VERSION_1_2_1
+ &__GLEW_VERSION_1_2_1,
+#endif
+#ifdef GL_VERSION_1_3
+ &__GLEW_VERSION_1_3,
+#endif
+#ifdef GL_VERSION_1_4
+ &__GLEW_VERSION_1_4,
+#endif
+#ifdef GL_VERSION_1_5
+ &__GLEW_VERSION_1_5,
+#endif
+#ifdef GL_VERSION_2_0
+ &__GLEW_VERSION_2_0,
+#endif
+#ifdef GL_VERSION_2_1
+ &__GLEW_VERSION_2_1,
+#endif
+#ifdef GL_VERSION_3_0
+ &__GLEW_VERSION_3_0,
+#endif
+#ifdef GL_VERSION_3_1
+ &__GLEW_VERSION_3_1,
+#endif
+#ifdef GL_VERSION_3_2
+ &__GLEW_VERSION_3_2,
+#endif
+#ifdef GL_VERSION_3_3
+ &__GLEW_VERSION_3_3,
+#endif
+#ifdef GL_VERSION_4_0
+ &__GLEW_VERSION_4_0,
+#endif
+#ifdef GL_VERSION_4_1
+ &__GLEW_VERSION_4_1,
+#endif
+#ifdef GL_VERSION_4_2
+ &__GLEW_VERSION_4_2,
+#endif
+#ifdef GL_VERSION_4_3
+ &__GLEW_VERSION_4_3,
+#endif
+#ifdef GL_VERSION_4_4
+ &__GLEW_VERSION_4_4,
+#endif
+#ifdef GL_VERSION_4_5
+ &__GLEW_VERSION_4_5,
+#endif
+#ifdef GL_VERSION_4_6
+ &__GLEW_VERSION_4_6,
+#endif
+#ifdef GL_3DFX_multisample
+ &__GLEW_3DFX_multisample,
+#endif
+#ifdef GL_3DFX_tbuffer
+ &__GLEW_3DFX_tbuffer,
+#endif
+#ifdef GL_3DFX_texture_compression_FXT1
+ &__GLEW_3DFX_texture_compression_FXT1,
+#endif
+#ifdef GL_AMD_blend_minmax_factor
+ &__GLEW_AMD_blend_minmax_factor,
+#endif
+#ifdef GL_AMD_compressed_3DC_texture
+ &__GLEW_AMD_compressed_3DC_texture,
+#endif
+#ifdef GL_AMD_compressed_ATC_texture
+ &__GLEW_AMD_compressed_ATC_texture,
+#endif
+#ifdef GL_AMD_conservative_depth
+ &__GLEW_AMD_conservative_depth,
+#endif
+#ifdef GL_AMD_debug_output
+ &__GLEW_AMD_debug_output,
+#endif
+#ifdef GL_AMD_depth_clamp_separate
+ &__GLEW_AMD_depth_clamp_separate,
+#endif
+#ifdef GL_AMD_draw_buffers_blend
+ &__GLEW_AMD_draw_buffers_blend,
+#endif
+#ifdef GL_AMD_framebuffer_sample_positions
+ &__GLEW_AMD_framebuffer_sample_positions,
+#endif
+#ifdef GL_AMD_gcn_shader
+ &__GLEW_AMD_gcn_shader,
+#endif
+#ifdef GL_AMD_gpu_shader_half_float
+ &__GLEW_AMD_gpu_shader_half_float,
+#endif
+#ifdef GL_AMD_gpu_shader_int16
+ &__GLEW_AMD_gpu_shader_int16,
+#endif
+#ifdef GL_AMD_gpu_shader_int64
+ &__GLEW_AMD_gpu_shader_int64,
+#endif
+#ifdef GL_AMD_interleaved_elements
+ &__GLEW_AMD_interleaved_elements,
+#endif
+#ifdef GL_AMD_multi_draw_indirect
+ &__GLEW_AMD_multi_draw_indirect,
+#endif
+#ifdef GL_AMD_name_gen_delete
+ &__GLEW_AMD_name_gen_delete,
+#endif
+#ifdef GL_AMD_occlusion_query_event
+ &__GLEW_AMD_occlusion_query_event,
+#endif
+#ifdef GL_AMD_performance_monitor
+ &__GLEW_AMD_performance_monitor,
+#endif
+#ifdef GL_AMD_pinned_memory
+ &__GLEW_AMD_pinned_memory,
+#endif
+#ifdef GL_AMD_program_binary_Z400
+ &__GLEW_AMD_program_binary_Z400,
+#endif
+#ifdef GL_AMD_query_buffer_object
+ &__GLEW_AMD_query_buffer_object,
+#endif
+#ifdef GL_AMD_sample_positions
+ &__GLEW_AMD_sample_positions,
+#endif
+#ifdef GL_AMD_seamless_cubemap_per_texture
+ &__GLEW_AMD_seamless_cubemap_per_texture,
+#endif
+#ifdef GL_AMD_shader_atomic_counter_ops
+ &__GLEW_AMD_shader_atomic_counter_ops,
+#endif
+#ifdef GL_AMD_shader_ballot
+ &__GLEW_AMD_shader_ballot,
+#endif
+#ifdef GL_AMD_shader_explicit_vertex_parameter
+ &__GLEW_AMD_shader_explicit_vertex_parameter,
+#endif
+#ifdef GL_AMD_shader_stencil_export
+ &__GLEW_AMD_shader_stencil_export,
+#endif
+#ifdef GL_AMD_shader_stencil_value_export
+ &__GLEW_AMD_shader_stencil_value_export,
+#endif
+#ifdef GL_AMD_shader_trinary_minmax
+ &__GLEW_AMD_shader_trinary_minmax,
+#endif
+#ifdef GL_AMD_sparse_texture
+ &__GLEW_AMD_sparse_texture,
+#endif
+#ifdef GL_AMD_stencil_operation_extended
+ &__GLEW_AMD_stencil_operation_extended,
+#endif
+#ifdef GL_AMD_texture_gather_bias_lod
+ &__GLEW_AMD_texture_gather_bias_lod,
+#endif
+#ifdef GL_AMD_texture_texture4
+ &__GLEW_AMD_texture_texture4,
+#endif
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+ &__GLEW_AMD_transform_feedback3_lines_triangles,
+#endif
+#ifdef GL_AMD_transform_feedback4
+ &__GLEW_AMD_transform_feedback4,
+#endif
+#ifdef GL_AMD_vertex_shader_layer
+ &__GLEW_AMD_vertex_shader_layer,
+#endif
+#ifdef GL_AMD_vertex_shader_tessellator
+ &__GLEW_AMD_vertex_shader_tessellator,
+#endif
+#ifdef GL_AMD_vertex_shader_viewport_index
+ &__GLEW_AMD_vertex_shader_viewport_index,
+#endif
+#ifdef GL_ANDROID_extension_pack_es31a
+ &__GLEW_ANDROID_extension_pack_es31a,
+#endif
+#ifdef GL_ANGLE_depth_texture
+ &__GLEW_ANGLE_depth_texture,
+#endif
+#ifdef GL_ANGLE_framebuffer_blit
+ &__GLEW_ANGLE_framebuffer_blit,
+#endif
+#ifdef GL_ANGLE_framebuffer_multisample
+ &__GLEW_ANGLE_framebuffer_multisample,
+#endif
+#ifdef GL_ANGLE_instanced_arrays
+ &__GLEW_ANGLE_instanced_arrays,
+#endif
+#ifdef GL_ANGLE_pack_reverse_row_order
+ &__GLEW_ANGLE_pack_reverse_row_order,
+#endif
+#ifdef GL_ANGLE_program_binary
+ &__GLEW_ANGLE_program_binary,
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt1
+ &__GLEW_ANGLE_texture_compression_dxt1,
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt3
+ &__GLEW_ANGLE_texture_compression_dxt3,
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt5
+ &__GLEW_ANGLE_texture_compression_dxt5,
+#endif
+#ifdef GL_ANGLE_texture_usage
+ &__GLEW_ANGLE_texture_usage,
+#endif
+#ifdef GL_ANGLE_timer_query
+ &__GLEW_ANGLE_timer_query,
+#endif
+#ifdef GL_ANGLE_translated_shader_source
+ &__GLEW_ANGLE_translated_shader_source,
+#endif
+#ifdef GL_APPLE_aux_depth_stencil
+ &__GLEW_APPLE_aux_depth_stencil,
+#endif
+#ifdef GL_APPLE_client_storage
+ &__GLEW_APPLE_client_storage,
+#endif
+#ifdef GL_APPLE_clip_distance
+ &__GLEW_APPLE_clip_distance,
+#endif
+#ifdef GL_APPLE_color_buffer_packed_float
+ &__GLEW_APPLE_color_buffer_packed_float,
+#endif
+#ifdef GL_APPLE_copy_texture_levels
+ &__GLEW_APPLE_copy_texture_levels,
+#endif
+#ifdef GL_APPLE_element_array
+ &__GLEW_APPLE_element_array,
+#endif
+#ifdef GL_APPLE_fence
+ &__GLEW_APPLE_fence,
+#endif
+#ifdef GL_APPLE_float_pixels
+ &__GLEW_APPLE_float_pixels,
+#endif
+#ifdef GL_APPLE_flush_buffer_range
+ &__GLEW_APPLE_flush_buffer_range,
+#endif
+#ifdef GL_APPLE_framebuffer_multisample
+ &__GLEW_APPLE_framebuffer_multisample,
+#endif
+#ifdef GL_APPLE_object_purgeable
+ &__GLEW_APPLE_object_purgeable,
+#endif
+#ifdef GL_APPLE_pixel_buffer
+ &__GLEW_APPLE_pixel_buffer,
+#endif
+#ifdef GL_APPLE_rgb_422
+ &__GLEW_APPLE_rgb_422,
+#endif
+#ifdef GL_APPLE_row_bytes
+ &__GLEW_APPLE_row_bytes,
+#endif
+#ifdef GL_APPLE_specular_vector
+ &__GLEW_APPLE_specular_vector,
+#endif
+#ifdef GL_APPLE_sync
+ &__GLEW_APPLE_sync,
+#endif
+#ifdef GL_APPLE_texture_2D_limited_npot
+ &__GLEW_APPLE_texture_2D_limited_npot,
+#endif
+#ifdef GL_APPLE_texture_format_BGRA8888
+ &__GLEW_APPLE_texture_format_BGRA8888,
+#endif
+#ifdef GL_APPLE_texture_max_level
+ &__GLEW_APPLE_texture_max_level,
+#endif
+#ifdef GL_APPLE_texture_packed_float
+ &__GLEW_APPLE_texture_packed_float,
+#endif
+#ifdef GL_APPLE_texture_range
+ &__GLEW_APPLE_texture_range,
+#endif
+#ifdef GL_APPLE_transform_hint
+ &__GLEW_APPLE_transform_hint,
+#endif
+#ifdef GL_APPLE_vertex_array_object
+ &__GLEW_APPLE_vertex_array_object,
+#endif
+#ifdef GL_APPLE_vertex_array_range
+ &__GLEW_APPLE_vertex_array_range,
+#endif
+#ifdef GL_APPLE_vertex_program_evaluators
+ &__GLEW_APPLE_vertex_program_evaluators,
+#endif
+#ifdef GL_APPLE_ycbcr_422
+ &__GLEW_APPLE_ycbcr_422,
+#endif
+#ifdef GL_ARB_ES2_compatibility
+ &__GLEW_ARB_ES2_compatibility,
+#endif
+#ifdef GL_ARB_ES3_1_compatibility
+ &__GLEW_ARB_ES3_1_compatibility,
+#endif
+#ifdef GL_ARB_ES3_2_compatibility
+ &__GLEW_ARB_ES3_2_compatibility,
+#endif
+#ifdef GL_ARB_ES3_compatibility
+ &__GLEW_ARB_ES3_compatibility,
+#endif
+#ifdef GL_ARB_arrays_of_arrays
+ &__GLEW_ARB_arrays_of_arrays,
+#endif
+#ifdef GL_ARB_base_instance
+ &__GLEW_ARB_base_instance,
+#endif
+#ifdef GL_ARB_bindless_texture
+ &__GLEW_ARB_bindless_texture,
+#endif
+#ifdef GL_ARB_blend_func_extended
+ &__GLEW_ARB_blend_func_extended,
+#endif
+#ifdef GL_ARB_buffer_storage
+ &__GLEW_ARB_buffer_storage,
+#endif
+#ifdef GL_ARB_cl_event
+ &__GLEW_ARB_cl_event,
+#endif
+#ifdef GL_ARB_clear_buffer_object
+ &__GLEW_ARB_clear_buffer_object,
+#endif
+#ifdef GL_ARB_clear_texture
+ &__GLEW_ARB_clear_texture,
+#endif
+#ifdef GL_ARB_clip_control
+ &__GLEW_ARB_clip_control,
+#endif
+#ifdef GL_ARB_color_buffer_float
+ &__GLEW_ARB_color_buffer_float,
+#endif
+#ifdef GL_ARB_compatibility
+ &__GLEW_ARB_compatibility,
+#endif
+#ifdef GL_ARB_compressed_texture_pixel_storage
+ &__GLEW_ARB_compressed_texture_pixel_storage,
+#endif
+#ifdef GL_ARB_compute_shader
+ &__GLEW_ARB_compute_shader,
+#endif
+#ifdef GL_ARB_compute_variable_group_size
+ &__GLEW_ARB_compute_variable_group_size,
+#endif
+#ifdef GL_ARB_conditional_render_inverted
+ &__GLEW_ARB_conditional_render_inverted,
+#endif
+#ifdef GL_ARB_conservative_depth
+ &__GLEW_ARB_conservative_depth,
+#endif
+#ifdef GL_ARB_copy_buffer
+ &__GLEW_ARB_copy_buffer,
+#endif
+#ifdef GL_ARB_copy_image
+ &__GLEW_ARB_copy_image,
+#endif
+#ifdef GL_ARB_cull_distance
+ &__GLEW_ARB_cull_distance,
+#endif
+#ifdef GL_ARB_debug_output
+ &__GLEW_ARB_debug_output,
+#endif
+#ifdef GL_ARB_depth_buffer_float
+ &__GLEW_ARB_depth_buffer_float,
+#endif
+#ifdef GL_ARB_depth_clamp
+ &__GLEW_ARB_depth_clamp,
+#endif
+#ifdef GL_ARB_depth_texture
+ &__GLEW_ARB_depth_texture,
+#endif
+#ifdef GL_ARB_derivative_control
+ &__GLEW_ARB_derivative_control,
+#endif
+#ifdef GL_ARB_direct_state_access
+ &__GLEW_ARB_direct_state_access,
+#endif
+#ifdef GL_ARB_draw_buffers
+ &__GLEW_ARB_draw_buffers,
+#endif
+#ifdef GL_ARB_draw_buffers_blend
+ &__GLEW_ARB_draw_buffers_blend,
+#endif
+#ifdef GL_ARB_draw_elements_base_vertex
+ &__GLEW_ARB_draw_elements_base_vertex,
+#endif
+#ifdef GL_ARB_draw_indirect
+ &__GLEW_ARB_draw_indirect,
+#endif
+#ifdef GL_ARB_draw_instanced
+ &__GLEW_ARB_draw_instanced,
+#endif
+#ifdef GL_ARB_enhanced_layouts
+ &__GLEW_ARB_enhanced_layouts,
+#endif
+#ifdef GL_ARB_explicit_attrib_location
+ &__GLEW_ARB_explicit_attrib_location,
+#endif
+#ifdef GL_ARB_explicit_uniform_location
+ &__GLEW_ARB_explicit_uniform_location,
+#endif
+#ifdef GL_ARB_fragment_coord_conventions
+ &__GLEW_ARB_fragment_coord_conventions,
+#endif
+#ifdef GL_ARB_fragment_layer_viewport
+ &__GLEW_ARB_fragment_layer_viewport,
+#endif
+#ifdef GL_ARB_fragment_program
+ &__GLEW_ARB_fragment_program,
+#endif
+#ifdef GL_ARB_fragment_program_shadow
+ &__GLEW_ARB_fragment_program_shadow,
+#endif
+#ifdef GL_ARB_fragment_shader
+ &__GLEW_ARB_fragment_shader,
+#endif
+#ifdef GL_ARB_fragment_shader_interlock
+ &__GLEW_ARB_fragment_shader_interlock,
+#endif
+#ifdef GL_ARB_framebuffer_no_attachments
+ &__GLEW_ARB_framebuffer_no_attachments,
+#endif
+#ifdef GL_ARB_framebuffer_object
+ &__GLEW_ARB_framebuffer_object,
+#endif
+#ifdef GL_ARB_framebuffer_sRGB
+ &__GLEW_ARB_framebuffer_sRGB,
+#endif
+#ifdef GL_ARB_geometry_shader4
+ &__GLEW_ARB_geometry_shader4,
+#endif
+#ifdef GL_ARB_get_program_binary
+ &__GLEW_ARB_get_program_binary,
+#endif
+#ifdef GL_ARB_get_texture_sub_image
+ &__GLEW_ARB_get_texture_sub_image,
+#endif
+#ifdef GL_ARB_gl_spirv
+ &__GLEW_ARB_gl_spirv,
+#endif
+#ifdef GL_ARB_gpu_shader5
+ &__GLEW_ARB_gpu_shader5,
+#endif
+#ifdef GL_ARB_gpu_shader_fp64
+ &__GLEW_ARB_gpu_shader_fp64,
+#endif
+#ifdef GL_ARB_gpu_shader_int64
+ &__GLEW_ARB_gpu_shader_int64,
+#endif
+#ifdef GL_ARB_half_float_pixel
+ &__GLEW_ARB_half_float_pixel,
+#endif
+#ifdef GL_ARB_half_float_vertex
+ &__GLEW_ARB_half_float_vertex,
+#endif
+#ifdef GL_ARB_imaging
+ &__GLEW_ARB_imaging,
+#endif
+#ifdef GL_ARB_indirect_parameters
+ &__GLEW_ARB_indirect_parameters,
+#endif
+#ifdef GL_ARB_instanced_arrays
+ &__GLEW_ARB_instanced_arrays,
+#endif
+#ifdef GL_ARB_internalformat_query
+ &__GLEW_ARB_internalformat_query,
+#endif
+#ifdef GL_ARB_internalformat_query2
+ &__GLEW_ARB_internalformat_query2,
+#endif
+#ifdef GL_ARB_invalidate_subdata
+ &__GLEW_ARB_invalidate_subdata,
+#endif
+#ifdef GL_ARB_map_buffer_alignment
+ &__GLEW_ARB_map_buffer_alignment,
+#endif
+#ifdef GL_ARB_map_buffer_range
+ &__GLEW_ARB_map_buffer_range,
+#endif
+#ifdef GL_ARB_matrix_palette
+ &__GLEW_ARB_matrix_palette,
+#endif
+#ifdef GL_ARB_multi_bind
+ &__GLEW_ARB_multi_bind,
+#endif
+#ifdef GL_ARB_multi_draw_indirect
+ &__GLEW_ARB_multi_draw_indirect,
+#endif
+#ifdef GL_ARB_multisample
+ &__GLEW_ARB_multisample,
+#endif
+#ifdef GL_ARB_multitexture
+ &__GLEW_ARB_multitexture,
+#endif
+#ifdef GL_ARB_occlusion_query
+ &__GLEW_ARB_occlusion_query,
+#endif
+#ifdef GL_ARB_occlusion_query2
+ &__GLEW_ARB_occlusion_query2,
+#endif
+#ifdef GL_ARB_parallel_shader_compile
+ &__GLEW_ARB_parallel_shader_compile,
+#endif
+#ifdef GL_ARB_pipeline_statistics_query
+ &__GLEW_ARB_pipeline_statistics_query,
+#endif
+#ifdef GL_ARB_pixel_buffer_object
+ &__GLEW_ARB_pixel_buffer_object,
+#endif
+#ifdef GL_ARB_point_parameters
+ &__GLEW_ARB_point_parameters,
+#endif
+#ifdef GL_ARB_point_sprite
+ &__GLEW_ARB_point_sprite,
+#endif
+#ifdef GL_ARB_polygon_offset_clamp
+ &__GLEW_ARB_polygon_offset_clamp,
+#endif
+#ifdef GL_ARB_post_depth_coverage
+ &__GLEW_ARB_post_depth_coverage,
+#endif
+#ifdef GL_ARB_program_interface_query
+ &__GLEW_ARB_program_interface_query,
+#endif
+#ifdef GL_ARB_provoking_vertex
+ &__GLEW_ARB_provoking_vertex,
+#endif
+#ifdef GL_ARB_query_buffer_object
+ &__GLEW_ARB_query_buffer_object,
+#endif
+#ifdef GL_ARB_robust_buffer_access_behavior
+ &__GLEW_ARB_robust_buffer_access_behavior,
+#endif
+#ifdef GL_ARB_robustness
+ &__GLEW_ARB_robustness,
+#endif
+#ifdef GL_ARB_robustness_application_isolation
+ &__GLEW_ARB_robustness_application_isolation,
+#endif
+#ifdef GL_ARB_robustness_share_group_isolation
+ &__GLEW_ARB_robustness_share_group_isolation,
+#endif
+#ifdef GL_ARB_sample_locations
+ &__GLEW_ARB_sample_locations,
+#endif
+#ifdef GL_ARB_sample_shading
+ &__GLEW_ARB_sample_shading,
+#endif
+#ifdef GL_ARB_sampler_objects
+ &__GLEW_ARB_sampler_objects,
+#endif
+#ifdef GL_ARB_seamless_cube_map
+ &__GLEW_ARB_seamless_cube_map,
+#endif
+#ifdef GL_ARB_seamless_cubemap_per_texture
+ &__GLEW_ARB_seamless_cubemap_per_texture,
+#endif
+#ifdef GL_ARB_separate_shader_objects
+ &__GLEW_ARB_separate_shader_objects,
+#endif
+#ifdef GL_ARB_shader_atomic_counter_ops
+ &__GLEW_ARB_shader_atomic_counter_ops,
+#endif
+#ifdef GL_ARB_shader_atomic_counters
+ &__GLEW_ARB_shader_atomic_counters,
+#endif
+#ifdef GL_ARB_shader_ballot
+ &__GLEW_ARB_shader_ballot,
+#endif
+#ifdef GL_ARB_shader_bit_encoding
+ &__GLEW_ARB_shader_bit_encoding,
+#endif
+#ifdef GL_ARB_shader_clock
+ &__GLEW_ARB_shader_clock,
+#endif
+#ifdef GL_ARB_shader_draw_parameters
+ &__GLEW_ARB_shader_draw_parameters,
+#endif
+#ifdef GL_ARB_shader_group_vote
+ &__GLEW_ARB_shader_group_vote,
+#endif
+#ifdef GL_ARB_shader_image_load_store
+ &__GLEW_ARB_shader_image_load_store,
+#endif
+#ifdef GL_ARB_shader_image_size
+ &__GLEW_ARB_shader_image_size,
+#endif
+#ifdef GL_ARB_shader_objects
+ &__GLEW_ARB_shader_objects,
+#endif
+#ifdef GL_ARB_shader_precision
+ &__GLEW_ARB_shader_precision,
+#endif
+#ifdef GL_ARB_shader_stencil_export
+ &__GLEW_ARB_shader_stencil_export,
+#endif
+#ifdef GL_ARB_shader_storage_buffer_object
+ &__GLEW_ARB_shader_storage_buffer_object,
+#endif
+#ifdef GL_ARB_shader_subroutine
+ &__GLEW_ARB_shader_subroutine,
+#endif
+#ifdef GL_ARB_shader_texture_image_samples
+ &__GLEW_ARB_shader_texture_image_samples,
+#endif
+#ifdef GL_ARB_shader_texture_lod
+ &__GLEW_ARB_shader_texture_lod,
+#endif
+#ifdef GL_ARB_shader_viewport_layer_array
+ &__GLEW_ARB_shader_viewport_layer_array,
+#endif
+#ifdef GL_ARB_shading_language_100
+ &__GLEW_ARB_shading_language_100,
+#endif
+#ifdef GL_ARB_shading_language_420pack
+ &__GLEW_ARB_shading_language_420pack,
+#endif
+#ifdef GL_ARB_shading_language_include
+ &__GLEW_ARB_shading_language_include,
+#endif
+#ifdef GL_ARB_shading_language_packing
+ &__GLEW_ARB_shading_language_packing,
+#endif
+#ifdef GL_ARB_shadow
+ &__GLEW_ARB_shadow,
+#endif
+#ifdef GL_ARB_shadow_ambient
+ &__GLEW_ARB_shadow_ambient,
+#endif
+#ifdef GL_ARB_sparse_buffer
+ &__GLEW_ARB_sparse_buffer,
+#endif
+#ifdef GL_ARB_sparse_texture
+ &__GLEW_ARB_sparse_texture,
+#endif
+#ifdef GL_ARB_sparse_texture2
+ &__GLEW_ARB_sparse_texture2,
+#endif
+#ifdef GL_ARB_sparse_texture_clamp
+ &__GLEW_ARB_sparse_texture_clamp,
+#endif
+#ifdef GL_ARB_spirv_extensions
+ &__GLEW_ARB_spirv_extensions,
+#endif
+#ifdef GL_ARB_stencil_texturing
+ &__GLEW_ARB_stencil_texturing,
+#endif
+#ifdef GL_ARB_sync
+ &__GLEW_ARB_sync,
+#endif
+#ifdef GL_ARB_tessellation_shader
+ &__GLEW_ARB_tessellation_shader,
+#endif
+#ifdef GL_ARB_texture_barrier
+ &__GLEW_ARB_texture_barrier,
+#endif
+#ifdef GL_ARB_texture_border_clamp
+ &__GLEW_ARB_texture_border_clamp,
+#endif
+#ifdef GL_ARB_texture_buffer_object
+ &__GLEW_ARB_texture_buffer_object,
+#endif
+#ifdef GL_ARB_texture_buffer_object_rgb32
+ &__GLEW_ARB_texture_buffer_object_rgb32,
+#endif
+#ifdef GL_ARB_texture_buffer_range
+ &__GLEW_ARB_texture_buffer_range,
+#endif
+#ifdef GL_ARB_texture_compression
+ &__GLEW_ARB_texture_compression,
+#endif
+#ifdef GL_ARB_texture_compression_bptc
+ &__GLEW_ARB_texture_compression_bptc,
+#endif
+#ifdef GL_ARB_texture_compression_rgtc
+ &__GLEW_ARB_texture_compression_rgtc,
+#endif
+#ifdef GL_ARB_texture_cube_map
+ &__GLEW_ARB_texture_cube_map,
+#endif
+#ifdef GL_ARB_texture_cube_map_array
+ &__GLEW_ARB_texture_cube_map_array,
+#endif
+#ifdef GL_ARB_texture_env_add
+ &__GLEW_ARB_texture_env_add,
+#endif
+#ifdef GL_ARB_texture_env_combine
+ &__GLEW_ARB_texture_env_combine,
+#endif
+#ifdef GL_ARB_texture_env_crossbar
+ &__GLEW_ARB_texture_env_crossbar,
+#endif
+#ifdef GL_ARB_texture_env_dot3
+ &__GLEW_ARB_texture_env_dot3,
+#endif
+#ifdef GL_ARB_texture_filter_anisotropic
+ &__GLEW_ARB_texture_filter_anisotropic,
+#endif
+#ifdef GL_ARB_texture_filter_minmax
+ &__GLEW_ARB_texture_filter_minmax,
+#endif
+#ifdef GL_ARB_texture_float
+ &__GLEW_ARB_texture_float,
+#endif
+#ifdef GL_ARB_texture_gather
+ &__GLEW_ARB_texture_gather,
+#endif
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+ &__GLEW_ARB_texture_mirror_clamp_to_edge,
+#endif
+#ifdef GL_ARB_texture_mirrored_repeat
+ &__GLEW_ARB_texture_mirrored_repeat,
+#endif
+#ifdef GL_ARB_texture_multisample
+ &__GLEW_ARB_texture_multisample,
+#endif
+#ifdef GL_ARB_texture_non_power_of_two
+ &__GLEW_ARB_texture_non_power_of_two,
+#endif
+#ifdef GL_ARB_texture_query_levels
+ &__GLEW_ARB_texture_query_levels,
+#endif
+#ifdef GL_ARB_texture_query_lod
+ &__GLEW_ARB_texture_query_lod,
+#endif
+#ifdef GL_ARB_texture_rectangle
+ &__GLEW_ARB_texture_rectangle,
+#endif
+#ifdef GL_ARB_texture_rg
+ &__GLEW_ARB_texture_rg,
+#endif
+#ifdef GL_ARB_texture_rgb10_a2ui
+ &__GLEW_ARB_texture_rgb10_a2ui,
+#endif
+#ifdef GL_ARB_texture_stencil8
+ &__GLEW_ARB_texture_stencil8,
+#endif
+#ifdef GL_ARB_texture_storage
+ &__GLEW_ARB_texture_storage,
+#endif
+#ifdef GL_ARB_texture_storage_multisample
+ &__GLEW_ARB_texture_storage_multisample,
+#endif
+#ifdef GL_ARB_texture_swizzle
+ &__GLEW_ARB_texture_swizzle,
+#endif
+#ifdef GL_ARB_texture_view
+ &__GLEW_ARB_texture_view,
+#endif
+#ifdef GL_ARB_timer_query
+ &__GLEW_ARB_timer_query,
+#endif
+#ifdef GL_ARB_transform_feedback2
+ &__GLEW_ARB_transform_feedback2,
+#endif
+#ifdef GL_ARB_transform_feedback3
+ &__GLEW_ARB_transform_feedback3,
+#endif
+#ifdef GL_ARB_transform_feedback_instanced
+ &__GLEW_ARB_transform_feedback_instanced,
+#endif
+#ifdef GL_ARB_transform_feedback_overflow_query
+ &__GLEW_ARB_transform_feedback_overflow_query,
+#endif
+#ifdef GL_ARB_transpose_matrix
+ &__GLEW_ARB_transpose_matrix,
+#endif
+#ifdef GL_ARB_uniform_buffer_object
+ &__GLEW_ARB_uniform_buffer_object,
+#endif
+#ifdef GL_ARB_vertex_array_bgra
+ &__GLEW_ARB_vertex_array_bgra,
+#endif
+#ifdef GL_ARB_vertex_array_object
+ &__GLEW_ARB_vertex_array_object,
+#endif
+#ifdef GL_ARB_vertex_attrib_64bit
+ &__GLEW_ARB_vertex_attrib_64bit,
+#endif
+#ifdef GL_ARB_vertex_attrib_binding
+ &__GLEW_ARB_vertex_attrib_binding,
+#endif
+#ifdef GL_ARB_vertex_blend
+ &__GLEW_ARB_vertex_blend,
+#endif
+#ifdef GL_ARB_vertex_buffer_object
+ &__GLEW_ARB_vertex_buffer_object,
+#endif
+#ifdef GL_ARB_vertex_program
+ &__GLEW_ARB_vertex_program,
+#endif
+#ifdef GL_ARB_vertex_shader
+ &__GLEW_ARB_vertex_shader,
+#endif
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+ &__GLEW_ARB_vertex_type_10f_11f_11f_rev,
+#endif
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ &__GLEW_ARB_vertex_type_2_10_10_10_rev,
+#endif
+#ifdef GL_ARB_viewport_array
+ &__GLEW_ARB_viewport_array,
+#endif
+#ifdef GL_ARB_window_pos
+ &__GLEW_ARB_window_pos,
+#endif
+#ifdef GL_ARM_mali_program_binary
+ &__GLEW_ARM_mali_program_binary,
+#endif
+#ifdef GL_ARM_mali_shader_binary
+ &__GLEW_ARM_mali_shader_binary,
+#endif
+#ifdef GL_ARM_rgba8
+ &__GLEW_ARM_rgba8,
+#endif
+#ifdef GL_ARM_shader_framebuffer_fetch
+ &__GLEW_ARM_shader_framebuffer_fetch,
+#endif
+#ifdef GL_ARM_shader_framebuffer_fetch_depth_stencil
+ &__GLEW_ARM_shader_framebuffer_fetch_depth_stencil,
+#endif
+#ifdef GL_ATIX_point_sprites
+ &__GLEW_ATIX_point_sprites,
+#endif
+#ifdef GL_ATIX_texture_env_combine3
+ &__GLEW_ATIX_texture_env_combine3,
+#endif
+#ifdef GL_ATIX_texture_env_route
+ &__GLEW_ATIX_texture_env_route,
+#endif
+#ifdef GL_ATIX_vertex_shader_output_point_size
+ &__GLEW_ATIX_vertex_shader_output_point_size,
+#endif
+#ifdef GL_ATI_draw_buffers
+ &__GLEW_ATI_draw_buffers,
+#endif
+#ifdef GL_ATI_element_array
+ &__GLEW_ATI_element_array,
+#endif
+#ifdef GL_ATI_envmap_bumpmap
+ &__GLEW_ATI_envmap_bumpmap,
+#endif
+#ifdef GL_ATI_fragment_shader
+ &__GLEW_ATI_fragment_shader,
+#endif
+#ifdef GL_ATI_map_object_buffer
+ &__GLEW_ATI_map_object_buffer,
+#endif
+#ifdef GL_ATI_meminfo
+ &__GLEW_ATI_meminfo,
+#endif
+#ifdef GL_ATI_pn_triangles
+ &__GLEW_ATI_pn_triangles,
+#endif
+#ifdef GL_ATI_separate_stencil
+ &__GLEW_ATI_separate_stencil,
+#endif
+#ifdef GL_ATI_shader_texture_lod
+ &__GLEW_ATI_shader_texture_lod,
+#endif
+#ifdef GL_ATI_text_fragment_shader
+ &__GLEW_ATI_text_fragment_shader,
+#endif
+#ifdef GL_ATI_texture_compression_3dc
+ &__GLEW_ATI_texture_compression_3dc,
+#endif
+#ifdef GL_ATI_texture_env_combine3
+ &__GLEW_ATI_texture_env_combine3,
+#endif
+#ifdef GL_ATI_texture_float
+ &__GLEW_ATI_texture_float,
+#endif
+#ifdef GL_ATI_texture_mirror_once
+ &__GLEW_ATI_texture_mirror_once,
+#endif
+#ifdef GL_ATI_vertex_array_object
+ &__GLEW_ATI_vertex_array_object,
+#endif
+#ifdef GL_ATI_vertex_attrib_array_object
+ &__GLEW_ATI_vertex_attrib_array_object,
+#endif
+#ifdef GL_ATI_vertex_streams
+ &__GLEW_ATI_vertex_streams,
+#endif
+#ifdef GL_EGL_KHR_context_flush_control
+ &__GLEW_EGL_KHR_context_flush_control,
+#endif
+#ifdef GL_EGL_NV_robustness_video_memory_purge
+ &__GLEW_EGL_NV_robustness_video_memory_purge,
+#endif
+#ifdef GL_EXT_422_pixels
+ &__GLEW_EXT_422_pixels,
+#endif
+#ifdef GL_EXT_Cg_shader
+ &__GLEW_EXT_Cg_shader,
+#endif
+#ifdef GL_EXT_EGL_image_array
+ &__GLEW_EXT_EGL_image_array,
+#endif
+#ifdef GL_EXT_YUV_target
+ &__GLEW_EXT_YUV_target,
+#endif
+#ifdef GL_EXT_abgr
+ &__GLEW_EXT_abgr,
+#endif
+#ifdef GL_EXT_base_instance
+ &__GLEW_EXT_base_instance,
+#endif
+#ifdef GL_EXT_bgra
+ &__GLEW_EXT_bgra,
+#endif
+#ifdef GL_EXT_bindable_uniform
+ &__GLEW_EXT_bindable_uniform,
+#endif
+#ifdef GL_EXT_blend_color
+ &__GLEW_EXT_blend_color,
+#endif
+#ifdef GL_EXT_blend_equation_separate
+ &__GLEW_EXT_blend_equation_separate,
+#endif
+#ifdef GL_EXT_blend_func_extended
+ &__GLEW_EXT_blend_func_extended,
+#endif
+#ifdef GL_EXT_blend_func_separate
+ &__GLEW_EXT_blend_func_separate,
+#endif
+#ifdef GL_EXT_blend_logic_op
+ &__GLEW_EXT_blend_logic_op,
+#endif
+#ifdef GL_EXT_blend_minmax
+ &__GLEW_EXT_blend_minmax,
+#endif
+#ifdef GL_EXT_blend_subtract
+ &__GLEW_EXT_blend_subtract,
+#endif
+#ifdef GL_EXT_buffer_storage
+ &__GLEW_EXT_buffer_storage,
+#endif
+#ifdef GL_EXT_clear_texture
+ &__GLEW_EXT_clear_texture,
+#endif
+#ifdef GL_EXT_clip_cull_distance
+ &__GLEW_EXT_clip_cull_distance,
+#endif
+#ifdef GL_EXT_clip_volume_hint
+ &__GLEW_EXT_clip_volume_hint,
+#endif
+#ifdef GL_EXT_cmyka
+ &__GLEW_EXT_cmyka,
+#endif
+#ifdef GL_EXT_color_buffer_float
+ &__GLEW_EXT_color_buffer_float,
+#endif
+#ifdef GL_EXT_color_buffer_half_float
+ &__GLEW_EXT_color_buffer_half_float,
+#endif
+#ifdef GL_EXT_color_subtable
+ &__GLEW_EXT_color_subtable,
+#endif
+#ifdef GL_EXT_compiled_vertex_array
+ &__GLEW_EXT_compiled_vertex_array,
+#endif
+#ifdef GL_EXT_compressed_ETC1_RGB8_sub_texture
+ &__GLEW_EXT_compressed_ETC1_RGB8_sub_texture,
+#endif
+#ifdef GL_EXT_conservative_depth
+ &__GLEW_EXT_conservative_depth,
+#endif
+#ifdef GL_EXT_convolution
+ &__GLEW_EXT_convolution,
+#endif
+#ifdef GL_EXT_coordinate_frame
+ &__GLEW_EXT_coordinate_frame,
+#endif
+#ifdef GL_EXT_copy_image
+ &__GLEW_EXT_copy_image,
+#endif
+#ifdef GL_EXT_copy_texture
+ &__GLEW_EXT_copy_texture,
+#endif
+#ifdef GL_EXT_cull_vertex
+ &__GLEW_EXT_cull_vertex,
+#endif
+#ifdef GL_EXT_debug_label
+ &__GLEW_EXT_debug_label,
+#endif
+#ifdef GL_EXT_debug_marker
+ &__GLEW_EXT_debug_marker,
+#endif
+#ifdef GL_EXT_depth_bounds_test
+ &__GLEW_EXT_depth_bounds_test,
+#endif
+#ifdef GL_EXT_direct_state_access
+ &__GLEW_EXT_direct_state_access,
+#endif
+#ifdef GL_EXT_discard_framebuffer
+ &__GLEW_EXT_discard_framebuffer,
+#endif
+#ifdef GL_EXT_draw_buffers
+ &__GLEW_EXT_draw_buffers,
+#endif
+#ifdef GL_EXT_draw_buffers2
+ &__GLEW_EXT_draw_buffers2,
+#endif
+#ifdef GL_EXT_draw_buffers_indexed
+ &__GLEW_EXT_draw_buffers_indexed,
+#endif
+#ifdef GL_EXT_draw_elements_base_vertex
+ &__GLEW_EXT_draw_elements_base_vertex,
+#endif
+#ifdef GL_EXT_draw_instanced
+ &__GLEW_EXT_draw_instanced,
+#endif
+#ifdef GL_EXT_draw_range_elements
+ &__GLEW_EXT_draw_range_elements,
+#endif
+#ifdef GL_EXT_external_buffer
+ &__GLEW_EXT_external_buffer,
+#endif
+#ifdef GL_EXT_float_blend
+ &__GLEW_EXT_float_blend,
+#endif
+#ifdef GL_EXT_fog_coord
+ &__GLEW_EXT_fog_coord,
+#endif
+#ifdef GL_EXT_frag_depth
+ &__GLEW_EXT_frag_depth,
+#endif
+#ifdef GL_EXT_fragment_lighting
+ &__GLEW_EXT_fragment_lighting,
+#endif
+#ifdef GL_EXT_framebuffer_blit
+ &__GLEW_EXT_framebuffer_blit,
+#endif
+#ifdef GL_EXT_framebuffer_multisample
+ &__GLEW_EXT_framebuffer_multisample,
+#endif
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+ &__GLEW_EXT_framebuffer_multisample_blit_scaled,
+#endif
+#ifdef GL_EXT_framebuffer_object
+ &__GLEW_EXT_framebuffer_object,
+#endif
+#ifdef GL_EXT_framebuffer_sRGB
+ &__GLEW_EXT_framebuffer_sRGB,
+#endif
+#ifdef GL_EXT_geometry_point_size
+ &__GLEW_EXT_geometry_point_size,
+#endif
+#ifdef GL_EXT_geometry_shader
+ &__GLEW_EXT_geometry_shader,
+#endif
+#ifdef GL_EXT_geometry_shader4
+ &__GLEW_EXT_geometry_shader4,
+#endif
+#ifdef GL_EXT_gpu_program_parameters
+ &__GLEW_EXT_gpu_program_parameters,
+#endif
+#ifdef GL_EXT_gpu_shader4
+ &__GLEW_EXT_gpu_shader4,
+#endif
+#ifdef GL_EXT_gpu_shader5
+ &__GLEW_EXT_gpu_shader5,
+#endif
+#ifdef GL_EXT_histogram
+ &__GLEW_EXT_histogram,
+#endif
+#ifdef GL_EXT_index_array_formats
+ &__GLEW_EXT_index_array_formats,
+#endif
+#ifdef GL_EXT_index_func
+ &__GLEW_EXT_index_func,
+#endif
+#ifdef GL_EXT_index_material
+ &__GLEW_EXT_index_material,
+#endif
+#ifdef GL_EXT_index_texture
+ &__GLEW_EXT_index_texture,
+#endif
+#ifdef GL_EXT_instanced_arrays
+ &__GLEW_EXT_instanced_arrays,
+#endif
+#ifdef GL_EXT_light_texture
+ &__GLEW_EXT_light_texture,
+#endif
+#ifdef GL_EXT_map_buffer_range
+ &__GLEW_EXT_map_buffer_range,
+#endif
+#ifdef GL_EXT_memory_object
+ &__GLEW_EXT_memory_object,
+#endif
+#ifdef GL_EXT_memory_object_fd
+ &__GLEW_EXT_memory_object_fd,
+#endif
+#ifdef GL_EXT_memory_object_win32
+ &__GLEW_EXT_memory_object_win32,
+#endif
+#ifdef GL_EXT_misc_attribute
+ &__GLEW_EXT_misc_attribute,
+#endif
+#ifdef GL_EXT_multi_draw_arrays
+ &__GLEW_EXT_multi_draw_arrays,
+#endif
+#ifdef GL_EXT_multi_draw_indirect
+ &__GLEW_EXT_multi_draw_indirect,
+#endif
+#ifdef GL_EXT_multiple_textures
+ &__GLEW_EXT_multiple_textures,
+#endif
+#ifdef GL_EXT_multisample
+ &__GLEW_EXT_multisample,
+#endif
+#ifdef GL_EXT_multisample_compatibility
+ &__GLEW_EXT_multisample_compatibility,
+#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+ &__GLEW_EXT_multisampled_render_to_texture,
+#endif
+#ifdef GL_EXT_multisampled_render_to_texture2
+ &__GLEW_EXT_multisampled_render_to_texture2,
+#endif
+#ifdef GL_EXT_multiview_draw_buffers
+ &__GLEW_EXT_multiview_draw_buffers,
+#endif
+#ifdef GL_EXT_packed_depth_stencil
+ &__GLEW_EXT_packed_depth_stencil,
+#endif
+#ifdef GL_EXT_packed_float
+ &__GLEW_EXT_packed_float,
+#endif
+#ifdef GL_EXT_packed_pixels
+ &__GLEW_EXT_packed_pixels,
+#endif
+#ifdef GL_EXT_paletted_texture
+ &__GLEW_EXT_paletted_texture,
+#endif
+#ifdef GL_EXT_pixel_buffer_object
+ &__GLEW_EXT_pixel_buffer_object,
+#endif
+#ifdef GL_EXT_pixel_transform
+ &__GLEW_EXT_pixel_transform,
+#endif
+#ifdef GL_EXT_pixel_transform_color_table
+ &__GLEW_EXT_pixel_transform_color_table,
+#endif
+#ifdef GL_EXT_point_parameters
+ &__GLEW_EXT_point_parameters,
+#endif
+#ifdef GL_EXT_polygon_offset
+ &__GLEW_EXT_polygon_offset,
+#endif
+#ifdef GL_EXT_polygon_offset_clamp
+ &__GLEW_EXT_polygon_offset_clamp,
+#endif
+#ifdef GL_EXT_post_depth_coverage
+ &__GLEW_EXT_post_depth_coverage,
+#endif
+#ifdef GL_EXT_provoking_vertex
+ &__GLEW_EXT_provoking_vertex,
+#endif
+#ifdef GL_EXT_pvrtc_sRGB
+ &__GLEW_EXT_pvrtc_sRGB,
+#endif
+#ifdef GL_EXT_raster_multisample
+ &__GLEW_EXT_raster_multisample,
+#endif
+#ifdef GL_EXT_read_format_bgra
+ &__GLEW_EXT_read_format_bgra,
+#endif
+#ifdef GL_EXT_render_snorm
+ &__GLEW_EXT_render_snorm,
+#endif
+#ifdef GL_EXT_rescale_normal
+ &__GLEW_EXT_rescale_normal,
+#endif
+#ifdef GL_EXT_sRGB
+ &__GLEW_EXT_sRGB,
+#endif
+#ifdef GL_EXT_sRGB_write_control
+ &__GLEW_EXT_sRGB_write_control,
+#endif
+#ifdef GL_EXT_scene_marker
+ &__GLEW_EXT_scene_marker,
+#endif
+#ifdef GL_EXT_secondary_color
+ &__GLEW_EXT_secondary_color,
+#endif
+#ifdef GL_EXT_semaphore
+ &__GLEW_EXT_semaphore,
+#endif
+#ifdef GL_EXT_semaphore_fd
+ &__GLEW_EXT_semaphore_fd,
+#endif
+#ifdef GL_EXT_semaphore_win32
+ &__GLEW_EXT_semaphore_win32,
+#endif
+#ifdef GL_EXT_separate_shader_objects
+ &__GLEW_EXT_separate_shader_objects,
+#endif
+#ifdef GL_EXT_separate_specular_color
+ &__GLEW_EXT_separate_specular_color,
+#endif
+#ifdef GL_EXT_shader_framebuffer_fetch
+ &__GLEW_EXT_shader_framebuffer_fetch,
+#endif
+#ifdef GL_EXT_shader_group_vote
+ &__GLEW_EXT_shader_group_vote,
+#endif
+#ifdef GL_EXT_shader_image_load_formatted
+ &__GLEW_EXT_shader_image_load_formatted,
+#endif
+#ifdef GL_EXT_shader_image_load_store
+ &__GLEW_EXT_shader_image_load_store,
+#endif
+#ifdef GL_EXT_shader_implicit_conversions
+ &__GLEW_EXT_shader_implicit_conversions,
+#endif
+#ifdef GL_EXT_shader_integer_mix
+ &__GLEW_EXT_shader_integer_mix,
+#endif
+#ifdef GL_EXT_shader_io_blocks
+ &__GLEW_EXT_shader_io_blocks,
+#endif
+#ifdef GL_EXT_shader_non_constant_global_initializers
+ &__GLEW_EXT_shader_non_constant_global_initializers,
+#endif
+#ifdef GL_EXT_shader_pixel_local_storage
+ &__GLEW_EXT_shader_pixel_local_storage,
+#endif
+#ifdef GL_EXT_shader_pixel_local_storage2
+ &__GLEW_EXT_shader_pixel_local_storage2,
+#endif
+#ifdef GL_EXT_shader_texture_lod
+ &__GLEW_EXT_shader_texture_lod,
+#endif
+#ifdef GL_EXT_shadow_funcs
+ &__GLEW_EXT_shadow_funcs,
+#endif
+#ifdef GL_EXT_shadow_samplers
+ &__GLEW_EXT_shadow_samplers,
+#endif
+#ifdef GL_EXT_shared_texture_palette
+ &__GLEW_EXT_shared_texture_palette,
+#endif
+#ifdef GL_EXT_sparse_texture
+ &__GLEW_EXT_sparse_texture,
+#endif
+#ifdef GL_EXT_sparse_texture2
+ &__GLEW_EXT_sparse_texture2,
+#endif
+#ifdef GL_EXT_stencil_clear_tag
+ &__GLEW_EXT_stencil_clear_tag,
+#endif
+#ifdef GL_EXT_stencil_two_side
+ &__GLEW_EXT_stencil_two_side,
+#endif
+#ifdef GL_EXT_stencil_wrap
+ &__GLEW_EXT_stencil_wrap,
+#endif
+#ifdef GL_EXT_subtexture
+ &__GLEW_EXT_subtexture,
+#endif
+#ifdef GL_EXT_texture
+ &__GLEW_EXT_texture,
+#endif
+#ifdef GL_EXT_texture3D
+ &__GLEW_EXT_texture3D,
+#endif
+#ifdef GL_EXT_texture_array
+ &__GLEW_EXT_texture_array,
+#endif
+#ifdef GL_EXT_texture_buffer_object
+ &__GLEW_EXT_texture_buffer_object,
+#endif
+#ifdef GL_EXT_texture_compression_astc_decode_mode
+ &__GLEW_EXT_texture_compression_astc_decode_mode,
+#endif
+#ifdef GL_EXT_texture_compression_astc_decode_mode_rgb9e5
+ &__GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5,
+#endif
+#ifdef GL_EXT_texture_compression_bptc
+ &__GLEW_EXT_texture_compression_bptc,
+#endif
+#ifdef GL_EXT_texture_compression_dxt1
+ &__GLEW_EXT_texture_compression_dxt1,
+#endif
+#ifdef GL_EXT_texture_compression_latc
+ &__GLEW_EXT_texture_compression_latc,
+#endif
+#ifdef GL_EXT_texture_compression_rgtc
+ &__GLEW_EXT_texture_compression_rgtc,
+#endif
+#ifdef GL_EXT_texture_compression_s3tc
+ &__GLEW_EXT_texture_compression_s3tc,
+#endif
+#ifdef GL_EXT_texture_cube_map
+ &__GLEW_EXT_texture_cube_map,
+#endif
+#ifdef GL_EXT_texture_cube_map_array
+ &__GLEW_EXT_texture_cube_map_array,
+#endif
+#ifdef GL_EXT_texture_edge_clamp
+ &__GLEW_EXT_texture_edge_clamp,
+#endif
+#ifdef GL_EXT_texture_env
+ &__GLEW_EXT_texture_env,
+#endif
+#ifdef GL_EXT_texture_env_add
+ &__GLEW_EXT_texture_env_add,
+#endif
+#ifdef GL_EXT_texture_env_combine
+ &__GLEW_EXT_texture_env_combine,
+#endif
+#ifdef GL_EXT_texture_env_dot3
+ &__GLEW_EXT_texture_env_dot3,
+#endif
+#ifdef GL_EXT_texture_filter_anisotropic
+ &__GLEW_EXT_texture_filter_anisotropic,
+#endif
+#ifdef GL_EXT_texture_filter_minmax
+ &__GLEW_EXT_texture_filter_minmax,
+#endif
+#ifdef GL_EXT_texture_format_BGRA8888
+ &__GLEW_EXT_texture_format_BGRA8888,
+#endif
+#ifdef GL_EXT_texture_integer
+ &__GLEW_EXT_texture_integer,
+#endif
+#ifdef GL_EXT_texture_lod_bias
+ &__GLEW_EXT_texture_lod_bias,
+#endif
+#ifdef GL_EXT_texture_mirror_clamp
+ &__GLEW_EXT_texture_mirror_clamp,
+#endif
+#ifdef GL_EXT_texture_norm16
+ &__GLEW_EXT_texture_norm16,
+#endif
+#ifdef GL_EXT_texture_object
+ &__GLEW_EXT_texture_object,
+#endif
+#ifdef GL_EXT_texture_perturb_normal
+ &__GLEW_EXT_texture_perturb_normal,
+#endif
+#ifdef GL_EXT_texture_rectangle
+ &__GLEW_EXT_texture_rectangle,
+#endif
+#ifdef GL_EXT_texture_rg
+ &__GLEW_EXT_texture_rg,
+#endif
+#ifdef GL_EXT_texture_sRGB
+ &__GLEW_EXT_texture_sRGB,
+#endif
+#ifdef GL_EXT_texture_sRGB_R8
+ &__GLEW_EXT_texture_sRGB_R8,
+#endif
+#ifdef GL_EXT_texture_sRGB_RG8
+ &__GLEW_EXT_texture_sRGB_RG8,
+#endif
+#ifdef GL_EXT_texture_sRGB_decode
+ &__GLEW_EXT_texture_sRGB_decode,
+#endif
+#ifdef GL_EXT_texture_shared_exponent
+ &__GLEW_EXT_texture_shared_exponent,
+#endif
+#ifdef GL_EXT_texture_snorm
+ &__GLEW_EXT_texture_snorm,
+#endif
+#ifdef GL_EXT_texture_storage
+ &__GLEW_EXT_texture_storage,
+#endif
+#ifdef GL_EXT_texture_swizzle
+ &__GLEW_EXT_texture_swizzle,
+#endif
+#ifdef GL_EXT_texture_type_2_10_10_10_REV
+ &__GLEW_EXT_texture_type_2_10_10_10_REV,
+#endif
+#ifdef GL_EXT_texture_view
+ &__GLEW_EXT_texture_view,
+#endif
+#ifdef GL_EXT_timer_query
+ &__GLEW_EXT_timer_query,
+#endif
+#ifdef GL_EXT_transform_feedback
+ &__GLEW_EXT_transform_feedback,
+#endif
+#ifdef GL_EXT_unpack_subimage
+ &__GLEW_EXT_unpack_subimage,
+#endif
+#ifdef GL_EXT_vertex_array
+ &__GLEW_EXT_vertex_array,
+#endif
+#ifdef GL_EXT_vertex_array_bgra
+ &__GLEW_EXT_vertex_array_bgra,
+#endif
+#ifdef GL_EXT_vertex_array_setXXX
+ &__GLEW_EXT_vertex_array_setXXX,
+#endif
+#ifdef GL_EXT_vertex_attrib_64bit
+ &__GLEW_EXT_vertex_attrib_64bit,
+#endif
+#ifdef GL_EXT_vertex_shader
+ &__GLEW_EXT_vertex_shader,
+#endif
+#ifdef GL_EXT_vertex_weighting
+ &__GLEW_EXT_vertex_weighting,
+#endif
+#ifdef GL_EXT_win32_keyed_mutex
+ &__GLEW_EXT_win32_keyed_mutex,
+#endif
+#ifdef GL_EXT_window_rectangles
+ &__GLEW_EXT_window_rectangles,
+#endif
+#ifdef GL_EXT_x11_sync_object
+ &__GLEW_EXT_x11_sync_object,
+#endif
+#ifdef GL_GREMEDY_frame_terminator
+ &__GLEW_GREMEDY_frame_terminator,
+#endif
+#ifdef GL_GREMEDY_string_marker
+ &__GLEW_GREMEDY_string_marker,
+#endif
+#ifdef GL_HP_convolution_border_modes
+ &__GLEW_HP_convolution_border_modes,
+#endif
+#ifdef GL_HP_image_transform
+ &__GLEW_HP_image_transform,
+#endif
+#ifdef GL_HP_occlusion_test
+ &__GLEW_HP_occlusion_test,
+#endif
+#ifdef GL_HP_texture_lighting
+ &__GLEW_HP_texture_lighting,
+#endif
+#ifdef GL_IBM_cull_vertex
+ &__GLEW_IBM_cull_vertex,
+#endif
+#ifdef GL_IBM_multimode_draw_arrays
+ &__GLEW_IBM_multimode_draw_arrays,
+#endif
+#ifdef GL_IBM_rasterpos_clip
+ &__GLEW_IBM_rasterpos_clip,
+#endif
+#ifdef GL_IBM_static_data
+ &__GLEW_IBM_static_data,
+#endif
+#ifdef GL_IBM_texture_mirrored_repeat
+ &__GLEW_IBM_texture_mirrored_repeat,
+#endif
+#ifdef GL_IBM_vertex_array_lists
+ &__GLEW_IBM_vertex_array_lists,
+#endif
+#ifdef GL_INGR_color_clamp
+ &__GLEW_INGR_color_clamp,
+#endif
+#ifdef GL_INGR_interlace_read
+ &__GLEW_INGR_interlace_read,
+#endif
+#ifdef GL_INTEL_conservative_rasterization
+ &__GLEW_INTEL_conservative_rasterization,
+#endif
+#ifdef GL_INTEL_fragment_shader_ordering
+ &__GLEW_INTEL_fragment_shader_ordering,
+#endif
+#ifdef GL_INTEL_framebuffer_CMAA
+ &__GLEW_INTEL_framebuffer_CMAA,
+#endif
+#ifdef GL_INTEL_map_texture
+ &__GLEW_INTEL_map_texture,
+#endif
+#ifdef GL_INTEL_parallel_arrays
+ &__GLEW_INTEL_parallel_arrays,
+#endif
+#ifdef GL_INTEL_performance_query
+ &__GLEW_INTEL_performance_query,
+#endif
+#ifdef GL_INTEL_texture_scissor
+ &__GLEW_INTEL_texture_scissor,
+#endif
+#ifdef GL_KHR_blend_equation_advanced
+ &__GLEW_KHR_blend_equation_advanced,
+#endif
+#ifdef GL_KHR_blend_equation_advanced_coherent
+ &__GLEW_KHR_blend_equation_advanced_coherent,
+#endif
+#ifdef GL_KHR_context_flush_control
+ &__GLEW_KHR_context_flush_control,
+#endif
+#ifdef GL_KHR_debug
+ &__GLEW_KHR_debug,
+#endif
+#ifdef GL_KHR_no_error
+ &__GLEW_KHR_no_error,
+#endif
+#ifdef GL_KHR_parallel_shader_compile
+ &__GLEW_KHR_parallel_shader_compile,
+#endif
+#ifdef GL_KHR_robust_buffer_access_behavior
+ &__GLEW_KHR_robust_buffer_access_behavior,
+#endif
+#ifdef GL_KHR_robustness
+ &__GLEW_KHR_robustness,
+#endif
+#ifdef GL_KHR_texture_compression_astc_hdr
+ &__GLEW_KHR_texture_compression_astc_hdr,
+#endif
+#ifdef GL_KHR_texture_compression_astc_ldr
+ &__GLEW_KHR_texture_compression_astc_ldr,
+#endif
+#ifdef GL_KHR_texture_compression_astc_sliced_3d
+ &__GLEW_KHR_texture_compression_astc_sliced_3d,
+#endif
+#ifdef GL_KTX_buffer_region
+ &__GLEW_KTX_buffer_region,
+#endif
+#ifdef GL_MESAX_texture_stack
+ &__GLEW_MESAX_texture_stack,
+#endif
+#ifdef GL_MESA_pack_invert
+ &__GLEW_MESA_pack_invert,
+#endif
+#ifdef GL_MESA_resize_buffers
+ &__GLEW_MESA_resize_buffers,
+#endif
+#ifdef GL_MESA_shader_integer_functions
+ &__GLEW_MESA_shader_integer_functions,
+#endif
+#ifdef GL_MESA_window_pos
+ &__GLEW_MESA_window_pos,
+#endif
+#ifdef GL_MESA_ycbcr_texture
+ &__GLEW_MESA_ycbcr_texture,
+#endif
+#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers
+ &__GLEW_NVX_blend_equation_advanced_multi_draw_buffers,
+#endif
+#ifdef GL_NVX_conditional_render
+ &__GLEW_NVX_conditional_render,
+#endif
+#ifdef GL_NVX_gpu_memory_info
+ &__GLEW_NVX_gpu_memory_info,
+#endif
+#ifdef GL_NVX_linked_gpu_multicast
+ &__GLEW_NVX_linked_gpu_multicast,
+#endif
+#ifdef GL_NV_3dvision_settings
+ &__GLEW_NV_3dvision_settings,
+#endif
+#ifdef GL_NV_EGL_stream_consumer_external
+ &__GLEW_NV_EGL_stream_consumer_external,
+#endif
+#ifdef GL_NV_alpha_to_coverage_dither_control
+ &__GLEW_NV_alpha_to_coverage_dither_control,
+#endif
+#ifdef GL_NV_bgr
+ &__GLEW_NV_bgr,
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect
+ &__GLEW_NV_bindless_multi_draw_indirect,
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect_count
+ &__GLEW_NV_bindless_multi_draw_indirect_count,
+#endif
+#ifdef GL_NV_bindless_texture
+ &__GLEW_NV_bindless_texture,
+#endif
+#ifdef GL_NV_blend_equation_advanced
+ &__GLEW_NV_blend_equation_advanced,
+#endif
+#ifdef GL_NV_blend_equation_advanced_coherent
+ &__GLEW_NV_blend_equation_advanced_coherent,
+#endif
+#ifdef GL_NV_blend_minmax_factor
+ &__GLEW_NV_blend_minmax_factor,
+#endif
+#ifdef GL_NV_blend_square
+ &__GLEW_NV_blend_square,
+#endif
+#ifdef GL_NV_clip_space_w_scaling
+ &__GLEW_NV_clip_space_w_scaling,
+#endif
+#ifdef GL_NV_command_list
+ &__GLEW_NV_command_list,
+#endif
+#ifdef GL_NV_compute_program5
+ &__GLEW_NV_compute_program5,
+#endif
+#ifdef GL_NV_conditional_render
+ &__GLEW_NV_conditional_render,
+#endif
+#ifdef GL_NV_conservative_raster
+ &__GLEW_NV_conservative_raster,
+#endif
+#ifdef GL_NV_conservative_raster_dilate
+ &__GLEW_NV_conservative_raster_dilate,
+#endif
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ &__GLEW_NV_conservative_raster_pre_snap_triangles,
+#endif
+#ifdef GL_NV_copy_buffer
+ &__GLEW_NV_copy_buffer,
+#endif
+#ifdef GL_NV_copy_depth_to_color
+ &__GLEW_NV_copy_depth_to_color,
+#endif
+#ifdef GL_NV_copy_image
+ &__GLEW_NV_copy_image,
+#endif
+#ifdef GL_NV_deep_texture3D
+ &__GLEW_NV_deep_texture3D,
+#endif
+#ifdef GL_NV_depth_buffer_float
+ &__GLEW_NV_depth_buffer_float,
+#endif
+#ifdef GL_NV_depth_clamp
+ &__GLEW_NV_depth_clamp,
+#endif
+#ifdef GL_NV_depth_range_unclamped
+ &__GLEW_NV_depth_range_unclamped,
+#endif
+#ifdef GL_NV_draw_buffers
+ &__GLEW_NV_draw_buffers,
+#endif
+#ifdef GL_NV_draw_instanced
+ &__GLEW_NV_draw_instanced,
+#endif
+#ifdef GL_NV_draw_texture
+ &__GLEW_NV_draw_texture,
+#endif
+#ifdef GL_NV_draw_vulkan_image
+ &__GLEW_NV_draw_vulkan_image,
+#endif
+#ifdef GL_NV_evaluators
+ &__GLEW_NV_evaluators,
+#endif
+#ifdef GL_NV_explicit_attrib_location
+ &__GLEW_NV_explicit_attrib_location,
+#endif
+#ifdef GL_NV_explicit_multisample
+ &__GLEW_NV_explicit_multisample,
+#endif
+#ifdef GL_NV_fbo_color_attachments
+ &__GLEW_NV_fbo_color_attachments,
+#endif
+#ifdef GL_NV_fence
+ &__GLEW_NV_fence,
+#endif
+#ifdef GL_NV_fill_rectangle
+ &__GLEW_NV_fill_rectangle,
+#endif
+#ifdef GL_NV_float_buffer
+ &__GLEW_NV_float_buffer,
+#endif
+#ifdef GL_NV_fog_distance
+ &__GLEW_NV_fog_distance,
+#endif
+#ifdef GL_NV_fragment_coverage_to_color
+ &__GLEW_NV_fragment_coverage_to_color,
+#endif
+#ifdef GL_NV_fragment_program
+ &__GLEW_NV_fragment_program,
+#endif
+#ifdef GL_NV_fragment_program2
+ &__GLEW_NV_fragment_program2,
+#endif
+#ifdef GL_NV_fragment_program4
+ &__GLEW_NV_fragment_program4,
+#endif
+#ifdef GL_NV_fragment_program_option
+ &__GLEW_NV_fragment_program_option,
+#endif
+#ifdef GL_NV_fragment_shader_interlock
+ &__GLEW_NV_fragment_shader_interlock,
+#endif
+#ifdef GL_NV_framebuffer_blit
+ &__GLEW_NV_framebuffer_blit,
+#endif
+#ifdef GL_NV_framebuffer_mixed_samples
+ &__GLEW_NV_framebuffer_mixed_samples,
+#endif
+#ifdef GL_NV_framebuffer_multisample
+ &__GLEW_NV_framebuffer_multisample,
+#endif
+#ifdef GL_NV_framebuffer_multisample_coverage
+ &__GLEW_NV_framebuffer_multisample_coverage,
+#endif
+#ifdef GL_NV_generate_mipmap_sRGB
+ &__GLEW_NV_generate_mipmap_sRGB,
+#endif
+#ifdef GL_NV_geometry_program4
+ &__GLEW_NV_geometry_program4,
+#endif
+#ifdef GL_NV_geometry_shader4
+ &__GLEW_NV_geometry_shader4,
+#endif
+#ifdef GL_NV_geometry_shader_passthrough
+ &__GLEW_NV_geometry_shader_passthrough,
+#endif
+#ifdef GL_NV_gpu_multicast
+ &__GLEW_NV_gpu_multicast,
+#endif
+#ifdef GL_NV_gpu_program4
+ &__GLEW_NV_gpu_program4,
+#endif
+#ifdef GL_NV_gpu_program5
+ &__GLEW_NV_gpu_program5,
+#endif
+#ifdef GL_NV_gpu_program5_mem_extended
+ &__GLEW_NV_gpu_program5_mem_extended,
+#endif
+#ifdef GL_NV_gpu_program_fp64
+ &__GLEW_NV_gpu_program_fp64,
+#endif
+#ifdef GL_NV_gpu_shader5
+ &__GLEW_NV_gpu_shader5,
+#endif
+#ifdef GL_NV_half_float
+ &__GLEW_NV_half_float,
+#endif
+#ifdef GL_NV_image_formats
+ &__GLEW_NV_image_formats,
+#endif
+#ifdef GL_NV_instanced_arrays
+ &__GLEW_NV_instanced_arrays,
+#endif
+#ifdef GL_NV_internalformat_sample_query
+ &__GLEW_NV_internalformat_sample_query,
+#endif
+#ifdef GL_NV_light_max_exponent
+ &__GLEW_NV_light_max_exponent,
+#endif
+#ifdef GL_NV_multisample_coverage
+ &__GLEW_NV_multisample_coverage,
+#endif
+#ifdef GL_NV_multisample_filter_hint
+ &__GLEW_NV_multisample_filter_hint,
+#endif
+#ifdef GL_NV_non_square_matrices
+ &__GLEW_NV_non_square_matrices,
+#endif
+#ifdef GL_NV_occlusion_query
+ &__GLEW_NV_occlusion_query,
+#endif
+#ifdef GL_NV_pack_subimage
+ &__GLEW_NV_pack_subimage,
+#endif
+#ifdef GL_NV_packed_depth_stencil
+ &__GLEW_NV_packed_depth_stencil,
+#endif
+#ifdef GL_NV_packed_float
+ &__GLEW_NV_packed_float,
+#endif
+#ifdef GL_NV_packed_float_linear
+ &__GLEW_NV_packed_float_linear,
+#endif
+#ifdef GL_NV_parameter_buffer_object
+ &__GLEW_NV_parameter_buffer_object,
+#endif
+#ifdef GL_NV_parameter_buffer_object2
+ &__GLEW_NV_parameter_buffer_object2,
+#endif
+#ifdef GL_NV_path_rendering
+ &__GLEW_NV_path_rendering,
+#endif
+#ifdef GL_NV_path_rendering_shared_edge
+ &__GLEW_NV_path_rendering_shared_edge,
+#endif
+#ifdef GL_NV_pixel_buffer_object
+ &__GLEW_NV_pixel_buffer_object,
+#endif
+#ifdef GL_NV_pixel_data_range
+ &__GLEW_NV_pixel_data_range,
+#endif
+#ifdef GL_NV_platform_binary
+ &__GLEW_NV_platform_binary,
+#endif
+#ifdef GL_NV_point_sprite
+ &__GLEW_NV_point_sprite,
+#endif
+#ifdef GL_NV_polygon_mode
+ &__GLEW_NV_polygon_mode,
+#endif
+#ifdef GL_NV_present_video
+ &__GLEW_NV_present_video,
+#endif
+#ifdef GL_NV_primitive_restart
+ &__GLEW_NV_primitive_restart,
+#endif
+#ifdef GL_NV_read_depth
+ &__GLEW_NV_read_depth,
+#endif
+#ifdef GL_NV_read_depth_stencil
+ &__GLEW_NV_read_depth_stencil,
+#endif
+#ifdef GL_NV_read_stencil
+ &__GLEW_NV_read_stencil,
+#endif
+#ifdef GL_NV_register_combiners
+ &__GLEW_NV_register_combiners,
+#endif
+#ifdef GL_NV_register_combiners2
+ &__GLEW_NV_register_combiners2,
+#endif
+#ifdef GL_NV_robustness_video_memory_purge
+ &__GLEW_NV_robustness_video_memory_purge,
+#endif
+#ifdef GL_NV_sRGB_formats
+ &__GLEW_NV_sRGB_formats,
+#endif
+#ifdef GL_NV_sample_locations
+ &__GLEW_NV_sample_locations,
+#endif
+#ifdef GL_NV_sample_mask_override_coverage
+ &__GLEW_NV_sample_mask_override_coverage,
+#endif
+#ifdef GL_NV_shader_atomic_counters
+ &__GLEW_NV_shader_atomic_counters,
+#endif
+#ifdef GL_NV_shader_atomic_float
+ &__GLEW_NV_shader_atomic_float,
+#endif
+#ifdef GL_NV_shader_atomic_float64
+ &__GLEW_NV_shader_atomic_float64,
+#endif
+#ifdef GL_NV_shader_atomic_fp16_vector
+ &__GLEW_NV_shader_atomic_fp16_vector,
+#endif
+#ifdef GL_NV_shader_atomic_int64
+ &__GLEW_NV_shader_atomic_int64,
+#endif
+#ifdef GL_NV_shader_buffer_load
+ &__GLEW_NV_shader_buffer_load,
+#endif
+#ifdef GL_NV_shader_noperspective_interpolation
+ &__GLEW_NV_shader_noperspective_interpolation,
+#endif
+#ifdef GL_NV_shader_storage_buffer_object
+ &__GLEW_NV_shader_storage_buffer_object,
+#endif
+#ifdef GL_NV_shader_thread_group
+ &__GLEW_NV_shader_thread_group,
+#endif
+#ifdef GL_NV_shader_thread_shuffle
+ &__GLEW_NV_shader_thread_shuffle,
+#endif
+#ifdef GL_NV_shadow_samplers_array
+ &__GLEW_NV_shadow_samplers_array,
+#endif
+#ifdef GL_NV_shadow_samplers_cube
+ &__GLEW_NV_shadow_samplers_cube,
+#endif
+#ifdef GL_NV_stereo_view_rendering
+ &__GLEW_NV_stereo_view_rendering,
+#endif
+#ifdef GL_NV_tessellation_program5
+ &__GLEW_NV_tessellation_program5,
+#endif
+#ifdef GL_NV_texgen_emboss
+ &__GLEW_NV_texgen_emboss,
+#endif
+#ifdef GL_NV_texgen_reflection
+ &__GLEW_NV_texgen_reflection,
+#endif
+#ifdef GL_NV_texture_array
+ &__GLEW_NV_texture_array,
+#endif
+#ifdef GL_NV_texture_barrier
+ &__GLEW_NV_texture_barrier,
+#endif
+#ifdef GL_NV_texture_border_clamp
+ &__GLEW_NV_texture_border_clamp,
+#endif
+#ifdef GL_NV_texture_compression_latc
+ &__GLEW_NV_texture_compression_latc,
+#endif
+#ifdef GL_NV_texture_compression_s3tc
+ &__GLEW_NV_texture_compression_s3tc,
+#endif
+#ifdef GL_NV_texture_compression_s3tc_update
+ &__GLEW_NV_texture_compression_s3tc_update,
+#endif
+#ifdef GL_NV_texture_compression_vtc
+ &__GLEW_NV_texture_compression_vtc,
+#endif
+#ifdef GL_NV_texture_env_combine4
+ &__GLEW_NV_texture_env_combine4,
+#endif
+#ifdef GL_NV_texture_expand_normal
+ &__GLEW_NV_texture_expand_normal,
+#endif
+#ifdef GL_NV_texture_multisample
+ &__GLEW_NV_texture_multisample,
+#endif
+#ifdef GL_NV_texture_npot_2D_mipmap
+ &__GLEW_NV_texture_npot_2D_mipmap,
+#endif
+#ifdef GL_NV_texture_rectangle
+ &__GLEW_NV_texture_rectangle,
+#endif
+#ifdef GL_NV_texture_rectangle_compressed
+ &__GLEW_NV_texture_rectangle_compressed,
+#endif
+#ifdef GL_NV_texture_shader
+ &__GLEW_NV_texture_shader,
+#endif
+#ifdef GL_NV_texture_shader2
+ &__GLEW_NV_texture_shader2,
+#endif
+#ifdef GL_NV_texture_shader3
+ &__GLEW_NV_texture_shader3,
+#endif
+#ifdef GL_NV_transform_feedback
+ &__GLEW_NV_transform_feedback,
+#endif
+#ifdef GL_NV_transform_feedback2
+ &__GLEW_NV_transform_feedback2,
+#endif
+#ifdef GL_NV_uniform_buffer_unified_memory
+ &__GLEW_NV_uniform_buffer_unified_memory,
+#endif
+#ifdef GL_NV_vdpau_interop
+ &__GLEW_NV_vdpau_interop,
+#endif
+#ifdef GL_NV_vertex_array_range
+ &__GLEW_NV_vertex_array_range,
+#endif
+#ifdef GL_NV_vertex_array_range2
+ &__GLEW_NV_vertex_array_range2,
+#endif
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ &__GLEW_NV_vertex_attrib_integer_64bit,
+#endif
+#ifdef GL_NV_vertex_buffer_unified_memory
+ &__GLEW_NV_vertex_buffer_unified_memory,
+#endif
+#ifdef GL_NV_vertex_program
+ &__GLEW_NV_vertex_program,
+#endif
+#ifdef GL_NV_vertex_program1_1
+ &__GLEW_NV_vertex_program1_1,
+#endif
+#ifdef GL_NV_vertex_program2
+ &__GLEW_NV_vertex_program2,
+#endif
+#ifdef GL_NV_vertex_program2_option
+ &__GLEW_NV_vertex_program2_option,
+#endif
+#ifdef GL_NV_vertex_program3
+ &__GLEW_NV_vertex_program3,
+#endif
+#ifdef GL_NV_vertex_program4
+ &__GLEW_NV_vertex_program4,
+#endif
+#ifdef GL_NV_video_capture
+ &__GLEW_NV_video_capture,
+#endif
+#ifdef GL_NV_viewport_array
+ &__GLEW_NV_viewport_array,
+#endif
+#ifdef GL_NV_viewport_array2
+ &__GLEW_NV_viewport_array2,
+#endif
+#ifdef GL_NV_viewport_swizzle
+ &__GLEW_NV_viewport_swizzle,
+#endif
+#ifdef GL_OES_byte_coordinates
+ &__GLEW_OES_byte_coordinates,
+#endif
+#ifdef GL_OML_interlace
+ &__GLEW_OML_interlace,
+#endif
+#ifdef GL_OML_resample
+ &__GLEW_OML_resample,
+#endif
+#ifdef GL_OML_subsample
+ &__GLEW_OML_subsample,
+#endif
+#ifdef GL_OVR_multiview
+ &__GLEW_OVR_multiview,
+#endif
+#ifdef GL_OVR_multiview2
+ &__GLEW_OVR_multiview2,
+#endif
+#ifdef GL_OVR_multiview_multisampled_render_to_texture
+ &__GLEW_OVR_multiview_multisampled_render_to_texture,
+#endif
+#ifdef GL_PGI_misc_hints
+ &__GLEW_PGI_misc_hints,
+#endif
+#ifdef GL_PGI_vertex_hints
+ &__GLEW_PGI_vertex_hints,
+#endif
+#ifdef GL_QCOM_alpha_test
+ &__GLEW_QCOM_alpha_test,
+#endif
+#ifdef GL_QCOM_binning_control
+ &__GLEW_QCOM_binning_control,
+#endif
+#ifdef GL_QCOM_driver_control
+ &__GLEW_QCOM_driver_control,
+#endif
+#ifdef GL_QCOM_extended_get
+ &__GLEW_QCOM_extended_get,
+#endif
+#ifdef GL_QCOM_extended_get2
+ &__GLEW_QCOM_extended_get2,
+#endif
+#ifdef GL_QCOM_framebuffer_foveated
+ &__GLEW_QCOM_framebuffer_foveated,
+#endif
+#ifdef GL_QCOM_perfmon_global_mode
+ &__GLEW_QCOM_perfmon_global_mode,
+#endif
+#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent
+ &__GLEW_QCOM_shader_framebuffer_fetch_noncoherent,
+#endif
+#ifdef GL_QCOM_tiled_rendering
+ &__GLEW_QCOM_tiled_rendering,
+#endif
+#ifdef GL_QCOM_writeonly_rendering
+ &__GLEW_QCOM_writeonly_rendering,
+#endif
+#ifdef GL_REGAL_ES1_0_compatibility
+ &__GLEW_REGAL_ES1_0_compatibility,
+#endif
+#ifdef GL_REGAL_ES1_1_compatibility
+ &__GLEW_REGAL_ES1_1_compatibility,
+#endif
+#ifdef GL_REGAL_enable
+ &__GLEW_REGAL_enable,
+#endif
+#ifdef GL_REGAL_error_string
+ &__GLEW_REGAL_error_string,
+#endif
+#ifdef GL_REGAL_extension_query
+ &__GLEW_REGAL_extension_query,
+#endif
+#ifdef GL_REGAL_log
+ &__GLEW_REGAL_log,
+#endif
+#ifdef GL_REGAL_proc_address
+ &__GLEW_REGAL_proc_address,
+#endif
+#ifdef GL_REND_screen_coordinates
+ &__GLEW_REND_screen_coordinates,
+#endif
+#ifdef GL_S3_s3tc
+ &__GLEW_S3_s3tc,
+#endif
+#ifdef GL_SGIS_clip_band_hint
+ &__GLEW_SGIS_clip_band_hint,
+#endif
+#ifdef GL_SGIS_color_range
+ &__GLEW_SGIS_color_range,
+#endif
+#ifdef GL_SGIS_detail_texture
+ &__GLEW_SGIS_detail_texture,
+#endif
+#ifdef GL_SGIS_fog_function
+ &__GLEW_SGIS_fog_function,
+#endif
+#ifdef GL_SGIS_generate_mipmap
+ &__GLEW_SGIS_generate_mipmap,
+#endif
+#ifdef GL_SGIS_line_texgen
+ &__GLEW_SGIS_line_texgen,
+#endif
+#ifdef GL_SGIS_multisample
+ &__GLEW_SGIS_multisample,
+#endif
+#ifdef GL_SGIS_multitexture
+ &__GLEW_SGIS_multitexture,
+#endif
+#ifdef GL_SGIS_pixel_texture
+ &__GLEW_SGIS_pixel_texture,
+#endif
+#ifdef GL_SGIS_point_line_texgen
+ &__GLEW_SGIS_point_line_texgen,
+#endif
+#ifdef GL_SGIS_shared_multisample
+ &__GLEW_SGIS_shared_multisample,
+#endif
+#ifdef GL_SGIS_sharpen_texture
+ &__GLEW_SGIS_sharpen_texture,
+#endif
+#ifdef GL_SGIS_texture4D
+ &__GLEW_SGIS_texture4D,
+#endif
+#ifdef GL_SGIS_texture_border_clamp
+ &__GLEW_SGIS_texture_border_clamp,
+#endif
+#ifdef GL_SGIS_texture_edge_clamp
+ &__GLEW_SGIS_texture_edge_clamp,
+#endif
+#ifdef GL_SGIS_texture_filter4
+ &__GLEW_SGIS_texture_filter4,
+#endif
+#ifdef GL_SGIS_texture_lod
+ &__GLEW_SGIS_texture_lod,
+#endif
+#ifdef GL_SGIS_texture_select
+ &__GLEW_SGIS_texture_select,
+#endif
+#ifdef GL_SGIX_async
+ &__GLEW_SGIX_async,
+#endif
+#ifdef GL_SGIX_async_histogram
+ &__GLEW_SGIX_async_histogram,
+#endif
+#ifdef GL_SGIX_async_pixel
+ &__GLEW_SGIX_async_pixel,
+#endif
+#ifdef GL_SGIX_bali_g_instruments
+ &__GLEW_SGIX_bali_g_instruments,
+#endif
+#ifdef GL_SGIX_bali_r_instruments
+ &__GLEW_SGIX_bali_r_instruments,
+#endif
+#ifdef GL_SGIX_bali_timer_instruments
+ &__GLEW_SGIX_bali_timer_instruments,
+#endif
+#ifdef GL_SGIX_blend_alpha_minmax
+ &__GLEW_SGIX_blend_alpha_minmax,
+#endif
+#ifdef GL_SGIX_blend_cadd
+ &__GLEW_SGIX_blend_cadd,
+#endif
+#ifdef GL_SGIX_blend_cmultiply
+ &__GLEW_SGIX_blend_cmultiply,
+#endif
+#ifdef GL_SGIX_calligraphic_fragment
+ &__GLEW_SGIX_calligraphic_fragment,
+#endif
+#ifdef GL_SGIX_clipmap
+ &__GLEW_SGIX_clipmap,
+#endif
+#ifdef GL_SGIX_color_matrix_accuracy
+ &__GLEW_SGIX_color_matrix_accuracy,
+#endif
+#ifdef GL_SGIX_color_table_index_mode
+ &__GLEW_SGIX_color_table_index_mode,
+#endif
+#ifdef GL_SGIX_complex_polar
+ &__GLEW_SGIX_complex_polar,
+#endif
+#ifdef GL_SGIX_convolution_accuracy
+ &__GLEW_SGIX_convolution_accuracy,
+#endif
+#ifdef GL_SGIX_cube_map
+ &__GLEW_SGIX_cube_map,
+#endif
+#ifdef GL_SGIX_cylinder_texgen
+ &__GLEW_SGIX_cylinder_texgen,
+#endif
+#ifdef GL_SGIX_datapipe
+ &__GLEW_SGIX_datapipe,
+#endif
+#ifdef GL_SGIX_decimation
+ &__GLEW_SGIX_decimation,
+#endif
+#ifdef GL_SGIX_depth_pass_instrument
+ &__GLEW_SGIX_depth_pass_instrument,
+#endif
+#ifdef GL_SGIX_depth_texture
+ &__GLEW_SGIX_depth_texture,
+#endif
+#ifdef GL_SGIX_dvc
+ &__GLEW_SGIX_dvc,
+#endif
+#ifdef GL_SGIX_flush_raster
+ &__GLEW_SGIX_flush_raster,
+#endif
+#ifdef GL_SGIX_fog_blend
+ &__GLEW_SGIX_fog_blend,
+#endif
+#ifdef GL_SGIX_fog_factor_to_alpha
+ &__GLEW_SGIX_fog_factor_to_alpha,
+#endif
+#ifdef GL_SGIX_fog_layers
+ &__GLEW_SGIX_fog_layers,
+#endif
+#ifdef GL_SGIX_fog_offset
+ &__GLEW_SGIX_fog_offset,
+#endif
+#ifdef GL_SGIX_fog_patchy
+ &__GLEW_SGIX_fog_patchy,
+#endif
+#ifdef GL_SGIX_fog_scale
+ &__GLEW_SGIX_fog_scale,
+#endif
+#ifdef GL_SGIX_fog_texture
+ &__GLEW_SGIX_fog_texture,
+#endif
+#ifdef GL_SGIX_fragment_lighting_space
+ &__GLEW_SGIX_fragment_lighting_space,
+#endif
+#ifdef GL_SGIX_fragment_specular_lighting
+ &__GLEW_SGIX_fragment_specular_lighting,
+#endif
+#ifdef GL_SGIX_fragments_instrument
+ &__GLEW_SGIX_fragments_instrument,
+#endif
+#ifdef GL_SGIX_framezoom
+ &__GLEW_SGIX_framezoom,
+#endif
+#ifdef GL_SGIX_icc_texture
+ &__GLEW_SGIX_icc_texture,
+#endif
+#ifdef GL_SGIX_igloo_interface
+ &__GLEW_SGIX_igloo_interface,
+#endif
+#ifdef GL_SGIX_image_compression
+ &__GLEW_SGIX_image_compression,
+#endif
+#ifdef GL_SGIX_impact_pixel_texture
+ &__GLEW_SGIX_impact_pixel_texture,
+#endif
+#ifdef GL_SGIX_instrument_error
+ &__GLEW_SGIX_instrument_error,
+#endif
+#ifdef GL_SGIX_interlace
+ &__GLEW_SGIX_interlace,
+#endif
+#ifdef GL_SGIX_ir_instrument1
+ &__GLEW_SGIX_ir_instrument1,
+#endif
+#ifdef GL_SGIX_line_quality_hint
+ &__GLEW_SGIX_line_quality_hint,
+#endif
+#ifdef GL_SGIX_list_priority
+ &__GLEW_SGIX_list_priority,
+#endif
+#ifdef GL_SGIX_mpeg1
+ &__GLEW_SGIX_mpeg1,
+#endif
+#ifdef GL_SGIX_mpeg2
+ &__GLEW_SGIX_mpeg2,
+#endif
+#ifdef GL_SGIX_nonlinear_lighting_pervertex
+ &__GLEW_SGIX_nonlinear_lighting_pervertex,
+#endif
+#ifdef GL_SGIX_nurbs_eval
+ &__GLEW_SGIX_nurbs_eval,
+#endif
+#ifdef GL_SGIX_occlusion_instrument
+ &__GLEW_SGIX_occlusion_instrument,
+#endif
+#ifdef GL_SGIX_packed_6bytes
+ &__GLEW_SGIX_packed_6bytes,
+#endif
+#ifdef GL_SGIX_pixel_texture
+ &__GLEW_SGIX_pixel_texture,
+#endif
+#ifdef GL_SGIX_pixel_texture_bits
+ &__GLEW_SGIX_pixel_texture_bits,
+#endif
+#ifdef GL_SGIX_pixel_texture_lod
+ &__GLEW_SGIX_pixel_texture_lod,
+#endif
+#ifdef GL_SGIX_pixel_tiles
+ &__GLEW_SGIX_pixel_tiles,
+#endif
+#ifdef GL_SGIX_polynomial_ffd
+ &__GLEW_SGIX_polynomial_ffd,
+#endif
+#ifdef GL_SGIX_quad_mesh
+ &__GLEW_SGIX_quad_mesh,
+#endif
+#ifdef GL_SGIX_reference_plane
+ &__GLEW_SGIX_reference_plane,
+#endif
+#ifdef GL_SGIX_resample
+ &__GLEW_SGIX_resample,
+#endif
+#ifdef GL_SGIX_scalebias_hint
+ &__GLEW_SGIX_scalebias_hint,
+#endif
+#ifdef GL_SGIX_shadow
+ &__GLEW_SGIX_shadow,
+#endif
+#ifdef GL_SGIX_shadow_ambient
+ &__GLEW_SGIX_shadow_ambient,
+#endif
+#ifdef GL_SGIX_slim
+ &__GLEW_SGIX_slim,
+#endif
+#ifdef GL_SGIX_spotlight_cutoff
+ &__GLEW_SGIX_spotlight_cutoff,
+#endif
+#ifdef GL_SGIX_sprite
+ &__GLEW_SGIX_sprite,
+#endif
+#ifdef GL_SGIX_subdiv_patch
+ &__GLEW_SGIX_subdiv_patch,
+#endif
+#ifdef GL_SGIX_subsample
+ &__GLEW_SGIX_subsample,
+#endif
+#ifdef GL_SGIX_tag_sample_buffer
+ &__GLEW_SGIX_tag_sample_buffer,
+#endif
+#ifdef GL_SGIX_texture_add_env
+ &__GLEW_SGIX_texture_add_env,
+#endif
+#ifdef GL_SGIX_texture_coordinate_clamp
+ &__GLEW_SGIX_texture_coordinate_clamp,
+#endif
+#ifdef GL_SGIX_texture_lod_bias
+ &__GLEW_SGIX_texture_lod_bias,
+#endif
+#ifdef GL_SGIX_texture_mipmap_anisotropic
+ &__GLEW_SGIX_texture_mipmap_anisotropic,
+#endif
+#ifdef GL_SGIX_texture_multi_buffer
+ &__GLEW_SGIX_texture_multi_buffer,
+#endif
+#ifdef GL_SGIX_texture_phase
+ &__GLEW_SGIX_texture_phase,
+#endif
+#ifdef GL_SGIX_texture_range
+ &__GLEW_SGIX_texture_range,
+#endif
+#ifdef GL_SGIX_texture_scale_bias
+ &__GLEW_SGIX_texture_scale_bias,
+#endif
+#ifdef GL_SGIX_texture_supersample
+ &__GLEW_SGIX_texture_supersample,
+#endif
+#ifdef GL_SGIX_vector_ops
+ &__GLEW_SGIX_vector_ops,
+#endif
+#ifdef GL_SGIX_vertex_array_object
+ &__GLEW_SGIX_vertex_array_object,
+#endif
+#ifdef GL_SGIX_vertex_preclip
+ &__GLEW_SGIX_vertex_preclip,
+#endif
+#ifdef GL_SGIX_vertex_preclip_hint
+ &__GLEW_SGIX_vertex_preclip_hint,
+#endif
+#ifdef GL_SGIX_ycrcb
+ &__GLEW_SGIX_ycrcb,
+#endif
+#ifdef GL_SGIX_ycrcb_subsample
+ &__GLEW_SGIX_ycrcb_subsample,
+#endif
+#ifdef GL_SGIX_ycrcba
+ &__GLEW_SGIX_ycrcba,
+#endif
+#ifdef GL_SGI_color_matrix
+ &__GLEW_SGI_color_matrix,
+#endif
+#ifdef GL_SGI_color_table
+ &__GLEW_SGI_color_table,
+#endif
+#ifdef GL_SGI_complex
+ &__GLEW_SGI_complex,
+#endif
+#ifdef GL_SGI_complex_type
+ &__GLEW_SGI_complex_type,
+#endif
+#ifdef GL_SGI_fft
+ &__GLEW_SGI_fft,
+#endif
+#ifdef GL_SGI_texture_color_table
+ &__GLEW_SGI_texture_color_table,
+#endif
+#ifdef GL_SUNX_constant_data
+ &__GLEW_SUNX_constant_data,
+#endif
+#ifdef GL_SUN_convolution_border_modes
+ &__GLEW_SUN_convolution_border_modes,
+#endif
+#ifdef GL_SUN_global_alpha
+ &__GLEW_SUN_global_alpha,
+#endif
+#ifdef GL_SUN_mesh_array
+ &__GLEW_SUN_mesh_array,
+#endif
+#ifdef GL_SUN_read_video_pixels
+ &__GLEW_SUN_read_video_pixels,
+#endif
+#ifdef GL_SUN_slice_accum
+ &__GLEW_SUN_slice_accum,
+#endif
+#ifdef GL_SUN_triangle_list
+ &__GLEW_SUN_triangle_list,
+#endif
+#ifdef GL_SUN_vertex
+ &__GLEW_SUN_vertex,
+#endif
+#ifdef GL_WIN_phong_shading
+ &__GLEW_WIN_phong_shading,
+#endif
+#ifdef GL_WIN_scene_markerXXX
+ &__GLEW_WIN_scene_markerXXX,
+#endif
+#ifdef GL_WIN_specular_fog
+ &__GLEW_WIN_specular_fog,
+#endif
+#ifdef GL_WIN_swap_hint
+ &__GLEW_WIN_swap_hint,
+#endif
+ NULL
+};
+static GLboolean _glewInit_GL_VERSION_1_2 ();
+static GLboolean _glewInit_GL_VERSION_1_3 ();
+static GLboolean _glewInit_GL_VERSION_1_4 ();
+static GLboolean _glewInit_GL_VERSION_1_5 ();
+static GLboolean _glewInit_GL_VERSION_2_0 ();
+static GLboolean _glewInit_GL_VERSION_2_1 ();
+static GLboolean _glewInit_GL_VERSION_3_0 ();
+static GLboolean _glewInit_GL_VERSION_3_1 ();
+static GLboolean _glewInit_GL_VERSION_3_2 ();
+static GLboolean _glewInit_GL_VERSION_3_3 ();
+static GLboolean _glewInit_GL_VERSION_4_0 ();
+static GLboolean _glewInit_GL_VERSION_4_5 ();
+static GLboolean _glewInit_GL_VERSION_4_6 ();
+static GLboolean _glewInit_GL_3DFX_tbuffer ();
+static GLboolean _glewInit_GL_AMD_debug_output ();
+static GLboolean _glewInit_GL_AMD_draw_buffers_blend ();
+static GLboolean _glewInit_GL_AMD_framebuffer_sample_positions ();
+static GLboolean _glewInit_GL_AMD_interleaved_elements ();
+static GLboolean _glewInit_GL_AMD_multi_draw_indirect ();
+static GLboolean _glewInit_GL_AMD_name_gen_delete ();
+static GLboolean _glewInit_GL_AMD_occlusion_query_event ();
+static GLboolean _glewInit_GL_AMD_performance_monitor ();
+static GLboolean _glewInit_GL_AMD_sample_positions ();
+static GLboolean _glewInit_GL_AMD_sparse_texture ();
+static GLboolean _glewInit_GL_AMD_stencil_operation_extended ();
+static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator ();
+static GLboolean _glewInit_GL_ANGLE_framebuffer_blit ();
+static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample ();
+static GLboolean _glewInit_GL_ANGLE_instanced_arrays ();
+static GLboolean _glewInit_GL_ANGLE_timer_query ();
+static GLboolean _glewInit_GL_ANGLE_translated_shader_source ();
+static GLboolean _glewInit_GL_APPLE_copy_texture_levels ();
+static GLboolean _glewInit_GL_APPLE_element_array ();
+static GLboolean _glewInit_GL_APPLE_fence ();
+static GLboolean _glewInit_GL_APPLE_flush_buffer_range ();
+static GLboolean _glewInit_GL_APPLE_framebuffer_multisample ();
+static GLboolean _glewInit_GL_APPLE_object_purgeable ();
+static GLboolean _glewInit_GL_APPLE_sync ();
+static GLboolean _glewInit_GL_APPLE_texture_range ();
+static GLboolean _glewInit_GL_APPLE_vertex_array_object ();
+static GLboolean _glewInit_GL_APPLE_vertex_array_range ();
+static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators ();
+static GLboolean _glewInit_GL_ARB_ES2_compatibility ();
+static GLboolean _glewInit_GL_ARB_ES3_1_compatibility ();
+static GLboolean _glewInit_GL_ARB_ES3_2_compatibility ();
+static GLboolean _glewInit_GL_ARB_base_instance ();
+static GLboolean _glewInit_GL_ARB_bindless_texture ();
+static GLboolean _glewInit_GL_ARB_blend_func_extended ();
+static GLboolean _glewInit_GL_ARB_buffer_storage ();
+static GLboolean _glewInit_GL_ARB_cl_event ();
+static GLboolean _glewInit_GL_ARB_clear_buffer_object ();
+static GLboolean _glewInit_GL_ARB_clear_texture ();
+static GLboolean _glewInit_GL_ARB_clip_control ();
+static GLboolean _glewInit_GL_ARB_color_buffer_float ();
+static GLboolean _glewInit_GL_ARB_compute_shader ();
+static GLboolean _glewInit_GL_ARB_compute_variable_group_size ();
+static GLboolean _glewInit_GL_ARB_copy_buffer ();
+static GLboolean _glewInit_GL_ARB_copy_image ();
+static GLboolean _glewInit_GL_ARB_debug_output ();
+static GLboolean _glewInit_GL_ARB_direct_state_access ();
+static GLboolean _glewInit_GL_ARB_draw_buffers ();
+static GLboolean _glewInit_GL_ARB_draw_buffers_blend ();
+static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex ();
+static GLboolean _glewInit_GL_ARB_draw_indirect ();
+static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments ();
+static GLboolean _glewInit_GL_ARB_framebuffer_object ();
+static GLboolean _glewInit_GL_ARB_geometry_shader4 ();
+static GLboolean _glewInit_GL_ARB_get_program_binary ();
+static GLboolean _glewInit_GL_ARB_get_texture_sub_image ();
+static GLboolean _glewInit_GL_ARB_gl_spirv ();
+static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 ();
+static GLboolean _glewInit_GL_ARB_gpu_shader_int64 ();
+static GLboolean _glewInit_GL_ARB_imaging ();
+static GLboolean _glewInit_GL_ARB_indirect_parameters ();
+static GLboolean _glewInit_GL_ARB_instanced_arrays ();
+static GLboolean _glewInit_GL_ARB_internalformat_query ();
+static GLboolean _glewInit_GL_ARB_internalformat_query2 ();
+static GLboolean _glewInit_GL_ARB_invalidate_subdata ();
+static GLboolean _glewInit_GL_ARB_map_buffer_range ();
+static GLboolean _glewInit_GL_ARB_matrix_palette ();
+static GLboolean _glewInit_GL_ARB_multi_bind ();
+static GLboolean _glewInit_GL_ARB_multi_draw_indirect ();
+static GLboolean _glewInit_GL_ARB_multisample ();
+static GLboolean _glewInit_GL_ARB_multitexture ();
+static GLboolean _glewInit_GL_ARB_occlusion_query ();
+static GLboolean _glewInit_GL_ARB_parallel_shader_compile ();
+static GLboolean _glewInit_GL_ARB_point_parameters ();
+static GLboolean _glewInit_GL_ARB_polygon_offset_clamp ();
+static GLboolean _glewInit_GL_ARB_program_interface_query ();
+static GLboolean _glewInit_GL_ARB_provoking_vertex ();
+static GLboolean _glewInit_GL_ARB_robustness ();
+static GLboolean _glewInit_GL_ARB_sample_locations ();
+static GLboolean _glewInit_GL_ARB_sample_shading ();
+static GLboolean _glewInit_GL_ARB_sampler_objects ();
+static GLboolean _glewInit_GL_ARB_separate_shader_objects ();
+static GLboolean _glewInit_GL_ARB_shader_atomic_counters ();
+static GLboolean _glewInit_GL_ARB_shader_image_load_store ();
+static GLboolean _glewInit_GL_ARB_shader_objects ();
+static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object ();
+static GLboolean _glewInit_GL_ARB_shader_subroutine ();
+static GLboolean _glewInit_GL_ARB_shading_language_include ();
+static GLboolean _glewInit_GL_ARB_sparse_buffer ();
+static GLboolean _glewInit_GL_ARB_sparse_texture ();
+static GLboolean _glewInit_GL_ARB_sync ();
+static GLboolean _glewInit_GL_ARB_tessellation_shader ();
+static GLboolean _glewInit_GL_ARB_texture_barrier ();
+static GLboolean _glewInit_GL_ARB_texture_buffer_object ();
+static GLboolean _glewInit_GL_ARB_texture_buffer_range ();
+static GLboolean _glewInit_GL_ARB_texture_compression ();
+static GLboolean _glewInit_GL_ARB_texture_multisample ();
+static GLboolean _glewInit_GL_ARB_texture_storage ();
+static GLboolean _glewInit_GL_ARB_texture_storage_multisample ();
+static GLboolean _glewInit_GL_ARB_texture_view ();
+static GLboolean _glewInit_GL_ARB_timer_query ();
+static GLboolean _glewInit_GL_ARB_transform_feedback2 ();
+static GLboolean _glewInit_GL_ARB_transform_feedback3 ();
+static GLboolean _glewInit_GL_ARB_transform_feedback_instanced ();
+static GLboolean _glewInit_GL_ARB_transpose_matrix ();
+static GLboolean _glewInit_GL_ARB_uniform_buffer_object ();
+static GLboolean _glewInit_GL_ARB_vertex_array_object ();
+static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit ();
+static GLboolean _glewInit_GL_ARB_vertex_attrib_binding ();
+static GLboolean _glewInit_GL_ARB_vertex_blend ();
+static GLboolean _glewInit_GL_ARB_vertex_buffer_object ();
+static GLboolean _glewInit_GL_ARB_vertex_program ();
+static GLboolean _glewInit_GL_ARB_vertex_shader ();
+static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev ();
+static GLboolean _glewInit_GL_ARB_viewport_array ();
+static GLboolean _glewInit_GL_ARB_window_pos ();
+static GLboolean _glewInit_GL_ATI_draw_buffers ();
+static GLboolean _glewInit_GL_ATI_element_array ();
+static GLboolean _glewInit_GL_ATI_envmap_bumpmap ();
+static GLboolean _glewInit_GL_ATI_fragment_shader ();
+static GLboolean _glewInit_GL_ATI_map_object_buffer ();
+static GLboolean _glewInit_GL_ATI_pn_triangles ();
+static GLboolean _glewInit_GL_ATI_separate_stencil ();
+static GLboolean _glewInit_GL_ATI_vertex_array_object ();
+static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object ();
+static GLboolean _glewInit_GL_ATI_vertex_streams ();
+static GLboolean _glewInit_GL_EXT_base_instance ();
+static GLboolean _glewInit_GL_EXT_bindable_uniform ();
+static GLboolean _glewInit_GL_EXT_blend_color ();
+static GLboolean _glewInit_GL_EXT_blend_equation_separate ();
+static GLboolean _glewInit_GL_EXT_blend_func_extended ();
+static GLboolean _glewInit_GL_EXT_blend_func_separate ();
+static GLboolean _glewInit_GL_EXT_blend_minmax ();
+static GLboolean _glewInit_GL_EXT_buffer_storage ();
+static GLboolean _glewInit_GL_EXT_clear_texture ();
+static GLboolean _glewInit_GL_EXT_color_subtable ();
+static GLboolean _glewInit_GL_EXT_compiled_vertex_array ();
+static GLboolean _glewInit_GL_EXT_convolution ();
+static GLboolean _glewInit_GL_EXT_coordinate_frame ();
+static GLboolean _glewInit_GL_EXT_copy_image ();
+static GLboolean _glewInit_GL_EXT_copy_texture ();
+static GLboolean _glewInit_GL_EXT_cull_vertex ();
+static GLboolean _glewInit_GL_EXT_debug_label ();
+static GLboolean _glewInit_GL_EXT_debug_marker ();
+static GLboolean _glewInit_GL_EXT_depth_bounds_test ();
+static GLboolean _glewInit_GL_EXT_direct_state_access ();
+static GLboolean _glewInit_GL_EXT_discard_framebuffer ();
+static GLboolean _glewInit_GL_EXT_draw_buffers ();
+static GLboolean _glewInit_GL_EXT_draw_buffers2 ();
+static GLboolean _glewInit_GL_EXT_draw_buffers_indexed ();
+static GLboolean _glewInit_GL_EXT_draw_elements_base_vertex ();
+static GLboolean _glewInit_GL_EXT_draw_instanced ();
+static GLboolean _glewInit_GL_EXT_draw_range_elements ();
+static GLboolean _glewInit_GL_EXT_external_buffer ();
+static GLboolean _glewInit_GL_EXT_fog_coord ();
+static GLboolean _glewInit_GL_EXT_fragment_lighting ();
+static GLboolean _glewInit_GL_EXT_framebuffer_blit ();
+static GLboolean _glewInit_GL_EXT_framebuffer_multisample ();
+static GLboolean _glewInit_GL_EXT_framebuffer_object ();
+static GLboolean _glewInit_GL_EXT_geometry_shader4 ();
+static GLboolean _glewInit_GL_EXT_gpu_program_parameters ();
+static GLboolean _glewInit_GL_EXT_gpu_shader4 ();
+static GLboolean _glewInit_GL_EXT_histogram ();
+static GLboolean _glewInit_GL_EXT_index_func ();
+static GLboolean _glewInit_GL_EXT_index_material ();
+static GLboolean _glewInit_GL_EXT_instanced_arrays ();
+static GLboolean _glewInit_GL_EXT_light_texture ();
+static GLboolean _glewInit_GL_EXT_map_buffer_range ();
+static GLboolean _glewInit_GL_EXT_memory_object ();
+static GLboolean _glewInit_GL_EXT_memory_object_fd ();
+static GLboolean _glewInit_GL_EXT_memory_object_win32 ();
+static GLboolean _glewInit_GL_EXT_multi_draw_arrays ();
+static GLboolean _glewInit_GL_EXT_multi_draw_indirect ();
+static GLboolean _glewInit_GL_EXT_multisample ();
+static GLboolean _glewInit_GL_EXT_multisampled_render_to_texture ();
+static GLboolean _glewInit_GL_EXT_multiview_draw_buffers ();
+static GLboolean _glewInit_GL_EXT_paletted_texture ();
+static GLboolean _glewInit_GL_EXT_pixel_transform ();
+static GLboolean _glewInit_GL_EXT_point_parameters ();
+static GLboolean _glewInit_GL_EXT_polygon_offset ();
+static GLboolean _glewInit_GL_EXT_polygon_offset_clamp ();
+static GLboolean _glewInit_GL_EXT_provoking_vertex ();
+static GLboolean _glewInit_GL_EXT_raster_multisample ();
+static GLboolean _glewInit_GL_EXT_scene_marker ();
+static GLboolean _glewInit_GL_EXT_secondary_color ();
+static GLboolean _glewInit_GL_EXT_semaphore ();
+static GLboolean _glewInit_GL_EXT_semaphore_fd ();
+static GLboolean _glewInit_GL_EXT_semaphore_win32 ();
+static GLboolean _glewInit_GL_EXT_separate_shader_objects ();
+static GLboolean _glewInit_GL_EXT_shader_image_load_store ();
+static GLboolean _glewInit_GL_EXT_shader_pixel_local_storage2 ();
+static GLboolean _glewInit_GL_EXT_sparse_texture ();
+static GLboolean _glewInit_GL_EXT_stencil_two_side ();
+static GLboolean _glewInit_GL_EXT_subtexture ();
+static GLboolean _glewInit_GL_EXT_texture3D ();
+static GLboolean _glewInit_GL_EXT_texture_array ();
+static GLboolean _glewInit_GL_EXT_texture_buffer_object ();
+static GLboolean _glewInit_GL_EXT_texture_integer ();
+static GLboolean _glewInit_GL_EXT_texture_object ();
+static GLboolean _glewInit_GL_EXT_texture_perturb_normal ();
+static GLboolean _glewInit_GL_EXT_texture_storage ();
+static GLboolean _glewInit_GL_EXT_texture_view ();
+static GLboolean _glewInit_GL_EXT_timer_query ();
+static GLboolean _glewInit_GL_EXT_transform_feedback ();
+static GLboolean _glewInit_GL_EXT_vertex_array ();
+static GLboolean _glewInit_GL_EXT_vertex_array_setXXX ();
+static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit ();
+static GLboolean _glewInit_GL_EXT_vertex_shader ();
+static GLboolean _glewInit_GL_EXT_vertex_weighting ();
+static GLboolean _glewInit_GL_EXT_win32_keyed_mutex ();
+static GLboolean _glewInit_GL_EXT_window_rectangles ();
+static GLboolean _glewInit_GL_EXT_x11_sync_object ();
+static GLboolean _glewInit_GL_GREMEDY_frame_terminator ();
+static GLboolean _glewInit_GL_GREMEDY_string_marker ();
+static GLboolean _glewInit_GL_HP_image_transform ();
+static GLboolean _glewInit_GL_IBM_multimode_draw_arrays ();
+static GLboolean _glewInit_GL_IBM_vertex_array_lists ();
+static GLboolean _glewInit_GL_INTEL_map_texture ();
+static GLboolean _glewInit_GL_INTEL_parallel_arrays ();
+static GLboolean _glewInit_GL_INTEL_performance_query ();
+static GLboolean _glewInit_GL_INTEL_texture_scissor ();
+static GLboolean _glewInit_GL_KHR_blend_equation_advanced ();
+static GLboolean _glewInit_GL_KHR_debug ();
+static GLboolean _glewInit_GL_KHR_parallel_shader_compile ();
+static GLboolean _glewInit_GL_KHR_robustness ();
+static GLboolean _glewInit_GL_KTX_buffer_region ();
+static GLboolean _glewInit_GL_MESA_resize_buffers ();
+static GLboolean _glewInit_GL_MESA_window_pos ();
+static GLboolean _glewInit_GL_NVX_conditional_render ();
+static GLboolean _glewInit_GL_NVX_linked_gpu_multicast ();
+static GLboolean _glewInit_GL_NV_3dvision_settings ();
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect ();
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count ();
+static GLboolean _glewInit_GL_NV_bindless_texture ();
+static GLboolean _glewInit_GL_NV_blend_equation_advanced ();
+static GLboolean _glewInit_GL_NV_clip_space_w_scaling ();
+static GLboolean _glewInit_GL_NV_command_list ();
+static GLboolean _glewInit_GL_NV_conditional_render ();
+static GLboolean _glewInit_GL_NV_conservative_raster ();
+static GLboolean _glewInit_GL_NV_conservative_raster_dilate ();
+static GLboolean _glewInit_GL_NV_conservative_raster_pre_snap_triangles ();
+static GLboolean _glewInit_GL_NV_copy_buffer ();
+static GLboolean _glewInit_GL_NV_copy_image ();
+static GLboolean _glewInit_GL_NV_depth_buffer_float ();
+static GLboolean _glewInit_GL_NV_draw_buffers ();
+static GLboolean _glewInit_GL_NV_draw_instanced ();
+static GLboolean _glewInit_GL_NV_draw_texture ();
+static GLboolean _glewInit_GL_NV_draw_vulkan_image ();
+static GLboolean _glewInit_GL_NV_evaluators ();
+static GLboolean _glewInit_GL_NV_explicit_multisample ();
+static GLboolean _glewInit_GL_NV_fence ();
+static GLboolean _glewInit_GL_NV_fragment_coverage_to_color ();
+static GLboolean _glewInit_GL_NV_fragment_program ();
+static GLboolean _glewInit_GL_NV_framebuffer_blit ();
+static GLboolean _glewInit_GL_NV_framebuffer_multisample ();
+static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage ();
+static GLboolean _glewInit_GL_NV_geometry_program4 ();
+static GLboolean _glewInit_GL_NV_gpu_multicast ();
+static GLboolean _glewInit_GL_NV_gpu_program4 ();
+static GLboolean _glewInit_GL_NV_gpu_shader5 ();
+static GLboolean _glewInit_GL_NV_half_float ();
+static GLboolean _glewInit_GL_NV_instanced_arrays ();
+static GLboolean _glewInit_GL_NV_internalformat_sample_query ();
+static GLboolean _glewInit_GL_NV_non_square_matrices ();
+static GLboolean _glewInit_GL_NV_occlusion_query ();
+static GLboolean _glewInit_GL_NV_parameter_buffer_object ();
+static GLboolean _glewInit_GL_NV_path_rendering ();
+static GLboolean _glewInit_GL_NV_pixel_data_range ();
+static GLboolean _glewInit_GL_NV_point_sprite ();
+static GLboolean _glewInit_GL_NV_polygon_mode ();
+static GLboolean _glewInit_GL_NV_present_video ();
+static GLboolean _glewInit_GL_NV_primitive_restart ();
+static GLboolean _glewInit_GL_NV_register_combiners ();
+static GLboolean _glewInit_GL_NV_register_combiners2 ();
+static GLboolean _glewInit_GL_NV_sample_locations ();
+static GLboolean _glewInit_GL_NV_shader_buffer_load ();
+static GLboolean _glewInit_GL_NV_texture_array ();
+static GLboolean _glewInit_GL_NV_texture_barrier ();
+static GLboolean _glewInit_GL_NV_texture_multisample ();
+static GLboolean _glewInit_GL_NV_transform_feedback ();
+static GLboolean _glewInit_GL_NV_transform_feedback2 ();
+static GLboolean _glewInit_GL_NV_vdpau_interop ();
+static GLboolean _glewInit_GL_NV_vertex_array_range ();
+static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit ();
+static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory ();
+static GLboolean _glewInit_GL_NV_vertex_program ();
+static GLboolean _glewInit_GL_NV_video_capture ();
+static GLboolean _glewInit_GL_NV_viewport_array ();
+static GLboolean _glewInit_GL_NV_viewport_swizzle ();
+static GLboolean _glewInit_GL_OVR_multiview ();
+static GLboolean _glewInit_GL_OVR_multiview_multisampled_render_to_texture ();
+static GLboolean _glewInit_GL_QCOM_alpha_test ();
+static GLboolean _glewInit_GL_QCOM_driver_control ();
+static GLboolean _glewInit_GL_QCOM_extended_get ();
+static GLboolean _glewInit_GL_QCOM_extended_get2 ();
+static GLboolean _glewInit_GL_QCOM_framebuffer_foveated ();
+static GLboolean _glewInit_GL_QCOM_shader_framebuffer_fetch_noncoherent ();
+static GLboolean _glewInit_GL_QCOM_tiled_rendering ();
+static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility ();
+static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility ();
+static GLboolean _glewInit_GL_REGAL_error_string ();
+static GLboolean _glewInit_GL_REGAL_extension_query ();
+static GLboolean _glewInit_GL_REGAL_log ();
+static GLboolean _glewInit_GL_REGAL_proc_address ();
+static GLboolean _glewInit_GL_SGIS_detail_texture ();
+static GLboolean _glewInit_GL_SGIS_fog_function ();
+static GLboolean _glewInit_GL_SGIS_multisample ();
+static GLboolean _glewInit_GL_SGIS_multitexture ();
+static GLboolean _glewInit_GL_SGIS_shared_multisample ();
+static GLboolean _glewInit_GL_SGIS_sharpen_texture ();
+static GLboolean _glewInit_GL_SGIS_texture4D ();
+static GLboolean _glewInit_GL_SGIS_texture_filter4 ();
+static GLboolean _glewInit_GL_SGIX_async ();
+static GLboolean _glewInit_GL_SGIX_datapipe ();
+static GLboolean _glewInit_GL_SGIX_flush_raster ();
+static GLboolean _glewInit_GL_SGIX_fog_layers ();
+static GLboolean _glewInit_GL_SGIX_fog_texture ();
+static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting ();
+static GLboolean _glewInit_GL_SGIX_framezoom ();
+static GLboolean _glewInit_GL_SGIX_igloo_interface ();
+static GLboolean _glewInit_GL_SGIX_mpeg1 ();
+static GLboolean _glewInit_GL_SGIX_nonlinear_lighting_pervertex ();
+static GLboolean _glewInit_GL_SGIX_pixel_texture ();
+static GLboolean _glewInit_GL_SGIX_polynomial_ffd ();
+static GLboolean _glewInit_GL_SGIX_quad_mesh ();
+static GLboolean _glewInit_GL_SGIX_reference_plane ();
+static GLboolean _glewInit_GL_SGIX_sprite ();
+static GLboolean _glewInit_GL_SGIX_tag_sample_buffer ();
+static GLboolean _glewInit_GL_SGIX_vector_ops ();
+static GLboolean _glewInit_GL_SGIX_vertex_array_object ();
+static GLboolean _glewInit_GL_SGI_color_table ();
+static GLboolean _glewInit_GL_SGI_fft ();
+static GLboolean _glewInit_GL_SUNX_constant_data ();
+static GLboolean _glewInit_GL_SUN_global_alpha ();
+static GLboolean _glewInit_GL_SUN_read_video_pixels ();
+static GLboolean _glewInit_GL_SUN_triangle_list ();
+static GLboolean _glewInit_GL_SUN_vertex ();
+static GLboolean _glewInit_GL_WIN_swap_hint ();
+
+#ifdef GL_VERSION_1_2
+
+static GLboolean _glewInit_GL_VERSION_1_2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3D")) == NULL) || r;
+ r = ((glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElements")) == NULL) || r;
+ r = ((glTexImage3D = (PFNGLTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexImage3D")) == NULL) || r;
+ r = ((glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_2 */
+
+#ifdef GL_VERSION_1_3
+
+static GLboolean _glewInit_GL_VERSION_1_3 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveTexture = (PFNGLACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glActiveTexture")) == NULL) || r;
+ r = ((glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTexture")) == NULL) || r;
+ r = ((glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1D")) == NULL) || r;
+ r = ((glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2D")) == NULL) || r;
+ r = ((glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3D")) == NULL) || r;
+ r = ((glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1D")) == NULL) || r;
+ r = ((glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2D")) == NULL) || r;
+ r = ((glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3D")) == NULL) || r;
+ r = ((glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImage")) == NULL) || r;
+ r = ((glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixd")) == NULL) || r;
+ r = ((glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixf")) == NULL) || r;
+ r = ((glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixd")) == NULL) || r;
+ r = ((glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixf")) == NULL) || r;
+ r = ((glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1d")) == NULL) || r;
+ r = ((glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dv")) == NULL) || r;
+ r = ((glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1f")) == NULL) || r;
+ r = ((glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fv")) == NULL) || r;
+ r = ((glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1i")) == NULL) || r;
+ r = ((glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iv")) == NULL) || r;
+ r = ((glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1s")) == NULL) || r;
+ r = ((glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sv")) == NULL) || r;
+ r = ((glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2d")) == NULL) || r;
+ r = ((glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dv")) == NULL) || r;
+ r = ((glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2f")) == NULL) || r;
+ r = ((glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fv")) == NULL) || r;
+ r = ((glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2i")) == NULL) || r;
+ r = ((glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iv")) == NULL) || r;
+ r = ((glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2s")) == NULL) || r;
+ r = ((glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sv")) == NULL) || r;
+ r = ((glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3d")) == NULL) || r;
+ r = ((glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dv")) == NULL) || r;
+ r = ((glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3f")) == NULL) || r;
+ r = ((glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fv")) == NULL) || r;
+ r = ((glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3i")) == NULL) || r;
+ r = ((glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iv")) == NULL) || r;
+ r = ((glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3s")) == NULL) || r;
+ r = ((glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sv")) == NULL) || r;
+ r = ((glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4d")) == NULL) || r;
+ r = ((glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dv")) == NULL) || r;
+ r = ((glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4f")) == NULL) || r;
+ r = ((glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fv")) == NULL) || r;
+ r = ((glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4i")) == NULL) || r;
+ r = ((glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iv")) == NULL) || r;
+ r = ((glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4s")) == NULL) || r;
+ r = ((glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sv")) == NULL) || r;
+ r = ((glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_3 */
+
+#ifdef GL_VERSION_1_4
+
+static GLboolean _glewInit_GL_VERSION_1_4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendColor = (PFNGLBLENDCOLORPROC)glewGetProcAddress((const GLubyte*)"glBlendColor")) == NULL) || r;
+ r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r;
+ r = ((glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparate")) == NULL) || r;
+ r = ((glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointer")) == NULL) || r;
+ r = ((glFogCoordd = (PFNGLFOGCOORDDPROC)glewGetProcAddress((const GLubyte*)"glFogCoordd")) == NULL) || r;
+ r = ((glFogCoorddv = (PFNGLFOGCOORDDVPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddv")) == NULL) || r;
+ r = ((glFogCoordf = (PFNGLFOGCOORDFPROC)glewGetProcAddress((const GLubyte*)"glFogCoordf")) == NULL) || r;
+ r = ((glFogCoordfv = (PFNGLFOGCOORDFVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfv")) == NULL) || r;
+ r = ((glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArrays")) == NULL) || r;
+ r = ((glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElements")) == NULL) || r;
+ r = ((glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glPointParameterf")) == NULL) || r;
+ r = ((glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfv")) == NULL) || r;
+ r = ((glPointParameteri = (PFNGLPOINTPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPointParameteri")) == NULL) || r;
+ r = ((glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriv")) == NULL) || r;
+ r = ((glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3b")) == NULL) || r;
+ r = ((glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bv")) == NULL) || r;
+ r = ((glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3d")) == NULL) || r;
+ r = ((glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dv")) == NULL) || r;
+ r = ((glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3f")) == NULL) || r;
+ r = ((glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fv")) == NULL) || r;
+ r = ((glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3i")) == NULL) || r;
+ r = ((glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iv")) == NULL) || r;
+ r = ((glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3s")) == NULL) || r;
+ r = ((glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sv")) == NULL) || r;
+ r = ((glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ub")) == NULL) || r;
+ r = ((glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubv")) == NULL) || r;
+ r = ((glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ui")) == NULL) || r;
+ r = ((glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiv")) == NULL) || r;
+ r = ((glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3us")) == NULL) || r;
+ r = ((glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usv")) == NULL) || r;
+ r = ((glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointer")) == NULL) || r;
+ r = ((glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2d")) == NULL) || r;
+ r = ((glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dv")) == NULL) || r;
+ r = ((glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2f")) == NULL) || r;
+ r = ((glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fv")) == NULL) || r;
+ r = ((glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2i")) == NULL) || r;
+ r = ((glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iv")) == NULL) || r;
+ r = ((glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2s")) == NULL) || r;
+ r = ((glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sv")) == NULL) || r;
+ r = ((glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3d")) == NULL) || r;
+ r = ((glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dv")) == NULL) || r;
+ r = ((glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3f")) == NULL) || r;
+ r = ((glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fv")) == NULL) || r;
+ r = ((glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3i")) == NULL) || r;
+ r = ((glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iv")) == NULL) || r;
+ r = ((glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3s")) == NULL) || r;
+ r = ((glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_4 */
+
+#ifdef GL_VERSION_1_5
+
+static GLboolean _glewInit_GL_VERSION_1_5 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQuery = (PFNGLBEGINQUERYPROC)glewGetProcAddress((const GLubyte*)"glBeginQuery")) == NULL) || r;
+ r = ((glBindBuffer = (PFNGLBINDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindBuffer")) == NULL) || r;
+ r = ((glBufferData = (PFNGLBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferData")) == NULL) || r;
+ r = ((glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferSubData")) == NULL) || r;
+ r = ((glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffers")) == NULL) || r;
+ r = ((glDeleteQueries = (PFNGLDELETEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueries")) == NULL) || r;
+ r = ((glEndQuery = (PFNGLENDQUERYPROC)glewGetProcAddress((const GLubyte*)"glEndQuery")) == NULL) || r;
+ r = ((glGenBuffers = (PFNGLGENBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenBuffers")) == NULL) || r;
+ r = ((glGenQueries = (PFNGLGENQUERIESPROC)glewGetProcAddress((const GLubyte*)"glGenQueries")) == NULL) || r;
+ r = ((glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteriv")) == NULL) || r;
+ r = ((glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointerv")) == NULL) || r;
+ r = ((glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubData")) == NULL) || r;
+ r = ((glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectiv")) == NULL) || r;
+ r = ((glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuiv")) == NULL) || r;
+ r = ((glGetQueryiv = (PFNGLGETQUERYIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryiv")) == NULL) || r;
+ r = ((glIsBuffer = (PFNGLISBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsBuffer")) == NULL) || r;
+ r = ((glIsQuery = (PFNGLISQUERYPROC)glewGetProcAddress((const GLubyte*)"glIsQuery")) == NULL) || r;
+ r = ((glMapBuffer = (PFNGLMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapBuffer")) == NULL) || r;
+ r = ((glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapBuffer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_5 */
+
+#ifdef GL_VERSION_2_0
+
+static GLboolean _glewInit_GL_VERSION_2_0 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r;
+ r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r;
+ r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r;
+ r = ((glCompileShader = (PFNGLCOMPILESHADERPROC)glewGetProcAddress((const GLubyte*)"glCompileShader")) == NULL) || r;
+ r = ((glCreateProgram = (PFNGLCREATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glCreateProgram")) == NULL) || r;
+ r = ((glCreateShader = (PFNGLCREATESHADERPROC)glewGetProcAddress((const GLubyte*)"glCreateShader")) == NULL) || r;
+ r = ((glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgram")) == NULL) || r;
+ r = ((glDeleteShader = (PFNGLDELETESHADERPROC)glewGetProcAddress((const GLubyte*)"glDeleteShader")) == NULL) || r;
+ r = ((glDetachShader = (PFNGLDETACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glDetachShader")) == NULL) || r;
+ r = ((glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArray")) == NULL) || r;
+ r = ((glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffers")) == NULL) || r;
+ r = ((glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArray")) == NULL) || r;
+ r = ((glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttrib")) == NULL) || r;
+ r = ((glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniform")) == NULL) || r;
+ r = ((glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedShaders")) == NULL) || r;
+ r = ((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocation")) == NULL) || r;
+ r = ((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInfoLog")) == NULL) || r;
+ r = ((glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramiv")) == NULL) || r;
+ r = ((glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetShaderInfoLog")) == NULL) || r;
+ r = ((glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSource")) == NULL) || r;
+ r = ((glGetShaderiv = (PFNGLGETSHADERIVPROC)glewGetProcAddress((const GLubyte*)"glGetShaderiv")) == NULL) || r;
+ r = ((glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocation")) == NULL) || r;
+ r = ((glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfv")) == NULL) || r;
+ r = ((glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformiv")) == NULL) || r;
+ r = ((glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointerv")) == NULL) || r;
+ r = ((glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdv")) == NULL) || r;
+ r = ((glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfv")) == NULL) || r;
+ r = ((glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribiv")) == NULL) || r;
+ r = ((glIsProgram = (PFNGLISPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glIsProgram")) == NULL) || r;
+ r = ((glIsShader = (PFNGLISSHADERPROC)glewGetProcAddress((const GLubyte*)"glIsShader")) == NULL) || r;
+ r = ((glLinkProgram = (PFNGLLINKPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glLinkProgram")) == NULL) || r;
+ r = ((glShaderSource = (PFNGLSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glShaderSource")) == NULL) || r;
+ r = ((glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparate")) == NULL) || r;
+ r = ((glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilMaskSeparate")) == NULL) || r;
+ r = ((glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparate")) == NULL) || r;
+ r = ((glUniform1f = (PFNGLUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glUniform1f")) == NULL) || r;
+ r = ((glUniform1fv = (PFNGLUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glUniform1fv")) == NULL) || r;
+ r = ((glUniform1i = (PFNGLUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glUniform1i")) == NULL) || r;
+ r = ((glUniform1iv = (PFNGLUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glUniform1iv")) == NULL) || r;
+ r = ((glUniform2f = (PFNGLUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glUniform2f")) == NULL) || r;
+ r = ((glUniform2fv = (PFNGLUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glUniform2fv")) == NULL) || r;
+ r = ((glUniform2i = (PFNGLUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glUniform2i")) == NULL) || r;
+ r = ((glUniform2iv = (PFNGLUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glUniform2iv")) == NULL) || r;
+ r = ((glUniform3f = (PFNGLUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glUniform3f")) == NULL) || r;
+ r = ((glUniform3fv = (PFNGLUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glUniform3fv")) == NULL) || r;
+ r = ((glUniform3i = (PFNGLUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glUniform3i")) == NULL) || r;
+ r = ((glUniform3iv = (PFNGLUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glUniform3iv")) == NULL) || r;
+ r = ((glUniform4f = (PFNGLUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glUniform4f")) == NULL) || r;
+ r = ((glUniform4fv = (PFNGLUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glUniform4fv")) == NULL) || r;
+ r = ((glUniform4i = (PFNGLUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glUniform4i")) == NULL) || r;
+ r = ((glUniform4iv = (PFNGLUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glUniform4iv")) == NULL) || r;
+ r = ((glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fv")) == NULL) || r;
+ r = ((glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fv")) == NULL) || r;
+ r = ((glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fv")) == NULL) || r;
+ r = ((glUseProgram = (PFNGLUSEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glUseProgram")) == NULL) || r;
+ r = ((glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glValidateProgram")) == NULL) || r;
+ r = ((glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1d")) == NULL) || r;
+ r = ((glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dv")) == NULL) || r;
+ r = ((glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1f")) == NULL) || r;
+ r = ((glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fv")) == NULL) || r;
+ r = ((glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1s")) == NULL) || r;
+ r = ((glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sv")) == NULL) || r;
+ r = ((glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2d")) == NULL) || r;
+ r = ((glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dv")) == NULL) || r;
+ r = ((glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2f")) == NULL) || r;
+ r = ((glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fv")) == NULL) || r;
+ r = ((glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2s")) == NULL) || r;
+ r = ((glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sv")) == NULL) || r;
+ r = ((glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3d")) == NULL) || r;
+ r = ((glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dv")) == NULL) || r;
+ r = ((glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3f")) == NULL) || r;
+ r = ((glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fv")) == NULL) || r;
+ r = ((glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3s")) == NULL) || r;
+ r = ((glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sv")) == NULL) || r;
+ r = ((glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nbv")) == NULL) || r;
+ r = ((glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Niv")) == NULL) || r;
+ r = ((glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nsv")) == NULL) || r;
+ r = ((glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nub")) == NULL) || r;
+ r = ((glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nubv")) == NULL) || r;
+ r = ((glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nuiv")) == NULL) || r;
+ r = ((glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nusv")) == NULL) || r;
+ r = ((glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bv")) == NULL) || r;
+ r = ((glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4d")) == NULL) || r;
+ r = ((glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dv")) == NULL) || r;
+ r = ((glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4f")) == NULL) || r;
+ r = ((glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fv")) == NULL) || r;
+ r = ((glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4iv")) == NULL) || r;
+ r = ((glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4s")) == NULL) || r;
+ r = ((glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sv")) == NULL) || r;
+ r = ((glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubv")) == NULL) || r;
+ r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r;
+ r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r;
+ r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_2_0 */
+
+#ifdef GL_VERSION_2_1
+
+static GLboolean _glewInit_GL_VERSION_2_1 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fv")) == NULL) || r;
+ r = ((glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fv")) == NULL) || r;
+ r = ((glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fv")) == NULL) || r;
+ r = ((glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fv")) == NULL) || r;
+ r = ((glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fv")) == NULL) || r;
+ r = ((glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_2_1 */
+
+#ifdef GL_VERSION_3_0
+
+static GLboolean _glewInit_GL_VERSION_3_0 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = _glewInit_GL_ARB_framebuffer_object() || r;
+ r = _glewInit_GL_ARB_map_buffer_range() || r;
+ r = _glewInit_GL_ARB_uniform_buffer_object() || r;
+ r = _glewInit_GL_ARB_vertex_array_object() || r;
+
+ r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r;
+ r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r;
+ r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r;
+ r = ((glClampColor = (PFNGLCLAMPCOLORPROC)glewGetProcAddress((const GLubyte*)"glClampColor")) == NULL) || r;
+ r = ((glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfi")) == NULL) || r;
+ r = ((glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfv")) == NULL) || r;
+ r = ((glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferiv")) == NULL) || r;
+ r = ((glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferuiv")) == NULL) || r;
+ r = ((glColorMaski = (PFNGLCOLORMASKIPROC)glewGetProcAddress((const GLubyte*)"glColorMaski")) == NULL) || r;
+ r = ((glDisablei = (PFNGLDISABLEIPROC)glewGetProcAddress((const GLubyte*)"glDisablei")) == NULL) || r;
+ r = ((glEnablei = (PFNGLENABLEIPROC)glewGetProcAddress((const GLubyte*)"glEnablei")) == NULL) || r;
+ r = ((glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRender")) == NULL) || r;
+ r = ((glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedback")) == NULL) || r;
+ r = ((glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glewGetProcAddress((const GLubyte*)"glGetBooleani_v")) == NULL) || r;
+ r = ((glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocation")) == NULL) || r;
+ r = ((glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi")) == NULL) || r;
+ r = ((glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIiv")) == NULL) || r;
+ r = ((glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuiv")) == NULL) || r;
+ r = ((glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVarying")) == NULL) || r;
+ r = ((glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuiv")) == NULL) || r;
+ r = ((glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIiv")) == NULL) || r;
+ r = ((glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuiv")) == NULL) || r;
+ r = ((glIsEnabledi = (PFNGLISENABLEDIPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledi")) == NULL) || r;
+ r = ((glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIiv")) == NULL) || r;
+ r = ((glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuiv")) == NULL) || r;
+ r = ((glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryings")) == NULL) || r;
+ r = ((glUniform1ui = (PFNGLUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui")) == NULL) || r;
+ r = ((glUniform1uiv = (PFNGLUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiv")) == NULL) || r;
+ r = ((glUniform2ui = (PFNGLUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui")) == NULL) || r;
+ r = ((glUniform2uiv = (PFNGLUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiv")) == NULL) || r;
+ r = ((glUniform3ui = (PFNGLUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui")) == NULL) || r;
+ r = ((glUniform3uiv = (PFNGLUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiv")) == NULL) || r;
+ r = ((glUniform4ui = (PFNGLUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui")) == NULL) || r;
+ r = ((glUniform4uiv = (PFNGLUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiv")) == NULL) || r;
+ r = ((glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1i")) == NULL) || r;
+ r = ((glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iv")) == NULL) || r;
+ r = ((glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ui")) == NULL) || r;
+ r = ((glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiv")) == NULL) || r;
+ r = ((glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2i")) == NULL) || r;
+ r = ((glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iv")) == NULL) || r;
+ r = ((glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ui")) == NULL) || r;
+ r = ((glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiv")) == NULL) || r;
+ r = ((glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3i")) == NULL) || r;
+ r = ((glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iv")) == NULL) || r;
+ r = ((glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ui")) == NULL) || r;
+ r = ((glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiv")) == NULL) || r;
+ r = ((glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bv")) == NULL) || r;
+ r = ((glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4i")) == NULL) || r;
+ r = ((glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iv")) == NULL) || r;
+ r = ((glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4sv")) == NULL) || r;
+ r = ((glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubv")) == NULL) || r;
+ r = ((glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ui")) == NULL) || r;
+ r = ((glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiv")) == NULL) || r;
+ r = ((glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usv")) == NULL) || r;
+ r = ((glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_0 */
+
+#ifdef GL_VERSION_3_1
+
+static GLboolean _glewInit_GL_VERSION_3_1 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = _glewInit_GL_ARB_copy_buffer() || r;
+
+ r = ((glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstanced")) == NULL) || r;
+ r = ((glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstanced")) == NULL) || r;
+ r = ((glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndex")) == NULL) || r;
+ r = ((glTexBuffer = (PFNGLTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glTexBuffer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_1 */
+
+#ifdef GL_VERSION_3_2
+
+static GLboolean _glewInit_GL_VERSION_3_2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = _glewInit_GL_ARB_draw_elements_base_vertex() || r;
+ r = _glewInit_GL_ARB_provoking_vertex() || r;
+ r = _glewInit_GL_ARB_sync() || r;
+ r = _glewInit_GL_ARB_texture_multisample() || r;
+
+ r = ((glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture")) == NULL) || r;
+ r = ((glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteri64v")) == NULL) || r;
+ r = ((glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64i_v")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_2 */
+
+#ifdef GL_VERSION_3_3
+
+static GLboolean _glewInit_GL_VERSION_3_3 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisor")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_3 */
+
+#ifdef GL_VERSION_4_0
+
+static GLboolean _glewInit_GL_VERSION_4_0 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparatei")) == NULL) || r;
+ r = ((glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationi")) == NULL) || r;
+ r = ((glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparatei")) == NULL) || r;
+ r = ((glBlendFunci = (PFNGLBLENDFUNCIPROC)glewGetProcAddress((const GLubyte*)"glBlendFunci")) == NULL) || r;
+ r = ((glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShading")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_4_0 */
+
+#ifdef GL_VERSION_4_5
+
+static GLboolean _glewInit_GL_VERSION_4_5 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)glewGetProcAddress((const GLubyte*)"glGetGraphicsResetStatus")) == NULL) || r;
+ r = ((glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetnCompressedTexImage")) == NULL) || r;
+ r = ((glGetnTexImage = (PFNGLGETNTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetnTexImage")) == NULL) || r;
+ r = ((glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformdv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_4_5 */
+
+#ifdef GL_VERSION_4_6
+
+static GLboolean _glewInit_GL_VERSION_4_6 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectCount")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectCount")) == NULL) || r;
+ r = ((glSpecializeShader = (PFNGLSPECIALIZESHADERPROC)glewGetProcAddress((const GLubyte*)"glSpecializeShader")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_4_6 */
+
+#ifdef GL_3DFX_tbuffer
+
+static GLboolean _glewInit_GL_3DFX_tbuffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC)glewGetProcAddress((const GLubyte*)"glTbufferMask3DFX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_3DFX_tbuffer */
+
+#ifdef GL_AMD_debug_output
+
+static GLboolean _glewInit_GL_AMD_debug_output ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDebugMessageCallbackAMD = (PFNGLDEBUGMESSAGECALLBACKAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackAMD")) == NULL) || r;
+ r = ((glDebugMessageEnableAMD = (PFNGLDEBUGMESSAGEENABLEAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageEnableAMD")) == NULL) || r;
+ r = ((glDebugMessageInsertAMD = (PFNGLDEBUGMESSAGEINSERTAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertAMD")) == NULL) || r;
+ r = ((glGetDebugMessageLogAMD = (PFNGLGETDEBUGMESSAGELOGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_debug_output */
+
+#ifdef GL_AMD_draw_buffers_blend
+
+static GLboolean _glewInit_GL_AMD_draw_buffers_blend ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationIndexedAMD")) == NULL) || r;
+ r = ((glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateIndexedAMD")) == NULL) || r;
+ r = ((glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncIndexedAMD")) == NULL) || r;
+ r = ((glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateIndexedAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_draw_buffers_blend */
+
+#ifdef GL_AMD_framebuffer_sample_positions
+
+static GLboolean _glewInit_GL_AMD_framebuffer_sample_positions ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)glewGetProcAddress((const GLubyte*)"glFramebufferSamplePositionsfvAMD")) == NULL) || r;
+ r = ((glGetFramebufferParameterfvAMD = (PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterfvAMD")) == NULL) || r;
+ r = ((glGetNamedFramebufferParameterfvAMD = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameterfvAMD")) == NULL) || r;
+ r = ((glNamedFramebufferSamplePositionsfvAMD = (PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferSamplePositionsfvAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_framebuffer_sample_positions */
+
+#ifdef GL_AMD_interleaved_elements
+
+static GLboolean _glewInit_GL_AMD_interleaved_elements ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexAttribParameteriAMD = (PFNGLVERTEXATTRIBPARAMETERIAMDPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribParameteriAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_interleaved_elements */
+
+#ifdef GL_AMD_multi_draw_indirect
+
+static GLboolean _glewInit_GL_AMD_multi_draw_indirect ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectAMD = (PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectAMD")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectAMD = (PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_multi_draw_indirect */
+
+#ifdef GL_AMD_name_gen_delete
+
+static GLboolean _glewInit_GL_AMD_name_gen_delete ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeleteNamesAMD = (PFNGLDELETENAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamesAMD")) == NULL) || r;
+ r = ((glGenNamesAMD = (PFNGLGENNAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glGenNamesAMD")) == NULL) || r;
+ r = ((glIsNameAMD = (PFNGLISNAMEAMDPROC)glewGetProcAddress((const GLubyte*)"glIsNameAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_name_gen_delete */
+
+#ifdef GL_AMD_occlusion_query_event
+
+static GLboolean _glewInit_GL_AMD_occlusion_query_event ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glQueryObjectParameteruiAMD = (PFNGLQUERYOBJECTPARAMETERUIAMDPROC)glewGetProcAddress((const GLubyte*)"glQueryObjectParameteruiAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_occlusion_query_event */
+
+#ifdef GL_AMD_performance_monitor
+
+static GLboolean _glewInit_GL_AMD_performance_monitor ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfMonitorAMD")) == NULL) || r;
+ r = ((glDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfMonitorsAMD")) == NULL) || r;
+ r = ((glEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glEndPerfMonitorAMD")) == NULL) || r;
+ r = ((glGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glGenPerfMonitorsAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterDataAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterInfoAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterStringAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCountersAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupStringAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupsAMD")) == NULL) || r;
+ r = ((glSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glSelectPerfMonitorCountersAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_performance_monitor */
+
+#ifdef GL_AMD_sample_positions
+
+static GLboolean _glewInit_GL_AMD_sample_positions ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSetMultisamplefvAMD = (PFNGLSETMULTISAMPLEFVAMDPROC)glewGetProcAddress((const GLubyte*)"glSetMultisamplefvAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_sample_positions */
+
+#ifdef GL_AMD_sparse_texture
+
+static GLboolean _glewInit_GL_AMD_sparse_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexStorageSparseAMD = (PFNGLTEXSTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTexStorageSparseAMD")) == NULL) || r;
+ r = ((glTextureStorageSparseAMD = (PFNGLTEXTURESTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageSparseAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_sparse_texture */
+
+#ifdef GL_AMD_stencil_operation_extended
+
+static GLboolean _glewInit_GL_AMD_stencil_operation_extended ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glStencilOpValueAMD = (PFNGLSTENCILOPVALUEAMDPROC)glewGetProcAddress((const GLubyte*)"glStencilOpValueAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_stencil_operation_extended */
+
+#ifdef GL_AMD_vertex_shader_tessellator
+
+static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTessellationFactorAMD = (PFNGLTESSELLATIONFACTORAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationFactorAMD")) == NULL) || r;
+ r = ((glTessellationModeAMD = (PFNGLTESSELLATIONMODEAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationModeAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_vertex_shader_tessellator */
+
+#ifdef GL_ANGLE_framebuffer_blit
+
+static GLboolean _glewInit_GL_ANGLE_framebuffer_blit ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlitFramebufferANGLE = (PFNGLBLITFRAMEBUFFERANGLEPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_framebuffer_blit */
+
+#ifdef GL_ANGLE_framebuffer_multisample
+
+static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_framebuffer_multisample */
+
+#ifdef GL_ANGLE_instanced_arrays
+
+static GLboolean _glewInit_GL_ANGLE_instanced_arrays ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedANGLE")) == NULL) || r;
+ r = ((glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedANGLE")) == NULL) || r;
+ r = ((glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_instanced_arrays */
+
+#ifdef GL_ANGLE_timer_query
+
+static GLboolean _glewInit_GL_ANGLE_timer_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQueryANGLE = (PFNGLBEGINQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryANGLE")) == NULL) || r;
+ r = ((glDeleteQueriesANGLE = (PFNGLDELETEQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesANGLE")) == NULL) || r;
+ r = ((glEndQueryANGLE = (PFNGLENDQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glEndQueryANGLE")) == NULL) || r;
+ r = ((glGenQueriesANGLE = (PFNGLGENQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesANGLE")) == NULL) || r;
+ r = ((glGetQueryObjecti64vANGLE = (PFNGLGETQUERYOBJECTI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vANGLE")) == NULL) || r;
+ r = ((glGetQueryObjectivANGLE = (PFNGLGETQUERYOBJECTIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivANGLE")) == NULL) || r;
+ r = ((glGetQueryObjectui64vANGLE = (PFNGLGETQUERYOBJECTUI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vANGLE")) == NULL) || r;
+ r = ((glGetQueryObjectuivANGLE = (PFNGLGETQUERYOBJECTUIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivANGLE")) == NULL) || r;
+ r = ((glGetQueryivANGLE = (PFNGLGETQUERYIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivANGLE")) == NULL) || r;
+ r = ((glIsQueryANGLE = (PFNGLISQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glIsQueryANGLE")) == NULL) || r;
+ r = ((glQueryCounterANGLE = (PFNGLQUERYCOUNTERANGLEPROC)glewGetProcAddress((const GLubyte*)"glQueryCounterANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_timer_query */
+
+#ifdef GL_ANGLE_translated_shader_source
+
+static GLboolean _glewInit_GL_ANGLE_translated_shader_source ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTranslatedShaderSourceANGLE = (PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetTranslatedShaderSourceANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_translated_shader_source */
+
+#ifdef GL_APPLE_copy_texture_levels
+
+static GLboolean _glewInit_GL_APPLE_copy_texture_levels ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyTextureLevelsAPPLE = (PFNGLCOPYTEXTURELEVELSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureLevelsAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_copy_texture_levels */
+
+#ifdef GL_APPLE_element_array
+
+static GLboolean _glewInit_GL_APPLE_element_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayAPPLE")) == NULL) || r;
+ r = ((glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayAPPLE")) == NULL) || r;
+ r = ((glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glElementPointerAPPLE")) == NULL) || r;
+ r = ((glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementArrayAPPLE")) == NULL) || r;
+ r = ((glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawRangeElementArrayAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_element_array */
+
+#ifdef GL_APPLE_fence
+
+static GLboolean _glewInit_GL_APPLE_fence ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesAPPLE")) == NULL) || r;
+ r = ((glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceAPPLE")) == NULL) || r;
+ r = ((glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishObjectAPPLE")) == NULL) || r;
+ r = ((glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenFencesAPPLE")) == NULL) || r;
+ r = ((glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsFenceAPPLE")) == NULL) || r;
+ r = ((glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glSetFenceAPPLE")) == NULL) || r;
+ r = ((glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestFenceAPPLE")) == NULL) || r;
+ r = ((glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestObjectAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_fence */
+
+#ifdef GL_APPLE_flush_buffer_range
+
+static GLboolean _glewInit_GL_APPLE_flush_buffer_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferParameteriAPPLE = (PFNGLBUFFERPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBufferParameteriAPPLE")) == NULL) || r;
+ r = ((glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_flush_buffer_range */
+
+#ifdef GL_APPLE_framebuffer_multisample
+
+static GLboolean _glewInit_GL_APPLE_framebuffer_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleAPPLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleAPPLE")) == NULL) || r;
+ r = ((glResolveMultisampleFramebufferAPPLE = (PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glResolveMultisampleFramebufferAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_framebuffer_multisample */
+
+#ifdef GL_APPLE_object_purgeable
+
+static GLboolean _glewInit_GL_APPLE_object_purgeable ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetObjectParameterivAPPLE = (PFNGLGETOBJECTPARAMETERIVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivAPPLE")) == NULL) || r;
+ r = ((glObjectPurgeableAPPLE = (PFNGLOBJECTPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectPurgeableAPPLE")) == NULL) || r;
+ r = ((glObjectUnpurgeableAPPLE = (PFNGLOBJECTUNPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectUnpurgeableAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_object_purgeable */
+
+#ifdef GL_APPLE_sync
+
+static GLboolean _glewInit_GL_APPLE_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClientWaitSyncAPPLE = (PFNGLCLIENTWAITSYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glClientWaitSyncAPPLE")) == NULL) || r;
+ r = ((glDeleteSyncAPPLE = (PFNGLDELETESYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteSyncAPPLE")) == NULL) || r;
+ r = ((glFenceSyncAPPLE = (PFNGLFENCESYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFenceSyncAPPLE")) == NULL) || r;
+ r = ((glGetInteger64vAPPLE = (PFNGLGETINTEGER64VAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64vAPPLE")) == NULL) || r;
+ r = ((glGetSyncivAPPLE = (PFNGLGETSYNCIVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetSyncivAPPLE")) == NULL) || r;
+ r = ((glIsSyncAPPLE = (PFNGLISSYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsSyncAPPLE")) == NULL) || r;
+ r = ((glWaitSyncAPPLE = (PFNGLWAITSYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glWaitSyncAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_sync */
+
+#ifdef GL_APPLE_texture_range
+
+static GLboolean _glewInit_GL_APPLE_texture_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterPointervAPPLE")) == NULL) || r;
+ r = ((glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureRangeAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_texture_range */
+
+#ifdef GL_APPLE_vertex_array_object
+
+static GLboolean _glewInit_GL_APPLE_vertex_array_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArrayAPPLE")) == NULL) || r;
+ r = ((glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysAPPLE")) == NULL) || r;
+ r = ((glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysAPPLE")) == NULL) || r;
+ r = ((glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArrayAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_vertex_array_object */
+
+#ifdef GL_APPLE_vertex_array_range
+
+static GLboolean _glewInit_GL_APPLE_vertex_array_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeAPPLE")) == NULL) || r;
+ r = ((glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayParameteriAPPLE")) == NULL) || r;
+ r = ((glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_vertex_array_range */
+
+#ifdef GL_APPLE_vertex_program_evaluators
+
+static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDisableVertexAttribAPPLE = (PFNGLDISABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribAPPLE")) == NULL) || r;
+ r = ((glEnableVertexAttribAPPLE = (PFNGLENABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribAPPLE")) == NULL) || r;
+ r = ((glIsVertexAttribEnabledAPPLE = (PFNGLISVERTEXATTRIBENABLEDAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexAttribEnabledAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib1dAPPLE = (PFNGLMAPVERTEXATTRIB1DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1dAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib1fAPPLE = (PFNGLMAPVERTEXATTRIB1FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1fAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib2dAPPLE = (PFNGLMAPVERTEXATTRIB2DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2dAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib2fAPPLE = (PFNGLMAPVERTEXATTRIB2FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2fAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_vertex_program_evaluators */
+
+#ifdef GL_ARB_ES2_compatibility
+
+static GLboolean _glewInit_GL_ARB_ES2_compatibility ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearDepthf = (PFNGLCLEARDEPTHFPROC)glewGetProcAddress((const GLubyte*)"glClearDepthf")) == NULL) || r;
+ r = ((glDepthRangef = (PFNGLDEPTHRANGEFPROC)glewGetProcAddress((const GLubyte*)"glDepthRangef")) == NULL) || r;
+ r = ((glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)glewGetProcAddress((const GLubyte*)"glGetShaderPrecisionFormat")) == NULL) || r;
+ r = ((glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)glewGetProcAddress((const GLubyte*)"glReleaseShaderCompiler")) == NULL) || r;
+ r = ((glShaderBinary = (PFNGLSHADERBINARYPROC)glewGetProcAddress((const GLubyte*)"glShaderBinary")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_ES2_compatibility */
+
+#ifdef GL_ARB_ES3_1_compatibility
+
+static GLboolean _glewInit_GL_ARB_ES3_1_compatibility ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrierByRegion")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_ES3_1_compatibility */
+
+#ifdef GL_ARB_ES3_2_compatibility
+
+static GLboolean _glewInit_GL_ARB_ES3_2_compatibility ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPrimitiveBoundingBoxARB = (PFNGLPRIMITIVEBOUNDINGBOXARBPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveBoundingBoxARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_ES3_2_compatibility */
+
+#ifdef GL_ARB_base_instance
+
+static GLboolean _glewInit_GL_ARB_base_instance ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedBaseInstance")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseInstance")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexBaseInstance")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_base_instance */
+
+#ifdef GL_ARB_bindless_texture
+
+static GLboolean _glewInit_GL_ARB_bindless_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetImageHandleARB = (PFNGLGETIMAGEHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleARB")) == NULL) || r;
+ r = ((glGetTextureHandleARB = (PFNGLGETTEXTUREHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleARB")) == NULL) || r;
+ r = ((glGetTextureSamplerHandleARB = (PFNGLGETTEXTURESAMPLERHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleARB")) == NULL) || r;
+ r = ((glGetVertexAttribLui64vARB = (PFNGLGETVERTEXATTRIBLUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vARB")) == NULL) || r;
+ r = ((glIsImageHandleResidentARB = (PFNGLISIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentARB")) == NULL) || r;
+ r = ((glIsTextureHandleResidentARB = (PFNGLISTEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentARB")) == NULL) || r;
+ r = ((glMakeImageHandleNonResidentARB = (PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentARB")) == NULL) || r;
+ r = ((glMakeImageHandleResidentARB = (PFNGLMAKEIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentARB")) == NULL) || r;
+ r = ((glMakeTextureHandleNonResidentARB = (PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentARB")) == NULL) || r;
+ r = ((glMakeTextureHandleResidentARB = (PFNGLMAKETEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentARB")) == NULL) || r;
+ r = ((glProgramUniformHandleui64ARB = (PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64ARB")) == NULL) || r;
+ r = ((glProgramUniformHandleui64vARB = (PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vARB")) == NULL) || r;
+ r = ((glUniformHandleui64ARB = (PFNGLUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64ARB")) == NULL) || r;
+ r = ((glUniformHandleui64vARB = (PFNGLUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vARB")) == NULL) || r;
+ r = ((glVertexAttribL1ui64ARB = (PFNGLVERTEXATTRIBL1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64ARB")) == NULL) || r;
+ r = ((glVertexAttribL1ui64vARB = (PFNGLVERTEXATTRIBL1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_bindless_texture */
+
+#ifdef GL_ARB_blend_func_extended
+
+static GLboolean _glewInit_GL_ARB_blend_func_extended ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationIndexed")) == NULL) || r;
+ r = ((glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataIndex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_blend_func_extended */
+
+#ifdef GL_ARB_buffer_storage
+
+static GLboolean _glewInit_GL_ARB_buffer_storage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferStorage = (PFNGLBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glBufferStorage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_buffer_storage */
+
+#ifdef GL_ARB_cl_event
+
+static GLboolean _glewInit_GL_ARB_cl_event ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCreateSyncFromCLeventARB = (PFNGLCREATESYNCFROMCLEVENTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateSyncFromCLeventARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_cl_event */
+
+#ifdef GL_ARB_clear_buffer_object
+
+static GLboolean _glewInit_GL_ARB_clear_buffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferData")) == NULL) || r;
+ r = ((glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferSubData")) == NULL) || r;
+ r = ((glClearNamedBufferDataEXT = (PFNGLCLEARNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferDataEXT")) == NULL) || r;
+ r = ((glClearNamedBufferSubDataEXT = (PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferSubDataEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_clear_buffer_object */
+
+#ifdef GL_ARB_clear_texture
+
+static GLboolean _glewInit_GL_ARB_clear_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexImage")) == NULL) || r;
+ r = ((glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexSubImage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_clear_texture */
+
+#ifdef GL_ARB_clip_control
+
+static GLboolean _glewInit_GL_ARB_clip_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClipControl = (PFNGLCLIPCONTROLPROC)glewGetProcAddress((const GLubyte*)"glClipControl")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_clip_control */
+
+#ifdef GL_ARB_color_buffer_float
+
+static GLboolean _glewInit_GL_ARB_color_buffer_float ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glewGetProcAddress((const GLubyte*)"glClampColorARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_color_buffer_float */
+
+#ifdef GL_ARB_compute_shader
+
+static GLboolean _glewInit_GL_ARB_compute_shader ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)glewGetProcAddress((const GLubyte*)"glDispatchCompute")) == NULL) || r;
+ r = ((glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeIndirect")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_compute_shader */
+
+#ifdef GL_ARB_compute_variable_group_size
+
+static GLboolean _glewInit_GL_ARB_compute_variable_group_size ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDispatchComputeGroupSizeARB = (PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeGroupSizeARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_compute_variable_group_size */
+
+#ifdef GL_ARB_copy_buffer
+
+static GLboolean _glewInit_GL_ARB_copy_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyBufferSubData")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_copy_buffer */
+
+#ifdef GL_ARB_copy_image
+
+static GLboolean _glewInit_GL_ARB_copy_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubData")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_copy_image */
+
+#ifdef GL_ARB_debug_output
+
+static GLboolean _glewInit_GL_ARB_debug_output ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackARB")) == NULL) || r;
+ r = ((glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControlARB")) == NULL) || r;
+ r = ((glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertARB")) == NULL) || r;
+ r = ((glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_debug_output */
+
+#ifdef GL_ARB_direct_state_access
+
+static GLboolean _glewInit_GL_ARB_direct_state_access ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnit")) == NULL) || r;
+ r = ((glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitNamedFramebuffer")) == NULL) || r;
+ r = ((glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatus")) == NULL) || r;
+ r = ((glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferData")) == NULL) || r;
+ r = ((glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferSubData")) == NULL) || r;
+ r = ((glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferfi")) == NULL) || r;
+ r = ((glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferfv")) == NULL) || r;
+ r = ((glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferiv")) == NULL) || r;
+ r = ((glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferuiv")) == NULL) || r;
+ r = ((glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1D")) == NULL) || r;
+ r = ((glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2D")) == NULL) || r;
+ r = ((glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3D")) == NULL) || r;
+ r = ((glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyNamedBufferSubData")) == NULL) || r;
+ r = ((glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1D")) == NULL) || r;
+ r = ((glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2D")) == NULL) || r;
+ r = ((glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3D")) == NULL) || r;
+ r = ((glCreateBuffers = (PFNGLCREATEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glCreateBuffers")) == NULL) || r;
+ r = ((glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glCreateFramebuffers")) == NULL) || r;
+ r = ((glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramPipelines")) == NULL) || r;
+ r = ((glCreateQueries = (PFNGLCREATEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glCreateQueries")) == NULL) || r;
+ r = ((glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glCreateRenderbuffers")) == NULL) || r;
+ r = ((glCreateSamplers = (PFNGLCREATESAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glCreateSamplers")) == NULL) || r;
+ r = ((glCreateTextures = (PFNGLCREATETEXTURESPROC)glewGetProcAddress((const GLubyte*)"glCreateTextures")) == NULL) || r;
+ r = ((glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glCreateTransformFeedbacks")) == NULL) || r;
+ r = ((glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glCreateVertexArrays")) == NULL) || r;
+ r = ((glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayAttrib")) == NULL) || r;
+ r = ((glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayAttrib")) == NULL) || r;
+ r = ((glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedNamedBufferRange")) == NULL) || r;
+ r = ((glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmap")) == NULL) || r;
+ r = ((glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImage")) == NULL) || r;
+ r = ((glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameteri64v")) == NULL) || r;
+ r = ((glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameteriv")) == NULL) || r;
+ r = ((glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointerv")) == NULL) || r;
+ r = ((glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubData")) == NULL) || r;
+ r = ((glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameteriv")) == NULL) || r;
+ r = ((glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameteriv")) == NULL) || r;
+ r = ((glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameteriv")) == NULL) || r;
+ r = ((glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjecti64v")) == NULL) || r;
+ r = ((glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjectiv")) == NULL) || r;
+ r = ((glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjectui64v")) == NULL) || r;
+ r = ((glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjectuiv")) == NULL) || r;
+ r = ((glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImage")) == NULL) || r;
+ r = ((glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfv")) == NULL) || r;
+ r = ((glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameteriv")) == NULL) || r;
+ r = ((glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIiv")) == NULL) || r;
+ r = ((glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuiv")) == NULL) || r;
+ r = ((glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfv")) == NULL) || r;
+ r = ((glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameteriv")) == NULL) || r;
+ r = ((glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbacki64_v")) == NULL) || r;
+ r = ((glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbacki_v")) == NULL) || r;
+ r = ((glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackiv")) == NULL) || r;
+ r = ((glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIndexed64iv")) == NULL) || r;
+ r = ((glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIndexediv")) == NULL) || r;
+ r = ((glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayiv")) == NULL) || r;
+ r = ((glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateNamedFramebufferData")) == NULL) || r;
+ r = ((glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateNamedFramebufferSubData")) == NULL) || r;
+ r = ((glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBuffer")) == NULL) || r;
+ r = ((glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferRange")) == NULL) || r;
+ r = ((glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferData")) == NULL) || r;
+ r = ((glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorage")) == NULL) || r;
+ r = ((glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubData")) == NULL) || r;
+ r = ((glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferDrawBuffer")) == NULL) || r;
+ r = ((glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferDrawBuffers")) == NULL) || r;
+ r = ((glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferParameteri")) == NULL) || r;
+ r = ((glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferReadBuffer")) == NULL) || r;
+ r = ((glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbuffer")) == NULL) || r;
+ r = ((glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture")) == NULL) || r;
+ r = ((glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayer")) == NULL) || r;
+ r = ((glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorage")) == NULL) || r;
+ r = ((glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisample")) == NULL) || r;
+ r = ((glTextureBuffer = (PFNGLTEXTUREBUFFERPROC)glewGetProcAddress((const GLubyte*)"glTextureBuffer")) == NULL) || r;
+ r = ((glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferRange")) == NULL) || r;
+ r = ((glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIiv")) == NULL) || r;
+ r = ((glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuiv")) == NULL) || r;
+ r = ((glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterf")) == NULL) || r;
+ r = ((glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfv")) == NULL) || r;
+ r = ((glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteri")) == NULL) || r;
+ r = ((glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriv")) == NULL) || r;
+ r = ((glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage1D")) == NULL) || r;
+ r = ((glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2D")) == NULL) || r;
+ r = ((glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DMultisample")) == NULL) || r;
+ r = ((glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3D")) == NULL) || r;
+ r = ((glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DMultisample")) == NULL) || r;
+ r = ((glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1D")) == NULL) || r;
+ r = ((glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2D")) == NULL) || r;
+ r = ((glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3D")) == NULL) || r;
+ r = ((glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackBufferBase")) == NULL) || r;
+ r = ((glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackBufferRange")) == NULL) || r;
+ r = ((glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBuffer")) == NULL) || r;
+ r = ((glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribBinding")) == NULL) || r;
+ r = ((glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribFormat")) == NULL) || r;
+ r = ((glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribIFormat")) == NULL) || r;
+ r = ((glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribLFormat")) == NULL) || r;
+ r = ((glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayBindingDivisor")) == NULL) || r;
+ r = ((glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayElementBuffer")) == NULL) || r;
+ r = ((glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexBuffer")) == NULL) || r;
+ r = ((glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexBuffers")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_direct_state_access */
+
+#ifdef GL_ARB_draw_buffers
+
+static GLboolean _glewInit_GL_ARB_draw_buffers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_buffers */
+
+#ifdef GL_ARB_draw_buffers_blend
+
+static GLboolean _glewInit_GL_ARB_draw_buffers_blend ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateiARB")) == NULL) || r;
+ r = ((glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationiARB")) == NULL) || r;
+ r = ((glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateiARB")) == NULL) || r;
+ r = ((glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFunciARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_buffers_blend */
+
+#ifdef GL_ARB_draw_elements_base_vertex
+
+static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsBaseVertex")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertex")) == NULL) || r;
+ r = ((glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsBaseVertex")) == NULL) || r;
+ r = ((glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsBaseVertex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_elements_base_vertex */
+
+#ifdef GL_ARB_draw_indirect
+
+static GLboolean _glewInit_GL_ARB_draw_indirect ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysIndirect")) == NULL) || r;
+ r = ((glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsIndirect")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_indirect */
+
+#ifdef GL_ARB_framebuffer_no_attachments
+
+static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glFramebufferParameteri")) == NULL) || r;
+ r = ((glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameteriv")) == NULL) || r;
+ r = ((glGetNamedFramebufferParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameterivEXT")) == NULL) || r;
+ r = ((glNamedFramebufferParameteriEXT = (PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferParameteriEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_framebuffer_no_attachments */
+
+#ifdef GL_ARB_framebuffer_object
+
+static GLboolean _glewInit_GL_ARB_framebuffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindFramebuffer")) == NULL) || r;
+ r = ((glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbuffer")) == NULL) || r;
+ r = ((glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebuffer")) == NULL) || r;
+ r = ((glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatus")) == NULL) || r;
+ r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r;
+ r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r;
+ r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r;
+ r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r;
+ r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r;
+ r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r;
+ r = ((glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayer")) == NULL) || r;
+ r = ((glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffers")) == NULL) || r;
+ r = ((glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffers")) == NULL) || r;
+ r = ((glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmap")) == NULL) || r;
+ r = ((glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameteriv")) == NULL) || r;
+ r = ((glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameteriv")) == NULL) || r;
+ r = ((glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsFramebuffer")) == NULL) || r;
+ r = ((glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbuffer")) == NULL) || r;
+ r = ((glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorage")) == NULL) || r;
+ r = ((glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisample")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_framebuffer_object */
+
+#ifdef GL_ARB_geometry_shader4
+
+static GLboolean _glewInit_GL_ARB_geometry_shader4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureARB")) == NULL) || r;
+ r = ((glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceARB")) == NULL) || r;
+ r = ((glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerARB")) == NULL) || r;
+ r = ((glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_geometry_shader4 */
+
+#ifdef GL_ARB_get_program_binary
+
+static GLboolean _glewInit_GL_ARB_get_program_binary ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glGetProgramBinary")) == NULL) || r;
+ r = ((glProgramBinary = (PFNGLPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glProgramBinary")) == NULL) || r;
+ r = ((glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteri")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_get_program_binary */
+
+#ifdef GL_ARB_get_texture_sub_image
+
+static GLboolean _glewInit_GL_ARB_get_texture_sub_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureSubImage")) == NULL) || r;
+ r = ((glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSubImage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_get_texture_sub_image */
+
+#ifdef GL_ARB_gl_spirv
+
+static GLboolean _glewInit_GL_ARB_gl_spirv ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSpecializeShaderARB = (PFNGLSPECIALIZESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glSpecializeShaderARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_gl_spirv */
+
+#ifdef GL_ARB_gpu_shader_fp64
+
+static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetUniformdv = (PFNGLGETUNIFORMDVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformdv")) == NULL) || r;
+ r = ((glUniform1d = (PFNGLUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glUniform1d")) == NULL) || r;
+ r = ((glUniform1dv = (PFNGLUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glUniform1dv")) == NULL) || r;
+ r = ((glUniform2d = (PFNGLUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glUniform2d")) == NULL) || r;
+ r = ((glUniform2dv = (PFNGLUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glUniform2dv")) == NULL) || r;
+ r = ((glUniform3d = (PFNGLUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glUniform3d")) == NULL) || r;
+ r = ((glUniform3dv = (PFNGLUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glUniform3dv")) == NULL) || r;
+ r = ((glUniform4d = (PFNGLUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glUniform4d")) == NULL) || r;
+ r = ((glUniform4dv = (PFNGLUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glUniform4dv")) == NULL) || r;
+ r = ((glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2dv")) == NULL) || r;
+ r = ((glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3dv")) == NULL) || r;
+ r = ((glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4dv")) == NULL) || r;
+ r = ((glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3dv")) == NULL) || r;
+ r = ((glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2dv")) == NULL) || r;
+ r = ((glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4dv")) == NULL) || r;
+ r = ((glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4dv")) == NULL) || r;
+ r = ((glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2dv")) == NULL) || r;
+ r = ((glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3dv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_gpu_shader_fp64 */
+
+#ifdef GL_ARB_gpu_shader_int64
+
+static GLboolean _glewInit_GL_ARB_gpu_shader_int64 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetUniformi64vARB = (PFNGLGETUNIFORMI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformi64vARB")) == NULL) || r;
+ r = ((glGetUniformui64vARB = (PFNGLGETUNIFORMUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformui64vARB")) == NULL) || r;
+ r = ((glGetnUniformi64vARB = (PFNGLGETNUNIFORMI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformi64vARB")) == NULL) || r;
+ r = ((glGetnUniformui64vARB = (PFNGLGETNUNIFORMUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformui64vARB")) == NULL) || r;
+ r = ((glProgramUniform1i64ARB = (PFNGLPROGRAMUNIFORM1I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64ARB")) == NULL) || r;
+ r = ((glProgramUniform1i64vARB = (PFNGLPROGRAMUNIFORM1I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64vARB")) == NULL) || r;
+ r = ((glProgramUniform1ui64ARB = (PFNGLPROGRAMUNIFORM1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64ARB")) == NULL) || r;
+ r = ((glProgramUniform1ui64vARB = (PFNGLPROGRAMUNIFORM1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64vARB")) == NULL) || r;
+ r = ((glProgramUniform2i64ARB = (PFNGLPROGRAMUNIFORM2I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64ARB")) == NULL) || r;
+ r = ((glProgramUniform2i64vARB = (PFNGLPROGRAMUNIFORM2I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64vARB")) == NULL) || r;
+ r = ((glProgramUniform2ui64ARB = (PFNGLPROGRAMUNIFORM2UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64ARB")) == NULL) || r;
+ r = ((glProgramUniform2ui64vARB = (PFNGLPROGRAMUNIFORM2UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64vARB")) == NULL) || r;
+ r = ((glProgramUniform3i64ARB = (PFNGLPROGRAMUNIFORM3I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64ARB")) == NULL) || r;
+ r = ((glProgramUniform3i64vARB = (PFNGLPROGRAMUNIFORM3I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64vARB")) == NULL) || r;
+ r = ((glProgramUniform3ui64ARB = (PFNGLPROGRAMUNIFORM3UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64ARB")) == NULL) || r;
+ r = ((glProgramUniform3ui64vARB = (PFNGLPROGRAMUNIFORM3UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64vARB")) == NULL) || r;
+ r = ((glProgramUniform4i64ARB = (PFNGLPROGRAMUNIFORM4I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64ARB")) == NULL) || r;
+ r = ((glProgramUniform4i64vARB = (PFNGLPROGRAMUNIFORM4I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64vARB")) == NULL) || r;
+ r = ((glProgramUniform4ui64ARB = (PFNGLPROGRAMUNIFORM4UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64ARB")) == NULL) || r;
+ r = ((glProgramUniform4ui64vARB = (PFNGLPROGRAMUNIFORM4UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64vARB")) == NULL) || r;
+ r = ((glUniform1i64ARB = (PFNGLUNIFORM1I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64ARB")) == NULL) || r;
+ r = ((glUniform1i64vARB = (PFNGLUNIFORM1I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64vARB")) == NULL) || r;
+ r = ((glUniform1ui64ARB = (PFNGLUNIFORM1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64ARB")) == NULL) || r;
+ r = ((glUniform1ui64vARB = (PFNGLUNIFORM1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64vARB")) == NULL) || r;
+ r = ((glUniform2i64ARB = (PFNGLUNIFORM2I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64ARB")) == NULL) || r;
+ r = ((glUniform2i64vARB = (PFNGLUNIFORM2I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64vARB")) == NULL) || r;
+ r = ((glUniform2ui64ARB = (PFNGLUNIFORM2UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64ARB")) == NULL) || r;
+ r = ((glUniform2ui64vARB = (PFNGLUNIFORM2UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64vARB")) == NULL) || r;
+ r = ((glUniform3i64ARB = (PFNGLUNIFORM3I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64ARB")) == NULL) || r;
+ r = ((glUniform3i64vARB = (PFNGLUNIFORM3I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64vARB")) == NULL) || r;
+ r = ((glUniform3ui64ARB = (PFNGLUNIFORM3UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64ARB")) == NULL) || r;
+ r = ((glUniform3ui64vARB = (PFNGLUNIFORM3UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64vARB")) == NULL) || r;
+ r = ((glUniform4i64ARB = (PFNGLUNIFORM4I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64ARB")) == NULL) || r;
+ r = ((glUniform4i64vARB = (PFNGLUNIFORM4I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64vARB")) == NULL) || r;
+ r = ((glUniform4ui64ARB = (PFNGLUNIFORM4UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64ARB")) == NULL) || r;
+ r = ((glUniform4ui64vARB = (PFNGLUNIFORM4UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64vARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_gpu_shader_int64 */
+
+#ifdef GL_ARB_imaging
+
+static GLboolean _glewInit_GL_ARB_imaging ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r;
+ r = ((glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorSubTable")) == NULL) || r;
+ r = ((glColorTable = (PFNGLCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorTable")) == NULL) || r;
+ r = ((glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfv")) == NULL) || r;
+ r = ((glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameteriv")) == NULL) || r;
+ r = ((glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1D")) == NULL) || r;
+ r = ((glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2D")) == NULL) || r;
+ r = ((glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterf")) == NULL) || r;
+ r = ((glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfv")) == NULL) || r;
+ r = ((glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteri")) == NULL) || r;
+ r = ((glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriv")) == NULL) || r;
+ r = ((glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTable")) == NULL) || r;
+ r = ((glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTable")) == NULL) || r;
+ r = ((glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1D")) == NULL) || r;
+ r = ((glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2D")) == NULL) || r;
+ r = ((glGetColorTable = (PFNGLGETCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glGetColorTable")) == NULL) || r;
+ r = ((glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfv")) == NULL) || r;
+ r = ((glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameteriv")) == NULL) || r;
+ r = ((glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilter")) == NULL) || r;
+ r = ((glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfv")) == NULL) || r;
+ r = ((glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameteriv")) == NULL) || r;
+ r = ((glGetHistogram = (PFNGLGETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glGetHistogram")) == NULL) || r;
+ r = ((glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfv")) == NULL) || r;
+ r = ((glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameteriv")) == NULL) || r;
+ r = ((glGetMinmax = (PFNGLGETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glGetMinmax")) == NULL) || r;
+ r = ((glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfv")) == NULL) || r;
+ r = ((glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameteriv")) == NULL) || r;
+ r = ((glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilter")) == NULL) || r;
+ r = ((glHistogram = (PFNGLHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glHistogram")) == NULL) || r;
+ r = ((glMinmax = (PFNGLMINMAXPROC)glewGetProcAddress((const GLubyte*)"glMinmax")) == NULL) || r;
+ r = ((glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glResetHistogram")) == NULL) || r;
+ r = ((glResetMinmax = (PFNGLRESETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glResetMinmax")) == NULL) || r;
+ r = ((glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_imaging */
+
+#ifdef GL_ARB_indirect_parameters
+
+static GLboolean _glewInit_GL_ARB_indirect_parameters ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectCountARB = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectCountARB")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectCountARB = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectCountARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_indirect_parameters */
+
+#ifdef GL_ARB_instanced_arrays
+
+static GLboolean _glewInit_GL_ARB_instanced_arrays ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedARB")) == NULL) || r;
+ r = ((glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedARB")) == NULL) || r;
+ r = ((glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_instanced_arrays */
+
+#ifdef GL_ARB_internalformat_query
+
+static GLboolean _glewInit_GL_ARB_internalformat_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformativ")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_internalformat_query */
+
+#ifdef GL_ARB_internalformat_query2
+
+static GLboolean _glewInit_GL_ARB_internalformat_query2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformati64v")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_internalformat_query2 */
+
+#ifdef GL_ARB_invalidate_subdata
+
+static GLboolean _glewInit_GL_ARB_invalidate_subdata ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferData")) == NULL) || r;
+ r = ((glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferSubData")) == NULL) || r;
+ r = ((glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateFramebuffer")) == NULL) || r;
+ r = ((glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateSubFramebuffer")) == NULL) || r;
+ r = ((glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexImage")) == NULL) || r;
+ r = ((glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexSubImage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_invalidate_subdata */
+
+#ifdef GL_ARB_map_buffer_range
+
+static GLboolean _glewInit_GL_ARB_map_buffer_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRange")) == NULL) || r;
+ r = ((glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRange")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_map_buffer_range */
+
+#ifdef GL_ARB_matrix_palette
+
+static GLboolean _glewInit_GL_ARB_matrix_palette ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC)glewGetProcAddress((const GLubyte*)"glCurrentPaletteMatrixARB")) == NULL) || r;
+ r = ((glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexPointerARB")) == NULL) || r;
+ r = ((glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexubvARB")) == NULL) || r;
+ r = ((glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexuivARB")) == NULL) || r;
+ r = ((glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexusvARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_matrix_palette */
+
+#ifdef GL_ARB_multi_bind
+
+static GLboolean _glewInit_GL_ARB_multi_bind ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersBase")) == NULL) || r;
+ r = ((glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersRange")) == NULL) || r;
+ r = ((glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextures")) == NULL) || r;
+ r = ((glBindSamplers = (PFNGLBINDSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glBindSamplers")) == NULL) || r;
+ r = ((glBindTextures = (PFNGLBINDTEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindTextures")) == NULL) || r;
+ r = ((glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffers")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multi_bind */
+
+#ifdef GL_ARB_multi_draw_indirect
+
+static GLboolean _glewInit_GL_ARB_multi_draw_indirect ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirect")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirect")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multi_draw_indirect */
+
+#ifdef GL_ARB_multisample
+
+static GLboolean _glewInit_GL_ARB_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverageARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multisample */
+
+#ifdef GL_ARB_multitexture
+
+static GLboolean _glewInit_GL_ARB_multitexture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glActiveTextureARB")) == NULL) || r;
+ r = ((glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTextureARB")) == NULL) || r;
+ r = ((glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dARB")) == NULL) || r;
+ r = ((glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fARB")) == NULL) || r;
+ r = ((glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iARB")) == NULL) || r;
+ r = ((glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sARB")) == NULL) || r;
+ r = ((glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1svARB")) == NULL) || r;
+ r = ((glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dARB")) == NULL) || r;
+ r = ((glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fARB")) == NULL) || r;
+ r = ((glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iARB")) == NULL) || r;
+ r = ((glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sARB")) == NULL) || r;
+ r = ((glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2svARB")) == NULL) || r;
+ r = ((glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dARB")) == NULL) || r;
+ r = ((glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fARB")) == NULL) || r;
+ r = ((glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iARB")) == NULL) || r;
+ r = ((glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sARB")) == NULL) || r;
+ r = ((glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3svARB")) == NULL) || r;
+ r = ((glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dARB")) == NULL) || r;
+ r = ((glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fARB")) == NULL) || r;
+ r = ((glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iARB")) == NULL) || r;
+ r = ((glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sARB")) == NULL) || r;
+ r = ((glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4svARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multitexture */
+
+#ifdef GL_ARB_occlusion_query
+
+static GLboolean _glewInit_GL_ARB_occlusion_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryARB")) == NULL) || r;
+ r = ((glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesARB")) == NULL) || r;
+ r = ((glEndQueryARB = (PFNGLENDQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glEndQueryARB")) == NULL) || r;
+ r = ((glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesARB")) == NULL) || r;
+ r = ((glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivARB")) == NULL) || r;
+ r = ((glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivARB")) == NULL) || r;
+ r = ((glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivARB")) == NULL) || r;
+ r = ((glIsQueryARB = (PFNGLISQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glIsQueryARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_occlusion_query */
+
+#ifdef GL_ARB_parallel_shader_compile
+
+static GLboolean _glewInit_GL_ARB_parallel_shader_compile ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMaxShaderCompilerThreadsARB = (PFNGLMAXSHADERCOMPILERTHREADSARBPROC)glewGetProcAddress((const GLubyte*)"glMaxShaderCompilerThreadsARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_parallel_shader_compile */
+
+#ifdef GL_ARB_point_parameters
+
+static GLboolean _glewInit_GL_ARB_point_parameters ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfARB")) == NULL) || r;
+ r = ((glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_point_parameters */
+
+#ifdef GL_ARB_polygon_offset_clamp
+
+static GLboolean _glewInit_GL_ARB_polygon_offset_clamp ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetClamp")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_polygon_offset_clamp */
+
+#ifdef GL_ARB_program_interface_query
+
+static GLboolean _glewInit_GL_ARB_program_interface_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInterfaceiv")) == NULL) || r;
+ r = ((glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceIndex")) == NULL) || r;
+ r = ((glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocation")) == NULL) || r;
+ r = ((glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocationIndex")) == NULL) || r;
+ r = ((glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceName")) == NULL) || r;
+ r = ((glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_program_interface_query */
+
+#ifdef GL_ARB_provoking_vertex
+
+static GLboolean _glewInit_GL_ARB_provoking_vertex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_provoking_vertex */
+
+#ifdef GL_ARB_robustness
+
+static GLboolean _glewInit_GL_ARB_robustness ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC)glewGetProcAddress((const GLubyte*)"glGetGraphicsResetStatusARB")) == NULL) || r;
+ r = ((glGetnColorTableARB = (PFNGLGETNCOLORTABLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnColorTableARB")) == NULL) || r;
+ r = ((glGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnCompressedTexImageARB")) == NULL) || r;
+ r = ((glGetnConvolutionFilterARB = (PFNGLGETNCONVOLUTIONFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnConvolutionFilterARB")) == NULL) || r;
+ r = ((glGetnHistogramARB = (PFNGLGETNHISTOGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glGetnHistogramARB")) == NULL) || r;
+ r = ((glGetnMapdvARB = (PFNGLGETNMAPDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapdvARB")) == NULL) || r;
+ r = ((glGetnMapfvARB = (PFNGLGETNMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapfvARB")) == NULL) || r;
+ r = ((glGetnMapivARB = (PFNGLGETNMAPIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapivARB")) == NULL) || r;
+ r = ((glGetnMinmaxARB = (PFNGLGETNMINMAXARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMinmaxARB")) == NULL) || r;
+ r = ((glGetnPixelMapfvARB = (PFNGLGETNPIXELMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapfvARB")) == NULL) || r;
+ r = ((glGetnPixelMapuivARB = (PFNGLGETNPIXELMAPUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapuivARB")) == NULL) || r;
+ r = ((glGetnPixelMapusvARB = (PFNGLGETNPIXELMAPUSVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapusvARB")) == NULL) || r;
+ r = ((glGetnPolygonStippleARB = (PFNGLGETNPOLYGONSTIPPLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPolygonStippleARB")) == NULL) || r;
+ r = ((glGetnSeparableFilterARB = (PFNGLGETNSEPARABLEFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnSeparableFilterARB")) == NULL) || r;
+ r = ((glGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnTexImageARB")) == NULL) || r;
+ r = ((glGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformdvARB")) == NULL) || r;
+ r = ((glGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformfvARB")) == NULL) || r;
+ r = ((glGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformivARB")) == NULL) || r;
+ r = ((glGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformuivARB")) == NULL) || r;
+ r = ((glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)glewGetProcAddress((const GLubyte*)"glReadnPixelsARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_robustness */
+
+#ifdef GL_ARB_sample_locations
+
+static GLboolean _glewInit_GL_ARB_sample_locations ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferSampleLocationsfvARB = (PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferSampleLocationsfvARB")) == NULL) || r;
+ r = ((glNamedFramebufferSampleLocationsfvARB = (PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferSampleLocationsfvARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sample_locations */
+
+#ifdef GL_ARB_sample_shading
+
+static GLboolean _glewInit_GL_ARB_sample_shading ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShadingARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sample_shading */
+
+#ifdef GL_ARB_sampler_objects
+
+static GLboolean _glewInit_GL_ARB_sampler_objects ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindSampler = (PFNGLBINDSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glBindSampler")) == NULL) || r;
+ r = ((glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteSamplers")) == NULL) || r;
+ r = ((glGenSamplers = (PFNGLGENSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glGenSamplers")) == NULL) || r;
+ r = ((glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIiv")) == NULL) || r;
+ r = ((glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIuiv")) == NULL) || r;
+ r = ((glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterfv")) == NULL) || r;
+ r = ((glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameteriv")) == NULL) || r;
+ r = ((glIsSampler = (PFNGLISSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glIsSampler")) == NULL) || r;
+ r = ((glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIiv")) == NULL) || r;
+ r = ((glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIuiv")) == NULL) || r;
+ r = ((glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterf")) == NULL) || r;
+ r = ((glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterfv")) == NULL) || r;
+ r = ((glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteri")) == NULL) || r;
+ r = ((glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteriv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sampler_objects */
+
+#ifdef GL_ARB_separate_shader_objects
+
+static GLboolean _glewInit_GL_ARB_separate_shader_objects ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glActiveShaderProgram")) == NULL) || r;
+ r = ((glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glBindProgramPipeline")) == NULL) || r;
+ r = ((glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramv")) == NULL) || r;
+ r = ((glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramPipelines")) == NULL) || r;
+ r = ((glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glGenProgramPipelines")) == NULL) || r;
+ r = ((glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineInfoLog")) == NULL) || r;
+ r = ((glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineiv")) == NULL) || r;
+ r = ((glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glIsProgramPipeline")) == NULL) || r;
+ r = ((glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1d")) == NULL) || r;
+ r = ((glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1dv")) == NULL) || r;
+ r = ((glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1f")) == NULL) || r;
+ r = ((glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fv")) == NULL) || r;
+ r = ((glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i")) == NULL) || r;
+ r = ((glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iv")) == NULL) || r;
+ r = ((glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui")) == NULL) || r;
+ r = ((glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiv")) == NULL) || r;
+ r = ((glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2d")) == NULL) || r;
+ r = ((glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2dv")) == NULL) || r;
+ r = ((glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2f")) == NULL) || r;
+ r = ((glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fv")) == NULL) || r;
+ r = ((glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i")) == NULL) || r;
+ r = ((glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iv")) == NULL) || r;
+ r = ((glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui")) == NULL) || r;
+ r = ((glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiv")) == NULL) || r;
+ r = ((glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3d")) == NULL) || r;
+ r = ((glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3dv")) == NULL) || r;
+ r = ((glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3f")) == NULL) || r;
+ r = ((glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fv")) == NULL) || r;
+ r = ((glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i")) == NULL) || r;
+ r = ((glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iv")) == NULL) || r;
+ r = ((glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui")) == NULL) || r;
+ r = ((glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiv")) == NULL) || r;
+ r = ((glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4d")) == NULL) || r;
+ r = ((glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4dv")) == NULL) || r;
+ r = ((glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4f")) == NULL) || r;
+ r = ((glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fv")) == NULL) || r;
+ r = ((glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i")) == NULL) || r;
+ r = ((glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iv")) == NULL) || r;
+ r = ((glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui")) == NULL) || r;
+ r = ((glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fv")) == NULL) || r;
+ r = ((glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)glewGetProcAddress((const GLubyte*)"glUseProgramStages")) == NULL) || r;
+ r = ((glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramPipeline")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_separate_shader_objects */
+
+#ifdef GL_ARB_shader_atomic_counters
+
+static GLboolean _glewInit_GL_ARB_shader_atomic_counters ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAtomicCounterBufferiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_atomic_counters */
+
+#ifdef GL_ARB_shader_image_load_store
+
+static GLboolean _glewInit_GL_ARB_shader_image_load_store ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glBindImageTexture")) == NULL) || r;
+ r = ((glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrier")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_image_load_store */
+
+#ifdef GL_ARB_shader_objects
+
+static GLboolean _glewInit_GL_ARB_shader_objects ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glAttachObjectARB")) == NULL) || r;
+ r = ((glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderARB")) == NULL) || r;
+ r = ((glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramObjectARB")) == NULL) || r;
+ r = ((glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderObjectARB")) == NULL) || r;
+ r = ((glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteObjectARB")) == NULL) || r;
+ r = ((glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDetachObjectARB")) == NULL) || r;
+ r = ((glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformARB")) == NULL) || r;
+ r = ((glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedObjectsARB")) == NULL) || r;
+ r = ((glGetHandleARB = (PFNGLGETHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetHandleARB")) == NULL) || r;
+ r = ((glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetInfoLogARB")) == NULL) || r;
+ r = ((glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterfvARB")) == NULL) || r;
+ r = ((glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivARB")) == NULL) || r;
+ r = ((glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSourceARB")) == NULL) || r;
+ r = ((glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocationARB")) == NULL) || r;
+ r = ((glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfvARB")) == NULL) || r;
+ r = ((glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformivARB")) == NULL) || r;
+ r = ((glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glLinkProgramARB")) == NULL) || r;
+ r = ((glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glShaderSourceARB")) == NULL) || r;
+ r = ((glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fARB")) == NULL) || r;
+ r = ((glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fvARB")) == NULL) || r;
+ r = ((glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1iARB")) == NULL) || r;
+ r = ((glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ivARB")) == NULL) || r;
+ r = ((glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fARB")) == NULL) || r;
+ r = ((glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fvARB")) == NULL) || r;
+ r = ((glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2iARB")) == NULL) || r;
+ r = ((glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ivARB")) == NULL) || r;
+ r = ((glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fARB")) == NULL) || r;
+ r = ((glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fvARB")) == NULL) || r;
+ r = ((glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3iARB")) == NULL) || r;
+ r = ((glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ivARB")) == NULL) || r;
+ r = ((glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fARB")) == NULL) || r;
+ r = ((glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fvARB")) == NULL) || r;
+ r = ((glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4iARB")) == NULL) || r;
+ r = ((glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ivARB")) == NULL) || r;
+ r = ((glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fvARB")) == NULL) || r;
+ r = ((glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fvARB")) == NULL) || r;
+ r = ((glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fvARB")) == NULL) || r;
+ r = ((glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glUseProgramObjectARB")) == NULL) || r;
+ r = ((glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_objects */
+
+#ifdef GL_ARB_shader_storage_buffer_object
+
+static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glShaderStorageBlockBinding")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_storage_buffer_object */
+
+#ifdef GL_ARB_shader_subroutine
+
+static GLboolean _glewInit_GL_ARB_shader_subroutine ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineName")) == NULL) || r;
+ r = ((glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformName")) == NULL) || r;
+ r = ((glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformiv")) == NULL) || r;
+ r = ((glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStageiv")) == NULL) || r;
+ r = ((glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineIndex")) == NULL) || r;
+ r = ((glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineUniformLocation")) == NULL) || r;
+ r = ((glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformSubroutineuiv")) == NULL) || r;
+ r = ((glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)glewGetProcAddress((const GLubyte*)"glUniformSubroutinesuiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_subroutine */
+
+#ifdef GL_ARB_shading_language_include
+
+static GLboolean _glewInit_GL_ARB_shading_language_include ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCompileShaderIncludeARB = (PFNGLCOMPILESHADERINCLUDEARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderIncludeARB")) == NULL) || r;
+ r = ((glDeleteNamedStringARB = (PFNGLDELETENAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamedStringARB")) == NULL) || r;
+ r = ((glGetNamedStringARB = (PFNGLGETNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringARB")) == NULL) || r;
+ r = ((glGetNamedStringivARB = (PFNGLGETNAMEDSTRINGIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringivARB")) == NULL) || r;
+ r = ((glIsNamedStringARB = (PFNGLISNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glIsNamedStringARB")) == NULL) || r;
+ r = ((glNamedStringARB = (PFNGLNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glNamedStringARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shading_language_include */
+
+#ifdef GL_ARB_sparse_buffer
+
+static GLboolean _glewInit_GL_ARB_sparse_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferPageCommitmentARB = (PFNGLBUFFERPAGECOMMITMENTARBPROC)glewGetProcAddress((const GLubyte*)"glBufferPageCommitmentARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sparse_buffer */
+
+#ifdef GL_ARB_sparse_texture
+
+static GLboolean _glewInit_GL_ARB_sparse_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexPageCommitmentARB = (PFNGLTEXPAGECOMMITMENTARBPROC)glewGetProcAddress((const GLubyte*)"glTexPageCommitmentARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sparse_texture */
+
+#ifdef GL_ARB_sync
+
+static GLboolean _glewInit_GL_ARB_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glClientWaitSync")) == NULL) || r;
+ r = ((glDeleteSync = (PFNGLDELETESYNCPROC)glewGetProcAddress((const GLubyte*)"glDeleteSync")) == NULL) || r;
+ r = ((glFenceSync = (PFNGLFENCESYNCPROC)glewGetProcAddress((const GLubyte*)"glFenceSync")) == NULL) || r;
+ r = ((glGetInteger64v = (PFNGLGETINTEGER64VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64v")) == NULL) || r;
+ r = ((glGetSynciv = (PFNGLGETSYNCIVPROC)glewGetProcAddress((const GLubyte*)"glGetSynciv")) == NULL) || r;
+ r = ((glIsSync = (PFNGLISSYNCPROC)glewGetProcAddress((const GLubyte*)"glIsSync")) == NULL) || r;
+ r = ((glWaitSync = (PFNGLWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glWaitSync")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sync */
+
+#ifdef GL_ARB_tessellation_shader
+
+static GLboolean _glewInit_GL_ARB_tessellation_shader ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPatchParameterfv")) == NULL) || r;
+ r = ((glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPatchParameteri")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_tessellation_shader */
+
+#ifdef GL_ARB_texture_barrier
+
+static GLboolean _glewInit_GL_ARB_texture_barrier ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureBarrier = (PFNGLTEXTUREBARRIERPROC)glewGetProcAddress((const GLubyte*)"glTextureBarrier")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_barrier */
+
+#ifdef GL_ARB_texture_buffer_object
+
+static GLboolean _glewInit_GL_ARB_texture_buffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glTexBufferARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_buffer_object */
+
+#ifdef GL_ARB_texture_buffer_range
+
+static GLboolean _glewInit_GL_ARB_texture_buffer_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTexBufferRange")) == NULL) || r;
+ r = ((glTextureBufferRangeEXT = (PFNGLTEXTUREBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferRangeEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_buffer_range */
+
+#ifdef GL_ARB_texture_compression
+
+static GLboolean _glewInit_GL_ARB_texture_compression ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1DARB")) == NULL) || r;
+ r = ((glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2DARB")) == NULL) || r;
+ r = ((glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DARB")) == NULL) || r;
+ r = ((glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1DARB")) == NULL) || r;
+ r = ((glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2DARB")) == NULL) || r;
+ r = ((glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DARB")) == NULL) || r;
+ r = ((glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImageARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_compression */
+
+#ifdef GL_ARB_texture_multisample
+
+static GLboolean _glewInit_GL_ARB_texture_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefv")) == NULL) || r;
+ r = ((glSampleMaski = (PFNGLSAMPLEMASKIPROC)glewGetProcAddress((const GLubyte*)"glSampleMaski")) == NULL) || r;
+ r = ((glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisample")) == NULL) || r;
+ r = ((glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisample")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_multisample */
+
+#ifdef GL_ARB_texture_storage
+
+static GLboolean _glewInit_GL_ARB_texture_storage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage1D")) == NULL) || r;
+ r = ((glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2D")) == NULL) || r;
+ r = ((glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_storage */
+
+#ifdef GL_ARB_texture_storage_multisample
+
+static GLboolean _glewInit_GL_ARB_texture_storage_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2DMultisample")) == NULL) || r;
+ r = ((glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3DMultisample")) == NULL) || r;
+ r = ((glTextureStorage2DMultisampleEXT = (PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DMultisampleEXT")) == NULL) || r;
+ r = ((glTextureStorage3DMultisampleEXT = (PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DMultisampleEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_storage_multisample */
+
+#ifdef GL_ARB_texture_view
+
+static GLboolean _glewInit_GL_ARB_texture_view ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureView = (PFNGLTEXTUREVIEWPROC)glewGetProcAddress((const GLubyte*)"glTextureView")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_view */
+
+#ifdef GL_ARB_timer_query
+
+static GLboolean _glewInit_GL_ARB_timer_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64v")) == NULL) || r;
+ r = ((glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64v")) == NULL) || r;
+ r = ((glQueryCounter = (PFNGLQUERYCOUNTERPROC)glewGetProcAddress((const GLubyte*)"glQueryCounter")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_timer_query */
+
+#ifdef GL_ARB_transform_feedback2
+
+static GLboolean _glewInit_GL_ARB_transform_feedback2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedback")) == NULL) || r;
+ r = ((glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacks")) == NULL) || r;
+ r = ((glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedback")) == NULL) || r;
+ r = ((glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacks")) == NULL) || r;
+ r = ((glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedback")) == NULL) || r;
+ r = ((glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedback")) == NULL) || r;
+ r = ((glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedback")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transform_feedback2 */
+
+#ifdef GL_ARB_transform_feedback3
+
+static GLboolean _glewInit_GL_ARB_transform_feedback3 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryIndexed")) == NULL) || r;
+ r = ((glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStream")) == NULL) || r;
+ r = ((glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glEndQueryIndexed")) == NULL) || r;
+ r = ((glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryIndexediv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transform_feedback3 */
+
+#ifdef GL_ARB_transform_feedback_instanced
+
+static GLboolean _glewInit_GL_ARB_transform_feedback_instanced ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackInstanced")) == NULL) || r;
+ r = ((glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStreamInstanced")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transform_feedback_instanced */
+
+#ifdef GL_ARB_transpose_matrix
+
+static GLboolean _glewInit_GL_ARB_transpose_matrix ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixdARB")) == NULL) || r;
+ r = ((glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixfARB")) == NULL) || r;
+ r = ((glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixdARB")) == NULL) || r;
+ r = ((glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixfARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transpose_matrix */
+
+#ifdef GL_ARB_uniform_buffer_object
+
+static GLboolean _glewInit_GL_ARB_uniform_buffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r;
+ r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r;
+ r = ((glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockName")) == NULL) || r;
+ r = ((glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockiv")) == NULL) || r;
+ r = ((glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformName")) == NULL) || r;
+ r = ((glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformsiv")) == NULL) || r;
+ r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r;
+ r = ((glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBlockIndex")) == NULL) || r;
+ r = ((glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)glewGetProcAddress((const GLubyte*)"glGetUniformIndices")) == NULL) || r;
+ r = ((glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glUniformBlockBinding")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_uniform_buffer_object */
+
+#ifdef GL_ARB_vertex_array_object
+
+static GLboolean _glewInit_GL_ARB_vertex_array_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray")) == NULL) || r;
+ r = ((glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays")) == NULL) || r;
+ r = ((glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays")) == NULL) || r;
+ r = ((glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_array_object */
+
+#ifdef GL_ARB_vertex_attrib_64bit
+
+static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdv")) == NULL) || r;
+ r = ((glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1d")) == NULL) || r;
+ r = ((glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dv")) == NULL) || r;
+ r = ((glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2d")) == NULL) || r;
+ r = ((glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dv")) == NULL) || r;
+ r = ((glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3d")) == NULL) || r;
+ r = ((glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dv")) == NULL) || r;
+ r = ((glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4d")) == NULL) || r;
+ r = ((glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dv")) == NULL) || r;
+ r = ((glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_attrib_64bit */
+
+#ifdef GL_ARB_vertex_attrib_binding
+
+static GLboolean _glewInit_GL_ARB_vertex_attrib_binding ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffer")) == NULL) || r;
+ r = ((glVertexArrayBindVertexBufferEXT = (PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayBindVertexBufferEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribBindingEXT = (PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribBindingEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribFormatEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribIFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIFormatEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribLFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribLFormatEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexBindingDivisorEXT = (PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexBindingDivisorEXT")) == NULL) || r;
+ r = ((glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribBinding")) == NULL) || r;
+ r = ((glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormat")) == NULL) || r;
+ r = ((glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormat")) == NULL) || r;
+ r = ((glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormat")) == NULL) || r;
+ r = ((glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexBindingDivisor")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_attrib_binding */
+
+#ifdef GL_ARB_vertex_blend
+
+static GLboolean _glewInit_GL_ARB_vertex_blend ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendARB")) == NULL) || r;
+ r = ((glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glWeightPointerARB")) == NULL) || r;
+ r = ((glWeightbvARB = (PFNGLWEIGHTBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightbvARB")) == NULL) || r;
+ r = ((glWeightdvARB = (PFNGLWEIGHTDVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightdvARB")) == NULL) || r;
+ r = ((glWeightfvARB = (PFNGLWEIGHTFVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightfvARB")) == NULL) || r;
+ r = ((glWeightivARB = (PFNGLWEIGHTIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightivARB")) == NULL) || r;
+ r = ((glWeightsvARB = (PFNGLWEIGHTSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightsvARB")) == NULL) || r;
+ r = ((glWeightubvARB = (PFNGLWEIGHTUBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightubvARB")) == NULL) || r;
+ r = ((glWeightuivARB = (PFNGLWEIGHTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightuivARB")) == NULL) || r;
+ r = ((glWeightusvARB = (PFNGLWEIGHTUSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightusvARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_blend */
+
+#ifdef GL_ARB_vertex_buffer_object
+
+static GLboolean _glewInit_GL_ARB_vertex_buffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glBindBufferARB")) == NULL) || r;
+ r = ((glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferDataARB")) == NULL) || r;
+ r = ((glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferSubDataARB")) == NULL) || r;
+ r = ((glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffersARB")) == NULL) || r;
+ r = ((glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glGenBuffersARB")) == NULL) || r;
+ r = ((glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterivARB")) == NULL) || r;
+ r = ((glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointervARB")) == NULL) || r;
+ r = ((glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubDataARB")) == NULL) || r;
+ r = ((glIsBufferARB = (PFNGLISBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glIsBufferARB")) == NULL) || r;
+ r = ((glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glMapBufferARB")) == NULL) || r;
+ r = ((glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glUnmapBufferARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_buffer_object */
+
+#ifdef GL_ARB_vertex_program
+
+static GLboolean _glewInit_GL_ARB_vertex_program ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glBindProgramARB")) == NULL) || r;
+ r = ((glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsARB")) == NULL) || r;
+ r = ((glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArrayARB")) == NULL) || r;
+ r = ((glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArrayARB")) == NULL) || r;
+ r = ((glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsARB")) == NULL) || r;
+ r = ((glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterdvARB")) == NULL) || r;
+ r = ((glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterfvARB")) == NULL) || r;
+ r = ((glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterdvARB")) == NULL) || r;
+ r = ((glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterfvARB")) == NULL) || r;
+ r = ((glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringARB")) == NULL) || r;
+ r = ((glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivARB")) == NULL) || r;
+ r = ((glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervARB")) == NULL) || r;
+ r = ((glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvARB")) == NULL) || r;
+ r = ((glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvARB")) == NULL) || r;
+ r = ((glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivARB")) == NULL) || r;
+ r = ((glIsProgramARB = (PFNGLISPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glIsProgramARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dvARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fvARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dvARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fvARB")) == NULL) || r;
+ r = ((glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glProgramStringARB")) == NULL) || r;
+ r = ((glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dARB")) == NULL) || r;
+ r = ((glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvARB")) == NULL) || r;
+ r = ((glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fARB")) == NULL) || r;
+ r = ((glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvARB")) == NULL) || r;
+ r = ((glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sARB")) == NULL) || r;
+ r = ((glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svARB")) == NULL) || r;
+ r = ((glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dARB")) == NULL) || r;
+ r = ((glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvARB")) == NULL) || r;
+ r = ((glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fARB")) == NULL) || r;
+ r = ((glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvARB")) == NULL) || r;
+ r = ((glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sARB")) == NULL) || r;
+ r = ((glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svARB")) == NULL) || r;
+ r = ((glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dARB")) == NULL) || r;
+ r = ((glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvARB")) == NULL) || r;
+ r = ((glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fARB")) == NULL) || r;
+ r = ((glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvARB")) == NULL) || r;
+ r = ((glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sARB")) == NULL) || r;
+ r = ((glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svARB")) == NULL) || r;
+ r = ((glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NbvARB")) == NULL) || r;
+ r = ((glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NivARB")) == NULL) || r;
+ r = ((glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NsvARB")) == NULL) || r;
+ r = ((glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubARB")) == NULL) || r;
+ r = ((glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubvARB")) == NULL) || r;
+ r = ((glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NuivARB")) == NULL) || r;
+ r = ((glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NusvARB")) == NULL) || r;
+ r = ((glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bvARB")) == NULL) || r;
+ r = ((glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dARB")) == NULL) || r;
+ r = ((glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvARB")) == NULL) || r;
+ r = ((glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fARB")) == NULL) || r;
+ r = ((glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvARB")) == NULL) || r;
+ r = ((glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ivARB")) == NULL) || r;
+ r = ((glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sARB")) == NULL) || r;
+ r = ((glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svARB")) == NULL) || r;
+ r = ((glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvARB")) == NULL) || r;
+ r = ((glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uivARB")) == NULL) || r;
+ r = ((glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usvARB")) == NULL) || r;
+ r = ((glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_program */
+
+#ifdef GL_ARB_vertex_shader
+
+static GLboolean _glewInit_GL_ARB_vertex_shader ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocationARB")) == NULL) || r;
+ r = ((glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttribARB")) == NULL) || r;
+ r = ((glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocationARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_shader */
+
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+
+static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorP3ui = (PFNGLCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glColorP3ui")) == NULL) || r;
+ r = ((glColorP3uiv = (PFNGLCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP3uiv")) == NULL) || r;
+ r = ((glColorP4ui = (PFNGLCOLORP4UIPROC)glewGetProcAddress((const GLubyte*)"glColorP4ui")) == NULL) || r;
+ r = ((glColorP4uiv = (PFNGLCOLORP4UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP4uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1ui")) == NULL) || r;
+ r = ((glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2ui")) == NULL) || r;
+ r = ((glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3ui")) == NULL) || r;
+ r = ((glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4ui")) == NULL) || r;
+ r = ((glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4uiv")) == NULL) || r;
+ r = ((glNormalP3ui = (PFNGLNORMALP3UIPROC)glewGetProcAddress((const GLubyte*)"glNormalP3ui")) == NULL) || r;
+ r = ((glNormalP3uiv = (PFNGLNORMALP3UIVPROC)glewGetProcAddress((const GLubyte*)"glNormalP3uiv")) == NULL) || r;
+ r = ((glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3ui")) == NULL) || r;
+ r = ((glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3uiv")) == NULL) || r;
+ r = ((glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1ui")) == NULL) || r;
+ r = ((glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1uiv")) == NULL) || r;
+ r = ((glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2ui")) == NULL) || r;
+ r = ((glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2uiv")) == NULL) || r;
+ r = ((glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3ui")) == NULL) || r;
+ r = ((glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3uiv")) == NULL) || r;
+ r = ((glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4ui")) == NULL) || r;
+ r = ((glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4uiv")) == NULL) || r;
+ r = ((glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1ui")) == NULL) || r;
+ r = ((glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1uiv")) == NULL) || r;
+ r = ((glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2ui")) == NULL) || r;
+ r = ((glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2uiv")) == NULL) || r;
+ r = ((glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3ui")) == NULL) || r;
+ r = ((glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3uiv")) == NULL) || r;
+ r = ((glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4ui")) == NULL) || r;
+ r = ((glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4uiv")) == NULL) || r;
+ r = ((glVertexP2ui = (PFNGLVERTEXP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP2ui")) == NULL) || r;
+ r = ((glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP2uiv")) == NULL) || r;
+ r = ((glVertexP3ui = (PFNGLVERTEXP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP3ui")) == NULL) || r;
+ r = ((glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP3uiv")) == NULL) || r;
+ r = ((glVertexP4ui = (PFNGLVERTEXP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP4ui")) == NULL) || r;
+ r = ((glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP4uiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_type_2_10_10_10_rev */
+
+#ifdef GL_ARB_viewport_array
+
+static GLboolean _glewInit_GL_ARB_viewport_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeArrayv")) == NULL) || r;
+ r = ((glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeIndexed")) == NULL) || r;
+ r = ((glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_v")) == NULL) || r;
+ r = ((glGetFloati_v = (PFNGLGETFLOATI_VPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_v")) == NULL) || r;
+ r = ((glScissorArrayv = (PFNGLSCISSORARRAYVPROC)glewGetProcAddress((const GLubyte*)"glScissorArrayv")) == NULL) || r;
+ r = ((glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexed")) == NULL) || r;
+ r = ((glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedv")) == NULL) || r;
+ r = ((glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)glewGetProcAddress((const GLubyte*)"glViewportArrayv")) == NULL) || r;
+ r = ((glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedf")) == NULL) || r;
+ r = ((glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_viewport_array */
+
+#ifdef GL_ARB_window_pos
+
+static GLboolean _glewInit_GL_ARB_window_pos ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dARB")) == NULL) || r;
+ r = ((glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvARB")) == NULL) || r;
+ r = ((glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fARB")) == NULL) || r;
+ r = ((glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvARB")) == NULL) || r;
+ r = ((glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iARB")) == NULL) || r;
+ r = ((glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivARB")) == NULL) || r;
+ r = ((glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sARB")) == NULL) || r;
+ r = ((glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svARB")) == NULL) || r;
+ r = ((glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dARB")) == NULL) || r;
+ r = ((glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvARB")) == NULL) || r;
+ r = ((glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fARB")) == NULL) || r;
+ r = ((glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvARB")) == NULL) || r;
+ r = ((glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iARB")) == NULL) || r;
+ r = ((glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivARB")) == NULL) || r;
+ r = ((glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sARB")) == NULL) || r;
+ r = ((glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_window_pos */
+
+#ifdef GL_ATI_draw_buffers
+
+static GLboolean _glewInit_GL_ATI_draw_buffers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_draw_buffers */
+
+#ifdef GL_ATI_element_array
+
+static GLboolean _glewInit_GL_ATI_element_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayATI")) == NULL) || r;
+ r = ((glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayATI")) == NULL) || r;
+ r = ((glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC)glewGetProcAddress((const GLubyte*)"glElementPointerATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_element_array */
+
+#ifdef GL_ATI_envmap_bumpmap
+
+static GLboolean _glewInit_GL_ATI_envmap_bumpmap ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterfvATI")) == NULL) || r;
+ r = ((glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterivATI")) == NULL) || r;
+ r = ((glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterfvATI")) == NULL) || r;
+ r = ((glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterivATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_envmap_bumpmap */
+
+#ifdef GL_ATI_fragment_shader
+
+static GLboolean _glewInit_GL_ATI_fragment_shader ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp1ATI")) == NULL) || r;
+ r = ((glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp2ATI")) == NULL) || r;
+ r = ((glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp3ATI")) == NULL) || r;
+ r = ((glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBeginFragmentShaderATI")) == NULL) || r;
+ r = ((glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBindFragmentShaderATI")) == NULL) || r;
+ r = ((glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp1ATI")) == NULL) || r;
+ r = ((glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp2ATI")) == NULL) || r;
+ r = ((glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp3ATI")) == NULL) || r;
+ r = ((glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glDeleteFragmentShaderATI")) == NULL) || r;
+ r = ((glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glEndFragmentShaderATI")) == NULL) || r;
+ r = ((glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)glewGetProcAddress((const GLubyte*)"glGenFragmentShadersATI")) == NULL) || r;
+ r = ((glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)glewGetProcAddress((const GLubyte*)"glPassTexCoordATI")) == NULL) || r;
+ r = ((glSampleMapATI = (PFNGLSAMPLEMAPATIPROC)glewGetProcAddress((const GLubyte*)"glSampleMapATI")) == NULL) || r;
+ r = ((glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)glewGetProcAddress((const GLubyte*)"glSetFragmentShaderConstantATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_fragment_shader */
+
+#ifdef GL_ATI_map_object_buffer
+
+static GLboolean _glewInit_GL_ATI_map_object_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glMapObjectBufferATI")) == NULL) || r;
+ r = ((glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUnmapObjectBufferATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_map_object_buffer */
+
+#ifdef GL_ATI_pn_triangles
+
+static GLboolean _glewInit_GL_ATI_pn_triangles ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesfATI")) == NULL) || r;
+ r = ((glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesiATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_pn_triangles */
+
+#ifdef GL_ATI_separate_stencil
+
+static GLboolean _glewInit_GL_ATI_separate_stencil ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparateATI")) == NULL) || r;
+ r = ((glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparateATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_separate_stencil */
+
+#ifdef GL_ATI_vertex_array_object
+
+static GLboolean _glewInit_GL_ATI_vertex_array_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glArrayObjectATI")) == NULL) || r;
+ r = ((glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glFreeObjectBufferATI")) == NULL) || r;
+ r = ((glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectfvATI")) == NULL) || r;
+ r = ((glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectivATI")) == NULL) || r;
+ r = ((glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferfvATI")) == NULL) || r;
+ r = ((glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferivATI")) == NULL) || r;
+ r = ((glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectfvATI")) == NULL) || r;
+ r = ((glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectivATI")) == NULL) || r;
+ r = ((glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glIsObjectBufferATI")) == NULL) || r;
+ r = ((glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glNewObjectBufferATI")) == NULL) || r;
+ r = ((glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUpdateObjectBufferATI")) == NULL) || r;
+ r = ((glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVariantArrayObjectATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_vertex_array_object */
+
+#ifdef GL_ATI_vertex_attrib_array_object
+
+static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectfvATI")) == NULL) || r;
+ r = ((glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectivATI")) == NULL) || r;
+ r = ((glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribArrayObjectATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_vertex_attrib_array_object */
+
+#ifdef GL_ATI_vertex_streams
+
+static GLboolean _glewInit_GL_ATI_vertex_streams ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)glewGetProcAddress((const GLubyte*)"glClientActiveVertexStreamATI")) == NULL) || r;
+ r = ((glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bATI")) == NULL) || r;
+ r = ((glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bvATI")) == NULL) || r;
+ r = ((glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dATI")) == NULL) || r;
+ r = ((glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dvATI")) == NULL) || r;
+ r = ((glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fATI")) == NULL) || r;
+ r = ((glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fvATI")) == NULL) || r;
+ r = ((glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3iATI")) == NULL) || r;
+ r = ((glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3ivATI")) == NULL) || r;
+ r = ((glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3sATI")) == NULL) || r;
+ r = ((glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3svATI")) == NULL) || r;
+ r = ((glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnvfATI")) == NULL) || r;
+ r = ((glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnviATI")) == NULL) || r;
+ r = ((glVertexStream1dATI = (PFNGLVERTEXSTREAM1DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dATI")) == NULL) || r;
+ r = ((glVertexStream1dvATI = (PFNGLVERTEXSTREAM1DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dvATI")) == NULL) || r;
+ r = ((glVertexStream1fATI = (PFNGLVERTEXSTREAM1FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fATI")) == NULL) || r;
+ r = ((glVertexStream1fvATI = (PFNGLVERTEXSTREAM1FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fvATI")) == NULL) || r;
+ r = ((glVertexStream1iATI = (PFNGLVERTEXSTREAM1IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1iATI")) == NULL) || r;
+ r = ((glVertexStream1ivATI = (PFNGLVERTEXSTREAM1IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1ivATI")) == NULL) || r;
+ r = ((glVertexStream1sATI = (PFNGLVERTEXSTREAM1SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1sATI")) == NULL) || r;
+ r = ((glVertexStream1svATI = (PFNGLVERTEXSTREAM1SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1svATI")) == NULL) || r;
+ r = ((glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dATI")) == NULL) || r;
+ r = ((glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dvATI")) == NULL) || r;
+ r = ((glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fATI")) == NULL) || r;
+ r = ((glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fvATI")) == NULL) || r;
+ r = ((glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2iATI")) == NULL) || r;
+ r = ((glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2ivATI")) == NULL) || r;
+ r = ((glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2sATI")) == NULL) || r;
+ r = ((glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2svATI")) == NULL) || r;
+ r = ((glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dATI")) == NULL) || r;
+ r = ((glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dvATI")) == NULL) || r;
+ r = ((glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fATI")) == NULL) || r;
+ r = ((glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fvATI")) == NULL) || r;
+ r = ((glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3iATI")) == NULL) || r;
+ r = ((glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3ivATI")) == NULL) || r;
+ r = ((glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3sATI")) == NULL) || r;
+ r = ((glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3svATI")) == NULL) || r;
+ r = ((glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dATI")) == NULL) || r;
+ r = ((glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dvATI")) == NULL) || r;
+ r = ((glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fATI")) == NULL) || r;
+ r = ((glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fvATI")) == NULL) || r;
+ r = ((glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4iATI")) == NULL) || r;
+ r = ((glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4ivATI")) == NULL) || r;
+ r = ((glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4sATI")) == NULL) || r;
+ r = ((glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4svATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_vertex_streams */
+
+#ifdef GL_EXT_base_instance
+
+static GLboolean _glewInit_GL_EXT_base_instance ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedBaseInstanceEXT = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedBaseInstanceEXT")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseInstanceEXT")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseVertexBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexBaseInstanceEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_base_instance */
+
+#ifdef GL_EXT_bindable_uniform
+
+static GLboolean _glewInit_GL_EXT_bindable_uniform ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetUniformBufferSizeEXT = (PFNGLGETUNIFORMBUFFERSIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBufferSizeEXT")) == NULL) || r;
+ r = ((glGetUniformOffsetEXT = (PFNGLGETUNIFORMOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformOffsetEXT")) == NULL) || r;
+ r = ((glUniformBufferEXT = (PFNGLUNIFORMBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUniformBufferEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_bindable_uniform */
+
+#ifdef GL_EXT_blend_color
+
+static GLboolean _glewInit_GL_EXT_blend_color ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glewGetProcAddress((const GLubyte*)"glBlendColorEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_color */
+
+#ifdef GL_EXT_blend_equation_separate
+
+static GLboolean _glewInit_GL_EXT_blend_equation_separate ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_equation_separate */
+
+#ifdef GL_EXT_blend_func_extended
+
+static GLboolean _glewInit_GL_EXT_blend_func_extended ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFragDataLocationIndexedEXT = (PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationIndexedEXT")) == NULL) || r;
+ r = ((glGetFragDataIndexEXT = (PFNGLGETFRAGDATAINDEXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataIndexEXT")) == NULL) || r;
+ r = ((glGetProgramResourceLocationIndexEXT = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocationIndexEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_func_extended */
+
+#ifdef GL_EXT_blend_func_separate
+
+static GLboolean _glewInit_GL_EXT_blend_func_separate ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_func_separate */
+
+#ifdef GL_EXT_blend_minmax
+
+static GLboolean _glewInit_GL_EXT_blend_minmax ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_minmax */
+
+#ifdef GL_EXT_buffer_storage
+
+static GLboolean _glewInit_GL_EXT_buffer_storage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferStorageEXT = (PFNGLBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferStorageEXT")) == NULL) || r;
+ r = ((glNamedBufferStorageEXT = (PFNGLNAMEDBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_buffer_storage */
+
+#ifdef GL_EXT_clear_texture
+
+static GLboolean _glewInit_GL_EXT_clear_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearTexImageEXT = (PFNGLCLEARTEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glClearTexImageEXT")) == NULL) || r;
+ r = ((glClearTexSubImageEXT = (PFNGLCLEARTEXSUBIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glClearTexSubImageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_clear_texture */
+
+#ifdef GL_EXT_color_subtable
+
+static GLboolean _glewInit_GL_EXT_color_subtable ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorSubTableEXT")) == NULL) || r;
+ r = ((glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTableEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_color_subtable */
+
+#ifdef GL_EXT_compiled_vertex_array
+
+static GLboolean _glewInit_GL_EXT_compiled_vertex_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glLockArraysEXT")) == NULL) || r;
+ r = ((glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glUnlockArraysEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_compiled_vertex_array */
+
+#ifdef GL_EXT_convolution
+
+static GLboolean _glewInit_GL_EXT_convolution ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1DEXT")) == NULL) || r;
+ r = ((glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2DEXT")) == NULL) || r;
+ r = ((glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfEXT")) == NULL) || r;
+ r = ((glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfvEXT")) == NULL) || r;
+ r = ((glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriEXT")) == NULL) || r;
+ r = ((glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterivEXT")) == NULL) || r;
+ r = ((glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1DEXT")) == NULL) || r;
+ r = ((glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2DEXT")) == NULL) || r;
+ r = ((glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilterEXT")) == NULL) || r;
+ r = ((glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfvEXT")) == NULL) || r;
+ r = ((glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterivEXT")) == NULL) || r;
+ r = ((glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilterEXT")) == NULL) || r;
+ r = ((glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_convolution */
+
+#ifdef GL_EXT_coordinate_frame
+
+static GLboolean _glewInit_GL_EXT_coordinate_frame ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glBinormalPointerEXT")) == NULL) || r;
+ r = ((glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTangentPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_coordinate_frame */
+
+#ifdef GL_EXT_copy_image
+
+static GLboolean _glewInit_GL_EXT_copy_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyImageSubDataEXT = (PFNGLCOPYIMAGESUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubDataEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_copy_image */
+
+#ifdef GL_EXT_copy_texture
+
+static GLboolean _glewInit_GL_EXT_copy_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage1DEXT")) == NULL) || r;
+ r = ((glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage2DEXT")) == NULL) || r;
+ r = ((glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage1DEXT")) == NULL) || r;
+ r = ((glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage2DEXT")) == NULL) || r;
+ r = ((glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_copy_texture */
+
+#ifdef GL_EXT_cull_vertex
+
+static GLboolean _glewInit_GL_EXT_cull_vertex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterdvEXT")) == NULL) || r;
+ r = ((glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_cull_vertex */
+
+#ifdef GL_EXT_debug_label
+
+static GLboolean _glewInit_GL_EXT_debug_label ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC)glewGetProcAddress((const GLubyte*)"glGetObjectLabelEXT")) == NULL) || r;
+ r = ((glLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC)glewGetProcAddress((const GLubyte*)"glLabelObjectEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_debug_label */
+
+#ifdef GL_EXT_debug_marker
+
+static GLboolean _glewInit_GL_EXT_debug_marker ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glInsertEventMarkerEXT")) == NULL) || r;
+ r = ((glPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPopGroupMarkerEXT")) == NULL) || r;
+ r = ((glPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPushGroupMarkerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_debug_marker */
+
+#ifdef GL_EXT_depth_bounds_test
+
+static GLboolean _glewInit_GL_EXT_depth_bounds_test ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_depth_bounds_test */
+
+#ifdef GL_EXT_direct_state_access
+
+static GLboolean _glewInit_GL_EXT_direct_state_access ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindMultiTextureEXT")) == NULL) || r;
+ r = ((glCheckNamedFramebufferStatusEXT = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatusEXT")) == NULL) || r;
+ r = ((glClientAttribDefaultEXT = (PFNGLCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glClientAttribDefaultEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexImage1DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage1DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexImage2DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage2DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexImage3DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage3DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexSubImage1DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage1DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexSubImage2DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage2DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexSubImage3DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage3DEXT")) == NULL) || r;
+ r = ((glCompressedTextureImage1DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage1DEXT")) == NULL) || r;
+ r = ((glCompressedTextureImage2DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage2DEXT")) == NULL) || r;
+ r = ((glCompressedTextureImage3DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage3DEXT")) == NULL) || r;
+ r = ((glCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1DEXT")) == NULL) || r;
+ r = ((glCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2DEXT")) == NULL) || r;
+ r = ((glCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexImage1DEXT = (PFNGLCOPYMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage1DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexImage2DEXT = (PFNGLCOPYMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage2DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexSubImage1DEXT = (PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage1DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexSubImage2DEXT = (PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage2DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexSubImage3DEXT = (PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage3DEXT")) == NULL) || r;
+ r = ((glCopyTextureImage1DEXT = (PFNGLCOPYTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage1DEXT")) == NULL) || r;
+ r = ((glCopyTextureImage2DEXT = (PFNGLCOPYTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage2DEXT")) == NULL) || r;
+ r = ((glCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1DEXT")) == NULL) || r;
+ r = ((glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2DEXT")) == NULL) || r;
+ r = ((glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3DEXT")) == NULL) || r;
+ r = ((glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateIndexedEXT")) == NULL) || r;
+ r = ((glDisableClientStateiEXT = (PFNGLDISABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateiEXT")) == NULL) || r;
+ r = ((glDisableVertexArrayAttribEXT = (PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayAttribEXT")) == NULL) || r;
+ r = ((glDisableVertexArrayEXT = (PFNGLDISABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayEXT")) == NULL) || r;
+ r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r;
+ r = ((glEnableClientStateiEXT = (PFNGLENABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateiEXT")) == NULL) || r;
+ r = ((glEnableVertexArrayAttribEXT = (PFNGLENABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayAttribEXT")) == NULL) || r;
+ r = ((glEnableVertexArrayEXT = (PFNGLENABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayEXT")) == NULL) || r;
+ r = ((glFlushMappedNamedBufferRangeEXT = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedNamedBufferRangeEXT")) == NULL) || r;
+ r = ((glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBufferEXT")) == NULL) || r;
+ r = ((glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBuffersEXT")) == NULL) || r;
+ r = ((glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferReadBufferEXT")) == NULL) || r;
+ r = ((glGenerateMultiTexMipmapEXT = (PFNGLGENERATEMULTITEXMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMultiTexMipmapEXT")) == NULL) || r;
+ r = ((glGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmapEXT")) == NULL) || r;
+ r = ((glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedMultiTexImageEXT")) == NULL) || r;
+ r = ((glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImageEXT")) == NULL) || r;
+ r = ((glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoubleIndexedvEXT")) == NULL) || r;
+ r = ((glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_vEXT")) == NULL) || r;
+ r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r;
+ r = ((glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_vEXT")) == NULL) || r;
+ r = ((glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterivEXT")) == NULL) || r;
+ r = ((glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvivEXT")) == NULL) || r;
+ r = ((glGetMultiTexGendvEXT = (PFNGLGETMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGendvEXT")) == NULL) || r;
+ r = ((glGetMultiTexGenfvEXT = (PFNGLGETMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexGenivEXT = (PFNGLGETMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenivEXT")) == NULL) || r;
+ r = ((glGetMultiTexImageEXT = (PFNGLGETMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexImageEXT")) == NULL) || r;
+ r = ((glGetMultiTexLevelParameterfvEXT = (PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexLevelParameterivEXT = (PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterivEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterIivEXT = (PFNGLGETMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIivEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterIuivEXT = (PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIuivEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterfvEXT = (PFNGLGETMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterivEXT = (PFNGLGETMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterivEXT")) == NULL) || r;
+ r = ((glGetNamedBufferParameterivEXT = (PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterivEXT")) == NULL) || r;
+ r = ((glGetNamedBufferPointervEXT = (PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointervEXT")) == NULL) || r;
+ r = ((glGetNamedBufferSubDataEXT = (PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubDataEXT")) == NULL) || r;
+ r = ((glGetNamedFramebufferAttachmentParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameterivEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterIivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIivEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterIuivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIuivEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterdvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterdvEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterfvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterfvEXT")) == NULL) || r;
+ r = ((glGetNamedProgramStringEXT = (PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramStringEXT")) == NULL) || r;
+ r = ((glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramivEXT")) == NULL) || r;
+ r = ((glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameterivEXT")) == NULL) || r;
+ r = ((glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointerIndexedvEXT")) == NULL) || r;
+ r = ((glGetPointeri_vEXT = (PFNGLGETPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointeri_vEXT")) == NULL) || r;
+ r = ((glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImageEXT")) == NULL) || r;
+ r = ((glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfvEXT")) == NULL) || r;
+ r = ((glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterivEXT")) == NULL) || r;
+ r = ((glGetTextureParameterIivEXT = (PFNGLGETTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIivEXT")) == NULL) || r;
+ r = ((glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuivEXT")) == NULL) || r;
+ r = ((glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfvEXT")) == NULL) || r;
+ r = ((glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterivEXT")) == NULL) || r;
+ r = ((glGetVertexArrayIntegeri_vEXT = (PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegeri_vEXT")) == NULL) || r;
+ r = ((glGetVertexArrayIntegervEXT = (PFNGLGETVERTEXARRAYINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegervEXT")) == NULL) || r;
+ r = ((glGetVertexArrayPointeri_vEXT = (PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointeri_vEXT")) == NULL) || r;
+ r = ((glGetVertexArrayPointervEXT = (PFNGLGETVERTEXARRAYPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointervEXT")) == NULL) || r;
+ r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r;
+ r = ((glMapNamedBufferRangeEXT = (PFNGLMAPNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferRangeEXT")) == NULL) || r;
+ r = ((glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixFrustumEXT")) == NULL) || r;
+ r = ((glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadIdentityEXT")) == NULL) || r;
+ r = ((glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposedEXT")) == NULL) || r;
+ r = ((glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposefEXT")) == NULL) || r;
+ r = ((glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoaddEXT")) == NULL) || r;
+ r = ((glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadfEXT")) == NULL) || r;
+ r = ((glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposedEXT")) == NULL) || r;
+ r = ((glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposefEXT")) == NULL) || r;
+ r = ((glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultdEXT")) == NULL) || r;
+ r = ((glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultfEXT")) == NULL) || r;
+ r = ((glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixOrthoEXT")) == NULL) || r;
+ r = ((glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPopEXT")) == NULL) || r;
+ r = ((glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPushEXT")) == NULL) || r;
+ r = ((glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatedEXT")) == NULL) || r;
+ r = ((glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatefEXT")) == NULL) || r;
+ r = ((glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScaledEXT")) == NULL) || r;
+ r = ((glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScalefEXT")) == NULL) || r;
+ r = ((glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatedEXT")) == NULL) || r;
+ r = ((glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatefEXT")) == NULL) || r;
+ r = ((glMultiTexBufferEXT = (PFNGLMULTITEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexBufferEXT")) == NULL) || r;
+ r = ((glMultiTexCoordPointerEXT = (PFNGLMULTITEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordPointerEXT")) == NULL) || r;
+ r = ((glMultiTexEnvfEXT = (PFNGLMULTITEXENVFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfEXT")) == NULL) || r;
+ r = ((glMultiTexEnvfvEXT = (PFNGLMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfvEXT")) == NULL) || r;
+ r = ((glMultiTexEnviEXT = (PFNGLMULTITEXENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnviEXT")) == NULL) || r;
+ r = ((glMultiTexEnvivEXT = (PFNGLMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvivEXT")) == NULL) || r;
+ r = ((glMultiTexGendEXT = (PFNGLMULTITEXGENDEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendEXT")) == NULL) || r;
+ r = ((glMultiTexGendvEXT = (PFNGLMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendvEXT")) == NULL) || r;
+ r = ((glMultiTexGenfEXT = (PFNGLMULTITEXGENFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfEXT")) == NULL) || r;
+ r = ((glMultiTexGenfvEXT = (PFNGLMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfvEXT")) == NULL) || r;
+ r = ((glMultiTexGeniEXT = (PFNGLMULTITEXGENIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGeniEXT")) == NULL) || r;
+ r = ((glMultiTexGenivEXT = (PFNGLMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenivEXT")) == NULL) || r;
+ r = ((glMultiTexImage1DEXT = (PFNGLMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage1DEXT")) == NULL) || r;
+ r = ((glMultiTexImage2DEXT = (PFNGLMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage2DEXT")) == NULL) || r;
+ r = ((glMultiTexImage3DEXT = (PFNGLMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage3DEXT")) == NULL) || r;
+ r = ((glMultiTexParameterIivEXT = (PFNGLMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIivEXT")) == NULL) || r;
+ r = ((glMultiTexParameterIuivEXT = (PFNGLMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIuivEXT")) == NULL) || r;
+ r = ((glMultiTexParameterfEXT = (PFNGLMULTITEXPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfEXT")) == NULL) || r;
+ r = ((glMultiTexParameterfvEXT = (PFNGLMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfvEXT")) == NULL) || r;
+ r = ((glMultiTexParameteriEXT = (PFNGLMULTITEXPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameteriEXT")) == NULL) || r;
+ r = ((glMultiTexParameterivEXT = (PFNGLMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterivEXT")) == NULL) || r;
+ r = ((glMultiTexRenderbufferEXT = (PFNGLMULTITEXRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexRenderbufferEXT")) == NULL) || r;
+ r = ((glMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage1DEXT")) == NULL) || r;
+ r = ((glMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage2DEXT")) == NULL) || r;
+ r = ((glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage3DEXT")) == NULL) || r;
+ r = ((glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferDataEXT")) == NULL) || r;
+ r = ((glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubDataEXT")) == NULL) || r;
+ r = ((glNamedCopyBufferSubDataEXT = (PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedCopyBufferSubDataEXT")) == NULL) || r;
+ r = ((glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbufferEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture1DEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture2DEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTexture3DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture3DEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTextureFaceEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureFaceEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTextureLayerEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayerEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4dEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4dvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dvEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4fEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fvEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4iEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4iEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4ivEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4uiEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uiEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uivEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameters4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameters4fvEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParametersI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4ivEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParametersI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4uivEXT")) == NULL) || r;
+ r = ((glNamedProgramStringEXT = (PFNGLNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramStringEXT")) == NULL) || r;
+ r = ((glNamedRenderbufferStorageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageEXT")) == NULL) || r;
+ r = ((glNamedRenderbufferStorageMultisampleCoverageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleCoverageEXT")) == NULL) || r;
+ r = ((glNamedRenderbufferStorageMultisampleEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleEXT")) == NULL) || r;
+ r = ((glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fEXT")) == NULL) || r;
+ r = ((glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fvEXT")) == NULL) || r;
+ r = ((glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iEXT")) == NULL) || r;
+ r = ((glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ivEXT")) == NULL) || r;
+ r = ((glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiEXT")) == NULL) || r;
+ r = ((glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uivEXT")) == NULL) || r;
+ r = ((glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fEXT")) == NULL) || r;
+ r = ((glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fvEXT")) == NULL) || r;
+ r = ((glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iEXT")) == NULL) || r;
+ r = ((glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ivEXT")) == NULL) || r;
+ r = ((glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiEXT")) == NULL) || r;
+ r = ((glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uivEXT")) == NULL) || r;
+ r = ((glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fEXT")) == NULL) || r;
+ r = ((glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fvEXT")) == NULL) || r;
+ r = ((glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iEXT")) == NULL) || r;
+ r = ((glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ivEXT")) == NULL) || r;
+ r = ((glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiEXT")) == NULL) || r;
+ r = ((glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uivEXT")) == NULL) || r;
+ r = ((glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fEXT")) == NULL) || r;
+ r = ((glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fvEXT")) == NULL) || r;
+ r = ((glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iEXT")) == NULL) || r;
+ r = ((glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ivEXT")) == NULL) || r;
+ r = ((glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiEXT")) == NULL) || r;
+ r = ((glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uivEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fvEXT")) == NULL) || r;
+ r = ((glPushClientAttribDefaultEXT = (PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glPushClientAttribDefaultEXT")) == NULL) || r;
+ r = ((glTextureBufferEXT = (PFNGLTEXTUREBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferEXT")) == NULL) || r;
+ r = ((glTextureImage1DEXT = (PFNGLTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage1DEXT")) == NULL) || r;
+ r = ((glTextureImage2DEXT = (PFNGLTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DEXT")) == NULL) || r;
+ r = ((glTextureImage3DEXT = (PFNGLTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DEXT")) == NULL) || r;
+ r = ((glTextureParameterIivEXT = (PFNGLTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIivEXT")) == NULL) || r;
+ r = ((glTextureParameterIuivEXT = (PFNGLTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuivEXT")) == NULL) || r;
+ r = ((glTextureParameterfEXT = (PFNGLTEXTUREPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfEXT")) == NULL) || r;
+ r = ((glTextureParameterfvEXT = (PFNGLTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfvEXT")) == NULL) || r;
+ r = ((glTextureParameteriEXT = (PFNGLTEXTUREPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriEXT")) == NULL) || r;
+ r = ((glTextureParameterivEXT = (PFNGLTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterivEXT")) == NULL) || r;
+ r = ((glTextureRenderbufferEXT = (PFNGLTEXTURERENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureRenderbufferEXT")) == NULL) || r;
+ r = ((glTextureSubImage1DEXT = (PFNGLTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1DEXT")) == NULL) || r;
+ r = ((glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2DEXT")) == NULL) || r;
+ r = ((glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3DEXT")) == NULL) || r;
+ r = ((glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBufferEXT")) == NULL) || r;
+ r = ((glVertexArrayColorOffsetEXT = (PFNGLVERTEXARRAYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayColorOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayEdgeFlagOffsetEXT = (PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayEdgeFlagOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayFogCoordOffsetEXT = (PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayFogCoordOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayIndexOffsetEXT = (PFNGLVERTEXARRAYINDEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayIndexOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayMultiTexCoordOffsetEXT = (PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayMultiTexCoordOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayNormalOffsetEXT = (PFNGLVERTEXARRAYNORMALOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayNormalOffsetEXT")) == NULL) || r;
+ r = ((glVertexArraySecondaryColorOffsetEXT = (PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArraySecondaryColorOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayTexCoordOffsetEXT = (PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayTexCoordOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribDivisorEXT = (PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribDivisorEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribIOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexOffsetEXT = (PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexOffsetEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_direct_state_access */
+
+#ifdef GL_EXT_discard_framebuffer
+
+static GLboolean _glewInit_GL_EXT_discard_framebuffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glDiscardFramebufferEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_discard_framebuffer */
+
+#ifdef GL_EXT_draw_buffers
+
+static GLboolean _glewInit_GL_EXT_draw_buffers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_buffers */
+
+#ifdef GL_EXT_draw_buffers2
+
+static GLboolean _glewInit_GL_EXT_draw_buffers2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskIndexedEXT")) == NULL) || r;
+ r = ((glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableIndexedEXT")) == NULL) || r;
+ r = ((glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableIndexedEXT")) == NULL) || r;
+ r = ((glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetBooleanIndexedvEXT")) == NULL) || r;
+ r = ((glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerIndexedvEXT")) == NULL) || r;
+ r = ((glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledIndexedEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_buffers2 */
+
+#ifdef GL_EXT_draw_buffers_indexed
+
+static GLboolean _glewInit_GL_EXT_draw_buffers_indexed ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationSeparateiEXT = (PFNGLBLENDEQUATIONSEPARATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateiEXT")) == NULL) || r;
+ r = ((glBlendEquationiEXT = (PFNGLBLENDEQUATIONIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationiEXT")) == NULL) || r;
+ r = ((glBlendFuncSeparateiEXT = (PFNGLBLENDFUNCSEPARATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateiEXT")) == NULL) || r;
+ r = ((glBlendFunciEXT = (PFNGLBLENDFUNCIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFunciEXT")) == NULL) || r;
+ r = ((glColorMaskiEXT = (PFNGLCOLORMASKIEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskiEXT")) == NULL) || r;
+ r = ((glDisableiEXT = (PFNGLDISABLEIEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableiEXT")) == NULL) || r;
+ r = ((glEnableiEXT = (PFNGLENABLEIEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableiEXT")) == NULL) || r;
+ r = ((glIsEnablediEXT = (PFNGLISENABLEDIEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnablediEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_buffers_indexed */
+
+#ifdef GL_EXT_draw_elements_base_vertex
+
+static GLboolean _glewInit_GL_EXT_draw_elements_base_vertex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawElementsBaseVertexEXT = (PFNGLDRAWELEMENTSBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsBaseVertexEXT")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseVertexEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexEXT")) == NULL) || r;
+ r = ((glDrawRangeElementsBaseVertexEXT = (PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsBaseVertexEXT")) == NULL) || r;
+ r = ((glMultiDrawElementsBaseVertexEXT = (PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsBaseVertexEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_elements_base_vertex */
+
+#ifdef GL_EXT_draw_instanced
+
+static GLboolean _glewInit_GL_EXT_draw_instanced ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedEXT")) == NULL) || r;
+ r = ((glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_instanced */
+
+#ifdef GL_EXT_draw_range_elements
+
+static GLboolean _glewInit_GL_EXT_draw_range_elements ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_range_elements */
+
+#ifdef GL_EXT_external_buffer
+
+static GLboolean _glewInit_GL_EXT_external_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferStorageExternalEXT = (PFNGLBUFFERSTORAGEEXTERNALEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferStorageExternalEXT")) == NULL) || r;
+ r = ((glNamedBufferStorageExternalEXT = (PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageExternalEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_external_buffer */
+
+#ifdef GL_EXT_fog_coord
+
+static GLboolean _glewInit_GL_EXT_fog_coord ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerEXT")) == NULL) || r;
+ r = ((glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddEXT")) == NULL) || r;
+ r = ((glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddvEXT")) == NULL) || r;
+ r = ((glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfEXT")) == NULL) || r;
+ r = ((glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_fog_coord */
+
+#ifdef GL_EXT_fragment_lighting
+
+static GLboolean _glewInit_GL_EXT_fragment_lighting ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFragmentColorMaterialEXT = (PFNGLFRAGMENTCOLORMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialEXT")) == NULL) || r;
+ r = ((glFragmentLightModelfEXT = (PFNGLFRAGMENTLIGHTMODELFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfEXT")) == NULL) || r;
+ r = ((glFragmentLightModelfvEXT = (PFNGLFRAGMENTLIGHTMODELFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvEXT")) == NULL) || r;
+ r = ((glFragmentLightModeliEXT = (PFNGLFRAGMENTLIGHTMODELIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliEXT")) == NULL) || r;
+ r = ((glFragmentLightModelivEXT = (PFNGLFRAGMENTLIGHTMODELIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivEXT")) == NULL) || r;
+ r = ((glFragmentLightfEXT = (PFNGLFRAGMENTLIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfEXT")) == NULL) || r;
+ r = ((glFragmentLightfvEXT = (PFNGLFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvEXT")) == NULL) || r;
+ r = ((glFragmentLightiEXT = (PFNGLFRAGMENTLIGHTIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiEXT")) == NULL) || r;
+ r = ((glFragmentLightivEXT = (PFNGLFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivEXT")) == NULL) || r;
+ r = ((glFragmentMaterialfEXT = (PFNGLFRAGMENTMATERIALFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfEXT")) == NULL) || r;
+ r = ((glFragmentMaterialfvEXT = (PFNGLFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvEXT")) == NULL) || r;
+ r = ((glFragmentMaterialiEXT = (PFNGLFRAGMENTMATERIALIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiEXT")) == NULL) || r;
+ r = ((glFragmentMaterialivEXT = (PFNGLFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivEXT")) == NULL) || r;
+ r = ((glGetFragmentLightfvEXT = (PFNGLGETFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvEXT")) == NULL) || r;
+ r = ((glGetFragmentLightivEXT = (PFNGLGETFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivEXT")) == NULL) || r;
+ r = ((glGetFragmentMaterialfvEXT = (PFNGLGETFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvEXT")) == NULL) || r;
+ r = ((glGetFragmentMaterialivEXT = (PFNGLGETFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivEXT")) == NULL) || r;
+ r = ((glLightEnviEXT = (PFNGLLIGHTENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glLightEnviEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_fragment_lighting */
+
+#ifdef GL_EXT_framebuffer_blit
+
+static GLboolean _glewInit_GL_EXT_framebuffer_blit ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_framebuffer_blit */
+
+#ifdef GL_EXT_framebuffer_multisample
+
+static GLboolean _glewInit_GL_EXT_framebuffer_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_framebuffer_multisample */
+
+#ifdef GL_EXT_framebuffer_object
+
+static GLboolean _glewInit_GL_EXT_framebuffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindFramebufferEXT")) == NULL) || r;
+ r = ((glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbufferEXT")) == NULL) || r;
+ r = ((glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatusEXT")) == NULL) || r;
+ r = ((glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffersEXT")) == NULL) || r;
+ r = ((glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffersEXT")) == NULL) || r;
+ r = ((glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbufferEXT")) == NULL) || r;
+ r = ((glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1DEXT")) == NULL) || r;
+ r = ((glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DEXT")) == NULL) || r;
+ r = ((glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3DEXT")) == NULL) || r;
+ r = ((glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffersEXT")) == NULL) || r;
+ r = ((glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffersEXT")) == NULL) || r;
+ r = ((glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmapEXT")) == NULL) || r;
+ r = ((glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameterivEXT")) == NULL) || r;
+ r = ((glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameterivEXT")) == NULL) || r;
+ r = ((glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsFramebufferEXT")) == NULL) || r;
+ r = ((glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbufferEXT")) == NULL) || r;
+ r = ((glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_framebuffer_object */
+
+#ifdef GL_EXT_geometry_shader4
+
+static GLboolean _glewInit_GL_EXT_geometry_shader4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureEXT")) == NULL) || r;
+ r = ((glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceEXT")) == NULL) || r;
+ r = ((glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_geometry_shader4 */
+
+#ifdef GL_EXT_gpu_program_parameters
+
+static GLboolean _glewInit_GL_EXT_gpu_program_parameters ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramEnvParameters4fvEXT = (PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameters4fvEXT")) == NULL) || r;
+ r = ((glProgramLocalParameters4fvEXT = (PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameters4fvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_gpu_program_parameters */
+
+#ifdef GL_EXT_gpu_shader4
+
+static GLboolean _glewInit_GL_EXT_gpu_shader4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationEXT")) == NULL) || r;
+ r = ((glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocationEXT")) == NULL) || r;
+ r = ((glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuivEXT")) == NULL) || r;
+ r = ((glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIivEXT")) == NULL) || r;
+ r = ((glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuivEXT")) == NULL) || r;
+ r = ((glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiEXT")) == NULL) || r;
+ r = ((glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uivEXT")) == NULL) || r;
+ r = ((glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiEXT")) == NULL) || r;
+ r = ((glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uivEXT")) == NULL) || r;
+ r = ((glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiEXT")) == NULL) || r;
+ r = ((glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uivEXT")) == NULL) || r;
+ r = ((glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiEXT")) == NULL) || r;
+ r = ((glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iEXT")) == NULL) || r;
+ r = ((glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iEXT")) == NULL) || r;
+ r = ((glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iEXT")) == NULL) || r;
+ r = ((glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bvEXT")) == NULL) || r;
+ r = ((glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iEXT")) == NULL) || r;
+ r = ((glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4svEXT")) == NULL) || r;
+ r = ((glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubvEXT")) == NULL) || r;
+ r = ((glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usvEXT")) == NULL) || r;
+ r = ((glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_gpu_shader4 */
+
+#ifdef GL_EXT_histogram
+
+static GLboolean _glewInit_GL_EXT_histogram ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramEXT")) == NULL) || r;
+ r = ((glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfvEXT")) == NULL) || r;
+ r = ((glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterivEXT")) == NULL) || r;
+ r = ((glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxEXT")) == NULL) || r;
+ r = ((glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfvEXT")) == NULL) || r;
+ r = ((glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterivEXT")) == NULL) || r;
+ r = ((glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glHistogramEXT")) == NULL) || r;
+ r = ((glMinmaxEXT = (PFNGLMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glMinmaxEXT")) == NULL) || r;
+ r = ((glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glResetHistogramEXT")) == NULL) || r;
+ r = ((glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glResetMinmaxEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_histogram */
+
+#ifdef GL_EXT_index_func
+
+static GLboolean _glewInit_GL_EXT_index_func ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexFuncEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_index_func */
+
+#ifdef GL_EXT_index_material
+
+static GLboolean _glewInit_GL_EXT_index_material ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexMaterialEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_index_material */
+
+#ifdef GL_EXT_instanced_arrays
+
+static GLboolean _glewInit_GL_EXT_instanced_arrays ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_instanced_arrays */
+
+#ifdef GL_EXT_light_texture
+
+static GLboolean _glewInit_GL_EXT_light_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glApplyTextureEXT")) == NULL) || r;
+ r = ((glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureLightEXT")) == NULL) || r;
+ r = ((glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureMaterialEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_light_texture */
+
+#ifdef GL_EXT_map_buffer_range
+
+static GLboolean _glewInit_GL_EXT_map_buffer_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushMappedBufferRangeEXT = (PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeEXT")) == NULL) || r;
+ r = ((glMapBufferRangeEXT = (PFNGLMAPBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRangeEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_map_buffer_range */
+
+#ifdef GL_EXT_memory_object
+
+static GLboolean _glewInit_GL_EXT_memory_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferStorageMemEXT = (PFNGLBUFFERSTORAGEMEMEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferStorageMemEXT")) == NULL) || r;
+ r = ((glCreateMemoryObjectsEXT = (PFNGLCREATEMEMORYOBJECTSEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateMemoryObjectsEXT")) == NULL) || r;
+ r = ((glDeleteMemoryObjectsEXT = (PFNGLDELETEMEMORYOBJECTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteMemoryObjectsEXT")) == NULL) || r;
+ r = ((glGetMemoryObjectParameterivEXT = (PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMemoryObjectParameterivEXT")) == NULL) || r;
+ r = ((glGetUnsignedBytei_vEXT = (PFNGLGETUNSIGNEDBYTEI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUnsignedBytei_vEXT")) == NULL) || r;
+ r = ((glGetUnsignedBytevEXT = (PFNGLGETUNSIGNEDBYTEVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUnsignedBytevEXT")) == NULL) || r;
+ r = ((glIsMemoryObjectEXT = (PFNGLISMEMORYOBJECTEXTPROC)glewGetProcAddress((const GLubyte*)"glIsMemoryObjectEXT")) == NULL) || r;
+ r = ((glMemoryObjectParameterivEXT = (PFNGLMEMORYOBJECTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMemoryObjectParameterivEXT")) == NULL) || r;
+ r = ((glNamedBufferStorageMemEXT = (PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageMemEXT")) == NULL) || r;
+ r = ((glTexStorageMem1DEXT = (PFNGLTEXSTORAGEMEM1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem1DEXT")) == NULL) || r;
+ r = ((glTexStorageMem2DEXT = (PFNGLTEXSTORAGEMEM2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem2DEXT")) == NULL) || r;
+ r = ((glTexStorageMem2DMultisampleEXT = (PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem2DMultisampleEXT")) == NULL) || r;
+ r = ((glTexStorageMem3DEXT = (PFNGLTEXSTORAGEMEM3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem3DEXT")) == NULL) || r;
+ r = ((glTexStorageMem3DMultisampleEXT = (PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem3DMultisampleEXT")) == NULL) || r;
+ r = ((glTextureStorageMem1DEXT = (PFNGLTEXTURESTORAGEMEM1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem1DEXT")) == NULL) || r;
+ r = ((glTextureStorageMem2DEXT = (PFNGLTEXTURESTORAGEMEM2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem2DEXT")) == NULL) || r;
+ r = ((glTextureStorageMem2DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem2DMultisampleEXT")) == NULL) || r;
+ r = ((glTextureStorageMem3DEXT = (PFNGLTEXTURESTORAGEMEM3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem3DEXT")) == NULL) || r;
+ r = ((glTextureStorageMem3DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem3DMultisampleEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_memory_object */
+
+#ifdef GL_EXT_memory_object_fd
+
+static GLboolean _glewInit_GL_EXT_memory_object_fd ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glImportMemoryFdEXT = (PFNGLIMPORTMEMORYFDEXTPROC)glewGetProcAddress((const GLubyte*)"glImportMemoryFdEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_memory_object_fd */
+
+#ifdef GL_EXT_memory_object_win32
+
+static GLboolean _glewInit_GL_EXT_memory_object_win32 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glImportMemoryWin32HandleEXT = (PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportMemoryWin32HandleEXT")) == NULL) || r;
+ r = ((glImportMemoryWin32NameEXT = (PFNGLIMPORTMEMORYWIN32NAMEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportMemoryWin32NameEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_memory_object_win32 */
+
+#ifdef GL_EXT_multi_draw_arrays
+
+static GLboolean _glewInit_GL_EXT_multi_draw_arrays ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysEXT")) == NULL) || r;
+ r = ((glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_multi_draw_arrays */
+
+#ifdef GL_EXT_multi_draw_indirect
+
+static GLboolean _glewInit_GL_EXT_multi_draw_indirect ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectEXT = (PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectEXT")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectEXT = (PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_multi_draw_indirect */
+
+#ifdef GL_EXT_multisample
+
+static GLboolean _glewInit_GL_EXT_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskEXT")) == NULL) || r;
+ r = ((glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_multisample */
+
+#ifdef GL_EXT_multisampled_render_to_texture
+
+static GLboolean _glewInit_GL_EXT_multisampled_render_to_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DMultisampleEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_multisampled_render_to_texture */
+
+#ifdef GL_EXT_multiview_draw_buffers
+
+static GLboolean _glewInit_GL_EXT_multiview_draw_buffers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawBuffersIndexedEXT = (PFNGLDRAWBUFFERSINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersIndexedEXT")) == NULL) || r;
+ r = ((glGetIntegeri_vEXT = (PFNGLGETINTEGERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_vEXT")) == NULL) || r;
+ r = ((glReadBufferIndexedEXT = (PFNGLREADBUFFERINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glReadBufferIndexedEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_multiview_draw_buffers */
+
+#ifdef GL_EXT_paletted_texture
+
+static GLboolean _glewInit_GL_EXT_paletted_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorTableEXT")) == NULL) || r;
+ r = ((glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableEXT")) == NULL) || r;
+ r = ((glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvEXT")) == NULL) || r;
+ r = ((glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_paletted_texture */
+
+#ifdef GL_EXT_pixel_transform
+
+static GLboolean _glewInit_GL_EXT_pixel_transform ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvEXT")) == NULL) || r;
+ r = ((glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivEXT")) == NULL) || r;
+ r = ((glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfEXT")) == NULL) || r;
+ r = ((glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvEXT")) == NULL) || r;
+ r = ((glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriEXT")) == NULL) || r;
+ r = ((glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_pixel_transform */
+
+#ifdef GL_EXT_point_parameters
+
+static GLboolean _glewInit_GL_EXT_point_parameters ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfEXT")) == NULL) || r;
+ r = ((glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_point_parameters */
+
+#ifdef GL_EXT_polygon_offset
+
+static GLboolean _glewInit_GL_EXT_polygon_offset ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_polygon_offset */
+
+#ifdef GL_EXT_polygon_offset_clamp
+
+static GLboolean _glewInit_GL_EXT_polygon_offset_clamp ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPolygonOffsetClampEXT = (PFNGLPOLYGONOFFSETCLAMPEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetClampEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_polygon_offset_clamp */
+
+#ifdef GL_EXT_provoking_vertex
+
+static GLboolean _glewInit_GL_EXT_provoking_vertex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertexEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_provoking_vertex */
+
+#ifdef GL_EXT_raster_multisample
+
+static GLboolean _glewInit_GL_EXT_raster_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCoverageModulationNV = (PFNGLCOVERAGEMODULATIONNVPROC)glewGetProcAddress((const GLubyte*)"glCoverageModulationNV")) == NULL) || r;
+ r = ((glCoverageModulationTableNV = (PFNGLCOVERAGEMODULATIONTABLENVPROC)glewGetProcAddress((const GLubyte*)"glCoverageModulationTableNV")) == NULL) || r;
+ r = ((glGetCoverageModulationTableNV = (PFNGLGETCOVERAGEMODULATIONTABLENVPROC)glewGetProcAddress((const GLubyte*)"glGetCoverageModulationTableNV")) == NULL) || r;
+ r = ((glRasterSamplesEXT = (PFNGLRASTERSAMPLESEXTPROC)glewGetProcAddress((const GLubyte*)"glRasterSamplesEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_raster_multisample */
+
+#ifdef GL_EXT_scene_marker
+
+static GLboolean _glewInit_GL_EXT_scene_marker ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginSceneEXT = (PFNGLBEGINSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginSceneEXT")) == NULL) || r;
+ r = ((glEndSceneEXT = (PFNGLENDSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glEndSceneEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_scene_marker */
+
+#ifdef GL_EXT_secondary_color
+
+static GLboolean _glewInit_GL_EXT_secondary_color ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bEXT")) == NULL) || r;
+ r = ((glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dEXT")) == NULL) || r;
+ r = ((glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fEXT")) == NULL) || r;
+ r = ((glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iEXT")) == NULL) || r;
+ r = ((glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ivEXT")) == NULL) || r;
+ r = ((glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sEXT")) == NULL) || r;
+ r = ((glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3svEXT")) == NULL) || r;
+ r = ((glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubEXT")) == NULL) || r;
+ r = ((glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiEXT")) == NULL) || r;
+ r = ((glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uivEXT")) == NULL) || r;
+ r = ((glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usEXT")) == NULL) || r;
+ r = ((glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usvEXT")) == NULL) || r;
+ r = ((glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_secondary_color */
+
+#ifdef GL_EXT_semaphore
+
+static GLboolean _glewInit_GL_EXT_semaphore ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeleteSemaphoresEXT = (PFNGLDELETESEMAPHORESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteSemaphoresEXT")) == NULL) || r;
+ r = ((glGenSemaphoresEXT = (PFNGLGENSEMAPHORESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSemaphoresEXT")) == NULL) || r;
+ r = ((glGetSemaphoreParameterui64vEXT = (PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetSemaphoreParameterui64vEXT")) == NULL) || r;
+ r = ((glIsSemaphoreEXT = (PFNGLISSEMAPHOREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsSemaphoreEXT")) == NULL) || r;
+ r = ((glSemaphoreParameterui64vEXT = (PFNGLSEMAPHOREPARAMETERUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glSemaphoreParameterui64vEXT")) == NULL) || r;
+ r = ((glSignalSemaphoreEXT = (PFNGLSIGNALSEMAPHOREEXTPROC)glewGetProcAddress((const GLubyte*)"glSignalSemaphoreEXT")) == NULL) || r;
+ r = ((glWaitSemaphoreEXT = (PFNGLWAITSEMAPHOREEXTPROC)glewGetProcAddress((const GLubyte*)"glWaitSemaphoreEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_semaphore */
+
+#ifdef GL_EXT_semaphore_fd
+
+static GLboolean _glewInit_GL_EXT_semaphore_fd ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glImportSemaphoreFdEXT = (PFNGLIMPORTSEMAPHOREFDEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSemaphoreFdEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_semaphore_fd */
+
+#ifdef GL_EXT_semaphore_win32
+
+static GLboolean _glewInit_GL_EXT_semaphore_win32 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glImportSemaphoreWin32HandleEXT = (PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSemaphoreWin32HandleEXT")) == NULL) || r;
+ r = ((glImportSemaphoreWin32NameEXT = (PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSemaphoreWin32NameEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_semaphore_win32 */
+
+#ifdef GL_EXT_separate_shader_objects
+
+static GLboolean _glewInit_GL_EXT_separate_shader_objects ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveProgramEXT = (PFNGLACTIVEPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveProgramEXT")) == NULL) || r;
+ r = ((glCreateShaderProgramEXT = (PFNGLCREATESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramEXT")) == NULL) || r;
+ r = ((glUseShaderProgramEXT = (PFNGLUSESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glUseShaderProgramEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_separate_shader_objects */
+
+#ifdef GL_EXT_shader_image_load_store
+
+static GLboolean _glewInit_GL_EXT_shader_image_load_store ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindImageTextureEXT = (PFNGLBINDIMAGETEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextureEXT")) == NULL) || r;
+ r = ((glMemoryBarrierEXT = (PFNGLMEMORYBARRIEREXTPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrierEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_shader_image_load_store */
+
+#ifdef GL_EXT_shader_pixel_local_storage2
+
+static GLboolean _glewInit_GL_EXT_shader_pixel_local_storage2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearPixelLocalStorageuiEXT = (PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearPixelLocalStorageuiEXT")) == NULL) || r;
+ r = ((glFramebufferPixelLocalStorageSizeEXT = (PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferPixelLocalStorageSizeEXT")) == NULL) || r;
+ r = ((glGetFramebufferPixelLocalStorageSizeEXT = (PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferPixelLocalStorageSizeEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_shader_pixel_local_storage2 */
+
+#ifdef GL_EXT_sparse_texture
+
+static GLboolean _glewInit_GL_EXT_sparse_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexPageCommitmentEXT = (PFNGLTEXPAGECOMMITMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glTexPageCommitmentEXT")) == NULL) || r;
+ r = ((glTexturePageCommitmentEXT = (PFNGLTEXTUREPAGECOMMITMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glTexturePageCommitmentEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_sparse_texture */
+
+#ifdef GL_EXT_stencil_two_side
+
+static GLboolean _glewInit_GL_EXT_stencil_two_side ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveStencilFaceEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_stencil_two_side */
+
+#ifdef GL_EXT_subtexture
+
+static GLboolean _glewInit_GL_EXT_subtexture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage1DEXT")) == NULL) || r;
+ r = ((glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage2DEXT")) == NULL) || r;
+ r = ((glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_subtexture */
+
+#ifdef GL_EXT_texture3D
+
+static GLboolean _glewInit_GL_EXT_texture3D ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture3D */
+
+#ifdef GL_EXT_texture_array
+
+static GLboolean _glewInit_GL_EXT_texture_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_array */
+
+#ifdef GL_EXT_texture_buffer_object
+
+static GLboolean _glewInit_GL_EXT_texture_buffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexBufferEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_buffer_object */
+
+#ifdef GL_EXT_texture_integer
+
+static GLboolean _glewInit_GL_EXT_texture_integer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearColorIiEXT = (PFNGLCLEARCOLORIIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIiEXT")) == NULL) || r;
+ r = ((glClearColorIuiEXT = (PFNGLCLEARCOLORIUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIuiEXT")) == NULL) || r;
+ r = ((glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIivEXT")) == NULL) || r;
+ r = ((glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuivEXT")) == NULL) || r;
+ r = ((glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIivEXT")) == NULL) || r;
+ r = ((glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_integer */
+
+#ifdef GL_EXT_texture_object
+
+static GLboolean _glewInit_GL_EXT_texture_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC)glewGetProcAddress((const GLubyte*)"glAreTexturesResidentEXT")) == NULL) || r;
+ r = ((glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureEXT")) == NULL) || r;
+ r = ((glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteTexturesEXT")) == NULL) || r;
+ r = ((glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenTexturesEXT")) == NULL) || r;
+ r = ((glIsTextureEXT = (PFNGLISTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsTextureEXT")) == NULL) || r;
+ r = ((glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeTexturesEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_object */
+
+#ifdef GL_EXT_texture_perturb_normal
+
+static GLboolean _glewInit_GL_EXT_texture_perturb_normal ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureNormalEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_perturb_normal */
+
+#ifdef GL_EXT_texture_storage
+
+static GLboolean _glewInit_GL_EXT_texture_storage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexStorage1DEXT = (PFNGLTEXSTORAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorage1DEXT")) == NULL) || r;
+ r = ((glTexStorage2DEXT = (PFNGLTEXSTORAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2DEXT")) == NULL) || r;
+ r = ((glTexStorage3DEXT = (PFNGLTEXSTORAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3DEXT")) == NULL) || r;
+ r = ((glTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage1DEXT")) == NULL) || r;
+ r = ((glTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DEXT")) == NULL) || r;
+ r = ((glTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_storage */
+
+#ifdef GL_EXT_texture_view
+
+static GLboolean _glewInit_GL_EXT_texture_view ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureViewEXT = (PFNGLTEXTUREVIEWEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureViewEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_view */
+
+#ifdef GL_EXT_timer_query
+
+static GLboolean _glewInit_GL_EXT_timer_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vEXT")) == NULL) || r;
+ r = ((glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_timer_query */
+
+#ifdef GL_EXT_transform_feedback
+
+static GLboolean _glewInit_GL_EXT_transform_feedback ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackEXT")) == NULL) || r;
+ r = ((glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseEXT")) == NULL) || r;
+ r = ((glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetEXT")) == NULL) || r;
+ r = ((glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeEXT")) == NULL) || r;
+ r = ((glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackEXT")) == NULL) || r;
+ r = ((glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingEXT")) == NULL) || r;
+ r = ((glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_transform_feedback */
+
+#ifdef GL_EXT_vertex_array
+
+static GLboolean _glewInit_GL_EXT_vertex_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glArrayElementEXT")) == NULL) || r;
+ r = ((glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glColorPointerEXT")) == NULL) || r;
+ r = ((glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysEXT")) == NULL) || r;
+ r = ((glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerEXT")) == NULL) || r;
+ r = ((glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerEXT")) == NULL) || r;
+ r = ((glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerEXT")) == NULL) || r;
+ r = ((glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerEXT")) == NULL) || r;
+ r = ((glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_array */
+
+#ifdef GL_EXT_vertex_array_setXXX
+
+static GLboolean _glewInit_GL_EXT_vertex_array_setXXX ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindArraySetEXT = (PFNGLBINDARRAYSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindArraySetEXT")) == NULL) || r;
+ r = ((glCreateArraySetExt = (PFNGLCREATEARRAYSETEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateArraySetExt")) == NULL) || r;
+ r = ((glDeleteArraySetsEXT = (PFNGLDELETEARRAYSETSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteArraySetsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_array_setXXX */
+
+#ifdef GL_EXT_vertex_attrib_64bit
+
+static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribLdvEXT = (PFNGLGETVERTEXATTRIBLDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdvEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribLOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribLOffsetEXT")) == NULL) || r;
+ r = ((glVertexAttribL1dEXT = (PFNGLVERTEXATTRIBL1DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dEXT")) == NULL) || r;
+ r = ((glVertexAttribL1dvEXT = (PFNGLVERTEXATTRIBL1DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dvEXT")) == NULL) || r;
+ r = ((glVertexAttribL2dEXT = (PFNGLVERTEXATTRIBL2DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dEXT")) == NULL) || r;
+ r = ((glVertexAttribL2dvEXT = (PFNGLVERTEXATTRIBL2DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dvEXT")) == NULL) || r;
+ r = ((glVertexAttribL3dEXT = (PFNGLVERTEXATTRIBL3DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dEXT")) == NULL) || r;
+ r = ((glVertexAttribL3dvEXT = (PFNGLVERTEXATTRIBL3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dvEXT")) == NULL) || r;
+ r = ((glVertexAttribL4dEXT = (PFNGLVERTEXATTRIBL4DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dEXT")) == NULL) || r;
+ r = ((glVertexAttribL4dvEXT = (PFNGLVERTEXATTRIBL4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dvEXT")) == NULL) || r;
+ r = ((glVertexAttribLPointerEXT = (PFNGLVERTEXATTRIBLPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_attrib_64bit */
+
+#ifdef GL_EXT_vertex_shader
+
+static GLboolean _glewInit_GL_EXT_vertex_shader ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBeginVertexShaderEXT")) == NULL) || r;
+ r = ((glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindLightParameterEXT")) == NULL) || r;
+ r = ((glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindMaterialParameterEXT")) == NULL) || r;
+ r = ((glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindParameterEXT")) == NULL) || r;
+ r = ((glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTexGenParameterEXT")) == NULL) || r;
+ r = ((glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnitParameterEXT")) == NULL) || r;
+ r = ((glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindVertexShaderEXT")) == NULL) || r;
+ r = ((glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexShaderEXT")) == NULL) || r;
+ r = ((glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVariantClientStateEXT")) == NULL) || r;
+ r = ((glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVariantClientStateEXT")) == NULL) || r;
+ r = ((glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glEndVertexShaderEXT")) == NULL) || r;
+ r = ((glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glExtractComponentEXT")) == NULL) || r;
+ r = ((glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSymbolsEXT")) == NULL) || r;
+ r = ((glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenVertexShadersEXT")) == NULL) || r;
+ r = ((glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantBooleanvEXT")) == NULL) || r;
+ r = ((glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantFloatvEXT")) == NULL) || r;
+ r = ((glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantIntegervEXT")) == NULL) || r;
+ r = ((glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantBooleanvEXT")) == NULL) || r;
+ r = ((glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantFloatvEXT")) == NULL) || r;
+ r = ((glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantIntegervEXT")) == NULL) || r;
+ r = ((glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantBooleanvEXT")) == NULL) || r;
+ r = ((glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantFloatvEXT")) == NULL) || r;
+ r = ((glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantIntegervEXT")) == NULL) || r;
+ r = ((glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantPointervEXT")) == NULL) || r;
+ r = ((glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glInsertComponentEXT")) == NULL) || r;
+ r = ((glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsVariantEnabledEXT")) == NULL) || r;
+ r = ((glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetInvariantEXT")) == NULL) || r;
+ r = ((glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetLocalConstantEXT")) == NULL) || r;
+ r = ((glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp1EXT")) == NULL) || r;
+ r = ((glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp2EXT")) == NULL) || r;
+ r = ((glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp3EXT")) == NULL) || r;
+ r = ((glSwizzleEXT = (PFNGLSWIZZLEEXTPROC)glewGetProcAddress((const GLubyte*)"glSwizzleEXT")) == NULL) || r;
+ r = ((glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVariantPointerEXT")) == NULL) || r;
+ r = ((glVariantbvEXT = (PFNGLVARIANTBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantbvEXT")) == NULL) || r;
+ r = ((glVariantdvEXT = (PFNGLVARIANTDVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantdvEXT")) == NULL) || r;
+ r = ((glVariantfvEXT = (PFNGLVARIANTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantfvEXT")) == NULL) || r;
+ r = ((glVariantivEXT = (PFNGLVARIANTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantivEXT")) == NULL) || r;
+ r = ((glVariantsvEXT = (PFNGLVARIANTSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantsvEXT")) == NULL) || r;
+ r = ((glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantubvEXT")) == NULL) || r;
+ r = ((glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantuivEXT")) == NULL) || r;
+ r = ((glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantusvEXT")) == NULL) || r;
+ r = ((glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glWriteMaskEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_shader */
+
+#ifdef GL_EXT_vertex_weighting
+
+static GLboolean _glewInit_GL_EXT_vertex_weighting ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightPointerEXT")) == NULL) || r;
+ r = ((glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfEXT")) == NULL) || r;
+ r = ((glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_weighting */
+
+#ifdef GL_EXT_win32_keyed_mutex
+
+static GLboolean _glewInit_GL_EXT_win32_keyed_mutex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAcquireKeyedMutexWin32EXT = (PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC)glewGetProcAddress((const GLubyte*)"glAcquireKeyedMutexWin32EXT")) == NULL) || r;
+ r = ((glReleaseKeyedMutexWin32EXT = (PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC)glewGetProcAddress((const GLubyte*)"glReleaseKeyedMutexWin32EXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_win32_keyed_mutex */
+
+#ifdef GL_EXT_window_rectangles
+
+static GLboolean _glewInit_GL_EXT_window_rectangles ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glWindowRectanglesEXT = (PFNGLWINDOWRECTANGLESEXTPROC)glewGetProcAddress((const GLubyte*)"glWindowRectanglesEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_window_rectangles */
+
+#ifdef GL_EXT_x11_sync_object
+
+static GLboolean _glewInit_GL_EXT_x11_sync_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glImportSyncEXT = (PFNGLIMPORTSYNCEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSyncEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_x11_sync_object */
+
+#ifdef GL_GREMEDY_frame_terminator
+
+static GLboolean _glewInit_GL_GREMEDY_frame_terminator ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFrameTerminatorGREMEDY = (PFNGLFRAMETERMINATORGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glFrameTerminatorGREMEDY")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_GREMEDY_frame_terminator */
+
+#ifdef GL_GREMEDY_string_marker
+
+static GLboolean _glewInit_GL_GREMEDY_string_marker ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glStringMarkerGREMEDY")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_GREMEDY_string_marker */
+
+#ifdef GL_HP_image_transform
+
+static GLboolean _glewInit_GL_HP_image_transform ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterfvHP")) == NULL) || r;
+ r = ((glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterivHP")) == NULL) || r;
+ r = ((glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfHP")) == NULL) || r;
+ r = ((glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfvHP")) == NULL) || r;
+ r = ((glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameteriHP")) == NULL) || r;
+ r = ((glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterivHP")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_HP_image_transform */
+
+#ifdef GL_IBM_multimode_draw_arrays
+
+static GLboolean _glewInit_GL_IBM_multimode_draw_arrays ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawArraysIBM")) == NULL) || r;
+ r = ((glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawElementsIBM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_IBM_multimode_draw_arrays */
+
+#ifdef GL_IBM_vertex_array_lists
+
+static GLboolean _glewInit_GL_IBM_vertex_array_lists ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glColorPointerListIBM")) == NULL) || r;
+ r = ((glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerListIBM")) == NULL) || r;
+ r = ((glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerListIBM")) == NULL) || r;
+ r = ((glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerListIBM")) == NULL) || r;
+ r = ((glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerListIBM")) == NULL) || r;
+ r = ((glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerListIBM")) == NULL) || r;
+ r = ((glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerListIBM")) == NULL) || r;
+ r = ((glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerListIBM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_IBM_vertex_array_lists */
+
+#ifdef GL_INTEL_map_texture
+
+static GLboolean _glewInit_GL_INTEL_map_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMapTexture2DINTEL = (PFNGLMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glMapTexture2DINTEL")) == NULL) || r;
+ r = ((glSyncTextureINTEL = (PFNGLSYNCTEXTUREINTELPROC)glewGetProcAddress((const GLubyte*)"glSyncTextureINTEL")) == NULL) || r;
+ r = ((glUnmapTexture2DINTEL = (PFNGLUNMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glUnmapTexture2DINTEL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_INTEL_map_texture */
+
+#ifdef GL_INTEL_parallel_arrays
+
+static GLboolean _glewInit_GL_INTEL_parallel_arrays ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glColorPointervINTEL")) == NULL) || r;
+ r = ((glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glNormalPointervINTEL")) == NULL) || r;
+ r = ((glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointervINTEL")) == NULL) || r;
+ r = ((glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glVertexPointervINTEL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_INTEL_parallel_arrays */
+
+#ifdef GL_INTEL_performance_query
+
+static GLboolean _glewInit_GL_INTEL_performance_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginPerfQueryINTEL = (PFNGLBEGINPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfQueryINTEL")) == NULL) || r;
+ r = ((glCreatePerfQueryINTEL = (PFNGLCREATEPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glCreatePerfQueryINTEL")) == NULL) || r;
+ r = ((glDeletePerfQueryINTEL = (PFNGLDELETEPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfQueryINTEL")) == NULL) || r;
+ r = ((glEndPerfQueryINTEL = (PFNGLENDPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glEndPerfQueryINTEL")) == NULL) || r;
+ r = ((glGetFirstPerfQueryIdINTEL = (PFNGLGETFIRSTPERFQUERYIDINTELPROC)glewGetProcAddress((const GLubyte*)"glGetFirstPerfQueryIdINTEL")) == NULL) || r;
+ r = ((glGetNextPerfQueryIdINTEL = (PFNGLGETNEXTPERFQUERYIDINTELPROC)glewGetProcAddress((const GLubyte*)"glGetNextPerfQueryIdINTEL")) == NULL) || r;
+ r = ((glGetPerfCounterInfoINTEL = (PFNGLGETPERFCOUNTERINFOINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfCounterInfoINTEL")) == NULL) || r;
+ r = ((glGetPerfQueryDataINTEL = (PFNGLGETPERFQUERYDATAINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryDataINTEL")) == NULL) || r;
+ r = ((glGetPerfQueryIdByNameINTEL = (PFNGLGETPERFQUERYIDBYNAMEINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryIdByNameINTEL")) == NULL) || r;
+ r = ((glGetPerfQueryInfoINTEL = (PFNGLGETPERFQUERYINFOINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryInfoINTEL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_INTEL_performance_query */
+
+#ifdef GL_INTEL_texture_scissor
+
+static GLboolean _glewInit_GL_INTEL_texture_scissor ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexScissorFuncINTEL = (PFNGLTEXSCISSORFUNCINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorFuncINTEL")) == NULL) || r;
+ r = ((glTexScissorINTEL = (PFNGLTEXSCISSORINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorINTEL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_INTEL_texture_scissor */
+
+#ifdef GL_KHR_blend_equation_advanced
+
+static GLboolean _glewInit_GL_KHR_blend_equation_advanced ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendBarrierKHR = (PFNGLBLENDBARRIERKHRPROC)glewGetProcAddress((const GLubyte*)"glBlendBarrierKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifdef GL_KHR_debug
+
+static GLboolean _glewInit_GL_KHR_debug ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallback")) == NULL) || r;
+ r = ((glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControl")) == NULL) || r;
+ r = ((glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsert")) == NULL) || r;
+ r = ((glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLog")) == NULL) || r;
+ r = ((glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectLabel")) == NULL) || r;
+ r = ((glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectPtrLabel")) == NULL) || r;
+ r = ((glObjectLabel = (PFNGLOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectLabel")) == NULL) || r;
+ r = ((glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectPtrLabel")) == NULL) || r;
+ r = ((glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPopDebugGroup")) == NULL) || r;
+ r = ((glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPushDebugGroup")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_KHR_debug */
+
+#ifdef GL_KHR_parallel_shader_compile
+
+static GLboolean _glewInit_GL_KHR_parallel_shader_compile ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMaxShaderCompilerThreadsKHR = (PFNGLMAXSHADERCOMPILERTHREADSKHRPROC)glewGetProcAddress((const GLubyte*)"glMaxShaderCompilerThreadsKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_KHR_parallel_shader_compile */
+
+#ifdef GL_KHR_robustness
+
+static GLboolean _glewInit_GL_KHR_robustness ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformfv")) == NULL) || r;
+ r = ((glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformiv")) == NULL) || r;
+ r = ((glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformuiv")) == NULL) || r;
+ r = ((glReadnPixels = (PFNGLREADNPIXELSPROC)glewGetProcAddress((const GLubyte*)"glReadnPixels")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_KHR_robustness */
+
+#ifdef GL_KTX_buffer_region
+
+static GLboolean _glewInit_GL_KTX_buffer_region ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferRegionEnabled = (PFNGLBUFFERREGIONENABLEDPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabled")) == NULL) || r;
+ r = ((glDeleteBufferRegion = (PFNGLDELETEBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegion")) == NULL) || r;
+ r = ((glDrawBufferRegion = (PFNGLDRAWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegion")) == NULL) || r;
+ r = ((glNewBufferRegion = (PFNGLNEWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegion")) == NULL) || r;
+ r = ((glReadBufferRegion = (PFNGLREADBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegion")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_KTX_buffer_region */
+
+#ifdef GL_MESA_resize_buffers
+
+static GLboolean _glewInit_GL_MESA_resize_buffers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glResizeBuffersMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_MESA_resize_buffers */
+
+#ifdef GL_MESA_window_pos
+
+static GLboolean _glewInit_GL_MESA_window_pos ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dMESA")) == NULL) || r;
+ r = ((glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvMESA")) == NULL) || r;
+ r = ((glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fMESA")) == NULL) || r;
+ r = ((glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvMESA")) == NULL) || r;
+ r = ((glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iMESA")) == NULL) || r;
+ r = ((glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivMESA")) == NULL) || r;
+ r = ((glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sMESA")) == NULL) || r;
+ r = ((glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svMESA")) == NULL) || r;
+ r = ((glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dMESA")) == NULL) || r;
+ r = ((glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvMESA")) == NULL) || r;
+ r = ((glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fMESA")) == NULL) || r;
+ r = ((glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvMESA")) == NULL) || r;
+ r = ((glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iMESA")) == NULL) || r;
+ r = ((glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivMESA")) == NULL) || r;
+ r = ((glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sMESA")) == NULL) || r;
+ r = ((glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svMESA")) == NULL) || r;
+ r = ((glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dMESA")) == NULL) || r;
+ r = ((glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dvMESA")) == NULL) || r;
+ r = ((glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fMESA")) == NULL) || r;
+ r = ((glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fvMESA")) == NULL) || r;
+ r = ((glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4iMESA")) == NULL) || r;
+ r = ((glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4ivMESA")) == NULL) || r;
+ r = ((glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4sMESA")) == NULL) || r;
+ r = ((glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4svMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_MESA_window_pos */
+
+#ifdef GL_NVX_conditional_render
+
+static GLboolean _glewInit_GL_NVX_conditional_render ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginConditionalRenderNVX = (PFNGLBEGINCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNVX")) == NULL) || r;
+ r = ((glEndConditionalRenderNVX = (PFNGLENDCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNVX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NVX_conditional_render */
+
+#ifdef GL_NVX_linked_gpu_multicast
+
+static GLboolean _glewInit_GL_NVX_linked_gpu_multicast ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLGPUCopyImageSubDataNVX = (PFNGLLGPUCOPYIMAGESUBDATANVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUCopyImageSubDataNVX")) == NULL) || r;
+ r = ((glLGPUInterlockNVX = (PFNGLLGPUINTERLOCKNVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUInterlockNVX")) == NULL) || r;
+ r = ((glLGPUNamedBufferSubDataNVX = (PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUNamedBufferSubDataNVX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NVX_linked_gpu_multicast */
+
+#ifdef GL_NV_3dvision_settings
+
+static GLboolean _glewInit_GL_NV_3dvision_settings ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glStereoParameterfNV = (PFNGLSTEREOPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glStereoParameterfNV")) == NULL) || r;
+ r = ((glStereoParameteriNV = (PFNGLSTEREOPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glStereoParameteriNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_3dvision_settings */
+
+#ifdef GL_NV_bindless_multi_draw_indirect
+
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectBindlessNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectBindlessNV")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectBindlessNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectBindlessNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_bindless_multi_draw_indirect */
+
+#ifdef GL_NV_bindless_multi_draw_indirect_count
+
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectBindlessCountNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectBindlessCountNV")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectBindlessCountNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectBindlessCountNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_bindless_multi_draw_indirect_count */
+
+#ifdef GL_NV_bindless_texture
+
+static GLboolean _glewInit_GL_NV_bindless_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetImageHandleNV = (PFNGLGETIMAGEHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleNV")) == NULL) || r;
+ r = ((glGetTextureHandleNV = (PFNGLGETTEXTUREHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleNV")) == NULL) || r;
+ r = ((glGetTextureSamplerHandleNV = (PFNGLGETTEXTURESAMPLERHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleNV")) == NULL) || r;
+ r = ((glIsImageHandleResidentNV = (PFNGLISIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentNV")) == NULL) || r;
+ r = ((glIsTextureHandleResidentNV = (PFNGLISTEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentNV")) == NULL) || r;
+ r = ((glMakeImageHandleNonResidentNV = (PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentNV")) == NULL) || r;
+ r = ((glMakeImageHandleResidentNV = (PFNGLMAKEIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentNV")) == NULL) || r;
+ r = ((glMakeTextureHandleNonResidentNV = (PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentNV")) == NULL) || r;
+ r = ((glMakeTextureHandleResidentNV = (PFNGLMAKETEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentNV")) == NULL) || r;
+ r = ((glProgramUniformHandleui64NV = (PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64NV")) == NULL) || r;
+ r = ((glProgramUniformHandleui64vNV = (PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vNV")) == NULL) || r;
+ r = ((glUniformHandleui64NV = (PFNGLUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64NV")) == NULL) || r;
+ r = ((glUniformHandleui64vNV = (PFNGLUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_bindless_texture */
+
+#ifdef GL_NV_blend_equation_advanced
+
+static GLboolean _glewInit_GL_NV_blend_equation_advanced ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendBarrierNV = (PFNGLBLENDBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glBlendBarrierNV")) == NULL) || r;
+ r = ((glBlendParameteriNV = (PFNGLBLENDPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glBlendParameteriNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_blend_equation_advanced */
+
+#ifdef GL_NV_clip_space_w_scaling
+
+static GLboolean _glewInit_GL_NV_clip_space_w_scaling ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glViewportPositionWScaleNV = (PFNGLVIEWPORTPOSITIONWSCALENVPROC)glewGetProcAddress((const GLubyte*)"glViewportPositionWScaleNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_clip_space_w_scaling */
+
+#ifdef GL_NV_command_list
+
+static GLboolean _glewInit_GL_NV_command_list ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCallCommandListNV = (PFNGLCALLCOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glCallCommandListNV")) == NULL) || r;
+ r = ((glCommandListSegmentsNV = (PFNGLCOMMANDLISTSEGMENTSNVPROC)glewGetProcAddress((const GLubyte*)"glCommandListSegmentsNV")) == NULL) || r;
+ r = ((glCompileCommandListNV = (PFNGLCOMPILECOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glCompileCommandListNV")) == NULL) || r;
+ r = ((glCreateCommandListsNV = (PFNGLCREATECOMMANDLISTSNVPROC)glewGetProcAddress((const GLubyte*)"glCreateCommandListsNV")) == NULL) || r;
+ r = ((glCreateStatesNV = (PFNGLCREATESTATESNVPROC)glewGetProcAddress((const GLubyte*)"glCreateStatesNV")) == NULL) || r;
+ r = ((glDeleteCommandListsNV = (PFNGLDELETECOMMANDLISTSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteCommandListsNV")) == NULL) || r;
+ r = ((glDeleteStatesNV = (PFNGLDELETESTATESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteStatesNV")) == NULL) || r;
+ r = ((glDrawCommandsAddressNV = (PFNGLDRAWCOMMANDSADDRESSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsAddressNV")) == NULL) || r;
+ r = ((glDrawCommandsNV = (PFNGLDRAWCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsNV")) == NULL) || r;
+ r = ((glDrawCommandsStatesAddressNV = (PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsStatesAddressNV")) == NULL) || r;
+ r = ((glDrawCommandsStatesNV = (PFNGLDRAWCOMMANDSSTATESNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsStatesNV")) == NULL) || r;
+ r = ((glGetCommandHeaderNV = (PFNGLGETCOMMANDHEADERNVPROC)glewGetProcAddress((const GLubyte*)"glGetCommandHeaderNV")) == NULL) || r;
+ r = ((glGetStageIndexNV = (PFNGLGETSTAGEINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glGetStageIndexNV")) == NULL) || r;
+ r = ((glIsCommandListNV = (PFNGLISCOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glIsCommandListNV")) == NULL) || r;
+ r = ((glIsStateNV = (PFNGLISSTATENVPROC)glewGetProcAddress((const GLubyte*)"glIsStateNV")) == NULL) || r;
+ r = ((glListDrawCommandsStatesClientNV = (PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC)glewGetProcAddress((const GLubyte*)"glListDrawCommandsStatesClientNV")) == NULL) || r;
+ r = ((glStateCaptureNV = (PFNGLSTATECAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glStateCaptureNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_command_list */
+
+#ifdef GL_NV_conditional_render
+
+static GLboolean _glewInit_GL_NV_conditional_render ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNV")) == NULL) || r;
+ r = ((glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_conditional_render */
+
+#ifdef GL_NV_conservative_raster
+
+static GLboolean _glewInit_GL_NV_conservative_raster ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSubpixelPrecisionBiasNV = (PFNGLSUBPIXELPRECISIONBIASNVPROC)glewGetProcAddress((const GLubyte*)"glSubpixelPrecisionBiasNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_conservative_raster */
+
+#ifdef GL_NV_conservative_raster_dilate
+
+static GLboolean _glewInit_GL_NV_conservative_raster_dilate ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glConservativeRasterParameterfNV = (PFNGLCONSERVATIVERASTERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glConservativeRasterParameterfNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_conservative_raster_dilate */
+
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+
+static GLboolean _glewInit_GL_NV_conservative_raster_pre_snap_triangles ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glConservativeRasterParameteriNV = (PFNGLCONSERVATIVERASTERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glConservativeRasterParameteriNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+
+#ifdef GL_NV_copy_buffer
+
+static GLboolean _glewInit_GL_NV_copy_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyBufferSubDataNV = (PFNGLCOPYBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glCopyBufferSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_copy_buffer */
+
+#ifdef GL_NV_copy_image
+
+static GLboolean _glewInit_GL_NV_copy_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_copy_image */
+
+#ifdef GL_NV_depth_buffer_float
+
+static GLboolean _glewInit_GL_NV_depth_buffer_float ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)glewGetProcAddress((const GLubyte*)"glClearDepthdNV")) == NULL) || r;
+ r = ((glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsdNV")) == NULL) || r;
+ r = ((glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangedNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_depth_buffer_float */
+
+#ifdef GL_NV_draw_buffers
+
+static GLboolean _glewInit_GL_NV_draw_buffers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawBuffersNV = (PFNGLDRAWBUFFERSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_draw_buffers */
+
+#ifdef GL_NV_draw_instanced
+
+static GLboolean _glewInit_GL_NV_draw_instanced ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedNV")) == NULL) || r;
+ r = ((glDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_draw_instanced */
+
+#ifdef GL_NV_draw_texture
+
+static GLboolean _glewInit_GL_NV_draw_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawTextureNV = (PFNGLDRAWTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glDrawTextureNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_draw_texture */
+
+#ifdef GL_NV_draw_vulkan_image
+
+static GLboolean _glewInit_GL_NV_draw_vulkan_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawVkImageNV = (PFNGLDRAWVKIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glDrawVkImageNV")) == NULL) || r;
+ r = ((glGetVkProcAddrNV = (PFNGLGETVKPROCADDRNVPROC)glewGetProcAddress((const GLubyte*)"glGetVkProcAddrNV")) == NULL) || r;
+ r = ((glSignalVkFenceNV = (PFNGLSIGNALVKFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSignalVkFenceNV")) == NULL) || r;
+ r = ((glSignalVkSemaphoreNV = (PFNGLSIGNALVKSEMAPHORENVPROC)glewGetProcAddress((const GLubyte*)"glSignalVkSemaphoreNV")) == NULL) || r;
+ r = ((glWaitVkSemaphoreNV = (PFNGLWAITVKSEMAPHORENVPROC)glewGetProcAddress((const GLubyte*)"glWaitVkSemaphoreNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_draw_vulkan_image */
+
+#ifdef GL_NV_evaluators
+
+static GLboolean _glewInit_GL_NV_evaluators ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glEvalMapsNV = (PFNGLEVALMAPSNVPROC)glewGetProcAddress((const GLubyte*)"glEvalMapsNV")) == NULL) || r;
+ r = ((glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterfvNV")) == NULL) || r;
+ r = ((glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterivNV")) == NULL) || r;
+ r = ((glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapControlPointsNV")) == NULL) || r;
+ r = ((glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterfvNV")) == NULL) || r;
+ r = ((glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterivNV")) == NULL) || r;
+ r = ((glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glMapControlPointsNV")) == NULL) || r;
+ r = ((glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterfvNV")) == NULL) || r;
+ r = ((glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_evaluators */
+
+#ifdef GL_NV_explicit_multisample
+
+static GLboolean _glewInit_GL_NV_explicit_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefvNV")) == NULL) || r;
+ r = ((glSampleMaskIndexedNV = (PFNGLSAMPLEMASKINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskIndexedNV")) == NULL) || r;
+ r = ((glTexRenderbufferNV = (PFNGLTEXRENDERBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glTexRenderbufferNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_explicit_multisample */
+
+#ifdef GL_NV_fence
+
+static GLboolean _glewInit_GL_NV_fence ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesNV")) == NULL) || r;
+ r = ((glFinishFenceNV = (PFNGLFINISHFENCENVPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceNV")) == NULL) || r;
+ r = ((glGenFencesNV = (PFNGLGENFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glGenFencesNV")) == NULL) || r;
+ r = ((glGetFenceivNV = (PFNGLGETFENCEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFenceivNV")) == NULL) || r;
+ r = ((glIsFenceNV = (PFNGLISFENCENVPROC)glewGetProcAddress((const GLubyte*)"glIsFenceNV")) == NULL) || r;
+ r = ((glSetFenceNV = (PFNGLSETFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSetFenceNV")) == NULL) || r;
+ r = ((glTestFenceNV = (PFNGLTESTFENCENVPROC)glewGetProcAddress((const GLubyte*)"glTestFenceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_fence */
+
+#ifdef GL_NV_fragment_coverage_to_color
+
+static GLboolean _glewInit_GL_NV_fragment_coverage_to_color ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFragmentCoverageColorNV = (PFNGLFRAGMENTCOVERAGECOLORNVPROC)glewGetProcAddress((const GLubyte*)"glFragmentCoverageColorNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_fragment_coverage_to_color */
+
+#ifdef GL_NV_fragment_program
+
+static GLboolean _glewInit_GL_NV_fragment_program ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterdvNV")) == NULL) || r;
+ r = ((glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterfvNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dvNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_fragment_program */
+
+#ifdef GL_NV_framebuffer_blit
+
+static GLboolean _glewInit_GL_NV_framebuffer_blit ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_framebuffer_blit */
+
+#ifdef GL_NV_framebuffer_multisample
+
+static GLboolean _glewInit_GL_NV_framebuffer_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_framebuffer_multisample */
+
+#ifdef GL_NV_framebuffer_multisample_coverage
+
+static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleCoverageNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleCoverageNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_framebuffer_multisample_coverage */
+
+#ifdef GL_NV_geometry_program4
+
+static GLboolean _glewInit_GL_NV_geometry_program4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramVertexLimitNV = (PFNGLPROGRAMVERTEXLIMITNVPROC)glewGetProcAddress((const GLubyte*)"glProgramVertexLimitNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_geometry_program4 */
+
+#ifdef GL_NV_gpu_multicast
+
+static GLboolean _glewInit_GL_NV_gpu_multicast ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMulticastBarrierNV = (PFNGLMULTICASTBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBarrierNV")) == NULL) || r;
+ r = ((glMulticastBlitFramebufferNV = (PFNGLMULTICASTBLITFRAMEBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBlitFramebufferNV")) == NULL) || r;
+ r = ((glMulticastBufferSubDataNV = (PFNGLMULTICASTBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBufferSubDataNV")) == NULL) || r;
+ r = ((glMulticastCopyBufferSubDataNV = (PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastCopyBufferSubDataNV")) == NULL) || r;
+ r = ((glMulticastCopyImageSubDataNV = (PFNGLMULTICASTCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastCopyImageSubDataNV")) == NULL) || r;
+ r = ((glMulticastFramebufferSampleLocationsfvNV = (PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastFramebufferSampleLocationsfvNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjecti64vNV = (PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjecti64vNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjectivNV = (PFNGLMULTICASTGETQUERYOBJECTIVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectivNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjectui64vNV = (PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectui64vNV")) == NULL) || r;
+ r = ((glMulticastGetQueryObjectuivNV = (PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectuivNV")) == NULL) || r;
+ r = ((glMulticastWaitSyncNV = (PFNGLMULTICASTWAITSYNCNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastWaitSyncNV")) == NULL) || r;
+ r = ((glRenderGpuMaskNV = (PFNGLRENDERGPUMASKNVPROC)glewGetProcAddress((const GLubyte*)"glRenderGpuMaskNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_gpu_multicast */
+
+#ifdef GL_NV_gpu_program4
+
+static GLboolean _glewInit_GL_NV_gpu_program4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramEnvParameterI4iNV = (PFNGLPROGRAMENVPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4iNV")) == NULL) || r;
+ r = ((glProgramEnvParameterI4ivNV = (PFNGLPROGRAMENVPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4ivNV")) == NULL) || r;
+ r = ((glProgramEnvParameterI4uiNV = (PFNGLPROGRAMENVPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uiNV")) == NULL) || r;
+ r = ((glProgramEnvParameterI4uivNV = (PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uivNV")) == NULL) || r;
+ r = ((glProgramEnvParametersI4ivNV = (PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4ivNV")) == NULL) || r;
+ r = ((glProgramEnvParametersI4uivNV = (PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4uivNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4iNV = (PFNGLPROGRAMLOCALPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4iNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4ivNV = (PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4ivNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4uiNV = (PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uiNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4uivNV = (PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uivNV")) == NULL) || r;
+ r = ((glProgramLocalParametersI4ivNV = (PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4ivNV")) == NULL) || r;
+ r = ((glProgramLocalParametersI4uivNV = (PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4uivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_gpu_program4 */
+
+#ifdef GL_NV_gpu_shader5
+
+static GLboolean _glewInit_GL_NV_gpu_shader5 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetUniformi64vNV = (PFNGLGETUNIFORMI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformi64vNV")) == NULL) || r;
+ r = ((glGetUniformui64vNV = (PFNGLGETUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformui64vNV")) == NULL) || r;
+ r = ((glProgramUniform1i64NV = (PFNGLPROGRAMUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64NV")) == NULL) || r;
+ r = ((glProgramUniform1i64vNV = (PFNGLPROGRAMUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64vNV")) == NULL) || r;
+ r = ((glProgramUniform1ui64NV = (PFNGLPROGRAMUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64NV")) == NULL) || r;
+ r = ((glProgramUniform1ui64vNV = (PFNGLPROGRAMUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64vNV")) == NULL) || r;
+ r = ((glProgramUniform2i64NV = (PFNGLPROGRAMUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64NV")) == NULL) || r;
+ r = ((glProgramUniform2i64vNV = (PFNGLPROGRAMUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64vNV")) == NULL) || r;
+ r = ((glProgramUniform2ui64NV = (PFNGLPROGRAMUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64NV")) == NULL) || r;
+ r = ((glProgramUniform2ui64vNV = (PFNGLPROGRAMUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64vNV")) == NULL) || r;
+ r = ((glProgramUniform3i64NV = (PFNGLPROGRAMUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64NV")) == NULL) || r;
+ r = ((glProgramUniform3i64vNV = (PFNGLPROGRAMUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64vNV")) == NULL) || r;
+ r = ((glProgramUniform3ui64NV = (PFNGLPROGRAMUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64NV")) == NULL) || r;
+ r = ((glProgramUniform3ui64vNV = (PFNGLPROGRAMUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64vNV")) == NULL) || r;
+ r = ((glProgramUniform4i64NV = (PFNGLPROGRAMUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64NV")) == NULL) || r;
+ r = ((glProgramUniform4i64vNV = (PFNGLPROGRAMUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64vNV")) == NULL) || r;
+ r = ((glProgramUniform4ui64NV = (PFNGLPROGRAMUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64NV")) == NULL) || r;
+ r = ((glProgramUniform4ui64vNV = (PFNGLPROGRAMUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64vNV")) == NULL) || r;
+ r = ((glUniform1i64NV = (PFNGLUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64NV")) == NULL) || r;
+ r = ((glUniform1i64vNV = (PFNGLUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64vNV")) == NULL) || r;
+ r = ((glUniform1ui64NV = (PFNGLUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64NV")) == NULL) || r;
+ r = ((glUniform1ui64vNV = (PFNGLUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64vNV")) == NULL) || r;
+ r = ((glUniform2i64NV = (PFNGLUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64NV")) == NULL) || r;
+ r = ((glUniform2i64vNV = (PFNGLUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64vNV")) == NULL) || r;
+ r = ((glUniform2ui64NV = (PFNGLUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64NV")) == NULL) || r;
+ r = ((glUniform2ui64vNV = (PFNGLUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64vNV")) == NULL) || r;
+ r = ((glUniform3i64NV = (PFNGLUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64NV")) == NULL) || r;
+ r = ((glUniform3i64vNV = (PFNGLUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64vNV")) == NULL) || r;
+ r = ((glUniform3ui64NV = (PFNGLUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64NV")) == NULL) || r;
+ r = ((glUniform3ui64vNV = (PFNGLUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64vNV")) == NULL) || r;
+ r = ((glUniform4i64NV = (PFNGLUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64NV")) == NULL) || r;
+ r = ((glUniform4i64vNV = (PFNGLUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64vNV")) == NULL) || r;
+ r = ((glUniform4ui64NV = (PFNGLUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64NV")) == NULL) || r;
+ r = ((glUniform4ui64vNV = (PFNGLUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64vNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_gpu_shader5 */
+
+#ifdef GL_NV_half_float
+
+static GLboolean _glewInit_GL_NV_half_float ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColor3hNV = (PFNGLCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hNV")) == NULL) || r;
+ r = ((glColor3hvNV = (PFNGLCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hvNV")) == NULL) || r;
+ r = ((glColor4hNV = (PFNGLCOLOR4HNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hNV")) == NULL) || r;
+ r = ((glColor4hvNV = (PFNGLCOLOR4HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hvNV")) == NULL) || r;
+ r = ((glFogCoordhNV = (PFNGLFOGCOORDHNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhNV")) == NULL) || r;
+ r = ((glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhvNV")) == NULL) || r;
+ r = ((glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hNV")) == NULL) || r;
+ r = ((glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hvNV")) == NULL) || r;
+ r = ((glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hNV")) == NULL) || r;
+ r = ((glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hvNV")) == NULL) || r;
+ r = ((glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hNV")) == NULL) || r;
+ r = ((glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hvNV")) == NULL) || r;
+ r = ((glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hNV")) == NULL) || r;
+ r = ((glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hvNV")) == NULL) || r;
+ r = ((glNormal3hNV = (PFNGLNORMAL3HNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hNV")) == NULL) || r;
+ r = ((glNormal3hvNV = (PFNGLNORMAL3HVNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hvNV")) == NULL) || r;
+ r = ((glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hNV")) == NULL) || r;
+ r = ((glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hvNV")) == NULL) || r;
+ r = ((glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hNV")) == NULL) || r;
+ r = ((glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hvNV")) == NULL) || r;
+ r = ((glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hNV")) == NULL) || r;
+ r = ((glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hvNV")) == NULL) || r;
+ r = ((glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hNV")) == NULL) || r;
+ r = ((glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hvNV")) == NULL) || r;
+ r = ((glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hNV")) == NULL) || r;
+ r = ((glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hvNV")) == NULL) || r;
+ r = ((glVertex2hNV = (PFNGLVERTEX2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hNV")) == NULL) || r;
+ r = ((glVertex2hvNV = (PFNGLVERTEX2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hvNV")) == NULL) || r;
+ r = ((glVertex3hNV = (PFNGLVERTEX3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hNV")) == NULL) || r;
+ r = ((glVertex3hvNV = (PFNGLVERTEX3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hvNV")) == NULL) || r;
+ r = ((glVertex4hNV = (PFNGLVERTEX4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hNV")) == NULL) || r;
+ r = ((glVertex4hvNV = (PFNGLVERTEX4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hvNV")) == NULL) || r;
+ r = ((glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hNV")) == NULL) || r;
+ r = ((glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hvNV")) == NULL) || r;
+ r = ((glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hNV")) == NULL) || r;
+ r = ((glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hvNV")) == NULL) || r;
+ r = ((glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hNV")) == NULL) || r;
+ r = ((glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hvNV")) == NULL) || r;
+ r = ((glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hNV")) == NULL) || r;
+ r = ((glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hvNV")) == NULL) || r;
+ r = ((glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1hvNV")) == NULL) || r;
+ r = ((glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2hvNV")) == NULL) || r;
+ r = ((glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3hvNV")) == NULL) || r;
+ r = ((glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4hvNV")) == NULL) || r;
+ r = ((glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthNV")) == NULL) || r;
+ r = ((glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_half_float */
+
+#ifdef GL_NV_instanced_arrays
+
+static GLboolean _glewInit_GL_NV_instanced_arrays ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_instanced_arrays */
+
+#ifdef GL_NV_internalformat_sample_query
+
+static GLboolean _glewInit_GL_NV_internalformat_sample_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetInternalformatSampleivNV = (PFNGLGETINTERNALFORMATSAMPLEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformatSampleivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_internalformat_sample_query */
+
+#ifdef GL_NV_non_square_matrices
+
+static GLboolean _glewInit_GL_NV_non_square_matrices ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glUniformMatrix2x3fvNV = (PFNGLUNIFORMMATRIX2X3FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fvNV")) == NULL) || r;
+ r = ((glUniformMatrix2x4fvNV = (PFNGLUNIFORMMATRIX2X4FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fvNV")) == NULL) || r;
+ r = ((glUniformMatrix3x2fvNV = (PFNGLUNIFORMMATRIX3X2FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fvNV")) == NULL) || r;
+ r = ((glUniformMatrix3x4fvNV = (PFNGLUNIFORMMATRIX3X4FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fvNV")) == NULL) || r;
+ r = ((glUniformMatrix4x2fvNV = (PFNGLUNIFORMMATRIX4X2FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fvNV")) == NULL) || r;
+ r = ((glUniformMatrix4x3fvNV = (PFNGLUNIFORMMATRIX4X3FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_non_square_matrices */
+
+#ifdef GL_NV_occlusion_query
+
+static GLboolean _glewInit_GL_NV_occlusion_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glBeginOcclusionQueryNV")) == NULL) || r;
+ r = ((glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteOcclusionQueriesNV")) == NULL) || r;
+ r = ((glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glEndOcclusionQueryNV")) == NULL) || r;
+ r = ((glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glGenOcclusionQueriesNV")) == NULL) || r;
+ r = ((glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryivNV")) == NULL) || r;
+ r = ((glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryuivNV")) == NULL) || r;
+ r = ((glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glIsOcclusionQueryNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_occlusion_query */
+
+#ifdef GL_NV_parameter_buffer_object
+
+static GLboolean _glewInit_GL_NV_parameter_buffer_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramBufferParametersIivNV = (PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIivNV")) == NULL) || r;
+ r = ((glProgramBufferParametersIuivNV = (PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIuivNV")) == NULL) || r;
+ r = ((glProgramBufferParametersfvNV = (PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersfvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_parameter_buffer_object */
+
+#ifdef GL_NV_path_rendering
+
+static GLboolean _glewInit_GL_NV_path_rendering ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyPathNV = (PFNGLCOPYPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCopyPathNV")) == NULL) || r;
+ r = ((glCoverFillPathInstancedNV = (PFNGLCOVERFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathInstancedNV")) == NULL) || r;
+ r = ((glCoverFillPathNV = (PFNGLCOVERFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathNV")) == NULL) || r;
+ r = ((glCoverStrokePathInstancedNV = (PFNGLCOVERSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathInstancedNV")) == NULL) || r;
+ r = ((glCoverStrokePathNV = (PFNGLCOVERSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathNV")) == NULL) || r;
+ r = ((glDeletePathsNV = (PFNGLDELETEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glDeletePathsNV")) == NULL) || r;
+ r = ((glGenPathsNV = (PFNGLGENPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glGenPathsNV")) == NULL) || r;
+ r = ((glGetPathColorGenfvNV = (PFNGLGETPATHCOLORGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenfvNV")) == NULL) || r;
+ r = ((glGetPathColorGenivNV = (PFNGLGETPATHCOLORGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenivNV")) == NULL) || r;
+ r = ((glGetPathCommandsNV = (PFNGLGETPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCommandsNV")) == NULL) || r;
+ r = ((glGetPathCoordsNV = (PFNGLGETPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCoordsNV")) == NULL) || r;
+ r = ((glGetPathDashArrayNV = (PFNGLGETPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathDashArrayNV")) == NULL) || r;
+ r = ((glGetPathLengthNV = (PFNGLGETPATHLENGTHNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathLengthNV")) == NULL) || r;
+ r = ((glGetPathMetricRangeNV = (PFNGLGETPATHMETRICRANGENVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricRangeNV")) == NULL) || r;
+ r = ((glGetPathMetricsNV = (PFNGLGETPATHMETRICSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricsNV")) == NULL) || r;
+ r = ((glGetPathParameterfvNV = (PFNGLGETPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterfvNV")) == NULL) || r;
+ r = ((glGetPathParameterivNV = (PFNGLGETPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterivNV")) == NULL) || r;
+ r = ((glGetPathSpacingNV = (PFNGLGETPATHSPACINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathSpacingNV")) == NULL) || r;
+ r = ((glGetPathTexGenfvNV = (PFNGLGETPATHTEXGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenfvNV")) == NULL) || r;
+ r = ((glGetPathTexGenivNV = (PFNGLGETPATHTEXGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenivNV")) == NULL) || r;
+ r = ((glGetProgramResourcefvNV = (PFNGLGETPROGRAMRESOURCEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourcefvNV")) == NULL) || r;
+ r = ((glInterpolatePathsNV = (PFNGLINTERPOLATEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glInterpolatePathsNV")) == NULL) || r;
+ r = ((glIsPathNV = (PFNGLISPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPathNV")) == NULL) || r;
+ r = ((glIsPointInFillPathNV = (PFNGLISPOINTINFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInFillPathNV")) == NULL) || r;
+ r = ((glIsPointInStrokePathNV = (PFNGLISPOINTINSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInStrokePathNV")) == NULL) || r;
+ r = ((glMatrixLoad3x2fNV = (PFNGLMATRIXLOAD3X2FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoad3x2fNV")) == NULL) || r;
+ r = ((glMatrixLoad3x3fNV = (PFNGLMATRIXLOAD3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoad3x3fNV")) == NULL) || r;
+ r = ((glMatrixLoadTranspose3x3fNV = (PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTranspose3x3fNV")) == NULL) || r;
+ r = ((glMatrixMult3x2fNV = (PFNGLMATRIXMULT3X2FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixMult3x2fNV")) == NULL) || r;
+ r = ((glMatrixMult3x3fNV = (PFNGLMATRIXMULT3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixMult3x3fNV")) == NULL) || r;
+ r = ((glMatrixMultTranspose3x3fNV = (PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTranspose3x3fNV")) == NULL) || r;
+ r = ((glPathColorGenNV = (PFNGLPATHCOLORGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathColorGenNV")) == NULL) || r;
+ r = ((glPathCommandsNV = (PFNGLPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCommandsNV")) == NULL) || r;
+ r = ((glPathCoordsNV = (PFNGLPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoordsNV")) == NULL) || r;
+ r = ((glPathCoverDepthFuncNV = (PFNGLPATHCOVERDEPTHFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoverDepthFuncNV")) == NULL) || r;
+ r = ((glPathDashArrayNV = (PFNGLPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathDashArrayNV")) == NULL) || r;
+ r = ((glPathFogGenNV = (PFNGLPATHFOGGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathFogGenNV")) == NULL) || r;
+ r = ((glPathGlyphIndexArrayNV = (PFNGLPATHGLYPHINDEXARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphIndexArrayNV")) == NULL) || r;
+ r = ((glPathGlyphIndexRangeNV = (PFNGLPATHGLYPHINDEXRANGENVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphIndexRangeNV")) == NULL) || r;
+ r = ((glPathGlyphRangeNV = (PFNGLPATHGLYPHRANGENVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphRangeNV")) == NULL) || r;
+ r = ((glPathGlyphsNV = (PFNGLPATHGLYPHSNVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphsNV")) == NULL) || r;
+ r = ((glPathMemoryGlyphIndexArrayNV = (PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathMemoryGlyphIndexArrayNV")) == NULL) || r;
+ r = ((glPathParameterfNV = (PFNGLPATHPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfNV")) == NULL) || r;
+ r = ((glPathParameterfvNV = (PFNGLPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfvNV")) == NULL) || r;
+ r = ((glPathParameteriNV = (PFNGLPATHPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPathParameteriNV")) == NULL) || r;
+ r = ((glPathParameterivNV = (PFNGLPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterivNV")) == NULL) || r;
+ r = ((glPathStencilDepthOffsetNV = (PFNGLPATHSTENCILDEPTHOFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilDepthOffsetNV")) == NULL) || r;
+ r = ((glPathStencilFuncNV = (PFNGLPATHSTENCILFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilFuncNV")) == NULL) || r;
+ r = ((glPathStringNV = (PFNGLPATHSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glPathStringNV")) == NULL) || r;
+ r = ((glPathSubCommandsNV = (PFNGLPATHSUBCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCommandsNV")) == NULL) || r;
+ r = ((glPathSubCoordsNV = (PFNGLPATHSUBCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCoordsNV")) == NULL) || r;
+ r = ((glPathTexGenNV = (PFNGLPATHTEXGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathTexGenNV")) == NULL) || r;
+ r = ((glPointAlongPathNV = (PFNGLPOINTALONGPATHNVPROC)glewGetProcAddress((const GLubyte*)"glPointAlongPathNV")) == NULL) || r;
+ r = ((glProgramPathFragmentInputGenNV = (PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC)glewGetProcAddress((const GLubyte*)"glProgramPathFragmentInputGenNV")) == NULL) || r;
+ r = ((glStencilFillPathInstancedNV = (PFNGLSTENCILFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathInstancedNV")) == NULL) || r;
+ r = ((glStencilFillPathNV = (PFNGLSTENCILFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathNV")) == NULL) || r;
+ r = ((glStencilStrokePathInstancedNV = (PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathInstancedNV")) == NULL) || r;
+ r = ((glStencilStrokePathNV = (PFNGLSTENCILSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathNV")) == NULL) || r;
+ r = ((glStencilThenCoverFillPathInstancedNV = (PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverFillPathInstancedNV")) == NULL) || r;
+ r = ((glStencilThenCoverFillPathNV = (PFNGLSTENCILTHENCOVERFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverFillPathNV")) == NULL) || r;
+ r = ((glStencilThenCoverStrokePathInstancedNV = (PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverStrokePathInstancedNV")) == NULL) || r;
+ r = ((glStencilThenCoverStrokePathNV = (PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverStrokePathNV")) == NULL) || r;
+ r = ((glTransformPathNV = (PFNGLTRANSFORMPATHNVPROC)glewGetProcAddress((const GLubyte*)"glTransformPathNV")) == NULL) || r;
+ r = ((glWeightPathsNV = (PFNGLWEIGHTPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glWeightPathsNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_path_rendering */
+
+#ifdef GL_NV_pixel_data_range
+
+static GLboolean _glewInit_GL_NV_pixel_data_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushPixelDataRangeNV")) == NULL) || r;
+ r = ((glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glPixelDataRangeNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_pixel_data_range */
+
+#ifdef GL_NV_point_sprite
+
+static GLboolean _glewInit_GL_NV_point_sprite ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriNV")) == NULL) || r;
+ r = ((glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_point_sprite */
+
+#ifdef GL_NV_polygon_mode
+
+static GLboolean _glewInit_GL_NV_polygon_mode ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPolygonModeNV = (PFNGLPOLYGONMODENVPROC)glewGetProcAddress((const GLubyte*)"glPolygonModeNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_polygon_mode */
+
+#ifdef GL_NV_present_video
+
+static GLboolean _glewInit_GL_NV_present_video ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVideoi64vNV = (PFNGLGETVIDEOI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoi64vNV")) == NULL) || r;
+ r = ((glGetVideoivNV = (PFNGLGETVIDEOIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoivNV")) == NULL) || r;
+ r = ((glGetVideoui64vNV = (PFNGLGETVIDEOUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoui64vNV")) == NULL) || r;
+ r = ((glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideouivNV")) == NULL) || r;
+ r = ((glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameDualFillNV")) == NULL) || r;
+ r = ((glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameKeyedNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_present_video */
+
+#ifdef GL_NV_primitive_restart
+
+static GLboolean _glewInit_GL_NV_primitive_restart ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndexNV")) == NULL) || r;
+ r = ((glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_primitive_restart */
+
+#ifdef GL_NV_register_combiners
+
+static GLboolean _glewInit_GL_NV_register_combiners ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerInputNV")) == NULL) || r;
+ r = ((glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerOutputNV")) == NULL) || r;
+ r = ((glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfNV")) == NULL) || r;
+ r = ((glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfvNV")) == NULL) || r;
+ r = ((glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameteriNV")) == NULL) || r;
+ r = ((glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterivNV")) == NULL) || r;
+ r = ((glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glFinalCombinerInputNV")) == NULL) || r;
+ r = ((glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterfvNV")) == NULL) || r;
+ r = ((glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterivNV")) == NULL) || r;
+ r = ((glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterfvNV")) == NULL) || r;
+ r = ((glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterivNV")) == NULL) || r;
+ r = ((glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterfvNV")) == NULL) || r;
+ r = ((glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_register_combiners */
+
+#ifdef GL_NV_register_combiners2
+
+static GLboolean _glewInit_GL_NV_register_combiners2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerStageParameterfvNV")) == NULL) || r;
+ r = ((glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerStageParameterfvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_register_combiners2 */
+
+#ifdef GL_NV_sample_locations
+
+static GLboolean _glewInit_GL_NV_sample_locations ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferSampleLocationsfvNV = (PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)glewGetProcAddress((const GLubyte*)"glFramebufferSampleLocationsfvNV")) == NULL) || r;
+ r = ((glNamedFramebufferSampleLocationsfvNV = (PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferSampleLocationsfvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_sample_locations */
+
+#ifdef GL_NV_shader_buffer_load
+
+static GLboolean _glewInit_GL_NV_shader_buffer_load ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetBufferParameterui64vNV = (PFNGLGETBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterui64vNV")) == NULL) || r;
+ r = ((glGetIntegerui64vNV = (PFNGLGETINTEGERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64vNV")) == NULL) || r;
+ r = ((glGetNamedBufferParameterui64vNV = (PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterui64vNV")) == NULL) || r;
+ r = ((glIsBufferResidentNV = (PFNGLISBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsBufferResidentNV")) == NULL) || r;
+ r = ((glIsNamedBufferResidentNV = (PFNGLISNAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsNamedBufferResidentNV")) == NULL) || r;
+ r = ((glMakeBufferNonResidentNV = (PFNGLMAKEBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferNonResidentNV")) == NULL) || r;
+ r = ((glMakeBufferResidentNV = (PFNGLMAKEBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferResidentNV")) == NULL) || r;
+ r = ((glMakeNamedBufferNonResidentNV = (PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferNonResidentNV")) == NULL) || r;
+ r = ((glMakeNamedBufferResidentNV = (PFNGLMAKENAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferResidentNV")) == NULL) || r;
+ r = ((glProgramUniformui64NV = (PFNGLPROGRAMUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64NV")) == NULL) || r;
+ r = ((glProgramUniformui64vNV = (PFNGLPROGRAMUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64vNV")) == NULL) || r;
+ r = ((glUniformui64NV = (PFNGLUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64NV")) == NULL) || r;
+ r = ((glUniformui64vNV = (PFNGLUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64vNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_shader_buffer_load */
+
+#ifdef GL_NV_texture_array
+
+static GLboolean _glewInit_GL_NV_texture_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCompressedTexImage3DNV = (PFNGLCOMPRESSEDTEXIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DNV")) == NULL) || r;
+ r = ((glCompressedTexSubImage3DNV = (PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DNV")) == NULL) || r;
+ r = ((glCopyTexSubImage3DNV = (PFNGLCOPYTEXSUBIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DNV")) == NULL) || r;
+ r = ((glFramebufferTextureLayerNV = (PFNGLFRAMEBUFFERTEXTURELAYERNVPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerNV")) == NULL) || r;
+ r = ((glTexImage3DNV = (PFNGLTEXIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DNV")) == NULL) || r;
+ r = ((glTexSubImage3DNV = (PFNGLTEXSUBIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_texture_array */
+
+#ifdef GL_NV_texture_barrier
+
+static GLboolean _glewInit_GL_NV_texture_barrier ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureBarrierNV = (PFNGLTEXTUREBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glTextureBarrierNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_texture_barrier */
+
+#ifdef GL_NV_texture_multisample
+
+static GLboolean _glewInit_GL_NV_texture_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexImage2DMultisampleCoverageNV = (PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTexImage3DMultisampleCoverageNV = (PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTextureImage2DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTextureImage2DMultisampleNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleNV")) == NULL) || r;
+ r = ((glTextureImage3DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTextureImage3DMultisampleNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_texture_multisample */
+
+#ifdef GL_NV_transform_feedback
+
+static GLboolean _glewInit_GL_NV_transform_feedback ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveVaryingNV = (PFNGLACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glActiveVaryingNV")) == NULL) || r;
+ r = ((glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackNV")) == NULL) || r;
+ r = ((glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseNV")) == NULL) || r;
+ r = ((glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetNV")) == NULL) || r;
+ r = ((glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeNV")) == NULL) || r;
+ r = ((glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackNV")) == NULL) || r;
+ r = ((glGetActiveVaryingNV = (PFNGLGETACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveVaryingNV")) == NULL) || r;
+ r = ((glGetTransformFeedbackVaryingNV = (PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingNV")) == NULL) || r;
+ r = ((glGetVaryingLocationNV = (PFNGLGETVARYINGLOCATIONNVPROC)glewGetProcAddress((const GLubyte*)"glGetVaryingLocationNV")) == NULL) || r;
+ r = ((glTransformFeedbackAttribsNV = (PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackAttribsNV")) == NULL) || r;
+ r = ((glTransformFeedbackVaryingsNV = (PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_transform_feedback */
+
+#ifdef GL_NV_transform_feedback2
+
+static GLboolean _glewInit_GL_NV_transform_feedback2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindTransformFeedbackNV = (PFNGLBINDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedbackNV")) == NULL) || r;
+ r = ((glDeleteTransformFeedbacksNV = (PFNGLDELETETRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacksNV")) == NULL) || r;
+ r = ((glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackNV")) == NULL) || r;
+ r = ((glGenTransformFeedbacksNV = (PFNGLGENTRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacksNV")) == NULL) || r;
+ r = ((glIsTransformFeedbackNV = (PFNGLISTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedbackNV")) == NULL) || r;
+ r = ((glPauseTransformFeedbackNV = (PFNGLPAUSETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedbackNV")) == NULL) || r;
+ r = ((glResumeTransformFeedbackNV = (PFNGLRESUMETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedbackNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_transform_feedback2 */
+
+#ifdef GL_NV_vdpau_interop
+
+static GLboolean _glewInit_GL_NV_vdpau_interop ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVDPAUFiniNV = (PFNGLVDPAUFININVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUFiniNV")) == NULL) || r;
+ r = ((glVDPAUGetSurfaceivNV = (PFNGLVDPAUGETSURFACEIVNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUGetSurfaceivNV")) == NULL) || r;
+ r = ((glVDPAUInitNV = (PFNGLVDPAUINITNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUInitNV")) == NULL) || r;
+ r = ((glVDPAUIsSurfaceNV = (PFNGLVDPAUISSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUIsSurfaceNV")) == NULL) || r;
+ r = ((glVDPAUMapSurfacesNV = (PFNGLVDPAUMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUMapSurfacesNV")) == NULL) || r;
+ r = ((glVDPAURegisterOutputSurfaceNV = (PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterOutputSurfaceNV")) == NULL) || r;
+ r = ((glVDPAURegisterVideoSurfaceNV = (PFNGLVDPAUREGISTERVIDEOSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterVideoSurfaceNV")) == NULL) || r;
+ r = ((glVDPAUSurfaceAccessNV = (PFNGLVDPAUSURFACEACCESSNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUSurfaceAccessNV")) == NULL) || r;
+ r = ((glVDPAUUnmapSurfacesNV = (PFNGLVDPAUUNMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnmapSurfacesNV")) == NULL) || r;
+ r = ((glVDPAUUnregisterSurfaceNV = (PFNGLVDPAUUNREGISTERSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnregisterSurfaceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vdpau_interop */
+
+#ifdef GL_NV_vertex_array_range
+
+static GLboolean _glewInit_GL_NV_vertex_array_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeNV")) == NULL) || r;
+ r = ((glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_array_range */
+
+#ifdef GL_NV_vertex_attrib_integer_64bit
+
+static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribLi64vNV = (PFNGLGETVERTEXATTRIBLI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLi64vNV")) == NULL) || r;
+ r = ((glGetVertexAttribLui64vNV = (PFNGLGETVERTEXATTRIBLUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL1i64NV = (PFNGLVERTEXATTRIBL1I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64NV")) == NULL) || r;
+ r = ((glVertexAttribL1i64vNV = (PFNGLVERTEXATTRIBL1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL1ui64NV = (PFNGLVERTEXATTRIBL1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL1ui64vNV = (PFNGLVERTEXATTRIBL1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL2i64NV = (PFNGLVERTEXATTRIBL2I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64NV")) == NULL) || r;
+ r = ((glVertexAttribL2i64vNV = (PFNGLVERTEXATTRIBL2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL2ui64NV = (PFNGLVERTEXATTRIBL2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL2ui64vNV = (PFNGLVERTEXATTRIBL2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL3i64NV = (PFNGLVERTEXATTRIBL3I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64NV")) == NULL) || r;
+ r = ((glVertexAttribL3i64vNV = (PFNGLVERTEXATTRIBL3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL3ui64NV = (PFNGLVERTEXATTRIBL3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL3ui64vNV = (PFNGLVERTEXATTRIBL3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL4i64NV = (PFNGLVERTEXATTRIBL4I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64NV")) == NULL) || r;
+ r = ((glVertexAttribL4i64vNV = (PFNGLVERTEXATTRIBL4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL4ui64NV = (PFNGLVERTEXATTRIBL4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL4ui64vNV = (PFNGLVERTEXATTRIBL4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribLFormatNV = (PFNGLVERTEXATTRIBLFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormatNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_attrib_integer_64bit */
+
+#ifdef GL_NV_vertex_buffer_unified_memory
+
+static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferAddressRangeNV = (PFNGLBUFFERADDRESSRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBufferAddressRangeNV")) == NULL) || r;
+ r = ((glColorFormatNV = (PFNGLCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glColorFormatNV")) == NULL) || r;
+ r = ((glEdgeFlagFormatNV = (PFNGLEDGEFLAGFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagFormatNV")) == NULL) || r;
+ r = ((glFogCoordFormatNV = (PFNGLFOGCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordFormatNV")) == NULL) || r;
+ r = ((glGetIntegerui64i_vNV = (PFNGLGETINTEGERUI64I_VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64i_vNV")) == NULL) || r;
+ r = ((glIndexFormatNV = (PFNGLINDEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glIndexFormatNV")) == NULL) || r;
+ r = ((glNormalFormatNV = (PFNGLNORMALFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glNormalFormatNV")) == NULL) || r;
+ r = ((glSecondaryColorFormatNV = (PFNGLSECONDARYCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorFormatNV")) == NULL) || r;
+ r = ((glTexCoordFormatNV = (PFNGLTEXCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordFormatNV")) == NULL) || r;
+ r = ((glVertexAttribFormatNV = (PFNGLVERTEXATTRIBFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormatNV")) == NULL) || r;
+ r = ((glVertexAttribIFormatNV = (PFNGLVERTEXATTRIBIFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormatNV")) == NULL) || r;
+ r = ((glVertexFormatNV = (PFNGLVERTEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexFormatNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_buffer_unified_memory */
+
+#ifdef GL_NV_vertex_program
+
+static GLboolean _glewInit_GL_NV_vertex_program ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glAreProgramsResidentNV")) == NULL) || r;
+ r = ((glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glBindProgramNV")) == NULL) || r;
+ r = ((glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsNV")) == NULL) || r;
+ r = ((glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glExecuteProgramNV")) == NULL) || r;
+ r = ((glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsNV")) == NULL) || r;
+ r = ((glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterdvNV")) == NULL) || r;
+ r = ((glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterfvNV")) == NULL) || r;
+ r = ((glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringNV")) == NULL) || r;
+ r = ((glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivNV")) == NULL) || r;
+ r = ((glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetTrackMatrixivNV")) == NULL) || r;
+ r = ((glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervNV")) == NULL) || r;
+ r = ((glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvNV")) == NULL) || r;
+ r = ((glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvNV")) == NULL) || r;
+ r = ((glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivNV")) == NULL) || r;
+ r = ((glIsProgramNV = (PFNGLISPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glIsProgramNV")) == NULL) || r;
+ r = ((glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glLoadProgramNV")) == NULL) || r;
+ r = ((glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dNV")) == NULL) || r;
+ r = ((glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dvNV")) == NULL) || r;
+ r = ((glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fNV")) == NULL) || r;
+ r = ((glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fvNV")) == NULL) || r;
+ r = ((glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4dvNV")) == NULL) || r;
+ r = ((glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4fvNV")) == NULL) || r;
+ r = ((glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glRequestResidentProgramsNV")) == NULL) || r;
+ r = ((glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC)glewGetProcAddress((const GLubyte*)"glTrackMatrixNV")) == NULL) || r;
+ r = ((glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dNV")) == NULL) || r;
+ r = ((glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvNV")) == NULL) || r;
+ r = ((glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fNV")) == NULL) || r;
+ r = ((glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvNV")) == NULL) || r;
+ r = ((glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sNV")) == NULL) || r;
+ r = ((glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svNV")) == NULL) || r;
+ r = ((glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dNV")) == NULL) || r;
+ r = ((glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvNV")) == NULL) || r;
+ r = ((glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fNV")) == NULL) || r;
+ r = ((glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvNV")) == NULL) || r;
+ r = ((glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sNV")) == NULL) || r;
+ r = ((glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svNV")) == NULL) || r;
+ r = ((glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dNV")) == NULL) || r;
+ r = ((glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvNV")) == NULL) || r;
+ r = ((glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fNV")) == NULL) || r;
+ r = ((glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvNV")) == NULL) || r;
+ r = ((glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sNV")) == NULL) || r;
+ r = ((glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svNV")) == NULL) || r;
+ r = ((glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dNV")) == NULL) || r;
+ r = ((glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvNV")) == NULL) || r;
+ r = ((glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fNV")) == NULL) || r;
+ r = ((glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvNV")) == NULL) || r;
+ r = ((glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sNV")) == NULL) || r;
+ r = ((glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svNV")) == NULL) || r;
+ r = ((glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubNV")) == NULL) || r;
+ r = ((glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvNV")) == NULL) || r;
+ r = ((glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerNV")) == NULL) || r;
+ r = ((glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1dvNV")) == NULL) || r;
+ r = ((glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1fvNV")) == NULL) || r;
+ r = ((glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1svNV")) == NULL) || r;
+ r = ((glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2dvNV")) == NULL) || r;
+ r = ((glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2fvNV")) == NULL) || r;
+ r = ((glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2svNV")) == NULL) || r;
+ r = ((glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3dvNV")) == NULL) || r;
+ r = ((glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3fvNV")) == NULL) || r;
+ r = ((glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3svNV")) == NULL) || r;
+ r = ((glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4dvNV")) == NULL) || r;
+ r = ((glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4fvNV")) == NULL) || r;
+ r = ((glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4svNV")) == NULL) || r;
+ r = ((glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4ubvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_program */
+
+#ifdef GL_NV_video_capture
+
+static GLboolean _glewInit_GL_NV_video_capture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginVideoCaptureNV = (PFNGLBEGINVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glBeginVideoCaptureNV")) == NULL) || r;
+ r = ((glBindVideoCaptureStreamBufferNV = (PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamBufferNV")) == NULL) || r;
+ r = ((glBindVideoCaptureStreamTextureNV = (PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamTextureNV")) == NULL) || r;
+ r = ((glEndVideoCaptureNV = (PFNGLENDVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glEndVideoCaptureNV")) == NULL) || r;
+ r = ((glGetVideoCaptureStreamdvNV = (PFNGLGETVIDEOCAPTURESTREAMDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamdvNV")) == NULL) || r;
+ r = ((glGetVideoCaptureStreamfvNV = (PFNGLGETVIDEOCAPTURESTREAMFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamfvNV")) == NULL) || r;
+ r = ((glGetVideoCaptureStreamivNV = (PFNGLGETVIDEOCAPTURESTREAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamivNV")) == NULL) || r;
+ r = ((glGetVideoCaptureivNV = (PFNGLGETVIDEOCAPTUREIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureivNV")) == NULL) || r;
+ r = ((glVideoCaptureNV = (PFNGLVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureNV")) == NULL) || r;
+ r = ((glVideoCaptureStreamParameterdvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterdvNV")) == NULL) || r;
+ r = ((glVideoCaptureStreamParameterfvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterfvNV")) == NULL) || r;
+ r = ((glVideoCaptureStreamParameterivNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_video_capture */
+
+#ifdef GL_NV_viewport_array
+
+static GLboolean _glewInit_GL_NV_viewport_array ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDepthRangeArrayfvNV = (PFNGLDEPTHRANGEARRAYFVNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeArrayfvNV")) == NULL) || r;
+ r = ((glDepthRangeIndexedfNV = (PFNGLDEPTHRANGEINDEXEDFNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeIndexedfNV")) == NULL) || r;
+ r = ((glDisableiNV = (PFNGLDISABLEINVPROC)glewGetProcAddress((const GLubyte*)"glDisableiNV")) == NULL) || r;
+ r = ((glEnableiNV = (PFNGLENABLEINVPROC)glewGetProcAddress((const GLubyte*)"glEnableiNV")) == NULL) || r;
+ r = ((glGetFloati_vNV = (PFNGLGETFLOATI_VNVPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_vNV")) == NULL) || r;
+ r = ((glIsEnablediNV = (PFNGLISENABLEDINVPROC)glewGetProcAddress((const GLubyte*)"glIsEnablediNV")) == NULL) || r;
+ r = ((glScissorArrayvNV = (PFNGLSCISSORARRAYVNVPROC)glewGetProcAddress((const GLubyte*)"glScissorArrayvNV")) == NULL) || r;
+ r = ((glScissorIndexedNV = (PFNGLSCISSORINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedNV")) == NULL) || r;
+ r = ((glScissorIndexedvNV = (PFNGLSCISSORINDEXEDVNVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedvNV")) == NULL) || r;
+ r = ((glViewportArrayvNV = (PFNGLVIEWPORTARRAYVNVPROC)glewGetProcAddress((const GLubyte*)"glViewportArrayvNV")) == NULL) || r;
+ r = ((glViewportIndexedfNV = (PFNGLVIEWPORTINDEXEDFNVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfNV")) == NULL) || r;
+ r = ((glViewportIndexedfvNV = (PFNGLVIEWPORTINDEXEDFVNVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_viewport_array */
+
+#ifdef GL_NV_viewport_swizzle
+
+static GLboolean _glewInit_GL_NV_viewport_swizzle ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glViewportSwizzleNV = (PFNGLVIEWPORTSWIZZLENVPROC)glewGetProcAddress((const GLubyte*)"glViewportSwizzleNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_viewport_swizzle */
+
+#ifdef GL_OVR_multiview
+
+static GLboolean _glewInit_GL_OVR_multiview ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureMultiviewOVR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_OVR_multiview */
+
+#ifdef GL_OVR_multiview_multisampled_render_to_texture
+
+static GLboolean _glewInit_GL_OVR_multiview_multisampled_render_to_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureMultisampleMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureMultisampleMultiviewOVR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_OVR_multiview_multisampled_render_to_texture */
+
+#ifdef GL_QCOM_alpha_test
+
+static GLboolean _glewInit_GL_QCOM_alpha_test ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAlphaFuncQCOM = (PFNGLALPHAFUNCQCOMPROC)glewGetProcAddress((const GLubyte*)"glAlphaFuncQCOM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_QCOM_alpha_test */
+
+#ifdef GL_QCOM_driver_control
+
+static GLboolean _glewInit_GL_QCOM_driver_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDisableDriverControlQCOM = (PFNGLDISABLEDRIVERCONTROLQCOMPROC)glewGetProcAddress((const GLubyte*)"glDisableDriverControlQCOM")) == NULL) || r;
+ r = ((glEnableDriverControlQCOM = (PFNGLENABLEDRIVERCONTROLQCOMPROC)glewGetProcAddress((const GLubyte*)"glEnableDriverControlQCOM")) == NULL) || r;
+ r = ((glGetDriverControlStringQCOM = (PFNGLGETDRIVERCONTROLSTRINGQCOMPROC)glewGetProcAddress((const GLubyte*)"glGetDriverControlStringQCOM")) == NULL) || r;
+ r = ((glGetDriverControlsQCOM = (PFNGLGETDRIVERCONTROLSQCOMPROC)glewGetProcAddress((const GLubyte*)"glGetDriverControlsQCOM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_QCOM_driver_control */
+
+#ifdef GL_QCOM_extended_get
+
+static GLboolean _glewInit_GL_QCOM_extended_get ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glExtGetBufferPointervQCOM = (PFNGLEXTGETBUFFERPOINTERVQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetBufferPointervQCOM")) == NULL) || r;
+ r = ((glExtGetBuffersQCOM = (PFNGLEXTGETBUFFERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetBuffersQCOM")) == NULL) || r;
+ r = ((glExtGetFramebuffersQCOM = (PFNGLEXTGETFRAMEBUFFERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetFramebuffersQCOM")) == NULL) || r;
+ r = ((glExtGetRenderbuffersQCOM = (PFNGLEXTGETRENDERBUFFERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetRenderbuffersQCOM")) == NULL) || r;
+ r = ((glExtGetTexLevelParameterivQCOM = (PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetTexLevelParameterivQCOM")) == NULL) || r;
+ r = ((glExtGetTexSubImageQCOM = (PFNGLEXTGETTEXSUBIMAGEQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetTexSubImageQCOM")) == NULL) || r;
+ r = ((glExtGetTexturesQCOM = (PFNGLEXTGETTEXTURESQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetTexturesQCOM")) == NULL) || r;
+ r = ((glExtTexObjectStateOverrideiQCOM = (PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtTexObjectStateOverrideiQCOM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_QCOM_extended_get */
+
+#ifdef GL_QCOM_extended_get2
+
+static GLboolean _glewInit_GL_QCOM_extended_get2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glExtGetProgramBinarySourceQCOM = (PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetProgramBinarySourceQCOM")) == NULL) || r;
+ r = ((glExtGetProgramsQCOM = (PFNGLEXTGETPROGRAMSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetProgramsQCOM")) == NULL) || r;
+ r = ((glExtGetShadersQCOM = (PFNGLEXTGETSHADERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetShadersQCOM")) == NULL) || r;
+ r = ((glExtIsProgramBinaryQCOM = (PFNGLEXTISPROGRAMBINARYQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtIsProgramBinaryQCOM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_QCOM_extended_get2 */
+
+#ifdef GL_QCOM_framebuffer_foveated
+
+static GLboolean _glewInit_GL_QCOM_framebuffer_foveated ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferFoveationConfigQCOM = (PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC)glewGetProcAddress((const GLubyte*)"glFramebufferFoveationConfigQCOM")) == NULL) || r;
+ r = ((glFramebufferFoveationParametersQCOM = (PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glFramebufferFoveationParametersQCOM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_QCOM_framebuffer_foveated */
+
+#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent
+
+static GLboolean _glewInit_GL_QCOM_shader_framebuffer_fetch_noncoherent ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferFetchBarrierQCOM = (PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC)glewGetProcAddress((const GLubyte*)"glFramebufferFetchBarrierQCOM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */
+
+#ifdef GL_QCOM_tiled_rendering
+
+static GLboolean _glewInit_GL_QCOM_tiled_rendering ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glEndTilingQCOM = (PFNGLENDTILINGQCOMPROC)glewGetProcAddress((const GLubyte*)"glEndTilingQCOM")) == NULL) || r;
+ r = ((glStartTilingQCOM = (PFNGLSTARTTILINGQCOMPROC)glewGetProcAddress((const GLubyte*)"glStartTilingQCOM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_QCOM_tiled_rendering */
+
+#ifdef GL_REGAL_ES1_0_compatibility
+
+static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAlphaFuncx = (PFNGLALPHAFUNCXPROC)glewGetProcAddress((const GLubyte*)"glAlphaFuncx")) == NULL) || r;
+ r = ((glClearColorx = (PFNGLCLEARCOLORXPROC)glewGetProcAddress((const GLubyte*)"glClearColorx")) == NULL) || r;
+ r = ((glClearDepthx = (PFNGLCLEARDEPTHXPROC)glewGetProcAddress((const GLubyte*)"glClearDepthx")) == NULL) || r;
+ r = ((glColor4x = (PFNGLCOLOR4XPROC)glewGetProcAddress((const GLubyte*)"glColor4x")) == NULL) || r;
+ r = ((glDepthRangex = (PFNGLDEPTHRANGEXPROC)glewGetProcAddress((const GLubyte*)"glDepthRangex")) == NULL) || r;
+ r = ((glFogx = (PFNGLFOGXPROC)glewGetProcAddress((const GLubyte*)"glFogx")) == NULL) || r;
+ r = ((glFogxv = (PFNGLFOGXVPROC)glewGetProcAddress((const GLubyte*)"glFogxv")) == NULL) || r;
+ r = ((glFrustumf = (PFNGLFRUSTUMFPROC)glewGetProcAddress((const GLubyte*)"glFrustumf")) == NULL) || r;
+ r = ((glFrustumx = (PFNGLFRUSTUMXPROC)glewGetProcAddress((const GLubyte*)"glFrustumx")) == NULL) || r;
+ r = ((glLightModelx = (PFNGLLIGHTMODELXPROC)glewGetProcAddress((const GLubyte*)"glLightModelx")) == NULL) || r;
+ r = ((glLightModelxv = (PFNGLLIGHTMODELXVPROC)glewGetProcAddress((const GLubyte*)"glLightModelxv")) == NULL) || r;
+ r = ((glLightx = (PFNGLLIGHTXPROC)glewGetProcAddress((const GLubyte*)"glLightx")) == NULL) || r;
+ r = ((glLightxv = (PFNGLLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glLightxv")) == NULL) || r;
+ r = ((glLineWidthx = (PFNGLLINEWIDTHXPROC)glewGetProcAddress((const GLubyte*)"glLineWidthx")) == NULL) || r;
+ r = ((glLoadMatrixx = (PFNGLLOADMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glLoadMatrixx")) == NULL) || r;
+ r = ((glMaterialx = (PFNGLMATERIALXPROC)glewGetProcAddress((const GLubyte*)"glMaterialx")) == NULL) || r;
+ r = ((glMaterialxv = (PFNGLMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glMaterialxv")) == NULL) || r;
+ r = ((glMultMatrixx = (PFNGLMULTMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glMultMatrixx")) == NULL) || r;
+ r = ((glMultiTexCoord4x = (PFNGLMULTITEXCOORD4XPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4x")) == NULL) || r;
+ r = ((glNormal3x = (PFNGLNORMAL3XPROC)glewGetProcAddress((const GLubyte*)"glNormal3x")) == NULL) || r;
+ r = ((glOrthof = (PFNGLORTHOFPROC)glewGetProcAddress((const GLubyte*)"glOrthof")) == NULL) || r;
+ r = ((glOrthox = (PFNGLORTHOXPROC)glewGetProcAddress((const GLubyte*)"glOrthox")) == NULL) || r;
+ r = ((glPointSizex = (PFNGLPOINTSIZEXPROC)glewGetProcAddress((const GLubyte*)"glPointSizex")) == NULL) || r;
+ r = ((glPolygonOffsetx = (PFNGLPOLYGONOFFSETXPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetx")) == NULL) || r;
+ r = ((glRotatex = (PFNGLROTATEXPROC)glewGetProcAddress((const GLubyte*)"glRotatex")) == NULL) || r;
+ r = ((glSampleCoveragex = (PFNGLSAMPLECOVERAGEXPROC)glewGetProcAddress((const GLubyte*)"glSampleCoveragex")) == NULL) || r;
+ r = ((glScalex = (PFNGLSCALEXPROC)glewGetProcAddress((const GLubyte*)"glScalex")) == NULL) || r;
+ r = ((glTexEnvx = (PFNGLTEXENVXPROC)glewGetProcAddress((const GLubyte*)"glTexEnvx")) == NULL) || r;
+ r = ((glTexEnvxv = (PFNGLTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glTexEnvxv")) == NULL) || r;
+ r = ((glTexParameterx = (PFNGLTEXPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glTexParameterx")) == NULL) || r;
+ r = ((glTranslatex = (PFNGLTRANSLATEXPROC)glewGetProcAddress((const GLubyte*)"glTranslatex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_ES1_0_compatibility */
+
+#ifdef GL_REGAL_ES1_1_compatibility
+
+static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClipPlanef = (PFNGLCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glClipPlanef")) == NULL) || r;
+ r = ((glClipPlanex = (PFNGLCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glClipPlanex")) == NULL) || r;
+ r = ((glGetClipPlanef = (PFNGLGETCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanef")) == NULL) || r;
+ r = ((glGetClipPlanex = (PFNGLGETCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanex")) == NULL) || r;
+ r = ((glGetFixedv = (PFNGLGETFIXEDVPROC)glewGetProcAddress((const GLubyte*)"glGetFixedv")) == NULL) || r;
+ r = ((glGetLightxv = (PFNGLGETLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glGetLightxv")) == NULL) || r;
+ r = ((glGetMaterialxv = (PFNGLGETMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glGetMaterialxv")) == NULL) || r;
+ r = ((glGetTexEnvxv = (PFNGLGETTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexEnvxv")) == NULL) || r;
+ r = ((glGetTexParameterxv = (PFNGLGETTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterxv")) == NULL) || r;
+ r = ((glPointParameterx = (PFNGLPOINTPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glPointParameterx")) == NULL) || r;
+ r = ((glPointParameterxv = (PFNGLPOINTPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterxv")) == NULL) || r;
+ r = ((glPointSizePointerOES = (PFNGLPOINTSIZEPOINTEROESPROC)glewGetProcAddress((const GLubyte*)"glPointSizePointerOES")) == NULL) || r;
+ r = ((glTexParameterxv = (PFNGLTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterxv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_ES1_1_compatibility */
+
+#ifdef GL_REGAL_error_string
+
+static GLboolean _glewInit_GL_REGAL_error_string ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glErrorStringREGAL = (PFNGLERRORSTRINGREGALPROC)glewGetProcAddress((const GLubyte*)"glErrorStringREGAL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_error_string */
+
+#ifdef GL_REGAL_extension_query
+
+static GLboolean _glewInit_GL_REGAL_extension_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetExtensionREGAL = (PFNGLGETEXTENSIONREGALPROC)glewGetProcAddress((const GLubyte*)"glGetExtensionREGAL")) == NULL) || r;
+ r = ((glIsSupportedREGAL = (PFNGLISSUPPORTEDREGALPROC)glewGetProcAddress((const GLubyte*)"glIsSupportedREGAL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_extension_query */
+
+#ifdef GL_REGAL_log
+
+static GLboolean _glewInit_GL_REGAL_log ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLogMessageCallbackREGAL = (PFNGLLOGMESSAGECALLBACKREGALPROC)glewGetProcAddress((const GLubyte*)"glLogMessageCallbackREGAL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_log */
+
+#ifdef GL_REGAL_proc_address
+
+static GLboolean _glewInit_GL_REGAL_proc_address ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetProcAddressREGAL = (PFNGLGETPROCADDRESSREGALPROC)glewGetProcAddress((const GLubyte*)"glGetProcAddressREGAL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_proc_address */
+
+#ifdef GL_SGIS_detail_texture
+
+static GLboolean _glewInit_GL_SGIS_detail_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glDetailTexFuncSGIS")) == NULL) || r;
+ r = ((glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetDetailTexFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_detail_texture */
+
+#ifdef GL_SGIS_fog_function
+
+static GLboolean _glewInit_GL_SGIS_fog_function ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glFogFuncSGIS")) == NULL) || r;
+ r = ((glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetFogFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_fog_function */
+
+#ifdef GL_SGIS_multisample
+
+static GLboolean _glewInit_GL_SGIS_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskSGIS")) == NULL) || r;
+ r = ((glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_multisample */
+
+#ifdef GL_SGIS_multitexture
+
+static GLboolean _glewInit_GL_SGIS_multitexture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glInterleavedTextureCoordSetsSGIS = (PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC)glewGetProcAddress((const GLubyte*)"glInterleavedTextureCoordSetsSGIS")) == NULL) || r;
+ r = ((glSelectTextureCoordSetSGIS = (PFNGLSELECTTEXTURECOORDSETSGISPROC)glewGetProcAddress((const GLubyte*)"glSelectTextureCoordSetSGIS")) == NULL) || r;
+ r = ((glSelectTextureSGIS = (PFNGLSELECTTEXTURESGISPROC)glewGetProcAddress((const GLubyte*)"glSelectTextureSGIS")) == NULL) || r;
+ r = ((glSelectTextureTransformSGIS = (PFNGLSELECTTEXTURETRANSFORMSGISPROC)glewGetProcAddress((const GLubyte*)"glSelectTextureTransformSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_multitexture */
+
+#ifdef GL_SGIS_shared_multisample
+
+static GLboolean _glewInit_GL_SGIS_shared_multisample ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultisampleSubRectPosSGIS = (PFNGLMULTISAMPLESUBRECTPOSSGISPROC)glewGetProcAddress((const GLubyte*)"glMultisampleSubRectPosSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_shared_multisample */
+
+#ifdef GL_SGIS_sharpen_texture
+
+static GLboolean _glewInit_GL_SGIS_sharpen_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetSharpenTexFuncSGIS")) == NULL) || r;
+ r = ((glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glSharpenTexFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_sharpen_texture */
+
+#ifdef GL_SGIS_texture4D
+
+static GLboolean _glewInit_GL_SGIS_texture4D ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexImage4DSGIS")) == NULL) || r;
+ r = ((glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage4DSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_texture4D */
+
+#ifdef GL_SGIS_texture_filter4
+
+static GLboolean _glewInit_GL_SGIS_texture_filter4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetTexFilterFuncSGIS")) == NULL) || r;
+ r = ((glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glTexFilterFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_texture_filter4 */
+
+#ifdef GL_SGIX_async
+
+static GLboolean _glewInit_GL_SGIX_async ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glAsyncMarkerSGIX")) == NULL) || r;
+ r = ((glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteAsyncMarkersSGIX")) == NULL) || r;
+ r = ((glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glFinishAsyncSGIX")) == NULL) || r;
+ r = ((glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenAsyncMarkersSGIX")) == NULL) || r;
+ r = ((glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsAsyncMarkerSGIX")) == NULL) || r;
+ r = ((glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glPollAsyncSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_async */
+
+#ifdef GL_SGIX_datapipe
+
+static GLboolean _glewInit_GL_SGIX_datapipe ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAddressSpace = (PFNGLADDRESSSPACEPROC)glewGetProcAddress((const GLubyte*)"glAddressSpace")) == NULL) || r;
+ r = ((glDataPipe = (PFNGLDATAPIPEPROC)glewGetProcAddress((const GLubyte*)"glDataPipe")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_datapipe */
+
+#ifdef GL_SGIX_flush_raster
+
+static GLboolean _glewInit_GL_SGIX_flush_raster ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC)glewGetProcAddress((const GLubyte*)"glFlushRasterSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_flush_raster */
+
+#ifdef GL_SGIX_fog_layers
+
+static GLboolean _glewInit_GL_SGIX_fog_layers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFogLayersSGIX = (PFNGLFOGLAYERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glFogLayersSGIX")) == NULL) || r;
+ r = ((glGetFogLayersSGIX = (PFNGLGETFOGLAYERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFogLayersSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_fog_layers */
+
+#ifdef GL_SGIX_fog_texture
+
+static GLboolean _glewInit_GL_SGIX_fog_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureFogSGIX = (PFNGLTEXTUREFOGSGIXPROC)glewGetProcAddress((const GLubyte*)"glTextureFogSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_fog_texture */
+
+#ifdef GL_SGIX_fragment_specular_lighting
+
+static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialSGIX")) == NULL) || r;
+ r = ((glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfSGIX")) == NULL) || r;
+ r = ((glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvSGIX")) == NULL) || r;
+ r = ((glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliSGIX")) == NULL) || r;
+ r = ((glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivSGIX")) == NULL) || r;
+ r = ((glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfSGIX")) == NULL) || r;
+ r = ((glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvSGIX")) == NULL) || r;
+ r = ((glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiSGIX")) == NULL) || r;
+ r = ((glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivSGIX")) == NULL) || r;
+ r = ((glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvSGIX")) == NULL) || r;
+ r = ((glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivSGIX")) == NULL) || r;
+ r = ((glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvSGIX")) == NULL) || r;
+ r = ((glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_fragment_specular_lighting */
+
+#ifdef GL_SGIX_framezoom
+
+static GLboolean _glewInit_GL_SGIX_framezoom ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC)glewGetProcAddress((const GLubyte*)"glFrameZoomSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_framezoom */
+
+#ifdef GL_SGIX_igloo_interface
+
+static GLboolean _glewInit_GL_SGIX_igloo_interface ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glIglooInterfaceSGIX = (PFNGLIGLOOINTERFACESGIXPROC)glewGetProcAddress((const GLubyte*)"glIglooInterfaceSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_igloo_interface */
+
+#ifdef GL_SGIX_mpeg1
+
+static GLboolean _glewInit_GL_SGIX_mpeg1 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAllocMPEGPredictorsSGIX = (PFNGLALLOCMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glAllocMPEGPredictorsSGIX")) == NULL) || r;
+ r = ((glDeleteMPEGPredictorsSGIX = (PFNGLDELETEMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteMPEGPredictorsSGIX")) == NULL) || r;
+ r = ((glGenMPEGPredictorsSGIX = (PFNGLGENMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenMPEGPredictorsSGIX")) == NULL) || r;
+ r = ((glGetMPEGParameterfvSGIX = (PFNGLGETMPEGPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGParameterfvSGIX")) == NULL) || r;
+ r = ((glGetMPEGParameterivSGIX = (PFNGLGETMPEGPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGParameterivSGIX")) == NULL) || r;
+ r = ((glGetMPEGPredictorSGIX = (PFNGLGETMPEGPREDICTORSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGPredictorSGIX")) == NULL) || r;
+ r = ((glGetMPEGQuantTableubv = (PFNGLGETMPEGQUANTTABLEUBVPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGQuantTableubv")) == NULL) || r;
+ r = ((glIsMPEGPredictorSGIX = (PFNGLISMPEGPREDICTORSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsMPEGPredictorSGIX")) == NULL) || r;
+ r = ((glMPEGPredictorSGIX = (PFNGLMPEGPREDICTORSGIXPROC)glewGetProcAddress((const GLubyte*)"glMPEGPredictorSGIX")) == NULL) || r;
+ r = ((glMPEGQuantTableubv = (PFNGLMPEGQUANTTABLEUBVPROC)glewGetProcAddress((const GLubyte*)"glMPEGQuantTableubv")) == NULL) || r;
+ r = ((glSwapMPEGPredictorsSGIX = (PFNGLSWAPMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glSwapMPEGPredictorsSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_mpeg1 */
+
+#ifdef GL_SGIX_nonlinear_lighting_pervertex
+
+static GLboolean _glewInit_GL_SGIX_nonlinear_lighting_pervertex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetNonlinLightfvSGIX = (PFNGLGETNONLINLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetNonlinLightfvSGIX")) == NULL) || r;
+ r = ((glGetNonlinMaterialfvSGIX = (PFNGLGETNONLINMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetNonlinMaterialfvSGIX")) == NULL) || r;
+ r = ((glNonlinLightfvSGIX = (PFNGLNONLINLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glNonlinLightfvSGIX")) == NULL) || r;
+ r = ((glNonlinMaterialfvSGIX = (PFNGLNONLINMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glNonlinMaterialfvSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_nonlinear_lighting_pervertex */
+
+#ifdef GL_SGIX_pixel_texture
+
+static GLboolean _glewInit_GL_SGIX_pixel_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC)glewGetProcAddress((const GLubyte*)"glPixelTexGenSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_pixel_texture */
+
+#ifdef GL_SGIX_polynomial_ffd
+
+static GLboolean _glewInit_GL_SGIX_polynomial_ffd ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeformSGIX = (PFNGLDEFORMSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeformSGIX")) == NULL) || r;
+ r = ((glLoadIdentityDeformationMapSGIX = (PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC)glewGetProcAddress((const GLubyte*)"glLoadIdentityDeformationMapSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_polynomial_ffd */
+
+#ifdef GL_SGIX_quad_mesh
+
+static GLboolean _glewInit_GL_SGIX_quad_mesh ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMeshBreadthSGIX = (PFNGLMESHBREADTHSGIXPROC)glewGetProcAddress((const GLubyte*)"glMeshBreadthSGIX")) == NULL) || r;
+ r = ((glMeshStrideSGIX = (PFNGLMESHSTRIDESGIXPROC)glewGetProcAddress((const GLubyte*)"glMeshStrideSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_quad_mesh */
+
+#ifdef GL_SGIX_reference_plane
+
+static GLboolean _glewInit_GL_SGIX_reference_plane ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC)glewGetProcAddress((const GLubyte*)"glReferencePlaneSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_reference_plane */
+
+#ifdef GL_SGIX_sprite
+
+static GLboolean _glewInit_GL_SGIX_sprite ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfSGIX")) == NULL) || r;
+ r = ((glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfvSGIX")) == NULL) || r;
+ r = ((glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameteriSGIX")) == NULL) || r;
+ r = ((glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterivSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_sprite */
+
+#ifdef GL_SGIX_tag_sample_buffer
+
+static GLboolean _glewInit_GL_SGIX_tag_sample_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glTagSampleBufferSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_tag_sample_buffer */
+
+#ifdef GL_SGIX_vector_ops
+
+static GLboolean _glewInit_GL_SGIX_vector_ops ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVectorOperationSGIX = (PFNGLGETVECTOROPERATIONSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetVectorOperationSGIX")) == NULL) || r;
+ r = ((glVectorOperationSGIX = (PFNGLVECTOROPERATIONSGIXPROC)glewGetProcAddress((const GLubyte*)"glVectorOperationSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_vector_ops */
+
+#ifdef GL_SGIX_vertex_array_object
+
+static GLboolean _glewInit_GL_SGIX_vertex_array_object ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAreVertexArraysResidentSGIX = (PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glAreVertexArraysResidentSGIX")) == NULL) || r;
+ r = ((glBindVertexArraySGIX = (PFNGLBINDVERTEXARRAYSGIXPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArraySGIX")) == NULL) || r;
+ r = ((glDeleteVertexArraysSGIX = (PFNGLDELETEVERTEXARRAYSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysSGIX")) == NULL) || r;
+ r = ((glGenVertexArraysSGIX = (PFNGLGENVERTEXARRAYSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysSGIX")) == NULL) || r;
+ r = ((glIsVertexArraySGIX = (PFNGLISVERTEXARRAYSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArraySGIX")) == NULL) || r;
+ r = ((glPrioritizeVertexArraysSGIX = (PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeVertexArraysSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_vertex_array_object */
+
+#ifdef GL_SGI_color_table
+
+static GLboolean _glewInit_GL_SGI_color_table ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfvSGI")) == NULL) || r;
+ r = ((glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterivSGI")) == NULL) || r;
+ r = ((glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableSGI")) == NULL) || r;
+ r = ((glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTableSGI")) == NULL) || r;
+ r = ((glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvSGI")) == NULL) || r;
+ r = ((glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivSGI")) == NULL) || r;
+ r = ((glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGI_color_table */
+
+#ifdef GL_SGI_fft
+
+static GLboolean _glewInit_GL_SGI_fft ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetPixelTransformParameterfvSGI = (PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvSGI")) == NULL) || r;
+ r = ((glGetPixelTransformParameterivSGI = (PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivSGI")) == NULL) || r;
+ r = ((glPixelTransformParameterfSGI = (PFNGLPIXELTRANSFORMPARAMETERFSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfSGI")) == NULL) || r;
+ r = ((glPixelTransformParameterfvSGI = (PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvSGI")) == NULL) || r;
+ r = ((glPixelTransformParameteriSGI = (PFNGLPIXELTRANSFORMPARAMETERISGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriSGI")) == NULL) || r;
+ r = ((glPixelTransformParameterivSGI = (PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivSGI")) == NULL) || r;
+ r = ((glPixelTransformSGI = (PFNGLPIXELTRANSFORMSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGI_fft */
+
+#ifdef GL_SUNX_constant_data
+
+static GLboolean _glewInit_GL_SUNX_constant_data ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC)glewGetProcAddress((const GLubyte*)"glFinishTextureSUNX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUNX_constant_data */
+
+#ifdef GL_SUN_global_alpha
+
+static GLboolean _glewInit_GL_SUN_global_alpha ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorbSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactordSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorfSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoriSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorsSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorubSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoruiSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorusSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_global_alpha */
+
+#ifdef GL_SUN_read_video_pixels
+
+static GLboolean _glewInit_GL_SUN_read_video_pixels ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glReadVideoPixelsSUN = (PFNGLREADVIDEOPIXELSSUNPROC)glewGetProcAddress((const GLubyte*)"glReadVideoPixelsSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_read_video_pixels */
+
+#ifdef GL_SUN_triangle_list
+
+static GLboolean _glewInit_GL_SUN_triangle_list ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodePointerSUN")) == NULL) || r;
+ r = ((glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubSUN")) == NULL) || r;
+ r = ((glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiSUN")) == NULL) || r;
+ r = ((glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuivSUN")) == NULL) || r;
+ r = ((glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusSUN")) == NULL) || r;
+ r = ((glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusvSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_triangle_list */
+
+#ifdef GL_SUN_vertex
+
+static GLboolean _glewInit_GL_SUN_vertex ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fSUN")) == NULL) || r;
+ r = ((glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fvSUN")) == NULL) || r;
+ r = ((glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fSUN")) == NULL) || r;
+ r = ((glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fvSUN")) == NULL) || r;
+ r = ((glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fSUN")) == NULL) || r;
+ r = ((glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fvSUN")) == NULL) || r;
+ r = ((glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fSUN")) == NULL) || r;
+ r = ((glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fvSUN")) == NULL) || r;
+ r = ((glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fSUN")) == NULL) || r;
+ r = ((glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fvSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_vertex */
+
+#ifdef GL_WIN_swap_hint
+
+static GLboolean _glewInit_GL_WIN_swap_hint ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)glewGetProcAddress((const GLubyte*)"glAddSwapHintRectWIN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_WIN_swap_hint */
+
+/* ------------------------------------------------------------------------- */
+
+static int _glewExtensionCompare(const char *s1, const char *s2)
+{
+ /* http://www.chanduthedev.com/2012/07/strcmp-implementation-in-c.html */
+ while (*s1 || *s2)
+ {
+ if (*s1 > *s2)
+ return 1;
+ if (*s1 < *s2)
+ return -1;
+ s1++;
+ s2++;
+ }
+ return 0;
+}
+
+static ptrdiff_t _glewBsearchExtension(const char* name)
+{
+ ptrdiff_t lo = 0, hi = sizeof(_glewExtensionLookup) / sizeof(char*) - 2;
+
+ while (lo <= hi)
+ {
+ ptrdiff_t mid = (lo + hi) / 2;
+ const int cmp = _glewExtensionCompare(name, _glewExtensionLookup[mid]);
+ if (cmp < 0) hi = mid - 1;
+ else if (cmp > 0) lo = mid + 1;
+ else return mid;
+ }
+ return -1;
+}
+
+static GLboolean *_glewGetExtensionString(const char *name)
+{
+ ptrdiff_t n = _glewBsearchExtension(name);
+ if (n >= 0) return &_glewExtensionString[n];
+ return NULL;
+}
+
+static GLboolean *_glewGetExtensionEnable(const char *name)
+{
+ ptrdiff_t n = _glewBsearchExtension(name);
+ if (n >= 0) return _glewExtensionEnabled[n];
+ return NULL;
+}
+
+static const char *_glewNextSpace(const char *i)
+{
+ const char *j = i;
+ if (j)
+ while (*j!=' ' && *j) ++j;
+ return j;
+}
+
+static const char *_glewNextNonSpace(const char *i)
+{
+ const char *j = i;
+ if (j)
+ while (*j==' ') ++j;
+ return j;
+}
+
+GLboolean GLEWAPIENTRY glewGetExtension (const char* name)
+{
+ GLboolean *enable = _glewGetExtensionString(name);
+ if (enable)
+ return *enable;
+ return GL_FALSE;
+}
+
+/* ------------------------------------------------------------------------- */
+
+typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params);
+
+static GLenum GLEWAPIENTRY glewContextInit ()
+{
+ PFNGLGETSTRINGPROC getString;
+ const GLubyte* s;
+ GLuint dot;
+ GLint major, minor;
+ size_t n;
+
+ #ifdef _WIN32
+ getString = glGetString;
+ #else
+ getString = (PFNGLGETSTRINGPROC) glewGetProcAddress((const GLubyte*)"glGetString");
+ if (!getString)
+ return GLEW_ERROR_NO_GL_VERSION;
+ #endif
+
+ /* query opengl version */
+ s = getString(GL_VERSION);
+ dot = _glewStrCLen(s, '.');
+ if (dot == 0)
+ return GLEW_ERROR_NO_GL_VERSION;
+
+ major = s[dot-1]-'0';
+ minor = s[dot+1]-'0';
+
+ if (minor < 0 || minor > 9)
+ minor = 0;
+ if (major<0 || major>9)
+ return GLEW_ERROR_NO_GL_VERSION;
+
+ if (major == 1 && minor == 0)
+ {
+ return GLEW_ERROR_GL_VERSION_10_ONLY;
+ }
+ else
+ {
+ GLEW_VERSION_4_6 = ( major > 4 ) || ( major == 4 && minor >= 6 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_4_5 = GLEW_VERSION_4_4 == GL_TRUE || ( major == 4 && minor >= 5 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_4_4 = GLEW_VERSION_4_5 == GL_TRUE || ( major == 4 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_4_3 = GLEW_VERSION_4_4 == GL_TRUE || ( major == 4 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_4_2 = GLEW_VERSION_4_3 == GL_TRUE || ( major == 4 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_4_1 = GLEW_VERSION_4_2 == GL_TRUE || ( major == 4 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_4_0 = GLEW_VERSION_4_1 == GL_TRUE || ( major == 4 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_3_3 = GLEW_VERSION_4_0 == GL_TRUE || ( major == 3 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_3_2 = GLEW_VERSION_3_3 == GL_TRUE || ( major == 3 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_3_1 = GLEW_VERSION_3_2 == GL_TRUE || ( major == 3 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_3_0 = GLEW_VERSION_3_1 == GL_TRUE || ( major == 3 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_2_1 = GLEW_VERSION_3_0 == GL_TRUE || ( major == 2 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_2_0 = GLEW_VERSION_2_1 == GL_TRUE || ( major == 2 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_1_5 = GLEW_VERSION_2_0 == GL_TRUE || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_1_4 = GLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_1_3 = GLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_1_2_1 = GLEW_VERSION_1_3 == GL_TRUE ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_1_2 = GLEW_VERSION_1_2_1 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ GLEW_VERSION_1_1 = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ }
+
+ for (n = 0; n < sizeof(_glewExtensionString) / sizeof(_glewExtensionString[0]); ++n)
+ _glewExtensionString[n] = GL_FALSE;
+
+ if (GLEW_VERSION_3_0)
+ {
+ GLint n = 0;
+ GLint i;
+ PFNGLGETINTEGERVPROC getIntegerv;
+ PFNGLGETSTRINGIPROC getStringi;
+ const char *ext;
+ GLboolean *enable;
+
+ #ifdef _WIN32
+ getIntegerv = glGetIntegerv;
+ #else
+ getIntegerv = (PFNGLGETINTEGERVPROC) glewGetProcAddress((const GLubyte*)"glGetIntegerv");
+ #endif
+
+ if (getIntegerv)
+ getIntegerv(GL_NUM_EXTENSIONS, &n);
+
+ /* glGetStringi is OpenGL 3.0 */
+ getStringi = (PFNGLGETSTRINGIPROC) glewGetProcAddress((const GLubyte*)"glGetStringi");
+ if (getStringi)
+ for (i = 0; i<n; ++i)
+ {
+ ext = (const char *) getStringi(GL_EXTENSIONS, i);
+
+ /* Based on extension string(s), glewGetExtension purposes */
+ enable = _glewGetExtensionString(ext);
+ if (enable)
+ *enable = GL_TRUE;
+
+ /* Based on extension string(s), experimental mode, glewIsSupported purposes */
+ enable = _glewGetExtensionEnable(ext);
+ if (enable)
+ *enable = GL_TRUE;
+ }
+ }
+ else
+ {
+ const char *extensions;
+ const char *end;
+ const char *i;
+ const char *j;
+ char ext[128];
+ GLboolean *enable;
+
+ extensions = (const char *) getString(GL_EXTENSIONS);
+
+ if (extensions)
+ {
+ end = extensions + _glewStrLen((const GLubyte *) extensions);
+ for (i=extensions; i<end; i = j + 1)
+ {
+ i = _glewNextNonSpace(i);
+ j = _glewNextSpace(i);
+
+ /* Copy extension into NUL terminated string */
+ if (j-i >= (ptrdiff_t) sizeof(ext))
+ continue;
+ _glewStrCopy(ext, i, ' ');
+
+ /* Based on extension string(s), glewGetExtension purposes */
+ enable = _glewGetExtensionString(ext);
+ if (enable)
+ *enable = GL_TRUE;
+
+ /* Based on extension string(s), experimental mode, glewIsSupported purposes */
+ enable = _glewGetExtensionEnable(ext);
+ if (enable)
+ *enable = GL_TRUE;
+ }
+ }
+ }
+#ifdef GL_VERSION_1_2
+ if (glewExperimental || GLEW_VERSION_1_2) GLEW_VERSION_1_2 = !_glewInit_GL_VERSION_1_2();
+#endif /* GL_VERSION_1_2 */
+#ifdef GL_VERSION_1_3
+ if (glewExperimental || GLEW_VERSION_1_3) GLEW_VERSION_1_3 = !_glewInit_GL_VERSION_1_3();
+#endif /* GL_VERSION_1_3 */
+#ifdef GL_VERSION_1_4
+ if (glewExperimental || GLEW_VERSION_1_4) GLEW_VERSION_1_4 = !_glewInit_GL_VERSION_1_4();
+#endif /* GL_VERSION_1_4 */
+#ifdef GL_VERSION_1_5
+ if (glewExperimental || GLEW_VERSION_1_5) GLEW_VERSION_1_5 = !_glewInit_GL_VERSION_1_5();
+#endif /* GL_VERSION_1_5 */
+#ifdef GL_VERSION_2_0
+ if (glewExperimental || GLEW_VERSION_2_0) GLEW_VERSION_2_0 = !_glewInit_GL_VERSION_2_0();
+#endif /* GL_VERSION_2_0 */
+#ifdef GL_VERSION_2_1
+ if (glewExperimental || GLEW_VERSION_2_1) GLEW_VERSION_2_1 = !_glewInit_GL_VERSION_2_1();
+#endif /* GL_VERSION_2_1 */
+#ifdef GL_VERSION_3_0
+ if (glewExperimental || GLEW_VERSION_3_0) GLEW_VERSION_3_0 = !_glewInit_GL_VERSION_3_0();
+#endif /* GL_VERSION_3_0 */
+#ifdef GL_VERSION_3_1
+ if (glewExperimental || GLEW_VERSION_3_1) GLEW_VERSION_3_1 = !_glewInit_GL_VERSION_3_1();
+#endif /* GL_VERSION_3_1 */
+#ifdef GL_VERSION_3_2
+ if (glewExperimental || GLEW_VERSION_3_2) GLEW_VERSION_3_2 = !_glewInit_GL_VERSION_3_2();
+#endif /* GL_VERSION_3_2 */
+#ifdef GL_VERSION_3_3
+ if (glewExperimental || GLEW_VERSION_3_3) GLEW_VERSION_3_3 = !_glewInit_GL_VERSION_3_3();
+#endif /* GL_VERSION_3_3 */
+#ifdef GL_VERSION_4_0
+ if (glewExperimental || GLEW_VERSION_4_0) GLEW_VERSION_4_0 = !_glewInit_GL_VERSION_4_0();
+#endif /* GL_VERSION_4_0 */
+#ifdef GL_VERSION_4_5
+ if (glewExperimental || GLEW_VERSION_4_5) GLEW_VERSION_4_5 = !_glewInit_GL_VERSION_4_5();
+#endif /* GL_VERSION_4_5 */
+#ifdef GL_VERSION_4_6
+ if (glewExperimental || GLEW_VERSION_4_6) GLEW_VERSION_4_6 = !_glewInit_GL_VERSION_4_6();
+#endif /* GL_VERSION_4_6 */
+#ifdef GL_3DFX_tbuffer
+ if (glewExperimental || GLEW_3DFX_tbuffer) GLEW_3DFX_tbuffer = !_glewInit_GL_3DFX_tbuffer();
+#endif /* GL_3DFX_tbuffer */
+#ifdef GL_AMD_debug_output
+ if (glewExperimental || GLEW_AMD_debug_output) GLEW_AMD_debug_output = !_glewInit_GL_AMD_debug_output();
+#endif /* GL_AMD_debug_output */
+#ifdef GL_AMD_draw_buffers_blend
+ if (glewExperimental || GLEW_AMD_draw_buffers_blend) GLEW_AMD_draw_buffers_blend = !_glewInit_GL_AMD_draw_buffers_blend();
+#endif /* GL_AMD_draw_buffers_blend */
+#ifdef GL_AMD_framebuffer_sample_positions
+ if (glewExperimental || GLEW_AMD_framebuffer_sample_positions) GLEW_AMD_framebuffer_sample_positions = !_glewInit_GL_AMD_framebuffer_sample_positions();
+#endif /* GL_AMD_framebuffer_sample_positions */
+#ifdef GL_AMD_interleaved_elements
+ if (glewExperimental || GLEW_AMD_interleaved_elements) GLEW_AMD_interleaved_elements = !_glewInit_GL_AMD_interleaved_elements();
+#endif /* GL_AMD_interleaved_elements */
+#ifdef GL_AMD_multi_draw_indirect
+ if (glewExperimental || GLEW_AMD_multi_draw_indirect) GLEW_AMD_multi_draw_indirect = !_glewInit_GL_AMD_multi_draw_indirect();
+#endif /* GL_AMD_multi_draw_indirect */
+#ifdef GL_AMD_name_gen_delete
+ if (glewExperimental || GLEW_AMD_name_gen_delete) GLEW_AMD_name_gen_delete = !_glewInit_GL_AMD_name_gen_delete();
+#endif /* GL_AMD_name_gen_delete */
+#ifdef GL_AMD_occlusion_query_event
+ if (glewExperimental || GLEW_AMD_occlusion_query_event) GLEW_AMD_occlusion_query_event = !_glewInit_GL_AMD_occlusion_query_event();
+#endif /* GL_AMD_occlusion_query_event */
+#ifdef GL_AMD_performance_monitor
+ if (glewExperimental || GLEW_AMD_performance_monitor) GLEW_AMD_performance_monitor = !_glewInit_GL_AMD_performance_monitor();
+#endif /* GL_AMD_performance_monitor */
+#ifdef GL_AMD_sample_positions
+ if (glewExperimental || GLEW_AMD_sample_positions) GLEW_AMD_sample_positions = !_glewInit_GL_AMD_sample_positions();
+#endif /* GL_AMD_sample_positions */
+#ifdef GL_AMD_sparse_texture
+ if (glewExperimental || GLEW_AMD_sparse_texture) GLEW_AMD_sparse_texture = !_glewInit_GL_AMD_sparse_texture();
+#endif /* GL_AMD_sparse_texture */
+#ifdef GL_AMD_stencil_operation_extended
+ if (glewExperimental || GLEW_AMD_stencil_operation_extended) GLEW_AMD_stencil_operation_extended = !_glewInit_GL_AMD_stencil_operation_extended();
+#endif /* GL_AMD_stencil_operation_extended */
+#ifdef GL_AMD_vertex_shader_tessellator
+ if (glewExperimental || GLEW_AMD_vertex_shader_tessellator) GLEW_AMD_vertex_shader_tessellator = !_glewInit_GL_AMD_vertex_shader_tessellator();
+#endif /* GL_AMD_vertex_shader_tessellator */
+#ifdef GL_ANGLE_framebuffer_blit
+ if (glewExperimental || GLEW_ANGLE_framebuffer_blit) GLEW_ANGLE_framebuffer_blit = !_glewInit_GL_ANGLE_framebuffer_blit();
+#endif /* GL_ANGLE_framebuffer_blit */
+#ifdef GL_ANGLE_framebuffer_multisample
+ if (glewExperimental || GLEW_ANGLE_framebuffer_multisample) GLEW_ANGLE_framebuffer_multisample = !_glewInit_GL_ANGLE_framebuffer_multisample();
+#endif /* GL_ANGLE_framebuffer_multisample */
+#ifdef GL_ANGLE_instanced_arrays
+ if (glewExperimental || GLEW_ANGLE_instanced_arrays) GLEW_ANGLE_instanced_arrays = !_glewInit_GL_ANGLE_instanced_arrays();
+#endif /* GL_ANGLE_instanced_arrays */
+#ifdef GL_ANGLE_timer_query
+ if (glewExperimental || GLEW_ANGLE_timer_query) GLEW_ANGLE_timer_query = !_glewInit_GL_ANGLE_timer_query();
+#endif /* GL_ANGLE_timer_query */
+#ifdef GL_ANGLE_translated_shader_source
+ if (glewExperimental || GLEW_ANGLE_translated_shader_source) GLEW_ANGLE_translated_shader_source = !_glewInit_GL_ANGLE_translated_shader_source();
+#endif /* GL_ANGLE_translated_shader_source */
+#ifdef GL_APPLE_copy_texture_levels
+ if (glewExperimental || GLEW_APPLE_copy_texture_levels) GLEW_APPLE_copy_texture_levels = !_glewInit_GL_APPLE_copy_texture_levels();
+#endif /* GL_APPLE_copy_texture_levels */
+#ifdef GL_APPLE_element_array
+ if (glewExperimental || GLEW_APPLE_element_array) GLEW_APPLE_element_array = !_glewInit_GL_APPLE_element_array();
+#endif /* GL_APPLE_element_array */
+#ifdef GL_APPLE_fence
+ if (glewExperimental || GLEW_APPLE_fence) GLEW_APPLE_fence = !_glewInit_GL_APPLE_fence();
+#endif /* GL_APPLE_fence */
+#ifdef GL_APPLE_flush_buffer_range
+ if (glewExperimental || GLEW_APPLE_flush_buffer_range) GLEW_APPLE_flush_buffer_range = !_glewInit_GL_APPLE_flush_buffer_range();
+#endif /* GL_APPLE_flush_buffer_range */
+#ifdef GL_APPLE_framebuffer_multisample
+ if (glewExperimental || GLEW_APPLE_framebuffer_multisample) GLEW_APPLE_framebuffer_multisample = !_glewInit_GL_APPLE_framebuffer_multisample();
+#endif /* GL_APPLE_framebuffer_multisample */
+#ifdef GL_APPLE_object_purgeable
+ if (glewExperimental || GLEW_APPLE_object_purgeable) GLEW_APPLE_object_purgeable = !_glewInit_GL_APPLE_object_purgeable();
+#endif /* GL_APPLE_object_purgeable */
+#ifdef GL_APPLE_sync
+ if (glewExperimental || GLEW_APPLE_sync) GLEW_APPLE_sync = !_glewInit_GL_APPLE_sync();
+#endif /* GL_APPLE_sync */
+#ifdef GL_APPLE_texture_range
+ if (glewExperimental || GLEW_APPLE_texture_range) GLEW_APPLE_texture_range = !_glewInit_GL_APPLE_texture_range();
+#endif /* GL_APPLE_texture_range */
+#ifdef GL_APPLE_vertex_array_object
+ if (glewExperimental || GLEW_APPLE_vertex_array_object) GLEW_APPLE_vertex_array_object = !_glewInit_GL_APPLE_vertex_array_object();
+#endif /* GL_APPLE_vertex_array_object */
+#ifdef GL_APPLE_vertex_array_range
+ if (glewExperimental || GLEW_APPLE_vertex_array_range) GLEW_APPLE_vertex_array_range = !_glewInit_GL_APPLE_vertex_array_range();
+#endif /* GL_APPLE_vertex_array_range */
+#ifdef GL_APPLE_vertex_program_evaluators
+ if (glewExperimental || GLEW_APPLE_vertex_program_evaluators) GLEW_APPLE_vertex_program_evaluators = !_glewInit_GL_APPLE_vertex_program_evaluators();
+#endif /* GL_APPLE_vertex_program_evaluators */
+#ifdef GL_ARB_ES2_compatibility
+ if (glewExperimental || GLEW_ARB_ES2_compatibility) GLEW_ARB_ES2_compatibility = !_glewInit_GL_ARB_ES2_compatibility();
+#endif /* GL_ARB_ES2_compatibility */
+#ifdef GL_ARB_ES3_1_compatibility
+ if (glewExperimental || GLEW_ARB_ES3_1_compatibility) GLEW_ARB_ES3_1_compatibility = !_glewInit_GL_ARB_ES3_1_compatibility();
+#endif /* GL_ARB_ES3_1_compatibility */
+#ifdef GL_ARB_ES3_2_compatibility
+ if (glewExperimental || GLEW_ARB_ES3_2_compatibility) GLEW_ARB_ES3_2_compatibility = !_glewInit_GL_ARB_ES3_2_compatibility();
+#endif /* GL_ARB_ES3_2_compatibility */
+#ifdef GL_ARB_base_instance
+ if (glewExperimental || GLEW_ARB_base_instance) GLEW_ARB_base_instance = !_glewInit_GL_ARB_base_instance();
+#endif /* GL_ARB_base_instance */
+#ifdef GL_ARB_bindless_texture
+ if (glewExperimental || GLEW_ARB_bindless_texture) GLEW_ARB_bindless_texture = !_glewInit_GL_ARB_bindless_texture();
+#endif /* GL_ARB_bindless_texture */
+#ifdef GL_ARB_blend_func_extended
+ if (glewExperimental || GLEW_ARB_blend_func_extended) GLEW_ARB_blend_func_extended = !_glewInit_GL_ARB_blend_func_extended();
+#endif /* GL_ARB_blend_func_extended */
+#ifdef GL_ARB_buffer_storage
+ if (glewExperimental || GLEW_ARB_buffer_storage) GLEW_ARB_buffer_storage = !_glewInit_GL_ARB_buffer_storage();
+#endif /* GL_ARB_buffer_storage */
+#ifdef GL_ARB_cl_event
+ if (glewExperimental || GLEW_ARB_cl_event) GLEW_ARB_cl_event = !_glewInit_GL_ARB_cl_event();
+#endif /* GL_ARB_cl_event */
+#ifdef GL_ARB_clear_buffer_object
+ if (glewExperimental || GLEW_ARB_clear_buffer_object) GLEW_ARB_clear_buffer_object = !_glewInit_GL_ARB_clear_buffer_object();
+#endif /* GL_ARB_clear_buffer_object */
+#ifdef GL_ARB_clear_texture
+ if (glewExperimental || GLEW_ARB_clear_texture) GLEW_ARB_clear_texture = !_glewInit_GL_ARB_clear_texture();
+#endif /* GL_ARB_clear_texture */
+#ifdef GL_ARB_clip_control
+ if (glewExperimental || GLEW_ARB_clip_control) GLEW_ARB_clip_control = !_glewInit_GL_ARB_clip_control();
+#endif /* GL_ARB_clip_control */
+#ifdef GL_ARB_color_buffer_float
+ if (glewExperimental || GLEW_ARB_color_buffer_float) GLEW_ARB_color_buffer_float = !_glewInit_GL_ARB_color_buffer_float();
+#endif /* GL_ARB_color_buffer_float */
+#ifdef GL_ARB_compute_shader
+ if (glewExperimental || GLEW_ARB_compute_shader) GLEW_ARB_compute_shader = !_glewInit_GL_ARB_compute_shader();
+#endif /* GL_ARB_compute_shader */
+#ifdef GL_ARB_compute_variable_group_size
+ if (glewExperimental || GLEW_ARB_compute_variable_group_size) GLEW_ARB_compute_variable_group_size = !_glewInit_GL_ARB_compute_variable_group_size();
+#endif /* GL_ARB_compute_variable_group_size */
+#ifdef GL_ARB_copy_buffer
+ if (glewExperimental || GLEW_ARB_copy_buffer) GLEW_ARB_copy_buffer = !_glewInit_GL_ARB_copy_buffer();
+#endif /* GL_ARB_copy_buffer */
+#ifdef GL_ARB_copy_image
+ if (glewExperimental || GLEW_ARB_copy_image) GLEW_ARB_copy_image = !_glewInit_GL_ARB_copy_image();
+#endif /* GL_ARB_copy_image */
+#ifdef GL_ARB_debug_output
+ if (glewExperimental || GLEW_ARB_debug_output) GLEW_ARB_debug_output = !_glewInit_GL_ARB_debug_output();
+#endif /* GL_ARB_debug_output */
+#ifdef GL_ARB_direct_state_access
+ if (glewExperimental || GLEW_ARB_direct_state_access) GLEW_ARB_direct_state_access = !_glewInit_GL_ARB_direct_state_access();
+#endif /* GL_ARB_direct_state_access */
+#ifdef GL_ARB_draw_buffers
+ if (glewExperimental || GLEW_ARB_draw_buffers) GLEW_ARB_draw_buffers = !_glewInit_GL_ARB_draw_buffers();
+#endif /* GL_ARB_draw_buffers */
+#ifdef GL_ARB_draw_buffers_blend
+ if (glewExperimental || GLEW_ARB_draw_buffers_blend) GLEW_ARB_draw_buffers_blend = !_glewInit_GL_ARB_draw_buffers_blend();
+#endif /* GL_ARB_draw_buffers_blend */
+#ifdef GL_ARB_draw_elements_base_vertex
+ if (glewExperimental || GLEW_ARB_draw_elements_base_vertex) GLEW_ARB_draw_elements_base_vertex = !_glewInit_GL_ARB_draw_elements_base_vertex();
+#endif /* GL_ARB_draw_elements_base_vertex */
+#ifdef GL_ARB_draw_indirect
+ if (glewExperimental || GLEW_ARB_draw_indirect) GLEW_ARB_draw_indirect = !_glewInit_GL_ARB_draw_indirect();
+#endif /* GL_ARB_draw_indirect */
+#ifdef GL_ARB_framebuffer_no_attachments
+ if (glewExperimental || GLEW_ARB_framebuffer_no_attachments) GLEW_ARB_framebuffer_no_attachments = !_glewInit_GL_ARB_framebuffer_no_attachments();
+#endif /* GL_ARB_framebuffer_no_attachments */
+#ifdef GL_ARB_framebuffer_object
+ if (glewExperimental || GLEW_ARB_framebuffer_object) GLEW_ARB_framebuffer_object = !_glewInit_GL_ARB_framebuffer_object();
+#endif /* GL_ARB_framebuffer_object */
+#ifdef GL_ARB_geometry_shader4
+ if (glewExperimental || GLEW_ARB_geometry_shader4) GLEW_ARB_geometry_shader4 = !_glewInit_GL_ARB_geometry_shader4();
+#endif /* GL_ARB_geometry_shader4 */
+#ifdef GL_ARB_get_program_binary
+ if (glewExperimental || GLEW_ARB_get_program_binary) GLEW_ARB_get_program_binary = !_glewInit_GL_ARB_get_program_binary();
+#endif /* GL_ARB_get_program_binary */
+#ifdef GL_ARB_get_texture_sub_image
+ if (glewExperimental || GLEW_ARB_get_texture_sub_image) GLEW_ARB_get_texture_sub_image = !_glewInit_GL_ARB_get_texture_sub_image();
+#endif /* GL_ARB_get_texture_sub_image */
+#ifdef GL_ARB_gl_spirv
+ if (glewExperimental || GLEW_ARB_gl_spirv) GLEW_ARB_gl_spirv = !_glewInit_GL_ARB_gl_spirv();
+#endif /* GL_ARB_gl_spirv */
+#ifdef GL_ARB_gpu_shader_fp64
+ if (glewExperimental || GLEW_ARB_gpu_shader_fp64) GLEW_ARB_gpu_shader_fp64 = !_glewInit_GL_ARB_gpu_shader_fp64();
+#endif /* GL_ARB_gpu_shader_fp64 */
+#ifdef GL_ARB_gpu_shader_int64
+ if (glewExperimental || GLEW_ARB_gpu_shader_int64) GLEW_ARB_gpu_shader_int64 = !_glewInit_GL_ARB_gpu_shader_int64();
+#endif /* GL_ARB_gpu_shader_int64 */
+#ifdef GL_ARB_imaging
+ if (glewExperimental || GLEW_ARB_imaging) GLEW_ARB_imaging = !_glewInit_GL_ARB_imaging();
+#endif /* GL_ARB_imaging */
+#ifdef GL_ARB_indirect_parameters
+ if (glewExperimental || GLEW_ARB_indirect_parameters) GLEW_ARB_indirect_parameters = !_glewInit_GL_ARB_indirect_parameters();
+#endif /* GL_ARB_indirect_parameters */
+#ifdef GL_ARB_instanced_arrays
+ if (glewExperimental || GLEW_ARB_instanced_arrays) GLEW_ARB_instanced_arrays = !_glewInit_GL_ARB_instanced_arrays();
+#endif /* GL_ARB_instanced_arrays */
+#ifdef GL_ARB_internalformat_query
+ if (glewExperimental || GLEW_ARB_internalformat_query) GLEW_ARB_internalformat_query = !_glewInit_GL_ARB_internalformat_query();
+#endif /* GL_ARB_internalformat_query */
+#ifdef GL_ARB_internalformat_query2
+ if (glewExperimental || GLEW_ARB_internalformat_query2) GLEW_ARB_internalformat_query2 = !_glewInit_GL_ARB_internalformat_query2();
+#endif /* GL_ARB_internalformat_query2 */
+#ifdef GL_ARB_invalidate_subdata
+ if (glewExperimental || GLEW_ARB_invalidate_subdata) GLEW_ARB_invalidate_subdata = !_glewInit_GL_ARB_invalidate_subdata();
+#endif /* GL_ARB_invalidate_subdata */
+#ifdef GL_ARB_map_buffer_range
+ if (glewExperimental || GLEW_ARB_map_buffer_range) GLEW_ARB_map_buffer_range = !_glewInit_GL_ARB_map_buffer_range();
+#endif /* GL_ARB_map_buffer_range */
+#ifdef GL_ARB_matrix_palette
+ if (glewExperimental || GLEW_ARB_matrix_palette) GLEW_ARB_matrix_palette = !_glewInit_GL_ARB_matrix_palette();
+#endif /* GL_ARB_matrix_palette */
+#ifdef GL_ARB_multi_bind
+ if (glewExperimental || GLEW_ARB_multi_bind) GLEW_ARB_multi_bind = !_glewInit_GL_ARB_multi_bind();
+#endif /* GL_ARB_multi_bind */
+#ifdef GL_ARB_multi_draw_indirect
+ if (glewExperimental || GLEW_ARB_multi_draw_indirect) GLEW_ARB_multi_draw_indirect = !_glewInit_GL_ARB_multi_draw_indirect();
+#endif /* GL_ARB_multi_draw_indirect */
+#ifdef GL_ARB_multisample
+ if (glewExperimental || GLEW_ARB_multisample) GLEW_ARB_multisample = !_glewInit_GL_ARB_multisample();
+#endif /* GL_ARB_multisample */
+#ifdef GL_ARB_multitexture
+ if (glewExperimental || GLEW_ARB_multitexture) GLEW_ARB_multitexture = !_glewInit_GL_ARB_multitexture();
+#endif /* GL_ARB_multitexture */
+#ifdef GL_ARB_occlusion_query
+ if (glewExperimental || GLEW_ARB_occlusion_query) GLEW_ARB_occlusion_query = !_glewInit_GL_ARB_occlusion_query();
+#endif /* GL_ARB_occlusion_query */
+#ifdef GL_ARB_parallel_shader_compile
+ if (glewExperimental || GLEW_ARB_parallel_shader_compile) GLEW_ARB_parallel_shader_compile = !_glewInit_GL_ARB_parallel_shader_compile();
+#endif /* GL_ARB_parallel_shader_compile */
+#ifdef GL_ARB_point_parameters
+ if (glewExperimental || GLEW_ARB_point_parameters) GLEW_ARB_point_parameters = !_glewInit_GL_ARB_point_parameters();
+#endif /* GL_ARB_point_parameters */
+#ifdef GL_ARB_polygon_offset_clamp
+ if (glewExperimental || GLEW_ARB_polygon_offset_clamp) GLEW_ARB_polygon_offset_clamp = !_glewInit_GL_ARB_polygon_offset_clamp();
+#endif /* GL_ARB_polygon_offset_clamp */
+#ifdef GL_ARB_program_interface_query
+ if (glewExperimental || GLEW_ARB_program_interface_query) GLEW_ARB_program_interface_query = !_glewInit_GL_ARB_program_interface_query();
+#endif /* GL_ARB_program_interface_query */
+#ifdef GL_ARB_provoking_vertex
+ if (glewExperimental || GLEW_ARB_provoking_vertex) GLEW_ARB_provoking_vertex = !_glewInit_GL_ARB_provoking_vertex();
+#endif /* GL_ARB_provoking_vertex */
+#ifdef GL_ARB_robustness
+ if (glewExperimental || GLEW_ARB_robustness) GLEW_ARB_robustness = !_glewInit_GL_ARB_robustness();
+#endif /* GL_ARB_robustness */
+#ifdef GL_ARB_sample_locations
+ if (glewExperimental || GLEW_ARB_sample_locations) GLEW_ARB_sample_locations = !_glewInit_GL_ARB_sample_locations();
+#endif /* GL_ARB_sample_locations */
+#ifdef GL_ARB_sample_shading
+ if (glewExperimental || GLEW_ARB_sample_shading) GLEW_ARB_sample_shading = !_glewInit_GL_ARB_sample_shading();
+#endif /* GL_ARB_sample_shading */
+#ifdef GL_ARB_sampler_objects
+ if (glewExperimental || GLEW_ARB_sampler_objects) GLEW_ARB_sampler_objects = !_glewInit_GL_ARB_sampler_objects();
+#endif /* GL_ARB_sampler_objects */
+#ifdef GL_ARB_separate_shader_objects
+ if (glewExperimental || GLEW_ARB_separate_shader_objects) GLEW_ARB_separate_shader_objects = !_glewInit_GL_ARB_separate_shader_objects();
+#endif /* GL_ARB_separate_shader_objects */
+#ifdef GL_ARB_shader_atomic_counters
+ if (glewExperimental || GLEW_ARB_shader_atomic_counters) GLEW_ARB_shader_atomic_counters = !_glewInit_GL_ARB_shader_atomic_counters();
+#endif /* GL_ARB_shader_atomic_counters */
+#ifdef GL_ARB_shader_image_load_store
+ if (glewExperimental || GLEW_ARB_shader_image_load_store) GLEW_ARB_shader_image_load_store = !_glewInit_GL_ARB_shader_image_load_store();
+#endif /* GL_ARB_shader_image_load_store */
+#ifdef GL_ARB_shader_objects
+ if (glewExperimental || GLEW_ARB_shader_objects) GLEW_ARB_shader_objects = !_glewInit_GL_ARB_shader_objects();
+#endif /* GL_ARB_shader_objects */
+#ifdef GL_ARB_shader_storage_buffer_object
+ if (glewExperimental || GLEW_ARB_shader_storage_buffer_object) GLEW_ARB_shader_storage_buffer_object = !_glewInit_GL_ARB_shader_storage_buffer_object();
+#endif /* GL_ARB_shader_storage_buffer_object */
+#ifdef GL_ARB_shader_subroutine
+ if (glewExperimental || GLEW_ARB_shader_subroutine) GLEW_ARB_shader_subroutine = !_glewInit_GL_ARB_shader_subroutine();
+#endif /* GL_ARB_shader_subroutine */
+#ifdef GL_ARB_shading_language_include
+ if (glewExperimental || GLEW_ARB_shading_language_include) GLEW_ARB_shading_language_include = !_glewInit_GL_ARB_shading_language_include();
+#endif /* GL_ARB_shading_language_include */
+#ifdef GL_ARB_sparse_buffer
+ if (glewExperimental || GLEW_ARB_sparse_buffer) GLEW_ARB_sparse_buffer = !_glewInit_GL_ARB_sparse_buffer();
+#endif /* GL_ARB_sparse_buffer */
+#ifdef GL_ARB_sparse_texture
+ if (glewExperimental || GLEW_ARB_sparse_texture) GLEW_ARB_sparse_texture = !_glewInit_GL_ARB_sparse_texture();
+#endif /* GL_ARB_sparse_texture */
+#ifdef GL_ARB_sync
+ if (glewExperimental || GLEW_ARB_sync) GLEW_ARB_sync = !_glewInit_GL_ARB_sync();
+#endif /* GL_ARB_sync */
+#ifdef GL_ARB_tessellation_shader
+ if (glewExperimental || GLEW_ARB_tessellation_shader) GLEW_ARB_tessellation_shader = !_glewInit_GL_ARB_tessellation_shader();
+#endif /* GL_ARB_tessellation_shader */
+#ifdef GL_ARB_texture_barrier
+ if (glewExperimental || GLEW_ARB_texture_barrier) GLEW_ARB_texture_barrier = !_glewInit_GL_ARB_texture_barrier();
+#endif /* GL_ARB_texture_barrier */
+#ifdef GL_ARB_texture_buffer_object
+ if (glewExperimental || GLEW_ARB_texture_buffer_object) GLEW_ARB_texture_buffer_object = !_glewInit_GL_ARB_texture_buffer_object();
+#endif /* GL_ARB_texture_buffer_object */
+#ifdef GL_ARB_texture_buffer_range
+ if (glewExperimental || GLEW_ARB_texture_buffer_range) GLEW_ARB_texture_buffer_range = !_glewInit_GL_ARB_texture_buffer_range();
+#endif /* GL_ARB_texture_buffer_range */
+#ifdef GL_ARB_texture_compression
+ if (glewExperimental || GLEW_ARB_texture_compression) GLEW_ARB_texture_compression = !_glewInit_GL_ARB_texture_compression();
+#endif /* GL_ARB_texture_compression */
+#ifdef GL_ARB_texture_multisample
+ if (glewExperimental || GLEW_ARB_texture_multisample) GLEW_ARB_texture_multisample = !_glewInit_GL_ARB_texture_multisample();
+#endif /* GL_ARB_texture_multisample */
+#ifdef GL_ARB_texture_storage
+ if (glewExperimental || GLEW_ARB_texture_storage) GLEW_ARB_texture_storage = !_glewInit_GL_ARB_texture_storage();
+#endif /* GL_ARB_texture_storage */
+#ifdef GL_ARB_texture_storage_multisample
+ if (glewExperimental || GLEW_ARB_texture_storage_multisample) GLEW_ARB_texture_storage_multisample = !_glewInit_GL_ARB_texture_storage_multisample();
+#endif /* GL_ARB_texture_storage_multisample */
+#ifdef GL_ARB_texture_view
+ if (glewExperimental || GLEW_ARB_texture_view) GLEW_ARB_texture_view = !_glewInit_GL_ARB_texture_view();
+#endif /* GL_ARB_texture_view */
+#ifdef GL_ARB_timer_query
+ if (glewExperimental || GLEW_ARB_timer_query) GLEW_ARB_timer_query = !_glewInit_GL_ARB_timer_query();
+#endif /* GL_ARB_timer_query */
+#ifdef GL_ARB_transform_feedback2
+ if (glewExperimental || GLEW_ARB_transform_feedback2) GLEW_ARB_transform_feedback2 = !_glewInit_GL_ARB_transform_feedback2();
+#endif /* GL_ARB_transform_feedback2 */
+#ifdef GL_ARB_transform_feedback3
+ if (glewExperimental || GLEW_ARB_transform_feedback3) GLEW_ARB_transform_feedback3 = !_glewInit_GL_ARB_transform_feedback3();
+#endif /* GL_ARB_transform_feedback3 */
+#ifdef GL_ARB_transform_feedback_instanced
+ if (glewExperimental || GLEW_ARB_transform_feedback_instanced) GLEW_ARB_transform_feedback_instanced = !_glewInit_GL_ARB_transform_feedback_instanced();
+#endif /* GL_ARB_transform_feedback_instanced */
+#ifdef GL_ARB_transpose_matrix
+ if (glewExperimental || GLEW_ARB_transpose_matrix) GLEW_ARB_transpose_matrix = !_glewInit_GL_ARB_transpose_matrix();
+#endif /* GL_ARB_transpose_matrix */
+#ifdef GL_ARB_uniform_buffer_object
+ if (glewExperimental || GLEW_ARB_uniform_buffer_object) GLEW_ARB_uniform_buffer_object = !_glewInit_GL_ARB_uniform_buffer_object();
+#endif /* GL_ARB_uniform_buffer_object */
+#ifdef GL_ARB_vertex_array_object
+ if (glewExperimental || GLEW_ARB_vertex_array_object) GLEW_ARB_vertex_array_object = !_glewInit_GL_ARB_vertex_array_object();
+#endif /* GL_ARB_vertex_array_object */
+#ifdef GL_ARB_vertex_attrib_64bit
+ if (glewExperimental || GLEW_ARB_vertex_attrib_64bit) GLEW_ARB_vertex_attrib_64bit = !_glewInit_GL_ARB_vertex_attrib_64bit();
+#endif /* GL_ARB_vertex_attrib_64bit */
+#ifdef GL_ARB_vertex_attrib_binding
+ if (glewExperimental || GLEW_ARB_vertex_attrib_binding) GLEW_ARB_vertex_attrib_binding = !_glewInit_GL_ARB_vertex_attrib_binding();
+#endif /* GL_ARB_vertex_attrib_binding */
+#ifdef GL_ARB_vertex_blend
+ if (glewExperimental || GLEW_ARB_vertex_blend) GLEW_ARB_vertex_blend = !_glewInit_GL_ARB_vertex_blend();
+#endif /* GL_ARB_vertex_blend */
+#ifdef GL_ARB_vertex_buffer_object
+ if (glewExperimental || GLEW_ARB_vertex_buffer_object) GLEW_ARB_vertex_buffer_object = !_glewInit_GL_ARB_vertex_buffer_object();
+#endif /* GL_ARB_vertex_buffer_object */
+#ifdef GL_ARB_vertex_program
+ if (glewExperimental || GLEW_ARB_vertex_program) GLEW_ARB_vertex_program = !_glewInit_GL_ARB_vertex_program();
+#endif /* GL_ARB_vertex_program */
+#ifdef GL_ARB_vertex_shader
+ if (glewExperimental || GLEW_ARB_vertex_shader) { GLEW_ARB_vertex_shader = !_glewInit_GL_ARB_vertex_shader(); _glewInit_GL_ARB_vertex_program(); }
+#endif /* GL_ARB_vertex_shader */
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ if (glewExperimental || GLEW_ARB_vertex_type_2_10_10_10_rev) GLEW_ARB_vertex_type_2_10_10_10_rev = !_glewInit_GL_ARB_vertex_type_2_10_10_10_rev();
+#endif /* GL_ARB_vertex_type_2_10_10_10_rev */
+#ifdef GL_ARB_viewport_array
+ if (glewExperimental || GLEW_ARB_viewport_array) GLEW_ARB_viewport_array = !_glewInit_GL_ARB_viewport_array();
+#endif /* GL_ARB_viewport_array */
+#ifdef GL_ARB_window_pos
+ if (glewExperimental || GLEW_ARB_window_pos) GLEW_ARB_window_pos = !_glewInit_GL_ARB_window_pos();
+#endif /* GL_ARB_window_pos */
+#ifdef GL_ATI_draw_buffers
+ if (glewExperimental || GLEW_ATI_draw_buffers) GLEW_ATI_draw_buffers = !_glewInit_GL_ATI_draw_buffers();
+#endif /* GL_ATI_draw_buffers */
+#ifdef GL_ATI_element_array
+ if (glewExperimental || GLEW_ATI_element_array) GLEW_ATI_element_array = !_glewInit_GL_ATI_element_array();
+#endif /* GL_ATI_element_array */
+#ifdef GL_ATI_envmap_bumpmap
+ if (glewExperimental || GLEW_ATI_envmap_bumpmap) GLEW_ATI_envmap_bumpmap = !_glewInit_GL_ATI_envmap_bumpmap();
+#endif /* GL_ATI_envmap_bumpmap */
+#ifdef GL_ATI_fragment_shader
+ if (glewExperimental || GLEW_ATI_fragment_shader) GLEW_ATI_fragment_shader = !_glewInit_GL_ATI_fragment_shader();
+#endif /* GL_ATI_fragment_shader */
+#ifdef GL_ATI_map_object_buffer
+ if (glewExperimental || GLEW_ATI_map_object_buffer) GLEW_ATI_map_object_buffer = !_glewInit_GL_ATI_map_object_buffer();
+#endif /* GL_ATI_map_object_buffer */
+#ifdef GL_ATI_pn_triangles
+ if (glewExperimental || GLEW_ATI_pn_triangles) GLEW_ATI_pn_triangles = !_glewInit_GL_ATI_pn_triangles();
+#endif /* GL_ATI_pn_triangles */
+#ifdef GL_ATI_separate_stencil
+ if (glewExperimental || GLEW_ATI_separate_stencil) GLEW_ATI_separate_stencil = !_glewInit_GL_ATI_separate_stencil();
+#endif /* GL_ATI_separate_stencil */
+#ifdef GL_ATI_vertex_array_object
+ if (glewExperimental || GLEW_ATI_vertex_array_object) GLEW_ATI_vertex_array_object = !_glewInit_GL_ATI_vertex_array_object();
+#endif /* GL_ATI_vertex_array_object */
+#ifdef GL_ATI_vertex_attrib_array_object
+ if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) GLEW_ATI_vertex_attrib_array_object = !_glewInit_GL_ATI_vertex_attrib_array_object();
+#endif /* GL_ATI_vertex_attrib_array_object */
+#ifdef GL_ATI_vertex_streams
+ if (glewExperimental || GLEW_ATI_vertex_streams) GLEW_ATI_vertex_streams = !_glewInit_GL_ATI_vertex_streams();
+#endif /* GL_ATI_vertex_streams */
+#ifdef GL_EXT_base_instance
+ if (glewExperimental || GLEW_EXT_base_instance) GLEW_EXT_base_instance = !_glewInit_GL_EXT_base_instance();
+#endif /* GL_EXT_base_instance */
+#ifdef GL_EXT_bindable_uniform
+ if (glewExperimental || GLEW_EXT_bindable_uniform) GLEW_EXT_bindable_uniform = !_glewInit_GL_EXT_bindable_uniform();
+#endif /* GL_EXT_bindable_uniform */
+#ifdef GL_EXT_blend_color
+ if (glewExperimental || GLEW_EXT_blend_color) GLEW_EXT_blend_color = !_glewInit_GL_EXT_blend_color();
+#endif /* GL_EXT_blend_color */
+#ifdef GL_EXT_blend_equation_separate
+ if (glewExperimental || GLEW_EXT_blend_equation_separate) GLEW_EXT_blend_equation_separate = !_glewInit_GL_EXT_blend_equation_separate();
+#endif /* GL_EXT_blend_equation_separate */
+#ifdef GL_EXT_blend_func_extended
+ if (glewExperimental || GLEW_EXT_blend_func_extended) GLEW_EXT_blend_func_extended = !_glewInit_GL_EXT_blend_func_extended();
+#endif /* GL_EXT_blend_func_extended */
+#ifdef GL_EXT_blend_func_separate
+ if (glewExperimental || GLEW_EXT_blend_func_separate) GLEW_EXT_blend_func_separate = !_glewInit_GL_EXT_blend_func_separate();
+#endif /* GL_EXT_blend_func_separate */
+#ifdef GL_EXT_blend_minmax
+ if (glewExperimental || GLEW_EXT_blend_minmax) GLEW_EXT_blend_minmax = !_glewInit_GL_EXT_blend_minmax();
+#endif /* GL_EXT_blend_minmax */
+#ifdef GL_EXT_buffer_storage
+ if (glewExperimental || GLEW_EXT_buffer_storage) GLEW_EXT_buffer_storage = !_glewInit_GL_EXT_buffer_storage();
+#endif /* GL_EXT_buffer_storage */
+#ifdef GL_EXT_clear_texture
+ if (glewExperimental || GLEW_EXT_clear_texture) GLEW_EXT_clear_texture = !_glewInit_GL_EXT_clear_texture();
+#endif /* GL_EXT_clear_texture */
+#ifdef GL_EXT_color_subtable
+ if (glewExperimental || GLEW_EXT_color_subtable) GLEW_EXT_color_subtable = !_glewInit_GL_EXT_color_subtable();
+#endif /* GL_EXT_color_subtable */
+#ifdef GL_EXT_compiled_vertex_array
+ if (glewExperimental || GLEW_EXT_compiled_vertex_array) GLEW_EXT_compiled_vertex_array = !_glewInit_GL_EXT_compiled_vertex_array();
+#endif /* GL_EXT_compiled_vertex_array */
+#ifdef GL_EXT_convolution
+ if (glewExperimental || GLEW_EXT_convolution) GLEW_EXT_convolution = !_glewInit_GL_EXT_convolution();
+#endif /* GL_EXT_convolution */
+#ifdef GL_EXT_coordinate_frame
+ if (glewExperimental || GLEW_EXT_coordinate_frame) GLEW_EXT_coordinate_frame = !_glewInit_GL_EXT_coordinate_frame();
+#endif /* GL_EXT_coordinate_frame */
+#ifdef GL_EXT_copy_image
+ if (glewExperimental || GLEW_EXT_copy_image) GLEW_EXT_copy_image = !_glewInit_GL_EXT_copy_image();
+#endif /* GL_EXT_copy_image */
+#ifdef GL_EXT_copy_texture
+ if (glewExperimental || GLEW_EXT_copy_texture) GLEW_EXT_copy_texture = !_glewInit_GL_EXT_copy_texture();
+#endif /* GL_EXT_copy_texture */
+#ifdef GL_EXT_cull_vertex
+ if (glewExperimental || GLEW_EXT_cull_vertex) GLEW_EXT_cull_vertex = !_glewInit_GL_EXT_cull_vertex();
+#endif /* GL_EXT_cull_vertex */
+#ifdef GL_EXT_debug_label
+ if (glewExperimental || GLEW_EXT_debug_label) GLEW_EXT_debug_label = !_glewInit_GL_EXT_debug_label();
+#endif /* GL_EXT_debug_label */
+#ifdef GL_EXT_debug_marker
+ if (glewExperimental || GLEW_EXT_debug_marker) GLEW_EXT_debug_marker = !_glewInit_GL_EXT_debug_marker();
+#endif /* GL_EXT_debug_marker */
+#ifdef GL_EXT_depth_bounds_test
+ if (glewExperimental || GLEW_EXT_depth_bounds_test) GLEW_EXT_depth_bounds_test = !_glewInit_GL_EXT_depth_bounds_test();
+#endif /* GL_EXT_depth_bounds_test */
+#ifdef GL_EXT_direct_state_access
+ if (glewExperimental || GLEW_EXT_direct_state_access) GLEW_EXT_direct_state_access = !_glewInit_GL_EXT_direct_state_access();
+#endif /* GL_EXT_direct_state_access */
+#ifdef GL_EXT_discard_framebuffer
+ if (glewExperimental || GLEW_EXT_discard_framebuffer) GLEW_EXT_discard_framebuffer = !_glewInit_GL_EXT_discard_framebuffer();
+#endif /* GL_EXT_discard_framebuffer */
+#ifdef GL_EXT_draw_buffers
+ if (glewExperimental || GLEW_EXT_draw_buffers) GLEW_EXT_draw_buffers = !_glewInit_GL_EXT_draw_buffers();
+#endif /* GL_EXT_draw_buffers */
+#ifdef GL_EXT_draw_buffers2
+ if (glewExperimental || GLEW_EXT_draw_buffers2) GLEW_EXT_draw_buffers2 = !_glewInit_GL_EXT_draw_buffers2();
+#endif /* GL_EXT_draw_buffers2 */
+#ifdef GL_EXT_draw_buffers_indexed
+ if (glewExperimental || GLEW_EXT_draw_buffers_indexed) GLEW_EXT_draw_buffers_indexed = !_glewInit_GL_EXT_draw_buffers_indexed();
+#endif /* GL_EXT_draw_buffers_indexed */
+#ifdef GL_EXT_draw_elements_base_vertex
+ if (glewExperimental || GLEW_EXT_draw_elements_base_vertex) GLEW_EXT_draw_elements_base_vertex = !_glewInit_GL_EXT_draw_elements_base_vertex();
+#endif /* GL_EXT_draw_elements_base_vertex */
+#ifdef GL_EXT_draw_instanced
+ if (glewExperimental || GLEW_EXT_draw_instanced) GLEW_EXT_draw_instanced = !_glewInit_GL_EXT_draw_instanced();
+#endif /* GL_EXT_draw_instanced */
+#ifdef GL_EXT_draw_range_elements
+ if (glewExperimental || GLEW_EXT_draw_range_elements) GLEW_EXT_draw_range_elements = !_glewInit_GL_EXT_draw_range_elements();
+#endif /* GL_EXT_draw_range_elements */
+#ifdef GL_EXT_external_buffer
+ if (glewExperimental || GLEW_EXT_external_buffer) GLEW_EXT_external_buffer = !_glewInit_GL_EXT_external_buffer();
+#endif /* GL_EXT_external_buffer */
+#ifdef GL_EXT_fog_coord
+ if (glewExperimental || GLEW_EXT_fog_coord) GLEW_EXT_fog_coord = !_glewInit_GL_EXT_fog_coord();
+#endif /* GL_EXT_fog_coord */
+#ifdef GL_EXT_fragment_lighting
+ if (glewExperimental || GLEW_EXT_fragment_lighting) GLEW_EXT_fragment_lighting = !_glewInit_GL_EXT_fragment_lighting();
+#endif /* GL_EXT_fragment_lighting */
+#ifdef GL_EXT_framebuffer_blit
+ if (glewExperimental || GLEW_EXT_framebuffer_blit) GLEW_EXT_framebuffer_blit = !_glewInit_GL_EXT_framebuffer_blit();
+#endif /* GL_EXT_framebuffer_blit */
+#ifdef GL_EXT_framebuffer_multisample
+ if (glewExperimental || GLEW_EXT_framebuffer_multisample) GLEW_EXT_framebuffer_multisample = !_glewInit_GL_EXT_framebuffer_multisample();
+#endif /* GL_EXT_framebuffer_multisample */
+#ifdef GL_EXT_framebuffer_object
+ if (glewExperimental || GLEW_EXT_framebuffer_object) GLEW_EXT_framebuffer_object = !_glewInit_GL_EXT_framebuffer_object();
+#endif /* GL_EXT_framebuffer_object */
+#ifdef GL_EXT_geometry_shader4
+ if (glewExperimental || GLEW_EXT_geometry_shader4) GLEW_EXT_geometry_shader4 = !_glewInit_GL_EXT_geometry_shader4();
+#endif /* GL_EXT_geometry_shader4 */
+#ifdef GL_EXT_gpu_program_parameters
+ if (glewExperimental || GLEW_EXT_gpu_program_parameters) GLEW_EXT_gpu_program_parameters = !_glewInit_GL_EXT_gpu_program_parameters();
+#endif /* GL_EXT_gpu_program_parameters */
+#ifdef GL_EXT_gpu_shader4
+ if (glewExperimental || GLEW_EXT_gpu_shader4) GLEW_EXT_gpu_shader4 = !_glewInit_GL_EXT_gpu_shader4();
+#endif /* GL_EXT_gpu_shader4 */
+#ifdef GL_EXT_histogram
+ if (glewExperimental || GLEW_EXT_histogram) GLEW_EXT_histogram = !_glewInit_GL_EXT_histogram();
+#endif /* GL_EXT_histogram */
+#ifdef GL_EXT_index_func
+ if (glewExperimental || GLEW_EXT_index_func) GLEW_EXT_index_func = !_glewInit_GL_EXT_index_func();
+#endif /* GL_EXT_index_func */
+#ifdef GL_EXT_index_material
+ if (glewExperimental || GLEW_EXT_index_material) GLEW_EXT_index_material = !_glewInit_GL_EXT_index_material();
+#endif /* GL_EXT_index_material */
+#ifdef GL_EXT_instanced_arrays
+ if (glewExperimental || GLEW_EXT_instanced_arrays) GLEW_EXT_instanced_arrays = !_glewInit_GL_EXT_instanced_arrays();
+#endif /* GL_EXT_instanced_arrays */
+#ifdef GL_EXT_light_texture
+ if (glewExperimental || GLEW_EXT_light_texture) GLEW_EXT_light_texture = !_glewInit_GL_EXT_light_texture();
+#endif /* GL_EXT_light_texture */
+#ifdef GL_EXT_map_buffer_range
+ if (glewExperimental || GLEW_EXT_map_buffer_range) GLEW_EXT_map_buffer_range = !_glewInit_GL_EXT_map_buffer_range();
+#endif /* GL_EXT_map_buffer_range */
+#ifdef GL_EXT_memory_object
+ if (glewExperimental || GLEW_EXT_memory_object) GLEW_EXT_memory_object = !_glewInit_GL_EXT_memory_object();
+#endif /* GL_EXT_memory_object */
+#ifdef GL_EXT_memory_object_fd
+ if (glewExperimental || GLEW_EXT_memory_object_fd) GLEW_EXT_memory_object_fd = !_glewInit_GL_EXT_memory_object_fd();
+#endif /* GL_EXT_memory_object_fd */
+#ifdef GL_EXT_memory_object_win32
+ if (glewExperimental || GLEW_EXT_memory_object_win32) GLEW_EXT_memory_object_win32 = !_glewInit_GL_EXT_memory_object_win32();
+#endif /* GL_EXT_memory_object_win32 */
+#ifdef GL_EXT_multi_draw_arrays
+ if (glewExperimental || GLEW_EXT_multi_draw_arrays) GLEW_EXT_multi_draw_arrays = !_glewInit_GL_EXT_multi_draw_arrays();
+#endif /* GL_EXT_multi_draw_arrays */
+#ifdef GL_EXT_multi_draw_indirect
+ if (glewExperimental || GLEW_EXT_multi_draw_indirect) GLEW_EXT_multi_draw_indirect = !_glewInit_GL_EXT_multi_draw_indirect();
+#endif /* GL_EXT_multi_draw_indirect */
+#ifdef GL_EXT_multisample
+ if (glewExperimental || GLEW_EXT_multisample) GLEW_EXT_multisample = !_glewInit_GL_EXT_multisample();
+#endif /* GL_EXT_multisample */
+#ifdef GL_EXT_multisampled_render_to_texture
+ if (glewExperimental || GLEW_EXT_multisampled_render_to_texture) GLEW_EXT_multisampled_render_to_texture = !_glewInit_GL_EXT_multisampled_render_to_texture();
+#endif /* GL_EXT_multisampled_render_to_texture */
+#ifdef GL_EXT_multiview_draw_buffers
+ if (glewExperimental || GLEW_EXT_multiview_draw_buffers) GLEW_EXT_multiview_draw_buffers = !_glewInit_GL_EXT_multiview_draw_buffers();
+#endif /* GL_EXT_multiview_draw_buffers */
+#ifdef GL_EXT_paletted_texture
+ if (glewExperimental || GLEW_EXT_paletted_texture) GLEW_EXT_paletted_texture = !_glewInit_GL_EXT_paletted_texture();
+#endif /* GL_EXT_paletted_texture */
+#ifdef GL_EXT_pixel_transform
+ if (glewExperimental || GLEW_EXT_pixel_transform) GLEW_EXT_pixel_transform = !_glewInit_GL_EXT_pixel_transform();
+#endif /* GL_EXT_pixel_transform */
+#ifdef GL_EXT_point_parameters
+ if (glewExperimental || GLEW_EXT_point_parameters) GLEW_EXT_point_parameters = !_glewInit_GL_EXT_point_parameters();
+#endif /* GL_EXT_point_parameters */
+#ifdef GL_EXT_polygon_offset
+ if (glewExperimental || GLEW_EXT_polygon_offset) GLEW_EXT_polygon_offset = !_glewInit_GL_EXT_polygon_offset();
+#endif /* GL_EXT_polygon_offset */
+#ifdef GL_EXT_polygon_offset_clamp
+ if (glewExperimental || GLEW_EXT_polygon_offset_clamp) GLEW_EXT_polygon_offset_clamp = !_glewInit_GL_EXT_polygon_offset_clamp();
+#endif /* GL_EXT_polygon_offset_clamp */
+#ifdef GL_EXT_provoking_vertex
+ if (glewExperimental || GLEW_EXT_provoking_vertex) GLEW_EXT_provoking_vertex = !_glewInit_GL_EXT_provoking_vertex();
+#endif /* GL_EXT_provoking_vertex */
+#ifdef GL_EXT_raster_multisample
+ if (glewExperimental || GLEW_EXT_raster_multisample) GLEW_EXT_raster_multisample = !_glewInit_GL_EXT_raster_multisample();
+#endif /* GL_EXT_raster_multisample */
+#ifdef GL_EXT_scene_marker
+ if (glewExperimental || GLEW_EXT_scene_marker) GLEW_EXT_scene_marker = !_glewInit_GL_EXT_scene_marker();
+#endif /* GL_EXT_scene_marker */
+#ifdef GL_EXT_secondary_color
+ if (glewExperimental || GLEW_EXT_secondary_color) GLEW_EXT_secondary_color = !_glewInit_GL_EXT_secondary_color();
+#endif /* GL_EXT_secondary_color */
+#ifdef GL_EXT_semaphore
+ if (glewExperimental || GLEW_EXT_semaphore) GLEW_EXT_semaphore = !_glewInit_GL_EXT_semaphore();
+#endif /* GL_EXT_semaphore */
+#ifdef GL_EXT_semaphore_fd
+ if (glewExperimental || GLEW_EXT_semaphore_fd) GLEW_EXT_semaphore_fd = !_glewInit_GL_EXT_semaphore_fd();
+#endif /* GL_EXT_semaphore_fd */
+#ifdef GL_EXT_semaphore_win32
+ if (glewExperimental || GLEW_EXT_semaphore_win32) GLEW_EXT_semaphore_win32 = !_glewInit_GL_EXT_semaphore_win32();
+#endif /* GL_EXT_semaphore_win32 */
+#ifdef GL_EXT_separate_shader_objects
+ if (glewExperimental || GLEW_EXT_separate_shader_objects) GLEW_EXT_separate_shader_objects = !_glewInit_GL_EXT_separate_shader_objects();
+#endif /* GL_EXT_separate_shader_objects */
+#ifdef GL_EXT_shader_image_load_store
+ if (glewExperimental || GLEW_EXT_shader_image_load_store) GLEW_EXT_shader_image_load_store = !_glewInit_GL_EXT_shader_image_load_store();
+#endif /* GL_EXT_shader_image_load_store */
+#ifdef GL_EXT_shader_pixel_local_storage2
+ if (glewExperimental || GLEW_EXT_shader_pixel_local_storage2) GLEW_EXT_shader_pixel_local_storage2 = !_glewInit_GL_EXT_shader_pixel_local_storage2();
+#endif /* GL_EXT_shader_pixel_local_storage2 */
+#ifdef GL_EXT_sparse_texture
+ if (glewExperimental || GLEW_EXT_sparse_texture) GLEW_EXT_sparse_texture = !_glewInit_GL_EXT_sparse_texture();
+#endif /* GL_EXT_sparse_texture */
+#ifdef GL_EXT_stencil_two_side
+ if (glewExperimental || GLEW_EXT_stencil_two_side) GLEW_EXT_stencil_two_side = !_glewInit_GL_EXT_stencil_two_side();
+#endif /* GL_EXT_stencil_two_side */
+#ifdef GL_EXT_subtexture
+ if (glewExperimental || GLEW_EXT_subtexture) GLEW_EXT_subtexture = !_glewInit_GL_EXT_subtexture();
+#endif /* GL_EXT_subtexture */
+#ifdef GL_EXT_texture3D
+ if (glewExperimental || GLEW_EXT_texture3D) GLEW_EXT_texture3D = !_glewInit_GL_EXT_texture3D();
+#endif /* GL_EXT_texture3D */
+#ifdef GL_EXT_texture_array
+ if (glewExperimental || GLEW_EXT_texture_array) GLEW_EXT_texture_array = !_glewInit_GL_EXT_texture_array();
+#endif /* GL_EXT_texture_array */
+#ifdef GL_EXT_texture_buffer_object
+ if (glewExperimental || GLEW_EXT_texture_buffer_object) GLEW_EXT_texture_buffer_object = !_glewInit_GL_EXT_texture_buffer_object();
+#endif /* GL_EXT_texture_buffer_object */
+#ifdef GL_EXT_texture_integer
+ if (glewExperimental || GLEW_EXT_texture_integer) GLEW_EXT_texture_integer = !_glewInit_GL_EXT_texture_integer();
+#endif /* GL_EXT_texture_integer */
+#ifdef GL_EXT_texture_object
+ if (glewExperimental || GLEW_EXT_texture_object) GLEW_EXT_texture_object = !_glewInit_GL_EXT_texture_object();
+#endif /* GL_EXT_texture_object */
+#ifdef GL_EXT_texture_perturb_normal
+ if (glewExperimental || GLEW_EXT_texture_perturb_normal) GLEW_EXT_texture_perturb_normal = !_glewInit_GL_EXT_texture_perturb_normal();
+#endif /* GL_EXT_texture_perturb_normal */
+#ifdef GL_EXT_texture_storage
+ if (glewExperimental || GLEW_EXT_texture_storage) GLEW_EXT_texture_storage = !_glewInit_GL_EXT_texture_storage();
+#endif /* GL_EXT_texture_storage */
+#ifdef GL_EXT_texture_view
+ if (glewExperimental || GLEW_EXT_texture_view) GLEW_EXT_texture_view = !_glewInit_GL_EXT_texture_view();
+#endif /* GL_EXT_texture_view */
+#ifdef GL_EXT_timer_query
+ if (glewExperimental || GLEW_EXT_timer_query) GLEW_EXT_timer_query = !_glewInit_GL_EXT_timer_query();
+#endif /* GL_EXT_timer_query */
+#ifdef GL_EXT_transform_feedback
+ if (glewExperimental || GLEW_EXT_transform_feedback) GLEW_EXT_transform_feedback = !_glewInit_GL_EXT_transform_feedback();
+#endif /* GL_EXT_transform_feedback */
+#ifdef GL_EXT_vertex_array
+ if (glewExperimental || GLEW_EXT_vertex_array) GLEW_EXT_vertex_array = !_glewInit_GL_EXT_vertex_array();
+#endif /* GL_EXT_vertex_array */
+#ifdef GL_EXT_vertex_array_setXXX
+ if (glewExperimental || GLEW_EXT_vertex_array_setXXX) GLEW_EXT_vertex_array_setXXX = !_glewInit_GL_EXT_vertex_array_setXXX();
+#endif /* GL_EXT_vertex_array_setXXX */
+#ifdef GL_EXT_vertex_attrib_64bit
+ if (glewExperimental || GLEW_EXT_vertex_attrib_64bit) GLEW_EXT_vertex_attrib_64bit = !_glewInit_GL_EXT_vertex_attrib_64bit();
+#endif /* GL_EXT_vertex_attrib_64bit */
+#ifdef GL_EXT_vertex_shader
+ if (glewExperimental || GLEW_EXT_vertex_shader) GLEW_EXT_vertex_shader = !_glewInit_GL_EXT_vertex_shader();
+#endif /* GL_EXT_vertex_shader */
+#ifdef GL_EXT_vertex_weighting
+ if (glewExperimental || GLEW_EXT_vertex_weighting) GLEW_EXT_vertex_weighting = !_glewInit_GL_EXT_vertex_weighting();
+#endif /* GL_EXT_vertex_weighting */
+#ifdef GL_EXT_win32_keyed_mutex
+ if (glewExperimental || GLEW_EXT_win32_keyed_mutex) GLEW_EXT_win32_keyed_mutex = !_glewInit_GL_EXT_win32_keyed_mutex();
+#endif /* GL_EXT_win32_keyed_mutex */
+#ifdef GL_EXT_window_rectangles
+ if (glewExperimental || GLEW_EXT_window_rectangles) GLEW_EXT_window_rectangles = !_glewInit_GL_EXT_window_rectangles();
+#endif /* GL_EXT_window_rectangles */
+#ifdef GL_EXT_x11_sync_object
+ if (glewExperimental || GLEW_EXT_x11_sync_object) GLEW_EXT_x11_sync_object = !_glewInit_GL_EXT_x11_sync_object();
+#endif /* GL_EXT_x11_sync_object */
+#ifdef GL_GREMEDY_frame_terminator
+ if (glewExperimental || GLEW_GREMEDY_frame_terminator) GLEW_GREMEDY_frame_terminator = !_glewInit_GL_GREMEDY_frame_terminator();
+#endif /* GL_GREMEDY_frame_terminator */
+#ifdef GL_GREMEDY_string_marker
+ if (glewExperimental || GLEW_GREMEDY_string_marker) GLEW_GREMEDY_string_marker = !_glewInit_GL_GREMEDY_string_marker();
+#endif /* GL_GREMEDY_string_marker */
+#ifdef GL_HP_image_transform
+ if (glewExperimental || GLEW_HP_image_transform) GLEW_HP_image_transform = !_glewInit_GL_HP_image_transform();
+#endif /* GL_HP_image_transform */
+#ifdef GL_IBM_multimode_draw_arrays
+ if (glewExperimental || GLEW_IBM_multimode_draw_arrays) GLEW_IBM_multimode_draw_arrays = !_glewInit_GL_IBM_multimode_draw_arrays();
+#endif /* GL_IBM_multimode_draw_arrays */
+#ifdef GL_IBM_vertex_array_lists
+ if (glewExperimental || GLEW_IBM_vertex_array_lists) GLEW_IBM_vertex_array_lists = !_glewInit_GL_IBM_vertex_array_lists();
+#endif /* GL_IBM_vertex_array_lists */
+#ifdef GL_INTEL_map_texture
+ if (glewExperimental || GLEW_INTEL_map_texture) GLEW_INTEL_map_texture = !_glewInit_GL_INTEL_map_texture();
+#endif /* GL_INTEL_map_texture */
+#ifdef GL_INTEL_parallel_arrays
+ if (glewExperimental || GLEW_INTEL_parallel_arrays) GLEW_INTEL_parallel_arrays = !_glewInit_GL_INTEL_parallel_arrays();
+#endif /* GL_INTEL_parallel_arrays */
+#ifdef GL_INTEL_performance_query
+ if (glewExperimental || GLEW_INTEL_performance_query) GLEW_INTEL_performance_query = !_glewInit_GL_INTEL_performance_query();
+#endif /* GL_INTEL_performance_query */
+#ifdef GL_INTEL_texture_scissor
+ if (glewExperimental || GLEW_INTEL_texture_scissor) GLEW_INTEL_texture_scissor = !_glewInit_GL_INTEL_texture_scissor();
+#endif /* GL_INTEL_texture_scissor */
+#ifdef GL_KHR_blend_equation_advanced
+ if (glewExperimental || GLEW_KHR_blend_equation_advanced) GLEW_KHR_blend_equation_advanced = !_glewInit_GL_KHR_blend_equation_advanced();
+#endif /* GL_KHR_blend_equation_advanced */
+#ifdef GL_KHR_debug
+ if (glewExperimental || GLEW_KHR_debug) GLEW_KHR_debug = !_glewInit_GL_KHR_debug();
+#endif /* GL_KHR_debug */
+#ifdef GL_KHR_parallel_shader_compile
+ if (glewExperimental || GLEW_KHR_parallel_shader_compile) GLEW_KHR_parallel_shader_compile = !_glewInit_GL_KHR_parallel_shader_compile();
+#endif /* GL_KHR_parallel_shader_compile */
+#ifdef GL_KHR_robustness
+ if (glewExperimental || GLEW_KHR_robustness) GLEW_KHR_robustness = !_glewInit_GL_KHR_robustness();
+#endif /* GL_KHR_robustness */
+#ifdef GL_KTX_buffer_region
+ if (glewExperimental || GLEW_KTX_buffer_region) GLEW_KTX_buffer_region = !_glewInit_GL_KTX_buffer_region();
+#endif /* GL_KTX_buffer_region */
+#ifdef GL_MESA_resize_buffers
+ if (glewExperimental || GLEW_MESA_resize_buffers) GLEW_MESA_resize_buffers = !_glewInit_GL_MESA_resize_buffers();
+#endif /* GL_MESA_resize_buffers */
+#ifdef GL_MESA_window_pos
+ if (glewExperimental || GLEW_MESA_window_pos) GLEW_MESA_window_pos = !_glewInit_GL_MESA_window_pos();
+#endif /* GL_MESA_window_pos */
+#ifdef GL_NVX_conditional_render
+ if (glewExperimental || GLEW_NVX_conditional_render) GLEW_NVX_conditional_render = !_glewInit_GL_NVX_conditional_render();
+#endif /* GL_NVX_conditional_render */
+#ifdef GL_NVX_linked_gpu_multicast
+ if (glewExperimental || GLEW_NVX_linked_gpu_multicast) GLEW_NVX_linked_gpu_multicast = !_glewInit_GL_NVX_linked_gpu_multicast();
+#endif /* GL_NVX_linked_gpu_multicast */
+#ifdef GL_NV_3dvision_settings
+ if (glewExperimental || GLEW_NV_3dvision_settings) GLEW_NV_3dvision_settings = !_glewInit_GL_NV_3dvision_settings();
+#endif /* GL_NV_3dvision_settings */
+#ifdef GL_NV_bindless_multi_draw_indirect
+ if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect) GLEW_NV_bindless_multi_draw_indirect = !_glewInit_GL_NV_bindless_multi_draw_indirect();
+#endif /* GL_NV_bindless_multi_draw_indirect */
+#ifdef GL_NV_bindless_multi_draw_indirect_count
+ if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect_count) GLEW_NV_bindless_multi_draw_indirect_count = !_glewInit_GL_NV_bindless_multi_draw_indirect_count();
+#endif /* GL_NV_bindless_multi_draw_indirect_count */
+#ifdef GL_NV_bindless_texture
+ if (glewExperimental || GLEW_NV_bindless_texture) GLEW_NV_bindless_texture = !_glewInit_GL_NV_bindless_texture();
+#endif /* GL_NV_bindless_texture */
+#ifdef GL_NV_blend_equation_advanced
+ if (glewExperimental || GLEW_NV_blend_equation_advanced) GLEW_NV_blend_equation_advanced = !_glewInit_GL_NV_blend_equation_advanced();
+#endif /* GL_NV_blend_equation_advanced */
+#ifdef GL_NV_clip_space_w_scaling
+ if (glewExperimental || GLEW_NV_clip_space_w_scaling) GLEW_NV_clip_space_w_scaling = !_glewInit_GL_NV_clip_space_w_scaling();
+#endif /* GL_NV_clip_space_w_scaling */
+#ifdef GL_NV_command_list
+ if (glewExperimental || GLEW_NV_command_list) GLEW_NV_command_list = !_glewInit_GL_NV_command_list();
+#endif /* GL_NV_command_list */
+#ifdef GL_NV_conditional_render
+ if (glewExperimental || GLEW_NV_conditional_render) GLEW_NV_conditional_render = !_glewInit_GL_NV_conditional_render();
+#endif /* GL_NV_conditional_render */
+#ifdef GL_NV_conservative_raster
+ if (glewExperimental || GLEW_NV_conservative_raster) GLEW_NV_conservative_raster = !_glewInit_GL_NV_conservative_raster();
+#endif /* GL_NV_conservative_raster */
+#ifdef GL_NV_conservative_raster_dilate
+ if (glewExperimental || GLEW_NV_conservative_raster_dilate) GLEW_NV_conservative_raster_dilate = !_glewInit_GL_NV_conservative_raster_dilate();
+#endif /* GL_NV_conservative_raster_dilate */
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ if (glewExperimental || GLEW_NV_conservative_raster_pre_snap_triangles) GLEW_NV_conservative_raster_pre_snap_triangles = !_glewInit_GL_NV_conservative_raster_pre_snap_triangles();
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+#ifdef GL_NV_copy_buffer
+ if (glewExperimental || GLEW_NV_copy_buffer) GLEW_NV_copy_buffer = !_glewInit_GL_NV_copy_buffer();
+#endif /* GL_NV_copy_buffer */
+#ifdef GL_NV_copy_image
+ if (glewExperimental || GLEW_NV_copy_image) GLEW_NV_copy_image = !_glewInit_GL_NV_copy_image();
+#endif /* GL_NV_copy_image */
+#ifdef GL_NV_depth_buffer_float
+ if (glewExperimental || GLEW_NV_depth_buffer_float) GLEW_NV_depth_buffer_float = !_glewInit_GL_NV_depth_buffer_float();
+#endif /* GL_NV_depth_buffer_float */
+#ifdef GL_NV_draw_buffers
+ if (glewExperimental || GLEW_NV_draw_buffers) GLEW_NV_draw_buffers = !_glewInit_GL_NV_draw_buffers();
+#endif /* GL_NV_draw_buffers */
+#ifdef GL_NV_draw_instanced
+ if (glewExperimental || GLEW_NV_draw_instanced) GLEW_NV_draw_instanced = !_glewInit_GL_NV_draw_instanced();
+#endif /* GL_NV_draw_instanced */
+#ifdef GL_NV_draw_texture
+ if (glewExperimental || GLEW_NV_draw_texture) GLEW_NV_draw_texture = !_glewInit_GL_NV_draw_texture();
+#endif /* GL_NV_draw_texture */
+#ifdef GL_NV_draw_vulkan_image
+ if (glewExperimental || GLEW_NV_draw_vulkan_image) GLEW_NV_draw_vulkan_image = !_glewInit_GL_NV_draw_vulkan_image();
+#endif /* GL_NV_draw_vulkan_image */
+#ifdef GL_NV_evaluators
+ if (glewExperimental || GLEW_NV_evaluators) GLEW_NV_evaluators = !_glewInit_GL_NV_evaluators();
+#endif /* GL_NV_evaluators */
+#ifdef GL_NV_explicit_multisample
+ if (glewExperimental || GLEW_NV_explicit_multisample) GLEW_NV_explicit_multisample = !_glewInit_GL_NV_explicit_multisample();
+#endif /* GL_NV_explicit_multisample */
+#ifdef GL_NV_fence
+ if (glewExperimental || GLEW_NV_fence) GLEW_NV_fence = !_glewInit_GL_NV_fence();
+#endif /* GL_NV_fence */
+#ifdef GL_NV_fragment_coverage_to_color
+ if (glewExperimental || GLEW_NV_fragment_coverage_to_color) GLEW_NV_fragment_coverage_to_color = !_glewInit_GL_NV_fragment_coverage_to_color();
+#endif /* GL_NV_fragment_coverage_to_color */
+#ifdef GL_NV_fragment_program
+ if (glewExperimental || GLEW_NV_fragment_program) GLEW_NV_fragment_program = !_glewInit_GL_NV_fragment_program();
+#endif /* GL_NV_fragment_program */
+#ifdef GL_NV_framebuffer_blit
+ if (glewExperimental || GLEW_NV_framebuffer_blit) GLEW_NV_framebuffer_blit = !_glewInit_GL_NV_framebuffer_blit();
+#endif /* GL_NV_framebuffer_blit */
+#ifdef GL_NV_framebuffer_multisample
+ if (glewExperimental || GLEW_NV_framebuffer_multisample) GLEW_NV_framebuffer_multisample = !_glewInit_GL_NV_framebuffer_multisample();
+#endif /* GL_NV_framebuffer_multisample */
+#ifdef GL_NV_framebuffer_multisample_coverage
+ if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) GLEW_NV_framebuffer_multisample_coverage = !_glewInit_GL_NV_framebuffer_multisample_coverage();
+#endif /* GL_NV_framebuffer_multisample_coverage */
+#ifdef GL_NV_geometry_program4
+ if (glewExperimental || GLEW_NV_geometry_program4) GLEW_NV_geometry_program4 = !_glewInit_GL_NV_geometry_program4();
+#endif /* GL_NV_geometry_program4 */
+#ifdef GL_NV_gpu_multicast
+ if (glewExperimental || GLEW_NV_gpu_multicast) GLEW_NV_gpu_multicast = !_glewInit_GL_NV_gpu_multicast();
+#endif /* GL_NV_gpu_multicast */
+#ifdef GL_NV_gpu_program4
+ if (glewExperimental || GLEW_NV_gpu_program4) GLEW_NV_gpu_program4 = !_glewInit_GL_NV_gpu_program4();
+#endif /* GL_NV_gpu_program4 */
+#ifdef GL_NV_gpu_shader5
+ if (glewExperimental || GLEW_NV_gpu_shader5) GLEW_NV_gpu_shader5 = !_glewInit_GL_NV_gpu_shader5();
+#endif /* GL_NV_gpu_shader5 */
+#ifdef GL_NV_half_float
+ if (glewExperimental || GLEW_NV_half_float) GLEW_NV_half_float = !_glewInit_GL_NV_half_float();
+#endif /* GL_NV_half_float */
+#ifdef GL_NV_instanced_arrays
+ if (glewExperimental || GLEW_NV_instanced_arrays) GLEW_NV_instanced_arrays = !_glewInit_GL_NV_instanced_arrays();
+#endif /* GL_NV_instanced_arrays */
+#ifdef GL_NV_internalformat_sample_query
+ if (glewExperimental || GLEW_NV_internalformat_sample_query) GLEW_NV_internalformat_sample_query = !_glewInit_GL_NV_internalformat_sample_query();
+#endif /* GL_NV_internalformat_sample_query */
+#ifdef GL_NV_non_square_matrices
+ if (glewExperimental || GLEW_NV_non_square_matrices) GLEW_NV_non_square_matrices = !_glewInit_GL_NV_non_square_matrices();
+#endif /* GL_NV_non_square_matrices */
+#ifdef GL_NV_occlusion_query
+ if (glewExperimental || GLEW_NV_occlusion_query) GLEW_NV_occlusion_query = !_glewInit_GL_NV_occlusion_query();
+#endif /* GL_NV_occlusion_query */
+#ifdef GL_NV_parameter_buffer_object
+ if (glewExperimental || GLEW_NV_parameter_buffer_object) GLEW_NV_parameter_buffer_object = !_glewInit_GL_NV_parameter_buffer_object();
+#endif /* GL_NV_parameter_buffer_object */
+#ifdef GL_NV_path_rendering
+ if (glewExperimental || GLEW_NV_path_rendering) GLEW_NV_path_rendering = !_glewInit_GL_NV_path_rendering();
+#endif /* GL_NV_path_rendering */
+#ifdef GL_NV_pixel_data_range
+ if (glewExperimental || GLEW_NV_pixel_data_range) GLEW_NV_pixel_data_range = !_glewInit_GL_NV_pixel_data_range();
+#endif /* GL_NV_pixel_data_range */
+#ifdef GL_NV_point_sprite
+ if (glewExperimental || GLEW_NV_point_sprite) GLEW_NV_point_sprite = !_glewInit_GL_NV_point_sprite();
+#endif /* GL_NV_point_sprite */
+#ifdef GL_NV_polygon_mode
+ if (glewExperimental || GLEW_NV_polygon_mode) GLEW_NV_polygon_mode = !_glewInit_GL_NV_polygon_mode();
+#endif /* GL_NV_polygon_mode */
+#ifdef GL_NV_present_video
+ if (glewExperimental || GLEW_NV_present_video) GLEW_NV_present_video = !_glewInit_GL_NV_present_video();
+#endif /* GL_NV_present_video */
+#ifdef GL_NV_primitive_restart
+ if (glewExperimental || GLEW_NV_primitive_restart) GLEW_NV_primitive_restart = !_glewInit_GL_NV_primitive_restart();
+#endif /* GL_NV_primitive_restart */
+#ifdef GL_NV_register_combiners
+ if (glewExperimental || GLEW_NV_register_combiners) GLEW_NV_register_combiners = !_glewInit_GL_NV_register_combiners();
+#endif /* GL_NV_register_combiners */
+#ifdef GL_NV_register_combiners2
+ if (glewExperimental || GLEW_NV_register_combiners2) GLEW_NV_register_combiners2 = !_glewInit_GL_NV_register_combiners2();
+#endif /* GL_NV_register_combiners2 */
+#ifdef GL_NV_sample_locations
+ if (glewExperimental || GLEW_NV_sample_locations) GLEW_NV_sample_locations = !_glewInit_GL_NV_sample_locations();
+#endif /* GL_NV_sample_locations */
+#ifdef GL_NV_shader_buffer_load
+ if (glewExperimental || GLEW_NV_shader_buffer_load) GLEW_NV_shader_buffer_load = !_glewInit_GL_NV_shader_buffer_load();
+#endif /* GL_NV_shader_buffer_load */
+#ifdef GL_NV_texture_array
+ if (glewExperimental || GLEW_NV_texture_array) GLEW_NV_texture_array = !_glewInit_GL_NV_texture_array();
+#endif /* GL_NV_texture_array */
+#ifdef GL_NV_texture_barrier
+ if (glewExperimental || GLEW_NV_texture_barrier) GLEW_NV_texture_barrier = !_glewInit_GL_NV_texture_barrier();
+#endif /* GL_NV_texture_barrier */
+#ifdef GL_NV_texture_multisample
+ if (glewExperimental || GLEW_NV_texture_multisample) GLEW_NV_texture_multisample = !_glewInit_GL_NV_texture_multisample();
+#endif /* GL_NV_texture_multisample */
+#ifdef GL_NV_transform_feedback
+ if (glewExperimental || GLEW_NV_transform_feedback) GLEW_NV_transform_feedback = !_glewInit_GL_NV_transform_feedback();
+#endif /* GL_NV_transform_feedback */
+#ifdef GL_NV_transform_feedback2
+ if (glewExperimental || GLEW_NV_transform_feedback2) GLEW_NV_transform_feedback2 = !_glewInit_GL_NV_transform_feedback2();
+#endif /* GL_NV_transform_feedback2 */
+#ifdef GL_NV_vdpau_interop
+ if (glewExperimental || GLEW_NV_vdpau_interop) GLEW_NV_vdpau_interop = !_glewInit_GL_NV_vdpau_interop();
+#endif /* GL_NV_vdpau_interop */
+#ifdef GL_NV_vertex_array_range
+ if (glewExperimental || GLEW_NV_vertex_array_range) GLEW_NV_vertex_array_range = !_glewInit_GL_NV_vertex_array_range();
+#endif /* GL_NV_vertex_array_range */
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ if (glewExperimental || GLEW_NV_vertex_attrib_integer_64bit) GLEW_NV_vertex_attrib_integer_64bit = !_glewInit_GL_NV_vertex_attrib_integer_64bit();
+#endif /* GL_NV_vertex_attrib_integer_64bit */
+#ifdef GL_NV_vertex_buffer_unified_memory
+ if (glewExperimental || GLEW_NV_vertex_buffer_unified_memory) GLEW_NV_vertex_buffer_unified_memory = !_glewInit_GL_NV_vertex_buffer_unified_memory();
+#endif /* GL_NV_vertex_buffer_unified_memory */
+#ifdef GL_NV_vertex_program
+ if (glewExperimental || GLEW_NV_vertex_program) GLEW_NV_vertex_program = !_glewInit_GL_NV_vertex_program();
+#endif /* GL_NV_vertex_program */
+#ifdef GL_NV_video_capture
+ if (glewExperimental || GLEW_NV_video_capture) GLEW_NV_video_capture = !_glewInit_GL_NV_video_capture();
+#endif /* GL_NV_video_capture */
+#ifdef GL_NV_viewport_array
+ if (glewExperimental || GLEW_NV_viewport_array) GLEW_NV_viewport_array = !_glewInit_GL_NV_viewport_array();
+#endif /* GL_NV_viewport_array */
+#ifdef GL_NV_viewport_swizzle
+ if (glewExperimental || GLEW_NV_viewport_swizzle) GLEW_NV_viewport_swizzle = !_glewInit_GL_NV_viewport_swizzle();
+#endif /* GL_NV_viewport_swizzle */
+#ifdef GL_OVR_multiview
+ if (glewExperimental || GLEW_OVR_multiview) GLEW_OVR_multiview = !_glewInit_GL_OVR_multiview();
+#endif /* GL_OVR_multiview */
+#ifdef GL_OVR_multiview_multisampled_render_to_texture
+ if (glewExperimental || GLEW_OVR_multiview_multisampled_render_to_texture) GLEW_OVR_multiview_multisampled_render_to_texture = !_glewInit_GL_OVR_multiview_multisampled_render_to_texture();
+#endif /* GL_OVR_multiview_multisampled_render_to_texture */
+#ifdef GL_QCOM_alpha_test
+ if (glewExperimental || GLEW_QCOM_alpha_test) GLEW_QCOM_alpha_test = !_glewInit_GL_QCOM_alpha_test();
+#endif /* GL_QCOM_alpha_test */
+#ifdef GL_QCOM_driver_control
+ if (glewExperimental || GLEW_QCOM_driver_control) GLEW_QCOM_driver_control = !_glewInit_GL_QCOM_driver_control();
+#endif /* GL_QCOM_driver_control */
+#ifdef GL_QCOM_extended_get
+ if (glewExperimental || GLEW_QCOM_extended_get) GLEW_QCOM_extended_get = !_glewInit_GL_QCOM_extended_get();
+#endif /* GL_QCOM_extended_get */
+#ifdef GL_QCOM_extended_get2
+ if (glewExperimental || GLEW_QCOM_extended_get2) GLEW_QCOM_extended_get2 = !_glewInit_GL_QCOM_extended_get2();
+#endif /* GL_QCOM_extended_get2 */
+#ifdef GL_QCOM_framebuffer_foveated
+ if (glewExperimental || GLEW_QCOM_framebuffer_foveated) GLEW_QCOM_framebuffer_foveated = !_glewInit_GL_QCOM_framebuffer_foveated();
+#endif /* GL_QCOM_framebuffer_foveated */
+#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent
+ if (glewExperimental || GLEW_QCOM_shader_framebuffer_fetch_noncoherent) GLEW_QCOM_shader_framebuffer_fetch_noncoherent = !_glewInit_GL_QCOM_shader_framebuffer_fetch_noncoherent();
+#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */
+#ifdef GL_QCOM_tiled_rendering
+ if (glewExperimental || GLEW_QCOM_tiled_rendering) GLEW_QCOM_tiled_rendering = !_glewInit_GL_QCOM_tiled_rendering();
+#endif /* GL_QCOM_tiled_rendering */
+#ifdef GL_REGAL_ES1_0_compatibility
+ if (glewExperimental || GLEW_REGAL_ES1_0_compatibility) GLEW_REGAL_ES1_0_compatibility = !_glewInit_GL_REGAL_ES1_0_compatibility();
+#endif /* GL_REGAL_ES1_0_compatibility */
+#ifdef GL_REGAL_ES1_1_compatibility
+ if (glewExperimental || GLEW_REGAL_ES1_1_compatibility) GLEW_REGAL_ES1_1_compatibility = !_glewInit_GL_REGAL_ES1_1_compatibility();
+#endif /* GL_REGAL_ES1_1_compatibility */
+#ifdef GL_REGAL_error_string
+ if (glewExperimental || GLEW_REGAL_error_string) GLEW_REGAL_error_string = !_glewInit_GL_REGAL_error_string();
+#endif /* GL_REGAL_error_string */
+#ifdef GL_REGAL_extension_query
+ if (glewExperimental || GLEW_REGAL_extension_query) GLEW_REGAL_extension_query = !_glewInit_GL_REGAL_extension_query();
+#endif /* GL_REGAL_extension_query */
+#ifdef GL_REGAL_log
+ if (glewExperimental || GLEW_REGAL_log) GLEW_REGAL_log = !_glewInit_GL_REGAL_log();
+#endif /* GL_REGAL_log */
+#ifdef GL_REGAL_proc_address
+ if (glewExperimental || GLEW_REGAL_proc_address) GLEW_REGAL_proc_address = !_glewInit_GL_REGAL_proc_address();
+#endif /* GL_REGAL_proc_address */
+#ifdef GL_SGIS_detail_texture
+ if (glewExperimental || GLEW_SGIS_detail_texture) GLEW_SGIS_detail_texture = !_glewInit_GL_SGIS_detail_texture();
+#endif /* GL_SGIS_detail_texture */
+#ifdef GL_SGIS_fog_function
+ if (glewExperimental || GLEW_SGIS_fog_function) GLEW_SGIS_fog_function = !_glewInit_GL_SGIS_fog_function();
+#endif /* GL_SGIS_fog_function */
+#ifdef GL_SGIS_multisample
+ if (glewExperimental || GLEW_SGIS_multisample) GLEW_SGIS_multisample = !_glewInit_GL_SGIS_multisample();
+#endif /* GL_SGIS_multisample */
+#ifdef GL_SGIS_multitexture
+ if (glewExperimental || GLEW_SGIS_multitexture) GLEW_SGIS_multitexture = !_glewInit_GL_SGIS_multitexture();
+#endif /* GL_SGIS_multitexture */
+#ifdef GL_SGIS_shared_multisample
+ if (glewExperimental || GLEW_SGIS_shared_multisample) GLEW_SGIS_shared_multisample = !_glewInit_GL_SGIS_shared_multisample();
+#endif /* GL_SGIS_shared_multisample */
+#ifdef GL_SGIS_sharpen_texture
+ if (glewExperimental || GLEW_SGIS_sharpen_texture) GLEW_SGIS_sharpen_texture = !_glewInit_GL_SGIS_sharpen_texture();
+#endif /* GL_SGIS_sharpen_texture */
+#ifdef GL_SGIS_texture4D
+ if (glewExperimental || GLEW_SGIS_texture4D) GLEW_SGIS_texture4D = !_glewInit_GL_SGIS_texture4D();
+#endif /* GL_SGIS_texture4D */
+#ifdef GL_SGIS_texture_filter4
+ if (glewExperimental || GLEW_SGIS_texture_filter4) GLEW_SGIS_texture_filter4 = !_glewInit_GL_SGIS_texture_filter4();
+#endif /* GL_SGIS_texture_filter4 */
+#ifdef GL_SGIX_async
+ if (glewExperimental || GLEW_SGIX_async) GLEW_SGIX_async = !_glewInit_GL_SGIX_async();
+#endif /* GL_SGIX_async */
+#ifdef GL_SGIX_datapipe
+ if (glewExperimental || GLEW_SGIX_datapipe) GLEW_SGIX_datapipe = !_glewInit_GL_SGIX_datapipe();
+#endif /* GL_SGIX_datapipe */
+#ifdef GL_SGIX_flush_raster
+ if (glewExperimental || GLEW_SGIX_flush_raster) GLEW_SGIX_flush_raster = !_glewInit_GL_SGIX_flush_raster();
+#endif /* GL_SGIX_flush_raster */
+#ifdef GL_SGIX_fog_layers
+ if (glewExperimental || GLEW_SGIX_fog_layers) GLEW_SGIX_fog_layers = !_glewInit_GL_SGIX_fog_layers();
+#endif /* GL_SGIX_fog_layers */
+#ifdef GL_SGIX_fog_texture
+ if (glewExperimental || GLEW_SGIX_fog_texture) GLEW_SGIX_fog_texture = !_glewInit_GL_SGIX_fog_texture();
+#endif /* GL_SGIX_fog_texture */
+#ifdef GL_SGIX_fragment_specular_lighting
+ if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) GLEW_SGIX_fragment_specular_lighting = !_glewInit_GL_SGIX_fragment_specular_lighting();
+#endif /* GL_SGIX_fragment_specular_lighting */
+#ifdef GL_SGIX_framezoom
+ if (glewExperimental || GLEW_SGIX_framezoom) GLEW_SGIX_framezoom = !_glewInit_GL_SGIX_framezoom();
+#endif /* GL_SGIX_framezoom */
+#ifdef GL_SGIX_igloo_interface
+ if (glewExperimental || GLEW_SGIX_igloo_interface) GLEW_SGIX_igloo_interface = !_glewInit_GL_SGIX_igloo_interface();
+#endif /* GL_SGIX_igloo_interface */
+#ifdef GL_SGIX_mpeg1
+ if (glewExperimental || GLEW_SGIX_mpeg1) GLEW_SGIX_mpeg1 = !_glewInit_GL_SGIX_mpeg1();
+#endif /* GL_SGIX_mpeg1 */
+#ifdef GL_SGIX_nonlinear_lighting_pervertex
+ if (glewExperimental || GLEW_SGIX_nonlinear_lighting_pervertex) GLEW_SGIX_nonlinear_lighting_pervertex = !_glewInit_GL_SGIX_nonlinear_lighting_pervertex();
+#endif /* GL_SGIX_nonlinear_lighting_pervertex */
+#ifdef GL_SGIX_pixel_texture
+ if (glewExperimental || GLEW_SGIX_pixel_texture) GLEW_SGIX_pixel_texture = !_glewInit_GL_SGIX_pixel_texture();
+#endif /* GL_SGIX_pixel_texture */
+#ifdef GL_SGIX_polynomial_ffd
+ if (glewExperimental || GLEW_SGIX_polynomial_ffd) GLEW_SGIX_polynomial_ffd = !_glewInit_GL_SGIX_polynomial_ffd();
+#endif /* GL_SGIX_polynomial_ffd */
+#ifdef GL_SGIX_quad_mesh
+ if (glewExperimental || GLEW_SGIX_quad_mesh) GLEW_SGIX_quad_mesh = !_glewInit_GL_SGIX_quad_mesh();
+#endif /* GL_SGIX_quad_mesh */
+#ifdef GL_SGIX_reference_plane
+ if (glewExperimental || GLEW_SGIX_reference_plane) GLEW_SGIX_reference_plane = !_glewInit_GL_SGIX_reference_plane();
+#endif /* GL_SGIX_reference_plane */
+#ifdef GL_SGIX_sprite
+ if (glewExperimental || GLEW_SGIX_sprite) GLEW_SGIX_sprite = !_glewInit_GL_SGIX_sprite();
+#endif /* GL_SGIX_sprite */
+#ifdef GL_SGIX_tag_sample_buffer
+ if (glewExperimental || GLEW_SGIX_tag_sample_buffer) GLEW_SGIX_tag_sample_buffer = !_glewInit_GL_SGIX_tag_sample_buffer();
+#endif /* GL_SGIX_tag_sample_buffer */
+#ifdef GL_SGIX_vector_ops
+ if (glewExperimental || GLEW_SGIX_vector_ops) GLEW_SGIX_vector_ops = !_glewInit_GL_SGIX_vector_ops();
+#endif /* GL_SGIX_vector_ops */
+#ifdef GL_SGIX_vertex_array_object
+ if (glewExperimental || GLEW_SGIX_vertex_array_object) GLEW_SGIX_vertex_array_object = !_glewInit_GL_SGIX_vertex_array_object();
+#endif /* GL_SGIX_vertex_array_object */
+#ifdef GL_SGI_color_table
+ if (glewExperimental || GLEW_SGI_color_table) GLEW_SGI_color_table = !_glewInit_GL_SGI_color_table();
+#endif /* GL_SGI_color_table */
+#ifdef GL_SGI_fft
+ if (glewExperimental || GLEW_SGI_fft) GLEW_SGI_fft = !_glewInit_GL_SGI_fft();
+#endif /* GL_SGI_fft */
+#ifdef GL_SUNX_constant_data
+ if (glewExperimental || GLEW_SUNX_constant_data) GLEW_SUNX_constant_data = !_glewInit_GL_SUNX_constant_data();
+#endif /* GL_SUNX_constant_data */
+#ifdef GL_SUN_global_alpha
+ if (glewExperimental || GLEW_SUN_global_alpha) GLEW_SUN_global_alpha = !_glewInit_GL_SUN_global_alpha();
+#endif /* GL_SUN_global_alpha */
+#ifdef GL_SUN_read_video_pixels
+ if (glewExperimental || GLEW_SUN_read_video_pixels) GLEW_SUN_read_video_pixels = !_glewInit_GL_SUN_read_video_pixels();
+#endif /* GL_SUN_read_video_pixels */
+#ifdef GL_SUN_triangle_list
+ if (glewExperimental || GLEW_SUN_triangle_list) GLEW_SUN_triangle_list = !_glewInit_GL_SUN_triangle_list();
+#endif /* GL_SUN_triangle_list */
+#ifdef GL_SUN_vertex
+ if (glewExperimental || GLEW_SUN_vertex) GLEW_SUN_vertex = !_glewInit_GL_SUN_vertex();
+#endif /* GL_SUN_vertex */
+#ifdef GL_WIN_swap_hint
+ if (glewExperimental || GLEW_WIN_swap_hint) GLEW_WIN_swap_hint = !_glewInit_GL_WIN_swap_hint();
+#endif /* GL_WIN_swap_hint */
+#ifdef GL_NV_fragment_program4
+ GLEW_NV_fragment_program4 = GLEW_NV_gpu_program4;
+#endif /* GL_NV_fragment_program4 */
+#ifdef GL_NV_geometry_program4
+ GLEW_NV_geometry_program4 = GLEW_NV_gpu_program4;
+#endif /* GL_NV_geometry_program4 */
+#ifdef GL_NV_tessellation_program5
+ GLEW_NV_tessellation_program5 = GLEW_NV_gpu_program5;
+#endif /* GL_NV_tessellation_program5 */
+#ifdef GL_NV_vertex_program4
+ GLEW_NV_vertex_program4 = GLEW_NV_gpu_program4;
+#endif /* GL_NV_vertex_program4 */
+
+ return GLEW_OK;
+}
+
+
+#if defined(GLEW_OSMESA)
+
+#elif defined(GLEW_EGL)
+
+PFNEGLCHOOSECONFIGPROC __eglewChooseConfig = NULL;
+PFNEGLCOPYBUFFERSPROC __eglewCopyBuffers = NULL;
+PFNEGLCREATECONTEXTPROC __eglewCreateContext = NULL;
+PFNEGLCREATEPBUFFERSURFACEPROC __eglewCreatePbufferSurface = NULL;
+PFNEGLCREATEPIXMAPSURFACEPROC __eglewCreatePixmapSurface = NULL;
+PFNEGLCREATEWINDOWSURFACEPROC __eglewCreateWindowSurface = NULL;
+PFNEGLDESTROYCONTEXTPROC __eglewDestroyContext = NULL;
+PFNEGLDESTROYSURFACEPROC __eglewDestroySurface = NULL;
+PFNEGLGETCONFIGATTRIBPROC __eglewGetConfigAttrib = NULL;
+PFNEGLGETCONFIGSPROC __eglewGetConfigs = NULL;
+PFNEGLGETCURRENTDISPLAYPROC __eglewGetCurrentDisplay = NULL;
+PFNEGLGETCURRENTSURFACEPROC __eglewGetCurrentSurface = NULL;
+PFNEGLGETDISPLAYPROC __eglewGetDisplay = NULL;
+PFNEGLGETERRORPROC __eglewGetError = NULL;
+PFNEGLINITIALIZEPROC __eglewInitialize = NULL;
+PFNEGLMAKECURRENTPROC __eglewMakeCurrent = NULL;
+PFNEGLQUERYCONTEXTPROC __eglewQueryContext = NULL;
+PFNEGLQUERYSTRINGPROC __eglewQueryString = NULL;
+PFNEGLQUERYSURFACEPROC __eglewQuerySurface = NULL;
+PFNEGLSWAPBUFFERSPROC __eglewSwapBuffers = NULL;
+PFNEGLTERMINATEPROC __eglewTerminate = NULL;
+PFNEGLWAITGLPROC __eglewWaitGL = NULL;
+PFNEGLWAITNATIVEPROC __eglewWaitNative = NULL;
+
+PFNEGLBINDTEXIMAGEPROC __eglewBindTexImage = NULL;
+PFNEGLRELEASETEXIMAGEPROC __eglewReleaseTexImage = NULL;
+PFNEGLSURFACEATTRIBPROC __eglewSurfaceAttrib = NULL;
+PFNEGLSWAPINTERVALPROC __eglewSwapInterval = NULL;
+
+PFNEGLBINDAPIPROC __eglewBindAPI = NULL;
+PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC __eglewCreatePbufferFromClientBuffer = NULL;
+PFNEGLQUERYAPIPROC __eglewQueryAPI = NULL;
+PFNEGLRELEASETHREADPROC __eglewReleaseThread = NULL;
+PFNEGLWAITCLIENTPROC __eglewWaitClient = NULL;
+
+PFNEGLGETCURRENTCONTEXTPROC __eglewGetCurrentContext = NULL;
+
+PFNEGLCLIENTWAITSYNCPROC __eglewClientWaitSync = NULL;
+PFNEGLCREATEIMAGEPROC __eglewCreateImage = NULL;
+PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC __eglewCreatePlatformPixmapSurface = NULL;
+PFNEGLCREATEPLATFORMWINDOWSURFACEPROC __eglewCreatePlatformWindowSurface = NULL;
+PFNEGLCREATESYNCPROC __eglewCreateSync = NULL;
+PFNEGLDESTROYIMAGEPROC __eglewDestroyImage = NULL;
+PFNEGLDESTROYSYNCPROC __eglewDestroySync = NULL;
+PFNEGLGETPLATFORMDISPLAYPROC __eglewGetPlatformDisplay = NULL;
+PFNEGLGETSYNCATTRIBPROC __eglewGetSyncAttrib = NULL;
+PFNEGLWAITSYNCPROC __eglewWaitSync = NULL;
+
+PFNEGLSETBLOBCACHEFUNCSANDROIDPROC __eglewSetBlobCacheFuncsANDROID = NULL;
+
+PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC __eglewCreateNativeClientBufferANDROID = NULL;
+
+PFNEGLDUPNATIVEFENCEFDANDROIDPROC __eglewDupNativeFenceFDANDROID = NULL;
+
+PFNEGLPRESENTATIONTIMEANDROIDPROC __eglewPresentationTimeANDROID = NULL;
+
+PFNEGLQUERYSURFACEPOINTERANGLEPROC __eglewQuerySurfacePointerANGLE = NULL;
+
+PFNEGLQUERYDEVICESEXTPROC __eglewQueryDevicesEXT = NULL;
+
+PFNEGLQUERYDEVICEATTRIBEXTPROC __eglewQueryDeviceAttribEXT = NULL;
+PFNEGLQUERYDEVICESTRINGEXTPROC __eglewQueryDeviceStringEXT = NULL;
+PFNEGLQUERYDISPLAYATTRIBEXTPROC __eglewQueryDisplayAttribEXT = NULL;
+
+PFNEGLQUERYDMABUFFORMATSEXTPROC __eglewQueryDmaBufFormatsEXT = NULL;
+PFNEGLQUERYDMABUFMODIFIERSEXTPROC __eglewQueryDmaBufModifiersEXT = NULL;
+
+PFNEGLGETOUTPUTLAYERSEXTPROC __eglewGetOutputLayersEXT = NULL;
+PFNEGLGETOUTPUTPORTSEXTPROC __eglewGetOutputPortsEXT = NULL;
+PFNEGLOUTPUTLAYERATTRIBEXTPROC __eglewOutputLayerAttribEXT = NULL;
+PFNEGLOUTPUTPORTATTRIBEXTPROC __eglewOutputPortAttribEXT = NULL;
+PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC __eglewQueryOutputLayerAttribEXT = NULL;
+PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC __eglewQueryOutputLayerStringEXT = NULL;
+PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC __eglewQueryOutputPortAttribEXT = NULL;
+PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC __eglewQueryOutputPortStringEXT = NULL;
+
+PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC __eglewCreatePlatformPixmapSurfaceEXT = NULL;
+PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC __eglewCreatePlatformWindowSurfaceEXT = NULL;
+PFNEGLGETPLATFORMDISPLAYEXTPROC __eglewGetPlatformDisplayEXT = NULL;
+
+PFNEGLSTREAMCONSUMEROUTPUTEXTPROC __eglewStreamConsumerOutputEXT = NULL;
+
+PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC __eglewSwapBuffersWithDamageEXT = NULL;
+
+PFNEGLCREATEPIXMAPSURFACEHIPROC __eglewCreatePixmapSurfaceHI = NULL;
+
+PFNEGLCREATESYNC64KHRPROC __eglewCreateSync64KHR = NULL;
+
+PFNEGLDEBUGMESSAGECONTROLKHRPROC __eglewDebugMessageControlKHR = NULL;
+PFNEGLLABELOBJECTKHRPROC __eglewLabelObjectKHR = NULL;
+PFNEGLQUERYDEBUGKHRPROC __eglewQueryDebugKHR = NULL;
+
+PFNEGLCREATEIMAGEKHRPROC __eglewCreateImageKHR = NULL;
+PFNEGLDESTROYIMAGEKHRPROC __eglewDestroyImageKHR = NULL;
+
+PFNEGLLOCKSURFACEKHRPROC __eglewLockSurfaceKHR = NULL;
+PFNEGLUNLOCKSURFACEKHRPROC __eglewUnlockSurfaceKHR = NULL;
+
+PFNEGLQUERYSURFACE64KHRPROC __eglewQuerySurface64KHR = NULL;
+
+PFNEGLSETDAMAGEREGIONKHRPROC __eglewSetDamageRegionKHR = NULL;
+
+PFNEGLCLIENTWAITSYNCKHRPROC __eglewClientWaitSyncKHR = NULL;
+PFNEGLCREATESYNCKHRPROC __eglewCreateSyncKHR = NULL;
+PFNEGLDESTROYSYNCKHRPROC __eglewDestroySyncKHR = NULL;
+PFNEGLGETSYNCATTRIBKHRPROC __eglewGetSyncAttribKHR = NULL;
+PFNEGLSIGNALSYNCKHRPROC __eglewSignalSyncKHR = NULL;
+
+PFNEGLCREATESTREAMKHRPROC __eglewCreateStreamKHR = NULL;
+PFNEGLDESTROYSTREAMKHRPROC __eglewDestroyStreamKHR = NULL;
+PFNEGLQUERYSTREAMKHRPROC __eglewQueryStreamKHR = NULL;
+PFNEGLQUERYSTREAMU64KHRPROC __eglewQueryStreamu64KHR = NULL;
+PFNEGLSTREAMATTRIBKHRPROC __eglewStreamAttribKHR = NULL;
+
+PFNEGLCREATESTREAMATTRIBKHRPROC __eglewCreateStreamAttribKHR = NULL;
+PFNEGLQUERYSTREAMATTRIBKHRPROC __eglewQueryStreamAttribKHR = NULL;
+PFNEGLSETSTREAMATTRIBKHRPROC __eglewSetStreamAttribKHR = NULL;
+PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC __eglewStreamConsumerAcquireAttribKHR = NULL;
+PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC __eglewStreamConsumerReleaseAttribKHR = NULL;
+
+PFNEGLSTREAMCONSUMERACQUIREKHRPROC __eglewStreamConsumerAcquireKHR = NULL;
+PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC __eglewStreamConsumerGLTextureExternalKHR = NULL;
+PFNEGLSTREAMCONSUMERRELEASEKHRPROC __eglewStreamConsumerReleaseKHR = NULL;
+
+PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC __eglewCreateStreamFromFileDescriptorKHR = NULL;
+PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC __eglewGetStreamFileDescriptorKHR = NULL;
+
+PFNEGLQUERYSTREAMTIMEKHRPROC __eglewQueryStreamTimeKHR = NULL;
+
+PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC __eglewCreateStreamProducerSurfaceKHR = NULL;
+
+PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC __eglewSwapBuffersWithDamageKHR = NULL;
+
+PFNEGLWAITSYNCKHRPROC __eglewWaitSyncKHR = NULL;
+
+PFNEGLCREATEDRMIMAGEMESAPROC __eglewCreateDRMImageMESA = NULL;
+PFNEGLEXPORTDRMIMAGEMESAPROC __eglewExportDRMImageMESA = NULL;
+
+PFNEGLEXPORTDMABUFIMAGEMESAPROC __eglewExportDMABUFImageMESA = NULL;
+PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC __eglewExportDMABUFImageQueryMESA = NULL;
+
+PFNEGLSWAPBUFFERSREGIONNOKPROC __eglewSwapBuffersRegionNOK = NULL;
+
+PFNEGLSWAPBUFFERSREGION2NOKPROC __eglewSwapBuffersRegion2NOK = NULL;
+
+PFNEGLQUERYNATIVEDISPLAYNVPROC __eglewQueryNativeDisplayNV = NULL;
+PFNEGLQUERYNATIVEPIXMAPNVPROC __eglewQueryNativePixmapNV = NULL;
+PFNEGLQUERYNATIVEWINDOWNVPROC __eglewQueryNativeWindowNV = NULL;
+
+PFNEGLPOSTSUBBUFFERNVPROC __eglewPostSubBufferNV = NULL;
+
+PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC __eglewStreamConsumerGLTextureExternalAttribsNV = NULL;
+
+PFNEGLQUERYDISPLAYATTRIBNVPROC __eglewQueryDisplayAttribNV = NULL;
+PFNEGLQUERYSTREAMMETADATANVPROC __eglewQueryStreamMetadataNV = NULL;
+PFNEGLSETSTREAMMETADATANVPROC __eglewSetStreamMetadataNV = NULL;
+
+PFNEGLRESETSTREAMNVPROC __eglewResetStreamNV = NULL;
+
+PFNEGLCREATESTREAMSYNCNVPROC __eglewCreateStreamSyncNV = NULL;
+
+PFNEGLCLIENTWAITSYNCNVPROC __eglewClientWaitSyncNV = NULL;
+PFNEGLCREATEFENCESYNCNVPROC __eglewCreateFenceSyncNV = NULL;
+PFNEGLDESTROYSYNCNVPROC __eglewDestroySyncNV = NULL;
+PFNEGLFENCENVPROC __eglewFenceNV = NULL;
+PFNEGLGETSYNCATTRIBNVPROC __eglewGetSyncAttribNV = NULL;
+PFNEGLSIGNALSYNCNVPROC __eglewSignalSyncNV = NULL;
+
+PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC __eglewGetSystemTimeFrequencyNV = NULL;
+PFNEGLGETSYSTEMTIMENVPROC __eglewGetSystemTimeNV = NULL;
+GLboolean __EGLEW_VERSION_1_0 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_1 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_2 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_3 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_4 = GL_FALSE;
+GLboolean __EGLEW_VERSION_1_5 = GL_FALSE;
+GLboolean __EGLEW_ANDROID_blob_cache = GL_FALSE;
+GLboolean __EGLEW_ANDROID_create_native_client_buffer = GL_FALSE;
+GLboolean __EGLEW_ANDROID_framebuffer_target = GL_FALSE;
+GLboolean __EGLEW_ANDROID_front_buffer_auto_refresh = GL_FALSE;
+GLboolean __EGLEW_ANDROID_image_native_buffer = GL_FALSE;
+GLboolean __EGLEW_ANDROID_native_fence_sync = GL_FALSE;
+GLboolean __EGLEW_ANDROID_presentation_time = GL_FALSE;
+GLboolean __EGLEW_ANDROID_recordable = GL_FALSE;
+GLboolean __EGLEW_ANGLE_d3d_share_handle_client_buffer = GL_FALSE;
+GLboolean __EGLEW_ANGLE_device_d3d = GL_FALSE;
+GLboolean __EGLEW_ANGLE_query_surface_pointer = GL_FALSE;
+GLboolean __EGLEW_ANGLE_surface_d3d_texture_2d_share_handle = GL_FALSE;
+GLboolean __EGLEW_ANGLE_window_fixed_size = GL_FALSE;
+GLboolean __EGLEW_ARM_implicit_external_sync = GL_FALSE;
+GLboolean __EGLEW_ARM_pixmap_multisample_discard = GL_FALSE;
+GLboolean __EGLEW_EXT_buffer_age = GL_FALSE;
+GLboolean __EGLEW_EXT_client_extensions = GL_FALSE;
+GLboolean __EGLEW_EXT_create_context_robustness = GL_FALSE;
+GLboolean __EGLEW_EXT_device_base = GL_FALSE;
+GLboolean __EGLEW_EXT_device_drm = GL_FALSE;
+GLboolean __EGLEW_EXT_device_enumeration = GL_FALSE;
+GLboolean __EGLEW_EXT_device_openwf = GL_FALSE;
+GLboolean __EGLEW_EXT_device_query = GL_FALSE;
+GLboolean __EGLEW_EXT_gl_colorspace_bt2020_linear = GL_FALSE;
+GLboolean __EGLEW_EXT_gl_colorspace_bt2020_pq = GL_FALSE;
+GLboolean __EGLEW_EXT_gl_colorspace_scrgb_linear = GL_FALSE;
+GLboolean __EGLEW_EXT_image_dma_buf_import = GL_FALSE;
+GLboolean __EGLEW_EXT_image_dma_buf_import_modifiers = GL_FALSE;
+GLboolean __EGLEW_EXT_multiview_window = GL_FALSE;
+GLboolean __EGLEW_EXT_output_base = GL_FALSE;
+GLboolean __EGLEW_EXT_output_drm = GL_FALSE;
+GLboolean __EGLEW_EXT_output_openwf = GL_FALSE;
+GLboolean __EGLEW_EXT_pixel_format_float = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_base = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_device = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_wayland = GL_FALSE;
+GLboolean __EGLEW_EXT_platform_x11 = GL_FALSE;
+GLboolean __EGLEW_EXT_protected_content = GL_FALSE;
+GLboolean __EGLEW_EXT_protected_surface = GL_FALSE;
+GLboolean __EGLEW_EXT_stream_consumer_egloutput = GL_FALSE;
+GLboolean __EGLEW_EXT_surface_SMPTE2086_metadata = GL_FALSE;
+GLboolean __EGLEW_EXT_swap_buffers_with_damage = GL_FALSE;
+GLboolean __EGLEW_EXT_yuv_surface = GL_FALSE;
+GLboolean __EGLEW_HI_clientpixmap = GL_FALSE;
+GLboolean __EGLEW_HI_colorformats = GL_FALSE;
+GLboolean __EGLEW_IMG_context_priority = GL_FALSE;
+GLboolean __EGLEW_IMG_image_plane_attribs = GL_FALSE;
+GLboolean __EGLEW_KHR_cl_event = GL_FALSE;
+GLboolean __EGLEW_KHR_cl_event2 = GL_FALSE;
+GLboolean __EGLEW_KHR_client_get_all_proc_addresses = GL_FALSE;
+GLboolean __EGLEW_KHR_config_attribs = GL_FALSE;
+GLboolean __EGLEW_KHR_context_flush_control = GL_FALSE;
+GLboolean __EGLEW_KHR_create_context = GL_FALSE;
+GLboolean __EGLEW_KHR_create_context_no_error = GL_FALSE;
+GLboolean __EGLEW_KHR_debug = GL_FALSE;
+GLboolean __EGLEW_KHR_fence_sync = GL_FALSE;
+GLboolean __EGLEW_KHR_get_all_proc_addresses = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_colorspace = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_renderbuffer_image = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_texture_2D_image = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_texture_3D_image = GL_FALSE;
+GLboolean __EGLEW_KHR_gl_texture_cubemap_image = GL_FALSE;
+GLboolean __EGLEW_KHR_image = GL_FALSE;
+GLboolean __EGLEW_KHR_image_base = GL_FALSE;
+GLboolean __EGLEW_KHR_image_pixmap = GL_FALSE;
+GLboolean __EGLEW_KHR_lock_surface = GL_FALSE;
+GLboolean __EGLEW_KHR_lock_surface2 = GL_FALSE;
+GLboolean __EGLEW_KHR_lock_surface3 = GL_FALSE;
+GLboolean __EGLEW_KHR_mutable_render_buffer = GL_FALSE;
+GLboolean __EGLEW_KHR_no_config_context = GL_FALSE;
+GLboolean __EGLEW_KHR_partial_update = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_android = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_gbm = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_wayland = GL_FALSE;
+GLboolean __EGLEW_KHR_platform_x11 = GL_FALSE;
+GLboolean __EGLEW_KHR_reusable_sync = GL_FALSE;
+GLboolean __EGLEW_KHR_stream = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_attrib = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_consumer_gltexture = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_cross_process_fd = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_fifo = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_producer_aldatalocator = GL_FALSE;
+GLboolean __EGLEW_KHR_stream_producer_eglsurface = GL_FALSE;
+GLboolean __EGLEW_KHR_surfaceless_context = GL_FALSE;
+GLboolean __EGLEW_KHR_swap_buffers_with_damage = GL_FALSE;
+GLboolean __EGLEW_KHR_vg_parent_image = GL_FALSE;
+GLboolean __EGLEW_KHR_wait_sync = GL_FALSE;
+GLboolean __EGLEW_MESA_drm_image = GL_FALSE;
+GLboolean __EGLEW_MESA_image_dma_buf_export = GL_FALSE;
+GLboolean __EGLEW_MESA_platform_gbm = GL_FALSE;
+GLboolean __EGLEW_MESA_platform_surfaceless = GL_FALSE;
+GLboolean __EGLEW_NOK_swap_region = GL_FALSE;
+GLboolean __EGLEW_NOK_swap_region2 = GL_FALSE;
+GLboolean __EGLEW_NOK_texture_from_pixmap = GL_FALSE;
+GLboolean __EGLEW_NV_3dvision_surface = GL_FALSE;
+GLboolean __EGLEW_NV_coverage_sample = GL_FALSE;
+GLboolean __EGLEW_NV_coverage_sample_resolve = GL_FALSE;
+GLboolean __EGLEW_NV_cuda_event = GL_FALSE;
+GLboolean __EGLEW_NV_depth_nonlinear = GL_FALSE;
+GLboolean __EGLEW_NV_device_cuda = GL_FALSE;
+GLboolean __EGLEW_NV_native_query = GL_FALSE;
+GLboolean __EGLEW_NV_post_convert_rounding = GL_FALSE;
+GLboolean __EGLEW_NV_post_sub_buffer = GL_FALSE;
+GLboolean __EGLEW_NV_robustness_video_memory_purge = GL_FALSE;
+GLboolean __EGLEW_NV_stream_consumer_gltexture_yuv = GL_FALSE;
+GLboolean __EGLEW_NV_stream_cross_display = GL_FALSE;
+GLboolean __EGLEW_NV_stream_cross_object = GL_FALSE;
+GLboolean __EGLEW_NV_stream_cross_partition = GL_FALSE;
+GLboolean __EGLEW_NV_stream_cross_process = GL_FALSE;
+GLboolean __EGLEW_NV_stream_cross_system = GL_FALSE;
+GLboolean __EGLEW_NV_stream_fifo_next = GL_FALSE;
+GLboolean __EGLEW_NV_stream_fifo_synchronous = GL_FALSE;
+GLboolean __EGLEW_NV_stream_frame_limits = GL_FALSE;
+GLboolean __EGLEW_NV_stream_metadata = GL_FALSE;
+GLboolean __EGLEW_NV_stream_remote = GL_FALSE;
+GLboolean __EGLEW_NV_stream_reset = GL_FALSE;
+GLboolean __EGLEW_NV_stream_socket = GL_FALSE;
+GLboolean __EGLEW_NV_stream_socket_inet = GL_FALSE;
+GLboolean __EGLEW_NV_stream_socket_unix = GL_FALSE;
+GLboolean __EGLEW_NV_stream_sync = GL_FALSE;
+GLboolean __EGLEW_NV_sync = GL_FALSE;
+GLboolean __EGLEW_NV_system_time = GL_FALSE;
+GLboolean __EGLEW_TIZEN_image_native_buffer = GL_FALSE;
+GLboolean __EGLEW_TIZEN_image_native_surface = GL_FALSE;
+#ifdef EGL_VERSION_1_0
+
+static GLboolean _glewInit_EGL_VERSION_1_0 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglChooseConfig = (PFNEGLCHOOSECONFIGPROC)glewGetProcAddress((const GLubyte*)"eglChooseConfig")) == NULL) || r;
+ r = ((eglCopyBuffers = (PFNEGLCOPYBUFFERSPROC)glewGetProcAddress((const GLubyte*)"eglCopyBuffers")) == NULL) || r;
+ r = ((eglCreateContext = (PFNEGLCREATECONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglCreateContext")) == NULL) || r;
+ r = ((eglCreatePbufferSurface = (PFNEGLCREATEPBUFFERSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePbufferSurface")) == NULL) || r;
+ r = ((eglCreatePixmapSurface = (PFNEGLCREATEPIXMAPSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePixmapSurface")) == NULL) || r;
+ r = ((eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreateWindowSurface")) == NULL) || r;
+ r = ((eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglDestroyContext")) == NULL) || r;
+ r = ((eglDestroySurface = (PFNEGLDESTROYSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglDestroySurface")) == NULL) || r;
+ r = ((eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"eglGetConfigAttrib")) == NULL) || r;
+ r = ((eglGetConfigs = (PFNEGLGETCONFIGSPROC)glewGetProcAddress((const GLubyte*)"eglGetConfigs")) == NULL) || r;
+ r = ((eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"eglGetCurrentDisplay")) == NULL) || r;
+ r = ((eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglGetCurrentSurface")) == NULL) || r;
+ r = ((eglGetDisplay = (PFNEGLGETDISPLAYPROC)glewGetProcAddress((const GLubyte*)"eglGetDisplay")) == NULL) || r;
+ r = ((eglGetError = (PFNEGLGETERRORPROC)glewGetProcAddress((const GLubyte*)"eglGetError")) == NULL) || r;
+ r = ((eglInitialize = (PFNEGLINITIALIZEPROC)glewGetProcAddress((const GLubyte*)"eglInitialize")) == NULL) || r;
+ r = ((eglMakeCurrent = (PFNEGLMAKECURRENTPROC)glewGetProcAddress((const GLubyte*)"eglMakeCurrent")) == NULL) || r;
+ r = ((eglQueryContext = (PFNEGLQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryContext")) == NULL) || r;
+ r = ((eglQueryString = (PFNEGLQUERYSTRINGPROC)glewGetProcAddress((const GLubyte*)"eglQueryString")) == NULL) || r;
+ r = ((eglQuerySurface = (PFNEGLQUERYSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglQuerySurface")) == NULL) || r;
+ r = ((eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffers")) == NULL) || r;
+ r = ((eglTerminate = (PFNEGLTERMINATEPROC)glewGetProcAddress((const GLubyte*)"eglTerminate")) == NULL) || r;
+ r = ((eglWaitGL = (PFNEGLWAITGLPROC)glewGetProcAddress((const GLubyte*)"eglWaitGL")) == NULL) || r;
+ r = ((eglWaitNative = (PFNEGLWAITNATIVEPROC)glewGetProcAddress((const GLubyte*)"eglWaitNative")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_0 */
+
+#ifdef EGL_VERSION_1_1
+
+static GLboolean _glewInit_EGL_VERSION_1_1 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglBindTexImage = (PFNEGLBINDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglBindTexImage")) == NULL) || r;
+ r = ((eglReleaseTexImage = (PFNEGLRELEASETEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglReleaseTexImage")) == NULL) || r;
+ r = ((eglSurfaceAttrib = (PFNEGLSURFACEATTRIBPROC)glewGetProcAddress((const GLubyte*)"eglSurfaceAttrib")) == NULL) || r;
+ r = ((eglSwapInterval = (PFNEGLSWAPINTERVALPROC)glewGetProcAddress((const GLubyte*)"eglSwapInterval")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_1 */
+
+#ifdef EGL_VERSION_1_2
+
+static GLboolean _glewInit_EGL_VERSION_1_2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglBindAPI = (PFNEGLBINDAPIPROC)glewGetProcAddress((const GLubyte*)"eglBindAPI")) == NULL) || r;
+ r = ((eglCreatePbufferFromClientBuffer = (PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)glewGetProcAddress((const GLubyte*)"eglCreatePbufferFromClientBuffer")) == NULL) || r;
+ r = ((eglQueryAPI = (PFNEGLQUERYAPIPROC)glewGetProcAddress((const GLubyte*)"eglQueryAPI")) == NULL) || r;
+ r = ((eglReleaseThread = (PFNEGLRELEASETHREADPROC)glewGetProcAddress((const GLubyte*)"eglReleaseThread")) == NULL) || r;
+ r = ((eglWaitClient = (PFNEGLWAITCLIENTPROC)glewGetProcAddress((const GLubyte*)"eglWaitClient")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_2 */
+
+#ifdef EGL_VERSION_1_4
+
+static GLboolean _glewInit_EGL_VERSION_1_4 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetCurrentContext")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_4 */
+
+#ifdef EGL_VERSION_1_5
+
+static GLboolean _glewInit_EGL_VERSION_1_5 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglClientWaitSync = (PFNEGLCLIENTWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"eglClientWaitSync")) == NULL) || r;
+ r = ((eglCreateImage = (PFNEGLCREATEIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglCreateImage")) == NULL) || r;
+ r = ((eglCreatePlatformPixmapSurface = (PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformPixmapSurface")) == NULL) || r;
+ r = ((eglCreatePlatformWindowSurface = (PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformWindowSurface")) == NULL) || r;
+ r = ((eglCreateSync = (PFNEGLCREATESYNCPROC)glewGetProcAddress((const GLubyte*)"eglCreateSync")) == NULL) || r;
+ r = ((eglDestroyImage = (PFNEGLDESTROYIMAGEPROC)glewGetProcAddress((const GLubyte*)"eglDestroyImage")) == NULL) || r;
+ r = ((eglDestroySync = (PFNEGLDESTROYSYNCPROC)glewGetProcAddress((const GLubyte*)"eglDestroySync")) == NULL) || r;
+ r = ((eglGetPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYPROC)glewGetProcAddress((const GLubyte*)"eglGetPlatformDisplay")) == NULL) || r;
+ r = ((eglGetSyncAttrib = (PFNEGLGETSYNCATTRIBPROC)glewGetProcAddress((const GLubyte*)"eglGetSyncAttrib")) == NULL) || r;
+ r = ((eglWaitSync = (PFNEGLWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"eglWaitSync")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_VERSION_1_5 */
+
+#ifdef EGL_ANDROID_blob_cache
+
+static GLboolean _glewInit_EGL_ANDROID_blob_cache ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSetBlobCacheFuncsANDROID = (PFNEGLSETBLOBCACHEFUNCSANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglSetBlobCacheFuncsANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_blob_cache */
+
+#ifdef EGL_ANDROID_create_native_client_buffer
+
+static GLboolean _glewInit_EGL_ANDROID_create_native_client_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateNativeClientBufferANDROID = (PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglCreateNativeClientBufferANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_create_native_client_buffer */
+
+#ifdef EGL_ANDROID_native_fence_sync
+
+static GLboolean _glewInit_EGL_ANDROID_native_fence_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglDupNativeFenceFDANDROID = (PFNEGLDUPNATIVEFENCEFDANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglDupNativeFenceFDANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_native_fence_sync */
+
+#ifdef EGL_ANDROID_presentation_time
+
+static GLboolean _glewInit_EGL_ANDROID_presentation_time ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglPresentationTimeANDROID = (PFNEGLPRESENTATIONTIMEANDROIDPROC)glewGetProcAddress((const GLubyte*)"eglPresentationTimeANDROID")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANDROID_presentation_time */
+
+#ifdef EGL_ANGLE_query_surface_pointer
+
+static GLboolean _glewInit_EGL_ANGLE_query_surface_pointer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQuerySurfacePointerANGLE = (PFNEGLQUERYSURFACEPOINTERANGLEPROC)glewGetProcAddress((const GLubyte*)"eglQuerySurfacePointerANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+#ifdef EGL_EXT_device_enumeration
+
+static GLboolean _glewInit_EGL_EXT_device_enumeration ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDevicesEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_device_enumeration */
+
+#ifdef EGL_EXT_device_query
+
+static GLboolean _glewInit_EGL_EXT_device_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDeviceAttribEXT")) == NULL) || r;
+ r = ((eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDeviceStringEXT")) == NULL) || r;
+ r = ((eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDisplayAttribEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_device_query */
+
+#ifdef EGL_EXT_image_dma_buf_import_modifiers
+
+static GLboolean _glewInit_EGL_EXT_image_dma_buf_import_modifiers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryDmaBufFormatsEXT = (PFNEGLQUERYDMABUFFORMATSEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDmaBufFormatsEXT")) == NULL) || r;
+ r = ((eglQueryDmaBufModifiersEXT = (PFNEGLQUERYDMABUFMODIFIERSEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryDmaBufModifiersEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_image_dma_buf_import_modifiers */
+
+#ifdef EGL_EXT_output_base
+
+static GLboolean _glewInit_EGL_EXT_output_base ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglGetOutputLayersEXT = (PFNEGLGETOUTPUTLAYERSEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetOutputLayersEXT")) == NULL) || r;
+ r = ((eglGetOutputPortsEXT = (PFNEGLGETOUTPUTPORTSEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetOutputPortsEXT")) == NULL) || r;
+ r = ((eglOutputLayerAttribEXT = (PFNEGLOUTPUTLAYERATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglOutputLayerAttribEXT")) == NULL) || r;
+ r = ((eglOutputPortAttribEXT = (PFNEGLOUTPUTPORTATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglOutputPortAttribEXT")) == NULL) || r;
+ r = ((eglQueryOutputLayerAttribEXT = (PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputLayerAttribEXT")) == NULL) || r;
+ r = ((eglQueryOutputLayerStringEXT = (PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputLayerStringEXT")) == NULL) || r;
+ r = ((eglQueryOutputPortAttribEXT = (PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputPortAttribEXT")) == NULL) || r;
+ r = ((eglQueryOutputPortStringEXT = (PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"eglQueryOutputPortStringEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_output_base */
+
+#ifdef EGL_EXT_platform_base
+
+static GLboolean _glewInit_EGL_EXT_platform_base ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformPixmapSurfaceEXT")) == NULL) || r;
+ r = ((eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)glewGetProcAddress((const GLubyte*)"eglCreatePlatformWindowSurfaceEXT")) == NULL) || r;
+ r = ((eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)glewGetProcAddress((const GLubyte*)"eglGetPlatformDisplayEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_platform_base */
+
+#ifdef EGL_EXT_stream_consumer_egloutput
+
+static GLboolean _glewInit_EGL_EXT_stream_consumer_egloutput ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglStreamConsumerOutputEXT = (PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerOutputEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_stream_consumer_egloutput */
+
+#ifdef EGL_EXT_swap_buffers_with_damage
+
+static GLboolean _glewInit_EGL_EXT_swap_buffers_with_damage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersWithDamageEXT = (PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersWithDamageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+#ifdef EGL_HI_clientpixmap
+
+static GLboolean _glewInit_EGL_HI_clientpixmap ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreatePixmapSurfaceHI = (PFNEGLCREATEPIXMAPSURFACEHIPROC)glewGetProcAddress((const GLubyte*)"eglCreatePixmapSurfaceHI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_HI_clientpixmap */
+
+#ifdef EGL_KHR_cl_event2
+
+static GLboolean _glewInit_EGL_KHR_cl_event2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateSync64KHR = (PFNEGLCREATESYNC64KHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateSync64KHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_cl_event2 */
+
+#ifdef EGL_KHR_debug
+
+static GLboolean _glewInit_EGL_KHR_debug ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglDebugMessageControlKHR = (PFNEGLDEBUGMESSAGECONTROLKHRPROC)glewGetProcAddress((const GLubyte*)"eglDebugMessageControlKHR")) == NULL) || r;
+ r = ((eglLabelObjectKHR = (PFNEGLLABELOBJECTKHRPROC)glewGetProcAddress((const GLubyte*)"eglLabelObjectKHR")) == NULL) || r;
+ r = ((eglQueryDebugKHR = (PFNEGLQUERYDEBUGKHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryDebugKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_debug */
+
+#ifdef EGL_KHR_image
+
+static GLboolean _glewInit_EGL_KHR_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateImageKHR")) == NULL) || r;
+ r = ((eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)glewGetProcAddress((const GLubyte*)"eglDestroyImageKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_image */
+
+#ifdef EGL_KHR_lock_surface
+
+static GLboolean _glewInit_EGL_KHR_lock_surface ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglLockSurfaceKHR = (PFNEGLLOCKSURFACEKHRPROC)glewGetProcAddress((const GLubyte*)"eglLockSurfaceKHR")) == NULL) || r;
+ r = ((eglUnlockSurfaceKHR = (PFNEGLUNLOCKSURFACEKHRPROC)glewGetProcAddress((const GLubyte*)"eglUnlockSurfaceKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_lock_surface */
+
+#ifdef EGL_KHR_lock_surface3
+
+static GLboolean _glewInit_EGL_KHR_lock_surface3 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQuerySurface64KHR = (PFNEGLQUERYSURFACE64KHRPROC)glewGetProcAddress((const GLubyte*)"eglQuerySurface64KHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_lock_surface3 */
+
+#ifdef EGL_KHR_partial_update
+
+static GLboolean _glewInit_EGL_KHR_partial_update ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSetDamageRegionKHR = (PFNEGLSETDAMAGEREGIONKHRPROC)glewGetProcAddress((const GLubyte*)"eglSetDamageRegionKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_partial_update */
+
+#ifdef EGL_KHR_reusable_sync
+
+static GLboolean _glewInit_EGL_KHR_reusable_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglClientWaitSyncKHR")) == NULL) || r;
+ r = ((eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateSyncKHR")) == NULL) || r;
+ r = ((eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglDestroySyncKHR")) == NULL) || r;
+ r = ((eglGetSyncAttribKHR = (PFNEGLGETSYNCATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglGetSyncAttribKHR")) == NULL) || r;
+ r = ((eglSignalSyncKHR = (PFNEGLSIGNALSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglSignalSyncKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_reusable_sync */
+
+#ifdef EGL_KHR_stream
+
+static GLboolean _glewInit_EGL_KHR_stream ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamKHR = (PFNEGLCREATESTREAMKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamKHR")) == NULL) || r;
+ r = ((eglDestroyStreamKHR = (PFNEGLDESTROYSTREAMKHRPROC)glewGetProcAddress((const GLubyte*)"eglDestroyStreamKHR")) == NULL) || r;
+ r = ((eglQueryStreamKHR = (PFNEGLQUERYSTREAMKHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamKHR")) == NULL) || r;
+ r = ((eglQueryStreamu64KHR = (PFNEGLQUERYSTREAMU64KHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamu64KHR")) == NULL) || r;
+ r = ((eglStreamAttribKHR = (PFNEGLSTREAMATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamAttribKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream */
+
+#ifdef EGL_KHR_stream_attrib
+
+static GLboolean _glewInit_EGL_KHR_stream_attrib ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamAttribKHR = (PFNEGLCREATESTREAMATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamAttribKHR")) == NULL) || r;
+ r = ((eglQueryStreamAttribKHR = (PFNEGLQUERYSTREAMATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamAttribKHR")) == NULL) || r;
+ r = ((eglSetStreamAttribKHR = (PFNEGLSETSTREAMATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglSetStreamAttribKHR")) == NULL) || r;
+ r = ((eglStreamConsumerAcquireAttribKHR = (PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerAcquireAttribKHR")) == NULL) || r;
+ r = ((eglStreamConsumerReleaseAttribKHR = (PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerReleaseAttribKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_attrib */
+
+#ifdef EGL_KHR_stream_consumer_gltexture
+
+static GLboolean _glewInit_EGL_KHR_stream_consumer_gltexture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglStreamConsumerAcquireKHR = (PFNEGLSTREAMCONSUMERACQUIREKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerAcquireKHR")) == NULL) || r;
+ r = ((eglStreamConsumerGLTextureExternalKHR = (PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerGLTextureExternalKHR")) == NULL) || r;
+ r = ((eglStreamConsumerReleaseKHR = (PFNEGLSTREAMCONSUMERRELEASEKHRPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerReleaseKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+#ifdef EGL_KHR_stream_cross_process_fd
+
+static GLboolean _glewInit_EGL_KHR_stream_cross_process_fd ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamFromFileDescriptorKHR = (PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamFromFileDescriptorKHR")) == NULL) || r;
+ r = ((eglGetStreamFileDescriptorKHR = (PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)glewGetProcAddress((const GLubyte*)"eglGetStreamFileDescriptorKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+#ifdef EGL_KHR_stream_fifo
+
+static GLboolean _glewInit_EGL_KHR_stream_fifo ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryStreamTimeKHR = (PFNEGLQUERYSTREAMTIMEKHRPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamTimeKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_fifo */
+
+#ifdef EGL_KHR_stream_producer_eglsurface
+
+static GLboolean _glewInit_EGL_KHR_stream_producer_eglsurface ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamProducerSurfaceKHR = (PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamProducerSurfaceKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+#ifdef EGL_KHR_swap_buffers_with_damage
+
+static GLboolean _glewInit_EGL_KHR_swap_buffers_with_damage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersWithDamageKHR = (PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersWithDamageKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
+#ifdef EGL_KHR_wait_sync
+
+static GLboolean _glewInit_EGL_KHR_wait_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglWaitSyncKHR = (PFNEGLWAITSYNCKHRPROC)glewGetProcAddress((const GLubyte*)"eglWaitSyncKHR")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_KHR_wait_sync */
+
+#ifdef EGL_MESA_drm_image
+
+static GLboolean _glewInit_EGL_MESA_drm_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateDRMImageMESA = (PFNEGLCREATEDRMIMAGEMESAPROC)glewGetProcAddress((const GLubyte*)"eglCreateDRMImageMESA")) == NULL) || r;
+ r = ((eglExportDRMImageMESA = (PFNEGLEXPORTDRMIMAGEMESAPROC)glewGetProcAddress((const GLubyte*)"eglExportDRMImageMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_MESA_drm_image */
+
+#ifdef EGL_MESA_image_dma_buf_export
+
+static GLboolean _glewInit_EGL_MESA_image_dma_buf_export ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglExportDMABUFImageMESA = (PFNEGLEXPORTDMABUFIMAGEMESAPROC)glewGetProcAddress((const GLubyte*)"eglExportDMABUFImageMESA")) == NULL) || r;
+ r = ((eglExportDMABUFImageQueryMESA = (PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC)glewGetProcAddress((const GLubyte*)"eglExportDMABUFImageQueryMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_MESA_image_dma_buf_export */
+
+#ifdef EGL_NOK_swap_region
+
+static GLboolean _glewInit_EGL_NOK_swap_region ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersRegionNOK = (PFNEGLSWAPBUFFERSREGIONNOKPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersRegionNOK")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NOK_swap_region */
+
+#ifdef EGL_NOK_swap_region2
+
+static GLboolean _glewInit_EGL_NOK_swap_region2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglSwapBuffersRegion2NOK = (PFNEGLSWAPBUFFERSREGION2NOKPROC)glewGetProcAddress((const GLubyte*)"eglSwapBuffersRegion2NOK")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NOK_swap_region2 */
+
+#ifdef EGL_NV_native_query
+
+static GLboolean _glewInit_EGL_NV_native_query ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryNativeDisplayNV = (PFNEGLQUERYNATIVEDISPLAYNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryNativeDisplayNV")) == NULL) || r;
+ r = ((eglQueryNativePixmapNV = (PFNEGLQUERYNATIVEPIXMAPNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryNativePixmapNV")) == NULL) || r;
+ r = ((eglQueryNativeWindowNV = (PFNEGLQUERYNATIVEWINDOWNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryNativeWindowNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_native_query */
+
+#ifdef EGL_NV_post_sub_buffer
+
+static GLboolean _glewInit_EGL_NV_post_sub_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"eglPostSubBufferNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_post_sub_buffer */
+
+#ifdef EGL_NV_stream_consumer_gltexture_yuv
+
+static GLboolean _glewInit_EGL_NV_stream_consumer_gltexture_yuv ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglStreamConsumerGLTextureExternalAttribsNV = (PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"eglStreamConsumerGLTextureExternalAttribsNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+
+#ifdef EGL_NV_stream_metadata
+
+static GLboolean _glewInit_EGL_NV_stream_metadata ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglQueryDisplayAttribNV = (PFNEGLQUERYDISPLAYATTRIBNVPROC)glewGetProcAddress((const GLubyte*)"eglQueryDisplayAttribNV")) == NULL) || r;
+ r = ((eglQueryStreamMetadataNV = (PFNEGLQUERYSTREAMMETADATANVPROC)glewGetProcAddress((const GLubyte*)"eglQueryStreamMetadataNV")) == NULL) || r;
+ r = ((eglSetStreamMetadataNV = (PFNEGLSETSTREAMMETADATANVPROC)glewGetProcAddress((const GLubyte*)"eglSetStreamMetadataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_stream_metadata */
+
+#ifdef EGL_NV_stream_reset
+
+static GLboolean _glewInit_EGL_NV_stream_reset ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglResetStreamNV = (PFNEGLRESETSTREAMNVPROC)glewGetProcAddress((const GLubyte*)"eglResetStreamNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_stream_reset */
+
+#ifdef EGL_NV_stream_sync
+
+static GLboolean _glewInit_EGL_NV_stream_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglCreateStreamSyncNV = (PFNEGLCREATESTREAMSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglCreateStreamSyncNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_stream_sync */
+
+#ifdef EGL_NV_sync
+
+static GLboolean _glewInit_EGL_NV_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglClientWaitSyncNV = (PFNEGLCLIENTWAITSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglClientWaitSyncNV")) == NULL) || r;
+ r = ((eglCreateFenceSyncNV = (PFNEGLCREATEFENCESYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglCreateFenceSyncNV")) == NULL) || r;
+ r = ((eglDestroySyncNV = (PFNEGLDESTROYSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglDestroySyncNV")) == NULL) || r;
+ r = ((eglFenceNV = (PFNEGLFENCENVPROC)glewGetProcAddress((const GLubyte*)"eglFenceNV")) == NULL) || r;
+ r = ((eglGetSyncAttribNV = (PFNEGLGETSYNCATTRIBNVPROC)glewGetProcAddress((const GLubyte*)"eglGetSyncAttribNV")) == NULL) || r;
+ r = ((eglSignalSyncNV = (PFNEGLSIGNALSYNCNVPROC)glewGetProcAddress((const GLubyte*)"eglSignalSyncNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_sync */
+
+#ifdef EGL_NV_system_time
+
+static GLboolean _glewInit_EGL_NV_system_time ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)glewGetProcAddress((const GLubyte*)"eglGetSystemTimeFrequencyNV")) == NULL) || r;
+ r = ((eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)glewGetProcAddress((const GLubyte*)"eglGetSystemTimeNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* EGL_NV_system_time */
+
+ /* ------------------------------------------------------------------------ */
+
+GLboolean eglewGetExtension (const char* name)
+{
+ const GLubyte* start;
+ const GLubyte* end;
+
+ start = (const GLubyte*) eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
+ if (0 == start) return GL_FALSE;
+ end = start + _glewStrLen(start);
+ return _glewSearchExtension(name, start, end);
+}
+
+GLenum eglewInit (EGLDisplay display)
+{
+ EGLint major, minor;
+ const GLubyte* extStart;
+ const GLubyte* extEnd;
+ PFNEGLINITIALIZEPROC initialize = NULL;
+ PFNEGLQUERYSTRINGPROC queryString = NULL;
+
+ /* Load necessary entry points */
+ initialize = (PFNEGLINITIALIZEPROC) glewGetProcAddress("eglInitialize");
+ queryString = (PFNEGLQUERYSTRINGPROC) glewGetProcAddress("eglQueryString");
+ if (!initialize || !queryString)
+ return 1;
+
+ /* query EGK version */
+ if (initialize(display, &major, &minor) != EGL_TRUE)
+ return 1;
+
+ EGLEW_VERSION_1_5 = ( major > 1 ) || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_4 = EGLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_3 = EGLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_2 = EGLEW_VERSION_1_3 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_1 = EGLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ EGLEW_VERSION_1_0 = EGLEW_VERSION_1_1 == GL_TRUE || ( major == 1 && minor >= 0 ) ? GL_TRUE : GL_FALSE;
+
+ /* query EGL extension string */
+ extStart = (const GLubyte*) queryString(display, EGL_EXTENSIONS);
+ if (extStart == 0)
+ extStart = (const GLubyte *)"";
+ extEnd = extStart + _glewStrLen(extStart);
+
+ /* initialize extensions */
+#ifdef EGL_VERSION_1_0
+ if (glewExperimental || EGLEW_VERSION_1_0) EGLEW_VERSION_1_0 = !_glewInit_EGL_VERSION_1_0();
+#endif /* EGL_VERSION_1_0 */
+#ifdef EGL_VERSION_1_1
+ if (glewExperimental || EGLEW_VERSION_1_1) EGLEW_VERSION_1_1 = !_glewInit_EGL_VERSION_1_1();
+#endif /* EGL_VERSION_1_1 */
+#ifdef EGL_VERSION_1_2
+ if (glewExperimental || EGLEW_VERSION_1_2) EGLEW_VERSION_1_2 = !_glewInit_EGL_VERSION_1_2();
+#endif /* EGL_VERSION_1_2 */
+#ifdef EGL_VERSION_1_4
+ if (glewExperimental || EGLEW_VERSION_1_4) EGLEW_VERSION_1_4 = !_glewInit_EGL_VERSION_1_4();
+#endif /* EGL_VERSION_1_4 */
+#ifdef EGL_VERSION_1_5
+ if (glewExperimental || EGLEW_VERSION_1_5) EGLEW_VERSION_1_5 = !_glewInit_EGL_VERSION_1_5();
+#endif /* EGL_VERSION_1_5 */
+#ifdef EGL_ANDROID_blob_cache
+ EGLEW_ANDROID_blob_cache = _glewSearchExtension("EGL_ANDROID_blob_cache", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_blob_cache) EGLEW_ANDROID_blob_cache = !_glewInit_EGL_ANDROID_blob_cache();
+#endif /* EGL_ANDROID_blob_cache */
+#ifdef EGL_ANDROID_create_native_client_buffer
+ EGLEW_ANDROID_create_native_client_buffer = _glewSearchExtension("EGL_ANDROID_create_native_client_buffer", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_create_native_client_buffer) EGLEW_ANDROID_create_native_client_buffer = !_glewInit_EGL_ANDROID_create_native_client_buffer();
+#endif /* EGL_ANDROID_create_native_client_buffer */
+#ifdef EGL_ANDROID_framebuffer_target
+ EGLEW_ANDROID_framebuffer_target = _glewSearchExtension("EGL_ANDROID_framebuffer_target", extStart, extEnd);
+#endif /* EGL_ANDROID_framebuffer_target */
+#ifdef EGL_ANDROID_front_buffer_auto_refresh
+ EGLEW_ANDROID_front_buffer_auto_refresh = _glewSearchExtension("EGL_ANDROID_front_buffer_auto_refresh", extStart, extEnd);
+#endif /* EGL_ANDROID_front_buffer_auto_refresh */
+#ifdef EGL_ANDROID_image_native_buffer
+ EGLEW_ANDROID_image_native_buffer = _glewSearchExtension("EGL_ANDROID_image_native_buffer", extStart, extEnd);
+#endif /* EGL_ANDROID_image_native_buffer */
+#ifdef EGL_ANDROID_native_fence_sync
+ EGLEW_ANDROID_native_fence_sync = _glewSearchExtension("EGL_ANDROID_native_fence_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_native_fence_sync) EGLEW_ANDROID_native_fence_sync = !_glewInit_EGL_ANDROID_native_fence_sync();
+#endif /* EGL_ANDROID_native_fence_sync */
+#ifdef EGL_ANDROID_presentation_time
+ EGLEW_ANDROID_presentation_time = _glewSearchExtension("EGL_ANDROID_presentation_time", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANDROID_presentation_time) EGLEW_ANDROID_presentation_time = !_glewInit_EGL_ANDROID_presentation_time();
+#endif /* EGL_ANDROID_presentation_time */
+#ifdef EGL_ANDROID_recordable
+ EGLEW_ANDROID_recordable = _glewSearchExtension("EGL_ANDROID_recordable", extStart, extEnd);
+#endif /* EGL_ANDROID_recordable */
+#ifdef EGL_ANGLE_d3d_share_handle_client_buffer
+ EGLEW_ANGLE_d3d_share_handle_client_buffer = _glewSearchExtension("EGL_ANGLE_d3d_share_handle_client_buffer", extStart, extEnd);
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+#ifdef EGL_ANGLE_device_d3d
+ EGLEW_ANGLE_device_d3d = _glewSearchExtension("EGL_ANGLE_device_d3d", extStart, extEnd);
+#endif /* EGL_ANGLE_device_d3d */
+#ifdef EGL_ANGLE_query_surface_pointer
+ EGLEW_ANGLE_query_surface_pointer = _glewSearchExtension("EGL_ANGLE_query_surface_pointer", extStart, extEnd);
+ if (glewExperimental || EGLEW_ANGLE_query_surface_pointer) EGLEW_ANGLE_query_surface_pointer = !_glewInit_EGL_ANGLE_query_surface_pointer();
+#endif /* EGL_ANGLE_query_surface_pointer */
+#ifdef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+ EGLEW_ANGLE_surface_d3d_texture_2d_share_handle = _glewSearchExtension("EGL_ANGLE_surface_d3d_texture_2d_share_handle", extStart, extEnd);
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+#ifdef EGL_ANGLE_window_fixed_size
+ EGLEW_ANGLE_window_fixed_size = _glewSearchExtension("EGL_ANGLE_window_fixed_size", extStart, extEnd);
+#endif /* EGL_ANGLE_window_fixed_size */
+#ifdef EGL_ARM_implicit_external_sync
+ EGLEW_ARM_implicit_external_sync = _glewSearchExtension("EGL_ARM_implicit_external_sync", extStart, extEnd);
+#endif /* EGL_ARM_implicit_external_sync */
+#ifdef EGL_ARM_pixmap_multisample_discard
+ EGLEW_ARM_pixmap_multisample_discard = _glewSearchExtension("EGL_ARM_pixmap_multisample_discard", extStart, extEnd);
+#endif /* EGL_ARM_pixmap_multisample_discard */
+#ifdef EGL_EXT_buffer_age
+ EGLEW_EXT_buffer_age = _glewSearchExtension("EGL_EXT_buffer_age", extStart, extEnd);
+#endif /* EGL_EXT_buffer_age */
+#ifdef EGL_EXT_client_extensions
+ EGLEW_EXT_client_extensions = _glewSearchExtension("EGL_EXT_client_extensions", extStart, extEnd);
+#endif /* EGL_EXT_client_extensions */
+#ifdef EGL_EXT_create_context_robustness
+ EGLEW_EXT_create_context_robustness = _glewSearchExtension("EGL_EXT_create_context_robustness", extStart, extEnd);
+#endif /* EGL_EXT_create_context_robustness */
+#ifdef EGL_EXT_device_base
+ EGLEW_EXT_device_base = _glewSearchExtension("EGL_EXT_device_base", extStart, extEnd);
+#endif /* EGL_EXT_device_base */
+#ifdef EGL_EXT_device_drm
+ EGLEW_EXT_device_drm = _glewSearchExtension("EGL_EXT_device_drm", extStart, extEnd);
+#endif /* EGL_EXT_device_drm */
+#ifdef EGL_EXT_device_enumeration
+ EGLEW_EXT_device_enumeration = _glewSearchExtension("EGL_EXT_device_enumeration", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_device_enumeration) EGLEW_EXT_device_enumeration = !_glewInit_EGL_EXT_device_enumeration();
+#endif /* EGL_EXT_device_enumeration */
+#ifdef EGL_EXT_device_openwf
+ EGLEW_EXT_device_openwf = _glewSearchExtension("EGL_EXT_device_openwf", extStart, extEnd);
+#endif /* EGL_EXT_device_openwf */
+#ifdef EGL_EXT_device_query
+ EGLEW_EXT_device_query = _glewSearchExtension("EGL_EXT_device_query", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_device_query) EGLEW_EXT_device_query = !_glewInit_EGL_EXT_device_query();
+#endif /* EGL_EXT_device_query */
+#ifdef EGL_EXT_gl_colorspace_bt2020_linear
+ EGLEW_EXT_gl_colorspace_bt2020_linear = _glewSearchExtension("EGL_EXT_gl_colorspace_bt2020_linear", extStart, extEnd);
+#endif /* EGL_EXT_gl_colorspace_bt2020_linear */
+#ifdef EGL_EXT_gl_colorspace_bt2020_pq
+ EGLEW_EXT_gl_colorspace_bt2020_pq = _glewSearchExtension("EGL_EXT_gl_colorspace_bt2020_pq", extStart, extEnd);
+#endif /* EGL_EXT_gl_colorspace_bt2020_pq */
+#ifdef EGL_EXT_gl_colorspace_scrgb_linear
+ EGLEW_EXT_gl_colorspace_scrgb_linear = _glewSearchExtension("EGL_EXT_gl_colorspace_scrgb_linear", extStart, extEnd);
+#endif /* EGL_EXT_gl_colorspace_scrgb_linear */
+#ifdef EGL_EXT_image_dma_buf_import
+ EGLEW_EXT_image_dma_buf_import = _glewSearchExtension("EGL_EXT_image_dma_buf_import", extStart, extEnd);
+#endif /* EGL_EXT_image_dma_buf_import */
+#ifdef EGL_EXT_image_dma_buf_import_modifiers
+ EGLEW_EXT_image_dma_buf_import_modifiers = _glewSearchExtension("EGL_EXT_image_dma_buf_import_modifiers", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_image_dma_buf_import_modifiers) EGLEW_EXT_image_dma_buf_import_modifiers = !_glewInit_EGL_EXT_image_dma_buf_import_modifiers();
+#endif /* EGL_EXT_image_dma_buf_import_modifiers */
+#ifdef EGL_EXT_multiview_window
+ EGLEW_EXT_multiview_window = _glewSearchExtension("EGL_EXT_multiview_window", extStart, extEnd);
+#endif /* EGL_EXT_multiview_window */
+#ifdef EGL_EXT_output_base
+ EGLEW_EXT_output_base = _glewSearchExtension("EGL_EXT_output_base", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_output_base) EGLEW_EXT_output_base = !_glewInit_EGL_EXT_output_base();
+#endif /* EGL_EXT_output_base */
+#ifdef EGL_EXT_output_drm
+ EGLEW_EXT_output_drm = _glewSearchExtension("EGL_EXT_output_drm", extStart, extEnd);
+#endif /* EGL_EXT_output_drm */
+#ifdef EGL_EXT_output_openwf
+ EGLEW_EXT_output_openwf = _glewSearchExtension("EGL_EXT_output_openwf", extStart, extEnd);
+#endif /* EGL_EXT_output_openwf */
+#ifdef EGL_EXT_pixel_format_float
+ EGLEW_EXT_pixel_format_float = _glewSearchExtension("EGL_EXT_pixel_format_float", extStart, extEnd);
+#endif /* EGL_EXT_pixel_format_float */
+#ifdef EGL_EXT_platform_base
+ EGLEW_EXT_platform_base = _glewSearchExtension("EGL_EXT_platform_base", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_platform_base) EGLEW_EXT_platform_base = !_glewInit_EGL_EXT_platform_base();
+#endif /* EGL_EXT_platform_base */
+#ifdef EGL_EXT_platform_device
+ EGLEW_EXT_platform_device = _glewSearchExtension("EGL_EXT_platform_device", extStart, extEnd);
+#endif /* EGL_EXT_platform_device */
+#ifdef EGL_EXT_platform_wayland
+ EGLEW_EXT_platform_wayland = _glewSearchExtension("EGL_EXT_platform_wayland", extStart, extEnd);
+#endif /* EGL_EXT_platform_wayland */
+#ifdef EGL_EXT_platform_x11
+ EGLEW_EXT_platform_x11 = _glewSearchExtension("EGL_EXT_platform_x11", extStart, extEnd);
+#endif /* EGL_EXT_platform_x11 */
+#ifdef EGL_EXT_protected_content
+ EGLEW_EXT_protected_content = _glewSearchExtension("EGL_EXT_protected_content", extStart, extEnd);
+#endif /* EGL_EXT_protected_content */
+#ifdef EGL_EXT_protected_surface
+ EGLEW_EXT_protected_surface = _glewSearchExtension("EGL_EXT_protected_surface", extStart, extEnd);
+#endif /* EGL_EXT_protected_surface */
+#ifdef EGL_EXT_stream_consumer_egloutput
+ EGLEW_EXT_stream_consumer_egloutput = _glewSearchExtension("EGL_EXT_stream_consumer_egloutput", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_stream_consumer_egloutput) EGLEW_EXT_stream_consumer_egloutput = !_glewInit_EGL_EXT_stream_consumer_egloutput();
+#endif /* EGL_EXT_stream_consumer_egloutput */
+#ifdef EGL_EXT_surface_SMPTE2086_metadata
+ EGLEW_EXT_surface_SMPTE2086_metadata = _glewSearchExtension("EGL_EXT_surface_SMPTE2086_metadata", extStart, extEnd);
+#endif /* EGL_EXT_surface_SMPTE2086_metadata */
+#ifdef EGL_EXT_swap_buffers_with_damage
+ EGLEW_EXT_swap_buffers_with_damage = _glewSearchExtension("EGL_EXT_swap_buffers_with_damage", extStart, extEnd);
+ if (glewExperimental || EGLEW_EXT_swap_buffers_with_damage) EGLEW_EXT_swap_buffers_with_damage = !_glewInit_EGL_EXT_swap_buffers_with_damage();
+#endif /* EGL_EXT_swap_buffers_with_damage */
+#ifdef EGL_EXT_yuv_surface
+ EGLEW_EXT_yuv_surface = _glewSearchExtension("EGL_EXT_yuv_surface", extStart, extEnd);
+#endif /* EGL_EXT_yuv_surface */
+#ifdef EGL_HI_clientpixmap
+ EGLEW_HI_clientpixmap = _glewSearchExtension("EGL_HI_clientpixmap", extStart, extEnd);
+ if (glewExperimental || EGLEW_HI_clientpixmap) EGLEW_HI_clientpixmap = !_glewInit_EGL_HI_clientpixmap();
+#endif /* EGL_HI_clientpixmap */
+#ifdef EGL_HI_colorformats
+ EGLEW_HI_colorformats = _glewSearchExtension("EGL_HI_colorformats", extStart, extEnd);
+#endif /* EGL_HI_colorformats */
+#ifdef EGL_IMG_context_priority
+ EGLEW_IMG_context_priority = _glewSearchExtension("EGL_IMG_context_priority", extStart, extEnd);
+#endif /* EGL_IMG_context_priority */
+#ifdef EGL_IMG_image_plane_attribs
+ EGLEW_IMG_image_plane_attribs = _glewSearchExtension("EGL_IMG_image_plane_attribs", extStart, extEnd);
+#endif /* EGL_IMG_image_plane_attribs */
+#ifdef EGL_KHR_cl_event
+ EGLEW_KHR_cl_event = _glewSearchExtension("EGL_KHR_cl_event", extStart, extEnd);
+#endif /* EGL_KHR_cl_event */
+#ifdef EGL_KHR_cl_event2
+ EGLEW_KHR_cl_event2 = _glewSearchExtension("EGL_KHR_cl_event2", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_cl_event2) EGLEW_KHR_cl_event2 = !_glewInit_EGL_KHR_cl_event2();
+#endif /* EGL_KHR_cl_event2 */
+#ifdef EGL_KHR_client_get_all_proc_addresses
+ EGLEW_KHR_client_get_all_proc_addresses = _glewSearchExtension("EGL_KHR_client_get_all_proc_addresses", extStart, extEnd);
+#endif /* EGL_KHR_client_get_all_proc_addresses */
+#ifdef EGL_KHR_config_attribs
+ EGLEW_KHR_config_attribs = _glewSearchExtension("EGL_KHR_config_attribs", extStart, extEnd);
+#endif /* EGL_KHR_config_attribs */
+#ifdef EGL_KHR_context_flush_control
+ EGLEW_KHR_context_flush_control = _glewSearchExtension("EGL_KHR_context_flush_control", extStart, extEnd);
+#endif /* EGL_KHR_context_flush_control */
+#ifdef EGL_KHR_create_context
+ EGLEW_KHR_create_context = _glewSearchExtension("EGL_KHR_create_context", extStart, extEnd);
+#endif /* EGL_KHR_create_context */
+#ifdef EGL_KHR_create_context_no_error
+ EGLEW_KHR_create_context_no_error = _glewSearchExtension("EGL_KHR_create_context_no_error", extStart, extEnd);
+#endif /* EGL_KHR_create_context_no_error */
+#ifdef EGL_KHR_debug
+ EGLEW_KHR_debug = _glewSearchExtension("EGL_KHR_debug", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_debug) EGLEW_KHR_debug = !_glewInit_EGL_KHR_debug();
+#endif /* EGL_KHR_debug */
+#ifdef EGL_KHR_fence_sync
+ EGLEW_KHR_fence_sync = _glewSearchExtension("EGL_KHR_fence_sync", extStart, extEnd);
+#endif /* EGL_KHR_fence_sync */
+#ifdef EGL_KHR_get_all_proc_addresses
+ EGLEW_KHR_get_all_proc_addresses = _glewSearchExtension("EGL_KHR_get_all_proc_addresses", extStart, extEnd);
+#endif /* EGL_KHR_get_all_proc_addresses */
+#ifdef EGL_KHR_gl_colorspace
+ EGLEW_KHR_gl_colorspace = _glewSearchExtension("EGL_KHR_gl_colorspace", extStart, extEnd);
+#endif /* EGL_KHR_gl_colorspace */
+#ifdef EGL_KHR_gl_renderbuffer_image
+ EGLEW_KHR_gl_renderbuffer_image = _glewSearchExtension("EGL_KHR_gl_renderbuffer_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_renderbuffer_image */
+#ifdef EGL_KHR_gl_texture_2D_image
+ EGLEW_KHR_gl_texture_2D_image = _glewSearchExtension("EGL_KHR_gl_texture_2D_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_texture_2D_image */
+#ifdef EGL_KHR_gl_texture_3D_image
+ EGLEW_KHR_gl_texture_3D_image = _glewSearchExtension("EGL_KHR_gl_texture_3D_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_texture_3D_image */
+#ifdef EGL_KHR_gl_texture_cubemap_image
+ EGLEW_KHR_gl_texture_cubemap_image = _glewSearchExtension("EGL_KHR_gl_texture_cubemap_image", extStart, extEnd);
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+#ifdef EGL_KHR_image
+ EGLEW_KHR_image = _glewSearchExtension("EGL_KHR_image", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_image) EGLEW_KHR_image = !_glewInit_EGL_KHR_image();
+#endif /* EGL_KHR_image */
+#ifdef EGL_KHR_image_base
+ EGLEW_KHR_image_base = _glewSearchExtension("EGL_KHR_image_base", extStart, extEnd);
+#endif /* EGL_KHR_image_base */
+#ifdef EGL_KHR_image_pixmap
+ EGLEW_KHR_image_pixmap = _glewSearchExtension("EGL_KHR_image_pixmap", extStart, extEnd);
+#endif /* EGL_KHR_image_pixmap */
+#ifdef EGL_KHR_lock_surface
+ EGLEW_KHR_lock_surface = _glewSearchExtension("EGL_KHR_lock_surface", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_lock_surface) EGLEW_KHR_lock_surface = !_glewInit_EGL_KHR_lock_surface();
+#endif /* EGL_KHR_lock_surface */
+#ifdef EGL_KHR_lock_surface2
+ EGLEW_KHR_lock_surface2 = _glewSearchExtension("EGL_KHR_lock_surface2", extStart, extEnd);
+#endif /* EGL_KHR_lock_surface2 */
+#ifdef EGL_KHR_lock_surface3
+ EGLEW_KHR_lock_surface3 = _glewSearchExtension("EGL_KHR_lock_surface3", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_lock_surface3) EGLEW_KHR_lock_surface3 = !_glewInit_EGL_KHR_lock_surface3();
+#endif /* EGL_KHR_lock_surface3 */
+#ifdef EGL_KHR_mutable_render_buffer
+ EGLEW_KHR_mutable_render_buffer = _glewSearchExtension("EGL_KHR_mutable_render_buffer", extStart, extEnd);
+#endif /* EGL_KHR_mutable_render_buffer */
+#ifdef EGL_KHR_no_config_context
+ EGLEW_KHR_no_config_context = _glewSearchExtension("EGL_KHR_no_config_context", extStart, extEnd);
+#endif /* EGL_KHR_no_config_context */
+#ifdef EGL_KHR_partial_update
+ EGLEW_KHR_partial_update = _glewSearchExtension("EGL_KHR_partial_update", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_partial_update) EGLEW_KHR_partial_update = !_glewInit_EGL_KHR_partial_update();
+#endif /* EGL_KHR_partial_update */
+#ifdef EGL_KHR_platform_android
+ EGLEW_KHR_platform_android = _glewSearchExtension("EGL_KHR_platform_android", extStart, extEnd);
+#endif /* EGL_KHR_platform_android */
+#ifdef EGL_KHR_platform_gbm
+ EGLEW_KHR_platform_gbm = _glewSearchExtension("EGL_KHR_platform_gbm", extStart, extEnd);
+#endif /* EGL_KHR_platform_gbm */
+#ifdef EGL_KHR_platform_wayland
+ EGLEW_KHR_platform_wayland = _glewSearchExtension("EGL_KHR_platform_wayland", extStart, extEnd);
+#endif /* EGL_KHR_platform_wayland */
+#ifdef EGL_KHR_platform_x11
+ EGLEW_KHR_platform_x11 = _glewSearchExtension("EGL_KHR_platform_x11", extStart, extEnd);
+#endif /* EGL_KHR_platform_x11 */
+#ifdef EGL_KHR_reusable_sync
+ EGLEW_KHR_reusable_sync = _glewSearchExtension("EGL_KHR_reusable_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_reusable_sync) EGLEW_KHR_reusable_sync = !_glewInit_EGL_KHR_reusable_sync();
+#endif /* EGL_KHR_reusable_sync */
+#ifdef EGL_KHR_stream
+ EGLEW_KHR_stream = _glewSearchExtension("EGL_KHR_stream", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream) EGLEW_KHR_stream = !_glewInit_EGL_KHR_stream();
+#endif /* EGL_KHR_stream */
+#ifdef EGL_KHR_stream_attrib
+ EGLEW_KHR_stream_attrib = _glewSearchExtension("EGL_KHR_stream_attrib", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_attrib) EGLEW_KHR_stream_attrib = !_glewInit_EGL_KHR_stream_attrib();
+#endif /* EGL_KHR_stream_attrib */
+#ifdef EGL_KHR_stream_consumer_gltexture
+ EGLEW_KHR_stream_consumer_gltexture = _glewSearchExtension("EGL_KHR_stream_consumer_gltexture", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_consumer_gltexture) EGLEW_KHR_stream_consumer_gltexture = !_glewInit_EGL_KHR_stream_consumer_gltexture();
+#endif /* EGL_KHR_stream_consumer_gltexture */
+#ifdef EGL_KHR_stream_cross_process_fd
+ EGLEW_KHR_stream_cross_process_fd = _glewSearchExtension("EGL_KHR_stream_cross_process_fd", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_cross_process_fd) EGLEW_KHR_stream_cross_process_fd = !_glewInit_EGL_KHR_stream_cross_process_fd();
+#endif /* EGL_KHR_stream_cross_process_fd */
+#ifdef EGL_KHR_stream_fifo
+ EGLEW_KHR_stream_fifo = _glewSearchExtension("EGL_KHR_stream_fifo", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_fifo) EGLEW_KHR_stream_fifo = !_glewInit_EGL_KHR_stream_fifo();
+#endif /* EGL_KHR_stream_fifo */
+#ifdef EGL_KHR_stream_producer_aldatalocator
+ EGLEW_KHR_stream_producer_aldatalocator = _glewSearchExtension("EGL_KHR_stream_producer_aldatalocator", extStart, extEnd);
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+#ifdef EGL_KHR_stream_producer_eglsurface
+ EGLEW_KHR_stream_producer_eglsurface = _glewSearchExtension("EGL_KHR_stream_producer_eglsurface", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_stream_producer_eglsurface) EGLEW_KHR_stream_producer_eglsurface = !_glewInit_EGL_KHR_stream_producer_eglsurface();
+#endif /* EGL_KHR_stream_producer_eglsurface */
+#ifdef EGL_KHR_surfaceless_context
+ EGLEW_KHR_surfaceless_context = _glewSearchExtension("EGL_KHR_surfaceless_context", extStart, extEnd);
+#endif /* EGL_KHR_surfaceless_context */
+#ifdef EGL_KHR_swap_buffers_with_damage
+ EGLEW_KHR_swap_buffers_with_damage = _glewSearchExtension("EGL_KHR_swap_buffers_with_damage", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_swap_buffers_with_damage) EGLEW_KHR_swap_buffers_with_damage = !_glewInit_EGL_KHR_swap_buffers_with_damage();
+#endif /* EGL_KHR_swap_buffers_with_damage */
+#ifdef EGL_KHR_vg_parent_image
+ EGLEW_KHR_vg_parent_image = _glewSearchExtension("EGL_KHR_vg_parent_image", extStart, extEnd);
+#endif /* EGL_KHR_vg_parent_image */
+#ifdef EGL_KHR_wait_sync
+ EGLEW_KHR_wait_sync = _glewSearchExtension("EGL_KHR_wait_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_KHR_wait_sync) EGLEW_KHR_wait_sync = !_glewInit_EGL_KHR_wait_sync();
+#endif /* EGL_KHR_wait_sync */
+#ifdef EGL_MESA_drm_image
+ EGLEW_MESA_drm_image = _glewSearchExtension("EGL_MESA_drm_image", extStart, extEnd);
+ if (glewExperimental || EGLEW_MESA_drm_image) EGLEW_MESA_drm_image = !_glewInit_EGL_MESA_drm_image();
+#endif /* EGL_MESA_drm_image */
+#ifdef EGL_MESA_image_dma_buf_export
+ EGLEW_MESA_image_dma_buf_export = _glewSearchExtension("EGL_MESA_image_dma_buf_export", extStart, extEnd);
+ if (glewExperimental || EGLEW_MESA_image_dma_buf_export) EGLEW_MESA_image_dma_buf_export = !_glewInit_EGL_MESA_image_dma_buf_export();
+#endif /* EGL_MESA_image_dma_buf_export */
+#ifdef EGL_MESA_platform_gbm
+ EGLEW_MESA_platform_gbm = _glewSearchExtension("EGL_MESA_platform_gbm", extStart, extEnd);
+#endif /* EGL_MESA_platform_gbm */
+#ifdef EGL_MESA_platform_surfaceless
+ EGLEW_MESA_platform_surfaceless = _glewSearchExtension("EGL_MESA_platform_surfaceless", extStart, extEnd);
+#endif /* EGL_MESA_platform_surfaceless */
+#ifdef EGL_NOK_swap_region
+ EGLEW_NOK_swap_region = _glewSearchExtension("EGL_NOK_swap_region", extStart, extEnd);
+ if (glewExperimental || EGLEW_NOK_swap_region) EGLEW_NOK_swap_region = !_glewInit_EGL_NOK_swap_region();
+#endif /* EGL_NOK_swap_region */
+#ifdef EGL_NOK_swap_region2
+ EGLEW_NOK_swap_region2 = _glewSearchExtension("EGL_NOK_swap_region2", extStart, extEnd);
+ if (glewExperimental || EGLEW_NOK_swap_region2) EGLEW_NOK_swap_region2 = !_glewInit_EGL_NOK_swap_region2();
+#endif /* EGL_NOK_swap_region2 */
+#ifdef EGL_NOK_texture_from_pixmap
+ EGLEW_NOK_texture_from_pixmap = _glewSearchExtension("EGL_NOK_texture_from_pixmap", extStart, extEnd);
+#endif /* EGL_NOK_texture_from_pixmap */
+#ifdef EGL_NV_3dvision_surface
+ EGLEW_NV_3dvision_surface = _glewSearchExtension("EGL_NV_3dvision_surface", extStart, extEnd);
+#endif /* EGL_NV_3dvision_surface */
+#ifdef EGL_NV_coverage_sample
+ EGLEW_NV_coverage_sample = _glewSearchExtension("EGL_NV_coverage_sample", extStart, extEnd);
+#endif /* EGL_NV_coverage_sample */
+#ifdef EGL_NV_coverage_sample_resolve
+ EGLEW_NV_coverage_sample_resolve = _glewSearchExtension("EGL_NV_coverage_sample_resolve", extStart, extEnd);
+#endif /* EGL_NV_coverage_sample_resolve */
+#ifdef EGL_NV_cuda_event
+ EGLEW_NV_cuda_event = _glewSearchExtension("EGL_NV_cuda_event", extStart, extEnd);
+#endif /* EGL_NV_cuda_event */
+#ifdef EGL_NV_depth_nonlinear
+ EGLEW_NV_depth_nonlinear = _glewSearchExtension("EGL_NV_depth_nonlinear", extStart, extEnd);
+#endif /* EGL_NV_depth_nonlinear */
+#ifdef EGL_NV_device_cuda
+ EGLEW_NV_device_cuda = _glewSearchExtension("EGL_NV_device_cuda", extStart, extEnd);
+#endif /* EGL_NV_device_cuda */
+#ifdef EGL_NV_native_query
+ EGLEW_NV_native_query = _glewSearchExtension("EGL_NV_native_query", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_native_query) EGLEW_NV_native_query = !_glewInit_EGL_NV_native_query();
+#endif /* EGL_NV_native_query */
+#ifdef EGL_NV_post_convert_rounding
+ EGLEW_NV_post_convert_rounding = _glewSearchExtension("EGL_NV_post_convert_rounding", extStart, extEnd);
+#endif /* EGL_NV_post_convert_rounding */
+#ifdef EGL_NV_post_sub_buffer
+ EGLEW_NV_post_sub_buffer = _glewSearchExtension("EGL_NV_post_sub_buffer", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_post_sub_buffer) EGLEW_NV_post_sub_buffer = !_glewInit_EGL_NV_post_sub_buffer();
+#endif /* EGL_NV_post_sub_buffer */
+#ifdef EGL_NV_robustness_video_memory_purge
+ EGLEW_NV_robustness_video_memory_purge = _glewSearchExtension("EGL_NV_robustness_video_memory_purge", extStart, extEnd);
+#endif /* EGL_NV_robustness_video_memory_purge */
+#ifdef EGL_NV_stream_consumer_gltexture_yuv
+ EGLEW_NV_stream_consumer_gltexture_yuv = _glewSearchExtension("EGL_NV_stream_consumer_gltexture_yuv", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_stream_consumer_gltexture_yuv) EGLEW_NV_stream_consumer_gltexture_yuv = !_glewInit_EGL_NV_stream_consumer_gltexture_yuv();
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+#ifdef EGL_NV_stream_cross_display
+ EGLEW_NV_stream_cross_display = _glewSearchExtension("EGL_NV_stream_cross_display", extStart, extEnd);
+#endif /* EGL_NV_stream_cross_display */
+#ifdef EGL_NV_stream_cross_object
+ EGLEW_NV_stream_cross_object = _glewSearchExtension("EGL_NV_stream_cross_object", extStart, extEnd);
+#endif /* EGL_NV_stream_cross_object */
+#ifdef EGL_NV_stream_cross_partition
+ EGLEW_NV_stream_cross_partition = _glewSearchExtension("EGL_NV_stream_cross_partition", extStart, extEnd);
+#endif /* EGL_NV_stream_cross_partition */
+#ifdef EGL_NV_stream_cross_process
+ EGLEW_NV_stream_cross_process = _glewSearchExtension("EGL_NV_stream_cross_process", extStart, extEnd);
+#endif /* EGL_NV_stream_cross_process */
+#ifdef EGL_NV_stream_cross_system
+ EGLEW_NV_stream_cross_system = _glewSearchExtension("EGL_NV_stream_cross_system", extStart, extEnd);
+#endif /* EGL_NV_stream_cross_system */
+#ifdef EGL_NV_stream_fifo_next
+ EGLEW_NV_stream_fifo_next = _glewSearchExtension("EGL_NV_stream_fifo_next", extStart, extEnd);
+#endif /* EGL_NV_stream_fifo_next */
+#ifdef EGL_NV_stream_fifo_synchronous
+ EGLEW_NV_stream_fifo_synchronous = _glewSearchExtension("EGL_NV_stream_fifo_synchronous", extStart, extEnd);
+#endif /* EGL_NV_stream_fifo_synchronous */
+#ifdef EGL_NV_stream_frame_limits
+ EGLEW_NV_stream_frame_limits = _glewSearchExtension("EGL_NV_stream_frame_limits", extStart, extEnd);
+#endif /* EGL_NV_stream_frame_limits */
+#ifdef EGL_NV_stream_metadata
+ EGLEW_NV_stream_metadata = _glewSearchExtension("EGL_NV_stream_metadata", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_stream_metadata) EGLEW_NV_stream_metadata = !_glewInit_EGL_NV_stream_metadata();
+#endif /* EGL_NV_stream_metadata */
+#ifdef EGL_NV_stream_remote
+ EGLEW_NV_stream_remote = _glewSearchExtension("EGL_NV_stream_remote", extStart, extEnd);
+#endif /* EGL_NV_stream_remote */
+#ifdef EGL_NV_stream_reset
+ EGLEW_NV_stream_reset = _glewSearchExtension("EGL_NV_stream_reset", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_stream_reset) EGLEW_NV_stream_reset = !_glewInit_EGL_NV_stream_reset();
+#endif /* EGL_NV_stream_reset */
+#ifdef EGL_NV_stream_socket
+ EGLEW_NV_stream_socket = _glewSearchExtension("EGL_NV_stream_socket", extStart, extEnd);
+#endif /* EGL_NV_stream_socket */
+#ifdef EGL_NV_stream_socket_inet
+ EGLEW_NV_stream_socket_inet = _glewSearchExtension("EGL_NV_stream_socket_inet", extStart, extEnd);
+#endif /* EGL_NV_stream_socket_inet */
+#ifdef EGL_NV_stream_socket_unix
+ EGLEW_NV_stream_socket_unix = _glewSearchExtension("EGL_NV_stream_socket_unix", extStart, extEnd);
+#endif /* EGL_NV_stream_socket_unix */
+#ifdef EGL_NV_stream_sync
+ EGLEW_NV_stream_sync = _glewSearchExtension("EGL_NV_stream_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_stream_sync) EGLEW_NV_stream_sync = !_glewInit_EGL_NV_stream_sync();
+#endif /* EGL_NV_stream_sync */
+#ifdef EGL_NV_sync
+ EGLEW_NV_sync = _glewSearchExtension("EGL_NV_sync", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_sync) EGLEW_NV_sync = !_glewInit_EGL_NV_sync();
+#endif /* EGL_NV_sync */
+#ifdef EGL_NV_system_time
+ EGLEW_NV_system_time = _glewSearchExtension("EGL_NV_system_time", extStart, extEnd);
+ if (glewExperimental || EGLEW_NV_system_time) EGLEW_NV_system_time = !_glewInit_EGL_NV_system_time();
+#endif /* EGL_NV_system_time */
+#ifdef EGL_TIZEN_image_native_buffer
+ EGLEW_TIZEN_image_native_buffer = _glewSearchExtension("EGL_TIZEN_image_native_buffer", extStart, extEnd);
+#endif /* EGL_TIZEN_image_native_buffer */
+#ifdef EGL_TIZEN_image_native_surface
+ EGLEW_TIZEN_image_native_surface = _glewSearchExtension("EGL_TIZEN_image_native_surface", extStart, extEnd);
+#endif /* EGL_TIZEN_image_native_surface */
+
+ return GLEW_OK;
+}
+
+#elif defined(_WIN32)
+
+PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL;
+
+PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD = NULL;
+PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD = NULL;
+PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD = NULL;
+PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD = NULL;
+PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD = NULL;
+PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD = NULL;
+PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD = NULL;
+PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD = NULL;
+PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD = NULL;
+
+PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB = NULL;
+PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB = NULL;
+PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB = NULL;
+PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB = NULL;
+
+PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB = NULL;
+
+PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB = NULL;
+
+PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB = NULL;
+PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB = NULL;
+
+PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB = NULL;
+PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB = NULL;
+PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB = NULL;
+PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB = NULL;
+PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB = NULL;
+
+PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB = NULL;
+PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB = NULL;
+PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB = NULL;
+
+PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB = NULL;
+PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB = NULL;
+PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB = NULL;
+
+PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT = NULL;
+PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT = NULL;
+PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT = NULL;
+PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT = NULL;
+
+PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT = NULL;
+
+PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT = NULL;
+PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT = NULL;
+
+PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT = NULL;
+PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT = NULL;
+PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT = NULL;
+PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT = NULL;
+PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT = NULL;
+
+PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT = NULL;
+PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT = NULL;
+PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT = NULL;
+
+PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT = NULL;
+PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT = NULL;
+
+PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D = NULL;
+PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D = NULL;
+
+PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D = NULL;
+PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D = NULL;
+PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D = NULL;
+PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D = NULL;
+
+PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D = NULL;
+PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D = NULL;
+PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D = NULL;
+PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D = NULL;
+PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D = NULL;
+PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D = NULL;
+PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D = NULL;
+PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D = NULL;
+PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D = NULL;
+PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D = NULL;
+PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D = NULL;
+PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D = NULL;
+
+PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D = NULL;
+PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D = NULL;
+PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D = NULL;
+PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D = NULL;
+
+PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D = NULL;
+PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D = NULL;
+PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D = NULL;
+PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D = NULL;
+
+PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D = NULL;
+PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D = NULL;
+PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D = NULL;
+PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D = NULL;
+
+PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV = NULL;
+PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV = NULL;
+PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV = NULL;
+PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV = NULL;
+PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV = NULL;
+PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV = NULL;
+PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV = NULL;
+PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV = NULL;
+
+PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV = NULL;
+
+PFNWGLDELAYBEFORESWAPNVPROC __wglewDelayBeforeSwapNV = NULL;
+
+PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV = NULL;
+PFNWGLDELETEDCNVPROC __wglewDeleteDCNV = NULL;
+PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV = NULL;
+PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV = NULL;
+PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV = NULL;
+
+PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV = NULL;
+PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV = NULL;
+PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV = NULL;
+
+PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV = NULL;
+PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV = NULL;
+PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV = NULL;
+PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV = NULL;
+PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV = NULL;
+PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV = NULL;
+
+PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV = NULL;
+PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV = NULL;
+
+PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV = NULL;
+PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV = NULL;
+PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV = NULL;
+PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV = NULL;
+PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV = NULL;
+
+PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV = NULL;
+PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV = NULL;
+PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV = NULL;
+PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV = NULL;
+PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV = NULL;
+PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV = NULL;
+
+PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML = NULL;
+PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML = NULL;
+PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML = NULL;
+PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML = NULL;
+PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML = NULL;
+PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML = NULL;
+GLboolean __WGLEW_3DFX_multisample = GL_FALSE;
+GLboolean __WGLEW_3DL_stereo_control = GL_FALSE;
+GLboolean __WGLEW_AMD_gpu_association = GL_FALSE;
+GLboolean __WGLEW_ARB_buffer_region = GL_FALSE;
+GLboolean __WGLEW_ARB_context_flush_control = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context_no_error = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context_profile = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context_robustness = GL_FALSE;
+GLboolean __WGLEW_ARB_extensions_string = GL_FALSE;
+GLboolean __WGLEW_ARB_framebuffer_sRGB = GL_FALSE;
+GLboolean __WGLEW_ARB_make_current_read = GL_FALSE;
+GLboolean __WGLEW_ARB_multisample = GL_FALSE;
+GLboolean __WGLEW_ARB_pbuffer = GL_FALSE;
+GLboolean __WGLEW_ARB_pixel_format = GL_FALSE;
+GLboolean __WGLEW_ARB_pixel_format_float = GL_FALSE;
+GLboolean __WGLEW_ARB_render_texture = GL_FALSE;
+GLboolean __WGLEW_ARB_robustness_application_isolation = GL_FALSE;
+GLboolean __WGLEW_ARB_robustness_share_group_isolation = GL_FALSE;
+GLboolean __WGLEW_ATI_pixel_format_float = GL_FALSE;
+GLboolean __WGLEW_ATI_render_texture_rectangle = GL_FALSE;
+GLboolean __WGLEW_EXT_colorspace = GL_FALSE;
+GLboolean __WGLEW_EXT_create_context_es2_profile = GL_FALSE;
+GLboolean __WGLEW_EXT_create_context_es_profile = GL_FALSE;
+GLboolean __WGLEW_EXT_depth_float = GL_FALSE;
+GLboolean __WGLEW_EXT_display_color_table = GL_FALSE;
+GLboolean __WGLEW_EXT_extensions_string = GL_FALSE;
+GLboolean __WGLEW_EXT_framebuffer_sRGB = GL_FALSE;
+GLboolean __WGLEW_EXT_make_current_read = GL_FALSE;
+GLboolean __WGLEW_EXT_multisample = GL_FALSE;
+GLboolean __WGLEW_EXT_pbuffer = GL_FALSE;
+GLboolean __WGLEW_EXT_pixel_format = GL_FALSE;
+GLboolean __WGLEW_EXT_pixel_format_packed_float = GL_FALSE;
+GLboolean __WGLEW_EXT_swap_control = GL_FALSE;
+GLboolean __WGLEW_EXT_swap_control_tear = GL_FALSE;
+GLboolean __WGLEW_I3D_digital_video_control = GL_FALSE;
+GLboolean __WGLEW_I3D_gamma = GL_FALSE;
+GLboolean __WGLEW_I3D_genlock = GL_FALSE;
+GLboolean __WGLEW_I3D_image_buffer = GL_FALSE;
+GLboolean __WGLEW_I3D_swap_frame_lock = GL_FALSE;
+GLboolean __WGLEW_I3D_swap_frame_usage = GL_FALSE;
+GLboolean __WGLEW_NV_DX_interop = GL_FALSE;
+GLboolean __WGLEW_NV_DX_interop2 = GL_FALSE;
+GLboolean __WGLEW_NV_copy_image = GL_FALSE;
+GLboolean __WGLEW_NV_delay_before_swap = GL_FALSE;
+GLboolean __WGLEW_NV_float_buffer = GL_FALSE;
+GLboolean __WGLEW_NV_gpu_affinity = GL_FALSE;
+GLboolean __WGLEW_NV_multisample_coverage = GL_FALSE;
+GLboolean __WGLEW_NV_present_video = GL_FALSE;
+GLboolean __WGLEW_NV_render_depth_texture = GL_FALSE;
+GLboolean __WGLEW_NV_render_texture_rectangle = GL_FALSE;
+GLboolean __WGLEW_NV_swap_group = GL_FALSE;
+GLboolean __WGLEW_NV_vertex_array_range = GL_FALSE;
+GLboolean __WGLEW_NV_video_capture = GL_FALSE;
+GLboolean __WGLEW_NV_video_output = GL_FALSE;
+GLboolean __WGLEW_OML_sync_control = GL_FALSE;
+#ifdef WGL_3DL_stereo_control
+
+static GLboolean _glewInit_WGL_3DL_stereo_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglSetStereoEmitterState3DL = (PFNWGLSETSTEREOEMITTERSTATE3DLPROC)glewGetProcAddress((const GLubyte*)"wglSetStereoEmitterState3DL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_3DL_stereo_control */
+
+#ifdef WGL_AMD_gpu_association
+
+static GLboolean _glewInit_WGL_AMD_gpu_association ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBlitContextFramebufferAMD = (PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)glewGetProcAddress((const GLubyte*)"wglBlitContextFramebufferAMD")) == NULL) || r;
+ r = ((wglCreateAssociatedContextAMD = (PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAMD")) == NULL) || r;
+ r = ((wglCreateAssociatedContextAttribsAMD = (PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAttribsAMD")) == NULL) || r;
+ r = ((wglDeleteAssociatedContextAMD = (PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglDeleteAssociatedContextAMD")) == NULL) || r;
+ r = ((wglGetContextGPUIDAMD = (PFNWGLGETCONTEXTGPUIDAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetContextGPUIDAMD")) == NULL) || r;
+ r = ((wglGetCurrentAssociatedContextAMD = (PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentAssociatedContextAMD")) == NULL) || r;
+ r = ((wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUIDsAMD")) == NULL) || r;
+ r = ((wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUInfoAMD")) == NULL) || r;
+ r = ((wglMakeAssociatedContextCurrentAMD = (PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)glewGetProcAddress((const GLubyte*)"wglMakeAssociatedContextCurrentAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_AMD_gpu_association */
+
+#ifdef WGL_ARB_buffer_region
+
+static GLboolean _glewInit_WGL_ARB_buffer_region ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreateBufferRegionARB = (PFNWGLCREATEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateBufferRegionARB")) == NULL) || r;
+ r = ((wglDeleteBufferRegionARB = (PFNWGLDELETEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglDeleteBufferRegionARB")) == NULL) || r;
+ r = ((wglRestoreBufferRegionARB = (PFNWGLRESTOREBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglRestoreBufferRegionARB")) == NULL) || r;
+ r = ((wglSaveBufferRegionARB = (PFNWGLSAVEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglSaveBufferRegionARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_buffer_region */
+
+#ifdef WGL_ARB_create_context
+
+static GLboolean _glewInit_WGL_ARB_create_context ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateContextAttribsARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_create_context */
+
+#ifdef WGL_ARB_extensions_string
+
+static GLboolean _glewInit_WGL_ARB_extensions_string ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_extensions_string */
+
+#ifdef WGL_ARB_make_current_read
+
+static GLboolean _glewInit_WGL_ARB_make_current_read ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCARB")) == NULL) || r;
+ r = ((wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_make_current_read */
+
+#ifdef WGL_ARB_pbuffer
+
+static GLboolean _glewInit_WGL_ARB_pbuffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferARB")) == NULL) || r;
+ r = ((wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferARB")) == NULL) || r;
+ r = ((wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCARB")) == NULL) || r;
+ r = ((wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferARB")) == NULL) || r;
+ r = ((wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_pbuffer */
+
+#ifdef WGL_ARB_pixel_format
+
+static GLboolean _glewInit_WGL_ARB_pixel_format ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatARB")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvARB")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_pixel_format */
+
+#ifdef WGL_ARB_render_texture
+
+static GLboolean _glewInit_WGL_ARB_render_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglBindTexImageARB")) == NULL) || r;
+ r = ((wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglReleaseTexImageARB")) == NULL) || r;
+ r = ((wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"wglSetPbufferAttribARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_render_texture */
+
+#ifdef WGL_EXT_display_color_table
+
+static GLboolean _glewInit_WGL_EXT_display_color_table ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindDisplayColorTableEXT = (PFNWGLBINDDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglBindDisplayColorTableEXT")) == NULL) || r;
+ r = ((wglCreateDisplayColorTableEXT = (PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglCreateDisplayColorTableEXT")) == NULL) || r;
+ r = ((wglDestroyDisplayColorTableEXT = (PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyDisplayColorTableEXT")) == NULL) || r;
+ r = ((wglLoadDisplayColorTableEXT = (PFNWGLLOADDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglLoadDisplayColorTableEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_display_color_table */
+
+#ifdef WGL_EXT_extensions_string
+
+static GLboolean _glewInit_WGL_EXT_extensions_string ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_extensions_string */
+
+#ifdef WGL_EXT_make_current_read
+
+static GLboolean _glewInit_WGL_EXT_make_current_read ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetCurrentReadDCEXT = (PFNWGLGETCURRENTREADDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCEXT")) == NULL) || r;
+ r = ((wglMakeContextCurrentEXT = (PFNWGLMAKECONTEXTCURRENTEXTPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_make_current_read */
+
+#ifdef WGL_EXT_pbuffer
+
+static GLboolean _glewInit_WGL_EXT_pbuffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreatePbufferEXT = (PFNWGLCREATEPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferEXT")) == NULL) || r;
+ r = ((wglDestroyPbufferEXT = (PFNWGLDESTROYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferEXT")) == NULL) || r;
+ r = ((wglGetPbufferDCEXT = (PFNWGLGETPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCEXT")) == NULL) || r;
+ r = ((wglQueryPbufferEXT = (PFNWGLQUERYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferEXT")) == NULL) || r;
+ r = ((wglReleasePbufferDCEXT = (PFNWGLRELEASEPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_pbuffer */
+
+#ifdef WGL_EXT_pixel_format
+
+static GLboolean _glewInit_WGL_EXT_pixel_format ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatEXT")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribfvEXT = (PFNWGLGETPIXELFORMATATTRIBFVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvEXT")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_pixel_format */
+
+#ifdef WGL_EXT_swap_control
+
+static GLboolean _glewInit_WGL_EXT_swap_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetSwapIntervalEXT")) == NULL) || r;
+ r = ((wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglSwapIntervalEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_swap_control */
+
+#ifdef WGL_I3D_digital_video_control
+
+static GLboolean _glewInit_WGL_I3D_digital_video_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetDigitalVideoParametersI3D = (PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetDigitalVideoParametersI3D")) == NULL) || r;
+ r = ((wglSetDigitalVideoParametersI3D = (PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetDigitalVideoParametersI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_digital_video_control */
+
+#ifdef WGL_I3D_gamma
+
+static GLboolean _glewInit_WGL_I3D_gamma ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetGammaTableI3D = (PFNWGLGETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableI3D")) == NULL) || r;
+ r = ((wglGetGammaTableParametersI3D = (PFNWGLGETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableParametersI3D")) == NULL) || r;
+ r = ((wglSetGammaTableI3D = (PFNWGLSETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableI3D")) == NULL) || r;
+ r = ((wglSetGammaTableParametersI3D = (PFNWGLSETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableParametersI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_gamma */
+
+#ifdef WGL_I3D_genlock
+
+static GLboolean _glewInit_WGL_I3D_genlock ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglDisableGenlockI3D = (PFNWGLDISABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableGenlockI3D")) == NULL) || r;
+ r = ((wglEnableGenlockI3D = (PFNWGLENABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableGenlockI3D")) == NULL) || r;
+ r = ((wglGenlockSampleRateI3D = (PFNWGLGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSampleRateI3D")) == NULL) || r;
+ r = ((wglGenlockSourceDelayI3D = (PFNWGLGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceDelayI3D")) == NULL) || r;
+ r = ((wglGenlockSourceEdgeI3D = (PFNWGLGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceEdgeI3D")) == NULL) || r;
+ r = ((wglGenlockSourceI3D = (PFNWGLGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceI3D")) == NULL) || r;
+ r = ((wglGetGenlockSampleRateI3D = (PFNWGLGETGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSampleRateI3D")) == NULL) || r;
+ r = ((wglGetGenlockSourceDelayI3D = (PFNWGLGETGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceDelayI3D")) == NULL) || r;
+ r = ((wglGetGenlockSourceEdgeI3D = (PFNWGLGETGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceEdgeI3D")) == NULL) || r;
+ r = ((wglGetGenlockSourceI3D = (PFNWGLGETGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceI3D")) == NULL) || r;
+ r = ((wglIsEnabledGenlockI3D = (PFNWGLISENABLEDGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledGenlockI3D")) == NULL) || r;
+ r = ((wglQueryGenlockMaxSourceDelayI3D = (PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryGenlockMaxSourceDelayI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_genlock */
+
+#ifdef WGL_I3D_image_buffer
+
+static GLboolean _glewInit_WGL_I3D_image_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglAssociateImageBufferEventsI3D = (PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglAssociateImageBufferEventsI3D")) == NULL) || r;
+ r = ((wglCreateImageBufferI3D = (PFNWGLCREATEIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglCreateImageBufferI3D")) == NULL) || r;
+ r = ((wglDestroyImageBufferI3D = (PFNWGLDESTROYIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglDestroyImageBufferI3D")) == NULL) || r;
+ r = ((wglReleaseImageBufferEventsI3D = (PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglReleaseImageBufferEventsI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_image_buffer */
+
+#ifdef WGL_I3D_swap_frame_lock
+
+static GLboolean _glewInit_WGL_I3D_swap_frame_lock ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglDisableFrameLockI3D = (PFNWGLDISABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableFrameLockI3D")) == NULL) || r;
+ r = ((wglEnableFrameLockI3D = (PFNWGLENABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableFrameLockI3D")) == NULL) || r;
+ r = ((wglIsEnabledFrameLockI3D = (PFNWGLISENABLEDFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledFrameLockI3D")) == NULL) || r;
+ r = ((wglQueryFrameLockMasterI3D = (PFNWGLQUERYFRAMELOCKMASTERI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameLockMasterI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_swap_frame_lock */
+
+#ifdef WGL_I3D_swap_frame_usage
+
+static GLboolean _glewInit_WGL_I3D_swap_frame_usage ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBeginFrameTrackingI3D = (PFNWGLBEGINFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglBeginFrameTrackingI3D")) == NULL) || r;
+ r = ((wglEndFrameTrackingI3D = (PFNWGLENDFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglEndFrameTrackingI3D")) == NULL) || r;
+ r = ((wglGetFrameUsageI3D = (PFNWGLGETFRAMEUSAGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetFrameUsageI3D")) == NULL) || r;
+ r = ((wglQueryFrameTrackingI3D = (PFNWGLQUERYFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameTrackingI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_swap_frame_usage */
+
+#ifdef WGL_NV_DX_interop
+
+static GLboolean _glewInit_WGL_NV_DX_interop ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglDXCloseDeviceNV = (PFNWGLDXCLOSEDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglDXCloseDeviceNV")) == NULL) || r;
+ r = ((wglDXLockObjectsNV = (PFNWGLDXLOCKOBJECTSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXLockObjectsNV")) == NULL) || r;
+ r = ((wglDXObjectAccessNV = (PFNWGLDXOBJECTACCESSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXObjectAccessNV")) == NULL) || r;
+ r = ((wglDXOpenDeviceNV = (PFNWGLDXOPENDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglDXOpenDeviceNV")) == NULL) || r;
+ r = ((wglDXRegisterObjectNV = (PFNWGLDXREGISTEROBJECTNVPROC)glewGetProcAddress((const GLubyte*)"wglDXRegisterObjectNV")) == NULL) || r;
+ r = ((wglDXSetResourceShareHandleNV = (PFNWGLDXSETRESOURCESHAREHANDLENVPROC)glewGetProcAddress((const GLubyte*)"wglDXSetResourceShareHandleNV")) == NULL) || r;
+ r = ((wglDXUnlockObjectsNV = (PFNWGLDXUNLOCKOBJECTSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXUnlockObjectsNV")) == NULL) || r;
+ r = ((wglDXUnregisterObjectNV = (PFNWGLDXUNREGISTEROBJECTNVPROC)glewGetProcAddress((const GLubyte*)"wglDXUnregisterObjectNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_DX_interop */
+
+#ifdef WGL_NV_copy_image
+
+static GLboolean _glewInit_WGL_NV_copy_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCopyImageSubDataNV = (PFNWGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"wglCopyImageSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_copy_image */
+
+#ifdef WGL_NV_delay_before_swap
+
+static GLboolean _glewInit_WGL_NV_delay_before_swap ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglDelayBeforeSwapNV = (PFNWGLDELAYBEFORESWAPNVPROC)glewGetProcAddress((const GLubyte*)"wglDelayBeforeSwapNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_delay_before_swap */
+
+#ifdef WGL_NV_gpu_affinity
+
+static GLboolean _glewInit_WGL_NV_gpu_affinity ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreateAffinityDCNV = (PFNWGLCREATEAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglCreateAffinityDCNV")) == NULL) || r;
+ r = ((wglDeleteDCNV = (PFNWGLDELETEDCNVPROC)glewGetProcAddress((const GLubyte*)"wglDeleteDCNV")) == NULL) || r;
+ r = ((wglEnumGpuDevicesNV = (PFNWGLENUMGPUDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpuDevicesNV")) == NULL) || r;
+ r = ((wglEnumGpusFromAffinityDCNV = (PFNWGLENUMGPUSFROMAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusFromAffinityDCNV")) == NULL) || r;
+ r = ((wglEnumGpusNV = (PFNWGLENUMGPUSNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_gpu_affinity */
+
+#ifdef WGL_NV_present_video
+
+static GLboolean _glewInit_WGL_NV_present_video ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindVideoDeviceNV = (PFNWGLBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoDeviceNV")) == NULL) || r;
+ r = ((wglEnumerateVideoDevicesNV = (PFNWGLENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoDevicesNV")) == NULL) || r;
+ r = ((wglQueryCurrentContextNV = (PFNWGLQUERYCURRENTCONTEXTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryCurrentContextNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_present_video */
+
+#ifdef WGL_NV_swap_group
+
+static GLboolean _glewInit_WGL_NV_swap_group ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindSwapBarrierNV = (PFNWGLBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"wglBindSwapBarrierNV")) == NULL) || r;
+ r = ((wglJoinSwapGroupNV = (PFNWGLJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglJoinSwapGroupNV")) == NULL) || r;
+ r = ((wglQueryFrameCountNV = (PFNWGLQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameCountNV")) == NULL) || r;
+ r = ((wglQueryMaxSwapGroupsNV = (PFNWGLQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryMaxSwapGroupsNV")) == NULL) || r;
+ r = ((wglQuerySwapGroupNV = (PFNWGLQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglQuerySwapGroupNV")) == NULL) || r;
+ r = ((wglResetFrameCountNV = (PFNWGLRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglResetFrameCountNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_swap_group */
+
+#ifdef WGL_NV_vertex_array_range
+
+static GLboolean _glewInit_WGL_NV_vertex_array_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglAllocateMemoryNV")) == NULL) || r;
+ r = ((wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglFreeMemoryNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_vertex_array_range */
+
+#ifdef WGL_NV_video_capture
+
+static GLboolean _glewInit_WGL_NV_video_capture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindVideoCaptureDeviceNV = (PFNWGLBINDVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((wglEnumerateVideoCaptureDevicesNV = (PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoCaptureDevicesNV")) == NULL) || r;
+ r = ((wglLockVideoCaptureDeviceNV = (PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglLockVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((wglQueryVideoCaptureDeviceNV = (PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglQueryVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((wglReleaseVideoCaptureDeviceNV = (PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoCaptureDeviceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_video_capture */
+
+#ifdef WGL_NV_video_output
+
+static GLboolean _glewInit_WGL_NV_video_output ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindVideoImageNV = (PFNWGLBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoImageNV")) == NULL) || r;
+ r = ((wglGetVideoDeviceNV = (PFNWGLGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoDeviceNV")) == NULL) || r;
+ r = ((wglGetVideoInfoNV = (PFNWGLGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoInfoNV")) == NULL) || r;
+ r = ((wglReleaseVideoDeviceNV = (PFNWGLRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoDeviceNV")) == NULL) || r;
+ r = ((wglReleaseVideoImageNV = (PFNWGLRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoImageNV")) == NULL) || r;
+ r = ((wglSendPbufferToVideoNV = (PFNWGLSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"wglSendPbufferToVideoNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_video_output */
+
+#ifdef WGL_OML_sync_control
+
+static GLboolean _glewInit_WGL_OML_sync_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetMscRateOML = (PFNWGLGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetMscRateOML")) == NULL) || r;
+ r = ((wglGetSyncValuesOML = (PFNWGLGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetSyncValuesOML")) == NULL) || r;
+ r = ((wglSwapBuffersMscOML = (PFNWGLSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapBuffersMscOML")) == NULL) || r;
+ r = ((wglSwapLayerBuffersMscOML = (PFNWGLSWAPLAYERBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapLayerBuffersMscOML")) == NULL) || r;
+ r = ((wglWaitForMscOML = (PFNWGLWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForMscOML")) == NULL) || r;
+ r = ((wglWaitForSbcOML = (PFNWGLWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForSbcOML")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_OML_sync_control */
+
+/* ------------------------------------------------------------------------- */
+
+static PFNWGLGETEXTENSIONSSTRINGARBPROC _wglewGetExtensionsStringARB = NULL;
+static PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglewGetExtensionsStringEXT = NULL;
+
+GLboolean GLEWAPIENTRY wglewGetExtension (const char* name)
+{
+ const GLubyte* start;
+ const GLubyte* end;
+ if (_wglewGetExtensionsStringARB == NULL)
+ if (_wglewGetExtensionsStringEXT == NULL)
+ return GL_FALSE;
+ else
+ start = (const GLubyte*)_wglewGetExtensionsStringEXT();
+ else
+ start = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC());
+ if (start == 0)
+ return GL_FALSE;
+ end = start + _glewStrLen(start);
+ return _glewSearchExtension(name, start, end);
+}
+
+GLenum GLEWAPIENTRY wglewInit ()
+{
+ GLboolean crippled;
+ const GLubyte* extStart;
+ const GLubyte* extEnd;
+ /* find wgl extension string query functions */
+ _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB");
+ _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT");
+ /* query wgl extension string */
+ if (_wglewGetExtensionsStringARB == NULL)
+ if (_wglewGetExtensionsStringEXT == NULL)
+ extStart = (const GLubyte*)"";
+ else
+ extStart = (const GLubyte*)_wglewGetExtensionsStringEXT();
+ else
+ extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC());
+ extEnd = extStart + _glewStrLen(extStart);
+ /* initialize extensions */
+ crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL;
+#ifdef WGL_3DFX_multisample
+ WGLEW_3DFX_multisample = _glewSearchExtension("WGL_3DFX_multisample", extStart, extEnd);
+#endif /* WGL_3DFX_multisample */
+#ifdef WGL_3DL_stereo_control
+ WGLEW_3DL_stereo_control = _glewSearchExtension("WGL_3DL_stereo_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) WGLEW_3DL_stereo_control= !_glewInit_WGL_3DL_stereo_control();
+#endif /* WGL_3DL_stereo_control */
+#ifdef WGL_AMD_gpu_association
+ WGLEW_AMD_gpu_association = _glewSearchExtension("WGL_AMD_gpu_association", extStart, extEnd);
+ if (glewExperimental || WGLEW_AMD_gpu_association|| crippled) WGLEW_AMD_gpu_association= !_glewInit_WGL_AMD_gpu_association();
+#endif /* WGL_AMD_gpu_association */
+#ifdef WGL_ARB_buffer_region
+ WGLEW_ARB_buffer_region = _glewSearchExtension("WGL_ARB_buffer_region", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) WGLEW_ARB_buffer_region= !_glewInit_WGL_ARB_buffer_region();
+#endif /* WGL_ARB_buffer_region */
+#ifdef WGL_ARB_context_flush_control
+ WGLEW_ARB_context_flush_control = _glewSearchExtension("WGL_ARB_context_flush_control", extStart, extEnd);
+#endif /* WGL_ARB_context_flush_control */
+#ifdef WGL_ARB_create_context
+ WGLEW_ARB_create_context = _glewSearchExtension("WGL_ARB_create_context", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_create_context|| crippled) WGLEW_ARB_create_context= !_glewInit_WGL_ARB_create_context();
+#endif /* WGL_ARB_create_context */
+#ifdef WGL_ARB_create_context_no_error
+ WGLEW_ARB_create_context_no_error = _glewSearchExtension("WGL_ARB_create_context_no_error", extStart, extEnd);
+#endif /* WGL_ARB_create_context_no_error */
+#ifdef WGL_ARB_create_context_profile
+ WGLEW_ARB_create_context_profile = _glewSearchExtension("WGL_ARB_create_context_profile", extStart, extEnd);
+#endif /* WGL_ARB_create_context_profile */
+#ifdef WGL_ARB_create_context_robustness
+ WGLEW_ARB_create_context_robustness = _glewSearchExtension("WGL_ARB_create_context_robustness", extStart, extEnd);
+#endif /* WGL_ARB_create_context_robustness */
+#ifdef WGL_ARB_extensions_string
+ WGLEW_ARB_extensions_string = _glewSearchExtension("WGL_ARB_extensions_string", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) WGLEW_ARB_extensions_string= !_glewInit_WGL_ARB_extensions_string();
+#endif /* WGL_ARB_extensions_string */
+#ifdef WGL_ARB_framebuffer_sRGB
+ WGLEW_ARB_framebuffer_sRGB = _glewSearchExtension("WGL_ARB_framebuffer_sRGB", extStart, extEnd);
+#endif /* WGL_ARB_framebuffer_sRGB */
+#ifdef WGL_ARB_make_current_read
+ WGLEW_ARB_make_current_read = _glewSearchExtension("WGL_ARB_make_current_read", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) WGLEW_ARB_make_current_read= !_glewInit_WGL_ARB_make_current_read();
+#endif /* WGL_ARB_make_current_read */
+#ifdef WGL_ARB_multisample
+ WGLEW_ARB_multisample = _glewSearchExtension("WGL_ARB_multisample", extStart, extEnd);
+#endif /* WGL_ARB_multisample */
+#ifdef WGL_ARB_pbuffer
+ WGLEW_ARB_pbuffer = _glewSearchExtension("WGL_ARB_pbuffer", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) WGLEW_ARB_pbuffer= !_glewInit_WGL_ARB_pbuffer();
+#endif /* WGL_ARB_pbuffer */
+#ifdef WGL_ARB_pixel_format
+ WGLEW_ARB_pixel_format = _glewSearchExtension("WGL_ARB_pixel_format", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) WGLEW_ARB_pixel_format= !_glewInit_WGL_ARB_pixel_format();
+#endif /* WGL_ARB_pixel_format */
+#ifdef WGL_ARB_pixel_format_float
+ WGLEW_ARB_pixel_format_float = _glewSearchExtension("WGL_ARB_pixel_format_float", extStart, extEnd);
+#endif /* WGL_ARB_pixel_format_float */
+#ifdef WGL_ARB_render_texture
+ WGLEW_ARB_render_texture = _glewSearchExtension("WGL_ARB_render_texture", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_render_texture|| crippled) WGLEW_ARB_render_texture= !_glewInit_WGL_ARB_render_texture();
+#endif /* WGL_ARB_render_texture */
+#ifdef WGL_ARB_robustness_application_isolation
+ WGLEW_ARB_robustness_application_isolation = _glewSearchExtension("WGL_ARB_robustness_application_isolation", extStart, extEnd);
+#endif /* WGL_ARB_robustness_application_isolation */
+#ifdef WGL_ARB_robustness_share_group_isolation
+ WGLEW_ARB_robustness_share_group_isolation = _glewSearchExtension("WGL_ARB_robustness_share_group_isolation", extStart, extEnd);
+#endif /* WGL_ARB_robustness_share_group_isolation */
+#ifdef WGL_ATI_pixel_format_float
+ WGLEW_ATI_pixel_format_float = _glewSearchExtension("WGL_ATI_pixel_format_float", extStart, extEnd);
+#endif /* WGL_ATI_pixel_format_float */
+#ifdef WGL_ATI_render_texture_rectangle
+ WGLEW_ATI_render_texture_rectangle = _glewSearchExtension("WGL_ATI_render_texture_rectangle", extStart, extEnd);
+#endif /* WGL_ATI_render_texture_rectangle */
+#ifdef WGL_EXT_colorspace
+ WGLEW_EXT_colorspace = _glewSearchExtension("WGL_EXT_colorspace", extStart, extEnd);
+#endif /* WGL_EXT_colorspace */
+#ifdef WGL_EXT_create_context_es2_profile
+ WGLEW_EXT_create_context_es2_profile = _glewSearchExtension("WGL_EXT_create_context_es2_profile", extStart, extEnd);
+#endif /* WGL_EXT_create_context_es2_profile */
+#ifdef WGL_EXT_create_context_es_profile
+ WGLEW_EXT_create_context_es_profile = _glewSearchExtension("WGL_EXT_create_context_es_profile", extStart, extEnd);
+#endif /* WGL_EXT_create_context_es_profile */
+#ifdef WGL_EXT_depth_float
+ WGLEW_EXT_depth_float = _glewSearchExtension("WGL_EXT_depth_float", extStart, extEnd);
+#endif /* WGL_EXT_depth_float */
+#ifdef WGL_EXT_display_color_table
+ WGLEW_EXT_display_color_table = _glewSearchExtension("WGL_EXT_display_color_table", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) WGLEW_EXT_display_color_table= !_glewInit_WGL_EXT_display_color_table();
+#endif /* WGL_EXT_display_color_table */
+#ifdef WGL_EXT_extensions_string
+ WGLEW_EXT_extensions_string = _glewSearchExtension("WGL_EXT_extensions_string", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) WGLEW_EXT_extensions_string= !_glewInit_WGL_EXT_extensions_string();
+#endif /* WGL_EXT_extensions_string */
+#ifdef WGL_EXT_framebuffer_sRGB
+ WGLEW_EXT_framebuffer_sRGB = _glewSearchExtension("WGL_EXT_framebuffer_sRGB", extStart, extEnd);
+#endif /* WGL_EXT_framebuffer_sRGB */
+#ifdef WGL_EXT_make_current_read
+ WGLEW_EXT_make_current_read = _glewSearchExtension("WGL_EXT_make_current_read", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) WGLEW_EXT_make_current_read= !_glewInit_WGL_EXT_make_current_read();
+#endif /* WGL_EXT_make_current_read */
+#ifdef WGL_EXT_multisample
+ WGLEW_EXT_multisample = _glewSearchExtension("WGL_EXT_multisample", extStart, extEnd);
+#endif /* WGL_EXT_multisample */
+#ifdef WGL_EXT_pbuffer
+ WGLEW_EXT_pbuffer = _glewSearchExtension("WGL_EXT_pbuffer", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) WGLEW_EXT_pbuffer= !_glewInit_WGL_EXT_pbuffer();
+#endif /* WGL_EXT_pbuffer */
+#ifdef WGL_EXT_pixel_format
+ WGLEW_EXT_pixel_format = _glewSearchExtension("WGL_EXT_pixel_format", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) WGLEW_EXT_pixel_format= !_glewInit_WGL_EXT_pixel_format();
+#endif /* WGL_EXT_pixel_format */
+#ifdef WGL_EXT_pixel_format_packed_float
+ WGLEW_EXT_pixel_format_packed_float = _glewSearchExtension("WGL_EXT_pixel_format_packed_float", extStart, extEnd);
+#endif /* WGL_EXT_pixel_format_packed_float */
+#ifdef WGL_EXT_swap_control
+ WGLEW_EXT_swap_control = _glewSearchExtension("WGL_EXT_swap_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_swap_control|| crippled) WGLEW_EXT_swap_control= !_glewInit_WGL_EXT_swap_control();
+#endif /* WGL_EXT_swap_control */
+#ifdef WGL_EXT_swap_control_tear
+ WGLEW_EXT_swap_control_tear = _glewSearchExtension("WGL_EXT_swap_control_tear", extStart, extEnd);
+#endif /* WGL_EXT_swap_control_tear */
+#ifdef WGL_I3D_digital_video_control
+ WGLEW_I3D_digital_video_control = _glewSearchExtension("WGL_I3D_digital_video_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) WGLEW_I3D_digital_video_control= !_glewInit_WGL_I3D_digital_video_control();
+#endif /* WGL_I3D_digital_video_control */
+#ifdef WGL_I3D_gamma
+ WGLEW_I3D_gamma = _glewSearchExtension("WGL_I3D_gamma", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_gamma|| crippled) WGLEW_I3D_gamma= !_glewInit_WGL_I3D_gamma();
+#endif /* WGL_I3D_gamma */
+#ifdef WGL_I3D_genlock
+ WGLEW_I3D_genlock = _glewSearchExtension("WGL_I3D_genlock", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_genlock|| crippled) WGLEW_I3D_genlock= !_glewInit_WGL_I3D_genlock();
+#endif /* WGL_I3D_genlock */
+#ifdef WGL_I3D_image_buffer
+ WGLEW_I3D_image_buffer = _glewSearchExtension("WGL_I3D_image_buffer", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) WGLEW_I3D_image_buffer= !_glewInit_WGL_I3D_image_buffer();
+#endif /* WGL_I3D_image_buffer */
+#ifdef WGL_I3D_swap_frame_lock
+ WGLEW_I3D_swap_frame_lock = _glewSearchExtension("WGL_I3D_swap_frame_lock", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) WGLEW_I3D_swap_frame_lock= !_glewInit_WGL_I3D_swap_frame_lock();
+#endif /* WGL_I3D_swap_frame_lock */
+#ifdef WGL_I3D_swap_frame_usage
+ WGLEW_I3D_swap_frame_usage = _glewSearchExtension("WGL_I3D_swap_frame_usage", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) WGLEW_I3D_swap_frame_usage= !_glewInit_WGL_I3D_swap_frame_usage();
+#endif /* WGL_I3D_swap_frame_usage */
+#ifdef WGL_NV_DX_interop
+ WGLEW_NV_DX_interop = _glewSearchExtension("WGL_NV_DX_interop", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_DX_interop|| crippled) WGLEW_NV_DX_interop= !_glewInit_WGL_NV_DX_interop();
+#endif /* WGL_NV_DX_interop */
+#ifdef WGL_NV_DX_interop2
+ WGLEW_NV_DX_interop2 = _glewSearchExtension("WGL_NV_DX_interop2", extStart, extEnd);
+#endif /* WGL_NV_DX_interop2 */
+#ifdef WGL_NV_copy_image
+ WGLEW_NV_copy_image = _glewSearchExtension("WGL_NV_copy_image", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_copy_image|| crippled) WGLEW_NV_copy_image= !_glewInit_WGL_NV_copy_image();
+#endif /* WGL_NV_copy_image */
+#ifdef WGL_NV_delay_before_swap
+ WGLEW_NV_delay_before_swap = _glewSearchExtension("WGL_NV_delay_before_swap", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_delay_before_swap|| crippled) WGLEW_NV_delay_before_swap= !_glewInit_WGL_NV_delay_before_swap();
+#endif /* WGL_NV_delay_before_swap */
+#ifdef WGL_NV_float_buffer
+ WGLEW_NV_float_buffer = _glewSearchExtension("WGL_NV_float_buffer", extStart, extEnd);
+#endif /* WGL_NV_float_buffer */
+#ifdef WGL_NV_gpu_affinity
+ WGLEW_NV_gpu_affinity = _glewSearchExtension("WGL_NV_gpu_affinity", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) WGLEW_NV_gpu_affinity= !_glewInit_WGL_NV_gpu_affinity();
+#endif /* WGL_NV_gpu_affinity */
+#ifdef WGL_NV_multisample_coverage
+ WGLEW_NV_multisample_coverage = _glewSearchExtension("WGL_NV_multisample_coverage", extStart, extEnd);
+#endif /* WGL_NV_multisample_coverage */
+#ifdef WGL_NV_present_video
+ WGLEW_NV_present_video = _glewSearchExtension("WGL_NV_present_video", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_present_video|| crippled) WGLEW_NV_present_video= !_glewInit_WGL_NV_present_video();
+#endif /* WGL_NV_present_video */
+#ifdef WGL_NV_render_depth_texture
+ WGLEW_NV_render_depth_texture = _glewSearchExtension("WGL_NV_render_depth_texture", extStart, extEnd);
+#endif /* WGL_NV_render_depth_texture */
+#ifdef WGL_NV_render_texture_rectangle
+ WGLEW_NV_render_texture_rectangle = _glewSearchExtension("WGL_NV_render_texture_rectangle", extStart, extEnd);
+#endif /* WGL_NV_render_texture_rectangle */
+#ifdef WGL_NV_swap_group
+ WGLEW_NV_swap_group = _glewSearchExtension("WGL_NV_swap_group", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_swap_group|| crippled) WGLEW_NV_swap_group= !_glewInit_WGL_NV_swap_group();
+#endif /* WGL_NV_swap_group */
+#ifdef WGL_NV_vertex_array_range
+ WGLEW_NV_vertex_array_range = _glewSearchExtension("WGL_NV_vertex_array_range", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) WGLEW_NV_vertex_array_range= !_glewInit_WGL_NV_vertex_array_range();
+#endif /* WGL_NV_vertex_array_range */
+#ifdef WGL_NV_video_capture
+ WGLEW_NV_video_capture = _glewSearchExtension("WGL_NV_video_capture", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_video_capture|| crippled) WGLEW_NV_video_capture= !_glewInit_WGL_NV_video_capture();
+#endif /* WGL_NV_video_capture */
+#ifdef WGL_NV_video_output
+ WGLEW_NV_video_output = _glewSearchExtension("WGL_NV_video_output", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_video_output|| crippled) WGLEW_NV_video_output= !_glewInit_WGL_NV_video_output();
+#endif /* WGL_NV_video_output */
+#ifdef WGL_OML_sync_control
+ WGLEW_OML_sync_control = _glewSearchExtension("WGL_OML_sync_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_OML_sync_control|| crippled) WGLEW_OML_sync_control= !_glewInit_WGL_OML_sync_control();
+#endif /* WGL_OML_sync_control */
+
+ return GLEW_OK;
+}
+
+#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX))
+
+PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay = NULL;
+
+PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig = NULL;
+PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext = NULL;
+PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer = NULL;
+PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap = NULL;
+PFNGLXCREATEWINDOWPROC __glewXCreateWindow = NULL;
+PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer = NULL;
+PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap = NULL;
+PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow = NULL;
+PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable = NULL;
+PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib = NULL;
+PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs = NULL;
+PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent = NULL;
+PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig = NULL;
+PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent = NULL;
+PFNGLXQUERYCONTEXTPROC __glewXQueryContext = NULL;
+PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable = NULL;
+PFNGLXSELECTEVENTPROC __glewXSelectEvent = NULL;
+
+PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD = NULL;
+PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD = NULL;
+PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD = NULL;
+PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD = NULL;
+PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD = NULL;
+PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD = NULL;
+PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD = NULL;
+PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD = NULL;
+PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD = NULL;
+
+PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB = NULL;
+
+PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI = NULL;
+PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI = NULL;
+PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI = NULL;
+
+PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT = NULL;
+PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT = NULL;
+PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT = NULL;
+PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT = NULL;
+
+PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT = NULL;
+
+PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT = NULL;
+PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT = NULL;
+
+PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA = NULL;
+
+PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA = NULL;
+
+PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA = NULL;
+
+PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC __glewXQueryCurrentRendererIntegerMESA = NULL;
+PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC __glewXQueryCurrentRendererStringMESA = NULL;
+PFNGLXQUERYRENDERERINTEGERMESAPROC __glewXQueryRendererIntegerMESA = NULL;
+PFNGLXQUERYRENDERERSTRINGMESAPROC __glewXQueryRendererStringMESA = NULL;
+
+PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA = NULL;
+
+PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL;
+
+PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA = NULL;
+PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA = NULL;
+
+PFNGLXCOPYBUFFERSUBDATANVPROC __glewXCopyBufferSubDataNV = NULL;
+PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC __glewXNamedCopyBufferSubDataNV = NULL;
+
+PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV = NULL;
+
+PFNGLXDELAYBEFORESWAPNVPROC __glewXDelayBeforeSwapNV = NULL;
+
+PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV = NULL;
+PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV = NULL;
+
+PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV = NULL;
+PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV = NULL;
+PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV = NULL;
+PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV = NULL;
+PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV = NULL;
+PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV = NULL;
+
+PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV = NULL;
+PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV = NULL;
+
+PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV = NULL;
+PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV = NULL;
+PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV = NULL;
+PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV = NULL;
+PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV = NULL;
+
+PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV = NULL;
+PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV = NULL;
+PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV = NULL;
+PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV = NULL;
+PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV = NULL;
+PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV = NULL;
+
+PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML = NULL;
+PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML = NULL;
+PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML = NULL;
+PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML = NULL;
+PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML = NULL;
+
+PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX = NULL;
+PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX = NULL;
+PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX = NULL;
+PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX = NULL;
+PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX = NULL;
+PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX = NULL;
+
+PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX = NULL;
+PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX = NULL;
+PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX = NULL;
+PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX = NULL;
+PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX = NULL;
+PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX = NULL;
+PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX = NULL;
+PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX = NULL;
+
+PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX = NULL;
+PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX = NULL;
+PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX = NULL;
+PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX = NULL;
+PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX = NULL;
+
+PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX = NULL;
+PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX = NULL;
+
+PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX = NULL;
+
+PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX = NULL;
+PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX = NULL;
+PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX = NULL;
+PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX = NULL;
+PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX = NULL;
+
+PFNGLXCUSHIONSGIPROC __glewXCushionSGI = NULL;
+
+PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI = NULL;
+PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI = NULL;
+
+PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI = NULL;
+
+PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI = NULL;
+PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI = NULL;
+
+PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN = NULL;
+
+PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN = NULL;
+PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN = NULL;
+
+GLboolean __GLXEW_VERSION_1_0 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_1 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_2 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_3 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_4 = GL_FALSE;
+GLboolean __GLXEW_3DFX_multisample = GL_FALSE;
+GLboolean __GLXEW_AMD_gpu_association = GL_FALSE;
+GLboolean __GLXEW_ARB_context_flush_control = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context_no_error = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context_profile = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context_robustness = GL_FALSE;
+GLboolean __GLXEW_ARB_fbconfig_float = GL_FALSE;
+GLboolean __GLXEW_ARB_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLXEW_ARB_get_proc_address = GL_FALSE;
+GLboolean __GLXEW_ARB_multisample = GL_FALSE;
+GLboolean __GLXEW_ARB_robustness_application_isolation = GL_FALSE;
+GLboolean __GLXEW_ARB_robustness_share_group_isolation = GL_FALSE;
+GLboolean __GLXEW_ARB_vertex_buffer_object = GL_FALSE;
+GLboolean __GLXEW_ATI_pixel_format_float = GL_FALSE;
+GLboolean __GLXEW_ATI_render_texture = GL_FALSE;
+GLboolean __GLXEW_EXT_buffer_age = GL_FALSE;
+GLboolean __GLXEW_EXT_create_context_es2_profile = GL_FALSE;
+GLboolean __GLXEW_EXT_create_context_es_profile = GL_FALSE;
+GLboolean __GLXEW_EXT_fbconfig_packed_float = GL_FALSE;
+GLboolean __GLXEW_EXT_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLXEW_EXT_import_context = GL_FALSE;
+GLboolean __GLXEW_EXT_libglvnd = GL_FALSE;
+GLboolean __GLXEW_EXT_scene_marker = GL_FALSE;
+GLboolean __GLXEW_EXT_stereo_tree = GL_FALSE;
+GLboolean __GLXEW_EXT_swap_control = GL_FALSE;
+GLboolean __GLXEW_EXT_swap_control_tear = GL_FALSE;
+GLboolean __GLXEW_EXT_texture_from_pixmap = GL_FALSE;
+GLboolean __GLXEW_EXT_visual_info = GL_FALSE;
+GLboolean __GLXEW_EXT_visual_rating = GL_FALSE;
+GLboolean __GLXEW_INTEL_swap_event = GL_FALSE;
+GLboolean __GLXEW_MESA_agp_offset = GL_FALSE;
+GLboolean __GLXEW_MESA_copy_sub_buffer = GL_FALSE;
+GLboolean __GLXEW_MESA_pixmap_colormap = GL_FALSE;
+GLboolean __GLXEW_MESA_query_renderer = GL_FALSE;
+GLboolean __GLXEW_MESA_release_buffers = GL_FALSE;
+GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE;
+GLboolean __GLXEW_MESA_swap_control = GL_FALSE;
+GLboolean __GLXEW_NV_copy_buffer = GL_FALSE;
+GLboolean __GLXEW_NV_copy_image = GL_FALSE;
+GLboolean __GLXEW_NV_delay_before_swap = GL_FALSE;
+GLboolean __GLXEW_NV_float_buffer = GL_FALSE;
+GLboolean __GLXEW_NV_multisample_coverage = GL_FALSE;
+GLboolean __GLXEW_NV_present_video = GL_FALSE;
+GLboolean __GLXEW_NV_robustness_video_memory_purge = GL_FALSE;
+GLboolean __GLXEW_NV_swap_group = GL_FALSE;
+GLboolean __GLXEW_NV_vertex_array_range = GL_FALSE;
+GLboolean __GLXEW_NV_video_capture = GL_FALSE;
+GLboolean __GLXEW_NV_video_out = GL_FALSE;
+GLboolean __GLXEW_OML_swap_method = GL_FALSE;
+GLboolean __GLXEW_OML_sync_control = GL_FALSE;
+GLboolean __GLXEW_SGIS_blended_overlay = GL_FALSE;
+GLboolean __GLXEW_SGIS_color_range = GL_FALSE;
+GLboolean __GLXEW_SGIS_multisample = GL_FALSE;
+GLboolean __GLXEW_SGIS_shared_multisample = GL_FALSE;
+GLboolean __GLXEW_SGIX_fbconfig = GL_FALSE;
+GLboolean __GLXEW_SGIX_hyperpipe = GL_FALSE;
+GLboolean __GLXEW_SGIX_pbuffer = GL_FALSE;
+GLboolean __GLXEW_SGIX_swap_barrier = GL_FALSE;
+GLboolean __GLXEW_SGIX_swap_group = GL_FALSE;
+GLboolean __GLXEW_SGIX_video_resize = GL_FALSE;
+GLboolean __GLXEW_SGIX_visual_select_group = GL_FALSE;
+GLboolean __GLXEW_SGI_cushion = GL_FALSE;
+GLboolean __GLXEW_SGI_make_current_read = GL_FALSE;
+GLboolean __GLXEW_SGI_swap_control = GL_FALSE;
+GLboolean __GLXEW_SGI_video_sync = GL_FALSE;
+GLboolean __GLXEW_SUN_get_transparent_index = GL_FALSE;
+GLboolean __GLXEW_SUN_video_resize = GL_FALSE;
+#ifdef GLX_VERSION_1_2
+
+static GLboolean _glewInit_GLX_VERSION_1_2 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentDisplay")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_VERSION_1_2 */
+
+#ifdef GLX_VERSION_1_3
+
+static GLboolean _glewInit_GLX_VERSION_1_3 ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfig")) == NULL) || r;
+ r = ((glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXCreateNewContext")) == NULL) || r;
+ r = ((glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXCreatePbuffer")) == NULL) || r;
+ r = ((glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXCreatePixmap")) == NULL) || r;
+ r = ((glXCreateWindow = (PFNGLXCREATEWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXCreateWindow")) == NULL) || r;
+ r = ((glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPbuffer")) == NULL) || r;
+ r = ((glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPixmap")) == NULL) || r;
+ r = ((glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXDestroyWindow")) == NULL) || r;
+ r = ((glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawable")) == NULL) || r;
+ r = ((glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttrib")) == NULL) || r;
+ r = ((glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigs")) == NULL) || r;
+ r = ((glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEvent")) == NULL) || r;
+ r = ((glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")) == NULL) || r;
+ r = ((glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC)glewGetProcAddress((const GLubyte*)"glXMakeContextCurrent")) == NULL) || r;
+ r = ((glXQueryContext = (PFNGLXQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContext")) == NULL) || r;
+ r = ((glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXQueryDrawable")) == NULL) || r;
+ r = ((glXSelectEvent = (PFNGLXSELECTEVENTPROC)glewGetProcAddress((const GLubyte*)"glXSelectEvent")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_VERSION_1_3 */
+
+#ifdef GLX_AMD_gpu_association
+
+static GLboolean _glewInit_GLX_AMD_gpu_association ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBlitContextFramebufferAMD = (PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC)glewGetProcAddress((const GLubyte*)"glXBlitContextFramebufferAMD")) == NULL) || r;
+ r = ((glXCreateAssociatedContextAMD = (PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXCreateAssociatedContextAMD")) == NULL) || r;
+ r = ((glXCreateAssociatedContextAttribsAMD = (PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)glewGetProcAddress((const GLubyte*)"glXCreateAssociatedContextAttribsAMD")) == NULL) || r;
+ r = ((glXDeleteAssociatedContextAMD = (PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXDeleteAssociatedContextAMD")) == NULL) || r;
+ r = ((glXGetContextGPUIDAMD = (PFNGLXGETCONTEXTGPUIDAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetContextGPUIDAMD")) == NULL) || r;
+ r = ((glXGetCurrentAssociatedContextAMD = (PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentAssociatedContextAMD")) == NULL) || r;
+ r = ((glXGetGPUIDsAMD = (PFNGLXGETGPUIDSAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetGPUIDsAMD")) == NULL) || r;
+ r = ((glXGetGPUInfoAMD = (PFNGLXGETGPUINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetGPUInfoAMD")) == NULL) || r;
+ r = ((glXMakeAssociatedContextCurrentAMD = (PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)glewGetProcAddress((const GLubyte*)"glXMakeAssociatedContextCurrentAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_AMD_gpu_association */
+
+#ifdef GLX_ARB_create_context
+
+static GLboolean _glewInit_GLX_ARB_create_context ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_ARB_create_context */
+
+#ifdef GLX_ATI_render_texture
+
+static GLboolean _glewInit_GLX_ATI_render_texture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindTexImageATI = (PFNGLXBINDTEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageATI")) == NULL) || r;
+ r = ((glXDrawableAttribATI = (PFNGLXDRAWABLEATTRIBATIPROC)glewGetProcAddress((const GLubyte*)"glXDrawableAttribATI")) == NULL) || r;
+ r = ((glXReleaseTexImageATI = (PFNGLXRELEASETEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_ATI_render_texture */
+
+#ifdef GLX_EXT_import_context
+
+static GLboolean _glewInit_GLX_EXT_import_context ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXFreeContextEXT")) == NULL) || r;
+ r = ((glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC)glewGetProcAddress((const GLubyte*)"glXGetContextIDEXT")) == NULL) || r;
+ r = ((glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXImportContextEXT")) == NULL) || r;
+ r = ((glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContextInfoEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_EXT_import_context */
+
+#ifdef GLX_EXT_swap_control
+
+static GLboolean _glewInit_GLX_EXT_swap_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_EXT_swap_control */
+
+#ifdef GLX_EXT_texture_from_pixmap
+
+static GLboolean _glewInit_GLX_EXT_texture_from_pixmap ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageEXT")) == NULL) || r;
+ r = ((glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_EXT_texture_from_pixmap */
+
+#ifdef GLX_MESA_agp_offset
+
+static GLboolean _glewInit_GLX_MESA_agp_offset ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetAGPOffsetMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_agp_offset */
+
+#ifdef GLX_MESA_copy_sub_buffer
+
+static GLboolean _glewInit_GLX_MESA_copy_sub_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)glewGetProcAddress((const GLubyte*)"glXCopySubBufferMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_copy_sub_buffer */
+
+#ifdef GLX_MESA_pixmap_colormap
+
+static GLboolean _glewInit_GLX_MESA_pixmap_colormap ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_pixmap_colormap */
+
+#ifdef GLX_MESA_query_renderer
+
+static GLboolean _glewInit_GLX_MESA_query_renderer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXQueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryCurrentRendererIntegerMESA")) == NULL) || r;
+ r = ((glXQueryCurrentRendererStringMESA = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryCurrentRendererStringMESA")) == NULL) || r;
+ r = ((glXQueryRendererIntegerMESA = (PFNGLXQUERYRENDERERINTEGERMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryRendererIntegerMESA")) == NULL) || r;
+ r = ((glXQueryRendererStringMESA = (PFNGLXQUERYRENDERERSTRINGMESAPROC)glewGetProcAddress((const GLubyte*)"glXQueryRendererStringMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_query_renderer */
+
+#ifdef GLX_MESA_release_buffers
+
+static GLboolean _glewInit_GLX_MESA_release_buffers ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glXReleaseBuffersMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_release_buffers */
+
+#ifdef GLX_MESA_set_3dfx_mode
+
+static GLboolean _glewInit_GLX_MESA_set_3dfx_mode ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC)glewGetProcAddress((const GLubyte*)"glXSet3DfxModeMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_set_3dfx_mode */
+
+#ifdef GLX_MESA_swap_control
+
+static GLboolean _glewInit_GLX_MESA_swap_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetSwapIntervalMESA")) == NULL) || r;
+ r = ((glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_swap_control */
+
+#ifdef GLX_NV_copy_buffer
+
+static GLboolean _glewInit_GLX_NV_copy_buffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCopyBufferSubDataNV = (PFNGLXCOPYBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glXCopyBufferSubDataNV")) == NULL) || r;
+ r = ((glXNamedCopyBufferSubDataNV = (PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glXNamedCopyBufferSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_copy_buffer */
+
+#ifdef GLX_NV_copy_image
+
+static GLboolean _glewInit_GLX_NV_copy_image ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCopyImageSubDataNV = (PFNGLXCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glXCopyImageSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_copy_image */
+
+#ifdef GLX_NV_delay_before_swap
+
+static GLboolean _glewInit_GLX_NV_delay_before_swap ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXDelayBeforeSwapNV = (PFNGLXDELAYBEFORESWAPNVPROC)glewGetProcAddress((const GLubyte*)"glXDelayBeforeSwapNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_delay_before_swap */
+
+#ifdef GLX_NV_present_video
+
+static GLboolean _glewInit_GLX_NV_present_video ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindVideoDeviceNV = (PFNGLXBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoDeviceNV")) == NULL) || r;
+ r = ((glXEnumerateVideoDevicesNV = (PFNGLXENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoDevicesNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_present_video */
+
+#ifdef GLX_NV_swap_group
+
+static GLboolean _glewInit_GLX_NV_swap_group ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierNV")) == NULL) || r;
+ r = ((glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupNV")) == NULL) || r;
+ r = ((glXQueryFrameCountNV = (PFNGLXQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryFrameCountNV")) == NULL) || r;
+ r = ((glXQueryMaxSwapGroupsNV = (PFNGLXQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapGroupsNV")) == NULL) || r;
+ r = ((glXQuerySwapGroupNV = (PFNGLXQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXQuerySwapGroupNV")) == NULL) || r;
+ r = ((glXResetFrameCountNV = (PFNGLXRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXResetFrameCountNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_swap_group */
+
+#ifdef GLX_NV_vertex_array_range
+
+static GLboolean _glewInit_GLX_NV_vertex_array_range ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXAllocateMemoryNV = (PFNGLXALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXAllocateMemoryNV")) == NULL) || r;
+ r = ((glXFreeMemoryNV = (PFNGLXFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXFreeMemoryNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_vertex_array_range */
+
+#ifdef GLX_NV_video_capture
+
+static GLboolean _glewInit_GLX_NV_video_capture ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindVideoCaptureDeviceNV = (PFNGLXBINDVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((glXEnumerateVideoCaptureDevicesNV = (PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoCaptureDevicesNV")) == NULL) || r;
+ r = ((glXLockVideoCaptureDeviceNV = (PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXLockVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((glXQueryVideoCaptureDeviceNV = (PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXQueryVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((glXReleaseVideoCaptureDeviceNV = (PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoCaptureDeviceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_video_capture */
+
+#ifdef GLX_NV_video_out
+
+static GLboolean _glewInit_GLX_NV_video_out ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindVideoImageNV = (PFNGLXBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoImageNV")) == NULL) || r;
+ r = ((glXGetVideoDeviceNV = (PFNGLXGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoDeviceNV")) == NULL) || r;
+ r = ((glXGetVideoInfoNV = (PFNGLXGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoInfoNV")) == NULL) || r;
+ r = ((glXReleaseVideoDeviceNV = (PFNGLXRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoDeviceNV")) == NULL) || r;
+ r = ((glXReleaseVideoImageNV = (PFNGLXRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoImageNV")) == NULL) || r;
+ r = ((glXSendPbufferToVideoNV = (PFNGLXSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"glXSendPbufferToVideoNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_video_out */
+
+#ifdef GLX_OML_sync_control
+
+static GLboolean _glewInit_GLX_OML_sync_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetMscRateOML")) == NULL) || r;
+ r = ((glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetSyncValuesOML")) == NULL) || r;
+ r = ((glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXSwapBuffersMscOML")) == NULL) || r;
+ r = ((glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForMscOML")) == NULL) || r;
+ r = ((glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForSbcOML")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_OML_sync_control */
+
+#ifdef GLX_SGIX_fbconfig
+
+static GLboolean _glewInit_GLX_SGIX_fbconfig ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfigSGIX")) == NULL) || r;
+ r = ((glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextWithConfigSGIX")) == NULL) || r;
+ r = ((glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapWithConfigSGIX")) == NULL) || r;
+ r = ((glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttribSGIX")) == NULL) || r;
+ r = ((glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigFromVisualSGIX")) == NULL) || r;
+ r = ((glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfigSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_fbconfig */
+
+#ifdef GLX_SGIX_hyperpipe
+
+static GLboolean _glewInit_GLX_SGIX_hyperpipe ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindHyperpipeSGIX = (PFNGLXBINDHYPERPIPESGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindHyperpipeSGIX")) == NULL) || r;
+ r = ((glXDestroyHyperpipeConfigSGIX = (PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyHyperpipeConfigSGIX")) == NULL) || r;
+ r = ((glXHyperpipeAttribSGIX = (PFNGLXHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeAttribSGIX")) == NULL) || r;
+ r = ((glXHyperpipeConfigSGIX = (PFNGLXHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeConfigSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeAttribSGIX = (PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeAttribSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeBestAttribSGIX = (PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeBestAttribSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeConfigSGIX = (PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeConfigSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeNetworkSGIX = (PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeNetworkSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_hyperpipe */
+
+#ifdef GLX_SGIX_pbuffer
+
+static GLboolean _glewInit_GLX_SGIX_pbuffer ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPbufferSGIX")) == NULL) || r;
+ r = ((glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyGLXPbufferSGIX")) == NULL) || r;
+ r = ((glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEventSGIX")) == NULL) || r;
+ r = ((glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryGLXPbufferSGIX")) == NULL) || r;
+ r = ((glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXSelectEventSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_pbuffer */
+
+#ifdef GLX_SGIX_swap_barrier
+
+static GLboolean _glewInit_GLX_SGIX_swap_barrier ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierSGIX")) == NULL) || r;
+ r = ((glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapBarriersSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_swap_barrier */
+
+#ifdef GLX_SGIX_swap_group
+
+static GLboolean _glewInit_GLX_SGIX_swap_group ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_swap_group */
+
+#ifdef GLX_SGIX_video_resize
+
+static GLboolean _glewInit_GLX_SGIX_video_resize ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindChannelToWindowSGIX")) == NULL) || r;
+ r = ((glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSGIX")) == NULL) || r;
+ r = ((glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSyncSGIX")) == NULL) || r;
+ r = ((glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelDeltasSGIX")) == NULL) || r;
+ r = ((glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelRectSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_video_resize */
+
+#ifdef GLX_SGI_cushion
+
+static GLboolean _glewInit_GLX_SGI_cushion ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCushionSGI = (PFNGLXCUSHIONSGIPROC)glewGetProcAddress((const GLubyte*)"glXCushionSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_cushion */
+
+#ifdef GLX_SGI_make_current_read
+
+static GLboolean _glewInit_GLX_SGI_make_current_read ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawableSGI")) == NULL) || r;
+ r = ((glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC)glewGetProcAddress((const GLubyte*)"glXMakeCurrentReadSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_make_current_read */
+
+#ifdef GLX_SGI_swap_control
+
+static GLboolean _glewInit_GLX_SGI_swap_control ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_swap_control */
+
+#ifdef GLX_SGI_video_sync
+
+static GLboolean _glewInit_GLX_SGI_video_sync ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI")) == NULL) || r;
+ r = ((glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_video_sync */
+
+#ifdef GLX_SUN_get_transparent_index
+
+static GLboolean _glewInit_GLX_SUN_get_transparent_index ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC)glewGetProcAddress((const GLubyte*)"glXGetTransparentIndexSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SUN_get_transparent_index */
+
+#ifdef GLX_SUN_video_resize
+
+static GLboolean _glewInit_GLX_SUN_video_resize ()
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetVideoResizeSUN = (PFNGLXGETVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoResizeSUN")) == NULL) || r;
+ r = ((glXVideoResizeSUN = (PFNGLXVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXVideoResizeSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SUN_video_resize */
+
+/* ------------------------------------------------------------------------ */
+
+GLboolean glxewGetExtension (const char* name)
+{
+ const GLubyte* start;
+ const GLubyte* end;
+
+ if (glXGetCurrentDisplay == NULL) return GL_FALSE;
+ start = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS);
+ if (0 == start) return GL_FALSE;
+ end = start + _glewStrLen(start);
+ return _glewSearchExtension(name, start, end);
+}
+
+GLenum glxewInit ()
+{
+ Display* display;
+ int major, minor;
+ const GLubyte* extStart;
+ const GLubyte* extEnd;
+ /* initialize core GLX 1.2 */
+ if (_glewInit_GLX_VERSION_1_2()) return GLEW_ERROR_GLX_VERSION_11_ONLY;
+ /* check for a display */
+ display = glXGetCurrentDisplay();
+ if (display == NULL) return GLEW_ERROR_NO_GLX_DISPLAY;
+ /* initialize flags */
+ GLXEW_VERSION_1_0 = GL_TRUE;
+ GLXEW_VERSION_1_1 = GL_TRUE;
+ GLXEW_VERSION_1_2 = GL_TRUE;
+ GLXEW_VERSION_1_3 = GL_TRUE;
+ GLXEW_VERSION_1_4 = GL_TRUE;
+ /* query GLX version */
+ glXQueryVersion(display, &major, &minor);
+ if (major == 1 && minor <= 3)
+ {
+ switch (minor)
+ {
+ case 3:
+ GLXEW_VERSION_1_4 = GL_FALSE;
+ break;
+ case 2:
+ GLXEW_VERSION_1_4 = GL_FALSE;
+ GLXEW_VERSION_1_3 = GL_FALSE;
+ break;
+ default:
+ return GLEW_ERROR_GLX_VERSION_11_ONLY;
+ break;
+ }
+ }
+ /* query GLX extension string */
+ extStart = 0;
+ if (glXGetCurrentDisplay != NULL)
+ extStart = (const GLubyte*)glXGetClientString(display, GLX_EXTENSIONS);
+ if (extStart == 0)
+ extStart = (const GLubyte *)"";
+ extEnd = extStart + _glewStrLen(extStart);
+ /* initialize extensions */
+#ifdef GLX_VERSION_1_3
+ if (glewExperimental || GLXEW_VERSION_1_3) GLXEW_VERSION_1_3 = !_glewInit_GLX_VERSION_1_3();
+#endif /* GLX_VERSION_1_3 */
+#ifdef GLX_3DFX_multisample
+ GLXEW_3DFX_multisample = _glewSearchExtension("GLX_3DFX_multisample", extStart, extEnd);
+#endif /* GLX_3DFX_multisample */
+#ifdef GLX_AMD_gpu_association
+ GLXEW_AMD_gpu_association = _glewSearchExtension("GLX_AMD_gpu_association", extStart, extEnd);
+ if (glewExperimental || GLXEW_AMD_gpu_association) GLXEW_AMD_gpu_association = !_glewInit_GLX_AMD_gpu_association();
+#endif /* GLX_AMD_gpu_association */
+#ifdef GLX_ARB_context_flush_control
+ GLXEW_ARB_context_flush_control = _glewSearchExtension("GLX_ARB_context_flush_control", extStart, extEnd);
+#endif /* GLX_ARB_context_flush_control */
+#ifdef GLX_ARB_create_context
+ GLXEW_ARB_create_context = _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd);
+ if (glewExperimental || GLXEW_ARB_create_context) GLXEW_ARB_create_context = !_glewInit_GLX_ARB_create_context();
+#endif /* GLX_ARB_create_context */
+#ifdef GLX_ARB_create_context_no_error
+ GLXEW_ARB_create_context_no_error = _glewSearchExtension("GLX_ARB_create_context_no_error", extStart, extEnd);
+#endif /* GLX_ARB_create_context_no_error */
+#ifdef GLX_ARB_create_context_profile
+ GLXEW_ARB_create_context_profile = _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd);
+#endif /* GLX_ARB_create_context_profile */
+#ifdef GLX_ARB_create_context_robustness
+ GLXEW_ARB_create_context_robustness = _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd);
+#endif /* GLX_ARB_create_context_robustness */
+#ifdef GLX_ARB_fbconfig_float
+ GLXEW_ARB_fbconfig_float = _glewSearchExtension("GLX_ARB_fbconfig_float", extStart, extEnd);
+#endif /* GLX_ARB_fbconfig_float */
+#ifdef GLX_ARB_framebuffer_sRGB
+ GLXEW_ARB_framebuffer_sRGB = _glewSearchExtension("GLX_ARB_framebuffer_sRGB", extStart, extEnd);
+#endif /* GLX_ARB_framebuffer_sRGB */
+#ifdef GLX_ARB_get_proc_address
+ GLXEW_ARB_get_proc_address = _glewSearchExtension("GLX_ARB_get_proc_address", extStart, extEnd);
+#endif /* GLX_ARB_get_proc_address */
+#ifdef GLX_ARB_multisample
+ GLXEW_ARB_multisample = _glewSearchExtension("GLX_ARB_multisample", extStart, extEnd);
+#endif /* GLX_ARB_multisample */
+#ifdef GLX_ARB_robustness_application_isolation
+ GLXEW_ARB_robustness_application_isolation = _glewSearchExtension("GLX_ARB_robustness_application_isolation", extStart, extEnd);
+#endif /* GLX_ARB_robustness_application_isolation */
+#ifdef GLX_ARB_robustness_share_group_isolation
+ GLXEW_ARB_robustness_share_group_isolation = _glewSearchExtension("GLX_ARB_robustness_share_group_isolation", extStart, extEnd);
+#endif /* GLX_ARB_robustness_share_group_isolation */
+#ifdef GLX_ARB_vertex_buffer_object
+ GLXEW_ARB_vertex_buffer_object = _glewSearchExtension("GLX_ARB_vertex_buffer_object", extStart, extEnd);
+#endif /* GLX_ARB_vertex_buffer_object */
+#ifdef GLX_ATI_pixel_format_float
+ GLXEW_ATI_pixel_format_float = _glewSearchExtension("GLX_ATI_pixel_format_float", extStart, extEnd);
+#endif /* GLX_ATI_pixel_format_float */
+#ifdef GLX_ATI_render_texture
+ GLXEW_ATI_render_texture = _glewSearchExtension("GLX_ATI_render_texture", extStart, extEnd);
+ if (glewExperimental || GLXEW_ATI_render_texture) GLXEW_ATI_render_texture = !_glewInit_GLX_ATI_render_texture();
+#endif /* GLX_ATI_render_texture */
+#ifdef GLX_EXT_buffer_age
+ GLXEW_EXT_buffer_age = _glewSearchExtension("GLX_EXT_buffer_age", extStart, extEnd);
+#endif /* GLX_EXT_buffer_age */
+#ifdef GLX_EXT_create_context_es2_profile
+ GLXEW_EXT_create_context_es2_profile = _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd);
+#endif /* GLX_EXT_create_context_es2_profile */
+#ifdef GLX_EXT_create_context_es_profile
+ GLXEW_EXT_create_context_es_profile = _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd);
+#endif /* GLX_EXT_create_context_es_profile */
+#ifdef GLX_EXT_fbconfig_packed_float
+ GLXEW_EXT_fbconfig_packed_float = _glewSearchExtension("GLX_EXT_fbconfig_packed_float", extStart, extEnd);
+#endif /* GLX_EXT_fbconfig_packed_float */
+#ifdef GLX_EXT_framebuffer_sRGB
+ GLXEW_EXT_framebuffer_sRGB = _glewSearchExtension("GLX_EXT_framebuffer_sRGB", extStart, extEnd);
+#endif /* GLX_EXT_framebuffer_sRGB */
+#ifdef GLX_EXT_import_context
+ GLXEW_EXT_import_context = _glewSearchExtension("GLX_EXT_import_context", extStart, extEnd);
+ if (glewExperimental || GLXEW_EXT_import_context) GLXEW_EXT_import_context = !_glewInit_GLX_EXT_import_context();
+#endif /* GLX_EXT_import_context */
+#ifdef GLX_EXT_libglvnd
+ GLXEW_EXT_libglvnd = _glewSearchExtension("GLX_EXT_libglvnd", extStart, extEnd);
+#endif /* GLX_EXT_libglvnd */
+#ifdef GLX_EXT_scene_marker
+ GLXEW_EXT_scene_marker = _glewSearchExtension("GLX_EXT_scene_marker", extStart, extEnd);
+#endif /* GLX_EXT_scene_marker */
+#ifdef GLX_EXT_stereo_tree
+ GLXEW_EXT_stereo_tree = _glewSearchExtension("GLX_EXT_stereo_tree", extStart, extEnd);
+#endif /* GLX_EXT_stereo_tree */
+#ifdef GLX_EXT_swap_control
+ GLXEW_EXT_swap_control = _glewSearchExtension("GLX_EXT_swap_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_EXT_swap_control) GLXEW_EXT_swap_control = !_glewInit_GLX_EXT_swap_control();
+#endif /* GLX_EXT_swap_control */
+#ifdef GLX_EXT_swap_control_tear
+ GLXEW_EXT_swap_control_tear = _glewSearchExtension("GLX_EXT_swap_control_tear", extStart, extEnd);
+#endif /* GLX_EXT_swap_control_tear */
+#ifdef GLX_EXT_texture_from_pixmap
+ GLXEW_EXT_texture_from_pixmap = _glewSearchExtension("GLX_EXT_texture_from_pixmap", extStart, extEnd);
+ if (glewExperimental || GLXEW_EXT_texture_from_pixmap) GLXEW_EXT_texture_from_pixmap = !_glewInit_GLX_EXT_texture_from_pixmap();
+#endif /* GLX_EXT_texture_from_pixmap */
+#ifdef GLX_EXT_visual_info
+ GLXEW_EXT_visual_info = _glewSearchExtension("GLX_EXT_visual_info", extStart, extEnd);
+#endif /* GLX_EXT_visual_info */
+#ifdef GLX_EXT_visual_rating
+ GLXEW_EXT_visual_rating = _glewSearchExtension("GLX_EXT_visual_rating", extStart, extEnd);
+#endif /* GLX_EXT_visual_rating */
+#ifdef GLX_INTEL_swap_event
+ GLXEW_INTEL_swap_event = _glewSearchExtension("GLX_INTEL_swap_event", extStart, extEnd);
+#endif /* GLX_INTEL_swap_event */
+#ifdef GLX_MESA_agp_offset
+ GLXEW_MESA_agp_offset = _glewSearchExtension("GLX_MESA_agp_offset", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_agp_offset) GLXEW_MESA_agp_offset = !_glewInit_GLX_MESA_agp_offset();
+#endif /* GLX_MESA_agp_offset */
+#ifdef GLX_MESA_copy_sub_buffer
+ GLXEW_MESA_copy_sub_buffer = _glewSearchExtension("GLX_MESA_copy_sub_buffer", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_copy_sub_buffer) GLXEW_MESA_copy_sub_buffer = !_glewInit_GLX_MESA_copy_sub_buffer();
+#endif /* GLX_MESA_copy_sub_buffer */
+#ifdef GLX_MESA_pixmap_colormap
+ GLXEW_MESA_pixmap_colormap = _glewSearchExtension("GLX_MESA_pixmap_colormap", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_pixmap_colormap) GLXEW_MESA_pixmap_colormap = !_glewInit_GLX_MESA_pixmap_colormap();
+#endif /* GLX_MESA_pixmap_colormap */
+#ifdef GLX_MESA_query_renderer
+ GLXEW_MESA_query_renderer = _glewSearchExtension("GLX_MESA_query_renderer", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_query_renderer) GLXEW_MESA_query_renderer = !_glewInit_GLX_MESA_query_renderer();
+#endif /* GLX_MESA_query_renderer */
+#ifdef GLX_MESA_release_buffers
+ GLXEW_MESA_release_buffers = _glewSearchExtension("GLX_MESA_release_buffers", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_release_buffers) GLXEW_MESA_release_buffers = !_glewInit_GLX_MESA_release_buffers();
+#endif /* GLX_MESA_release_buffers */
+#ifdef GLX_MESA_set_3dfx_mode
+ GLXEW_MESA_set_3dfx_mode = _glewSearchExtension("GLX_MESA_set_3dfx_mode", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_set_3dfx_mode) GLXEW_MESA_set_3dfx_mode = !_glewInit_GLX_MESA_set_3dfx_mode();
+#endif /* GLX_MESA_set_3dfx_mode */
+#ifdef GLX_MESA_swap_control
+ GLXEW_MESA_swap_control = _glewSearchExtension("GLX_MESA_swap_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_swap_control) GLXEW_MESA_swap_control = !_glewInit_GLX_MESA_swap_control();
+#endif /* GLX_MESA_swap_control */
+#ifdef GLX_NV_copy_buffer
+ GLXEW_NV_copy_buffer = _glewSearchExtension("GLX_NV_copy_buffer", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_copy_buffer) GLXEW_NV_copy_buffer = !_glewInit_GLX_NV_copy_buffer();
+#endif /* GLX_NV_copy_buffer */
+#ifdef GLX_NV_copy_image
+ GLXEW_NV_copy_image = _glewSearchExtension("GLX_NV_copy_image", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_copy_image) GLXEW_NV_copy_image = !_glewInit_GLX_NV_copy_image();
+#endif /* GLX_NV_copy_image */
+#ifdef GLX_NV_delay_before_swap
+ GLXEW_NV_delay_before_swap = _glewSearchExtension("GLX_NV_delay_before_swap", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_delay_before_swap) GLXEW_NV_delay_before_swap = !_glewInit_GLX_NV_delay_before_swap();
+#endif /* GLX_NV_delay_before_swap */
+#ifdef GLX_NV_float_buffer
+ GLXEW_NV_float_buffer = _glewSearchExtension("GLX_NV_float_buffer", extStart, extEnd);
+#endif /* GLX_NV_float_buffer */
+#ifdef GLX_NV_multisample_coverage
+ GLXEW_NV_multisample_coverage = _glewSearchExtension("GLX_NV_multisample_coverage", extStart, extEnd);
+#endif /* GLX_NV_multisample_coverage */
+#ifdef GLX_NV_present_video
+ GLXEW_NV_present_video = _glewSearchExtension("GLX_NV_present_video", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_present_video) GLXEW_NV_present_video = !_glewInit_GLX_NV_present_video();
+#endif /* GLX_NV_present_video */
+#ifdef GLX_NV_robustness_video_memory_purge
+ GLXEW_NV_robustness_video_memory_purge = _glewSearchExtension("GLX_NV_robustness_video_memory_purge", extStart, extEnd);
+#endif /* GLX_NV_robustness_video_memory_purge */
+#ifdef GLX_NV_swap_group
+ GLXEW_NV_swap_group = _glewSearchExtension("GLX_NV_swap_group", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_swap_group) GLXEW_NV_swap_group = !_glewInit_GLX_NV_swap_group();
+#endif /* GLX_NV_swap_group */
+#ifdef GLX_NV_vertex_array_range
+ GLXEW_NV_vertex_array_range = _glewSearchExtension("GLX_NV_vertex_array_range", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_vertex_array_range) GLXEW_NV_vertex_array_range = !_glewInit_GLX_NV_vertex_array_range();
+#endif /* GLX_NV_vertex_array_range */
+#ifdef GLX_NV_video_capture
+ GLXEW_NV_video_capture = _glewSearchExtension("GLX_NV_video_capture", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_video_capture) GLXEW_NV_video_capture = !_glewInit_GLX_NV_video_capture();
+#endif /* GLX_NV_video_capture */
+#ifdef GLX_NV_video_out
+ GLXEW_NV_video_out = _glewSearchExtension("GLX_NV_video_out", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_video_out) GLXEW_NV_video_out = !_glewInit_GLX_NV_video_out();
+#endif /* GLX_NV_video_out */
+#ifdef GLX_OML_swap_method
+ GLXEW_OML_swap_method = _glewSearchExtension("GLX_OML_swap_method", extStart, extEnd);
+#endif /* GLX_OML_swap_method */
+#ifdef GLX_OML_sync_control
+ GLXEW_OML_sync_control = _glewSearchExtension("GLX_OML_sync_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_OML_sync_control) GLXEW_OML_sync_control = !_glewInit_GLX_OML_sync_control();
+#endif /* GLX_OML_sync_control */
+#ifdef GLX_SGIS_blended_overlay
+ GLXEW_SGIS_blended_overlay = _glewSearchExtension("GLX_SGIS_blended_overlay", extStart, extEnd);
+#endif /* GLX_SGIS_blended_overlay */
+#ifdef GLX_SGIS_color_range
+ GLXEW_SGIS_color_range = _glewSearchExtension("GLX_SGIS_color_range", extStart, extEnd);
+#endif /* GLX_SGIS_color_range */
+#ifdef GLX_SGIS_multisample
+ GLXEW_SGIS_multisample = _glewSearchExtension("GLX_SGIS_multisample", extStart, extEnd);
+#endif /* GLX_SGIS_multisample */
+#ifdef GLX_SGIS_shared_multisample
+ GLXEW_SGIS_shared_multisample = _glewSearchExtension("GLX_SGIS_shared_multisample", extStart, extEnd);
+#endif /* GLX_SGIS_shared_multisample */
+#ifdef GLX_SGIX_fbconfig
+ GLXEW_SGIX_fbconfig = _glewSearchExtension("GLX_SGIX_fbconfig", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_fbconfig) GLXEW_SGIX_fbconfig = !_glewInit_GLX_SGIX_fbconfig();
+#endif /* GLX_SGIX_fbconfig */
+#ifdef GLX_SGIX_hyperpipe
+ GLXEW_SGIX_hyperpipe = _glewSearchExtension("GLX_SGIX_hyperpipe", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_hyperpipe) GLXEW_SGIX_hyperpipe = !_glewInit_GLX_SGIX_hyperpipe();
+#endif /* GLX_SGIX_hyperpipe */
+#ifdef GLX_SGIX_pbuffer
+ GLXEW_SGIX_pbuffer = _glewSearchExtension("GLX_SGIX_pbuffer", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_pbuffer) GLXEW_SGIX_pbuffer = !_glewInit_GLX_SGIX_pbuffer();
+#endif /* GLX_SGIX_pbuffer */
+#ifdef GLX_SGIX_swap_barrier
+ GLXEW_SGIX_swap_barrier = _glewSearchExtension("GLX_SGIX_swap_barrier", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_swap_barrier) GLXEW_SGIX_swap_barrier = !_glewInit_GLX_SGIX_swap_barrier();
+#endif /* GLX_SGIX_swap_barrier */
+#ifdef GLX_SGIX_swap_group
+ GLXEW_SGIX_swap_group = _glewSearchExtension("GLX_SGIX_swap_group", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_swap_group) GLXEW_SGIX_swap_group = !_glewInit_GLX_SGIX_swap_group();
+#endif /* GLX_SGIX_swap_group */
+#ifdef GLX_SGIX_video_resize
+ GLXEW_SGIX_video_resize = _glewSearchExtension("GLX_SGIX_video_resize", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_video_resize) GLXEW_SGIX_video_resize = !_glewInit_GLX_SGIX_video_resize();
+#endif /* GLX_SGIX_video_resize */
+#ifdef GLX_SGIX_visual_select_group
+ GLXEW_SGIX_visual_select_group = _glewSearchExtension("GLX_SGIX_visual_select_group", extStart, extEnd);
+#endif /* GLX_SGIX_visual_select_group */
+#ifdef GLX_SGI_cushion
+ GLXEW_SGI_cushion = _glewSearchExtension("GLX_SGI_cushion", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_cushion) GLXEW_SGI_cushion = !_glewInit_GLX_SGI_cushion();
+#endif /* GLX_SGI_cushion */
+#ifdef GLX_SGI_make_current_read
+ GLXEW_SGI_make_current_read = _glewSearchExtension("GLX_SGI_make_current_read", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_make_current_read) GLXEW_SGI_make_current_read = !_glewInit_GLX_SGI_make_current_read();
+#endif /* GLX_SGI_make_current_read */
+#ifdef GLX_SGI_swap_control
+ GLXEW_SGI_swap_control = _glewSearchExtension("GLX_SGI_swap_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_swap_control) GLXEW_SGI_swap_control = !_glewInit_GLX_SGI_swap_control();
+#endif /* GLX_SGI_swap_control */
+#ifdef GLX_SGI_video_sync
+ GLXEW_SGI_video_sync = _glewSearchExtension("GLX_SGI_video_sync", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_video_sync) GLXEW_SGI_video_sync = !_glewInit_GLX_SGI_video_sync();
+#endif /* GLX_SGI_video_sync */
+#ifdef GLX_SUN_get_transparent_index
+ GLXEW_SUN_get_transparent_index = _glewSearchExtension("GLX_SUN_get_transparent_index", extStart, extEnd);
+ if (glewExperimental || GLXEW_SUN_get_transparent_index) GLXEW_SUN_get_transparent_index = !_glewInit_GLX_SUN_get_transparent_index();
+#endif /* GLX_SUN_get_transparent_index */
+#ifdef GLX_SUN_video_resize
+ GLXEW_SUN_video_resize = _glewSearchExtension("GLX_SUN_video_resize", extStart, extEnd);
+ if (glewExperimental || GLXEW_SUN_video_resize) GLXEW_SUN_video_resize = !_glewInit_GLX_SUN_video_resize();
+#endif /* GLX_SUN_video_resize */
+
+ return GLEW_OK;
+}
+
+#endif /* !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) */
+
+/* ------------------------------------------------------------------------ */
+
+const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error)
+{
+ static const GLubyte* _glewErrorString[] =
+ {
+ (const GLubyte*)"No error",
+ (const GLubyte*)"Missing GL version",
+ (const GLubyte*)"GL 1.1 and up are not supported",
+ (const GLubyte*)"GLX 1.2 and up are not supported",
+ (const GLubyte*)"Unknown error"
+ };
+ const size_t max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1;
+ return _glewErrorString[(size_t)error > max_error ? max_error : (size_t)error];
+}
+
+const GLubyte * GLEWAPIENTRY glewGetString (GLenum name)
+{
+ static const GLubyte* _glewString[] =
+ {
+ (const GLubyte*)NULL,
+ (const GLubyte*)"2.1.0",
+ (const GLubyte*)"2",
+ (const GLubyte*)"1",
+ (const GLubyte*)"0"
+ };
+ const size_t max_string = sizeof(_glewString)/sizeof(*_glewString) - 1;
+ return _glewString[(size_t)name > max_string ? 0 : (size_t)name];
+}
+
+/* ------------------------------------------------------------------------ */
+
+GLboolean glewExperimental = GL_FALSE;
+
+GLenum GLEWAPIENTRY glewInit (void)
+{
+ GLenum r;
+#if defined(GLEW_EGL)
+ PFNEGLGETCURRENTDISPLAYPROC getCurrentDisplay = NULL;
+#endif
+ r = glewContextInit();
+ if ( r != 0 ) return r;
+#if defined(GLEW_EGL)
+ getCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) glewGetProcAddress("eglGetCurrentDisplay");
+ return eglewInit(getCurrentDisplay());
+#elif defined(GLEW_OSMESA) || defined(__ANDROID__) || defined(__native_client__) || defined(__HAIKU__)
+ return r;
+#elif defined(_WIN32)
+ return wglewInit();
+#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */
+ return glxewInit();
+#else
+ return r;
+#endif /* _WIN32 */
+}
+
+#if defined(_WIN32) && defined(GLEW_BUILD) && defined(__GNUC__)
+/* GCC requires a DLL entry point even without any standard library included. */
+/* Types extracted from windows.h to avoid polluting the rest of the file. */
+int __stdcall DllMainCRTStartup(void* instance, unsigned reason, void* reserved)
+{
+ (void) instance;
+ (void) reason;
+ (void) reserved;
+ return 1;
+}
+#endif
+GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
+{
+ const GLubyte* pos = (const GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if (_glewStrSame1(&pos, &len, (const GLubyte*)"GL_", 3))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8))
+ {
+#ifdef GL_VERSION_1_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3))
+ {
+ ret = GLEW_VERSION_1_2;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_2_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2_1", 5))
+ {
+ ret = GLEW_VERSION_1_2_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3))
+ {
+ ret = GLEW_VERSION_1_3;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3))
+ {
+ ret = GLEW_VERSION_1_4;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3))
+ {
+ ret = GLEW_VERSION_1_5;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_2_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_0", 3))
+ {
+ ret = GLEW_VERSION_2_0;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_2_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_1", 3))
+ {
+ ret = GLEW_VERSION_2_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_0", 3))
+ {
+ ret = GLEW_VERSION_3_0;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_1", 3))
+ {
+ ret = GLEW_VERSION_3_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_2", 3))
+ {
+ ret = GLEW_VERSION_3_2;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_3", 3))
+ {
+ ret = GLEW_VERSION_3_3;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_0", 3))
+ {
+ ret = GLEW_VERSION_4_0;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_1", 3))
+ {
+ ret = GLEW_VERSION_4_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_2", 3))
+ {
+ ret = GLEW_VERSION_4_2;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_3", 3))
+ {
+ ret = GLEW_VERSION_4_3;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_4", 3))
+ {
+ ret = GLEW_VERSION_4_4;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_5", 3))
+ {
+ ret = GLEW_VERSION_4_5;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_6
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_6", 3))
+ {
+ ret = GLEW_VERSION_4_6;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5))
+ {
+#ifdef GL_3DFX_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_3DFX_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_3DFX_tbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tbuffer", 7))
+ {
+ ret = GLEW_3DFX_tbuffer;
+ continue;
+ }
+#endif
+#ifdef GL_3DFX_texture_compression_FXT1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_FXT1", 24))
+ {
+ ret = GLEW_3DFX_texture_compression_FXT1;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+ {
+#ifdef GL_AMD_blend_minmax_factor
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax_factor", 19))
+ {
+ ret = GLEW_AMD_blend_minmax_factor;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_compressed_3DC_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_3DC_texture", 22))
+ {
+ ret = GLEW_AMD_compressed_3DC_texture;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_compressed_ATC_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_ATC_texture", 22))
+ {
+ ret = GLEW_AMD_compressed_ATC_texture;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_conservative_depth
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18))
+ {
+ ret = GLEW_AMD_conservative_depth;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_debug_output
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12))
+ {
+ ret = GLEW_AMD_debug_output;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_depth_clamp_separate
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp_separate", 20))
+ {
+ ret = GLEW_AMD_depth_clamp_separate;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_draw_buffers_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18))
+ {
+ ret = GLEW_AMD_draw_buffers_blend;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_framebuffer_sample_positions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sample_positions", 28))
+ {
+ ret = GLEW_AMD_framebuffer_sample_positions;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_gcn_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gcn_shader", 10))
+ {
+ ret = GLEW_AMD_gcn_shader;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_gpu_shader_half_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_half_float", 21))
+ {
+ ret = GLEW_AMD_gpu_shader_half_float;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_gpu_shader_int16
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_int16", 16))
+ {
+ ret = GLEW_AMD_gpu_shader_int16;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_gpu_shader_int64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_int64", 16))
+ {
+ ret = GLEW_AMD_gpu_shader_int64;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_interleaved_elements
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interleaved_elements", 20))
+ {
+ ret = GLEW_AMD_interleaved_elements;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_multi_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19))
+ {
+ ret = GLEW_AMD_multi_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_name_gen_delete
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"name_gen_delete", 15))
+ {
+ ret = GLEW_AMD_name_gen_delete;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_occlusion_query_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query_event", 21))
+ {
+ ret = GLEW_AMD_occlusion_query_event;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_performance_monitor
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_monitor", 19))
+ {
+ ret = GLEW_AMD_performance_monitor;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_pinned_memory
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pinned_memory", 13))
+ {
+ ret = GLEW_AMD_pinned_memory;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_program_binary_Z400
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_binary_Z400", 19))
+ {
+ ret = GLEW_AMD_program_binary_Z400;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_query_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19))
+ {
+ ret = GLEW_AMD_query_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_sample_positions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_positions", 16))
+ {
+ ret = GLEW_AMD_sample_positions;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_seamless_cubemap_per_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28))
+ {
+ ret = GLEW_AMD_seamless_cubemap_per_texture;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_atomic_counter_ops
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counter_ops", 25))
+ {
+ ret = GLEW_AMD_shader_atomic_counter_ops;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_ballot
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_ballot", 13))
+ {
+ ret = GLEW_AMD_shader_ballot;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_explicit_vertex_parameter
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_explicit_vertex_parameter", 32))
+ {
+ ret = GLEW_AMD_shader_explicit_vertex_parameter;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_stencil_export
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21))
+ {
+ ret = GLEW_AMD_shader_stencil_export;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_stencil_value_export
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_value_export", 27))
+ {
+ ret = GLEW_AMD_shader_stencil_value_export;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_trinary_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_trinary_minmax", 21))
+ {
+ ret = GLEW_AMD_shader_trinary_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_sparse_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14))
+ {
+ ret = GLEW_AMD_sparse_texture;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_stencil_operation_extended
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_operation_extended", 26))
+ {
+ ret = GLEW_AMD_stencil_operation_extended;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_texture_gather_bias_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_gather_bias_lod", 23))
+ {
+ ret = GLEW_AMD_texture_gather_bias_lod;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_texture_texture4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_texture4", 16))
+ {
+ ret = GLEW_AMD_texture_texture4;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3_lines_triangles", 35))
+ {
+ ret = GLEW_AMD_transform_feedback3_lines_triangles;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_transform_feedback4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback4", 19))
+ {
+ ret = GLEW_AMD_transform_feedback4;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_vertex_shader_layer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_layer", 19))
+ {
+ ret = GLEW_AMD_vertex_shader_layer;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_vertex_shader_tessellator
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_tessellator", 25))
+ {
+ ret = GLEW_AMD_vertex_shader_tessellator;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_vertex_shader_viewport_index
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_viewport_index", 28))
+ {
+ ret = GLEW_AMD_vertex_shader_viewport_index;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANDROID_", 8))
+ {
+#ifdef GL_ANDROID_extension_pack_es31a
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extension_pack_es31a", 20))
+ {
+ ret = GLEW_ANDROID_extension_pack_es31a;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANGLE_", 6))
+ {
+#ifdef GL_ANGLE_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13))
+ {
+ ret = GLEW_ANGLE_depth_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_framebuffer_blit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16))
+ {
+ ret = GLEW_ANGLE_framebuffer_blit;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_framebuffer_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23))
+ {
+ ret = GLEW_ANGLE_framebuffer_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_instanced_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16))
+ {
+ ret = GLEW_ANGLE_instanced_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_pack_reverse_row_order
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_reverse_row_order", 22))
+ {
+ ret = GLEW_ANGLE_pack_reverse_row_order;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_program_binary
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_binary", 14))
+ {
+ ret = GLEW_ANGLE_program_binary;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24))
+ {
+ ret = GLEW_ANGLE_texture_compression_dxt1;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt3", 24))
+ {
+ ret = GLEW_ANGLE_texture_compression_dxt3;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt5", 24))
+ {
+ ret = GLEW_ANGLE_texture_compression_dxt5;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_usage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_usage", 13))
+ {
+ ret = GLEW_ANGLE_texture_usage;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_timer_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11))
+ {
+ ret = GLEW_ANGLE_timer_query;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_translated_shader_source
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"translated_shader_source", 24))
+ {
+ ret = GLEW_ANGLE_translated_shader_source;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6))
+ {
+#ifdef GL_APPLE_aux_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"aux_depth_stencil", 17))
+ {
+ ret = GLEW_APPLE_aux_depth_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_client_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14))
+ {
+ ret = GLEW_APPLE_client_storage;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_clip_distance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_distance", 13))
+ {
+ ret = GLEW_APPLE_clip_distance;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_color_buffer_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_packed_float", 25))
+ {
+ ret = GLEW_APPLE_color_buffer_packed_float;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_copy_texture_levels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture_levels", 19))
+ {
+ ret = GLEW_APPLE_copy_texture_levels;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_element_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13))
+ {
+ ret = GLEW_APPLE_element_array;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_fence
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5))
+ {
+ ret = GLEW_APPLE_fence;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_float_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_pixels", 12))
+ {
+ ret = GLEW_APPLE_float_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_flush_buffer_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_buffer_range", 18))
+ {
+ ret = GLEW_APPLE_flush_buffer_range;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_framebuffer_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23))
+ {
+ ret = GLEW_APPLE_framebuffer_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_object_purgeable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"object_purgeable", 16))
+ {
+ ret = GLEW_APPLE_object_purgeable;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_pixel_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12))
+ {
+ ret = GLEW_APPLE_pixel_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_rgb_422
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"rgb_422", 7))
+ {
+ ret = GLEW_APPLE_rgb_422;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_row_bytes
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"row_bytes", 9))
+ {
+ ret = GLEW_APPLE_row_bytes;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_specular_vector
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15))
+ {
+ ret = GLEW_APPLE_specular_vector;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4))
+ {
+ ret = GLEW_APPLE_sync;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_texture_2D_limited_npot
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_2D_limited_npot", 23))
+ {
+ ret = GLEW_APPLE_texture_2D_limited_npot;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_texture_format_BGRA8888
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_format_BGRA8888", 23))
+ {
+ ret = GLEW_APPLE_texture_format_BGRA8888;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_texture_max_level
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_max_level", 17))
+ {
+ ret = GLEW_APPLE_texture_max_level;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_texture_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_packed_float", 20))
+ {
+ ret = GLEW_APPLE_texture_packed_float;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_texture_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13))
+ {
+ ret = GLEW_APPLE_texture_range;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_transform_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_hint", 14))
+ {
+ ret = GLEW_APPLE_transform_hint;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_vertex_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
+ {
+ ret = GLEW_APPLE_vertex_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = GLEW_APPLE_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_vertex_program_evaluators
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program_evaluators", 25))
+ {
+ ret = GLEW_APPLE_vertex_program_evaluators;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_ycbcr_422
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9))
+ {
+ ret = GLEW_APPLE_ycbcr_422;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4))
+ {
+#ifdef GL_ARB_ES2_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES2_compatibility", 17))
+ {
+ ret = GLEW_ARB_ES2_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_ES3_1_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_1_compatibility", 19))
+ {
+ ret = GLEW_ARB_ES3_1_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_ES3_2_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_2_compatibility", 19))
+ {
+ ret = GLEW_ARB_ES3_2_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_ES3_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_compatibility", 17))
+ {
+ ret = GLEW_ARB_ES3_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_arrays_of_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"arrays_of_arrays", 16))
+ {
+ ret = GLEW_ARB_arrays_of_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_base_instance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"base_instance", 13))
+ {
+ ret = GLEW_ARB_base_instance;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_bindless_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16))
+ {
+ ret = GLEW_ARB_bindless_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_blend_func_extended
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_extended", 19))
+ {
+ ret = GLEW_ARB_blend_func_extended;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_buffer_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_storage", 14))
+ {
+ ret = GLEW_ARB_buffer_storage;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_cl_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event", 8))
+ {
+ ret = GLEW_ARB_cl_event;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_clear_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_buffer_object", 19))
+ {
+ ret = GLEW_ARB_clear_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_clear_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_texture", 13))
+ {
+ ret = GLEW_ARB_clear_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_clip_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_control", 12))
+ {
+ ret = GLEW_ARB_clip_control;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_color_buffer_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18))
+ {
+ ret = GLEW_ARB_color_buffer_float;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compatibility", 13))
+ {
+ ret = GLEW_ARB_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compressed_texture_pixel_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_texture_pixel_storage", 32))
+ {
+ ret = GLEW_ARB_compressed_texture_pixel_storage;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compute_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_shader", 14))
+ {
+ ret = GLEW_ARB_compute_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compute_variable_group_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_variable_group_size", 27))
+ {
+ ret = GLEW_ARB_compute_variable_group_size;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_conditional_render_inverted
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render_inverted", 27))
+ {
+ ret = GLEW_ARB_conditional_render_inverted;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_conservative_depth
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18))
+ {
+ ret = GLEW_ARB_conservative_depth;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_copy_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11))
+ {
+ ret = GLEW_ARB_copy_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = GLEW_ARB_copy_image;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_cull_distance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_distance", 13))
+ {
+ ret = GLEW_ARB_cull_distance;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_debug_output
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12))
+ {
+ ret = GLEW_ARB_debug_output;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_depth_buffer_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18))
+ {
+ ret = GLEW_ARB_depth_buffer_float;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_depth_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11))
+ {
+ ret = GLEW_ARB_depth_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13))
+ {
+ ret = GLEW_ARB_depth_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_derivative_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"derivative_control", 18))
+ {
+ ret = GLEW_ARB_derivative_control;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_direct_state_access
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19))
+ {
+ ret = GLEW_ARB_direct_state_access;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12))
+ {
+ ret = GLEW_ARB_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_buffers_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18))
+ {
+ ret = GLEW_ARB_draw_buffers_blend;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_elements_base_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_elements_base_vertex", 25))
+ {
+ ret = GLEW_ARB_draw_elements_base_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_indirect", 13))
+ {
+ ret = GLEW_ARB_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_instanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14))
+ {
+ ret = GLEW_ARB_draw_instanced;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_enhanced_layouts
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"enhanced_layouts", 16))
+ {
+ ret = GLEW_ARB_enhanced_layouts;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_explicit_attrib_location
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_attrib_location", 24))
+ {
+ ret = GLEW_ARB_explicit_attrib_location;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_explicit_uniform_location
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_uniform_location", 25))
+ {
+ ret = GLEW_ARB_explicit_uniform_location;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_coord_conventions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_coord_conventions", 26))
+ {
+ ret = GLEW_ARB_fragment_coord_conventions;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_layer_viewport
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_layer_viewport", 23))
+ {
+ ret = GLEW_ARB_fragment_layer_viewport;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16))
+ {
+ ret = GLEW_ARB_fragment_program;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_program_shadow
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_shadow", 23))
+ {
+ ret = GLEW_ARB_fragment_program_shadow;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15))
+ {
+ ret = GLEW_ARB_fragment_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_shader_interlock
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_interlock", 25))
+ {
+ ret = GLEW_ARB_fragment_shader_interlock;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_framebuffer_no_attachments
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_no_attachments", 26))
+ {
+ ret = GLEW_ARB_framebuffer_no_attachments;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_framebuffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18))
+ {
+ ret = GLEW_ARB_framebuffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLEW_ARB_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_geometry_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16))
+ {
+ ret = GLEW_ARB_geometry_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_get_program_binary
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_program_binary", 18))
+ {
+ ret = GLEW_ARB_get_program_binary;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_get_texture_sub_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_texture_sub_image", 21))
+ {
+ ret = GLEW_ARB_get_texture_sub_image;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_gl_spirv
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_spirv", 8))
+ {
+ ret = GLEW_ARB_gl_spirv;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_gpu_shader5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11))
+ {
+ ret = GLEW_ARB_gpu_shader5;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_gpu_shader_fp64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_fp64", 15))
+ {
+ ret = GLEW_ARB_gpu_shader_fp64;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_gpu_shader_int64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_int64", 16))
+ {
+ ret = GLEW_ARB_gpu_shader_int64;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_half_float_pixel
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_pixel", 16))
+ {
+ ret = GLEW_ARB_half_float_pixel;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_half_float_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_vertex", 17))
+ {
+ ret = GLEW_ARB_half_float_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_imaging
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"imaging", 7))
+ {
+ ret = GLEW_ARB_imaging;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_indirect_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"indirect_parameters", 19))
+ {
+ ret = GLEW_ARB_indirect_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_instanced_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16))
+ {
+ ret = GLEW_ARB_instanced_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_internalformat_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query", 20))
+ {
+ ret = GLEW_ARB_internalformat_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_internalformat_query2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query2", 21))
+ {
+ ret = GLEW_ARB_internalformat_query2;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_invalidate_subdata
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"invalidate_subdata", 18))
+ {
+ ret = GLEW_ARB_invalidate_subdata;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_map_buffer_alignment
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_alignment", 20))
+ {
+ ret = GLEW_ARB_map_buffer_alignment;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_map_buffer_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16))
+ {
+ ret = GLEW_ARB_map_buffer_range;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_matrix_palette
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"matrix_palette", 14))
+ {
+ ret = GLEW_ARB_matrix_palette;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multi_bind
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_bind", 10))
+ {
+ ret = GLEW_ARB_multi_bind;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multi_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19))
+ {
+ ret = GLEW_ARB_multi_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_ARB_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multitexture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12))
+ {
+ ret = GLEW_ARB_multitexture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_occlusion_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15))
+ {
+ ret = GLEW_ARB_occlusion_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_occlusion_query2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query2", 16))
+ {
+ ret = GLEW_ARB_occlusion_query2;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_parallel_shader_compile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_shader_compile", 23))
+ {
+ ret = GLEW_ARB_parallel_shader_compile;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_pipeline_statistics_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pipeline_statistics_query", 25))
+ {
+ ret = GLEW_ARB_pipeline_statistics_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_pixel_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19))
+ {
+ ret = GLEW_ARB_pixel_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_point_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16))
+ {
+ ret = GLEW_ARB_point_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_point_sprite
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12))
+ {
+ ret = GLEW_ARB_point_sprite;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_polygon_offset_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset_clamp", 20))
+ {
+ ret = GLEW_ARB_polygon_offset_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_post_depth_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_depth_coverage", 19))
+ {
+ ret = GLEW_ARB_post_depth_coverage;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_program_interface_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_interface_query", 23))
+ {
+ ret = GLEW_ARB_program_interface_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_provoking_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16))
+ {
+ ret = GLEW_ARB_provoking_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_query_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19))
+ {
+ ret = GLEW_ARB_query_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robust_buffer_access_behavior
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robust_buffer_access_behavior", 29))
+ {
+ ret = GLEW_ARB_robust_buffer_access_behavior;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness", 10))
+ {
+ ret = GLEW_ARB_robustness;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robustness_application_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32))
+ {
+ ret = GLEW_ARB_robustness_application_isolation;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robustness_share_group_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32))
+ {
+ ret = GLEW_ARB_robustness_share_group_isolation;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sample_locations
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_locations", 16))
+ {
+ ret = GLEW_ARB_sample_locations;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sample_shading
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_shading", 14))
+ {
+ ret = GLEW_ARB_sample_shading;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sampler_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sampler_objects", 15))
+ {
+ ret = GLEW_ARB_sampler_objects;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_seamless_cube_map
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cube_map", 17))
+ {
+ ret = GLEW_ARB_seamless_cube_map;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_seamless_cubemap_per_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28))
+ {
+ ret = GLEW_ARB_seamless_cubemap_per_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_separate_shader_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23))
+ {
+ ret = GLEW_ARB_separate_shader_objects;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_atomic_counter_ops
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counter_ops", 25))
+ {
+ ret = GLEW_ARB_shader_atomic_counter_ops;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_atomic_counters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22))
+ {
+ ret = GLEW_ARB_shader_atomic_counters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_ballot
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_ballot", 13))
+ {
+ ret = GLEW_ARB_shader_ballot;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_bit_encoding
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_bit_encoding", 19))
+ {
+ ret = GLEW_ARB_shader_bit_encoding;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_clock
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_clock", 12))
+ {
+ ret = GLEW_ARB_shader_clock;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_draw_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_draw_parameters", 22))
+ {
+ ret = GLEW_ARB_shader_draw_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_group_vote
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_group_vote", 17))
+ {
+ ret = GLEW_ARB_shader_group_vote;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_image_load_store
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23))
+ {
+ ret = GLEW_ARB_shader_image_load_store;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_image_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_size", 17))
+ {
+ ret = GLEW_ARB_shader_image_size;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14))
+ {
+ ret = GLEW_ARB_shader_objects;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_precision
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_precision", 16))
+ {
+ ret = GLEW_ARB_shader_precision;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_stencil_export
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21))
+ {
+ ret = GLEW_ARB_shader_stencil_export;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_storage_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28))
+ {
+ ret = GLEW_ARB_shader_storage_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_subroutine
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_subroutine", 17))
+ {
+ ret = GLEW_ARB_shader_subroutine;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_texture_image_samples
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_image_samples", 28))
+ {
+ ret = GLEW_ARB_shader_texture_image_samples;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18))
+ {
+ ret = GLEW_ARB_shader_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_viewport_layer_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_viewport_layer_array", 27))
+ {
+ ret = GLEW_ARB_shader_viewport_layer_array;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_100
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20))
+ {
+ ret = GLEW_ARB_shading_language_100;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_420pack
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_420pack", 24))
+ {
+ ret = GLEW_ARB_shading_language_420pack;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_include
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_include", 24))
+ {
+ ret = GLEW_ARB_shading_language_include;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_packing
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_packing", 24))
+ {
+ ret = GLEW_ARB_shading_language_packing;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shadow
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6))
+ {
+ ret = GLEW_ARB_shadow;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shadow_ambient
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14))
+ {
+ ret = GLEW_ARB_shadow_ambient;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sparse_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_buffer", 13))
+ {
+ ret = GLEW_ARB_sparse_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sparse_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14))
+ {
+ ret = GLEW_ARB_sparse_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sparse_texture2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture2", 15))
+ {
+ ret = GLEW_ARB_sparse_texture2;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sparse_texture_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture_clamp", 20))
+ {
+ ret = GLEW_ARB_sparse_texture_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_spirv_extensions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"spirv_extensions", 16))
+ {
+ ret = GLEW_ARB_spirv_extensions;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_stencil_texturing
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_texturing", 17))
+ {
+ ret = GLEW_ARB_stencil_texturing;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4))
+ {
+ ret = GLEW_ARB_sync;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_tessellation_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_shader", 19))
+ {
+ ret = GLEW_ARB_tessellation_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_barrier
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_barrier", 15))
+ {
+ ret = GLEW_ARB_texture_barrier;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_border_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20))
+ {
+ ret = GLEW_ARB_texture_border_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21))
+ {
+ ret = GLEW_ARB_texture_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_buffer_object_rgb32
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object_rgb32", 27))
+ {
+ ret = GLEW_ARB_texture_buffer_object_rgb32;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_buffer_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_range", 20))
+ {
+ ret = GLEW_ARB_texture_buffer_range;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_compression
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression", 19))
+ {
+ ret = GLEW_ARB_texture_compression;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_compression_bptc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_bptc", 24))
+ {
+ ret = GLEW_ARB_texture_compression_bptc;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_compression_rgtc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24))
+ {
+ ret = GLEW_ARB_texture_compression_rgtc;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_cube_map
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16))
+ {
+ ret = GLEW_ARB_texture_cube_map;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_cube_map_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map_array", 22))
+ {
+ ret = GLEW_ARB_texture_cube_map_array;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_add
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15))
+ {
+ ret = GLEW_ARB_texture_env_add;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_combine
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19))
+ {
+ ret = GLEW_ARB_texture_env_combine;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_crossbar
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_crossbar", 20))
+ {
+ ret = GLEW_ARB_texture_env_crossbar;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_dot3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16))
+ {
+ ret = GLEW_ARB_texture_env_dot3;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_filter_anisotropic
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26))
+ {
+ ret = GLEW_ARB_texture_filter_anisotropic;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_filter_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_minmax", 21))
+ {
+ ret = GLEW_ARB_texture_filter_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13))
+ {
+ ret = GLEW_ARB_texture_float;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_gather
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_gather", 14))
+ {
+ ret = GLEW_ARB_texture_gather;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp_to_edge", 28))
+ {
+ ret = GLEW_ARB_texture_mirror_clamp_to_edge;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_mirrored_repeat
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23))
+ {
+ ret = GLEW_ARB_texture_mirrored_repeat;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19))
+ {
+ ret = GLEW_ARB_texture_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_non_power_of_two
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24))
+ {
+ ret = GLEW_ARB_texture_non_power_of_two;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_query_levels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_levels", 20))
+ {
+ ret = GLEW_ARB_texture_query_levels;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_query_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_lod", 17))
+ {
+ ret = GLEW_ARB_texture_query_lod;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17))
+ {
+ ret = GLEW_ARB_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_rg
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10))
+ {
+ ret = GLEW_ARB_texture_rg;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_rgb10_a2ui
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rgb10_a2ui", 18))
+ {
+ ret = GLEW_ARB_texture_rgb10_a2ui;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_stencil8
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stencil8", 16))
+ {
+ ret = GLEW_ARB_texture_stencil8;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage", 15))
+ {
+ ret = GLEW_ARB_texture_storage;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_storage_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage_multisample", 27))
+ {
+ ret = GLEW_ARB_texture_storage_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_swizzle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15))
+ {
+ ret = GLEW_ARB_texture_swizzle;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_view
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_view", 12))
+ {
+ ret = GLEW_ARB_texture_view;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_timer_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11))
+ {
+ ret = GLEW_ARB_timer_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transform_feedback2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19))
+ {
+ ret = GLEW_ARB_transform_feedback2;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transform_feedback3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3", 19))
+ {
+ ret = GLEW_ARB_transform_feedback3;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transform_feedback_instanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback_instanced", 28))
+ {
+ ret = GLEW_ARB_transform_feedback_instanced;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transform_feedback_overflow_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback_overflow_query", 33))
+ {
+ ret = GLEW_ARB_transform_feedback_overflow_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transpose_matrix
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transpose_matrix", 16))
+ {
+ ret = GLEW_ARB_transpose_matrix;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_uniform_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"uniform_buffer_object", 21))
+ {
+ ret = GLEW_ARB_uniform_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_array_bgra
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17))
+ {
+ ret = GLEW_ARB_vertex_array_bgra;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
+ {
+ ret = GLEW_ARB_vertex_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_attrib_64bit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19))
+ {
+ ret = GLEW_ARB_vertex_attrib_64bit;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_attrib_binding
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_binding", 21))
+ {
+ ret = GLEW_ARB_vertex_attrib_binding;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_blend", 12))
+ {
+ ret = GLEW_ARB_vertex_blend;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20))
+ {
+ ret = GLEW_ARB_vertex_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14))
+ {
+ ret = GLEW_ARB_vertex_program;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13))
+ {
+ ret = GLEW_ARB_vertex_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_10f_11f_11f_rev", 27))
+ {
+ ret = GLEW_ARB_vertex_type_10f_11f_11f_rev;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_2_10_10_10_rev", 26))
+ {
+ ret = GLEW_ARB_vertex_type_2_10_10_10_rev;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_viewport_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array", 14))
+ {
+ ret = GLEW_ARB_viewport_array;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_window_pos
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10))
+ {
+ ret = GLEW_ARB_window_pos;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARM_", 4))
+ {
+#ifdef GL_ARM_mali_program_binary
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mali_program_binary", 19))
+ {
+ ret = GLEW_ARM_mali_program_binary;
+ continue;
+ }
+#endif
+#ifdef GL_ARM_mali_shader_binary
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mali_shader_binary", 18))
+ {
+ ret = GLEW_ARM_mali_shader_binary;
+ continue;
+ }
+#endif
+#ifdef GL_ARM_rgba8
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"rgba8", 5))
+ {
+ ret = GLEW_ARM_rgba8;
+ continue;
+ }
+#endif
+#ifdef GL_ARM_shader_framebuffer_fetch
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch", 24))
+ {
+ ret = GLEW_ARM_shader_framebuffer_fetch;
+ continue;
+ }
+#endif
+#ifdef GL_ARM_shader_framebuffer_fetch_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch_depth_stencil", 38))
+ {
+ ret = GLEW_ARM_shader_framebuffer_fetch_depth_stencil;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATIX_", 5))
+ {
+#ifdef GL_ATIX_point_sprites
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprites", 13))
+ {
+ ret = GLEW_ATIX_point_sprites;
+ continue;
+ }
+#endif
+#ifdef GL_ATIX_texture_env_combine3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20))
+ {
+ ret = GLEW_ATIX_texture_env_combine3;
+ continue;
+ }
+#endif
+#ifdef GL_ATIX_texture_env_route
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_route", 17))
+ {
+ ret = GLEW_ATIX_texture_env_route;
+ continue;
+ }
+#endif
+#ifdef GL_ATIX_vertex_shader_output_point_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_output_point_size", 31))
+ {
+ ret = GLEW_ATIX_vertex_shader_output_point_size;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4))
+ {
+#ifdef GL_ATI_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12))
+ {
+ ret = GLEW_ATI_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_element_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13))
+ {
+ ret = GLEW_ATI_element_array;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_envmap_bumpmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"envmap_bumpmap", 14))
+ {
+ ret = GLEW_ATI_envmap_bumpmap;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_fragment_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15))
+ {
+ ret = GLEW_ATI_fragment_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_map_object_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_object_buffer", 17))
+ {
+ ret = GLEW_ATI_map_object_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_meminfo
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"meminfo", 7))
+ {
+ ret = GLEW_ATI_meminfo;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_pn_triangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12))
+ {
+ ret = GLEW_ATI_pn_triangles;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_separate_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_stencil", 16))
+ {
+ ret = GLEW_ATI_separate_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_shader_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18))
+ {
+ ret = GLEW_ATI_shader_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_text_fragment_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"text_fragment_shader", 20))
+ {
+ ret = GLEW_ATI_text_fragment_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_compression_3dc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_3dc", 23))
+ {
+ ret = GLEW_ATI_texture_compression_3dc;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_env_combine3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20))
+ {
+ ret = GLEW_ATI_texture_env_combine3;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13))
+ {
+ ret = GLEW_ATI_texture_float;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_mirror_once
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_once", 19))
+ {
+ ret = GLEW_ATI_texture_mirror_once;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_vertex_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
+ {
+ ret = GLEW_ATI_vertex_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_vertex_attrib_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_array_object", 26))
+ {
+ ret = GLEW_ATI_vertex_attrib_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_vertex_streams
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_streams", 14))
+ {
+ ret = GLEW_ATI_vertex_streams;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EGL_", 4))
+ {
+#ifdef GL_EGL_KHR_context_flush_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"KHR_context_flush_control", 25))
+ {
+ ret = GLEW_EGL_KHR_context_flush_control;
+ continue;
+ }
+#endif
+#ifdef GL_EGL_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"NV_robustness_video_memory_purge", 32))
+ {
+ ret = GLEW_EGL_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef GL_EXT_422_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"422_pixels", 10))
+ {
+ ret = GLEW_EXT_422_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_Cg_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"Cg_shader", 9))
+ {
+ ret = GLEW_EXT_Cg_shader;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_EGL_image_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"EGL_image_array", 15))
+ {
+ ret = GLEW_EXT_EGL_image_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_YUV_target
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"YUV_target", 10))
+ {
+ ret = GLEW_EXT_YUV_target;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_abgr
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"abgr", 4))
+ {
+ ret = GLEW_EXT_abgr;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_base_instance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"base_instance", 13))
+ {
+ ret = GLEW_EXT_base_instance;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_bgra
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgra", 4))
+ {
+ ret = GLEW_EXT_bgra;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_bindable_uniform
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindable_uniform", 16))
+ {
+ ret = GLEW_EXT_bindable_uniform;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_color", 11))
+ {
+ ret = GLEW_EXT_blend_color;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_equation_separate
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_separate", 23))
+ {
+ ret = GLEW_EXT_blend_equation_separate;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_func_extended
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_extended", 19))
+ {
+ ret = GLEW_EXT_blend_func_extended;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_func_separate
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_separate", 19))
+ {
+ ret = GLEW_EXT_blend_func_separate;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_logic_op
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_logic_op", 14))
+ {
+ ret = GLEW_EXT_blend_logic_op;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax", 12))
+ {
+ ret = GLEW_EXT_blend_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_subtract
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_subtract", 14))
+ {
+ ret = GLEW_EXT_blend_subtract;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_buffer_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_storage", 14))
+ {
+ ret = GLEW_EXT_buffer_storage;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_clear_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_texture", 13))
+ {
+ ret = GLEW_EXT_clear_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_clip_cull_distance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_cull_distance", 18))
+ {
+ ret = GLEW_EXT_clip_cull_distance;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_clip_volume_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_volume_hint", 16))
+ {
+ ret = GLEW_EXT_clip_volume_hint;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_cmyka
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cmyka", 5))
+ {
+ ret = GLEW_EXT_cmyka;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_color_buffer_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18))
+ {
+ ret = GLEW_EXT_color_buffer_float;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_color_buffer_half_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_half_float", 23))
+ {
+ ret = GLEW_EXT_color_buffer_half_float;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_color_subtable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_subtable", 14))
+ {
+ ret = GLEW_EXT_color_subtable;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_compiled_vertex_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compiled_vertex_array", 21))
+ {
+ ret = GLEW_EXT_compiled_vertex_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_compressed_ETC1_RGB8_sub_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_ETC1_RGB8_sub_texture", 32))
+ {
+ ret = GLEW_EXT_compressed_ETC1_RGB8_sub_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_conservative_depth
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18))
+ {
+ ret = GLEW_EXT_conservative_depth;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_convolution
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution", 11))
+ {
+ ret = GLEW_EXT_convolution;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_coordinate_frame
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"coordinate_frame", 16))
+ {
+ ret = GLEW_EXT_coordinate_frame;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = GLEW_EXT_copy_image;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_copy_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture", 12))
+ {
+ ret = GLEW_EXT_copy_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_cull_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11))
+ {
+ ret = GLEW_EXT_cull_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_debug_label
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_label", 11))
+ {
+ ret = GLEW_EXT_debug_label;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_debug_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_marker", 12))
+ {
+ ret = GLEW_EXT_debug_marker;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_depth_bounds_test
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_bounds_test", 17))
+ {
+ ret = GLEW_EXT_depth_bounds_test;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_direct_state_access
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19))
+ {
+ ret = GLEW_EXT_direct_state_access;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_discard_framebuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"discard_framebuffer", 19))
+ {
+ ret = GLEW_EXT_discard_framebuffer;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12))
+ {
+ ret = GLEW_EXT_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_buffers2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers2", 13))
+ {
+ ret = GLEW_EXT_draw_buffers2;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_buffers_indexed
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_indexed", 20))
+ {
+ ret = GLEW_EXT_draw_buffers_indexed;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_elements_base_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_elements_base_vertex", 25))
+ {
+ ret = GLEW_EXT_draw_elements_base_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_instanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14))
+ {
+ ret = GLEW_EXT_draw_instanced;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_range_elements
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_range_elements", 19))
+ {
+ ret = GLEW_EXT_draw_range_elements;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_external_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"external_buffer", 15))
+ {
+ ret = GLEW_EXT_external_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_float_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_blend", 11))
+ {
+ ret = GLEW_EXT_float_blend;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_fog_coord
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_coord", 9))
+ {
+ ret = GLEW_EXT_fog_coord;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_frag_depth
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"frag_depth", 10))
+ {
+ ret = GLEW_EXT_frag_depth;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_fragment_lighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting", 17))
+ {
+ ret = GLEW_EXT_fragment_lighting;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_blit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16))
+ {
+ ret = GLEW_EXT_framebuffer_blit;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23))
+ {
+ ret = GLEW_EXT_framebuffer_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_blit_scaled", 35))
+ {
+ ret = GLEW_EXT_framebuffer_multisample_blit_scaled;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18))
+ {
+ ret = GLEW_EXT_framebuffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLEW_EXT_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_geometry_point_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_point_size", 19))
+ {
+ ret = GLEW_EXT_geometry_point_size;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_geometry_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader", 15))
+ {
+ ret = GLEW_EXT_geometry_shader;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_geometry_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16))
+ {
+ ret = GLEW_EXT_geometry_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_gpu_program_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_parameters", 22))
+ {
+ ret = GLEW_EXT_gpu_program_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_gpu_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader4", 11))
+ {
+ ret = GLEW_EXT_gpu_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_gpu_shader5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11))
+ {
+ ret = GLEW_EXT_gpu_shader5;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_histogram
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"histogram", 9))
+ {
+ ret = GLEW_EXT_histogram;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_array_formats
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_array_formats", 19))
+ {
+ ret = GLEW_EXT_index_array_formats;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_func
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_func", 10))
+ {
+ ret = GLEW_EXT_index_func;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_material
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_material", 14))
+ {
+ ret = GLEW_EXT_index_material;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_texture", 13))
+ {
+ ret = GLEW_EXT_index_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_instanced_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16))
+ {
+ ret = GLEW_EXT_instanced_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_light_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_texture", 13))
+ {
+ ret = GLEW_EXT_light_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_map_buffer_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16))
+ {
+ ret = GLEW_EXT_map_buffer_range;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_memory_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"memory_object", 13))
+ {
+ ret = GLEW_EXT_memory_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_memory_object_fd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"memory_object_fd", 16))
+ {
+ ret = GLEW_EXT_memory_object_fd;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_memory_object_win32
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"memory_object_win32", 19))
+ {
+ ret = GLEW_EXT_memory_object_win32;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_misc_attribute
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_attribute", 14))
+ {
+ ret = GLEW_EXT_misc_attribute;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multi_draw_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_arrays", 17))
+ {
+ ret = GLEW_EXT_multi_draw_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multi_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19))
+ {
+ ret = GLEW_EXT_multi_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multiple_textures
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiple_textures", 17))
+ {
+ ret = GLEW_EXT_multiple_textures;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_EXT_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multisample_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_compatibility", 25))
+ {
+ ret = GLEW_EXT_multisample_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisampled_render_to_texture", 30))
+ {
+ ret = GLEW_EXT_multisampled_render_to_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multisampled_render_to_texture2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisampled_render_to_texture2", 31))
+ {
+ ret = GLEW_EXT_multisampled_render_to_texture2;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multiview_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview_draw_buffers", 22))
+ {
+ ret = GLEW_EXT_multiview_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_packed_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20))
+ {
+ ret = GLEW_EXT_packed_depth_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12))
+ {
+ ret = GLEW_EXT_packed_float;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_packed_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_pixels", 13))
+ {
+ ret = GLEW_EXT_packed_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_paletted_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"paletted_texture", 16))
+ {
+ ret = GLEW_EXT_paletted_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_pixel_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19))
+ {
+ ret = GLEW_EXT_pixel_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_pixel_transform
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform", 15))
+ {
+ ret = GLEW_EXT_pixel_transform;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_pixel_transform_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform_color_table", 27))
+ {
+ ret = GLEW_EXT_pixel_transform_color_table;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_point_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16))
+ {
+ ret = GLEW_EXT_point_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_polygon_offset
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset", 14))
+ {
+ ret = GLEW_EXT_polygon_offset;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_polygon_offset_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset_clamp", 20))
+ {
+ ret = GLEW_EXT_polygon_offset_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_post_depth_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_depth_coverage", 19))
+ {
+ ret = GLEW_EXT_post_depth_coverage;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_provoking_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16))
+ {
+ ret = GLEW_EXT_provoking_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_pvrtc_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pvrtc_sRGB", 10))
+ {
+ ret = GLEW_EXT_pvrtc_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_raster_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"raster_multisample", 18))
+ {
+ ret = GLEW_EXT_raster_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_read_format_bgra
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_format_bgra", 16))
+ {
+ ret = GLEW_EXT_read_format_bgra;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_render_snorm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_snorm", 12))
+ {
+ ret = GLEW_EXT_render_snorm;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_rescale_normal
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14))
+ {
+ ret = GLEW_EXT_rescale_normal;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sRGB", 4))
+ {
+ ret = GLEW_EXT_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_sRGB_write_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sRGB_write_control", 18))
+ {
+ ret = GLEW_EXT_sRGB_write_control;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_scene_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12))
+ {
+ ret = GLEW_EXT_scene_marker;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_secondary_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"secondary_color", 15))
+ {
+ ret = GLEW_EXT_secondary_color;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_semaphore
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"semaphore", 9))
+ {
+ ret = GLEW_EXT_semaphore;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_semaphore_fd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"semaphore_fd", 12))
+ {
+ ret = GLEW_EXT_semaphore_fd;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_semaphore_win32
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"semaphore_win32", 15))
+ {
+ ret = GLEW_EXT_semaphore_win32;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_separate_shader_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23))
+ {
+ ret = GLEW_EXT_separate_shader_objects;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_separate_specular_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23))
+ {
+ ret = GLEW_EXT_separate_specular_color;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_framebuffer_fetch
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch", 24))
+ {
+ ret = GLEW_EXT_shader_framebuffer_fetch;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_group_vote
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_group_vote", 17))
+ {
+ ret = GLEW_EXT_shader_group_vote;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_image_load_formatted
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_formatted", 27))
+ {
+ ret = GLEW_EXT_shader_image_load_formatted;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_image_load_store
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23))
+ {
+ ret = GLEW_EXT_shader_image_load_store;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_implicit_conversions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_implicit_conversions", 27))
+ {
+ ret = GLEW_EXT_shader_implicit_conversions;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_integer_mix
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_integer_mix", 18))
+ {
+ ret = GLEW_EXT_shader_integer_mix;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_io_blocks
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_io_blocks", 16))
+ {
+ ret = GLEW_EXT_shader_io_blocks;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_non_constant_global_initializers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_non_constant_global_initializers", 39))
+ {
+ ret = GLEW_EXT_shader_non_constant_global_initializers;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_pixel_local_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_pixel_local_storage", 26))
+ {
+ ret = GLEW_EXT_shader_pixel_local_storage;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_pixel_local_storage2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_pixel_local_storage2", 27))
+ {
+ ret = GLEW_EXT_shader_pixel_local_storage2;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18))
+ {
+ ret = GLEW_EXT_shader_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shadow_funcs
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_funcs", 12))
+ {
+ ret = GLEW_EXT_shadow_funcs;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shadow_samplers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_samplers", 15))
+ {
+ ret = GLEW_EXT_shadow_samplers;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shared_texture_palette
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_texture_palette", 22))
+ {
+ ret = GLEW_EXT_shared_texture_palette;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_sparse_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14))
+ {
+ ret = GLEW_EXT_sparse_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_sparse_texture2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture2", 15))
+ {
+ ret = GLEW_EXT_sparse_texture2;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_stencil_clear_tag
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_clear_tag", 17))
+ {
+ ret = GLEW_EXT_stencil_clear_tag;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_stencil_two_side
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_two_side", 16))
+ {
+ ret = GLEW_EXT_stencil_two_side;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_stencil_wrap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_wrap", 12))
+ {
+ ret = GLEW_EXT_stencil_wrap;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_subtexture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"subtexture", 10))
+ {
+ ret = GLEW_EXT_subtexture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture", 7))
+ {
+ ret = GLEW_EXT_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture3D
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture3D", 9))
+ {
+ ret = GLEW_EXT_texture3D;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13))
+ {
+ ret = GLEW_EXT_texture_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21))
+ {
+ ret = GLEW_EXT_texture_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_astc_decode_mode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_decode_mode", 36))
+ {
+ ret = GLEW_EXT_texture_compression_astc_decode_mode;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_astc_decode_mode_rgb9e5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_decode_mode_rgb9e5", 43))
+ {
+ ret = GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_bptc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_bptc", 24))
+ {
+ ret = GLEW_EXT_texture_compression_bptc;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_dxt1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24))
+ {
+ ret = GLEW_EXT_texture_compression_dxt1;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_latc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24))
+ {
+ ret = GLEW_EXT_texture_compression_latc;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_rgtc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24))
+ {
+ ret = GLEW_EXT_texture_compression_rgtc;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_s3tc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24))
+ {
+ ret = GLEW_EXT_texture_compression_s3tc;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_cube_map
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16))
+ {
+ ret = GLEW_EXT_texture_cube_map;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_cube_map_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map_array", 22))
+ {
+ ret = GLEW_EXT_texture_cube_map_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_edge_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18))
+ {
+ ret = GLEW_EXT_texture_edge_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env", 11))
+ {
+ ret = GLEW_EXT_texture_env;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env_add
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15))
+ {
+ ret = GLEW_EXT_texture_env_add;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env_combine
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19))
+ {
+ ret = GLEW_EXT_texture_env_combine;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env_dot3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16))
+ {
+ ret = GLEW_EXT_texture_env_dot3;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_filter_anisotropic
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26))
+ {
+ ret = GLEW_EXT_texture_filter_anisotropic;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_filter_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_minmax", 21))
+ {
+ ret = GLEW_EXT_texture_filter_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_format_BGRA8888
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_format_BGRA8888", 23))
+ {
+ ret = GLEW_EXT_texture_format_BGRA8888;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_integer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_integer", 15))
+ {
+ ret = GLEW_EXT_texture_integer;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_lod_bias
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16))
+ {
+ ret = GLEW_EXT_texture_lod_bias;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_mirror_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp", 20))
+ {
+ ret = GLEW_EXT_texture_mirror_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_norm16
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_norm16", 14))
+ {
+ ret = GLEW_EXT_texture_norm16;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_object", 14))
+ {
+ ret = GLEW_EXT_texture_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_perturb_normal
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_perturb_normal", 22))
+ {
+ ret = GLEW_EXT_texture_perturb_normal;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17))
+ {
+ ret = GLEW_EXT_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_rg
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10))
+ {
+ ret = GLEW_EXT_texture_rg;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB", 12))
+ {
+ ret = GLEW_EXT_texture_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_sRGB_R8
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_R8", 15))
+ {
+ ret = GLEW_EXT_texture_sRGB_R8;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_sRGB_RG8
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_RG8", 16))
+ {
+ ret = GLEW_EXT_texture_sRGB_RG8;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_sRGB_decode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_decode", 19))
+ {
+ ret = GLEW_EXT_texture_sRGB_decode;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_shared_exponent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shared_exponent", 23))
+ {
+ ret = GLEW_EXT_texture_shared_exponent;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_snorm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_snorm", 13))
+ {
+ ret = GLEW_EXT_texture_snorm;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage", 15))
+ {
+ ret = GLEW_EXT_texture_storage;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_swizzle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15))
+ {
+ ret = GLEW_EXT_texture_swizzle;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_type_2_10_10_10_REV
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_type_2_10_10_10_REV", 27))
+ {
+ ret = GLEW_EXT_texture_type_2_10_10_10_REV;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_view
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_view", 12))
+ {
+ ret = GLEW_EXT_texture_view;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_timer_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11))
+ {
+ ret = GLEW_EXT_timer_query;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_transform_feedback
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18))
+ {
+ ret = GLEW_EXT_transform_feedback;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_unpack_subimage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"unpack_subimage", 15))
+ {
+ ret = GLEW_EXT_unpack_subimage;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array", 12))
+ {
+ ret = GLEW_EXT_vertex_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_array_bgra
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17))
+ {
+ ret = GLEW_EXT_vertex_array_bgra;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_array_setXXX
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_setXXX", 19))
+ {
+ ret = GLEW_EXT_vertex_array_setXXX;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_attrib_64bit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19))
+ {
+ ret = GLEW_EXT_vertex_attrib_64bit;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13))
+ {
+ ret = GLEW_EXT_vertex_shader;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_weighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_weighting", 16))
+ {
+ ret = GLEW_EXT_vertex_weighting;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_win32_keyed_mutex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"win32_keyed_mutex", 17))
+ {
+ ret = GLEW_EXT_win32_keyed_mutex;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_window_rectangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_rectangles", 17))
+ {
+ ret = GLEW_EXT_window_rectangles;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_x11_sync_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"x11_sync_object", 15))
+ {
+ ret = GLEW_EXT_x11_sync_object;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"GREMEDY_", 8))
+ {
+#ifdef GL_GREMEDY_frame_terminator
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"frame_terminator", 16))
+ {
+ ret = GLEW_GREMEDY_frame_terminator;
+ continue;
+ }
+#endif
+#ifdef GL_GREMEDY_string_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"string_marker", 13))
+ {
+ ret = GLEW_GREMEDY_string_marker;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"HP_", 3))
+ {
+#ifdef GL_HP_convolution_border_modes
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24))
+ {
+ ret = GLEW_HP_convolution_border_modes;
+ continue;
+ }
+#endif
+#ifdef GL_HP_image_transform
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_transform", 15))
+ {
+ ret = GLEW_HP_image_transform;
+ continue;
+ }
+#endif
+#ifdef GL_HP_occlusion_test
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_test", 14))
+ {
+ ret = GLEW_HP_occlusion_test;
+ continue;
+ }
+#endif
+#ifdef GL_HP_texture_lighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lighting", 16))
+ {
+ ret = GLEW_HP_texture_lighting;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"IBM_", 4))
+ {
+#ifdef GL_IBM_cull_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11))
+ {
+ ret = GLEW_IBM_cull_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_multimode_draw_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multimode_draw_arrays", 21))
+ {
+ ret = GLEW_IBM_multimode_draw_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_rasterpos_clip
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"rasterpos_clip", 14))
+ {
+ ret = GLEW_IBM_rasterpos_clip;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_static_data
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"static_data", 11))
+ {
+ ret = GLEW_IBM_static_data;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_texture_mirrored_repeat
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23))
+ {
+ ret = GLEW_IBM_texture_mirrored_repeat;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_vertex_array_lists
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_lists", 18))
+ {
+ ret = GLEW_IBM_vertex_array_lists;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"INGR_", 5))
+ {
+#ifdef GL_INGR_color_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_clamp", 11))
+ {
+ ret = GLEW_INGR_color_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_INGR_interlace_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace_read", 14))
+ {
+ ret = GLEW_INGR_interlace_read;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6))
+ {
+#ifdef GL_INTEL_conservative_rasterization
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_rasterization", 26))
+ {
+ ret = GLEW_INTEL_conservative_rasterization;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_fragment_shader_ordering
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_ordering", 24))
+ {
+ ret = GLEW_INTEL_fragment_shader_ordering;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_framebuffer_CMAA
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_CMAA", 16))
+ {
+ ret = GLEW_INTEL_framebuffer_CMAA;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_map_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_texture", 11))
+ {
+ ret = GLEW_INTEL_map_texture;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_parallel_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15))
+ {
+ ret = GLEW_INTEL_parallel_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_performance_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_query", 17))
+ {
+ ret = GLEW_INTEL_performance_query;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_texture_scissor
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scissor", 15))
+ {
+ ret = GLEW_INTEL_texture_scissor;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"KHR_", 4))
+ {
+#ifdef GL_KHR_blend_equation_advanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced", 23))
+ {
+ ret = GLEW_KHR_blend_equation_advanced;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_blend_equation_advanced_coherent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_coherent", 32))
+ {
+ ret = GLEW_KHR_blend_equation_advanced_coherent;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_context_flush_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"context_flush_control", 21))
+ {
+ ret = GLEW_KHR_context_flush_control;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_debug
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug", 5))
+ {
+ ret = GLEW_KHR_debug;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_no_error
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"no_error", 8))
+ {
+ ret = GLEW_KHR_no_error;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_parallel_shader_compile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_shader_compile", 23))
+ {
+ ret = GLEW_KHR_parallel_shader_compile;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_robust_buffer_access_behavior
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robust_buffer_access_behavior", 29))
+ {
+ ret = GLEW_KHR_robust_buffer_access_behavior;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness", 10))
+ {
+ ret = GLEW_KHR_robustness;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_texture_compression_astc_hdr
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_hdr", 28))
+ {
+ ret = GLEW_KHR_texture_compression_astc_hdr;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_texture_compression_astc_ldr
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_ldr", 28))
+ {
+ ret = GLEW_KHR_texture_compression_astc_ldr;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_texture_compression_astc_sliced_3d
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_sliced_3d", 34))
+ {
+ ret = GLEW_KHR_texture_compression_astc_sliced_3d;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4))
+ {
+#ifdef GL_KTX_buffer_region
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13))
+ {
+ ret = GLEW_KTX_buffer_region;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESAX_", 6))
+ {
+#ifdef GL_MESAX_texture_stack
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stack", 13))
+ {
+ ret = GLEW_MESAX_texture_stack;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5))
+ {
+#ifdef GL_MESA_pack_invert
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_invert", 11))
+ {
+ ret = GLEW_MESA_pack_invert;
+ continue;
+ }
+#endif
+#ifdef GL_MESA_resize_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"resize_buffers", 14))
+ {
+ ret = GLEW_MESA_resize_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_MESA_shader_integer_functions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_integer_functions", 24))
+ {
+ ret = GLEW_MESA_shader_integer_functions;
+ continue;
+ }
+#endif
+#ifdef GL_MESA_window_pos
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10))
+ {
+ ret = GLEW_MESA_window_pos;
+ continue;
+ }
+#endif
+#ifdef GL_MESA_ycbcr_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_texture", 13))
+ {
+ ret = GLEW_MESA_ycbcr_texture;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NVX_", 4))
+ {
+#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_multi_draw_buffers", 42))
+ {
+ ret = GLEW_NVX_blend_equation_advanced_multi_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_NVX_conditional_render
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18))
+ {
+ ret = GLEW_NVX_conditional_render;
+ continue;
+ }
+#endif
+#ifdef GL_NVX_gpu_memory_info
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_memory_info", 15))
+ {
+ ret = GLEW_NVX_gpu_memory_info;
+ continue;
+ }
+#endif
+#ifdef GL_NVX_linked_gpu_multicast
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"linked_gpu_multicast", 20))
+ {
+ ret = GLEW_NVX_linked_gpu_multicast;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef GL_NV_3dvision_settings
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3dvision_settings", 17))
+ {
+ ret = GLEW_NV_3dvision_settings;
+ continue;
+ }
+#endif
+#ifdef GL_NV_EGL_stream_consumer_external
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"EGL_stream_consumer_external", 28))
+ {
+ ret = GLEW_NV_EGL_stream_consumer_external;
+ continue;
+ }
+#endif
+#ifdef GL_NV_alpha_to_coverage_dither_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"alpha_to_coverage_dither_control", 32))
+ {
+ ret = GLEW_NV_alpha_to_coverage_dither_control;
+ continue;
+ }
+#endif
+#ifdef GL_NV_bgr
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgr", 3))
+ {
+ ret = GLEW_NV_bgr;
+ continue;
+ }
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_multi_draw_indirect", 28))
+ {
+ ret = GLEW_NV_bindless_multi_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_NV_bindless_multi_draw_indirect_count
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_multi_draw_indirect_count", 34))
+ {
+ ret = GLEW_NV_bindless_multi_draw_indirect_count;
+ continue;
+ }
+#endif
+#ifdef GL_NV_bindless_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16))
+ {
+ ret = GLEW_NV_bindless_texture;
+ continue;
+ }
+#endif
+#ifdef GL_NV_blend_equation_advanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced", 23))
+ {
+ ret = GLEW_NV_blend_equation_advanced;
+ continue;
+ }
+#endif
+#ifdef GL_NV_blend_equation_advanced_coherent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_coherent", 32))
+ {
+ ret = GLEW_NV_blend_equation_advanced_coherent;
+ continue;
+ }
+#endif
+#ifdef GL_NV_blend_minmax_factor
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax_factor", 19))
+ {
+ ret = GLEW_NV_blend_minmax_factor;
+ continue;
+ }
+#endif
+#ifdef GL_NV_blend_square
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12))
+ {
+ ret = GLEW_NV_blend_square;
+ continue;
+ }
+#endif
+#ifdef GL_NV_clip_space_w_scaling
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_space_w_scaling", 20))
+ {
+ ret = GLEW_NV_clip_space_w_scaling;
+ continue;
+ }
+#endif
+#ifdef GL_NV_command_list
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"command_list", 12))
+ {
+ ret = GLEW_NV_command_list;
+ continue;
+ }
+#endif
+#ifdef GL_NV_compute_program5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_program5", 16))
+ {
+ ret = GLEW_NV_compute_program5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_conditional_render
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18))
+ {
+ ret = GLEW_NV_conditional_render;
+ continue;
+ }
+#endif
+#ifdef GL_NV_conservative_raster
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_raster", 19))
+ {
+ ret = GLEW_NV_conservative_raster;
+ continue;
+ }
+#endif
+#ifdef GL_NV_conservative_raster_dilate
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_raster_dilate", 26))
+ {
+ ret = GLEW_NV_conservative_raster_dilate;
+ continue;
+ }
+#endif
+#ifdef GL_NV_conservative_raster_pre_snap_triangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_raster_pre_snap_triangles", 38))
+ {
+ ret = GLEW_NV_conservative_raster_pre_snap_triangles;
+ continue;
+ }
+#endif
+#ifdef GL_NV_copy_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11))
+ {
+ ret = GLEW_NV_copy_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_NV_copy_depth_to_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19))
+ {
+ ret = GLEW_NV_copy_depth_to_color;
+ continue;
+ }
+#endif
+#ifdef GL_NV_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = GLEW_NV_copy_image;
+ continue;
+ }
+#endif
+#ifdef GL_NV_deep_texture3D
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"deep_texture3D", 14))
+ {
+ ret = GLEW_NV_deep_texture3D;
+ continue;
+ }
+#endif
+#ifdef GL_NV_depth_buffer_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18))
+ {
+ ret = GLEW_NV_depth_buffer_float;
+ continue;
+ }
+#endif
+#ifdef GL_NV_depth_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11))
+ {
+ ret = GLEW_NV_depth_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_NV_depth_range_unclamped
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_range_unclamped", 21))
+ {
+ ret = GLEW_NV_depth_range_unclamped;
+ continue;
+ }
+#endif
+#ifdef GL_NV_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12))
+ {
+ ret = GLEW_NV_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_NV_draw_instanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14))
+ {
+ ret = GLEW_NV_draw_instanced;
+ continue;
+ }
+#endif
+#ifdef GL_NV_draw_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_texture", 12))
+ {
+ ret = GLEW_NV_draw_texture;
+ continue;
+ }
+#endif
+#ifdef GL_NV_draw_vulkan_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_vulkan_image", 17))
+ {
+ ret = GLEW_NV_draw_vulkan_image;
+ continue;
+ }
+#endif
+#ifdef GL_NV_evaluators
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10))
+ {
+ ret = GLEW_NV_evaluators;
+ continue;
+ }
+#endif
+#ifdef GL_NV_explicit_attrib_location
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_attrib_location", 24))
+ {
+ ret = GLEW_NV_explicit_attrib_location;
+ continue;
+ }
+#endif
+#ifdef GL_NV_explicit_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_multisample", 20))
+ {
+ ret = GLEW_NV_explicit_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fbo_color_attachments
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbo_color_attachments", 21))
+ {
+ ret = GLEW_NV_fbo_color_attachments;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fence
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5))
+ {
+ ret = GLEW_NV_fence;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fill_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fill_rectangle", 14))
+ {
+ ret = GLEW_NV_fill_rectangle;
+ continue;
+ }
+#endif
+#ifdef GL_NV_float_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
+ {
+ ret = GLEW_NV_float_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fog_distance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_distance", 12))
+ {
+ ret = GLEW_NV_fog_distance;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_coverage_to_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_coverage_to_color", 26))
+ {
+ ret = GLEW_NV_fragment_coverage_to_color;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16))
+ {
+ ret = GLEW_NV_fragment_program;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program2", 17))
+ {
+ ret = GLEW_NV_fragment_program2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program4", 17))
+ {
+ ret = GLEW_NV_fragment_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program_option
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_option", 23))
+ {
+ ret = GLEW_NV_fragment_program_option;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_shader_interlock
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_interlock", 25))
+ {
+ ret = GLEW_NV_fragment_shader_interlock;
+ continue;
+ }
+#endif
+#ifdef GL_NV_framebuffer_blit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16))
+ {
+ ret = GLEW_NV_framebuffer_blit;
+ continue;
+ }
+#endif
+#ifdef GL_NV_framebuffer_mixed_samples
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_mixed_samples", 25))
+ {
+ ret = GLEW_NV_framebuffer_mixed_samples;
+ continue;
+ }
+#endif
+#ifdef GL_NV_framebuffer_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23))
+ {
+ ret = GLEW_NV_framebuffer_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_NV_framebuffer_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_coverage", 32))
+ {
+ ret = GLEW_NV_framebuffer_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef GL_NV_generate_mipmap_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap_sRGB", 20))
+ {
+ ret = GLEW_NV_generate_mipmap_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_NV_geometry_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_program4", 17))
+ {
+ ret = GLEW_NV_geometry_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_geometry_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16))
+ {
+ ret = GLEW_NV_geometry_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_geometry_shader_passthrough
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader_passthrough", 27))
+ {
+ ret = GLEW_NV_geometry_shader_passthrough;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_multicast
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_multicast", 13))
+ {
+ ret = GLEW_NV_gpu_multicast;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program4", 12))
+ {
+ ret = GLEW_NV_gpu_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5", 12))
+ {
+ ret = GLEW_NV_gpu_program5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program5_mem_extended
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5_mem_extended", 25))
+ {
+ ret = GLEW_NV_gpu_program5_mem_extended;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program_fp64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_fp64", 16))
+ {
+ ret = GLEW_NV_gpu_program_fp64;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_shader5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11))
+ {
+ ret = GLEW_NV_gpu_shader5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_half_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float", 10))
+ {
+ ret = GLEW_NV_half_float;
+ continue;
+ }
+#endif
+#ifdef GL_NV_image_formats
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_formats", 13))
+ {
+ ret = GLEW_NV_image_formats;
+ continue;
+ }
+#endif
+#ifdef GL_NV_instanced_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16))
+ {
+ ret = GLEW_NV_instanced_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_NV_internalformat_sample_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_sample_query", 27))
+ {
+ ret = GLEW_NV_internalformat_sample_query;
+ continue;
+ }
+#endif
+#ifdef GL_NV_light_max_exponent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_max_exponent", 18))
+ {
+ ret = GLEW_NV_light_max_exponent;
+ continue;
+ }
+#endif
+#ifdef GL_NV_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20))
+ {
+ ret = GLEW_NV_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef GL_NV_multisample_filter_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_filter_hint", 23))
+ {
+ ret = GLEW_NV_multisample_filter_hint;
+ continue;
+ }
+#endif
+#ifdef GL_NV_non_square_matrices
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"non_square_matrices", 19))
+ {
+ ret = GLEW_NV_non_square_matrices;
+ continue;
+ }
+#endif
+#ifdef GL_NV_occlusion_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15))
+ {
+ ret = GLEW_NV_occlusion_query;
+ continue;
+ }
+#endif
+#ifdef GL_NV_pack_subimage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_subimage", 13))
+ {
+ ret = GLEW_NV_pack_subimage;
+ continue;
+ }
+#endif
+#ifdef GL_NV_packed_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20))
+ {
+ ret = GLEW_NV_packed_depth_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_NV_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12))
+ {
+ ret = GLEW_NV_packed_float;
+ continue;
+ }
+#endif
+#ifdef GL_NV_packed_float_linear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float_linear", 19))
+ {
+ ret = GLEW_NV_packed_float_linear;
+ continue;
+ }
+#endif
+#ifdef GL_NV_parameter_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object", 23))
+ {
+ ret = GLEW_NV_parameter_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_NV_parameter_buffer_object2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object2", 24))
+ {
+ ret = GLEW_NV_parameter_buffer_object2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_path_rendering
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"path_rendering", 14))
+ {
+ ret = GLEW_NV_path_rendering;
+ continue;
+ }
+#endif
+#ifdef GL_NV_path_rendering_shared_edge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"path_rendering_shared_edge", 26))
+ {
+ ret = GLEW_NV_path_rendering_shared_edge;
+ continue;
+ }
+#endif
+#ifdef GL_NV_pixel_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19))
+ {
+ ret = GLEW_NV_pixel_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_NV_pixel_data_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16))
+ {
+ ret = GLEW_NV_pixel_data_range;
+ continue;
+ }
+#endif
+#ifdef GL_NV_platform_binary
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_binary", 15))
+ {
+ ret = GLEW_NV_platform_binary;
+ continue;
+ }
+#endif
+#ifdef GL_NV_point_sprite
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12))
+ {
+ ret = GLEW_NV_point_sprite;
+ continue;
+ }
+#endif
+#ifdef GL_NV_polygon_mode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_mode", 12))
+ {
+ ret = GLEW_NV_polygon_mode;
+ continue;
+ }
+#endif
+#ifdef GL_NV_present_video
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13))
+ {
+ ret = GLEW_NV_present_video;
+ continue;
+ }
+#endif
+#ifdef GL_NV_primitive_restart
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"primitive_restart", 17))
+ {
+ ret = GLEW_NV_primitive_restart;
+ continue;
+ }
+#endif
+#ifdef GL_NV_read_depth
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_depth", 10))
+ {
+ ret = GLEW_NV_read_depth;
+ continue;
+ }
+#endif
+#ifdef GL_NV_read_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_depth_stencil", 18))
+ {
+ ret = GLEW_NV_read_depth_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_NV_read_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_stencil", 12))
+ {
+ ret = GLEW_NV_read_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_NV_register_combiners
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners", 18))
+ {
+ ret = GLEW_NV_register_combiners;
+ continue;
+ }
+#endif
+#ifdef GL_NV_register_combiners2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners2", 19))
+ {
+ ret = GLEW_NV_register_combiners2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_video_memory_purge", 29))
+ {
+ ret = GLEW_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
+#ifdef GL_NV_sRGB_formats
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sRGB_formats", 12))
+ {
+ ret = GLEW_NV_sRGB_formats;
+ continue;
+ }
+#endif
+#ifdef GL_NV_sample_locations
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_locations", 16))
+ {
+ ret = GLEW_NV_sample_locations;
+ continue;
+ }
+#endif
+#ifdef GL_NV_sample_mask_override_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_mask_override_coverage", 29))
+ {
+ ret = GLEW_NV_sample_mask_override_coverage;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_atomic_counters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22))
+ {
+ ret = GLEW_NV_shader_atomic_counters;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_atomic_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_float", 19))
+ {
+ ret = GLEW_NV_shader_atomic_float;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_atomic_float64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_float64", 21))
+ {
+ ret = GLEW_NV_shader_atomic_float64;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_atomic_fp16_vector
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_fp16_vector", 25))
+ {
+ ret = GLEW_NV_shader_atomic_fp16_vector;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_atomic_int64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_int64", 19))
+ {
+ ret = GLEW_NV_shader_atomic_int64;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_buffer_load
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_buffer_load", 18))
+ {
+ ret = GLEW_NV_shader_buffer_load;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_noperspective_interpolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_noperspective_interpolation", 34))
+ {
+ ret = GLEW_NV_shader_noperspective_interpolation;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_storage_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28))
+ {
+ ret = GLEW_NV_shader_storage_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_thread_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_thread_group", 19))
+ {
+ ret = GLEW_NV_shader_thread_group;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_thread_shuffle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_thread_shuffle", 21))
+ {
+ ret = GLEW_NV_shader_thread_shuffle;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shadow_samplers_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_samplers_array", 21))
+ {
+ ret = GLEW_NV_shadow_samplers_array;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shadow_samplers_cube
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_samplers_cube", 20))
+ {
+ ret = GLEW_NV_shadow_samplers_cube;
+ continue;
+ }
+#endif
+#ifdef GL_NV_stereo_view_rendering
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_view_rendering", 21))
+ {
+ ret = GLEW_NV_stereo_view_rendering;
+ continue;
+ }
+#endif
+#ifdef GL_NV_tessellation_program5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_program5", 21))
+ {
+ ret = GLEW_NV_tessellation_program5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texgen_emboss
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13))
+ {
+ ret = GLEW_NV_texgen_emboss;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texgen_reflection
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_reflection", 17))
+ {
+ ret = GLEW_NV_texgen_reflection;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13))
+ {
+ ret = GLEW_NV_texture_array;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_barrier
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_barrier", 15))
+ {
+ ret = GLEW_NV_texture_barrier;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_border_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20))
+ {
+ ret = GLEW_NV_texture_border_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_compression_latc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24))
+ {
+ ret = GLEW_NV_texture_compression_latc;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_compression_s3tc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24))
+ {
+ ret = GLEW_NV_texture_compression_s3tc;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_compression_s3tc_update
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc_update", 31))
+ {
+ ret = GLEW_NV_texture_compression_s3tc_update;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_compression_vtc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23))
+ {
+ ret = GLEW_NV_texture_compression_vtc;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_env_combine4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine4", 20))
+ {
+ ret = GLEW_NV_texture_env_combine4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_expand_normal
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_expand_normal", 21))
+ {
+ ret = GLEW_NV_texture_expand_normal;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19))
+ {
+ ret = GLEW_NV_texture_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_npot_2D_mipmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_npot_2D_mipmap", 22))
+ {
+ ret = GLEW_NV_texture_npot_2D_mipmap;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17))
+ {
+ ret = GLEW_NV_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_rectangle_compressed
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle_compressed", 28))
+ {
+ ret = GLEW_NV_texture_rectangle_compressed;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader", 14))
+ {
+ ret = GLEW_NV_texture_shader;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_shader2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader2", 15))
+ {
+ ret = GLEW_NV_texture_shader2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_shader3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader3", 15))
+ {
+ ret = GLEW_NV_texture_shader3;
+ continue;
+ }
+#endif
+#ifdef GL_NV_transform_feedback
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18))
+ {
+ ret = GLEW_NV_transform_feedback;
+ continue;
+ }
+#endif
+#ifdef GL_NV_transform_feedback2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19))
+ {
+ ret = GLEW_NV_transform_feedback2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_uniform_buffer_unified_memory
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"uniform_buffer_unified_memory", 29))
+ {
+ ret = GLEW_NV_uniform_buffer_unified_memory;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vdpau_interop
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vdpau_interop", 13))
+ {
+ ret = GLEW_NV_vdpau_interop;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = GLEW_NV_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_array_range2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range2", 19))
+ {
+ ret = GLEW_NV_vertex_array_range2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_integer_64bit", 27))
+ {
+ ret = GLEW_NV_vertex_attrib_integer_64bit;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_buffer_unified_memory
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_unified_memory", 28))
+ {
+ ret = GLEW_NV_vertex_buffer_unified_memory;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14))
+ {
+ ret = GLEW_NV_vertex_program;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program1_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program1_1", 17))
+ {
+ ret = GLEW_NV_vertex_program1_1;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2", 15))
+ {
+ ret = GLEW_NV_vertex_program2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program2_option
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2_option", 22))
+ {
+ ret = GLEW_NV_vertex_program2_option;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program3", 15))
+ {
+ ret = GLEW_NV_vertex_program3;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program4", 15))
+ {
+ ret = GLEW_NV_vertex_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_video_capture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13))
+ {
+ ret = GLEW_NV_video_capture;
+ continue;
+ }
+#endif
+#ifdef GL_NV_viewport_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array", 14))
+ {
+ ret = GLEW_NV_viewport_array;
+ continue;
+ }
+#endif
+#ifdef GL_NV_viewport_array2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array2", 15))
+ {
+ ret = GLEW_NV_viewport_array2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_viewport_swizzle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_swizzle", 16))
+ {
+ ret = GLEW_NV_viewport_swizzle;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OES_", 4))
+ {
+#ifdef GL_OES_byte_coordinates
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"byte_coordinates", 16))
+ {
+ ret = GLEW_OES_byte_coordinates;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4))
+ {
+#ifdef GL_OML_interlace
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9))
+ {
+ ret = GLEW_OML_interlace;
+ continue;
+ }
+#endif
+#ifdef GL_OML_resample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8))
+ {
+ ret = GLEW_OML_resample;
+ continue;
+ }
+#endif
+#ifdef GL_OML_subsample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9))
+ {
+ ret = GLEW_OML_subsample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OVR_", 4))
+ {
+#ifdef GL_OVR_multiview
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview", 9))
+ {
+ ret = GLEW_OVR_multiview;
+ continue;
+ }
+#endif
+#ifdef GL_OVR_multiview2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview2", 10))
+ {
+ ret = GLEW_OVR_multiview2;
+ continue;
+ }
+#endif
+#ifdef GL_OVR_multiview_multisampled_render_to_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview_multisampled_render_to_texture", 40))
+ {
+ ret = GLEW_OVR_multiview_multisampled_render_to_texture;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"PGI_", 4))
+ {
+#ifdef GL_PGI_misc_hints
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_hints", 10))
+ {
+ ret = GLEW_PGI_misc_hints;
+ continue;
+ }
+#endif
+#ifdef GL_PGI_vertex_hints
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_hints", 12))
+ {
+ ret = GLEW_PGI_vertex_hints;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"QCOM_", 5))
+ {
+#ifdef GL_QCOM_alpha_test
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"alpha_test", 10))
+ {
+ ret = GLEW_QCOM_alpha_test;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_binning_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"binning_control", 15))
+ {
+ ret = GLEW_QCOM_binning_control;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_driver_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"driver_control", 14))
+ {
+ ret = GLEW_QCOM_driver_control;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_extended_get
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extended_get", 12))
+ {
+ ret = GLEW_QCOM_extended_get;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_extended_get2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extended_get2", 13))
+ {
+ ret = GLEW_QCOM_extended_get2;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_framebuffer_foveated
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_foveated", 20))
+ {
+ ret = GLEW_QCOM_framebuffer_foveated;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_perfmon_global_mode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"perfmon_global_mode", 19))
+ {
+ ret = GLEW_QCOM_perfmon_global_mode;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch_noncoherent", 36))
+ {
+ ret = GLEW_QCOM_shader_framebuffer_fetch_noncoherent;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_tiled_rendering
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tiled_rendering", 15))
+ {
+ ret = GLEW_QCOM_tiled_rendering;
+ continue;
+ }
+#endif
+#ifdef GL_QCOM_writeonly_rendering
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"writeonly_rendering", 19))
+ {
+ ret = GLEW_QCOM_writeonly_rendering;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"REGAL_", 6))
+ {
+#ifdef GL_REGAL_ES1_0_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_0_compatibility", 19))
+ {
+ ret = GLEW_REGAL_ES1_0_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_ES1_1_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_1_compatibility", 19))
+ {
+ ret = GLEW_REGAL_ES1_1_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_enable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"enable", 6))
+ {
+ ret = GLEW_REGAL_enable;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_error_string
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"error_string", 12))
+ {
+ ret = GLEW_REGAL_error_string;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_extension_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extension_query", 15))
+ {
+ ret = GLEW_REGAL_extension_query;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_log
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"log", 3))
+ {
+ ret = GLEW_REGAL_log;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_proc_address
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"proc_address", 12))
+ {
+ ret = GLEW_REGAL_proc_address;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"REND_", 5))
+ {
+#ifdef GL_REND_screen_coordinates
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"screen_coordinates", 18))
+ {
+ ret = GLEW_REND_screen_coordinates;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"S3_", 3))
+ {
+#ifdef GL_S3_s3tc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"s3tc", 4))
+ {
+ ret = GLEW_S3_s3tc;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5))
+ {
+#ifdef GL_SGIS_clip_band_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_band_hint", 14))
+ {
+ ret = GLEW_SGIS_clip_band_hint;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_color_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11))
+ {
+ ret = GLEW_SGIS_color_range;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_detail_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"detail_texture", 14))
+ {
+ ret = GLEW_SGIS_detail_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_fog_function
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_function", 12))
+ {
+ ret = GLEW_SGIS_fog_function;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_generate_mipmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap", 15))
+ {
+ ret = GLEW_SGIS_generate_mipmap;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_line_texgen
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"line_texgen", 11))
+ {
+ ret = GLEW_SGIS_line_texgen;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_SGIS_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_multitexture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12))
+ {
+ ret = GLEW_SGIS_multitexture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_pixel_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13))
+ {
+ ret = GLEW_SGIS_pixel_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_point_line_texgen
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_line_texgen", 17))
+ {
+ ret = GLEW_SGIS_point_line_texgen;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_shared_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18))
+ {
+ ret = GLEW_SGIS_shared_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_sharpen_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sharpen_texture", 15))
+ {
+ ret = GLEW_SGIS_sharpen_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture4D
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture4D", 9))
+ {
+ ret = GLEW_SGIS_texture4D;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_border_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20))
+ {
+ ret = GLEW_SGIS_texture_border_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_edge_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18))
+ {
+ ret = GLEW_SGIS_texture_edge_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_filter4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter4", 15))
+ {
+ ret = GLEW_SGIS_texture_filter4;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod", 11))
+ {
+ ret = GLEW_SGIS_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_select
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_select", 14))
+ {
+ ret = GLEW_SGIS_texture_select;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5))
+ {
+#ifdef GL_SGIX_async
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"async", 5))
+ {
+ ret = GLEW_SGIX_async;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_async_histogram
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_histogram", 15))
+ {
+ ret = GLEW_SGIX_async_histogram;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_async_pixel
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_pixel", 11))
+ {
+ ret = GLEW_SGIX_async_pixel;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_bali_g_instruments
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bali_g_instruments", 18))
+ {
+ ret = GLEW_SGIX_bali_g_instruments;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_bali_r_instruments
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bali_r_instruments", 18))
+ {
+ ret = GLEW_SGIX_bali_r_instruments;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_bali_timer_instruments
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bali_timer_instruments", 22))
+ {
+ ret = GLEW_SGIX_bali_timer_instruments;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_blend_alpha_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_alpha_minmax", 18))
+ {
+ ret = GLEW_SGIX_blend_alpha_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_blend_cadd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_cadd", 10))
+ {
+ ret = GLEW_SGIX_blend_cadd;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_blend_cmultiply
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_cmultiply", 15))
+ {
+ ret = GLEW_SGIX_blend_cmultiply;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_calligraphic_fragment
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"calligraphic_fragment", 21))
+ {
+ ret = GLEW_SGIX_calligraphic_fragment;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_clipmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clipmap", 7))
+ {
+ ret = GLEW_SGIX_clipmap;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_color_matrix_accuracy
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix_accuracy", 21))
+ {
+ ret = GLEW_SGIX_color_matrix_accuracy;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_color_table_index_mode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table_index_mode", 22))
+ {
+ ret = GLEW_SGIX_color_table_index_mode;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_complex_polar
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"complex_polar", 13))
+ {
+ ret = GLEW_SGIX_complex_polar;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_convolution_accuracy
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_accuracy", 20))
+ {
+ ret = GLEW_SGIX_convolution_accuracy;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_cube_map
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cube_map", 8))
+ {
+ ret = GLEW_SGIX_cube_map;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_cylinder_texgen
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cylinder_texgen", 15))
+ {
+ ret = GLEW_SGIX_cylinder_texgen;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_datapipe
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"datapipe", 8))
+ {
+ ret = GLEW_SGIX_datapipe;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_decimation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"decimation", 10))
+ {
+ ret = GLEW_SGIX_decimation;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_depth_pass_instrument
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_pass_instrument", 21))
+ {
+ ret = GLEW_SGIX_depth_pass_instrument;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13))
+ {
+ ret = GLEW_SGIX_depth_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_dvc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"dvc", 3))
+ {
+ ret = GLEW_SGIX_dvc;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_flush_raster
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_raster", 12))
+ {
+ ret = GLEW_SGIX_flush_raster;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_blend", 9))
+ {
+ ret = GLEW_SGIX_fog_blend;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_factor_to_alpha
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_factor_to_alpha", 19))
+ {
+ ret = GLEW_SGIX_fog_factor_to_alpha;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_layers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_layers", 10))
+ {
+ ret = GLEW_SGIX_fog_layers;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_offset
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_offset", 10))
+ {
+ ret = GLEW_SGIX_fog_offset;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_patchy
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_patchy", 10))
+ {
+ ret = GLEW_SGIX_fog_patchy;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_scale
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_scale", 9))
+ {
+ ret = GLEW_SGIX_fog_scale;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_texture", 11))
+ {
+ ret = GLEW_SGIX_fog_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fragment_lighting_space
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting_space", 23))
+ {
+ ret = GLEW_SGIX_fragment_lighting_space;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fragment_specular_lighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_specular_lighting", 26))
+ {
+ ret = GLEW_SGIX_fragment_specular_lighting;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fragments_instrument
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragments_instrument", 20))
+ {
+ ret = GLEW_SGIX_fragments_instrument;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_framezoom
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framezoom", 9))
+ {
+ ret = GLEW_SGIX_framezoom;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_icc_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"icc_texture", 11))
+ {
+ ret = GLEW_SGIX_icc_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_igloo_interface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"igloo_interface", 15))
+ {
+ ret = GLEW_SGIX_igloo_interface;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_image_compression
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_compression", 17))
+ {
+ ret = GLEW_SGIX_image_compression;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_impact_pixel_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"impact_pixel_texture", 20))
+ {
+ ret = GLEW_SGIX_impact_pixel_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_instrument_error
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"instrument_error", 16))
+ {
+ ret = GLEW_SGIX_instrument_error;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_interlace
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9))
+ {
+ ret = GLEW_SGIX_interlace;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_ir_instrument1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ir_instrument1", 14))
+ {
+ ret = GLEW_SGIX_ir_instrument1;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_line_quality_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"line_quality_hint", 17))
+ {
+ ret = GLEW_SGIX_line_quality_hint;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_list_priority
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"list_priority", 13))
+ {
+ ret = GLEW_SGIX_list_priority;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_mpeg1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mpeg1", 5))
+ {
+ ret = GLEW_SGIX_mpeg1;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_mpeg2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mpeg2", 5))
+ {
+ ret = GLEW_SGIX_mpeg2;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_nonlinear_lighting_pervertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"nonlinear_lighting_pervertex", 28))
+ {
+ ret = GLEW_SGIX_nonlinear_lighting_pervertex;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_nurbs_eval
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"nurbs_eval", 10))
+ {
+ ret = GLEW_SGIX_nurbs_eval;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_occlusion_instrument
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_instrument", 20))
+ {
+ ret = GLEW_SGIX_occlusion_instrument;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_packed_6bytes
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_6bytes", 13))
+ {
+ ret = GLEW_SGIX_packed_6bytes;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_pixel_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13))
+ {
+ ret = GLEW_SGIX_pixel_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_pixel_texture_bits
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_bits", 18))
+ {
+ ret = GLEW_SGIX_pixel_texture_bits;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_pixel_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_lod", 17))
+ {
+ ret = GLEW_SGIX_pixel_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_pixel_tiles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_tiles", 11))
+ {
+ ret = GLEW_SGIX_pixel_tiles;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_polynomial_ffd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"polynomial_ffd", 14))
+ {
+ ret = GLEW_SGIX_polynomial_ffd;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_quad_mesh
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"quad_mesh", 9))
+ {
+ ret = GLEW_SGIX_quad_mesh;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_reference_plane
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"reference_plane", 15))
+ {
+ ret = GLEW_SGIX_reference_plane;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_resample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8))
+ {
+ ret = GLEW_SGIX_resample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_scalebias_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"scalebias_hint", 14))
+ {
+ ret = GLEW_SGIX_scalebias_hint;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_shadow
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6))
+ {
+ ret = GLEW_SGIX_shadow;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_shadow_ambient
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14))
+ {
+ ret = GLEW_SGIX_shadow_ambient;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_slim
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"slim", 4))
+ {
+ ret = GLEW_SGIX_slim;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_spotlight_cutoff
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"spotlight_cutoff", 16))
+ {
+ ret = GLEW_SGIX_spotlight_cutoff;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_sprite
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sprite", 6))
+ {
+ ret = GLEW_SGIX_sprite;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_subdiv_patch
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"subdiv_patch", 12))
+ {
+ ret = GLEW_SGIX_subdiv_patch;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_subsample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9))
+ {
+ ret = GLEW_SGIX_subsample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_tag_sample_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tag_sample_buffer", 17))
+ {
+ ret = GLEW_SGIX_tag_sample_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_add_env
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_add_env", 15))
+ {
+ ret = GLEW_SGIX_texture_add_env;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_coordinate_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_coordinate_clamp", 24))
+ {
+ ret = GLEW_SGIX_texture_coordinate_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_lod_bias
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16))
+ {
+ ret = GLEW_SGIX_texture_lod_bias;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_mipmap_anisotropic
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mipmap_anisotropic", 26))
+ {
+ ret = GLEW_SGIX_texture_mipmap_anisotropic;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_multi_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multi_buffer", 20))
+ {
+ ret = GLEW_SGIX_texture_multi_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_phase
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_phase", 13))
+ {
+ ret = GLEW_SGIX_texture_phase;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13))
+ {
+ ret = GLEW_SGIX_texture_range;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_scale_bias
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scale_bias", 18))
+ {
+ ret = GLEW_SGIX_texture_scale_bias;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_supersample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_supersample", 19))
+ {
+ ret = GLEW_SGIX_texture_supersample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_vector_ops
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vector_ops", 10))
+ {
+ ret = GLEW_SGIX_vector_ops;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_vertex_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
+ {
+ ret = GLEW_SGIX_vertex_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_vertex_preclip
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip", 14))
+ {
+ ret = GLEW_SGIX_vertex_preclip;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_vertex_preclip_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip_hint", 19))
+ {
+ ret = GLEW_SGIX_vertex_preclip_hint;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_ycrcb
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb", 5))
+ {
+ ret = GLEW_SGIX_ycrcb;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_ycrcb_subsample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb_subsample", 15))
+ {
+ ret = GLEW_SGIX_ycrcb_subsample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_ycrcba
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcba", 6))
+ {
+ ret = GLEW_SGIX_ycrcba;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4))
+ {
+#ifdef GL_SGI_color_matrix
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix", 12))
+ {
+ ret = GLEW_SGI_color_matrix;
+ continue;
+ }
+#endif
+#ifdef GL_SGI_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table", 11))
+ {
+ ret = GLEW_SGI_color_table;
+ continue;
+ }
+#endif
+#ifdef GL_SGI_complex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"complex", 7))
+ {
+ ret = GLEW_SGI_complex;
+ continue;
+ }
+#endif
+#ifdef GL_SGI_complex_type
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"complex_type", 12))
+ {
+ ret = GLEW_SGI_complex_type;
+ continue;
+ }
+#endif
+#ifdef GL_SGI_fft
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fft", 3))
+ {
+ ret = GLEW_SGI_fft;
+ continue;
+ }
+#endif
+#ifdef GL_SGI_texture_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_color_table", 19))
+ {
+ ret = GLEW_SGI_texture_color_table;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUNX_", 5))
+ {
+#ifdef GL_SUNX_constant_data
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"constant_data", 13))
+ {
+ ret = GLEW_SUNX_constant_data;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4))
+ {
+#ifdef GL_SUN_convolution_border_modes
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24))
+ {
+ ret = GLEW_SUN_convolution_border_modes;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_global_alpha
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"global_alpha", 12))
+ {
+ ret = GLEW_SUN_global_alpha;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_mesh_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mesh_array", 10))
+ {
+ ret = GLEW_SUN_mesh_array;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_read_video_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_video_pixels", 17))
+ {
+ ret = GLEW_SUN_read_video_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_slice_accum
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"slice_accum", 11))
+ {
+ ret = GLEW_SUN_slice_accum;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_triangle_list
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"triangle_list", 13))
+ {
+ ret = GLEW_SUN_triangle_list;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex", 6))
+ {
+ ret = GLEW_SUN_vertex;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"WIN_", 4))
+ {
+#ifdef GL_WIN_phong_shading
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"phong_shading", 13))
+ {
+ ret = GLEW_WIN_phong_shading;
+ continue;
+ }
+#endif
+#ifdef GL_WIN_scene_markerXXX
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_markerXXX", 15))
+ {
+ ret = GLEW_WIN_scene_markerXXX;
+ continue;
+ }
+#endif
+#ifdef GL_WIN_specular_fog
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_fog", 12))
+ {
+ ret = GLEW_WIN_specular_fog;
+ continue;
+ }
+#endif
+#ifdef GL_WIN_swap_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_hint", 9))
+ {
+ ret = GLEW_WIN_swap_hint;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
+#if defined(_WIN32) && !defined(GLEW_EGL) && !defined(GLEW_OSMESA)
+
+GLboolean GLEWAPIENTRY wglewIsSupported (const char* name)
+{
+ const GLubyte* pos = (const GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if (_glewStrSame1(&pos, &len, (const GLubyte*)"WGL_", 4))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5))
+ {
+#ifdef WGL_3DFX_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = WGLEW_3DFX_multisample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DL_", 4))
+ {
+#ifdef WGL_3DL_stereo_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_control", 14))
+ {
+ ret = WGLEW_3DL_stereo_control;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+ {
+#ifdef WGL_AMD_gpu_association
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_association", 15))
+ {
+ ret = WGLEW_AMD_gpu_association;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4))
+ {
+#ifdef WGL_ARB_buffer_region
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13))
+ {
+ ret = WGLEW_ARB_buffer_region;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_context_flush_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"context_flush_control", 21))
+ {
+ ret = WGLEW_ARB_context_flush_control;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_create_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14))
+ {
+ ret = WGLEW_ARB_create_context;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_create_context_no_error
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_no_error", 23))
+ {
+ ret = WGLEW_ARB_create_context_no_error;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_create_context_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22))
+ {
+ ret = WGLEW_ARB_create_context_profile;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_create_context_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25))
+ {
+ ret = WGLEW_ARB_create_context_robustness;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_extensions_string
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17))
+ {
+ ret = WGLEW_ARB_extensions_string;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = WGLEW_ARB_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_make_current_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17))
+ {
+ ret = WGLEW_ARB_make_current_read;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = WGLEW_ARB_multisample;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_pbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7))
+ {
+ ret = WGLEW_ARB_pbuffer;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_pixel_format
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12))
+ {
+ ret = WGLEW_ARB_pixel_format;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_pixel_format_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18))
+ {
+ ret = WGLEW_ARB_pixel_format_float;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_render_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14))
+ {
+ ret = WGLEW_ARB_render_texture;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_robustness_application_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32))
+ {
+ ret = WGLEW_ARB_robustness_application_isolation;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_robustness_share_group_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32))
+ {
+ ret = WGLEW_ARB_robustness_share_group_isolation;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4))
+ {
+#ifdef WGL_ATI_pixel_format_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18))
+ {
+ ret = WGLEW_ATI_pixel_format_float;
+ continue;
+ }
+#endif
+#ifdef WGL_ATI_render_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24))
+ {
+ ret = WGLEW_ATI_render_texture_rectangle;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef WGL_EXT_colorspace
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"colorspace", 10))
+ {
+ ret = WGLEW_EXT_colorspace;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_create_context_es2_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es2_profile", 26))
+ {
+ ret = WGLEW_EXT_create_context_es2_profile;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_create_context_es_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es_profile", 25))
+ {
+ ret = WGLEW_EXT_create_context_es_profile;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_depth_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_float", 11))
+ {
+ ret = WGLEW_EXT_depth_float;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_display_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"display_color_table", 19))
+ {
+ ret = WGLEW_EXT_display_color_table;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_extensions_string
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17))
+ {
+ ret = WGLEW_EXT_extensions_string;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = WGLEW_EXT_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_make_current_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17))
+ {
+ ret = WGLEW_EXT_make_current_read;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = WGLEW_EXT_multisample;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_pbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7))
+ {
+ ret = WGLEW_EXT_pbuffer;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_pixel_format
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12))
+ {
+ ret = WGLEW_EXT_pixel_format;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_pixel_format_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_packed_float", 25))
+ {
+ ret = WGLEW_EXT_pixel_format_packed_float;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = WGLEW_EXT_swap_control;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_swap_control_tear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control_tear", 17))
+ {
+ ret = WGLEW_EXT_swap_control_tear;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"I3D_", 4))
+ {
+#ifdef WGL_I3D_digital_video_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"digital_video_control", 21))
+ {
+ ret = WGLEW_I3D_digital_video_control;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_gamma
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gamma", 5))
+ {
+ ret = WGLEW_I3D_gamma;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_genlock
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"genlock", 7))
+ {
+ ret = WGLEW_I3D_genlock;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_image_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_buffer", 12))
+ {
+ ret = WGLEW_I3D_image_buffer;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_swap_frame_lock
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_lock", 15))
+ {
+ ret = WGLEW_I3D_swap_frame_lock;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_swap_frame_usage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_usage", 16))
+ {
+ ret = WGLEW_I3D_swap_frame_usage;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef WGL_NV_DX_interop
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"DX_interop", 10))
+ {
+ ret = WGLEW_NV_DX_interop;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_DX_interop2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"DX_interop2", 11))
+ {
+ ret = WGLEW_NV_DX_interop2;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = WGLEW_NV_copy_image;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_delay_before_swap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"delay_before_swap", 17))
+ {
+ ret = WGLEW_NV_delay_before_swap;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_float_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
+ {
+ ret = WGLEW_NV_float_buffer;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_gpu_affinity
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_affinity", 12))
+ {
+ ret = WGLEW_NV_gpu_affinity;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20))
+ {
+ ret = WGLEW_NV_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_present_video
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13))
+ {
+ ret = WGLEW_NV_present_video;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_render_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_depth_texture", 20))
+ {
+ ret = WGLEW_NV_render_depth_texture;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_render_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24))
+ {
+ ret = WGLEW_NV_render_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_swap_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10))
+ {
+ ret = WGLEW_NV_swap_group;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = WGLEW_NV_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_video_capture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13))
+ {
+ ret = WGLEW_NV_video_capture;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_video_output
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12))
+ {
+ ret = WGLEW_NV_video_output;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4))
+ {
+#ifdef WGL_OML_sync_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12))
+ {
+ ret = WGLEW_OML_sync_control;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
+#elif !defined(GLEW_OSMESA) && !defined(GLEW_EGL) && !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
+
+GLboolean glxewIsSupported (const char* name)
+{
+ const GLubyte* pos = (const GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if(_glewStrSame1(&pos, &len, (const GLubyte*)"GLX_", 4))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8))
+ {
+#ifdef GLX_VERSION_1_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3))
+ {
+ ret = GLXEW_VERSION_1_2;
+ continue;
+ }
+#endif
+#ifdef GLX_VERSION_1_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3))
+ {
+ ret = GLXEW_VERSION_1_3;
+ continue;
+ }
+#endif
+#ifdef GLX_VERSION_1_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3))
+ {
+ ret = GLXEW_VERSION_1_4;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5))
+ {
+#ifdef GLX_3DFX_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLXEW_3DFX_multisample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+ {
+#ifdef GLX_AMD_gpu_association
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_association", 15))
+ {
+ ret = GLXEW_AMD_gpu_association;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4))
+ {
+#ifdef GLX_ARB_context_flush_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"context_flush_control", 21))
+ {
+ ret = GLXEW_ARB_context_flush_control;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_create_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14))
+ {
+ ret = GLXEW_ARB_create_context;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_create_context_no_error
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_no_error", 23))
+ {
+ ret = GLXEW_ARB_create_context_no_error;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_create_context_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22))
+ {
+ ret = GLXEW_ARB_create_context_profile;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_create_context_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25))
+ {
+ ret = GLXEW_ARB_create_context_robustness;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_fbconfig_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_float", 14))
+ {
+ ret = GLXEW_ARB_fbconfig_float;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLXEW_ARB_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_get_proc_address
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_proc_address", 16))
+ {
+ ret = GLXEW_ARB_get_proc_address;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLXEW_ARB_multisample;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_robustness_application_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32))
+ {
+ ret = GLXEW_ARB_robustness_application_isolation;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_robustness_share_group_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32))
+ {
+ ret = GLXEW_ARB_robustness_share_group_isolation;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_vertex_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20))
+ {
+ ret = GLXEW_ARB_vertex_buffer_object;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4))
+ {
+#ifdef GLX_ATI_pixel_format_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18))
+ {
+ ret = GLXEW_ATI_pixel_format_float;
+ continue;
+ }
+#endif
+#ifdef GLX_ATI_render_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14))
+ {
+ ret = GLXEW_ATI_render_texture;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef GLX_EXT_buffer_age
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_age", 10))
+ {
+ ret = GLXEW_EXT_buffer_age;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_create_context_es2_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es2_profile", 26))
+ {
+ ret = GLXEW_EXT_create_context_es2_profile;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_create_context_es_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es_profile", 25))
+ {
+ ret = GLXEW_EXT_create_context_es_profile;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_fbconfig_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_packed_float", 21))
+ {
+ ret = GLXEW_EXT_fbconfig_packed_float;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLXEW_EXT_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_import_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"import_context", 14))
+ {
+ ret = GLXEW_EXT_import_context;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_libglvnd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"libglvnd", 8))
+ {
+ ret = GLXEW_EXT_libglvnd;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_scene_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12))
+ {
+ ret = GLXEW_EXT_scene_marker;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_stereo_tree
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_tree", 11))
+ {
+ ret = GLXEW_EXT_stereo_tree;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = GLXEW_EXT_swap_control;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_swap_control_tear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control_tear", 17))
+ {
+ ret = GLXEW_EXT_swap_control_tear;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_texture_from_pixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19))
+ {
+ ret = GLXEW_EXT_texture_from_pixmap;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_visual_info
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_info", 11))
+ {
+ ret = GLXEW_EXT_visual_info;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_visual_rating
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_rating", 13))
+ {
+ ret = GLXEW_EXT_visual_rating;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6))
+ {
+#ifdef GLX_INTEL_swap_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_event", 10))
+ {
+ ret = GLXEW_INTEL_swap_event;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5))
+ {
+#ifdef GLX_MESA_agp_offset
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"agp_offset", 10))
+ {
+ ret = GLXEW_MESA_agp_offset;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_copy_sub_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_sub_buffer", 15))
+ {
+ ret = GLXEW_MESA_copy_sub_buffer;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_pixmap_colormap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_colormap", 15))
+ {
+ ret = GLXEW_MESA_pixmap_colormap;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_query_renderer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_renderer", 14))
+ {
+ ret = GLXEW_MESA_query_renderer;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_release_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"release_buffers", 15))
+ {
+ ret = GLXEW_MESA_release_buffers;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_set_3dfx_mode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"set_3dfx_mode", 13))
+ {
+ ret = GLXEW_MESA_set_3dfx_mode;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = GLXEW_MESA_swap_control;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef GLX_NV_copy_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11))
+ {
+ ret = GLXEW_NV_copy_buffer;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = GLXEW_NV_copy_image;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_delay_before_swap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"delay_before_swap", 17))
+ {
+ ret = GLXEW_NV_delay_before_swap;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_float_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
+ {
+ ret = GLXEW_NV_float_buffer;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20))
+ {
+ ret = GLXEW_NV_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_present_video
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13))
+ {
+ ret = GLXEW_NV_present_video;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_video_memory_purge", 29))
+ {
+ ret = GLXEW_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_swap_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10))
+ {
+ ret = GLXEW_NV_swap_group;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = GLXEW_NV_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_video_capture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13))
+ {
+ ret = GLXEW_NV_video_capture;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_video_out
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_out", 9))
+ {
+ ret = GLXEW_NV_video_out;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4))
+ {
+#ifdef GLX_OML_swap_method
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_method", 11))
+ {
+ ret = GLXEW_OML_swap_method;
+ continue;
+ }
+#endif
+#ifdef GLX_OML_sync_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12))
+ {
+ ret = GLXEW_OML_sync_control;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5))
+ {
+#ifdef GLX_SGIS_blended_overlay
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blended_overlay", 15))
+ {
+ ret = GLXEW_SGIS_blended_overlay;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIS_color_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11))
+ {
+ ret = GLXEW_SGIS_color_range;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIS_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLXEW_SGIS_multisample;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIS_shared_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18))
+ {
+ ret = GLXEW_SGIS_shared_multisample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5))
+ {
+#ifdef GLX_SGIX_fbconfig
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig", 8))
+ {
+ ret = GLXEW_SGIX_fbconfig;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_hyperpipe
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"hyperpipe", 9))
+ {
+ ret = GLXEW_SGIX_hyperpipe;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_pbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7))
+ {
+ ret = GLXEW_SGIX_pbuffer;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_swap_barrier
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_barrier", 12))
+ {
+ ret = GLXEW_SGIX_swap_barrier;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_swap_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10))
+ {
+ ret = GLXEW_SGIX_swap_group;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_video_resize
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12))
+ {
+ ret = GLXEW_SGIX_video_resize;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_visual_select_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_select_group", 19))
+ {
+ ret = GLXEW_SGIX_visual_select_group;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4))
+ {
+#ifdef GLX_SGI_cushion
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cushion", 7))
+ {
+ ret = GLXEW_SGI_cushion;
+ continue;
+ }
+#endif
+#ifdef GLX_SGI_make_current_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17))
+ {
+ ret = GLXEW_SGI_make_current_read;
+ continue;
+ }
+#endif
+#ifdef GLX_SGI_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = GLXEW_SGI_swap_control;
+ continue;
+ }
+#endif
+#ifdef GLX_SGI_video_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_sync", 10))
+ {
+ ret = GLXEW_SGI_video_sync;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4))
+ {
+#ifdef GLX_SUN_get_transparent_index
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_transparent_index", 21))
+ {
+ ret = GLXEW_SUN_get_transparent_index;
+ continue;
+ }
+#endif
+#ifdef GLX_SUN_video_resize
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12))
+ {
+ ret = GLXEW_SUN_video_resize;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
+#elif defined(GLEW_EGL)
+
+GLboolean eglewIsSupported (const char* name)
+{
+ const GLubyte* pos = (const GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if(_glewStrSame1(&pos, &len, (const GLubyte*)"EGL_", 4))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8))
+ {
+#ifdef EGL_VERSION_1_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_0", 3))
+ {
+ ret = EGLEW_VERSION_1_0;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_1", 3))
+ {
+ ret = EGLEW_VERSION_1_1;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3))
+ {
+ ret = EGLEW_VERSION_1_2;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3))
+ {
+ ret = EGLEW_VERSION_1_3;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3))
+ {
+ ret = EGLEW_VERSION_1_4;
+ continue;
+ }
+#endif
+#ifdef EGL_VERSION_1_5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3))
+ {
+ ret = EGLEW_VERSION_1_5;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANDROID_", 8))
+ {
+#ifdef EGL_ANDROID_blob_cache
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blob_cache", 10))
+ {
+ ret = EGLEW_ANDROID_blob_cache;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_create_native_client_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_native_client_buffer", 27))
+ {
+ ret = EGLEW_ANDROID_create_native_client_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_framebuffer_target
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_target", 18))
+ {
+ ret = EGLEW_ANDROID_framebuffer_target;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_front_buffer_auto_refresh
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"front_buffer_auto_refresh", 25))
+ {
+ ret = EGLEW_ANDROID_front_buffer_auto_refresh;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_image_native_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_native_buffer", 19))
+ {
+ ret = EGLEW_ANDROID_image_native_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_native_fence_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"native_fence_sync", 17))
+ {
+ ret = EGLEW_ANDROID_native_fence_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_presentation_time
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"presentation_time", 17))
+ {
+ ret = EGLEW_ANDROID_presentation_time;
+ continue;
+ }
+#endif
+#ifdef EGL_ANDROID_recordable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"recordable", 10))
+ {
+ ret = EGLEW_ANDROID_recordable;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANGLE_", 6))
+ {
+#ifdef EGL_ANGLE_d3d_share_handle_client_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"d3d_share_handle_client_buffer", 30))
+ {
+ ret = EGLEW_ANGLE_d3d_share_handle_client_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_device_d3d
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_d3d", 10))
+ {
+ ret = EGLEW_ANGLE_device_d3d;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_query_surface_pointer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_surface_pointer", 21))
+ {
+ ret = EGLEW_ANGLE_query_surface_pointer;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"surface_d3d_texture_2d_share_handle", 35))
+ {
+ ret = EGLEW_ANGLE_surface_d3d_texture_2d_share_handle;
+ continue;
+ }
+#endif
+#ifdef EGL_ANGLE_window_fixed_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_fixed_size", 17))
+ {
+ ret = EGLEW_ANGLE_window_fixed_size;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARM_", 4))
+ {
+#ifdef EGL_ARM_implicit_external_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"implicit_external_sync", 22))
+ {
+ ret = EGLEW_ARM_implicit_external_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_ARM_pixmap_multisample_discard
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_multisample_discard", 26))
+ {
+ ret = EGLEW_ARM_pixmap_multisample_discard;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef EGL_EXT_buffer_age
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_age", 10))
+ {
+ ret = EGLEW_EXT_buffer_age;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_client_extensions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_extensions", 17))
+ {
+ ret = EGLEW_EXT_client_extensions;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_create_context_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25))
+ {
+ ret = EGLEW_EXT_create_context_robustness;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_base", 11))
+ {
+ ret = EGLEW_EXT_device_base;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_drm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_drm", 10))
+ {
+ ret = EGLEW_EXT_device_drm;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_enumeration
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_enumeration", 18))
+ {
+ ret = EGLEW_EXT_device_enumeration;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_openwf
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_openwf", 13))
+ {
+ ret = EGLEW_EXT_device_openwf;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_device_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_query", 12))
+ {
+ ret = EGLEW_EXT_device_query;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_gl_colorspace_bt2020_linear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_colorspace_bt2020_linear", 27))
+ {
+ ret = EGLEW_EXT_gl_colorspace_bt2020_linear;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_gl_colorspace_bt2020_pq
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_colorspace_bt2020_pq", 23))
+ {
+ ret = EGLEW_EXT_gl_colorspace_bt2020_pq;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_gl_colorspace_scrgb_linear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_colorspace_scrgb_linear", 26))
+ {
+ ret = EGLEW_EXT_gl_colorspace_scrgb_linear;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_image_dma_buf_import
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_dma_buf_import", 20))
+ {
+ ret = EGLEW_EXT_image_dma_buf_import;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_image_dma_buf_import_modifiers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_dma_buf_import_modifiers", 30))
+ {
+ ret = EGLEW_EXT_image_dma_buf_import_modifiers;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_multiview_window
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview_window", 16))
+ {
+ ret = EGLEW_EXT_multiview_window;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_output_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"output_base", 11))
+ {
+ ret = EGLEW_EXT_output_base;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_output_drm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"output_drm", 10))
+ {
+ ret = EGLEW_EXT_output_drm;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_output_openwf
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"output_openwf", 13))
+ {
+ ret = EGLEW_EXT_output_openwf;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_pixel_format_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18))
+ {
+ ret = EGLEW_EXT_pixel_format_float;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_base", 13))
+ {
+ ret = EGLEW_EXT_platform_base;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_device
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_device", 15))
+ {
+ ret = EGLEW_EXT_platform_device;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_wayland
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_wayland", 16))
+ {
+ ret = EGLEW_EXT_platform_wayland;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_platform_x11
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_x11", 12))
+ {
+ ret = EGLEW_EXT_platform_x11;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_protected_content
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"protected_content", 17))
+ {
+ ret = EGLEW_EXT_protected_content;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_protected_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"protected_surface", 17))
+ {
+ ret = EGLEW_EXT_protected_surface;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_stream_consumer_egloutput
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_consumer_egloutput", 25))
+ {
+ ret = EGLEW_EXT_stream_consumer_egloutput;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_surface_SMPTE2086_metadata
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"surface_SMPTE2086_metadata", 26))
+ {
+ ret = EGLEW_EXT_surface_SMPTE2086_metadata;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_swap_buffers_with_damage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_buffers_with_damage", 24))
+ {
+ ret = EGLEW_EXT_swap_buffers_with_damage;
+ continue;
+ }
+#endif
+#ifdef EGL_EXT_yuv_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"yuv_surface", 11))
+ {
+ ret = EGLEW_EXT_yuv_surface;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"HI_", 3))
+ {
+#ifdef EGL_HI_clientpixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clientpixmap", 12))
+ {
+ ret = EGLEW_HI_clientpixmap;
+ continue;
+ }
+#endif
+#ifdef EGL_HI_colorformats
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"colorformats", 12))
+ {
+ ret = EGLEW_HI_colorformats;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"IMG_", 4))
+ {
+#ifdef EGL_IMG_context_priority
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"context_priority", 16))
+ {
+ ret = EGLEW_IMG_context_priority;
+ continue;
+ }
+#endif
+#ifdef EGL_IMG_image_plane_attribs
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_plane_attribs", 19))
+ {
+ ret = EGLEW_IMG_image_plane_attribs;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"KHR_", 4))
+ {
+#ifdef EGL_KHR_cl_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event", 8))
+ {
+ ret = EGLEW_KHR_cl_event;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_cl_event2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event2", 9))
+ {
+ ret = EGLEW_KHR_cl_event2;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_client_get_all_proc_addresses
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_get_all_proc_addresses", 29))
+ {
+ ret = EGLEW_KHR_client_get_all_proc_addresses;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_config_attribs
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"config_attribs", 14))
+ {
+ ret = EGLEW_KHR_config_attribs;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_context_flush_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"context_flush_control", 21))
+ {
+ ret = EGLEW_KHR_context_flush_control;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_create_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14))
+ {
+ ret = EGLEW_KHR_create_context;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_create_context_no_error
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_no_error", 23))
+ {
+ ret = EGLEW_KHR_create_context_no_error;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_debug
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug", 5))
+ {
+ ret = EGLEW_KHR_debug;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_fence_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence_sync", 10))
+ {
+ ret = EGLEW_KHR_fence_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_get_all_proc_addresses
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_all_proc_addresses", 22))
+ {
+ ret = EGLEW_KHR_get_all_proc_addresses;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_colorspace
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_colorspace", 13))
+ {
+ ret = EGLEW_KHR_gl_colorspace;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_renderbuffer_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_renderbuffer_image", 21))
+ {
+ ret = EGLEW_KHR_gl_renderbuffer_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_texture_2D_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_texture_2D_image", 19))
+ {
+ ret = EGLEW_KHR_gl_texture_2D_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_texture_3D_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_texture_3D_image", 19))
+ {
+ ret = EGLEW_KHR_gl_texture_3D_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_gl_texture_cubemap_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_texture_cubemap_image", 24))
+ {
+ ret = EGLEW_KHR_gl_texture_cubemap_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image", 5))
+ {
+ ret = EGLEW_KHR_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_image_base
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_base", 10))
+ {
+ ret = EGLEW_KHR_image_base;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_image_pixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_pixmap", 12))
+ {
+ ret = EGLEW_KHR_image_pixmap;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_lock_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"lock_surface", 12))
+ {
+ ret = EGLEW_KHR_lock_surface;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_lock_surface2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"lock_surface2", 13))
+ {
+ ret = EGLEW_KHR_lock_surface2;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_lock_surface3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"lock_surface3", 13))
+ {
+ ret = EGLEW_KHR_lock_surface3;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_mutable_render_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mutable_render_buffer", 21))
+ {
+ ret = EGLEW_KHR_mutable_render_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_no_config_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"no_config_context", 17))
+ {
+ ret = EGLEW_KHR_no_config_context;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_partial_update
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"partial_update", 14))
+ {
+ ret = EGLEW_KHR_partial_update;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_android
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_android", 16))
+ {
+ ret = EGLEW_KHR_platform_android;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_gbm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_gbm", 12))
+ {
+ ret = EGLEW_KHR_platform_gbm;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_wayland
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_wayland", 16))
+ {
+ ret = EGLEW_KHR_platform_wayland;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_platform_x11
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_x11", 12))
+ {
+ ret = EGLEW_KHR_platform_x11;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_reusable_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"reusable_sync", 13))
+ {
+ ret = EGLEW_KHR_reusable_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream", 6))
+ {
+ ret = EGLEW_KHR_stream;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_attrib
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_attrib", 13))
+ {
+ ret = EGLEW_KHR_stream_attrib;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_consumer_gltexture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_consumer_gltexture", 25))
+ {
+ ret = EGLEW_KHR_stream_consumer_gltexture;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_cross_process_fd
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_cross_process_fd", 23))
+ {
+ ret = EGLEW_KHR_stream_cross_process_fd;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_fifo
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_fifo", 11))
+ {
+ ret = EGLEW_KHR_stream_fifo;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_producer_aldatalocator
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_producer_aldatalocator", 29))
+ {
+ ret = EGLEW_KHR_stream_producer_aldatalocator;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_stream_producer_eglsurface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_producer_eglsurface", 26))
+ {
+ ret = EGLEW_KHR_stream_producer_eglsurface;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_surfaceless_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"surfaceless_context", 19))
+ {
+ ret = EGLEW_KHR_surfaceless_context;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_swap_buffers_with_damage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_buffers_with_damage", 24))
+ {
+ ret = EGLEW_KHR_swap_buffers_with_damage;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_vg_parent_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vg_parent_image", 15))
+ {
+ ret = EGLEW_KHR_vg_parent_image;
+ continue;
+ }
+#endif
+#ifdef EGL_KHR_wait_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"wait_sync", 9))
+ {
+ ret = EGLEW_KHR_wait_sync;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5))
+ {
+#ifdef EGL_MESA_drm_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"drm_image", 9))
+ {
+ ret = EGLEW_MESA_drm_image;
+ continue;
+ }
+#endif
+#ifdef EGL_MESA_image_dma_buf_export
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_dma_buf_export", 20))
+ {
+ ret = EGLEW_MESA_image_dma_buf_export;
+ continue;
+ }
+#endif
+#ifdef EGL_MESA_platform_gbm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_gbm", 12))
+ {
+ ret = EGLEW_MESA_platform_gbm;
+ continue;
+ }
+#endif
+#ifdef EGL_MESA_platform_surfaceless
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_surfaceless", 20))
+ {
+ ret = EGLEW_MESA_platform_surfaceless;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NOK_", 4))
+ {
+#ifdef EGL_NOK_swap_region
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_region", 11))
+ {
+ ret = EGLEW_NOK_swap_region;
+ continue;
+ }
+#endif
+#ifdef EGL_NOK_swap_region2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_region2", 12))
+ {
+ ret = EGLEW_NOK_swap_region2;
+ continue;
+ }
+#endif
+#ifdef EGL_NOK_texture_from_pixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19))
+ {
+ ret = EGLEW_NOK_texture_from_pixmap;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef EGL_NV_3dvision_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3dvision_surface", 16))
+ {
+ ret = EGLEW_NV_3dvision_surface;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_coverage_sample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"coverage_sample", 15))
+ {
+ ret = EGLEW_NV_coverage_sample;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_coverage_sample_resolve
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"coverage_sample_resolve", 23))
+ {
+ ret = EGLEW_NV_coverage_sample_resolve;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_cuda_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cuda_event", 10))
+ {
+ ret = EGLEW_NV_cuda_event;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_depth_nonlinear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_nonlinear", 15))
+ {
+ ret = EGLEW_NV_depth_nonlinear;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_device_cuda
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"device_cuda", 11))
+ {
+ ret = EGLEW_NV_device_cuda;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_native_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"native_query", 12))
+ {
+ ret = EGLEW_NV_native_query;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_post_convert_rounding
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_convert_rounding", 21))
+ {
+ ret = EGLEW_NV_post_convert_rounding;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_post_sub_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_sub_buffer", 15))
+ {
+ ret = EGLEW_NV_post_sub_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_robustness_video_memory_purge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_video_memory_purge", 29))
+ {
+ ret = EGLEW_NV_robustness_video_memory_purge;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_consumer_gltexture_yuv
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_consumer_gltexture_yuv", 29))
+ {
+ ret = EGLEW_NV_stream_consumer_gltexture_yuv;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_cross_display
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_cross_display", 20))
+ {
+ ret = EGLEW_NV_stream_cross_display;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_cross_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_cross_object", 19))
+ {
+ ret = EGLEW_NV_stream_cross_object;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_cross_partition
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_cross_partition", 22))
+ {
+ ret = EGLEW_NV_stream_cross_partition;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_cross_process
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_cross_process", 20))
+ {
+ ret = EGLEW_NV_stream_cross_process;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_cross_system
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_cross_system", 19))
+ {
+ ret = EGLEW_NV_stream_cross_system;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_fifo_next
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_fifo_next", 16))
+ {
+ ret = EGLEW_NV_stream_fifo_next;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_fifo_synchronous
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_fifo_synchronous", 23))
+ {
+ ret = EGLEW_NV_stream_fifo_synchronous;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_frame_limits
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_frame_limits", 19))
+ {
+ ret = EGLEW_NV_stream_frame_limits;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_metadata
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_metadata", 15))
+ {
+ ret = EGLEW_NV_stream_metadata;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_remote
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_remote", 13))
+ {
+ ret = EGLEW_NV_stream_remote;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_reset
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_reset", 12))
+ {
+ ret = EGLEW_NV_stream_reset;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_socket
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_socket", 13))
+ {
+ ret = EGLEW_NV_stream_socket;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_socket_inet
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_socket_inet", 18))
+ {
+ ret = EGLEW_NV_stream_socket_inet;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_socket_unix
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_socket_unix", 18))
+ {
+ ret = EGLEW_NV_stream_socket_unix;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_stream_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stream_sync", 11))
+ {
+ ret = EGLEW_NV_stream_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4))
+ {
+ ret = EGLEW_NV_sync;
+ continue;
+ }
+#endif
+#ifdef EGL_NV_system_time
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"system_time", 11))
+ {
+ ret = EGLEW_NV_system_time;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"TIZEN_", 6))
+ {
+#ifdef EGL_TIZEN_image_native_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_native_buffer", 19))
+ {
+ ret = EGLEW_TIZEN_image_native_buffer;
+ continue;
+ }
+#endif
+#ifdef EGL_TIZEN_image_native_surface
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_native_surface", 20))
+ {
+ ret = EGLEW_TIZEN_image_native_surface;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
+#endif /* _WIN32 */
diff --git a/graphics/asymptote/GL/glew.h b/graphics/asymptote/GL/glew.h
new file mode 100644
index 0000000000..b5b6987fc7
--- /dev/null
+++ b/graphics/asymptote/GL/glew.h
@@ -0,0 +1,23686 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2008-2017, Nigel Stewart <nigels[]users sourceforge net>
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.0
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * 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 AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE 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 AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __glew_h__
+#define __glew_h__
+#define __GLEW_H__
+
+#if defined(__gl_h_) || defined(__GL_H__) || defined(_GL_H) || defined(__X_GL_H)
+#error gl.h included before glew.h
+#endif
+#if defined(__gl2_h_)
+#error gl2.h included before glew.h
+#endif
+#if defined(__gltypes_h_)
+#error gltypes.h included before glew.h
+#endif
+#if defined(__REGAL_H__)
+#error Regal.h included before glew.h
+#endif
+#if defined(__glext_h_) || defined(__GLEXT_H_)
+#error glext.h included before glew.h
+#endif
+#if defined(__gl_ATI_h_)
+#error glATI.h included before glew.h
+#endif
+
+#define __gl_h_
+#define __gl2_h_
+#define __GL_H__
+#define _GL_H
+#define __gltypes_h_
+#define __REGAL_H__
+#define __X_GL_H
+#define __glext_h_
+#define __GLEXT_H_
+#define __gl_ATI_h_
+
+#if defined(_WIN32)
+
+/*
+ * GLEW does not include <windows.h> to avoid name space pollution.
+ * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t
+ * defined properly.
+ */
+/* <windef.h> and <gl.h>*/
+#ifdef APIENTRY
+# ifndef GLAPIENTRY
+# define GLAPIENTRY APIENTRY
+# endif
+# ifndef GLEWAPIENTRY
+# define GLEWAPIENTRY APIENTRY
+# endif
+#else
+#define GLEW_APIENTRY_DEFINED
+# if defined(__MINGW32__) || defined(__CYGWIN__) || (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__)
+# define APIENTRY __stdcall
+# ifndef GLAPIENTRY
+# define GLAPIENTRY __stdcall
+# endif
+# ifndef GLEWAPIENTRY
+# define GLEWAPIENTRY __stdcall
+# endif
+# else
+# define APIENTRY
+# endif
+#endif
+#ifndef GLAPI
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+# define GLAPI extern
+# endif
+#endif
+/* <winnt.h> */
+#ifndef CALLBACK
+#define GLEW_CALLBACK_DEFINED
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+# define CALLBACK __attribute__ ((__stdcall__))
+# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
+# define CALLBACK __stdcall
+# else
+# define CALLBACK
+# endif
+#endif
+/* <wingdi.h> and <winnt.h> */
+#ifndef WINGDIAPI
+#define GLEW_WINGDIAPI_DEFINED
+#define WINGDIAPI __declspec(dllimport)
+#endif
+/* <ctype.h> */
+#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED)
+typedef unsigned short wchar_t;
+# define _WCHAR_T_DEFINED
+#endif
+/* <stddef.h> */
+#if !defined(_W64)
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) && !defined(__MINGW64__)
+# ifdef _WIN64
+typedef __int64 ptrdiff_t;
+# else
+typedef _W64 int ptrdiff_t;
+# endif
+# define _PTRDIFF_T_DEFINED
+# define _PTRDIFF_T_
+#endif
+
+#ifndef GLAPI
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+# define GLAPI extern
+# else
+# define GLAPI WINGDIAPI
+# endif
+#endif
+
+/*
+ * GLEW_STATIC is defined for static library.
+ * GLEW_BUILD is defined for building the DLL library.
+ */
+
+#ifdef GLEW_STATIC
+# define GLEWAPI extern
+#else
+# ifdef GLEW_BUILD
+# define GLEWAPI extern __declspec(dllexport)
+# else
+# define GLEWAPI extern __declspec(dllimport)
+# endif
+#endif
+
+#else /* _UNIX */
+
+/*
+ * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO
+ * C. On my system, this amounts to _3 lines_ of included code, all of
+ * them pretty much harmless. If you know of a way of detecting 32 vs
+ * 64 _targets_ at compile time you are free to replace this with
+ * something that's portable. For now, _this_ is the portable solution.
+ * (mem, 2004-01-04)
+ */
+
+#include <stddef.h>
+
+/* SGI MIPSPro doesn't like stdint.h in C++ mode */
+/* ID: 3376260 Solaris 9 has inttypes.h, but not stdint.h */
+
+#if (defined(__sgi) || defined(__sun)) && !defined(__GNUC__)
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+#define GLEW_APIENTRY_DEFINED
+#define APIENTRY
+
+/*
+ * GLEW_STATIC is defined for static library.
+ */
+
+#ifdef GLEW_STATIC
+# define GLEWAPI extern
+#else
+# if defined(__GNUC__) && __GNUC__>=4
+# define GLEWAPI extern __attribute__ ((visibility("default")))
+# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# define GLEWAPI extern __global
+# else
+# define GLEWAPI extern
+# endif
+#endif
+
+/* <glu.h> */
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+#endif /* _WIN32 */
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY
+#endif
+
+#ifndef GLEWAPIENTRY
+#define GLEWAPIENTRY
+#endif
+
+#define GLEW_VAR_EXPORT GLEWAPI
+#define GLEW_FUN_EXPORT GLEWAPI
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----------------------------- GL_VERSION_1_1 ---------------------------- */
+
+#ifndef GL_VERSION_1_1
+#define GL_VERSION_1_1 1
+
+typedef unsigned int GLenum;
+typedef unsigned int GLbitfield;
+typedef unsigned int GLuint;
+typedef int GLint;
+typedef int GLsizei;
+typedef unsigned char GLboolean;
+typedef signed char GLbyte;
+typedef short GLshort;
+typedef unsigned char GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned long GLulong;
+typedef float GLfloat;
+typedef float GLclampf;
+typedef double GLdouble;
+typedef double GLclampd;
+typedef void GLvoid;
+#if defined(_MSC_VER) && _MSC_VER < 1400
+typedef __int64 GLint64EXT;
+typedef unsigned __int64 GLuint64EXT;
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+typedef signed long long GLint64EXT;
+typedef unsigned long long GLuint64EXT;
+#else
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+#include <inttypes.h>
+# endif
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+typedef GLint64EXT GLint64;
+typedef GLuint64EXT GLuint64;
+typedef struct __GLsync *GLsync;
+
+typedef char GLchar;
+
+#define GL_ZERO 0
+#define GL_FALSE 0
+#define GL_LOGIC_OP 0x0BF1
+#define GL_NONE 0
+#define GL_TEXTURE_COMPONENTS 0x1003
+#define GL_NO_ERROR 0
+#define GL_POINTS 0x0000
+#define GL_CURRENT_BIT 0x00000001
+#define GL_TRUE 1
+#define GL_ONE 1
+#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_POINT_BIT 0x00000002
+#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
+#define GL_LINE_STRIP 0x0003
+#define GL_LINE_BIT 0x00000004
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_QUADS 0x0007
+#define GL_QUAD_STRIP 0x0008
+#define GL_POLYGON_BIT 0x00000008
+#define GL_POLYGON 0x0009
+#define GL_POLYGON_STIPPLE_BIT 0x00000010
+#define GL_PIXEL_MODE_BIT 0x00000020
+#define GL_LIGHTING_BIT 0x00000040
+#define GL_FOG_BIT 0x00000080
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_ACCUM 0x0100
+#define GL_LOAD 0x0101
+#define GL_RETURN 0x0102
+#define GL_MULT 0x0103
+#define GL_ADD 0x0104
+#define GL_NEVER 0x0200
+#define GL_ACCUM_BUFFER_BIT 0x00000200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_LEFT 0x0406
+#define GL_RIGHT 0x0407
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_AUX0 0x0409
+#define GL_AUX1 0x040A
+#define GL_AUX2 0x040B
+#define GL_AUX3 0x040C
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_2D 0x0600
+#define GL_3D 0x0601
+#define GL_3D_COLOR 0x0602
+#define GL_3D_COLOR_TEXTURE 0x0603
+#define GL_4D_COLOR_TEXTURE 0x0604
+#define GL_PASS_THROUGH_TOKEN 0x0700
+#define GL_POINT_TOKEN 0x0701
+#define GL_LINE_TOKEN 0x0702
+#define GL_POLYGON_TOKEN 0x0703
+#define GL_BITMAP_TOKEN 0x0704
+#define GL_DRAW_PIXEL_TOKEN 0x0705
+#define GL_COPY_PIXEL_TOKEN 0x0706
+#define GL_LINE_RESET_TOKEN 0x0707
+#define GL_EXP 0x0800
+#define GL_VIEWPORT_BIT 0x00000800
+#define GL_EXP2 0x0801
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_COEFF 0x0A00
+#define GL_ORDER 0x0A01
+#define GL_DOMAIN 0x0A02
+#define GL_CURRENT_COLOR 0x0B00
+#define GL_CURRENT_INDEX 0x0B01
+#define GL_CURRENT_NORMAL 0x0B02
+#define GL_CURRENT_TEXTURE_COORDS 0x0B03
+#define GL_CURRENT_RASTER_COLOR 0x0B04
+#define GL_CURRENT_RASTER_INDEX 0x0B05
+#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06
+#define GL_CURRENT_RASTER_POSITION 0x0B07
+#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08
+#define GL_CURRENT_RASTER_DISTANCE 0x0B09
+#define GL_POINT_SMOOTH 0x0B10
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_RANGE 0x0B12
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_RANGE 0x0B22
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_STIPPLE 0x0B24
+#define GL_LINE_STIPPLE_PATTERN 0x0B25
+#define GL_LINE_STIPPLE_REPEAT 0x0B26
+#define GL_LIST_MODE 0x0B30
+#define GL_MAX_LIST_NESTING 0x0B31
+#define GL_LIST_BASE 0x0B32
+#define GL_LIST_INDEX 0x0B33
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_STIPPLE 0x0B42
+#define GL_EDGE_FLAG 0x0B43
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_LIGHTING 0x0B50
+#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
+#define GL_LIGHT_MODEL_AMBIENT 0x0B53
+#define GL_SHADE_MODEL 0x0B54
+#define GL_COLOR_MATERIAL_FACE 0x0B55
+#define GL_COLOR_MATERIAL_PARAMETER 0x0B56
+#define GL_COLOR_MATERIAL 0x0B57
+#define GL_FOG 0x0B60
+#define GL_FOG_INDEX 0x0B61
+#define GL_FOG_DENSITY 0x0B62
+#define GL_FOG_START 0x0B63
+#define GL_FOG_END 0x0B64
+#define GL_FOG_MODE 0x0B65
+#define GL_FOG_COLOR 0x0B66
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_ACCUM_CLEAR_VALUE 0x0B80
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_MATRIX_MODE 0x0BA0
+#define GL_NORMALIZE 0x0BA1
+#define GL_VIEWPORT 0x0BA2
+#define GL_MODELVIEW_STACK_DEPTH 0x0BA3
+#define GL_PROJECTION_STACK_DEPTH 0x0BA4
+#define GL_TEXTURE_STACK_DEPTH 0x0BA5
+#define GL_MODELVIEW_MATRIX 0x0BA6
+#define GL_PROJECTION_MATRIX 0x0BA7
+#define GL_TEXTURE_MATRIX 0x0BA8
+#define GL_ATTRIB_STACK_DEPTH 0x0BB0
+#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
+#define GL_ALPHA_TEST 0x0BC0
+#define GL_ALPHA_TEST_FUNC 0x0BC1
+#define GL_ALPHA_TEST_REF 0x0BC2
+#define GL_DITHER 0x0BD0
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLEND 0x0BE2
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_INDEX_LOGIC_OP 0x0BF1
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_AUX_BUFFERS 0x0C00
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_READ_BUFFER 0x0C02
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_INDEX_CLEAR_VALUE 0x0C20
+#define GL_INDEX_WRITEMASK 0x0C21
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_INDEX_MODE 0x0C30
+#define GL_RGBA_MODE 0x0C31
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_STEREO 0x0C33
+#define GL_RENDER_MODE 0x0C40
+#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
+#define GL_POINT_SMOOTH_HINT 0x0C51
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_FOG_HINT 0x0C54
+#define GL_TEXTURE_GEN_S 0x0C60
+#define GL_TEXTURE_GEN_T 0x0C61
+#define GL_TEXTURE_GEN_R 0x0C62
+#define GL_TEXTURE_GEN_Q 0x0C63
+#define GL_PIXEL_MAP_I_TO_I 0x0C70
+#define GL_PIXEL_MAP_S_TO_S 0x0C71
+#define GL_PIXEL_MAP_I_TO_R 0x0C72
+#define GL_PIXEL_MAP_I_TO_G 0x0C73
+#define GL_PIXEL_MAP_I_TO_B 0x0C74
+#define GL_PIXEL_MAP_I_TO_A 0x0C75
+#define GL_PIXEL_MAP_R_TO_R 0x0C76
+#define GL_PIXEL_MAP_G_TO_G 0x0C77
+#define GL_PIXEL_MAP_B_TO_B 0x0C78
+#define GL_PIXEL_MAP_A_TO_A 0x0C79
+#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0
+#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1
+#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2
+#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3
+#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4
+#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5
+#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6
+#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7
+#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8
+#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAP_COLOR 0x0D10
+#define GL_MAP_STENCIL 0x0D11
+#define GL_INDEX_SHIFT 0x0D12
+#define GL_INDEX_OFFSET 0x0D13
+#define GL_RED_SCALE 0x0D14
+#define GL_RED_BIAS 0x0D15
+#define GL_ZOOM_X 0x0D16
+#define GL_ZOOM_Y 0x0D17
+#define GL_GREEN_SCALE 0x0D18
+#define GL_GREEN_BIAS 0x0D19
+#define GL_BLUE_SCALE 0x0D1A
+#define GL_BLUE_BIAS 0x0D1B
+#define GL_ALPHA_SCALE 0x0D1C
+#define GL_ALPHA_BIAS 0x0D1D
+#define GL_DEPTH_SCALE 0x0D1E
+#define GL_DEPTH_BIAS 0x0D1F
+#define GL_MAX_EVAL_ORDER 0x0D30
+#define GL_MAX_LIGHTS 0x0D31
+#define GL_MAX_CLIP_PLANES 0x0D32
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_PIXEL_MAP_TABLE 0x0D34
+#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35
+#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36
+#define GL_MAX_NAME_STACK_DEPTH 0x0D37
+#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
+#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_INDEX_BITS 0x0D51
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_ACCUM_RED_BITS 0x0D58
+#define GL_ACCUM_GREEN_BITS 0x0D59
+#define GL_ACCUM_BLUE_BITS 0x0D5A
+#define GL_ACCUM_ALPHA_BITS 0x0D5B
+#define GL_NAME_STACK_DEPTH 0x0D70
+#define GL_AUTO_NORMAL 0x0D80
+#define GL_MAP1_COLOR_4 0x0D90
+#define GL_MAP1_INDEX 0x0D91
+#define GL_MAP1_NORMAL 0x0D92
+#define GL_MAP1_TEXTURE_COORD_1 0x0D93
+#define GL_MAP1_TEXTURE_COORD_2 0x0D94
+#define GL_MAP1_TEXTURE_COORD_3 0x0D95
+#define GL_MAP1_TEXTURE_COORD_4 0x0D96
+#define GL_MAP1_VERTEX_3 0x0D97
+#define GL_MAP1_VERTEX_4 0x0D98
+#define GL_MAP2_COLOR_4 0x0DB0
+#define GL_MAP2_INDEX 0x0DB1
+#define GL_MAP2_NORMAL 0x0DB2
+#define GL_MAP2_TEXTURE_COORD_1 0x0DB3
+#define GL_MAP2_TEXTURE_COORD_2 0x0DB4
+#define GL_MAP2_TEXTURE_COORD_3 0x0DB5
+#define GL_MAP2_TEXTURE_COORD_4 0x0DB6
+#define GL_MAP2_VERTEX_3 0x0DB7
+#define GL_MAP2_VERTEX_4 0x0DB8
+#define GL_MAP1_GRID_DOMAIN 0x0DD0
+#define GL_MAP1_GRID_SEGMENTS 0x0DD1
+#define GL_MAP2_GRID_DOMAIN 0x0DD2
+#define GL_MAP2_GRID_SEGMENTS 0x0DD3
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
+#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1
+#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2
+#define GL_SELECTION_BUFFER_POINTER 0x0DF3
+#define GL_SELECTION_BUFFER_SIZE 0x0DF4
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TRANSFORM_BIT 0x00001000
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_BORDER 0x1005
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_AMBIENT 0x1200
+#define GL_DIFFUSE 0x1201
+#define GL_SPECULAR 0x1202
+#define GL_POSITION 0x1203
+#define GL_SPOT_DIRECTION 0x1204
+#define GL_SPOT_EXPONENT 0x1205
+#define GL_SPOT_CUTOFF 0x1206
+#define GL_CONSTANT_ATTENUATION 0x1207
+#define GL_LINEAR_ATTENUATION 0x1208
+#define GL_QUADRATIC_ATTENUATION 0x1209
+#define GL_COMPILE 0x1300
+#define GL_COMPILE_AND_EXECUTE 0x1301
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_2_BYTES 0x1407
+#define GL_3_BYTES 0x1408
+#define GL_4_BYTES 0x1409
+#define GL_DOUBLE 0x140A
+#define GL_CLEAR 0x1500
+#define GL_AND 0x1501
+#define GL_AND_REVERSE 0x1502
+#define GL_COPY 0x1503
+#define GL_AND_INVERTED 0x1504
+#define GL_NOOP 0x1505
+#define GL_XOR 0x1506
+#define GL_OR 0x1507
+#define GL_NOR 0x1508
+#define GL_EQUIV 0x1509
+#define GL_INVERT 0x150A
+#define GL_OR_REVERSE 0x150B
+#define GL_COPY_INVERTED 0x150C
+#define GL_OR_INVERTED 0x150D
+#define GL_NAND 0x150E
+#define GL_SET 0x150F
+#define GL_EMISSION 0x1600
+#define GL_SHININESS 0x1601
+#define GL_AMBIENT_AND_DIFFUSE 0x1602
+#define GL_COLOR_INDEXES 0x1603
+#define GL_MODELVIEW 0x1700
+#define GL_PROJECTION 0x1701
+#define GL_TEXTURE 0x1702
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_COLOR_INDEX 0x1900
+#define GL_STENCIL_INDEX 0x1901
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_BITMAP 0x1A00
+#define GL_POINT 0x1B00
+#define GL_LINE 0x1B01
+#define GL_FILL 0x1B02
+#define GL_RENDER 0x1C00
+#define GL_FEEDBACK 0x1C01
+#define GL_SELECT 0x1C02
+#define GL_FLAT 0x1D00
+#define GL_SMOOTH 0x1D01
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_S 0x2000
+#define GL_ENABLE_BIT 0x00002000
+#define GL_T 0x2001
+#define GL_R 0x2002
+#define GL_Q 0x2003
+#define GL_MODULATE 0x2100
+#define GL_DECAL 0x2101
+#define GL_TEXTURE_ENV_MODE 0x2200
+#define GL_TEXTURE_ENV_COLOR 0x2201
+#define GL_TEXTURE_ENV 0x2300
+#define GL_EYE_LINEAR 0x2400
+#define GL_OBJECT_LINEAR 0x2401
+#define GL_SPHERE_MAP 0x2402
+#define GL_TEXTURE_GEN_MODE 0x2500
+#define GL_OBJECT_PLANE 0x2501
+#define GL_EYE_PLANE 0x2502
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_CLAMP 0x2900
+#define GL_REPEAT 0x2901
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_R3_G3_B2 0x2A10
+#define GL_V2F 0x2A20
+#define GL_V3F 0x2A21
+#define GL_C4UB_V2F 0x2A22
+#define GL_C4UB_V3F 0x2A23
+#define GL_C3F_V3F 0x2A24
+#define GL_N3F_V3F 0x2A25
+#define GL_C4F_N3F_V3F 0x2A26
+#define GL_T2F_V3F 0x2A27
+#define GL_T4F_V4F 0x2A28
+#define GL_T2F_C4UB_V3F 0x2A29
+#define GL_T2F_C3F_V3F 0x2A2A
+#define GL_T2F_N3F_V3F 0x2A2B
+#define GL_T2F_C4F_N3F_V3F 0x2A2C
+#define GL_T4F_C4F_N3F_V4F 0x2A2D
+#define GL_CLIP_PLANE0 0x3000
+#define GL_CLIP_PLANE1 0x3001
+#define GL_CLIP_PLANE2 0x3002
+#define GL_CLIP_PLANE3 0x3003
+#define GL_CLIP_PLANE4 0x3004
+#define GL_CLIP_PLANE5 0x3005
+#define GL_LIGHT0 0x4000
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_LIGHT1 0x4001
+#define GL_LIGHT2 0x4002
+#define GL_LIGHT3 0x4003
+#define GL_LIGHT4 0x4004
+#define GL_LIGHT5 0x4005
+#define GL_LIGHT6 0x4006
+#define GL_LIGHT7 0x4007
+#define GL_HINT_BIT 0x00008000
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_ALPHA4 0x803B
+#define GL_ALPHA8 0x803C
+#define GL_ALPHA12 0x803D
+#define GL_ALPHA16 0x803E
+#define GL_LUMINANCE4 0x803F
+#define GL_LUMINANCE8 0x8040
+#define GL_LUMINANCE12 0x8041
+#define GL_LUMINANCE16 0x8042
+#define GL_LUMINANCE4_ALPHA4 0x8043
+#define GL_LUMINANCE6_ALPHA2 0x8044
+#define GL_LUMINANCE8_ALPHA8 0x8045
+#define GL_LUMINANCE12_ALPHA4 0x8046
+#define GL_LUMINANCE12_ALPHA12 0x8047
+#define GL_LUMINANCE16_ALPHA16 0x8048
+#define GL_INTENSITY 0x8049
+#define GL_INTENSITY4 0x804A
+#define GL_INTENSITY8 0x804B
+#define GL_INTENSITY12 0x804C
+#define GL_INTENSITY16 0x804D
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB8 0x8051
+#define GL_RGB10 0x8052
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGBA2 0x8055
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE 0x8061
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_TEXTURE_PRIORITY 0x8066
+#define GL_TEXTURE_RESIDENT 0x8067
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_NORMAL_ARRAY 0x8075
+#define GL_COLOR_ARRAY 0x8076
+#define GL_INDEX_ARRAY 0x8077
+#define GL_TEXTURE_COORD_ARRAY 0x8078
+#define GL_EDGE_FLAG_ARRAY 0x8079
+#define GL_VERTEX_ARRAY_SIZE 0x807A
+#define GL_VERTEX_ARRAY_TYPE 0x807B
+#define GL_VERTEX_ARRAY_STRIDE 0x807C
+#define GL_NORMAL_ARRAY_TYPE 0x807E
+#define GL_NORMAL_ARRAY_STRIDE 0x807F
+#define GL_COLOR_ARRAY_SIZE 0x8081
+#define GL_COLOR_ARRAY_TYPE 0x8082
+#define GL_COLOR_ARRAY_STRIDE 0x8083
+#define GL_INDEX_ARRAY_TYPE 0x8085
+#define GL_INDEX_ARRAY_STRIDE 0x8086
+#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
+#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
+#define GL_VERTEX_ARRAY_POINTER 0x808E
+#define GL_NORMAL_ARRAY_POINTER 0x808F
+#define GL_COLOR_ARRAY_POINTER 0x8090
+#define GL_INDEX_ARRAY_POINTER 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_EVAL_BIT 0x00010000
+#define GL_LIST_BIT 0x00020000
+#define GL_TEXTURE_BIT 0x00040000
+#define GL_SCISSOR_BIT 0x00080000
+#define GL_ALL_ATTRIB_BITS 0x000fffff
+#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff
+
+GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value);
+GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref);
+GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences);
+GLAPI void GLAPIENTRY glArrayElement (GLint i);
+GLAPI void GLAPIENTRY glBegin (GLenum mode);
+GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture);
+GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
+GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GLAPI void GLAPIENTRY glCallList (GLuint list);
+GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const void *lists);
+GLAPI void GLAPIENTRY glClear (GLbitfield mask);
+GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void GLAPIENTRY glClearDepth (GLclampd depth);
+GLAPI void GLAPIENTRY glClearIndex (GLfloat c);
+GLAPI void GLAPIENTRY glClearStencil (GLint s);
+GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation);
+GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v);
+GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue);
+GLAPI void GLAPIENTRY glColor3iv (const GLint *v);
+GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue);
+GLAPI void GLAPIENTRY glColor3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v);
+GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue);
+GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v);
+GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue);
+GLAPI void GLAPIENTRY glColor3usv (const GLushort *v);
+GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
+GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v);
+GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha);
+GLAPI void GLAPIENTRY glColor4iv (const GLint *v);
+GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha);
+GLAPI void GLAPIENTRY glColor4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v);
+GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v);
+GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha);
+GLAPI void GLAPIENTRY glColor4usv (const GLushort *v);
+GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode);
+GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer);
+GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
+GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void GLAPIENTRY glCullFace (GLenum mode);
+GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range);
+GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GLAPI void GLAPIENTRY glDepthFunc (GLenum func);
+GLAPI void GLAPIENTRY glDepthMask (GLboolean flag);
+GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar);
+GLAPI void GLAPIENTRY glDisable (GLenum cap);
+GLAPI void GLAPIENTRY glDisableClientState (GLenum array);
+GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode);
+GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
+GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag);
+GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const void *pointer);
+GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag);
+GLAPI void GLAPIENTRY glEnable (GLenum cap);
+GLAPI void GLAPIENTRY glEnableClientState (GLenum array);
+GLAPI void GLAPIENTRY glEnd (void);
+GLAPI void GLAPIENTRY glEndList (void);
+GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u);
+GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u);
+GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u);
+GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u);
+GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v);
+GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u);
+GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v);
+GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u);
+GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2);
+GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
+GLAPI void GLAPIENTRY glEvalPoint1 (GLint i);
+GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j);
+GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer);
+GLAPI void GLAPIENTRY glFinish (void);
+GLAPI void GLAPIENTRY glFlush (void);
+GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glFrontFace (GLenum mode);
+GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range);
+GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params);
+GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation);
+GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params);
+GLAPI GLenum GLAPIENTRY glGetError (void);
+GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v);
+GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v);
+GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v);
+GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values);
+GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values);
+GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values);
+GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, void* *params);
+GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask);
+GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name);
+GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params);
+GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
+GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode);
+GLAPI void GLAPIENTRY glIndexMask (GLuint mask);
+GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const void *pointer);
+GLAPI void GLAPIENTRY glIndexd (GLdouble c);
+GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c);
+GLAPI void GLAPIENTRY glIndexf (GLfloat c);
+GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c);
+GLAPI void GLAPIENTRY glIndexi (GLint c);
+GLAPI void GLAPIENTRY glIndexiv (const GLint *c);
+GLAPI void GLAPIENTRY glIndexs (GLshort c);
+GLAPI void GLAPIENTRY glIndexsv (const GLshort *c);
+GLAPI void GLAPIENTRY glIndexub (GLubyte c);
+GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c);
+GLAPI void GLAPIENTRY glInitNames (void);
+GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const void *pointer);
+GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap);
+GLAPI GLboolean GLAPIENTRY glIsList (GLuint list);
+GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture);
+GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern);
+GLAPI void GLAPIENTRY glLineWidth (GLfloat width);
+GLAPI void GLAPIENTRY glListBase (GLuint base);
+GLAPI void GLAPIENTRY glLoadIdentity (void);
+GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m);
+GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m);
+GLAPI void GLAPIENTRY glLoadName (GLuint name);
+GLAPI void GLAPIENTRY glLogicOp (GLenum opcode);
+GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2);
+GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2);
+GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
+GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
+GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glMatrixMode (GLenum mode);
+GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m);
+GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m);
+GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode);
+GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz);
+GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v);
+GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz);
+GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz);
+GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz);
+GLAPI void GLAPIENTRY glNormal3iv (const GLint *v);
+GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz);
+GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const void *pointer);
+GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void GLAPIENTRY glPassThrough (GLfloat token);
+GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values);
+GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values);
+GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values);
+GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor);
+GLAPI void GLAPIENTRY glPointSize (GLfloat size);
+GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode);
+GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask);
+GLAPI void GLAPIENTRY glPopAttrib (void);
+GLAPI void GLAPIENTRY glPopClientAttrib (void);
+GLAPI void GLAPIENTRY glPopMatrix (void);
+GLAPI void GLAPIENTRY glPopName (void);
+GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask);
+GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask);
+GLAPI void GLAPIENTRY glPushMatrix (void);
+GLAPI void GLAPIENTRY glPushName (GLuint name);
+GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y);
+GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y);
+GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y);
+GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v);
+GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y);
+GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v);
+GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z);
+GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v);
+GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z);
+GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w);
+GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v);
+GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glReadBuffer (GLenum mode);
+GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
+GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2);
+GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2);
+GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2);
+GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2);
+GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2);
+GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2);
+GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode);
+GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer);
+GLAPI void GLAPIENTRY glShadeModel (GLenum mode);
+GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GLAPI void GLAPIENTRY glStencilMask (GLuint mask);
+GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s);
+GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s);
+GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord1i (GLint s);
+GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord1s (GLshort s);
+GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t);
+GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t);
+GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t);
+GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t);
+GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r);
+GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r);
+GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r);
+GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r);
+GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q);
+GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const void *pointer);
+GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param);
+GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params);
+GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);
+GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);
+GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y);
+GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y);
+GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y);
+GLAPI void GLAPIENTRY glVertex2iv (const GLint *v);
+GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y);
+GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v);
+GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z);
+GLAPI void GLAPIENTRY glVertex3iv (const GLint *v);
+GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z);
+GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w);
+GLAPI void GLAPIENTRY glVertex4iv (const GLint *v);
+GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const void *pointer);
+GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1)
+
+#endif /* GL_VERSION_1_1 */
+
+/* ---------------------------------- GLU ---------------------------------- */
+
+#ifndef GLEW_NO_GLU
+# ifdef __APPLE__
+# include <Availability.h>
+# if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+# define GLEW_NO_GLU
+# endif
+# endif
+#endif
+
+#ifndef GLEW_NO_GLU
+/* this is where we can safely include GLU */
+# if defined(__APPLE__) && defined(__MACH__)
+# include <OpenGL/glu.h>
+# else
+# include <GL/glu.h>
+# endif
+#endif
+
+/* ----------------------------- GL_VERSION_1_2 ---------------------------- */
+
+#ifndef GL_VERSION_1_2
+#define GL_VERSION_1_2 1
+
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+
+#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D)
+#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements)
+#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D)
+#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D)
+
+#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2)
+
+#endif /* GL_VERSION_1_2 */
+
+/* ---------------------------- GL_VERSION_1_2_1 --------------------------- */
+
+#ifndef GL_VERSION_1_2_1
+#define GL_VERSION_1_2_1 1
+
+#define GLEW_VERSION_1_2_1 GLEW_GET_VAR(__GLEW_VERSION_1_2_1)
+
+#endif /* GL_VERSION_1_2_1 */
+
+/* ----------------------------- GL_VERSION_1_3 ---------------------------- */
+
+#ifndef GL_VERSION_1_3
+#define GL_VERSION_1_3 1
+
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_SUBTRACT 0x84E7
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#define GL_MULTISAMPLE_BIT 0x20000000
+
+typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, void *img);
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+
+#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture)
+#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture)
+#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D)
+#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D)
+#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D)
+#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D)
+#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D)
+#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D)
+#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage)
+#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd)
+#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf)
+#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd)
+#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf)
+#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d)
+#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv)
+#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f)
+#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv)
+#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i)
+#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv)
+#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s)
+#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv)
+#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d)
+#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv)
+#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f)
+#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv)
+#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i)
+#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv)
+#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s)
+#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv)
+#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d)
+#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv)
+#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f)
+#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv)
+#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i)
+#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv)
+#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s)
+#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv)
+#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d)
+#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv)
+#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f)
+#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv)
+#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i)
+#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv)
+#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s)
+#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv)
+#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage)
+
+#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3)
+
+#endif /* GL_VERSION_1_3 */
+
+/* ----------------------------- GL_VERSION_1_4 ---------------------------- */
+
+#ifndef GL_VERSION_1_4
+#define GL_VERSION_1_4 1
+
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_COLOR_SUM 0x8458
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+
+typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const* indices, GLsizei drawcount);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p);
+
+#define glBlendColor GLEW_GET_FUN(__glewBlendColor)
+#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation)
+#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate)
+#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer)
+#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd)
+#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv)
+#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf)
+#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv)
+#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays)
+#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements)
+#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf)
+#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv)
+#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri)
+#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv)
+#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b)
+#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv)
+#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d)
+#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv)
+#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f)
+#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv)
+#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i)
+#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv)
+#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s)
+#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv)
+#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub)
+#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv)
+#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui)
+#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv)
+#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us)
+#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv)
+#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer)
+#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d)
+#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv)
+#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f)
+#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv)
+#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i)
+#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv)
+#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s)
+#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv)
+#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d)
+#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv)
+#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f)
+#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv)
+#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i)
+#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv)
+#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s)
+#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv)
+
+#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4)
+
+#endif /* GL_VERSION_1_4 */
+
+/* ----------------------------- GL_VERSION_1_5 ---------------------------- */
+
+#ifndef GL_VERSION_1_5
+#define GL_VERSION_1_5 1
+
+#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE
+#define GL_FOG_COORD GL_FOG_COORDINATE
+#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING
+#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER
+#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE
+#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE
+#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE
+#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA
+#define GL_SRC0_RGB GL_SOURCE0_RGB
+#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA
+#define GL_SRC1_RGB GL_SOURCE1_RGB
+#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA
+#define GL_SRC2_RGB GL_SOURCE2_RGB
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_SAMPLES_PASSED 0x8914
+
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void* data, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
+typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void** params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void* data);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id);
+typedef void* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target);
+
+#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery)
+#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer)
+#define glBufferData GLEW_GET_FUN(__glewBufferData)
+#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData)
+#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers)
+#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries)
+#define glEndQuery GLEW_GET_FUN(__glewEndQuery)
+#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers)
+#define glGenQueries GLEW_GET_FUN(__glewGenQueries)
+#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv)
+#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv)
+#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData)
+#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv)
+#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv)
+#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv)
+#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer)
+#define glIsQuery GLEW_GET_FUN(__glewIsQuery)
+#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer)
+#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer)
+
+#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5)
+
+#endif /* GL_VERSION_1_5 */
+
+/* ----------------------------- GL_VERSION_2_0 ---------------------------- */
+
+#ifndef GL_VERSION_2_0
+#define GL_VERSION_2_0 1
+
+#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_POINT_SPRITE 0x8861
+#define GL_COORD_REPLACE 0x8862
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_DELETE_STATUS 0x8B80
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+
+typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders);
+typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source);
+typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param);
+typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void** pointer);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader);
+typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const* string, const GLint* length);
+typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
+
+#define glAttachShader GLEW_GET_FUN(__glewAttachShader)
+#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation)
+#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate)
+#define glCompileShader GLEW_GET_FUN(__glewCompileShader)
+#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram)
+#define glCreateShader GLEW_GET_FUN(__glewCreateShader)
+#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram)
+#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader)
+#define glDetachShader GLEW_GET_FUN(__glewDetachShader)
+#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray)
+#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers)
+#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray)
+#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib)
+#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform)
+#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders)
+#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation)
+#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog)
+#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv)
+#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog)
+#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource)
+#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv)
+#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation)
+#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv)
+#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv)
+#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv)
+#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv)
+#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv)
+#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv)
+#define glIsProgram GLEW_GET_FUN(__glewIsProgram)
+#define glIsShader GLEW_GET_FUN(__glewIsShader)
+#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram)
+#define glShaderSource GLEW_GET_FUN(__glewShaderSource)
+#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate)
+#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate)
+#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate)
+#define glUniform1f GLEW_GET_FUN(__glewUniform1f)
+#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv)
+#define glUniform1i GLEW_GET_FUN(__glewUniform1i)
+#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv)
+#define glUniform2f GLEW_GET_FUN(__glewUniform2f)
+#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv)
+#define glUniform2i GLEW_GET_FUN(__glewUniform2i)
+#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv)
+#define glUniform3f GLEW_GET_FUN(__glewUniform3f)
+#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv)
+#define glUniform3i GLEW_GET_FUN(__glewUniform3i)
+#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv)
+#define glUniform4f GLEW_GET_FUN(__glewUniform4f)
+#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv)
+#define glUniform4i GLEW_GET_FUN(__glewUniform4i)
+#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv)
+#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv)
+#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv)
+#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv)
+#define glUseProgram GLEW_GET_FUN(__glewUseProgram)
+#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram)
+#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d)
+#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv)
+#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f)
+#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv)
+#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s)
+#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv)
+#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d)
+#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv)
+#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f)
+#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv)
+#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s)
+#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv)
+#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d)
+#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv)
+#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f)
+#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv)
+#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s)
+#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv)
+#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv)
+#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv)
+#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv)
+#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub)
+#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv)
+#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv)
+#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv)
+#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv)
+#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d)
+#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv)
+#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f)
+#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv)
+#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv)
+#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s)
+#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv)
+#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv)
+#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv)
+#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv)
+#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer)
+
+#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0)
+
+#endif /* GL_VERSION_2_0 */
+
+/* ----------------------------- GL_VERSION_2_1 ---------------------------- */
+
+#ifndef GL_VERSION_2_1
+#define GL_VERSION_2_1 1
+
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SLUMINANCE_ALPHA 0x8C44
+#define GL_SLUMINANCE8_ALPHA8 0x8C45
+#define GL_SLUMINANCE 0x8C46
+#define GL_SLUMINANCE8 0x8C47
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+
+#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv)
+#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv)
+#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv)
+#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv)
+#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv)
+#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv)
+
+#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1)
+
+#endif /* GL_VERSION_2_1 */
+
+/* ----------------------------- GL_VERSION_3_0 ---------------------------- */
+
+#ifndef GL_VERSION_3_0
+#define GL_VERSION_3_0 1
+
+#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0
+#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1
+#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2
+#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3
+#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4
+#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5
+#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB
+#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES
+#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_DEPTH_BUFFER 0x8223
+#define GL_STENCIL_BUFFER 0x8224
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_CLAMP_VERTEX_COLOR 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR 0x891B
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_FIXED_ONLY 0x891D
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_ALPHA_INTEGER 0x8D97
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+
+typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint colorNumber, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawBuffer, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawBuffer, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawBuffer, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum cap, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum cap, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void);
+typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum pname, GLuint index, GLboolean* data);
+typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar* name);
+typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum cap, GLuint index);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint v0, GLint v1);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint v0, GLuint v1);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint v0, GLint v1, GLint v2);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort* v0);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void*pointer);
+
+#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender)
+#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback)
+#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation)
+#define glClampColor GLEW_GET_FUN(__glewClampColor)
+#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi)
+#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv)
+#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv)
+#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv)
+#define glColorMaski GLEW_GET_FUN(__glewColorMaski)
+#define glDisablei GLEW_GET_FUN(__glewDisablei)
+#define glEnablei GLEW_GET_FUN(__glewEnablei)
+#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender)
+#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback)
+#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v)
+#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation)
+#define glGetStringi GLEW_GET_FUN(__glewGetStringi)
+#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv)
+#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv)
+#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying)
+#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv)
+#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv)
+#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv)
+#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi)
+#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv)
+#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv)
+#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings)
+#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui)
+#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv)
+#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui)
+#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv)
+#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui)
+#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv)
+#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui)
+#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv)
+#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i)
+#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv)
+#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui)
+#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv)
+#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i)
+#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv)
+#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui)
+#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv)
+#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i)
+#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv)
+#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui)
+#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv)
+#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv)
+#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i)
+#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv)
+#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv)
+#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv)
+#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui)
+#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv)
+#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv)
+#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer)
+
+#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0)
+
+#endif /* GL_VERSION_3_0 */
+
+/* ----------------------------- GL_VERSION_3_1 ---------------------------- */
+
+#ifndef GL_VERSION_3_1
+#define GL_VERSION_3_1 1
+
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalFormat, GLuint buffer);
+
+#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced)
+#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced)
+#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex)
+#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer)
+
+#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1)
+
+#endif /* GL_VERSION_3_1 */
+
+/* ----------------------------- GL_VERSION_3_2 ---------------------------- */
+
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum value, GLint64 * data);
+typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum pname, GLuint index, GLint64 * data);
+
+#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture)
+#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v)
+#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v)
+
+#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2)
+
+#endif /* GL_VERSION_3_2 */
+
+/* ----------------------------- GL_VERSION_3_3 ---------------------------- */
+
+#ifndef GL_VERSION_3_3
+#define GL_VERSION_3_3 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_RGB10_A2UI 0x906F
+
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+
+#define glVertexAttribDivisor GLEW_GET_FUN(__glewVertexAttribDivisor)
+
+#define GLEW_VERSION_3_3 GLEW_GET_VAR(__GLEW_VERSION_3_3)
+
+#endif /* GL_VERSION_3_3 */
+
+/* ----------------------------- GL_VERSION_4_0 ---------------------------- */
+
+#ifndef GL_VERSION_4_0
+#define GL_VERSION_4_0 1
+
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+
+#define glBlendEquationSeparatei GLEW_GET_FUN(__glewBlendEquationSeparatei)
+#define glBlendEquationi GLEW_GET_FUN(__glewBlendEquationi)
+#define glBlendFuncSeparatei GLEW_GET_FUN(__glewBlendFuncSeparatei)
+#define glBlendFunci GLEW_GET_FUN(__glewBlendFunci)
+#define glMinSampleShading GLEW_GET_FUN(__glewMinSampleShading)
+
+#define GLEW_VERSION_4_0 GLEW_GET_VAR(__GLEW_VERSION_4_0)
+
+#endif /* GL_VERSION_4_0 */
+
+/* ----------------------------- GL_VERSION_4_1 ---------------------------- */
+
+#ifndef GL_VERSION_4_1
+#define GL_VERSION_4_1 1
+
+#define GLEW_VERSION_4_1 GLEW_GET_VAR(__GLEW_VERSION_4_1)
+
+#endif /* GL_VERSION_4_1 */
+
+/* ----------------------------- GL_VERSION_4_2 ---------------------------- */
+
+#ifndef GL_VERSION_4_2
+#define GL_VERSION_4_2 1
+
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+
+#define GLEW_VERSION_4_2 GLEW_GET_VAR(__GLEW_VERSION_4_2)
+
+#endif /* GL_VERSION_4_2 */
+
+/* ----------------------------- GL_VERSION_4_3 ---------------------------- */
+
+#ifndef GL_VERSION_4_3
+#define GL_VERSION_4_3 1
+
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+
+#define GLEW_VERSION_4_3 GLEW_GET_VAR(__GLEW_VERSION_4_3)
+
+#endif /* GL_VERSION_4_3 */
+
+/* ----------------------------- GL_VERSION_4_4 ---------------------------- */
+
+#ifndef GL_VERSION_4_4
+#define GL_VERSION_4_4 1
+
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+#define GL_TEXTURE_BUFFER_BINDING 0x8C2A
+
+#define GLEW_VERSION_4_4 GLEW_GET_VAR(__GLEW_VERSION_4_4)
+
+#endif /* GL_VERSION_4_4 */
+
+/* ----------------------------- GL_VERSION_4_5 ---------------------------- */
+
+#ifndef GL_VERSION_4_5
+#define GL_VERSION_4_5 1
+
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
+
+typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEPROC) (GLenum tex, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+
+#define glGetGraphicsResetStatus GLEW_GET_FUN(__glewGetGraphicsResetStatus)
+#define glGetnCompressedTexImage GLEW_GET_FUN(__glewGetnCompressedTexImage)
+#define glGetnTexImage GLEW_GET_FUN(__glewGetnTexImage)
+#define glGetnUniformdv GLEW_GET_FUN(__glewGetnUniformdv)
+
+#define GLEW_VERSION_4_5 GLEW_GET_VAR(__GLEW_VERSION_4_5)
+
+#endif /* GL_VERSION_4_5 */
+
+/* ----------------------------- GL_VERSION_4_6 ---------------------------- */
+
+#ifndef GL_VERSION_4_6
+#define GL_VERSION_4_6 1
+
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008
+#define GL_PARAMETER_BUFFER 0x80EE
+#define GL_PARAMETER_BUFFER_BINDING 0x80EF
+#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC
+#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED
+#define GL_VERTICES_SUBMITTED 0x82EE
+#define GL_PRIMITIVES_SUBMITTED 0x82EF
+#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0
+#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1
+#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2
+#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3
+#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4
+#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5
+#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6
+#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7
+#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
+#define GL_POLYGON_OFFSET_CLAMP 0x8E1B
+#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551
+#define GL_SPIR_V_BINARY 0x9552
+#define GL_SPIR_V_EXTENSIONS 0x9553
+#define GL_NUM_SPIR_V_EXTENSIONS 0x9554
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) (GLenum mode, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue);
+
+#define glMultiDrawArraysIndirectCount GLEW_GET_FUN(__glewMultiDrawArraysIndirectCount)
+#define glMultiDrawElementsIndirectCount GLEW_GET_FUN(__glewMultiDrawElementsIndirectCount)
+#define glSpecializeShader GLEW_GET_FUN(__glewSpecializeShader)
+
+#define GLEW_VERSION_4_6 GLEW_GET_VAR(__GLEW_VERSION_4_6)
+
+#endif /* GL_VERSION_4_6 */
+
+/* -------------------------- GL_3DFX_multisample -------------------------- */
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+
+#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample)
+
+#endif /* GL_3DFX_multisample */
+
+/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+
+typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+
+#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX)
+
+#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer)
+
+#endif /* GL_3DFX_tbuffer */
+
+/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+
+#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1)
+
+#endif /* GL_3DFX_texture_compression_FXT1 */
+
+/* ----------------------- GL_AMD_blend_minmax_factor ---------------------- */
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_AMD_blend_minmax_factor 1
+
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+
+#define GLEW_AMD_blend_minmax_factor GLEW_GET_VAR(__GLEW_AMD_blend_minmax_factor)
+
+#endif /* GL_AMD_blend_minmax_factor */
+
+/* --------------------- GL_AMD_compressed_3DC_texture --------------------- */
+
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+
+#define GL_3DC_X_AMD 0x87F9
+#define GL_3DC_XY_AMD 0x87FA
+
+#define GLEW_AMD_compressed_3DC_texture GLEW_GET_VAR(__GLEW_AMD_compressed_3DC_texture)
+
+#endif /* GL_AMD_compressed_3DC_texture */
+
+/* --------------------- GL_AMD_compressed_ATC_texture --------------------- */
+
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#define GL_ATC_RGB_AMD 0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
+
+#define GLEW_AMD_compressed_ATC_texture GLEW_GET_VAR(__GLEW_AMD_compressed_ATC_texture)
+
+#endif /* GL_AMD_compressed_ATC_texture */
+
+/* ----------------------- GL_AMD_conservative_depth ----------------------- */
+
+#ifndef GL_AMD_conservative_depth
+#define GL_AMD_conservative_depth 1
+
+#define GLEW_AMD_conservative_depth GLEW_GET_VAR(__GLEW_AMD_conservative_depth)
+
+#endif /* GL_AMD_conservative_depth */
+
+/* -------------------------- GL_AMD_debug_output -------------------------- */
+
+#ifndef GL_AMD_debug_output
+#define GL_AMD_debug_output 1
+
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147
+#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148
+#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
+#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
+
+typedef void (GLAPIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, void* userParam);
+
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf);
+typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message);
+
+#define glDebugMessageCallbackAMD GLEW_GET_FUN(__glewDebugMessageCallbackAMD)
+#define glDebugMessageEnableAMD GLEW_GET_FUN(__glewDebugMessageEnableAMD)
+#define glDebugMessageInsertAMD GLEW_GET_FUN(__glewDebugMessageInsertAMD)
+#define glGetDebugMessageLogAMD GLEW_GET_FUN(__glewGetDebugMessageLogAMD)
+
+#define GLEW_AMD_debug_output GLEW_GET_VAR(__GLEW_AMD_debug_output)
+
+#endif /* GL_AMD_debug_output */
+
+/* ---------------------- GL_AMD_depth_clamp_separate ---------------------- */
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_AMD_depth_clamp_separate 1
+
+#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E
+#define GL_DEPTH_CLAMP_FAR_AMD 0x901F
+
+#define GLEW_AMD_depth_clamp_separate GLEW_GET_VAR(__GLEW_AMD_depth_clamp_separate)
+
+#endif /* GL_AMD_depth_clamp_separate */
+
+/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD)
+#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD)
+#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD)
+#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD)
+
+#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend)
+
+#endif /* GL_AMD_draw_buffers_blend */
+
+/* ------------------ GL_AMD_framebuffer_sample_positions ------------------ */
+
+#ifndef GL_AMD_framebuffer_sample_positions
+#define GL_AMD_framebuffer_sample_positions 1
+
+#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
+#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE
+#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF
+#define GL_ALL_PIXELS_AMD 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat* values);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC) (GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat* values);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC) (GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat* values);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat* values);
+
+#define glFramebufferSamplePositionsfvAMD GLEW_GET_FUN(__glewFramebufferSamplePositionsfvAMD)
+#define glGetFramebufferParameterfvAMD GLEW_GET_FUN(__glewGetFramebufferParameterfvAMD)
+#define glGetNamedFramebufferParameterfvAMD GLEW_GET_FUN(__glewGetNamedFramebufferParameterfvAMD)
+#define glNamedFramebufferSamplePositionsfvAMD GLEW_GET_FUN(__glewNamedFramebufferSamplePositionsfvAMD)
+
+#define GLEW_AMD_framebuffer_sample_positions GLEW_GET_VAR(__GLEW_AMD_framebuffer_sample_positions)
+
+#endif /* GL_AMD_framebuffer_sample_positions */
+
+/* --------------------------- GL_AMD_gcn_shader --------------------------- */
+
+#ifndef GL_AMD_gcn_shader
+#define GL_AMD_gcn_shader 1
+
+#define GLEW_AMD_gcn_shader GLEW_GET_VAR(__GLEW_AMD_gcn_shader)
+
+#endif /* GL_AMD_gcn_shader */
+
+/* ---------------------- GL_AMD_gpu_shader_half_float --------------------- */
+
+#ifndef GL_AMD_gpu_shader_half_float
+#define GL_AMD_gpu_shader_half_float 1
+
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+#define GL_FLOAT16_MAT2_AMD 0x91C5
+#define GL_FLOAT16_MAT3_AMD 0x91C6
+#define GL_FLOAT16_MAT4_AMD 0x91C7
+#define GL_FLOAT16_MAT2x3_AMD 0x91C8
+#define GL_FLOAT16_MAT2x4_AMD 0x91C9
+#define GL_FLOAT16_MAT3x2_AMD 0x91CA
+#define GL_FLOAT16_MAT3x4_AMD 0x91CB
+#define GL_FLOAT16_MAT4x2_AMD 0x91CC
+#define GL_FLOAT16_MAT4x3_AMD 0x91CD
+
+#define GLEW_AMD_gpu_shader_half_float GLEW_GET_VAR(__GLEW_AMD_gpu_shader_half_float)
+
+#endif /* GL_AMD_gpu_shader_half_float */
+
+/* ------------------------ GL_AMD_gpu_shader_int16 ------------------------ */
+
+#ifndef GL_AMD_gpu_shader_int16
+#define GL_AMD_gpu_shader_int16 1
+
+#define GLEW_AMD_gpu_shader_int16 GLEW_GET_VAR(__GLEW_AMD_gpu_shader_int16)
+
+#endif /* GL_AMD_gpu_shader_int16 */
+
+/* ------------------------ GL_AMD_gpu_shader_int64 ------------------------ */
+
+#ifndef GL_AMD_gpu_shader_int64
+#define GL_AMD_gpu_shader_int64 1
+
+#define GLEW_AMD_gpu_shader_int64 GLEW_GET_VAR(__GLEW_AMD_gpu_shader_int64)
+
+#endif /* GL_AMD_gpu_shader_int64 */
+
+/* ---------------------- GL_AMD_interleaved_elements ---------------------- */
+
+#ifndef GL_AMD_interleaved_elements
+#define GL_AMD_interleaved_elements 1
+
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
+#define GL_RG8UI 0x8238
+#define GL_RG16UI 0x823A
+#define GL_RGBA8UI 0x8D7C
+#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4
+#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5
+
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param);
+
+#define glVertexAttribParameteriAMD GLEW_GET_FUN(__glewVertexAttribParameteriAMD)
+
+#define GLEW_AMD_interleaved_elements GLEW_GET_VAR(__GLEW_AMD_interleaved_elements)
+
+#endif /* GL_AMD_interleaved_elements */
+
+/* ----------------------- GL_AMD_multi_draw_indirect ---------------------- */
+
+#ifndef GL_AMD_multi_draw_indirect
+#define GL_AMD_multi_draw_indirect 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride);
+
+#define glMultiDrawArraysIndirectAMD GLEW_GET_FUN(__glewMultiDrawArraysIndirectAMD)
+#define glMultiDrawElementsIndirectAMD GLEW_GET_FUN(__glewMultiDrawElementsIndirectAMD)
+
+#define GLEW_AMD_multi_draw_indirect GLEW_GET_VAR(__GLEW_AMD_multi_draw_indirect)
+
+#endif /* GL_AMD_multi_draw_indirect */
+
+/* ------------------------- GL_AMD_name_gen_delete ------------------------ */
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_AMD_name_gen_delete 1
+
+#define GL_DATA_BUFFER_AMD 0x9151
+#define GL_PERFORMANCE_MONITOR_AMD 0x9152
+#define GL_QUERY_OBJECT_AMD 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154
+#define GL_SAMPLER_OBJECT_AMD 0x9155
+
+typedef void (GLAPIENTRY * PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint* names);
+typedef void (GLAPIENTRY * PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint* names);
+typedef GLboolean (GLAPIENTRY * PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name);
+
+#define glDeleteNamesAMD GLEW_GET_FUN(__glewDeleteNamesAMD)
+#define glGenNamesAMD GLEW_GET_FUN(__glewGenNamesAMD)
+#define glIsNameAMD GLEW_GET_FUN(__glewIsNameAMD)
+
+#define GLEW_AMD_name_gen_delete GLEW_GET_VAR(__GLEW_AMD_name_gen_delete)
+
+#endif /* GL_AMD_name_gen_delete */
+
+/* ---------------------- GL_AMD_occlusion_query_event --------------------- */
+
+#ifndef GL_AMD_occlusion_query_event
+#define GL_AMD_occlusion_query_event 1
+
+#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001
+#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002
+#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004
+#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008
+#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F
+#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param);
+
+#define glQueryObjectParameteruiAMD GLEW_GET_FUN(__glewQueryObjectParameteruiAMD)
+
+#define GLEW_AMD_occlusion_query_event GLEW_GET_VAR(__GLEW_AMD_occlusion_query_event)
+
+#endif /* GL_AMD_occlusion_query_event */
+
+/* ----------------------- GL_AMD_performance_monitor ---------------------- */
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+
+typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors);
+typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar *counterString);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, GLchar *groupString);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList);
+
+#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD)
+#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD)
+#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD)
+#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD)
+#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD)
+#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD)
+#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD)
+#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD)
+#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD)
+#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD)
+#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD)
+
+#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor)
+
+#endif /* GL_AMD_performance_monitor */
+
+/* -------------------------- GL_AMD_pinned_memory ------------------------- */
+
+#ifndef GL_AMD_pinned_memory
+#define GL_AMD_pinned_memory 1
+
+#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160
+
+#define GLEW_AMD_pinned_memory GLEW_GET_VAR(__GLEW_AMD_pinned_memory)
+
+#endif /* GL_AMD_pinned_memory */
+
+/* ----------------------- GL_AMD_program_binary_Z400 ---------------------- */
+
+#ifndef GL_AMD_program_binary_Z400
+#define GL_AMD_program_binary_Z400 1
+
+#define GL_Z400_BINARY_AMD 0x8740
+
+#define GLEW_AMD_program_binary_Z400 GLEW_GET_VAR(__GLEW_AMD_program_binary_Z400)
+
+#endif /* GL_AMD_program_binary_Z400 */
+
+/* ----------------------- GL_AMD_query_buffer_object ---------------------- */
+
+#ifndef GL_AMD_query_buffer_object
+#define GL_AMD_query_buffer_object 1
+
+#define GL_QUERY_BUFFER_AMD 0x9192
+#define GL_QUERY_BUFFER_BINDING_AMD 0x9193
+#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194
+
+#define GLEW_AMD_query_buffer_object GLEW_GET_VAR(__GLEW_AMD_query_buffer_object)
+
+#endif /* GL_AMD_query_buffer_object */
+
+/* ------------------------ GL_AMD_sample_positions ------------------------ */
+
+#ifndef GL_AMD_sample_positions
+#define GL_AMD_sample_positions 1
+
+#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
+
+typedef void (GLAPIENTRY * PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat* val);
+
+#define glSetMultisamplefvAMD GLEW_GET_FUN(__glewSetMultisamplefvAMD)
+
+#define GLEW_AMD_sample_positions GLEW_GET_VAR(__GLEW_AMD_sample_positions)
+
+#endif /* GL_AMD_sample_positions */
+
+/* ------------------ GL_AMD_seamless_cubemap_per_texture ------------------ */
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+#define GL_AMD_seamless_cubemap_per_texture 1
+
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+
+#define GLEW_AMD_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_AMD_seamless_cubemap_per_texture)
+
+#endif /* GL_AMD_seamless_cubemap_per_texture */
+
+/* -------------------- GL_AMD_shader_atomic_counter_ops ------------------- */
+
+#ifndef GL_AMD_shader_atomic_counter_ops
+#define GL_AMD_shader_atomic_counter_ops 1
+
+#define GLEW_AMD_shader_atomic_counter_ops GLEW_GET_VAR(__GLEW_AMD_shader_atomic_counter_ops)
+
+#endif /* GL_AMD_shader_atomic_counter_ops */
+
+/* -------------------------- GL_AMD_shader_ballot ------------------------- */
+
+#ifndef GL_AMD_shader_ballot
+#define GL_AMD_shader_ballot 1
+
+#define GLEW_AMD_shader_ballot GLEW_GET_VAR(__GLEW_AMD_shader_ballot)
+
+#endif /* GL_AMD_shader_ballot */
+
+/* ---------------- GL_AMD_shader_explicit_vertex_parameter ---------------- */
+
+#ifndef GL_AMD_shader_explicit_vertex_parameter
+#define GL_AMD_shader_explicit_vertex_parameter 1
+
+#define GLEW_AMD_shader_explicit_vertex_parameter GLEW_GET_VAR(__GLEW_AMD_shader_explicit_vertex_parameter)
+
+#endif /* GL_AMD_shader_explicit_vertex_parameter */
+
+/* ---------------------- GL_AMD_shader_stencil_export --------------------- */
+
+#ifndef GL_AMD_shader_stencil_export
+#define GL_AMD_shader_stencil_export 1
+
+#define GLEW_AMD_shader_stencil_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_export)
+
+#endif /* GL_AMD_shader_stencil_export */
+
+/* ------------------- GL_AMD_shader_stencil_value_export ------------------ */
+
+#ifndef GL_AMD_shader_stencil_value_export
+#define GL_AMD_shader_stencil_value_export 1
+
+#define GLEW_AMD_shader_stencil_value_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_value_export)
+
+#endif /* GL_AMD_shader_stencil_value_export */
+
+/* ---------------------- GL_AMD_shader_trinary_minmax --------------------- */
+
+#ifndef GL_AMD_shader_trinary_minmax
+#define GL_AMD_shader_trinary_minmax 1
+
+#define GLEW_AMD_shader_trinary_minmax GLEW_GET_VAR(__GLEW_AMD_shader_trinary_minmax)
+
+#endif /* GL_AMD_shader_trinary_minmax */
+
+/* ------------------------- GL_AMD_sparse_texture ------------------------- */
+
+#ifndef GL_AMD_sparse_texture
+#define GL_AMD_sparse_texture 1
+
+#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001
+#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197
+#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A
+#define GL_MIN_SPARSE_LEVEL_AMD 0x919B
+#define GL_MIN_LOD_WARNING_AMD 0x919C
+
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags);
+
+#define glTexStorageSparseAMD GLEW_GET_FUN(__glewTexStorageSparseAMD)
+#define glTextureStorageSparseAMD GLEW_GET_FUN(__glewTextureStorageSparseAMD)
+
+#define GLEW_AMD_sparse_texture GLEW_GET_VAR(__GLEW_AMD_sparse_texture)
+
+#endif /* GL_AMD_sparse_texture */
+
+/* ------------------- GL_AMD_stencil_operation_extended ------------------- */
+
+#ifndef GL_AMD_stencil_operation_extended
+#define GL_AMD_stencil_operation_extended 1
+
+#define GL_SET_AMD 0x874A
+#define GL_REPLACE_VALUE_AMD 0x874B
+#define GL_STENCIL_OP_VALUE_AMD 0x874C
+#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D
+
+typedef void (GLAPIENTRY * PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value);
+
+#define glStencilOpValueAMD GLEW_GET_FUN(__glewStencilOpValueAMD)
+
+#define GLEW_AMD_stencil_operation_extended GLEW_GET_VAR(__GLEW_AMD_stencil_operation_extended)
+
+#endif /* GL_AMD_stencil_operation_extended */
+
+/* --------------------- GL_AMD_texture_gather_bias_lod -------------------- */
+
+#ifndef GL_AMD_texture_gather_bias_lod
+#define GL_AMD_texture_gather_bias_lod 1
+
+#define GLEW_AMD_texture_gather_bias_lod GLEW_GET_VAR(__GLEW_AMD_texture_gather_bias_lod)
+
+#endif /* GL_AMD_texture_gather_bias_lod */
+
+/* ------------------------ GL_AMD_texture_texture4 ------------------------ */
+
+#ifndef GL_AMD_texture_texture4
+#define GL_AMD_texture_texture4 1
+
+#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4)
+
+#endif /* GL_AMD_texture_texture4 */
+
+/* --------------- GL_AMD_transform_feedback3_lines_triangles -------------- */
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#define GL_AMD_transform_feedback3_lines_triangles 1
+
+#define GLEW_AMD_transform_feedback3_lines_triangles GLEW_GET_VAR(__GLEW_AMD_transform_feedback3_lines_triangles)
+
+#endif /* GL_AMD_transform_feedback3_lines_triangles */
+
+/* ----------------------- GL_AMD_transform_feedback4 ---------------------- */
+
+#ifndef GL_AMD_transform_feedback4
+#define GL_AMD_transform_feedback4 1
+
+#define GL_STREAM_RASTERIZATION_AMD 0x91A0
+
+#define GLEW_AMD_transform_feedback4 GLEW_GET_VAR(__GLEW_AMD_transform_feedback4)
+
+#endif /* GL_AMD_transform_feedback4 */
+
+/* ----------------------- GL_AMD_vertex_shader_layer ---------------------- */
+
+#ifndef GL_AMD_vertex_shader_layer
+#define GL_AMD_vertex_shader_layer 1
+
+#define GLEW_AMD_vertex_shader_layer GLEW_GET_VAR(__GLEW_AMD_vertex_shader_layer)
+
+#endif /* GL_AMD_vertex_shader_layer */
+
+/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */
+
+#ifndef GL_AMD_vertex_shader_tessellator
+#define GL_AMD_vertex_shader_tessellator 1
+
+#define GL_SAMPLER_BUFFER_AMD 0x9001
+#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_TESSELLATION_MODE_AMD 0x9004
+#define GL_TESSELLATION_FACTOR_AMD 0x9005
+#define GL_DISCRETE_AMD 0x9006
+#define GL_CONTINUOUS_AMD 0x9007
+
+typedef void (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
+typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
+
+#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD)
+#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD)
+
+#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator)
+
+#endif /* GL_AMD_vertex_shader_tessellator */
+
+/* ------------------ GL_AMD_vertex_shader_viewport_index ------------------ */
+
+#ifndef GL_AMD_vertex_shader_viewport_index
+#define GL_AMD_vertex_shader_viewport_index 1
+
+#define GLEW_AMD_vertex_shader_viewport_index GLEW_GET_VAR(__GLEW_AMD_vertex_shader_viewport_index)
+
+#endif /* GL_AMD_vertex_shader_viewport_index */
+
+/* -------------------- GL_ANDROID_extension_pack_es31a -------------------- */
+
+#ifndef GL_ANDROID_extension_pack_es31a
+#define GL_ANDROID_extension_pack_es31a 1
+
+#define GLEW_ANDROID_extension_pack_es31a GLEW_GET_VAR(__GLEW_ANDROID_extension_pack_es31a)
+
+#endif /* GL_ANDROID_extension_pack_es31a */
+
+/* ------------------------- GL_ANGLE_depth_texture ------------------------ */
+
+#ifndef GL_ANGLE_depth_texture
+#define GL_ANGLE_depth_texture 1
+
+#define GLEW_ANGLE_depth_texture GLEW_GET_VAR(__GLEW_ANGLE_depth_texture)
+
+#endif /* GL_ANGLE_depth_texture */
+
+/* ----------------------- GL_ANGLE_framebuffer_blit ----------------------- */
+
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+
+typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+
+#define glBlitFramebufferANGLE GLEW_GET_FUN(__glewBlitFramebufferANGLE)
+
+#define GLEW_ANGLE_framebuffer_blit GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_blit)
+
+#endif /* GL_ANGLE_framebuffer_blit */
+
+/* -------------------- GL_ANGLE_framebuffer_multisample ------------------- */
+
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glRenderbufferStorageMultisampleANGLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleANGLE)
+
+#define GLEW_ANGLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_multisample)
+
+#endif /* GL_ANGLE_framebuffer_multisample */
+
+/* ----------------------- GL_ANGLE_instanced_arrays ----------------------- */
+
+#ifndef GL_ANGLE_instanced_arrays
+#define GL_ANGLE_instanced_arrays 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor);
+
+#define glDrawArraysInstancedANGLE GLEW_GET_FUN(__glewDrawArraysInstancedANGLE)
+#define glDrawElementsInstancedANGLE GLEW_GET_FUN(__glewDrawElementsInstancedANGLE)
+#define glVertexAttribDivisorANGLE GLEW_GET_FUN(__glewVertexAttribDivisorANGLE)
+
+#define GLEW_ANGLE_instanced_arrays GLEW_GET_VAR(__GLEW_ANGLE_instanced_arrays)
+
+#endif /* GL_ANGLE_instanced_arrays */
+
+/* -------------------- GL_ANGLE_pack_reverse_row_order -------------------- */
+
+#ifndef GL_ANGLE_pack_reverse_row_order
+#define GL_ANGLE_pack_reverse_row_order 1
+
+#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+
+#define GLEW_ANGLE_pack_reverse_row_order GLEW_GET_VAR(__GLEW_ANGLE_pack_reverse_row_order)
+
+#endif /* GL_ANGLE_pack_reverse_row_order */
+
+/* ------------------------ GL_ANGLE_program_binary ------------------------ */
+
+#ifndef GL_ANGLE_program_binary
+#define GL_ANGLE_program_binary 1
+
+#define GL_PROGRAM_BINARY_ANGLE 0x93A6
+
+#define GLEW_ANGLE_program_binary GLEW_GET_VAR(__GLEW_ANGLE_program_binary)
+
+#endif /* GL_ANGLE_program_binary */
+
+/* ------------------- GL_ANGLE_texture_compression_dxt1 ------------------- */
+
+#ifndef GL_ANGLE_texture_compression_dxt1
+#define GL_ANGLE_texture_compression_dxt1 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+
+#define GLEW_ANGLE_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt1)
+
+#endif /* GL_ANGLE_texture_compression_dxt1 */
+
+/* ------------------- GL_ANGLE_texture_compression_dxt3 ------------------- */
+
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_ANGLE_texture_compression_dxt3 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+
+#define GLEW_ANGLE_texture_compression_dxt3 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt3)
+
+#endif /* GL_ANGLE_texture_compression_dxt3 */
+
+/* ------------------- GL_ANGLE_texture_compression_dxt5 ------------------- */
+
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_ANGLE_texture_compression_dxt5 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+
+#define GLEW_ANGLE_texture_compression_dxt5 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt5)
+
+#endif /* GL_ANGLE_texture_compression_dxt5 */
+
+/* ------------------------- GL_ANGLE_texture_usage ------------------------ */
+
+#ifndef GL_ANGLE_texture_usage
+#define GL_ANGLE_texture_usage 1
+
+#define GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+
+#define GLEW_ANGLE_texture_usage GLEW_GET_VAR(__GLEW_ANGLE_texture_usage)
+
+#endif /* GL_ANGLE_texture_usage */
+
+/* -------------------------- GL_ANGLE_timer_query ------------------------- */
+
+#ifndef GL_ANGLE_timer_query
+#define GL_ANGLE_timer_query 1
+
+#define GL_QUERY_COUNTER_BITS_ANGLE 0x8864
+#define GL_CURRENT_QUERY_ANGLE 0x8865
+#define GL_QUERY_RESULT_ANGLE 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ANGLE 0x8867
+#define GL_TIME_ELAPSED_ANGLE 0x88BF
+#define GL_TIMESTAMP_ANGLE 0x8E28
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYANGLEPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEQUERIESANGLEPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDQUERYANGLEPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENQUERIESANGLEPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VANGLEPROC) (GLuint id, GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVANGLEPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VANGLEPROC) (GLuint id, GLenum pname, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVANGLEPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYIVANGLEPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISQUERYANGLEPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERANGLEPROC) (GLuint id, GLenum target);
+
+#define glBeginQueryANGLE GLEW_GET_FUN(__glewBeginQueryANGLE)
+#define glDeleteQueriesANGLE GLEW_GET_FUN(__glewDeleteQueriesANGLE)
+#define glEndQueryANGLE GLEW_GET_FUN(__glewEndQueryANGLE)
+#define glGenQueriesANGLE GLEW_GET_FUN(__glewGenQueriesANGLE)
+#define glGetQueryObjecti64vANGLE GLEW_GET_FUN(__glewGetQueryObjecti64vANGLE)
+#define glGetQueryObjectivANGLE GLEW_GET_FUN(__glewGetQueryObjectivANGLE)
+#define glGetQueryObjectui64vANGLE GLEW_GET_FUN(__glewGetQueryObjectui64vANGLE)
+#define glGetQueryObjectuivANGLE GLEW_GET_FUN(__glewGetQueryObjectuivANGLE)
+#define glGetQueryivANGLE GLEW_GET_FUN(__glewGetQueryivANGLE)
+#define glIsQueryANGLE GLEW_GET_FUN(__glewIsQueryANGLE)
+#define glQueryCounterANGLE GLEW_GET_FUN(__glewQueryCounterANGLE)
+
+#define GLEW_ANGLE_timer_query GLEW_GET_VAR(__GLEW_ANGLE_timer_query)
+
+#endif /* GL_ANGLE_timer_query */
+
+/* ------------------- GL_ANGLE_translated_shader_source ------------------- */
+
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_ANGLE_translated_shader_source 1
+
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+
+typedef void (GLAPIENTRY * PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+
+#define glGetTranslatedShaderSourceANGLE GLEW_GET_FUN(__glewGetTranslatedShaderSourceANGLE)
+
+#define GLEW_ANGLE_translated_shader_source GLEW_GET_VAR(__GLEW_ANGLE_translated_shader_source)
+
+#endif /* GL_ANGLE_translated_shader_source */
+
+/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+
+#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil)
+
+#endif /* GL_APPLE_aux_depth_stencil */
+
+/* ------------------------ GL_APPLE_client_storage ------------------------ */
+
+#ifndef GL_APPLE_client_storage
+#define GL_APPLE_client_storage 1
+
+#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+
+#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage)
+
+#endif /* GL_APPLE_client_storage */
+
+/* ------------------------- GL_APPLE_clip_distance ------------------------ */
+
+#ifndef GL_APPLE_clip_distance
+#define GL_APPLE_clip_distance 1
+
+#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32
+#define GL_CLIP_DISTANCE0_APPLE 0x3000
+#define GL_CLIP_DISTANCE1_APPLE 0x3001
+#define GL_CLIP_DISTANCE2_APPLE 0x3002
+#define GL_CLIP_DISTANCE3_APPLE 0x3003
+#define GL_CLIP_DISTANCE4_APPLE 0x3004
+#define GL_CLIP_DISTANCE5_APPLE 0x3005
+#define GL_CLIP_DISTANCE6_APPLE 0x3006
+#define GL_CLIP_DISTANCE7_APPLE 0x3007
+
+#define GLEW_APPLE_clip_distance GLEW_GET_VAR(__GLEW_APPLE_clip_distance)
+
+#endif /* GL_APPLE_clip_distance */
+
+/* ------------------- GL_APPLE_color_buffer_packed_float ------------------ */
+
+#ifndef GL_APPLE_color_buffer_packed_float
+#define GL_APPLE_color_buffer_packed_float 1
+
+#define GLEW_APPLE_color_buffer_packed_float GLEW_GET_VAR(__GLEW_APPLE_color_buffer_packed_float)
+
+#endif /* GL_APPLE_color_buffer_packed_float */
+
+/* ---------------------- GL_APPLE_copy_texture_levels --------------------- */
+
+#ifndef GL_APPLE_copy_texture_levels
+#define GL_APPLE_copy_texture_levels 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+
+#define glCopyTextureLevelsAPPLE GLEW_GET_FUN(__glewCopyTextureLevelsAPPLE)
+
+#define GLEW_APPLE_copy_texture_levels GLEW_GET_VAR(__GLEW_APPLE_copy_texture_levels)
+
+#endif /* GL_APPLE_copy_texture_levels */
+
+/* ------------------------- GL_APPLE_element_array ------------------------ */
+
+#ifndef GL_APPLE_element_array
+#define GL_APPLE_element_array 1
+
+#define GL_ELEMENT_ARRAY_APPLE 0x8A0C
+#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D
+#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount);
+
+#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE)
+#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE)
+#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE)
+#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE)
+#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE)
+
+#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array)
+
+#endif /* GL_APPLE_element_array */
+
+/* ----------------------------- GL_APPLE_fence ---------------------------- */
+
+#ifndef GL_APPLE_fence
+#define GL_APPLE_fence 1
+
+#define GL_DRAW_PIXELS_APPLE 0x8A0A
+#define GL_FENCE_APPLE 0x8A0B
+
+typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences);
+typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name);
+typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences);
+typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name);
+
+#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE)
+#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE)
+#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE)
+#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE)
+#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE)
+#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE)
+#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE)
+#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE)
+
+#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence)
+
+#endif /* GL_APPLE_fence */
+
+/* ------------------------- GL_APPLE_float_pixels ------------------------- */
+
+#ifndef GL_APPLE_float_pixels
+#define GL_APPLE_float_pixels 1
+
+#define GL_HALF_APPLE 0x140B
+#define GL_RGBA_FLOAT32_APPLE 0x8814
+#define GL_RGB_FLOAT32_APPLE 0x8815
+#define GL_ALPHA_FLOAT32_APPLE 0x8816
+#define GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define GL_RGBA_FLOAT16_APPLE 0x881A
+#define GL_RGB_FLOAT16_APPLE 0x881B
+#define GL_ALPHA_FLOAT16_APPLE 0x881C
+#define GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define GL_COLOR_FLOAT_APPLE 0x8A0F
+
+#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels)
+
+#endif /* GL_APPLE_float_pixels */
+
+/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_APPLE_flush_buffer_range 1
+
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+
+typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size);
+
+#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE)
+#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE)
+
+#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range)
+
+#endif /* GL_APPLE_flush_buffer_range */
+
+/* -------------------- GL_APPLE_framebuffer_multisample ------------------- */
+
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+
+#define glRenderbufferStorageMultisampleAPPLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleAPPLE)
+#define glResolveMultisampleFramebufferAPPLE GLEW_GET_FUN(__glewResolveMultisampleFramebufferAPPLE)
+
+#define GLEW_APPLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_APPLE_framebuffer_multisample)
+
+#endif /* GL_APPLE_framebuffer_multisample */
+
+/* ----------------------- GL_APPLE_object_purgeable ----------------------- */
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_PURGEABLE_APPLE 0x8A1D
+
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params);
+typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+
+#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE)
+#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE)
+#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE)
+
+#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable)
+
+#endif /* GL_APPLE_object_purgeable */
+
+/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */
+
+#ifndef GL_APPLE_pixel_buffer
+#define GL_APPLE_pixel_buffer 1
+
+#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10
+
+#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer)
+
+#endif /* GL_APPLE_pixel_buffer */
+
+/* ---------------------------- GL_APPLE_rgb_422 --------------------------- */
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#define GL_RGB_422_APPLE 0x8A1F
+#define GL_RGB_RAW_422_APPLE 0x8A51
+
+#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422)
+
+#endif /* GL_APPLE_rgb_422 */
+
+/* --------------------------- GL_APPLE_row_bytes -------------------------- */
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+
+#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes)
+
+#endif /* GL_APPLE_row_bytes */
+
+/* ------------------------ GL_APPLE_specular_vector ----------------------- */
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+
+#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector)
+
+#endif /* GL_APPLE_specular_vector */
+
+/* ----------------------------- GL_APPLE_sync ----------------------------- */
+
+#ifndef GL_APPLE_sync
+#define GL_APPLE_sync 1
+
+#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001
+#define GL_SYNC_OBJECT_APPLE 0x8A53
+#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
+#define GL_OBJECT_TYPE_APPLE 0x9112
+#define GL_SYNC_CONDITION_APPLE 0x9113
+#define GL_SYNC_STATUS_APPLE 0x9114
+#define GL_SYNC_FLAGS_APPLE 0x9115
+#define GL_SYNC_FENCE_APPLE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define GL_UNSIGNALED_APPLE 0x9118
+#define GL_SIGNALED_APPLE 0x9119
+#define GL_ALREADY_SIGNALED_APPLE 0x911A
+#define GL_TIMEOUT_EXPIRED_APPLE 0x911B
+#define GL_CONDITION_SATISFIED_APPLE 0x911C
+#define GL_WAIT_FAILED_APPLE 0x911D
+#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull
+
+typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync GLsync, GLbitfield flags, GLuint64 timeout);
+typedef void (GLAPIENTRY * PFNGLDELETESYNCAPPLEPROC) (GLsync GLsync);
+typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETSYNCIVAPPLEPROC) (GLsync GLsync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values);
+typedef GLboolean (GLAPIENTRY * PFNGLISSYNCAPPLEPROC) (GLsync GLsync);
+typedef void (GLAPIENTRY * PFNGLWAITSYNCAPPLEPROC) (GLsync GLsync, GLbitfield flags, GLuint64 timeout);
+
+#define glClientWaitSyncAPPLE GLEW_GET_FUN(__glewClientWaitSyncAPPLE)
+#define glDeleteSyncAPPLE GLEW_GET_FUN(__glewDeleteSyncAPPLE)
+#define glFenceSyncAPPLE GLEW_GET_FUN(__glewFenceSyncAPPLE)
+#define glGetInteger64vAPPLE GLEW_GET_FUN(__glewGetInteger64vAPPLE)
+#define glGetSyncivAPPLE GLEW_GET_FUN(__glewGetSyncivAPPLE)
+#define glIsSyncAPPLE GLEW_GET_FUN(__glewIsSyncAPPLE)
+#define glWaitSyncAPPLE GLEW_GET_FUN(__glewWaitSyncAPPLE)
+
+#define GLEW_APPLE_sync GLEW_GET_VAR(__GLEW_APPLE_sync)
+
+#endif /* GL_APPLE_sync */
+
+/* -------------------- GL_APPLE_texture_2D_limited_npot ------------------- */
+
+#ifndef GL_APPLE_texture_2D_limited_npot
+#define GL_APPLE_texture_2D_limited_npot 1
+
+#define GLEW_APPLE_texture_2D_limited_npot GLEW_GET_VAR(__GLEW_APPLE_texture_2D_limited_npot)
+
+#endif /* GL_APPLE_texture_2D_limited_npot */
+
+/* -------------------- GL_APPLE_texture_format_BGRA8888 ------------------- */
+
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+
+#define GL_BGRA_EXT 0x80E1
+#define GL_BGRA8_EXT 0x93A1
+
+#define GLEW_APPLE_texture_format_BGRA8888 GLEW_GET_VAR(__GLEW_APPLE_texture_format_BGRA8888)
+
+#endif /* GL_APPLE_texture_format_BGRA8888 */
+
+/* ----------------------- GL_APPLE_texture_max_level ---------------------- */
+
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+
+#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+
+#define GLEW_APPLE_texture_max_level GLEW_GET_VAR(__GLEW_APPLE_texture_max_level)
+
+#endif /* GL_APPLE_texture_max_level */
+
+/* --------------------- GL_APPLE_texture_packed_float --------------------- */
+
+#ifndef GL_APPLE_texture_packed_float
+#define GL_APPLE_texture_packed_float 1
+
+#define GL_R11F_G11F_B10F_APPLE 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B
+#define GL_RGB9_E5_APPLE 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E
+
+#define GLEW_APPLE_texture_packed_float GLEW_GET_VAR(__GLEW_APPLE_texture_packed_float)
+
+#endif /* GL_APPLE_texture_packed_float */
+
+/* ------------------------- GL_APPLE_texture_range ------------------------ */
+
+#ifndef GL_APPLE_texture_range
+#define GL_APPLE_texture_range 1
+
+#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define GL_STORAGE_PRIVATE_APPLE 0x85BD
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params);
+typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, void *pointer);
+
+#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE)
+#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE)
+
+#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range)
+
+#endif /* GL_APPLE_texture_range */
+
+/* ------------------------ GL_APPLE_transform_hint ------------------------ */
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+
+#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint)
+
+#endif /* GL_APPLE_transform_hint */
+
+/* ---------------------- GL_APPLE_vertex_array_object --------------------- */
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_APPLE_vertex_array_object 1
+
+#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array);
+typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays);
+typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array);
+
+#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE)
+#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE)
+#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE)
+#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE)
+
+#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object)
+
+#endif /* GL_APPLE_vertex_array_object */
+
+/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_APPLE_vertex_array_range 1
+
+#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_STORAGE_CLIENT_APPLE 0x85B4
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+
+typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer);
+
+#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE)
+#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE)
+#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE)
+
+#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range)
+
+#endif /* GL_APPLE_vertex_array_range */
+
+/* ------------------- GL_APPLE_vertex_program_evaluators ------------------ */
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points);
+
+#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE)
+#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE)
+#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE)
+#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE)
+#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE)
+#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE)
+#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE)
+
+#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators)
+
+#endif /* GL_APPLE_vertex_program_evaluators */
+
+/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_APPLE_ycbcr_422 1
+
+#define GL_YCBCR_422_APPLE 0x85B9
+
+#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422)
+
+#endif /* GL_APPLE_ycbcr_422 */
+
+/* ------------------------ GL_ARB_ES2_compatibility ----------------------- */
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_ARB_ES2_compatibility 1
+
+#define GL_FIXED 0x140C
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_RGB565 0x8D62
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+
+typedef int GLfixed;
+
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f);
+typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision);
+typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const void*binary, GLsizei length);
+
+#define glClearDepthf GLEW_GET_FUN(__glewClearDepthf)
+#define glDepthRangef GLEW_GET_FUN(__glewDepthRangef)
+#define glGetShaderPrecisionFormat GLEW_GET_FUN(__glewGetShaderPrecisionFormat)
+#define glReleaseShaderCompiler GLEW_GET_FUN(__glewReleaseShaderCompiler)
+#define glShaderBinary GLEW_GET_FUN(__glewShaderBinary)
+
+#define GLEW_ARB_ES2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES2_compatibility)
+
+#endif /* GL_ARB_ES2_compatibility */
+
+/* ----------------------- GL_ARB_ES3_1_compatibility ---------------------- */
+
+#ifndef GL_ARB_ES3_1_compatibility
+#define GL_ARB_ES3_1_compatibility 1
+
+typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers);
+
+#define glMemoryBarrierByRegion GLEW_GET_FUN(__glewMemoryBarrierByRegion)
+
+#define GLEW_ARB_ES3_1_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_1_compatibility)
+
+#endif /* GL_ARB_ES3_1_compatibility */
+
+/* ----------------------- GL_ARB_ES3_2_compatibility ---------------------- */
+
+#ifndef GL_ARB_ES3_2_compatibility
+#define GL_ARB_ES3_2_compatibility 1
+
+#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE
+#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381
+#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382
+
+typedef void (GLAPIENTRY * PFNGLPRIMITIVEBOUNDINGBOXARBPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+
+#define glPrimitiveBoundingBoxARB GLEW_GET_FUN(__glewPrimitiveBoundingBoxARB)
+
+#define GLEW_ARB_ES3_2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_2_compatibility)
+
+#endif /* GL_ARB_ES3_2_compatibility */
+
+/* ------------------------ GL_ARB_ES3_compatibility ----------------------- */
+
+#ifndef GL_ARB_ES3_compatibility
+#define GL_ARB_ES3_compatibility 1
+
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+
+#define GLEW_ARB_ES3_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_compatibility)
+
+#endif /* GL_ARB_ES3_compatibility */
+
+/* ------------------------ GL_ARB_arrays_of_arrays ------------------------ */
+
+#ifndef GL_ARB_arrays_of_arrays
+#define GL_ARB_arrays_of_arrays 1
+
+#define GLEW_ARB_arrays_of_arrays GLEW_GET_VAR(__GLEW_ARB_arrays_of_arrays)
+
+#endif /* GL_ARB_arrays_of_arrays */
+
+/* -------------------------- GL_ARB_base_instance ------------------------- */
+
+#ifndef GL_ARB_base_instance
+#define GL_ARB_base_instance 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+
+#define glDrawArraysInstancedBaseInstance GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstance)
+#define glDrawElementsInstancedBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstance)
+#define glDrawElementsInstancedBaseVertexBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstance)
+
+#define GLEW_ARB_base_instance GLEW_GET_VAR(__GLEW_ARB_base_instance)
+
+#endif /* GL_ARB_base_instance */
+
+/* ------------------------ GL_ARB_bindless_texture ------------------------ */
+
+#ifndef GL_ARB_bindless_texture
+#define GL_ARB_bindless_texture 1
+
+#define GL_UNSIGNED_INT64_ARB 0x140F
+
+typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle);
+typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT* v);
+
+#define glGetImageHandleARB GLEW_GET_FUN(__glewGetImageHandleARB)
+#define glGetTextureHandleARB GLEW_GET_FUN(__glewGetTextureHandleARB)
+#define glGetTextureSamplerHandleARB GLEW_GET_FUN(__glewGetTextureSamplerHandleARB)
+#define glGetVertexAttribLui64vARB GLEW_GET_FUN(__glewGetVertexAttribLui64vARB)
+#define glIsImageHandleResidentARB GLEW_GET_FUN(__glewIsImageHandleResidentARB)
+#define glIsTextureHandleResidentARB GLEW_GET_FUN(__glewIsTextureHandleResidentARB)
+#define glMakeImageHandleNonResidentARB GLEW_GET_FUN(__glewMakeImageHandleNonResidentARB)
+#define glMakeImageHandleResidentARB GLEW_GET_FUN(__glewMakeImageHandleResidentARB)
+#define glMakeTextureHandleNonResidentARB GLEW_GET_FUN(__glewMakeTextureHandleNonResidentARB)
+#define glMakeTextureHandleResidentARB GLEW_GET_FUN(__glewMakeTextureHandleResidentARB)
+#define glProgramUniformHandleui64ARB GLEW_GET_FUN(__glewProgramUniformHandleui64ARB)
+#define glProgramUniformHandleui64vARB GLEW_GET_FUN(__glewProgramUniformHandleui64vARB)
+#define glUniformHandleui64ARB GLEW_GET_FUN(__glewUniformHandleui64ARB)
+#define glUniformHandleui64vARB GLEW_GET_FUN(__glewUniformHandleui64vARB)
+#define glVertexAttribL1ui64ARB GLEW_GET_FUN(__glewVertexAttribL1ui64ARB)
+#define glVertexAttribL1ui64vARB GLEW_GET_FUN(__glewVertexAttribL1ui64vARB)
+
+#define GLEW_ARB_bindless_texture GLEW_GET_VAR(__GLEW_ARB_bindless_texture)
+
+#endif /* GL_ARB_bindless_texture */
+
+/* ----------------------- GL_ARB_blend_func_extended ---------------------- */
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_ARB_blend_func_extended 1
+
+#define GL_SRC1_COLOR 0x88F9
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name);
+typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar * name);
+
+#define glBindFragDataLocationIndexed GLEW_GET_FUN(__glewBindFragDataLocationIndexed)
+#define glGetFragDataIndex GLEW_GET_FUN(__glewGetFragDataIndex)
+
+#define GLEW_ARB_blend_func_extended GLEW_GET_VAR(__GLEW_ARB_blend_func_extended)
+
+#endif /* GL_ARB_blend_func_extended */
+
+/* ------------------------- GL_ARB_buffer_storage ------------------------- */
+
+#ifndef GL_ARB_buffer_storage
+#define GL_ARB_buffer_storage 1
+
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_PERSISTENT_BIT 0x00000040
+#define GL_MAP_COHERENT_BIT 0x00000080
+#define GL_DYNAMIC_STORAGE_BIT 0x0100
+#define GL_CLIENT_STORAGE_BIT 0x0200
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000
+#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F
+#define GL_BUFFER_STORAGE_FLAGS 0x8220
+
+typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+
+#define glBufferStorage GLEW_GET_FUN(__glewBufferStorage)
+
+#define GLEW_ARB_buffer_storage GLEW_GET_VAR(__GLEW_ARB_buffer_storage)
+
+#endif /* GL_ARB_buffer_storage */
+
+/* ---------------------------- GL_ARB_cl_event ---------------------------- */
+
+#ifndef GL_ARB_cl_event
+#define GL_ARB_cl_event 1
+
+#define GL_SYNC_CL_EVENT_ARB 0x8240
+#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241
+
+typedef struct _cl_context *cl_context;
+typedef struct _cl_event *cl_event;
+
+typedef GLsync (GLAPIENTRY * PFNGLCREATESYNCFROMCLEVENTARBPROC) (cl_context context, cl_event event, GLbitfield flags);
+
+#define glCreateSyncFromCLeventARB GLEW_GET_FUN(__glewCreateSyncFromCLeventARB)
+
+#define GLEW_ARB_cl_event GLEW_GET_VAR(__GLEW_ARB_cl_event)
+
+#endif /* GL_ARB_cl_event */
+
+/* ----------------------- GL_ARB_clear_buffer_object ---------------------- */
+
+#ifndef GL_ARB_clear_buffer_object
+#define GL_ARB_clear_buffer_object 1
+
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
+
+#define glClearBufferData GLEW_GET_FUN(__glewClearBufferData)
+#define glClearBufferSubData GLEW_GET_FUN(__glewClearBufferSubData)
+#define glClearNamedBufferDataEXT GLEW_GET_FUN(__glewClearNamedBufferDataEXT)
+#define glClearNamedBufferSubDataEXT GLEW_GET_FUN(__glewClearNamedBufferSubDataEXT)
+
+#define GLEW_ARB_clear_buffer_object GLEW_GET_VAR(__GLEW_ARB_clear_buffer_object)
+
+#endif /* GL_ARB_clear_buffer_object */
+
+/* -------------------------- GL_ARB_clear_texture ------------------------- */
+
+#ifndef GL_ARB_clear_texture
+#define GL_ARB_clear_texture 1
+
+#define GL_CLEAR_TEXTURE 0x9365
+
+typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+
+#define glClearTexImage GLEW_GET_FUN(__glewClearTexImage)
+#define glClearTexSubImage GLEW_GET_FUN(__glewClearTexSubImage)
+
+#define GLEW_ARB_clear_texture GLEW_GET_VAR(__GLEW_ARB_clear_texture)
+
+#endif /* GL_ARB_clear_texture */
+
+/* -------------------------- GL_ARB_clip_control -------------------------- */
+
+#ifndef GL_ARB_clip_control
+#define GL_ARB_clip_control 1
+
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_CLIP_ORIGIN 0x935C
+#define GL_CLIP_DEPTH_MODE 0x935D
+#define GL_NEGATIVE_ONE_TO_ONE 0x935E
+#define GL_ZERO_TO_ONE 0x935F
+
+typedef void (GLAPIENTRY * PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth);
+
+#define glClipControl GLEW_GET_FUN(__glewClipControl)
+
+#define GLEW_ARB_clip_control GLEW_GET_VAR(__GLEW_ARB_clip_control)
+
+#endif /* GL_ARB_clip_control */
+
+/* ----------------------- GL_ARB_color_buffer_float ----------------------- */
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_ARB_color_buffer_float 1
+
+#define GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define GL_CLAMP_READ_COLOR_ARB 0x891C
+#define GL_FIXED_ONLY_ARB 0x891D
+
+typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
+
+#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB)
+
+#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float)
+
+#endif /* GL_ARB_color_buffer_float */
+
+/* -------------------------- GL_ARB_compatibility ------------------------- */
+
+#ifndef GL_ARB_compatibility
+#define GL_ARB_compatibility 1
+
+#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility)
+
+#endif /* GL_ARB_compatibility */
+
+/* ---------------- GL_ARB_compressed_texture_pixel_storage ---------------- */
+
+#ifndef GL_ARB_compressed_texture_pixel_storage
+#define GL_ARB_compressed_texture_pixel_storage 1
+
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+
+#define GLEW_ARB_compressed_texture_pixel_storage GLEW_GET_VAR(__GLEW_ARB_compressed_texture_pixel_storage)
+
+#endif /* GL_ARB_compressed_texture_pixel_storage */
+
+/* ------------------------- GL_ARB_compute_shader ------------------------- */
+
+#ifndef GL_ARB_compute_shader
+#define GL_ARB_compute_shader 1
+
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+
+typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);
+
+#define glDispatchCompute GLEW_GET_FUN(__glewDispatchCompute)
+#define glDispatchComputeIndirect GLEW_GET_FUN(__glewDispatchComputeIndirect)
+
+#define GLEW_ARB_compute_shader GLEW_GET_VAR(__GLEW_ARB_compute_shader)
+
+#endif /* GL_ARB_compute_shader */
+
+/* ------------------- GL_ARB_compute_variable_group_size ------------------ */
+
+#ifndef GL_ARB_compute_variable_group_size
+#define GL_ARB_compute_variable_group_size 1
+
+#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB
+#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF
+#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344
+#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345
+
+typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z);
+
+#define glDispatchComputeGroupSizeARB GLEW_GET_FUN(__glewDispatchComputeGroupSizeARB)
+
+#define GLEW_ARB_compute_variable_group_size GLEW_GET_VAR(__GLEW_ARB_compute_variable_group_size)
+
+#endif /* GL_ARB_compute_variable_group_size */
+
+/* ------------------- GL_ARB_conditional_render_inverted ------------------ */
+
+#ifndef GL_ARB_conditional_render_inverted
+#define GL_ARB_conditional_render_inverted 1
+
+#define GL_QUERY_WAIT_INVERTED 0x8E17
+#define GL_QUERY_NO_WAIT_INVERTED 0x8E18
+#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19
+#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A
+
+#define GLEW_ARB_conditional_render_inverted GLEW_GET_VAR(__GLEW_ARB_conditional_render_inverted)
+
+#endif /* GL_ARB_conditional_render_inverted */
+
+/* ----------------------- GL_ARB_conservative_depth ----------------------- */
+
+#ifndef GL_ARB_conservative_depth
+#define GL_ARB_conservative_depth 1
+
+#define GLEW_ARB_conservative_depth GLEW_GET_VAR(__GLEW_ARB_conservative_depth)
+
+#endif /* GL_ARB_conservative_depth */
+
+/* --------------------------- GL_ARB_copy_buffer -------------------------- */
+
+#ifndef GL_ARB_copy_buffer
+#define GL_ARB_copy_buffer 1
+
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+
+typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size);
+
+#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData)
+
+#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer)
+
+#endif /* GL_ARB_copy_buffer */
+
+/* --------------------------- GL_ARB_copy_image --------------------------- */
+
+#ifndef GL_ARB_copy_image
+#define GL_ARB_copy_image 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+
+#define glCopyImageSubData GLEW_GET_FUN(__glewCopyImageSubData)
+
+#define GLEW_ARB_copy_image GLEW_GET_VAR(__GLEW_ARB_copy_image)
+
+#endif /* GL_ARB_copy_image */
+
+/* -------------------------- GL_ARB_cull_distance ------------------------- */
+
+#ifndef GL_ARB_cull_distance
+#define GL_ARB_cull_distance 1
+
+#define GL_MAX_CULL_DISTANCES 0x82F9
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA
+
+#define GLEW_ARB_cull_distance GLEW_GET_VAR(__GLEW_ARB_cull_distance)
+
+#endif /* GL_ARB_cull_distance */
+
+/* -------------------------- GL_ARB_debug_output -------------------------- */
+
+#ifndef GL_ARB_debug_output
+#define GL_ARB_debug_output 1
+
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
+#define GL_DEBUG_SOURCE_API_ARB 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
+#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
+#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
+#define GL_DEBUG_TYPE_OTHER_ARB 0x8251
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
+#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
+
+typedef void (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam);
+
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
+typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
+
+#define glDebugMessageCallbackARB GLEW_GET_FUN(__glewDebugMessageCallbackARB)
+#define glDebugMessageControlARB GLEW_GET_FUN(__glewDebugMessageControlARB)
+#define glDebugMessageInsertARB GLEW_GET_FUN(__glewDebugMessageInsertARB)
+#define glGetDebugMessageLogARB GLEW_GET_FUN(__glewGetDebugMessageLogARB)
+
+#define GLEW_ARB_debug_output GLEW_GET_VAR(__GLEW_ARB_debug_output)
+
+#endif /* GL_ARB_debug_output */
+
+/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_ARB_depth_buffer_float 1
+
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+
+#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float)
+
+#endif /* GL_ARB_depth_buffer_float */
+
+/* --------------------------- GL_ARB_depth_clamp -------------------------- */
+
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+
+#define GL_DEPTH_CLAMP 0x864F
+
+#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp)
+
+#endif /* GL_ARB_depth_clamp */
+
+/* -------------------------- GL_ARB_depth_texture ------------------------- */
+
+#ifndef GL_ARB_depth_texture
+#define GL_ARB_depth_texture 1
+
+#define GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+
+#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture)
+
+#endif /* GL_ARB_depth_texture */
+
+/* ----------------------- GL_ARB_derivative_control ----------------------- */
+
+#ifndef GL_ARB_derivative_control
+#define GL_ARB_derivative_control 1
+
+#define GLEW_ARB_derivative_control GLEW_GET_VAR(__GLEW_ARB_derivative_control)
+
+#endif /* GL_ARB_derivative_control */
+
+/* ----------------------- GL_ARB_direct_state_access ---------------------- */
+
+#ifndef GL_ARB_direct_state_access
+#define GL_ARB_direct_state_access 1
+
+#define GL_TEXTURE_TARGET 0x1006
+#define GL_QUERY_TARGET 0x82EA
+
+typedef void (GLAPIENTRY * PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture);
+typedef void (GLAPIENTRY * PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines);
+typedef void (GLAPIENTRY * PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint* samplers);
+typedef void (GLAPIENTRY * PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint* textures);
+typedef void (GLAPIENTRY * PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void** params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);
+typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64* param);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments);
+typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access);
+typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat* param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint* param);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides);
+
+#define glBindTextureUnit GLEW_GET_FUN(__glewBindTextureUnit)
+#define glBlitNamedFramebuffer GLEW_GET_FUN(__glewBlitNamedFramebuffer)
+#define glCheckNamedFramebufferStatus GLEW_GET_FUN(__glewCheckNamedFramebufferStatus)
+#define glClearNamedBufferData GLEW_GET_FUN(__glewClearNamedBufferData)
+#define glClearNamedBufferSubData GLEW_GET_FUN(__glewClearNamedBufferSubData)
+#define glClearNamedFramebufferfi GLEW_GET_FUN(__glewClearNamedFramebufferfi)
+#define glClearNamedFramebufferfv GLEW_GET_FUN(__glewClearNamedFramebufferfv)
+#define glClearNamedFramebufferiv GLEW_GET_FUN(__glewClearNamedFramebufferiv)
+#define glClearNamedFramebufferuiv GLEW_GET_FUN(__glewClearNamedFramebufferuiv)
+#define glCompressedTextureSubImage1D GLEW_GET_FUN(__glewCompressedTextureSubImage1D)
+#define glCompressedTextureSubImage2D GLEW_GET_FUN(__glewCompressedTextureSubImage2D)
+#define glCompressedTextureSubImage3D GLEW_GET_FUN(__glewCompressedTextureSubImage3D)
+#define glCopyNamedBufferSubData GLEW_GET_FUN(__glewCopyNamedBufferSubData)
+#define glCopyTextureSubImage1D GLEW_GET_FUN(__glewCopyTextureSubImage1D)
+#define glCopyTextureSubImage2D GLEW_GET_FUN(__glewCopyTextureSubImage2D)
+#define glCopyTextureSubImage3D GLEW_GET_FUN(__glewCopyTextureSubImage3D)
+#define glCreateBuffers GLEW_GET_FUN(__glewCreateBuffers)
+#define glCreateFramebuffers GLEW_GET_FUN(__glewCreateFramebuffers)
+#define glCreateProgramPipelines GLEW_GET_FUN(__glewCreateProgramPipelines)
+#define glCreateQueries GLEW_GET_FUN(__glewCreateQueries)
+#define glCreateRenderbuffers GLEW_GET_FUN(__glewCreateRenderbuffers)
+#define glCreateSamplers GLEW_GET_FUN(__glewCreateSamplers)
+#define glCreateTextures GLEW_GET_FUN(__glewCreateTextures)
+#define glCreateTransformFeedbacks GLEW_GET_FUN(__glewCreateTransformFeedbacks)
+#define glCreateVertexArrays GLEW_GET_FUN(__glewCreateVertexArrays)
+#define glDisableVertexArrayAttrib GLEW_GET_FUN(__glewDisableVertexArrayAttrib)
+#define glEnableVertexArrayAttrib GLEW_GET_FUN(__glewEnableVertexArrayAttrib)
+#define glFlushMappedNamedBufferRange GLEW_GET_FUN(__glewFlushMappedNamedBufferRange)
+#define glGenerateTextureMipmap GLEW_GET_FUN(__glewGenerateTextureMipmap)
+#define glGetCompressedTextureImage GLEW_GET_FUN(__glewGetCompressedTextureImage)
+#define glGetNamedBufferParameteri64v GLEW_GET_FUN(__glewGetNamedBufferParameteri64v)
+#define glGetNamedBufferParameteriv GLEW_GET_FUN(__glewGetNamedBufferParameteriv)
+#define glGetNamedBufferPointerv GLEW_GET_FUN(__glewGetNamedBufferPointerv)
+#define glGetNamedBufferSubData GLEW_GET_FUN(__glewGetNamedBufferSubData)
+#define glGetNamedFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameteriv)
+#define glGetNamedFramebufferParameteriv GLEW_GET_FUN(__glewGetNamedFramebufferParameteriv)
+#define glGetNamedRenderbufferParameteriv GLEW_GET_FUN(__glewGetNamedRenderbufferParameteriv)
+#define glGetQueryBufferObjecti64v GLEW_GET_FUN(__glewGetQueryBufferObjecti64v)
+#define glGetQueryBufferObjectiv GLEW_GET_FUN(__glewGetQueryBufferObjectiv)
+#define glGetQueryBufferObjectui64v GLEW_GET_FUN(__glewGetQueryBufferObjectui64v)
+#define glGetQueryBufferObjectuiv GLEW_GET_FUN(__glewGetQueryBufferObjectuiv)
+#define glGetTextureImage GLEW_GET_FUN(__glewGetTextureImage)
+#define glGetTextureLevelParameterfv GLEW_GET_FUN(__glewGetTextureLevelParameterfv)
+#define glGetTextureLevelParameteriv GLEW_GET_FUN(__glewGetTextureLevelParameteriv)
+#define glGetTextureParameterIiv GLEW_GET_FUN(__glewGetTextureParameterIiv)
+#define glGetTextureParameterIuiv GLEW_GET_FUN(__glewGetTextureParameterIuiv)
+#define glGetTextureParameterfv GLEW_GET_FUN(__glewGetTextureParameterfv)
+#define glGetTextureParameteriv GLEW_GET_FUN(__glewGetTextureParameteriv)
+#define glGetTransformFeedbacki64_v GLEW_GET_FUN(__glewGetTransformFeedbacki64_v)
+#define glGetTransformFeedbacki_v GLEW_GET_FUN(__glewGetTransformFeedbacki_v)
+#define glGetTransformFeedbackiv GLEW_GET_FUN(__glewGetTransformFeedbackiv)
+#define glGetVertexArrayIndexed64iv GLEW_GET_FUN(__glewGetVertexArrayIndexed64iv)
+#define glGetVertexArrayIndexediv GLEW_GET_FUN(__glewGetVertexArrayIndexediv)
+#define glGetVertexArrayiv GLEW_GET_FUN(__glewGetVertexArrayiv)
+#define glInvalidateNamedFramebufferData GLEW_GET_FUN(__glewInvalidateNamedFramebufferData)
+#define glInvalidateNamedFramebufferSubData GLEW_GET_FUN(__glewInvalidateNamedFramebufferSubData)
+#define glMapNamedBuffer GLEW_GET_FUN(__glewMapNamedBuffer)
+#define glMapNamedBufferRange GLEW_GET_FUN(__glewMapNamedBufferRange)
+#define glNamedBufferData GLEW_GET_FUN(__glewNamedBufferData)
+#define glNamedBufferStorage GLEW_GET_FUN(__glewNamedBufferStorage)
+#define glNamedBufferSubData GLEW_GET_FUN(__glewNamedBufferSubData)
+#define glNamedFramebufferDrawBuffer GLEW_GET_FUN(__glewNamedFramebufferDrawBuffer)
+#define glNamedFramebufferDrawBuffers GLEW_GET_FUN(__glewNamedFramebufferDrawBuffers)
+#define glNamedFramebufferParameteri GLEW_GET_FUN(__glewNamedFramebufferParameteri)
+#define glNamedFramebufferReadBuffer GLEW_GET_FUN(__glewNamedFramebufferReadBuffer)
+#define glNamedFramebufferRenderbuffer GLEW_GET_FUN(__glewNamedFramebufferRenderbuffer)
+#define glNamedFramebufferTexture GLEW_GET_FUN(__glewNamedFramebufferTexture)
+#define glNamedFramebufferTextureLayer GLEW_GET_FUN(__glewNamedFramebufferTextureLayer)
+#define glNamedRenderbufferStorage GLEW_GET_FUN(__glewNamedRenderbufferStorage)
+#define glNamedRenderbufferStorageMultisample GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisample)
+#define glTextureBuffer GLEW_GET_FUN(__glewTextureBuffer)
+#define glTextureBufferRange GLEW_GET_FUN(__glewTextureBufferRange)
+#define glTextureParameterIiv GLEW_GET_FUN(__glewTextureParameterIiv)
+#define glTextureParameterIuiv GLEW_GET_FUN(__glewTextureParameterIuiv)
+#define glTextureParameterf GLEW_GET_FUN(__glewTextureParameterf)
+#define glTextureParameterfv GLEW_GET_FUN(__glewTextureParameterfv)
+#define glTextureParameteri GLEW_GET_FUN(__glewTextureParameteri)
+#define glTextureParameteriv GLEW_GET_FUN(__glewTextureParameteriv)
+#define glTextureStorage1D GLEW_GET_FUN(__glewTextureStorage1D)
+#define glTextureStorage2D GLEW_GET_FUN(__glewTextureStorage2D)
+#define glTextureStorage2DMultisample GLEW_GET_FUN(__glewTextureStorage2DMultisample)
+#define glTextureStorage3D GLEW_GET_FUN(__glewTextureStorage3D)
+#define glTextureStorage3DMultisample GLEW_GET_FUN(__glewTextureStorage3DMultisample)
+#define glTextureSubImage1D GLEW_GET_FUN(__glewTextureSubImage1D)
+#define glTextureSubImage2D GLEW_GET_FUN(__glewTextureSubImage2D)
+#define glTextureSubImage3D GLEW_GET_FUN(__glewTextureSubImage3D)
+#define glTransformFeedbackBufferBase GLEW_GET_FUN(__glewTransformFeedbackBufferBase)
+#define glTransformFeedbackBufferRange GLEW_GET_FUN(__glewTransformFeedbackBufferRange)
+#define glUnmapNamedBuffer GLEW_GET_FUN(__glewUnmapNamedBuffer)
+#define glVertexArrayAttribBinding GLEW_GET_FUN(__glewVertexArrayAttribBinding)
+#define glVertexArrayAttribFormat GLEW_GET_FUN(__glewVertexArrayAttribFormat)
+#define glVertexArrayAttribIFormat GLEW_GET_FUN(__glewVertexArrayAttribIFormat)
+#define glVertexArrayAttribLFormat GLEW_GET_FUN(__glewVertexArrayAttribLFormat)
+#define glVertexArrayBindingDivisor GLEW_GET_FUN(__glewVertexArrayBindingDivisor)
+#define glVertexArrayElementBuffer GLEW_GET_FUN(__glewVertexArrayElementBuffer)
+#define glVertexArrayVertexBuffer GLEW_GET_FUN(__glewVertexArrayVertexBuffer)
+#define glVertexArrayVertexBuffers GLEW_GET_FUN(__glewVertexArrayVertexBuffers)
+
+#define GLEW_ARB_direct_state_access GLEW_GET_VAR(__GLEW_ARB_direct_state_access)
+
+#endif /* GL_ARB_direct_state_access */
+
+/* -------------------------- GL_ARB_draw_buffers -------------------------- */
+
+#ifndef GL_ARB_draw_buffers
+#define GL_ARB_draw_buffers 1
+
+#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define GL_DRAW_BUFFER0_ARB 0x8825
+#define GL_DRAW_BUFFER1_ARB 0x8826
+#define GL_DRAW_BUFFER2_ARB 0x8827
+#define GL_DRAW_BUFFER3_ARB 0x8828
+#define GL_DRAW_BUFFER4_ARB 0x8829
+#define GL_DRAW_BUFFER5_ARB 0x882A
+#define GL_DRAW_BUFFER6_ARB 0x882B
+#define GL_DRAW_BUFFER7_ARB 0x882C
+#define GL_DRAW_BUFFER8_ARB 0x882D
+#define GL_DRAW_BUFFER9_ARB 0x882E
+#define GL_DRAW_BUFFER10_ARB 0x882F
+#define GL_DRAW_BUFFER11_ARB 0x8830
+#define GL_DRAW_BUFFER12_ARB 0x8831
+#define GL_DRAW_BUFFER13_ARB 0x8832
+#define GL_DRAW_BUFFER14_ARB 0x8833
+#define GL_DRAW_BUFFER15_ARB 0x8834
+
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs);
+
+#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB)
+
+#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers)
+
+#endif /* GL_ARB_draw_buffers */
+
+/* ----------------------- GL_ARB_draw_buffers_blend ----------------------- */
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);
+
+#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB)
+#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB)
+#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB)
+#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB)
+
+#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend)
+
+#endif /* GL_ARB_draw_buffers_blend */
+
+/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, void *indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, void *indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei* count, GLenum type, void**indices, GLsizei primcount, GLint *basevertex);
+
+#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex)
+#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex)
+#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex)
+#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex)
+
+#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex)
+
+#endif /* GL_ARB_draw_elements_base_vertex */
+
+/* -------------------------- GL_ARB_draw_indirect ------------------------- */
+
+#ifndef GL_ARB_draw_indirect
+#define GL_ARB_draw_indirect 1
+
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect);
+
+#define glDrawArraysIndirect GLEW_GET_FUN(__glewDrawArraysIndirect)
+#define glDrawElementsIndirect GLEW_GET_FUN(__glewDrawElementsIndirect)
+
+#define GLEW_ARB_draw_indirect GLEW_GET_VAR(__GLEW_ARB_draw_indirect)
+
+#endif /* GL_ARB_draw_indirect */
+
+/* ------------------------- GL_ARB_draw_instanced ------------------------- */
+
+#ifndef GL_ARB_draw_instanced
+#define GL_ARB_draw_instanced 1
+
+#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced)
+
+#endif /* GL_ARB_draw_instanced */
+
+/* ------------------------ GL_ARB_enhanced_layouts ------------------------ */
+
+#ifndef GL_ARB_enhanced_layouts
+#define GL_ARB_enhanced_layouts 1
+
+#define GL_LOCATION_COMPONENT 0x934A
+#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B
+#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C
+
+#define GLEW_ARB_enhanced_layouts GLEW_GET_VAR(__GLEW_ARB_enhanced_layouts)
+
+#endif /* GL_ARB_enhanced_layouts */
+
+/* -------------------- GL_ARB_explicit_attrib_location -------------------- */
+
+#ifndef GL_ARB_explicit_attrib_location
+#define GL_ARB_explicit_attrib_location 1
+
+#define GLEW_ARB_explicit_attrib_location GLEW_GET_VAR(__GLEW_ARB_explicit_attrib_location)
+
+#endif /* GL_ARB_explicit_attrib_location */
+
+/* -------------------- GL_ARB_explicit_uniform_location ------------------- */
+
+#ifndef GL_ARB_explicit_uniform_location
+#define GL_ARB_explicit_uniform_location 1
+
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+
+#define GLEW_ARB_explicit_uniform_location GLEW_GET_VAR(__GLEW_ARB_explicit_uniform_location)
+
+#endif /* GL_ARB_explicit_uniform_location */
+
+/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+
+#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions)
+
+#endif /* GL_ARB_fragment_coord_conventions */
+
+/* --------------------- GL_ARB_fragment_layer_viewport -------------------- */
+
+#ifndef GL_ARB_fragment_layer_viewport
+#define GL_ARB_fragment_layer_viewport 1
+
+#define GLEW_ARB_fragment_layer_viewport GLEW_GET_VAR(__GLEW_ARB_fragment_layer_viewport)
+
+#endif /* GL_ARB_fragment_layer_viewport */
+
+/* ------------------------ GL_ARB_fragment_program ------------------------ */
+
+#ifndef GL_ARB_fragment_program
+#define GL_ARB_fragment_program 1
+
+#define GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+
+#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program)
+
+#endif /* GL_ARB_fragment_program */
+
+/* --------------------- GL_ARB_fragment_program_shadow -------------------- */
+
+#ifndef GL_ARB_fragment_program_shadow
+#define GL_ARB_fragment_program_shadow 1
+
+#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow)
+
+#endif /* GL_ARB_fragment_program_shadow */
+
+/* ------------------------- GL_ARB_fragment_shader ------------------------ */
+
+#ifndef GL_ARB_fragment_shader
+#define GL_ARB_fragment_shader 1
+
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+
+#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader)
+
+#endif /* GL_ARB_fragment_shader */
+
+/* -------------------- GL_ARB_fragment_shader_interlock ------------------- */
+
+#ifndef GL_ARB_fragment_shader_interlock
+#define GL_ARB_fragment_shader_interlock 1
+
+#define GLEW_ARB_fragment_shader_interlock GLEW_GET_VAR(__GLEW_ARB_fragment_shader_interlock)
+
+#endif /* GL_ARB_fragment_shader_interlock */
+
+/* ------------------- GL_ARB_framebuffer_no_attachments ------------------- */
+
+#ifndef GL_ARB_framebuffer_no_attachments
+#define GL_ARB_framebuffer_no_attachments 1
+
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param);
+
+#define glFramebufferParameteri GLEW_GET_FUN(__glewFramebufferParameteri)
+#define glGetFramebufferParameteriv GLEW_GET_FUN(__glewGetFramebufferParameteriv)
+#define glGetNamedFramebufferParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferParameterivEXT)
+#define glNamedFramebufferParameteriEXT GLEW_GET_FUN(__glewNamedFramebufferParameteriEXT)
+
+#define GLEW_ARB_framebuffer_no_attachments GLEW_GET_VAR(__GLEW_ARB_framebuffer_no_attachments)
+
+#endif /* GL_ARB_framebuffer_no_attachments */
+
+/* ----------------------- GL_ARB_framebuffer_object ----------------------- */
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_ARB_framebuffer_object 1
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_INDEX 0x8222
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_SRGB 0x8C40
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer);
+typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer)
+#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer)
+#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer)
+#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus)
+#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers)
+#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers)
+#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer)
+#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D)
+#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D)
+#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D)
+#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer)
+#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers)
+#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers)
+#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap)
+#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv)
+#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv)
+#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer)
+#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer)
+#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage)
+#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample)
+
+#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object)
+
+#endif /* GL_ARB_framebuffer_object */
+
+/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_ARB_framebuffer_sRGB 1
+
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+
+#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB)
+
+#endif /* GL_ARB_framebuffer_sRGB */
+
+/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_ARB_geometry_shader4 1
+
+#define GL_LINES_ADJACENCY_ARB 0xA
+#define GL_LINE_STRIP_ADJACENCY_ARB 0xB
+#define GL_TRIANGLES_ADJACENCY_ARB 0xC
+#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD
+#define GL_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define GL_GEOMETRY_SHADER_ARB 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value);
+
+#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB)
+#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB)
+#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB)
+#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB)
+
+#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4)
+
+#endif /* GL_ARB_geometry_shader4 */
+
+/* ----------------------- GL_ARB_get_program_binary ----------------------- */
+
+#ifndef GL_ARB_get_program_binary
+#define GL_ARB_get_program_binary 1
+
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, void*binary);
+typedef void (GLAPIENTRY * PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+
+#define glGetProgramBinary GLEW_GET_FUN(__glewGetProgramBinary)
+#define glProgramBinary GLEW_GET_FUN(__glewProgramBinary)
+#define glProgramParameteri GLEW_GET_FUN(__glewProgramParameteri)
+
+#define GLEW_ARB_get_program_binary GLEW_GET_VAR(__GLEW_ARB_get_program_binary)
+
+#endif /* GL_ARB_get_program_binary */
+
+/* ---------------------- GL_ARB_get_texture_sub_image --------------------- */
+
+#ifndef GL_ARB_get_texture_sub_image
+#define GL_ARB_get_texture_sub_image 1
+
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels);
+typedef void (GLAPIENTRY * PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels);
+
+#define glGetCompressedTextureSubImage GLEW_GET_FUN(__glewGetCompressedTextureSubImage)
+#define glGetTextureSubImage GLEW_GET_FUN(__glewGetTextureSubImage)
+
+#define GLEW_ARB_get_texture_sub_image GLEW_GET_VAR(__GLEW_ARB_get_texture_sub_image)
+
+#endif /* GL_ARB_get_texture_sub_image */
+
+/* ---------------------------- GL_ARB_gl_spirv ---------------------------- */
+
+#ifndef GL_ARB_gl_spirv
+#define GL_ARB_gl_spirv 1
+
+#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551
+#define GL_SPIR_V_BINARY_ARB 0x9552
+
+typedef void (GLAPIENTRY * PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue);
+
+#define glSpecializeShaderARB GLEW_GET_FUN(__glewSpecializeShaderARB)
+
+#define GLEW_ARB_gl_spirv GLEW_GET_VAR(__GLEW_ARB_gl_spirv)
+
+#endif /* GL_ARB_gl_spirv */
+
+/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_ARB_gpu_shader5 1
+
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+
+#define GLEW_ARB_gpu_shader5 GLEW_GET_VAR(__GLEW_ARB_gpu_shader5)
+
+#endif /* GL_ARB_gpu_shader5 */
+
+/* ------------------------- GL_ARB_gpu_shader_fp64 ------------------------ */
+
+#ifndef GL_ARB_gpu_shader_fp64
+#define GL_ARB_gpu_shader_fp64 1
+
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+
+#define glGetUniformdv GLEW_GET_FUN(__glewGetUniformdv)
+#define glUniform1d GLEW_GET_FUN(__glewUniform1d)
+#define glUniform1dv GLEW_GET_FUN(__glewUniform1dv)
+#define glUniform2d GLEW_GET_FUN(__glewUniform2d)
+#define glUniform2dv GLEW_GET_FUN(__glewUniform2dv)
+#define glUniform3d GLEW_GET_FUN(__glewUniform3d)
+#define glUniform3dv GLEW_GET_FUN(__glewUniform3dv)
+#define glUniform4d GLEW_GET_FUN(__glewUniform4d)
+#define glUniform4dv GLEW_GET_FUN(__glewUniform4dv)
+#define glUniformMatrix2dv GLEW_GET_FUN(__glewUniformMatrix2dv)
+#define glUniformMatrix2x3dv GLEW_GET_FUN(__glewUniformMatrix2x3dv)
+#define glUniformMatrix2x4dv GLEW_GET_FUN(__glewUniformMatrix2x4dv)
+#define glUniformMatrix3dv GLEW_GET_FUN(__glewUniformMatrix3dv)
+#define glUniformMatrix3x2dv GLEW_GET_FUN(__glewUniformMatrix3x2dv)
+#define glUniformMatrix3x4dv GLEW_GET_FUN(__glewUniformMatrix3x4dv)
+#define glUniformMatrix4dv GLEW_GET_FUN(__glewUniformMatrix4dv)
+#define glUniformMatrix4x2dv GLEW_GET_FUN(__glewUniformMatrix4x2dv)
+#define glUniformMatrix4x3dv GLEW_GET_FUN(__glewUniformMatrix4x3dv)
+
+#define GLEW_ARB_gpu_shader_fp64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_fp64)
+
+#endif /* GL_ARB_gpu_shader_fp64 */
+
+/* ------------------------ GL_ARB_gpu_shader_int64 ------------------------ */
+
+#ifndef GL_ARB_gpu_shader_int64
+#define GL_ARB_gpu_shader_int64 1
+
+#define GL_INT64_ARB 0x140E
+#define GL_UNSIGNED_INT64_ARB 0x140F
+#define GL_INT64_VEC2_ARB 0x8FE9
+#define GL_INT64_VEC3_ARB 0x8FEA
+#define GL_INT64_VEC4_ARB 0x8FEB
+#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7
+
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VARBPROC) (GLuint program, GLint location, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64ARBPROC) (GLuint program, GLint location, GLint64 x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64ARBPROC) (GLuint program, GLint location, GLuint64 x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1I64ARBPROC) (GLint location, GLint64 x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VARBPROC) (GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64ARBPROC) (GLint location, GLuint64 x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2I64ARBPROC) (GLint location, GLint64 x, GLint64 y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VARBPROC) (GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VARBPROC) (GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VARBPROC) (GLint location, GLsizei count, const GLint64* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value);
+
+#define glGetUniformi64vARB GLEW_GET_FUN(__glewGetUniformi64vARB)
+#define glGetUniformui64vARB GLEW_GET_FUN(__glewGetUniformui64vARB)
+#define glGetnUniformi64vARB GLEW_GET_FUN(__glewGetnUniformi64vARB)
+#define glGetnUniformui64vARB GLEW_GET_FUN(__glewGetnUniformui64vARB)
+#define glProgramUniform1i64ARB GLEW_GET_FUN(__glewProgramUniform1i64ARB)
+#define glProgramUniform1i64vARB GLEW_GET_FUN(__glewProgramUniform1i64vARB)
+#define glProgramUniform1ui64ARB GLEW_GET_FUN(__glewProgramUniform1ui64ARB)
+#define glProgramUniform1ui64vARB GLEW_GET_FUN(__glewProgramUniform1ui64vARB)
+#define glProgramUniform2i64ARB GLEW_GET_FUN(__glewProgramUniform2i64ARB)
+#define glProgramUniform2i64vARB GLEW_GET_FUN(__glewProgramUniform2i64vARB)
+#define glProgramUniform2ui64ARB GLEW_GET_FUN(__glewProgramUniform2ui64ARB)
+#define glProgramUniform2ui64vARB GLEW_GET_FUN(__glewProgramUniform2ui64vARB)
+#define glProgramUniform3i64ARB GLEW_GET_FUN(__glewProgramUniform3i64ARB)
+#define glProgramUniform3i64vARB GLEW_GET_FUN(__glewProgramUniform3i64vARB)
+#define glProgramUniform3ui64ARB GLEW_GET_FUN(__glewProgramUniform3ui64ARB)
+#define glProgramUniform3ui64vARB GLEW_GET_FUN(__glewProgramUniform3ui64vARB)
+#define glProgramUniform4i64ARB GLEW_GET_FUN(__glewProgramUniform4i64ARB)
+#define glProgramUniform4i64vARB GLEW_GET_FUN(__glewProgramUniform4i64vARB)
+#define glProgramUniform4ui64ARB GLEW_GET_FUN(__glewProgramUniform4ui64ARB)
+#define glProgramUniform4ui64vARB GLEW_GET_FUN(__glewProgramUniform4ui64vARB)
+#define glUniform1i64ARB GLEW_GET_FUN(__glewUniform1i64ARB)
+#define glUniform1i64vARB GLEW_GET_FUN(__glewUniform1i64vARB)
+#define glUniform1ui64ARB GLEW_GET_FUN(__glewUniform1ui64ARB)
+#define glUniform1ui64vARB GLEW_GET_FUN(__glewUniform1ui64vARB)
+#define glUniform2i64ARB GLEW_GET_FUN(__glewUniform2i64ARB)
+#define glUniform2i64vARB GLEW_GET_FUN(__glewUniform2i64vARB)
+#define glUniform2ui64ARB GLEW_GET_FUN(__glewUniform2ui64ARB)
+#define glUniform2ui64vARB GLEW_GET_FUN(__glewUniform2ui64vARB)
+#define glUniform3i64ARB GLEW_GET_FUN(__glewUniform3i64ARB)
+#define glUniform3i64vARB GLEW_GET_FUN(__glewUniform3i64vARB)
+#define glUniform3ui64ARB GLEW_GET_FUN(__glewUniform3ui64ARB)
+#define glUniform3ui64vARB GLEW_GET_FUN(__glewUniform3ui64vARB)
+#define glUniform4i64ARB GLEW_GET_FUN(__glewUniform4i64ARB)
+#define glUniform4i64vARB GLEW_GET_FUN(__glewUniform4i64vARB)
+#define glUniform4ui64ARB GLEW_GET_FUN(__glewUniform4ui64ARB)
+#define glUniform4ui64vARB GLEW_GET_FUN(__glewUniform4ui64vARB)
+
+#define GLEW_ARB_gpu_shader_int64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_int64)
+
+#endif /* GL_ARB_gpu_shader_int64 */
+
+/* ------------------------ GL_ARB_half_float_pixel ------------------------ */
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_ARB_half_float_pixel 1
+
+#define GL_HALF_FLOAT_ARB 0x140B
+
+#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel)
+
+#endif /* GL_ARB_half_float_pixel */
+
+/* ------------------------ GL_ARB_half_float_vertex ----------------------- */
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex 1
+
+#define GL_HALF_FLOAT 0x140B
+
+#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex)
+
+#endif /* GL_ARB_half_float_vertex */
+
+/* ----------------------------- GL_ARB_imaging ---------------------------- */
+
+#ifndef GL_ARB_imaging
+#define GL_ARB_imaging 1
+
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_FUNC_ADD 0x8006
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_BLEND_EQUATION 0x8009
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_IGNORE_BORDER 0x8150
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_WRAP_BORDER 0x8152
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+
+typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, void *values);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span);
+typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column);
+
+#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable)
+#define glColorTable GLEW_GET_FUN(__glewColorTable)
+#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv)
+#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv)
+#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D)
+#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D)
+#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf)
+#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv)
+#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri)
+#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv)
+#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable)
+#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable)
+#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D)
+#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D)
+#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable)
+#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv)
+#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv)
+#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter)
+#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv)
+#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv)
+#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram)
+#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv)
+#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv)
+#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax)
+#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv)
+#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv)
+#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter)
+#define glHistogram GLEW_GET_FUN(__glewHistogram)
+#define glMinmax GLEW_GET_FUN(__glewMinmax)
+#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram)
+#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax)
+#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D)
+
+#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging)
+
+#endif /* GL_ARB_imaging */
+
+/* ----------------------- GL_ARB_indirect_parameters ---------------------- */
+
+#ifndef GL_ARB_indirect_parameters
+#define GL_ARB_indirect_parameters 1
+
+#define GL_PARAMETER_BUFFER_ARB 0x80EE
+#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+
+#define glMultiDrawArraysIndirectCountARB GLEW_GET_FUN(__glewMultiDrawArraysIndirectCountARB)
+#define glMultiDrawElementsIndirectCountARB GLEW_GET_FUN(__glewMultiDrawElementsIndirectCountARB)
+
+#define GLEW_ARB_indirect_parameters GLEW_GET_VAR(__GLEW_ARB_indirect_parameters)
+
+#endif /* GL_ARB_indirect_parameters */
+
+/* ------------------------ GL_ARB_instanced_arrays ------------------------ */
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_ARB_instanced_arrays 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
+
+#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB)
+#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB)
+#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB)
+
+#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays)
+
+#endif /* GL_ARB_instanced_arrays */
+
+/* ---------------------- GL_ARB_internalformat_query ---------------------- */
+
+#ifndef GL_ARB_internalformat_query
+#define GL_ARB_internalformat_query 1
+
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+
+typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+#define glGetInternalformativ GLEW_GET_FUN(__glewGetInternalformativ)
+
+#define GLEW_ARB_internalformat_query GLEW_GET_VAR(__GLEW_ARB_internalformat_query)
+
+#endif /* GL_ARB_internalformat_query */
+
+/* ---------------------- GL_ARB_internalformat_query2 --------------------- */
+
+#ifndef GL_ARB_internalformat_query2
+#define GL_ARB_internalformat_query2 1
+
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_MAX_WIDTH 0x827E
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_MIPMAP 0x8293
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_COLOR_ENCODING 0x8296
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_SRGB_DECODE_ARB 0x8299
+#define GL_FILTER 0x829A
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+
+typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64* params);
+
+#define glGetInternalformati64v GLEW_GET_FUN(__glewGetInternalformati64v)
+
+#define GLEW_ARB_internalformat_query2 GLEW_GET_VAR(__GLEW_ARB_internalformat_query2)
+
+#endif /* GL_ARB_internalformat_query2 */
+
+/* ----------------------- GL_ARB_invalidate_subdata ----------------------- */
+
+#ifndef GL_ARB_invalidate_subdata
+#define GL_ARB_invalidate_subdata 1
+
+typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+typedef void (GLAPIENTRY * PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glInvalidateBufferData GLEW_GET_FUN(__glewInvalidateBufferData)
+#define glInvalidateBufferSubData GLEW_GET_FUN(__glewInvalidateBufferSubData)
+#define glInvalidateFramebuffer GLEW_GET_FUN(__glewInvalidateFramebuffer)
+#define glInvalidateSubFramebuffer GLEW_GET_FUN(__glewInvalidateSubFramebuffer)
+#define glInvalidateTexImage GLEW_GET_FUN(__glewInvalidateTexImage)
+#define glInvalidateTexSubImage GLEW_GET_FUN(__glewInvalidateTexSubImage)
+
+#define GLEW_ARB_invalidate_subdata GLEW_GET_VAR(__GLEW_ARB_invalidate_subdata)
+
+#endif /* GL_ARB_invalidate_subdata */
+
+/* ---------------------- GL_ARB_map_buffer_alignment ---------------------- */
+
+#ifndef GL_ARB_map_buffer_alignment
+#define GL_ARB_map_buffer_alignment 1
+
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+
+#define GLEW_ARB_map_buffer_alignment GLEW_GET_VAR(__GLEW_ARB_map_buffer_alignment)
+
+#endif /* GL_ARB_map_buffer_alignment */
+
+/* ------------------------ GL_ARB_map_buffer_range ------------------------ */
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_ARB_map_buffer_range 1
+
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+typedef void * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+
+#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange)
+#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange)
+
+#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range)
+
+#endif /* GL_ARB_map_buffer_range */
+
+/* ------------------------- GL_ARB_matrix_palette ------------------------- */
+
+#ifndef GL_ARB_matrix_palette
+#define GL_ARB_matrix_palette 1
+
+#define GL_MATRIX_PALETTE_ARB 0x8840
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+
+typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, void *pointer);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices);
+
+#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB)
+#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB)
+#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB)
+#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB)
+#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB)
+
+#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette)
+
+#endif /* GL_ARB_matrix_palette */
+
+/* --------------------------- GL_ARB_multi_bind --------------------------- */
+
+#ifndef GL_ARB_multi_bind
+#define GL_ARB_multi_bind 1
+
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizeiptr *sizes);
+typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures);
+typedef void (GLAPIENTRY * PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint* samplers);
+typedef void (GLAPIENTRY * PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures);
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides);
+
+#define glBindBuffersBase GLEW_GET_FUN(__glewBindBuffersBase)
+#define glBindBuffersRange GLEW_GET_FUN(__glewBindBuffersRange)
+#define glBindImageTextures GLEW_GET_FUN(__glewBindImageTextures)
+#define glBindSamplers GLEW_GET_FUN(__glewBindSamplers)
+#define glBindTextures GLEW_GET_FUN(__glewBindTextures)
+#define glBindVertexBuffers GLEW_GET_FUN(__glewBindVertexBuffers)
+
+#define GLEW_ARB_multi_bind GLEW_GET_VAR(__GLEW_ARB_multi_bind)
+
+#endif /* GL_ARB_multi_bind */
+
+/* ----------------------- GL_ARB_multi_draw_indirect ---------------------- */
+
+#ifndef GL_ARB_multi_draw_indirect
+#define GL_ARB_multi_draw_indirect 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride);
+
+#define glMultiDrawArraysIndirect GLEW_GET_FUN(__glewMultiDrawArraysIndirect)
+#define glMultiDrawElementsIndirect GLEW_GET_FUN(__glewMultiDrawElementsIndirect)
+
+#define GLEW_ARB_multi_draw_indirect GLEW_GET_VAR(__GLEW_ARB_multi_draw_indirect)
+
+#endif /* GL_ARB_multi_draw_indirect */
+
+/* --------------------------- GL_ARB_multisample -------------------------- */
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+
+typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+
+#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB)
+
+#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample)
+
+#endif /* GL_ARB_multisample */
+
+/* -------------------------- GL_ARB_multitexture -------------------------- */
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+
+typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+
+#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB)
+#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB)
+#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB)
+#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB)
+#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB)
+#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB)
+#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB)
+#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB)
+#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB)
+#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB)
+#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB)
+#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB)
+#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB)
+#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB)
+#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB)
+#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB)
+#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB)
+#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB)
+#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB)
+#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB)
+#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB)
+#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB)
+#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB)
+#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB)
+#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB)
+#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB)
+#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB)
+#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB)
+#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB)
+#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB)
+#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB)
+#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB)
+#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB)
+#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB)
+
+#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture)
+
+#endif /* GL_ARB_multitexture */
+
+/* ------------------------- GL_ARB_occlusion_query ------------------------ */
+
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+
+#define GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define GL_CURRENT_QUERY_ARB 0x8865
+#define GL_QUERY_RESULT_ARB 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define GL_SAMPLES_PASSED_ARB 0x8914
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id);
+
+#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB)
+#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB)
+#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB)
+#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB)
+#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB)
+#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB)
+#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB)
+#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB)
+
+#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query)
+
+#endif /* GL_ARB_occlusion_query */
+
+/* ------------------------ GL_ARB_occlusion_query2 ------------------------ */
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ARB_occlusion_query2 1
+
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+
+#define GLEW_ARB_occlusion_query2 GLEW_GET_VAR(__GLEW_ARB_occlusion_query2)
+
+#endif /* GL_ARB_occlusion_query2 */
+
+/* --------------------- GL_ARB_parallel_shader_compile -------------------- */
+
+#ifndef GL_ARB_parallel_shader_compile
+#define GL_ARB_parallel_shader_compile 1
+
+#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0
+#define GL_COMPLETION_STATUS_ARB 0x91B1
+
+typedef void (GLAPIENTRY * PFNGLMAXSHADERCOMPILERTHREADSARBPROC) (GLuint count);
+
+#define glMaxShaderCompilerThreadsARB GLEW_GET_FUN(__glewMaxShaderCompilerThreadsARB)
+
+#define GLEW_ARB_parallel_shader_compile GLEW_GET_VAR(__GLEW_ARB_parallel_shader_compile)
+
+#endif /* GL_ARB_parallel_shader_compile */
+
+/* -------------------- GL_ARB_pipeline_statistics_query ------------------- */
+
+#ifndef GL_ARB_pipeline_statistics_query
+#define GL_ARB_pipeline_statistics_query 1
+
+#define GL_VERTICES_SUBMITTED_ARB 0x82EE
+#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF
+#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0
+#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1
+#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2
+#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3
+#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4
+#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5
+#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6
+#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+
+#define GLEW_ARB_pipeline_statistics_query GLEW_GET_VAR(__GLEW_ARB_pipeline_statistics_query)
+
+#endif /* GL_ARB_pipeline_statistics_query */
+
+/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_ARB_pixel_buffer_object 1
+
+#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+
+#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object)
+
+#endif /* GL_ARB_pixel_buffer_object */
+
+/* ------------------------ GL_ARB_point_parameters ------------------------ */
+
+#ifndef GL_ARB_point_parameters
+#define GL_ARB_point_parameters 1
+
+#define GL_POINT_SIZE_MIN_ARB 0x8126
+#define GL_POINT_SIZE_MAX_ARB 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat* params);
+
+#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB)
+#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB)
+
+#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters)
+
+#endif /* GL_ARB_point_parameters */
+
+/* -------------------------- GL_ARB_point_sprite -------------------------- */
+
+#ifndef GL_ARB_point_sprite
+#define GL_ARB_point_sprite 1
+
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_COORD_REPLACE_ARB 0x8862
+
+#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite)
+
+#endif /* GL_ARB_point_sprite */
+
+/* ---------------------- GL_ARB_polygon_offset_clamp ---------------------- */
+
+#ifndef GL_ARB_polygon_offset_clamp
+#define GL_ARB_polygon_offset_clamp 1
+
+#define GL_POLYGON_OFFSET_CLAMP 0x8E1B
+
+typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp);
+
+#define glPolygonOffsetClamp GLEW_GET_FUN(__glewPolygonOffsetClamp)
+
+#define GLEW_ARB_polygon_offset_clamp GLEW_GET_VAR(__GLEW_ARB_polygon_offset_clamp)
+
+#endif /* GL_ARB_polygon_offset_clamp */
+
+/* ----------------------- GL_ARB_post_depth_coverage ---------------------- */
+
+#ifndef GL_ARB_post_depth_coverage
+#define GL_ARB_post_depth_coverage 1
+
+#define GLEW_ARB_post_depth_coverage GLEW_GET_VAR(__GLEW_ARB_post_depth_coverage)
+
+#endif /* GL_ARB_post_depth_coverage */
+
+/* --------------------- GL_ARB_program_interface_query -------------------- */
+
+#ifndef GL_ARB_program_interface_query
+#define GL_ARB_program_interface_query 1
+
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_NAME_LENGTH 0x92F9
+#define GL_TYPE 0x92FA
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_OFFSET 0x92FC
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_INDEX 0x930F
+
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint* params);
+typedef GLuint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name);
+typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar* name);
+typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLint *params);
+
+#define glGetProgramInterfaceiv GLEW_GET_FUN(__glewGetProgramInterfaceiv)
+#define glGetProgramResourceIndex GLEW_GET_FUN(__glewGetProgramResourceIndex)
+#define glGetProgramResourceLocation GLEW_GET_FUN(__glewGetProgramResourceLocation)
+#define glGetProgramResourceLocationIndex GLEW_GET_FUN(__glewGetProgramResourceLocationIndex)
+#define glGetProgramResourceName GLEW_GET_FUN(__glewGetProgramResourceName)
+#define glGetProgramResourceiv GLEW_GET_FUN(__glewGetProgramResourceiv)
+
+#define GLEW_ARB_program_interface_query GLEW_GET_VAR(__GLEW_ARB_program_interface_query)
+
+#endif /* GL_ARB_program_interface_query */
+
+/* ------------------------ GL_ARB_provoking_vertex ------------------------ */
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+
+#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex)
+
+#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex)
+
+#endif /* GL_ARB_provoking_vertex */
+
+/* ----------------------- GL_ARB_query_buffer_object ---------------------- */
+
+#ifndef GL_ARB_query_buffer_object
+#define GL_ARB_query_buffer_object 1
+
+#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
+#define GL_QUERY_BUFFER 0x9192
+#define GL_QUERY_BUFFER_BINDING 0x9193
+#define GL_QUERY_RESULT_NO_WAIT 0x9194
+
+#define GLEW_ARB_query_buffer_object GLEW_GET_VAR(__GLEW_ARB_query_buffer_object)
+
+#endif /* GL_ARB_query_buffer_object */
+
+/* ------------------ GL_ARB_robust_buffer_access_behavior ----------------- */
+
+#ifndef GL_ARB_robust_buffer_access_behavior
+#define GL_ARB_robust_buffer_access_behavior 1
+
+#define GLEW_ARB_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_ARB_robust_buffer_access_behavior)
+
+#endif /* GL_ARB_robust_buffer_access_behavior */
+
+/* --------------------------- GL_ARB_robustness --------------------------- */
+
+#ifndef GL_ARB_robustness
+#define GL_ARB_robustness 1
+
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
+
+typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table);
+typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void* img);
+typedef void (GLAPIENTRY * PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image);
+typedef void (GLAPIENTRY * PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values);
+typedef void (GLAPIENTRY * PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint* v);
+typedef void (GLAPIENTRY * PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values);
+typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat* values);
+typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint* values);
+typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort* values);
+typedef void (GLAPIENTRY * PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte* pattern);
+typedef void (GLAPIENTRY * PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, void*column, void*span);
+typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* img);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data);
+
+#define glGetGraphicsResetStatusARB GLEW_GET_FUN(__glewGetGraphicsResetStatusARB)
+#define glGetnColorTableARB GLEW_GET_FUN(__glewGetnColorTableARB)
+#define glGetnCompressedTexImageARB GLEW_GET_FUN(__glewGetnCompressedTexImageARB)
+#define glGetnConvolutionFilterARB GLEW_GET_FUN(__glewGetnConvolutionFilterARB)
+#define glGetnHistogramARB GLEW_GET_FUN(__glewGetnHistogramARB)
+#define glGetnMapdvARB GLEW_GET_FUN(__glewGetnMapdvARB)
+#define glGetnMapfvARB GLEW_GET_FUN(__glewGetnMapfvARB)
+#define glGetnMapivARB GLEW_GET_FUN(__glewGetnMapivARB)
+#define glGetnMinmaxARB GLEW_GET_FUN(__glewGetnMinmaxARB)
+#define glGetnPixelMapfvARB GLEW_GET_FUN(__glewGetnPixelMapfvARB)
+#define glGetnPixelMapuivARB GLEW_GET_FUN(__glewGetnPixelMapuivARB)
+#define glGetnPixelMapusvARB GLEW_GET_FUN(__glewGetnPixelMapusvARB)
+#define glGetnPolygonStippleARB GLEW_GET_FUN(__glewGetnPolygonStippleARB)
+#define glGetnSeparableFilterARB GLEW_GET_FUN(__glewGetnSeparableFilterARB)
+#define glGetnTexImageARB GLEW_GET_FUN(__glewGetnTexImageARB)
+#define glGetnUniformdvARB GLEW_GET_FUN(__glewGetnUniformdvARB)
+#define glGetnUniformfvARB GLEW_GET_FUN(__glewGetnUniformfvARB)
+#define glGetnUniformivARB GLEW_GET_FUN(__glewGetnUniformivARB)
+#define glGetnUniformuivARB GLEW_GET_FUN(__glewGetnUniformuivARB)
+#define glReadnPixelsARB GLEW_GET_FUN(__glewReadnPixelsARB)
+
+#define GLEW_ARB_robustness GLEW_GET_VAR(__GLEW_ARB_robustness)
+
+#endif /* GL_ARB_robustness */
+
+/* ---------------- GL_ARB_robustness_application_isolation ---------------- */
+
+#ifndef GL_ARB_robustness_application_isolation
+#define GL_ARB_robustness_application_isolation 1
+
+#define GLEW_ARB_robustness_application_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_application_isolation)
+
+#endif /* GL_ARB_robustness_application_isolation */
+
+/* ---------------- GL_ARB_robustness_share_group_isolation ---------------- */
+
+#ifndef GL_ARB_robustness_share_group_isolation
+#define GL_ARB_robustness_share_group_isolation 1
+
+#define GLEW_ARB_robustness_share_group_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_share_group_isolation)
+
+#endif /* GL_ARB_robustness_share_group_isolation */
+
+/* ------------------------ GL_ARB_sample_locations ------------------------ */
+
+#ifndef GL_ARB_sample_locations
+#define GL_ARB_sample_locations 1
+
+#define GL_SAMPLE_LOCATION_ARB 0x8E50
+#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341
+#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342
+#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v);
+
+#define glFramebufferSampleLocationsfvARB GLEW_GET_FUN(__glewFramebufferSampleLocationsfvARB)
+#define glNamedFramebufferSampleLocationsfvARB GLEW_GET_FUN(__glewNamedFramebufferSampleLocationsfvARB)
+
+#define GLEW_ARB_sample_locations GLEW_GET_VAR(__GLEW_ARB_sample_locations)
+
+#endif /* GL_ARB_sample_locations */
+
+/* ------------------------- GL_ARB_sample_shading ------------------------- */
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+
+#define GL_SAMPLE_SHADING_ARB 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+
+typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+
+#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB)
+
+#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading)
+
+#endif /* GL_ARB_sample_shading */
+
+/* ------------------------- GL_ARB_sampler_objects ------------------------ */
+
+#ifndef GL_ARB_sampler_objects
+#define GL_ARB_sampler_objects 1
+
+#define GL_SAMPLER_BINDING 0x8919
+
+typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers);
+typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint* params);
+
+#define glBindSampler GLEW_GET_FUN(__glewBindSampler)
+#define glDeleteSamplers GLEW_GET_FUN(__glewDeleteSamplers)
+#define glGenSamplers GLEW_GET_FUN(__glewGenSamplers)
+#define glGetSamplerParameterIiv GLEW_GET_FUN(__glewGetSamplerParameterIiv)
+#define glGetSamplerParameterIuiv GLEW_GET_FUN(__glewGetSamplerParameterIuiv)
+#define glGetSamplerParameterfv GLEW_GET_FUN(__glewGetSamplerParameterfv)
+#define glGetSamplerParameteriv GLEW_GET_FUN(__glewGetSamplerParameteriv)
+#define glIsSampler GLEW_GET_FUN(__glewIsSampler)
+#define glSamplerParameterIiv GLEW_GET_FUN(__glewSamplerParameterIiv)
+#define glSamplerParameterIuiv GLEW_GET_FUN(__glewSamplerParameterIuiv)
+#define glSamplerParameterf GLEW_GET_FUN(__glewSamplerParameterf)
+#define glSamplerParameterfv GLEW_GET_FUN(__glewSamplerParameterfv)
+#define glSamplerParameteri GLEW_GET_FUN(__glewSamplerParameteri)
+#define glSamplerParameteriv GLEW_GET_FUN(__glewSamplerParameteriv)
+
+#define GLEW_ARB_sampler_objects GLEW_GET_VAR(__GLEW_ARB_sampler_objects)
+
+#endif /* GL_ARB_sampler_objects */
+
+/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+
+#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map)
+
+#endif /* GL_ARB_seamless_cube_map */
+
+/* ------------------ GL_ARB_seamless_cubemap_per_texture ------------------ */
+
+#ifndef GL_ARB_seamless_cubemap_per_texture
+#define GL_ARB_seamless_cubemap_per_texture 1
+
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+
+#define GLEW_ARB_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_ARB_seamless_cubemap_per_texture)
+
+#endif /* GL_ARB_seamless_cubemap_per_texture */
+
+/* --------------------- GL_ARB_separate_shader_objects -------------------- */
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_ARB_separate_shader_objects 1
+
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef void (GLAPIENTRY * PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar * const * strings);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint* pipelines);
+typedef void (GLAPIENTRY * PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar *infoLog);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint x, GLuint y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+
+#define glActiveShaderProgram GLEW_GET_FUN(__glewActiveShaderProgram)
+#define glBindProgramPipeline GLEW_GET_FUN(__glewBindProgramPipeline)
+#define glCreateShaderProgramv GLEW_GET_FUN(__glewCreateShaderProgramv)
+#define glDeleteProgramPipelines GLEW_GET_FUN(__glewDeleteProgramPipelines)
+#define glGenProgramPipelines GLEW_GET_FUN(__glewGenProgramPipelines)
+#define glGetProgramPipelineInfoLog GLEW_GET_FUN(__glewGetProgramPipelineInfoLog)
+#define glGetProgramPipelineiv GLEW_GET_FUN(__glewGetProgramPipelineiv)
+#define glIsProgramPipeline GLEW_GET_FUN(__glewIsProgramPipeline)
+#define glProgramUniform1d GLEW_GET_FUN(__glewProgramUniform1d)
+#define glProgramUniform1dv GLEW_GET_FUN(__glewProgramUniform1dv)
+#define glProgramUniform1f GLEW_GET_FUN(__glewProgramUniform1f)
+#define glProgramUniform1fv GLEW_GET_FUN(__glewProgramUniform1fv)
+#define glProgramUniform1i GLEW_GET_FUN(__glewProgramUniform1i)
+#define glProgramUniform1iv GLEW_GET_FUN(__glewProgramUniform1iv)
+#define glProgramUniform1ui GLEW_GET_FUN(__glewProgramUniform1ui)
+#define glProgramUniform1uiv GLEW_GET_FUN(__glewProgramUniform1uiv)
+#define glProgramUniform2d GLEW_GET_FUN(__glewProgramUniform2d)
+#define glProgramUniform2dv GLEW_GET_FUN(__glewProgramUniform2dv)
+#define glProgramUniform2f GLEW_GET_FUN(__glewProgramUniform2f)
+#define glProgramUniform2fv GLEW_GET_FUN(__glewProgramUniform2fv)
+#define glProgramUniform2i GLEW_GET_FUN(__glewProgramUniform2i)
+#define glProgramUniform2iv GLEW_GET_FUN(__glewProgramUniform2iv)
+#define glProgramUniform2ui GLEW_GET_FUN(__glewProgramUniform2ui)
+#define glProgramUniform2uiv GLEW_GET_FUN(__glewProgramUniform2uiv)
+#define glProgramUniform3d GLEW_GET_FUN(__glewProgramUniform3d)
+#define glProgramUniform3dv GLEW_GET_FUN(__glewProgramUniform3dv)
+#define glProgramUniform3f GLEW_GET_FUN(__glewProgramUniform3f)
+#define glProgramUniform3fv GLEW_GET_FUN(__glewProgramUniform3fv)
+#define glProgramUniform3i GLEW_GET_FUN(__glewProgramUniform3i)
+#define glProgramUniform3iv GLEW_GET_FUN(__glewProgramUniform3iv)
+#define glProgramUniform3ui GLEW_GET_FUN(__glewProgramUniform3ui)
+#define glProgramUniform3uiv GLEW_GET_FUN(__glewProgramUniform3uiv)
+#define glProgramUniform4d GLEW_GET_FUN(__glewProgramUniform4d)
+#define glProgramUniform4dv GLEW_GET_FUN(__glewProgramUniform4dv)
+#define glProgramUniform4f GLEW_GET_FUN(__glewProgramUniform4f)
+#define glProgramUniform4fv GLEW_GET_FUN(__glewProgramUniform4fv)
+#define glProgramUniform4i GLEW_GET_FUN(__glewProgramUniform4i)
+#define glProgramUniform4iv GLEW_GET_FUN(__glewProgramUniform4iv)
+#define glProgramUniform4ui GLEW_GET_FUN(__glewProgramUniform4ui)
+#define glProgramUniform4uiv GLEW_GET_FUN(__glewProgramUniform4uiv)
+#define glProgramUniformMatrix2dv GLEW_GET_FUN(__glewProgramUniformMatrix2dv)
+#define glProgramUniformMatrix2fv GLEW_GET_FUN(__glewProgramUniformMatrix2fv)
+#define glProgramUniformMatrix2x3dv GLEW_GET_FUN(__glewProgramUniformMatrix2x3dv)
+#define glProgramUniformMatrix2x3fv GLEW_GET_FUN(__glewProgramUniformMatrix2x3fv)
+#define glProgramUniformMatrix2x4dv GLEW_GET_FUN(__glewProgramUniformMatrix2x4dv)
+#define glProgramUniformMatrix2x4fv GLEW_GET_FUN(__glewProgramUniformMatrix2x4fv)
+#define glProgramUniformMatrix3dv GLEW_GET_FUN(__glewProgramUniformMatrix3dv)
+#define glProgramUniformMatrix3fv GLEW_GET_FUN(__glewProgramUniformMatrix3fv)
+#define glProgramUniformMatrix3x2dv GLEW_GET_FUN(__glewProgramUniformMatrix3x2dv)
+#define glProgramUniformMatrix3x2fv GLEW_GET_FUN(__glewProgramUniformMatrix3x2fv)
+#define glProgramUniformMatrix3x4dv GLEW_GET_FUN(__glewProgramUniformMatrix3x4dv)
+#define glProgramUniformMatrix3x4fv GLEW_GET_FUN(__glewProgramUniformMatrix3x4fv)
+#define glProgramUniformMatrix4dv GLEW_GET_FUN(__glewProgramUniformMatrix4dv)
+#define glProgramUniformMatrix4fv GLEW_GET_FUN(__glewProgramUniformMatrix4fv)
+#define glProgramUniformMatrix4x2dv GLEW_GET_FUN(__glewProgramUniformMatrix4x2dv)
+#define glProgramUniformMatrix4x2fv GLEW_GET_FUN(__glewProgramUniformMatrix4x2fv)
+#define glProgramUniformMatrix4x3dv GLEW_GET_FUN(__glewProgramUniformMatrix4x3dv)
+#define glProgramUniformMatrix4x3fv GLEW_GET_FUN(__glewProgramUniformMatrix4x3fv)
+#define glUseProgramStages GLEW_GET_FUN(__glewUseProgramStages)
+#define glValidateProgramPipeline GLEW_GET_FUN(__glewValidateProgramPipeline)
+
+#define GLEW_ARB_separate_shader_objects GLEW_GET_VAR(__GLEW_ARB_separate_shader_objects)
+
+#endif /* GL_ARB_separate_shader_objects */
+
+/* -------------------- GL_ARB_shader_atomic_counter_ops ------------------- */
+
+#ifndef GL_ARB_shader_atomic_counter_ops
+#define GL_ARB_shader_atomic_counter_ops 1
+
+#define GLEW_ARB_shader_atomic_counter_ops GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counter_ops)
+
+#endif /* GL_ARB_shader_atomic_counter_ops */
+
+/* --------------------- GL_ARB_shader_atomic_counters --------------------- */
+
+#ifndef GL_ARB_shader_atomic_counters
+#define GL_ARB_shader_atomic_counters 1
+
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+
+typedef void (GLAPIENTRY * PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint* params);
+
+#define glGetActiveAtomicCounterBufferiv GLEW_GET_FUN(__glewGetActiveAtomicCounterBufferiv)
+
+#define GLEW_ARB_shader_atomic_counters GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counters)
+
+#endif /* GL_ARB_shader_atomic_counters */
+
+/* -------------------------- GL_ARB_shader_ballot ------------------------- */
+
+#ifndef GL_ARB_shader_ballot
+#define GL_ARB_shader_ballot 1
+
+#define GLEW_ARB_shader_ballot GLEW_GET_VAR(__GLEW_ARB_shader_ballot)
+
+#endif /* GL_ARB_shader_ballot */
+
+/* ----------------------- GL_ARB_shader_bit_encoding ---------------------- */
+
+#ifndef GL_ARB_shader_bit_encoding
+#define GL_ARB_shader_bit_encoding 1
+
+#define GLEW_ARB_shader_bit_encoding GLEW_GET_VAR(__GLEW_ARB_shader_bit_encoding)
+
+#endif /* GL_ARB_shader_bit_encoding */
+
+/* -------------------------- GL_ARB_shader_clock -------------------------- */
+
+#ifndef GL_ARB_shader_clock
+#define GL_ARB_shader_clock 1
+
+#define GLEW_ARB_shader_clock GLEW_GET_VAR(__GLEW_ARB_shader_clock)
+
+#endif /* GL_ARB_shader_clock */
+
+/* --------------------- GL_ARB_shader_draw_parameters --------------------- */
+
+#ifndef GL_ARB_shader_draw_parameters
+#define GL_ARB_shader_draw_parameters 1
+
+#define GLEW_ARB_shader_draw_parameters GLEW_GET_VAR(__GLEW_ARB_shader_draw_parameters)
+
+#endif /* GL_ARB_shader_draw_parameters */
+
+/* ------------------------ GL_ARB_shader_group_vote ----------------------- */
+
+#ifndef GL_ARB_shader_group_vote
+#define GL_ARB_shader_group_vote 1
+
+#define GLEW_ARB_shader_group_vote GLEW_GET_VAR(__GLEW_ARB_shader_group_vote)
+
+#endif /* GL_ARB_shader_group_vote */
+
+/* --------------------- GL_ARB_shader_image_load_store -------------------- */
+
+#ifndef GL_ARB_shader_image_load_store
+#define GL_ARB_shader_image_load_store 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
+
+#define glBindImageTexture GLEW_GET_FUN(__glewBindImageTexture)
+#define glMemoryBarrier GLEW_GET_FUN(__glewMemoryBarrier)
+
+#define GLEW_ARB_shader_image_load_store GLEW_GET_VAR(__GLEW_ARB_shader_image_load_store)
+
+#endif /* GL_ARB_shader_image_load_store */
+
+/* ------------------------ GL_ARB_shader_image_size ----------------------- */
+
+#ifndef GL_ARB_shader_image_size
+#define GL_ARB_shader_image_size 1
+
+#define GLEW_ARB_shader_image_size GLEW_GET_VAR(__GLEW_ARB_shader_image_size)
+
+#endif /* GL_ARB_shader_image_size */
+
+/* ------------------------- GL_ARB_shader_objects ------------------------- */
+
+#ifndef GL_ARB_shader_objects
+#define GL_ARB_shader_objects 1
+
+#define GL_PROGRAM_OBJECT_ARB 0x8B40
+#define GL_SHADER_OBJECT_ARB 0x8B48
+#define GL_OBJECT_TYPE_ARB 0x8B4E
+#define GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define GL_FLOAT_VEC2_ARB 0x8B50
+#define GL_FLOAT_VEC3_ARB 0x8B51
+#define GL_FLOAT_VEC4_ARB 0x8B52
+#define GL_INT_VEC2_ARB 0x8B53
+#define GL_INT_VEC3_ARB 0x8B54
+#define GL_INT_VEC4_ARB 0x8B55
+#define GL_BOOL_ARB 0x8B56
+#define GL_BOOL_VEC2_ARB 0x8B57
+#define GL_BOOL_VEC3_ARB 0x8B58
+#define GL_BOOL_VEC4_ARB 0x8B59
+#define GL_FLOAT_MAT2_ARB 0x8B5A
+#define GL_FLOAT_MAT3_ARB 0x8B5B
+#define GL_FLOAT_MAT4_ARB 0x8B5C
+#define GL_SAMPLER_1D_ARB 0x8B5D
+#define GL_SAMPLER_2D_ARB 0x8B5E
+#define GL_SAMPLER_3D_ARB 0x8B5F
+#define GL_SAMPLER_CUBE_ARB 0x8B60
+#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+
+typedef char GLcharARB;
+typedef unsigned int GLhandleARB;
+
+typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
+typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
+typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
+typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
+typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj);
+typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name);
+typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj);
+typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname);
+typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source);
+typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params);
+typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
+typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj);
+
+#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB)
+#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB)
+#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB)
+#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB)
+#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB)
+#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB)
+#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB)
+#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB)
+#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB)
+#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB)
+#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB)
+#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB)
+#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB)
+#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB)
+#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB)
+#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB)
+#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB)
+#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB)
+#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB)
+#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB)
+#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB)
+#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB)
+#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB)
+#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB)
+#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB)
+#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB)
+#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB)
+#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB)
+#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB)
+#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB)
+#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB)
+#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB)
+#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB)
+#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB)
+#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB)
+#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB)
+#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB)
+#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB)
+#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB)
+
+#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects)
+
+#endif /* GL_ARB_shader_objects */
+
+/* ------------------------ GL_ARB_shader_precision ------------------------ */
+
+#ifndef GL_ARB_shader_precision
+#define GL_ARB_shader_precision 1
+
+#define GLEW_ARB_shader_precision GLEW_GET_VAR(__GLEW_ARB_shader_precision)
+
+#endif /* GL_ARB_shader_precision */
+
+/* ---------------------- GL_ARB_shader_stencil_export --------------------- */
+
+#ifndef GL_ARB_shader_stencil_export
+#define GL_ARB_shader_stencil_export 1
+
+#define GLEW_ARB_shader_stencil_export GLEW_GET_VAR(__GLEW_ARB_shader_stencil_export)
+
+#endif /* GL_ARB_shader_stencil_export */
+
+/* ------------------ GL_ARB_shader_storage_buffer_object ------------------ */
+
+#ifndef GL_ARB_shader_storage_buffer_object
+#define GL_ARB_shader_storage_buffer_object 1
+
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+
+typedef void (GLAPIENTRY * PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
+
+#define glShaderStorageBlockBinding GLEW_GET_FUN(__glewShaderStorageBlockBinding)
+
+#define GLEW_ARB_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_ARB_shader_storage_buffer_object)
+
+#endif /* GL_ARB_shader_storage_buffer_object */
+
+/* ------------------------ GL_ARB_shader_subroutine ----------------------- */
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ARB_shader_subroutine 1
+
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+
+typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint* values);
+typedef GLuint (GLAPIENTRY * PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar* name);
+typedef GLint (GLAPIENTRY * PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint* indices);
+
+#define glGetActiveSubroutineName GLEW_GET_FUN(__glewGetActiveSubroutineName)
+#define glGetActiveSubroutineUniformName GLEW_GET_FUN(__glewGetActiveSubroutineUniformName)
+#define glGetActiveSubroutineUniformiv GLEW_GET_FUN(__glewGetActiveSubroutineUniformiv)
+#define glGetProgramStageiv GLEW_GET_FUN(__glewGetProgramStageiv)
+#define glGetSubroutineIndex GLEW_GET_FUN(__glewGetSubroutineIndex)
+#define glGetSubroutineUniformLocation GLEW_GET_FUN(__glewGetSubroutineUniformLocation)
+#define glGetUniformSubroutineuiv GLEW_GET_FUN(__glewGetUniformSubroutineuiv)
+#define glUniformSubroutinesuiv GLEW_GET_FUN(__glewUniformSubroutinesuiv)
+
+#define GLEW_ARB_shader_subroutine GLEW_GET_VAR(__GLEW_ARB_shader_subroutine)
+
+#endif /* GL_ARB_shader_subroutine */
+
+/* ------------------ GL_ARB_shader_texture_image_samples ------------------ */
+
+#ifndef GL_ARB_shader_texture_image_samples
+#define GL_ARB_shader_texture_image_samples 1
+
+#define GLEW_ARB_shader_texture_image_samples GLEW_GET_VAR(__GLEW_ARB_shader_texture_image_samples)
+
+#endif /* GL_ARB_shader_texture_image_samples */
+
+/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */
+
+#ifndef GL_ARB_shader_texture_lod
+#define GL_ARB_shader_texture_lod 1
+
+#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod)
+
+#endif /* GL_ARB_shader_texture_lod */
+
+/* ------------------- GL_ARB_shader_viewport_layer_array ------------------ */
+
+#ifndef GL_ARB_shader_viewport_layer_array
+#define GL_ARB_shader_viewport_layer_array 1
+
+#define GLEW_ARB_shader_viewport_layer_array GLEW_GET_VAR(__GLEW_ARB_shader_viewport_layer_array)
+
+#endif /* GL_ARB_shader_viewport_layer_array */
+
+/* ---------------------- GL_ARB_shading_language_100 ---------------------- */
+
+#ifndef GL_ARB_shading_language_100
+#define GL_ARB_shading_language_100 1
+
+#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+
+#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100)
+
+#endif /* GL_ARB_shading_language_100 */
+
+/* -------------------- GL_ARB_shading_language_420pack -------------------- */
+
+#ifndef GL_ARB_shading_language_420pack
+#define GL_ARB_shading_language_420pack 1
+
+#define GLEW_ARB_shading_language_420pack GLEW_GET_VAR(__GLEW_ARB_shading_language_420pack)
+
+#endif /* GL_ARB_shading_language_420pack */
+
+/* -------------------- GL_ARB_shading_language_include -------------------- */
+
+#ifndef GL_ARB_shading_language_include
+#define GL_ARB_shading_language_include 1
+
+#define GL_SHADER_INCLUDE_ARB 0x8DAE
+#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9
+#define GL_NAMED_STRING_TYPE_ARB 0x8DEA
+
+typedef void (GLAPIENTRY * PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* const *path, const GLint *length);
+typedef void (GLAPIENTRY * PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar* name, GLenum pname, GLint *params);
+typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar* name, GLint stringlen, const GLchar *string);
+
+#define glCompileShaderIncludeARB GLEW_GET_FUN(__glewCompileShaderIncludeARB)
+#define glDeleteNamedStringARB GLEW_GET_FUN(__glewDeleteNamedStringARB)
+#define glGetNamedStringARB GLEW_GET_FUN(__glewGetNamedStringARB)
+#define glGetNamedStringivARB GLEW_GET_FUN(__glewGetNamedStringivARB)
+#define glIsNamedStringARB GLEW_GET_FUN(__glewIsNamedStringARB)
+#define glNamedStringARB GLEW_GET_FUN(__glewNamedStringARB)
+
+#define GLEW_ARB_shading_language_include GLEW_GET_VAR(__GLEW_ARB_shading_language_include)
+
+#endif /* GL_ARB_shading_language_include */
+
+/* -------------------- GL_ARB_shading_language_packing -------------------- */
+
+#ifndef GL_ARB_shading_language_packing
+#define GL_ARB_shading_language_packing 1
+
+#define GLEW_ARB_shading_language_packing GLEW_GET_VAR(__GLEW_ARB_shading_language_packing)
+
+#endif /* GL_ARB_shading_language_packing */
+
+/* ----------------------------- GL_ARB_shadow ----------------------------- */
+
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+
+#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow)
+
+#endif /* GL_ARB_shadow */
+
+/* ------------------------- GL_ARB_shadow_ambient ------------------------- */
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_ARB_shadow_ambient 1
+
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+
+#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient)
+
+#endif /* GL_ARB_shadow_ambient */
+
+/* -------------------------- GL_ARB_sparse_buffer ------------------------- */
+
+#ifndef GL_ARB_sparse_buffer
+#define GL_ARB_sparse_buffer 1
+
+#define GL_SPARSE_STORAGE_BIT_ARB 0x0400
+#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8
+
+typedef void (GLAPIENTRY * PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit);
+
+#define glBufferPageCommitmentARB GLEW_GET_FUN(__glewBufferPageCommitmentARB)
+
+#define GLEW_ARB_sparse_buffer GLEW_GET_VAR(__GLEW_ARB_sparse_buffer)
+
+#endif /* GL_ARB_sparse_buffer */
+
+/* ------------------------- GL_ARB_sparse_texture ------------------------- */
+
+#ifndef GL_ARB_sparse_texture
+#define GL_ARB_sparse_texture 1
+
+#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197
+#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A
+#define GL_TEXTURE_SPARSE_ARB 0x91A6
+#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7
+#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8
+#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9
+#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA
+
+typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+
+#define glTexPageCommitmentARB GLEW_GET_FUN(__glewTexPageCommitmentARB)
+
+#define GLEW_ARB_sparse_texture GLEW_GET_VAR(__GLEW_ARB_sparse_texture)
+
+#endif /* GL_ARB_sparse_texture */
+
+/* ------------------------- GL_ARB_sparse_texture2 ------------------------ */
+
+#ifndef GL_ARB_sparse_texture2
+#define GL_ARB_sparse_texture2 1
+
+#define GLEW_ARB_sparse_texture2 GLEW_GET_VAR(__GLEW_ARB_sparse_texture2)
+
+#endif /* GL_ARB_sparse_texture2 */
+
+/* ---------------------- GL_ARB_sparse_texture_clamp ---------------------- */
+
+#ifndef GL_ARB_sparse_texture_clamp
+#define GL_ARB_sparse_texture_clamp 1
+
+#define GLEW_ARB_sparse_texture_clamp GLEW_GET_VAR(__GLEW_ARB_sparse_texture_clamp)
+
+#endif /* GL_ARB_sparse_texture_clamp */
+
+/* ------------------------ GL_ARB_spirv_extensions ------------------------ */
+
+#ifndef GL_ARB_spirv_extensions
+#define GL_ARB_spirv_extensions 1
+
+#define GL_SPIR_V_EXTENSIONS 0x9553
+#define GL_NUM_SPIR_V_EXTENSIONS 0x9554
+
+#define GLEW_ARB_spirv_extensions GLEW_GET_VAR(__GLEW_ARB_spirv_extensions)
+
+#endif /* GL_ARB_spirv_extensions */
+
+/* ------------------------ GL_ARB_stencil_texturing ----------------------- */
+
+#ifndef GL_ARB_stencil_texturing
+#define GL_ARB_stencil_texturing 1
+
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+
+#define GLEW_ARB_stencil_texturing GLEW_GET_VAR(__GLEW_ARB_stencil_texturing)
+
+#endif /* GL_ARB_stencil_texturing */
+
+/* ------------------------------ GL_ARB_sync ------------------------------ */
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+
+typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
+typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync);
+typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values);
+typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync);
+typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
+
+#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync)
+#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync)
+#define glFenceSync GLEW_GET_FUN(__glewFenceSync)
+#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v)
+#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv)
+#define glIsSync GLEW_GET_FUN(__glewIsSync)
+#define glWaitSync GLEW_GET_FUN(__glewWaitSync)
+
+#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync)
+
+#endif /* GL_ARB_sync */
+
+/* ----------------------- GL_ARB_tessellation_shader ---------------------- */
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_ARB_tessellation_shader 1
+
+#define GL_PATCHES 0xE
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_ISOLINES 0x8E7A
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+
+typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat* values);
+typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);
+
+#define glPatchParameterfv GLEW_GET_FUN(__glewPatchParameterfv)
+#define glPatchParameteri GLEW_GET_FUN(__glewPatchParameteri)
+
+#define GLEW_ARB_tessellation_shader GLEW_GET_VAR(__GLEW_ARB_tessellation_shader)
+
+#endif /* GL_ARB_tessellation_shader */
+
+/* ------------------------- GL_ARB_texture_barrier ------------------------ */
+
+#ifndef GL_ARB_texture_barrier
+#define GL_ARB_texture_barrier 1
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERPROC) (void);
+
+#define glTextureBarrier GLEW_GET_FUN(__glewTextureBarrier)
+
+#define GLEW_ARB_texture_barrier GLEW_GET_VAR(__GLEW_ARB_texture_barrier)
+
+#endif /* GL_ARB_texture_barrier */
+
+/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_ARB_texture_border_clamp 1
+
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+
+#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp)
+
+#endif /* GL_ARB_texture_border_clamp */
+
+/* ---------------------- GL_ARB_texture_buffer_object --------------------- */
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_ARB_texture_buffer_object 1
+
+#define GL_TEXTURE_BUFFER_ARB 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E
+
+typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+
+#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB)
+
+#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object)
+
+#endif /* GL_ARB_texture_buffer_object */
+
+/* ------------------- GL_ARB_texture_buffer_object_rgb32 ------------------ */
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+#define GL_ARB_texture_buffer_object_rgb32 1
+
+#define GLEW_ARB_texture_buffer_object_rgb32 GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object_rgb32)
+
+#endif /* GL_ARB_texture_buffer_object_rgb32 */
+
+/* ---------------------- GL_ARB_texture_buffer_range ---------------------- */
+
+#ifndef GL_ARB_texture_buffer_range
+#define GL_ARB_texture_buffer_range 1
+
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+
+typedef void (GLAPIENTRY * PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+
+#define glTexBufferRange GLEW_GET_FUN(__glewTexBufferRange)
+#define glTextureBufferRangeEXT GLEW_GET_FUN(__glewTextureBufferRangeEXT)
+
+#define GLEW_ARB_texture_buffer_range GLEW_GET_VAR(__GLEW_ARB_texture_buffer_range)
+
+#endif /* GL_ARB_texture_buffer_range */
+
+/* ----------------------- GL_ARB_texture_compression ---------------------- */
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void *img);
+
+#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB)
+#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB)
+#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB)
+#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB)
+#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB)
+#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB)
+#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB)
+
+#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression)
+
+#endif /* GL_ARB_texture_compression */
+
+/* -------------------- GL_ARB_texture_compression_bptc -------------------- */
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_ARB_texture_compression_bptc 1
+
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+
+#define GLEW_ARB_texture_compression_bptc GLEW_GET_VAR(__GLEW_ARB_texture_compression_bptc)
+
+#endif /* GL_ARB_texture_compression_bptc */
+
+/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc 1
+
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+
+#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc)
+
+#endif /* GL_ARB_texture_compression_rgtc */
+
+/* ------------------------ GL_ARB_texture_cube_map ------------------------ */
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+
+#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map)
+
+#endif /* GL_ARB_texture_cube_map */
+
+/* --------------------- GL_ARB_texture_cube_map_array --------------------- */
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+
+#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array)
+
+#endif /* GL_ARB_texture_cube_map_array */
+
+/* ------------------------- GL_ARB_texture_env_add ------------------------ */
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+
+#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add)
+
+#endif /* GL_ARB_texture_env_add */
+
+/* ----------------------- GL_ARB_texture_env_combine ---------------------- */
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine 1
+
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_CONSTANT_ARB 0x8576
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PREVIOUS_ARB 0x8578
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+
+#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine)
+
+#endif /* GL_ARB_texture_env_combine */
+
+/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */
+
+#ifndef GL_ARB_texture_env_crossbar
+#define GL_ARB_texture_env_crossbar 1
+
+#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar)
+
+#endif /* GL_ARB_texture_env_crossbar */
+
+/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_ARB_texture_env_dot3 1
+
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGBA_ARB 0x86AF
+
+#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3)
+
+#endif /* GL_ARB_texture_env_dot3 */
+
+/* ------------------- GL_ARB_texture_filter_anisotropic ------------------- */
+
+#ifndef GL_ARB_texture_filter_anisotropic
+#define GL_ARB_texture_filter_anisotropic 1
+
+#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
+
+#define GLEW_ARB_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_ARB_texture_filter_anisotropic)
+
+#endif /* GL_ARB_texture_filter_anisotropic */
+
+/* ---------------------- GL_ARB_texture_filter_minmax --------------------- */
+
+#ifndef GL_ARB_texture_filter_minmax
+#define GL_ARB_texture_filter_minmax 1
+
+#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366
+#define GL_WEIGHTED_AVERAGE_ARB 0x9367
+
+#define GLEW_ARB_texture_filter_minmax GLEW_GET_VAR(__GLEW_ARB_texture_filter_minmax)
+
+#endif /* GL_ARB_texture_filter_minmax */
+
+/* -------------------------- GL_ARB_texture_float ------------------------- */
+
+#ifndef GL_ARB_texture_float
+#define GL_ARB_texture_float 1
+
+#define GL_RGBA32F_ARB 0x8814
+#define GL_RGB32F_ARB 0x8815
+#define GL_ALPHA32F_ARB 0x8816
+#define GL_INTENSITY32F_ARB 0x8817
+#define GL_LUMINANCE32F_ARB 0x8818
+#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define GL_RGBA16F_ARB 0x881A
+#define GL_RGB16F_ARB 0x881B
+#define GL_ALPHA16F_ARB 0x881C
+#define GL_INTENSITY16F_ARB 0x881D
+#define GL_LUMINANCE16F_ARB 0x881E
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+
+#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float)
+
+#endif /* GL_ARB_texture_float */
+
+/* ------------------------- GL_ARB_texture_gather ------------------------- */
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F
+
+#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather)
+
+#endif /* GL_ARB_texture_gather */
+
+/* ------------------ GL_ARB_texture_mirror_clamp_to_edge ------------------ */
+
+#ifndef GL_ARB_texture_mirror_clamp_to_edge
+#define GL_ARB_texture_mirror_clamp_to_edge 1
+
+#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
+
+#define GLEW_ARB_texture_mirror_clamp_to_edge GLEW_GET_VAR(__GLEW_ARB_texture_mirror_clamp_to_edge)
+
+#endif /* GL_ARB_texture_mirror_clamp_to_edge */
+
+/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_ARB_texture_mirrored_repeat 1
+
+#define GL_MIRRORED_REPEAT_ARB 0x8370
+
+#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat)
+
+#endif /* GL_ARB_texture_mirrored_repeat */
+
+/* ----------------------- GL_ARB_texture_multisample ---------------------- */
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+
+typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val);
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+
+#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv)
+#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski)
+#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample)
+#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample)
+
+#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample)
+
+#endif /* GL_ARB_texture_multisample */
+
+/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */
+
+#ifndef GL_ARB_texture_non_power_of_two
+#define GL_ARB_texture_non_power_of_two 1
+
+#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two)
+
+#endif /* GL_ARB_texture_non_power_of_two */
+
+/* ---------------------- GL_ARB_texture_query_levels ---------------------- */
+
+#ifndef GL_ARB_texture_query_levels
+#define GL_ARB_texture_query_levels 1
+
+#define GLEW_ARB_texture_query_levels GLEW_GET_VAR(__GLEW_ARB_texture_query_levels)
+
+#endif /* GL_ARB_texture_query_levels */
+
+/* ------------------------ GL_ARB_texture_query_lod ----------------------- */
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+
+#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod)
+
+#endif /* GL_ARB_texture_query_lod */
+
+/* ------------------------ GL_ARB_texture_rectangle ----------------------- */
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+
+#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle)
+
+#endif /* GL_ARB_texture_rectangle */
+
+/* --------------------------- GL_ARB_texture_rg --------------------------- */
+
+#ifndef GL_ARB_texture_rg
+#define GL_ARB_texture_rg 1
+
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RG 0x8226
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_R16 0x822A
+#define GL_RG8 0x822B
+#define GL_RG16 0x822C
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+
+#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg)
+
+#endif /* GL_ARB_texture_rg */
+
+/* ----------------------- GL_ARB_texture_rgb10_a2ui ----------------------- */
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_ARB_texture_rgb10_a2ui 1
+
+#define GL_RGB10_A2UI 0x906F
+
+#define GLEW_ARB_texture_rgb10_a2ui GLEW_GET_VAR(__GLEW_ARB_texture_rgb10_a2ui)
+
+#endif /* GL_ARB_texture_rgb10_a2ui */
+
+/* ------------------------ GL_ARB_texture_stencil8 ------------------------ */
+
+#ifndef GL_ARB_texture_stencil8
+#define GL_ARB_texture_stencil8 1
+
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_INDEX8 0x8D48
+
+#define GLEW_ARB_texture_stencil8 GLEW_GET_VAR(__GLEW_ARB_texture_stencil8)
+
+#endif /* GL_ARB_texture_stencil8 */
+
+/* ------------------------- GL_ARB_texture_storage ------------------------ */
+
+#ifndef GL_ARB_texture_storage
+#define GL_ARB_texture_storage 1
+
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glTexStorage1D GLEW_GET_FUN(__glewTexStorage1D)
+#define glTexStorage2D GLEW_GET_FUN(__glewTexStorage2D)
+#define glTexStorage3D GLEW_GET_FUN(__glewTexStorage3D)
+
+#define GLEW_ARB_texture_storage GLEW_GET_VAR(__GLEW_ARB_texture_storage)
+
+#endif /* GL_ARB_texture_storage */
+
+/* ------------------- GL_ARB_texture_storage_multisample ------------------ */
+
+#ifndef GL_ARB_texture_storage_multisample
+#define GL_ARB_texture_storage_multisample 1
+
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+
+#define glTexStorage2DMultisample GLEW_GET_FUN(__glewTexStorage2DMultisample)
+#define glTexStorage3DMultisample GLEW_GET_FUN(__glewTexStorage3DMultisample)
+#define glTextureStorage2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage2DMultisampleEXT)
+#define glTextureStorage3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage3DMultisampleEXT)
+
+#define GLEW_ARB_texture_storage_multisample GLEW_GET_VAR(__GLEW_ARB_texture_storage_multisample)
+
+#endif /* GL_ARB_texture_storage_multisample */
+
+/* ------------------------- GL_ARB_texture_swizzle ------------------------ */
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_ARB_texture_swizzle 1
+
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+
+#define GLEW_ARB_texture_swizzle GLEW_GET_VAR(__GLEW_ARB_texture_swizzle)
+
+#endif /* GL_ARB_texture_swizzle */
+
+/* -------------------------- GL_ARB_texture_view -------------------------- */
+
+#ifndef GL_ARB_texture_view
+#define GL_ARB_texture_view 1
+
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+
+#define glTextureView GLEW_GET_FUN(__glewTextureView)
+
+#define GLEW_ARB_texture_view GLEW_GET_VAR(__GLEW_ARB_texture_view)
+
+#endif /* GL_ARB_texture_view */
+
+/* --------------------------- GL_ARB_timer_query -------------------------- */
+
+#ifndef GL_ARB_timer_query
+#define GL_ARB_timer_query 1
+
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TIMESTAMP 0x8E28
+
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);
+
+#define glGetQueryObjecti64v GLEW_GET_FUN(__glewGetQueryObjecti64v)
+#define glGetQueryObjectui64v GLEW_GET_FUN(__glewGetQueryObjectui64v)
+#define glQueryCounter GLEW_GET_FUN(__glewQueryCounter)
+
+#define GLEW_ARB_timer_query GLEW_GET_VAR(__GLEW_ARB_timer_query)
+
+#endif /* GL_ARB_timer_query */
+
+/* ----------------------- GL_ARB_transform_feedback2 ---------------------- */
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_ARB_transform_feedback2 1
+
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+
+typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);
+typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids);
+typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+
+#define glBindTransformFeedback GLEW_GET_FUN(__glewBindTransformFeedback)
+#define glDeleteTransformFeedbacks GLEW_GET_FUN(__glewDeleteTransformFeedbacks)
+#define glDrawTransformFeedback GLEW_GET_FUN(__glewDrawTransformFeedback)
+#define glGenTransformFeedbacks GLEW_GET_FUN(__glewGenTransformFeedbacks)
+#define glIsTransformFeedback GLEW_GET_FUN(__glewIsTransformFeedback)
+#define glPauseTransformFeedback GLEW_GET_FUN(__glewPauseTransformFeedback)
+#define glResumeTransformFeedback GLEW_GET_FUN(__glewResumeTransformFeedback)
+
+#define GLEW_ARB_transform_feedback2 GLEW_GET_VAR(__GLEW_ARB_transform_feedback2)
+
+#endif /* GL_ARB_transform_feedback2 */
+
+/* ----------------------- GL_ARB_transform_feedback3 ---------------------- */
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_ARB_transform_feedback3 1
+
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);
+typedef void (GLAPIENTRY * PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params);
+
+#define glBeginQueryIndexed GLEW_GET_FUN(__glewBeginQueryIndexed)
+#define glDrawTransformFeedbackStream GLEW_GET_FUN(__glewDrawTransformFeedbackStream)
+#define glEndQueryIndexed GLEW_GET_FUN(__glewEndQueryIndexed)
+#define glGetQueryIndexediv GLEW_GET_FUN(__glewGetQueryIndexediv)
+
+#define GLEW_ARB_transform_feedback3 GLEW_GET_VAR(__GLEW_ARB_transform_feedback3)
+
+#endif /* GL_ARB_transform_feedback3 */
+
+/* ------------------ GL_ARB_transform_feedback_instanced ------------------ */
+
+#ifndef GL_ARB_transform_feedback_instanced
+#define GL_ARB_transform_feedback_instanced 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+
+#define glDrawTransformFeedbackInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackInstanced)
+#define glDrawTransformFeedbackStreamInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackStreamInstanced)
+
+#define GLEW_ARB_transform_feedback_instanced GLEW_GET_VAR(__GLEW_ARB_transform_feedback_instanced)
+
+#endif /* GL_ARB_transform_feedback_instanced */
+
+/* ---------------- GL_ARB_transform_feedback_overflow_query --------------- */
+
+#ifndef GL_ARB_transform_feedback_overflow_query
+#define GL_ARB_transform_feedback_overflow_query 1
+
+#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC
+#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED
+
+#define GLEW_ARB_transform_feedback_overflow_query GLEW_GET_VAR(__GLEW_ARB_transform_feedback_overflow_query)
+
+#endif /* GL_ARB_transform_feedback_overflow_query */
+
+/* ------------------------ GL_ARB_transpose_matrix ------------------------ */
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]);
+
+#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB)
+#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB)
+#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB)
+#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB)
+
+#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix)
+
+#endif /* GL_ARB_transpose_matrix */
+
+/* ---------------------- GL_ARB_uniform_buffer_object --------------------- */
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_ARB_uniform_buffer_object 1
+
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data);
+typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar* uniformBlockName);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const * uniformNames, GLuint* uniformIndices);
+typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+
+#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase)
+#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange)
+#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName)
+#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv)
+#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName)
+#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv)
+#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v)
+#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex)
+#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices)
+#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding)
+
+#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object)
+
+#endif /* GL_ARB_uniform_buffer_object */
+
+/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+
+#define GL_BGRA 0x80E1
+
+#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra)
+
+#endif /* GL_ARB_vertex_array_bgra */
+
+/* ----------------------- GL_ARB_vertex_array_object ---------------------- */
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_ARB_vertex_array_object 1
+
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays);
+typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array);
+
+#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray)
+#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays)
+#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays)
+#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray)
+
+#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object)
+
+#endif /* GL_ARB_vertex_array_object */
+
+/* ----------------------- GL_ARB_vertex_attrib_64bit ---------------------- */
+
+#ifndef GL_ARB_vertex_attrib_64bit
+#define GL_ARB_vertex_attrib_64bit 1
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
+
+#define glGetVertexAttribLdv GLEW_GET_FUN(__glewGetVertexAttribLdv)
+#define glVertexAttribL1d GLEW_GET_FUN(__glewVertexAttribL1d)
+#define glVertexAttribL1dv GLEW_GET_FUN(__glewVertexAttribL1dv)
+#define glVertexAttribL2d GLEW_GET_FUN(__glewVertexAttribL2d)
+#define glVertexAttribL2dv GLEW_GET_FUN(__glewVertexAttribL2dv)
+#define glVertexAttribL3d GLEW_GET_FUN(__glewVertexAttribL3d)
+#define glVertexAttribL3dv GLEW_GET_FUN(__glewVertexAttribL3dv)
+#define glVertexAttribL4d GLEW_GET_FUN(__glewVertexAttribL4d)
+#define glVertexAttribL4dv GLEW_GET_FUN(__glewVertexAttribL4dv)
+#define glVertexAttribLPointer GLEW_GET_FUN(__glewVertexAttribLPointer)
+
+#define GLEW_ARB_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_64bit)
+
+#endif /* GL_ARB_vertex_attrib_64bit */
+
+/* ---------------------- GL_ARB_vertex_attrib_binding --------------------- */
+
+#ifndef GL_ARB_vertex_attrib_binding
+#define GL_ARB_vertex_attrib_binding 1
+
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_VERTEX_BINDING_BUFFER 0x8F4F
+
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor);
+
+#define glBindVertexBuffer GLEW_GET_FUN(__glewBindVertexBuffer)
+#define glVertexArrayBindVertexBufferEXT GLEW_GET_FUN(__glewVertexArrayBindVertexBufferEXT)
+#define glVertexArrayVertexAttribBindingEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribBindingEXT)
+#define glVertexArrayVertexAttribFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribFormatEXT)
+#define glVertexArrayVertexAttribIFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIFormatEXT)
+#define glVertexArrayVertexAttribLFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLFormatEXT)
+#define glVertexArrayVertexBindingDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexBindingDivisorEXT)
+#define glVertexAttribBinding GLEW_GET_FUN(__glewVertexAttribBinding)
+#define glVertexAttribFormat GLEW_GET_FUN(__glewVertexAttribFormat)
+#define glVertexAttribIFormat GLEW_GET_FUN(__glewVertexAttribIFormat)
+#define glVertexAttribLFormat GLEW_GET_FUN(__glewVertexAttribLFormat)
+#define glVertexBindingDivisor GLEW_GET_FUN(__glewVertexBindingDivisor)
+
+#define GLEW_ARB_vertex_attrib_binding GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_binding)
+
+#endif /* GL_ARB_vertex_attrib_binding */
+
+/* -------------------------- GL_ARB_vertex_blend -------------------------- */
+
+#ifndef GL_ARB_vertex_blend
+#define GL_ARB_vertex_blend 1
+
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+
+typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count);
+typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, void *pointer);
+typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights);
+
+#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB)
+#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB)
+#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB)
+#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB)
+#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB)
+#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB)
+#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB)
+#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB)
+#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB)
+#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB)
+
+#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend)
+
+#endif /* GL_ARB_vertex_blend */
+
+/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+
+#define GL_BUFFER_SIZE_ARB 0x8764
+#define GL_BUFFER_USAGE_ARB 0x8765
+#define GL_ARRAY_BUFFER_ARB 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_READ_ONLY_ARB 0x88B8
+#define GL_WRITE_ONLY_ARB 0x88B9
+#define GL_READ_WRITE_ARB 0x88BA
+#define GL_BUFFER_ACCESS_ARB 0x88BB
+#define GL_BUFFER_MAPPED_ARB 0x88BC
+#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data);
+typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void** params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data);
+typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer);
+typedef void * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
+typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target);
+
+#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB)
+#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB)
+#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB)
+#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB)
+#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB)
+#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB)
+#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB)
+#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB)
+#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB)
+#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB)
+#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB)
+
+#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object)
+
+#endif /* GL_ARB_vertex_buffer_object */
+
+/* ------------------------- GL_ARB_vertex_program ------------------------- */
+
+#ifndef GL_ARB_vertex_program
+#define GL_ARB_vertex_program 1
+
+#define GL_COLOR_SUM_ARB 0x8458
+#define GL_VERTEX_PROGRAM_ARB 0x8620
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define GL_PROGRAM_LENGTH_ARB 0x8627
+#define GL_PROGRAM_STRING_ARB 0x8628
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_ARB 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GL_PROGRAM_BINDING_ARB 0x8677
+#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define GL_PROGRAM_FORMAT_ARB 0x8876
+#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define GL_MATRIX0_ARB 0x88C0
+#define GL_MATRIX1_ARB 0x88C1
+#define GL_MATRIX2_ARB 0x88C2
+#define GL_MATRIX3_ARB 0x88C3
+#define GL_MATRIX4_ARB 0x88C4
+#define GL_MATRIX5_ARB 0x88C5
+#define GL_MATRIX6_ARB 0x88C6
+#define GL_MATRIX7_ARB 0x88C7
+#define GL_MATRIX8_ARB 0x88C8
+#define GL_MATRIX9_ARB 0x88C9
+#define GL_MATRIX10_ARB 0x88CA
+#define GL_MATRIX11_ARB 0x88CB
+#define GL_MATRIX12_ARB 0x88CC
+#define GL_MATRIX13_ARB 0x88CD
+#define GL_MATRIX14_ARB 0x88CE
+#define GL_MATRIX15_ARB 0x88CF
+#define GL_MATRIX16_ARB 0x88D0
+#define GL_MATRIX17_ARB 0x88D1
+#define GL_MATRIX18_ARB 0x88D2
+#define GL_MATRIX19_ARB 0x88D3
+#define GL_MATRIX20_ARB 0x88D4
+#define GL_MATRIX21_ARB 0x88D5
+#define GL_MATRIX22_ARB 0x88D6
+#define GL_MATRIX23_ARB 0x88D7
+#define GL_MATRIX24_ARB 0x88D8
+#define GL_MATRIX25_ARB 0x88D9
+#define GL_MATRIX26_ARB 0x88DA
+#define GL_MATRIX27_ARB 0x88DB
+#define GL_MATRIX28_ARB 0x88DC
+#define GL_MATRIX29_ARB 0x88DD
+#define GL_MATRIX30_ARB 0x88DE
+#define GL_MATRIX31_ARB 0x88DF
+
+typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void** pointer);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+
+#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB)
+#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB)
+#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB)
+#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB)
+#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB)
+#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB)
+#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB)
+#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB)
+#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB)
+#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB)
+#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB)
+#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB)
+#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB)
+#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB)
+#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB)
+#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB)
+#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB)
+#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB)
+#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB)
+#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB)
+#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB)
+#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB)
+#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB)
+#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB)
+#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB)
+#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB)
+#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB)
+#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB)
+#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB)
+#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB)
+#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB)
+#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB)
+#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB)
+#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB)
+#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB)
+#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB)
+#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB)
+#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB)
+#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB)
+#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB)
+#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB)
+#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB)
+#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB)
+#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB)
+#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB)
+#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB)
+#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB)
+#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB)
+#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB)
+#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB)
+#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB)
+#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB)
+#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB)
+#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB)
+#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB)
+#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB)
+#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB)
+#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB)
+#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB)
+#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB)
+#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB)
+#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB)
+
+#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program)
+
+#endif /* GL_ARB_vertex_program */
+
+/* -------------------------- GL_ARB_vertex_shader ------------------------- */
+
+#ifndef GL_ARB_vertex_shader
+#define GL_ARB_vertex_shader 1
+
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+
+typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name);
+typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name);
+
+#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB)
+#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB)
+#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB)
+
+#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader)
+
+#endif /* GL_ARB_vertex_shader */
+
+/* ------------------- GL_ARB_vertex_type_10f_11f_11f_rev ------------------ */
+
+#ifndef GL_ARB_vertex_type_10f_11f_11f_rev
+#define GL_ARB_vertex_type_10f_11f_11f_rev 1
+
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+
+#define GLEW_ARB_vertex_type_10f_11f_11f_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_10f_11f_11f_rev)
+
+#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */
+
+/* ------------------- GL_ARB_vertex_type_2_10_10_10_rev ------------------- */
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+#define GL_ARB_vertex_type_2_10_10_10_rev 1
+
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_INT_2_10_10_10_REV 0x8D9F
+
+typedef void (GLAPIENTRY * PFNGLCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (GLAPIENTRY * PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint* color);
+typedef void (GLAPIENTRY * PFNGLCOLORP4UIPROC) (GLenum type, GLuint color);
+typedef void (GLAPIENTRY * PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint* color);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint* color);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint* value);
+
+#define glColorP3ui GLEW_GET_FUN(__glewColorP3ui)
+#define glColorP3uiv GLEW_GET_FUN(__glewColorP3uiv)
+#define glColorP4ui GLEW_GET_FUN(__glewColorP4ui)
+#define glColorP4uiv GLEW_GET_FUN(__glewColorP4uiv)
+#define glMultiTexCoordP1ui GLEW_GET_FUN(__glewMultiTexCoordP1ui)
+#define glMultiTexCoordP1uiv GLEW_GET_FUN(__glewMultiTexCoordP1uiv)
+#define glMultiTexCoordP2ui GLEW_GET_FUN(__glewMultiTexCoordP2ui)
+#define glMultiTexCoordP2uiv GLEW_GET_FUN(__glewMultiTexCoordP2uiv)
+#define glMultiTexCoordP3ui GLEW_GET_FUN(__glewMultiTexCoordP3ui)
+#define glMultiTexCoordP3uiv GLEW_GET_FUN(__glewMultiTexCoordP3uiv)
+#define glMultiTexCoordP4ui GLEW_GET_FUN(__glewMultiTexCoordP4ui)
+#define glMultiTexCoordP4uiv GLEW_GET_FUN(__glewMultiTexCoordP4uiv)
+#define glNormalP3ui GLEW_GET_FUN(__glewNormalP3ui)
+#define glNormalP3uiv GLEW_GET_FUN(__glewNormalP3uiv)
+#define glSecondaryColorP3ui GLEW_GET_FUN(__glewSecondaryColorP3ui)
+#define glSecondaryColorP3uiv GLEW_GET_FUN(__glewSecondaryColorP3uiv)
+#define glTexCoordP1ui GLEW_GET_FUN(__glewTexCoordP1ui)
+#define glTexCoordP1uiv GLEW_GET_FUN(__glewTexCoordP1uiv)
+#define glTexCoordP2ui GLEW_GET_FUN(__glewTexCoordP2ui)
+#define glTexCoordP2uiv GLEW_GET_FUN(__glewTexCoordP2uiv)
+#define glTexCoordP3ui GLEW_GET_FUN(__glewTexCoordP3ui)
+#define glTexCoordP3uiv GLEW_GET_FUN(__glewTexCoordP3uiv)
+#define glTexCoordP4ui GLEW_GET_FUN(__glewTexCoordP4ui)
+#define glTexCoordP4uiv GLEW_GET_FUN(__glewTexCoordP4uiv)
+#define glVertexAttribP1ui GLEW_GET_FUN(__glewVertexAttribP1ui)
+#define glVertexAttribP1uiv GLEW_GET_FUN(__glewVertexAttribP1uiv)
+#define glVertexAttribP2ui GLEW_GET_FUN(__glewVertexAttribP2ui)
+#define glVertexAttribP2uiv GLEW_GET_FUN(__glewVertexAttribP2uiv)
+#define glVertexAttribP3ui GLEW_GET_FUN(__glewVertexAttribP3ui)
+#define glVertexAttribP3uiv GLEW_GET_FUN(__glewVertexAttribP3uiv)
+#define glVertexAttribP4ui GLEW_GET_FUN(__glewVertexAttribP4ui)
+#define glVertexAttribP4uiv GLEW_GET_FUN(__glewVertexAttribP4uiv)
+#define glVertexP2ui GLEW_GET_FUN(__glewVertexP2ui)
+#define glVertexP2uiv GLEW_GET_FUN(__glewVertexP2uiv)
+#define glVertexP3ui GLEW_GET_FUN(__glewVertexP3ui)
+#define glVertexP3uiv GLEW_GET_FUN(__glewVertexP3uiv)
+#define glVertexP4ui GLEW_GET_FUN(__glewVertexP4ui)
+#define glVertexP4uiv GLEW_GET_FUN(__glewVertexP4uiv)
+
+#define GLEW_ARB_vertex_type_2_10_10_10_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_2_10_10_10_rev)
+
+#endif /* GL_ARB_vertex_type_2_10_10_10_rev */
+
+/* ------------------------- GL_ARB_viewport_array ------------------------- */
+
+#ifndef GL_ARB_viewport_array
+#define GL_ARB_viewport_array 1
+
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd * v);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble* data);
+typedef void (GLAPIENTRY * PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat* data);
+typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint * v);
+typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint * v);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat * v);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat * v);
+
+#define glDepthRangeArrayv GLEW_GET_FUN(__glewDepthRangeArrayv)
+#define glDepthRangeIndexed GLEW_GET_FUN(__glewDepthRangeIndexed)
+#define glGetDoublei_v GLEW_GET_FUN(__glewGetDoublei_v)
+#define glGetFloati_v GLEW_GET_FUN(__glewGetFloati_v)
+#define glScissorArrayv GLEW_GET_FUN(__glewScissorArrayv)
+#define glScissorIndexed GLEW_GET_FUN(__glewScissorIndexed)
+#define glScissorIndexedv GLEW_GET_FUN(__glewScissorIndexedv)
+#define glViewportArrayv GLEW_GET_FUN(__glewViewportArrayv)
+#define glViewportIndexedf GLEW_GET_FUN(__glewViewportIndexedf)
+#define glViewportIndexedfv GLEW_GET_FUN(__glewViewportIndexedfv)
+
+#define GLEW_ARB_viewport_array GLEW_GET_VAR(__GLEW_ARB_viewport_array)
+
+#endif /* GL_ARB_viewport_array */
+
+/* --------------------------- GL_ARB_window_pos --------------------------- */
+
+#ifndef GL_ARB_window_pos
+#define GL_ARB_window_pos 1
+
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p);
+
+#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB)
+#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB)
+#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB)
+#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB)
+#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB)
+#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB)
+#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB)
+#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB)
+#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB)
+#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB)
+#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB)
+#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB)
+#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB)
+#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB)
+#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB)
+#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB)
+
+#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos)
+
+#endif /* GL_ARB_window_pos */
+
+/* ----------------------- GL_ARM_mali_program_binary ---------------------- */
+
+#ifndef GL_ARM_mali_program_binary
+#define GL_ARM_mali_program_binary 1
+
+#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61
+
+#define GLEW_ARM_mali_program_binary GLEW_GET_VAR(__GLEW_ARM_mali_program_binary)
+
+#endif /* GL_ARM_mali_program_binary */
+
+/* ----------------------- GL_ARM_mali_shader_binary ----------------------- */
+
+#ifndef GL_ARM_mali_shader_binary
+#define GL_ARM_mali_shader_binary 1
+
+#define GL_MALI_SHADER_BINARY_ARM 0x8F60
+
+#define GLEW_ARM_mali_shader_binary GLEW_GET_VAR(__GLEW_ARM_mali_shader_binary)
+
+#endif /* GL_ARM_mali_shader_binary */
+
+/* ------------------------------ GL_ARM_rgba8 ----------------------------- */
+
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+
+#define GL_RGBA8_OES 0x8058
+
+#define GLEW_ARM_rgba8 GLEW_GET_VAR(__GLEW_ARM_rgba8)
+
+#endif /* GL_ARM_rgba8 */
+
+/* -------------------- GL_ARM_shader_framebuffer_fetch -------------------- */
+
+#ifndef GL_ARM_shader_framebuffer_fetch
+#define GL_ARM_shader_framebuffer_fetch 1
+
+#define GL_FETCH_PER_SAMPLE_ARM 0x8F65
+#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66
+
+#define GLEW_ARM_shader_framebuffer_fetch GLEW_GET_VAR(__GLEW_ARM_shader_framebuffer_fetch)
+
+#endif /* GL_ARM_shader_framebuffer_fetch */
+
+/* ------------- GL_ARM_shader_framebuffer_fetch_depth_stencil ------------- */
+
+#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil
+#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1
+
+#define GLEW_ARM_shader_framebuffer_fetch_depth_stencil GLEW_GET_VAR(__GLEW_ARM_shader_framebuffer_fetch_depth_stencil)
+
+#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */
+
+/* ------------------------- GL_ATIX_point_sprites ------------------------- */
+
+#ifndef GL_ATIX_point_sprites
+#define GL_ATIX_point_sprites 1
+
+#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0
+#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1
+#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2
+#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3
+#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4
+#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5
+
+#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites)
+
+#endif /* GL_ATIX_point_sprites */
+
+/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */
+
+#ifndef GL_ATIX_texture_env_combine3
+#define GL_ATIX_texture_env_combine3 1
+
+#define GL_MODULATE_ADD_ATIX 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745
+#define GL_MODULATE_SUBTRACT_ATIX 0x8746
+
+#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3)
+
+#endif /* GL_ATIX_texture_env_combine3 */
+
+/* ----------------------- GL_ATIX_texture_env_route ----------------------- */
+
+#ifndef GL_ATIX_texture_env_route
+#define GL_ATIX_texture_env_route 1
+
+#define GL_SECONDARY_COLOR_ATIX 0x8747
+#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748
+#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749
+
+#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route)
+
+#endif /* GL_ATIX_texture_env_route */
+
+/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */
+
+#ifndef GL_ATIX_vertex_shader_output_point_size
+#define GL_ATIX_vertex_shader_output_point_size 1
+
+#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E
+
+#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size)
+
+#endif /* GL_ATIX_vertex_shader_output_point_size */
+
+/* -------------------------- GL_ATI_draw_buffers -------------------------- */
+
+#ifndef GL_ATI_draw_buffers
+#define GL_ATI_draw_buffers 1
+
+#define GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define GL_DRAW_BUFFER0_ATI 0x8825
+#define GL_DRAW_BUFFER1_ATI 0x8826
+#define GL_DRAW_BUFFER2_ATI 0x8827
+#define GL_DRAW_BUFFER3_ATI 0x8828
+#define GL_DRAW_BUFFER4_ATI 0x8829
+#define GL_DRAW_BUFFER5_ATI 0x882A
+#define GL_DRAW_BUFFER6_ATI 0x882B
+#define GL_DRAW_BUFFER7_ATI 0x882C
+#define GL_DRAW_BUFFER8_ATI 0x882D
+#define GL_DRAW_BUFFER9_ATI 0x882E
+#define GL_DRAW_BUFFER10_ATI 0x882F
+#define GL_DRAW_BUFFER11_ATI 0x8830
+#define GL_DRAW_BUFFER12_ATI 0x8831
+#define GL_DRAW_BUFFER13_ATI 0x8832
+#define GL_DRAW_BUFFER14_ATI 0x8833
+#define GL_DRAW_BUFFER15_ATI 0x8834
+
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs);
+
+#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI)
+
+#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers)
+
+#endif /* GL_ATI_draw_buffers */
+
+/* -------------------------- GL_ATI_element_array ------------------------- */
+
+#ifndef GL_ATI_element_array
+#define GL_ATI_element_array 1
+
+#define GL_ELEMENT_ARRAY_ATI 0x8768
+#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer);
+
+#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI)
+#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI)
+#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI)
+
+#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array)
+
+#endif /* GL_ATI_element_array */
+
+/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_ATI_envmap_bumpmap 1
+
+#define GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define GL_BUMP_TEX_UNITS_ATI 0x8778
+#define GL_DUDV_ATI 0x8779
+#define GL_DU8DV8_ATI 0x877A
+#define GL_BUMP_ENVMAP_ATI 0x877B
+#define GL_BUMP_TARGET_ATI 0x877C
+
+typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+
+#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI)
+#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI)
+#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI)
+#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI)
+
+#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap)
+
+#endif /* GL_ATI_envmap_bumpmap */
+
+/* ------------------------- GL_ATI_fragment_shader ------------------------ */
+
+#ifndef GL_ATI_fragment_shader
+#define GL_ATI_fragment_shader 1
+
+#define GL_2X_BIT_ATI 0x00000001
+#define GL_RED_BIT_ATI 0x00000001
+#define GL_4X_BIT_ATI 0x00000002
+#define GL_COMP_BIT_ATI 0x00000002
+#define GL_GREEN_BIT_ATI 0x00000002
+#define GL_8X_BIT_ATI 0x00000004
+#define GL_BLUE_BIT_ATI 0x00000004
+#define GL_NEGATE_BIT_ATI 0x00000004
+#define GL_BIAS_BIT_ATI 0x00000008
+#define GL_HALF_BIT_ATI 0x00000008
+#define GL_QUARTER_BIT_ATI 0x00000010
+#define GL_EIGHTH_BIT_ATI 0x00000020
+#define GL_SATURATE_BIT_ATI 0x00000040
+#define GL_FRAGMENT_SHADER_ATI 0x8920
+#define GL_REG_0_ATI 0x8921
+#define GL_REG_1_ATI 0x8922
+#define GL_REG_2_ATI 0x8923
+#define GL_REG_3_ATI 0x8924
+#define GL_REG_4_ATI 0x8925
+#define GL_REG_5_ATI 0x8926
+#define GL_CON_0_ATI 0x8941
+#define GL_CON_1_ATI 0x8942
+#define GL_CON_2_ATI 0x8943
+#define GL_CON_3_ATI 0x8944
+#define GL_CON_4_ATI 0x8945
+#define GL_CON_5_ATI 0x8946
+#define GL_CON_6_ATI 0x8947
+#define GL_CON_7_ATI 0x8948
+#define GL_MOV_ATI 0x8961
+#define GL_ADD_ATI 0x8963
+#define GL_MUL_ATI 0x8964
+#define GL_SUB_ATI 0x8965
+#define GL_DOT3_ATI 0x8966
+#define GL_DOT4_ATI 0x8967
+#define GL_MAD_ATI 0x8968
+#define GL_LERP_ATI 0x8969
+#define GL_CND_ATI 0x896A
+#define GL_CND0_ATI 0x896B
+#define GL_DOT2_ADD_ATI 0x896C
+#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define GL_NUM_PASSES_ATI 0x8970
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define GL_SWIZZLE_STR_ATI 0x8976
+#define GL_SWIZZLE_STQ_ATI 0x8977
+#define GL_SWIZZLE_STR_DR_ATI 0x8978
+#define GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define GL_SWIZZLE_STRQ_ATI 0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+
+typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void);
+typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void);
+typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range);
+typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle);
+typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle);
+typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value);
+
+#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI)
+#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI)
+#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI)
+#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI)
+#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI)
+#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI)
+#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI)
+#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI)
+#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI)
+#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI)
+#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI)
+#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI)
+#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI)
+#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI)
+
+#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader)
+
+#endif /* GL_ATI_fragment_shader */
+
+/* ------------------------ GL_ATI_map_object_buffer ----------------------- */
+
+#ifndef GL_ATI_map_object_buffer
+#define GL_ATI_map_object_buffer 1
+
+typedef void * (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+
+#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI)
+#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI)
+
+#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer)
+
+#endif /* GL_ATI_map_object_buffer */
+
+/* ----------------------------- GL_ATI_meminfo ---------------------------- */
+
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo 1
+
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+
+#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo)
+
+#endif /* GL_ATI_meminfo */
+
+/* -------------------------- GL_ATI_pn_triangles -------------------------- */
+
+#ifndef GL_ATI_pn_triangles
+#define GL_ATI_pn_triangles 1
+
+#define GL_PN_TRIANGLES_ATI 0x87F0
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+
+typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param);
+
+#define glPNTrianglesfATI GLEW_GET_FUN(__glewPNTrianglesfATI)
+#define glPNTrianglesiATI GLEW_GET_FUN(__glewPNTrianglesiATI)
+
+#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles)
+
+#endif /* GL_ATI_pn_triangles */
+
+/* ------------------------ GL_ATI_separate_stencil ------------------------ */
+
+#ifndef GL_ATI_separate_stencil
+#define GL_ATI_separate_stencil 1
+
+#define GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+
+typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+
+#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI)
+#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI)
+
+#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil)
+
+#endif /* GL_ATI_separate_stencil */
+
+/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */
+
+#ifndef GL_ATI_shader_texture_lod
+#define GL_ATI_shader_texture_lod 1
+
+#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod)
+
+#endif /* GL_ATI_shader_texture_lod */
+
+/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_ATI_text_fragment_shader 1
+
+#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+
+#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader)
+
+#endif /* GL_ATI_text_fragment_shader */
+
+/* --------------------- GL_ATI_texture_compression_3dc -------------------- */
+
+#ifndef GL_ATI_texture_compression_3dc
+#define GL_ATI_texture_compression_3dc 1
+
+#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837
+
+#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc)
+
+#endif /* GL_ATI_texture_compression_3dc */
+
+/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+
+#define GL_MODULATE_ADD_ATI 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define GL_MODULATE_SUBTRACT_ATI 0x8746
+
+#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3)
+
+#endif /* GL_ATI_texture_env_combine3 */
+
+/* -------------------------- GL_ATI_texture_float ------------------------- */
+
+#ifndef GL_ATI_texture_float
+#define GL_ATI_texture_float 1
+
+#define GL_RGBA_FLOAT32_ATI 0x8814
+#define GL_RGB_FLOAT32_ATI 0x8815
+#define GL_ALPHA_FLOAT32_ATI 0x8816
+#define GL_INTENSITY_FLOAT32_ATI 0x8817
+#define GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define GL_RGBA_FLOAT16_ATI 0x881A
+#define GL_RGB_FLOAT16_ATI 0x881B
+#define GL_ALPHA_FLOAT16_ATI 0x881C
+#define GL_INTENSITY_FLOAT16_ATI 0x881D
+#define GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+
+#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float)
+
+#endif /* GL_ATI_texture_float */
+
+/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+
+#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once)
+
+#endif /* GL_ATI_texture_mirror_once */
+
+/* ----------------------- GL_ATI_vertex_array_object ---------------------- */
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_ATI_vertex_array_object 1
+
+#define GL_STATIC_ATI 0x8760
+#define GL_DYNAMIC_ATI 0x8761
+#define GL_PRESERVE_ATI 0x8762
+#define GL_DISCARD_ATI 0x8763
+#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+
+typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve);
+typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+
+#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI)
+#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI)
+#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI)
+#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI)
+#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI)
+#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI)
+#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI)
+#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI)
+#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI)
+#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI)
+#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI)
+#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI)
+
+#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object)
+
+#endif /* GL_ATI_vertex_array_object */
+
+/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#define GL_ATI_vertex_attrib_array_object 1
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+
+#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI)
+#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI)
+#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI)
+
+#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object)
+
+#endif /* GL_ATI_vertex_attrib_array_object */
+
+/* ------------------------- GL_ATI_vertex_streams ------------------------- */
+
+#ifndef GL_ATI_vertex_streams
+#define GL_ATI_vertex_streams 1
+
+#define GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define GL_VERTEX_SOURCE_ATI 0x876C
+#define GL_VERTEX_STREAM0_ATI 0x876D
+#define GL_VERTEX_STREAM1_ATI 0x876E
+#define GL_VERTEX_STREAM2_ATI 0x876F
+#define GL_VERTEX_STREAM3_ATI 0x8770
+#define GL_VERTEX_STREAM4_ATI 0x8771
+#define GL_VERTEX_STREAM5_ATI 0x8772
+#define GL_VERTEX_STREAM6_ATI 0x8773
+#define GL_VERTEX_STREAM7_ATI 0x8774
+
+typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords);
+
+#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI)
+#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI)
+#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI)
+#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI)
+#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI)
+#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI)
+#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI)
+#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI)
+#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI)
+#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI)
+#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI)
+#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI)
+#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI)
+#define glVertexStream1dATI GLEW_GET_FUN(__glewVertexStream1dATI)
+#define glVertexStream1dvATI GLEW_GET_FUN(__glewVertexStream1dvATI)
+#define glVertexStream1fATI GLEW_GET_FUN(__glewVertexStream1fATI)
+#define glVertexStream1fvATI GLEW_GET_FUN(__glewVertexStream1fvATI)
+#define glVertexStream1iATI GLEW_GET_FUN(__glewVertexStream1iATI)
+#define glVertexStream1ivATI GLEW_GET_FUN(__glewVertexStream1ivATI)
+#define glVertexStream1sATI GLEW_GET_FUN(__glewVertexStream1sATI)
+#define glVertexStream1svATI GLEW_GET_FUN(__glewVertexStream1svATI)
+#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI)
+#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI)
+#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI)
+#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI)
+#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI)
+#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI)
+#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI)
+#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI)
+#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI)
+#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI)
+#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI)
+#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI)
+#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI)
+#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI)
+#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI)
+#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI)
+#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI)
+#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI)
+#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI)
+#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI)
+#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI)
+#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI)
+#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI)
+#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI)
+
+#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams)
+
+#endif /* GL_ATI_vertex_streams */
+
+/* -------------------- GL_EGL_KHR_context_flush_control ------------------- */
+
+#ifndef GL_EGL_KHR_context_flush_control
+#define GL_EGL_KHR_context_flush_control 1
+
+#define GLEW_EGL_KHR_context_flush_control GLEW_GET_VAR(__GLEW_EGL_KHR_context_flush_control)
+
+#endif /* GL_EGL_KHR_context_flush_control */
+
+/* ---------------- GL_EGL_NV_robustness_video_memory_purge ---------------- */
+
+#ifndef GL_EGL_NV_robustness_video_memory_purge
+#define GL_EGL_NV_robustness_video_memory_purge 1
+
+#define GL_EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
+
+#define GLEW_EGL_NV_robustness_video_memory_purge GLEW_GET_VAR(__GLEW_EGL_NV_robustness_video_memory_purge)
+
+#endif /* GL_EGL_NV_robustness_video_memory_purge */
+
+/* --------------------------- GL_EXT_422_pixels --------------------------- */
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_EXT 0x80CD
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+
+#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels)
+
+#endif /* GL_EXT_422_pixels */
+
+/* ---------------------------- GL_EXT_Cg_shader --------------------------- */
+
+#ifndef GL_EXT_Cg_shader
+#define GL_EXT_Cg_shader 1
+
+#define GL_CG_VERTEX_SHADER_EXT 0x890E
+#define GL_CG_FRAGMENT_SHADER_EXT 0x890F
+
+#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader)
+
+#endif /* GL_EXT_Cg_shader */
+
+/* ------------------------- GL_EXT_EGL_image_array ------------------------ */
+
+#ifndef GL_EXT_EGL_image_array
+#define GL_EXT_EGL_image_array 1
+
+#define GLEW_EXT_EGL_image_array GLEW_GET_VAR(__GLEW_EXT_EGL_image_array)
+
+#endif /* GL_EXT_EGL_image_array */
+
+/* --------------------------- GL_EXT_YUV_target --------------------------- */
+
+#ifndef GL_EXT_YUV_target
+#define GL_EXT_YUV_target 1
+
+#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7
+
+#define GLEW_EXT_YUV_target GLEW_GET_VAR(__GLEW_EXT_YUV_target)
+
+#endif /* GL_EXT_YUV_target */
+
+/* ------------------------------ GL_EXT_abgr ------------------------------ */
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+
+#define GL_ABGR_EXT 0x8000
+
+#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr)
+
+#endif /* GL_EXT_abgr */
+
+/* -------------------------- GL_EXT_base_instance ------------------------- */
+
+#ifndef GL_EXT_base_instance
+#define GL_EXT_base_instance 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+
+#define glDrawArraysInstancedBaseInstanceEXT GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstanceEXT)
+#define glDrawElementsInstancedBaseInstanceEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstanceEXT)
+#define glDrawElementsInstancedBaseVertexBaseInstanceEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstanceEXT)
+
+#define GLEW_EXT_base_instance GLEW_GET_VAR(__GLEW_EXT_base_instance)
+
+#endif /* GL_EXT_base_instance */
+
+/* ------------------------------ GL_EXT_bgra ------------------------------ */
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+
+#define GL_BGR_EXT 0x80E0
+#define GL_BGRA_EXT 0x80E1
+
+#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra)
+
+#endif /* GL_EXT_bgra */
+
+/* ------------------------ GL_EXT_bindable_uniform ------------------------ */
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_EXT_bindable_uniform 1
+
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+
+typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location);
+typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location);
+typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer);
+
+#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT)
+#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT)
+#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT)
+
+#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform)
+
+#endif /* GL_EXT_bindable_uniform */
+
+/* --------------------------- GL_EXT_blend_color -------------------------- */
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_BLEND_COLOR_EXT 0x8005
+
+typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+
+#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT)
+
+#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color)
+
+#endif /* GL_EXT_blend_color */
+
+/* --------------------- GL_EXT_blend_equation_separate -------------------- */
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_EXT_blend_equation_separate 1
+
+#define GL_BLEND_EQUATION_RGB_EXT 0x8009
+#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha);
+
+#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT)
+
+#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate)
+
+#endif /* GL_EXT_blend_equation_separate */
+
+/* ----------------------- GL_EXT_blend_func_extended ---------------------- */
+
+#ifndef GL_EXT_blend_func_extended
+#define GL_EXT_blend_func_extended 1
+
+#define GL_SRC_ALPHA_SATURATE_EXT 0x0308
+#define GL_SRC1_ALPHA_EXT 0x8589
+#define GL_SRC1_COLOR_EXT 0x88F9
+#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC
+#define GL_LOCATION_INDEX_EXT 0x930F
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name);
+typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar * name);
+typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar* name);
+
+#define glBindFragDataLocationIndexedEXT GLEW_GET_FUN(__glewBindFragDataLocationIndexedEXT)
+#define glGetFragDataIndexEXT GLEW_GET_FUN(__glewGetFragDataIndexEXT)
+#define glGetProgramResourceLocationIndexEXT GLEW_GET_FUN(__glewGetProgramResourceLocationIndexEXT)
+
+#define GLEW_EXT_blend_func_extended GLEW_GET_VAR(__GLEW_EXT_blend_func_extended)
+
+#endif /* GL_EXT_blend_func_extended */
+
+/* ----------------------- GL_EXT_blend_func_separate ---------------------- */
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+
+#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT)
+
+#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate)
+
+#endif /* GL_EXT_blend_func_separate */
+
+/* ------------------------- GL_EXT_blend_logic_op ------------------------- */
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+
+#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op)
+
+#endif /* GL_EXT_blend_logic_op */
+
+/* -------------------------- GL_EXT_blend_minmax -------------------------- */
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#define GL_BLEND_EQUATION_EXT 0x8009
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+
+#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT)
+
+#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax)
+
+#endif /* GL_EXT_blend_minmax */
+
+/* ------------------------- GL_EXT_blend_subtract ------------------------- */
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+
+#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract)
+
+#endif /* GL_EXT_blend_subtract */
+
+/* ------------------------- GL_EXT_buffer_storage ------------------------- */
+
+#ifndef GL_EXT_buffer_storage
+#define GL_EXT_buffer_storage 1
+
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_PERSISTENT_BIT_EXT 0x0040
+#define GL_MAP_COHERENT_BIT_EXT 0x0080
+#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100
+#define GL_CLIENT_STORAGE_BIT_EXT 0x0200
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000
+#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F
+#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220
+
+typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);
+
+#define glBufferStorageEXT GLEW_GET_FUN(__glewBufferStorageEXT)
+#define glNamedBufferStorageEXT GLEW_GET_FUN(__glewNamedBufferStorageEXT)
+
+#define GLEW_EXT_buffer_storage GLEW_GET_VAR(__GLEW_EXT_buffer_storage)
+
+#endif /* GL_EXT_buffer_storage */
+
+/* -------------------------- GL_EXT_clear_texture ------------------------- */
+
+#ifndef GL_EXT_clear_texture
+#define GL_EXT_clear_texture 1
+
+typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+
+#define glClearTexImageEXT GLEW_GET_FUN(__glewClearTexImageEXT)
+#define glClearTexSubImageEXT GLEW_GET_FUN(__glewClearTexSubImageEXT)
+
+#define GLEW_EXT_clear_texture GLEW_GET_VAR(__GLEW_EXT_clear_texture)
+
+#endif /* GL_EXT_clear_texture */
+
+/* ----------------------- GL_EXT_clip_cull_distance ----------------------- */
+
+#ifndef GL_EXT_clip_cull_distance
+#define GL_EXT_clip_cull_distance 1
+
+#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32
+#define GL_CLIP_DISTANCE0_EXT 0x3000
+#define GL_CLIP_DISTANCE1_EXT 0x3001
+#define GL_CLIP_DISTANCE2_EXT 0x3002
+#define GL_CLIP_DISTANCE3_EXT 0x3003
+#define GL_CLIP_DISTANCE4_EXT 0x3004
+#define GL_CLIP_DISTANCE5_EXT 0x3005
+#define GL_CLIP_DISTANCE6_EXT 0x3006
+#define GL_CLIP_DISTANCE7_EXT 0x3007
+#define GL_MAX_CULL_DISTANCES_EXT 0x82F9
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA
+
+#define GLEW_EXT_clip_cull_distance GLEW_GET_VAR(__GLEW_EXT_clip_cull_distance)
+
+#endif /* GL_EXT_clip_cull_distance */
+
+/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+
+#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint)
+
+#endif /* GL_EXT_clip_volume_hint */
+
+/* ------------------------------ GL_EXT_cmyka ----------------------------- */
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+
+#define GL_CMYK_EXT 0x800C
+#define GL_CMYKA_EXT 0x800D
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+
+#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka)
+
+#endif /* GL_EXT_cmyka */
+
+/* ----------------------- GL_EXT_color_buffer_float ----------------------- */
+
+#ifndef GL_EXT_color_buffer_float
+#define GL_EXT_color_buffer_float 1
+
+#define GLEW_EXT_color_buffer_float GLEW_GET_VAR(__GLEW_EXT_color_buffer_float)
+
+#endif /* GL_EXT_color_buffer_float */
+
+/* --------------------- GL_EXT_color_buffer_half_float -------------------- */
+
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_EXT_color_buffer_half_float 1
+
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define GL_R16F_EXT 0x822D
+#define GL_RG16F_EXT 0x822F
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17
+
+#define GLEW_EXT_color_buffer_half_float GLEW_GET_VAR(__GLEW_EXT_color_buffer_half_float)
+
+#endif /* GL_EXT_color_buffer_half_float */
+
+/* ------------------------- GL_EXT_color_subtable ------------------------- */
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+
+typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+
+#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT)
+#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT)
+
+#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable)
+
+#endif /* GL_EXT_color_subtable */
+
+/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+
+typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
+
+#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT)
+#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT)
+
+#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array)
+
+#endif /* GL_EXT_compiled_vertex_array */
+
+/* ---------------- GL_EXT_compressed_ETC1_RGB8_sub_texture ---------------- */
+
+#ifndef GL_EXT_compressed_ETC1_RGB8_sub_texture
+#define GL_EXT_compressed_ETC1_RGB8_sub_texture 1
+
+#define GLEW_EXT_compressed_ETC1_RGB8_sub_texture GLEW_GET_VAR(__GLEW_EXT_compressed_ETC1_RGB8_sub_texture)
+
+#endif /* GL_EXT_compressed_ETC1_RGB8_sub_texture */
+
+/* ----------------------- GL_EXT_conservative_depth ----------------------- */
+
+#ifndef GL_EXT_conservative_depth
+#define GL_EXT_conservative_depth 1
+
+#define GLEW_EXT_conservative_depth GLEW_GET_VAR(__GLEW_EXT_conservative_depth)
+
+#endif /* GL_EXT_conservative_depth */
+
+/* --------------------------- GL_EXT_convolution -------------------------- */
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_REDUCE_EXT 0x8016
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span);
+typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column);
+
+#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT)
+#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT)
+#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT)
+#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT)
+#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT)
+#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT)
+#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT)
+#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT)
+#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT)
+#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT)
+#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT)
+#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT)
+#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT)
+
+#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution)
+
+#endif /* GL_EXT_convolution */
+
+/* ------------------------ GL_EXT_coordinate_frame ------------------------ */
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP2_BINORMAL_EXT 0x8447
+
+typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void *pointer);
+typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void *pointer);
+
+#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT)
+#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT)
+
+#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame)
+
+#endif /* GL_EXT_coordinate_frame */
+
+/* --------------------------- GL_EXT_copy_image --------------------------- */
+
+#ifndef GL_EXT_copy_image
+#define GL_EXT_copy_image 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAEXTPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+
+#define glCopyImageSubDataEXT GLEW_GET_FUN(__glewCopyImageSubDataEXT)
+
+#define GLEW_EXT_copy_image GLEW_GET_VAR(__GLEW_EXT_copy_image)
+
+#endif /* GL_EXT_copy_image */
+
+/* -------------------------- GL_EXT_copy_texture -------------------------- */
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT)
+#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT)
+#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT)
+#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT)
+#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT)
+
+#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture)
+
+#endif /* GL_EXT_copy_texture */
+
+/* --------------------------- GL_EXT_cull_vertex -------------------------- */
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+
+typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params);
+
+#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT)
+#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT)
+
+#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex)
+
+#endif /* GL_EXT_cull_vertex */
+
+/* --------------------------- GL_EXT_debug_label -------------------------- */
+
+#ifndef GL_EXT_debug_label
+#define GL_EXT_debug_label 1
+
+#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
+#define GL_PROGRAM_OBJECT_EXT 0x8B40
+#define GL_SHADER_OBJECT_EXT 0x8B48
+#define GL_BUFFER_OBJECT_EXT 0x9151
+#define GL_QUERY_OBJECT_EXT 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
+
+typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei* length, GLchar *label);
+typedef void (GLAPIENTRY * PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar* label);
+
+#define glGetObjectLabelEXT GLEW_GET_FUN(__glewGetObjectLabelEXT)
+#define glLabelObjectEXT GLEW_GET_FUN(__glewLabelObjectEXT)
+
+#define GLEW_EXT_debug_label GLEW_GET_VAR(__GLEW_EXT_debug_label)
+
+#endif /* GL_EXT_debug_label */
+
+/* -------------------------- GL_EXT_debug_marker -------------------------- */
+
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+
+typedef void (GLAPIENTRY * PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar* marker);
+typedef void (GLAPIENTRY * PFNGLPOPGROUPMARKEREXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar* marker);
+
+#define glInsertEventMarkerEXT GLEW_GET_FUN(__glewInsertEventMarkerEXT)
+#define glPopGroupMarkerEXT GLEW_GET_FUN(__glewPopGroupMarkerEXT)
+#define glPushGroupMarkerEXT GLEW_GET_FUN(__glewPushGroupMarkerEXT)
+
+#define GLEW_EXT_debug_marker GLEW_GET_VAR(__GLEW_EXT_debug_marker)
+
+#endif /* GL_EXT_debug_marker */
+
+/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_EXT_depth_bounds_test 1
+
+#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define GL_DEPTH_BOUNDS_EXT 0x8891
+
+typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax);
+
+#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT)
+
+#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test)
+
+#endif /* GL_EXT_depth_bounds_test */
+
+/* ----------------------- GL_EXT_direct_state_access ---------------------- */
+
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+
+#define GL_PROGRAM_MATRIX_EXT 0x8E2D
+#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
+#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+
+typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture);
+typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target);
+typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);
+typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void *img);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void *img);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void** params);
+typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void** params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
+typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void** param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void** param);
+typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);
+typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f);
+typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode);
+typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode);
+typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
+typedef void (GLAPIENTRY * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param);
+typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+
+#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT)
+#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT)
+#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT)
+#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT)
+#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT)
+#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT)
+#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT)
+#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT)
+#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT)
+#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT)
+#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT)
+#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT)
+#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT)
+#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT)
+#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT)
+#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT)
+#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT)
+#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT)
+#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT)
+#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT)
+#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT)
+#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT)
+#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT)
+#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT)
+#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT)
+#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT)
+#define glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT)
+#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT)
+#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT)
+#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT)
+#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT)
+#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT)
+#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT)
+#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT)
+#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT)
+#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT)
+#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT)
+#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT)
+#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT)
+#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT)
+#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT)
+#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT)
+#define glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT)
+#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT)
+#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT)
+#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT)
+#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT)
+#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT)
+#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT)
+#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT)
+#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT)
+#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT)
+#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT)
+#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT)
+#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT)
+#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT)
+#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT)
+#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT)
+#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT)
+#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT)
+#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT)
+#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT)
+#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT)
+#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT)
+#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT)
+#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT)
+#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT)
+#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT)
+#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT)
+#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT)
+#define glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT)
+#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT)
+#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT)
+#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT)
+#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT)
+#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT)
+#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT)
+#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT)
+#define glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT)
+#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT)
+#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT)
+#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT)
+#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT)
+#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT)
+#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT)
+#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT)
+#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT)
+#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT)
+#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT)
+#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT)
+#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT)
+#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT)
+#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT)
+#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT)
+#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT)
+#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT)
+#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT)
+#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT)
+#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT)
+#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT)
+#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT)
+#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT)
+#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT)
+#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT)
+#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT)
+#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT)
+#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT)
+#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT)
+#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT)
+#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT)
+#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT)
+#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT)
+#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT)
+#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT)
+#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT)
+#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT)
+#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT)
+#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT)
+#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT)
+#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT)
+#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT)
+#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT)
+#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT)
+#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT)
+#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT)
+#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT)
+#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT)
+#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT)
+#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT)
+#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT)
+#define glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT)
+#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT)
+#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT)
+#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT)
+#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT)
+#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT)
+#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT)
+#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT)
+#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT)
+#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT)
+#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT)
+#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT)
+#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT)
+#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT)
+#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT)
+#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT)
+#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT)
+#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT)
+#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT)
+#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT)
+#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT)
+#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT)
+#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT)
+#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT)
+#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT)
+#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT)
+#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT)
+#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT)
+#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT)
+#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT)
+#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT)
+#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT)
+#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT)
+#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT)
+#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT)
+#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT)
+#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT)
+#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT)
+#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT)
+#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT)
+#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT)
+#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT)
+#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT)
+#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT)
+#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT)
+#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT)
+#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT)
+#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT)
+#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT)
+#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT)
+#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT)
+#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT)
+#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT)
+#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT)
+#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT)
+#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT)
+#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT)
+#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT)
+#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT)
+#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT)
+#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT)
+#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT)
+#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT)
+#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT)
+#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT)
+#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT)
+#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT)
+#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT)
+#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT)
+#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT)
+#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT)
+#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT)
+#define glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT)
+#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT)
+#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT)
+#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT)
+#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT)
+#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT)
+#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT)
+#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT)
+#define glVertexArrayVertexAttribDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribDivisorEXT)
+#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT)
+#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT)
+#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT)
+
+#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access)
+
+#endif /* GL_EXT_direct_state_access */
+
+/* ----------------------- GL_EXT_discard_framebuffer ---------------------- */
+
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+
+#define GL_COLOR_EXT 0x1800
+#define GL_DEPTH_EXT 0x1801
+#define GL_STENCIL_EXT 0x1802
+
+typedef void (GLAPIENTRY * PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+
+#define glDiscardFramebufferEXT GLEW_GET_FUN(__glewDiscardFramebufferEXT)
+
+#define GLEW_EXT_discard_framebuffer GLEW_GET_VAR(__GLEW_EXT_discard_framebuffer)
+
+#endif /* GL_EXT_discard_framebuffer */
+
+/* -------------------------- GL_EXT_draw_buffers -------------------------- */
+
+#ifndef GL_EXT_draw_buffers
+#define GL_EXT_draw_buffers 1
+
+#define GL_MAX_DRAW_BUFFERS_EXT 0x8824
+#define GL_DRAW_BUFFER0_EXT 0x8825
+#define GL_DRAW_BUFFER1_EXT 0x8826
+#define GL_DRAW_BUFFER2_EXT 0x8827
+#define GL_DRAW_BUFFER3_EXT 0x8828
+#define GL_DRAW_BUFFER4_EXT 0x8829
+#define GL_DRAW_BUFFER5_EXT 0x882A
+#define GL_DRAW_BUFFER6_EXT 0x882B
+#define GL_DRAW_BUFFER7_EXT 0x882C
+#define GL_DRAW_BUFFER8_EXT 0x882D
+#define GL_DRAW_BUFFER9_EXT 0x882E
+#define GL_DRAW_BUFFER10_EXT 0x882F
+#define GL_DRAW_BUFFER11_EXT 0x8830
+#define GL_DRAW_BUFFER12_EXT 0x8831
+#define GL_DRAW_BUFFER13_EXT 0x8832
+#define GL_DRAW_BUFFER14_EXT 0x8833
+#define GL_DRAW_BUFFER15_EXT 0x8834
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum* bufs);
+
+#define glDrawBuffersEXT GLEW_GET_FUN(__glewDrawBuffersEXT)
+
+#define GLEW_EXT_draw_buffers GLEW_GET_VAR(__GLEW_EXT_draw_buffers)
+
+#endif /* GL_EXT_draw_buffers */
+
+/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */
+
+#ifndef GL_EXT_draw_buffers2
+#define GL_EXT_draw_buffers2 1
+
+typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data);
+typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);
+
+#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT)
+#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT)
+#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT)
+#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT)
+#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT)
+#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT)
+
+#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2)
+
+#endif /* GL_EXT_draw_buffers2 */
+
+/* ---------------------- GL_EXT_draw_buffers_indexed ---------------------- */
+
+#ifndef GL_EXT_draw_buffers_indexed
+#define GL_EXT_draw_buffers_indexed 1
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAPIENTRY * PFNGLCOLORMASKIEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (GLAPIENTRY * PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEIEXTPROC) (GLenum target, GLuint index);
+typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index);
+
+#define glBlendEquationSeparateiEXT GLEW_GET_FUN(__glewBlendEquationSeparateiEXT)
+#define glBlendEquationiEXT GLEW_GET_FUN(__glewBlendEquationiEXT)
+#define glBlendFuncSeparateiEXT GLEW_GET_FUN(__glewBlendFuncSeparateiEXT)
+#define glBlendFunciEXT GLEW_GET_FUN(__glewBlendFunciEXT)
+#define glColorMaskiEXT GLEW_GET_FUN(__glewColorMaskiEXT)
+#define glDisableiEXT GLEW_GET_FUN(__glewDisableiEXT)
+#define glEnableiEXT GLEW_GET_FUN(__glewEnableiEXT)
+#define glIsEnablediEXT GLEW_GET_FUN(__glewIsEnablediEXT)
+
+#define GLEW_EXT_draw_buffers_indexed GLEW_GET_VAR(__GLEW_EXT_draw_buffers_indexed)
+
+#endif /* GL_EXT_draw_buffers_indexed */
+
+/* -------------------- GL_EXT_draw_elements_base_vertex ------------------- */
+
+#ifndef GL_EXT_draw_elements_base_vertex
+#define GL_EXT_draw_elements_base_vertex 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei* count, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex);
+
+#define glDrawElementsBaseVertexEXT GLEW_GET_FUN(__glewDrawElementsBaseVertexEXT)
+#define glDrawElementsInstancedBaseVertexEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexEXT)
+#define glDrawRangeElementsBaseVertexEXT GLEW_GET_FUN(__glewDrawRangeElementsBaseVertexEXT)
+#define glMultiDrawElementsBaseVertexEXT GLEW_GET_FUN(__glewMultiDrawElementsBaseVertexEXT)
+
+#define GLEW_EXT_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_EXT_draw_elements_base_vertex)
+
+#endif /* GL_EXT_draw_elements_base_vertex */
+
+/* ------------------------- GL_EXT_draw_instanced ------------------------- */
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+
+#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT)
+#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT)
+
+#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced)
+
+#endif /* GL_EXT_draw_instanced */
+
+/* ----------------------- GL_EXT_draw_range_elements ---------------------- */
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+
+#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT)
+
+#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements)
+
+#endif /* GL_EXT_draw_range_elements */
+
+/* ------------------------- GL_EXT_external_buffer ------------------------ */
+
+#ifndef GL_EXT_external_buffer
+#define GL_EXT_external_buffer 1
+
+typedef void* GLeglClientBufferEXT;
+
+typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+
+#define glBufferStorageExternalEXT GLEW_GET_FUN(__glewBufferStorageExternalEXT)
+#define glNamedBufferStorageExternalEXT GLEW_GET_FUN(__glewNamedBufferStorageExternalEXT)
+
+#define GLEW_EXT_external_buffer GLEW_GET_VAR(__GLEW_EXT_external_buffer)
+
+#endif /* GL_EXT_external_buffer */
+
+/* --------------------------- GL_EXT_float_blend -------------------------- */
+
+#ifndef GL_EXT_float_blend
+#define GL_EXT_float_blend 1
+
+#define GLEW_EXT_float_blend GLEW_GET_VAR(__GLEW_EXT_float_blend)
+
+#endif /* GL_EXT_float_blend */
+
+/* ---------------------------- GL_EXT_fog_coord --------------------------- */
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+
+typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+
+#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT)
+#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT)
+#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT)
+#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT)
+#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT)
+
+#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord)
+
+#endif /* GL_EXT_fog_coord */
+
+/* --------------------------- GL_EXT_frag_depth --------------------------- */
+
+#ifndef GL_EXT_frag_depth
+#define GL_EXT_frag_depth 1
+
+#define GLEW_EXT_frag_depth GLEW_GET_VAR(__GLEW_EXT_frag_depth)
+
+#endif /* GL_EXT_frag_depth */
+
+/* ------------------------ GL_EXT_fragment_lighting ----------------------- */
+
+#ifndef GL_EXT_fragment_lighting
+#define GL_EXT_fragment_lighting 1
+
+#define GL_FRAGMENT_LIGHTING_EXT 0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404
+#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405
+#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406
+#define GL_LIGHT_ENV_MODE_EXT 0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B
+#define GL_FRAGMENT_LIGHT0_EXT 0x840C
+#define GL_FRAGMENT_LIGHT7_EXT 0x8413
+
+typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param);
+
+#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT)
+#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT)
+#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT)
+#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT)
+#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT)
+#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT)
+#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT)
+#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT)
+#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT)
+#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT)
+#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT)
+#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT)
+#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT)
+#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT)
+#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT)
+#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT)
+#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT)
+#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT)
+
+#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting)
+
+#endif /* GL_EXT_fragment_lighting */
+
+/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_EXT_framebuffer_blit 1
+
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
+
+typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+
+#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT)
+
+#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit)
+
+#endif /* GL_EXT_framebuffer_blit */
+
+/* --------------------- GL_EXT_framebuffer_multisample -------------------- */
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT)
+
+#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample)
+
+#endif /* GL_EXT_framebuffer_multisample */
+
+/* --------------- GL_EXT_framebuffer_multisample_blit_scaled -------------- */
+
+#ifndef GL_EXT_framebuffer_multisample_blit_scaled
+#define GL_EXT_framebuffer_multisample_blit_scaled 1
+
+#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
+#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB
+
+#define GLEW_EXT_framebuffer_multisample_blit_scaled GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample_blit_scaled)
+
+#endif /* GL_EXT_framebuffer_multisample_blit_scaled */
+
+/* ----------------------- GL_EXT_framebuffer_object ----------------------- */
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_EXT_framebuffer_object 1
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_STENCIL_INDEX1_EXT 0x8D46
+#define GL_STENCIL_INDEX4_EXT 0x8D47
+#define GL_STENCIL_INDEX8_EXT 0x8D48
+#define GL_STENCIL_INDEX16_EXT 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
+typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT)
+#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT)
+#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT)
+#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT)
+#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT)
+#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT)
+#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT)
+#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT)
+#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT)
+#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT)
+#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT)
+#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT)
+#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT)
+#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT)
+#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT)
+#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT)
+#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT)
+
+#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object)
+
+#endif /* GL_EXT_framebuffer_object */
+
+/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_EXT_framebuffer_sRGB 1
+
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+
+#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB)
+
+#endif /* GL_EXT_framebuffer_sRGB */
+
+/* ----------------------- GL_EXT_geometry_point_size ---------------------- */
+
+#ifndef GL_EXT_geometry_point_size
+#define GL_EXT_geometry_point_size 1
+
+#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004
+#define GL_LINES_ADJACENCY_EXT 0xA
+#define GL_LINE_STRIP_ADJACENCY_EXT 0xB
+#define GL_TRIANGLES_ADJACENCY_EXT 0xC
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD
+#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E
+#define GL_UNDEFINED_VERTEX_EXT 0x8260
+#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317
+
+#define GLEW_EXT_geometry_point_size GLEW_GET_VAR(__GLEW_EXT_geometry_point_size)
+
+#endif /* GL_EXT_geometry_point_size */
+
+/* ------------------------- GL_EXT_geometry_shader ------------------------ */
+
+#ifndef GL_EXT_geometry_shader
+#define GL_EXT_geometry_shader 1
+
+#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004
+#define GL_LINES_ADJACENCY_EXT 0xA
+#define GL_LINE_STRIP_ADJACENCY_EXT 0xB
+#define GL_TRIANGLES_ADJACENCY_EXT 0xC
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD
+#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E
+#define GL_UNDEFINED_VERTEX_EXT 0x8260
+#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317
+
+#define GLEW_EXT_geometry_shader GLEW_GET_VAR(__GLEW_EXT_geometry_shader)
+
+#endif /* GL_EXT_geometry_shader */
+
+/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_EXT_geometry_shader4 1
+
+#define GL_LINES_ADJACENCY_EXT 0xA
+#define GL_LINE_STRIP_ADJACENCY_EXT 0xB
+#define GL_TRIANGLES_ADJACENCY_EXT 0xC
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD
+#define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+
+#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT)
+#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT)
+#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT)
+
+#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4)
+
+#endif /* GL_EXT_geometry_shader4 */
+
+/* --------------------- GL_EXT_gpu_program_parameters --------------------- */
+
+#ifndef GL_EXT_gpu_program_parameters
+#define GL_EXT_gpu_program_parameters 1
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params);
+
+#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT)
+#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT)
+
+#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters)
+
+#endif /* GL_EXT_gpu_program_parameters */
+
+/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_EXT_gpu_shader4 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD
+#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+
+#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT)
+#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT)
+#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT)
+#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT)
+#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT)
+#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT)
+#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT)
+#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT)
+#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT)
+#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT)
+#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT)
+#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT)
+#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT)
+#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT)
+#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT)
+#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT)
+#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT)
+#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT)
+#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT)
+#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT)
+#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT)
+#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT)
+#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT)
+#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT)
+#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT)
+#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT)
+#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT)
+#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT)
+#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT)
+#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT)
+#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT)
+#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT)
+#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT)
+#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT)
+
+#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4)
+
+#endif /* GL_EXT_gpu_shader4 */
+
+/* --------------------------- GL_EXT_gpu_shader5 -------------------------- */
+
+#ifndef GL_EXT_gpu_shader5
+#define GL_EXT_gpu_shader5 1
+
+#define GLEW_EXT_gpu_shader5 GLEW_GET_VAR(__GLEW_EXT_gpu_shader5)
+
+#endif /* GL_EXT_gpu_shader5 */
+
+/* ---------------------------- GL_EXT_histogram --------------------------- */
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK_EXT 0x8030
+
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target);
+
+#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT)
+#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT)
+#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT)
+#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT)
+#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT)
+#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT)
+#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT)
+#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT)
+#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT)
+#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT)
+
+#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram)
+
+#endif /* GL_EXT_histogram */
+
+/* ----------------------- GL_EXT_index_array_formats ---------------------- */
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+
+#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats)
+
+#endif /* GL_EXT_index_array_formats */
+
+/* --------------------------- GL_EXT_index_func --------------------------- */
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+
+typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref);
+
+#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT)
+
+#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func)
+
+#endif /* GL_EXT_index_func */
+
+/* ------------------------- GL_EXT_index_material ------------------------- */
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+
+typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+
+#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT)
+
+#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material)
+
+#endif /* GL_EXT_index_material */
+
+/* -------------------------- GL_EXT_index_texture ------------------------- */
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+
+#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture)
+
+#endif /* GL_EXT_index_texture */
+
+/* ------------------------ GL_EXT_instanced_arrays ------------------------ */
+
+#ifndef GL_EXT_instanced_arrays
+#define GL_EXT_instanced_arrays 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE
+
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor);
+
+#define glVertexAttribDivisorEXT GLEW_GET_FUN(__glewVertexAttribDivisorEXT)
+
+#define GLEW_EXT_instanced_arrays GLEW_GET_VAR(__GLEW_EXT_instanced_arrays)
+
+#endif /* GL_EXT_instanced_arrays */
+
+/* -------------------------- GL_EXT_light_texture ------------------------- */
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+
+typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+
+#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT)
+#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT)
+#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT)
+
+#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture)
+
+#endif /* GL_EXT_light_texture */
+
+/* ------------------------ GL_EXT_map_buffer_range ------------------------ */
+
+#ifndef GL_EXT_map_buffer_range
+#define GL_EXT_map_buffer_range 1
+
+#define GL_MAP_READ_BIT_EXT 0x0001
+#define GL_MAP_WRITE_BIT_EXT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020
+
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+typedef void * (GLAPIENTRY * PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+
+#define glFlushMappedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedBufferRangeEXT)
+#define glMapBufferRangeEXT GLEW_GET_FUN(__glewMapBufferRangeEXT)
+
+#define GLEW_EXT_map_buffer_range GLEW_GET_VAR(__GLEW_EXT_map_buffer_range)
+
+#endif /* GL_EXT_map_buffer_range */
+
+/* -------------------------- GL_EXT_memory_object ------------------------- */
+
+#ifndef GL_EXT_memory_object
+#define GL_EXT_memory_object 1
+
+#define GL_UUID_SIZE_EXT 16
+#define GL_TEXTURE_TILING_EXT 0x9580
+#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581
+#define GL_NUM_TILING_TYPES_EXT 0x9582
+#define GL_TILING_TYPES_EXT 0x9583
+#define GL_OPTIMAL_TILING_EXT 0x9584
+#define GL_LINEAR_TILING_EXT 0x9585
+#define GL_LAYOUT_GENERAL_EXT 0x958D
+#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E
+#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F
+#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590
+#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591
+#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592
+#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593
+#define GL_NUM_DEVICE_UUIDS_EXT 0x9596
+#define GL_DEVICE_UUID_EXT 0x9597
+#define GL_DRIVER_UUID_EXT 0x9598
+#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B
+
+typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint* memoryObjects);
+typedef void (GLAPIENTRY * PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint* memoryObjects);
+typedef void (GLAPIENTRY * PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte* data);
+typedef void (GLAPIENTRY * PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte* data);
+typedef GLboolean (GLAPIENTRY * PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject);
+typedef void (GLAPIENTRY * PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM1DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+
+#define glBufferStorageMemEXT GLEW_GET_FUN(__glewBufferStorageMemEXT)
+#define glCreateMemoryObjectsEXT GLEW_GET_FUN(__glewCreateMemoryObjectsEXT)
+#define glDeleteMemoryObjectsEXT GLEW_GET_FUN(__glewDeleteMemoryObjectsEXT)
+#define glGetMemoryObjectParameterivEXT GLEW_GET_FUN(__glewGetMemoryObjectParameterivEXT)
+#define glGetUnsignedBytei_vEXT GLEW_GET_FUN(__glewGetUnsignedBytei_vEXT)
+#define glGetUnsignedBytevEXT GLEW_GET_FUN(__glewGetUnsignedBytevEXT)
+#define glIsMemoryObjectEXT GLEW_GET_FUN(__glewIsMemoryObjectEXT)
+#define glMemoryObjectParameterivEXT GLEW_GET_FUN(__glewMemoryObjectParameterivEXT)
+#define glNamedBufferStorageMemEXT GLEW_GET_FUN(__glewNamedBufferStorageMemEXT)
+#define glTexStorageMem1DEXT GLEW_GET_FUN(__glewTexStorageMem1DEXT)
+#define glTexStorageMem2DEXT GLEW_GET_FUN(__glewTexStorageMem2DEXT)
+#define glTexStorageMem2DMultisampleEXT GLEW_GET_FUN(__glewTexStorageMem2DMultisampleEXT)
+#define glTexStorageMem3DEXT GLEW_GET_FUN(__glewTexStorageMem3DEXT)
+#define glTexStorageMem3DMultisampleEXT GLEW_GET_FUN(__glewTexStorageMem3DMultisampleEXT)
+#define glTextureStorageMem1DEXT GLEW_GET_FUN(__glewTextureStorageMem1DEXT)
+#define glTextureStorageMem2DEXT GLEW_GET_FUN(__glewTextureStorageMem2DEXT)
+#define glTextureStorageMem2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorageMem2DMultisampleEXT)
+#define glTextureStorageMem3DEXT GLEW_GET_FUN(__glewTextureStorageMem3DEXT)
+#define glTextureStorageMem3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorageMem3DMultisampleEXT)
+
+#define GLEW_EXT_memory_object GLEW_GET_VAR(__GLEW_EXT_memory_object)
+
+#endif /* GL_EXT_memory_object */
+
+/* ------------------------ GL_EXT_memory_object_fd ------------------------ */
+
+#ifndef GL_EXT_memory_object_fd
+#define GL_EXT_memory_object_fd 1
+
+#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586
+
+typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+
+#define glImportMemoryFdEXT GLEW_GET_FUN(__glewImportMemoryFdEXT)
+
+#define GLEW_EXT_memory_object_fd GLEW_GET_VAR(__GLEW_EXT_memory_object_fd)
+
+#endif /* GL_EXT_memory_object_fd */
+
+/* ----------------------- GL_EXT_memory_object_win32 ---------------------- */
+
+#ifndef GL_EXT_memory_object_win32
+#define GL_EXT_memory_object_win32 1
+
+#define GL_LUID_SIZE_EXT 8
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588
+#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589
+#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A
+#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B
+#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C
+#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594
+#define GL_D3D12_FENCE_VALUE_EXT 0x9595
+#define GL_DEVICE_LUID_EXT 0x9599
+#define GL_DEVICE_NODE_MASK_EXT 0x959A
+
+typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+
+#define glImportMemoryWin32HandleEXT GLEW_GET_FUN(__glewImportMemoryWin32HandleEXT)
+#define glImportMemoryWin32NameEXT GLEW_GET_FUN(__glewImportMemoryWin32NameEXT)
+
+#define GLEW_EXT_memory_object_win32 GLEW_GET_VAR(__GLEW_EXT_memory_object_win32)
+
+#endif /* GL_EXT_memory_object_win32 */
+
+/* ------------------------- GL_EXT_misc_attribute ------------------------- */
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+
+#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute)
+
+#endif /* GL_EXT_misc_attribute */
+
+/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const void *const *indices, GLsizei primcount);
+
+#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT)
+#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT)
+
+#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays)
+
+#endif /* GL_EXT_multi_draw_arrays */
+
+/* ----------------------- GL_EXT_multi_draw_indirect ---------------------- */
+
+#ifndef GL_EXT_multi_draw_indirect
+#define GL_EXT_multi_draw_indirect 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+
+#define glMultiDrawArraysIndirectEXT GLEW_GET_FUN(__glewMultiDrawArraysIndirectEXT)
+#define glMultiDrawElementsIndirectEXT GLEW_GET_FUN(__glewMultiDrawElementsIndirectEXT)
+
+#define GLEW_EXT_multi_draw_indirect GLEW_GET_VAR(__GLEW_EXT_multi_draw_indirect)
+
+#endif /* GL_EXT_multi_draw_indirect */
+
+/* ------------------------ GL_EXT_multiple_textures ----------------------- */
+
+#ifndef GL_EXT_multiple_textures
+#define GL_EXT_multiple_textures 1
+
+#define GLEW_EXT_multiple_textures GLEW_GET_VAR(__GLEW_EXT_multiple_textures)
+
+#endif /* GL_EXT_multiple_textures */
+
+/* --------------------------- GL_EXT_multisample -------------------------- */
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_1PASS_EXT 0x80A1
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#define GL_MULTISAMPLE_BIT_EXT 0x20000000
+
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+
+#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT)
+#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT)
+
+#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample)
+
+#endif /* GL_EXT_multisample */
+
+/* -------------------- GL_EXT_multisample_compatibility ------------------- */
+
+#ifndef GL_EXT_multisample_compatibility
+#define GL_EXT_multisample_compatibility 1
+
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+
+#define GLEW_EXT_multisample_compatibility GLEW_GET_VAR(__GLEW_EXT_multisample_compatibility)
+
+#endif /* GL_EXT_multisample_compatibility */
+
+/* ----------------- GL_EXT_multisampled_render_to_texture ----------------- */
+
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+
+#define glFramebufferTexture2DMultisampleEXT GLEW_GET_FUN(__glewFramebufferTexture2DMultisampleEXT)
+
+#define GLEW_EXT_multisampled_render_to_texture GLEW_GET_VAR(__GLEW_EXT_multisampled_render_to_texture)
+
+#endif /* GL_EXT_multisampled_render_to_texture */
+
+/* ----------------- GL_EXT_multisampled_render_to_texture2 ---------------- */
+
+#ifndef GL_EXT_multisampled_render_to_texture2
+#define GL_EXT_multisampled_render_to_texture2 1
+
+#define GLEW_EXT_multisampled_render_to_texture2 GLEW_GET_VAR(__GLEW_EXT_multisampled_render_to_texture2)
+
+#endif /* GL_EXT_multisampled_render_to_texture2 */
+
+/* --------------------- GL_EXT_multiview_draw_buffers --------------------- */
+
+#ifndef GL_EXT_multiview_draw_buffers
+#define GL_EXT_multiview_draw_buffers 1
+
+#define GL_DRAW_BUFFER_EXT 0x0C01
+#define GL_READ_BUFFER_EXT 0x0C02
+#define GL_COLOR_ATTACHMENT_EXT 0x90F0
+#define GL_MULTIVIEW_EXT 0x90F1
+#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2
+
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum* location, const GLint *indices);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint* data);
+typedef void (GLAPIENTRY * PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index);
+
+#define glDrawBuffersIndexedEXT GLEW_GET_FUN(__glewDrawBuffersIndexedEXT)
+#define glGetIntegeri_vEXT GLEW_GET_FUN(__glewGetIntegeri_vEXT)
+#define glReadBufferIndexedEXT GLEW_GET_FUN(__glewReadBufferIndexedEXT)
+
+#define GLEW_EXT_multiview_draw_buffers GLEW_GET_VAR(__GLEW_EXT_multiview_draw_buffers)
+
+#endif /* GL_EXT_multiview_draw_buffers */
+
+/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+
+#define GL_DEPTH_STENCIL_EXT 0x84F9
+#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+
+#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil)
+
+#endif /* GL_EXT_packed_depth_stencil */
+
+/* -------------------------- GL_EXT_packed_float -------------------------- */
+
+#ifndef GL_EXT_packed_float
+#define GL_EXT_packed_float 1
+
+#define GL_R11F_G11F_B10F_EXT 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+
+#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float)
+
+#endif /* GL_EXT_packed_float */
+
+/* -------------------------- GL_EXT_packed_pixels ------------------------- */
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+
+#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels)
+
+#endif /* GL_EXT_packed_pixels */
+
+/* ------------------------ GL_EXT_paletted_texture ------------------------ */
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8
+#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *data);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+
+#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT)
+#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT)
+#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT)
+#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT)
+
+#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture)
+
+#endif /* GL_EXT_paletted_texture */
+
+/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_EXT_pixel_buffer_object 1
+
+#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+
+#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object)
+
+#endif /* GL_EXT_pixel_buffer_object */
+
+/* ------------------------- GL_EXT_pixel_transform ------------------------ */
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_CUBIC_EXT 0x8334
+#define GL_AVERAGE_EXT 0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+
+typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params);
+
+#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT)
+#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT)
+#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT)
+#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT)
+#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT)
+#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT)
+
+#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform)
+
+#endif /* GL_EXT_pixel_transform */
+
+/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+
+#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table)
+
+#endif /* GL_EXT_pixel_transform_color_table */
+
+/* ------------------------ GL_EXT_point_parameters ------------------------ */
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat* params);
+
+#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT)
+#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT)
+
+#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters)
+
+#endif /* GL_EXT_point_parameters */
+
+/* ------------------------- GL_EXT_polygon_offset ------------------------- */
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+
+typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+
+#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT)
+
+#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset)
+
+#endif /* GL_EXT_polygon_offset */
+
+/* ---------------------- GL_EXT_polygon_offset_clamp ---------------------- */
+
+#ifndef GL_EXT_polygon_offset_clamp
+#define GL_EXT_polygon_offset_clamp 1
+
+#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B
+
+typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp);
+
+#define glPolygonOffsetClampEXT GLEW_GET_FUN(__glewPolygonOffsetClampEXT)
+
+#define GLEW_EXT_polygon_offset_clamp GLEW_GET_VAR(__GLEW_EXT_polygon_offset_clamp)
+
+#endif /* GL_EXT_polygon_offset_clamp */
+
+/* ----------------------- GL_EXT_post_depth_coverage ---------------------- */
+
+#ifndef GL_EXT_post_depth_coverage
+#define GL_EXT_post_depth_coverage 1
+
+#define GLEW_EXT_post_depth_coverage GLEW_GET_VAR(__GLEW_EXT_post_depth_coverage)
+
+#endif /* GL_EXT_post_depth_coverage */
+
+/* ------------------------ GL_EXT_provoking_vertex ------------------------ */
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_PROVOKING_VERTEX_EXT 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
+
+#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT)
+
+#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex)
+
+#endif /* GL_EXT_provoking_vertex */
+
+/* --------------------------- GL_EXT_pvrtc_sRGB --------------------------- */
+
+#ifndef GL_EXT_pvrtc_sRGB
+#define GL_EXT_pvrtc_sRGB 1
+
+#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
+#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
+
+#define GLEW_EXT_pvrtc_sRGB GLEW_GET_VAR(__GLEW_EXT_pvrtc_sRGB)
+
+#endif /* GL_EXT_pvrtc_sRGB */
+
+/* ----------------------- GL_EXT_raster_multisample ----------------------- */
+
+#ifndef GL_EXT_raster_multisample
+#define GL_EXT_raster_multisample 1
+
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#define GL_RASTER_MULTISAMPLE_EXT 0x9327
+#define GL_RASTER_SAMPLES_EXT 0x9328
+#define GL_MAX_RASTER_SAMPLES_EXT 0x9329
+#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A
+#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B
+#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C
+#define GL_DEPTH_SAMPLES_NV 0x932D
+#define GL_STENCIL_SAMPLES_NV 0x932E
+#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F
+#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330
+#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331
+#define GL_COVERAGE_MODULATION_NV 0x9332
+#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333
+
+typedef void (GLAPIENTRY * PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components);
+typedef void (GLAPIENTRY * PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations);
+
+#define glCoverageModulationNV GLEW_GET_FUN(__glewCoverageModulationNV)
+#define glCoverageModulationTableNV GLEW_GET_FUN(__glewCoverageModulationTableNV)
+#define glGetCoverageModulationTableNV GLEW_GET_FUN(__glewGetCoverageModulationTableNV)
+#define glRasterSamplesEXT GLEW_GET_FUN(__glewRasterSamplesEXT)
+
+#define GLEW_EXT_raster_multisample GLEW_GET_VAR(__GLEW_EXT_raster_multisample)
+
+#endif /* GL_EXT_raster_multisample */
+
+/* ------------------------ GL_EXT_read_format_bgra ------------------------ */
+
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+
+#define GL_BGRA_EXT 0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+
+#define GLEW_EXT_read_format_bgra GLEW_GET_VAR(__GLEW_EXT_read_format_bgra)
+
+#endif /* GL_EXT_read_format_bgra */
+
+/* -------------------------- GL_EXT_render_snorm -------------------------- */
+
+#ifndef GL_EXT_render_snorm
+#define GL_EXT_render_snorm 1
+
+#define GL_BYTE 0x1400
+#define GL_SHORT 0x1402
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM_EXT 0x8F98
+#define GL_RG16_SNORM_EXT 0x8F99
+#define GL_RGBA16_SNORM_EXT 0x8F9B
+
+#define GLEW_EXT_render_snorm GLEW_GET_VAR(__GLEW_EXT_render_snorm)
+
+#endif /* GL_EXT_render_snorm */
+
+/* ------------------------- GL_EXT_rescale_normal ------------------------- */
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+
+#define GL_RESCALE_NORMAL_EXT 0x803A
+
+#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal)
+
+#endif /* GL_EXT_rescale_normal */
+
+/* ------------------------------ GL_EXT_sRGB ------------------------------ */
+
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+
+#define GLEW_EXT_sRGB GLEW_GET_VAR(__GLEW_EXT_sRGB)
+
+#endif /* GL_EXT_sRGB */
+
+/* ----------------------- GL_EXT_sRGB_write_control ----------------------- */
+
+#ifndef GL_EXT_sRGB_write_control
+#define GL_EXT_sRGB_write_control 1
+
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+
+#define GLEW_EXT_sRGB_write_control GLEW_GET_VAR(__GLEW_EXT_sRGB_write_control)
+
+#endif /* GL_EXT_sRGB_write_control */
+
+/* -------------------------- GL_EXT_scene_marker -------------------------- */
+
+#ifndef GL_EXT_scene_marker
+#define GL_EXT_scene_marker 1
+
+typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void);
+
+#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT)
+#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT)
+
+#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker)
+
+#endif /* GL_EXT_scene_marker */
+
+/* ------------------------- GL_EXT_secondary_color ------------------------ */
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer);
+
+#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT)
+#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT)
+#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT)
+#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT)
+#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT)
+#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT)
+#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT)
+#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT)
+#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT)
+#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT)
+#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT)
+#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT)
+#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT)
+#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT)
+#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT)
+#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT)
+#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT)
+
+#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color)
+
+#endif /* GL_EXT_secondary_color */
+
+/* ---------------------------- GL_EXT_semaphore --------------------------- */
+
+#ifndef GL_EXT_semaphore
+#define GL_EXT_semaphore 1
+
+typedef void (GLAPIENTRY * PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint* semaphores);
+typedef void (GLAPIENTRY * PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint* semaphores);
+typedef void (GLAPIENTRY * PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore);
+typedef void (GLAPIENTRY * PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint* buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+typedef void (GLAPIENTRY * PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint* buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+
+#define glDeleteSemaphoresEXT GLEW_GET_FUN(__glewDeleteSemaphoresEXT)
+#define glGenSemaphoresEXT GLEW_GET_FUN(__glewGenSemaphoresEXT)
+#define glGetSemaphoreParameterui64vEXT GLEW_GET_FUN(__glewGetSemaphoreParameterui64vEXT)
+#define glIsSemaphoreEXT GLEW_GET_FUN(__glewIsSemaphoreEXT)
+#define glSemaphoreParameterui64vEXT GLEW_GET_FUN(__glewSemaphoreParameterui64vEXT)
+#define glSignalSemaphoreEXT GLEW_GET_FUN(__glewSignalSemaphoreEXT)
+#define glWaitSemaphoreEXT GLEW_GET_FUN(__glewWaitSemaphoreEXT)
+
+#define GLEW_EXT_semaphore GLEW_GET_VAR(__GLEW_EXT_semaphore)
+
+#endif /* GL_EXT_semaphore */
+
+/* -------------------------- GL_EXT_semaphore_fd -------------------------- */
+
+#ifndef GL_EXT_semaphore_fd
+#define GL_EXT_semaphore_fd 1
+
+typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd);
+
+#define glImportSemaphoreFdEXT GLEW_GET_FUN(__glewImportSemaphoreFdEXT)
+
+#define GLEW_EXT_semaphore_fd GLEW_GET_VAR(__GLEW_EXT_semaphore_fd)
+
+#endif /* GL_EXT_semaphore_fd */
+
+/* ------------------------- GL_EXT_semaphore_win32 ------------------------ */
+
+#ifndef GL_EXT_semaphore_win32
+#define GL_EXT_semaphore_win32 1
+
+typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle);
+typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name);
+
+#define glImportSemaphoreWin32HandleEXT GLEW_GET_FUN(__glewImportSemaphoreWin32HandleEXT)
+#define glImportSemaphoreWin32NameEXT GLEW_GET_FUN(__glewImportSemaphoreWin32NameEXT)
+
+#define GLEW_EXT_semaphore_win32 GLEW_GET_VAR(__GLEW_EXT_semaphore_win32)
+
+#endif /* GL_EXT_semaphore_win32 */
+
+/* --------------------- GL_EXT_separate_shader_objects -------------------- */
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+
+#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
+
+typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
+typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar* string);
+typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
+
+#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT)
+#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT)
+#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT)
+
+#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects)
+
+#endif /* GL_EXT_separate_shader_objects */
+
+/* --------------------- GL_EXT_separate_specular_color -------------------- */
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+
+#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color)
+
+#endif /* GL_EXT_separate_specular_color */
+
+/* -------------------- GL_EXT_shader_framebuffer_fetch -------------------- */
+
+#ifndef GL_EXT_shader_framebuffer_fetch
+#define GL_EXT_shader_framebuffer_fetch 1
+
+#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+
+#define GLEW_EXT_shader_framebuffer_fetch GLEW_GET_VAR(__GLEW_EXT_shader_framebuffer_fetch)
+
+#endif /* GL_EXT_shader_framebuffer_fetch */
+
+/* ------------------------ GL_EXT_shader_group_vote ----------------------- */
+
+#ifndef GL_EXT_shader_group_vote
+#define GL_EXT_shader_group_vote 1
+
+#define GLEW_EXT_shader_group_vote GLEW_GET_VAR(__GLEW_EXT_shader_group_vote)
+
+#endif /* GL_EXT_shader_group_vote */
+
+/* ------------------- GL_EXT_shader_image_load_formatted ------------------ */
+
+#ifndef GL_EXT_shader_image_load_formatted
+#define GL_EXT_shader_image_load_formatted 1
+
+#define GLEW_EXT_shader_image_load_formatted GLEW_GET_VAR(__GLEW_EXT_shader_image_load_formatted)
+
+#endif /* GL_EXT_shader_image_load_formatted */
+
+/* --------------------- GL_EXT_shader_image_load_store -------------------- */
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_EXT_shader_image_load_store 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define GL_MAX_IMAGE_UNITS_EXT 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
+#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
+#define GL_IMAGE_1D_EXT 0x904C
+#define GL_IMAGE_2D_EXT 0x904D
+#define GL_IMAGE_3D_EXT 0x904E
+#define GL_IMAGE_2D_RECT_EXT 0x904F
+#define GL_IMAGE_CUBE_EXT 0x9050
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_IMAGE_1D_ARRAY_EXT 0x9052
+#define GL_IMAGE_2D_ARRAY_EXT 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define GL_INT_IMAGE_1D_EXT 0x9057
+#define GL_INT_IMAGE_2D_EXT 0x9058
+#define GL_INT_IMAGE_3D_EXT 0x9059
+#define GL_INT_IMAGE_2D_RECT_EXT 0x905A
+#define GL_INT_IMAGE_CUBE_EXT 0x905B
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
+#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D
+#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E
+#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+typedef void (GLAPIENTRY * PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers);
+
+#define glBindImageTextureEXT GLEW_GET_FUN(__glewBindImageTextureEXT)
+#define glMemoryBarrierEXT GLEW_GET_FUN(__glewMemoryBarrierEXT)
+
+#define GLEW_EXT_shader_image_load_store GLEW_GET_VAR(__GLEW_EXT_shader_image_load_store)
+
+#endif /* GL_EXT_shader_image_load_store */
+
+/* ------------------- GL_EXT_shader_implicit_conversions ------------------ */
+
+#ifndef GL_EXT_shader_implicit_conversions
+#define GL_EXT_shader_implicit_conversions 1
+
+#define GLEW_EXT_shader_implicit_conversions GLEW_GET_VAR(__GLEW_EXT_shader_implicit_conversions)
+
+#endif /* GL_EXT_shader_implicit_conversions */
+
+/* ----------------------- GL_EXT_shader_integer_mix ----------------------- */
+
+#ifndef GL_EXT_shader_integer_mix
+#define GL_EXT_shader_integer_mix 1
+
+#define GLEW_EXT_shader_integer_mix GLEW_GET_VAR(__GLEW_EXT_shader_integer_mix)
+
+#endif /* GL_EXT_shader_integer_mix */
+
+/* ------------------------ GL_EXT_shader_io_blocks ------------------------ */
+
+#ifndef GL_EXT_shader_io_blocks
+#define GL_EXT_shader_io_blocks 1
+
+#define GLEW_EXT_shader_io_blocks GLEW_GET_VAR(__GLEW_EXT_shader_io_blocks)
+
+#endif /* GL_EXT_shader_io_blocks */
+
+/* ------------- GL_EXT_shader_non_constant_global_initializers ------------ */
+
+#ifndef GL_EXT_shader_non_constant_global_initializers
+#define GL_EXT_shader_non_constant_global_initializers 1
+
+#define GLEW_EXT_shader_non_constant_global_initializers GLEW_GET_VAR(__GLEW_EXT_shader_non_constant_global_initializers)
+
+#endif /* GL_EXT_shader_non_constant_global_initializers */
+
+/* ------------------- GL_EXT_shader_pixel_local_storage ------------------- */
+
+#ifndef GL_EXT_shader_pixel_local_storage
+#define GL_EXT_shader_pixel_local_storage 1
+
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
+#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67
+
+#define GLEW_EXT_shader_pixel_local_storage GLEW_GET_VAR(__GLEW_EXT_shader_pixel_local_storage)
+
+#endif /* GL_EXT_shader_pixel_local_storage */
+
+/* ------------------- GL_EXT_shader_pixel_local_storage2 ------------------ */
+
+#ifndef GL_EXT_shader_pixel_local_storage2
+#define GL_EXT_shader_pixel_local_storage2 1
+
+#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650
+#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651
+#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652
+
+typedef void (GLAPIENTRY * PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) (GLsizei offset, GLsizei n, const GLuint* values);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target, GLsizei size);
+typedef GLsizei (GLAPIENTRY * PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target);
+
+#define glClearPixelLocalStorageuiEXT GLEW_GET_FUN(__glewClearPixelLocalStorageuiEXT)
+#define glFramebufferPixelLocalStorageSizeEXT GLEW_GET_FUN(__glewFramebufferPixelLocalStorageSizeEXT)
+#define glGetFramebufferPixelLocalStorageSizeEXT GLEW_GET_FUN(__glewGetFramebufferPixelLocalStorageSizeEXT)
+
+#define GLEW_EXT_shader_pixel_local_storage2 GLEW_GET_VAR(__GLEW_EXT_shader_pixel_local_storage2)
+
+#endif /* GL_EXT_shader_pixel_local_storage2 */
+
+/* ----------------------- GL_EXT_shader_texture_lod ----------------------- */
+
+#ifndef GL_EXT_shader_texture_lod
+#define GL_EXT_shader_texture_lod 1
+
+#define GLEW_EXT_shader_texture_lod GLEW_GET_VAR(__GLEW_EXT_shader_texture_lod)
+
+#endif /* GL_EXT_shader_texture_lod */
+
+/* -------------------------- GL_EXT_shadow_funcs -------------------------- */
+
+#ifndef GL_EXT_shadow_funcs
+#define GL_EXT_shadow_funcs 1
+
+#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs)
+
+#endif /* GL_EXT_shadow_funcs */
+
+/* ------------------------- GL_EXT_shadow_samplers ------------------------ */
+
+#ifndef GL_EXT_shadow_samplers
+#define GL_EXT_shadow_samplers 1
+
+#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D
+#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E
+#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62
+
+#define GLEW_EXT_shadow_samplers GLEW_GET_VAR(__GLEW_EXT_shadow_samplers)
+
+#endif /* GL_EXT_shadow_samplers */
+
+/* --------------------- GL_EXT_shared_texture_palette --------------------- */
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+
+#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette)
+
+#endif /* GL_EXT_shared_texture_palette */
+
+/* ------------------------- GL_EXT_sparse_texture ------------------------- */
+
+#ifndef GL_EXT_sparse_texture
+#define GL_EXT_sparse_texture 1
+
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009
+#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197
+#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A
+#define GL_TEXTURE_SPARSE_EXT 0x91A6
+#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7
+#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8
+#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9
+#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA
+
+typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+
+#define glTexPageCommitmentEXT GLEW_GET_FUN(__glewTexPageCommitmentEXT)
+#define glTexturePageCommitmentEXT GLEW_GET_FUN(__glewTexturePageCommitmentEXT)
+
+#define GLEW_EXT_sparse_texture GLEW_GET_VAR(__GLEW_EXT_sparse_texture)
+
+#endif /* GL_EXT_sparse_texture */
+
+/* ------------------------- GL_EXT_sparse_texture2 ------------------------ */
+
+#ifndef GL_EXT_sparse_texture2
+#define GL_EXT_sparse_texture2 1
+
+#define GLEW_EXT_sparse_texture2 GLEW_GET_VAR(__GLEW_EXT_sparse_texture2)
+
+#endif /* GL_EXT_sparse_texture2 */
+
+/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_EXT_stencil_clear_tag 1
+
+#define GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+
+#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag)
+
+#endif /* GL_EXT_stencil_clear_tag */
+
+/* ------------------------ GL_EXT_stencil_two_side ------------------------ */
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_EXT_stencil_two_side 1
+
+#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+
+typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
+
+#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT)
+
+#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side)
+
+#endif /* GL_EXT_stencil_two_side */
+
+/* -------------------------- GL_EXT_stencil_wrap -------------------------- */
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_DECR_WRAP_EXT 0x8508
+
+#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap)
+
+#endif /* GL_EXT_stencil_wrap */
+
+/* --------------------------- GL_EXT_subtexture --------------------------- */
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+
+#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT)
+#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT)
+#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT)
+
+#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture)
+
+#endif /* GL_EXT_subtexture */
+
+/* ----------------------------- GL_EXT_texture ---------------------------- */
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16_EXT 0x803E
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16_EXT 0x805B
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_REPLACE_EXT 0x8062
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+
+#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture)
+
+#endif /* GL_EXT_texture */
+
+/* ---------------------------- GL_EXT_texture3D --------------------------- */
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+
+#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT)
+
+#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D)
+
+#endif /* GL_EXT_texture3D */
+
+/* -------------------------- GL_EXT_texture_array ------------------------- */
+
+#ifndef GL_EXT_texture_array
+#define GL_EXT_texture_array 1
+
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+
+#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT)
+
+#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array)
+
+#endif /* GL_EXT_texture_array */
+
+/* ---------------------- GL_EXT_texture_buffer_object --------------------- */
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_EXT_texture_buffer_object 1
+
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+
+typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+
+#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT)
+
+#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object)
+
+#endif /* GL_EXT_texture_buffer_object */
+
+/* -------------- GL_EXT_texture_compression_astc_decode_mode -------------- */
+
+#ifndef GL_EXT_texture_compression_astc_decode_mode
+#define GL_EXT_texture_compression_astc_decode_mode 1
+
+#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69
+
+#define GLEW_EXT_texture_compression_astc_decode_mode GLEW_GET_VAR(__GLEW_EXT_texture_compression_astc_decode_mode)
+
+#endif /* GL_EXT_texture_compression_astc_decode_mode */
+
+/* ----------- GL_EXT_texture_compression_astc_decode_mode_rgb9e5 ---------- */
+
+#ifndef GL_EXT_texture_compression_astc_decode_mode_rgb9e5
+#define GL_EXT_texture_compression_astc_decode_mode_rgb9e5 1
+
+#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69
+
+#define GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5 GLEW_GET_VAR(__GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5)
+
+#endif /* GL_EXT_texture_compression_astc_decode_mode_rgb9e5 */
+
+/* -------------------- GL_EXT_texture_compression_bptc -------------------- */
+
+#ifndef GL_EXT_texture_compression_bptc
+#define GL_EXT_texture_compression_bptc 1
+
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F
+
+#define GLEW_EXT_texture_compression_bptc GLEW_GET_VAR(__GLEW_EXT_texture_compression_bptc)
+
+#endif /* GL_EXT_texture_compression_bptc */
+
+/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */
+
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+
+#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1)
+
+#endif /* GL_EXT_texture_compression_dxt1 */
+
+/* -------------------- GL_EXT_texture_compression_latc -------------------- */
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_EXT_texture_compression_latc 1
+
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+
+#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc)
+
+#endif /* GL_EXT_texture_compression_latc */
+
+/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+
+#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc)
+
+#endif /* GL_EXT_texture_compression_rgtc */
+
+/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_EXT_texture_compression_s3tc 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+
+#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc)
+
+#endif /* GL_EXT_texture_compression_s3tc */
+
+/* ------------------------ GL_EXT_texture_cube_map ------------------------ */
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_EXT_texture_cube_map 1
+
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+
+#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map)
+
+#endif /* GL_EXT_texture_cube_map */
+
+/* --------------------- GL_EXT_texture_cube_map_array --------------------- */
+
+#ifndef GL_EXT_texture_cube_map_array
+#define GL_EXT_texture_cube_map_array 1
+
+#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+
+#define GLEW_EXT_texture_cube_map_array GLEW_GET_VAR(__GLEW_EXT_texture_cube_map_array)
+
+#endif /* GL_EXT_texture_cube_map_array */
+
+/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */
+
+#ifndef GL_EXT_texture_edge_clamp
+#define GL_EXT_texture_edge_clamp 1
+
+#define GL_CLAMP_TO_EDGE_EXT 0x812F
+
+#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp)
+
+#endif /* GL_EXT_texture_edge_clamp */
+
+/* --------------------------- GL_EXT_texture_env -------------------------- */
+
+#ifndef GL_EXT_texture_env
+#define GL_EXT_texture_env 1
+
+#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env)
+
+#endif /* GL_EXT_texture_env */
+
+/* ------------------------- GL_EXT_texture_env_add ------------------------ */
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+
+#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add)
+
+#endif /* GL_EXT_texture_env_add */
+
+/* ----------------------- GL_EXT_texture_env_combine ---------------------- */
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+
+#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine)
+
+#endif /* GL_EXT_texture_env_combine */
+
+/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+
+#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3)
+
+#endif /* GL_EXT_texture_env_dot3 */
+
+/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+
+#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic)
+
+#endif /* GL_EXT_texture_filter_anisotropic */
+
+/* ---------------------- GL_EXT_texture_filter_minmax --------------------- */
+
+#ifndef GL_EXT_texture_filter_minmax
+#define GL_EXT_texture_filter_minmax 1
+
+#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366
+#define GL_WEIGHTED_AVERAGE_EXT 0x9367
+
+#define GLEW_EXT_texture_filter_minmax GLEW_GET_VAR(__GLEW_EXT_texture_filter_minmax)
+
+#endif /* GL_EXT_texture_filter_minmax */
+
+/* --------------------- GL_EXT_texture_format_BGRA8888 -------------------- */
+
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+
+#define GL_BGRA_EXT 0x80E1
+
+#define GLEW_EXT_texture_format_BGRA8888 GLEW_GET_VAR(__GLEW_EXT_texture_format_BGRA8888)
+
+#endif /* GL_EXT_texture_format_BGRA8888 */
+
+/* ------------------------- GL_EXT_texture_integer ------------------------ */
+
+#ifndef GL_EXT_texture_integer
+#define GL_EXT_texture_integer 1
+
+#define GL_RGBA32UI_EXT 0x8D70
+#define GL_RGB32UI_EXT 0x8D71
+#define GL_ALPHA32UI_EXT 0x8D72
+#define GL_INTENSITY32UI_EXT 0x8D73
+#define GL_LUMINANCE32UI_EXT 0x8D74
+#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define GL_RGBA16UI_EXT 0x8D76
+#define GL_RGB16UI_EXT 0x8D77
+#define GL_ALPHA16UI_EXT 0x8D78
+#define GL_INTENSITY16UI_EXT 0x8D79
+#define GL_LUMINANCE16UI_EXT 0x8D7A
+#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define GL_RGBA8UI_EXT 0x8D7C
+#define GL_RGB8UI_EXT 0x8D7D
+#define GL_ALPHA8UI_EXT 0x8D7E
+#define GL_INTENSITY8UI_EXT 0x8D7F
+#define GL_LUMINANCE8UI_EXT 0x8D80
+#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define GL_RGBA32I_EXT 0x8D82
+#define GL_RGB32I_EXT 0x8D83
+#define GL_ALPHA32I_EXT 0x8D84
+#define GL_INTENSITY32I_EXT 0x8D85
+#define GL_LUMINANCE32I_EXT 0x8D86
+#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define GL_RGBA16I_EXT 0x8D88
+#define GL_RGB16I_EXT 0x8D89
+#define GL_ALPHA16I_EXT 0x8D8A
+#define GL_INTENSITY16I_EXT 0x8D8B
+#define GL_LUMINANCE16I_EXT 0x8D8C
+#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define GL_RGBA8I_EXT 0x8D8E
+#define GL_RGB8I_EXT 0x8D8F
+#define GL_ALPHA8I_EXT 0x8D90
+#define GL_INTENSITY8I_EXT 0x8D91
+#define GL_LUMINANCE8I_EXT 0x8D92
+#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define GL_RED_INTEGER_EXT 0x8D94
+#define GL_GREEN_INTEGER_EXT 0x8D95
+#define GL_BLUE_INTEGER_EXT 0x8D96
+#define GL_ALPHA_INTEGER_EXT 0x8D97
+#define GL_RGB_INTEGER_EXT 0x8D98
+#define GL_RGBA_INTEGER_EXT 0x8D99
+#define GL_BGR_INTEGER_EXT 0x8D9A
+#define GL_BGRA_INTEGER_EXT 0x8D9B
+#define GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+
+typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+
+#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT)
+#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT)
+#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT)
+#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT)
+#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT)
+#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT)
+
+#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer)
+
+#endif /* GL_EXT_texture_integer */
+
+/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+
+#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias)
+
+#endif /* GL_EXT_texture_lod_bias */
+
+/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_EXT_texture_mirror_clamp 1
+
+#define GL_MIRROR_CLAMP_EXT 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+
+#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp)
+
+#endif /* GL_EXT_texture_mirror_clamp */
+
+/* ------------------------- GL_EXT_texture_norm16 ------------------------- */
+
+#ifndef GL_EXT_texture_norm16
+#define GL_EXT_texture_norm16 1
+
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA16_EXT 0x805B
+#define GL_R16_EXT 0x822A
+#define GL_RG16_EXT 0x822C
+#define GL_R16_SNORM_EXT 0x8F98
+#define GL_RG16_SNORM_EXT 0x8F99
+#define GL_RGB16_SNORM_EXT 0x8F9A
+#define GL_RGBA16_SNORM_EXT 0x8F9B
+
+#define GLEW_EXT_texture_norm16 GLEW_GET_VAR(__GLEW_EXT_texture_norm16)
+
+#endif /* GL_EXT_texture_norm16 */
+
+/* ------------------------- GL_EXT_texture_object ------------------------- */
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+
+typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences);
+typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures);
+typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures);
+typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities);
+
+#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT)
+#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT)
+#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT)
+#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT)
+#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT)
+#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT)
+
+#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object)
+
+#endif /* GL_EXT_texture_object */
+
+/* --------------------- GL_EXT_texture_perturb_normal --------------------- */
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+
+#define GL_PERTURB_EXT 0x85AE
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+
+typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+
+#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT)
+
+#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal)
+
+#endif /* GL_EXT_texture_perturb_normal */
+
+/* ------------------------ GL_EXT_texture_rectangle ----------------------- */
+
+#ifndef GL_EXT_texture_rectangle
+#define GL_EXT_texture_rectangle 1
+
+#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8
+
+#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle)
+
+#endif /* GL_EXT_texture_rectangle */
+
+/* --------------------------- GL_EXT_texture_rg --------------------------- */
+
+#ifndef GL_EXT_texture_rg
+#define GL_EXT_texture_rg 1
+
+#define GL_RED_EXT 0x1903
+#define GL_RG_EXT 0x8227
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+
+#define GLEW_EXT_texture_rg GLEW_GET_VAR(__GLEW_EXT_texture_rg)
+
+#endif /* GL_EXT_texture_rg */
+
+/* -------------------------- GL_EXT_texture_sRGB -------------------------- */
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+
+#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB)
+
+#endif /* GL_EXT_texture_sRGB */
+
+/* ------------------------- GL_EXT_texture_sRGB_R8 ------------------------ */
+
+#ifndef GL_EXT_texture_sRGB_R8
+#define GL_EXT_texture_sRGB_R8 1
+
+#define GL_SR8_EXT 0x8FBD
+
+#define GLEW_EXT_texture_sRGB_R8 GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_R8)
+
+#endif /* GL_EXT_texture_sRGB_R8 */
+
+/* ------------------------ GL_EXT_texture_sRGB_RG8 ------------------------ */
+
+#ifndef GL_EXT_texture_sRGB_RG8
+#define GL_EXT_texture_sRGB_RG8 1
+
+#define GL_SRG8_EXT 0x8FBE
+
+#define GLEW_EXT_texture_sRGB_RG8 GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_RG8)
+
+#endif /* GL_EXT_texture_sRGB_RG8 */
+
+/* ----------------------- GL_EXT_texture_sRGB_decode ---------------------- */
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define GL_DECODE_EXT 0x8A49
+#define GL_SKIP_DECODE_EXT 0x8A4A
+
+#define GLEW_EXT_texture_sRGB_decode GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_decode)
+
+#endif /* GL_EXT_texture_sRGB_decode */
+
+/* --------------------- GL_EXT_texture_shared_exponent -------------------- */
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_EXT_texture_shared_exponent 1
+
+#define GL_RGB9_E5_EXT 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+
+#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent)
+
+#endif /* GL_EXT_texture_shared_exponent */
+
+/* -------------------------- GL_EXT_texture_snorm ------------------------- */
+
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_ALPHA_SNORM 0x9010
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_INTENSITY16_SNORM 0x901B
+
+#define GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm)
+
+#endif /* GL_EXT_texture_snorm */
+
+/* ------------------------- GL_EXT_texture_storage ------------------------ */
+
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+#define GL_R16F_EXT 0x822D
+#define GL_R32F_EXT 0x822E
+#define GL_RG16F_EXT 0x822F
+#define GL_RG32F_EXT 0x8230
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_RGB_RAW_422_APPLE 0x8A51
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_BGRA8_EXT 0x93A1
+
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glTexStorage1DEXT GLEW_GET_FUN(__glewTexStorage1DEXT)
+#define glTexStorage2DEXT GLEW_GET_FUN(__glewTexStorage2DEXT)
+#define glTexStorage3DEXT GLEW_GET_FUN(__glewTexStorage3DEXT)
+#define glTextureStorage1DEXT GLEW_GET_FUN(__glewTextureStorage1DEXT)
+#define glTextureStorage2DEXT GLEW_GET_FUN(__glewTextureStorage2DEXT)
+#define glTextureStorage3DEXT GLEW_GET_FUN(__glewTextureStorage3DEXT)
+
+#define GLEW_EXT_texture_storage GLEW_GET_VAR(__GLEW_EXT_texture_storage)
+
+#endif /* GL_EXT_texture_storage */
+
+/* ------------------------- GL_EXT_texture_swizzle ------------------------ */
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_EXT_texture_swizzle 1
+
+#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
+#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
+#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
+#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
+
+#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle)
+
+#endif /* GL_EXT_texture_swizzle */
+
+/* ------------------- GL_EXT_texture_type_2_10_10_10_REV ------------------ */
+
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_EXT_texture_type_2_10_10_10_REV 1
+
+#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
+
+#define GLEW_EXT_texture_type_2_10_10_10_REV GLEW_GET_VAR(__GLEW_EXT_texture_type_2_10_10_10_REV)
+
+#endif /* GL_EXT_texture_type_2_10_10_10_REV */
+
+/* -------------------------- GL_EXT_texture_view -------------------------- */
+
+#ifndef GL_EXT_texture_view
+#define GL_EXT_texture_view 1
+
+#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+
+#define glTextureViewEXT GLEW_GET_FUN(__glewTextureViewEXT)
+
+#define GLEW_EXT_texture_view GLEW_GET_VAR(__GLEW_EXT_texture_view)
+
+#endif /* GL_EXT_texture_view */
+
+/* --------------------------- GL_EXT_timer_query -------------------------- */
+
+#ifndef GL_EXT_timer_query
+#define GL_EXT_timer_query 1
+
+#define GL_TIME_ELAPSED_EXT 0x88BF
+
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
+
+#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT)
+#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT)
+
+#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query)
+
+#endif /* GL_EXT_timer_query */
+
+/* ----------------------- GL_EXT_transform_feedback ----------------------- */
+
+#ifndef GL_EXT_transform_feedback
+#define GL_EXT_transform_feedback 1
+
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define GL_RASTERIZER_DISCARD_EXT 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C
+#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+
+typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar * const* varyings, GLenum bufferMode);
+
+#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT)
+#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT)
+#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT)
+#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT)
+#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT)
+#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT)
+#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT)
+
+#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback)
+
+#endif /* GL_EXT_transform_feedback */
+
+/* ------------------------- GL_EXT_unpack_subimage ------------------------ */
+
+#ifndef GL_EXT_unpack_subimage
+#define GL_EXT_unpack_subimage 1
+
+#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2
+#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4
+
+#define GLEW_EXT_unpack_subimage GLEW_GET_VAR(__GLEW_EXT_unpack_subimage)
+
+#endif /* GL_EXT_unpack_subimage */
+
+/* -------------------------- GL_EXT_vertex_array -------------------------- */
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+
+#define GL_DOUBLE_EXT 0x140A
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+
+typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer);
+typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer);
+
+#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT)
+#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT)
+#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT)
+#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT)
+#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT)
+#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT)
+#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT)
+#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT)
+
+#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array)
+
+#endif /* GL_EXT_vertex_array */
+
+/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */
+
+#ifndef GL_EXT_vertex_array_bgra
+#define GL_EXT_vertex_array_bgra 1
+
+#define GL_BGRA 0x80E1
+
+#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra)
+
+#endif /* GL_EXT_vertex_array_bgra */
+
+/* ----------------------- GL_EXT_vertex_array_setXXX ---------------------- */
+
+#ifndef GL_EXT_vertex_array_setXXX
+#define GL_EXT_vertex_array_setXXX 1
+
+typedef void (GLAPIENTRY * PFNGLBINDARRAYSETEXTPROC) (const void *arrayset);
+typedef const void * (GLAPIENTRY * PFNGLCREATEARRAYSETEXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLDELETEARRAYSETSEXTPROC) (GLsizei n, const void *arrayset[]);
+
+#define glBindArraySetEXT GLEW_GET_FUN(__glewBindArraySetEXT)
+#define glCreateArraySetExt GLEW_GET_FUN(__glewCreateArraySetExt)
+#define glDeleteArraySetsEXT GLEW_GET_FUN(__glewDeleteArraySetsEXT)
+
+#define GLEW_EXT_vertex_array_setXXX GLEW_GET_VAR(__GLEW_EXT_vertex_array_setXXX)
+
+#endif /* GL_EXT_vertex_array_setXXX */
+
+/* ----------------------- GL_EXT_vertex_attrib_64bit ---------------------- */
+
+#ifndef GL_EXT_vertex_attrib_64bit
+#define GL_EXT_vertex_attrib_64bit 1
+
+#define GL_DOUBLE_MAT2_EXT 0x8F46
+#define GL_DOUBLE_MAT3_EXT 0x8F47
+#define GL_DOUBLE_MAT4_EXT 0x8F48
+#define GL_DOUBLE_MAT2x3_EXT 0x8F49
+#define GL_DOUBLE_MAT2x4_EXT 0x8F4A
+#define GL_DOUBLE_MAT3x2_EXT 0x8F4B
+#define GL_DOUBLE_MAT3x4_EXT 0x8F4C
+#define GL_DOUBLE_MAT4x2_EXT 0x8F4D
+#define GL_DOUBLE_MAT4x3_EXT 0x8F4E
+#define GL_DOUBLE_VEC2_EXT 0x8FFC
+#define GL_DOUBLE_VEC3_EXT 0x8FFD
+#define GL_DOUBLE_VEC4_EXT 0x8FFE
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+
+#define glGetVertexAttribLdvEXT GLEW_GET_FUN(__glewGetVertexAttribLdvEXT)
+#define glVertexArrayVertexAttribLOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLOffsetEXT)
+#define glVertexAttribL1dEXT GLEW_GET_FUN(__glewVertexAttribL1dEXT)
+#define glVertexAttribL1dvEXT GLEW_GET_FUN(__glewVertexAttribL1dvEXT)
+#define glVertexAttribL2dEXT GLEW_GET_FUN(__glewVertexAttribL2dEXT)
+#define glVertexAttribL2dvEXT GLEW_GET_FUN(__glewVertexAttribL2dvEXT)
+#define glVertexAttribL3dEXT GLEW_GET_FUN(__glewVertexAttribL3dEXT)
+#define glVertexAttribL3dvEXT GLEW_GET_FUN(__glewVertexAttribL3dvEXT)
+#define glVertexAttribL4dEXT GLEW_GET_FUN(__glewVertexAttribL4dEXT)
+#define glVertexAttribL4dvEXT GLEW_GET_FUN(__glewVertexAttribL4dvEXT)
+#define glVertexAttribLPointerEXT GLEW_GET_FUN(__glewVertexAttribLPointerEXT)
+
+#define GLEW_EXT_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_EXT_vertex_attrib_64bit)
+
+#endif /* GL_EXT_vertex_attrib_64bit */
+
+/* -------------------------- GL_EXT_vertex_shader ------------------------- */
+
+#ifndef GL_EXT_vertex_shader
+#define GL_EXT_vertex_shader 1
+
+#define GL_VERTEX_SHADER_EXT 0x8780
+#define GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define GL_OP_INDEX_EXT 0x8782
+#define GL_OP_NEGATE_EXT 0x8783
+#define GL_OP_DOT3_EXT 0x8784
+#define GL_OP_DOT4_EXT 0x8785
+#define GL_OP_MUL_EXT 0x8786
+#define GL_OP_ADD_EXT 0x8787
+#define GL_OP_MADD_EXT 0x8788
+#define GL_OP_FRAC_EXT 0x8789
+#define GL_OP_MAX_EXT 0x878A
+#define GL_OP_MIN_EXT 0x878B
+#define GL_OP_SET_GE_EXT 0x878C
+#define GL_OP_SET_LT_EXT 0x878D
+#define GL_OP_CLAMP_EXT 0x878E
+#define GL_OP_FLOOR_EXT 0x878F
+#define GL_OP_ROUND_EXT 0x8790
+#define GL_OP_EXP_BASE_2_EXT 0x8791
+#define GL_OP_LOG_BASE_2_EXT 0x8792
+#define GL_OP_POWER_EXT 0x8793
+#define GL_OP_RECIP_EXT 0x8794
+#define GL_OP_RECIP_SQRT_EXT 0x8795
+#define GL_OP_SUB_EXT 0x8796
+#define GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define GL_OP_MOV_EXT 0x8799
+#define GL_OUTPUT_VERTEX_EXT 0x879A
+#define GL_OUTPUT_COLOR0_EXT 0x879B
+#define GL_OUTPUT_COLOR1_EXT 0x879C
+#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define GL_OUTPUT_FOG_EXT 0x87BD
+#define GL_SCALAR_EXT 0x87BE
+#define GL_VECTOR_EXT 0x87BF
+#define GL_MATRIX_EXT 0x87C0
+#define GL_VARIANT_EXT 0x87C1
+#define GL_INVARIANT_EXT 0x87C2
+#define GL_LOCAL_CONSTANT_EXT 0x87C3
+#define GL_LOCAL_EXT 0x87C4
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define GL_X_EXT 0x87D5
+#define GL_Y_EXT 0x87D6
+#define GL_Z_EXT 0x87D7
+#define GL_W_EXT 0x87D8
+#define GL_NEGATIVE_X_EXT 0x87D9
+#define GL_NEGATIVE_Y_EXT 0x87DA
+#define GL_NEGATIVE_Z_EXT 0x87DB
+#define GL_NEGATIVE_W_EXT 0x87DC
+#define GL_ZERO_EXT 0x87DD
+#define GL_ONE_EXT 0x87DE
+#define GL_NEGATIVE_ONE_EXT 0x87DF
+#define GL_NORMALIZED_RANGE_EXT 0x87E0
+#define GL_FULL_RANGE_EXT 0x87E1
+#define GL_CURRENT_VERTEX_EXT 0x87E2
+#define GL_MVP_MATRIX_EXT 0x87E3
+#define GL_VARIANT_VALUE_EXT 0x87E4
+#define GL_VARIANT_DATATYPE_EXT 0x87E5
+#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define GL_VARIANT_ARRAY_EXT 0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define GL_INVARIANT_VALUE_EXT 0x87EA
+#define GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+
+typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void);
+typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value);
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components);
+typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range);
+typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data);
+typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap);
+typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, void *addr);
+typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, void *addr);
+typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1);
+typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, void *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr);
+typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+
+#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT)
+#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT)
+#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT)
+#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT)
+#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT)
+#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT)
+#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT)
+#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT)
+#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT)
+#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT)
+#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT)
+#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT)
+#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT)
+#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT)
+#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT)
+#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT)
+#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT)
+#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT)
+#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT)
+#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT)
+#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT)
+#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT)
+#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT)
+#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT)
+#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT)
+#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT)
+#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT)
+#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT)
+#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT)
+#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT)
+#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT)
+#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT)
+#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT)
+#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT)
+#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT)
+#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT)
+#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT)
+#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT)
+#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT)
+#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT)
+#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT)
+#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT)
+
+#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader)
+
+#endif /* GL_EXT_vertex_shader */
+
+/* ------------------------ GL_EXT_vertex_weighting ------------------------ */
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+
+#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3
+#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6
+#define GL_MODELVIEW0_EXT 0x1700
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight);
+
+#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT)
+#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT)
+#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT)
+
+#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting)
+
+#endif /* GL_EXT_vertex_weighting */
+
+/* ------------------------ GL_EXT_win32_keyed_mutex ----------------------- */
+
+#ifndef GL_EXT_win32_keyed_mutex
+#define GL_EXT_win32_keyed_mutex 1
+
+typedef GLboolean (GLAPIENTRY * PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout);
+typedef GLboolean (GLAPIENTRY * PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key);
+
+#define glAcquireKeyedMutexWin32EXT GLEW_GET_FUN(__glewAcquireKeyedMutexWin32EXT)
+#define glReleaseKeyedMutexWin32EXT GLEW_GET_FUN(__glewReleaseKeyedMutexWin32EXT)
+
+#define GLEW_EXT_win32_keyed_mutex GLEW_GET_VAR(__GLEW_EXT_win32_keyed_mutex)
+
+#endif /* GL_EXT_win32_keyed_mutex */
+
+/* ------------------------ GL_EXT_window_rectangles ----------------------- */
+
+#ifndef GL_EXT_window_rectangles
+#define GL_EXT_window_rectangles 1
+
+#define GL_INCLUSIVE_EXT 0x8F10
+#define GL_EXCLUSIVE_EXT 0x8F11
+#define GL_WINDOW_RECTANGLE_EXT 0x8F12
+#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13
+#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14
+#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15
+
+typedef void (GLAPIENTRY * PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint box[]);
+
+#define glWindowRectanglesEXT GLEW_GET_FUN(__glewWindowRectanglesEXT)
+
+#define GLEW_EXT_window_rectangles GLEW_GET_VAR(__GLEW_EXT_window_rectangles)
+
+#endif /* GL_EXT_window_rectangles */
+
+/* ------------------------- GL_EXT_x11_sync_object ------------------------ */
+
+#ifndef GL_EXT_x11_sync_object
+#define GL_EXT_x11_sync_object 1
+
+#define GL_SYNC_X11_FENCE_EXT 0x90E1
+
+typedef GLsync (GLAPIENTRY * PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags);
+
+#define glImportSyncEXT GLEW_GET_FUN(__glewImportSyncEXT)
+
+#define GLEW_EXT_x11_sync_object GLEW_GET_VAR(__GLEW_EXT_x11_sync_object)
+
+#endif /* GL_EXT_x11_sync_object */
+
+/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */
+
+#ifndef GL_GREMEDY_frame_terminator
+#define GL_GREMEDY_frame_terminator 1
+
+typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void);
+
+#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY)
+
+#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator)
+
+#endif /* GL_GREMEDY_frame_terminator */
+
+/* ------------------------ GL_GREMEDY_string_marker ----------------------- */
+
+#ifndef GL_GREMEDY_string_marker
+#define GL_GREMEDY_string_marker 1
+
+typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string);
+
+#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY)
+
+#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker)
+
+#endif /* GL_GREMEDY_string_marker */
+
+/* --------------------- GL_HP_convolution_border_modes -------------------- */
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+
+#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes)
+
+#endif /* GL_HP_convolution_border_modes */
+
+/* ------------------------- GL_HP_image_transform ------------------------- */
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+
+typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params);
+
+#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP)
+#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP)
+#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP)
+#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP)
+#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP)
+#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP)
+
+#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform)
+
+#endif /* GL_HP_image_transform */
+
+/* -------------------------- GL_HP_occlusion_test ------------------------- */
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+
+#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test)
+
+#endif /* GL_HP_occlusion_test */
+
+/* ------------------------- GL_HP_texture_lighting ------------------------ */
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+
+#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting)
+
+#endif /* GL_HP_texture_lighting */
+
+/* --------------------------- GL_IBM_cull_vertex -------------------------- */
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+
+#define GL_CULL_VERTEX_IBM 103050
+
+#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex)
+
+#endif /* GL_IBM_cull_vertex */
+
+/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount, GLint modestride);
+
+#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM)
+#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM)
+
+#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays)
+
+#endif /* GL_IBM_multimode_draw_arrays */
+
+/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010
+
+#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip)
+
+#endif /* GL_IBM_rasterpos_clip */
+
+/* --------------------------- GL_IBM_static_data -------------------------- */
+
+#ifndef GL_IBM_static_data
+#define GL_IBM_static_data 1
+
+#define GL_ALL_STATIC_DATA_IBM 103060
+#define GL_STATIC_VERTEX_ARRAY_IBM 103061
+
+#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data)
+
+#endif /* GL_IBM_static_data */
+
+/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */
+
+#ifndef GL_IBM_texture_mirrored_repeat
+#define GL_IBM_texture_mirrored_repeat 1
+
+#define GL_MIRRORED_REPEAT_IBM 0x8370
+
+#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat)
+
+#endif /* GL_IBM_texture_mirrored_repeat */
+
+/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+
+typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride);
+
+#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM)
+#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM)
+#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM)
+#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM)
+#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM)
+#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM)
+#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM)
+#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM)
+
+#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists)
+
+#endif /* GL_IBM_vertex_array_lists */
+
+/* -------------------------- GL_INGR_color_clamp -------------------------- */
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+
+#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp)
+
+#endif /* GL_INGR_color_clamp */
+
+/* ------------------------- GL_INGR_interlace_read ------------------------ */
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+
+#define GL_INTERLACE_READ_INGR 0x8568
+
+#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read)
+
+#endif /* GL_INGR_interlace_read */
+
+/* ------------------ GL_INTEL_conservative_rasterization ------------------ */
+
+#ifndef GL_INTEL_conservative_rasterization
+#define GL_INTEL_conservative_rasterization 1
+
+#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE
+
+#define GLEW_INTEL_conservative_rasterization GLEW_GET_VAR(__GLEW_INTEL_conservative_rasterization)
+
+#endif /* GL_INTEL_conservative_rasterization */
+
+/* ------------------- GL_INTEL_fragment_shader_ordering ------------------- */
+
+#ifndef GL_INTEL_fragment_shader_ordering
+#define GL_INTEL_fragment_shader_ordering 1
+
+#define GLEW_INTEL_fragment_shader_ordering GLEW_GET_VAR(__GLEW_INTEL_fragment_shader_ordering)
+
+#endif /* GL_INTEL_fragment_shader_ordering */
+
+/* ----------------------- GL_INTEL_framebuffer_CMAA ----------------------- */
+
+#ifndef GL_INTEL_framebuffer_CMAA
+#define GL_INTEL_framebuffer_CMAA 1
+
+#define GLEW_INTEL_framebuffer_CMAA GLEW_GET_VAR(__GLEW_INTEL_framebuffer_CMAA)
+
+#endif /* GL_INTEL_framebuffer_CMAA */
+
+/* -------------------------- GL_INTEL_map_texture ------------------------- */
+
+#ifndef GL_INTEL_map_texture
+#define GL_INTEL_map_texture 1
+
+#define GL_LAYOUT_DEFAULT_INTEL 0
+#define GL_LAYOUT_LINEAR_INTEL 1
+#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2
+#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF
+
+typedef void * (GLAPIENTRY * PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint* stride, GLenum *layout);
+typedef void (GLAPIENTRY * PFNGLSYNCTEXTUREINTELPROC) (GLuint texture);
+typedef void (GLAPIENTRY * PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level);
+
+#define glMapTexture2DINTEL GLEW_GET_FUN(__glewMapTexture2DINTEL)
+#define glSyncTextureINTEL GLEW_GET_FUN(__glewSyncTextureINTEL)
+#define glUnmapTexture2DINTEL GLEW_GET_FUN(__glewUnmapTexture2DINTEL)
+
+#define GLEW_INTEL_map_texture GLEW_GET_VAR(__GLEW_INTEL_map_texture)
+
+#endif /* GL_INTEL_map_texture */
+
+/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+
+typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer);
+typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer);
+
+#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL)
+#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL)
+#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL)
+#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL)
+
+#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays)
+
+#endif /* GL_INTEL_parallel_arrays */
+
+/* ----------------------- GL_INTEL_performance_query ---------------------- */
+
+#ifndef GL_INTEL_performance_query
+#define GL_INTEL_performance_query 1
+
+#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x0000
+#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x0001
+#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9
+#define GL_PERFQUERY_FLUSH_INTEL 0x83FA
+#define GL_PERFQUERY_WAIT_INTEL 0x83FB
+#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0
+#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1
+#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2
+#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3
+#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4
+#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5
+#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8
+#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9
+#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA
+#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB
+#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC
+#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD
+#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE
+#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF
+#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500
+
+typedef void (GLAPIENTRY * PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GLAPIENTRY * PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint* queryHandle);
+typedef void (GLAPIENTRY * PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GLAPIENTRY * PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GLAPIENTRY * PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint* queryId);
+typedef void (GLAPIENTRY * PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint* nextQueryId);
+typedef void (GLAPIENTRY * PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar* counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
+typedef void (GLAPIENTRY * PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);
+typedef void (GLAPIENTRY * PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar* queryName, GLuint *queryId);
+typedef void (GLAPIENTRY * PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar* queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
+
+#define glBeginPerfQueryINTEL GLEW_GET_FUN(__glewBeginPerfQueryINTEL)
+#define glCreatePerfQueryINTEL GLEW_GET_FUN(__glewCreatePerfQueryINTEL)
+#define glDeletePerfQueryINTEL GLEW_GET_FUN(__glewDeletePerfQueryINTEL)
+#define glEndPerfQueryINTEL GLEW_GET_FUN(__glewEndPerfQueryINTEL)
+#define glGetFirstPerfQueryIdINTEL GLEW_GET_FUN(__glewGetFirstPerfQueryIdINTEL)
+#define glGetNextPerfQueryIdINTEL GLEW_GET_FUN(__glewGetNextPerfQueryIdINTEL)
+#define glGetPerfCounterInfoINTEL GLEW_GET_FUN(__glewGetPerfCounterInfoINTEL)
+#define glGetPerfQueryDataINTEL GLEW_GET_FUN(__glewGetPerfQueryDataINTEL)
+#define glGetPerfQueryIdByNameINTEL GLEW_GET_FUN(__glewGetPerfQueryIdByNameINTEL)
+#define glGetPerfQueryInfoINTEL GLEW_GET_FUN(__glewGetPerfQueryInfoINTEL)
+
+#define GLEW_INTEL_performance_query GLEW_GET_VAR(__GLEW_INTEL_performance_query)
+
+#endif /* GL_INTEL_performance_query */
+
+/* ------------------------ GL_INTEL_texture_scissor ----------------------- */
+
+#ifndef GL_INTEL_texture_scissor
+#define GL_INTEL_texture_scissor 1
+
+typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc);
+typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh);
+
+#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL)
+#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL)
+
+#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor)
+
+#endif /* GL_INTEL_texture_scissor */
+
+/* --------------------- GL_KHR_blend_equation_advanced -------------------- */
+
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+
+#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285
+#define GL_MULTIPLY_KHR 0x9294
+#define GL_SCREEN_KHR 0x9295
+#define GL_OVERLAY_KHR 0x9296
+#define GL_DARKEN_KHR 0x9297
+#define GL_LIGHTEN_KHR 0x9298
+#define GL_COLORDODGE_KHR 0x9299
+#define GL_COLORBURN_KHR 0x929A
+#define GL_HARDLIGHT_KHR 0x929B
+#define GL_SOFTLIGHT_KHR 0x929C
+#define GL_DIFFERENCE_KHR 0x929E
+#define GL_EXCLUSION_KHR 0x92A0
+#define GL_HSL_HUE_KHR 0x92AD
+#define GL_HSL_SATURATION_KHR 0x92AE
+#define GL_HSL_COLOR_KHR 0x92AF
+#define GL_HSL_LUMINOSITY_KHR 0x92B0
+
+typedef void (GLAPIENTRY * PFNGLBLENDBARRIERKHRPROC) (void);
+
+#define glBlendBarrierKHR GLEW_GET_FUN(__glewBlendBarrierKHR)
+
+#define GLEW_KHR_blend_equation_advanced GLEW_GET_VAR(__GLEW_KHR_blend_equation_advanced)
+
+#endif /* GL_KHR_blend_equation_advanced */
+
+/* ---------------- GL_KHR_blend_equation_advanced_coherent ---------------- */
+
+#ifndef GL_KHR_blend_equation_advanced_coherent
+#define GL_KHR_blend_equation_advanced_coherent 1
+
+#define GLEW_KHR_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_KHR_blend_equation_advanced_coherent)
+
+#endif /* GL_KHR_blend_equation_advanced_coherent */
+
+/* ---------------------- GL_KHR_context_flush_control --------------------- */
+
+#ifndef GL_KHR_context_flush_control
+#define GL_KHR_context_flush_control 1
+
+#define GLEW_KHR_context_flush_control GLEW_GET_VAR(__GLEW_KHR_context_flush_control)
+
+#endif /* GL_KHR_context_flush_control */
+
+/* ------------------------------ GL_KHR_debug ----------------------------- */
+
+#ifndef GL_KHR_debug
+#define GL_KHR_debug 1
+
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_BUFFER 0x82E0
+#define GL_SHADER 0x82E1
+#define GL_PROGRAM 0x82E2
+#define GL_QUERY 0x82E3
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_SAMPLER 0x82E6
+#define GL_DISPLAY_LIST 0x82E7
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_OUTPUT 0x92E0
+
+typedef void (GLAPIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam);
+
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
+typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar *label);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABELPROC) (void* ptr, GLsizei bufSize, GLsizei* length, GLchar *label);
+typedef void (GLAPIENTRY * PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label);
+typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABELPROC) (void* ptr, GLsizei length, const GLchar* label);
+typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message);
+
+#define glDebugMessageCallback GLEW_GET_FUN(__glewDebugMessageCallback)
+#define glDebugMessageControl GLEW_GET_FUN(__glewDebugMessageControl)
+#define glDebugMessageInsert GLEW_GET_FUN(__glewDebugMessageInsert)
+#define glGetDebugMessageLog GLEW_GET_FUN(__glewGetDebugMessageLog)
+#define glGetObjectLabel GLEW_GET_FUN(__glewGetObjectLabel)
+#define glGetObjectPtrLabel GLEW_GET_FUN(__glewGetObjectPtrLabel)
+#define glObjectLabel GLEW_GET_FUN(__glewObjectLabel)
+#define glObjectPtrLabel GLEW_GET_FUN(__glewObjectPtrLabel)
+#define glPopDebugGroup GLEW_GET_FUN(__glewPopDebugGroup)
+#define glPushDebugGroup GLEW_GET_FUN(__glewPushDebugGroup)
+
+#define GLEW_KHR_debug GLEW_GET_VAR(__GLEW_KHR_debug)
+
+#endif /* GL_KHR_debug */
+
+/* ---------------------------- GL_KHR_no_error ---------------------------- */
+
+#ifndef GL_KHR_no_error
+#define GL_KHR_no_error 1
+
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
+
+#define GLEW_KHR_no_error GLEW_GET_VAR(__GLEW_KHR_no_error)
+
+#endif /* GL_KHR_no_error */
+
+/* --------------------- GL_KHR_parallel_shader_compile -------------------- */
+
+#ifndef GL_KHR_parallel_shader_compile
+#define GL_KHR_parallel_shader_compile 1
+
+#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0
+#define GL_COMPLETION_STATUS_KHR 0x91B1
+
+typedef void (GLAPIENTRY * PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count);
+
+#define glMaxShaderCompilerThreadsKHR GLEW_GET_FUN(__glewMaxShaderCompilerThreadsKHR)
+
+#define GLEW_KHR_parallel_shader_compile GLEW_GET_VAR(__GLEW_KHR_parallel_shader_compile)
+
+#endif /* GL_KHR_parallel_shader_compile */
+
+/* ------------------ GL_KHR_robust_buffer_access_behavior ----------------- */
+
+#ifndef GL_KHR_robust_buffer_access_behavior
+#define GL_KHR_robust_buffer_access_behavior 1
+
+#define GLEW_KHR_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_KHR_robust_buffer_access_behavior)
+
+#endif /* GL_KHR_robust_buffer_access_behavior */
+
+/* --------------------------- GL_KHR_robustness --------------------------- */
+
+#ifndef GL_KHR_robustness
+#define GL_KHR_robustness 1
+
+#define GL_CONTEXT_LOST 0x0507
+#define GL_LOSE_CONTEXT_ON_RESET 0x8252
+#define GL_GUILTY_CONTEXT_RESET 0x8253
+#define GL_INNOCENT_CONTEXT_RESET 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY 0x8256
+#define GL_NO_RESET_NOTIFICATION 0x8261
+#define GL_CONTEXT_ROBUST_ACCESS 0x90F3
+
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+
+#define glGetnUniformfv GLEW_GET_FUN(__glewGetnUniformfv)
+#define glGetnUniformiv GLEW_GET_FUN(__glewGetnUniformiv)
+#define glGetnUniformuiv GLEW_GET_FUN(__glewGetnUniformuiv)
+#define glReadnPixels GLEW_GET_FUN(__glewReadnPixels)
+
+#define GLEW_KHR_robustness GLEW_GET_VAR(__GLEW_KHR_robustness)
+
+#endif /* GL_KHR_robustness */
+
+/* ------------------ GL_KHR_texture_compression_astc_hdr ------------------ */
+
+#ifndef GL_KHR_texture_compression_astc_hdr
+#define GL_KHR_texture_compression_astc_hdr 1
+
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+
+#define GLEW_KHR_texture_compression_astc_hdr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_hdr)
+
+#endif /* GL_KHR_texture_compression_astc_hdr */
+
+/* ------------------ GL_KHR_texture_compression_astc_ldr ------------------ */
+
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_KHR_texture_compression_astc_ldr 1
+
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+
+#define GLEW_KHR_texture_compression_astc_ldr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_ldr)
+
+#endif /* GL_KHR_texture_compression_astc_ldr */
+
+/* --------------- GL_KHR_texture_compression_astc_sliced_3d --------------- */
+
+#ifndef GL_KHR_texture_compression_astc_sliced_3d
+#define GL_KHR_texture_compression_astc_sliced_3d 1
+
+#define GLEW_KHR_texture_compression_astc_sliced_3d GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_sliced_3d)
+
+#endif /* GL_KHR_texture_compression_astc_sliced_3d */
+
+/* -------------------------- GL_KTX_buffer_region ------------------------- */
+
+#ifndef GL_KTX_buffer_region
+#define GL_KTX_buffer_region 1
+
+#define GL_KTX_FRONT_REGION 0x0
+#define GL_KTX_BACK_REGION 0x1
+#define GL_KTX_Z_REGION 0x2
+#define GL_KTX_STENCIL_REGION 0x3
+
+typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDPROC) (void);
+typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONPROC) (GLenum region);
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest);
+typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONPROC) (GLenum region);
+typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define glBufferRegionEnabled GLEW_GET_FUN(__glewBufferRegionEnabled)
+#define glDeleteBufferRegion GLEW_GET_FUN(__glewDeleteBufferRegion)
+#define glDrawBufferRegion GLEW_GET_FUN(__glewDrawBufferRegion)
+#define glNewBufferRegion GLEW_GET_FUN(__glewNewBufferRegion)
+#define glReadBufferRegion GLEW_GET_FUN(__glewReadBufferRegion)
+
+#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region)
+
+#endif /* GL_KTX_buffer_region */
+
+/* ------------------------- GL_MESAX_texture_stack ------------------------ */
+
+#ifndef GL_MESAX_texture_stack
+#define GL_MESAX_texture_stack 1
+
+#define GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+
+#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack)
+
+#endif /* GL_MESAX_texture_stack */
+
+/* -------------------------- GL_MESA_pack_invert -------------------------- */
+
+#ifndef GL_MESA_pack_invert
+#define GL_MESA_pack_invert 1
+
+#define GL_PACK_INVERT_MESA 0x8758
+
+#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert)
+
+#endif /* GL_MESA_pack_invert */
+
+/* ------------------------- GL_MESA_resize_buffers ------------------------ */
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+
+typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void);
+
+#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA)
+
+#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers)
+
+#endif /* GL_MESA_resize_buffers */
+
+/* -------------------- GL_MESA_shader_integer_functions ------------------- */
+
+#ifndef GL_MESA_shader_integer_functions
+#define GL_MESA_shader_integer_functions 1
+
+#define GLEW_MESA_shader_integer_functions GLEW_GET_VAR(__GLEW_MESA_shader_integer_functions)
+
+#endif /* GL_MESA_shader_integer_functions */
+
+/* --------------------------- GL_MESA_window_pos -------------------------- */
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p);
+
+#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA)
+#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA)
+#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA)
+#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA)
+#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA)
+#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA)
+#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA)
+#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA)
+#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA)
+#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA)
+#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA)
+#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA)
+#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA)
+#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA)
+#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA)
+#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA)
+#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA)
+#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA)
+#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA)
+#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA)
+#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA)
+#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA)
+#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA)
+#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA)
+
+#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos)
+
+#endif /* GL_MESA_window_pos */
+
+/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_MESA_ycbcr_texture 1
+
+#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define GL_YCBCR_MESA 0x8757
+
+#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture)
+
+#endif /* GL_MESA_ycbcr_texture */
+
+/* ----------- GL_NVX_blend_equation_advanced_multi_draw_buffers ----------- */
+
+#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers
+#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1
+
+#define GLEW_NVX_blend_equation_advanced_multi_draw_buffers GLEW_GET_VAR(__GLEW_NVX_blend_equation_advanced_multi_draw_buffers)
+
+#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */
+
+/* ----------------------- GL_NVX_conditional_render ----------------------- */
+
+#ifndef GL_NVX_conditional_render
+#define GL_NVX_conditional_render 1
+
+typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVXPROC) (void);
+
+#define glBeginConditionalRenderNVX GLEW_GET_FUN(__glewBeginConditionalRenderNVX)
+#define glEndConditionalRenderNVX GLEW_GET_FUN(__glewEndConditionalRenderNVX)
+
+#define GLEW_NVX_conditional_render GLEW_GET_VAR(__GLEW_NVX_conditional_render)
+
+#endif /* GL_NVX_conditional_render */
+
+/* ------------------------- GL_NVX_gpu_memory_info ------------------------ */
+
+#ifndef GL_NVX_gpu_memory_info
+#define GL_NVX_gpu_memory_info 1
+
+#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
+#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
+#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
+#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
+#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
+
+#define GLEW_NVX_gpu_memory_info GLEW_GET_VAR(__GLEW_NVX_gpu_memory_info)
+
+#endif /* GL_NVX_gpu_memory_info */
+
+/* ---------------------- GL_NVX_linked_gpu_multicast ---------------------- */
+
+#ifndef GL_NVX_linked_gpu_multicast
+#define GL_NVX_linked_gpu_multicast 1
+
+#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800
+#define GL_MAX_LGPU_GPUS_NVX 0x92BA
+
+typedef void (GLAPIENTRY * PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAPIENTRY * PFNGLLGPUINTERLOCKNVXPROC) (void);
+typedef void (GLAPIENTRY * PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
+
+#define glLGPUCopyImageSubDataNVX GLEW_GET_FUN(__glewLGPUCopyImageSubDataNVX)
+#define glLGPUInterlockNVX GLEW_GET_FUN(__glewLGPUInterlockNVX)
+#define glLGPUNamedBufferSubDataNVX GLEW_GET_FUN(__glewLGPUNamedBufferSubDataNVX)
+
+#define GLEW_NVX_linked_gpu_multicast GLEW_GET_VAR(__GLEW_NVX_linked_gpu_multicast)
+
+#endif /* GL_NVX_linked_gpu_multicast */
+
+/* ------------------------ GL_NV_3dvision_settings ------------------------ */
+
+#ifndef GL_NV_3dvision_settings
+#define GL_NV_3dvision_settings 1
+
+#define GL_3DVISION_STEREO_NV 0x90F4
+#define GL_STEREO_SEPARATION_NV 0x90F5
+#define GL_STEREO_CONVERGENCE_NV 0x90F6
+#define GL_STEREO_CUTOFF_NV 0x90F7
+#define GL_STEREO_PROJECTION_NV 0x90F8
+#define GL_STEREO_PROJECTION_PERSPECTIVE_NV 0x90F9
+#define GL_STEREO_PROJECTION_ORTHO_NV 0x90FA
+
+typedef void (GLAPIENTRY * PFNGLSTEREOPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLSTEREOPARAMETERINVPROC) (GLenum pname, GLint param);
+
+#define glStereoParameterfNV GLEW_GET_FUN(__glewStereoParameterfNV)
+#define glStereoParameteriNV GLEW_GET_FUN(__glewStereoParameteriNV)
+
+#define GLEW_NV_3dvision_settings GLEW_GET_VAR(__GLEW_NV_3dvision_settings)
+
+#endif /* GL_NV_3dvision_settings */
+
+/* ------------------- GL_NV_EGL_stream_consumer_external ------------------ */
+
+#ifndef GL_NV_EGL_stream_consumer_external
+#define GL_NV_EGL_stream_consumer_external 1
+
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_SAMPLER_EXTERNAL_OES 0x8D66
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+
+#define GLEW_NV_EGL_stream_consumer_external GLEW_GET_VAR(__GLEW_NV_EGL_stream_consumer_external)
+
+#endif /* GL_NV_EGL_stream_consumer_external */
+
+/* ----------------- GL_NV_alpha_to_coverage_dither_control ---------------- */
+
+#ifndef GL_NV_alpha_to_coverage_dither_control
+#define GL_NV_alpha_to_coverage_dither_control 1
+
+#define GL_ALPHA_TO_COVERAGE_DITHER_MODE_NV 0x92BF
+#define GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV 0x934D
+#define GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV 0x934E
+#define GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV 0x934F
+
+#define GLEW_NV_alpha_to_coverage_dither_control GLEW_GET_VAR(__GLEW_NV_alpha_to_coverage_dither_control)
+
+#endif /* GL_NV_alpha_to_coverage_dither_control */
+
+/* ------------------------------- GL_NV_bgr ------------------------------- */
+
+#ifndef GL_NV_bgr
+#define GL_NV_bgr 1
+
+#define GL_BGR_NV 0x80E0
+
+#define GLEW_NV_bgr GLEW_GET_VAR(__GLEW_NV_bgr)
+
+#endif /* GL_NV_bgr */
+
+/* ------------------- GL_NV_bindless_multi_draw_indirect ------------------ */
+
+#ifndef GL_NV_bindless_multi_draw_indirect
+#define GL_NV_bindless_multi_draw_indirect 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);
+
+#define glMultiDrawArraysIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessNV)
+#define glMultiDrawElementsIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessNV)
+
+#define GLEW_NV_bindless_multi_draw_indirect GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect)
+
+#endif /* GL_NV_bindless_multi_draw_indirect */
+
+/* ---------------- GL_NV_bindless_multi_draw_indirect_count --------------- */
+
+#ifndef GL_NV_bindless_multi_draw_indirect_count
+#define GL_NV_bindless_multi_draw_indirect_count 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLintptr drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount);
+
+#define glMultiDrawArraysIndirectBindlessCountNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessCountNV)
+#define glMultiDrawElementsIndirectBindlessCountNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessCountNV)
+
+#define GLEW_NV_bindless_multi_draw_indirect_count GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect_count)
+
+#endif /* GL_NV_bindless_multi_draw_indirect_count */
+
+/* ------------------------- GL_NV_bindless_texture ------------------------ */
+
+#ifndef GL_NV_bindless_texture
+#define GL_NV_bindless_texture 1
+
+typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler);
+typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64* value);
+
+#define glGetImageHandleNV GLEW_GET_FUN(__glewGetImageHandleNV)
+#define glGetTextureHandleNV GLEW_GET_FUN(__glewGetTextureHandleNV)
+#define glGetTextureSamplerHandleNV GLEW_GET_FUN(__glewGetTextureSamplerHandleNV)
+#define glIsImageHandleResidentNV GLEW_GET_FUN(__glewIsImageHandleResidentNV)
+#define glIsTextureHandleResidentNV GLEW_GET_FUN(__glewIsTextureHandleResidentNV)
+#define glMakeImageHandleNonResidentNV GLEW_GET_FUN(__glewMakeImageHandleNonResidentNV)
+#define glMakeImageHandleResidentNV GLEW_GET_FUN(__glewMakeImageHandleResidentNV)
+#define glMakeTextureHandleNonResidentNV GLEW_GET_FUN(__glewMakeTextureHandleNonResidentNV)
+#define glMakeTextureHandleResidentNV GLEW_GET_FUN(__glewMakeTextureHandleResidentNV)
+#define glProgramUniformHandleui64NV GLEW_GET_FUN(__glewProgramUniformHandleui64NV)
+#define glProgramUniformHandleui64vNV GLEW_GET_FUN(__glewProgramUniformHandleui64vNV)
+#define glUniformHandleui64NV GLEW_GET_FUN(__glewUniformHandleui64NV)
+#define glUniformHandleui64vNV GLEW_GET_FUN(__glewUniformHandleui64vNV)
+
+#define GLEW_NV_bindless_texture GLEW_GET_VAR(__GLEW_NV_bindless_texture)
+
+#endif /* GL_NV_bindless_texture */
+
+/* --------------------- GL_NV_blend_equation_advanced --------------------- */
+
+#ifndef GL_NV_blend_equation_advanced
+#define GL_NV_blend_equation_advanced 1
+
+#define GL_XOR_NV 0x1506
+#define GL_RED_NV 0x1903
+#define GL_GREEN_NV 0x1904
+#define GL_BLUE_NV 0x1905
+#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280
+#define GL_BLEND_OVERLAP_NV 0x9281
+#define GL_UNCORRELATED_NV 0x9282
+#define GL_DISJOINT_NV 0x9283
+#define GL_CONJOINT_NV 0x9284
+#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285
+#define GL_SRC_NV 0x9286
+#define GL_DST_NV 0x9287
+#define GL_SRC_OVER_NV 0x9288
+#define GL_DST_OVER_NV 0x9289
+#define GL_SRC_IN_NV 0x928A
+#define GL_DST_IN_NV 0x928B
+#define GL_SRC_OUT_NV 0x928C
+#define GL_DST_OUT_NV 0x928D
+#define GL_SRC_ATOP_NV 0x928E
+#define GL_DST_ATOP_NV 0x928F
+#define GL_PLUS_NV 0x9291
+#define GL_PLUS_DARKER_NV 0x9292
+#define GL_MULTIPLY_NV 0x9294
+#define GL_SCREEN_NV 0x9295
+#define GL_OVERLAY_NV 0x9296
+#define GL_DARKEN_NV 0x9297
+#define GL_LIGHTEN_NV 0x9298
+#define GL_COLORDODGE_NV 0x9299
+#define GL_COLORBURN_NV 0x929A
+#define GL_HARDLIGHT_NV 0x929B
+#define GL_SOFTLIGHT_NV 0x929C
+#define GL_DIFFERENCE_NV 0x929E
+#define GL_MINUS_NV 0x929F
+#define GL_EXCLUSION_NV 0x92A0
+#define GL_CONTRAST_NV 0x92A1
+#define GL_INVERT_RGB_NV 0x92A3
+#define GL_LINEARDODGE_NV 0x92A4
+#define GL_LINEARBURN_NV 0x92A5
+#define GL_VIVIDLIGHT_NV 0x92A6
+#define GL_LINEARLIGHT_NV 0x92A7
+#define GL_PINLIGHT_NV 0x92A8
+#define GL_HARDMIX_NV 0x92A9
+#define GL_HSL_HUE_NV 0x92AD
+#define GL_HSL_SATURATION_NV 0x92AE
+#define GL_HSL_COLOR_NV 0x92AF
+#define GL_HSL_LUMINOSITY_NV 0x92B0
+#define GL_PLUS_CLAMPED_NV 0x92B1
+#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2
+#define GL_MINUS_CLAMPED_NV 0x92B3
+#define GL_INVERT_OVG_NV 0x92B4
+
+typedef void (GLAPIENTRY * PFNGLBLENDBARRIERNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value);
+
+#define glBlendBarrierNV GLEW_GET_FUN(__glewBlendBarrierNV)
+#define glBlendParameteriNV GLEW_GET_FUN(__glewBlendParameteriNV)
+
+#define GLEW_NV_blend_equation_advanced GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced)
+
+#endif /* GL_NV_blend_equation_advanced */
+
+/* ----------------- GL_NV_blend_equation_advanced_coherent ---------------- */
+
+#ifndef GL_NV_blend_equation_advanced_coherent
+#define GL_NV_blend_equation_advanced_coherent 1
+
+#define GLEW_NV_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced_coherent)
+
+#endif /* GL_NV_blend_equation_advanced_coherent */
+
+/* ----------------------- GL_NV_blend_minmax_factor ----------------------- */
+
+#ifndef GL_NV_blend_minmax_factor
+#define GL_NV_blend_minmax_factor 1
+
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+
+#define GLEW_NV_blend_minmax_factor GLEW_GET_VAR(__GLEW_NV_blend_minmax_factor)
+
+#endif /* GL_NV_blend_minmax_factor */
+
+/* --------------------------- GL_NV_blend_square -------------------------- */
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+
+#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square)
+
+#endif /* GL_NV_blend_square */
+
+/* ----------------------- GL_NV_clip_space_w_scaling ---------------------- */
+
+#ifndef GL_NV_clip_space_w_scaling
+#define GL_NV_clip_space_w_scaling 1
+
+#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C
+#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D
+#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E
+
+typedef void (GLAPIENTRY * PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff);
+
+#define glViewportPositionWScaleNV GLEW_GET_FUN(__glewViewportPositionWScaleNV)
+
+#define GLEW_NV_clip_space_w_scaling GLEW_GET_VAR(__GLEW_NV_clip_space_w_scaling)
+
+#endif /* GL_NV_clip_space_w_scaling */
+
+/* --------------------------- GL_NV_command_list -------------------------- */
+
+#ifndef GL_NV_command_list
+#define GL_NV_command_list 1
+
+#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000
+#define GL_NOP_COMMAND_NV 0x0001
+#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002
+#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003
+#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004
+#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005
+#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006
+#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007
+#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008
+#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009
+#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000a
+#define GL_BLEND_COLOR_COMMAND_NV 0x000b
+#define GL_STENCIL_REF_COMMAND_NV 0x000c
+#define GL_LINE_WIDTH_COMMAND_NV 0x000d
+#define GL_POLYGON_OFFSET_COMMAND_NV 0x000e
+#define GL_ALPHA_REF_COMMAND_NV 0x000f
+#define GL_VIEWPORT_COMMAND_NV 0x0010
+#define GL_SCISSOR_COMMAND_NV 0x0011
+#define GL_FRONT_FACE_COMMAND_NV 0x0012
+
+typedef void (GLAPIENTRY * PFNGLCALLCOMMANDLISTNVPROC) (GLuint list);
+typedef void (GLAPIENTRY * PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments);
+typedef void (GLAPIENTRY * PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list);
+typedef void (GLAPIENTRY * PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint* lists);
+typedef void (GLAPIENTRY * PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint* states);
+typedef void (GLAPIENTRY * PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint* lists);
+typedef void (GLAPIENTRY * PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint* states);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64* indirects, const GLsizei* sizes, GLuint count);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, GLuint count);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count);
+typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count);
+typedef GLuint (GLAPIENTRY * PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size);
+typedef GLushort (GLAPIENTRY * PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype);
+typedef GLboolean (GLAPIENTRY * PFNGLISCOMMANDLISTNVPROC) (GLuint list);
+typedef GLboolean (GLAPIENTRY * PFNGLISSTATENVPROC) (GLuint state);
+typedef void (GLAPIENTRY * PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void** indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count);
+typedef void (GLAPIENTRY * PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode);
+
+#define glCallCommandListNV GLEW_GET_FUN(__glewCallCommandListNV)
+#define glCommandListSegmentsNV GLEW_GET_FUN(__glewCommandListSegmentsNV)
+#define glCompileCommandListNV GLEW_GET_FUN(__glewCompileCommandListNV)
+#define glCreateCommandListsNV GLEW_GET_FUN(__glewCreateCommandListsNV)
+#define glCreateStatesNV GLEW_GET_FUN(__glewCreateStatesNV)
+#define glDeleteCommandListsNV GLEW_GET_FUN(__glewDeleteCommandListsNV)
+#define glDeleteStatesNV GLEW_GET_FUN(__glewDeleteStatesNV)
+#define glDrawCommandsAddressNV GLEW_GET_FUN(__glewDrawCommandsAddressNV)
+#define glDrawCommandsNV GLEW_GET_FUN(__glewDrawCommandsNV)
+#define glDrawCommandsStatesAddressNV GLEW_GET_FUN(__glewDrawCommandsStatesAddressNV)
+#define glDrawCommandsStatesNV GLEW_GET_FUN(__glewDrawCommandsStatesNV)
+#define glGetCommandHeaderNV GLEW_GET_FUN(__glewGetCommandHeaderNV)
+#define glGetStageIndexNV GLEW_GET_FUN(__glewGetStageIndexNV)
+#define glIsCommandListNV GLEW_GET_FUN(__glewIsCommandListNV)
+#define glIsStateNV GLEW_GET_FUN(__glewIsStateNV)
+#define glListDrawCommandsStatesClientNV GLEW_GET_FUN(__glewListDrawCommandsStatesClientNV)
+#define glStateCaptureNV GLEW_GET_FUN(__glewStateCaptureNV)
+
+#define GLEW_NV_command_list GLEW_GET_VAR(__GLEW_NV_command_list)
+
+#endif /* GL_NV_command_list */
+
+/* ------------------------- GL_NV_compute_program5 ------------------------ */
+
+#ifndef GL_NV_compute_program5
+#define GL_NV_compute_program5 1
+
+#define GL_COMPUTE_PROGRAM_NV 0x90FB
+#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC
+
+#define GLEW_NV_compute_program5 GLEW_GET_VAR(__GLEW_NV_compute_program5)
+
+#endif /* GL_NV_compute_program5 */
+
+/* ------------------------ GL_NV_conditional_render ----------------------- */
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+
+typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void);
+
+#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV)
+#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV)
+
+#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render)
+
+#endif /* GL_NV_conditional_render */
+
+/* ----------------------- GL_NV_conservative_raster ----------------------- */
+
+#ifndef GL_NV_conservative_raster
+#define GL_NV_conservative_raster 1
+
+#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
+#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347
+#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348
+#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349
+
+typedef void (GLAPIENTRY * PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits);
+
+#define glSubpixelPrecisionBiasNV GLEW_GET_FUN(__glewSubpixelPrecisionBiasNV)
+
+#define GLEW_NV_conservative_raster GLEW_GET_VAR(__GLEW_NV_conservative_raster)
+
+#endif /* GL_NV_conservative_raster */
+
+/* -------------------- GL_NV_conservative_raster_dilate ------------------- */
+
+#ifndef GL_NV_conservative_raster_dilate
+#define GL_NV_conservative_raster_dilate 1
+
+#define GL_CONSERVATIVE_RASTER_DILATE_NV 0x9379
+#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A
+#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B
+
+typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) (GLenum pname, GLfloat value);
+
+#define glConservativeRasterParameterfNV GLEW_GET_FUN(__glewConservativeRasterParameterfNV)
+
+#define GLEW_NV_conservative_raster_dilate GLEW_GET_VAR(__GLEW_NV_conservative_raster_dilate)
+
+#endif /* GL_NV_conservative_raster_dilate */
+
+/* -------------- GL_NV_conservative_raster_pre_snap_triangles ------------- */
+
+#ifndef GL_NV_conservative_raster_pre_snap_triangles
+#define GL_NV_conservative_raster_pre_snap_triangles 1
+
+#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D
+#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E
+#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F
+
+typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param);
+
+#define glConservativeRasterParameteriNV GLEW_GET_FUN(__glewConservativeRasterParameteriNV)
+
+#define GLEW_NV_conservative_raster_pre_snap_triangles GLEW_GET_VAR(__GLEW_NV_conservative_raster_pre_snap_triangles)
+
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+
+/* --------------------------- GL_NV_copy_buffer --------------------------- */
+
+#ifndef GL_NV_copy_buffer
+#define GL_NV_copy_buffer 1
+
+#define GL_COPY_READ_BUFFER_NV 0x8F36
+#define GL_COPY_WRITE_BUFFER_NV 0x8F37
+
+typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size);
+
+#define glCopyBufferSubDataNV GLEW_GET_FUN(__glewCopyBufferSubDataNV)
+
+#define GLEW_NV_copy_buffer GLEW_GET_VAR(__GLEW_NV_copy_buffer)
+
+#endif /* GL_NV_copy_buffer */
+
+/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_NV_copy_depth_to_color 1
+
+#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+
+#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color)
+
+#endif /* GL_NV_copy_depth_to_color */
+
+/* ---------------------------- GL_NV_copy_image --------------------------- */
+
+#ifndef GL_NV_copy_image
+#define GL_NV_copy_image 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV)
+
+#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image)
+
+#endif /* GL_NV_copy_image */
+
+/* -------------------------- GL_NV_deep_texture3D ------------------------- */
+
+#ifndef GL_NV_deep_texture3D
+#define GL_NV_deep_texture3D 1
+
+#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0
+#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1
+
+#define GLEW_NV_deep_texture3D GLEW_GET_VAR(__GLEW_NV_deep_texture3D)
+
+#endif /* GL_NV_deep_texture3D */
+
+/* ------------------------ GL_NV_depth_buffer_float ----------------------- */
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_NV_depth_buffer_float 1
+
+#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);
+typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);
+
+#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV)
+#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV)
+#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV)
+
+#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float)
+
+#endif /* GL_NV_depth_buffer_float */
+
+/* --------------------------- GL_NV_depth_clamp --------------------------- */
+
+#ifndef GL_NV_depth_clamp
+#define GL_NV_depth_clamp 1
+
+#define GL_DEPTH_CLAMP_NV 0x864F
+
+#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp)
+
+#endif /* GL_NV_depth_clamp */
+
+/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */
+
+#ifndef GL_NV_depth_range_unclamped
+#define GL_NV_depth_range_unclamped 1
+
+#define GL_SAMPLE_COUNT_BITS_NV 0x8864
+#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865
+#define GL_QUERY_RESULT_NV 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867
+#define GL_SAMPLE_COUNT_NV 0x8914
+
+#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped)
+
+#endif /* GL_NV_depth_range_unclamped */
+
+/* --------------------------- GL_NV_draw_buffers -------------------------- */
+
+#ifndef GL_NV_draw_buffers
+#define GL_NV_draw_buffers 1
+
+#define GL_MAX_DRAW_BUFFERS_NV 0x8824
+#define GL_DRAW_BUFFER0_NV 0x8825
+#define GL_DRAW_BUFFER1_NV 0x8826
+#define GL_DRAW_BUFFER2_NV 0x8827
+#define GL_DRAW_BUFFER3_NV 0x8828
+#define GL_DRAW_BUFFER4_NV 0x8829
+#define GL_DRAW_BUFFER5_NV 0x882A
+#define GL_DRAW_BUFFER6_NV 0x882B
+#define GL_DRAW_BUFFER7_NV 0x882C
+#define GL_DRAW_BUFFER8_NV 0x882D
+#define GL_DRAW_BUFFER9_NV 0x882E
+#define GL_DRAW_BUFFER10_NV 0x882F
+#define GL_DRAW_BUFFER11_NV 0x8830
+#define GL_DRAW_BUFFER12_NV 0x8831
+#define GL_DRAW_BUFFER13_NV 0x8832
+#define GL_DRAW_BUFFER14_NV 0x8833
+#define GL_DRAW_BUFFER15_NV 0x8834
+#define GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
+
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum* bufs);
+
+#define glDrawBuffersNV GLEW_GET_FUN(__glewDrawBuffersNV)
+
+#define GLEW_NV_draw_buffers GLEW_GET_VAR(__GLEW_NV_draw_buffers)
+
+#endif /* GL_NV_draw_buffers */
+
+/* -------------------------- GL_NV_draw_instanced ------------------------- */
+
+#ifndef GL_NV_draw_instanced
+#define GL_NV_draw_instanced 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+
+#define glDrawArraysInstancedNV GLEW_GET_FUN(__glewDrawArraysInstancedNV)
+#define glDrawElementsInstancedNV GLEW_GET_FUN(__glewDrawElementsInstancedNV)
+
+#define GLEW_NV_draw_instanced GLEW_GET_VAR(__GLEW_NV_draw_instanced)
+
+#endif /* GL_NV_draw_instanced */
+
+/* --------------------------- GL_NV_draw_texture -------------------------- */
+
+#ifndef GL_NV_draw_texture
+#define GL_NV_draw_texture 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+
+#define glDrawTextureNV GLEW_GET_FUN(__glewDrawTextureNV)
+
+#define GLEW_NV_draw_texture GLEW_GET_VAR(__GLEW_NV_draw_texture)
+
+#endif /* GL_NV_draw_texture */
+
+/* ------------------------ GL_NV_draw_vulkan_image ------------------------ */
+
+#ifndef GL_NV_draw_vulkan_image
+#define GL_NV_draw_vulkan_image 1
+
+typedef void (APIENTRY *GLVULKANPROCNV)(void);
+
+typedef void (GLAPIENTRY * PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+typedef GLVULKANPROCNV (GLAPIENTRY * PFNGLGETVKPROCADDRNVPROC) (const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence);
+typedef void (GLAPIENTRY * PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+typedef void (GLAPIENTRY * PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+
+#define glDrawVkImageNV GLEW_GET_FUN(__glewDrawVkImageNV)
+#define glGetVkProcAddrNV GLEW_GET_FUN(__glewGetVkProcAddrNV)
+#define glSignalVkFenceNV GLEW_GET_FUN(__glewSignalVkFenceNV)
+#define glSignalVkSemaphoreNV GLEW_GET_FUN(__glewSignalVkSemaphoreNV)
+#define glWaitVkSemaphoreNV GLEW_GET_FUN(__glewWaitVkSemaphoreNV)
+
+#define GLEW_NV_draw_vulkan_image GLEW_GET_VAR(__GLEW_NV_draw_vulkan_image)
+
+#endif /* GL_NV_draw_vulkan_image */
+
+/* ---------------------------- GL_NV_evaluators --------------------------- */
+
+#ifndef GL_NV_evaluators
+#define GL_NV_evaluators 1
+
+#define GL_EVAL_2D_NV 0x86C0
+#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define GL_MAP_TESSELLATION_NV 0x86C2
+#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+
+typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points);
+typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points);
+typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params);
+
+#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV)
+#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV)
+#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV)
+#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV)
+#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV)
+#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV)
+#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV)
+#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV)
+#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV)
+
+#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators)
+
+#endif /* GL_NV_evaluators */
+
+/* --------------------- GL_NV_explicit_attrib_location -------------------- */
+
+#ifndef GL_NV_explicit_attrib_location
+#define GL_NV_explicit_attrib_location 1
+
+#define GLEW_NV_explicit_attrib_location GLEW_GET_VAR(__GLEW_NV_explicit_attrib_location)
+
+#endif /* GL_NV_explicit_attrib_location */
+
+/* ----------------------- GL_NV_explicit_multisample ---------------------- */
+
+#ifndef GL_NV_explicit_multisample
+#define GL_NV_explicit_multisample 1
+
+#define GL_SAMPLE_POSITION_NV 0x8E50
+#define GL_SAMPLE_MASK_NV 0x8E51
+#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
+#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
+#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
+#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
+#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
+
+typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val);
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer);
+
+#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV)
+#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV)
+#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV)
+
+#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample)
+
+#endif /* GL_NV_explicit_multisample */
+
+/* ---------------------- GL_NV_fbo_color_attachments ---------------------- */
+
+#ifndef GL_NV_fbo_color_attachments
+#define GL_NV_fbo_color_attachments 1
+
+#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
+#define GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
+
+#define GLEW_NV_fbo_color_attachments GLEW_GET_VAR(__GLEW_NV_fbo_color_attachments)
+
+#endif /* GL_NV_fbo_color_attachments */
+
+/* ------------------------------ GL_NV_fence ------------------------------ */
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+
+typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences);
+typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences);
+typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence);
+
+#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV)
+#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV)
+#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV)
+#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV)
+#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV)
+#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV)
+#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV)
+
+#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence)
+
+#endif /* GL_NV_fence */
+
+/* -------------------------- GL_NV_fill_rectangle ------------------------- */
+
+#ifndef GL_NV_fill_rectangle
+#define GL_NV_fill_rectangle 1
+
+#define GL_FILL_RECTANGLE_NV 0x933C
+
+#define GLEW_NV_fill_rectangle GLEW_GET_VAR(__GLEW_NV_fill_rectangle)
+
+#endif /* GL_NV_fill_rectangle */
+
+/* --------------------------- GL_NV_float_buffer -------------------------- */
+
+#ifndef GL_NV_float_buffer
+#define GL_NV_float_buffer 1
+
+#define GL_FLOAT_R_NV 0x8880
+#define GL_FLOAT_RG_NV 0x8881
+#define GL_FLOAT_RGB_NV 0x8882
+#define GL_FLOAT_RGBA_NV 0x8883
+#define GL_FLOAT_R16_NV 0x8884
+#define GL_FLOAT_R32_NV 0x8885
+#define GL_FLOAT_RG16_NV 0x8886
+#define GL_FLOAT_RG32_NV 0x8887
+#define GL_FLOAT_RGB16_NV 0x8888
+#define GL_FLOAT_RGB32_NV 0x8889
+#define GL_FLOAT_RGBA16_NV 0x888A
+#define GL_FLOAT_RGBA32_NV 0x888B
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define GL_FLOAT_RGBA_MODE_NV 0x888E
+
+#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer)
+
+#endif /* GL_NV_float_buffer */
+
+/* --------------------------- GL_NV_fog_distance -------------------------- */
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+
+#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance)
+
+#endif /* GL_NV_fog_distance */
+
+/* -------------------- GL_NV_fragment_coverage_to_color ------------------- */
+
+#ifndef GL_NV_fragment_coverage_to_color
+#define GL_NV_fragment_coverage_to_color 1
+
+#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD
+#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE
+
+typedef void (GLAPIENTRY * PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color);
+
+#define glFragmentCoverageColorNV GLEW_GET_FUN(__glewFragmentCoverageColorNV)
+
+#define GLEW_NV_fragment_coverage_to_color GLEW_GET_VAR(__GLEW_NV_fragment_coverage_to_color)
+
+#endif /* GL_NV_fragment_coverage_to_color */
+
+/* ------------------------- GL_NV_fragment_program ------------------------ */
+
+#ifndef GL_NV_fragment_program
+#define GL_NV_fragment_program 1
+
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_FRAGMENT_PROGRAM_NV 0x8870
+#define GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define GL_PROGRAM_ERROR_STRING_NV 0x8874
+
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]);
+
+#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV)
+#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV)
+#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV)
+#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV)
+#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV)
+#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV)
+
+#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program)
+
+#endif /* GL_NV_fragment_program */
+
+/* ------------------------ GL_NV_fragment_program2 ------------------------ */
+
+#ifndef GL_NV_fragment_program2
+#define GL_NV_fragment_program2 1
+
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+
+#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2)
+
+#endif /* GL_NV_fragment_program2 */
+
+/* ------------------------ GL_NV_fragment_program4 ------------------------ */
+
+#ifndef GL_NV_fragment_program4
+#define GL_NV_fragment_program4 1
+
+#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4)
+
+#endif /* GL_NV_fragment_program4 */
+
+/* --------------------- GL_NV_fragment_program_option --------------------- */
+
+#ifndef GL_NV_fragment_program_option
+#define GL_NV_fragment_program_option 1
+
+#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option)
+
+#endif /* GL_NV_fragment_program_option */
+
+/* -------------------- GL_NV_fragment_shader_interlock -------------------- */
+
+#ifndef GL_NV_fragment_shader_interlock
+#define GL_NV_fragment_shader_interlock 1
+
+#define GLEW_NV_fragment_shader_interlock GLEW_GET_VAR(__GLEW_NV_fragment_shader_interlock)
+
+#endif /* GL_NV_fragment_shader_interlock */
+
+/* ------------------------- GL_NV_framebuffer_blit ------------------------ */
+
+#ifndef GL_NV_framebuffer_blit
+#define GL_NV_framebuffer_blit 1
+
+#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
+#define GL_READ_FRAMEBUFFER_NV 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA
+
+typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+
+#define glBlitFramebufferNV GLEW_GET_FUN(__glewBlitFramebufferNV)
+
+#define GLEW_NV_framebuffer_blit GLEW_GET_VAR(__GLEW_NV_framebuffer_blit)
+
+#endif /* GL_NV_framebuffer_blit */
+
+/* -------------------- GL_NV_framebuffer_mixed_samples -------------------- */
+
+#ifndef GL_NV_framebuffer_mixed_samples
+#define GL_NV_framebuffer_mixed_samples 1
+
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#define GL_RASTER_MULTISAMPLE_EXT 0x9327
+#define GL_RASTER_SAMPLES_EXT 0x9328
+#define GL_MAX_RASTER_SAMPLES_EXT 0x9329
+#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A
+#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B
+#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C
+#define GL_DEPTH_SAMPLES_NV 0x932D
+#define GL_STENCIL_SAMPLES_NV 0x932E
+#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F
+#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330
+#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331
+#define GL_COVERAGE_MODULATION_NV 0x9332
+#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333
+
+#define GLEW_NV_framebuffer_mixed_samples GLEW_GET_VAR(__GLEW_NV_framebuffer_mixed_samples)
+
+#endif /* GL_NV_framebuffer_mixed_samples */
+
+/* --------------------- GL_NV_framebuffer_multisample --------------------- */
+
+#ifndef GL_NV_framebuffer_multisample
+#define GL_NV_framebuffer_multisample 1
+
+#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56
+#define GL_MAX_SAMPLES_NV 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glRenderbufferStorageMultisampleNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleNV)
+
+#define GLEW_NV_framebuffer_multisample GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample)
+
+#endif /* GL_NV_framebuffer_multisample */
+
+/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_NV_framebuffer_multisample_coverage 1
+
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV)
+
+#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage)
+
+#endif /* GL_NV_framebuffer_multisample_coverage */
+
+/* ----------------------- GL_NV_generate_mipmap_sRGB ---------------------- */
+
+#ifndef GL_NV_generate_mipmap_sRGB
+#define GL_NV_generate_mipmap_sRGB 1
+
+#define GLEW_NV_generate_mipmap_sRGB GLEW_GET_VAR(__GLEW_NV_generate_mipmap_sRGB)
+
+#endif /* GL_NV_generate_mipmap_sRGB */
+
+/* ------------------------ GL_NV_geometry_program4 ------------------------ */
+
+#ifndef GL_NV_geometry_program4
+#define GL_NV_geometry_program4 1
+
+#define GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit);
+
+#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV)
+
+#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4)
+
+#endif /* GL_NV_geometry_program4 */
+
+/* ------------------------- GL_NV_geometry_shader4 ------------------------ */
+
+#ifndef GL_NV_geometry_shader4
+#define GL_NV_geometry_shader4 1
+
+#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4)
+
+#endif /* GL_NV_geometry_shader4 */
+
+/* ------------------- GL_NV_geometry_shader_passthrough ------------------- */
+
+#ifndef GL_NV_geometry_shader_passthrough
+#define GL_NV_geometry_shader_passthrough 1
+
+#define GLEW_NV_geometry_shader_passthrough GLEW_GET_VAR(__GLEW_NV_geometry_shader_passthrough)
+
+#endif /* GL_NV_geometry_shader_passthrough */
+
+/* -------------------------- GL_NV_gpu_multicast -------------------------- */
+
+#ifndef GL_NV_gpu_multicast
+#define GL_NV_gpu_multicast 1
+
+#define GL_PER_GPU_STORAGE_BIT_NV 0x0800
+#define GL_MULTICAST_GPUS_NV 0x92BA
+#define GL_PER_GPU_STORAGE_NV 0x9548
+#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549
+#define GL_RENDER_GPU_MASK_NV 0x9558
+
+typedef void (GLAPIENTRY * PFNGLMULTICASTBARRIERNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GLAPIENTRY * PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
+typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+typedef void (GLAPIENTRY * PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGpu, GLbitfield waitGpuMask);
+typedef void (GLAPIENTRY * PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask);
+
+#define glMulticastBarrierNV GLEW_GET_FUN(__glewMulticastBarrierNV)
+#define glMulticastBlitFramebufferNV GLEW_GET_FUN(__glewMulticastBlitFramebufferNV)
+#define glMulticastBufferSubDataNV GLEW_GET_FUN(__glewMulticastBufferSubDataNV)
+#define glMulticastCopyBufferSubDataNV GLEW_GET_FUN(__glewMulticastCopyBufferSubDataNV)
+#define glMulticastCopyImageSubDataNV GLEW_GET_FUN(__glewMulticastCopyImageSubDataNV)
+#define glMulticastFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewMulticastFramebufferSampleLocationsfvNV)
+#define glMulticastGetQueryObjecti64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjecti64vNV)
+#define glMulticastGetQueryObjectivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectivNV)
+#define glMulticastGetQueryObjectui64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjectui64vNV)
+#define glMulticastGetQueryObjectuivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectuivNV)
+#define glMulticastWaitSyncNV GLEW_GET_FUN(__glewMulticastWaitSyncNV)
+#define glRenderGpuMaskNV GLEW_GET_FUN(__glewRenderGpuMaskNV)
+
+#define GLEW_NV_gpu_multicast GLEW_GET_VAR(__GLEW_NV_gpu_multicast)
+
+#endif /* GL_NV_gpu_multicast */
+
+/* --------------------------- GL_NV_gpu_program4 -------------------------- */
+
+#ifndef GL_NV_gpu_program4
+#define GL_NV_gpu_program4 1
+
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+
+#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV)
+#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV)
+#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV)
+#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV)
+#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV)
+#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV)
+#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV)
+#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV)
+#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV)
+#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV)
+#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV)
+#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV)
+
+#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4)
+
+#endif /* GL_NV_gpu_program4 */
+
+/* --------------------------- GL_NV_gpu_program5 -------------------------- */
+
+#ifndef GL_NV_gpu_program5
+#define GL_NV_gpu_program5 1
+
+#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F
+
+#define GLEW_NV_gpu_program5 GLEW_GET_VAR(__GLEW_NV_gpu_program5)
+
+#endif /* GL_NV_gpu_program5 */
+
+/* -------------------- GL_NV_gpu_program5_mem_extended -------------------- */
+
+#ifndef GL_NV_gpu_program5_mem_extended
+#define GL_NV_gpu_program5_mem_extended 1
+
+#define GLEW_NV_gpu_program5_mem_extended GLEW_GET_VAR(__GLEW_NV_gpu_program5_mem_extended)
+
+#endif /* GL_NV_gpu_program5_mem_extended */
+
+/* ------------------------- GL_NV_gpu_program_fp64 ------------------------ */
+
+#ifndef GL_NV_gpu_program_fp64
+#define GL_NV_gpu_program_fp64 1
+
+#define GLEW_NV_gpu_program_fp64 GLEW_GET_VAR(__GLEW_NV_gpu_program_fp64)
+
+#endif /* GL_NV_gpu_program_fp64 */
+
+/* --------------------------- GL_NV_gpu_shader5 --------------------------- */
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+
+#define glGetUniformi64vNV GLEW_GET_FUN(__glewGetUniformi64vNV)
+#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV)
+#define glProgramUniform1i64NV GLEW_GET_FUN(__glewProgramUniform1i64NV)
+#define glProgramUniform1i64vNV GLEW_GET_FUN(__glewProgramUniform1i64vNV)
+#define glProgramUniform1ui64NV GLEW_GET_FUN(__glewProgramUniform1ui64NV)
+#define glProgramUniform1ui64vNV GLEW_GET_FUN(__glewProgramUniform1ui64vNV)
+#define glProgramUniform2i64NV GLEW_GET_FUN(__glewProgramUniform2i64NV)
+#define glProgramUniform2i64vNV GLEW_GET_FUN(__glewProgramUniform2i64vNV)
+#define glProgramUniform2ui64NV GLEW_GET_FUN(__glewProgramUniform2ui64NV)
+#define glProgramUniform2ui64vNV GLEW_GET_FUN(__glewProgramUniform2ui64vNV)
+#define glProgramUniform3i64NV GLEW_GET_FUN(__glewProgramUniform3i64NV)
+#define glProgramUniform3i64vNV GLEW_GET_FUN(__glewProgramUniform3i64vNV)
+#define glProgramUniform3ui64NV GLEW_GET_FUN(__glewProgramUniform3ui64NV)
+#define glProgramUniform3ui64vNV GLEW_GET_FUN(__glewProgramUniform3ui64vNV)
+#define glProgramUniform4i64NV GLEW_GET_FUN(__glewProgramUniform4i64NV)
+#define glProgramUniform4i64vNV GLEW_GET_FUN(__glewProgramUniform4i64vNV)
+#define glProgramUniform4ui64NV GLEW_GET_FUN(__glewProgramUniform4ui64NV)
+#define glProgramUniform4ui64vNV GLEW_GET_FUN(__glewProgramUniform4ui64vNV)
+#define glUniform1i64NV GLEW_GET_FUN(__glewUniform1i64NV)
+#define glUniform1i64vNV GLEW_GET_FUN(__glewUniform1i64vNV)
+#define glUniform1ui64NV GLEW_GET_FUN(__glewUniform1ui64NV)
+#define glUniform1ui64vNV GLEW_GET_FUN(__glewUniform1ui64vNV)
+#define glUniform2i64NV GLEW_GET_FUN(__glewUniform2i64NV)
+#define glUniform2i64vNV GLEW_GET_FUN(__glewUniform2i64vNV)
+#define glUniform2ui64NV GLEW_GET_FUN(__glewUniform2ui64NV)
+#define glUniform2ui64vNV GLEW_GET_FUN(__glewUniform2ui64vNV)
+#define glUniform3i64NV GLEW_GET_FUN(__glewUniform3i64NV)
+#define glUniform3i64vNV GLEW_GET_FUN(__glewUniform3i64vNV)
+#define glUniform3ui64NV GLEW_GET_FUN(__glewUniform3ui64NV)
+#define glUniform3ui64vNV GLEW_GET_FUN(__glewUniform3ui64vNV)
+#define glUniform4i64NV GLEW_GET_FUN(__glewUniform4i64NV)
+#define glUniform4i64vNV GLEW_GET_FUN(__glewUniform4i64vNV)
+#define glUniform4ui64NV GLEW_GET_FUN(__glewUniform4ui64NV)
+#define glUniform4ui64vNV GLEW_GET_FUN(__glewUniform4ui64vNV)
+
+#define GLEW_NV_gpu_shader5 GLEW_GET_VAR(__GLEW_NV_gpu_shader5)
+
+#endif /* GL_NV_gpu_shader5 */
+
+/* ---------------------------- GL_NV_half_float --------------------------- */
+
+#ifndef GL_NV_half_float
+#define GL_NV_half_float 1
+
+#define GL_HALF_FLOAT_NV 0x140B
+
+typedef unsigned short GLhalf;
+
+typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz);
+typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y);
+typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z);
+typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w);
+typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight);
+
+#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV)
+#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV)
+#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV)
+#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV)
+#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV)
+#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV)
+#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV)
+#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV)
+#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV)
+#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV)
+#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV)
+#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV)
+#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV)
+#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV)
+#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV)
+#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV)
+#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV)
+#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV)
+#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV)
+#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV)
+#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV)
+#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV)
+#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV)
+#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV)
+#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV)
+#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV)
+#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV)
+#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV)
+#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV)
+#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV)
+#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV)
+#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV)
+#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV)
+#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV)
+#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV)
+#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV)
+#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV)
+#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV)
+#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV)
+#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV)
+#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV)
+#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV)
+#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV)
+#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV)
+#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV)
+#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV)
+
+#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float)
+
+#endif /* GL_NV_half_float */
+
+/* -------------------------- GL_NV_image_formats -------------------------- */
+
+#ifndef GL_NV_image_formats
+#define GL_NV_image_formats 1
+
+#define GLEW_NV_image_formats GLEW_GET_VAR(__GLEW_NV_image_formats)
+
+#endif /* GL_NV_image_formats */
+
+/* ------------------------- GL_NV_instanced_arrays ------------------------ */
+
+#ifndef GL_NV_instanced_arrays
+#define GL_NV_instanced_arrays 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE
+
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor);
+
+#define glVertexAttribDivisorNV GLEW_GET_FUN(__glewVertexAttribDivisorNV)
+
+#define GLEW_NV_instanced_arrays GLEW_GET_VAR(__GLEW_NV_instanced_arrays)
+
+#endif /* GL_NV_instanced_arrays */
+
+/* ------------------- GL_NV_internalformat_sample_query ------------------- */
+
+#ifndef GL_NV_internalformat_sample_query
+#define GL_NV_internalformat_sample_query 1
+
+#define GL_MULTISAMPLES_NV 0x9371
+#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372
+#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373
+#define GL_CONFORMANT_NV 0x9374
+
+typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint* params);
+
+#define glGetInternalformatSampleivNV GLEW_GET_FUN(__glewGetInternalformatSampleivNV)
+
+#define GLEW_NV_internalformat_sample_query GLEW_GET_VAR(__GLEW_NV_internalformat_sample_query)
+
+#endif /* GL_NV_internalformat_sample_query */
+
+/* ------------------------ GL_NV_light_max_exponent ----------------------- */
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+
+#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent)
+
+#endif /* GL_NV_light_max_exponent */
+
+/* ----------------------- GL_NV_multisample_coverage ---------------------- */
+
+#ifndef GL_NV_multisample_coverage
+#define GL_NV_multisample_coverage 1
+
+#define GL_COLOR_SAMPLES_NV 0x8E20
+
+#define GLEW_NV_multisample_coverage GLEW_GET_VAR(__GLEW_NV_multisample_coverage)
+
+#endif /* GL_NV_multisample_coverage */
+
+/* --------------------- GL_NV_multisample_filter_hint --------------------- */
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_NV_multisample_filter_hint 1
+
+#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+
+#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint)
+
+#endif /* GL_NV_multisample_filter_hint */
+
+/* ----------------------- GL_NV_non_square_matrices ----------------------- */
+
+#ifndef GL_NV_non_square_matrices
+#define GL_NV_non_square_matrices 1
+
+#define GL_FLOAT_MAT2x3_NV 0x8B65
+#define GL_FLOAT_MAT2x4_NV 0x8B66
+#define GL_FLOAT_MAT3x2_NV 0x8B67
+#define GL_FLOAT_MAT3x4_NV 0x8B68
+#define GL_FLOAT_MAT4x2_NV 0x8B69
+#define GL_FLOAT_MAT4x3_NV 0x8B6A
+
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+
+#define glUniformMatrix2x3fvNV GLEW_GET_FUN(__glewUniformMatrix2x3fvNV)
+#define glUniformMatrix2x4fvNV GLEW_GET_FUN(__glewUniformMatrix2x4fvNV)
+#define glUniformMatrix3x2fvNV GLEW_GET_FUN(__glewUniformMatrix3x2fvNV)
+#define glUniformMatrix3x4fvNV GLEW_GET_FUN(__glewUniformMatrix3x4fvNV)
+#define glUniformMatrix4x2fvNV GLEW_GET_FUN(__glewUniformMatrix4x2fvNV)
+#define glUniformMatrix4x3fvNV GLEW_GET_FUN(__glewUniformMatrix4x3fvNV)
+
+#define GLEW_NV_non_square_matrices GLEW_GET_VAR(__GLEW_NV_non_square_matrices)
+
+#endif /* GL_NV_non_square_matrices */
+
+/* ------------------------- GL_NV_occlusion_query ------------------------- */
+
+#ifndef GL_NV_occlusion_query
+#define GL_NV_occlusion_query 1
+
+#define GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define GL_PIXEL_COUNT_NV 0x8866
+#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+
+typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id);
+
+#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV)
+#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV)
+#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV)
+#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV)
+#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV)
+#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV)
+#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV)
+
+#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query)
+
+#endif /* GL_NV_occlusion_query */
+
+/* -------------------------- GL_NV_pack_subimage -------------------------- */
+
+#ifndef GL_NV_pack_subimage
+#define GL_NV_pack_subimage 1
+
+#define GL_PACK_ROW_LENGTH_NV 0x0D02
+#define GL_PACK_SKIP_ROWS_NV 0x0D03
+#define GL_PACK_SKIP_PIXELS_NV 0x0D04
+
+#define GLEW_NV_pack_subimage GLEW_GET_VAR(__GLEW_NV_pack_subimage)
+
+#endif /* GL_NV_pack_subimage */
+
+/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_NV_packed_depth_stencil 1
+
+#define GL_DEPTH_STENCIL_NV 0x84F9
+#define GL_UNSIGNED_INT_24_8_NV 0x84FA
+
+#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil)
+
+#endif /* GL_NV_packed_depth_stencil */
+
+/* --------------------------- GL_NV_packed_float -------------------------- */
+
+#ifndef GL_NV_packed_float
+#define GL_NV_packed_float 1
+
+#define GL_R11F_G11F_B10F_NV 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_NV 0x8C3B
+
+#define GLEW_NV_packed_float GLEW_GET_VAR(__GLEW_NV_packed_float)
+
+#endif /* GL_NV_packed_float */
+
+/* ----------------------- GL_NV_packed_float_linear ----------------------- */
+
+#ifndef GL_NV_packed_float_linear
+#define GL_NV_packed_float_linear 1
+
+#define GL_R11F_G11F_B10F_NV 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_NV 0x8C3B
+
+#define GLEW_NV_packed_float_linear GLEW_GET_VAR(__GLEW_NV_packed_float_linear)
+
+#endif /* GL_NV_packed_float_linear */
+
+/* --------------------- GL_NV_parameter_buffer_object --------------------- */
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_NV_parameter_buffer_object 1
+
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+
+#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV)
+#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV)
+#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV)
+
+#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object)
+
+#endif /* GL_NV_parameter_buffer_object */
+
+/* --------------------- GL_NV_parameter_buffer_object2 -------------------- */
+
+#ifndef GL_NV_parameter_buffer_object2
+#define GL_NV_parameter_buffer_object2 1
+
+#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2)
+
+#endif /* GL_NV_parameter_buffer_object2 */
+
+/* -------------------------- GL_NV_path_rendering ------------------------- */
+
+#ifndef GL_NV_path_rendering
+#define GL_NV_path_rendering 1
+
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_BOLD_BIT_NV 0x01
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_MOVE_TO_NV 0x02
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_LINE_TO_NV 0x04
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_CONIC_CURVE_TO_NV 0x1A
+#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_ROUNDED_RECT_NV 0xE8
+#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9
+#define GL_ROUNDED_RECT2_NV 0xEA
+#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB
+#define GL_ROUNDED_RECT4_NV 0xEC
+#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED
+#define GL_ROUNDED_RECT8_NV 0xEE
+#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_RECT_NV 0xF6
+#define GL_RELATIVE_RECT_NV 0xF7
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_ARC_TO_NV 0xFE
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_FILE_NAME_NV 0x9074
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_PATH_STROKE_BOUND_NV 0x9086
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_UTF8_NV 0x909A
+#define GL_UTF16_NV 0x909B
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_SQUARE_NV 0x90A3
+#define GL_ROUND_NV 0x90A4
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_BEVEL_NV 0x90A6
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_PATH_FOG_GEN_MODE_NV 0x90AC
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368
+#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369
+#define GL_FONT_UNAVAILABLE_NV 0x936A
+#define GL_FONT_UNINTELLIGIBLE_NV 0x936B
+#define GL_STANDARD_FONT_FORMAT_NV 0x936C
+#define GL_FRAGMENT_INPUT_NV 0x936D
+#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000
+
+typedef void (GLAPIENTRY * PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath);
+typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GLAPIENTRY * PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range);
+typedef GLuint (GLAPIENTRY * PFNGLGENPATHSNVPROC) (GLsizei range);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte* commands);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat* coords);
+typedef void (GLAPIENTRY * PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat* dashArray);
+typedef GLfloat (GLAPIENTRY * PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments);
+typedef void (GLAPIENTRY * PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat* metrics);
+typedef void (GLAPIENTRY * PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint* value);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+typedef GLboolean (GLAPIENTRY * PFNGLISPATHNVPROC) (GLuint path);
+typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat* coeffs);
+typedef void (GLAPIENTRY * PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords);
+typedef void (GLAPIENTRY * PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GLAPIENTRY * PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum zfunc);
+typedef void (GLAPIENTRY * PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat* dashArray);
+typedef void (GLAPIENTRY * PFNGLPATHFOGGENNVPROC) (GLenum genMode);
+typedef GLenum (GLAPIENTRY * PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef GLenum (GLAPIENTRY * PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+typedef void (GLAPIENTRY * PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GLAPIENTRY * PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void*charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef GLenum (GLAPIENTRY * PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units);
+typedef void (GLAPIENTRY * PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString);
+typedef void (GLAPIENTRY * PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords);
+typedef void (GLAPIENTRY * PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GLAPIENTRY * PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat* coeffs);
+typedef GLboolean (GLAPIENTRY * PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat* x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat* coeffs);
+typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat* transformValues);
+typedef void (GLAPIENTRY * PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint paths[], const GLfloat weights[]);
+
+#define glCopyPathNV GLEW_GET_FUN(__glewCopyPathNV)
+#define glCoverFillPathInstancedNV GLEW_GET_FUN(__glewCoverFillPathInstancedNV)
+#define glCoverFillPathNV GLEW_GET_FUN(__glewCoverFillPathNV)
+#define glCoverStrokePathInstancedNV GLEW_GET_FUN(__glewCoverStrokePathInstancedNV)
+#define glCoverStrokePathNV GLEW_GET_FUN(__glewCoverStrokePathNV)
+#define glDeletePathsNV GLEW_GET_FUN(__glewDeletePathsNV)
+#define glGenPathsNV GLEW_GET_FUN(__glewGenPathsNV)
+#define glGetPathColorGenfvNV GLEW_GET_FUN(__glewGetPathColorGenfvNV)
+#define glGetPathColorGenivNV GLEW_GET_FUN(__glewGetPathColorGenivNV)
+#define glGetPathCommandsNV GLEW_GET_FUN(__glewGetPathCommandsNV)
+#define glGetPathCoordsNV GLEW_GET_FUN(__glewGetPathCoordsNV)
+#define glGetPathDashArrayNV GLEW_GET_FUN(__glewGetPathDashArrayNV)
+#define glGetPathLengthNV GLEW_GET_FUN(__glewGetPathLengthNV)
+#define glGetPathMetricRangeNV GLEW_GET_FUN(__glewGetPathMetricRangeNV)
+#define glGetPathMetricsNV GLEW_GET_FUN(__glewGetPathMetricsNV)
+#define glGetPathParameterfvNV GLEW_GET_FUN(__glewGetPathParameterfvNV)
+#define glGetPathParameterivNV GLEW_GET_FUN(__glewGetPathParameterivNV)
+#define glGetPathSpacingNV GLEW_GET_FUN(__glewGetPathSpacingNV)
+#define glGetPathTexGenfvNV GLEW_GET_FUN(__glewGetPathTexGenfvNV)
+#define glGetPathTexGenivNV GLEW_GET_FUN(__glewGetPathTexGenivNV)
+#define glGetProgramResourcefvNV GLEW_GET_FUN(__glewGetProgramResourcefvNV)
+#define glInterpolatePathsNV GLEW_GET_FUN(__glewInterpolatePathsNV)
+#define glIsPathNV GLEW_GET_FUN(__glewIsPathNV)
+#define glIsPointInFillPathNV GLEW_GET_FUN(__glewIsPointInFillPathNV)
+#define glIsPointInStrokePathNV GLEW_GET_FUN(__glewIsPointInStrokePathNV)
+#define glMatrixLoad3x2fNV GLEW_GET_FUN(__glewMatrixLoad3x2fNV)
+#define glMatrixLoad3x3fNV GLEW_GET_FUN(__glewMatrixLoad3x3fNV)
+#define glMatrixLoadTranspose3x3fNV GLEW_GET_FUN(__glewMatrixLoadTranspose3x3fNV)
+#define glMatrixMult3x2fNV GLEW_GET_FUN(__glewMatrixMult3x2fNV)
+#define glMatrixMult3x3fNV GLEW_GET_FUN(__glewMatrixMult3x3fNV)
+#define glMatrixMultTranspose3x3fNV GLEW_GET_FUN(__glewMatrixMultTranspose3x3fNV)
+#define glPathColorGenNV GLEW_GET_FUN(__glewPathColorGenNV)
+#define glPathCommandsNV GLEW_GET_FUN(__glewPathCommandsNV)
+#define glPathCoordsNV GLEW_GET_FUN(__glewPathCoordsNV)
+#define glPathCoverDepthFuncNV GLEW_GET_FUN(__glewPathCoverDepthFuncNV)
+#define glPathDashArrayNV GLEW_GET_FUN(__glewPathDashArrayNV)
+#define glPathFogGenNV GLEW_GET_FUN(__glewPathFogGenNV)
+#define glPathGlyphIndexArrayNV GLEW_GET_FUN(__glewPathGlyphIndexArrayNV)
+#define glPathGlyphIndexRangeNV GLEW_GET_FUN(__glewPathGlyphIndexRangeNV)
+#define glPathGlyphRangeNV GLEW_GET_FUN(__glewPathGlyphRangeNV)
+#define glPathGlyphsNV GLEW_GET_FUN(__glewPathGlyphsNV)
+#define glPathMemoryGlyphIndexArrayNV GLEW_GET_FUN(__glewPathMemoryGlyphIndexArrayNV)
+#define glPathParameterfNV GLEW_GET_FUN(__glewPathParameterfNV)
+#define glPathParameterfvNV GLEW_GET_FUN(__glewPathParameterfvNV)
+#define glPathParameteriNV GLEW_GET_FUN(__glewPathParameteriNV)
+#define glPathParameterivNV GLEW_GET_FUN(__glewPathParameterivNV)
+#define glPathStencilDepthOffsetNV GLEW_GET_FUN(__glewPathStencilDepthOffsetNV)
+#define glPathStencilFuncNV GLEW_GET_FUN(__glewPathStencilFuncNV)
+#define glPathStringNV GLEW_GET_FUN(__glewPathStringNV)
+#define glPathSubCommandsNV GLEW_GET_FUN(__glewPathSubCommandsNV)
+#define glPathSubCoordsNV GLEW_GET_FUN(__glewPathSubCoordsNV)
+#define glPathTexGenNV GLEW_GET_FUN(__glewPathTexGenNV)
+#define glPointAlongPathNV GLEW_GET_FUN(__glewPointAlongPathNV)
+#define glProgramPathFragmentInputGenNV GLEW_GET_FUN(__glewProgramPathFragmentInputGenNV)
+#define glStencilFillPathInstancedNV GLEW_GET_FUN(__glewStencilFillPathInstancedNV)
+#define glStencilFillPathNV GLEW_GET_FUN(__glewStencilFillPathNV)
+#define glStencilStrokePathInstancedNV GLEW_GET_FUN(__glewStencilStrokePathInstancedNV)
+#define glStencilStrokePathNV GLEW_GET_FUN(__glewStencilStrokePathNV)
+#define glStencilThenCoverFillPathInstancedNV GLEW_GET_FUN(__glewStencilThenCoverFillPathInstancedNV)
+#define glStencilThenCoverFillPathNV GLEW_GET_FUN(__glewStencilThenCoverFillPathNV)
+#define glStencilThenCoverStrokePathInstancedNV GLEW_GET_FUN(__glewStencilThenCoverStrokePathInstancedNV)
+#define glStencilThenCoverStrokePathNV GLEW_GET_FUN(__glewStencilThenCoverStrokePathNV)
+#define glTransformPathNV GLEW_GET_FUN(__glewTransformPathNV)
+#define glWeightPathsNV GLEW_GET_FUN(__glewWeightPathsNV)
+
+#define GLEW_NV_path_rendering GLEW_GET_VAR(__GLEW_NV_path_rendering)
+
+#endif /* GL_NV_path_rendering */
+
+/* -------------------- GL_NV_path_rendering_shared_edge ------------------- */
+
+#ifndef GL_NV_path_rendering_shared_edge
+#define GL_NV_path_rendering_shared_edge 1
+
+#define GL_SHARED_EDGE_NV 0xC0
+
+#define GLEW_NV_path_rendering_shared_edge GLEW_GET_VAR(__GLEW_NV_path_rendering_shared_edge)
+
+#endif /* GL_NV_path_rendering_shared_edge */
+
+/* ----------------------- GL_NV_pixel_buffer_object ----------------------- */
+
+#ifndef GL_NV_pixel_buffer_object
+#define GL_NV_pixel_buffer_object 1
+
+#define GL_PIXEL_PACK_BUFFER_NV 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF
+
+#define GLEW_NV_pixel_buffer_object GLEW_GET_VAR(__GLEW_NV_pixel_buffer_object)
+
+#endif /* GL_NV_pixel_buffer_object */
+
+/* ------------------------- GL_NV_pixel_data_range ------------------------ */
+
+#ifndef GL_NV_pixel_data_range
+#define GL_NV_pixel_data_range 1
+
+#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+
+typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void *pointer);
+
+#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV)
+#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV)
+
+#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range)
+
+#endif /* GL_NV_pixel_data_range */
+
+/* ------------------------- GL_NV_platform_binary ------------------------- */
+
+#ifndef GL_NV_platform_binary
+#define GL_NV_platform_binary 1
+
+#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
+
+#define GLEW_NV_platform_binary GLEW_GET_VAR(__GLEW_NV_platform_binary)
+
+#endif /* GL_NV_platform_binary */
+
+/* --------------------------- GL_NV_point_sprite -------------------------- */
+
+#ifndef GL_NV_point_sprite
+#define GL_NV_point_sprite 1
+
+#define GL_POINT_SPRITE_NV 0x8861
+#define GL_COORD_REPLACE_NV 0x8862
+#define GL_POINT_SPRITE_R_MODE_NV 0x8863
+
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params);
+
+#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV)
+#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV)
+
+#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite)
+
+#endif /* GL_NV_point_sprite */
+
+/* --------------------------- GL_NV_polygon_mode -------------------------- */
+
+#ifndef GL_NV_polygon_mode
+#define GL_NV_polygon_mode 1
+
+#define GL_POLYGON_MODE_NV 0x0B40
+#define GL_POINT_NV 0x1B00
+#define GL_LINE_NV 0x1B01
+#define GL_FILL_NV 0x1B02
+#define GL_POLYGON_OFFSET_POINT_NV 0x2A01
+#define GL_POLYGON_OFFSET_LINE_NV 0x2A02
+
+typedef void (GLAPIENTRY * PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode);
+
+#define glPolygonModeNV GLEW_GET_FUN(__glewPolygonModeNV)
+
+#define GLEW_NV_polygon_mode GLEW_GET_VAR(__GLEW_NV_polygon_mode)
+
+#endif /* GL_NV_polygon_mode */
+
+/* -------------------------- GL_NV_present_video -------------------------- */
+
+#ifndef GL_NV_present_video
+#define GL_NV_present_video 1
+
+#define GL_FRAME_NV 0x8E26
+#define GL_FIELDS_NV 0x8E27
+#define GL_CURRENT_TIME_NV 0x8E28
+#define GL_NUM_FILL_STREAMS_NV 0x8E29
+#define GL_PRESENT_TIME_NV 0x8E2A
+#define GL_PRESENT_DURATION_NV 0x8E2B
+
+typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+
+#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV)
+#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV)
+#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV)
+#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV)
+#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV)
+#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV)
+
+#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video)
+
+#endif /* GL_NV_present_video */
+
+/* ------------------------ GL_NV_primitive_restart ------------------------ */
+
+#ifndef GL_NV_primitive_restart
+#define GL_NV_primitive_restart 1
+
+#define GL_PRIMITIVE_RESTART_NV 0x8558
+#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+
+typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void);
+
+#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV)
+#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV)
+
+#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart)
+
+#endif /* GL_NV_primitive_restart */
+
+/* ---------------------------- GL_NV_read_depth --------------------------- */
+
+#ifndef GL_NV_read_depth
+#define GL_NV_read_depth 1
+
+#define GLEW_NV_read_depth GLEW_GET_VAR(__GLEW_NV_read_depth)
+
+#endif /* GL_NV_read_depth */
+
+/* ------------------------ GL_NV_read_depth_stencil ----------------------- */
+
+#ifndef GL_NV_read_depth_stencil
+#define GL_NV_read_depth_stencil 1
+
+#define GLEW_NV_read_depth_stencil GLEW_GET_VAR(__GLEW_NV_read_depth_stencil)
+
+#endif /* GL_NV_read_depth_stencil */
+
+/* --------------------------- GL_NV_read_stencil -------------------------- */
+
+#ifndef GL_NV_read_stencil
+#define GL_NV_read_stencil 1
+
+#define GLEW_NV_read_stencil GLEW_GET_VAR(__GLEW_NV_read_stencil)
+
+#endif /* GL_NV_read_stencil */
+
+/* ------------------------ GL_NV_register_combiners ----------------------- */
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE1_NV 0x852F
+#define GL_DISCARD_NV 0x8530
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+
+typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params);
+
+#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV)
+#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV)
+#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV)
+#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV)
+#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV)
+#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV)
+#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV)
+#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV)
+#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV)
+#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV)
+#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV)
+#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV)
+#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV)
+
+#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners)
+
+#endif /* GL_NV_register_combiners */
+
+/* ----------------------- GL_NV_register_combiners2 ----------------------- */
+
+#ifndef GL_NV_register_combiners2
+#define GL_NV_register_combiners2 1
+
+#define GL_PER_STAGE_CONSTANTS_NV 0x8535
+
+typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params);
+
+#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV)
+#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV)
+
+#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2)
+
+#endif /* GL_NV_register_combiners2 */
+
+/* ------------------ GL_NV_robustness_video_memory_purge ------------------ */
+
+#ifndef GL_NV_robustness_video_memory_purge
+#define GL_NV_robustness_video_memory_purge 1
+
+#define GL_EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
+
+#define GLEW_NV_robustness_video_memory_purge GLEW_GET_VAR(__GLEW_NV_robustness_video_memory_purge)
+
+#endif /* GL_NV_robustness_video_memory_purge */
+
+/* --------------------------- GL_NV_sRGB_formats -------------------------- */
+
+#ifndef GL_NV_sRGB_formats
+#define GL_NV_sRGB_formats 1
+
+#define GL_ETC1_SRGB8_NV 0x88EE
+#define GL_SRGB8_NV 0x8C41
+#define GL_SLUMINANCE_ALPHA_NV 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45
+#define GL_SLUMINANCE_NV 0x8C46
+#define GL_SLUMINANCE8_NV 0x8C47
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F
+
+#define GLEW_NV_sRGB_formats GLEW_GET_VAR(__GLEW_NV_sRGB_formats)
+
+#endif /* GL_NV_sRGB_formats */
+
+/* ------------------------- GL_NV_sample_locations ------------------------ */
+
+#ifndef GL_NV_sample_locations
+#define GL_NV_sample_locations 1
+
+#define GL_SAMPLE_LOCATION_NV 0x8E50
+#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341
+#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342
+#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v);
+
+#define glFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewFramebufferSampleLocationsfvNV)
+#define glNamedFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewNamedFramebufferSampleLocationsfvNV)
+
+#define GLEW_NV_sample_locations GLEW_GET_VAR(__GLEW_NV_sample_locations)
+
+#endif /* GL_NV_sample_locations */
+
+/* ------------------ GL_NV_sample_mask_override_coverage ------------------ */
+
+#ifndef GL_NV_sample_mask_override_coverage
+#define GL_NV_sample_mask_override_coverage 1
+
+#define GLEW_NV_sample_mask_override_coverage GLEW_GET_VAR(__GLEW_NV_sample_mask_override_coverage)
+
+#endif /* GL_NV_sample_mask_override_coverage */
+
+/* ---------------------- GL_NV_shader_atomic_counters --------------------- */
+
+#ifndef GL_NV_shader_atomic_counters
+#define GL_NV_shader_atomic_counters 1
+
+#define GLEW_NV_shader_atomic_counters GLEW_GET_VAR(__GLEW_NV_shader_atomic_counters)
+
+#endif /* GL_NV_shader_atomic_counters */
+
+/* ----------------------- GL_NV_shader_atomic_float ----------------------- */
+
+#ifndef GL_NV_shader_atomic_float
+#define GL_NV_shader_atomic_float 1
+
+#define GLEW_NV_shader_atomic_float GLEW_GET_VAR(__GLEW_NV_shader_atomic_float)
+
+#endif /* GL_NV_shader_atomic_float */
+
+/* ---------------------- GL_NV_shader_atomic_float64 ---------------------- */
+
+#ifndef GL_NV_shader_atomic_float64
+#define GL_NV_shader_atomic_float64 1
+
+#define GLEW_NV_shader_atomic_float64 GLEW_GET_VAR(__GLEW_NV_shader_atomic_float64)
+
+#endif /* GL_NV_shader_atomic_float64 */
+
+/* -------------------- GL_NV_shader_atomic_fp16_vector -------------------- */
+
+#ifndef GL_NV_shader_atomic_fp16_vector
+#define GL_NV_shader_atomic_fp16_vector 1
+
+#define GLEW_NV_shader_atomic_fp16_vector GLEW_GET_VAR(__GLEW_NV_shader_atomic_fp16_vector)
+
+#endif /* GL_NV_shader_atomic_fp16_vector */
+
+/* ----------------------- GL_NV_shader_atomic_int64 ----------------------- */
+
+#ifndef GL_NV_shader_atomic_int64
+#define GL_NV_shader_atomic_int64 1
+
+#define GLEW_NV_shader_atomic_int64 GLEW_GET_VAR(__GLEW_NV_shader_atomic_int64)
+
+#endif /* GL_NV_shader_atomic_int64 */
+
+/* ------------------------ GL_NV_shader_buffer_load ----------------------- */
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_NV_shader_buffer_load 1
+
+#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define GL_GPU_ADDRESS_NV 0x8F34
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
+typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
+typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+
+#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV)
+#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV)
+#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV)
+#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV)
+#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV)
+#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV)
+#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV)
+#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV)
+#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV)
+#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV)
+#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV)
+#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV)
+#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV)
+
+#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load)
+
+#endif /* GL_NV_shader_buffer_load */
+
+/* ---------------- GL_NV_shader_noperspective_interpolation --------------- */
+
+#ifndef GL_NV_shader_noperspective_interpolation
+#define GL_NV_shader_noperspective_interpolation 1
+
+#define GLEW_NV_shader_noperspective_interpolation GLEW_GET_VAR(__GLEW_NV_shader_noperspective_interpolation)
+
+#endif /* GL_NV_shader_noperspective_interpolation */
+
+/* ------------------- GL_NV_shader_storage_buffer_object ------------------ */
+
+#ifndef GL_NV_shader_storage_buffer_object
+#define GL_NV_shader_storage_buffer_object 1
+
+#define GLEW_NV_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_NV_shader_storage_buffer_object)
+
+#endif /* GL_NV_shader_storage_buffer_object */
+
+/* ----------------------- GL_NV_shader_thread_group ----------------------- */
+
+#ifndef GL_NV_shader_thread_group
+#define GL_NV_shader_thread_group 1
+
+#define GL_WARP_SIZE_NV 0x9339
+#define GL_WARPS_PER_SM_NV 0x933A
+#define GL_SM_COUNT_NV 0x933B
+
+#define GLEW_NV_shader_thread_group GLEW_GET_VAR(__GLEW_NV_shader_thread_group)
+
+#endif /* GL_NV_shader_thread_group */
+
+/* ---------------------- GL_NV_shader_thread_shuffle ---------------------- */
+
+#ifndef GL_NV_shader_thread_shuffle
+#define GL_NV_shader_thread_shuffle 1
+
+#define GLEW_NV_shader_thread_shuffle GLEW_GET_VAR(__GLEW_NV_shader_thread_shuffle)
+
+#endif /* GL_NV_shader_thread_shuffle */
+
+/* ---------------------- GL_NV_shadow_samplers_array ---------------------- */
+
+#ifndef GL_NV_shadow_samplers_array
+#define GL_NV_shadow_samplers_array 1
+
+#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4
+
+#define GLEW_NV_shadow_samplers_array GLEW_GET_VAR(__GLEW_NV_shadow_samplers_array)
+
+#endif /* GL_NV_shadow_samplers_array */
+
+/* ----------------------- GL_NV_shadow_samplers_cube ---------------------- */
+
+#ifndef GL_NV_shadow_samplers_cube
+#define GL_NV_shadow_samplers_cube 1
+
+#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5
+
+#define GLEW_NV_shadow_samplers_cube GLEW_GET_VAR(__GLEW_NV_shadow_samplers_cube)
+
+#endif /* GL_NV_shadow_samplers_cube */
+
+/* ---------------------- GL_NV_stereo_view_rendering ---------------------- */
+
+#ifndef GL_NV_stereo_view_rendering
+#define GL_NV_stereo_view_rendering 1
+
+#define GLEW_NV_stereo_view_rendering GLEW_GET_VAR(__GLEW_NV_stereo_view_rendering)
+
+#endif /* GL_NV_stereo_view_rendering */
+
+/* ---------------------- GL_NV_tessellation_program5 ---------------------- */
+
+#ifndef GL_NV_tessellation_program5
+#define GL_NV_tessellation_program5 1
+
+#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8
+#define GL_TESS_CONTROL_PROGRAM_NV 0x891E
+#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F
+#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+
+#define GLEW_NV_tessellation_program5 GLEW_GET_VAR(__GLEW_NV_tessellation_program5)
+
+#endif /* GL_NV_tessellation_program5 */
+
+/* -------------------------- GL_NV_texgen_emboss -------------------------- */
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_MAP_NV 0x855F
+
+#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss)
+
+#endif /* GL_NV_texgen_emboss */
+
+/* ------------------------ GL_NV_texgen_reflection ------------------------ */
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_REFLECTION_MAP_NV 0x8512
+
+#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection)
+
+#endif /* GL_NV_texgen_reflection */
+
+/* -------------------------- GL_NV_texture_array -------------------------- */
+
+#ifndef GL_NV_texture_array
+#define GL_NV_texture_array 1
+
+#define GL_UNPACK_SKIP_IMAGES_NV 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_NV 0x806E
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_NV 0x88FF
+#define GL_TEXTURE_2D_ARRAY_NV 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY_NV 0x8C1D
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_NV 0x8CD4
+#define GL_SAMPLER_2D_ARRAY_NV 0x8DC1
+
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DNVPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERNVPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DNVPROC) (GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+
+#define glCompressedTexImage3DNV GLEW_GET_FUN(__glewCompressedTexImage3DNV)
+#define glCompressedTexSubImage3DNV GLEW_GET_FUN(__glewCompressedTexSubImage3DNV)
+#define glCopyTexSubImage3DNV GLEW_GET_FUN(__glewCopyTexSubImage3DNV)
+#define glFramebufferTextureLayerNV GLEW_GET_FUN(__glewFramebufferTextureLayerNV)
+#define glTexImage3DNV GLEW_GET_FUN(__glewTexImage3DNV)
+#define glTexSubImage3DNV GLEW_GET_FUN(__glewTexSubImage3DNV)
+
+#define GLEW_NV_texture_array GLEW_GET_VAR(__GLEW_NV_texture_array)
+
+#endif /* GL_NV_texture_array */
+
+/* ------------------------- GL_NV_texture_barrier ------------------------- */
+
+#ifndef GL_NV_texture_barrier
+#define GL_NV_texture_barrier 1
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void);
+
+#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV)
+
+#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier)
+
+#endif /* GL_NV_texture_barrier */
+
+/* ----------------------- GL_NV_texture_border_clamp ---------------------- */
+
+#ifndef GL_NV_texture_border_clamp
+#define GL_NV_texture_border_clamp 1
+
+#define GL_TEXTURE_BORDER_COLOR_NV 0x1004
+#define GL_CLAMP_TO_BORDER_NV 0x812D
+
+#define GLEW_NV_texture_border_clamp GLEW_GET_VAR(__GLEW_NV_texture_border_clamp)
+
+#endif /* GL_NV_texture_border_clamp */
+
+/* --------------------- GL_NV_texture_compression_latc -------------------- */
+
+#ifndef GL_NV_texture_compression_latc
+#define GL_NV_texture_compression_latc 1
+
+#define GL_COMPRESSED_LUMINANCE_LATC1_NV 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_NV 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_NV 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV 0x8C73
+
+#define GLEW_NV_texture_compression_latc GLEW_GET_VAR(__GLEW_NV_texture_compression_latc)
+
+#endif /* GL_NV_texture_compression_latc */
+
+/* --------------------- GL_NV_texture_compression_s3tc -------------------- */
+
+#ifndef GL_NV_texture_compression_s3tc
+#define GL_NV_texture_compression_s3tc 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_NV 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_NV 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_NV 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_NV 0x83F3
+
+#define GLEW_NV_texture_compression_s3tc GLEW_GET_VAR(__GLEW_NV_texture_compression_s3tc)
+
+#endif /* GL_NV_texture_compression_s3tc */
+
+/* ----------------- GL_NV_texture_compression_s3tc_update ----------------- */
+
+#ifndef GL_NV_texture_compression_s3tc_update
+#define GL_NV_texture_compression_s3tc_update 1
+
+#define GLEW_NV_texture_compression_s3tc_update GLEW_GET_VAR(__GLEW_NV_texture_compression_s3tc_update)
+
+#endif /* GL_NV_texture_compression_s3tc_update */
+
+/* --------------------- GL_NV_texture_compression_vtc --------------------- */
+
+#ifndef GL_NV_texture_compression_vtc
+#define GL_NV_texture_compression_vtc 1
+
+#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc)
+
+#endif /* GL_NV_texture_compression_vtc */
+
+/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+
+#define GL_COMBINE4_NV 0x8503
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OPERAND3_ALPHA_NV 0x859B
+
+#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4)
+
+#endif /* GL_NV_texture_env_combine4 */
+
+/* ---------------------- GL_NV_texture_expand_normal ---------------------- */
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_NV_texture_expand_normal 1
+
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+
+#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal)
+
+#endif /* GL_NV_texture_expand_normal */
+
+/* ----------------------- GL_NV_texture_multisample ----------------------- */
+
+#ifndef GL_NV_texture_multisample
+#define GL_NV_texture_multisample 1
+
+#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045
+#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046
+
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+
+#define glTexImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage2DMultisampleCoverageNV)
+#define glTexImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage3DMultisampleCoverageNV)
+#define glTextureImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage2DMultisampleCoverageNV)
+#define glTextureImage2DMultisampleNV GLEW_GET_FUN(__glewTextureImage2DMultisampleNV)
+#define glTextureImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage3DMultisampleCoverageNV)
+#define glTextureImage3DMultisampleNV GLEW_GET_FUN(__glewTextureImage3DMultisampleNV)
+
+#define GLEW_NV_texture_multisample GLEW_GET_VAR(__GLEW_NV_texture_multisample)
+
+#endif /* GL_NV_texture_multisample */
+
+/* ---------------------- GL_NV_texture_npot_2D_mipmap --------------------- */
+
+#ifndef GL_NV_texture_npot_2D_mipmap
+#define GL_NV_texture_npot_2D_mipmap 1
+
+#define GLEW_NV_texture_npot_2D_mipmap GLEW_GET_VAR(__GLEW_NV_texture_npot_2D_mipmap)
+
+#endif /* GL_NV_texture_npot_2D_mipmap */
+
+/* ------------------------ GL_NV_texture_rectangle ------------------------ */
+
+#ifndef GL_NV_texture_rectangle
+#define GL_NV_texture_rectangle 1
+
+#define GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+
+#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle)
+
+#endif /* GL_NV_texture_rectangle */
+
+/* ------------------- GL_NV_texture_rectangle_compressed ------------------ */
+
+#ifndef GL_NV_texture_rectangle_compressed
+#define GL_NV_texture_rectangle_compressed 1
+
+#define GLEW_NV_texture_rectangle_compressed GLEW_GET_VAR(__GLEW_NV_texture_rectangle_compressed)
+
+#endif /* GL_NV_texture_rectangle_compressed */
+
+/* -------------------------- GL_NV_texture_shader ------------------------- */
+
+#ifndef GL_NV_texture_shader
+#define GL_NV_texture_shader 1
+
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_SHADER_CONSISTENT_NV 0x86DD
+#define GL_TEXTURE_SHADER_NV 0x86DE
+#define GL_SHADER_OPERATION_NV 0x86DF
+#define GL_CULL_MODES_NV 0x86E0
+#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3
+#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define GL_CONST_EYE_NV 0x86E5
+#define GL_PASS_THROUGH_NV 0x86E6
+#define GL_CULL_FRAGMENT_NV 0x86E7
+#define GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define GL_DOT_PRODUCT_NV 0x86EC
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_HI_SCALE_NV 0x870E
+#define GL_LO_SCALE_NV 0x870F
+#define GL_DS_SCALE_NV 0x8710
+#define GL_DT_SCALE_NV 0x8711
+#define GL_MAGNITUDE_SCALE_NV 0x8712
+#define GL_VIBRANCE_SCALE_NV 0x8713
+#define GL_HI_BIAS_NV 0x8714
+#define GL_LO_BIAS_NV 0x8715
+#define GL_DS_BIAS_NV 0x8716
+#define GL_DT_BIAS_NV 0x8717
+#define GL_MAGNITUDE_BIAS_NV 0x8718
+#define GL_VIBRANCE_BIAS_NV 0x8719
+#define GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define GL_TEXTURE_HI_SIZE_NV 0x871B
+#define GL_TEXTURE_LO_SIZE_NV 0x871C
+#define GL_TEXTURE_DS_SIZE_NV 0x871D
+#define GL_TEXTURE_DT_SIZE_NV 0x871E
+#define GL_TEXTURE_MAG_SIZE_NV 0x871F
+
+#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader)
+
+#endif /* GL_NV_texture_shader */
+
+/* ------------------------- GL_NV_texture_shader2 ------------------------- */
+
+#ifndef GL_NV_texture_shader2
+#define GL_NV_texture_shader2 1
+
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+
+#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2)
+
+#endif /* GL_NV_texture_shader2 */
+
+/* ------------------------- GL_NV_texture_shader3 ------------------------- */
+
+#ifndef GL_NV_texture_shader3
+#define GL_NV_texture_shader3 1
+
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_HILO8_NV 0x885E
+#define GL_SIGNED_HILO8_NV 0x885F
+#define GL_FORCE_BLUE_TO_ONE_NV 0x8860
+
+#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3)
+
+#endif /* GL_NV_texture_shader3 */
+
+/* ------------------------ GL_NV_transform_feedback ----------------------- */
+
+#ifndef GL_NV_transform_feedback
+#define GL_NV_transform_feedback 1
+
+#define GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define GL_TEXTURE_COORD_NV 0x8C79
+#define GL_CLIP_DISTANCE_NV 0x8C7A
+#define GL_VERTEX_ID_NV 0x8C7B
+#define GL_PRIMITIVE_ID_NV 0x8C7C
+#define GL_GENERIC_ATTRIB_NV 0x8C7D
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_ACTIVE_VARYINGS_NV 0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_RASTERIZER_DISCARD_NV 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+
+typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
+typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location);
+typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+
+#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV)
+#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV)
+#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV)
+#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV)
+#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV)
+#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV)
+#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV)
+#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV)
+#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV)
+#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV)
+#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV)
+
+#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback)
+
+#endif /* GL_NV_transform_feedback */
+
+/* ----------------------- GL_NV_transform_feedback2 ----------------------- */
+
+#ifndef GL_NV_transform_feedback2
+#define GL_NV_transform_feedback2 1
+
+#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+
+typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
+typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids);
+typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
+
+#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV)
+#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV)
+#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV)
+#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV)
+#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV)
+#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV)
+#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV)
+
+#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2)
+
+#endif /* GL_NV_transform_feedback2 */
+
+/* ------------------ GL_NV_uniform_buffer_unified_memory ------------------ */
+
+#ifndef GL_NV_uniform_buffer_unified_memory
+#define GL_NV_uniform_buffer_unified_memory 1
+
+#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E
+#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F
+#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370
+
+#define GLEW_NV_uniform_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_uniform_buffer_unified_memory)
+
+#endif /* GL_NV_uniform_buffer_unified_memory */
+
+/* -------------------------- GL_NV_vdpau_interop -------------------------- */
+
+#ifndef GL_NV_vdpau_interop
+#define GL_NV_vdpau_interop 1
+
+#define GL_SURFACE_STATE_NV 0x86EB
+#define GL_SURFACE_REGISTERED_NV 0x86FD
+#define GL_SURFACE_MAPPED_NV 0x8700
+#define GL_WRITE_DISCARD_NV 0x88BE
+
+typedef GLintptr GLvdpauSurfaceNV;
+
+typedef void (GLAPIENTRY * PFNGLVDPAUFININVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values);
+typedef void (GLAPIENTRY * PFNGLVDPAUINITNVPROC) (const void* vdpDevice, const void*getProcAddress);
+typedef void (GLAPIENTRY * PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (GLAPIENTRY * PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV* surfaces);
+typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef void (GLAPIENTRY * PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access);
+typedef void (GLAPIENTRY * PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV* surfaces);
+typedef void (GLAPIENTRY * PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface);
+
+#define glVDPAUFiniNV GLEW_GET_FUN(__glewVDPAUFiniNV)
+#define glVDPAUGetSurfaceivNV GLEW_GET_FUN(__glewVDPAUGetSurfaceivNV)
+#define glVDPAUInitNV GLEW_GET_FUN(__glewVDPAUInitNV)
+#define glVDPAUIsSurfaceNV GLEW_GET_FUN(__glewVDPAUIsSurfaceNV)
+#define glVDPAUMapSurfacesNV GLEW_GET_FUN(__glewVDPAUMapSurfacesNV)
+#define glVDPAURegisterOutputSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterOutputSurfaceNV)
+#define glVDPAURegisterVideoSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterVideoSurfaceNV)
+#define glVDPAUSurfaceAccessNV GLEW_GET_FUN(__glewVDPAUSurfaceAccessNV)
+#define glVDPAUUnmapSurfacesNV GLEW_GET_FUN(__glewVDPAUUnmapSurfacesNV)
+#define glVDPAUUnregisterSurfaceNV GLEW_GET_FUN(__glewVDPAUUnregisterSurfaceNV)
+
+#define GLEW_NV_vdpau_interop GLEW_GET_VAR(__GLEW_NV_vdpau_interop)
+
+#endif /* GL_NV_vdpau_interop */
+
+/* ------------------------ GL_NV_vertex_array_range ----------------------- */
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+
+typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void *pointer);
+
+#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV)
+#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV)
+
+#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range)
+
+#endif /* GL_NV_vertex_array_range */
+
+/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_NV_vertex_array_range2 1
+
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+
+#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2)
+
+#endif /* GL_NV_vertex_array_range2 */
+
+/* ------------------- GL_NV_vertex_attrib_integer_64bit ------------------- */
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+#define GL_NV_vertex_attrib_integer_64bit 1
+
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+
+#define glGetVertexAttribLi64vNV GLEW_GET_FUN(__glewGetVertexAttribLi64vNV)
+#define glGetVertexAttribLui64vNV GLEW_GET_FUN(__glewGetVertexAttribLui64vNV)
+#define glVertexAttribL1i64NV GLEW_GET_FUN(__glewVertexAttribL1i64NV)
+#define glVertexAttribL1i64vNV GLEW_GET_FUN(__glewVertexAttribL1i64vNV)
+#define glVertexAttribL1ui64NV GLEW_GET_FUN(__glewVertexAttribL1ui64NV)
+#define glVertexAttribL1ui64vNV GLEW_GET_FUN(__glewVertexAttribL1ui64vNV)
+#define glVertexAttribL2i64NV GLEW_GET_FUN(__glewVertexAttribL2i64NV)
+#define glVertexAttribL2i64vNV GLEW_GET_FUN(__glewVertexAttribL2i64vNV)
+#define glVertexAttribL2ui64NV GLEW_GET_FUN(__glewVertexAttribL2ui64NV)
+#define glVertexAttribL2ui64vNV GLEW_GET_FUN(__glewVertexAttribL2ui64vNV)
+#define glVertexAttribL3i64NV GLEW_GET_FUN(__glewVertexAttribL3i64NV)
+#define glVertexAttribL3i64vNV GLEW_GET_FUN(__glewVertexAttribL3i64vNV)
+#define glVertexAttribL3ui64NV GLEW_GET_FUN(__glewVertexAttribL3ui64NV)
+#define glVertexAttribL3ui64vNV GLEW_GET_FUN(__glewVertexAttribL3ui64vNV)
+#define glVertexAttribL4i64NV GLEW_GET_FUN(__glewVertexAttribL4i64NV)
+#define glVertexAttribL4i64vNV GLEW_GET_FUN(__glewVertexAttribL4i64vNV)
+#define glVertexAttribL4ui64NV GLEW_GET_FUN(__glewVertexAttribL4ui64NV)
+#define glVertexAttribL4ui64vNV GLEW_GET_FUN(__glewVertexAttribL4ui64vNV)
+#define glVertexAttribLFormatNV GLEW_GET_FUN(__glewVertexAttribLFormatNV)
+
+#define GLEW_NV_vertex_attrib_integer_64bit GLEW_GET_VAR(__GLEW_NV_vertex_attrib_integer_64bit)
+
+#endif /* GL_NV_vertex_attrib_integer_64bit */
+
+/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_NV_vertex_buffer_unified_memory 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40
+#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41
+#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42
+
+typedef void (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]);
+typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+
+#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV)
+#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV)
+#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV)
+#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV)
+#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV)
+#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV)
+#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV)
+#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV)
+#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV)
+#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV)
+#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV)
+#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV)
+
+#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory)
+
+#endif /* GL_NV_vertex_buffer_unified_memory */
+
+/* -------------------------- GL_NV_vertex_program ------------------------- */
+
+#ifndef GL_NV_vertex_program
+#define GL_NV_vertex_program 1
+
+#define GL_VERTEX_PROGRAM_NV 0x8620
+#define GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define GL_CURRENT_ATTRIB_NV 0x8626
+#define GL_PROGRAM_LENGTH_NV 0x8627
+#define GL_PROGRAM_STRING_NV 0x8628
+#define GL_MODELVIEW_PROJECTION_NV 0x8629
+#define GL_IDENTITY_NV 0x862A
+#define GL_INVERSE_NV 0x862B
+#define GL_TRANSPOSE_NV 0x862C
+#define GL_INVERSE_TRANSPOSE_NV 0x862D
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRACK_MATRICES_NV 0x862F
+#define GL_MATRIX0_NV 0x8630
+#define GL_MATRIX1_NV 0x8631
+#define GL_MATRIX2_NV 0x8632
+#define GL_MATRIX3_NV 0x8633
+#define GL_MATRIX4_NV 0x8634
+#define GL_MATRIX5_NV 0x8635
+#define GL_MATRIX6_NV 0x8636
+#define GL_MATRIX7_NV 0x8637
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define GL_CURRENT_MATRIX_NV 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define GL_PROGRAM_PARAMETER_NV 0x8644
+#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define GL_PROGRAM_TARGET_NV 0x8646
+#define GL_PROGRAM_RESIDENT_NV 0x8647
+#define GL_TRACK_MATRIX_NV 0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+
+typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences);
+typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void** pointer);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v);
+
+#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV)
+#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV)
+#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV)
+#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV)
+#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV)
+#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV)
+#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV)
+#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV)
+#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV)
+#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV)
+#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV)
+#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV)
+#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV)
+#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV)
+#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV)
+#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV)
+#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV)
+#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV)
+#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV)
+#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV)
+#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV)
+#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV)
+#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV)
+#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV)
+#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV)
+#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV)
+#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV)
+#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV)
+#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV)
+#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV)
+#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV)
+#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV)
+#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV)
+#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV)
+#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV)
+#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV)
+#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV)
+#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV)
+#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV)
+#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV)
+#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV)
+#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV)
+#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV)
+#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV)
+#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV)
+#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV)
+#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV)
+#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV)
+#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV)
+#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV)
+#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV)
+#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV)
+#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV)
+#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV)
+#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV)
+#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV)
+#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV)
+#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV)
+#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV)
+#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV)
+#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV)
+#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV)
+#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV)
+#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV)
+
+#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program)
+
+#endif /* GL_NV_vertex_program */
+
+/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */
+
+#ifndef GL_NV_vertex_program1_1
+#define GL_NV_vertex_program1_1 1
+
+#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1)
+
+#endif /* GL_NV_vertex_program1_1 */
+
+/* ------------------------- GL_NV_vertex_program2 ------------------------- */
+
+#ifndef GL_NV_vertex_program2
+#define GL_NV_vertex_program2 1
+
+#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2)
+
+#endif /* GL_NV_vertex_program2 */
+
+/* ---------------------- GL_NV_vertex_program2_option --------------------- */
+
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option 1
+
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+
+#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option)
+
+#endif /* GL_NV_vertex_program2_option */
+
+/* ------------------------- GL_NV_vertex_program3 ------------------------- */
+
+#ifndef GL_NV_vertex_program3
+#define GL_NV_vertex_program3 1
+
+#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+
+#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3)
+
+#endif /* GL_NV_vertex_program3 */
+
+/* ------------------------- GL_NV_vertex_program4 ------------------------- */
+
+#ifndef GL_NV_vertex_program4
+#define GL_NV_vertex_program4 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+
+#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4)
+
+#endif /* GL_NV_vertex_program4 */
+
+/* -------------------------- GL_NV_video_capture -------------------------- */
+
+#ifndef GL_NV_video_capture
+#define GL_NV_video_capture 1
+
+#define GL_VIDEO_BUFFER_NV 0x9020
+#define GL_VIDEO_BUFFER_BINDING_NV 0x9021
+#define GL_FIELD_UPPER_NV 0x9022
+#define GL_FIELD_LOWER_NV 0x9023
+#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
+#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
+#define GL_VIDEO_BUFFER_PITCH_NV 0x9028
+#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
+#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
+#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define GL_PARTIAL_SUCCESS_NV 0x902E
+#define GL_SUCCESS_NV 0x902F
+#define GL_FAILURE_NV 0x9030
+#define GL_YCBYCR8_422_NV 0x9031
+#define GL_YCBAYCR8A_4224_NV 0x9032
+#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
+#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
+#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
+#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
+#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
+#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+
+typedef void (GLAPIENTRY * PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+typedef void (GLAPIENTRY * PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint* params);
+typedef GLenum (GLAPIENTRY * PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint* sequence_num, GLuint64EXT *capture_time);
+typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint* params);
+
+#define glBeginVideoCaptureNV GLEW_GET_FUN(__glewBeginVideoCaptureNV)
+#define glBindVideoCaptureStreamBufferNV GLEW_GET_FUN(__glewBindVideoCaptureStreamBufferNV)
+#define glBindVideoCaptureStreamTextureNV GLEW_GET_FUN(__glewBindVideoCaptureStreamTextureNV)
+#define glEndVideoCaptureNV GLEW_GET_FUN(__glewEndVideoCaptureNV)
+#define glGetVideoCaptureStreamdvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamdvNV)
+#define glGetVideoCaptureStreamfvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamfvNV)
+#define glGetVideoCaptureStreamivNV GLEW_GET_FUN(__glewGetVideoCaptureStreamivNV)
+#define glGetVideoCaptureivNV GLEW_GET_FUN(__glewGetVideoCaptureivNV)
+#define glVideoCaptureNV GLEW_GET_FUN(__glewVideoCaptureNV)
+#define glVideoCaptureStreamParameterdvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterdvNV)
+#define glVideoCaptureStreamParameterfvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterfvNV)
+#define glVideoCaptureStreamParameterivNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterivNV)
+
+#define GLEW_NV_video_capture GLEW_GET_VAR(__GLEW_NV_video_capture)
+
+#endif /* GL_NV_video_capture */
+
+/* -------------------------- GL_NV_viewport_array ------------------------- */
+
+#ifndef GL_NV_viewport_array
+#define GL_NV_viewport_array 1
+
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_MAX_VIEWPORTS_NV 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F
+
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat * v);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f);
+typedef void (GLAPIENTRY * PFNGLDISABLEINVPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEINVPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat* data);
+typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINVPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint * v);
+typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint * v);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat * v);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat * v);
+
+#define glDepthRangeArrayfvNV GLEW_GET_FUN(__glewDepthRangeArrayfvNV)
+#define glDepthRangeIndexedfNV GLEW_GET_FUN(__glewDepthRangeIndexedfNV)
+#define glDisableiNV GLEW_GET_FUN(__glewDisableiNV)
+#define glEnableiNV GLEW_GET_FUN(__glewEnableiNV)
+#define glGetFloati_vNV GLEW_GET_FUN(__glewGetFloati_vNV)
+#define glIsEnablediNV GLEW_GET_FUN(__glewIsEnablediNV)
+#define glScissorArrayvNV GLEW_GET_FUN(__glewScissorArrayvNV)
+#define glScissorIndexedNV GLEW_GET_FUN(__glewScissorIndexedNV)
+#define glScissorIndexedvNV GLEW_GET_FUN(__glewScissorIndexedvNV)
+#define glViewportArrayvNV GLEW_GET_FUN(__glewViewportArrayvNV)
+#define glViewportIndexedfNV GLEW_GET_FUN(__glewViewportIndexedfNV)
+#define glViewportIndexedfvNV GLEW_GET_FUN(__glewViewportIndexedfvNV)
+
+#define GLEW_NV_viewport_array GLEW_GET_VAR(__GLEW_NV_viewport_array)
+
+#endif /* GL_NV_viewport_array */
+
+/* ------------------------- GL_NV_viewport_array2 ------------------------- */
+
+#ifndef GL_NV_viewport_array2
+#define GL_NV_viewport_array2 1
+
+#define GLEW_NV_viewport_array2 GLEW_GET_VAR(__GLEW_NV_viewport_array2)
+
+#endif /* GL_NV_viewport_array2 */
+
+/* ------------------------- GL_NV_viewport_swizzle ------------------------ */
+
+#ifndef GL_NV_viewport_swizzle
+#define GL_NV_viewport_swizzle 1
+
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357
+#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358
+#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359
+#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A
+#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B
+
+typedef void (GLAPIENTRY * PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);
+
+#define glViewportSwizzleNV GLEW_GET_FUN(__glewViewportSwizzleNV)
+
+#define GLEW_NV_viewport_swizzle GLEW_GET_VAR(__GLEW_NV_viewport_swizzle)
+
+#endif /* GL_NV_viewport_swizzle */
+
+/* ------------------------ GL_OES_byte_coordinates ------------------------ */
+
+#ifndef GL_OES_byte_coordinates
+#define GL_OES_byte_coordinates 1
+
+#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates)
+
+#endif /* GL_OES_byte_coordinates */
+
+/* ---------------------------- GL_OML_interlace --------------------------- */
+
+#ifndef GL_OML_interlace
+#define GL_OML_interlace 1
+
+#define GL_INTERLACE_OML 0x8980
+#define GL_INTERLACE_READ_OML 0x8981
+
+#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace)
+
+#endif /* GL_OML_interlace */
+
+/* ---------------------------- GL_OML_resample ---------------------------- */
+
+#ifndef GL_OML_resample
+#define GL_OML_resample 1
+
+#define GL_PACK_RESAMPLE_OML 0x8984
+#define GL_UNPACK_RESAMPLE_OML 0x8985
+#define GL_RESAMPLE_REPLICATE_OML 0x8986
+#define GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define GL_RESAMPLE_AVERAGE_OML 0x8988
+#define GL_RESAMPLE_DECIMATE_OML 0x8989
+
+#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample)
+
+#endif /* GL_OML_resample */
+
+/* ---------------------------- GL_OML_subsample --------------------------- */
+
+#ifndef GL_OML_subsample
+#define GL_OML_subsample 1
+
+#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+
+#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample)
+
+#endif /* GL_OML_subsample */
+
+/* ---------------------------- GL_OVR_multiview --------------------------- */
+
+#ifndef GL_OVR_multiview
+#define GL_OVR_multiview 1
+
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630
+#define GL_MAX_VIEWS_OVR 0x9631
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632
+#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+
+#define glFramebufferTextureMultiviewOVR GLEW_GET_FUN(__glewFramebufferTextureMultiviewOVR)
+
+#define GLEW_OVR_multiview GLEW_GET_VAR(__GLEW_OVR_multiview)
+
+#endif /* GL_OVR_multiview */
+
+/* --------------------------- GL_OVR_multiview2 --------------------------- */
+
+#ifndef GL_OVR_multiview2
+#define GL_OVR_multiview2 1
+
+#define GLEW_OVR_multiview2 GLEW_GET_VAR(__GLEW_OVR_multiview2)
+
+#endif /* GL_OVR_multiview2 */
+
+/* ------------ GL_OVR_multiview_multisampled_render_to_texture ------------ */
+
+#ifndef GL_OVR_multiview_multisampled_render_to_texture
+#define GL_OVR_multiview_multisampled_render_to_texture 1
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
+
+#define glFramebufferTextureMultisampleMultiviewOVR GLEW_GET_FUN(__glewFramebufferTextureMultisampleMultiviewOVR)
+
+#define GLEW_OVR_multiview_multisampled_render_to_texture GLEW_GET_VAR(__GLEW_OVR_multiview_multisampled_render_to_texture)
+
+#endif /* GL_OVR_multiview_multisampled_render_to_texture */
+
+/* --------------------------- GL_PGI_misc_hints --------------------------- */
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000
+#define GL_CONSERVE_MEMORY_HINT_PGI 107005
+#define GL_RECLAIM_MEMORY_HINT_PGI 107006
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012
+#define GL_ALWAYS_FAST_HINT_PGI 107020
+#define GL_ALWAYS_SOFT_HINT_PGI 107021
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030
+#define GL_STRICT_LIGHTING_HINT_PGI 107031
+#define GL_STRICT_SCISSOR_HINT_PGI 107032
+#define GL_FULL_STIPPLE_HINT_PGI 107033
+#define GL_CLIP_NEAR_HINT_PGI 107040
+#define GL_CLIP_FAR_HINT_PGI 107041
+#define GL_WIDE_LINE_HINT_PGI 107042
+#define GL_BACK_NORMALS_HINT_PGI 107043
+
+#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints)
+
+#endif /* GL_PGI_misc_hints */
+
+/* -------------------------- GL_PGI_vertex_hints -------------------------- */
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_VERTEX_DATA_HINT_PGI 107050
+#define GL_VERTEX_CONSISTENT_HINT_PGI 107051
+#define GL_MATERIAL_SIDE_HINT_PGI 107052
+#define GL_MAX_VERTEX_HINT_PGI 107053
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+
+#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints)
+
+#endif /* GL_PGI_vertex_hints */
+
+/* --------------------------- GL_QCOM_alpha_test -------------------------- */
+
+#ifndef GL_QCOM_alpha_test
+#define GL_QCOM_alpha_test 1
+
+#define GL_ALPHA_TEST_QCOM 0x0BC0
+#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1
+#define GL_ALPHA_TEST_REF_QCOM 0x0BC2
+
+typedef void (GLAPIENTRY * PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref);
+
+#define glAlphaFuncQCOM GLEW_GET_FUN(__glewAlphaFuncQCOM)
+
+#define GLEW_QCOM_alpha_test GLEW_GET_VAR(__GLEW_QCOM_alpha_test)
+
+#endif /* GL_QCOM_alpha_test */
+
+/* ------------------------ GL_QCOM_binning_control ------------------------ */
+
+#ifndef GL_QCOM_binning_control
+#define GL_QCOM_binning_control 1
+
+#define GL_DONT_CARE 0x1100
+#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0
+#define GL_CPU_OPTIMIZED_QCOM 0x8FB1
+#define GL_GPU_OPTIMIZED_QCOM 0x8FB2
+#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
+
+#define GLEW_QCOM_binning_control GLEW_GET_VAR(__GLEW_QCOM_binning_control)
+
+#endif /* GL_QCOM_binning_control */
+
+/* ------------------------- GL_QCOM_driver_control ------------------------ */
+
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+
+typedef void (GLAPIENTRY * PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GLAPIENTRY * PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GLAPIENTRY * PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar *driverControlString);
+typedef void (GLAPIENTRY * PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint* num, GLsizei size, GLuint *driverControls);
+
+#define glDisableDriverControlQCOM GLEW_GET_FUN(__glewDisableDriverControlQCOM)
+#define glEnableDriverControlQCOM GLEW_GET_FUN(__glewEnableDriverControlQCOM)
+#define glGetDriverControlStringQCOM GLEW_GET_FUN(__glewGetDriverControlStringQCOM)
+#define glGetDriverControlsQCOM GLEW_GET_FUN(__glewGetDriverControlsQCOM)
+
+#define GLEW_QCOM_driver_control GLEW_GET_VAR(__GLEW_QCOM_driver_control)
+
+#endif /* GL_QCOM_driver_control */
+
+/* -------------------------- GL_QCOM_extended_get ------------------------- */
+
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+
+#define GL_TEXTURE_WIDTH_QCOM 0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM 0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM 0x8BD6
+#define GL_TEXTURE_TYPE_QCOM 0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9
+#define GL_TEXTURE_TARGET_QCOM 0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB
+#define GL_STATE_RESTORE 0x8BDC
+
+typedef void (GLAPIENTRY * PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void** params);
+typedef void (GLAPIENTRY * PFNGLEXTGETBUFFERSQCOMPROC) (GLuint* buffers, GLint maxBuffers, GLint* numBuffers);
+typedef void (GLAPIENTRY * PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers);
+typedef void (GLAPIENTRY * PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers);
+typedef void (GLAPIENTRY * PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels);
+typedef void (GLAPIENTRY * PFNGLEXTGETTEXTURESQCOMPROC) (GLuint* textures, GLint maxTextures, GLint* numTextures);
+typedef void (GLAPIENTRY * PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param);
+
+#define glExtGetBufferPointervQCOM GLEW_GET_FUN(__glewExtGetBufferPointervQCOM)
+#define glExtGetBuffersQCOM GLEW_GET_FUN(__glewExtGetBuffersQCOM)
+#define glExtGetFramebuffersQCOM GLEW_GET_FUN(__glewExtGetFramebuffersQCOM)
+#define glExtGetRenderbuffersQCOM GLEW_GET_FUN(__glewExtGetRenderbuffersQCOM)
+#define glExtGetTexLevelParameterivQCOM GLEW_GET_FUN(__glewExtGetTexLevelParameterivQCOM)
+#define glExtGetTexSubImageQCOM GLEW_GET_FUN(__glewExtGetTexSubImageQCOM)
+#define glExtGetTexturesQCOM GLEW_GET_FUN(__glewExtGetTexturesQCOM)
+#define glExtTexObjectStateOverrideiQCOM GLEW_GET_FUN(__glewExtTexObjectStateOverrideiQCOM)
+
+#define GLEW_QCOM_extended_get GLEW_GET_VAR(__GLEW_QCOM_extended_get)
+
+#endif /* GL_QCOM_extended_get */
+
+/* ------------------------- GL_QCOM_extended_get2 ------------------------- */
+
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+
+typedef void (GLAPIENTRY * PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar* source, GLint* length);
+typedef void (GLAPIENTRY * PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint* programs, GLint maxPrograms, GLint* numPrograms);
+typedef void (GLAPIENTRY * PFNGLEXTGETSHADERSQCOMPROC) (GLuint* shaders, GLint maxShaders, GLint* numShaders);
+typedef GLboolean (GLAPIENTRY * PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program);
+
+#define glExtGetProgramBinarySourceQCOM GLEW_GET_FUN(__glewExtGetProgramBinarySourceQCOM)
+#define glExtGetProgramsQCOM GLEW_GET_FUN(__glewExtGetProgramsQCOM)
+#define glExtGetShadersQCOM GLEW_GET_FUN(__glewExtGetShadersQCOM)
+#define glExtIsProgramBinaryQCOM GLEW_GET_FUN(__glewExtIsProgramBinaryQCOM)
+
+#define GLEW_QCOM_extended_get2 GLEW_GET_VAR(__GLEW_QCOM_extended_get2)
+
+#endif /* GL_QCOM_extended_get2 */
+
+/* ---------------------- GL_QCOM_framebuffer_foveated --------------------- */
+
+#ifndef GL_QCOM_framebuffer_foveated
+#define GL_QCOM_framebuffer_foveated 1
+
+#define GL_FOVEATION_ENABLE_BIT_QCOM 0x1
+#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x2
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) (GLuint fbo, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint* providedFeatures);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) (GLuint fbo, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+
+#define glFramebufferFoveationConfigQCOM GLEW_GET_FUN(__glewFramebufferFoveationConfigQCOM)
+#define glFramebufferFoveationParametersQCOM GLEW_GET_FUN(__glewFramebufferFoveationParametersQCOM)
+
+#define GLEW_QCOM_framebuffer_foveated GLEW_GET_VAR(__GLEW_QCOM_framebuffer_foveated)
+
+#endif /* GL_QCOM_framebuffer_foveated */
+
+/* ---------------------- GL_QCOM_perfmon_global_mode ---------------------- */
+
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+
+#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
+
+#define GLEW_QCOM_perfmon_global_mode GLEW_GET_VAR(__GLEW_QCOM_perfmon_global_mode)
+
+#endif /* GL_QCOM_perfmon_global_mode */
+
+/* -------------- GL_QCOM_shader_framebuffer_fetch_noncoherent ------------- */
+
+#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent
+#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1
+
+#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void);
+
+#define glFramebufferFetchBarrierQCOM GLEW_GET_FUN(__glewFramebufferFetchBarrierQCOM)
+
+#define GLEW_QCOM_shader_framebuffer_fetch_noncoherent GLEW_GET_VAR(__GLEW_QCOM_shader_framebuffer_fetch_noncoherent)
+
+#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */
+
+/* ------------------------ GL_QCOM_tiled_rendering ------------------------ */
+
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+
+#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
+
+typedef void (GLAPIENTRY * PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
+typedef void (GLAPIENTRY * PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+
+#define glEndTilingQCOM GLEW_GET_FUN(__glewEndTilingQCOM)
+#define glStartTilingQCOM GLEW_GET_FUN(__glewStartTilingQCOM)
+
+#define GLEW_QCOM_tiled_rendering GLEW_GET_VAR(__GLEW_QCOM_tiled_rendering)
+
+#endif /* GL_QCOM_tiled_rendering */
+
+/* ---------------------- GL_QCOM_writeonly_rendering ---------------------- */
+
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+
+#define GL_WRITEONLY_RENDERING_QCOM 0x8823
+
+#define GLEW_QCOM_writeonly_rendering GLEW_GET_VAR(__GLEW_QCOM_writeonly_rendering)
+
+#endif /* GL_QCOM_writeonly_rendering */
+
+/* ---------------------- GL_REGAL_ES1_0_compatibility --------------------- */
+
+#ifndef GL_REGAL_ES1_0_compatibility
+#define GL_REGAL_ES1_0_compatibility 1
+
+typedef int GLclampx;
+
+typedef void (GLAPIENTRY * PFNGLALPHAFUNCXPROC) (GLenum func, GLclampx ref);
+typedef void (GLAPIENTRY * PFNGLCLEARCOLORXPROC) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHXPROC) (GLclampx depth);
+typedef void (GLAPIENTRY * PFNGLCOLOR4XPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEXPROC) (GLclampx zNear, GLclampx zFar);
+typedef void (GLAPIENTRY * PFNGLFOGXPROC) (GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLFOGXVPROC) (GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLFRUSTUMFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+typedef void (GLAPIENTRY * PFNGLFRUSTUMXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELXPROC) (GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELXVPROC) (GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLLIGHTXPROC) (GLenum light, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLLIGHTXVPROC) (GLenum light, GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLLINEWIDTHXPROC) (GLfixed width);
+typedef void (GLAPIENTRY * PFNGLLOADMATRIXXPROC) (const GLfixed* m);
+typedef void (GLAPIENTRY * PFNGLMATERIALXPROC) (GLenum face, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLMATERIALXVPROC) (GLenum face, GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLMULTMATRIXXPROC) (const GLfixed* m);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4XPROC) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+typedef void (GLAPIENTRY * PFNGLNORMAL3XPROC) (GLfixed nx, GLfixed ny, GLfixed nz);
+typedef void (GLAPIENTRY * PFNGLORTHOFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+typedef void (GLAPIENTRY * PFNGLORTHOXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+typedef void (GLAPIENTRY * PFNGLPOINTSIZEXPROC) (GLfixed size);
+typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETXPROC) (GLfixed factor, GLfixed units);
+typedef void (GLAPIENTRY * PFNGLROTATEXPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEXPROC) (GLclampx value, GLboolean invert);
+typedef void (GLAPIENTRY * PFNGLSCALEXPROC) (GLfixed x, GLfixed y, GLfixed z);
+typedef void (GLAPIENTRY * PFNGLTEXENVXPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLTEXENVXVPROC) (GLenum target, GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLTRANSLATEXPROC) (GLfixed x, GLfixed y, GLfixed z);
+
+#define glAlphaFuncx GLEW_GET_FUN(__glewAlphaFuncx)
+#define glClearColorx GLEW_GET_FUN(__glewClearColorx)
+#define glClearDepthx GLEW_GET_FUN(__glewClearDepthx)
+#define glColor4x GLEW_GET_FUN(__glewColor4x)
+#define glDepthRangex GLEW_GET_FUN(__glewDepthRangex)
+#define glFogx GLEW_GET_FUN(__glewFogx)
+#define glFogxv GLEW_GET_FUN(__glewFogxv)
+#define glFrustumf GLEW_GET_FUN(__glewFrustumf)
+#define glFrustumx GLEW_GET_FUN(__glewFrustumx)
+#define glLightModelx GLEW_GET_FUN(__glewLightModelx)
+#define glLightModelxv GLEW_GET_FUN(__glewLightModelxv)
+#define glLightx GLEW_GET_FUN(__glewLightx)
+#define glLightxv GLEW_GET_FUN(__glewLightxv)
+#define glLineWidthx GLEW_GET_FUN(__glewLineWidthx)
+#define glLoadMatrixx GLEW_GET_FUN(__glewLoadMatrixx)
+#define glMaterialx GLEW_GET_FUN(__glewMaterialx)
+#define glMaterialxv GLEW_GET_FUN(__glewMaterialxv)
+#define glMultMatrixx GLEW_GET_FUN(__glewMultMatrixx)
+#define glMultiTexCoord4x GLEW_GET_FUN(__glewMultiTexCoord4x)
+#define glNormal3x GLEW_GET_FUN(__glewNormal3x)
+#define glOrthof GLEW_GET_FUN(__glewOrthof)
+#define glOrthox GLEW_GET_FUN(__glewOrthox)
+#define glPointSizex GLEW_GET_FUN(__glewPointSizex)
+#define glPolygonOffsetx GLEW_GET_FUN(__glewPolygonOffsetx)
+#define glRotatex GLEW_GET_FUN(__glewRotatex)
+#define glSampleCoveragex GLEW_GET_FUN(__glewSampleCoveragex)
+#define glScalex GLEW_GET_FUN(__glewScalex)
+#define glTexEnvx GLEW_GET_FUN(__glewTexEnvx)
+#define glTexEnvxv GLEW_GET_FUN(__glewTexEnvxv)
+#define glTexParameterx GLEW_GET_FUN(__glewTexParameterx)
+#define glTranslatex GLEW_GET_FUN(__glewTranslatex)
+
+#define GLEW_REGAL_ES1_0_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_0_compatibility)
+
+#endif /* GL_REGAL_ES1_0_compatibility */
+
+/* ---------------------- GL_REGAL_ES1_1_compatibility --------------------- */
+
+#ifndef GL_REGAL_ES1_1_compatibility
+#define GL_REGAL_ES1_1_compatibility 1
+
+typedef void (GLAPIENTRY * PFNGLCLIPPLANEFPROC) (GLenum plane, const GLfloat* equation);
+typedef void (GLAPIENTRY * PFNGLCLIPPLANEXPROC) (GLenum plane, const GLfixed* equation);
+typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFPROC) (GLenum pname, GLfloat eqn[4]);
+typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEXPROC) (GLenum pname, GLfixed eqn[4]);
+typedef void (GLAPIENTRY * PFNGLGETFIXEDVPROC) (GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETLIGHTXVPROC) (GLenum light, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETMATERIALXVPROC) (GLenum face, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXENVXVPROC) (GLenum env, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERXVPROC) (GLenum target, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXPROC) (GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXVPROC) (GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLPOINTSIZEPOINTEROESPROC) (GLenum type, GLsizei stride, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXVPROC) (GLenum target, GLenum pname, const GLfixed* params);
+
+#define glClipPlanef GLEW_GET_FUN(__glewClipPlanef)
+#define glClipPlanex GLEW_GET_FUN(__glewClipPlanex)
+#define glGetClipPlanef GLEW_GET_FUN(__glewGetClipPlanef)
+#define glGetClipPlanex GLEW_GET_FUN(__glewGetClipPlanex)
+#define glGetFixedv GLEW_GET_FUN(__glewGetFixedv)
+#define glGetLightxv GLEW_GET_FUN(__glewGetLightxv)
+#define glGetMaterialxv GLEW_GET_FUN(__glewGetMaterialxv)
+#define glGetTexEnvxv GLEW_GET_FUN(__glewGetTexEnvxv)
+#define glGetTexParameterxv GLEW_GET_FUN(__glewGetTexParameterxv)
+#define glPointParameterx GLEW_GET_FUN(__glewPointParameterx)
+#define glPointParameterxv GLEW_GET_FUN(__glewPointParameterxv)
+#define glPointSizePointerOES GLEW_GET_FUN(__glewPointSizePointerOES)
+#define glTexParameterxv GLEW_GET_FUN(__glewTexParameterxv)
+
+#define GLEW_REGAL_ES1_1_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_1_compatibility)
+
+#endif /* GL_REGAL_ES1_1_compatibility */
+
+/* ---------------------------- GL_REGAL_enable ---------------------------- */
+
+#ifndef GL_REGAL_enable
+#define GL_REGAL_enable 1
+
+#define GL_ERROR_REGAL 0x9322
+#define GL_DEBUG_REGAL 0x9323
+#define GL_LOG_REGAL 0x9324
+#define GL_EMULATION_REGAL 0x9325
+#define GL_DRIVER_REGAL 0x9326
+#define GL_MISSING_REGAL 0x9360
+#define GL_TRACE_REGAL 0x9361
+#define GL_CACHE_REGAL 0x9362
+#define GL_CODE_REGAL 0x9363
+#define GL_STATISTICS_REGAL 0x9364
+
+#define GLEW_REGAL_enable GLEW_GET_VAR(__GLEW_REGAL_enable)
+
+#endif /* GL_REGAL_enable */
+
+/* ------------------------- GL_REGAL_error_string ------------------------- */
+
+#ifndef GL_REGAL_error_string
+#define GL_REGAL_error_string 1
+
+typedef const GLchar* (GLAPIENTRY * PFNGLERRORSTRINGREGALPROC) (GLenum error);
+
+#define glErrorStringREGAL GLEW_GET_FUN(__glewErrorStringREGAL)
+
+#define GLEW_REGAL_error_string GLEW_GET_VAR(__GLEW_REGAL_error_string)
+
+#endif /* GL_REGAL_error_string */
+
+/* ------------------------ GL_REGAL_extension_query ----------------------- */
+
+#ifndef GL_REGAL_extension_query
+#define GL_REGAL_extension_query 1
+
+typedef GLboolean (GLAPIENTRY * PFNGLGETEXTENSIONREGALPROC) (const GLchar* ext);
+typedef GLboolean (GLAPIENTRY * PFNGLISSUPPORTEDREGALPROC) (const GLchar* ext);
+
+#define glGetExtensionREGAL GLEW_GET_FUN(__glewGetExtensionREGAL)
+#define glIsSupportedREGAL GLEW_GET_FUN(__glewIsSupportedREGAL)
+
+#define GLEW_REGAL_extension_query GLEW_GET_VAR(__GLEW_REGAL_extension_query)
+
+#endif /* GL_REGAL_extension_query */
+
+/* ------------------------------ GL_REGAL_log ----------------------------- */
+
+#ifndef GL_REGAL_log
+#define GL_REGAL_log 1
+
+#define GL_LOG_ERROR_REGAL 0x9319
+#define GL_LOG_WARNING_REGAL 0x931A
+#define GL_LOG_INFO_REGAL 0x931B
+#define GL_LOG_APP_REGAL 0x931C
+#define GL_LOG_DRIVER_REGAL 0x931D
+#define GL_LOG_INTERNAL_REGAL 0x931E
+#define GL_LOG_DEBUG_REGAL 0x931F
+#define GL_LOG_STATUS_REGAL 0x9320
+#define GL_LOG_HTTP_REGAL 0x9321
+
+typedef void (APIENTRY *GLLOGPROCREGAL)(GLenum stream, GLsizei length, const GLchar *message, void *context);
+
+typedef void (GLAPIENTRY * PFNGLLOGMESSAGECALLBACKREGALPROC) (GLLOGPROCREGAL callback);
+
+#define glLogMessageCallbackREGAL GLEW_GET_FUN(__glewLogMessageCallbackREGAL)
+
+#define GLEW_REGAL_log GLEW_GET_VAR(__GLEW_REGAL_log)
+
+#endif /* GL_REGAL_log */
+
+/* ------------------------- GL_REGAL_proc_address ------------------------- */
+
+#ifndef GL_REGAL_proc_address
+#define GL_REGAL_proc_address 1
+
+typedef void * (GLAPIENTRY * PFNGLGETPROCADDRESSREGALPROC) (const GLchar *name);
+
+#define glGetProcAddressREGAL GLEW_GET_FUN(__glewGetProcAddressREGAL)
+
+#define GLEW_REGAL_proc_address GLEW_GET_VAR(__GLEW_REGAL_proc_address)
+
+#endif /* GL_REGAL_proc_address */
+
+/* ----------------------- GL_REND_screen_coordinates ---------------------- */
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+
+#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates)
+
+#endif /* GL_REND_screen_coordinates */
+
+/* ------------------------------- GL_S3_s3tc ------------------------------ */
+
+#ifndef GL_S3_s3tc
+#define GL_S3_s3tc 1
+
+#define GL_RGB_S3TC 0x83A0
+#define GL_RGB4_S3TC 0x83A1
+#define GL_RGBA_S3TC 0x83A2
+#define GL_RGBA4_S3TC 0x83A3
+#define GL_RGBA_DXT5_S3TC 0x83A4
+#define GL_RGBA4_DXT5_S3TC 0x83A5
+
+#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc)
+
+#endif /* GL_S3_s3tc */
+
+/* ------------------------- GL_SGIS_clip_band_hint ------------------------ */
+
+#ifndef GL_SGIS_clip_band_hint
+#define GL_SGIS_clip_band_hint 1
+
+#define GLEW_SGIS_clip_band_hint GLEW_GET_VAR(__GLEW_SGIS_clip_band_hint)
+
+#endif /* GL_SGIS_clip_band_hint */
+
+/* -------------------------- GL_SGIS_color_range -------------------------- */
+
+#ifndef GL_SGIS_color_range
+#define GL_SGIS_color_range 1
+
+#define GL_EXTENDED_RANGE_SGIS 0x85A5
+#define GL_MIN_RED_SGIS 0x85A6
+#define GL_MAX_RED_SGIS 0x85A7
+#define GL_MIN_GREEN_SGIS 0x85A8
+#define GL_MAX_GREEN_SGIS 0x85A9
+#define GL_MIN_BLUE_SGIS 0x85AA
+#define GL_MAX_BLUE_SGIS 0x85AB
+#define GL_MIN_ALPHA_SGIS 0x85AC
+#define GL_MAX_ALPHA_SGIS 0x85AD
+
+#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range)
+
+#endif /* GL_SGIS_color_range */
+
+/* ------------------------- GL_SGIS_detail_texture ------------------------ */
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+
+typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points);
+
+#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS)
+#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS)
+
+#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture)
+
+#endif /* GL_SGIS_detail_texture */
+
+/* -------------------------- GL_SGIS_fog_function ------------------------- */
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+
+typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points);
+
+#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS)
+#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS)
+
+#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function)
+
+#endif /* GL_SGIS_fog_function */
+
+/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+
+#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap)
+
+#endif /* GL_SGIS_generate_mipmap */
+
+/* -------------------------- GL_SGIS_line_texgen -------------------------- */
+
+#ifndef GL_SGIS_line_texgen
+#define GL_SGIS_line_texgen 1
+
+#define GLEW_SGIS_line_texgen GLEW_GET_VAR(__GLEW_SGIS_line_texgen)
+
+#endif /* GL_SGIS_line_texgen */
+
+/* -------------------------- GL_SGIS_multisample -------------------------- */
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+
+#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS)
+#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS)
+
+#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample)
+
+#endif /* GL_SGIS_multisample */
+
+/* -------------------------- GL_SGIS_multitexture ------------------------- */
+
+#ifndef GL_SGIS_multitexture
+#define GL_SGIS_multitexture 1
+
+#define GL_SELECTED_TEXTURE_SGIS 0x83C0
+#define GL_SELECTED_TEXTURE_COORD_SET_SGIS 0x83C1
+#define GL_SELECTED_TEXTURE_TRANSFORM_SGIS 0x83C2
+#define GL_MAX_TEXTURES_SGIS 0x83C3
+#define GL_MAX_TEXTURE_COORD_SETS_SGIS 0x83C4
+#define GL_TEXTURE_COORD_SET_INTERLEAVE_FACTOR_SGIS 0x83C5
+#define GL_TEXTURE_ENV_COORD_SET_SGIS 0x83C6
+#define GL_TEXTURE0_SGIS 0x83C7
+#define GL_TEXTURE1_SGIS 0x83C8
+#define GL_TEXTURE2_SGIS 0x83C9
+#define GL_TEXTURE3_SGIS 0x83CA
+
+typedef void (GLAPIENTRY * PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC) (GLint factor);
+typedef void (GLAPIENTRY * PFNGLSELECTTEXTURECOORDSETSGISPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLSELECTTEXTURESGISPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLSELECTTEXTURETRANSFORMSGISPROC) (GLenum target);
+
+#define glInterleavedTextureCoordSetsSGIS GLEW_GET_FUN(__glewInterleavedTextureCoordSetsSGIS)
+#define glSelectTextureCoordSetSGIS GLEW_GET_FUN(__glewSelectTextureCoordSetSGIS)
+#define glSelectTextureSGIS GLEW_GET_FUN(__glewSelectTextureSGIS)
+#define glSelectTextureTransformSGIS GLEW_GET_FUN(__glewSelectTextureTransformSGIS)
+
+#define GLEW_SGIS_multitexture GLEW_GET_VAR(__GLEW_SGIS_multitexture)
+
+#endif /* GL_SGIS_multitexture */
+
+/* ------------------------- GL_SGIS_pixel_texture ------------------------- */
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+
+#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture)
+
+#endif /* GL_SGIS_pixel_texture */
+
+/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_OBJECT_LINE_SGIS 0x81F7
+
+#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen)
+
+#endif /* GL_SGIS_point_line_texgen */
+
+/* ----------------------- GL_SGIS_shared_multisample ---------------------- */
+
+#ifndef GL_SGIS_shared_multisample
+#define GL_SGIS_shared_multisample 1
+
+typedef void (GLAPIENTRY * PFNGLMULTISAMPLESUBRECTPOSSGISPROC) (GLint x, GLint y);
+
+#define glMultisampleSubRectPosSGIS GLEW_GET_FUN(__glewMultisampleSubRectPosSGIS)
+
+#define GLEW_SGIS_shared_multisample GLEW_GET_VAR(__GLEW_SGIS_shared_multisample)
+
+#endif /* GL_SGIS_shared_multisample */
+
+/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+
+typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points);
+
+#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS)
+#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS)
+
+#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture)
+
+#endif /* GL_SGIS_sharpen_texture */
+
+/* --------------------------- GL_SGIS_texture4D --------------------------- */
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void *pixels);
+
+#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS)
+#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS)
+
+#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D)
+
+#endif /* GL_SGIS_texture4D */
+
+/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+
+#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp)
+
+#endif /* GL_SGIS_texture_border_clamp */
+
+/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+
+#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp)
+
+#endif /* GL_SGIS_texture_edge_clamp */
+
+/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+
+typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights);
+typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights);
+
+#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS)
+#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS)
+
+#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4)
+
+#endif /* GL_SGIS_texture_filter4 */
+
+/* -------------------------- GL_SGIS_texture_lod -------------------------- */
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+
+#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod)
+
+#endif /* GL_SGIS_texture_lod */
+
+/* ------------------------- GL_SGIS_texture_select ------------------------ */
+
+#ifndef GL_SGIS_texture_select
+#define GL_SGIS_texture_select 1
+
+#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select)
+
+#endif /* GL_SGIS_texture_select */
+
+/* ----------------------------- GL_SGIX_async ----------------------------- */
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+
+#define GL_ASYNC_MARKER_SGIX 0x8329
+
+typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp);
+typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp);
+
+#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX)
+#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX)
+#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX)
+#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX)
+#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX)
+#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX)
+
+#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async)
+
+#endif /* GL_SGIX_async */
+
+/* ------------------------ GL_SGIX_async_histogram ------------------------ */
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+
+#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram)
+
+#endif /* GL_SGIX_async_histogram */
+
+/* -------------------------- GL_SGIX_async_pixel -------------------------- */
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+
+#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel)
+
+#endif /* GL_SGIX_async_pixel */
+
+/* ----------------------- GL_SGIX_bali_g_instruments ---------------------- */
+
+#ifndef GL_SGIX_bali_g_instruments
+#define GL_SGIX_bali_g_instruments 1
+
+#define GL_BALI_NUM_TRIS_CULLED_INSTRUMENT 0x6080
+#define GL_BALI_NUM_PRIMS_CLIPPED_INSTRUMENT 0x6081
+#define GL_BALI_NUM_PRIMS_REJECT_INSTRUMENT 0x6082
+#define GL_BALI_NUM_PRIMS_CLIP_RESULT_INSTRUMENT 0x6083
+
+#define GLEW_SGIX_bali_g_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_g_instruments)
+
+#endif /* GL_SGIX_bali_g_instruments */
+
+/* ----------------------- GL_SGIX_bali_r_instruments ---------------------- */
+
+#ifndef GL_SGIX_bali_r_instruments
+#define GL_SGIX_bali_r_instruments 1
+
+#define GL_BALI_FRAGMENTS_GENERATED_INSTRUMENT 0x6090
+#define GL_BALI_DEPTH_PASS_INSTRUMENT 0x6091
+#define GL_BALI_R_CHIP_COUNT 0x6092
+
+#define GLEW_SGIX_bali_r_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_r_instruments)
+
+#endif /* GL_SGIX_bali_r_instruments */
+
+/* --------------------- GL_SGIX_bali_timer_instruments -------------------- */
+
+#ifndef GL_SGIX_bali_timer_instruments
+#define GL_SGIX_bali_timer_instruments 1
+
+#define GLEW_SGIX_bali_timer_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_timer_instruments)
+
+#endif /* GL_SGIX_bali_timer_instruments */
+
+/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_MAX_SGIX 0x8321
+
+#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax)
+
+#endif /* GL_SGIX_blend_alpha_minmax */
+
+/* --------------------------- GL_SGIX_blend_cadd -------------------------- */
+
+#ifndef GL_SGIX_blend_cadd
+#define GL_SGIX_blend_cadd 1
+
+#define GL_FUNC_COMPLEX_ADD_EXT 0x601C
+
+#define GLEW_SGIX_blend_cadd GLEW_GET_VAR(__GLEW_SGIX_blend_cadd)
+
+#endif /* GL_SGIX_blend_cadd */
+
+/* ------------------------ GL_SGIX_blend_cmultiply ------------------------ */
+
+#ifndef GL_SGIX_blend_cmultiply
+#define GL_SGIX_blend_cmultiply 1
+
+#define GL_FUNC_COMPLEX_MULTIPLY_EXT 0x601B
+
+#define GLEW_SGIX_blend_cmultiply GLEW_GET_VAR(__GLEW_SGIX_blend_cmultiply)
+
+#endif /* GL_SGIX_blend_cmultiply */
+
+/* --------------------- GL_SGIX_calligraphic_fragment --------------------- */
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_SGIX_calligraphic_fragment 1
+
+#define GLEW_SGIX_calligraphic_fragment GLEW_GET_VAR(__GLEW_SGIX_calligraphic_fragment)
+
+#endif /* GL_SGIX_calligraphic_fragment */
+
+/* ---------------------------- GL_SGIX_clipmap ---------------------------- */
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+
+#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap)
+
+#endif /* GL_SGIX_clipmap */
+
+/* --------------------- GL_SGIX_color_matrix_accuracy --------------------- */
+
+#ifndef GL_SGIX_color_matrix_accuracy
+#define GL_SGIX_color_matrix_accuracy 1
+
+#define GL_COLOR_MATRIX_HINT 0x8317
+
+#define GLEW_SGIX_color_matrix_accuracy GLEW_GET_VAR(__GLEW_SGIX_color_matrix_accuracy)
+
+#endif /* GL_SGIX_color_matrix_accuracy */
+
+/* --------------------- GL_SGIX_color_table_index_mode -------------------- */
+
+#ifndef GL_SGIX_color_table_index_mode
+#define GL_SGIX_color_table_index_mode 1
+
+#define GLEW_SGIX_color_table_index_mode GLEW_GET_VAR(__GLEW_SGIX_color_table_index_mode)
+
+#endif /* GL_SGIX_color_table_index_mode */
+
+/* ------------------------- GL_SGIX_complex_polar ------------------------- */
+
+#ifndef GL_SGIX_complex_polar
+#define GL_SGIX_complex_polar 1
+
+#define GLEW_SGIX_complex_polar GLEW_GET_VAR(__GLEW_SGIX_complex_polar)
+
+#endif /* GL_SGIX_complex_polar */
+
+/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+
+#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy)
+
+#endif /* GL_SGIX_convolution_accuracy */
+
+/* ---------------------------- GL_SGIX_cube_map --------------------------- */
+
+#ifndef GL_SGIX_cube_map
+#define GL_SGIX_cube_map 1
+
+#define GL_ENV_MAP_SGIX 0x8340
+#define GL_CUBE_MAP_SGIX 0x8341
+#define GL_CUBE_MAP_ZP_SGIX 0x8342
+#define GL_CUBE_MAP_ZN_SGIX 0x8343
+#define GL_CUBE_MAP_XN_SGIX 0x8344
+#define GL_CUBE_MAP_XP_SGIX 0x8345
+#define GL_CUBE_MAP_YN_SGIX 0x8346
+#define GL_CUBE_MAP_YP_SGIX 0x8347
+#define GL_CUBE_MAP_BINDING_SGIX 0x8348
+
+#define GLEW_SGIX_cube_map GLEW_GET_VAR(__GLEW_SGIX_cube_map)
+
+#endif /* GL_SGIX_cube_map */
+
+/* ------------------------ GL_SGIX_cylinder_texgen ------------------------ */
+
+#ifndef GL_SGIX_cylinder_texgen
+#define GL_SGIX_cylinder_texgen 1
+
+#define GLEW_SGIX_cylinder_texgen GLEW_GET_VAR(__GLEW_SGIX_cylinder_texgen)
+
+#endif /* GL_SGIX_cylinder_texgen */
+
+/* ---------------------------- GL_SGIX_datapipe --------------------------- */
+
+#ifndef GL_SGIX_datapipe
+#define GL_SGIX_datapipe 1
+
+#define GL_GEOMETRY_BIT 0x1
+#define GL_IMAGE_BIT 0x2
+
+typedef void (GLAPIENTRY * PFNGLADDRESSSPACEPROC) (GLenum space, GLbitfield mask);
+typedef GLint (GLAPIENTRY * PFNGLDATAPIPEPROC) (GLenum space);
+
+#define glAddressSpace GLEW_GET_FUN(__glewAddressSpace)
+#define glDataPipe GLEW_GET_FUN(__glewDataPipe)
+
+#define GLEW_SGIX_datapipe GLEW_GET_VAR(__GLEW_SGIX_datapipe)
+
+#endif /* GL_SGIX_datapipe */
+
+/* --------------------------- GL_SGIX_decimation -------------------------- */
+
+#ifndef GL_SGIX_decimation
+#define GL_SGIX_decimation 1
+
+#define GLEW_SGIX_decimation GLEW_GET_VAR(__GLEW_SGIX_decimation)
+
+#endif /* GL_SGIX_decimation */
+
+/* --------------------- GL_SGIX_depth_pass_instrument --------------------- */
+
+#ifndef GL_SGIX_depth_pass_instrument
+#define GL_SGIX_depth_pass_instrument 1
+
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+
+#define GLEW_SGIX_depth_pass_instrument GLEW_GET_VAR(__GLEW_SGIX_depth_pass_instrument)
+
+#endif /* GL_SGIX_depth_pass_instrument */
+
+/* ------------------------- GL_SGIX_depth_texture ------------------------- */
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+
+#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture)
+
+#endif /* GL_SGIX_depth_texture */
+
+/* ------------------------------ GL_SGIX_dvc ------------------------------ */
+
+#ifndef GL_SGIX_dvc
+#define GL_SGIX_dvc 1
+
+#define GLEW_SGIX_dvc GLEW_GET_VAR(__GLEW_SGIX_dvc)
+
+#endif /* GL_SGIX_dvc */
+
+/* -------------------------- GL_SGIX_flush_raster ------------------------- */
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+
+typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void);
+
+#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX)
+
+#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster)
+
+#endif /* GL_SGIX_flush_raster */
+
+/* --------------------------- GL_SGIX_fog_blend --------------------------- */
+
+#ifndef GL_SGIX_fog_blend
+#define GL_SGIX_fog_blend 1
+
+#define GL_FOG_BLEND_ALPHA_SGIX 0x81FE
+#define GL_FOG_BLEND_COLOR_SGIX 0x81FF
+
+#define GLEW_SGIX_fog_blend GLEW_GET_VAR(__GLEW_SGIX_fog_blend)
+
+#endif /* GL_SGIX_fog_blend */
+
+/* ---------------------- GL_SGIX_fog_factor_to_alpha ---------------------- */
+
+#ifndef GL_SGIX_fog_factor_to_alpha
+#define GL_SGIX_fog_factor_to_alpha 1
+
+#define GLEW_SGIX_fog_factor_to_alpha GLEW_GET_VAR(__GLEW_SGIX_fog_factor_to_alpha)
+
+#endif /* GL_SGIX_fog_factor_to_alpha */
+
+/* --------------------------- GL_SGIX_fog_layers -------------------------- */
+
+#ifndef GL_SGIX_fog_layers
+#define GL_SGIX_fog_layers 1
+
+#define GL_FOG_TYPE_SGIX 0x8323
+#define GL_UNIFORM_SGIX 0x8324
+#define GL_LAYERED_SGIX 0x8325
+#define GL_FOG_GROUND_PLANE_SGIX 0x8326
+#define GL_FOG_LAYERS_POINTS_SGIX 0x8327
+#define GL_MAX_FOG_LAYERS_POINTS_SGIX 0x8328
+
+typedef void (GLAPIENTRY * PFNGLFOGLAYERSSGIXPROC) (GLsizei n, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLGETFOGLAYERSSGIXPROC) (GLfloat* points);
+
+#define glFogLayersSGIX GLEW_GET_FUN(__glewFogLayersSGIX)
+#define glGetFogLayersSGIX GLEW_GET_FUN(__glewGetFogLayersSGIX)
+
+#define GLEW_SGIX_fog_layers GLEW_GET_VAR(__GLEW_SGIX_fog_layers)
+
+#endif /* GL_SGIX_fog_layers */
+
+/* --------------------------- GL_SGIX_fog_offset -------------------------- */
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+
+#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset)
+
+#endif /* GL_SGIX_fog_offset */
+
+/* --------------------------- GL_SGIX_fog_patchy -------------------------- */
+
+#ifndef GL_SGIX_fog_patchy
+#define GL_SGIX_fog_patchy 1
+
+#define GLEW_SGIX_fog_patchy GLEW_GET_VAR(__GLEW_SGIX_fog_patchy)
+
+#endif /* GL_SGIX_fog_patchy */
+
+/* --------------------------- GL_SGIX_fog_scale --------------------------- */
+
+#ifndef GL_SGIX_fog_scale
+#define GL_SGIX_fog_scale 1
+
+#define GL_FOG_SCALE_SGIX 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX 0x81FD
+
+#define GLEW_SGIX_fog_scale GLEW_GET_VAR(__GLEW_SGIX_fog_scale)
+
+#endif /* GL_SGIX_fog_scale */
+
+/* -------------------------- GL_SGIX_fog_texture -------------------------- */
+
+#ifndef GL_SGIX_fog_texture
+#define GL_SGIX_fog_texture 1
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname);
+
+#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX)
+
+#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture)
+
+#endif /* GL_SGIX_fog_texture */
+
+/* -------------------- GL_SGIX_fragment_lighting_space -------------------- */
+
+#ifndef GL_SGIX_fragment_lighting_space
+#define GL_SGIX_fragment_lighting_space 1
+
+#define GL_EYE_SPACE_SGIX 0x8436
+#define GL_TANGENT_SPACE_SGIX 0x8437
+#define GL_OBJECT_SPACE_SGIX 0x8438
+#define GL_FRAGMENT_LIGHT_SPACE_SGIX 0x843D
+
+#define GLEW_SGIX_fragment_lighting_space GLEW_GET_VAR(__GLEW_SGIX_fragment_lighting_space)
+
+#endif /* GL_SGIX_fragment_lighting_space */
+
+/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */
+
+#ifndef GL_SGIX_fragment_specular_lighting
+#define GL_SGIX_fragment_specular_lighting 1
+
+typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data);
+
+#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX)
+#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX)
+#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX)
+#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX)
+#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX)
+#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX)
+#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX)
+#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX)
+#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX)
+#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX)
+#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX)
+#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX)
+#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX)
+#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX)
+#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX)
+#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX)
+#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX)
+
+#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting)
+
+#endif /* GL_SGIX_fragment_specular_lighting */
+
+/* ---------------------- GL_SGIX_fragments_instrument --------------------- */
+
+#ifndef GL_SGIX_fragments_instrument
+#define GL_SGIX_fragments_instrument 1
+
+#define GL_FRAGMENTS_INSTRUMENT_SGIX 0x8313
+#define GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX 0x8314
+#define GL_FRAGMENTS_INSTRUMENT_MAX_SGIX 0x8315
+
+#define GLEW_SGIX_fragments_instrument GLEW_GET_VAR(__GLEW_SGIX_fragments_instrument)
+
+#endif /* GL_SGIX_fragments_instrument */
+
+/* --------------------------- GL_SGIX_framezoom --------------------------- */
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+
+typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+
+#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX)
+
+#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom)
+
+#endif /* GL_SGIX_framezoom */
+
+/* -------------------------- GL_SGIX_icc_texture -------------------------- */
+
+#ifndef GL_SGIX_icc_texture
+#define GL_SGIX_icc_texture 1
+
+#define GL_RGB_ICC_SGIX 0x8460
+#define GL_RGBA_ICC_SGIX 0x8461
+#define GL_ALPHA_ICC_SGIX 0x8462
+#define GL_LUMINANCE_ICC_SGIX 0x8463
+#define GL_INTENSITY_ICC_SGIX 0x8464
+#define GL_LUMINANCE_ALPHA_ICC_SGIX 0x8465
+#define GL_R5_G6_B5_ICC_SGIX 0x8466
+#define GL_R5_G6_B5_A8_ICC_SGIX 0x8467
+#define GL_ALPHA16_ICC_SGIX 0x8468
+#define GL_LUMINANCE16_ICC_SGIX 0x8469
+#define GL_INTENSITY16_ICC_SGIX 0x846A
+#define GL_LUMINANCE16_ALPHA8_ICC_SGIX 0x846B
+
+#define GLEW_SGIX_icc_texture GLEW_GET_VAR(__GLEW_SGIX_icc_texture)
+
+#endif /* GL_SGIX_icc_texture */
+
+/* ------------------------ GL_SGIX_igloo_interface ------------------------ */
+
+#ifndef GL_SGIX_igloo_interface
+#define GL_SGIX_igloo_interface 1
+
+#define GL_IGLOO_FULLSCREEN_SGIX 0x819E
+#define GL_IGLOO_VIEWPORT_OFFSET_SGIX 0x819F
+#define GL_IGLOO_SWAPTMESH_SGIX 0x81A0
+#define GL_IGLOO_COLORNORMAL_SGIX 0x81A1
+#define GL_IGLOO_IRISGL_MODE_SGIX 0x81A2
+#define GL_IGLOO_LMC_COLOR_SGIX 0x81A3
+#define GL_IGLOO_TMESHMODE_SGIX 0x81A4
+#define GL_LIGHT31 0xBEAD
+
+typedef void (GLAPIENTRY * PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, void *param);
+
+#define glIglooInterfaceSGIX GLEW_GET_FUN(__glewIglooInterfaceSGIX)
+
+#define GLEW_SGIX_igloo_interface GLEW_GET_VAR(__GLEW_SGIX_igloo_interface)
+
+#endif /* GL_SGIX_igloo_interface */
+
+/* ----------------------- GL_SGIX_image_compression ----------------------- */
+
+#ifndef GL_SGIX_image_compression
+#define GL_SGIX_image_compression 1
+
+#define GLEW_SGIX_image_compression GLEW_GET_VAR(__GLEW_SGIX_image_compression)
+
+#endif /* GL_SGIX_image_compression */
+
+/* ---------------------- GL_SGIX_impact_pixel_texture --------------------- */
+
+#ifndef GL_SGIX_impact_pixel_texture
+#define GL_SGIX_impact_pixel_texture 1
+
+#define GLEW_SGIX_impact_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_impact_pixel_texture)
+
+#endif /* GL_SGIX_impact_pixel_texture */
+
+/* ------------------------ GL_SGIX_instrument_error ----------------------- */
+
+#ifndef GL_SGIX_instrument_error
+#define GL_SGIX_instrument_error 1
+
+#define GLEW_SGIX_instrument_error GLEW_GET_VAR(__GLEW_SGIX_instrument_error)
+
+#endif /* GL_SGIX_instrument_error */
+
+/* --------------------------- GL_SGIX_interlace --------------------------- */
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+
+#define GL_INTERLACE_SGIX 0x8094
+
+#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace)
+
+#endif /* GL_SGIX_interlace */
+
+/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+
+#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1)
+
+#endif /* GL_SGIX_ir_instrument1 */
+
+/* ----------------------- GL_SGIX_line_quality_hint ----------------------- */
+
+#ifndef GL_SGIX_line_quality_hint
+#define GL_SGIX_line_quality_hint 1
+
+#define GL_LINE_QUALITY_HINT_SGIX 0x835B
+
+#define GLEW_SGIX_line_quality_hint GLEW_GET_VAR(__GLEW_SGIX_line_quality_hint)
+
+#endif /* GL_SGIX_line_quality_hint */
+
+/* ------------------------- GL_SGIX_list_priority ------------------------- */
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+
+#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority)
+
+#endif /* GL_SGIX_list_priority */
+
+/* ----------------------------- GL_SGIX_mpeg1 ----------------------------- */
+
+#ifndef GL_SGIX_mpeg1
+#define GL_SGIX_mpeg1 1
+
+typedef void (GLAPIENTRY * PFNGLALLOCMPEGPREDICTORSSGIXPROC) (GLsizei width, GLsizei height, GLsizei n, GLuint* predictors);
+typedef void (GLAPIENTRY * PFNGLDELETEMPEGPREDICTORSSGIXPROC) (GLsizei n, GLuint* predictors);
+typedef void (GLAPIENTRY * PFNGLGENMPEGPREDICTORSSGIXPROC) (GLsizei n, GLuint* predictors);
+typedef void (GLAPIENTRY * PFNGLGETMPEGPARAMETERFVSGIXPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMPEGPARAMETERIVSGIXPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMPEGPREDICTORSGIXPROC) (GLenum target, GLenum format, GLenum type, void *pixels);
+typedef void (GLAPIENTRY * PFNGLGETMPEGQUANTTABLEUBVPROC) (GLenum target, GLubyte* values);
+typedef GLboolean (GLAPIENTRY * PFNGLISMPEGPREDICTORSGIXPROC) (GLuint predictor);
+typedef void (GLAPIENTRY * PFNGLMPEGPREDICTORSGIXPROC) (GLenum target, GLenum format, GLenum type, void *pixels);
+typedef void (GLAPIENTRY * PFNGLMPEGQUANTTABLEUBVPROC) (GLenum target, GLubyte* values);
+typedef void (GLAPIENTRY * PFNGLSWAPMPEGPREDICTORSSGIXPROC) (GLenum target0, GLenum target1);
+
+#define glAllocMPEGPredictorsSGIX GLEW_GET_FUN(__glewAllocMPEGPredictorsSGIX)
+#define glDeleteMPEGPredictorsSGIX GLEW_GET_FUN(__glewDeleteMPEGPredictorsSGIX)
+#define glGenMPEGPredictorsSGIX GLEW_GET_FUN(__glewGenMPEGPredictorsSGIX)
+#define glGetMPEGParameterfvSGIX GLEW_GET_FUN(__glewGetMPEGParameterfvSGIX)
+#define glGetMPEGParameterivSGIX GLEW_GET_FUN(__glewGetMPEGParameterivSGIX)
+#define glGetMPEGPredictorSGIX GLEW_GET_FUN(__glewGetMPEGPredictorSGIX)
+#define glGetMPEGQuantTableubv GLEW_GET_FUN(__glewGetMPEGQuantTableubv)
+#define glIsMPEGPredictorSGIX GLEW_GET_FUN(__glewIsMPEGPredictorSGIX)
+#define glMPEGPredictorSGIX GLEW_GET_FUN(__glewMPEGPredictorSGIX)
+#define glMPEGQuantTableubv GLEW_GET_FUN(__glewMPEGQuantTableubv)
+#define glSwapMPEGPredictorsSGIX GLEW_GET_FUN(__glewSwapMPEGPredictorsSGIX)
+
+#define GLEW_SGIX_mpeg1 GLEW_GET_VAR(__GLEW_SGIX_mpeg1)
+
+#endif /* GL_SGIX_mpeg1 */
+
+/* ----------------------------- GL_SGIX_mpeg2 ----------------------------- */
+
+#ifndef GL_SGIX_mpeg2
+#define GL_SGIX_mpeg2 1
+
+#define GLEW_SGIX_mpeg2 GLEW_GET_VAR(__GLEW_SGIX_mpeg2)
+
+#endif /* GL_SGIX_mpeg2 */
+
+/* ------------------ GL_SGIX_nonlinear_lighting_pervertex ----------------- */
+
+#ifndef GL_SGIX_nonlinear_lighting_pervertex
+#define GL_SGIX_nonlinear_lighting_pervertex 1
+
+typedef void (GLAPIENTRY * PFNGLGETNONLINLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLint* terms, GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLGETNONLINMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLint* terms, const GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLNONLINLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLint terms, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLNONLINMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLint terms, const GLfloat* params);
+
+#define glGetNonlinLightfvSGIX GLEW_GET_FUN(__glewGetNonlinLightfvSGIX)
+#define glGetNonlinMaterialfvSGIX GLEW_GET_FUN(__glewGetNonlinMaterialfvSGIX)
+#define glNonlinLightfvSGIX GLEW_GET_FUN(__glewNonlinLightfvSGIX)
+#define glNonlinMaterialfvSGIX GLEW_GET_FUN(__glewNonlinMaterialfvSGIX)
+
+#define GLEW_SGIX_nonlinear_lighting_pervertex GLEW_GET_VAR(__GLEW_SGIX_nonlinear_lighting_pervertex)
+
+#endif /* GL_SGIX_nonlinear_lighting_pervertex */
+
+/* --------------------------- GL_SGIX_nurbs_eval -------------------------- */
+
+#ifndef GL_SGIX_nurbs_eval
+#define GL_SGIX_nurbs_eval 1
+
+#define GL_MAP1_VERTEX_3_NURBS_SGIX 0x81CB
+#define GL_MAP1_VERTEX_4_NURBS_SGIX 0x81CC
+#define GL_MAP1_INDEX_NURBS_SGIX 0x81CD
+#define GL_MAP1_COLOR_4_NURBS_SGIX 0x81CE
+#define GL_MAP1_NORMAL_NURBS_SGIX 0x81CF
+#define GL_MAP1_TEXTURE_COORD_1_NURBS_SGIX 0x81E0
+#define GL_MAP1_TEXTURE_COORD_2_NURBS_SGIX 0x81E1
+#define GL_MAP1_TEXTURE_COORD_3_NURBS_SGIX 0x81E2
+#define GL_MAP1_TEXTURE_COORD_4_NURBS_SGIX 0x81E3
+#define GL_MAP2_VERTEX_3_NURBS_SGIX 0x81E4
+#define GL_MAP2_VERTEX_4_NURBS_SGIX 0x81E5
+#define GL_MAP2_INDEX_NURBS_SGIX 0x81E6
+#define GL_MAP2_COLOR_4_NURBS_SGIX 0x81E7
+#define GL_MAP2_NORMAL_NURBS_SGIX 0x81E8
+#define GL_MAP2_TEXTURE_COORD_1_NURBS_SGIX 0x81E9
+#define GL_MAP2_TEXTURE_COORD_2_NURBS_SGIX 0x81EA
+#define GL_MAP2_TEXTURE_COORD_3_NURBS_SGIX 0x81EB
+#define GL_MAP2_TEXTURE_COORD_4_NURBS_SGIX 0x81EC
+#define GL_NURBS_KNOT_COUNT_SGIX 0x81ED
+#define GL_NURBS_KNOT_VECTOR_SGIX 0x81EE
+
+#define GLEW_SGIX_nurbs_eval GLEW_GET_VAR(__GLEW_SGIX_nurbs_eval)
+
+#endif /* GL_SGIX_nurbs_eval */
+
+/* ---------------------- GL_SGIX_occlusion_instrument --------------------- */
+
+#ifndef GL_SGIX_occlusion_instrument
+#define GL_SGIX_occlusion_instrument 1
+
+#define GL_OCCLUSION_INSTRUMENT_SGIX 0x6060
+
+#define GLEW_SGIX_occlusion_instrument GLEW_GET_VAR(__GLEW_SGIX_occlusion_instrument)
+
+#endif /* GL_SGIX_occlusion_instrument */
+
+/* ------------------------- GL_SGIX_packed_6bytes ------------------------- */
+
+#ifndef GL_SGIX_packed_6bytes
+#define GL_SGIX_packed_6bytes 1
+
+#define GLEW_SGIX_packed_6bytes GLEW_GET_VAR(__GLEW_SGIX_packed_6bytes)
+
+#endif /* GL_SGIX_packed_6bytes */
+
+/* ------------------------- GL_SGIX_pixel_texture ------------------------- */
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+
+typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+
+#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX)
+
+#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture)
+
+#endif /* GL_SGIX_pixel_texture */
+
+/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */
+
+#ifndef GL_SGIX_pixel_texture_bits
+#define GL_SGIX_pixel_texture_bits 1
+
+#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits)
+
+#endif /* GL_SGIX_pixel_texture_bits */
+
+/* ----------------------- GL_SGIX_pixel_texture_lod ----------------------- */
+
+#ifndef GL_SGIX_pixel_texture_lod
+#define GL_SGIX_pixel_texture_lod 1
+
+#define GLEW_SGIX_pixel_texture_lod GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_lod)
+
+#endif /* GL_SGIX_pixel_texture_lod */
+
+/* -------------------------- GL_SGIX_pixel_tiles -------------------------- */
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_SGIX_pixel_tiles 1
+
+#define GLEW_SGIX_pixel_tiles GLEW_GET_VAR(__GLEW_SGIX_pixel_tiles)
+
+#endif /* GL_SGIX_pixel_tiles */
+
+/* ------------------------- GL_SGIX_polynomial_ffd ------------------------ */
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_SGIX_polynomial_ffd 1
+
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x1
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x2
+
+typedef void (GLAPIENTRY * PFNGLDEFORMSGIXPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask);
+
+#define glDeformSGIX GLEW_GET_FUN(__glewDeformSGIX)
+#define glLoadIdentityDeformationMapSGIX GLEW_GET_FUN(__glewLoadIdentityDeformationMapSGIX)
+
+#define GLEW_SGIX_polynomial_ffd GLEW_GET_VAR(__GLEW_SGIX_polynomial_ffd)
+
+#endif /* GL_SGIX_polynomial_ffd */
+
+/* --------------------------- GL_SGIX_quad_mesh --------------------------- */
+
+#ifndef GL_SGIX_quad_mesh
+#define GL_SGIX_quad_mesh 1
+
+typedef void (GLAPIENTRY * PFNGLMESHBREADTHSGIXPROC) (GLint breadth);
+typedef void (GLAPIENTRY * PFNGLMESHSTRIDESGIXPROC) (GLint stride);
+
+#define glMeshBreadthSGIX GLEW_GET_FUN(__glewMeshBreadthSGIX)
+#define glMeshStrideSGIX GLEW_GET_FUN(__glewMeshStrideSGIX)
+
+#define GLEW_SGIX_quad_mesh GLEW_GET_VAR(__GLEW_SGIX_quad_mesh)
+
+#endif /* GL_SGIX_quad_mesh */
+
+/* ------------------------ GL_SGIX_reference_plane ------------------------ */
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+
+typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation);
+
+#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX)
+
+#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane)
+
+#endif /* GL_SGIX_reference_plane */
+
+/* ---------------------------- GL_SGIX_resample --------------------------- */
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+
+#define GL_PACK_RESAMPLE_SGIX 0x842E
+#define GL_UNPACK_RESAMPLE_SGIX 0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#define GL_RESAMPLE_REPLICATE_SGIX 0x8433
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434
+
+#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample)
+
+#endif /* GL_SGIX_resample */
+
+/* ------------------------- GL_SGIX_scalebias_hint ------------------------ */
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SGIX_scalebias_hint 1
+
+#define GL_SCALEBIAS_HINT_SGIX 0x8322
+
+#define GLEW_SGIX_scalebias_hint GLEW_GET_VAR(__GLEW_SGIX_scalebias_hint)
+
+#endif /* GL_SGIX_scalebias_hint */
+
+/* ----------------------------- GL_SGIX_shadow ---------------------------- */
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+
+#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow)
+
+#endif /* GL_SGIX_shadow */
+
+/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+
+#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient)
+
+#endif /* GL_SGIX_shadow_ambient */
+
+/* ------------------------------ GL_SGIX_slim ----------------------------- */
+
+#ifndef GL_SGIX_slim
+#define GL_SGIX_slim 1
+
+#define GL_PACK_MAX_COMPRESSED_SIZE_SGIX 0x831B
+#define GL_SLIM8U_SGIX 0x831D
+#define GL_SLIM10U_SGIX 0x831E
+#define GL_SLIM12S_SGIX 0x831F
+
+#define GLEW_SGIX_slim GLEW_GET_VAR(__GLEW_SGIX_slim)
+
+#endif /* GL_SGIX_slim */
+
+/* ------------------------ GL_SGIX_spotlight_cutoff ----------------------- */
+
+#ifndef GL_SGIX_spotlight_cutoff
+#define GL_SGIX_spotlight_cutoff 1
+
+#define GL_SPOT_CUTOFF_DELTA_SGIX 0x8193
+
+#define GLEW_SGIX_spotlight_cutoff GLEW_GET_VAR(__GLEW_SGIX_spotlight_cutoff)
+
+#endif /* GL_SGIX_spotlight_cutoff */
+
+/* ----------------------------- GL_SGIX_sprite ---------------------------- */
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params);
+
+#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX)
+#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX)
+#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX)
+#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX)
+
+#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite)
+
+#endif /* GL_SGIX_sprite */
+
+/* -------------------------- GL_SGIX_subdiv_patch ------------------------- */
+
+#ifndef GL_SGIX_subdiv_patch
+#define GL_SGIX_subdiv_patch 1
+
+#define GLEW_SGIX_subdiv_patch GLEW_GET_VAR(__GLEW_SGIX_subdiv_patch)
+
+#endif /* GL_SGIX_subdiv_patch */
+
+/* --------------------------- GL_SGIX_subsample --------------------------- */
+
+#ifndef GL_SGIX_subsample
+#define GL_SGIX_subsample 1
+
+#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+
+#define GLEW_SGIX_subsample GLEW_GET_VAR(__GLEW_SGIX_subsample)
+
+#endif /* GL_SGIX_subsample */
+
+/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+
+typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+
+#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX)
+
+#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer)
+
+#endif /* GL_SGIX_tag_sample_buffer */
+
+/* ------------------------ GL_SGIX_texture_add_env ------------------------ */
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+
+#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env)
+
+#endif /* GL_SGIX_texture_add_env */
+
+/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_SGIX_texture_coordinate_clamp 1
+
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+
+#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp)
+
+#endif /* GL_SGIX_texture_coordinate_clamp */
+
+/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+
+#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias)
+
+#endif /* GL_SGIX_texture_lod_bias */
+
+/* ------------------- GL_SGIX_texture_mipmap_anisotropic ------------------ */
+
+#ifndef GL_SGIX_texture_mipmap_anisotropic
+#define GL_SGIX_texture_mipmap_anisotropic 1
+
+#define GL_TEXTURE_MIPMAP_ANISOTROPY_SGIX 0x832E
+#define GL_MAX_MIPMAP_ANISOTROPY_SGIX 0x832F
+
+#define GLEW_SGIX_texture_mipmap_anisotropic GLEW_GET_VAR(__GLEW_SGIX_texture_mipmap_anisotropic)
+
+#endif /* GL_SGIX_texture_mipmap_anisotropic */
+
+/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+
+#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer)
+
+#endif /* GL_SGIX_texture_multi_buffer */
+
+/* ------------------------- GL_SGIX_texture_phase ------------------------- */
+
+#ifndef GL_SGIX_texture_phase
+#define GL_SGIX_texture_phase 1
+
+#define GL_PHASE_SGIX 0x832A
+
+#define GLEW_SGIX_texture_phase GLEW_GET_VAR(__GLEW_SGIX_texture_phase)
+
+#endif /* GL_SGIX_texture_phase */
+
+/* ------------------------- GL_SGIX_texture_range ------------------------- */
+
+#ifndef GL_SGIX_texture_range
+#define GL_SGIX_texture_range 1
+
+#define GL_RGB_SIGNED_SGIX 0x85E0
+#define GL_RGBA_SIGNED_SGIX 0x85E1
+#define GL_ALPHA_SIGNED_SGIX 0x85E2
+#define GL_LUMINANCE_SIGNED_SGIX 0x85E3
+#define GL_INTENSITY_SIGNED_SGIX 0x85E4
+#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5
+#define GL_RGB16_SIGNED_SGIX 0x85E6
+#define GL_RGBA16_SIGNED_SGIX 0x85E7
+#define GL_ALPHA16_SIGNED_SGIX 0x85E8
+#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9
+#define GL_INTENSITY16_SIGNED_SGIX 0x85EA
+#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB
+#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC
+#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED
+#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE
+#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF
+#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0
+#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1
+#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2
+#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3
+#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4
+#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5
+#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6
+#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7
+#define GL_MIN_LUMINANCE_SGIS 0x85F8
+#define GL_MAX_LUMINANCE_SGIS 0x85F9
+#define GL_MIN_INTENSITY_SGIS 0x85FA
+#define GL_MAX_INTENSITY_SGIS 0x85FB
+
+#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range)
+
+#endif /* GL_SGIX_texture_range */
+
+/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+
+#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias)
+
+#endif /* GL_SGIX_texture_scale_bias */
+
+/* ---------------------- GL_SGIX_texture_supersample ---------------------- */
+
+#ifndef GL_SGIX_texture_supersample
+#define GL_SGIX_texture_supersample 1
+
+#define GLEW_SGIX_texture_supersample GLEW_GET_VAR(__GLEW_SGIX_texture_supersample)
+
+#endif /* GL_SGIX_texture_supersample */
+
+/* --------------------------- GL_SGIX_vector_ops -------------------------- */
+
+#ifndef GL_SGIX_vector_ops
+#define GL_SGIX_vector_ops 1
+
+typedef void (GLAPIENTRY * PFNGLGETVECTOROPERATIONSGIXPROC) (GLenum operation);
+typedef void (GLAPIENTRY * PFNGLVECTOROPERATIONSGIXPROC) (GLenum operation);
+
+#define glGetVectorOperationSGIX GLEW_GET_FUN(__glewGetVectorOperationSGIX)
+#define glVectorOperationSGIX GLEW_GET_FUN(__glewVectorOperationSGIX)
+
+#define GLEW_SGIX_vector_ops GLEW_GET_VAR(__GLEW_SGIX_vector_ops)
+
+#endif /* GL_SGIX_vector_ops */
+
+/* ---------------------- GL_SGIX_vertex_array_object ---------------------- */
+
+#ifndef GL_SGIX_vertex_array_object
+#define GL_SGIX_vertex_array_object 1
+
+typedef GLboolean (GLAPIENTRY * PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC) (GLsizei n, const GLuint* arrays, GLboolean* residences);
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYSGIXPROC) (GLuint array);
+typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSSGIXPROC) (GLsizei n, const GLuint* arrays);
+typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSSGIXPROC) (GLsizei n, GLuint* arrays);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYSGIXPROC) (GLuint array);
+typedef void (GLAPIENTRY * PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC) (GLsizei n, const GLuint* arrays, const GLclampf* priorities);
+
+#define glAreVertexArraysResidentSGIX GLEW_GET_FUN(__glewAreVertexArraysResidentSGIX)
+#define glBindVertexArraySGIX GLEW_GET_FUN(__glewBindVertexArraySGIX)
+#define glDeleteVertexArraysSGIX GLEW_GET_FUN(__glewDeleteVertexArraysSGIX)
+#define glGenVertexArraysSGIX GLEW_GET_FUN(__glewGenVertexArraysSGIX)
+#define glIsVertexArraySGIX GLEW_GET_FUN(__glewIsVertexArraySGIX)
+#define glPrioritizeVertexArraysSGIX GLEW_GET_FUN(__glewPrioritizeVertexArraysSGIX)
+
+#define GLEW_SGIX_vertex_array_object GLEW_GET_VAR(__GLEW_SGIX_vertex_array_object)
+
+#endif /* GL_SGIX_vertex_array_object */
+
+/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_SGIX_vertex_preclip 1
+
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+
+#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip)
+
+#endif /* GL_SGIX_vertex_preclip */
+
+/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */
+
+#ifndef GL_SGIX_vertex_preclip_hint
+#define GL_SGIX_vertex_preclip_hint 1
+
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+
+#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint)
+
+#endif /* GL_SGIX_vertex_preclip_hint */
+
+/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+
+#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb)
+
+#endif /* GL_SGIX_ycrcb */
+
+/* ------------------------ GL_SGIX_ycrcb_subsample ------------------------ */
+
+#ifndef GL_SGIX_ycrcb_subsample
+#define GL_SGIX_ycrcb_subsample 1
+
+#define GLEW_SGIX_ycrcb_subsample GLEW_GET_VAR(__GLEW_SGIX_ycrcb_subsample)
+
+#endif /* GL_SGIX_ycrcb_subsample */
+
+/* ----------------------------- GL_SGIX_ycrcba ---------------------------- */
+
+#ifndef GL_SGIX_ycrcba
+#define GL_SGIX_ycrcba 1
+
+#define GL_YCRCB_SGIX 0x8318
+#define GL_YCRCBA_SGIX 0x8319
+
+#define GLEW_SGIX_ycrcba GLEW_GET_VAR(__GLEW_SGIX_ycrcba)
+
+#endif /* GL_SGIX_ycrcba */
+
+/* -------------------------- GL_SGI_color_matrix -------------------------- */
+
+#ifndef GL_SGI_color_matrix
+#define GL_SGI_color_matrix 1
+
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+
+#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix)
+
+#endif /* GL_SGI_color_matrix */
+
+/* --------------------------- GL_SGI_color_table -------------------------- */
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table);
+
+#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI)
+#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI)
+#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI)
+#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI)
+#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI)
+#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI)
+#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI)
+
+#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table)
+
+#endif /* GL_SGI_color_table */
+
+/* ----------------------------- GL_SGI_complex ---------------------------- */
+
+#ifndef GL_SGI_complex
+#define GL_SGI_complex 1
+
+#define GLEW_SGI_complex GLEW_GET_VAR(__GLEW_SGI_complex)
+
+#endif /* GL_SGI_complex */
+
+/* -------------------------- GL_SGI_complex_type -------------------------- */
+
+#ifndef GL_SGI_complex_type
+#define GL_SGI_complex_type 1
+
+#define GL_COMPLEX_UNSIGNED_BYTE_SGI 0x81BD
+#define GL_COMPLEX_BYTE_SGI 0x81BE
+#define GL_COMPLEX_UNSIGNED_SHORT_SGI 0x81BF
+#define GL_COMPLEX_SHORT_SGI 0x81C0
+#define GL_COMPLEX_UNSIGNED_INT_SGI 0x81C1
+#define GL_COMPLEX_INT_SGI 0x81C2
+#define GL_COMPLEX_FLOAT_SGI 0x81C3
+
+#define GLEW_SGI_complex_type GLEW_GET_VAR(__GLEW_SGI_complex_type)
+
+#endif /* GL_SGI_complex_type */
+
+/* ------------------------------- GL_SGI_fft ------------------------------ */
+
+#ifndef GL_SGI_fft
+#define GL_SGI_fft 1
+
+#define GL_PIXEL_TRANSFORM_OPERATOR_SGI 0x81C4
+#define GL_CONVOLUTION_SGI 0x81C5
+#define GL_FFT_1D_SGI 0x81C6
+#define GL_PIXEL_TRANSFORM_SGI 0x81C7
+#define GL_MAX_FFT_WIDTH_SGI 0x81C8
+
+typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFSGIPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERISGIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMSGIPROC) (GLenum target);
+
+#define glGetPixelTransformParameterfvSGI GLEW_GET_FUN(__glewGetPixelTransformParameterfvSGI)
+#define glGetPixelTransformParameterivSGI GLEW_GET_FUN(__glewGetPixelTransformParameterivSGI)
+#define glPixelTransformParameterfSGI GLEW_GET_FUN(__glewPixelTransformParameterfSGI)
+#define glPixelTransformParameterfvSGI GLEW_GET_FUN(__glewPixelTransformParameterfvSGI)
+#define glPixelTransformParameteriSGI GLEW_GET_FUN(__glewPixelTransformParameteriSGI)
+#define glPixelTransformParameterivSGI GLEW_GET_FUN(__glewPixelTransformParameterivSGI)
+#define glPixelTransformSGI GLEW_GET_FUN(__glewPixelTransformSGI)
+
+#define GLEW_SGI_fft GLEW_GET_VAR(__GLEW_SGI_fft)
+
+#endif /* GL_SGI_fft */
+
+/* ----------------------- GL_SGI_texture_color_table ---------------------- */
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+
+#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table)
+
+#endif /* GL_SGI_texture_color_table */
+
+/* ------------------------- GL_SUNX_constant_data ------------------------- */
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+
+typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void);
+
+#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX)
+
+#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data)
+
+#endif /* GL_SUNX_constant_data */
+
+/* -------------------- GL_SUN_convolution_border_modes -------------------- */
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+
+#define GL_WRAP_BORDER_SUN 0x81D4
+
+#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes)
+
+#endif /* GL_SUN_convolution_border_modes */
+
+/* -------------------------- GL_SUN_global_alpha -------------------------- */
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+
+#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN)
+#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN)
+#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN)
+#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN)
+#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN)
+#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN)
+#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN)
+#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN)
+
+#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha)
+
+#endif /* GL_SUN_global_alpha */
+
+/* --------------------------- GL_SUN_mesh_array --------------------------- */
+
+#ifndef GL_SUN_mesh_array
+#define GL_SUN_mesh_array 1
+
+#define GL_QUAD_MESH_SUN 0x8614
+#define GL_TRIANGLE_MESH_SUN 0x8615
+
+#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array)
+
+#endif /* GL_SUN_mesh_array */
+
+/* ------------------------ GL_SUN_read_video_pixels ----------------------- */
+
+#ifndef GL_SUN_read_video_pixels
+#define GL_SUN_read_video_pixels 1
+
+typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
+
+#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN)
+
+#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels)
+
+#endif /* GL_SUN_read_video_pixels */
+
+/* --------------------------- GL_SUN_slice_accum -------------------------- */
+
+#ifndef GL_SUN_slice_accum
+#define GL_SUN_slice_accum 1
+
+#define GL_SLICE_ACCUM_SUN 0x85CC
+
+#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum)
+
+#endif /* GL_SUN_slice_accum */
+
+/* -------------------------- GL_SUN_triangle_list ------------------------- */
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+
+#define GL_RESTART_SUN 0x01
+#define GL_REPLACE_MIDDLE_SUN 0x02
+#define GL_REPLACE_OLDEST_SUN 0x03
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void *pointer);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code);
+
+#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN)
+#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN)
+#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN)
+#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN)
+#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN)
+#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN)
+#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN)
+
+#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list)
+
+#endif /* GL_SUN_triangle_list */
+
+/* ----------------------------- GL_SUN_vertex ----------------------------- */
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+
+typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v);
+
+#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN)
+#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN)
+#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN)
+#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN)
+#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN)
+#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN)
+#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN)
+#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN)
+#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN)
+#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN)
+#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN)
+#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN)
+#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN)
+#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN)
+#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN)
+#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN)
+#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN)
+#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN)
+#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN)
+#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN)
+#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN)
+#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN)
+#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN)
+#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN)
+#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN)
+#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN)
+#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN)
+#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN)
+#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN)
+#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN)
+#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN)
+#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN)
+#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN)
+#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN)
+#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN)
+#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN)
+#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN)
+#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN)
+#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN)
+#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN)
+
+#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex)
+
+#endif /* GL_SUN_vertex */
+
+/* -------------------------- GL_WIN_phong_shading ------------------------- */
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+
+#define GL_PHONG_WIN 0x80EA
+#define GL_PHONG_HINT_WIN 0x80EB
+
+#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading)
+
+#endif /* GL_WIN_phong_shading */
+
+/* ------------------------- GL_WIN_scene_markerXXX ------------------------ */
+
+#ifndef GL_WIN_scene_markerXXX
+#define GL_WIN_scene_markerXXX 1
+
+#define GLEW_WIN_scene_markerXXX GLEW_GET_VAR(__GLEW_WIN_scene_markerXXX)
+
+#endif /* GL_WIN_scene_markerXXX */
+
+/* -------------------------- GL_WIN_specular_fog -------------------------- */
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+
+#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog)
+
+#endif /* GL_WIN_specular_fog */
+
+/* ---------------------------- GL_WIN_swap_hint --------------------------- */
+
+#ifndef GL_WIN_swap_hint
+#define GL_WIN_swap_hint 1
+
+typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN)
+
+#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint)
+
+#endif /* GL_WIN_swap_hint */
+
+/* ------------------------------------------------------------------------- */
+
+
+
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D;
+
+GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture;
+GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage;
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd;
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv;
+GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage;
+
+GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate;
+GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer;
+GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData;
+GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData;
+GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers;
+GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries;
+GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery;
+GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers;
+GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv;
+GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv;
+GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv;
+GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer;
+GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery;
+GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer;
+GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer;
+
+GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader;
+GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate;
+GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader;
+GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram;
+GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram;
+GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader;
+GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray;
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray;
+GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform;
+GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders;
+GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv;
+GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog;
+GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource;
+GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv;
+GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram;
+GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader;
+GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram;
+GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource;
+GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate;
+GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate;
+GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv;
+GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram;
+GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer;
+
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv;
+
+GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender;
+GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback;
+GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation;
+GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv;
+GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski;
+GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei;
+GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei;
+GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender;
+GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback;
+GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v;
+GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation;
+GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv;
+GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced;
+GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex;
+GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v;
+GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v;
+
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIPROC __glewBlendEquationi;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCIPROC __glewBlendFunci;
+GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading;
+
+GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSPROC __glewGetGraphicsResetStatus;
+GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEPROC __glewGetnCompressedTexImage;
+GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEPROC __glewGetnTexImage;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVPROC __glewGetnUniformdv;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC __glewMultiDrawArraysIndirectCount;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC __glewMultiDrawElementsIndirectCount;
+GLEW_FUN_EXPORT PFNGLSPECIALIZESHADERPROC __glewSpecializeShader;
+
+GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX;
+
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD;
+GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewFramebufferSamplePositionsfvAMD;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC __glewGetFramebufferParameterfvAMD;
+GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC __glewGetNamedFramebufferParameterfvAMD;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewNamedFramebufferSamplePositionsfvAMD;
+
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD;
+
+GLEW_FUN_EXPORT PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD;
+GLEW_FUN_EXPORT PFNGLGENNAMESAMDPROC __glewGenNamesAMD;
+GLEW_FUN_EXPORT PFNGLISNAMEAMDPROC __glewIsNameAMD;
+
+GLEW_FUN_EXPORT PFNGLQUERYOBJECTPARAMETERUIAMDPROC __glewQueryObjectParameteruiAMD;
+
+GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD;
+GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD;
+GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD;
+GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD;
+GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD;
+
+GLEW_FUN_EXPORT PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD;
+
+GLEW_FUN_EXPORT PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD;
+
+GLEW_FUN_EXPORT PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD;
+
+GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD;
+GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD;
+
+GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE;
+GLEW_FUN_EXPORT PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE;
+GLEW_FUN_EXPORT PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE;
+GLEW_FUN_EXPORT PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE;
+GLEW_FUN_EXPORT PFNGLISQUERYANGLEPROC __glewIsQueryANGLE;
+GLEW_FUN_EXPORT PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE;
+
+GLEW_FUN_EXPORT PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE;
+
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURELEVELSAPPLEPROC __glewCopyTextureLevelsAPPLE;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE;
+
+GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE;
+GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE;
+GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE;
+GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE;
+
+GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE;
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC __glewRenderbufferStorageMultisampleAPPLE;
+GLEW_FUN_EXPORT PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC __glewResolveMultisampleFramebufferAPPLE;
+
+GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE;
+GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE;
+GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE;
+
+GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCAPPLEPROC __glewClientWaitSyncAPPLE;
+GLEW_FUN_EXPORT PFNGLDELETESYNCAPPLEPROC __glewDeleteSyncAPPLE;
+GLEW_FUN_EXPORT PFNGLFENCESYNCAPPLEPROC __glewFenceSyncAPPLE;
+GLEW_FUN_EXPORT PFNGLGETINTEGER64VAPPLEPROC __glewGetInteger64vAPPLE;
+GLEW_FUN_EXPORT PFNGLGETSYNCIVAPPLEPROC __glewGetSyncivAPPLE;
+GLEW_FUN_EXPORT PFNGLISSYNCAPPLEPROC __glewIsSyncAPPLE;
+GLEW_FUN_EXPORT PFNGLWAITSYNCAPPLEPROC __glewWaitSyncAPPLE;
+
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE;
+GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE;
+
+GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE;
+GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE;
+GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE;
+
+GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE;
+
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE;
+GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE;
+
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHFPROC __glewClearDepthf;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEFPROC __glewDepthRangef;
+GLEW_FUN_EXPORT PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat;
+GLEW_FUN_EXPORT PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler;
+GLEW_FUN_EXPORT PFNGLSHADERBINARYPROC __glewShaderBinary;
+
+GLEW_FUN_EXPORT PFNGLMEMORYBARRIERBYREGIONPROC __glewMemoryBarrierByRegion;
+
+GLEW_FUN_EXPORT PFNGLPRIMITIVEBOUNDINGBOXARBPROC __glewPrimitiveBoundingBoxARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance;
+
+GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB;
+GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB;
+GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed;
+GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex;
+
+GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEPROC __glewBufferStorage;
+
+GLEW_FUN_EXPORT PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB;
+
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERDATAPROC __glewClearBufferData;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT;
+
+GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEPROC __glewClearTexImage;
+GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage;
+
+GLEW_FUN_EXPORT PFNGLCLIPCONTROLPROC __glewClipControl;
+
+GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB;
+
+GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute;
+GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect;
+
+GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB;
+
+GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData;
+
+GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData;
+
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB;
+GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB;
+
+GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPROC __glewBindTextureUnit;
+GLEW_FUN_EXPORT PFNGLBLITNAMEDFRAMEBUFFERPROC __glewBlitNamedFramebuffer;
+GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC __glewCheckNamedFramebufferStatus;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAPROC __glewClearNamedBufferData;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAPROC __glewClearNamedBufferSubData;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERFIPROC __glewClearNamedFramebufferfi;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERFVPROC __glewClearNamedFramebufferfv;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERIVPROC __glewClearNamedFramebufferiv;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC __glewClearNamedFramebufferuiv;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC __glewCompressedTextureSubImage1D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC __glewCompressedTextureSubImage2D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC __glewCompressedTextureSubImage3D;
+GLEW_FUN_EXPORT PFNGLCOPYNAMEDBUFFERSUBDATAPROC __glewCopyNamedBufferSubData;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DPROC __glewCopyTextureSubImage1D;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DPROC __glewCopyTextureSubImage2D;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DPROC __glewCopyTextureSubImage3D;
+GLEW_FUN_EXPORT PFNGLCREATEBUFFERSPROC __glewCreateBuffers;
+GLEW_FUN_EXPORT PFNGLCREATEFRAMEBUFFERSPROC __glewCreateFramebuffers;
+GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPIPELINESPROC __glewCreateProgramPipelines;
+GLEW_FUN_EXPORT PFNGLCREATEQUERIESPROC __glewCreateQueries;
+GLEW_FUN_EXPORT PFNGLCREATERENDERBUFFERSPROC __glewCreateRenderbuffers;
+GLEW_FUN_EXPORT PFNGLCREATESAMPLERSPROC __glewCreateSamplers;
+GLEW_FUN_EXPORT PFNGLCREATETEXTURESPROC __glewCreateTextures;
+GLEW_FUN_EXPORT PFNGLCREATETRANSFORMFEEDBACKSPROC __glewCreateTransformFeedbacks;
+GLEW_FUN_EXPORT PFNGLCREATEVERTEXARRAYSPROC __glewCreateVertexArrays;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBPROC __glewDisableVertexArrayAttrib;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBPROC __glewEnableVertexArrayAttrib;
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC __glewFlushMappedNamedBufferRange;
+GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPPROC __glewGenerateTextureMipmap;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC __glewGetCompressedTextureImage;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERI64VPROC __glewGetNamedBufferParameteri64v;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVPROC __glewGetNamedBufferParameteriv;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVPROC __glewGetNamedBufferPointerv;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAPROC __glewGetNamedBufferSubData;
+GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetNamedFramebufferAttachmentParameteriv;
+GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC __glewGetNamedFramebufferParameteriv;
+GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC __glewGetNamedRenderbufferParameteriv;
+GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTI64VPROC __glewGetQueryBufferObjecti64v;
+GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTIVPROC __glewGetQueryBufferObjectiv;
+GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTUI64VPROC __glewGetQueryBufferObjectui64v;
+GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTUIVPROC __glewGetQueryBufferObjectuiv;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEPROC __glewGetTextureImage;
+GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVPROC __glewGetTextureLevelParameterfv;
+GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVPROC __glewGetTextureLevelParameteriv;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVPROC __glewGetTextureParameterIiv;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVPROC __glewGetTextureParameterIuiv;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVPROC __glewGetTextureParameterfv;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVPROC __glewGetTextureParameteriv;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKI64_VPROC __glewGetTransformFeedbacki64_v;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKI_VPROC __glewGetTransformFeedbacki_v;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKIVPROC __glewGetTransformFeedbackiv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINDEXED64IVPROC __glewGetVertexArrayIndexed64iv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINDEXEDIVPROC __glewGetVertexArrayIndexediv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYIVPROC __glewGetVertexArrayiv;
+GLEW_FUN_EXPORT PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC __glewInvalidateNamedFramebufferData;
+GLEW_FUN_EXPORT PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC __glewInvalidateNamedFramebufferSubData;
+GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERPROC __glewMapNamedBuffer;
+GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEPROC __glewMapNamedBufferRange;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAPROC __glewNamedBufferData;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEPROC __glewNamedBufferStorage;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAPROC __glewNamedBufferSubData;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC __glewNamedFramebufferDrawBuffer;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC __glewNamedFramebufferDrawBuffers;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC __glewNamedFramebufferParameteri;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC __glewNamedFramebufferReadBuffer;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC __glewNamedFramebufferRenderbuffer;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREPROC __glewNamedFramebufferTexture;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC __glewNamedFramebufferTextureLayer;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEPROC __glewNamedRenderbufferStorage;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewNamedRenderbufferStorageMultisample;
+GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERPROC __glewTextureBuffer;
+GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEPROC __glewTextureBufferRange;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVPROC __glewTextureParameterIiv;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVPROC __glewTextureParameterIuiv;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFPROC __glewTextureParameterf;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVPROC __glewTextureParameterfv;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIPROC __glewTextureParameteri;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVPROC __glewTextureParameteriv;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DPROC __glewTextureStorage1D;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DPROC __glewTextureStorage2D;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC __glewTextureStorage2DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DPROC __glewTextureStorage3D;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC __glewTextureStorage3DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DPROC __glewTextureSubImage1D;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DPROC __glewTextureSubImage2D;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DPROC __glewTextureSubImage3D;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC __glewTransformFeedbackBufferBase;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC __glewTransformFeedbackBufferRange;
+GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFERPROC __glewUnmapNamedBuffer;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBBINDINGPROC __glewVertexArrayAttribBinding;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBFORMATPROC __glewVertexArrayAttribFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBIFORMATPROC __glewVertexArrayAttribIFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBLFORMATPROC __glewVertexArrayAttribLFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYBINDINGDIVISORPROC __glewVertexArrayBindingDivisor;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYELEMENTBUFFERPROC __glewVertexArrayElementBuffer;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBUFFERPROC __glewVertexArrayVertexBuffer;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBUFFERSPROC __glewVertexArrayVertexBuffers;
+
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv;
+GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer;
+GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer;
+GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer;
+GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus;
+GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers;
+GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer;
+GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers;
+GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers;
+GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv;
+GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv;
+GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer;
+GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer;
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage;
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB;
+
+GLEW_FUN_EXPORT PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary;
+GLEW_FUN_EXPORT PFNGLPROGRAMBINARYPROC __glewProgramBinary;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri;
+
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC __glewGetCompressedTextureSubImage;
+GLEW_FUN_EXPORT PFNGLGETTEXTURESUBIMAGEPROC __glewGetTextureSubImage;
+
+GLEW_FUN_EXPORT PFNGLSPECIALIZESHADERARBPROC __glewSpecializeShaderARB;
+
+GLEW_FUN_EXPORT PFNGLGETUNIFORMDVPROC __glewGetUniformdv;
+GLEW_FUN_EXPORT PFNGLUNIFORM1DPROC __glewUniform1d;
+GLEW_FUN_EXPORT PFNGLUNIFORM1DVPROC __glewUniform1dv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2DPROC __glewUniform2d;
+GLEW_FUN_EXPORT PFNGLUNIFORM2DVPROC __glewUniform2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3DPROC __glewUniform3d;
+GLEW_FUN_EXPORT PFNGLUNIFORM3DVPROC __glewUniform3dv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4DPROC __glewUniform4d;
+GLEW_FUN_EXPORT PFNGLUNIFORM4DVPROC __glewUniform4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv;
+
+GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VARBPROC __glewGetUniformi64vARB;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VARBPROC __glewGetUniformui64vARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMI64VARBPROC __glewGetnUniformi64vARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMUI64VARBPROC __glewGetnUniformui64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64ARBPROC __glewProgramUniform1i64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VARBPROC __glewProgramUniform1i64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64ARBPROC __glewProgramUniform1ui64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VARBPROC __glewProgramUniform1ui64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64ARBPROC __glewProgramUniform2i64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VARBPROC __glewProgramUniform2i64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64ARBPROC __glewProgramUniform2ui64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VARBPROC __glewProgramUniform2ui64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64ARBPROC __glewProgramUniform3i64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VARBPROC __glewProgramUniform3i64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64ARBPROC __glewProgramUniform3ui64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VARBPROC __glewProgramUniform3ui64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64ARBPROC __glewProgramUniform4i64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VARBPROC __glewProgramUniform4i64vARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64ARBPROC __glewProgramUniform4ui64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VARBPROC __glewProgramUniform4ui64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1I64ARBPROC __glewUniform1i64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1I64VARBPROC __glewUniform1i64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UI64ARBPROC __glewUniform1ui64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VARBPROC __glewUniform1ui64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2I64ARBPROC __glewUniform2i64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2I64VARBPROC __glewUniform2i64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UI64ARBPROC __glewUniform2ui64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VARBPROC __glewUniform2ui64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3I64ARBPROC __glewUniform3i64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3I64VARBPROC __glewUniform3i64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UI64ARBPROC __glewUniform3ui64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VARBPROC __glewUniform3ui64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4I64ARBPROC __glewUniform4i64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4I64VARBPROC __glewUniform4i64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UI64ARBPROC __glewUniform4ui64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VARBPROC __glewUniform4ui64vARB;
+
+GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv;
+GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter;
+GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram;
+GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax;
+GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram;
+GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax;
+GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB;
+
+GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ;
+
+GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v;
+
+GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData;
+GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData;
+GLEW_FUN_EXPORT PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer;
+GLEW_FUN_EXPORT PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer;
+GLEW_FUN_EXPORT PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage;
+GLEW_FUN_EXPORT PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage;
+
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange;
+GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange;
+
+GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB;
+
+GLEW_FUN_EXPORT PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange;
+GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures;
+GLEW_FUN_EXPORT PFNGLBINDSAMPLERSPROC __glewBindSamplers;
+GLEW_FUN_EXPORT PFNGLBINDTEXTURESPROC __glewBindTextures;
+GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect;
+
+GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB;
+
+GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB;
+GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB;
+GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB;
+GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB;
+GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB;
+GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB;
+GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB;
+
+GLEW_FUN_EXPORT PFNGLMAXSHADERCOMPILERTHREADSARBPROC __glewMaxShaderCompilerThreadsARB;
+
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB;
+
+GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETCLAMPPROC __glewPolygonOffsetClamp;
+
+GLEW_FUN_EXPORT PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv;
+
+GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex;
+
+GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB;
+GLEW_FUN_EXPORT PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB;
+GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB;
+GLEW_FUN_EXPORT PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB;
+GLEW_FUN_EXPORT PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB;
+GLEW_FUN_EXPORT PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB;
+GLEW_FUN_EXPORT PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB;
+GLEW_FUN_EXPORT PFNGLGETNMAPIVARBPROC __glewGetnMapivARB;
+GLEW_FUN_EXPORT PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB;
+GLEW_FUN_EXPORT PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB;
+GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB;
+GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB;
+GLEW_FUN_EXPORT PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB;
+GLEW_FUN_EXPORT PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB;
+GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB;
+GLEW_FUN_EXPORT PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewFramebufferSampleLocationsfvARB;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewNamedFramebufferSampleLocationsfvARB;
+
+GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB;
+
+GLEW_FUN_EXPORT PFNGLBINDSAMPLERPROC __glewBindSampler;
+GLEW_FUN_EXPORT PFNGLDELETESAMPLERSPROC __glewDeleteSamplers;
+GLEW_FUN_EXPORT PFNGLGENSAMPLERSPROC __glewGenSamplers;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv;
+GLEW_FUN_EXPORT PFNGLISSAMPLERPROC __glewIsSampler;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv;
+
+GLEW_FUN_EXPORT PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram;
+GLEW_FUN_EXPORT PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline;
+GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines;
+GLEW_FUN_EXPORT PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv;
+GLEW_FUN_EXPORT PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv;
+GLEW_FUN_EXPORT PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages;
+GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline;
+
+GLEW_FUN_EXPORT PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv;
+
+GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture;
+GLEW_FUN_EXPORT PFNGLMEMORYBARRIERPROC __glewMemoryBarrier;
+
+GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB;
+GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB;
+GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB;
+GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB;
+GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB;
+GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB;
+GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB;
+GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB;
+GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB;
+GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB;
+GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB;
+GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB;
+GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB;
+GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB;
+GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB;
+GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB;
+
+GLEW_FUN_EXPORT PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding;
+
+GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName;
+GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName;
+GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv;
+GLEW_FUN_EXPORT PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex;
+GLEW_FUN_EXPORT PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv;
+GLEW_FUN_EXPORT PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv;
+
+GLEW_FUN_EXPORT PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB;
+GLEW_FUN_EXPORT PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB;
+GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB;
+GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB;
+GLEW_FUN_EXPORT PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB;
+GLEW_FUN_EXPORT PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB;
+
+GLEW_FUN_EXPORT PFNGLBUFFERPAGECOMMITMENTARBPROC __glewBufferPageCommitmentARB;
+
+GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB;
+
+GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync;
+GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync;
+GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync;
+GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v;
+GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv;
+GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync;
+GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync;
+
+GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv;
+GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIPROC __glewPatchParameteri;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERPROC __glewTextureBarrier;
+
+GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB;
+
+GLEW_FUN_EXPORT PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange;
+GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT;
+
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB;
+
+GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv;
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample;
+
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DPROC __glewTexStorage1D;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DPROC __glewTexStorage2D;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DPROC __glewTexStorage3D;
+
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREVIEWPROC __glewTextureView;
+
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v;
+GLEW_FUN_EXPORT PFNGLQUERYCOUNTERPROC __glewQueryCounter;
+
+GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback;
+GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback;
+GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks;
+GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback;
+GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback;
+GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream;
+GLEW_FUN_EXPORT PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed;
+GLEW_FUN_EXPORT PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv;
+
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced;
+
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB;
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB;
+
+GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv;
+GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices;
+GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding;
+
+GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray;
+GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays;
+GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays;
+GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer;
+
+GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC __glewVertexArrayBindVertexBufferEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC __glewVertexArrayVertexAttribBindingEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC __glewVertexArrayVertexAttribFormatEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC __glewVertexArrayVertexAttribIFormatEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC __glewVertexArrayVertexAttribLFormatEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC __glewVertexArrayVertexBindingDivisorEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor;
+
+GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB;
+
+GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB;
+GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB;
+GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB;
+GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB;
+GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB;
+GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB;
+GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB;
+GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB;
+GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB;
+
+GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB;
+GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB;
+GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB;
+
+GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB;
+GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB;
+GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB;
+
+GLEW_FUN_EXPORT PFNGLCOLORP3UIPROC __glewColorP3ui;
+GLEW_FUN_EXPORT PFNGLCOLORP3UIVPROC __glewColorP3uiv;
+GLEW_FUN_EXPORT PFNGLCOLORP4UIPROC __glewColorP4ui;
+GLEW_FUN_EXPORT PFNGLCOLORP4UIVPROC __glewColorP4uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv;
+GLEW_FUN_EXPORT PFNGLNORMALP3UIPROC __glewNormalP3ui;
+GLEW_FUN_EXPORT PFNGLNORMALP3UIVPROC __glewNormalP3uiv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXP2UIPROC __glewVertexP2ui;
+GLEW_FUN_EXPORT PFNGLVERTEXP2UIVPROC __glewVertexP2uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXP3UIPROC __glewVertexP3ui;
+GLEW_FUN_EXPORT PFNGLVERTEXP3UIVPROC __glewVertexP3uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXP4UIPROC __glewVertexP4ui;
+GLEW_FUN_EXPORT PFNGLVERTEXP4UIVPROC __glewVertexP4uiv;
+
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v;
+GLEW_FUN_EXPORT PFNGLGETFLOATI_VPROC __glewGetFloati_v;
+GLEW_FUN_EXPORT PFNGLSCISSORARRAYVPROC __glewScissorArrayv;
+GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDPROC __glewScissorIndexed;
+GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv;
+GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv;
+GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf;
+GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv;
+
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI;
+GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI;
+
+GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI;
+GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI;
+GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI;
+GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI;
+
+GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI;
+GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI;
+GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI;
+GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI;
+GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI;
+GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI;
+GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI;
+GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI;
+GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI;
+GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI;
+
+GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI;
+
+GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI;
+GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI;
+
+GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI;
+GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI;
+
+GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI;
+GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI;
+GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI;
+GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI;
+GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI;
+GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI;
+GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI;
+GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI;
+
+GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI;
+GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC __glewDrawArraysInstancedBaseInstanceEXT;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseInstanceEXT;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseVertexBaseInstanceEXT;
+
+GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC __glewBindFragDataLocationIndexedEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXEXTPROC __glewGetFragDataIndexEXT;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC __glewGetProgramResourceLocationIndexEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT;
+
+GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEEXTPROC __glewBufferStorageEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT;
+
+GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEEXTPROC __glewClearTexImageEXT;
+GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEEXTPROC __glewClearTexSubImageEXT;
+
+GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT;
+
+GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT;
+GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT;
+
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT;
+GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT;
+
+GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT;
+GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAEXTPROC __glewCopyImageSubDataEXT;
+
+GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT;
+GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT;
+
+GLEW_FUN_EXPORT PFNGLGETOBJECTLABELEXTPROC __glewGetObjectLabelEXT;
+GLEW_FUN_EXPORT PFNGLLABELOBJECTEXTPROC __glewLabelObjectEXT;
+
+GLEW_FUN_EXPORT PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT;
+GLEW_FUN_EXPORT PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT;
+GLEW_FUN_EXPORT PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT;
+
+GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT;
+GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT;
+GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT;
+GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT;
+GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT;
+GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT;
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT;
+GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT;
+GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT;
+GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT;
+GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT;
+GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT;
+GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC __glewVertexArrayVertexAttribDivisorEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT;
+
+GLEW_FUN_EXPORT PFNGLDISCARDFRAMEBUFFEREXTPROC __glewDiscardFramebufferEXT;
+
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSEXTPROC __glewDrawBuffersEXT;
+
+GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT;
+GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT;
+GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIEXTPROC __glewBlendEquationSeparateiEXT;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIEXTPROC __glewBlendEquationiEXT;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIEXTPROC __glewBlendFuncSeparateiEXT;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCIEXTPROC __glewBlendFunciEXT;
+GLEW_FUN_EXPORT PFNGLCOLORMASKIEXTPROC __glewColorMaskiEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEIEXTPROC __glewDisableiEXT;
+GLEW_FUN_EXPORT PFNGLENABLEIEXTPROC __glewEnableiEXT;
+GLEW_FUN_EXPORT PFNGLISENABLEDIEXTPROC __glewIsEnablediEXT;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXEXTPROC __glewDrawElementsBaseVertexEXT;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC __glewDrawElementsInstancedBaseVertexEXT;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC __glewDrawRangeElementsBaseVertexEXT;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC __glewMultiDrawElementsBaseVertexEXT;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT;
+
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT;
+
+GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEEXTERNALEXTPROC __glewBufferStorageExternalEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC __glewNamedBufferStorageExternalEXT;
+
+GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT;
+GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT;
+
+GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT;
+GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT;
+GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT;
+GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT;
+GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT;
+GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT;
+GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT;
+GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT;
+GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT;
+GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT;
+GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT;
+GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT;
+
+GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT;
+
+GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT;
+
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISOREXTPROC __glewVertexAttribDivisorEXT;
+
+GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT;
+
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC __glewFlushMappedBufferRangeEXT;
+GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEEXTPROC __glewMapBufferRangeEXT;
+
+GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEMEMEXTPROC __glewBufferStorageMemEXT;
+GLEW_FUN_EXPORT PFNGLCREATEMEMORYOBJECTSEXTPROC __glewCreateMemoryObjectsEXT;
+GLEW_FUN_EXPORT PFNGLDELETEMEMORYOBJECTSEXTPROC __glewDeleteMemoryObjectsEXT;
+GLEW_FUN_EXPORT PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC __glewGetMemoryObjectParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETUNSIGNEDBYTEI_VEXTPROC __glewGetUnsignedBytei_vEXT;
+GLEW_FUN_EXPORT PFNGLGETUNSIGNEDBYTEVEXTPROC __glewGetUnsignedBytevEXT;
+GLEW_FUN_EXPORT PFNGLISMEMORYOBJECTEXTPROC __glewIsMemoryObjectEXT;
+GLEW_FUN_EXPORT PFNGLMEMORYOBJECTPARAMETERIVEXTPROC __glewMemoryObjectParameterivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC __glewNamedBufferStorageMemEXT;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM1DEXTPROC __glewTexStorageMem1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM2DEXTPROC __glewTexStorageMem2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC __glewTexStorageMem2DMultisampleEXT;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM3DEXTPROC __glewTexStorageMem3DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC __glewTexStorageMem3DMultisampleEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM1DEXTPROC __glewTextureStorageMem1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM2DEXTPROC __glewTextureStorageMem2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC __glewTextureStorageMem2DMultisampleEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM3DEXTPROC __glewTextureStorageMem3DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC __glewTextureStorageMem3DMultisampleEXT;
+
+GLEW_FUN_EXPORT PFNGLIMPORTMEMORYFDEXTPROC __glewImportMemoryFdEXT;
+
+GLEW_FUN_EXPORT PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC __glewImportMemoryWin32HandleEXT;
+GLEW_FUN_EXPORT PFNGLIMPORTMEMORYWIN32NAMEEXTPROC __glewImportMemoryWin32NameEXT;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC __glewMultiDrawArraysIndirectEXT;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC __glewMultiDrawElementsIndirectEXT;
+
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT;
+GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC __glewFramebufferTexture2DMultisampleEXT;
+
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSINDEXEDEXTPROC __glewDrawBuffersIndexedEXT;
+GLEW_FUN_EXPORT PFNGLGETINTEGERI_VEXTPROC __glewGetIntegeri_vEXT;
+GLEW_FUN_EXPORT PFNGLREADBUFFERINDEXEDEXTPROC __glewReadBufferIndexedEXT;
+
+GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT;
+
+GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT;
+
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT;
+
+GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT;
+
+GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETCLAMPEXTPROC __glewPolygonOffsetClampEXT;
+
+GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT;
+
+GLEW_FUN_EXPORT PFNGLCOVERAGEMODULATIONNVPROC __glewCoverageModulationNV;
+GLEW_FUN_EXPORT PFNGLCOVERAGEMODULATIONTABLENVPROC __glewCoverageModulationTableNV;
+GLEW_FUN_EXPORT PFNGLGETCOVERAGEMODULATIONTABLENVPROC __glewGetCoverageModulationTableNV;
+GLEW_FUN_EXPORT PFNGLRASTERSAMPLESEXTPROC __glewRasterSamplesEXT;
+
+GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT;
+GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT;
+
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLDELETESEMAPHORESEXTPROC __glewDeleteSemaphoresEXT;
+GLEW_FUN_EXPORT PFNGLGENSEMAPHORESEXTPROC __glewGenSemaphoresEXT;
+GLEW_FUN_EXPORT PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC __glewGetSemaphoreParameterui64vEXT;
+GLEW_FUN_EXPORT PFNGLISSEMAPHOREEXTPROC __glewIsSemaphoreEXT;
+GLEW_FUN_EXPORT PFNGLSEMAPHOREPARAMETERUI64VEXTPROC __glewSemaphoreParameterui64vEXT;
+GLEW_FUN_EXPORT PFNGLSIGNALSEMAPHOREEXTPROC __glewSignalSemaphoreEXT;
+GLEW_FUN_EXPORT PFNGLWAITSEMAPHOREEXTPROC __glewWaitSemaphoreEXT;
+
+GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREFDEXTPROC __glewImportSemaphoreFdEXT;
+
+GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC __glewImportSemaphoreWin32HandleEXT;
+GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC __glewImportSemaphoreWin32NameEXT;
+
+GLEW_FUN_EXPORT PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT;
+GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT;
+GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT;
+GLEW_FUN_EXPORT PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT;
+
+GLEW_FUN_EXPORT PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC __glewClearPixelLocalStorageuiEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewFramebufferPixelLocalStorageSizeEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewGetFramebufferPixelLocalStorageSizeEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTEXTPROC __glewTexPageCommitmentEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT;
+
+GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT;
+
+GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT;
+GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT;
+
+GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT;
+GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT;
+GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT;
+GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT;
+GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT;
+GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DEXTPROC __glewTexStorage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DEXTPROC __glewTexStorage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DEXTPROC __glewTexStorage3DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREVIEWEXTPROC __glewTextureViewEXT;
+
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT;
+
+GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT;
+GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT;
+GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT;
+
+GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT;
+GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT;
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT;
+GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT;
+GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT;
+GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDARRAYSETEXTPROC __glewBindArraySetEXT;
+GLEW_FUN_EXPORT PFNGLCREATEARRAYSETEXTPROC __glewCreateArraySetExt;
+GLEW_FUN_EXPORT PFNGLDELETEARRAYSETSEXTPROC __glewDeleteArraySetsEXT;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT;
+GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT;
+GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT;
+GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT;
+GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT;
+GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT;
+GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT;
+GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT;
+GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT;
+GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT;
+GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT;
+GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT;
+GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT;
+GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT;
+GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT;
+GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT;
+GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT;
+GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT;
+
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT;
+
+GLEW_FUN_EXPORT PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC __glewAcquireKeyedMutexWin32EXT;
+GLEW_FUN_EXPORT PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC __glewReleaseKeyedMutexWin32EXT;
+
+GLEW_FUN_EXPORT PFNGLWINDOWRECTANGLESEXTPROC __glewWindowRectanglesEXT;
+
+GLEW_FUN_EXPORT PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY;
+
+GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY;
+
+GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP;
+GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP;
+
+GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM;
+GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM;
+
+GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM;
+GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM;
+GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM;
+GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM;
+GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM;
+GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM;
+
+GLEW_FUN_EXPORT PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL;
+GLEW_FUN_EXPORT PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL;
+GLEW_FUN_EXPORT PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL;
+
+GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL;
+GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL;
+GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL;
+GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL;
+
+GLEW_FUN_EXPORT PFNGLBEGINPERFQUERYINTELPROC __glewBeginPerfQueryINTEL;
+GLEW_FUN_EXPORT PFNGLCREATEPERFQUERYINTELPROC __glewCreatePerfQueryINTEL;
+GLEW_FUN_EXPORT PFNGLDELETEPERFQUERYINTELPROC __glewDeletePerfQueryINTEL;
+GLEW_FUN_EXPORT PFNGLENDPERFQUERYINTELPROC __glewEndPerfQueryINTEL;
+GLEW_FUN_EXPORT PFNGLGETFIRSTPERFQUERYIDINTELPROC __glewGetFirstPerfQueryIdINTEL;
+GLEW_FUN_EXPORT PFNGLGETNEXTPERFQUERYIDINTELPROC __glewGetNextPerfQueryIdINTEL;
+GLEW_FUN_EXPORT PFNGLGETPERFCOUNTERINFOINTELPROC __glewGetPerfCounterInfoINTEL;
+GLEW_FUN_EXPORT PFNGLGETPERFQUERYDATAINTELPROC __glewGetPerfQueryDataINTEL;
+GLEW_FUN_EXPORT PFNGLGETPERFQUERYIDBYNAMEINTELPROC __glewGetPerfQueryIdByNameINTEL;
+GLEW_FUN_EXPORT PFNGLGETPERFQUERYINFOINTELPROC __glewGetPerfQueryInfoINTEL;
+
+GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL;
+GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL;
+
+GLEW_FUN_EXPORT PFNGLBLENDBARRIERKHRPROC __glewBlendBarrierKHR;
+
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert;
+GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog;
+GLEW_FUN_EXPORT PFNGLGETOBJECTLABELPROC __glewGetObjectLabel;
+GLEW_FUN_EXPORT PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel;
+GLEW_FUN_EXPORT PFNGLOBJECTLABELPROC __glewObjectLabel;
+GLEW_FUN_EXPORT PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel;
+GLEW_FUN_EXPORT PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup;
+GLEW_FUN_EXPORT PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup;
+
+GLEW_FUN_EXPORT PFNGLMAXSHADERCOMPILERTHREADSKHRPROC __glewMaxShaderCompilerThreadsKHR;
+
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVPROC __glewGetnUniformfv;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVPROC __glewGetnUniformiv;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVPROC __glewGetnUniformuiv;
+GLEW_FUN_EXPORT PFNGLREADNPIXELSPROC __glewReadnPixels;
+
+GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled;
+GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion;
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion;
+GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion;
+GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion;
+
+GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA;
+
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA;
+
+GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX;
+GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX;
+
+GLEW_FUN_EXPORT PFNGLLGPUCOPYIMAGESUBDATANVXPROC __glewLGPUCopyImageSubDataNVX;
+GLEW_FUN_EXPORT PFNGLLGPUINTERLOCKNVXPROC __glewLGPUInterlockNVX;
+GLEW_FUN_EXPORT PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC __glewLGPUNamedBufferSubDataNVX;
+
+GLEW_FUN_EXPORT PFNGLSTEREOPARAMETERFNVPROC __glewStereoParameterfNV;
+GLEW_FUN_EXPORT PFNGLSTEREOPARAMETERINVPROC __glewStereoParameteriNV;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawArraysIndirectBindlessCountNV;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawElementsIndirectBindlessCountNV;
+
+GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV;
+GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV;
+GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV;
+
+GLEW_FUN_EXPORT PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV;
+GLEW_FUN_EXPORT PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV;
+
+GLEW_FUN_EXPORT PFNGLVIEWPORTPOSITIONWSCALENVPROC __glewViewportPositionWScaleNV;
+
+GLEW_FUN_EXPORT PFNGLCALLCOMMANDLISTNVPROC __glewCallCommandListNV;
+GLEW_FUN_EXPORT PFNGLCOMMANDLISTSEGMENTSNVPROC __glewCommandListSegmentsNV;
+GLEW_FUN_EXPORT PFNGLCOMPILECOMMANDLISTNVPROC __glewCompileCommandListNV;
+GLEW_FUN_EXPORT PFNGLCREATECOMMANDLISTSNVPROC __glewCreateCommandListsNV;
+GLEW_FUN_EXPORT PFNGLCREATESTATESNVPROC __glewCreateStatesNV;
+GLEW_FUN_EXPORT PFNGLDELETECOMMANDLISTSNVPROC __glewDeleteCommandListsNV;
+GLEW_FUN_EXPORT PFNGLDELETESTATESNVPROC __glewDeleteStatesNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSADDRESSNVPROC __glewDrawCommandsAddressNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSNVPROC __glewDrawCommandsNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC __glewDrawCommandsStatesAddressNV;
+GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESNVPROC __glewDrawCommandsStatesNV;
+GLEW_FUN_EXPORT PFNGLGETCOMMANDHEADERNVPROC __glewGetCommandHeaderNV;
+GLEW_FUN_EXPORT PFNGLGETSTAGEINDEXNVPROC __glewGetStageIndexNV;
+GLEW_FUN_EXPORT PFNGLISCOMMANDLISTNVPROC __glewIsCommandListNV;
+GLEW_FUN_EXPORT PFNGLISSTATENVPROC __glewIsStateNV;
+GLEW_FUN_EXPORT PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC __glewListDrawCommandsStatesClientNV;
+GLEW_FUN_EXPORT PFNGLSTATECAPTURENVPROC __glewStateCaptureNV;
+
+GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV;
+GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV;
+
+GLEW_FUN_EXPORT PFNGLSUBPIXELPRECISIONBIASNVPROC __glewSubpixelPrecisionBiasNV;
+
+GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERFNVPROC __glewConservativeRasterParameterfNV;
+
+GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERINVPROC __glewConservativeRasterParameteriNV;
+
+GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATANVPROC __glewCopyBufferSubDataNV;
+
+GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV;
+
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV;
+GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV;
+
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSNVPROC __glewDrawBuffersNV;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDNVPROC __glewDrawArraysInstancedNV;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDNVPROC __glewDrawElementsInstancedNV;
+
+GLEW_FUN_EXPORT PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV;
+
+GLEW_FUN_EXPORT PFNGLDRAWVKIMAGENVPROC __glewDrawVkImageNV;
+GLEW_FUN_EXPORT PFNGLGETVKPROCADDRNVPROC __glewGetVkProcAddrNV;
+GLEW_FUN_EXPORT PFNGLSIGNALVKFENCENVPROC __glewSignalVkFenceNV;
+GLEW_FUN_EXPORT PFNGLSIGNALVKSEMAPHORENVPROC __glewSignalVkSemaphoreNV;
+GLEW_FUN_EXPORT PFNGLWAITVKSEMAPHORENVPROC __glewWaitVkSemaphoreNV;
+
+GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV;
+GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV;
+GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV;
+GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV;
+GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV;
+GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV;
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV;
+GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV;
+
+GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV;
+GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV;
+GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV;
+GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV;
+GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV;
+GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV;
+GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV;
+
+GLEW_FUN_EXPORT PFNGLFRAGMENTCOVERAGECOLORNVPROC __glewFragmentCoverageColorNV;
+
+GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV;
+
+GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERNVPROC __glewBlitFramebufferNV;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC __glewRenderbufferStorageMultisampleNV;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV;
+
+GLEW_FUN_EXPORT PFNGLMULTICASTBARRIERNVPROC __glewMulticastBarrierNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTBLITFRAMEBUFFERNVPROC __glewMulticastBlitFramebufferNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTBUFFERSUBDATANVPROC __glewMulticastBufferSubDataNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC __glewMulticastCopyBufferSubDataNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTCOPYIMAGESUBDATANVPROC __glewMulticastCopyImageSubDataNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewMulticastFramebufferSampleLocationsfvNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC __glewMulticastGetQueryObjecti64vNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTIVNVPROC __glewMulticastGetQueryObjectivNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC __glewMulticastGetQueryObjectui64vNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC __glewMulticastGetQueryObjectuivNV;
+GLEW_FUN_EXPORT PFNGLMULTICASTWAITSYNCNVPROC __glewMulticastWaitSyncNV;
+GLEW_FUN_EXPORT PFNGLRENDERGPUMASKNVPROC __glewRenderGpuMaskNV;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV;
+
+GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV;
+
+GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV;
+GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV;
+GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV;
+GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV;
+GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV;
+GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV;
+GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV;
+GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV;
+GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV;
+GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV;
+GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV;
+
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORNVPROC __glewVertexAttribDivisorNV;
+
+GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATSAMPLEIVNVPROC __glewGetInternalformatSampleivNV;
+
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVNVPROC __glewUniformMatrix2x3fvNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVNVPROC __glewUniformMatrix2x4fvNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVNVPROC __glewUniformMatrix3x2fvNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVNVPROC __glewUniformMatrix3x4fvNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVNVPROC __glewUniformMatrix4x2fvNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVNVPROC __glewUniformMatrix4x3fvNV;
+
+GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV;
+GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV;
+GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV;
+GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV;
+GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV;
+GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV;
+GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV;
+
+GLEW_FUN_EXPORT PFNGLCOPYPATHNVPROC __glewCopyPathNV;
+GLEW_FUN_EXPORT PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV;
+GLEW_FUN_EXPORT PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV;
+GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV;
+GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV;
+GLEW_FUN_EXPORT PFNGLDELETEPATHSNVPROC __glewDeletePathsNV;
+GLEW_FUN_EXPORT PFNGLGENPATHSNVPROC __glewGenPathsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV;
+GLEW_FUN_EXPORT PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV;
+GLEW_FUN_EXPORT PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV;
+GLEW_FUN_EXPORT PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV;
+GLEW_FUN_EXPORT PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV;
+GLEW_FUN_EXPORT PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEFVNVPROC __glewGetProgramResourcefvNV;
+GLEW_FUN_EXPORT PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV;
+GLEW_FUN_EXPORT PFNGLISPATHNVPROC __glewIsPathNV;
+GLEW_FUN_EXPORT PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV;
+GLEW_FUN_EXPORT PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV;
+GLEW_FUN_EXPORT PFNGLMATRIXLOAD3X2FNVPROC __glewMatrixLoad3x2fNV;
+GLEW_FUN_EXPORT PFNGLMATRIXLOAD3X3FNVPROC __glewMatrixLoad3x3fNV;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC __glewMatrixLoadTranspose3x3fNV;
+GLEW_FUN_EXPORT PFNGLMATRIXMULT3X2FNVPROC __glewMatrixMult3x2fNV;
+GLEW_FUN_EXPORT PFNGLMATRIXMULT3X3FNVPROC __glewMatrixMult3x3fNV;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC __glewMatrixMultTranspose3x3fNV;
+GLEW_FUN_EXPORT PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV;
+GLEW_FUN_EXPORT PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV;
+GLEW_FUN_EXPORT PFNGLPATHCOORDSNVPROC __glewPathCoordsNV;
+GLEW_FUN_EXPORT PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV;
+GLEW_FUN_EXPORT PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV;
+GLEW_FUN_EXPORT PFNGLPATHFOGGENNVPROC __glewPathFogGenNV;
+GLEW_FUN_EXPORT PFNGLPATHGLYPHINDEXARRAYNVPROC __glewPathGlyphIndexArrayNV;
+GLEW_FUN_EXPORT PFNGLPATHGLYPHINDEXRANGENVPROC __glewPathGlyphIndexRangeNV;
+GLEW_FUN_EXPORT PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV;
+GLEW_FUN_EXPORT PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV;
+GLEW_FUN_EXPORT PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC __glewPathMemoryGlyphIndexArrayNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV;
+GLEW_FUN_EXPORT PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV;
+GLEW_FUN_EXPORT PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV;
+GLEW_FUN_EXPORT PFNGLPATHSTRINGNVPROC __glewPathStringNV;
+GLEW_FUN_EXPORT PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV;
+GLEW_FUN_EXPORT PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV;
+GLEW_FUN_EXPORT PFNGLPATHTEXGENNVPROC __glewPathTexGenNV;
+GLEW_FUN_EXPORT PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC __glewProgramPathFragmentInputGenNV;
+GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV;
+GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV;
+GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV;
+GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV;
+GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC __glewStencilThenCoverFillPathInstancedNV;
+GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERFILLPATHNVPROC __glewStencilThenCoverFillPathNV;
+GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC __glewStencilThenCoverStrokePathInstancedNV;
+GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC __glewStencilThenCoverStrokePathNV;
+GLEW_FUN_EXPORT PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV;
+GLEW_FUN_EXPORT PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV;
+
+GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV;
+GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV;
+
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLPOLYGONMODENVPROC __glewPolygonModeNV;
+
+GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV;
+GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV;
+GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV;
+
+GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV;
+GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV;
+
+GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV;
+GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV;
+GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewFramebufferSampleLocationsfvNV;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewNamedFramebufferSampleLocationsfvNV;
+
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV;
+GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV;
+GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV;
+
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DNVPROC __glewCompressedTexImage3DNV;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC __glewCompressedTexSubImage3DNV;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DNVPROC __glewCopyTexSubImage3DNV;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERNVPROC __glewFramebufferTextureLayerNV;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DNVPROC __glewTexImage3DNV;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DNVPROC __glewTexSubImage3DNV;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV;
+
+GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV;
+
+GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV;
+GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV;
+GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV;
+GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV;
+GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV;
+
+GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV;
+GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV;
+
+GLEW_FUN_EXPORT PFNGLVDPAUFININVPROC __glewVDPAUFiniNV;
+GLEW_FUN_EXPORT PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV;
+GLEW_FUN_EXPORT PFNGLVDPAUINITNVPROC __glewVDPAUInitNV;
+GLEW_FUN_EXPORT PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV;
+GLEW_FUN_EXPORT PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV;
+GLEW_FUN_EXPORT PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV;
+GLEW_FUN_EXPORT PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV;
+GLEW_FUN_EXPORT PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV;
+GLEW_FUN_EXPORT PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV;
+GLEW_FUN_EXPORT PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV;
+
+GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV;
+
+GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV;
+GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV;
+GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV;
+GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV;
+GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV;
+
+GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV;
+GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV;
+GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV;
+GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV;
+GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV;
+GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV;
+GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV;
+GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV;
+GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV;
+
+GLEW_FUN_EXPORT PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV;
+GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV;
+GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV;
+GLEW_FUN_EXPORT PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYFVNVPROC __glewDepthRangeArrayfvNV;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDFNVPROC __glewDepthRangeIndexedfNV;
+GLEW_FUN_EXPORT PFNGLDISABLEINVPROC __glewDisableiNV;
+GLEW_FUN_EXPORT PFNGLENABLEINVPROC __glewEnableiNV;
+GLEW_FUN_EXPORT PFNGLGETFLOATI_VNVPROC __glewGetFloati_vNV;
+GLEW_FUN_EXPORT PFNGLISENABLEDINVPROC __glewIsEnablediNV;
+GLEW_FUN_EXPORT PFNGLSCISSORARRAYVNVPROC __glewScissorArrayvNV;
+GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDNVPROC __glewScissorIndexedNV;
+GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVNVPROC __glewScissorIndexedvNV;
+GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVNVPROC __glewViewportArrayvNV;
+GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFNVPROC __glewViewportIndexedfNV;
+GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVNVPROC __glewViewportIndexedfvNV;
+
+GLEW_FUN_EXPORT PFNGLVIEWPORTSWIZZLENVPROC __glewViewportSwizzleNV;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __glewFramebufferTextureMultiviewOVR;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC __glewFramebufferTextureMultisampleMultiviewOVR;
+
+GLEW_FUN_EXPORT PFNGLALPHAFUNCQCOMPROC __glewAlphaFuncQCOM;
+
+GLEW_FUN_EXPORT PFNGLDISABLEDRIVERCONTROLQCOMPROC __glewDisableDriverControlQCOM;
+GLEW_FUN_EXPORT PFNGLENABLEDRIVERCONTROLQCOMPROC __glewEnableDriverControlQCOM;
+GLEW_FUN_EXPORT PFNGLGETDRIVERCONTROLSTRINGQCOMPROC __glewGetDriverControlStringQCOM;
+GLEW_FUN_EXPORT PFNGLGETDRIVERCONTROLSQCOMPROC __glewGetDriverControlsQCOM;
+
+GLEW_FUN_EXPORT PFNGLEXTGETBUFFERPOINTERVQCOMPROC __glewExtGetBufferPointervQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETBUFFERSQCOMPROC __glewExtGetBuffersQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETFRAMEBUFFERSQCOMPROC __glewExtGetFramebuffersQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETRENDERBUFFERSQCOMPROC __glewExtGetRenderbuffersQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC __glewExtGetTexLevelParameterivQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETTEXSUBIMAGEQCOMPROC __glewExtGetTexSubImageQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETTEXTURESQCOMPROC __glewExtGetTexturesQCOM;
+GLEW_FUN_EXPORT PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC __glewExtTexObjectStateOverrideiQCOM;
+
+GLEW_FUN_EXPORT PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC __glewExtGetProgramBinarySourceQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETPROGRAMSQCOMPROC __glewExtGetProgramsQCOM;
+GLEW_FUN_EXPORT PFNGLEXTGETSHADERSQCOMPROC __glewExtGetShadersQCOM;
+GLEW_FUN_EXPORT PFNGLEXTISPROGRAMBINARYQCOMPROC __glewExtIsProgramBinaryQCOM;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC __glewFramebufferFoveationConfigQCOM;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC __glewFramebufferFoveationParametersQCOM;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC __glewFramebufferFetchBarrierQCOM;
+
+GLEW_FUN_EXPORT PFNGLENDTILINGQCOMPROC __glewEndTilingQCOM;
+GLEW_FUN_EXPORT PFNGLSTARTTILINGQCOMPROC __glewStartTilingQCOM;
+
+GLEW_FUN_EXPORT PFNGLALPHAFUNCXPROC __glewAlphaFuncx;
+GLEW_FUN_EXPORT PFNGLCLEARCOLORXPROC __glewClearColorx;
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHXPROC __glewClearDepthx;
+GLEW_FUN_EXPORT PFNGLCOLOR4XPROC __glewColor4x;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEXPROC __glewDepthRangex;
+GLEW_FUN_EXPORT PFNGLFOGXPROC __glewFogx;
+GLEW_FUN_EXPORT PFNGLFOGXVPROC __glewFogxv;
+GLEW_FUN_EXPORT PFNGLFRUSTUMFPROC __glewFrustumf;
+GLEW_FUN_EXPORT PFNGLFRUSTUMXPROC __glewFrustumx;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELXPROC __glewLightModelx;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELXVPROC __glewLightModelxv;
+GLEW_FUN_EXPORT PFNGLLIGHTXPROC __glewLightx;
+GLEW_FUN_EXPORT PFNGLLIGHTXVPROC __glewLightxv;
+GLEW_FUN_EXPORT PFNGLLINEWIDTHXPROC __glewLineWidthx;
+GLEW_FUN_EXPORT PFNGLLOADMATRIXXPROC __glewLoadMatrixx;
+GLEW_FUN_EXPORT PFNGLMATERIALXPROC __glewMaterialx;
+GLEW_FUN_EXPORT PFNGLMATERIALXVPROC __glewMaterialxv;
+GLEW_FUN_EXPORT PFNGLMULTMATRIXXPROC __glewMultMatrixx;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x;
+GLEW_FUN_EXPORT PFNGLNORMAL3XPROC __glewNormal3x;
+GLEW_FUN_EXPORT PFNGLORTHOFPROC __glewOrthof;
+GLEW_FUN_EXPORT PFNGLORTHOXPROC __glewOrthox;
+GLEW_FUN_EXPORT PFNGLPOINTSIZEXPROC __glewPointSizex;
+GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx;
+GLEW_FUN_EXPORT PFNGLROTATEXPROC __glewRotatex;
+GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex;
+GLEW_FUN_EXPORT PFNGLSCALEXPROC __glewScalex;
+GLEW_FUN_EXPORT PFNGLTEXENVXPROC __glewTexEnvx;
+GLEW_FUN_EXPORT PFNGLTEXENVXVPROC __glewTexEnvxv;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERXPROC __glewTexParameterx;
+GLEW_FUN_EXPORT PFNGLTRANSLATEXPROC __glewTranslatex;
+
+GLEW_FUN_EXPORT PFNGLCLIPPLANEFPROC __glewClipPlanef;
+GLEW_FUN_EXPORT PFNGLCLIPPLANEXPROC __glewClipPlanex;
+GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef;
+GLEW_FUN_EXPORT PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex;
+GLEW_FUN_EXPORT PFNGLGETFIXEDVPROC __glewGetFixedv;
+GLEW_FUN_EXPORT PFNGLGETLIGHTXVPROC __glewGetLightxv;
+GLEW_FUN_EXPORT PFNGLGETMATERIALXVPROC __glewGetMaterialxv;
+GLEW_FUN_EXPORT PFNGLGETTEXENVXVPROC __glewGetTexEnvxv;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXPROC __glewPointParameterx;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv;
+GLEW_FUN_EXPORT PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERXVPROC __glewTexParameterxv;
+
+GLEW_FUN_EXPORT PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL;
+
+GLEW_FUN_EXPORT PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL;
+GLEW_FUN_EXPORT PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL;
+
+GLEW_FUN_EXPORT PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL;
+
+GLEW_FUN_EXPORT PFNGLGETPROCADDRESSREGALPROC __glewGetProcAddressREGAL;
+
+GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS;
+GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS;
+GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS;
+GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS;
+
+GLEW_FUN_EXPORT PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC __glewInterleavedTextureCoordSetsSGIS;
+GLEW_FUN_EXPORT PFNGLSELECTTEXTURECOORDSETSGISPROC __glewSelectTextureCoordSetSGIS;
+GLEW_FUN_EXPORT PFNGLSELECTTEXTURESGISPROC __glewSelectTextureSGIS;
+GLEW_FUN_EXPORT PFNGLSELECTTEXTURETRANSFORMSGISPROC __glewSelectTextureTransformSGIS;
+
+GLEW_FUN_EXPORT PFNGLMULTISAMPLESUBRECTPOSSGISPROC __glewMultisampleSubRectPosSGIS;
+
+GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS;
+GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS;
+
+GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS;
+GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX;
+GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX;
+GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX;
+GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX;
+GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX;
+GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX;
+
+GLEW_FUN_EXPORT PFNGLADDRESSSPACEPROC __glewAddressSpace;
+GLEW_FUN_EXPORT PFNGLDATAPIPEPROC __glewDataPipe;
+
+GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX;
+
+GLEW_FUN_EXPORT PFNGLFOGLAYERSSGIXPROC __glewFogLayersSGIX;
+GLEW_FUN_EXPORT PFNGLGETFOGLAYERSSGIXPROC __glewGetFogLayersSGIX;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX;
+
+GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX;
+
+GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX;
+
+GLEW_FUN_EXPORT PFNGLIGLOOINTERFACESGIXPROC __glewIglooInterfaceSGIX;
+
+GLEW_FUN_EXPORT PFNGLALLOCMPEGPREDICTORSSGIXPROC __glewAllocMPEGPredictorsSGIX;
+GLEW_FUN_EXPORT PFNGLDELETEMPEGPREDICTORSSGIXPROC __glewDeleteMPEGPredictorsSGIX;
+GLEW_FUN_EXPORT PFNGLGENMPEGPREDICTORSSGIXPROC __glewGenMPEGPredictorsSGIX;
+GLEW_FUN_EXPORT PFNGLGETMPEGPARAMETERFVSGIXPROC __glewGetMPEGParameterfvSGIX;
+GLEW_FUN_EXPORT PFNGLGETMPEGPARAMETERIVSGIXPROC __glewGetMPEGParameterivSGIX;
+GLEW_FUN_EXPORT PFNGLGETMPEGPREDICTORSGIXPROC __glewGetMPEGPredictorSGIX;
+GLEW_FUN_EXPORT PFNGLGETMPEGQUANTTABLEUBVPROC __glewGetMPEGQuantTableubv;
+GLEW_FUN_EXPORT PFNGLISMPEGPREDICTORSGIXPROC __glewIsMPEGPredictorSGIX;
+GLEW_FUN_EXPORT PFNGLMPEGPREDICTORSGIXPROC __glewMPEGPredictorSGIX;
+GLEW_FUN_EXPORT PFNGLMPEGQUANTTABLEUBVPROC __glewMPEGQuantTableubv;
+GLEW_FUN_EXPORT PFNGLSWAPMPEGPREDICTORSSGIXPROC __glewSwapMPEGPredictorsSGIX;
+
+GLEW_FUN_EXPORT PFNGLGETNONLINLIGHTFVSGIXPROC __glewGetNonlinLightfvSGIX;
+GLEW_FUN_EXPORT PFNGLGETNONLINMATERIALFVSGIXPROC __glewGetNonlinMaterialfvSGIX;
+GLEW_FUN_EXPORT PFNGLNONLINLIGHTFVSGIXPROC __glewNonlinLightfvSGIX;
+GLEW_FUN_EXPORT PFNGLNONLINMATERIALFVSGIXPROC __glewNonlinMaterialfvSGIX;
+
+GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX;
+
+GLEW_FUN_EXPORT PFNGLDEFORMSGIXPROC __glewDeformSGIX;
+GLEW_FUN_EXPORT PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC __glewLoadIdentityDeformationMapSGIX;
+
+GLEW_FUN_EXPORT PFNGLMESHBREADTHSGIXPROC __glewMeshBreadthSGIX;
+GLEW_FUN_EXPORT PFNGLMESHSTRIDESGIXPROC __glewMeshStrideSGIX;
+
+GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX;
+
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX;
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX;
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX;
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX;
+
+GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX;
+
+GLEW_FUN_EXPORT PFNGLGETVECTOROPERATIONSGIXPROC __glewGetVectorOperationSGIX;
+GLEW_FUN_EXPORT PFNGLVECTOROPERATIONSGIXPROC __glewVectorOperationSGIX;
+
+GLEW_FUN_EXPORT PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC __glewAreVertexArraysResidentSGIX;
+GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYSGIXPROC __glewBindVertexArraySGIX;
+GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSSGIXPROC __glewDeleteVertexArraysSGIX;
+GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSSGIXPROC __glewGenVertexArraysSGIX;
+GLEW_FUN_EXPORT PFNGLISVERTEXARRAYSGIXPROC __glewIsVertexArraySGIX;
+GLEW_FUN_EXPORT PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC __glewPrioritizeVertexArraysSGIX;
+
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI;
+GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI;
+
+GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC __glewGetPixelTransformParameterfvSGI;
+GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC __glewGetPixelTransformParameterivSGI;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFSGIPROC __glewPixelTransformParameterfSGI;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC __glewPixelTransformParameterfvSGI;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERISGIPROC __glewPixelTransformParameteriSGI;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC __glewPixelTransformParameterivSGI;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMSGIPROC __glewPixelTransformSGI;
+
+GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX;
+
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN;
+
+GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN;
+
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN;
+
+GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN;
+
+GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_3;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_0;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_2;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_3;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_4;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_5;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_6;
+GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_blend_minmax_factor;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_compressed_3DC_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_compressed_ATC_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_conservative_depth;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_debug_output;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_depth_clamp_separate;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_framebuffer_sample_positions;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gcn_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_half_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_int16;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_int64;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_interleaved_elements;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_multi_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_name_gen_delete;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_occlusion_query_event;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_pinned_memory;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_program_binary_Z400;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_query_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sample_positions;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_atomic_counter_ops;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_ballot;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_explicit_vertex_parameter;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_value_export;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_trinary_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sparse_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_stencil_operation_extended;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_gather_bias_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback3_lines_triangles;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback4;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_layer;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_viewport_index;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANDROID_extension_pack_es31a;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_depth_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_blit;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_instanced_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_pack_reverse_row_order;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_program_binary;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt1;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt5;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_usage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_timer_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_translated_shader_source;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_clip_distance;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_color_buffer_packed_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_copy_texture_levels;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_framebuffer_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_object_purgeable;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_sync;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_2D_limited_npot;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_format_BGRA8888;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_max_level;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_packed_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_program_evaluators;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES2_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_1_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_2_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_arrays_of_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_base_instance;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_bindless_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_blend_func_extended;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_buffer_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cl_event;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clip_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compressed_texture_pixel_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_variable_group_size;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conditional_render_inverted;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conservative_depth;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cull_distance;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_debug_output;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_derivative_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_direct_state_access;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_enhanced_layouts;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_attrib_location;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_uniform_location;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_layer_viewport;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader_interlock;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_no_attachments;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_program_binary;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_texture_sub_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gl_spirv;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_int64;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_indirect_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query2;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_invalidate_subdata;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_alignment;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_bind;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query2;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_parallel_shader_compile;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pipeline_statistics_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_polygon_offset_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_post_depth_coverage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_program_interface_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_query_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robust_buffer_access_behavior;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_application_isolation;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_share_group_isolation;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_locations;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sampler_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cubemap_per_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_separate_shader_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counter_ops;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_ballot;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_bit_encoding;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_clock;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_draw_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_group_vote;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_load_store;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_size;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_precision;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_stencil_export;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_storage_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_subroutine;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_image_samples;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_viewport_layer_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_420pack;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_include;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_packing;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture2;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_spirv_extensions;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_stencil_texturing;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_tessellation_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_barrier;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object_rgb32;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_bptc;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_filter_anisotropic;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_filter_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_gather;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_levels;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rgb10_a2ui;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_stencil8;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_swizzle;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_view;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_timer_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback2;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_overflow_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_64bit;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_binding;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_10f_11f_11f_rev;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_viewport_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARM_mali_program_binary;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARM_mali_shader_binary;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARM_rgba8;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARM_shader_framebuffer_fetch;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARM_shader_framebuffer_fetch_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_meminfo;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams;
+GLEW_VAR_EXPORT GLboolean __GLEW_EGL_KHR_context_flush_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_EGL_NV_robustness_video_memory_purge;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_EGL_image_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_YUV_target;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_base_instance;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_extended;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_buffer_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clear_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_cull_distance;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_buffer_half_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compressed_ETC1_RGB8_sub_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_conservative_depth;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_label;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_marker;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_discard_framebuffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers_indexed;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_elements_base_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_external_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_float_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_frag_depth;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample_blit_scaled;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_point_size;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader5;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_instanced_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_map_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object_fd;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object_win32;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiple_textures;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisampled_render_to_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisampled_render_to_texture2;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiview_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_post_depth_coverage;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_provoking_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pvrtc_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_raster_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_read_format_bgra;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_render_snorm;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sRGB_write_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore_fd;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore_win32;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_shader_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_framebuffer_fetch;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_group_vote;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_formatted;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_store;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_implicit_conversions;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_integer_mix;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_io_blocks;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_non_constant_global_initializers;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_pixel_local_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_pixel_local_storage2;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_samplers;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sparse_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sparse_texture2;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_astc_decode_mode;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_bptc;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_format_BGRA8888;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_norm16;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rg;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_R8;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_RG8;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_decode;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_type_2_10_10_10_REV;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_view;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_unpack_subimage;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_setXXX;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_attrib_64bit;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_win32_keyed_mutex;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_window_rectangles;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_x11_sync_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator;
+GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists;
+GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_conservative_rasterization;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_fragment_shader_ordering;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_framebuffer_CMAA;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_map_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_performance_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_blend_equation_advanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_blend_equation_advanced_coherent;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_context_flush_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_debug;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_no_error;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_parallel_shader_compile;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robust_buffer_access_behavior;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robustness;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_hdr;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_ldr;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_sliced_3d;
+GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_shader_integer_functions;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_blend_equation_advanced_multi_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_conditional_render;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_memory_info;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_linked_gpu_multicast;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_3dvision_settings;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_EGL_stream_consumer_external;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_alpha_to_coverage_dither_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_bgr;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect_count;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced_coherent;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_minmax_factor;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_clip_space_w_scaling;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_command_list;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_compute_program5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_dilate;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_pre_snap_triangles;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_deep_texture3D;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_vulkan_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_attrib_location;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fbo_color_attachments;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fill_rectangle;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_coverage_to_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_shader_interlock;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_blit;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_mixed_samples;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_generate_mipmap_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader_passthrough;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_multicast;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5_mem_extended;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program_fp64;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_shader5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_image_formats;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_instanced_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_internalformat_sample_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_coverage;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_non_square_matrices;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_pack_subimage;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_float_linear;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering_shared_edge;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_platform_binary;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_polygon_mode;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_depth;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_robustness_video_memory_purge;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_sRGB_formats;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_locations;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_mask_override_coverage;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_counters;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float64;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_fp16_vector;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_int64;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_noperspective_interpolation;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_storage_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_group;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_shuffle;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shadow_samplers_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shadow_samplers_cube;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_stereo_view_rendering;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_border_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_latc;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_s3tc;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_s3tc_update;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_npot_2D_mipmap;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle_compressed;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_uniform_buffer_unified_memory;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vdpau_interop;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_attrib_integer_64bit;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_video_capture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_array2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_swizzle;
+GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates;
+GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace;
+GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample;
+GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample;
+GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview;
+GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview2;
+GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview_multisampled_render_to_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints;
+GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_alpha_test;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_binning_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_driver_control;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_extended_get;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_extended_get2;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_framebuffer_foveated;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_perfmon_global_mode;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_shader_framebuffer_fetch_noncoherent;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_tiled_rendering;
+GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_writeonly_rendering;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_0_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_1_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_enable;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_error_string;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_extension_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_log;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_proc_address;
+GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates;
+GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_clip_band_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_line_texgen;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multitexture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_shared_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_g_instruments;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_r_instruments;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_timer_instruments;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_cadd;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_cmultiply;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_calligraphic_fragment;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_color_matrix_accuracy;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_color_table_index_mode;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_complex_polar;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_cylinder_texgen;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_datapipe;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_decimation;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_pass_instrument;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_dvc;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_factor_to_alpha;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_layers;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_patchy;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_scale;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_lighting_space;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragments_instrument;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_icc_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_igloo_interface;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_image_compression;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_impact_pixel_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_instrument_error;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_line_quality_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_mpeg1;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_mpeg2;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_nonlinear_lighting_pervertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_nurbs_eval;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_occlusion_instrument;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_packed_6bytes;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_tiles;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_polynomial_ffd;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_quad_mesh;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_scalebias_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_slim;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_spotlight_cutoff;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_subdiv_patch;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_subsample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_mipmap_anisotropic;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_phase;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_supersample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vector_ops;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb_subsample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcba;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_complex;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_complex_type;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_fft;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading;
+GLEW_VAR_EXPORT GLboolean __GLEW_WIN_scene_markerXXX;
+GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog;
+GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint;
+/* ------------------------------------------------------------------------- */
+
+/* error codes */
+#define GLEW_OK 0
+#define GLEW_NO_ERROR 0
+#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */
+#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* Need at least OpenGL 1.1 */
+#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* Need at least GLX 1.2 */
+#define GLEW_ERROR_NO_GLX_DISPLAY 4 /* Need GLX display for GLX support */
+
+/* string codes */
+#define GLEW_VERSION 1
+#define GLEW_VERSION_MAJOR 2
+#define GLEW_VERSION_MINOR 3
+#define GLEW_VERSION_MICRO 4
+
+/* ------------------------------------------------------------------------- */
+
+/* GLEW version info */
+
+/*
+VERSION 2.1.0
+VERSION_MAJOR 2
+VERSION_MINOR 1
+VERSION_MICRO 0
+*/
+
+/* API */
+GLEWAPI GLenum GLEWAPIENTRY glewInit (void);
+GLEWAPI GLboolean GLEWAPIENTRY glewIsSupported (const char *name);
+#define glewIsExtensionSupported(x) glewIsSupported(x)
+
+#ifndef GLEW_GET_VAR
+#define GLEW_GET_VAR(x) (*(const GLboolean*)&x)
+#endif
+
+#ifndef GLEW_GET_FUN
+#define GLEW_GET_FUN(x) x
+#endif
+
+GLEWAPI GLboolean glewExperimental;
+GLEWAPI GLboolean GLEWAPIENTRY glewGetExtension (const char *name);
+GLEWAPI const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error);
+GLEWAPI const GLubyte * GLEWAPIENTRY glewGetString (GLenum name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef GLEW_APIENTRY_DEFINED
+#undef GLEW_APIENTRY_DEFINED
+#undef APIENTRY
+#endif
+
+#ifdef GLEW_CALLBACK_DEFINED
+#undef GLEW_CALLBACK_DEFINED
+#undef CALLBACK
+#endif
+
+#ifdef GLEW_WINGDIAPI_DEFINED
+#undef GLEW_WINGDIAPI_DEFINED
+#undef WINGDIAPI
+#endif
+
+#undef GLAPI
+/* #undef GLEWAPI */
+
+#endif /* __glew_h__ */
diff --git a/graphics/asymptote/GL/glxew.h b/graphics/asymptote/GL/glxew.h
new file mode 100644
index 0000000000..7e39c2fd98
--- /dev/null
+++ b/graphics/asymptote/GL/glxew.h
@@ -0,0 +1,1775 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2008-2017, Nigel Stewart <nigels[]users sourceforge net>
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.0
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * 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 AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE 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 AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __glxew_h__
+#define __glxew_h__
+#define __GLXEW_H__
+
+#ifdef __glxext_h_
+#error glxext.h included before glxew.h
+#endif
+
+#if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__)
+#error glx.h included before glxew.h
+#endif
+
+#define __glxext_h_
+
+#define GLX_H
+#define __GLX_glx_h__
+#define __glx_h__
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xmd.h>
+#include <GL/glew.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---------------------------- GLX_VERSION_1_0 --------------------------- */
+
+#ifndef GLX_VERSION_1_0
+#define GLX_VERSION_1_0 1
+
+#define GLX_USE_GL 1
+#define GLX_BUFFER_SIZE 2
+#define GLX_LEVEL 3
+#define GLX_RGBA 4
+#define GLX_DOUBLEBUFFER 5
+#define GLX_STEREO 6
+#define GLX_AUX_BUFFERS 7
+#define GLX_RED_SIZE 8
+#define GLX_GREEN_SIZE 9
+#define GLX_BLUE_SIZE 10
+#define GLX_ALPHA_SIZE 11
+#define GLX_DEPTH_SIZE 12
+#define GLX_STENCIL_SIZE 13
+#define GLX_ACCUM_RED_SIZE 14
+#define GLX_ACCUM_GREEN_SIZE 15
+#define GLX_ACCUM_BLUE_SIZE 16
+#define GLX_ACCUM_ALPHA_SIZE 17
+#define GLX_BAD_SCREEN 1
+#define GLX_BAD_ATTRIBUTE 2
+#define GLX_NO_EXTENSION 3
+#define GLX_BAD_VISUAL 4
+#define GLX_BAD_CONTEXT 5
+#define GLX_BAD_VALUE 6
+#define GLX_BAD_ENUM 7
+
+typedef XID GLXDrawable;
+typedef XID GLXPixmap;
+#ifdef __sun
+typedef struct __glXContextRec *GLXContext;
+#else
+typedef struct __GLXcontextRec *GLXContext;
+#endif
+
+typedef unsigned int GLXVideoDeviceNV;
+
+extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase);
+extern Bool glXQueryVersion (Display *dpy, int *major, int *minor);
+extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value);
+extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList);
+extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap);
+extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix);
+extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
+extern void glXDestroyContext (Display *dpy, GLXContext ctx);
+extern Bool glXIsDirect (Display *dpy, GLXContext ctx);
+extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask);
+extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx);
+extern GLXContext glXGetCurrentContext (void);
+extern GLXDrawable glXGetCurrentDrawable (void);
+extern void glXWaitGL (void);
+extern void glXWaitX (void);
+extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable);
+extern void glXUseXFont (Font font, int first, int count, int listBase);
+
+#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0)
+
+#endif /* GLX_VERSION_1_0 */
+
+/* ---------------------------- GLX_VERSION_1_1 --------------------------- */
+
+#ifndef GLX_VERSION_1_1
+#define GLX_VERSION_1_1
+
+#define GLX_VENDOR 0x1
+#define GLX_VERSION 0x2
+#define GLX_EXTENSIONS 0x3
+
+extern const char* glXQueryExtensionsString (Display *dpy, int screen);
+extern const char* glXGetClientString (Display *dpy, int name);
+extern const char* glXQueryServerString (Display *dpy, int screen, int name);
+
+#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1)
+
+#endif /* GLX_VERSION_1_1 */
+
+/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */
+
+#ifndef GLX_VERSION_1_2
+#define GLX_VERSION_1_2 1
+
+typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void);
+
+#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay)
+
+#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2)
+
+#endif /* GLX_VERSION_1_2 */
+
+/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */
+
+#ifndef GLX_VERSION_1_3
+#define GLX_VERSION_1_3 1
+
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_CONFIG_CAVEAT 0x20
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_X_VISUAL_TYPE 0x22
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_STATIC_GRAY 0x8007
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_INDEX 0x8009
+#define GLX_VISUAL_ID 0x800B
+#define GLX_SCREEN 0x800C
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_COLOR_INDEX_TYPE 0x8015
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_WIDTH 0x801D
+#define GLX_HEIGHT 0x801E
+#define GLX_EVENT_MASK 0x801F
+#define GLX_DAMAGED 0x8020
+#define GLX_SAVED 0x8021
+#define GLX_WINDOW 0x8022
+#define GLX_PBUFFER 0x8023
+#define GLX_PBUFFER_HEIGHT 0x8040
+#define GLX_PBUFFER_WIDTH 0x8041
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+#define GLX_DONT_CARE 0xFFFFFFFF
+
+typedef XID GLXFBConfigID;
+typedef XID GLXPbuffer;
+typedef XID GLXWindow;
+typedef struct __GLXFBConfigRec *GLXFBConfig;
+
+typedef struct {
+ int event_type;
+ int draw_type;
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ GLXDrawable drawable;
+ unsigned int buffer_mask;
+ unsigned int aux_buffer;
+ int x, y;
+ int width, height;
+ int count;
+} GLXPbufferClobberEvent;
+typedef union __GLXEvent {
+ GLXPbufferClobberEvent glxpbufferclobber;
+ long pad[24];
+} GLXEvent;
+
+typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
+typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
+typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void);
+typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
+typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
+typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
+typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
+typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+
+#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig)
+#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext)
+#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer)
+#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap)
+#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow)
+#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer)
+#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap)
+#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow)
+#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable)
+#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib)
+#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs)
+#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent)
+#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig)
+#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent)
+#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext)
+#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable)
+#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent)
+
+#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3)
+
+#endif /* GLX_VERSION_1_3 */
+
+/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */
+
+#ifndef GLX_VERSION_1_4
+#define GLX_VERSION_1_4 1
+
+#define GLX_SAMPLE_BUFFERS 100000
+#define GLX_SAMPLES 100001
+
+extern void ( * glXGetProcAddress (const GLubyte *procName)) (void);
+
+#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4)
+
+#endif /* GLX_VERSION_1_4 */
+
+/* -------------------------- GLX_3DFX_multisample ------------------------- */
+
+#ifndef GLX_3DFX_multisample
+#define GLX_3DFX_multisample 1
+
+#define GLX_SAMPLE_BUFFERS_3DFX 0x8050
+#define GLX_SAMPLES_3DFX 0x8051
+
+#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample)
+
+#endif /* GLX_3DFX_multisample */
+
+/* ------------------------ GLX_AMD_gpu_association ------------------------ */
+
+#ifndef GLX_AMD_gpu_association
+#define GLX_AMD_gpu_association 1
+
+#define GLX_GPU_VENDOR_AMD 0x1F00
+#define GLX_GPU_RENDERER_STRING_AMD 0x1F01
+#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define GLX_GPU_RAM_AMD 0x21A3
+#define GLX_GPU_CLOCK_AMD 0x21A4
+#define GLX_GPU_NUM_PIPES_AMD 0x21A5
+#define GLX_GPU_NUM_SIMD_AMD 0x21A6
+#define GLX_GPU_NUM_RB_AMD 0x21A7
+#define GLX_GPU_NUM_SPI_AMD 0x21A8
+
+typedef void ( * PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list);
+typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int* attribList);
+typedef Bool ( * PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx);
+typedef unsigned int ( * PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx);
+typedef GLXContext ( * PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef unsigned int ( * PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int* ids);
+typedef int ( * PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void* data);
+typedef Bool ( * PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx);
+
+#define glXBlitContextFramebufferAMD GLXEW_GET_FUN(__glewXBlitContextFramebufferAMD)
+#define glXCreateAssociatedContextAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAMD)
+#define glXCreateAssociatedContextAttribsAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAttribsAMD)
+#define glXDeleteAssociatedContextAMD GLXEW_GET_FUN(__glewXDeleteAssociatedContextAMD)
+#define glXGetContextGPUIDAMD GLXEW_GET_FUN(__glewXGetContextGPUIDAMD)
+#define glXGetCurrentAssociatedContextAMD GLXEW_GET_FUN(__glewXGetCurrentAssociatedContextAMD)
+#define glXGetGPUIDsAMD GLXEW_GET_FUN(__glewXGetGPUIDsAMD)
+#define glXGetGPUInfoAMD GLXEW_GET_FUN(__glewXGetGPUInfoAMD)
+#define glXMakeAssociatedContextCurrentAMD GLXEW_GET_FUN(__glewXMakeAssociatedContextCurrentAMD)
+
+#define GLXEW_AMD_gpu_association GLXEW_GET_VAR(__GLXEW_AMD_gpu_association)
+
+#endif /* GLX_AMD_gpu_association */
+
+/* --------------------- GLX_ARB_context_flush_control --------------------- */
+
+#ifndef GLX_ARB_context_flush_control
+#define GLX_ARB_context_flush_control 1
+
+#define GLXEW_ARB_context_flush_control GLXEW_GET_VAR(__GLXEW_ARB_context_flush_control)
+
+#endif /* GLX_ARB_context_flush_control */
+
+/* ------------------------- GLX_ARB_create_context ------------------------ */
+
+#ifndef GLX_ARB_create_context
+#define GLX_ARB_create_context 1
+
+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define GLX_CONTEXT_FLAGS_ARB 0x2094
+
+typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+
+#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB)
+
+#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context)
+
+#endif /* GLX_ARB_create_context */
+
+/* -------------------- GLX_ARB_create_context_no_error -------------------- */
+
+#ifndef GLX_ARB_create_context_no_error
+#define GLX_ARB_create_context_no_error 1
+
+#define GLXEW_ARB_create_context_no_error GLXEW_GET_VAR(__GLXEW_ARB_create_context_no_error)
+
+#endif /* GLX_ARB_create_context_no_error */
+
+/* --------------------- GLX_ARB_create_context_profile -------------------- */
+
+#ifndef GLX_ARB_create_context_profile
+#define GLX_ARB_create_context_profile 1
+
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+
+#define GLXEW_ARB_create_context_profile GLXEW_GET_VAR(__GLXEW_ARB_create_context_profile)
+
+#endif /* GLX_ARB_create_context_profile */
+
+/* ------------------- GLX_ARB_create_context_robustness ------------------- */
+
+#ifndef GLX_ARB_create_context_robustness
+#define GLX_ARB_create_context_robustness 1
+
+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
+
+#define GLXEW_ARB_create_context_robustness GLXEW_GET_VAR(__GLXEW_ARB_create_context_robustness)
+
+#endif /* GLX_ARB_create_context_robustness */
+
+/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */
+
+#ifndef GLX_ARB_fbconfig_float
+#define GLX_ARB_fbconfig_float 1
+
+#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
+#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9
+
+#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float)
+
+#endif /* GLX_ARB_fbconfig_float */
+
+/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */
+
+#ifndef GLX_ARB_framebuffer_sRGB
+#define GLX_ARB_framebuffer_sRGB 1
+
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
+
+#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB)
+
+#endif /* GLX_ARB_framebuffer_sRGB */
+
+/* ------------------------ GLX_ARB_get_proc_address ----------------------- */
+
+#ifndef GLX_ARB_get_proc_address
+#define GLX_ARB_get_proc_address 1
+
+extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void);
+
+#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address)
+
+#endif /* GLX_ARB_get_proc_address */
+
+/* -------------------------- GLX_ARB_multisample -------------------------- */
+
+#ifndef GLX_ARB_multisample
+#define GLX_ARB_multisample 1
+
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB 100001
+
+#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample)
+
+#endif /* GLX_ARB_multisample */
+
+/* ---------------- GLX_ARB_robustness_application_isolation --------------- */
+
+#ifndef GLX_ARB_robustness_application_isolation
+#define GLX_ARB_robustness_application_isolation 1
+
+#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define GLXEW_ARB_robustness_application_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_application_isolation)
+
+#endif /* GLX_ARB_robustness_application_isolation */
+
+/* ---------------- GLX_ARB_robustness_share_group_isolation --------------- */
+
+#ifndef GLX_ARB_robustness_share_group_isolation
+#define GLX_ARB_robustness_share_group_isolation 1
+
+#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define GLXEW_ARB_robustness_share_group_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_share_group_isolation)
+
+#endif /* GLX_ARB_robustness_share_group_isolation */
+
+/* ---------------------- GLX_ARB_vertex_buffer_object --------------------- */
+
+#ifndef GLX_ARB_vertex_buffer_object
+#define GLX_ARB_vertex_buffer_object 1
+
+#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
+
+#define GLXEW_ARB_vertex_buffer_object GLXEW_GET_VAR(__GLXEW_ARB_vertex_buffer_object)
+
+#endif /* GLX_ARB_vertex_buffer_object */
+
+/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */
+
+#ifndef GLX_ATI_pixel_format_float
+#define GLX_ATI_pixel_format_float 1
+
+#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100
+
+#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float)
+
+#endif /* GLX_ATI_pixel_format_float */
+
+/* ------------------------- GLX_ATI_render_texture ------------------------ */
+
+#ifndef GLX_ATI_render_texture
+#define GLX_ATI_render_texture 1
+
+#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800
+#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801
+#define GLX_TEXTURE_FORMAT_ATI 0x9802
+#define GLX_TEXTURE_TARGET_ATI 0x9803
+#define GLX_MIPMAP_TEXTURE_ATI 0x9804
+#define GLX_TEXTURE_RGB_ATI 0x9805
+#define GLX_TEXTURE_RGBA_ATI 0x9806
+#define GLX_NO_TEXTURE_ATI 0x9807
+#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808
+#define GLX_TEXTURE_1D_ATI 0x9809
+#define GLX_TEXTURE_2D_ATI 0x980A
+#define GLX_MIPMAP_LEVEL_ATI 0x980B
+#define GLX_CUBE_MAP_FACE_ATI 0x980C
+#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D
+#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E
+#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F
+#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810
+#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811
+#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812
+#define GLX_FRONT_LEFT_ATI 0x9813
+#define GLX_FRONT_RIGHT_ATI 0x9814
+#define GLX_BACK_LEFT_ATI 0x9815
+#define GLX_BACK_RIGHT_ATI 0x9816
+#define GLX_AUX0_ATI 0x9817
+#define GLX_AUX1_ATI 0x9818
+#define GLX_AUX2_ATI 0x9819
+#define GLX_AUX3_ATI 0x981A
+#define GLX_AUX4_ATI 0x981B
+#define GLX_AUX5_ATI 0x981C
+#define GLX_AUX6_ATI 0x981D
+#define GLX_AUX7_ATI 0x981E
+#define GLX_AUX8_ATI 0x981F
+#define GLX_AUX9_ATI 0x9820
+#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821
+#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822
+
+typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer);
+typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list);
+typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer);
+
+#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI)
+#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI)
+#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI)
+
+#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture)
+
+#endif /* GLX_ATI_render_texture */
+
+/* --------------------------- GLX_EXT_buffer_age -------------------------- */
+
+#ifndef GLX_EXT_buffer_age
+#define GLX_EXT_buffer_age 1
+
+#define GLX_BACK_BUFFER_AGE_EXT 0x20F4
+
+#define GLXEW_EXT_buffer_age GLXEW_GET_VAR(__GLXEW_EXT_buffer_age)
+
+#endif /* GLX_EXT_buffer_age */
+
+/* ------------------- GLX_EXT_create_context_es2_profile ------------------ */
+
+#ifndef GLX_EXT_create_context_es2_profile
+#define GLX_EXT_create_context_es2_profile 1
+
+#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+
+#define GLXEW_EXT_create_context_es2_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es2_profile)
+
+#endif /* GLX_EXT_create_context_es2_profile */
+
+/* ------------------- GLX_EXT_create_context_es_profile ------------------- */
+
+#ifndef GLX_EXT_create_context_es_profile
+#define GLX_EXT_create_context_es_profile 1
+
+#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+
+#define GLXEW_EXT_create_context_es_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es_profile)
+
+#endif /* GLX_EXT_create_context_es_profile */
+
+/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */
+
+#ifndef GLX_EXT_fbconfig_packed_float
+#define GLX_EXT_fbconfig_packed_float 1
+
+#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
+#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
+
+#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float)
+
+#endif /* GLX_EXT_fbconfig_packed_float */
+
+/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */
+
+#ifndef GLX_EXT_framebuffer_sRGB
+#define GLX_EXT_framebuffer_sRGB 1
+
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
+
+#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB)
+
+#endif /* GLX_EXT_framebuffer_sRGB */
+
+/* ------------------------- GLX_EXT_import_context ------------------------ */
+
+#ifndef GLX_EXT_import_context
+#define GLX_EXT_import_context 1
+
+#define GLX_SHARE_CONTEXT_EXT 0x800A
+#define GLX_VISUAL_ID_EXT 0x800B
+#define GLX_SCREEN_EXT 0x800C
+
+typedef XID GLXContextID;
+
+typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context);
+typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context);
+typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID);
+typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value);
+
+#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT)
+#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT)
+#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT)
+#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT)
+
+#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context)
+
+#endif /* GLX_EXT_import_context */
+
+/* ---------------------------- GLX_EXT_libglvnd --------------------------- */
+
+#ifndef GLX_EXT_libglvnd
+#define GLX_EXT_libglvnd 1
+
+#define GLX_VENDOR_NAMES_EXT 0x20F6
+
+#define GLXEW_EXT_libglvnd GLXEW_GET_VAR(__GLXEW_EXT_libglvnd)
+
+#endif /* GLX_EXT_libglvnd */
+
+/* -------------------------- GLX_EXT_scene_marker ------------------------- */
+
+#ifndef GLX_EXT_scene_marker
+#define GLX_EXT_scene_marker 1
+
+#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker)
+
+#endif /* GLX_EXT_scene_marker */
+
+/* -------------------------- GLX_EXT_stereo_tree -------------------------- */
+
+#ifndef GLX_EXT_stereo_tree
+#define GLX_EXT_stereo_tree 1
+
+#define GLX_STEREO_NOTIFY_EXT 0x00000000
+#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
+#define GLX_STEREO_TREE_EXT 0x20F5
+
+#define GLXEW_EXT_stereo_tree GLXEW_GET_VAR(__GLXEW_EXT_stereo_tree)
+
+#endif /* GLX_EXT_stereo_tree */
+
+/* -------------------------- GLX_EXT_swap_control ------------------------- */
+
+#ifndef GLX_EXT_swap_control
+#define GLX_EXT_swap_control 1
+
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+
+typedef void ( * PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval);
+
+#define glXSwapIntervalEXT GLXEW_GET_FUN(__glewXSwapIntervalEXT)
+
+#define GLXEW_EXT_swap_control GLXEW_GET_VAR(__GLXEW_EXT_swap_control)
+
+#endif /* GLX_EXT_swap_control */
+
+/* ----------------------- GLX_EXT_swap_control_tear ----------------------- */
+
+#ifndef GLX_EXT_swap_control_tear
+#define GLX_EXT_swap_control_tear 1
+
+#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
+
+#define GLXEW_EXT_swap_control_tear GLXEW_GET_VAR(__GLXEW_EXT_swap_control_tear)
+
+#endif /* GLX_EXT_swap_control_tear */
+
+/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */
+
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_EXT_texture_from_pixmap 1
+
+#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
+#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
+#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
+#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
+#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
+#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
+#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
+#define GLX_Y_INVERTED_EXT 0x20D4
+#define GLX_TEXTURE_FORMAT_EXT 0x20D5
+#define GLX_TEXTURE_TARGET_EXT 0x20D6
+#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
+#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define GLX_TEXTURE_1D_EXT 0x20DB
+#define GLX_TEXTURE_2D_EXT 0x20DC
+#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
+#define GLX_FRONT_LEFT_EXT 0x20DE
+#define GLX_FRONT_RIGHT_EXT 0x20DF
+#define GLX_BACK_LEFT_EXT 0x20E0
+#define GLX_BACK_RIGHT_EXT 0x20E1
+#define GLX_AUX0_EXT 0x20E2
+#define GLX_AUX1_EXT 0x20E3
+#define GLX_AUX2_EXT 0x20E4
+#define GLX_AUX3_EXT 0x20E5
+#define GLX_AUX4_EXT 0x20E6
+#define GLX_AUX5_EXT 0x20E7
+#define GLX_AUX6_EXT 0x20E8
+#define GLX_AUX7_EXT 0x20E9
+#define GLX_AUX8_EXT 0x20EA
+#define GLX_AUX9_EXT 0x20EB
+
+typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer, const int *attrib_list);
+typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer);
+
+#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT)
+#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT)
+
+#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap)
+
+#endif /* GLX_EXT_texture_from_pixmap */
+
+/* -------------------------- GLX_EXT_visual_info -------------------------- */
+
+#ifndef GLX_EXT_visual_info
+#define GLX_EXT_visual_info 1
+
+#define GLX_X_VISUAL_TYPE_EXT 0x22
+#define GLX_TRANSPARENT_TYPE_EXT 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
+#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
+#define GLX_NONE_EXT 0x8000
+#define GLX_TRUE_COLOR_EXT 0x8002
+#define GLX_DIRECT_COLOR_EXT 0x8003
+#define GLX_PSEUDO_COLOR_EXT 0x8004
+#define GLX_STATIC_COLOR_EXT 0x8005
+#define GLX_GRAY_SCALE_EXT 0x8006
+#define GLX_STATIC_GRAY_EXT 0x8007
+#define GLX_TRANSPARENT_RGB_EXT 0x8008
+#define GLX_TRANSPARENT_INDEX_EXT 0x8009
+
+#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info)
+
+#endif /* GLX_EXT_visual_info */
+
+/* ------------------------- GLX_EXT_visual_rating ------------------------- */
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_EXT_visual_rating 1
+
+#define GLX_VISUAL_CAVEAT_EXT 0x20
+#define GLX_SLOW_VISUAL_EXT 0x8001
+#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+
+#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating)
+
+#endif /* GLX_EXT_visual_rating */
+
+/* -------------------------- GLX_INTEL_swap_event ------------------------- */
+
+#ifndef GLX_INTEL_swap_event
+#define GLX_INTEL_swap_event 1
+
+#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180
+#define GLX_COPY_COMPLETE_INTEL 0x8181
+#define GLX_FLIP_COMPLETE_INTEL 0x8182
+#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000
+
+#define GLXEW_INTEL_swap_event GLXEW_GET_VAR(__GLXEW_INTEL_swap_event)
+
+#endif /* GLX_INTEL_swap_event */
+
+/* -------------------------- GLX_MESA_agp_offset -------------------------- */
+
+#ifndef GLX_MESA_agp_offset
+#define GLX_MESA_agp_offset 1
+
+typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer);
+
+#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA)
+
+#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset)
+
+#endif /* GLX_MESA_agp_offset */
+
+/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */
+
+#ifndef GLX_MESA_copy_sub_buffer
+#define GLX_MESA_copy_sub_buffer 1
+
+typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height);
+
+#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA)
+
+#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer)
+
+#endif /* GLX_MESA_copy_sub_buffer */
+
+/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */
+
+#ifndef GLX_MESA_pixmap_colormap
+#define GLX_MESA_pixmap_colormap 1
+
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+
+#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA)
+
+#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap)
+
+#endif /* GLX_MESA_pixmap_colormap */
+
+/* ------------------------ GLX_MESA_query_renderer ------------------------ */
+
+#ifndef GLX_MESA_query_renderer
+#define GLX_MESA_query_renderer 1
+
+#define GLX_RENDERER_VENDOR_ID_MESA 0x8183
+#define GLX_RENDERER_DEVICE_ID_MESA 0x8184
+#define GLX_RENDERER_VERSION_MESA 0x8185
+#define GLX_RENDERER_ACCELERATED_MESA 0x8186
+#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187
+#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188
+#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189
+#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A
+#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B
+#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C
+#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D
+#define GLX_RENDERER_ID_MESA 0x818E
+
+typedef Bool ( * PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int* value);
+typedef const char* ( * PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute);
+typedef Bool ( * PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display* dpy, int screen, int renderer, int attribute, unsigned int *value);
+typedef const char* ( * PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute);
+
+#define glXQueryCurrentRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererIntegerMESA)
+#define glXQueryCurrentRendererStringMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererStringMESA)
+#define glXQueryRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryRendererIntegerMESA)
+#define glXQueryRendererStringMESA GLXEW_GET_FUN(__glewXQueryRendererStringMESA)
+
+#define GLXEW_MESA_query_renderer GLXEW_GET_VAR(__GLXEW_MESA_query_renderer)
+
+#endif /* GLX_MESA_query_renderer */
+
+/* ------------------------ GLX_MESA_release_buffers ----------------------- */
+
+#ifndef GLX_MESA_release_buffers
+#define GLX_MESA_release_buffers 1
+
+typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d);
+
+#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA)
+
+#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers)
+
+#endif /* GLX_MESA_release_buffers */
+
+/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */
+
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_MESA_set_3dfx_mode 1
+
+#define GLX_3DFX_WINDOW_MODE_MESA 0x1
+#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
+
+typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode);
+
+#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA)
+
+#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode)
+
+#endif /* GLX_MESA_set_3dfx_mode */
+
+/* ------------------------- GLX_MESA_swap_control ------------------------- */
+
+#ifndef GLX_MESA_swap_control
+#define GLX_MESA_swap_control 1
+
+typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC) (void);
+typedef int ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval);
+
+#define glXGetSwapIntervalMESA GLXEW_GET_FUN(__glewXGetSwapIntervalMESA)
+#define glXSwapIntervalMESA GLXEW_GET_FUN(__glewXSwapIntervalMESA)
+
+#define GLXEW_MESA_swap_control GLXEW_GET_VAR(__GLXEW_MESA_swap_control)
+
+#endif /* GLX_MESA_swap_control */
+
+/* --------------------------- GLX_NV_copy_buffer -------------------------- */
+
+#ifndef GLX_NV_copy_buffer
+#define GLX_NV_copy_buffer 1
+
+typedef void ( * PFNGLXCOPYBUFFERSUBDATANVPROC) (Display* dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void ( * PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) (Display* dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+
+#define glXCopyBufferSubDataNV GLXEW_GET_FUN(__glewXCopyBufferSubDataNV)
+#define glXNamedCopyBufferSubDataNV GLXEW_GET_FUN(__glewXNamedCopyBufferSubDataNV)
+
+#define GLXEW_NV_copy_buffer GLXEW_GET_VAR(__GLXEW_NV_copy_buffer)
+
+#endif /* GLX_NV_copy_buffer */
+
+/* --------------------------- GLX_NV_copy_image --------------------------- */
+
+#ifndef GLX_NV_copy_image
+#define GLX_NV_copy_image 1
+
+typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glXCopyImageSubDataNV GLXEW_GET_FUN(__glewXCopyImageSubDataNV)
+
+#define GLXEW_NV_copy_image GLXEW_GET_VAR(__GLXEW_NV_copy_image)
+
+#endif /* GLX_NV_copy_image */
+
+/* ------------------------ GLX_NV_delay_before_swap ----------------------- */
+
+#ifndef GLX_NV_delay_before_swap
+#define GLX_NV_delay_before_swap 1
+
+typedef Bool ( * PFNGLXDELAYBEFORESWAPNVPROC) (Display* dpy, GLXDrawable drawable, GLfloat seconds);
+
+#define glXDelayBeforeSwapNV GLXEW_GET_FUN(__glewXDelayBeforeSwapNV)
+
+#define GLXEW_NV_delay_before_swap GLXEW_GET_VAR(__GLXEW_NV_delay_before_swap)
+
+#endif /* GLX_NV_delay_before_swap */
+
+/* -------------------------- GLX_NV_float_buffer -------------------------- */
+
+#ifndef GLX_NV_float_buffer
+#define GLX_NV_float_buffer 1
+
+#define GLX_FLOAT_COMPONENTS_NV 0x20B0
+
+#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer)
+
+#endif /* GLX_NV_float_buffer */
+
+/* ---------------------- GLX_NV_multisample_coverage ---------------------- */
+
+#ifndef GLX_NV_multisample_coverage
+#define GLX_NV_multisample_coverage 1
+
+#define GLX_COLOR_SAMPLES_NV 0x20B3
+#define GLX_COVERAGE_SAMPLES_NV 100001
+
+#define GLXEW_NV_multisample_coverage GLXEW_GET_VAR(__GLXEW_NV_multisample_coverage)
+
+#endif /* GLX_NV_multisample_coverage */
+
+/* -------------------------- GLX_NV_present_video ------------------------- */
+
+#ifndef GLX_NV_present_video
+#define GLX_NV_present_video 1
+
+#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0
+
+typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
+typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements);
+
+#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV)
+#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV)
+
+#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video)
+
+#endif /* GLX_NV_present_video */
+
+/* ------------------ GLX_NV_robustness_video_memory_purge ----------------- */
+
+#ifndef GLX_NV_robustness_video_memory_purge
+#define GLX_NV_robustness_video_memory_purge 1
+
+#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
+
+#define GLXEW_NV_robustness_video_memory_purge GLXEW_GET_VAR(__GLXEW_NV_robustness_video_memory_purge)
+
+#endif /* GLX_NV_robustness_video_memory_purge */
+
+/* --------------------------- GLX_NV_swap_group --------------------------- */
+
+#ifndef GLX_NV_swap_group
+#define GLX_NV_swap_group 1
+
+typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier);
+typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group);
+typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint *count);
+typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
+typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
+typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen);
+
+#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV)
+#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV)
+#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV)
+#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV)
+#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV)
+#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV)
+
+#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group)
+
+#endif /* GLX_NV_swap_group */
+
+/* ----------------------- GLX_NV_vertex_array_range ----------------------- */
+
+#ifndef GLX_NV_vertex_array_range
+#define GLX_NV_vertex_array_range 1
+
+typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority);
+typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer);
+
+#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV)
+#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV)
+
+#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range)
+
+#endif /* GLX_NV_vertex_array_range */
+
+/* -------------------------- GLX_NV_video_capture ------------------------- */
+
+#ifndef GLX_NV_video_capture
+#define GLX_NV_video_capture 1
+
+#define GLX_DEVICE_ID_NV 0x20CD
+#define GLX_UNIQUE_ID_NV 0x20CE
+#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+
+typedef XID GLXVideoCaptureDeviceNV;
+
+typedef int ( * PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display* dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
+typedef GLXVideoCaptureDeviceNV * ( * PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display* dpy, int screen, int *nelements);
+typedef void ( * PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device);
+typedef int ( * PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
+typedef void ( * PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device);
+
+#define glXBindVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXBindVideoCaptureDeviceNV)
+#define glXEnumerateVideoCaptureDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoCaptureDevicesNV)
+#define glXLockVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXLockVideoCaptureDeviceNV)
+#define glXQueryVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXQueryVideoCaptureDeviceNV)
+#define glXReleaseVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoCaptureDeviceNV)
+
+#define GLXEW_NV_video_capture GLXEW_GET_VAR(__GLXEW_NV_video_capture)
+
+#endif /* GLX_NV_video_capture */
+
+/* ---------------------------- GLX_NV_video_out --------------------------- */
+
+#ifndef GLX_NV_video_out
+#define GLX_NV_video_out 1
+
+#define GLX_VIDEO_OUT_COLOR_NV 0x20C3
+#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4
+#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5
+#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define GLX_VIDEO_OUT_FRAME_NV 0x20C8
+#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9
+#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA
+#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB
+#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC
+
+typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
+typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
+typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice);
+typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf);
+typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
+
+#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV)
+#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV)
+#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV)
+#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV)
+#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV)
+#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV)
+
+#define GLXEW_NV_video_out GLXEW_GET_VAR(__GLXEW_NV_video_out)
+
+#endif /* GLX_NV_video_out */
+
+/* -------------------------- GLX_OML_swap_method -------------------------- */
+
+#ifndef GLX_OML_swap_method
+#define GLX_OML_swap_method 1
+
+#define GLX_SWAP_METHOD_OML 0x8060
+#define GLX_SWAP_EXCHANGE_OML 0x8061
+#define GLX_SWAP_COPY_OML 0x8062
+#define GLX_SWAP_UNDEFINED_OML 0x8063
+
+#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method)
+
+#endif /* GLX_OML_swap_method */
+
+/* -------------------------- GLX_OML_sync_control ------------------------- */
+
+#ifndef GLX_OML_sync_control
+#define GLX_OML_sync_control 1
+
+typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator);
+typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc);
+typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc);
+typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc);
+
+#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML)
+#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML)
+#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML)
+#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML)
+#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML)
+
+#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control)
+
+#endif /* GLX_OML_sync_control */
+
+/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */
+
+#ifndef GLX_SGIS_blended_overlay
+#define GLX_SGIS_blended_overlay 1
+
+#define GLX_BLENDED_RGBA_SGIS 0x8025
+
+#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay)
+
+#endif /* GLX_SGIS_blended_overlay */
+
+/* -------------------------- GLX_SGIS_color_range ------------------------- */
+
+#ifndef GLX_SGIS_color_range
+#define GLX_SGIS_color_range 1
+
+#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range)
+
+#endif /* GLX_SGIS_color_range */
+
+/* -------------------------- GLX_SGIS_multisample ------------------------- */
+
+#ifndef GLX_SGIS_multisample
+#define GLX_SGIS_multisample 1
+
+#define GLX_SAMPLE_BUFFERS_SGIS 100000
+#define GLX_SAMPLES_SGIS 100001
+
+#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample)
+
+#endif /* GLX_SGIS_multisample */
+
+/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */
+
+#ifndef GLX_SGIS_shared_multisample
+#define GLX_SGIS_shared_multisample 1
+
+#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
+#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
+
+#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample)
+
+#endif /* GLX_SGIS_shared_multisample */
+
+/* --------------------------- GLX_SGIX_fbconfig --------------------------- */
+
+#ifndef GLX_SGIX_fbconfig
+#define GLX_SGIX_fbconfig 1
+
+#define GLX_RGBA_BIT_SGIX 0x00000001
+#define GLX_WINDOW_BIT_SGIX 0x00000001
+#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002
+#define GLX_PIXMAP_BIT_SGIX 0x00000002
+#define GLX_SCREEN_EXT 0x800C
+#define GLX_DRAWABLE_TYPE_SGIX 0x8010
+#define GLX_RENDER_TYPE_SGIX 0x8011
+#define GLX_X_RENDERABLE_SGIX 0x8012
+#define GLX_FBCONFIG_ID_SGIX 0x8013
+#define GLX_RGBA_TYPE_SGIX 0x8014
+#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015
+
+typedef XID GLXFBConfigIDSGIX;
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+
+typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap);
+typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value);
+typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis);
+typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config);
+
+#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX)
+#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX)
+#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX)
+#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX)
+#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX)
+#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX)
+
+#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig)
+
+#endif /* GLX_SGIX_fbconfig */
+
+/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */
+
+#ifndef GLX_SGIX_hyperpipe
+#define GLX_SGIX_hyperpipe 1
+
+#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001
+#define GLX_PIPE_RECT_SGIX 0x00000001
+#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002
+#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002
+#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003
+#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004
+#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
+#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91
+#define GLX_BAD_HYPERPIPE_SGIX 92
+#define GLX_HYPERPIPE_ID_SGIX 0x8030
+
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int networkId;
+} GLXHyperpipeNetworkSGIX;
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int XOrigin;
+ int YOrigin;
+ int maxHeight;
+ int maxWidth;
+} GLXPipeRectLimits;
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int channel;
+ unsigned int participationType;
+ int timeSlice;
+} GLXHyperpipeConfigSGIX;
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int srcXOrigin;
+ int srcYOrigin;
+ int srcWidth;
+ int srcHeight;
+ int destXOrigin;
+ int destYOrigin;
+ int destWidth;
+ int destHeight;
+} GLXPipeRect;
+
+typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
+typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
+typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
+typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
+typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes);
+typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes);
+
+#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX)
+#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX)
+#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX)
+#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX)
+#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX)
+#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX)
+#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX)
+#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX)
+
+#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe)
+
+#endif /* GLX_SGIX_hyperpipe */
+
+/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_SGIX_pbuffer 1
+
+#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
+#define GLX_PBUFFER_BIT_SGIX 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
+#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
+#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
+#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
+#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
+#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
+#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
+#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
+#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
+#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
+#define GLX_PRESERVED_CONTENTS_SGIX 0x801B
+#define GLX_LARGEST_PBUFFER_SGIX 0x801C
+#define GLX_WIDTH_SGIX 0x801D
+#define GLX_HEIGHT_SGIX 0x801E
+#define GLX_EVENT_MASK_SGIX 0x801F
+#define GLX_DAMAGED_SGIX 0x8020
+#define GLX_SAVED_SGIX 0x8021
+#define GLX_WINDOW_SGIX 0x8022
+#define GLX_PBUFFER_SGIX 0x8023
+#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
+
+typedef XID GLXPbufferSGIX;
+typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX;
+
+typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list);
+typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf);
+typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask);
+typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value);
+typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask);
+
+#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX)
+#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX)
+#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX)
+#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX)
+#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX)
+
+#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer)
+
+#endif /* GLX_SGIX_pbuffer */
+
+/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */
+
+#ifndef GLX_SGIX_swap_barrier
+#define GLX_SGIX_swap_barrier 1
+
+typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier);
+typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max);
+
+#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX)
+#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX)
+
+#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier)
+
+#endif /* GLX_SGIX_swap_barrier */
+
+/* -------------------------- GLX_SGIX_swap_group -------------------------- */
+
+#ifndef GLX_SGIX_swap_group
+#define GLX_SGIX_swap_group 1
+
+typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
+
+#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX)
+
+#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group)
+
+#endif /* GLX_SGIX_swap_group */
+
+/* ------------------------- GLX_SGIX_video_resize ------------------------- */
+
+#ifndef GLX_SGIX_video_resize
+#define GLX_SGIX_video_resize 1
+
+#define GLX_SYNC_FRAME_SGIX 0x00000000
+#define GLX_SYNC_SWAP_SGIX 0x00000001
+
+typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window);
+typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h);
+typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype);
+typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h);
+typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
+
+#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX)
+#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX)
+#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX)
+#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX)
+#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX)
+
+#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize)
+
+#endif /* GLX_SGIX_video_resize */
+
+/* ---------------------- GLX_SGIX_visual_select_group --------------------- */
+
+#ifndef GLX_SGIX_visual_select_group
+#define GLX_SGIX_visual_select_group 1
+
+#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028
+
+#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group)
+
+#endif /* GLX_SGIX_visual_select_group */
+
+/* ---------------------------- GLX_SGI_cushion ---------------------------- */
+
+#ifndef GLX_SGI_cushion
+#define GLX_SGI_cushion 1
+
+typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion);
+
+#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI)
+
+#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion)
+
+#endif /* GLX_SGI_cushion */
+
+/* ----------------------- GLX_SGI_make_current_read ----------------------- */
+
+#ifndef GLX_SGI_make_current_read
+#define GLX_SGI_make_current_read 1
+
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void);
+typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+
+#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI)
+#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI)
+
+#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read)
+
+#endif /* GLX_SGI_make_current_read */
+
+/* -------------------------- GLX_SGI_swap_control ------------------------- */
+
+#ifndef GLX_SGI_swap_control
+#define GLX_SGI_swap_control 1
+
+typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
+
+#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI)
+
+#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control)
+
+#endif /* GLX_SGI_swap_control */
+
+/* --------------------------- GLX_SGI_video_sync -------------------------- */
+
+#ifndef GLX_SGI_video_sync
+#define GLX_SGI_video_sync 1
+
+typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int* count);
+typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count);
+
+#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI)
+#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI)
+
+#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync)
+
+#endif /* GLX_SGI_video_sync */
+
+/* --------------------- GLX_SUN_get_transparent_index --------------------- */
+
+#ifndef GLX_SUN_get_transparent_index
+#define GLX_SUN_get_transparent_index 1
+
+typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex);
+
+#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN)
+
+#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index)
+
+#endif /* GLX_SUN_get_transparent_index */
+
+/* -------------------------- GLX_SUN_video_resize ------------------------- */
+
+#ifndef GLX_SUN_video_resize
+#define GLX_SUN_video_resize 1
+
+#define GLX_VIDEO_RESIZE_SUN 0x8171
+#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD
+
+typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor);
+typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor);
+
+#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN)
+#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN)
+
+#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize)
+
+#endif /* GLX_SUN_video_resize */
+
+/* ------------------------------------------------------------------------- */
+
+#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT
+#define GLXEW_VAR_EXPORT GLEW_VAR_EXPORT
+
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay;
+
+GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig;
+GLXEW_FUN_EXPORT PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext;
+GLXEW_FUN_EXPORT PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer;
+GLXEW_FUN_EXPORT PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap;
+GLXEW_FUN_EXPORT PFNGLXCREATEWINDOWPROC __glewXCreateWindow;
+GLXEW_FUN_EXPORT PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer;
+GLXEW_FUN_EXPORT PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap;
+GLXEW_FUN_EXPORT PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow;
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs;
+GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent;
+GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig;
+GLXEW_FUN_EXPORT PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent;
+GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTPROC __glewXQueryContext;
+GLXEW_FUN_EXPORT PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable;
+GLXEW_FUN_EXPORT PFNGLXSELECTEVENTPROC __glewXSelectEvent;
+
+GLXEW_FUN_EXPORT PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD;
+GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD;
+GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD;
+GLXEW_FUN_EXPORT PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD;
+GLXEW_FUN_EXPORT PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD;
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD;
+GLXEW_FUN_EXPORT PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD;
+GLXEW_FUN_EXPORT PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD;
+GLXEW_FUN_EXPORT PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD;
+
+GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB;
+
+GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI;
+GLXEW_FUN_EXPORT PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI;
+GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI;
+
+GLXEW_FUN_EXPORT PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT;
+GLXEW_FUN_EXPORT PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT;
+GLXEW_FUN_EXPORT PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT;
+GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT;
+
+GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT;
+
+GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT;
+GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT;
+
+GLXEW_FUN_EXPORT PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA;
+
+GLXEW_FUN_EXPORT PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA;
+
+GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA;
+
+GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC __glewXQueryCurrentRendererIntegerMESA;
+GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC __glewXQueryCurrentRendererStringMESA;
+GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERINTEGERMESAPROC __glewXQueryRendererIntegerMESA;
+GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERSTRINGMESAPROC __glewXQueryRendererStringMESA;
+
+GLXEW_FUN_EXPORT PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA;
+
+GLXEW_FUN_EXPORT PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA;
+
+GLXEW_FUN_EXPORT PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA;
+GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA;
+
+GLXEW_FUN_EXPORT PFNGLXCOPYBUFFERSUBDATANVPROC __glewXCopyBufferSubDataNV;
+GLXEW_FUN_EXPORT PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC __glewXNamedCopyBufferSubDataNV;
+
+GLXEW_FUN_EXPORT PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV;
+
+GLXEW_FUN_EXPORT PFNGLXDELAYBEFORESWAPNVPROC __glewXDelayBeforeSwapNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV;
+GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV;
+GLXEW_FUN_EXPORT PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV;
+
+GLXEW_FUN_EXPORT PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV;
+GLXEW_FUN_EXPORT PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV;
+GLXEW_FUN_EXPORT PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV;
+GLXEW_FUN_EXPORT PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV;
+GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV;
+GLXEW_FUN_EXPORT PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV;
+
+GLXEW_FUN_EXPORT PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML;
+GLXEW_FUN_EXPORT PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML;
+GLXEW_FUN_EXPORT PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML;
+GLXEW_FUN_EXPORT PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML;
+GLXEW_FUN_EXPORT PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML;
+
+GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX;
+GLXEW_FUN_EXPORT PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX;
+GLXEW_FUN_EXPORT PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX;
+GLXEW_FUN_EXPORT PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX;
+GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX;
+GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXCUSHIONSGIPROC __glewXCushionSGI;
+
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI;
+GLXEW_FUN_EXPORT PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI;
+
+GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI;
+
+GLXEW_FUN_EXPORT PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI;
+GLXEW_FUN_EXPORT PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI;
+
+GLXEW_FUN_EXPORT PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN;
+
+GLXEW_FUN_EXPORT PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN;
+GLXEW_FUN_EXPORT PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_3;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_4;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_3DFX_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_AMD_gpu_association;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_context_flush_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_no_error;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_profile;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_robustness;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_fbconfig_float;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_get_proc_address;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_application_isolation;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_share_group_isolation;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_vertex_buffer_object;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_pixel_format_float;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_render_texture;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_buffer_age;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es2_profile;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es_profile;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_import_context;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_libglvnd;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_scene_marker;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_stereo_tree;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control_tear;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_info;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_rating;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_INTEL_swap_event;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_agp_offset;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_query_renderer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_release_buffers;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_swap_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_buffer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_image;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_delay_before_swap;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_float_buffer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_multisample_coverage;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_present_video;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_robustness_video_memory_purge;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_swap_group;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_vertex_array_range;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_capture;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_out;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_swap_method;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_sync_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_blended_overlay;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_color_range;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_shared_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_fbconfig;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_hyperpipe;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_pbuffer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_barrier;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_group;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_video_resize;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_visual_select_group;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_cushion;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_make_current_read;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_swap_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_video_sync;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_get_transparent_index;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_video_resize;
+/* ------------------------------------------------------------------------ */
+
+GLEWAPI GLenum GLEWAPIENTRY glxewInit ();
+GLEWAPI GLboolean GLEWAPIENTRY glxewIsSupported (const char *name);
+
+#ifndef GLXEW_GET_VAR
+#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x)
+#endif
+
+#ifndef GLXEW_GET_FUN
+#define GLXEW_GET_FUN(x) x
+#endif
+
+GLEWAPI GLboolean GLEWAPIENTRY glxewGetExtension (const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __glxew_h__ */
diff --git a/graphics/asymptote/GL/wglew.h b/graphics/asymptote/GL/wglew.h
new file mode 100644
index 0000000000..2097c0f033
--- /dev/null
+++ b/graphics/asymptote/GL/wglew.h
@@ -0,0 +1,1447 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2008-2017, Nigel Stewart <nigels[]users sourceforge net>
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE 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 AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __wglew_h__
+#define __wglew_h__
+#define __WGLEW_H__
+
+#ifdef __wglext_h_
+#error wglext.h included before wglew.h
+#endif
+
+#define __wglext_h_
+
+#if !defined(WINAPI)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif
+#include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+/*
+ * GLEW_STATIC needs to be set when using the static version.
+ * GLEW_BUILD is set when building the DLL version.
+ */
+#ifdef GLEW_STATIC
+# define GLEWAPI extern
+#else
+# ifdef GLEW_BUILD
+# define GLEWAPI extern __declspec(dllexport)
+# else
+# define GLEWAPI extern __declspec(dllimport)
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* -------------------------- WGL_3DFX_multisample ------------------------- */
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+
+#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define WGL_SAMPLES_3DFX 0x2061
+
+#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample)
+
+#endif /* WGL_3DFX_multisample */
+
+/* ------------------------- WGL_3DL_stereo_control ------------------------ */
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_3DL_stereo_control 1
+
+#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+
+typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
+
+#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL)
+
+#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control)
+
+#endif /* WGL_3DL_stereo_control */
+
+/* ------------------------ WGL_AMD_gpu_association ------------------------ */
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+
+#define WGL_GPU_VENDOR_AMD 0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD 0x21A3
+#define WGL_GPU_CLOCK_AMD 0x21A4
+#define WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define WGL_GPU_NUM_RB_AMD 0x21A7
+#define WGL_GPU_NUM_SPI_AMD 0x21A8
+
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int* attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT* ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, INT property, GLenum dataType, UINT size, void* data);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+
+#define wglBlitContextFramebufferAMD WGLEW_GET_FUN(__wglewBlitContextFramebufferAMD)
+#define wglCreateAssociatedContextAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAMD)
+#define wglCreateAssociatedContextAttribsAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAttribsAMD)
+#define wglDeleteAssociatedContextAMD WGLEW_GET_FUN(__wglewDeleteAssociatedContextAMD)
+#define wglGetContextGPUIDAMD WGLEW_GET_FUN(__wglewGetContextGPUIDAMD)
+#define wglGetCurrentAssociatedContextAMD WGLEW_GET_FUN(__wglewGetCurrentAssociatedContextAMD)
+#define wglGetGPUIDsAMD WGLEW_GET_FUN(__wglewGetGPUIDsAMD)
+#define wglGetGPUInfoAMD WGLEW_GET_FUN(__wglewGetGPUInfoAMD)
+#define wglMakeAssociatedContextCurrentAMD WGLEW_GET_FUN(__wglewMakeAssociatedContextCurrentAMD)
+
+#define WGLEW_AMD_gpu_association WGLEW_GET_VAR(__WGLEW_AMD_gpu_association)
+
+#endif /* WGL_AMD_gpu_association */
+
+/* ------------------------- WGL_ARB_buffer_region ------------------------- */
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+
+#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB)
+#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB)
+#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB)
+#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB)
+
+#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region)
+
+#endif /* WGL_ARB_buffer_region */
+
+/* --------------------- WGL_ARB_context_flush_control --------------------- */
+
+#ifndef WGL_ARB_context_flush_control
+#define WGL_ARB_context_flush_control 1
+
+#define WGLEW_ARB_context_flush_control WGLEW_GET_VAR(__WGLEW_ARB_context_flush_control)
+
+#endif /* WGL_ARB_context_flush_control */
+
+/* ------------------------- WGL_ARB_create_context ------------------------ */
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList);
+
+#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB)
+
+#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context)
+
+#endif /* WGL_ARB_create_context */
+
+/* -------------------- WGL_ARB_create_context_no_error -------------------- */
+
+#ifndef WGL_ARB_create_context_no_error
+#define WGL_ARB_create_context_no_error 1
+
+#define WGLEW_ARB_create_context_no_error WGLEW_GET_VAR(__WGLEW_ARB_create_context_no_error)
+
+#endif /* WGL_ARB_create_context_no_error */
+
+/* --------------------- WGL_ARB_create_context_profile -------------------- */
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+
+#define WGLEW_ARB_create_context_profile WGLEW_GET_VAR(__WGLEW_ARB_create_context_profile)
+
+#endif /* WGL_ARB_create_context_profile */
+
+/* ------------------- WGL_ARB_create_context_robustness ------------------- */
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness 1
+
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+
+#define WGLEW_ARB_create_context_robustness WGLEW_GET_VAR(__WGLEW_ARB_create_context_robustness)
+
+#endif /* WGL_ARB_create_context_robustness */
+
+/* ----------------------- WGL_ARB_extensions_string ----------------------- */
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+
+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+
+#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB)
+
+#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string)
+
+#endif /* WGL_ARB_extensions_string */
+
+/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB 1
+
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+
+#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB)
+
+#endif /* WGL_ARB_framebuffer_sRGB */
+
+/* ----------------------- WGL_ARB_make_current_read ----------------------- */
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+
+#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+
+#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB)
+#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB)
+
+#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read)
+
+#endif /* WGL_ARB_make_current_read */
+
+/* -------------------------- WGL_ARB_multisample -------------------------- */
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+
+#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample)
+
+#endif /* WGL_ARB_multisample */
+
+/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LOST_ARB 0x2036
+
+DECLARE_HANDLE(HPBUFFERARB);
+
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+
+#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB)
+#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB)
+#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB)
+#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB)
+#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB)
+
+#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer)
+
+#endif /* WGL_ARB_pbuffer */
+
+/* -------------------------- WGL_ARB_pixel_format ------------------------- */
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues);
+
+#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB)
+#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB)
+#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB)
+
+#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format)
+
+#endif /* WGL_ARB_pixel_format */
+
+/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+
+#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+
+#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float)
+
+#endif /* WGL_ARB_pixel_format_float */
+
+/* ------------------------- WGL_ARB_render_texture ------------------------ */
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+
+#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define WGL_TEXTURE_FORMAT_ARB 0x2072
+#define WGL_TEXTURE_TARGET_ARB 0x2073
+#define WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define WGL_TEXTURE_RGB_ARB 0x2075
+#define WGL_TEXTURE_RGBA_ARB 0x2076
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define WGL_TEXTURE_1D_ARB 0x2079
+#define WGL_TEXTURE_2D_ARB 0x207A
+#define WGL_MIPMAP_LEVEL_ARB 0x207B
+#define WGL_CUBE_MAP_FACE_ARB 0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB 0x2083
+#define WGL_FRONT_RIGHT_ARB 0x2084
+#define WGL_BACK_LEFT_ARB 0x2085
+#define WGL_BACK_RIGHT_ARB 0x2086
+#define WGL_AUX0_ARB 0x2087
+#define WGL_AUX1_ARB 0x2088
+#define WGL_AUX2_ARB 0x2089
+#define WGL_AUX3_ARB 0x208A
+#define WGL_AUX4_ARB 0x208B
+#define WGL_AUX5_ARB 0x208C
+#define WGL_AUX6_ARB 0x208D
+#define WGL_AUX7_ARB 0x208E
+#define WGL_AUX8_ARB 0x208F
+#define WGL_AUX9_ARB 0x2090
+
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList);
+
+#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB)
+#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB)
+#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB)
+
+#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture)
+
+#endif /* WGL_ARB_render_texture */
+
+/* ---------------- WGL_ARB_robustness_application_isolation --------------- */
+
+#ifndef WGL_ARB_robustness_application_isolation
+#define WGL_ARB_robustness_application_isolation 1
+
+#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define WGLEW_ARB_robustness_application_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_application_isolation)
+
+#endif /* WGL_ARB_robustness_application_isolation */
+
+/* ---------------- WGL_ARB_robustness_share_group_isolation --------------- */
+
+#ifndef WGL_ARB_robustness_share_group_isolation
+#define WGL_ARB_robustness_share_group_isolation 1
+
+#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define WGLEW_ARB_robustness_share_group_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_share_group_isolation)
+
+#endif /* WGL_ARB_robustness_share_group_isolation */
+
+/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+
+#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#define GL_RGBA_FLOAT_MODE_ATI 0x8820
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+
+#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float)
+
+#endif /* WGL_ATI_pixel_format_float */
+
+/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */
+
+#ifndef WGL_ATI_render_texture_rectangle
+#define WGL_ATI_render_texture_rectangle 1
+
+#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5
+
+#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle)
+
+#endif /* WGL_ATI_render_texture_rectangle */
+
+/* --------------------------- WGL_EXT_colorspace -------------------------- */
+
+#ifndef WGL_EXT_colorspace
+#define WGL_EXT_colorspace 1
+
+#define WGL_COLORSPACE_SRGB_EXT 0x3089
+#define WGL_COLORSPACE_LINEAR_EXT 0x308A
+#define WGL_COLORSPACE_EXT 0x309D
+
+#define WGLEW_EXT_colorspace WGLEW_GET_VAR(__WGLEW_EXT_colorspace)
+
+#endif /* WGL_EXT_colorspace */
+
+/* ------------------- WGL_EXT_create_context_es2_profile ------------------ */
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_EXT_create_context_es2_profile 1
+
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+
+#define WGLEW_EXT_create_context_es2_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es2_profile)
+
+#endif /* WGL_EXT_create_context_es2_profile */
+
+/* ------------------- WGL_EXT_create_context_es_profile ------------------- */
+
+#ifndef WGL_EXT_create_context_es_profile
+#define WGL_EXT_create_context_es_profile 1
+
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+
+#define WGLEW_EXT_create_context_es_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es_profile)
+
+#endif /* WGL_EXT_create_context_es_profile */
+
+/* -------------------------- WGL_EXT_depth_float -------------------------- */
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+
+#define WGL_DEPTH_FLOAT_EXT 0x2040
+
+#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float)
+
+#endif /* WGL_EXT_depth_float */
+
+/* ---------------------- WGL_EXT_display_color_table ---------------------- */
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length);
+
+#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT)
+#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT)
+#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT)
+#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT)
+
+#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table)
+
+#endif /* WGL_EXT_display_color_table */
+
+/* ----------------------- WGL_EXT_extensions_string ----------------------- */
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+
+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+
+#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT)
+
+#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string)
+
+#endif /* WGL_EXT_extensions_string */
+
+/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+
+#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB)
+
+#endif /* WGL_EXT_framebuffer_sRGB */
+
+/* ----------------------- WGL_EXT_make_current_read ----------------------- */
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+
+#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
+
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+
+#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT)
+#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT)
+
+#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read)
+
+#endif /* WGL_EXT_make_current_read */
+
+/* -------------------------- WGL_EXT_multisample -------------------------- */
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+
+#define WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define WGL_SAMPLES_EXT 0x2042
+
+#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample)
+
+#endif /* WGL_EXT_multisample */
+
+/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+
+#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT 0x2033
+#define WGL_PBUFFER_WIDTH_EXT 0x2034
+#define WGL_PBUFFER_HEIGHT_EXT 0x2035
+
+DECLARE_HANDLE(HPBUFFEREXT);
+
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+
+#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT)
+#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT)
+#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT)
+#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT)
+#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT)
+
+#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer)
+
+#endif /* WGL_EXT_pbuffer */
+
+/* -------------------------- WGL_EXT_pixel_format ------------------------- */
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues);
+
+#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT)
+#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT)
+#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT)
+
+#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format)
+
+#endif /* WGL_EXT_pixel_format */
+
+/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+
+#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float)
+
+#endif /* WGL_EXT_pixel_format_packed_float */
+
+/* -------------------------- WGL_EXT_swap_control ------------------------- */
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+
+#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT)
+#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT)
+
+#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control)
+
+#endif /* WGL_EXT_swap_control */
+
+/* ----------------------- WGL_EXT_swap_control_tear ----------------------- */
+
+#ifndef WGL_EXT_swap_control_tear
+#define WGL_EXT_swap_control_tear 1
+
+#define WGLEW_EXT_swap_control_tear WGLEW_GET_VAR(__WGLEW_EXT_swap_control_tear)
+
+#endif /* WGL_EXT_swap_control_tear */
+
+/* --------------------- WGL_I3D_digital_video_control --------------------- */
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue);
+
+#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D)
+#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D)
+
+#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control)
+
+#endif /* WGL_I3D_digital_video_control */
+
+/* ----------------------------- WGL_I3D_gamma ----------------------------- */
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+
+#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue);
+
+#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D)
+#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D)
+#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D)
+#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D)
+
+#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma)
+
+#endif /* WGL_I3D_gamma */
+
+/* ---------------------------- WGL_I3D_genlock ---------------------------- */
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay);
+
+#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D)
+#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D)
+#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D)
+#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D)
+#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D)
+#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D)
+#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D)
+#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D)
+#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D)
+#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D)
+#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D)
+#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D)
+
+#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock)
+
+#endif /* WGL_I3D_genlock */
+
+/* -------------------------- WGL_I3D_image_buffer ------------------------- */
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count);
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count);
+
+#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D)
+#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D)
+#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D)
+#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D)
+
+#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer)
+
+#endif /* WGL_I3D_image_buffer */
+
+/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag);
+
+#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D)
+#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D)
+#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D)
+#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D)
+
+#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock)
+
+#endif /* WGL_I3D_swap_frame_lock */
+
+/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+
+#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D)
+#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D)
+#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D)
+#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D)
+
+#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage)
+
+#endif /* WGL_I3D_swap_frame_usage */
+
+/* --------------------------- WGL_NV_DX_interop --------------------------- */
+
+#ifndef WGL_NV_DX_interop
+#define WGL_NV_DX_interop 1
+
+#define WGL_ACCESS_READ_ONLY_NV 0x0000
+#define WGL_ACCESS_READ_WRITE_NV 0x0001
+#define WGL_ACCESS_WRITE_DISCARD_NV 0x0002
+
+typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
+typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects);
+typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
+typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice);
+typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle);
+typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects);
+typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
+
+#define wglDXCloseDeviceNV WGLEW_GET_FUN(__wglewDXCloseDeviceNV)
+#define wglDXLockObjectsNV WGLEW_GET_FUN(__wglewDXLockObjectsNV)
+#define wglDXObjectAccessNV WGLEW_GET_FUN(__wglewDXObjectAccessNV)
+#define wglDXOpenDeviceNV WGLEW_GET_FUN(__wglewDXOpenDeviceNV)
+#define wglDXRegisterObjectNV WGLEW_GET_FUN(__wglewDXRegisterObjectNV)
+#define wglDXSetResourceShareHandleNV WGLEW_GET_FUN(__wglewDXSetResourceShareHandleNV)
+#define wglDXUnlockObjectsNV WGLEW_GET_FUN(__wglewDXUnlockObjectsNV)
+#define wglDXUnregisterObjectNV WGLEW_GET_FUN(__wglewDXUnregisterObjectNV)
+
+#define WGLEW_NV_DX_interop WGLEW_GET_VAR(__WGLEW_NV_DX_interop)
+
+#endif /* WGL_NV_DX_interop */
+
+/* --------------------------- WGL_NV_DX_interop2 -------------------------- */
+
+#ifndef WGL_NV_DX_interop2
+#define WGL_NV_DX_interop2 1
+
+#define WGLEW_NV_DX_interop2 WGLEW_GET_VAR(__WGLEW_NV_DX_interop2)
+
+#endif /* WGL_NV_DX_interop2 */
+
+/* --------------------------- WGL_NV_copy_image --------------------------- */
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define wglCopyImageSubDataNV WGLEW_GET_FUN(__wglewCopyImageSubDataNV)
+
+#define WGLEW_NV_copy_image WGLEW_GET_VAR(__WGLEW_NV_copy_image)
+
+#endif /* WGL_NV_copy_image */
+
+/* ------------------------ WGL_NV_delay_before_swap ----------------------- */
+
+#ifndef WGL_NV_delay_before_swap
+#define WGL_NV_delay_before_swap 1
+
+typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds);
+
+#define wglDelayBeforeSwapNV WGLEW_GET_FUN(__wglewDelayBeforeSwapNV)
+
+#define WGLEW_NV_delay_before_swap WGLEW_GET_VAR(__WGLEW_NV_delay_before_swap)
+
+#endif /* WGL_NV_delay_before_swap */
+
+/* -------------------------- WGL_NV_float_buffer -------------------------- */
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+
+#define WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+
+#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer)
+
+#endif /* WGL_NV_float_buffer */
+
+/* -------------------------- WGL_NV_gpu_affinity -------------------------- */
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_NV_gpu_affinity 1
+
+#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
+#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
+
+DECLARE_HANDLE(HGPUNV);
+typedef struct _GPU_DEVICE {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD Flags;
+ RECT rcVirtualScreen;
+} GPU_DEVICE, *PGPU_DEVICE;
+
+typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
+typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
+typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
+
+#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV)
+#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV)
+#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV)
+#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV)
+#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV)
+
+#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity)
+
+#endif /* WGL_NV_gpu_affinity */
+
+/* ---------------------- WGL_NV_multisample_coverage ---------------------- */
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_NV_multisample_coverage 1
+
+#define WGL_COVERAGE_SAMPLES_NV 0x2042
+#define WGL_COLOR_SAMPLES_NV 0x20B9
+
+#define WGLEW_NV_multisample_coverage WGLEW_GET_VAR(__WGLEW_NV_multisample_coverage)
+
+#endif /* WGL_NV_multisample_coverage */
+
+/* -------------------------- WGL_NV_present_video ------------------------- */
+
+#ifndef WGL_NV_present_video
+#define WGL_NV_present_video 1
+
+#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
+
+DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
+
+typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList);
+typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList);
+typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue);
+
+#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV)
+#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV)
+#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV)
+
+#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video)
+
+#endif /* WGL_NV_present_video */
+
+/* ---------------------- WGL_NV_render_depth_texture ---------------------- */
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_NV_render_depth_texture 1
+
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV 0x20A7
+
+#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture)
+
+#endif /* WGL_NV_render_depth_texture */
+
+/* -------------------- WGL_NV_render_texture_rectangle -------------------- */
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_NV_render_texture_rectangle 1
+
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
+
+#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle)
+
+#endif /* WGL_NV_render_texture_rectangle */
+
+/* --------------------------- WGL_NV_swap_group --------------------------- */
+
+#ifndef WGL_NV_swap_group
+#define WGL_NV_swap_group 1
+
+typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
+typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count);
+typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group, GLuint *barrier);
+typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
+
+#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV)
+#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV)
+#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV)
+#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV)
+#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV)
+#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV)
+
+#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group)
+
+#endif /* WGL_NV_swap_group */
+
+/* ----------------------- WGL_NV_vertex_array_range ----------------------- */
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+
+typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+
+#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV)
+#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV)
+
+#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range)
+
+#endif /* WGL_NV_vertex_array_range */
+
+/* -------------------------- WGL_NV_video_capture ------------------------- */
+
+#ifndef WGL_NV_video_capture
+#define WGL_NV_video_capture 1
+
+#define WGL_UNIQUE_ID_NV 0x20CE
+#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+
+DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
+
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV* phDeviceList);
+typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int* piValue);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+
+#define wglBindVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewBindVideoCaptureDeviceNV)
+#define wglEnumerateVideoCaptureDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoCaptureDevicesNV)
+#define wglLockVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewLockVideoCaptureDeviceNV)
+#define wglQueryVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewQueryVideoCaptureDeviceNV)
+#define wglReleaseVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoCaptureDeviceNV)
+
+#define WGLEW_NV_video_capture WGLEW_GET_VAR(__WGLEW_NV_video_capture)
+
+#endif /* WGL_NV_video_capture */
+
+/* -------------------------- WGL_NV_video_output -------------------------- */
+
+#ifndef WGL_NV_video_output
+#define WGL_NV_video_output 1
+
+#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
+#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
+#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
+#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
+#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
+#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define WGL_VIDEO_OUT_FRAME 0x20C8
+#define WGL_VIDEO_OUT_FIELD_1 0x20C9
+#define WGL_VIDEO_OUT_FIELD_2 0x20CA
+#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+
+DECLARE_HANDLE(HPVIDEODEV);
+
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock);
+
+#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV)
+#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV)
+#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV)
+#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV)
+#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV)
+#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV)
+
+#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output)
+
+#endif /* WGL_NV_video_output */
+
+/* -------------------------- WGL_OML_sync_control ------------------------- */
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator);
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc);
+
+#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML)
+#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML)
+#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML)
+#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML)
+#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML)
+#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML)
+
+#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control)
+
+#endif /* WGL_OML_sync_control */
+
+/* ------------------------------------------------------------------------- */
+
+#define WGLEW_FUN_EXPORT GLEW_FUN_EXPORT
+#define WGLEW_VAR_EXPORT GLEW_VAR_EXPORT
+
+WGLEW_FUN_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL;
+
+WGLEW_FUN_EXPORT PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD;
+WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD;
+WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD;
+WGLEW_FUN_EXPORT PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD;
+WGLEW_FUN_EXPORT PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD;
+WGLEW_FUN_EXPORT PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD;
+WGLEW_FUN_EXPORT PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD;
+WGLEW_FUN_EXPORT PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD;
+WGLEW_FUN_EXPORT PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB;
+WGLEW_FUN_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB;
+WGLEW_FUN_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB;
+WGLEW_FUN_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB;
+
+WGLEW_FUN_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB;
+
+WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB;
+
+WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB;
+WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB;
+WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB;
+WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB;
+WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB;
+WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB;
+
+WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB;
+
+WGLEW_FUN_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB;
+WGLEW_FUN_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB;
+WGLEW_FUN_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB;
+
+WGLEW_FUN_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT;
+WGLEW_FUN_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT;
+WGLEW_FUN_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT;
+WGLEW_FUN_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT;
+WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT;
+WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT;
+WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT;
+WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT;
+WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT;
+
+WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT;
+WGLEW_FUN_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D;
+WGLEW_FUN_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D;
+
+WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D;
+WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D;
+WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D;
+
+WGLEW_FUN_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D;
+WGLEW_FUN_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D;
+WGLEW_FUN_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D;
+WGLEW_FUN_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D;
+
+WGLEW_FUN_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D;
+WGLEW_FUN_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D;
+WGLEW_FUN_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D;
+WGLEW_FUN_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D;
+
+WGLEW_FUN_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D;
+WGLEW_FUN_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D;
+WGLEW_FUN_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D;
+WGLEW_FUN_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D;
+
+WGLEW_FUN_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D;
+WGLEW_FUN_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D;
+WGLEW_FUN_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D;
+WGLEW_FUN_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D;
+
+WGLEW_FUN_EXPORT PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV;
+WGLEW_FUN_EXPORT PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV;
+WGLEW_FUN_EXPORT PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV;
+WGLEW_FUN_EXPORT PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV;
+WGLEW_FUN_EXPORT PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV;
+WGLEW_FUN_EXPORT PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV;
+
+WGLEW_FUN_EXPORT PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV;
+
+WGLEW_FUN_EXPORT PFNWGLDELAYBEFORESWAPNVPROC __wglewDelayBeforeSwapNV;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV;
+WGLEW_FUN_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV;
+WGLEW_FUN_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV;
+WGLEW_FUN_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV;
+WGLEW_FUN_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV;
+WGLEW_FUN_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV;
+WGLEW_FUN_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV;
+
+WGLEW_FUN_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV;
+WGLEW_FUN_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV;
+WGLEW_FUN_EXPORT PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV;
+WGLEW_FUN_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV;
+WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV;
+WGLEW_FUN_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV;
+
+WGLEW_FUN_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML;
+WGLEW_FUN_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML;
+WGLEW_FUN_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML;
+WGLEW_FUN_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML;
+WGLEW_FUN_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML;
+WGLEW_FUN_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_3DFX_multisample;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_3DL_stereo_control;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_AMD_gpu_association;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_buffer_region;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_context_flush_control;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_no_error;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_profile;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_robustness;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_extensions_string;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_make_current_read;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_multisample;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pbuffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_render_texture;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_application_isolation;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_share_group_isolation;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_pixel_format_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_colorspace;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es2_profile;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es_profile;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_depth_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_display_color_table;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_extensions_string;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_make_current_read;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_multisample;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pbuffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control_tear;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_digital_video_control;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_gamma;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_genlock;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_image_buffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop2;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_copy_image;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_delay_before_swap;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_float_buffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_gpu_affinity;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_multisample_coverage;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_present_video;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_depth_texture;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_swap_group;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_vertex_array_range;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_capture;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_output;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_OML_sync_control;
+/* ------------------------------------------------------------------------- */
+
+GLEWAPI GLenum GLEWAPIENTRY wglewInit ();
+GLEWAPI GLboolean GLEWAPIENTRY wglewIsSupported (const char *name);
+
+#ifndef WGLEW_GET_VAR
+#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x)
+#endif
+
+#ifndef WGLEW_GET_FUN
+#define WGLEW_GET_FUN(x) x
+#endif
+
+GLEWAPI GLboolean GLEWAPIENTRY wglewGetExtension (const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef GLEWAPI
+
+#endif /* __wglew_h__ */
diff --git a/graphics/asymptote/GUI/CustMatTransform.py b/graphics/asymptote/GUI/CustMatTransform.py
new file mode 100644
index 0000000000..563907fc50
--- /dev/null
+++ b/graphics/asymptote/GUI/CustMatTransform.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+import numpy as np
+import xasy2asy as x2a
+from pyUIClass.custMatTransform import Ui_Dialog
+
+
+class CustMatTransform(Qw.QDialog):
+ def __init__(self):
+ super().__init__()
+ self.ui = Ui_Dialog()
+ self.ui.setupUi(self)
+
+ self.ui.btnAccept.clicked.connect(self.accept)
+ self.ui.btnCancel.clicked.connect(self.reject)
+ self.ui.btnReset.clicked.connect(self.resetDialog)
+
+ self.mainTransformation = Qg.QTransform()
+ self.mainTransformation.scale(1, -1)
+
+ self.matrixLineInputs = [
+ self.ui.lineMat00, self.ui.lineMat01, self.ui.lineMatTx,
+ self.ui.lineMat10, self.ui.lineMat11, self.ui.lineMatTy]
+
+ validator = Qg.QDoubleValidator()
+ for lineInput in self.matrixLineInputs:
+ lineInput.setValidator(validator)
+ lineInput.textChanged.connect(self.handleUpdateText)
+
+ def show(self):
+ super().show()
+ self.createCanvas()
+ self.updatePreview()
+
+ def createCanvas(self):
+ self.canvSize = self.ui.imgPreview.size()
+ self.previewPixmap = Qg.QPixmap(self.canvSize)
+ tx, ty = self.canvSize.width() / 2, self.canvSize.height() / 2
+ self.mainTransformation.translate(tx, -ty)
+
+ def handleUpdateText(self, text):
+ if str(text) not in {'.', '-', '.-', '-.'} and str(text):
+ self.updatePreview()
+ self.ui.btnAccept.setEnabled(True)
+ else:
+ self.previewPixmap.fill()
+ self.ui.imgPreview.setPixmap(self.previewPixmap)
+ self.ui.btnAccept.setEnabled(False)
+
+ def updatePreview(self):
+ self.previewPixmap.fill()
+ canvas = Qg.QPainter(self.previewPixmap)
+ if not canvas.isActive():
+ return
+ canvas.setTransform(self.mainTransformation)
+
+ canvas.save()
+ canvas.setPen(Qc.Qt.lightGray)
+ self.drawBasicGrid(canvas)
+ transform = x2a.asyTransform.fromNumpyMatrix(self.getTransformationMatrix())
+ canvTransform = transform.toQTransform()
+ canvas.setTransform(canvTransform, True)
+
+ canvas.setPen(Qc.Qt.black)
+
+ if canvTransform.isInvertible():
+ self.drawBasicGrid(canvas, False)
+
+ if canvTransform.determinant() <= 0:
+ canvas.setPen(Qc.Qt.red)
+
+ canvas.drawRect(Qc.QRect(Qc.QPoint(0, 0), Qc.QSize(20, 20)))
+
+ self.ui.imgPreview.setPixmap(self.previewPixmap)
+
+ def resetDialog(self):
+ self.ui.lineMatTx.setText('0')
+ self.ui.lineMatTx.setText('0')
+
+ self.ui.lineMat00.setText('1')
+ self.ui.lineMat01.setText('0')
+ self.ui.lineMat10.setText('0')
+ self.ui.lineMat11.setText('1')
+
+ def drawBasicGrid(self, canvas, grid=True):
+ canvas.drawLine(Qc.QLine(-9999, 0, 9999, 0))
+ canvas.drawLine(Qc.QLine(0, -9999, 0, 9999))
+
+ fromIter, toIter = -7, 7
+ gridSize = 20
+ if grid:
+ for iterIndex in range(fromIter, toIter + 1):
+ canvas.drawLine(Qc.QLine(-9999, iterIndex * gridSize, 9999, iterIndex * gridSize))
+ canvas.drawLine(Qc.QLine(iterIndex * gridSize, -9999, iterIndex * gridSize, 9999))
+
+ def getTransformationMatrix(self):
+ rawMatrixNum = [float(lineInput.text()) for lineInput in self.matrixLineInputs]
+ rawMatrixNum.extend([0, 0, 1])
+ return np.matrix(rawMatrixNum).reshape((3, 3))
diff --git a/graphics/asymptote/GUI/DebugFlags.py b/graphics/asymptote/GUI/DebugFlags.py
new file mode 100644
index 0000000000..8a7eb4b282
--- /dev/null
+++ b/graphics/asymptote/GUI/DebugFlags.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+keepFiles = False
+printFoutTranscript = False
+printDeconstTranscript = False
+forceRasterizationSVG = False
diff --git a/graphics/asymptote/GUI/GuidesManager.py b/graphics/asymptote/GUI/GuidesManager.py
new file mode 100644
index 0000000000..5467843377
--- /dev/null
+++ b/graphics/asymptote/GUI/GuidesManager.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+import numpy as np
+
+class Guide:
+ def __init__(self, pen=None):
+ if pen is None:
+ pen = Qg.QPen()
+ assert isinstance(pen, Qg.QPen)
+ self.pen = pen
+
+ def drawShape(self, pen):
+ assert isinstance(pen, Qg.QPainter)
+ pen.save()
+ pen.setPen(self.pen)
+
+class LineGuide(Guide):
+ def __init__(self, origin, direction, pen=None):
+ super().__init__(pen)
+ self.origin = origin
+ self.direction = direction
+
+ def drawShape(self, pen):
+ super().drawShape(pen)
+ p1 = self.origin + (9999 * Qc.QPointF(np.cos(self.direction), np.sin(self.direction)))
+ p2 = self.origin - (9999 * Qc.QPointF(np.cos(self.direction), np.sin(self.direction)))
+ pen.drawLine(Qc.QLineF(p1, p2))
+ pen.restore()
+
+class ArcGuide(Guide):
+ @classmethod
+ def radTo16Deg(cls, radians):
+ return int(round(np.rad2deg(radians) * 16))
+
+ def __init__(self, center=None, radius=1, startAng=0, endAng=(2*np.pi), pen=None):
+ if center is None:
+ center = Qc.QPointF(0, 0)
+ super().__init__(pen)
+ self.center = center
+ self.radius = int(radius)
+ self.startAng = startAng
+ self.endAng = endAng
+
+ def drawShape(self, pen):
+ super().drawShape(pen)
+ assert isinstance(pen, Qg.QPainter)
+ x, y = int(round(self.center.x())), int(round(self.center.y()))
+ pen.drawArc(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius, ArcGuide.radTo16Deg(self.startAng),
+ -ArcGuide.radTo16Deg(self.endAng - self.startAng))
+ pen.restore()
diff --git a/graphics/asymptote/GUI/InplaceAddObj.py b/graphics/asymptote/GUI/InplaceAddObj.py
new file mode 100644
index 0000000000..132969dad1
--- /dev/null
+++ b/graphics/asymptote/GUI/InplaceAddObj.py
@@ -0,0 +1,356 @@
+#!/usr/bin/env python3
+
+import PyQt5.QtCore as Qc
+import PyQt5.QtGui as Qg
+import xasy2asy as x2a
+
+import PrimitiveShape
+import math
+
+import Widg_addPolyOpt
+import Widg_addLabel
+
+
+class InplaceObjProcess(Qc.QObject):
+ objectCreated = Qc.pyqtSignal(Qc.QObject)
+ objectUpdated = Qc.pyqtSignal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._active = False
+ pass
+
+ @property
+ def active(self):
+ return self._active
+
+ def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ raise NotImplementedError
+
+ def mouseMove(self, pos, event: Qg.QMouseEvent):
+ raise NotImplementedError
+
+ def mouseRelease(self):
+ raise NotImplementedError
+
+ def forceFinalize(self):
+ raise NotImplementedError
+
+ def getPreview(self):
+ return None
+
+ def getObject(self):
+ raise NotImplementedError
+
+ def getXasyObject(self):
+ raise NotImplementedError
+
+ def postDrawPreview(self, canvas: Qg.QPainter):
+ pass
+
+ def createOptWidget(self, info):
+ return None
+
+
+class AddCircle(InplaceObjProcess):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.center = Qc.QPointF(0, 0)
+ self.radius = 0
+
+ def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.radius = 0
+ self.center.setX(x)
+ self.center.setY(y)
+ self.fill = info['fill']
+ self._active = True
+
+ def mouseMove(self, pos, event):
+ self.radius = PrimitiveShape.PrimitiveShape.euclideanNorm(pos, self.center)
+
+ def mouseRelease(self):
+ self.objectCreated.emit(self.getXasyObject())
+ self._active = False
+
+ def getPreview(self):
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.center)
+ boundRect = Qc.QRectF(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius)
+ # because the internal image is flipped...
+ newPath = Qg.QPainterPath()
+ newPath.addEllipse(boundRect)
+ # newPath.addRect(boundRect)
+ return newPath
+
+ def getObject(self):
+ return PrimitiveShape.PrimitiveShape.circle(self.center, self.radius)
+
+ def getXasyObject(self):
+ if self.fill:
+ newObj = x2a.xasyFilledShape(self.getObject(), None)
+ else:
+ newObj = x2a.xasyShape(self.getObject(), None)
+ return newObj
+
+ def forceFinalize(self):
+ self.mouseRelease()
+
+
+class AddLabel(InplaceObjProcess):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.alignMode = None
+ self.opt = None
+ self.text = None
+ self.anchor = Qc.QPointF(0, 0)
+ self._active = False
+
+ def createOptWidget(self, info):
+ self.opt = Widg_addLabel.Widg_addLabel(info)
+ return self.opt
+
+ def getPreview(self):
+ return None
+
+ def mouseRelease(self):
+ self.objectCreated.emit(self.getXasyObject())
+ self._active = False
+
+ def mouseMove(self, pos, event):
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.anchor.setX(x)
+ self.anchor.setY(y)
+
+ def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ if self.opt is not None:
+ self.text = self.opt.labelText
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.anchor.setX(x)
+ self.anchor.setY(y)
+
+ self.alignMode = info['align']
+ self.fontSize = info['fontSize']
+ self._active = True
+
+ def getObject(self):
+ finalTuple = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.anchor)
+ return {'txt': self.text, 'align': str(self.alignMode), 'anchor': finalTuple}
+
+ def getXasyObject(self):
+ text = self.text
+ align = str(self.alignMode)
+ anchor = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.anchor)
+ newLabel = x2a.xasyText(text=text, location=anchor, pen=None,
+ align=align, asyengine=None, fontsize=self.fontSize)
+ newLabel.asyfied = False
+ return newLabel
+
+ def forceFinalize(self):
+ self.mouseRelease()
+
+
+class AddBezierShape(InplaceObjProcess):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.asyengine = None
+ self.basePath = None
+ self.basePathPreview = None
+ self.closedPath = None
+ self.info = None
+ self.fill = False
+ self.opt = None
+
+ # list of "committed" points with Linkage information.
+ # Linkmode should be to the last point.
+ # (x, y, linkmode), (u, v, lm2) <==> (x, y) <=lm2=> (u, v)
+ self.pointsList = []
+ self.currentPoint = Qc.QPointF(0, 0)
+ self.pendingPoint = None
+ self.useLegacy = False
+
+ def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.currentPoint.setX(x)
+ self.currentPoint.setY(y)
+ self.info = info
+
+ if not self._active:
+ self._active = True
+ self.fill = info['fill']
+ self.asyengine = info['asyengine']
+ self.closedPath = info['closedPath']
+ self.useBezierBase = info['useBezier']
+ self.useLegacy = self.info['options']['useLegacyDrawMode']
+ self.pointsList.clear()
+ self.pointsList.append((x, y, None))
+ else:
+ # see http://doc.qt.io/archives/qt-4.8/qt.html#MouseButton-enum
+ if (int(mouseEvent.buttons()) if mouseEvent is not None else 0) & 0x2 and self.useLegacy:
+ self.forceFinalize()
+
+ def _getLinkType(self):
+ if self.info['useBezier']:
+ return '..'
+ else:
+ return '--'
+
+ def mouseMove(self, pos, event):
+ # in postscript coords.
+ if self._active:
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+
+ if self.useLegacy or int(event.buttons()) != 0:
+ self.currentPoint.setX(x)
+ self.currentPoint.setY(y)
+ else:
+ self.forceFinalize()
+
+
+ def createOptWidget(self, info):
+ return None
+ # self.opt = Widg_addBezierInPlace.Widg_addBezierInplace(info)
+ # return self.opt
+
+ def finalizeClosure(self):
+ if self.active:
+ self.closedPath = True
+ self.forceFinalize()
+
+ def mouseRelease(self):
+ x, y = self.currentPoint.x(), self.currentPoint.y()
+ self.pointsList.append((x, y, self._getLinkType()))
+ # self.updateBasePath()
+
+ def updateBasePath(self):
+ self.basePath = x2a.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ newNode = [(x, y) for x, y, _ in self.pointsList]
+ newLink = [lnk for *args, lnk in self.pointsList[1:]]
+ if self.useLegacy:
+ newNode += [(self.currentPoint.x(), self.currentPoint.y())]
+ newLink += [self._getLinkType()]
+ if self.closedPath:
+ newNode.append('cycle')
+ newLink.append(self._getLinkType())
+ self.basePath.initFromNodeList(newNode, newLink)
+
+ if self.useBezierBase:
+ self.basePath.computeControls()
+
+ def updateBasePathPreview(self):
+ self.basePathPreview = x2a.asyPath(
+ asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ newNode = [(x, y) for x, y, _ in self.pointsList] + [(self.currentPoint.x(), self.currentPoint.y())]
+ newLink = [lnk for *args, lnk in self.pointsList[1:]] + [self._getLinkType()]
+ if self.closedPath:
+ newNode.append('cycle')
+ newLink.append(self._getLinkType())
+ self.basePathPreview.initFromNodeList(newNode, newLink)
+
+ if self.useBezierBase:
+ self.basePathPreview.computeControls()
+
+ def forceFinalize(self):
+ self.updateBasePath()
+ self._active = False
+ self.pointsList.clear()
+ self.objectCreated.emit(self.getXasyObject())
+ self.basePath = None
+
+ def getObject(self):
+ if self.basePath is None:
+ raise RuntimeError('BasePath is None')
+ self.basePath.asyengine = self.asyengine
+ return self.basePath
+
+ def getPreview(self):
+ if self._active:
+ if self.pointsList:
+ self.updateBasePathPreview()
+ newPath = self.basePathPreview.toQPainterPath()
+ return newPath
+
+ def getXasyObject(self):
+ if self.fill:
+ return x2a.xasyFilledShape(self.getObject(), None)
+ else:
+ return x2a.xasyShape(self.getObject(), None)
+
+
+class AddPoly(InplaceObjProcess):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.center = Qc.QPointF(0, 0)
+ self.currPos = Qc.QPointF(0, 0)
+ self.sides = None
+ self.inscribed = None
+ self.centermode = None
+ self.asyengine = None
+ self.fill = None
+ self.opt = None
+
+ def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ self._active = True
+ self.sides = info['sides']
+ self.inscribed = info['inscribed']
+ self.centermode = info['centermode']
+ self.fill = info['fill']
+
+
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.center.setX(x)
+ self.center.setY(y)
+ self.currPos = Qc.QPointF(self.center)
+
+ def mouseMove(self, pos, event):
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.currPos.setX(x)
+ self.currPos.setY(y)
+
+ def mouseRelease(self):
+ if self.active:
+ self.objectCreated.emit(self.getXasyObject())
+ self._active = False
+
+ def forceFinalize(self):
+ self.mouseRelease()
+
+ def getObject(self):
+ if self.inscribed:
+ return PrimitiveShape.PrimitiveShape.inscribedRegPolygon(self.sides, self.center, self._rad(),
+ self._angle())
+ else:
+ return PrimitiveShape.PrimitiveShape.exscribedRegPolygon(self.sides, self.center, self._rad(),
+ self._angle())
+
+ def getPreview(self):
+ if self.inscribed:
+ poly = PrimitiveShape.PrimitiveShape.inscribedRegPolygon(self.sides, self.center, self._rad(),
+ self._angle(), qpoly=True)
+ else:
+ poly = PrimitiveShape.PrimitiveShape.exscribedRegPolygon(self.sides, self.center, self._rad(),
+ self._angle(), qpoly=True)
+ newPath = Qg.QPainterPath()
+ newPath.addPolygon(poly)
+ return newPath
+
+ def createOptWidget(self, info):
+ self.opt = Widg_addPolyOpt.Widg_addPolyOpt(info)
+ return self.opt
+
+ def _rad(self):
+ return PrimitiveShape.PrimitiveShape.euclideanNorm(self.currPos, self.center)
+
+ def _angle(self):
+ dist_x = self.currPos.x() - self.center.x()
+ dist_y = self.currPos.y() - self.center.y()
+ if dist_x == 0 and dist_y == 0:
+ return 0
+ else:
+ return math.atan2(dist_y, dist_x)
+
+ def getXasyObject(self):
+ if self.fill:
+ newObj = x2a.xasyFilledShape(self.getObject(), None)
+ else:
+ newObj = x2a.xasyShape(self.getObject(), None)
+ return newObj
diff --git a/graphics/asymptote/GUI/PrimitiveShape.py b/graphics/asymptote/GUI/PrimitiveShape.py
new file mode 100644
index 0000000000..c75e014079
--- /dev/null
+++ b/graphics/asymptote/GUI/PrimitiveShape.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+import xasy2asy as x2a
+import numpy as np
+import math
+import PyQt5.QtCore as Qc
+import PyQt5.QtGui as Qg
+
+
+class PrimitiveShape:
+ # The magic number.
+ # see https://www.desmos.com/calculator/lw6j7khikj for unitcircle
+ # optimal_ctl_pt = 0.5447
+
+ @staticmethod
+ def pos_to_tuple(pos):
+ if isinstance(pos, tuple) or isinstance(pos, np.ndarray):
+ return pos
+ elif isinstance(pos, Qc.QPoint) or isinstance(pos, Qc.QPointF):
+ return pos.x(), pos.y()
+ else:
+ raise TypeError("Position must be a valid type!")
+
+ @staticmethod
+ def euclideanNorm(p1, p2):
+ x1, y1 = PrimitiveShape.pos_to_tuple(p1)
+ x2, y2 = PrimitiveShape.pos_to_tuple(p2)
+
+ normSq = ((x1 - x2) ** 2) + ((y1 - y2) ** 2)
+ return math.sqrt(normSq)
+
+ @classmethod
+ def circle(cls, position, radius):
+ pos_x, pos_y = PrimitiveShape.pos_to_tuple(position)
+ newCircle = x2a.asyPath()
+ ptsList = [(pos_x + radius, pos_y), (pos_x, pos_y + radius), (pos_x - radius, pos_y), (pos_x, pos_y - radius),
+ 'cycle']
+ # cycle doesn't work for now.
+ lkList = ['..', '..', '..', '..']
+ newCircle.initFromNodeList(ptsList, lkList)
+ return newCircle
+
+ @classmethod
+ def inscribedRegPolygon(cls, sides, position, radius, starting_rad, qpoly=False):
+ pos_x, pos_y = PrimitiveShape.pos_to_tuple(position)
+ lkList = ['--'] * sides
+ ptsList = []
+ for ang in np.linspace(starting_rad, starting_rad + math.tau, sides, endpoint=False):
+ ptsList.append((pos_x + radius * math.cos(ang), pos_y + radius * math.sin(ang)))
+
+ if qpoly:
+ ptsList.append((pos_x + radius * math.cos(starting_rad), pos_y + radius * math.sin(starting_rad)))
+ qpoints = [Qc.QPointF(x, y) for (x, y) in ptsList]
+ return Qg.QPolygonF(qpoints)
+ else:
+ ptsList.append('cycle')
+ newPoly = x2a.asyPath()
+ newPoly.initFromNodeList(ptsList, lkList)
+ return newPoly
+
+ @classmethod
+ def exscribedRegPolygon(cls, sides, position, length, starting_rad, qpoly=False):
+ ang = math.tau/sides
+ # see notes
+ adjusted_radius = length / math.cos(ang/2)
+ return cls.inscribedRegPolygon(sides, position, adjusted_radius, starting_rad - ang/2, qpoly)
diff --git a/graphics/asymptote/GUI/SetCustomAnchor.py b/graphics/asymptote/GUI/SetCustomAnchor.py
new file mode 100644
index 0000000000..ad5925cddb
--- /dev/null
+++ b/graphics/asymptote/GUI/SetCustomAnchor.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+from pyUIClass.setCustomAnchor import Ui_Dialog
+
+
+class CustomAnchorDialog(Qw.QDialog):
+
+ def __init__(self):
+ super().__init__()
+ self.ui = Ui_Dialog()
+ self.ui.setupUi(self)
+ self.ui.buttonBox.button(Qw.QDialogButtonBox.Reset).clicked.connect(self.resetDialog)
+
+ validator = Qg.QDoubleValidator()
+
+ self.ui.lineEditX.setValidator(validator)
+ self.ui.lineEditY.setValidator(validator)
+
+ self.ui.lineEditX.textChanged.connect(self.checkTextChanged)
+ self.ui.lineEditY.textChanged.connect(self.checkTextChanged)
+
+ def checkTextChanged(self, text):
+ if str(text) not in {'.', '-', '.-', '-.'} and str(text):
+ self.ui.buttonBox.button(Qw.QDialogButtonBox.Ok).setEnabled(True)
+ else:
+ self.ui.buttonBox.button(Qw.QDialogButtonBox.Ok).setEnabled(False)
+
+ def getPoint(self):
+ xPoint = float(self.ui.lineEditX.text())
+ yPoint = float(self.ui.lineEditY.text())
+
+ return Qc.QPointF(xPoint, yPoint)
+
+ def handleBtnBoxClick(self, button):
+ assert isinstance(button, Qw.QAbstractButton)
+ if button.text() == 'Reset':
+ self.resetDialog()
+
+ def resetDialog(self):
+ self.ui.lineEditX.setText('0')
+ self.ui.lineEditY.setText('0')
diff --git a/graphics/asymptote/GUI/UndoRedoStack.py b/graphics/asymptote/GUI/UndoRedoStack.py
new file mode 100755
index 0000000000..7285b15ff2
--- /dev/null
+++ b/graphics/asymptote/GUI/UndoRedoStack.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+###########################################################################
+#
+# UndoRedoStack implements the usual undo/redo capabilities of a GUI
+#
+# Author: Orest Shardt
+# Created: July 23, 2007
+#
+###########################################################################
+
+
+class action:
+ def __init__(self, actions):
+ act, inv = actions
+ self.act = act
+ self.inv = inv
+
+ def undo(self):
+ # print ("Undo:",self)
+ self.inv()
+
+ def redo(self):
+ # print ("Redo:",self)
+ self.act()
+
+ def __str__(self):
+ return "A generic action"
+
+
+class beginActionGroup:
+ pass
+
+
+class endActionGroup:
+ pass
+
+
+class actionStack:
+ def __init__(self):
+ self.clear()
+
+ def add(self, action):
+ self.undoStack.append(action)
+ # print ("Added",action)
+ self.redoStack = []
+
+ def undo(self):
+ if len(self.undoStack) > 0:
+ op = self.undoStack.pop()
+ if op is beginActionGroup:
+ level = 1
+ self.redoStack.append(endActionGroup)
+ while level > 0:
+ op = self.undoStack.pop()
+ if op is endActionGroup:
+ level -= 1
+ self.redoStack.append(beginActionGroup)
+ elif op is beginActionGroup:
+ level += 1
+ self.redoStack.append(endActionGroup)
+ else:
+ op.undo()
+ self.redoStack.append(op)
+ elif op is endActionGroup:
+ raise Exception("endActionGroup without previous beginActionGroup")
+ else:
+ self.redoStack.append(op)
+ op.undo()
+ # print ("undid",op)
+ else:
+ pass # print ("nothing to undo")
+
+ def redo(self):
+ if len(self.redoStack) > 0:
+ op = self.redoStack.pop()
+ if op is beginActionGroup:
+ level = 1
+ self.undoStack.append(endActionGroup)
+ while level > 0:
+ op = self.redoStack.pop()
+ if op is endActionGroup:
+ level -= 1
+ self.undoStack.append(beginActionGroup)
+ elif op is beginActionGroup:
+ level += 1
+ self.undoStack.append(endActionGroup)
+ else:
+ op.redo()
+ self.undoStack.append(op)
+ elif op is endActionGroup:
+ raise Exception("endActionGroup without previous beginActionGroup")
+ else:
+ self.undoStack.append(op)
+ op.redo()
+ # print ("redid",op)
+ else:
+ pass # print ("nothing to redo")
+
+ def setCommitLevel(self):
+ self.commitLevel = len(self.undoStack)
+
+ def changesMade(self):
+ if len(self.undoStack) != self.commitLevel:
+ return True
+ else:
+ return False
+
+ def clear(self):
+ self.redoStack = []
+ self.undoStack = []
+ self.commitLevel = 0
+
+
+if __name__ == '__main__':
+ import sys
+
+
+ def opq():
+ print("action1")
+
+
+ def unopq():
+ print("inverse1")
+
+
+ q = action(opq, unopq)
+ w = action(lambda: sys.stdout.write("action2\n"), lambda: sys.stdout.write("inverse2\n"))
+ e = action(lambda: sys.stdout.write("action3\n"), lambda: sys.stdout.write("inverse3\n"))
+ s = actionStack()
+ s.add(q)
+ s.add(w)
+ s.add(e)
diff --git a/graphics/asymptote/GUI/Widg_addLabel.py b/graphics/asymptote/GUI/Widg_addLabel.py
new file mode 100644
index 0000000000..776d3e02df
--- /dev/null
+++ b/graphics/asymptote/GUI/Widg_addLabel.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python3
+
+from pyUIClass.widg_addLabel import Ui_Form
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+
+import labelEditor
+import xasyUtils as xu
+
+
+class Widg_addLabel(Qw.QWidget):
+ def __init__(self, info):
+ super().__init__()
+ self.ui = Ui_Form()
+ self.info = info
+ self.ui.setupUi(self)
+ self.setFixedSize(self.size())
+
+ if 'alignIndex' not in self.info.keys():
+ self.info['alignIndex'] = 0
+
+ if 'shift_x' not in self.info.keys():
+ self.info['shift_x'] = None
+
+ if 'shift_y' not in self.info.keys():
+ self.info['shift_y'] = None
+
+ if 'align' not in self.info.keys():
+ self.info['align'] = (0, 0)
+
+ if self.info['shift_x'] is not None:
+ self.ui.txtShiftX.setText(str(self.info['shift_x']))
+
+ if self.info['shift_y'] is not None:
+ self.ui.txtShiftY.setText(str(self.info['shift_y']))
+
+
+ self.ui.cmbFontSize.setCurrentText(str(self.info['fontSize']) if self.info['fontSize'] is not None else '-')
+ self.ui.cmbAlign.setCurrentIndex(self.info['alignIndex'])
+
+ validator = Qg.QDoubleValidator()
+
+ self.ui.txtShiftX.setValidator(validator)
+ self.ui.txtShiftY.setValidator(validator)
+ self.ui.cmbFontSize.setValidator(validator)
+
+ self.ui.cmbAlign.currentTextChanged.connect(self.updateCheck)
+ self.ui.cmbAlign.currentIndexChanged.connect(self.cmbIndexUpdate)
+ self.ui.txtShiftX.textEdited.connect(self.shftXUpdate)
+ self.ui.txtShiftY.textEdited.connect(self.shftYUpdate)
+ self.ui.btnAdvancedEdit.clicked.connect(self.btnAdvancedEditClicked)
+ self.ui.cmbFontSize.currentTextChanged.connect(self.cmbFontSizeTextChanged)
+
+ self.updateCheck(self.ui.cmbAlign.currentText())
+
+ def cmbFontSizeTextChanged(self, text: str):
+ tryParseVal = xu.tryParse(text, float)
+ self.info['fontSize'] = tryParseVal
+
+ def btnAdvancedEditClicked(self):
+ advancedEditDialog = labelEditor.labelEditor(self.ui.txtLabelText.text())
+ advancedEditDialog.show()
+ result = advancedEditDialog.exec_()
+ if result == Qw.QDialog.Accepted:
+ self.ui.txtLabelText.setText(advancedEditDialog.getText())
+
+ @property
+ def labelText(self):
+ return self.ui.txtLabelText.text()
+
+ def updateCheck(self, a0):
+ self.ui.txtShiftX.setEnabled(a0 == 'Custom')
+ self.ui.txtShiftY.setEnabled(a0 == 'Custom')
+
+ def shftXUpdate(self, text):
+ if text:
+ self.info['shift_x'] = float(text)
+ self.updateAlign()
+
+ def shftYUpdate(self, text):
+ if text:
+ self.info['shift_y'] = float(text)
+ self.updateAlign()
+
+ def updateAlign(self):
+ index = self.ui.cmbAlign.currentIndex()
+ self.info['alignIndex'] = index
+ if self.ui.cmbAlign.currentText() == 'Custom':
+ self.info['align'] = (self.info['shift_x'], self.info['shift_y'])
+ elif self.ui.cmbAlign.currentText() == 'None':
+ self.info['align'] = (0, 0)
+ else:
+ self.info['align'] = self.ui.cmbAlign.currentText()
+
+ def cmbIndexUpdate(self, index):
+ self.updateAlign()
diff --git a/graphics/asymptote/GUI/Widg_addPolyOpt.py b/graphics/asymptote/GUI/Widg_addPolyOpt.py
new file mode 100644
index 0000000000..b9b9a77f7a
--- /dev/null
+++ b/graphics/asymptote/GUI/Widg_addPolyOpt.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+
+from pyUIClass.widg_addPolyOpt import Ui_Form
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+
+import sys
+
+
+class Widg_addPolyOpt(Qw.QWidget):
+ def __init__(self, info):
+ super().__init__()
+ self.ui = Ui_Form()
+ self.info = info
+ self.ui.setupUi(self)
+ self.setFixedSize(self.size())
+
+ self.ui.chkInscribed.setChecked(self.info['inscribed'])
+ self.ui.txtSides.setText(str(self.info['sides']))
+ self.ui.txtSides.setValidator(Qg.QIntValidator())
+
+ self.ui.chkInscribed.stateChanged.connect(self.chkInscribedUpdate)
+ self.ui.txtSides.textChanged.connect(self.txtSidesUpdate)
+
+ def chkInscribedUpdate(self, checked):
+ self.info['inscribed'] = checked
+
+ def txtSidesUpdate(self, text):
+ if text:
+ self.info['sides'] = int(text)
diff --git a/graphics/asymptote/GUI/Widg_editBezier.py b/graphics/asymptote/GUI/Widg_editBezier.py
new file mode 100644
index 0000000000..3a3cbab94a
--- /dev/null
+++ b/graphics/asymptote/GUI/Widg_editBezier.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+
+from pyUIClass.widg_editBezier import Ui_Form
+
+import PyQt5.QtCore as Qc
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+
+class LockMode:
+ noLock = 0
+ angleLock = 1
+ angleAndScaleLock = 2
+
+class Widg_editBezier(Qw.QWidget):
+ def __init__(self, info: dict, enableCurveFeatures: bool=True):
+ super().__init__()
+ self.ui = Ui_Form()
+ self.ui.setupUi(self)
+ self.info = info
+
+ self.ui.chkRecompute.setChecked(self.info['autoRecompute'])
+ self.ui.cmbLockMode.setCurrentIndex(self.info['editBezierlockMode'])
+
+ self.ui.cmbLockMode.currentIndexChanged[int].connect(self.cmbLockIndexChange)
+ self.ui.chkRecompute.stateChanged.connect(self.chkRecomputeChanged)
+
+ self.disableOnAutoRecompute = {self.ui.cmbLockMode, self.ui.btnForceRecompute}
+ self.curveBtnsOnly = {self.ui.cmbLockMode, self.ui.btnForceRecompute, self.ui.chkRecompute}
+
+ for elem in self.curveBtnsOnly:
+ elem.setEnabled(enableCurveFeatures)
+
+ @property
+ def autoRecompute(self) -> bool:
+ return self.ui.chkRecompute.isChecked()
+
+ @property
+ def lockMode(self) -> int:
+ return self.ui.cmbLockMode.currentIndex()
+
+ @Qc.pyqtSlot(int)
+ def cmbLockIndexChange(self, index: int):
+ self.info['editBezierlockMode'] = index
+
+ @Qc.pyqtSlot(int)
+ def chkRecomputeChanged(self, checked: int):
+ isChecked = (checked == 2)
+ for obj in self.disableOnAutoRecompute:
+ obj.setEnabled(not checked)
+ self.info['autoRecompute'] = checked
+
+ if isChecked:
+ self.ui.btnForceRecompute.clicked.emit()
diff --git a/graphics/asymptote/GUI/Window1.py b/graphics/asymptote/GUI/Window1.py
new file mode 100644
index 0000000000..7fda2bfc35
--- /dev/null
+++ b/graphics/asymptote/GUI/Window1.py
@@ -0,0 +1,1900 @@
+#!/usr/bin/env python3
+
+from pyUIClass.window1 import Ui_MainWindow
+
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+import xasyVersion
+
+import numpy as np
+import os
+import json
+import io
+import pathlib
+import webbrowser
+import subprocess
+import tempfile
+import datetime
+import string
+import atexit
+
+import xasyUtils as xu
+import xasy2asy as x2a
+import xasyFile as xf
+import xasyOptions as xo
+import UndoRedoStack as Urs
+import xasyArgs as xa
+import xasyBezierInterface as xbi
+from xasyTransform import xasyTransform as xT
+import xasyStrings as xs
+
+import PrimitiveShape
+import InplaceAddObj
+
+import CustMatTransform
+import SetCustomAnchor
+import GuidesManager
+
+
+class ActionChanges:
+ pass
+
+
+# State Invariance: When ActionChanges is at the top, all state of the program & file
+# is exactly like what it was the event right after that ActionChanges was created.
+
+class TransformationChanges(ActionChanges):
+ def __init__(self, objIndex, transformation, isLocal=False):
+ self.objIndex = objIndex
+ self.transformation = transformation
+ self.isLocal = isLocal
+
+
+class ObjCreationChanges(ActionChanges):
+ def __init__(self, obj):
+ self.object = obj
+
+class HardDeletionChanges(ActionChanges):
+ def __init__(self, obj, pos):
+ self.item = obj
+ self.objIndex = pos
+
+class AnchorMode:
+ origin = 0
+ center = 1
+ topLeft = 2
+ topRight = 3
+ bottomRight = 4
+ bottomLeft = 5
+ customAnchor = 6
+
+
+class GridMode:
+ cartesian = 0
+ polar = 1
+
+
+class SelectionMode:
+ select = 0
+ pan = 1
+ translate = 2
+ rotate = 3
+ scale = 4
+ delete = 5
+ setAnchor = 6
+ selectEdit = 7
+
+class AddObjectMode:
+ Circle = 0
+ Arc = 1
+ Polygon = 2
+
+class MainWindow1(Qw.QMainWindow):
+ defaultFrameStyle = """
+ QFrame{{
+ padding: 4.0;
+ border-radius: 3.0;
+ background: rgb({0}, {1}, {2})
+ }}
+ """
+
+ def __init__(self):
+ super().__init__()
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+ self.ui.menubar.setNativeMenuBar(False)
+
+ self.settings = xo.BasicConfigs.defaultOpt
+ self.keyMaps = xo.BasicConfigs.keymaps
+
+ self.raw_args = Qc.QCoreApplication.arguments()
+ self.args = xa.parseArgs(self.raw_args)
+
+ self.strings = xs.xasyString(self.args.language)
+ self.asy2psmap = x2a.identity()
+
+ if self.settings['asyBaseLocation'] is not None:
+ os.environ['ASYMPTOTE_DIR'] = self.settings['asyBaseLocation']
+
+ if self.args.asypath is not None:
+ asyPath = self.args.asypath
+ else:
+ asyPath = self.settings['asyPath']
+
+ self.asyPath = asyPath
+ self.asyEngine = x2a.AsymptoteEngine(self.asyPath)
+
+ try:
+ self.asyEngine.start()
+ finally:
+ atexit.register(self.asyEngine.cleanup)
+
+ # For initialization purposes
+ self.canvSize = Qc.QSize()
+ self.filename = None
+ self.currDir = None
+ self.mainCanvas = None
+ self.dpi = 300
+ self.canvasPixmap = None
+
+ # Actions
+ # <editor-fold> Connecting Actions
+ self.ui.txtLineWidth.setValidator(Qg.QDoubleValidator())
+
+ self.connectActions()
+ self.connectButtons()
+
+ self.ui.txtLineWidth.returnPressed.connect(self.btnTerminalCommandOnClick)
+ # </editor-fold>
+
+ # Base Transformations
+
+ self.mainTransformation = Qg.QTransform()
+ self.mainTransformation.scale(1, 1)
+ self.localTransform = Qg.QTransform()
+ self.screenTransformation = Qg.QTransform()
+ self.panTranslation = Qg.QTransform()
+
+ # Internal Settings
+ self.magnification = self.args.mag
+ self.inMidTransformation = False
+ self.addMode = None
+ self.currentlySelectedObj = {'key': None, 'allSameKey': set(), 'selectedIndex': None, 'keyIndex': None}
+ self.pendingSelectedObjList = []
+ self.pendingSelectedObjIndex = -1
+
+ self.savedMousePosition = None
+ self.currentBoundingBox = None
+ self.selectionDelta = None
+ self.newTransform = None
+ self.origBboxTransform = None
+ self.deltaAngle = 0
+ self.scaleFactor = 1
+ self.panOffset = [0, 0]
+
+ super().setMouseTracking(True)
+ # setMouseTracking(True)
+
+ self.undoRedoStack = Urs.actionStack()
+
+ self.lockX = False
+ self.lockY = False
+ self.anchorMode = AnchorMode.center
+ self.currentAnchor = Qc.QPointF(0, 0)
+ self.customAnchor = None
+ self.useGlobalCoords = True
+ self.drawAxes = True
+ self.drawGrid = False
+ self.gridSnap = False # TODO: for now. turn it on later
+
+ self.fileChanged = False
+
+ self.terminalPythonMode = self.ui.btnTogglePython.isChecked()
+
+ self.savedWindowMousePos = None
+
+ self.finalPixmap = None
+ self.preCanvasPixmap = None
+ self.postCanvasPixmap = None
+ self.previewCurve = None
+ self.mouseDown = False
+
+ self.globalObjectCounter = 0
+
+ self.fileItems = []
+ self.drawObjects = []
+ self.xasyDrawObj = {'drawDict': self.drawObjects}
+
+ self.modeButtons = {
+ self.ui.btnTranslate, self.ui.btnRotate, self.ui.btnScale, # self.ui.btnSelect,
+ self.ui.btnPan, self.ui.btnDeleteMode, self.ui.btnAnchor,
+ self.ui.btnSelectEdit
+ }
+
+ self.objButtons = {self.ui.btnCustTransform, self.ui.actionTransform, self.ui.btnSendForwards,
+ self.ui.btnSendBackwards, self.ui.btnToggleVisible
+ }
+
+ self.globalTransformOnlyButtons = (self.ui.comboAnchor, self.ui.btnAnchor)
+
+ self.ui.txtTerminalPrompt.setFont(Qg.QFont(self.settings['terminalFont']))
+
+ self.currAddOptionsWgt = None
+ self.currAddOptions = {
+ 'options': self.settings,
+ 'inscribed': True,
+ 'sides': 3,
+ 'centermode': True,
+ 'fontSize': None,
+ 'asyengine': self.asyEngine,
+ 'fill': self.ui.btnFill.isChecked(),
+ 'closedPath': False,
+ 'useBezier': True,
+ 'magnification': self.magnification,
+ 'editBezierlockMode': xbi.Web.LockMode.angleLock,
+ 'autoRecompute': False
+ }
+
+
+ self.currentModeStack = [SelectionMode.translate]
+ self.drawGridMode = GridMode.cartesian
+ self.setAllInSetEnabled(self.objButtons, False)
+ self._currentPen = x2a.asyPen()
+ self.currentGuides = []
+ self.selectAsGroup = self.settings['groupObjDefault']
+
+ # commands switchboard
+ self.commandsFunc = {
+ 'quit': Qc.QCoreApplication.quit,
+ 'undo': self.btnUndoOnClick,
+ 'redo': self.btnRedoOnClick,
+ 'manual': self.actionManual,
+ 'about': self.actionAbout,
+ 'loadFile': self.btnLoadFileonClick,
+ 'save': self.actionSave,
+ 'saveAs': self.actionSaveAs,
+ 'transform': self.btnCustTransformOnClick,
+ 'commandPalette': self.enterCustomCommand,
+ 'clearGuide': self.clearGuides,
+ 'finalizeAddObj': self.finalizeAddObj,
+ 'finalizeCurve': self.finalizeCurve,
+ 'finalizeCurveClosed': self.finalizeCurveClosed,
+ 'setMag': self.setMagPrompt,
+ 'deleteObject': self.btnSelectiveDeleteOnClick,
+ 'anchorMode': self.switchToAnchorMode,
+ 'moveUp': lambda: self.arrowButtons(0, 1, False),
+ 'moveDown': lambda: self.arrowButtons(0, -1, False),
+
+ 'scrollLeft': lambda: self.arrowButtons(-1, 0, True),
+ 'scrollRight': lambda: self.arrowButtons(1, 0, True),
+ 'scrollUp': lambda: self.arrowButtons(0, 1, True),
+ 'scrollDown': lambda: self.arrowButtons(0, -1, True),
+
+ 'zoomIn': lambda: self.arrowButtons(0, 1, False, True),
+ 'zoomOut': lambda: self.arrowButtons(0, -1, False, True)
+ }
+
+ self.hiddenKeys = set()
+
+ # Coordinates Label
+
+ self.coordLabel = Qw.QLabel(self.ui.statusbar)
+ self.ui.statusbar.addPermanentWidget(self.coordLabel)
+
+ # Settings Initialization
+ # from xasyoptions config file
+ self.loadKeyMaps()
+ self.setupXasyOptions()
+
+ self.colorDialog = Qw.QColorDialog(x2a.asyPen.convertToQColor(self._currentPen.color), self)
+ self.initPenInterface()
+
+ def arrowButtons(self, x:int , y:int, shift: bool=False, ctrl: bool=False):
+ "x, y indicates update button orientation on the cartesian plane."
+ if not (shift or ctrl):
+ self.changeSelection(y)
+ elif not (shift and ctrl):
+ self.mouseWheel(30*x, 30*y)
+ self.quickUpdate()
+
+ def cleanup(self):
+ self.asyengine.cleanup()
+
+ def getScrsTransform(self):
+ # pipeline:
+ # assuming origin <==> top left
+ # (Pan) * (Translate) * (Flip the images) * (Zoom) * (Obj transform) * (Base Information)
+
+ # pipeline --> let x, y be the postscript point
+ # p = (mx + cx + panoffset, -ny + cy + panoffset)
+ cx, cy = self.canvSize.width() / 2, self.canvSize.height() / 2
+
+ newTransf = Qg.QTransform()
+ newTransf.translate(*self.panOffset)
+ newTransf.translate(cx, cy)
+ newTransf.scale(1, 1)
+ newTransf.scale(self.magnification, self.magnification)
+
+ return newTransf
+
+ def finalizeCurve(self):
+ if self.addMode is not None:
+ if self.addMode.active and isinstance(self.addMode, InplaceAddObj.AddBezierShape):
+ self.addMode.forceFinalize()
+ self.fileChanged = True
+
+ def finalizeCurveClosed(self):
+ if self.addMode is not None:
+ if self.addMode.active and isinstance(self.addMode, InplaceAddObj.AddBezierShape):
+ self.addMode.finalizeClosure()
+ self.fileChanged = True
+
+ def getAllBoundingBox(self) -> Qc.QRectF:
+ newRect = Qc.QRectF()
+ for majitem in self.drawObjects:
+ for minitem in majitem:
+ newRect = newRect.united(minitem.boundingBox)
+ return newRect
+
+ def finalizeAddObj(self):
+ if self.addMode is not None:
+ if self.addMode.active:
+ self.addMode.forceFinalize()
+ self.fileChanged = True
+
+ def openAndReloadSettings(self):
+ settingsFile = self.settings.settingsFileLocation()
+ subprocess.run(args=self.getExternalEditor(asypath=settingsFile))
+ self.settings.load()
+ self.quickUpdate()
+
+ def setMagPrompt(self):
+ commandText, result = Qw.QInputDialog.getText(self, '', 'Enter magnification:')
+ if result:
+ self.magnification = float(commandText)
+ self.currAddOptions['magnification'] = self.magnification
+ self.quickUpdate()
+
+ def btnTogglePythonOnClick(self, checked):
+ self.terminalPythonMode = checked
+
+ def internationalize(self):
+ self.ui.btnRotate.setToolTip(self.strings.rotate)
+
+ def handleArguments(self):
+ if self.args.filename is not None:
+ self.loadFile(self.args.filename)
+ else:
+ self.initializeEmptyFile()
+
+ if self.args.language != 'en':
+ self.internationalize()
+
+ def initPenInterface(self):
+ self.ui.txtLineWidth.setText(str(self._currentPen.width))
+ self.updateFrameDispColor()
+
+ def updateFrameDispColor(self):
+ r, g, b = [int(x * 255) for x in self._currentPen.color]
+ self.ui.frameCurrColor.setStyleSheet(MainWindow1.defaultFrameStyle.format(r, g, b))
+
+ def initDebug(self):
+ debugFunc = {
+ }
+ self.commandsFunc = {**self.commandsFunc, **debugFunc}
+
+ def dbgRecomputeCtrl(self):
+ if isinstance(self.addMode, xbi.InteractiveBezierEditor):
+ self.addMode.recalculateCtrls()
+ self.quickUpdate()
+
+ def objectUpdated(self):
+ self.removeAddMode()
+ self.clearSelection()
+ self.asyfyCanvas()
+
+ def connectActions(self):
+ self.ui.actionQuit.triggered.connect(lambda: self.execCustomCommand('quit'))
+ self.ui.actionUndo.triggered.connect(lambda: self.execCustomCommand('undo'))
+ self.ui.actionRedo.triggered.connect(lambda: self.execCustomCommand('redo'))
+ self.ui.actionTransform.triggered.connect(lambda: self.execCustomCommand('transform'))
+
+ self.ui.actionOpen.triggered.connect(self.actionOpen)
+ self.ui.actionSave.triggered.connect(self.actionSave)
+ self.ui.actionSaveAs.triggered.connect(self.actionSaveAs)
+ self.ui.actionManual.triggered.connect(self.actionManual)
+ self.ui.actionAbout.triggered.connect(self.actionAbout)
+ self.ui.actionSettings.triggered.connect(self.openAndReloadSettings)
+ self.ui.actionEnterCommand.triggered.connect(self.enterCustomCommand)
+ self.ui.actionExportAsymptote.triggered.connect(self.btnExportAsyOnClick)
+
+ def setupXasyOptions(self):
+ if self.settings['debugMode']:
+ self.initDebug()
+ newColor = Qg.QColor(self.settings['defaultPenColor'])
+ newWidth = self.settings['defaultPenWidth']
+
+ self._currentPen.setColorFromQColor(newColor)
+ self._currentPen.setWidth(newWidth)
+
+ def connectButtons(self):
+ # Button initialization
+ self.ui.btnUndo.clicked.connect(self.btnUndoOnClick)
+ self.ui.btnRedo.clicked.connect(self.btnRedoOnClick)
+ self.ui.btnLoadFile.clicked.connect(self.btnLoadFileonClick)
+ self.ui.btnSave.clicked.connect(self.btnSaveonClick)
+ self.ui.btnQuickScreenshot.clicked.connect(self.btnQuickScreenshotOnClick)
+
+ # self.ui.btnExportAsy.clicked.connect(self.btnExportAsyOnClick)
+
+ self.ui.btnDrawAxes.clicked.connect(self.btnDrawAxesOnClick)
+# self.ui.btnAsyfy.clicked.connect(lambda: self.asyfyCanvas(True))
+ self.ui.btnSetZoom.clicked.connect(self.setMagPrompt)
+ self.ui.btnResetPan.clicked.connect(self.resetPan)
+ self.ui.btnPanCenter.clicked.connect(self.btnPanCenterOnClick)
+
+ self.ui.btnTranslate.clicked.connect(self.btnTranslateonClick)
+ self.ui.btnRotate.clicked.connect(self.btnRotateOnClick)
+ self.ui.btnScale.clicked.connect(self.btnScaleOnClick)
+ # self.ui.btnSelect.clicked.connect(self.btnSelectOnClick)
+ self.ui.btnPan.clicked.connect(self.btnPanOnClick)
+
+ # self.ui.btnDebug.clicked.connect(self.pauseBtnOnClick)
+ self.ui.btnAlignX.clicked.connect(self.btnAlignXOnClick)
+ self.ui.btnAlignY.clicked.connect(self.btnAlignYOnClick)
+ self.ui.comboAnchor.currentIndexChanged.connect(self.handleAnchorComboIndex)
+ self.ui.btnCustTransform.clicked.connect(self.btnCustTransformOnClick)
+ self.ui.btnViewCode.clicked.connect(self.btnLoadEditorOnClick)
+
+ self.ui.btnAnchor.clicked.connect(self.btnAnchorModeOnClick)
+
+ self.ui.btnSelectColor.clicked.connect(self.btnColorSelectOnClick)
+ self.ui.txtLineWidth.textEdited.connect(self.txtLineWithEdited)
+
+ # self.ui.btnCreateCurve.clicked.connect(self.btnCreateCurveOnClick)
+ self.ui.btnDrawGrid.clicked.connect(self.btnDrawGridOnClick)
+
+ self.ui.btnAddCircle.clicked.connect(self.btnAddCircleOnClick)
+ self.ui.btnAddPoly.clicked.connect(self.btnAddPolyOnClick)
+ self.ui.btnAddLabel.clicked.connect(self.btnAddLabelOnClick)
+ # self.ui.btnAddBezierInplace.clicked.connect(self.btnAddBezierInplaceOnClick)
+ self.ui.btnClosedCurve.clicked.connect(self.btnAddClosedCurveOnClick)
+ self.ui.btnOpenCurve.clicked.connect(self.btnAddOpenCurveOnClick)
+ self.ui.btnClosedPoly.clicked.connect(self.btnAddClosedLineOnClick)
+ self.ui.btnOpenPoly.clicked.connect(self.btnAddOpenLineOnClick)
+
+ self.ui.btnFill.clicked.connect(self.btnFillOnClick)
+
+ self.ui.btnSendBackwards.clicked.connect(self.btnSendBackwardsOnClick)
+ self.ui.btnSendForwards.clicked.connect(self.btnSendForwardsOnClick)
+ # self.ui.btnDelete.clicked.connect(self.btnSelectiveDeleteOnClick)
+ self.ui.btnDeleteMode.clicked.connect(self.btnDeleteModeOnClick)
+ # self.ui.btnSoftDelete.clicked.connect(self.btnSoftDeleteOnClick)
+ self.ui.btnToggleVisible.clicked.connect(self.btnSetVisibilityOnClick)
+
+ self.ui.btnEnterCommand.clicked.connect(self.btnTerminalCommandOnClick)
+ self.ui.btnTogglePython.clicked.connect(self.btnTogglePythonOnClick)
+ self.ui.btnSelectEdit.clicked.connect(self.btnSelectEditOnClick)
+
+ def btnDeleteModeOnClick(self):
+ self.currentModeStack = [SelectionMode.delete]
+ self.ui.statusbar.showMessage('Delete Mode')
+ self.clearSelection()
+ self.updateChecks()
+
+ def btnTerminalCommandOnClick(self):
+ if self.terminalPythonMode:
+ exec(self.ui.txtTerminalPrompt.text())
+ self.fileChanged = True
+ else:
+ pass
+ # TODO: How to handle this case?
+ # Like AutoCAD?
+ self.ui.txtTerminalPrompt.clear()
+
+ def btnFillOnClick(self, checked):
+ self.currAddOptions['fill'] = checked
+ self.ui.btnOpenCurve.setEnabled(not checked)
+ self.ui.btnOpenPoly.setEnabled(not checked)
+
+ def btnSelectEditOnClick(self):
+ self.ui.statusbar.showMessage('Edit mode')
+ self.currentModeStack = [SelectionMode.selectEdit]
+ self.updateChecks()
+
+ @property
+ def currentPen(self):
+ return x2a.asyPen.fromAsyPen(self._currentPen)
+ pass
+ def debug(self):
+ print('Put a breakpoint here.')
+
+ def execPythonCmd(self):
+ commandText, result = Qw.QInputDialog.getText(self, '', 'enter python cmd')
+ if result:
+ exec(commandText)
+
+ def deleteAddOptions(self):
+ if self.currAddOptionsWgt is not None:
+ self.currAddOptionsWgt.hide()
+ self.ui.addOptionLayout.removeWidget(self.currAddOptionsWgt)
+ self.currAddOptionsWgt = None
+
+ def updateOptionWidget(self):
+ try:
+ self.addMode.objectCreated.disconnect()
+ except Exception:
+ pass
+
+ self.currentModeStack[-1] = None
+ self.addMode.objectCreated.connect(self.addInPlace)
+ self.updateModeBtnsOnly()
+
+
+ self.deleteAddOptions()
+
+ self.currAddOptionsWgt = self.addMode.createOptWidget(self.currAddOptions)
+ if self.currAddOptionsWgt is not None:
+ self.ui.addOptionLayout.addWidget(self.currAddOptionsWgt)
+
+ def addInPlace(self, obj):
+ obj.asyengine = self.asyEngine
+ obj.pen = self.currentPen
+ obj.onCanvas = self.xasyDrawObj
+ obj.setKey(str(self.globalObjectCounter))
+ self.globalObjectCounter = self.globalObjectCounter + 1
+
+ self.fileItems.append(obj)
+ self.fileChanged = True
+ self.addObjCreationUrs(obj)
+ self.asyfyCanvas()
+
+ def addObjCreationUrs(self, obj):
+ newAction = self.createAction(ObjCreationChanges(obj))
+ self.undoRedoStack.add(newAction)
+ self.checkUndoRedoButtons()
+
+ def clearGuides(self):
+ self.currentGuides.clear()
+ self.quickUpdate()
+
+ def btnAddCircleOnClick(self):
+ self.addMode = InplaceAddObj.AddCircle(self)
+ self.ui.statusbar.showMessage('')
+ self.updateOptionWidget()
+
+ LegacyHint='Click and drag to draw; right click or space bar to finalize'
+ Hint='Click and drag to draw; release and click in place to add node; continue dragging'
+ HintClose=' or c to close.'
+
+ def drawHint(self):
+ if self.settings['useLegacyDrawMode']:
+ self.ui.statusbar.showMessage(self.LegacyHint+'.')
+ else:
+ self.ui.statusbar.showMessage(self.Hint+'.')
+
+ def drawHintOpen(self):
+ if self.settings['useLegacyDrawMode']:
+ self.ui.statusbar.showMessage(self.LegacyHint+self.HintClose)
+ else:
+ self.ui.statusbar.showMessage(self.Hint+self.HintClose)
+
+ def btnAddBezierInplaceOnClick(self):
+ self.addMode = InplaceAddObj.AddBezierShape(self)
+ self.updateOptionWidget()
+
+ def btnAddOpenLineOnClick(self):
+ self.currAddOptions['useBezier'] = False
+ self.currAddOptions['closedPath'] = False
+ self.drawHintOpen()
+ self.btnAddBezierInplaceOnClick()
+
+ def btnAddClosedLineOnClick(self):
+ self.currAddOptions['useBezier'] = False
+ self.currAddOptions['closedPath'] = True
+ self.drawHint()
+ self.btnAddBezierInplaceOnClick()
+
+ def btnAddOpenCurveOnClick(self):
+ self.currAddOptions['useBezier'] = True
+ self.currAddOptions['closedPath'] = False
+ self.drawHintOpen()
+ self.btnAddBezierInplaceOnClick()
+
+ def btnAddClosedCurveOnClick(self):
+ self.currAddOptions['useBezier'] = True
+ self.currAddOptions['closedPath'] = True
+ self.drawHint()
+ self.btnAddBezierInplaceOnClick()
+
+ def btnAddPolyOnClick(self):
+ self.addMode = InplaceAddObj.AddPoly(self)
+ self.ui.statusbar.showMessage('')
+ self.updateOptionWidget()
+
+ def btnAddLabelOnClick(self):
+ self.addMode = InplaceAddObj.AddLabel(self)
+ self.ui.statusbar.showMessage('')
+ self.updateOptionWidget()
+
+ def updateCurve(self, valid, newCurve):
+ self.previewCurve = newCurve
+ self.quickUpdate()
+
+ def addTransformationChanges(self, objIndex, transform, isLocal=False):
+ self.undoRedoStack.add(self.createAction(TransformationChanges(objIndex,
+ transform, isLocal)))
+ self.checkUndoRedoButtons()
+
+ def btnSendForwardsOnClick(self):
+ if self.currentlySelectedObj['selectedIndex'] is not None:
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ selectedObj = self.drawObjects[maj][minor]
+ index = self.fileItems.index(selectedObj.parent())
+
+ self.clearSelection()
+ if index == len(self.fileItems) - 1:
+ return
+ else:
+ self.fileItems[index], self.fileItems[index + 1] = self.fileItems[index + 1], self.fileItems[index]
+ self.asyfyCanvas()
+
+ def btnSelectiveDeleteOnClick(self):
+ if self.currentlySelectedObj['selectedIndex'] is not None:
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ selectedObj = self.drawObjects[maj][minor]
+
+ parent = selectedObj.parent()
+
+ if isinstance(parent, x2a.xasyScript):
+ self.hiddenKeys.add((selectedObj.key, selectedObj.keyIndex))
+ self.softDeleteObj((maj, minor))
+ else:
+ index = self.fileItems.index(selectedObj.parent())
+
+ self.undoRedoStack.add(self.createAction(
+ HardDeletionChanges(selectedObj.parent(), index)
+ ))
+ self.checkUndoRedoButtons()
+
+ self.fileItems.remove(selectedObj.parent())
+
+ self.fileChanged = True
+ self.clearSelection()
+ self.asyfyCanvas()
+ else:
+ result = self.selectOnHover()
+ if result:
+ self.btnSelectiveDeleteOnClick()
+
+ def btnSetVisibilityOnClick(self):
+ if self.currentlySelectedObj['selectedIndex'] is not None:
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ selectedObj = self.drawObjects[maj][minor]
+
+ self.hiddenKeys.symmetric_difference_update({(selectedObj.key, selectedObj.keyIndex)})
+ self.clearSelection()
+ self.quickUpdate()
+
+ def btnSendBackwardsOnClick(self):
+ if self.currentlySelectedObj['selectedIndex'] is not None:
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ selectedObj = self.drawObjects[maj][minor]
+ index = self.fileItems.index(selectedObj.parent())
+
+ self.clearSelection()
+ if index == 0:
+ return
+ else:
+ self.fileItems[index], self.fileItems[index - 1] = self.fileItems[index - 1], self.fileItems[index]
+ self.asyfyCanvas()
+
+
+ def btnUndoOnClick(self):
+ self.undoRedoStack.undo()
+ self.checkUndoRedoButtons()
+
+ def btnRedoOnClick(self):
+ self.undoRedoStack.redo()
+ self.checkUndoRedoButtons()
+
+ def checkUndoRedoButtons(self):
+ self.ui.btnUndo.setEnabled(self.undoRedoStack.changesMade())
+ self.ui.actionUndo.setEnabled(self.undoRedoStack.changesMade())
+
+ self.ui.btnRedo.setEnabled(len(self.undoRedoStack.redoStack) > 0)
+ self.ui.actionRedo.setEnabled(len(self.undoRedoStack.redoStack) > 0)
+
+ def handleUndoChanges(self, change):
+ assert isinstance(change, ActionChanges)
+ if isinstance(change, TransformationChanges):
+ self.transformObject(change.objIndex, change.transformation.inverted(), change.isLocal)
+ elif isinstance(change, ObjCreationChanges):
+ self.fileItems.pop()
+ elif isinstance(change, HardDeletionChanges):
+ self.fileItems.insert(change.objIndex, change.item)
+ self.asyfyCanvas()
+
+ def handleRedoChanges(self, change):
+ assert isinstance(change, ActionChanges)
+ if isinstance(change, TransformationChanges):
+ self.transformObject(
+ change.objIndex, change.transformation, change.isLocal)
+ elif isinstance(change, ObjCreationChanges):
+ self.fileItems.append(change.object)
+ elif isinstance(change, HardDeletionChanges):
+ self.fileItems.remove(change.item)
+ self.asyfyCanvas()
+
+ # is this a "pythonic" way?
+ def createAction(self, changes):
+ def _change():
+ return self.handleRedoChanges(changes)
+
+ def _undoChange():
+ return self.handleUndoChanges(changes)
+
+ return Urs.action((_change, _undoChange))
+
+ def execCustomCommand(self, command):
+ if command in self.commandsFunc:
+ self.commandsFunc[command]()
+ else:
+ self.ui.statusbar.showMessage('Command {0} not found'.format(command))
+
+ def enterCustomCommand(self):
+ commandText, result = Qw.QInputDialog.getText(self, 'Enter Custom Command', 'Enter Custom Command')
+ if result:
+ self.execCustomCommand(commandText)
+
+ def addItemFromPath(self, path):
+ newItem = x2a.xasyShape(path, self.asyEngine, pen=self.currentPen)
+ self.fileItems.append(newItem)
+ self.fileChanged = True
+ self.asyfyCanvas()
+
+ def actionManual(self):
+ asyManualURL = 'http://asymptote.sourceforge.net/asymptote.pdf'
+ webbrowser.open_new(asyManualURL)
+
+ def actionAbout(self):
+ Qw.QMessageBox.about(self,"xasy","This is xasy "+xasyVersion.xasyVersion+"; a graphical front end to the Asymptote vector graphics language: http://asymptote.sourceforge.net/")
+
+ def btnExportAsyOnClick(self):
+ diag = Qw.QFileDialog(self)
+ diag.setAcceptMode(Qw.QFileDialog.AcceptSave)
+
+ formatId = {
+ 'pdf': {
+ 'name': 'PDF Files',
+ 'ext': ['*.pdf']
+ },
+ 'svg': {
+ 'name': 'Scalable Vector Graphics',
+ 'ext': ['*.svg']
+ },
+ 'eps': {
+ 'name': 'Postscript Files',
+ 'ext': ['*.eps']
+ },
+ 'png': {
+ 'name': 'Portable Network Graphics',
+ 'ext': ['*.png']
+ },
+ '*': {
+ 'name': 'Any Files',
+ 'ext': ['*.*']
+ }
+ }
+
+ formats = ['pdf', 'svg', 'eps', 'png', '*']
+
+ formatText = ';;'.join('{0:s} ({1:s})'.format(formatId[form]['name'], ' '.join(formatId[form]['ext']))
+ for form in formats)
+
+ if self.currDir is not None:
+ diag.setDirectory(self.currDir)
+ rawFile = os.path.splitext(os.path.basename(self.filename))[0] + '.pdf'
+ diag.selectFile(rawFile)
+
+ diag.setNameFilter(formatText)
+ diag.show()
+ result = diag.exec_()
+
+ if result != diag.Accepted:
+ return
+
+ finalFiles = diag.selectedFiles()
+
+ with io.StringIO() as finalCode:
+ xf.saveFile(finalCode, self.fileItems, self.asy2psmap)
+ finalString = finalCode.getvalue()
+
+ for file in finalFiles:
+ ext = os.path.splitext(file)
+ if len(ext) < 2:
+ ext = 'pdf'
+ else:
+ ext = ext[1][1:]
+
+ with subprocess.Popen(args=[self.asyPath, '-f{0}'.format(ext), '-o{0}'.format(file), '-'], encoding='utf-8',
+ stdin=subprocess.PIPE) as asy:
+ print('test:', finalString)
+ asy.stdin.write(finalString)
+ asy.stdin.close()
+ asy.wait(timeout=35)
+
+
+ def loadKeyMaps(self):
+ """Inverts the mapping of the key
+ Input map is in format 'Action' : 'Key Sequence' """
+ for action, key in self.keyMaps.options.items():
+ shortcut = Qw.QShortcut(self)
+ shortcut.setKey(Qg.QKeySequence(key))
+
+ # hate doing this, but python doesn't have explicit way to pass a
+ # string to a lambda without an identifier
+ # attached to it.
+ exec('shortcut.activated.connect(lambda: self.execCustomCommand("{0}"))'.format(action),
+ {'self': self, 'shortcut': shortcut})
+
+ def initializeButtons(self):
+ self.ui.btnDrawAxes.setChecked(self.settings['defaultShowAxes'])
+ self.btnDrawAxesOnClick(self.settings['defaultShowAxes'])
+
+ self.ui.btnDrawGrid.setChecked(self.settings['defaultShowGrid'])
+ self.btnDrawGridOnClick(self.settings['defaultShowGrid'])
+
+ def erase(self):
+ self.fileItems.clear()
+ self.fileChanged = False
+
+ def actionOpen(self):
+ if self.fileChanged:
+ save="Save current file?"
+ reply=Qw.QMessageBox.question(self,'Message',save,Qw.QMessageBox.Yes,
+ Qw.QMessageBox.No)
+ if reply == Qw.QMessageBox.Yes:
+ self.actionSave()
+
+ filename = Qw.QFileDialog.getOpenFileName(self, 'Open Asymptote File','', '*.asy')
+ if filename[0]:
+ self.loadFile(filename[0])
+
+ def actionSave(self):
+ if self.filename is None:
+ self.actionSaveAs()
+ else:
+ saveFile = io.open(self.filename, 'w')
+ xf.saveFile(saveFile, self.fileItems, self.asy2psmap)
+ saveFile.close()
+ self.updateScript()
+
+ def updateScript(self):
+ for item in self.fileItems:
+ if isinstance(item, x2a.xasyScript):
+ if item.updatedCode:
+ item.setScript(item.updatedCode)
+ item.updatedCode = None
+
+ def actionSaveAs(self):
+ saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save File')[0]
+ if saveLocation:
+ saveFile = io.open(saveLocation, 'w')
+ xf.saveFile(saveFile, self.fileItems, self.asy2psmap)
+ saveFile.close()
+ self.filename = saveLocation
+ self.updateScript()
+
+
+ def btnQuickScreenshotOnClick(self):
+ saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save Screenshot','')
+ if saveLocation[0]:
+ self.ui.imgLabel.pixmap().save(saveLocation[0])
+
+ def btnLoadFileonClick(self):
+ self.actionOpen()
+
+ def btnSaveonClick(self):
+ self.actionSave()
+
+ @Qc.pyqtSlot(int)
+ def handleAnchorComboIndex(self, index: int):
+ self.anchorMode = index
+ if self.anchorMode == AnchorMode.customAnchor:
+ if self.customAnchor is not None:
+ self.anchorMode = AnchorMode.customAnchor
+ else:
+ self.ui.comboAnchor.setCurrentIndex(AnchorMode.center)
+ self.anchorMode = AnchorMode.center
+ self.quickUpdate()
+ def btnColorSelectOnClick(self):
+ self.colorDialog.show()
+ result = self.colorDialog.exec()
+ if result == Qw.QDialog.Accepted:
+ self._currentPen.setColorFromQColor(self.colorDialog.selectedColor())
+ self.updateFrameDispColor()
+
+ def txtLineWithEdited(self, text):
+ new_val = xu.tryParse(text, float)
+ if new_val is not None:
+ if new_val > 0:
+ self._currentPen.setWidth(new_val)
+
+ def isReady(self):
+ return self.mainCanvas is not None
+
+ def resizeEvent(self, resizeEvent):
+ # super().resizeEvent(resizeEvent)
+ assert isinstance(resizeEvent, Qg.QResizeEvent)
+
+ if self.isReady():
+ if self.mainCanvas.isActive():
+ self.mainCanvas.end()
+ self.canvSize = self.ui.imgFrame.size()
+ self.ui.imgFrame.setSizePolicy(Qw.QSizePolicy.Ignored, Qw.QSizePolicy.Ignored)
+ self.canvasPixmap = Qg.QPixmap(self.canvSize)
+ # self.canvasPixmap.setDevicePixelRatio(3)
+ self.postCanvasPixmap = Qg.QPixmap(self.canvSize)
+
+ self.quickUpdate()
+
+ def show(self):
+ super().show()
+ self.createMainCanvas() # somehow, the coordinates doesn't get updated until after showing.
+ self.initializeButtons()
+ self.postShow()
+
+ def postShow(self):
+ self.handleArguments()
+
+ def roundPositionSnap(self, oldPoint):
+ minorGridSize = self.settings['gridMajorAxesSpacing'] / (self.settings['gridMinorAxesCount'] + 1)
+ if isinstance(oldPoint, list) or isinstance(oldPoint, tuple):
+ return [round(val / minorGridSize) * minorGridSize for val in oldPoint]
+ elif isinstance(oldPoint, Qc.QPoint) or isinstance(oldPoint, Qc.QPointF):
+ x, y = oldPoint.x(), oldPoint.y()
+ x = round(x / minorGridSize) * minorGridSize
+ y = round(y / minorGridSize) * minorGridSize
+ return Qc.QPointF(x, y)
+ else:
+ raise Exception
+
+ def getAsyCoordinates(self):
+ canvasPosOrig = self.getCanvasCoordinates()
+ return canvasPosOrig, canvasPosOrig
+
+ def mouseMoveEvent(self, mouseEvent: Qg.QMouseEvent): # TODO: Actually refine grid snapping...
+ if not self.ui.imgLabel.underMouse() and not self.mouseDown:
+ return
+
+ self.updateMouseCoordLabel()
+ asyPos, canvasPos = self.getAsyCoordinates()
+
+ # add mode
+ if self.addMode is not None:
+ if self.addMode.active:
+ self.addMode.mouseMove(asyPos, mouseEvent)
+ self.quickUpdate()
+ return
+
+ # pan mode
+ if self.currentModeStack[-1] == SelectionMode.pan and int(mouseEvent.buttons()) and self.savedWindowMousePos is not None:
+ mousePos = self.getWindowCoordinates()
+ newPos = mousePos - self.savedWindowMousePos
+
+ tx, ty = newPos.x(), newPos.y()
+
+ if self.lockX:
+ tx = 0
+ if self.lockY:
+ ty = 0
+
+ self.panOffset[0] += tx
+ self.panOffset[1] += ty
+
+ self.savedWindowMousePos = self.getWindowCoordinates()
+ self.quickUpdate()
+ return
+
+ # otherwise, in transformation
+ if self.inMidTransformation:
+ if self.currentModeStack[-1] == SelectionMode.translate:
+ newPos = canvasPos - self.savedMousePosition
+ if self.gridSnap:
+ newPos = self.roundPositionSnap(newPos) # actually round to the nearest minor grid afterwards...
+
+ self.tx, self.ty = newPos.x(), newPos.y()
+
+ if self.lockX:
+ self.tx = 0
+ if self.lockY:
+ self.ty = 0
+ self.newTransform = Qg.QTransform.fromTranslate(self.tx, self.ty)
+
+ elif self.currentModeStack[-1] == SelectionMode.rotate:
+ if self.gridSnap:
+ canvasPos = self.roundPositionSnap(canvasPos)
+
+ adjustedSavedMousePos = self.savedMousePosition - self.currentAnchor
+ adjustedCanvasCoords = canvasPos - self.currentAnchor
+
+ origAngle = np.arctan2(adjustedSavedMousePos.y(), adjustedSavedMousePos.x())
+ newAng = np.arctan2(adjustedCanvasCoords.y(), adjustedCanvasCoords.x())
+ self.deltaAngle = newAng - origAngle
+ self.newTransform = xT.makeRotTransform(self.deltaAngle, self.currentAnchor).toQTransform()
+
+ elif self.currentModeStack[-1] == SelectionMode.scale:
+ if self.gridSnap:
+ canvasPos = self.roundPositionSnap(canvasPos)
+ x, y = int(round(canvasPos.x())), int(round(canvasPos.y())) # otherwise it crashes...
+ canvasPos = Qc.QPoint(x, y)
+
+ originalDeltaPts = self.savedMousePosition - self.currentAnchor
+ scaleFactor = Qc.QPointF.dotProduct(canvasPos - self.currentAnchor, originalDeltaPts) /\
+ (xu.twonorm((originalDeltaPts.x(), originalDeltaPts.y())) ** 2)
+ if not self.lockX:
+ self.scaleFactorX = scaleFactor
+ else:
+ self.scaleFactorX = 1
+
+ if not self.lockY:
+ self.scaleFactorY = scaleFactor
+ else:
+ self.scaleFactorY = 1
+
+ self.newTransform = xT.makeScaleTransform(self.scaleFactorX, self.scaleFactorY, self.currentAnchor).\
+ toQTransform()
+
+ self.quickUpdate()
+ return
+
+ # otherwise, select a candinate for selection
+
+ if self.currentlySelectedObj['selectedIndex'] is None:
+ selectedIndex, selKeyList = self.selectObject()
+ if selectedIndex is not None:
+ if self.pendingSelectedObjList != selKeyList:
+ self.pendingSelectedObjList = selKeyList
+ self.pendingSelectedObjIndex = -1
+ else:
+ self.pendingSelectedObjList.clear()
+ self.pendingSelectedObjIndex = -1
+ self.quickUpdate()
+ return
+
+
+ def mouseReleaseEvent(self, mouseEvent):
+ assert isinstance(mouseEvent, Qg.QMouseEvent)
+ if not self.mouseDown:
+ return
+
+ self.mouseDown = False
+ if self.addMode is not None:
+ self.addMode.mouseRelease()
+ if self.inMidTransformation:
+ self.clearSelection()
+ self.inMidTransformation = False
+ self.quickUpdate()
+
+ def clearSelection(self):
+ if self.currentlySelectedObj['selectedIndex'] is not None:
+ self.releaseTransform()
+ self.setAllInSetEnabled(self.objButtons, False)
+ self.currentlySelectedObj['selectedIndex'] = None
+ self.currentlySelectedObj['key'] = None
+
+ self.currentlySelectedObj['allSameKey'].clear()
+ self.newTransform = Qg.QTransform()
+ self.currentBoundingBox = None
+ self.quickUpdate()
+
+ def changeSelection(self, offset):
+ if self.pendingSelectedObjList:
+ if offset > 0:
+ if self.pendingSelectedObjIndex + offset <= -1:
+ self.pendingSelectedObjIndex = self.pendingSelectedObjIndex + offset
+ else:
+ if self.pendingSelectedObjIndex + offset >= -len(self.pendingSelectedObjList):
+ self.pendingSelectedObjIndex = self.pendingSelectedObjIndex + offset
+
+ def mouseWheel(self, rawAngleX: float, rawAngle: float, defaultModifiers: int=0):
+ keyModifiers = int(Qw.QApplication.keyboardModifiers())
+ keyModifiers = keyModifiers | defaultModifiers
+ if keyModifiers & int(Qc.Qt.ControlModifier):
+ oldMag = self.magnification
+
+ cx, cy = self.canvSize.width() / 2, self.canvSize.height() / 2
+ centerPoint = Qc.QPointF(cx, cy) * self.getScrsTransform().inverted()[0]
+
+ self.magnification += (rawAngle/100)
+
+ if self.magnification < self.settings['minimumMagnification']:
+ self.magnification = self.settings['minimumMagnification']
+ elif self.magnification > self.settings['maximumMagnification']:
+ self.magnification = self.settings['maximumMagnification']
+
+ # set the new pan. Let c be the fixed point (center point),
+ # Let m the old mag, n the new mag
+
+ # find t2 such that
+ # mc + t1 = nc + t2 ==> t2 = (m - n)c + t1
+
+ centerPoint = (oldMag - self.magnification) * centerPoint
+
+ self.panOffset = [
+ self.panOffset[0] + centerPoint.x(),
+ self.panOffset[1] + centerPoint.y()
+ ]
+
+ self.currAddOptions['magnification'] = self.magnification
+
+ if self.addMode is xbi.InteractiveBezierEditor:
+ self.addMode.setSelectionBoundaries()
+
+ elif keyModifiers & (int(Qc.Qt.ShiftModifier) | int(Qc.Qt.AltModifier)):
+ self.panOffset[1] += rawAngle/1
+ self.panOffset[0] -= rawAngleX/1
+ # handle scrolling
+ else:
+ # process selection layer change
+ if rawAngle >= 15:
+ self.changeSelection(1)
+ elif rawAngle <= -15:
+ self.changeSelection(-1)
+ self.quickUpdate()
+
+ def wheelEvent(self, event: Qg.QWheelEvent):
+ rawAngle = event.angleDelta().y() / 8
+ rawAngleX = event.angleDelta().x() / 8
+ self.mouseWheel(rawAngleX, rawAngle)
+
+ def selectOnHover(self):
+ """Returns True if selection happened, False otherwise.
+ """
+ if self.pendingSelectedObjList:
+ selectedIndex = self.pendingSelectedObjList[self.pendingSelectedObjIndex]
+ self.pendingSelectedObjList.clear()
+
+ maj, minor = selectedIndex
+
+ self.currentlySelectedObj['selectedIndex'] = selectedIndex
+ self.currentlySelectedObj['key'], self.currentlySelectedObj['allSameKey'] = self.selectObjectSet(
+ )
+
+ self.currentBoundingBox = self.drawObjects[maj][minor].boundingBox
+
+ if self.selectAsGroup:
+ for selItems in self.currentlySelectedObj['allSameKey']:
+ obj = self.drawObjects[selItems[0]][selItems[1]]
+ self.currentBoundingBox = self.currentBoundingBox.united(obj.boundingBox)
+
+ self.origBboxTransform = self.drawObjects[maj][minor].transform.toQTransform()
+ self.newTransform = Qg.QTransform()
+ return True
+ else:
+ return False
+
+ def mousePressEvent(self, mouseEvent: Qg.QMouseEvent):
+ # we make an exception for bezier curve
+ bezierException = False
+ if self.addMode is not None:
+ if self.addMode.active and isinstance(self.addMode, InplaceAddObj.AddBezierShape):
+ bezierException = True
+
+ if not self.ui.imgLabel.underMouse() and not bezierException:
+ return
+
+ self.mouseDown = True
+ asyPos, self.savedMousePosition = self.getAsyCoordinates()
+
+ if self.addMode is not None:
+ self.addMode.mouseDown(asyPos, self.currAddOptions, mouseEvent)
+ elif self.currentModeStack[-1] == SelectionMode.pan:
+ self.savedWindowMousePos = self.getWindowCoordinates()
+ elif self.currentModeStack[-1] == SelectionMode.setAnchor:
+ self.customAnchor = self.savedMousePosition
+ self.currentModeStack.pop()
+
+ self.anchorMode = AnchorMode.customAnchor
+ self.ui.comboAnchor.setCurrentIndex(AnchorMode.customAnchor)
+ self.updateChecks()
+ self.quickUpdate()
+ elif self.inMidTransformation:
+ pass
+ elif self.pendingSelectedObjList:
+ self.selectOnHover()
+
+ if self.currentModeStack[-1] in {SelectionMode.translate, SelectionMode.rotate, SelectionMode.scale}:
+ self.setAllInSetEnabled(self.objButtons, False)
+ self.inMidTransformation = True
+ self.setAnchor()
+ elif self.currentModeStack[-1] == SelectionMode.delete:
+ self.btnSelectiveDeleteOnClick()
+ elif self.currentModeStack[-1] == SelectionMode.selectEdit:
+ self.setupSelectEdit()
+ else:
+ self.setAllInSetEnabled(self.objButtons, True)
+ self.inMidTransformation = False
+ self.setAnchor()
+
+ else:
+ self.setAllInSetEnabled(self.objButtons, False)
+ self.currentBoundingBox = None
+ self.inMidTransformation = False
+ self.clearSelection()
+
+ self.quickUpdate()
+
+ def removeAddMode(self):
+ self.addMode = None
+ self.deleteAddOptions()
+
+ def editFinalized(self):
+ self.addMode.forceFinalize()
+ self.removeAddMode()
+ self.fileChanged = True
+ self.quickUpdate()
+
+ def editRejected(self):
+ self.addMode.resetObj()
+ self.editFinalized()
+
+ def setupSelectEdit(self):
+ """For Select-Edit mode. For now, if the object selected is a bezier curve, opens up a bezier editor"""
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ obj = self.fileItems[maj]
+ if isinstance(obj, x2a.xasyDrawnItem):
+ # bezier path
+ self.addMode = xbi.InteractiveBezierEditor(self, obj, self.currAddOptions)
+ self.addMode.objectUpdated.connect(self.objectUpdated)
+ self.addMode.editAccepted.connect(self.editFinalized)
+ self.addMode.editRejected.connect(self.editRejected)
+ self.updateOptionWidget()
+ self.currentModeStack[-1] = SelectionMode.selectEdit
+ self.fileChanged = True
+ else:
+ self.clearSelection()
+ self.quickUpdate()
+
+ def setAnchor(self):
+ if self.anchorMode == AnchorMode.center:
+ self.currentAnchor = self.currentBoundingBox.center()
+ elif self.anchorMode == AnchorMode.topLeft:
+ self.currentAnchor = self.currentBoundingBox.bottomLeft() # due to internal image being flipped
+ elif self.anchorMode == AnchorMode.topRight:
+ self.currentAnchor = self.currentBoundingBox.bottomRight()
+ elif self.anchorMode == AnchorMode.bottomLeft:
+ self.currentAnchor = self.currentBoundingBox.topLeft()
+ elif self.anchorMode == AnchorMode.bottomRight:
+ self.currentAnchor = self.currentBoundingBox.topRight()
+ elif self.anchorMode == AnchorMode.customAnchor:
+ self.currentAnchor = self.customAnchor
+ else:
+ self.currentAnchor = Qc.QPointF(0, 0)
+
+ if self.anchorMode != AnchorMode.origin:
+ pass
+ # TODO: Record base points/bbox before hand and use that for
+ # anchor?
+ # adjTransform =
+ # self.drawObjects[selectedIndex].transform.toQTransform()
+ # self.currentAnchor = adjTransform.map(self.currentAnchor)
+
+
+ def releaseTransform(self):
+ if self.newTransform.isIdentity():
+ return
+ newTransform = x2a.asyTransform.fromQTransform(self.newTransform)
+ objKey = self.currentlySelectedObj['selectedIndex']
+ self.addTransformationChanges(objKey, newTransform, not self.useGlobalCoords)
+ self.transformObject(objKey, newTransform, not self.useGlobalCoords)
+
+ def adjustTransform(self, appendTransform):
+ self.screenTransformation = self.screenTransformation * appendTransform
+
+ def createMainCanvas(self):
+ self.canvSize = self.ui.imgFrame.size()
+ self.ui.imgFrame.setSizePolicy(Qw.QSizePolicy.Ignored, Qw.QSizePolicy.Ignored)
+ x, y = self.canvSize.width() / 2, self.canvSize.height() / 2
+
+ self.canvasPixmap = Qg.QPixmap(self.canvSize)
+ self.canvasPixmap.fill()
+
+ self.finalPixmap = Qg.QPixmap(self.canvSize)
+
+ self.preCanvasPixmap = Qg.QPixmap(self.canvSize)
+ self.postCanvasPixmap = Qg.QPixmap(self.canvSize)
+
+ self.mainCanvas = Qg.QPainter(self.canvasPixmap)
+ self.mainCanvas.setRenderHint(Qg.QPainter.Antialiasing)
+ self.mainCanvas.setRenderHint(Qg.QPainter.SmoothPixmapTransform)
+ self.mainCanvas.setRenderHint(Qg.QPainter.HighQualityAntialiasing)
+ self.xasyDrawObj['canvas'] = self.mainCanvas
+
+ self.mainTransformation = Qg.QTransform()
+ self.mainTransformation.scale(1, 1)
+ self.mainTransformation.translate(x, y)
+
+ self.mainCanvas.setTransform(self.getScrsTransform(), True)
+
+ self.ui.imgLabel.setPixmap(self.canvasPixmap)
+
+ def resetPan(self):
+ self.panOffset = [0, 0]
+ self.quickUpdate()
+
+ def btnPanCenterOnClick(self):
+ newCenter = self.getAllBoundingBox().center()
+
+ # adjust to new magnification
+ # technically, doable through getscrstransform()
+ # and subtract pan offset and center points
+ # but it's much more work...
+ newCenter = self.magnification * newCenter
+ self.panOffset = [-newCenter.x(), newCenter.y()]
+
+ self.quickUpdate()
+
+ def selectObject(self):
+ if not self.ui.imgLabel.underMouse():
+ return None, []
+ canvasCoords = self.getCanvasCoordinates()
+ highestDrawPriority = -np.inf
+ collidedObjKey = None
+ rawObjNumList = []
+ for objKeyMaj in range(len(self.drawObjects)):
+ for objKeyMin in range(len(self.drawObjects[objKeyMaj])):
+ obj = self.drawObjects[objKeyMaj][objKeyMin]
+ if obj.collide(canvasCoords) and (obj.key, obj.keyIndex) not in self.hiddenKeys:
+ rawObjNumList.append(((objKeyMaj, objKeyMin), obj.drawOrder))
+ if obj.drawOrder > highestDrawPriority:
+ collidedObjKey = (objKeyMaj, objKeyMin)
+ if collidedObjKey is not None:
+ rawKey = self.drawObjects[collidedObjKey[0]][collidedObjKey[1]].key
+# self.ui.statusbar.showMessage('Collide with {0}, Key is {1}'.format(str(collidedObjKey), rawKey), 2500)
+ self.ui.statusbar.showMessage('Key: {0}'.format(rawKey), 2500)
+ return collidedObjKey, [rawObj[0] for rawObj in sorted(rawObjNumList, key=lambda ordobj: ordobj[1])]
+ else:
+ return None, []
+
+ def selectObjectSet(self):
+ objKey = self.currentlySelectedObj['selectedIndex']
+ if objKey is None:
+ return set()
+ assert isinstance(objKey, (tuple, list)) and len(objKey) == 2
+ rawObj = self.drawObjects[objKey[0]][objKey[1]]
+ rawKey = rawObj.key
+ rawSet = {objKey}
+ for objKeyMaj in range(len(self.drawObjects)):
+ for objKeyMin in range(len(self.drawObjects[objKeyMaj])):
+ obj = self.drawObjects[objKeyMaj][objKeyMin]
+ if obj.key == rawKey:
+ rawSet.add((objKeyMaj, objKeyMin))
+ return rawKey, rawSet
+
+ def getCanvasCoordinates(self):
+ # assert self.ui.imgLabel.underMouse()
+ uiPos = self.mapFromGlobal(Qg.QCursor.pos())
+ canvasPos = self.ui.imgLabel.mapFrom(self, uiPos)
+
+ # Issue: For magnification, should xasy treats this at xasy level, or asy level?
+ return canvasPos * self.getScrsTransform().inverted()[0]
+
+ def getWindowCoordinates(self):
+ # assert self.ui.imgLabel.underMouse()
+ return self.mapFromGlobal(Qg.QCursor.pos())
+
+ def refreshCanvas(self):
+ if self.mainCanvas.isActive():
+ self.mainCanvas.end()
+ self.mainCanvas.begin(self.canvasPixmap)
+ self.mainCanvas.setTransform(self.getScrsTransform())
+
+ def asyfyCanvas(self, force=False):
+ self.drawObjects = []
+ self.populateCanvasWithItems(force)
+ self.quickUpdate()
+ if self.currentModeStack[-1] == SelectionMode.translate:
+ self.ui.statusbar.showMessage(self.strings.asyfyComplete)
+
+ def updateMouseCoordLabel(self):
+ *args, canvasPos = self.getAsyCoordinates()
+ nx, ny = self.asy2psmap.inverted() * (canvasPos.x(), canvasPos.y())
+ self.coordLabel.setText('{0:.2f}, {1:.2f} '.format(nx, ny))
+
+ def quickUpdate(self):
+ self.updateMouseCoordLabel()
+ self.refreshCanvas()
+
+ self.preDraw(self.mainCanvas)
+ self.quickDraw()
+
+ self.mainCanvas.end()
+ self.postDraw()
+ self.updateScreen()
+
+ def quickDraw(self):
+ assert self.isReady()
+ dpi = self.magnification * self.dpi
+ activeItem = None
+ for majorItem in self.drawObjects:
+ for item in majorItem:
+ # hidden objects - toggleable
+ if (item.key, item.keyIndex) in self.hiddenKeys:
+ continue
+ isSelected = item.key == self.currentlySelectedObj['key']
+ if not self.selectAsGroup and isSelected and self.currentlySelectedObj['selectedIndex'] is not None:
+ maj, min_ = self.currentlySelectedObj['selectedIndex']
+ isSelected = isSelected and item is self.drawObjects[maj][min_]
+ if isSelected and self.settings['enableImmediatePreview']:
+ activeItem = item
+ if self.useGlobalCoords:
+ item.draw(self.newTransform, canvas=self.mainCanvas, dpi=dpi)
+ else:
+ item.draw(self.newTransform, applyReverse=True, canvas=self.mainCanvas, dpi=dpi)
+ else:
+ item.draw(canvas=self.mainCanvas, dpi=dpi)
+
+ if self.settings['drawSelectedOnTop']:
+ if self.pendingSelectedObjList:
+ maj, minor = self.pendingSelectedObjList[self.pendingSelectedObjIndex]
+ self.drawObjects[maj][minor].draw(canvas=self.mainCanvas, dpi=dpi)
+ # and apply the preview too...
+ elif activeItem is not None:
+ if self.useGlobalCoords:
+ activeItem.draw(self.newTransform, canvas=self.mainCanvas, dpi=dpi)
+ else:
+ activeItem.draw(self.newTransform, applyReverse=True, canvas=self.mainCanvas, dpi=dpi)
+ activeItem = None
+
+ def updateScreen(self):
+ self.finalPixmap = Qg.QPixmap(self.canvSize)
+ self.finalPixmap.fill(Qc.Qt.black)
+ with Qg.QPainter(self.finalPixmap) as finalPainter:
+ drawPoint = Qc.QPoint(0, 0)
+ # finalPainter.drawPixmap(drawPoint, self.preCanvasPixmap)
+ finalPainter.drawPixmap(drawPoint, self.canvasPixmap)
+ finalPainter.drawPixmap(drawPoint, self.postCanvasPixmap)
+ self.ui.imgLabel.setPixmap(self.finalPixmap)
+
+ def drawCartesianGrid(self, preCanvas):
+ majorGrid = self.settings['gridMajorAxesSpacing'] * self.asy2psmap.xx
+ minorGridCount = self.settings['gridMinorAxesCount']
+
+ majorGridCol = Qg.QColor(self.settings['gridMajorAxesColor'])
+ minorGridCol = Qg.QColor(self.settings['gridMinorAxesColor'])
+
+ panX, panY = self.panOffset
+
+ x_range = (self.canvSize.width() / 2 + (2 * abs(panX)))/self.magnification
+ y_range = (self.canvSize.height() / 2 + (2 * abs(panY)))/self.magnification
+
+ for x in np.arange(0, 2 * x_range + 1, majorGrid): # have to do
+ # this in two stages...
+ preCanvas.setPen(minorGridCol)
+ for xMinor in range(1, minorGridCount + 1):
+ xCoord = x + ((xMinor / (minorGridCount + 1)) * majorGrid)
+ preCanvas.drawLine(Qc.QLine(xCoord, -9999, xCoord, 9999))
+ preCanvas.drawLine(Qc.QLine(-xCoord, -9999, -xCoord, 9999))
+
+ for y in np.arange(0, 2 * y_range + 1, majorGrid):
+ preCanvas.setPen(minorGridCol)
+ for yMinor in range(1, minorGridCount + 1):
+ yCoord = y + ((yMinor / (minorGridCount + 1)) * majorGrid)
+ preCanvas.drawLine(Qc.QLine(-9999, yCoord, 9999, yCoord))
+ preCanvas.drawLine(Qc.QLine(-9999, -yCoord, 9999, -yCoord))
+
+ preCanvas.setPen(majorGridCol)
+ preCanvas.drawLine(Qc.QLine(-9999, y, 9999, y))
+ preCanvas.drawLine(Qc.QLine(-9999, -y, 9999, -y))
+
+ for x in np.arange(0, 2 * x_range + 1, majorGrid):
+ preCanvas.setPen(majorGridCol)
+ preCanvas.drawLine(Qc.QLine(x, -9999, x, 9999))
+ preCanvas.drawLine(Qc.QLine(-x, -9999, -x, 9999))
+
+ def drawPolarGrid(self, preCanvas):
+ center = Qc.QPointF(0, 0)
+ majorGridCol = Qg.QColor(self.settings['gridMajorAxesColor'])
+ minorGridCol = Qg.QColor(self.settings['gridMinorAxesColor'])
+ majorGrid = self.settings['gridMajorAxesSpacing']
+ minorGridCount = self.settings['gridMinorAxesCount']
+
+ majorAxisAng = (np.pi/4) # 45 degrees - for now.
+ minorAxisCount = 2 # 15 degrees each
+
+ subRadiusSize = int(round((majorGrid / (minorGridCount + 1))))
+ subAngleSize = majorAxisAng / (minorAxisCount + 1)
+
+ for radius in range(majorGrid, 9999 + 1, majorGrid):
+ preCanvas.setPen(majorGridCol)
+ preCanvas.drawEllipse(center, radius, radius)
+
+ preCanvas.setPen(minorGridCol)
+
+ for minorRing in range(minorGridCount):
+ subRadius = round(radius - (subRadiusSize * (minorRing + 1)))
+ preCanvas.drawEllipse(center, subRadius, subRadius)
+
+ currAng = majorAxisAng
+ while currAng <= (2 * np.pi):
+ preCanvas.setPen(majorGridCol)
+ p1 = center + (9999 * Qc.QPointF(np.cos(currAng), np.sin(currAng)))
+ preCanvas.drawLine(Qc.QLineF(center, p1))
+
+ preCanvas.setPen(minorGridCol)
+ for minorAngLine in range(minorAxisCount):
+ newAng = currAng - (subAngleSize * (minorAngLine + 1))
+ p1 = center + (9999 * Qc.QPointF(np.cos(newAng), np.sin(newAng)))
+ preCanvas.drawLine(Qc.QLineF(center, p1))
+
+ currAng = currAng + majorAxisAng
+
+ def preDraw(self, painter):
+ # self.preCanvasPixmap.fill(Qc.Qt.white)
+ self.canvasPixmap.fill()
+ preCanvas = painter
+
+ # preCanvas = Qg.QPainter(self.preCanvasPixmap)
+ preCanvas.setTransform(self.getScrsTransform())
+
+ if self.drawAxes:
+ preCanvas.setPen(Qc.Qt.gray)
+ preCanvas.drawLine(Qc.QLine(-9999, 0, 9999, 0))
+ preCanvas.drawLine(Qc.QLine(0, -9999, 0, 9999))
+
+ if self.drawGrid:
+ if self.drawGridMode == GridMode.cartesian:
+ self.drawCartesianGrid(painter)
+ elif self.drawGridMode == GridMode.polar:
+ self.drawPolarGrid(painter)
+
+ if self.currentGuides:
+ for guide in self.currentGuides:
+ guide.drawShape(preCanvas)
+ # preCanvas.end()
+
+ def drawAddModePreview(self, painter):
+ if self.addMode is not None:
+ if self.addMode.active:
+ # Preview Object
+ if self.addMode.getPreview() is not None:
+ painter.setPen(self.currentPen.toQPen())
+ painter.drawPath(self.addMode.getPreview())
+ self.addMode.postDrawPreview(painter)
+
+
+ def drawTransformPreview(self, painter):
+ if self.currentBoundingBox is not None and self.currentlySelectedObj['selectedIndex'] is not None:
+ painter.save()
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ selObj = self.drawObjects[maj][minor]
+ if not self.useGlobalCoords:
+ painter.save()
+ painter.setTransform(
+ selObj.transform.toQTransform(), True)
+ # painter.setTransform(selObj.baseTransform.toQTransform(), True)
+ painter.setPen(Qc.Qt.gray)
+ painter.drawLine(Qc.QLine(-9999, 0, 9999, 0))
+ painter.drawLine(Qc.QLine(0, -9999, 0, 9999))
+ painter.setPen(Qc.Qt.black)
+ painter.restore()
+
+ painter.setTransform(selObj.getInteriorScrTransform(
+ self.newTransform).toQTransform(), True)
+ painter.drawRect(selObj.localBoundingBox)
+ else:
+ painter.setTransform(self.newTransform, True)
+ painter.drawRect(self.currentBoundingBox)
+ painter.restore()
+
+ def postDraw(self):
+ self.postCanvasPixmap.fill(Qc.Qt.transparent)
+ with Qg.QPainter(self.postCanvasPixmap) as postCanvas:
+ postCanvas.setRenderHints(self.mainCanvas.renderHints())
+ postCanvas.setTransform(self.getScrsTransform())
+
+ self.drawTransformPreview(postCanvas)
+
+ if self.pendingSelectedObjList:
+ maj, minor = self.pendingSelectedObjList[self.pendingSelectedObjIndex]
+ postCanvas.drawRect(self.drawObjects[maj][minor].boundingBox)
+
+ self.drawAddModePreview(postCanvas)
+
+ if self.customAnchor is not None and self.anchorMode == AnchorMode.customAnchor:
+ self.drawAnchorCursor(postCanvas)
+
+ # postCanvas.drawRect(self.getAllBoundingBox())
+
+ def drawAnchorCursor(self, painter):
+ painter.drawEllipse(self.customAnchor, 6, 6)
+ newCirclePath = Qg.QPainterPath()
+ newCirclePath.addEllipse(self.customAnchor, 2, 2)
+
+ painter.fillPath(newCirclePath, Qg.QColor.fromRgb(0, 0, 0))
+
+ def updateModeBtnsOnly(self):
+ if self.currentModeStack[-1] == SelectionMode.translate:
+ activeBtn = self.ui.btnTranslate
+ elif self.currentModeStack[-1] == SelectionMode.rotate:
+ activeBtn = self.ui.btnRotate
+ elif self.currentModeStack[-1] == SelectionMode.scale:
+ activeBtn = self.ui.btnScale
+ elif self.currentModeStack[-1] == SelectionMode.pan:
+ activeBtn = self.ui.btnPan
+ elif self.currentModeStack[-1] == SelectionMode.setAnchor:
+ activeBtn = self.ui.btnAnchor
+ elif self.currentModeStack[-1] == SelectionMode.delete:
+ activeBtn = self.ui.btnDeleteMode
+ elif self.currentModeStack[-1] == SelectionMode.selectEdit:
+ activeBtn = self.ui.btnSelectEdit
+ else:
+ activeBtn = None
+
+
+ disableFill = isinstance(self.addMode, InplaceAddObj.AddBezierShape) and not self.currAddOptions['closedPath']
+ self.ui.btnFill.setEnabled(not disableFill)
+ if disableFill and self.ui.btnFill.isEnabled():
+ self.ui.btnFill.setChecked(not disableFill)
+
+
+ for button in self.modeButtons:
+ button.setChecked(button is activeBtn)
+
+ def updateChecks(self):
+ self.removeAddMode()
+ self.updateModeBtnsOnly()
+ self.quickUpdate()
+
+ def btnAlignXOnClick(self, checked):
+ self.lockY = checked
+ if self.lockX:
+ self.lockX = False
+ self.ui.btnAlignY.setChecked(False)
+
+ def btnAlignYOnClick(self, checked):
+ self.lockX = checked
+ if self.lockY:
+ self.lockY = False
+ self.ui.btnAlignX.setChecked(False)
+
+ def btnAnchorModeOnClick(self):
+ if self.currentModeStack[-1] != SelectionMode.setAnchor:
+ self.currentModeStack.append(SelectionMode.setAnchor)
+ self.updateChecks()
+
+ def switchToAnchorMode(self):
+ if self.currentModeStack[-1] != SelectionMode.setAnchor:
+ self.currentModeStack.append(SelectionMode.setAnchor)
+ self.updateChecks()
+
+ def btnTranslateonClick(self):
+ self.currentModeStack = [SelectionMode.translate]
+ self.ui.statusbar.showMessage('Translate mode')
+ self.clearSelection()
+ self.updateChecks()
+
+ def btnRotateOnClick(self):
+ self.currentModeStack = [SelectionMode.rotate]
+ self.ui.statusbar.showMessage('Rotate mode')
+ self.clearSelection()
+ self.updateChecks()
+
+ def btnScaleOnClick(self):
+ self.currentModeStack = [SelectionMode.scale]
+ self.ui.statusbar.showMessage('Scale mode')
+ self.clearSelection()
+ self.updateChecks()
+
+ def btnPanOnClick(self):
+ self.currentModeStack = [SelectionMode.pan]
+ self.ui.statusbar.showMessage('Pan mode')
+ self.clearSelection()
+ self.updateChecks()
+
+ def btnWorldCoordsOnClick(self, checked):
+ self.useGlobalCoords = checked
+ if not self.useGlobalCoords:
+ self.ui.comboAnchor.setCurrentIndex(AnchorMode.origin)
+ self.setAllInSetEnabled(self.globalTransformOnlyButtons, checked)
+
+ def setAllInSetEnabled(self, widgetSet, enabled):
+ for widget in widgetSet:
+ widget.setEnabled(enabled)
+
+ def btnDrawAxesOnClick(self, checked):
+ self.drawAxes = checked
+ self.quickUpdate()
+
+ def btnDrawGridOnClick(self, checked):
+ self.drawGrid = checked
+ self.quickUpdate()
+
+ def btnCustTransformOnClick(self):
+ matrixDialog = CustMatTransform.CustMatTransform()
+ matrixDialog.show()
+ result = matrixDialog.exec_()
+ if result == Qw.QDialog.Accepted:
+ objKey = self.currentlySelectedObj['selectedIndex']
+ self.transformObject(objKey,
+ matrixDialog.getTransformationMatrix(), not
+ self.useGlobalCoords)
+
+ # for now, unless we update the bouding box transformation.
+ self.clearSelection()
+ self.quickUpdate()
+
+ def btnLoadEditorOnClick(self):
+ if self.fileChanged:
+ save = "Save current file?"
+ reply = Qw.QMessageBox.question(self, 'Message', save, Qw.QMessageBox.Yes,
+ Qw.QMessageBox.No)
+ if reply == Qw.QMessageBox.Yes:
+ self.actionSave()
+
+ rawExternalEditor = self.settings['externalEditor']
+ rawExtEditorArgs = self.settings['externalEditorArgs']
+ execEditor = [rawExternalEditor]
+
+ for arg in rawExtEditorArgs:
+ execEditor.append(string.Template(
+ arg).substitute(asypath=(self.filename)))
+
+ subprocess.Popen(args=execEditor)
+
+ def btnAddCodeOnClick(self):
+ header = """
+// xasy object created at $time
+// Object Number: $uid
+// This header is automatically generated by xasy.
+// Your code here
+"""
+ header = string.Template(header).substitute(time=str(datetime.datetime.now()), uid=str(self.globalObjectCounter))
+
+ with tempfile.TemporaryDirectory() as tmpdir:
+ newPath = os.path.join(tmpdir, 'tmpcode.asy')
+ f = io.open(newPath, 'w')
+ f.write(header)
+ f.close()
+
+ subprocess.run(args=self.getExternalEditor(asypath=newPath))
+
+ f = io.open(newPath, 'r')
+ newItem = x2a.xasyScript(engine=self.asyEngine, canvas=self.xasyDrawObj)
+ newItem.setScript(f.read())
+ f.close()
+
+ # newItem.replaceKey(str(self.globalObjectCounter) + ':')
+ self.fileItems.append(newItem)
+ self.addObjCreationUrs(newItem)
+ self.asyfyCanvas()
+
+ self.globalObjectCounter = self.globalObjectCounter + 1
+ def softDeleteObj(self, objKey):
+ maj, minor = objKey
+ drawObj = self.drawObjects[maj][minor]
+ item = drawObj.originalObj
+ key = drawObj.key
+ keyIndex = drawObj.keyIndex
+
+
+ item.transfKeymap[key][keyIndex].deleted = True
+ # item.asyfied = False
+
+ def getSelectedObjInfo(self, objIndex):
+ maj, minor = objIndex
+ drawObj = self.drawObjects[maj][minor]
+ item = drawObj.originalObj
+ key = drawObj.key
+ keyIndex = drawObj.keyIndex
+
+ return item, key, keyIndex
+
+ def transformObjKey(self, item, key, keyIndex, transform, applyFirst=False, drawObj=None):
+ if isinstance(transform, np.ndarray):
+ obj_transform = x2a.asyTransform.fromNumpyMatrix(transform)
+ elif isinstance(transform, Qg.QTransform):
+ assert transform.isAffine()
+ obj_transform = x2a.asyTransform.fromQTransform(transform)
+ else:
+ obj_transform = transform
+
+ scr_transform = obj_transform
+
+ if not applyFirst:
+ item.transfKeymap[key][keyIndex] = obj_transform * \
+ item.transfKeymap[key][keyIndex]
+ if drawObj is not None:
+ drawObj.transform = scr_transform * drawObj.transform
+ else:
+ item.transfKeymap[key][keyIndex] = item.transfKeymap[key][keyIndex] * obj_transform
+ if drawObj is not None:
+ drawObj.transform = drawObj.transform * scr_transform
+
+ if self.selectAsGroup:
+ for (maj2, min2) in self.currentlySelectedObj['allSameKey']:
+ if (maj2, min2) == (maj, minor):
+ continue
+ obj = self.drawObjects[maj2][min2]
+ newIndex = obj.keyIndex
+ if not applyFirst:
+ item.transfKeymap[key][newIndex] = obj_transform * \
+ item.transfKeymap[key][newIndex]
+ obj.transform = scr_transform * obj.transform
+ else:
+ item.transfKeymap[key][newIndex] = item.transfKeymap[key][newIndex] * obj_transform
+ obj.transform = obj.transform * scr_transform
+
+ self.fileChanged = True
+ self.quickUpdate()
+
+ def transformObject(self, objKey, transform, applyFirst=False):
+ maj, minor = objKey
+ drawObj = self.drawObjects[maj][minor]
+ item, key, keyIndex = self.getSelectedObjInfo(objKey)
+ self.transformObjKey(item, key, keyIndex, transform, applyFirst, drawObj)
+
+ def initializeEmptyFile(self):
+ pass
+
+ def getExternalEditor(self, **kwargs) -> str:
+ editor = os.getenv("VISUAL")
+ if(editor == None) :
+ editor = os.getenv("EDITOR")
+ if(editor == None) :
+ rawExternalEditor = self.settings['externalEditor']
+ rawExtEditorArgs = self.settings['externalEditorArgs']
+ else:
+ s = editor.split()
+ rawExternalEditor = s[0]
+ rawExtEditorArgs = s[1:]+["$asypath"]
+
+ execEditor = [rawExternalEditor]
+
+ for arg in rawExtEditorArgs:
+ execEditor.append(string.Template(arg).substitute(**kwargs))
+
+ return execEditor
+
+
+ def loadFile(self, name):
+ filename = os.path.abspath(name)
+ if not os.path.isfile(filename):
+ filename = filename + '.asy'
+
+ if not os.path.isfile(filename):
+ self.ui.statusbar.showMessage('File {0} not found'.format(filename))
+ return
+
+ self.ui.statusbar.showMessage('Load {0}'.format(filename))
+ self.filename = filename
+ self.currDir = os.path.dirname(self.filename)
+
+ self.erase()
+
+ f = open(self.filename, 'rt')
+ try:
+ rawFileStr = f.read()
+ except IOError:
+ Qw.QMessageBox.critical(self, self.strings.fileOpenFailed, self.strings.fileOpenFailedText)
+ else:
+ rawText, transfDict, maxKey = xf.extractTransformsFromFile(rawFileStr)
+ item = x2a.xasyScript(canvas=self.xasyDrawObj, engine=self.asyEngine, transfKeyMap=transfDict)
+
+ item.setScript(rawText)
+ self.fileItems.append(item)
+ self.asyfyCanvas(True)
+
+ maxKey2 = item.getMaxKeyCounter()
+ self.asy2psmap = item.asy2psmap
+ self.globalObjectCounter = max(maxKey + 1, maxKey2)
+ finally:
+ f.close()
+
+ def populateCanvasWithItems(self, forceUpdate=False):
+ self.itemCount = 0
+ for item in self.fileItems:
+ self.drawObjects.append(item.generateDrawObjects(forceUpdate))
diff --git a/graphics/asymptote/GUI/__init__.py b/graphics/asymptote/GUI/__init__.py
new file mode 100644
index 0000000000..e5a0d9b483
--- /dev/null
+++ b/graphics/asymptote/GUI/__init__.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3
diff --git a/graphics/asymptote/GUI/configs/__init__.py b/graphics/asymptote/GUI/configs/__init__.py
new file mode 100644
index 0000000000..5f7ce86af6
--- /dev/null
+++ b/graphics/asymptote/GUI/configs/__init__.py
@@ -0,0 +1 @@
+#!/usr/bin/env python3 \ No newline at end of file
diff --git a/graphics/asymptote/GUI/configs/xasyconfig.cson b/graphics/asymptote/GUI/configs/xasyconfig.cson
new file mode 100644
index 0000000000..0b5d8bfc02
--- /dev/null
+++ b/graphics/asymptote/GUI/configs/xasyconfig.cson
@@ -0,0 +1,62 @@
+# Default Options for xasy
+
+# External editor. $asypath will be replaced by the current file.
+externalEditor: "emacs"
+externalEditorArgs: ["$asypath"]
+
+# Path to Asymptote executable
+asyPath: "asy"
+
+# Overwrites the ASYMPTOTE_DIR Environment variable if set. Otherwise, leaves asymptote to decide.
+asyBaseLocation: null
+
+# Show Debugging Information
+showDebug: false
+
+# Default Pen Options
+defaultPenOptions: ""
+
+# Default Pen Color
+defaultPenColor: "#000000"
+
+#
+defaultPenWidth: 0.5
+useLegacyDrawMode: false
+enableImmediatePreview: true
+useDegrees: false
+groupObjDefault: false
+
+#
+terminalFont: "Courier"
+terminalFontSize: 9
+
+#
+defaultShowAxes: true
+defaultShowGrid: false
+defaultGridSnap: false
+
+# Draw Selected Objects on top of the frame
+drawSelectedOnTop: true
+
+# Grid Settings
+
+gridMajorAxesColor: "#858585"
+gridMinorAxesColor: "#dddddd"
+gridMajorAxesSpacing: 5
+gridMinorAxesCount: 9
+
+# Magnification Settings
+minimumMagnification: 0.01
+maximumMagnification: 100
+
+# Debug Mode
+debugMode: true
+
+# Overrides
+
+windows:
+ externalEditor: "notepad.exe"
+
+Darwin:
+ externalEditor: "open"
+ externalEditorArgs: ["-a","TextEdit","$asypath"]
diff --git a/graphics/asymptote/GUI/configs/xasykeymap.cson b/graphics/asymptote/GUI/configs/xasykeymap.cson
new file mode 100644
index 0000000000..7ab1b34a2f
--- /dev/null
+++ b/graphics/asymptote/GUI/configs/xasykeymap.cson
@@ -0,0 +1,24 @@
+# Default Keymaps for xasy
+
+commandPalette: "Ctrl+P"
+quit: "Ctrl+Q"
+deleteObject: "Del"
+
+finalizeCurve: "Space"
+finalizeCurveClosed: "c"
+
+anchorMode: "Ctrl+A"
+
+undo: 'Ctrl+Z'
+redo: 'Ctrl+Y'
+
+moveUp: 'Up'
+moveDown: 'Down'
+
+scrollUp: 'Shift+Up'
+scrollDown: 'Shift+Down'
+scrollLeft: 'Shift+Left'
+scrollRight: 'Shift+Right'
+
+zoomIn: 'Ctrl+Up'
+zoomOut: 'Ctrl+Down' \ No newline at end of file
diff --git a/graphics/asymptote/GUI/icon-list.txt b/graphics/asymptote/GUI/icon-list.txt
new file mode 100644
index 0000000000..29e301cfd6
--- /dev/null
+++ b/graphics/asymptote/GUI/icon-list.txt
@@ -0,0 +1 @@
+https://superdevresources.com/free-svg-icons/ \ No newline at end of file
diff --git a/graphics/asymptote/GUI/icons_rc.py b/graphics/asymptote/GUI/icons_rc.py
new file mode 100644
index 0000000000..d1b18d19f4
--- /dev/null
+++ b/graphics/asymptote/GUI/icons_rc.py
@@ -0,0 +1,2680 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created by: The Resource Compiler for PyQt5 (Qt v5.11.3)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x03\x0c\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x68\x65\x63\x6b\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\
+\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
+\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
+\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
+\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
+\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
+\x4d\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x63\x2d\x30\
+\x2e\x34\x33\x35\x2c\x30\x2d\x30\x2e\x38\x34\x37\x2d\x30\x2e\x32\
+\x30\x33\x2d\x31\x2e\x31\x31\x31\x2d\x30\x2e\x35\x35\x33\x4c\x33\
+\x2e\x36\x31\x2c\x31\x31\x2e\x37\x32\x34\x63\x2d\x30\x2e\x34\x36\
+\x35\x2d\x30\x2e\x36\x31\x33\x2d\x30\x2e\x33\x34\x34\x2d\x31\x2e\
+\x34\x38\x36\x2c\x30\x2e\x32\x37\x2d\x31\x2e\x39\x35\x31\x0d\x0a\
+\x09\x63\x30\x2e\x36\x31\x35\x2d\x30\x2e\x34\x36\x37\x2c\x31\x2e\
+\x34\x38\x38\x2d\x30\x2e\x33\x34\x34\x2c\x31\x2e\x39\x35\x33\x2c\
+\x30\x2e\x32\x37\x6c\x32\x2e\x33\x35\x31\x2c\x33\x2e\x31\x30\x34\
+\x6c\x35\x2e\x39\x31\x31\x2d\x39\x2e\x34\x39\x32\x63\x30\x2e\x34\
+\x30\x37\x2d\x30\x2e\x36\x35\x32\x2c\x31\x2e\x32\x36\x37\x2d\x30\
+\x2e\x38\x35\x32\x2c\x31\x2e\x39\x32\x31\x2d\x30\x2e\x34\x34\x35\
+\x0d\x0a\x09\x63\x30\x2e\x36\x35\x33\x2c\x30\x2e\x34\x30\x36\x2c\
+\x30\x2e\x38\x35\x34\x2c\x31\x2e\x32\x36\x36\x2c\x30\x2e\x34\x34\
+\x36\x2c\x31\x2e\x39\x32\x4c\x39\x2e\x34\x37\x38\x2c\x31\x36\x2e\
+\x33\x34\x63\x2d\x30\x2e\x32\x34\x32\x2c\x30\x2e\x33\x39\x31\x2d\
+\x30\x2e\x36\x36\x31\x2c\x30\x2e\x36\x33\x35\x2d\x31\x2e\x31\x32\
+\x2c\x30\x2e\x36\x35\x36\x43\x38\x2e\x33\x33\x36\x2c\x31\x36\x2e\
+\x39\x39\x38\x2c\x38\x2e\x33\x31\x36\x2c\x31\x36\x2e\x39\x39\x38\
+\x2c\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x00\x6c\
+\x3c\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
+\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
+\x20\x64\x3d\x22\x4d\x31\x38\x20\x31\x32\x76\x31\x48\x38\x76\x35\
+\x6c\x2d\x36\x2d\x36\x20\x36\x2d\x36\x76\x35\x68\x38\x56\x32\x68\
+\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\x26\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x33\x38\
+\x38\x63\x2d\x37\x32\x2e\x35\x39\x37\x2c\x30\x2d\x31\x33\x32\x2d\
+\x35\x39\x2e\x34\x30\x35\x2d\x31\x33\x32\x2d\x31\x33\x32\x63\x30\
+\x2d\x37\x32\x2e\x36\x30\x31\x2c\x35\x39\x2e\x34\x30\x33\x2d\x31\
+\x33\x32\x2c\x31\x33\x32\x2d\x31\x33\x32\x63\x33\x36\x2e\x33\x2c\
+\x30\x2c\x36\x39\x2e\x32\x39\x39\x2c\x31\x35\x2e\x34\x2c\x39\x32\
+\x2e\x34\x30\x36\x2c\x33\x39\x2e\x36\x30\x31\x4c\x32\x37\x38\x2c\
+\x32\x33\x34\x68\x31\x35\x34\x56\x38\x30\x0d\x0a\x09\x09\x6c\x2d\
+\x35\x31\x2e\x36\x39\x38\x2c\x35\x31\x2e\x37\x30\x32\x43\x33\x34\
+\x38\x2e\x34\x30\x36\x2c\x39\x39\x2e\x37\x39\x38\x2c\x33\x30\x34\
+\x2e\x34\x30\x36\x2c\x38\x30\x2c\x32\x35\x36\x2c\x38\x30\x63\x2d\
+\x39\x36\x2e\x37\x39\x37\x2c\x30\x2d\x31\x37\x36\x2c\x37\x39\x2e\
+\x32\x30\x33\x2d\x31\x37\x36\x2c\x31\x37\x36\x73\x37\x38\x2e\x30\
+\x39\x34\x2c\x31\x37\x36\x2c\x31\x37\x36\x2c\x31\x37\x36\x0d\x0a\
+\x09\x09\x63\x38\x31\x2e\x30\x34\x35\x2c\x30\x2c\x31\x34\x38\x2e\
+\x32\x38\x37\x2d\x35\x34\x2e\x31\x33\x34\x2c\x31\x36\x39\x2e\x34\
+\x30\x31\x2d\x31\x32\x38\x48\x33\x37\x38\x2e\x38\x35\x43\x33\x36\
+\x30\x2e\x31\x30\x35\x2c\x33\x35\x33\x2e\x35\x36\x31\x2c\x33\x31\
+\x31\x2e\x37\x31\x32\x2c\x33\x38\x38\x2c\x32\x35\x36\x2c\x33\x38\
+\x38\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
+\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\x6c\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x53\x61\x76\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
+\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
+\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
+\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\x3d\
+\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
+\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
+\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
+\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
+\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
+\x31\x35\x2e\x31\x37\x33\x2c\x32\x48\x34\x43\x32\x2e\x38\x39\x39\
+\x2c\x32\x2c\x32\x2c\x32\x2e\x39\x2c\x32\x2c\x34\x76\x31\x32\x63\
+\x30\x2c\x31\x2e\x31\x2c\x30\x2e\x38\x39\x39\x2c\x32\x2c\x32\x2c\
+\x32\x68\x31\x32\x63\x31\x2e\x31\x30\x31\x2c\x30\x2c\x32\x2d\x30\
+\x2e\x39\x2c\x32\x2d\x32\x56\x35\x2e\x31\x32\x37\x4c\x31\x35\x2e\
+\x31\x37\x33\x2c\x32\x7a\x20\x4d\x31\x34\x2c\x38\x63\x30\x2c\x30\
+\x2e\x35\x34\x39\x2d\x30\x2e\x34\x35\x2c\x31\x2d\x31\x2c\x31\x48\
+\x37\x0d\x0a\x09\x43\x36\x2e\x34\x35\x2c\x39\x2c\x36\x2c\x38\x2e\
+\x35\x34\x39\x2c\x36\x2c\x38\x56\x33\x68\x38\x56\x38\x7a\x20\x4d\
+\x31\x33\x2c\x34\x68\x2d\x32\x76\x34\x68\x32\x56\x34\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x05\xca\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
+\x64\x3d\x22\x4d\x34\x35\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\
+\x35\x63\x2d\x31\x34\x2e\x35\x38\x35\x2d\x31\x34\x2e\x35\x37\x37\
+\x2d\x33\x36\x2e\x30\x35\x34\x2d\x31\x35\x2e\x38\x39\x2d\x35\x30\
+\x2e\x36\x33\x39\x2d\x31\x2e\x33\x31\x32\x6c\x2d\x34\x31\x2e\x36\
+\x38\x37\x2c\x34\x31\x2e\x36\x36\x34\x63\x2d\x31\x30\x2e\x38\x35\
+\x32\x2c\x31\x30\x2e\x38\x33\x36\x2d\x32\x33\x2e\x39\x33\x2c\x31\
+\x30\x2e\x38\x35\x39\x2d\x33\x31\x2e\x35\x36\x34\x2c\x31\x2e\x38\
+\x35\x32\x0d\x0a\x09\x63\x2d\x35\x2e\x30\x35\x37\x2d\x35\x2e\x39\
+\x36\x38\x2d\x33\x2e\x30\x36\x31\x2d\x32\x34\x2e\x33\x37\x34\x2d\
+\x31\x2e\x36\x34\x34\x2d\x33\x36\x2e\x30\x34\x39\x6c\x32\x30\x2e\
+\x39\x30\x37\x2d\x31\x37\x31\x2e\x38\x34\x39\x63\x31\x2e\x38\x36\
+\x37\x2d\x31\x35\x2e\x33\x35\x33\x2d\x39\x2e\x30\x37\x2d\x33\x30\
+\x2e\x31\x38\x35\x2d\x32\x34\x2e\x34\x33\x2d\x33\x32\x2e\x30\x35\
+\x31\x0d\x0a\x09\x63\x2d\x31\x35\x2e\x33\x35\x38\x2d\x31\x2e\x38\
+\x36\x37\x2d\x32\x39\x2e\x33\x32\x32\x2c\x39\x2e\x39\x33\x39\x2d\
+\x33\x31\x2e\x31\x39\x31\x2c\x32\x35\x2e\x32\x38\x39\x4c\x32\x36\
+\x37\x2e\x33\x37\x2c\x32\x33\x36\x2e\x30\x32\x31\x63\x2d\x31\x2e\
+\x32\x30\x35\x2c\x33\x2e\x33\x35\x38\x2d\x33\x2e\x37\x39\x2c\x33\
+\x2e\x39\x33\x38\x2d\x34\x2e\x30\x38\x31\x2d\x30\x2e\x35\x38\x32\
+\x4c\x32\x35\x35\x2e\x34\x34\x2c\x36\x30\x0d\x0a\x09\x63\x30\x2d\
+\x31\x35\x2e\x34\x36\x35\x2d\x31\x32\x2e\x35\x34\x32\x2d\x32\x38\
+\x2d\x32\x38\x2e\x30\x31\x34\x2d\x32\x38\x63\x2d\x31\x35\x2e\x34\
+\x37\x33\x2c\x30\x2d\x32\x38\x2e\x30\x31\x35\x2c\x31\x32\x2e\x35\
+\x33\x35\x2d\x32\x38\x2e\x30\x31\x35\x2c\x32\x38\x6c\x2d\x30\x2e\
+\x35\x35\x32\x2c\x31\x37\x36\x2e\x37\x35\x32\x63\x30\x2e\x31\x34\
+\x36\x2c\x32\x2e\x30\x34\x2d\x31\x2e\x36\x30\x34\x2c\x32\x2e\x36\
+\x32\x34\x2d\x31\x2e\x39\x32\x2c\x30\x2e\x32\x39\x34\x4c\x31\x37\
+\x32\x2e\x30\x31\x36\x2c\x39\x39\x2e\x30\x37\x37\x0d\x0a\x09\x63\
+\x2d\x32\x2e\x37\x35\x2d\x31\x35\x2e\x32\x31\x39\x2d\x31\x37\x2e\
+\x33\x32\x33\x2d\x32\x36\x2e\x32\x30\x33\x2d\x33\x32\x2e\x35\x34\
+\x38\x2d\x32\x33\x2e\x34\x35\x33\x63\x2d\x31\x35\x2e\x32\x32\x37\
+\x2c\x32\x2e\x37\x34\x38\x2d\x32\x35\x2e\x33\x33\x39\x2c\x31\x38\
+\x2e\x31\x38\x37\x2d\x32\x32\x2e\x35\x39\x31\x2c\x33\x33\x2e\x34\
+\x30\x33\x6c\x32\x32\x2e\x31\x39\x33\x2c\x31\x36\x31\x2e\x34\x35\
+\x35\x0d\x0a\x09\x63\x30\x2e\x30\x32\x33\x2c\x32\x2e\x38\x37\x32\
+\x2d\x30\x2e\x39\x34\x31\x2c\x34\x2e\x35\x31\x33\x2d\x32\x2e\x33\
+\x30\x38\x2c\x30\x2e\x38\x33\x31\x6c\x2d\x33\x33\x2e\x31\x30\x39\
+\x2d\x38\x38\x2e\x35\x31\x37\x63\x2d\x35\x2e\x31\x38\x2d\x31\x34\
+\x2e\x35\x37\x32\x2d\x32\x31\x2e\x31\x39\x36\x2d\x32\x33\x2e\x30\
+\x36\x35\x2d\x33\x35\x2e\x37\x37\x36\x2d\x31\x37\x2e\x38\x38\x39\
+\x0d\x0a\x09\x63\x2d\x31\x34\x2e\x35\x37\x39\x2c\x35\x2e\x31\x37\
+\x37\x2d\x32\x32\x2e\x32\x30\x31\x2c\x32\x32\x2e\x30\x36\x31\x2d\
+\x31\x37\x2e\x30\x32\x33\x2c\x33\x36\x2e\x36\x33\x31\x6c\x35\x38\
+\x2e\x30\x34\x32\x2c\x31\x38\x39\x2e\x36\x32\x35\x63\x30\x2e\x33\
+\x30\x33\x2c\x31\x2e\x30\x34\x36\x2c\x30\x2e\x36\x32\x34\x2c\x32\
+\x2e\x30\x38\x35\x2c\x30\x2e\x39\x35\x33\x2c\x33\x2e\x31\x31\x38\
+\x6c\x30\x2e\x31\x32\x31\x2c\x30\x2e\x33\x39\x0d\x0a\x09\x63\x30\
+\x2e\x30\x31\x31\x2c\x30\x2e\x30\x33\x31\x2c\x30\x2e\x30\x32\x35\
+\x2c\x30\x2e\x30\x35\x38\x2c\x30\x2e\x30\x33\x35\x2c\x30\x2e\x30\
+\x38\x38\x43\x31\x32\x36\x2e\x30\x37\x39\x2c\x34\x34\x34\x2e\x32\
+\x33\x33\x2c\x31\x37\x32\x2e\x35\x37\x2c\x34\x38\x30\x2c\x32\x32\
+\x37\x2e\x34\x32\x37\x2c\x34\x38\x30\x63\x33\x35\x2e\x31\x31\x36\
+\x2c\x30\x2c\x37\x31\x2e\x35\x39\x31\x2d\x31\x32\x2e\x33\x37\x38\
+\x2c\x39\x39\x2e\x33\x35\x37\x2d\x33\x33\x2e\x36\x37\x32\x0d\x0a\
+\x09\x63\x30\x2e\x30\x30\x31\x2c\x30\x2c\x30\x2e\x30\x30\x33\x2d\
+\x30\x2e\x30\x30\x32\x2c\x30\x2e\x30\x30\x33\x2d\x30\x2e\x30\x30\
+\x32\x63\x32\x39\x2e\x39\x39\x2d\x31\x38\x2e\x30\x35\x31\x2c\x31\
+\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x2c\x31\
+\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x43\x34\
+\x36\x37\x2e\x34\x34\x35\x2c\x33\x31\x30\x2e\x34\x30\x32\x2c\x34\
+\x36\x35\x2e\x32\x36\x36\x2c\x32\x38\x38\x2e\x30\x38\x2c\x34\x35\
+\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\x35\x7a\x22\x2f\x3e\x0d\
+\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\xca\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\x72\
+\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\x75\
+\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x39\x2e\x32\x2e\x31\x2c\x20\
+\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\x2d\
+\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\x6e\
+\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\x20\
+\x20\x2d\x2d\x3e\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\
+\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\
+\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\
+\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\
+\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\
+\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\
+\x31\x2e\x64\x74\x64\x22\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\
+\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x09\x20\x69\x64\x3d\
+\x22\x73\x76\x67\x34\x36\x31\x39\x22\x20\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\
+\x2b\x64\x65\x76\x65\x6c\x2b\x6f\x73\x78\x6d\x65\x6e\x75\x20\x72\
+\x31\x32\x39\x31\x31\x22\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\
+\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x74\x72\x69\x61\x6e\x67\x6c\
+\x65\x2d\x73\x74\x72\x6f\x6b\x65\x64\x2d\x31\x35\x2e\x73\x76\x67\
+\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
+\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
+\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\
+\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\
+\x73\x2f\x31\x2e\x31\x2f\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\
+\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\
+\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\
+\x61\x70\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\
+\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x20\x78\x6d\x6c\
+\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\x74\
+\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\x75\
+\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\x44\
+\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\x22\
+\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\
+\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\
+\x30\x30\x2f\x73\x76\x67\x22\x0a\x09\x20\x78\x6d\x6c\x6e\x73\x3d\
+\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
+\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\
+\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\
+\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\
+\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\
+\x79\x3d\x22\x30\x70\x78\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x31\
+\x35\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x35\x70\
+\x78\x22\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
+\x30\x20\x31\x35\x20\x31\x35\x22\x20\x73\x74\x79\x6c\x65\x3d\x22\
+\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
+\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\x31\x35\x20\x31\x35\x3b\
+\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\
+\x73\x65\x72\x76\x65\x22\x3e\x0a\x3c\x70\x61\x74\x68\x20\x69\x64\
+\x3d\x22\x72\x65\x63\x74\x33\x33\x33\x38\x22\x20\x69\x6e\x6b\x73\
+\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\
+\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x73\x6f\x64\
+\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\
+\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x64\
+\x3d\x22\x4d\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\
+\x0a\x09\x43\x37\x2e\x32\x34\x32\x39\x2c\x31\x2e\x34\x39\x31\x33\
+\x2c\x36\x2e\x39\x37\x38\x37\x2c\x31\x2e\x36\x34\x32\x33\x2c\x36\
+\x2e\x38\x33\x33\x36\x2c\x31\x2e\x38\x39\x35\x32\x6c\x2d\x35\x2e\
+\x35\x2c\x39\x2e\x38\x36\x39\x32\x43\x31\x2e\x30\x32\x31\x38\x2c\
+\x31\x32\x2e\x33\x30\x37\x38\x2c\x31\x2e\x33\x39\x35\x2c\x31\x32\
+\x2e\x39\x39\x39\x39\x2c\x32\x2c\x31\x33\x68\x31\x31\x0a\x09\x63\
+\x30\x2e\x36\x30\x35\x2d\x30\x2e\x30\x30\x30\x31\x2c\x30\x2e\x39\
+\x37\x38\x32\x2d\x30\x2e\x36\x39\x32\x32\x2c\x30\x2e\x36\x36\x36\
+\x34\x2d\x31\x2e\x32\x33\x35\x35\x6c\x2d\x35\x2e\x35\x2d\x39\x2e\
+\x38\x36\x39\x32\x43\x38\x2e\x30\x33\x30\x32\x2c\x31\x2e\x36\x35\
+\x37\x39\x2c\x37\x2e\x37\x38\x38\x34\x2c\x31\x2e\x35\x30\x39\x32\
+\x2c\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\x7a\x20\
+\x4d\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x6c\x34\x2e\x31\x32\
+\x36\x37\x2c\x37\x2e\x34\x37\x30\x34\x0a\x09\x48\x33\x2e\x33\x37\
+\x33\x33\x4c\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x7a\x22\x2f\
+\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
+\x00\x00\x03\x6c\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x0d\x0a\x09\x09\x3c\x72\x65\x63\x74\x20\x78\x3d\x22\x31\x37\x38\
+\x2e\x38\x34\x36\x22\x20\x79\x3d\x22\x39\x32\x2e\x30\x38\x37\x22\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\
+\x69\x78\x28\x2d\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\
+\x37\x31\x20\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\x37\
+\x31\x20\x32\x32\x34\x2e\x33\x34\x37\x36\x20\x36\x33\x31\x2e\x31\
+\x34\x39\x38\x29\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\x38\
+\x2e\x30\x38\x35\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x35\
+\x34\x2e\x30\x34\x39\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\
+\x20\x64\x3d\x22\x4d\x34\x37\x31\x2e\x37\x32\x33\x2c\x38\x38\x2e\
+\x33\x39\x33\x6c\x2d\x34\x38\x2e\x31\x31\x35\x2d\x34\x38\x2e\x31\
+\x31\x34\x63\x2d\x31\x31\x2e\x37\x32\x33\x2d\x31\x31\x2e\x37\x32\
+\x34\x2d\x33\x31\x2e\x35\x35\x38\x2d\x31\x30\x2e\x38\x39\x36\x2d\
+\x34\x34\x2e\x33\x30\x34\x2c\x31\x2e\x38\x35\x6c\x2d\x34\x35\x2e\
+\x32\x30\x32\x2c\x34\x35\x2e\x32\x30\x33\x6c\x39\x30\x2e\x35\x36\
+\x39\x2c\x39\x30\x2e\x35\x36\x38\x6c\x34\x35\x2e\x32\x30\x32\x2d\
+\x34\x35\x2e\x32\x30\x32\x0d\x0a\x09\x09\x43\x34\x38\x32\x2e\x36\
+\x31\x36\x2c\x31\x31\x39\x2e\x39\x35\x32\x2c\x34\x38\x33\x2e\x34\
+\x34\x35\x2c\x31\x30\x30\x2e\x31\x31\x36\x2c\x34\x37\x31\x2e\x37\
+\x32\x33\x2c\x38\x38\x2e\x33\x39\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\
+\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
+\x22\x36\x34\x2e\x30\x32\x31\x2c\x33\x36\x33\x2e\x32\x35\x32\x20\
+\x33\x32\x2c\x34\x38\x30\x20\x31\x34\x38\x2e\x37\x33\x37\x2c\x34\
+\x34\x37\x2e\x39\x37\x39\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\x64\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\x09\
+\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x31\
+\x37\x36\x63\x2d\x34\x34\x2e\x30\x30\x34\x2c\x30\x2d\x38\x30\x2e\
+\x30\x30\x31\x2c\x33\x36\x2d\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\
+\x63\x30\x2c\x34\x34\x2e\x30\x30\x34\x2c\x33\x35\x2e\x39\x39\x37\
+\x2c\x38\x30\x2c\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\x63\x34\x34\
+\x2e\x30\x30\x35\x2c\x30\x2c\x37\x39\x2e\x39\x39\x39\x2d\x33\x35\
+\x2e\x39\x39\x36\x2c\x37\x39\x2e\x39\x39\x39\x2d\x38\x30\x0d\x0a\
+\x09\x09\x09\x43\x33\x33\x35\x2e\x39\x39\x39\x2c\x32\x31\x32\x2c\
+\x33\x30\x30\x2e\x30\x30\x35\x2c\x31\x37\x36\x2c\x32\x35\x36\x2c\
+\x31\x37\x36\x7a\x20\x4d\x34\x34\x36\x2e\x39\x33\x38\x2c\x32\x33\
+\x34\x2e\x36\x36\x37\x63\x2d\x39\x2e\x36\x30\x35\x2d\x38\x38\x2e\
+\x35\x33\x31\x2d\x38\x31\x2e\x30\x37\x34\x2d\x31\x36\x30\x2d\x31\
+\x36\x39\x2e\x36\x30\x35\x2d\x31\x36\x39\x2e\x35\x39\x39\x56\x33\
+\x32\x68\x2d\x34\x32\x2e\x36\x36\x36\x76\x33\x33\x2e\x30\x36\x37\
+\x0d\x0a\x09\x09\x09\x63\x2d\x38\x38\x2e\x35\x33\x31\x2c\x39\x2e\
+\x35\x39\x39\x2d\x31\x36\x30\x2c\x38\x31\x2e\x30\x36\x38\x2d\x31\
+\x36\x39\x2e\x36\x30\x34\x2c\x31\x36\x39\x2e\x35\x39\x39\x48\x33\
+\x32\x76\x34\x32\x2e\x36\x36\x37\x68\x33\x33\x2e\x30\x36\x32\x63\
+\x39\x2e\x36\x30\x34\x2c\x38\x38\x2e\x35\x33\x31\x2c\x38\x31\x2e\
+\x30\x37\x32\x2c\x31\x36\x30\x2c\x31\x36\x39\x2e\x36\x30\x34\x2c\
+\x31\x36\x39\x2e\x36\x30\x34\x56\x34\x38\x30\x68\x34\x32\x2e\x36\
+\x36\x36\x76\x2d\x33\x33\x2e\x30\x36\x32\x0d\x0a\x09\x09\x09\x63\
+\x38\x38\x2e\x35\x33\x31\x2d\x39\x2e\x36\x30\x34\x2c\x31\x36\x30\
+\x2d\x38\x31\x2e\x30\x37\x33\x2c\x31\x36\x39\x2e\x36\x30\x35\x2d\
+\x31\x36\x39\x2e\x36\x30\x34\x48\x34\x38\x30\x76\x2d\x34\x32\x2e\
+\x36\x36\x37\x48\x34\x34\x36\x2e\x39\x33\x38\x7a\x20\x4d\x32\x35\
+\x36\x2c\x34\x30\x35\x2e\x33\x33\x33\x63\x2d\x38\x32\x2e\x31\x33\
+\x37\x2c\x30\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x36\x37\x2e\x31\
+\x39\x38\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\
+\x33\x33\x0d\x0a\x09\x09\x09\x63\x30\x2d\x38\x32\x2e\x31\x33\x36\
+\x2c\x36\x37\x2e\x31\x39\x37\x2d\x31\x34\x39\x2e\x33\x33\x33\x2c\
+\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\x33\x33\x63\
+\x38\x32\x2e\x31\x33\x35\x2c\x30\x2c\x31\x34\x39\x2e\x33\x33\x32\
+\x2c\x36\x37\x2e\x31\x39\x38\x2c\x31\x34\x39\x2e\x33\x33\x32\x2c\
+\x31\x34\x39\x2e\x33\x33\x33\x43\x34\x30\x35\x2e\x33\x33\x32\x2c\
+\x33\x33\x38\x2e\x31\x33\x35\x2c\x33\x33\x38\x2e\x31\x33\x35\x2c\
+\x34\x30\x35\x2e\x33\x33\x33\x2c\x32\x35\x36\x2c\x34\x30\x35\x2e\
+\x33\x33\x33\x7a\x0d\x0a\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x3c\
+\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
+\x3e\x0d\x0a\
+\x00\x00\x04\x22\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x32\x34\x70\x74\x27\x20\x76\x65\x72\x73\x69\x6f\x6e\
+\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x27\
+\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\x38\x33\x20\
+\x32\x34\x20\x32\x34\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x32\x34\
+\x70\x74\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
+\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
+\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
+\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
+\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x39\x2e\x33\x39\
+\x31\x31\x38\x20\x2d\x30\x4c\x20\x2d\x36\x2e\x36\x34\x30\x35\x37\
+\x20\x2d\x31\x32\x2e\x30\x34\x35\x4c\x20\x38\x2e\x36\x37\x36\x33\
+\x32\x20\x2d\x36\x2e\x35\x31\x38\x37\x31\x4c\x20\x33\x2e\x33\x32\
+\x30\x32\x38\x20\x36\x2e\x30\x32\x32\x35\x27\x20\x66\x69\x6c\x6c\
+\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
+\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\
+\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\
+\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\
+\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\
+\x3d\x27\x31\x2e\x37\x35\x36\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
+\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\
+\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\
+\x39\x31\x31\x38\x27\x20\x63\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\
+\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\
+\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\
+\x35\x37\x27\x20\x63\x79\x3d\x27\x2d\x31\x32\x2e\x30\x34\x35\x27\
+\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\
+\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\
+\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
+\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\
+\x2e\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\
+\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\
+\x37\x36\x33\x32\x27\x20\x63\x79\x3d\x27\x2d\x36\x2e\x35\x31\x38\
+\x37\x31\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\
+\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\
+\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\
+\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\
+\x33\x2e\x33\x32\x30\x32\x38\x27\x20\x63\x79\x3d\x27\x36\x2e\x30\
+\x32\x32\x35\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\
+\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\
+\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\
+\x3e\
+\x00\x00\x03\x4c\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x32\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
+\x35\x36\x2c\x31\x35\x32\x63\x2d\x35\x37\x2e\x32\x2c\x30\x2d\x31\
+\x30\x34\x2c\x34\x36\x2e\x38\x2d\x31\x30\x34\x2c\x31\x30\x34\x73\
+\x34\x36\x2e\x38\x2c\x31\x30\x34\x2c\x31\x30\x34\x2c\x31\x30\x34\
+\x73\x31\x30\x34\x2d\x34\x36\x2e\x38\x2c\x31\x30\x34\x2d\x31\x30\
+\x34\x53\x33\x31\x33\x2e\x32\x2c\x31\x35\x32\x2c\x32\x35\x36\x2c\
+\x31\x35\x32\x7a\x20\x4d\x32\x35\x36\x2c\x34\x38\x0d\x0a\x09\x09\
+\x09\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x34\x38\x2c\
+\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\x35\x36\x73\x39\
+\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\x38\x2c\x32\x30\
+\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\
+\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\x2c\x34\x38\x2c\
+\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\x2c\x34\x32\x32\
+\x2e\x34\x0d\x0a\x09\x09\x09\x63\x2d\x39\x31\x2e\x35\x31\x38\x2c\
+\x30\x2d\x31\x36\x36\x2e\x34\x2d\x37\x34\x2e\x38\x38\x33\x2d\x31\
+\x36\x36\x2e\x34\x2d\x31\x36\x36\x2e\x34\x53\x31\x36\x34\x2e\x34\
+\x38\x32\x2c\x38\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\
+\x53\x34\x32\x32\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\
+\x32\x32\x2e\x34\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\
+\x2c\x34\x32\x32\x2e\x34\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x34\
+\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\xbd\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x69\x72\x63\x6c\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\
+\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
+\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\
+\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\
+\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\
+\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\
+\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\
+\x6f\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\
+\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\
+\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\
+\x22\x4d\x31\x30\x2c\x30\x2e\x34\x43\x34\x2e\x36\x39\x38\x2c\x30\
+\x2e\x34\x2c\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\x2c\x30\x2e\x34\
+\x2c\x31\x30\x43\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x32\x2c\x34\
+\x2e\x36\x39\x38\x2c\x31\x39\x2e\x36\x2c\x31\x30\x2c\x31\x39\x2e\
+\x36\x63\x35\x2e\x33\x30\x31\x2c\x30\x2c\x39\x2e\x36\x2d\x34\x2e\
+\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x30\x31\x0d\x0a\x09\
+\x43\x31\x39\x2e\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\x33\
+\x30\x31\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\
+\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x63\x2d\x34\x2e\x31\x39\x37\
+\x2c\x30\x2d\x37\x2e\x36\x2d\x33\x2e\x34\x30\x32\x2d\x37\x2e\x36\
+\x2d\x37\x2e\x36\x53\x35\x2e\x38\x30\x32\x2c\x32\x2e\x34\x2c\x31\
+\x30\x2c\x32\x2e\x34\x63\x34\x2e\x31\x39\x37\x2c\x30\x2c\x37\x2e\
+\x36\x30\x31\x2c\x33\x2e\x34\x30\x32\x2c\x37\x2e\x36\x30\x31\x2c\
+\x37\x2e\x36\x0d\x0a\x09\x53\x31\x34\x2e\x31\x39\x37\x2c\x31\x37\
+\x2e\x35\x39\x39\x2c\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x7a\x22\
+\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x05\xb7\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x32\x34\x70\x74\x27\x20\x76\x65\x72\x73\x69\x6f\x6e\
+\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x27\
+\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\x38\x33\x20\
+\x31\x38\x2e\x34\x33\x37\x35\x20\x32\x34\x27\x20\x77\x69\x64\x74\
+\x68\x3d\x27\x31\x38\x2e\x34\x33\x37\x35\x70\x74\x27\x20\x78\x6d\
+\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\
+\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\
+\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\
+\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\
+\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x27\x3e\x0a\x3c\x67\x20\
+\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\
+\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
+\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
+\x39\x39\x36\x32\x36\x34\x20\x36\x35\x2e\x36\x32\x38\x32\x20\x37\
+\x34\x2e\x32\x30\x32\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\
+\x3d\x27\x4d\x20\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x31\x2e\
+\x31\x36\x36\x37\x43\x20\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\
+\x32\x2e\x37\x30\x38\x35\x20\x34\x2e\x36\x32\x35\x34\x31\x20\x2d\
+\x31\x33\x2e\x39\x35\x38\x34\x20\x30\x20\x2d\x31\x33\x2e\x39\x35\
+\x38\x34\x43\x20\x2d\x34\x2e\x36\x32\x35\x34\x31\x20\x2d\x31\x33\
+\x2e\x39\x35\x38\x34\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\
+\x31\x32\x2e\x37\x30\x38\x35\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\
+\x20\x2d\x31\x31\x2e\x31\x36\x36\x37\x43\x20\x2d\x38\x2e\x33\x37\
+\x35\x30\x34\x20\x2d\x39\x2e\x36\x32\x34\x39\x32\x20\x2d\x34\x2e\
+\x36\x32\x35\x34\x31\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x30\
+\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x43\x20\x34\x2e\x36\x32\x35\
+\x34\x31\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x38\x2e\x33\x37\
+\x35\x30\x34\x20\x2d\x39\x2e\x36\x32\x34\x39\x32\x20\x38\x2e\x33\
+\x37\x35\x30\x34\x20\x2d\x31\x31\x2e\x31\x36\x36\x37\x5a\x27\x20\
+\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\
+\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\
+\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\
+\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\
+\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\
+\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\
+\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\x36\x35\x36\x27\x2f\x3e\
+\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x36\x35\x2e\x36\x32\x38\x32\x20\x37\x34\x2e\x32\x30\x32\x29\
+\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x38\
+\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x31\x2e\x31\x36\x36\x37\x4c\
+\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x30\x4c\x20\x2d\x38\
+\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x2e\x38\x35\x39\x36\x33\x65\
+\x2d\x31\x35\x43\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\
+\x2e\x32\x33\x39\x37\x35\x65\x2d\x31\x35\x20\x2d\x38\x2e\x33\x37\
+\x35\x30\x34\x20\x2d\x36\x2e\x31\x39\x38\x37\x37\x65\x2d\x31\x36\
+\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x30\x43\x20\x2d\x38\
+\x2e\x33\x37\x35\x30\x34\x20\x31\x2e\x35\x34\x31\x38\x20\x2d\x34\
+\x2e\x36\x32\x35\x34\x31\x20\x32\x2e\x37\x39\x31\x36\x38\x20\x30\
+\x20\x32\x2e\x37\x39\x31\x36\x38\x43\x20\x34\x2e\x36\x32\x35\x34\
+\x31\x20\x32\x2e\x37\x39\x31\x36\x38\x20\x38\x2e\x33\x37\x35\x30\
+\x34\x20\x31\x2e\x35\x34\x31\x38\x20\x38\x2e\x33\x37\x35\x30\x34\
+\x20\x30\x4c\x20\x38\x2e\x33\x37\x35\x30\x34\x20\x30\x4c\x20\x38\
+\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x31\x2e\x31\x36\x36\x37\x27\
+\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\
+\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\
+\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\
+\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\x36\x35\x36\x27\x2f\
+\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\
+\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\
+\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\
+\x34\x20\x36\x35\x2e\x36\x32\x38\x32\x20\x37\x34\x2e\x32\x30\x32\
+\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x38\
+\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x31\x2e\x31\x36\x36\x37\x43\
+\x20\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x35\x2e\x37\x39\x32\
+\x31\x20\x34\x2e\x36\x32\x35\x34\x31\x20\x2d\x31\x39\x2e\x35\x34\
+\x31\x38\x20\x30\x20\x2d\x31\x39\x2e\x35\x34\x31\x38\x43\x20\x2d\
+\x34\x2e\x36\x32\x35\x34\x31\x20\x2d\x31\x39\x2e\x35\x34\x31\x38\
+\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x35\x2e\x37\x39\
+\x32\x31\x20\x2d\x38\x2e\x33\x37\x35\x30\x34\x20\x2d\x31\x31\x2e\
+\x31\x36\x36\x37\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\
+\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\
+\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\
+\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\
+\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\
+\x36\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\
+\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x02\xb7\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x35\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
+\x6e\x74\x73\x3d\x22\x34\x30\x35\x2c\x31\x33\x36\x2e\x37\x39\x38\
+\x20\x33\x37\x35\x2e\x32\x30\x32\x2c\x31\x30\x37\x20\x32\x35\x36\
+\x2c\x32\x32\x36\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
+\x2c\x31\x30\x37\x20\x31\x30\x37\x2c\x31\x33\x36\x2e\x37\x39\x38\
+\x20\x32\x32\x36\x2e\x32\x30\x32\x2c\x32\x35\x36\x20\x31\x30\x37\
+\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
+\x2c\x34\x30\x35\x20\x32\x35\x36\x2c\x32\x38\x35\x2e\x37\x39\x38\
+\x20\x0d\x0a\x09\x09\x09\x33\x37\x35\x2e\x32\x30\x32\x2c\x34\x30\
+\x35\x20\x34\x30\x35\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x32\x38\
+\x35\x2e\x37\x39\x38\x2c\x32\x35\x36\x20\x09\x09\x22\x2f\x3e\x0d\
+\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\xfc\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x32\x30\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
+\x35\x36\x2c\x34\x38\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\
+\x2c\x34\x38\x2c\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\
+\x35\x36\x73\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\
+\x38\x2c\x32\x30\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\
+\x2c\x32\x30\x38\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\
+\x2c\x34\x38\x2c\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\
+\x2c\x34\x32\x32\x2e\x33\x39\x39\x0d\x0a\x09\x09\x09\x63\x2d\x39\
+\x31\x2e\x35\x31\x38\x2c\x30\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\
+\x37\x34\x2e\x38\x38\x32\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\x31\
+\x36\x36\x2e\x33\x39\x39\x53\x31\x36\x34\x2e\x34\x38\x32\x2c\x38\
+\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\x53\x34\x32\x32\
+\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\x32\x32\x2e\x34\
+\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\x2c\x34\x32\x32\
+\x2e\x33\x39\x39\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x33\x39\x39\
+\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x01\x20\
+\x3c\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
+\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
+\x20\x64\x3d\x22\x4d\x34\x2e\x33\x34\x20\x31\x35\x2e\x36\x36\x41\
+\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\x30\x20\x30\x20\
+\x39\x20\x31\x37\x2e\x39\x34\x56\x31\x30\x48\x35\x56\x38\x68\x34\
+\x56\x35\x2e\x38\x33\x61\x33\x20\x33\x20\x30\x20\x31\x20\x31\x20\
+\x32\x20\x30\x56\x38\x68\x34\x76\x32\x68\x2d\x34\x76\x37\x2e\x39\
+\x34\x61\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\x30\x20\
+\x30\x20\x34\x2e\x36\x36\x2d\x32\x2e\x32\x38\x6c\x2d\x31\x2e\x34\
+\x32\x2d\x31\x2e\x34\x32\x68\x35\x2e\x36\x36\x6c\x2d\x32\x2e\x38\
+\x33\x20\x32\x2e\x38\x33\x61\x31\x30\x20\x31\x30\x20\x30\x20\x30\
+\x20\x31\x2d\x31\x34\x2e\x31\x34\x20\x30\x4c\x2e\x31\x20\x31\x34\
+\x2e\x32\x34\x68\x35\x2e\x36\x36\x6c\x2d\x31\x2e\x34\x32\x20\x31\
+\x2e\x34\x32\x7a\x4d\x31\x30\x20\x34\x61\x31\x20\x31\x20\x30\x20\
+\x31\x20\x30\x20\x30\x2d\x32\x20\x31\x20\x31\x20\x30\x20\x30\x20\
+\x30\x20\x30\x20\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x07\x80\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x39\x33\x2e\x34\x36\
+\x2c\x32\x34\x39\x2e\x30\x35\x36\x63\x33\x2e\x37\x32\x33\x2d\x30\
+\x2e\x36\x37\x2c\x37\x2e\x35\x38\x39\x2d\x31\x2e\x30\x34\x31\x2c\
+\x31\x31\x2e\x35\x38\x36\x2d\x31\x2e\x30\x34\x31\x4c\x32\x30\x31\
+\x2e\x39\x32\x34\x2c\x32\x34\x38\x68\x31\x30\x33\x2e\x38\x32\x33\
+\x63\x34\x2e\x35\x30\x33\x2c\x30\x2c\x38\x2e\x38\x30\x36\x2d\x30\
+\x2e\x36\x31\x37\x2c\x31\x32\x2e\x39\x30\x38\x2d\x31\x2e\x37\x35\
+\x34\x0d\x0a\x09\x09\x63\x31\x39\x2e\x33\x37\x2d\x35\x2e\x33\x36\
+\x33\x2c\x33\x33\x2e\x33\x34\x35\x2d\x32\x32\x2e\x35\x33\x37\x2c\
+\x33\x33\x2e\x33\x34\x35\x2d\x34\x33\x2e\x36\x36\x33\x76\x2d\x33\
+\x30\x2e\x38\x32\x32\x76\x2d\x35\x36\x2e\x34\x30\x32\x63\x30\x2d\
+\x32\x34\x2e\x38\x33\x32\x2d\x32\x31\x2e\x31\x35\x2d\x34\x33\x2e\
+\x34\x38\x34\x2d\x34\x36\x2e\x32\x38\x39\x2d\x34\x37\x2e\x36\x30\
+\x36\x0d\x0a\x09\x09\x63\x2d\x31\x35\x2e\x39\x33\x31\x2d\x32\x2e\
+\x36\x32\x34\x2d\x33\x39\x2e\x32\x35\x38\x2d\x33\x2e\x38\x32\x37\
+\x2d\x35\x35\x2e\x30\x38\x39\x2d\x33\x2e\x37\x34\x39\x63\x2d\x31\
+\x35\x2e\x38\x32\x39\x2c\x30\x2e\x30\x38\x36\x2d\x33\x30\x2e\x39\
+\x38\x31\x2c\x31\x2e\x34\x30\x34\x2d\x34\x34\x2e\x32\x37\x37\x2c\
+\x33\x2e\x37\x34\x39\x43\x31\x36\x37\x2e\x31\x34\x33\x2c\x37\x34\
+\x2e\x35\x37\x36\x2c\x31\x36\x30\x2c\x38\x38\x2e\x39\x32\x38\x2c\
+\x31\x36\x30\x2c\x31\x31\x35\x2e\x33\x35\x39\x56\x31\x34\x34\x68\
+\x39\x36\x0d\x0a\x09\x09\x76\x31\x36\x48\x31\x32\x38\x2e\x38\x32\
+\x63\x2d\x33\x35\x2e\x36\x32\x38\x2c\x30\x2d\x36\x34\x2e\x35\x33\
+\x38\x2c\x34\x32\x2e\x35\x37\x31\x2d\x36\x34\x2e\x38\x31\x33\x2c\
+\x39\x35\x2e\x32\x34\x32\x43\x36\x34\x2e\x30\x30\x35\x2c\x32\x35\
+\x35\x2e\x34\x39\x35\x2c\x36\x34\x2c\x32\x35\x35\x2e\x37\x34\x37\
+\x2c\x36\x34\x2c\x32\x35\x36\x63\x30\x2c\x39\x2e\x35\x32\x33\x2c\
+\x30\x2e\x39\x34\x2c\x31\x38\x2e\x37\x32\x2c\x32\x2e\x36\x38\x35\
+\x2c\x32\x37\x2e\x34\x30\x34\x0d\x0a\x09\x09\x43\x37\x34\x2e\x36\
+\x34\x38\x2c\x33\x32\x33\x2e\x30\x37\x2c\x39\x39\x2e\x34\x35\x31\
+\x2c\x33\x35\x32\x2c\x31\x32\x38\x2e\x38\x32\x2c\x33\x35\x32\x48\
+\x31\x34\x34\x76\x2d\x32\x2e\x36\x36\x32\x76\x2d\x34\x33\x2e\x32\
+\x37\x33\x43\x31\x34\x34\x2c\x32\x37\x39\x2e\x32\x33\x38\x2c\x31\
+\x36\x34\x2e\x31\x34\x36\x2c\x32\x35\x34\x2e\x33\x33\x32\x2c\x31\
+\x39\x33\x2e\x34\x36\x2c\x32\x34\x39\x2e\x30\x35\x36\x7a\x20\x4d\
+\x32\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x0d\
+\x0a\x09\x09\x63\x2d\x39\x2e\x35\x39\x32\x2c\x30\x2d\x31\x37\x2e\
+\x33\x38\x34\x2d\x37\x2e\x37\x38\x35\x2d\x31\x37\x2e\x33\x38\x34\
+\x2d\x31\x37\x2e\x34\x30\x33\x63\x30\x2d\x39\x2e\x36\x36\x34\x2c\
+\x37\x2e\x37\x37\x34\x2d\x31\x37\x2e\x35\x32\x2c\x31\x37\x2e\x33\
+\x38\x34\x2d\x31\x37\x2e\x35\x32\x63\x39\x2e\x35\x37\x34\x2c\x30\
+\x2c\x31\x37\x2e\x33\x39\x39\x2c\x37\x2e\x38\x35\x35\x2c\x31\x37\
+\x2e\x33\x39\x39\x2c\x31\x37\x2e\x35\x32\x0d\x0a\x09\x09\x43\x32\
+\x32\x31\x2e\x30\x35\x36\x2c\x31\x31\x39\x2e\x32\x31\x37\x2c\x32\
+\x31\x33\x2e\x32\x34\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x2c\x32\
+\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x7a\x22\
+\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
+\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\x35\x34\x33\x43\x34\
+\x33\x34\x2e\x37\x38\x2c\x31\x38\x36\x2e\x30\x32\x31\x2c\x34\x31\
+\x31\x2e\x30\x33\x33\x2c\x31\x36\x30\x2c\x33\x38\x33\x2e\x31\x38\
+\x2c\x31\x36\x30\x48\x33\x36\x38\x76\x32\x2e\x36\x32\x36\x76\x33\
+\x38\x2e\x30\x34\x36\x63\x30\x2c\x33\x33\x2e\x39\x31\x35\x2d\x32\
+\x32\x2e\x32\x38\x36\x2c\x35\x38\x2e\x34\x37\x34\x2d\x34\x39\x2e\
+\x34\x38\x39\x2c\x36\x32\x2e\x36\x38\x31\x0d\x0a\x09\x09\x63\x2d\
+\x32\x2e\x37\x33\x37\x2c\x30\x2e\x34\x32\x34\x2d\x35\x2e\x34\x38\
+\x33\x2c\x30\x2e\x36\x34\x36\x2d\x38\x2e\x33\x30\x31\x2c\x30\x2e\
+\x36\x34\x36\x48\x32\x30\x36\x2e\x33\x35\x31\x63\x2d\x34\x2e\x35\
+\x31\x38\x2c\x30\x2d\x38\x2e\x39\x30\x34\x2c\x30\x2e\x35\x38\x34\
+\x2d\x31\x33\x2e\x30\x34\x39\x2c\x31\x2e\x36\x37\x32\x43\x31\x37\
+\x34\x2e\x31\x38\x2c\x32\x37\x30\x2e\x36\x38\x39\x2c\x31\x36\x30\
+\x2c\x32\x38\x36\x2e\x36\x2c\x31\x36\x30\x2c\x33\x30\x37\x2e\x32\
+\x33\x36\x76\x33\x32\x2e\x39\x32\x32\x0d\x0a\x09\x09\x76\x35\x34\
+\x2e\x33\x30\x35\x63\x30\x2c\x32\x34\x2e\x38\x33\x32\x2c\x32\x34\
+\x2e\x39\x37\x37\x2c\x33\x39\x2e\x34\x32\x36\x2c\x34\x39\x2e\x34\
+\x38\x31\x2c\x34\x36\x2e\x35\x35\x31\x63\x32\x39\x2e\x33\x32\x37\
+\x2c\x38\x2e\x35\x33\x31\x2c\x36\x31\x2e\x32\x36\x37\x2c\x31\x30\
+\x2e\x30\x36\x38\x2c\x39\x36\x2e\x33\x36\x36\x2c\x30\x43\x33\x32\
+\x39\x2e\x31\x35\x2c\x34\x33\x34\x2e\x33\x35\x34\x2c\x33\x35\x32\
+\x2c\x34\x32\x30\x2e\x38\x39\x33\x2c\x33\x35\x32\x2c\x33\x39\x34\
+\x2e\x34\x36\x33\x56\x33\x36\x38\x0d\x0a\x09\x09\x68\x2d\x39\x36\
+\x76\x2d\x31\x36\x68\x31\x32\x37\x2e\x31\x38\x63\x32\x35\x2e\x32\
+\x34\x2c\x30\x2c\x34\x37\x2e\x31\x30\x37\x2d\x32\x31\x2e\x33\x36\
+\x35\x2c\x35\x37\x2e\x38\x31\x34\x2d\x35\x32\x2e\x35\x34\x39\x43\
+\x34\x34\x35\x2e\x34\x37\x34\x2c\x32\x38\x36\x2e\x34\x30\x34\x2c\
+\x34\x34\x38\x2c\x32\x37\x31\x2e\x36\x34\x31\x2c\x34\x34\x38\x2c\
+\x32\x35\x36\x0d\x0a\x09\x09\x43\x34\x34\x38\x2c\x32\x34\x34\x2e\
+\x32\x33\x32\x2c\x34\x34\x36\x2e\x35\x36\x37\x2c\x32\x33\x32\x2e\
+\x39\x36\x32\x2c\x34\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\
+\x35\x34\x33\x7a\x20\x4d\x33\x30\x37\x2e\x38\x36\x37\x2c\x33\x38\
+\x32\x2e\x38\x32\x63\x39\x2e\x35\x39\x2c\x30\x2c\x31\x37\x2e\x33\
+\x38\x31\x2c\x37\x2e\x37\x38\x35\x2c\x31\x37\x2e\x33\x38\x31\x2c\
+\x31\x37\x2e\x34\x0d\x0a\x09\x09\x63\x30\x2c\x39\x2e\x36\x35\x2d\
+\x37\x2e\x37\x39\x31\x2c\x31\x37\x2e\x35\x32\x31\x2d\x31\x37\x2e\
+\x33\x38\x31\x2c\x31\x37\x2e\x35\x32\x31\x63\x2d\x39\x2e\x35\x37\
+\x37\x2c\x30\x2d\x31\x37\x2e\x33\x39\x39\x2d\x37\x2e\x38\x37\x31\
+\x2d\x31\x37\x2e\x33\x39\x39\x2d\x31\x37\x2e\x35\x32\x31\x43\x32\
+\x39\x30\x2e\x34\x36\x38\x2c\x33\x39\x30\x2e\x35\x39\x2c\x32\x39\
+\x38\x2e\x32\x37\x34\x2c\x33\x38\x32\x2e\x38\x32\x2c\x33\x30\x37\
+\x2e\x38\x36\x37\x2c\x33\x38\x32\x2e\x38\x32\x7a\x22\x2f\x3e\x0d\
+\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\x7d\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x32\
+\x37\x2c\x32\x33\x34\x2e\x36\x32\x35\x48\x31\x36\x37\x2e\x32\x39\
+\x36\x6c\x31\x31\x39\x2e\x37\x30\x32\x2d\x31\x31\x39\x2e\x37\x30\
+\x32\x4c\x32\x35\x36\x2c\x38\x35\x4c\x38\x35\x2c\x32\x35\x36\x6c\
+\x31\x37\x31\x2c\x31\x37\x31\x6c\x32\x39\x2e\x39\x32\x32\x2d\x32\
+\x39\x2e\x39\x32\x34\x4c\x31\x36\x37\x2e\x32\x39\x36\x2c\x32\x37\
+\x37\x2e\x33\x37\x35\x48\x34\x32\x37\x56\x32\x33\x34\x2e\x36\x32\
+\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\xf7\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x31\x37\x2e\x34\
+\x2c\x32\x32\x34\x48\x32\x38\x38\x56\x39\x34\x2e\x36\x63\x30\x2d\
+\x31\x36\x2e\x39\x2d\x31\x34\x2e\x33\x2d\x33\x30\x2e\x36\x2d\x33\
+\x32\x2d\x33\x30\x2e\x36\x63\x2d\x31\x37\x2e\x37\x2c\x30\x2d\x33\
+\x32\x2c\x31\x33\x2e\x37\x2d\x33\x32\x2c\x33\x30\x2e\x36\x56\x32\
+\x32\x34\x48\x39\x34\x2e\x36\x43\x37\x37\x2e\x37\x2c\x32\x32\x34\
+\x2c\x36\x34\x2c\x32\x33\x38\x2e\x33\x2c\x36\x34\x2c\x32\x35\x36\
+\x0d\x0a\x09\x63\x30\x2c\x31\x37\x2e\x37\x2c\x31\x33\x2e\x37\x2c\
+\x33\x32\x2c\x33\x30\x2e\x36\x2c\x33\x32\x48\x32\x32\x34\x76\x31\
+\x32\x39\x2e\x34\x63\x30\x2c\x31\x36\x2e\x39\x2c\x31\x34\x2e\x33\
+\x2c\x33\x30\x2e\x36\x2c\x33\x32\x2c\x33\x30\x2e\x36\x63\x31\x37\
+\x2e\x37\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x37\x2c\x33\x32\x2d\
+\x33\x30\x2e\x36\x56\x32\x38\x38\x68\x31\x32\x39\x2e\x34\x63\x31\
+\x36\x2e\x39\x2c\x30\x2c\x33\x30\x2e\x36\x2d\x31\x34\x2e\x33\x2c\
+\x33\x30\x2e\x36\x2d\x33\x32\x0d\x0a\x09\x43\x34\x34\x38\x2c\x32\
+\x33\x38\x2e\x33\x2c\x34\x33\x34\x2e\x33\x2c\x32\x32\x34\x2c\x34\
+\x31\x37\x2e\x34\x2c\x32\x32\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\
+\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x93\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4d\x61\x67\x6e\x69\x66\x79\x69\x6e\x67\x5f\x67\x6c\x61\
+\x73\x73\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
+\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
+\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
+\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x79\x3d\x22\
+\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
+\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\x62\x6c\x65\x2d\
+\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\x6e\x65\x77\x20\
+\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\x6d\x6c\x3a\x73\
+\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\
+\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x37\x2e\x35\
+\x34\x35\x2c\x31\x35\x2e\x34\x36\x37\x6c\x2d\x33\x2e\x37\x37\x39\
+\x2d\x33\x2e\x37\x37\x39\x63\x30\x2e\x35\x37\x2d\x30\x2e\x39\x33\
+\x35\x2c\x30\x2e\x38\x39\x38\x2d\x32\x2e\x30\x33\x35\x2c\x30\x2e\
+\x38\x39\x38\x2d\x33\x2e\x32\x31\x63\x30\x2d\x33\x2e\x34\x31\x37\
+\x2d\x32\x2e\x39\x36\x31\x2d\x36\x2e\x33\x37\x37\x2d\x36\x2e\x33\
+\x37\x38\x2d\x36\x2e\x33\x37\x37\x0d\x0a\x09\x43\x34\x2e\x38\x36\
+\x39\x2c\x32\x2e\x31\x2c\x32\x2e\x31\x2c\x34\x2e\x38\x37\x2c\x32\
+\x2e\x31\x2c\x38\x2e\x32\x38\x37\x63\x30\x2c\x33\x2e\x34\x31\x36\
+\x2c\x32\x2e\x39\x36\x31\x2c\x36\x2e\x33\x37\x37\x2c\x36\x2e\x33\
+\x37\x37\x2c\x36\x2e\x33\x37\x37\x63\x31\x2e\x31\x33\x37\x2c\x30\
+\x2c\x32\x2e\x32\x2d\x30\x2e\x33\x30\x39\x2c\x33\x2e\x31\x31\x35\
+\x2d\x30\x2e\x38\x34\x34\x6c\x33\x2e\x37\x39\x39\x2c\x33\x2e\x38\
+\x30\x31\x0d\x0a\x09\x63\x30\x2e\x33\x37\x32\x2c\x30\x2e\x33\x37\
+\x31\x2c\x30\x2e\x39\x37\x35\x2c\x30\x2e\x33\x37\x31\x2c\x31\x2e\
+\x33\x34\x36\x2c\x30\x6c\x30\x2e\x39\x34\x33\x2d\x30\x2e\x39\x34\
+\x33\x43\x31\x38\x2e\x30\x35\x31\x2c\x31\x36\x2e\x33\x30\x37\x2c\
+\x31\x37\x2e\x39\x31\x36\x2c\x31\x35\x2e\x38\x33\x38\x2c\x31\x37\
+\x2e\x35\x34\x35\x2c\x31\x35\x2e\x34\x36\x37\x7a\x20\x4d\x34\x2e\
+\x30\x30\x34\x2c\x38\x2e\x32\x38\x37\x0d\x0a\x09\x63\x30\x2d\x32\
+\x2e\x33\x36\x36\x2c\x31\x2e\x39\x31\x37\x2d\x34\x2e\x32\x38\x33\
+\x2c\x34\x2e\x32\x38\x32\x2d\x34\x2e\x32\x38\x33\x63\x32\x2e\x33\
+\x36\x36\x2c\x30\x2c\x34\x2e\x34\x37\x34\x2c\x32\x2e\x31\x30\x37\
+\x2c\x34\x2e\x34\x37\x34\x2c\x34\x2e\x34\x37\x34\x63\x30\x2c\x32\
+\x2e\x33\x36\x35\x2d\x31\x2e\x39\x31\x38\x2c\x34\x2e\x32\x38\x33\
+\x2d\x34\x2e\x32\x38\x33\x2c\x34\x2e\x32\x38\x33\x0d\x0a\x09\x43\
+\x36\x2e\x31\x31\x31\x2c\x31\x32\x2e\x37\x36\x2c\x34\x2e\x30\x30\
+\x34\x2c\x31\x30\x2e\x36\x35\x32\x2c\x34\x2e\x30\x30\x34\x2c\x38\
+\x2e\x32\x38\x37\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x0d\x0a\
+\x00\x00\x03\x22\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x22\x32\x35\x36\x22\
+\x20\x63\x79\x3d\x22\x32\x38\x30\x22\x20\x72\x3d\x22\x36\x33\x22\
+\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
+\x34\x30\x2c\x39\x36\x68\x2d\x38\x38\x6c\x2d\x33\x32\x2d\x33\x32\
+\x48\x31\x39\x32\x6c\x2d\x33\x32\x2c\x33\x32\x48\x37\x32\x63\x2d\
+\x32\x32\x2e\x30\x39\x32\x2c\x30\x2d\x34\x30\x2c\x31\x37\x2e\x39\
+\x30\x38\x2d\x34\x30\x2c\x34\x30\x76\x32\x37\x32\x63\x30\x2c\x32\
+\x32\x2e\x30\x39\x32\x2c\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2c\
+\x34\x30\x2c\x34\x30\x68\x33\x36\x38\x63\x32\x32\x2e\x30\x39\x32\
+\x2c\x30\x2c\x34\x30\x2d\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2d\
+\x34\x30\x0d\x0a\x09\x09\x56\x31\x33\x36\x43\x34\x38\x30\x2c\x31\
+\x31\x33\x2e\x39\x30\x38\x2c\x34\x36\x32\x2e\x30\x39\x32\x2c\x39\
+\x36\x2c\x34\x34\x30\x2c\x39\x36\x7a\x20\x4d\x32\x35\x36\x2c\x33\
+\x39\x32\x63\x2d\x36\x31\x2e\x38\x35\x35\x2c\x30\x2d\x31\x31\x32\
+\x2d\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2d\x31\x31\x32\x73\
+\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2c\x31\x31\x32\x2d\x31\
+\x31\x32\x73\x31\x31\x32\x2c\x35\x30\x2e\x31\x34\x35\x2c\x31\x31\
+\x32\x2c\x31\x31\x32\x0d\x0a\x09\x09\x53\x33\x31\x37\x2e\x38\x35\
+\x35\x2c\x33\x39\x32\x2c\x32\x35\x36\x2c\x33\x39\x32\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x05\x27\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x31\x32\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
+\x35\x36\x2c\x36\x34\x43\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\
+\x2c\x36\x34\x2c\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\x2c\x32\
+\x35\x36\x63\x30\x2c\x31\x30\x35\x2e\x36\x30\x34\x2c\x38\x36\x2e\
+\x34\x30\x31\x2c\x31\x39\x32\x2c\x31\x39\x32\x2c\x31\x39\x32\x63\
+\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x38\
+\x36\x34\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\
+\x38\x2e\x35\x33\x31\x2d\x33\x2e\x31\x39\x38\x2d\x31\x36\x2d\x38\
+\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\x33\x33\x63\x2d\x35\x2e\x33\
+\x33\x33\x2d\x35\x2e\x33\x33\x34\x2d\x38\x2e\x35\x33\x31\x2d\x31\
+\x32\x2e\x38\x30\x33\x2d\x38\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\
+\x33\x34\x63\x30\x2d\x31\x38\x2e\x31\x33\x35\x2c\x31\x33\x2e\x38\
+\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x68\x33\x38\x2e\x33\
+\x39\x36\x0d\x0a\x09\x09\x09\x63\x35\x38\x2e\x36\x36\x37\x2c\x30\
+\x2c\x31\x30\x36\x2e\x36\x36\x37\x2d\x34\x38\x2c\x31\x30\x36\x2e\
+\x36\x36\x37\x2d\x31\x30\x36\x2e\x36\x36\x36\x43\x34\x34\x38\x2c\
+\x31\x34\x30\x2e\x38\x30\x32\x2c\x33\x36\x31\x2e\x36\x30\x34\x2c\
+\x36\x34\x2c\x32\x35\x36\x2c\x36\x34\x7a\x20\x4d\x31\x33\x38\x2e\
+\x36\x36\x37\x2c\x32\x35\x36\x63\x2d\x31\x38\x2e\x31\x33\x36\x2c\
+\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\
+\x32\x73\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\
+\x32\x0d\x0a\x09\x09\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\
+\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x53\
+\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x35\x36\x2c\x31\x33\x38\x2e\
+\x36\x36\x37\x2c\x32\x35\x36\x7a\x20\x4d\x32\x30\x32\x2e\x36\x36\
+\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\x2e\x31\x33\
+\x36\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\
+\x2d\x33\x32\x63\x30\x2d\x31\x38\x2e\x31\x33\x36\x2c\x31\x33\x2e\
+\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\
+\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\x33\x32\x2c\x31\x33\
+\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x32\x33\x34\x2e\x36\
+\x36\x37\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x32\x30\x2e\x38\
+\x30\x32\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x32\x30\x32\x2e\x36\
+\x36\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\x33\x30\x39\
+\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\
+\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\
+\x2d\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\x31\x38\
+\x2e\x31\x33\x36\x2c\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\x2c\x33\
+\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\
+\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x33\x34\
+\x31\x2e\x33\x33\x33\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x33\x32\
+\x37\x2e\x34\x36\x39\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x33\x30\
+\x39\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\
+\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x0d\x0a\x09\x09\x09\
+\x63\x2d\x31\x38\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\
+\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\x32\x73\x31\x33\x2e\x38\x36\
+\x35\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\
+\x36\x2c\x30\x2c\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\
+\x2c\x33\x32\x53\x33\x39\x31\x2e\x34\x36\x39\x2c\x32\x35\x36\x2c\
+\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x7a\x22\x2f\x3e\x0d\
+\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\xc9\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
+\x3d\x22\x34\x38\x30\x2c\x32\x35\x36\x20\x33\x38\x34\x2c\x31\x36\
+\x30\x20\x33\x38\x34\x2c\x32\x33\x36\x20\x32\x37\x36\x2c\x32\x33\
+\x36\x20\x32\x37\x36\x2c\x31\x32\x38\x20\x33\x35\x32\x2c\x31\x32\
+\x38\x20\x32\x35\x36\x2c\x33\x32\x20\x31\x36\x30\x2c\x31\x32\x38\
+\x20\x32\x33\x36\x2c\x31\x32\x38\x20\x32\x33\x36\x2c\x32\x33\x36\
+\x20\x31\x32\x38\x2c\x32\x33\x36\x20\x31\x32\x38\x2c\x31\x36\x30\
+\x20\x33\x32\x2c\x32\x35\x36\x20\x31\x32\x38\x2c\x33\x35\x32\x20\
+\x0d\x0a\x09\x31\x32\x38\x2c\x32\x37\x36\x20\x32\x33\x36\x2c\x32\
+\x37\x36\x20\x32\x33\x36\x2c\x33\x38\x34\x20\x31\x36\x30\x2c\x33\
+\x38\x34\x20\x32\x35\x36\x2c\x34\x38\x30\x20\x33\x35\x32\x2c\x33\
+\x38\x34\x20\x32\x37\x35\x2e\x38\x2c\x33\x38\x34\x20\x32\x37\x35\
+\x2e\x34\x2c\x32\x37\x35\x2e\x35\x20\x33\x38\x34\x2c\x32\x37\x35\
+\x2e\x38\x20\x33\x38\x34\x2c\x33\x35\x32\x20\x22\x2f\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x36\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
+\x22\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x39\x36\x2e\x38\x20\x33\
+\x32\x30\x2c\x33\x39\x36\x2e\x38\x20\x33\x32\x30\x2c\x34\x34\x38\
+\x20\x34\x34\x38\x2c\x34\x34\x38\x20\x34\x34\x38\x2c\x33\x32\x30\
+\x20\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x32\x30\x20\x09\x22\x2f\
+\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
+\x6e\x74\x73\x3d\x22\x33\x39\x36\x2e\x38\x2c\x31\x31\x35\x2e\x32\
+\x30\x35\x20\x33\x39\x36\x2e\x38\x2c\x31\x39\x32\x20\x34\x34\x38\
+\x2c\x31\x39\x32\x20\x34\x34\x38\x2c\x36\x34\x20\x33\x32\x30\x2c\
+\x36\x34\x20\x33\x32\x30\x2c\x31\x31\x35\x2e\x32\x30\x35\x20\x09\
+\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
+\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\
+\x31\x35\x2e\x32\x20\x31\x39\x32\x2c\x31\x31\x35\x2e\x32\x20\x31\
+\x39\x32\x2c\x36\x34\x20\x36\x34\x2c\x36\x34\x20\x36\x34\x2c\x31\
+\x39\x32\x20\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\x39\x32\x20\x09\
+\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
+\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x2c\x33\x39\x36\
+\x2e\x37\x39\x35\x20\x31\x31\x35\x2e\x32\x2c\x33\x32\x30\x20\x36\
+\x34\x2c\x33\x32\x30\x20\x36\x34\x2c\x34\x34\x38\x20\x31\x39\x32\
+\x2c\x34\x34\x38\x20\x31\x39\x32\x2c\x33\x39\x36\x2e\x37\x39\x35\
+\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
+\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\x8d\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x32\x34\x70\x74\x27\x20\x76\x65\x72\x73\x69\x6f\x6e\
+\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x27\
+\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\x38\x33\x20\
+\x32\x34\x20\x32\x34\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x32\x34\
+\x70\x74\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
+\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
+\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
+\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
+\x37\x36\x35\x35\x20\x36\x39\x2e\x38\x31\x32\x33\x29\x27\x3e\x0a\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x39\x2e\x33\x39\
+\x31\x31\x38\x20\x2d\x30\x43\x20\x2d\x39\x2e\x33\x32\x32\x35\x37\
+\x20\x2d\x33\x2e\x37\x37\x37\x38\x33\x20\x2d\x38\x2e\x33\x34\x33\
+\x32\x34\x20\x2d\x37\x2e\x33\x38\x34\x34\x34\x20\x2d\x36\x2e\x36\
+\x34\x30\x35\x37\x20\x2d\x31\x30\x2e\x31\x32\x39\x38\x43\x20\x2d\
+\x31\x2e\x32\x36\x32\x31\x39\x20\x2d\x31\x38\x2e\x38\x30\x31\x37\
+\x20\x37\x2e\x36\x38\x39\x37\x31\x20\x2d\x31\x35\x2e\x35\x33\x35\
+\x31\x20\x38\x2e\x36\x37\x36\x33\x32\x20\x2d\x35\x2e\x34\x38\x32\
+\x32\x43\x20\x39\x2e\x31\x38\x36\x37\x39\x20\x2d\x30\x2e\x32\x38\
+\x30\x38\x37\x37\x20\x36\x2e\x37\x34\x39\x33\x37\x20\x34\x2e\x35\
+\x31\x38\x38\x37\x20\x33\x2e\x33\x32\x30\x32\x38\x20\x35\x2e\x30\
+\x36\x34\x38\x39\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\
+\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\
+\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\
+\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\
+\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\
+\x36\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\
+\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
+\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
+\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\
+\x39\x2e\x38\x31\x32\x33\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\
+\x65\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\x39\x31\x31\x38\x27\x20\
+\x63\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\
+\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\
+\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\
+\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\
+\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\
+\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x39\x2e\
+\x38\x31\x32\x33\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\
+\x63\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\x35\x37\x27\x20\x63\x79\
+\x3d\x27\x2d\x31\x30\x2e\x31\x32\x39\x38\x27\x20\x72\x3d\x27\x33\
+\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\
+\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
+\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\
+\x20\x36\x39\x2e\x38\x31\x32\x33\x29\x27\x3e\x0a\x3c\x63\x69\x72\
+\x63\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\x37\x36\x33\x32\x27\
+\x20\x63\x79\x3d\x27\x2d\x35\x2e\x34\x38\x32\x32\x27\x20\x72\x3d\
+\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\
+\x35\x35\x20\x36\x39\x2e\x38\x31\x32\x33\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x33\x32\x30\x32\
+\x38\x27\x20\x63\x79\x3d\x27\x35\x2e\x30\x36\x34\x38\x39\x27\x20\
+\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\
+\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\
+\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\x46\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x33\x37\x2e\x35\
+\x2c\x33\x38\x36\x2e\x36\x4c\x33\x30\x36\x2e\x39\x2c\x32\x35\x36\
+\x6c\x31\x33\x30\x2e\x36\x2d\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\
+\x31\x2d\x31\x34\x2e\x31\x2c\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\
+\x2c\x30\x2d\x35\x30\x2e\x39\x63\x2d\x31\x34\x2e\x31\x2d\x31\x34\
+\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\x2d\x35\x30\x2e\
+\x39\x2c\x30\x4c\x32\x35\x36\x2c\x32\x30\x35\x2e\x31\x4c\x31\x32\
+\x35\x2e\x34\x2c\x37\x34\x2e\x35\x0d\x0a\x09\x63\x2d\x31\x34\x2e\
+\x31\x2d\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\
+\x2d\x35\x30\x2e\x39\x2c\x30\x63\x2d\x31\x34\x2e\x31\x2c\x31\x34\
+\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\x35\
+\x30\x2e\x39\x4c\x32\x30\x35\x2e\x31\x2c\x32\x35\x36\x4c\x37\x34\
+\x2e\x35\x2c\x33\x38\x36\x2e\x36\x63\x2d\x31\x34\x2e\x31\x2c\x31\
+\x34\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\
+\x35\x30\x2e\x39\x0d\x0a\x09\x63\x31\x34\x2e\x31\x2c\x31\x34\x2e\
+\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\x39\
+\x2c\x30\x4c\x32\x35\x36\x2c\x33\x30\x36\x2e\x39\x6c\x31\x33\x30\
+\x2e\x36\x2c\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\x31\x2c\x31\x34\
+\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\
+\x39\x2c\x30\x43\x34\x35\x31\x2e\x35\x2c\x34\x32\x33\x2e\x34\x2c\
+\x34\x35\x31\x2e\x35\x2c\x34\x30\x30\x2e\x36\x2c\x34\x33\x37\x2e\
+\x35\x2c\x33\x38\x36\x2e\x36\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\
+\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\x79\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x6f\x64\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
+\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
+\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
+\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\x3d\
+\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
+\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
+\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
+\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
+\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
+\x35\x2e\x37\x31\x39\x2c\x31\x34\x2e\x37\x35\x63\x2d\x30\x2e\x32\
+\x33\x36\x2c\x30\x2d\x30\x2e\x34\x37\x34\x2d\x30\x2e\x30\x38\x33\
+\x2d\x30\x2e\x36\x36\x34\x2d\x30\x2e\x32\x35\x32\x4c\x2d\x30\x2e\
+\x30\x30\x35\x2c\x31\x30\x6c\x35\x2e\x33\x34\x31\x2d\x34\x2e\x37\
+\x34\x38\x43\x35\x2e\x37\x34\x38\x2c\x34\x2e\x38\x38\x37\x2c\x36\
+\x2e\x33\x38\x2c\x34\x2e\x39\x32\x32\x2c\x36\x2e\x37\x34\x37\x2c\
+\x35\x2e\x33\x33\x35\x0d\x0a\x09\x63\x30\x2e\x33\x36\x37\x2c\x30\
+\x2e\x34\x31\x33\x2c\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\x2d\
+\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\x31\x32\x4c\x33\x2e\x30\x30\
+\x35\x2c\x31\x30\x6c\x33\x2e\x33\x37\x38\x2c\x33\x2e\x30\x30\x32\
+\x63\x30\x2e\x34\x31\x33\x2c\x30\x2e\x33\x36\x37\x2c\x30\x2e\x34\
+\x35\x2c\x30\x2e\x39\x39\x39\x2c\x30\x2e\x30\x38\x33\x2c\x31\x2e\
+\x34\x31\x32\x0d\x0a\x09\x43\x36\x2e\x32\x36\x39\x2c\x31\x34\x2e\
+\x36\x33\x37\x2c\x35\x2e\x39\x39\x34\x2c\x31\x34\x2e\x37\x35\x2c\
+\x35\x2e\x37\x31\x39\x2c\x31\x34\x2e\x37\x35\x7a\x20\x4d\x31\x34\
+\x2e\x36\x36\x34\x2c\x31\x34\x2e\x37\x34\x38\x4c\x32\x30\x2e\x30\
+\x30\x35\x2c\x31\x30\x6c\x2d\x35\x2e\x30\x36\x2d\x34\x2e\x34\x39\
+\x38\x63\x2d\x30\x2e\x34\x31\x33\x2d\x30\x2e\x33\x36\x37\x2d\x31\
+\x2e\x30\x34\x35\x2d\x30\x2e\x33\x33\x2d\x31\x2e\x34\x31\x31\x2c\
+\x30\x2e\x30\x38\x33\x0d\x0a\x09\x63\x2d\x30\x2e\x33\x36\x37\x2c\
+\x30\x2e\x34\x31\x33\x2d\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\
+\x2c\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\x31\x32\x4c\x31\x36\x2e\
+\x39\x39\x35\x2c\x31\x30\x6c\x2d\x33\x2e\x36\x35\x39\x2c\x33\x2e\
+\x32\x35\x32\x63\x2d\x30\x2e\x34\x31\x33\x2c\x30\x2e\x33\x36\x37\
+\x2d\x30\x2e\x34\x35\x2c\x30\x2e\x39\x39\x39\x2d\x30\x2e\x30\x38\
+\x33\x2c\x31\x2e\x34\x31\x32\x43\x31\x33\x2e\x34\x35\x2c\x31\x34\
+\x2e\x38\x38\x37\x2c\x31\x33\x2e\x37\x32\x35\x2c\x31\x35\x2c\x31\
+\x34\x2c\x31\x35\x0d\x0a\x09\x43\x31\x34\x2e\x32\x33\x36\x2c\x31\
+\x35\x2c\x31\x34\x2e\x34\x37\x34\x2c\x31\x34\x2e\x39\x31\x37\x2c\
+\x31\x34\x2e\x36\x36\x34\x2c\x31\x34\x2e\x37\x34\x38\x7a\x20\x4d\
+\x39\x2e\x39\x38\x36\x2c\x31\x36\x2e\x31\x36\x35\x6c\x32\x2d\x31\
+\x32\x63\x30\x2e\x30\x39\x31\x2d\x30\x2e\x35\x34\x35\x2d\x30\x2e\
+\x32\x37\x37\x2d\x31\x2e\x30\x36\x2d\x30\x2e\x38\x32\x32\x2d\x31\
+\x2e\x31\x35\x31\x0d\x0a\x09\x63\x2d\x30\x2e\x35\x34\x37\x2d\x30\
+\x2e\x30\x39\x32\x2d\x31\x2e\x30\x36\x31\x2c\x30\x2e\x32\x37\x37\
+\x2d\x31\x2e\x31\x35\x2c\x30\x2e\x38\x32\x32\x6c\x2d\x32\x2c\x31\
+\x32\x63\x2d\x30\x2e\x30\x39\x31\x2c\x30\x2e\x35\x34\x35\x2c\x30\
+\x2e\x32\x37\x37\x2c\x31\x2e\x30\x36\x2c\x30\x2e\x38\x32\x32\x2c\
+\x31\x2e\x31\x35\x31\x43\x38\x2e\x38\x39\x32\x2c\x31\x36\x2e\x39\
+\x39\x36\x2c\x38\x2e\x39\x34\x36\x2c\x31\x37\x2c\x39\x2e\x30\x30\
+\x31\x2c\x31\x37\x0d\x0a\x09\x43\x39\x2e\x34\x38\x31\x2c\x31\x37\
+\x2c\x39\x2e\x39\x30\x35\x2c\x31\x36\x2e\x36\x35\x33\x2c\x39\x2e\
+\x39\x38\x36\x2c\x31\x36\x2e\x31\x36\x35\x7a\x22\x2f\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\x30\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x32\x34\x70\x74\x27\x20\x76\x65\x72\x73\x69\x6f\x6e\
+\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x27\
+\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\x38\x33\x20\
+\x32\x34\x20\x32\x34\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x32\x34\
+\x70\x74\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
+\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
+\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
+\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
+\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x39\x2e\x33\x39\
+\x31\x31\x38\x20\x2d\x30\x4c\x20\x2d\x36\x2e\x36\x34\x30\x35\x37\
+\x20\x2d\x31\x32\x2e\x30\x34\x35\x4c\x20\x38\x2e\x36\x37\x36\x33\
+\x32\x20\x2d\x36\x2e\x35\x31\x38\x37\x31\x4c\x20\x33\x2e\x33\x32\
+\x30\x32\x38\x20\x36\x2e\x30\x32\x32\x35\x4c\x20\x2d\x39\x2e\x33\
+\x39\x31\x31\x38\x20\x2d\x30\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\
+\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\
+\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\
+\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\
+\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\
+\x31\x2e\x37\x35\x36\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\
+\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\x39\x31\
+\x31\x38\x27\x20\x63\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\x27\x33\
+\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\
+\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
+\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\
+\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\x3c\x63\x69\x72\
+\x63\x6c\x65\x20\x63\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\x35\x37\
+\x27\x20\x63\x79\x3d\x27\x2d\x31\x32\x2e\x30\x34\x35\x27\x20\x72\
+\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\
+\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\
+\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\
+\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\
+\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\
+\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\x3e\x0a\x3c\
+\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\x37\x36\
+\x33\x32\x27\x20\x63\x79\x3d\x27\x2d\x36\x2e\x35\x31\x38\x37\x31\
+\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\
+\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\
+\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
+\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\
+\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\
+\x38\x2e\x37\x36\x35\x35\x20\x36\x38\x2e\x38\x35\x38\x33\x29\x27\
+\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\
+\x33\x32\x30\x32\x38\x27\x20\x63\x79\x3d\x27\x36\x2e\x30\x32\x32\
+\x35\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\
+\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\
+\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x01\xdd\
+\x00\
+\x00\x06\xe4\x78\x9c\xcd\x54\x4d\x6f\x9b\x40\x10\x3d\x13\x29\xff\
+\x61\xba\xb7\x4a\xec\x17\xc4\xd4\xa6\xa6\x51\xfd\x21\xcb\x52\x9a\
+\x58\x6a\xea\xaa\xa7\x0a\xc3\x16\x50\x28\x20\x58\xc0\xce\xaf\xef\
+\xee\x92\x54\x51\x95\xfa\x18\xfb\xb0\x33\xda\x79\x6f\xde\xbc\x65\
+\x24\xa6\xd7\xfb\xdf\x39\x74\xa2\x6e\xb2\xb2\x08\x10\x27\x0c\x81\
+\x28\xa2\x32\xce\x8a\x24\x40\xad\xfc\x85\xc7\xe8\xfa\xd3\xe5\xc5\
+\xf4\x1d\xc6\xb0\x12\x85\xa8\x43\x59\xd6\x3e\x7c\x8e\xcb\x9d\x80\
+\x75\x9e\xb7\x8d\x34\x25\xe0\x1e\x71\x08\xb7\xe1\xeb\x76\x05\xcb\
+\x7d\x55\xd6\x12\x36\x79\x9b\xe0\x75\x01\xc4\x14\xb7\xc3\x10\x1f\
+\x3c\xc2\x18\xcc\xda\x2c\x8f\x81\xbd\x07\xc0\xd8\xe8\x2f\xee\xe6\
+\xf7\x3f\x36\x4b\x68\xba\x04\x36\xdf\x66\x37\xeb\x39\x20\x4c\xe9\
+\x77\x77\x4e\xe9\xe2\x7e\x61\x24\x38\xe1\x94\x2e\x6f\x11\xa0\x54\
+\xca\xca\xa7\xb4\xef\x7b\xd2\xbb\xa4\xac\x13\xba\xaa\xc3\x2a\xcd\
+\xa2\x86\x2a\x22\xd5\x44\xd5\x44\x95\x18\xe7\x24\x96\x31\xd2\x33\
+\xb4\xf4\x8b\xa7\x72\x04\x59\x1c\xa0\x9b\xf0\x20\xea\x9f\xea\xa2\
+\xbe\x44\xd1\x04\xaf\x48\x3b\x8c\x31\x2d\xf5\x44\xf1\xf7\x79\x56\
+\x3c\xbc\x46\xe4\x93\xc9\x84\x1a\x54\x51\x03\xc4\xaa\x3d\x82\xc3\
+\x90\x2f\x2f\x2c\xe8\xb3\x58\xa6\x01\x1a\x71\x47\x03\xa9\xc8\x92\
+\x54\xfe\xbd\x76\x99\xe8\x67\xa5\xee\x02\x06\xaa\xa6\x0f\x82\x46\
+\x1e\x72\x11\x20\x51\x84\xbb\x5c\xe0\x5d\x18\x3d\x24\x75\xd9\x16\
+\xb1\x5f\x88\x1e\x5e\x30\x3f\x1a\x6f\x7e\x53\x85\x91\xa2\x57\xb5\
+\x68\x44\xdd\x09\xf3\xea\x44\x05\x6b\x88\xd6\xb4\x0a\x65\x0a\xea\
+\xd1\x5f\xb8\xc7\x6c\x3e\x72\x89\x1b\x31\xdb\x25\x1f\xb0\x6b\x7b\
+\x2a\xaa\xa3\x73\x8a\x47\x8c\x8c\x22\xac\x00\x9b\xe9\x22\x76\xf1\
+\x13\xdc\x0d\x10\x33\x98\xfb\xdc\xa0\x73\x6a\x00\xd3\xa2\x4b\xb6\
+\x51\xd4\x67\x6b\xe6\x3c\xea\x4f\x60\x59\xf4\x1f\x1f\xce\x78\x7c\
+\x16\x3e\xae\xb8\x77\x3a\x1f\x53\xfa\xff\x25\x39\x63\xfe\x26\xa6\
+\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x71\x6c\x49\x57\x6c\
+\xf2\x26\xa6\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x31\x2c\
+\xe9\x39\xaa\x7f\xb6\xca\x7f\x00\x99\x18\x96\x19\
+\x00\x00\x04\xbd\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x32\x34\x70\x74\x27\x20\x76\x65\x72\x73\x69\x6f\x6e\
+\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x27\
+\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\x38\x33\x20\
+\x32\x34\x20\x32\x34\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x32\x34\
+\x70\x74\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
+\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
+\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
+\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\
+\x37\x36\x35\x35\x20\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x2d\x39\x2e\x33\x39\
+\x31\x31\x38\x20\x2d\x30\x43\x20\x2d\x39\x2e\x39\x36\x38\x36\x31\
+\x20\x2d\x33\x2e\x38\x33\x30\x30\x34\x20\x2d\x38\x2e\x35\x35\x37\
+\x30\x36\x20\x2d\x37\x2e\x35\x31\x39\x34\x34\x20\x2d\x36\x2e\x36\
+\x34\x30\x35\x37\x20\x2d\x31\x30\x2e\x32\x31\x37\x31\x43\x20\x2d\
+\x30\x2e\x34\x39\x31\x30\x38\x39\x20\x2d\x31\x38\x2e\x38\x37\x33\
+\x33\x20\x38\x2e\x33\x35\x36\x37\x36\x20\x2d\x31\x35\x2e\x31\x39\
+\x30\x36\x20\x38\x2e\x36\x37\x36\x33\x32\x20\x2d\x35\x2e\x35\x32\
+\x39\x34\x38\x43\x20\x38\x2e\x38\x33\x36\x20\x2d\x30\x2e\x37\x30\
+\x32\x30\x30\x38\x20\x36\x2e\x32\x33\x39\x36\x38\x20\x32\x2e\x39\
+\x34\x32\x30\x37\x20\x33\x2e\x33\x32\x30\x32\x38\x20\x35\x2e\x31\
+\x30\x38\x35\x37\x43\x20\x2d\x31\x2e\x39\x36\x38\x39\x31\x20\x39\
+\x2e\x30\x33\x33\x37\x31\x20\x2d\x38\x2e\x32\x36\x38\x39\x35\x20\
+\x37\x2e\x34\x34\x33\x37\x20\x2d\x39\x2e\x33\x39\x31\x31\x38\x20\
+\x2d\x30\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\
+\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\
+\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x37\x35\x36\
+\x35\x36\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
+\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x39\
+\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
+\x20\x63\x78\x3d\x27\x2d\x39\x2e\x33\x39\x31\x31\x38\x27\x20\x63\
+\x79\x3d\x27\x2d\x30\x27\x20\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\
+\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
+\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\
+\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\
+\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\x36\x39\x2e\x37\
+\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\
+\x78\x3d\x27\x2d\x36\x2e\x36\x34\x30\x35\x37\x27\x20\x63\x79\x3d\
+\x27\x2d\x31\x30\x2e\x32\x31\x37\x31\x27\x20\x72\x3d\x27\x33\x2e\
+\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\
+\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\
+\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\
+\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\
+\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\x35\x35\x20\
+\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\
+\x6c\x65\x20\x63\x78\x3d\x27\x38\x2e\x36\x37\x36\x33\x32\x27\x20\
+\x63\x79\x3d\x27\x2d\x35\x2e\x35\x32\x39\x34\x38\x27\x20\x72\x3d\
+\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x38\x2e\x37\x36\
+\x35\x35\x20\x36\x39\x2e\x37\x36\x38\x38\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x33\x32\x30\x32\
+\x38\x27\x20\x63\x79\x3d\x27\x35\x2e\x31\x30\x38\x35\x37\x27\x20\
+\x72\x3d\x27\x33\x2e\x30\x31\x31\x32\x35\x27\x20\x66\x69\x6c\x6c\
+\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\
+\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x02\x20\
+\x00\
+\x00\x07\x7f\x78\x9c\xdd\x55\x3b\x6f\xdb\x30\x10\xde\xfb\x2b\xae\
+\xe8\xc0\x76\x20\x45\x52\x24\x45\x06\x51\x02\xd4\x40\xa7\x74\x4b\
+\x96\x6e\x6a\xcc\x48\x6c\x6c\xc9\x90\x54\xcb\xfd\xf7\x3d\xc5\xd6\
+\xc3\x56\xd0\x29\x43\x11\x69\xd0\x3d\x78\x77\xdf\x7d\xc7\x83\xae\
+\x6f\x0f\xdb\x0d\xec\x7d\xdd\x84\xaa\x4c\x89\x60\x9c\x80\x2f\x1f\
+\xab\x75\x28\xf3\x94\x3c\xdc\x7f\xa3\x96\xdc\xde\x7c\xb8\xfe\x48\
+\x29\xdc\x17\xa1\x81\xa7\xb0\xf1\xd0\x65\x0d\xe4\xbe\xf4\x75\xd6\
+\xfa\x35\xfc\xfc\x03\xeb\x7d\x68\xf6\xf9\x16\x24\x53\x40\x29\x9e\
+\x47\x0d\x0a\x1f\xf2\xa2\x4d\x89\x54\xbb\x96\xcc\x6b\x08\xd4\x82\
+\xef\xbe\x56\x87\x94\x68\xc3\x14\x77\x0a\x74\xcc\xac\xb6\x31\x08\
+\xcb\x54\x9c\x68\x90\x8a\x40\x17\xd6\x6d\x81\x01\x47\x53\x9f\x04\
+\xc1\x96\x4d\x4a\x8a\xb6\xdd\x5d\x45\x51\xd7\x75\xac\x8b\x59\x55\
+\xe7\x91\xe4\x9c\x47\x58\xf4\x74\xe4\xea\xb0\x09\xe5\xf3\x6b\x07\
+\x85\x73\x2e\x7a\xf1\x12\x84\x99\x43\x58\xa7\x64\x97\xe5\x5e\x1c\
+\xd5\xb6\xce\xca\xe6\xa9\xaa\xb7\x29\xd9\x66\x6d\x1d\x0e\x9f\x39\
+\x73\xce\x48\xa3\x80\xf7\xef\xa0\x18\xcd\x8c\xb4\x12\x12\xc5\x24\
+\x97\x5f\xfa\xe0\x5d\xd6\x16\x80\xd9\xbe\x03\xb5\x0c\xf1\x72\xa4\
+\x42\x33\x2e\x35\x97\x77\x33\x13\x9f\x2b\x02\x9b\x76\x26\xf6\x54\
+\xe8\xd5\x99\x59\xc6\x2e\xd1\xbd\x79\x66\x35\x4c\x38\x9b\x24\x68\
+\x35\xf3\x7c\xb3\x40\xc1\xb4\x12\x16\xa8\x42\x70\x28\xe1\x38\x12\
+\x27\x8c\x45\xe0\x27\x69\x05\x97\xae\x8b\xd0\x41\x45\x94\xaf\x88\
+\x53\x3f\x13\x54\xce\x38\x62\x9f\x74\x4c\xe4\x30\xd1\x50\x87\x0a\
+\xc9\xac\x12\x09\x62\x18\xc4\xd5\x04\x70\xf4\xd2\x45\x02\x7a\x5e\
+\xe2\x6e\xc9\xea\x0f\xd2\xdf\xc6\x4d\x4a\x3e\x59\xde\xbf\x24\xc2\
+\x29\x44\xf9\xdb\xcd\x71\x8e\x49\x18\x93\xcc\xdb\x44\xfe\xb8\xd5\
+\xb3\x36\x63\xe6\xb4\x55\x2f\x6d\x1e\xc5\xb3\x36\x4f\x5e\xba\x48\
+\x40\x97\x45\x26\x93\xc3\x78\xe5\xe4\x2c\xd1\x38\x94\x51\x9c\x46\
+\x3a\x3a\x17\xf1\x97\x35\x46\xe6\xca\xaa\xf4\x04\x9a\xb6\xae\x9e\
+\x3d\xf2\xc8\x5f\x9e\xc1\x40\x71\x4b\xfc\x63\xb6\x4b\x49\x5d\xfd\
+\x2e\xd7\x67\xe6\x5f\x55\x28\x2f\xed\xdb\xd0\xfa\x7a\x13\xf0\x83\
+\x3b\x8b\x33\xc3\x9a\xa3\x6f\x58\x65\x96\x68\xa3\xcd\x9b\x4f\x6a\
+\xc1\xe2\xbb\xd9\xb8\x53\x3f\xef\x6d\x60\xff\x5a\x2d\x8d\x44\x49\
+\x31\x5b\x2d\x77\x64\x8a\x8f\xe2\xd9\x6a\x9d\xbc\x74\x91\x60\x71\
+\x29\xfe\x13\x12\x8f\x44\xf6\x7f\xab\x9b\xbf\x3f\x45\xd8\x3d\
+\x00\x00\x03\x65\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\x76\x65\x72\x73\
+\x69\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\
+\x38\x33\x20\x31\x38\x2e\x37\x35\x20\x31\x38\x2e\x37\x35\x27\x20\
+\x77\x69\x64\x74\x68\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\
+\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
+\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x27\x3e\x0a\x3c\
+\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\x3e\x0a\x3c\x67\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
+\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\
+\x20\x36\x33\x2e\x32\x33\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\
+\x68\x20\x64\x3d\x27\x4d\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x20\
+\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\x34\
+\x20\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\
+\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\x38\x2e\x36\
+\x35\x37\x33\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\
+\x38\x2e\x36\x35\x37\x33\x34\x20\x38\x2e\x36\x35\x37\x33\x34\x5a\
+\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\
+\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\
+\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\
+\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\
+\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\
+\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x35\x30\x35\x36\x32\x27\
+\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
+\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
+\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\x20\x36\x33\x2e\x32\x33\
+\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
+\x20\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x43\x20\x34\x2e\x33\x32\
+\x38\x36\x37\x20\x2d\x32\x2e\x33\x39\x30\x36\x36\x20\x32\x2e\x33\
+\x39\x30\x36\x36\x20\x2d\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x20\
+\x2d\x34\x2e\x33\x32\x38\x36\x37\x43\x20\x2d\x32\x2e\x33\x39\x30\
+\x36\x36\x20\x2d\x34\x2e\x33\x32\x38\x36\x37\x20\x2d\x34\x2e\x33\
+\x32\x38\x36\x37\x20\x2d\x32\x2e\x33\x39\x30\x36\x36\x20\x2d\x34\
+\x2e\x33\x32\x38\x36\x37\x20\x2d\x30\x43\x20\x2d\x34\x2e\x33\x32\
+\x38\x36\x37\x20\x32\x2e\x33\x39\x30\x36\x36\x20\x2d\x32\x2e\x33\
+\x39\x30\x36\x36\x20\x34\x2e\x33\x32\x38\x36\x37\x20\x30\x20\x34\
+\x2e\x33\x32\x38\x36\x37\x43\x20\x32\x2e\x33\x39\x30\x36\x36\x20\
+\x34\x2e\x33\x32\x38\x36\x37\x20\x34\x2e\x33\x32\x38\x36\x37\x20\
+\x32\x2e\x33\x39\x30\x36\x36\x20\x34\x2e\x33\x32\x38\x36\x37\x20\
+\x30\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\
+\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\
+\x73\x76\x67\x3e\
+\x00\x00\x02\x7d\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x35\
+\x2c\x32\x37\x37\x2e\x33\x37\x35\x68\x32\x35\x39\x2e\x37\x30\x34\
+\x4c\x32\x32\x35\x2e\x30\x30\x32\x2c\x33\x39\x37\x2e\x30\x37\x37\
+\x4c\x32\x35\x36\x2c\x34\x32\x37\x6c\x31\x37\x31\x2d\x31\x37\x31\
+\x4c\x32\x35\x36\x2c\x38\x35\x6c\x2d\x32\x39\x2e\x39\x32\x32\x2c\
+\x32\x39\x2e\x39\x32\x34\x6c\x31\x31\x38\x2e\x36\x32\x36\x2c\x31\
+\x31\x39\x2e\x37\x30\x31\x48\x38\x35\x56\x32\x37\x37\x2e\x33\x37\
+\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x52\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
+\x64\x3d\x22\x4d\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x48\
+\x32\x35\x36\x2e\x30\x30\x36\x6c\x2d\x34\x32\x2e\x36\x36\x38\x2d\
+\x34\x38\x48\x37\x34\x2e\x36\x36\x36\x43\x35\x31\x2e\x31\x39\x37\
+\x2c\x39\x36\x2c\x33\x32\x2c\x31\x31\x35\x2e\x31\x39\x38\x2c\x33\
+\x32\x2c\x31\x33\x38\x2e\x36\x36\x37\x76\x32\x33\x34\x2e\x36\x36\
+\x36\x43\x33\x32\x2c\x33\x39\x36\x2e\x38\x30\x32\x2c\x35\x31\x2e\
+\x31\x39\x37\x2c\x34\x31\x36\x2c\x37\x34\x2e\x36\x36\x36\x2c\x34\
+\x31\x36\x68\x33\x36\x32\x2e\x36\x36\x38\x0d\x0a\x09\x43\x34\x36\
+\x30\x2e\x38\x30\x33\x2c\x34\x31\x36\x2c\x34\x38\x30\x2c\x33\x39\
+\x36\x2e\x38\x30\x32\x2c\x34\x38\x30\x2c\x33\x37\x33\x2e\x33\x33\
+\x33\x56\x31\x38\x36\x2e\x36\x36\x37\x43\x34\x38\x30\x2c\x31\x36\
+\x33\x2e\x31\x39\x38\x2c\x34\x36\x30\x2e\x38\x30\x33\x2c\x31\x34\
+\x34\x2c\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x7a\x20\x4d\
+\x34\x34\x38\x2c\x33\x37\x33\x2e\x33\x33\x33\x0d\x0a\x09\x63\x30\
+\x2c\x35\x2e\x37\x38\x32\x2d\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\
+\x36\x36\x37\x2d\x31\x30\x2e\x36\x36\x36\x2c\x31\x30\x2e\x36\x36\
+\x37\x48\x37\x34\x2e\x36\x36\x36\x43\x36\x38\x2e\x38\x38\x34\x2c\
+\x33\x38\x34\x2c\x36\x34\x2c\x33\x37\x39\x2e\x31\x31\x35\x2c\x36\
+\x34\x2c\x33\x37\x33\x2e\x33\x33\x33\x56\x31\x37\x36\x68\x33\x37\
+\x33\x2e\x33\x33\x34\x63\x35\x2e\x37\x38\x31\x2c\x30\x2c\x31\x30\
+\x2e\x36\x36\x36\x2c\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\x36\x36\
+\x36\x2c\x31\x30\x2e\x36\x36\x37\x0d\x0a\x09\x56\x33\x37\x33\x2e\
+\x33\x33\x33\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x03\xc4\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
+\x64\x5f\x6c\x65\x66\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
+\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
+\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
+\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\x61\
+\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\
+\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x78\
+\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
+\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\
+\x31\x31\x2e\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x63\x2d\x30\x2e\
+\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2d\x30\x2e\x35\x31\x35\x2d\
+\x30\x2e\x31\x39\x37\x2d\x30\x2e\x37\x31\x2c\x30\x4c\x37\x2e\x37\
+\x38\x35\x2c\x39\x2e\x36\x34\x31\x63\x2d\x30\x2e\x31\x39\x36\x2c\
+\x30\x2e\x31\x39\x39\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x35\x32\
+\x2c\x30\x2c\x30\x2e\x37\x31\x37\x6c\x32\x2e\x38\x30\x37\x2c\x32\
+\x2e\x38\x36\x34\x0d\x0a\x09\x63\x30\x2e\x31\x39\x35\x2c\x30\x2e\
+\x31\x39\x39\x2c\x30\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\x38\x2c\
+\x30\x2e\x37\x31\x2c\x30\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\
+\x39\x37\x2c\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\x38\x2c\x30\
+\x2d\x30\x2e\x37\x31\x37\x4c\x39\x2c\x31\x30\x6c\x32\x2e\x33\x30\
+\x32\x2d\x32\x2e\x35\x30\x36\x43\x31\x31\x2e\x34\x39\x38\x2c\x37\
+\x2e\x32\x39\x36\x2c\x31\x31\x2e\x34\x39\x38\x2c\x36\x2e\x39\x37\
+\x36\x2c\x31\x31\x2e\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x7a\x0d\
+\x0a\x09\x20\x4d\x31\x30\x2c\x30\x2e\x34\x63\x2d\x35\x2e\x33\x30\
+\x32\x2c\x30\x2d\x39\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2d\x39\x2e\
+\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\x30\x33\x2c\x34\x2e\
+\x32\x39\x38\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x73\
+\x39\x2e\x36\x2d\x34\x2e\x32\x39\x37\x2c\x39\x2e\x36\x2d\x39\x2e\
+\x36\x43\x31\x39\x2e\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\
+\x33\x30\x32\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\
+\x4d\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x2d\x34\
+\x2e\x36\x31\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\
+\x34\x2d\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\
+\x34\x2e\x36\x31\x34\x2c\x33\x2e\x37\x33\x39\x2d\x38\x2e\x33\x35\
+\x34\x2c\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x34\x2e\
+\x36\x31\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\
+\x2c\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\
+\x31\x38\x2e\x33\x35\x34\x2c\x31\x34\x2e\x36\x31\x34\x2c\x31\x34\
+\x2e\x36\x31\x33\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\
+\x38\x2e\x33\x35\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
+\x3e\x0d\x0a\
+\x00\x00\x00\xdd\
+\x3c\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x38\x22\
+\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x38\x22\x20\x76\x69\x65\x77\
+\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x38\x20\x38\x22\x3e\x0a\x20\
+\x20\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x30\x20\x30\x76\x32\
+\x68\x2e\x35\x63\x30\x2d\x2e\x35\x35\x2e\x34\x35\x2d\x31\x20\x31\
+\x2d\x31\x68\x31\x2e\x35\x76\x35\x2e\x35\x63\x30\x20\x2e\x32\x38\
+\x2d\x2e\x32\x32\x2e\x35\x2d\x2e\x35\x2e\x35\x68\x2d\x2e\x35\x76\
+\x31\x68\x34\x76\x2d\x31\x68\x2d\x2e\x35\x63\x2d\x2e\x32\x38\x20\
+\x30\x2d\x2e\x35\x2d\x2e\x32\x32\x2d\x2e\x35\x2d\x2e\x35\x76\x2d\
+\x35\x2e\x35\x68\x31\x2e\x35\x63\x2e\x35\x35\x20\x30\x20\x31\x20\
+\x2e\x34\x35\x20\x31\x20\x31\x68\x2e\x35\x76\x2d\x32\x68\x2d\x38\
+\x7a\x22\x20\x2f\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\xeb\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x67\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
+\x4d\x32\x35\x36\x2c\x31\x32\x38\x63\x2d\x38\x31\x2e\x39\x2c\x30\
+\x2d\x31\x34\x35\x2e\x37\x2c\x34\x38\x2e\x38\x2d\x32\x32\x34\x2c\
+\x31\x32\x38\x63\x36\x37\x2e\x34\x2c\x36\x37\x2e\x37\x2c\x31\x32\
+\x34\x2c\x31\x32\x38\x2c\x32\x32\x34\x2c\x31\x32\x38\x63\x39\x39\
+\x2e\x39\x2c\x30\x2c\x31\x37\x33\x2e\x34\x2d\x37\x36\x2e\x34\x2c\
+\x32\x32\x34\x2d\x31\x32\x36\x2e\x36\x0d\x0a\x09\x09\x43\x34\x32\
+\x38\x2e\x32\x2c\x31\x39\x38\x2e\x36\x2c\x33\x35\x34\x2e\x38\x2c\
+\x31\x32\x38\x2c\x32\x35\x36\x2c\x31\x32\x38\x7a\x20\x4d\x32\x35\
+\x36\x2c\x33\x34\x37\x2e\x33\x63\x2d\x34\x39\x2e\x34\x2c\x30\x2d\
+\x38\x39\x2e\x36\x2d\x34\x31\x2d\x38\x39\x2e\x36\x2d\x39\x31\x2e\
+\x33\x63\x30\x2d\x35\x30\x2e\x34\x2c\x34\x30\x2e\x32\x2d\x39\x31\
+\x2e\x33\x2c\x38\x39\x2e\x36\x2d\x39\x31\x2e\x33\x73\x38\x39\x2e\
+\x36\x2c\x34\x31\x2c\x38\x39\x2e\x36\x2c\x39\x31\x2e\x33\x0d\x0a\
+\x09\x09\x43\x33\x34\x35\x2e\x36\x2c\x33\x30\x36\x2e\x34\x2c\x33\
+\x30\x35\x2e\x34\x2c\x33\x34\x37\x2e\x33\x2c\x32\x35\x36\x2c\x33\
+\x34\x37\x2e\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\
+\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\
+\x32\x32\x34\x63\x30\x2d\x37\x2e\x39\x2c\x32\x2e\x39\x2d\x31\x35\
+\x2e\x31\x2c\x37\x2e\x36\x2d\x32\x30\x2e\x37\x63\x2d\x32\x2e\x35\
+\x2d\x30\x2e\x34\x2d\x35\x2d\x30\x2e\x36\x2d\x37\x2e\x36\x2d\x30\
+\x2e\x36\x63\x2d\x32\x38\x2e\x38\x2c\x30\x2d\x35\x32\x2e\x33\x2c\
+\x32\x33\x2e\x39\x2d\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x63\x30\
+\x2c\x32\x39\x2e\x34\x2c\x32\x33\x2e\x35\x2c\x35\x33\x2e\x33\x2c\
+\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x0d\x0a\x09\x09\x09\x73\x35\
+\x32\x2e\x33\x2d\x32\x33\x2e\x39\x2c\x35\x32\x2e\x33\x2d\x35\x33\
+\x2e\x33\x63\x30\x2d\x32\x2e\x33\x2d\x30\x2e\x32\x2d\x34\x2e\x36\
+\x2d\x30\x2e\x34\x2d\x36\x2e\x39\x63\x2d\x35\x2e\x35\x2c\x34\x2e\
+\x33\x2d\x31\x32\x2e\x33\x2c\x36\x2e\x39\x2d\x31\x39\x2e\x38\x2c\
+\x36\x2e\x39\x43\x32\x37\x30\x2e\x33\x2c\x32\x35\x36\x2c\x32\x35\
+\x36\x2c\x32\x34\x31\x2e\x37\x2c\x32\x35\x36\x2c\x32\x32\x34\x7a\
+\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\
+\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x02\xa2\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x32\x38\x2c\x34\x30\
+\x35\x2e\x34\x32\x39\x43\x31\x32\x38\x2c\x34\x32\x38\x2e\x38\x34\
+\x36\x2c\x31\x34\x37\x2e\x31\x39\x38\x2c\x34\x34\x38\x2c\x31\x37\
+\x30\x2e\x36\x36\x37\x2c\x34\x34\x38\x68\x31\x37\x30\x2e\x36\x36\
+\x37\x43\x33\x36\x34\x2e\x38\x30\x32\x2c\x34\x34\x38\x2c\x33\x38\
+\x34\x2c\x34\x32\x38\x2e\x38\x34\x36\x2c\x33\x38\x34\x2c\x34\x30\
+\x35\x2e\x34\x32\x39\x56\x31\x36\x30\x48\x31\x32\x38\x56\x34\x30\
+\x35\x2e\x34\x32\x39\x7a\x20\x4d\x34\x31\x36\x2c\x39\x36\x0d\x0a\
+\x09\x09\x68\x2d\x38\x30\x6c\x2d\x32\x36\x2e\x37\x38\x35\x2d\x33\
+\x32\x48\x32\x30\x32\x2e\x37\x38\x36\x4c\x31\x37\x36\x2c\x39\x36\
+\x48\x39\x36\x76\x33\x32\x68\x33\x32\x30\x56\x39\x36\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x02\x7f\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
+\x3d\x22\x32\x38\x38\x2c\x39\x36\x20\x33\x33\x37\x2e\x39\x2c\x31\
+\x34\x35\x2e\x39\x20\x32\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x32\
+\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x31\x34\x35\x2e\x39\x2c\x33\
+\x33\x37\x2e\x39\x20\x39\x36\x2c\x32\x38\x38\x20\x39\x36\x2c\x34\
+\x31\x36\x20\x32\x32\x34\x2c\x34\x31\x36\x20\x31\x37\x34\x2e\x31\
+\x2c\x33\x36\x36\x2e\x31\x20\x33\x35\x37\x2e\x34\x2c\x31\x38\x32\
+\x2e\x39\x20\x33\x36\x36\x2e\x31\x2c\x31\x37\x34\x2e\x31\x20\x0d\
+\x0a\x09\x34\x31\x36\x2c\x32\x32\x34\x20\x34\x31\x36\x2c\x39\x36\
+\x20\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\x10\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x34\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x68\x65\x69\x67\x68\
+\x74\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\x76\x65\x72\x73\
+\x69\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\x38\x35\
+\x38\x33\x20\x31\x38\x2e\x37\x35\x20\x31\x38\x2e\x37\x35\x27\x20\
+\x77\x69\x64\x74\x68\x3d\x27\x31\x38\x2e\x37\x35\x70\x74\x27\x20\
+\x78\x6d\x6c\x6e\x73\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
+\x67\x27\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x27\x3e\x0a\x3c\
+\x67\x20\x69\x64\x3d\x27\x70\x61\x67\x65\x31\x27\x3e\x0a\x3c\x67\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
+\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\
+\x20\x36\x33\x2e\x32\x33\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\
+\x68\x20\x64\x3d\x27\x4d\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x20\
+\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\x34\
+\x20\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x38\x2e\x36\x35\x37\x33\
+\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\x38\x2e\x36\
+\x35\x37\x33\x34\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x4c\x20\x2d\
+\x38\x2e\x36\x35\x37\x33\x34\x20\x38\x2e\x36\x35\x37\x33\x34\x5a\
+\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\
+\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\
+\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\
+\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\
+\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\
+\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\x2e\x35\x30\x35\x36\x32\x27\
+\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
+\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
+\x36\x34\x20\x36\x35\x2e\x37\x38\x34\x34\x20\x36\x33\x2e\x32\x33\
+\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
+\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x20\x2d\x30\x4c\x20\x38\x2e\
+\x36\x35\x37\x33\x34\x20\x30\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\
+\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\
+\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\
+\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\
+\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\
+\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x31\
+\x2e\x35\x30\x35\x36\x32\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\
+\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\
+\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\
+\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x36\x35\x2e\x37\x38\x34\
+\x34\x20\x36\x33\x2e\x32\x33\x33\x33\x29\x27\x3e\x0a\x3c\x70\x61\
+\x74\x68\x20\x64\x3d\x27\x4d\x20\x30\x20\x38\x2e\x36\x35\x37\x33\
+\x34\x4c\x20\x30\x20\x2d\x38\x2e\x36\x35\x37\x33\x34\x27\x20\x66\
+\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\
+\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\
+\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\
+\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\
+\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\
+\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\
+\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\
+\x64\x74\x68\x3d\x27\x31\x2e\x35\x30\x35\x36\x32\x27\x2f\x3e\x0a\
+\x3c\x2f\x67\x3e\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x02\x79\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x6f\x6c\
+\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x31\x38\x36\
+\x2e\x33\x30\x31\x2c\x33\x33\x39\x2e\x38\x39\x33\x20\x39\x36\x2c\
+\x32\x34\x39\x2e\x34\x36\x31\x20\x36\x34\x2c\x32\x37\x39\x2e\x39\
+\x36\x38\x20\x31\x38\x36\x2e\x33\x30\x31\x2c\x34\x30\x32\x20\x34\
+\x34\x38\x2c\x31\x34\x30\x2e\x35\x30\x36\x20\x34\x31\x36\x2c\x31\
+\x31\x30\x20\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\
+\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\xb5\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
+\x64\x5f\x72\x69\x67\x68\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\
+\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
+\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
+\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
+\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
+\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
+\x4d\x31\x31\x2c\x31\x30\x4c\x38\x2e\x36\x39\x38\x2c\x37\x2e\x34\
+\x39\x34\x63\x2d\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x38\x2d\
+\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\x39\x2c\x30\x2d\x30\x2e\
+\x37\x31\x38\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\
+\x30\x2e\x35\x31\x35\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x37\x31\
+\x2c\x30\x6c\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\x0a\
+\x09\x63\x30\x2e\x31\x39\x36\x2c\x30\x2e\x31\x39\x39\x2c\x30\x2e\
+\x31\x39\x36\x2c\x30\x2e\x35\x32\x2c\x30\x2c\x30\x2e\x37\x31\x37\
+\x6c\x2d\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x63\x2d\x30\
+\x2e\x31\x39\x35\x2c\x30\x2e\x31\x39\x39\x2d\x30\x2e\x35\x31\x34\
+\x2c\x30\x2e\x31\x39\x38\x2d\x30\x2e\x37\x31\x2c\x30\x63\x2d\x30\
+\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2d\x30\x2e\x31\x39\x36\
+\x2d\x30\x2e\x35\x31\x38\x2c\x30\x2d\x30\x2e\x37\x31\x37\x4c\x31\
+\x31\x2c\x31\x30\x7a\x20\x4d\x31\x30\x2c\x30\x2e\x34\x0d\x0a\x09\
+\x63\x35\x2e\x33\x30\x32\x2c\x30\x2c\x39\x2e\x36\x2c\x34\x2e\x32\
+\x39\x38\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\
+\x30\x33\x2d\x34\x2e\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\
+\x2c\x39\x2e\x36\x53\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x33\x2c\
+\x30\x2e\x34\x2c\x31\x30\x43\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\
+\x2c\x34\x2e\x36\x39\x38\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\
+\x34\x7a\x20\x4d\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\
+\x63\x34\x2e\x36\x31\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2d\x33\
+\x2e\x37\x34\x2c\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\
+\x30\x2d\x34\x2e\x36\x31\x34\x2d\x33\x2e\x37\x34\x31\x2d\x38\x2e\
+\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\
+\x2d\x34\x2e\x36\x31\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2c\x33\
+\x2e\x37\x34\x2d\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\
+\x0a\x09\x43\x31\x2e\x36\x34\x35\x2c\x31\x34\x2e\x36\x31\x34\x2c\
+\x35\x2e\x33\x38\x35\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\
+\x31\x38\x2e\x33\x35\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\
+\x67\x3e\x0d\x0a\
+"
+
+qt_resource_name = b"\
+\x00\x05\
+\x00\x6f\xa6\x53\
+\x00\x69\
+\x00\x63\x00\x6f\x00\x6e\x00\x73\
+\x00\x09\
+\x0b\x9e\x89\x07\
+\x00\x63\
+\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x15\
+\x0f\xc4\x59\xe7\
+\x00\x73\
+\x00\x75\x00\x62\x00\x64\x00\x69\x00\x72\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x79\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\
+\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x13\
+\x03\x24\x75\x47\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x65\x00\x66\x00\x72\x00\x65\x00\x73\x00\x68\x00\x2e\x00\x73\
+\x00\x76\x00\x67\
+\x00\x08\
+\x08\xc8\x55\xe7\
+\x00\x73\
+\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x06\xe3\xaf\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x68\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x17\
+\x06\xc6\x02\xa7\
+\x00\x74\
+\x00\x72\x00\x69\x00\x61\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2d\x00\x73\x00\x74\x00\x72\x00\x6f\x00\x6b\x00\x65\x00\x64\x00\x2d\
+\x00\x31\x00\x35\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x0b\x07\x57\xa7\
+\x00\x65\
+\x00\x64\x00\x69\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x12\
+\x0c\x5e\xd4\xa7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\
+\x00\x67\
+\x00\x0f\
+\x07\x0e\xc4\x87\
+\x00\x6f\
+\x00\x70\x00\x65\x00\x6e\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x1b\
+\x0e\xb5\x68\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
+\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x0a\x2d\x1b\xc7\
+\x00\x63\
+\x00\x69\x00\x72\x00\x63\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x01\xca\x6d\x87\
+\x00\x62\
+\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x11\
+\x0c\xdb\x38\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x1c\
+\x08\x8a\x79\x07\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
+\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x66\x00\x66\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x0f\x68\x53\xe7\
+\x00\x61\
+\x00\x6e\x00\x63\x00\x68\x00\x6f\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x11\
+\x01\x60\xbc\x47\
+\x00\x73\
+\x00\x6f\x00\x63\x00\x69\x00\x61\x00\x6c\x00\x2d\x00\x70\x00\x79\x00\x74\x00\x68\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x16\
+\x01\xfb\x76\x27\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x62\x00\x61\x00\x63\
+\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0e\
+\x0f\xcb\xd5\xc7\
+\x00\x70\
+\x00\x6c\x00\x75\x00\x73\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x14\
+\x0f\xa5\xe0\xc7\
+\x00\x6d\
+\x00\x61\x00\x67\x00\x6e\x00\x69\x00\x66\x00\x79\x00\x69\x00\x6e\x00\x67\x00\x2d\x00\x67\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x2e\
+\x00\x73\x00\x76\x00\x67\
+\x00\x12\
+\x08\x79\x97\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x73\x00\x76\
+\x00\x67\
+\x00\x19\
+\x0f\xef\x7b\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6f\x00\x6c\x00\x6f\x00\x72\x00\x2d\x00\x70\x00\x61\x00\x6c\
+\x00\x65\x00\x74\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0e\
+\x05\xed\x38\x67\
+\x00\x61\
+\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x12\
+\x04\xb2\x21\x47\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x65\x00\x78\x00\x70\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\
+\x00\x67\
+\x00\x0d\
+\x05\x20\xce\x87\
+\x00\x6f\
+\x00\x70\x00\x65\x00\x6e\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0f\
+\x09\x76\x60\xc7\
+\x00\x63\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x05\xa8\x57\x87\
+\x00\x63\
+\x00\x6f\x00\x64\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x11\
+\x0c\xa7\xc7\x47\
+\x00\x63\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x08\
+\x08\xf7\x57\x07\
+\x00\x67\
+\x00\x72\x00\x69\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0f\
+\x04\xf2\xa7\x87\
+\x00\x63\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x04\xa9\x22\xc7\
+\x00\x66\
+\x00\x69\x00\x6c\x00\x6c\x00\x65\x00\x64\x00\x62\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x0a\xc8\x62\x67\
+\x00\x63\
+\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x19\
+\x0a\x43\x45\xc7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x66\x00\x6f\x00\x72\
+\x00\x77\x00\x61\x00\x72\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x17\
+\x07\x87\x48\x27\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x66\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2d\x00\x6f\x00\x70\
+\x00\x65\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x1c\
+\x04\x66\xe1\x67\
+\x00\x63\
+\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
+\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x0c\xf7\x55\x87\
+\x00\x74\
+\x00\x65\x00\x78\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x07\
+\x0c\xf8\x5a\x07\
+\x00\x65\
+\x00\x79\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x12\
+\x08\x55\xef\xc7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x65\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\
+\x00\x67\
+\x00\x10\
+\x0c\x57\x65\x47\
+\x00\x61\
+\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x65\x00\x73\x00\x69\x00\x7a\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x08\x89\xfa\x47\
+\x00\x63\
+\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x6f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x08\xe4\xaf\x47\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x6f\x00\x6e\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x1d\
+\x06\xec\xf4\xc7\
+\x00\x63\
+\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
+\x00\x6c\x00\x65\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+"
+
+qt_resource_struct_v1 = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
+\x00\x00\x02\x48\x00\x00\x00\x00\x00\x01\x00\x00\x32\x5f\
+\x00\x00\x01\xae\x00\x00\x00\x00\x00\x01\x00\x00\x25\xc5\
+\x00\x00\x02\x70\x00\x00\x00\x00\x00\x01\x00\x00\x39\xe3\
+\x00\x00\x00\x58\x00\x00\x00\x00\x00\x01\x00\x00\x03\x80\
+\x00\x00\x05\x08\x00\x00\x00\x00\x00\x01\x00\x00\x73\xe0\
+\x00\x00\x04\x5c\x00\x01\x00\x00\x00\x01\x00\x00\x68\x7c\
+\x00\x00\x03\x76\x00\x00\x00\x00\x00\x01\x00\x00\x4e\x14\
+\x00\x00\x04\x38\x00\x00\x00\x00\x00\x01\x00\x00\x63\xbb\
+\x00\x00\x03\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x51\x4e\
+\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x29\
+\x00\x00\x03\x54\x00\x00\x00\x00\x00\x01\x00\x00\x4b\x47\
+\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe8\
+\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x09\x1a\
+\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x88\x32\
+\x00\x00\x01\x34\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x8e\
+\x00\x00\x04\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x70\x8a\
+\x00\x00\x05\x70\x00\x00\x00\x00\x00\x01\x00\x00\x7c\x78\
+\x00\x00\x02\xf2\x00\x00\x00\x00\x00\x01\x00\x00\x42\xf6\
+\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x81\xa1\
+\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x3b\
+\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x06\xaa\
+\x00\x00\x05\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x85\xb5\
+\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x00\x61\xda\
+\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x55\xdf\
+\x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x00\x23\x04\
+\x00\x00\x04\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x09\
+\x00\x00\x04\x82\x00\x00\x00\x00\x00\x01\x00\x00\x6a\xa0\
+\x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x13\xb6\
+\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x05\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x7f\x1e\
+\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x17\x26\
+\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x5d\xa6\
+\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x80\
+\x00\x00\x05\x46\x00\x00\x00\x00\x00\x01\x00\x00\x77\xa8\
+\x00\x00\x05\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x78\x89\
+\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\xb4\
+\x00\x00\x02\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x31\x3b\
+\x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x3f\x5f\
+\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x03\x10\
+\x00\x00\x02\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x64\
+\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x46\x1c\
+"
+
+qt_resource_struct_v2 = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x02\x48\x00\x00\x00\x00\x00\x01\x00\x00\x32\x5f\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x01\xae\x00\x00\x00\x00\x00\x01\x00\x00\x25\xc5\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x02\x70\x00\x00\x00\x00\x00\x01\x00\x00\x39\xe3\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x00\x58\x00\x00\x00\x00\x00\x01\x00\x00\x03\x80\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x05\x08\x00\x00\x00\x00\x00\x01\x00\x00\x73\xe0\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x04\x5c\x00\x01\x00\x00\x00\x01\x00\x00\x68\x7c\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x03\x76\x00\x00\x00\x00\x00\x01\x00\x00\x4e\x14\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x04\x38\x00\x00\x00\x00\x00\x01\x00\x00\x63\xbb\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x03\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x51\x4e\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x29\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x03\x54\x00\x00\x00\x00\x00\x01\x00\x00\x4b\x47\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe8\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf7\
+\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x09\x1a\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x88\x32\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x01\x34\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x8e\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x04\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x70\x8a\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x05\x70\x00\x00\x00\x00\x00\x01\x00\x00\x7c\x78\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x02\xf2\x00\x00\x00\x00\x00\x01\x00\x00\x42\xf6\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x05\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x81\xa1\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x3b\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x06\xaa\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x05\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x85\xb5\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x04\x22\x00\x01\x00\x00\x00\x01\x00\x00\x61\xda\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x03\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x55\xdf\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x00\x23\x04\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x04\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x09\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x04\x82\x00\x00\x00\x00\x00\x01\x00\x00\x6a\xa0\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x13\xb6\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x05\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x7f\x1e\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x17\x26\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x5d\xa6\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf5\
+\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x2b\x80\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x05\x46\x00\x00\x00\x00\x00\x01\x00\x00\x77\xa8\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x05\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x78\x89\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\xb4\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf4\
+\x00\x00\x02\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x31\x3b\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+\x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x3f\x5f\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x03\x10\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x02\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x64\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf6\
+\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x46\x1c\
+\x00\x00\x01\x6c\xb2\x83\xbd\xf3\
+"
+
+qt_version = [int(v) for v in QtCore.qVersion().split('.')]
+if qt_version < [5, 8, 0]:
+ rcc_version = 1
+ qt_resource_struct = qt_resource_struct_v1
+else:
+ rcc_version = 2
+ qt_resource_struct = qt_resource_struct_v2
+
+def qInitResources():
+ QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/graphics/asymptote/GUI/labelEditor.py b/graphics/asymptote/GUI/labelEditor.py
new file mode 100644
index 0000000000..76bc8d7d0a
--- /dev/null
+++ b/graphics/asymptote/GUI/labelEditor.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python3
+
+from pyUIClass.labelTextEditor import Ui_Dialog
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtSvg as Qs
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+import xasyArgs as xa
+import xasy2asy as x2a
+import subprocess
+import xasyOptions as xo
+import xasyUtils as xu
+import tempfile
+import uuid
+import os
+import io
+
+
+class labelEditor(Qw.QDialog):
+ def __init__(self, text=''):
+ super().__init__()
+ self.ui = Ui_Dialog()
+ self.ui.setupUi(self)
+
+ self.ui.btnAccept.clicked.connect(self.accept)
+ self.ui.btnCancel.clicked.connect(self.reject)
+ self.ui.chkMathMode.stateChanged.connect(self.chkMathModeChecked)
+ self.ui.btnPreview.clicked.connect(self.btnPreviewOnClick)
+ self.ui.btnGetText.clicked.connect(self.btnGetTextOnClick)
+
+ self.svgPreview = None
+ self.initializeText(text)
+
+ def initializeText(self, text: str):
+ if text[0] == '$' and text[-1] == '$':
+ self.ui.chkMathMode.setChecked(True)
+ text = text.strip('$')
+
+ if text.startswith('\\displaystyle{'):
+ self.ui.cmbMathStyle.setCurrentText('Display Style')
+ text = text.rstrip('}')
+ text = text.replace('\\displaystyle{', '', 1)
+ elif text.startswith('\\scriptstyle{'):
+ self.ui.cmbMathStyle.setCurrentText('Script Style')
+ text = text.rstrip('}')
+ text = text.replace('\\scriptstyle{', '', 1)
+
+ self.ui.txtLabelEdit.setPlainText(text)
+
+ def chkMathModeChecked(self, checked):
+ self.ui.cmbMathStyle.setEnabled(checked)
+
+ def getText(self):
+ rawText = self.ui.txtLabelEdit.toPlainText()
+ rawText.replace('\n', ' ')
+ if self.ui.chkMathMode.isChecked():
+ prefix = ''
+ suffix = ''
+ if self.ui.cmbMathStyle.currentText() == 'Display Style':
+ prefix = '\\displaystyle{'
+ suffix = '}'
+ elif self.ui.cmbMathStyle.currentText() == 'Script Style':
+ prefix = '\\scriptstyle{'
+ suffix = '}'
+ return '${0}{1}{2}$'.format(prefix, rawText, suffix)
+ else:
+ return rawText
+
+ def btnPreviewOnClick(self):
+ path = xa.getArgs().asypath
+ if path is None:
+ opt = xo.xasyOptions().load()
+ path = opt['asyPath']
+
+ asyInput = """
+ frame f;
+ label(f, "{0}");
+ write(min(f), newl);
+ write(max(f), newl);
+ shipout(f);
+ """
+
+ self.svgPreview = Qs.QSvgRenderer()
+ with tempfile.TemporaryDirectory(prefix='xasylbl_') as tmpdir:
+ id = str(uuid.uuid4())
+ tmpFile = os.path.join(tmpdir, 'lbl-{0}.svg'.format(id))
+
+ with subprocess.Popen(args=[path, '-fsvg', '-o', tmpFile, '-'], encoding='utf-8', stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE) as asy:
+ asy.stdin.write(asyInput.format(self.getText()))
+ asy.stdin.close()
+ out = asy.stdout.read()
+
+ raw_array = out.splitlines()
+
+ bounds_1, bounds_2 = [val.strip() for val in raw_array]
+
+ min_bounds = xu.listize(bounds_1, (float, float))
+ max_bounds = xu.listize(bounds_2, (float, float))
+
+ new_rect = self.processBounds(min_bounds, max_bounds)
+ self.svgPreview.load(tmpFile)
+
+
+
+ self.drawPreview(new_rect)
+
+ def drawPreview(self, naturalBounds):
+ img = Qg.QPixmap(self.ui.lblLabelPreview.size())
+ img.fill(Qg.QColor.fromRgbF(1, 1, 1, 1))
+ if self.svgPreview is None:
+ pass
+ else:
+ with Qg.QPainter(img) as pnt:
+ scale_ratio = self.getIdealScaleRatio(naturalBounds, self.ui.lblLabelPreview.rect())
+
+ pnt.translate(self.ui.lblLabelPreview.rect().center())
+ pnt.scale(scale_ratio, scale_ratio)
+ self.svgPreview.render(pnt, naturalBounds)
+ self.ui.lblLabelPreview.setPixmap(img)
+
+
+ def getIdealScaleRatio(self, rect, boundsRect):
+ assert isinstance(rect, (Qc.QRect, Qc.QRectF))
+ assert isinstance(rect, (Qc.QRect, Qc.QRectF))
+
+ magic_ratio = 0.50
+ idealRatioHeight = (magic_ratio * boundsRect.height()) / rect.height()
+ magicRatioWidth = 0.50
+
+ if idealRatioHeight * rect.width() > magicRatioWidth * boundsRect.width():
+ idealRatioWidth = (magicRatioWidth * boundsRect.width()) / rect.width()
+ idealRatio = min(idealRatioHeight, idealRatioWidth)
+ else:
+ idealRatio = idealRatioHeight
+ return idealRatio
+
+ def processBounds(self, minPt, maxPt):
+ p1x, p1y = minPt
+ p2x, p2y = maxPt
+
+ minPt = Qc.QPointF(p1x, p1y)
+ maxPt = Qc.QPointF(p2x, p2y)
+
+ newRect = Qc.QRectF(minPt, maxPt)
+ return newRect
+
+
+ def btnGetTextOnClick(self):
+ msgbox = Qw.QMessageBox()
+ msgbox.setText('Text Preview:\n' + self.getText())
+ msgbox.setWindowTitle('Text preview')
+ msgbox.show()
+ return msgbox.exec_()
diff --git a/graphics/asymptote/GUI/locale/th/LC_MESSAGES/base.po b/graphics/asymptote/GUI/locale/th/LC_MESSAGES/base.po
new file mode 100644
index 0000000000..507fd33561
--- /dev/null
+++ b/graphics/asymptote/GUI/locale/th/LC_MESSAGES/base.po
@@ -0,0 +1,24 @@
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Supakorn Rassameemasmuang, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-05-16 17:07-0600\n"
+"PO-Revision-Date: 2018-05-16 17:20-0700\n"
+"Last-Translator: Supakorn Rassameemasmuang <rassamee@ualberta.ca>\n"
+"Language-Team: English <kde-i18n-doc@kde.org>\n"
+"Language: th\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 2.0\n"
+
+#: xasyStrings.py:10
+msgid "Rotate"
+msgstr "หมุน"
+
+
diff --git a/graphics/asymptote/GUI/pyUIClass/custMatTransform.py b/graphics/asymptote/GUI/pyUIClass/custMatTransform.py
new file mode 100644
index 0000000000..7f35f8d0e7
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/custMatTransform.py
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/custMatTransform.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ Dialog.setObjectName("Dialog")
+ Dialog.resize(500, 320)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
+ Dialog.setSizePolicy(sizePolicy)
+ Dialog.setMinimumSize(QtCore.QSize(500, 320))
+ Dialog.setMaximumSize(QtCore.QSize(500, 320))
+ Dialog.setMouseTracking(False)
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(":/icons/android-expand.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ Dialog.setWindowIcon(icon)
+ Dialog.setSizeGripEnabled(True)
+ Dialog.setModal(False)
+ self.centralFrame = QtWidgets.QFrame(Dialog)
+ self.centralFrame.setGeometry(QtCore.QRect(20, 20, 461, 271))
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.centralFrame.sizePolicy().hasHeightForWidth())
+ self.centralFrame.setSizePolicy(sizePolicy)
+ self.centralFrame.setBaseSize(QtCore.QSize(0, 0))
+ self.centralFrame.setObjectName("centralFrame")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.centralFrame)
+ self.verticalLayout_3.setSpacing(4)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.verticalLayout = QtWidgets.QVBoxLayout()
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.label = QtWidgets.QLabel(self.centralFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
+ self.label.setSizePolicy(sizePolicy)
+ self.label.setObjectName("label")
+ self.verticalLayout.addWidget(self.label)
+ self.gridFrame = QtWidgets.QFrame(self.centralFrame)
+ self.gridFrame.setFrameShape(QtWidgets.QFrame.Box)
+ self.gridFrame.setObjectName("gridFrame")
+ self.gridLayout = QtWidgets.QGridLayout(self.gridFrame)
+ self.gridLayout.setObjectName("gridLayout")
+ self.lineMat00 = QtWidgets.QLineEdit(self.gridFrame)
+ self.lineMat00.setMaximumSize(QtCore.QSize(70, 16777215))
+ self.lineMat00.setObjectName("lineMat00")
+ self.gridLayout.addWidget(self.lineMat00, 1, 0, 1, 1)
+ self.lineMat11 = QtWidgets.QLineEdit(self.gridFrame)
+ self.lineMat11.setMaximumSize(QtCore.QSize(70, 16777215))
+ self.lineMat11.setObjectName("lineMat11")
+ self.gridLayout.addWidget(self.lineMat11, 2, 1, 1, 1)
+ self.lineMat10 = QtWidgets.QLineEdit(self.gridFrame)
+ self.lineMat10.setMaximumSize(QtCore.QSize(70, 16777215))
+ self.lineMat10.setObjectName("lineMat10")
+ self.gridLayout.addWidget(self.lineMat10, 2, 0, 1, 1)
+ self.lineMat01 = QtWidgets.QLineEdit(self.gridFrame)
+ self.lineMat01.setMaximumSize(QtCore.QSize(70, 16777215))
+ self.lineMat01.setObjectName("lineMat01")
+ self.gridLayout.addWidget(self.lineMat01, 1, 1, 1, 1)
+ self.verticalLayout.addWidget(self.gridFrame)
+ self.horizontalLayout_3.addLayout(self.verticalLayout)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_3.addItem(spacerItem)
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.label_3 = QtWidgets.QLabel(self.centralFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
+ self.label_3.setSizePolicy(sizePolicy)
+ self.label_3.setObjectName("label_3")
+ self.verticalLayout_4.addWidget(self.label_3)
+ self.gridFrame_2 = QtWidgets.QFrame(self.centralFrame)
+ self.gridFrame_2.setFrameShape(QtWidgets.QFrame.Box)
+ self.gridFrame_2.setObjectName("gridFrame_2")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.gridFrame_2)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.lineMatTy = QtWidgets.QLineEdit(self.gridFrame_2)
+ self.lineMatTy.setMaximumSize(QtCore.QSize(70, 16777215))
+ self.lineMatTy.setObjectName("lineMatTy")
+ self.gridLayout_2.addWidget(self.lineMatTy, 2, 1, 1, 1)
+ self.lineMatTx = QtWidgets.QLineEdit(self.gridFrame_2)
+ self.lineMatTx.setMaximumSize(QtCore.QSize(70, 16777215))
+ self.lineMatTx.setObjectName("lineMatTx")
+ self.gridLayout_2.addWidget(self.lineMatTx, 1, 1, 1, 1)
+ self.verticalLayout_4.addWidget(self.gridFrame_2)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_4)
+ self.horizontalLayout.addLayout(self.horizontalLayout_3)
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.label_2 = QtWidgets.QLabel(self.centralFrame)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout_2.addWidget(self.label_2)
+ self.imgPreview = QtWidgets.QLabel(self.centralFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.imgPreview.sizePolicy().hasHeightForWidth())
+ self.imgPreview.setSizePolicy(sizePolicy)
+ self.imgPreview.setMinimumSize(QtCore.QSize(150, 150))
+ self.imgPreview.setBaseSize(QtCore.QSize(300, 300))
+ self.imgPreview.setFrameShape(QtWidgets.QFrame.Box)
+ self.imgPreview.setText("")
+ self.imgPreview.setObjectName("imgPreview")
+ self.verticalLayout_2.addWidget(self.imgPreview)
+ self.horizontalLayout.addLayout(self.verticalLayout_2)
+ self.verticalLayout_3.addLayout(self.horizontalLayout)
+ self.lblAnchor = QtWidgets.QLabel(self.centralFrame)
+ self.lblAnchor.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.lblAnchor.setObjectName("lblAnchor")
+ self.verticalLayout_3.addWidget(self.lblAnchor)
+ self.lblCoordsMode = QtWidgets.QLabel(self.centralFrame)
+ self.lblCoordsMode.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.lblCoordsMode.setObjectName("lblCoordsMode")
+ self.verticalLayout_3.addWidget(self.lblCoordsMode)
+ spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ self.verticalLayout_3.addItem(spacerItem2)
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_2.addItem(spacerItem3)
+ self.btnReset = QtWidgets.QPushButton(self.centralFrame)
+ self.btnReset.setObjectName("btnReset")
+ self.horizontalLayout_2.addWidget(self.btnReset)
+ self.btnCancel = QtWidgets.QPushButton(self.centralFrame)
+ self.btnCancel.setObjectName("btnCancel")
+ self.horizontalLayout_2.addWidget(self.btnCancel)
+ self.btnAccept = QtWidgets.QPushButton(self.centralFrame)
+ self.btnAccept.setObjectName("btnAccept")
+ self.horizontalLayout_2.addWidget(self.btnAccept)
+ self.verticalLayout_3.addLayout(self.horizontalLayout_2)
+
+ self.retranslateUi(Dialog)
+ QtCore.QMetaObject.connectSlotsByName(Dialog)
+
+ def retranslateUi(self, Dialog):
+ _translate = QtCore.QCoreApplication.translate
+ Dialog.setWindowTitle(_translate("Dialog", "Set Custom Transformation"))
+ self.label.setText(_translate("Dialog", "Transformation Matrix"))
+ self.lineMat00.setText(_translate("Dialog", "1"))
+ self.lineMat11.setText(_translate("Dialog", "1"))
+ self.lineMat10.setText(_translate("Dialog", "0"))
+ self.lineMat01.setText(_translate("Dialog", "0"))
+ self.label_3.setText(_translate("Dialog", "Translation"))
+ self.lineMatTy.setText(_translate("Dialog", "0"))
+ self.lineMatTx.setText(_translate("Dialog", "0"))
+ self.label_2.setText(_translate("Dialog", "Preview:"))
+ self.imgPreview.setToolTip(_translate("Dialog", "Shows a red square if transformation determinant is negative."))
+ self.lblAnchor.setText(_translate("Dialog", "Anchor: Top Left"))
+ self.lblCoordsMode.setText(_translate("Dialog", "Coordinates: Global"))
+ self.btnReset.setText(_translate("Dialog", "Reset"))
+ self.btnCancel.setText(_translate("Dialog", "Cancel"))
+ self.btnAccept.setText(_translate("Dialog", "Accept"))
+
+import icons_rc
diff --git a/graphics/asymptote/GUI/pyUIClass/labelTextEditor.py b/graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
new file mode 100644
index 0000000000..142f951009
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/labelTextEditor.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ Dialog.setObjectName("Dialog")
+ Dialog.resize(473, 424)
+ self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.frame = QtWidgets.QFrame(Dialog)
+ self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.gridLayout = QtWidgets.QGridLayout()
+ self.gridLayout.setContentsMargins(-1, 0, -1, -1)
+ self.gridLayout.setObjectName("gridLayout")
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.gridLayout.addItem(spacerItem, 0, 2, 1, 1)
+ self.chkMathMode = QtWidgets.QCheckBox(self.frame)
+ self.chkMathMode.setObjectName("chkMathMode")
+ self.gridLayout.addWidget(self.chkMathMode, 0, 0, 1, 1)
+ self.cmbMathStyle = QtWidgets.QComboBox(self.frame)
+ self.cmbMathStyle.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.cmbMathStyle.sizePolicy().hasHeightForWidth())
+ self.cmbMathStyle.setSizePolicy(sizePolicy)
+ self.cmbMathStyle.setMinimumSize(QtCore.QSize(100, 0))
+ self.cmbMathStyle.setObjectName("cmbMathStyle")
+ self.cmbMathStyle.addItem("")
+ self.cmbMathStyle.addItem("")
+ self.cmbMathStyle.addItem("")
+ self.gridLayout.addWidget(self.cmbMathStyle, 0, 1, 1, 1)
+ self.verticalLayout_3.addLayout(self.gridLayout)
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.txtLabelEdit = QtWidgets.QPlainTextEdit(self.frame)
+ self.txtLabelEdit.setObjectName("txtLabelEdit")
+ self.verticalLayout_2.addWidget(self.txtLabelEdit)
+ self.verticalLayout_3.addLayout(self.verticalLayout_2)
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_4.setContentsMargins(-1, 0, -1, -1)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.label = QtWidgets.QLabel(self.frame)
+ self.label.setObjectName("label")
+ self.verticalLayout_4.addWidget(self.label)
+ self.lblLabelPreview = QtWidgets.QLabel(self.frame)
+ self.lblLabelPreview.setMinimumSize(QtCore.QSize(0, 100))
+ self.lblLabelPreview.setFrameShape(QtWidgets.QFrame.Box)
+ self.lblLabelPreview.setText("")
+ self.lblLabelPreview.setObjectName("lblLabelPreview")
+ self.verticalLayout_4.addWidget(self.lblLabelPreview)
+ self.verticalLayout_3.addLayout(self.verticalLayout_4)
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
+ self.btnGetText = QtWidgets.QPushButton(self.frame)
+ self.btnGetText.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnGetText.setText("")
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(":/icons/text.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnGetText.setIcon(icon)
+ self.btnGetText.setFlat(True)
+ self.btnGetText.setObjectName("btnGetText")
+ self.horizontalLayout.addWidget(self.btnGetText)
+ self.btnPreview = QtWidgets.QPushButton(self.frame)
+ self.btnPreview.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnPreview.setText("")
+ icon1 = QtGui.QIcon()
+ icon1.addPixmap(QtGui.QPixmap(":/icons/eye.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnPreview.setIcon(icon1)
+ self.btnPreview.setFlat(True)
+ self.btnPreview.setObjectName("btnPreview")
+ self.horizontalLayout.addWidget(self.btnPreview)
+ self.btnCancel = QtWidgets.QPushButton(self.frame)
+ self.btnCancel.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnCancel.setText("")
+ icon2 = QtGui.QIcon()
+ icon2.addPixmap(QtGui.QPixmap(":/icons/android-close.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnCancel.setIcon(icon2)
+ self.btnCancel.setFlat(True)
+ self.btnCancel.setObjectName("btnCancel")
+ self.horizontalLayout.addWidget(self.btnCancel)
+ self.btnAccept = QtWidgets.QPushButton(self.frame)
+ self.btnAccept.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnAccept.setText("")
+ icon3 = QtGui.QIcon()
+ icon3.addPixmap(QtGui.QPixmap(":/icons/android-done.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnAccept.setIcon(icon3)
+ self.btnAccept.setFlat(True)
+ self.btnAccept.setObjectName("btnAccept")
+ self.horizontalLayout.addWidget(self.btnAccept)
+ self.verticalLayout_3.addLayout(self.horizontalLayout)
+ self.verticalLayout.addWidget(self.frame)
+
+ self.retranslateUi(Dialog)
+ QtCore.QMetaObject.connectSlotsByName(Dialog)
+
+ def retranslateUi(self, Dialog):
+ _translate = QtCore.QCoreApplication.translate
+ Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
+ self.chkMathMode.setText(_translate("Dialog", "Math Mode"))
+ self.cmbMathStyle.setItemText(0, _translate("Dialog", "Inline Style"))
+ self.cmbMathStyle.setItemText(1, _translate("Dialog", "Display Style"))
+ self.cmbMathStyle.setItemText(2, _translate("Dialog", "Script Style"))
+ self.label.setText(_translate("Dialog", "Preview"))
+
+import icons_rc
diff --git a/graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py b/graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
new file mode 100644
index 0000000000..828c27135d
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/setCustomAnchor.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ Dialog.setObjectName("Dialog")
+ Dialog.resize(245, 161)
+ self.verticalLayoutWidget = QtWidgets.QWidget(Dialog)
+ self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 201, 121))
+ self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.formLayout = QtWidgets.QFormLayout()
+ self.formLayout.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
+ self.formLayout.setObjectName("formLayout")
+ self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
+ self.label.setObjectName("label")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
+ self.lineEditX = QtWidgets.QLineEdit(self.verticalLayoutWidget)
+ self.lineEditX.setObjectName("lineEditX")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.lineEditX)
+ self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget)
+ self.label_2.setObjectName("label_2")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
+ self.lineEditY = QtWidgets.QLineEdit(self.verticalLayoutWidget)
+ self.lineEditY.setObjectName("lineEditY")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.lineEditY)
+ self.verticalLayout.addLayout(self.formLayout)
+ self.buttonBox = QtWidgets.QDialogButtonBox(self.verticalLayoutWidget)
+ self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Reset)
+ self.buttonBox.setObjectName("buttonBox")
+ self.verticalLayout.addWidget(self.buttonBox)
+
+ self.retranslateUi(Dialog)
+ self.buttonBox.accepted.connect(Dialog.accept)
+ self.buttonBox.rejected.connect(Dialog.reject)
+ QtCore.QMetaObject.connectSlotsByName(Dialog)
+
+ def retranslateUi(self, Dialog):
+ _translate = QtCore.QCoreApplication.translate
+ Dialog.setWindowTitle(_translate("Dialog", "Set Custom Anchor"))
+ self.label.setText(_translate("Dialog", "X:"))
+ self.lineEditX.setText(_translate("Dialog", "0"))
+ self.label_2.setText(_translate("Dialog", "Y:"))
+ self.lineEditY.setText(_translate("Dialog", "0"))
+
diff --git a/graphics/asymptote/GUI/pyUIClass/widg_addLabel.py b/graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
new file mode 100644
index 0000000000..fba79f6e21
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
@@ -0,0 +1,140 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/widg_addLabel.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ Form.setObjectName("Form")
+ Form.setWindowModality(QtCore.Qt.NonModal)
+ Form.resize(599, 35)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
+ Form.setSizePolicy(sizePolicy)
+ Form.setMinimumSize(QtCore.QSize(0, 35))
+ Form.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(Form)
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_2.setSpacing(0)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.txtLabelText = QtWidgets.QLineEdit(Form)
+ self.txtLabelText.setObjectName("txtLabelText")
+ self.horizontalLayout.addWidget(self.txtLabelText)
+ self.btnAdvancedEdit = QtWidgets.QPushButton(Form)
+ self.btnAdvancedEdit.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnAdvancedEdit.setText("")
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(":/icons/edit.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnAdvancedEdit.setIcon(icon)
+ self.btnAdvancedEdit.setFlat(True)
+ self.btnAdvancedEdit.setObjectName("btnAdvancedEdit")
+ self.horizontalLayout.addWidget(self.btnAdvancedEdit)
+ self.label = QtWidgets.QLabel(Form)
+ self.label.setObjectName("label")
+ self.horizontalLayout.addWidget(self.label)
+ self.cmbAlign = QtWidgets.QComboBox(Form)
+ self.cmbAlign.setObjectName("cmbAlign")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.cmbAlign.addItem("")
+ self.horizontalLayout.addWidget(self.cmbAlign)
+ self.label_3 = QtWidgets.QLabel(Form)
+ self.label_3.setObjectName("label_3")
+ self.horizontalLayout.addWidget(self.label_3)
+ self.cmbFontSize = QtWidgets.QComboBox(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.cmbFontSize.sizePolicy().hasHeightForWidth())
+ self.cmbFontSize.setSizePolicy(sizePolicy)
+ self.cmbFontSize.setEditable(True)
+ self.cmbFontSize.setObjectName("cmbFontSize")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.cmbFontSize.addItem("")
+ self.horizontalLayout.addWidget(self.cmbFontSize)
+ self.label_2 = QtWidgets.QLabel(Form)
+ self.label_2.setObjectName("label_2")
+ self.horizontalLayout.addWidget(self.label_2)
+ self.txtShiftX = QtWidgets.QLineEdit(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.txtShiftX.sizePolicy().hasHeightForWidth())
+ self.txtShiftX.setSizePolicy(sizePolicy)
+ self.txtShiftX.setMaximumSize(QtCore.QSize(50, 16777215))
+ self.txtShiftX.setObjectName("txtShiftX")
+ self.horizontalLayout.addWidget(self.txtShiftX)
+ self.txtShiftY = QtWidgets.QLineEdit(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.txtShiftY.sizePolicy().hasHeightForWidth())
+ self.txtShiftY.setSizePolicy(sizePolicy)
+ self.txtShiftY.setMaximumSize(QtCore.QSize(50, 16777215))
+ self.txtShiftY.setObjectName("txtShiftY")
+ self.horizontalLayout.addWidget(self.txtShiftY)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.horizontalLayout_2.addLayout(self.horizontalLayout)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Form"))
+ self.txtLabelText.setToolTip(_translate("Form", "Number of Sides"))
+ self.txtLabelText.setPlaceholderText(_translate("Form", "Text"))
+ self.label.setText(_translate("Form", "Align"))
+ self.cmbAlign.setItemText(0, _translate("Form", "Center"))
+ self.cmbAlign.setItemText(1, _translate("Form", "N"))
+ self.cmbAlign.setItemText(2, _translate("Form", "E"))
+ self.cmbAlign.setItemText(3, _translate("Form", "W"))
+ self.cmbAlign.setItemText(4, _translate("Form", "S"))
+ self.cmbAlign.setItemText(5, _translate("Form", "NW"))
+ self.cmbAlign.setItemText(6, _translate("Form", "NE"))
+ self.cmbAlign.setItemText(7, _translate("Form", "SW"))
+ self.cmbAlign.setItemText(8, _translate("Form", "SE"))
+ self.cmbAlign.setItemText(9, _translate("Form", "Custom"))
+ self.label_3.setText(_translate("Form", "Font Size"))
+ self.cmbFontSize.setItemText(0, _translate("Form", "-"))
+ self.cmbFontSize.setItemText(1, _translate("Form", "8"))
+ self.cmbFontSize.setItemText(2, _translate("Form", "9"))
+ self.cmbFontSize.setItemText(3, _translate("Form", "10"))
+ self.cmbFontSize.setItemText(4, _translate("Form", "11"))
+ self.cmbFontSize.setItemText(5, _translate("Form", "12"))
+ self.cmbFontSize.setItemText(6, _translate("Form", "14"))
+ self.cmbFontSize.setItemText(7, _translate("Form", "18"))
+ self.cmbFontSize.setItemText(8, _translate("Form", "24"))
+ self.cmbFontSize.setItemText(9, _translate("Form", "48"))
+ self.cmbFontSize.setItemText(10, _translate("Form", "72"))
+ self.label_2.setText(_translate("Form", "Custom Align"))
+ self.txtShiftX.setPlaceholderText(_translate("Form", "Shift X"))
+ self.txtShiftY.setPlaceholderText(_translate("Form", "Shift Y"))
+
+import icons_rc
diff --git a/graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py b/graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
new file mode 100644
index 0000000000..289f0a929b
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/widg_addPolyOpt.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ Form.setObjectName("Form")
+ Form.setWindowModality(QtCore.Qt.NonModal)
+ Form.resize(326, 35)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
+ Form.setSizePolicy(sizePolicy)
+ Form.setMinimumSize(QtCore.QSize(0, 35))
+ Form.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(Form)
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_2.setSpacing(0)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.chkInscribed = QtWidgets.QCheckBox(Form)
+ self.chkInscribed.setObjectName("chkInscribed")
+ self.horizontalLayout.addWidget(self.chkInscribed)
+ self.txtSides = QtWidgets.QLineEdit(Form)
+ self.txtSides.setObjectName("txtSides")
+ self.horizontalLayout.addWidget(self.txtSides)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.horizontalLayout_2.addLayout(self.horizontalLayout)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Form"))
+ self.chkInscribed.setText(_translate("Form", "Start at Vertex"))
+ self.txtSides.setToolTip(_translate("Form", "Number of Sides"))
+ self.txtSides.setPlaceholderText(_translate("Form", "Sides"))
+
diff --git a/graphics/asymptote/GUI/pyUIClass/widg_editBezier.py b/graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
new file mode 100644
index 0000000000..e2d95a8c98
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/widg_editBezier.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ Form.setObjectName("Form")
+ Form.setWindowModality(QtCore.Qt.NonModal)
+ Form.resize(692, 35)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
+ Form.setSizePolicy(sizePolicy)
+ Form.setMinimumSize(QtCore.QSize(0, 35))
+ Form.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(Form)
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_2.setSpacing(0)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.cmbLockMode = QtWidgets.QComboBox(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.cmbLockMode.sizePolicy().hasHeightForWidth())
+ self.cmbLockMode.setSizePolicy(sizePolicy)
+ self.cmbLockMode.setObjectName("cmbLockMode")
+ self.cmbLockMode.addItem("")
+ self.cmbLockMode.addItem("")
+ self.cmbLockMode.addItem("")
+ self.horizontalLayout.addWidget(self.cmbLockMode)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.chkRecompute = QtWidgets.QCheckBox(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.chkRecompute.sizePolicy().hasHeightForWidth())
+ self.chkRecompute.setSizePolicy(sizePolicy)
+ self.chkRecompute.setObjectName("chkRecompute")
+ self.horizontalLayout.addWidget(self.chkRecompute)
+ self.btnForceRecompute = QtWidgets.QPushButton(Form)
+ self.btnForceRecompute.setObjectName("btnForceRecompute")
+ self.horizontalLayout.addWidget(self.btnForceRecompute)
+ self.btnOk = QtWidgets.QPushButton(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnOk.sizePolicy().hasHeightForWidth())
+ self.btnOk.setSizePolicy(sizePolicy)
+ self.btnOk.setMaximumSize(QtCore.QSize(25, 25))
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(":/icons/check.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnOk.setIcon(icon)
+ self.btnOk.setFlat(True)
+ self.btnOk.setObjectName("btnOk")
+ self.horizontalLayout.addWidget(self.btnOk)
+ self.btnCancel = QtWidgets.QPushButton(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnCancel.sizePolicy().hasHeightForWidth())
+ self.btnCancel.setSizePolicy(sizePolicy)
+ self.btnCancel.setMaximumSize(QtCore.QSize(25, 25))
+ icon1 = QtGui.QIcon()
+ icon1.addPixmap(QtGui.QPixmap(":/icons/close-round.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnCancel.setIcon(icon1)
+ self.btnCancel.setFlat(True)
+ self.btnCancel.setObjectName("btnCancel")
+ self.horizontalLayout.addWidget(self.btnCancel)
+ self.horizontalLayout_2.addLayout(self.horizontalLayout)
+
+ self.retranslateUi(Form)
+ self.cmbLockMode.setCurrentIndex(1)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Form"))
+ self.cmbLockMode.setItemText(0, _translate("Form", "No Lock"))
+ self.cmbLockMode.setItemText(1, _translate("Form", "Lock Angle"))
+ self.cmbLockMode.setItemText(2, _translate("Form", "Lock Angle & Scale"))
+ self.chkRecompute.setText(_translate("Form", "Recompute Path"))
+ self.btnForceRecompute.setText(_translate("Form", "Recompute Once"))
+
+import icons_rc
diff --git a/graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py b/graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
new file mode 100644
index 0000000000..c092ede85a
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/widgetPointEditor.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ Form.setObjectName("Form")
+ Form.resize(324, 67)
+ self.verticalLayout = QtWidgets.QVBoxLayout(Form)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.nameLabel = QtWidgets.QLabel(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.nameLabel.sizePolicy().hasHeightForWidth())
+ self.nameLabel.setSizePolicy(sizePolicy)
+ self.nameLabel.setObjectName("nameLabel")
+ self.verticalLayout.addWidget(self.nameLabel)
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.lineXorA = QtWidgets.QLineEdit(Form)
+ self.lineXorA.setEnabled(False)
+ self.lineXorA.setReadOnly(False)
+ self.lineXorA.setObjectName("lineXorA")
+ self.horizontalLayout.addWidget(self.lineXorA)
+ self.lineYorM = QtWidgets.QLineEdit(Form)
+ self.lineYorM.setEnabled(False)
+ self.lineYorM.setAutoFillBackground(False)
+ self.lineYorM.setReadOnly(False)
+ self.lineYorM.setObjectName("lineYorM")
+ self.horizontalLayout.addWidget(self.lineYorM)
+ self.btnRelative = QtWidgets.QPushButton(Form)
+ self.btnRelative.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnRelative.sizePolicy().hasHeightForWidth())
+ self.btnRelative.setSizePolicy(sizePolicy)
+ self.btnRelative.setText("")
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(":/icons/android-locate.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnRelative.setIcon(icon)
+ self.btnRelative.setCheckable(True)
+ self.btnRelative.setFlat(False)
+ self.btnRelative.setObjectName("btnRelative")
+ self.horizontalLayout.addWidget(self.btnRelative)
+ self.btnPolar = QtWidgets.QPushButton(Form)
+ self.btnPolar.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnPolar.sizePolicy().hasHeightForWidth())
+ self.btnPolar.setSizePolicy(sizePolicy)
+ self.btnPolar.setText("")
+ icon1 = QtGui.QIcon()
+ icon1.addPixmap(QtGui.QPixmap(":/icons/android-radio-button-off.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnPolar.setIcon(icon1)
+ self.btnPolar.setCheckable(True)
+ self.btnPolar.setFlat(False)
+ self.btnPolar.setObjectName("btnPolar")
+ self.horizontalLayout.addWidget(self.btnPolar)
+ self.btnManualAdj = QtWidgets.QPushButton(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnManualAdj.sizePolicy().hasHeightForWidth())
+ self.btnManualAdj.setSizePolicy(sizePolicy)
+ self.btnManualAdj.setText("")
+ icon2 = QtGui.QIcon()
+ icon2.addPixmap(QtGui.QPixmap(":/icons/edit.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnManualAdj.setIcon(icon2)
+ self.btnManualAdj.setCheckable(True)
+ self.btnManualAdj.setFlat(False)
+ self.btnManualAdj.setObjectName("btnManualAdj")
+ self.horizontalLayout.addWidget(self.btnManualAdj)
+ self.verticalLayout.addLayout(self.horizontalLayout)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Form"))
+ self.nameLabel.setText(_translate("Form", "Left Control Point"))
+ self.lineXorA.setToolTip(_translate("Form", "X"))
+ self.lineXorA.setPlaceholderText(_translate("Form", "X"))
+ self.lineYorM.setToolTip(_translate("Form", "X"))
+ self.lineYorM.setPlaceholderText(_translate("Form", "Y"))
+
+import icons_rc
diff --git a/graphics/asymptote/GUI/pyUIClass/window1.py b/graphics/asymptote/GUI/pyUIClass/window1.py
new file mode 100644
index 0000000000..f77d018fce
--- /dev/null
+++ b/graphics/asymptote/GUI/pyUIClass/window1.py
@@ -0,0 +1,930 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'GUI/windows/window1.ui'
+#
+# Created by: PyQt5 UI code generator 5.11.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ MainWindow.setObjectName("MainWindow")
+ MainWindow.resize(1030, 768)
+ self.centralwidget = QtWidgets.QWidget(MainWindow)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
+ self.centralwidget.setSizePolicy(sizePolicy)
+ self.centralwidget.setMouseTracking(True)
+ self.centralwidget.setObjectName("centralwidget")
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.centralwidget)
+ self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_4.setSpacing(0)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ self.mainWidget = QtWidgets.QWidget(self.centralwidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.mainWidget.sizePolicy().hasHeightForWidth())
+ self.mainWidget.setSizePolicy(sizePolicy)
+ self.mainWidget.setMouseTracking(True)
+ self.mainWidget.setObjectName("mainWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.mainWidget)
+ self.verticalLayout.setContentsMargins(2, 2, 2, 2)
+ self.verticalLayout.setSpacing(4)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.menuFrame = QtWidgets.QFrame(self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.menuFrame.sizePolicy().hasHeightForWidth())
+ self.menuFrame.setSizePolicy(sizePolicy)
+ self.menuFrame.setFrameShape(QtWidgets.QFrame.NoFrame)
+ self.menuFrame.setObjectName("menuFrame")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.menuFrame)
+ self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
+ self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout.setSpacing(4)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.btnUndo = QtWidgets.QPushButton(self.menuFrame)
+ self.btnUndo.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnUndo.sizePolicy().hasHeightForWidth())
+ self.btnUndo.setSizePolicy(sizePolicy)
+ self.btnUndo.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnUndo.setBaseSize(QtCore.QSize(32, 32))
+ self.btnUndo.setText("")
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(":/icons/android-arrow-back.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnUndo.setIcon(icon)
+ self.btnUndo.setIconSize(QtCore.QSize(16, 16))
+ self.btnUndo.setFlat(True)
+ self.btnUndo.setObjectName("btnUndo")
+ self.horizontalLayout.addWidget(self.btnUndo)
+ self.btnRedo = QtWidgets.QPushButton(self.menuFrame)
+ self.btnRedo.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnRedo.sizePolicy().hasHeightForWidth())
+ self.btnRedo.setSizePolicy(sizePolicy)
+ self.btnRedo.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnRedo.setBaseSize(QtCore.QSize(32, 32))
+ self.btnRedo.setText("")
+ icon1 = QtGui.QIcon()
+ icon1.addPixmap(QtGui.QPixmap(":/icons/android-arrow-forward.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnRedo.setIcon(icon1)
+ self.btnRedo.setFlat(True)
+ self.btnRedo.setObjectName("btnRedo")
+ self.horizontalLayout.addWidget(self.btnRedo)
+ self.btnLoadFile = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnLoadFile.sizePolicy().hasHeightForWidth())
+ self.btnLoadFile.setSizePolicy(sizePolicy)
+ self.btnLoadFile.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnLoadFile.setBaseSize(QtCore.QSize(32, 32))
+ self.btnLoadFile.setText("")
+ icon2 = QtGui.QIcon()
+ icon2.addPixmap(QtGui.QPixmap(":/icons/android-folder-open.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnLoadFile.setIcon(icon2)
+ self.btnLoadFile.setFlat(True)
+ self.btnLoadFile.setObjectName("btnLoadFile")
+ self.horizontalLayout.addWidget(self.btnLoadFile)
+ self.btnSave = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnSave.sizePolicy().hasHeightForWidth())
+ self.btnSave.setSizePolicy(sizePolicy)
+ self.btnSave.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnSave.setBaseSize(QtCore.QSize(32, 32))
+ self.btnSave.setText("")
+ icon3 = QtGui.QIcon()
+ icon3.addPixmap(QtGui.QPixmap(":/icons/save.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnSave.setIcon(icon3)
+ self.btnSave.setFlat(True)
+ self.btnSave.setObjectName("btnSave")
+ self.horizontalLayout.addWidget(self.btnSave)
+ self.btnViewCode = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnViewCode.sizePolicy().hasHeightForWidth())
+ self.btnViewCode.setSizePolicy(sizePolicy)
+ self.btnViewCode.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnViewCode.setBaseSize(QtCore.QSize(32, 32))
+ self.btnViewCode.setText("")
+ icon4 = QtGui.QIcon()
+ icon4.addPixmap(QtGui.QPixmap(":/icons/code.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnViewCode.setIcon(icon4)
+ self.btnViewCode.setFlat(True)
+ self.btnViewCode.setObjectName("btnViewCode")
+ self.horizontalLayout.addWidget(self.btnViewCode)
+ self.btnQuickScreenshot = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnQuickScreenshot.sizePolicy().hasHeightForWidth())
+ self.btnQuickScreenshot.setSizePolicy(sizePolicy)
+ self.btnQuickScreenshot.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnQuickScreenshot.setBaseSize(QtCore.QSize(32, 32))
+ self.btnQuickScreenshot.setText("")
+ icon5 = QtGui.QIcon()
+ icon5.addPixmap(QtGui.QPixmap(":/icons/android-camera.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnQuickScreenshot.setIcon(icon5)
+ self.btnQuickScreenshot.setFlat(True)
+ self.btnQuickScreenshot.setObjectName("btnQuickScreenshot")
+ self.horizontalLayout.addWidget(self.btnQuickScreenshot)
+ spacerItem = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.btnDrawAxes = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnDrawAxes.sizePolicy().hasHeightForWidth())
+ self.btnDrawAxes.setSizePolicy(sizePolicy)
+ self.btnDrawAxes.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnDrawAxes.setBaseSize(QtCore.QSize(32, 32))
+ font = QtGui.QFont()
+ font.setFamily("Roboto")
+ font.setBold(True)
+ font.setWeight(75)
+ self.btnDrawAxes.setFont(font)
+ self.btnDrawAxes.setText("")
+ icon6 = QtGui.QIcon()
+ icon6.addPixmap(QtGui.QPixmap(":/icons/plus-round.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnDrawAxes.setIcon(icon6)
+ self.btnDrawAxes.setCheckable(True)
+ self.btnDrawAxes.setChecked(True)
+ self.btnDrawAxes.setFlat(True)
+ self.btnDrawAxes.setObjectName("btnDrawAxes")
+ self.horizontalLayout.addWidget(self.btnDrawAxes)
+ self.btnDrawGrid = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnDrawGrid.sizePolicy().hasHeightForWidth())
+ self.btnDrawGrid.setSizePolicy(sizePolicy)
+ self.btnDrawGrid.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnDrawGrid.setBaseSize(QtCore.QSize(32, 32))
+ font = QtGui.QFont()
+ font.setFamily("Roboto")
+ font.setBold(True)
+ font.setWeight(75)
+ self.btnDrawGrid.setFont(font)
+ self.btnDrawGrid.setText("")
+ icon7 = QtGui.QIcon()
+ icon7.addPixmap(QtGui.QPixmap(":/icons/grid.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnDrawGrid.setIcon(icon7)
+ self.btnDrawGrid.setCheckable(True)
+ self.btnDrawGrid.setChecked(False)
+ self.btnDrawGrid.setFlat(True)
+ self.btnDrawGrid.setObjectName("btnDrawGrid")
+ self.horizontalLayout.addWidget(self.btnDrawGrid)
+ self.btnSetZoom = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnSetZoom.sizePolicy().hasHeightForWidth())
+ self.btnSetZoom.setSizePolicy(sizePolicy)
+ self.btnSetZoom.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnSetZoom.setBaseSize(QtCore.QSize(32, 32))
+ self.btnSetZoom.setText("")
+ icon8 = QtGui.QIcon()
+ icon8.addPixmap(QtGui.QPixmap(":/icons/magnifying-glass.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnSetZoom.setIcon(icon8)
+ self.btnSetZoom.setFlat(True)
+ self.btnSetZoom.setObjectName("btnSetZoom")
+ self.horizontalLayout.addWidget(self.btnSetZoom)
+ self.btnPanCenter = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnPanCenter.sizePolicy().hasHeightForWidth())
+ self.btnPanCenter.setSizePolicy(sizePolicy)
+ self.btnPanCenter.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnPanCenter.setBaseSize(QtCore.QSize(32, 32))
+ self.btnPanCenter.setText("")
+ icon9 = QtGui.QIcon()
+ icon9.addPixmap(QtGui.QPixmap(":/icons/center.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnPanCenter.setIcon(icon9)
+ self.btnPanCenter.setFlat(True)
+ self.btnPanCenter.setObjectName("btnPanCenter")
+ self.horizontalLayout.addWidget(self.btnPanCenter)
+ self.btnResetPan = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnResetPan.sizePolicy().hasHeightForWidth())
+ self.btnResetPan.setSizePolicy(sizePolicy)
+ self.btnResetPan.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnResetPan.setBaseSize(QtCore.QSize(32, 32))
+ self.btnResetPan.setText("")
+ icon10 = QtGui.QIcon()
+ icon10.addPixmap(QtGui.QPixmap(":/icons/centerorigin.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnResetPan.setIcon(icon10)
+ self.btnResetPan.setFlat(True)
+ self.btnResetPan.setObjectName("btnResetPan")
+ self.horizontalLayout.addWidget(self.btnResetPan)
+ self.btnAlignX = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnAlignX.sizePolicy().hasHeightForWidth())
+ self.btnAlignX.setSizePolicy(sizePolicy)
+ self.btnAlignX.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnAlignX.setBaseSize(QtCore.QSize(32, 32))
+ font = QtGui.QFont()
+ font.setFamily("Roboto")
+ font.setBold(True)
+ font.setWeight(75)
+ self.btnAlignX.setFont(font)
+ self.btnAlignX.setCheckable(True)
+ self.btnAlignX.setFlat(True)
+ self.btnAlignX.setObjectName("btnAlignX")
+ self.horizontalLayout.addWidget(self.btnAlignX)
+ self.btnAlignY = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnAlignY.sizePolicy().hasHeightForWidth())
+ self.btnAlignY.setSizePolicy(sizePolicy)
+ self.btnAlignY.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnAlignY.setBaseSize(QtCore.QSize(32, 32))
+ font = QtGui.QFont()
+ font.setBold(True)
+ font.setWeight(75)
+ self.btnAlignY.setFont(font)
+ self.btnAlignY.setCheckable(True)
+ self.btnAlignY.setFlat(True)
+ self.btnAlignY.setObjectName("btnAlignY")
+ self.horizontalLayout.addWidget(self.btnAlignY)
+ spacerItem1 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
+ self.btnSelectEdit = QtWidgets.QPushButton(self.menuFrame)
+ self.btnSelectEdit.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnSelectEdit.sizePolicy().hasHeightForWidth())
+ self.btnSelectEdit.setSizePolicy(sizePolicy)
+ self.btnSelectEdit.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnSelectEdit.setText("")
+ icon11 = QtGui.QIcon()
+ icon11.addPixmap(QtGui.QPixmap(":/icons/edit.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnSelectEdit.setIcon(icon11)
+ self.btnSelectEdit.setFlat(True)
+ self.btnSelectEdit.setObjectName("btnSelectEdit")
+ self.horizontalLayout.addWidget(self.btnSelectEdit)
+ self.btnDeleteMode = QtWidgets.QPushButton(self.menuFrame)
+ self.btnDeleteMode.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnDeleteMode.sizePolicy().hasHeightForWidth())
+ self.btnDeleteMode.setSizePolicy(sizePolicy)
+ self.btnDeleteMode.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnDeleteMode.setBaseSize(QtCore.QSize(32, 32))
+ self.btnDeleteMode.setText("")
+ icon12 = QtGui.QIcon()
+ icon12.addPixmap(QtGui.QPixmap(":/icons/android-delete.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnDeleteMode.setIcon(icon12)
+ self.btnDeleteMode.setCheckable(False)
+ self.btnDeleteMode.setFlat(True)
+ self.btnDeleteMode.setObjectName("btnDeleteMode")
+ self.horizontalLayout.addWidget(self.btnDeleteMode)
+ spacerItem2 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem2)
+ self.btnPan = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnPan.sizePolicy().hasHeightForWidth())
+ self.btnPan.setSizePolicy(sizePolicy)
+ self.btnPan.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnPan.setBaseSize(QtCore.QSize(32, 32))
+ self.btnPan.setText("")
+ icon13 = QtGui.QIcon()
+ icon13.addPixmap(QtGui.QPixmap(":/icons/android-hand.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnPan.setIcon(icon13)
+ self.btnPan.setCheckable(True)
+ self.btnPan.setFlat(True)
+ self.btnPan.setObjectName("btnPan")
+ self.horizontalLayout.addWidget(self.btnPan)
+ self.btnTranslate = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnTranslate.sizePolicy().hasHeightForWidth())
+ self.btnTranslate.setSizePolicy(sizePolicy)
+ self.btnTranslate.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnTranslate.setBaseSize(QtCore.QSize(32, 32))
+ self.btnTranslate.setText("")
+ icon14 = QtGui.QIcon()
+ icon14.addPixmap(QtGui.QPixmap(":/icons/arrow-move.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnTranslate.setIcon(icon14)
+ self.btnTranslate.setCheckable(True)
+ self.btnTranslate.setChecked(True)
+ self.btnTranslate.setFlat(True)
+ self.btnTranslate.setObjectName("btnTranslate")
+ self.horizontalLayout.addWidget(self.btnTranslate)
+ self.btnScale = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnScale.sizePolicy().hasHeightForWidth())
+ self.btnScale.setSizePolicy(sizePolicy)
+ self.btnScale.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnScale.setBaseSize(QtCore.QSize(32, 32))
+ self.btnScale.setText("")
+ icon15 = QtGui.QIcon()
+ icon15.addPixmap(QtGui.QPixmap(":/icons/arrow-resize.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnScale.setIcon(icon15)
+ self.btnScale.setCheckable(True)
+ self.btnScale.setFlat(True)
+ self.btnScale.setObjectName("btnScale")
+ self.horizontalLayout.addWidget(self.btnScale)
+ self.btnRotate = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnRotate.sizePolicy().hasHeightForWidth())
+ self.btnRotate.setSizePolicy(sizePolicy)
+ self.btnRotate.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnRotate.setBaseSize(QtCore.QSize(32, 32))
+ self.btnRotate.setText("")
+ icon16 = QtGui.QIcon()
+ icon16.addPixmap(QtGui.QPixmap(":/icons/android-refresh.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnRotate.setIcon(icon16)
+ self.btnRotate.setCheckable(True)
+ self.btnRotate.setFlat(True)
+ self.btnRotate.setObjectName("btnRotate")
+ self.horizontalLayout.addWidget(self.btnRotate)
+ spacerItem3 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem3)
+ self.btnAnchor = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnAnchor.sizePolicy().hasHeightForWidth())
+ self.btnAnchor.setSizePolicy(sizePolicy)
+ self.btnAnchor.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnAnchor.setBaseSize(QtCore.QSize(32, 32))
+ self.btnAnchor.setText("")
+ icon17 = QtGui.QIcon()
+ icon17.addPixmap(QtGui.QPixmap(":/icons/anchor.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnAnchor.setIcon(icon17)
+ self.btnAnchor.setCheckable(True)
+ self.btnAnchor.setChecked(False)
+ self.btnAnchor.setFlat(True)
+ self.btnAnchor.setObjectName("btnAnchor")
+ self.horizontalLayout.addWidget(self.btnAnchor)
+ self.comboAnchor = QtWidgets.QComboBox(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.comboAnchor.sizePolicy().hasHeightForWidth())
+ self.comboAnchor.setSizePolicy(sizePolicy)
+ self.comboAnchor.setMinimumSize(QtCore.QSize(127, 0))
+ self.comboAnchor.setMaximumSize(QtCore.QSize(127, 25))
+ self.comboAnchor.setLayoutDirection(QtCore.Qt.LeftToRight)
+ self.comboAnchor.setEditable(False)
+ self.comboAnchor.setInsertPolicy(QtWidgets.QComboBox.InsertAtCurrent)
+ self.comboAnchor.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContentsOnFirstShow)
+ self.comboAnchor.setIconSize(QtCore.QSize(0, 0))
+ self.comboAnchor.setDuplicatesEnabled(False)
+ self.comboAnchor.setFrame(False)
+ self.comboAnchor.setModelColumn(0)
+ self.comboAnchor.setObjectName("comboAnchor")
+ self.comboAnchor.addItem("")
+ self.comboAnchor.addItem("")
+ self.comboAnchor.addItem("")
+ self.comboAnchor.addItem("")
+ self.comboAnchor.addItem("")
+ self.comboAnchor.addItem("")
+ self.comboAnchor.addItem("")
+ self.horizontalLayout.addWidget(self.comboAnchor)
+ self.btnToggleVisible = QtWidgets.QPushButton(self.menuFrame)
+ self.btnToggleVisible.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnToggleVisible.sizePolicy().hasHeightForWidth())
+ self.btnToggleVisible.setSizePolicy(sizePolicy)
+ self.btnToggleVisible.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnToggleVisible.setBaseSize(QtCore.QSize(32, 32))
+ self.btnToggleVisible.setText("")
+ icon18 = QtGui.QIcon()
+ icon18.addPixmap(QtGui.QPixmap(":/icons/eye.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnToggleVisible.setIcon(icon18)
+ self.btnToggleVisible.setCheckable(False)
+ self.btnToggleVisible.setFlat(True)
+ self.btnToggleVisible.setObjectName("btnToggleVisible")
+ self.horizontalLayout.addWidget(self.btnToggleVisible)
+ self.btnCustTransform = QtWidgets.QPushButton(self.menuFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnCustTransform.sizePolicy().hasHeightForWidth())
+ self.btnCustTransform.setSizePolicy(sizePolicy)
+ self.btnCustTransform.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnCustTransform.setBaseSize(QtCore.QSize(32, 32))
+ self.btnCustTransform.setText("")
+ icon19 = QtGui.QIcon()
+ icon19.addPixmap(QtGui.QPixmap(":/icons/android-expand.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnCustTransform.setIcon(icon19)
+ self.btnCustTransform.setFlat(True)
+ self.btnCustTransform.setObjectName("btnCustTransform")
+ self.horizontalLayout.addWidget(self.btnCustTransform)
+ self.btnSendBackwards = QtWidgets.QPushButton(self.menuFrame)
+ self.btnSendBackwards.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnSendBackwards.sizePolicy().hasHeightForWidth())
+ self.btnSendBackwards.setSizePolicy(sizePolicy)
+ self.btnSendBackwards.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnSendBackwards.setBaseSize(QtCore.QSize(32, 32))
+ self.btnSendBackwards.setText("")
+ icon20 = QtGui.QIcon()
+ icon20.addPixmap(QtGui.QPixmap(":/icons/chevron-with-circle-left.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnSendBackwards.setIcon(icon20)
+ self.btnSendBackwards.setFlat(True)
+ self.btnSendBackwards.setObjectName("btnSendBackwards")
+ self.horizontalLayout.addWidget(self.btnSendBackwards)
+ self.btnSendForwards = QtWidgets.QPushButton(self.menuFrame)
+ self.btnSendForwards.setEnabled(False)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnSendForwards.sizePolicy().hasHeightForWidth())
+ self.btnSendForwards.setSizePolicy(sizePolicy)
+ self.btnSendForwards.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnSendForwards.setBaseSize(QtCore.QSize(32, 32))
+ self.btnSendForwards.setText("")
+ icon21 = QtGui.QIcon()
+ icon21.addPixmap(QtGui.QPixmap(":/icons/chevron-with-circle-right.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnSendForwards.setIcon(icon21)
+ self.btnSendForwards.setFlat(True)
+ self.btnSendForwards.setObjectName("btnSendForwards")
+ self.horizontalLayout.addWidget(self.btnSendForwards)
+ spacerItem4 = QtWidgets.QSpacerItem(40, 25, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem4)
+ self.btnUndo.raise_()
+ self.btnRedo.raise_()
+ self.btnLoadFile.raise_()
+ self.btnSave.raise_()
+ self.btnViewCode.raise_()
+ self.btnQuickScreenshot.raise_()
+ self.btnDrawAxes.raise_()
+ self.btnDrawGrid.raise_()
+ self.btnSetZoom.raise_()
+ self.btnPanCenter.raise_()
+ self.btnResetPan.raise_()
+ self.btnAlignX.raise_()
+ self.btnAlignY.raise_()
+ self.btnPan.raise_()
+ self.btnTranslate.raise_()
+ self.btnScale.raise_()
+ self.btnCustTransform.raise_()
+ self.btnSendBackwards.raise_()
+ self.btnSendForwards.raise_()
+ self.comboAnchor.raise_()
+ self.btnToggleVisible.raise_()
+ self.btnAnchor.raise_()
+ self.btnRotate.raise_()
+ self.btnSelectEdit.raise_()
+ self.btnDeleteMode.raise_()
+ self.verticalLayout.addWidget(self.menuFrame)
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_2.setSpacing(4)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_2.setSpacing(3)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.addOption = QtWidgets.QHBoxLayout()
+ self.addOption.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
+ self.addOption.setContentsMargins(6, -1, -1, 0)
+ self.addOption.setSpacing(6)
+ self.addOption.setObjectName("addOption")
+ self.btnFill = QtWidgets.QPushButton(self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnFill.sizePolicy().hasHeightForWidth())
+ self.btnFill.setSizePolicy(sizePolicy)
+ self.btnFill.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnFill.setBaseSize(QtCore.QSize(32, 32))
+ self.btnFill.setAutoFillBackground(False)
+ self.btnFill.setStyleSheet("")
+ self.btnFill.setText("")
+ icon22 = QtGui.QIcon()
+ icon22.addPixmap(QtGui.QPixmap(":/icons/bucket.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon22.addPixmap(QtGui.QPixmap(":/icons/filledbucket.svg"), QtGui.QIcon.Normal, QtGui.QIcon.On)
+ self.btnFill.setIcon(icon22)
+ self.btnFill.setCheckable(True)
+ self.btnFill.setDefault(False)
+ self.btnFill.setFlat(True)
+ self.btnFill.setObjectName("btnFill")
+ self.addOption.addWidget(self.btnFill)
+ self.addOptionLayout = QtWidgets.QGridLayout()
+ self.addOptionLayout.setSpacing(6)
+ self.addOptionLayout.setObjectName("addOptionLayout")
+ self.addOption.addLayout(self.addOptionLayout)
+ spacerItem5 = QtWidgets.QSpacerItem(40, 35, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Minimum)
+ self.addOption.addItem(spacerItem5)
+ self.label = QtWidgets.QLabel(self.mainWidget)
+ self.label.setObjectName("label")
+ self.addOption.addWidget(self.label)
+ self.txtLineWidth = QtWidgets.QLineEdit(self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.txtLineWidth.sizePolicy().hasHeightForWidth())
+ self.txtLineWidth.setSizePolicy(sizePolicy)
+ self.txtLineWidth.setMaximumSize(QtCore.QSize(75, 16777215))
+ self.txtLineWidth.setObjectName("txtLineWidth")
+ self.addOption.addWidget(self.txtLineWidth)
+ self.frameCurrColor = QtWidgets.QFrame(self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frameCurrColor.sizePolicy().hasHeightForWidth())
+ self.frameCurrColor.setSizePolicy(sizePolicy)
+ self.frameCurrColor.setMinimumSize(QtCore.QSize(15, 15))
+ self.frameCurrColor.setAutoFillBackground(False)
+ self.frameCurrColor.setStyleSheet("QFrame{ \n"
+"padding: 4.0;\n"
+"border-radius: 3.0; \n"
+"background: rgb(0, 0, 0)\n"
+"}")
+ self.frameCurrColor.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frameCurrColor.setFrameShadow(QtWidgets.QFrame.Sunken)
+ self.frameCurrColor.setObjectName("frameCurrColor")
+ self.addOption.addWidget(self.frameCurrColor)
+ self.btnSelectColor = QtWidgets.QPushButton(self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnSelectColor.sizePolicy().hasHeightForWidth())
+ self.btnSelectColor.setSizePolicy(sizePolicy)
+ self.btnSelectColor.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnSelectColor.setBaseSize(QtCore.QSize(32, 32))
+ self.btnSelectColor.setAutoFillBackground(False)
+ self.btnSelectColor.setStyleSheet("")
+ self.btnSelectColor.setText("")
+ icon23 = QtGui.QIcon()
+ icon23.addPixmap(QtGui.QPixmap(":/icons/android-color-palette.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnSelectColor.setIcon(icon23)
+ self.btnSelectColor.setDefault(False)
+ self.btnSelectColor.setFlat(True)
+ self.btnSelectColor.setObjectName("btnSelectColor")
+ self.addOption.addWidget(self.btnSelectColor)
+ self.verticalLayout_2.addLayout(self.addOption)
+ self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_7.setContentsMargins(-1, 6, -1, -1)
+ self.horizontalLayout_7.setSpacing(6)
+ self.horizontalLayout_7.setObjectName("horizontalLayout_7")
+ self.formFrame = QtWidgets.QFrame(self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.formFrame.sizePolicy().hasHeightForWidth())
+ self.formFrame.setSizePolicy(sizePolicy)
+ self.formFrame.setFrameShape(QtWidgets.QFrame.NoFrame)
+ self.formFrame.setFrameShadow(QtWidgets.QFrame.Plain)
+ self.formFrame.setLineWidth(0)
+ self.formFrame.setObjectName("formFrame")
+ self.formLayout = QtWidgets.QFormLayout(self.formFrame)
+ self.formLayout.setContentsMargins(0, 0, 0, 0)
+ self.formLayout.setSpacing(0)
+ self.formLayout.setObjectName("formLayout")
+ self.btnOpenPoly = QtWidgets.QPushButton(self.formFrame)
+ self.btnOpenPoly.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnOpenPoly.sizePolicy().hasHeightForWidth())
+ self.btnOpenPoly.setSizePolicy(sizePolicy)
+ self.btnOpenPoly.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnOpenPoly.setText("")
+ icon24 = QtGui.QIcon()
+ icon24.addPixmap(QtGui.QPixmap(":/icons/openpolygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnOpenPoly.setIcon(icon24)
+ self.btnOpenPoly.setFlat(True)
+ self.btnOpenPoly.setObjectName("btnOpenPoly")
+ self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.btnOpenPoly)
+ self.btnClosedPoly = QtWidgets.QPushButton(self.formFrame)
+ self.btnClosedPoly.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnClosedPoly.sizePolicy().hasHeightForWidth())
+ self.btnClosedPoly.setSizePolicy(sizePolicy)
+ self.btnClosedPoly.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnClosedPoly.setText("")
+ icon25 = QtGui.QIcon()
+ icon25.addPixmap(QtGui.QPixmap(":/icons/closedpolygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnClosedPoly.setIcon(icon25)
+ self.btnClosedPoly.setFlat(True)
+ self.btnClosedPoly.setObjectName("btnClosedPoly")
+ self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.btnClosedPoly)
+ self.btnOpenCurve = QtWidgets.QPushButton(self.formFrame)
+ self.btnOpenCurve.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnOpenCurve.sizePolicy().hasHeightForWidth())
+ self.btnOpenCurve.setSizePolicy(sizePolicy)
+ self.btnOpenCurve.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnOpenCurve.setText("")
+ icon26 = QtGui.QIcon()
+ icon26.addPixmap(QtGui.QPixmap(":/icons/opencurve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnOpenCurve.setIcon(icon26)
+ self.btnOpenCurve.setFlat(True)
+ self.btnOpenCurve.setObjectName("btnOpenCurve")
+ self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.btnOpenCurve)
+ self.btnClosedCurve = QtWidgets.QPushButton(self.formFrame)
+ self.btnClosedCurve.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnClosedCurve.sizePolicy().hasHeightForWidth())
+ self.btnClosedCurve.setSizePolicy(sizePolicy)
+ self.btnClosedCurve.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnClosedCurve.setText("")
+ icon27 = QtGui.QIcon()
+ icon27.addPixmap(QtGui.QPixmap(":/icons/closedcurve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnClosedCurve.setIcon(icon27)
+ self.btnClosedCurve.setFlat(True)
+ self.btnClosedCurve.setObjectName("btnClosedCurve")
+ self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.btnClosedCurve)
+ self.btnAddPoly = QtWidgets.QPushButton(self.formFrame)
+ self.btnAddPoly.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnAddPoly.sizePolicy().hasHeightForWidth())
+ self.btnAddPoly.setSizePolicy(sizePolicy)
+ self.btnAddPoly.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnAddPoly.setText("")
+ icon28 = QtGui.QIcon()
+ icon28.addPixmap(QtGui.QPixmap(":/icons/triangle-stroked-15.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnAddPoly.setIcon(icon28)
+ self.btnAddPoly.setFlat(True)
+ self.btnAddPoly.setObjectName("btnAddPoly")
+ self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.btnAddPoly)
+ self.btnAddCircle = QtWidgets.QPushButton(self.formFrame)
+ self.btnAddCircle.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnAddCircle.sizePolicy().hasHeightForWidth())
+ self.btnAddCircle.setSizePolicy(sizePolicy)
+ self.btnAddCircle.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnAddCircle.setText("")
+ icon29 = QtGui.QIcon()
+ icon29.addPixmap(QtGui.QPixmap(":/icons/circle.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnAddCircle.setIcon(icon29)
+ self.btnAddCircle.setFlat(True)
+ self.btnAddCircle.setObjectName("btnAddCircle")
+ self.formLayout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.btnAddCircle)
+ self.btnAddLabel = QtWidgets.QPushButton(self.formFrame)
+ self.btnAddLabel.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnAddLabel.sizePolicy().hasHeightForWidth())
+ self.btnAddLabel.setSizePolicy(sizePolicy)
+ self.btnAddLabel.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnAddLabel.setText("")
+ icon30 = QtGui.QIcon()
+ icon30.addPixmap(QtGui.QPixmap(":/icons/text.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnAddLabel.setIcon(icon30)
+ self.btnAddLabel.setFlat(True)
+ self.btnAddLabel.setObjectName("btnAddLabel")
+ self.formLayout.setWidget(11, QtWidgets.QFormLayout.LabelRole, self.btnAddLabel)
+ self.horizontalLayout_7.addWidget(self.formFrame)
+ self.imgFrame = QtWidgets.QFrame(self.mainWidget)
+ self.imgFrame.setMinimumSize(QtCore.QSize(0, 6))
+ self.imgFrame.setMouseTracking(True)
+ self.imgFrame.setFrameShape(QtWidgets.QFrame.NoFrame)
+ self.imgFrame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.imgFrame.setObjectName("imgFrame")
+ self.gridLayout = QtWidgets.QGridLayout(self.imgFrame)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.imgLabel = QtWidgets.QLabel(self.imgFrame)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.imgLabel.sizePolicy().hasHeightForWidth())
+ self.imgLabel.setSizePolicy(sizePolicy)
+ self.imgLabel.setMouseTracking(True)
+ self.imgLabel.setFrameShape(QtWidgets.QFrame.Panel)
+ self.imgLabel.setText("")
+ self.imgLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
+ self.imgLabel.setObjectName("imgLabel")
+ self.gridLayout.addWidget(self.imgLabel, 0, 1, 1, 1)
+ self.horizontalLayout_7.addWidget(self.imgFrame)
+ self.verticalLayout_2.addLayout(self.horizontalLayout_7)
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_3.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
+ self.horizontalLayout_3.setContentsMargins(-1, 0, -1, -1)
+ self.horizontalLayout_3.setSpacing(0)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.btnTogglePython = QtWidgets.QPushButton(self.mainWidget)
+ self.btnTogglePython.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnTogglePython.sizePolicy().hasHeightForWidth())
+ self.btnTogglePython.setSizePolicy(sizePolicy)
+ self.btnTogglePython.setText("")
+ icon31 = QtGui.QIcon()
+ icon31.addPixmap(QtGui.QPixmap(":/icons/social-python.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnTogglePython.setIcon(icon31)
+ self.btnTogglePython.setIconSize(QtCore.QSize(16, 16))
+ self.btnTogglePython.setCheckable(True)
+ self.btnTogglePython.setFlat(True)
+ self.btnTogglePython.setObjectName("btnTogglePython")
+ self.horizontalLayout_3.addWidget(self.btnTogglePython)
+ self.txtTerminalPrompt = QtWidgets.QLineEdit(self.mainWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.txtTerminalPrompt.sizePolicy().hasHeightForWidth())
+ self.txtTerminalPrompt.setSizePolicy(sizePolicy)
+ self.txtTerminalPrompt.setObjectName("txtTerminalPrompt")
+ self.horizontalLayout_3.addWidget(self.txtTerminalPrompt)
+ self.btnEnterCommand = QtWidgets.QPushButton(self.mainWidget)
+ self.btnEnterCommand.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnEnterCommand.sizePolicy().hasHeightForWidth())
+ self.btnEnterCommand.setSizePolicy(sizePolicy)
+ self.btnEnterCommand.setText("")
+ icon32 = QtGui.QIcon()
+ icon32.addPixmap(QtGui.QPixmap(":/icons/subdirectory-left.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnEnterCommand.setIcon(icon32)
+ self.btnEnterCommand.setFlat(True)
+ self.btnEnterCommand.setObjectName("btnEnterCommand")
+ self.horizontalLayout_3.addWidget(self.btnEnterCommand)
+ self.verticalLayout_2.addLayout(self.horizontalLayout_3)
+ self.horizontalLayout_2.addLayout(self.verticalLayout_2)
+ self.verticalLayout.addLayout(self.horizontalLayout_2)
+ self.horizontalLayout_4.addWidget(self.mainWidget)
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(MainWindow)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 1030, 28))
+ self.menubar.setObjectName("menubar")
+ self.menuFIle = QtWidgets.QMenu(self.menubar)
+ self.menuFIle.setObjectName("menuFIle")
+ self.menuEdit = QtWidgets.QMenu(self.menubar)
+ self.menuEdit.setObjectName("menuEdit")
+ self.menuOptions = QtWidgets.QMenu(self.menubar)
+ self.menuOptions.setObjectName("menuOptions")
+ self.menuHelp = QtWidgets.QMenu(self.menubar)
+ self.menuHelp.setObjectName("menuHelp")
+ self.menuTools = QtWidgets.QMenu(self.menubar)
+ self.menuTools.setObjectName("menuTools")
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(MainWindow)
+ self.statusbar.setSizeGripEnabled(False)
+ self.statusbar.setObjectName("statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+ self.actionAbout = QtWidgets.QAction(MainWindow)
+ self.actionAbout.setObjectName("actionAbout")
+ self.actionManual = QtWidgets.QAction(MainWindow)
+ self.actionManual.setObjectName("actionManual")
+ self.actionSettings = QtWidgets.QAction(MainWindow)
+ self.actionSettings.setObjectName("actionSettings")
+ self.actionPause = QtWidgets.QAction(MainWindow)
+ self.actionPause.setObjectName("actionPause")
+ self.actionSaveAs = QtWidgets.QAction(MainWindow)
+ self.actionSaveAs.setObjectName("actionSaveAs")
+ self.actionEnterCommand = QtWidgets.QAction(MainWindow)
+ self.actionEnterCommand.setObjectName("actionEnterCommand")
+ self.actionQuit = QtWidgets.QAction(MainWindow)
+ self.actionQuit.setObjectName("actionQuit")
+ self.actionUndo = QtWidgets.QAction(MainWindow)
+ self.actionUndo.setEnabled(False)
+ self.actionUndo.setObjectName("actionUndo")
+ self.actionRedo = QtWidgets.QAction(MainWindow)
+ self.actionRedo.setEnabled(False)
+ self.actionRedo.setObjectName("actionRedo")
+ self.actionShow_Grid = QtWidgets.QAction(MainWindow)
+ self.actionShow_Grid.setObjectName("actionShow_Grid")
+ self.actionShow_Local_Grid = QtWidgets.QAction(MainWindow)
+ self.actionShow_Local_Grid.setObjectName("actionShow_Local_Grid")
+ self.actionTransform = QtWidgets.QAction(MainWindow)
+ self.actionTransform.setObjectName("actionTransform")
+ self.actionExportAsymptote = QtWidgets.QAction(MainWindow)
+ self.actionExportAsymptote.setObjectName("actionExportAsymptote")
+ self.actionSave = QtWidgets.QAction(MainWindow)
+ self.actionSave.setObjectName("actionSave")
+ self.actionOpen = QtWidgets.QAction(MainWindow)
+ self.actionOpen.setObjectName("actionOpen")
+ self.menuFIle.addAction(self.actionOpen)
+ self.menuFIle.addAction(self.actionSave)
+ self.menuFIle.addAction(self.actionSaveAs)
+ self.menuFIle.addAction(self.actionExportAsymptote)
+ self.menuFIle.addSeparator()
+ self.menuFIle.addAction(self.actionQuit)
+ self.menuEdit.addAction(self.actionUndo)
+ self.menuEdit.addAction(self.actionRedo)
+ self.menuEdit.addSeparator()
+ self.menuOptions.addAction(self.actionSettings)
+ self.menuHelp.addAction(self.actionManual)
+ self.menuHelp.addAction(self.actionAbout)
+ self.menuTools.addAction(self.actionEnterCommand)
+ self.menubar.addAction(self.menuFIle.menuAction())
+ self.menubar.addAction(self.menuEdit.menuAction())
+ self.menubar.addAction(self.menuOptions.menuAction())
+ self.menubar.addAction(self.menuTools.menuAction())
+ self.menubar.addAction(self.menuHelp.menuAction())
+
+ self.retranslateUi(MainWindow)
+ self.comboAnchor.setCurrentIndex(0)
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+ def retranslateUi(self, MainWindow):
+ _translate = QtCore.QCoreApplication.translate
+ MainWindow.setWindowTitle(_translate("MainWindow", "xasy"))
+ self.btnUndo.setToolTip(_translate("MainWindow", "Undo"))
+ self.btnRedo.setToolTip(_translate("MainWindow", "Redo"))
+ self.btnLoadFile.setToolTip(_translate("MainWindow", "<html><head/><body><p>Open file</p></body></html>"))
+ self.btnSave.setToolTip(_translate("MainWindow", "<html><head/><body><p>Save file</p></body></html>"))
+ self.btnViewCode.setToolTip(_translate("MainWindow", "<html><head/><body><p>Edit code</p></body></html>"))
+ self.btnQuickScreenshot.setToolTip(_translate("MainWindow", "<html><head/><body><p>Screenshot</p></body></html>"))
+ self.btnDrawAxes.setToolTip(_translate("MainWindow", "<html><head/><body><p>Toggle display axes</p></body></html>"))
+ self.btnDrawGrid.setToolTip(_translate("MainWindow", "<html><head/><body><p>Toggle grid</p></body></html>"))
+ self.btnSetZoom.setToolTip(_translate("MainWindow", "Synchronize with Asymptote"))
+ self.btnPanCenter.setToolTip(_translate("MainWindow", "<html><head/><body><p>Center</p></body></html>"))
+ self.btnResetPan.setToolTip(_translate("MainWindow", "<html><head/><body><p>Center about origin</p></body></html>"))
+ self.btnAlignX.setToolTip(_translate("MainWindow", "<html><head/><body><p>Lock transform to X axis</p></body></html>"))
+ self.btnAlignX.setText(_translate("MainWindow", "X"))
+ self.btnAlignY.setToolTip(_translate("MainWindow", "<html><head/><body><p>Lock transform to Y axis</p></body></html>"))
+ self.btnAlignY.setText(_translate("MainWindow", "Y"))
+ self.btnSelectEdit.setToolTip(_translate("MainWindow", "<html><head/><body><p>Bézier editor</p></body></html>"))
+ self.btnDeleteMode.setToolTip(_translate("MainWindow", "<html><head/><body><p>Delete</p></body></html>"))
+ self.btnPan.setToolTip(_translate("MainWindow", "Pan"))
+ self.btnTranslate.setToolTip(_translate("MainWindow", "Translate"))
+ self.btnScale.setToolTip(_translate("MainWindow", "Scale"))
+ self.btnRotate.setToolTip(_translate("MainWindow", "Rotate"))
+ self.btnAnchor.setToolTip(_translate("MainWindow", "<html><head/><body><p>Set custom anchor</p></body></html>"))
+ self.comboAnchor.setToolTip(_translate("MainWindow", "<html><head/><body><p>Anchor</p></body></html>"))
+ self.comboAnchor.setCurrentText(_translate("MainWindow", "Origin"))
+ self.comboAnchor.setItemText(0, _translate("MainWindow", "Origin"))
+ self.comboAnchor.setItemText(1, _translate("MainWindow", "Center"))
+ self.comboAnchor.setItemText(2, _translate("MainWindow", "Top Left"))
+ self.comboAnchor.setItemText(3, _translate("MainWindow", "Top Right"))
+ self.comboAnchor.setItemText(4, _translate("MainWindow", "Bottom Right"))
+ self.comboAnchor.setItemText(5, _translate("MainWindow", "Bottom Left"))
+ self.comboAnchor.setItemText(6, _translate("MainWindow", "Custom"))
+ self.btnCustTransform.setToolTip(_translate("MainWindow", "<html><head/><body><p><br/></p></body></html>"))
+ self.btnSendBackwards.setToolTip(_translate("MainWindow", "<html><head/><body><p><br/></p></body></html>"))
+ self.btnSendForwards.setToolTip(_translate("MainWindow", "Translate"))
+ self.btnFill.setToolTip(_translate("MainWindow", "<html><head/><body><p>Toggle fill/outline</p></body></html>"))
+ self.label.setText(_translate("MainWindow", "Line Width:"))
+ self.txtLineWidth.setToolTip(_translate("MainWindow", "<html><head/><body><p>Current pen width</p></body></html>"))
+ self.frameCurrColor.setToolTip(_translate("MainWindow", "<html><head/><body><p>Current pen color</p></body></html>"))
+ self.btnSelectColor.setToolTip(_translate("MainWindow", "<html><head/><body><p>Set color</p></body></html>"))
+ self.btnOpenPoly.setToolTip(_translate("MainWindow", "<html><head/><body><p>Open polygon</p></body></html>"))
+ self.btnClosedPoly.setToolTip(_translate("MainWindow", "<html><head/><body><p>Closed polygon</p></body></html>"))
+ self.btnOpenCurve.setToolTip(_translate("MainWindow", "<html><head/><body><p>Open Bézier curve</p></body></html>"))
+ self.btnClosedCurve.setToolTip(_translate("MainWindow", "<html><head/><body><p>Closed Bézier curve</p></body></html>"))
+ self.btnAddPoly.setToolTip(_translate("MainWindow", "<html><head/><body><p>Regular polygon</p></body></html>"))
+ self.btnAddCircle.setToolTip(_translate("MainWindow", "<html><head/><body><p>Circle</p></body></html>"))
+ self.btnAddLabel.setToolTip(_translate("MainWindow", "<html><head/><body><p>Text</p></body></html>"))
+ self.menuFIle.setTitle(_translate("MainWindow", "&File"))
+ self.menuEdit.setTitle(_translate("MainWindow", "&Edit"))
+ self.menuOptions.setTitle(_translate("MainWindow", "Optio&ns"))
+ self.menuHelp.setTitle(_translate("MainWindow", "&Help"))
+ self.menuTools.setTitle(_translate("MainWindow", "&Tools"))
+ self.actionAbout.setText(_translate("MainWindow", "&About"))
+ self.actionManual.setText(_translate("MainWindow", "&Manual"))
+ self.actionSettings.setText(_translate("MainWindow", "&Settings"))
+ self.actionPause.setText(_translate("MainWindow", "Pause "))
+ self.actionSaveAs.setText(_translate("MainWindow", "&Save As"))
+ self.actionEnterCommand.setText(_translate("MainWindow", "&Enter Command"))
+ self.actionQuit.setText(_translate("MainWindow", "&Quit"))
+ self.actionUndo.setText(_translate("MainWindow", "&Undo"))
+ self.actionRedo.setText(_translate("MainWindow", "&Redo"))
+ self.actionShow_Grid.setText(_translate("MainWindow", "&Show Grid"))
+ self.actionShow_Local_Grid.setText(_translate("MainWindow", "Show &Local Grid"))
+ self.actionTransform.setText(_translate("MainWindow", "&Transform"))
+ self.actionExportAsymptote.setText(_translate("MainWindow", "Export"))
+ self.actionSave.setText(_translate("MainWindow", "Save"))
+ self.actionOpen.setText(_translate("MainWindow", "Open"))
+
+import icons_rc
diff --git a/graphics/asymptote/GUI/requirements.txt b/graphics/asymptote/GUI/requirements.txt
new file mode 100644
index 0000000000..47966fe275
--- /dev/null
+++ b/graphics/asymptote/GUI/requirements.txt
@@ -0,0 +1,4 @@
+numpy==1.11.0
+cson==0.7
+PyQt5==5.11
+rsvg-convert==2.42.3
diff --git a/graphics/asymptote/GUI/res/icons.qrc b/graphics/asymptote/GUI/res/icons.qrc
new file mode 100644
index 0000000000..50928ef9b7
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons.qrc
@@ -0,0 +1,45 @@
+<RCC>
+ <qresource prefix="">
+ <file>icons/android-arrow-back.svg</file>
+ <file>icons/android-arrow-forward.svg</file>
+ <file>icons/android-folder-open.svg</file>
+ <file>icons/save.svg</file>
+ <file>icons/code.svg</file>
+ <file>icons/android-camera.svg</file>
+ <file>icons/plus-round.svg</file>
+ <file>icons/grid.svg</file>
+ <file>icons/magnifying-glass.svg</file>
+ <file>icons/center.svg</file>
+ <file>icons/centerorigin.svg</file>
+ <file>icons/edit.svg</file>
+ <file>icons/android-delete.svg</file>
+ <file>icons/android-hand.svg</file>
+ <file>icons/arrow-move.svg</file>
+ <file>icons/arrow-resize.svg</file>
+ <file>icons/android-refresh.svg</file>
+ <file>icons/anchor.svg</file>
+ <file>icons/eye.svg</file>
+ <file>icons/android-expand.svg</file>
+ <file>icons/chevron-with-circle-left.svg</file>
+ <file>icons/chevron-with-circle-right.svg</file>
+ <file>icons/bucket.svg</file>
+ <file>icons/filledbucket.svg</file>
+ <file>icons/android-color-palette.svg</file>
+ <file>icons/openpolygon.svg</file>
+ <file>icons/closedpolygon.svg</file>
+ <file>icons/opencurve.svg</file>
+ <file>icons/closedcurve.svg</file>
+ <file>icons/triangle-stroked-15.svg</file>
+ <file>icons/circle.svg</file>
+ <file>icons/text.svg</file>
+ <file>icons/social-python.svg</file>
+ <file>icons/subdirectory-left.svg</file>
+ <file>icons/android-done.svg</file>
+ <file>icons/android-close.svg</file>
+ <file>icons/check.svg</file>
+ <file>icons/android-radio-button-on.svg</file>
+ <file>icons/android-radio-button-off.svg</file>
+ <file>icons/android-locate.svg</file>
+ <file>icons/close-round.svg</file>
+ </qresource>
+</RCC>
diff --git a/graphics/asymptote/GUI/res/icons/anchor.svg b/graphics/asymptote/GUI/res/icons/anchor.svg
new file mode 100644
index 0000000000..886aadebf9
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/anchor.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M4.34 15.66A7.97 7.97 0 0 0 9 17.94V10H5V8h4V5.83a3 3 0 1 1 2 0V8h4v2h-4v7.94a7.97 7.97 0 0 0 4.66-2.28l-1.42-1.42h5.66l-2.83 2.83a10 10 0 0 1-14.14 0L.1 14.24h5.66l-1.42 1.42zM10 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/android-arrow-back.svg b/graphics/asymptote/GUI/res/icons/android-arrow-back.svg
new file mode 100644
index 0000000000..79cfe814a1
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-arrow-back.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon_8_">
+ <g>
+ <path d="M427,234.625H167.296l119.702-119.702L256,85L85,256l171,171l29.922-29.924L167.296,277.375H427V234.625z"/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-arrow-forward.svg b/graphics/asymptote/GUI/res/icons/android-arrow-forward.svg
new file mode 100644
index 0000000000..d63794dcc0
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-arrow-forward.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon_8_">
+ <g>
+ <path d="M85,277.375h259.704L225.002,397.077L256,427l171-171L256,85l-29.922,29.924l118.626,119.701H85V277.375z"/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-camera.svg b/graphics/asymptote/GUI/res/icons/android-camera.svg
new file mode 100644
index 0000000000..73aeaabe49
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-camera.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g>
+ <circle cx="256" cy="280" r="63"/>
+ <path d="M440,96h-88l-32-32H192l-32,32H72c-22.092,0-40,17.908-40,40v272c0,22.092,17.908,40,40,40h368c22.092,0,40-17.908,40-40
+ V136C480,113.908,462.092,96,440,96z M256,392c-61.855,0-112-50.145-112-112s50.145-112,112-112s112,50.145,112,112
+ S317.855,392,256,392z"/>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-close.svg b/graphics/asymptote/GUI/res/icons/android-close.svg
new file mode 100644
index 0000000000..aee0f9f630
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-close.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon_5_">
+ <g>
+ <polygon points="405,136.798 375.202,107 256,226.202 136.798,107 107,136.798 226.202,256 107,375.202 136.798,405 256,285.798
+ 375.202,405 405,375.202 285.798,256 "/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-color-palette.svg b/graphics/asymptote/GUI/res/icons/android-color-palette.svg
new file mode 100644
index 0000000000..d700fe6b9d
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-color-palette.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon_12_">
+ <g>
+ <path d="M256,64C150.401,64,64,150.401,64,256c0,105.604,86.401,192,192,192c18.136,0,32-13.864,32-32
+ c0-8.531-3.198-16-8.531-21.333c-5.333-5.334-8.531-12.803-8.531-21.334c0-18.135,13.864-32,32-32h38.396
+ c58.667,0,106.667-48,106.667-106.666C448,140.802,361.604,64,256,64z M138.667,256c-18.136,0-32-13.864-32-32s13.864-32,32-32
+ c18.135,0,32,13.864,32,32S156.802,256,138.667,256z M202.667,170.667c-18.136,0-32-13.865-32-32c0-18.136,13.864-32,32-32
+ c18.135,0,32,13.864,32,32C234.667,156.802,220.802,170.667,202.667,170.667z M309.333,170.667c-18.135,0-32-13.865-32-32
+ c0-18.136,13.865-32,32-32c18.136,0,32,13.864,32,32C341.333,156.802,327.469,170.667,309.333,170.667z M373.333,256
+ c-18.135,0-32-13.864-32-32s13.865-32,32-32c18.136,0,32,13.864,32,32S391.469,256,373.333,256z"/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-delete.svg b/graphics/asymptote/GUI/res/icons/android-delete.svg
new file mode 100644
index 0000000000..49cfa5ade4
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-delete.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g>
+ <path d="M128,405.429C128,428.846,147.198,448,170.667,448h170.667C364.802,448,384,428.846,384,405.429V160H128V405.429z M416,96
+ h-80l-26.785-32H202.786L176,96H96v32h320V96z"/>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-done.svg b/graphics/asymptote/GUI/res/icons/android-done.svg
new file mode 100644
index 0000000000..4bcb946f05
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-done.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon_1_">
+ <g>
+ <g>
+ <polygon points="186.301,339.893 96,249.461 64,279.968 186.301,402 448,140.506 416,110 "/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-expand.svg b/graphics/asymptote/GUI/res/icons/android-expand.svg
new file mode 100644
index 0000000000..51be003c07
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-expand.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g>
+ <polygon points="396.795,396.8 320,396.8 320,448 448,448 448,320 396.795,320 "/>
+ <polygon points="396.8,115.205 396.8,192 448,192 448,64 320,64 320,115.205 "/>
+ <polygon points="115.205,115.2 192,115.2 192,64 64,64 64,192 115.205,192 "/>
+ <polygon points="115.2,396.795 115.2,320 64,320 64,448 192,448 192,396.795 "/>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-folder-open.svg b/graphics/asymptote/GUI/res/icons/android-folder-open.svg
new file mode 100644
index 0000000000..fa77fea215
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-folder-open.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<path d="M437.334,144H256.006l-42.668-48H74.666C51.197,96,32,115.198,32,138.667v234.666C32,396.802,51.197,416,74.666,416h362.668
+ C460.803,416,480,396.802,480,373.333V186.667C480,163.198,460.803,144,437.334,144z M448,373.333
+ c0,5.782-4.885,10.667-10.666,10.667H74.666C68.884,384,64,379.115,64,373.333V176h373.334c5.781,0,10.666,4.885,10.666,10.667
+ V373.333z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-hand.svg b/graphics/asymptote/GUI/res/icons/android-hand.svg
new file mode 100644
index 0000000000..5035d875be
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-hand.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<path d="M450.679,273.5c-14.585-14.577-36.054-15.89-50.639-1.312l-41.687,41.664c-10.852,10.836-23.93,10.859-31.564,1.852
+ c-5.057-5.968-3.061-24.374-1.644-36.049l20.907-171.849c1.867-15.353-9.07-30.185-24.43-32.051
+ c-15.358-1.867-29.322,9.939-31.191,25.289L267.37,236.021c-1.205,3.358-3.79,3.938-4.081-0.582L255.44,60
+ c0-15.465-12.542-28-28.014-28c-15.473,0-28.015,12.535-28.015,28l-0.552,176.752c0.146,2.04-1.604,2.624-1.92,0.294L172.016,99.077
+ c-2.75-15.219-17.323-26.203-32.548-23.453c-15.227,2.748-25.339,18.187-22.591,33.403l22.193,161.455
+ c0.023,2.872-0.941,4.513-2.308,0.831l-33.109-88.517c-5.18-14.572-21.196-23.065-35.776-17.889
+ c-14.579,5.177-22.201,22.061-17.023,36.631l58.042,189.625c0.303,1.046,0.624,2.085,0.953,3.118l0.121,0.39
+ c0.011,0.031,0.025,0.058,0.035,0.088C126.079,444.233,172.57,480,227.427,480c35.116,0,71.591-12.378,99.357-33.672
+ c0.001,0,0.003-0.002,0.003-0.002c29.99-18.051,126.071-121.347,126.071-121.347C467.445,310.402,465.266,288.08,450.679,273.5z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-locate.svg b/graphics/asymptote/GUI/res/icons/android-locate.svg
new file mode 100644
index 0000000000..e2dd098cbd
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-locate.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon">
+ <g>
+ <path d="M256,176c-44.004,0-80.001,36-80.001,80c0,44.004,35.997,80,80.001,80c44.005,0,79.999-35.996,79.999-80
+ C335.999,212,300.005,176,256,176z M446.938,234.667c-9.605-88.531-81.074-160-169.605-169.599V32h-42.666v33.067
+ c-88.531,9.599-160,81.068-169.604,169.599H32v42.667h33.062c9.604,88.531,81.072,160,169.604,169.604V480h42.666v-33.062
+ c88.531-9.604,160-81.073,169.605-169.604H480v-42.667H446.938z M256,405.333c-82.137,0-149.334-67.198-149.334-149.333
+ c0-82.136,67.197-149.333,149.334-149.333c82.135,0,149.332,67.198,149.332,149.333C405.332,338.135,338.135,405.333,256,405.333z
+ "/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-radio-button-off.svg b/graphics/asymptote/GUI/res/icons/android-radio-button-off.svg
new file mode 100644
index 0000000000..d36fa657c0
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-radio-button-off.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon_20_">
+ <g>
+ <path d="M256,48C141.601,48,48,141.601,48,256s93.601,208,208,208s208-93.601,208-208S370.399,48,256,48z M256,422.399
+ c-91.518,0-166.399-74.882-166.399-166.399S164.482,89.6,256,89.6S422.4,164.482,422.4,256S347.518,422.399,256,422.399z"/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-radio-button-on.svg b/graphics/asymptote/GUI/res/icons/android-radio-button-on.svg
new file mode 100644
index 0000000000..1f7f54c0f2
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-radio-button-on.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon_21_">
+ <g>
+ <path d="M256,152c-57.2,0-104,46.8-104,104s46.8,104,104,104s104-46.8,104-104S313.2,152,256,152z M256,48
+ C141.601,48,48,141.601,48,256s93.601,208,208,208s208-93.601,208-208S370.399,48,256,48z M256,422.4
+ c-91.518,0-166.4-74.883-166.4-166.4S164.482,89.6,256,89.6S422.4,164.482,422.4,256S347.518,422.4,256,422.4z"/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/android-refresh.svg b/graphics/asymptote/GUI/res/icons/android-refresh.svg
new file mode 100644
index 0000000000..066f7d22c6
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/android-refresh.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g>
+ <path d="M256,388c-72.597,0-132-59.405-132-132c0-72.601,59.403-132,132-132c36.3,0,69.299,15.4,92.406,39.601L278,234h154V80
+ l-51.698,51.702C348.406,99.798,304.406,80,256,80c-96.797,0-176,79.203-176,176s78.094,176,176,176
+ c81.045,0,148.287-54.134,169.401-128H378.85C360.105,353.561,311.712,388,256,388z"/>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/arrow-move.svg b/graphics/asymptote/GUI/res/icons/arrow-move.svg
new file mode 100644
index 0000000000..1d4263f45a
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/arrow-move.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<polygon points="480,256 384,160 384,236 276,236 276,128 352,128 256,32 160,128 236,128 236,236 128,236 128,160 32,256 128,352
+ 128,276 236,276 236,384 160,384 256,480 352,384 275.8,384 275.4,275.5 384,275.8 384,352 "/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/arrow-resize.svg b/graphics/asymptote/GUI/res/icons/arrow-resize.svg
new file mode 100644
index 0000000000..a9c3b3cc14
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/arrow-resize.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<polygon points="288,96 337.9,145.9 274,209.7 274,209.7 145.9,337.9 96,288 96,416 224,416 174.1,366.1 357.4,182.9 366.1,174.1
+ 416,224 416,96 "/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/bucket.asy b/graphics/asymptote/GUI/res/icons/bucket.asy
new file mode 100644
index 0000000000..e6468b3f06
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/bucket.asy
@@ -0,0 +1,28 @@
+// Empty bucket: asy bucket -f svg
+// Filled bucket: asy bucket -f svg -u fill=true -o filledbucket
+
+real pixel=1inch/96;
+size(32*pixel);
+defaultpen(1.75bp);
+
+real h=4;
+real r=3;
+path left=(-r,h)--(-r,0);
+path right=(r,0)--(r,h);
+path bottom=xscale(r)*arc(0,1,180,360);
+
+real H=0.9h;
+path Left=(-r,H/2)--(-r,0);
+path Right=(r,0)--(r,H/2);
+
+bool fill=false; // Set to true for filled bucket.
+usersetting();
+
+if(fill)
+ fill(Left--bottom--Right--shift(0,H)*xscale(r)*arc(0,1,0,180)--cycle,gray);
+
+
+draw(shift(0,h)*xscale(r)*unitcircle);
+draw(left--bottom--right);
+draw(shift(0,h)*scale(r)*arc(0,1,0,180));
+
diff --git a/graphics/asymptote/GUI/res/icons/bucket.svg b/graphics/asymptote/GUI/res/icons/bucket.svg
new file mode 100644
index 0000000000..8898aba609
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/bucket.svg
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='24pt' version='1.1' viewBox='56.4094 53.8583 18.4375 24' width='18.4375pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 65.6282 74.202)'>
+<path d='M 8.37504 -11.1667C 8.37504 -12.7085 4.62541 -13.9584 0 -13.9584C -4.62541 -13.9584 -8.37504 -12.7085 -8.37504 -11.1667C -8.37504 -9.62492 -4.62541 -8.37504 0 -8.37504C 4.62541 -8.37504 8.37504 -9.62492 8.37504 -11.1667Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.6282 74.202)'>
+<path d='M -8.37504 -11.1667L -8.37504 -0L -8.37504 -1.85963e-15C -8.37504 -1.23975e-15 -8.37504 -6.19877e-16 -8.37504 -0C -8.37504 1.5418 -4.62541 2.79168 0 2.79168C 4.62541 2.79168 8.37504 1.5418 8.37504 0L 8.37504 0L 8.37504 -11.1667' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.6282 74.202)'>
+<path d='M 8.37504 -11.1667C 8.37504 -15.7921 4.62541 -19.5418 0 -19.5418C -4.62541 -19.5418 -8.37504 -15.7921 -8.37504 -11.1667' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/center.asy b/graphics/asymptote/GUI/res/icons/center.asy
new file mode 100644
index 0000000000..8db11ef08a
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/center.asy
@@ -0,0 +1,9 @@
+// Empty bucket: asy bucket -f svg
+// Filled bucket: asy bucket -f svg -u fill=true -o filledbucket
+
+real pixel=1inch/96;
+size(25*pixel);
+defaultpen(1.5bp);
+
+draw(scale(2)*shift(-0.5,-0.5)*unitsquare);
+fill(scale(0.5)*unitcircle);
diff --git a/graphics/asymptote/GUI/res/icons/center.svg b/graphics/asymptote/GUI/res/icons/center.svg
new file mode 100644
index 0000000000..15b77f5a64
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/center.svg
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='18.75pt' version='1.1' viewBox='56.4094 53.8583 18.75 18.75' width='18.75pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 65.7844 63.2333)'>
+<path d='M -8.65734 8.65734L 8.65734 8.65734L 8.65734 -8.65734L -8.65734 -8.65734L -8.65734 8.65734Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.50562'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.7844 63.2333)'>
+<path d='M 4.32867 0C 4.32867 -2.39066 2.39066 -4.32867 0 -4.32867C -2.39066 -4.32867 -4.32867 -2.39066 -4.32867 -0C -4.32867 2.39066 -2.39066 4.32867 0 4.32867C 2.39066 4.32867 4.32867 2.39066 4.32867 0Z' fill='#000000'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/centerorigin.asy b/graphics/asymptote/GUI/res/icons/centerorigin.asy
new file mode 100644
index 0000000000..b1df599d38
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/centerorigin.asy
@@ -0,0 +1,7 @@
+real pixel=1inch/96;
+size(25*pixel);
+defaultpen(1.5bp);
+
+draw(scale(2)*shift(-0.5,-0.5)*unitsquare);
+draw((-1,0)--(1,0));
+draw((0,-1)--(0,1));
diff --git a/graphics/asymptote/GUI/res/icons/centerorigin.svg b/graphics/asymptote/GUI/res/icons/centerorigin.svg
new file mode 100644
index 0000000000..253ba7789f
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/centerorigin.svg
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='18.75pt' version='1.1' viewBox='56.4094 53.8583 18.75 18.75' width='18.75pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 65.7844 63.2333)'>
+<path d='M -8.65734 8.65734L 8.65734 8.65734L 8.65734 -8.65734L -8.65734 -8.65734L -8.65734 8.65734Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.50562'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.7844 63.2333)'>
+<path d='M -8.65734 -0L 8.65734 0' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.50562'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.7844 63.2333)'>
+<path d='M 0 8.65734L 0 -8.65734' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.50562'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/check.svg b/graphics/asymptote/GUI/res/icons/check.svg
new file mode 100644
index 0000000000..08ee56d87d
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/check.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Check" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
+<path d="M8.294,16.998c-0.435,0-0.847-0.203-1.111-0.553L3.61,11.724c-0.465-0.613-0.344-1.486,0.27-1.951
+ c0.615-0.467,1.488-0.344,1.953,0.27l2.351,3.104l5.911-9.492c0.407-0.652,1.267-0.852,1.921-0.445
+ c0.653,0.406,0.854,1.266,0.446,1.92L9.478,16.34c-0.242,0.391-0.661,0.635-1.12,0.656C8.336,16.998,8.316,16.998,8.294,16.998z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/chevron-with-circle-left.svg b/graphics/asymptote/GUI/res/icons/chevron-with-circle-left.svg
new file mode 100644
index 0000000000..57d5c5b257
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/chevron-with-circle-left.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Chevron_circled_left" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+ x="0px" y="0px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
+<path d="M11.302,6.776c-0.196-0.197-0.515-0.197-0.71,0L7.785,9.641c-0.196,0.199-0.196,0.52,0,0.717l2.807,2.864
+ c0.195,0.199,0.514,0.198,0.71,0c0.196-0.197,0.196-0.518,0-0.717L9,10l2.302-2.506C11.498,7.296,11.498,6.976,11.302,6.776z
+ M10,0.4c-5.302,0-9.6,4.298-9.6,9.6c0,5.303,4.298,9.6,9.6,9.6s9.6-4.297,9.6-9.6C19.6,4.698,15.302,0.4,10,0.4z M10,18.354
+ c-4.615,0-8.354-3.74-8.354-8.354c0-4.614,3.739-8.354,8.354-8.354c4.613,0,8.354,3.74,8.354,8.354
+ C18.354,14.614,14.613,18.354,10,18.354z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/chevron-with-circle-right.svg b/graphics/asymptote/GUI/res/icons/chevron-with-circle-right.svg
new file mode 100644
index 0000000000..a48f0376a0
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/chevron-with-circle-right.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Chevron_circled_right" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+ x="0px" y="0px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
+<path d="M11,10L8.698,7.494c-0.196-0.198-0.196-0.519,0-0.718c0.196-0.197,0.515-0.197,0.71,0l2.807,2.864
+ c0.196,0.199,0.196,0.52,0,0.717l-2.807,2.864c-0.195,0.199-0.514,0.198-0.71,0c-0.196-0.197-0.196-0.518,0-0.717L11,10z M10,0.4
+ c5.302,0,9.6,4.298,9.6,9.6c0,5.303-4.298,9.6-9.6,9.6S0.4,15.303,0.4,10C0.4,4.698,4.698,0.4,10,0.4z M10,18.354
+ c4.613,0,8.354-3.74,8.354-8.354c0-4.614-3.741-8.354-8.354-8.354c-4.615,0-8.354,3.74-8.354,8.354
+ C1.645,14.614,5.385,18.354,10,18.354z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/circle.svg b/graphics/asymptote/GUI/res/icons/circle.svg
new file mode 100644
index 0000000000..b841c238db
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/circle.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Circle" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
+<path d="M10,0.4C4.698,0.4,0.4,4.698,0.4,10C0.4,15.302,4.698,19.6,10,19.6c5.301,0,9.6-4.298,9.6-9.601
+ C19.6,4.698,15.301,0.4,10,0.4z M10,17.599c-4.197,0-7.6-3.402-7.6-7.6S5.802,2.4,10,2.4c4.197,0,7.601,3.402,7.601,7.6
+ S14.197,17.599,10,17.599z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/close-round.svg b/graphics/asymptote/GUI/res/icons/close-round.svg
new file mode 100644
index 0000000000..d8b5554c5c
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/close-round.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<path d="M437.5,386.6L306.9,256l130.6-130.6c14.1-14.1,14.1-36.8,0-50.9c-14.1-14.1-36.8-14.1-50.9,0L256,205.1L125.4,74.5
+ c-14.1-14.1-36.8-14.1-50.9,0c-14.1,14.1-14.1,36.8,0,50.9L205.1,256L74.5,386.6c-14.1,14.1-14.1,36.8,0,50.9
+ c14.1,14.1,36.8,14.1,50.9,0L256,306.9l130.6,130.6c14.1,14.1,36.8,14.1,50.9,0C451.5,423.4,451.5,400.6,437.5,386.6z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/closedcurve.asy b/graphics/asymptote/GUI/res/icons/closedcurve.asy
new file mode 100644
index 0000000000..6406807998
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/closedcurve.asy
@@ -0,0 +1,7 @@
+real pixel=1inch/96;
+size(32*pixel,IgnoreAspect);
+defaultpen(1.75bp);
+
+path p=W..NW..ENE..0.5*SE..cycle;
+draw(p);
+dot(p,linewidth(8pixel));
diff --git a/graphics/asymptote/GUI/res/icons/closedcurve.svg b/graphics/asymptote/GUI/res/icons/closedcurve.svg
new file mode 100644
index 0000000000..946ef84df7
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/closedcurve.svg
@@ -0,0 +1,20 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='24pt' version='1.1' viewBox='56.4094 53.8583 24 24' width='24pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.7688)'>
+<path d='M -9.39118 -0C -9.96861 -3.83004 -8.55706 -7.51944 -6.64057 -10.2171C -0.491089 -18.8733 8.35676 -15.1906 8.67632 -5.52948C 8.836 -0.702008 6.23968 2.94207 3.32028 5.10857C -1.96891 9.03371 -8.26895 7.4437 -9.39118 -0Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.7688)'>
+<circle cx='-9.39118' cy='-0' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.7688)'>
+<circle cx='-6.64057' cy='-10.2171' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.7688)'>
+<circle cx='8.67632' cy='-5.52948' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.7688)'>
+<circle cx='3.32028' cy='5.10857' r='3.01125' fill='#000000'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/closedpolygon.asy b/graphics/asymptote/GUI/res/icons/closedpolygon.asy
new file mode 100644
index 0000000000..9e4719a36b
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/closedpolygon.asy
@@ -0,0 +1,7 @@
+real pixel=1inch/96;
+size(32*pixel,IgnoreAspect);
+defaultpen(1.75bp);
+
+path p=W--NW--ENE--0.5*SE--cycle;
+draw(p);
+dot(p,linewidth(8pixel));
diff --git a/graphics/asymptote/GUI/res/icons/closedpolygon.svg b/graphics/asymptote/GUI/res/icons/closedpolygon.svg
new file mode 100644
index 0000000000..432195d706
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/closedpolygon.svg
@@ -0,0 +1,20 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='24pt' version='1.1' viewBox='56.4094 53.8583 24 24' width='24pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<path d='M -9.39118 -0L -6.64057 -12.045L 8.67632 -6.51871L 3.32028 6.0225L -9.39118 -0Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='-9.39118' cy='-0' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='-6.64057' cy='-12.045' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='8.67632' cy='-6.51871' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='3.32028' cy='6.0225' r='3.01125' fill='#000000'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/code.svg b/graphics/asymptote/GUI/res/icons/code.svg
new file mode 100644
index 0000000000..33a99fd5d7
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/code.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Code" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
+<path d="M5.719,14.75c-0.236,0-0.474-0.083-0.664-0.252L-0.005,10l5.341-4.748C5.748,4.887,6.38,4.922,6.747,5.335
+ c0.367,0.413,0.33,1.045-0.083,1.412L3.005,10l3.378,3.002c0.413,0.367,0.45,0.999,0.083,1.412
+ C6.269,14.637,5.994,14.75,5.719,14.75z M14.664,14.748L20.005,10l-5.06-4.498c-0.413-0.367-1.045-0.33-1.411,0.083
+ c-0.367,0.413-0.33,1.045,0.083,1.412L16.995,10l-3.659,3.252c-0.413,0.367-0.45,0.999-0.083,1.412C13.45,14.887,13.725,15,14,15
+ C14.236,15,14.474,14.917,14.664,14.748z M9.986,16.165l2-12c0.091-0.545-0.277-1.06-0.822-1.151
+ c-0.547-0.092-1.061,0.277-1.15,0.822l-2,12c-0.091,0.545,0.277,1.06,0.822,1.151C8.892,16.996,8.946,17,9.001,17
+ C9.481,17,9.905,16.653,9.986,16.165z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/edit.svg b/graphics/asymptote/GUI/res/icons/edit.svg
new file mode 100644
index 0000000000..a0be3454e1
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/edit.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g>
+
+ <rect x="178.846" y="92.087" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 224.3476 631.1498)" width="128.085" height="354.049"/>
+ <path d="M471.723,88.393l-48.115-48.114c-11.723-11.724-31.558-10.896-44.304,1.85l-45.202,45.203l90.569,90.568l45.202-45.202
+ C482.616,119.952,483.445,100.116,471.723,88.393z"/>
+ <polygon points="64.021,363.252 32,480 148.737,447.979 "/>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/eye.svg b/graphics/asymptote/GUI/res/icons/eye.svg
new file mode 100644
index 0000000000..6b64633fce
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/eye.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<g>
+ <path d="M256,128c-81.9,0-145.7,48.8-224,128c67.4,67.7,124,128,224,128c99.9,0,173.4-76.4,224-126.6
+ C428.2,198.6,354.8,128,256,128z M256,347.3c-49.4,0-89.6-41-89.6-91.3c0-50.4,40.2-91.3,89.6-91.3s89.6,41,89.6,91.3
+ C345.6,306.4,305.4,347.3,256,347.3z"/>
+ <g>
+ <path d="M256,224c0-7.9,2.9-15.1,7.6-20.7c-2.5-0.4-5-0.6-7.6-0.6c-28.8,0-52.3,23.9-52.3,53.3c0,29.4,23.5,53.3,52.3,53.3
+ s52.3-23.9,52.3-53.3c0-2.3-0.2-4.6-0.4-6.9c-5.5,4.3-12.3,6.9-19.8,6.9C270.3,256,256,241.7,256,224z"/>
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/filledbucket.svg b/graphics/asymptote/GUI/res/icons/filledbucket.svg
new file mode 100644
index 0000000000..e768fa3d1c
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/filledbucket.svg
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='24pt' version='1.1' viewBox='56.4094 53.8583 18.4375 24' width='18.4375pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 65.6282 74.202)'>
+<path d='M -8.37504 -5.02502L -8.37504 -0L -8.37504 -1.85963e-15C -8.37504 -1.23975e-15 -8.37504 -6.19877e-16 -8.37504 -0C -8.37504 1.5418 -4.62541 2.79168 0 2.79168C 4.62541 2.79168 8.37504 1.5418 8.37504 0L 8.37504 0L 8.37504 -5.02502L 8.37504 -10.05C 8.37504 -11.5918 4.62541 -12.8417 0 -12.8417C -4.62541 -12.8417 -8.37504 -11.5918 -8.37504 -10.05L -8.37504 -5.02502Z' fill='#808080'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.6282 74.202)'>
+<path d='M 8.37504 -11.1667C 8.37504 -12.7085 4.62541 -13.9584 0 -13.9584C -4.62541 -13.9584 -8.37504 -12.7085 -8.37504 -11.1667C -8.37504 -9.62492 -4.62541 -8.37504 0 -8.37504C 4.62541 -8.37504 8.37504 -9.62492 8.37504 -11.1667Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.6282 74.202)'>
+<path d='M -8.37504 -11.1667L -8.37504 -0L -8.37504 -1.85963e-15C -8.37504 -1.23975e-15 -8.37504 -6.19877e-16 -8.37504 -0C -8.37504 1.5418 -4.62541 2.79168 0 2.79168C 4.62541 2.79168 8.37504 1.5418 8.37504 0L 8.37504 0L 8.37504 -11.1667' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 65.6282 74.202)'>
+<path d='M 8.37504 -11.1667C 8.37504 -15.7921 4.62541 -19.5418 0 -19.5418C -4.62541 -19.5418 -8.37504 -15.7921 -8.37504 -11.1667' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/grid.svg b/graphics/asymptote/GUI/res/icons/grid.svg
new file mode 100644
index 0000000000..456e501131
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/grid.svg
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<g>
+ <g>
+ <path d="M160,153.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V153.3z"
+ />
+ <path d="M288,153.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V153.3z"
+ />
+ <path d="M416,153.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V153.3z"
+ />
+ </g>
+ <g>
+ <path d="M160,281.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V281.3z"
+ />
+ <path d="M288,281.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V281.3z"
+ />
+ <path d="M416,281.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V281.3z"
+ />
+ </g>
+ <g>
+ <path d="M160,409.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V409.3z"
+ />
+ <path d="M288,409.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V409.3z"
+ />
+ <path d="M416,409.3c0,3.7-3,6.7-6.7,6.7h-50.5c-3.7,0-6.7-3-6.7-6.7v-50.5c0-3.7,3-6.7,6.7-6.7h50.5c3.7,0,6.7,3,6.7,6.7V409.3z"
+ />
+ </g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/magnifying-glass.svg b/graphics/asymptote/GUI/res/icons/magnifying-glass.svg
new file mode 100644
index 0000000000..f82283d618
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/magnifying-glass.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Magnifying_glass" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
+<path d="M17.545,15.467l-3.779-3.779c0.57-0.935,0.898-2.035,0.898-3.21c0-3.417-2.961-6.377-6.378-6.377
+ C4.869,2.1,2.1,4.87,2.1,8.287c0,3.416,2.961,6.377,6.377,6.377c1.137,0,2.2-0.309,3.115-0.844l3.799,3.801
+ c0.372,0.371,0.975,0.371,1.346,0l0.943-0.943C18.051,16.307,17.916,15.838,17.545,15.467z M4.004,8.287
+ c0-2.366,1.917-4.283,4.282-4.283c2.366,0,4.474,2.107,4.474,4.474c0,2.365-1.918,4.283-4.283,4.283
+ C6.111,12.76,4.004,10.652,4.004,8.287z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/opencurve.asy b/graphics/asymptote/GUI/res/icons/opencurve.asy
new file mode 100644
index 0000000000..885128358a
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/opencurve.asy
@@ -0,0 +1,7 @@
+real pixel=1inch/96;
+size(32*pixel,IgnoreAspect);
+defaultpen(1.75bp);
+
+path p=W..NW..ENE..0.5*SE;
+draw(p);
+dot(p,linewidth(8pixel));
diff --git a/graphics/asymptote/GUI/res/icons/opencurve.svg b/graphics/asymptote/GUI/res/icons/opencurve.svg
new file mode 100644
index 0000000000..5086ab071b
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/opencurve.svg
@@ -0,0 +1,20 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='24pt' version='1.1' viewBox='56.4094 53.8583 24 24' width='24pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.8123)'>
+<path d='M -9.39118 -0C -9.32257 -3.77783 -8.34324 -7.38444 -6.64057 -10.1298C -1.26219 -18.8017 7.68971 -15.5351 8.67632 -5.4822C 9.18679 -0.280877 6.74937 4.51887 3.32028 5.06489' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.8123)'>
+<circle cx='-9.39118' cy='-0' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.8123)'>
+<circle cx='-6.64057' cy='-10.1298' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.8123)'>
+<circle cx='8.67632' cy='-5.4822' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 69.8123)'>
+<circle cx='3.32028' cy='5.06489' r='3.01125' fill='#000000'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/openpolygon.asy b/graphics/asymptote/GUI/res/icons/openpolygon.asy
new file mode 100644
index 0000000000..19f4d5cb03
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/openpolygon.asy
@@ -0,0 +1,7 @@
+real pixel=1inch/96;
+size(32*pixel,IgnoreAspect);
+defaultpen(1.75bp);
+
+path p=W--NW--ENE--0.5*SE;
+draw(p);
+dot(p,linewidth(8pixel));
diff --git a/graphics/asymptote/GUI/res/icons/openpolygon.svg b/graphics/asymptote/GUI/res/icons/openpolygon.svg
new file mode 100644
index 0000000000..a07a63abd7
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/openpolygon.svg
@@ -0,0 +1,20 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- This file was generated by dvisvgm 2.4 -->
+<svg height='24pt' version='1.1' viewBox='56.4094 53.8583 24 24' width='24pt' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
+<g id='page1'>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<path d='M -9.39118 -0L -6.64057 -12.045L 8.67632 -6.51871L 3.32028 6.0225' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='1.75656'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='-9.39118' cy='-0' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='-6.64057' cy='-12.045' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='8.67632' cy='-6.51871' r='3.01125' fill='#000000'/>
+</g>
+<g transform='matrix(0.996264 0 0 0.996264 68.7655 68.8583)'>
+<circle cx='3.32028' cy='6.0225' r='3.01125' fill='#000000'/>
+</g></g>
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/plus-round.svg b/graphics/asymptote/GUI/res/icons/plus-round.svg
new file mode 100644
index 0000000000..465d937802
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/plus-round.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
+<path d="M417.4,224H288V94.6c0-16.9-14.3-30.6-32-30.6c-17.7,0-32,13.7-32,30.6V224H94.6C77.7,224,64,238.3,64,256
+ c0,17.7,13.7,32,30.6,32H224v129.4c0,16.9,14.3,30.6,32,30.6c17.7,0,32-13.7,32-30.6V288h129.4c16.9,0,30.6-14.3,30.6-32
+ C448,238.3,434.3,224,417.4,224z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/save.svg b/graphics/asymptote/GUI/res/icons/save.svg
new file mode 100644
index 0000000000..2d2823d391
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/save.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Save" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
+<path d="M15.173,2H4C2.899,2,2,2.9,2,4v12c0,1.1,0.899,2,2,2h12c1.101,0,2-0.9,2-2V5.127L15.173,2z M14,8c0,0.549-0.45,1-1,1H7
+ C6.45,9,6,8.549,6,8V3h8V8z M13,4h-2v4h2V4z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/social-python.svg b/graphics/asymptote/GUI/res/icons/social-python.svg
new file mode 100644
index 0000000000..35fcdde7c1
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/social-python.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g>
+ <path d="M193.46,249.056c3.723-0.67,7.589-1.041,11.586-1.041L201.924,248h103.823c4.503,0,8.806-0.617,12.908-1.754
+ c19.37-5.363,33.345-22.537,33.345-43.663v-30.822v-56.402c0-24.832-21.15-43.484-46.289-47.606
+ c-15.931-2.624-39.258-3.827-55.089-3.749c-15.829,0.086-30.981,1.404-44.277,3.749C167.143,74.576,160,88.928,160,115.359V144h96
+ v16H128.82c-35.628,0-64.538,42.571-64.813,95.242C64.005,255.495,64,255.747,64,256c0,9.523,0.94,18.72,2.685,27.404
+ C74.648,323.07,99.451,352,128.82,352H144v-2.662v-43.273C144,279.238,164.146,254.332,193.46,249.056z M203.656,127.002
+ c-9.592,0-17.384-7.785-17.384-17.403c0-9.664,7.774-17.52,17.384-17.52c9.574,0,17.399,7.855,17.399,17.52
+ C221.056,119.217,213.246,127.002,203.656,127.002z"/>
+ <path d="M443.951,222.543C434.78,186.021,411.033,160,383.18,160H368v2.626v38.046c0,33.915-22.286,58.474-49.489,62.681
+ c-2.737,0.424-5.483,0.646-8.301,0.646H206.351c-4.518,0-8.904,0.584-13.049,1.672C174.18,270.689,160,286.6,160,307.236v32.922
+ v54.305c0,24.832,24.977,39.426,49.481,46.551c29.327,8.531,61.267,10.068,96.366,0C329.15,434.354,352,420.893,352,394.463V368
+ h-96v-16h127.18c25.24,0,47.107-21.365,57.814-52.549C445.474,286.404,448,271.641,448,256
+ C448,244.232,446.567,232.962,443.951,222.543z M307.867,382.82c9.59,0,17.381,7.785,17.381,17.4
+ c0,9.65-7.791,17.521-17.381,17.521c-9.577,0-17.399-7.871-17.399-17.521C290.468,390.59,298.274,382.82,307.867,382.82z"/>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/subdirectory-left.svg b/graphics/asymptote/GUI/res/icons/subdirectory-left.svg
new file mode 100644
index 0000000000..bbbf333652
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/subdirectory-left.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M18 12v1H8v5l-6-6 6-6v5h8V2h2z"/></svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/text.svg b/graphics/asymptote/GUI/res/icons/text.svg
new file mode 100644
index 0000000000..7a4ffb4c0d
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/text.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
+ <path d="M0 0v2h.5c0-.55.45-1 1-1h1.5v5.5c0 .28-.22.5-.5.5h-.5v1h4v-1h-.5c-.28 0-.5-.22-.5-.5v-5.5h1.5c.55 0 1 .45 1 1h.5v-2h-8z" />
+</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/triangle-stroked-15.svg b/graphics/asymptote/GUI/res/icons/triangle-stroked-15.svg
new file mode 100644
index 0000000000..c87ff1d223
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/triangle-stroked-15.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1"
+ id="svg4619" inkscape:version="0.91+devel+osxmenu r12911" sodipodi:docname="triangle-stroked-15.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="15px" height="15px"
+ viewBox="0 0 15 15" style="enable-background:new 0 0 15 15;" xml:space="preserve">
+<path id="rect3338" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccc" d="M7.5243,1.5004
+ C7.2429,1.4913,6.9787,1.6423,6.8336,1.8952l-5.5,9.8692C1.0218,12.3078,1.395,12.9999,2,13h11
+ c0.605-0.0001,0.9782-0.6922,0.6664-1.2355l-5.5-9.8692C8.0302,1.6579,7.7884,1.5092,7.5243,1.5004z M7.5,3.8993l4.1267,7.4704
+ H3.3733L7.5,3.8993z"/>
+</svg>
diff --git a/graphics/asymptote/GUI/setup.py b/graphics/asymptote/GUI/setup.py
new file mode 100644
index 0000000000..d6a4c0d6a7
--- /dev/null
+++ b/graphics/asymptote/GUI/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+import xasyVersion
+from setuptools import setup
+
+setup(
+ name="xasy",
+ version=xasyVersion.xasyVersion,
+ author="Supakorn Rassameemasmuang, Orest Shardt, and John C. Bowman",
+ description="User interface for Asymptote, a vector graphics language",
+ url="http://asymptote.sourceforge.net",
+ download_url="https://sourceforge.net/projects/asymptote/"
+)
diff --git a/graphics/asymptote/GUI/windows/custMatTransform.ui b/graphics/asymptote/GUI/windows/custMatTransform.ui
new file mode 100644
index 0000000000..4612f277c9
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/custMatTransform.ui
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>500</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>320</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>500</width>
+ <height>320</height>
+ </size>
+ </property>
+ <property name="mouseTracking">
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle">
+ <string>Set Custom Transformation</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/android-expand.svg</normaloff>:/icons/android-expand.svg</iconset>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="modal">
+ <bool>false</bool>
+ </property>
+ <widget class="QFrame" name="centralFrame">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>461</width>
+ <height>271</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Transformation Matrix</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="gridFrame">
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLineEdit" name="lineMat00">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="lineMat11">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLineEdit" name="lineMat10">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="lineMat01">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Translation</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="gridFrame_2">
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="lineMatTy">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="lineMatTx">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Preview:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="imgPreview">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>150</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>300</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Shows a red square if transformation determinant is negative.</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblAnchor">
+ <property name="text">
+ <string>Anchor: Top Left</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblCoordsMode">
+ <property name="text">
+ <string>Coordinates: Global</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnReset">
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnAccept">
+ <property name="text">
+ <string>Accept</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources>
+ <include location="../res/icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/graphics/asymptote/GUI/windows/labelTextEditor.ui b/graphics/asymptote/GUI/windows/labelTextEditor.ui
new file mode 100644
index 0000000000..06cd31bd1a
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/labelTextEditor.ui
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>473</width>
+ <height>424</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="chkMathMode">
+ <property name="text">
+ <string>Math Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="cmbMathStyle">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>Inline Style</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Display Style</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Script Style</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPlainTextEdit" name="txtLabelEdit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Preview</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblLabelPreview">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnGetText">
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/text.svg</normaloff>:/icons/text.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPreview">
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/eye.svg</normaloff>:/icons/eye.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/android-close.svg</normaloff>:/icons/android-close.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnAccept">
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/android-done.svg</normaloff>:/icons/android-done.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../res/icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/graphics/asymptote/GUI/windows/setCustomAnchor.ui b/graphics/asymptote/GUI/windows/setCustomAnchor.ui
new file mode 100644
index 0000000000..5a4b14676e
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/setCustomAnchor.ui
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>245</width>
+ <height>161</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Set Custom Anchor</string>
+ </property>
+ <widget class="QWidget" name="verticalLayoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>201</width>
+ <height>121</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>X:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="lineEditX">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Y:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="lineEditY">
+ <property name="text">
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/graphics/asymptote/GUI/windows/widg_addLabel.ui b/graphics/asymptote/GUI/windows/widg_addLabel.ui
new file mode 100644
index 0000000000..40bc4ddc60
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/widg_addLabel.ui
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>599</width>
+ <height>35</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLineEdit" name="txtLabelText">
+ <property name="toolTip">
+ <string>Number of Sides</string>
+ </property>
+ <property name="placeholderText">
+ <string>Text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnAdvancedEdit">
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/edit.svg</normaloff>:/icons/edit.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Align</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cmbAlign">
+ <item>
+ <property name="text">
+ <string>Center</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>N</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>E</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>W</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>S</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NW</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NE</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SW</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SE</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Custom</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Font Size</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cmbFontSize">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <item>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>8</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>9</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>10</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>11</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>12</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>18</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>24</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>48</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>72</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Custom Align</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtShiftX">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="placeholderText">
+ <string>Shift X</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtShiftY">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="placeholderText">
+ <string>Shift Y</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../res/icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/graphics/asymptote/GUI/windows/widg_addPolyOpt.ui b/graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
new file mode 100644
index 0000000000..b8bde4236a
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>326</width>
+ <height>35</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QCheckBox" name="chkInscribed">
+ <property name="text">
+ <string>Start at Vertex</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtSides">
+ <property name="toolTip">
+ <string>Number of Sides</string>
+ </property>
+ <property name="placeholderText">
+ <string>Sides</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/graphics/asymptote/GUI/windows/widg_editBezier.ui b/graphics/asymptote/GUI/windows/widg_editBezier.ui
new file mode 100644
index 0000000000..cca3aaaa2d
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/widg_editBezier.ui
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>692</width>
+ <height>35</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>35</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QComboBox" name="cmbLockMode">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>No Lock</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Lock Angle</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Lock Angle &amp; Scale</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="chkRecompute">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Recompute Path</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnForceRecompute">
+ <property name="text">
+ <string>Recompute Once</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnOk">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/check.svg</normaloff>:/icons/check.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/close-round.svg</normaloff>:/icons/close-round.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../res/icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/graphics/asymptote/GUI/windows/widgetPointEditor.ui b/graphics/asymptote/GUI/windows/widgetPointEditor.ui
new file mode 100644
index 0000000000..c3e486ad5a
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/widgetPointEditor.ui
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>324</width>
+ <height>67</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="nameLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Left Control Point</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLineEdit" name="lineXorA">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>X</string>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="placeholderText">
+ <string>X</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineYorM">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>X</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="placeholderText">
+ <string>Y</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnRelative">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/android-locate.svg</normaloff>:/icons/android-locate.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPolar">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/android-radio-button-off.svg</normaloff>:/icons/android-radio-button-off.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnManualAdj">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/edit.svg</normaloff>:/icons/edit.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../res/icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/graphics/asymptote/GUI/windows/window1.ui b/graphics/asymptote/GUI/windows/window1.ui
new file mode 100644
index 0000000000..bbe474bab1
--- /dev/null
+++ b/graphics/asymptote/GUI/windows/window1.ui
@@ -0,0 +1,2000 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1030</width>
+ <height>768</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>xasy</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="mouseTracking">
+ <bool>true</bool>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QWidget" name="mainWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="mouseTracking">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="menuFrame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnUndo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Undo</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-arrow-back.svg</normaloff>:/icons/android-arrow-back.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnRedo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Redo</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-arrow-forward.svg</normaloff>:/icons/android-arrow-forward.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnLoadFile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Open file&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-folder-open.svg</normaloff>:/icons/android-folder-open.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSave">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Save file&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/save.svg</normaloff>:/icons/save.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnViewCode">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Edit code&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/code.svg</normaloff>:/icons/code.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnQuickScreenshot">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Screenshot&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-camera.svg</normaloff>:/icons/android-camera.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDrawAxes">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>Roboto</family>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Toggle display axes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/plus-round.svg</normaloff>:/icons/plus-round.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDrawGrid">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>Roboto</family>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Toggle grid&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/grid.svg</normaloff>:/icons/grid.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSetZoom">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Synchronize with Asymptote</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/magnifying-glass.svg</normaloff>:/icons/magnifying-glass.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPanCenter">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Center&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/center.svg</normaloff>:/icons/center.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnResetPan">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Center about origin&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/centerorigin.svg</normaloff>:/icons/centerorigin.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnAlignX">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>Roboto</family>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lock transform to X axis&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>X</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnAlignY">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lock transform to Y axis&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Y</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSelectEdit">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Bézier editor&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/edit.svg</normaloff>:/icons/edit.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDeleteMode">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Delete&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-delete.svg</normaloff>:/icons/android-delete.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPan">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Pan</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-hand.svg</normaloff>:/icons/android-hand.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnTranslate">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Translate</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/arrow-move.svg</normaloff>:/icons/arrow-move.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnScale">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Scale</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/arrow-resize.svg</normaloff>:/icons/arrow-resize.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnRotate">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Rotate</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-refresh.svg</normaloff>:/icons/android-refresh.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnAnchor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set custom anchor&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/anchor.svg</normaloff>:/icons/anchor.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboAnchor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>127</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>127</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Anchor&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ <property name="currentText">
+ <string>Origin</string>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <property name="insertPolicy">
+ <enum>QComboBox::InsertAtCurrent</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToContentsOnFirstShow</enum>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="frame">
+ <bool>false</bool>
+ </property>
+ <property name="modelColumn">
+ <number>0</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Origin</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Center</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Top Left</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Top Right</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Bottom Right</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Bottom Left</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Custom</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnToggleVisible">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/eye.svg</normaloff>:/icons/eye.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCustTransform">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-expand.svg</normaloff>:/icons/android-expand.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSendBackwards">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/chevron-with-circle-left.svg</normaloff>:/icons/chevron-with-circle-left.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSendForwards">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Translate</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/chevron-with-circle-right.svg</normaloff>:/icons/chevron-with-circle-right.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>25</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ <zorder>btnUndo</zorder>
+ <zorder>btnRedo</zorder>
+ <zorder>btnLoadFile</zorder>
+ <zorder>btnSave</zorder>
+ <zorder>btnViewCode</zorder>
+ <zorder>btnQuickScreenshot</zorder>
+ <zorder>btnDrawAxes</zorder>
+ <zorder>btnDrawGrid</zorder>
+ <zorder>btnSetZoom</zorder>
+ <zorder>btnPanCenter</zorder>
+ <zorder>btnResetPan</zorder>
+ <zorder>btnAlignX</zorder>
+ <zorder>btnAlignY</zorder>
+ <zorder>btnPan</zorder>
+ <zorder>btnTranslate</zorder>
+ <zorder>btnScale</zorder>
+ <zorder>btnCustTransform</zorder>
+ <zorder>btnSendBackwards</zorder>
+ <zorder>btnSendForwards</zorder>
+ <zorder>comboAnchor</zorder>
+ <zorder>btnToggleVisible</zorder>
+ <zorder>btnAnchor</zorder>
+ <zorder>btnRotate</zorder>
+ <zorder>btnSelectEdit</zorder>
+ <zorder>btnDeleteMode</zorder>
+ <zorder>horizontalSpacer_4</zorder>
+ <zorder>horizontalSpacer_5</zorder>
+ <zorder>horizontalSpacer_6</zorder>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="addOption">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnFill">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Toggle fill/outline&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/bucket.svg</normaloff>
+ <normalon>:/icons/filledbucket.svg</normalon>:/icons/bucket.svg</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="addOptionLayout"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>35</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Line Width:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtLineWidth">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>75</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Current pen width&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frameCurrColor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>15</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Current pen color&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QFrame{
+padding: 4.0;
+border-radius: 3.0;
+background: rgb(0, 0, 0)
+}</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSelectColor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>25</width>
+ <height>25</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set color&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/android-color-palette.svg</normaloff>:/icons/android-color-palette.svg</iconset>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="formFrame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="horizontalSpacing">
+ <number>0</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="4" column="0">
+ <widget class="QPushButton" name="btnOpenPoly">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Open polygon&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/openpolygon.svg</normaloff>:/icons/openpolygon.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QPushButton" name="btnClosedPoly">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Closed polygon&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/closedpolygon.svg</normaloff>:/icons/closedpolygon.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QPushButton" name="btnOpenCurve">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Open Bézier curve&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/opencurve.svg</normaloff>:/icons/opencurve.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QPushButton" name="btnClosedCurve">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Closed Bézier curve&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/closedcurve.svg</normaloff>:/icons/closedcurve.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QPushButton" name="btnAddPoly">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Regular polygon&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/triangle-stroked-15.svg</normaloff>:/icons/triangle-stroked-15.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QPushButton" name="btnAddCircle">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Circle&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/circle.svg</normaloff>:/icons/circle.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QPushButton" name="btnAddLabel">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Text&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/text.svg</normaloff>:/icons/text.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="imgFrame">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>6</height>
+ </size>
+ </property>
+ <property name="mouseTracking">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QLabel" name="imgLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="mouseTracking">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Panel</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnTogglePython">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/social-python.svg</normaloff>:/icons/social-python.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="txtTerminalPrompt">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnEnterCommand">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/icons/subdirectory-left.svg</normaloff>:/icons/subdirectory-left.svg</iconset>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1030</width>
+ <height>28</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFIle">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="actionOpen"/>
+ <addaction name="actionSave"/>
+ <addaction name="actionSaveAs"/>
+ <addaction name="actionExportAsymptote"/>
+ <addaction name="separator"/>
+ <addaction name="actionQuit"/>
+ </widget>
+ <widget class="QMenu" name="menuEdit">
+ <property name="title">
+ <string>&amp;Edit</string>
+ </property>
+ <addaction name="actionUndo"/>
+ <addaction name="actionRedo"/>
+ <addaction name="separator"/>
+ </widget>
+ <widget class="QMenu" name="menuOptions">
+ <property name="title">
+ <string>Optio&amp;ns</string>
+ </property>
+ <addaction name="actionSettings"/>
+ </widget>
+ <widget class="QMenu" name="menuHelp">
+ <property name="title">
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="actionManual"/>
+ <addaction name="actionAbout"/>
+ </widget>
+ <widget class="QMenu" name="menuTools">
+ <property name="title">
+ <string>&amp;Tools</string>
+ </property>
+ <addaction name="actionEnterCommand"/>
+ </widget>
+ <addaction name="menuFIle"/>
+ <addaction name="menuEdit"/>
+ <addaction name="menuOptions"/>
+ <addaction name="menuTools"/>
+ <addaction name="menuHelp"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar">
+ <property name="sizeGripEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <action name="actionAbout">
+ <property name="text">
+ <string>&amp;About</string>
+ </property>
+ </action>
+ <action name="actionManual">
+ <property name="text">
+ <string>&amp;Manual</string>
+ </property>
+ </action>
+ <action name="actionSettings">
+ <property name="text">
+ <string>&amp;Settings</string>
+ </property>
+ </action>
+ <action name="actionPause">
+ <property name="text">
+ <string>Pause </string>
+ </property>
+ </action>
+ <action name="actionSaveAs">
+ <property name="text">
+ <string>&amp;Save As</string>
+ </property>
+ </action>
+ <action name="actionEnterCommand">
+ <property name="text">
+ <string>&amp;Enter Command</string>
+ </property>
+ </action>
+ <action name="actionQuit">
+ <property name="text">
+ <string>&amp;Quit</string>
+ </property>
+ </action>
+ <action name="actionUndo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Undo</string>
+ </property>
+ </action>
+ <action name="actionRedo">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Redo</string>
+ </property>
+ </action>
+ <action name="actionShow_Grid">
+ <property name="text">
+ <string>&amp;Show Grid</string>
+ </property>
+ </action>
+ <action name="actionShow_Local_Grid">
+ <property name="text">
+ <string>Show &amp;Local Grid</string>
+ </property>
+ </action>
+ <action name="actionTransform">
+ <property name="text">
+ <string>&amp;Transform</string>
+ </property>
+ </action>
+ <action name="actionExportAsymptote">
+ <property name="text">
+ <string>Export</string>
+ </property>
+ </action>
+ <action name="actionSave">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </action>
+ <action name="actionOpen">
+ <property name="text">
+ <string>Open</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="9"/>
+ <resources>
+ <include location="../res/icons.qrc"/>
+ </resources>
+ <connections/>
+ <designerdata>
+ <property name="gridDeltaX">
+ <number>10</number>
+ </property>
+ <property name="gridDeltaY">
+ <number>10</number>
+ </property>
+ <property name="gridSnapX">
+ <bool>true</bool>
+ </property>
+ <property name="gridSnapY">
+ <bool>true</bool>
+ </property>
+ <property name="gridVisible">
+ <bool>true</bool>
+ </property>
+ </designerdata>
+</ui>
diff --git a/graphics/asymptote/GUI/xasy.py b/graphics/asymptote/GUI/xasy.py
new file mode 100755
index 0000000000..7e38f73a2a
--- /dev/null
+++ b/graphics/asymptote/GUI/xasy.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import sys
+import PyQt5.QtWidgets as Qw
+from Window1 import MainWindow1
+
+
+def main(args):
+ qtApp = Qw.QApplication(args)
+ mainWin1 = MainWindow1()
+ mainWin1.show()
+ return qtApp.exec_()
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv) or 0)
diff --git a/graphics/asymptote/GUI/xasy2asy.py b/graphics/asymptote/GUI/xasy2asy.py
new file mode 100755
index 0000000000..2df6c3417a
--- /dev/null
+++ b/graphics/asymptote/GUI/xasy2asy.py
@@ -0,0 +1,1407 @@
+#!/usr/bin/env python3
+
+###########################################################################
+#
+# xasy2asy provides a Python interface to Asymptote
+#
+#
+# Authors: Orest Shardt, Supakorn Rassameemasmuang, and John C. Bowman
+#
+###########################################################################
+
+import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+import PyQt5.QtSvg as Qs
+
+import numpy as np
+
+import sys
+import os
+import signal
+import threading
+import string
+import subprocess
+import tempfile
+import re
+import shutil
+import copy
+import queue
+import io
+import atexit
+import DebugFlags
+
+import xasyUtils as xu
+import xasyArgs as xa
+import xasyOptions as xo
+import xasySvg as xs
+
+class AsymptoteEngine:
+ xasy=chr(4)+"\n"
+
+ def __init__(self, path=None, keepFiles=DebugFlags.keepFiles, keepDefaultArgs=True):
+ if path is None:
+ path = xa.getArgs().asypath
+ if path is None:
+ opt = xo.BasicConfigs.defaultOpt
+ opt.load()
+ path = opt['asyPath']
+
+ if sys.platform[:3] == 'win':
+ rx = 0 # stdin
+ wa = 2 # stderr
+ else:
+ rx, wx = os.pipe()
+ ra, wa = os.pipe()
+ os.set_inheritable(rx, True)
+ os.set_inheritable(wx, True)
+ os.set_inheritable(ra, True)
+ os.set_inheritable(wa, True)
+ self.ostream = os.fdopen(wx, 'w')
+ self.istream = os.fdopen(ra, 'r')
+
+ self.keepFiles = keepFiles
+ if sys.platform[:3] == 'win':
+ self.tmpdir = tempfile.mkdtemp(prefix='xasyData_',dir='./')+'/'
+ else:
+ self.tmpdir = tempfile.mkdtemp(prefix='xasyData_')+os.sep
+
+ self.args=['-xasy', '-noV', '-q', '-inpipe=' + str(rx), '-outpipe=' + str(wa), '-o', self.tmpdir]
+
+ self.asyPath = path
+ self.asyProcess = None
+
+ def start(self):
+ try:
+ if sys.platform[:3] == 'win':
+ self.asyProcess = subprocess.Popen([self.asyPath] + self.args,
+ stdin=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines=True)
+ self.ostream = self.asyProcess.stdin
+ self.istream = self.asyProcess.stderr
+ else:
+ self.asyProcess = subprocess.Popen([self.asyPath] + self.args,close_fds=False)
+ finally:
+ atexit.register(self.cleanup)
+
+ def wait(self):
+ if self.asyProcess.returncode is not None:
+ return
+ else:
+ return self.asyProcess.wait()
+
+ def __enter__(self):
+ self.start()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.stop()
+ self.wait()
+
+ @property
+ def tempDirName(self):
+ return self.tmpdir
+
+ def startThenStop(self):
+ self.start()
+ self.stop()
+ self.wait()
+
+ @property
+ def active(self):
+ if self.asyProcess is None:
+ return False
+ return self.asyProcess.returncode is None
+
+ def stop(self):
+ if self.active:
+ self.asyProcess.kill()
+
+ def cleanup(self):
+ self.stop()
+ if self.asyProcess is not None:
+ self.asyProcess.wait()
+ if not self.keepFiles:
+ if os.path.isdir(self.tempDirName + os.sep):
+ shutil.rmtree(self.tempDirName, ignore_errors=True)
+
+class asyTransform(Qc.QObject):
+ """A python implementation of an asy transform"""
+
+ def __init__(self, initTuple, delete=False):
+ """Initialize the transform with a 6 entry tuple"""
+ super().__init__()
+ if isinstance(initTuple, (tuple, list)) and len(initTuple) == 6:
+ self.t = initTuple
+ self.x, self.y, self.xx, self.xy, self.yx, self.yy = initTuple
+ self._deleted = delete
+ else:
+ raise TypeError("Illegal initializer for asyTransform")
+
+ @property
+ def deleted(self):
+ return self._deleted
+
+ @deleted.setter
+ def deleted(self, value):
+ self._deleted = value
+
+ @classmethod
+ def zero(cls):
+ return asyTransform((0, 0, 0, 0, 0, 0))
+
+ @classmethod
+ def fromQTransform(cls, transform: Qg.QTransform):
+ tx, ty = transform.dx(), transform.dy()
+ xx, xy, yx, yy = transform.m11(), transform.m21(), transform.m12(), transform.m22()
+
+ return asyTransform((tx, ty, xx, xy, yx, yy))
+
+ @classmethod
+ def fromNumpyMatrix(cls, transform: np.ndarray):
+ assert transform.shape == (3, 3)
+
+ tx = transform[0, 2]
+ ty = transform[1, 2]
+
+ xx, xy, yx, yy = transform[0:2, 0:2].ravel().tolist()[0]
+
+ return asyTransform((tx, ty, xx, xy, yx, yy))
+
+ def getRawCode(self):
+ return xu.tuple2StrWOspaces(self.t)
+
+ def getCode(self, asy2psmap=None):
+ """Obtain the asy code that represents this transform"""
+ if asy2psmap is None:
+ asy2psmap = asyTransform((0, 0, 1, 0, 0, 1))
+ if self.deleted:
+ return 'zeroTransform'
+ else:
+ return (asy2psmap.inverted() * self * asy2psmap).getRawCode()
+
+ def scale(self, s):
+ return asyTransform((0, 0, s, 0, 0, s)) * self
+
+ def toQTransform(self):
+ return Qg.QTransform(self.xx, self.yx, self.xy, self.yy, self.x, self.y)
+
+ def __str__(self):
+ """Equivalent functionality to getCode(). It allows the expression str(asyTransform) to be meaningful."""
+ return self.getCode()
+
+ def isIdentity(self):
+ return self == identity()
+
+ def inverted(self):
+ return asyTransform.fromQTransform(self.toQTransform().inverted()[0])
+
+ def __eq__(self, other):
+ return list(self.t) == list(other.t)
+
+ def __mul__(self, other):
+ """Define multiplication of transforms as composition."""
+ if isinstance(other, tuple):
+ if len(other) == 6:
+ return self * asyTransform(other)
+ elif len(other) == 2:
+ return ((self.t[0] + self.t[2] * other[0] + self.t[3] * other[1]),
+ (self.t[1] + self.t[4] * other[0] + self.t[5] * other[1]))
+ else:
+ raise Exception("Illegal multiplier of {:s}".format(str(type(other))))
+ elif isinstance(other, asyTransform):
+ result = asyTransform((0, 0, 0, 0, 0, 0))
+ result.x = self.x + self.xx * other.x + self.xy * other.y
+ result.y = self.y + self.yx * other.x + self.yy * other.y
+ result.xx = self.xx * other.xx + self.xy * other.yx
+ result.xy = self.xx * other.xy + self.xy * other.yy
+ result.yx = self.yx * other.xx + self.yy * other.yx
+ result.yy = self.yx * other.xy + self.yy * other.yy
+ result.t = (result.x, result.y, result.xx, result.xy, result.yx, result.yy)
+ return result
+ elif isinstance(other, str):
+ if other != 'cycle':
+ raise TypeError
+ else:
+ return 'cycle'
+ else:
+ raise TypeError("Illegal multiplier of {:s}".format(str(type(other))))
+
+
+def identity():
+ return asyTransform((0, 0, 1, 0, 0, 1))
+
+def yflip():
+ return asyTransform((0, 0, 1, 0, 0, -1))
+
+class asyObj(Qc.QObject):
+ """A base class for asy objects: an item represented by asymptote code."""
+ def __init__(self):
+ """Initialize the object"""
+ super().__init__()
+ self.asyCode = ''
+
+ def updateCode(self, ps2asymap=identity()):
+ """Update the object's code: should be overriden."""
+ raise NotImplementedError
+
+ def getCode(self, ps2asymap=identity()):
+ """Return the code describing the object"""
+ self.updateCode(ps2asymap)
+ return self.asyCode
+
+
+class asyPen(asyObj):
+ """A python wrapper for an asymptote pen"""
+ @staticmethod
+ def getColorFromQColor(color):
+ return color.redF(), color.greenF(), color.blueF()
+
+ @staticmethod
+ def convertToQColor(color):
+ r, g, b = color
+ return Qg.QColor.fromRgbF(r, g, b)
+
+ @classmethod
+ def fromAsyPen(cls, pen):
+ assert isinstance(pen, cls)
+ return cls(asyengine=pen._asyengine, color=pen.color, width=pen.width, pen_options=pen.options)
+
+ def __init__(self, asyengine=None, color=(0, 0, 0), width=0.5, pen_options=""):
+ """Initialize the pen"""
+ asyObj.__init__(self)
+ self.color = (0, 0, 0)
+ self.options = pen_options
+ self.width = width
+ self._asyengine = asyengine
+ self._deferAsyfy = False
+ if pen_options:
+ self._deferAsyfy = True
+ self.updateCode()
+ self.setColor(color)
+
+ @property
+ def asyEngine(self):
+ return self._asyengine
+
+ @asyEngine.setter
+ def asyEngine(self, value):
+ self._asyengine = value
+
+ def updateCode(self, asy2psmap=identity()):
+ """Generate the pen's code"""
+ if self._deferAsyfy:
+ self.computeColor()
+ self.asyCode = 'rgb({:g},{:g},{:g})+{:s}'.format(self.color[0], self.color[1], self.color[2], str(self.width))
+ if len(self.options) > 0:
+ self.asyCode = self.asyCode + '+' + self.options
+
+ def setWidth(self, newWidth):
+ """Set the pen's width"""
+ self.width = newWidth
+ self.updateCode()
+
+ def setColor(self, color):
+ """Set the pen's color"""
+ if isinstance(color, tuple) and len(color) == 3:
+ self.color = color
+ else:
+ self.color = (0, 0, 0)
+ self.updateCode()
+
+ def setColorFromQColor(self, color):
+ self.setColor(asyPen.getColorFromQColor(color))
+
+ def computeColor(self):
+ """Find out the color of an arbitrary asymptote pen."""
+ assert isinstance(self.asyEngine, AsymptoteEngine)
+ assert self.asyEngine.active
+
+ fout = self.asyEngine.ostream
+ fin = self.asyEngine.istream
+
+ fout.write("pen p=" + self.getCode() + ';\n')
+ fout.write("write(_outpipe,colorspace(p),newl);\n")
+ fout.write("write(_outpipe,colors(p));\n")
+ fout.write("flush(_outpipe);\n")
+ fout.write(self.asyEngine.xasy)
+ fout.flush()
+
+ colorspace = fin.readline()
+ if colorspace.find("cmyk") != -1:
+ lines = fin.readline() + fin.readline() + fin.readline() + fin.readline()
+ parts = lines.split()
+ c, m, y, k = eval(parts[0]), eval(parts[1]), eval(parts[2]), eval(parts[3])
+ k = 1 - k
+ r, g, b = ((1 - c) * k, (1 - m) * k, (1 - y) * k)
+ elif colorspace.find("rgb") != -1:
+ lines = fin.readline() + fin.readline() + fin.readline()
+ parts = lines.split()
+ r, g, b = eval(parts[0]), eval(parts[1]), eval(parts[2])
+ elif colorspace.find("gray") != -1:
+ lines = fin.readline()
+ parts = lines.split()
+ r = g = b = eval(parts[0])
+ else:
+ raise ChildProcessError('Asymptote error.')
+ self.color = (r, g, b)
+ self._deferAsyfy = False
+
+ def tkColor(self):
+ """Return the tk version of the pen's color"""
+ self.computeColor()
+ return '#{}'.format("".join(["{:02x}".format(min(int(256 * a), 255)) for a in self.color]))
+
+ def toQPen(self):
+ if self._deferAsyfy:
+ self.computeColor()
+ newPen = Qg.QPen()
+ newPen.setColor(asyPen.convertToQColor(self.color))
+ newPen.setWidthF(self.width)
+
+ return newPen
+
+
+class asyPath(asyObj):
+ """A python wrapper for an asymptote path"""
+
+ def __init__(self, asyengine: AsymptoteEngine=None, forceCurve=False):
+ """Initialize the path to be an empty path: a path with no nodes, control points, or links."""
+ super().__init__()
+ self.nodeSet = []
+ self.linkSet = []
+ self.forceCurve = forceCurve
+ self.controlSet = []
+ self.computed = False
+ self.asyengine = asyengine
+
+ @classmethod
+ def fromPath(cls, oldPath):
+ newObj = asyPath(None)
+ newObj.nodeSet = copy.copy(oldPath.nodeSet)
+ newObj.linkSet = copy.copy(oldPath.linkSet)
+ newObj.controlSet = copy.deepcopy(oldPath.controlSet)
+ newObj.computed = oldPath.computed
+ newObj.asyengine = oldPath.asyengine
+
+ return newObj
+
+ @classmethod
+ def fromBezierPoints(cls, pointList: list, engine=None):
+ if not pointList:
+ return None
+ assert isinstance(pointList[0], BezierCurveEditor.BezierPoint)
+ nodeList = []
+ controlList = []
+ for point in pointList:
+ nodeList.append(BezierCurveEditor.QPoint2Tuple(point.point))
+ if point.rCtrlPoint is not None: # first
+ controlList.append([BezierCurveEditor.QPoint2Tuple(point.rCtrlPoint)])
+ if point.lCtrlPoint is not None: # last
+ controlList[-1].append(BezierCurveEditor.QPoint2Tuple(point.lCtrlPoint))
+ newPath = asyPath(asyengine=engine)
+ newPath.initFromControls(nodeList, controlList)
+ return newPath
+
+ def setInfo(self, path):
+ self.nodeSet = copy.copy(path.nodeSet)
+ self.linkSet = copy.copy(path.linkSet)
+ self.controlSet = copy.deepcopy(path.controlSet)
+ self.computed = path.computed
+
+ @property
+ def isEmpty(self):
+ return len(self.nodeSet) == 0
+
+ @property
+ def isDrawable(self):
+ return len(self.nodeSet) >= 2
+
+ def toQPainterPath(self) -> Qg.QPainterPath:
+ return self.toQPainterPathCurve() if self.containsCurve else self.toQPainterPathLine()
+
+ def toQPainterPathLine(self):
+ baseX, baseY = self.nodeSet[0]
+ painterPath = Qg.QPainterPath(Qc.QPointF(baseX, baseY))
+
+ for pointIndex in range(1, len(self.nodeSet)):
+ node = self.nodeSet[pointIndex]
+ if self.nodeSet[pointIndex] == 'cycle':
+ node = self.nodeSet[0]
+
+ painterPath.lineTo(*node)
+
+ return painterPath
+
+
+ def toQPainterPathCurve(self):
+ if not self.computed:
+ self.computeControls()
+
+ baseX, baseY = self.nodeSet[0]
+ painterPath = Qg.QPainterPath(Qc.QPointF(baseX, baseY))
+
+ for pointIndex in range(1, len(self.nodeSet)):
+ node = self.nodeSet[pointIndex]
+ if self.nodeSet[pointIndex] == 'cycle':
+ node = self.nodeSet[0]
+ endPoint = Qc.QPointF(node[0], node[1])
+ ctrlPoint1 = Qc.QPointF(self.controlSet[pointIndex-1][0][0], self.controlSet[pointIndex-1][0][1])
+ ctrlPoint2 = Qc.QPointF(self.controlSet[pointIndex-1][1][0], self.controlSet[pointIndex-1][1][1])
+
+ painterPath.cubicTo(ctrlPoint1, ctrlPoint2, endPoint)
+ return painterPath
+
+ def initFromNodeList(self, nodeSet, linkSet):
+ """Initialize the path from a set of nodes and link types, "--", "..", or "::" """
+ if len(nodeSet) > 0:
+ self.nodeSet = nodeSet[:]
+ self.linkSet = linkSet[:]
+ self.computed = False
+
+ def initFromControls(self, nodeSet, controlSet):
+ """Initialize the path from nodes and control points"""
+ self.controlSet = controlSet[:]
+ self.nodeSet = nodeSet[:]
+ self.computed = True
+
+ def makeNodeStr(self, node):
+ """Represent a node as a string"""
+ if node == 'cycle':
+ return node
+ else:
+ # if really want to, disable this rounding
+ # shouldn't be to much of a problem since 10e-6 is quite small...
+ return '({:.6g},{:.6g})'.format(node[0], node[1])
+
+ def updateCode(self, ps2asymap=identity()):
+ """Generate the code describing the path"""
+ # currently at postscript. Convert to asy
+ asy2psmap = ps2asymap.inverted()
+ with io.StringIO() as rawAsyCode:
+ count = 0
+ rawAsyCode.write(self.makeNodeStr(asy2psmap * self.nodeSet[0]))
+ for node in self.nodeSet[1:]:
+ if not self.computed or count >= len(self.controlSet):
+ rawAsyCode.write(self.linkSet[count])
+ rawAsyCode.write(self.makeNodeStr(asy2psmap * node))
+ else:
+ rawAsyCode.write('..controls ')
+ rawAsyCode.write(self.makeNodeStr(asy2psmap * self.controlSet[count][0]))
+ rawAsyCode.write(' and ')
+ rawAsyCode.write(self.makeNodeStr(asy2psmap * self.controlSet[count][1]))
+ rawAsyCode.write(".." + self.makeNodeStr(asy2psmap * node))
+ count = count + 1
+ self.asyCode = rawAsyCode.getvalue()
+
+ @property
+ def containsCurve(self):
+ return '..' in self.linkSet or self.forceCurve
+
+ def getNode(self, index):
+ """Return the requested node"""
+ return self.nodeSet[index]
+
+ def getLink(self, index):
+ """Return the requested link"""
+ return self.linkSet[index]
+
+ def setNode(self, index, newNode):
+ """Set a node to a new position"""
+ self.nodeSet[index] = newNode
+
+ def moveNode(self, index, offset):
+ """Translate a node"""
+ if self.nodeSet[index] != "cycle":
+ self.nodeSet[index] = (self.nodeSet[index][0] + offset[0], self.nodeSet[index][1] + offset[1])
+
+ def setLink(self, index, ltype):
+ """Change the specified link"""
+ self.linkSet[index] = ltype
+
+ def addNode(self, point, ltype):
+ """Add a node to the end of a path"""
+ self.nodeSet.append(point)
+ if len(self.nodeSet) != 1:
+ self.linkSet.append(ltype)
+ if self.computed:
+ self.computeControls()
+
+ def insertNode(self, index, point, ltype=".."):
+ """Insert a node, and its corresponding link, at the given index"""
+ self.nodeSet.insert(index, point)
+ self.linkSet.insert(index, ltype)
+ if self.computed:
+ self.computeControls()
+
+ def setControl(self, index, position):
+ """Set a control point to a new position"""
+ self.controlSet[index] = position
+
+ def popNode(self):
+ if len(self.controlSet) == len(self.nodeSet):
+ self.controlSet.pop()
+ self.nodeSet.pop()
+ self.linkSet.pop()
+
+ def moveControl(self, index, offset):
+ """Translate a control point"""
+ self.controlSet[index] = (self.controlSet[index][0] + offset[0], self.controlSet[index][1] + offset[1])
+
+ def computeControls(self):
+ """Evaluate the code of the path to obtain its control points"""
+ # For now, if no asymptote process is given spawns a new one.
+ # Only happens if asyengine is None.
+ if self.asyengine is not None:
+ assert isinstance(self.asyengine, AsymptoteEngine)
+ assert self.asyengine.active
+ asy = self.asyengine
+ startUp = False
+ else:
+ startUp = True
+ asy = AsymptoteEngine()
+ asy.start()
+
+ fout = asy.ostream
+ fin = asy.istream
+
+ fout.write("path p=" + self.getCode() + ';\n')
+ fout.write("write(_outpipe,length(p),newl);\n")
+ fout.write("write(_outpipe,unstraighten(p),endl);\n")
+ fout.write(asy.xasy)
+ fout.flush()
+
+ lengthStr = fin.readline()
+ pathSegments = eval(lengthStr.split()[-1])
+ pathStrLines = []
+ for i in range(pathSegments + 1):
+ line = fin.readline()
+ line = line.replace("\n", "")
+ pathStrLines.append(line)
+ oneLiner = "".join(pathStrLines).replace(" ", "")
+ splitList = oneLiner.split("..")
+ nodes = [a for a in splitList if a.find("controls") == -1]
+ self.nodeSet = []
+ for a in nodes:
+ if a == 'cycle':
+ self.nodeSet.append(a)
+ else:
+ self.nodeSet.append(eval(a))
+ controls = [a.replace("controls", "").split("and") for a in splitList if a.find("controls") != -1]
+ self.controlSet = [[eval(a[0]), eval(a[1])] for a in controls]
+ self.computed = True
+
+ if startUp:
+ asy.stop()
+
+class asyLabel(asyObj):
+ """A python wrapper for an asy label"""
+
+ def __init__(self, text="", location=(0, 0), pen=None, align=None, fontSize:int=None):
+ """Initialize the label with the given test, location, and pen"""
+ asyObj.__init__(self)
+ self.align = align
+ self.pen = pen
+ self.fontSize = fontSize
+ if align is None:
+ self.align = 'SE'
+ if pen is None:
+ self.pen = asyPen()
+ self.text = text
+ self.location = location
+
+ def updateCode(self, asy2psmap=identity()):
+ """Generate the code describing the label"""
+ newLoc = asy2psmap.inverted() * self.location
+ locStr = xu.tuple2StrWOspaces(newLoc)
+ self.asyCode = 'Label("{0}",{1},p={2}{4},align={3})'.format(self.text, locStr, self.pen.getCode(), self.align,
+ self.getFontSizeText())
+
+ def getFontSizeText(self):
+ if self.fontSize is not None:
+ return '+fontsize({:.6g})'.format(self.fontSize)
+ else:
+ return ''
+
+ def setText(self, text):
+ """Set the label's text"""
+ self.text = text
+ self.updateCode()
+
+ def setPen(self, pen):
+ """Set the label's pen"""
+ self.pen = pen
+ self.updateCode()
+
+ def moveTo(self, newl):
+ """Translate the label's location"""
+ self.location = newl
+
+
+class asyImage:
+ """A structure containing an image and its format, bbox, and IDTag"""
+ def __init__(self, image, format, bbox, transfKey=None, keyIndex=0):
+ self.image = image
+ self.format = format
+ self.bbox = bbox
+ self.IDTag = None
+ self.key = transfKey
+ self.keyIndex = keyIndex
+
+class xasyItem(Qc.QObject):
+ """A base class for items in the xasy GUI"""
+ mapString = 'xmap'
+ setKeyFormatStr = string.Template('$map("{:s}",{:s});').substitute(map=mapString)
+ setKeyAloneFormatStr = string.Template('$map("{:s}");').substitute(map=mapString)
+ resizeComment="// Resize to initial xasy transform"
+ asySize=""
+ def __init__(self, canvas=None, asyengine=None):
+ """Initialize the item to an empty item"""
+ super().__init__()
+ self.transfKeymap = {} # the new keymap.
+ # should be a dictionary to a list...
+ self.asyCode = ''
+ self.imageList = []
+ self.IDTag = None
+ self.asyfied = False
+ self.onCanvas = canvas
+ self.keyBuffer = None
+ self._asyengine = asyengine
+ self.drawObjects = []
+ self.drawObjectsMap = {}
+ self.setKeyed = True
+ self.unsetKeys = set()
+ self.userKeys = set()
+ self.lineOffset = 0
+ self.imageHandleQueue = queue.Queue()
+
+ def updateCode(self, ps2asymap=identity()):
+ """Update the item's code: to be overriden"""
+ with io.StringIO() as rawCode:
+ transfCode = self.getTransformCode()
+ objCode = self.getObjectCode()
+
+ rawCode.write(transfCode)
+ rawCode.write(objCode)
+ self.asyCode = rawCode.getvalue()
+
+ return len(transfCode.splitlines()), len(objCode.splitlines())
+
+ @property
+ def asyengine(self):
+ return self._asyengine
+
+ @asyengine.setter
+ def asyengine(self, value):
+ self._asyengine = value
+
+ def getCode(self, ps2asymap=identity()):
+ """Return the code describing the item"""
+ self.updateCode(ps2asymap)
+ return self.asyCode
+
+ def getTransformCode(self, asy2psmap=identity()):
+ raise NotImplementedError
+
+ def getObjectCode(self, asy2psmap=identity()):
+ raise NotImplementedError
+
+ def generateDrawObjects(self):
+ raise NotImplementedError
+
+ def handleImageReception(self, file, fileformat, bbox, count, key=None, localCount=0, containsClip=False):
+ """Receive an image from an asy deconstruction. It replaces the default n asyProcess."""
+ # image = Image.open(file).transpose(Image.FLIP_TOP_BOTTOM)
+ if fileformat == 'png':
+ image = Qg.QImage(file)
+ elif fileformat == 'svg':
+ if containsClip:
+ image = xs.SvgObject(file)
+ else:
+ image = Qs.QSvgRenderer(file)
+ assert image.isValid()
+ else:
+ raise Exception('Format not supported!')
+ self.imageList.append(asyImage(image, fileformat, bbox, transfKey=key, keyIndex=localCount))
+ if self.onCanvas is not None:
+ # self.imageList[-1].iqt = ImageTk.PhotoImage(image)
+ currImage = self.imageList[-1]
+ currImage.iqt = image
+ currImage.originalImage = image
+ currImage.originalImage.theta = 0.0
+ currImage.originalImage.bbox = list(bbox)
+ currImage.performCanvasTransform = False
+
+ # handle this case if transform is not in the map yet.
+ # if deleted - set transform to 0, 0, 0, 0, 0
+ transfExists = key in self.transfKeymap.keys()
+ if transfExists:
+ transfExists = localCount <= len(self.transfKeymap[key]) - 1
+ if transfExists:
+ validKey = not self.transfKeymap[key][localCount].deleted
+ else:
+ validKey = False
+
+ if (not transfExists) or validKey:
+ currImage.IDTag = str(file)
+ newDrawObj = DrawObject(currImage.iqt, self.onCanvas['canvas'], transform=identity(),
+ btmRightanchor=Qc.QPointF(bbox[0], bbox[2]), drawOrder=-1, key=key,
+ parentObj=self, keyIndex=localCount)
+ newDrawObj.setBoundingBoxPs(bbox)
+ newDrawObj.setParent(self)
+
+ self.drawObjects.append(newDrawObj)
+
+ if key not in self.drawObjectsMap.keys():
+ self.drawObjectsMap[key] = [newDrawObj]
+ else:
+ self.drawObjectsMap[key].append(newDrawObj)
+ return containsClip
+ def asyfy(self, force=False):
+ if self.asyengine is None:
+ return 1
+ if self.asyfied and not force:
+ return
+
+ self.drawObjects = []
+ self.drawObjectsMap.clear()
+ assert isinstance(self.asyengine, AsymptoteEngine)
+ self.imageList = []
+
+ self.unsetKeys.clear()
+ self.userKeys.clear()
+
+ self.imageHandleQueue = queue.Queue()
+ worker = threading.Thread(target=self.asyfyThread, args=[])
+ worker.start()
+ item = self.imageHandleQueue.get()
+ while item != (None,) and item[0] != "ERROR":
+ if item[0] == "OUTPUT":
+ print(item[1])
+ else:
+ keepFile = self.handleImageReception(*item)
+ if not DebugFlags.keepFiles and not keepFile:
+ try:
+ os.remove(item[0])
+ pass
+ except OSError:
+ pass
+ finally:
+ pass
+ item = self.imageHandleQueue.get()
+ # self.imageHandleQueue.task_done()
+ worker.join()
+
+ def asyfyThread(self):
+ """Convert the item to a list of images by deconstructing this item's code"""
+ assert self.asyengine.active
+
+ fout = self.asyengine.ostream
+ fin = self.asyengine.istream
+
+ self.lineOffset = len(self.getTransformCode().splitlines())
+
+ fout.write("reset\n")
+ fout.flush();
+ for line in self.getCode().splitlines():
+ if DebugFlags.printDeconstTranscript:
+ print('fout:', line)
+ fout.write(line+"\n")
+ fout.write(self.asySize)
+ fout.write("deconstruct();\n")
+ fout.write('write(_outpipe,yscale(-1)*currentpicture.calculateTransform(),endl);\n')
+ fout.write(self.asyengine.xasy)
+ fout.flush()
+
+ imageInfos = [] # of (box, key)
+ n = 0
+
+ keyCounts = {}
+
+ def render():
+ for i in range(len(imageInfos)):
+ box, key, localCount, useClip = imageInfos[i]
+ l, b, r, t = [float(a) for a in box.split()]
+ name = "{:s}_{:d}.{:s}".format(self.asyengine.tempDirName, i, fileformat)
+
+ self.imageHandleQueue.put((name, fileformat, (l, -t, r, -b), i, key, localCount, useClip))
+
+ # key first, box second.
+ # if key is "Done"
+ raw_text = fin.readline()
+ text = ""
+ if DebugFlags.printDeconstTranscript:
+ print(raw_text.strip())
+
+ # template=AsyTempDir+"%d_%d.%s"
+ fileformat = 'svg'
+
+ while raw_text != "Done\n" and raw_text != "Error\n":
+# print(raw_text)
+ text = fin.readline() # the actual bounding box.
+ # print('TESTING:', text)
+ keydata = raw_text.strip().replace('KEY=', '', 1) # key
+
+ clipflag = keydata[-1] == '1'
+ userkey = keydata[-2] == '1'
+ keydata = keydata[:-3]
+
+ if not userkey:
+ self.unsetKeys.add(keydata) # the line and column to replace.
+ else:
+ self.userKeys.add(keydata)
+
+# print(line, col)
+
+ if keydata not in keyCounts.keys():
+ keyCounts[keydata] = 0
+
+ imageInfos.append((text, keydata, keyCounts[keydata], clipflag)) # key-data pair
+
+ # for the next item
+ keyCounts[keydata] += 1
+
+ raw_text = fin.readline()
+
+ if DebugFlags.printDeconstTranscript:
+ print(text.rstrip())
+ print(raw_text.rstrip())
+
+ n += 1
+
+ if text == "Error\n":
+ self.imageHandleQueue.put(("ERROR", fin.readline()))
+ else:
+ render()
+
+ self.asy2psmap = asyTransform(xu.listize(fin.readline().rstrip(),float))
+ self.imageHandleQueue.put((None,))
+ self.asyfied = True
+
+class xasyDrawnItem(xasyItem):
+ """A base class for GUI items was drawn by the user. It combines a path, a pen, and a transform."""
+
+ def __init__(self, path, engine, pen=None, transform=identity(), key=None):
+ """Initialize the item with a path, pen, and transform"""
+ super().__init__(canvas=None, asyengine=engine)
+ if pen is None:
+ pen = asyPen()
+ self.path = path
+ self.path.asyengine = engine
+ self.asyfied = True
+ self.pen = pen
+ self._asyengine = engine
+ self.rawIdentifier = ''
+ self.transfKey = key
+ self.transfKeymap = {self.transfKey: [transform]}
+
+ @property
+ def asyengine(self):
+ return self._asyengine
+
+ @asyengine.setter
+ def asyengine(self, value: AsymptoteEngine):
+ self._asyengine = value
+ self.path.asyengine = value
+
+ def setKey(self, newKey=None):
+ transform = self.transfKeymap[self.transfKey][0]
+
+ self.transfKey = newKey
+ self.transfKeymap = {self.transfKey: [transform]}
+
+ def generateDrawObjects(self, forceUpdate=False):
+ raise NotImplementedError
+
+ def appendPoint(self, point, link=None):
+ """Append a point to the path. If the path is cyclic, add this point before the 'cycle' node."""
+ if self.path.nodeSet[-1] == 'cycle':
+ self.path.nodeSet[-1] = point
+ self.path.nodeSet.append('cycle')
+ else:
+ self.path.nodeSet.append(point)
+ self.path.computed = False
+ self.asyfied = False
+ if len(self.path.nodeSet) > 1 and link is not None:
+ self.path.linkSet.append(link)
+
+ def clearTransform(self):
+ """Reset the item's transform"""
+ self.transform = [identity()]
+ self.asyfied = False
+
+ def removeLastPoint(self):
+ """Remove the last point in the path. If the path is cyclic, remove the node before the 'cycle' node."""
+ if self.path.nodeSet[-1] == 'cycle':
+ del self.path.nodeSet[-2]
+ else:
+ del self.path.nodeSet[-1]
+ del self.path.linkSet[-1]
+ self.path.computed = False
+ self.asyfied = False
+
+ def setLastPoint(self, point):
+ """Modify the last point in the path. If the path is cyclic, modify the node before the 'cycle' node."""
+ if self.path.nodeSet[-1] == 'cycle':
+ self.path.nodeSet[-2] = point
+ else:
+ self.path.nodeSet[-1] = point
+ self.path.computed = False
+ self.asyfied = False
+
+
+class xasyShape(xasyDrawnItem):
+ """An outlined shape drawn on the GUI"""
+ def __init__(self, path, asyengine, pen=None, transform=identity()):
+ """Initialize the shape with a path, pen, and transform"""
+ super().__init__(path=path, engine=asyengine, pen=pen, transform=transform)
+
+ def getObjectCode(self, asy2psmap=identity()):
+ return 'draw(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
+
+ def getTransformCode(self, asy2psmap=identity()):
+ transf = self.transfKeymap[self.transfKey][0]
+ if transf == identity():
+ return ''
+ else:
+ return xasyItem.setKeyFormatStr.format(self.transfKey, transf.getCode(asy2psmap))+'\n'
+
+ def generateDrawObjects(self, forceUpdate=False):
+ if self.path.containsCurve:
+ self.path.computeControls()
+ transf = self.transfKeymap[self.transfKey][0]
+
+ newObj = DrawObject(self.path.toQPainterPath(), None, drawOrder=0, transform=transf, pen=self.pen,
+ key=self.transfKey)
+ newObj.originalObj = self
+ newObj.setParent(self)
+ return [newObj]
+
+ def __str__(self):
+ """Create a string describing this shape"""
+ return "xasyShape code:{:s}".format("\n\t".join(self.getCode().splitlines()))
+
+
+class xasyFilledShape(xasyShape):
+ """A filled shape drawn on the GUI"""
+
+ def __init__(self, path, asyengine, pen=None, transform=identity()):
+ """Initialize this shape with a path, pen, and transform"""
+ if path.nodeSet[-1] != 'cycle':
+ raise Exception("Filled paths must be cyclic")
+ super().__init__(path, asyengine, pen, transform)
+
+ def getObjectCode(self, asy2psmap=identity()):
+ return 'fill(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
+
+ def generateDrawObjects(self, forceUpdate=False):
+ if self.path.containsCurve:
+ self.path.computeControls()
+ newObj = DrawObject(self.path.toQPainterPath(), None, drawOrder=0, transform=self.transfKeymap[self.transfKey][0],
+ pen=self.pen, key=self.transfKey, fill=True)
+ newObj.originalObj = self
+ newObj.setParent(self)
+ return [newObj]
+
+ def __str__(self):
+ """Return a string describing this shape"""
+ return "xasyFilledShape code:{:s}".format("\n\t".join(self.getCode().splitlines()))
+
+
+class xasyText(xasyItem):
+ """Text created by the GUI"""
+
+ def __init__(self, text, location, asyengine, pen=None, transform=yflip(), key=None, align=None, fontsize:int=None):
+ """Initialize this item with text, a location, pen, and transform"""
+ super().__init__(asyengine=asyengine)
+ if pen is None:
+ pen = asyPen(asyengine=asyengine)
+ if pen.asyEngine is None:
+ pen.asyEngine = asyengine
+ self.label = asyLabel(text, location, pen, align, fontSize=fontsize)
+ # self.transform = [transform]
+ self.transfKey = key
+ self.transfKeymap = {self.transfKey: [transform]}
+ self.asyfied = False
+ self.onCanvas = None
+
+ def setKey(self, newKey=None):
+ transform = self.transfKeymap[self.transfKey][0]
+
+ self.transfKey = newKey
+ self.transfKeymap = {self.transfKey: [transform]}
+
+ def getTransformCode(self, asy2psmap=yflip()):
+ transf = self.transfKeymap[self.transfKey][0]
+ if transf == yflip():
+ # return xasyItem.setKeyAloneFormatStr.format(self.transfKey)
+ return ''
+ else:
+ return xasyItem.setKeyFormatStr.format(self.transfKey, transf.getCode(asy2psmap))+"\n"
+
+ def getObjectCode(self, asy2psmap=yflip()):
+ return 'label(KEY="{0}",{1});'.format(self.transfKey, self.label.getCode(asy2psmap))+'\n'
+
+ def generateDrawObjects(self, forceUpdate=False):
+ self.asyfy(forceUpdate)
+ return self.drawObjects
+
+ def getBoundingBox(self):
+ self.asyfy()
+ return self.imageList[0].bbox
+
+ def __str__(self):
+ return "xasyText code:{:s}".format("\n\t".join(self.getCode().splitlines()))
+
+
+class xasyScript(xasyItem):
+ """A set of images create from asymptote code. It is always deconstructed."""
+
+ def __init__(self, canvas, engine, script="", transforms=None, transfKeyMap=None):
+ """Initialize this script item"""
+ super().__init__(canvas, asyengine=engine)
+ if transfKeyMap is not None:
+ self.transfKeymap = transfKeyMap
+ else:
+ self.transfKeymap = {}
+
+ self.script = script
+ self.key2imagemap = {}
+ self.namedUnsetKeys = {}
+ self.keyPrefix = ''
+ self.scriptAsyfied = False
+ self.updatedPrefix = True
+
+ def clearTransform(self):
+ """Reset the transforms for each of the deconstructed images"""
+ # self.transform = [identity()] * len(self.imageList)
+ keyCount = {}
+
+ for im in self.imageList:
+ if im.key not in keyCount.keys():
+ keyCount[im.key] = 1
+ else:
+ keyCount[im.key] += 1
+
+ for key in keyCount:
+ self.transfKeymap[key] = [identity()] * keyCount[key]
+
+ def getMaxKeyCounter(self):
+ maxCounter = -1
+ for key in self.transfKeymap:
+ testNum = re.match(r'^x(\d+)$', key)
+ if testNum is not None:
+ maxCounter = max(maxCounter, int(testNum.group(1)))
+ return maxCounter + 1
+
+ def getTransformCode(self, asy2psmap=identity()):
+ with io.StringIO() as rawAsyCode:
+ if self.transfKeymap:
+ for key in self.transfKeymap.keys():
+ val = self.transfKeymap[key]
+
+ writeval = list(reversed(val))
+ # need to map all transforms in a list if there is any non-identity
+ # unfortunately, have to check all transformations in the list.
+ while not all(checktransf == identity() for checktransf in writeval) and writeval:
+ transf = writeval.pop()
+ if transf.deleted:
+ rawAsyCode.write(xasyItem.setKeyFormatStr.format(key, transf.getCode(asy2psmap)) + '\n//')
+ if transf == identity() and not transf.deleted:
+ rawAsyCode.write(xasyItem.setKeyAloneFormatStr.format(key))
+ else:
+ rawAsyCode.write(xasyItem.setKeyFormatStr.format(key, transf.getCode(asy2psmap)))
+ rawAsyCode.write('\n')
+ result = rawAsyCode.getvalue()
+ return result
+
+ def findNonIdKeys(self):
+ return {key for key in self.transfKeymap if not all(transf == identity() for transf in self.transfKeymap[key]) }
+
+ def getObjectCode(self, asy2psmap=identity()):
+ numeric=r'([-+]?(?:(?:\d*\.\d+)|(?:\d+\.?)))'
+ rSize=re.compile("size\(\("+numeric+","+numeric+","+numeric+","
+ +numeric+","+numeric+","+numeric+"\)\); "+
+ self.resizeComment)
+
+ newScript = self.getReplacedKeysCode(self.findNonIdKeys())
+ with io.StringIO() as rawAsyCode:
+ for line in newScript.splitlines():
+ if(rSize.match(line)):
+ self.asySize=line.rstrip()+'\n'
+ else:
+ raw_line = line.rstrip().replace('\t', ' ' * 4)
+ rawAsyCode.write(raw_line + '\n')
+
+ self.updatedCode = rawAsyCode.getvalue()
+ return self.updatedCode
+
+ def setScript(self, script):
+ """Sets the content of the script item."""
+ self.script = script
+ self.updateCode()
+
+ def setKeyPrefix(self, newPrefix=''):
+ self.keyPrefix = newPrefix
+ self.updatedPrefix = False
+
+ def getReplacedKeysCode(self, key2replace: set=None) -> str:
+ keylist = {}
+ prefix = ''
+
+ key2replaceSet = self.unsetKeys if key2replace is None else \
+ self.unsetKeys & key2replace
+
+ linenum2key = {}
+
+ if not self.updatedPrefix:
+ prefix = self.keyPrefix
+
+ for key in key2replaceSet:
+ actualkey = key
+
+ key = key.split(':')[0]
+ raw_parsed = xu.tryParseKey(key)
+ assert raw_parsed is not None
+ line, col = [int(val) for val in raw_parsed.groups()]
+ if line not in keylist:
+ keylist[line] = set()
+ keylist[line].add(col)
+ linenum2key[(line, col)] = actualkey
+ self.unsetKeys.discard(key)
+
+
+ raw_code_lines = self.script.splitlines()
+ with io.StringIO() as raw_str:
+ for i_0 in range(len(raw_code_lines)):
+ i = i_0 + self.lineOffset
+ curr_str = raw_code_lines[i_0]
+ if i + 1 in keylist.keys():
+ # this case, we have a key.
+ with io.StringIO() as raw_line:
+ for j in range(len(curr_str)):
+ raw_line.write(curr_str[j])
+ if j + 1 in keylist[i + 1]:
+ # at this point, replace keys with xkey
+ raw_line.write('KEY="{0:s}",'.format(linenum2key[(i + 1, j + 1)]))
+ self.userKeys.add(linenum2key[(i + 1, j + 1)])
+ curr_str = raw_line.getvalue()
+ # else, skip and just write the line.
+ raw_str.write(curr_str + '\n')
+ return raw_str.getvalue()
+
+ def getUnusedKey(self, oldkey) -> str:
+ baseCounter = 0
+ newKey = oldkey
+ while newKey in self.userKeys:
+ newKey = oldkey + ':' + str(baseCounter)
+ baseCounter += 1
+ return newKey
+
+ def asyfy(self, keyOnly=False):
+ """Generate the list of images described by this object and adjust the length of the transform list."""
+ super().asyfy()
+
+ # Id --> Transf --> asy-fied --> Transf
+ # Transf should keep the original, raw transformation
+ # but for all new drawn objects - assign Id as transform.
+
+ if self.scriptAsyfied:
+ return
+
+ keyCount = {}
+ settedKey = {}
+
+ for im in self.imageList:
+ if im.key in self.unsetKeys and im.key not in settedKey.keys():
+ oldkey = im.key
+ self.unsetKeys.remove(im.key)
+ im.key = self.getUnusedKey(im.key)
+ self.unsetKeys.add(im.key)
+
+ for drawobj in self.drawObjectsMap[oldkey]:
+ drawobj.key = im.key
+
+ self.drawObjectsMap[im.key] = self.drawObjectsMap[oldkey]
+ self.drawObjectsMap.pop(oldkey)
+
+ settedKey[oldkey] = im.key
+ elif im.key in settedKey.keys():
+ im.key = settedKey[im.key]
+
+ if im.key not in keyCount.keys():
+ keyCount[im.key] = 1
+ else:
+ keyCount[im.key] += 1
+
+ if im.key not in self.key2imagemap.keys():
+ self.key2imagemap[im.key] = [im]
+ else:
+ self.key2imagemap[im.key].append(im)
+
+
+
+ for key in keyCount:
+ if key not in self.transfKeymap.keys():
+ self.transfKeymap[key] = [identity()] * keyCount[key]
+ else:
+ while len(self.transfKeymap[key]) < keyCount[key]:
+ self.transfKeymap[key].append(identity())
+
+ # while len(self.transfKeymap[key]) > keyCount[key]:
+ # self.transfKeymap[key].pop()
+
+ # change of basis
+ for keylist in self.transfKeymap.values():
+ for i in range(len(keylist)):
+ if keylist[i] != identity():
+ keylist[i] = self.asy2psmap * keylist[i] * self.asy2psmap.inverted()
+
+ self.updateCode()
+ self.scriptAsyfied = True
+
+ def generateDrawObjects(self, forceUpdate=False):
+ self.asyfy(forceUpdate)
+ return self.drawObjects
+
+ def __str__(self):
+ """Return a string describing this script"""
+ retVal = "xasyScript\n\tTransforms:\n"
+ for xform in self.transform:
+ retVal += "\t" + str(xform) + "\n"
+ retVal += "\tCode Ommitted"
+ return retVal
+
+
+class DrawObject(Qc.QObject):
+ def __init__(self, drawObject, mainCanvas=None, transform=identity(), btmRightanchor=Qc.QPointF(0, 0),
+ drawOrder=(-1, -1), pen=None, key=None, parentObj=None, fill=False, keyIndex=0):
+ super().__init__()
+ self.drawObject = drawObject
+ self.mainCanvas = mainCanvas
+ self.pTransform = transform
+ self.baseTransform = transform
+ self.drawOrder = drawOrder
+ self.btmRightAnchor = btmRightanchor
+ self.originalObj = parentObj
+ self.explicitBoundingBox = None
+ self.useCanvasTransformation = False
+ self.key = key
+ self.cachedSvgImg = None
+ self.cachedDPI = None
+ self.maxDPI=0
+ self.keyIndex = keyIndex
+ self.pen = pen
+ self.fill = fill
+
+ def getInteriorScrTransform(self, transform):
+ """Generates the transform with Interior transform applied beforehand."""
+ if isinstance(transform, Qg.QTransform):
+ transform = asyTransform.fromQTransform(transform)
+ return self.transform * transform * self.baseTransform.inverted()
+
+ @property
+ def transform(self):
+ return self.pTransform
+
+ @transform.setter
+ def transform(self, value):
+ self.pTransform = value
+
+ def setBoundingBoxPs(self, bbox):
+ l, b, r, t = bbox
+ self.explicitBoundingBox = Qc.QRectF(Qc.QPointF(l, b), Qc.QPointF(r, t))
+ # self.explicitBoundingBox = Qc.QRectF(0, 0, 100, 100)
+
+ @property
+ def boundingBox(self):
+ if self.explicitBoundingBox is not None:
+ testBbox = self.explicitBoundingBox
+ else:
+ if isinstance(self.drawObject, Qg.QImage):
+ testBbox = self.drawObject.rect()
+ testBbox.moveTo(self.btmRightAnchor.toPoint())
+ elif isinstance(self.drawObject, Qg.QPainterPath):
+ testBbox = self.baseTransform.toQTransform().mapRect(self.drawObject.boundingRect())
+ else:
+ raise TypeError('drawObject is not a valid type!')
+ pointList = [self.getScreenTransform().toQTransform().map(point) for point in [
+ testBbox.topLeft(), testBbox.topRight(), testBbox.bottomLeft(), testBbox.bottomRight()
+ ]]
+ return Qg.QPolygonF(pointList).boundingRect()
+
+ @property
+ def localBoundingBox(self):
+ testBbox = self.drawObject.rect()
+ testBbox.moveTo(self.btmRightAnchor.toPoint())
+ return testBbox
+
+ def getScreenTransform(self):
+ scrTransf = self.baseTransform.toQTransform().inverted()[0] * self.pTransform.toQTransform()
+ return asyTransform.fromQTransform(scrTransf)
+
+ def draw(self, additionalTransformation=None, applyReverse=False, canvas: Qg.QPainter=None, dpi=300):
+ if canvas is None:
+ canvas = self.mainCanvas
+ if additionalTransformation is None:
+ additionalTransformation = Qg.QTransform()
+
+ assert canvas.isActive()
+
+ canvas.save()
+ if self.pen:
+ oldPen = Qg.QPen(canvas.pen())
+ canvas.setPen(self.pen.toQPen())
+ else:
+ oldPen = Qg.QPen()
+
+ if not applyReverse:
+ canvas.setTransform(additionalTransformation, True)
+ canvas.setTransform(self.transform.toQTransform(), True)
+ else:
+ canvas.setTransform(self.transform.toQTransform(), True)
+ canvas.setTransform(additionalTransformation, True)
+
+ canvas.setTransform(self.baseTransform.toQTransform().inverted()[0], True)
+
+ if isinstance(self.drawObject, Qg.QImage):
+ canvas.drawImage(self.explicitBoundingBox, self.drawObject)
+ elif isinstance(self.drawObject, xs.SvgObject):
+ threshold = 1.44
+
+ if self.cachedDPI is None or self.cachedSvgImg is None \
+ or dpi > self.maxDPI*threshold:
+ self.cachedDPI = dpi
+ self.maxDPI=max(self.maxDPI,dpi)
+ self.cachedSvgImg = self.drawObject.render(dpi)
+
+ canvas.drawImage(self.explicitBoundingBox, self.cachedSvgImg)
+ elif isinstance(self.drawObject, Qs.QSvgRenderer):
+ self.drawObject.render(canvas, self.explicitBoundingBox)
+ elif isinstance(self.drawObject, Qg.QPainterPath):
+ path = self.baseTransform.toQTransform().map(self.drawObject)
+ if self.fill:
+ if self.pen:
+ brush = self.pen.toQPen().brush()
+ else:
+ brush = Qg.QBrush()
+ canvas.fillPath(path, brush)
+ else:
+ canvas.drawPath(path)
+
+ if self.pen:
+ canvas.setPen(oldPen)
+ canvas.restore()
+
+ def collide(self, coords, canvasCoordinates=True):
+ # modify these values to grow/shrink the fuzz.
+ fuzzTolerance = 1
+ marginGrowth = 1
+ leftMargin = marginGrowth if self.boundingBox.width() < fuzzTolerance else 0
+ topMargin = marginGrowth if self.boundingBox.height() < fuzzTolerance else 0
+
+ newMargin = Qc.QMarginsF(leftMargin, topMargin, leftMargin, topMargin)
+ return self.boundingBox.marginsAdded(newMargin).contains(coords)
+
+ def getID(self):
+ return self.originalObj
diff --git a/graphics/asymptote/GUI/xasyArgs.py b/graphics/asymptote/GUI/xasyArgs.py
new file mode 100644
index 0000000000..045f4bc669
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyArgs.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+import argparse
+import xasyVersion
+import PyQt5.QtCore as Qc
+# Add arguments here.
+
+
+def parseArgs(args):
+ parser = argparse.ArgumentParser(args)
+ parser.add_argument('-p', '--asypath', help='Custom Asymptote asy executable')
+ parser.add_argument('-v', '--version', help='Version number', action='version',
+ version='xasy v{0}'.format(xasyVersion.xasyVersion))
+ parser.add_argument('-l', '--language', help='language')
+ parser.add_argument('-x', '--mag', help='Magnification. Defaults to 1', default=1, type=float)
+
+ parser.add_argument(
+ 'filename', help='Filename to load. If empty, initializes empty xasy canvas.', nargs='?', default=None)
+
+ return parser.parse_args()
+
+
+def getArgs():
+ return parseArgs(Qc.QCoreApplication.arguments())
diff --git a/graphics/asymptote/GUI/xasyBezierInterface.py b/graphics/asymptote/GUI/xasyBezierInterface.py
new file mode 100644
index 0000000000..0a5c689bff
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyBezierInterface.py
@@ -0,0 +1,375 @@
+#!/usr/bin/env python3
+
+import xasy2asy as x2a
+import xasyUtils as xu
+
+import PyQt5.QtCore as Qc
+import PyQt5.QtGui as Qg
+import PyQt5.QtWidgets as Qw
+
+import Widg_editBezier as Web
+
+import InplaceAddObj
+
+import math
+
+class CurrentlySelctedType:
+ none = -1
+ node = 0
+ ctrlPoint = 1
+
+class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
+ editAccepted = Qc.pyqtSignal()
+ editRejected = Qc.pyqtSignal()
+
+ def __init__(self, parent: Qc.QObject, obj: x2a.xasyDrawnItem, info: dict={}):
+ super().__init__(parent)
+ self.info = info
+ self.asyPathBackup = x2a.asyPath.fromPath(obj.path)
+ self.asyPath = obj.path
+ self.curveMode = self.asyPath.containsCurve
+ assert isinstance(self.asyPath, x2a.asyPath)
+ self.transf = obj.transfKeymap[obj.transfKey][0]
+ self._active = True
+
+ self.currentSelMode = None
+ # (Node index, Node subindex for )
+ self.currentSelIndex = (None, 0)
+
+ self.nodeSelRects = []
+ self.ctrlSelRects = []
+
+ self.setSelectionBoundaries()
+
+ self.lastSelPoint = None
+ self.preCtrlOffset = None
+ self.postCtrlOffset = None
+ self.inTransformMode = False
+
+ self.opt = None
+
+ self.prosectiveNodes = []
+ self.prospectiveCtrlPts = []
+
+ def setSelectionBoundaries(self):
+ self.nodeSelRects = self.handleNodeSelectionBounds()
+
+ if self.curveMode:
+ self.ctrlSelRects = self.handleCtrlSelectionBoundaries()
+
+ def handleNodeSelectionBounds(self):
+ nodeSelectionBoundaries = []
+
+ for node in self.asyPath.nodeSet:
+ if node == 'cycle':
+ nodeSelectionBoundaries.append(None)
+ continue
+
+ selEpsilon = 6/self.info['magnification']
+ newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
+ x, y = self.transf * node
+ x = int(round(x))
+ y = int(round(y))
+ newRect.moveCenter(Qc.QPoint(x, y))
+
+ nodeSelectionBoundaries.append(newRect)
+
+ return nodeSelectionBoundaries
+
+ def handleCtrlSelectionBoundaries(self):
+ ctrlPointSelBoundaries = []
+
+ for nodes in self.asyPath.controlSet:
+ nodea, nodeb = nodes
+
+ selEpsilon = 6/self.info['magnification']
+
+ newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
+ newRectb = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
+
+ x, y = self.transf * nodea
+ x2, y2 = self.transf * nodeb
+
+ x = int(round(x))
+ y = int(round(y))
+
+ x2 = int(round(x2))
+ y2 = int(round(y2))
+
+ newRect.moveCenter(Qc.QPoint(x, y))
+ newRectb.moveCenter(Qc.QPoint(x2, y2))
+
+ ctrlPointSelBoundaries.append((newRect, newRectb))
+
+ return ctrlPointSelBoundaries
+
+ def postDrawPreview(self, canvas: Qg.QPainter):
+ assert canvas.isActive()
+
+ dashedPen = Qg.QPen(Qc.Qt.DashLine)
+ dashedPen.setWidthF(1/self.info['magnification'])
+ # draw the base points
+ canvas.save()
+ canvas.setWorldTransform(self.transf.toQTransform(), True)
+
+ epsilonSize = 6/self.info['magnification']
+
+ if self.info['autoRecompute'] or not self.curveMode:
+ ctrlPtsColor = 'gray'
+ else:
+ ctrlPtsColor = 'red'
+
+ canvas.setPen(dashedPen)
+
+ canvas.drawPath(self.asyPath.toQPainterPath())
+
+ nodePen = Qg.QPen(Qg.QColor('blue'))
+ nodePen.setWidthF(1/self.info['magnification'])
+
+ ctlPtsPen = Qg.QPen(Qg.QColor(ctrlPtsColor))
+ ctlPtsPen.setWidthF(1/self.info['magnification'])
+
+ for index in range(len(self.asyPath.nodeSet)):
+ point = self.asyPath.nodeSet[index]
+
+ if point != 'cycle':
+ basePoint = Qc.QPointF(point[0], point[1])
+ canvas.setPen(nodePen)
+ canvas.drawEllipse(basePoint, epsilonSize, epsilonSize)
+ else:
+ point = self.asyPath.nodeSet[0]
+ basePoint = Qc.QPointF(point[0], point[1])
+ if self.curveMode:
+ if index != 0:
+ canvas.setPen(ctlPtsPen)
+ postCtrolSet = self.asyPath.controlSet[index - 1][1]
+ postCtrlPoint = Qc.QPointF(postCtrolSet[0], postCtrolSet[1])
+ canvas.drawEllipse(postCtrlPoint, epsilonSize, epsilonSize)
+
+ canvas.setPen(dashedPen)
+ canvas.drawLine(basePoint, postCtrlPoint)
+
+ if index != len(self.asyPath.nodeSet) - 1:
+ canvas.setPen(ctlPtsPen)
+ preCtrlSet = self.asyPath.controlSet[index][0]
+ preCtrlPoint = Qc.QPointF(preCtrlSet[0], preCtrlSet[1])
+ canvas.drawEllipse(preCtrlPoint, epsilonSize, epsilonSize)
+
+ canvas.setPen(dashedPen)
+ canvas.drawLine(basePoint, preCtrlPoint)
+
+ canvas.restore()
+
+ def getPreAndPostCtrlPts(self, index):
+ isCycle = self.asyPath.nodeSet[-1] == 'cycle'
+
+ if index == 0 and not isCycle:
+ preCtrl = None
+ else:
+ preCtrl = self.asyPath.controlSet[index - 1][1]
+
+ if index == len(self.asyPath.nodeSet) - 1 and not isCycle:
+ postCtrl = None
+ else:
+ postCtrl = self.asyPath.controlSet[index % (len(self.asyPath.nodeSet) - 1)][0]
+
+ return preCtrl, postCtrl
+
+ def findLinkingNode(self, index, subindex):
+ """index and subindex are of the control points list."""
+ if subindex == 0:
+ return index
+ else:
+ if self.asyPath.nodeSet[index + 1] == 'cycle':
+ return 0
+ else:
+ return index + 1
+
+ def resetObj(self):
+ self.asyPath.setInfo(self.asyPathBackup)
+ self.setSelectionBoundaries()
+
+ def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ self.lastSelPoint = pos
+ if self.inTransformMode:
+ return
+
+ if self.prosectiveNodes and not self.inTransformMode:
+ self.currentSelMode = CurrentlySelctedType.node
+ self.currentSelIndex = (self.prosectiveNodes[0], 0)
+ self.inTransformMode = True
+ self.parentNodeIndex = self.currentSelIndex[0]
+ elif self.prospectiveCtrlPts and not self.inTransformMode:
+ self.currentSelMode = CurrentlySelctedType.ctrlPoint
+ self.currentSelIndex = self.prospectiveCtrlPts[0]
+ self.inTransformMode = True
+ self.parentNodeIndex = self.findLinkingNode(*self.currentSelIndex)
+
+ if self.inTransformMode:
+ parentNode = self.asyPath.nodeSet[self.parentNodeIndex]
+
+ # find the offset of each control point to the node
+ if not self.curveMode:
+ return
+
+ preCtrl, postCtrl = self.getPreAndPostCtrlPts(self.parentNodeIndex)
+
+ if parentNode == 'cycle':
+ parentNode = self.asyPath.nodeSet[0]
+ self.parentNodeIndex = 0
+
+ if preCtrl is not None:
+ self.preCtrlOffset = xu.funcOnList(
+ preCtrl, parentNode, lambda a, b: a - b)
+ else:
+ self.preCtrlOffset = None
+
+ if postCtrl is not None:
+ self.postCtrlOffset = xu.funcOnList(
+ postCtrl, parentNode, lambda a, b: a - b)
+ else:
+ self.postCtrlOffset = None
+
+ def mouseMove(self, pos, event: Qg.QMouseEvent):
+ if self.currentSelMode is None and not self.inTransformMode:
+ # in this case, search for prosective nodes.
+ prospectiveNodes = []
+ prospectiveCtrlpts = []
+
+ for i in range(len(self.nodeSelRects)):
+ rect = self.nodeSelRects[i]
+ if rect is None:
+ continue
+ if rect.contains(pos):
+ prospectiveNodes.append(i)
+
+ self.prosectiveNodes = prospectiveNodes
+
+ if not self.info['autoRecompute'] and self.curveMode:
+ for i in range(len(self.ctrlSelRects)):
+ recta, rectb = self.ctrlSelRects[i]
+
+ if recta.contains(pos):
+ prospectiveCtrlpts.append((i, 0))
+
+ if rectb.contains(pos):
+ prospectiveCtrlpts.append((i, 1))
+
+ self.prospectiveCtrlPts = prospectiveCtrlpts
+ else:
+ self.prospectiveCtrlPts = []
+
+
+ if self.inTransformMode:
+ index, subindex = self.currentSelIndex
+ deltaPos = pos - self.lastSelPoint
+ newNode = (pos.x(), pos.y())
+ if self.currentSelMode == CurrentlySelctedType.node:
+ # static throughout the moving
+ if self.asyPath.nodeSet[index] == 'cycle':
+ return
+
+ self.asyPath.setNode(index, newNode)
+ # if also move node:
+
+ if self.curveMode:
+ checkPre, checkPost = self.getPreAndPostCtrlPts(index)
+
+ if 1 == 1: # TODO: Replace this with an option to also move control pts.
+ if checkPre is not None:
+ self.asyPath.controlSet[index - 1][1] = xu.funcOnList(
+ newNode, self.preCtrlOffset, lambda a, b: a + b
+ )
+ if checkPost is not None:
+ self.asyPath.controlSet[index][0] = xu.funcOnList(
+ newNode, self.postCtrlOffset, lambda a, b: a + b
+ )
+
+ if self.info['autoRecompute']:
+ self.quickRecalculateCtrls()
+
+
+ elif self.currentSelMode == CurrentlySelctedType.ctrlPoint and self.curveMode:
+ self.asyPath.controlSet[index][subindex] = newNode
+ parentNode = self.asyPath.nodeSet[self.parentNodeIndex]
+
+ if parentNode == 'cycle':
+ parentNode = self.asyPath.nodeSet[0]
+ isCycle = True
+ else:
+ isCycle = False
+
+ if self.parentNodeIndex == 0 and self.asyPath.nodeSet[-1] == 'cycle':
+ isCycle = True
+
+ rawNewNode = xu.funcOnList(newNode, parentNode, lambda a, b: a - b)
+ rawAngle = math.atan2(rawNewNode[1], rawNewNode[0])
+ newNorm = xu.twonorm(rawNewNode)
+
+
+ if self.info['editBezierlockMode'] >= Web.LockMode.angleLock:
+ otherIndex = 1 - subindex # 1 if 0, 0 otherwise.
+ if otherIndex == 0:
+ if index < (len(self.asyPath.controlSet) - 1) or isCycle:
+ newIndex = 0 if isCycle else index + 1
+
+ oldOtherCtrlPnt = xu.funcOnList(
+ self.asyPath.controlSet[newIndex][0], parentNode, lambda a, b: a - b)
+
+ if self.info['editBezierlockMode'] >= Web.LockMode.angleAndScaleLock:
+ rawNorm = newNorm
+ else:
+ rawNorm = xu.twonorm(oldOtherCtrlPnt)
+
+ newPnt = (rawNorm * math.cos(rawAngle + math.pi),
+ rawNorm * math.sin(rawAngle + math.pi))
+
+ self.asyPath.controlSet[newIndex][0] = xu.funcOnList(
+ newPnt, parentNode, lambda a, b: a + b)
+ else:
+ if index > 0 or isCycle:
+ newIndex = -1 if isCycle else index - 1
+ oldOtherCtrlPnt = xu.funcOnList(
+ self.asyPath.controlSet[newIndex][1], parentNode, lambda a, b: a - b)
+
+ if self.info['editBezierlockMode'] >= Web.LockMode.angleAndScaleLock:
+ rawNorm = newNorm
+ else:
+ rawNorm = xu.twonorm(oldOtherCtrlPnt)
+
+ newPnt = (rawNorm * math.cos(rawAngle + math.pi),
+ rawNorm * math.sin(rawAngle + math.pi))
+ self.asyPath.controlSet[newIndex][1] = xu.funcOnList(
+ newPnt, parentNode, lambda a, b: a + b)
+
+ def recalculateCtrls(self):
+ self.quickRecalculateCtrls()
+ self.setSelectionBoundaries()
+
+ def quickRecalculateCtrls(self):
+ self.asyPath.controlSet.clear()
+ self.asyPath.computeControls()
+
+ def mouseRelease(self):
+ if self.inTransformMode:
+ self.inTransformMode = False
+ self.currentSelMode = None
+
+ self.setSelectionBoundaries()
+
+ def forceFinalize(self):
+ self.objectUpdated.emit()
+
+ def createOptWidget(self, info):
+ self.opt = Web.Widg_editBezier(self.info, self.curveMode)
+ self.opt.ui.btnOk.clicked.connect(self.editAccepted)
+ self.opt.ui.btnCancel.clicked.connect(self.editRejected)
+ self.opt.ui.btnForceRecompute.clicked.connect(self.recalculateCtrls)
+
+ return self.opt
+
+ def getObject(self):
+ pass
+
+ def getXasyObject(self):
+ pass
diff --git a/graphics/asymptote/GUI/xasyFile.py b/graphics/asymptote/GUI/xasyFile.py
new file mode 100755
index 0000000000..eee6d69a85
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyFile.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+###########################################################################
+#
+# xasyFile implements the loading, parsing, and saving of an xasy file.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+############################################################################
+
+from string import *
+import xasy2asy as x2a
+import io
+import re
+
+
+class xasyParseError(Exception):
+ """A parsing error"""
+ pass
+
+
+class xasyFileError(Exception):
+ """An i/o error or other error not related to parsing"""
+ pass
+
+
+def extractTransform(line):
+ """Returns key and the new transform."""
+ # see https://regex101.com/r/6DqkRJ/4 for info
+ mapString = x2a.xasyItem.mapString
+ testMatch = re.match(
+ r'^{0:s}\s*\(\s*\"([^\"]+)\"\s*,\s*\(([-\d, .]+)\)\s*\)'.format(mapString), line.strip())
+ if testMatch is None:
+ mapOnlyMatch = re.match(r'^{0:s}\s*\(\s *\"([^\"]+)\"\s*\)'.format(mapString), line.strip())
+ if mapOnlyMatch is None:
+ return None
+ else:
+ key = mapOnlyMatch.group(1)
+ return key, x2a.identity()
+ else:
+ key = testMatch.group(1)
+ rawStr = testMatch.group(2)
+ rawStrArray = rawStr.split(',')
+
+ if len(rawStrArray) != 6:
+ return None
+ transf = [float(val.strip()) for val in rawStrArray]
+ return key, x2a.asyTransform(transf)
+
+
+def extractTransformsFromFile(fileStr):
+ transfDict = {}
+ maxItemCount = 0
+ with io.StringIO() as rawCode:
+ for line in fileStr.splitlines():
+ test_transf = extractTransform(line.rstrip())
+ if test_transf is None:
+ rawCode.write(line + '\n')
+ else:
+ key, transf = test_transf
+ if key not in transfDict.keys():
+ transfDict[key] = []
+ transfDict[key].append(transf)
+
+ # see https://regex101.com/r/RgeBVc/2 for regex
+
+ testNum = re.match(r'^x(\d+)($|:.*$)', key)
+ if testNum is not None:
+ maxItemCount = max(maxItemCount, int(testNum.group(1)))
+ final_str = rawCode.getvalue()
+ return final_str, transfDict, maxItemCount
+
+
+def saveFile(file, xasyItems, asy2psmap):
+ """Write a list of xasyItems to a file"""
+ for item in xasyItems:
+ file.write(item.getTransformCode(asy2psmap))
+
+ for item in xasyItems:
+ file.write(item.getObjectCode(asy2psmap))
+
+ file.write('size('+str(asy2psmap*x2a.yflip())+'); '+ x2a.xasyItem.resizeComment+'\n')
diff --git a/graphics/asymptote/GUI/xasyOptions.py b/graphics/asymptote/GUI/xasyOptions.py
new file mode 100755
index 0000000000..1923990fae
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyOptions.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+###########################################################################
+#
+# xasyOptions provides a mechanism for storing and restoring a user's
+# preferences.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+###########################################################################
+
+import json
+import sys
+import io
+import os
+import platform
+import shutil
+
+import configs
+
+try:
+ import cson
+except ModuleNotFoundError:
+ cson = None
+
+try:
+ pass
+# import yaml
+except ModuleNotFoundError:
+ yaml = None
+
+class xasyOptions:
+ def defaultOptions(self):
+ if self._defaultOptions is None:
+ f = io.open(self._defaultOptLocation)
+ try:
+ opt = cson.loads(f.read())
+ finally:
+ f.close()
+ self._defaultOptions = opt
+ return self._defaultOptions
+
+ def overrideSettings(self):
+ settingsName = platform.system()
+
+ if settingsName not in self.options:
+ return
+
+ for key in self.options[settingsName]:
+ self.options[key] = self.options[settingsName][key]
+
+
+ def settingsFileLocation(self):
+ folder = os.path.expanduser("~/.asy/")
+
+ searchOrder = ['.cson', '.yaml', '.json', '']
+
+ searchIndex = 0
+ found = False
+ currentFile = ''
+ while searchIndex < len(searchOrder) and not found:
+ currentFile = os.path.join(folder, self.configName + searchOrder[searchIndex])
+ if os.path.isfile(currentFile):
+ found = True
+ searchIndex += 1
+
+ if found:
+ return os.path.normcase(currentFile)
+ else:
+ return os.path.normcase(os.path.join(folder, self.configName + '.cson'))
+
+ def __init__(self, configName, defaultConfigLocation):
+ self.configName = configName
+ self.defaultConfigName = defaultConfigLocation
+
+ self._defaultOptions = None
+ self._defaultOptLocation = os.path.join(defaultConfigLocation)
+
+ self.options = self.defaultOptions()
+ self.load()
+ self.overrideSettings()
+
+ def __getitem__(self, item):
+ return self.options[item]
+
+ def __setitem__(self, key, value):
+ self.options[key] = value
+
+ def load(self):
+ fileName = self.settingsFileLocation()
+ if not os.path.exists(fileName):
+ # make folder
+ thedir = os.path.dirname(fileName)
+ if not os.path.exists(thedir):
+ os.makedirs(thedir)
+ if not os.path.isdir(thedir):
+ raise Exception("Configuration folder path does not point to a folder")
+ self.setDefaults()
+ f = io.open(fileName, 'r')
+ try:
+ ext = os.path.splitext(fileName)[1]
+ if ext == '.cson':
+ if cson is None:
+ raise ModuleNotFoundError
+ newOptions = cson.loads(f.read())
+ elif ext in {'.yml', '.yaml'}:
+ if yaml is None:
+ raise ModuleNotFoundError
+ newOptions = yaml.load(f)
+ else:
+ newOptions = json.loads(f.read())
+ except (IOError, ModuleNotFoundError):
+ self.setDefaults()
+ else:
+ for key in self.options.keys():
+ if key in newOptions:
+ assert isinstance(newOptions[key], type(self.options[key]))
+ else:
+ newOptions[key] = self.options[key]
+ self.options = newOptions
+ finally:
+ f.close()
+
+ def setDefaults(self):
+ self.options = self.defaultOptions()
+ if sys.platform[:3] == 'win': # for windows, wince, win32, etc
+ # setAsyPathFromWindowsRegistry()
+ pass
+ folder = os.path.expanduser("~/.asy/")
+ defaultPath = os.path.join(folder, self.configName + '.cson')
+ shutil.copy2(self._defaultOptLocation, defaultPath)
+
+
+# TODO: Figure out how to merge this back.
+"""
+def setAsyPathFromWindowsRegistry():
+ if os.name == 'nt':
+ import _winreg as registry
+ # test both registry locations
+ try:
+ key = registry.OpenKey(registry.HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Asymptote")
+ options['asyPath'] = registry.QueryValueEx(key, "Path")[0] + "\\asy.exe"
+ registry.CloseKey(key)
+ except:
+ key = registry.OpenKey(registry.HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Asymptote")
+ options['asyPath'] = registry.QueryValueEx(key, "InstallLocation")[0] + "\\asy.exe"
+ registry.CloseKey(key)
+"""
+
+
+class BasicConfigs:
+ _configPath = list(configs.__path__)[0]
+ defaultOpt = xasyOptions(
+ 'xasyconfig', os.path.join(_configPath, 'xasyconfig.cson'))
+ keymaps = xasyOptions('xasykeymap', os.path.join(
+ _configPath, 'xasykeymap.cson'))
diff --git a/graphics/asymptote/GUI/xasyStrings.py b/graphics/asymptote/GUI/xasyStrings.py
new file mode 100644
index 0000000000..53f83a64f1
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyStrings.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+
+import gettext
+
+p = property
+
+class xasyString:
+ def __init__(self, lang=None):
+ s = self
+ if lang is None:
+ _ = lambda x: x
+ else:
+ lng = gettext.translation('base', localedir='GUI/locale', languages=[lang])
+ lng.install()
+ _ = lng.gettext
+
+ s.rotate = _('Rotate')
+ s.scale = _('Scale')
+ s.translate = _('Translate')
+
+ s.fileOpenFailed = _('File Opening Failed.')
+ s.fileOpenFailedText = _('File could not be opened.')
+ s.asyfyComplete = _('Ready.')
diff --git a/graphics/asymptote/GUI/xasySvg.py b/graphics/asymptote/GUI/xasySvg.py
new file mode 100644
index 0000000000..a5325f9bdd
--- /dev/null
+++ b/graphics/asymptote/GUI/xasySvg.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+
+import PyQt5.QtGui as Qg
+import PyQt5.QtWidgets as Qw
+import io
+import subprocess
+import sys
+
+class SvgObject():
+ def __init__(self, file: str):
+ self.file=file
+
+ def render(self, dpi:int) -> Qg.QImage:
+ try:
+ rawDataProc = subprocess.Popen(['rsvg-convert', '--dpi-x', str(dpi),
+ '--dpi-y', str(dpi), self.file],
+ stdout=subprocess.PIPE)
+ except:
+ Qw.QMessageBox.about(None,'rsvg-convert missing','Please install rsvg-convert version >= 2.40 in your path.')
+ sys.exit(-1)
+
+ return Qg.QImage.fromData(rawDataProc.stdout.read(), 'PNG')
diff --git a/graphics/asymptote/GUI/xasyTransform.py b/graphics/asymptote/GUI/xasyTransform.py
new file mode 100644
index 0000000000..928e9011f0
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyTransform.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+import xasy2asy as x2a
+import PyQt5.QtGui as Qg
+import PyQt5.QtCore as Qc
+import numpy as np
+import math
+
+
+class xasyTransform:
+ @classmethod
+ def makeRotTransform(cls, theta, origin):
+ if isinstance(origin, Qc.QPointF) or isinstance(origin, Qc.QPoint):
+ origin = (origin.x(), origin.y())
+ rotMat = (math.cos(theta), -math.sin(theta), math.sin(theta), math.cos(theta))
+ shift = x2a.asyTransform((0, 0, 1 - rotMat[0], -rotMat[1], -rotMat[2], 1 - rotMat[3])) * origin
+ return x2a.asyTransform((shift[0], shift[1], rotMat[0], rotMat[1], rotMat[2], rotMat[3]))
+
+ @classmethod
+ def makeScaleTransform(cls, sx, sy, origin):
+ if isinstance(origin, Qc.QPointF) or isinstance(origin, Qc.QPoint):
+ origin = (origin.x(), origin.y())
+ shiftMat = x2a.asyTransform((0, 0, 1 - sx, 0, 0, 1 - sy)) * origin
+ return x2a.asyTransform((shiftMat[0], shiftMat[1], sx, 0, 0, sy))
+
diff --git a/graphics/asymptote/GUI/xasyUtils.py b/graphics/asymptote/GUI/xasyUtils.py
new file mode 100644
index 0000000000..255e8b6add
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyUtils.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+
+import re
+import typing as ty
+import math
+import itertools
+
+def tuple2StrWOspaces(val: tuple) -> str:
+ newStr = ','.join(['{:.6g}'.format(value) for value in val])
+ return '({0})'.format(newStr)
+
+def tryParse(val, typ=float):
+ try:
+ return typ(val)
+ except ValueError:
+ return None
+
+def funcOnList(list1: ty.Union[ty.List, ty.Tuple], list2: ty.Union[ty.List, ty.Tuple], func: ty.Callable) -> tuple:
+ """Returns [f(x[i], y[i]) : i in 1, ..., n - 1] in order with f as func
+ and x and y as list1 and 2. """
+
+ assert len(list1) == len(list2)
+ return tuple([func(list1[i], list2[i]) for i in range(len(list1))])
+
+
+def listize(str, typ, delim='()') -> list:
+ str = str.strip(delim)
+ raw_elem = str.split(',')
+ final_list = []
+ if isinstance(typ, (list, tuple)):
+ for i in range(len(raw_elem)):
+ if i < len(typ):
+ curr_typ = typ[i]
+ else:
+ curr_typ = typ[-1]
+ final_list.append(curr_typ(raw_elem[i].strip()))
+ else:
+ for elem in raw_elem:
+ final_list.append(typ(elem.strip()))
+ return final_list
+
+def twonorm(vec: ty.Iterable[ty.Union[float, int]]) -> float:
+ rawSquared = sum(map(lambda x: x*x, vec))
+ return math.sqrt(rawSquared)
+
+def tryParseKey(raw_key):
+ """Returns None if raw key is not in #.# format"""
+ # See https://regex101.com/r/6G9MZD/1/
+ # for the regex data
+ return re.fullmatch(r'^(\d+)\.(\d+)$', raw_key)
diff --git a/graphics/asymptote/GUI/xasyValidator.py b/graphics/asymptote/GUI/xasyValidator.py
new file mode 100644
index 0000000000..264e105441
--- /dev/null
+++ b/graphics/asymptote/GUI/xasyValidator.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+def validateFloat(text):
+ try:
+ float(text)
+ return True
+ except ValueError:
+ return False
+
+
+if __name__ == '__main__':
+ assert validateFloat('0.5')
+ assert not validateFloat('.-')
diff --git a/graphics/asymptote/INSTALL b/graphics/asymptote/INSTALL
new file mode 100644
index 0000000000..ae5e3394b9
--- /dev/null
+++ b/graphics/asymptote/INSTALL
@@ -0,0 +1,275 @@
+Compiling Asymptote from a Source Release
+=========================================
+
+To compile and install Asymptote version x.xx from a source release:
+
+gunzip asymptote-x.xx.src.tgz
+tar -xf asymptote-x.xx.src.tar
+cd asymptote-x.xx
+./configure
+make all
+make install
+
+The last command requires root privileges. To install without root privileges
+you should change the first line to
+
+./configure --prefix=$HOME/asymptote
+
+If you get errors from a broken texinfo or pdftex installation, simply put
+http://asymptote.sourceforge.net/asymptote.pdf
+in the doc directory and repeat the commands make all and make install.
+
+For a list of configure options, type
+
+configure --help
+
+See also the generic configure instructions below.
+
+Compiling Asymptote from Git Developmental Source Code
+=============================================================
+
+To compile from Git developmental source code:
+
+git clone http://github.com/vectorgraphics/asymptote
+cd asymptote
+./autogen.sh
+./configure
+make all
+make install
+
+Optional packages:
+
+* Fast Fourier Transform library
+ http://www.fftw.org/
+
+ Version requirement >= 3.0
+
+* The GNU Scientific Library for numerical analysis:
+ http://www.gnu.org/software/gsl/
+
+*****************************************
+Generic Configure Instructions (advanced)
+*****************************************
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other options. Run
+`configure --help' for more details.
+
diff --git a/graphics/asymptote/LICENSE b/graphics/asymptote/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/graphics/asymptote/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/graphics/asymptote/LICENSE.LESSER b/graphics/asymptote/LICENSE.LESSER
new file mode 100644
index 0000000000..fc8a5de7ed
--- /dev/null
+++ b/graphics/asymptote/LICENSE.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/graphics/asymptote/Makefile.in b/graphics/asymptote/Makefile.in
new file mode 100644
index 0000000000..5728027c2d
--- /dev/null
+++ b/graphics/asymptote/Makefile.in
@@ -0,0 +1,383 @@
+# @configure_input@
+
+ARCH = unix
+POLL = poll
+
+GCVERSION = @GCVERSION@
+GC = gc-$(GCVERSION)
+LIBATOMIC = libatomic_ops-@ATOMICVERSION@
+GCOPTIONS = @GCOPTIONS@
+GCLIB = @GCLIB@
+GCPPLIB = @GCPPLIB@
+GCLIBS = $(GCPPLIB) $(GCLIB)
+LFLAGS = @LDFLAGS@
+LIBS = $(LFLAGS) @PTHREAD_LIBS@ @LIBS@ $(GCLIBS)
+DOSLIBS = $(subst -lncurses, -ltermcap, $(LIBS)) -lgdi32 -lwinmm -s -static
+
+PERL = perl
+
+# Libraries needed to make asymptote.so.
+# We have to remove OpenGL, threading, GC, etc from this.
+SHAREDLIBS = $(filter-out -lglut -GL -pthread $(GCLIBS), $(LIBS))
+
+vpath %.cc prc
+vpath %.ui GUI/windows
+vpath %.py GUI/pyUIClass
+
+CAMP = camperror path drawpath drawlabel picture psfile texfile util settings \
+ guide flatguide knot drawfill path3 drawpath3 drawsurface \
+ beziercurve bezierpatch pen pipestream
+
+RUNTIME_FILES = runtime runbacktrace runpicture runlabel runhistory runarray \
+ runfile runsystem runpair runtriple runpath runpath3d runstring \
+ runmath
+
+# Files to be scanned for pre-translated symbols defined by SYM(name).
+SYMBOL_FILES = types builtin gsl $(RUNTIME_FILES)
+
+PRC = PRCbitStream oPRCFile PRCdouble writePRC
+
+COREFILES = $(CAMP) $(SYMBOL_FILES) env genv stm dec errormsg \
+ callable name symbol entry exp newexp stack camp.tab lex.yy \
+ access virtualfieldaccess absyn record interact fileio \
+ fftw++asy simpson coder coenv impdatum \
+ @getopt@ locate parser program application varinit fundec refaccess \
+ envcompleter process constructor array Delaunay predicates \
+ $(PRC) glrender tr arcball algebra3 quaternion shaders
+
+FILES = $(COREFILES) main
+
+SYMBOLSH = opsymbols.h allsymbols.h $(SYMBOL_FILES:=.symbols.h)
+UIFILES = $(wildcard GUI/windows/*.ui)
+PYFILES = $(wildcard GUI/pyUIClass/*.py) GUI/icons_rc.py
+DIST = camp.tab.h camp.tab.cc lex.yy.cc runtime.cc keywords.cc \
+ asy-keywords.el $(RUNTIME_FILES:=.cc) $(RUNTIME_FILES:=.h) asy.list \
+ $(SYMBOLSH) $(PYFILES)
+NAME = asy
+XNAME = x$(NAME)
+CLEAN = camp.output base/version.asy doc/version.texi \
+ GUI/xasyVersion.py $(XNAME) doc/asy-latex.pdf $(SYMBOLSH)
+EXTRA = asy-mode.el asy-init.el asy.vim asy_filetype.vim asy-kate.sh \
+ asymptote.py reload.js nopapersize.ps
+EXEXTRA = piicon.eps *.views *.dat *.bib
+DOCEXTRA = *.asy *.csv *.dat latexusage.tex externalprc.tex pixel.pdf
+KEYWORDS = base $(ASYMPTOTE_SITEDIR)
+LATEXFILES = asymptote.sty asycolors.sty ocg.sty latexmkrc
+CONTEXTFILES = colo-asy.tex
+ASY = ./asy -dir base -config "" -render=0
+
+DEFS = @DEFS@ @OPTIONS@ @PTHREAD_CFLAGS@ -DFFTWPP_SINGLE_THREAD
+CFLAGS = @CFLAGS@
+OPTS = $(DEFS) @CPPFLAGS@ @CXXFLAGS@ $(CFLAGS)
+GLEWOPTS = $(DEFS) @CPPFLAGS@ $(CFLAGS) -D GLEW_NO_GLU
+
+# Options for compiling the object files for the shared library.
+# gc has to be configured with the option --disable-threads in order to make a
+# shared library that doesn't seg fault. For now, just disable gc in the
+# shared library.
+SHAREDOPTS = $(filter-out -DUSEGC, $(OPTS)) -fPIC -DFOR_SHARED
+
+CXX = @CXX@ -Wall
+CC = @CC@ -Wall
+MAKEDEPEND = $(OPTS) -O0 -M -DDEPEND
+BISON ?= bison
+PYRCC ?= pyrcc5
+PYUIC ?= pyuic5
+LEX = @LEX@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+bindir = $(DESTDIR)@bindir@
+mandir = $(DESTDIR)@mandir@
+infodir = $(DESTDIR)@infodir@
+datadir = $(DESTDIR)@datadir@
+asydir = $(datadir)/asymptote
+GUIdir = $(asydir)/GUI
+shaderdir = $(asydir)/shaders
+docdir = $(DESTDIR)@docdir@
+exampledir = $(docdir)/examples
+animationsdir = $(exampledir)/animations
+latexdir = $(DESTDIR)@latexdir@
+contextdir = $(DESTDIR)@contextdir@
+INSTALL = @INSTALL@
+REVISION = "const char *REVISION="
+last = $(shell cat revision.cc | sed -e 's/.*\"\(.*\)\";/\1/')
+usinggit = $(shell if test -d ".git"; then echo yes; fi)
+ifeq ($(usinggit),yes)
+ revision = $(shell LC_ALL="C" git describe --long | sed -e 's/git//' \
+ | sed -e 's/-g.*//')
+else
+ revision = @VERSION@
+endif
+
+export prefix docdir exampledir mandir infodir INSTALL MAKE DESTDIR TEXI2DVI
+
+asy: version glew.o
+ if test -n "$(MSDOS)"; then \
+ $(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) revision.o asy.o $(DOSLIBS); \
+ else \
+ ln -sf GUI/xasy.py $(XNAME); \
+ $(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) revision.o $(LIBS); \
+ fi
+
+version: $(GCLIB) $(FILES:=.o) $(notdir $(UIFILES:.ui=.py)) GUI/icons_rc.py
+ if test ! -s revision.cc -o "$(revision)" != "$(last)"; then \
+ echo $(REVISION)\"$(revision)\"\; > revision.cc; \
+ fi
+ $(CXX) $(OPTS) -o revision.o -c revision.cc;
+
+ echo string VERSION=\"$(revision)\"\; > base/version.asy
+ echo @set VERSION $(revision) > doc/version.texi
+ echo @set Datadir @datadir@ >> doc/version.texi
+
+ echo "#!/usr/bin/env python3" > GUI/xasyVersion.py
+ echo xasyVersion = \"$(revision)\" >> GUI/xasyVersion.py
+
+ if test -n "$(MSDOS)"; then \
+ cat asy.rc | sed -e "s/ASYMPTOTE_VERSION/$(revision)/" | \
+ windres -o asy.o; \
+ fi
+
+asymptote.so: $(COREFILES:=.pic.o)
+ $(CXX) $(OPTS) -shared -o asymptote.so revision.o $(COREFILES:=.pic.o) $(SHAREDLIBS)
+
+all: asy sty man faq asy-keywords.el
+
+$(GCLIB): $(GC).tar.gz
+ gunzip -c $(GC).tar.gz > $(GC).tar
+ tar -xf $(GC).tar
+ rm -f $(GC).tar
+ if test -r $(LIBATOMIC).tar.gz; then \
+ gunzip -c $(LIBATOMIC).tar.gz > $(LIBATOMIC).tar; \
+ tar -xf $(LIBATOMIC).tar; \
+ rm -f $(LIBATOMIC).tar; \
+ mv $(LIBATOMIC) $(GC)/libatomic_ops; \
+ fi
+ if test "$(GC)" = "gc-7.0"; then \
+ cd $(GC)/include/private && \
+ patch < ../../../patches/gc-7.0nomem.patch; \
+ fi
+ if test "$(GC)" = "gc-7.2b"; then \
+ mv gc-7.2 gc-7.2b; \
+ fi
+ if test "$(GC)" = "gc-7.2c"; then \
+ mv gc-7.2 gc-7.2c; \
+ fi
+ if test "$(GC)" = "gc-7.2d"; then \
+ mv gc-7.2 gc-7.2d; \
+ fi
+ cd $(GC) && \
+ ./configure CC="$(CC)" CXX="$(CXX)" $(GCOPTIONS); \
+ $(MAKE) check
+
+$(GCPPLIB): $(GCLIB)
+
+sty:
+ cd doc && $(MAKE) asy-latex.pdf
+
+dvi: asy sty
+ cd doc && $(MAKE) dvi
+
+html: asy sty
+ cd doc && $(MAKE) doc
+
+man: asy sty
+ cd doc && $(MAKE) man
+
+faq: asy sty
+ cd doc && $(MAKE) faq
+
+$(RUNTIME_FILES:=.cc): %.cc: runtime.pl opsymbols.h runtimebase.in %.in
+ $(PERL) ./runtime.pl $(@:.cc=)
+
+$(SYMBOL_FILES:=.symbols.h): %.symbols.h: findsym.pl %.cc
+ $(CXX) -E -DNOSYM $(OPTS) $(@:.symbols.h=.cc) | \
+ $(PERL) ./findsym.pl $@ -
+
+$(SYMBOL_FILES:=.o): %.o: %.symbols.h
+
+allsymbols.h: findsym.pl $(SYMBOL_FILES:=.cc)
+ $(CXX) -E -DNOSYM $(OPTS) $(SYMBOL_FILES:=.cc) | \
+ $(PERL) ./findsym.pl $@ -
+
+symbol.o: $(SYMBOLSH)
+
+GUI/icons_rc.py: GUI/res/icons.qrc
+ -$(PYRCC) GUI/res/icons.qrc -o GUI/icons_rc.py
+
+camp.tab.cc: camp.y
+ $(BISON) -dvt -b camp camp.y && mv camp.tab.c camp.tab.cc
+
+camp.tab.h: camp.tab.cc
+
+lex.yy.cc: camp.l
+ $(LEX) -d -olex.yy.cc camp.l
+
+lex.yy.d: $(GCLIB) lex.yy.cc camp.tab.h
+
+keywords.cc: keywords.pl camp.l process.cc
+ $(PERL) ./keywords.pl
+
+opsymbols.h: opsymbols.pl camp.l
+ $(PERL) ./opsymbols.pl
+
+envcompleter.d: keywords.cc
+
+asy-keywords.el: asy
+ @echo Creating $@;
+ $(ASY) -l > asy.list
+ ls $(addsuffix /*.asy,$(KEYWORDS)) | grep -v plain\* | \
+ grep -v three_\* | grep -v featpost3D | xargs $(ASY) -l >> asy.list
+ $(PERL) ./asy-list.pl asy.list $(revision)
+
+install-notexhash: asy-keywords.el install-asy install-man
+
+install: install-notexhash install-texhash
+
+install-all: install install-html
+
+install-texhash: install-asy
+ -if test -z "$(DESTDIR)"; then \
+ texhash; \
+ fi
+
+install-asy: asy sty
+ ${INSTALL} -d $(bindir) $(asydir) $(exampledir) $(animationsdir)
+ ${INSTALL} -d $(GUIdir) $(GUIdir)/pyUIClass $(GUIdir)/configs \
+ $(GUIdir)/res $(GUIdir)/res/icons $(shaderdir)
+ -${INSTALL} -d $(latexdir)
+ -${INSTALL} -d $(contextdir)
+ ${INSTALL} -p -m 755 $(NAME) $(bindir)
+ ${INSTALL} -p -m 644 base/*.asy $(addprefix base/,$(EXTRA)) \
+ asy-keywords.el $(asydir)
+ ${INSTALL} -p -m 755 GUI/*.py $(GUIdir)
+ ${INSTALL} -p -m 755 base/shaders/*.glsl $(shaderdir)
+ -${INSTALL} -p -m 644 GUI/pyUIClass/*.py $(GUIdir)/pyUIClass
+ ${INSTALL} -p -m 644 GUI/configs/*.cson $(GUIdir)/configs
+ ${INSTALL} -p -m 644 GUI/res/icons.qrc $(GUIdir)/res
+ ${INSTALL} -p -m 644 GUI/res/icons/*.svg $(GUIdir)/res/icons
+ ln -sf @datadir@/asymptote/GUI/xasy.py $(bindir)/$(XNAME)
+ ${INSTALL} -p -m 644 examples/*.asy $(addprefix examples/,$(EXEXTRA)) \
+ doc/extra/*.asy $(addprefix doc/,$(DOCEXTRA)) $(exampledir)
+ ${INSTALL} -p -m 644 examples/animations/*.asy \
+ examples/animations/inlinemovie.tex \
+ examples/animations/inlinemovie3.tex $(animationsdir)
+ -${INSTALL} -p -m 644 $(addprefix doc/,$(LATEXFILES)) $(latexdir)
+ -${INSTALL} -p -m 644 $(addprefix doc/,$(CONTEXTFILES)) $(contextdir)
+
+install-html: html
+ cd doc && $(MAKE) install-all
+
+install-man: man
+ cd doc && $(MAKE) install
+
+install-prebuilt: install-asy
+ cd doc && $(MAKE) install-prebuilt
+
+uninstall: uninstall-all
+
+uninstall-all: uninstall-man uninstall-asy uninstall-docdir
+
+uninstall-asy:
+ -cd $(animationsdir) && rm -f *.asy *.tex
+ -rmdir $(animationsdir)
+ -cd $(exampledir) && rm -f $(EXEXTRA) $(DOCEXTRA)
+ -rmdir $(exampledir)
+ -cd $(GUIdir) && rm -f *.py
+ -rmdir $(GUIdir)
+ -cd $(shaderdir) && rm -f *.glsl
+ -rmdir $(shaderdir)
+ -cd $(asydir) && rm -f asy-keywords.el *.asy $(EXTRA)
+ -rmdir $(asydir)
+ -cd $(latexdir) && rm -f $(LATEXFILES)
+ -rmdir $(latexdir)
+ -cd $(contextdir) && rm -f $(CONTEXTFILES)
+ -rmdir $(contextdir)
+ -cd $(bindir) && rm -f $(NAME) $(XNAME)
+
+uninstall-man:
+ cd doc && $(MAKE) uninstall
+
+uninstall-docdir:
+ -rmdir $(docdir)
+
+clean: FORCE
+ -rm -f asy asymptote.so *.pic.o *.o *.d *mon.out $(CLEAN)
+
+gc-clean: FORCE clean
+ -if test -d $(GC); then \
+ $(MAKE) -C $(GC) clean; \
+ fi
+
+cleaner: FORCE clean
+ -if test -d $(GC); then \
+ rm -rf $(GC); \
+ fi
+ -rm -f Makefile config.h config.log config.status errors.temp
+ cd doc && $(MAKE) clean
+ cd tests && $(MAKE) distclean
+
+distclean: FORCE cleaner
+ cd doc && $(MAKE) distclean
+
+cleanest: FORCE maintainer-clean
+maintainer-clean: FORCE distclean
+ -rm -f configure config.h.in $(DIST)
+ -rm -rf autom4te.cache
+ -rm -rf GUI/pyUIClass
+
+test: asy FORCE
+ ./wce
+ $(MAKE) -C tests
+
+check: test
+
+check-all: asy FORCE
+ ./wce
+ $(MAKE) -C tests all
+
+glew.o: glew.c GL/glew.h
+ if test -n "$(MSDOS)"; then \
+ $(CC) -I. $(GLEWOPTS) -o glew.o -D_WIN32 -D GLEW_BUILD -c glew.c; \
+ else \
+ $(CC) -I. $(GLEWOPTS) -o glew.o -c glew.c; \
+ fi
+
+.SUFFIXES: .c .cc .o .d .ui .py
+%.o: %.cc
+ $(CXX) $(OPTS) -o $@ -c $<
+%.d: %.cc
+ @echo Creating $@; \
+ rm -f $@; \
+ ${CXX} $(MAKEDEPEND) $(MDOPTS) $< > $@.$$$$ 2>/dev/null && \
+ sed 's,\($*\)\.o[ :]*,\1.o \1.pic.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+%.d: %.c
+ @echo Creating $@; \
+ rm -f $@; \
+ ${CC} $(MAKEDEPEND) $(MDOPTS) $< > $@.$$$$ 2>/dev/null && \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+%.py: %.ui
+ mkdir -p GUI/pyUIClass
+ -$(PYUIC) -o GUI/pyUIClass/$(notdir $@) $<
+# Compile for the shared library. OpenGL must be disabled as it causes
+# crashes inside a shared library.
+%.pic.o: %.cc
+ $(CXX) $(SHAREDOPTS) -o $@ -c $<
+
+ifeq (,$(findstring clean,${MAKECMDGOALS}))
+-include $(FILES:=.d)
+endif
+
+FORCE:
+
+configure: configure.ac
+ autoheader && autoconf
+
+Makefile: Makefile.in config.status
+ ./config.status
+
+config.status: configure
+ ./config.status --recheck
diff --git a/graphics/asymptote/Pipfile b/graphics/asymptote/Pipfile
new file mode 100644
index 0000000000..7a9e19a0f6
--- /dev/null
+++ b/graphics/asymptote/Pipfile
@@ -0,0 +1,11 @@
+[[source]]
+url = "https://pypi.org/simple"
+verify_ssl = true
+name = "pypi"
+
+[packages]
+
+[dev-packages]
+
+[requires]
+python_version = "3.6"
diff --git a/graphics/asymptote/README b/graphics/asymptote/README
new file mode 100644
index 0000000000..77e7edfb59
--- /dev/null
+++ b/graphics/asymptote/README
@@ -0,0 +1,66 @@
+ ASYMPTOTE
+ Copyright 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince
+
+Asymptote is a powerful descriptive vector graphics language for technical
+drawing, inspired by MetaPost but with an improved C++-like
+syntax. Asymptote provides for figures the same high-quality level of
+typesetting that LaTeX does for scientific text.
+
+Installation instructions, documentation, binaries, and source code are
+available at:
+
+http://asymptote.sourceforge.net
+
+Bugs/Patches/Feature Requests can be submitted to
+
+https://github.com/vectorgraphics/asymptote/issues
+
+Questions and comments should be sent to the Asymptote Forum:
+
+http://sourceforge.net/p/asymptote/discussion/409349
+
+All source files in the Asymptote project, unless explicitly noted otherwise,
+are released under version 3 (or later) of the GNU Lesser General Public
+License (see the files LICENSE.LESSER and LICENSE in the top-level source
+directory).
+
+========================================================================
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+========================================================================
+
+Note that the MSWindows executable version of Asymptote can only be
+released under the GNU General Public License (GPL) as it is linked against
+the GNU Scientific Library, GNU Readline library, and other GPL
+libraries. This version of Asymptote also ships with the cygwin1.dll libraries
+noted below.
+
+========================================================================
+
+Source code for the x86_64 and i386 3.0.4 cygwin1.dll libraries is
+available under the GPL license:
+https://cygwin.com/snapshots/
+
+Source for various icons is available under the MIT license from
+https://github.com/driftyco/ionicons/archive/v2.0.1.zip
+https://github.com/iconic/open-iconic/archive/master.zip
+under the CC-BY-SA 4.0 license:
+http://www.entypo.com/
+and under a CC license:
+http://www.zondicons.com/zondicons.zip
+
+Uses OpenImageIO, which the source is available at
+https://github.com/OpenImageIO/oiio.
+Copyright 2008-2018 Larry Gritz et al. All Rights Reserved. \ No newline at end of file
diff --git a/graphics/asymptote/ReleaseNotes b/graphics/asymptote/ReleaseNotes
new file mode 100644
index 0000000000..773543ee81
--- /dev/null
+++ b/graphics/asymptote/ReleaseNotes
@@ -0,0 +1,2114 @@
+Release Notes for Version 2.53
+
+A memory leak and antialiasing artifacts in the 3D rendering engine were fixed.
+For PRC content, oblique projections are now converted to orthographic
+projections. Portability issues were addressed.
+
+Release Notes for Version 2.52
+
+Under MacOS X, 3D rendering is supported again, the xasy menubar is
+now visible, and the default PostScript previewer was changed to "open".
+VISUAL, EDITOR, and OS-specific editor overrides are now supported in xasy.
+Obsolete code was removed and spelling mistakes were fixed.
+
+Release Notes for Version 2.51
+
+Portability fixes for FreeBSD x86 and MacOS X were made.
+
+Release Notes for Version 2.50
+
+The Phong-Blinn lighting model was replaced by a physically based rendering
+model; the ambient attribute was removed. Various portability and build issues
+were addressed. OpenGL is supported again for both 32-bit and 64-bit MSWindows.
+
+Release Notes for Version 2.49
+
+Portability issues and numerical precision issues were fixed.
+
+Release Notes for Version 2.48
+
+The OpenGL code was modernized to use GLSL shaders. Transparent
+triangles of different materials are now sorted before drawing.
+The viewport option from the light function was removed.
+A workaround was implemented for the Ghostscript transparency extension
+-dSAFER bug. Bugs in the simplex method were fixed. Experimental
+offscreen rendering is now disabled by default due to NVIDIA conflicts.
+The min, max, minratio, maxratio, and intersection calculations were
+accelerated. A workaround was implemented for broken Intel GPU drivers
+under MSWindows.
+
+Release Notes for Version 2.47
+
+Further shipout and scaling problems were fixed. Unused files were removed.
+Multiple-page documents now produce PS instead of EPS output.
+
+Release Notes for Version 2.46
+
+The pen width is now accounted for in the bbox function. The relative
+alignment of a label to a path now transforms correctly with picture
+rotation. Various shipout issues were fixed. The ghostscript library
+location from the MSWindows registry is now ignored for compatibility
+with TeXLive.
+
+Release Notes for Version 2.45
+
+The xasy graphical front end for Asymptote has been rewritten to
+support code reordering, using Qt5 and scalable vector graphics.
+An uninitialized counter was fixed. A stable=true option was added to sort.
+The restricted simplex method has been replaced by a complete simplex
+solver that handles general size constraints. The rpc library has been
+replaced by the tirpc library. The dvips utility is forced to respect
+EPS requirements again. The system ghostscript library is now used by
+default for dvisvgm. Make clean now removes GSL symbols. The MSWindows
+system path is no longer modified by the installer. A CLZ bug was fixed.
+
+Release Notes for Version 2.44
+
+Floating point exceptions are masked again under CYGWIN, pending strtod bug fix
+(issue #65). Various portability issues were also addressed.
+
+Release Notes for Version 2.43
+
+The real modulo operator was fixed. Vector SVG output is now supported for
+PDF tex engines. Compilation under MacOS X was fixed. Both 32- and 64-bit
+MSWindows binaries are now available.
+
+Release Notes for Version 2.42
+
+Bitreverse and popcount functions were added. An overflow in the modulo
+operator was fixed. An asymmetry in angle(transform t) was fixed so that
+angle(yscale(-1))=0. Missing 3D underline characters were fixed.
+The MSWindows binary is now 64-bit.
+
+Release Notes for Version 2.41
+
+The rendering of Bezier patches was improved. Minor improvements were made
+to perpendicular marks in the geometry package. A perl issue was addressed.
+Two unwanted temporary files are now removed after TeX processing.
+EPS output is now supported with all TeX engines. A workaround was
+implemented for the ImageMagick jpeg black background bug.
+
+Release Notes for Version 2.40
+
+A partial workaround for the OpenGL transparency bug was implemented, by
+presorting transparent triangles of the same material. The examples were
+updated and a segmentation fault was fixed. Multisample detection, surface
+rendering, and crack filling algorithms were fixed. The default compilation
+flags now specify -std=c++11.
+
+Release Notes for Version 2.39
+
+A workaround was implemented for the backwards incompatibility in the
+TeXLive 2016 graphicx package. Empty tick labels in graphs are now avoided.
+A paletteticks NoTicks option was added. Support for lualatex was improved.
+Renderers for Bezier patches and curves more efficient than those
+in the deprecated GLU library were implemented.
+
+Release Notes for Version 2.38
+
+An integer division operator # was added. Control points in xasy are now
+correctly parsed. Longitudinal splitting in the revolution structure of
+the solids module was fixed. Portability fixes were implemented.
+The ncurses library is now only required with --enable-readline.
+A --disable-sigsegv configuration option was added.
+
+Release Notes for Version 2.37
+
+The xasy graphical user interface now runs under both Python 2.7 and Python 3.
+Legacy versions (prior to 9.14) of Ghostscript can be supported by
+assigning settings.epsdriver="epswrite" (or by setting the environment
+variable ASYMPTOTE_EPSDRIVER to epswrite). The quiet flag suppresses
+noninteractive standard output when settings.verbosity <= 1. A progress
+function was added to the plain_strings module. The smoothcontour3 module
+was optimized to use Bezier triangles where appropriate, along with a
+built-in least-squares routine and an improved root finder based on
+quadratic interpolation. If settings.sysdir is empty, preference is given
+to a version of kpsewhich in the same directory as the executable for
+determining the correct sysdir. The handling of degenerate normals of
+Bezier triangles was fixed. Bugs in forking, integer formatting, dash
+adjustment, subpaths, and guide reversion were fixed. Version 1.30 of
+asymptote.sty (auto-generated) and version 0.35 (or later) of media9.sty
+are now required.
+
+Release Notes for Version 2.36
+
+Bezier triangle patches have been implemented in place of degenerate Bezier
+tensor product patches. Surface rendering was improved. The configuration
+of the readline and gc libraries was fixed. The asy configuration
+directory is only created if localhistory=false. Patches are now sorted by
+projected distance. Animations were fixed by running LaTeX twice.
+The asy-mode.el headers were updated. Intermittent segmentation faults and
+floating point exceptions in the OpenGL renderer were fixed. Support for
+GSL 2.0 was added. A quite nan constant was added. Straight segments are no
+longer split in bezulate. Segmentation faults in tab completion were fixed.
+A work around for a clang 3.7.0 compiler bug was implemented.
+The smoothcontour routine was sped up. Several bugs in the file read routines
+were fixed. A bug in rest argument signature equivalence was fixed.
+Threads are no longer used in batch mode, except under MacOS X. A convenience
+function graphicscale was added for using graphic with the conTeXt tex
+engine. The splinetype detection for Spline surfaces was fixed.
+
+Release Notes for Version 2.35
+
+A work around was implemented for a ghostscript eps2write bug that forces
+all postscript to the first page, breaking multiple 3D XeLaTeX and ConTeXt
+labels.
+
+Release Notes for Version 2.34
+
+The readability of named pen colors was improved in the documentation.
+A surface cone(path3 base, triple vertex) routine was added for
+constructing an approximate cone over an arbitrary base. A test for
+Ghostscript 9.14 or later was added to the build process. The documentation
+was updated. A CYGWIN warning message under Windows 8 was fixed.
+
+Release Notes for Version 2.33
+
+A work around was implemented for the missing epswrite driver in
+ghostscript-9.15. Deconstruction is now always done in the C locale.
+A work around for a unit change in dvisvgm-1.5.3 was implemented.
+The path arc(pair B, pair A, pair C, real r) function was fixed.
+The handling of the boolean condition in parametric surfaces was fixed.
+The default meshlight was changed to nolight so that mesh lines with
+positive width appear consistent with the default mesh lines.
+A nonsquare image dimension error was fixed. The definition of the
+SimpleHead arrowhead was fixed. The zoom/menu button and play option were
+fixed. An intersect(path, surface) function was implemented.
+A smoothcontour3 module written by Charles Staats and leminiscate example
+were added. The inline asymptote.sty option now works with xelatex.
+An obsolete workaround for an Adobe Reader transparency artifact
+was removed. An asylatexdir option was added to support the pdflatex
+-output-directory option. An aligndir option for aligning the picture to
+an arbitrary point of the page boundary was added. The garbage collector was
+updated to gc-7.4.2. The documentation was updated.
+
+Release Notes for Version 2.32
+
+The libc++ stringstream workaround was also enabled for FreeBSD.
+The segment(bool[] b) function was fixed. The side(pair,pair,pair) function
+was renamed to orient(pair,pair,pair) and an error in its documentation was
+corrected. New functions orient(triple,triple,triple,triple) and
+insphere(triple,triple,triple,triple,triple) were implemented. A random
+number generator incompatibility on some platforms was fixed. Support was
+removed for the obsolete utility texi2dvi4a2ps. Compiler warnings were
+suppressed.
+
+Release Notes for Version 2.31
+
+Hangs in 3D font generation and also in the "none" tex engine were fixed.
+
+Release Notes for Version 2.30
+
+Compilation issues were addressed. A workaround for the broken stringstream
+container in MacOS 10.9 libc++ was implemented. The OpenGL zoom/menu button
+was fixed.
+
+Release Notes for Version 2.29
+
+The TeX bidirectional pipe was overhauled to support the context tex engine
+again. The luatex and lualatex tex engines were enabled. The inline option
+used by the asymptote.sty LaTeX package and the inlineimage option used for
+generating external PRC files were fixed. Portability issues were addressed.
+
+Release Notes for Version 2.28
+
+A locale bug that interfered with the 3D PRC camera transformation was fixed.
+Minimum OpenGL window constraints were removed in favour of the viewportsize
+variable. The transform(u,v,O) function, which projects onto the plane
+spanned by u and v through point O, was fixed. Numerical overflow issues in
+quadraticroots and cubicroots were fixed. The documentation was updated.
+
+Release Notes for Version 2.27
+
+Move Adobe transparency workaround to C++ code to allow use of texpreamble
+again with the pdflatex tex engine.
+
+Release Notes for Version 2.26
+
+The xasy graphical user interface now terminates the asy process on exit.
+The xasy code editor under MSWindows was fixed; the default code editor is
+now winpad. Degenerate HookHead and SimpleHead arrows were fixed.
+Portability issues were addressed.
+
+Release Notes for Version 2.25
+
+A superfluous play button in rendered 3D images embedded by recent versions of
+media9 is now suppressed. The contour.asy module was reverted to a previous
+stable linearized version. A numerical precision issue in makepen was fixed.
+A routine for drawing braces was added. Deep recursion is now avoided in
+guide flattening. A workaround for an Adobe Reader transparency artifact
+was implemented for the pdflatex and xelatex tex engines. Raw PRC output
+can now be generated with the "-f prc" command-line option. Vector patches
+are now sorted to work around opacity artifacts in many rendering engines.
+The xasy code editor now accepts command-line options. Under MSWindows,
+the ghostscript library is searched for in both the 32 bit and 64 bit
+registries. The FAQ and documentation were updated.
+
+Release Notes for Version 2.24
+
+A segmentation fault in drawSphere was fixed. Recursive calls to simpson
+are now supported. The explicit libglapi dependency was removed.
+A latexmkrc example file that shows how to store figures in a subdirectory
+is now included.
+
+Release Notes for Version 2.23
+
+Compilation without the FFTW library is now supported again.
+
+Release Notes for Version 2.22
+
+Self-defined unary operators are now allowed. Formatted strings instead of
+real values are compared in OmitFormat. The segment(bool[]) function was
+rewritten to use the more efficient segmentlimits(bool[]) call.
+Unnecessary buffering of surface and path3 data was removed.
+Portability tweaks were made. References to out-of-date trembling
+examples were removed. Vertex-colored triangles now work again in Adobe XI.
+The transformation of normal vectors was fixed. PostScript extend
+qualifiers were added for axial and radial shading. The TEXMFMAN
+environment variable is now used to find the TeXLive sysdir.
+
+Release Notes for Version 2.21
+
+Explicitly transformed billboard labels now work correctly again.
+The alignment point of OpenGL billboard labels was fixed. An extend
+parameter was added to the axes (default true) and axes3 (default false)
+routines. A history recall bug was fixed. A typo was corrected in the
+documentation of the Jacobi elliptic functions sncndn.
+
+Release Notes for Version 2.20
+
+A work around was implemented for a dvipdfmx bug that prevents the
+xelatex tex engine from properly embedding PRC objects. Billboard rotation
+is now disabled for explicitly transformed labels.
+
+Release Notes for Version 2.19
+
+Numerical resolution issues with the PRC camera orientation and viewportshift
+were fixed. The lighting of NURBS surfaces was fixed. The special 8192
+strlen NSIS build was now correctly reinstated, with stubs, to prevent the
+installer from overwriting Windows PATH environment variables > 1023 bytes.
+
+Release Notes for Version 2.18
+
+A compilation issue on MacOSX was addressed. Secondary axes pictures now
+inherit the size of the primary picture, so that the markthin marker works
+properly. The special 8192 strlen NSIS build was reinstated to prevent the
+installer from overwriting extremely long Windows PATH environment variables.
+
+Release Notes for Version 2.17
+
+A bug with non-square pen function images was fixed. Autoscaled
+logarithmic axes were fixed. Offscreen and non-offscreen rendering are now
+supported in a single binary (requiring OSMesa version 8), with
+settings.offscreen defaulting to false. The media9 LaTeX style file is now
+used to embed 3D PRC content instead of movie15. Local 3D coordinates are
+now used. PRC Part names are nolonger generated by default. A bug in
+bezulate was fixed. A settings.axes3 flag was added to control the
+visibility of PRC axes. An efficient 3D routine for drawing many
+triangles, with specified vertices and optional normals or vertex colors,
+was implemented.
+
+Release Notes for Version 2.16
+
+Ticks are no longer autoscaled when the number of major intervals is
+specified and autoscale is false. Manual tick scaling was fixed. A bug in
+the palette range was fixed. A division by zero in constructing curved arrows
+was fixed. A numerical underflow was fixed. A picture bound error was
+fixed. The current value of currentpen is now always respected in default
+arguments. A default viewportwidth is no longer imposed for attached
+images. A routine for computing camera positions was added. The format
+command is now more consistent with C++ printf formatting. Named arguments
+can now appear in function calls after rest arguments. The wheel example
+was improved to support PDF animations. The erase command no longer resets
+the machine state. Pipes are now used for xasy communication. A new mode
+parameter to input and output replaces xinput, xoutput, binput, and
+boutput. The icon directory path for 64-bit MSWindows systems was fixed.
+Compilation of native CYGWIN binaries is now supported.
+
+Release Notes for Version 2.15
+
+A compilation problem under MacOS X was fixed.
+
+Release Notes for Version 2.14
+
+Minor problems in the geometry module were fixed. Billboard interaction is
+now disabled for offscreen rendering. A markthin(path) marker with opacity
+thinning was implemented. A locale string was added to format(string,int).
+The copy, map, and sequence functions were generalized to arbitrary depths.
+Asymptote can now be compiled as a shared library. A tuple operator was
+added. The draw(revolution) function now defers drawing until the final
+camera position is known. Nonrendered preview images can now be generated
+for fitted pictures. String reads from binary files were fixed. An int
+ascii(string) function and a bool isnan(real) function were implemented.
+Jacobi elliptic functions were implemented. A quick reference card was added.
+Compilation and static initialization issues under MacOS X Lion were addressed.
+
+Release Notes for Version 2.13
+
+Compilation and installation issues were addressed.
+
+Release Notes for Version 2.12
+
+Minor compilation issues were addressed.
+
+Release Notes for Version 2.11
+
+A new offscreen (software) 3D rendering option supports rendering on
+machines that are remote or lack a working video graphics card.
+Shifted pens now work correctly. The handling of whitespace in word mode
+file reads was fixed. A transpose argument was added to the pen function image
+facility, for consistency with the other image functions. The limit
+calculation of parabola and hyperbola was fixed in the geometry module.
+
+Release Notes for Version 2.10
+
+PRC vertex-shading for straight patches was implemented. A general image
+routine that uses a pen function of two integer parameters was implemented.
+A 3D pixel routine was added. A temporary expression is now used to avoid
+side effects in self operators. Keyword-only function arguments were
+implemented. The sizing routines were recoded. Bugs in drawline and
+geometry were fixed. The geometry module no longer overloads the built-in
+circle and ellipse functions. PDF TeX engines are now supported in xasy.
+Directory prefixes are no longer stripped from .js and .prc file names.
+The TeXShop instructions were updated. The asymptote.sty LaTeX style file
+was updated to allow leading spaces before \end{asy} and to introduce a
+keepAspect keyval option. Segmentation faults were fixed.
+Unwanted state-dependency was removed from the startTrembling function of
+the contributed trembling module by introducing a tremble structure
+(backwards incompatible change); see the example floatingdisk.asy.
+
+Release Notes for Version 2.08
+
+Legend markers now work again.
+
+Release Notes for Version 2.07
+
+The -P option required by ghostscript 9.00 was added. The limits command
+now works correctly with reversed axes. The asyinclude command of
+asymptote.sty was improved so that asy source files do not need to be sent
+to publishers; the asy extension is now optional. A mktemp function was
+implemented. Further MSWindows installer problems were addressed.
+
+Release Notes for Version 2.06
+
+Compilation problems and build issues were fixed.
+
+Release Notes for Version 2.05
+
+Arbitrary depth array constructors were re-instated. Profiling code was
+added. Spaces within file names and eps file attachments are now supported
+in inlinetex mode, and interference from any pre-existing aux file is
+avoided. A new auto-generated version (1.21) of asymptote.sty contributed
+by Will Robertson features a latexmk-compatible asyinclude command.
+Path-overwriting bugs in the NSIS MSWindows installer were circumvented.
+
+Release Notes for Version 2.04
+
+Subdivision cracks in transparent labels are no longer filled.
+Warning messages from the FP package are suppressed. MSDOS line terminators
+are now handled; DOSendl and DOSnewl line terminators were added.
+Files generated in inlinetex mode can now be renamed without editing their
+contents (using asymptote.sty version 1.19). The man page was fixed.
+The documentation of render.merge was fixed.
+
+Release Notes for Version 2.03
+
+An optional asydir parameter that allows asy files to be generated in a
+subdirectory was added to version 1.18 of asymptote.sty; XeLaTeX support was
+fixed. Nonrendered preview images via render=0 are now implemented.
+Blank 3D labels were fixed. Problems with arc directions and ellipses in
+the geometry module were fixed. The definition of the Dotted linetype was
+improved. Missing pen and margin parameters were added to the blockconnector
+function calls. Virtual methods were optimized. Makefile dependencies were
+fixed and autogenerated files are cleaned up. The dependence of the source
+tarball on perl was removed. Minor improvements were made to the
+documentation and man page. The Asymptote installation directory is now
+automatically added to the MSWindows path.
+
+Release Notes for Version 2.02
+
+A global latexusage.asy file is no longer generated, in favour of
+individual latexusage-*.asy files (this is a backwards incompatible
+change). Global and local values can now be given for both the inline and
+attach asymptote.sty (version 1.15) options. Underscores were removed from
+the .pre and .tex file names in inlinetex mode. Latexmk support was added
+for compiling individually only those figures that have changed; this
+requires that the inline option be used for 3D figures.
+The asy() function was fixed. A multiple fraction bar bug in texpath was
+fixed. Warning messages and portability issues were addressed. A frame
+label alignment problem was fixed. PDF animations are now supported with
+the XeLaTeX TeX engine.
+
+Release Notes for Version 2.01
+
+The normal vector for perspective projections was fixed. Individual
+processing of each figure within a LaTeX document is now supported.
+The fontsize package uses type1cm.sty again since fix-cm.sty does not
+appear to work as advertised. Uninitialized item bits are cleared.
+Extended for statements now support the var type. PenMargin is used in
+drawing a binarytree. Minor optimizations were made.
+
+Release Notes for Version 2.00
+
+The construction of 3D TeX labels was sped up greatly. Plain TeX page
+numbers were suppressed. Dotted 3D lines and 3D sizing problems were fixed.
+A general search function for sorted structures was implemented; the
+lexorder functions in math.asy now return strict partial orders. Additional
+GSL functions were added. The correct PRC units (PostScript pt units,
+properly called bp) are now displayed in Adobe Reader.
+
+Release Notes for Version 1.99
+
+A segmentation fault was fixed. Perspective animations were fixed. A bug in
+the bezulate topological sorting algorithm was fixed. A framedelay setting
+was added for working around OpenGL animation rendering buffer overruns.
+Further optimizations were made. A portability issue was addressed.
+
+Release Notes for Version 1.98
+
+Memory usage and garbage collection were greatly improved, and many
+optimizations were made. Labels are now aligned using the rotational instead of
+the shiftless part of the transform. A portable CYGWIN memory limit fix was
+implemented. Noncyclic stokepaths are discarded to work around a bug in gs 8.71.
+
+Release Notes for Version 1.97
+
+A new render.labelfill option (enabled by default) fills subdivision cracks in
+unlighted labels. The dependence on gcc-4.3 was removed. Offscreen detection and
+zoom bugs in the OpenGL renderer were fixed. Three-dimensional grouping was
+improved. The symbol table was replaced with a custom hash table. Portability
+updates were made. The Cygwin memory limit fix for MSWindows now works even on
+systems that lack a complete Cygwin installation. The examples were updated to
+exploit the new PRC rendering options.
+
+Release Notes for Version 1.96
+
+The viewpoint function and some examples were updated.
+
+Release Notes for Version 1.95
+
+The PRC driver has been overhauled to support model tree groups, lossy
+compression, efficient representations of elementary geometrical objects,
+and specialized rendering options. More efficient OpenGL thick tubes were
+implemented; the capping of 3D curves was improved. The SIGQUIT signal was
+replaced by SIGTERM. Under MSWindows, the 384MB Cygwin memory limit is now
+automatically disabled by the Asymptote installer. Inferred variable types
+were added and operator symbols are now pretranslated.
+
+Release Notes for Version 1.94
+
+Workarounds for MSWindows registry problems and obsolete runtime libraries
+were implemented. The SimpleHead arrowhead was fixed. Additional matrix
+routines and casts were implemented. The pair dir(path, path) routine now
+returns a unit vector. Variable conflicts coming from the contour module
+were addressed. A RadialShadeDraw filltype was implemented. A guide bug was
+fixed. Redundant mismatched version warnings are avoided. Support for
+fitting one 3D picture within another was added. The documentation was updated.
+
+Release Notes for Version 1.93
+
+Portability issues were addressed. Latticeshading bounds and behaviour
+under svgemulation were fixed. The initial SVG pen was fixed.
+A parallelogram block was added to the flowchart module.
+Temporary files are cleaned up even after TeX errors. The GUI export
+function was fixed; an SVG export option was added. The XeLaTex bounding
+box was fixed. Spaces in output directory names are now allowed for
+supporting drivers. One can cd to other directories, preserving the output
+directory. All output files are written to the directory part of
+settings.outname; if this is empty, the current directory is used.
+
+Release Notes for Version 1.92
+
+Labels work correctly with oblique projections. Transformed Label
+alignment and pt scalings were fixed. Latticeshading is now properly clipped.
+The normal and true Circle calculations were fixed. The interface to the
+simpson integrator and an array index in contour.asy were fixed. In the
+flowchart module, the implicit cast from a pair to a virtual node was
+removed in favour of a block constructor. The ode integration routines now
+return a structure that includes the sampled time values; dynamic
+timestepping was implemented for solveBVP. New predefined tick modifiers
+were added. The CLZ and CTZ bit functions were implemented. PRC part names
+were fixed. The GL library is now explicitly linked. Memory usage was
+improved by configuring the garbage collector with --enable-large-config.
+Null 3D paths are ignored. Non-pdf output is supported for PDF tex engines.
+Portability changes for CYGWIN 1.7 were made.
+
+Release Notes for Version 1.91
+
+The precision of the 3D perspective sizing routines were improved. The
+offset in transformed 3D labels with render=0 was fixed. 3D planar
+arrowhead gaps were fixed; a duplicate 3D arrow angle factor was removed.
+Pen width contributions to the box and ellipse envelopes were fixed. A more
+robust contour algorithm based on paraboloid approximation was implemented.
+A polargraph routine for arrays was implemented. Default font problems were
+fixed. The pdfborder={0 0 0} option was added to settings.hyperrefOptions;
+the hypersetup command is now used to avoid hyperref option clashes. The
+size of pngalpha images was fixed; the pngalpha driver is used only if
+antialias=2. The -alpha Off default convert option was removed in favour of
+convertOptions="-alpha Off". Inlinetex support for xelatex was updated.
+Picture transformations are now respected by latticeshade. The Bessel
+functions J and Y were renamed to Jn and Yn. An operator --(block, block)
+was implemented to simplify the flowchart syntax. The expression % expands
+to the last result returned at the interactive prompt. The GLU-1.3 library
+included in the MSWindows distribution was fixed.
+
+Release Notes for Version 1.90
+
+SVG axial, radial, and emulated tensor-patch shading were fixed; the
+dependency on dvisvgm-0.8.7 was documented.
+
+Release Notes for Version 1.89
+
+The draw, fill, and clip commands now pass raw SVG code directly to dvisvgm
+(version 0.8.6 required); zero-length paths are output as circles.
+Unsupported SVG elements are converted to PNG images; unimplemented SVG
+features such as Gouraud and tensor-patch shading can be (partially)
+emulated as vector elements using the -svgemulation option.
+The control point normalization of rational NURBS surfaces was fixed;
+3D NURBS curves are now implemented. A problem with inlinemovie3 was fixed.
+The linetype pattern is now a real array: for backwards compatibility, a
+string is still accepted, but the return type of linetype(pen) is now
+real[] instead of string (backwards incompatible). The split routine was
+changed so that an empty delimiter splits on spaces, discarding duplicates.
+The palette routines are now guaranteed to generate at least the
+specified number of colours. PNG output produces a transparent background.
+Surface and path3 garbage collection was fixed.
+
+Release Notes for Version 1.88
+
+Compilation without OpenGL was fixed. PRC billboard labels were
+implemented; settings.billboard was renamed to settings.autobillboard
+and by default enabled for all 3D labels. The surface constructor for
+embedding labels on surfaces now draws both the top and bottom faces by
+default. The meshpen, knot, weight, and color arrays are now properly cached.
+The example fequlogo.asy illustrates how to draw an arbitrary 3D background
+plane. The intermediate dvi file is now removed when producing SVG output.
+Improvements were made to the tutorial.
+
+Release Notes for Version 1.87
+
+Support for SVG output was added (requires dvisvgm-0.8.4). Billboard
+labels were implemented for the OpenGL renderer. OpenGL animations were
+improved: reverse and step menu items were added, along with a framerate
+setting. An addStereoViews function and example stereoscopic.asy were added.
+The addViews function was generalized to handle any layout; the default
+layout was changed from ThreeViewsFR to SixViewsUS. PRC node names are
+now implemented for curves, surface, labels, and dots. OmitTick was
+generalized to omit both major and minor ticks. A graphicx.tex workaround
+was implemented to parse paths properly. A viewportsize bug was fixed.
+A memory deallocation bug was fixed. The ENDIAN test was fixed. The ucyclic
+and vcyclic parameters are no longer set for conditional surfaces. The
+erase() function clears the PostScript canvas again. A projection()
+function that returns the interactive camera parameters was implemented.
+A hyperrefOptions setting was implemented. The tutorial was improved.
+
+Release Notes for Version 1.86
+
+PRC polygons were optimized. Surface memory usage was reduced.
+The automatic sizing of NURBS surfaces was fixed. A bug in the radius of
+curvature computation at nodes was fixed. The configuration test for the
+GNU readline library was improved. The naming of PRC parts was implemented.
+
+Release Notes for Version 1.85
+
+Compilation is now supported again on platforms lacking OpenGL.
+Missing pen dimensions were added to a 3D picture sizing routine.
+The labelsurface routine was renamed to surface and extended to surfaces
+containing a single patch.
+
+Release Notes for Version 1.84
+
+The perspective PRC viewportmargin was fixed. Unwanted spaces were removed
+from (version 1.10 of) asymptote.sty. Support for drawing PRC and OpenGL
+NURBS surfaces was added. Obsolete code, including an unwanted inline
+qualifier, was removed. A split structure that can be adapted for splitting
+intersecting patches was added, along with the example splitpatch.asy.
+
+Release Notes for Version 1.83
+
+OpenGL animations, illustrated in glmovie.asy, were implemented.
+Viewportshift flicker was fixed. An empirical translation between
+OpenGL and PRC shininess was implemented. Splined parametric surfaces are
+now used to implement smooth thick lines and tubes. The projected bounding box
+calculation and angle calculations were fixed. A labelsurface function was
+added. The Headlamp light is now the default light; a light argument was
+added to shipout. Patches are now constructed with the usual orientation
+for a counterclockwise external path; the convention for tensor product
+shading was updated. Picture environments for TeX clipping are no longer
+nested. A texpath initialization bug was fixed. An ASYMPTOTE_HOME
+environment variable was added. Viewing was fixed for file names
+containing spaces. A picture sizing bug was fixed. An example of an inset
+graph was added. Type information for variables is now returned at the
+interactive prompt. Warning message suppression was improved; warnings in
+Asymptote code can now be disabled. The cyclic member of an array is now
+writeable; the obsolete cyclicflag and void cyclic(bool) functions were
+removed. File mode functions are now virtual members; this backwards
+incompatibility requires that line(file f) be changed to f.line(), etc.
+
+Release Notes for Version 1.82
+
+Threaded exports were fixed. The texpath fontsize was fixed for PDF tex engines.
+A default currentprojection argument was added to transform3(projection).
+The -gray and -bw settings are now respected in PRC output.
+A consistent approximation is now used for drawing tube centers.
+Missing pt units were added to all fontsize examples.
+
+Release Notes for Version 1.81
+
+A boolean targetsize option can now be used to draw 3D labels with the apparent
+size they would have on the target plane. The camera adjustment algorithms
+were fixed; the autoadjust flag is respected. Missing path3 functions
+such as endpoint(path3) were added. The doubleclick timeout under MSWindows
+was fixed. A workaround for a ConTeXT small font bug is illustrated in
+contextfonts.asy. File associations are now used under MSWindows for
+psviewer, pdfviewer, display, and animate. Single quotation marks are now
+allowed in filenames. Deconstruction is now only supported in PNG format;
+the xformat setting was removed. The example lmfit illustrates
+Levenberg-Marquardt nonlinear least-squares fitting.
+
+Release Notes for Version 1.80
+
+The interface for changing the precision for XDR/binary files was
+simplified; file parameters can now be queried as virtual members.
+The zoom/menu action was improved to emulate a double-click and assigned again
+to the right mouse button; a left-button binding bug was fixed.
+New settings zoomfactor, zoomstep, spinstep, arcballradius, resizestep, and
+doubleclick were added. The OpenGL thread is now exited gracefully; idle
+state and other parameters are properly reset on quitting. Lighting is now
+initialized only in home(). Animations with global=false were fixed.
+An improved (and free) psview PostScript viewer is now suggested for MSDOS
+users. A mechanism for disabling annoying warnings like "writeoverloaded"
+was implemented. The documentation directory under TeXLive was fixed.
+
+Release Notes for Version 1.79
+
+The perp vector calculation in the solids module was fixed. A bug in the
+mouse motion functions was fixed. A pan action (which differs from shift
+due to perspective distortion) was added to the OpenGl renderer;
+the Camera (c) menu item now outputs all camera settings. The default right
+mouse button mouse binding was changed from "zoom/menu" to "zoom".
+User-initiated exports no longer cause the renderer to quit.
+Dynamic time stepping was fixed in the ode module; the "integrate"
+routines now return the array of computed values. Operators == and != were
+added for all built-in arithmetic 2D arrays; a segmentation fault was
+fixed. The etc/fstab kludge for Cygwin 1.7 was removed. The configuration
+directory under TeXLive is now $TEXMFCONFIG/asymptote.
+
+Release Notes for Version 1.78
+
+Thread locking issues were fixed. The linegranularity is now respected when
+drawing thick curved lines. A bug in FSAL ODE integrators when using a
+fixed time step was fixed. Missing miterlimit defaults were added.
+Xasy was updated to use Python 2.6.2 and Imaging-1.1.7b1 (which requires no
+alpha support patches). Obsolete patches were removed. More TeXLive build
+issues were addressed: the install-prebuilt target omits texhash and does
+not attempt to install PNG files for asymptote.info. A configuration
+problem with --disable-gc was fixed. The 3D mouse bindings are now
+customizable. Support was added for generating syntax highlighting for the KDE
+editor Kate.
+
+Release Notes for Version 1.77
+
+Splined parametric surfaces were implemented; a bug in the Cartesian
+splined surface routines was fixed. An ode module for solving ordinary
+differential equations was added. A bug in maxtimes and mintimes was fixed.
+A Levenberg-Marquardt nonlinear fitting routine was added. The format
+command now returns TeX compatible output only in math mode. A path3 label
+alignment problem was fixed. The MSWindows support for TeXLive 2009 was fixed.
+
+Release Notes for Version 1.76
+
+A bezulate bug was fixed. The resolution and caching of texpath were
+improved; for PDF tex engines, the basealign pen attribute is now
+respected. Support for OCG layers was added. Lights Headlamp and White were
+implemented; the predefined adobe light was removed. Holes are now handled
+in superpath-to-surface constructor when planar=true. A degenerate
+transform3 issue was fixed. The alignment of rendered and PRC images was
+improved; the angle for rendering absolute projections was fixed. Inaccurate
+TeX and ConTeXt font scalings were fixed. A texsize(string, pen=currentpen)
+function returns the raw TeX dimensions {width,height,depth}. A new version
+of asymptote.sty (1.07) fixes attach=true mode.
+
+Release Notes for Version 1.75
+
+Issues with 3D labels and texpath, both in inlinetex mode and with the
+ConTeXt TeX engine, were resolved. A bug in bezulate was fixed. A partial
+workaround was added for the unimplememented -output-directory ConTeXt
+option (the current directory must still be writeable). The aspect ratio
+and viewportmargin calculation in module three was improved, with tighter
+3D bounds. A bug in the intersections(path3, surface) routine was fixed.
+
+Release Notes for Version 1.74
+
+An error in the surface bounding box routines was fixed. Path/surface
+intersection routines were added. PDF tex engines are now supported for
+3D labels and texpath. The new ConTeXT tex engine can be used for both 2D
+and non-PRC 3D drawings. Projections LeftView, RightView, FrontView,
+BackView, BottomView, and TopView, along with an addViews function, were
+implemented. Portability fixes and various updates to support TeXLive
+builds were made. The dependence on currentprojection in label(Label,
+path3) was removed. The font command for LaTeX tex engines now requires all
+four NFSS (encoding, family, series, shape) arguments.
+
+Release Notes for Version 1.73
+
+An alternative OpenGL background color can now be specified with the pen
+currentlight.background. A new textpath command allows 3D labels to be
+drawn with settings.texengine="none". Minor bugs in the geometry package were
+fixed. The interface to the vectorfield routines was improved.
+The autoadjust parameter was removed from orthographic projections;
+autoadjust=false is now always respected for perspective projections.
+Optional warn=true arguments were added to the polar, azimuth, colatitude,
+and latitude functions. A call to reportError interrupts execution again.
+A segmentation fault that can occur after file mode errors was fixed.
+
+Release Notes for Version 1.72
+
+PostScript calculator function shading was implemented. Interactive camera
+parameters of the native OpenGL renderer can now be queried.
+The effective camera positions for oblique projections was fixed.
+Philippe Ivaldi's geometry_dev module was merged into geometry.asy;
+trembling_pi was added as trembling.asy. The GSL module was expanded.
+An extrude routine for labels was implemented. Rotated path
+label alignments were fixed. The alignment of 3D axis labels was fixed.
+The basealign pen now always typesets "ace" and "acg" at the same location.
+Arrow endpoint detection was fixed. A sysdir setting was added, along
+with an --enable-tetex-build configure option. The store argument of
+saveline is respected again. Left-justified trailingzero alignment was
+fixed; a signedtrailingzero specifier was added. Boolean conditions on
+linearly interpolated surfaces now suppress function evaluation.
+The adaptive algorithm used for rendering thick lines and tubes was
+improved. An ambiguity in the flowchart module was fixed.
+A patch is included to work around an MSWindows XP problem with 3Dgetview
+in the 2009/03/23 version of movie15.sty. A problem with spurious menu
+interaction zooming was fixed. The asy.bat MSWindows batch file now
+respects all command-line arguments.
+
+Release Notes for Version 1.70
+
+A labelpath3 module for typesetting curved labels in 3D, contributed by Jens
+Schwaiger, was added. PenMargin2 was defined for use with planar arrowhead
+types like DefaultHead2. A center=false parameter was added to projections
+to allow one to automatically center the target within the bounding volume.
+The ambiguity in the surface function was resolved. Problems with spaces in
+filenames were fixed.
+
+Release Notes for Version 1.69
+
+Internal patch degeneracies were removed by splitting. Bugs in the
+windingnumber and the intersection routines were fixed. The inside(path)
+routine was improved; a fillrule argument was added. The bezulate connect
+routine was improved. Bezulate is now automatically applied to path arrays:
+surfaces should be constructed directly, without first calling bezulate.
+A workaround for recent changes in the hyperref package was implemented.
+The divisor setting was replaced with purge(divisor=0). The calls to baseline
+in graph.asy were fixed. A miterlimit attribute was added to pens.
+Animation problems were fixed. Lighting problems with multiple exports and
+a quit deadlock were fixed. A new version of asymptote.sty (1.06) fixes
+an undefined \ASYbox.
+
+Release Notes for Version 1.68
+
+Support for 3D inline pdf movies was added. Camera adjustment was fixed;
+the filesurface.asy example illustrates automated camera and target
+computation. A deadlock in the export loop was fixed. A new version of
+asymptote.sty (1.05) fixes the definition of \ASYanimategraphics.
+The handling of intersection fuzz was improved. The baseline routine was
+generalized. New paragraphs are now allowed in minipage labels.
+Some minor errors in the documentation were fixed.
+
+Release Notes for Version 1.67
+
+Spurious annotation question marks in 3D PDF attachments were fixed;
+attached images are now printable. The asy environment defined in the new
+(1.04) version of asymptote.sty supports keyval options width, height,
+viewportwidth, viewportheight, and attach; the obsolete asyattach
+environment was removed. The default viewportwidth is the linewidth in
+inline mode and 0 in attached mode. Planar projected arrows were fixed.
+Automatic camera adjustment was improved. A minimum viewportsize can now be
+specified. The control points for cyclic segments produced by texpath were
+fixed. Overlap issues in planar surface patches were fixed. Surface
+constructors were simplified: the routine planar has been replaced by
+surface(path3) and in most cases there is no need to call bezulate directly.
+An Align constant was added. The parameter limits used in buildcycle were
+fixed. The intersection routines now respect the fuzz parameter.
+Segmentation faults involving null cyclic guides were fixed.
+Subpath now preserves the straight flag. Pictures containing graphs
+now transform correctly; unextended axes limits and tick selection were
+improved. Axial and radial shading respect now respect -gray. The animation
+prefix was fixed. An example of drawing a surface from irregular data was
+added. A work around was implemented for an intermittent hang on exit in
+the 3D native renderer. An auto3D option was added for controlling the
+poster option. The 2008/10/08 version of movie15.sty is now compulsory.
+The cd %USERPROFILE% command was removed from asy.bat.
+
+Release Notes for Version 1.66
+
+An alignment problem with the pdflatex tex engine was fixed.
+Problems in the animations module were fixed, including a broken
+ImageMagick layers optimization. Optional direction arguments
+were added for three-dimensional bars. The appearance and alignment of the
+planar arrowheads DefaultHead2, HookHead2, and TeXHead2 was improved; they
+now accept an optional normal argument and respect the filltype.
+A transverse/longitudinal confusion was fixed in the solids module.
+The camera adjustment routine was improved and is now controlled by the
+autoadjust=true option for perspective projections; the user is notified
+when the camera is moved. The obsolete featpost3D.asy module was
+removed. Midpoint interpolation was reinstated for drawing contours.
+The Asymptote license was upgraded to the GNU Lesser General Public License.
+
+Release Notes for Version 1.65
+
+The xelatex tex engine was implemented. Bugs in pdflatex output and the
+xelatex alignment were fixed.
+
+Release Notes for Version 1.64
+
+Support was added for XeLaTeX PDF specials. The target point is not forced
+to be part of the control volume for absolute projections. The directory is
+now stripped from the animation prefix; generated PDF animations are no longer
+automatically deleted. New parameters xsize and ysize of the asyinclude
+function of the slide module are illustrated in interactive 3D examples in
+intro.asy. A Protein Data Bank example was added to illustrate the
+generation of predefined views. The slidedemo example was fixed.
+The license of the PRC code and tools was upgraded from GPL to LGPL.
+
+Release Notes for Version 1.63
+
+Support was added for XeLaTeX (which requires a modified version of
+movie15.sty; note however that PDF specials are not yet implemented in
+dvipdfmx). The 2D contour routines were generalized to handle nonuiform
+lattices; interpolation artifacts are now avoided when the midpoint
+function values are unknown. The ncell parameter for 3D contours was
+replaced by nmesh. The complex gamma function was implemented. Interactive
+rendering of preview images is now properly synchronized. The bounding
+volume is now automatically expanded to include the target position.
+An interactive 3D surface of revolution example was added to slidedemo;
+rendered images are now automatically included when fitting non-PRC
+pictures. Duplicate beginclip/endclip functions in pstoedit.asy were
+removed and the pstoedit-3.45 patch was updated to fix compilation errors.
+Errors on EOF after reading 0 values are no longer reported. One-column
+legends are now handled correctly. Old-style constructors were replaced
+with operator init. An electromagnetic spectrum example was added.
+
+Release Notes for Version 1.62
+
+Outputting PDF format to other directories was fixed. An int hex(string)
+function that casts a hexadecimal string to an integer and a
+pen rgb(string) routine that returns a pen corresponding to a given
+6-character RGB hexadecimal string were added. In the dot routines, Label
+arguments were added and minor bugs were fixed. A parametric version of
+markuniform was added.
+
+Release Notes for Version 1.61
+
+A workaround was implemented for a dvips misconfiguration in TeXlive 2008
+that introduces unwanted %%BeginPaperSize commands into the EPS output.
+The -q option was reinstated; the asymptote.py Python module was fixed.
+The bezulate.asy module now enforces the same zerowinding fillrule as used by
+dvips. In solids.asy, a warning is issued if the silhouette routine is used
+in a fully 3d context. The freeglut extensions to support user-specified
+multisampling values were re-instated. A freeglut segmentation fault
+triggered by spurious window creation in the export loop was fixed. An
+aspect ratio problem was fixed. A string[] to int[] ecast was added. A
+Pentype function was added. The asydir() function was fixed under MSDOS.
+
+Release Notes for Version 1.60
+
+An optional bool3 condition was added to the graph functions, allowing one
+to skip points or segment a graph into distinct branches, based on a
+user-supplied test (see the example gamma.asy). A gettriple routine was
+added. The interp function first promotes its pen arguments to the highest
+colorspace. Export exceptions are now caught gracefully. Under UNIX,
+xasy can now be run from a write-protected directory again. A work around
+was implemented for the inability of the movie15.sty package to handle
+spaces in filenames. Stack overflow diagnostics were improved. A read from
+pipe failure under MSDOS was fixed.
+
+Release Notes for Version 1.59
+
+A missing filltype option for projected 2D arrowheads was added.
+The scaling of plain TeX fonts was fixed. Examples that mix 3D exporting and
+viewing now work properly. With the -nothreads option, the main process
+now waits for 3D exports to finish before proceeding. Conflicts in slide
+presentations were fixed; the asy(string) function assigns defaultfilename
+correctly. A bug in processing command-line options was fixed.
+
+Release Notes for Version 1.58
+
+Two-dimensional arrowheads are now drawn automatically for 2D projections.
+ArcArrow3 routines were added. Standard pen arithmetic is now used in all
+colorspaces, so that interp(pen,pen,real) and Gradient(pen[] p) now work as
+expected. A Wheel palette was added and is used in the example gamma3 to
+indicate the phase of the complex Gamma function. A silhouette routine for
+solids of revolution is illustrated in the examples spheresilhouette.asy
+and hyperboloidsilhouette.asy. Problems with 3D axis label alignments were
+fixed. The example scaledgraph illustrates how to factor out an axis
+scaling. Interactive mode is now exited on EOF, unless exitonEOF=false.
+Support for open function signatures was added. A conflict between
+asymptote.sty and the breqn package was fixed. PNG images for the manual
+are now built in a separate directory so that they don't take precedence
+over PDF files. A problem with xasy under MSDOS was fixed.
+
+Release Notes for Version 1.57
+
+The pdflatex texengine was fixed. The default MSDOS "start-in" directory is
+now %USERPROFILE%, for compatibility with the MSWindows Vista operating
+system. Temporary files are now generated in the directory specified by
+the -outname (-o) command-line option, so that write access to the current
+directory is no longer required. Various font size problems were fixed.
+The axis coverage calculation was improved. An object(Label, envelope, ...)
+constructor was added, along with support for object transformation and
+alignment. Clipping is now allowed across page boundaries;
+beginclip(picture, path[]) and endclip(picture) functions were implemented.
+
+Release Notes for Version 1.56
+
+A bounding box bug in the latex texengine was fixed.
+The font scaling is now rounded to the nearest integer. The wait=true
+argument of shipout was fixed. The documentation of grid3 was fixed;
+examples of using grid3 with scale(true) were added. The handling of the
+asydef environment within Emacs lasy-mode was fixed. An asyinclude function
+for embedding 3D PRC graphs in slides was implemented.
+
+Release Notes for Version 1.55
+
+A serious bug in drawing paths of length 0 that broke the dot(pair)
+routine was fixed. Problems in guide to path and path to guide conversions
+were fixed. A triple invert(pair) routine was added to invert a pair z
+onto the projection plane. The obsolete field of view factor was removed.
+
+Release Notes for Version 1.54
+
+The filltype of three-dimensional labels is now respected when render=0.
+Multiple file batch mode under MSWindows was fixed. The reverse(guide) and
+guide examination routines were fixed. A reverse(guide3) routine was added.
+Curved cyclic paths of size 1 were fixed. Fork is now used by default under
+MSWindows pending stable CYGWIN POSIX thread support; this can be overridden
+with settings.threads=true. The need to remove latexusage_.pre along with
+latexusage-* and latexusage.aux when switching between latex and pdflatex
+usage was documented.
+
+Release Notes for Version 1.53
+
+Forking problems under Windows 2000 were fixed and MS-DOS style path
+warnings were suppressed. Problems with PRC projection sizing and the
+rendering logic were fixed. The toolbar is now enabled by default within
+the asyattach environment. Two-dimensional transforms no longer prevent
+three-dimensional labels from being projected onto the initial viewing
+plane. Out-of-memory errors in the OpenGL renderer are caught again.
+The new tube module was documented and a trefoilknot example was added.
+
+Release Notes for Version 1.52
+
+Support for generating PRC output on bigendian machines was added.
+Multisampling was improved: by updating the freeglut library to svn version
+761, one can now specify an antialiasing pixel width with the parameter
+multisample, which is now an integer. The asymptote.sty and asycolors.sty
+files are now installed by default in $TEXMFLOCAL/tex/latex. The OpenGL
+renderer by default now uses POSIX threads instead of fork. A work around
+for the nonstandardized signature of gluNurbsCallback on various MacOS
+platforms was implemented. Planar vertex shading was fixed. A planar
+argument to surface was added. To work around rendering problems with some
+graphics cards, the window is now hidden only when iconify=true. A tube
+module was added. A setlocale segmentation fault was fixed. Now that we
+require a multithreaded version of the Boehm garbage collector, the
+installation instructions were updated for using the system version. An
+optional user=false argument was added to min(picture), max(picture), and
+size(picture). The dependency of asy-mode.el on the cc-mode.el source file
+was removed.
+
+Release Notes for Version 1.51
+
+A separate multisample setting is used to control screen antialiasing;
+multisampling is now only enabled when viewing. The problem of multiple
+glInit calls is fixed. A more conservative multisampling patch for freeglut
+is supplied. The OpenGL process is now always forked for better
+performance. The last freeglut extension was removed.
+
+Release Notes for Version 1.50
+
+Detection and support for the native glut library on MacOSX now allows
+Asymptote's adaptive OpenGL renderer to be used on all major platforms.
+The OpenGL renderer now supports antialiasing; a race condition and export
+problems were fixed. The new default value of maxtile=(0,0) denotes
+the screen dimensions. Lighting problems due to incorrect normal
+orientations were fixed. The up vector for embedded PRC output was fixed.
+A viewportmargin parameter was added to allow for a larger viewport.
+An iconify setting was added for UNIX systems that support rendering in an
+iconified state. An embed option (default true) was added to allow one to
+suppress the embedding of a rendered preview image. A new version of
+asymptote.sty (1.01) supports file attachments, which provide a better way
+of embedding 3D PRC files in a LaTeX document. The latexusage file prefix
+was renamed from latexusage_ to latexusage-. A numerical precision issue in
+the surface of revolution constructor was fixed. Support for
+three-dimensional dimension bars was added; PenMargin3 and DotMargin3 were
+fixed. The argument put=Above (put=Below) should now be replaced by
+above=true (above=false); this is a backwards incompatible change.
+
+Release Notes for Version 1.49
+
+Issues with surface normals that led to incorrect lighting were fixed.
+By default, the mean(pen[]) routine now returns an interpolated pen with the
+minimum opacity of all given pens. A patch reverse(patch) function was
+added. The settings.keep flag is now handled correctly in texpath and
+strokepath. A cornermean function for surfaces was added. Several
+examples that illustrate patch and vertex shading were updated.
+
+Release Notes for Version 1.48
+
+High-resolution OpenGL tiled rendering was implemented. Support for
+vertex-dependent colors was added. Centering of perspective projections
+was improved. Rendering artifacts in planar surfaces and thick lines were
+fixed. A Gradient palette that varies linearly over a specified range of
+pens was added. An improved surface constructor for convex
+three-dimensional paths was added; the planar constructor should now only
+be used for nonconvex paths. A DefaultHead2(filltype filltype=Fill)
+arrowhead was implemented, along with an optional filltype argument for
+HookHead2. New maxheight, hstretch, and vstretch parameters were added to
+legend(). A boolean user=true argument was added to the point(picture, pair)
+function; the framepoint routine was removed in favour of
+truepoint(picture, pair, user=false). A roundbox envelope routine was
+added. An antialias setting (default true) was added. A bug in xasy and an
+incorrect precontrol bug in write(path) was fixed. Compilation with
+standard glut for systems without freeglut is now supported.
+
+Release Notes for Version 1.47
+
+Support for simple obj files and patch-specific surfacepens and meshpens
+was added. Surface constructors for triangles were added. Three-dimensional
+margins were implemented. Flat 3D arrowhead types HookHead2 and TeXHead2
+were implemented. By default, 3D arrowheads are now always drawn with
+currentlight. A missing angle parameter in HookHead3 was added. Functions
+that construct a pen array from a given function and palette were added, as
+illustrated in the example elevation.asy. A bug in the cyclic path write
+functions was fixed. A strokepath(path g, pen p) function was implemented.
+A missing put argument in grid3 and a missing transform for projected 3D
+mesh lines were fixed. File prefix problems were fixed. Spurious "camera
+too close" errors were fixed. Tighter three-dimensional bounds are generated.
+
+Release Notes for Version 1.46
+
+Support was added for embedding 3D PRC files within LaTeX even when
+settings.render=0. An error is now signalled if the user tries to render an
+image without freeglut library support. The Klein bottle example was
+updated to use lightgray instead of the new default surface color (black).
+The sphere animation example was updated to work with the new skeleton
+structure in the solids module.
+
+Release Notes for Version 1.45
+
+Bugs in the solids of revolution and graph3 modules were fixed;
+longitudinal curves are split into front and back pieces. Min and max
+arguments were added to axes and axes3. Rendering artifacts are now
+avoided. When render=0, 2D and 3D objects are now sized consistently.
+The automatic camera adjustment was improved. Bugs in thick three-dimensional
+lines were fixed; thick lines are now drawn with fewer Bezier patches and
+3D Linetype offsets are supported. The appearance of unitcones and arrows
+was improved. New arrowhead3 types HookHead3 and TeXHead3 were added. The
+default surface color is now black. New surface and path constructors were
+added. Secure options can now be queried as read-only settings.
+
+Release Notes for Version 1.44
+
+Full interactive 3D support has been added to Asymptote, with the option of
+generating and embedding 3D PRC data in PDF files or rendering scenes
+directly with Asymptote's own fast OpenGL-based renderer. The implicit
+casts from 3D to 2D objects were removed (in favour of call explicit calls
+to project). A path[][] texpath(string s) routine was added to convert
+string into the paths that TeX would fill. Add boolean stroke parameter was
+added for shading (and clipping to) stroked paths. The Circle and Arc
+routines were fixed. Autoscaling of graph axes limits is now disabled by
+default. A path3 path3(path p, triple plane(pair)=XYplane) constructor was
+added; the path3 routines were moved to C++ code. Optimized and robust
+versions of the intersection, windingnumber, inside, and surface extrema
+routines were implemented. The lighting routines were replaced by the
+OpenGL model. Each Asymptote process once again uses a separate
+currentpen. A segmentation fault and an incorrect parameter in the
+Delaunay triangulation routine were fixed. This major overhaul of the
+three-dimensional graphics has necessitated a few backwards
+incompatibilities. The most significant change involves filldraw:
+
+filldraw(polygon(5),red);
+
+should be replaced by
+
+draw(surface(polygon(5)),red);
+
+Also, the solids module has been improved so that
+
+revolution a=revolution(O--X+Z,Z);
+a.filldraw(red,blue);
+
+is now more sensibly written as
+
+revolution a=revolution(O--X+Z,Z);
+draw(surface(a),red);
+draw(a,blue);
+
+Release Notes for Version 1.43
+
+A new array(n, value) function returns an array consisting of n copies of
+value. Conditional drawing of surfaces meshes was implemented. Vector
+field support was improved. Graph tick selection without autoscaling
+was improved. By default, all 2D axes are drawn below existing objects.
+An interface for drawing contours on arbitrary nonoverlapping
+meshes was added. Optional support for Jonathan Shewchuk's more robust
+triangulation routines was added. The file precision setting can now be
+queried. A beep() function was added. The partialsum function now returns an
+array of the same length as its argument (backwards incompatible). Dash
+offset and font selection bugs were fixed. Modules to redefine LaTeX named
+fontsizes for 10pt and 11pt article documentclasses were added. Problems
+in asy-mode.el were fixed. A problem with label alignment was fixed.
+The international inch is now used instead of the U.S. survey inch.
+The code now compiles cleanly under gcc-4.3.0.
+
+Release Notes for Version 1.42
+
+A routine was added for projecting a Label onto a given plane;
+an ambiguity in the three-dimensional scale routine was resolved.
+An inside(path p, path q, pen fillrule=currentpen) routine was added to
+determine if one path is strictly within another. Optional arrows were
+added to the slopefield routines. The movie function now generates
+multipage PDF animations when format="pdf" and global=true; a fit argument
+was added to support an optional filled bounding box for each movie frame.
+Casts were added between the hsv structure and pens. Bad casts from TeX
+bidirectional pipe are now caught. In inline latex mode, TeX headers are
+now output only when needed. A bug in the cancellation of text addition in
+xasy was fixed. The sticky bit is no longer set when creating the ~/.asy
+directory. The documentation and FAQ were updated.
+The dot(real[] a, real[] b) routine now returns the dot product of the
+vectors a and b; this introduced a backwards incompatibility:
+dot(x,y) should now be replaced with dot(pairs(x,y)).
+
+Release Notes for Version 1.41
+
+Python-style array slices were added. The array virtual field A.keys
+returns the indices of initialized entries. The concat routine can now
+take an arbitrary number of arguments. The write functions now output
+nothing for uninitialized values instead of producing an error. A bounding
+path is stored in the object structure to allow connections to
+noncardinal boundary points. The buildcycle algorithm was improved.
+The expression dir(E) is a synonym for E. The visibility of unsplit solid
+slices is now properly resolved. A drawpen argument was added to FillDraw.
+The uniform(real a, real b, int n) function returns a uniform partition of
+[a,b] into n subintervals. Complex exp, log, sin, and cos functions were
+added. An interface to the internal adaptive simpson integration routine
+was added. History lines are now stored immediately after input (as well
+at exit, after stifling). Support for the HSV colorspace was added.
+The dependence of non-PDF animations on the animate.sty package was removed by
+renaming animate.asy to animation.asy (PDF animations still need to import
+animate.asy). Transparency groups are now respected by xasy.
+TeX diagnostics were improved. An obsolete function for drawing boxes on
+pictures was removed in favour of draw(Label,box).
+
+Release Notes for Version 1.40
+
+Hatch widths for PDF output were fixed by disabling dynamic line width
+adjustment. A nurb-related bug in solid shading was also fixed.
+
+Release Notes for Version 1.39
+
+In the animate module, a constructor bug was fixed and the temporary
+multipage pdf movie file is deleted by default.
+
+Release Notes for Version 1.38
+
+For perspective projection, nonuniform rational B-splines (NURBS) are now
+approximated by adding additional control points to Bezier curves.
+Inline PDF movies can be generated directly within LaTeX files (requires
+animate package, version 2007/11/30 or later). SimpleHead, HookHead, and
+TeXHead (Computer Modern) arrow styles were added. FillDraw is
+automatically reduced to Draw for noncyclic paths. Empty clipping bounding
+boxes were fixed. The xasy diagnostic Console should now work reliably on
+all platforms. Graph and interpolation array length diagnostics were
+improved. The axes routines now take optional xlabel, ylabel, and zlabel
+arguments defaulting to empty strings. The autoformat axes tick label
+routines now try to add an extra digit of precision. Pen arguments were
+added to the flowchart block routines. A path&cycle operator was added.
+The read1, read2, and read3 routines now affect only the current operation.
+A -c (command) option and exit() command were implemented. Ambiguous
+expressions are now resolved by interactiveWrite (with a warning). A patch
+is included for fixing problems with the Asymptote backend for pstoedit-3.45.
+
+Release Notes for Version 1.37
+
+The speed and useability of the graphical user interface has been greatly
+improved, including full transparency support under MSWindows.
+The intersections routine was fixed, and an optional fuzz parameter was
+added. A bug in the arrow routines was fixed. The 2D graph routines were
+improved when autoscaling is disabled, secondary axis bugs were fixed,
+and the automatic logarithmic axis coverage routine was re-enabled.
+Degenerate 3D reference vectors are now handled and the default 3D
+tick directions were improved. The array returned by intersections is now
+automatically sorted. A patch is applied to avoid out-of-memory
+segmentation faults with gc-7.0. A history(int n=1) function can be used to
+return the interactive history. Automatic semicolons are now added to the
+history. Locale bugs were fixed. A string[] split function was added.
+Installation, uninstallation, and diagnostics under MSWindows were
+improved. A marker dot routine was added. The output(s,update=true)
+function was fixed. Configure now uses a system version of Boehm GC if the
+recommended local version isn't present.
+
+Release Notes for Version 1.36
+
+Recently introduced bugs in the tex(), postscript(), gsave(), and grestore()
+commands were fixed.
+
+Release Notes for Version 1.35
+
+A hang in testing for the intersection of nearly identical paths in
+solids.asy was fixed. The numeric formatting of setdash arguments was fixed.
+
+Release Notes for Version 1.34
+
+An innovative graphical front end to Asymptote (xasy) has been developed.
+Clipping of labels is done within a picture environment to avoid unwanted
+page breaks. The default LaTeX font is now package-dependent. The syntax
+was generalized to allow expressions such as (x). Comments are now
+supported when reading strings in csv mode. Nesting capacity overflows
+in arctime were fixed. The autoscaling of graphs for close minimum and
+maximum values was improved, the default tick format is automatically
+adjusted to make tick labels unique, and a general trailingzero format
+string was added. Improved, robust versions of intersect and
+intersectionpoints were implemented (based on a new routine
+intersections). A permissions bug was fixed. A filltype argument was added
+to the dot routines. Printer stack use was optimized by pruning unneeded
+gsave/grestore commands. Temporary EPS files are now removed in inline PDF
+mode. A discussion of the 3D generalization of Hobby's algorithm used in
+Asymptote was added (intro.asy).
+
+Release Notes for Version 1.33
+
+Routines to find the 3D and projected 2D bounding boxes of Bezier surfaces
+were added to the surface module, along with the standard teapot example.
+Extended for loops were documented. The page numbering of slide
+presentations with stepping enabled was fixed. The int type is now a long
+long type (typically a 64-bit integer). Support for reading and writing
+64-bit integers in binary and XDR modes and large file support were added.
+Input files are now opened in input-only mode. Multiple invocations
+of labelpath now work. A projection bug in the grid3 module was fixed.
+The search path order was changed: directories specified by the dir
+configuration variable are now examined before the .asy subdirectory in the
+user's home directory. User configuration files are ignored during
+installation. Some bugs in asy-mode.el were fixed. Texput files are
+removed again. A memory allocation incompatibility in the workaround for
+old, broken readline libraries was fixed. The framepoint and truepoint
+routines now work even when an exact picture size estimate is unavailable;
+a picture scaling bug was fixed. Writing to a file specified with
+-o /dir/file.eps is allowed again. A quarticroots solver was added, the
+cubicroots solver was improved, and a complex quadraticroots solver was
+added. A workaround for broken texi2dvi installations was implemented.
+Memory leaks were fixed. The garbage collector was update to gc-7.0;
+upgrading to gv-3.6.3 is also recommended. A segmentation fault in
+complement was fixed.
+
+Release Notes for Version 1.32
+
+A recently introduced segmentation fault in subpath was fixed.
+The current directory can now be examined with cd() even if globalwrite is
+false. The cd path is now only written once in interactive mode.
+Further garbage collection improvements and leak fixes were made.
+
+Release Notes for Version 1.31
+
+Garbage collection was dramatically improved, resulting in reduced memory
+usage and increased speed. The options -compact and -divisor and the
+function purge() were added to give the user more control over garbage
+collection. The array virtual member function delete() with no arguments
+explicitly deletes all elements of the array.
+An interpolate(real[][] f, pen[] palette) function was added for
+constructing the pen array needed by the latticeshade routine.
+A nullpath frame and picture sizing bug was fixed.
+LaTeX diagnostics were improved. A facility that does not rely on
+garbage collection finalizers was implemented for closing open files
+at the end of each asy process.
+
+Release Notes for Version 1.30
+
+Constructors were added. Routines to allow access to guide
+components were added. The three-dimensional projection and contour
+routines were optimized. A tickmodifier NoZero and ticklabel format
+NoZeroFormat were added. A simplified gouraudshade interface was added.
+A linewidth bug was fixed. The array insert and delete routines were
+generalized. The new array virtual member "initialized" can be used to
+detect whether an element is initialized. All fonts are now automatically
+embedded in PDF files. Inline PDF animations now require version 2007/05/24
+or later of the animate.sty package. General root solving routines were added.
+The implicit initializer for files is null. Boolean arguments
+were added to the image and shading routines to allow one to disable
+data buffering. The functionality of the readline routine was split into
+the routines history, readline, and saveline. Many fixes were made to
+the Emacs asy-mode.el.
+
+Release Notes for Version 1.29
+
+Support for drawing surfaces described by the null space of real-valued
+functions of three variables was added. The dir command now works correctly
+for degenerate Bezier paths; an optional final argument can be used to
+examine incoming and outgoing tangent directions. Numerical overflow and
+precision issues were addressed. A piecewise monotonic spline type and
+example were added. Optional fillpen and legend entries were added to
+histogram. The "q" command quits in interactive mode only if there is no
+top-level variable of that name. Standard input of strings was
+fixed. Support for transparent PNG images in xasy was added. Animation
+support was upgraded to use the new animate.sty package rather than the
+interim pdfanim_temp.sty package.
+
+Release Notes for Version 1.28
+
+TeX error handling was improved. A dvipsOptions configuration variable was
+added. A recently introduced bug in the XDR routine xinput was fixed.
+Compilation under the upcoming GCC 4.3 release is now supported.
+Nonglobal PDF animations, where each frame is separately scaled and written
+to a file, were implemented. Reading from standard input now works correctly
+even in the absence of a working readline library. A build problem under
+Fedora Core 5 was fixed. Parallel builds are now supported.
+
+Release Notes for Version 1.27
+
+A Hermite spline graph interpolate type was added for smoothly joining
+sampled functions. The cycle3, tension3, and curl3 keywords were
+respectively renamed cycle, tension, and curl. Assignments no longer write
+the value at the prompt. A bug in longitudinal skeleton detection was
+fixed. The filloutside routine now works with paths that extend beyond the
+current boundary. The unit n-point cross function returns a cyclic path.
+The "append" argument of the output function was renamed to
+"update", which now allows both reads and writes to the data file.
+Negative arguments to seek mean relative to the end-of-file; a seekeof
+function was added. PDF animations can now be loaded from an external file.
+The TeX pipe handshaking was improved. TeXLive 2007 is now supported under
+MSWindows. A work around was implemented for a MikTeX bug in handling file
+names containing spaces.
+
+Release Notes for Version 1.26
+
+The correct surface normal is now used when calculating lighting; a Klein
+bottle example was added. The front/back detection of the transverse
+skeleton of solids of revolution is fixed. A better camera-independent
+reference value for resolving path3 orientation is used. A 3D midpoint
+routine was added. Tick values for broken axes can now be autogenerated;
+broken logarithmic axes are also supported. A 2D aligned axes example was
+added. A patch that fixes a redisplay bug in gv-3.6.2 is included.
+
+Release Notes for Version 1.25
+
+A new picture size routine, which maps specified user coordinates to a
+given final size, provides a convenient way of forcing the plotted
+subregion of a graph to have a fixed size. The correct surface
+normal is chosen when calculating lighting. The comment character can now be
+escaped when reading strings from data files (but is disabled when reading
+raw characters with getc). The new word file mode is useful for reading
+white space-delimited strings. PostScript output files are now explicitly
+designated as EPSF in the header line. The minimum width and height of
+flowchart blocks may now be controlled separately. Interpolation and knot
+theory modules were added. The usage of path vs. guide in the base files was
+standardized.
+
+Release Notes for Version 1.24
+
+Structures now have implicit initializers. PDF animations are supported in
+inline tex mode by communicating the texpreamble to LaTeX. The asypreamble
+environment was removed in favour of corresponding Asymptote commands in
+the asydef environment. Default y tick values were fixed. The binary space
+partition now works correctly for projections from infinity; an arbitrary
+target point can be specified for perspective projections. A 3D version of
+the intersectionpoints routine was added. Unconditional binary logical
+operators & and | and bitwise integer functions AND, OR, XOR, and NOT were
+defined; the array boolean operators && and || were renamed to & and |.
+The PostScript clipping code was fixed. The angle(rotate(x)) routine now
+always returns x (mod 360). User debugging errors are now cleared.
+The fontsize package was updated to use fix-cm.sty instead of type1cm.sty.
+The Microsoft Windows registry is checked for both GPL and AFPL Ghostscript.
+A workaround was implemented for a pdflatex vertical offset bug.
+Segmentation faults in the Delaunay triangulation and image codes were fixed.
+
+Release Notes for Version 1.23
+
+Microsoft Windows autoconfiguration has been implemented by querying the
+registry: Asymptote and the applications it depends on may now be installed in
+any location. The shipout command is allowed to write to other directories
+if and only if -global is true. An autoimport configuration setting was
+added. Importing the Gnu Scientific Library (gsl) now works on all
+platforms. A texpreamble environment to contain the LaTeX preamble for
+both LaTeX and Asymptote was added to asymptote.sty. A conflict with the
+French babel packages was fixed. Background picture sizing in the slide
+presentation package was fixed.
+
+Release Notes for Version 1.22
+
+Problems with loading LaTeX packages and slide presentations were fixed.
+Non-static variables in every loop iteration are now allocated anew.
+Formatting under locales with nonperiod decimal separators was fixed,
+along with logarithmic tick labels near the machine epsilon. Concatenation
+of nullpaths was fixed. New path markers were added and the perpendicular
+symbol in the geometry module was improved. The skeleton routines in the
+solids module were split to provide finer control. Routines to facilitate
+drawing 3d contours were added. Reading portable XDR binary data into
+arrays works again; functions for reading and writing also in native binary
+formats were added. The TeX preamble is no longer output in inline
+mode. The TeX pipe is now aware of a previously generated aux file. Memory
+leaks were fixed. An inline limit is now imposed on old compilers to speed
+up compilation. Setlocale warnings are disabled unless debugging is on. A
+colorspace command for extracting the colorspace of a pen was added. An
+Asymptote introductory slide presentation was added and a user-written
+Asymptote tutorial is now cited in the manual.
+
+Release Notes for Version 1.21
+
+Expressions entered at the interactive prompt are automatically evaluated
+and written to stdout. The routine intersectionpoints returns all
+intersection points of two paths. Bounding box computations of paths drawn
+with transformed pen nibs were fixed. Transparency and automatic
+colorspace promotion are supported when shading and drawing images.
+A grid3 module for drawing 3D grids and a binary tree module were added.
+Automatic tick computations were improved: the actual tick value is now
+passed to the ticklabel formatting routine, even for logarithmic axes.
+A tickmodifier routine gives users complete control over which of the
+auto-generated ticks actually get drawn. The contour drawing and filling
+routines were improved. A --where option makes --listvariables show where
+global functions and variables are declared. Emacs asy-mode was improved,
+including function source code lookup. An optional labelpath interface to
+the PSTricks pstextpath macro was implemented for drawing curved labels
+along paths. In inline latex usage, picture are no longer scaled by
+default (use \begin{asy}[\the\linewidth] to recover previous default of
+scaling to line width). A texcommand option was added to override the tex
+engine command name. The slide presentation module no longer forces
+pdflatex; bibliography support was added, figuremattpen was reimplemented,
+and the spurious vertical shifting of bullets was fixed. Compilation under
+AIX and IRIX systems is supported.
+
+Release Notes for Version 1.20
+
+Explicit yaxis label angles were fixed. Loading and including diagnostics
+under the -vv option were improved. The Emacs asy-mode now respects
+TeX-electric-sub-and-superscript. The texpath configuration variable and
+diagnostics were fixed under MSWindows. Low-resolution palettes now
+display correctly. A routine to fill cyclic contours was added, along with
+the example fillcontour.asy. A command-line option to change the current
+working directory was added. The FAQ was updated.
+
+Release Notes for Version 1.19
+
+Bezier surfaces were implemented, along with tensor and Coons patch
+shading. The cylinder function was changed to be consistent with the cone
+function. The intersect routine now returns an array of two reals.
+The unitsize, xunitsize, and yunitsize arguments of shipout have been
+replaced with a unitsize function. The seconds() function now works
+portably. Minor bugs in inside() were fixed; a winding number routine was
+added. The movie bounding box is set to the largest bounding box of all
+pictures. Portable high-quality embedded PDF movies are now supported, as
+well as portable external movies. An embedded U3D example was added.
+Alignment positioning transformation was fixed; a Rotate(pair) and a
+string(real x) routine was added. Flowchart routines and the labelbox and
+advection examples now work with pictures as well as frames.
+An add(picture pic=currentpicture, drawer d) wrapper was added; a picture
+rescaling bug was fixed. Tex error handling was improved. Optional bounds
+arguments were added to verbatim postscript and tex commands. Writing to
+only the local directory is allowed unless the -global (or -unsafe) option
+is specified. A final backslash continues a line on the interactive prompt;
+a new multiline option is convenient for cutting and pasting code in
+interactive mode. Clipping now sets the true size coordinates to 0. Memory
+usage was reduced. The documentation was updated, including a description
+of how to produce Debian binaries from RPM binaries.
+
+Release Notes for Version 1.18
+
+A pen caching problem and clipping bugs were fixed. Bugs in interactive
+mode and in linemode string reads were fixed. The picture.scale() routine
+now guards against division by zero. The drawing of surface meshes was fixed.
+The minbound and maxbound functions were implemented also for arrays.
+The labelx, labely, xtick, and ytick routines respect the current graph
+scaling. The asycolors.sty file was updated to remove the pstricks
+dependency. The slide package now works with both latex and pdflatex; the
+colordvi dependency was removed. A nativeformat() function returns "eps"
+or "pdf", depending on the current tex engine. The pdf() and latex()
+functions are now visible. The usepackage and minilatex modules check for
+latex mode. Static variable allocation is now discussed in the FAQ.
+An image histogram and contour example was added. The diatom example was
+modified to illustrate interaction of fixed-sized and scaled coordinates.
+
+Release Notes for Version 1.17
+
+A workaround for a garbage collection bus error under MacOS X was implemented.
+A uniform histogram routine was added to the stats module. New frequency
+binning routines were added. The argument order of the nonuniform frequency
+binning routines was interchanged for consistency (backwards incompatible).
+The FAQ was updated.
+
+Release Notes for Version 1.16
+
+Inline LaTeX mode was fixed. The legend routine was generalized to allow
+multiple entries per line; an example was added. The truepoint
+function was renamed framepoint. A function truepoint that works like point
+but accounts for fixed-sized objects was added.
+The picture.calculateTransform function now returns the actual transform used
+for fitting in the case where only an approximate picture size was
+available. A 2d frequency binning routine was added to the stats module.
+A memory leak was fixed.
+
+Release Notes for Version 1.15
+
+Graphics label bounds and incorrect path bounds in latticeshade were
+fixed. The LaTeX color package is now used for the latex and pdflatex engines,
+to keep them informed of the current color. A unitlength of 1pt is now
+enforced in inlinetex mode. In cases like 2D graphs where only an
+approximate picture size estimate is available, the transform is adjusted
+so that the fitted frame meets the size specification. The cube animation
+and binary space partition were fixed. The determinant of a singular
+matrix now returns 0 instead of an error. Temporary pdf files are removed.
+The gv patches were removed since these are included in the long-awaited
+gv-3.6.2 release. A workaround for a compilation problem under MacOS X
+10.3.9 was implemented. A DIN 15 CAD package and new examples were added.
+
+Release Notes for Version 1.14
+
+General affine transforms and clipping may be applied to TeX labels;
+bugs in label alignment transformation were fixed. The TeX engines latex,
+pdflatex, tex, and pdftex are supported. Separate xunitsize and
+yunitsize scalings are allowed. Graph axis bound communication was added
+to allow axes with ticks and unextended axes to be called on an empty
+picture. Path labels are drawn after the path (to support UnFill).
+Filltype definitions were standardized; a Draw filltype was added (for
+drawing a bounding box around a label). New filloutside routines were
+added. Images can be drawn for irregular mesh contours and two-dimensional
+pen arrays. Landscape slides automatically enable PDF autorotate option.
+A MetaPost buildcycle routine was added. Setlocale errors are ignored.
+The "Cannot write to venn_.tex" error under Windows XP was fixed. Very old
+readline libraries found on many MacOS X systems are detected. The editing
+mode asy-mode.el supports Emacs version 21. The option
+\usepackage[inline]{asymptote} is now supported under both latex and pdflatex.
+
+
+Release Notes for Version 1.13
+
+Image and contour transposition conventions for matrices were standardized;
+resolution arguments were removed from the matrix contour routines.
+The bounding box is now correctly calculated for square pen caps.
+A bug in drawline was fixed. An up argument was added to the projection
+routines to specify the camera orientation. The definition and
+documentation of cone was fixed; surface function signatures were
+consolidated. New 3d examples were added. Legends and markers are now
+allowed when drawing superpaths. Zero page alignment no longer suppresses
+labels; bounding box fuzz was removed. Intelligent interactive
+auto-completion was added. If scroll is negative, an entire page is
+scrolled. Support for Adobe Reader annotations was added.
+Write without data arguments now works like write with data arguments.
+A list function displays all global functions and variables in a module.
+The Emacs asy-mode.el was improved. A FAQ was added.
+
+Release Notes for Version 1.12
+
+PDF transparency was implemented. The documentation of Bezier curves was
+improved. Bounding box calculations now account for label scaling.
+A special case of the Step calculation in graph.asy was fixed. The function
+scroll(int) was changed to a setting; a quit (q) option was added to the
+scroll facility. To avoid an unwanted ghostscript window, gswin32c (rather
+than gswin32) is used by default for producing pdf files under MSDOS.
+
+Release Notes for Version 1.11
+
+The defaultformat string is used again for graph tick labelling commands
+instead of an empty format string. A workaround for the broken
+libsigsegv-2.3 library that caused a premature exit(1) was implemented.
+An extra blank line at the end of 3D array writes was removed; 3D array
+transpose and copy functions were added. The realmult routine was moved to
+runtime and documented. The example embeddedmovie of embedding movies
+within PDF files was added. Overflow diagnostic messages during mpeg merges
+are now suppressed. A twice setting was added to resolve LaTeX references.
+The settings module is now globally accessible. Duplicate trace messages
+were pruned. Debugger breakpoints can now be set using a matching substring
+instead of a line number. Conditional breakpoints are now supported.
+Runtime errors and interrupts no longer reset the interactive environment.
+
+Release Notes for Version 1.10
+
+Parametric surfaces were implemented and parametric graphs now respect
+picture scaling. Fill and FillDraw now work for markers and superpaths.
+A bug in reading strings from files was fixed. Support for MikTeX 2.5 and
+Autoconf > 2.59 was added. Asymptote and output filenames can now contain
+spaces. Interrupts are working again. A line-based debugger was implemented.
+
+Release Notes for Version 1.09
+
+The workaround for the gv-3.6.1 option handling bug now supports earlier
+versions of gv, including gv-3.5.8. By default, Ghostscript version 8.54 is
+used by the MSWindows version to produce PDF files.
+
+Release Notes for Version 1.08
+
+Resolution problems in the contour routines were fixed; null contour labels
+are now suppressed. Configuration problems were fixed; the malloc
+configuration checks were removed and the help command again knows the
+correct location of the manual. In the slides package, some stepping bugs
+were fixed, an institution field was added to the titlepage, and vbox
+support (say for aligned equations) was added. A colorless(pen) function
+that strips pen color attributes was added. A clean copy of the source
+files is now shipped.
+
+Release Notes for Version 1.07
+
+This release implements uniform and irregular mesh contour drawing
+algorithms: contours can be individually labelled or filled using a
+colour density palette. The flowchart interface and alignment were
+improved. A slope fields package was added. The arrow size limiting code
+was fixed. Some bugs in makepen were fixed. Image and shading functions
+now respect the -gray, -rgb, -cmyk, and -bw options. Date arithmetic routines
+were added. Several small bugs in the graph routines were fixed. Custom
+three-dimensional projections can now be easily constructed.
+
+The public keyword is now the default permission modifer. A new keyword,
+restricted, makes variables readable but not writeable outside the
+structure in which they are defined (previous this was the default behaviour).
+A user-transparent work around for the backwards-incompatible command-line
+options of gv-3.6.1 was implemented. Various configuration problems were
+addressed to better support the Asymptote rpm for the Fedora Core Extras
+project. A cputime() function was added.
+
+Release Notes for Version 1.06
+
+General flowchart routines and an example were added. Papersizes other than
+letter now work with -outformat pdf again. Performance was improved by
+avoiding unnecessary output flushing. An asycolors.sty package was added
+to make LaTeX aware of CMYK versions of predefined Asymptote colours.
+The default pdf viewer for MacOS is now "open". The -u option can now be
+specified multiple times on the command line. Optional x and y margin
+arguments were added to Fill. A reverse video option was added to
+slide.asy; titlepage and title by default call newslide, unless the
+currentpicture is empty. An argument was added to newslide to allow
+stepping to be turned off for that slide. The slidedemo example now
+generates any required eps files. A segmentation fault in eval was fixed.
+
+Release Notes for Version 1.05
+
+Shaded and skeletal representations of surfaces of rotation were
+implemented. New oblique projections were added and bugs in the 3D graph
+routines were fixed. An argument reversal in one of the add routines was
+fixed. A clipping margin was added to unfill. General determinants were
+added. Sin, Cos, Tan, aSin, aCos, and aTan, which use degrees, are now
+built-in functions. The dash adjustment algorithm was improved. The
+cubicroots solver now works again when R=0. Internal operations are now
+added for all variable declarations of new arrays and functions. Automatic
+viewing can easily be turned off under MSDOS. Nonstandard paper sizes
+are now correctly handled. The C locale is always used when producing
+postscript patterns. Configuration problems were fixed. The editor
+customization files asy.vim and asy-mode.el were moved to the Asymptote
+system directory. Stepping of slide presentations can now be enabled from
+the command line. Many new tests were implemented. The examples were moved
+to the examples subdirectory of the documentation directory.
+RPM files are now released.
+
+Release Notes for Version 1.04
+
+A convenient presentation slide package was developed. The misalignment of
+TeX and PostScript layers was fixed by giving includegraphics the exact
+bounding box. The overall bounding box was also fixed. The tension atleast
+command and the clipping of remote labels by unfill near the frame boundary
+were fixed. Permission checking for types was added. The new point-like
+truepoint function uses the actual current picture size. Locale support,
+the ', I, and F format specifiers, and custom pagewidth and pageheight
+settings were added. A Ticks specifier draws ticks on both sides of the path;
+format="%" also suppress tick labels for logarithmic axis.
+The linetype adjustment to the arclength was improved and can now be
+optionally disabled. Color names were systematized, including texcolors
+and x11colors. A general purpose user command-line option accepts arbitrary
+Asymptote code as a string. All duplicate path points in three.asy are now
+removed. A convenient fixedscaling picture sizing routine was added.
+Selected special functions from the GNU scientific library, DESTDIR support,
+and a Python module to access Asymptote commands were added.
+The legend skip is now based on the actual legend entry height, not the
+fontsize. A backwards incompatibility was introduced in attach, add, and
+legends (add and attach take arguments in the same order as label):
+
+attach(point(E),legend(20E),UnFill) -> attach(legend(),point(E),20E,UnFill).
+
+Release Notes for Version 1.03
+
+Support was added for compiling under gcc-4.1.0. A memory leak in
+interactive mode was fixed. A procedure for using CJK fonts was documented.
+The return type of the three-dimensional intersectionpoint routines was
+fixed. A function for inverting 2D points projected from 3D back onto a
+specified plane was added, along with a solid geometry package with
+routines to draw cylinders. New xaxis(triple,real), min(guide3[]), and
+max(guide3[]) convenience functions were added. A Degrees function like
+degrees(pair), except that it returns 0 for a (0,0) argument rather than
+generating an error, was added. Interactive mode (without command-line
+editing or history) now works even in the absence of the GNU readline
+library. An upper limit (100000) on the number of calls to intersectcubics
+per cubic segment was imposed on the intersection routines. The
+documentation was updated.
+
+Release Notes for Version 1.02
+
+Lighting was implemented for surfaces described by functions and matrices.
+A bug in the positioning of axis labels was fixed. The type of randMax was
+fixed. Configuration and diagnostics were improved; the "dir" setting in
+configuration files is respected. Under MSDOS, the configuration file is
+now %USERPROFILE%/.asy/config.asy; configuration settings now work as
+documented. On UNIX systems, installation can optionally be performed
+without root privileges. Errors thrown by the parser while reading the
+configuration file are now handled gracefully. The patches to pstoedit
+were removed since they are now included in pstoedit-3.44.
+
+Release Notes for Version 1.01
+
+A bug in the surface plot of a matrix was fixed. A workaround was
+implemented for the broken GNU readline/history library under MacOS.
+
+Release Notes for Version 1.00
+
+A pen bounds error was fixed. A bug in the linear equations solver was
+fixed. Images now transform properly and nonsquare images appear
+correctly. The legend argument of draw accepts a Label. An interface to
+the movie15 package for embedding movies, sounds, and 3D objects within a
+PDF file was added. A bug where nonsolid pen types were ignored was fixed.
+Missing xpart, ypart, and zpart functions were re-added. A segmentation
+fault in format was fixed. An interface to the GNU readline function was
+added to allow editing of input. A complement function was added. A bug in
+the 2D graph tick selection routines was fixed; xlimits and ylimits no
+longer crop data by default. For consistency, the "includegraphics"
+labeling function was renamed to "graphic".
+
+Release Notes for Version 0.99
+
+A bus error and compilation error under MacOS X were fixed. If -debug is
+set, execution continues after the first error. The "make check" code was
+fixed. The contributed MacOS X binary site is now mentioned in the
+documentation.
+
+Release Notes for Version 0.98
+
+Command-line options and configuration variables were reorganized into an
+Asymptote settings module, allowing default values to be set in
+~/.asy/config.asy (~/.asy/options is obsolete). Command-line options
+can be negated by prepending -no to the option name. Type-dependent
+function and record operators are now added to the parent record.
+Execution stops after the first error in a runnable. Two- and
+three-dimensional array min/max functions for all ordered builtin types
+were implemented. Comments are now allowed within 3d data blocks. The base
+file plain.asy was split into many subfiles. The currentpen nib is
+respected. Warning messages are suppressed when shipping out an empty
+picture. The tick computation was fixed when xaxis and yaxis are called
+with explicit limits. The -t option was removed as it is no longer needed
+for generating inline tex files. Machine constants are now implemented as
+variables rather than functions.
+
+Release Notes for Version 0.97
+
+An uninitialized pen transform bug was fixed. A workaround was added for a
+readline incompatibility under MacOS X 10.4.3. Incorrect and missing names
+for builtin function arguments were fixed. Duplicate functions were removed.
+
+Release Notes for Version 0.96
+
+A MetaPost-style makepen function allows the default pen nib to be changed
+to any polygonal (possibly nonconvex) cyclic path. A unitsize argument was
+added to the shipout command. Three-dimensional lighting effects were
+added and illustrated with the Gouraud shading of a sphere. The MidArrow
+attribute was fixed. Builtin functions now have named arguments. Brackets
+are now part of the quote syntax. The write command was generalized
+to allow writing a list of vectors as columns. Drawing to standard output
+now works even when there are no labels. The -noView command was replace
+by -nView or -no View. Several segmentation faults were fixed. Custom axis
+types were documented.
+
+Release Notes for Version 0.95
+
+A memory leak was fixed; garbage collection messages are now suppressed
+unless the -d option is given. In interactive mode, a reset keyword was
+implemented to restore the environment, except for the scroll setting.
+The interactive input command now does an automatic reset. A link was
+added to the GNU readline library documentation for customizing interactive
+key bindings. A hang in scroll mode on an end-of-file condition was
+fixed. To reduce LaTeX memory usage, the scalebox macro is used only where
+required. A legend problem was fixed. The documentation was updated.
+
+Release Notes for Version 0.94
+
+A label bug arising from a conflict between some versions of the LaTeX
+pstricks and graphicx packages was fixed. Embedded LaTeX files are always
+run in quiet (-noView) mode. Frame loading issues with imported types
+(for example, with the triangle SAS constructor in the geometry module) was
+fixed. The command import graph is now an abbreviation for access graph;
+unravel graph.
+
+Release Notes for Version 0.93
+
+The import scheme was completely redesigned, with new keywords access,
+unravel, from, and include. A true (rather than emulated) interactive mode
+and runtime imports have been implemented. The default pdf browser is now
+acroread; the pdf fuzz workaround for gv was removed. The tension3 and
+curl3 keywords were re-added; a surface graph routine for matrices was
+implemented. Problems with csv mode were fixed. The function defaultpen()
+was renamed to resetdefaultpen(). Integer division via quotient(int,int)
+is now consistent with the modulo (%) operator. Checks for integer
+overflow and erf, erfc, and gamma functions were added. More descriptive
+names latticeshade, axialshade, radialshade, and gouraudshade for the
+shading routines were chosen. Horizontal and vertical label scaling was
+implemented. Default command line style-parameters can now be stored in
+~/.asy/options. The interactive history file is now ~/.asy/history by
+default unless -localhistory is specified. Outputting to standard output
+via "-o -" is now allowed.
+
+
+Release Notes for Version 0.92
+
+Clipping now clips labels and all layers of a picture, not just the most
+recent one. A bug in precontrol and postcontrol was fixed. A ticklabel bug
+and precision errors at +/-1e-4 were fixed. An example of a "broken" x
+axis was added. A dot product now requires explicit pair arguments.
+The implicit cast from real to pen was removed. Straight flags are now
+preserved when using a path as part of a guide. An UnFill filltype was
+added for clipping underneath labels and legends. A struct marker was added
+to support arbitrary marker locations. Directories are no longer stripped
+from explicit output filenames.
+
+A function inside was implemented to test whether a point is inside a
+cyclic path. The routines inside, quadratic solver, and intersect in
+math.asy were replaced by internal C++ routines. A robust real cubic root
+solver was added. A floating point exception in complex powers when base is
+zero was fixed. Colinearity checks were added to the leastsquares routine.
+
+The interface to plane was changed to return a representation of the plane
+through point O with normal cross(u,v). The routine intersectionpoint was
+moved to plain.asy and a 3d version was added to three.asy. We now draw
+over existing TeX layers when doing 3d hidden surface removal. A 3d aspect
+ratio can now be specified. A gui() function and MSWindows support for xasy
+was added; this will require renaming "gui(" to "GUI(" in any existing .gui
+files. The dir argument of picture.fit() was moved to add(frame,pair)
+and attach(frame,pair):
+
+add(pic.fit(E)) -> add(pic.fit(),E).
+
+Release Notes for Version 0.91
+
+Fixed GUI transforms: grouping should not depend on deconstruct flag.
+
+Release Notes for Version 0.90
+
+Default function arguments are now evaluated in the scope where the
+function is defined, not in the scope of the caller. The depth handling
+of deferred TeX labels was fixed. The positioning of 3d axes labels was
+improved; an example showing tick and axis label rotation was added.
+A minimum value of fuzz in the intersect routines is enforced to prevent
+infinite loops. An error in the man page regarding the -t option was
+fixed. The write function was generalized to handle an arbitrary number of
+data values.
+
+Release Notes for Version 0.89
+
+The processing of GUI files was fixed. User-specified ticks now work also
+with logarithmic axes. The arguments of LeftTicks and RightTicks were
+standardized; it is now possible to include a general string(real) routine
+to typeset each label. Logarithmic axes ranges of less than a decade are no
+longer upscaled when autoscaling is disabled. All references to the
+mailing list were removed from the documentation since the forum is now
+used in its place. The temporary included PostScript file suffix was
+renamed from "ps" to "eps".
+
+Release Notes for Version 0.88
+
+The graph routines were overhauled to support both two- and three-
+dimensional axes, partitioning them uniformly in tick value space,
+not with respect to arclength. An empty format string is treated as
+defaultformat. A fuzz parameter was added to the intersect routines;
+these routines now work for points. Data file comments were implemented.
+The perpendicular routine now uses an alignment argument; scale(pair) was
+removed. An option was added to asymptote.sty to make all LaTeX symbols
+visible, along with a second optional string to Label for providing a size
+estimate for undefined labels. Numerous small bugs were fixed; the
+pstoedit patch was updated. The installation and instructions were
+improved. An environment variable for every external command was added.
+
+The argument order of the axes routines was standardized; a call like
+xaxis(min,max,"$x$",red,Bottom,LeftTicks);
+should now be written
+xaxis("$x$",Bottom,min,max,red,LeftTicks);
+
+Release Notes for Version 0.87
+
+This release implements general hidden surface removal using a binary space
+partition and adds three-dimensional versions of the standard path
+functions (arclength, subpath, intersect, etc.), along with circle and arc
+functions. Hidden surfaces in regular mesh surface plots now are properly
+handled from any camera location. The arclength rather than the length is
+used for determining default label position on paths; Relative(real) and
+Relative(pair) functions were added for labelling paths relative to the
+total arclength and local path direction. Structure constructors and
+operators == and != were implemented and documented. The permissions of
+static functions within structures was fixed. A pen argument to filltype
+Fill to specify an interior pen distinct from the boundary pen was added.
+For convenience, array push members now return the pushed element.
+A missing shift in Label.out(frame) was added. The feynman module was
+updated to include a new function texshipout; MidArrow was moved to
+plain.asy. The optional position arguments of BeginArrow and related
+functions were fixed. A numerically robust quadratic equation solver was
+added.
+
+Release Notes for Version 0.86
+
+Fixed make man problems.
+
+Release Notes for Version 0.85
+
+A fully three-dimensional, rotationally invariant, generalization of the
+two-dimensional MetaPost path construction algorithms has been
+implemented. A tridiagonal solver was added. Adobe's automatic rotation of
+PDF files was disabled. Cyclic indices are now allowed only on arrays
+having the virtual cyclic flag set to true. The bug fix in simplex was
+generalized. An online help option was added to interactive mode; exit is
+now a synonym for quit. Microsoft Windows resource fields and an icon were
+added. ASYMPTOTE_DIR can now be a list of directories.
+
+Since some files were moved in this release, Microsoft users may wish to
+first uninstall the previous release to avoid duplicate files.
+
+Release Notes for Version 0.84
+
+This release ports Asymptote to the Microsoft Windows operating system; an
+executable file is distributed. Label parameters are now in a structure
+called Label, to which strings are implicitly cast, and which can be
+rotated and shifted with a transform. Automatic sizing under picture
+transformation was fixed. A bug in the simplex method was fixed. Lattice
+and Gouraud shading were added. An array append method, virtual transform
+components, and transform 6-tuple notation were added. A pen and filltype
+were added to legend. The 2d graph and palette code were cleaned up.
+An extend option was added to draw ticks across the graph for producing a
+grid. Problems with nullguide3 were fixed, the arguments of 3d rotate were
+swapped, and 3d reflections were added. A spurious papersize comment
+inserted by newer versions of dvips was removed. Pstoedit support was updated.
+
+This release introduces a few minor backward incompatibilities. Here is a
+summary of the main changes:
+
+draw("text",(0,0)--(1,1),1.0) -> draw(Label("text",1.0),(0,0)--(1,1))
+label("text",90,(0,0)) -> label(rotate(90)*"text",(0,0))
+labeldot("text",(0,0)) -> dot("text",(0,0))
+labeldot((0,0)) -> dot(Label,(0,0))
+labelbox(2mm,2mm,"text",(0,0)) -> box(Label("text",(0,0)),2mm,2mm)
+xaxis("$x$",0.5) -> xaxis(Label("$x$",0.5))
+labelxtick(1) -> xtick(Label,1)
+
+Release Notes for Version 0.83
+
+This release extends Asymptote to three dimensions. A triple type (which
+replaces the old vector type in math.asy) and a guide3 type were added,
+along with the 3D projection routines in three.asy. Three-dimensional
+arrays can now be read in line mode, using blank lines as block
+delimiters. An array pop function was added. Math mode ($ delimiters) were
+moved to within the "defaultformat" string, to allow use of non-math mode
+fonts in tick labels (by overriding the default format). A pticklabel
+option for drawing tick labels with a different pen was added. Routines
+labelxtick and labelytick were added, and the tick size and shift in xtick
+were fixed. The autoscaling of unextended axes was fixed. The xline and
+yline routines were renamed to xequals and yequals, Dot was renamed to dot,
+Cross was renamed to cross, the function "Angle(pair)" was renamed to
+"degrees(pair)", and a "Degrees(pair)" function was added to math.asy. The
+Metapost --- operator and the replacement :: for the MetaPost ... operator
+were implemented. A segmentation fault involving controls points with
+direction specifiers and a bug in "string font(pen)" were fixed. Tensions
+in straight sections of paths are now handled as in MetaPost. The -l option
+was reimplemented.
+
+Release Notes for Version 0.82
+
+Initializers for structures and general cast operators can be specified.
+Functions can be called with named (keyword) arguments, in any order.
+Rest arguments are supported. Size and aspect ratio arguments, which may
+be specified with "size", were removed from "shipout". The tick routines
+were standardized; custom tick locations and arrows on axes were implemented.
+The default frame initializer nullframe was renamed to newframe. A segmentation
+fault in the file garbage collection code and an optimization-related bug
+in fill were fixed.
+
+Unlike in the C and C++ languages, an assignment in a function argument is
+now interpreted as an assignment to a parameter of the same name in the
+function signature, not within the local scope. The command-line option -d
+may be used to check Asymptote code for cases where a named function
+argument may be mistaken for a local assignment.
+
+Release Notes for Version 0.81
+
+A guide solver bug was fixed, allowing the construction of graphs with a single
+data point. Compilation under g++-4.0.0 is now supported.
+
+Release Notes for Version 0.80
+
+A segmentation fault on the alpha (cxx) and mac platforms was fixed.
+All members of the picture structure are now deep copied.
+The latest Boehm garbage collector (version 6.5) is used by default.
+
+Release Notes for Version 0.79
+
+Types are now cached to speed up parsing. All outstanding garbage collection
+issues were addressed. The autoscaling of scaled axes was fixed.
+Another example of a secondary axis was added to the documentation.
+A Pythagorean tree example illustrates picture transforms.
+
+Release Notes for Version 0.78
+
+A binary search routine was added for sorted arrays. The handling of NAN
+values was fixed. The "checkaxis" test in graph.asy was improved.
+A problem with implicit closing of files was fixed. Minor changes were made
+to support compilation under Cygwin. A workaround for the garbage
+collection warning about repeated allocation of very large
+blocks was introduced, along with other miscellaneous garbage collection
+updates. A configuration option was added to request use of a (slower,
+multi-theaded) system version of the Boehm garbage collector.
+
+Release Notes for Version 0.77
+
+Integer arguments are now converted to real values before dividing and a real
+quotient is returned. The "quotient(int, int)" function returns the integer
+part of that result. Garbage collection has been implemented to fix memory
+leaks. A knot solving bug was fixed. Pen "plabel" vs. "p" issues were
+addressed. The eval function was renamed to map and the new eval(string)
+function was documented. The concat function can be used to concatenate two
+arrays. Complex exponential and logarithmic functions were added. The new
+function reltime can be used to compute the label position argument for draw.
+A new geometry module includes a triangle structure and functions to draw
+interior arcs of triangles and perpendicular symbols.
+
+Release Notes for Version 0.76
+
+Installation has been simplified by removing the last remaining dependency
+on the boost header files. A "plabel" argument was added to "draw" to allow
+labels and legends to use a different pen than the curve itself. The pen
+arguments in the axes routines were rearranged to be consistent with
+"draw". TeX errors in interactive mode and the TeX preamble are now
+handled properly. New functions "getstring" and "getreal" can get and
+remember user parameters. Marker frame arrays, a "Mark(int)" function,
+and "node", "value", and "slope" path computation functions were added.
+Problems with implicit scaling were addressed. The "without side-effect"
+warning was removed. An option was added to list all loaded global
+functions. The documentation of structures was improved.
+
+Release Notes for Version 0.75
+
+This release fixes a number of bugs with the new parser controller,
+including a segmentation fault with the -p option, problems with
+interactive mode, and problems reading from standard input. The graph
+module now uses a better default value of axislabelmargin for positioning
+axis labels. The put argument of the axis routines was moved to the end of
+the argument list, for consistency with draw. Convenient xline and yline
+interfaces to the axis routines were added. The definition of the
+correlation coefficient in the least squares routine was fixed, and a fit
+function was added to the 'linefit' structure. A linear interpolation (with
+endpoint extrapolation) and a binary search routine were added to math.asy.
+
+Release Notes for Version 0.74
+
+This release fixes a segmentation fault in version 0.73 and also reduces
+the default number of colors in image palettes to work around
+PostScript/PDF limitations (that can cause the manual not to print).
+
+Release Notes for Version 0.73
+
+A more efficient type-safe union was used to speed up the virtual machine
+by roughly a factor of 5. New routines "ellipse" and "labelellipse"
+were added for drawing ovals around frames and labels. The function
+"bbox(frame)" was renamed "box(frame)". These routines now prepend to
+the frame for filling with a background color; they also return the boundary
+as a guide. A workaround was added for a bug in gcc version 3.3 to
+facilitate compilation under Darwin (MacOS). Many internal coding
+improvements were made.
diff --git a/graphics/asymptote/TODO b/graphics/asymptote/TODO
new file mode 100644
index 0000000000..f9e98d426c
--- /dev/null
+++ b/graphics/asymptote/TODO
@@ -0,0 +1,37 @@
+Andy: add keyword-only arguments
+
+Andy: Arbitrary depth copying of arrays.
+
+Andy: Investigate bbox error in uofa-talk Shadowing slide
+
+Andy: change label in coder to a class not an Int
+
+Andy: look at label alignment in rotvenn
+
+Andy: possible optimizations:
+ eliminate frame copying in picture.add(picture pic, ...)
+ varpush+popcall --> varcall?
+ fieldpush+popcall --> fieldcall?
+ overloaded::simplify copies
+ straight guide which references a subset of a pair vector.
+ Is it cheaper to import a bltin module than to call base_venv again?
+ varpush+pop --> no op
+ varsave+pop --> one op
+ closure+pushfunc+varsave+pop --> savefunc
+ stack::popWithoutReturningValue
+ look at position information saved in program, maybe save separately
+ formal::addOps calls trans
+ only hash first 3 or 4 args of signature
+ rm transToType from varinitArg::trans
+ change camp.y to flag arglists with named args
+
+Andy: testing in errortest.asy for packing versus casting, default argument
+ambiguities, and whatever else you can think of
+
+Andy: operator tuple, to let people define their own tuples
+
+Andy: Decide if we should change vm::error to em in application.cc
+
+John or Andy: Add unit test for AddOps.
+
+Jamie: Finish environment texture & other PBR refinements.
diff --git a/graphics/asymptote/absyn.cc b/graphics/asymptote/absyn.cc
new file mode 100644
index 0000000000..8ff3148dc2
--- /dev/null
+++ b/graphics/asymptote/absyn.cc
@@ -0,0 +1,30 @@
+/****
+ * absyn.cc
+ * Tom Prince 2004/05/12
+ *
+ * Utility functions for syntax trees.
+ *****/
+
+#include "absyn.h"
+#include "coenv.h"
+
+namespace absyntax {
+
+void absyn::markPos(trans::coenv& e)
+{
+ e.c.markPos(getPos());
+}
+
+absyn::~absyn()
+{}
+
+void prettyindent(ostream &out, Int indent)
+{
+ for (Int i = 0; i < indent; i++) out << " ";
+}
+void prettyname(ostream &out, string name, Int indent) {
+ prettyindent(out,indent);
+ out << name << "\n";
+}
+
+} // namespace absyntax
diff --git a/graphics/asymptote/absyn.h b/graphics/asymptote/absyn.h
new file mode 100644
index 0000000000..c8b85009ec
--- /dev/null
+++ b/graphics/asymptote/absyn.h
@@ -0,0 +1,65 @@
+/****
+ * absyn.h
+ * Andy Hammerlindl 2002/07/14
+ *
+ * Defines the basic types of abstract syntax objects using forward
+ * class declarations.
+ *****/
+
+#ifndef ABSYN_H
+#define ABSYN_H
+
+#include "common.h"
+#include "errormsg.h" // For position
+
+// Forward declaration for markPos.
+namespace trans {
+class coenv;
+}
+
+namespace absyntax {
+
+class absyn : public gc {
+protected:
+ const position pos;
+
+ void markPos(trans::coenv& c);
+
+public:
+ absyn(position pos)
+ : pos(pos) {}
+
+ virtual ~absyn();
+
+ position getPos() const
+ {
+ return pos;
+ }
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+private: // Non-copyable
+ void operator=(const absyn&);
+ absyn(const absyn&);
+};
+
+void prettyindent(ostream &out, Int indent);
+void prettyname(ostream &out, string name, Int indent);
+
+class name;
+class ty;
+class varinit;
+class exp;
+class runnable;
+class stm;
+class dec;
+class block;
+
+typedef block file;
+
+// This is the abstract syntax tree of a file, assigned to when running
+// yyparse.
+extern file *root;
+
+}
+
+#endif
diff --git a/graphics/asymptote/access.cc b/graphics/asymptote/access.cc
new file mode 100644
index 0000000000..f71dba71bf
--- /dev/null
+++ b/graphics/asymptote/access.cc
@@ -0,0 +1,163 @@
+/*****
+ * access.cc
+ * Andy Hammerlindl 2003/12/03
+ * Describes an "access," a representation of where a variable will be
+ * stored at runtime, so that read, write, and call instructions can be
+ * made.
+ *****/
+
+#include "access.h"
+#include "frame.h"
+#include "coder.h"
+#include "callable.h"
+
+using vm::item;
+
+namespace trans {
+
+/* access */
+access::~access()
+{}
+
+/* identAccess */
+void identAccess::encode(action act, position pos, coder& e)
+{
+ if (act != CALL) {
+ access::encode(act, pos, e);
+ }
+ // else - do nothing
+}
+
+
+/* bltinAccess */
+static void bltinError(position pos)
+{
+ em.error(pos);
+ em << "built-in functions cannot be modified";
+}
+
+void bltinAccess::encode(action act, position pos, coder &e)
+{
+ switch (act) {
+ case READ:
+ e.encode(inst::constpush,(item)(vm::callable*)new vm::bfunc(f));
+ break;
+ case WRITE:
+ bltinError(pos);
+ break;
+ case CALL:
+ e.encode(inst::builtin, f);
+ break;
+ }
+}
+
+void bltinAccess::encode(action act, position pos, coder &e, frame *)
+{
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+/* callableAccess */
+void callableAccess::encode(action act, position pos, coder &e)
+{
+ switch (act) {
+ case READ:
+ e.encode(inst::constpush, (item)f);
+ break;
+ case WRITE:
+ bltinError(pos);
+ break;
+ case CALL:
+ this->encode(READ, pos, e);
+ e.encode(inst::popcall);
+ break;
+ }
+}
+
+void callableAccess::encode(action act, position pos, coder &e, frame *)
+{
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+
+/* frameAccess */
+void frameAccess::encode(action act, position pos, coder &e)
+{
+ if (act == READ) {
+ if (!e.encode(f)) {
+ em.compiler(pos);
+ em << "encoding frame out of context";
+ }
+ }
+ else
+ access::encode(act, pos, e);
+}
+
+void frameAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ if (act == READ) {
+ if (!e.encode(f, top)) {
+ em.compiler(pos);
+ em << "encoding frame out of context";
+ }
+ }
+ else
+ access::encode(act, pos, e, top);
+}
+
+/* localAccess */
+static void frameError(position pos) {
+ // A local variable is being used when its frame is not active.
+ em.error(pos);
+ em << "static use of dynamic variable";
+}
+
+void localAccess::encode(action act, position pos, coder &e)
+{
+ // Get the active frame of the virtual machine.
+ frame *active = e.getFrame();
+ if (level == active) {
+ e.encode(act == WRITE ? inst::varsave : inst::varpush,
+ offset);
+ }
+ else if (e.encode(level)) {
+ e.encode(act == WRITE ? inst::fieldsave : inst::fieldpush,
+ offset);
+ }
+ else {
+ frameError(pos);
+ }
+
+ if (act == CALL)
+ e.encode(inst::popcall);
+}
+
+void localAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ if (e.encode(level,top)) {
+ e.encode(act == WRITE ? inst::fieldsave : inst::fieldpush,
+ offset);
+ if (act == CALL)
+ e.encode(inst::popcall);
+ }
+ else {
+ frameError(pos);
+ }
+}
+
+
+void qualifiedAccess::encode(action act, position pos, coder &e)
+{
+ qualifier->encode(READ, pos, e);
+ field->encode(act, pos, e, qualifierLevel);
+}
+
+void qualifiedAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ qualifier->encode(READ, pos, e, top);
+ field->encode(act, pos, e, qualifierLevel);
+}
+
+
+} // namespace trans
diff --git a/graphics/asymptote/access.h b/graphics/asymptote/access.h
new file mode 100644
index 0000000000..08e0a48e3a
--- /dev/null
+++ b/graphics/asymptote/access.h
@@ -0,0 +1,135 @@
+/*****
+ * access.h
+ * Andy Hammerlindl 2003/12/03
+ *
+ * Describes an "access," a representation of where a variable will be
+ * stored at runtime, so that read, write, and call instructions can be
+ * made.
+ *****/
+
+#ifndef ACCESS_H
+#define ACCESS_H
+
+#include <cassert>
+
+#include "errormsg.h"
+#include "item.h"
+#include "vm.h"
+
+namespace vm {
+ struct callable;
+}
+
+namespace trans {
+
+class frame;
+class coder;
+
+enum action {
+ READ,
+ WRITE,
+ CALL
+};
+
+// These serves as the base class for the accesses.
+class access : public gc {
+protected:
+ // Generic compiler access error - if the compiler functions properly,
+ // none of these should be reachable by the user.
+ void error(position pos)
+ {
+ em.compiler(pos);
+ em << "invalid use of access";
+ }
+
+public:
+ virtual ~access() = 0;
+
+ // Encode a read/write/call of the access when nothing is on the stack.
+ virtual void encode(action, position pos, coder &)
+ {
+ error(pos);
+ }
+ // Encode a read/write/call of the access when the frame "top" is on top
+ // of the stack.
+ virtual void encode(action, position pos, coder &, frame *)
+ {
+ error(pos);
+ }
+};
+
+// This class represents identity conversions in casting.
+class identAccess : public access
+{
+ virtual void encode(action act, position, coder&);
+};
+
+// Represents a function that is implemented by a built-in C++ function.
+class bltinAccess : public access {
+ vm::bltin f;
+
+public:
+ bltinAccess(vm::bltin f)
+ : f(f) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+};
+
+// Similar to bltinAccess, but works for any callable.
+class callableAccess : public access {
+ vm::callable *f;
+
+public:
+ callableAccess(vm::callable *f)
+ : f(f) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+};
+
+// An access that puts a frame on the top of the stack.
+class frameAccess : public access {
+ frame *f;
+
+public:
+ frameAccess(frame *f)
+ : f(f) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *top);
+};
+
+// Represents the access of a local variable.
+class localAccess : public access {
+ Int offset;
+ frame *level;
+
+public:
+ localAccess(Int offset, frame *level)
+ : offset(offset), level(level) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *top);
+};
+
+class qualifiedAccess : public access {
+ // The location and frame of the record.
+ access *qualifier;
+ frame *qualifierLevel;
+
+ // The location of the field relative to the record.
+ access *field;
+
+public:
+ qualifiedAccess(access *qualifier, frame *qualifierLevel, access *field)
+ : qualifier(qualifier), qualifierLevel(qualifierLevel), field(field) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *top);
+};
+
+} // namespace trans
+
+#endif // ACCESS_H
+
diff --git a/graphics/asymptote/algebra3.cc b/graphics/asymptote/algebra3.cc
new file mode 100644
index 0000000000..4b76942815
--- /dev/null
+++ b/graphics/asymptote/algebra3.cc
@@ -0,0 +1,1610 @@
+/*
+
+ algebra3.cpp, algebra3.h - C++ Vector and Matrix Algebra routines
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+
+ WWW: http://sourceforge.net/projects/glui/
+ Forums: http://sourceforge.net/forum/?group_id=92496
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**************************************************************************
+
+ There are three vector classes and two matrix classes: vec2, vec3,
+ vec4, mat3, and mat4.
+
+ All the standard arithmetic operations are defined, with '*'
+ for dot product of two vectors and multiplication of two matrices,
+ and '^' for cross product of two vectors.
+
+ Additional functions include length(), normalize(), homogenize for
+ vectors, and print(), set(), apply() for all classes.
+
+ There is a function transpose() for matrices, but note that it
+ does not actually change the matrix,
+
+ When multiplied with a matrix, a vector is treated as a row vector
+ if it precedes the matrix (v*M), and as a column vector if it
+ follows the matrix (M*v).
+
+ Matrices are stored in row-major form.
+
+ A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
+ of a higher or lower dimension. If casting to a higher dimension,
+ the new component is set by default to 1.0, unless a value is
+ specified:
+ vec3 a(1.0, 2.0, 3.0 );
+ vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0};
+ When casting to a lower dimension, the vector is homogenized in
+ the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
+ resulting vector is {X/W, Y/W, Z/W}. It is up to the user to
+ insure the fourth component is not zero before casting.
+
+ There are also the following function for building matrices:
+ identity2D(), translation2D(), rotation2D(),
+ scaling2D(), identity3D(), translation3D(),
+ rotation3D(), rotation3Drad(), scaling3D(),
+ perspective3D()
+
+
+ ---------------------------------------------------------------------
+
+ Author: Jean-Francois DOUEg
+ Revised: Paul Rademacher
+ Version 3.2 - Feb 1998
+ Revised: Nigel Stewart (GLUI Code Cleaning)
+
+**************************************************************************/
+
+#include "algebra3.h"
+#include <cmath>
+
+static const double radians=std::acos(-1)/180.0;
+
+#ifdef VEC_ERROR_FATAL
+#ifndef VEC_ERROR
+#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); exit(1); }
+#endif
+#else
+#ifndef VEC_ERROR
+#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); }
+#endif
+#endif
+
+/****************************************************************
+ * *
+ * vec2 Member functions *
+ * *
+ ****************************************************************/
+
+/******************** vec2 CONSTRUCTORS ********************/
+
+vec2::vec2()
+{
+ n[VX] = n[VY] = 0.0;
+}
+
+vec2::vec2(float x, float y)
+{
+ n[VX] = x;
+ n[VY] = y;
+}
+
+vec2::vec2(const vec2 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+}
+
+vec2::vec2(const vec3 &v) // it is up to caller to avoid divide-by-zero
+{
+ n[VX] = v.n[VX]/v.n[VZ];
+ n[VY] = v.n[VY]/v.n[VZ];
+}
+
+vec2::vec2(const vec3 &v, int dropAxis)
+{
+ switch (dropAxis)
+ {
+ case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; break;
+ case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; break;
+ default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; break;
+ }
+}
+
+/******************** vec2 ASSIGNMENT OPERATORS ******************/
+
+vec2 & vec2::operator=(const vec2 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ return *this;
+}
+
+vec2 & vec2::operator+=(const vec2 &v)
+{
+ n[VX] += v.n[VX];
+ n[VY] += v.n[VY];
+ return *this;
+}
+
+vec2 & vec2::operator-=(const vec2 &v)
+{
+ n[VX] -= v.n[VX];
+ n[VY] -= v.n[VY];
+ return *this;
+}
+
+vec2 &vec2::operator*=(float d)
+{
+ n[VX] *= d;
+ n[VY] *= d;
+ return *this;
+}
+
+vec2 &vec2::operator/=(float d)
+{
+ float d_inv = 1.0f/d;
+ n[VX] *= d_inv;
+ n[VY] *= d_inv;
+ return *this;
+}
+
+float &vec2::operator[](int i)
+{
+ if (i < VX || i > VY)
+ //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec2 [] operator: illegal access" );
+ return n[i];
+}
+
+const float &vec2::operator[](int i) const
+{
+ if (i < VX || i > VY)
+ //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec2 [] operator: illegal access" );
+
+ return n[i];
+}
+
+/******************** vec2 SPECIAL FUNCTIONS ********************/
+
+float vec2::length() const
+{
+ return (float) sqrt(length2());
+}
+
+float vec2::length2() const
+{
+ return n[VX]*n[VX] + n[VY]*n[VY];
+}
+
+vec2 &vec2::normalize() // it is up to caller to avoid divide-by-zero
+{
+ *this /= length();
+ return *this;
+}
+
+vec2 &vec2::apply(V_FCT_PTR fct)
+{
+ n[VX] = (*fct)(n[VX]);
+ n[VY] = (*fct)(n[VY]);
+ return *this;
+}
+
+void vec2::set( float x, float y )
+{
+ n[VX] = x; n[VY] = y;
+}
+
+/******************** vec2 FRIENDS *****************************/
+
+vec2 operator-(const vec2 &a)
+{
+ return vec2(-a.n[VX],-a.n[VY]);
+}
+
+vec2 operator+(const vec2 &a, const vec2& b)
+{
+ return vec2(a.n[VX]+b.n[VX], a.n[VY]+b.n[VY]);
+}
+
+vec2 operator-(const vec2 &a, const vec2& b)
+{
+ return vec2(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY]);
+}
+
+vec2 operator*(const vec2 &a, float d)
+{
+ return vec2(d*a.n[VX], d*a.n[VY]);
+}
+
+vec2 operator*(float d, const vec2 &a)
+{
+ return a*d;
+}
+
+vec2 operator*(const mat3 &a, const vec2 &v)
+{
+ vec3 av;
+
+ av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ];
+ av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ];
+ av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ];
+
+ return av;
+}
+
+vec2 operator*(const vec2 &v, const mat3 &a)
+{
+ return a.transpose() * v;
+}
+
+vec3 operator*(const mat3 &a, const vec3 &v)
+{
+ vec3 av;
+
+ av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ]*v.n[VZ];
+ av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ]*v.n[VZ];
+ av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ]*v.n[VZ];
+
+ return av;
+}
+
+vec3 operator*(const vec3 &v, const mat3 &a)
+{
+ return a.transpose() * v;
+}
+
+float operator*(const vec2 &a, const vec2 &b)
+{
+ return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY];
+}
+
+vec2 operator/(const vec2 &a, float d)
+{
+ float d_inv = 1.0f/d;
+ return vec2(a.n[VX]*d_inv, a.n[VY]*d_inv);
+}
+
+vec3 operator^(const vec2 &a, const vec2 &b)
+{
+ return vec3(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]);
+}
+
+int operator==(const vec2 &a, const vec2 &b)
+{
+ return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]);
+}
+
+int operator!=(const vec2 &a, const vec2 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, vec2& v)
+{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << " |"; }
+*/
+
+/*istream& operator >> (istream& s, vec2& v) {
+ vec2 v_tmp;
+ char c = ' ';
+
+ while (isspace(c))
+ s >> c;
+ // The vectors can be formatted either as x y or | x y |
+ if (c == '|') {
+ s >> v_tmp[VX] >> v_tmp[VY];
+ while (s >> c && isspace(c)) ;
+ if (c != '|')
+ ;//s.set(_bad);
+ }
+ else {
+ s.putback(c);
+ s >> v_tmp[VX] >> v_tmp[VY];
+ }
+ if (s)
+ v = v_tmp;
+ return s;
+}
+*/
+
+void swap(vec2 &a, vec2 &b)
+{
+ vec2 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+vec2 min_vec(const vec2 &a, const vec2 &b)
+{
+ return vec2(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY]));
+}
+
+vec2 max_vec(const vec2 &a, const vec2 &b)
+{
+ return vec2(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY]));
+}
+
+vec2 prod(const vec2 &a, const vec2 &b)
+{
+ return vec2(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]);
+}
+
+/****************************************************************
+ * *
+ * vec3 Member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+vec3::vec3()
+{
+ n[VX] = n[VY] = n[VZ] = 0.0;
+}
+
+vec3::vec3(float x, float y, float z)
+{
+ n[VX] = x;
+ n[VY] = y;
+ n[VZ] = z;
+}
+
+vec3::vec3(const vec3 &v)
+{
+ n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ];
+}
+
+vec3::vec3(const vec2 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = 1.0;
+}
+
+vec3::vec3(const vec2 &v, float d)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = d;
+}
+
+vec3::vec3(const vec4 &v) // it is up to caller to avoid divide-by-zero
+{
+ n[VX] = v.n[VX] / v.n[VW];
+ n[VY] = v.n[VY] / v.n[VW];
+ n[VZ] = v.n[VZ] / v.n[VW];
+}
+
+vec3::vec3(const vec4 &v, int dropAxis)
+{
+ switch (dropAxis)
+ {
+ case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
+ case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
+ case VZ: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VW]; break;
+ default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ]; break;
+ }
+}
+
+
+// ASSIGNMENT OPERATORS
+
+vec3 &vec3::operator=(const vec3 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ return *this;
+}
+
+vec3 &vec3::operator+=(const vec3 &v)
+{
+ n[VX] += v.n[VX];
+ n[VY] += v.n[VY];
+ n[VZ] += v.n[VZ];
+ return *this;
+}
+
+vec3 &vec3::operator-=(const vec3& v)
+{
+ n[VX] -= v.n[VX];
+ n[VY] -= v.n[VY];
+ n[VZ] -= v.n[VZ];
+ return *this;
+}
+
+vec3 &vec3::operator*=(float d)
+{
+ n[VX] *= d;
+ n[VY] *= d;
+ n[VZ] *= d;
+ return *this;
+}
+
+vec3 &vec3::operator/=(float d)
+{
+ float d_inv = 1.0f/d;
+ n[VX] *= d_inv;
+ n[VY] *= d_inv;
+ n[VZ] *= d_inv;
+ return *this;
+}
+
+float &vec3::operator[](int i)
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec3 [] operator: illegal access" );
+
+ return n[i];
+}
+
+const float &vec3::operator[](int i) const
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec3 [] operator: illegal access" );
+
+ return n[i];
+}
+
+// SPECIAL FUNCTIONS
+
+float vec3::length() const
+{
+ return (float) sqrt(length2());
+}
+
+float vec3::length2() const
+{
+ return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ];
+}
+
+vec3 &vec3::normalize() // it is up to caller to avoid divide-by-zero
+{
+ *this /= length();
+ return *this;
+}
+
+vec3 &vec3::homogenize(void) // it is up to caller to avoid divide-by-zero
+{
+ n[VX] /= n[VZ];
+ n[VY] /= n[VZ];
+ n[VZ] = 1.0;
+ return *this;
+}
+
+vec3 &vec3::apply(V_FCT_PTR fct)
+{
+ n[VX] = (*fct)(n[VX]);
+ n[VY] = (*fct)(n[VY]);
+ n[VZ] = (*fct)(n[VZ]);
+ return *this;
+}
+
+void vec3::set(float x, float y, float z) // set vector
+{
+ n[VX] = x;
+ n[VY] = y;
+ n[VZ] = z;
+}
+
+void vec3::print(FILE *file, const char *name) const // print vector to a file
+{
+ fprintf( file, "%s: <%f, %f, %f>\n", name, n[VX], n[VY], n[VZ] );
+}
+
+// FRIENDS
+
+vec3 operator-(const vec3 &a)
+{
+ return vec3(-a.n[VX],-a.n[VY],-a.n[VZ]);
+}
+
+vec3 operator+(const vec3 &a, const vec3 &b)
+{
+ return vec3(a.n[VX]+ b.n[VX], a.n[VY] + b.n[VY], a.n[VZ] + b.n[VZ]);
+}
+
+vec3 operator-(const vec3 &a, const vec3 &b)
+{
+ return vec3(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY], a.n[VZ]-b.n[VZ]);
+}
+
+vec3 operator*(const vec3 &a, float d)
+{
+ return vec3(d*a.n[VX], d*a.n[VY], d*a.n[VZ]);
+}
+
+vec3 operator*(float d, const vec3 &a)
+{
+ return a*d;
+}
+
+vec3 operator*(const mat4 &a, const vec3 &v)
+{
+ return a*vec4(v);
+}
+
+vec3 operator*(const vec3 &v, mat4 &a)
+{
+ return a.transpose()*v;
+}
+
+float operator*(const vec3 &a, const vec3 &b)
+{
+ return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ];
+}
+
+vec3 operator/(const vec3 &a, float d)
+{
+ float d_inv = 1.0f/d;
+ return vec3(a.n[VX]*d_inv, a.n[VY]*d_inv, a.n[VZ]*d_inv);
+}
+
+vec3 operator^(const vec3 &a, const vec3 &b)
+{
+ return
+ vec3(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY],
+ a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ],
+ a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]);
+}
+
+int operator==(const vec3 &a, const vec3 &b)
+{
+ return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]);
+}
+
+int operator!=(const vec3 &a, const vec3 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, vec3& v)
+{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << " |"; }
+
+istream& operator >> (istream& s, vec3& v) {
+ vec3 v_tmp;
+ char c = ' ';
+
+ while (isspace(c))
+ s >> c;
+ // The vectors can be formatted either as x y z or | x y z |
+ if (c == '|') {
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
+ while (s >> c && isspace(c)) ;
+ if (c != '|')
+ ;//s.set(_bad);
+ }
+ else {
+ s.putback(c);
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
+ }
+ if (s)
+ v = v_tmp;
+ return s;
+}
+*/
+
+void swap(vec3 &a, vec3 &b)
+{
+ vec3 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+vec3 min_vec(const vec3 &a, const vec3 &b)
+{
+ return vec3(
+ MIN(a.n[VX], b.n[VX]),
+ MIN(a.n[VY], b.n[VY]),
+ MIN(a.n[VZ], b.n[VZ]));
+}
+
+vec3 max_vec(const vec3 &a, const vec3 &b)
+{
+ return vec3(
+ MAX(a.n[VX], b.n[VX]),
+ MAX(a.n[VY], b.n[VY]),
+ MAX(a.n[VZ], b.n[VZ]));
+}
+
+vec3 prod(const vec3 &a, const vec3 &b)
+{
+ return vec3(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]);
+}
+
+/****************************************************************
+ * *
+ * vec4 Member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+vec4::vec4()
+{
+ n[VX] = n[VY] = n[VZ] = 0.0;
+ n[VW] = 1.0;
+}
+
+vec4::vec4(float x, float y, float z, float w)
+{
+ n[VX] = x;
+ n[VY] = y;
+ n[VZ] = z;
+ n[VW] = w;
+}
+
+vec4::vec4(const vec4 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = v.n[VW];
+}
+
+vec4::vec4(const vec3 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = 1.0;
+}
+
+vec4::vec4(const vec3 &v, float d)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = d;
+}
+
+// ASSIGNMENT OPERATORS
+
+vec4 &vec4::operator=(const vec4 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = v.n[VW];
+ return *this;
+}
+
+vec4 &vec4::operator+=(const vec4 &v)
+{
+ n[VX] += v.n[VX];
+ n[VY] += v.n[VY];
+ n[VZ] += v.n[VZ];
+ n[VW] += v.n[VW];
+ return *this;
+}
+
+vec4 &vec4::operator-=(const vec4 &v)
+{
+ n[VX] -= v.n[VX];
+ n[VY] -= v.n[VY];
+ n[VZ] -= v.n[VZ];
+ n[VW] -= v.n[VW];
+ return *this;
+}
+
+vec4 &vec4::operator*=(float d)
+{
+ n[VX] *= d;
+ n[VY] *= d;
+ n[VZ] *= d;
+ n[VW] *= d;
+ return *this;
+}
+
+vec4 &vec4::operator/=(float d)
+{
+ float d_inv = 1.0f/d;
+ n[VX] *= d_inv;
+ n[VY] *= d_inv;
+ n[VZ] *= d_inv;
+ n[VW] *= d_inv;
+ return *this;
+}
+
+float &vec4::operator[](int i)
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec4 [] operator: illegal access" );
+
+ return n[i];
+}
+
+const float &vec4::operator[](int i) const
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec4 [] operator: illegal access" );
+
+ return n[i];
+}
+
+// SPECIAL FUNCTIONS
+
+float vec4::length() const
+{
+ return (float) sqrt(length2());
+}
+
+float vec4::length2() const
+{
+ return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ] + n[VW]*n[VW];
+}
+
+vec4 &vec4::normalize() // it is up to caller to avoid divide-by-zero
+{
+ *this /= length();
+ return *this;
+}
+
+vec4 &vec4::homogenize() // it is up to caller to avoid divide-by-zero
+{
+ n[VX] /= n[VW];
+ n[VY] /= n[VW];
+ n[VZ] /= n[VW];
+ n[VW] = 1.0;
+ return *this;
+}
+
+vec4 &vec4::apply(V_FCT_PTR fct)
+{
+ n[VX] = (*fct)(n[VX]);
+ n[VY] = (*fct)(n[VY]);
+ n[VZ] = (*fct)(n[VZ]);
+ n[VW] = (*fct)(n[VW]);
+ return *this;
+}
+
+void vec4::print(FILE *file, const char *name) const // print vector to a file
+{
+ fprintf( file, "%s: <%f, %f, %f, %f>\n", name, n[VX], n[VY], n[VZ], n[VW]);
+}
+
+void vec4::set(float x, float y, float z, float a)
+{
+ n[0] = x;
+ n[1] = y;
+ n[2] = z;
+ n[3] = a;
+}
+
+
+// FRIENDS
+
+vec4 operator-(const vec4 &a)
+{
+ return vec4(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]);
+}
+
+vec4 operator+(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ a.n[VX] + b.n[VX],
+ a.n[VY] + b.n[VY],
+ a.n[VZ] + b.n[VZ],
+ a.n[VW] + b.n[VW]);
+}
+
+vec4 operator-(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ a.n[VX] - b.n[VX],
+ a.n[VY] - b.n[VY],
+ a.n[VZ] - b.n[VZ],
+ a.n[VW] - b.n[VW]);
+}
+
+vec4 operator*(const vec4 &a, float d)
+{
+ return vec4(d*a.n[VX], d*a.n[VY], d*a.n[VZ], d*a.n[VW]);
+}
+
+vec4 operator*(float d, const vec4 &a)
+{
+ return a*d;
+}
+
+vec4 operator*(const mat4 &a, const vec4 &v)
+{
+ #define ROWCOL(i) \
+ a.v[i].n[0]*v.n[VX] + \
+ a.v[i].n[1]*v.n[VY] + \
+ a.v[i].n[2]*v.n[VZ] + \
+ a.v[i].n[3]*v.n[VW]
+
+ return vec4(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3));
+
+ #undef ROWCOL
+}
+
+vec4 operator*(const vec4 &v, const mat4 &a)
+{
+ return a.transpose()*v;
+}
+
+float operator*(const vec4 &a, const vec4 &b)
+{
+ return
+ a.n[VX]*b.n[VX] +
+ a.n[VY]*b.n[VY] +
+ a.n[VZ]*b.n[VZ] +
+ a.n[VW]*b.n[VW];
+}
+
+vec4 operator/(const vec4 &a, float d)
+{
+ float d_inv = 1.0f/d;
+ return vec4(
+ a.n[VX]*d_inv,
+ a.n[VY]*d_inv,
+ a.n[VZ]*d_inv,
+ a.n[VW]*d_inv);
+}
+
+int operator==(const vec4 &a, const vec4 &b)
+{
+ return
+ (a.n[VX] == b.n[VX]) &&
+ (a.n[VY] == b.n[VY]) &&
+ (a.n[VZ] == b.n[VZ]) &&
+ (a.n[VW] == b.n[VW]);
+}
+
+int operator!=(const vec4 &a, const vec4 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, vec4& v)
+{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << ' '
+ << v.n[VW] << " |"; }
+
+istream& operator >> (istream& s, vec4& v) {
+ vec4 v_tmp;
+ char c = ' ';
+
+ while (isspace(c))
+ s >> c;
+ // The vectors can be formatted either as x y z w or | x y z w |
+ if (c == '|') {
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
+ while (s >> c && isspace(c)) ;
+ if (c != '|')
+ ;//s.set(_bad);
+ }
+ else {
+ s.putback(c);
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
+ }
+ if (s)
+ v = v_tmp;
+ return s;
+}
+*/
+
+void swap(vec4 &a, vec4 &b)
+{
+ vec4 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+vec4 min_vec(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ MIN(a.n[VX], b.n[VX]),
+ MIN(a.n[VY], b.n[VY]),
+ MIN(a.n[VZ], b.n[VZ]),
+ MIN(a.n[VW], b.n[VW]));
+}
+
+vec4 max_vec(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ MAX(a.n[VX], b.n[VX]),
+ MAX(a.n[VY], b.n[VY]),
+ MAX(a.n[VZ], b.n[VZ]),
+ MAX(a.n[VW], b.n[VW]));
+}
+
+vec4 prod(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ a.n[VX] * b.n[VX],
+ a.n[VY] * b.n[VY],
+ a.n[VZ] * b.n[VZ],
+ a.n[VW] * b.n[VW]);
+}
+
+/****************************************************************
+ * *
+ * mat3 member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+mat3::mat3()
+{
+ *this = identity2D();
+}
+
+mat3::mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2)
+{
+ set(v0, v1, v2);
+}
+
+mat3::mat3(const mat3 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+}
+
+// ASSIGNMENT OPERATORS
+
+mat3 &mat3::operator=(const mat3 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+ return *this;
+}
+
+mat3 &mat3::operator+=(const mat3& m)
+{
+ v[0] += m.v[0];
+ v[1] += m.v[1];
+ v[2] += m.v[2];
+ return *this;
+}
+
+mat3 &mat3::operator-=(const mat3& m)
+{
+ v[0] -= m.v[0];
+ v[1] -= m.v[1];
+ v[2] -= m.v[2];
+ return *this;
+}
+
+mat3 &mat3::operator*=(float d)
+{
+ v[0] *= d;
+ v[1] *= d;
+ v[2] *= d;
+ return *this;
+}
+
+mat3 &mat3::operator/=(float d)
+{
+ v[0] /= d;
+ v[1] /= d;
+ v[2] /= d;
+ return *this;
+}
+
+vec3 &mat3::operator[](int i)
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat3 [] operator: illegal access" );
+
+ return v[i];
+}
+
+const vec3 &mat3::operator[](int i) const
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat3 [] operator: illegal access" );
+
+ return v[i];
+}
+
+void mat3::set(const vec3 &v0, const vec3 &v1, const vec3 &v2)
+{
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+}
+
+// SPECIAL FUNCTIONS
+
+mat3 mat3::transpose() const
+{
+ return mat3(
+ vec3(v[0][0], v[1][0], v[2][0]),
+ vec3(v[0][1], v[1][1], v[2][1]),
+ vec3(v[0][2], v[1][2], v[2][2]));
+}
+
+mat3 mat3::inverse() const // Gauss-Jordan elimination with partial pivoting
+{
+ mat3 a(*this); // As a evolves from original mat into identity
+ mat3 b(identity2D()); // b evolves from identity into inverse(a)
+ int i, j, i1;
+
+ // Loop over cols of a from left to right, eliminating above and below diag
+ for (j=0; j<3; j++) // Find largest pivot in column j among rows j..2
+ {
+ i1 = j; // Row with largest pivot candidate
+ for (i=j+1; i<3; i++)
+ if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
+ i1 = i;
+
+ // Swap rows i1 and j in a and b to put pivot on diagonal
+ swap(a.v[i1], a.v[j]);
+ swap(b.v[i1], b.v[j]);
+
+ // Scale row j to have a unit diagonal
+ if (a.v[j].n[j]==0.)
+ VEC_ERROR("mat3::inverse: singular matrix; can't invert\n");
+
+ b.v[j] /= a.v[j].n[j];
+ a.v[j] /= a.v[j].n[j];
+
+ // Eliminate off-diagonal elems in col j of a, doing identical ops to b
+ for (i=0; i<3; i++)
+ if (i!=j)
+ {
+ b.v[i] -= a.v[i].n[j]*b.v[j];
+ a.v[i] -= a.v[i].n[j]*a.v[j];
+ }
+ }
+
+ return b;
+}
+
+mat3 &mat3::apply(V_FCT_PTR fct)
+{
+ v[VX].apply(fct);
+ v[VY].apply(fct);
+ v[VZ].apply(fct);
+ return *this;
+}
+
+
+// FRIENDS
+
+mat3 operator-(const mat3 &a)
+{
+ return mat3(-a.v[0], -a.v[1], -a.v[2]);
+}
+
+mat3 operator+(const mat3 &a, const mat3 &b)
+{
+ return mat3(a.v[0]+b.v[0], a.v[1]+b.v[1], a.v[2]+b.v[2]);
+}
+
+mat3 operator-(const mat3 &a, const mat3 &b)
+{
+ return mat3(a.v[0]-b.v[0], a.v[1]-b.v[1], a.v[2]-b.v[2]);
+}
+
+mat3 operator*(const mat3 &a, const mat3 &b)
+{
+ #define ROWCOL(i, j) \
+ a.v[i].n[0]*b.v[0][j] + a.v[i].n[1]*b.v[1][j] + a.v[i].n[2]*b.v[2][j]
+
+ return mat3(
+ vec3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)),
+ vec3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)),
+ vec3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)));
+
+ #undef ROWCOL
+}
+
+mat3 operator*(const mat3 &a, float d)
+{
+ return mat3(a.v[0]*d, a.v[1]*d, a.v[2]*d);
+}
+
+mat3 operator*(float d, const mat3 &a)
+{
+ return a*d;
+}
+
+mat3 operator/(const mat3 &a, float d)
+{
+ return mat3(a.v[0]/d, a.v[1]/d, a.v[2]/d);
+}
+
+int operator==(const mat3 &a, const mat3 &b)
+{
+ return
+ (a.v[0] == b.v[0]) &&
+ (a.v[1] == b.v[1]) &&
+ (a.v[2] == b.v[2]);
+}
+
+int operator!=(const mat3 &a, const mat3 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, mat3& m)
+{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ]; }
+
+istream& operator >> (istream& s, mat3& m) {
+ mat3 m_tmp;
+
+ s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ];
+ if (s)
+ m = m_tmp;
+ return s;
+}
+*/
+
+void swap(mat3 &a, mat3 &b)
+{
+ mat3 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+void mat3::print(FILE *file, const char *name) const
+{
+ int i, j;
+
+ fprintf( stderr, "%s:\n", name );
+
+ for( i = 0; i < 3; i++ )
+ {
+ fprintf( stderr, " " );
+ for( j = 0; j < 3; j++ )
+ {
+ fprintf( stderr, "%f ", v[i][j] );
+ }
+ fprintf( stderr, "\n" );
+ }
+}
+
+
+
+/****************************************************************
+ * *
+ * mat4 member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+mat4::mat4()
+{
+ *this = identity3D();
+}
+
+mat4::mat4(const vec4& v0, const vec4& v1, const vec4& v2, const vec4& v3)
+{
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+}
+
+mat4::mat4(const mat4 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+ v[3] = m.v[3];
+}
+
+mat4::mat4(
+ float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33 )
+{
+ v[0][0] = a00; v[0][1] = a01; v[0][2] = a02; v[0][3] = a03;
+ v[1][0] = a10; v[1][1] = a11; v[1][2] = a12; v[1][3] = a13;
+ v[2][0] = a20; v[2][1] = a21; v[2][2] = a22; v[2][3] = a23;
+ v[3][0] = a30; v[3][1] = a31; v[3][2] = a32; v[3][3] = a33;
+}
+
+// ASSIGNMENT OPERATORS
+
+mat4 &mat4::operator=(const mat4 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+ v[3] = m.v[3];
+ return *this;
+}
+
+mat4 &mat4::operator+=(const mat4 &m)
+{
+ v[0] += m.v[0];
+ v[1] += m.v[1];
+ v[2] += m.v[2];
+ v[3] += m.v[3];
+ return *this;
+}
+
+mat4 &mat4::operator-=(const mat4 &m)
+{
+ v[0] -= m.v[0];
+ v[1] -= m.v[1];
+ v[2] -= m.v[2];
+ v[3] -= m.v[3];
+ return *this;
+}
+
+mat4 &mat4::operator*=(float d)
+{
+ v[0] *= d;
+ v[1] *= d;
+ v[2] *= d;
+ v[3] *= d;
+ return *this;
+}
+
+mat4 &mat4::operator/=(float d)
+{
+ v[0] /= d;
+ v[1] /= d;
+ v[2] /= d;
+ v[3] /= d;
+ return *this;
+}
+
+vec4 &mat4::operator[](int i)
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat4 [] operator: illegal access" );
+ return v[i];
+}
+
+const vec4 &mat4::operator[](int i) const
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat4 [] operator: illegal access" );
+ return v[i];
+}
+
+// SPECIAL FUNCTIONS;
+
+mat4 mat4::transpose() const
+{
+ return mat4(
+ vec4(v[0][0], v[1][0], v[2][0], v[3][0]),
+ vec4(v[0][1], v[1][1], v[2][1], v[3][1]),
+ vec4(v[0][2], v[1][2], v[2][2], v[3][2]),
+ vec4(v[0][3], v[1][3], v[2][3], v[3][3]));
+}
+
+mat4 mat4::inverse() const // Gauss-Jordan elimination with partial pivoting
+{
+ mat4 a(*this); // As a evolves from original mat into identity
+ mat4 b(identity3D()); // b evolves from identity into inverse(a)
+ int i, j, i1;
+
+ // Loop over cols of a from left to right, eliminating above and below diag
+ for (j=0; j<4; j++) // Find largest pivot in column j among rows j..3
+ {
+ i1 = j; // Row with largest pivot candidate
+ for (i=j+1; i<4; i++)
+ if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
+ i1 = i;
+
+ // Swap rows i1 and j in a and b to put pivot on diagonal
+ swap(a.v[i1], a.v[j]);
+ swap(b.v[i1], b.v[j]);
+
+ // Scale row j to have a unit diagonal
+ if (a.v[j].n[j]==0.)
+ VEC_ERROR("mat4::inverse: singular matrix; can't invert\n");
+
+ b.v[j] /= a.v[j].n[j];
+ a.v[j] /= a.v[j].n[j];
+
+ // Eliminate off-diagonal elems in col j of a, doing identical ops to b
+ for (i=0; i<4; i++)
+ if (i!=j)
+ {
+ b.v[i] -= a.v[i].n[j]*b.v[j];
+ a.v[i] -= a.v[i].n[j]*a.v[j];
+ }
+ }
+
+ return b;
+}
+
+mat4 &mat4::apply(V_FCT_PTR fct)
+{
+ v[VX].apply(fct);
+ v[VY].apply(fct);
+ v[VZ].apply(fct);
+ v[VW].apply(fct);
+ return *this;
+}
+
+void mat4::print(FILE *file, const char *name) const
+{
+ int i, j;
+
+ fprintf( stderr, "%s:\n", name );
+
+ for( i = 0; i < 4; i++ )
+ {
+ fprintf( stderr, " " );
+ for( j = 0; j < 4; j++ )
+ {
+ fprintf( stderr, "%f ", v[i][j] );
+ }
+ fprintf( stderr, "\n" );
+ }
+}
+
+void mat4::swap_rows(int i, int j)
+{
+ vec4 t;
+
+ t = v[i];
+ v[i] = v[j];
+ v[j] = t;
+}
+
+void mat4::swap_cols(int i, int j)
+{
+ float t;
+ int k;
+
+ for (k=0; k<4; k++)
+ {
+ t = v[k][i];
+ v[k][i] = v[k][j];
+ v[k][j] = t;
+ }
+}
+
+
+// FRIENDS
+
+mat4 operator-(const mat4 &a)
+{
+ return mat4(-a.v[0],-a.v[1],-a.v[2],-a.v[3]);
+}
+
+mat4 operator+(const mat4 &a, const mat4 &b)
+{
+ return mat4(
+ a.v[0] + b.v[0],
+ a.v[1] + b.v[1],
+ a.v[2] + b.v[2],
+ a.v[3] + b.v[3]);
+}
+
+mat4 operator-(const mat4 &a, const mat4 &b)
+{
+ return mat4(
+ a.v[0] - b.v[0],
+ a.v[1] - b.v[1],
+ a.v[2] - b.v[2],
+ a.v[3] - b.v[3]);
+}
+
+mat4 operator*(const mat4 &a, const mat4 &b)
+{
+ #define ROWCOL(i, j) \
+ a.v[i].n[0]*b.v[0][j] + \
+ a.v[i].n[1]*b.v[1][j] + \
+ a.v[i].n[2]*b.v[2][j] + \
+ a.v[i].n[3]*b.v[3][j]
+
+ return mat4(
+ vec4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
+ vec4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
+ vec4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
+ vec4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
+ );
+
+ #undef ROWCOL
+}
+
+mat4 operator*(const mat4 &a, float d)
+{
+ return mat4(a.v[0]*d, a.v[1]*d, a.v[2]*d, a.v[3]*d);
+}
+
+mat4 operator*(float d, const mat4 &a)
+{
+ return a*d;
+}
+
+mat4 operator/(const mat4 &a, float d)
+{
+ return mat4(a.v[0]/d, a.v[1]/d, a.v[2]/d, a.v[3]/d);
+}
+
+int operator==(const mat4 &a, const mat4 &b)
+{
+ return
+ (a.v[0] == b.v[0]) &&
+ (a.v[1] == b.v[1]) &&
+ (a.v[2] == b.v[2]) &&
+ (a.v[3] == b.v[3]);
+}
+
+int operator!=(const mat4 &a, const mat4 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, mat4& m)
+{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ] << '\n' << m.v[VW]; }
+
+istream& operator >> (istream& s, mat4& m)
+{
+ mat4 m_tmp;
+
+ s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ] >> m_tmp[VW];
+ if (s)
+ m = m_tmp;
+ return s;
+}
+*/
+
+void swap(mat4 &a, mat4 &b)
+{
+ mat4 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+/****************************************************************
+ * *
+ * 2D functions and 3D functions *
+ * *
+ ****************************************************************/
+
+mat3 identity2D()
+{
+ return mat3(
+ vec3(1.0, 0.0, 0.0),
+ vec3(0.0, 1.0, 0.0),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat3 translation2D(const vec2 &v)
+{
+ return mat3(
+ vec3(1.0, 0.0, v[VX]),
+ vec3(0.0, 1.0, v[VY]),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat3 rotation2D(const vec2 &Center, float angleDeg)
+{
+ float angleRad = (float) (angleDeg * radians);
+ float c = (float) cos(angleRad);
+ float s = (float) sin(angleRad);
+
+ return mat3(
+ vec3(c, -s, Center[VX] * (1.0f-c) + Center[VY] * s),
+ vec3(s, c, Center[VY] * (1.0f-c) - Center[VX] * s),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat3 scaling2D(const vec2 &scaleVector)
+{
+ return mat3(
+ vec3(scaleVector[VX], 0.0, 0.0),
+ vec3(0.0, scaleVector[VY], 0.0),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat4 identity3D()
+{
+ return mat4(
+ vec4(1.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 1.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 translation3D(const vec3 &v)
+{
+ return mat4(
+ vec4(1.0, 0.0, 0.0, v[VX]),
+ vec4(0.0, 1.0, 0.0, v[VY]),
+ vec4(0.0, 0.0, 1.0, v[VZ]),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 rotation3D(const vec3 &Axis, float angleDeg)
+{
+ float angleRad = (float) (angleDeg * radians);
+ float c = (float) cos(angleRad);
+ float s = (float) sin(angleRad);
+ float t = 1.0f - c;
+
+ vec3 axis(Axis);
+ axis.normalize();
+
+ return mat4(
+ vec4(t * axis[VX] * axis[VX] + c,
+ t * axis[VX] * axis[VY] - s * axis[VZ],
+ t * axis[VX] * axis[VZ] + s * axis[VY],
+ 0.0),
+ vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
+ t * axis[VY] * axis[VY] + c,
+ t * axis[VY] * axis[VZ] - s * axis[VX],
+ 0.0),
+ vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
+ t * axis[VY] * axis[VZ] + s * axis[VX],
+ t * axis[VZ] * axis[VZ] + c,
+ 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 rotation3Drad(const vec3 &Axis, float angleRad)
+{
+ float c = (float) cos(angleRad);
+ float s = (float) sin(angleRad);
+ float t = 1.0f - c;
+
+ vec3 axis(Axis);
+ axis.normalize();
+
+ return mat4(
+ vec4(t * axis[VX] * axis[VX] + c,
+ t * axis[VX] * axis[VY] - s * axis[VZ],
+ t * axis[VX] * axis[VZ] + s * axis[VY],
+ 0.0),
+ vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
+ t * axis[VY] * axis[VY] + c,
+ t * axis[VY] * axis[VZ] - s * axis[VX],
+ 0.0),
+ vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
+ t * axis[VY] * axis[VZ] + s * axis[VX],
+ t * axis[VZ] * axis[VZ] + c,
+ 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 scaling3D(const vec3 &scaleVector)
+{
+ return mat4(
+ vec4(scaleVector[VX], 0.0, 0.0, 0.0),
+ vec4(0.0, scaleVector[VY], 0.0, 0.0),
+ vec4(0.0, 0.0, scaleVector[VZ], 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 perspective3D(float d)
+{
+ return mat4(
+ vec4(1.0f, 0.0f, 0.0f, 0.0f),
+ vec4(0.0f, 1.0f, 0.0f, 0.0f),
+ vec4(0.0f, 0.0f, 1.0f, 0.0f),
+ vec4(0.0f, 0.0f, 1.0f/d, 0.0f));
+}
diff --git a/graphics/asymptote/algebra3.h b/graphics/asymptote/algebra3.h
new file mode 100644
index 0000000000..7043ff3c75
--- /dev/null
+++ b/graphics/asymptote/algebra3.h
@@ -0,0 +1,480 @@
+/*
+
+ algebra3.cc, algebra3.h - C++ Vector and Matrix Algebra routines
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+
+ WWW: http://sourceforge.net/projects/glui/
+ Forums: http://sourceforge.net/forum/?group_id=92496
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**************************************************************************
+
+ There are three vector classes and two matrix classes: vec2, vec3,
+ vec4, mat3, and mat4.
+
+ All the standard arithmetic operations are defined, with '*'
+ for dot product of two vectors and multiplication of two matrices,
+ and '^' for cross product of two vectors.
+
+ Additional functions include length(), normalize(), homogenize for
+ vectors, and print(), set(), apply() for all classes.
+
+ There is a function transpose() for matrices, but note that it
+ does not actually change the matrix,
+
+ When multiplied with a matrix, a vector is treated as a row vector
+ if it precedes the matrix (v*M), and as a column vector if it
+ follows the matrix (M*v).
+
+ Matrices are stored in row-major form.
+
+ A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
+ of a higher or lower dimension. If casting to a higher dimension,
+ the new component is set by default to 1.0, unless a value is
+ specified:
+ vec3 a(1.0, 2.0, 3.0 );
+ vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0};
+ When casting to a lower dimension, the vector is homogenized in
+ the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
+ resulting vector is {X/W, Y/W, Z/W}. It is up to the user to
+ insure the fourth component is not zero before casting.
+
+ There are also the following function for building matrices:
+ identity2D(), translation2D(), rotation2D(),
+ scaling2D(), identity3D(), translation3D(),
+ rotation3D(), rotation3Drad(), scaling3D(),
+ perspective3D()
+
+ NOTE: When compiling for Windows, include this file first, to avoid
+ certain name conflicts
+
+ ---------------------------------------------------------------------
+
+ Author: Jean-Francois DOUEg
+ Revised: Paul Rademacher
+ Version 3.2 - Feb 1998
+ Revised: Nigel Stewart (GLUI Code Cleaning)
+
+**************************************************************************/
+
+#ifndef GLUI_ALGEBRA3_H
+#define GLUI_ALGEBRA3_H
+
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+#endif
+
+#define FUDGE .00001
+
+// this line defines a new type: pointer to a function which returns a
+// float and takes as argument a float
+typedef float (*V_FCT_PTR)(float);
+
+class vec2;
+class vec3;
+class vec4;
+class mat3;
+class mat4;
+
+enum axes {VX, VY, VZ, VW};
+/*
+enum planes {PA, PB, PC, PD};
+enum colors {RED, GREEN, BLUE, ALPHA};
+enum phong {KA, KD, KS, ES};
+*/
+
+/****************************************************************
+ * *
+ * 2D Vector *
+ * *
+ ****************************************************************/
+
+class vec2
+{
+ friend class vec3;
+
+protected:
+
+ float n[2];
+
+public:
+
+ // Constructors
+
+ vec2();
+ vec2(float x, float y);
+ vec2(const vec2 &v); // copy constructor
+ vec2(const vec3 &v); // cast v3 to v2
+ vec2(const vec3 &v, int dropAxis); // cast v3 to v2
+
+ // Assignment operators
+
+ vec2 &operator = (const vec2 &v); // assignment of a vec2
+ vec2 &operator += (const vec2 &v); // incrementation by a vec2
+ vec2 &operator -= (const vec2 &v); // decrementation by a vec2
+ vec2 &operator *= (float d); // multiplication by a constant
+ vec2 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ float length() const; // length of a vec2
+ float length2() const; // squared length of a vec2
+ vec2 &normalize(); // normalize a vec2
+ vec2 &apply(V_FCT_PTR fct); // apply a func. to each component
+ void set(float x, float y); // set vector
+
+ float &operator [] (int i); // indexing
+ const float &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend vec2 operator - (const vec2 &v); // -v1
+ friend vec2 operator + (const vec2 &a, const vec2 &b); // v1 + v2
+ friend vec2 operator - (const vec2 &a, const vec2 &b); // v1 - v2
+ friend vec2 operator * (const vec2 &a, float d); // v1 * 3.0
+ friend vec2 operator * (float d, const vec2 &a); // 3.0 * v1
+ friend vec2 operator * (const mat3 &a, const vec2 &v); // M . v
+ friend vec2 operator * (const vec2 &v, const mat3 &a); // v . M
+ friend float operator * (const vec2 &a, const vec2 &b); // dot product
+ friend vec2 operator / (const vec2 &a, float d); // v1 / 3.0
+ friend vec3 operator ^ (const vec2 &a, const vec2 &b); // cross product
+ friend int operator == (const vec2 &a, const vec2 &b); // v1 == v2 ?
+ friend int operator != (const vec2 &a, const vec2 &b); // v1 != v2 ?
+ //friend ostream& operator << (ostream& s, vec2& v); // output to stream
+ //friend istream& operator >> (istream& s, vec2& v); // input from strm.
+ friend void swap(vec2 &a, vec2 &b); // swap v1 & v2
+ friend vec2 min_vec(const vec2 &a, const vec2 &b); // min(v1, v2)
+ friend vec2 max_vec(const vec2 &a, const vec2 &b); // max(v1, v2)
+ friend vec2 prod (const vec2 &a, const vec2 &b); // term by term *
+};
+
+/****************************************************************
+ * *
+ * 3D Vector *
+ * *
+ ****************************************************************/
+
+class vec3
+{
+ friend class vec2;
+ friend class vec4;
+ friend class mat3;
+
+protected:
+
+ float n[3];
+
+public:
+
+ // Constructors
+
+ vec3();
+ vec3(float x, float y, float z);
+ vec3(const vec3 &v); // copy constructor
+ vec3(const vec2 &v); // cast v2 to v3
+ vec3(const vec2 &v, float d); // cast v2 to v3
+ vec3(const vec4 &v); // cast v4 to v3
+ vec3(const vec4 &v, int dropAxis); // cast v4 to v3
+
+ // Assignment operators
+
+ vec3 &operator = (const vec3 &v); // assignment of a vec3
+ vec3 &operator += (const vec3 &v); // incrementation by a vec3
+ vec3 &operator -= (const vec3 &v); // decrementation by a vec3
+ vec3 &operator *= (float d); // multiplication by a constant
+ vec3 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ float length() const; // length of a vec3
+ float length2() const; // squared length of a vec3
+ vec3& normalize(); // normalize a vec3
+ vec3& homogenize(); // homogenize (div by Z)
+ vec3& apply(V_FCT_PTR fct); // apply a func. to each component
+ void set(float x, float y, float z); // set vector
+
+ void print(FILE *file, const char *name) const; // print vector to a file
+
+
+ float &operator [] (int i); // indexing
+ const float &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend vec3 operator - (const vec3 &v); // -v1
+ friend vec3 operator + (const vec3 &a, const vec3 &b); // v1 + v2
+ friend vec3 operator - (const vec3 &a, const vec3 &b); // v1 - v2
+ friend vec3 operator * (const vec3 &a, float d); // v1 * 3.0
+ friend vec3 operator * (float d, const vec3 &a); // 3.0 * v1
+ friend vec3 operator * (const mat4 &a, const vec3 &v); // M . v
+ friend vec3 operator * (const vec3 &v, const mat4 &a); // v . M
+ friend float operator * (const vec3 &a, const vec3 &b); // dot product
+ friend vec3 operator / (const vec3 &a, float d); // v1 / 3.0
+ friend vec3 operator ^ (const vec3 &a, const vec3 &b); // cross product
+ friend int operator == (const vec3 &a, const vec3 &b); // v1 == v2 ?
+ friend int operator != (const vec3 &a, const vec3 &b); // v1 != v2 ?
+ //friend ostream& operator << (ostream& s, vec3& v); // output to stream
+ //friend istream& operator >> (istream& s, vec3& v); // input from strm.
+ friend void swap(vec3 &a, vec3 &b); // swap v1 & v2
+ friend vec3 min_vec(const vec3 &a, const vec3 &b); // min(v1, v2)
+ friend vec3 max_vec(const vec3 &a, const vec3 &b); // max(v1, v2)
+ friend vec3 prod(const vec3 &a, const vec3 &b); // term by term *
+
+ // necessary friend declarations
+
+ friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform
+ friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform
+ friend mat3 operator * (const mat3 &a, const mat3 &b); // matrix 3 product
+};
+
+/****************************************************************
+ * *
+ * 4D Vector *
+ * *
+ ****************************************************************/
+
+class vec4
+{
+ friend class vec3;
+ friend class mat4;
+
+protected:
+
+ float n[4];
+
+public:
+
+ // Constructors
+
+ vec4();
+ vec4(float x, float y, float z, float w);
+ vec4(const vec4 &v); // copy constructor
+ vec4(const vec3 &v); // cast vec3 to vec4
+ vec4(const vec3 &v, float d); // cast vec3 to vec4
+
+ // Assignment operators
+
+ vec4 &operator = (const vec4 &v); // assignment of a vec4
+ vec4 &operator += (const vec4 &v); // incrementation by a vec4
+ vec4 &operator -= (const vec4 &v); // decrementation by a vec4
+ vec4 &operator *= (float d); // multiplication by a constant
+ vec4 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ float length() const; // length of a vec4
+ float length2() const; // squared length of a vec4
+ vec4 &normalize(); // normalize a vec4
+ vec4 &apply(V_FCT_PTR fct); // apply a func. to each component
+ vec4 &homogenize();
+
+ void print(FILE *file, const char *name) const; // print vector to a file
+
+ void set(float x, float y, float z, float a);
+
+ float &operator [] (int i); // indexing
+ const float &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend vec4 operator - (const vec4 &v); // -v1
+ friend vec4 operator + (const vec4 &a, const vec4 &b); // v1 + v2
+ friend vec4 operator - (const vec4 &a, const vec4 &b); // v1 - v2
+ friend vec4 operator * (const vec4 &a, float d); // v1 * 3.0
+ friend vec4 operator * (float d, const vec4 &a); // 3.0 * v1
+ friend vec4 operator * (const mat4 &a, const vec4 &v); // M . v
+ friend vec4 operator * (const vec4 &v, const mat4 &a); // v . M
+ friend float operator * (const vec4 &a, const vec4 &b); // dot product
+ friend vec4 operator / (const vec4 &a, float d); // v1 / 3.0
+ friend int operator == (const vec4 &a, const vec4 &b); // v1 == v2 ?
+ friend int operator != (const vec4 &a, const vec4 &b); // v1 != v2 ?
+ //friend ostream& operator << (ostream& s, vec4& v); // output to stream
+ //friend istream& operator >> (istream& s, vec4& v); // input from strm.
+ friend void swap(vec4 &a, vec4 &b); // swap v1 & v2
+ friend vec4 min_vec(const vec4 &a, const vec4 &b); // min(v1, v2)
+ friend vec4 max_vec(const vec4 &a, const vec4 &b); // max(v1, v2)
+ friend vec4 prod (const vec4 &a, const vec4 &b); // term by term *
+
+ // necessary friend declarations
+
+ friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform
+ friend mat4 operator * (const mat4 &a, const mat4 &b); // matrix 4 product
+};
+
+/****************************************************************
+ * *
+ * 3x3 Matrix *
+ * *
+ ****************************************************************/
+
+class mat3
+{
+protected:
+
+ vec3 v[3];
+
+public:
+
+ // Constructors
+
+ mat3();
+ mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2);
+ mat3(const mat3 &m);
+
+ // Assignment operators
+
+ mat3 &operator = (const mat3 &m); // assignment of a mat3
+ mat3 &operator += (const mat3 &m); // incrementation by a mat3
+ mat3 &operator -= (const mat3 &m); // decrementation by a mat3
+ mat3 &operator *= (float d); // multiplication by a constant
+ mat3 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ mat3 transpose() const; // transpose
+ mat3 inverse() const; // inverse
+ mat3 &apply(V_FCT_PTR fct); // apply a func. to each element
+
+ void print(FILE *file, const char *name ) const; // print matrix to a file
+
+ void set(const vec3 &v0, const vec3 &v1, const vec3 &v2);
+
+ vec3 &operator [] (int i); // indexing
+ const vec3 &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend mat3 operator - (const mat3 &a); // -m1
+ friend mat3 operator + (const mat3 &a, const mat3 &b); // m1 + m2
+ friend mat3 operator - (const mat3 &a, const mat3 &b); // m1 - m2
+ friend mat3 operator * (const mat3 &a, const mat3 &b); // m1 * m2
+ friend mat3 operator * (const mat3 &a, float d); // m1 * 3.0
+ friend mat3 operator * (float d, const mat3 &a); // 3.0 * m1
+ friend mat3 operator / (const mat3 &a, float d); // m1 / 3.0
+ friend int operator == (const mat3 &a, const mat3 &b); // m1 == m2 ?
+ friend int operator != (const mat3 &a, const mat3 &b); // m1 != m2 ?
+ //friend ostream& operator << (ostream& s, mat3& m); // output to stream
+ //friend istream& operator >> (istream& s, mat3& m); // input from strm.
+ friend void swap(mat3 &a, mat3 &b); // swap m1 & m2
+
+ // necessary friend declarations
+
+ friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform
+ friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform
+};
+
+/****************************************************************
+ * *
+ * 4x4 Matrix *
+ * *
+ ****************************************************************/
+
+class mat4
+{
+protected:
+
+ vec4 v[4];
+
+public:
+
+ // Constructors
+
+ mat4();
+ mat4(const vec4 &v0, const vec4 &v1, const vec4 &v2, const vec4 &v3);
+ mat4(const mat4 &m);
+ mat4(float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33 );
+
+
+ // Assignment operators
+
+ mat4 &operator = (const mat4 &m); // assignment of a mat4
+ mat4 &operator += (const mat4 &m); // incrementation by a mat4
+ mat4 &operator -= (const mat4 &m); // decrementation by a mat4
+ mat4 &operator *= (float d); // multiplication by a constant
+ mat4 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ mat4 transpose() const; // transpose
+ mat4 inverse() const; // inverse
+ mat4 &apply(V_FCT_PTR fct); // apply a func. to each element
+
+ void print(FILE *file, const char *name) const; // print matrix to a file
+
+ vec4 &operator [] (int i); // indexing
+ const vec4 &operator [] (int i) const; // indexing
+
+ void swap_rows(int i, int j); // swap rows i and j
+ void swap_cols(int i, int j); // swap cols i and j
+
+ // friends
+
+ friend mat4 operator - (const mat4 &a); // -m1
+ friend mat4 operator + (const mat4 &a, const mat4 &b); // m1 + m2
+ friend mat4 operator - (const mat4 &a, const mat4 &b); // m1 - m2
+ friend mat4 operator * (const mat4 &a, const mat4 &b); // m1 * m2
+ friend mat4 operator * (const mat4 &a, float d); // m1 * 4.0
+ friend mat4 operator * (float d, const mat4 &a); // 4.0 * m1
+ friend mat4 operator / (const mat4 &a, float d); // m1 / 3.0
+ friend int operator == (const mat4 &a, const mat4 &b); // m1 == m2 ?
+ friend int operator != (const mat4 &a, const mat4 &b); // m1 != m2 ?
+ //friend ostream& operator << (ostream& s, mat4& m); // output to stream
+ //friend istream& operator >> (istream& s, mat4& m); // input from strm.
+ friend void swap(mat4 &a, mat4 &b); // swap m1 & m2
+
+ // necessary friend declarations
+
+ friend vec4 operator * (const mat4 &a, const vec4 &v); // linear transform
+ //friend vec4 operator * (const vec4& v, const mat4& a); // linear transform
+ friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform
+ friend vec3 operator * (const vec3 &v, const mat4 &a); // linear transform
+};
+
+/****************************************************************
+ * *
+ * 2D functions and 3D functions *
+ * *
+ ****************************************************************/
+
+mat3 identity2D (); // identity 2D
+mat3 translation2D(const vec2 &v); // translation 2D
+mat3 rotation2D (const vec2 &Center, float angleDeg); // rotation 2D
+mat3 scaling2D (const vec2 &scaleVector); // scaling 2D
+mat4 identity3D (); // identity 3D
+mat4 translation3D(const vec3 &v); // translation 3D
+mat4 rotation3D (const vec3 &Axis, float angleDeg); // rotation 3D
+mat4 rotation3Drad(const vec3 &Axis, float angleRad); // rotation 3D
+mat4 scaling3D (const vec3 &scaleVector); // scaling 3D
+mat4 perspective3D(float d); // perspective 3D
+
+vec3 operator * (const vec3 &v, const mat3 &a);
+vec2 operator * (const vec2 &v, const mat3 &a);
+vec3 operator * (const vec3 &v, const mat4 &a);
+vec4 operator * (const vec4 &v, const mat4 &a);
+
+#endif
diff --git a/graphics/asymptote/align.h b/graphics/asymptote/align.h
new file mode 100644
index 0000000000..f6f2e94f68
--- /dev/null
+++ b/graphics/asymptote/align.h
@@ -0,0 +1,123 @@
+#ifndef __align_h__
+#define __align_h__ 1
+
+#ifndef HAVE_POSIX_MEMALIGN
+
+#ifdef __GLIBC_PREREQ
+#if __GLIBC_PREREQ(2,3)
+#define HAVE_POSIX_MEMALIGN
+#endif
+#else
+#ifdef _POSIX_SOURCE
+#define HAVE_POSIX_MEMALIGN
+#endif
+#endif
+
+#endif
+
+#ifdef __Array_h__
+
+namespace Array {
+static const array1<Complex> NULL1;
+static const array2<Complex> NULL2;
+static const array3<Complex> NULL3;
+}
+
+#else
+
+#ifdef HAVE_POSIX_MEMALIGN
+#ifdef _AIX
+extern "C" int posix_memalign(void **memptr, size_t alignment, size_t size);
+#endif
+#else
+namespace Array {
+
+// Adapted from FFTW aligned malloc/free. Assumes that malloc is at least
+// sizeof(void*)-aligned. Allocated memory must be freed with free0.
+inline int posix_memalign0(void **memptr, size_t alignment, size_t size)
+{
+ if(alignment % sizeof (void *) != 0 || (alignment & (alignment - 1)) != 0)
+ return EINVAL;
+ void *p0=malloc(size+alignment);
+ if(!p0) return ENOMEM;
+ void *p=(void *)(((size_t) p0+alignment)&~(alignment-1));
+ *((void **) p-1)=p0;
+ *memptr=p;
+ return 0;
+}
+
+inline void free0(void *p)
+{
+ if(p) free(*((void **) p-1));
+}
+
+}
+#endif
+
+namespace Array {
+
+template<class T>
+inline void newAlign(T *&v, size_t len, size_t align)
+{
+ void *mem=NULL;
+ const char *invalid="Invalid alignment requested";
+ const char *nomem="Memory limits exceeded";
+#ifdef HAVE_POSIX_MEMALIGN
+ int rc=posix_memalign(&mem,align,len*sizeof(T));
+#else
+ int rc=posix_memalign0(&mem,align,len*sizeof(T));
+#endif
+ if(rc == EINVAL) std::cerr << invalid << std::endl;
+ if(rc == ENOMEM) std::cerr << nomem << std::endl;
+ v=(T *) mem;
+ for(size_t i=0; i < len; i++) new(v+i) T;
+}
+
+template<class T>
+inline void deleteAlign(T *v, size_t len)
+{
+ for(size_t i=len; i-- > 0;) v[i].~T();
+#ifdef HAVE_POSIX_MEMALIGN
+ free(v);
+#else
+ free0(v);
+#endif
+}
+}
+
+#endif
+
+namespace utils {
+
+inline unsigned int ceilquotient(unsigned int a, unsigned int b)
+{
+ return (a+b-1)/b;
+}
+
+inline Complex *ComplexAlign(size_t size)
+{
+ Complex *v;
+ Array::newAlign(v,size,sizeof(Complex));
+ return v;
+}
+
+inline double *doubleAlign(size_t size)
+{
+ double *v;
+ Array::newAlign(v,size,sizeof(Complex));
+ return v;
+}
+
+template<class T>
+inline void deleteAlign(T *p)
+{
+#ifdef HAVE_POSIX_MEMALIGN
+ free(p);
+#else
+ Array::free0(p);
+#endif
+}
+
+}
+
+#endif
diff --git a/graphics/asymptote/angle.h b/graphics/asymptote/angle.h
new file mode 100644
index 0000000000..3437333aaf
--- /dev/null
+++ b/graphics/asymptote/angle.h
@@ -0,0 +1,49 @@
+/*****
+ * angle.h
+ * Andy Hammerlindl 2004/04/29
+ *
+ * For degree to radian conversion and visa versa.
+ *****/
+
+#ifndef ANGLE_H
+#define ANGLE_H
+
+#include <cmath>
+#include "camperror.h"
+
+namespace camp {
+
+const double PI=acos(-1.0);
+
+const double Cpiby180=PI/180.0;
+const double C180bypi=180.0/PI;
+
+inline double radians(double theta)
+{
+ return theta*Cpiby180;
+}
+
+inline double degrees(double theta)
+{
+ return theta*C180bypi;
+}
+
+// Wrapper for atan2 with sensible (lexical) argument order and (0,0) check
+inline double angle(double x, double y)
+{
+ if(x == 0.0 && y == 0.0)
+ reportError("taking angle of (0,0)");
+ return atan2(y,x);
+}
+
+// Return an angle in the interval [0,360).
+inline double principalBranch(double deg)
+{
+ deg=fmod(deg,360.0);
+ if(deg < 0) deg += 360.0;
+ return deg;
+}
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/application.cc b/graphics/asymptote/application.cc
new file mode 100644
index 0000000000..6a3ce6f24d
--- /dev/null
+++ b/graphics/asymptote/application.cc
@@ -0,0 +1,711 @@
+/*****
+ * application.cc
+ * Andy Hammerlindl 2005/05/20
+ *
+ * An application is a matching of arguments in a call expression to formal
+ * parameters of a function. Since the language allows default arguments,
+ * keyword arguments, rest arguments, and anything else we think of, this
+ * is not a simple mapping.
+ *****/
+
+#include "application.h"
+#include "exp.h"
+#include "coenv.h"
+#include "runtime.h"
+#include "runarray.h"
+
+using namespace types;
+using absyntax::varinit;
+using absyntax::arrayinit;
+using absyntax::arglist;
+
+namespace trans {
+
+// Lower scores are better. Packed is added onto the other qualifiers so
+// we may score both exact and casted packed arguments.
+const score FAIL=0, EXACT=1, CAST=2;
+const score PACKED=2;
+
+bool castable(env &e, formal& target, formal& source) {
+ return target.Explicit ? equivalent(target.t,source.t)
+ : e.castable(target.t,source.t, symbol::castsym);
+}
+
+score castScore(env &e, formal& target, formal& source) {
+ return equivalent(target.t,source.t) ? EXACT :
+ (!target.Explicit &&
+ e.fastCastable(target.t,source.t)) ? CAST : FAIL;
+}
+
+
+void restArg::transMaker(coenv &e, Int size, bool rest) {
+ // Push the number of cells and call the array maker.
+ e.c.encode(inst::intpush, size);
+ e.c.encode(inst::builtin, rest ? run::newAppendedArray :
+ run::newInitializedArray);
+}
+
+void restArg::trans(coenv &e, temp_vector &temps)
+{
+ // Push the values on the stack.
+ for (mem::list<arg *>::iterator p = inits.begin(); p != inits.end(); ++p)
+ (*p)->trans(e, temps);
+
+ if (rest)
+ rest->trans(e, temps);
+
+ transMaker(e, (Int)inits.size(), (bool)rest);
+}
+
+class maximizer {
+ app_list l;
+
+ // Tests if x is as good (or better) an application as y.
+ bool asgood(application *x, application *y) {
+ // Matches to open signatures are always worse than matches to normal
+ // signatures.
+ if (x->sig->isOpen)
+ return y->sig->isOpen;
+ else if (y->sig->isOpen)
+ return true;
+
+ assert (x->scores.size() == y->scores.size());
+
+ // Test if each score in x is no higher than the corresponding score in
+ // y.
+ return std::equal(x->scores.begin(), x->scores.end(), y->scores.begin(),
+ std::less_equal<score>());
+ }
+
+ bool better(application *x, application *y) {
+ return asgood(x,y) && !asgood(y,x);
+ }
+
+ // Add an application that has already been determined to be maximal.
+ // Remove any other applications that are now not maximal because of its
+ // addition.
+ void addMaximal(application *x) {
+ app_list::iterator y=l.begin();
+ while (y!=l.end())
+ if (better(x,*y))
+ y=l.erase(y);
+ else
+ ++y;
+ l.push_front(x);
+ }
+
+ // Tests if x is maximal.
+ bool maximal(application *x) {
+ for (app_list::iterator y=l.begin(); y!=l.end(); ++y)
+ if (better(*y,x))
+ return false;
+ return true;
+ }
+
+public:
+ maximizer() {}
+
+ void add(application *x) {
+ if (maximal(x))
+ addMaximal(x);
+ }
+
+ app_list result() {
+ return l;
+ }
+};
+
+ty *restCellType(signature *sig) {
+ formal& f=sig->getRest();
+ if (f.t) {
+ array *a=dynamic_cast<array *>(f.t);
+ if (a)
+ return a->celltype;
+ }
+
+ return 0;
+}
+
+void application::initRest() {
+ formal& f=sig->getRest();
+ if (f.t) {
+ ty *ct = restCellType(sig);
+ if (!ct)
+ vm::error("formal rest argument must be an array");
+
+ rf=formal(ct, symbol::nullsym, false, f.Explicit);
+ }
+ if (f.t || sig->isOpen) {
+ rest=new restArg();
+ }
+}
+
+//const Int REST=-1;
+const Int NOMATCH=-2;
+
+Int application::find(symbol name) {
+ formal_vector &f=sig->formals;
+ for (size_t i=index; i<f.size(); ++i)
+ if (f[i].name==name && args[i]==0)
+ return (Int)i;
+ return NOMATCH;
+}
+
+bool application::matchDefault() {
+ if (index==args.size())
+ return false;
+ else {
+ formal &target=getTarget();
+ if (target.defval) {
+ args[index]=new defaultArg(target.t);
+ advanceIndex();
+ return true;
+ }
+ else
+ return false;
+ }
+}
+
+bool application::matchArgumentToRest(env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ if (rest) {
+ score s=castScore(e, rf, source);
+ if (s!=FAIL) {
+ rest->add(seq.addArg(a, rf.t, evalIndex));
+ scores.push_back(s+PACKED);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool application::matchAtSpot(size_t spot, env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ formal &target=sig->getFormal(spot);
+ score s=castScore(e, target, source);
+
+ if (s == FAIL)
+ return false;
+ else if (sig->formalIsKeywordOnly(spot) && source.name == symbol::nullsym)
+ return false;
+ else {
+ // The argument matches.
+ args[spot]=seq.addArg(a, target.t, evalIndex);
+ if (spot==index)
+ advanceIndex();
+ scores.push_back(s);
+ return true;
+ }
+}
+
+bool application::matchArgument(env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ assert(!source.name);
+
+ if (index==args.size())
+ // Try to pack into the rest array.
+ return matchArgumentToRest(e, source, a, evalIndex);
+ else
+ // Match here, or failing that use a default and try to match at the next
+ // spot.
+ return matchAtSpot(index, e, source, a, evalIndex) ||
+ (matchDefault() && matchArgument(e, source, a, evalIndex));
+}
+
+bool application::matchNamedArgument(env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ assert(source.name);
+
+ Int spot=find(source.name);
+ return spot!=NOMATCH && matchAtSpot(spot, e, source, a, evalIndex);
+}
+
+bool application::complete() {
+ if (index==args.size())
+ return true;
+ else if (matchDefault())
+ return complete();
+ else
+ return false;
+}
+
+bool application::matchRest(env &e, formal &source, varinit *a,
+ size_t evalIndex) {
+ // First make sure all non-rest arguments are matched (matching to defaults
+ // if necessary).
+ if (complete())
+ // Match rest to rest.
+ if (rest) {
+ formal &target=sig->getRest();
+ score s=castScore(e, target, source);
+ if (s!=FAIL) {
+ rest->addRest(seq.addArg(a, target.t, evalIndex));
+ scores.push_back(s);
+ return true;
+ }
+ }
+ return false;
+}
+
+// When the argument should be evaluated, possibly adjusting for a rest
+// argument which occurs before named arguments.
+size_t adjustIndex(size_t i, size_t ri)
+{
+ return i < ri ? i : i+1;
+}
+
+bool application::matchSignature(env &e, types::signature *source,
+ arglist &al) {
+ formal_vector &f=source->formals;
+
+#if 0
+ cout << "num args: " << f.size() << endl;
+ cout << "num keyword-only: " << sig->numKeywordOnly << endl;
+#endif
+
+ size_t ri = al.rest.val ? al.restPosition : f.size();
+
+ // First, match all of the named (non-rest) arguments.
+ for (size_t i=0; i<f.size(); ++i)
+ if (f[i].name)
+ if (!matchNamedArgument(e, f[i], al[i].val, adjustIndex(i,ri)))
+ return false;
+
+ // Then, the unnamed.
+ for (size_t i=0; i<f.size(); ++i)
+ if (!f[i].name)
+ if (!matchArgument(e, f[i], al[i].val, adjustIndex(i,ri)))
+ return false;
+
+ // Then, the rest argument.
+ if (source->hasRest())
+ if (!matchRest(e, source->getRest(), al.rest.val, ri))
+ return false;
+
+ // Fill in any remaining arguments with their defaults.
+ return complete();
+}
+
+bool application::matchOpen(env &e, signature *source, arglist &al) {
+ assert(rest);
+
+ // Pack all given parameters into the rest argument.
+ formal_vector &f=source->formals;
+ for (size_t i = 0; i < f.size(); ++i)
+ if (al[i].name)
+ // Named arguments are not handled by open signatures.
+ return false;
+ else
+ rest->add(seq.addArg(al[i].val, f[i].t, i));
+
+ if (source->hasRest())
+ rest->addRest(new varinitArg(al.rest.val, source->getRest().t));
+
+ return true;
+}
+
+application *application::match(env &e, function *t, signature *source,
+ arglist &al) {
+ assert(t->kind==ty_function);
+ application *app=new application(t);
+
+ bool success = t->getSignature()->isOpen ?
+ app->matchOpen(e, source, al) :
+ app->matchSignature(e, source, al);
+
+ //cout << "MATCH " << success << endl;
+
+ return success ? app : 0;
+}
+
+void application::transArgs(coenv &e) {
+ temp_vector temps;
+
+ for(arg_vector::iterator a=args.begin(); a != args.end(); ++a)
+ (*a)->trans(e,temps);
+
+ if (rest)
+ rest->trans(e,temps);
+}
+
+bool application::exact() {
+ if (sig->isOpen)
+ return false;
+ for (score_vector::iterator p = scores.begin(); p != scores.end(); ++p)
+ if (*p != EXACT)
+ return false;
+ return true;
+}
+
+bool application::halfExact() {
+ if (sig->isOpen)
+ return false;
+ if (scores.size() != 2)
+ return false;
+ if (scores[0] == EXACT && scores[1] == CAST)
+ return true;
+ if (scores[0] == CAST && scores[1] == EXACT)
+ return true;
+ return false;
+}
+
+// True if any of the formals have names.
+bool namedFormals(signature *sig)
+{
+ formal_vector& formals = sig->formals;
+ size_t n = formals.size();
+ for (size_t i = 0; i < n; ++i) {
+ if (formals[i].name)
+ return true;
+ }
+ return false;
+}
+
+// Tests if arguments in the source signature can be matched to the formals
+// in the target signature with no casting or packing.
+// This allows overloaded args, but not named args.
+bool exactMightMatch(signature *target, signature *source)
+{
+ // Open signatures never exactly match.
+ if (target->isOpen)
+ return false;
+
+#if 0
+ assert(!namedFormals(source));
+#endif
+
+ formal_vector& formals = target->formals;
+ formal_vector& args = source->formals;
+
+ // Sizes of the two lists.
+ size_t fn = formals.size(), an = args.size();
+
+ // Indices for the two lists.
+ size_t fi = 0, ai = 0;
+
+ while (fi < fn && ai < an) {
+ if (equivalent(formals[fi].t, args[ai].t)) {
+ // Arguments match, move to the next.
+ ++fi; ++ai;
+ } else if (formals[fi].defval) {
+ // Match formal to default value.
+ ++fi;
+ } else {
+ // Failed to match formal.
+ return false;
+ }
+ }
+
+ assert(fi == fn || ai == an);
+
+ // Packing array arguments into the rest formal is inexact. Do not allow it
+ // here.
+ if (ai < an)
+ return false;
+
+ assert(ai == an);
+
+ // Match any remaining formal to defaults.
+ while (fi < fn)
+ if (formals[fi].defval) {
+ // Match formal to default value.
+ ++fi;
+ } else {
+ // Failed to match formal.
+ return false;
+ }
+
+ // Non-rest arguments have matched.
+ assert(fi == fn && ai == an);
+
+ // Try to match the rest argument if given.
+ if (source->hasRest()) {
+ if (!target->hasRest())
+ return false;
+
+ if (!equivalent(source->getRest().t, target->getRest().t))
+ return false;
+ }
+
+ // All arguments have matched.
+ return true;
+}
+
+// Tries to match applications without casting. If an application matches
+// here, we need not attempt to match others with the slower, more general
+// techniques.
+app_list exactMultimatch(env &e,
+ types::overloaded *o,
+ types::signature *source,
+ arglist &al)
+{
+ assert(source);
+
+ app_list l;
+
+ // This can't handle named arguments.
+ if (namedFormals(source))
+ return l; /* empty */
+
+ for (ty_vector::iterator t=o->sub.begin(); t!=o->sub.end(); ++t)
+ {
+ if ((*t)->kind != ty_function)
+ continue;
+
+ function *ft = (function *)*t;
+
+ // First we run a test to see if all arguments could be exactly matched.
+ // If this returns false, no such match is possible.
+ // If it returns true, an exact match may or may not be possible.
+ if (!exactMightMatch(ft->getSignature(), source))
+ continue;
+
+ application *a=application::match(e, ft, source, al);
+
+ // Consider calling
+ // void f(A a=new A, int y)
+ // with
+ // f(3)
+ // This matches exactly if there is no implicit cast from int to A.
+ // Otherwise, it does not match.
+ // Thus, there is no way to know if the
+ // match truly is exact without looking at the environment.
+ // In such a case, exactMightMatch() must return true, but there is no
+ // exact match. Such false positives are eliminated here.
+ //
+ // Consider calling
+ // void f(int x, real y=0.0, int z=0)
+ // with
+ // f(1,2)
+ // exactMightMatch() will return true, matching 1 to x and 2 to z, but the
+ // application::match will give an inexact match of 1 to x to 2 to y, due
+ // to the cast from int to real. Therefore, we must test for exactness
+ // even after matching.
+ if (a && a->exact())
+ l.push_back(a);
+ }
+
+ //cout << "EXACTMATCH " << (!l.empty()) << endl;
+ return l;
+}
+
+bool halfExactMightMatch(env &e,
+ signature *target, types::ty *t1, types::ty *t2)
+{
+ formal_vector& formals = target->formals;
+ if (formals.size() < 2)
+ return false;
+ if (formals.size() > 2) {
+ // We should probably abort the whole matching in this case. For now,
+ // return true and let the usual matching handle it.
+ return true;
+ }
+
+ assert(formals[0].t);
+ assert(formals[1].t);
+
+ // These casting tests if successful will be repeated again by
+ // application::match. It would be nice to avoid this somehow, but the
+ // additional complexity is probably not worth the minor speed improvement.
+ if (equivalent(formals[0].t, t1))
+ return e.fastCastable(formals[1].t, t2);
+ else
+ return equivalent(formals[1].t, t2) && e.fastCastable(formals[0].t, t1);
+}
+
+// Most common after exact matches are cases such as
+// 2 + 3.4 (int, real) --> (real, real)
+// that is, binary operations where one of the operands matches exactly and the
+// other does not. This function searches for these so-called "half-exact"
+// matches. This should only be called after exactMultimatch has failed.
+app_list halfExactMultimatch(env &e,
+ types::overloaded *o,
+ types::signature *source,
+ arglist &al)
+{
+ assert(source);
+
+ app_list l;
+
+
+ // Half exact is only in the case of two arguments.
+ formal_vector& formals = source->formals;
+ if (formals.size() != 2 || source->hasRest())
+ return l; /* empty */
+
+ // This can't handle named arguments.
+ if (namedFormals(source))
+ return l; /* empty */
+
+ // Alias the two argument types.
+ types::ty *t1 = formals[0].t;
+ types::ty *t2 = formals[1].t;
+
+ assert(t1); assert(t2);
+
+ for (ty_vector::iterator t=o->sub.begin(); t!=o->sub.end(); ++t)
+ {
+ if ((*t)->kind != ty_function)
+ continue;
+
+ function *ft = (function *)*t;
+
+#if 1
+ if (!halfExactMightMatch(e, ft->getSignature(), t1, t2))
+ continue;
+#endif
+
+ application *a=application::match(e, ft, source, al);
+
+#if 1
+ if (a && a->halfExact())
+ l.push_back(a);
+#endif
+ }
+
+ return l;
+}
+
+// Simple check if there are too many arguments to match the candidate
+// function.
+// A "tooFewArgs" variant was also implemented at some point, but did
+// not give any speed-up.
+bool tooManyArgs(types::signature *target, types::signature *source) {
+ return source->getNumFormals() > target->getNumFormals() &&
+ !target->hasRest();
+}
+
+// The full overloading resolution system, which handles casting of arguments,
+// packing into rest arguments, named arguments, etc.
+app_list inexactMultimatch(env &e,
+ types::overloaded *o,
+ types::signature *source,
+ arglist &al)
+{
+ assert(source);
+
+ app_list l;
+
+
+#define DEBUG_GETAPP 0
+#if DEBUG_GETAPP
+ //cout << "source: " << *source << endl;
+ //cout << "ARGS: " << source->getNumFormals() << endl;
+ bool perfect=false;
+ bool exact=false;
+ bool halfExact=false;
+#endif
+
+ for(ty_vector::iterator t=o->sub.begin(); t!=o->sub.end(); ++t) {
+ if ((*t)->kind==ty_function) {
+#if DEBUG_GETAPP
+ function *ft = dynamic_cast<function *>(*t);
+ signature *target = ft->getSignature();
+ if (equivalent(target, source))
+ perfect = true;
+#endif
+
+ // Check if there are two many arguments to match.
+ if (tooManyArgs((*t)->getSignature(), source))
+ continue;
+
+ application *a=application::match(e, (function *)(*t), source, al);
+ if (a)
+ l.push_back(a);
+
+#if DEBUG_GETAPP
+ if (a && !namedFormals(source)) {
+ assert(a->exact() == exactlyMatchable(ft->getSignature(), source));
+ if (a->halfExact() && !namedFormals(source)) {
+ assert(halfExactMightMatch(e, target, source->getFormal(0).t,
+ source->getFormal(1).t));
+ }
+
+ }
+ if (a && a->exact())
+ exact = true;
+ if (a && a->halfExact())
+ halfExact = true;
+#endif
+ }
+ }
+
+#if DEBUG_GETAPP
+ cout << (perfect ? "PERFECT" :
+ exact ? "EXACT" :
+ halfExact ? "HALFEXACT" :
+ "IMPERFECT")
+ << endl;
+#endif
+
+ if (l.size() > 1) {
+ // Return the most specific candidates.
+ maximizer m;
+ for (app_list::iterator x=l.begin(); x!=l.end(); ++x) {
+ assert(*x);
+ m.add(*x);
+ }
+ return m.result();
+ }
+ else
+ return l;
+}
+
+enum testExactType {
+ TEST_EXACT,
+ DONT_TEST_EXACT,
+};
+
+// Sanity check for multimatch optimizations.
+void sameApplications(app_list a, app_list b, testExactType te) {
+ assert(a.size() == b.size());
+
+ if (te == TEST_EXACT) {
+ for (app_list::iterator i = a.begin(); i != a.end(); ++i) {
+ if (!(*i)->exact()) {
+ cout << *(*i)->getType() << endl;
+ }
+ assert((*i)->exact());
+ }
+ for (app_list::iterator i = b.begin(); i != b.end(); ++i)
+ assert((*i)->exact());
+ }
+
+ if (a.size() == 1)
+ assert(equivalent(a.front()->getType(), b.front()->getType()));
+}
+
+app_list multimatch(env &e,
+ types::overloaded *o,
+ types::signature *source,
+ arglist &al)
+{
+ app_list a = exactMultimatch(e, o, source, al);
+ if (!a.empty()) {
+#if DEBUG_CACHE
+ // Make sure that exactMultimatch and the fallback return the same
+ // application(s).
+ sameApplications(a, inexactMultimatch(e, o, source, al), TEST_EXACT);
+#endif
+
+ return a;
+ }
+
+ a = halfExactMultimatch(e, o, source, al);
+ if (!a.empty()) {
+#if DEBUG_CACHE
+ sameApplications(a, inexactMultimatch(e, o, source, al), DONT_TEST_EXACT);
+#endif
+
+ return a;
+ }
+
+ // Slow but most general method.
+ return inexactMultimatch(e, o, source, al);
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/application.h b/graphics/asymptote/application.h
new file mode 100644
index 0000000000..8ca4296bd3
--- /dev/null
+++ b/graphics/asymptote/application.h
@@ -0,0 +1,313 @@
+/*****
+ * application.h
+ * Andy Hammerlindl 2005/05/20
+ *
+ * An application is a matching of arguments in a call expression to formal
+ * parameters of a function. Since the language allows default arguments,
+ * keyword arguments, rest arguments, and anything else we think of, this
+ * is not a simple mapping.
+ *****/
+
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+#include "common.h"
+#include "types.h"
+#include "coenv.h"
+#include "exp.h"
+
+// Defined in runtime.in:
+namespace run {
+ void pushDefault(vm::stack *Stack);
+}
+
+using absyntax::arglist;
+using absyntax::varinit;
+using absyntax::arrayinit;
+using absyntax::tempExp;
+
+// This is mid-way between trans and absyntax.
+namespace trans {
+
+typedef Int score;
+
+typedef mem::vector<score> score_vector;
+
+// This is used during the translation of arguments to store temporary
+// expressions for arguments that need to be translated for side-effects at a
+// certain point but used later on. The invariant maintained is that if the
+// vector has n elements, then the side-effects for the first n arguments have
+// been translated. Null is pushed onto the vector to indicate that the
+// expression was evaluated directly onto the stack, without the use of a
+// temporary.
+typedef mem::vector<tempExp *> temp_vector;
+
+struct arg : public gc {
+ types::ty *t;
+
+ arg(types::ty *t)
+ : t(t) {}
+ virtual ~arg() {}
+
+ virtual void trans(coenv &e, temp_vector &) = 0;
+};
+
+struct varinitArg : public arg {
+ varinit *v;
+
+ varinitArg(varinit *v, types::ty *t)
+ : arg(t), v(v) {}
+
+ virtual void trans(coenv &e, temp_vector &) {
+ // Open signatures can match overloaded variables, but there is no way to
+ // translate the result, so report an error.
+ if (t->kind == types::ty_overloaded) {
+ em.error(v->getPos());
+ em << "overloaded argument in function call";
+ }
+ else
+ v->transToType(e, t);
+ }
+};
+
+
+// Pushes a default argument token on the stack as a placeholder for the
+// argument.
+struct defaultArg : public arg {
+ defaultArg(types::ty *t)
+ : arg(t) {}
+
+ virtual void trans(coenv &e, temp_vector &) {
+ //e.c.encode(inst::builtin, run::pushDefault);
+ e.c.encode(inst::push_default);
+ }
+};
+
+// Handles translation of all the arguments matched to the rest formal.
+// NOTE: This code duplicates a lot of arrayinit.
+struct restArg : public gc {
+ mem::list<arg *> inits;
+
+ arg *rest;
+public:
+ restArg()
+ : rest(0) {}
+
+ virtual ~restArg()
+ {}
+
+ // Encodes the instructions to make an array from size elements on the stack.
+ static void transMaker(coenv &e, Int size, bool rest);
+
+ void trans(coenv &e, temp_vector &temps);
+
+ void add(arg *init) {
+ inits.push_back(init);
+ }
+
+ void addRest(arg *init) {
+ rest=init;
+ }
+};
+
+// This class generates sequenced args, args whose side-effects occur in order
+// according to their index, regardless of the order they are called. This is
+// used to ensure left-to-right order of evaluation of keyword arguments, even
+// if they are given out of the order specified in the declaration.
+class sequencer {
+ struct sequencedArg : public varinitArg {
+ sequencer &parent;
+ size_t i;
+ sequencedArg(varinit *v, types::ty *t, sequencer &parent, size_t i)
+ : varinitArg(v, t), parent(parent), i(i) {}
+
+ void trans(coenv &e, temp_vector &temps) {
+ parent.trans(e, i, temps);
+ }
+ };
+
+ typedef mem::vector<sequencedArg *> sa_vector;
+ sa_vector args;
+
+ // Makes a temporary for the next argument in the sequence.
+ void alias(coenv &e, temp_vector &temps) {
+ size_t n=temps.size();
+ assert(n < args.size());
+ sequencedArg *sa=args[n];
+ assert(sa);
+
+ temps.push_back(new tempExp(e, sa->v, sa->t));
+ }
+
+ // Get in a state to translate the i-th argument, aliasing any arguments that
+ // occur before it in the sequence.
+ void advance(coenv &e, size_t i, temp_vector &temps) {
+ while (temps.size() < i)
+ alias(e,temps);
+ }
+
+ void trans(coenv &e, size_t i, temp_vector &temps) {
+ if (i < temps.size()) {
+ // Already translated, use the alias.
+ assert(temps[i]);
+ temps[i]->trans(e);
+ }
+ else {
+ // Alias earlier args if necessary.
+ advance(e, i, temps);
+
+ // Translate using the base method.
+ args[i]->varinitArg::trans(e,temps);
+
+ // Push null to indicate the argument has been translated.
+ temps.push_back(0);
+ }
+ }
+
+public:
+ arg *addArg(varinit *v, types::ty *t, size_t i) {
+ if (args.size() <= i)
+ args.resize(i+1);
+ return args[i]=new sequencedArg(v, t, *this, i);
+ }
+};
+
+
+class application : public gc {
+ types::signature *sig;
+ types::function *t;
+
+ // Sequencer to ensure given arguments are evaluated in the proper order.
+ // Use of this sequencer means that transArgs can only be called once.
+ sequencer seq;
+
+ typedef mem::vector<arg *> arg_vector;
+ arg_vector args;
+ restArg *rest;
+
+ // Target formal to match with arguments to be packed into the rest array.
+ types::formal rf;
+
+ // During the matching of arguments to an application, this stores the index
+ // of the first unmatched formal.
+ size_t index;
+
+ // To resolve which is the best application in case of multiple matches of
+ // overloaded functions, a score is kept for every source argument matched,
+ // and an application with higher-scoring matches is chosen.
+ score_vector scores;
+
+ void initRest();
+
+ application(types::signature *sig)
+ : sig(sig),
+ t(0),
+ args(sig->formals.size()),
+ rest(0),
+ rf(0),
+ index(0)
+ { assert(sig); initRest(); }
+
+ application(types::function *t)
+ : sig(t->getSignature()),
+ t(t),
+ args(sig->formals.size()),
+ rest(0),
+ rf(0),
+ index(0)
+ { assert(sig); initRest(); }
+
+ types::formal &getTarget() {
+ return sig->getFormal(index);
+ }
+
+ // Move the index forward one, then keep going until we're at an unmatched
+ // argument.
+ void advanceIndex() {
+ do {
+ ++index;
+ } while (index < args.size() && args[index]!=0);
+ }
+
+ // Finds the first unmatched formal of the given name, returning the index.
+ // The rest formal is not tested. This function returns FAIL if no formals
+ // match.
+ Int find(symbol name);
+
+ // Match the formal at index to its default argument (if it has one).
+ bool matchDefault();
+
+ // Match the argument to the formal indexed by spot.
+ bool matchAtSpot(size_t spot, env &e, types::formal &source,
+ varinit *a, size_t evalIndex);
+
+ // Match the argument to be packed into the rest array, if possible.
+ bool matchArgumentToRest(env &e, types::formal& source,
+ varinit *a, size_t evalIndex);
+
+ // Matches the argument to a formal in the target signature (possibly causing
+ // other formals in the target to be matched to default values), and updates
+ // the matchpoint accordingly.
+ bool matchArgument(env &e, types::formal& source,
+ varinit *a, size_t evalIndex);
+
+ // Match an argument bound to a name, as in f(index=7).
+ bool matchNamedArgument(env &e, types::formal& source,
+ varinit *a, size_t evalIndex);
+
+ // After all source formals have been matched, checks if the match is
+ // complete (filling in final default values if necessary).
+ bool complete();
+
+ // Match a rest argument in the calling expression.
+ bool matchRest(env &e, types::formal& f, varinit *a, size_t evalIndex);
+
+ // Match the argument represented in signature to the target signature. On
+ // success, all of the arguments in args will be properly set up.
+ bool matchSignature(env &e, types::signature *source, arglist &al);
+
+ // Match a signature which is open, meaning that any sequence of arguments is
+ // matched.
+ bool matchOpen(env &e, signature *source, arglist &al);
+
+ friend class maximizer;
+public:
+ // Attempt to build an application given the target signature and the source
+ // signature (representing the given arguments). Return 0 if they cannot be
+ // matched.
+ static application *match(env &e,
+ types::function *t,
+ types::signature *source,
+ arglist &al);
+
+ // Translate the arguments so they appear in order on the stack in
+ // preparation for a call.
+ void transArgs(coenv &e);
+
+ types::function *getType() {
+ return t;
+ }
+
+ // This returns true in the special case that the arguments matched without
+ // casting or packing into the rest formal.
+ bool exact();
+
+ // The next best thing (score-wise) to an exact match. This returns true if
+ // there are two arguments, one of which is cast and one is matched exactly
+ // and neither are packed into the rest argument.
+ bool halfExact();
+};
+
+typedef mem::list<application *> app_list;
+
+// Given an overloaded list of types, determines which type to call. If none
+// are applicable, returns an empty vector, if there is ambiguity, several will
+// be returned.
+app_list multimatch(env &e,
+ types::overloaded *o,
+ types::signature *source,
+ arglist &al);
+
+} // namespace trans
+
+#endif
diff --git a/graphics/asymptote/arcball.cc b/graphics/asymptote/arcball.cc
new file mode 100644
index 0000000000..358195597a
--- /dev/null
+++ b/graphics/asymptote/arcball.cc
@@ -0,0 +1,237 @@
+/**********************************************************************
+
+ arcball.cc
+
+
+ --------------------------------------------------
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+ Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
+ Oct 2003, Nigel Stewart - GLUI Code Cleaning
+
+ WWW: http://sourceforge.net/projects/glui/
+ Forums: http://sourceforge.net/forum/?group_id=92496
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+**********************************************************************/
+
+#include "arcball.h"
+
+#include <cstdio>
+
+
+/**************************************** Arcball::Arcball() ****/
+/* Default (void) constructor for Arcball */
+
+Arcball::Arcball()
+{
+ rot_ptr = &rot;
+ init();
+}
+
+/**************************************** Arcball::Arcball() ****/
+/* Takes as argument a mat4 to use instead of the internal rot */
+
+Arcball::Arcball(mat4 *mtx)
+{
+ rot_ptr = mtx;
+}
+
+
+/**************************************** Arcball::Arcball() ****/
+/* A constructor that accepts the screen center and arcball radius*/
+
+Arcball::Arcball(const vec2 &_center, float _radius)
+{
+ rot_ptr = &rot;
+ init();
+ set_params(_center, _radius);
+}
+
+
+/************************************** Arcball::set_params() ****/
+
+void Arcball::set_params(const vec2 &_center, float _radius)
+{
+ center = _center;
+ radius = _radius;
+}
+
+/*************************************** Arcball::init() **********/
+
+void Arcball::init()
+{
+ center.set( 0.0, 0.0 );
+ radius = 1.0;
+ q_now = quat_identity();
+ *rot_ptr = identity3D();
+ q_increment = quat_identity();
+ rot_increment = identity3D();
+ is_mouse_down = false;
+ is_spinning = false;
+ damp_factor = 0.0;
+ zero_increment = true;
+}
+
+/*********************************** Arcball::mouse_to_sphere() ****/
+
+vec3 Arcball::mouse_to_sphere(const vec2 &p)
+{
+ float mag;
+ vec2 v2 = (p - center) / radius;
+ vec3 v3( v2[0], v2[1], 0.0 );
+
+ mag = v2*v2;
+
+ if ( mag > 1.0 )
+ v3.normalize();
+ else
+ v3[VZ] = (float) sqrt( 1.0 - mag );
+
+ /* Now we add constraints - X takes precedence over Y */
+ if ( constraint_x )
+ {
+ v3 = constrain_vector( v3, vec3( 1.0, 0.0, 0.0 ));
+ }
+ else if ( constraint_y )
+ {
+ v3 = constrain_vector( v3, vec3( 0.0, 1.0, 0.0 ));
+ }
+
+ return v3;
+}
+
+
+/************************************ Arcball::constrain_vector() ****/
+
+vec3 Arcball::constrain_vector(const vec3 &vector, const vec3 &axis)
+{
+ return (vector-(vector*axis)*axis).normalize();
+}
+
+/************************************ Arcball::mouse_down() **********/
+
+void Arcball::mouse_down(int x, int y)
+{
+ down_pt.set( (float)x, (float) y );
+ is_mouse_down = true;
+
+ q_increment = quat_identity();
+ rot_increment = identity3D();
+ zero_increment = true;
+}
+
+
+/************************************ Arcball::mouse_up() **********/
+
+void Arcball::mouse_up()
+{
+ q_now = q_drag * q_now;
+ is_mouse_down = false;
+}
+
+
+/********************************** Arcball::mouse_motion() **********/
+
+void Arcball::mouse_motion(int x, int y, int shift, int ctrl, int alt)
+{
+ /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
+ set_constraints( ctrl != 0, alt != 0 );
+
+ vec2 new_pt( (float)x, (float) y );
+ vec3 v0 = mouse_to_sphere( down_pt );
+ vec3 v1 = mouse_to_sphere( new_pt );
+
+ vec3 cross = v0^v1;
+
+ q_drag.set( cross, v0 * v1 );
+
+ // *rot_ptr = (q_drag * q_now).to_mat4();
+ mat4 temp = q_drag.to_mat4();
+ *rot_ptr = *rot_ptr * temp;
+
+ down_pt = new_pt;
+
+ /* We keep a copy of the current incremental rotation (= q_drag) */
+ q_increment = q_drag;
+ rot_increment = q_increment.to_mat4();
+
+ set_constraints(false, false);
+
+ if ( q_increment.s < .999999 )
+ {
+ is_spinning = true;
+ zero_increment = false;
+ }
+ else
+ {
+ is_spinning = false;
+ zero_increment = true;
+ }
+}
+
+
+/********************************** Arcball::mouse_motion() **********/
+
+void Arcball::mouse_motion(int x, int y)
+{
+ mouse_motion(x, y, 0, 0, 0);
+}
+
+
+/***************************** Arcball::set_constraints() **********/
+
+void Arcball::set_constraints(bool _constraint_x, bool _constraint_y)
+{
+ constraint_x = _constraint_x;
+ constraint_y = _constraint_y;
+}
+
+/***************************** Arcball::idle() *********************/
+
+void Arcball::idle()
+{
+ if (is_mouse_down)
+ {
+ is_spinning = false;
+ zero_increment = true;
+ }
+
+ if (damp_factor < 1.0f)
+ q_increment.scale_angle(1.0f - damp_factor);
+
+ rot_increment = q_increment.to_mat4();
+
+ if (q_increment.s >= .999999f)
+ {
+ is_spinning = false;
+ zero_increment = true;
+ }
+}
+
+
+/************************ Arcball::set_damping() *********************/
+
+void Arcball::set_damping(float d)
+{
+ damp_factor = d;
+}
+
+
+
+
+
diff --git a/graphics/asymptote/arcball.h b/graphics/asymptote/arcball.h
new file mode 100644
index 0000000000..58bc3a8c6a
--- /dev/null
+++ b/graphics/asymptote/arcball.h
@@ -0,0 +1,95 @@
+/**********************************************************************
+
+ arcball.h
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+ Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
+ Oct 2003, Nigel Stewart - GLUI Code Cleaning
+
+
+ WWW: http://sourceforge.net/projects/glui/
+ Forums: http://sourceforge.net/forum/?group_id=92496
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ---------------------------------------------------------------------
+
+ A C++ class that implements the Arcball, as described by Ken
+ Shoemake in Graphics Gems IV.
+ This class takes as input mouse events (mouse down, mouse drag,
+ mouse up), and creates the appropriate quaternions and 4x4 matrices
+ to represent the rotation given by the mouse.
+
+ This class is used as follows:
+ - initialize [either in the constructor or with set_params()], the
+ center position (x,y) of the arcball on the screen, and the radius
+ - on mouse down, call mouse_down(x,y) with the mouse position
+ - as the mouse is dragged, repeatedly call mouse_motion() with the
+ current x and y positions. One can optionally pass in the current
+ state of the SHIFT, ALT, and CONTROL keys (passing zero if keys
+ are not pressed, non-zero otherwise), which constrains
+ the rotation to certain axes (X for CONTROL, Y for ALT).
+ - when the mouse button is released, call mouse_up()
+
+ Axis constraints can also be explicitly set with the
+ set_constraints() function.
+
+ The current rotation is stored in the 4x4 float matrix 'rot'.
+ It is also stored in the quaternion 'q_now'.
+
+**********************************************************************/
+
+#ifndef GLUI_ARCBALL_H
+#define GLUI_ARCBALL_H
+
+#include "algebra3.h"
+#include "quaternion.h"
+
+class Arcball
+{
+public:
+ Arcball();
+ Arcball(mat4 *mtx);
+ Arcball(const vec2 &center, float radius);
+
+ void set_damping(float d);
+ void idle();
+ void mouse_down(int x, int y);
+ void mouse_up();
+ void mouse_motion(int x, int y, int shift, int ctrl, int alt);
+ void mouse_motion(int x, int y);
+ void set_constraints(bool constrain_x, bool constrain_y);
+ void set_params(const vec2 &center, float radius);
+ void init();
+
+ vec3 constrain_vector(const vec3 &vector, const vec3 &axis);
+ vec3 mouse_to_sphere(const vec2 &p);
+
+ //public:
+ int is_mouse_down; /* true for down, false for up */
+ int is_spinning;
+ quat q_now, q_down, q_drag, q_increment;
+ vec2 down_pt;
+ mat4 rot, rot_increment;
+ mat4 *rot_ptr;
+
+ bool constraint_x, constraint_y;
+ vec2 center;
+ float radius, damp_factor;
+ int zero_increment;
+};
+
+#endif
diff --git a/graphics/asymptote/array.cc b/graphics/asymptote/array.cc
new file mode 100644
index 0000000000..58c4371064
--- /dev/null
+++ b/graphics/asymptote/array.cc
@@ -0,0 +1,188 @@
+/*****
+ * array.cc
+ * Andy Hammerlindl 2008/01/26
+ *
+ * Array type used by virtual machine.
+ *****/
+
+#include "array.h"
+#include "mod.h"
+
+namespace vm {
+
+inline void checkBackSlice(Int left, Int right)
+{
+ if (right < left)
+ // There isn't a clear behaviour for slices of the form A[5:2], so we don't
+ // allow them. (Atleast, not until we can figure out what the behaviour
+ // should be.)
+ vm::error("slice ends before it begins");
+}
+
+inline size_t sliceIndex(Int in, size_t len) {
+ if (in < 0)
+ // The Python behaviour here would simply be
+ // in += len;
+ // but this is inconsistent with Asymptote issuing an error for A[-1] if A
+ // is a non-cyclic array, so we also issue an error here.
+ vm::error("invalid negative index in slice of non-cyclic array");
+ if (in < 0)
+ return 0;
+ size_t index = (size_t)in;
+ return index < len ? index : len;
+}
+
+array *array::slice(Int left, Int right)
+{
+ checkBackSlice(left, right);
+
+ if (left == right)
+ return new array();
+
+ size_t length=size();
+ if (length == 0)
+ return new array();
+
+ if (cycle) {
+ size_t resultLength = (size_t)(right - left);
+ array *result = new array(resultLength);
+
+ size_t i = (size_t)imod(left, length), ri = 0;
+ while (ri < resultLength) {
+ (*result)[ri] = (*this)[i];
+
+ ++ri;
+ ++i;
+ if (i >= length)
+ i -= length;
+ }
+
+ return result;
+ }
+ else { // Non-cyclic
+ size_t l = sliceIndex(left, length);
+ size_t r = sliceIndex(right, length);
+
+ size_t resultLength = r - l;
+ array *result = new array(resultLength);
+
+ std::copy(this->begin()+l, this->begin()+r, result->begin());
+
+ return result;
+ }
+}
+
+void array::setNonBridgingSlice(size_t l, size_t r, mem::vector<item> *a)
+{
+ assert(0 <= l);
+ assert(l <= r);
+
+ size_t asize=a->size();
+ if (asize == r-l) {
+ // In place
+ std::copy(a->begin(), a->end(), this->begin()+l);
+ }
+ else if (asize < r-l) {
+ // Shrinking
+ std::copy(a->begin(), a->end(), this->begin()+l);
+ this->erase(this->begin()+l+a->size(), this->begin()+r);
+ }
+ else {
+ // Expanding
+ // NOTE: As a speed optimization, we could check capacity() to see if the
+ // array can fit the new entries, and build the new array from scratch
+ // (using swap()) if a new allocation is necessary.
+ std::copy(a->begin(), a->begin()+r-l, this->begin()+l);
+ this->insert(this->begin()+r, a->begin()+r-l, a->end());
+ }
+}
+
+void array::setBridgingSlice(size_t l, size_t r, mem::vector<item> *a)
+{
+ size_t len=this->size();
+
+ assert(r<=l);
+ assert(r+len-l == a->size());
+
+ std::copy(a->begin(), a->begin()+(len-l), this->begin()+l);
+ std::copy(a->begin()+(len-l), a->end(), this->begin());
+}
+
+void array::setSlice(Int left, Int right, array *a)
+{
+ checkBackSlice(left, right);
+
+ // If we are slicing an array into itself, slice in a copy instead, to ensure
+ // the proper result.
+ mem::vector<item> *v = (a == this) ? new mem::vector<item>(*a) : a;
+
+ size_t length=size();
+ if (cycle) {
+ if (right == left) {
+ // Notice that assigning to the slice A[A.length:A.length] is the same as
+ // assigning to the slice A[0:0] for a cyclic array.
+ size_t l = (size_t)imod(left, length);
+ setNonBridgingSlice(l, l, v);
+ }
+ else {
+ if (left + (Int) length < right)
+ vm::error("assigning to cyclic slice with repeated entries");
+
+ size_t l = (size_t)imod(left, length);
+
+ // Set r to length instead of zero, so that slices that go to the end of
+ // the array are properly treated as non-bridging.
+ size_t r = (size_t)imod(right, length);
+ if (r == 0)
+ r = length;
+
+ if (l < r)
+ setNonBridgingSlice(l, r, v);
+ else {
+ if (r + length - l == v->size())
+ setBridgingSlice(l, r, v);
+ else
+ vm::error("assignment to cyclic slice is not well defined");
+ }
+ }
+ }
+ else {
+ size_t l=sliceIndex(left, length);
+ size_t r=sliceIndex(right, length);
+
+ setNonBridgingSlice(l, r, v);
+ }
+}
+
+item copyItemToDepth(item i, size_t depth)
+{
+ if (depth == 0)
+ return i;
+ else
+ return get<array *>(i)->copyToDepth(depth);
+}
+
+array *array::copyToDepth(size_t depth)
+{
+ if (depth == 0) {
+ return this;
+ } else {
+ size_t n=this->size();
+ array *a=new array(n);
+ a->cycle = this->cycle;
+
+ for (size_t i=0; i<n; ++i)
+ (*a)[i]=copyItemToDepth((*this)[i], depth-1);
+
+ return a;
+ }
+}
+
+array::array(size_t n, item i, size_t depth)
+ : mem::vector<item>(n), cycle(false)
+{
+ for (size_t k=0; k<n; ++k)
+ (*this)[k] = copyItemToDepth(i, depth);
+}
+
+} // namespace vm
diff --git a/graphics/asymptote/array.h b/graphics/asymptote/array.h
new file mode 100644
index 0000000000..58a97d7b25
--- /dev/null
+++ b/graphics/asymptote/array.h
@@ -0,0 +1,105 @@
+/*****
+ * array.h
+ * Tom Prince 2005/06/18
+ *
+ * Array type used by virtual machine.
+ *****/
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include "vm.h"
+#include "common.h"
+#include "item.h"
+
+namespace vm {
+
+// Arrays are vectors with push and pop functions.
+class array : public mem::vector<item> {
+ bool cycle;
+
+ void setNonBridgingSlice(size_t l, size_t r, mem::vector<item> *a);
+ void setBridgingSlice(size_t l, size_t r, mem::vector<item> *a);
+public:
+ array() : cycle(false) {}
+
+ array(size_t n)
+ : mem::vector<item>(n), cycle(false)
+ {}
+
+ array(size_t n, item i, size_t depth);
+
+ void push(item i)
+ {
+ push_back(i);
+ }
+
+ item pop()
+ {
+ item i=back();
+ pop_back();
+ return i;
+ }
+
+ template <typename T>
+ T read(size_t i) const
+ {
+ return get<T>((*this)[i]);
+ }
+
+ array *slice(Int left, Int right);
+ void setSlice(Int left, Int right, array *a);
+
+ void cyclic(bool b) {
+ cycle=b;
+ }
+
+ bool cyclic() const {
+ return cycle;
+ }
+
+ array *copyToDepth(size_t depth);
+};
+
+template <typename T>
+inline T read(const array *a, size_t i)
+{
+ return a->array::read<T>(i);
+}
+
+template <typename T>
+inline T read(const array &a, size_t i)
+{
+ return a.array::read<T>(i);
+}
+
+inline size_t checkArray(const vm::array *a)
+{
+ if(a == 0) vm::error("dereference of null array");
+ return a->size();
+}
+
+inline void checkEqual(size_t i, size_t j) {
+ if(i == j) return;
+ ostringstream buf;
+ buf << "operation attempted on arrays of different lengths: "
+ << i << " != " << j;
+ vm::error(buf);
+}
+
+inline size_t checkArrays(const vm::array *a, const vm::array *b)
+{
+ size_t asize=checkArray(a);
+ size_t bsize=checkArray(b);
+ checkEqual(asize,bsize);
+ return asize;
+}
+
+// Copies an item to a depth d. If d == 0 then the item is just returned
+// without copying, otherwise, the array and its subarrays are copied to
+// depth d.
+item copyItemToDepth(item i, size_t depth);
+
+} // namespace vm
+
+#endif // ARRAY_H
diff --git a/graphics/asymptote/arrayop.h b/graphics/asymptote/arrayop.h
new file mode 100644
index 0000000000..f63d8ae099
--- /dev/null
+++ b/graphics/asymptote/arrayop.h
@@ -0,0 +1,592 @@
+/*****
+ * arrayop
+ * John Bowman
+ *
+ * Array operations
+ *****/
+#ifndef ARRAYOP_H
+#define ARRAYOP_H
+
+#include "util.h"
+#include "stack.h"
+#include "array.h"
+#include "types.h"
+#include "fileio.h"
+#include "callable.h"
+#include "mathop.h"
+
+namespace run {
+
+using vm::pop;
+using vm::read;
+using vm::array;
+using camp::tab;
+
+vm::array *copyArray(vm::array *a);
+vm::array *copyArray2(vm::array *a);
+
+template<class T, class U, template <class S> class op>
+void arrayOp(vm::stack *s)
+{
+ U b=pop<U>(s);
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=op<T>()(read<T>(a,i),b,i);
+ s->push(c);
+}
+
+template<class T, class U, template <class S> class op>
+void opArray(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ T b=pop<T>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=op<U>()(b,read<U>(a,i),i);
+ s->push(c);
+}
+
+template<class T, template <class S> class op>
+void arrayArrayOp(vm::stack *s)
+{
+ array *b=pop<array*>(s);
+ array *a=pop<array*>(s);
+ size_t size=checkArrays(a,b);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=op<T>()(read<T>(a,i),read<T>(b,i),i);
+ s->push(c);
+}
+
+template<class T>
+void sumArray(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ T sum=0;
+ for(size_t i=0; i < size; i++)
+ sum += read<T>(a,i);
+ s->push(sum);
+}
+
+extern const char *arrayempty;
+
+template<class T, template <class S> class op>
+void binopArray(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ if(size == 0) vm::error(arrayempty);
+ T m=read<T>(a,0);
+ for(size_t i=1; i < size; i++)
+ m=op<T>()(m,read<T>(a,i));
+ s->push(m);
+}
+
+template<class T, template <class S> class op>
+void binopArray2(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ bool empty=true;
+ T m=0;
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ if(aisize) {
+ if(empty) {
+ m=read<T>(ai,0);
+ empty=false;
+ }
+ for(size_t j=0; j < aisize; j++)
+ m=op<T>()(m,read<T>(ai,j));
+ }
+ }
+ if(empty) vm::error(arrayempty);
+ s->push(m);
+}
+
+template<class T, template <class S> class op>
+void binopArray3(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ bool empty=true;
+ T m=0;
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ for(size_t j=0; j < aisize; j++) {
+ array *aij=read<array*>(ai,j);
+ size_t aijsize=checkArray(aij);
+ if(aijsize) {
+ if(empty) {
+ m=read<T>(aij,0);
+ empty=false;
+ }
+ for(size_t k=0; k < aijsize; k++) {
+ m=op<T>()(m,read<T>(aij,k));
+ }
+ }
+ }
+ }
+ if(empty) vm::error(arrayempty);
+ s->push(m);
+}
+
+template<class T, class U, template <class S> class op>
+void array2Op(vm::stack *s)
+{
+ U b=pop<U>(s);
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=op<T>()(read<T>(ai,j),b,0);
+ }
+ s->push(c);
+}
+
+template<class T, class U, template <class S> class op>
+void opArray2(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ T b=pop<T>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=op<U>()(read<U>(ai,j),b,0);
+ }
+ s->push(c);
+}
+
+template<class T, template <class S> class op>
+void array2Array2Op(vm::stack *s)
+{
+ array *b=pop<array*>(s);
+ array *a=pop<array*>(s);
+ size_t size=checkArrays(a,b);
+ array *c=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ array *ai=read<array*>(a,i);
+ array *bi=read<array*>(b,i);
+ size_t aisize=checkArrays(ai,bi);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=op<T>()(read<T>(ai,j),read<T>(bi,j),0);
+ }
+ s->push(c);
+}
+
+template<class T>
+bool Array2Equals(vm::stack *s)
+{
+ array *b=pop<array*>(s);
+ array *a=pop<array*>(s);
+ size_t n=checkArray(a);
+ if(n != checkArray(b)) return false;
+ if(n == 0) return true;
+ size_t n0=checkArray(read<array*>(a,0));
+ if(n0 != checkArray(read<array*>(b,0))) return false;
+
+ for(size_t i=0; i < n; ++i) {
+ array *ai=read<array*>(a,i);
+ array *bi=read<array*>(b,i);
+ for(size_t j=0; j < n0; ++j) {
+ if(read<T>(ai,j) != read<T>(bi,j))
+ return false;
+ }
+ }
+ return true;
+}
+
+template<class T>
+void array2Equals(vm::stack *s)
+{
+ s->push(Array2Equals<T>(s));
+}
+
+template<class T>
+void array2NotEquals(vm::stack *s)
+{
+ s->push(!Array2Equals<T>(s));
+}
+
+template<class T>
+void diagonal(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t n=checkArray(a);
+ array *c=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *ci=new array(n);
+ (*c)[i]=ci;
+ for(size_t j=0; j < i; ++j)
+ (*ci)[j]=T();
+ (*ci)[i]=read<T>(a,i);
+ for(size_t j=i+1; j < n; ++j)
+ (*ci)[j]=T();
+ }
+ s->push(c);
+}
+
+template<class T>
+struct compare {
+ bool operator() (const vm::item& a, const vm::item& b)
+ {
+ return vm::get<T>(a) < vm::get<T>(b);
+ }
+};
+
+template<class T>
+void sortArray(vm::stack *s)
+{
+ array *c=copyArray(pop<array*>(s));
+ sort(c->begin(),c->end(),compare<T>());
+ s->push(c);
+}
+
+template<class T>
+struct compare2 {
+ bool operator() (const vm::item& A, const vm::item& B)
+ {
+ array *a=vm::get<array*>(A);
+ array *b=vm::get<array*>(B);
+ size_t size=a->size();
+ if(size != b->size()) return false;
+
+ for(size_t j=0; j < size; j++) {
+ if(read<T>(a,j) < read<T>(b,j)) return true;
+ if(read<T>(a,j) > read<T>(b,j)) return false;
+ }
+ return false;
+ }
+};
+
+// Sort the rows of a 2-dimensional array by the first column, breaking
+// ties with successively higher columns.
+template<class T>
+void sortArray2(vm::stack *s)
+{
+ array *c=copyArray(pop<array*>(s));
+ stable_sort(c->begin(),c->end(),compare2<T>());
+ s->push(c);
+}
+
+// Search a sorted ordered array a of n elements for key, returning the index i
+// if a[i] <= key < a[i+1], -1 if key is less than all elements of a, or
+// n-1 if key is greater than or equal to the last element of a.
+template<class T>
+void searchArray(vm::stack *s)
+{
+ T key=pop<T>(s);
+ array *a=pop<array*>(s);
+ size_t size= a->size();
+ if(size == 0 || key < read<T>(a,0)) {s->push(-1); return;}
+ size_t u=size-1;
+ if(key >= read<T>(a,u)) {s->push((Int) u); return;}
+ size_t l=0;
+
+ while (l < u) {
+ size_t i=(l+u)/2;
+ if(key < read<T>(a,i)) u=i;
+ else if(key < read<T>(a,i+1)) {s->push((Int) i); return;}
+ else l=i+1;
+ }
+ s->push(0);
+}
+
+extern string emptystring;
+
+void writestring(vm::stack *s);
+
+template<class T>
+void write(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ vm::callable *suffix=pop<vm::callable *>(s,NULL);
+ T first=pop<T>(s);
+ string S=pop<string>(s,emptystring);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::ofile *f=defaultfile ? &camp::Stdout : vm::get<camp::ofile*>(it);
+ if(!f->isOpen() || !f->enabled()) return;
+
+ size_t size=checkArray(a);
+ if(S != "") f->write(S);
+ f->write(first);
+ for(size_t i=0; i < size; ++i) {
+ f->write(tab);
+ f->write(read<T>(a,i));
+ }
+ if(f->text()) {
+ if(suffix) {
+ s->push(f);
+ suffix->call(s);
+ } else if(defaultfile) {
+ try {
+ f->writeline();
+ } catch (quit&) {
+ }
+ }
+ }
+}
+
+template<class T>
+void writeArray(vm::stack *s)
+{
+ array *A=pop<array*>(s);
+ array *a=pop<array*>(s);
+ string S=pop<string>(s,emptystring);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::ofile *f=defaultfile ? &camp::Stdout : vm::get<camp::ofile*>(it);
+ if(!f->isOpen() || !f->enabled()) return;
+
+ size_t asize=checkArray(a);
+ size_t Asize=checkArray(A);
+ if(f->Standard()) interact::lines=0;
+ else if(!f->isOpen()) return;
+ try {
+ if(S != "") {f->write(S); f->writeline();}
+
+ size_t i=0;
+ bool cont=true;
+ while(cont) {
+ cont=false;
+ bool first=true;
+ if(i < asize) {
+ vm::item& I=(*a)[i];
+ if(defaultfile) cout << i << ":\t";
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ cont=true;
+ first=false;
+ }
+ unsigned count=0;
+ for(size_t j=0; j < Asize; ++j) {
+ array *Aj=read<array*>(A,j);
+ size_t Ajsize=checkArray(Aj);
+ if(i < Ajsize) {
+ if(f->text()) {
+ if(first && defaultfile) cout << i << ":\t";
+ for(unsigned k=0; k <= count; ++k)
+ f->write(tab);
+ count=0;
+ }
+ vm::item& I=(*Aj)[i];
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ cont=true;
+ first=false;
+ } else count++;
+ }
+ ++i;
+ if(cont && f->text()) f->writeline();
+ }
+ } catch (quit&) {
+ }
+ f->flush();
+}
+
+template<class T>
+void writeArray2(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::ofile *f=defaultfile ? &camp::Stdout : vm::get<camp::ofile*>(it);
+ if(!f->isOpen() || !f->enabled()) return;
+
+ size_t size=checkArray(a);
+ if(f->Standard()) interact::lines=0;
+
+ try {
+ for(size_t i=0; i < size; i++) {
+ vm::item& I=(*a)[i];
+ if(!I.empty()) {
+ array *ai=vm::get<array*>(I);
+ size_t aisize=checkArray(ai);
+ for(size_t j=0; j < aisize; j++) {
+ if(j > 0 && f->text()) f->write(tab);
+ vm::item& I=(*ai)[j];
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ }
+ }
+ if(f->text()) f->writeline();
+ }
+ } catch (quit&) {
+ }
+ f->flush();
+}
+
+template<class T>
+void writeArray3(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::ofile *f=defaultfile ? &camp::Stdout : vm::get<camp::ofile*>(it);
+ if(!f->isOpen() || !f->enabled()) return;
+
+ size_t size=checkArray(a);
+ if(f->Standard()) interact::lines=0;
+
+ try {
+ for(size_t i=0; i < size;) {
+ vm::item& I=(*a)[i];
+ if(!I.empty()) {
+ array *ai=vm::get<array*>(I);
+ size_t aisize=checkArray(ai);
+ for(size_t j=0; j < aisize; j++) {
+ vm::item& I=(*ai)[j];
+ if(!I.empty()) {
+ array *aij=vm::get<array*>(I);
+ size_t aijsize=checkArray(aij);
+ for(size_t k=0; k < aijsize; k++) {
+ if(k > 0 && f->text()) f->write(tab);
+ vm::item& I=(*aij)[k];
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ }
+ }
+ if(f->text()) f->writeline();
+ }
+ }
+ ++i;
+ if(i < size && f->text()) f->writeline();
+ }
+ } catch (quit&) {
+ }
+ f->flush();
+}
+
+template <class T, class S, T (*func)(S)>
+void arrayFunc(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=func(read<S>(a,i));
+ s->push(c);
+}
+
+template <class T, class S, T (*func)(S)>
+void arrayFunc2(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=func(read<S>(ai,j));
+ }
+ s->push(c);
+}
+
+vm::array *Identity(Int n);
+camp::triple operator *(const vm::array& a, const camp::triple& v);
+double norm(double *a, size_t n);
+double norm(camp::triple *a, size_t n);
+
+inline size_t checkdimension(const vm::array *a, size_t dim)
+{
+ size_t size=checkArray(a);
+ if(dim && size != dim) {
+ ostringstream buf;
+ buf << "array of length " << dim << " expected";
+ vm::error(buf);
+ }
+ return size;
+}
+
+template<class T>
+inline void copyArrayC(T* &dest, const vm::array *a, size_t dim=0,
+ GCPlacement placement=NoGC)
+{
+ size_t size=checkdimension(a,dim);
+ dest=(placement == NoGC) ? new T[size] : new(placement) T[size];
+ for(size_t i=0; i < size; i++)
+ dest[i]=vm::read<T>(a,i);
+}
+
+template<class T, class A>
+inline void copyArrayC(T* &dest, const vm::array *a, T (*cast)(A),
+ size_t dim=0, GCPlacement placement=NoGC)
+{
+ size_t size=checkdimension(a,dim);
+ dest=(placement == NoGC) ? new T[size] : new(placement) T[size];
+ for(size_t i=0; i < size; i++)
+ dest[i]=cast(vm::read<A>(a,i));
+}
+
+template<typename T>
+inline vm::array* copyCArray(const size_t n, const T* p)
+{
+ vm::array* a = new vm::array(n);
+ for(size_t i=0; i < n; ++i) (*a)[i] = p[i];
+ return a;
+}
+
+template<class T>
+inline void copyArray2C(T* &dest, const vm::array *a, bool square=true,
+ size_t dim2=0, GCPlacement placement=NoGC)
+{
+ size_t n=checkArray(a);
+ size_t m=(square || n == 0) ? n : checkArray(vm::read<vm::array*>(a,0));
+ if(n > 0 && dim2 && m != dim2) {
+ ostringstream buf;
+ buf << "second matrix dimension must be " << dim2;
+ vm::error(buf);
+ }
+
+ dest=(placement == NoGC) ? new T[n*m] : new(placement) T[n*m];
+ for(size_t i=0; i < n; i++) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t aisize=checkArray(ai);
+ if(aisize == m) {
+ T *desti=dest+i*m;
+ for(size_t j=0; j < m; j++)
+ desti[j]=vm::read<T>(ai,j);
+ } else
+ vm::error(square ? "matrix must be square" :
+ "matrix must be rectangular");
+ }
+}
+
+template<typename T>
+inline vm::array* copyCArray2(const size_t n, const size_t m, const T* p)
+{
+ vm::array* a=new vm::array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *ai=new array(m);
+ (*a)[i]=ai;
+ for(size_t j=0; j < m; ++j)
+ (*ai)[j]=p[m*i+j];
+ }
+ return a;
+}
+
+} // namespace run
+
+#endif // ARRAYOP_H
diff --git a/graphics/asymptote/aspy.py b/graphics/asymptote/aspy.py
new file mode 100644
index 0000000000..6b3fb3ec2e
--- /dev/null
+++ b/graphics/asymptote/aspy.py
@@ -0,0 +1,355 @@
+#####
+#
+# aspy.py
+#
+# Andy Hammerlindl 2011/09/03
+#
+# Uses ctypes to interface with the shared library version of Python.
+# Asymptote can run and its datatypes inspected via Python.
+#
+#
+# To use the module:
+# 1. make asymptote.so
+# 2. Ensure that asymptote.so is visable to python, say adding its directory
+# to LD_LIBRARY_PATH
+# 3. Run this module. (See runExample for an example.)
+#
+#####
+
+from ctypes import *
+
+asyInt = c_longlong
+handle_typ = c_void_p
+arguments_typ = c_void_p
+state_typ = c_void_p
+
+function_typ = CFUNCTYPE(None, state_typ, c_void_p)
+
+class string_typ(Structure):
+ _fields_ = [
+ ("buf", c_char_p), # Should be NUL-terminated? Maybe replace with
+ # POINTER(c_char).
+ ("length", asyInt)
+ ]
+
+ErrorCallbackFUNC = CFUNCTYPE(None, string_typ)
+
+NORMAL_ARG = 45000
+REST_ARG = 45001
+
+class Policy(Structure):
+ _fields_ = [
+ ("version", asyInt),
+ ("copyHandle", CFUNCTYPE(handle_typ, handle_typ)),
+ ("releaseHandle", CFUNCTYPE(None, handle_typ)),
+ ("handleFromInt", CFUNCTYPE(handle_typ, asyInt)),
+ ("handleFromBool", CFUNCTYPE(handle_typ, asyInt)),
+ ("handleFromDouble", CFUNCTYPE(handle_typ, c_double)),
+ ("handleFromString", CFUNCTYPE(handle_typ, string_typ)),
+ ("handleFromFunction", CFUNCTYPE(handle_typ,
+ c_char_p,
+ function_typ,
+ c_void_p)),
+ ("IntFromHandle", CFUNCTYPE(asyInt, handle_typ)),
+ ("boolFromHandle", CFUNCTYPE(asyInt, handle_typ)),
+ ("doubleFromHandle", CFUNCTYPE(c_double, handle_typ)),
+ ("stringFromHandle", CFUNCTYPE(string_typ, handle_typ)),
+ ("getField", CFUNCTYPE(handle_typ,
+ handle_typ,
+ c_char_p)),
+ ("getCell", CFUNCTYPE(handle_typ,
+ handle_typ,
+ asyInt)),
+ ("addField", CFUNCTYPE(None,
+ handle_typ,
+ c_char_p,
+ handle_typ)),
+ ("newArguments", CFUNCTYPE(arguments_typ)),
+ ("releaseArguments", CFUNCTYPE(None, arguments_typ)),
+ ("addArgument", CFUNCTYPE(None,
+ arguments_typ,
+ c_char_p,
+ handle_typ,
+ asyInt)),
+ ("call", CFUNCTYPE(handle_typ,
+ handle_typ,
+ arguments_typ)),
+ ("globals", CFUNCTYPE(handle_typ, state_typ)),
+ ("numParams", CFUNCTYPE(asyInt, state_typ)),
+ ("getParam", CFUNCTYPE(handle_typ, state_typ, asyInt)),
+ ("setReturnValue", CFUNCTYPE(None, state_typ, handle_typ)),
+ ("setErrorCallback", CFUNCTYPE(None, ErrorCallbackFUNC)),
+ ]
+
+policy = None
+baseState = None
+def initPolicyAndBaseState():
+ global policy, baseState
+ lib = CDLL("asymptote.so")
+
+ getPolicy = lib._asy_getPolicy
+ getPolicy.restype = POINTER(Policy)
+ policy = getPolicy()
+
+ getState = lib._asy_getState
+ getState.restype = state_typ
+ baseState = getState()
+
+initPolicyAndBaseState()
+
+def pyStringFromAsyString(st):
+ #TODO: Handle strings with null-terminators.
+ return str(st.buf)
+
+def pyStringFromHandle(h):
+ #TODO: Handle strings with null-terminators.
+ st = policy.contents.stringFromHandle(h)
+ checkForErrors()
+ return pyStringFromAsyString(st)
+
+def handleFromPyString(s):
+ st = string_typ(s, len(s))
+ h = policy.contents.handleFromString(st)
+ checkForErrors()
+ return h
+
+def ensureDatum(val):
+ return val if type(val) is Datum else Datum(val)
+
+# The error detection scheme.
+# policyError is set to a string when an error occurs.
+policyError = []
+def pyErrorCallback(s):
+ global policyError
+ policyError.append(pyStringFromAsyString(s))
+
+cErrorCallback = ErrorCallbackFUNC(pyErrorCallback)
+policy.contents.setErrorCallback(cErrorCallback)
+
+class AsyException(Exception):
+ def __init__(self, msg):
+ self.msg = msg
+ def __str__(self):
+ return self.msg
+
+def checkForErrors():
+ """Raises an exception if an error occured."""
+ global policyError
+ if policyError != []:
+ s = policyError[0]
+ if len(policyError) > 1:
+ s += ' (and other errors)'
+ policyError = []
+ raise AsyException(s)
+
+class Datum(object):
+
+ def _setHandle(self, handle):
+ object.__setattr__(self, 'handle', handle)
+
+ def __init__(self, val):
+ self._setHandle(0)
+
+ if val is None:
+ return
+
+ if type(val) is int:
+ self._setHandle(policy.contents.handleFromInt(val))
+ checkForErrors()
+ elif type(val) is bool:
+ self._setHandle(policy.contents.handleFromBool(1 if val else 0))
+ checkForErrors()
+ elif type(val) is float:
+ self._setHandle(policy.contents.handleFromDouble(val))
+ elif type(val) is str:
+ self._setHandle(handleFromPyString(val))
+ checkForErrors()
+ elif type(val) is tuple:
+ # Could do this more efficiently, and avoid a copyHandle
+ ret = state.globals()["operator tuple"](*val)
+ self._setHandle(policy.contents.copyHandle(ret.handle))
+ checkForErrors()
+ elif type(val) is Datum:
+ self._setHandle(policy.contents.copyHandle(val.handle))
+ checkForErrors()
+ else:
+ # TODO: check if val has a toDatum field
+ raise TypeError("cannot initialize Datum from '%s'" %
+ type(val).__name__)
+
+ def __repr__(self):
+ # TODO: Add type-checking to policy.
+ return '<Datum with handle %s>' % hex(self.handle)
+
+ def __int__(self):
+ l = policy.contents.IntFromHandle(self.handle)
+ checkForErrors()
+ return int(l)
+
+ def __nonzero__(self):
+ # This will throw an exception for anything but an underlying bool
+ # type. Perhaps we should be more pythonic.
+ l = policy.contents.boolFromHandle(self.handle)
+ checkForErrors()
+ assert l in [0,1]
+ return l == 1
+
+ def __float__(self):
+ x = policy.contents.doubleFromHandle(self.handle)
+ checkForErrors()
+ return float(x)
+
+ def __str__(self):
+ return pyStringFromHandle(self.handle)
+
+ def __getattr__(self, name):
+ field = policy.contents.getField(self.handle, name)
+ checkForErrors()
+ return DatumFromHandle(field)
+
+ def __getitem__(self, name):
+ assert type(name) == str
+ return self.__getattr__(name)
+ #TODO: raise an IndexError when appropriate.
+ #TODO: implement array indices
+
+ def __setattr__(self, name, val):
+ # TODO: Resolve setting versus declaring.
+ # One idea: d.x = f or d["x"] = f sets and d["int x()"] = f declares
+ # anew.
+ policy.contents.addField(self.handle,
+ name, ensureDatum(val).handle)
+ checkForErrors()
+
+ def __setitem__(self, name, val):
+ assert type(name) == str
+ self.__setattr__(name, val)
+ #TODO: raise an IndexError when appropriate.
+ #TODO: implement array indices
+
+ def __call__(self, *args, **namedArgs):
+ alist = policy.contents.newArguments()
+ checkForErrors()
+
+
+ for arg in args:
+ d = ensureDatum(arg)
+ policy.contents.addArgument(alist, "", d.handle, NORMAL_ARG)
+ checkForErrors()
+
+ for name,arg in namedArgs.items():
+ d = ensureDatum(arg)
+ policy.contents.addArgument(alist, name, d.handle, NORMAL_ARG)
+ checkForErrors()
+
+ ret = policy.contents.call(self.handle, alist)
+ checkForErrors()
+
+ policy.contents.releaseArguments(alist)
+ checkForErrors()
+
+ if ret != None:
+ return DatumFromHandle(ret)
+
+ def __add__(self, other):
+ return state.globals()["operator +"](self, other)
+ def __sub__(self, other):
+ return state.globals()["operator -"](self, other)
+ def __mul__(self, other):
+ return state.globals()["operator *"](self, other)
+ def __div__(self, other):
+ return state.globals()["operator /"](self, other)
+ def __truediv__(self, other):
+ return state.globals()["operator /"](self, other)
+ def __mod__(self, other):
+ return state.globals()["operator %"](self, other)
+ def __pow__(self, other):
+ return state.globals()["operator ^"](self, other)
+ def __and__(self, other):
+ return state.globals()["operator &"](self, other)
+ def __or__(self, other):
+ return state.globals()["operator |"](self, other)
+ def __neg__(self, other):
+ return state.globals()["operator -"](self)
+
+ def __lt__(self, other):
+ return state.globals()["operator <"](self, other)
+ def __le__(self, other):
+ return state.globals()["operator <="](self, other)
+ def __eq__(self, other):
+ return state.globals()["operator =="](self, other)
+ def __ne__(self, other):
+ return state.globals()["operator !="](self, other)
+ def __gt__(self, other):
+ return state.globals()["operator >"](self, other)
+ def __ge__(self, other):
+ return state.globals()["operator >="](self, other)
+
+def DatumFromHandle(handle):
+ """Initializes a Datum from a given low-level handle. Does not invoke
+ copyHandle."""
+ d = Datum(None)
+ d._setHandle(handle)
+ return d
+
+class State(object):
+ def __init__(self, base):
+ self.base = base
+
+ def globals(self):
+ handle = policy.contents.globals(self.base)
+ checkForErrors()
+ return DatumFromHandle(handle)
+
+ def params(self):
+ p = []
+
+ numParams = policy.contents.numParams(self.base)
+ checkForErrors()
+
+ for i in range(numParams):
+ h = policy.contents.getParam(self.base, i)
+ checkForErrors()
+ p.append(DatumFromHandle(h))
+
+ assert len(p) == numParams
+ return p
+
+ def setReturnValue(self, val):
+ policy.contents.setReturnValue(self.base, ensureDatum(val).handle)
+ checkForErrors()
+
+# Keep a link to all of the callbacks created, so they aren't garbage
+# collected. TODO: See if this is neccessary.
+storedCallbacks = []
+
+def DatumFromCallable(f):
+ def wrapped(s, d):
+ state = State(s)
+ params = state.params()
+ r = f(*params)
+ if r != None:
+ state.setReturnValue(r)
+
+ cf = function_typ(wrapped)
+ storedCallbacks.append(cf)
+
+ h = policy.contents.handleFromFunction(f.__name__, cf, None)
+ checkForErrors()
+
+ return DatumFromHandle(h)
+
+print "version", policy.contents.version
+
+state = State(baseState)
+
+# An example
+def runExample():
+ g = state.globals()
+
+ g.eval("path p = (0,0) -- (100,100) -- (200,0)", embedded=True)
+ g.draw(g.p)
+ g.shipout("frompython")
+
+ g.draw(g.circle(100), g.red)
+
diff --git a/graphics/asymptote/asy-keywords.el b/graphics/asymptote/asy-keywords.el
new file mode 100644
index 0000000000..5cf87e595b
--- /dev/null
+++ b/graphics/asymptote/asy-keywords.el
@@ -0,0 +1,17 @@
+;;
+;; This file is automatically generated by asy-list.pl.
+;; Changes will be overwritten.
+;;
+(defvar asy-keywords-version "2.53")
+
+(defvar asy-keyword-name '(
+and controls tension atleast curl if else while for do return break continue struct typedef new access import unravel from include quote static public private restricted this explicit true false null cycle newframe operator ))
+
+(defvar asy-type-name '(
+Braid FitResult Label Legend Solution TreeNode abscissa arc arrowhead binarytree binarytreeNode block bool bool3 bounds bqe circle conic coord coordsys cputime ellipse evaluatedpoint file filltype frame grid3 guide horner hsv hyperbola int inversion key light line linefit marginT marker mass node object pair parabola patch path path3 pen picture point position positionedvector projection rational real revolution scaleT scientific segment side simplex slice solution splitface string surface tensionSpecifier ticklocate ticksgridT tickvalues transform transformation tree triangle trilinear triple vector vertex void ))
+
+(defvar asy-function-name '(
+AND Arc ArcArrow ArcArrows Arrow Arrows AtA Automatic AvantGarde B03 B13 B23 B33 BBox BWRainbow BWRainbow2 Bar Bars BeginArcArrow BeginArrow BeginBar BeginDotMargin BeginMargin BeginPenMargin Blank Bookman Bottom BottomTop Bounds Break Broken BrokenLog CLZ CTZ Ceil Circle CircleBarIntervalMarker Cos Courier CrossIntervalMarker DOSendl DOSnewl DefaultFormat DefaultLogFormat Degrees Dir DotMargin DotMargins Dotted Draw Drawline Embed EndArcArrow EndArrow EndBar EndDotMargin EndMargin EndPenMargin Fill FillDraw Floor Format Full Gaussian Gaussrand Gaussrandpair Gradient Grayscale Helvetica Hermite HookHead InOutTicks InTicks Jn Label Landscape Left LeftRight LeftTicks Legend Linear Log LogFormat Margin Margins Mark MidArcArrow MidArrow NOT NewCenturySchoolBook NoBox NoMargin NoModifier NoTicks NoTicks3 NoZero NoZeroFormat None OR OmitFormat OmitTick OmitTickInterval OmitTickIntervals OutTicks Ox Oy Palatino PaletteTicks Pen PenMargin PenMargins Pentype Portrait RGB RadialShade RadialShadeDraw Rainbow Range Relative Right RightTicks Rotate Round SQR Scale ScaleX ScaleY ScaleZ Seascape Shift Sin Slant Spline StickIntervalMarker Straight Symbol Tan TeXify Ticks Ticks3 TildeIntervalMarker TimesRoman Top TrueMargin UnFill UpsideDown Wheel X XEquals XOR XY XYEquals XYZero XYgrid XZEquals XZZero XZero XZgrid Y YEquals YXgrid YZ YZEquals YZZero YZero YZgrid Yn Z ZX ZXgrid ZYgrid ZapfChancery ZapfDingbats _begingroup3 _cputime _draw _eval _findroot _image _labelpath _projection _shipout _strokepath _texpath aCos aSin aTan abort abs accel acos acosh acot acsc activatequote add addArrow addMargins addSaveFunction addpenarc addpenline addseg adjust alias align all altitude angabscissa angle angledegrees angpoint animate annotate anticomplementary antipedal apply approximate arc arcarrowsize arccircle arcdir arcfromcenter arcfromfocus arclength arcnodesnumber arcpoint arcsubtended arcsubtendedcenter arctime arctopath array arrow arrow2 arrowbase arrowbasepoints arrowsize ascii asec asin asinh ask assert asy asycode asydir asyfigure asyfilecode asyinclude asywrite atan atan2 atanh atbreakpoint atexit attach attract atupdate autoformat autoscale autoscale3 axes axes3 axialshade axis axiscoverage azimuth babel background bangles bar barmarksize barsize basealign baseline bbox beep begin beginclip begingroup beginpoint between bevel bezier bezierP bezierPP bezierPPP bezulate bibliography bibliographystyle binarytree binarytreeNode binomial bins bisector bisectorpoint bispline bitreverse blend blockconnector box bqe brace breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor byte calculateScaling canonical canonicalcartesiansystem cartesiansystem case1 case2 case3 cbrt cd ceil center centerToFocus centroid cevian change2 changecoordsys checkSegment check_fpt_zero checkconditionlength checker checkincreasing checklengths checkposition checkpt checkptincube checktriangle choose circle circlebarframe circlemarkradius circlenodesnumber circumcenter circumcircle clamped clear clip clipdraw close cmyk code colatitude collect collinear color colorless colors colorspace comma compassmark complement complementary concat concurrent cone conic conicnodesnumber conictype conj connect containmentTree contains contour contour3 controlSpecifier convert coordinates coordsys copy copyPairOrTriple cos cosh cot countIntersections cputime crop cropcode cross crossframe crosshatch crossmarksize csc cubicroots curabscissa curlSpecifier curpoint currentarrow currentexitfunction currentmomarrow currentpolarconicroutine curve cut cutafter cutbefore cyclic cylinder deactivatequote debugger deconstruct defaultdir defaultformat defaultpen defined degenerate degrees delete deletepreamble determinant diagonal diamond diffdiv dir dirSpecifier dirtime display distance divisors do_overpaint dot dotframe dotsize downcase draw drawAll drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPRCcylinder drawPRCdisk drawPRCsphere drawPRCtube drawPhoton drawScalar drawVertex drawVertexBox drawVertexBoxO drawVertexBoxX drawVertexO drawVertexOX drawVertexTriangle drawVertexTriangleO drawVertexX drawarrow drawarrow2 drawbeziertriangle drawline drawpixel drawstrokepath drawtick duplicate elle ellipse ellipsenodesnumber embed embed3 embedplayer empty enclose end endclip endgroup endgroup3 endl endpoint endpoints eof eol equation equations erase erasestep erf erfc error errorbar errorbars eval excenter excircle exit exitfunction exp expfactors expi expm1 exradius extend extension extouch fabs factorial fermat fft fhorner figure file filecode fill filldraw filloutside fillrule filltype find findall findroot finite finiteDifferenceJacobian firstcut firstframe fit fit2 fixedscaling floor flush fmdefaults fmod focusToCenter font fontcommand fontsize foot format frac frequency fromCenter fromFocus fspline functionshade gamma gcd generate_random_backtrace generateticks gergonne getc getint getpair getreal getstring gettriple gluon gouraudshade graph graphic graphicscale gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image implicitsurface incenter incentral incircle increasing incrementposition indexedfigure initdefaults initialized input inradius insert inside insphere integrate interactive interior interp interpolate intersect intersection intersectionpoint intersectionpoints intersections intouch inverse inversion invisible is3D isDuplicate isnan isogonal isogonalconjugate isotomic isotomicconjugate isparabola italic item jobname key kurtosis kurtosisexcess label labelaxis labelmargin labelpath labels labeltick labelx labelx3 labely labely3 labelz labelz3 lastcut latex latitude latticeshade layer layout lcm ldexp leastsquares legend legenditem length lexorder lift light limits line linear linecap lineinversion linejoin linemargin lineskip linetype linewidth link list lm_enorm lm_evaluate_default lm_lmdif lm_lmpar lm_minimize lm_print_default lm_print_quiet lm_qrfac lm_qrsolv locale locate locatefile location log log10 log1p logaxiscoverage longitude lookup make3dgrid makeMappingArray makeNode makecircle makedraw makepen maketriangle map margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markthin markuniform mass masscenter massformat math max max3 maxAfterTransform maxbezier maxbound maxcoords maxlength maxratio maxtimes mean medial median midpoint min min3 minAfterTransform minbezier minbound minipage minratio mintimes miterlimit mktemp momArrowPath momarrowsize monotonic multifigure nGrad nativeformat natural newl newpage newslide newton newtree nextframe nextnormal nextpage nib nodabscissa node none norm normalout normalvideo nosetpagesize notaknot nowarn numberpage nurb object offset onpath opacity opposite orient orientation origin orthic orthocentercenter outformat outline outname outprefix output overloadedMessage overwrite pack pad pairs palette parabola parabolanodesnumber parallel parallelogram partialsum patchwithnormals path path3 pathbetween pathinface pattern pause pdf pedal periodic perp perpendicular perpendicularmark phantom phi1 phi2 phi3 photon piecewisestraight point polar polarconicroutine polargraph polygon popcount postcontrol postscript pow10 ppoint prc prc0 prconly precision precontrol prepend printBytecode print_random_addresses progress project projection projecttospan projecttospan_findcoeffs purge pwhermite quadpatches quadrant quadraticroots quantize quarticroots quotient radialshade radians radicalcenter radicalline radius rand randompath rationalidentity rd readline realmult realquarticroots rectangle rectangular rectify reflect relabscissa relative relativedistance reldir relpoint reltime remainder remark removeDuplicates rename replace report resetdefaultpen restore restoredefaults reverse reversevideo rf rfind rgb rgba rgbint rms rotate rotateO rotation round roundbox roundedpath roundrectangle samecoordsys sameside sample save savedefaults saveline scale scale3 scaleO scaleT scaleless scientific search searchtree sec secondaryX secondaryY seconds section sector seek seekeof segment segmentlimits sequence setpens sgn sgnd sharpangle sharpdegrees shift shiftless shipout shipout3 show simeq simplex simplexPhase2 simplexTableau simplexWrite simpson sin sinh size size3 skewness skip slant sleep slice slope slopefield solve solveBVP sort sourceline sphere split sqrt square srand standardizecoordsys stdev step stickframe stickmarksize stickmarkspace stop straight straightness string stripdirectory stripextension stripfile stripsuffix strokepath subdivide subitem subpath substr sum surface symmedial symmedian system tab tableau tan tangent tangential tangents tanh tell tensionSpecifier tensorshade tex texcolor texify texpath texpreamble texreset texshipout texsize texstring textpath thick thin tick tickMax tickMax3 tickMin tickMin3 ticklabelshift ticklocate tildeframe tildemarksize tile tiling time times title titlepage topbox toplocation transform transformation transpose trembleFuzz triangle triangleAbc triangleabc triangletoquads trianglewithnormals triangulate tricoef tridiagonal trilinear trim truepoint tube uncycle unfill uniform unique unit unitrand unitsize unityroot unstraighten upcase updatefunction uperiodic upscale uptodate usepackage usersetting usetypescript usleep value variance variancebiased vbox vector vectorfield verbatim view vline vperiodic vprojection warn warning windingnumber write xasyKEY xaxis xaxis3 xaxis3At xaxisAt xequals xlimits xmap xpart xscale xscaleO xtick xtick3 xtrans yaxis yaxis3 yaxis3At yaxisAt yequals ylimits ypart yscale yscaleO ytick ytick3 ytrans zaxis3 zaxis3At zero zlimits zpart ztick ztick3 ztrans ))
+
+(defvar asy-variable-name '(
+Accent AliceBlue Align Allow AntiqueWhite Apricot Aqua Aquamarine Aspect Azure BeginPoint Beige Bisque Bittersweet Black BlanchedAlmond Blue BlueGreen BlueViolet Blues Both BrBG Break BrickRed Brown BuGn BuPu BurlyWood BurntOrange CCW CMRmap CW CadetBlue CarnationPink Center Centered Cerulean Chartreuse Chocolate Coeff Coral CornflowerBlue Cornsilk Crimson Crop Cyan Dandelion Dark2 DarkBlue DarkCyan DarkGoldenrod DarkGray DarkGreen DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkTurquoise DarkViolet DeepPink DeepSkyBlue DefaultHead DimGray DodgerBlue Dotted Down Draw E ENE EPS ESE E_Euler E_PC E_RK2 E_RK3BS Emerald EndPoint Euler Fill FillDraw FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite GnBu Gold Goldenrod Gray Green GreenYellow Greens Greys Honeydew HookHead Horizontal HotPink I IgnoreAspect IndianRed Indigo Ivory JOIN_IN JOIN_OUT JungleGreen Khaki LM_DWARF LM_MACHEP LM_SQRT_DWARF LM_SQRT_GIANT LM_USERTOL Label Lavender LavenderBlush LawnGreen Left LeftJustified LeftSide LemonChiffon LightBlue LightCoral LightCyan LightGoldenrodYellow LightGreen LightGrey LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray LightSteelBlue LightYellow Lime LimeGreen Linear Linen Log Logarithmic Magenta Mahogany Mark MarkFill MarkPath Maroon Max MediumAquamarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed Melon MidPoint MidnightBlue Min MintCream MistyRose Moccasin Move MoveQuiet Mulberry N NE NNE NNW NULL_VERTEX NW NavajoWhite Navy NavyBlue NoAlign NoCrop NoFill NoSide OldLace Olive OliveDrab OliveGreen OrRd Orange OrangeRed Oranges Orchid Ox Oy PC PRGn Paired PaleGoldenrod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip Pastel1 Pastel2 Peach PeachPuff Periwinkle Peru PiYG PineGreen Pink Plum PowderBlue ProcessBlue PuBu PuBuGn PuOr PuRd Purple Purples RK2 RK3 RK3BS RK4 RK5 RK5DP RK5F RawSienna RdBu RdGy RdPu RdYlBu RdYlGn Red RedOrange RedViolet Reds Rhodamine Right RightJustified RightSide RosyBrown RoyalBlue RoyalPurple RubineRed S SE SSE SSW SW SaddleBrown Salmon SandyBrown SeaGreen Seashell Sepia Set1 Set2 Set3 Sienna Silver SimpleHead SkyBlue SlateBlue SlateGray Snow Spectral SpringGreen SteelBlue Suppress SuppressQuiet Tan TeXHead Teal TealBlue Thistle Ticksize Tomato Turquoise UnFill Up VERSION Value Vertical Violet VioletRed W WNW WSW Wheat White WhiteSmoke WildStrawberry XHIGH XLOW XYAlign YAlign YHIGH YLOW Yellow YellowGreen YellowOrange YlGn YlGnBu YlOrBr YlOrRd ZHIGH ZLOW _outpipe aboveequationskip addpenarc addpenline align allowstepping angularsystem animationdelay appendsuffix arcarrowangle arcarrowfactor arrow2sizelimit arrowangle arrowbarb arrowdir arrowfactor arrowhookfactor arrowlength arrowsizelimit arrowtexfactor authorpen autumn axis axiscoverage axislabelfactor background backgroundcolor backgroundpen barfactor barmarksizefactor basealign baselinetemplate bernstein beveljoin bigvertexpen bigvertexsize binary black blue bm bone bottom bp bracedefaultratio braceinnerangle bracemidangle braceouterangle brg brown bullet bwr byfoci byvertices camerafactor chartreuse circlemarkradiusfactor circlenodesnumberfactor circleprecision circlescale cividis cm codefile codepen codeskip colorPen coloredNodes coloredSegments conditionlength conicnodesfactor cool coolwarm copper count cputimeformat crossmarksizefactor currentcoordsys currentlight currentpatterns currentpen currentpicture currentposition currentprojection curvilinearsystem cuttings cyan darkblue darkbrown darkcyan darkgray darkgreen darkgrey darkmagenta darkolive darkred dashdotted dashed datepen dateskip debuggerlines debugging deepblue deepcyan deepgray deepgreen deepgrey deepmagenta deepred deepyellow default defaultControl defaultS defaultbackpen defaultcoordsys defaultexcursion defaultfilename defaultformat defaultmassformat defaultpen defaultseparator differentlengths dot dotfactor dotfilltype dotframe dotted doublelinepen doublelinespacing down duplicateFuzz ellipsenodesnumberfactor eps epsgeo epsilon evenodd expansionfactor extendcap fermionpen figureborder figuremattpen file3 firstnode firststep foregroundcolor fuchsia fuzz gapfactor ghostpen gist_earth gist_ncar gist_stern gluonamplitude gluonpen gluonratio gray green grey hatchepsilon havepagenumber heavyblue heavycyan heavygray heavygreen heavygrey heavymagenta heavyred hline hot hsv hwratio hyperbolanodesnumberfactor identity identity4 ignore implicitshipout inch inches includegraphicscommand inf inferno infinity institutionpen intMax intMin invert invisible itempen itemskip itemstep jet labelmargin landscape lastnode left legendhskip legendlinelength legendmargin legendmarkersize legendmaxrelativewidth legendvskip lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightolive lightred lightyellow linemargin lm_infmsg lm_shortmsg longdashdotted longdashed magenta magma magneticRadius mantissaBits markangleradius markangleradiusfactor markanglespace markanglespacefactor maxrefinements mediumblue mediumcyan mediumgray mediumgreen mediumgrey mediummagenta mediumred mediumyellow middle minDistDefault minblockheight minblockwidth mincirclediameter minipagemargin minipagewidth minvertexangle miterjoin mm momarrowfactor momarrowlength momarrowmargin momarrowoffset momarrowpen monoPen morepoints nCircle nan newbulletcolor ngraph nil nipy_spectral nmesh nobasealign nodeMarginDefault nodesystem nomarker nopoint noprimary nullpath nullpen numarray ocgindex oldbulletcolor olive orange origin overpaint page pageheight pagemargin pagenumberalign pagenumberpen pagenumberposition pagewidth paleblue palecyan palegray palegreen palegrey palemagenta palered paleyellow parabolanodesnumberfactor perpfactor phi photonamplitude photonpen photonratio pi pink plain plain_bounds plain_scaling plasma plus preamblenodes pt purple r3 r4a r4b randMax realDigits realEpsilon realMax realMin red relativesystem reverse right roundcap roundjoin royalblue salmon saveFunctions scalarpen seismic sequencereal settings signedtrailingzero simplex solid spinner spring springgreen sqrtEpsilon squarecap squarepen startposition stdin stdout stepfactor stepfraction steppagenumberpen stepping stickframe stickmarksizefactor stickmarkspacefactor summer swap tab10 tab20 tab20b tab20c textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom twilight twilight_shifted undefined unitcircle unitsquare up urlpen urlskip version vertexpen vertexsize viewportmargin viewportsize viridis vline white winter wistia wye yellow ylabelwidth zeroTransform zerotickfuzz zerowinding ))
diff --git a/graphics/asymptote/asy-list.pl b/graphics/asymptote/asy-list.pl
new file mode 100755
index 0000000000..4206adc480
--- /dev/null
+++ b/graphics/asymptote/asy-list.pl
@@ -0,0 +1,106 @@
+#!/usr/bin/env perl
+#####
+# asy-list.pl
+#
+# Build asy-keywords.el from list of asy global functions and variables
+#
+#####
+
+open(keywords, "> asy-keywords.el") ||
+ die("Couldn't open asy-keywords.el for writing.");
+
+print keywords <<END;
+;;
+;; This file is automatically generated by asy-list.pl.
+;; Changes will be overwritten.
+;;
+(defvar asy-keywords-version "$ARGV[1]")
+
+END
+
+sub add {
+ print keywords $_[0]." ";
+}
+
+sub openlist {
+ open(asylist, $ARGV[0]) || die("Couldn't open $ARGV[0]");
+}
+
+print keywords <<END;
+(defvar asy-keyword-name '(
+END
+
+open(camp, "camp.l") || die("Couldn't open camp.l");
+
+# Search for the %% separator, after which the definitions start.
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # Break out of the loop.
+ }
+}
+
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # A second %% indicates the end of definitions.
+ }
+ if (/^(\w+)\s*\{/) {
+ add($1);
+ }
+}
+
+openlist();
+
+while (<asylist>) {
+ if (/^(\w*)[^ ]* (\w*)\(.*/) {
+ push @types, $1;
+ push @functions, $2;
+ }
+ if (/^([^ ]*) (\w*);/) {
+ push @variables, $2;
+ }
+}
+
+@saw{@types} = ();
+@types = sort keys %saw;
+undef %saw;
+
+@saw{@functions} = ();
+@functions = sort keys %saw;
+undef %saw;
+
+@saw{@variables} = ();
+@variables = sort keys %saw;
+undef %saw;
+
+print keywords <<END;
+))
+
+(defvar asy-type-name '(
+END
+
+foreach(@types) {
+ print keywords $_ . " ";
+}
+
+print keywords <<END;
+))
+
+(defvar asy-function-name '(
+END
+
+foreach(@functions) {
+ print keywords $_ . " ";
+}
+
+print keywords <<END;
+))
+
+(defvar asy-variable-name '(
+END
+
+foreach(@variables) {
+ print keywords $_ . " ";
+}
+
+print keywords "))\n";
+
diff --git a/graphics/asymptote/asy.ico b/graphics/asymptote/asy.ico
new file mode 100644
index 0000000000..f9c89bc2be
--- /dev/null
+++ b/graphics/asymptote/asy.ico
Binary files differ
diff --git a/graphics/asymptote/asy.list b/graphics/asymptote/asy.list
new file mode 100644
index 0000000000..566f365a90
--- /dev/null
+++ b/graphics/asymptote/asy.list
@@ -0,0 +1,3934 @@
+string stripfile(string s);
+string stripsuffix(string f, string suffix=<default>);
+real cbrt(real x);
+real[] cbrt(real[] a);
+pen RGB(int r, int g, int b);
+cputime cputime();
+string stripdirectory(string s);
+real sqrtEpsilon;
+string stripextension(string s);
+version version;
+void nosetpagesize();
+void texpreamble(string s);
+pen beveljoin;
+string cputimeformat;
+real Cos(real deg);
+string insert(string s, int pos, string t);
+marginT EndDotMargin(path, pen);
+pen heavyred;
+pen black;
+pen heavyblue;
+filltype dotfilltype;
+pen heavygreen;
+pen heavycyan;
+marginT PenMargin(path, pen)(real begin, real end);
+marginT PenMargin(path, pen);
+int realDigits;
+pen heavymagenta;
+marginT PenMargins(path, pen);
+void newl(file file);
+void seek(file f, int pos);
+string verbatim(string s);
+pen heavygray;
+pen heavygrey;
+void markuniform(picture pic=<default>, frame f, path g)(pair z(real t), real a, real b, int n);
+void markuniform(picture pic=<default>, frame f, path g)(bool centered=<default>, int n, bool rotated=<default>);
+real[] mintimes(path p);
+real[] mintimes(path3 p);
+bool straight(path p, int t);
+bool straight(path3 p, int t);
+pen makepen(path p);
+real dotsize(pen p=<default>);
+real[] curlSpecifier(guide g, int t);
+real straightness(path3 p, int t);
+real straightness(triple z0, triple c0, triple c1, triple z1);
+real log10(real x);
+real[] log10(real[] a);
+pen paleblue;
+bool prc0(string format=<default>);
+string xasyKEY();
+void xasyKEY(string s);
+int CTZ(int a);
+void _shipout(string prefix=<default>, frame f, frame preamble=<default>, string format=<default>, bool wait=<default>, bool view=<default>, transform t=<default>);
+real barfactor;
+pen Magenta;
+real cos(real x);
+real[] cos(real[] a);
+pair cos(explicit pair z);
+int intMax;
+bool cyclic(guide g);
+bool cyclic(path p);
+bool cyclic(path3 p);
+void printBytecode(<open>);
+transform Rotate(transform)(pair z);
+transform Rotate(transform t);
+path subpath(path p, int a, int b);
+path subpath(path p, real a, real b);
+path3 subpath(path3 p, int a, int b);
+path3 subpath(path3 p, real a, real b);
+bool isnan(real x);
+string jobname(string name);
+void print_random_addresses(int n=<default>);
+void attach(picture dest=<default>, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void attach(picture dest=<default>, frame src, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+real[] quadraticroots(real a, real b, real c);
+pair[] quadraticroots(explicit pair a, explicit pair b, explicit pair c);
+pen darkcyan;
+string[] file3;
+real[] maxtimes(path p);
+real[] maxtimes(path3 p);
+filltype FillDraw;
+filltype FillDraw(real xmargin=<default>, real ymargin=<default>, pen fillpen=<default>, pen drawpen=<default>);
+void initdefaults();
+void erase(frame f);
+string erase(string s, int pos, int n);
+void erase(picture pic=<default>);
+pair E;
+int Ceil(real x);
+pair I;
+pair SSW;
+pen magenta;
+pair WSW;
+pair N;
+bool view();
+void usersetting();
+pair S;
+void nowarn(string s);
+transform rotate(real angle, pair z=<default>);
+int quotient(int x, int y);
+transform rotation(transform t);
+pair W;
+int rand();
+pen ZapfChancery(string series=<default>, string shape=<default>);
+int XOR(int a, int b);
+void atupdate(void f());
+void atupdate()();
+void unfill(frame f, path[] g, bool copy=<default>);
+void unfill(picture pic=<default>, path[] g, bool copy=<default>);
+bool Bar(picture, path, pen, marginT(path, pen))(real size=<default>);
+bool Bar(picture, path, pen, marginT(path, pen));
+bool eol(file f);
+pen zerowinding;
+void atbreakpoint(string f(string, int, int, code));
+void savedefaults()();
+bool MidArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
+bool MidArrow(picture, path, pen, marginT(path, pen));
+bool MidArcArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
+bool MidArcArrow(picture, path, pen, marginT(path, pen));
+void grestore(frame f);
+pair extension(pair p, pair q, pair p, pair q);
+pen extendcap;
+int ceil(real x);
+pen thick(pen p=<default>);
+pair left;
+int Suppress;
+file input(string name=<default>, bool check=<default>, string comment=<default>, string mode=<default>);
+int SuppressQuiet;
+real[] texsize(string s, pen p=<default>);
+string nativeformat();
+bool invisible(pen p);
+pen invisible();
+pen invisible;
+bool CCW;
+void usetypescript(string s, string encoding=<default>);
+path randompath(int n, bool cumulate=<default>, guide join(... guide[])=<default>);
+int system(string[] s);
+int system(string s);
+void bar(picture pic, pair a, pair d, pen p=<default>);
+picture bar(pair a, pair d, pen p=<default>);
+side NoSide;
+file stdout;
+transform Shift(transform t);
+real fmod(real x, real y);
+real offset(pen p);
+pen rgb(pen p);
+pen rgb(real r, real g, real b);
+pen rgb(string s);
+real inch;
+bool ArcArrow(picture, path, pen, marginT(path, pen));
+bool ArcArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
+bool ArcArrows(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
+bool ArcArrows(picture, path, pen, marginT(path, pen));
+pen currentpen;
+pair precontrol(path p, int t);
+pair precontrol(path p, real t);
+triple precontrol(path3 p, int t);
+triple precontrol(path3 p, real t);
+light currentlight;
+pen royalblue;
+picture currentpicture;
+frame currentpatterns;
+int JOIN_IN;
+int JOIN_OUT;
+projection currentprojection;
+real orient(pair a, pair b, pair c);
+real orient(triple a, triple b, triple c, triple d);
+pen linetype(real[] pattern, real offset=<default>, bool scale=<default>, bool adjust=<default>);
+real[] linetype(pen p=<default>);
+pen linetype(string pattern, real offset=<default>, bool scale=<default>, bool adjust=<default>);
+real xpart(pair z);
+real xpart(triple v);
+side Center;
+real ypart(pair z);
+real ypart(triple v);
+real zpart(triple v);
+frame orientation(frame);
+pen Courier(string series=<default>, string shape=<default>);
+real simpson(real f(real), real a, real b, real acc=<default>, real dxmax=<default>);
+transform shift(transform t);
+transform shift(pair z);
+transform shift(real x, real y);
+transform shift(frame f, pair align);
+real asinh(real x);
+real[] asinh(real[] a);
+pen orange;
+pen darkgray;
+slice lastcut(path p, path knife);
+pen darkgreen;
+pen darkgrey;
+transform xscale(real x);
+transform shiftless(transform t);
+real[][] shiftless(real[][] t);
+transform yscale(real y);
+void usleep(int microseconds);
+real cosh(real x);
+real[] cosh(real[] a);
+position MidPoint;
+real Sin(real deg);
+void assert(bool b, string s=<default>);
+pen Palatino(string series=<default>, string shape=<default>);
+real incircle(pair a, pair b, pair c, pair d);
+frame Landscape(frame f);
+pen purple;
+string italic(string s);
+real atan(real x);
+real[] atan(real[] a);
+real acos(real x);
+real[] acos(real[] a);
+int popcount(int a);
+pair minbound(pair a, pair b);
+triple minbound(triple a, triple b);
+pair minbound(pair[] a);
+pair minbound(pair[][] a);
+pair minbound(pair[][][] a);
+triple minbound(triple[] a);
+triple minbound(triple[][] a);
+triple minbound(triple[][][] a);
+void restore();
+pen basealign(int n);
+int basealign(pen p=<default>);
+pen basealign;
+int min(int a, int b);
+int[] min(int a, int[] b);
+int[] min(int[] a, int b);
+int[] min(int[] a, int[] b);
+int min(int[] a);
+int min(int[][] a);
+int min(int[][][] a);
+real min(real a, real b);
+real[] min(real a, real[] b);
+real[] min(real[] a, real b);
+real[] min(real[] a, real[] b);
+real min(real[] a);
+real min(real[][] a);
+real min(real[][][] a);
+string min(string a, string b);
+string[] min(string a, string[] b);
+string[] min(string[] a, string b);
+string[] min(string[] a, string[] b);
+string min(string[] a);
+string min(string[][] a);
+string min(string[][][] a);
+pair min(pen p);
+pair min(frame f);
+pair min(explicit path p);
+pair min(path[] p);
+triple min(path3 p);
+pair min(picture pic, bool user=<default>);
+real min(... real[] a);
+real min(real m, scaling s, coord[] c);
+real min(real m, scaling s, coord[] c);
+int min(... int[] a);
+filltype RadialShade(pen penc, pen penr);
+int search(int[] a, int key);
+int search(real[] a, real key);
+int search(string[] a, string key);
+int search(void()()[] a, void key()(), bool less(void()(), void()()));
+int search(picture[] a, picture key, bool less(picture, picture));
+int search(real[] a, real key, bool less(real, real));
+int search(guide[] a, guide key, bool less(guide, guide));
+int search(object[] a, object key, bool less(object, object));
+int search(pair[] a, pair key, bool less(pair, pair));
+int search(coord[] a, coord key, bool less(coord, coord));
+int search(Label[] a, Label key, bool less(Label, Label));
+int search(frame[] a, frame key, bool less(frame, frame));
+int search(coord[] a, coord key, bool less(coord, coord));
+int search(Legend[] a, Legend key, bool less(Legend, Legend));
+int search(int[] a, int key, bool less(int, int));
+int search(bool3[] a, bool3 key, bool less(bool3, bool3));
+int search(string[] a, string key, bool less(string, string));
+int search(path[] a, path key, bool less(path, path));
+int search(pen[] a, pen key, bool less(pen, pen));
+int search(bool[] a, bool key, bool less(bool, bool));
+int search(triple[] a, triple key, bool less(triple, triple));
+int search(marker[] a, marker key, bool less(marker, marker));
+filltype RadialShadeDraw(real xmargin=<default>, real ymargin=<default>, pen penc, pen penr, pen drawpen=<default>);
+real sin(real x);
+real[] sin(real[] a);
+pair sin(explicit pair z);
+pen deepcyan;
+void restoredefaults();
+path[] plus;
+pair expi(real angle);
+triple expi(real polar, real azimuth);
+void endclip(frame f);
+void endclip(picture pic=<default>);
+pen opacity(real opacity=<default>, string blend=<default>);
+real opacity(pen p);
+real[] solve(real[][] a, real[] b, bool warn=<default>);
+real[][] solve(real[][] a, real[][] b, bool warn=<default>);
+int rename(string from, string to);
+void DOSendl(file file);
+string debugger(string file, int line, int column, code s=<default>);
+string getc(file f);
+bool debugging;
+void shipout(string prefix=<default>, frame f, string format=<default>, bool wait=<default>, bool view=<default>, string options=<default>, string script=<default>, light light=<default>, projection P=<default>, transform t=<default>);
+void shipout(string prefix=<default>, picture pic=<default>, frame orientation(frame)=<default>, string format=<default>, bool wait=<default>, bool view=<default>, string options=<default>, string script=<default>, light light=<default>, projection P=<default>);
+void shipout3(string prefix, frame f, string format=<default>, real width, real height, real angle, real zoom, triple m, triple m, pair shift, real[][] t, real[] background, triple[] lights, real[][] diffuse, real[][] specular, bool view=<default>);
+void shipout3(string prefix, frame f);
+string getstring(string name=<default>, string default=<default>, string prompt=<default>, bool store=<default>);
+int debuggerlines;
+frame bbox(picture pic=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>);
+real radians(real degrees);
+bool pdf();
+void _eval(string s, bool embedded, bool interactivewrite=<default>);
+void _eval(code s, bool embedded);
+path[][] textpath(string[] s, pen[] p);
+void radialshade(frame f, path[] g, bool stroke=<default>, pen pena, pair a, real ra, bool extenda=<default>, pen penb, pair b, real rb, bool extendb=<default>, bool copy=<default>);
+void radialshade(picture pic=<default>, path[] g, bool stroke=<default>, pen pena, pair a, real ra, bool extenda=<default>, pen penb, pair b, real rb, bool extendb=<default>, bool copy=<default>);
+pair maxbound(pair a, pair b);
+triple maxbound(triple a, triple b);
+pair maxbound(pair[] a);
+pair maxbound(pair[][] a);
+pair maxbound(pair[][][] a);
+triple maxbound(triple[] a);
+triple maxbound(triple[][] a);
+triple maxbound(triple[][][] a);
+string Embed(string name, string text=<default>, string options=<default>, real width=<default>, real height=<default>);
+pair postcontrol(path p, int t);
+pair postcontrol(path p, real t);
+triple postcontrol(path3 p, int t);
+triple postcontrol(path3 p, real t);
+int max(int a, int b);
+int[] max(int a, int[] b);
+int[] max(int[] a, int b);
+int[] max(int[] a, int[] b);
+int max(int[] a);
+int max(int[][] a);
+int max(int[][][] a);
+real max(real a, real b);
+real[] max(real a, real[] b);
+real[] max(real[] a, real b);
+real[] max(real[] a, real[] b);
+real max(real[] a);
+real max(real[][] a);
+real max(real[][][] a);
+string max(string a, string b);
+string[] max(string a, string[] b);
+string[] max(string[] a, string b);
+string[] max(string[] a, string[] b);
+string max(string[] a);
+string max(string[][] a);
+string max(string[][][] a);
+pair max(pen p);
+pair max(frame f);
+pair max(explicit path p);
+pair max(path[] p);
+triple max(path3 p);
+real max(real M, scaling s, coord[] c);
+int max(... int[] a);
+pair max(picture pic, bool user=<default>);
+real max(... real[] a);
+real max(real M, scaling s, coord[] c);
+Label Label(Label L, pair position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label(string s, string size=<default>, explicit position position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label(Label L, explicit position position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label(explicit pair position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label;
+Label Label(string s=<default>, string size=<default>, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label(string s, string size=<default>, pair position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label(Label L, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+string font(pen p=<default>);
+pen font(string name, string options=<default>);
+pen font(string encoding, string family, string series, string shape);
+pen font(string name, real size, string options=<default>);
+marker markthin(path g, pen p=<default>, real thin(real fraction)=<default>, filltype filltype=<default>);
+int intMin;
+pen white;
+side RightSide;
+string replace(string s, string[][] translate);
+string replace(string s, string before, string after);
+transform fixedscaling(picture pic=<default>, pair min, pair max, pen p=<default>, bool warn=<default>);
+pen Symbol(string series=<default>, string shape=<default>);
+slice firstcut(path p, path knife);
+pen squarecap;
+pen squarepen;
+pen deepyellow;
+real barsize(pen p=<default>);
+bool EndArrow(picture, path, pen, marginT(path, pen));
+bool EndArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
+bool EndArcArrow(picture, path, pen, marginT(path, pen));
+bool EndArcArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
+void tensorshade(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[][] p, path[] b=<default>, pair[][] z=<default>, bool copy=<default>);
+void tensorshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[][] p, path[] b=<default>, pair[][] z=<default>, bool copy=<default>);
+void tensorshade(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, path b=<default>, pair[] z);
+void tensorshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, path b=<default>, pair[] z);
+void tensorshade(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, path b=<default>);
+void tensorshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, path b=<default>);
+string[] split(string s, string delimiter=<default>);
+void addSaveFunction(void s()());
+object embed3(string, frame, string, string, string, light, projection);
+filltype NoFill;
+real colatitude(triple v, bool warn=<default>);
+void label(frame f, string s, string size, transform t, pair position, pair align, pen p);
+void label(picture pic=<default>, Label L, align align=<default>, pen p=<default>, filltype filltype=<default>);
+void label(pair origin, picture pic=<default>, Label L, align align=<default>, pen p=<default>, filltype filltype=<default>);
+void label(frame f, Label L, pair position, align align=<default>, pen p=<default>, filltype filltype=<default>);
+void label(picture pic=<default>, Label L, pair position, align align=<default>, pen p=<default>, filltype filltype=<default>);
+void label(frame f, Label L, align align=<default>, pen p=<default>, filltype filltype=<default>);
+void label(picture pic=<default>, Label L, explicit guide g, align align=<default>, pen p=<default>, filltype filltype=<default>);
+void label(picture pic=<default>, Label L, explicit path g, align align=<default>, pen p=<default>, filltype filltype=<default>);
+real fabs(real x);
+real[] fabs(real[] a);
+bool labels(frame f);
+light light(pen diffuse=<default>, pen specular=<default>, pen background=<default>, real x, real y, real z);
+light light(pen diffuse=<default>, pen specular=<default>, pen background=<default>, real specularfactor=<default> ... triple[] position);
+light light(explicit light light);
+light light(pen[] diffuse, pen[] specular=<default>, pen background=<default>, real specularfactor=<default>, triple[] position);
+real remainder(real x, real y);
+int byte(real x);
+real camerafactor;
+pen lightred;
+real labelmargin;
+real labelmargin(pen p=<default>);
+pen lightblue;
+pen lightgreen;
+pair right;
+string outformat(string format=<default>);
+pen lightcyan;
+pen lightmagenta;
+pen lightyellow;
+pen lightgray;
+pen lightolive;
+pen lightgrey;
+string upcase(string s);
+pen darkblue;
+pen darkbrown;
+path[] strokepath(path g, pen p=<default>);
+real erf(real x);
+void saveline(string name, string value, bool store=<default>);
+pen fuchsia;
+filltype filltype(int type=<default>, pen fillpen=<default>, pen drawpen=<default>, void fill2(frame f, path[] g, pen fillpen));
+pen Bookman(string series=<default>, string shape=<default>);
+path box(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+path box(frame f, Label L, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+path box(pair a, pair b);
+frame[] fit(string prefix=<default>, picture[] pictures, string format=<default>, bool view=<default>, string options=<default>, string script=<default>, projection P=<default>);
+void seekeof(file f);
+path unitcircle;
+pair[] conj(pair[] a);
+pair[][] conj(pair[][] a);
+pair conj(pair z);
+pen deepgray;
+pen deepgreen;
+pen deepgrey;
+marker[] Mark;
+marker Mark(int n);
+real aTan(real x);
+void _begingroup3(frame f, string name, real compression, real granularity, bool closed, bool tessellate, bool dobreak, bool nobreak, triple center, int interaction);
+path[] MarkPath;
+string graphic(string name, string options=<default>);
+real aCos(real x);
+void texreset();
+string graphicscale(real x);
+int[] complement(int[] a, int n);
+path[] complement(frame f, path[] g);
+pen Cyan;
+marginT NoMargin(path, pen);
+marginT NoMargin(path, pen)();
+path[][] _texpath(string[] s, pen[] p);
+real sinh(real x);
+real[] sinh(real[] a);
+real[] _cputime();
+position EndPoint;
+hsv hsv(real h, real s, real v);
+hsv hsv(pen p);
+void deconstruct(frame f, frame preamble=<default>, transform t=<default>);
+void deconstruct(picture pic=<default>);
+int sgn(real x);
+node node(void d(frame f, transform t, transform T, pair lb, pair rt), string key=<default>);
+pair minAfterTransform(transform t, path[] p);
+int seconds(string t=<default>, string format=<default>);
+pen cyan;
+pen grey;
+real cm;
+filltype Fill;
+filltype Fill(real xmargin=<default>, real ymargin=<default>, pen p=<default>);
+pen olive;
+pen darkolive;
+int ascii(string s);
+real arcarrowangle;
+real arcarrowfactor;
+real mm;
+real arcarrowsize(pen p=<default>);
+real calculateScaling(string dir, coord[] coords, real size, bool warn=<default>);
+real calculateScaling(string dir, coord[] coords, real size, bool warn=<default>);
+real calculateScaling(string dir, coord[] m, coord[] M, real size, bool warn=<default>);
+real calculateScaling(string dir, coord[] m, coord[] M, real size, bool warn=<default>);
+triple gettriple(string name=<default>, triple default=<default>, string prompt=<default>, bool store=<default>);
+void drawpixel(frame f, triple v, pen p, real width=<default>);
+pen fontsize(real size, real lineskip);
+real fontsize(pen p=<default>);
+pen fontsize(real size);
+void close(file f);
+real lineskip(pen p=<default>);
+pen dashed;
+pair maxAfterTransform(transform t, path[] p);
+int[][] triangulate(pair[] z);
+void fill(frame f, path[] g, pen p=<default>, bool copy=<default>);
+path fill(frame dest, frame src, filltype filltype=<default>, real xmargin=<default>, real ymargin=<default>);
+void fill(picture pic=<default>, path[] g, pen p=<default>, bool copy=<default>);
+void fill(pair origin, picture pic=<default>, path[] g, pen p=<default>);
+pair midpoint(path p);
+real exp(real x);
+real[] exp(real[] a);
+pair exp(explicit pair z);
+pen linejoin(int n);
+int linejoin(pen p=<default>);
+real ldexp(real x, int e);
+pen rgba(real[] a);
+real[] rgba(pen p);
+string time(string format=<default>);
+string time(int seconds, string format=<default>);
+void prepend(frame dest, frame src);
+real pt;
+settings settings;
+int MoveQuiet;
+marginT EndMargin(path, pen);
+pen nullpen;
+side LeftSide;
+path nullpath;
+guide[] copy(guide[] a, int depth=<default>);
+real[] copy(real[] a, int depth=<default>);
+triple[] copy(triple[] a, int depth=<default>);
+bool[] copy(bool[] a, int depth=<default>);
+real[][] copy(real[][] a, int depth=<default>);
+pen[] copy(pen[] a, int depth=<default>);
+coord[] copy(coord[] a, int depth=<default>);
+object[] copy(object[] a, int depth=<default>);
+marker[] copy(marker[] a, int depth=<default>);
+Legend[] copy(Legend[] a, int depth=<default>);
+pen[][] copy(pen[][] a, int depth=<default>);
+path[] copy(path[] a, int depth=<default>);
+string[] copy(string[] a, int depth=<default>);
+void()()[] copy(void()()[] a, int depth=<default>);
+int[] copy(int[] a, int depth=<default>);
+string[][] copy(string[][] a, int depth=<default>);
+frame[] copy(frame[] a, int depth=<default>);
+pair[] copy(pair[] a, int depth=<default>);
+bool3[] copy(bool3[] a, int depth=<default>);
+coord[] copy(coord[] a, int depth=<default>);
+Label[] copy(Label[] a, int depth=<default>);
+picture[] copy(picture[] a, int depth=<default>);
+pair[][] copy(pair[][] a, int depth=<default>);
+real[] abs(pair[] a);
+real[] abs(triple[] a);
+real abs(real x);
+real[] abs(real[] a);
+real abs(pair z);
+real abs(triple v);
+int abs(int x);
+pen pink;
+real inches;
+path ellipse(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+path ellipse(frame f, Label L, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+path ellipse(pair c, real a, real b);
+pair getpair(string name=<default>, pair default=<default>, string prompt=<default>, bool store=<default>);
+void axialshade(frame f, path[] g, bool stroke=<default>, pen pena, pair a, bool extenda=<default>, pen penb, pair b, bool extendb=<default>, bool copy=<default>);
+void axialshade(picture pic=<default>, path[] g, bool stroke=<default>, pen pena, pair a, bool extenda=<default>, pen penb, pair b, bool extendb=<default>, bool copy=<default>);
+string locale(string s=<default>);
+real dirtime(path p, pair z);
+void copyPairOrTriple(pairOrTriple dest, pairOrTriple src);
+real[] colors(pen p);
+void filloutside(picture pic=<default>, path[] g, pen p=<default>, bool copy=<default>);
+void filloutside(frame f, path[] g, pen p=<default>, bool copy=<default>);
+pen[] colorPen;
+real _findroot(real f(real), real a, real b, real tolerance, real fa, real fb);
+pen colorless(pen p);
+pen solid;
+string colorspace(pen p);
+void warn(string s);
+pen deepblue;
+pen palered;
+real[] map(real f(pair), pair[] a);
+int[] map(int f(real), real[] a);
+bool3[] map(bool3 f(bool3), bool3[] a);
+frame[] map(frame f(frame), frame[] a);
+coord[] map(coord f(coord), coord[] a);
+Legend[] map(Legend f(Legend), Legend[] a);
+pen[][] map(pen[] f(pen[]), pen[][] a);
+triple[] map(triple f(triple), triple[] a);
+pen[] map(pen f(pen), pen[] a);
+coord[] map(coord f(coord), coord[] a);
+Label[] map(Label f(Label), Label[] a);
+pair[] map(pair f(pair), pair[] a);
+object[] map(object f(object), object[] a);
+string[] map(string f(string), string[] a);
+picture[] map(picture f(picture), picture[] a);
+void()()[] map(void f()()(void()()), void()()[] a);
+pair[][] map(pair[] f(pair[]), pair[][] a);
+real[] map(real f(real), real[] a);
+marker[] map(marker f(marker), marker[] a);
+int[] map(int f(int), int[] a);
+string[][] map(string[] f(string[]), string[][] a);
+bool[] map(bool f(bool), bool[] a);
+path[] map(path f(path), path[] a);
+real[][] map(real[] f(real[]), real[][] a);
+guide[] map(guide f(guide), guide[] a);
+path unstraighten(path p);
+path3 unstraighten(path3 p);
+void _image(frame f, real[][] data, pair initial, pair final, pen[] palette=<default>, transform t=<default>, bool copy=<default>, bool antialias=<default>);
+void _image(frame f, pen[][] data, pair initial, pair final, transform t=<default>, bool copy=<default>, bool antialias=<default>);
+void _image(frame f, pen f(int, int), int width, int height, pair initial, pair final, transform t=<default>, bool antialias=<default>);
+pair arcpoint(path p, real L);
+pen Pen(int n);
+int rfind(string s, string t, int pos=<default>);
+pair minratio(frame f);
+pair minratio(triple[][] p, pair b);
+pair minratio(path3 g);
+string toplocation();
+int[] sequence(int n);
+pen[][] sequence(pen[] f(int), int n);
+coord[] sequence(coord f(int), int n);
+object[] sequence(object f(int), int n);
+marker[] sequence(marker f(int), int n);
+Legend[] sequence(Legend f(int), int n);
+int[] sequence(int f(int), int n);
+string[][] sequence(string[] f(int), int n);
+pair[] sequence(pair f(int), int n);
+guide[] sequence(guide f(int), int n);
+pen[] sequence(pen f(int), int n);
+void()()[] sequence(void f()()(int), int n);
+bool[] sequence(bool f(int), int n);
+string[] sequence(string f(int), int n);
+pair[][] sequence(pair[] f(int), int n);
+bool3[] sequence(bool3 f(int), int n);
+coord[] sequence(coord f(int), int n);
+Label[] sequence(Label f(int), int n);
+picture[] sequence(picture f(int), int n);
+real[][] sequence(real[] f(int), int n);
+real[] sequence(real f(int), int n);
+int[] sequence(int n, int m);
+triple[] sequence(triple f(int), int n);
+path[] sequence(path f(int), int n);
+frame[] sequence(frame f(int), int n);
+triple minbezier(triple[][] p, triple b);
+path trim(path g, real begin, real end);
+marginT DotMargin(path, pen)(real begin, real end);
+marginT DotMargin(path, pen);
+marginT DotMargins(path, pen);
+string string(int x);
+string string(real x, int digits=<default>);
+string cd(string s=<default>);
+int size(guide g);
+pair size(frame f);
+int size(path p);
+int size(path[] p);
+int size(path3 p);
+void size(picture dest, picture src);
+pair size(picture pic, bool user=<default>);
+void size(picture pic=<default>, transform t);
+void size(picture pic=<default>, real x, real y=<default>, bool keepAspect=<default>);
+void size(picture pic=<default>, real xsize, real ysize, pair min, pair max);
+void clear(file f);
+void clear(string file, int line);
+void clear();
+void clear(string file, string text);
+pen mediumred;
+pen mediumblue;
+pen mediumgreen;
+pen mediumcyan;
+pen mediummagenta;
+pair arcdir(path p, real L);
+pen mediumyellow;
+pen mediumgray;
+string downcase(string s);
+pen mediumgrey;
+transform transform(pen p);
+string readline(string prompt=<default>, string name=<default>, bool tabcompletion=<default>);
+void beep();
+pair relpoint(path p, real l);
+pair[][] transpose(pair[][] a);
+pen[][] transpose(pen[][] a);
+string[][] transpose(string[][] a);
+real[][] transpose(real[][] a);
+pen overwrite(int n);
+int overwrite(pen p=<default>);
+pen linewidth(real x);
+real linewidth(pen p=<default>);
+transformation transformation(real[][] modelview);
+transformation transformation(real[][] modelview, real[][] projection);
+pair maxratio(frame f);
+pair maxratio(triple[][] p, pair b);
+pair maxratio(path3 g);
+triple maxbezier(triple[][] p, triple b);
+void layer(frame f);
+void layer(picture pic=<default>);
+void DOSnewl(file file);
+pen cmyk(pen p);
+pen cmyk(real c, real m, real y, real k);
+pen blue;
+pen evenodd;
+int precision(file f=<default>, int digits=<default>);
+path3 path3(triple[] pre, triple[] point, triple[] post, bool[] straight, bool cyclic);
+bool piecewisestraight(path p);
+bool piecewisestraight(path3 p);
+void stop(string file, int line, code s=<default>);
+void stop(string file, string text, code s=<default>);
+pair reldir(path p, real l);
+pen TimesRoman(string series=<default>, string shape=<default>);
+slice cut(path p, path knife, int n);
+bool is3D(frame f);
+bool is3D(string format=<default>);
+void add(frame dest, frame src);
+void add(picture dest=<default>, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(frame dest, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture src, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture pic=<default>, void d(frame f, transform t), bool exact=<default>);
+void add(picture pic=<default>, void d(picture, real[][]), bool exact=<default>);
+void add(picture dest, picture src, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture dest, picture src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture dest=<default>, object F, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(frame dest, frame src, filltype filltype, bool above=<default>);
+void add(frame dest, frame src, bool group, filltype filltype=<default>, bool above=<default>);
+void add(picture pic=<default>, void d(frame f, real[][] t, picture pic, projection P), bool exact=<default>);
+void add(frame dest, frame src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture dest=<default>, frame src, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture pic=<default>, Label L);
+void add(picture pic=<default>, void d(picture, transform), bool exact=<default>);
+void add(frame f, transform t=<default>, Label L);
+void add(picture src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+plain plain;
+void purge(int divisor=<default>);
+int Round(real x);
+real sqrt(real x);
+real[] sqrt(real[] a);
+pair sqrt(explicit pair z);
+string[] spinner;
+real[] times(path p, real x);
+real[] times(path p, explicit pair z);
+void drawbeziertriangle(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] colors, int interaction, bool prc=<default>);
+void Draw(picture pic=<default>, path g, pen p=<default>);
+filltype Draw;
+void Draw(picture pic=<default>, explicit path[] g, pen p=<default>);
+filltype Draw(real xmargin=<default>, real ymargin=<default>, pen p=<default>);
+void tab(file file);
+plain_scaling plain_scaling;
+string file(string s);
+plain_bounds plain_bounds;
+string outprefix(string prefix=<default>);
+object object(Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+object object(frame f);
+object object(Label L);
+file stdin;
+void()()[] array(int n, void value()(), int depth=<default>);
+bool[] array(int n, bool value, int depth=<default>);
+string[] array(int n, string value, int depth=<default>);
+pair[][] array(int n, pair[] value, int depth=<default>);
+bool3[] array(int n, bool3 value, int depth=<default>);
+coord[] array(int n, coord value, int depth=<default>);
+Label[] array(int n, Label value, int depth=<default>);
+picture[] array(int n, picture value, int depth=<default>);
+real[][] array(int n, real[] value, int depth=<default>);
+real[] array(int n, real value, int depth=<default>);
+triple[] array(int n, triple value, int depth=<default>);
+path[] array(int n, path value, int depth=<default>);
+frame[] array(int n, frame value, int depth=<default>);
+pen[][] array(int n, pen[] value, int depth=<default>);
+coord[] array(int n, coord value, int depth=<default>);
+object[] array(int n, object value, int depth=<default>);
+marker[] array(int n, marker value, int depth=<default>);
+Legend[] array(int n, Legend value, int depth=<default>);
+int[] array(int n, int value, int depth=<default>);
+string[][] array(int n, string[] value, int depth=<default>);
+pair[] array(int n, pair value, int depth=<default>);
+guide[] array(int n, guide value, int depth=<default>);
+pen[] array(int n, pen value, int depth=<default>);
+string[] array(string s);
+bool BeginBar(picture, path, pen, marginT(path, pen));
+bool BeginBar(picture, path, pen, marginT(path, pen))(real size=<default>);
+triple perp(triple v, triple u);
+int find(bool[] a, int n=<default>);
+int find(string s, string t, int pos=<default>);
+position BeginPoint;
+marginT BeginMargin(path, pen);
+path buildcycle(... path[] p);
+bool BeginArrow(picture, path, pen, marginT(path, pen));
+bool BeginArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
+marginT BeginPenMargin(path, pen);
+int round(real x);
+marginT BeginDotMargin(path, pen);
+bool BeginArcArrow(picture, path, pen, marginT(path, pen));
+bool BeginArcArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
+pen roundcap;
+void buildRestoreThunk()();
+pen roundjoin;
+int sourceline(string file, string text);
+void buildRestoreDefaults()();
+path roundbox(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+path roundbox(frame f, Label L, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+real asin(real x);
+real[] asin(real[] a);
+pair endpoint(path p);
+real latitude(triple v, bool warn=<default>);
+int sum(int[] a);
+real sum(real[] a);
+pair sum(pair[] a);
+triple sum(triple[] a);
+int sum(bool[] a);
+void xmap(string key, transform t=<default>);
+real inf;
+real arctime(path p, real l);
+real arctime(path3 p, real dval);
+pen palemagenta;
+void draw(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] colors, int interaction, bool prc=<default>);
+void draw(frame f, triple[] p, real[] knot, real[] weights=<default>, pen p);
+void draw(frame f, triple[][] p, real[] uknot, real[] vknot, real[][] weights=<default>, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] colors);
+void draw(frame f, triple[] v, int[][] vi, triple[] n, int[][] ni, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] c=<default>, int[][] ci=<default>);
+void draw(picture pic=<default>, path[] g, pen fillrule=<default>, pen[] p);
+object draw(picture pic=<default>, Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), pair position, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+void draw(frame f, explicit path[] g, pen p=<default>);
+void draw(picture pic=<default>, guide[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
+void draw(pair origin, picture pic=<default>, guide[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
+void draw(picture pic=<default>, explicit path[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
+void draw(pair origin, picture pic=<default>, explicit path[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
+object draw(picture pic=<default>, Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+void draw(frame f, guide[] g, pen p=<default>);
+void draw(frame f, path g, pen p=<default>);
+void draw(picture pic=<default>, Label L=<default>, path g, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(pair origin, picture pic=<default>, Label L=<default>, path g, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(frame f, path g, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen)));
+int mantissaBits;
+real identity(real x);
+real[] identity(real[] a);
+transform identity();
+real[][] identity(int n);
+transform identity;
+real[][] identity4;
+marker[] MarkFill;
+pen pattern(string s);
+string pattern(pen p);
+transform invert;
+transform inverse(transform t);
+real[][] inverse(real[][] a);
+pair unit(pair z);
+triple unit(triple v);
+triple min3(frame f);
+triple min3(pen p);
+void begin(picture pic=<default>, string name, string id=<default>, bool visible=<default>);
+void drawPRCdisk(frame f, real[][] t, pen[] p, real opacity, real shininess);
+void drawPRCtube(frame f, path3 center, path3 g, pen[] p, real opacity, real shininess);
+int CLZ(int a);
+void drawPRCsphere(frame f, real[][] t, bool half=<default>, pen[] p, real opacity, real shininess, int type);
+arrowhead DefaultHead;
+void drawPRCcylinder(frame f, real[][] t, pen[] p, real opacity, real shininess);
+void beginclip(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, bool copy=<default>);
+void beginclip(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, bool copy=<default>);
+void begingroup(frame f);
+void begingroup(picture pic=<default>);
+marker nomarker;
+pair beginpoint(path p);
+real azimuth(triple v, bool warn=<default>);
+real angle(pair z, bool warn=<default>);
+real angle(transform t);
+pair ENE;
+frame pack(pair align=<default> ... object[] inset);
+void gsave(frame f);
+void write(file file=<default>, string s=<default>, bool x, void suffix(file)=<default> ... bool[]);
+void write(file file=<default>, string s=<default>, explicit bool[] a ... bool[][]);
+void write(file file=<default>, bool[][]);
+void write(file file=<default>, bool[][][]);
+void write(file file=<default>, string s=<default>, int x, void suffix(file)=<default> ... int[]);
+void write(file file=<default>, string s=<default>, explicit int[] a ... int[][]);
+void write(file file=<default>, int[][]);
+void write(file file=<default>, int[][][]);
+void write(file file=<default>, string s=<default>, real x, void suffix(file)=<default> ... real[]);
+void write(file file=<default>, string s=<default>, explicit real[] a ... real[][]);
+void write(file file=<default>, real[][]);
+void write(file file=<default>, real[][][]);
+void write(file file=<default>, string s=<default>, pair x, void suffix(file)=<default> ... pair[]);
+void write(file file=<default>, string s=<default>, explicit pair[] a ... pair[][]);
+void write(file file=<default>, pair[][]);
+void write(file file=<default>, pair[][][]);
+void write(file file=<default>, string s=<default>, triple x, void suffix(file)=<default> ... triple[]);
+void write(file file=<default>, string s=<default>, explicit triple[] a ... triple[][]);
+void write(file file=<default>, triple[][]);
+void write(file file=<default>, triple[][][]);
+void write(file file=<default>, string s=<default>, string x, void suffix(file)=<default> ... string[]);
+void write(file file=<default>, string s=<default>, explicit string[] a ... string[][]);
+void write(file file=<default>, string[][]);
+void write(file file=<default>, string[][][]);
+void write(file file=<default>, string s, void suffix(file)=<default>);
+void write(file file=<default>, string s=<default>, transform x, void suffix(file)=<default> ... transform[]);
+void write(file file=<default>, string s=<default>, guide x, void suffix(file)=<default> ... guide[]);
+void write(file file=<default>, string s=<default>, pen x, void suffix(file)=<default> ... pen[]);
+void write(file file, string s=<default>, explicit guide[] x, void suffix(file)=<default>);
+void write(string s=<default>, cputime c, string format=<default>, void suffix(file)=<default>);
+void write(string s=<default>, explicit path[] x, void suffix(file)=<default>);
+void write(file file, void suffix(file)=<default>);
+void write(file file=<default>, string s=<default>, pen[] p);
+void write(void suffix(file)=<default>);
+void write(file file, string s=<default>, explicit path[] x, void suffix(file)=<default>);
+void write(file file=<default>, align align, void suffix(file)=<default>);
+void write(pairOrTriple a);
+void write(file file, string s=<default>, cputime c, string format=<default>, void suffix(file)=<default>);
+void write(string s=<default>, bool3 b, void suffix(file)=<default>);
+void write(file file, string s=<default>, bool3 b, void suffix(file)=<default>);
+void write(string s=<default>, explicit guide[] x, void suffix(file)=<default>);
+void write(file file=<default>, Label L, void suffix(file)=<default>);
+void save()();
+marginT EndPenMargin(path, pen);
+pair NNE;
+real[] tridiagonal(real[] a, real[] b, real[] c, real[] f);
+pen Dotted;
+pen Dotted(pen p=<default>);
+pair dir(real degrees);
+pair dir(explicit pair z);
+triple dir(explicit triple z);
+triple dir(real colatitude, real longitude);
+pair dir(path p, int t, int sign=<default>, bool normalize=<default>);
+pair dir(path p, real t, bool normalize=<default>);
+triple dir(path3 p, int t, int sign=<default>, bool normalize=<default>);
+triple dir(path3 p, real t, bool normalize=<default>);
+pair dir(path p);
+pair dir(path p, path q);
+int[][] diagonal(... int[]);
+real[][] diagonal(... real[]);
+pair[][] diagonal(... pair[]);
+real reltime(path p, real l);
+void marknodes(picture pic=<default>, frame f, path g);
+real newton(int iterations=<default>, real f(real), real fprime(real), real x, bool verbose=<default>);
+real newton(int iterations=<default>, real f(real), real fprime(real), real x1, real x2, bool verbose=<default>);
+string TeXify(string s);
+bool3 default;
+pair[] controlSpecifier(guide g, int t);
+void defaultpen(pen p);
+pen defaultpen();
+pen defaultpen;
+void defaultpen(real w);
+transform Slant(transform t);
+triple max3(frame f);
+triple max3(pen p);
+string defaultformat(int n, string trailingzero=<default>, bool fixed=<default>, bool signed=<default>);
+string defaultformat;
+pen dashdotted;
+string defaultseparator;
+string asydir();
+string defaultfilename;
+real longitude(triple v, bool warn=<default>);
+bool Blank(picture, path, pen, marginT(path, pen));
+tensionSpecifier tensionSpecifier(guide g, int t);
+marker marker(frame f=<default>, void markroutine(picture pic=<default>, frame f, path g)=<default>, bool above=<default>);
+marker marker(path[] g, void markroutine(picture pic=<default>, frame f, path g)=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+int Move;
+string location();
+string locatefile(string file);
+pen dotted;
+string blend(pen p);
+arrowhead HookHead;
+arrowhead HookHead(real dir=<default>, real barb=<default>);
+marker[] concat(... marker[][]);
+real[] concat(... real[][]);
+picture[] concat(... picture[][]);
+pair[] concat(... pair[][]);
+object[] concat(... object[][]);
+pen[] concat(... pen[][]);
+coord[] concat(... coord[][]);
+Label[] concat(... Label[][]);
+path[] concat(... path[][]);
+coord[] concat(... coord[][]);
+Legend[] concat(... Legend[][]);
+int[] concat(... int[][]);
+void()()[] concat(... void()()[][]);
+bool3[] concat(... bool3[][]);
+string[] concat(... string[][]);
+triple[] concat(... triple[][]);
+frame[] concat(... frame[][]);
+guide[] concat(... guide[][]);
+bool[] concat(... bool[][]);
+int OR(int a, int b);
+real log1p(real x);
+real[] log1p(real[] a);
+real infinity;
+bool alias(pair[][] a, pair[][] b);
+bool alias(guide[] a, guide[] b);
+bool alias(marginT a, marginT b);
+bool alias(coord[] a, coord[] b);
+bool alias(autoscaleT a, autoscaleT b);
+bool alias(align a, align b);
+bool alias(Legend[] a, Legend[] b);
+bool alias(processtime a, processtime b);
+bool alias(pair[] a, pair[] b);
+bool alias(scaling a, scaling b);
+bool alias(coord a, coord b);
+bool alias(transformation a, transformation b);
+bool alias(node a, node b);
+bool alias(Label a, Label b);
+bool alias(int[] a, int[] b);
+bool alias(string[][] a, string[][] b);
+bool alias(slice a, slice b);
+bool alias(freezableBounds a, freezableBounds b);
+bool alias(projection a, projection b);
+bool alias(coords3 a, coords3 b);
+bool alias(object[] a, object[] b);
+bool alias(marker a, marker b);
+bool alias(real[][] a, real[][] b);
+bool alias(bool3 a, bool3 b);
+bool alias(bool3[] a, bool3[] b);
+bool alias(light a, light b);
+bool alias(ScaleT a, ScaleT b);
+bool alias(side a, side b);
+bool alias(cputime a, cputime b);
+bool alias(string[] a, string[] b);
+bool alias(frame[] a, frame[] b);
+bool alias(coords2 a, coords2 b);
+bool alias(scaling a, scaling b);
+bool alias(pairOrTriple a, pairOrTriple b);
+bool alias(object a, object b);
+bool alias(marker[] a, marker[] b);
+bool alias(bool[] a, bool[] b);
+bool alias(void()()[] a, void()()[] b);
+bool alias(pen[][] a, pen[][] b);
+bool alias(filltype a, filltype b);
+bool alias(simplex a, simplex b);
+bool alias(coord[] a, coord[] b);
+bool alias(scaleT a, scaleT b);
+bool alias(Label[] a, Label[] b);
+bool alias(arrowhead a, arrowhead b);
+bool alias(path[] a, path[] b);
+bool alias(triple[] a, triple[] b);
+bool alias(coord a, coord b);
+bool alias(bounds a, bounds b);
+bool alias(Legend a, Legend b);
+bool alias(position a, position b);
+bool alias(real[] a, real[] b);
+bool alias(pen[] a, pen[] b);
+bool alias(hsv a, hsv b);
+bool alias(coords2 a, coords2 b);
+bool alias(picture a, picture b);
+bool alias(picture[] a, picture[] b);
+real pi;
+int getint(string name=<default>, int default=<default>, string prompt=<default>, bool store=<default>);
+int bitreverse(int a, int bits);
+bool IgnoreAspect;
+void postscript(frame f, string s);
+void postscript(frame f, string s, pair min, pair max);
+void postscript(picture pic=<default>, string s);
+void postscript(picture pic=<default>, string s, pair min, pair max);
+transform slant(real s);
+void breakpoint(code s=<default>);
+void breakpoints();
+void endgroup(frame f);
+void endgroup(picture pic=<default>);
+void endgroup3(frame f);
+int Floor(real x);
+pair gamma(explicit pair z);
+real gamma(real x);
+real pow10(real x);
+real[] pow10(real[] a);
+real[][] AtA(real[][] a);
+real bp;
+int[] sort(int[] a);
+int[][] sort(int[][] a);
+real[] sort(real[] a);
+real[][] sort(real[][] a);
+string[] sort(string[] a);
+string[][] sort(string[][] a);
+coord[] sort(coord[] a, bool less(coord, coord), bool stable=<default>);
+object[] sort(object[] a, bool less(object, object), bool stable=<default>);
+marker[] sort(marker[] a, bool less(marker, marker), bool stable=<default>);
+Legend[] sort(Legend[] a, bool less(Legend, Legend), bool stable=<default>);
+path[] sort(path[] a, bool less(path, path), bool stable=<default>);
+pen[][] sort(pen[][] a, bool less(pen[], pen[]), bool stable=<default>);
+pair[][] sort(pair[][] a, bool less(pair[], pair[]), bool stable=<default>);
+pen[] sort(pen[] a, bool less(pen, pen), bool stable=<default>);
+bool[] sort(bool[] a, bool less(bool, bool), bool stable=<default>);
+void()()[] sort(void()()[] a, bool less(void()(), void()()), bool stable=<default>);
+frame[] sort(frame[] a, bool less(frame, frame), bool stable=<default>);
+bool3[] sort(bool3[] a, bool less(bool3, bool3), bool stable=<default>);
+coord[] sort(coord[] a, bool less(coord, coord), bool stable=<default>);
+Label[] sort(Label[] a, bool less(Label, Label), bool stable=<default>);
+picture[] sort(picture[] a, bool less(picture, picture), bool stable=<default>);
+int[] sort(int[] a, bool less(int, int), bool stable=<default>);
+string[][] sort(string[][] a, bool less(string[], string[]), bool stable=<default>);
+real[] sort(real[] a, bool less(real, real), bool stable=<default>);
+string[] sort(string[] a, bool less(string, string), bool stable=<default>);
+pair[] sort(pair[] a, bool less(pair, pair), bool stable=<default>);
+real[][] sort(real[][] a, bool less(real[], real[]), bool stable=<default>);
+triple[] sort(triple[] a, bool less(triple, triple), bool stable=<default>);
+guide[] sort(guide[] a, bool less(guide, guide), bool stable=<default>);
+pen salmon;
+bool ignore;
+pen Pentype(int n);
+pen chartreuse;
+void latticeshade(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[][] p, transform t=<default>, bool copy=<default>);
+void latticeshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[][] p, bool copy=<default>);
+pair[] pairs(real[] x, real[] y);
+void eval(code s, bool embedded=<default>);
+void eval(string s, bool embedded=<default>);
+bool Arrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
+bool Arrow(picture, path, pen, marginT(path, pen));
+bool Arrows(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
+bool Arrows(picture, path, pen, marginT(path, pen));
+int tell(file f);
+pen Yellow;
+pair up;
+guide reverse(guide g);
+string reverse(string s);
+path reverse(path p);
+path3 reverse(path3 p);
+triple[] reverse(triple[] a);
+int[] reverse(int[] a);
+real[] reverse(real[] a);
+int[] reverse(int n);
+string[] reverse(string[] a);
+pair[] reverse(pair[] a);
+bool[] reverse(bool[] a);
+void _labelpath(frame f, string s, string size, path g, string justify, pair offset, pen p);
+int floor(real x);
+void resetdefaultpen();
+real aSin(real x);
+pen darkred;
+transform Scale(transform t);
+pen mean(pen[] p, real opacity(real[])=<default>);
+pen[] mean(pen[][] palette, real opacity(real[])=<default>);
+string mktemp(string s);
+void sleep(int seconds);
+void drawstrokepath(picture pic=<default>, path g, pen strokepen, pen p=<default>);
+void arrow(picture pic=<default>, Label L=<default>, pair b, pair dir, real length=<default>, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>);
+picture arrow(arrowhead arrowhead=<default>, path g, pen p=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>, bool forwards=<default>, marginT margin(path, pen)=<default>, bool center=<default>);
+void unitsize(picture pic=<default>, real x, real y=<default>, real z=<default>);
+picture arrow2(arrowhead arrowhead=<default>, path g, pen p=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, marginT margin(path, pen)=<default>);
+path unitsquare;
+real arrowdir;
+real arrowbarb;
+pen yellow;
+int delete(string s);
+pen miterjoin;
+arrowhead SimpleHead;
+real arrowangle;
+real arrowlength;
+pen miterlimit(real x);
+real miterlimit(pen p=<default>);
+real arrowfactor;
+real arrowsize(pen p=<default>);
+real Tan(real deg);
+real arrowsizelimit;
+real arrow2sizelimit;
+real arrowhookfactor;
+real arrowtexfactor;
+void comma(file file);
+void deletepreamble();
+real[] arrowbasepoints(path base, path left, path right, real default=<default>);
+path arrowbase(path r, pair y, real t, real size);
+int choose(int n, int k);
+real hypot(real x, real y);
+path[] _strokepath(path g, pen p=<default>);
+void pause(string w=<default>);
+int ocgindex;
+pen springgreen;
+pen brown;
+bool scale(pen p);
+transform scale(real x);
+transform scale(real x, real y);
+real[][] scale(real x, real y, real z);
+scaleT scaleT(real T(real x), real Tinv(real x), bool logarithmic=<default>, bool automin=<default>, bool automax=<default>);
+string baseline(string s, string template=<default>);
+int[] findall(bool[] a);
+real[][] scale3(real s);
+int AND(int a, int b);
+real polar(triple v, bool warn=<default>);
+real radius(path p, real t);
+real radius(path3 p, real t);
+real radius(triple z0, triple c0, triple c1, triple z1, real t);
+transform scaleless(transform t);
+void makedraw(frame f, path g, pen p, int depth=<default>);
+simplex simplex(real[] c, real[][] A, real[] b, bool phase1=<default>, bool dual=<default>);
+simplex simplex(real[] c, real[][] A, int[] s, real[] b);
+simplex simplex;
+real nan;
+pair down;
+path arc(pair c, real r, real angle1, real angle2);
+path arc(pair c, explicit pair z1, explicit pair z2, bool direction=<default>);
+path arc(pair c, real r, real angle1, real angle2, bool direction);
+real[] cubicroots(real a, real b, real c, real d);
+pen green;
+real tan(real x);
+real[] tan(real[] a);
+pen longdashed;
+pair point(guide g, int t);
+pair point(path p, int t);
+pair point(path p, real t);
+triple point(path3 p, int t);
+triple point(path3 p, real t);
+pair point(picture pic=<default>, pair dir, bool user=<default>);
+pair point(object F, pair dir, transform t=<default>);
+pair point(frame f, pair dir);
+void progress(bool3 init=<default>);
+pen longdashdotted;
+void usepackage(string s, string options=<default>);
+void drawarrow(frame f, arrowhead arrowhead=<default>, path g, pen p=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>, bool forwards=<default>, marginT margin(path, pen)=<default>, bool center=<default>);
+void drawarrow2(frame f, arrowhead arrowhead=<default>, path g, pen p=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, marginT margin(path, pen)=<default>);
+pen fillrule(int n);
+int fillrule(pen p);
+pair ESE;
+pair project(triple v, real[][] t);
+bool prc(string format=<default>);
+projection projection(triple camera, triple up=<default>, triple target=<default>, triple normal=<default>, real zoom=<default>, real angle=<default>, pair viewportshift=<default>, bool showtarget=<default>, bool autoadjust=<default>, bool center=<default>, transformation projector(triple camera, triple up, triple target));
+void endl(file file);
+marginT TrueMargin(path, pen)(real begin, real end);
+pair bezier(pair a, pair b, pair c, pair d, real t);
+triple bezier(triple a, triple b, triple c, triple d, real t);
+pair SSE;
+pair bezierP(pair a, pair b, pair c, pair d, real t);
+triple bezierP(triple a, triple b, triple c, triple d, real t);
+pair bezierPP(pair a, pair b, pair c, pair d, real t);
+triple bezierPP(triple a, triple b, triple c, triple d, real t);
+real[] _projection();
+pair bezierPPP(pair a, pair b, pair c, pair d);
+triple bezierPPP(triple a, triple b, triple c, triple d);
+real Jn(int n, real x);
+int randMax;
+path nurb(pair z0, pair z1, pair z2, pair z3, real w0, real w1, real w2, real w3, int m);
+align NoAlign;
+bool EndBar(picture, path, pen, marginT(path, pen));
+bool EndBar(picture, path, pen, marginT(path, pen))(real size=<default>);
+Legend Legend(string label, pen plabel=<default>, pen p=<default>, frame mark=<default>, bool above=<default>);
+real Yn(int n, real x);
+int NOT(int a);
+pen[] monoPen;
+bool CW;
+bool all(bool[] a);
+real atanh(real x);
+real[] atanh(real[] a);
+frame UpsideDown(frame f);
+pair realmult(pair z, pair w);
+triple realmult(triple u, triple v);
+real acosh(real x);
+real[] acosh(real[] a);
+real realEpsilon;
+pair NW;
+real norm(real[] a);
+real norm(real[][] a);
+real norm(triple[][] a);
+int length(guide g);
+int length(string s);
+real length(pair z);
+real length(triple v);
+int length(path p);
+int length(path3 p);
+pair SW;
+void flush(file f);
+pen thin();
+pen palecyan;
+void warning(string s, string t, bool position=<default>);
+frame legend(picture pic=<default>, int perline=<default>, real xmargin=<default>, real ymargin=<default>, real linelength=<default>, real hskip=<default>, real vskip=<default>, real maxwidth=<default>, real maxheight=<default>, bool hstretch=<default>, bool vstretch=<default>, pen p=<default>);
+picture legend(Legend[] Legend, int perline=<default>, real linelength, real hskip, real vskip, real maxwidth=<default>, real maxheight=<default>, bool hstretch=<default>, bool vstretch=<default>);
+real Degrees(real radians);
+picture legenditem(Legend legenditem, real linelength);
+real legendhskip;
+real legendvskip;
+pen darkmagenta;
+real change2(triple[][] a);
+real legendmargin;
+bool None(picture, path, pen, marginT(path, pen));
+real dotfactor;
+real legendlinelength;
+string minipage(string s, real width=<default>);
+real legendmaxrelativewidth;
+real cross(explicit pair z, explicit pair w);
+triple cross(triple u, triple v);
+path cross(int n, bool round=<default>, real r=<default>);
+string operator +(string a, string b);
+int operator +(int a, int b);
+int[] operator +(int a, int[] b);
+int[] operator +(int[] a, int b);
+int[] operator +(int[] a, int[] b);
+int[][] operator +(int[][] a, int[][] b);
+int operator +(int a);
+int[] operator +(int[] a);
+real operator +(real a, real b);
+real[] operator +(real a, real[] b);
+real[] operator +(real[] a, real b);
+real[] operator +(real[] a, real[] b);
+real[][] operator +(real[][] a, real[][] b);
+real operator +(real a);
+real[] operator +(real[] a);
+pair operator +(pair a, pair b);
+pair[] operator +(pair a, pair[] b);
+pair[] operator +(pair[] a, pair b);
+pair[] operator +(pair[] a, pair[] b);
+pair[][] operator +(pair[][] a, pair[][] b);
+pair operator +(pair a);
+pair[] operator +(pair[] a);
+triple operator +(triple a, triple b);
+triple[] operator +(triple a, triple[] b);
+triple[] operator +(triple[] a, triple b);
+triple[] operator +(triple[] a, triple[] b);
+triple[][] operator +(triple[][] a, triple[][] b);
+triple operator +(triple a);
+triple[] operator +(triple[] a);
+pen operator +(pen a, pen b);
+transform operator +(transform a, transform b);
+pen operator +(pen p, real w);
+pen[] operator +(pen a, pen[] b);
+pen operator +(real w, pen p);
+string operator +(... string[] a);
+marginT operator +(path, pen)(marginT ma(path, pen), marginT mb(path, pen));
+pen[] operator +(pen[] a, pen b);
+int operator -(int a, int b);
+int[] operator -(int a, int[] b);
+int[] operator -(int[] a, int b);
+int[] operator -(int[] a, int[] b);
+int[][] operator -(int[][] a, int[][] b);
+int operator -(int a);
+int[] operator -(int[] a);
+int[][] operator -(int[][] a);
+real operator -(real a, real b);
+real[] operator -(real a, real[] b);
+real[] operator -(real[] a, real b);
+real[] operator -(real[] a, real[] b);
+real[][] operator -(real[][] a, real[][] b);
+real operator -(real a);
+real[] operator -(real[] a);
+real[][] operator -(real[][] a);
+pair operator -(pair a, pair b);
+pair[] operator -(pair a, pair[] b);
+pair[] operator -(pair[] a, pair b);
+pair[] operator -(pair[] a, pair[] b);
+pair[][] operator -(pair[][] a, pair[][] b);
+pair operator -(pair a);
+pair[] operator -(pair[] a);
+pair[][] operator -(pair[][] a);
+triple operator -(triple a, triple b);
+triple[] operator -(triple a, triple[] b);
+triple[] operator -(triple[] a, triple b);
+triple[] operator -(triple[] a, triple[] b);
+triple[][] operator -(triple[][] a, triple[][] b);
+triple operator -(triple a);
+triple[] operator -(triple[] a);
+triple[][] operator -(triple[][] a);
+int operator *(int a, int b);
+int[] operator *(int a, int[] b);
+int[] operator *(int[] a, int b);
+int[] operator *(int[] a, int[] b);
+int[][] operator *(int a, int[][] b);
+int[][] operator *(int[][] a, int b);
+real operator *(real a, real b);
+real[] operator *(real a, real[] b);
+real[] operator *(real[] a, real b);
+real[] operator *(real[] a, real[] b);
+real[][] operator *(real a, real[][] b);
+real[][] operator *(real[][] a, real b);
+pair operator *(pair a, pair b);
+pair[] operator *(pair a, pair[] b);
+pair[] operator *(pair[] a, pair b);
+pair[] operator *(pair[] a, pair[] b);
+pair[][] operator *(pair a, pair[][] b);
+pair[][] operator *(pair[][] a, pair b);
+triple[] operator *(real a, triple[] b);
+triple[][] operator *(real a, triple[][] b);
+triple[] operator *(triple[] a, real b);
+triple[][] operator *(triple[][] a, real b);
+pen operator *(real a, pen b);
+pen operator *(pen a, real b);
+transform operator *(transform a, transform b);
+pair operator *(transform t, pair z);
+path operator *(transform t, path g);
+pen operator *(transform t, pen p);
+frame operator *(transform t, frame f);
+frame operator *(real[][] t, frame f);
+real[] operator *(real[][] a, real[] b);
+real[] operator *(real[] a, real[][] b);
+int[][] operator *(int[][] a, int[][] b);
+real[][] operator *(real[][] a, real[][] b);
+pair[][] operator *(pair[][] a, pair[][] b);
+triple operator *(real[][] t, triple v);
+triple operator *(real x, triple v);
+triple operator *(triple v, real x);
+path3 operator *(real[][] t, path3 g);
+side operator *(real x, side s);
+Label operator *(real[][] t, Label L);
+picture operator *(transform t, picture orig);
+object operator *(transform t, explicit object F);
+path[] operator *(transform t, explicit path[] p);
+Label operator *(transform t, Label L);
+pair[] operator *(transform t, pair[] z);
+bounds operator *(transform t, bounds b);
+picture operator *(real[][] t, picture orig);
+bool operator init();
+int operator init();
+real operator init();
+string operator init();
+pair operator init();
+triple operator init();
+transform operator init();
+guide operator init();
+path operator init();
+path3 operator init();
+pen operator init();
+frame operator init();
+file operator init();
+marginT operator init();
+autoscaleT operator init();
+align operator init();
+processtime operator init();
+filltype operator init();
+simplex operator init();
+scaleT operator init();
+arrowhead operator init();
+slice operator init();
+projection operator init();
+coords3 operator init();
+marker operator init();
+hsv operator init();
+coords2 operator init();
+picture operator init();
+coords2 operator init();
+scaling operator init();
+pairOrTriple operator init();
+object operator init();
+scaling operator init();
+coord operator init();
+transformation operator init();
+node operator init();
+Label operator init();
+coord operator init();
+bounds operator init();
+Legend operator init();
+position operator init();
+bool3 operator init();
+light operator init();
+ScaleT operator init();
+side operator init();
+cputime operator init();
+real operator cast(int);
+pair operator cast(int);
+pair operator cast(real);
+path operator cast(pair);
+guide operator cast(pair);
+guide operator cast(path);
+path operator cast(guide);
+file operator cast(null);
+real[] operator cast(int[]);
+pair[] operator cast(int[]);
+pair[] operator cast(real[]);
+real[][] operator cast(int[][]);
+pair[][] operator cast(int[][]);
+pair[][] operator cast(real[][]);
+bool operator cast(file);
+bool[] operator cast(file);
+bool[][] operator cast(file);
+bool[][][] operator cast(file);
+int operator cast(file);
+int[] operator cast(file);
+int[][] operator cast(file);
+int[][][] operator cast(file);
+real operator cast(file);
+real[] operator cast(file);
+real[][] operator cast(file);
+real[][][] operator cast(file);
+pair operator cast(file);
+pair[] operator cast(file);
+pair[][] operator cast(file);
+pair[][][] operator cast(file);
+triple operator cast(file);
+triple[] operator cast(file);
+triple[][] operator cast(file);
+triple[][][] operator cast(file);
+string operator cast(file);
+string[] operator cast(file);
+string[][] operator cast(file);
+string[][][] operator cast(file);
+guide operator cast(cycleToken tok);
+guide operator cast(curlSpecifier spec);
+guide operator cast(tensionSpecifier t);
+align operator cast(side side);
+guide[] operator cast(path[] g);
+pair operator cast(pairOrTriple a);
+triple operator cast(pairOrTriple a);
+frame operator cast(object F);
+hsv operator cast(pen p);
+bool3[] operator cast(bool[] b);
+position operator cast(pair x);
+object operator cast(Label L);
+Label operator cast(object F);
+pair operator cast(position P);
+object operator cast(frame f);
+guide[] operator cast(pair[] z);
+path[] operator cast(guide[] g);
+bool operator cast(bool3 b);
+align operator cast(pair dir);
+path[] operator cast(guide g);
+path[] operator cast(pair[] z);
+align operator cast(triple dir);
+path[] operator cast(path p);
+bool[] operator cast(bool3[] b);
+bool3 operator cast(bool b);
+position operator cast(int x);
+object operator cast(string s);
+pen operator cast(hsv hsv);
+position operator cast(real x);
+Label operator cast(string s);
+pen deepred;
+bool error(file f);
+string operator ecast(int);
+string operator ecast(real);
+string operator ecast(pair);
+string operator ecast(triple);
+int operator ecast(string);
+real operator ecast(string);
+pair operator ecast(string);
+triple operator ecast(string);
+int operator ecast(real);
+int[] operator ecast(real[]);
+real[] operator ecast(string[] a);
+int[] operator ecast(string[] a);
+pair operator tuple(real x, real y);
+triple operator tuple(real x, real y, real z);
+transform operator tuple(real x, real y, real xx, real xy, real yx, real yy);
+real operator /(real a, real b);
+real[] operator /(real a, real[] b);
+real[] operator /(real[] a, real b);
+real[] operator /(real[] a, real[] b);
+real[][] operator /(real[][] a, real b);
+pair operator /(pair a, pair b);
+pair[] operator /(pair a, pair[] b);
+pair[] operator /(pair[] a, pair b);
+pair[] operator /(pair[] a, pair[] b);
+pair[][] operator /(pair[][] a, pair b);
+triple[] operator /(triple[] a, real b);
+real operator /(int a, int b);
+real[] operator /(int[] a, int b);
+real[] operator /(int a, int[] b);
+real[] operator /(int[] a, int[] b);
+triple operator /(triple v, real x);
+path[] texpath(string s, pen p, bool tex=<default>, bool bbox=<default>);
+path[] texpath(Label L, bool tex=<default>, bool bbox=<default>);
+bool uptodate();
+int operator #(int a, int b);
+int[] operator #(int a, int[] b);
+int[] operator #(int[] a, int b);
+int[] operator #(int[] a, int[] b);
+int operator %(int a, int b);
+int[] operator %(int a, int[] b);
+int[] operator %(int[] a, int b);
+int[] operator %(int[] a, int[] b);
+real operator %(real a, real b);
+real[] operator %(real a, real[] b);
+real[] operator %(real[] a, real b);
+real[] operator %(real[] a, real[] b);
+bool operator ^(bool a, bool b);
+bool[] operator ^(bool a, bool[] b);
+bool[] operator ^(bool[] a, bool b);
+bool[] operator ^(bool[] a, bool[] b);
+int operator ^(int a, int b);
+int[] operator ^(int a, int[] b);
+int[] operator ^(int[] a, int b);
+int[] operator ^(int[] a, int[] b);
+real operator ^(real a, real b);
+real[] operator ^(real a, real[] b);
+real[] operator ^(real[] a, real b);
+real[] operator ^(real[] a, real[] b);
+pair operator ^(pair a, pair b);
+pair[] operator ^(pair a, pair[] b);
+pair[] operator ^(pair[] a, pair b);
+pair[] operator ^(pair[] a, pair[] b);
+transform operator ^(transform t, int n);
+real operator ^(real x, int y);
+pair operator ^(pair z, int y);
+bool operator ==(bool a, bool b);
+bool[] operator ==(bool a, bool[] b);
+bool[] operator ==(bool[] a, bool b);
+bool[] operator ==(bool[] a, bool[] b);
+bool operator ==(bool[][] a, bool[][] b);
+bool operator ==(int a, int b);
+bool[] operator ==(int a, int[] b);
+bool[] operator ==(int[] a, int b);
+bool[] operator ==(int[] a, int[] b);
+bool operator ==(int[][] a, int[][] b);
+bool operator ==(real a, real b);
+bool[] operator ==(real a, real[] b);
+bool[] operator ==(real[] a, real b);
+bool[] operator ==(real[] a, real[] b);
+bool operator ==(real[][] a, real[][] b);
+bool operator ==(pair a, pair b);
+bool[] operator ==(pair a, pair[] b);
+bool[] operator ==(pair[] a, pair b);
+bool[] operator ==(pair[] a, pair[] b);
+bool operator ==(pair[][] a, pair[][] b);
+bool operator ==(triple a, triple b);
+bool[] operator ==(triple a, triple[] b);
+bool[] operator ==(triple[] a, triple b);
+bool[] operator ==(triple[] a, triple[] b);
+bool operator ==(triple[][] a, triple[][] b);
+bool operator ==(string a, string b);
+bool[] operator ==(string a, string[] b);
+bool[] operator ==(string[] a, string b);
+bool[] operator ==(string[] a, string[] b);
+bool operator ==(string[][] a, string[][] b);
+bool[] operator ==(pen[] a, pen[] b);
+bool operator ==(pen a, pen b);
+bool operator ==(transform a, transform b);
+bool operator ==(file a, file b);
+bool operator ==(path a, path b);
+bool operator ==(path3 a, path3 b);
+bool operator ==(bool3 a, bool3 b);
+bool operator ==(light a, light b);
+bool operator ==(ScaleT a, ScaleT b);
+bool operator ==(side a, side b);
+bool operator ==(cputime a, cputime b);
+bool operator ==(coords2 a, coords2 b);
+bool operator ==(scaling a, scaling b);
+bool operator ==(pairOrTriple a, pairOrTriple b);
+bool operator ==(object a, object b);
+bool operator ==(filltype a, filltype b);
+bool operator ==(simplex a, simplex b);
+bool operator ==(scaleT a, scaleT b);
+bool operator ==(arrowhead a, arrowhead b);
+bool operator ==(coord a, coord b);
+bool operator ==(bounds a, bounds b);
+bool operator ==(Legend a, Legend b);
+bool operator ==(position a, position b);
+bool operator ==(hsv a, hsv b);
+bool operator ==(coords2 a, coords2 b);
+bool operator ==(picture a, picture b);
+bool operator ==(bool3 a, bool b);
+bool operator ==(marginT a, marginT b);
+bool operator ==(autoscaleT a, autoscaleT b);
+bool operator ==(align a, align b);
+bool operator ==(processtime a, processtime b);
+bool operator ==(scaling a, scaling b);
+bool operator ==(coord a, coord b);
+bool operator ==(transformation a, transformation b);
+bool operator ==(node a, node b);
+bool operator ==(Label a, Label b);
+bool operator ==(bool a, bool3 b);
+bool operator ==(slice a, slice b);
+bool operator ==(freezableBounds a, freezableBounds b);
+bool operator ==(projection a, projection b);
+bool operator ==(coords3 a, coords3 b);
+bool operator ==(marker a, marker b);
+bool operator !=(bool a, bool b);
+bool[] operator !=(bool a, bool[] b);
+bool[] operator !=(bool[] a, bool b);
+bool[] operator !=(bool[] a, bool[] b);
+bool operator !=(bool[][] a, bool[][] b);
+bool operator !=(int a, int b);
+bool[] operator !=(int a, int[] b);
+bool[] operator !=(int[] a, int b);
+bool[] operator !=(int[] a, int[] b);
+bool operator !=(int[][] a, int[][] b);
+bool operator !=(real a, real b);
+bool[] operator !=(real a, real[] b);
+bool[] operator !=(real[] a, real b);
+bool[] operator !=(real[] a, real[] b);
+bool operator !=(real[][] a, real[][] b);
+bool operator !=(pair a, pair b);
+bool[] operator !=(pair a, pair[] b);
+bool[] operator !=(pair[] a, pair b);
+bool[] operator !=(pair[] a, pair[] b);
+bool operator !=(pair[][] a, pair[][] b);
+bool operator !=(triple a, triple b);
+bool[] operator !=(triple a, triple[] b);
+bool[] operator !=(triple[] a, triple b);
+bool[] operator !=(triple[] a, triple[] b);
+bool operator !=(triple[][] a, triple[][] b);
+bool operator !=(string a, string b);
+bool[] operator !=(string a, string[] b);
+bool[] operator !=(string[] a, string b);
+bool[] operator !=(string[] a, string[] b);
+bool operator !=(string[][] a, string[][] b);
+bool[] operator !=(pen[] a, pen[] b);
+bool operator !=(pen a, pen b);
+bool operator !=(transform a, transform b);
+bool operator !=(file a, file b);
+bool operator !=(path a, path b);
+bool operator !=(path3 a, path3 b);
+bool operator !=(bool3 a, bool3 b);
+bool operator !=(light a, light b);
+bool operator !=(ScaleT a, ScaleT b);
+bool operator !=(side a, side b);
+bool operator !=(cputime a, cputime b);
+bool operator !=(coords2 a, coords2 b);
+bool operator !=(scaling a, scaling b);
+bool operator !=(pairOrTriple a, pairOrTriple b);
+bool operator !=(object a, object b);
+bool operator !=(filltype a, filltype b);
+bool operator !=(simplex a, simplex b);
+bool operator !=(scaleT a, scaleT b);
+bool operator !=(arrowhead a, arrowhead b);
+bool operator !=(coord a, coord b);
+bool operator !=(bounds a, bounds b);
+bool operator !=(Legend a, Legend b);
+bool operator !=(position a, position b);
+bool operator !=(hsv a, hsv b);
+bool operator !=(coords2 a, coords2 b);
+bool operator !=(picture a, picture b);
+bool operator !=(bool3 a, bool b);
+bool operator !=(marginT a, marginT b);
+bool operator !=(autoscaleT a, autoscaleT b);
+bool operator !=(align a, align b);
+bool operator !=(processtime a, processtime b);
+bool operator !=(scaling a, scaling b);
+bool operator !=(coord a, coord b);
+bool operator !=(transformation a, transformation b);
+bool operator !=(node a, node b);
+bool operator !=(Label a, Label b);
+bool operator !=(bool a, bool3 b);
+bool operator !=(slice a, slice b);
+bool operator !=(freezableBounds a, freezableBounds b);
+bool operator !=(projection a, projection b);
+bool operator !=(coords3 a, coords3 b);
+bool operator !=(marker a, marker b);
+bool operator <(int a, int b);
+bool[] operator <(int a, int[] b);
+bool[] operator <(int[] a, int b);
+bool[] operator <(int[] a, int[] b);
+bool operator <(real a, real b);
+bool[] operator <(real a, real[] b);
+bool[] operator <(real[] a, real b);
+bool[] operator <(real[] a, real[] b);
+bool operator <(string a, string b);
+bool[] operator <(string a, string[] b);
+bool[] operator <(string[] a, string b);
+bool[] operator <(string[] a, string[] b);
+bool operator <=(int a, int b);
+bool[] operator <=(int a, int[] b);
+bool[] operator <=(int[] a, int b);
+bool[] operator <=(int[] a, int[] b);
+bool operator <=(real a, real b);
+bool[] operator <=(real a, real[] b);
+bool[] operator <=(real[] a, real b);
+bool[] operator <=(real[] a, real[] b);
+bool operator <=(string a, string b);
+bool[] operator <=(string a, string[] b);
+bool[] operator <=(string[] a, string b);
+bool[] operator <=(string[] a, string[] b);
+bool operator <=(coord a, coord b);
+bool operator <=(coord a, coord b);
+void srand(int seed);
+bool operator >(int a, int b);
+bool[] operator >(int a, int[] b);
+bool[] operator >(int[] a, int b);
+bool[] operator >(int[] a, int[] b);
+bool operator >(real a, real b);
+bool[] operator >(real a, real[] b);
+bool[] operator >(real[] a, real b);
+bool[] operator >(real[] a, real[] b);
+bool operator >(string a, string b);
+bool[] operator >(string a, string[] b);
+bool[] operator >(string[] a, string b);
+bool[] operator >(string[] a, string[] b);
+bool operator >=(int a, int b);
+bool[] operator >=(int a, int[] b);
+bool[] operator >=(int[] a, int b);
+bool[] operator >=(int[] a, int[] b);
+bool operator >=(real a, real b);
+bool[] operator >=(real a, real[] b);
+bool[] operator >=(real[] a, real b);
+bool[] operator >=(real[] a, real[] b);
+bool operator >=(string a, string b);
+bool[] operator >=(string a, string[] b);
+bool[] operator >=(string[] a, string b);
+bool[] operator >=(string[] a, string[] b);
+bool operator >=(coord a, coord b);
+bool operator >=(coord a, coord b);
+filltype UnFill(real xmargin=<default>, real ymargin=<default>);
+filltype UnFill;
+real degrees(pair z, bool warn=<default>);
+real degrees(real radians);
+bool[] operator !(bool[] a);
+bool operator !(bool b);
+path[] operator ^^(path p, path q);
+path[] operator ^^(explicit path[] p, path q);
+path[] operator ^^(path p, explicit path[] q);
+path[] operator ^^(explicit path[] p, explicit path[] q);
+guide operator ::(... guide[]);
+pen Helvetica(string series=<default>, string shape=<default>);
+transform reflect(pair a, pair b);
+bool Bars(picture, path, pen, marginT(path, pen));
+bool Bars(picture, path, pen, marginT(path, pen))(real size=<default>);
+void none(file file);
+int factorial(int n);
+real log(real x);
+real[] log(real[] a);
+pair log(explicit pair z);
+guide operator ..(... guide[]);
+guide operator ..(... guide[])(tensionSpecifier t);
+path polygon(int n);
+guide operator --(... guide[]);
+guide operator ---(... guide[]);
+pen NewCenturySchoolBook(string series=<default>, string shape=<default>);
+void()()[] saveFunctions;
+bool operator &(bool a, bool b);
+bool[] operator &(bool a, bool[] b);
+bool[] operator &(bool[] a, bool b);
+bool[] operator &(bool[] a, bool[] b);
+path operator &(path p, path q);
+path3 operator &(path3 p, path3 q);
+path operator &(path p, cycleToken tok);
+bool operator |(bool a, bool b);
+bool[] operator |(bool a, bool[] b);
+bool[] operator |(bool[] a, bool b);
+bool[] operator |(bool[] a, bool[] b);
+string texify(string s);
+guide operator controls(pair zout, pair zin);
+guide operator controls(pair z);
+bool empty(frame f);
+tensionSpecifier operator tension(real tout, real tin, bool atleast);
+tensionSpecifier operator tension(real t, bool atLeast);
+void end(picture pic=<default>);
+curlSpecifier operator curl(real gamma, int p);
+guide operator spec(pair z, int p);
+string substr(string s, int pos, int n=<default>);
+pen paleyellow;
+file output(string name=<default>, bool update=<default>, string comment=<default>, string mode=<default>);
+pen ZapfDingbats(string series=<default>, string shape=<default>);
+real tanh(real x);
+real[] tanh(real[] a);
+real interp(real a, real b, real t);
+pair interp(explicit pair a, explicit pair b, real t);
+triple interp(triple a, triple b, real t);
+pen interp(pen a, pen b, real t);
+frame Seascape(frame f);
+bool interior(int windingnumber, pen fillrule);
+real[] intersect(path p, path q, real fuzz=<default>);
+real[] intersect(path3 p, path3 q, real fuzz=<default>);
+real[] intersect(path3 p, triple[][] p, real fuzz=<default>);
+bool interactive();
+real[][] intersections(path p, path q, real fuzz=<default>);
+real[] intersections(path p, explicit pair a, explicit pair b, real fuzz=<default>);
+real[][] intersections(path3 p, path3 q, real fuzz=<default>);
+real[][] intersections(path3 p, triple[][] p, real fuzz=<default>);
+int animate(string args=<default>, string file=<default>, string format=<default>);
+void generate_random_backtrace();
+pair intersectionpoint(path p, path q, real fuzz=<default>);
+pair[] intersectionpoints(path p, path q, real fuzz=<default>);
+pair[] intersectionpoints(explicit path[] p, explicit path[] q, real fuzz=<default>);
+void asy(string format, bool overwrite=<default> ... string[] s);
+bool latex();
+bool adjust(pen p);
+pen adjust(pen p, real arclength, bool cyclic);
+pair Align;
+void exit();
+real[] uniform(real a, real b, int n);
+pair viewportsize;
+pair viewportmargin;
+string VERSION;
+real insphere(triple a, triple b, triple c, triple d, triple e);
+void filldraw(picture pic=<default>, path[] g, pen fillpen=<default>, pen drawpen=<default>);
+void filldraw(frame f, path[] g, pen fillpen=<default>, pen drawpen=<default>);
+real dot(real[] a, real[] b);
+pair dot(pair[] a, pair[] b);
+real dot(explicit pair z, explicit pair w);
+real dot(triple u, triple v);
+void dot(picture pic=<default>, Label[] L=<default>, explicit path g, align align=<default>, string format=<default>, pen p=<default>, filltype filltype=<default>);
+marker dot(pen p=<default>, filltype filltype=<default>);
+void dot(picture pic=<default>, pair z, pen p=<default>, filltype filltype=<default>);
+void dot(frame f, pair z, pen p=<default>, filltype filltype=<default>);
+void dot(picture pic=<default>, Label L, pen p=<default>, filltype filltype=<default>);
+void dot(picture pic=<default>, Label[] L=<default>, pair[] z, align align=<default>, string format=<default>, pen p=<default>, filltype filltype=<default>);
+void dot(picture pic=<default>, path[] g, pen p=<default>, filltype filltype=<default>);
+marker dot;
+void dot(picture pic=<default>, Label L, pair z, align align=<default>, string format=<default>, pen p=<default>, filltype filltype=<default>);
+void list(string s, bool imports=<default>);
+pair NNW;
+string phantom(string s);
+void atexit(void f());
+void atexit()();
+real getreal(string name=<default>, real default=<default>, string prompt=<default>, bool store=<default>);
+int convert(string args=<default>, string file=<default>, string format=<default>);
+pair WNW;
+pen palegray;
+pen palegreen;
+pen palegrey;
+void clip(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, bool copy=<default>);
+void clip(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, bool copy=<default>);
+marginT Margin(path, pen)(real begin, real end);
+marginT Margin(path, pen);
+position Relative(real position);
+side Relative(explicit pair align);
+marginT Margins(path, pen);
+pair truepoint(picture pic=<default>, pair dir, bool user=<default>);
+real arclength(path p);
+real arclength(path3 p);
+bool finite(real x);
+bool finite(pair z);
+bool finite(triple v);
+void updatefunction();
+bool implicitshipout;
+void _draw(frame f, path g, pen p);
+void _draw(frame f, path3 g, triple center=<default>, pen p, int interaction=<default>);
+void _draw(picture pic, path g, pen p, marginT margin(path, pen));
+frame align(frame f, pair align);
+object align(object F, pair align);
+path[] align(path[] g, transform t=<default>, pair position, pair align, pen p=<default>);
+real unitrand();
+string[] history(string name, int n=<default>);
+string[] history(int n=<default>);
+coord[] maxcoords(coord[] in, bool operator <=(coord, coord));
+coord[] maxcoords(coord[] in, bool operator <=(coord, coord));
+pen AvantGarde(string series=<default>, string shape=<default>);
+frame enclose(string prefix=<default>, object F, string format=<default>);
+int count;
+real atan2(real y, real x);
+bool inside(explicit path[] g, pair z, pen fillrule=<default>);
+bool inside(path g, pair z, pen fillrule=<default>);
+int inside(path p, path q, pen fillrule=<default>);
+pair inside(path p, pen fillrule=<default>);
+pair rectify(pair dir);
+arrowhead TeXHead;
+bool initialized(int a);
+bool initialized(real a);
+bool initialized(pair a);
+bool initialized(triple a);
+path[] margin(path[] g, real xmargin, real ymargin);
+pair relative(picture pic=<default>, pair z);
+real erfc(real x);
+int windingnumber(path[] p, pair z);
+real expansionfactor;
+void addArrow(picture pic, arrowhead arrowhead, path g, pen p, real size, real angle, filltype filltype, real position);
+void exitfunction();
+pen gray(pen p);
+pen gray(real gray);
+pen gray;
+real relativedistance(real theta, real phi, real t, bool atleast);
+path circle(pair c, real r);
+void overloadedMessage(file file);
+pen deepmagenta;
+real circlescale;
+string math(string s);
+real circleprecision;
+int Allow;
+real determinant(real[][] a);
+void functionshade(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, string shader=<default>, bool copy=<default>);
+void functionshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, string shader, bool copy=<default>);
+pen red;
+pair[] dirSpecifier(guide g, int t);
+void abort(string s=<default>);
+bool Aspect;
+string hex(pen p);
+int hex(string s);
+path brace(pair a, pair b, real amplitude=<default>);
+void deactivatequote(picture pic=<default>);
+string format(string format, int x, string locale=<default>);
+string format(string format, bool forcemath=<default>, string separator, real x, string locale=<default>);
+string format(string format=<default>, bool forcemath=<default>, real x, string locale=<default>);
+real expm1(real x);
+real[] expm1(real[] a);
+void activatequote(picture pic=<default>);
+int undefined;
+transform zeroTransform;
+string ask(string prompt);
+frame[] fit2(picture[] pictures, picture all);
+pen linecap(int n);
+int linecap(pen p=<default>);
+string outname();
+void newpage(frame f);
+void newpage(picture pic=<default>);
+pen fontcommand(string s);
+real bracemidangle;
+pair accel(path p, int t, int sign=<default>);
+pair accel(path p, real t);
+triple accel(path3 p, int t, int sign=<default>);
+triple accel(path3 p, real t);
+frame Portrait(frame f);
+real braceinnerangle;
+real braceouterangle;
+void tex(frame f, string s);
+void tex(frame f, string s, pair min, pair max);
+void tex(picture pic=<default>, string s);
+void tex(picture pic=<default>, string s, pair min, pair max);
+real bracedefaultratio;
+bool prconly(string format=<default>);
+pen Black;
+triple size3(frame f);
+void size3(picture pic=<default>, real x, real y=<default>, real z=<default>, bool keepAspect=<default>);
+bool eof(file f);
+frame dotframe(pen p=<default>, filltype filltype=<default>);
+frame dotframe;
+real realMax;
+pair NE;
+real realMin;
+path nib(pen p);
+file _outpipe;
+void gouraudshade(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, pair[] z, int[] edges, bool copy=<default>);
+void gouraudshade(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, int[] edges, bool copy=<default>);
+void gouraudshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, pair[] z, int[] edges, bool copy=<default>);
+void gouraudshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, int[] edges, bool copy=<default>);
+pair[] fft(pair[] a, int sign=<default>);
+pair SE;
+pen nobasealign;
+sCAD operator init();
+real animationdelay;
+animation operator init();
+frame NoBox(frame f);
+frame BBox(frame)(real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>);
+void annotate(picture pic=<default>, string title, string text, pair position);
+void babel(string s);
+path removeDuplicates(path p);
+path uncycle(path p, real t);
+path[] bezulate(path[] p);
+real[][] intersections(pair a, pair b, path p);
+void connect(path[] paths, path[] result, path[] patch);
+int countIntersections(path[] p, pair start, pair end);
+real duplicateFuzz;
+path subdivide(path p);
+bool isDuplicate(pair a, pair b, real relSize);
+bool checkSegment(path g, pair p, pair q);
+path section(path p, real t1, real t2, bool loop=<default>);
+real fuzz;
+real maxrefinements;
+path[][] containmentTree(path[] paths);
+binarytree searchtree(... int[] keys);
+object draw(picture pic=<default>, binarytreeNode node, pair pos, int height, real minDist, real levelDist, real nodeDiameter, pen p=<default>, bool condensed=<default>);
+void draw(picture pic=<default>, binarytree tree, real minDist=<default>, real nodeMargin=<default>, pen p=<default>, bool condensed=<default>);
+real nodeMarginDefault;
+key key(int n, bool active=<default>);
+binarytree binarytree(... key[] keys);
+binarytreeNode binarytreeNode(int key);
+key nil;
+real minDistDefault;
+binarytreeNode operator init();
+key operator init();
+binarytree operator init();
+key operator cast(int n);
+int operator cast(key k);
+int[] operator cast(key[] k);
+line intersection(face a, face b);
+real epsilon;
+splitface split(face a, face cut, projection P);
+face operator init();
+line operator init();
+half operator init();
+splitface operator init();
+bsp operator init();
+picture operator cast(face f);
+face operator cast(path3 p);
+void add(picture pic=<default>, face[] faces, projection P=<default>);
+list_data Set2;
+list_data YlOrBr;
+list_data YlGn;
+list_data BuPu;
+list_data tab20;
+list_data tab20b;
+list_data tab20c;
+seg_data gist_earth;
+seg_data gist_ncar;
+seg_data gist_stern;
+list_data PuBuGn;
+seg_data hot;
+list_data Blues;
+seg_data autumn;
+list_data PuBu;
+list_data plasma;
+seg_data nipy_spectral;
+seg_data spring;
+list_data Set3;
+list_data Dark2;
+seg_data bone;
+seg_data hsv;
+list_data bwr;
+list_data viridis;
+list_data Reds;
+list_data inferno;
+seg_data copper;
+seg_data pink;
+list_data YlOrRd;
+seg_data gray;
+list_data RdYlGn;
+seg_data CMRmap;
+seg_data winter;
+list_data Greys;
+list_data Purples;
+list_data BuGn;
+list_data Oranges;
+list_data RdGy;
+seg_data binary;
+list_data magma;
+list_data cividis;
+seg_data operator init();
+list_data operator init();
+list_data BrBG;
+list_data seismic;
+list_data Greens;
+list_data YlGnBu;
+list_data PuRd;
+real[] makeMappingArray(int N, triple[] data, real gamma=<default>);
+seg_data coolwarm;
+list_data RdPu;
+list_data RdBu;
+list_data twilight;
+list_data twilight_shifted;
+seg_data wistia;
+list_data brg;
+list_data Pastel1;
+list_data Pastel2;
+list_data GnBu;
+list_data Accent;
+list_data PuOr;
+list_data Spectral;
+list_data PiYG;
+list_data OrRd;
+seg_data cool;
+list_data PRGn;
+list_data Set1;
+list_data tab10;
+list_data Paired;
+seg_data jet;
+seg_data summer;
+list_data RdYlBu;
+segment case1(pair p0, pair p1, int edge);
+void draw(picture pic=<default>, Label[] L=<default>, guide[][] g, pen[] p);
+void draw(picture pic=<default>, Label[] L=<default>, guide[][] g, pen p=<default>);
+pen[][] interior(picture pic=<default>, guide[][] g, pen[] palette);
+pen[] extend(pen[] palette, pen below, pen above);
+guide[][] connect(pair[][][] points, real[] c, guide join(... guide[]));
+segment case2(pair p0, pair p1, pair p2, real v0, real v1, real v2, int edge);
+void collect(pair[][][] points, real[] c);
+segment case3(pair p0, pair p1, pair p2, real v0, real v1, real v2, int edge=<default>);
+segment checktriangle(pair p0, pair p1, pair p2, real v0, real v1, real v2, int edge=<default>);
+segment operator init();
+void addseg(pair[][] gds, segment seg);
+void fill(picture pic=<default>, guide[][] g, pen[][] palette);
+guide[][] contour(pair[][] z, real[][] f, real[][] midpoint=<default>, real[] c, guide join(... guide[])=<default>);
+guide[][] contour(real[][] f, real[][] midpoint=<default>, pair a, pair b, real[] c, guide join(... guide[])=<default>);
+guide[][] contour(real f(real, real), pair a, pair b, real[] c, int nx=<default>, int ny=<default>, guide join(... guide[])=<default>);
+guide[][] contour(real f(pair), pair a, pair b, real[] c, int nx=<default>, int ny=<default>, guide join(... guide[])=<default>);
+guide[][] contour(pair[] z, real[] f, real[] c, guide join(... guide[])=<default>);
+real eps;
+surface surface(vertex[][] g);
+weighted operator init();
+bucket operator init();
+vertex operator init();
+object operator init();
+vertex[][] contour3(triple[][][] v, real[][][] f, real[][][] midpoint=<default>, projection P=<default>);
+vertex[][] contour3(real[][][] f, real[][][] midpoint=<default>, triple a, triple b, projection P=<default>);
+vertex[][] contour3(real f(real, real, real), triple a, triple b, int nx=<default>, int ny=<default>, int nz=<default>, projection P=<default>);
+real eps;
+void draw(TreeNode root, pair pos);
+real treeNodeStep;
+void drawAll(TreeNode node, frame f);
+real layout(int level, TreeNode node);
+TreeNode operator init();
+void add(TreeNode child, TreeNode parent);
+real treeLevelStep;
+real treeMinNodeWidth;
+TreeNode makeNode(TreeNode parent=<default>, frame f);
+TreeNode makeNode(TreeNode parent=<default>, Label label);
+string link(string label, string text=<default>);
+string embed(string name, string text=<default>, string options=<default>, real width=<default>, real height=<default>);
+string embedplayer(string name, string text=<default>, string options=<default>, real width=<default>, real height=<default>);
+string link(string label, string text=<default>);
+string embed(string name, string text=<default>, string options=<default>, real width=<default>, real height=<default>, string image=<default>);
+string hyperlink(string url, string text);
+real gluonratio;
+real gluonamplitude;
+void drawGluon(picture pic=<default>, path p, real amp=<default>, real width=<default>, pen fgpen=<default>, bool erasebg=<default>, pen bgpen=<default>, real vertexangle=<default>, real margin=<default>);
+void drawGhost(picture pic=<default>, path p, pen fgpen=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool erasebg=<default>, pen bgpen=<default>, real vertexangle=<default>, real margin=<default>);
+void drawVertex(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>);
+void drawVertexO(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>, bool erasebg=<default>, pen bgpen=<default>);
+void drawVertexX(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>);
+void drawVertexBox(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>);
+void drawVertexBoxO(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>, bool erasebg=<default>, pen bgpen=<default>);
+void drawVertexOX(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>, bool erasebg=<default>, pen bgpen=<default>);
+void drawVertexTriangle(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>);
+void drawVertexTriangleO(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>, bool erasebg=<default>, pen bgpen=<default>);
+void drawVertexBoxX(picture pic=<default>, pair xy, real r=<default>, pen fgpen=<default>, bool erasebg=<default>, pen bgpen=<default>);
+void do_overpaint(picture pic, path p, pen bgpen, real halfwidth, real vertexangle);
+void texshipout(string stem, picture pic=<default>, bool xalign=<default>);
+pen doublelinepen;
+real doublelinespacing;
+void drawDoubleLine(picture pic=<default>, path p, pen fgpen=<default>, real dlspacing=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool erasebg=<default>, pen bgpen=<default>, real vertexangle=<default>, real margin=<default>);
+void drawScalar(picture pic=<default>, path p, pen fgpen=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool erasebg=<default>, pen bgpen=<default>, real vertexangle=<default>, real margin=<default>);
+bool overpaint;
+path photon(path p, real amp=<default>, real width=<default>);
+pen photonpen;
+real photonratio;
+real photonamplitude;
+string includegraphicscommand;
+pen momarrowpen;
+real momarrowsize(pen p=<default>);
+real momarrowlength;
+real momarrowoffset;
+real momarrowmargin;
+real momarrowfactor;
+bool XYAlign;
+pen vertexpen;
+real vertexsize;
+path momArrowPath(path p, align align, position pos, real offset=<default>, real length=<default>);
+void drawPhoton(picture pic=<default>, path p, real amp=<default>, real width=<default>, pen fgpen=<default>, bool erasebg=<default>, pen bgpen=<default>, real vertexangle=<default>, real margin=<default>);
+bool YAlign;
+pen backgroundpen;
+pen scalarpen;
+pen fermionpen;
+pen bigvertexpen;
+real bigvertexsize;
+real minvertexangle;
+void drawMomArrow(picture pic=<default>, path p, align align, position pos=<default>, real offset=<default>, real length=<default>, pen fgpen=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool erasebg=<default>, pen bgpen=<default>, real margin=<default>);
+void fmdefaults();
+real linemargin;
+pen ghostpen;
+void drawFermion(picture pic=<default>, path p, pen fgpen=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool erasebg=<default>, pen bgpen=<default>, real vertexangle=<default>, real margin=<default>);
+bool currentarrow(picture, path, pen, marginT(path, pen));
+bool currentmomarrow(picture, path, pen, marginT(path, pen));
+bool appendsuffix;
+path gluon(path p, real amp=<default>, real width=<default>);
+pen gluonpen;
+Dir Left;
+block roundrectangle(object body, pair center=<default>, pen fillpen=<default>, pen drawpen=<default>, real ds=<default>, real dw=<default>, real minwidth=<default>, real minheight=<default>);
+block diamond(object body, pair center=<default>, pen fillpen=<default>, pen drawpen=<default>, real ds=<default>, real dw=<default>, real height=<default>, real minwidth=<default>, real minheight=<default>);
+void draw(picture pic=<default>, block block, pen p=<default>);
+real minblockwidth;
+real minblockheight;
+real defaultexcursion;
+path path(pair[] point ... flowdir[] dir);
+Dir Up;
+real mincirclediameter;
+flowdir Vertical;
+block rectangle(object header, object body, pair center=<default>, pen headerpen=<default>, pen bodypen=<default>, pen drawpen=<default>, real dx=<default>, real minheaderwidth=<default>, real minheaderheight=<default>, real minbodywidth=<default>, real minbodyheight=<default>);
+block rectangle(object body, pair center=<default>, pen fillpen=<default>, pen drawpen=<default>, real dx=<default>, real minwidth=<default>, real minheight=<default>);
+block parallelogram(object body, pair center=<default>, pen fillpen=<default>, pen drawpen=<default>, real dx=<default>, real slope=<default>, real minwidth=<default>, real minheight=<default>);
+block blockconnector(block, block)(picture pic, transform t, pen p=<default>, marginT margin(path, pen)=<default>);
+block circle(object body, pair center=<default>, pen fillpen=<default>, pen drawpen=<default>, real dr=<default>, real mindiameter=<default>);
+flowdir operator init();
+block operator init();
+Dir operator init();
+block operator --(block b1, Label label);
+block operator --(block b1, Dir dir);
+block operator --(block b, bool arrowbar(picture, path, pen, marginT(path, pen)));
+flowdir Horizontal;
+block bevel(object body, pair center=<default>, pen fillpen=<default>, pen drawpen=<default>, real dh=<default>, real dw=<default>, real minwidth=<default>, real minheight=<default>);
+Dir Right;
+Dir Down;
+int[] numarray;
+point midpoint(segment s);
+point midpoint(side side);
+point isotomicconjugate(triangle t, point M);
+real rd(real x, real y, real z);
+point circumcenter(point A, point B, point C);
+point circumcenter(triangle t);
+circle circumcircle(point A, point B, point C);
+circle circumcircle(triangle t);
+point point(coordsys R, pair p, real m=<default>);
+point point(explicit pair p, real m);
+point point(coordsys R, explicit point M, real m=<default>);
+point point(explicit vector u);
+point point(circle c, abscissa l);
+point point(ellipse el, abscissa l);
+point point(parabola p, abscissa l);
+point point(hyperbola h, abscissa l);
+point point(explicit conic co, abscissa l);
+point point(line l, abscissa x);
+point point(line l, explicit real x);
+point point(line l, explicit int x);
+point point(explicit circle c, explicit real x);
+point point(explicit circle c, explicit int x);
+point point(explicit ellipse el, explicit real x);
+point point(explicit ellipse el, explicit int x);
+point point(explicit parabola p, explicit real x);
+point point(explicit parabola p, explicit int x);
+point point(explicit hyperbola h, explicit real x);
+point point(explicit hyperbola h, explicit int x);
+point point(explicit conic co, explicit real x);
+point point(explicit conic co, explicit int x);
+point point(arc a, abscissa l);
+point point(arc a, real x);
+pair point(explicit arc a, int x);
+point point(explicit mass m);
+point point(explicit vertex V);
+point point(trilinear tri);
+point point(circle c, point M);
+point point(circle c, explicit vector v);
+bool finite(explicit point p);
+void dot(picture pic=<default>, Label L, explicit point Z, align align=<default>, string format=<default>, pen p=<default>);
+real dot(point A, point B);
+real dot(point A, explicit pair B);
+real dot(explicit pair A, point B);
+void dot(picture pic=<default>, Label L, explicit mass M, align align=<default>, string format=<default>, pen p=<default>);
+void dot(picture pic=<default>, triangle t, pen p=<default>);
+real[] realquarticroots(real a, real b, real c, real d, real e);
+point origin;
+point origin(coordsys R=<default>);
+void draw(picture pic=<default>, Label L=<default>, line l, bool dirA=<default>, bool dirB=<default>, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, Label legend=<default>, marker marker=<default>, path pathModifier(path)=<default>);
+void draw(picture pic=<default>, Label[] L=<default>, line[] l, align align=<default>, pen[] p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, Label[] legend=<default>, marker marker=<default>, path pathModifier(path)=<default>);
+void draw(picture pic=<default>, Label[] L=<default>, line[] l, align align=<default>, pen p, bool arrow(picture, path, pen, marginT(path, pen))=<default>, Label[] legend=<default>, marker marker=<default>, path pathModifier(path)=<default>);
+void draw(picture pic=<default>, Label L=<default>, circle c, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(picture pic=<default>, Label L=<default>, ellipse el, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(picture pic=<default>, Label L=<default>, parabola parabola, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(picture pic=<default>, Label L=<default>, hyperbola h, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(picture pic=<default>, Label L=<default>, explicit conic co, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(picture pic=<default>, Label L=<default>, arc a, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
+void draw(picture pic=<default>, triangle t, pen p=<default>, marker marker=<default>);
+void draw(picture pic=<default>, triangle[] t, pen p=<default>, marker marker=<default>);
+coordsys defaultcoordsys;
+string defaultmassformat;
+line radicalline(circle c1, circle c2);
+point radicalcenter(circle c1, circle c2);
+point radicalcenter(circle c1, circle c2, circle c3);
+ellipse ellipse(point F1, point F2, real a);
+ellipse ellipse(point F1, point F2, point M);
+ellipse ellipse(point C, real a, real b, real angle=<default>);
+ellipse ellipse(bqe bqe);
+ellipse ellipse(point M1, point M2, point M3, point M4, point M5);
+path arctopath(arc a, int n);
+bool inside(ellipse el, point M);
+bool inside(parabola p, point M);
+int ellipsenodesnumber(real a, real b);
+int ellipsenodesnumber(real a, real b, real angle1, real angle2, bool dir);
+int ellipsenodesnumberfactor;
+bool byfoci;
+transform reflect(line l);
+transform reflect(line l1, line l2, bool safe=<default>);
+real[] bangles(picture pic=<default>, parabola p);
+real[][] bangles(picture pic=<default>, hyperbola h);
+abscissa relabscissa(real x);
+abscissa relabscissa(int x);
+abscissa relabscissa(line l, point M);
+abscissa relabscissa(circle c, point M);
+abscissa relabscissa(ellipse el, point M);
+abscissa relabscissa(conic co, point M);
+abscissa relabscissa(arc a, point M);
+circle incircle(point A, point B, point C);
+circle incircle(triangle t);
+mass masscenter(... mass[] M);
+vector unit(point M);
+vector unit(vector u);
+line Ox(coordsys R=<default>);
+line Ox;
+conic conic(point F, line l, real e);
+conic conic(point M1, point M2, point M3, point M4, point M5);
+conic conic(bqe bqe);
+bool defined(point P);
+string conictype(bqe bqe);
+triangle antipedal(triangle t, point M);
+void clipdraw(picture pic=<default>, Label L=<default>, path g, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, real xmargin=<default>, real ymargin=<default>, Label legend=<default>, marker marker=<default>);
+real perpfactor;
+int conicnodesfactor;
+int conicnodesnumber(conic co, real angle1, real angle2, bool dir=<default>);
+line altitude(vertex V);
+line altitude(side side);
+point isogonalconjugate(triangle t, point M);
+point isogonal(side side, point M);
+line isogonal(vertex V, point M);
+triangle isogonal(triangle t, point M);
+line hline(coordsys R=<default>);
+line hline;
+int[] tricoef(side side);
+path arcfromfocus(conic co, real angle1, real angle2, int n=<default>, bool direction=<default>);
+line sector(int n=<default>, int p=<default>, line l1, line l2, real angle=<default>, bool sharp=<default>);
+path arcfromcenter(ellipse el, real angle1, real angle2, bool direction=<default>, int n=<default>);
+path arcfromcenter(hyperbola h, real angle1, real angle2, int n=<default>, bool direction=<default>);
+path arcfromcenter(explicit conic co, real angle1, real angle2, int n, bool direction=<default>);
+line vline(coordsys R=<default>);
+line vline;
+vector vector(coordsys R=<default>, pair v);
+vector vector(point M);
+real[] intersect(path g, explicit pair p, real fuzz=<default>);
+real[] intersect(path g, explicit point P, real fuzz=<default>);
+int sgnd(real x);
+int sgnd(int x);
+circle excircle(point A, point B, point C);
+circle excircle(side side);
+line extend(line l);
+point intersectionpoint(line l1, line l2);
+pair[] intersectionpoints(pair A, pair B, real a, real b, real c, real d, real f, real g);
+pair[] intersectionpoints(pair A, pair B, real[] equation);
+point[] intersectionpoints(line l, path g);
+point[] intersectionpoints(bqe bqe1, bqe bqe2);
+point[] intersectionpoints(triangle t, line l, bool extended=<default>);
+point[] intersectionpoints(line l, triangle t, bool extended=<default>);
+point[] intersectionpoints(line l, circle c);
+point[] intersectionpoints(circle c, line l);
+point[] intersectionpoints(line l, ellipse el);
+point[] intersectionpoints(ellipse el, line l);
+point[] intersectionpoints(line l, parabola p);
+point[] intersectionpoints(parabola p, line l);
+point[] intersectionpoints(line l, hyperbola h);
+point[] intersectionpoints(hyperbola h, line l);
+point[] intersectionpoints(line l, conic co);
+point[] intersectionpoints(conic co, line l);
+point[] intersectionpoints(conic co1, conic co2);
+point[] intersectionpoints(triangle t, conic co, bool extended=<default>);
+point[] intersectionpoints(conic co, triangle t, bool extended=<default>);
+point[] intersectionpoints(ellipse a, ellipse b);
+point[] intersectionpoints(ellipse a, circle b);
+point[] intersectionpoints(circle a, ellipse b);
+point[] intersectionpoints(ellipse a, parabola b);
+point[] intersectionpoints(parabola a, ellipse b);
+point[] intersectionpoints(ellipse a, hyperbola b);
+point[] intersectionpoints(hyperbola a, ellipse b);
+point[] intersectionpoints(circle a, parabola b);
+point[] intersectionpoints(parabola a, circle b);
+point[] intersectionpoints(circle a, hyperbola b);
+point[] intersectionpoints(hyperbola a, circle b);
+point[] intersectionpoints(parabola a, parabola b);
+point[] intersectionpoints(parabola a, hyperbola b);
+point[] intersectionpoints(hyperbola a, parabola b);
+point[] intersectionpoints(hyperbola a, hyperbola b);
+point[] intersectionpoints(circle c1, circle c2);
+point[] intersectionpoints(conic co, arc a);
+point[] intersectionpoints(arc a, conic co);
+point[] intersectionpoints(arc a1, arc a2);
+point[] intersectionpoints(line l, arc a);
+point[] intersectionpoints(arc a, line l);
+point intouch(side side);
+triangle intouch(triangle t);
+point orthocentercenter(point A, point B, point C);
+point orthocentercenter(triangle t);
+real rf(real x, real y, real z);
+bool concurrent(... line[] l);
+real inradius(point A, point B, point C);
+real inradius(triangle t);
+pen addpenline;
+pen addpenline(pen p);
+pen addpenarc;
+pen addpenarc(pen p);
+void label(picture pic=<default>, Label L, explicit mass M, align align=<default>, string format=<default>, pen p=<default>, filltype filltype=<default>);
+void label(picture pic=<default>, Label L, vertex V, pair align=<default>, real alignFactor=<default>, pen p=<default>, filltype filltype=<default>);
+void label(picture pic=<default>, Label LA=<default>, Label LB=<default>, Label LC=<default>, triangle t, real alignAngle=<default>, real alignFactor=<default>, pen p=<default>, filltype filltype=<default>);
+real abs(coordsys R, pair m);
+real abs(explicit point M);
+point curpoint(line l, real x);
+point curpoint(explicit circle c, real x);
+point curpoint(explicit ellipse el, real x);
+point curpoint(explicit parabola p, real x);
+point curpoint(conic co, real x);
+point curpoint(arc a, real x);
+line bisector(line l1, line l2, real angle=<default>, bool sharp=<default>);
+line bisector(point A, point B, point C, point D, real angle=<default>, bool sharp=<default>);
+line bisector(segment s, real angle=<default>);
+line bisector(point A, point B, real angle=<default>);
+line bisector(vertex V, real angle=<default>);
+line bisector(side side);
+bqe canonical(bqe bqe);
+point bisectorpoint(side side);
+abscissa angabscissa(real x, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
+abscissa angabscissa(int x, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
+abscissa angabscissa(circle c, point M);
+abscissa angabscissa(ellipse el, point M, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
+abscissa angabscissa(hyperbola h, point M, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
+abscissa angabscissa(parabola p, point M);
+abscissa angabscissa(explicit conic co, point M);
+abscissa angabscissa(arc a, point M);
+pair locate(point P);
+point locate(pair p);
+pair locate(explicit vector v);
+bool samecoordsys(bool warn=<default> ... point[] M);
+bool samecoordsys(bool warn=<default> ... bqe[] bqes);
+triangle extouch(triangle t);
+triangle extouch(side side);
+coordsys canonicalcartesiansystem(ellipse el);
+coordsys canonicalcartesiansystem(parabola p);
+coordsys canonicalcartesiansystem(hyperbola h);
+coordsys canonicalcartesiansystem(explicit conic co);
+arc arc(ellipse el, real angle1, real angle2, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>, bool direction=<default>);
+arc arc(ellipse el, explicit abscissa x1, explicit abscissa x2, bool direction=<default>);
+arc arc(ellipse el, point M, point N, bool direction=<default>);
+arc arc(explicit arc a, abscissa x1, abscissa x2);
+arc arc(explicit arc a, point M, point N);
+path arc(explicit pair B, explicit pair A, explicit pair C, real r);
+void markrightangle(picture pic=<default>, point A, point O, point B, real size=<default>, pen p=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+real epsgeo;
+real sharpangle(line l1, line l2);
+bool isparabola(bqe bqe);
+real sharpdegrees(line l1, line l2);
+real exradius(point A, point B, point C);
+real exradius(side side);
+abscissa nodabscissa(real x);
+abscissa nodabscissa(int x);
+abscissa nodabscissa(line l, point M);
+abscissa nodabscissa(circle c, point M);
+abscissa nodabscissa(ellipse el, point M);
+abscissa nodabscissa(parabola p, point M);
+abscissa nodabscissa(conic co, point M);
+abscissa nodabscissa(arc a, point M);
+coordsys coordsys(line l);
+coordsys coordsys(conic co);
+coordsys coordsys(ellipse el);
+pair coordinates(point M);
+real length(explicit point M);
+real length(segment s);
+int arcnodesnumber(explicit arc a);
+point[] standardizecoordsys(coordsys R=<default>, bool warn=<default> ... point[] M);
+int nodesystem;
+bool collinear(vector u, vector v);
+point centroid(point A, point B, point C);
+point centroid(triangle t);
+int angularsystem;
+path square(pair z1, pair z2);
+point symmedian(triangle t);
+point symmedian(side side);
+line symmedian(vertex V);
+triangle symmedial(triangle t);
+int curvilinearsystem;
+bqe bqe(coordsys R=<default>, real a, real b, real c, real d, real e, real f);
+bqe bqe(point M1, point M2, point M3, point M4, point M5);
+arc arccircle(point A, point M, point B);
+arc arccircle(point A, point B, real angle, bool direction=<default>);
+point relpoint(line l, real x);
+point relpoint(explicit circle c, real x);
+point relpoint(explicit ellipse el, real x);
+point relpoint(explicit parabola p, real x);
+point relpoint(explicit hyperbola h, real x);
+point relpoint(explicit conic co, explicit real x);
+point relpoint(explicit conic co, explicit int x);
+point relpoint(arc a, real x);
+point changecoordsys(coordsys R, point M);
+vector changecoordsys(coordsys R, vector v);
+line changecoordsys(coordsys R, line l);
+bqe changecoordsys(coordsys R, bqe bqe);
+conic changecoordsys(coordsys R, conic co);
+real angle(explicit point M, coordsys R=<default>, bool warn=<default>);
+real angle(explicit vector v, coordsys R=<default>, bool warn=<default>);
+real angle(line l, coordsys R=<default>);
+real angle(line l1, line l2);
+real angle(arc a);
+point[] fermat(triangle t);
+real arclength(circle c);
+real arclength(ellipse el);
+real arclength(ellipse el, real angle1, real angle2, bool direction=<default>, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
+real arclength(parabola p, real angle);
+real arclength(parabola p, real angle1, real angle2);
+real arclength(parabola p);
+real arclength(arc a);
+line reverse(line l);
+arc reverse(arc a);
+point gergonne(triangle t);
+real focusToCenter(ellipse el, real a);
+hyperbola hyperbola(point P1, point P2, real ae, bool byfoci=<default>);
+hyperbola hyperbola(point C, real a, real b, real angle=<default>);
+hyperbola hyperbola(bqe bqe);
+hyperbola hyperbola(point M1, point M2, point M3, point M4, point M5);
+side opposite(vertex V);
+vertex opposite(side side);
+int hyperbolanodesnumber(hyperbola h, real angle1, real angle2);
+path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)(conic co);
+int hyperbolanodesnumberfactor;
+line parallel(point M, line l);
+line parallel(point M, explicit vector dir);
+line parallel(point M, explicit pair dir);
+bool parallel(line l1, line l2, bool strictly=<default>);
+transform projection(point A, point B);
+transform projection(point A, point B, point C, point D, bool safe=<default>);
+transform projection(line l);
+transform projection(line l1, line l2, bool safe=<default>);
+bool degenerate(conic c);
+bool degenerate(circle c);
+bool degenerate(ellipse el);
+line line(point A, bool extendA=<default>, point B, bool extendB=<default>);
+line line(segment s);
+line line(real a, point A=<default>);
+line line(point A=<default>, real a);
+line line(int a, point A=<default>);
+line line(coordsys R=<default>, real slope, real origin);
+line line(coordsys R=<default>, real a, real b, real c);
+line line(circle c);
+line line(explicit side side);
+line complementary(explicit line l);
+line[] complementary(explicit segment s);
+arc complementary(arc a);
+point ppoint(arc a, real x);
+path fromFocus(conic co, real angle1, real angle2, int n, bool direction);
+bool between(point M, point O, point N);
+bool sameside(point M, point N, point O);
+bool sameside(point M, point P, line l);
+point[] sameside(point M, line l1, line l2);
+arc arcsubtended(point A, point B, real angle);
+void distance(picture pic=<default>, Label L=<default>, point A, point B, bool rotated=<default>, real offset=<default>, pen p=<default>, pen joinpen=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>);
+real distance(point M, line l);
+real distance(line l, point M);
+point incenter(point A, point B, point C);
+point incenter(triangle t);
+void write(explicit line l);
+void write(explicit segment s);
+void write(trilinear tri);
+triangle incentral(triangle t);
+point arcsubtendedcenter(point A, point B, real angle);
+circle circle(explicit point C, real r);
+circle circle(point A, point B);
+circle circle(segment s);
+circle circle(point A, point B, point C);
+circle circle(triangle t);
+circle circle(inversion i);
+point angpoint(conic co, real angle);
+point angpoint(explicit circle c, real x);
+point angpoint(explicit ellipse el, real x, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
+point angpoint(explicit parabola p, real x);
+point angpoint(explicit hyperbola h, real x, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
+point angpoint(arc a, real angle);
+triangle orthic(triangle t);
+int circlenodesnumber(real r);
+int circlenodesnumber(real r, real angle1, real angle2);
+path compassmark(pair O, pair A, real position, real angle=<default>);
+bool byvertices;
+int circlenodesnumberfactor;
+transform xscale(real k, point M);
+transform yscale(real k, point M);
+transform scale(real k, point M);
+transform scale(real k, point A, point B, point C, point D, bool safe=<default>);
+transform scale(real k, line l1, line l2, bool safe=<default>);
+point operator +(explicit point P1, explicit point P2);
+point operator +(explicit point P1, explicit pair p2);
+point operator +(explicit pair p1, explicit point p2);
+point operator +(point M, explicit vector v);
+point operator +(explicit pair m, explicit vector v);
+vector operator +(explicit vector v1, explicit vector v2);
+line operator +(line l, vector u);
+conic operator +(conic c, explicit point M);
+conic operator +(conic c, explicit pair m);
+conic operator +(conic c, vector v);
+circle operator +(explicit circle c, explicit point M);
+circle operator +(explicit circle c, pair m);
+circle operator +(explicit circle c, vector m);
+abscissa operator +(real x, explicit abscissa a);
+abscissa operator +(explicit abscissa a, real x);
+abscissa operator +(int x, explicit abscissa a);
+arc operator +(explicit arc a, point M);
+arc operator +(explicit arc a, vector v);
+mass operator +(mass M1, mass M2);
+mass operator +(explicit mass M, real x);
+mass operator +(explicit mass M, int x);
+point operator -(explicit point P);
+point operator -(explicit point P1, explicit point P2);
+point operator -(explicit point P1, explicit pair p2);
+point operator -(explicit pair p1, explicit point P2);
+point operator -(point M, explicit vector v);
+vector operator -(explicit vector v);
+point operator -(explicit pair m, explicit vector v);
+vector operator -(explicit vector v1, explicit vector v2);
+line operator -(line l, vector u);
+conic operator -(conic c, explicit point M);
+conic operator -(conic c, explicit pair m);
+conic operator -(conic c, vector v);
+circle operator -(explicit circle c, explicit point M);
+circle operator -(explicit circle c, pair m);
+circle operator -(explicit circle c, vector m);
+abscissa operator -(explicit abscissa a);
+abscissa operator -(real x, explicit abscissa a);
+abscissa operator -(explicit abscissa a, real x);
+abscissa operator -(int x, explicit abscissa a);
+arc operator -(explicit arc a, point M);
+arc operator -(explicit arc a, vector v);
+mass operator -(mass M1, mass M2);
+mass operator -(explicit mass M, real x);
+mass operator -(explicit mass M, int x);
+pair operator *(coordsys R, pair p);
+path operator *(coordsys R, path g);
+coordsys operator *(transform t, coordsys R);
+point operator *(real x, explicit point P);
+point operator *(transform t, explicit point P);
+point operator *(explicit point P1, explicit point P2);
+point operator *(explicit point P1, explicit pair p2);
+point operator *(explicit pair p1, explicit point p2);
+vector operator *(real x, explicit vector v);
+vector operator *(transform t, explicit vector v);
+vector operator *(explicit point M, explicit vector v);
+line operator *(transform t, line l);
+line operator *(real x, line l);
+line operator *(int x, line l);
+line operator *(point M, line l);
+circle operator *(real x, explicit circle c);
+circle operator *(int x, explicit circle c);
+ellipse operator *(transform t, ellipse el);
+parabola operator *(transform t, parabola p);
+ellipse operator *(transform t, circle c);
+hyperbola operator *(transform t, hyperbola h);
+conic operator *(transform t, conic co);
+ellipse operator *(real x, ellipse el);
+abscissa operator *(real x, explicit abscissa a);
+abscissa operator *(explicit abscissa a, real x);
+arc operator *(transform t, explicit arc a);
+arc operator *(real x, explicit arc a);
+arc operator *(int x, explicit arc a);
+mass operator *(real x, explicit mass M);
+mass operator *(int x, explicit mass M);
+mass operator *(transform t, mass M);
+triangle operator *(transform T, triangle t);
+point operator *(inversion i, point P);
+circle operator *(inversion i, line l);
+circle operator *(inversion i, circle c);
+arc operator *(inversion i, segment s);
+path operator *(inversion i, triangle t);
+coordsys operator init();
+point operator init();
+vector operator init();
+line operator init();
+segment operator init();
+bqe operator init();
+conic operator init();
+circle operator init();
+ellipse operator init();
+parabola operator init();
+hyperbola operator init();
+abscissa operator init();
+arc operator init();
+mass operator init();
+triangle operator init();
+trilinear operator init();
+inversion operator init();
+pair operator cast(point P);
+pair[] operator cast(point[] P);
+point operator cast(pair p);
+point[] operator cast(pair[] p);
+guide operator cast(point p);
+path operator cast(point p);
+point operator cast(vector v);
+vector operator cast(pair v);
+vector operator cast(explicit point v);
+pair operator cast(explicit vector v);
+align operator cast(vector v);
+line operator cast(segment s);
+segment operator cast(line l);
+ellipse operator cast(circle c);
+circle operator cast(ellipse el);
+ellipse operator cast(conic co);
+parabola operator cast(conic co);
+conic operator cast(parabola p);
+hyperbola operator cast(conic co);
+conic operator cast(hyperbola h);
+conic operator cast(ellipse el);
+conic operator cast(circle c);
+circle operator cast(conic c);
+path operator cast(ellipse el);
+path operator cast(circle c);
+path operator cast(parabola p);
+path operator cast(hyperbola h);
+path operator cast(conic co);
+abscissa operator cast(explicit position position);
+abscissa operator cast(real x);
+abscissa operator cast(int x);
+path operator cast(explicit arc a);
+guide operator cast(explicit arc a);
+point operator cast(mass m);
+mass operator cast(point M);
+point[] operator cast(mass[] m);
+mass[] operator cast(point[] P);
+mass operator cast(pair m);
+path operator cast(mass M);
+guide operator cast(mass M);
+line operator cast(side side);
+point operator cast(vertex V);
+point operator cast(trilinear tri);
+circle operator cast(inversion i);
+inversion operator cast(circle c);
+void lineinversion();
+pair operator /(pair p, coordsys R);
+point operator /(explicit point P, real x);
+point operator /(real x, explicit point P);
+vector operator /(explicit vector v, real x);
+line operator /(line l, real x);
+line operator /(line l, int x);
+circle operator /(explicit circle c, real x);
+circle operator /(explicit circle c, int x);
+ellipse operator /(ellipse el, real x);
+abscissa operator /(real x, explicit abscissa a);
+abscissa operator /(explicit abscissa a, real x);
+abscissa operator /(int x, explicit abscissa a);
+arc operator /(explicit arc a, real x);
+mass operator /(explicit mass M, real x);
+mass operator /(explicit mass M, int x);
+transform scaleO(real x);
+real operator ^(point M, explicit circle c);
+bool operator ==(coordsys c1, coordsys c2);
+bool operator ==(explicit point M, explicit point N);
+bool operator ==(explicit vector u, explicit vector v);
+bool operator ==(line l1, line l2);
+bool operator !=(explicit point M, explicit point N);
+bool operator !=(line l1, line l2);
+transform xscaleO(real x);
+transform yscaleO(real x);
+line[] operator ^^(line l1, line l2);
+line[] operator ^^(line l1, line[] l2);
+line[] operator ^^(line[] l2, line l1);
+line[] operator ^^(line[] l1, line[] l2);
+triangle[] operator ^^(triangle[] t1, triangle t2);
+triangle[] operator ^^(... triangle[] t);
+real elle(real phi, real k);
+point excenter(point A, point B, point C);
+point excenter(side side);
+mass mass(point M, real m);
+mass mass(explicit point P);
+mass mass(coordsys R, explicit pair p, real m);
+bool operator @(point m, line l);
+bool operator @(point M, conic co);
+bool operator @(point M, explicit circle c);
+bool operator @(point M, arc a);
+triangle triangle(line l1, line l2, line l3);
+trilinear trilinear(triangle t, real a, real b, real c);
+trilinear trilinear(triangle t, point M);
+trilinear trilinear(triangle t, real f(real, real, real), real a=<default>, real b=<default>, real c=<default>);
+triangle triangleAbc(real alpha, real b, real c, real angle=<default>, point A=<default>);
+triangle triangleabc(real a, real b, real c, real angle=<default>, point A=<default>);
+triangle anticomplementary(triangle t);
+vector dir(vertex V);
+real degrees(explicit point M, coordsys R=<default>, bool warn=<default>);
+real degrees(vector v, coordsys R=<default>, bool warn=<default>);
+real degrees(line l, coordsys R=<default>);
+real degrees(line l1, line l2);
+real degrees(arc a);
+real linemargin;
+real linemargin();
+segment segment(point A, point B);
+segment segment(line l);
+segment segment(explicit side side);
+line Oy(coordsys R=<default>);
+line Oy;
+path fromCenter(conic co, real angle1, real angle2, int n, bool direction);
+void markarc(picture pic=<default>, Label L=<default>, int n=<default>, real radius=<default>, real space=<default>, arc a, pen sectorpen=<default>, pen markpen=<default>, marginT margin(path, pen)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marker marker=<default>);
+real approximate(real t);
+real[] approximate(real[] T);
+void markangle(picture pic=<default>, Label L=<default>, int n=<default>, real radius=<default>, real space=<default>, explicit line l1, explicit line l2, explicit pair align=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, pen p=<default>, filltype filltype=<default>, marginT margin(path, pen)=<default>, marker marker=<default>);
+void markangle(picture pic=<default>, Label L=<default>, int n=<default>, real radius=<default>, real space=<default>, explicit line l1, explicit line l2, explicit vector align, bool arrow(picture, path, pen, marginT(path, pen))=<default>, pen p=<default>, filltype filltype=<default>, marginT margin(path, pen)=<default>, marker marker=<default>);
+transform hprojection(line l, bool safe=<default>);
+point conj(explicit point M);
+vector conj(explicit vector u);
+hyperbola conj(hyperbola h);
+transform vprojection(line l, bool safe=<default>);
+parabola parabola(point F, line l);
+parabola parabola(point F, point vertex);
+parabola parabola(point F, real a, real angle);
+parabola parabola(bqe bqe);
+parabola parabola(point M1, point M2, point M3, line l);
+parabola parabola(point M1, point M2, point M3, point M4, point M5);
+bool onpath(picture pic=<default>, path g, point M, pen p=<default>);
+int parabolanodesnumber(parabola p, real angle1, real angle2);
+int parabolanodesnumberfactor;
+path NoModifier(path);
+coordsys currentcoordsys;
+point foot(vertex V);
+point foot(side side);
+path currentpolarconicroutine(conic co, real angle1, real angle2, int n, bool direction);
+transform rotate(explicit pair dir);
+transform rotate(explicit vector dir);
+transform rotate(explicit point dir);
+real EPS;
+transform rotateO(real a);
+line perpendicular(point M, line l);
+line perpendicular(point M, explicit vector normal);
+line perpendicular(point M, explicit pair normal);
+bool perpendicular(line l1, line l2);
+void perpendicular(picture pic=<default>, pair z, pair align, pair dir=<default>, real size=<default>, pen p=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+void perpendicular(picture pic=<default>, pair z, pair align, path g, real size=<default>, pen p=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+real binomial(real n, real k);
+void perpendicularmark(picture pic=<default>, point z, explicit pair align, explicit pair dir=<default>, real size=<default>, pen p=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+void perpendicularmark(picture pic=<default>, point z, vector align, vector dir=<default>, real size=<default>, pen p=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+void perpendicularmark(picture pic=<default>, point z, explicit pair align, path g, real size=<default>, pen p=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+void perpendicularmark(picture pic=<default>, point z, vector align, path g, real size=<default>, pen p=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+void perpendicularmark(picture pic=<default>, line l1, line l2, real size=<default>, pen p=<default>, int quarter=<default>, marginT margin(path, pen)=<default>, filltype filltype=<default>);
+pair attract(pair m, path g, real fuzz=<default>);
+point attract(point M, path g, real fuzz=<default>);
+void Drawline(picture pic=<default>, Label L=<default>, pair P, bool dirP=<default>, pair Q, bool dirQ=<default>, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, Label legend=<default>, marker marker=<default>, path pathModifier(path)=<default>);
+bool simeq(point A, point B, real fuzz=<default>);
+bool simeq(point a, real b, real fuzz=<default>);
+point inverse(real k, point A, point M);
+circle inverse(real k, point A, line l);
+circle inverse(real k, point A, circle c);
+arc inverse(real k, point A, segment s);
+inversion inversion(real k, point C);
+inversion inversion(point C, real k);
+inversion inversion(circle c1, circle c2, real sgn=<default>);
+inversion inversion(circle c1, circle c2, circle c3);
+inversion inversion(circle c);
+coordsys cartesiansystem(pair O=<default>, pair i, pair j);
+line tangent(circle c, abscissa x);
+line tangent(circle c, point M);
+line tangent(circle c, explicit vector v);
+line tangent(ellipse el, abscissa x);
+line tangent(parabola p, abscissa x);
+line tangent(hyperbola h, abscissa x);
+line tangent(explicit arc a, abscissa x);
+line tangent(explicit arc a, point M);
+line[] tangents(circle c, point M);
+line[] tangents(ellipse el, point M);
+line[] tangents(parabola p, point M);
+line[] tangents(hyperbola h, point M);
+real centerToFocus(ellipse el, real a);
+bqe equation(ellipse el);
+bqe equation(parabola p);
+bqe equation(hyperbola h);
+bqe equation(explicit conic co);
+triangle tangential(triangle t);
+triangle pedal(triangle t, point M);
+line pedal(side side, point M);
+string massformat(string format=<default>, string s, mass M);
+int relativesystem;
+triangle cevian(triangle t, point P);
+point cevian(side side, point P);
+line cevian(vertex V, point P);
+void drawline(picture pic=<default>, triangle t, pen p=<default>);
+void addMargins(picture pic=<default>, real lmargin=<default>, real bmargin=<default>, real rmargin=<default>, real tmargin=<default>, bool rigid=<default>, bool allObject=<default>);
+triangle medial(triangle t);
+line median(vertex V);
+line median(side side);
+void show(picture pic=<default>, Label lo=<default>, Label li=<default>, Label lj=<default>, coordsys R, pen dotpen=<default>, pen xpen=<default>, pen ypen=<default>, pen ipen=<default>, pen jpen=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>);
+void show(Label L, vector v, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>);
+void show(picture pic=<default>, line l, pen p=<default>);
+void show(picture pic=<default>, Label LA=<default>, Label LB=<default>, Label LC=<default>, Label La=<default>, Label Lb=<default>, Label Lc=<default>, triangle t, pen p=<default>, filltype filltype=<default>);
+line isotomic(vertex V, point M);
+point isotomic(side side, point M);
+triangle isotomic(triangle t, point M);
+abscissa curabscissa(real x);
+abscissa curabscissa(int x);
+abscissa curabscissa(line l, point M);
+abscissa curabscissa(circle c, point M);
+abscissa curabscissa(ellipse el, point M);
+abscissa curabscissa(parabola p, point M);
+abscissa curabscissa(conic co, point M);
+abscissa curabscissa(arc a, point M);
+string DefaultFormat(real);
+string DefaultLogFormat(real)(int base);
+string DefaultLogFormat(real);
+guide graph(pair f(real), real, real, int)(guide join(... guide[]));
+guide[] graph(pair f(real), real, real, int)(guide join(... guide[]), bool3 cond(real));
+guide graph(picture pic=<default>, real f(real), real a, real b, int n=<default>, real T(real)=<default>, guide join(... guide[])=<default>);
+guide[] graph(picture pic=<default>, real f(real), real a, real b, int n=<default>, real T(real)=<default>, bool3 cond(real), guide join(... guide[])=<default>);
+guide graph(picture pic=<default>, real x(real), real y(real), real a, real b, int n=<default>, real T(real)=<default>, guide join(... guide[])=<default>);
+guide[] graph(picture pic=<default>, real x(real), real y(real), real a, real b, int n=<default>, real T(real)=<default>, bool3 cond(real), guide join(... guide[])=<default>);
+guide graph(picture pic=<default>, pair z(real), real a, real b, int n=<default>, real T(real)=<default>, guide join(... guide[])=<default>);
+guide[] graph(picture pic=<default>, pair z(real), real a, real b, int n=<default>, real T(real)=<default>, bool3 cond(real), guide join(... guide[])=<default>);
+guide graph(picture pic=<default>, pair[] z, guide join(... guide[])=<default>);
+guide[] graph(picture pic=<default>, pair[] z, bool3[] cond, guide join(... guide[])=<default>);
+guide graph(picture pic=<default>, real[] x, real[] y, guide join(... guide[])=<default>);
+guide[] graph(picture pic=<default>, real[] x, real[] y, bool3[] cond, guide join(... guide[])=<default>);
+scientific scientific(real x);
+void Left(picture, axisT)(bool extend=<default>);
+void Left(picture, axisT);
+autoscaleT defaultS;
+void XEquals(picture, axisT)(real x, bool extend=<default>);
+void YEquals(picture, axisT)(real y, bool extend=<default>);
+string LogFormat(real)(int base);
+string LogFormat(real);
+axisT axis;
+void axis(picture pic=<default>, Label L=<default>, path g, path g2=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>), ticklocate locate, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, int[] divisor=<default>, bool above=<default>, bool opposite=<default>);
+void drawtick(frame f, transform T, path g, path g2, ticklocate locate, real val, real Size, int sign, pen p, bool extend);
+real maxlength(pair a, pair b, int nx, int ny);
+void errorbar(picture pic, pair z, pair dp, pair dm, pen p=<default>, real size=<default>);
+void errorbars(picture pic=<default>, pair[] z, pair[] dp, pair[] dm=<default>, bool[] cond=<default>, pen p=<default>, real size=<default>);
+void errorbars(picture pic=<default>, real[] x, real[] y, real[] dpx, real[] dpy, real[] dmx=<default>, real[] dmy=<default>, bool[] cond=<default>, pen p=<default>, real size=<default>);
+void errorbars(picture pic=<default>, real[] x, real[] y, real[] dpy, bool[] cond=<default>, pen p=<default>, real size=<default>);
+void xlimits(picture pic=<default>, real min=<default>, real max=<default>, bool crop=<default>);
+string conditionlength;
+void ylimits(picture pic=<default>, real min=<default>, real max=<default>, bool crop=<default>);
+tickvalues None(tickvalues v);
+scaleT Logarithmic;
+void limits(picture pic=<default>, pair min, pair max, bool crop=<default>);
+void crop(picture pic=<default>);
+picture vectorfield(path vector(real), path g, int n, bool truesize=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>);
+picture vectorfield(path vector(pair), pair a, pair b, int nx=<default>, int ny=<default>, bool truesize=<default>, real maxlength=<default>, bool cond(pair z)=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>);
+string OmitFormat(real)(string s=<default> ... real[] x);
+guide Straight(... guide[]);
+int Min;
+string trailingzero;
+void label(picture pic, Label L, pair z, real x, align align, string format, pen p);
+void labelx(picture pic=<default>, Label L=<default>, explicit pair z, align align=<default>, string format=<default>, pen p=<default>);
+void labelx(picture pic=<default>, Label L=<default>, real x, align align=<default>, string format=<default>, pen p=<default>);
+void labelx(picture pic=<default>, Label L, string format=<default>, explicit pen p=<default>);
+path Arc(pair c, real r, real angle1, real angle2, bool direction, int n=<default>);
+path Arc(pair c, real r, real angle1, real angle2, int n=<default>);
+path Arc(pair c, explicit pair z1, explicit pair z2, bool direction=<default>, int n=<default>);
+void labely(picture pic=<default>, Label L=<default>, explicit pair z, align align=<default>, string format=<default>, pen p=<default>);
+void labely(picture pic=<default>, Label L=<default>, real y, align align=<default>, string format=<default>, pen p=<default>);
+void labely(picture pic=<default>, Label L, string format=<default>, explicit pen p=<default>);
+pair labeltick(frame d, transform T, path g, ticklocate locate, real val, pair side, int sign, real Size, string ticklabel(real), Label F, real norm=<default>);
+void labelaxis(frame f, transform T, Label L, path g, ticklocate locate=<default>, int sign=<default>, bool ticklabels=<default>);
+void xtick(picture pic=<default>, explicit pair z, pair dir=<default>, real size=<default>, pen p=<default>);
+void xtick(picture pic=<default>, real x, pair dir=<default>, real size=<default>, pen p=<default>);
+void xtick(picture pic=<default>, Label L, explicit pair z, pair dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void xtick(picture pic=<default>, Label L, real x, pair dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, explicit pair z, pair dir=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, real y, pair dir=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, Label L, explicit pair z, pair dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, Label L, real y, pair dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+picture secondaryX(picture primary=<default>, void f(picture));
+picture secondaryY(picture primary=<default>, void f(picture));
+tickvalues OmitTickIntervals(tickvalues)(real[] a, real[] b);
+tickvalues OmitTickInterval(tickvalues)(real a, real b);
+tickvalues OmitTick(tickvalues)(... real[] x);
+Label Break;
+tickvalues Break(tickvalues)(real, real);
+scaleT Linear;
+scaleT Linear(bool automin=<default>, bool automax=<default>, real s=<default>, real intercept=<default>);
+pair tickMin(picture pic);
+pair tickMax(picture pic);
+string autoformat(string format=<default>, real norm ... real[] a);
+real linear(real)(real S(real x)=<default>, real Min, real Max);
+pair polar(real r, real theta);
+string Format(real)(string s=<default>);
+guide polargraph(picture pic=<default>, real r(real), real a, real b, int n=<default>, guide join(... guide[])=<default>);
+guide polargraph(picture pic=<default>, real[] r, real[] theta, guide join(... guide[])=<default>);
+void LeftTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void LeftTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void LeftTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>);
+tickvalues NoZero(tickvalues);
+string NoZeroFormat(real);
+guide Hermite(... guide[])(real[] splinetype(real[], real[]));
+guide Hermite(... guide[]);
+path Circle(pair c, real r, int n=<default>);
+bool axiscoverage(int N, transform T, path g, ticklocate locate, real Step, pair side, int sign, real Size, Label F, string ticklabel(real), real norm, real limit);
+scaleT Broken(real a, real b, bool automin=<default>, bool automax=<default>);
+scaleT BrokenLog(real a, real b, bool automin=<default>, bool automax=<default>);
+void Ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks=<default>, real[] ticks=<default>, int N=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void Ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void Ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void Ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void Ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>);
+string noprimary;
+void xequals(picture pic=<default>, Label L=<default>, real x, bool extend=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
+void yequals(picture pic=<default>, Label L=<default>, real y, bool extend=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
+pair Scale(picture pic=<default>, pair z);
+real ScaleX(picture pic=<default>, real x);
+real ScaleY(picture pic=<default>, real y);
+void xaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
+tickvalues generateticks(int sign, Label F=<default>, string ticklabel(real)=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, real Size=<default>, real size=<default>, transform T, pair side, path g, real limit, pen p, ticklocate locate, int[] divisor, bool opposite);
+void yaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
+void xaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
+void yaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool autorotate=<default>);
+void checkconditionlength(int x, int y);
+real xtrans(transform t, real x);
+void Top(picture, axisT)(bool extend=<default>);
+void Top(picture, axisT);
+real ytrans(transform t, real y);
+void scale(picture pic=<default>, scaleT x, scaleT y=<default>, scaleT z=<default>);
+void scale(picture pic=<default>, bool xautoscale=<default>, bool yautoscale=<default>, bool zautoscale=<default>);
+int[] divisors(int a, int b);
+scientific operator init();
+bounds operator init();
+ticklocate operator init();
+locateT operator init();
+tickvalues operator init();
+axisT operator init();
+int Both;
+void axes(picture pic=<default>, Label xlabel=<default>, Label ylabel=<default>, bool extend=<default>, pair min=<default>, pair max=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
+string signedtrailingzero;
+path[] segment(pair[] z, bool[] cond, guide join(... guide[])=<default>);
+ticklocate ticklocate(real a, real b, autoscaleT S=<default>, real tickmin=<default>, real tickmax=<default>, real time(real)=<default>, pair dir(real)=<default>);
+pair ticklabelshift(pair align, pen p=<default>);
+pair zero(real);
+void Bottom(picture, axisT)(bool extend=<default>);
+void Bottom(picture, axisT);
+void BottomTop(picture, axisT)(bool extend=<default>);
+void BottomTop(picture, axisT);
+real zerotickfuzz;
+real upscale(real b, real a);
+bool logaxiscoverage(int N, transform T, path g, ticklocate locate, pair side, int sign, real Size, Label F, string ticklabel(real), real limit, int first, int last);
+string baselinetemplate;
+void NoTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)();
+void NoTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>);
+void tick(picture pic=<default>, pair z, pair dir, real size=<default>, pen p=<default>);
+void tick(picture pic=<default>, Label L, real value, explicit pair z, pair dir, string format=<default>, real size=<default>, pen p=<default>);
+int Value;
+scaleT Log;
+scaleT Log(bool automin=<default>, bool automax=<default>);
+void Right(picture, axisT)(bool extend=<default>);
+void Right(picture, axisT);
+void RightTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void RightTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void RightTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>);
+int Max;
+void XZero(picture, axisT)(bool extend=<default>);
+void XZero(picture, axisT);
+void YZero(picture, axisT)(bool extend=<default>);
+void YZero(picture, axisT);
+bounds autoscale(real Min, real Max, scaleT scale=<default>);
+void autoscale(picture pic=<default>, void axis(picture, axisT));
+guide Spline(... guide[]);
+void LeftRight(picture, axisT)(bool extend=<default>);
+void LeftRight(picture, axisT);
+path3[] segment(triple[] v, bool[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
+locateT operator init();
+void Straight(flatguide3)(... void(flatguide3)[]);
+void graph(flatguide3)(triple F(real), real, real, int)(void join(flatguide3)(... void(flatguide3)[]));
+void(flatguide3)[] graph(triple F(real), real, real, int)(void join(flatguide3)(... void(flatguide3)[]), bool3 cond(real));
+void graph(flatguide3)(picture pic=<default>, real x(real), real y(real), real z(real), real a, real b, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, real x(real), real y(real), real z(real), real a, real b, int n=<default>, bool3 cond(real), void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, triple v(real), real a, real b, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, triple v(real), real a, real b, int n=<default>, bool3 cond(real), void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, triple[] v, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, triple[] v, bool3[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, real[] x, real[] y, real[] z, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, real[] x, real[] y, real[] z, bool3[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(triple F(path, real), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(triple F(pair), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, real f(pair), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(real f(pair), path p, int n=<default>, real T(pair), void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[][] lift(real f(real x, real y), guide[][] g, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[][] lift(real f(pair z), guide[][] g, void join(flatguide3)(... void(flatguide3)[])=<default>);
+triple polar(real r, real theta, real phi);
+void polargraph(flatguide3)(real r(real, real), real theta(real), real phi(real), int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+bool uperiodic(triple[][] a);
+bool vperiodic(triple[][] a);
+void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
+void axis(picture pic=<default>, Label L=<default>, path3 g, path3 g2=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>), ticklocate locate, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, int[] divisor=<default>, bool above=<default>, bool opposite=<default>);
+void Bounds(picture, axisT)(int type=<default>, int type2=<default>, triple align=<default>, bool extend=<default>);
+void Bounds(picture, axisT);
+void XZZero(picture, axisT)(triple align=<default>, bool extend=<default>);
+void XZZero(picture, axisT);
+void YZZero(picture, axisT)(triple align=<default>, bool extend=<default>);
+void YZZero(picture, axisT);
+void xaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
+void yaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
+void zaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real zmin=<default>, real zmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
+void xaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
+void yaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
+void zaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real zmin=<default>, real zmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
+surface surface(triple[][] f, bool[][] cond=<default>);
+surface surface(real[][] f, real[] x, real[] y, real[] xsplinetype(real[], real[])=<default>, real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
+surface surface(real[][] f, pair a, pair b, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
+surface surface(real[][] f, pair a, pair b, bool[][] cond=<default>);
+surface surface(triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, bool cond(pair z)=<default>);
+surface surface(triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, real[](real[], real[])[] usplinetype, real[](real[], real[])[] vsplinetype=<default>, bool cond(pair z)=<default>);
+surface surface(real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, bool cond(pair z)=<default>);
+surface surface(real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool cond(pair z)=<default>);
+void XYEquals(picture, axisT)(real x, real y, triple align=<default>, bool extend=<default>);
+triple Dir(real)(triple dir);
+void draw(picture pic=<default>, Label[] L=<default>, void(flatguide3)[][] g, pen[] p, light light=<default>, string name=<default>, render render=<default>, interaction interaction=<default>);
+void draw(picture pic=<default>, Label[] L=<default>, void(flatguide3)[][] g, pen p=<default>, light light=<default>, string name=<default>, render render=<default>, interaction interaction=<default>);
+void Ticks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks=<default>, real[] ticks=<default>, int N=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void Ticks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+real maxlength(triple f(pair z), pair a, pair b, int nu, int nv);
+void drawtick(picture pic, real[][] T, path3 g, path3 g2, ticklocate locate, real val, real Size, int sign, pen p, bool extend);
+triple tickMin3(picture pic);
+triple tickMax3(picture pic);
+triple Scale(picture pic=<default>, triple v);
+real ScaleZ(picture pic=<default>, real z);
+picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, bool truesize=<default>, real maxlength=<default>, bool cond(pair z)=<default>, pen p=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, string name=<default>, render render=<default>);
+path3 Circle(triple c, real r, triple normal=<default>, int n=<default>);
+void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
+void Spline(flatguide3)(... void(flatguide3)[]);
+void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
+void axes3(picture pic=<default>, Label xlabel=<default>, Label ylabel=<default>, Label zlabel=<default>, bool extend=<default>, triple min=<default>, triple max=<default>, pen p=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>);
+void label(picture pic, Label L, triple v, real x, align align, string format, pen p);
+void labelx(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
+void labely(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
+void labeltick(picture pic, real[][] T, path3 g, ticklocate locate, real val, int sign, real Size, string ticklabel(real), Label F, real norm=<default>);
+void labelaxis(picture pic, real[][] T, Label L, path3 g, ticklocate locate=<default>, int sign=<default>, bool ticklabels=<default>);
+void labelx3(picture pic=<default>, Label L=<default>, real x, align align=<default>, string format=<default>, pen p=<default>);
+void labely3(picture pic=<default>, Label L=<default>, real y, align align=<default>, string format=<default>, pen p=<default>);
+void labelz(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
+void labelz3(picture pic=<default>, Label L=<default>, real z, align align=<default>, string format=<default>, pen p=<default>);
+void autoscale3(picture pic=<default>, void axis(picture, axisT));
+void xtick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
+void xtick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void xtick3(picture pic=<default>, real x, triple dir=<default>, real size=<default>, pen p=<default>);
+void xtick3(picture pic=<default>, Label L, real x, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ytick3(picture pic=<default>, real y, triple dir=<default>, real size=<default>, pen p=<default>);
+void ytick3(picture pic=<default>, Label L, real y, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ztick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
+void ztick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ztick3(picture pic=<default>, real z, triple dir=<default>, real size=<default>, pen p=<default>);
+void ztick3(picture pic=<default>, Label L, real z, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+triple defaultdir(triple X, triple Y, triple Z, bool opposite=<default>, projection P);
+real xtrans(real[][] t, real x);
+real ytrans(real[][] t, real y);
+real ztrans(real[][] t, real z);
+ticklocate ticklocate(real a, real b, autoscaleT S=<default>, real tickmin=<default>, real tickmax=<default>, real time(real)=<default>, triple dir(real));
+triple ticklabelshift(triple align, pen p=<default>);
+path3 Arc(triple c, triple v1, triple v2, triple normal=<default>, bool direction=<default>, int n=<default>);
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2, triple normal=<default>, bool direction, int n=<default>);
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2, triple normal=<default>, int n=<default>);
+void limits(picture pic=<default>, triple min, triple max);
+void XZEquals(picture, axisT)(real x, real z, triple align=<default>, bool extend=<default>);
+void YZEquals(picture, axisT)(real y, real z, triple align=<default>, bool extend=<default>);
+void XYZero(picture, axisT)(triple align=<default>, bool extend=<default>);
+void XYZero(picture, axisT);
+void zlimits(picture pic=<default>, real min=<default>, real max=<default>, bool crop=<default>);
+void tick(picture pic=<default>, triple v, triple dir, real size=<default>, pen p=<default>);
+void tick(picture pic=<default>, Label L, real value, triple v, triple dir, string format=<default>, real size=<default>, pen p=<default>);
+surface bispline(real[][] z, real[][] p, real[][] q, real[][] r, real[] x, real[] y, bool[][] cond=<default>);
+void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)();
+void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
+bool Crop;
+int ngraph;
+real epsilon;
+real axiscoverage;
+real Ticksize;
+bool NoCrop;
+real ticksize;
+int nmesh;
+int nCircle;
+real ylabelwidth;
+real axislabelfactor;
+real[] clamped(real[], real[])(real slopea, real slopeb);
+real[] natural(real[] x, real[] y);
+real[] monotonic(real[] x, real[] y);
+real[] notaknot(real[] x, real[] y);
+real[] linear(real[] x, real[] y);
+string morepoints;
+guide hermite(real[] x, real[] y, real[] splinetype(real[], real[])=<default>);
+void checklengths(int x, int y, string text=<default>);
+void checkincreasing(real[] x);
+real[] periodic(real[] x, real[] y);
+string differentlengths;
+real[] Spline(real[] x, real[] y);
+real[](real[], real[])[] Spline;
+grid3(picture pic)[] YXYgrid(position pos=<default>);
+grid3(picture pic)[] YXYgrid;
+grid3 operator init();
+ticksgridT operator init();
+grid3(picture pic)[] operator cast(grid3 gridroutine(picture pic));
+grid3(picture pic)[][] operator cast(grid3(picture pic)[] gridroutine);
+grid3(picture pic)[][] operator cast(grid3 gridroutine(picture pic));
+triple X(picture pic);
+triple Y(picture pic);
+triple Z(picture pic);
+grid3(picture pic)[] XYXgrid(position pos=<default>);
+grid3(picture pic)[] XYXgrid;
+grid3(picture pic)[] XY_XZgrid(position posa=<default>, position posb=<default>);
+grid3(picture pic)[] XY_XZgrid;
+grid3(picture pic)[] ZX_ZYgrid(position posa=<default>, position posb=<default>);
+grid3(picture pic)[] ZX_ZYgrid;
+grid3 XYgrid(picture pic)(position pos=<default>);
+grid3 XYgrid(picture pic);
+grid3 ZYgrid(picture pic)(position pos=<default>);
+grid3 ZYgrid(picture pic);
+position middle;
+void grid3(picture pic=<default>, grid3(picture pic)[][] gridroutine=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, pen pGrid=<default>, pen pgrid=<default>, bool above=<default>);
+void grid3(picture pic=<default>, grid3(picture pic)[][] gridroutine, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, pen[] pGrid, pen[] pgrid, bool above=<default>);
+ticksgridT OutTicks()(Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, pen pTick=<default>, pen ptick=<default>, grid3(picture pic)[][] gridroutine, pen pGrid=<default>, pen pgrid=<default>);
+triple YZ(picture pic);
+triple ZX(picture pic);
+void xaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, pen p=<default>, ticksgridT ticks(), bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, bool above=<default>);
+void yaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, pen p=<default>, ticksgridT ticks(), bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, bool above=<default>);
+void zaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, pen p=<default>, ticksgridT ticks(), bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, bool above=<default>);
+grid3(picture pic)[] ZXZgrid(position pos=<default>);
+grid3(picture pic)[] ZXZgrid;
+position top;
+grid3(picture pic)[] XZXgrid(position pos=<default>);
+grid3(picture pic)[] XZXgrid;
+ticksgridT InTicks()(Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, pen pTick=<default>, pen ptick=<default>, grid3(picture pic)[][] gridroutine, pen pGrid=<default>, pen pgrid=<default>);
+ticksgridT InOutTicks()(Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, pen pTick=<default>, pen ptick=<default>, grid3(picture pic)[][] gridroutine, pen pGrid=<default>, pen pgrid=<default>);
+grid3(picture pic)[] YX_YZgrid(position posa=<default>, position posb=<default>);
+grid3(picture pic)[] YX_YZgrid;
+position bottom;
+grid3 YXgrid(picture pic)(position pos=<default>);
+grid3 YXgrid(picture pic);
+grid3 ZXgrid(picture pic)(position pos=<default>);
+grid3 ZXgrid(picture pic);
+triple XY(picture pic);
+grid3(picture pic)[][] XYZgrid(position pos=<default>);
+grid3(picture pic)[][] XYZgrid;
+grid3(picture pic)[] ZYZgrid(position pos=<default>);
+grid3(picture pic)[] ZYZgrid;
+grid3 XZgrid(picture pic)(position pos=<default>);
+grid3 XZgrid(picture pic);
+grid3 YZgrid(picture pic)(position pos=<default>);
+grid3 YZgrid(picture pic);
+grid3(picture pic)[] YZYgrid(position pos=<default>);
+grid3(picture pic)[] YZYgrid;
+real fspline(real)(real[] x, real[] y, real[] splinetype(real[], real[])=<default>);
+real pwhermite(real)(real[] x, real[] y, real[] dy);
+horner diffdiv(real[] x, real[] y);
+horner hdiffdiv(real[] x, real[] y, real[] dy);
+horner operator init();
+real fhorner(real)(horner sh);
+void labelpath(frame f, Label L, path g, string justify=<default>, pen p=<default>);
+void labelpath(picture pic=<default>, Label L, path g, string justify=<default>, pen p=<default>);
+string LeftJustified;
+string Centered;
+string RightJustified;
+surface labelpath(string s, path3 p, real angle=<default>, triple optional=<default>);
+triple[] firstframe(path3 p, triple optional=<default>);
+triple[] nextframe(path3 p, real reltimestart, triple[] start, real reltimeend, int subdiv=<default>);
+real eps;
+triple nextnormal(triple p, triple q);
+string[] lm_infmsg;
+void lm_qrfac(int m, int n, real[] a, bool pivot, int[] ipvt, real[] rdiag, real[] acnorm, real[] wa);
+void lm_qrsolv(int n, real[] r, int ldr, int[] ipvt, real[] diag, real[] qtb, real[] x, real[] sdiag, real[] wa);
+FitControl defaultControl;
+real LM_MACHEP;
+real LM_SQRT_DWARF;
+real LM_SQRT_GIANT;
+void lm_lmpar(int n, real[] r, int ldr, int[] ipvt, real[] diag, real[] qtb, real delta, lm_real_type par, real[] x, real[] sdiag, real[] wa1, real[] wa2);
+void lm_lmdif(int m, int n, real[] x, real[] fvec, real ftol, real xtol, real gtol, int maxfev, real epsfcn, real[] diag, int mode, real factor, lm_int_type info, lm_int_type nfev, real[] fjac, int[] ipvt, real[] qtf, real[] wa1, real[] wa2, real[] wa3, real[] wa4, void evaluate(real[] par, int m_dat, real[] fvec, lm_data_type data, lm_int_type info), void printout(int n_par, real[] par, int m_dat, real[] fvec, lm_data_type data, int iflag, int iter, int nfev), lm_data_type data);
+void lm_minimize(int m_dat, int n_par, real[] par, void evaluate(real[] par, int m_dat, real[] fvec, lm_data_type data, lm_int_type info), void printout(int n_par, real[] par, int m_dat, real[] fvec, lm_data_type data, int iflag, int iter, int nfev), lm_data_type data, lm_control_type control);
+FitResult fit(real[] xdata, real[] ydata, real[] errors, real function(real[], real), real[] parameters, FitControl control=<default>);
+FitResult fit(real[] xdata, real[] ydata, real function(real[], real), real[] parameters, FitControl control=<default>);
+real lm_enorm(int n, real[] x, int offset=<default>);
+lm_data_type operator init();
+lm_int_type operator init();
+lm_real_type operator init();
+lm_control_type operator init();
+FitControl operator init();
+FitResult operator init();
+real SQR(real x);
+string[] lm_shortmsg;
+void lm_evaluate_default(real[] par, int m_dat, real[] fvec, lm_data_type data, lm_int_type info);
+string pad(string str, int count, string pad=<default>);
+string pad(int num, int digits, string pad=<default>);
+string pad(real num, int digits, string pad=<default>);
+real LM_USERTOL;
+real LM_DWARF;
+void lm_print_quiet(int n_par, real[] par, int m_dat, real[] fvec, lm_data_type data, int iflag, int iter, int nfev);
+void lm_print_default(int n_par, real[] par, int m_dat, real[] fvec, lm_data_type data, int iflag, int iter, int nfev);
+real barmarksize(pen p=<default>);
+real barmarksizefactor;
+marker CrossIntervalMarker(int i=<default>, int n=<default>, real size=<default>, real space=<default>, real angle=<default>, pair offset=<default>, bool rotated=<default>, pen p=<default>, frame uniform=<default>, bool above=<default>);
+marker StickIntervalMarker(int i=<default>, int n=<default>, real size=<default>, real space=<default>, real angle=<default>, pair offset=<default>, bool rotated=<default>, pen p=<default>, frame uniform=<default>, bool above=<default>);
+frame crossframe(int n=<default>, real size=<default>, pair space=<default>, real angle=<default>, pair offset=<default>, pen p=<default>);
+real crossmarksize(pen p=<default>);
+real crossmarksizefactor;
+frame stickframe(int n=<default>, real size=<default>, pair space=<default>, real angle=<default>, pair offset=<default>, pen p=<default>);
+frame stickframe;
+real stickmarksize(pen p=<default>);
+real stickmarkspace(pen p=<default>);
+real stickmarksizefactor;
+real stickmarkspacefactor;
+frame duplicate(path g, int n=<default>, pair space=<default>, pen p=<default>);
+marker CircleBarIntervalMarker(int i=<default>, int n=<default>, real barsize=<default>, real radius=<default>, real angle=<default>, pair offset=<default>, bool rotated=<default>, pen p=<default>, filltype filltype=<default>, bool circleabove=<default>, frame uniform=<default>, bool above=<default>);
+frame circlebarframe(int n=<default>, real barsize=<default>, real radius=<default>, real angle=<default>, pair offset=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+real circlemarkradius(pen p=<default>);
+real circlemarkradiusfactor;
+marker operator *(transform T, marker m);
+marker TildeIntervalMarker(int i=<default>, int n=<default>, real size=<default>, real space=<default>, real angle=<default>, pair offset=<default>, bool rotated=<default>, pen p=<default>, frame uniform=<default>, bool above=<default>);
+frame tildeframe(int n=<default>, real size=<default>, pair space=<default>, real angle=<default>, pair offset=<default>, pen p=<default>);
+frame tildeframe;
+real tildemarksize(pen p=<default>);
+real tildemarksizefactor;
+void markangle(picture pic=<default>, Label L=<default>, int n=<default>, real radius=<default>, real space=<default>, pair A, pair O, pair B, bool arrow(picture, path, pen, marginT(path, pen))=<default>, pen p=<default>, filltype filltype=<default>, marginT margin(path, pen)=<default>, marker marker=<default>);
+real markanglespace(pen p=<default>);
+real markanglespace;
+real markangleradius(pen p=<default>);
+real markangleradius;
+real markanglespacefactor;
+real markangleradiusfactor;
+void markinterval(picture pic=<default>, frame f, path g)(int n=<default>, frame f, bool rotated=<default>);
+real[] partialsum(real[] a);
+real[] partialsum(real[] a, real[] dx);
+int[] partialsum(int[] a);
+int[] partialsum(int[] a, int[] dx);
+real cot(real x);
+int unique(real[] a, real x);
+int unique(string[] a, string x);
+int quadrant(real degrees);
+pair exp(explicit pair z);
+string nopoint;
+real intersect(pair p, pair q, pair z);
+real intersect(triple P, triple Q, triple n, triple Z);
+real interpolate(real[] x, real[] y, real x0, int i);
+real interpolate(real[] x, real[] y, real x0);
+triple intersectionpoint(triple n0, triple P0, triple n1, triple P1);
+pair[] quarticroots(real a, real b, real c, real d, real e);
+bool lexorder(pair a, pair b);
+bool lexorder(triple a, triple b);
+bool square(real[][] m);
+real sec(real x);
+bool rectangular(real[][] m);
+bool rectangular(pair[][] m);
+bool rectangular(triple[][] m);
+bool polygon(path p);
+pair unityroot(int n, int k=<default>);
+real acot(real x);
+pair[][] fft(pair[][] a, int sign=<default>);
+real slope(path g, real x, int n=<default>);
+real slope(path g, explicit pair z, int n=<default>);
+picture grid(int Nx, int Ny, pen p=<default>);
+rootfinder_settings operator init();
+real frac(real x);
+real asec(real x);
+int[][] segmentlimits(bool[] b);
+int[][] segment(bool[] b);
+real time(path g, real x, int n=<default>);
+real time(path g, explicit pair z, int n=<default>);
+real[] leastsquares(real[][] A, real[] b, bool warn=<default>);
+bool increasing(real[] a, bool strict=<default>);
+real[] zero(int n);
+real[][] zero(int n, int m);
+real findroot(real f(real), real a, real b, real tolerance=<default>, real fa=<default>, real fb=<default>);
+real acsc(real x);
+real value(path g, real x, int n=<default>);
+real value(path g, explicit pair z, int n=<default>);
+real csc(real x);
+pair log(explicit pair z);
+void drawline(picture pic=<default>, pair P, pair Q, pen p=<default>);
+path cutbefore(path p, path q);
+path cutafter(path p, path q);
+path cuttings;
+void draw(picture pic=<default>, obj o, light light=<default>);
+obj operator *(real[][] T, obj o);
+obj operator init();
+real[][] finiteDifferenceJacobian(real[] f(real[]), real[] t, real[] h=<default>);
+RKTableau E_Euler;
+real error(real error, real initial, real lowOrder, real norm, real diff);
+RKTableau RK5;
+real stepfactor;
+RKTableau RK4;
+real[] newton(int iterations=<default>, real[] f(real[]), real[][] jacobian(real[]), real[] t);
+real phi1(real x);
+solution integrate(real y, real c=<default>, real f(real t, real y), real a, real b=<default>, real h=<default>, int n=<default>, bool dynamic=<default>, real tolmin=<default>, real tolmax=<default>, real dtmin=<default>, real dtmax=<default>, RKTableau tableau, bool verbose=<default>);
+Solution integrate(real[] y, real[] f(real t, real[] y), real a, real b=<default>, real h=<default>, int n=<default>, bool dynamic=<default>, real tolmin=<default>, real tolmax=<default>, real dtmin=<default>, real dtmax=<default>, RKTableau tableau, bool verbose=<default>);
+RKTableau RK3;
+void expfactors(real x, coefficients a);
+real phi2(real x);
+void report(real old, real h, real t);
+real[] solveBVP(real[] f(real, real[]), real a, real b=<default>, real h=<default>, int n=<default>, bool dynamic=<default>, real tolmin=<default>, real tolmax=<default>, real dtmin=<default>, real dtmax=<default>, RKTableau tableau, bool verbose=<default>, real[] initial(real[]), real[] discrepancy(real[]), real[] guess, int iterations=<default>);
+RKTableau Euler;
+RKTableau E_PC;
+RKTableau RK2;
+real phi3(real x);
+void write(solution S);
+void write(Solution S);
+coefficients operator init();
+RKTableau operator init();
+solution operator init();
+Solution operator init();
+RKTableau E_RK2;
+RKTableau RK3BS;
+RKTableau RK5F;
+real adjust(real h, real error, real tolmin, real tolmax, RKTableau tableau);
+RKTableau RK5DP;
+real[] Coeff;
+RKTableau PC;
+RKTableau E_RK3BS;
+pen[] Grayscale(int NColors=<default>);
+bounds Range(picture pic, real min, real max)(bool automin=<default>, real min=<default>, bool automax=<default>, real max=<default>);
+pen[] Wheel(int NColors=<default>);
+void image(frame f, real[][] data, pair initial, pair final, pen[] palette, bool transpose=<default>, transform t=<default>, bool copy=<default>, bool antialias=<default>);
+void image(frame f, pen[][] data, pair initial, pair final, bool transpose=<default>, transform t=<default>, bool copy=<default>, bool antialias=<default>);
+bounds image(picture pic=<default>, real[][] f, bounds range(picture pic, real min, real max)=<default>, pair initial, pair final, pen[] palette, bool transpose=<default>, bool copy=<default>, bool antialias=<default>);
+bounds image(picture pic=<default>, real f(real, real), bounds range(picture pic, real min, real max)=<default>, pair initial, pair final, int nx=<default>, int ny=<default>, pen[] palette, bool antialias=<default>);
+void image(picture pic=<default>, pen[][] data, pair initial, pair final, bool transpose=<default>, bool copy=<default>, bool antialias=<default>);
+void image(picture pic=<default>, pen f(int, int), int width, int height, pair initial, pair final, bool transpose=<default>, bool antialias=<default>);
+bounds image(picture pic=<default>, pair[] z, real[] f, bounds range(picture pic, real min, real max)=<default>, pen[] palette);
+bounds image(picture pic=<default>, real[] x, real[] y, real[] f, bounds range(picture pic, real min, real max)=<default>, pen[] palette);
+pen[] cmyk(pen[] Palette);
+pen[] BWRainbow(int NColors, bool two);
+pen[] BWRainbow(int NColors=<default>);
+pen[] BWRainbow2(int NColors=<default>);
+transform swap;
+bounds Automatic(picture pic, real min, real max);
+real[] sequencereal;
+pen[] Rainbow(int NColors=<default>);
+pen[] adjust(picture pic, real min, real max, real rmin, real rmax, pen[] palette);
+pen[] Gradient(int NColors=<default> ... pen[] p);
+pen[] quantize(pen[] Palette, int n);
+void NoTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(int sign=<default>);
+bounds Full(picture pic, real min, real max);
+void PaletteTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(int sign=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, pen pTick=<default>, pen ptick=<default>);
+void PaletteTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(int sign=<default>);
+pen[] palette(real[] f, pen[] palette);
+pen[][] palette(real[][] f, pen[] palette);
+void palette(picture pic=<default>, Label L=<default>, bounds bounds, pair initial, pair final, void axis(picture, axisT)=<default>, pen[] palette, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(int sign=<default>)=<default>, bool copy=<default>, bool antialias=<default>);
+picture brick(real Hx=<default>, real Hy=<default>, pen p=<default>);
+picture crosshatch(real H=<default>, pen p=<default>);
+picture hatch(real H=<default>, pair dir=<default>, pen p=<default>);
+real hatchepsilon;
+picture checker(real Hx=<default>, real Hy=<default>, pen p=<default>);
+void add(string name, picture pic, pair lb=<default>, pair rt=<default>);
+frame tiling(string name, picture pic, pair lb=<default>, pair rt=<default>);
+picture tile(real Hx=<default>, real Hy=<default>, pen p=<default>, filltype filltype=<default>);
+void grestore(picture pic=<default>);
+pen textpen;
+void gsave(picture pic=<default>);
+pair align;
+rational[][] rationalidentity(int n);
+int gcd(int m, int n);
+rational min(rational a, rational b);
+rational abs(rational r);
+string texstring(rational r);
+bool rectangular(rational[][] m);
+string string(rational r);
+void write(file fout=<default>, string s=<default>, rational r, void suffix(file)=<default>);
+void write(file fout=<default>, string s=<default>, rational[] a, void suffix(file)=<default>);
+void write(file fout=<default>, string s=<default>, rational[][] a, void suffix(file)=<default>);
+rational operator +(rational r, rational s);
+rational operator -(rational r);
+rational operator -(rational r, rational s);
+rational[] operator -(rational[] r);
+rational operator *(rational r, rational s);
+rational operator init();
+rational operator cast(int p);
+rational[] operator cast(int[] a);
+rational[][] operator cast(int[][] a);
+real operator ecast(rational r);
+rational operator /(rational r, rational s);
+bool operator ==(rational r, rational s);
+bool[] operator ==(rational[] r, rational s);
+bool operator ==(rational[] r, rational[] s);
+bool operator ==(rational[][] r, rational[][] s);
+bool operator !=(rational r, rational s);
+bool operator <(rational r, rational s);
+bool[] operator <(rational[] r, rational s);
+bool operator <=(rational r, rational s);
+bool[] operator <=(rational[] r, rational s);
+bool operator >(rational r, rational s);
+bool[] operator >(rational[] r, rational s);
+bool operator >=(rational r, rational s);
+bool[] operator >=(rational[] r, rational s);
+rational sum(rational[] a);
+int lcm(int m, int n);
+rational max(rational a, rational b);
+rational max(rational[] a);
+simplex operator init();
+void simplexPhase2();
+void simplexTableau(rational[][] E, int[] Bindices, int I=<default>, int J=<default>);
+void simplexWrite(rational[][] E, int[] Bindicies, int, int);
+path roundedpath(path A, real R, real S=<default>);
+simplex operator init();
+void display(frame[] f, real margin=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool final=<default>);
+void display(frame f, real margin=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool final=<default>);
+void display(string[] s, real margin=<default>, string[] captions=<default>, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool final=<default>);
+void display(string s, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool final=<default>);
+void multifigure(string[] slist, string options=<default>, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool step=<default>);
+int page;
+void subitem(string s, pen p=<default>);
+pen pagenumberpen;
+pair pagenumberalign;
+pair pagenumberposition;
+void indexedfigure(string prefix, int first, int last, string options=<default>, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool step=<default>);
+string texcolor(pen p);
+void color(string name, string color);
+pen foregroundcolor;
+void bibliography(string name);
+void bibliographystyle(string name);
+int[] lastnode;
+real aboveequationskip;
+void nextpage(pen p=<default>);
+void asyfigure(string s, string options=<default>, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, filltype filltype=<default>, bool newslide=<default>);
+void asyfilecode(bool center=<default>, string s, string options=<default>, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>, bool newslide=<default>);
+bool itemstep;
+real itemskip;
+void remark(bool center=<default>, string s, pair align=<default>, pen p=<default>, real indent=<default>, bool minipage=<default>, real skip=<default>, filltype filltype=<default>, bool step=<default>);
+void filecode(bool center=<default>, string s, pen p=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>);
+void usersetting();
+bool landscape;
+real codeskip;
+void newslide(bool stepping=<default>);
+pen itempen;
+bool reverse;
+void reversevideo();
+void vbox(string s, pen p=<default>);
+void asycode(bool center=<default>, string s, string options=<default>, string caption=<default>, string preamble=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>, bool newslide=<default>);
+void exitfunction();
+bool havepagenumber;
+void item(string s, pen p=<default>, bool step=<default>);
+real pageheight;
+real pagewidth;
+picture background;
+void background();
+pen backgroundcolor;
+void normalvideo();
+void title(string s, pair position=<default>, pair align=<default>, pen p=<default>, bool newslide=<default>);
+pen titlepen;
+real titleskip;
+pair dateskip;
+pair titlealign;
+pen titlepagepen;
+pen authorpen;
+void titlepage(string title, string author, string institution=<default>, string date=<default>, string url=<default>, bool newslide=<default>);
+pair titlepageposition;
+pen codepen;
+void erasestep(int erasenode);
+bool checkposition();
+void setpens(pen red=<default>, pen blue=<default>, pen steppen=<default>);
+string cropcode(string s);
+void code(bool center=<default>, string s, pen p=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>);
+transform tinv;
+pair urlskip;
+void numberpage(pen p=<default>);
+pen urlpen;
+bool allowstepping;
+pair currentposition;
+int[] firstnode;
+bool firststep;
+string asywrite(string s, string preamble=<default>);
+pair startposition;
+string oldbulletcolor;
+string newbulletcolor;
+pen datepen;
+void incrementposition(pair z);
+pen institutionpen;
+void skip(real n=<default>);
+bool stepping;
+real pagemargin;
+pen steppagenumberpen;
+bool empty();
+void currentexitfunction();
+void step();
+string[] codefile;
+void outline(string s=<default>, pair position=<default>, pair align=<default>, pen p=<default>);
+void center(string s, pen p=<default>);
+void equation(string s, pen p=<default>);
+void equations(string s, pen p=<default>);
+void asyinclude(string s, real xsize=<default>, real ysize=<default>);
+void figure(string[] s, string options=<default>, real margin=<default>, string[] captions=<default>, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool final=<default>);
+void figure(string s, string options=<default>, string caption=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, bool final=<default>);
+real figureborder;
+pen figuremattpen;
+string bullet;
+int preamblenodes;
+string bulletcolor(string color);
+real minipagewidth;
+real minipagemargin;
+real stepfraction;
+path curve(pair c, real f(real, real), pair a, pair b);
+path curve(pair c, real f(real), pair a, pair b);
+picture slopefield(real f(real, real), pair a, pair b, int nx=<default>, int ny=<default>, real tickfactor=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>);
+picture slopefield(real f(real), pair a, pair b, int nx=<default>, int ny=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>);
+real B03(real t);
+patch[] maketriangle(path3 external, real f(triple), triple grad(triple), bool allowsubdivide=<default>);
+real B23(real t);
+path3 pathinface(positionedvector v1, positionedvector v2, triple facenorm, triple edge1normout, triple edge2normout);
+path3 pathinface(positionedvector v1, positionedvector v2, int face, int edge1face, int edge2face);
+path3 bisector(path3 edgecycle, int[] savevertices);
+int XHIGH;
+int YHIGH;
+int ZHIGH;
+real(real)[] bernstein;
+path3 pathbetween(positionedvector v1, positionedvector v2);
+path3 pathbetween(path3 edgecycle, int vertex1, int vertex2);
+patch patchwithnormals(path3 external, triple[] u0normals, triple[] u1normals, triple[] v0normals, triple[] v1normals);
+patch patchwithnormals(path3 external, triple normalat(triple));
+real angledegrees(triple a, triple b);
+triple projecttospan(triple toproject, triple v1, triple v2, real mincoeff=<default>);
+real[] projecttospan_findcoeffs(triple toproject, triple v1, triple v2, bool warn=<default>);
+triple nGrad(triple)(real f(triple));
+patch[] quadpatches(path3 edgecycle, positionedvector[] corners, real f(triple), triple grad(triple), triple a, triple b, bool usetriangles);
+triple normalout(int face);
+int[] makecircle(edge[] edges);
+real B13(real t);
+bool check_fpt_zero(triple testpoint, real f(triple), triple grad(triple));
+bool checkptincube(triple pt, triple a, triple b);
+bool checkpt(triple testpt, real f(triple), triple grad(triple), triple a, triple b);
+int XLOW;
+int YLOW;
+int ZLOW;
+pathwithnormals_settings operator init();
+intset operator init();
+int_to_intset operator init();
+edge operator init();
+positionedvector operator init();
+evaluatedpoint operator init();
+gridwithzeros operator init();
+string operator cast(edge e);
+string operator cast(edge[] edges);
+string operator cast(positionedvector vv);
+triple operator cast(evaluatedpoint p);
+surface implicitsurface(real f(triple)=<default>, real ff(real, real, real)=<default>, triple a, triple b, int n=<default>, bool keyword overlapedges=<default>, int keyword nx=<default>, int keyword ny=<default>, int keyword nz=<default>, int keyword maxdepth=<default>, bool keyword usetriangles=<default>);
+bool operator ==(edge a, edge b);
+patch[] triangletoquads(path3 external, real f(triple), triple grad(triple), triple a, triple b);
+patch trianglewithnormals(path3 external, triple n1, triple n2, triple n3);
+evaluatedpoint[][][] make3dgrid(triple a, triple b, int nx, int ny, int nz, real f(triple), bool allowzero=<default>);
+real B33(real t);
+evaluatedpoint[][] slice(evaluatedpoint[][] a, int start1, int end1, int start2, int end2);
+evaluatedpoint[][][] slice(evaluatedpoint[][][] a, int start1, int end1, int start2, int end2, int start3, int end3);
+positionedvector[][] slice(positionedvector[][] a, int start1, int end1, int start2, int end2);
+positionedvector[][][] slice(positionedvector[][][] a, int start1, int end1, int start2, int end2, int start3, int end3);
+int NULL_VERTEX;
+revolution operator *(real[][] t, revolution r);
+skeleton operator init();
+revolution operator init();
+revolution sphere(triple c=<default>, real r, int n=<default>);
+path line(path p, path q, real[] t);
+surface surface(revolution r, int n=<default>, pen color(int i, real j)=<default>);
+void draw(picture pic=<default>, revolution r, int m=<default>, int n=<default>, pen frontpen=<default>, pen backpen=<default>, pen longitudinalpen=<default>, pen longitudinalbackpen=<default>, light light=<default>, string name=<default>, render render=<default>, projection P=<default>);
+real[] tangent(path p, path q, bool side);
+pen defaultbackpen;
+path[] cylinder(path3 base, real h, triple axis=<default>, projection P);
+revolution cylinder(triple c=<default>, real r, real h, triple axis=<default>);
+revolution cone(triple c=<default>, real r, real h, triple axis=<default>, int n=<default>);
+real rms(real[] A);
+int[] frequency(real[] data, real[] bins);
+int[] frequency(real[] data, real a, real b, int n);
+int[][] frequency(real[] x, real[] y, real[] xbins, real[] ybins);
+int[][] frequency(real[] x, real[] y, pair a, pair b, int nx, int ny=<default>);
+int[][] frequency(pair[] z, pair a, pair b, int nx, int ny=<default>);
+void histogram(picture pic=<default>, real[] bins, real[] count, real low=<default>, pen fillpen=<default>, pen drawpen=<default>, bool bars=<default>, Label legend=<default>, real markersize=<default>);
+void histogram(picture pic=<default>, real[] data, real a, real b, int n, bool normalize=<default>, real low=<default>, pen fillpen=<default>, pen drawpen=<default>, bool bars=<default>, Label legend=<default>, real markersize=<default>);
+real mean(real[] A);
+int bins(real[] data, int max=<default>);
+path topbox(pair a, pair b);
+path halfbox(pair a, pair b);
+real stdev(real[] A);
+real variance(real[] A);
+real legendmarkersize;
+real variancebiased(real[] A);
+real Gaussian(real x, real sigma);
+real Gaussian(real x);
+pair Gaussrandpair();
+real Gaussrand();
+linefit operator init();
+real skewness(real[] A);
+linefit leastsquares(real[] x, real[] y);
+real kurtosis(real[] A);
+real kurtosisexcess(real[] A);
+Relation r4a;
+pair[] endpoints(guide[] a);
+Relation r3;
+picture tableau(frame[] cards, bool number=<default>);
+pair min(pair[] z);
+Component bp;
+Component phi;
+real gapfactor;
+Component bm;
+Braid apply(Relation r, Braid b, int step, int place);
+Relation operator -(Relation r);
+Component operator init();
+Braid operator init();
+Relation operator init();
+Syzygy operator init();
+Relation r4b;
+Component wye;
+pair max(pair[] z);
+real hwratio;
+pen Orchid;
+pen WildStrawberry;
+pen Magenta;
+pen BrickRed;
+pen CadetBlue;
+pen CarnationPink;
+pen SpringGreen;
+pen MidnightBlue;
+pen OliveGreen;
+pen Apricot;
+pen Salmon;
+pen Cyan;
+pen Red;
+pen RawSienna;
+pen Mahogany;
+pen Gray;
+pen Plum;
+pen BlueGreen;
+pen Cerulean;
+pen Blue;
+pen BlueViolet;
+pen RedOrange;
+pen Goldenrod;
+pen ForestGreen;
+pen BurntOrange;
+pen Tan;
+pen Aquamarine;
+pen Brown;
+pen Lavender;
+pen RubineRed;
+pen TealBlue;
+pen White;
+pen Purple;
+pen Bittersweet;
+pen Orange;
+pen OrangeRed;
+pen Fuchsia;
+pen Peach;
+pen PineGreen;
+pen Dandelion;
+pen Black;
+pen NavyBlue;
+pen Rhodamine;
+pen YellowOrange;
+pen Maroon;
+pen ProcessBlue;
+pen YellowGreen;
+pen LimeGreen;
+pen Green;
+pen GreenYellow;
+pen Sepia;
+pen Emerald;
+pen Mulberry;
+pen RedViolet;
+pen SkyBlue;
+pen SeaGreen;
+pen VioletRed;
+pen Violet;
+pen Periwinkle;
+pen Thistle;
+pen Yellow;
+pen JungleGreen;
+pen DarkOrchid;
+pen CornflowerBlue;
+pen RoyalBlue;
+pen Melon;
+pen RoyalPurple;
+pen Turquoise;
+int lookup(tree t, int key);
+tree newtree();
+void write(file out=<default>, tree t);
+tree operator init();
+tree add(tree t, int key, int value);
+bool contains(tree t, int key);
+real trembleFuzz();
+real trembleAngle;
+real trembleRandom;
+real trembleFrequency;
+tremble operator init();
+real magneticRadius;
+real[] sample(path3 g, real r, real relstep=<default>);
+path3 roundedpath(path3 A, real r);
+int coloredNodes;
+int coloredSegments;
+surface surface(rmf[] R, real[] t, coloredpath cp, transform T(real), bool cyclic);
+surface tube(path3 g, coloredpath section, transform T(real)=<default>, real corner=<default>, real relstep=<default>);
+coloredpath operator init();
+coloredpath operator cast(path p);
+coloredpath operator cast(guide p);
+real degrees(rmf a, rmf b);
+string VERSION;
+pen Orchid;
+pen Indigo;
+pen Beige;
+pen Seashell;
+pen SlateBlue;
+pen SlateGray;
+pen Magenta;
+pen GhostWhite;
+pen CadetBlue;
+pen DeepPink;
+pen SpringGreen;
+pen MidnightBlue;
+pen Olive;
+pen OliveDrab;
+pen Salmon;
+pen LavenderBlush;
+pen Chocolate;
+pen Wheat;
+pen Cyan;
+pen Gainsboro;
+pen Ivory;
+pen PeachPuff;
+pen PapayaWhip;
+pen Red;
+pen Pink;
+pen MintCream;
+pen DarkTurquoise;
+pen Lime;
+pen SteelBlue;
+pen Gray;
+pen MediumBlue;
+pen MediumOrchid;
+pen MediumPurple;
+pen MediumSeaGreen;
+pen MediumSlateBlue;
+pen MediumAquamarine;
+pen MediumSpringGreen;
+pen MediumTurquoise;
+pen MediumVioletRed;
+pen Plum;
+pen Blue;
+pen Gold;
+pen BlueViolet;
+pen Goldenrod;
+pen ForestGreen;
+pen Chartreuse;
+pen NavajoWhite;
+pen LemonChiffon;
+pen Tan;
+pen DarkMagenta;
+pen AntiqueWhite;
+pen PaleTurquoise;
+pen Aquamarine;
+pen IndianRed;
+pen Aqua;
+pen Crimson;
+pen Azure;
+pen LawnGreen;
+pen Lavender;
+pen Brown;
+pen BurlyWood;
+pen Moccasin;
+pen DarkBlue;
+pen Peru;
+pen White;
+pen Purple;
+pen WhiteSmoke;
+pen DimGray;
+pen Orange;
+pen OrangeRed;
+pen Fuchsia;
+pen Bisque;
+pen Honeydew;
+pen RosyBrown;
+pen Black;
+pen Sienna;
+pen Khaki;
+pen FireBrick;
+pen Snow;
+pen Maroon;
+pen YellowGreen;
+pen LimeGreen;
+pen OldLace;
+pen Green;
+pen DarkOliveGreen;
+pen DarkOrange;
+pen GreenYellow;
+pen DarkCyan;
+pen FloralWhite;
+pen DarkRed;
+pen Silver;
+pen BlanchedAlmond;
+pen PowderBlue;
+pen DarkGray;
+pen DarkGreen;
+pen DarkGoldenrod;
+pen SkyBlue;
+pen SeaGreen;
+pen DarkViolet;
+pen Teal;
+pen Violet;
+pen AliceBlue;
+pen SandyBrown;
+pen HotPink;
+pen DodgerBlue;
+pen SaddleBrown;
+pen Tomato;
+pen DarkKhaki;
+pen DeepSkyBlue;
+pen Thistle;
+pen LightBlue;
+pen LightCoral;
+pen Yellow;
+pen LightCyan;
+pen PaleGreen;
+pen Linen;
+pen LightGoldenrodYellow;
+pen LightGreen;
+pen LightGrey;
+pen PaleGoldenrod;
+pen LightPink;
+pen LightSalmon;
+pen LightSeaGreen;
+pen Navy;
+pen LightSkyBlue;
+pen PaleVioletRed;
+pen DarkOrchid;
+pen LightSlateGray;
+pen LightSteelBlue;
+pen CornflowerBlue;
+pen LightYellow;
+pen rgbint(int r, int g, int b);
+pen Cornsilk;
+pen Coral;
+pen MistyRose;
+pen DarkSalmon;
+pen DarkSeaGreen;
+pen RoyalBlue;
+pen DarkSlateBlue;
+pen DarkSlateGray;
+pen Turquoise;
diff --git a/graphics/asymptote/asy.rc b/graphics/asymptote/asy.rc
new file mode 100644
index 0000000000..62b2e91dd3
--- /dev/null
+++ b/graphics/asymptote/asy.rc
@@ -0,0 +1,26 @@
+asy ICON PRELOAD "asy.ico"
+
+1 VERSIONINFO
+ FILEOS 0x40004
+ FILETYPE 0x1
+ FILESUBTYPE 0x0
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Vector Graphics Language\0"
+ VALUE "OriginalFilename", "asy.exe\0"
+ VALUE "LegalCopyright", "Copyright \251 2005 Andy Hammerlindl, John Bowman, Tom Prince\0"
+ VALUE "CompanyName", "Andy Hammerlindl, John Bowman, Tom Prince\0"
+ VALUE "ProductName", "Asymptote\0"
+ VALUE "ProductVersion", "ASYMPTOTE_VERSION\0"
+ VALUE "GPL Copyleft", "Released under the GNU General Public License version 2\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 0x04b0
+ END
+END
diff --git a/graphics/asymptote/asymptote.nsi b/graphics/asymptote/asymptote.nsi
new file mode 100644
index 0000000000..c9afcdb8b4
--- /dev/null
+++ b/graphics/asymptote/asymptote.nsi
@@ -0,0 +1,180 @@
+!define PRODUCT_NAME "Asymptote"
+!include AsymptoteInstallInfo.nsi
+!define PRODUCT_WEB_SITE "http://asymptote.sourceforge.net/"
+!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Asymptote"
+!define PRODUCT_FILE_TYPE_REGKEY1 "Software\Classes\.asy"
+!define PRODUCT_FILE_TYPE_REGKEY2 "Software\Classes\ASYFile\shell\open\command"
+!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
+!define PRODUCT_UNINST_ROOT_KEY "HKLM"
+!define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"
+
+SetCompressor lzma
+XPStyle On
+
+; MUI 1.67 compatible ------
+!include "MUI.nsh"
+!include "LogicLib.nsh"
+!include "lnkX64IconFix.nsh"
+
+; MUI Settings
+!define MUI_ABORTWARNING
+!define MUI_ICON "asy.ico"
+!define MUI_UNICON "asy.ico"
+
+; Welcome page
+!insertmacro MUI_PAGE_WELCOME
+; License page
+!insertmacro MUI_PAGE_LICENSE "LICENSE"
+;Components page
+; don't bother with this until there are other components to install
+; e.g.: possibility to automatically detect presence of, download, and install python, miktex, ImageMagick, etc
+;!insertmacro MUI_PAGE_COMPONENTS
+; Directory page
+!insertmacro MUI_PAGE_DIRECTORY
+; Start menu page
+var ICONS_GROUP
+!define MUI_STARTMENUPAGE_NODISABLE
+!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Asymptote"
+!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
+!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
+!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"
+!insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP
+; Instfiles page
+!insertmacro MUI_PAGE_INSTFILES
+; Finish page
+;!define MUI_FINISHPAGE_RUN "$INSTDIR\asy.bat"
+;!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\asymptote.pdf"
+!define MUI_FINISHPAGE_LINK ${PRODUCT_WEB_SITE}
+!define MUI_FINISHPAGE_LINK_LOCATION ${PRODUCT_WEB_SITE}
+!insertmacro MUI_PAGE_FINISH
+
+; Uninstaller pages
+!insertmacro MUI_UNPAGE_WELCOME
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+!insertmacro MUI_UNPAGE_FINISH
+
+; Language files
+!insertmacro MUI_LANGUAGE "English"
+
+; Reserve files
+!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+
+; MUI end ------
+
+Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
+OutFile "asymptote-${PRODUCT_VERSION}-setup.exe"
+InstallDir "$PROGRAMFILES64\Asymptote"
+InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
+ShowInstDetails show
+ShowUnInstDetails show
+
+Section "Asymptote" SEC01
+ SetOutPath "$INSTDIR"
+ SetOverwrite try
+ File /r build-${PRODUCT_VERSION}\*
+
+ FileOpen $0 $INSTDIR\asy.bat w
+
+ FileWrite $0 "@ECHO OFF"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "set CYGWIN=nodosfilewarning"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 '"$INSTDIR\asy.exe" %*'
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "if %errorlevel% == 0 exit /b"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "echo."
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "PAUSE"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileClose $0
+
+; Shortcuts
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"
+ SetOutPath "%USERPROFILE%"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Asymptote.lnk" "$INSTDIR\asy.bat" "" "$INSTDIR\asy.ico"
+ ${lnkX64IconFix} "$SMPROGRAMS\$ICONS_GROUP\Asymptote.lnk"
+ CreateShortCut "$DESKTOP\Asymptote.lnk" "$INSTDIR\asy.bat" "" "$INSTDIR\asy.ico"
+ ${lnkX64IconFix} "$DESKTOP\Asymptote.lnk"
+ CreateShortCut "$DESKTOP\Xasy.lnk" "$INSTDIR\GUI\xasy.py"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Xasy.lnk" "$INSTDIR\GUI\xasy.py"
+ SetOutPath "$INSTDIR"
+ !insertmacro MUI_STARTMENU_WRITE_END
+SectionEnd
+
+Section "Tester"
+
+SectionEnd
+
+Section -AdditionalIcons
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe"
+ !insertmacro MUI_STARTMENU_WRITE_END
+SectionEnd
+
+Section -Post
+ WriteUninstaller "$INSTDIR\uninst.exe"
+ ;create registry keys with information needed to run asymptote
+ WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\asy.exe"
+ WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "Path" "$INSTDIR"
+ WriteRegStr HKLM "${PRODUCT_FILE_TYPE_REGKEY1}" "" "ASYFile"
+ WriteRegStr HKLM "${PRODUCT_FILE_TYPE_REGKEY2}" "" '"$INSTDIR\asy.bat" "%1"'
+ WriteRegDWORD HKLM "SOFTWARE\Cygwin" "heap_chunk_in_mb" 0xFFFFFF00
+ ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "CYGWIN"
+ ${If} $0 == ""
+ WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "CYGWIN" "nodosfilewarning"
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ ${Endif}
+
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\asy.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
+SectionEnd
+
+
+Function un.onUninstSuccess
+ HideWindow
+ MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."
+FunctionEnd
+
+Section Uninstall
+ !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP
+ Delete "$INSTDIR\${PRODUCT_NAME}.url"
+ Delete "$INSTDIR\uninst.exe"
+ !include AsymptoteUninstallList.nsi
+ Delete "$INSTDIR\asy.bat"
+ RMDir "$INSTDIR"
+
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Website.lnk"
+ Delete "$DESKTOP\Asymptote.lnk"
+ Delete "$DESKTOP\Xasy.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Asymptote.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Xasy.lnk"
+ RMDir "$SMPROGRAMS\$ICONS_GROUP"
+
+
+ DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
+ DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
+ DeleteRegKey HKLM "${PRODUCT_FILE_TYPE_REGKEY1}"
+ DeleteRegKey HKLM "${PRODUCT_FILE_TYPE_REGKEY2}"
+ SetAutoClose true
+SectionEnd
diff --git a/graphics/asymptote/asymptote.spec b/graphics/asymptote/asymptote.spec
new file mode 100644
index 0000000000..87cabb3ff6
--- /dev/null
+++ b/graphics/asymptote/asymptote.spec
@@ -0,0 +1,109 @@
+%{!?_texmf: %global _texmf %(eval "echo `kpsewhich -expand-var '$TEXMFLOCAL'`")}
+%global _python_bytecompile_errors_terminate_build 0
+%global __python %{__python3}
+
+Name: asymptote
+Version: 2.53
+Release: 1%{?dist}
+Summary: Descriptive vector graphics language
+
+Group: Applications/Publishing
+License: GPL
+URL: http://asymptote.sourceforge.net/
+Source: http://downloads.sourceforge.net/sourceforge/asymptote/asymptote-%{version}.src.tgz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildRequires: ncurses-devel
+BuildRequires: readline-devel
+BuildRequires: fftw-devel >= 3.0
+BuildRequires: gc-devel >= 6.7
+BuildRequires: gsl-devel
+BuildRequires: glm-devel
+BuildRequires: tetex-latex
+BuildRequires: ghostscript >= 9.14
+BuildRequires: texinfo >= 4.7
+BuildRequires: ImageMagick
+
+Requires: tetex-latex
+Requires: tkinter
+Requires: freeglut-devel >= 3.0.0
+Requires(post): /usr/bin/texhash /sbin/install-info
+Requires(postun): /usr/bin/texhash /sbin/install-info
+
+%description
+Asymptote is a powerful descriptive vector graphics language for technical
+drawings, inspired by MetaPost but with an improved C++-like syntax.
+Asymptote provides for figures the same high-quality level of typesetting
+that LaTeX does for scientific text.
+
+
+%prep
+%setup -q
+
+
+%build
+CFLAGS="`echo $RPM_OPT_FLAGS | sed s/-O2/-O3/`" \
+%configure --with-latex=%{_texmf}/tex/latex --with-context=%{_texmf}/tex/context/third
+make %{?_smp_mflags}
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install-notexhash DESTDIR=$RPM_BUILD_ROOT
+
+%{__install} -p -m 644 BUGS ChangeLog LICENSE README ReleaseNotes TODO \
+ $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}/
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%post
+texhash >/dev/null 2>&1 || :
+/sbin/install-info %{_infodir}/%{name}/%{name}.info.gz %{_infodir}/dir 2>/dev/null || :
+
+%postun
+texhash >/dev/null 2>&1 || :
+if [ $1 = 0 ]; then
+ /sbin/install-info --remove %{_infodir}/%{name}/%{name}.info.gz %{_infodir}/dir 2>/dev/null || :
+fi
+
+
+%files
+%defattr(-,root,root,-)
+%doc %{_defaultdocdir}/%{name}/
+%{_bindir}/*
+%{_datadir}/%{name}/
+%{_texmf}/tex/latex/%{name}
+%{_texmf}/tex/context/third/%{name}
+%{_mandir}/man1/*.1*
+%{_infodir}/%{name}/
+%{_infodir}/%{name}/*.info*
+%{_infodir}/*.info*
+
+
+%changelog
+* Thu Apr 19 2007 John Bowman <> - 1.26-1
+- Update source tar ball name.
+
+* Tue May 30 2006 John Bowman <> - 1.07-1
+- Use make install-all to also install info pages.
+
+* Fri May 26 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.07-1
+- Update to 1.07.
+
+* Sun May 21 2006 John Bowman <> - 1.06-1
+- Update to 1.06.
+
+* Mon May 8 2006 John Bowman <> - 1.05-1
+- Update to 1.05.
+
+* Sun May 7 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.04-1
+- Update to 1.04.
+
+* Fri Mar 31 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.03-1
+- Update to 1.03.
+
+* Thu Mar 23 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.02-1
+- First build.
diff --git a/graphics/asymptote/autogen.sh b/graphics/asymptote/autogen.sh
new file mode 100755
index 0000000000..5ec2b3585b
--- /dev/null
+++ b/graphics/asymptote/autogen.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+autoheader && autoconf
diff --git a/graphics/asymptote/ax_pthread.m4 b/graphics/asymptote/ax_pthread.m4
new file mode 100644
index 0000000000..d90de34d14
--- /dev/null
+++ b/graphics/asymptote/ax_pthread.m4
@@ -0,0 +1,309 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise). (This
+# is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also link it with them as well. e.g. you should link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threads programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 18
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
+ AC_MSG_RESULT($ax_pthread_ok)
+ if test x"$ax_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+ ;;
+
+ darwin*)
+ ax_pthread_flags="-pthread $ax_pthread_flags"
+ ;;
+esac
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
+ if test x"$ax_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT($ax_pthread_ok)
+ if test "x$ax_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+ [int attr = $attr; return attr /* ; */])],
+ [attr_name=$attr; break],
+ [])
+ done
+ AC_MSG_RESULT($attr_name)
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case ${host_os} in
+ aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+ osf* | hpux*) flag="-D_REENTRANT";;
+ solaris*)
+ if test "$GCC" = "yes"; then
+ flag="-D_REENTRANT"
+ else
+ flag="-mt -D_REENTRANT"
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT(${flag})
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ ax_cv_PTHREAD_PRIO_INHERIT, [
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+ AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: must compile with xlc_r or cc_r
+ if test x"$GCC" != xyes; then
+ AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+ else
+ PTHREAD_CC=$CC
+ fi
+else
+ PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+ ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+ :
+else
+ ax_pthread_ok=no
+ $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/graphics/asymptote/base/CAD.asy b/graphics/asymptote/base/CAD.asy
new file mode 100644
index 0000000000..1bed03bc20
--- /dev/null
+++ b/graphics/asymptote/base/CAD.asy
@@ -0,0 +1,367 @@
+struct sCAD
+{
+ int nLineGroup = 0; // 0-3
+
+ pen
+ // A
+ pA,
+ pVisibleEdge, // Sichtbare Kanten
+ pVisibleContour, // Sichtbarer Umriss
+ pUsableWindingLength, // Nitzbare Gewindelänge
+ pSystemLine, // Systemlinie (Stahlbau)
+ pDiagramCurve, // Kurve in Diagrammen
+ pSurfaceStructure, // Oberflächenstrukturen
+ // B
+ pB,
+ pLightEdge, // Lichtkante
+ pMeasureLine, // Maßlinie
+ pMeasureHelpLine, // Maßhilfslinie
+ pMeasureLineBound, // Maßlinienbegrenzung
+ pReferenceLine, // Hinweislinie
+ pHatch, // Schraffur
+ pWindingGround, // Gewindegrund
+ pDiagonalCross, // Diagonalkreuz
+ pBendLine, // Biegelinie
+ pProjectionLine, // Projektionslinie
+ pGrid, // Rasterlinien
+ // C
+ pC,
+ pFreehand, // Begrenzung abgebrochener oder unterbrochener
+ // Schnitte, wenn die Begrenzung
+ // keine Mittellinie ist
+ // E
+ pE,
+ pSurfaceTreatmentAllowed, // Bereich zulässiger Oberflächenbehandlung
+ // F
+ pF,
+ pInvisibleEdge, // unsichtbare Kante
+ pInvisibleContour, // unsichtbarer Umriss
+ // G
+ pG,
+ pMiddleLine, // Mittellinie
+ pSymmetryLine, // Symmetrielinie
+ pPartialCircle, // Teilkreis
+ pCircularHole, // Lochkreis
+ pDivisionPlane, // Teilungsebene
+ pTransferLine, // Trajektorien (Übertragunslinien)
+ // J
+ pJ,
+ pCuttingPlane, // Schnittebene
+ pSurfaceTreatmentRequested, // Bereich geforderter Behandlungen
+ // K
+ pK,
+ pContourBeforeDeformation, // Umrisse vor Verformung
+ pAdjacentPartContour, // Umrisse angrenzender Teile
+ pEndShapeRawMaterial, // Fertigformen in Rohteilen
+ pContourEligibleType, // Umrisse wahlweiser Ausführungen
+ pPartInFrontOfCuttingPlane; // Teile vor der Schnittebene
+
+
+
+ static sCAD Create(int nLineGroup = 1)
+ {
+ sCAD cad = new sCAD;
+ if ( nLineGroup < 0 )
+ nLineGroup = 0;
+ if ( nLineGroup > 3 )
+ nLineGroup = 3;
+ cad.nLineGroup = nLineGroup;
+
+ restricted real[] dblFullWidth = {0.35mm, 0.5mm, 0.7mm, 1.0mm};
+ restricted real[] dblHalfWidth = {0.18mm, 0.25mm, 0.35mm, 0.5mm};
+
+ pen pFullWidth = linewidth(dblFullWidth[nLineGroup]);
+ pen pHalfWidth = linewidth(dblHalfWidth[nLineGroup]);
+
+ // Linienarten:
+ // A
+ cad.pA =
+ cad.pVisibleEdge =
+ cad.pVisibleContour =
+ cad.pUsableWindingLength =
+ cad.pSystemLine =
+ cad.pDiagramCurve =
+ cad.pSurfaceStructure =
+ pFullWidth + solid;
+ // B
+ cad.pB =
+ cad.pLightEdge =
+ cad.pMeasureLine =
+ cad.pMeasureHelpLine =
+ cad.pMeasureLineBound =
+ cad.pReferenceLine =
+ cad.pHatch =
+ cad.pWindingGround =
+ cad.pDiagonalCross =
+ cad.pBendLine =
+ cad.pProjectionLine =
+ cad.pGrid =
+ pHalfWidth + solid;
+ // C
+ cad.pC =
+ cad.pFreehand =
+ pHalfWidth + solid;
+ // D
+ // Missing, as I have no idea how to implement this...
+ // E
+ cad.pE =
+ cad.pSurfaceTreatmentAllowed =
+ pFullWidth + linetype(new real[] {10,2.5});
+ // F
+ cad.pF =
+ cad.pInvisibleEdge =
+ cad.pInvisibleContour =
+ pHalfWidth + linetype(new real[] {20,5});
+ // G
+ cad.pG =
+ cad.pMiddleLine =
+ cad.pSymmetryLine =
+ cad.pPartialCircle =
+ cad.pCircularHole =
+ cad.pDivisionPlane =
+ cad.pTransferLine =
+ pHalfWidth + linetype(new real[] {40,5,5,5});
+ // H
+ // see J
+ // I
+ // This letter is not used in DIN 15
+ // J
+ cad.pJ =
+ cad.pCuttingPlane =
+ cad.pSurfaceTreatmentRequested =
+ pFullWidth + linetype(new real[] {20,2.5,2.5,2.5});
+ // K
+ cad.pK =
+ cad.pContourBeforeDeformation =
+ cad.pAdjacentPartContour =
+ cad.pEndShapeRawMaterial =
+ cad.pContourEligibleType =
+ cad.pPartInFrontOfCuttingPlane =
+ pHalfWidth + linetype(new real[] {40,5,5,5,5,5});
+
+ return cad;
+ } // end of Create
+
+
+
+ real GetMeasurementBoundSize(bool bSmallBound = false)
+ {
+ if ( bSmallBound )
+ return 1.5 * linewidth(pVisibleEdge) / 2;
+ else
+ return 5 * linewidth(pVisibleEdge);
+ }
+
+
+
+ path GetMeasurementBound(bool bSmallBound = false)
+ {
+ if ( bSmallBound )
+ return scale(GetMeasurementBoundSize(bSmallBound = bSmallBound)) *
+ unitcircle;
+ else
+ return (0,0) --
+ (-cos(radians(7.5)), -sin(radians(7.5))) *
+ GetMeasurementBoundSize(bSmallBound = bSmallBound) --
+ (-cos(radians(7.5)), sin(radians(7.5))) *
+ GetMeasurementBoundSize(bSmallBound = bSmallBound) --
+ cycle;
+ }
+
+
+
+ void MeasureLine(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+ {
+ if ( dblLeft < 0 )
+ dblLeft = 0;
+ if ( dblRight < 0 )
+ dblRight = 0;
+ if ( (dblLeft > 0) && (dblRight == 0) )
+ dblRight = dblLeft;
+ if ( (dblLeft == 0) && (dblRight > 0) )
+ dblLeft = dblRight;
+ pair pDiff = pTo - pFrom;
+ real dblLength = length(pDiff);
+ pair pBegin = pFrom - dblLeft * unit(pDiff);
+ pair pEnd = pTo + dblRight * unit(pDiff);
+ if ( bSmallBound )
+ {
+ draw(
+ pic = pic,
+ g = pBegin--pEnd,
+ p = pMeasureLine);
+ }
+ else
+ {
+ real dblBoundSize = GetMeasurementBoundSize(bSmallBound = bSmallBound);
+ if ( dblLeft == 0 )
+ draw(
+ pic = pic,
+ g = (pFrom + dblBoundSize/2 * unit(pDiff))
+ -- (pTo - dblBoundSize/2 * unit(pDiff)),
+ p = pMeasureLine);
+ else
+ draw(
+ pic = pic,
+ g = pBegin -- (pFrom - dblBoundSize/2 * unit(pDiff))
+ ^^ pFrom -- pTo
+ ^^ (pTo + dblBoundSize/2 * unit(pDiff)) -- pEnd,
+ p = pMeasureLine);
+ }
+ path gArrow = GetMeasurementBound(bSmallBound = bSmallBound);
+ picture picL;
+ label(picL, L);
+ pair pLabelSize = 1.2 * (max(picL) - min(picL));
+ if ( dblLeft == 0 )
+ {
+ fill(
+ pic = pic,
+ g = shift(pFrom) * rotate(degrees(-pDiff)) * gArrow,
+ p = pVisibleEdge);
+ fill(
+ pic = pic,
+ g = shift(pTo) * rotate(degrees(pDiff)) * gArrow,
+ p = pVisibleEdge);
+ if ( dblRelPosition < 0 )
+ dblRelPosition = 0;
+ if ( dblRelPosition > 1 )
+ dblRelPosition = 1;
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pFrom
+ + dblRelPosition * pDiff
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ }
+ else
+ {
+ fill(
+ pic = pic,
+ g = shift(pFrom) * rotate(degrees(pDiff)) * gArrow,
+ p = pVisibleEdge);
+ fill(
+ pic = pic,
+ g = shift(pTo) * rotate(degrees(-pDiff)) * gArrow,
+ p = pVisibleEdge);
+ if ( (dblRelPosition >= 0) && (dblRelPosition <= 1) )
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pFrom
+ + dblRelPosition * pDiff
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ else
+ {
+ // draw label outside
+ if ( dblRelPosition < 0 )
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pBegin
+ + pLabelSize.x / 2 * unit(pDiff)
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ else
+ // dblRelPosition > 1
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pEnd
+ - pLabelSize.x / 2 * unit(pDiff)
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ }
+ }
+ } // end of MeasureLine
+
+
+
+ void MeasureParallel(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblDistance,
+ // Variables from MeasureLine
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+ {
+ pair pDiff = pTo - pFrom;
+ pair pPerpendicularDiff = unit(rotate(90) * pDiff);
+ real dblDistancePlus;
+ if ( dblDistance >= 0 )
+ dblDistancePlus = dblDistance + 1mm;
+ else
+ dblDistancePlus = dblDistance - 1mm;
+ draw(
+ pic = pic,
+ g = pFrom--(pFrom + dblDistancePlus*pPerpendicularDiff),
+ p = pMeasureHelpLine
+ );
+ draw(
+ pic = pic,
+ g = pTo--(pTo + dblDistancePlus*pPerpendicularDiff),
+ p = pMeasureHelpLine
+ );
+ MeasureLine(
+ pic = pic,
+ L = L,
+ pFrom = pFrom + dblDistance * pPerpendicularDiff,
+ pTo = pTo + dblDistance * pPerpendicularDiff,
+ dblLeft = dblLeft,
+ dblRight = dblRight,
+ dblRelPosition = dblRelPosition,
+ bSmallBound = bSmallBound);
+ } // end of MeasureParallel
+
+
+
+ path MakeFreehand(pair pFrom, pair pTo,
+ real dblRelDivisionLength = 12.5,
+ real dblRelDistortion = 2.5,
+ bool bIncludeTo = true)
+ {
+ pair pDiff = pTo - pFrom;
+ pair pPerpendicular = dblRelDistortion * linewidth(pFreehand) *
+ unit(rotate(90) * pDiff);
+
+ int nNumOfSubDivisions=ceil(length(pDiff) /
+ (dblRelDivisionLength * linewidth(pFreehand)));
+
+ restricted real[] dblDistortion = {1, -.5, .75, -.25, .25, -1, .5, -.75,
+ .25, -.25};
+ int nDistortion = 0;
+
+ guide g;
+ g = pFrom;
+ for ( int i = 1 ; i < nNumOfSubDivisions ; ++i )
+ {
+ g = g ..
+ (pFrom
+ + pDiff * i / (real)nNumOfSubDivisions
+ + pPerpendicular * dblDistortion[nDistortion]);
+ nDistortion += 1;
+ if ( nDistortion > 9 )
+ nDistortion = 0;
+ }
+
+ if ( bIncludeTo )
+ g = g .. pTo;
+
+ return g;
+ } // end of MakeFreehand
+
+
+
+} // end of CAD
+
diff --git a/graphics/asymptote/base/animate.asy b/graphics/asymptote/base/animate.asy
new file mode 100644
index 0000000000..586e71041b
--- /dev/null
+++ b/graphics/asymptote/base/animate.asy
@@ -0,0 +1,3 @@
+usepackage("animate");
+import animation;
+
diff --git a/graphics/asymptote/base/animation.asy b/graphics/asymptote/base/animation.asy
new file mode 100644
index 0000000000..e2fd1ea18c
--- /dev/null
+++ b/graphics/asymptote/base/animation.asy
@@ -0,0 +1,188 @@
+/*****
+ * animation.asy
+ * Andy Hammerlindl and John Bowman 2005/11/06
+ *
+ * Produce GIF, inline PDF, or other animations.
+ *****/
+
+// animation delay is in milliseconds
+real animationdelay=50;
+
+typedef frame enclosure(frame);
+
+frame NoBox(frame f) {
+ return f;
+}
+
+enclosure BBox(real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill) {
+ return new frame(frame f) {
+ box(f,xmargin,ymargin,p,filltype,above=false);
+ return f;
+ };
+}
+
+struct animation {
+ picture[] pictures;
+ string[] files;
+ int index;
+
+ string prefix;
+ bool global; // If true, use a global scaling for all frames; this requires
+ // extra memory since the actual shipout is deferred until all frames have
+ // been generated.
+
+ void operator init(string prefix="", bool global=true) {
+ prefix=replace(stripdirectory(outprefix(prefix))," ","_");
+ this.prefix=prefix;
+ this.global=global;
+ }
+
+ string basename(string prefix=stripextension(prefix)) {
+ return "_"+prefix;
+ }
+
+ string name(string prefix, int index) {
+ return stripextension(prefix)+"+"+string(index);
+ }
+
+ private string nextname() {
+ string name=basename(name(prefix,index));
+ ++index;
+ return name;
+ }
+
+ void shipout(string name=nextname(), frame f) {
+ string format=nativeformat();
+ plain.shipout(name,f,format=format,view=false);
+ files.push(name+"."+format);
+ }
+
+ void add(picture pic=currentpicture, enclosure enclosure=NoBox) {
+ if(global) {
+ ++index;
+ pictures.push(pic.copy());
+ } else this.shipout(enclosure(pic.fit()));
+ }
+
+ void purge(bool keep=settings.keep) {
+ if(!keep) {
+ for(int i=0; i < files.length; ++i)
+ delete(files[i]);
+ }
+ }
+
+ int merge(int loops=0, real delay=animationdelay, string format="gif",
+ string options="", bool keep=settings.keep) {
+ string args="-loop " +(string) loops+" -delay "+(string)(delay/10)+
+ " -alpha Off -dispose Background "+options;
+ for(int i=0; i < files.length; ++i)
+ args += " " +files[i];
+ int rc=convert(args,prefix+"."+format,format=format);
+ this.purge(keep);
+ if(rc == 0) animate(file=prefix+"."+format,format=format);
+ else abort("merge failed");
+ return rc;
+ }
+
+ void glmovie(string prefix=prefix, projection P=currentprojection) {
+ if(!view() || settings.render == 0) return;
+ fit(prefix,pictures,view=true,P);
+ }
+
+ // Export all frames with the same scaling.
+ void export(string prefix=prefix, enclosure enclosure=NoBox,
+ bool multipage=false, bool view=false,
+ projection P=currentprojection) {
+ if(pictures.length == 0) return;
+ if(!global) multipage=false;
+ bool inlinetex=settings.inlinetex;
+ if(multipage)
+ settings.inlinetex=false;
+ frame multi;
+ frame[] fits=fit(prefix,pictures,view=false,P);
+ for(int i=0; i < fits.length; ++i) {
+ string s=name(prefix,i);
+ if(multipage) {
+ add(multi,enclosure(fits[i]));
+ newpage(multi);
+ files.push(s+"."+nativeformat());
+ } else {
+ if(pictures[i].empty3() || settings.render <= 0)
+ this.shipout(s,enclosure(fits[i]));
+ else // 3D frames
+ files.push(s+"."+nativeformat());
+ }
+ }
+ if(multipage) {
+ plain.shipout(prefix,multi,view=view);
+ settings.inlinetex=inlinetex;
+ }
+ }
+
+ string load(int frames, real delay=animationdelay, string options="",
+ bool multipage=false) {
+ if(!global) multipage=false;
+ string s="\animategraphics["+options+"]{"+format("%.18f",1000/delay,"C")+
+ "}{"+basename();
+ if(!multipage) s += "+";
+ s += "}{0}{"+string(frames-1)+"}";
+ return s;
+ }
+
+ bool pdflatex()
+ {
+ return latex() && pdf();
+ }
+
+ string pdf(enclosure enclosure=NoBox, real delay=animationdelay,
+ string options="", bool keep=settings.keep, bool multipage=true) {
+ settings.twice=true;
+ if(settings.inlinetex) multipage=true;
+ if(!global) multipage=false;
+ if(!pdflatex())
+ abort("inline pdf animations require -tex pdflatex or -tex xelatex");
+ if(settings.outformat != "") settings.outformat="pdf";
+
+ string filename=basename();
+ string pdfname=filename+".pdf";
+
+ if(global)
+ export(filename,enclosure,multipage=multipage);
+
+ if(!keep) {
+ exitfcn currentexitfunction=atexit();
+ void exitfunction() {
+ if(currentexitfunction != null) currentexitfunction();
+ if(multipage || !settings.inlinetex)
+ this.purge();
+ if(multipage && !settings.inlinetex)
+ delete(pdfname);
+ }
+ atexit(exitfunction);
+ }
+
+ if(!multipage)
+ delete(pdfname);
+
+ return load(index,delay,options,multipage);
+ }
+
+ int movie(enclosure enclosure=NoBox, int loops=0, real delay=animationdelay,
+ string format=settings.outformat == "" ? "gif" : settings.outformat,
+ string options="", bool keep=settings.keep) {
+ if(global) {
+ if(format == "pdf") {
+ export(enclosure,multipage=true,view=true);
+ return 0;
+ }
+ export(enclosure);
+ }
+ return merge(loops,delay,format,options,keep);
+ }
+}
+
+animation operator init() {
+ animation a=animation();
+ return a;
+}
diff --git a/graphics/asymptote/base/annotate.asy b/graphics/asymptote/base/annotate.asy
new file mode 100644
index 0000000000..aba9309cb6
--- /dev/null
+++ b/graphics/asymptote/base/annotate.asy
@@ -0,0 +1,16 @@
+void annotate(picture pic=currentpicture, string title, string text,
+ pair position)
+{
+ pic.add(new void(frame f, transform t) {
+ position=t*position;
+ label(f,"\special{!/pdfmark where
+ {pop} {userdict /pdfmark /cleartomark load put} ifelse
+ [/Rect["+(string) position.x+" 0 0 "+(string) position.y+"]
+ /Subtype /Text
+ /Name /Comment
+ /Title ("+title+")
+ /Contents ("+text+")
+ /ANN pdfmark}");
+ },true);
+ draw(pic,position,invisible);
+}
diff --git a/graphics/asymptote/base/asy-init.el b/graphics/asymptote/base/asy-init.el
new file mode 100644
index 0000000000..0e3f178a22
--- /dev/null
+++ b/graphics/asymptote/base/asy-init.el
@@ -0,0 +1,4 @@
+(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
diff --git a/graphics/asymptote/base/asy-kate.sh b/graphics/asymptote/base/asy-kate.sh
new file mode 100644
index 0000000000..5f482b376d
--- /dev/null
+++ b/graphics/asymptote/base/asy-kate.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+echo '<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE language SYSTEM "language.dtd">
+<!-- based on asy-keywords.el and Highlighting file asymptote.xml by Christoph Hormann-->
+<language version="1.0" kateversion="3.2.2" name="asymptote" section="Sources" extensions="*.asy" mimetype="text/x-asymptote" licence="LGPL" author="Carsten Brenner">
+
+<highlighting>
+' > asymptote.xml
+
+# 1. Change Name of lists in <\list> <list name="...">
+# 2. tail to get rid of the first lines
+# 3. building the right line ending
+# 4-5. kill linebreaks
+# 6. change spaces into <\item><item>
+# 7. Undo change (7.) in 'list name'
+# 8. do some formatting
+
+cat asy-keywords.el | sed 's/^(.*\-\([^\-]*\)\-.*/\n<list name="\1"><item>/' | tail -14 | sed 's/ ))/<\/item><\/list>/' | tr '\n' '@' | sed 's/@//g' | sed 's/ /<\/item><item>/g' | sed 's/list<\/item><item>name/list name/g' | sed 's/></>\n</g' >> asymptote.xml
+
+echo '
+<contexts>
+ <context attribute="Normal Text" lineEndContext="#stay" name="Normal">
+ <DetectSpaces />
+ <RegExpr attribute="Preprocessor" context="Outscoped" String="#\s*if\s+0" beginRegion="Outscoped" firstNonSpace="true" />
+ <DetectChar attribute="Preprocessor" context="Preprocessor" char="#" firstNonSpace="true" />
+ <StringDetect attribute="Region Marker" context="Region Marker" String="//BEGIN" beginRegion="Region1" firstNonSpace="true" />
+ <StringDetect attribute="Region Marker" context="Region Marker" String="//END" endRegion="Region1" firstNonSpace="true" />
+ <keyword attribute="Keyword" context="#stay" String="keyword" />
+ <keyword attribute="Extensions" context="#stay" String="extensions" />
+ <keyword attribute="Function" context="#stay" String="function" />
+ <keyword attribute="Data Type" context="#stay" String="type" />
+ <keyword attribute="Constants" context="#stay" String="constants" />
+ <keyword attribute="Variable" context="#stay" String="variable" />
+ <HlCChar attribute="Char" context="#stay"/>
+ <DetectChar attribute="String" context="String" char="&quot;"/>
+ <DetectIdentifier />
+ <Float attribute="Float" context="#stay">
+ <AnyChar String="fF" attribute="Float" context="#stay"/>
+ </Float>
+ <HlCOct attribute="Octal" context="#stay"/>
+ <HlCHex attribute="Hex" context="#stay"/>
+ <Int attribute="Decimal" context="#stay">
+ <StringDetect attribute="Decimal" context="#stay" String="ULL" insensitive="TRUE"/>
+ <StringDetect attribute="Decimal" context="#stay" String="LUL" insensitive="TRUE"/>
+ <StringDetect attribute="Decimal" context="#stay" String="LLU" insensitive="TRUE"/>
+ <StringDetect attribute="Decimal" context="#stay" String="UL" insensitive="TRUE"/>
+ <StringDetect attribute="Decimal" context="#stay" String="LU" insensitive="TRUE"/>
+ <StringDetect attribute="Decimal" context="#stay" String="LL" insensitive="TRUE"/>
+ <StringDetect attribute="Decimal" context="#stay" String="U" insensitive="TRUE"/>
+ <StringDetect attribute="Decimal" context="#stay" String="L" insensitive="TRUE"/>
+ </Int>
+ <IncludeRules context="##Doxygen" />
+ <Detect2Chars attribute="Comment" context="Commentar 1" char="/" char1="/"/>
+ <Detect2Chars attribute="Comment" context="Commentar 2" char="/" char1="*" beginRegion="Comment"/>
+ <DetectChar attribute="Symbol" context="#stay" char="{" beginRegion="Brace1" />
+ <DetectChar attribute="Symbol" context="#stay" char="}" endRegion="Brace1" />
+ <AnyChar attribute="Symbol" context="#stay" String=":!%&amp;()+,-/.*&lt;=&gt;?[]{|}~^&#59;"/>
+ </context>
+ <context attribute="String" lineEndContext="#pop" name="String">
+ <LineContinue attribute="String" context="#stay"/>
+ <HlCStringChar attribute="String Char" context="#stay"/>
+ <DetectChar attribute="String" context="#pop" char="&quot;"/>
+ </context>
+ <context attribute="Region Marker" lineEndContext="#pop" name="Region Marker">
+ </context>
+ <context attribute="Comment" lineEndContext="#pop" name="Commentar 1">
+ <DetectSpaces />
+ <IncludeRules context="##Alerts" />
+ <DetectIdentifier />
+ </context>
+ <context attribute="Comment" lineEndContext="#stay" name="Commentar 2">
+ <DetectSpaces />
+ <Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" endRegion="Comment"/>
+ <IncludeRules context="##Alerts" />
+ <DetectIdentifier />
+ </context>
+ <context attribute="Preprocessor" lineEndContext="#pop" name="Preprocessor">
+ <LineContinue attribute="Preprocessor" context="#stay"/>
+ <RegExpr attribute="Preprocessor" context="Define" String="define.*((?=\\))"/>
+ <RegExpr attribute="Preprocessor" context="#stay" String="define.*"/>
+ <RangeDetect attribute="Prep. Lib" context="#stay" char="&quot;" char1="&quot;"/>
+ <RangeDetect attribute="Prep. Lib" context="#stay" char="&lt;" char1="&gt;"/>
+ <IncludeRules context="##Doxygen" />
+ <Detect2Chars attribute="Comment" context="Commentar 1" char="/" char1="/"/>
+ <Detect2Chars attribute="Comment" context="Commentar/Preprocessor" char="/" char1="*"/>
+ </context>
+ <context attribute="Preprocessor" lineEndContext="#pop" name="Define">
+ <LineContinue attribute="Preprocessor" context="#stay"/>
+ </context>
+ <context attribute="Comment" lineEndContext="#stay" name="Commentar/Preprocessor">
+ <DetectSpaces />
+ <Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" />
+ <DetectIdentifier />
+ </context>
+ <context attribute="Comment" lineEndContext="#stay" name="Outscoped" >
+ <DetectSpaces />
+ <IncludeRules context="##Alerts" />
+ <DetectIdentifier />
+ <DetectChar attribute="String" context="String" char="&quot;"/>
+ <IncludeRules context="##Doxygen" />
+ <Detect2Chars attribute="Comment" context="Commentar 1" char="/" char1="/"/>
+ <Detect2Chars attribute="Comment" context="Commentar 2" char="/" char1="*" beginRegion="Comment"/>
+ <RegExpr attribute="Comment" context="Outscoped intern" String="#\s*if" beginRegion="Outscoped" firstNonSpace="true" />
+ <RegExpr attribute="Preprocessor" context="#pop" String="#\s*(endif|else|elif)" endRegion="Outscoped" firstNonSpace="true" />
+ </context>
+ <context attribute="Comment" lineEndContext="#stay" name="Outscoped intern">
+ <DetectSpaces />
+ <IncludeRules context="##Alerts" />
+ <DetectIdentifier />
+ <DetectChar attribute="String" context="String" char="&quot;"/>
+ <IncludeRules context="##Doxygen" />
+ <Detect2Chars attribute="Comment" context="Commentar 1" char="/" char1="/"/>
+ <Detect2Chars attribute="Comment" context="Commentar 2" char="/" char1="*" beginRegion="Comment"/>
+ <RegExpr attribute="Comment" context="Outscoped intern" String="#\s*if" beginRegion="Outscoped" firstNonSpace="true"/>
+ <RegExpr attribute="Comment" context="#pop" String="#\s*endif" endRegion="Outscoped" firstNonSpace="true"/>
+ </context>
+ </contexts>
+ <itemDatas>
+ <itemData name="Char" defStyleNum="dsChar"/>
+ <itemData name="Comment" defStyleNum="dsComment"/>
+ <itemData name="Data Type" defStyleNum="dsDataType"/>
+ <itemData name="Decimal" defStyleNum="dsDecVal"/>
+ <itemData name="Extensions" defStyleNum="dsKeyword" color="#0095ff" selColor="#ffffff" bold="1" italic="0"/>
+ <itemData name="Float" defStyleNum="dsFloat"/>
+ <itemData name="Function" defStyleNum="dsFunction" />
+ <itemData name="Hex" defStyleNum="dsBaseN"/>
+ <itemData name="Keyword" defStyleNum="dsKeyword"/>
+ <itemData name="Normal Text" defStyleNum="dsNormal"/>
+ <itemData name="Octal" defStyleNum="dsBaseN"/>
+ <itemData name="Prep. Lib" defStyleNum="dsOthers"/>
+ <itemData name="Preprocessor" defStyleNum="dsOthers"/>
+ <itemData name="Region Marker" defStyleNum="dsRegionMarker" />
+ <itemData name="String Char" defStyleNum="dsChar"/>
+ <itemData name="String" defStyleNum="dsString"/>
+ <itemData name="Symbol" defStyleNum="dsNormal"/>
+ <itemData name="Variable" defStyleNum="dsOthers" />
+ </itemDatas>
+ </highlighting>
+ <general>
+ <comments>
+ <comment name="singleLine" start="//" />
+ <comment name="multiLine" start="/*" end="*/" region="Comment"/>
+ </comments>
+ <keywords casesensitive="1" />
+ </general>
+ </language>' >> asymptote.xml
diff --git a/graphics/asymptote/base/asy-mode.el b/graphics/asymptote/base/asy-mode.el
new file mode 100644
index 0000000000..c1960e2303
--- /dev/null
+++ b/graphics/asymptote/base/asy-mode.el
@@ -0,0 +1,1600 @@
+;;; asy-mode.el --- Major mode for editing Asymptote source code.
+
+;; Copyright (C) 2006-8
+
+;; Author: Philippe IVALDI 20 August 2006
+;; Maintainer: John Bowman
+;; URL: https://github.com/vectorgraphics/asymptote
+;; Version: 1.6
+;; Keywords: language, mode
+
+;;; License:
+
+;; This program is free software ; you can redistribute it and/or modify
+;; it under the terms of the GNU Lesser General Public License as published by
+;; the Free Software Foundation ; either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY ; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public License
+;; along with this program ; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+;;; Commentary
+
+;; Major mode for editing Asymptote source code.
+
+;; INSTALLATION:
+;; Place this file (asy-mode.el) and asy-keywords.el in your Emacs load path.
+;; Then choose ONE of the following installation methods:
+
+;; * Method 1:
+;; Copy and uncomment the following lines to your .emacs initialization file:
+;;(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+;;(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+;;(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+;;(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+;; * Method 2:
+;; Copy and uncomment the following line to your .emacs initialization file:
+;;(require 'asy-mode)
+
+;; Notes:
+;;
+;; For full functionality the two-mode-mode package should also be installed
+;; (http://www.dedasys.com/freesoftware/files/two-mode-mode.el).
+;;
+;; See also paragraph II of the documentation below to automate asy-insinuate-latex.
+
+;;; Code:
+
+(defvar asy-mode-version "1.6")
+
+;;;###autoload
+(define-derived-mode asy-mode objc-mode "Asymptote"
+ "Emacs mode for editing Asymptote source code.
+For full functionality the `two-mode-mode' package should also be installed
+(http://www.dedasys.com/freesoftware/files/two-mode-mode.el).
+
+I. This package provides two modes:
+1- asy-mode:
+All the files with the extension '.asy' are edited in this mode, which provides the following features:
+* Syntax color highlighting;
+* Compiling and viewing current buffer with the key binding C-c C-c;
+* Moving cursor to the error by pressing the key F4.
+* Showing the available function prototypes for the command at the cursor with the key binding C-c ?
+* Compiling and viewing a TeX document linked with the current buffer (usually a document that includes the output picture).
+To link a Tex document try 'M-x asy-set-master-tex' follow by C-Return (see descriptions further of the key binding C-Return, C-S-Return, M-Return, M-S-Return etc within 2- lasy-mode)
+
+2- lasy-mode
+Editing a TeX file that contains Asymptote code is facilitated with the hybrid mode 'lasy-mode'.
+Toggle lasy-mode with M-x lasy-mode.
+In this hybrid mode the major mode is LaTeX when the cursor is in LaTeX code and becomes asy-mode when the cursor is between '\\begin{asy}' and '\\end{asy}'.
+All the features of asy-mode are provided and the key binding C-c C-c of asy-mode compiles and views only the code of the picture where the cursor is.
+Note that some keys binding are added to the LaTeX-mode-map in lasy-mode if the value of the variable lasy-extra-key is t (the default)
+.
+* C-return: compile (if the buffer/file is modified) and view the PostScript output with sequence [latex->[asy->latex]->dvips]->PSviewer
+* M-return: same with pdf output and with the sequence [pdflatex->[asy->pdflatex]]->PDFviewer
+* C-M-return: same with pdf output and with the sequence [latex->[asy->latex]->dvips->ps2pdf]->PSviewer
+* Add the Shift key to the sequence of keys to compile even if the file is not modified.
+
+II. To add a menu bar in current 'latex-mode' buffer and activate hot keys, use 'M-x asy-insinuate-latex <RET>'.
+You can automate this feature for all the 'latex-mode' buffers by inserting the five following lines in your .emacs initialization file:
+(eval-after-load \"latex\"
+ '(progn
+ ;; Add here your personal features for 'latex-mode':
+ (asy-insinuate-latex t) ;; Asymptote globally insinuates Latex.
+ ))
+
+You can access this help within Emacs by the key binding C-h f asy-mode <RET>
+
+BUGS:
+This package has been tested in:
+* Linux Debian Etch
+- GNU Emacs 22.0.50.1
+- GNU Emacs 21.4.1 (only basic errors management and basic font-lock features within lasy-mode are supported)
+* WindowsXP
+- GNU Emacs 22.0.990.1 (i386-mingw-nt5.1.2600)
+
+This package seems to work with XEmacs 21.4 but not all the features are available (in particular syntax highlighting).
+
+Report bugs to http://asymptote.sourceforge.net
+
+Some variables can be customized: M-x customize-group <RET> asymptote <RET>."
+
+ (setq c++-font-lock-extra-types (cons "true" c++-font-lock-extra-types)))
+
+(require 'font-lock)
+(require 'cc-mode)
+(require 'cl) ;; Common Lisp extensions for Emacs
+(require 'compile)
+(require 'wid-edit)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+(defvar running-xemacs-p (featurep 'xemacs))
+(defvar running-unix-p (not (string-match "windows-nt\\|ms-dos" (symbol-name system-type))))
+
+(when running-xemacs-p
+ (defalias 'turn-on-font-lock-if-enabled 'ignore)
+ (defalias 'line-number-at-pos 'line-number)
+ (defvar temporary-file-directory (temp-directory))
+ (defun replace-regexp-in-string (regexp rep string)
+ (replace-in-string string regexp rep))
+ )
+
+(when (or (< emacs-major-version 22) running-xemacs-p)
+ ;; Add regexp for parsing the compilation errors of asy
+ (add-to-list 'compilation-error-regexp-alist
+ '("\\(.*?.asy\\): \\(.*?\\)\\.\\(.*?\\):" 1 2 3)))
+
+(when (< emacs-major-version 22)
+ (defun line-number-at-pos (&optional pos)
+ "Return (narrowed) buffer line number at position POS.
+If POS is nil, use current buffer location.
+Counting starts at (point-min), so the value refers
+to the contents of the accessible portion of the buffer."
+ (let ((opoint (or pos (point))) start)
+ (save-excursion
+ (goto-char (point-min))
+ (setq start (point))
+ (goto-char opoint)
+ (forward-line 0)
+ (1+ (count-lines start (point)))))))
+
+(defcustom lasy-extra-key t
+ "* If on, the folowing binding keys are added in lasy-mode :
+ (define-key lasy-mode-map (kbd \"<C-return>\") 'lasy-view-ps)
+ (define-key lasy-mode-map (kbd \"<C-S-return>\") 'asy-master-tex-view-ps-f)
+ (define-key lasy-mode-map (kbd \"<M-return>\") 'lasy-view-pdf-via-pdflatex)
+ (define-key lasy-mode-map (kbd \"<M-S-return>\") 'asy-master-tex-view-pdflatex-f)
+ (define-key lasy-mode-map (kbd \"<C-M-return>\") 'lasy-view-pdf-via-ps2pdf)
+ (define-key lasy-mode-map (kbd \"<C-M-S-return>\") 'asy-master-tex-view-ps2pdf-f)
+
+If you also want this feature in pure latex-mode, you can set this variable to `nil' and add these lines in your .emacs:
+
+(require 'asy-mode)
+(eval-after-load \"latex\"
+ '(progn
+ (define-key LaTeX-mode-map (kbd \"<C-return>\") 'lasy-view-ps)
+ (define-key LaTeX-mode-map (kbd \"<C-S-return>\") 'asy-master-tex-view-ps-f)
+ (define-key LaTeX-mode-map (kbd \"<M-return>\") 'lasy-view-pdf-via-pdflatex)
+ (define-key LaTeX-mode-map (kbd \"<M-S-return>\") 'asy-master-tex-view-pdflatex-f)
+ (define-key LaTeX-mode-map (kbd \"<C-M-return>\") 'lasy-view-pdf-via-ps2pdf)
+ (define-key LaTeX-mode-map (kbd \"<C-M-S-return>\") 'asy-master-tex-view-ps2pdf-f)))"
+ :type 'boolean
+ :group 'asymptote)
+
+(defcustom asy-compilation-buffer 'none
+ " 'visible means keep compilation buffer visible ;
+ 'available means keep compilation buffer available in other buffer but not visible;
+ 'none means delete compilation buffer automatically after a *successful* compilation.
+ 'never means don't open any window or buffer attached to the compilation process.
+If the value is 'never':
+* Emacs is suspended until the child program returns;
+* the management of errors is poorer than with other value;
+* the compilation doesn't modify your current window configuration."
+ :type '(choice (const visible) (const available) (const none) (const never))
+ :group 'asymptote)
+
+(defcustom lasy-ask-about-temp-compilation-buffer t
+ "* If t, ask before visiting a temporary buffer of compilation."
+ :type 'boolean
+ :group 'asymptote)
+
+(defcustom lasy-compilation-inline-auto-detection nil
+ "* If t, lasy-mode detects automatically if the option 'inline' is passed to asymptote.sty.
+In case of 'inline' option, the compilation of a figure separately of the document is processed by rebuilding the preamble and compiling it as a file '.tex' containing only this picture.
+ If nil (the default), the compilation of a figure separately of the document is processed by building a file '.asy', without the features of the LaTeX preamble."
+ :type 'boolean
+ :group 'asymptote)
+
+(defcustom asy-command-location ""
+ "* If not in the path, you can put here the name of the directory containing Asy's binary files.
+this variable must end in /."
+ :type 'directory
+ :group 'asymptote)
+
+(defcustom asy-command "asy -V"
+ "* Command invoked to compile a Asymptote file.
+You can define the location of this command with the variable `asy-command-location'."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-command "asy"
+ "* Command invoked to compile a Asymptote file generated compiling a .tex file.
+You can define the location of this command with the variable `asy-command-location'."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-latex-command "latex -halt-on-error"
+ "* Command invoked to compile a .tex file with LaTeX."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-pdflatex-command "pdflatex -halt-on-error"
+ "* Command invoked to compile a .tex file with pdflaTex."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-dvips-pre-pdf-command "dvips -Ppdf"
+ "* Command invoked to convert a .dvi file to a temporary .ps file in order to
+generate a final .pdf file."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-dvips-command "dvips -q"
+ "* Command invoked to convert a .dvi file to a final .ps file."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-ps2pdf-command "ps2pdf14"
+ "* Command invoked to convert a .dvi file to .ps file."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom asy-temp-dir temporary-file-directory
+ "*The name of a directory for Asy's temporary files.
+Such files are generated by functions like
+`asy-compile' when lasy-mode is enable."
+ :type 'directory
+ :group 'asymptote)
+
+(defcustom ps-view-command (if running-unix-p "gv" "")
+ "Command to view a PostScript file generated by compiling a tex file within lasy-mode.
+This variable is not used when running the Windows OS.
+See `asy-open-file'."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom pdf-view-command
+ (if running-unix-p
+ "xpdf" "")
+ "Command to view a pdf file generated by compiling a tex file within lasy-mode.
+This variable is not used when running the Windows OS.
+See `asy-open-file'."
+ :type 'string
+ :group 'asymptote)
+
+(defvar asy-TeX-master-file nil
+ "TeX file associate with current asymptote code.
+This variable must be modified only using the function 'asy-set-master-tex by M-x asy-set-master-tex <RET>.")
+(make-variable-buffer-local 'asy-TeX-master-file)
+
+(defvar lasy-compile-tex nil
+ "* Internal use. t if LaTeX compilation come from latex-mode.")
+
+(when (fboundp 'font-lock-add-keywords)
+ (if (< max-specpdl-size 2000) (setq max-specpdl-size 2000))
+ (defun asy-add-function-keywords (function-keywords face-name)
+ (let* ((keyword-list (mapcar #'(lambda (x)
+ (symbol-name x))
+ function-keywords))
+ (keyword-regexp (concat "\\<\\("
+ (regexp-opt keyword-list)
+ "\\)(")))
+ (font-lock-add-keywords 'asy-mode
+ `((,keyword-regexp 1 ',face-name)))))
+
+ (defun asy-add-variable-keywords (function-keywords face-name)
+ (let* ((keyword-list (mapcar #'(lambda (x)
+ (symbol-name x))
+ function-keywords))
+ (keyword-regexp (concat "\\<[0-9]*\\("
+ (regexp-opt keyword-list)
+ "\\)\\(?:[^(a-zA-Z]\\|\\'\\)")))
+ (font-lock-add-keywords 'asy-mode
+ `((,keyword-regexp 1 ',face-name)))))
+
+ ;; External definitions of keywords:
+ ;; asy-function-name and asy-variable-name
+ (if (locate-library "asy-keywords.el")
+ (load "asy-keywords.el")
+ (progn
+ ;; Use dummy keyword definitions if asy-keywords.el is not found:
+ (defvar asy-keyword-name nil)
+ (defvar asy-type-name nil)
+ (defvar asy-function-name nil)
+ (defvar asy-variable-name nil)))
+
+ (defcustom asy-extra-type-name '()
+ "Extra user type names highlighted with 'font-lock-type-face"
+ :type '(repeat symbol)
+ :group 'asymptote)
+
+ (defcustom asy-extra-function-name
+ '()
+ "Extra user function names highlighted with 'font-lock-function-name-face"
+ :type '(repeat symbol)
+ :group 'asymptote)
+
+ (defcustom asy-extra-variable-name '()
+ "Extra user variable names highlighted with 'font-lock-constant-face"
+ :type '(repeat symbol)
+ :group 'asymptote)
+
+ (asy-add-variable-keywords
+ asy-keyword-name
+ 'font-lock-builtin-face)
+
+ (asy-add-variable-keywords
+ (nconc asy-type-name asy-extra-type-name)
+ 'font-lock-type-face)
+
+ (asy-add-function-keywords
+ (nconc asy-function-name asy-extra-function-name)
+ 'font-lock-function-name-face)
+
+ (asy-add-variable-keywords
+ (nconc asy-variable-name asy-extra-variable-name)
+ 'font-lock-constant-face)
+
+ (defface asy-environment-face
+ `((t
+ (:underline t :inverse-video t)))
+ "Face used to highlighting the keywords '\\begin{asy}' and '\\end{asy}' within lasy-mode."
+ :group 'asymptote)
+
+ (font-lock-add-keywords
+ 'asy-mode
+ '(("\\\\begin{asy}.*" . 'asy-environment-face)
+ ("\\\\end{asy}" . 'asy-environment-face)))
+
+ (defface asy-link-face ;; widget-field-face
+ `((t
+ (:underline t)))
+ "Face used to highlighting the links."
+ :group 'asymptote)
+
+ (font-lock-add-keywords
+ 'asy-mode
+ '(("\\[.*?\\.asy\\]" . 'asy-link-face)))
+ )
+
+(setq buffers-menu-max-size nil)
+(setq mode-name "Asymptote")
+
+(if running-xemacs-p
+ (defvar asy-menu
+ '("Asy"
+ ["Toggle lasy-mode" lasy-mode :active (and (featurep 'two-mode-mode) two-mode-bool)]
+ ["Compile/View" asy-compile t]
+ ["Go to error" asy-goto-error t]
+ ["Describe command" asy-show-function-at-point t]"--"
+ ("Master TeX file"
+ ["Set/Change value" (asy-set-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool))]
+ ["Erase value" (asy-unset-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool))]
+ ("Compile OR View"
+ ["PS" asy-master-tex-view-ps :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf :active t])
+ ("Compile AND View"
+ ["PS" asy-master-tex-view-ps-f :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex-f :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf-f :active t]))
+ ["Asymptote insinuates globally LaTeX" asy-insinuate-latex-globally :active (not asy-insinuate-latex-globally-p)]"--"
+ ("Debugger Buffer"
+ ["Visible" (setq asy-compilation-buffer 'visible) :style radio :selected (eq asy-compilation-buffer 'visible) :active t]
+ ["Available" (setq asy-compilation-buffer 'available) :style radio :selected (eq asy-compilation-buffer 'available) :active t]
+ ["None" (setq asy-compilation-buffer 'none) :style radio :selected (eq asy-compilation-buffer 'none) :active t]
+ ["Never" (setq asy-compilation-buffer 'never) :style radio :selected (eq asy-compilation-buffer 'never) :active t])
+ ("Compilation Options" :included (and (featurep 'two-mode-mode) two-mode-bool)
+ ["Enable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection t) :style radio :selected lasy-compilation-inline-auto-detection :active t]
+ ["Disable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection nil) :style radio :selected (not lasy-compilation-inline-auto-detection) :active t])
+ ["Customize" (customize-group "asymptote") :active t]
+ ["Help" (describe-function 'asy-mode) :active t]
+ ))
+ (defvar asy-menu
+ '("Asy"
+ ["Toggle Lasy-Mode" lasy-mode :visible (and (featurep 'two-mode-mode) two-mode-bool)]
+ ["Compile/View" asy-compile t]
+ ["Go to Error" asy-goto-error t]
+ ["Describe Command" asy-show-function-at-point t]"--"
+ ("Master TeX File"
+ ["Set/Change Value" (asy-set-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool)) :key-sequence nil]
+ ["Erase Value" (asy-unset-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool)) :key-sequence nil]
+ ("Compile or View"
+ ["PS" asy-master-tex-view-ps :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf :active t])
+ ("Compile and View"
+ ["PS" asy-master-tex-view-ps-f :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex-f :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf-f :active t]))
+ ["Asymptote Insinuates Globally LaTeX" asy-insinuate-latex-globally :active (not asy-insinuate-latex-globally-p)]"--"
+ ("Debugger Buffer"
+ ["Visible" (setq asy-compilation-buffer 'visible) :style radio :selected (eq asy-compilation-buffer 'visible) :active t :key-sequence nil]
+ ["Available" (setq asy-compilation-buffer 'available) :style radio :selected (eq asy-compilation-buffer 'available) :active t :key-sequence nil]
+ ["None" (setq asy-compilation-buffer 'none) :style radio :selected (eq asy-compilation-buffer 'none) :active t :key-sequence nil]
+ ["Never" (setq asy-compilation-buffer 'never) :style radio :selected (eq asy-compilation-buffer 'never) :active t :key-sequence nil])
+ ("Compilation Options" :visible (and (featurep 'two-mode-mode) two-mode-bool)
+ ["Enable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection t) :style radio :selected lasy-compilation-inline-auto-detection :active t :key-sequence nil]
+ ["Disable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection nil) :style radio :selected (not lasy-compilation-inline-auto-detection) :active t :key-sequence nil])
+ ["Customize" (customize-group "asymptote") :active t :key-sequence nil]
+ ["Help" (describe-function 'asy-mode) :active t :key-sequence nil]
+ )))
+(easy-menu-define asy-mode-menu asy-mode-map "Asymptote Mode Commands" asy-menu)
+;; On the hook for XEmacs only.
+(if running-xemacs-p
+ (add-hook 'asy-mode-hook
+ (lambda ()
+ (and (eq major-mode 'asy-mode)
+ (easy-menu-add asy-mode-menu asy-mode-map)))))
+
+(defun asy-protect-file-name(Filename)
+ (concat "\"" Filename "\""))
+
+(defun asy-get-temp-file-name(&optional noext)
+ "Get a temp file name for printing."
+ (if running-xemacs-p
+ (concat (make-temp-name asy-temp-dir) (if noext "" ".asy"))
+ (concat (make-temp-file
+ (expand-file-name "asy" asy-temp-dir)) (if noext "" ".asy"))))
+
+(defun asy-log-filename()
+ (concat buffer-file-name ".log"))
+
+(defun asy-compile()
+ "Compile Asymptote code."
+ (interactive)
+ (if (and (boundp two-mode-bool) two-mode-bool)
+ (lasy-compile) ;; compile asy code in a TeX file.
+ (progn ;; compile asy code in a asy file.
+ (let*
+ ((buffer-base-name (file-name-sans-extension (file-name-nondirectory buffer-file-name)))
+ (asy-compile-command
+ (concat asy-command-location asy-command
+ (if (eq asy-compilation-buffer 'never)
+ " " " -wait ")
+ (asy-protect-file-name buffer-base-name))))
+ (if (buffer-modified-p) (save-buffer))
+ (message "%s" asy-compile-command)
+ (asy-internal-compile asy-compile-command t t)))))
+
+(defun asy-error-message(&optional P)
+ (let ((asy-last-error
+ (asy-log-field-string
+ (asy-log-filename) 0)))
+ (if (and asy-last-error (not (string= asy-last-error "")))
+ (message (concat asy-last-error (if P "\nPress F4 to go to error" "")))
+ (when (and (boundp two-mode-bool) two-mode-bool lasy-run-tex (not (zerop asy-last-compilation-code)))
+ (message "The LaTeX code may be incorrect.")))))
+
+(defun asy-log-field-string(Filename Field)
+ "Return field of first line of file filename.
+Fields are defined as 'field1: field2.field3:field4' . Field=0 <-> all fields"
+ (let ((view-inhibit-help-message t))
+ (with-temp-buffer
+ (progn
+ (insert-file Filename)
+ (beginning-of-buffer)
+ (if (re-search-forward "^\\(.*?\\): \\(.*?\\)\\.\\(.*?\\):\\(.*\\)$" (point-max) t)
+ (match-string Field) nil)))))
+
+(defun asy-next-error(arg reset)
+ (if (> emacs-major-version 21)
+ (next-error arg reset)
+ (next-error arg)))
+
+(defun lasy-ask-visit-tem-compilation-buffer()
+ "* Ask before visiting a temporary compilation buffer depending the value of `lasy-ask-about-temp-compilation-buffer'."
+ (if lasy-ask-about-temp-compilation-buffer
+ (y-or-n-p "Visit temporary buffer of compilation ? ") t))
+
+(defun lasy-place-cursor-to-error(Filename li co)
+ (save-excursion
+ (with-temp-buffer
+ (insert-file-contents
+ (if running-unix-p Filename
+ (replace-regexp-in-string
+ "//" ":/"
+ (replace-regexp-in-string "/cygdrive/" "" Filename)))) ;; Not right,
+;;;maybe take a look at the code of compilation-find-file
+ (beginning-of-buffer)
+ (next-line (1- (string-to-number li)))
+ (setq line-err
+ (buffer-substring-no-properties
+ (progn (beginning-of-line) (point))
+ (progn (end-of-line) (point))))))
+ (beginning-of-buffer)
+ (search-forward line-err)
+ (beginning-of-line)
+ (forward-char (1- (string-to-number co))))
+
+(defun asy-goto-error(&optional arg reset)
+ "Go to point of last error within asy/lasy-mode."
+ (interactive "P")
+ (if (or (eq asy-compilation-buffer 'never)
+ (and (boundp two-mode-bool) two-mode-bool))
+ (let* ((log-file (asy-log-filename))
+ (li_ (asy-log-field-string log-file 2))
+ (co_ (asy-log-field-string log-file 3)))
+ (if (and (boundp two-mode-bool) two-mode-bool) ;; Within Lasy-mode
+ (progn ;; lasy-mode need the compilation of file.tex
+ ;; the error can be in Tex commands or in Asymptote commands
+ (if (eq asy-compilation-buffer 'never) ;; Find error in the log file.
+ (if li_ ;; Asy error found in the log-file
+ (progn
+ (lasy-place-cursor-to-error
+ (asy-log-field-string log-file 1) li_ co_)
+ (asy-error-message))
+ (message "There is an error in your LaTeX code..."))
+ (if (or running-xemacs-p (< emacs-major-version 22))
+ (when (lasy-ask-visit-tem-compilation-buffer)
+ (next-error arg))
+ (let ((msg)) ;; Find error in the compilation buffer
+ (save-excursion
+ (set-buffer (next-error-find-buffer))
+ (when reset
+ (setq compilation-current-error nil))
+ (let* ((columns compilation-error-screen-columns)
+ (last 1)
+ (loc (compilation-next-error (or arg 1) nil
+ (or compilation-current-error
+ compilation-messages-start
+ (point-min))))
+ (end-loc (nth 2 loc))
+ (marker (point-marker)))
+ (setq compilation-current-error (point-marker)
+ overlay-arrow-position
+ (if (bolp)
+ compilation-current-error
+ (copy-marker (line-beginning-position)))
+ loc (car loc)))
+ (if (re-search-forward "^\\(.*?\\): \\(.*?\\)\\.\\(.*?\\):\\(.*\\)$" (point-max) t)
+ (progn
+ (setq msg (match-string 0)
+ log-file (match-string 1)
+ li_ (match-string 2)
+ co_ (match-string 3)))
+ (error "Not other errors.")))
+ (lasy-place-cursor-to-error log-file li_ co_)
+ (message msg)))))
+ (if li_ ;;Pure asy-mode and compilation with shell-command
+ (progn
+ (goto-line (string-to-number li_))
+ (forward-char (1- (string-to-number co_)))
+ (asy-error-message))
+ (progn (message "No error.")))))
+ (asy-next-error arg reset)))
+
+(defun asy-grep (Regexp)
+ "Internal function used by asymptote."
+ (let ((Strout "")
+ (case-fold-search-asy case-fold-search))
+ (progn
+ (beginning-of-buffer)
+ (setq case-fold-search nil)
+ (while (re-search-forward Regexp (point-max) t)
+ (setq Strout (concat Strout (match-string 0) "\n\n")))
+ (setq case-fold-search case-fold-search-asy)
+ (if (string= Strout "") "No match.\n" Strout))))
+
+(defun asy-widget-open-file-at-pos (widget &optional event)
+ ""
+ (kill-buffer (current-buffer))
+ (find-file (widget-get widget :follow-link))
+ (goto-line (string-to-number (widget-get widget :value))))
+
+(defun asy-show-function-at-point()
+ "Show the Asymptote definitions of the command at point."
+ (interactive)
+ (save-excursion
+ (let ((cWord (current-word))
+ (cWindow (selected-window)))
+ (switch-to-buffer-other-window "*asy-help*")
+ (fundamental-mode)
+ (setq default-directory "/")
+ (if (> emacs-major-version 21)
+ (call-process-shell-command
+ (concat asy-command-location "asy -l --where") nil t nil)
+ (insert (shell-command-to-string "asy -l --where")))
+ (let ((rHelp (asy-grep (concat "^.*\\b" cWord "(\\(.\\)*?$")))
+ (tag)(file)(line))
+ (erase-buffer)
+ (insert rHelp)
+ (beginning-of-buffer)
+ (while (re-search-forward "\\(.*\\): \\([0-9]*\\)\\.\\([0-9]*\\)" (point-max) t)
+ (setq file (match-string 1)
+ line (match-string 2)
+ tag (file-name-nondirectory file))
+ (widget-create `(file-link
+ :tag ,tag
+ :follow-link ,file
+ :value ,line
+ :action asy-widget-open-file-at-pos
+ ))))
+ (beginning-of-buffer)
+ (while (re-search-forward "\\(.*: [0-9]*\\.[0-9]*\\)" (point-max) t)
+ (replace-match ""))
+ (asy-mode)
+ (use-local-map widget-keymap)
+ (widget-setup)
+ (goto-char (point-min))
+ (select-window cWindow))))
+
+(add-hook 'asy-mode-hook
+ (lambda ()
+ (c-set-style "gnu");
+ (c-set-offset (quote topmost-intro-cont) 0 nil)
+ (make-local-variable 'c-label-minimum-indentation)
+ (setq c-label-minimum-indentation 0)
+ (when (fboundp 'flyspell-mode) (flyspell-mode -1))
+ (turn-on-font-lock)
+ (column-number-mode t)
+ ))
+
+
+;;;###autoload (defun lasy-mode ())
+;;; ************************************
+;;; asy-mode mixed with LaTeX-mode: lasy
+;;; ************************************
+(if (locate-library "two-mode-mode")
+ (progn
+
+ (defvar lasy-fontify-asy-p nil
+ "Variable to communicate with `font-lock-unfontify-region'.
+Internal use, don't set in any fashion.")
+ (setq lasy-fontify-asy-p nil)
+
+ (eval-after-load "two-mode-mode"
+ '(progn
+ ;; Redefine `two-mode-mode-update-mode' to use regexp.
+ (defun two-mode-mode-update-mode ()
+ "Redefined in `asy-mode.el' to use regexp"
+ (when (and two-mode-bool two-mode-update)
+ (setq two-mode-update 0)
+ (let ((mode-list second-modes)
+ (flag 0))
+ (while mode-list
+ (let ((mode (car mode-list))
+ (lm -1)
+ (rm -1))
+ (save-excursion
+ (if (search-backward-regexp (cadr mode) nil t)
+ (setq lm (point))
+ (setq lm -1)))
+ (save-excursion
+ (if (search-backward-regexp (car (cddr mode)) nil t)
+ (setq rm (point))
+ (setq rm -1)))
+ (if (and (not (and (= lm -1) (= rm -1))) (>= lm rm))
+ (progn
+ (setq flag 1)
+ (setq mode-list '())
+ (two-mode-change-mode (car mode) (car (cdr (cddr mode)))))))
+ (setq mode-list (cdr mode-list)))
+ (if (= flag 0)
+ (two-mode-change-mode (car default-mode) (cadr default-mode))))))
+
+ (defun two-mode-change-mode (to-mode func)
+ "Redefined in asy-mode.
+Change the variable `lasy-fontify-asy-p' according to the value of func and
+the current mode."
+ (if (string= to-mode mode-name)
+ t
+ (progn
+ (setq lasy-fontify-asy-p (eq func 'asy-mode))
+ (funcall func)
+ (hack-local-variables)
+ (two-mode-mode-setup)
+ (if two-mode-switch-hook
+ (run-hooks 'two-mode-switch-hook))
+ (if (eq font-lock-mode t)
+ (font-lock-fontify-buffer))
+ (turn-on-font-lock-if-enabled))))
+ ))
+
+
+ (require 'two-mode-mode)
+
+ (defun lasy-mode ()
+ "Treat, in some cases, the current buffer as a literal Asymptote program."
+ (interactive)
+ (save-excursion
+ (let ((prefix
+ (progn
+ (goto-char (point-max))
+ (re-search-backward "^\\([^\n]+\\)Local Variables:"
+ (- (point-max) 3000) t)
+ (match-string 1)))
+ (pos-b (point)))
+ (when
+ (and prefix
+ (progn
+ (re-search-forward (regexp-quote
+ (concat prefix
+ "End:")) (point-max) t)
+ (re-search-backward (concat "\\(" prefix "mode: .*\\)") pos-b t))
+ )
+ (error (concat "lasy-mode can not work if a mode is specified as local file variable.
+You should remove the line " (int-to-string (line-number-at-pos)))))))
+ (set (make-local-variable 'asy-insinuate-latex-p) asy-insinuate-latex-p)
+ (make-local-variable 'lasy-fontify-asy-p)
+ (when (< emacs-major-version 22)
+ (make-local-variable 'font-lock-keywords-only))
+ (setq default-mode '("LaTeX" latex-mode)
+ second-modes '(("Asymptote"
+ "^\\\\begin{asy}.*$"
+ "^\\\\end{asy}"
+ asy-mode)))
+ (if two-mode-bool
+ (progn
+ (latex-mode)
+ (asy-insinuate-latex))
+ (progn
+ (two-mode-mode)
+ )))
+
+ (when (not running-xemacs-p)
+ (defadvice TeX-command-master (around asy-choose-compile act)
+ "Hack to circumvent the preempt of 'C-c C-c' by AucTeX within `lasy-mode'."
+ (if (string-match "asymptote" (downcase mode-name))
+ (asy-compile)
+ ad-do-it)))
+
+ (add-hook 'two-mode-switch-hook
+ (lambda ()
+ (if (eq major-mode 'latex-mode)
+ (progn ;; Switch to latex-mode
+ ;; Disable LaTeX-math-Mode within lasy-mode (because of incompatibility)
+ (when LaTeX-math-mode (LaTeX-math-mode -1))
+ (asy-insinuate-latex)
+ (when (< emacs-major-version 22)
+ (setq font-lock-keywords-only nil)))
+ (progn ;; Switch to asy-mode
+ (when (< emacs-major-version 22)
+ (setq font-lock-keywords-only t))
+ ))))
+ ;; (setq two-mode-switch-hook nil)
+
+ ;; Solve a problem restoring a TeX file via desktop.el previously in lasy-mode.
+ (if (boundp 'desktop-buffer-mode-handlers)
+ (progn
+ (defun asy-restore-desktop-buffer (desktop-b-f-name d-b-n d-b-m)
+ (find-file desktop-b-f-name))
+ (add-to-list 'desktop-buffer-mode-handlers
+ '(asy-mode . asy-restore-desktop-buffer))))
+
+ ;; Functions and 'advises' to restrict 'font-lock-unfontify-region'
+ ;; and 'font-lock-fontify-syntactically-region' within lasy-mode
+ ;; Special thanks to Olivier Ramaré for his help.
+ (when (and (fboundp 'font-lock-add-keywords) (> emacs-major-version 21))
+ (defun lasy-mode-at-pos (pos &optional interior strictly)
+ "If point at POS is in an asy environment return the list (start end)."
+ (save-excursion
+ (save-match-data
+ (goto-char pos)
+ (let* ((basy
+ (progn
+ (unless strictly (end-of-line))
+ (when (re-search-backward "^\\\\begin{asy}" (point-min) t)
+ (when interior (next-line))
+ (point))))
+ (easy
+ (and basy
+ (progn
+ (when (re-search-forward "^\\\\end{asy}" (point-max) t)
+ (when interior (previous-line)(beginning-of-line))
+ (point))))))
+ (and basy easy
+ (> pos (- basy (if interior 12 0)))
+ (< pos (+ easy (if interior 10 0)))
+ (list basy easy))))))
+
+ (defun lasy-region (start end &optional interior)
+ "If the region 'start to end' contains the beginning or
+the end of an asy environment return the list of points where
+the asy environment starts and ends."
+ (let* ((beg (min start end))
+ (lim (max start end)))
+ (or (lasy-mode-at-pos beg interior)
+ (save-match-data
+ (save-excursion
+ (goto-char beg)
+ (and (re-search-forward "^\\\\begin{asy}" lim t)
+ (lasy-mode-at-pos (point) interior)))))))
+
+ (defun lasy-tags (start end)
+ "Return associated list of points where the tags starts and ends
+restricted to the region (start end).
+\"b\" associated with (start-beginTag end-beginTag),
+\"e\" associated with (start-endTag end-endTag)."
+ (let*
+ ((beg (min start end))
+ (lim (max start end))
+ out)
+ (save-excursion
+ (goto-char beg)(beginning-of-line)
+ (while
+ (when (re-search-forward "^\\\\begin{asy}.*" lim t)
+ (push (list
+ (progn (beginning-of-line)(point))
+ (progn (end-of-line)(point))) out)))
+ (goto-char beg)(beginning-of-line)
+ (while
+ (when (re-search-forward "^\\\\end{asy}" lim t)
+ (push (list
+ (progn (beginning-of-line)(point))
+ (progn (end-of-line)(point))) out)))
+ out)))
+
+ (defun lasy-restrict-region (start end &optional interior)
+ "If the region 'start to end' contains the beginning or
+the end of an asy environment, returns the list of points wich
+restricts the region to the asy environment.
+Else, return (start end)."
+ (let*
+ ((beg (min start end))
+ (lim (max start end))
+ (be (if (lasy-mode-at-pos beg)
+ beg
+ (or (save-excursion
+ (goto-char beg)
+ (when (re-search-forward "^\\\\begin{asy}.*" lim t)
+ (unless interior (beginning-of-line))
+ (point)))
+ beg)))
+ (en (or (save-excursion
+ (goto-char be)
+ (when (re-search-forward "^\\\\end{asy}" lim t)
+ (when interior (beginning-of-line))
+ (point)))
+ lim)))
+ (list be en)))
+
+ (defun lasy-parse-region (start end)
+ "Return a list ((a (start1 end1)) (b (start2 end2)) [...]).
+where a, b, ... are nil or t; t means the region from 'startX' through 'endX' (are points)
+is in a asy environnement."
+ (let (regasy out rr brr err tags)
+ (save-excursion
+ (goto-char start)
+ (while (< (point) end)
+ (setq regasy (lasy-region (point) end))
+ (if regasy
+ (progn
+ (setq rr (lasy-mode-at-pos (point)))
+ (setq brr (and rr (nth 0 rr))
+ err (and rr (nth 1 rr)))
+ (if rr
+ (progn
+ (push (list t (list (max 1 (1- (point))) (min end err))) out)
+ (goto-char (min end err)))
+ (progn
+ (push (list nil (list (point) (nth 0 regasy))) out)
+ (goto-char (1+ (nth 0 regasy))))))
+ (progn
+ (push (list nil (list (min (1+ (point)) end) end)) out)
+ (goto-char end)))
+ ))
+ ;; Put start and end of tag in latex fontification.
+ (setq tags (lasy-tags start end))
+ (dolist (tag tags) (push (list nil tag) out))
+ (reverse out)))
+
+ (defadvice font-lock-unfontify-region
+ (around asy-font-lock-unfontify-region (beg end))
+ (if two-mode-bool
+ (let ((rstate (lasy-parse-region beg end))
+ curr reg asy-fontify latex-fontify)
+ (while (setq curr (pop rstate))
+ (setq reg (nth 1 curr))
+ (setq asy-fontify (and (nth 0 curr) lasy-fontify-asy-p)
+ latex-fontify (and (not (nth 0 curr))
+ (not lasy-fontify-asy-p)))
+ (when (or asy-fontify latex-fontify)
+ (setq beg (nth 0 reg)
+ end (nth 1 reg))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ ad-do-it
+ (widen))))))
+ ad-do-it))
+
+ (ad-activate 'font-lock-unfontify-region)
+ ;; (ad-deactivate 'font-lock-unfontify-region)
+
+ (defadvice font-lock-fontify-syntactically-region
+ (around asy-font-lock-fontify-syntactically-region
+ (start end &optional loudly))
+ (if (and two-mode-bool (eq major-mode 'asy-mode))
+ (let*((reg (lasy-restrict-region start end)))
+ (save-restriction
+ (setq start (nth 0 reg) end (nth 1 reg))
+ (narrow-to-region start end)
+ (condition-case nil
+ ad-do-it
+ (error nil))
+ (widen)
+ ))
+ ad-do-it))
+
+ (ad-activate 'font-lock-fontify-syntactically-region)
+ ;; (ad-deactivate 'font-lock-fontify-syntactically-region)
+
+ (defadvice font-lock-default-fontify-region
+ (around asy-font-lock-default-fontify-region
+ (beg end loudly))
+ (if two-mode-bool
+ (let ((rstate (lasy-parse-region beg end))
+ asy-fontify latex-fontify curr reg)
+ (while (setq curr (pop rstate))
+ (setq reg (nth 1 curr))
+ (setq asy-fontify (and (nth 0 curr) lasy-fontify-asy-p)
+ latex-fontify (and (not (nth 0 curr))
+ (not lasy-fontify-asy-p)))
+ (when (or asy-fontify latex-fontify)
+ (setq beg (nth 0 reg)
+ end (nth 1 reg))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (condition-case nil
+ ad-do-it
+ (error nil))
+ (widen)
+ )))))
+ ad-do-it))
+
+ (ad-activate 'font-lock-default-fontify-region)
+ ;; (ad-deactivate 'font-lock-default-fontify-region)
+
+ ))
+ (progn
+ (defvar two-mode-bool nil)
+ (defun lasy-mode ()
+ (message "You must install the package two-mode-mode.el."))))
+
+(setq asy-latex-menu-item
+ '(["Toggle lasy-mode" lasy-mode :active (featurep 'two-mode-mode)]
+ ["View asy picture near cursor" lasy-compile :active t]"--"
+ ("Compile OR View"
+ ["PS" lasy-view-ps :active t]
+ ["PDF (pdflatex)" lasy-view-pdf-via-pdflatex :active t]
+ ["PDF (ps2pdf)" lasy-view-pdf-via-ps2pdf :active t])
+ ("Compile AND View"
+ ["PS" asy-master-tex-view-ps-f :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex-f :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf-f :active t])"--"
+ ["Asymptote insinuates globally LaTeX" asy-insinuate-latex-globally :active (not asy-insinuate-latex-globally-p)]
+ ("Disable Asymptote insinuate Latex"
+ ["locally" asy-no-insinuate-locally :active t]
+ ["globally" asy-no-insinuate-globally :active t])
+ ("Debugger Buffer"
+ ["Visible" (setq asy-compilation-buffer 'visible) :style radio :selected (eq asy-compilation-buffer 'visible) :active t]
+ ["Available" (setq asy-compilation-buffer 'available) :style radio :selected (eq asy-compilation-buffer 'available) :active t]
+ ["None" (setq asy-compilation-buffer 'none) :style radio :selected (eq asy-compilation-buffer 'none) :active t]
+ ["Never" (setq asy-compilation-buffer 'never) :style radio :selected (eq asy-compilation-buffer 'never) :active t])
+ ))
+(if running-xemacs-p
+ (setq asy-latex-menu-item (nconc '("Asymptote") asy-latex-menu-item))
+ (setq asy-latex-menu-item (nconc '("Asymptote" :visible asy-insinuate-latex-p) asy-latex-menu-item)))
+
+(defun asy-insinuate-latex-maybe ()
+ "This function is added to `LaTeX-mode-hook' to define the environment 'asy'
+and, eventually, set its indentation.
+For internal use only."
+ (when (or asy-insinuate-latex-globally-p
+ (save-excursion
+ (beginning-of-buffer)
+ (save-match-data
+ (search-forward "\\begin{asy}" nil t))))
+ (asy-insinuate-latex))
+ (LaTeX-add-environments
+ '("asy" (lambda (env &rest ignore)
+ (unless asy-insinuate-latex-p (asy-insinuate-latex))
+ (LaTeX-insert-environment env)))))
+
+;; (add-hook 'after-init-hook
+;; (lambda ()
+(eval-after-load "latex"
+ '(progn
+ (add-hook 'LaTeX-mode-hook 'asy-insinuate-latex-maybe)
+ (setq lasy-mode-map (copy-keymap LaTeX-mode-map))
+ (setq LaTeX-mode-map-backup (copy-keymap LaTeX-mode-map))
+
+ (defadvice TeX-add-local-master (after asy-adjust-local-variable ())
+ "Delete the line that defines the mode in a file .tex because two-mode-mode reread
+the local variables after switching mode."
+ (when (string= (file-name-extension buffer-file-name) "tex")
+ (save-excursion
+ (goto-char (point-max))
+ (delete-matching-lines
+ "mode: latex"
+ (re-search-backward "^\\([^\n]+\\)Local Variables:"
+ (- (point-max) 3000) t)
+ (re-search-forward (regexp-quote
+ (concat (match-string 1)
+ "End:"))) nil))))
+ (ad-activate 'TeX-add-local-master)
+ ;; (ad-deactivate 'TeX-add-local-master)
+
+ (when lasy-extra-key
+ (define-key lasy-mode-map (kbd "<C-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-ps nil nil t)))
+ (define-key lasy-mode-map (kbd "<C-S-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-ps t nil t)))
+ (define-key lasy-mode-map (kbd "<M-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-pdflatex nil nil t)))
+ (define-key lasy-mode-map (kbd "<M-S-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-pdflatex t nil t)))
+ (define-key lasy-mode-map (kbd "<C-M-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-ps2pdf nil nil t)))
+ (define-key lasy-mode-map (kbd "<C-M-S-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-ps2pdf t nil t)))
+ (define-key lasy-mode-map (kbd "<f4>") 'asy-goto-error))
+
+ (easy-menu-define asy-latex-mode-menu lasy-mode-map "Asymptote insinuates LaTeX" asy-latex-menu-item)
+ ))
+;; ))
+
+(defvar asy-insinuate-latex-p nil
+ "Not nil when current buffer is insinuated by Asymptote.
+May be a local variable.
+For internal use.")
+
+(defvar asy-insinuate-latex-globally-p nil
+ "Not nil when all latex-mode buffers is insinuated by Asymptote.
+For internal use.")
+
+(defun asy-set-latex-asy-indentation ()
+ "Set the indentation of environnment 'asy' like the environnment 'verbatim' is."
+ ;; Regexp matching environments with indentation at col 0 for begin/end.
+ (set (make-local-variable 'LaTeX-verbatim-regexp)
+ (concat (default-value 'LaTeX-verbatim-regexp) "\\|asy"))
+ ;; Alist of environments with special indentation.
+ (make-local-variable 'LaTeX-indent-environment-list)
+ (add-to-list 'LaTeX-indent-environment-list
+ '("asy" current-indentation)))
+
+(defun asy-unset-latex-asy-indentation ()
+ "Unset the indentation of environnment 'asy' like the environnment 'verbatim' is."
+ (set (make-local-variable 'LaTeX-verbatim-regexp)
+ (default-value 'LaTeX-verbatim-regexp))
+ (set (make-local-variable 'LaTeX-indent-environment-list)
+ (default-value 'LaTeX-indent-environment-list)))
+
+(defun asy-no-insinuate-locally ()
+ (interactive)
+ (set (make-local-variable 'asy-insinuate-latex-p) nil)
+ (setq asy-insinuate-latex-globally-p nil)
+ (asy-unset-latex-asy-indentation)
+ (if running-xemacs-p
+ (easy-menu-remove-item nil nil "Asymptote")
+ (menu-bar-update-buffers))
+ (if (and (boundp 'two-mode-bool) two-mode-bool)
+ (lasy-mode))
+ (use-local-map LaTeX-mode-map-backup))
+
+
+(defun asy-no-insinuate-globally ()
+ (interactive)
+ (if running-xemacs-p
+ (easy-menu-remove-item nil nil "Asymptote")
+ (easy-menu-remove-item LaTeX-mode-map nil "Asymptote"))
+ (kill-local-variable asy-insinuate-latex-p)
+ (setq-default asy-insinuate-latex-p nil)
+ (setq asy-insinuate-latex-globally-p nil)
+ (if (not running-xemacs-p)
+ (menu-bar-update-buffers))
+ (setq LaTeX-mode-map (copy-keymap LaTeX-mode-map-backup))
+ ;;Disable lasy-mode in all latex-mode buffers.
+ (when (featurep 'two-mode-mode)
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (when (and (buffer-file-name) (string= (file-name-extension (buffer-file-name)) "tex"))
+ (asy-unset-latex-asy-indentation)
+ (latex-mode)
+ (setq asy-insinuate-latex-p nil))))
+ (buffer-list))))
+
+;;;###autoload
+(defun asy-insinuate-latex (&optional global)
+ "Add a menu bar in current 'latex-mode' buffer and activate asy keys bindings.
+If the optional parameter (only for internal use) 'global' is 't' then all the FUTURE 'latex-mode' buffers are insinuated.
+To insinuate all (current and future) 'latex-mode' buffers, use 'asy-insinuate-latex-globally' instead.
+You can automate this feature for all the 'latex-mode' buffers by inserting the five following lines in your .emacs initialization file:
+ (eval-after-load \"latex\"
+ '(progn
+ ;; Add here your personal features for 'latex-mode':
+ (asy-insinuate-latex t) ;; Asymptote insinuates globally Latex.
+ ))"
+ (interactive)
+ (if (and (not asy-insinuate-latex-globally-p) (or global (string= major-mode "latex-mode")))
+ (progn
+ (asy-set-latex-asy-indentation)
+ (if global
+ (progn
+ (setq asy-insinuate-latex-p t)
+ (setq asy-insinuate-latex-globally-p t)
+ (setq LaTeX-mode-map (copy-keymap lasy-mode-map))
+ (if running-xemacs-p
+ (add-hook 'LaTeX-mode-hook
+ (lambda ()
+ (if asy-insinuate-latex-globally-p
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map))))))
+ (progn
+ (use-local-map lasy-mode-map)
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map)
+ (set (make-local-variable 'asy-insinuate-latex-p) t)))
+ )))
+
+(defun asy-insinuate-latex-globally ()
+ "Insinuates all (current and future) 'latex-mode' buffers.
+See `asy-insinuate-latex'."
+ (interactive)
+ (asy-insinuate-latex t)
+ (if running-xemacs-p
+ (add-hook 'LaTeX-mode-hook
+ (lambda ()
+ (if asy-insinuate-latex-globally-p
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map)))))
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (when (and
+ (buffer-file-name)
+ (string= (file-name-extension (buffer-file-name)) "tex"))
+ (setq asy-insinuate-latex-p t)
+ (use-local-map LaTeX-mode-map)
+ (use-local-map lasy-mode-map)
+ (asy-set-latex-asy-indentation)
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map))))
+ (buffer-list)))
+
+(defun lasy-inline-p()
+ "Return nil if the option 'inline' is not used or if `lasy-compilation-inline-auto-detection' value is nil."
+ (if lasy-compilation-inline-auto-detection
+ (save-excursion
+ (re-search-backward "^[^%]* *\\\\usepackage\\[ *inline *\\]{ *asymptote *}" 0 t))
+ nil))
+
+(defvar lasy-run-tex nil)
+(defun lasy-asydef()
+ "Return the content between the tags \\begin{asydef} and \\end{asydef}."
+ (save-excursion
+ (if (re-search-backward "\\\\begin{asydef}" 0 t)
+ (buffer-substring
+ (progn (next-line)(beginning-of-line)(point))
+ (progn (re-search-forward "\\\\end{asydef}")
+ (previous-line)(end-of-line)
+ (point)))
+ "")))
+
+(defun lasy-compile-tex()
+ "Compile region between \\begin{asy}[text with backslash] and \\end{asy} through a reconstructed file .tex."
+ (interactive)
+ (setq lasy-run-tex t)
+ (save-excursion
+ (let* ((Filename (asy-get-temp-file-name t))
+ (FilenameTex (concat Filename ".tex"))
+ (asydef (lasy-asydef)))
+ (save-excursion
+ (beginning-of-buffer)
+ (write-region (point)
+ (progn
+ (re-search-forward "\\\\begin{document}.*\n")
+ (point)) FilenameTex)
+ (write-region (concat "\\begin{asydef}\n" asydef "\n\\end{asydef}\n") 0 FilenameTex t))
+ (re-search-backward "\\\\begin{asy}")
+ (write-region (point) (progn
+ (re-search-forward "\\\\end{asy}")
+ (point)) FilenameTex t)
+ (with-temp-file FilenameTex
+ (insert-file FilenameTex)
+ (end-of-buffer)
+ (insert "\n\\end{document}"))
+ (let ((default-directory asy-temp-dir))
+ (lasy-view-ps t Filename)))))
+
+(defun lasy-compile()
+ "Compile region between \\begin{asy} and \\end{asy}."
+ (interactive)
+ (if (or (lasy-inline-p) (progn ;; find \begin{asy}[any backslash]
+ (save-excursion
+ (re-search-forward "\\\\end{asy}" (point-max) t)
+ (re-search-backward "\\\\begin{asy}.*\\(\\[.*\\\\.*\\]\\)" 0 t))
+ (match-string 1)))
+ (progn
+ (lasy-compile-tex)) ;; a temporary TeX file must be reconstructed.
+ (progn
+ (setq lasy-run-tex nil)
+ (save-excursion
+ (let ((Filename (asy-get-temp-file-name))
+ (asydef (lasy-asydef)))
+ (write-region (match-string 0) 0 Filename)
+ (re-search-backward "\\\\begin{asy}")
+ (write-region (point) (progn
+ (re-search-forward "\\\\end{asy}")
+ (point)) Filename)
+ (with-temp-file Filename
+ (insert-file-contents Filename)
+ (beginning-of-buffer)
+ (if (re-search-forward "\\\\begin{asy}\\[\\(.*\\)\\]" (point-max) t)
+ (let ((sz (match-string 1)))
+ (replace-match "")
+ (insert (concat asydef "\nsize(" sz ");")))
+ (when (re-search-forward "\\\\begin{asy}" (point-max) t)
+ (replace-match "")
+ (insert asydef)))
+ (while (re-search-forward "\\\\end{asy}" (point-max) t)
+ (replace-match "")))
+ (let* ((asy-compile-command
+ (concat asy-command-location
+ asy-command
+ (if (eq asy-compilation-buffer 'never)
+ " " " -wait ")
+ (asy-protect-file-name Filename))))
+ (asy-internal-compile
+ asy-compile-command t
+ (not (eq asy-compilation-buffer 'never)))))))))
+
+(defun asy-set-master-tex ()
+ "Set the local variable 'asy-TeX-master-file.
+This variable is used by 'asy-master-tex-view-ps"
+ (interactive)
+ (set (make-local-variable 'asy-TeX-master-file)
+ (file-name-sans-extension
+ (file-relative-name
+ (expand-file-name
+ (read-file-name "TeX document: ")))))
+ (if (string= (concat default-directory asy-TeX-master-file)
+ (file-name-sans-extension buffer-file-name))
+ (prog1
+ (set (make-local-variable 'asy-TeX-master-file) nil)
+ (error "You should never give the same name to the TeX file and the Asymptote file"))
+ (save-excursion
+ (end-of-buffer)
+ (if (re-search-backward "asy-TeX-master-file\\(.\\)*$" 0 t)
+ (replace-match (concat "asy-TeX-master-file: \"" asy-TeX-master-file "\""))
+ (insert (concat "
+/// Local Variables:
+/// asy-TeX-master-file: \"" asy-TeX-master-file "\"
+/// End:")) t))))
+
+(defun asy-unset-master-tex ()
+ "Set the local variable 'asy-TeX-master-file to 'nil.
+This variable is used by 'asy-master-tex-view-ps"
+ (interactive)
+ (set (make-local-variable 'asy-TeX-master-file) nil)
+ (save-excursion
+ (end-of-buffer)
+ (if (re-search-backward "^.*asy-TeX-master-file:.*\n" 0 t)
+ (replace-match ""))))
+
+(defun asy-master-tex-error ()
+ "Asy-mode internal use..."
+ (if (y-or-n-p "You try to compile the TeX document that contains this picture.
+You must set the local variable asy-TeX-master-file.
+Do you want set this variable now ?")
+ (asy-set-master-tex) nil))
+
+(defun asy-master-tex-view (Func-view &optional Force fromtex)
+ "Compile the LaTeX document that contains the picture of the current Asymptote code with the function Func-view.
+Func-view can be one of 'lasy-view-ps, 'lasy-view-pdf-via-pdflatex, 'lasy-view-pdf-via-ps2pdf."
+ (interactive)
+ (if (or
+ (and (boundp two-mode-bool) two-mode-bool)
+ (string-match "latex" (downcase mode-name)))
+ (progn ;; Current mode is lasy-mode or latex-mode not asy-mode
+ (funcall Func-view Force nil fromtex))
+ (if asy-TeX-master-file
+ (if (string= asy-TeX-master-file
+ (file-name-sans-extension buffer-file-name))
+ (error "You should never give the same name to the TeX file and the Asymptote file")
+ (funcall Func-view Force asy-TeX-master-file fromtex))
+ (if (asy-master-tex-error)
+ (funcall Func-view Force asy-TeX-master-file fromtex)))))
+
+(defvar asy-last-compilation-code nil
+ "Code returned by the last compilation with `compile'.")
+
+(defvar asy-compilation-auto-close nil
+ "Variable to communicate with `asy-compilation-finish-function'.
+Do not set this variable in any fashion.")
+
+(defun asy-compilation-finish-function (buf msg)
+ "Function to automatically close the compilation buffer '*asy-compilation*'
+when no error or warning occurs."
+ (when (string-match "*asy-compilation*" (buffer-name buf))
+ (when (and asy-compilation-auto-close
+ (eq asy-compilation-buffer 'none))
+ (setq asy-compilation-auto-close nil)
+ (if (not (string-match "exited abnormally" msg))
+ (progn
+ (save-excursion
+ (set-buffer buf)
+ (beginning-of-buffer)
+ (if (not (search-forward-regexp "[wW]arning" nil t))
+ (when (not (eq asy-compilation-buffer 'visible))
+ ;;no errors/Warning, make the compilation window go away
+ (run-at-time 0.5 nil (lambda (buf_)
+ (delete-windows-on buf_)
+ (kill-buffer buf_)) buf)
+ (message (replace-regexp-in-string "\n" "" msg)))
+ (message "Compilation warnings..."))))))))
+
+(if running-xemacs-p
+ (setq compilation-finish-function 'asy-compilation-finish-function)
+ (add-to-list 'compilation-finish-functions
+ 'asy-compilation-finish-function))
+
+(defun asy-compilation-wait(&optional pass auto-close)
+ "Wait for process in *asy-compilation* exits.
+If pass is 't' don't wait.
+If auto-close is 't' close the window if the process exit with success."
+ (setq asy-compilation-auto-close auto-close)
+ (let* ((buff (get-buffer "*asy-compilation*"))
+ (comp-proc (get-buffer-process buff)))
+ (while (and comp-proc
+ (not (eq (process-status comp-proc) 'exit))
+ (not pass))
+ (setq comp-proc (get-buffer-process buff))
+ (sit-for 1)
+ (message "Waiting process...") ;; need message in Windows system
+ )
+ (message "") ;; Erase previous message.
+ (if (and (not pass) comp-proc)
+ (setq asy-last-compilation-code (process-exit-status comp-proc))
+ (setq asy-last-compilation-code 0))
+ (when (and (eq asy-compilation-buffer 'available)
+ (zerop asy-last-compilation-code))
+ (delete-windows-on buff))))
+
+
+(defun asy-internal-shell (command &optional pass)
+ "Execute 'command' in a inferior shell discarding output and
+redirecting stderr in the file given by the command `asy-log-filename'.
+`asy-internal-shell' waits for PROGRAM to terminate and returns a numeric exit status.
+The variable `asy-last-compilation-code' is always set to the exit status.
+The optional argument pass, for compatibility, is not used."
+ (let* ((log-file (asy-log-filename))
+ (discard (if pass 0 nil))
+ (status
+ (progn
+ (let ((view-inhibit-help-message t))(write-region "" 0 log-file nil))
+ (message "%s" command)
+ (call-process shell-file-name nil (list nil log-file) nil shell-command-switch command))))
+ (setq asy-last-compilation-code (if status status 0))
+ (if status status nil)))
+
+;; (defun asy-internal-shell (command &optional pass)
+;; "Execute 'command' in a inferior shell discarding output and
+;; redirecting stderr in the file given by the command `asy-log-filename'.
+;; pass non-nil means `asy-internal-shell' returns immediately with nil value.
+;; Otherwise it waits for PROGRAM to terminate and returns a numeric exit status.
+;; The variable `asy-last-compilation-code' is always set to the exit status or 0 if the
+;; process returns immediately."
+;; (let* ((log-file (asy-log-filename))
+;; (discard (if pass 0 nil))
+;; (status
+;; (progn
+;; (let ((inhibit-redisplay t))(write-region "" 0 log-file nil))
+;; (message "%s" command)
+;; (call-process shell-file-name nil (list discard log-file) nil shell-command-switch command))))
+;; (setq asy-last-compilation-code (if status status 0))
+;; (when pass (sit-for 1))
+;; (if status status nil)))
+
+(defun asy-internal-compile (command &optional pass auto-close stderr)
+ "Execute command.
+pass non-nil means don't wait the end of the process.
+auto-close non-nil means automatically close the compilation buffer.
+stderr non-nil means redirect the standard output error to the file
+returned by `asy-log-filename'.
+In this case command is running in an inferior shell without any output and
+the parameter auto-close is not used (see `asy-internal-shell')."
+ (setq asy-last-compilation-code -1)
+ (let* ((compilation-buffer-name "*asy-compilation*")
+ (compilation-buffer-name-function (lambda (mj) compilation-buffer-name)))
+ (if (or stderr (eq asy-compilation-buffer 'never))
+ (progn
+ (asy-internal-shell command pass)
+ (asy-error-message t))
+ (progn
+ (let ((comp-proc (get-buffer-process compilation-buffer-name)))
+ (if comp-proc
+ (condition-case ()
+ (progn
+ (interrupt-process comp-proc)
+ (sit-for 1)
+ (delete-process comp-proc)
+ (when (and asy-compilation-auto-close
+ (eq asy-compilation-buffer 'none)
+ (not (eq asy-compilation-buffer 'visible)))
+ (sit-for 0.6)))
+ (error ""))
+ ))
+ (let ((view-inhibit-help-message t))
+ (write-region "" 0 (asy-log-filename) nil))
+ (compile command))
+ (asy-compilation-wait pass auto-close))))
+
+(defun asy-open-file(Filename)
+ "Open the ps or pdf file Filename.
+In unix-like system the variables `ps-view-command' and `pdf-view-command' are used.
+In Windows the associated system file type is used instead."
+ (let ((command
+ (if running-unix-p
+ (let ((ext (file-name-extension Filename)))
+ (cond
+ ((string= ext "ps") ps-view-command)
+ ((string= ext "pdf") pdf-view-command)
+ (t (error "Extension Not Supported."))))
+ (asy-protect-file-name (file-name-nondirectory Filename))))
+ )
+ (if running-unix-p
+ (start-process "" nil command Filename)
+ (call-process-shell-command command nil 0))))
+
+(defun lasy-TeX-master-file ()
+ "Return the file name of the master file for the current document.
+The returned string contain the directory but does not contain the extension of the file."
+ (expand-file-name
+ (concat (TeX-master-directory) (TeX-master-file nil t))))
+
+(defun lasy-must-compile-p (TeX-Master-File out-file &optional Force)
+ ""
+ (or Force
+ (file-newer-than-file-p
+ (concat TeX-Master-File ".tex") out-file)
+ (and (stringp (TeX-master-file)) ;; current buffer is not a mater tex file
+ (file-newer-than-file-p buffer-file-name out-file))))
+
+(defun lasy-view-ps (&optional Force Filename fromtex)
+ "Compile a LaTeX document embedding Asymptote code with latex->asy->latex->dvips and/or view the PostScript output.
+If optional argument Force is t then force compilation."
+ (interactive)
+ (setq lasy-run-tex t)
+ (setq lasy-compile-tex fromtex)
+ (if (buffer-modified-p) (save-buffer))
+ (when (eq asy-compilation-buffer 'never) (write-region "" 0 (asy-log-filename) nil))
+ (let*
+ ((b-b-n (if Filename Filename (lasy-TeX-master-file)))
+ (b-b-n-tex (asy-protect-file-name (concat b-b-n ".tex")))
+ (b-b-n-ps (asy-protect-file-name (concat b-b-n ".ps")))
+ (b-b-n-dvi (asy-protect-file-name (concat b-b-n ".dvi")))
+ (b-b-n-asy (asy-protect-file-name (concat b-b-n ".asy")))
+ (stderr (eq asy-compilation-buffer 'never)))
+ (if (lasy-must-compile-p b-b-n (concat b-b-n ".ps") Force)
+ (progn
+ (let ((default-directory (file-name-directory b-b-n)))
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))
+ (when (and (zerop asy-last-compilation-code) (file-readable-p (concat b-b-n ".asy")))
+ (asy-internal-compile (concat asy-command-location lasy-command " " b-b-n-asy) nil nil stderr)
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))))
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-dvips-command " " b-b-n-dvi " -o " b-b-n-ps) nil t)
+ (when (zerop asy-last-compilation-code)
+ (asy-open-file (concat b-b-n ".ps"))))))
+ (asy-open-file (concat b-b-n ".ps")))))
+
+(defun lasy-view-pdf-via-pdflatex (&optional Force Filename fromtex)
+ "Compile a LaTeX document embedding Asymptote code with pdflatex->asy->pdflatex and/or view the PDF output.
+If optional argument Force is t then force compilation."
+ (interactive)
+ (setq lasy-run-tex t)
+ (setq lasy-compile-tex fromtex)
+ (if (buffer-modified-p) (save-buffer))
+ (when (eq asy-compilation-buffer 'never) (write-region "" 0 (asy-log-filename) nil))
+ (let*
+ ((b-b-n (if Filename Filename (lasy-TeX-master-file)))
+ (b-b-n-tex (asy-protect-file-name (concat b-b-n ".tex")))
+ (b-b-n-pdf (asy-protect-file-name (concat b-b-n ".pdf")))
+ (b-b-n-asy (asy-protect-file-name (concat b-b-n ".asy")))
+ ;; (stderr (or (eq asy-compilation-buffer 'never) lasy-compile-tex)))
+ (stderr (eq asy-compilation-buffer 'never)))
+ (if (lasy-must-compile-p b-b-n (concat b-b-n ".pdf") Force)
+ (progn
+ (let ((default-directory (file-name-directory b-b-n)))
+ (asy-internal-compile (concat lasy-pdflatex-command " " b-b-n-tex))
+ (when (and (zerop asy-last-compilation-code) (file-readable-p (concat b-b-n ".asy")))
+ (asy-internal-compile (concat asy-command-location lasy-command " " b-b-n-asy) nil nil stderr)
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-pdflatex-command " " b-b-n-tex) t)))
+ (when (zerop asy-last-compilation-code)
+ (asy-open-file (concat b-b-n ".pdf")))))
+ (asy-open-file (concat b-b-n ".pdf")))))
+
+(defun lasy-view-pdf-via-ps2pdf (&optional Force Filename fromtex)
+ "Compile a LaTeX document embedding Asymptote code with latex->asy->latex->dvips->ps2pdf14 and/or view the PDF output.
+If optional argument Force is t then force compilation."
+ (interactive)
+ (setq lasy-run-tex t)
+ (setq lasy-compile-tex fromtex)
+ (if (buffer-modified-p) (save-buffer))
+ (when (eq asy-compilation-buffer 'never) (write-region "" 0 (asy-log-filename) nil))
+ (let*
+ ((b-b-n (if Filename Filename (lasy-TeX-master-file)))
+ (b-b-n-tex (asy-protect-file-name (concat b-b-n ".tex")))
+ (b-b-n-ps (asy-protect-file-name (concat b-b-n ".ps")))
+ (b-b-n-dvi (asy-protect-file-name (concat b-b-n ".dvi")))
+ (b-b-n-pdf (asy-protect-file-name (concat b-b-n ".pdf")))
+ (b-b-n-asy (asy-protect-file-name (concat b-b-n ".asy")))
+ ;; (stderr (or (eq asy-compilation-buffer 'never) lasy-compile-tex)))
+ (stderr (eq asy-compilation-buffer 'never)))
+ (if (lasy-must-compile-p b-b-n (concat b-b-n ".pdf") Force)
+ (progn
+ (let ((default-directory (file-name-directory b-b-n)))
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))
+ (when (and (zerop asy-last-compilation-code) (file-readable-p (concat b-b-n ".asy")))
+ (asy-internal-compile (concat asy-command-location lasy-command " " b-b-n-asy) nil nil stderr)
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))))
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-dvips-pre-pdf-command " " b-b-n-dvi " -o " b-b-n-ps))
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-ps2pdf-command " " b-b-n-ps " " b-b-n-pdf) t)
+ (when (zerop asy-last-compilation-code)
+ (asy-open-file (concat b-b-n ".pdf")))))))
+ (asy-open-file (concat b-b-n ".pdf")))))
+
+;; Goto error of last compilation
+(define-key asy-mode-map (kbd "<f4>") 'asy-goto-error)
+
+;; Save and compile the file with option -V
+(define-key asy-mode-map (kbd "C-c C-c") 'asy-compile)
+
+;; Show the definitions of command at point
+(define-key asy-mode-map (kbd "C-c ?") 'asy-show-function-at-point)
+
+;; new line and indent
+(define-key asy-mode-map (kbd "RET") 'newline-and-indent)
+
+(defun asy-master-tex-view-ps ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-ps nil t))
+(define-key asy-mode-map (kbd "<C-return>") 'asy-master-tex-view-ps)
+
+(defun asy-master-tex-view-ps-f ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-ps t t))
+(define-key asy-mode-map (kbd "<C-S-return>") 'asy-master-tex-view-ps-f)
+
+(defun asy-master-tex-view-pdflatex ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-pdflatex nil t))
+(define-key asy-mode-map (kbd "<M-return>") 'asy-master-tex-view-pdflatex)
+
+(defun asy-master-tex-view-pdflatex-f ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-pdflatex t t))
+(define-key asy-mode-map (kbd "<M-S-return>") 'asy-master-tex-view-pdflatex-f)
+
+(defun asy-master-tex-view-ps2pdf ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-ps2pdf nil t))
+(define-key asy-mode-map (kbd "<C-M-return>") 'asy-master-tex-view-ps2pdf)
+
+(defun asy-master-tex-view-ps2pdf-f ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-ps2pdf t t))
+(define-key asy-mode-map (kbd "<C-M-S-return>") 'asy-master-tex-view-ps2pdf-f)
+
+(provide `asy-mode)
+;;; asy-mode.el ends here
diff --git a/graphics/asymptote/base/asy.vim b/graphics/asymptote/base/asy.vim
new file mode 100644
index 0000000000..4cb897f131
--- /dev/null
+++ b/graphics/asymptote/base/asy.vim
@@ -0,0 +1,202 @@
+" Vim syntax file
+" Language: Asymptote
+" Maintainer: Andy Hammerlindl
+" Last Change: 2005 Aug 23
+
+" Hacked together from Bram Moolenaar's C syntax file, and Claudio Fleiner's
+" Java syntax file.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+" A bunch of useful C keywords
+syn keyword asyStatement break return continue unravel
+syn keyword asyConditional if else
+syn keyword asyRepeat while for do
+syn keyword asyExternal access from import include
+syn keyword asyOperator new operator
+
+syn keyword asyTodo contained TODO FIXME XXX
+
+" asyCommentGroup allows adding matches for special things in comments
+syn cluster asyCommentGroup contains=asyTodo
+
+" String and Character constants
+" Highlight special characters (those proceding a double backslash) differently
+syn match asySpecial display contained "\\\\."
+" Highlight line continuation slashes
+syn match asySpecial display contained "\\$"
+syn region asyString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=asySpecial
+ " asyCppString: same as asyString, but ends at end of line
+if 0
+syn region asyCppString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=asySpecial
+endif
+
+"when wanted, highlight trailing white space
+if exists("asy_space_errors")
+ if !exists("asy_no_trail_space_error")
+ syn match asySpaceError display excludenl "\s\+$"
+ endif
+ if !exists("asy_no_tab_space_error")
+ syn match asySpaceError display " \+\t"me=e-1
+ endif
+endif
+
+"catch errors caused by wrong parenthesis and brackets
+syn cluster asyParenGroup contains=asyParenError,asyIncluded,asySpecial,asyCommentSkip,asyCommentString,asyComment2String,@asyCommentGroup,asyCommentStartError,asyUserCont,asyUserLabel,asyBitField,asyCommentSkip,asyOctalZero,asyCppOut,asyCppOut2,asyCppSkip,asyFormat,asyNumber,asyFloat,asyOctal,asyOctalError,asyNumbersCom
+if exists("asy_no_bracket_error")
+ syn region asyParen transparent start='(' end=')' contains=ALLBUT,@asyParenGroup,asyCppParen,asyCppString
+ " asyCppParen: same as asyParen but ends at end-of-line; used in asyDefine
+ syn region asyCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@asyParenGroup,asyParen,asyString
+ syn match asyParenError display ")"
+ syn match asyErrInParen display contained "[{}]"
+else
+ syn region asyParen transparent start='(' end=')' contains=ALLBUT,@asyParenGroup,asyCppParen,asyErrInBracket,asyCppBracket,asyCppString
+ " asyCppParen: same as asyParen but ends at end-of-line; used in asyDefine
+ syn region asyCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@asyParenGroup,asyErrInBracket,asyParen,asyBracket,asyString
+if 0
+ syn match asyParenError display "[\])]"
+ syn match asyErrInParen display contained "[\]]"
+endif
+ syn region asyBracket transparent start='\[' end=']' contains=ALLBUT,@asyParenGroup,asyErrInParen,asyCppParen,asyCppBracket,asyCppString
+ " asyCppBracket: same as asyParen but ends at end-of-line; used in asyDefine
+ syn region asyCppBracket transparent start='\[' skip='\\$' excludenl end=']' end='$' contained contains=ALLBUT,@asyParenGroup,asyErrInParen,asyParen,asyBracket,asyString
+ syn match asyErrInBracket display contained "[);]"
+endif
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match asyNumbers display transparent "\<\d\|\.\d" contains=asyNumber,asyFloat
+syn match asyNumber display contained "\d\+"
+"floating point number, with dot, optional exponent
+syn match asyFloat display contained "\d\+\.\d*\(e[-+]\=\d\+\)\="
+"floating point number, starting with a dot, optional exponent
+syn match asyFloat display contained "\.\d\+\(e[-+]\=\d\+\)\="
+"floating point number, without dot, with exponent
+syn match asyFloat display contained "\d\+e[-+]\=\d\+"
+syn case match
+
+if exists("asy_comment_strings")
+ " A comment can contain asyString, asyCharacter and asyNumber.
+ " But a "*/" inside a asyString in a asyComment DOES end the comment! So we
+ " need to use a special type of asyString: asyCommentString, which also ends on
+ " "*/", and sees a "*" at the start of the line as comment again.
+ " Unfortunately this doesn't very well work for // type of comments :-(
+ syntax match asyCommentSkip contained "^\s*\*\($\|\s\+\)"
+ syntax region asyCommentString contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=asySpecial,asyCommentSkip
+ syntax region asyComment2String contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=asySpecial
+ syntax region asyCommentL start="//" skip="\\$" end="$" keepend contains=@asyCommentGroup,asyComment2String,asyCharacter,asyNumbersCom,asySpaceError
+ syntax region asyComment matchgroup=asyCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@asyCommentGroup,asyCommentStartError,asyCommentString,asyCharacter,asyNumbersCom,asySpaceError
+else
+ syn region asyCommentL start="//" skip="\\$" end="$" keepend contains=@asyCommentGroup,asySpaceError
+ syn region asyComment matchgroup=asyCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@asyCommentGroup,asyCommentStartError,asySpaceError
+endif
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match asyCommentError display "\*/"
+syntax match asyCommentStartError display "/\*"me=e-1 contained
+
+syn keyword asyType void bool int real string
+syn keyword asyType pair triple transform guide path pen frame
+syn keyword asyType picture
+
+syn keyword asyStructure struct typedef
+syn keyword asyStorageClass static public readable private explicit
+
+syn keyword asyPathSpec and cycle controls tension atleast curl
+
+syn keyword asyConstant true false
+syn keyword asyConstant null nullframe nullpath
+
+if exists("asy_syn_plain")
+ syn keyword asyConstant currentpicture currentpen currentprojection
+ syn keyword asyConstant inch inches cm mm bp pt up down right left
+ syn keyword asyConstant E NE N NW W SW S SE
+ syn keyword asyConstant ENE NNE NNW WNW WSW SSW SSE ESE
+ syn keyword asyConstant I pi twopi
+ syn keyword asyConstant solid dotted dashed dashdotted
+ syn keyword asyConstant longdashed longdashdotted
+ syn keyword asyConstant squarecap roundcap extendcap
+ syn keyword asyConstant miterjoin roundjoin beveljoin
+ syn keyword asyConstant zerowinding evenodd
+ syn keyword asyConstant invisible black gray grey white
+ syn keyword asyConstant lightgray lightgrey
+ syn keyword asyConstant red green blue
+ syn keyword asyConstant cmyk Cyan Magenta Yellow Black
+ syn keyword asyConstant yellow magenta cyan
+ syn keyword asyConstant brown darkgreen darkblue
+ syn keyword asyConstant orange purple royalblue olive
+ syn keyword asyConstant chartreuse fuchsia salmon lightblue springgreen
+ syn keyword asyConstant pink
+endif
+
+syn sync ccomment asyComment minlines=15
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_asy_syn_inits")
+ if version < 508
+ let did_asy_syn_inits = 1
+ command -nargs=+ HiLink hi link <args>
+ else
+ command -nargs=+ HiLink hi def link <args>
+ endif
+
+ HiLink asyFormat asySpecial
+ HiLink asyCppString asyString
+ HiLink asyCommentL asyComment
+ HiLink asyCommentStart asyComment
+ HiLink asyLabel Label
+ HiLink asyUserLabel Label
+ HiLink asyConditional Conditional
+ HiLink asyRepeat Repeat
+ HiLink asyCharacter Character
+ HiLink asySpecialCharacter asySpecial
+ HiLink asyNumber Number
+ HiLink asyOctal Number
+ HiLink asyOctalZero PreProc " link this to Error if you want
+ HiLink asyFloat Float
+ HiLink asyOctalError asyError
+ HiLink asyParenError asyError
+ HiLink asyErrInParen asyError
+ HiLink asyErrInBracket asyError
+ HiLink asyCommentError asyError
+ HiLink asyCommentStartError asyError
+ HiLink asySpaceError asyError
+ HiLink asySpecialError asyError
+ HiLink asyOperator Operator
+ HiLink asyStructure Structure
+ HiLink asyStorageClass StorageClass
+ HiLink asyExternal Include
+ HiLink asyPreProc PreProc
+ HiLink asyDefine Macro
+ HiLink asyIncluded asyString
+ HiLink asyError Error
+ HiLink asyStatement Statement
+ HiLink asyPreCondit PreCondit
+ HiLink asyType Type
+ HiLink asyConstant Constant
+ HiLink asyCommentString asyString
+ HiLink asyComment2String asyString
+ HiLink asyCommentSkip asyComment
+ HiLink asyString String
+ HiLink asyComment Comment
+ HiLink asySpecial SpecialChar
+ HiLink asyTodo Todo
+ HiLink asyCppSkip asyCppOut
+ HiLink asyCppOut2 asyCppOut
+ HiLink asyCppOut Comment
+ HiLink asyPathSpec Statement
+
+
+ delcommand HiLink
+endif
+
+let b:current_syntax = "c"
+
+" vim: ts=8
diff --git a/graphics/asymptote/base/asy_filetype.vim b/graphics/asymptote/base/asy_filetype.vim
new file mode 100644
index 0000000000..3b614edf12
--- /dev/null
+++ b/graphics/asymptote/base/asy_filetype.vim
@@ -0,0 +1,3 @@
+" Vim filetype detection file
+" Language: Asymptote
+au BufNewFile,BufRead *.asy setfiletype asy
diff --git a/graphics/asymptote/base/asymptote.py b/graphics/asymptote/base/asymptote.py
new file mode 100755
index 0000000000..19b72c5082
--- /dev/null
+++ b/graphics/asymptote/base/asymptote.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+
+# Python module to feed Asymptote with commands
+# (modified from gnuplot.py)
+from subprocess import *
+class asy:
+ def __init__(self):
+ self.session = Popen(['asy','-quiet','-inpipe=0','-outpipe=2'],stdin=PIPE)
+ self.help()
+ def send(self, cmd):
+ self.session.stdin.write(bytes(cmd+'\n','utf-8'))
+ self.session.stdin.flush()
+ def size(self, size):
+ self.send("size(%d);" % size)
+ def draw(self, str):
+ self.send("draw(%s);" % str)
+ def fill(self, str):
+ self.send("fill(%s);" % str)
+ def clip(self, str):
+ self.send("clip(%s);" % str)
+ def label(self, str):
+ self.send("label(%s);" % str)
+ def shipout(self, str):
+ self.send("shipout(\"%s\");" % str)
+ def erase(self):
+ self.send("erase();")
+ def help(self):
+ print("Asymptote session is open. Available methods are:")
+ print(" help(), size(int), draw(str), fill(str), clip(str), label(str), shipout(str), send(str), erase()")
+ def __del__(self):
+ print("closing Asymptote session...")
+ self.send('quit');
+ self.session.stdin.close();
+ self.session.wait()
+
+
+
+
+
+if __name__=="__main__":
+ g = asy()
+ g.size(200)
+ g.draw("unitcircle")
+ g.send("draw(unitsquare)")
+ g.fill("unitsquare, blue")
+ g.clip("unitcircle")
+ g.label("\"$O$\", (0,0), SW")
+ raw_input("press ENTER to continue")
+ g.erase()
+ del g
diff --git a/graphics/asymptote/base/babel.asy b/graphics/asymptote/base/babel.asy
new file mode 100644
index 0000000000..e93dec2a5c
--- /dev/null
+++ b/graphics/asymptote/base/babel.asy
@@ -0,0 +1,4 @@
+void babel(string s)
+{
+ usepackage("babel",s);
+}
diff --git a/graphics/asymptote/base/bezulate.asy b/graphics/asymptote/base/bezulate.asy
new file mode 100644
index 0000000000..38d35718d4
--- /dev/null
+++ b/graphics/asymptote/base/bezulate.asy
@@ -0,0 +1,310 @@
+// Bezier triangulation routines written by Orest Shardt, 2008.
+
+private real fuzz=sqrtEpsilon;
+real duplicateFuzz=1e-3; // Work around font errors.
+real maxrefinements=10;
+
+private real[][] intersections(pair a, pair b, path p)
+{
+ pair delta=fuzz*unit(b-a);
+ return intersections(a-delta--b+delta,p,fuzz);
+}
+
+int countIntersections(path[] p, pair start, pair end)
+{
+ int intersects=0;
+ for(path q : p)
+ intersects += intersections(start,end,q).length;
+ return intersects;
+}
+
+path[][] containmentTree(path[] paths)
+{
+ path[][] result;
+ for(path g : paths) {
+ // check if current curve contains or is contained in a group of curves
+ int j;
+ for(j=0; j < result.length; ++j) {
+ path[] resultj=result[j];
+ int test=inside(g,resultj[0],zerowinding);
+ if(test == 1) {
+ // current curve contains group's toplevel curve;
+ // replace toplevel curve with current curve
+ resultj.insert(0,g);
+ // check to see if any other groups are contained within this curve
+ for(int k=j+1; k < result.length;) {
+ if(inside(g,result[k][0],zerowinding) == 1) {
+ resultj.append(result[k]);
+ result.delete(k);
+ } else ++k;
+ }
+ break;
+ } else if(test == -1) {
+ // current curve contained within group's toplevel curve
+ resultj.push(g);
+ break;
+ }
+ }
+ // create a new group if this curve does not belong to another group
+ if(j == result.length)
+ result.push(new path[] {g});
+ }
+ return result;
+}
+
+bool isDuplicate(pair a, pair b, real relSize)
+{
+ return abs(a-b) <= duplicateFuzz*relSize;
+}
+
+path removeDuplicates(path p)
+{
+ real relSize = abs(max(p)-min(p));
+ bool cyclic=cyclic(p);
+ for(int i=0; i < length(p); ++i) {
+ if(isDuplicate(point(p,i),point(p,i+1),relSize)) {
+ p=subpath(p,0,i)&subpath(p,i+1,length(p));
+ --i;
+ }
+ }
+ return cyclic ? p&cycle : p;
+}
+
+path section(path p, real t1, real t2, bool loop=false)
+{
+ if(t2 < t1 || loop && t1 == t2)
+ t2 += length(p);
+ return subpath(p,t1,t2);
+}
+
+path uncycle(path p, real t)
+{
+ return subpath(p,t,t+length(p));
+}
+
+// returns outer paths
+void connect(path[] paths, path[] result, path[] patch)
+{
+ path[][] tree=containmentTree(paths);
+ for(path[] group : tree) {
+ path outer = group[0];
+ group.delete(0);
+ path[][] innerTree = containmentTree(group);
+ path[] remainingCurves;
+ path[] inners;
+ for(path[] innerGroup:innerTree)
+ {
+ inners.push(innerGroup[0]);
+ if(innerGroup.length>1)
+ remainingCurves.append(innerGroup[1:]);
+ }
+ connect(remainingCurves,result,patch);
+ real d=2*abs(max(outer)-min(outer));
+ while(inners.length > 0) {
+ int curveIndex = 0;
+ //pair direction=I*dir(inners[curveIndex],0,1); // Use outgoing direction
+ //if(direction == 0) // Try a random direction
+ // direction=expi(2pi*unitrand());
+ //pair start=point(inners[curveIndex],0);
+
+ // find shortest distance between a node on the inner curve and a node
+ // on the outer curve
+
+ real mindist = d;
+ int inner_i = 0;
+ int outer_i = 0;
+ for(int ni = 0; ni < length(inners[curveIndex]); ++ni)
+ {
+ for(int no = 0; no < length(outer); ++no)
+ {
+ real dist = abs(point(inners[curveIndex],ni)-point(outer,no));
+ if(dist < mindist)
+ {
+ inner_i = ni;
+ outer_i = no;
+ mindist = dist;
+ }
+ }
+ }
+ pair start=point(inners[curveIndex],inner_i);
+ pair end = point(outer,outer_i);
+
+ // find first intersection of line segment with outer curve
+ //real[][] ints=intersections(start,start+d*direction,outer);
+ real[][] ints=intersections(start,end,outer);
+ assert(ints.length != 0);
+ real endtime=ints[0][1]; // endtime is time on outer
+ end = point(outer,endtime);
+ // find first intersection of end--start with any inner curve
+ real starttime=inner_i; // starttime is time on inners[curveIndex]
+ real earliestTime=1;
+ for(int j=0; j < inners.length; ++j) {
+ real[][] ints=intersections(end,start,inners[j]);
+
+ if(ints.length > 0 && ints[0][0] < earliestTime) {
+ earliestTime=ints[0][0]; // time on end--start
+ starttime=ints[0][1]; // time on inner curve
+ curveIndex=j;
+ }
+ }
+ start=point(inners[curveIndex],starttime);
+
+
+ bool found_forward = false;
+ real timeoffset_forward = 2;
+ path portion_forward;
+ path[] allCurves = {outer};
+ allCurves.append(inners);
+
+ while(!found_forward && timeoffset_forward > fuzz) {
+ timeoffset_forward /= 2;
+ if(countIntersections(allCurves,start,
+ point(outer,endtime+timeoffset_forward)) == 2)
+ {
+ portion_forward = subpath(outer,endtime,endtime+timeoffset_forward)--start--cycle;
+
+ found_forward=true;
+ // check if an inner curve is inside the portion
+ for(int k = 0; found_forward && k < inners.length; ++k)
+ {
+ if(k!=curveIndex &&
+ inside(portion_forward,point(inners[k],0),zerowinding))
+ found_forward = false;
+ }
+ }
+ }
+
+ bool found_backward = false;
+ real timeoffset_backward = -2;
+ path portion_backward;
+ while(!found_backward && timeoffset_backward < -fuzz) {
+ timeoffset_backward /= 2;
+ if(countIntersections(allCurves,start,
+ point(outer,endtime+timeoffset_backward))==2)
+ {
+ portion_backward = subpath(outer,endtime+timeoffset_backward,endtime)--start--cycle;
+ found_backward = true;
+ // check if an inner curve is inside the portion
+ for(int k = 0; found_backward && k < inners.length; ++k)
+ {
+ if(k!=curveIndex &&
+ inside(portion_backward,point(inners[k],0),zerowinding))
+ found_backward = false;
+ }
+ }
+ }
+ assert(found_forward || found_backward);
+ real timeoffset;
+ path portion;
+ if(found_forward && !found_backward)
+ {
+ timeoffset = timeoffset_forward;
+ portion = portion_forward;
+ }
+ else if(found_backward && !found_forward)
+ {
+ timeoffset = timeoffset_backward;
+ portion = portion_backward;
+ }
+ else // assert handles case of neither found
+ {
+ if(timeoffset_forward > -timeoffset_backward)
+ {
+ timeoffset = timeoffset_forward;
+ portion = portion_forward;
+ }
+ else
+ {
+ timeoffset = timeoffset_backward;
+ portion = portion_backward;
+ }
+ }
+
+ endtime=min(endtime,endtime+timeoffset);
+ // or go from timeoffset+timeoffset_backward to timeoffset+timeoffset_forward?
+ timeoffset=abs(timeoffset);
+
+ // depends on the curves having opposite orientations
+ path remainder=section(outer,endtime+timeoffset,endtime)
+ --uncycle(inners[curveIndex],
+ starttime)--cycle;
+ inners.delete(curveIndex);
+ outer = remainder;
+ patch.append(portion);
+ }
+ result.append(outer);
+ }
+}
+
+bool checkSegment(path g, pair p, pair q)
+{
+ pair mid=0.5*(p+q);
+ return intersections(p,q,g).length == 2 &&
+ inside(g,mid,zerowinding) && intersections(g,mid).length == 0;
+}
+
+path subdivide(path p)
+{
+ path q;
+ int l=length(p);
+ for(int i=0; i < l; ++i)
+ q=q&(straight(p,i) ? subpath(p,i,i+1) :
+ subpath(p,i,i+0.5)&subpath(p,i+0.5,i+1));
+ return cyclic(p) ? q&cycle : q;
+}
+
+path[] bezulate(path[] p)
+{
+ if(p.length == 1 && length(p[0]) <= 4) return p;
+ path[] patch;
+ path[] result;
+ connect(p,result,patch);
+ for(int i=0; i < result.length; ++i) {
+ path p=result[i];
+ int refinements=0;
+ if(size(p) <= 1) return p;
+ if(!cyclic(p))
+ abort("path must be cyclic and nonselfintersecting.");
+ p=removeDuplicates(p);
+ if(length(p) > 4) {
+ static real SIZE_STEPS=10;
+ static real factor=1.05/SIZE_STEPS;
+ for(int k=1; k <= SIZE_STEPS; ++k) {
+ real L=factor*k*abs(max(p)-min(p));
+ for(int i=0; length(p) > 4 && i < length(p); ++i) {
+ bool found=false;
+ pair start=point(p,i);
+ //look for quadrilaterals and triangles with one line, 4 | 3 curves
+ for(int desiredSides=4; !found && desiredSides >= 3;
+ --desiredSides) {
+ if(desiredSides == 3 && length(p) <= 3)
+ break;
+ pair end;
+ int endi=i+desiredSides-1;
+ end=point(p,endi);
+ found=checkSegment(p,start,end) && abs(end-start) < L;
+ if(found) {
+ path p1=subpath(p,endi,i+length(p))--cycle;
+ patch.append(subpath(p,i,endi)--cycle);
+ p=removeDuplicates(p1);
+ i=-1; // increment will make i be 0
+ }
+ }
+ if(!found && k == SIZE_STEPS && length(p) > 4 && i == length(p)-1) {
+ // avoid infinite recursion
+ ++refinements;
+ if(refinements > maxrefinements) {
+ warning("subdivisions","too many subdivisions",position=true);
+ } else {
+ p=subdivide(p);
+ i=-1;
+ }
+ }
+ }
+ }
+ }
+ if(length(p) <= 4)
+ patch.append(p);
+ }
+ return patch;
+}
diff --git a/graphics/asymptote/base/binarytree.asy b/graphics/asymptote/base/binarytree.asy
new file mode 100644
index 0000000000..31e0e3aab6
--- /dev/null
+++ b/graphics/asymptote/base/binarytree.asy
@@ -0,0 +1,383 @@
+/* **********************************************************************
+ * binarytree: An Asymptote module to draw binary trees *
+ * *
+ * Copyright(C) 2006 *
+ * Tobias Langner tobias[at]langner[dot]nightlabs[dot]de *
+ * *
+ * Modified by John Bowman *
+ * *
+ * Condensed mode: *
+ * Copyright(C) 2012 *
+ * Gerasimos Dimitriadis dimeg [at] intracom [dot] gr *
+ * *
+ ************************************************************************
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 of the License, or(at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Or get it online: *
+ * http: //www.gnu.org/copyleft/lesser.html *
+ * *
+ ***********************************************************************/
+
+// default values
+real minDistDefault=0.2cm;
+real nodeMarginDefault=0.1cm;
+
+// structure to represent nodes in a binary tree
+struct binarytreeNode {
+ int key;
+ binarytreeNode left;
+ binarytreeNode right;
+ binarytreeNode parent;
+ bool spans_calculated=false;
+ int left_span,total_left_span;
+ int right_span,total_right_span;
+ void update_spans();
+
+ // Get the horizontal span of the tree consisting of the current
+ // node plus the whole subtree that is rooted at the right child
+ // (condensed mode)
+ int getTotalRightSpan() {
+ if(spans_calculated == false) {
+ update_spans();
+ }
+
+ return total_right_span;
+ }
+
+ // Get the horizontal span of the tree consisting of the current
+ // node plus the whole subtree that is rooted at the left child
+ // (condensed mode)
+ int getTotalLeftSpan() {
+ if(spans_calculated == false) {
+ update_spans();
+ }
+ return total_left_span;
+ }
+
+ // Get the horizontal distance between this node and its right child
+ // (condensed mode)
+ int getRightSpan() {
+ if(spans_calculated == false) {
+ update_spans();
+ }
+ return right_span;
+ }
+
+ // Get the horizontal distance between this node and its left child
+ // (condensed mode)
+ int getLeftSpan() {
+ if(spans_calculated == false) {
+ update_spans();
+ }
+ return left_span;
+ }
+
+ // Update all span figures for this node.
+ // condensed mode)
+ update_spans=new void() {
+ if(spans_calculated == true)
+ return;
+
+ left_span=0;
+ total_left_span=0;
+ right_span=0;
+ total_right_span=0;
+
+ if(left != null) {
+ left_span=left.getTotalRightSpan()+1;
+ total_left_span=left_span+left.getTotalLeftSpan();
+ }
+
+ if(right != null) {
+ right_span=right.getTotalLeftSpan()+1;
+ total_right_span=right_span+right.getTotalRightSpan();
+ }
+ spans_calculated=true;
+ };
+
+ // set the left child of this node
+ void setLeft(binarytreeNode left) {
+ this.left=left;
+ this.left.parent=this;
+ }
+
+ // set the right child of this node
+ void setRight(binarytreeNode right) {
+ this.right=right;
+ this.right.parent=this;
+ }
+
+ // return a boolean indicating whether this node is the root
+ bool isRoot() {
+ return parent == null;
+ }
+
+ // return the level of the subtree rooted at this node.
+ int getLevel() {
+ if(isRoot())
+ return 1;
+ else
+ return parent.getLevel()+1;
+ }
+
+ // set the children of this binarytreeNode
+ void setChildren(binarytreeNode left, binarytreeNode right) {
+ setLeft(left);
+ setRight(right);
+ }
+
+ // create a new binarytreeNode with key <key>
+ static binarytreeNode binarytreeNode(int key) {
+ binarytreeNode toReturn=new binarytreeNode;
+ toReturn.key=key;
+ return toReturn;
+ }
+
+ // returns the height of the subtree rooted at this node.
+ int getHeight() {
+ if(left == null && right == null)
+ return 1;
+ if(left == null)
+ return right.getHeight()+1;
+ if(right == null)
+ return left.getHeight()+1;
+
+ return max(left.getHeight(),right.getHeight())+1;
+ }
+}
+
+binarytreeNode operator init() {return null;}
+
+// "constructor" for binarytreeNode
+binarytreeNode binarytreeNode(int key)=binarytreeNode.binarytreeNode;
+
+// draw the tree rooted at the given <node> at the given position <pos>, with
+// <height>=the height of the containing tree,
+// <minDist>=the minimal horizontal distance of two nodes at the lowest level,
+// <levelDist>=the vertical distance between two levels,
+// <nodeDiameter>=the diameter of one node.
+object draw(picture pic=currentpicture, binarytreeNode node, pair pos,
+ int height, real minDist, real levelDist, real nodeDiameter,
+ pen p=currentpen, bool condensed=false) {
+ Label label=Label(math((string) node.key),pos);
+
+ binarytreeNode left=node.left;
+ binarytreeNode right=node.right;
+
+ // return the distance for two nodes at the given <level> when the
+ // containing tree has height <height>
+ // and the minimal distance between two nodes is <minDist> .
+ real getDistance(int level, int height, real minDist) {
+ return(nodeDiameter+minDist)*2^(height-level);
+ }
+
+ // return the horiontal distance between node <n> and its left child
+ // (condensed mode)
+ real getLeftDistance(binarytreeNode n) {
+ return(nodeDiameter+minDist) *(real)n.getLeftSpan() * 0.5;
+ }
+
+ // return the horiontal distance between node <n> and its right child
+ // (condensed mode)
+ real getRightDistance(binarytreeNode n) {
+ return(nodeDiameter+minDist) *(real)n.getRightSpan() * 0.5;
+ }
+
+ real dist=getDistance(node.getLevel(),height,minDist)/2;
+
+ // draw the connection between the two nodes at the given positions
+ // by calculating the connection points and drawing the corresponding
+ // arrow.
+ void deferredDrawNodeConnection(pair parentPos, pair childPos) {
+ pic.add(new void(frame f, transform t) {
+ pair start,end;
+ // calculate connection path
+ transform T=shift(nodeDiameter/2*unit(t*childPos-t*parentPos));
+ path arr=(T*t*parentPos)--(inverse(T)*t*childPos);
+ draw(f,PenMargin(arr,p).g,p,Arrow(5));
+ });
+ pic.addPoint(parentPos);
+ pic.addPoint(childPos);
+ }
+
+ if(left != null) {
+ pair childPos;
+ if(condensed == false) {
+ childPos=pos-(0,levelDist)-(dist/2,0);
+ }
+ else {
+ childPos=pos-(0,levelDist)-((real)getLeftDistance(node),0);
+ }
+ draw(pic,left,childPos,height,minDist,levelDist,nodeDiameter,p,condensed);
+ deferredDrawNodeConnection(pos,childPos);
+ }
+
+ if(right != null) {
+ pair childPos;
+ if(condensed == false) {
+ childPos=pos-(0,levelDist)+(dist/2,0);
+ }
+ else {
+ childPos=pos-(0,levelDist)+((real)getRightDistance(node),0);
+ }
+ draw(pic,right,childPos,height,minDist,levelDist,nodeDiameter,p,condensed);
+ deferredDrawNodeConnection(pos,childPos);
+ }
+
+ picture obj;
+ draw(obj,circle((0,0),nodeDiameter/2),p);
+ label(obj,label,(0,0),p);
+
+ add(pic,obj,pos);
+
+ return label;
+}
+
+struct key {
+ int n;
+ bool active;
+}
+
+key key(int n, bool active=true) {key k; k.n=n; k.active=active; return k;}
+
+key operator cast(int n) {return key(n);}
+int operator cast(key k) {return k.n;}
+int[] operator cast(key[] k) {
+ int[] I;
+ for(int i=0; i < k.length; ++i)
+ I[i]=k[i].n;
+ return I;
+}
+
+key nil=key(0,false);
+
+// structure to represent a binary tree.
+struct binarytree {
+ binarytreeNode root;
+ int[] keys;
+
+ // add the given <key> to the tree by searching for its place and
+ // inserting it there.
+ void addKey(int key) {
+ binarytreeNode newNode=binarytreeNode(key);
+
+ if(root == null) {
+ root=newNode;
+ keys.push(key);
+ return;
+ }
+
+ binarytreeNode n=root;
+ while(n != null) {
+ if(key < n.key) {
+ if(n.left != null)
+ n=n.left;
+ else {
+ n.setLeft(newNode);
+ keys.push(key);
+ return;
+ }
+ } else if(key > n.key) {
+ if(n.right != null)
+ n=n.right;
+ else {
+ n.setRight(newNode);
+ keys.push(key);
+ return;
+ }
+ }
+ }
+ }
+
+ // return the height of the tree
+ int getHeight() {
+ if(root == null)
+ return 0;
+ else
+ return root.getHeight();
+ }
+
+ // add all given keys to the tree sequentially
+ void addSearchKeys(int[] keys) {
+ for(int i=0; i < keys.length; ++i) {
+ int key=keys[i];
+ // Ignore duplicate keys
+ if(find(this.keys == key) == -1)
+ addKey(key);
+ }
+ }
+
+ binarytreeNode build(key[] keys, int[] ind) {
+ if(ind[0] >= keys.length) return null;
+ key k=keys[ind[0]];
+ ++ind[0];
+ if(!k.active) return null;
+ binarytreeNode bt=binarytreeNode(k);
+ binarytreeNode left=build(keys,ind);
+ binarytreeNode right=build(keys,ind);
+ bt.left=left; bt.right=right;
+ if(left != null) left.parent=bt;
+ if(right != null) right.parent=bt;
+ return bt;
+ }
+
+ void addKeys(key[] keys) {
+ int[] ind={0};
+ root=build(keys,ind);
+ this.keys=keys;
+ }
+
+
+ // return all key in the tree
+ int[] getKeys() {
+ return keys;
+ }
+}
+
+binarytree searchtree(...int[] keys)
+{
+ binarytree bt;
+ bt.addSearchKeys(keys);
+ return bt;
+}
+
+binarytree binarytree(...key[] keys)
+{
+ binarytree bt;
+ bt.addKeys(keys);
+ return bt;
+}
+
+// draw the given binary tree.
+void draw(picture pic=currentpicture, binarytree tree,
+ real minDist=minDistDefault, real nodeMargin=nodeMarginDefault,
+ pen p=currentpen, bool condensed=false)
+{
+ int[] keys=tree.getKeys();
+
+ // calculate the node diameter so that all keys fit into it
+ frame f;
+ for(int i=0; i < keys.length; ++i)
+ label(f,math(string(keys[i])),p);
+
+ real nodeDiameter=abs(max(f)-min(f))+2*nodeMargin;
+ real levelDist=nodeDiameter*1.8;
+
+ draw(pic,tree.root,(0,0),tree.getHeight(),minDist,levelDist,nodeDiameter,p,
+ condensed);
+}
diff --git a/graphics/asymptote/base/bsp.asy b/graphics/asymptote/base/bsp.asy
new file mode 100644
index 0000000000..cf9d7e0781
--- /dev/null
+++ b/graphics/asymptote/base/bsp.asy
@@ -0,0 +1,209 @@
+private import math;
+import three;
+
+real epsilon=10*realEpsilon;
+
+// Routines for hidden surface removal (via binary space partition):
+// Structure face is derived from picture.
+struct face {
+ picture pic;
+ transform t;
+ frame fit;
+ triple normal,point;
+ triple min,max;
+ void operator init(path3 p) {
+ this.normal=normal(p);
+ if(this.normal == O) abort("path is linear");
+ this.point=point(p,0);
+ min=min(p);
+ max=max(p);
+ }
+ face copy() {
+ face f=new face;
+ f.pic=pic.copy();
+ f.t=t;
+ f.normal=normal;
+ f.point=point;
+ f.min=min;
+ f.max=max;
+ add(f.fit,fit);
+ return f;
+ }
+}
+
+picture operator cast(face f) {return f.pic;}
+face operator cast(path3 p) {return face(p);}
+
+struct line {
+ triple point;
+ triple dir;
+}
+
+private line intersection(face a, face b)
+{
+ line L;
+ L.point=intersectionpoint(a.normal,a.point,b.normal,b.point);
+ L.dir=unit(cross(a.normal,b.normal));
+ return L;
+}
+
+struct half {
+ pair[] left,right;
+
+ // Sort the points in the pair array z according to whether they lie on the
+ // left or right side of the line L in the direction dir passing through P.
+ // Points exactly on L are considered to be on the right side.
+ // Also push any points of intersection of L with the path operator --(... z)
+ // onto each of the arrays left and right.
+ void operator init(pair dir, pair P ... pair[] z) {
+ pair lastz;
+ pair invdir=dir != 0 ? 1/dir : 0;
+ bool left,last;
+ for(int i=0; i < z.length; ++i) {
+ left=(invdir*z[i]).y > (invdir*P).y;
+ if(i > 0 && last != left) {
+ pair w=extension(P,P+dir,lastz,z[i]);
+ this.left.push(w);
+ this.right.push(w);
+ }
+ if(left) this.left.push(z[i]);
+ else this.right.push(z[i]);
+ last=left;
+ lastz=z[i];
+ }
+ }
+}
+
+struct splitface {
+ face back,front;
+}
+
+// Return the pieces obtained by splitting face a by face cut.
+splitface split(face a, face cut, projection P)
+{
+ splitface S;
+
+ void nointersection() {
+ if(abs(dot(a.point-P.camera,a.normal)) >=
+ abs(dot(cut.point-P.camera,cut.normal))) {
+ S.back=a;
+ S.front=null;
+ } else {
+ S.back=null;
+ S.front=a;
+ }
+ }
+
+ if(P.infinity) {
+ P=P.copy();
+ static real factor=1/sqrtEpsilon;
+ P.camera *= factor*max(abs(a.min),abs(a.max),
+ abs(cut.min),abs(cut.max));
+ }
+
+ if((abs(a.normal-cut.normal) < epsilon ||
+ abs(a.normal+cut.normal) < epsilon)) {
+ nointersection();
+ return S;
+ }
+
+ line L=intersection(a,cut);
+
+ if(dot(P.camera-L.point,P.camera-P.target) < 0) {
+ nointersection();
+ return S;
+ }
+
+ pair point=a.t*project(L.point,P);
+ pair dir=a.t*project(L.point+L.dir,P)-point;
+ pair invdir=dir != 0 ? 1/dir : 0;
+ triple apoint=L.point+cross(L.dir,a.normal);
+ bool left=(invdir*(a.t*project(apoint,P))).y >= (invdir*point).y;
+
+ real t=intersect(apoint,P.camera,cut.normal,cut.point);
+ bool rightfront=left ^ (t <= 0 || t >= 1);
+
+ face back=a, front=a.copy();
+ pair max=max(a.fit);
+ pair min=min(a.fit);
+ half h=half(dir,point,max,(min.x,max.y),min,(max.x,min.y),max);
+ if(h.right.length == 0) {
+ if(rightfront) front=null;
+ else back=null;
+ } else if(h.left.length == 0) {
+ if(rightfront) back=null;
+ else front=null;
+ }
+ if(front != null)
+ clip(front.fit,operator --(... rightfront ? h.right : h.left)--cycle,
+ zerowinding);
+ if(back != null)
+ clip(back.fit,operator --(... rightfront ? h.left : h.right)--cycle,
+ zerowinding);
+ S.back=back;
+ S.front=front;
+ return S;
+}
+
+// A binary space partition
+struct bsp
+{
+ bsp back;
+ bsp front;
+ face node;
+
+ // Construct the bsp.
+ void operator init(face[] faces, projection P) {
+ if(faces.length != 0) {
+ this.node=faces.pop();
+ face[] front,back;
+ for(int i=0; i < faces.length; ++i) {
+ splitface split=split(faces[i],this.node,P);
+ if(split.front != null) front.push(split.front);
+ if(split.back != null) back.push(split.back);
+ }
+ this.front=bsp(front,P);
+ this.back=bsp(back,P);
+ }
+ }
+
+ // Draw from back to front.
+ void add(frame f) {
+ if(back != null) back.add(f);
+ add(f,node.fit,group=true);
+ if(labels(node.fit)) layer(f); // Draw over any existing TeX layers.
+ if(front != null) front.add(f);
+ }
+}
+
+void add(picture pic=currentpicture, face[] faces,
+ projection P=currentprojection)
+{
+ int n=faces.length;
+ face[] Faces=new face[n];
+ for(int i=0; i < n; ++i)
+ Faces[i]=faces[i].copy();
+
+ pic.add(new void (frame f, transform t, transform T,
+ pair m, pair M) {
+ // Fit all of the pictures so we know their exact sizes.
+ face[] faces=new face[n];
+ for(int i=0; i < n; ++i) {
+ faces[i]=Faces[i].copy();
+ face F=faces[i];
+ F.t=t*T*F.pic.T;
+ F.fit=F.pic.fit(t,T*F.pic.T,m,M);
+ }
+
+ bsp bsp=bsp(faces,P);
+ if(bsp != null) bsp.add(f);
+ });
+
+ for(int i=0; i < n; ++i) {
+ picture F=Faces[i].pic;
+ pic.userBox3(F.userMin3(), F.userMax3());
+ pic.bounds.append(F.T, F.bounds);
+ // The above 2 lines should be replaced with a routine in picture which
+ // copies only sizing data from another picture.
+ }
+}
diff --git a/graphics/asymptote/base/colormap.asy b/graphics/asymptote/base/colormap.asy
new file mode 100644
index 0000000000..4b2242d661
--- /dev/null
+++ b/graphics/asymptote/base/colormap.asy
@@ -0,0 +1,3890 @@
+// author: Fabian Hassler
+// year: 2019
+
+// This module implements a list of colormaps
+// the code has been converted from the python library
+// matplotlib 3.0.2 license under BSD
+// Feel free to use or to modify the code
+
+// example: the generate a palette wistia
+// pen[] Palette = wistia.palette()
+//
+// There are two types of palettes. For a complete list see below:
+//
+// 1) The segmented palettes can be used as
+// <name>.palette(int NColors=256, real gamma=1.)
+// NColors are the number of colors in the palette
+// gamma is the gamma-factor
+//
+// 2) The listed palettes can only be used as
+// <name>.palette()
+//
+// Both functions return pen[] that can be used as a palette in the
+// module palette.
+
+// list of palettes
+// see also https://matplotlib.org/tutorials/colors/colormaps.html
+
+// segmented palettes:
+// CMRmap
+// autumn
+// binary
+// bone
+// cool
+// coolwarm
+// copper
+// gist_earth
+// gist_ncar
+// gist_stern
+// gray
+// hot
+// hsv
+// jet
+// nipy_spectral
+// pink
+// spring
+// summer
+// winter
+// wistia
+
+// listed palettes:
+// Accent
+// Blues
+// BrBG
+// BuGn
+// BuPu
+// Dark2
+// GnBu
+// Greens
+// Greys
+// OrRd
+// Oranges
+// PRGn
+// Paired
+// Pastel1
+// Pastel2
+// PiYG
+// PuBuGn
+// PuBu
+// PuOr
+// PuRd
+// Purples
+// RdBu
+// RdGy
+// RdPu
+// RdYlBu
+// RdYlGn
+// Reds
+// Set1
+// Set2
+// Set3
+// Spectral
+// YlGnBu
+// YlGn
+// YlOrBr
+// YlOrRd
+// brg
+// bwr
+// seismic
+// tab10
+// tab20
+// tab20b
+// tab20c
+// cividis
+// inferno
+// magma
+// plasma
+// twilight
+// twilight_shifted
+// viridis
+
+
+// Example of usage:
+
+// import graph;
+// import palette;
+// import colormap;
+// int NColors=5;
+// pen[] Palette=spring.palette(NColors);
+// palette(bounds(0,1),(0.,0),(500,50),Bottom,Palette);
+
+//
+// SOURCE CODE
+//
+private real[] makeMappingArray(int N, triple[] data, real gamma=1.) {
+ real[] x;
+ real[] y0;
+ real[] y1;
+
+ for (int i=0; i<data.length; ++i) {
+ x.push(data[i].x);
+ y0.push(data[i].y);
+ y1.push(data[i].z);
+ };
+
+ x = x*(N-1);
+ real[] lut = new real[N];
+ real[] xind = (N - 1) * uniform(0, 1, N-1) ** gamma;
+ int[] ind = map(new int(real xi) {return search(x, xi);}, xind);
+ ind = ind[1:N-1]; // note that the index is shifted from python
+
+ real[] dist = (xind[1:N-1] - x[ind])/(x[ind+1] - x[ind]);
+
+ lut[1:N-1] = dist * (y0[ind+1] - y1[ind]) + y1[ind];
+ lut[0] = y1[0];
+ lut[N-1] = y0[y0.length-1];
+ return lut;
+}
+
+// struct for segmented data
+struct seg_data {
+ private triple[] r; // red
+ private triple[] g; // green
+ private triple[] b; // blue
+
+ void operator init(triple[] r, triple[] g, triple[] b) {
+ this.r=r;
+ this.g=g;
+ this.b=b;
+ }
+
+ pen[] palette(int NColors=256, real gamma=1.) {
+ real[] red = makeMappingArray(NColors, this.r, gamma);
+ real[] green = makeMappingArray(NColors, this.g, gamma);
+ real[] blue = makeMappingArray(NColors, this.b, gamma);
+
+ pen[] pal =
+ sequence(new pen(int i) {return rgb(red[i], green[i], blue[i]);},
+ NColors);
+
+ return pal;
+ }
+}
+
+// struct for list data
+struct list_data {
+ private pen[] data;
+ pen[] palette(){return data;}
+ void operator init(pen[] d) {
+ this.data=d;
+ }
+}
+
+//
+// DATA
+//
+list_data Accent = list_data(new pen[] {
+ rgb (0.4980392156862745, 0.788235294117647, 0.4980392156862745) ,
+ rgb (0.7450980392156863, 0.6823529411764706, 0.8313725490196079) ,
+ rgb (0.9921568627450981, 0.7529411764705882, 0.5254901960784314) ,
+ rgb (1.0, 1.0, 0.6) ,
+ rgb (0.2196078431372549, 0.4235294117647059, 0.6901960784313725) ,
+ rgb (0.9411764705882353, 0.00784313725490196, 0.4980392156862745) ,
+ rgb (0.7490196078431373, 0.3568627450980392, 0.09019607843137253) ,
+ rgb (0.4, 0.4, 0.4)
+});
+
+
+list_data Blues = list_data(new pen[] {
+ rgb (0.9686274509803922, 0.984313725490196, 1.0) ,
+ rgb (0.8705882352941177, 0.9215686274509803, 0.9686274509803922) ,
+ rgb (0.7764705882352941, 0.8588235294117647, 0.9372549019607843) ,
+ rgb (0.6196078431372549, 0.792156862745098, 0.8823529411764706) ,
+ rgb (0.4196078431372549, 0.6823529411764706, 0.8392156862745098) ,
+ rgb (0.25882352941176473, 0.5725490196078431, 0.7764705882352941) ,
+ rgb (0.12941176470588237, 0.44313725490196076, 0.7098039215686275) ,
+ rgb (0.03137254901960784, 0.3176470588235294, 0.611764705882353) ,
+ rgb (0.03137254901960784, 0.18823529411764706, 0.4196078431372549)
+});
+
+
+list_data BrBG = list_data(new pen[] {
+ rgb (0.32941176470588235, 0.18823529411764706, 0.0196078431372549) ,
+ rgb (0.5490196078431373, 0.3176470588235294, 0.0392156862745098) ,
+ rgb (0.7490196078431373, 0.5058823529411764, 0.17647058823529413) ,
+ rgb (0.8745098039215686, 0.7607843137254902, 0.49019607843137253) ,
+ rgb (0.9647058823529412, 0.9098039215686274, 0.7647058823529411) ,
+ rgb (0.9607843137254902, 0.9607843137254902, 0.9607843137254902) ,
+ rgb (0.7803921568627451, 0.9176470588235294, 0.8980392156862745) ,
+ rgb (0.5019607843137255, 0.803921568627451, 0.7568627450980392) ,
+ rgb (0.20784313725490197, 0.592156862745098, 0.5607843137254902) ,
+ rgb (0.00392156862745098, 0.4, 0.3686274509803922) ,
+ rgb (0.0, 0.23529411764705882, 0.18823529411764706)
+});
+
+
+list_data BuGn = list_data(new pen[] {
+ rgb (0.9686274509803922, 0.9882352941176471, 0.9921568627450981) ,
+ rgb (0.8980392156862745, 0.9607843137254902, 0.9764705882352941) ,
+ rgb (0.8, 0.9254901960784314, 0.9019607843137255) ,
+ rgb (0.6, 0.8470588235294118, 0.788235294117647) ,
+ rgb (0.4, 0.7607843137254902, 0.6431372549019608) ,
+ rgb (0.2549019607843137, 0.6823529411764706, 0.4627450980392157) ,
+ rgb (0.13725490196078433, 0.5450980392156862, 0.27058823529411763) ,
+ rgb (0.0, 0.42745098039215684, 0.17254901960784313) ,
+ rgb (0.0, 0.26666666666666666, 0.10588235294117647)
+});
+
+
+list_data BuPu = list_data(new pen[] {
+ rgb (0.9686274509803922, 0.9882352941176471, 0.9921568627450981) ,
+ rgb (0.8784313725490196, 0.9254901960784314, 0.9568627450980393) ,
+ rgb (0.7490196078431373, 0.8274509803921568, 0.9019607843137255) ,
+ rgb (0.6196078431372549, 0.7372549019607844, 0.8549019607843137) ,
+ rgb (0.5490196078431373, 0.5882352941176471, 0.7764705882352941) ,
+ rgb (0.5490196078431373, 0.4196078431372549, 0.6941176470588235) ,
+ rgb (0.5333333333333333, 0.2549019607843137, 0.615686274509804) ,
+ rgb (0.5058823529411764, 0.05882352941176471, 0.48627450980392156) ,
+ rgb (0.30196078431372547, 0.0, 0.29411764705882354)
+});
+
+
+seg_data CMRmap = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (0.125, 0.15, 0.15) ,
+ (0.25, 0.3, 0.3) ,
+ (0.375, 0.6, 0.6) ,
+ (0.5, 1.0, 1.0) ,
+ (0.625, 0.9, 0.9) ,
+ (0.75, 0.9, 0.9) ,
+ (0.875, 0.9, 0.9) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.125, 0.15, 0.15) ,
+ (0.25, 0.15, 0.15) ,
+ (0.375, 0.2, 0.2) ,
+ (0.5, 0.25, 0.25) ,
+ (0.625, 0.5, 0.5) ,
+ (0.75, 0.75, 0.75) ,
+ (0.875, 0.9, 0.9) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.125, 0.5, 0.5) ,
+ (0.25, 0.75, 0.75) ,
+ (0.375, 0.5, 0.5) ,
+ (0.5, 0.15, 0.15) ,
+ (0.625, 0.0, 0.0) ,
+ (0.75, 0.1, 0.1) ,
+ (0.875, 0.5, 0.5) ,
+ (1.0, 1.0, 1.0)
+ }
+);
+
+
+list_data Dark2 = list_data(new pen[] {
+ rgb (0.10588235294117647, 0.6196078431372549, 0.4666666666666667) ,
+ rgb (0.8509803921568627, 0.37254901960784315, 0.00784313725490196) ,
+ rgb (0.4588235294117647, 0.4392156862745098, 0.7019607843137254) ,
+ rgb (0.9058823529411765, 0.1607843137254902, 0.5411764705882353) ,
+ rgb (0.4, 0.6509803921568628, 0.11764705882352941) ,
+ rgb (0.9019607843137255, 0.6705882352941176, 0.00784313725490196) ,
+ rgb (0.6509803921568628, 0.4627450980392157, 0.11372549019607843) ,
+ rgb (0.4, 0.4, 0.4)
+});
+
+
+list_data GnBu = list_data(new pen[] {
+ rgb (0.9686274509803922, 0.9882352941176471, 0.9411764705882353) ,
+ rgb (0.8784313725490196, 0.9529411764705882, 0.8588235294117647) ,
+ rgb (0.8, 0.9215686274509803, 0.7725490196078432) ,
+ rgb (0.6588235294117647, 0.8666666666666667, 0.7098039215686275) ,
+ rgb (0.4823529411764706, 0.8, 0.7686274509803922) ,
+ rgb (0.3058823529411765, 0.7019607843137254, 0.8274509803921568) ,
+ rgb (0.16862745098039217, 0.5490196078431373, 0.7450980392156863) ,
+ rgb (0.03137254901960784, 0.40784313725490196, 0.6745098039215687) ,
+ rgb (0.03137254901960784, 0.25098039215686274, 0.5058823529411764)
+});
+
+
+list_data Greens = list_data(new pen[] {
+ rgb (0.9686274509803922, 0.9882352941176471, 0.9607843137254902) ,
+ rgb (0.8980392156862745, 0.9607843137254902, 0.8784313725490196) ,
+ rgb (0.7803921568627451, 0.9137254901960784, 0.7529411764705882) ,
+ rgb (0.6313725490196078, 0.8509803921568627, 0.6078431372549019) ,
+ rgb (0.4549019607843137, 0.7686274509803922, 0.4627450980392157) ,
+ rgb (0.2549019607843137, 0.6705882352941176, 0.36470588235294116) ,
+ rgb (0.13725490196078433, 0.5450980392156862, 0.27058823529411763) ,
+ rgb (0.0, 0.42745098039215684, 0.17254901960784313) ,
+ rgb (0.0, 0.26666666666666666, 0.10588235294117647)
+});
+
+
+list_data Greys = list_data(new pen[] {
+ rgb (1.0, 1.0, 1.0) ,
+ rgb (0.9411764705882353, 0.9411764705882353, 0.9411764705882353) ,
+ rgb (0.8509803921568627, 0.8509803921568627, 0.8509803921568627) ,
+ rgb (0.7411764705882353, 0.7411764705882353, 0.7411764705882353) ,
+ rgb (0.5882352941176471, 0.5882352941176471, 0.5882352941176471) ,
+ rgb (0.45098039215686275, 0.45098039215686275, 0.45098039215686275) ,
+ rgb (0.3215686274509804, 0.3215686274509804, 0.3215686274509804) ,
+ rgb (0.1450980392156863, 0.1450980392156863, 0.1450980392156863) ,
+ rgb (0.0, 0.0, 0.0)
+});
+
+
+list_data OrRd = list_data(new pen[] {
+ rgb (1.0, 0.9686274509803922, 0.9254901960784314) ,
+ rgb (0.996078431372549, 0.9098039215686274, 0.7843137254901961) ,
+ rgb (0.9921568627450981, 0.8313725490196079, 0.6196078431372549) ,
+ rgb (0.9921568627450981, 0.7333333333333333, 0.5176470588235295) ,
+ rgb (0.9882352941176471, 0.5529411764705883, 0.34901960784313724) ,
+ rgb (0.9372549019607843, 0.396078431372549, 0.2823529411764706) ,
+ rgb (0.8431372549019608, 0.18823529411764706, 0.12156862745098039) ,
+ rgb (0.7019607843137254, 0.0, 0.0) ,
+ rgb (0.4980392156862745, 0.0, 0.0)
+});
+
+
+list_data Oranges = list_data(new pen[] {
+ rgb (1.0, 0.9607843137254902, 0.9215686274509803) ,
+ rgb (0.996078431372549, 0.9019607843137255, 0.807843137254902) ,
+ rgb (0.9921568627450981, 0.8156862745098039, 0.6352941176470588) ,
+ rgb (0.9921568627450981, 0.6823529411764706, 0.4196078431372549) ,
+ rgb (0.9921568627450981, 0.5529411764705883, 0.23529411764705882) ,
+ rgb (0.9450980392156862, 0.4117647058823529, 0.07450980392156863) ,
+ rgb (0.8509803921568627, 0.2823529411764706, 0.00392156862745098) ,
+ rgb (0.6509803921568628, 0.21176470588235294, 0.01176470588235294) ,
+ rgb (0.4980392156862745, 0.15294117647058825, 0.01568627450980392)
+});
+
+
+list_data PRGn = list_data(new pen[] {
+ rgb (0.25098039215686274, 0.0, 0.29411764705882354) ,
+ rgb (0.4627450980392157, 0.16470588235294117, 0.5137254901960784) ,
+ rgb (0.6, 0.4392156862745098, 0.6705882352941176) ,
+ rgb (0.7607843137254902, 0.6470588235294118, 0.8117647058823529) ,
+ rgb (0.9058823529411765, 0.8313725490196079, 0.9098039215686274) ,
+ rgb (0.9686274509803922, 0.9686274509803922, 0.9686274509803922) ,
+ rgb (0.8509803921568627, 0.9411764705882353, 0.8274509803921568) ,
+ rgb (0.6509803921568628, 0.8588235294117647, 0.6274509803921569) ,
+ rgb (0.35294117647058826, 0.6823529411764706, 0.3803921568627451) ,
+ rgb (0.10588235294117647, 0.47058823529411764, 0.21568627450980393) ,
+ rgb (0.0, 0.26666666666666666, 0.10588235294117647)
+});
+
+
+list_data Paired = list_data(new pen[] {
+ rgb (0.6509803921568628, 0.807843137254902, 0.8901960784313725) ,
+ rgb (0.12156862745098039, 0.47058823529411764, 0.7058823529411765) ,
+ rgb (0.6980392156862745, 0.8745098039215686, 0.5411764705882353) ,
+ rgb (0.2, 0.6274509803921569, 0.17254901960784313) ,
+ rgb (0.984313725490196, 0.6039215686274509, 0.6) ,
+ rgb (0.8901960784313725, 0.10196078431372549, 0.10980392156862745) ,
+ rgb (0.9921568627450981, 0.7490196078431373, 0.43529411764705883) ,
+ rgb (1.0, 0.4980392156862745, 0.0) ,
+ rgb (0.792156862745098, 0.6980392156862745, 0.8392156862745098) ,
+ rgb (0.41568627450980394, 0.23921568627450981, 0.6039215686274509) ,
+ rgb (1.0, 1.0, 0.6) ,
+ rgb (0.6941176470588235, 0.34901960784313724, 0.1568627450980392)
+});
+
+
+list_data Pastel1 = list_data(new pen[] {
+ rgb (0.984313725490196, 0.7058823529411765, 0.6823529411764706) ,
+ rgb (0.7019607843137254, 0.803921568627451, 0.8901960784313725) ,
+ rgb (0.8, 0.9215686274509803, 0.7725490196078432) ,
+ rgb (0.8705882352941177, 0.796078431372549, 0.8941176470588236) ,
+ rgb (0.996078431372549, 0.8509803921568627, 0.6509803921568628) ,
+ rgb (1.0, 1.0, 0.8) ,
+ rgb (0.8980392156862745, 0.8470588235294118, 0.7411764705882353) ,
+ rgb (0.9921568627450981, 0.8549019607843137, 0.9254901960784314) ,
+ rgb (0.9490196078431372, 0.9490196078431372, 0.9490196078431372)
+});
+
+
+list_data Pastel2 = list_data(new pen[] {
+ rgb (0.7019607843137254, 0.8862745098039215, 0.803921568627451) ,
+ rgb (0.9921568627450981, 0.803921568627451, 0.6745098039215687) ,
+ rgb (0.796078431372549, 0.8352941176470589, 0.9098039215686274) ,
+ rgb (0.9568627450980393, 0.792156862745098, 0.8941176470588236) ,
+ rgb (0.9019607843137255, 0.9607843137254902, 0.788235294117647) ,
+ rgb (1.0, 0.9490196078431372, 0.6823529411764706) ,
+ rgb (0.9450980392156862, 0.8862745098039215, 0.8) ,
+ rgb (0.8, 0.8, 0.8)
+});
+
+
+list_data PiYG = list_data(new pen[] {
+ rgb (0.5568627450980392, 0.00392156862745098, 0.3215686274509804) ,
+ rgb (0.7725490196078432, 0.10588235294117647, 0.49019607843137253) ,
+ rgb (0.8705882352941177, 0.4666666666666667, 0.6823529411764706) ,
+ rgb (0.9450980392156862, 0.7137254901960784, 0.8549019607843137) ,
+ rgb (0.9921568627450981, 0.8784313725490196, 0.9372549019607843) ,
+ rgb (0.9686274509803922, 0.9686274509803922, 0.9686274509803922) ,
+ rgb (0.9019607843137255, 0.9607843137254902, 0.8156862745098039) ,
+ rgb (0.7215686274509804, 0.8823529411764706, 0.5254901960784314) ,
+ rgb (0.4980392156862745, 0.7372549019607844, 0.2549019607843137) ,
+ rgb (0.30196078431372547, 0.5725490196078431, 0.12941176470588237) ,
+ rgb (0.15294117647058825, 0.39215686274509803, 0.09803921568627451)
+});
+
+
+list_data PuBuGn = list_data(new pen[] {
+ rgb (1.0, 0.9686274509803922, 0.984313725490196) ,
+ rgb (0.9254901960784314, 0.8862745098039215, 0.9411764705882353) ,
+ rgb (0.8156862745098039, 0.8196078431372549, 0.9019607843137255) ,
+ rgb (0.6509803921568628, 0.7411764705882353, 0.8588235294117647) ,
+ rgb (0.403921568627451, 0.6627450980392157, 0.8117647058823529) ,
+ rgb (0.21176470588235294, 0.5647058823529412, 0.7529411764705882) ,
+ rgb (0.00784313725490196, 0.5058823529411764, 0.5411764705882353) ,
+ rgb (0.00392156862745098, 0.4235294117647059, 0.34901960784313724) ,
+ rgb (0.00392156862745098, 0.27450980392156865, 0.21176470588235294)
+});
+
+
+list_data PuBu = list_data(new pen[] {
+ rgb (1.0, 0.9686274509803922, 0.984313725490196) ,
+ rgb (0.9254901960784314, 0.9058823529411765, 0.9490196078431372) ,
+ rgb (0.8156862745098039, 0.8196078431372549, 0.9019607843137255) ,
+ rgb (0.6509803921568628, 0.7411764705882353, 0.8588235294117647) ,
+ rgb (0.4549019607843137, 0.6627450980392157, 0.8117647058823529) ,
+ rgb (0.21176470588235294, 0.5647058823529412, 0.7529411764705882) ,
+ rgb (0.0196078431372549, 0.4392156862745098, 0.6901960784313725) ,
+ rgb (0.01568627450980392, 0.35294117647058826, 0.5529411764705883) ,
+ rgb (0.00784313725490196, 0.2196078431372549, 0.34509803921568627)
+});
+
+
+list_data PuOr = list_data(new pen[] {
+ rgb (0.4980392156862745, 0.23137254901960785, 0.03137254901960784) ,
+ rgb (0.7019607843137254, 0.34509803921568627, 0.02352941176470588) ,
+ rgb (0.8784313725490196, 0.5098039215686274, 0.0784313725490196) ,
+ rgb (0.9921568627450981, 0.7215686274509804, 0.38823529411764707) ,
+ rgb (0.996078431372549, 0.8784313725490196, 0.7137254901960784) ,
+ rgb (0.9686274509803922, 0.9686274509803922, 0.9686274509803922) ,
+ rgb (0.8470588235294118, 0.8549019607843137, 0.9215686274509803) ,
+ rgb (0.6980392156862745, 0.6705882352941176, 0.8235294117647058) ,
+ rgb (0.5019607843137255, 0.45098039215686275, 0.6745098039215687) ,
+ rgb (0.32941176470588235, 0.15294117647058825, 0.5333333333333333) ,
+ rgb (0.17647058823529413, 0.0, 0.29411764705882354)
+});
+
+
+list_data PuRd = list_data(new pen[] {
+ rgb (0.9686274509803922, 0.9568627450980393, 0.9764705882352941) ,
+ rgb (0.9058823529411765, 0.8823529411764706, 0.9372549019607843) ,
+ rgb (0.8313725490196079, 0.7254901960784313, 0.8549019607843137) ,
+ rgb (0.788235294117647, 0.5803921568627451, 0.7803921568627451) ,
+ rgb (0.8745098039215686, 0.396078431372549, 0.6901960784313725) ,
+ rgb (0.9058823529411765, 0.1607843137254902, 0.5411764705882353) ,
+ rgb (0.807843137254902, 0.07058823529411765, 0.33725490196078434) ,
+ rgb (0.596078431372549, 0.0, 0.2627450980392157) ,
+ rgb (0.403921568627451, 0.0, 0.12156862745098039)
+});
+
+
+list_data Purples = list_data(new pen[] {
+ rgb (0.9882352941176471, 0.984313725490196, 0.9921568627450981) ,
+ rgb (0.9372549019607843, 0.9294117647058824, 0.9607843137254902) ,
+ rgb (0.8549019607843137, 0.8549019607843137, 0.9215686274509803) ,
+ rgb (0.7372549019607844, 0.7411764705882353, 0.8627450980392157) ,
+ rgb (0.6196078431372549, 0.6039215686274509, 0.7843137254901961) ,
+ rgb (0.5019607843137255, 0.49019607843137253, 0.7294117647058823) ,
+ rgb (0.41568627450980394, 0.3176470588235294, 0.6392156862745098) ,
+ rgb (0.32941176470588235, 0.15294117647058825, 0.5607843137254902) ,
+ rgb (0.24705882352941178, 0.0, 0.49019607843137253)
+});
+
+
+list_data RdBu = list_data(new pen[] {
+ rgb (0.403921568627451, 0.0, 0.12156862745098039) ,
+ rgb (0.6980392156862745, 0.09411764705882353, 0.16862745098039217) ,
+ rgb (0.8392156862745098, 0.3764705882352941, 0.30196078431372547) ,
+ rgb (0.9568627450980393, 0.6470588235294118, 0.5098039215686274) ,
+ rgb (0.9921568627450981, 0.8588235294117647, 0.7803921568627451) ,
+ rgb (0.9686274509803922, 0.9686274509803922, 0.9686274509803922) ,
+ rgb (0.8196078431372549, 0.8980392156862745, 0.9411764705882353) ,
+ rgb (0.5725490196078431, 0.7725490196078432, 0.8705882352941177) ,
+ rgb (0.2627450980392157, 0.5764705882352941, 0.7647058823529411) ,
+ rgb (0.12941176470588237, 0.4, 0.6745098039215687) ,
+ rgb (0.0196078431372549, 0.18823529411764706, 0.3803921568627451)
+});
+
+
+list_data RdGy = list_data(new pen[] {
+ rgb (0.403921568627451, 0.0, 0.12156862745098039) ,
+ rgb (0.6980392156862745, 0.09411764705882353, 0.16862745098039217) ,
+ rgb (0.8392156862745098, 0.3764705882352941, 0.30196078431372547) ,
+ rgb (0.9568627450980393, 0.6470588235294118, 0.5098039215686274) ,
+ rgb (0.9921568627450981, 0.8588235294117647, 0.7803921568627451) ,
+ rgb (1.0, 1.0, 1.0) ,
+ rgb (0.8784313725490196, 0.8784313725490196, 0.8784313725490196) ,
+ rgb (0.7294117647058823, 0.7294117647058823, 0.7294117647058823) ,
+ rgb (0.5294117647058824, 0.5294117647058824, 0.5294117647058824) ,
+ rgb (0.30196078431372547, 0.30196078431372547, 0.30196078431372547) ,
+ rgb (0.10196078431372549, 0.10196078431372549, 0.10196078431372549)
+});
+
+
+list_data RdPu = list_data(new pen[] {
+ rgb (1.0, 0.9686274509803922, 0.9529411764705882) ,
+ rgb (0.9921568627450981, 0.8784313725490196, 0.8666666666666667) ,
+ rgb (0.9882352941176471, 0.7725490196078432, 0.7529411764705882) ,
+ rgb (0.9803921568627451, 0.6235294117647059, 0.7098039215686275) ,
+ rgb (0.9686274509803922, 0.40784313725490196, 0.6313725490196078) ,
+ rgb (0.8666666666666667, 0.20392156862745098, 0.592156862745098) ,
+ rgb (0.6823529411764706, 0.00392156862745098, 0.49411764705882355) ,
+ rgb (0.47843137254901963, 0.00392156862745098, 0.4666666666666667) ,
+ rgb (0.28627450980392155, 0.0, 0.41568627450980394)
+});
+
+
+list_data RdYlBu = list_data(new pen[] {
+ rgb (0.6470588235294118, 0.0, 0.14901960784313725) ,
+ rgb (0.8431372549019608, 0.18823529411764706, 0.15294117647058825) ,
+ rgb (0.9568627450980393, 0.42745098039215684, 0.2627450980392157) ,
+ rgb (0.9921568627450981, 0.6823529411764706, 0.3803921568627451) ,
+ rgb (0.996078431372549, 0.8784313725490196, 0.5647058823529412) ,
+ rgb (1.0, 1.0, 0.7490196078431373) ,
+ rgb (0.8784313725490196, 0.9529411764705882, 0.9725490196078431) ,
+ rgb (0.6705882352941176, 0.8509803921568627, 0.9137254901960784) ,
+ rgb (0.4549019607843137, 0.6784313725490196, 0.8196078431372549) ,
+ rgb (0.27058823529411763, 0.4588235294117647, 0.7058823529411765) ,
+ rgb (0.19215686274509805, 0.21176470588235294, 0.5843137254901961)
+});
+
+
+list_data RdYlGn = list_data(new pen[] {
+ rgb (0.6470588235294118, 0.0, 0.14901960784313725) ,
+ rgb (0.8431372549019608, 0.18823529411764706, 0.15294117647058825) ,
+ rgb (0.9568627450980393, 0.42745098039215684, 0.2627450980392157) ,
+ rgb (0.9921568627450981, 0.6823529411764706, 0.3803921568627451) ,
+ rgb (0.996078431372549, 0.8784313725490196, 0.5450980392156862) ,
+ rgb (1.0, 1.0, 0.7490196078431373) ,
+ rgb (0.8509803921568627, 0.9372549019607843, 0.5450980392156862) ,
+ rgb (0.6509803921568628, 0.8509803921568627, 0.41568627450980394) ,
+ rgb (0.4, 0.7411764705882353, 0.38823529411764707) ,
+ rgb (0.10196078431372549, 0.596078431372549, 0.3137254901960784) ,
+ rgb (0.0, 0.40784313725490196, 0.21568627450980393)
+});
+
+
+list_data Reds = list_data(new pen[] {
+ rgb (1.0, 0.9607843137254902, 0.9411764705882353) ,
+ rgb (0.996078431372549, 0.8784313725490196, 0.8235294117647058) ,
+ rgb (0.9882352941176471, 0.7333333333333333, 0.6313725490196078) ,
+ rgb (0.9882352941176471, 0.5725490196078431, 0.4470588235294118) ,
+ rgb (0.984313725490196, 0.41568627450980394, 0.2901960784313726) ,
+ rgb (0.9372549019607843, 0.23137254901960785, 0.17254901960784313) ,
+ rgb (0.796078431372549, 0.09411764705882353, 0.11372549019607843) ,
+ rgb (0.6470588235294118, 0.058823529411764705, 0.08235294117647057) ,
+ rgb (0.403921568627451, 0.0, 0.05098039215686274)
+});
+
+
+list_data Set1 = list_data(new pen[] {
+ rgb (0.8941176470588236, 0.10196078431372549, 0.10980392156862745) ,
+ rgb (0.21568627450980393, 0.49411764705882355, 0.7215686274509804) ,
+ rgb (0.30196078431372547, 0.6862745098039216, 0.2901960784313726) ,
+ rgb (0.596078431372549, 0.3058823529411765, 0.6392156862745098) ,
+ rgb (1.0, 0.4980392156862745, 0.0) ,
+ rgb (1.0, 1.0, 0.2) ,
+ rgb (0.6509803921568628, 0.33725490196078434, 0.1568627450980392) ,
+ rgb (0.9686274509803922, 0.5058823529411764, 0.7490196078431373) ,
+ rgb (0.6, 0.6, 0.6)
+});
+
+
+list_data Set2 = list_data(new pen[] {
+ rgb (0.4, 0.7607843137254902, 0.6470588235294118) ,
+ rgb (0.9882352941176471, 0.5529411764705883, 0.3843137254901961) ,
+ rgb (0.5529411764705883, 0.6274509803921569, 0.796078431372549) ,
+ rgb (0.9058823529411765, 0.5411764705882353, 0.7647058823529411) ,
+ rgb (0.6509803921568628, 0.8470588235294118, 0.32941176470588235) ,
+ rgb (1.0, 0.8509803921568627, 0.1843137254901961) ,
+ rgb (0.8980392156862745, 0.7686274509803922, 0.5803921568627451) ,
+ rgb (0.7019607843137254, 0.7019607843137254, 0.7019607843137254)
+});
+
+
+list_data Set3 = list_data(new pen[] {
+ rgb (0.5529411764705883, 0.8274509803921568, 0.7803921568627451) ,
+ rgb (1.0, 1.0, 0.7019607843137254) ,
+ rgb (0.7450980392156863, 0.7294117647058823, 0.8549019607843137) ,
+ rgb (0.984313725490196, 0.5019607843137255, 0.4470588235294118) ,
+ rgb (0.5019607843137255, 0.6941176470588235, 0.8274509803921568) ,
+ rgb (0.9921568627450981, 0.7058823529411765, 0.3843137254901961) ,
+ rgb (0.7019607843137254, 0.8705882352941177, 0.4117647058823529) ,
+ rgb (0.9882352941176471, 0.803921568627451, 0.8980392156862745) ,
+ rgb (0.8509803921568627, 0.8509803921568627, 0.8509803921568627) ,
+ rgb (0.7372549019607844, 0.5019607843137255, 0.7411764705882353) ,
+ rgb (0.8, 0.9215686274509803, 0.7725490196078432) ,
+ rgb (1.0, 0.9294117647058824, 0.43529411764705883)
+});
+
+
+list_data Spectral = list_data(new pen[] {
+ rgb (0.6196078431372549, 0.00392156862745098, 0.25882352941176473) ,
+ rgb (0.8352941176470589, 0.24313725490196078, 0.30980392156862746) ,
+ rgb (0.9568627450980393, 0.42745098039215684, 0.2627450980392157) ,
+ rgb (0.9921568627450981, 0.6823529411764706, 0.3803921568627451) ,
+ rgb (0.996078431372549, 0.8784313725490196, 0.5450980392156862) ,
+ rgb (1.0, 1.0, 0.7490196078431373) ,
+ rgb (0.9019607843137255, 0.9607843137254902, 0.596078431372549) ,
+ rgb (0.6705882352941176, 0.8666666666666667, 0.6431372549019608) ,
+ rgb (0.4, 0.7607843137254902, 0.6470588235294118) ,
+ rgb (0.19607843137254902, 0.5333333333333333, 0.7411764705882353) ,
+ rgb (0.3686274509803922, 0.30980392156862746, 0.6352941176470588)
+});
+
+
+list_data YlGnBu = list_data(new pen[] {
+ rgb (1.0, 1.0, 0.8509803921568627) ,
+ rgb (0.9294117647058824, 0.9725490196078431, 0.6941176470588235) ,
+ rgb (0.7803921568627451, 0.9137254901960784, 0.7058823529411765) ,
+ rgb (0.4980392156862745, 0.803921568627451, 0.7333333333333333) ,
+ rgb (0.2549019607843137, 0.7137254901960784, 0.7686274509803922) ,
+ rgb (0.11372549019607843, 0.5686274509803921, 0.7529411764705882) ,
+ rgb (0.13333333333333333, 0.3686274509803922, 0.6588235294117647) ,
+ rgb (0.1450980392156863, 0.20392156862745098, 0.5803921568627451) ,
+ rgb (0.03137254901960784, 0.11372549019607843, 0.34509803921568627)
+});
+
+
+list_data YlGn = list_data(new pen[] {
+ rgb (1.0, 1.0, 0.8980392156862745) ,
+ rgb (0.9686274509803922, 0.9882352941176471, 0.7254901960784313) ,
+ rgb (0.8509803921568627, 0.9411764705882353, 0.6392156862745098) ,
+ rgb (0.6784313725490196, 0.8666666666666667, 0.5568627450980392) ,
+ rgb (0.47058823529411764, 0.7764705882352941, 0.4745098039215686) ,
+ rgb (0.2549019607843137, 0.6705882352941176, 0.36470588235294116) ,
+ rgb (0.13725490196078433, 0.5176470588235295, 0.2627450980392157) ,
+ rgb (0.0, 0.40784313725490196, 0.21568627450980393) ,
+ rgb (0.0, 0.27058823529411763, 0.1607843137254902)
+});
+
+
+list_data YlOrBr = list_data(new pen[] {
+ rgb (1.0, 1.0, 0.8980392156862745) ,
+ rgb (1.0, 0.9686274509803922, 0.7372549019607844) ,
+ rgb (0.996078431372549, 0.8901960784313725, 0.5686274509803921) ,
+ rgb (0.996078431372549, 0.7686274509803922, 0.30980392156862746) ,
+ rgb (0.996078431372549, 0.6, 0.1607843137254902) ,
+ rgb (0.9254901960784314, 0.4392156862745098, 0.0784313725490196) ,
+ rgb (0.8, 0.2980392156862745, 0.00784313725490196) ,
+ rgb (0.6, 0.20392156862745098, 0.01568627450980392) ,
+ rgb (0.4, 0.1450980392156863, 0.02352941176470588)
+});
+
+
+list_data YlOrRd = list_data(new pen[] {
+ rgb (1.0, 1.0, 0.8) ,
+ rgb (1.0, 0.9294117647058824, 0.6274509803921569) ,
+ rgb (0.996078431372549, 0.8509803921568627, 0.4627450980392157) ,
+ rgb (0.996078431372549, 0.6980392156862745, 0.2980392156862745) ,
+ rgb (0.9921568627450981, 0.5529411764705883, 0.23529411764705882) ,
+ rgb (0.9882352941176471, 0.3058823529411765, 0.16470588235294117) ,
+ rgb (0.8901960784313725, 0.10196078431372549, 0.10980392156862745) ,
+ rgb (0.7411764705882353, 0.0, 0.14901960784313725) ,
+ rgb (0.5019607843137255, 0.0, 0.14901960784313725)
+});
+
+
+seg_data autumn = seg_data(
+ new triple[] { // red
+ (0.0, 1.0, 1.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (1.0, 0.0, 0.0)
+ }
+);
+
+
+seg_data binary = seg_data(
+ new triple[] { // red
+ (0.0, 1.0, 1.0) ,
+ (1.0, 0.0, 0.0)
+ },
+ new triple[] { // green
+ (0.0, 1.0, 1.0) ,
+ (1.0, 0.0, 0.0)
+ },
+ new triple[] { // blue
+ (0.0, 1.0, 1.0) ,
+ (1.0, 0.0, 0.0)
+ }
+);
+
+
+seg_data bone = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (0.746032, 0.652778, 0.652778) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.365079, 0.319444, 0.319444) ,
+ (0.746032, 0.777778, 0.777778) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.365079, 0.444444, 0.444444) ,
+ (1.0, 1.0, 1.0)
+ }
+);
+
+
+list_data brg = list_data(new pen[] {
+ rgb (0.0, 0.0, 1.0) ,
+ rgb (1.0, 0.0, 0.0) ,
+ rgb (0.0, 1.0, 0.0)
+});
+
+
+list_data bwr = list_data(new pen[] {
+ rgb (0.0, 0.0, 1.0) ,
+ rgb (1.0, 1.0, 1.0) ,
+ rgb (1.0, 0.0, 0.0)
+});
+
+
+seg_data cool = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 1.0, 1.0) ,
+ (1.0, 0.0, 0.0)
+ },
+ new triple[] { // blue
+ (0.0, 1.0, 1.0) ,
+ (1.0, 1.0, 1.0)
+ }
+);
+
+
+seg_data coolwarm = seg_data(
+ new triple[] { // red
+ (0.0, 0.2298057, 0.2298057) ,
+ (0.03125, 0.26623388, 0.26623388) ,
+ (0.0625, 0.30386891, 0.30386891) ,
+ (0.09375, 0.342804478, 0.342804478) ,
+ (0.125, 0.38301334, 0.38301334) ,
+ (0.15625, 0.424369608, 0.424369608) ,
+ (0.1875, 0.46666708, 0.46666708) ,
+ (0.21875, 0.509635204, 0.509635204) ,
+ (0.25, 0.552953156, 0.552953156) ,
+ (0.28125, 0.596262162, 0.596262162) ,
+ (0.3125, 0.639176211, 0.639176211) ,
+ (0.34375, 0.681291281, 0.681291281) ,
+ (0.375, 0.722193294, 0.722193294) ,
+ (0.40625, 0.761464949, 0.761464949) ,
+ (0.4375, 0.798691636, 0.798691636) ,
+ (0.46875, 0.833466556, 0.833466556) ,
+ (0.5, 0.865395197, 0.865395197) ,
+ (0.53125, 0.897787179, 0.897787179) ,
+ (0.5625, 0.924127593, 0.924127593) ,
+ (0.59375, 0.944468518, 0.944468518) ,
+ (0.625, 0.958852946, 0.958852946) ,
+ (0.65625, 0.96732803, 0.96732803) ,
+ (0.6875, 0.969954137, 0.969954137) ,
+ (0.71875, 0.966811177, 0.966811177) ,
+ (0.75, 0.958003065, 0.958003065) ,
+ (0.78125, 0.943660866, 0.943660866) ,
+ (0.8125, 0.923944917, 0.923944917) ,
+ (0.84375, 0.89904617, 0.89904617) ,
+ (0.875, 0.869186849, 0.869186849) ,
+ (0.90625, 0.834620542, 0.834620542) ,
+ (0.9375, 0.795631745, 0.795631745) ,
+ (0.96875, 0.752534934, 0.752534934) ,
+ (1.0, 0.705673158, 0.705673158)
+ },
+ new triple[] { // green
+ (0.0, 0.298717966, 0.298717966) ,
+ (0.03125, 0.353094838, 0.353094838) ,
+ (0.0625, 0.406535296, 0.406535296) ,
+ (0.09375, 0.458757618, 0.458757618) ,
+ (0.125, 0.50941904, 0.50941904) ,
+ (0.15625, 0.558148092, 0.558148092) ,
+ (0.1875, 0.604562568, 0.604562568) ,
+ (0.21875, 0.648280772, 0.648280772) ,
+ (0.25, 0.688929332, 0.688929332) ,
+ (0.28125, 0.726149107, 0.726149107) ,
+ (0.3125, 0.759599947, 0.759599947) ,
+ (0.34375, 0.788964712, 0.788964712) ,
+ (0.375, 0.813952739, 0.813952739) ,
+ (0.40625, 0.834302879, 0.834302879) ,
+ (0.4375, 0.849786142, 0.849786142) ,
+ (0.46875, 0.860207984, 0.860207984) ,
+ (0.5, 0.86541021, 0.86541021) ,
+ (0.53125, 0.848937047, 0.848937047) ,
+ (0.5625, 0.827384882, 0.827384882) ,
+ (0.59375, 0.800927443, 0.800927443) ,
+ (0.625, 0.769767752, 0.769767752) ,
+ (0.65625, 0.734132809, 0.734132809) ,
+ (0.6875, 0.694266682, 0.694266682) ,
+ (0.71875, 0.650421156, 0.650421156) ,
+ (0.75, 0.602842431, 0.602842431) ,
+ (0.78125, 0.551750968, 0.551750968) ,
+ (0.8125, 0.49730856, 0.49730856) ,
+ (0.84375, 0.439559467, 0.439559467) ,
+ (0.875, 0.378313092, 0.378313092) ,
+ (0.90625, 0.312874446, 0.312874446) ,
+ (0.9375, 0.24128379, 0.24128379) ,
+ (0.96875, 0.157246067, 0.157246067) ,
+ (1.0, 0.01555616, 0.01555616)
+ },
+ new triple[] { // blue
+ (0.0, 0.753683153, 0.753683153) ,
+ (0.03125, 0.801466763, 0.801466763) ,
+ (0.0625, 0.84495867, 0.84495867) ,
+ (0.09375, 0.883725899, 0.883725899) ,
+ (0.125, 0.917387822, 0.917387822) ,
+ (0.15625, 0.945619588, 0.945619588) ,
+ (0.1875, 0.968154911, 0.968154911) ,
+ (0.21875, 0.98478814, 0.98478814) ,
+ (0.25, 0.995375608, 0.995375608) ,
+ (0.28125, 0.999836203, 0.999836203) ,
+ (0.3125, 0.998151185, 0.998151185) ,
+ (0.34375, 0.990363227, 0.990363227) ,
+ (0.375, 0.976574709, 0.976574709) ,
+ (0.40625, 0.956945269, 0.956945269) ,
+ (0.4375, 0.931688648, 0.931688648) ,
+ (0.46875, 0.901068838, 0.901068838) ,
+ (0.5, 0.865395561, 0.865395561) ,
+ (0.53125, 0.820880546, 0.820880546) ,
+ (0.5625, 0.774508472, 0.774508472) ,
+ (0.59375, 0.726736146, 0.726736146) ,
+ (0.625, 0.678007945, 0.678007945) ,
+ (0.65625, 0.628751763, 0.628751763) ,
+ (0.6875, 0.579375448, 0.579375448) ,
+ (0.71875, 0.530263762, 0.530263762) ,
+ (0.75, 0.481775914, 0.481775914) ,
+ (0.78125, 0.434243684, 0.434243684) ,
+ (0.8125, 0.387970225, 0.387970225) ,
+ (0.84375, 0.343229596, 0.343229596) ,
+ (0.875, 0.300267182, 0.300267182) ,
+ (0.90625, 0.259301199, 0.259301199) ,
+ (0.9375, 0.220525627, 0.220525627) ,
+ (0.96875, 0.184115123, 0.184115123) ,
+ (1.0, 0.150232812, 0.150232812)
+ }
+);
+
+
+seg_data copper = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (0.809524, 1.0, 1.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (1.0, 0.7812, 0.7812)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (1.0, 0.4975, 0.4975)
+ }
+);
+
+
+seg_data gist_earth = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (0.2824, 0.1882, 0.1882) ,
+ (0.4588, 0.2714, 0.2714) ,
+ (0.549, 0.4719, 0.4719) ,
+ (0.698, 0.7176, 0.7176) ,
+ (0.7882, 0.7553, 0.7553) ,
+ (1.0, 0.9922, 0.9922)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.0275, 0.0, 0.0) ,
+ (0.1098, 0.1893, 0.1893) ,
+ (0.1647, 0.3035, 0.3035) ,
+ (0.2078, 0.3841, 0.3841) ,
+ (0.2824, 0.502, 0.502) ,
+ (0.5216, 0.6397, 0.6397) ,
+ (0.698, 0.7171, 0.7171) ,
+ (0.7882, 0.6392, 0.6392) ,
+ (0.7922, 0.6413, 0.6413) ,
+ (0.8, 0.6447, 0.6447) ,
+ (0.8078, 0.6481, 0.6481) ,
+ (0.8157, 0.6549, 0.6549) ,
+ (0.8667, 0.6991, 0.6991) ,
+ (0.8745, 0.7103, 0.7103) ,
+ (0.8824, 0.7216, 0.7216) ,
+ (0.8902, 0.7323, 0.7323) ,
+ (0.898, 0.743, 0.743) ,
+ (0.9412, 0.8275, 0.8275) ,
+ (0.9569, 0.8635, 0.8635) ,
+ (0.9647, 0.8816, 0.8816) ,
+ (0.9961, 0.9733, 0.9733) ,
+ (1.0, 0.9843, 0.9843)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.0039, 0.1684, 0.1684) ,
+ (0.0078, 0.2212, 0.2212) ,
+ (0.0275, 0.4329, 0.4329) ,
+ (0.0314, 0.4549, 0.4549) ,
+ (0.2824, 0.5004, 0.5004) ,
+ (0.4667, 0.2748, 0.2748) ,
+ (0.5451, 0.3205, 0.3205) ,
+ (0.7843, 0.3961, 0.3961) ,
+ (0.8941, 0.6651, 0.6651) ,
+ (1.0, 0.9843, 0.9843)
+ }
+);
+
+
+seg_data gist_ncar = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (0.3098, 0.0, 0.0) ,
+ (0.3725, 0.3993, 0.3993) ,
+ (0.4235, 0.5003, 0.5003) ,
+ (0.5333, 1.0, 1.0) ,
+ (0.7922, 1.0, 1.0) ,
+ (0.8471, 0.6218, 0.6218) ,
+ (0.898, 0.9235, 0.9235) ,
+ (1.0, 0.9961, 0.9961)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.051, 0.3722, 0.3722) ,
+ (0.1059, 0.0, 0.0) ,
+ (0.1569, 0.7202, 0.7202) ,
+ (0.1608, 0.7537, 0.7537) ,
+ (0.1647, 0.7752, 0.7752) ,
+ (0.2157, 1.0, 1.0) ,
+ (0.2588, 0.9804, 0.9804) ,
+ (0.2706, 0.9804, 0.9804) ,
+ (0.3176, 1.0, 1.0) ,
+ (0.3686, 0.8081, 0.8081) ,
+ (0.4275, 1.0, 1.0) ,
+ (0.5216, 1.0, 1.0) ,
+ (0.6314, 0.7292, 0.7292) ,
+ (0.6863, 0.2796, 0.2796) ,
+ (0.7451, 0.0, 0.0) ,
+ (0.7922, 0.0, 0.0) ,
+ (0.8431, 0.1753, 0.1753) ,
+ (0.898, 0.5, 0.5) ,
+ (1.0, 0.9725, 0.9725)
+ },
+ new triple[] { // blue
+ (0.0, 0.502, 0.502) ,
+ (0.051, 0.0222, 0.0222) ,
+ (0.1098, 1.0, 1.0) ,
+ (0.2039, 1.0, 1.0) ,
+ (0.2627, 0.6145, 0.6145) ,
+ (0.3216, 0.0, 0.0) ,
+ (0.4157, 0.0, 0.0) ,
+ (0.4745, 0.2342, 0.2342) ,
+ (0.5333, 0.0, 0.0) ,
+ (0.5804, 0.0, 0.0) ,
+ (0.6314, 0.0549, 0.0549) ,
+ (0.6902, 0.0, 0.0) ,
+ (0.7373, 0.0, 0.0) ,
+ (0.7922, 0.9738, 0.9738) ,
+ (0.8, 1.0, 1.0) ,
+ (0.8431, 1.0, 1.0) ,
+ (0.898, 0.9341, 0.9341) ,
+ (1.0, 0.9961, 0.9961)
+ }
+);
+
+
+seg_data gist_stern = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (0.0547, 1.0, 1.0) ,
+ (0.25, 0.027, 0.25) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0, 0, 0) ,
+ (1, 1, 1)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.5, 1.0, 1.0) ,
+ (0.735, 0.0, 0.0) ,
+ (1.0, 1.0, 1.0)
+ }
+);
+
+
+seg_data gray = seg_data(
+ new triple[] { // red
+ (0.0, 0, 0) ,
+ (1.0, 1, 1)
+ },
+ new triple[] { // green
+ (0.0, 0, 0) ,
+ (1.0, 1, 1)
+ },
+ new triple[] { // blue
+ (0.0, 0, 0) ,
+ (1.0, 1, 1)
+ }
+);
+
+
+seg_data hot = seg_data(
+ new triple[] { // red
+ (0.0, 0.0416, 0.0416) ,
+ (0.365079, 1.0, 1.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.365079, 0.0, 0.0) ,
+ (0.746032, 1.0, 1.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.746032, 0.0, 0.0) ,
+ (1.0, 1.0, 1.0)
+ }
+);
+
+
+seg_data hsv = seg_data(
+ new triple[] { // red
+ (0.0, 1.0, 1.0) ,
+ (0.15873, 1.0, 1.0) ,
+ (0.174603, 0.96875, 0.96875) ,
+ (0.333333, 0.03125, 0.03125) ,
+ (0.349206, 0.0, 0.0) ,
+ (0.666667, 0.0, 0.0) ,
+ (0.68254, 0.03125, 0.03125) ,
+ (0.84127, 0.96875, 0.96875) ,
+ (0.857143, 1.0, 1.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.15873, 0.9375, 0.9375) ,
+ (0.174603, 1.0, 1.0) ,
+ (0.507937, 1.0, 1.0) ,
+ (0.666667, 0.0625, 0.0625) ,
+ (0.68254, 0.0, 0.0) ,
+ (1.0, 0.0, 0.0)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.333333, 0.0, 0.0) ,
+ (0.349206, 0.0625, 0.0625) ,
+ (0.507937, 1.0, 1.0) ,
+ (0.84127, 1.0, 1.0) ,
+ (0.857143, 0.9375, 0.9375) ,
+ (1.0, 0.09375, 0.09375)
+ }
+);
+
+
+seg_data jet = seg_data(
+ new triple[] { // red
+ (0.0, 0, 0) ,
+ (0.35, 0, 0) ,
+ (0.66, 1, 1) ,
+ (0.89, 1, 1) ,
+ (1, 0.5, 0.5)
+ },
+ new triple[] { // green
+ (0.0, 0, 0) ,
+ (0.125, 0, 0) ,
+ (0.375, 1, 1) ,
+ (0.64, 1, 1) ,
+ (0.91, 0, 0) ,
+ (1, 0, 0)
+ },
+ new triple[] { // blue
+ (0.0, 0.5, 0.5) ,
+ (0.11, 1, 1) ,
+ (0.34, 1, 1) ,
+ (0.65, 0, 0) ,
+ (1, 0, 0)
+ }
+);
+
+
+seg_data nipy_spectral = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (0.05, 0.4667, 0.4667) ,
+ (0.1, 0.5333, 0.5333) ,
+ (0.15, 0.0, 0.0) ,
+ (0.2, 0.0, 0.0) ,
+ (0.25, 0.0, 0.0) ,
+ (0.3, 0.0, 0.0) ,
+ (0.35, 0.0, 0.0) ,
+ (0.4, 0.0, 0.0) ,
+ (0.45, 0.0, 0.0) ,
+ (0.5, 0.0, 0.0) ,
+ (0.55, 0.0, 0.0) ,
+ (0.6, 0.0, 0.0) ,
+ (0.65, 0.7333, 0.7333) ,
+ (0.7, 0.9333, 0.9333) ,
+ (0.75, 1.0, 1.0) ,
+ (0.8, 1.0, 1.0) ,
+ (0.85, 1.0, 1.0) ,
+ (0.9, 0.8667, 0.8667) ,
+ (0.95, 0.8, 0.8) ,
+ (1.0, 0.8, 0.8)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.05, 0.0, 0.0) ,
+ (0.1, 0.0, 0.0) ,
+ (0.15, 0.0, 0.0) ,
+ (0.2, 0.0, 0.0) ,
+ (0.25, 0.4667, 0.4667) ,
+ (0.3, 0.6, 0.6) ,
+ (0.35, 0.6667, 0.6667) ,
+ (0.4, 0.6667, 0.6667) ,
+ (0.45, 0.6, 0.6) ,
+ (0.5, 0.7333, 0.7333) ,
+ (0.55, 0.8667, 0.8667) ,
+ (0.6, 1.0, 1.0) ,
+ (0.65, 1.0, 1.0) ,
+ (0.7, 0.9333, 0.9333) ,
+ (0.75, 0.8, 0.8) ,
+ (0.8, 0.6, 0.6) ,
+ (0.85, 0.0, 0.0) ,
+ (0.9, 0.0, 0.0) ,
+ (0.95, 0.0, 0.0) ,
+ (1.0, 0.8, 0.8)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.05, 0.5333, 0.5333) ,
+ (0.1, 0.6, 0.6) ,
+ (0.15, 0.6667, 0.6667) ,
+ (0.2, 0.8667, 0.8667) ,
+ (0.25, 0.8667, 0.8667) ,
+ (0.3, 0.8667, 0.8667) ,
+ (0.35, 0.6667, 0.6667) ,
+ (0.4, 0.5333, 0.5333) ,
+ (0.45, 0.0, 0.0) ,
+ (0.5, 0.0, 0.0) ,
+ (0.55, 0.0, 0.0) ,
+ (0.6, 0.0, 0.0) ,
+ (0.65, 0.0, 0.0) ,
+ (0.7, 0.0, 0.0) ,
+ (0.75, 0.0, 0.0) ,
+ (0.8, 0.0, 0.0) ,
+ (0.85, 0.0, 0.0) ,
+ (0.9, 0.0, 0.0) ,
+ (0.95, 0.0, 0.0) ,
+ (1.0, 0.8, 0.8)
+ }
+);
+
+
+seg_data pink = seg_data(
+ new triple[] { // red
+ (0.0, 0.1178, 0.1178) ,
+ (0.015873, 0.195857, 0.195857) ,
+ (0.031746, 0.250661, 0.250661) ,
+ (0.047619, 0.295468, 0.295468) ,
+ (0.063492, 0.334324, 0.334324) ,
+ (0.079365, 0.369112, 0.369112) ,
+ (0.095238, 0.400892, 0.400892) ,
+ (0.111111, 0.430331, 0.430331) ,
+ (0.126984, 0.457882, 0.457882) ,
+ (0.142857, 0.483867, 0.483867) ,
+ (0.15873, 0.508525, 0.508525) ,
+ (0.174603, 0.532042, 0.532042) ,
+ (0.190476, 0.554563, 0.554563) ,
+ (0.206349, 0.576204, 0.576204) ,
+ (0.222222, 0.597061, 0.597061) ,
+ (0.238095, 0.617213, 0.617213) ,
+ (0.253968, 0.636729, 0.636729) ,
+ (0.269841, 0.655663, 0.655663) ,
+ (0.285714, 0.674066, 0.674066) ,
+ (0.301587, 0.69198, 0.69198) ,
+ (0.31746, 0.709441, 0.709441) ,
+ (0.333333, 0.726483, 0.726483) ,
+ (0.349206, 0.743134, 0.743134) ,
+ (0.365079, 0.759421, 0.759421) ,
+ (0.380952, 0.766356, 0.766356) ,
+ (0.396825, 0.773229, 0.773229) ,
+ (0.412698, 0.780042, 0.780042) ,
+ (0.428571, 0.786796, 0.786796) ,
+ (0.444444, 0.793492, 0.793492) ,
+ (0.460317, 0.800132, 0.800132) ,
+ (0.47619, 0.806718, 0.806718) ,
+ (0.492063, 0.81325, 0.81325) ,
+ (0.507937, 0.81973, 0.81973) ,
+ (0.52381, 0.82616, 0.82616) ,
+ (0.539683, 0.832539, 0.832539) ,
+ (0.555556, 0.83887, 0.83887) ,
+ (0.571429, 0.845154, 0.845154) ,
+ (0.587302, 0.851392, 0.851392) ,
+ (0.603175, 0.857584, 0.857584) ,
+ (0.619048, 0.863731, 0.863731) ,
+ (0.634921, 0.869835, 0.869835) ,
+ (0.650794, 0.875897, 0.875897) ,
+ (0.666667, 0.881917, 0.881917) ,
+ (0.68254, 0.887896, 0.887896) ,
+ (0.698413, 0.893835, 0.893835) ,
+ (0.714286, 0.899735, 0.899735) ,
+ (0.730159, 0.905597, 0.905597) ,
+ (0.746032, 0.911421, 0.911421) ,
+ (0.761905, 0.917208, 0.917208) ,
+ (0.777778, 0.922958, 0.922958) ,
+ (0.793651, 0.928673, 0.928673) ,
+ (0.809524, 0.934353, 0.934353) ,
+ (0.825397, 0.939999, 0.939999) ,
+ (0.84127, 0.945611, 0.945611) ,
+ (0.857143, 0.95119, 0.95119) ,
+ (0.873016, 0.956736, 0.956736) ,
+ (0.888889, 0.96225, 0.96225) ,
+ (0.904762, 0.967733, 0.967733) ,
+ (0.920635, 0.973185, 0.973185) ,
+ (0.936508, 0.978607, 0.978607) ,
+ (0.952381, 0.983999, 0.983999) ,
+ (0.968254, 0.989361, 0.989361) ,
+ (0.984127, 0.994695, 0.994695) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (0.015873, 0.102869, 0.102869) ,
+ (0.031746, 0.145479, 0.145479) ,
+ (0.047619, 0.178174, 0.178174) ,
+ (0.063492, 0.205738, 0.205738) ,
+ (0.079365, 0.230022, 0.230022) ,
+ (0.095238, 0.251976, 0.251976) ,
+ (0.111111, 0.272166, 0.272166) ,
+ (0.126984, 0.290957, 0.290957) ,
+ (0.142857, 0.308607, 0.308607) ,
+ (0.15873, 0.3253, 0.3253) ,
+ (0.174603, 0.341178, 0.341178) ,
+ (0.190476, 0.356348, 0.356348) ,
+ (0.206349, 0.370899, 0.370899) ,
+ (0.222222, 0.3849, 0.3849) ,
+ (0.238095, 0.39841, 0.39841) ,
+ (0.253968, 0.411476, 0.411476) ,
+ (0.269841, 0.424139, 0.424139) ,
+ (0.285714, 0.436436, 0.436436) ,
+ (0.301587, 0.448395, 0.448395) ,
+ (0.31746, 0.460044, 0.460044) ,
+ (0.333333, 0.471405, 0.471405) ,
+ (0.349206, 0.482498, 0.482498) ,
+ (0.365079, 0.493342, 0.493342) ,
+ (0.380952, 0.517549, 0.517549) ,
+ (0.396825, 0.540674, 0.540674) ,
+ (0.412698, 0.562849, 0.562849) ,
+ (0.428571, 0.584183, 0.584183) ,
+ (0.444444, 0.604765, 0.604765) ,
+ (0.460317, 0.624669, 0.624669) ,
+ (0.47619, 0.643958, 0.643958) ,
+ (0.492063, 0.662687, 0.662687) ,
+ (0.507937, 0.6809, 0.6809) ,
+ (0.52381, 0.698638, 0.698638) ,
+ (0.539683, 0.715937, 0.715937) ,
+ (0.555556, 0.732828, 0.732828) ,
+ (0.571429, 0.749338, 0.749338) ,
+ (0.587302, 0.765493, 0.765493) ,
+ (0.603175, 0.781313, 0.781313) ,
+ (0.619048, 0.796819, 0.796819) ,
+ (0.634921, 0.812029, 0.812029) ,
+ (0.650794, 0.82696, 0.82696) ,
+ (0.666667, 0.841625, 0.841625) ,
+ (0.68254, 0.85604, 0.85604) ,
+ (0.698413, 0.870216, 0.870216) ,
+ (0.714286, 0.884164, 0.884164) ,
+ (0.730159, 0.897896, 0.897896) ,
+ (0.746032, 0.911421, 0.911421) ,
+ (0.761905, 0.917208, 0.917208) ,
+ (0.777778, 0.922958, 0.922958) ,
+ (0.793651, 0.928673, 0.928673) ,
+ (0.809524, 0.934353, 0.934353) ,
+ (0.825397, 0.939999, 0.939999) ,
+ (0.84127, 0.945611, 0.945611) ,
+ (0.857143, 0.95119, 0.95119) ,
+ (0.873016, 0.956736, 0.956736) ,
+ (0.888889, 0.96225, 0.96225) ,
+ (0.904762, 0.967733, 0.967733) ,
+ (0.920635, 0.973185, 0.973185) ,
+ (0.936508, 0.978607, 0.978607) ,
+ (0.952381, 0.983999, 0.983999) ,
+ (0.968254, 0.989361, 0.989361) ,
+ (0.984127, 0.994695, 0.994695) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 0.0, 0.0) ,
+ (0.015873, 0.102869, 0.102869) ,
+ (0.031746, 0.145479, 0.145479) ,
+ (0.047619, 0.178174, 0.178174) ,
+ (0.063492, 0.205738, 0.205738) ,
+ (0.079365, 0.230022, 0.230022) ,
+ (0.095238, 0.251976, 0.251976) ,
+ (0.111111, 0.272166, 0.272166) ,
+ (0.126984, 0.290957, 0.290957) ,
+ (0.142857, 0.308607, 0.308607) ,
+ (0.15873, 0.3253, 0.3253) ,
+ (0.174603, 0.341178, 0.341178) ,
+ (0.190476, 0.356348, 0.356348) ,
+ (0.206349, 0.370899, 0.370899) ,
+ (0.222222, 0.3849, 0.3849) ,
+ (0.238095, 0.39841, 0.39841) ,
+ (0.253968, 0.411476, 0.411476) ,
+ (0.269841, 0.424139, 0.424139) ,
+ (0.285714, 0.436436, 0.436436) ,
+ (0.301587, 0.448395, 0.448395) ,
+ (0.31746, 0.460044, 0.460044) ,
+ (0.333333, 0.471405, 0.471405) ,
+ (0.349206, 0.482498, 0.482498) ,
+ (0.365079, 0.493342, 0.493342) ,
+ (0.380952, 0.503953, 0.503953) ,
+ (0.396825, 0.514344, 0.514344) ,
+ (0.412698, 0.524531, 0.524531) ,
+ (0.428571, 0.534522, 0.534522) ,
+ (0.444444, 0.544331, 0.544331) ,
+ (0.460317, 0.553966, 0.553966) ,
+ (0.47619, 0.563436, 0.563436) ,
+ (0.492063, 0.57275, 0.57275) ,
+ (0.507937, 0.581914, 0.581914) ,
+ (0.52381, 0.590937, 0.590937) ,
+ (0.539683, 0.599824, 0.599824) ,
+ (0.555556, 0.608581, 0.608581) ,
+ (0.571429, 0.617213, 0.617213) ,
+ (0.587302, 0.625727, 0.625727) ,
+ (0.603175, 0.634126, 0.634126) ,
+ (0.619048, 0.642416, 0.642416) ,
+ (0.634921, 0.6506, 0.6506) ,
+ (0.650794, 0.658682, 0.658682) ,
+ (0.666667, 0.666667, 0.666667) ,
+ (0.68254, 0.674556, 0.674556) ,
+ (0.698413, 0.682355, 0.682355) ,
+ (0.714286, 0.690066, 0.690066) ,
+ (0.730159, 0.697691, 0.697691) ,
+ (0.746032, 0.705234, 0.705234) ,
+ (0.761905, 0.727166, 0.727166) ,
+ (0.777778, 0.748455, 0.748455) ,
+ (0.793651, 0.769156, 0.769156) ,
+ (0.809524, 0.789314, 0.789314) ,
+ (0.825397, 0.808969, 0.808969) ,
+ (0.84127, 0.828159, 0.828159) ,
+ (0.857143, 0.846913, 0.846913) ,
+ (0.873016, 0.865261, 0.865261) ,
+ (0.888889, 0.883229, 0.883229) ,
+ (0.904762, 0.900837, 0.900837) ,
+ (0.920635, 0.918109, 0.918109) ,
+ (0.936508, 0.935061, 0.935061) ,
+ (0.952381, 0.951711, 0.951711) ,
+ (0.968254, 0.968075, 0.968075) ,
+ (0.984127, 0.984167, 0.984167) ,
+ (1.0, 1.0, 1.0)
+ }
+);
+
+
+list_data seismic = list_data(new pen[] {
+ rgb (0.0, 0.0, 0.3) ,
+ rgb (0.0, 0.0, 1.0) ,
+ rgb (1.0, 1.0, 1.0) ,
+ rgb (1.0, 0.0, 0.0) ,
+ rgb (0.5, 0.0, 0.0)
+});
+
+
+seg_data spring = seg_data(
+ new triple[] { // red
+ (0.0, 1.0, 1.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 1.0, 1.0) ,
+ (1.0, 0.0, 0.0)
+ }
+);
+
+
+seg_data summer = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // green
+ (0.0, 0.5, 0.5) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 0.4, 0.4) ,
+ (1.0, 0.4, 0.4)
+ }
+);
+
+
+list_data tab10 = list_data(new pen[] {
+ rgb (0.12156862745098039, 0.4666666666666667, 0.7058823529411765) ,
+ rgb (1.0, 0.4980392156862745, 0.054901960784313725) ,
+ rgb (0.17254901960784313, 0.6274509803921569, 0.17254901960784313) ,
+ rgb (0.8392156862745098, 0.15294117647058825, 0.1568627450980392) ,
+ rgb (0.5803921568627451, 0.403921568627451, 0.7411764705882353) ,
+ rgb (0.5490196078431373, 0.33725490196078434, 0.29411764705882354) ,
+ rgb (0.8901960784313725, 0.4666666666666667, 0.7607843137254902) ,
+ rgb (0.4980392156862745, 0.4980392156862745, 0.4980392156862745) ,
+ rgb (0.7372549019607844, 0.7411764705882353, 0.13333333333333333) ,
+ rgb (0.09019607843137255, 0.7450980392156863, 0.8117647058823529)
+});
+
+
+list_data tab20 = list_data(new pen[] {
+ rgb (0.12156862745098039, 0.4666666666666667, 0.7058823529411765) ,
+ rgb (0.6823529411764706, 0.7803921568627451, 0.9098039215686274) ,
+ rgb (1.0, 0.4980392156862745, 0.054901960784313725) ,
+ rgb (1.0, 0.7333333333333333, 0.47058823529411764) ,
+ rgb (0.17254901960784313, 0.6274509803921569, 0.17254901960784313) ,
+ rgb (0.596078431372549, 0.8745098039215686, 0.5411764705882353) ,
+ rgb (0.8392156862745098, 0.15294117647058825, 0.1568627450980392) ,
+ rgb (1.0, 0.596078431372549, 0.5882352941176471) ,
+ rgb (0.5803921568627451, 0.403921568627451, 0.7411764705882353) ,
+ rgb (0.7725490196078432, 0.6901960784313725, 0.8352941176470589) ,
+ rgb (0.5490196078431373, 0.33725490196078434, 0.29411764705882354) ,
+ rgb (0.7686274509803922, 0.611764705882353, 0.5803921568627451) ,
+ rgb (0.8901960784313725, 0.4666666666666667, 0.7607843137254902) ,
+ rgb (0.9686274509803922, 0.7137254901960784, 0.8235294117647058) ,
+ rgb (0.4980392156862745, 0.4980392156862745, 0.4980392156862745) ,
+ rgb (0.7803921568627451, 0.7803921568627451, 0.7803921568627451) ,
+ rgb (0.7372549019607844, 0.7411764705882353, 0.13333333333333333) ,
+ rgb (0.8588235294117647, 0.8588235294117647, 0.5529411764705883) ,
+ rgb (0.09019607843137255, 0.7450980392156863, 0.8117647058823529) ,
+ rgb (0.6196078431372549, 0.8549019607843137, 0.8980392156862745)
+});
+
+
+list_data tab20b = list_data(new pen[] {
+ rgb (0.2235294117647059, 0.23137254901960785, 0.4745098039215686) ,
+ rgb (0.3215686274509804, 0.32941176470588235, 0.6392156862745098) ,
+ rgb (0.4196078431372549, 0.43137254901960786, 0.8117647058823529) ,
+ rgb (0.611764705882353, 0.6196078431372549, 0.8705882352941177) ,
+ rgb (0.38823529411764707, 0.4745098039215686, 0.2235294117647059) ,
+ rgb (0.5490196078431373, 0.6352941176470588, 0.3215686274509804) ,
+ rgb (0.7098039215686275, 0.8117647058823529, 0.4196078431372549) ,
+ rgb (0.807843137254902, 0.8588235294117647, 0.611764705882353) ,
+ rgb (0.5490196078431373, 0.42745098039215684, 0.19215686274509805) ,
+ rgb (0.7411764705882353, 0.6196078431372549, 0.2235294117647059) ,
+ rgb (0.9058823529411765, 0.7294117647058823, 0.3215686274509804) ,
+ rgb (0.9058823529411765, 0.796078431372549, 0.5803921568627451) ,
+ rgb (0.5176470588235295, 0.23529411764705882, 0.2235294117647059) ,
+ rgb (0.6784313725490196, 0.28627450980392155, 0.2901960784313726) ,
+ rgb (0.8392156862745098, 0.3803921568627451, 0.4196078431372549) ,
+ rgb (0.9058823529411765, 0.5882352941176471, 0.611764705882353) ,
+ rgb (0.4823529411764706, 0.2549019607843137, 0.45098039215686275) ,
+ rgb (0.6470588235294118, 0.3176470588235294, 0.5803921568627451) ,
+ rgb (0.807843137254902, 0.42745098039215684, 0.7411764705882353) ,
+ rgb (0.8705882352941177, 0.6196078431372549, 0.8392156862745098)
+});
+
+
+list_data tab20c = list_data(new pen[] {
+ rgb (0.19215686274509805, 0.5098039215686274, 0.7411764705882353) ,
+ rgb (0.4196078431372549, 0.6823529411764706, 0.8392156862745098) ,
+ rgb (0.6196078431372549, 0.792156862745098, 0.8823529411764706) ,
+ rgb (0.7764705882352941, 0.8588235294117647, 0.9372549019607843) ,
+ rgb (0.9019607843137255, 0.3333333333333333, 0.050980392156862744) ,
+ rgb (0.9921568627450981, 0.5529411764705883, 0.23529411764705882) ,
+ rgb (0.9921568627450981, 0.6823529411764706, 0.4196078431372549) ,
+ rgb (0.9921568627450981, 0.8156862745098039, 0.6352941176470588) ,
+ rgb (0.19215686274509805, 0.6392156862745098, 0.32941176470588235) ,
+ rgb (0.4549019607843137, 0.7686274509803922, 0.4627450980392157) ,
+ rgb (0.6313725490196078, 0.8509803921568627, 0.6078431372549019) ,
+ rgb (0.7803921568627451, 0.9137254901960784, 0.7529411764705882) ,
+ rgb (0.4588235294117647, 0.4196078431372549, 0.6941176470588235) ,
+ rgb (0.6196078431372549, 0.6039215686274509, 0.7843137254901961) ,
+ rgb (0.7372549019607844, 0.7411764705882353, 0.8627450980392157) ,
+ rgb (0.8549019607843137, 0.8549019607843137, 0.9215686274509803) ,
+ rgb (0.38823529411764707, 0.38823529411764707, 0.38823529411764707) ,
+ rgb (0.5882352941176471, 0.5882352941176471, 0.5882352941176471) ,
+ rgb (0.7411764705882353, 0.7411764705882353, 0.7411764705882353) ,
+ rgb (0.8509803921568627, 0.8509803921568627, 0.8509803921568627)
+});
+
+
+seg_data winter = seg_data(
+ new triple[] { // red
+ (0.0, 0.0, 0.0) ,
+ (1.0, 0.0, 0.0)
+ },
+ new triple[] { // green
+ (0.0, 0.0, 0.0) ,
+ (1.0, 1.0, 1.0)
+ },
+ new triple[] { // blue
+ (0.0, 1.0, 1.0) ,
+ (1.0, 0.5, 0.5)
+ }
+);
+
+
+seg_data wistia = seg_data(
+ new triple[] { // red
+ (0.0, 0.8941176470588236, 0.8941176470588236) ,
+ (0.25, 1.0, 1.0) ,
+ (0.5, 1.0, 1.0) ,
+ (0.75, 1.0, 1.0) ,
+ (1.0, 0.9882352941176471, 0.9882352941176471)
+ },
+ new triple[] { // green
+ (0.0, 1.0, 1.0) ,
+ (0.25, 0.9098039215686274, 0.9098039215686274) ,
+ (0.5, 0.7411764705882353, 0.7411764705882353) ,
+ (0.75, 0.6274509803921569, 0.6274509803921569) ,
+ (1.0, 0.4980392156862745, 0.4980392156862745)
+ },
+ new triple[] { // blue
+ (0.0, 0.47843137254901963, 0.47843137254901963) ,
+ (0.25, 0.10196078431372549, 0.10196078431372549) ,
+ (0.5, 0.0, 0.0) ,
+ (0.75, 0.0, 0.0) ,
+ (1.0, 0.0, 0.0)
+ }
+);
+
+
+list_data cividis = list_data(new pen[] {
+ rgb (0.0, 0.135112, 0.304751) ,
+ rgb (0.0, 0.138068, 0.311105) ,
+ rgb (0.0, 0.141013, 0.317579) ,
+ rgb (0.0, 0.143951, 0.323982) ,
+ rgb (0.0, 0.146877, 0.330479) ,
+ rgb (0.0, 0.149791, 0.337065) ,
+ rgb (0.0, 0.152673, 0.343704) ,
+ rgb (0.0, 0.155377, 0.3505) ,
+ rgb (0.0, 0.157932, 0.357521) ,
+ rgb (0.0, 0.160495, 0.364534) ,
+ rgb (0.0, 0.163058, 0.371608) ,
+ rgb (0.0, 0.165621, 0.378769) ,
+ rgb (0.0, 0.168204, 0.385902) ,
+ rgb (0.0, 0.1708, 0.3931) ,
+ rgb (0.0, 0.17342, 0.400353) ,
+ rgb (0.0, 0.176082, 0.407577) ,
+ rgb (0.0, 0.178802, 0.414764) ,
+ rgb (0.0, 0.18161, 0.421859) ,
+ rgb (0.0, 0.18455, 0.428802) ,
+ rgb (0.0, 0.186915, 0.435532) ,
+ rgb (0.0, 0.188769, 0.439563) ,
+ rgb (0.0, 0.19095, 0.441085) ,
+ rgb (0.0, 0.193366, 0.441561) ,
+ rgb (0.003602, 0.195911, 0.441564) ,
+ rgb (0.017852, 0.198528, 0.441248) ,
+ rgb (0.03211, 0.201199, 0.440785) ,
+ rgb (0.046205, 0.203903, 0.440196) ,
+ rgb (0.058378, 0.206629, 0.439531) ,
+ rgb (0.068968, 0.209372, 0.438863) ,
+ rgb (0.078624, 0.212122, 0.438105) ,
+ rgb (0.087465, 0.214879, 0.437342) ,
+ rgb (0.095645, 0.217643, 0.436593) ,
+ rgb (0.103401, 0.220406, 0.43579) ,
+ rgb (0.110658, 0.22317, 0.435067) ,
+ rgb (0.117612, 0.225935, 0.434308) ,
+ rgb (0.124291, 0.228697, 0.433547) ,
+ rgb (0.130669, 0.231458, 0.43284) ,
+ rgb (0.13683, 0.234216, 0.432148) ,
+ rgb (0.142852, 0.236972, 0.431404) ,
+ rgb (0.148638, 0.239724, 0.430752) ,
+ rgb (0.154261, 0.242475, 0.43012) ,
+ rgb (0.159733, 0.245221, 0.429528) ,
+ rgb (0.165113, 0.247965, 0.428908) ,
+ rgb (0.170362, 0.250707, 0.428325) ,
+ rgb (0.17549, 0.253444, 0.42779) ,
+ rgb (0.180503, 0.25618, 0.427299) ,
+ rgb (0.185453, 0.258914, 0.426788) ,
+ rgb (0.190303, 0.261644, 0.426329) ,
+ rgb (0.195057, 0.264372, 0.425924) ,
+ rgb (0.199764, 0.267099, 0.425497) ,
+ rgb (0.204385, 0.269823, 0.425126) ,
+ rgb (0.208926, 0.272546, 0.424809) ,
+ rgb (0.213431, 0.275266, 0.42448) ,
+ rgb (0.217863, 0.277985, 0.424206) ,
+ rgb (0.222264, 0.280702, 0.423914) ,
+ rgb (0.226598, 0.283419, 0.423678) ,
+ rgb (0.230871, 0.286134, 0.423498) ,
+ rgb (0.23512, 0.288848, 0.423304) ,
+ rgb (0.239312, 0.291562, 0.423167) ,
+ rgb (0.243485, 0.294274, 0.423014) ,
+ rgb (0.247605, 0.296986, 0.422917) ,
+ rgb (0.251675, 0.299698, 0.422873) ,
+ rgb (0.255731, 0.302409, 0.422814) ,
+ rgb (0.25974, 0.30512, 0.42281) ,
+ rgb (0.263738, 0.307831, 0.422789) ,
+ rgb (0.267693, 0.310542, 0.422821) ,
+ rgb (0.271639, 0.313253, 0.422837) ,
+ rgb (0.275513, 0.315965, 0.422979) ,
+ rgb (0.279411, 0.318677, 0.423031) ,
+ rgb (0.28324, 0.32139, 0.423211) ,
+ rgb (0.287065, 0.324103, 0.423373) ,
+ rgb (0.290884, 0.326816, 0.423517) ,
+ rgb (0.294669, 0.329531, 0.423716) ,
+ rgb (0.298421, 0.332247, 0.423973) ,
+ rgb (0.302169, 0.334963, 0.424213) ,
+ rgb (0.305886, 0.337681, 0.424512) ,
+ rgb (0.309601, 0.340399, 0.42479) ,
+ rgb (0.313287, 0.34312, 0.42512) ,
+ rgb (0.316941, 0.345842, 0.425512) ,
+ rgb (0.320595, 0.348565, 0.425889) ,
+ rgb (0.32425, 0.351289, 0.42625) ,
+ rgb (0.327875, 0.354016, 0.42667) ,
+ rgb (0.331474, 0.356744, 0.427144) ,
+ rgb (0.335073, 0.359474, 0.427605) ,
+ rgb (0.338673, 0.362206, 0.428053) ,
+ rgb (0.342246, 0.364939, 0.428559) ,
+ rgb (0.345793, 0.367676, 0.429127) ,
+ rgb (0.349341, 0.370414, 0.429685) ,
+ rgb (0.352892, 0.373153, 0.430226) ,
+ rgb (0.356418, 0.375896, 0.430823) ,
+ rgb (0.359916, 0.378641, 0.431501) ,
+ rgb (0.363446, 0.381388, 0.432075) ,
+ rgb (0.366923, 0.384139, 0.432796) ,
+ rgb (0.37043, 0.38689, 0.433428) ,
+ rgb (0.373884, 0.389646, 0.434209) ,
+ rgb (0.377371, 0.392404, 0.43489) ,
+ rgb (0.38083, 0.395164, 0.435653) ,
+ rgb (0.384268, 0.397928, 0.436475) ,
+ rgb (0.387705, 0.400694, 0.437305) ,
+ rgb (0.391151, 0.403464, 0.438096) ,
+ rgb (0.394568, 0.406236, 0.438986) ,
+ rgb (0.397991, 0.409011, 0.439848) ,
+ rgb (0.401418, 0.41179, 0.440708) ,
+ rgb (0.40482, 0.414572, 0.441642) ,
+ rgb (0.408226, 0.417357, 0.44257) ,
+ rgb (0.411607, 0.420145, 0.443577) ,
+ rgb (0.414992, 0.422937, 0.444578) ,
+ rgb (0.418383, 0.425733, 0.44556) ,
+ rgb (0.421748, 0.428531, 0.44664) ,
+ rgb (0.42512, 0.431334, 0.447692) ,
+ rgb (0.428462, 0.43414, 0.448864) ,
+ rgb (0.431817, 0.43695, 0.449982) ,
+ rgb (0.435168, 0.439763, 0.451134) ,
+ rgb (0.438504, 0.44258, 0.452341) ,
+ rgb (0.44181, 0.445402, 0.453659) ,
+ rgb (0.445148, 0.448226, 0.454885) ,
+ rgb (0.448447, 0.451053, 0.456264) ,
+ rgb (0.451759, 0.453887, 0.457582) ,
+ rgb (0.455072, 0.456718, 0.458976) ,
+ rgb (0.458366, 0.459552, 0.460457) ,
+ rgb (0.461616, 0.462405, 0.461969) ,
+ rgb (0.464947, 0.465241, 0.463395) ,
+ rgb (0.468254, 0.468083, 0.464908) ,
+ rgb (0.471501, 0.47096, 0.466357) ,
+ rgb (0.474812, 0.473832, 0.467681) ,
+ rgb (0.478186, 0.476699, 0.468845) ,
+ rgb (0.481622, 0.479573, 0.469767) ,
+ rgb (0.485141, 0.482451, 0.470384) ,
+ rgb (0.488697, 0.485318, 0.471008) ,
+ rgb (0.492278, 0.488198, 0.471453) ,
+ rgb (0.495913, 0.491076, 0.471751) ,
+ rgb (0.499552, 0.49396, 0.472032) ,
+ rgb (0.503185, 0.496851, 0.472305) ,
+ rgb (0.506866, 0.499743, 0.472432) ,
+ rgb (0.51054, 0.502643, 0.47255) ,
+ rgb (0.514226, 0.505546, 0.47264) ,
+ rgb (0.51792, 0.508454, 0.472707) ,
+ rgb (0.521643, 0.511367, 0.472639) ,
+ rgb (0.525348, 0.514285, 0.47266) ,
+ rgb (0.529086, 0.517207, 0.472543) ,
+ rgb (0.532829, 0.520135, 0.472401) ,
+ rgb (0.536553, 0.523067, 0.472352) ,
+ rgb (0.540307, 0.526005, 0.472163) ,
+ rgb (0.544069, 0.528948, 0.471947) ,
+ rgb (0.54784, 0.531895, 0.471704) ,
+ rgb (0.551612, 0.534849, 0.471439) ,
+ rgb (0.555393, 0.537807, 0.471147) ,
+ rgb (0.559181, 0.540771, 0.470829) ,
+ rgb (0.562972, 0.543741, 0.470488) ,
+ rgb (0.566802, 0.546715, 0.469988) ,
+ rgb (0.570607, 0.549695, 0.469593) ,
+ rgb (0.574417, 0.552682, 0.469172) ,
+ rgb (0.578236, 0.555673, 0.468724) ,
+ rgb (0.582087, 0.55867, 0.468118) ,
+ rgb (0.585916, 0.561674, 0.467618) ,
+ rgb (0.589753, 0.564682, 0.46709) ,
+ rgb (0.593622, 0.567697, 0.466401) ,
+ rgb (0.597469, 0.570718, 0.465821) ,
+ rgb (0.601354, 0.573743, 0.465074) ,
+ rgb (0.605211, 0.576777, 0.464441) ,
+ rgb (0.609105, 0.579816, 0.463638) ,
+ rgb (0.612977, 0.582861, 0.46295) ,
+ rgb (0.616852, 0.585913, 0.462237) ,
+ rgb (0.620765, 0.58897, 0.461351) ,
+ rgb (0.624654, 0.592034, 0.460583) ,
+ rgb (0.628576, 0.595104, 0.459641) ,
+ rgb (0.632506, 0.59818, 0.458668) ,
+ rgb (0.636412, 0.601264, 0.457818) ,
+ rgb (0.640352, 0.604354, 0.456791) ,
+ rgb (0.64427, 0.60745, 0.455886) ,
+ rgb (0.648222, 0.610553, 0.454801) ,
+ rgb (0.652178, 0.613664, 0.453689) ,
+ rgb (0.656114, 0.61678, 0.452702) ,
+ rgb (0.660082, 0.619904, 0.451534) ,
+ rgb (0.664055, 0.623034, 0.450338) ,
+ rgb (0.668008, 0.626171, 0.44927) ,
+ rgb (0.671991, 0.629316, 0.448018) ,
+ rgb (0.675981, 0.632468, 0.446736) ,
+ rgb (0.679979, 0.635626, 0.445424) ,
+ rgb (0.68395, 0.638793, 0.444251) ,
+ rgb (0.687957, 0.641966, 0.442886) ,
+ rgb (0.691971, 0.645145, 0.441491) ,
+ rgb (0.695985, 0.648334, 0.440072) ,
+ rgb (0.700008, 0.651529, 0.438624) ,
+ rgb (0.704037, 0.654731, 0.437147) ,
+ rgb (0.708067, 0.657942, 0.435647) ,
+ rgb (0.712105, 0.66116, 0.434117) ,
+ rgb (0.716177, 0.664384, 0.432386) ,
+ rgb (0.720222, 0.667618, 0.430805) ,
+ rgb (0.724274, 0.670859, 0.429194) ,
+ rgb (0.728334, 0.674107, 0.427554) ,
+ rgb (0.732422, 0.677364, 0.425717) ,
+ rgb (0.736488, 0.680629, 0.424028) ,
+ rgb (0.740589, 0.6839, 0.422131) ,
+ rgb (0.744664, 0.687181, 0.420393) ,
+ rgb (0.748772, 0.69047, 0.418448) ,
+ rgb (0.752886, 0.693766, 0.416472) ,
+ rgb (0.756975, 0.697071, 0.414659) ,
+ rgb (0.761096, 0.700384, 0.412638) ,
+ rgb (0.765223, 0.703705, 0.410587) ,
+ rgb (0.769353, 0.707035, 0.408516) ,
+ rgb (0.773486, 0.710373, 0.406422) ,
+ rgb (0.777651, 0.713719, 0.404112) ,
+ rgb (0.781795, 0.717074, 0.401966) ,
+ rgb (0.785965, 0.720438, 0.399613) ,
+ rgb (0.790116, 0.72381, 0.397423) ,
+ rgb (0.794298, 0.72719, 0.395016) ,
+ rgb (0.79848, 0.73058, 0.392597) ,
+ rgb (0.802667, 0.733978, 0.390153) ,
+ rgb (0.806859, 0.737385, 0.387684) ,
+ rgb (0.811054, 0.740801, 0.385198) ,
+ rgb (0.815274, 0.744226, 0.382504) ,
+ rgb (0.819499, 0.747659, 0.379785) ,
+ rgb (0.823729, 0.751101, 0.377043) ,
+ rgb (0.827959, 0.754553, 0.374292) ,
+ rgb (0.832192, 0.758014, 0.371529) ,
+ rgb (0.836429, 0.761483, 0.368747) ,
+ rgb (0.840693, 0.764962, 0.365746) ,
+ rgb (0.844957, 0.76845, 0.362741) ,
+ rgb (0.849223, 0.771947, 0.359729) ,
+ rgb (0.853515, 0.775454, 0.3565) ,
+ rgb (0.857809, 0.778969, 0.353259) ,
+ rgb (0.862105, 0.782494, 0.350011) ,
+ rgb (0.866421, 0.786028, 0.346571) ,
+ rgb (0.870717, 0.789572, 0.343333) ,
+ rgb (0.875057, 0.793125, 0.339685) ,
+ rgb (0.879378, 0.796687, 0.336241) ,
+ rgb (0.88372, 0.800258, 0.332599) ,
+ rgb (0.888081, 0.803839, 0.32877) ,
+ rgb (0.89244, 0.80743, 0.324968) ,
+ rgb (0.896818, 0.81103, 0.320982) ,
+ rgb (0.901195, 0.814639, 0.317021) ,
+ rgb (0.905589, 0.818257, 0.312889) ,
+ rgb (0.91, 0.821885, 0.308594) ,
+ rgb (0.914407, 0.825522, 0.304348) ,
+ rgb (0.918828, 0.829168, 0.29996) ,
+ rgb (0.923279, 0.832822, 0.295244) ,
+ rgb (0.927724, 0.836486, 0.290611) ,
+ rgb (0.93218, 0.840159, 0.28588) ,
+ rgb (0.93666, 0.843841, 0.280876) ,
+ rgb (0.941147, 0.84753, 0.275815) ,
+ rgb (0.945654, 0.851228, 0.270532) ,
+ rgb (0.950178, 0.854933, 0.265085) ,
+ rgb (0.954725, 0.858646, 0.259365) ,
+ rgb (0.959284, 0.862365, 0.253563) ,
+ rgb (0.963872, 0.866089, 0.247445) ,
+ rgb (0.968469, 0.869819, 0.24131) ,
+ rgb (0.973114, 0.87355, 0.234677) ,
+ rgb (0.97778, 0.877281, 0.227954) ,
+ rgb (0.982497, 0.881008, 0.220878) ,
+ rgb (0.987293, 0.884718, 0.213336) ,
+ rgb (0.992218, 0.888385, 0.205468) ,
+ rgb (0.994847, 0.892954, 0.203445) ,
+ rgb (0.995249, 0.898384, 0.207561) ,
+ rgb (0.995503, 0.903866, 0.21237) ,
+ rgb (0.995737, 0.909344, 0.217772)
+});
+
+
+list_data inferno = list_data(new pen[] {
+ rgb (0.001462, 0.000466, 0.013866) ,
+ rgb (0.002267, 0.00127, 0.01857) ,
+ rgb (0.003299, 0.002249, 0.024239) ,
+ rgb (0.004547, 0.003392, 0.030909) ,
+ rgb (0.006006, 0.004692, 0.038558) ,
+ rgb (0.007676, 0.006136, 0.046836) ,
+ rgb (0.009561, 0.007713, 0.055143) ,
+ rgb (0.011663, 0.009417, 0.06346) ,
+ rgb (0.013995, 0.011225, 0.071862) ,
+ rgb (0.016561, 0.013136, 0.080282) ,
+ rgb (0.019373, 0.015133, 0.088767) ,
+ rgb (0.022447, 0.017199, 0.097327) ,
+ rgb (0.025793, 0.019331, 0.10593) ,
+ rgb (0.029432, 0.021503, 0.114621) ,
+ rgb (0.033385, 0.023702, 0.123397) ,
+ rgb (0.037668, 0.025921, 0.132232) ,
+ rgb (0.042253, 0.028139, 0.141141) ,
+ rgb (0.046915, 0.030324, 0.150164) ,
+ rgb (0.051644, 0.032474, 0.159254) ,
+ rgb (0.056449, 0.034569, 0.168414) ,
+ rgb (0.06134, 0.03659, 0.177642) ,
+ rgb (0.066331, 0.038504, 0.186962) ,
+ rgb (0.071429, 0.040294, 0.196354) ,
+ rgb (0.076637, 0.041905, 0.205799) ,
+ rgb (0.081962, 0.043328, 0.215289) ,
+ rgb (0.087411, 0.044556, 0.224813) ,
+ rgb (0.09299, 0.045583, 0.234358) ,
+ rgb (0.098702, 0.046402, 0.243904) ,
+ rgb (0.104551, 0.047008, 0.25343) ,
+ rgb (0.110536, 0.047399, 0.262912) ,
+ rgb (0.116656, 0.047574, 0.272321) ,
+ rgb (0.122908, 0.047536, 0.281624) ,
+ rgb (0.129285, 0.047293, 0.290788) ,
+ rgb (0.135778, 0.046856, 0.299776) ,
+ rgb (0.142378, 0.046242, 0.308553) ,
+ rgb (0.149073, 0.045468, 0.317085) ,
+ rgb (0.15585, 0.044559, 0.325338) ,
+ rgb (0.162689, 0.043554, 0.333277) ,
+ rgb (0.169575, 0.042489, 0.340874) ,
+ rgb (0.176493, 0.041402, 0.348111) ,
+ rgb (0.183429, 0.040329, 0.354971) ,
+ rgb (0.190367, 0.039309, 0.361447) ,
+ rgb (0.197297, 0.0384, 0.367535) ,
+ rgb (0.204209, 0.037632, 0.373238) ,
+ rgb (0.211095, 0.03703, 0.378563) ,
+ rgb (0.217949, 0.036615, 0.383522) ,
+ rgb (0.224763, 0.036405, 0.388129) ,
+ rgb (0.231538, 0.036405, 0.3924) ,
+ rgb (0.238273, 0.036621, 0.396353) ,
+ rgb (0.244967, 0.037055, 0.400007) ,
+ rgb (0.25162, 0.037705, 0.403378) ,
+ rgb (0.258234, 0.038571, 0.406485) ,
+ rgb (0.26481, 0.039647, 0.409345) ,
+ rgb (0.271347, 0.040922, 0.411976) ,
+ rgb (0.27785, 0.042353, 0.414392) ,
+ rgb (0.284321, 0.043933, 0.416608) ,
+ rgb (0.290763, 0.045644, 0.418637) ,
+ rgb (0.297178, 0.04747, 0.420491) ,
+ rgb (0.303568, 0.049396, 0.422182) ,
+ rgb (0.309935, 0.051407, 0.423721) ,
+ rgb (0.316282, 0.05349, 0.425116) ,
+ rgb (0.32261, 0.055634, 0.426377) ,
+ rgb (0.328921, 0.057827, 0.427511) ,
+ rgb (0.335217, 0.06006, 0.428524) ,
+ rgb (0.3415, 0.062325, 0.429425) ,
+ rgb (0.347771, 0.064616, 0.430217) ,
+ rgb (0.354032, 0.066925, 0.430906) ,
+ rgb (0.360284, 0.069247, 0.431497) ,
+ rgb (0.366529, 0.071579, 0.431994) ,
+ rgb (0.372768, 0.073915, 0.4324) ,
+ rgb (0.379001, 0.076253, 0.432719) ,
+ rgb (0.385228, 0.078591, 0.432955) ,
+ rgb (0.391453, 0.080927, 0.433109) ,
+ rgb (0.397674, 0.083257, 0.433183) ,
+ rgb (0.403894, 0.08558, 0.433179) ,
+ rgb (0.410113, 0.087896, 0.433098) ,
+ rgb (0.416331, 0.090203, 0.432943) ,
+ rgb (0.422549, 0.092501, 0.432714) ,
+ rgb (0.428768, 0.09479, 0.432412) ,
+ rgb (0.434987, 0.097069, 0.432039) ,
+ rgb (0.441207, 0.099338, 0.431594) ,
+ rgb (0.447428, 0.101597, 0.43108) ,
+ rgb (0.453651, 0.103848, 0.430498) ,
+ rgb (0.459875, 0.106089, 0.429846) ,
+ rgb (0.4661, 0.108322, 0.429125) ,
+ rgb (0.472328, 0.110547, 0.428334) ,
+ rgb (0.478558, 0.112764, 0.427475) ,
+ rgb (0.484789, 0.114974, 0.426548) ,
+ rgb (0.491022, 0.117179, 0.425552) ,
+ rgb (0.497257, 0.119379, 0.424488) ,
+ rgb (0.503493, 0.121575, 0.423356) ,
+ rgb (0.50973, 0.123769, 0.422156) ,
+ rgb (0.515967, 0.12596, 0.420887) ,
+ rgb (0.522206, 0.12815, 0.419549) ,
+ rgb (0.528444, 0.130341, 0.418142) ,
+ rgb (0.534683, 0.132534, 0.416667) ,
+ rgb (0.54092, 0.134729, 0.415123) ,
+ rgb (0.547157, 0.136929, 0.413511) ,
+ rgb (0.553392, 0.139134, 0.411829) ,
+ rgb (0.559624, 0.141346, 0.410078) ,
+ rgb (0.565854, 0.143567, 0.408258) ,
+ rgb (0.572081, 0.145797, 0.406369) ,
+ rgb (0.578304, 0.148039, 0.404411) ,
+ rgb (0.584521, 0.150294, 0.402385) ,
+ rgb (0.590734, 0.152563, 0.40029) ,
+ rgb (0.59694, 0.154848, 0.398125) ,
+ rgb (0.603139, 0.157151, 0.395891) ,
+ rgb (0.60933, 0.159474, 0.393589) ,
+ rgb (0.615513, 0.161817, 0.391219) ,
+ rgb (0.621685, 0.164184, 0.388781) ,
+ rgb (0.627847, 0.166575, 0.386276) ,
+ rgb (0.633998, 0.168992, 0.383704) ,
+ rgb (0.640135, 0.171438, 0.381065) ,
+ rgb (0.64626, 0.173914, 0.378359) ,
+ rgb (0.652369, 0.176421, 0.375586) ,
+ rgb (0.658463, 0.178962, 0.372748) ,
+ rgb (0.66454, 0.181539, 0.369846) ,
+ rgb (0.670599, 0.184153, 0.366879) ,
+ rgb (0.676638, 0.186807, 0.363849) ,
+ rgb (0.682656, 0.189501, 0.360757) ,
+ rgb (0.688653, 0.192239, 0.357603) ,
+ rgb (0.694627, 0.195021, 0.354388) ,
+ rgb (0.700576, 0.197851, 0.351113) ,
+ rgb (0.7065, 0.200728, 0.347777) ,
+ rgb (0.712396, 0.203656, 0.344383) ,
+ rgb (0.718264, 0.206636, 0.340931) ,
+ rgb (0.724103, 0.20967, 0.337424) ,
+ rgb (0.729909, 0.212759, 0.333861) ,
+ rgb (0.735683, 0.215906, 0.330245) ,
+ rgb (0.741423, 0.219112, 0.326576) ,
+ rgb (0.747127, 0.222378, 0.322856) ,
+ rgb (0.752794, 0.225706, 0.319085) ,
+ rgb (0.758422, 0.229097, 0.315266) ,
+ rgb (0.76401, 0.232554, 0.311399) ,
+ rgb (0.769556, 0.236077, 0.307485) ,
+ rgb (0.775059, 0.239667, 0.303526) ,
+ rgb (0.780517, 0.243327, 0.299523) ,
+ rgb (0.785929, 0.247056, 0.295477) ,
+ rgb (0.791293, 0.250856, 0.29139) ,
+ rgb (0.796607, 0.254728, 0.287264) ,
+ rgb (0.801871, 0.258674, 0.283099) ,
+ rgb (0.807082, 0.262692, 0.278898) ,
+ rgb (0.812239, 0.266786, 0.274661) ,
+ rgb (0.817341, 0.270954, 0.27039) ,
+ rgb (0.822386, 0.275197, 0.266085) ,
+ rgb (0.827372, 0.279517, 0.26175) ,
+ rgb (0.832299, 0.283913, 0.257383) ,
+ rgb (0.837165, 0.288385, 0.252988) ,
+ rgb (0.841969, 0.292933, 0.248564) ,
+ rgb (0.846709, 0.297559, 0.244113) ,
+ rgb (0.851384, 0.30226, 0.239636) ,
+ rgb (0.855992, 0.307038, 0.235133) ,
+ rgb (0.860533, 0.311892, 0.230606) ,
+ rgb (0.865006, 0.316822, 0.226055) ,
+ rgb (0.869409, 0.321827, 0.221482) ,
+ rgb (0.873741, 0.326906, 0.216886) ,
+ rgb (0.878001, 0.33206, 0.212268) ,
+ rgb (0.882188, 0.337287, 0.207628) ,
+ rgb (0.886302, 0.342586, 0.202968) ,
+ rgb (0.890341, 0.347957, 0.198286) ,
+ rgb (0.894305, 0.353399, 0.193584) ,
+ rgb (0.898192, 0.358911, 0.18886) ,
+ rgb (0.902003, 0.364492, 0.184116) ,
+ rgb (0.905735, 0.37014, 0.17935) ,
+ rgb (0.90939, 0.375856, 0.174563) ,
+ rgb (0.912966, 0.381636, 0.169755) ,
+ rgb (0.916462, 0.387481, 0.164924) ,
+ rgb (0.919879, 0.393389, 0.16007) ,
+ rgb (0.923215, 0.399359, 0.155193) ,
+ rgb (0.92647, 0.405389, 0.150292) ,
+ rgb (0.929644, 0.411479, 0.145367) ,
+ rgb (0.932737, 0.417627, 0.140417) ,
+ rgb (0.935747, 0.423831, 0.13544) ,
+ rgb (0.938675, 0.430091, 0.130438) ,
+ rgb (0.941521, 0.436405, 0.125409) ,
+ rgb (0.944285, 0.442772, 0.120354) ,
+ rgb (0.946965, 0.449191, 0.115272) ,
+ rgb (0.949562, 0.45566, 0.110164) ,
+ rgb (0.952075, 0.462178, 0.105031) ,
+ rgb (0.954506, 0.468744, 0.099874) ,
+ rgb (0.956852, 0.475356, 0.094695) ,
+ rgb (0.959114, 0.482014, 0.089499) ,
+ rgb (0.961293, 0.488716, 0.084289) ,
+ rgb (0.963387, 0.495462, 0.079073) ,
+ rgb (0.965397, 0.502249, 0.073859) ,
+ rgb (0.967322, 0.509078, 0.068659) ,
+ rgb (0.969163, 0.515946, 0.063488) ,
+ rgb (0.970919, 0.522853, 0.058367) ,
+ rgb (0.97259, 0.529798, 0.053324) ,
+ rgb (0.974176, 0.53678, 0.048392) ,
+ rgb (0.975677, 0.543798, 0.043618) ,
+ rgb (0.977092, 0.55085, 0.03905) ,
+ rgb (0.978422, 0.557937, 0.034931) ,
+ rgb (0.979666, 0.565057, 0.031409) ,
+ rgb (0.980824, 0.572209, 0.028508) ,
+ rgb (0.981895, 0.579392, 0.02625) ,
+ rgb (0.982881, 0.586606, 0.024661) ,
+ rgb (0.983779, 0.593849, 0.02377) ,
+ rgb (0.984591, 0.601122, 0.023606) ,
+ rgb (0.985315, 0.608422, 0.024202) ,
+ rgb (0.985952, 0.61575, 0.025592) ,
+ rgb (0.986502, 0.623105, 0.027814) ,
+ rgb (0.986964, 0.630485, 0.030908) ,
+ rgb (0.987337, 0.63789, 0.034916) ,
+ rgb (0.987622, 0.64532, 0.039886) ,
+ rgb (0.987819, 0.652773, 0.045581) ,
+ rgb (0.987926, 0.66025, 0.05175) ,
+ rgb (0.987945, 0.667748, 0.058329) ,
+ rgb (0.987874, 0.675267, 0.065257) ,
+ rgb (0.987714, 0.682807, 0.072489) ,
+ rgb (0.987464, 0.690366, 0.07999) ,
+ rgb (0.987124, 0.697944, 0.087731) ,
+ rgb (0.986694, 0.70554, 0.095694) ,
+ rgb (0.986175, 0.713153, 0.103863) ,
+ rgb (0.985566, 0.720782, 0.112229) ,
+ rgb (0.984865, 0.728427, 0.120785) ,
+ rgb (0.984075, 0.736087, 0.129527) ,
+ rgb (0.983196, 0.743758, 0.138453) ,
+ rgb (0.982228, 0.751442, 0.147565) ,
+ rgb (0.981173, 0.759135, 0.156863) ,
+ rgb (0.980032, 0.766837, 0.166353) ,
+ rgb (0.978806, 0.774545, 0.176037) ,
+ rgb (0.977497, 0.782258, 0.185923) ,
+ rgb (0.976108, 0.789974, 0.196018) ,
+ rgb (0.974638, 0.797692, 0.206332) ,
+ rgb (0.973088, 0.805409, 0.216877) ,
+ rgb (0.971468, 0.813122, 0.227658) ,
+ rgb (0.969783, 0.820825, 0.238686) ,
+ rgb (0.968041, 0.828515, 0.249972) ,
+ rgb (0.966243, 0.836191, 0.261534) ,
+ rgb (0.964394, 0.843848, 0.273391) ,
+ rgb (0.962517, 0.851476, 0.285546) ,
+ rgb (0.960626, 0.859069, 0.29801) ,
+ rgb (0.95872, 0.866624, 0.31082) ,
+ rgb (0.956834, 0.874129, 0.323974) ,
+ rgb (0.954997, 0.881569, 0.337475) ,
+ rgb (0.953215, 0.888942, 0.351369) ,
+ rgb (0.951546, 0.896226, 0.365627) ,
+ rgb (0.950018, 0.903409, 0.380271) ,
+ rgb (0.948683, 0.910473, 0.395289) ,
+ rgb (0.947594, 0.917399, 0.410665) ,
+ rgb (0.946809, 0.924168, 0.426373) ,
+ rgb (0.946392, 0.930761, 0.442367) ,
+ rgb (0.946403, 0.937159, 0.458592) ,
+ rgb (0.946903, 0.943348, 0.47497) ,
+ rgb (0.947937, 0.949318, 0.491426) ,
+ rgb (0.949545, 0.955063, 0.50786) ,
+ rgb (0.95174, 0.960587, 0.524203) ,
+ rgb (0.954529, 0.965896, 0.540361) ,
+ rgb (0.957896, 0.971003, 0.556275) ,
+ rgb (0.961812, 0.975924, 0.571925) ,
+ rgb (0.966249, 0.980678, 0.587206) ,
+ rgb (0.971162, 0.985282, 0.602154) ,
+ rgb (0.976511, 0.989753, 0.61676) ,
+ rgb (0.982257, 0.994109, 0.631017) ,
+ rgb (0.988362, 0.998364, 0.644924)
+});
+
+
+list_data magma = list_data(new pen[] {
+ rgb (0.001462, 0.000466, 0.013866) ,
+ rgb (0.002258, 0.001295, 0.018331) ,
+ rgb (0.003279, 0.002305, 0.023708) ,
+ rgb (0.004512, 0.00349, 0.029965) ,
+ rgb (0.00595, 0.004843, 0.03713) ,
+ rgb (0.007588, 0.006356, 0.044973) ,
+ rgb (0.009426, 0.008022, 0.052844) ,
+ rgb (0.011465, 0.009828, 0.06075) ,
+ rgb (0.013708, 0.011771, 0.068667) ,
+ rgb (0.016156, 0.01384, 0.076603) ,
+ rgb (0.018815, 0.016026, 0.084584) ,
+ rgb (0.021692, 0.01832, 0.09261) ,
+ rgb (0.024792, 0.020715, 0.100676) ,
+ rgb (0.028123, 0.023201, 0.108787) ,
+ rgb (0.031696, 0.025765, 0.116965) ,
+ rgb (0.03552, 0.028397, 0.125209) ,
+ rgb (0.039608, 0.03109, 0.133515) ,
+ rgb (0.04383, 0.03383, 0.141886) ,
+ rgb (0.048062, 0.036607, 0.150327) ,
+ rgb (0.05232, 0.039407, 0.158841) ,
+ rgb (0.056615, 0.04216, 0.167446) ,
+ rgb (0.060949, 0.044794, 0.176129) ,
+ rgb (0.06533, 0.047318, 0.184892) ,
+ rgb (0.069764, 0.049726, 0.193735) ,
+ rgb (0.074257, 0.052017, 0.20266) ,
+ rgb (0.078815, 0.054184, 0.211667) ,
+ rgb (0.083446, 0.056225, 0.220755) ,
+ rgb (0.088155, 0.058133, 0.229922) ,
+ rgb (0.092949, 0.059904, 0.239164) ,
+ rgb (0.097833, 0.061531, 0.248477) ,
+ rgb (0.102815, 0.06301, 0.257854) ,
+ rgb (0.107899, 0.064335, 0.267289) ,
+ rgb (0.113094, 0.065492, 0.276784) ,
+ rgb (0.118405, 0.066479, 0.286321) ,
+ rgb (0.123833, 0.067295, 0.295879) ,
+ rgb (0.12938, 0.067935, 0.305443) ,
+ rgb (0.135053, 0.068391, 0.315) ,
+ rgb (0.140858, 0.068654, 0.324538) ,
+ rgb (0.146785, 0.068738, 0.334011) ,
+ rgb (0.152839, 0.068637, 0.343404) ,
+ rgb (0.159018, 0.068354, 0.352688) ,
+ rgb (0.165308, 0.067911, 0.361816) ,
+ rgb (0.171713, 0.067305, 0.370771) ,
+ rgb (0.178212, 0.066576, 0.379497) ,
+ rgb (0.184801, 0.065732, 0.387973) ,
+ rgb (0.19146, 0.064818, 0.396152) ,
+ rgb (0.198177, 0.063862, 0.404009) ,
+ rgb (0.204935, 0.062907, 0.411514) ,
+ rgb (0.211718, 0.061992, 0.418647) ,
+ rgb (0.218512, 0.061158, 0.425392) ,
+ rgb (0.225302, 0.060445, 0.431742) ,
+ rgb (0.232077, 0.059889, 0.437695) ,
+ rgb (0.238826, 0.059517, 0.443256) ,
+ rgb (0.245543, 0.059352, 0.448436) ,
+ rgb (0.25222, 0.059415, 0.453248) ,
+ rgb (0.258857, 0.059706, 0.45771) ,
+ rgb (0.265447, 0.060237, 0.46184) ,
+ rgb (0.271994, 0.060994, 0.46566) ,
+ rgb (0.278493, 0.061978, 0.46919) ,
+ rgb (0.284951, 0.063168, 0.472451) ,
+ rgb (0.291366, 0.064553, 0.475462) ,
+ rgb (0.29774, 0.066117, 0.478243) ,
+ rgb (0.304081, 0.067835, 0.480812) ,
+ rgb (0.310382, 0.069702, 0.483186) ,
+ rgb (0.316654, 0.07169, 0.48538) ,
+ rgb (0.322899, 0.073782, 0.487408) ,
+ rgb (0.329114, 0.075972, 0.489287) ,
+ rgb (0.335308, 0.078236, 0.491024) ,
+ rgb (0.341482, 0.080564, 0.492631) ,
+ rgb (0.347636, 0.082946, 0.494121) ,
+ rgb (0.353773, 0.085373, 0.495501) ,
+ rgb (0.359898, 0.087831, 0.496778) ,
+ rgb (0.366012, 0.090314, 0.49796) ,
+ rgb (0.372116, 0.092816, 0.499053) ,
+ rgb (0.378211, 0.095332, 0.500067) ,
+ rgb (0.384299, 0.097855, 0.501002) ,
+ rgb (0.390384, 0.100379, 0.501864) ,
+ rgb (0.396467, 0.102902, 0.502658) ,
+ rgb (0.402548, 0.10542, 0.503386) ,
+ rgb (0.408629, 0.10793, 0.504052) ,
+ rgb (0.414709, 0.110431, 0.504662) ,
+ rgb (0.420791, 0.11292, 0.505215) ,
+ rgb (0.426877, 0.115395, 0.505714) ,
+ rgb (0.432967, 0.117855, 0.50616) ,
+ rgb (0.439062, 0.120298, 0.506555) ,
+ rgb (0.445163, 0.122724, 0.506901) ,
+ rgb (0.451271, 0.125132, 0.507198) ,
+ rgb (0.457386, 0.127522, 0.507448) ,
+ rgb (0.463508, 0.129893, 0.507652) ,
+ rgb (0.46964, 0.132245, 0.507809) ,
+ rgb (0.47578, 0.134577, 0.507921) ,
+ rgb (0.481929, 0.136891, 0.507989) ,
+ rgb (0.488088, 0.139186, 0.508011) ,
+ rgb (0.494258, 0.141462, 0.507988) ,
+ rgb (0.500438, 0.143719, 0.50792) ,
+ rgb (0.506629, 0.145958, 0.507806) ,
+ rgb (0.512831, 0.148179, 0.507648) ,
+ rgb (0.519045, 0.150383, 0.507443) ,
+ rgb (0.52527, 0.152569, 0.507192) ,
+ rgb (0.531507, 0.154739, 0.506895) ,
+ rgb (0.537755, 0.156894, 0.506551) ,
+ rgb (0.544015, 0.159033, 0.506159) ,
+ rgb (0.550287, 0.161158, 0.505719) ,
+ rgb (0.556571, 0.163269, 0.50523) ,
+ rgb (0.562866, 0.165368, 0.504692) ,
+ rgb (0.569172, 0.167454, 0.504105) ,
+ rgb (0.57549, 0.16953, 0.503466) ,
+ rgb (0.581819, 0.171596, 0.502777) ,
+ rgb (0.588158, 0.173652, 0.502035) ,
+ rgb (0.594508, 0.175701, 0.501241) ,
+ rgb (0.600868, 0.177743, 0.500394) ,
+ rgb (0.607238, 0.179779, 0.499492) ,
+ rgb (0.613617, 0.181811, 0.498536) ,
+ rgb (0.620005, 0.18384, 0.497524) ,
+ rgb (0.626401, 0.185867, 0.496456) ,
+ rgb (0.632805, 0.187893, 0.495332) ,
+ rgb (0.639216, 0.189921, 0.49415) ,
+ rgb (0.645633, 0.191952, 0.49291) ,
+ rgb (0.652056, 0.193986, 0.491611) ,
+ rgb (0.658483, 0.196027, 0.490253) ,
+ rgb (0.664915, 0.198075, 0.488836) ,
+ rgb (0.671349, 0.200133, 0.487358) ,
+ rgb (0.677786, 0.202203, 0.485819) ,
+ rgb (0.684224, 0.204286, 0.484219) ,
+ rgb (0.690661, 0.206384, 0.482558) ,
+ rgb (0.697098, 0.208501, 0.480835) ,
+ rgb (0.703532, 0.210638, 0.479049) ,
+ rgb (0.709962, 0.212797, 0.477201) ,
+ rgb (0.716387, 0.214982, 0.47529) ,
+ rgb (0.722805, 0.217194, 0.473316) ,
+ rgb (0.729216, 0.219437, 0.471279) ,
+ rgb (0.735616, 0.221713, 0.46918) ,
+ rgb (0.742004, 0.224025, 0.467018) ,
+ rgb (0.748378, 0.226377, 0.464794) ,
+ rgb (0.754737, 0.228772, 0.462509) ,
+ rgb (0.761077, 0.231214, 0.460162) ,
+ rgb (0.767398, 0.233705, 0.457755) ,
+ rgb (0.773695, 0.236249, 0.455289) ,
+ rgb (0.779968, 0.238851, 0.452765) ,
+ rgb (0.786212, 0.241514, 0.450184) ,
+ rgb (0.792427, 0.244242, 0.447543) ,
+ rgb (0.798608, 0.24704, 0.444848) ,
+ rgb (0.804752, 0.249911, 0.442102) ,
+ rgb (0.810855, 0.252861, 0.439305) ,
+ rgb (0.816914, 0.255895, 0.436461) ,
+ rgb (0.822926, 0.259016, 0.433573) ,
+ rgb (0.828886, 0.262229, 0.430644) ,
+ rgb (0.834791, 0.26554, 0.427671) ,
+ rgb (0.840636, 0.268953, 0.424666) ,
+ rgb (0.846416, 0.272473, 0.421631) ,
+ rgb (0.852126, 0.276106, 0.418573) ,
+ rgb (0.857763, 0.279857, 0.415496) ,
+ rgb (0.86332, 0.283729, 0.412403) ,
+ rgb (0.868793, 0.287728, 0.409303) ,
+ rgb (0.874176, 0.291859, 0.406205) ,
+ rgb (0.879464, 0.296125, 0.403118) ,
+ rgb (0.884651, 0.30053, 0.400047) ,
+ rgb (0.889731, 0.305079, 0.397002) ,
+ rgb (0.8947, 0.309773, 0.393995) ,
+ rgb (0.899552, 0.314616, 0.391037) ,
+ rgb (0.904281, 0.31961, 0.388137) ,
+ rgb (0.908884, 0.324755, 0.385308) ,
+ rgb (0.913354, 0.330052, 0.382563) ,
+ rgb (0.917689, 0.3355, 0.379915) ,
+ rgb (0.921884, 0.341098, 0.377376) ,
+ rgb (0.925937, 0.346844, 0.374959) ,
+ rgb (0.929845, 0.352734, 0.372677) ,
+ rgb (0.933606, 0.358764, 0.370541) ,
+ rgb (0.937221, 0.364929, 0.368567) ,
+ rgb (0.940687, 0.371224, 0.366762) ,
+ rgb (0.944006, 0.377643, 0.365136) ,
+ rgb (0.94718, 0.384178, 0.363701) ,
+ rgb (0.95021, 0.39082, 0.362468) ,
+ rgb (0.953099, 0.397563, 0.361438) ,
+ rgb (0.955849, 0.4044, 0.360619) ,
+ rgb (0.958464, 0.411324, 0.360014) ,
+ rgb (0.960949, 0.418323, 0.35963) ,
+ rgb (0.96331, 0.42539, 0.359469) ,
+ rgb (0.965549, 0.432519, 0.359529) ,
+ rgb (0.967671, 0.439703, 0.35981) ,
+ rgb (0.96968, 0.446936, 0.360311) ,
+ rgb (0.971582, 0.45421, 0.36103) ,
+ rgb (0.973381, 0.46152, 0.361965) ,
+ rgb (0.975082, 0.468861, 0.363111) ,
+ rgb (0.97669, 0.476226, 0.364466) ,
+ rgb (0.97821, 0.483612, 0.366025) ,
+ rgb (0.979645, 0.491014, 0.367783) ,
+ rgb (0.981, 0.498428, 0.369734) ,
+ rgb (0.982279, 0.505851, 0.371874) ,
+ rgb (0.983485, 0.51328, 0.374198) ,
+ rgb (0.984622, 0.520713, 0.376698) ,
+ rgb (0.985693, 0.528148, 0.379371) ,
+ rgb (0.9867, 0.535582, 0.38221) ,
+ rgb (0.987646, 0.543015, 0.38521) ,
+ rgb (0.988533, 0.550446, 0.388365) ,
+ rgb (0.989363, 0.557873, 0.391671) ,
+ rgb (0.990138, 0.565296, 0.395122) ,
+ rgb (0.990871, 0.572706, 0.398714) ,
+ rgb (0.991558, 0.580107, 0.402441) ,
+ rgb (0.992196, 0.587502, 0.406299) ,
+ rgb (0.992785, 0.594891, 0.410283) ,
+ rgb (0.993326, 0.602275, 0.41439) ,
+ rgb (0.993834, 0.609644, 0.418613) ,
+ rgb (0.994309, 0.616999, 0.42295) ,
+ rgb (0.994738, 0.62435, 0.427397) ,
+ rgb (0.995122, 0.631696, 0.431951) ,
+ rgb (0.99548, 0.639027, 0.436607) ,
+ rgb (0.99581, 0.646344, 0.441361) ,
+ rgb (0.996096, 0.653659, 0.446213) ,
+ rgb (0.996341, 0.660969, 0.45116) ,
+ rgb (0.99658, 0.668256, 0.456192) ,
+ rgb (0.996775, 0.675541, 0.461314) ,
+ rgb (0.996925, 0.682828, 0.466526) ,
+ rgb (0.997077, 0.690088, 0.471811) ,
+ rgb (0.997186, 0.697349, 0.477182) ,
+ rgb (0.997254, 0.704611, 0.482635) ,
+ rgb (0.997325, 0.711848, 0.488154) ,
+ rgb (0.997351, 0.719089, 0.493755) ,
+ rgb (0.997351, 0.726324, 0.499428) ,
+ rgb (0.997341, 0.733545, 0.505167) ,
+ rgb (0.997285, 0.740772, 0.510983) ,
+ rgb (0.997228, 0.747981, 0.516859) ,
+ rgb (0.997138, 0.75519, 0.522806) ,
+ rgb (0.997019, 0.762398, 0.528821) ,
+ rgb (0.996898, 0.769591, 0.534892) ,
+ rgb (0.996727, 0.776795, 0.541039) ,
+ rgb (0.996571, 0.783977, 0.547233) ,
+ rgb (0.996369, 0.791167, 0.553499) ,
+ rgb (0.996162, 0.798348, 0.55982) ,
+ rgb (0.995932, 0.805527, 0.566202) ,
+ rgb (0.99568, 0.812706, 0.572645) ,
+ rgb (0.995424, 0.819875, 0.57914) ,
+ rgb (0.995131, 0.827052, 0.585701) ,
+ rgb (0.994851, 0.834213, 0.592307) ,
+ rgb (0.994524, 0.841387, 0.598983) ,
+ rgb (0.994222, 0.84854, 0.605696) ,
+ rgb (0.993866, 0.855711, 0.612482) ,
+ rgb (0.993545, 0.862859, 0.619299) ,
+ rgb (0.99317, 0.870024, 0.626189) ,
+ rgb (0.992831, 0.877168, 0.633109) ,
+ rgb (0.99244, 0.88433, 0.640099) ,
+ rgb (0.992089, 0.89147, 0.647116) ,
+ rgb (0.991688, 0.898627, 0.654202) ,
+ rgb (0.991332, 0.905763, 0.661309) ,
+ rgb (0.99093, 0.912915, 0.668481) ,
+ rgb (0.99057, 0.920049, 0.675675) ,
+ rgb (0.990175, 0.927196, 0.682926) ,
+ rgb (0.989815, 0.934329, 0.690198) ,
+ rgb (0.989434, 0.94147, 0.697519) ,
+ rgb (0.989077, 0.948604, 0.704863) ,
+ rgb (0.988717, 0.955742, 0.712242) ,
+ rgb (0.988367, 0.962878, 0.719649) ,
+ rgb (0.988033, 0.970012, 0.727077) ,
+ rgb (0.987691, 0.977154, 0.734536) ,
+ rgb (0.987387, 0.984288, 0.742002) ,
+ rgb (0.987053, 0.991438, 0.749504)
+});
+
+
+list_data plasma = list_data(new pen[] {
+ rgb (0.050383, 0.029803, 0.527975) ,
+ rgb (0.063536, 0.028426, 0.533124) ,
+ rgb (0.075353, 0.027206, 0.538007) ,
+ rgb (0.086222, 0.026125, 0.542658) ,
+ rgb (0.096379, 0.025165, 0.547103) ,
+ rgb (0.10598, 0.024309, 0.551368) ,
+ rgb (0.115124, 0.023556, 0.555468) ,
+ rgb (0.123903, 0.022878, 0.559423) ,
+ rgb (0.132381, 0.022258, 0.56325) ,
+ rgb (0.140603, 0.021687, 0.566959) ,
+ rgb (0.148607, 0.021154, 0.570562) ,
+ rgb (0.156421, 0.020651, 0.574065) ,
+ rgb (0.16407, 0.020171, 0.577478) ,
+ rgb (0.171574, 0.019706, 0.580806) ,
+ rgb (0.17895, 0.019252, 0.584054) ,
+ rgb (0.186213, 0.018803, 0.587228) ,
+ rgb (0.193374, 0.018354, 0.59033) ,
+ rgb (0.200445, 0.017902, 0.593364) ,
+ rgb (0.207435, 0.017442, 0.596333) ,
+ rgb (0.21435, 0.016973, 0.599239) ,
+ rgb (0.221197, 0.016497, 0.602083) ,
+ rgb (0.227983, 0.016007, 0.604867) ,
+ rgb (0.234715, 0.015502, 0.607592) ,
+ rgb (0.241396, 0.014979, 0.610259) ,
+ rgb (0.248032, 0.014439, 0.612868) ,
+ rgb (0.254627, 0.013882, 0.615419) ,
+ rgb (0.261183, 0.013308, 0.617911) ,
+ rgb (0.267703, 0.012716, 0.620346) ,
+ rgb (0.274191, 0.012109, 0.622722) ,
+ rgb (0.280648, 0.011488, 0.625038) ,
+ rgb (0.287076, 0.010855, 0.627295) ,
+ rgb (0.293478, 0.010213, 0.62949) ,
+ rgb (0.299855, 0.009561, 0.631624) ,
+ rgb (0.30621, 0.008902, 0.633694) ,
+ rgb (0.312543, 0.008239, 0.6357) ,
+ rgb (0.318856, 0.007576, 0.63764) ,
+ rgb (0.32515, 0.006915, 0.639512) ,
+ rgb (0.331426, 0.006261, 0.641316) ,
+ rgb (0.337683, 0.005618, 0.643049) ,
+ rgb (0.343925, 0.004991, 0.64471) ,
+ rgb (0.35015, 0.004382, 0.646298) ,
+ rgb (0.356359, 0.003798, 0.64781) ,
+ rgb (0.362553, 0.003243, 0.649245) ,
+ rgb (0.368733, 0.002724, 0.650601) ,
+ rgb (0.374897, 0.002245, 0.651876) ,
+ rgb (0.381047, 0.001814, 0.653068) ,
+ rgb (0.387183, 0.001434, 0.654177) ,
+ rgb (0.393304, 0.001114, 0.655199) ,
+ rgb (0.399411, 0.000859, 0.656133) ,
+ rgb (0.405503, 0.000678, 0.656977) ,
+ rgb (0.41158, 0.000577, 0.65773) ,
+ rgb (0.417642, 0.000564, 0.65839) ,
+ rgb (0.423689, 0.000646, 0.658956) ,
+ rgb (0.429719, 0.000831, 0.659425) ,
+ rgb (0.435734, 0.001127, 0.659797) ,
+ rgb (0.441732, 0.00154, 0.660069) ,
+ rgb (0.447714, 0.00208, 0.66024) ,
+ rgb (0.453677, 0.002755, 0.66031) ,
+ rgb (0.459623, 0.003574, 0.660277) ,
+ rgb (0.46555, 0.004545, 0.660139) ,
+ rgb (0.471457, 0.005678, 0.659897) ,
+ rgb (0.477344, 0.00698, 0.659549) ,
+ rgb (0.48321, 0.00846, 0.659095) ,
+ rgb (0.489055, 0.010127, 0.658534) ,
+ rgb (0.494877, 0.01199, 0.657865) ,
+ rgb (0.500678, 0.014055, 0.657088) ,
+ rgb (0.506454, 0.016333, 0.656202) ,
+ rgb (0.512206, 0.018833, 0.655209) ,
+ rgb (0.517933, 0.021563, 0.654109) ,
+ rgb (0.523633, 0.024532, 0.652901) ,
+ rgb (0.529306, 0.027747, 0.651586) ,
+ rgb (0.534952, 0.031217, 0.650165) ,
+ rgb (0.54057, 0.03495, 0.64864) ,
+ rgb (0.546157, 0.038954, 0.64701) ,
+ rgb (0.551715, 0.043136, 0.645277) ,
+ rgb (0.557243, 0.047331, 0.643443) ,
+ rgb (0.562738, 0.051545, 0.641509) ,
+ rgb (0.568201, 0.055778, 0.639477) ,
+ rgb (0.573632, 0.060028, 0.637349) ,
+ rgb (0.579029, 0.064296, 0.635126) ,
+ rgb (0.584391, 0.068579, 0.632812) ,
+ rgb (0.589719, 0.072878, 0.630408) ,
+ rgb (0.595011, 0.07719, 0.627917) ,
+ rgb (0.600266, 0.081516, 0.625342) ,
+ rgb (0.605485, 0.085854, 0.622686) ,
+ rgb (0.610667, 0.090204, 0.619951) ,
+ rgb (0.615812, 0.094564, 0.61714) ,
+ rgb (0.620919, 0.098934, 0.614257) ,
+ rgb (0.625987, 0.103312, 0.611305) ,
+ rgb (0.631017, 0.107699, 0.608287) ,
+ rgb (0.636008, 0.112092, 0.605205) ,
+ rgb (0.640959, 0.116492, 0.602065) ,
+ rgb (0.645872, 0.120898, 0.598867) ,
+ rgb (0.650746, 0.125309, 0.595617) ,
+ rgb (0.65558, 0.129725, 0.592317) ,
+ rgb (0.660374, 0.134144, 0.588971) ,
+ rgb (0.665129, 0.138566, 0.585582) ,
+ rgb (0.669845, 0.142992, 0.582154) ,
+ rgb (0.674522, 0.147419, 0.578688) ,
+ rgb (0.67916, 0.151848, 0.575189) ,
+ rgb (0.683758, 0.156278, 0.57166) ,
+ rgb (0.688318, 0.160709, 0.568103) ,
+ rgb (0.69284, 0.165141, 0.564522) ,
+ rgb (0.697324, 0.169573, 0.560919) ,
+ rgb (0.701769, 0.174005, 0.557296) ,
+ rgb (0.706178, 0.178437, 0.553657) ,
+ rgb (0.710549, 0.182868, 0.550004) ,
+ rgb (0.714883, 0.187299, 0.546338) ,
+ rgb (0.719181, 0.191729, 0.542663) ,
+ rgb (0.723444, 0.196158, 0.538981) ,
+ rgb (0.72767, 0.200586, 0.535293) ,
+ rgb (0.731862, 0.205013, 0.531601) ,
+ rgb (0.736019, 0.209439, 0.527908) ,
+ rgb (0.740143, 0.213864, 0.524216) ,
+ rgb (0.744232, 0.218288, 0.520524) ,
+ rgb (0.748289, 0.222711, 0.516834) ,
+ rgb (0.752312, 0.227133, 0.513149) ,
+ rgb (0.756304, 0.231555, 0.509468) ,
+ rgb (0.760264, 0.235976, 0.505794) ,
+ rgb (0.764193, 0.240396, 0.502126) ,
+ rgb (0.76809, 0.244817, 0.498465) ,
+ rgb (0.771958, 0.249237, 0.494813) ,
+ rgb (0.775796, 0.253658, 0.491171) ,
+ rgb (0.779604, 0.258078, 0.487539) ,
+ rgb (0.783383, 0.2625, 0.483918) ,
+ rgb (0.787133, 0.266922, 0.480307) ,
+ rgb (0.790855, 0.271345, 0.476706) ,
+ rgb (0.794549, 0.27577, 0.473117) ,
+ rgb (0.798216, 0.280197, 0.469538) ,
+ rgb (0.801855, 0.284626, 0.465971) ,
+ rgb (0.805467, 0.289057, 0.462415) ,
+ rgb (0.809052, 0.293491, 0.45887) ,
+ rgb (0.812612, 0.297928, 0.455338) ,
+ rgb (0.816144, 0.302368, 0.451816) ,
+ rgb (0.819651, 0.306812, 0.448306) ,
+ rgb (0.823132, 0.311261, 0.444806) ,
+ rgb (0.826588, 0.315714, 0.441316) ,
+ rgb (0.830018, 0.320172, 0.437836) ,
+ rgb (0.833422, 0.324635, 0.434366) ,
+ rgb (0.836801, 0.329105, 0.430905) ,
+ rgb (0.840155, 0.33358, 0.427455) ,
+ rgb (0.843484, 0.338062, 0.424013) ,
+ rgb (0.846788, 0.342551, 0.420579) ,
+ rgb (0.850066, 0.347048, 0.417153) ,
+ rgb (0.853319, 0.351553, 0.413734) ,
+ rgb (0.856547, 0.356066, 0.410322) ,
+ rgb (0.85975, 0.360588, 0.406917) ,
+ rgb (0.862927, 0.365119, 0.403519) ,
+ rgb (0.866078, 0.36966, 0.400126) ,
+ rgb (0.869203, 0.374212, 0.396738) ,
+ rgb (0.872303, 0.378774, 0.393355) ,
+ rgb (0.875376, 0.383347, 0.389976) ,
+ rgb (0.878423, 0.387932, 0.3866) ,
+ rgb (0.881443, 0.392529, 0.383229) ,
+ rgb (0.884436, 0.397139, 0.37986) ,
+ rgb (0.887402, 0.401762, 0.376494) ,
+ rgb (0.89034, 0.406398, 0.37313) ,
+ rgb (0.89325, 0.411048, 0.369768) ,
+ rgb (0.896131, 0.415712, 0.366407) ,
+ rgb (0.898984, 0.420392, 0.363047) ,
+ rgb (0.901807, 0.425087, 0.359688) ,
+ rgb (0.904601, 0.429797, 0.356329) ,
+ rgb (0.907365, 0.434524, 0.35297) ,
+ rgb (0.910098, 0.439268, 0.34961) ,
+ rgb (0.9128, 0.444029, 0.346251) ,
+ rgb (0.915471, 0.448807, 0.34289) ,
+ rgb (0.918109, 0.453603, 0.339529) ,
+ rgb (0.920714, 0.458417, 0.336166) ,
+ rgb (0.923287, 0.463251, 0.332801) ,
+ rgb (0.925825, 0.468103, 0.329435) ,
+ rgb (0.928329, 0.472975, 0.326067) ,
+ rgb (0.930798, 0.477867, 0.322697) ,
+ rgb (0.933232, 0.48278, 0.319325) ,
+ rgb (0.93563, 0.487712, 0.315952) ,
+ rgb (0.93799, 0.492667, 0.312575) ,
+ rgb (0.940313, 0.497642, 0.309197) ,
+ rgb (0.942598, 0.502639, 0.305816) ,
+ rgb (0.944844, 0.507658, 0.302433) ,
+ rgb (0.947051, 0.512699, 0.299049) ,
+ rgb (0.949217, 0.517763, 0.295662) ,
+ rgb (0.951344, 0.52285, 0.292275) ,
+ rgb (0.953428, 0.52796, 0.288883) ,
+ rgb (0.95547, 0.533093, 0.28549) ,
+ rgb (0.957469, 0.53825, 0.282096) ,
+ rgb (0.959424, 0.543431, 0.278701) ,
+ rgb (0.961336, 0.548636, 0.275305) ,
+ rgb (0.963203, 0.553865, 0.271909) ,
+ rgb (0.965024, 0.559118, 0.268513) ,
+ rgb (0.966798, 0.564396, 0.265118) ,
+ rgb (0.968526, 0.5697, 0.261721) ,
+ rgb (0.970205, 0.575028, 0.258325) ,
+ rgb (0.971835, 0.580382, 0.254931) ,
+ rgb (0.973416, 0.585761, 0.25154) ,
+ rgb (0.974947, 0.591165, 0.248151) ,
+ rgb (0.976428, 0.596595, 0.244767) ,
+ rgb (0.977856, 0.602051, 0.241387) ,
+ rgb (0.979233, 0.607532, 0.238013) ,
+ rgb (0.980556, 0.613039, 0.234646) ,
+ rgb (0.981826, 0.618572, 0.231287) ,
+ rgb (0.983041, 0.624131, 0.227937) ,
+ rgb (0.984199, 0.629718, 0.224595) ,
+ rgb (0.985301, 0.63533, 0.221265) ,
+ rgb (0.986345, 0.640969, 0.217948) ,
+ rgb (0.987332, 0.646633, 0.214648) ,
+ rgb (0.98826, 0.652325, 0.211364) ,
+ rgb (0.989128, 0.658043, 0.2081) ,
+ rgb (0.989935, 0.663787, 0.204859) ,
+ rgb (0.990681, 0.669558, 0.201642) ,
+ rgb (0.991365, 0.675355, 0.198453) ,
+ rgb (0.991985, 0.681179, 0.195295) ,
+ rgb (0.992541, 0.68703, 0.19217) ,
+ rgb (0.993032, 0.692907, 0.189084) ,
+ rgb (0.993456, 0.69881, 0.186041) ,
+ rgb (0.993814, 0.704741, 0.183043) ,
+ rgb (0.994103, 0.710698, 0.180097) ,
+ rgb (0.994324, 0.716681, 0.177208) ,
+ rgb (0.994474, 0.722691, 0.174381) ,
+ rgb (0.994553, 0.728728, 0.171622) ,
+ rgb (0.994561, 0.734791, 0.168938) ,
+ rgb (0.994495, 0.74088, 0.166335) ,
+ rgb (0.994355, 0.746995, 0.163821) ,
+ rgb (0.994141, 0.753137, 0.161404) ,
+ rgb (0.993851, 0.759304, 0.159092) ,
+ rgb (0.993482, 0.765499, 0.156891) ,
+ rgb (0.993033, 0.77172, 0.154808) ,
+ rgb (0.992505, 0.777967, 0.152855) ,
+ rgb (0.991897, 0.784239, 0.151042) ,
+ rgb (0.991209, 0.790537, 0.149377) ,
+ rgb (0.990439, 0.796859, 0.14787) ,
+ rgb (0.989587, 0.803205, 0.146529) ,
+ rgb (0.988648, 0.809579, 0.145357) ,
+ rgb (0.987621, 0.815978, 0.144363) ,
+ rgb (0.986509, 0.822401, 0.143557) ,
+ rgb (0.985314, 0.828846, 0.142945) ,
+ rgb (0.984031, 0.835315, 0.142528) ,
+ rgb (0.982653, 0.841812, 0.142303) ,
+ rgb (0.98119, 0.848329, 0.142279) ,
+ rgb (0.979644, 0.854866, 0.142453) ,
+ rgb (0.977995, 0.861432, 0.142808) ,
+ rgb (0.976265, 0.868016, 0.143351) ,
+ rgb (0.974443, 0.874622, 0.144061) ,
+ rgb (0.97253, 0.88125, 0.144923) ,
+ rgb (0.970533, 0.887896, 0.145919) ,
+ rgb (0.968443, 0.894564, 0.147014) ,
+ rgb (0.966271, 0.901249, 0.14818) ,
+ rgb (0.964021, 0.90795, 0.14937) ,
+ rgb (0.961681, 0.914672, 0.15052) ,
+ rgb (0.959276, 0.921407, 0.151566) ,
+ rgb (0.956808, 0.928152, 0.152409) ,
+ rgb (0.954287, 0.934908, 0.152921) ,
+ rgb (0.951726, 0.941671, 0.152925) ,
+ rgb (0.949151, 0.948435, 0.152178) ,
+ rgb (0.946602, 0.95519, 0.150328) ,
+ rgb (0.944152, 0.961916, 0.146861) ,
+ rgb (0.941896, 0.96859, 0.140956) ,
+ rgb (0.940015, 0.975158, 0.131326)
+});
+
+
+list_data twilight = list_data(new pen[] {
+ rgb (0.8857501584075443, 0.8500092494306783, 0.8879736506427196) ,
+ rgb (0.8837852019553906, 0.8507294054031063, 0.8872322209694989) ,
+ rgb (0.8817223105928579, 0.8512759407765347, 0.8863805692551482) ,
+ rgb (0.8795410528270573, 0.8516567540749572, 0.8854143767924102) ,
+ rgb (0.8772488085896548, 0.8518702833887027, 0.8843412038131143) ,
+ rgb (0.8748534750857597, 0.8519152612302319, 0.8831692696761383) ,
+ rgb (0.8723313408512408, 0.8518016547808089, 0.8818970435500162) ,
+ rgb (0.8697047485350982, 0.8515240300479789, 0.8805388339000336) ,
+ rgb (0.8669601550533358, 0.8510896085314068, 0.8790976697717334) ,
+ rgb (0.86408985081464, 0.8505039116750779, 0.8775792578489263) ,
+ rgb (0.8611024543689985, 0.8497675485700126, 0.8759924292343957) ,
+ rgb (0.8579825924567037, 0.8488893481028184, 0.8743403855344628) ,
+ rgb (0.8547259318925698, 0.8478748812467282, 0.8726282980930582) ,
+ rgb (0.8513371457085719, 0.8467273579611647, 0.8708608165735044) ,
+ rgb (0.8478071070257792, 0.8454546229209523, 0.8690403678369444) ,
+ rgb (0.8441261828674842, 0.8440648271103739, 0.8671697332269007) ,
+ rgb (0.8403042080595778, 0.8425605950855084, 0.865250882410458) ,
+ rgb (0.8363403180919118, 0.8409479651895194, 0.8632852800107016) ,
+ rgb (0.8322270571293441, 0.8392349062775448, 0.8612756350042788) ,
+ rgb (0.8279689431601354, 0.837426007513952, 0.8592239945130679) ,
+ rgb (0.8235742968025285, 0.8355248776479544, 0.8571319132851495) ,
+ rgb (0.8190465467793753, 0.8335364929949034, 0.855002062870101) ,
+ rgb (0.8143898212114309, 0.8314655869419785, 0.8528375906214702) ,
+ rgb (0.8095999819094809, 0.8293189667350546, 0.8506444160105037) ,
+ rgb (0.8046916442981458, 0.8270983878056066, 0.8484244929697402) ,
+ rgb (0.79967075421268, 0.8248078181208093, 0.8461821002957853) ,
+ rgb (0.7945430508923111, 0.8224511622630462, 0.8439218478682798) ,
+ rgb (0.7893144556460892, 0.8200321318870201, 0.8416486380471222) ,
+ rgb (0.7839910104276492, 0.8175542640053343, 0.8393674746403673) ,
+ rgb (0.7785789200822759, 0.8150208937874255, 0.8370834463093898) ,
+ rgb (0.7730841659017094, 0.8124352473546601, 0.8348017295057968) ,
+ rgb (0.7675110850441786, 0.8098007598713145, 0.8325281663805967) ,
+ rgb (0.7618690793798029, 0.8071194938764749, 0.830266486168872) ,
+ rgb (0.7561644358438198, 0.8043940873347794, 0.8280213899472) ,
+ rgb (0.750403467654067, 0.8016269900896532, 0.8257973785108242) ,
+ rgb (0.7445924777189017, 0.7988204771958325, 0.8235986758615652) ,
+ rgb (0.7387377170049494, 0.7959766573503101, 0.8214292278043301) ,
+ rgb (0.7328454364552346, 0.7930974646884407, 0.8192926338423038) ,
+ rgb (0.726921775128297, 0.7901846863592763, 0.8171921746672638) ,
+ rgb (0.7209728066553678, 0.7872399592345264, 0.8151307392087926) ,
+ rgb (0.7150040307625213, 0.7842648709158119, 0.8131111655994991) ,
+ rgb (0.709020781345393, 0.7812608871607091, 0.8111359185511793) ,
+ rgb (0.7030297722540817, 0.7782290497335813, 0.8092061884805697) ,
+ rgb (0.6970365443886174, 0.7751705000806606, 0.8073233538006345) ,
+ rgb (0.691046410093091, 0.7720862946067809, 0.8054884169067907) ,
+ rgb (0.6850644615439593, 0.7689774029354699, 0.8037020626717691) ,
+ rgb (0.6790955449988215, 0.765844721313959, 0.8019646617300199) ,
+ rgb (0.6731442255942621, 0.7626890873389048, 0.8002762854580953) ,
+ rgb (0.6672147980375281, 0.7595112803730375, 0.7986367465453776) ,
+ rgb (0.6613112930078745, 0.7563120270871903, 0.7970456043491897) ,
+ rgb (0.6554369232645472, 0.7530920875676843, 0.7955027112903105) ,
+ rgb (0.6495957300425348, 0.7498520122194177, 0.7940067402149911) ,
+ rgb (0.6437910831099849, 0.7465923800833657, 0.7925565320130605) ,
+ rgb (0.6380258682854598, 0.7433137671403319, 0.7911510045957317) ,
+ rgb (0.6323027138710603, 0.740016721601314, 0.7897889276264043) ,
+ rgb (0.6266240202260459, 0.7367017540369944, 0.7884690131633456) ,
+ rgb (0.6209919306481755, 0.733369347989232, 0.7871899462469658) ,
+ rgb (0.6154084641177048, 0.7300199523273969, 0.7859502270675048) ,
+ rgb (0.6098754317609306, 0.7266539875975829, 0.7847483573269471) ,
+ rgb (0.6043943420027486, 0.7232718614323369, 0.7835829559353559) ,
+ rgb (0.5989665814482068, 0.7198739489224673, 0.7824525989934664) ,
+ rgb (0.5935933569683722, 0.7164606049658685, 0.781355882376401) ,
+ rgb (0.588275797805555, 0.7130321464645814, 0.7802914140563652) ,
+ rgb (0.5830148703693241, 0.7095888767699747, 0.7792578182047659) ,
+ rgb (0.5778116438998202, 0.7061310615715398, 0.7782534512102552) ,
+ rgb (0.5726668948158774, 0.7026589535425779, 0.7772770268091199) ,
+ rgb (0.5675811785386197, 0.6991727930264627, 0.776327485342753) ,
+ rgb (0.5625551535721934, 0.6956727838162965, 0.7754035914230984) ,
+ rgb (0.5575894041960517, 0.6921591145825405, 0.7745041337932782) ,
+ rgb (0.5526845058934713, 0.6886319451516638, 0.7736279426902245) ,
+ rgb (0.5478409815301863, 0.6850914221850988, 0.7727738647344087) ,
+ rgb (0.5430593242401823, 0.6815376725306588, 0.7719407969783508) ,
+ rgb (0.5383401557517628, 0.677970811290954, 0.7711273443905772) ,
+ rgb (0.533683891477284, 0.6743909370521273, 0.7703325054879735) ,
+ rgb (0.529090861832473, 0.6707981230280622, 0.7695555229231313) ,
+ rgb (0.5245615147059358, 0.6671924299614223, 0.7687954171423095) ,
+ rgb (0.5200962739223556, 0.6635739143403039, 0.768051194033441) ,
+ rgb (0.5156955988596057, 0.65994260812898, 0.7673219148959617) ,
+ rgb (0.5113599254160193, 0.6562985398183186, 0.7666066378064533) ,
+ rgb (0.5070896957645166, 0.6526417240314645, 0.7659044566083585) ,
+ rgb (0.5028853540415561, 0.6489721673409526, 0.7652144671817491) ,
+ rgb (0.4987473366135607, 0.6452898684900934, 0.7645357873418008) ,
+ rgb (0.4946761847863938, 0.6415948411950443, 0.7638671900213091) ,
+ rgb (0.4906722493856122, 0.6378870485884708, 0.7632081276316384) ,
+ rgb (0.4867359599430568, 0.6341664625110051, 0.7625578008592404) ,
+ rgb (0.4828677867260272, 0.6304330455306234, 0.761915371498953) ,
+ rgb (0.47906816236197386, 0.6266867625186013, 0.7612800037566242) ,
+ rgb (0.47533752394906287, 0.6229275728383581, 0.7606508557181775) ,
+ rgb (0.4716762951887709, 0.6191554324288464, 0.7600270922788305) ,
+ rgb (0.46808490970531597, 0.6153702869579029, 0.7594078989109274) ,
+ rgb (0.4645637671630393, 0.6115720882286415, 0.7587924262302581) ,
+ rgb (0.4611132664702388, 0.607760777169989, 0.7581798643680714) ,
+ rgb (0.45773377230160567, 0.6039363004658646, 0.7575693690185916) ,
+ rgb (0.45442563977552913, 0.6000985950385866, 0.7569601366060649) ,
+ rgb (0.45118918687617743, 0.5962476205135354, 0.7563512064324664) ,
+ rgb (0.4480247093358917, 0.5923833145214658, 0.7557417647410792) ,
+ rgb (0.4449324685421538, 0.5885055998308617, 0.7551311041857901) ,
+ rgb (0.441912717666964, 0.5846144110017557, 0.7545183888441067) ,
+ rgb (0.43896563958048396, 0.5807096924109849, 0.7539027620828594) ,
+ rgb (0.4360913895835637, 0.5767913799818608, 0.7532834105961016) ,
+ rgb (0.43329008867358393, 0.5728594162560667, 0.7526594653256667) ,
+ rgb (0.4305617907305757, 0.5689137457245718, 0.752030080993127) ,
+ rgb (0.42790652284925834, 0.5649543060909209, 0.7513944352191484) ,
+ rgb (0.42532423665011354, 0.560981049599503, 0.7507516498900512) ,
+ rgb (0.4228148567577266, 0.5569939212699658, 0.7501008698822764) ,
+ rgb (0.42037822361396326, 0.5529928715810817, 0.7494412559451894) ,
+ rgb (0.4180141407923363, 0.5489778542188889, 0.7487719316700112) ,
+ rgb (0.4157223260454232, 0.544948827153504, 0.7480920445900052) ,
+ rgb (0.4135024574331473, 0.5409057477109848, 0.7474007329754309) ,
+ rgb (0.4113541469730457, 0.5368485776500593, 0.7466971285506578) ,
+ rgb (0.4092768899914751, 0.5327773017713032, 0.7459803063570782) ,
+ rgb (0.4072701869421907, 0.5286918801105741, 0.7452494263758127) ,
+ rgb (0.4053334378930318, 0.5245922817498312, 0.7445036583670813) ,
+ rgb (0.40346600333905397, 0.5204784765384003, 0.7437421522356709) ,
+ rgb (0.40166714010896104, 0.5163504496968876, 0.7429640345324835) ,
+ rgb (0.39993606933454834, 0.5122081814321852, 0.7421684457131799) ,
+ rgb (0.3982719152586337, 0.5080516653927614, 0.7413545091809972) ,
+ rgb (0.3966737490566561, 0.5038808905384797, 0.7405213858051674) ,
+ rgb (0.3951405880820763, 0.4996958532637776, 0.7396682021171571) ,
+ rgb (0.39367135736822567, 0.4954965577745118, 0.738794102296364) ,
+ rgb (0.39226494876209317, 0.4912830033289926, 0.7378982478447508) ,
+ rgb (0.390920175719949, 0.4870552025122304, 0.7369797713388125) ,
+ rgb (0.38963580160340855, 0.48281316715123496, 0.7360378254693274) ,
+ rgb (0.3884105330084243, 0.47855691131792805, 0.7350715764115726) ,
+ rgb (0.3872430145933025, 0.4742864593363539, 0.7340801678785439) ,
+ rgb (0.386131841788921, 0.4700018340988123, 0.7330627749243106) ,
+ rgb (0.3850755679365139, 0.46570306719930193, 0.732018540336905) ,
+ rgb (0.38407269378943537, 0.46139018782416635, 0.7309466543290268) ,
+ rgb (0.3831216808440275, 0.457063235814072, 0.7298462679135326) ,
+ rgb (0.38222094988570376, 0.45272225034283325, 0.7287165614400378) ,
+ rgb (0.3813688793045416, 0.4483672766927786, 0.7275567131714135) ,
+ rgb (0.3805638069656562, 0.4439983720863372, 0.7263658704513531) ,
+ rgb (0.3798040374484875, 0.4396155882122263, 0.7251432377876109) ,
+ rgb (0.3790878928311076, 0.43521897612544935, 0.7238879869132313) ,
+ rgb (0.378413635091359, 0.43080859411413064, 0.7225993199306104) ,
+ rgb (0.3777794975351373, 0.4263845142616835, 0.7212763999353023) ,
+ rgb (0.3771837184425123, 0.4219468022345483, 0.7199184152447577) ,
+ rgb (0.37662448930806297, 0.41749553747893614, 0.7185245473617611) ,
+ rgb (0.37610001286385814, 0.4130307995247706, 0.7170939691992023) ,
+ rgb (0.375608469194424, 0.40855267638072096, 0.7156258509158755) ,
+ rgb (0.37514802505380473, 0.4040612609993941, 0.7141193695725726) ,
+ rgb (0.3747168601930223, 0.3995566498711684, 0.7125736851650046) ,
+ rgb (0.3743131319931234, 0.3950389482828331, 0.7109879652237746) ,
+ rgb (0.3739349933047578, 0.3905082752937583, 0.7093613429347845) ,
+ rgb (0.3735806215098284, 0.3859647438605754, 0.7076929760731058) ,
+ rgb (0.37324816143326384, 0.38140848555753937, 0.7059820097480604) ,
+ rgb (0.3729357864666503, 0.3768396383521984, 0.7042275578058994) ,
+ rgb (0.37264166757849604, 0.3722583500483685, 0.7024287314570723) ,
+ rgb (0.37236397858465387, 0.36766477862108266, 0.7005846349652077) ,
+ rgb (0.3721008970244382, 0.3630590973698238, 0.6986943461507372) ,
+ rgb (0.3718506155898596, 0.3584414828587522, 0.6967569581025654) ,
+ rgb (0.3716113323440048, 0.3538121372967869, 0.6947714991938089) ,
+ rgb (0.37138124223736607, 0.34917126878479027, 0.6927370347192883) ,
+ rgb (0.37115856636209105, 0.3445191141023017, 0.6906525358646499) ,
+ rgb (0.3709415155133733, 0.33985591488818123, 0.6885170337950512) ,
+ rgb (0.3707283327942267, 0.33518193808489577, 0.6863294816960677) ,
+ rgb (0.37051738634484427, 0.3304974124430785, 0.6840888878885721) ,
+ rgb (0.37030682071842685, 0.32580269697872455, 0.6817941168448668) ,
+ rgb (0.37009487130772695, 0.3210981375964933, 0.6794440539905685) ,
+ rgb (0.3698798032902536, 0.31638410101153364, 0.6770375543809057) ,
+ rgb (0.36965987626565955, 0.3116609876295197, 0.6745734474341955) ,
+ rgb (0.3694333459127623, 0.3069292355186234, 0.6720505284912062) ,
+ rgb (0.36919847837592484, 0.3021893217650707, 0.6694675433161452) ,
+ rgb (0.3689535530659678, 0.29744175492366276, 0.6668232208982426) ,
+ rgb (0.3686968223189527, 0.292687098561501, 0.6641162529823691) ,
+ rgb (0.36842655638020444, 0.2879259643777846, 0.661345269109446) ,
+ rgb (0.3681410147989972, 0.2831590122118299, 0.6585088880697231) ,
+ rgb (0.3678384369653108, 0.2783869718129776, 0.655605668384537) ,
+ rgb (0.36751707094367697, 0.2736106331709098, 0.6526341171161864) ,
+ rgb (0.36717513650699446, 0.26883085667326956, 0.6495927229789225) ,
+ rgb (0.3668108554010799, 0.26404857724525643, 0.6464799165290824) ,
+ rgb (0.3664224325155063, 0.25926481158628106, 0.6432940914076554) ,
+ rgb (0.36600853966739794, 0.25448043878086224, 0.6400336180336859) ,
+ rgb (0.3655669837353898, 0.24969683475296395, 0.6366967518748858) ,
+ rgb (0.3650957984588681, 0.24491536803550484, 0.6332817352005559) ,
+ rgb (0.3645930889012501, 0.24013747024823828, 0.629786801550261) ,
+ rgb (0.3640569302208851, 0.23536470386204195, 0.6262101345195302) ,
+ rgb (0.36348537610385145, 0.2305987621839642, 0.6225498862239288) ,
+ rgb (0.3628764356004103, 0.2258414929328703, 0.6188041741082302) ,
+ rgb (0.36222809558295926, 0.22109488427338303, 0.6149711234609613) ,
+ rgb (0.36153829010998356, 0.21636111429594002, 0.6110488067964093) ,
+ rgb (0.36080493826624654, 0.21164251793458128, 0.6070353217206471) ,
+ rgb (0.36002681809096376, 0.20694122817889948, 0.6029284543191687) ,
+ rgb (0.35920088560930186, 0.20226037920758122, 0.5987265295935138) ,
+ rgb (0.3583248996661781, 0.197602942459778, 0.5944276851750107) ,
+ rgb (0.35739663292915563, 0.1929720819784246, 0.5900301125106313) ,
+ rgb (0.35641381143126327, 0.18837119869242164, 0.5855320765920552) ,
+ rgb (0.3553741530690672, 0.18380392577704466, 0.580931914318328) ,
+ rgb (0.3542753496066376, 0.17927413271618647, 0.5762280966066872) ,
+ rgb (0.35311574421123737, 0.17478570377561287, 0.5714187152355529) ,
+ rgb (0.3518924860887379, 0.17034320478524959, 0.5665028491121665) ,
+ rgb (0.3506030444193101, 0.1659512998472086, 0.5614796470399323) ,
+ rgb (0.34924513554955644, 0.16161477763045118, 0.5563483747416378) ,
+ rgb (0.3478165323877778, 0.1573386351115298, 0.5511085345270326) ,
+ rgb (0.3463150717579309, 0.15312802296627787, 0.5457599924248665) ,
+ rgb (0.34473901574536375, 0.1489882058982641, 0.5403024592040654) ,
+ rgb (0.34308600291572294, 0.14492465359918028, 0.534737042820671) ,
+ rgb (0.34135411074506483, 0.1409427920655632, 0.5290650094033675) ,
+ rgb (0.33954168752669694, 0.1370480189671817, 0.5232879753508524) ,
+ rgb (0.3376473209067111, 0.13324562282438077, 0.5174080757397947) ,
+ rgb (0.33566978565015315, 0.12954074251271822, 0.5114280721516895) ,
+ rgb (0.33360804901486, 0.1259381830100592, 0.505351647966549) ,
+ rgb (0.33146154891145124, 0.12244245263391232, 0.4991827458843107) ,
+ rgb (0.3292300520323141, 0.11905764321981127, 0.49292595612342666) ,
+ rgb (0.3269137124539796, 0.1157873496841953, 0.4865864649569746) ,
+ rgb (0.32451307931207785, 0.11263459791730848, 0.48017007211645196) ,
+ rgb (0.3220288227606932, 0.10960114111258401, 0.4736849472572688) ,
+ rgb (0.31946262395497965, 0.1066887988239266, 0.46713728801395243) ,
+ rgb (0.316816480890235, 0.10389861387653518, 0.46053414662739794) ,
+ rgb (0.3140927841475553, 0.10123077676403242, 0.45388335612058467) ,
+ rgb (0.31129434479712365, 0.0986847719340522, 0.4471931371516162) ,
+ rgb (0.30842444457210105, 0.09625938534057774, 0.44047194882050544) ,
+ rgb (0.30548675819945936, 0.09395276484082374, 0.4337284999936111) ,
+ rgb (0.3024853636457425, 0.0917611873973036, 0.42697404043749887) ,
+ rgb (0.2994248396021477, 0.08968225371675004, 0.42021619665853854) ,
+ rgb (0.2963100038890529, 0.08771325096046395, 0.41346259134143476) ,
+ rgb (0.2931459309698525, 0.08585065688962071, 0.40672178082365834) ,
+ rgb (0.2899379244517661, 0.08409078829085731, 0.40000214725256295) ,
+ rgb (0.28669151388283165, 0.08242987384848069, 0.39331182532243375) ,
+ rgb (0.28341239797185225, 0.08086415336549937, 0.38665868550105914) ,
+ rgb (0.2801063857697547, 0.07938999480226153, 0.38005028528138707) ,
+ rgb (0.2767793961581559, 0.07800394103378822, 0.37349382846504675) ,
+ rgb (0.2734373934245081, 0.07670280023749607, 0.36699616136347685) ,
+ rgb (0.2700863774911405, 0.07548367558427554, 0.36056376228111864) ,
+ rgb (0.26673233211995284, 0.0743440180285462, 0.3542027606624096) ,
+ rgb (0.26338121807151404, 0.07328165793989708, 0.34791888996380105) ,
+ rgb (0.26003895187439957, 0.0722947810433622, 0.3417175669546984) ,
+ rgb (0.256711916510839, 0.07138010624208224, 0.3356064898460009) ,
+ rgb (0.25340685873736807, 0.07053358292685183, 0.3295945757321303) ,
+ rgb (0.2501284530619938, 0.06975820642910699, 0.32368100685760637) ,
+ rgb (0.24688226237959, 0.06905363944920445, 0.31786993834254956) ,
+ rgb (0.24367372557466271, 0.06841985515092269, 0.3121652405088837) ,
+ rgb (0.2405081333229594, 0.0678571038148556, 0.3065705449367832) ,
+ rgb (0.23739062429054825, 0.06736588805055552, 0.3010892218406587) ,
+ rgb (0.23433055727563878, 0.0669355996616394, 0.295740099298676) ,
+ rgb (0.23132955273021344, 0.06657618693909059, 0.29051361067988485) ,
+ rgb (0.2283917709422868, 0.06628997924139618, 0.28541074411068496) ,
+ rgb (0.22552164337737857, 0.0660781731193956, 0.28043398847505197) ,
+ rgb (0.22272706739121817, 0.06593379067565194, 0.275597146520537) ,
+ rgb (0.22001251100779617, 0.0658579189189076, 0.2709027999432586) ,
+ rgb (0.21737845072382705, 0.06585966123356204, 0.2663420934966951) ,
+ rgb (0.21482843531473683, 0.06594038561377849, 0.26191675992376573) ,
+ rgb (0.21237411048541005, 0.06608502466175845, 0.2576516509356954) ,
+ rgb (0.21001214221188125, 0.06630857391894718, 0.2535289048041211) ,
+ rgb (0.2077442377448806, 0.06661453200418091, 0.24954644291943817) ,
+ rgb (0.20558051999470117, 0.06699046239786874, 0.24572497420147632) ,
+ rgb (0.20352007949514977, 0.06744417961242422, 0.24205576625191821) ,
+ rgb (0.2015613376412984, 0.06798327102620025, 0.23852974228695395) ,
+ rgb (0.19971571438603364, 0.06859271055370472, 0.23517094067076993) ,
+ rgb (0.19794834061899208, 0.06931406607166066, 0.23194647381302336) ,
+ rgb (0.1960826032659409, 0.07032122724242362, 0.22874673279569585) ,
+ rgb (0.19410351363791453, 0.07160830485689157, 0.22558727307410353) ,
+ rgb (0.19199449184606268, 0.0731828306492733, 0.22243385243433622) ,
+ rgb (0.18975853639094634, 0.07501986186214377, 0.2193005075652994) ,
+ rgb (0.18739228342697645, 0.07710209689958833, 0.21618875376309582) ,
+ rgb (0.18488035509396164, 0.07942573027972388, 0.21307651648984993) ,
+ rgb (0.18774482037046955, 0.07725158846803931, 0.21387448578597812) ,
+ rgb (0.19049578401722037, 0.07531127841678764, 0.2146562337112265) ,
+ rgb (0.1931548636579131, 0.07360681904011795, 0.21542362939081539) ,
+ rgb (0.19571853588267552, 0.07215778103960274, 0.21617499187076789) ,
+ rgb (0.19819343656336558, 0.07097462525273879, 0.21690975060032436) ,
+ rgb (0.20058760685133747, 0.07006457614998421, 0.21762721310371608) ,
+ rgb (0.20290365333558247, 0.06943524858045896, 0.21833167885096033) ,
+ rgb (0.20531725273301316, 0.06891959226639757, 0.21911516689288835) ,
+ rgb (0.20785704662965598, 0.06848439879702528, 0.22000133917653536) ,
+ rgb (0.21052882914958676, 0.06812195249816172, 0.22098759107715404) ,
+ rgb (0.2133313859647627, 0.06783014842602667, 0.2220704321302429) ,
+ rgb (0.21625279838647882, 0.06761633027051639, 0.22324568672294431) ,
+ rgb (0.21930503925136402, 0.06746578636294004, 0.22451023616807558) ,
+ rgb (0.22247308588973624, 0.06738821405309284, 0.22585960379408354) ,
+ rgb (0.2257539681670791, 0.06738213230014747, 0.22728984778098055) ,
+ rgb (0.2291562027859284, 0.06743473087115257, 0.22879681433956656) ,
+ rgb (0.23266299920501882, 0.06755710438847978, 0.23037617493752832) ,
+ rgb (0.23627495835774248, 0.06774359820987802, 0.23202360805926608) ,
+ rgb (0.23999586188690308, 0.06798502996477995, 0.23373434258507808) ,
+ rgb (0.2438114972024792, 0.06828985152901187, 0.23550427698321885) ,
+ rgb (0.247720929905011, 0.06865333790948652, 0.2373288009471749) ,
+ rgb (0.25172899728289466, 0.0690646308260355, 0.23920260612763083) ,
+ rgb (0.2558213554748177, 0.06953231029187984, 0.24112190491594204) ,
+ rgb (0.25999463887892144, 0.07005385560386188, 0.24308218808684579) ,
+ rgb (0.2642551220706094, 0.07061659562299544, 0.24507758869355967) ,
+ rgb (0.2685909594817286, 0.07122671627792246, 0.24710443563450618) ,
+ rgb (0.272997015188973, 0.07188355544616351, 0.2491584709323293) ,
+ rgb (0.277471508091428, 0.07258296989925478, 0.2512349399594277) ,
+ rgb (0.2820174629736694, 0.07331569321404097, 0.25332800295084507) ,
+ rgb (0.28662309235899847, 0.07408846082680887, 0.2554347867371703) ,
+ rgb (0.29128515387578635, 0.0748990498474667, 0.25755101595750435) ,
+ rgb (0.2960004726065818, 0.07574533600095842, 0.25967245030364566) ,
+ rgb (0.3007727681291869, 0.07661782433616476, 0.2617929409781967) ,
+ rgb (0.30559226007249934, 0.07752196310753731, 0.2639100669211966) ,
+ rgb (0.31045520848595526, 0.07845687167618218, 0.2660200572779356) ,
+ rgb (0.3153587000920581, 0.07942099731524319, 0.2681190407694196) ,
+ rgb (0.3202998655799406, 0.08041299473755484, 0.2702032289303951) ,
+ rgb (0.3252788886040126, 0.08142839007654609, 0.27226772884656186) ,
+ rgb (0.3302917447118144, 0.08246763389003825, 0.27430929404579435) ,
+ rgb (0.3353335322445545, 0.08353243411900396, 0.2763253435679004) ,
+ rgb (0.34040164359597463, 0.08462223619170267, 0.27831254595259397) ,
+ rgb (0.345493557138718, 0.08573665496512634, 0.28026769921081435) ,
+ rgb (0.3506067824603248, 0.08687555176033529, 0.28218770540182386) ,
+ rgb (0.35573889947341125, 0.08803897435024335, 0.2840695897279818) ,
+ rgb (0.36088752387578377, 0.0892271943627452, 0.28591050458531014) ,
+ rgb (0.36605031412464006, 0.0904406854276979, 0.2877077458811747) ,
+ rgb (0.3712250843130934, 0.09167999748026273, 0.2894586539763317) ,
+ rgb (0.3764103053221462, 0.09294519809377791, 0.2911602415731392) ,
+ rgb (0.38160247377467543, 0.09423873126371218, 0.2928110750626949) ,
+ rgb (0.3867993907954417, 0.09556181960083443, 0.29440901248173756) ,
+ rgb (0.39199887556812907, 0.09691583650296684, 0.2959521200550908) ,
+ rgb (0.39719876876325577, 0.09830232096827862, 0.2974385647628578) ,
+ rgb (0.40239692379737496, 0.09972293031495055, 0.2988667436973397) ,
+ rgb (0.4075912039268871, 0.10117945586419633, 0.300235195077286) ,
+ rgb (0.41277985630360303, 0.1026734006932461, 0.3015422643746897) ,
+ rgb (0.41796105205173684, 0.10420644885760968, 0.3027865203963184) ,
+ rgb (0.42313214269556043, 0.10578120994917611, 0.3039675809469457) ,
+ rgb (0.4282910131578975, 0.1073997763055258, 0.30508479060294547) ,
+ rgb (0.4334355841041439, 0.1090642347484701, 0.3061376792828915) ,
+ rgb (0.4385637818793154, 0.11077667828375456, 0.30712600062348083) ,
+ rgb (0.44367358645071275, 0.11253912421257944, 0.3080497309546545) ,
+ rgb (0.4487629917317482, 0.1143535557462255, 0.30890905921943196) ,
+ rgb (0.4538300508699989, 0.11622183788331528, 0.3097044124984492) ,
+ rgb (0.45887288947308297, 0.11814571137706886, 0.3104363697903881) ,
+ rgb (0.46389102840284874, 0.12012561256850712, 0.31110343446582983) ,
+ rgb (0.46888111384598413, 0.12216445576414045, 0.31170911458932665) ,
+ rgb (0.473841437035254, 0.12426354237989065, 0.31225470169927194) ,
+ rgb (0.47877034239726296, 0.12642401401409453, 0.3127417273582196) ,
+ rgb (0.48366628618847957, 0.1286467902201389, 0.31317188565991266) ,
+ rgb (0.48852847371852987, 0.13093210934893723, 0.31354553695453014) ,
+ rgb (0.49335504375145617, 0.13328091630401023, 0.31386561956734976) ,
+ rgb (0.4981443546207415, 0.13569380302451714, 0.314135190862664) ,
+ rgb (0.5028952497497061, 0.13817086581280427, 0.3143566215383367) ,
+ rgb (0.5076068118105369, 0.14071192654913128, 0.3145320012008257) ,
+ rgb (0.5122783510532176, 0.14331656120063752, 0.3146630922831542) ,
+ rgb (0.5169084880054446, 0.14598463068714407, 0.3147540759228004) ,
+ rgb (0.5214965286322996, 0.14871544765633712, 0.3148076795453443) ,
+ rgb (0.5260418962547748, 0.15150818660835483, 0.31482653406646727) ,
+ rgb (0.5305442048985645, 0.15436183633886777, 0.3148129978918713) ,
+ rgb (0.5350027976174474, 0.15727540775107324, 0.3147708520739653) ,
+ rgb (0.5394173664919906, 0.16024769309971934, 0.31470295028655965) ,
+ rgb (0.5437877131360856, 0.16327738551419116, 0.31461204226295625) ,
+ rgb (0.5481137003346762, 0.1663630904279047, 0.3145010299091471) ,
+ rgb (0.5523952157271191, 0.16950338809328983, 0.3143729155461537) ,
+ rgb (0.5566322903496934, 0.17269677158182117, 0.31423043195101424) ,
+ rgb (0.5608249903911717, 0.17594170887918095, 0.31407639883970623) ,
+ rgb (0.564973435290177, 0.17923664950367169, 0.3139136046337036) ,
+ rgb (0.5690778478401143, 0.18258004462335425, 0.3137444095679653) ,
+ rgb (0.5731384575410787, 0.18597036007065024, 0.3135712686852) ,
+ rgb (0.5771555081299204, 0.18940601489760422, 0.3133970433357208) ,
+ rgb (0.5811293276158656, 0.19288548904692518, 0.3132239939418394) ,
+ rgb (0.5850602439646688, 0.19640737049066315, 0.3130540116373273) ,
+ rgb (0.5889486193554471, 0.19997020971775276, 0.31288922211590126) ,
+ rgb (0.5927948053652026, 0.20357251410079796, 0.3127323483930494) ,
+ rgb (0.5965991810912237, 0.207212956082026, 0.3125852303112123) ,
+ rgb (0.6003621301041158, 0.21089030138947745, 0.3124493441041469) ,
+ rgb (0.6040840169673274, 0.21460331490206347, 0.31232652641170694) ,
+ rgb (0.6077652399481865, 0.21835070166659282, 0.312219032918702) ,
+ rgb (0.6114062072731884, 0.22213124697023234, 0.3121288139643524) ,
+ rgb (0.6150072323639137, 0.22594402043981826, 0.3120568068576574) ,
+ rgb (0.6185686525887719, 0.2297879924917992, 0.3120046383872893) ,
+ rgb (0.6220907982108261, 0.2336621873300741, 0.3119738327362739) ,
+ rgb (0.6255741650043496, 0.23756535071152696, 0.3119669831491227) ,
+ rgb (0.6290189201698587, 0.24149689191922535, 0.3119844719564572) ,
+ rgb (0.6324253485421027, 0.24545598775548677, 0.3120276597462445) ,
+ rgb (0.6357937104834237, 0.24944185818822678, 0.3120979395330059) ,
+ rgb (0.6391243387840212, 0.2534536546198314, 0.3121968961206398) ,
+ rgb (0.642417577481186, 0.257490519876798, 0.31232631707560987) ,
+ rgb (0.6456734938264543, 0.2615520316161528, 0.31248673753935263) ,
+ rgb (0.6488923016945825, 0.2656375533620908, 0.3126794181957019) ,
+ rgb (0.652074172902773, 0.269746505252367, 0.3129056060581917) ,
+ rgb (0.6552193260932713, 0.2738782665241015, 0.3131666792687211) ,
+ rgb (0.6583280801134499, 0.2780321095766563, 0.3134643447952643) ,
+ rgb (0.6614003753260178, 0.28220778870555907, 0.3137991292649849) ,
+ rgb (0.6644363246987884, 0.2864048361425618, 0.31417223403606975) ,
+ rgb (0.6674360376636913, 0.29062280081258873, 0.31458483752056837) ,
+ rgb (0.670399595476762, 0.29486126309253047, 0.3150381395687221) ,
+ rgb (0.6733272556481733, 0.29911962764489264, 0.3155337232398221) ,
+ rgb (0.6762189792440975, 0.30339762792450425, 0.3160724937230589) ,
+ rgb (0.6790747402815734, 0.30769497879760166, 0.31665545668946665) ,
+ rgb (0.6818945715094452, 0.31201133280550686, 0.3172838048924495) ,
+ rgb (0.6846785094249453, 0.3163463482122221, 0.31795870784057567) ,
+ rgb (0.6874265643516962, 0.32069970535138104, 0.3186813762227769) ,
+ rgb (0.6901389321505248, 0.32507091815606004, 0.319453323328983) ,
+ rgb (0.6928154484676493, 0.32945984647042675, 0.3202754315314667) ,
+ rgb (0.6954560834689112, 0.33386622163232865, 0.3211488430698579) ,
+ rgb (0.6980608153581771, 0.3382897632604862, 0.3220747885521809) ,
+ rgb (0.700629624772421, 0.34273019305341756, 0.32305449047765694) ,
+ rgb (0.7031624945881415, 0.34718723719598, 0.32408913679491225) ,
+ rgb (0.7056595112261009, 0.3516605297812094, 0.32518014084085567) ,
+ rgb (0.7081205956842048, 0.356149855233803, 0.32632861885644465) ,
+ rgb (0.7105456546582587, 0.36065500290840113, 0.3275357416278876) ,
+ rgb (0.7129346683977347, 0.36517570519856757, 0.3288027427038317) ,
+ rgb (0.7152876061484729, 0.3697117022522345, 0.3301308728723546) ,
+ rgb (0.7176044490813385, 0.3742627271068619, 0.3315213862095893) ,
+ rgb (0.7198852149054985, 0.37882848839337313, 0.332975552002454) ,
+ rgb (0.7221299918421461, 0.3834086450896306, 0.33449469983585844) ,
+ rgb (0.7243386564778159, 0.38800301593162145, 0.3360799596569183) ,
+ rgb (0.7265112290022755, 0.3926113126792577, 0.3377325942005665) ,
+ rgb (0.7286477385671655, 0.39723324476747235, 0.33945384341064017) ,
+ rgb (0.7307482075484517, 0.401868526884681, 0.3412449533046818) ,
+ rgb (0.7328127050626875, 0.4065168468778026, 0.3431071517341082) ,
+ rgb (0.7348413359856494, 0.4111778700451951, 0.3450416947080907) ,
+ rgb (0.7368342217358587, 0.4158512585029011, 0.347049785207584) ,
+ rgb (0.7387914002459927, 0.4205367299231533, 0.34913260148542435) ,
+ rgb (0.7407130161950609, 0.4252339389526239, 0.35129130890802607) ,
+ rgb (0.7425992159973317, 0.42994254036133867, 0.3535270924537459) ,
+ rgb (0.7444501867657067, 0.4346621718461711, 0.35584108091122535) ,
+ rgb (0.7462661578916344, 0.439392450449735, 0.3582343914230064) ,
+ rgb (0.7480473927555956, 0.44413297780351974, 0.36070813602540136) ,
+ rgb (0.7497942054717047, 0.4488833348154881, 0.3632633755836028) ,
+ rgb (0.7515068504589166, 0.45364314496866825, 0.36590112443835765) ,
+ rgb (0.7531856636904657, 0.45841199172949604, 0.3686223664223477) ,
+ rgb (0.7548310506695954, 0.46318942799460555, 0.3714280448394211) ,
+ rgb (0.7564434157714071, 0.4679750143794846, 0.37431909037543515) ,
+ rgb (0.7580232553845584, 0.4727682731566229, 0.3772963553109668) ,
+ rgb (0.7595711110534006, 0.4775687122205708, 0.380360657784311) ,
+ rgb (0.7610876378057071, 0.48237579130289127, 0.3835127572385229) ,
+ rgb (0.7625733355405261, 0.48718906673415824, 0.38675335037837993) ,
+ rgb (0.7640288560928866, 0.49200802533379656, 0.39008308392311997) ,
+ rgb (0.7654549259333051, 0.4968321290972723, 0.3935025400011538) ,
+ rgb (0.7668522895064389, 0.5016608471009063, 0.39701221751773474) ,
+ rgb (0.768221765997353, 0.5064936237128791, 0.40061257089416885) ,
+ rgb (0.7695642334401418, 0.5113298901696085, 0.4043039806968248) ,
+ rgb (0.7708809196230247, 0.516168926434691, 0.40808667584648967) ,
+ rgb (0.7721725722960555, 0.5210102658711383, 0.4119608998712287) ,
+ rgb (0.7734402182988989, 0.5258533209345156, 0.41592679539764366) ,
+ rgb (0.774684947460632, 0.5306974938477673, 0.4199844035696376) ,
+ rgb (0.775907907306857, 0.5355421788246119, 0.42413367909988375) ,
+ rgb (0.7771103295521099, 0.5403867491056124, 0.4283745037125848) ,
+ rgb (0.7782934580763312, 0.545230594884266, 0.432706647838971) ,
+ rgb (0.7794586273150664, 0.5500730841397727, 0.4371297985644476) ,
+ rgb (0.7806077474948377, 0.5549133574489061, 0.4416433242636464) ,
+ rgb (0.7817418047898184, 0.5597509805259486, 0.44624687186865436) ,
+ rgb (0.7828622526444091, 0.5645853311116688, 0.45093985823706345) ,
+ rgb (0.7839706083641448, 0.5694157832671042, 0.4557215474289206) ,
+ rgb (0.7850684501960684, 0.5742417003617839, 0.46059116206904965) ,
+ rgb (0.7861573713233296, 0.5790624629815756, 0.465547782819184) ,
+ rgb (0.7872390410818835, 0.5838774374455721, 0.47059039582133383) ,
+ rgb (0.7883151404562396, 0.5886860017356244, 0.4757179187907608) ,
+ rgb (0.7893873776625194, 0.5934875421745599, 0.48092913815357724) ,
+ rgb (0.7904577684772788, 0.5982813427706246, 0.48622257801969754) ,
+ rgb (0.7915283284347561, 0.603066705931472, 0.49159667021646397) ,
+ rgb (0.7926003430423745, 0.6078432208703702, 0.4970502062153201) ,
+ rgb (0.7936755969866496, 0.6126102933407219, 0.5025816129126943) ,
+ rgb (0.7947558597265404, 0.617367344002207, 0.5081892121310299) ,
+ rgb (0.7958429237958377, 0.6221137880845115, 0.5138712409190979) ,
+ rgb (0.7969385471995161, 0.626849056792967, 0.5196258425240281) ,
+ rgb (0.7980444781513664, 0.6315725822508955, 0.5254510814483478) ,
+ rgb (0.7991624518501963, 0.6362837937202919, 0.5313449594256143) ,
+ rgb (0.8002941538975398, 0.6409821330674986, 0.5373053518514104) ,
+ rgb (0.8014412429256005, 0.6456670345921877, 0.5433300863249918) ,
+ rgb (0.8026053114611295, 0.6503379374810385, 0.5494169158460365) ,
+ rgb (0.8037879253107763, 0.6549942654947263, 0.5555635086708381) ,
+ rgb (0.804990547908103, 0.6596354502756416, 0.5617674511054698) ,
+ rgb (0.8062146052692706, 0.6642608958528229, 0.5680262917864979) ,
+ rgb (0.8074614045096935, 0.6688700095398864, 0.5743374637345958) ,
+ rgb (0.8087321917008969, 0.6734621670219452, 0.5806983480557674) ,
+ rgb (0.8100280946652069, 0.6780367267397182, 0.5871062690808275) ,
+ rgb (0.8113501401176333, 0.6825930154624339, 0.5935584890905076) ,
+ rgb (0.8126992203988149, 0.6871303371461888, 0.600052148204351) ,
+ rgb (0.8140761104699334, 0.6916479479148213, 0.6065843782630862) ,
+ rgb (0.8154814662727948, 0.6961450550830809, 0.6131522120932265) ,
+ rgb (0.8169157577505589, 0.7006208301478398, 0.6197526063725792) ,
+ rgb (0.8183793116449822, 0.705074381896351, 0.626382454789333) ,
+ rgb (0.8198723065045529, 0.7095047497878748, 0.6330385704006711) ,
+ rgb (0.8213947205565636, 0.7139109141951604, 0.6397176669767276) ,
+ rgb (0.8229463511042843, 0.7182917733129006, 0.6464164243818421) ,
+ rgb (0.8245268129450285, 0.7226461431208888, 0.653131379154226) ,
+ rgb (0.8261354971058026, 0.7269727551823826, 0.659859001562165) ,
+ rgb (0.8277716072353446, 0.7312702332407809, 0.6665957020468297) ,
+ rgb (0.8294340781648147, 0.7355371221572935, 0.6733377200930191) ,
+ rgb (0.8311216352909631, 0.7397718464763862, 0.6800812520363146) ,
+ rgb (0.8328327718577798, 0.7439727181745988, 0.6868223587464855) ,
+ rgb (0.8345656905566583, 0.7481379479992134, 0.6935569764986385) ,
+ rgb (0.8363189884473793, 0.7522654895287526, 0.7002799902886496) ,
+ rgb (0.8380912347613196, 0.7563531486080863, 0.7069856139021298) ,
+ rgb (0.8398783988412087, 0.7603990719977968, 0.7136714781112923) ,
+ rgb (0.8416775076684515, 0.7644010120098295, 0.7203329938728462) ,
+ rgb (0.843485292229337, 0.7683566039987018, 0.7269653699897204) ,
+ rgb (0.8452981073195511, 0.7722633860104472, 0.7335636824054149) ,
+ rgb (0.847111955079651, 0.7761188023604716, 0.7401227576280706) ,
+ rgb (0.8489224556311764, 0.7799202140765015, 0.7466371929366437) ,
+ rgb (0.8507269702317879, 0.7836645734238389, 0.7530974636118285) ,
+ rgb (0.8525190720770844, 0.7873493613354844, 0.7594994148789691) ,
+ rgb (0.8542921961147046, 0.7909719677709199, 0.765838014779141) ,
+ rgb (0.856040223147254, 0.7945296360155061, 0.7721061003767414) ,
+ rgb (0.857756629435049, 0.7980196314271393, 0.778295716672475) ,
+ rgb (0.8594346370300241, 0.8014392309950078, 0.7843978875138392) ,
+ rgb (0.8610711702756552, 0.8047851790981223, 0.7903952966373629) ,
+ rgb (0.8626560105112757, 0.8080552380426153, 0.796282666437655) ,
+ rgb (0.8641834372394103, 0.8112464422465354, 0.8020461269686395) ,
+ rgb (0.8656493432560532, 0.8143554406751491, 0.8076697232416455) ,
+ rgb (0.867053149070485, 0.8173780404191124, 0.813134196269114) ,
+ rgb (0.8683995469581863, 0.8203087551218152, 0.8184163896312899) ,
+ rgb (0.8696913150261381, 0.8231415885956916, 0.8235047668317317) ,
+ rgb (0.8709384671729751, 0.8258685788943851, 0.8283849726114961) ,
+ rgb (0.8721533197845432, 0.8284805282370967, 0.8330486712880828) ,
+ rgb (0.8733517136091627, 0.8309671525127262, 0.8374885100119709) ,
+ rgb (0.8745379332026019, 0.8333197294864546, 0.8417192535806901) ,
+ rgb (0.875714587099614, 0.8355302318472394, 0.8457553751902708) ,
+ rgb (0.8768784845161469, 0.8375923807118654, 0.8496137354915025) ,
+ rgb (0.8780229843664901, 0.8395016561854007, 0.8533064535245892) ,
+ rgb (0.8791324424079277, 0.8412555488447591, 0.8568557229103964) ,
+ rgb (0.8801929331569581, 0.8428522482477862, 0.8602739992715663) ,
+ rgb (0.8811916987134195, 0.8442906671771735, 0.8635659516866988) ,
+ rgb (0.8821154248940161, 0.8455700725455935, 0.8667376504623333) ,
+ rgb (0.8829516859544853, 0.8466897027569927, 0.8697961704819097) ,
+ rgb (0.8836912714589804, 0.8476489176151927, 0.8727414710144156) ,
+ rgb (0.8843271305411354, 0.8484474157205542, 0.8755678522824297) ,
+ rgb (0.8848513815990857, 0.849084264228938, 0.8782823528537247) ,
+ rgb (0.8852589797263047, 0.8495589281098921, 0.8808841479402484) ,
+ rgb (0.8855471481195238, 0.8498717428363158, 0.8833620612117095) ,
+ rgb (0.8857115512284565, 0.8500218611585632, 0.8857253899008712)
+});
+
+
+list_data twilight_shifted = list_data(new pen[] {
+ rgb (0.18739228342697645, 0.07710209689958833, 0.21618875376309582) ,
+ rgb (0.18975853639094634, 0.07501986186214377, 0.2193005075652994) ,
+ rgb (0.19199449184606268, 0.0731828306492733, 0.22243385243433622) ,
+ rgb (0.19410351363791453, 0.07160830485689157, 0.22558727307410353) ,
+ rgb (0.1960826032659409, 0.07032122724242362, 0.22874673279569585) ,
+ rgb (0.19794834061899208, 0.06931406607166066, 0.23194647381302336) ,
+ rgb (0.19971571438603364, 0.06859271055370472, 0.23517094067076993) ,
+ rgb (0.2015613376412984, 0.06798327102620025, 0.23852974228695395) ,
+ rgb (0.20352007949514977, 0.06744417961242422, 0.24205576625191821) ,
+ rgb (0.20558051999470117, 0.06699046239786874, 0.24572497420147632) ,
+ rgb (0.2077442377448806, 0.06661453200418091, 0.24954644291943817) ,
+ rgb (0.21001214221188125, 0.06630857391894718, 0.2535289048041211) ,
+ rgb (0.21237411048541005, 0.06608502466175845, 0.2576516509356954) ,
+ rgb (0.21482843531473683, 0.06594038561377849, 0.26191675992376573) ,
+ rgb (0.21737845072382705, 0.06585966123356204, 0.2663420934966951) ,
+ rgb (0.22001251100779617, 0.0658579189189076, 0.2709027999432586) ,
+ rgb (0.22272706739121817, 0.06593379067565194, 0.275597146520537) ,
+ rgb (0.22552164337737857, 0.0660781731193956, 0.28043398847505197) ,
+ rgb (0.2283917709422868, 0.06628997924139618, 0.28541074411068496) ,
+ rgb (0.23132955273021344, 0.06657618693909059, 0.29051361067988485) ,
+ rgb (0.23433055727563878, 0.0669355996616394, 0.295740099298676) ,
+ rgb (0.23739062429054825, 0.06736588805055552, 0.3010892218406587) ,
+ rgb (0.2405081333229594, 0.0678571038148556, 0.3065705449367832) ,
+ rgb (0.24367372557466271, 0.06841985515092269, 0.3121652405088837) ,
+ rgb (0.24688226237959, 0.06905363944920445, 0.31786993834254956) ,
+ rgb (0.2501284530619938, 0.06975820642910699, 0.32368100685760637) ,
+ rgb (0.25340685873736807, 0.07053358292685183, 0.3295945757321303) ,
+ rgb (0.256711916510839, 0.07138010624208224, 0.3356064898460009) ,
+ rgb (0.26003895187439957, 0.0722947810433622, 0.3417175669546984) ,
+ rgb (0.26338121807151404, 0.07328165793989708, 0.34791888996380105) ,
+ rgb (0.26673233211995284, 0.0743440180285462, 0.3542027606624096) ,
+ rgb (0.2700863774911405, 0.07548367558427554, 0.36056376228111864) ,
+ rgb (0.2734373934245081, 0.07670280023749607, 0.36699616136347685) ,
+ rgb (0.2767793961581559, 0.07800394103378822, 0.37349382846504675) ,
+ rgb (0.2801063857697547, 0.07938999480226153, 0.38005028528138707) ,
+ rgb (0.28341239797185225, 0.08086415336549937, 0.38665868550105914) ,
+ rgb (0.28669151388283165, 0.08242987384848069, 0.39331182532243375) ,
+ rgb (0.2899379244517661, 0.08409078829085731, 0.40000214725256295) ,
+ rgb (0.2931459309698525, 0.08585065688962071, 0.40672178082365834) ,
+ rgb (0.2963100038890529, 0.08771325096046395, 0.41346259134143476) ,
+ rgb (0.2994248396021477, 0.08968225371675004, 0.42021619665853854) ,
+ rgb (0.3024853636457425, 0.0917611873973036, 0.42697404043749887) ,
+ rgb (0.30548675819945936, 0.09395276484082374, 0.4337284999936111) ,
+ rgb (0.30842444457210105, 0.09625938534057774, 0.44047194882050544) ,
+ rgb (0.31129434479712365, 0.0986847719340522, 0.4471931371516162) ,
+ rgb (0.3140927841475553, 0.10123077676403242, 0.45388335612058467) ,
+ rgb (0.316816480890235, 0.10389861387653518, 0.46053414662739794) ,
+ rgb (0.31946262395497965, 0.1066887988239266, 0.46713728801395243) ,
+ rgb (0.3220288227606932, 0.10960114111258401, 0.4736849472572688) ,
+ rgb (0.32451307931207785, 0.11263459791730848, 0.48017007211645196) ,
+ rgb (0.3269137124539796, 0.1157873496841953, 0.4865864649569746) ,
+ rgb (0.3292300520323141, 0.11905764321981127, 0.49292595612342666) ,
+ rgb (0.33146154891145124, 0.12244245263391232, 0.4991827458843107) ,
+ rgb (0.33360804901486, 0.1259381830100592, 0.505351647966549) ,
+ rgb (0.33566978565015315, 0.12954074251271822, 0.5114280721516895) ,
+ rgb (0.3376473209067111, 0.13324562282438077, 0.5174080757397947) ,
+ rgb (0.33954168752669694, 0.1370480189671817, 0.5232879753508524) ,
+ rgb (0.34135411074506483, 0.1409427920655632, 0.5290650094033675) ,
+ rgb (0.34308600291572294, 0.14492465359918028, 0.534737042820671) ,
+ rgb (0.34473901574536375, 0.1489882058982641, 0.5403024592040654) ,
+ rgb (0.3463150717579309, 0.15312802296627787, 0.5457599924248665) ,
+ rgb (0.3478165323877778, 0.1573386351115298, 0.5511085345270326) ,
+ rgb (0.34924513554955644, 0.16161477763045118, 0.5563483747416378) ,
+ rgb (0.3506030444193101, 0.1659512998472086, 0.5614796470399323) ,
+ rgb (0.3518924860887379, 0.17034320478524959, 0.5665028491121665) ,
+ rgb (0.35311574421123737, 0.17478570377561287, 0.5714187152355529) ,
+ rgb (0.3542753496066376, 0.17927413271618647, 0.5762280966066872) ,
+ rgb (0.3553741530690672, 0.18380392577704466, 0.580931914318328) ,
+ rgb (0.35641381143126327, 0.18837119869242164, 0.5855320765920552) ,
+ rgb (0.35739663292915563, 0.1929720819784246, 0.5900301125106313) ,
+ rgb (0.3583248996661781, 0.197602942459778, 0.5944276851750107) ,
+ rgb (0.35920088560930186, 0.20226037920758122, 0.5987265295935138) ,
+ rgb (0.36002681809096376, 0.20694122817889948, 0.6029284543191687) ,
+ rgb (0.36080493826624654, 0.21164251793458128, 0.6070353217206471) ,
+ rgb (0.36153829010998356, 0.21636111429594002, 0.6110488067964093) ,
+ rgb (0.36222809558295926, 0.22109488427338303, 0.6149711234609613) ,
+ rgb (0.3628764356004103, 0.2258414929328703, 0.6188041741082302) ,
+ rgb (0.36348537610385145, 0.2305987621839642, 0.6225498862239288) ,
+ rgb (0.3640569302208851, 0.23536470386204195, 0.6262101345195302) ,
+ rgb (0.3645930889012501, 0.24013747024823828, 0.629786801550261) ,
+ rgb (0.3650957984588681, 0.24491536803550484, 0.6332817352005559) ,
+ rgb (0.3655669837353898, 0.24969683475296395, 0.6366967518748858) ,
+ rgb (0.36600853966739794, 0.25448043878086224, 0.6400336180336859) ,
+ rgb (0.3664224325155063, 0.25926481158628106, 0.6432940914076554) ,
+ rgb (0.3668108554010799, 0.26404857724525643, 0.6464799165290824) ,
+ rgb (0.36717513650699446, 0.26883085667326956, 0.6495927229789225) ,
+ rgb (0.36751707094367697, 0.2736106331709098, 0.6526341171161864) ,
+ rgb (0.3678384369653108, 0.2783869718129776, 0.655605668384537) ,
+ rgb (0.3681410147989972, 0.2831590122118299, 0.6585088880697231) ,
+ rgb (0.36842655638020444, 0.2879259643777846, 0.661345269109446) ,
+ rgb (0.3686968223189527, 0.292687098561501, 0.6641162529823691) ,
+ rgb (0.3689535530659678, 0.29744175492366276, 0.6668232208982426) ,
+ rgb (0.36919847837592484, 0.3021893217650707, 0.6694675433161452) ,
+ rgb (0.3694333459127623, 0.3069292355186234, 0.6720505284912062) ,
+ rgb (0.36965987626565955, 0.3116609876295197, 0.6745734474341955) ,
+ rgb (0.3698798032902536, 0.31638410101153364, 0.6770375543809057) ,
+ rgb (0.37009487130772695, 0.3210981375964933, 0.6794440539905685) ,
+ rgb (0.37030682071842685, 0.32580269697872455, 0.6817941168448668) ,
+ rgb (0.37051738634484427, 0.3304974124430785, 0.6840888878885721) ,
+ rgb (0.3707283327942267, 0.33518193808489577, 0.6863294816960677) ,
+ rgb (0.3709415155133733, 0.33985591488818123, 0.6885170337950512) ,
+ rgb (0.37115856636209105, 0.3445191141023017, 0.6906525358646499) ,
+ rgb (0.37138124223736607, 0.34917126878479027, 0.6927370347192883) ,
+ rgb (0.3716113323440048, 0.3538121372967869, 0.6947714991938089) ,
+ rgb (0.3718506155898596, 0.3584414828587522, 0.6967569581025654) ,
+ rgb (0.3721008970244382, 0.3630590973698238, 0.6986943461507372) ,
+ rgb (0.37236397858465387, 0.36766477862108266, 0.7005846349652077) ,
+ rgb (0.37264166757849604, 0.3722583500483685, 0.7024287314570723) ,
+ rgb (0.3729357864666503, 0.3768396383521984, 0.7042275578058994) ,
+ rgb (0.37324816143326384, 0.38140848555753937, 0.7059820097480604) ,
+ rgb (0.3735806215098284, 0.3859647438605754, 0.7076929760731058) ,
+ rgb (0.3739349933047578, 0.3905082752937583, 0.7093613429347845) ,
+ rgb (0.3743131319931234, 0.3950389482828331, 0.7109879652237746) ,
+ rgb (0.3747168601930223, 0.3995566498711684, 0.7125736851650046) ,
+ rgb (0.37514802505380473, 0.4040612609993941, 0.7141193695725726) ,
+ rgb (0.375608469194424, 0.40855267638072096, 0.7156258509158755) ,
+ rgb (0.37610001286385814, 0.4130307995247706, 0.7170939691992023) ,
+ rgb (0.37662448930806297, 0.41749553747893614, 0.7185245473617611) ,
+ rgb (0.3771837184425123, 0.4219468022345483, 0.7199184152447577) ,
+ rgb (0.3777794975351373, 0.4263845142616835, 0.7212763999353023) ,
+ rgb (0.378413635091359, 0.43080859411413064, 0.7225993199306104) ,
+ rgb (0.3790878928311076, 0.43521897612544935, 0.7238879869132313) ,
+ rgb (0.3798040374484875, 0.4396155882122263, 0.7251432377876109) ,
+ rgb (0.3805638069656562, 0.4439983720863372, 0.7263658704513531) ,
+ rgb (0.3813688793045416, 0.4483672766927786, 0.7275567131714135) ,
+ rgb (0.38222094988570376, 0.45272225034283325, 0.7287165614400378) ,
+ rgb (0.3831216808440275, 0.457063235814072, 0.7298462679135326) ,
+ rgb (0.38407269378943537, 0.46139018782416635, 0.7309466543290268) ,
+ rgb (0.3850755679365139, 0.46570306719930193, 0.732018540336905) ,
+ rgb (0.386131841788921, 0.4700018340988123, 0.7330627749243106) ,
+ rgb (0.3872430145933025, 0.4742864593363539, 0.7340801678785439) ,
+ rgb (0.3884105330084243, 0.47855691131792805, 0.7350715764115726) ,
+ rgb (0.38963580160340855, 0.48281316715123496, 0.7360378254693274) ,
+ rgb (0.390920175719949, 0.4870552025122304, 0.7369797713388125) ,
+ rgb (0.39226494876209317, 0.4912830033289926, 0.7378982478447508) ,
+ rgb (0.39367135736822567, 0.4954965577745118, 0.738794102296364) ,
+ rgb (0.3951405880820763, 0.4996958532637776, 0.7396682021171571) ,
+ rgb (0.3966737490566561, 0.5038808905384797, 0.7405213858051674) ,
+ rgb (0.3982719152586337, 0.5080516653927614, 0.7413545091809972) ,
+ rgb (0.39993606933454834, 0.5122081814321852, 0.7421684457131799) ,
+ rgb (0.40166714010896104, 0.5163504496968876, 0.7429640345324835) ,
+ rgb (0.40346600333905397, 0.5204784765384003, 0.7437421522356709) ,
+ rgb (0.4053334378930318, 0.5245922817498312, 0.7445036583670813) ,
+ rgb (0.4072701869421907, 0.5286918801105741, 0.7452494263758127) ,
+ rgb (0.4092768899914751, 0.5327773017713032, 0.7459803063570782) ,
+ rgb (0.4113541469730457, 0.5368485776500593, 0.7466971285506578) ,
+ rgb (0.4135024574331473, 0.5409057477109848, 0.7474007329754309) ,
+ rgb (0.4157223260454232, 0.544948827153504, 0.7480920445900052) ,
+ rgb (0.4180141407923363, 0.5489778542188889, 0.7487719316700112) ,
+ rgb (0.42037822361396326, 0.5529928715810817, 0.7494412559451894) ,
+ rgb (0.4228148567577266, 0.5569939212699658, 0.7501008698822764) ,
+ rgb (0.42532423665011354, 0.560981049599503, 0.7507516498900512) ,
+ rgb (0.42790652284925834, 0.5649543060909209, 0.7513944352191484) ,
+ rgb (0.4305617907305757, 0.5689137457245718, 0.752030080993127) ,
+ rgb (0.43329008867358393, 0.5728594162560667, 0.7526594653256667) ,
+ rgb (0.4360913895835637, 0.5767913799818608, 0.7532834105961016) ,
+ rgb (0.43896563958048396, 0.5807096924109849, 0.7539027620828594) ,
+ rgb (0.441912717666964, 0.5846144110017557, 0.7545183888441067) ,
+ rgb (0.4449324685421538, 0.5885055998308617, 0.7551311041857901) ,
+ rgb (0.4480247093358917, 0.5923833145214658, 0.7557417647410792) ,
+ rgb (0.45118918687617743, 0.5962476205135354, 0.7563512064324664) ,
+ rgb (0.45442563977552913, 0.6000985950385866, 0.7569601366060649) ,
+ rgb (0.45773377230160567, 0.6039363004658646, 0.7575693690185916) ,
+ rgb (0.4611132664702388, 0.607760777169989, 0.7581798643680714) ,
+ rgb (0.4645637671630393, 0.6115720882286415, 0.7587924262302581) ,
+ rgb (0.46808490970531597, 0.6153702869579029, 0.7594078989109274) ,
+ rgb (0.4716762951887709, 0.6191554324288464, 0.7600270922788305) ,
+ rgb (0.47533752394906287, 0.6229275728383581, 0.7606508557181775) ,
+ rgb (0.47906816236197386, 0.6266867625186013, 0.7612800037566242) ,
+ rgb (0.4828677867260272, 0.6304330455306234, 0.761915371498953) ,
+ rgb (0.4867359599430568, 0.6341664625110051, 0.7625578008592404) ,
+ rgb (0.4906722493856122, 0.6378870485884708, 0.7632081276316384) ,
+ rgb (0.4946761847863938, 0.6415948411950443, 0.7638671900213091) ,
+ rgb (0.4987473366135607, 0.6452898684900934, 0.7645357873418008) ,
+ rgb (0.5028853540415561, 0.6489721673409526, 0.7652144671817491) ,
+ rgb (0.5070896957645166, 0.6526417240314645, 0.7659044566083585) ,
+ rgb (0.5113599254160193, 0.6562985398183186, 0.7666066378064533) ,
+ rgb (0.5156955988596057, 0.65994260812898, 0.7673219148959617) ,
+ rgb (0.5200962739223556, 0.6635739143403039, 0.768051194033441) ,
+ rgb (0.5245615147059358, 0.6671924299614223, 0.7687954171423095) ,
+ rgb (0.529090861832473, 0.6707981230280622, 0.7695555229231313) ,
+ rgb (0.533683891477284, 0.6743909370521273, 0.7703325054879735) ,
+ rgb (0.5383401557517628, 0.677970811290954, 0.7711273443905772) ,
+ rgb (0.5430593242401823, 0.6815376725306588, 0.7719407969783508) ,
+ rgb (0.5478409815301863, 0.6850914221850988, 0.7727738647344087) ,
+ rgb (0.5526845058934713, 0.6886319451516638, 0.7736279426902245) ,
+ rgb (0.5575894041960517, 0.6921591145825405, 0.7745041337932782) ,
+ rgb (0.5625551535721934, 0.6956727838162965, 0.7754035914230984) ,
+ rgb (0.5675811785386197, 0.6991727930264627, 0.776327485342753) ,
+ rgb (0.5726668948158774, 0.7026589535425779, 0.7772770268091199) ,
+ rgb (0.5778116438998202, 0.7061310615715398, 0.7782534512102552) ,
+ rgb (0.5830148703693241, 0.7095888767699747, 0.7792578182047659) ,
+ rgb (0.588275797805555, 0.7130321464645814, 0.7802914140563652) ,
+ rgb (0.5935933569683722, 0.7164606049658685, 0.781355882376401) ,
+ rgb (0.5989665814482068, 0.7198739489224673, 0.7824525989934664) ,
+ rgb (0.6043943420027486, 0.7232718614323369, 0.7835829559353559) ,
+ rgb (0.6098754317609306, 0.7266539875975829, 0.7847483573269471) ,
+ rgb (0.6154084641177048, 0.7300199523273969, 0.7859502270675048) ,
+ rgb (0.6209919306481755, 0.733369347989232, 0.7871899462469658) ,
+ rgb (0.6266240202260459, 0.7367017540369944, 0.7884690131633456) ,
+ rgb (0.6323027138710603, 0.740016721601314, 0.7897889276264043) ,
+ rgb (0.6380258682854598, 0.7433137671403319, 0.7911510045957317) ,
+ rgb (0.6437910831099849, 0.7465923800833657, 0.7925565320130605) ,
+ rgb (0.6495957300425348, 0.7498520122194177, 0.7940067402149911) ,
+ rgb (0.6554369232645472, 0.7530920875676843, 0.7955027112903105) ,
+ rgb (0.6613112930078745, 0.7563120270871903, 0.7970456043491897) ,
+ rgb (0.6672147980375281, 0.7595112803730375, 0.7986367465453776) ,
+ rgb (0.6731442255942621, 0.7626890873389048, 0.8002762854580953) ,
+ rgb (0.6790955449988215, 0.765844721313959, 0.8019646617300199) ,
+ rgb (0.6850644615439593, 0.7689774029354699, 0.8037020626717691) ,
+ rgb (0.691046410093091, 0.7720862946067809, 0.8054884169067907) ,
+ rgb (0.6970365443886174, 0.7751705000806606, 0.8073233538006345) ,
+ rgb (0.7030297722540817, 0.7782290497335813, 0.8092061884805697) ,
+ rgb (0.709020781345393, 0.7812608871607091, 0.8111359185511793) ,
+ rgb (0.7150040307625213, 0.7842648709158119, 0.8131111655994991) ,
+ rgb (0.7209728066553678, 0.7872399592345264, 0.8151307392087926) ,
+ rgb (0.726921775128297, 0.7901846863592763, 0.8171921746672638) ,
+ rgb (0.7328454364552346, 0.7930974646884407, 0.8192926338423038) ,
+ rgb (0.7387377170049494, 0.7959766573503101, 0.8214292278043301) ,
+ rgb (0.7445924777189017, 0.7988204771958325, 0.8235986758615652) ,
+ rgb (0.750403467654067, 0.8016269900896532, 0.8257973785108242) ,
+ rgb (0.7561644358438198, 0.8043940873347794, 0.8280213899472) ,
+ rgb (0.7618690793798029, 0.8071194938764749, 0.830266486168872) ,
+ rgb (0.7675110850441786, 0.8098007598713145, 0.8325281663805967) ,
+ rgb (0.7730841659017094, 0.8124352473546601, 0.8348017295057968) ,
+ rgb (0.7785789200822759, 0.8150208937874255, 0.8370834463093898) ,
+ rgb (0.7839910104276492, 0.8175542640053343, 0.8393674746403673) ,
+ rgb (0.7893144556460892, 0.8200321318870201, 0.8416486380471222) ,
+ rgb (0.7945430508923111, 0.8224511622630462, 0.8439218478682798) ,
+ rgb (0.79967075421268, 0.8248078181208093, 0.8461821002957853) ,
+ rgb (0.8046916442981458, 0.8270983878056066, 0.8484244929697402) ,
+ rgb (0.8095999819094809, 0.8293189667350546, 0.8506444160105037) ,
+ rgb (0.8143898212114309, 0.8314655869419785, 0.8528375906214702) ,
+ rgb (0.8190465467793753, 0.8335364929949034, 0.855002062870101) ,
+ rgb (0.8235742968025285, 0.8355248776479544, 0.8571319132851495) ,
+ rgb (0.8279689431601354, 0.837426007513952, 0.8592239945130679) ,
+ rgb (0.8322270571293441, 0.8392349062775448, 0.8612756350042788) ,
+ rgb (0.8363403180919118, 0.8409479651895194, 0.8632852800107016) ,
+ rgb (0.8403042080595778, 0.8425605950855084, 0.865250882410458) ,
+ rgb (0.8441261828674842, 0.8440648271103739, 0.8671697332269007) ,
+ rgb (0.8478071070257792, 0.8454546229209523, 0.8690403678369444) ,
+ rgb (0.8513371457085719, 0.8467273579611647, 0.8708608165735044) ,
+ rgb (0.8547259318925698, 0.8478748812467282, 0.8726282980930582) ,
+ rgb (0.8579825924567037, 0.8488893481028184, 0.8743403855344628) ,
+ rgb (0.8611024543689985, 0.8497675485700126, 0.8759924292343957) ,
+ rgb (0.86408985081464, 0.8505039116750779, 0.8775792578489263) ,
+ rgb (0.8669601550533358, 0.8510896085314068, 0.8790976697717334) ,
+ rgb (0.8697047485350982, 0.8515240300479789, 0.8805388339000336) ,
+ rgb (0.8723313408512408, 0.8518016547808089, 0.8818970435500162) ,
+ rgb (0.8748534750857597, 0.8519152612302319, 0.8831692696761383) ,
+ rgb (0.8772488085896548, 0.8518702833887027, 0.8843412038131143) ,
+ rgb (0.8795410528270573, 0.8516567540749572, 0.8854143767924102) ,
+ rgb (0.8817223105928579, 0.8512759407765347, 0.8863805692551482) ,
+ rgb (0.8837852019553906, 0.8507294054031063, 0.8872322209694989) ,
+ rgb (0.8857501584075443, 0.8500092494306783, 0.8879736506427196) ,
+ rgb (0.8857115512284565, 0.8500218611585632, 0.8857253899008712) ,
+ rgb (0.8855471481195238, 0.8498717428363158, 0.8833620612117095) ,
+ rgb (0.8852589797263047, 0.8495589281098921, 0.8808841479402484) ,
+ rgb (0.8848513815990857, 0.849084264228938, 0.8782823528537247) ,
+ rgb (0.8843271305411354, 0.8484474157205542, 0.8755678522824297) ,
+ rgb (0.8836912714589804, 0.8476489176151927, 0.8727414710144156) ,
+ rgb (0.8829516859544853, 0.8466897027569927, 0.8697961704819097) ,
+ rgb (0.8821154248940161, 0.8455700725455935, 0.8667376504623333) ,
+ rgb (0.8811916987134195, 0.8442906671771735, 0.8635659516866988) ,
+ rgb (0.8801929331569581, 0.8428522482477862, 0.8602739992715663) ,
+ rgb (0.8791324424079277, 0.8412555488447591, 0.8568557229103964) ,
+ rgb (0.8780229843664901, 0.8395016561854007, 0.8533064535245892) ,
+ rgb (0.8768784845161469, 0.8375923807118654, 0.8496137354915025) ,
+ rgb (0.875714587099614, 0.8355302318472394, 0.8457553751902708) ,
+ rgb (0.8745379332026019, 0.8333197294864546, 0.8417192535806901) ,
+ rgb (0.8733517136091627, 0.8309671525127262, 0.8374885100119709) ,
+ rgb (0.8721533197845432, 0.8284805282370967, 0.8330486712880828) ,
+ rgb (0.8709384671729751, 0.8258685788943851, 0.8283849726114961) ,
+ rgb (0.8696913150261381, 0.8231415885956916, 0.8235047668317317) ,
+ rgb (0.8683995469581863, 0.8203087551218152, 0.8184163896312899) ,
+ rgb (0.867053149070485, 0.8173780404191124, 0.813134196269114) ,
+ rgb (0.8656493432560532, 0.8143554406751491, 0.8076697232416455) ,
+ rgb (0.8641834372394103, 0.8112464422465354, 0.8020461269686395) ,
+ rgb (0.8626560105112757, 0.8080552380426153, 0.796282666437655) ,
+ rgb (0.8610711702756552, 0.8047851790981223, 0.7903952966373629) ,
+ rgb (0.8594346370300241, 0.8014392309950078, 0.7843978875138392) ,
+ rgb (0.857756629435049, 0.7980196314271393, 0.778295716672475) ,
+ rgb (0.856040223147254, 0.7945296360155061, 0.7721061003767414) ,
+ rgb (0.8542921961147046, 0.7909719677709199, 0.765838014779141) ,
+ rgb (0.8525190720770844, 0.7873493613354844, 0.7594994148789691) ,
+ rgb (0.8507269702317879, 0.7836645734238389, 0.7530974636118285) ,
+ rgb (0.8489224556311764, 0.7799202140765015, 0.7466371929366437) ,
+ rgb (0.847111955079651, 0.7761188023604716, 0.7401227576280706) ,
+ rgb (0.8452981073195511, 0.7722633860104472, 0.7335636824054149) ,
+ rgb (0.843485292229337, 0.7683566039987018, 0.7269653699897204) ,
+ rgb (0.8416775076684515, 0.7644010120098295, 0.7203329938728462) ,
+ rgb (0.8398783988412087, 0.7603990719977968, 0.7136714781112923) ,
+ rgb (0.8380912347613196, 0.7563531486080863, 0.7069856139021298) ,
+ rgb (0.8363189884473793, 0.7522654895287526, 0.7002799902886496) ,
+ rgb (0.8345656905566583, 0.7481379479992134, 0.6935569764986385) ,
+ rgb (0.8328327718577798, 0.7439727181745988, 0.6868223587464855) ,
+ rgb (0.8311216352909631, 0.7397718464763862, 0.6800812520363146) ,
+ rgb (0.8294340781648147, 0.7355371221572935, 0.6733377200930191) ,
+ rgb (0.8277716072353446, 0.7312702332407809, 0.6665957020468297) ,
+ rgb (0.8261354971058026, 0.7269727551823826, 0.659859001562165) ,
+ rgb (0.8245268129450285, 0.7226461431208888, 0.653131379154226) ,
+ rgb (0.8229463511042843, 0.7182917733129006, 0.6464164243818421) ,
+ rgb (0.8213947205565636, 0.7139109141951604, 0.6397176669767276) ,
+ rgb (0.8198723065045529, 0.7095047497878748, 0.6330385704006711) ,
+ rgb (0.8183793116449822, 0.705074381896351, 0.626382454789333) ,
+ rgb (0.8169157577505589, 0.7006208301478398, 0.6197526063725792) ,
+ rgb (0.8154814662727948, 0.6961450550830809, 0.6131522120932265) ,
+ rgb (0.8140761104699334, 0.6916479479148213, 0.6065843782630862) ,
+ rgb (0.8126992203988149, 0.6871303371461888, 0.600052148204351) ,
+ rgb (0.8113501401176333, 0.6825930154624339, 0.5935584890905076) ,
+ rgb (0.8100280946652069, 0.6780367267397182, 0.5871062690808275) ,
+ rgb (0.8087321917008969, 0.6734621670219452, 0.5806983480557674) ,
+ rgb (0.8074614045096935, 0.6688700095398864, 0.5743374637345958) ,
+ rgb (0.8062146052692706, 0.6642608958528229, 0.5680262917864979) ,
+ rgb (0.804990547908103, 0.6596354502756416, 0.5617674511054698) ,
+ rgb (0.8037879253107763, 0.6549942654947263, 0.5555635086708381) ,
+ rgb (0.8026053114611295, 0.6503379374810385, 0.5494169158460365) ,
+ rgb (0.8014412429256005, 0.6456670345921877, 0.5433300863249918) ,
+ rgb (0.8002941538975398, 0.6409821330674986, 0.5373053518514104) ,
+ rgb (0.7991624518501963, 0.6362837937202919, 0.5313449594256143) ,
+ rgb (0.7980444781513664, 0.6315725822508955, 0.5254510814483478) ,
+ rgb (0.7969385471995161, 0.626849056792967, 0.5196258425240281) ,
+ rgb (0.7958429237958377, 0.6221137880845115, 0.5138712409190979) ,
+ rgb (0.7947558597265404, 0.617367344002207, 0.5081892121310299) ,
+ rgb (0.7936755969866496, 0.6126102933407219, 0.5025816129126943) ,
+ rgb (0.7926003430423745, 0.6078432208703702, 0.4970502062153201) ,
+ rgb (0.7915283284347561, 0.603066705931472, 0.49159667021646397) ,
+ rgb (0.7904577684772788, 0.5982813427706246, 0.48622257801969754) ,
+ rgb (0.7893873776625194, 0.5934875421745599, 0.48092913815357724) ,
+ rgb (0.7883151404562396, 0.5886860017356244, 0.4757179187907608) ,
+ rgb (0.7872390410818835, 0.5838774374455721, 0.47059039582133383) ,
+ rgb (0.7861573713233296, 0.5790624629815756, 0.465547782819184) ,
+ rgb (0.7850684501960684, 0.5742417003617839, 0.46059116206904965) ,
+ rgb (0.7839706083641448, 0.5694157832671042, 0.4557215474289206) ,
+ rgb (0.7828622526444091, 0.5645853311116688, 0.45093985823706345) ,
+ rgb (0.7817418047898184, 0.5597509805259486, 0.44624687186865436) ,
+ rgb (0.7806077474948377, 0.5549133574489061, 0.4416433242636464) ,
+ rgb (0.7794586273150664, 0.5500730841397727, 0.4371297985644476) ,
+ rgb (0.7782934580763312, 0.545230594884266, 0.432706647838971) ,
+ rgb (0.7771103295521099, 0.5403867491056124, 0.4283745037125848) ,
+ rgb (0.775907907306857, 0.5355421788246119, 0.42413367909988375) ,
+ rgb (0.774684947460632, 0.5306974938477673, 0.4199844035696376) ,
+ rgb (0.7734402182988989, 0.5258533209345156, 0.41592679539764366) ,
+ rgb (0.7721725722960555, 0.5210102658711383, 0.4119608998712287) ,
+ rgb (0.7708809196230247, 0.516168926434691, 0.40808667584648967) ,
+ rgb (0.7695642334401418, 0.5113298901696085, 0.4043039806968248) ,
+ rgb (0.768221765997353, 0.5064936237128791, 0.40061257089416885) ,
+ rgb (0.7668522895064389, 0.5016608471009063, 0.39701221751773474) ,
+ rgb (0.7654549259333051, 0.4968321290972723, 0.3935025400011538) ,
+ rgb (0.7640288560928866, 0.49200802533379656, 0.39008308392311997) ,
+ rgb (0.7625733355405261, 0.48718906673415824, 0.38675335037837993) ,
+ rgb (0.7610876378057071, 0.48237579130289127, 0.3835127572385229) ,
+ rgb (0.7595711110534006, 0.4775687122205708, 0.380360657784311) ,
+ rgb (0.7580232553845584, 0.4727682731566229, 0.3772963553109668) ,
+ rgb (0.7564434157714071, 0.4679750143794846, 0.37431909037543515) ,
+ rgb (0.7548310506695954, 0.46318942799460555, 0.3714280448394211) ,
+ rgb (0.7531856636904657, 0.45841199172949604, 0.3686223664223477) ,
+ rgb (0.7515068504589166, 0.45364314496866825, 0.36590112443835765) ,
+ rgb (0.7497942054717047, 0.4488833348154881, 0.3632633755836028) ,
+ rgb (0.7480473927555956, 0.44413297780351974, 0.36070813602540136) ,
+ rgb (0.7462661578916344, 0.439392450449735, 0.3582343914230064) ,
+ rgb (0.7444501867657067, 0.4346621718461711, 0.35584108091122535) ,
+ rgb (0.7425992159973317, 0.42994254036133867, 0.3535270924537459) ,
+ rgb (0.7407130161950609, 0.4252339389526239, 0.35129130890802607) ,
+ rgb (0.7387914002459927, 0.4205367299231533, 0.34913260148542435) ,
+ rgb (0.7368342217358587, 0.4158512585029011, 0.347049785207584) ,
+ rgb (0.7348413359856494, 0.4111778700451951, 0.3450416947080907) ,
+ rgb (0.7328127050626875, 0.4065168468778026, 0.3431071517341082) ,
+ rgb (0.7307482075484517, 0.401868526884681, 0.3412449533046818) ,
+ rgb (0.7286477385671655, 0.39723324476747235, 0.33945384341064017) ,
+ rgb (0.7265112290022755, 0.3926113126792577, 0.3377325942005665) ,
+ rgb (0.7243386564778159, 0.38800301593162145, 0.3360799596569183) ,
+ rgb (0.7221299918421461, 0.3834086450896306, 0.33449469983585844) ,
+ rgb (0.7198852149054985, 0.37882848839337313, 0.332975552002454) ,
+ rgb (0.7176044490813385, 0.3742627271068619, 0.3315213862095893) ,
+ rgb (0.7152876061484729, 0.3697117022522345, 0.3301308728723546) ,
+ rgb (0.7129346683977347, 0.36517570519856757, 0.3288027427038317) ,
+ rgb (0.7105456546582587, 0.36065500290840113, 0.3275357416278876) ,
+ rgb (0.7081205956842048, 0.356149855233803, 0.32632861885644465) ,
+ rgb (0.7056595112261009, 0.3516605297812094, 0.32518014084085567) ,
+ rgb (0.7031624945881415, 0.34718723719598, 0.32408913679491225) ,
+ rgb (0.700629624772421, 0.34273019305341756, 0.32305449047765694) ,
+ rgb (0.6980608153581771, 0.3382897632604862, 0.3220747885521809) ,
+ rgb (0.6954560834689112, 0.33386622163232865, 0.3211488430698579) ,
+ rgb (0.6928154484676493, 0.32945984647042675, 0.3202754315314667) ,
+ rgb (0.6901389321505248, 0.32507091815606004, 0.319453323328983) ,
+ rgb (0.6874265643516962, 0.32069970535138104, 0.3186813762227769) ,
+ rgb (0.6846785094249453, 0.3163463482122221, 0.31795870784057567) ,
+ rgb (0.6818945715094452, 0.31201133280550686, 0.3172838048924495) ,
+ rgb (0.6790747402815734, 0.30769497879760166, 0.31665545668946665) ,
+ rgb (0.6762189792440975, 0.30339762792450425, 0.3160724937230589) ,
+ rgb (0.6733272556481733, 0.29911962764489264, 0.3155337232398221) ,
+ rgb (0.670399595476762, 0.29486126309253047, 0.3150381395687221) ,
+ rgb (0.6674360376636913, 0.29062280081258873, 0.31458483752056837) ,
+ rgb (0.6644363246987884, 0.2864048361425618, 0.31417223403606975) ,
+ rgb (0.6614003753260178, 0.28220778870555907, 0.3137991292649849) ,
+ rgb (0.6583280801134499, 0.2780321095766563, 0.3134643447952643) ,
+ rgb (0.6552193260932713, 0.2738782665241015, 0.3131666792687211) ,
+ rgb (0.652074172902773, 0.269746505252367, 0.3129056060581917) ,
+ rgb (0.6488923016945825, 0.2656375533620908, 0.3126794181957019) ,
+ rgb (0.6456734938264543, 0.2615520316161528, 0.31248673753935263) ,
+ rgb (0.642417577481186, 0.257490519876798, 0.31232631707560987) ,
+ rgb (0.6391243387840212, 0.2534536546198314, 0.3121968961206398) ,
+ rgb (0.6357937104834237, 0.24944185818822678, 0.3120979395330059) ,
+ rgb (0.6324253485421027, 0.24545598775548677, 0.3120276597462445) ,
+ rgb (0.6290189201698587, 0.24149689191922535, 0.3119844719564572) ,
+ rgb (0.6255741650043496, 0.23756535071152696, 0.3119669831491227) ,
+ rgb (0.6220907982108261, 0.2336621873300741, 0.3119738327362739) ,
+ rgb (0.6185686525887719, 0.2297879924917992, 0.3120046383872893) ,
+ rgb (0.6150072323639137, 0.22594402043981826, 0.3120568068576574) ,
+ rgb (0.6114062072731884, 0.22213124697023234, 0.3121288139643524) ,
+ rgb (0.6077652399481865, 0.21835070166659282, 0.312219032918702) ,
+ rgb (0.6040840169673274, 0.21460331490206347, 0.31232652641170694) ,
+ rgb (0.6003621301041158, 0.21089030138947745, 0.3124493441041469) ,
+ rgb (0.5965991810912237, 0.207212956082026, 0.3125852303112123) ,
+ rgb (0.5927948053652026, 0.20357251410079796, 0.3127323483930494) ,
+ rgb (0.5889486193554471, 0.19997020971775276, 0.31288922211590126) ,
+ rgb (0.5850602439646688, 0.19640737049066315, 0.3130540116373273) ,
+ rgb (0.5811293276158656, 0.19288548904692518, 0.3132239939418394) ,
+ rgb (0.5771555081299204, 0.18940601489760422, 0.3133970433357208) ,
+ rgb (0.5731384575410787, 0.18597036007065024, 0.3135712686852) ,
+ rgb (0.5690778478401143, 0.18258004462335425, 0.3137444095679653) ,
+ rgb (0.564973435290177, 0.17923664950367169, 0.3139136046337036) ,
+ rgb (0.5608249903911717, 0.17594170887918095, 0.31407639883970623) ,
+ rgb (0.5566322903496934, 0.17269677158182117, 0.31423043195101424) ,
+ rgb (0.5523952157271191, 0.16950338809328983, 0.3143729155461537) ,
+ rgb (0.5481137003346762, 0.1663630904279047, 0.3145010299091471) ,
+ rgb (0.5437877131360856, 0.16327738551419116, 0.31461204226295625) ,
+ rgb (0.5394173664919906, 0.16024769309971934, 0.31470295028655965) ,
+ rgb (0.5350027976174474, 0.15727540775107324, 0.3147708520739653) ,
+ rgb (0.5305442048985645, 0.15436183633886777, 0.3148129978918713) ,
+ rgb (0.5260418962547748, 0.15150818660835483, 0.31482653406646727) ,
+ rgb (0.5214965286322996, 0.14871544765633712, 0.3148076795453443) ,
+ rgb (0.5169084880054446, 0.14598463068714407, 0.3147540759228004) ,
+ rgb (0.5122783510532176, 0.14331656120063752, 0.3146630922831542) ,
+ rgb (0.5076068118105369, 0.14071192654913128, 0.3145320012008257) ,
+ rgb (0.5028952497497061, 0.13817086581280427, 0.3143566215383367) ,
+ rgb (0.4981443546207415, 0.13569380302451714, 0.314135190862664) ,
+ rgb (0.49335504375145617, 0.13328091630401023, 0.31386561956734976) ,
+ rgb (0.48852847371852987, 0.13093210934893723, 0.31354553695453014) ,
+ rgb (0.48366628618847957, 0.1286467902201389, 0.31317188565991266) ,
+ rgb (0.47877034239726296, 0.12642401401409453, 0.3127417273582196) ,
+ rgb (0.473841437035254, 0.12426354237989065, 0.31225470169927194) ,
+ rgb (0.46888111384598413, 0.12216445576414045, 0.31170911458932665) ,
+ rgb (0.46389102840284874, 0.12012561256850712, 0.31110343446582983) ,
+ rgb (0.45887288947308297, 0.11814571137706886, 0.3104363697903881) ,
+ rgb (0.4538300508699989, 0.11622183788331528, 0.3097044124984492) ,
+ rgb (0.4487629917317482, 0.1143535557462255, 0.30890905921943196) ,
+ rgb (0.44367358645071275, 0.11253912421257944, 0.3080497309546545) ,
+ rgb (0.4385637818793154, 0.11077667828375456, 0.30712600062348083) ,
+ rgb (0.4334355841041439, 0.1090642347484701, 0.3061376792828915) ,
+ rgb (0.4282910131578975, 0.1073997763055258, 0.30508479060294547) ,
+ rgb (0.42313214269556043, 0.10578120994917611, 0.3039675809469457) ,
+ rgb (0.41796105205173684, 0.10420644885760968, 0.3027865203963184) ,
+ rgb (0.41277985630360303, 0.1026734006932461, 0.3015422643746897) ,
+ rgb (0.4075912039268871, 0.10117945586419633, 0.300235195077286) ,
+ rgb (0.40239692379737496, 0.09972293031495055, 0.2988667436973397) ,
+ rgb (0.39719876876325577, 0.09830232096827862, 0.2974385647628578) ,
+ rgb (0.39199887556812907, 0.09691583650296684, 0.2959521200550908) ,
+ rgb (0.3867993907954417, 0.09556181960083443, 0.29440901248173756) ,
+ rgb (0.38160247377467543, 0.09423873126371218, 0.2928110750626949) ,
+ rgb (0.3764103053221462, 0.09294519809377791, 0.2911602415731392) ,
+ rgb (0.3712250843130934, 0.09167999748026273, 0.2894586539763317) ,
+ rgb (0.36605031412464006, 0.0904406854276979, 0.2877077458811747) ,
+ rgb (0.36088752387578377, 0.0892271943627452, 0.28591050458531014) ,
+ rgb (0.35573889947341125, 0.08803897435024335, 0.2840695897279818) ,
+ rgb (0.3506067824603248, 0.08687555176033529, 0.28218770540182386) ,
+ rgb (0.345493557138718, 0.08573665496512634, 0.28026769921081435) ,
+ rgb (0.34040164359597463, 0.08462223619170267, 0.27831254595259397) ,
+ rgb (0.3353335322445545, 0.08353243411900396, 0.2763253435679004) ,
+ rgb (0.3302917447118144, 0.08246763389003825, 0.27430929404579435) ,
+ rgb (0.3252788886040126, 0.08142839007654609, 0.27226772884656186) ,
+ rgb (0.3202998655799406, 0.08041299473755484, 0.2702032289303951) ,
+ rgb (0.3153587000920581, 0.07942099731524319, 0.2681190407694196) ,
+ rgb (0.31045520848595526, 0.07845687167618218, 0.2660200572779356) ,
+ rgb (0.30559226007249934, 0.07752196310753731, 0.2639100669211966) ,
+ rgb (0.3007727681291869, 0.07661782433616476, 0.2617929409781967) ,
+ rgb (0.2960004726065818, 0.07574533600095842, 0.25967245030364566) ,
+ rgb (0.29128515387578635, 0.0748990498474667, 0.25755101595750435) ,
+ rgb (0.28662309235899847, 0.07408846082680887, 0.2554347867371703) ,
+ rgb (0.2820174629736694, 0.07331569321404097, 0.25332800295084507) ,
+ rgb (0.277471508091428, 0.07258296989925478, 0.2512349399594277) ,
+ rgb (0.272997015188973, 0.07188355544616351, 0.2491584709323293) ,
+ rgb (0.2685909594817286, 0.07122671627792246, 0.24710443563450618) ,
+ rgb (0.2642551220706094, 0.07061659562299544, 0.24507758869355967) ,
+ rgb (0.25999463887892144, 0.07005385560386188, 0.24308218808684579) ,
+ rgb (0.2558213554748177, 0.06953231029187984, 0.24112190491594204) ,
+ rgb (0.25172899728289466, 0.0690646308260355, 0.23920260612763083) ,
+ rgb (0.247720929905011, 0.06865333790948652, 0.2373288009471749) ,
+ rgb (0.2438114972024792, 0.06828985152901187, 0.23550427698321885) ,
+ rgb (0.23999586188690308, 0.06798502996477995, 0.23373434258507808) ,
+ rgb (0.23627495835774248, 0.06774359820987802, 0.23202360805926608) ,
+ rgb (0.23266299920501882, 0.06755710438847978, 0.23037617493752832) ,
+ rgb (0.2291562027859284, 0.06743473087115257, 0.22879681433956656) ,
+ rgb (0.2257539681670791, 0.06738213230014747, 0.22728984778098055) ,
+ rgb (0.22247308588973624, 0.06738821405309284, 0.22585960379408354) ,
+ rgb (0.21930503925136402, 0.06746578636294004, 0.22451023616807558) ,
+ rgb (0.21625279838647882, 0.06761633027051639, 0.22324568672294431) ,
+ rgb (0.2133313859647627, 0.06783014842602667, 0.2220704321302429) ,
+ rgb (0.21052882914958676, 0.06812195249816172, 0.22098759107715404) ,
+ rgb (0.20785704662965598, 0.06848439879702528, 0.22000133917653536) ,
+ rgb (0.20531725273301316, 0.06891959226639757, 0.21911516689288835) ,
+ rgb (0.20290365333558247, 0.06943524858045896, 0.21833167885096033) ,
+ rgb (0.20058760685133747, 0.07006457614998421, 0.21762721310371608) ,
+ rgb (0.19819343656336558, 0.07097462525273879, 0.21690975060032436) ,
+ rgb (0.19571853588267552, 0.07215778103960274, 0.21617499187076789) ,
+ rgb (0.1931548636579131, 0.07360681904011795, 0.21542362939081539) ,
+ rgb (0.19049578401722037, 0.07531127841678764, 0.2146562337112265) ,
+ rgb (0.18774482037046955, 0.07725158846803931, 0.21387448578597812) ,
+ rgb (0.18488035509396164, 0.07942573027972388, 0.21307651648984993)
+});
+
+
+list_data viridis = list_data(new pen[] {
+ rgb (0.267004, 0.004874, 0.329415) ,
+ rgb (0.26851, 0.009605, 0.335427) ,
+ rgb (0.269944, 0.014625, 0.341379) ,
+ rgb (0.271305, 0.019942, 0.347269) ,
+ rgb (0.272594, 0.025563, 0.353093) ,
+ rgb (0.273809, 0.031497, 0.358853) ,
+ rgb (0.274952, 0.037752, 0.364543) ,
+ rgb (0.276022, 0.044167, 0.370164) ,
+ rgb (0.277018, 0.050344, 0.375715) ,
+ rgb (0.277941, 0.056324, 0.381191) ,
+ rgb (0.278791, 0.062145, 0.386592) ,
+ rgb (0.279566, 0.067836, 0.391917) ,
+ rgb (0.280267, 0.073417, 0.397163) ,
+ rgb (0.280894, 0.078907, 0.402329) ,
+ rgb (0.281446, 0.08432, 0.407414) ,
+ rgb (0.281924, 0.089666, 0.412415) ,
+ rgb (0.282327, 0.094955, 0.417331) ,
+ rgb (0.282656, 0.100196, 0.42216) ,
+ rgb (0.28291, 0.105393, 0.426902) ,
+ rgb (0.283091, 0.110553, 0.431554) ,
+ rgb (0.283197, 0.11568, 0.436115) ,
+ rgb (0.283229, 0.120777, 0.440584) ,
+ rgb (0.283187, 0.125848, 0.44496) ,
+ rgb (0.283072, 0.130895, 0.449241) ,
+ rgb (0.282884, 0.13592, 0.453427) ,
+ rgb (0.282623, 0.140926, 0.457517) ,
+ rgb (0.28229, 0.145912, 0.46151) ,
+ rgb (0.281887, 0.150881, 0.465405) ,
+ rgb (0.281412, 0.155834, 0.469201) ,
+ rgb (0.280868, 0.160771, 0.472899) ,
+ rgb (0.280255, 0.165693, 0.476498) ,
+ rgb (0.279574, 0.170599, 0.479997) ,
+ rgb (0.278826, 0.17549, 0.483397) ,
+ rgb (0.278012, 0.180367, 0.486697) ,
+ rgb (0.277134, 0.185228, 0.489898) ,
+ rgb (0.276194, 0.190074, 0.493001) ,
+ rgb (0.275191, 0.194905, 0.496005) ,
+ rgb (0.274128, 0.199721, 0.498911) ,
+ rgb (0.273006, 0.20452, 0.501721) ,
+ rgb (0.271828, 0.209303, 0.504434) ,
+ rgb (0.270595, 0.214069, 0.507052) ,
+ rgb (0.269308, 0.218818, 0.509577) ,
+ rgb (0.267968, 0.223549, 0.512008) ,
+ rgb (0.26658, 0.228262, 0.514349) ,
+ rgb (0.265145, 0.232956, 0.516599) ,
+ rgb (0.263663, 0.237631, 0.518762) ,
+ rgb (0.262138, 0.242286, 0.520837) ,
+ rgb (0.260571, 0.246922, 0.522828) ,
+ rgb (0.258965, 0.251537, 0.524736) ,
+ rgb (0.257322, 0.25613, 0.526563) ,
+ rgb (0.255645, 0.260703, 0.528312) ,
+ rgb (0.253935, 0.265254, 0.529983) ,
+ rgb (0.252194, 0.269783, 0.531579) ,
+ rgb (0.250425, 0.27429, 0.533103) ,
+ rgb (0.248629, 0.278775, 0.534556) ,
+ rgb (0.246811, 0.283237, 0.535941) ,
+ rgb (0.244972, 0.287675, 0.53726) ,
+ rgb (0.243113, 0.292092, 0.538516) ,
+ rgb (0.241237, 0.296485, 0.539709) ,
+ rgb (0.239346, 0.300855, 0.540844) ,
+ rgb (0.237441, 0.305202, 0.541921) ,
+ rgb (0.235526, 0.309527, 0.542944) ,
+ rgb (0.233603, 0.313828, 0.543914) ,
+ rgb (0.231674, 0.318106, 0.544834) ,
+ rgb (0.229739, 0.322361, 0.545706) ,
+ rgb (0.227802, 0.326594, 0.546532) ,
+ rgb (0.225863, 0.330805, 0.547314) ,
+ rgb (0.223925, 0.334994, 0.548053) ,
+ rgb (0.221989, 0.339161, 0.548752) ,
+ rgb (0.220057, 0.343307, 0.549413) ,
+ rgb (0.21813, 0.347432, 0.550038) ,
+ rgb (0.21621, 0.351535, 0.550627) ,
+ rgb (0.214298, 0.355619, 0.551184) ,
+ rgb (0.212395, 0.359683, 0.55171) ,
+ rgb (0.210503, 0.363727, 0.552206) ,
+ rgb (0.208623, 0.367752, 0.552675) ,
+ rgb (0.206756, 0.371758, 0.553117) ,
+ rgb (0.204903, 0.375746, 0.553533) ,
+ rgb (0.203063, 0.379716, 0.553925) ,
+ rgb (0.201239, 0.38367, 0.554294) ,
+ rgb (0.19943, 0.387607, 0.554642) ,
+ rgb (0.197636, 0.391528, 0.554969) ,
+ rgb (0.19586, 0.395433, 0.555276) ,
+ rgb (0.1941, 0.399323, 0.555565) ,
+ rgb (0.192357, 0.403199, 0.555836) ,
+ rgb (0.190631, 0.407061, 0.556089) ,
+ rgb (0.188923, 0.41091, 0.556326) ,
+ rgb (0.187231, 0.414746, 0.556547) ,
+ rgb (0.185556, 0.41857, 0.556753) ,
+ rgb (0.183898, 0.422383, 0.556944) ,
+ rgb (0.182256, 0.426184, 0.55712) ,
+ rgb (0.180629, 0.429975, 0.557282) ,
+ rgb (0.179019, 0.433756, 0.55743) ,
+ rgb (0.177423, 0.437527, 0.557565) ,
+ rgb (0.175841, 0.44129, 0.557685) ,
+ rgb (0.174274, 0.445044, 0.557792) ,
+ rgb (0.172719, 0.448791, 0.557885) ,
+ rgb (0.171176, 0.45253, 0.557965) ,
+ rgb (0.169646, 0.456262, 0.55803) ,
+ rgb (0.168126, 0.459988, 0.558082) ,
+ rgb (0.166617, 0.463708, 0.558119) ,
+ rgb (0.165117, 0.467423, 0.558141) ,
+ rgb (0.163625, 0.471133, 0.558148) ,
+ rgb (0.162142, 0.474838, 0.55814) ,
+ rgb (0.160665, 0.47854, 0.558115) ,
+ rgb (0.159194, 0.482237, 0.558073) ,
+ rgb (0.157729, 0.485932, 0.558013) ,
+ rgb (0.15627, 0.489624, 0.557936) ,
+ rgb (0.154815, 0.493313, 0.55784) ,
+ rgb (0.153364, 0.497, 0.557724) ,
+ rgb (0.151918, 0.500685, 0.557587) ,
+ rgb (0.150476, 0.504369, 0.55743) ,
+ rgb (0.149039, 0.508051, 0.55725) ,
+ rgb (0.147607, 0.511733, 0.557049) ,
+ rgb (0.14618, 0.515413, 0.556823) ,
+ rgb (0.144759, 0.519093, 0.556572) ,
+ rgb (0.143343, 0.522773, 0.556295) ,
+ rgb (0.141935, 0.526453, 0.555991) ,
+ rgb (0.140536, 0.530132, 0.555659) ,
+ rgb (0.139147, 0.533812, 0.555298) ,
+ rgb (0.13777, 0.537492, 0.554906) ,
+ rgb (0.136408, 0.541173, 0.554483) ,
+ rgb (0.135066, 0.544853, 0.554029) ,
+ rgb (0.133743, 0.548535, 0.553541) ,
+ rgb (0.132444, 0.552216, 0.553018) ,
+ rgb (0.131172, 0.555899, 0.552459) ,
+ rgb (0.129933, 0.559582, 0.551864) ,
+ rgb (0.128729, 0.563265, 0.551229) ,
+ rgb (0.127568, 0.566949, 0.550556) ,
+ rgb (0.126453, 0.570633, 0.549841) ,
+ rgb (0.125394, 0.574318, 0.549086) ,
+ rgb (0.124395, 0.578002, 0.548287) ,
+ rgb (0.123463, 0.581687, 0.547445) ,
+ rgb (0.122606, 0.585371, 0.546557) ,
+ rgb (0.121831, 0.589055, 0.545623) ,
+ rgb (0.121148, 0.592739, 0.544641) ,
+ rgb (0.120565, 0.596422, 0.543611) ,
+ rgb (0.120092, 0.600104, 0.54253) ,
+ rgb (0.119738, 0.603785, 0.5414) ,
+ rgb (0.119512, 0.607464, 0.540218) ,
+ rgb (0.119423, 0.611141, 0.538982) ,
+ rgb (0.119483, 0.614817, 0.537692) ,
+ rgb (0.119699, 0.61849, 0.536347) ,
+ rgb (0.120081, 0.622161, 0.534946) ,
+ rgb (0.120638, 0.625828, 0.533488) ,
+ rgb (0.12138, 0.629492, 0.531973) ,
+ rgb (0.122312, 0.633153, 0.530398) ,
+ rgb (0.123444, 0.636809, 0.528763) ,
+ rgb (0.12478, 0.640461, 0.527068) ,
+ rgb (0.126326, 0.644107, 0.525311) ,
+ rgb (0.128087, 0.647749, 0.523491) ,
+ rgb (0.130067, 0.651384, 0.521608) ,
+ rgb (0.132268, 0.655014, 0.519661) ,
+ rgb (0.134692, 0.658636, 0.517649) ,
+ rgb (0.137339, 0.662252, 0.515571) ,
+ rgb (0.14021, 0.665859, 0.513427) ,
+ rgb (0.143303, 0.669459, 0.511215) ,
+ rgb (0.146616, 0.67305, 0.508936) ,
+ rgb (0.150148, 0.676631, 0.506589) ,
+ rgb (0.153894, 0.680203, 0.504172) ,
+ rgb (0.157851, 0.683765, 0.501686) ,
+ rgb (0.162016, 0.687316, 0.499129) ,
+ rgb (0.166383, 0.690856, 0.496502) ,
+ rgb (0.170948, 0.694384, 0.493803) ,
+ rgb (0.175707, 0.6979, 0.491033) ,
+ rgb (0.180653, 0.701402, 0.488189) ,
+ rgb (0.185783, 0.704891, 0.485273) ,
+ rgb (0.19109, 0.708366, 0.482284) ,
+ rgb (0.196571, 0.711827, 0.479221) ,
+ rgb (0.202219, 0.715272, 0.476084) ,
+ rgb (0.20803, 0.718701, 0.472873) ,
+ rgb (0.214, 0.722114, 0.469588) ,
+ rgb (0.220124, 0.725509, 0.466226) ,
+ rgb (0.226397, 0.728888, 0.462789) ,
+ rgb (0.232815, 0.732247, 0.459277) ,
+ rgb (0.239374, 0.735588, 0.455688) ,
+ rgb (0.24607, 0.73891, 0.452024) ,
+ rgb (0.252899, 0.742211, 0.448284) ,
+ rgb (0.259857, 0.745492, 0.444467) ,
+ rgb (0.266941, 0.748751, 0.440573) ,
+ rgb (0.274149, 0.751988, 0.436601) ,
+ rgb (0.281477, 0.755203, 0.432552) ,
+ rgb (0.288921, 0.758394, 0.428426) ,
+ rgb (0.296479, 0.761561, 0.424223) ,
+ rgb (0.304148, 0.764704, 0.419943) ,
+ rgb (0.311925, 0.767822, 0.415586) ,
+ rgb (0.319809, 0.770914, 0.411152) ,
+ rgb (0.327796, 0.77398, 0.40664) ,
+ rgb (0.335885, 0.777018, 0.402049) ,
+ rgb (0.344074, 0.780029, 0.397381) ,
+ rgb (0.35236, 0.783011, 0.392636) ,
+ rgb (0.360741, 0.785964, 0.387814) ,
+ rgb (0.369214, 0.788888, 0.382914) ,
+ rgb (0.377779, 0.791781, 0.377939) ,
+ rgb (0.386433, 0.794644, 0.372886) ,
+ rgb (0.395174, 0.797475, 0.367757) ,
+ rgb (0.404001, 0.800275, 0.362552) ,
+ rgb (0.412913, 0.803041, 0.357269) ,
+ rgb (0.421908, 0.805774, 0.35191) ,
+ rgb (0.430983, 0.808473, 0.346476) ,
+ rgb (0.440137, 0.811138, 0.340967) ,
+ rgb (0.449368, 0.813768, 0.335384) ,
+ rgb (0.458674, 0.816363, 0.329727) ,
+ rgb (0.468053, 0.818921, 0.323998) ,
+ rgb (0.477504, 0.821444, 0.318195) ,
+ rgb (0.487026, 0.823929, 0.312321) ,
+ rgb (0.496615, 0.826376, 0.306377) ,
+ rgb (0.506271, 0.828786, 0.300362) ,
+ rgb (0.515992, 0.831158, 0.294279) ,
+ rgb (0.525776, 0.833491, 0.288127) ,
+ rgb (0.535621, 0.835785, 0.281908) ,
+ rgb (0.545524, 0.838039, 0.275626) ,
+ rgb (0.555484, 0.840254, 0.269281) ,
+ rgb (0.565498, 0.84243, 0.262877) ,
+ rgb (0.575563, 0.844566, 0.256415) ,
+ rgb (0.585678, 0.846661, 0.249897) ,
+ rgb (0.595839, 0.848717, 0.243329) ,
+ rgb (0.606045, 0.850733, 0.236712) ,
+ rgb (0.616293, 0.852709, 0.230052) ,
+ rgb (0.626579, 0.854645, 0.223353) ,
+ rgb (0.636902, 0.856542, 0.21662) ,
+ rgb (0.647257, 0.8584, 0.209861) ,
+ rgb (0.657642, 0.860219, 0.203082) ,
+ rgb (0.668054, 0.861999, 0.196293) ,
+ rgb (0.678489, 0.863742, 0.189503) ,
+ rgb (0.688944, 0.865448, 0.182725) ,
+ rgb (0.699415, 0.867117, 0.175971) ,
+ rgb (0.709898, 0.868751, 0.169257) ,
+ rgb (0.720391, 0.87035, 0.162603) ,
+ rgb (0.730889, 0.871916, 0.156029) ,
+ rgb (0.741388, 0.873449, 0.149561) ,
+ rgb (0.751884, 0.874951, 0.143228) ,
+ rgb (0.762373, 0.876424, 0.137064) ,
+ rgb (0.772852, 0.877868, 0.131109) ,
+ rgb (0.783315, 0.879285, 0.125405) ,
+ rgb (0.79376, 0.880678, 0.120005) ,
+ rgb (0.804182, 0.882046, 0.114965) ,
+ rgb (0.814576, 0.883393, 0.110347) ,
+ rgb (0.82494, 0.88472, 0.106217) ,
+ rgb (0.83527, 0.886029, 0.102646) ,
+ rgb (0.845561, 0.887322, 0.099702) ,
+ rgb (0.85581, 0.888601, 0.097452) ,
+ rgb (0.866013, 0.889868, 0.095953) ,
+ rgb (0.876168, 0.891125, 0.09525) ,
+ rgb (0.886271, 0.892374, 0.095374) ,
+ rgb (0.89632, 0.893616, 0.096335) ,
+ rgb (0.906311, 0.894855, 0.098125) ,
+ rgb (0.916242, 0.896091, 0.100717) ,
+ rgb (0.926106, 0.89733, 0.104071) ,
+ rgb (0.935904, 0.89857, 0.108131) ,
+ rgb (0.945636, 0.899815, 0.112838) ,
+ rgb (0.9553, 0.901065, 0.118128) ,
+ rgb (0.964894, 0.902323, 0.123941) ,
+ rgb (0.974417, 0.90359, 0.130215) ,
+ rgb (0.983868, 0.904867, 0.136897) ,
+ rgb (0.993248, 0.906157, 0.143936)
+});
+
+
diff --git a/graphics/asymptote/base/contour.asy b/graphics/asymptote/base/contour.asy
new file mode 100644
index 0000000000..fbb4cd1c71
--- /dev/null
+++ b/graphics/asymptote/base/contour.asy
@@ -0,0 +1,682 @@
+// Contour routines written by Radoslav Marinov and John Bowman.
+
+import graph_settings;
+
+real eps=10000*realEpsilon;
+
+// 1
+// 6 +-------------------+ 5
+// | \ / |
+// | \ / |
+// | \ / |
+// | \ / |
+// 2 | X | 0
+// | / \ |
+// | / \ |
+// | / \ |
+// | / \ |
+// 7 +-------------------+ 4 or 8
+// 3
+
+private struct segment
+{
+ bool active;
+ pair a,b; // Endpoints; a is always an edge point if one exists.
+ int c; // Contour value.
+ int edge; // -1: interior, 0 to 3: edge,
+ // 4-8: single-vertex edge, 9: double-vertex edge.
+}
+
+// Case 1: line passes through two vertices of a triangle
+private segment case1(pair p0, pair p1, int edge)
+{
+ // Will cause a duplicate guide; luckily case1 is rare
+ segment rtrn;
+ rtrn.active=true;
+ rtrn.a=p0;
+ rtrn.b=p1;
+ rtrn.edge=edge;
+ return rtrn;
+}
+
+// Case 2: line passes through a vertex and a side of a triangle
+// (the first vertex passed and the side between the other two)
+private segment case2(pair p0, pair p1, pair p2,
+ real v0, real v1, real v2, int edge)
+{
+ segment rtrn;
+ pair val=interp(p1,p2,abs(v1/(v2-v1)));
+ rtrn.active=true;
+ if(edge < 4) {
+ rtrn.a=val;
+ rtrn.b=p0;
+ } else {
+ rtrn.a=p0;
+ rtrn.b=val;
+ }
+ rtrn.edge=edge;
+ return rtrn;
+}
+
+// Case 3: line passes through two sides of a triangle
+// (through the sides formed by the first & second, and second & third
+// vertices)
+private segment case3(pair p0, pair p1, pair p2,
+ real v0, real v1, real v2, int edge=-1)
+{
+ segment rtrn;
+ rtrn.active=true;
+ rtrn.a=interp(p1,p0,abs(v1/(v0-v1)));
+ rtrn.b=interp(p1,p2,abs(v1/(v2-v1)));
+ rtrn.edge=edge;
+ return rtrn;
+}
+
+// Check if a line passes through a triangle, and draw the required line.
+private segment checktriangle(pair p0, pair p1, pair p2,
+ real v0, real v1, real v2, int edge=-1)
+{
+ // default null return
+ static segment dflt;
+
+ real eps=eps*max(abs(v0),abs(v1),abs(v2));
+
+ if(v0 < -eps) {
+ if(v1 < -eps) {
+ if(v2 < -eps) return dflt; // nothing to do
+ else if(v2 <= eps) return dflt; // nothing to do
+ else return case3(p0,p2,p1,v0,v2,v1);
+ } else if(v1 <= eps) {
+ if(v2 < -eps) return dflt; // nothing to do
+ else if(v2 <= eps) return case1(p1,p2,5+edge);
+ else return case2(p1,p0,p2,v1,v0,v2,5+edge);
+ } else {
+ if(v2 < -eps) return case3(p0,p1,p2,v0,v1,v2,edge);
+ else if(v2 <= eps)
+ return case2(p2,p0,p1,v2,v0,v1,edge);
+ else return case3(p1,p0,p2,v1,v0,v2,edge);
+ }
+ } else if(v0 <= eps) {
+ if(v1 < -eps) {
+ if(v2 < -eps) return dflt; // nothing to do
+ else if(v2 <= eps) return case1(p0,p2,4+edge);
+ else return case2(p0,p1,p2,v0,v1,v2,4+edge);
+ } else if(v1 <= eps) {
+ if(v2 < -eps) return case1(p0,p1,9);
+ else if(v2 <= eps) return dflt; // use finer partitioning.
+ else return case1(p0,p1,9);
+ } else {
+ if(v2 < -eps) return case2(p0,p1,p2,v0,v1,v2,4+edge);
+ else if(v2 <= eps) return case1(p0,p2,4+edge);
+ else return dflt; // nothing to do
+ }
+ } else {
+ if(v1 < -eps) {
+ if(v2 < -eps) return case3(p1,p0,p2,v1,v0,v2,edge);
+ else if(v2 <= eps)
+ return case2(p2,p0,p1,v2,v0,v1,edge);
+ else return case3(p0,p1,p2,v0,v1,v2,edge);
+ } else if(v1 <= eps) {
+ if(v2 < -eps) return case2(p1,p0,p2,v1,v0,v2,5+edge);
+ else if(v2 <= eps) return case1(p1,p2,5+edge);
+ else return dflt; // nothing to do
+ } else {
+ if(v2 < -eps) return case3(p0,p2,p1,v0,v2,v1);
+ else if(v2 <= eps) return dflt; // nothing to do
+ else return dflt; // nothing to do
+ }
+ }
+}
+
+// Collect connecting path segments.
+private void collect(pair[][][] points, real[] c)
+{
+ // use to reverse an array, omitting the first point
+ int[] reverseF(int n) {return sequence(new int(int x){return n-1-x;},n-1);}
+ // use to reverse an array, omitting the last point
+ int[] reverseL(int n) {return sequence(new int(int x){return n-2-x;},n-1);}
+
+ for(int cnt=0; cnt < c.length; ++cnt) {
+ pair[][] gdscnt=points[cnt];
+ for(int i=0; i < gdscnt.length; ++i) {
+ pair[] gig=gdscnt[i];
+ int Li=gig.length;
+ for(int j=i+1; j < gdscnt.length; ++j) {
+ pair[] gjg=gdscnt[j];
+ int Lj=gjg.length;
+ if(abs(gig[0]-gjg[0]) < eps) {
+ gdscnt[j]=gjg[reverseF(Lj)];
+ gdscnt[j].append(gig);
+ gdscnt.delete(i);
+ --i;
+ break;
+ } else if(abs(gig[0]-gjg[Lj-1]) < eps) {
+ gig.delete(0);
+ gdscnt[j].append(gig);
+ gdscnt.delete(i);
+ --i;
+ break;
+ } else if(abs(gig[Li-1]-gjg[0]) < eps) {
+ gjg.delete(0);
+ gig.append(gjg);
+ gdscnt[j]=gig;
+ gdscnt.delete(i);
+ --i;
+ break;
+ } else if(abs(gig[Li-1]-gjg[Lj-1]) < eps) {
+ gig.append(gjg[reverseL(Lj)]);
+ gdscnt[j]=gig;
+ gdscnt.delete(i);
+ --i;
+ break;
+ }
+ }
+ }
+ }
+}
+
+// Join path segments.
+private guide[][] connect(pair[][][] points, real[] c, interpolate join)
+{
+ // set up return value
+ guide[][] result=new guide[c.length][];
+ for(int cnt=0; cnt < c.length; ++cnt) {
+ pair[][] pointscnt=points[cnt];
+ guide[] resultcnt=result[cnt]=new guide[pointscnt.length];
+ for(int i=0; i < pointscnt.length; ++i) {
+ pair[] pts=pointscnt[i];
+ guide gd;
+ if(pts.length > 0) {
+ if(pts.length > 1 && abs(pts[0]-pts[pts.length-1]) < eps) {
+ guide[] g=sequence(new guide(int i) {
+ return pts[i];
+ },pts.length-1);
+ g.push(cycle);
+ gd=join(...g);
+ } else
+ gd=join(...sequence(new guide(int i) {
+ return pts[i];
+ },pts.length));
+ }
+ resultcnt[i]=gd;
+ }
+ }
+ return result;
+}
+
+
+// Return contour guides for a 2D data array.
+// z: two-dimensional array of nonoverlapping mesh points
+// f: two-dimensional array of corresponding f(z) data values
+// midpoint: optional array containing values of f at cell midpoints
+// c: array of contour values
+// join: interpolation operator (e.g. operator -- or operator ..)
+guide[][] contour(pair[][] z, real[][] f,
+ real[][] midpoint=new real[][], real[] c,
+ interpolate join=operator --)
+{
+ int nx=z.length-1;
+ if(nx == 0)
+ abort("array z must have length >= 2");
+ int ny=z[0].length-1;
+ if(ny == 0)
+ abort("array z[0] must have length >= 2");
+
+ c=sort(c);
+ bool midpoints=midpoint.length > 0;
+
+ segment segments[][][]=new segment[nx][ny][];
+
+ // go over region a rectangle at a time
+ for(int i=0; i < nx; ++i) {
+ pair[] zi=z[i];
+ pair[] zp=z[i+1];
+ real[] fi=f[i];
+ real[] fp=f[i+1];
+ real[] midpointi;
+ if(midpoints) midpointi=midpoint[i];
+ segment[][] segmentsi=segments[i];
+ for(int j=0; j < ny; ++j) {
+ segment[] segmentsij=segmentsi[j];
+
+ // define points
+ pair bleft=zi[j];
+ pair bright=zp[j];
+ pair tleft=zi[j+1];
+ pair tright=zp[j+1];
+ pair middle=0.25*(bleft+bright+tleft+tright);
+
+ real f00=fi[j];
+ real f01=fi[j+1];
+ real f10=fp[j];
+ real f11=fp[j+1];
+ real fmm=midpoints ? midpoint[i][j] : 0.25*(f00+f01+f10+f11);
+
+ // optimization: we make sure we don't work with empty rectangles
+ int checkcell(int cnt) {
+ real C=c[cnt];
+ real vertdat0=f00-C; // bottom-left vertex
+ real vertdat1=f10-C; // bottom-right vertex
+ real vertdat2=f01-C; // top-left vertex
+ real vertdat3=f11-C; // top-right vertex
+
+ // optimization: we make sure we don't work with empty rectangles
+ int countm=0;
+ int countz=0;
+ int countp=0;
+
+ void check(real vertdat) {
+ if(vertdat < -eps) ++countm;
+ else {
+ if(vertdat <= eps) ++countz;
+ else ++countp;
+ }
+ }
+
+ check(vertdat0);
+ check(vertdat1);
+ check(vertdat2);
+ check(vertdat3);
+
+ if(countm == 4) return 1; // nothing to do
+ if(countp == 4) return -1; // nothing to do
+ if((countm == 3 || countp == 3) && countz == 1) return 0;
+
+ // go through the triangles
+
+ void addseg(segment seg) {
+ if(seg.active) {
+ seg.c=cnt;
+ segmentsij.push(seg);
+ }
+ }
+ real vertdat4=fmm-C;
+ addseg(checktriangle(bright,tright,middle,
+ vertdat1,vertdat3,vertdat4,0));
+ addseg(checktriangle(tright,tleft,middle,
+ vertdat3,vertdat2,vertdat4,1));
+ addseg(checktriangle(tleft,bleft,middle,
+ vertdat2,vertdat0,vertdat4,2));
+ addseg(checktriangle(bleft,bright,middle,
+ vertdat0,vertdat1,vertdat4,3));
+ return 0;
+ }
+
+ void process(int l, int u) {
+ if(l >= u) return;
+ int i=quotient(l+u,2);
+ int sign=checkcell(i);
+ if(sign == -1) process(i+1,u);
+ else if(sign == 1) process(l,i);
+ else {
+ process(l,i);
+ process(i+1,u);
+ }
+ }
+
+ process(0,c.length);
+ }
+ }
+
+ // set up return value
+ pair[][][] points=new pair[c.length][][];
+
+ for(int i=0; i < nx; ++i) {
+ segment[][] segmentsi=segments[i];
+ for(int j=0; j < ny; ++j) {
+ segment[] segmentsij=segmentsi[j];
+ for(int k=0; k < segmentsij.length; ++k) {
+ segment C=segmentsij[k];
+
+ if(!C.active) continue;
+
+ pair[] g=new pair[] {C.a,C.b};
+ segmentsij[k].active=false;
+
+ int forward(int I, int J, bool first=true) {
+ if(I >= 0 && I < nx && J >= 0 && J < ny) {
+ segment[] segmentsIJ=segments[I][J];
+ for(int l=0; l < segmentsIJ.length; ++l) {
+ segment D=segmentsIJ[l];
+ if(!D.active) continue;
+ if(abs(D.a-g[g.length-1]) < eps) {
+ g.push(D.b);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ } else if(abs(D.b-g[g.length-1]) < eps) {
+ g.push(D.a);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ int backward(int I, int J, bool first=true) {
+ if(I >= 0 && I < nx && J >= 0 && J < ny) {
+ segment[] segmentsIJ=segments[I][J];
+ for(int l=0; l < segmentsIJ.length; ++l) {
+ segment D=segmentsIJ[l];
+ if(!D.active) continue;
+ if(abs(D.a-g[0]) < eps) {
+ g.insert(0,D.b);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ } else if(abs(D.b-g[0]) < eps) {
+ g.insert(0,D.a);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ void follow(int f(int, int, bool first=true), int edge) {
+ int I=i;
+ int J=j;
+ while(true) {
+ static int ix[]={1,0,-1,0};
+ static int iy[]={0,1,0,-1};
+ if(edge >= 0 && edge < 4) {
+ I += ix[edge];
+ J += iy[edge];
+ edge=f(I,J);
+ } else {
+ if(edge == -1) break;
+ if(edge < 9) {
+ int edge0=(edge-5) % 4;
+ int edge1=(edge-4) % 4;
+ int ix0=ix[edge0];
+ int iy0=iy[edge0];
+ I += ix0;
+ J += iy0;
+ // Search all 3 corner cells
+ if((edge=f(I,J)) == -1) {
+ I += ix[edge1];
+ J += iy[edge1];
+ if((edge=f(I,J)) == -1) {
+ I -= ix0;
+ J -= iy0;
+ edge=f(I,J);
+ }
+ }
+ } else {
+ // Double-vertex edge: search all 8 surrounding cells
+ void search() {
+ for(int i=-1; i <= 1; ++i) {
+ for(int j=-1; j <= 1; ++j) {
+ if((edge=f(I+i,J+j,false)) >= 0) {
+ I += i;
+ J += j;
+ return;
+ }
+ }
+ }
+ }
+ search();
+ }
+ }
+ }
+ }
+
+ // Follow contour in cell
+ int edge=forward(i,j,first=false);
+
+ // Follow contour forward outside of cell
+ follow(forward,edge);
+
+ // Follow contour backward outside of cell
+ follow(backward,C.edge);
+
+ points[C.c].push(g);
+ }
+ }
+ }
+
+ collect(points,c); // Required to join remaining case1 cycles.
+
+ return connect(points,c,join);
+}
+
+// Return contour guides for a 2D data array on a uniform lattice
+// f: two-dimensional array of real data values
+// midpoint: optional array containing data values at cell midpoints
+// a,b: diagonally opposite vertices of rectangular domain
+// c: array of contour values
+// join: interpolation operator (e.g. operator -- or operator ..)
+guide[][] contour(real[][] f, real[][] midpoint=new real[][],
+ pair a, pair b, real[] c,
+ interpolate join=operator --)
+{
+ int nx=f.length-1;
+ if(nx == 0)
+ abort("array f must have length >= 2");
+ int ny=f[0].length-1;
+ if(ny == 0)
+ abort("array f[0] must have length >= 2");
+
+ pair[][] z=new pair[nx+1][ny+1];
+ for(int i=0; i <= nx; ++i) {
+ pair[] zi=z[i];
+ real xi=interp(a.x,b.x,i/nx);
+ for(int j=0; j <= ny; ++j) {
+ zi[j]=(xi,interp(a.y,b.y,j/ny));
+ }
+ }
+ return contour(z,f,midpoint,c,join);
+}
+
+// return contour guides for a real-valued function
+// f: real-valued function of two real variables
+// a,b: diagonally opposite vertices of rectangular domain
+// c: array of contour values
+// nx,ny: number of subdivisions in x and y directions (determines accuracy)
+// join: interpolation operator (e.g. operator -- or operator ..)
+guide[][] contour(real f(real, real), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --)
+{
+ // evaluate function at points and midpoints
+ real[][] dat=new real[nx+1][ny+1];
+ real[][] midpoint=new real[nx+1][ny+1];
+
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i/nx);
+ real x2=interp(a.x,b.x,(i+0.5)/nx);
+ real[] dati=dat[i];
+ real[] midpointi=midpoint[i];
+ for(int j=0; j <= ny; ++j) {
+ dati[j]=f(x,interp(a.y,b.y,j/ny));
+ midpointi[j]=f(x2,interp(a.y,b.y,(j+0.5)/ny));
+ }
+ }
+
+ return contour(dat,midpoint,a,b,c,join);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen[] p)
+{
+ begingroup(pic);
+ for(int cnt=0; cnt < g.length; ++cnt) {
+ guide[] gcnt=g[cnt];
+ pen pcnt=p[cnt];
+ for(int i=0; i < gcnt.length; ++i)
+ draw(pic,gcnt[i],pcnt);
+ if(L.length > 0) {
+ Label Lcnt=L[cnt];
+ for(int i=0; i < gcnt.length; ++i) {
+ if(Lcnt.s != "" && size(gcnt[i]) > 1)
+ label(pic,Lcnt,gcnt[i],pcnt);
+ }
+ }
+ }
+ endgroup(pic);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen p=currentpen)
+{
+ draw(pic,L,g,sequence(new pen(int) {return p;},g.length));
+}
+
+// Extend palette by the colors below and above at each end.
+pen[] extend(pen[] palette, pen below, pen above) {
+ pen[] p=copy(palette);
+ p.insert(0,below);
+ p.push(above);
+ return p;
+}
+
+// Compute the interior palette for a sequence of cyclic contours
+// corresponding to palette.
+pen[][] interior(picture pic=currentpicture, guide[][] g, pen[] palette)
+{
+ if(palette.length != g.length+1)
+ abort("Palette array must have length one more than guide array");
+ pen[][] fillpalette=new pen[g.length][];
+ for(int i=0; i < g.length; ++i) {
+ guide[] gi=g[i];
+ guide[] gp;
+ if(i+1 < g.length) gp=g[i+1];
+ guide[] gm;
+ if(i > 0) gm=g[i-1];
+
+ pen[] fillpalettei=new pen[gi.length];
+ for(int j=0; j < gi.length; ++j) {
+ path P=gi[j];
+ if(cyclic(P)) {
+ int index=i+1;
+ bool nextinside;
+ for(int k=0; k < gp.length; ++k) {
+ path next=gp[k];
+ if(cyclic(next)) {
+ if(inside(P,point(next,0)))
+ nextinside=true;
+ else if(inside(next,point(P,0)))
+ index=i;
+ }
+ }
+ if(!nextinside) {
+ // Check to see if previous contour is inside
+ for(int k=0; k < gm.length; ++k) {
+ path prev=gm[k];
+ if(cyclic(prev)) {
+ if(inside(P,point(prev,0)))
+ index=i;
+ }
+ }
+ }
+ fillpalettei[j]=palette[index];
+ }
+ fillpalette[i]=fillpalettei;
+ }
+ }
+ return fillpalette;
+}
+
+// Fill the interior of cyclic contours with palette
+void fill(picture pic=currentpicture, guide[][] g, pen[][] palette)
+{
+ for(int i=0; i < g.length; ++i) {
+ guide[] gi=g[i];
+ guide[] gp;
+ if(i+1 < g.length) gp=g[i+1];
+ guide[] gm;
+ if(i > 0) gm=g[i-1];
+
+ for(int j=0; j < gi.length; ++j) {
+ path P=gi[j];
+ path[] S=P;
+ if(cyclic(P)) {
+ for(int k=0; k < gp.length; ++k) {
+ path next=gp[k];
+ if(cyclic(next) && inside(P,point(next,0)))
+ S=S^^next;
+ }
+ for(int k=0; k < gm.length; ++k) {
+ path next=gm[k];
+ if(cyclic(next) && inside(P,point(next,0)))
+ S=S^^next;
+ }
+ fill(pic,S,palette[i][j]+evenodd);
+ }
+ }
+ }
+}
+
+// routines for irregularly spaced points:
+
+// check existing guides and adds new segment to them if possible,
+// or otherwise store segment as a new guide
+private void addseg(pair[][] gds, segment seg)
+{
+ if(!seg.active) return;
+ // search for a path to extend
+ for(int i=0; i < gds.length; ++i) {
+ pair[] gd=gds[i];
+ if(abs(gd[0]-seg.b) < eps) {
+ gd.insert(0,seg.a);
+ return;
+ } else if(abs(gd[gd.length-1]-seg.b) < eps) {
+ gd.push(seg.a);
+ return;
+ } else if(abs(gd[0]-seg.a) < eps) {
+ gd.insert(0,seg.b);
+ return;
+ } else if(abs(gd[gd.length-1]-seg.a) < eps) {
+ gd.push(seg.b);
+ return;
+ }
+ }
+
+ // in case nothing is found
+ pair[] segm;
+ segm=new pair[] {seg.a,seg.b};
+ gds.push(segm);
+
+ return;
+}
+
+guide[][] contour(real f(pair), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --)
+{
+ return contour(new real(real x, real y) {return f((x,y));},a,b,c,nx,ny,join);
+}
+
+guide[][] contour(pair[] z, real[] f, real[] c, interpolate join=operator --)
+{
+ if(z.length != f.length)
+ abort("z and f arrays have different lengths");
+
+ int[][] trn=triangulate(z);
+
+ // array to store guides found so far
+ pair[][][] points=new pair[c.length][][];
+
+ for(int cnt=0; cnt < c.length; ++cnt) {
+ pair[][] pointscnt=points[cnt];
+ real C=c[cnt];
+ for(int i=0; i < trn.length; ++i) {
+ int[] trni=trn[i];
+ int i0=trni[0], i1=trni[1], i2=trni[2];
+ addseg(pointscnt,checktriangle(z[i0],z[i1],z[i2],
+ f[i0]-C,f[i1]-C,f[i2]-C));
+ }
+ }
+
+ collect(points,c);
+
+ return connect(points,c,join);
+}
diff --git a/graphics/asymptote/base/contour3.asy b/graphics/asymptote/base/contour3.asy
new file mode 100644
index 0000000000..4977a351bf
--- /dev/null
+++ b/graphics/asymptote/base/contour3.asy
@@ -0,0 +1,479 @@
+import graph_settings;
+import three;
+
+real eps=10000*realEpsilon;
+
+private struct weighted
+{
+ triple normal;
+ real ratio;
+ int kpa0,kpa1,kpa2;
+ int kpb0,kpb1,kpb2;
+ triple v;
+}
+
+private struct bucket
+{
+ triple v;
+ triple val;
+ int count;
+}
+
+struct vertex
+{
+ triple v;
+ triple normal;
+}
+
+// A group of 3 or 4 points.
+private struct object
+{
+ bool active;
+ weighted[] pts;
+}
+
+// Return contour vertices for a 3D data array.
+// z: three-dimensional array of nonoverlapping mesh points
+// f: three-dimensional arrays of real data values
+// midpoint: optional array containing estimate of f at midpoint values
+vertex[][] contour3(triple[][][] v, real[][][] f,
+ real[][][] midpoint=new real[][][],
+ projection P=currentprojection)
+{
+ int nx=v.length-1;
+ if(nx == 0)
+ abort("array v must have length >= 2");
+ int ny=v[0].length-1;
+ if(ny == 0)
+ abort("array v[0] must have length >= 2");
+ int nz=v[0][0].length-1;
+ if(nz == 0)
+ abort("array v[0][0] must have length >= 2");
+
+ bool midpoints=midpoint.length > 0;
+
+ bucket[][][][] kps=new bucket[2nx+1][2ny+1][2nz+1][];
+ for(int i=0; i < 2nx+1; ++i)
+ for(int j=0; j < 2ny+1; ++j)
+ for(int k=0; k < 2nz+1; ++k)
+ kps[i][j][k]=new bucket[];
+
+ object[] objects;
+
+ // go over region a rectangle at a time
+ for(int i=0; i < nx; ++i) {
+ triple[][] vi=v[i];
+ triple[][] vp=v[i+1];
+ real[][] fi=f[i];
+ real[][] fp=f[i+1];
+ int i2=2i;
+ int i2p1=i2+1;
+ int i2p2=i2+2;
+ for(int j=0; j < ny; ++j) {
+ triple[] vij=vi[j];
+ triple[] vpj=vp[j];
+ triple[] vip=vi[j+1];
+ triple[] vpp=vp[j+1];
+ real[] fij=fi[j];
+ real[] fpj=fp[j];
+ real[] fip=fi[j+1];
+ real[] fpp=fp[j+1];
+ int j2=2j;
+ int j2p1=j2+1;
+ int j2p2=j2+2;
+
+ for(int k=0; k < nz; ++k) {
+ // vertex values
+ real vdat0=fij[k];
+ real vdat1=fij[k+1];
+ real vdat2=fip[k];
+ real vdat3=fip[k+1];
+ real vdat4=fpj[k];
+ real vdat5=fpj[k+1];
+ real vdat6=fpp[k];
+ real vdat7=fpp[k+1];
+
+ // define points
+ triple p000=vij[k];
+ triple p001=vij[k+1];
+ triple p010=vip[k];
+ triple p011=vip[k+1];
+ triple p100=vpj[k];
+ triple p101=vpj[k+1];
+ triple p110=vpp[k];
+ triple p111=vpp[k+1];
+ triple m0=0.25*(p000+p010+p110+p100);
+ triple m1=0.25*(p010+p110+p111+p011);
+ triple m2=0.25*(p110+p100+p101+p111);
+ triple m3=0.25*(p100+p000+p001+p101);
+ triple m4=0.25*(p000+p010+p011+p001);
+ triple m5=0.25*(p001+p011+p111+p101);
+ triple mc=0.5*(m0+m5);
+
+ // optimization: we make sure we don't work with empty rectangles
+ int countm=0;
+ int countz=0;
+ int countp=0;
+
+ void check(real vdat) {
+ if(vdat < -eps) ++countm;
+ else {
+ if(vdat <= eps) ++countz;
+ else ++countp;
+ }
+ }
+
+ check(vdat0);
+ check(vdat1);
+ check(vdat2);
+ check(vdat3);
+ check(vdat4);
+ check(vdat5);
+ check(vdat6);
+ check(vdat7);
+
+ if(countm == 8 || countp == 8 ||
+ ((countm == 7 || countp == 7) && countz == 1)) continue;
+
+ int k2=2k;
+ int k2p1=k2+1;
+ int k2p2=k2+2;
+
+ // Evaluate midpoints of cube sides.
+ // Then evaluate midpoint of cube.
+ real vdat8=midpoints ? midpoint[i2p1][j2p1][k2] :
+ 0.25*(vdat0+vdat2+vdat6+vdat4);
+ real vdat9=midpoints ? midpoint[i2p1][j2p2][k2p1] :
+ 0.25*(vdat2+vdat6+vdat7+vdat3);
+ real vdat10=midpoints ? midpoint[i2p2][j2p1][k2p1] :
+ 0.25*(vdat7+vdat6+vdat4+vdat5);
+ real vdat11=midpoints ? midpoint[i2p1][j2][k2p1] :
+ 0.25*(vdat0+vdat4+vdat5+vdat1);
+ real vdat12=midpoints ? midpoint[i2][j2p1][k2p1] :
+ 0.25*(vdat0+vdat2+vdat3+vdat1);
+ real vdat13=midpoints ? midpoint[i2p1][j2p1][k2p2] :
+ 0.25*(vdat1+vdat3+vdat7+vdat5);
+ real vdat14=midpoints ? midpoint[i2p1][j2p1][k2p1] :
+ 0.125*(vdat0+vdat1+vdat2+vdat3+vdat4+vdat5+vdat6+vdat7);
+
+ // Go through the 24 pyramids, 4 for each side.
+
+ void addval(int kp0, int kp1, int kp2, triple add, triple v) {
+ bucket[] cur=kps[kp0][kp1][kp2];
+ for(int q=0; q < cur.length; ++q) {
+ if(length(cur[q].v-v) < eps) {
+ cur[q].val += add;
+ ++cur[q].count;
+ return;
+ }
+ }
+ bucket newbuck;
+ newbuck.v=v;
+ newbuck.val=add;
+ newbuck.count=1;
+ cur.push(newbuck);
+ }
+
+ void accrue(weighted w) {
+ triple val1=w.normal*w.ratio;
+ triple val2=w.normal*(1-w.ratio);
+ addval(w.kpa0,w.kpa1,w.kpa2,val1,w.v);
+ addval(w.kpb0,w.kpb1,w.kpb2,val2,w.v);
+ }
+
+ triple dir=P.normal;
+
+ void addnormals(weighted[] pts) {
+ triple vec2=pts[1].v-pts[0].v;
+ triple vec1=pts[0].v-pts[2].v;
+ triple vec0=-vec2-vec1;
+ vec2=unit(vec2);
+ vec1=unit(vec1);
+ vec0=unit(vec0);
+ triple normal=cross(vec2,vec1);
+ normal *= sgn(dot(normal,dir));
+ real angle0=acos(-dot(vec1,vec2));
+ real angle1=acos(-dot(vec2,vec0));
+ pts[0].normal=normal*angle0;
+ pts[1].normal=normal*angle1;
+ pts[2].normal=normal*(pi-angle0-angle1);
+ }
+
+ void addobj(object obj) {
+ if(!obj.active) return;
+
+ if(obj.pts.length == 4) {
+ weighted[] points=obj.pts;
+ object obj1;
+ object obj2;
+ obj1.active=true;
+ obj2.active=true;
+ obj1.pts=new weighted[] {points[0],points[1],points[2]};
+ obj2.pts=new weighted[] {points[1],points[2],points[3]};
+ addobj(obj1);
+ addobj(obj2);
+ } else {
+ addnormals(obj.pts);
+ for(int q=0; q < obj.pts.length; ++q)
+ accrue(obj.pts[q]);
+ objects.push(obj);
+ }
+ }
+
+ weighted setupweighted(triple va, triple vb, real da, real db,
+ int[] kpa, int[] kpb) {
+ weighted w;
+ real ratio=abs(da/(db-da));
+ w.v=interp(va,vb,ratio);
+ w.ratio=ratio;
+ w.kpa0=i2+kpa[0];
+ w.kpa1=j2+kpa[1];
+ w.kpa2=k2+kpa[2];
+ w.kpb0=i2+kpb[0];
+ w.kpb1=j2+kpb[1];
+ w.kpb2=k2+kpb[2];
+
+ return w;
+ }
+
+ weighted setupweighted(triple v, int[] kp) {
+ weighted w;
+ w.v=v;
+ w.ratio=0.5;
+ w.kpa0=w.kpb0=i2+kp[0];
+ w.kpa1=w.kpb1=j2+kp[1];
+ w.kpa2=w.kpb2=k2+kp[2];
+
+ return w;
+ }
+
+ // Checks if a pyramid contains a contour object.
+ object checkpyr(triple v0, triple v1, triple v2, triple v3,
+ real d0, real d1, real d2, real d3,
+ int[] c0, int[] c1, int[] c2, int[] c3) {
+ object obj;
+ real a0=abs(d0);
+ real a1=abs(d1);
+ real a2=abs(d2);
+ real a3=abs(d3);
+
+ bool b0=a0 < eps;
+ bool b1=a1 < eps;
+ bool b2=a2 < eps;
+ bool b3=a3 < eps;
+
+ weighted[] pts;
+
+ if(b0) pts.push(setupweighted(v0,c0));
+ if(b1) pts.push(setupweighted(v1,c1));
+ if(b2) pts.push(setupweighted(v2,c2));
+ if(b3) pts.push(setupweighted(v3,c3));
+
+ if(!b0 && !b1 && abs(d0+d1)+eps < a0+a1)
+ pts.push(setupweighted(v0,v1,d0,d1,c0,c1));
+ if(!b0 && !b2 && abs(d0+d2)+eps < a0+a2)
+ pts.push(setupweighted(v0,v2,d0,d2,c0,c2));
+ if(!b0 && !b3 && abs(d0+d3)+eps < a0+a3)
+ pts.push(setupweighted(v0,v3,d0,d3,c0,c3));
+ if(!b1 && !b2 && abs(d1+d2)+eps < a1+a2)
+ pts.push(setupweighted(v1,v2,d1,d2,c1,c2));
+ if(!b1 && !b3 && abs(d1+d3)+eps < a1+a3)
+ pts.push(setupweighted(v1,v3,d1,d3,c1,c3));
+ if(!b2 && !b3 && abs(d2+d3)+eps < a2+a3)
+ pts.push(setupweighted(v2,v3,d2,d3,c2,c3));
+
+ int s=pts.length;
+ //There are three or four points.
+ if(s > 2) {
+ obj.active=true;
+ obj.pts=pts;
+ } else obj.active=false;
+
+ return obj;
+ }
+
+ void check4pyr(triple v0, triple v1, triple v2, triple v3,
+ triple v4, triple v5,
+ real d0, real d1, real d2, real d3, real d4, real d5,
+ int[] c0, int[] c1, int[] c2, int[] c3, int[] c4,
+ int[] c5) {
+ addobj(checkpyr(v5,v4,v0,v1,d5,d4,d0,d1,c5,c4,c0,c1));
+ addobj(checkpyr(v5,v4,v1,v2,d5,d4,d1,d2,c5,c4,c1,c2));
+ addobj(checkpyr(v5,v4,v2,v3,d5,d4,d2,d3,c5,c4,c2,c3));
+ addobj(checkpyr(v5,v4,v3,v0,d5,d4,d3,d0,c5,c4,c3,c0));
+ }
+
+ static int[] pp000={0,0,0};
+ static int[] pp001={0,0,2};
+ static int[] pp010={0,2,0};
+ static int[] pp011={0,2,2};
+ static int[] pp100={2,0,0};
+ static int[] pp101={2,0,2};
+ static int[] pp110={2,2,0};
+ static int[] pp111={2,2,2};
+ static int[] pm0={1,1,0};
+ static int[] pm1={1,2,1};
+ static int[] pm2={2,1,1};
+ static int[] pm3={1,0,1};
+ static int[] pm4={0,1,1};
+ static int[] pm5={1,1,2};
+ static int[] pmc={1,1,1};
+
+ check4pyr(p000,p010,p110,p100,mc,m0,
+ vdat0,vdat2,vdat6,vdat4,vdat14,vdat8,
+ pp000,pp010,pp110,pp100,pmc,pm0);
+ check4pyr(p010,p110,p111,p011,mc,m1,
+ vdat2,vdat6,vdat7,vdat3,vdat14,vdat9,
+ pp010,pp110,pp111,pp011,pmc,pm1);
+ check4pyr(p110,p100,p101,p111,mc,m2,
+ vdat6,vdat4,vdat5,vdat7,vdat14,vdat10,
+ pp110,pp100,pp101,pp111,pmc,pm2);
+ check4pyr(p100,p000,p001,p101,mc,m3,
+ vdat4,vdat0,vdat1,vdat5,vdat14,vdat11,
+ pp100,pp000,pp001,pp101,pmc,pm3);
+ check4pyr(p000,p010,p011,p001,mc,m4,
+ vdat0,vdat2,vdat3,vdat1,vdat14,vdat12,
+ pp000,pp010,pp011,pp001,pmc,pm4);
+ check4pyr(p001,p011,p111,p101,mc,m5,
+ vdat1,vdat3,vdat7,vdat5,vdat14,vdat13,
+ pp001,pp011,pp111,pp101,pmc,pm5);
+ }
+ }
+ }
+
+ vertex preparevertex(weighted w) {
+ vertex ret;
+ triple normal=O;
+ bool first=true;
+ bucket[] kp1=kps[w.kpa0][w.kpa1][w.kpa2];
+ bucket[] kp2=kps[w.kpb0][w.kpb1][w.kpb2];
+ bool notfound1=true;
+ bool notfound2=true;
+ int count=0;
+ int stop=max(kp1.length,kp2.length);
+ for(int r=0; r < stop; ++r) {
+ if(notfound1) {
+ if(length(w.v-kp1[r].v) < eps) {
+ if(first) {
+ ret.v=kp1[r].v;
+ first=false;
+ }
+ normal += kp1[r].val;
+ count += kp1[r].count;
+ notfound1=false;
+ }
+ }
+ if(notfound2) {
+ if(length(w.v-kp2[r].v) < eps) {
+ if(first) {
+ ret.v=kp2[r].v;
+ first=false;
+ }
+ normal += kp2[r].val;
+ count += kp2[r].count;
+ notfound2=false;
+ }
+ }
+ }
+ ret.normal=normal*2/count;
+ return ret;
+ }
+
+ // Prepare return value.
+ vertex[][] g;
+
+ for(int q=0; q < objects.length; ++q) {
+ object p=objects[q];
+ g.push(new vertex[] {preparevertex(p.pts[0]),preparevertex(p.pts[1]),
+ preparevertex(p.pts[2])});
+ }
+ return g;
+}
+
+// Return contour vertices for a 3D data array on a uniform lattice.
+// f: three-dimensional arrays of real data values
+// midpoint: optional array containing estimate of f at midpoint values
+// a,b: diagonally opposite points of rectangular parellelpiped domain
+vertex[][] contour3(real[][][] f, real[][][] midpoint=new real[][][],
+ triple a, triple b, projection P=currentprojection)
+
+{
+ int nx=f.length-1;
+ if(nx == 0)
+ abort("array f must have length >= 2");
+ int ny=f[0].length-1;
+ if(ny == 0)
+ abort("array f[0] must have length >= 2");
+ int nz=f[0][0].length-1;
+ if(nz == 0)
+ abort("array f[0][0] must have length >= 2");
+
+ triple[][][] v=new triple[nx+1][ny+1][nz+1];
+ for(int i=0; i <= nx; ++i) {
+ real xi=interp(a.x,b.x,i/nx);
+ triple[][] vi=v[i];
+ for(int j=0; j <= ny; ++j) {
+ triple[] vij=v[i][j];
+ real yj=interp(a.y,b.y,j/ny);
+ for(int k=0; k <= nz; ++k) {
+ vij[k]=(xi,yj,interp(a.z,b.z,k/nz));
+ }
+ }
+ }
+ return contour3(v,f,midpoint,P);
+}
+
+// Return contour vertices for a 3D data array, using a pyramid mesh
+// f: real-valued function of three real variables
+// a,b: diagonally opposite points of rectangular parellelpiped domain
+// nx,ny,nz number of subdivisions in x, y, and z directions
+vertex[][] contour3(real f(real, real, real), triple a, triple b,
+ int nx=nmesh, int ny=nx, int nz=nx,
+ projection P=currentprojection)
+{
+ // evaluate function at points and midpoints
+ real[][][] dat=new real[nx+1][ny+1][nz+1];
+ real[][][] midpoint=new real[2nx+2][2ny+2][2nz+1];
+
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i/nx);
+ real x2=interp(a.x,b.x,(i+0.5)/nx);
+ real[][] dati=dat[i];
+ real[][] midpointi2=midpoint[2i];
+ real[][] midpointi2p1=midpoint[2i+1];
+ for(int j=0; j <= ny; ++j) {
+ real y=interp(a.y,b.y,j/ny);
+ real y2=interp(a.y,b.y,(j+0.5)/ny);
+ real datij[]=dati[j];
+ real[] midpointi2p1j2=midpointi2p1[2j];
+ real[] midpointi2p1j2p1=midpointi2p1[2j+1];
+ real[] midpointi2j2p1=midpointi2[2j+1];
+ for(int k=0; k <= nz; ++k) {
+ real z=interp(a.z,b.z,k/nz);
+ real z2=interp(a.z,b.z,(k+0.5)/nz);
+ datij[k]=f(x,y,z);
+ if(i == nx || j == ny || k == nz) continue;
+ int k2p1=2k+1;
+ midpointi2p1j2p1[2k]=f(x2,y2,z);
+ midpointi2p1j2p1[k2p1]=f(x2,y2,z2);
+ midpointi2p1j2[k2p1]=f(x2,y,z2);
+ midpointi2j2p1[k2p1]=f(x,y2,z2);
+ if(i == 0) midpoint[2nx][2j+1][k2p1]=f(b.x,y2,z2);
+ if(j == 0) midpointi2p1[2ny][k2p1]=f(x2,b.y,z2);
+ if(k == 0) midpointi2p1j2p1[2nz]=f(x2,y2,b.z);
+ }
+ }
+ }
+ return contour3(dat,midpoint,a,b,P);
+}
+
+// Construct contour surface for a 3D data array, using a pyramid mesh.
+surface surface(vertex[][] g)
+{
+ surface s=surface(g.length);
+ for(int i=0; i < g.length; ++i) {
+ vertex[] cur=g[i];
+ s.s[i]=patch(cur[0].v--cur[1].v--cur[2].v--cycle);
+ }
+ return s;
+}
diff --git a/graphics/asymptote/base/drawtree.asy b/graphics/asymptote/base/drawtree.asy
new file mode 100644
index 0000000000..832dfc658a
--- /dev/null
+++ b/graphics/asymptote/base/drawtree.asy
@@ -0,0 +1,101 @@
+// A simple tree drawing module contributed by adarovsky
+// See example treetest.asy
+
+real treeNodeStep = 0.5cm;
+real treeLevelStep = 1cm;
+real treeMinNodeWidth = 2cm;
+
+struct TreeNode {
+ TreeNode parent;
+ TreeNode[] children;
+
+ frame content;
+
+ pair pos;
+ real adjust;
+}
+
+void add( TreeNode child, TreeNode parent )
+{
+ child.parent = parent;
+ parent.children.push( child );
+}
+
+TreeNode makeNode( TreeNode parent = null, frame f )
+{
+ TreeNode child = new TreeNode;
+ child.content = f;
+ if( parent != null ) {
+ add( child, parent );
+ }
+ return child;
+}
+
+TreeNode makeNode( TreeNode parent = null, Label label )
+{
+ frame f;
+ box( f, label);
+ return makeNode( parent, f );
+}
+
+
+real layout( int level, TreeNode node )
+{
+ if( node.children.length > 0 ) {
+ real width[] = new real[node.children.length];
+ real curWidth = 0;
+
+ for( int i = 0; i < node.children.length; ++i ) {
+ width[i] = layout( level+1, node.children[i] );
+
+ node.children[i].pos = (curWidth + width[i]/2,
+ -level*treeLevelStep);
+ curWidth += width[i] + treeNodeStep;
+ }
+
+ real midPoint = ( sum( width )+treeNodeStep*(width.length-1)) / 2;
+ for( int i = 0; i < node.children.length; ++i ) {
+ node.children[i].adjust = - midPoint;
+ }
+
+ return max( (max(node.content)-min(node.content)).x,
+ sum(width)+treeNodeStep*(width.length-1) );
+ }
+ else {
+ return max( treeMinNodeWidth, (max(node.content)-min(node.content)).x );
+ }
+}
+
+void drawAll( TreeNode node, frame f )
+{
+ pair pos;
+ if( node.parent != null )
+ pos = (node.parent.pos.x+node.adjust, 0);
+ else
+ pos = (node.adjust, 0);
+ node.pos += pos;
+
+ node.content = shift(node.pos)*node.content;
+ add( f, node.content );
+
+
+ if( node.parent != null ) {
+ path p = point(node.content, N)--point(node.parent.content,S);
+ draw( f, p, currentpen );
+ }
+
+ for( int i = 0; i < node.children.length; ++i )
+ drawAll( node.children[i], f );
+}
+
+void draw( TreeNode root, pair pos )
+{
+ frame f;
+
+ root.pos = (0,0);
+ layout( 1, root );
+
+ drawAll( root, f );
+
+ add(f,pos);
+}
diff --git a/graphics/asymptote/base/embed.asy b/graphics/asymptote/base/embed.asy
new file mode 100644
index 0000000000..88495f1212
--- /dev/null
+++ b/graphics/asymptote/base/embed.asy
@@ -0,0 +1,37 @@
+if(latex()) {
+ usepackage("hyperref");
+ texpreamble("\hypersetup{"+settings.hyperrefOptions+"}");
+ usepackage("media9","bigfiles");
+}
+
+// For documentation of the options see
+// http://mirror.ctan.org/macros/latex/contrib/media9/doc/media9.pdf
+
+// Embed PRC or SWF content in pdf file
+string embedplayer(string name, string text="", string options="",
+ real width=0, real height=0)
+{
+ if(width != 0) options += ",width="+(string) (width/pt)+"pt";
+ if(height != 0) options += ",height="+(string) (height/pt)+"pt";
+ return "%
+\includemedia[noplaybutton,"+options+"]{"+text+"}{"+name+"}";
+}
+
+// Embed media in pdf file
+string embed(string name, string text="", string options="",
+ real width=0, real height=0)
+{
+ return embedplayer("VPlayer.swf",text,"label="+name+
+ ",activate=pageopen,addresource="+name+
+ ",flashvars={source="+name+"&scaleMode=letterbox},"+
+ options,width,height);
+}
+
+string link(string label, string text="Play")
+{
+ return "\PushButton[
+ onclick={
+ annotRM['"+label+"'].activated=true;
+ annotRM['"+label+"'].callAS('playPause');
+ }]{\fbox{"+text+"}}";
+}
diff --git a/graphics/asymptote/base/external.asy b/graphics/asymptote/base/external.asy
new file mode 100644
index 0000000000..f9ab5365ae
--- /dev/null
+++ b/graphics/asymptote/base/external.asy
@@ -0,0 +1,37 @@
+usepackage("hyperref");
+texpreamble("\hypersetup{"+settings.hyperrefOptions+"}");
+
+// Embed object to be run in an external window. An image file name can be
+// specified; if not given one will be automatically generated.
+string embed(string name, string text="", string options="",
+ real width=0, real height=0, string image="")
+{
+ string options; // Ignore passed options.
+ if(image == "") {
+ image=stripdirectory(stripextension(name))+"."+nativeformat();
+ convert(name+"[0]",image,nativeformat());
+
+ if(!settings.keep) {
+ exitfcn currentexitfunction=atexit();
+ void exitfunction() {
+ if(currentexitfunction != null) currentexitfunction();
+ delete(image);
+ }
+ atexit(exitfunction);
+ }
+ }
+ if(width != 0) options += ", width="+(string) (width/pt)+"pt";
+ if(height != 0) options +=", height="+(string) (height/pt)+"pt";
+ return "\href{run:"+name+"}{"+graphic(image,options)+"}";
+}
+
+string hyperlink(string url, string text)
+{
+ return "\href{"+url+"}{"+text+"}";
+}
+
+string link(string label, string text="Play")
+{
+ return hyperlink("run:"+label,text);
+}
+
diff --git a/graphics/asymptote/base/feynman.asy b/graphics/asymptote/base/feynman.asy
new file mode 100644
index 0000000000..4360ee9f52
--- /dev/null
+++ b/graphics/asymptote/base/feynman.asy
@@ -0,0 +1,622 @@
+/*****************************************************************************
+ * feynman.asy -- An Asymptote library for drawing Feynman diagrams. *
+ * *
+ * by: Martin Wiebusch <martin.wiebusch@gmx.net> *
+ * last change: 2007/04/13 *
+ *****************************************************************************/
+
+
+/* default parameters ********************************************************/
+
+// default ratio of width (distance between two loops) to amplitude for a gluon
+// line. The gluon function uses this ratio, if the width parameter is
+// negative.
+real gluonratio;
+
+// default ratio of width (distance between two crests) to amplitude for a
+// photon line. The photon function uses this ratio, if the width parameter is
+// negative.
+real photonratio;
+
+// default gluon amplitude
+real gluonamplitude;
+
+// default photon amplitude
+real photonamplitude;
+
+// default pen for drawing the background. Usually white.
+pen backgroundpen;
+
+// default pen for drawing gluon lines
+pen gluonpen;
+
+// default pen for drawing photon lines
+pen photonpen;
+
+// default pen for drawing fermion lines
+pen fermionpen;
+
+// default pen for drawing scalar lines
+pen scalarpen;
+
+// default pen for drawing ghost lines
+pen ghostpen;
+
+// default pen for drawing double lines
+pen doublelinepen;
+
+// default pen for drawing vertices
+pen vertexpen;
+
+// default pen for drawing big vertices (drawVertexOX and drawVertexBoxX)
+pen bigvertexpen;
+
+// inner spacing of a double line
+real doublelinespacing;
+
+// default arrow for propagators
+arrowbar currentarrow;
+
+// if true, each of the drawSomething commands blots out the background
+// (with pen backgroundpen) before drawing.
+bool overpaint;
+
+// margin around lines. If one line is drawn over anoter, a white margin
+// of size linemargin is kept around the top one.
+real linemargin;
+
+// at vertices, where many lines join, the last line drawn should not blot
+// out the others. By not erasing the background near the ends of lines,
+// this is prevented for lines with an angle greater than minvertexangle to
+// each other. Note, that small values for minvertexangle mean that the
+// background is only erased behind a small segment of every line. Setting
+// minvertexangle = 0 effectively disables background erasing for lines.
+real minvertexangle;
+
+// size (radius) of vertices
+real vertexsize;
+
+// size (radius) of big vertices (drawVertexOX and drawVertexBoxX)
+real bigvertexsize;
+
+/* defaults for momentum arrows **********************************************/
+
+// (momentum arrows are small arrows parallel to particle lines indicating the
+// direction of momentum)
+
+// default size of the arrowhead of momentum arrows
+arrowbar currentmomarrow;
+
+// default length of momentum arrows
+real momarrowlength;
+
+// default pen for momentum arrows
+pen momarrowpen;
+
+// default offset between momentum arrow and related particle line
+real momarrowoffset;
+
+// default margin for momentum arrows
+real momarrowmargin;
+
+// factor for determining the size of momentum arrowheads. After changing it,
+// you still have to update currentmomarrow manually.
+real momarrowfactor;
+
+// size function for momentum arrowheads
+real momarrowsize(pen p=momarrowpen) { return momarrowfactor*linewidth(p); }
+
+
+/* defaults for texshipout ***************************************************/
+
+// tex command for including graphics. It takes one argument, which is the
+// name of the graphics (eps or pdf) file.
+string includegraphicscommand;
+
+// Determines whether the suffix (.eps or .pdf) should be appended to the stem
+// of the file name in the \includegraphics command.
+bool appendsuffix;
+
+
+/* helper functions **********************************************************/
+
+// internal function for overpainting
+private void do_overpaint(picture pic, path p, pen bgpen,
+ real halfwidth, real vertexangle)
+{
+ real tanvertexangle = tan(vertexangle*pi/180);
+ if(tanvertexangle != 0) {
+ real t1 = arctime(p, halfwidth/tanvertexangle+halfwidth);
+ real t2 = arctime(p, arclength(p)-halfwidth/tanvertexangle-halfwidth);
+ draw(pic, subpath(p, t1, t2),
+ bgpen+linewidth(2*halfwidth));
+ }
+}
+
+// returns the path of a gluon line along path p, with amplitude amp and width
+// width (distance between two loops). If width is negative, the width is
+// set to amp*gluonratio
+path gluon(path p, real amp = gluonamplitude, real width=-1)
+{
+ if(width < 0) width = abs(gluonratio*amp);
+
+ real pathlen = arclength(p);
+ int ncurls = floor(pathlen/width);
+ real firstlen = (pathlen - width*(ncurls-1))/2;
+ real firstt = arctime(p, firstlen);
+ pair firstv = dir(p, firstt);
+ guide g = point(p, 0)..{firstv}( point(p, firstt)
+ +amp*unit(rotate(90)*firstv));
+
+ real t1;
+ pair v1;
+ real t2;
+ pair v2;
+ pathlen -= firstlen;
+ for(real len = firstlen+width/2; len < pathlen; len += width) {
+ t1 = arctime(p, len);
+ v1 = dir(p, t1);
+ t2 = arctime(p, len + width/2);
+ v2 = dir(p, t2);
+
+ g=g..{-v1}(point(p, t1)+amp*unit(rotate(-90)*v1))
+ ..{+v2}(point(p, t2)+amp*unit(rotate(+90)*v2));
+ }
+ g = g..point(p, size(p));
+ return g;
+}
+
+// returns the path of a photon line along path p, with amplitude amp and width
+// width (distance between two crests). If width is negative, the width is
+// set to amp*photonratio
+path photon(path p, real amp = photonamplitude, real width=-1)
+{
+ if(width < 0)
+ width = abs(photonratio*amp)/2;
+ else
+ width = width/2;
+
+ real pathlen = arclength(p);
+ int ncurls = floor(pathlen/width);
+ real firstlen = (pathlen - width*ncurls)/2;
+ real firstt = arctime(p, firstlen+width);
+ guide g = point(p, 0){unit(point(p, firstt)-point(p, 0))};
+
+ real t;
+ pair v;
+ pathlen -= firstlen;
+ for(real len = firstlen+width; len < pathlen; len += width) {
+ t = arctime(p, len);
+ v = dir(p, t);
+
+ g=g..{v}(point(p, t)+amp*unit(rotate(90)*v));
+ amp = -amp;
+ }
+ g = g..{unit(point(p, size(p))-point(p, t))}point(p, size(p));
+ return g;
+}
+
+// returns the path of a momentum arrow along path p, with length length,
+// an offset offset from the path p and at position position. position will
+// usually be one of the predefined pairs left or right. Making adjust
+// nonzero shifts the momentum arrow along the path.
+path momArrowPath(path p,
+ align align,
+ position pos,
+ real offset = momarrowoffset,
+ real length = momarrowlength)
+{
+ real pathlen = arclength(p);
+
+ real t1, t2;
+ if(pos.relative) {
+ t1 = arctime(p, (pathlen-length)*pos.position.x);
+ t2 = arctime(p, (pathlen-length)*pos.position.x+length);
+ } else {
+ t1 = arctime(p, (pathlen-length)/2 + pos.position.x);
+ t2 = arctime(p, (pathlen+length)/2+ pos.position.x);
+ }
+
+ pair v1 = dir(p, t1);
+ pair v2 = dir(p, t2);
+
+ pair p1, p2;
+ if(align.relative) {
+ p1 = point(p, t1) + offset*abs(align.dir)
+ *unit(rotate(degrees(align.dir)-90)*v1);
+ p2 = point(p, t2) + offset*abs(align.dir)
+ *unit(rotate(degrees(align.dir)-90)*v2);
+ } else {
+ p1 = point(p, t1) + offset*align.dir;
+ p2 = point(p, t2) + offset*align.dir;
+ }
+
+ return p1{v1}..{v2}p2;
+}
+
+
+
+
+/* drawing functions *********************************************************/
+
+// draw a gluon line on picture pic, along path p, with amplitude amp, width
+// width (distance between loops) and with pen fgpen. If erasebg is true,
+// bgpen is used to erase the background behind the line and at a margin
+// margin around it. The background is not erased at a certain distance to
+// the endpoints, which is determined by vertexangle (see comments to the
+// default parameter minvertexangle). For negative values of width, the width
+// is set to gluonratio*amp.
+void drawGluon(picture pic = currentpicture,
+ path p,
+ real amp = gluonamplitude,
+ real width = -1,
+ pen fgpen = gluonpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(width < 0) width = abs(2*amp);
+
+ if(erasebg) do_overpaint(pic, p, bgpen, amp+margin, vertexangle);
+ draw(pic, gluon(p, amp, width), fgpen);
+}
+
+// draw a photon line on picture pic, along path p, with amplitude amp, width
+// width (distance between loops) and with pen fgpen. If erasebg is true,
+// bgpen is used to erase the background behind the line and at a margin
+// margin around it. The background is not erased at a certain distance to
+// the endpoints, which is determined by vertexangle (see comments to the
+// default parameter minvertexangle). For negative values of width, the width
+// is set to photonratio*amp.
+void drawPhoton(picture pic = currentpicture,
+ path p,
+ real amp = photonamplitude,
+ real width = -1,
+ pen fgpen = currentpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(width < 0) width = abs(4*amp);
+
+ if(erasebg) do_overpaint(pic, p, bgpen, amp+margin, vertexangle);
+ draw(pic, photon(p, amp, width), fgpen);
+}
+
+// draw a fermion line on picture pic, along path p with pen fgpen and an
+// arrowhead arrow. If erasebg is true, bgpen is used to erase the background
+// at a margin margin around the line. The background is not erased at a
+// certain distance to the endpoints, which is determined by vertexangle
+// (see comments to the default parameter minvertexangle).
+void drawFermion(picture pic = currentpicture,
+ path p,
+ pen fgpen = currentpen,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+ draw(pic, p, fgpen, arrow);
+}
+
+// draw a scalar line on picture pic, along path p with pen fgpen and an
+// arrowhead arrow. If erasebg is true, bgpen is used to erase the background
+// at a margin margin around the line. The background is not erased at a
+// certain distance to the endpoints, which is determined by vertexangle
+// (see comments to the default parameter minvertexangle).
+void drawScalar(picture pic = currentpicture,
+ path p,
+ pen fgpen = scalarpen,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+ draw(pic, p, fgpen, arrow);
+}
+
+// draw a ghost line on picture pic, along path p with pen fgpen and an
+// arrowhead arrow. If erasebg is true, bgpen is used to erase the background
+// at a margin margin around the line. The background is not erased at a
+// certain distance to the endpoints, which is determined by vertexangle
+// (see comments to the default parameter minvertexangle).
+void drawGhost(picture pic = currentpicture,
+ path p,
+ pen fgpen = ghostpen,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+ draw(pic, p, fgpen, arrow);
+}
+
+// draw a double line on picture pic, along path p with pen fgpen, an inner
+// spacing of dlspacint and an arrowhead arrow. If erasebg is true, bgpen is
+// used to erase the background at a margin margin around the line. The
+// background is not erased at a certain distance to the endpoints, which is
+// determined by vertexangle (see comments to the default parameter
+// minvertexangle).
+void drawDoubleLine(picture pic = currentpicture,
+ path p,
+ pen fgpen = doublelinepen,
+ real dlspacing = doublelinespacing,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+
+ real htw = linewidth(fgpen)+dlspacing/2;
+ draw(pic, p, fgpen+2*htw);
+ draw(pic, p, bgpen+(linewidth(dlspacing)));
+ path rect = (-htw,-htw)--(-htw,htw)--(0,htw)--(0,-htw)--cycle;
+ fill(shift(point(p,0))*rotate(degrees(dir(p,0)))*rect, bgpen);
+ fill(shift(point(p,size(p)))*scale(-1)*rotate(degrees(dir(p,size(p))))*
+ rect,bgpen);
+ draw(pic, p, invisible, arrow);
+}
+
+// draw a vertex dot on picture pic, at position xy with radius r and pen
+// fgpen
+void drawVertex(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ fill(pic, circle(xy, r), fgpen);
+}
+
+// draw an empty vertex dot on picture pic, at position xy with radius r
+// and pen fgpen. If erasebg is true, the background is erased in the inside
+// of the circle.
+void drawVertexO(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ if(erasebg)
+ filldraw(pic, circle(xy, r), bgpen, fgpen);
+ else
+ draw(pic, circle(xy, r), fgpen);
+}
+
+// draw a vertex triangle on picture pic, at position xy with radius r and pen
+// fgpen
+void drawVertexTriangle(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ real cospi6 = cos(pi/6);
+ real sinpi6 = sin(pi/6);
+ path triangle = (cospi6,-sinpi6)--(0,1)--(-cospi6,-sinpi6)--cycle;
+ fill(pic, shift(xy)*scale(r)*triangle, fgpen);
+}
+
+// draw an empty vertex triangle on picture pic, at position xy with size r
+// and pen fgpen. If erasebg is true, the background is erased in the inside
+// of the triangle.
+void drawVertexTriangleO(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ real cospi6 = cos(pi/6);
+ real sinpi6 = sin(pi/6);
+ path triangle = (cospi6,-sinpi6)--(0,1)--(-cospi6,-sinpi6)--cycle;
+
+ if(erasebg)
+ filldraw(pic, shift(xy)*scale(r)*triangle, bgpen, fgpen);
+ else
+ draw(pic, shift(xy)*scale(r)*triangle, fgpen);
+}
+
+// draw a vertex box on picture pic, at position xy with radius r and pen
+// fgpen
+void drawVertexBox(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ path box = (1,1)--(-1,1)--(-1,-1)--(1,-1)--cycle;
+ fill(pic, shift(xy)*scale(r)*box, fgpen);
+}
+
+// draw an empty vertex box on picture pic, at position xy with size r
+// and pen fgpen. If erasebg is true, the background is erased in the inside
+// of the box.
+void drawVertexBoxO(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ path box = (1,1)--(-1,1)--(-1,-1)--(1,-1)--cycle;
+ if(erasebg)
+ filldraw(pic, shift(xy)*scale(r)*box, bgpen, fgpen);
+ else
+ draw(pic, shift(xy)*scale(r)*box, fgpen);
+}
+
+// draw an X on picture pic, at position xy with size r and pen
+// fgpen
+void drawVertexX(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ draw(pic, shift(xy)*scale(r)*((-1,-1)--(1,1)), fgpen);
+ draw(pic, shift(xy)*scale(r)*((1,-1)--(-1,1)), fgpen);
+}
+
+// draw a circle with an X in the middle on picture pic, at position xy with
+// size r and pen fgpen. If erasebg is true, the background is erased in the
+// inside of the circle.
+void drawVertexOX(picture pic = currentpicture,
+ pair xy,
+ real r = bigvertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ if(erasebg)
+ filldraw(pic, circle(xy, r), bgpen, fgpen);
+ else
+ draw(pic, circle(xy, r), fgpen);
+ draw(pic, shift(xy)*scale(r)*(NW--SE), fgpen);
+ draw(pic, shift(xy)*scale(r)*(SW--NE), fgpen);
+}
+
+// draw a box with an X in the middle on picture pic, at position xy with
+// size r and pen fgpen. If erasebg is true, the background is erased in the
+// inside of the box.
+void drawVertexBoxX(picture pic = currentpicture,
+ pair xy,
+ real r = bigvertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ path box = (1,1)--(-1,1)--(-1,-1)--(1,-1)--cycle;
+ box = shift(xy)*scale(r)*box;
+ if(erasebg)
+ filldraw(pic, box, bgpen, fgpen);
+ else
+ draw(pic, box, fgpen);
+ draw(pic, shift(xy)*scale(r)*((-1,-1)--(1,1)), fgpen);
+ draw(pic, shift(xy)*scale(r)*((1,-1)--(-1,1)), fgpen);
+}
+
+// draw a momentum arrow on picture pic, along path p, at position position
+// (use one of the predefined pairs left or right), with an offset offset
+// from the path, a length length, a pen fgpen and an arrowhead arrow. Making
+// adjust nonzero shifts the momentum arrow along the path. If erasebg is true,
+// the background is erased inside a margin margin around the momentum arrow.
+// Make sure that offset and margin are chosen in such a way that the momentum
+// arrow does not overdraw the particle line.
+void drawMomArrow(picture pic = currentpicture,
+ path p,
+ align align,
+ position pos = MidPoint,
+ real offset = momarrowoffset,
+ real length = momarrowlength,
+ pen fgpen = momarrowpen,
+ arrowbar arrow = currentmomarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real margin = momarrowmargin)
+{
+ path momarrow = momArrowPath(p, align, pos, offset, length);
+ if(erasebg) do_overpaint(pic, momarrow, bgpen,
+ linewidth(fgpen)+margin, 90);
+ draw(pic, momarrow, fgpen, arrow);
+}
+
+
+/* initialisation ************************************************************/
+
+// The function fmdefaults() tries to guess reasonable values for the
+// default parameters above by looking at the default parameters of plain.asy
+// (essentially, currentpen, arrowfactor and dotfactor). After customising the
+// default parameters of plain.asy, you may call fmdefaults to adjust the
+// parameters of feynman.asy.
+void fmdefaults()
+{
+ real arrowsize=arrowsize(currentpen);
+ real linewidth=linewidth(currentpen);
+
+ gluonratio = 2;
+ photonratio = 4;
+ gluonamplitude = arrowsize/3;
+ photonamplitude = arrowsize/4;
+
+ backgroundpen = white;
+ gluonpen = currentpen;
+ photonpen = currentpen;
+ fermionpen = currentpen;
+ scalarpen = dashed+linewidth;
+ ghostpen = dotted+linewidth;
+ doublelinepen = currentpen;
+ vertexpen = currentpen;
+ bigvertexpen = currentpen;
+ currentarrow = MidArrow;
+
+ doublelinespacing = 2*linewidth;
+ linemargin = 0.5*arrowsize;
+ minvertexangle = 30;
+ overpaint = true;
+ vertexsize = 0.5*dotfactor*linewidth;
+ bigvertexsize = 0.4*arrowsize;
+
+ momarrowfactor = 1.5*arrowfactor;
+ momarrowlength = 2.5*arrowsize;
+ momarrowpen = currentpen+0.5*linewidth;
+ momarrowoffset = 0.8*arrowsize;
+ momarrowmargin = 0.25*arrowsize;
+ currentmomarrow = EndArrow(momarrowsize());
+
+ includegraphicscommand = "\includegraphics";
+ appendsuffix = false;
+}
+
+// We call fmdefaults once, when the module is loaded.
+fmdefaults();
+
+
+/* shipout *******************************************************************/
+
+bool YAlign = false;
+bool XYAlign = true;
+
+// texshipout("filename", pic) creates two files: filename.eps holding the
+// picture pic and filename.tex holding some LaTeX code that includes the
+// picture from filename.eps and shifts it vertically in such a way that the
+// point (0,0) lies on the baseline.
+void texshipout(string stem,
+ picture pic = currentpicture,
+ bool xalign = YAlign)
+{
+ file tf = output(stem + ".tex");
+ pair min=pic.min();
+ real depth = min.y;
+ real xoffset = min.x;
+ if(xalign) {
+ write(tf, "\makebox[0pt][l]{\kern");
+ write(tf, xoffset);
+ write(tf, "bp\relax");
+ }
+ write(tf, "\raisebox{");
+ write(tf, depth);
+ write(tf, "bp}{"+includegraphicscommand+"{");
+ write(tf, stem);
+ string suffix="."+nativeformat();
+ if(appendsuffix)
+ write(tf, suffix);
+ write(tf, "}}");
+ if(xalign)
+ write(tf, "}");
+ close(tf);
+ shipout(stem+suffix, pic);
+}
+
+
diff --git a/graphics/asymptote/base/flowchart.asy b/graphics/asymptote/base/flowchart.asy
new file mode 100644
index 0000000000..3db6617375
--- /dev/null
+++ b/graphics/asymptote/base/flowchart.asy
@@ -0,0 +1,526 @@
+// Flowchart routines written by Jacques Pienaar, Steve Melenchuk, John Bowman.
+
+private import math;
+
+struct flowdir {}
+
+restricted flowdir Horizontal;
+restricted flowdir Vertical;
+
+real minblockwidth=0;
+real minblockheight=0;
+real mincirclediameter=0;
+real defaultexcursion=0.1;
+
+struct block {
+ // The absolute center of the block in user coordinates.
+ pair center;
+
+ // The size of the block
+ pair size;
+
+ // The relative center of the block.
+ pair f_center;
+
+ // These eight variables return the appropriate location on the block
+ // in relative coordinates, where the lower left corner of the block is (0,0).
+ pair f_top;
+ pair f_left;
+ pair f_right;
+ pair f_bottom;
+ pair f_topleft;
+ pair f_topright;
+ pair f_bottomleft;
+ pair f_bottomright;
+
+ void operator init(pair z) {
+ center=z;
+ }
+
+ void operator init(real x, real y) {
+ center=(x,y);
+ }
+
+ pair shift(transform t=identity()) {
+ return t*center-f_center;
+ }
+
+ // Returns the relative position along the boundary of the block.
+ pair f_position(real x);
+
+ // Returns the absolute position along the boundary of the block.
+ pair position(real x, transform t=identity()) {
+ return shift(t)+f_position(x);
+ }
+
+ // These eight functions return the appropriate location on the block
+ // in absolute coordinates.
+ pair top(transform t=identity()) {
+ return shift(t)+f_top;
+ }
+ pair bottom(transform t=identity()) {
+ return shift(t)+f_bottom;
+ }
+ pair left(transform t=identity()) {
+ return shift(t)+f_left;
+ }
+ pair right(transform t=identity()) {
+ return shift(t)+f_right;
+ }
+ pair topleft(transform t=identity()) {
+ return shift(t)+f_topleft;
+ }
+ pair topright(transform t=identity()) {
+ return shift(t)+f_topright;
+ }
+ pair bottomleft(transform t=identity()) {
+ return shift(t)+f_bottomleft;
+ }
+ pair bottomright(transform t=identity()) {
+ return shift(t)+f_bottomright;
+ }
+
+ // Return a frame representing the block.
+ frame draw(pen p=currentpen);
+
+ // Store optional label on outgoing edge.
+ Label label;
+
+ // Store rectilinear path directions.
+ pair[] dirs;
+
+ // Store optional arrow.
+ arrowbar arrow=None;
+};
+
+// Construct a rectangular block with header and body objects.
+block rectangle(object header, object body, pair center=(0,0),
+ pen headerpen=mediumgray, pen bodypen=invisible,
+ pen drawpen=currentpen,
+ real dx=3, real minheaderwidth=minblockwidth,
+ real minheaderheight=minblockwidth,
+ real minbodywidth=minblockheight,
+ real minbodyheight=minblockheight)
+{
+ frame fbody=body.f;
+ frame fheader=header.f;
+ pair mheader=min(fheader);
+ pair Mheader=max(fheader);
+ pair mbody=min(fbody);
+ pair Mbody=max(fbody);
+ pair bound0=Mheader-mheader;
+ pair bound1=Mbody-mbody;
+ real width=max(bound0.x,bound1.x);
+ pair z0=maxbound((width+2dx,bound0.y+2dx),(minbodywidth,minbodyheight));
+ pair z1=maxbound((width+2dx,bound1.y+2dx),(minheaderwidth,minheaderheight));
+ path shape=(0,0)--(0,z1.y)--(0,z0.y+z1.y)--(z0.x,z0.y+z1.y)--z1--(z0.x,0)--
+ cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shift(0,z1.y)*box((0,0),z0),headerpen,drawpen);
+ add(block,shift(-0.5*(Mheader+mheader))*fheader,(0,z1.y)+0.5z0);
+ filldraw(block,box((0,0),z1),bodypen,drawpen);
+ add(block,shift(-0.5*(Mbody+mbody))*fbody,0.5z1);
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=interp(point(shape,0),point(shape,3),0.5);
+ block.f_bottomleft=point(shape,0);
+ block.f_bottom=point(shape,5.5);
+ block.f_bottomright=point(shape,5);
+ block.f_right=point(shape,4.5);
+ block.f_topright=point(shape,3);
+ block.f_top=point(shape,2.5);
+ block.f_topleft=point(shape,2);
+ block.f_left=point(shape,0.5);
+ block.center=center;
+ block.size=point(shape,3);
+ return block;
+}
+
+// As above, but without the header.
+block rectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real minwidth=minblockwidth,
+ real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair z=maxbound(M-m+dx*(2,2),(minwidth,minheight));
+ path shape=box((0,0),z);
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,0.5z);
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=0.5*z;
+ block.center=center;
+ block.size=z;
+ block.f_bottomleft=point(shape,0);
+ block.f_bottom=point(shape,0.5);
+ block.f_bottomright=point(shape,1);
+ block.f_right=point(shape,1.5);
+ block.f_topright=point(shape,2);
+ block.f_top=point(shape,2.5);
+ block.f_topleft=point(shape,3);
+ block.f_left=point(shape,3.5);
+ return block;
+}
+
+block parallelogram(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real slope=2,
+ real minwidth=minblockwidth,
+ real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair bound=maxbound(M-m+dx*(0,2),(minwidth,minheight));
+
+ real skew=bound.y/slope;
+ real a=bound.x+skew;
+ real b=bound.y;
+
+ path shape=(0,0)--(a,0)--(a+skew,b)--(skew,b)--cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,((a+skew)/2,b/2));
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=((a+skew)/2,b/2);
+ block.center=center;
+ block.size=(a+skew,b);
+ block.f_bottomleft=(0,0);
+ block.f_bottom=((a+skew)/2,0);
+ block.f_bottomright=(a,0);
+ block.f_right=(a+skew/2,b/2);
+ block.f_topright=(a+skew,b);
+ block.f_top=((a+skew)/2,b);
+ block.f_topleft=(skew,b);
+ block.f_left=(skew/2,b/2);
+ return block;
+}
+
+block diamond(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=1,
+ real height=20, real minwidth=minblockwidth,
+ real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair bound=maxbound(M-m,(minwidth,minheight));
+
+ real e=ds;
+ real a=0.5bound.x-dw;
+ real b=0.5bound.y;
+ real c=b+height;
+
+ real arg=a^2+b^2+c^2-2b*c-e^2;
+ real denom=e^2-a^2;
+ real slope=arg >= 0 && denom != 0 ? (a*(c-b)-e*sqrt(arg))/denom : 1.0;
+ real d=abs(c/slope);
+
+ path shape=(2d,c)--(d,2c)--(0,c)--(d,0)--cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(d,c));
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(point(shape,1).x,point(shape,0).y);
+ block.center=center;
+ block.size=(point(shape,0).x,point(shape,1).y);
+ block.f_bottomleft=point(shape,2.5);
+ block.f_bottom=point(shape,3);
+ block.f_bottomright=point(shape,3.5);
+ block.f_right=point(shape,0);
+ block.f_topright=point(shape,0.5);
+ block.f_top=point(shape,1);
+ block.f_topleft=point(shape,1.5);
+ block.f_left=point(shape,2);
+ return block;
+}
+
+block circle(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dr=3,
+ real mindiameter=mincirclediameter)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ real r=max(0.5length(M-m)+dr,0.5mindiameter);
+
+ path shape=(0,r)..(r,2r)..(2r,r)..(r,0)..cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(r,r));
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(r,r);
+ block.center=center;
+ block.size=(2r,2r);
+ block.f_left=point(shape,0);
+ block.f_topleft=point(shape,0.5);
+ block.f_top=point(shape,1);
+ block.f_topright=point(shape,1.5);
+ block.f_right=point(shape,2);
+ block.f_bottomright=point(shape,2.5);
+ block.f_bottom=point(shape,3);
+ block.f_bottomleft=point(shape,3.5);
+ return block;
+}
+
+block roundrectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=0, real minwidth=minblockwidth,
+ real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair bound=maxbound(M-m,(minwidth,minheight));
+
+ real a=bound.x;
+ real b=bound.y;
+
+ path shape=(0,ds+dw)--(0,ds+b-dw){up}..{right}
+ (ds+dw,2ds+b)--(ds+a-dw,2ds+b){right}..{down}
+ (2ds+a,ds+b-dw)--(2ds+a,ds+dw){down}..{left}
+ (ds+a-dw,0)--(ds+dw,0){left}..{up}cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(ds,ds)+0.5bound);
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(ds+0.5a,ds+0.5b);
+ block.center=center;
+ block.size=(2ds+a,2ds+b);
+ block.f_bottomleft=point(shape,7.5);
+ block.f_bottom=point(shape,6.5);
+ block.f_bottomright=point(shape,5.5);
+ block.f_right=point(shape,4.5);
+ block.f_topright=point(shape,3.5);
+ block.f_top=point(shape,2.5);
+ block.f_topleft=point(shape,1.5);
+ block.f_left=point(shape,0.5);
+ return block;
+}
+
+block bevel(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dh=5, real dw=5,
+ real minwidth=minblockwidth, real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair bound=maxbound(M-m,(minwidth,minheight));
+
+ real a=bound.x;
+ real b=0.5bound.y;
+
+ path shape=(2dw+a,b+dh)--(dw+a,2b+2dh)--(dw,2b+2dh)--(0,b+dh)--(dw,0)--
+ (dw+a,0)--cycle;
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(0.5bound+(dw,dh)));
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(dw+0.5a,dh+b);
+ block.center=center;
+ block.size=(2dw+a,2dh+2b);
+ block.f_bottomleft=point(shape,4);
+ block.f_bottom=point(shape,4.5);
+ block.f_bottomright=point(shape,5);
+ block.f_right=point(shape,0);
+ block.f_topright=point(shape,1);
+ block.f_top=point(shape,1.5);
+ block.f_topleft=point(shape,2);
+ block.f_left=point(shape,3);
+ return block;
+}
+
+path path(pair point[] ... flowdir dir[])
+{
+ path line=point[0];
+ pair current, prev=point[0];
+ for(int i=1; i < point.length; ++i) {
+ if(i-1 >= dir.length || dir[i-1] == Horizontal)
+ current=(point[i].x,point[i-1].y);
+ else
+ current=(point[i-1].x,point[i].y);
+
+ if(current != prev) {
+ line=line--current;
+ prev=current;
+ }
+
+ current=point[i];
+ if(current != prev) {
+ line=line--current;
+ prev=current;
+ }
+ }
+ return line;
+}
+
+void draw(picture pic=currentpicture, block block, pen p=currentpen)
+{
+ pic.add(new void(frame f, transform t) {
+ add(f,shift(block.shift(t))*block.draw(p));
+ },true);
+ pic.addBox(block.center,block.center,
+ -0.5*block.size+min(p),0.5*block.size+max(p));
+}
+
+typedef block blockconnector(block, block);
+
+blockconnector blockconnector(picture pic, transform t, pen p=currentpen,
+ margin margin=PenMargin)
+{
+ return new block(block b1, block b2) {
+ if(b1.dirs.length == 0) {
+ if(abs(b1.center.y-b2.center.y) < sqrtEpsilon) {
+ // horizontally aligned
+ b1.dirs[0]=b1.center.x < b2.center.x ? right : left;
+ blockconnector(pic,t,p,margin)(b1,b2);
+ } else if(abs(b1.center.x-b2.center.x) < sqrtEpsilon) {
+ // vertically aligned
+ b1.dirs[0]=b1.center.y < b2.center.y ? up : down;
+ blockconnector(pic,t,p,margin)(b1,b2);
+ } else {
+ if(abs(b1.center.y-b2.center.y) < abs(b1.center.x-b2.center.x)) {
+ b1.dirs[0]=b1.center.x < b2.center.x ? right : left;
+ b1.dirs[1]=b1.center.y < b2.center.y ? up : down;
+ blockconnector(pic,t,p,margin)(b1,b2);
+ } else {
+ b1.dirs[0]=b1.center.y < b2.center.y ? up : down;
+ b1.dirs[1]=b1.center.x < b2.center.x ? right : left;
+ blockconnector(pic,t,p,margin)(b1,b2);
+ }
+ }
+ return b2;
+ }
+
+ // compute the link for given directions (and label if any)
+ pair[] dirs=copy(b1.dirs); // deep copy
+ pair current,prev;
+ pair dir=dirs[0];
+ if(dir == up) prev=b1.top(t);
+ if(dir == down) prev=b1.bottom(t);
+ if(dir == left) prev=b1.left(t);
+ if(dir == right) prev=b1.right(t);
+ path line=prev;
+ arrowbar arrow=b1.arrow;
+
+ int i;
+ for(i=1; i < dirs.length-1; ++i) {
+ if(abs(length(dirs[i-1])-1) < sqrtEpsilon)
+ current=prev+t*dirs[i-1]*defaultexcursion;
+ else
+ current=prev+t*dirs[i-1];
+
+ if(current != prev) {
+ line=line--current;
+ prev=current;
+ }
+ }
+ dir=dirs[dirs.length-1];
+ current=0;
+ if(dir == up) current=b2.bottom(t);
+ if(dir == down) current=b2.top(t);
+ if(dir == left) current=b2.right(t);
+ if(dir == right) current=b2.left(t);
+ if(abs(dirs[i-1].y) < sqrtEpsilon &&
+ abs(prev.x-current.x) > sqrtEpsilon) {
+ prev=(current.x,prev.y);
+ line=line--prev; // horizontal
+ } else if(abs(dirs[i-1].x) < sqrtEpsilon &&
+ abs(prev.y-current.y) > sqrtEpsilon) {
+ prev=(prev.x,current.y);
+ line=line--prev;
+ }
+ if(current != prev)
+ line=line--current;
+
+ draw(pic,b1.label,line,p,arrow,margin);
+
+ b1.label="";
+ b1.dirs.delete();
+ b1.arrow=None;
+ return b2;
+ };
+}
+
+struct Dir
+{
+ pair z;
+ void operator init(pair z) {this.z=z;}
+}
+
+Dir Right=Dir(right);
+Dir Left=Dir(left);
+Dir Up=Dir(up);
+Dir Down=Dir(down);
+
+// Add a label to the current link
+block operator --(block b1, Label label)
+{
+ b1.label=label;
+ return b1;
+}
+
+// Add a direction to the current link
+block operator --(block b1, Dir dir)
+{
+ b1.dirs.push(dir.z);
+ return b1;
+}
+
+// Add an arrowbar to the current link
+block operator --(block b, arrowbar arrowbar)
+{
+ b.arrow=arrowbar;
+ return b;
+}
diff --git a/graphics/asymptote/base/fontsize.asy b/graphics/asymptote/base/fontsize.asy
new file mode 100644
index 0000000000..54b0182955
--- /dev/null
+++ b/graphics/asymptote/base/fontsize.asy
@@ -0,0 +1 @@
+if(latex()) usepackage("type1cm");
diff --git a/graphics/asymptote/base/geometry.asy b/graphics/asymptote/base/geometry.asy
new file mode 100644
index 0000000000..245c59ec08
--- /dev/null
+++ b/graphics/asymptote/base/geometry.asy
@@ -0,0 +1,7192 @@
+// geometry.asy
+
+// Copyright (C) 2007
+// Author: Philippe IVALDI 2007/09/01
+// http://www.piprime.fr/
+
+// This program is free software ; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation ; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY ; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program ; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+// COMMENTARY:
+// An Asymptote geometry module.
+
+// THANKS:
+// Special thanks to Olivier Guibé for his help in mathematical issues.
+
+// BUGS:
+
+// CODE:
+
+import math;
+import markers;
+
+// A rotation in the direction dir limited to [-90,90]
+// This is useful for rotating text along a line in the direction dir.
+private transform rotate(explicit pair dir)
+{
+ real angle=degrees(dir);
+ if(angle > 90 && angle < 270) angle -= 180;
+ return rotate(angle);
+}
+
+// *=======================================================*
+// *........................HEADER.........................*
+/*<asyxml><variable type="real" signature="epsgeo"><code></asyxml>*/
+real epsgeo = 10 * sqrt(realEpsilon);/*<asyxml></code><documentation>Variable used in the approximate calculations.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="void" signature="addMargins(picture,real,real,real,real)"><code></asyxml>*/
+void addMargins(picture pic = currentpicture,
+ real lmargin = 0, real bmargin = 0,
+ real rmargin = lmargin, real tmargin = bmargin,
+ bool rigid = true, bool allObject = true)
+{/*<asyxml></code><documentation>Add margins to 'pic' with respect to
+ the current bounding box of 'pic'.
+ If 'rigid' is false, margins are added iff an infinite curve will
+ be prolonged on the margin.
+ If 'allObject' is false, fixed - size objects (such as labels and
+ arrowheads) will be ignored.</documentation></function></asyxml>*/
+ pair m = allObject ? truepoint(pic, SW) : point(pic, SW);
+ pair M = allObject ? truepoint(pic, NE) : point(pic, NE);
+ if(rigid) {
+ draw(m - inverse(pic.calculateTransform()) * (lmargin, bmargin), invisible);
+ draw(M + inverse(pic.calculateTransform()) * (rmargin, tmargin), invisible);
+ } else pic.addBox(m, M, -(lmargin, bmargin), (rmargin, tmargin));
+}
+
+real approximate(real t)
+{
+ real ot = t;
+ if(abs(t - ceil(t)) < epsgeo) ot = ceil(t);
+ else if(abs(t - floor(t)) < epsgeo) ot = floor(t);
+ return ot;
+}
+
+real[] approximate(real[] T)
+{
+ return map(approximate, T);
+}
+
+/*<asyxml><function type="real" signature="binomial(real,real)"><code></asyxml>*/
+real binomial(real n, real k)
+{/*<asyxml></code><documentation>Return n!/((n - k)!*k!)</documentation></function></asyxml>*/
+ return gamma(n + 1)/(gamma(n - k + 1) * gamma(k + 1));
+}
+
+/*<asyxml><function type="real" signature="rf(real,real,real)"><code></asyxml>*/
+real rf(real x, real y, real z)
+{/*<asyxml></code><documentation>Computes Carlson's elliptic integral of the first kind.
+ x, y, and z must be non negative, and at most one can be zero.</documentation></function></asyxml>*/
+ real ERRTOL = 0.0025,
+ TINY = 1.5e-38,
+ BIG = 3e37,
+ THIRD = 1/3,
+ C1 = 1/24,
+ C2 = 0.1,
+ C3 = 3/44,
+ C4 = 1/14;
+ real alamb, ave, delx, dely, delz, e2, e3, sqrtx, sqrty, sqrtz, xt, yt, zt;
+ if(min(x, y, z) < 0 || min(x + y, x + z, y + z) < TINY ||
+ max(x, y, z) > BIG) abort("rf: invalid arguments.");
+ xt = x;
+ yt = y;
+ zt = z;
+ do {
+ sqrtx = sqrt(xt);
+ sqrty = sqrt(yt);
+ sqrtz = sqrt(zt);
+ alamb = sqrtx * (sqrty + sqrtz) + sqrty * sqrtz;
+ xt = 0.25 * (xt + alamb);
+ yt = 0.25 * (yt + alamb);
+ zt = 0.25 * (zt + alamb);
+ ave = THIRD * (xt + yt + zt);
+ delx = (ave - xt)/ave;
+ dely = (ave - yt)/ave;
+ delz = (ave - zt)/ave;
+ } while(max(fabs(delx), fabs(dely), fabs(delz)) > ERRTOL);
+ e2 = delx * dely - delz * delz;
+ e3 = delx * dely * delz;
+ return (1.0 + (C1 * e2 - C2 - C3 * e3) * e2 + C4 * e3)/sqrt(ave);
+}
+
+/*<asyxml><function type="real" signature="rd(real,real,real)"><code></asyxml>*/
+real rd(real x, real y, real z)
+{/*<asyxml></code><documentation>Computes Carlson's elliptic integral of the second kind.
+ x and y must be positive, and at most one can be zero.
+ z must be non negative.</documentation></function></asyxml>*/
+ real ERRTOL = 0.0015,
+ TINY = 1e-25,
+ BIG = 4.5 * 10.0^21,
+ C1 = (3/14),
+ C2 = (1/6),
+ C3 = (9/22),
+ C4 = (3/26),
+ C5 = (0.25 * C3),
+ C6 = (1.5 * C4);
+ real alamb, ave, delx, dely, delz, ea, eb, ec, ed, ee, fac, sqrtx, sqrty,
+ sqrtz, sum, xt, yt, zt;
+ if (min(x, y) < 0 || min(x + y, z) < TINY || max(x, y, z) > BIG)
+ abort("rd: invalid arguments");
+ xt = x;
+ yt = y;
+ zt = z;
+ sum = 0;
+ fac = 1;
+ do {
+ sqrtx = sqrt(xt);
+ sqrty = sqrt(yt);
+ sqrtz = sqrt(zt);
+ alamb = sqrtx * (sqrty + sqrtz) + sqrty * sqrtz;
+ sum += fac/(sqrtz * (zt + alamb));
+ fac = 0.25 * fac;
+ xt = 0.25 * (xt + alamb);
+ yt = 0.25 * (yt + alamb);
+ zt = 0.25 * (zt + alamb);
+ ave = 0.2 * (xt + yt + 3.0 * zt);
+ delx = (ave - xt)/ave;
+ dely = (ave - yt)/ave;
+ delz = (ave - zt)/ave;
+ } while (max(fabs(delx), fabs(dely), fabs(delz)) > ERRTOL);
+ ea = delx * dely;
+ eb = delz * delz;
+ ec = ea - eb;
+ ed = ea - 6 * eb;
+ ee = ed + ec + ec;
+ return 3 * sum + fac * (1.0 + ed * (-C1 + C5 * ed - C6 * delz * ee)
+ +delz * (C2 * ee + delz * (-C3 * ec + delz * C4 * ea)))/(ave * sqrt(ave));
+}
+
+/*<asyxml><function type="real" signature="elle(real,real)"><code></asyxml>*/
+real elle(real phi, real k)
+{/*<asyxml></code><documentation>Legendre elliptic integral of the 2nd kind,
+ evaluated using Carlson's functions RD and RF.
+ The argument ranges are -infinity < phi < +infinity, 0 <= k * sin(phi) <= 1.</documentation></function></asyxml>*/
+ real result;
+ if (phi >= 0 && phi <= pi/2) {
+ real cc, q, s;
+ s = sin(phi);
+ cc = cos(phi)^2;
+ q = (1 - s * k) * (1 + s * k);
+ result = s * (rf(cc, q, 1) - (s * k)^2 * rd(cc, q, 1)/3);
+ } else
+ if (phi <= pi && phi >= 0) {
+ result = 2 * elle(pi/2, k) - elle(pi - phi, k);
+ } else
+ if (phi <= 3 * pi/2 && phi >= 0) {
+ result = 2 * elle(pi/2, k) + elle(phi - pi, k);
+ } else
+ if (phi <= 2 * pi && phi >= 0) {
+ result = 4 * elle(pi/2, k) - elle(2 * pi - phi, k);
+ } else
+ if (phi >= 0) {
+ int nb = floor(0.5 * phi/pi);
+ result = nb * elle(2 * pi, k) + elle(phi%(2 * pi), k);
+ } else result = -elle(-phi, k);
+ return result;
+}
+
+/*<asyxml><function type="pair[]" signature="intersectionpoints(pair,pair,real,real,real,real,real,real)"><code></asyxml>*/
+pair[] intersectionpoints(pair A, pair B,
+ real a, real b, real c, real d, real f, real g)
+{/*<asyxml></code><documentation>Intersection points with the line (AB) and the quadric curve
+ a * x^2 + b * x * y + c * y^2 + d * x + f * y + g = 0 given in the default coordinate system</documentation></function></asyxml>*/
+ pair[] op;
+ real ap = B.y - A.y,
+ bpp = A.x - B.x,
+ cp = A.y * B.x - A.x * B.y;
+ real sol[];
+ if (abs(ap) > epsgeo) {
+ real aa = ap * c + a * bpp^2/ap - b * bpp,
+ bb = ap * f - bpp * d + 2 * a * bpp * cp/ap - b * cp,
+ cc = ap * g - cp * d + a * cp^2/ap;
+ sol = quadraticroots(aa, bb, cc);
+ for (int i = 0; i < sol.length; ++i) {
+ op.push((-bpp * sol[i]/ap - cp/ap, sol[i]));
+ }
+ } else {
+ real aa = a * bpp,
+ bb = d * bpp - b * cp,
+ cc = g * bpp - cp * f + c * cp^2/bpp;
+ sol = quadraticroots(aa, bb, cc);
+ for (int i = 0; i < sol.length; ++i) {
+ op.push((sol[i], -cp/bpp));
+ }
+ }
+ return op;
+}
+
+/*<asyxml><function type="pair[]" signature="intersectionpoints(pair,pair,real[])"><code></asyxml>*/
+pair[] intersectionpoints(pair A, pair B, real[] equation)
+{/*<asyxml></code><documentation>Return the intersection points of the line AB with
+ the conic whose an equation is
+ equation[0] * x^2 + equation[1] * x * y + equation[2] * y^2 + equation[3] * x + equation[4] * y + equation[5] = 0</documentation></function></asyxml>*/
+ if(equation.length != 6) abort("intersectionpoints: bad length of array for a conic equation.");
+ return intersectionpoints(A, B, equation[0], equation[1], equation[2],
+ equation[3], equation[4], equation[5]);
+}
+// *........................HEADER.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *......................COORDINATES......................*
+
+real EPS = sqrt(realEpsilon);
+
+/*<asyxml><typedef type = "convert" return = "pair" params = "pair"><code></asyxml>*/
+typedef pair convert(pair);/*<asyxml></code><documentation>Function type to convert pair in an other coordinate system.</documentation></typedef></asyxml>*/
+/*<asyxml><typedef type = "abs" return = "real" params = "pair"><code></asyxml>*/
+typedef real abs(pair);/*<asyxml></code><documentation>Function type to calculate modulus of pair.</documentation></typedef></asyxml>*/
+/*<asyxml><typedef type = "dot" return = "real" params = "pair, pair"><code></asyxml>*/
+typedef real dot(pair, pair);/*<asyxml></code><documentation>Function type to calculate dot product.</documentation></typedef></asyxml>*/
+/*<asyxml><typedef type = "polar" return = "pair" params = "real, real"><code></asyxml>*/
+typedef pair polar(real, real);/*<asyxml></code><documentation>Function type to calculate the coordinates from the polar coordinates.</documentation></typedef></asyxml>*/
+
+/*<asyxml><struct signature="coordsys"><code></asyxml>*/
+struct coordsys
+{/*<asyxml></code><documentation>This structure represents a coordinate system in the plane.</documentation></asyxml>*/
+ /*<asyxml><method type = "pair" signature="relativetodefault(pair)"><code></asyxml>*/
+ restricted convert relativetodefault = new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to this coordinate system to
+ the pair relatively to the default coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type = "pair" signature="defaulttorelativet(pair)"><code></asyxml>*/
+ restricted convert defaulttorelative = new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to the default coordinate system to
+ the pair relatively to this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type = "real" signature="dot(pair,pair)"><code></asyxml>*/
+ restricted dot dot = new real(pair m, pair n){return dot(m, n);};/*<asyxml></code><documentation>Return the dot product of this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type = "real" signature="abs(pair)"><code></asyxml>*/
+ restricted abs abs = new real(pair m){return abs(m);};/*<asyxml></code><documentation>Return the modulus of a pair in this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type = "pair" signature="polar(real,real)"><code></asyxml>*/
+ restricted polar polar = new pair(real r, real a){return (r * cos(a), r * sin(a));};/*<asyxml></code><documentation>Polar coordinates routine of this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><property type = "pair" signature="O,i,j"><code></asyxml>*/
+ restricted pair O = (0, 0), i = (1, 0), j = (0, 1);/*<asyxml></code><documentation>Origin and units vector.</documentation></property></asyxml>*/
+ /*<asyxml><method type = "void" signature="init(convert,convert,polar,dot)"><code></asyxml>*/
+ void init(convert rtd, convert dtr,
+ polar polar, dot dot)
+ {/*<asyxml></code><documentation>The default constructor of the coordinate system.</documentation></method></asyxml>*/
+ this.relativetodefault = rtd;
+ this.defaulttorelative = dtr;
+ this.polar = polar;
+ this.dot = dot;
+ this.abs = new real(pair m){return sqrt(dot(m, m));};;
+ this.O = rtd((0, 0));
+ this.i = rtd((1, 0)) - O;
+ this.j = rtd((0, 1)) - O;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><operator type = "bool" signature="==(coordsys,coordsys)"><code></asyxml>*/
+bool operator ==(coordsys c1, coordsys c2)
+{/*<asyxml></code><documentation>Return true iff the coordinate system have the same origin and units vector.</documentation></operator></asyxml>*/
+ return c1.O == c2.O && c1.i == c2.i && c1.j == c2.j;
+}
+
+/*<asyxml><function type="coordsys" signature="cartesiansystem(pair,pair,pair)"><code></asyxml>*/
+coordsys cartesiansystem(pair O = (0, 0), pair i, pair j)
+{/*<asyxml></code><documentation>Return the Cartesian coordinate system (O, i, j).</documentation></function></asyxml>*/
+ coordsys R;
+ real[][] P = {{0, 0}, {0, 0}};
+ real[][] iP;
+ P[0][0] = i.x;
+ P[0][1] = j.x;
+ P[1][0] = i.y;
+ P[1][1] = j.y;
+ iP = inverse(P);
+ real ni = abs(i);
+ real nj = abs(j);
+ real ij = angle(j) - angle(i);
+
+ pair rtd(pair m)
+ {
+ return O + (P[0][0] * m.x + P[0][1] * m.y, P[1][0] * m.x + P[1][1] * m.y);
+ }
+
+ pair dtr(pair m)
+ {
+ m-=O;
+ return (iP[0][0] * m.x + iP[0][1] * m.y, iP[1][0] * m.x + iP[1][1] * m.y);
+ }
+
+ pair polar(real r, real a)
+ {
+ real ca = sin(ij - a)/(ni * sin(ij));
+ real sa = sin(a)/(nj * sin(ij));
+ return r * (ca, sa);
+ }
+
+ real tdot(pair m, pair n)
+ {
+ return m.x * n.x * ni^2 + m.y * n.y * nj^2 + (m.x * n.y + n.x * m.y) * dot(i, j);
+ }
+
+ R.init(rtd, dtr, polar, tdot);
+ return R;
+}
+
+
+/*<asyxml><function type="void" signature="show(picture,Label,Label,Label,coordsys,pen,pen,pen,pen,pen)"><code></asyxml>*/
+void show(picture pic = currentpicture, Label lo = "$O$",
+ Label li = "$\vec{\imath}$",
+ Label lj = "$\vec{\jmath}$",
+ coordsys R,
+ pen dotpen = currentpen, pen xpen = currentpen, pen ypen = xpen,
+ pen ipen = red,
+ pen jpen = ipen,
+ arrowbar arrow = Arrow)
+{/*<asyxml></code><documentation>Draw the components (O, i, j, x - axis, y - axis) of 'R'.</documentation></function></asyxml>*/
+ unravel R;
+ dot(pic, O, dotpen);
+ drawline(pic, O, O + i, xpen);
+ drawline(pic, O, O + j, ypen);
+ draw(pic, li, O--(O + i), ipen, arrow);
+ Label lj = lj.copy();
+ lj.align(lj.align, unit(I * j));
+ draw(pic, lj, O--(O + j), jpen, arrow);
+ draw(pic, lj, O--(O + j), jpen, arrow);
+ Label lo = lo.copy();
+ lo.align(lo.align, -2 * dir(O--O + i, O--O + j));
+ lo.p(dotpen);
+ label(pic, lo, O);
+}
+
+/*<asyxml><operator type = "pair" signature="/(pair,coordsys)"><code></asyxml>*/
+pair operator /(pair p, coordsys R)
+{/*<asyxml></code><documentation>Return the xy - coordinates of 'p' relatively to
+ the coordinate system 'R'.
+ For example, if R = cartesiansystem((1, 2), (1, 0), (0, 1)), (0, 0)/R is (-1, -2).</documentation></operator></asyxml>*/
+ return R.defaulttorelative(p);
+}
+
+/*<asyxml><operator type = "pair" signature="*(coordsys,pair)"><code></asyxml>*/
+pair operator *(coordsys R, pair p)
+{/*<asyxml></code><documentation>Return the coordinates of 'p' given in the
+ xy - coordinates 'R'.
+ For example, if R = cartesiansystem((1, 2), (1, 0), (0, 1)), R * (0, 0) is (1, 2).</documentation></operator></asyxml>*/
+ return R.relativetodefault(p);
+}
+
+/*<asyxml><operator type = "path" signature="*(coordsys,path)"><code></asyxml>*/
+path operator *(coordsys R, path g)
+{/*<asyxml></code><documentation>Return the reconstructed path applying R * pair to each node, pre and post control point of 'g'.</documentation></operator></asyxml>*/
+ guide og = R * point(g, 0);
+ real l = length(g);
+ for(int i = 1; i <= l; ++i)
+ {
+ pair P = R * point(g, i);
+ pair post = R * postcontrol(g, i - 1);
+ pair pre = R * precontrol(g, i);
+ if(i == l && (cyclic(g)))
+ og = og..controls post and pre..cycle;
+ else
+ og = og..controls post and pre..P;
+ }
+ return og;
+}
+
+/*<asyxml><operator type = "coordsys" signature="*(transform,coordsys)"><code></asyxml>*/
+coordsys operator *(transform t,coordsys R)
+{/*<asyxml></code><documentation>Provide transform * coordsys.
+ Note that shiftless(t) is applied to R.i and R.j.</documentation></operator></asyxml>*/
+ coordsys oc;
+ oc = cartesiansystem(t * R.O, shiftless(t) * R.i, shiftless(t) * R.j);
+ return oc;
+}
+
+/*<asyxml><constant type = "coordsys" signature="defaultcoordsys"><code></asyxml>*/
+restricted coordsys defaultcoordsys = cartesiansystem(0, (1, 0), (0, 1));/*<asyxml></code><documentation>One can always refer to the default coordinate system using this constant.</documentation></constant></asyxml>*/
+/*<asyxml><variable type="coordsys" signature="currentcoordsys"><code></asyxml>*/
+coordsys currentcoordsys = defaultcoordsys;/*<asyxml></code><documentation>The coordinate system used by default.</documentation></variable></asyxml>*/
+
+/*<asyxml><struct signature="point"><code></asyxml>*/
+struct point
+{/*<asyxml></code><documentation>This structure replaces the pair to embed its coordinate system.
+ For example, if 'P = point(cartesiansystem((1, 2), i, j), (0, 0))',
+ P is equal to the pair (1, 2).</documentation></asyxml>*/
+ /*<asyxml><property type = "coordsys" signature="coordsys"><code></asyxml>*/
+ coordsys coordsys;/*<asyxml></code><documentation>The coordinate system of this point.</documentation></property><property type = "pair" signature="coordinates"><code></asyxml>*/
+ restricted pair coordinates;/*<asyxml></code><documentation>The coordinates of this point relatively to the coordinate system 'coordsys'.</documentation></property><property type = "real" signature="x, y"><code></asyxml>*/
+ restricted real x, y;/*<asyxml></code><documentation>The xpart and the ypart of 'coordinates'.</documentation></property></asyxml>*/
+ /*<asyxml><method type = "" signature="init(coordsys,pair)"><code><property type = "real" signature="m"><code></asyxml>*/
+ real m = 1;/*<asyxml></code><documentation>Used to cast mass<->point.</documentation></property></asyxml>*/
+ void init(coordsys R, pair coordinates, real mass)
+ {/*<asyxml></code><documentation>The constructor.</documentation></method></asyxml>*/
+ this.coordsys = R;
+ this.coordinates = coordinates;
+ this.x = coordinates.x;
+ this.y = coordinates.y;
+ this.m = mass;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="point" signature="point(coordsys,pair,real)"><code></asyxml>*/
+point point(coordsys R, pair p, real m = 1)
+{/*<asyxml></code><documentation>Return the point which has the coodinates 'p' in the
+ coordinate system 'R' and the mass 'm'.</documentation></function></asyxml>*/
+ point op;
+ op.init(R, p, m);
+ return op;
+}
+
+/*<asyxml><function type="point" signature="point(explicit pair,real)"><code></asyxml>*/
+point point(explicit pair p, real m)
+{/*<asyxml></code><documentation>Return the point which has the coodinates 'p' in the current
+ coordinate system and the mass 'm'.</documentation></function></asyxml>*/
+ point op;
+ op.init(currentcoordsys, p, m);
+ return op;
+}
+
+/*<asyxml><function type="point" signature="point(coordsys,explicit point,real)"><code></asyxml>*/
+point point(coordsys R, explicit point M, real m = M.m)
+{/*<asyxml></code><documentation>Return the point of 'R' which has the coordinates of 'M' and the mass 'm'.
+ Do not confuse this routine with the further routine 'changecoordsys'.</documentation></function></asyxml>*/
+ point op;
+ op.init(R, M.coordinates, M.m);
+ return op;
+}
+
+/*<asyxml><function type="point" signature="changecoordsys(coordsys,point)"><code></asyxml>*/
+point changecoordsys(coordsys R, point M)
+{/*<asyxml></code><documentation>Return the point 'M' in the coordinate system 'coordsys'.
+ In other words, the returned point marks the same plot as 'M' does.</documentation></function></asyxml>*/
+ point op;
+ coordsys mco = M.coordsys;
+ op.init(R, R.defaulttorelative(mco.relativetodefault(M.coordinates)), M.m);
+ return op;
+}
+
+/*<asyxml><function type="pair" signature="pair coordinates(point)"><code></asyxml>*/
+pair coordinates(point M)
+{/*<asyxml></code><documentation>Return the coordinates of 'M' in its coordinate system.</documentation></function></asyxml>*/
+ return M.coordinates;
+}
+
+/*<asyxml><function type="bool" signature="bool samecoordsys(bool...point[])"><code></asyxml>*/
+bool samecoordsys(bool warn = true ... point[] M)
+{/*<asyxml></code><documentation>Return true iff all the points have the same coordinate system.
+ If 'warn' is true and the coordinate systems are different, a warning is sent.</documentation></function></asyxml>*/
+ bool ret = true;
+ coordsys t = M[0].coordsys;
+ for (int i = 1; i < M.length; ++i) {
+ ret = (t == M[i].coordsys);
+ if(!ret) break;
+ t = M[i].coordsys;
+ }
+ if(warn && !ret)
+ warning("coodinatesystem",
+ "the coordinate system of two objects are not the same.
+The operation will be done relative to the default coordinate system.");
+ return ret;
+}
+
+/*<asyxml><function type="point[]" signature="standardizecoordsys(coordsys,bool...point[])"><code></asyxml>*/
+point[] standardizecoordsys(coordsys R = currentcoordsys,
+ bool warn = true ... point[] M)
+{/*<asyxml></code><documentation>Return the points with the same coordinate system 'R'.
+ If 'warn' is true and the coordinate systems are different, a warning is sent.</documentation></function></asyxml>*/
+ point[] op = new point[];
+ op = M;
+ if(!samecoordsys(warn ... M))
+ for (int i = 1; i < M.length; ++i)
+ op[i] = changecoordsys(R, M[i]);
+ return op;
+}
+
+/*<asyxml><operator type = "pair" signature="cast(point)"><code></asyxml>*/
+pair operator cast(point P)
+{/*<asyxml></code><documentation>Cast point to pair.</documentation></operator></asyxml>*/
+ return P.coordsys.relativetodefault(P.coordinates);
+}
+
+/*<asyxml><operator type = "pair[]" signature="cast(point[])"><code></asyxml>*/
+pair[] operator cast(point[] P)
+{/*<asyxml></code><documentation>Cast point[] to pair[].</documentation></operator></asyxml>*/
+ pair[] op;
+ for (int i = 0; i < P.length; ++i) {
+ op.push((pair)P[i]);
+ }
+ return op;
+}
+
+/*<asyxml><operator type = "point" signature="cast(pair)"><code></asyxml>*/
+point operator cast(pair p)
+{/*<asyxml></code><documentation>Cast pair to point relatively to the current coordinate
+ system 'currentcoordsys'.</documentation></operator></asyxml>*/
+ return point(currentcoordsys, p);
+}
+
+/*<asyxml><operator type = "point[]" signature="cast(pair[])"><code></asyxml>*/
+point[] operator cast(pair[] p)
+{/*<asyxml></code><documentation>Cast pair[] to point[] relatively to the current coordinate
+ system 'currentcoordsys'.</documentation></operator></asyxml>*/
+ pair[] op;
+ for (int i = 0; i < p.length; ++i) {
+ op.push((point)p[i]);
+ }
+ return op;
+}
+
+/*<asyxml><function type="pair" signature="locate(point)"><code></asyxml>*/
+pair locate(point P)
+{/*<asyxml></code><documentation>Return the coordinates of 'P' in the default coordinate system.</documentation></function></asyxml>*/
+ return P.coordsys * P.coordinates;
+}
+
+/*<asyxml><function type="point" signature="locate(pair)"><code></asyxml>*/
+point locate(pair p)
+{/*<asyxml></code><documentation>Return the point in the current coordinate system 'currentcoordsys'.</documentation></function></asyxml>*/
+ return p; //automatic casting 'pair to point'.
+}
+
+/*<asyxml><operator type = "point" signature="*(real,explicit point)"><code></asyxml>*/
+point operator *(real x, explicit point P)
+{/*<asyxml></code><documentation>Multiply the coordinates (not the mass) of 'P' by 'x'.</documentation></operator></asyxml>*/
+ return point(P.coordsys, x * P.coordinates, P.m);
+}
+
+/*<asyxml><operator type = "point" signature="/(explicit point,real)"><code></asyxml>*/
+point operator /(explicit point P, real x)
+{/*<asyxml></code><documentation>Divide the coordinates (not the mass) of 'P' by 'x'.</documentation></operator></asyxml>*/
+ return point(P.coordsys, P.coordinates/x, P.m);
+}
+
+/*<asyxml><operator type = "point" signature="/(real,explicit point)"><code></asyxml>*/
+point operator /(real x, explicit point P)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return point(P.coordsys, x/P.coordinates, P.m);
+}
+
+/*<asyxml><operator type = "point" signature="-(explicit point)"><code></asyxml>*/
+point operator -(explicit point P)
+{/*<asyxml></code><documentation>-P. The mass is inchanged.</documentation></operator></asyxml>*/
+ return point(P.coordsys, -P.coordinates, P.m);
+}
+
+/*<asyxml><operator type = "point" signature="+(explicit point,explicit point)"><code></asyxml>*/
+point operator +(explicit point P1, explicit point P2)
+{/*<asyxml></code><documentation>Provide 'point + point'.
+ If the two points haven't the same coordinate system, a warning is sent and the
+ returned point has the default coordinate system 'defaultcoordsys'.
+ The masses are added.</documentation></operator></asyxml>*/
+ point[] P = standardizecoordsys(P1, P2);
+ coordsys R = P[0].coordsys;
+ return point(R, P[0].coordinates + P[1].coordinates, P1.m + P2.m);
+}
+
+/*<asyxml><operator type = "point" signature="+(explicit point,explicit pair)"><code></asyxml>*/
+point operator +(explicit point P1, explicit pair p2)
+{/*<asyxml></code><documentation>Provide 'point + pair'.
+ The pair 'p2' is supposed to be coordinates relatively to the coordinates system of 'P1'.
+ The mass is not changed.</documentation></operator></asyxml>*/
+ coordsys R = currentcoordsys;
+ return point(R, P1.coordinates + point(R, p2).coordinates, P1.m);
+}
+point operator +(explicit pair p1, explicit point p2)
+{
+ return p2 + p1;
+}
+
+/*<asyxml><operator type = "point" signature="-(explicit point,explicit point)"><code></asyxml>*/
+point operator -(explicit point P1, explicit point P2)
+{/*<asyxml></code><documentation>Provide 'point - point'.</documentation></operator></asyxml>*/
+ return P1 + (-P2);
+}
+
+/*<asyxml><operator type = "point" signature="-(explicit point,explicit pair)"><code></asyxml>*/
+point operator -(explicit point P1, explicit pair p2)
+{/*<asyxml></code><documentation>Provide 'point - pair'.
+ The pair 'p2' is supposed to be coordinates relatively to the coordinates system of 'P1'.</documentation></operator></asyxml>*/
+ return P1 + (-p2);
+}
+point operator -(explicit pair p1, explicit point P2)
+{
+ return p1 + (-P2);
+}
+
+/*<asyxml><operator type = "point" signature="*(transform,explicit point)"><code></asyxml>*/
+point operator *(transform t, explicit point P)
+{/*<asyxml></code><documentation>Provide 'transform * point'.
+ Note that the transforms scale, xscale, yscale and rotate are carried out relatively
+ the default coordinate system 'defaultcoordsys' which is not desired for point
+ defined in an other coordinate system.
+ On can use scale(real, point), xscale(real, point), yscale(real, point), rotate(real, point),
+ scaleO(real), xscaleO(real), yscaleO(real) and rotateO(real) (described further)
+ to change the coordinate system of reference.</documentation></operator></asyxml>*/
+ coordsys R = P.coordsys;
+ return point(R, (t * locate(P))/R, P.m);
+}
+
+/*<asyxml><operator type = "point" signature="*(explicit point,explicit point)"><code></asyxml>*/
+point operator *(explicit point P1, explicit point P2)
+{/*<asyxml></code><documentation>Provide 'point * point'.
+ The resulted mass is the mass of P2</documentation></operator></asyxml>*/
+ point[] P = standardizecoordsys(P1, P2);
+ coordsys R = P[0].coordsys;
+ return point(R, P[0].coordinates * P[1].coordinates, P2.m);
+}
+
+/*<asyxml><operator type = "point" signature="*(explicit point,explicit pair)"><code></asyxml>*/
+point operator *(explicit point P1, explicit pair p2)
+{/*<asyxml></code><documentation>Provide 'point * pair'.
+ The pair 'p2' is supposed to be the coordinates of
+ the point in the coordinates system of 'P1'.
+ 'pair * point' is also defined.</documentation></operator></asyxml>*/
+ point P = point(P1.coordsys, p2, P1.m);
+ return P1 * P;
+}
+point operator *(explicit pair p1, explicit point p2)
+{
+ return p2 * p1;
+}
+
+/*<asyxml><operator type = "bool" signature="==(explicit point,explicit point)"><code></asyxml>*/
+bool operator ==(explicit point M, explicit point N)
+{/*<asyxml></code><documentation>Provide the test 'M == N' wish returns true iff MN < EPS</documentation></operator></asyxml>*/
+ return abs(locate(M) - locate(N)) < EPS;
+}
+
+/*<asyxml><operator type = "bool" signature="!=(explicit point,explicit point)"><code></asyxml>*/
+bool operator !=(explicit point M, explicit point N)
+{/*<asyxml></code><documentation>Provide the test 'M != N' wish return true iff MN >= EPS</documentation></operator></asyxml>*/
+ return !(M == N);
+}
+
+/*<asyxml><operator type = "guide" signature="cast(point)"><code></asyxml>*/
+guide operator cast(point p)
+{/*<asyxml></code><documentation>Cast point to guide.</documentation></operator></asyxml>*/
+ return locate(p);
+}
+
+/*<asyxml><operator type = "path" signature="cast(point)"><code></asyxml>*/
+path operator cast(point p)
+{/*<asyxml></code><documentation>Cast point to path.</documentation></operator></asyxml>*/
+ return locate(p);
+}
+
+/*<asyxml><function type="void" signature="dot(picture,Label,explicit point,align,string,pen)"><code></asyxml>*/
+void dot(picture pic = currentpicture, Label L, explicit point Z,
+ align align = NoAlign,
+ string format = defaultformat, pen p = currentpen)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ Label L = L.copy();
+ L.position(locate(Z));
+ if(L.s == "") {
+ if(format == "") format = defaultformat;
+ L.s = "("+format(format, Z.x)+", "+format(format, Z.y)+")";
+ }
+ L.align(align, E);
+ L.p(p);
+ dot(pic, locate(Z), p);
+ add(pic, L);
+}
+
+/*<asyxml><function type="real" signature="abs(coordsys,pair)"><code></asyxml>*/
+real abs(coordsys R, pair m)
+{/*<asyxml></code><documentation>Return the modulus |m| in the coordinate system 'R'.</documentation></function></asyxml>*/
+ return R.abs(m);
+}
+
+/*<asyxml><function type="real" signature="abs(explicit point)"><code></asyxml>*/
+real abs(explicit point M)
+{/*<asyxml></code><documentation>Return the modulus |M| in its coordinate system.</documentation></function></asyxml>*/
+ return M.coordsys.abs(M.coordinates);
+}
+
+/*<asyxml><function type="real" signature="length(explicit point)"><code></asyxml>*/
+real length(explicit point M)
+{/*<asyxml></code><documentation>Return the modulus |M| in its coordinate system (same as 'abs').</documentation></function></asyxml>*/
+ return M.coordsys.abs(M.coordinates);
+}
+
+/*<asyxml><function type="point" signature="conj(explicit point)"><code></asyxml>*/
+point conj(explicit point M)
+{/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/
+ return point(M.coordsys, conj(M.coordinates), M.m);
+}
+
+/*<asyxml><function type="real" signature="degrees(explicit point,coordsys,bool)"><code></asyxml>*/
+real degrees(explicit point M, coordsys R = M.coordsys, bool warn = true)
+{/*<asyxml></code><documentation>Return the angle of M (in degrees) relatively to 'R'.</documentation></function></asyxml>*/
+ return (degrees(locate(M) - R.O, warn) - degrees(R.i))%360;
+}
+
+/*<asyxml><function type="real" signature="angle(explicit point,coordsys,bool)"><code></asyxml>*/
+real angle(explicit point M, coordsys R = M.coordsys, bool warn = true)
+{/*<asyxml></code><documentation>Return the angle of M (in radians) relatively to 'R'.</documentation></function></asyxml>*/
+ return radians(degrees(M, R, warn));
+}
+
+/*<asyxml><function type="bool" signature="finite(explicit point)"><code></asyxml>*/
+bool finite(explicit point p)
+{/*<asyxml></code><documentation>Avoid to compute 'finite((pair)(infinite_point))'.</documentation></function></asyxml>*/
+ return finite(p.coordinates);
+}
+
+/*<asyxml><function type="real" signature="dot(point,point)"><code></asyxml>*/
+real dot(point A, point B)
+{/*<asyxml></code><documentation>Return the dot product in the coordinate system of 'A'.</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A.coordsys, A, B);
+ return P[0].coordsys.dot(P[0].coordinates, P[1].coordinates);
+}
+
+/*<asyxml><function type="real" signature="dot(point,explicit pair)"><code></asyxml>*/
+real dot(point A, explicit pair B)
+{/*<asyxml></code><documentation>Return the dot product in the default coordinate system.
+ dot(explicit pair, point) is also defined.</documentation></function></asyxml>*/
+ return dot(locate(A), B);
+}
+real dot(explicit pair A, point B)
+{
+ return dot(A, locate(B));
+}
+
+/*<asyxml><function type="transforms" signature="rotateO(real)"><code></asyxml>*/
+transform rotateO(real a)
+{/*<asyxml></code><documentation>Rotation around the origin of the current coordinate system.</documentation></function></asyxml>*/
+ return rotate(a, currentcoordsys.O);
+};
+
+/*<asyxml><function type="transform" signature="projection(point,point)"><code></asyxml>*/
+transform projection(point A, point B)
+{/*<asyxml></code><documentation>Return the orthogonal projection on the line (AB).</documentation></function></asyxml>*/
+ pair dir = unit(locate(A) - locate(B));
+ pair a = locate(A);
+ real cof = dir.x * a.x + dir.y * a.y;
+ real tx = a.x - dir.x * cof;
+ real txx = dir.x^2;
+ real txy = dir.x * dir.y;
+ real ty = a.y - dir.y * cof;
+ real tyx = txy;
+ real tyy = dir.y^2;
+ transform t = (tx, ty, txx, txy, tyx, tyy);
+ return t;
+}
+
+/*<asyxml><function type="transform" signature="projection(point,point,point,point,bool)"><code></asyxml>*/
+transform projection(point A, point B, point C, point D, bool safe = false)
+{/*<asyxml></code><documentation>Return the (CD) parallel projection on (AB).
+ If 'safe = true' and (AB)//(CD) return the identity.
+ If 'safe = false' and (AB)//(CD) return an infinity scaling.</documentation></function></asyxml>*/
+ pair a = locate(A);
+ pair u = unit(locate(B) - locate(A));
+ pair v = unit(locate(D) - locate(C));
+ real c = u.x * a.y - u.y * a.x;
+ real d = (conj(u) * v).y;
+ if (abs(d) < epsgeo) {
+ return safe ? identity() : scale(infinity);
+ }
+ real tx = c * v.x/d;
+ real ty = c * v.y/d;
+ real txx = u.x * v.y/d;
+ real txy = -u.x * v.x/d;
+ real tyx = u.y * v.y/d;
+ real tyy = -u.y * v.x/d;
+ transform t = (tx, ty, txx, txy, tyx, tyy);
+ return t;
+}
+
+/*<asyxml><function type="transform" signature="scale(real,point)"><code></asyxml>*/
+transform scale(real k, point M)
+{/*<asyxml></code><documentation>Homothety.</documentation></function></asyxml>*/
+ pair P = locate(M);
+ return shift(P) * scale(k) * shift(-P);
+}
+
+/*<asyxml><function type="transform" signature="xscale(real,point)"><code></asyxml>*/
+transform xscale(real k, point M)
+{/*<asyxml></code><documentation>xscale from 'M' relatively to the x - axis of the coordinate system of 'M'.</documentation></function></asyxml>*/
+ pair P = locate(M);
+ real a = degrees(M.coordsys.i);
+ return (shift(P) * rotate(a)) * xscale(k) * (rotate(-a) * shift(-P));
+}
+
+/*<asyxml><function type="transform" signature="yscale(real,point)"><code></asyxml>*/
+transform yscale(real k, point M)
+{/*<asyxml></code><documentation>yscale from 'M' relatively to the y - axis of the coordinate system of 'M'.</documentation></function></asyxml>*/
+ pair P = locate(M);
+ real a = degrees(M.coordsys.j) - 90;
+ return (shift(P) * rotate(a)) * yscale(k) * (rotate(-a) * shift(-P));
+}
+
+/*<asyxml><function type="transform" signature="scale(real,point,point,point,point,bool)"><code></asyxml>*/
+transform scale(real k, point A, point B, point C, point D, bool safe = false)
+{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Affinit%C3%A9_%28math%C3%A9matiques%29"/>
+ (help me for English translation...)
+ If 'safe = true' and (AB)//(CD) return the identity.
+ If 'safe = false' and (AB)//(CD) return a infinity scaling.</documentation></function></asyxml>*/
+ pair a = locate(A);
+ pair u = unit(locate(B) - locate(A));
+ pair v = unit(locate(D) - locate(C));
+ real c = u.x * a.y - u.y * a.x;
+ real d = (conj(u) * v).y;
+ real d = (conj(u) * v).y;
+ if (abs(d) < epsgeo) {
+ return safe ? identity() : scale(infinity);
+ }
+ real tx = (1 - k) * c * v.x/d;
+ real ty = (1 - k) * c * v.y/d;
+ real txx = (1 - k) * u.x * v.y/d + k;
+ real txy = (k - 1) * u.x * v.x/d;
+ real tyx = (1 - k) * u.y * v.y/d;
+ real tyy = (k - 1) * u.y * v.x/d + k;
+ transform t = (tx, ty, txx, txy, tyx, tyy);
+ return t;
+}
+
+/*<asyxml><function type="transform" signature="scaleO(real)"><code></asyxml>*/
+transform scaleO(real x)
+{/*<asyxml></code><documentation>Homothety from the origin of the current coordinate system.</documentation></function></asyxml>*/
+ return scale(x, (0, 0));
+}
+
+/*<asyxml><function type="transform" signature="xscaleO(real)"><code></asyxml>*/
+transform xscaleO(real x)
+{/*<asyxml></code><documentation>xscale from the origin and relatively to the current coordinate system.</documentation></function></asyxml>*/
+ return scale(x, (0, 0), (0, 1), (0, 0), (1, 0));
+}
+
+/*<asyxml><function type="transform" signature="yscaleO(real)"><code></asyxml>*/
+transform yscaleO(real x)
+{/*<asyxml></code><documentation>yscale from the origin and relatively to the current coordinate system.</documentation></function></asyxml>*/
+ return scale(x, (0, 0), (1, 0), (0, 0), (0, 1));
+}
+
+/*<asyxml><struct signature="vector"><code></asyxml>*/
+struct vector
+{/*<asyxml></code><documentation>Like a point but casting to pair, adding etc does not take account
+ of the origin of the coordinate system.</documentation><property type = "point" signature="v"><code></asyxml>*/
+ point v;/*<asyxml></code><documentation>Coordinates as a point (embed coordinate system and pair).</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><operator type = "point" signature="cast(vector)"><code></asyxml>*/
+point operator cast(vector v)
+{/*<asyxml></code><documentation>Cast vector 'v' to point 'M' so that OM = v.</documentation></operator></asyxml>*/
+ return v.v;
+}
+
+/*<asyxml><operator type = "vector" signature="cast(pair)"><code></asyxml>*/
+vector operator cast(pair v)
+{/*<asyxml></code><documentation>Cast pair to vector relatively to the current coordinate
+ system 'currentcoordsys'.</documentation></operator></asyxml>*/
+ vector ov;
+ ov.v = point(currentcoordsys, v);
+ return ov;
+}
+
+/*<asyxml><operator type = "vector" signature="cast(explicit point)"><code></asyxml>*/
+vector operator cast(explicit point v)
+{/*<asyxml></code><documentation>A point can be interpreted like a vector using the code
+ '(vector)a_point'.</documentation></operator></asyxml>*/
+ vector ov;
+ ov.v = v;
+ return ov;
+}
+
+/*<asyxml><operator type = "pair" signature="cast(explicit vector)"><code></asyxml>*/
+pair operator cast(explicit vector v)
+{/*<asyxml></code><documentation>Cast vector to pair (the coordinates of 'v' in the default coordinate system).</documentation></operator></asyxml>*/
+ return locate(v.v) - v.v.coordsys.O;
+}
+
+/*<asyxml><operator type = "align" signature="cast(vector)"><code></asyxml>*/
+align operator cast(vector v)
+{/*<asyxml></code><documentation>Cast vector to align.</documentation></operator></asyxml>*/
+ return (pair)v;
+}
+
+/*<asyxml><function type="vector" signature="vector(coordsys, pair)"><code></asyxml>*/
+vector vector(coordsys R = currentcoordsys, pair v)
+{/*<asyxml></code><documentation>Return the vector of 'R' which has the coordinates 'v'.</documentation></function></asyxml>*/
+ vector ov;
+ ov.v = point(R, v);
+ return ov;
+}
+
+/*<asyxml><function type="vector" signature="vector(point)"><code></asyxml>*/
+vector vector(point M)
+{/*<asyxml></code><documentation>Return the vector OM, where O is the origin of the coordinate system of 'M'.
+ Useful to write 'vector(P - M);' instead of '(vector)(P - M)'.</documentation></function></asyxml>*/
+ return M;
+}
+
+/*<asyxml><function type="point" signature="point(explicit vector)"><code></asyxml>*/
+point point(explicit vector u)
+{/*<asyxml></code><documentation>Return the point M so that OM = u, where O is the origin of the coordinate system of 'u'.</documentation></function></asyxml>*/
+ return u.v;
+}
+
+/*<asyxml><function type="pair" signature="locate(explicit vector)"><code></asyxml>*/
+pair locate(explicit vector v)
+{/*<asyxml></code><documentation>Return the coordinates of 'v' in the default coordinate system (like casting vector to pair).</documentation></function></asyxml>*/
+ return (pair)v;
+}
+
+/*<asyxml><function type="void" signature="show(Label,pen,arrowbar)"><code></asyxml>*/
+void show(Label L, vector v, pen p = currentpen, arrowbar arrow = Arrow)
+{/*<asyxml></code><documentation>Draw the vector v (from the origin of its coordinate system).</documentation></function></asyxml>*/
+ coordsys R = v.v.coordsys;
+ draw(L, R.O--v.v, p, arrow);
+}
+
+/*<asyxml><function type="vector" signature="changecoordsys(coordsys,vector)"><code></asyxml>*/
+vector changecoordsys(coordsys R, vector v)
+{/*<asyxml></code><documentation>Return the vector 'v' relatively to coordinate system 'R'.</documentation></function></asyxml>*/
+ vector ov;
+ ov.v = point(R, (locate(v) + R.O)/R);
+ return ov;
+}
+
+/*<asyxml><operator type = "vector" signature="*(real,explicit vector)"><code></asyxml>*/
+vector operator *(real x, explicit vector v)
+{/*<asyxml></code><documentation>Provide real * vector.</documentation></operator></asyxml>*/
+ return x * v.v;
+}
+
+/*<asyxml><operator type = "vector" signature="/(explicit vector,real)"><code></asyxml>*/
+vector operator /(explicit vector v, real x)
+{/*<asyxml></code><documentation>Provide vector/real</documentation></operator></asyxml>*/
+ return v.v/x;
+}
+
+/*<asyxml><operator type = "vector" signature="*(transform t,explicit vector)"><code></asyxml>*/
+vector operator *(transform t, explicit vector v)
+{/*<asyxml></code><documentation>Provide transform * vector.</documentation></operator></asyxml>*/
+ return t * v.v;
+}
+
+/*<asyxml><operator type = "vector" signature="*(explicit point,explicit vector)"><code></asyxml>*/
+vector operator *(explicit point M, explicit vector v)
+{/*<asyxml></code><documentation>Provide point * vector</documentation></operator></asyxml>*/
+ return M * v.v;
+}
+
+/*<asyxml><operator type = "point" signature="+(explicit point,explicit vector)"><code></asyxml>*/
+point operator +(point M, explicit vector v)
+{/*<asyxml></code><documentation>Return 'M' shifted by 'v'.</documentation></operator></asyxml>*/
+ return shift(locate(v)) * M;
+}
+
+/*<asyxml><operator type = "point" signature="-(explicit point,explicit vector)"><code></asyxml>*/
+point operator -(point M, explicit vector v)
+{/*<asyxml></code><documentation>Return 'M' shifted by '-v'.</documentation></operator></asyxml>*/
+ return shift(-locate(v)) * M;
+}
+
+/*<asyxml><operator type = "vector" signature="-(explicit vector)"><code></asyxml>*/
+vector operator -(explicit vector v)
+{/*<asyxml></code><documentation>Provide -v.</documentation></operator></asyxml>*/
+ return -v.v;
+}
+
+/*<asyxml><operator type = "point" signature="+(explicit pair,explicit vector)"><code></asyxml>*/
+point operator +(explicit pair m, explicit vector v)
+{/*<asyxml></code><documentation>The pair 'm' is supposed to be the coordinates of
+ a point in the current coordinates system 'currentcoordsys'.
+ Return this point shifted by the vector 'v'.</documentation></operator></asyxml>*/
+ return locate(m) + v;
+}
+
+/*<asyxml><operator type = "point" signature="-(explicit pair,explicit vector)"><code></asyxml>*/
+point operator -(explicit pair m, explicit vector v)
+{/*<asyxml></code><documentation>The pair 'm' is supposed to be the coordinates of
+ a point in the current coordinates system 'currentcoordsys'.
+ Return this point shifted by the vector '-v'.</documentation></operator></asyxml>*/
+ return m + (-v);
+}
+
+/*<asyxml><operator type = "vector" signature="+(explicit vector,explicit vector)"><code></asyxml>*/
+vector operator +(explicit vector v1, explicit vector v2)
+{/*<asyxml></code><documentation>Provide vector + vector.
+ If the two vector haven't the same coordinate system, the returned
+ vector is relative to the default coordinate system (without warning).</documentation></operator></asyxml>*/
+ coordsys R = v1.v.coordsys;
+ if(samecoordsys(false, v1, v2)){R = defaultcoordsys;}
+ return vector(R, (locate(v1) + locate(v2))/R);
+}
+
+/*<asyxml><operator type = "vector" signature="-(explicit vector, explicit vector)"><code></asyxml>*/
+vector operator -(explicit vector v1, explicit vector v2)
+{/*<asyxml></code><documentation>Provide vector - vector.
+ If the two vector haven't the same coordinate system, the returned
+ vector is relative to the default coordinate system (without warning).</documentation></operator></asyxml>*/
+ return v1 + (-v2);
+}
+
+/*<asyxml><operator type = "bool" signature="==(explicit vector,explicit vector)"><code></asyxml>*/
+bool operator ==(explicit vector u, explicit vector v)
+{/*<asyxml></code><documentation>Return true iff |u - v|<EPS.</documentation></operator></asyxml>*/
+ return abs(u - v) < EPS;
+}
+
+/*<asyxml><function type="bool" signature="collinear(vector,vector)"><code></asyxml>*/
+bool collinear(vector u, vector v)
+{/*<asyxml></code><documentation>Return 'true' iff the vectors 'u' and 'v' are collinear.</documentation></function></asyxml>*/
+ return abs(ypart((conj((pair)u) * (pair)v))) < EPS;
+}
+
+/*<asyxml><function type="vector" signature="unit(point)"><code></asyxml>*/
+vector unit(point M)
+{/*<asyxml></code><documentation>Return the unit vector according to the modulus of its coordinate system.</documentation></function></asyxml>*/
+ return M/abs(M);
+}
+
+/*<asyxml><function type="vector" signature="unit(vector)"><code></asyxml>*/
+vector unit(vector u)
+{/*<asyxml></code><documentation>Return the unit vector according to the modulus of its coordinate system.</documentation></function></asyxml>*/
+ return u.v/abs(u.v);
+}
+
+/*<asyxml><function type="real" signature="degrees(vector,coordsys,bool)"><code></asyxml>*/
+real degrees(vector v,
+ coordsys R = v.v.coordsys,
+ bool warn = true)
+{/*<asyxml></code><documentation>Return the angle of 'v' (in degrees) relatively to 'R'.</documentation></function></asyxml>*/
+ return (degrees(locate(v), warn) - degrees(R.i))%360;
+}
+
+/*<asyxml><function type="real" signature="angle(vector,coordsys,bool)"><code></asyxml>*/
+real angle(explicit vector v,
+ coordsys R = v.v.coordsys,
+ bool warn = true)
+{/*<asyxml></code><documentation>Return the angle of 'v' (in radians) relatively to 'R'.</documentation></function></asyxml>*/
+ return radians(degrees(v, R, warn));
+}
+
+/*<asyxml><function type="vector" signature="conj(explicit vector)"><code></asyxml>*/
+vector conj(explicit vector u)
+{/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/
+ return conj(u.v);
+}
+
+/*<asyxml><function type="transform" signature="rotate(explicit vector)"><code></asyxml>*/
+transform rotate(explicit vector dir)
+{/*<asyxml></code><documentation>A rotation in the direction 'dir' limited to [-90, 90]
+ This is useful for rotating text along a line in the direction dir.
+ rotate(explicit point dir) is also defined.
+ </documentation></function></asyxml>*/
+ return rotate(locate(dir));
+}
+transform rotate(explicit point dir){return rotate(locate(vector(dir)));}
+// *......................COORDINATES......................*
+// *=======================================================*
+
+// *=======================================================*
+// *.........................BASES.........................*
+/*<asyxml><variable type="point" signature="origin"><code></asyxml>*/
+point origin = point(defaultcoordsys, (0, 0));/*<asyxml></code><documentation>The origin of the current coordinate system.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="point" signature="origin(coordsys)"><code></asyxml>*/
+point origin(coordsys R = currentcoordsys)
+{/*<asyxml></code><documentation>Return the origin of the coordinate system 'R'.</documentation></function></asyxml>*/
+ return point(R, (0, 0)); //use automatic casting;
+}
+
+/*<asyxml><variable type="real" signature="linemargin"><code></asyxml>*/
+real linemargin = 0;/*<asyxml></code><documentation>Margin used to draw lines.</documentation></variable></asyxml>*/
+/*<asyxml><function type="real" signature="linemargin()"><code></asyxml>*/
+real linemargin()
+{/*<asyxml></code><documentation>Return the margin used to draw lines.</documentation></function></asyxml>*/
+ return linemargin;
+}
+
+/*<asyxml><variable type="pen" signature="addpenline"><code></asyxml>*/
+pen addpenline = squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of "finish" lines.</documentation></variable></asyxml>*/
+pen addpenline(pen p) {
+ return addpenline + p;
+}
+
+/*<asyxml><variable type="pen" signature="addpenarc"><code></asyxml>*/
+pen addpenarc = squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of arcs.</documentation></variable></asyxml>*/
+pen addpenarc(pen p) {return addpenarc + p;}
+
+/*<asyxml><variable type="string" signature="defaultmassformat"><code></asyxml>*/
+string defaultmassformat = "$\left(%L;%.4g\right)$";/*<asyxml></code><documentation>Format used to construct the default label of masses.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="int" signature="sgnd(real)"><code></asyxml>*/
+int sgnd(real x)
+{/*<asyxml></code><documentation>Return the -1 if x < 0, 1 if x >= 0.</documentation></function></asyxml>*/
+ return (x == 0) ? 1 : sgn(x);
+}
+int sgnd(int x)
+{
+ return (x == 0) ? 1 : sgn(x);
+}
+
+/*<asyxml><function type="bool" signature="defined(pair)"><code></asyxml>*/
+bool defined(point P)
+{/*<asyxml></code><documentation>Return true iff the coordinates of 'P' are finite.</documentation></function></asyxml>*/
+ return finite(P.coordinates);
+}
+
+/*<asyxml><function type="bool" signature="onpath(picture,path,point,pen)"><code></asyxml>*/
+bool onpath(picture pic = currentpicture, path g, point M, pen p = currentpen)
+{/*<asyxml></code><documentation>Return true iff 'M' is on the path drawn with the pen 'p' in 'pic'.</documentation></function></asyxml>*/
+ transform t = inverse(pic.calculateTransform());
+ return intersect(g, shift(locate(M)) * scale(linewidth(p)/2) * t * unitcircle).length > 0;
+}
+
+/*<asyxml><function type="bool" signature="sameside(point,point,point)"><code></asyxml>*/
+bool sameside(point M, point N, point O)
+{/*<asyxml></code><documentation>Return 'true' iff 'M' and 'N' are same side of the point 'O'.</documentation></function></asyxml>*/
+ pair m = M, n = N, o = O;
+ return dot(m - o, n - o) >= -epsgeo;
+}
+
+/*<asyxml><function type="bool" signature="between(point,point,point)"><code></asyxml>*/
+bool between(point M, point O, point N)
+{/*<asyxml></code><documentation>Return 'true' iff 'O' is between 'M' and 'N'.</documentation></function></asyxml>*/
+ return (!sameside(N, M, O) || M == O || N == O);
+}
+
+
+typedef path pathModifier(path);
+pathModifier NoModifier = new path(path g){return g;};
+
+private void Drawline(picture pic = currentpicture, Label L = "", pair P, bool dirP = true, pair Q, bool dirQ = true,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None,
+ Label legend = "", marker marker = nomarker,
+ pathModifier pathModifier = NoModifier)
+{/* Add the two parameters 'dirP' and 'dirQ' to the native routine
+ 'drawline' of the module 'math'.
+ Segment [PQ] will be prolonged in direction of P if 'dirP = true', in
+ direction of Q if 'dirQ = true'.
+ If 'dirP = dirQ = true', the behavior is that of the native 'drawline'.
+ Add all the other parameters of 'Draw'.*/
+ pic.add(new void (frame f, transform t, transform T, pair m, pair M) {
+ picture opic;
+ // Reduce the bounds by the size of the pen.
+ m -= min(p) - (linemargin(), linemargin()); M -= max(p) + (linemargin(), linemargin());
+
+ // Calculate the points and direction vector in the transformed space.
+ t = t * T;
+ pair z = t * P;
+ pair q = t * Q;
+ pair v = q - z;
+ // path g;
+ pair ptp, ptq;
+ real cp = dirP ? 1:0;
+ real cq = dirQ ? 1:0;
+ // Handle horizontal and vertical lines.
+ if(v.x == 0) {
+ if(m.x <= z.x && z.x <= M.x)
+ if (dot(v, m - z) < 0) {
+ ptp = (z.x, z.y + cp * (m.y - z.y));
+ ptq = (z.x, q.y + cq * (M.y - q.y));
+ } else {
+ ptq = (z.x, q.y + cq * (m.y - q.y));
+ ptp = (z.x, z.y + cp * (M.y - z.y));
+ }
+ } else if(v.y == 0) {
+ if (dot(v, m - z) < 0) {
+ ptp = (z.x + cp * (m.x - z.x), z.y);
+ ptq = (q.x + cq * (M.x - q.x), z.y);
+ } else {
+ ptq = (q.x + cq * (m.x - q.x), z.y);
+ ptp = (z.x + cp * (M.x - z.x), z.y);
+ }
+ } else {
+ // Calculate the maximum and minimum t values allowed for the
+ // parametric equation z + t * v
+ real mx = (m.x - z.x)/v.x, Mx = (M.x - z.x)/v.x;
+ real my = (m.y - z.y)/v.y, My = (M.y - z.y)/v.y;
+ real tmin = max(v.x > 0 ? mx : Mx, v.y > 0 ? my : My);
+ real tmax = min(v.x > 0 ? Mx : mx, v.y > 0 ? My : my);
+ pair pmin = z + tmin * v;
+ pair pmax = z + tmax * v;
+ if(tmin <= tmax) {
+ ptp = z + cp * tmin * v;
+ ptq = z + (cq == 0 ? v:tmax * v);
+ }
+ }
+ path g = ptp--ptq;
+ if (length(g)>0)
+ {
+ if(L.s != "") {
+ Label lL = L.copy();
+ if(L.defaultposition) lL.position(Relative(.9));
+ lL.p(p);
+ lL.out(opic, g);
+ }
+ g = pathModifier(g);
+ if(linetype(p).length == 0){
+ pair m = midpoint(g);
+ pen tp;
+ tp = dirP ? p : addpenline(p);
+ draw(opic, pathModifier(m--ptp), tp);
+ tp = dirQ ? p : addpenline(p);
+ draw(opic, pathModifier(m--ptq), tp);
+ } else {
+ draw(opic, g, p);
+ }
+ marker.markroutine(opic, marker.f, g);
+ arrow(opic, g, p, NoMargin);
+ add(f, opic.fit());
+ }
+ });
+}
+
+/*<asyxml><function type="void" signature="clipdraw(picture,Label,path,align,pen,arrowbar,arrowbar,real,real,Label,marker)"><code></asyxml>*/
+void clipdraw(picture pic = currentpicture, Label L = "", path g,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None, arrowbar bar = None,
+ real xmargin = 0, real ymargin = xmargin,
+ Label legend = "", marker marker = nomarker)
+{/*<asyxml></code><documentation>Draw the path 'g' on 'pic' clipped to the bounding box of 'pic'.</documentation></function></asyxml>*/
+ if(L.s != "") {
+ picture tmp;
+ label(tmp, L, g, p);
+ add(pic, tmp);
+ }
+ pic.add(new void (frame f, transform t, transform T, pair m, pair M) {
+ // Reduce the bounds by the size of the pen and the margins.
+ m += min(p) + (xmargin, ymargin); M -= max(p) + (xmargin, ymargin);
+ path bound = box(m, M);
+ picture tmp;
+ draw(tmp, "", t * T * g, align, p, arrow, bar, NoMargin, legend, marker);
+ clip(tmp, bound);
+ add(f, tmp.fit());
+ });
+}
+
+/*<asyxml><function type="void" signature="distance(picture pic,Label,point,point,bool,real,pen,pen,arrow)"><code></asyxml>*/
+void distance(picture pic = currentpicture, Label L = "", point A, point B,
+ bool rotated = true, real offset = 3mm,
+ pen p = currentpen, pen joinpen = invisible,
+ arrowbar arrow = Arrows(NoFill))
+{/*<asyxml></code><documentation>Draw arrow between A and B (from FAQ).</documentation></function></asyxml>*/
+ pair A = A, B = B;
+ path g = A--B;
+ transform Tp = shift(-offset * unit(B - A) * I);
+ pic.add(new void(frame f, transform t) {
+ picture opic;
+ path G = Tp * t * g;
+ transform id = identity();
+ transform T = rotated ? rotate(B - A) : id;
+ Label L = L.copy();
+ L.align(L.align, Center);
+ if(abs(ypart((conj(A - B) * L.align.dir))) < epsgeo && L.filltype == NoFill)
+ L.filltype = UnFill(1);
+ draw(opic, T * L, G, p, arrow, Bars, PenMargins);
+ pair Ap = t * A, Bp = t * B;
+ draw(opic, (Ap--Tp * Ap)^^(Bp--Tp * Bp), joinpen);
+ add(f, opic.fit());
+ }, true);
+ pic.addBox(min(g), max(g), Tp * min(p), Tp * max(p));
+}
+
+/*<asyxml><variable type="real" signature="perpfactor"><code></asyxml>*/
+real perpfactor = 1;/*<asyxml></code><documentation>Factor for drawing perpendicular symbol.</documentation></variable></asyxml>*/
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,explicit pair,explicit pair,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic = currentpicture, point z,
+ explicit pair align,
+ explicit pair dir = E, real size = 0,
+ pen p = currentpen,
+ margin margin = NoMargin,
+ filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z + dir.
+ dir(45 + n * 90), where n in N*, are common values for 'align'.</documentation></function></asyxml>*/
+ p = squarecap + miterjoin + p;
+ if(size == 0) size = perpfactor * 3mm + linewidth(p) / 2;
+ frame apic;
+ pair d1 = size * align * unit(dir) * dir(-45);
+ pair d2 = I * d1;
+ path g = d1--d1 + d2--d2;
+ g = margin(g, p).g;
+ draw(apic, g, p);
+ if(filltype != NoFill) filltype.fill(apic, (relpoint(g, 0) - relpoint(g, 0.5)+
+ relpoint(g, 1))--g--cycle, p + solid);
+ add(pic, apic, locate(z));
+}
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,vector,vector,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic = currentpicture, point z,
+ vector align,
+ vector dir = E, real size = 0,
+ pen p = currentpen,
+ margin margin = NoMargin,
+ filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z + dir.
+ dir(45 + n * 90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/
+ perpendicularmark(pic, z, (pair)align, (pair)dir, size,
+ p, margin, filltype);
+}
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,explicit pair,path,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic = currentpicture, point z, explicit pair align, path g,
+ real size = 0, pen p = currentpen,
+ margin margin = NoMargin,
+ filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z + dir(g, 0).
+ dir(45 + n * 90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/
+ perpendicularmark(pic, z, align, dir(g, 0), size, p, margin, filltype);
+}
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,vector,path,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic = currentpicture, point z, vector align, path g,
+ real size = 0, pen p = currentpen,
+ margin margin = NoMargin,
+ filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z + dir(g, 0).
+ dir(45 + n * 90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/
+ perpendicularmark(pic, z, (pair)align, dir(g, 0), size, p, margin, filltype);
+}
+
+/*<asyxml><function type="void" signature="markrightangle(picture,point,point,point,real,pen,margin,filltype)"><code></asyxml>*/
+void markrightangle(picture pic = currentpicture, point A, point O,
+ point B, real size = 0, pen p = currentpen,
+ margin margin = NoMargin,
+ filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Mark the angle AOB with a perpendicular symbol.</documentation></function></asyxml>*/
+ pair Ap = A, Bp = B, Op = O;
+ pair dir = Ap - Op;
+ real a1 = degrees(dir);
+ pair align = rotate(-a1) * unit(dir(Op--Ap, Op--Bp));
+ perpendicularmark(pic = pic, z = O, align = align,
+ dir = dir, size = size, p = p,
+ margin = margin, filltype = filltype);
+}
+
+/*<asyxml><function type="bool" signature="simeq(point,point,real)"><code></asyxml>*/
+bool simeq(point A, point B, real fuzz = epsgeo)
+{/*<asyxml></code><documentation>Return true iff abs(A - B) < fuzz.
+ This routine is used internally to know if two points are equal, in particular by the operator == in 'point == point'.</documentation></function></asyxml>*/
+ return (abs(A - B) < fuzz);
+}
+bool simeq(point a, real b, real fuzz = epsgeo)
+{
+ coordsys R = a.coordsys;
+ return (abs(a - point(R, ((pair)b)/R)) < fuzz);
+}
+
+/*<asyxml><function type="pair" signature="attract(pair,path,real)"><code></asyxml>*/
+pair attract(pair m, path g, real fuzz = 0)
+{/*<asyxml></code><documentation>Return the nearest point (A PAIR) of 'm' which is on the path g.
+ 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/
+ if(intersect(m, g, fuzz).length > 0) return m;
+ pair p;
+ real step = 1, r = 0;
+ real[] t;
+ static real eps = sqrt(realEpsilon);
+ do {// Find a radius for intersection
+ r += step;
+ t = intersect(shift(m) * scale(r) * unitcircle, g);
+ } while(t.length <= 0);
+ p = point(g, t[1]);
+ real rm = 0, rM = r;
+ while(rM - rm > eps) {
+ r = (rm + rM)/2;
+ t = intersect(shift(m) * scale(r) * unitcircle, g, fuzz);
+ if(t.length <= 0) {
+ rm = r;
+ } else {
+ rM = r;
+ p = point(g, t[1]);
+ }
+ }
+ return p;
+}
+
+/*<asyxml><function type="point" signature="attract(point,path,real)"><code></asyxml>*/
+point attract(point M, path g, real fuzz = 0)
+{/*<asyxml></code><documentation>Return the nearest point (A POINT) of 'M' which is on the path g.
+ 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/
+ return point(M.coordsys, attract(locate(M), g)/M.coordsys);
+}
+
+/*<asyxml><function type="real[]" signature="intersect(path,explicit pair)"><code></asyxml>*/
+real[] intersect(path g, explicit pair p, real fuzz = 0)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ fuzz = fuzz <= 0 ? sqrt(realEpsilon) : fuzz;
+ real[] or;
+ real r = realEpsilon;
+ do{
+ or = intersect(g, shift(p) * scale(r) * unitcircle, fuzz);
+ r *= 2;
+ } while(or.length == 0);
+ return or;
+}
+
+/*<asyxml><function type="real[]" signature="intersect(path,explicit point)"><code></asyxml>*/
+real[] intersect(path g, explicit point P, real fuzz = epsgeo)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersect(g, locate(P), fuzz);
+}
+// *.........................BASES.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.........................LINES.........................*
+/*<asyxml><struct signature="line"><code></asyxml>*/
+struct line
+{/*<asyxml></code><documentation>This structure provides the objects line, semi - line and segment oriented from A to B.
+ All the calculus with this structure will be as exact as Asymptote can do.
+ For a full precision, you must not cast 'line' to 'path' excepted for drawing routines.</documentation></asyxml>*/
+ /*<asyxml><property type = "point" signature="A,B"><code></asyxml>*/
+ restricted point A,B;/*<asyxml></code><documentation>Two line's points with same coordinate system.</documentation></property><property type = "bool" signature="extendA,extendB"><code></asyxml>*/
+ bool extendA,extendB;/*<asyxml></code><documentation>If true,extend 'l' in direction of A (resp. B).</documentation></property><property type = "vector" signature="u,v"><code></asyxml>*/
+ restricted vector u,v;/*<asyxml></code><documentation>u = unit(AB) = direction vector,v = normal vector.</documentation></property><property type = "real" signature="a,b,c"><code></asyxml>*/
+ restricted real a,b,c;/*<asyxml></code><documentation>Coefficients of the equation ax + by + c = 0 in the coordinate system of 'A'.</documentation></property><property type = "real" signature="slope,origin"><code></asyxml>*/
+ restricted real slope, origin;/*<asyxml></code><documentation>Slope and ordinate at the origin.</documentation></property></asyxml>*/
+ /*<asyxml><method type = "line" signature="copy()"><code></asyxml>*/
+ line copy()
+ {/*<asyxml></code><documentation>Copy a line in a new instance.</documentation></method></asyxml>*/
+ line l = new line;
+ l.A = A;
+ l.B = B;
+ l.a = a;
+ l.b = b;
+ l.c = c;
+ l.slope = slope;
+ l.origin = origin;
+ l.u = u;
+ l.v = v;
+ l.extendA = extendA;
+ l.extendB = extendB;
+ return l;
+ }
+
+ /*<asyxml><method type = "void" signature="init(point,bool,point,bool)"><code></asyxml>*/
+ void init(point A, bool extendA = true, point B, bool extendB = true)
+ {/*<asyxml></code><documentation>Initialize line.
+ If 'extendA' is true, the "line" is infinite in the direction of A.</documentation></method></asyxml>*/
+ point[] P = standardizecoordsys(A, B);
+ this.A = P[0];
+ this.B = P[1];
+ this.a = B.y - A.y;
+ this.b = A.x - B.x;
+ this.c = A.y * B.x - A.x * B.y;
+ this.slope= (this.b == 0) ? infinity : -this.a/this.b;
+ this.origin = (this.b == 0) ? (this.c == 0) ? 0:infinity : -this.c/this.b;
+ this.u = unit(P[1]-P[0]);
+ // int tmp = sgnd(this.slope);
+ // this.u = (dot((pair)this.u, N) >= 0) ? tmp * this.u : -tmp * this.u;
+ this.v = rotate(90, point(P[0].coordsys, (0, 0))) * this.u;
+ this.extendA = extendA;
+ this.extendB = extendB;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="line" signature="line(point,bool,point,bool)"><code></asyxml>*/
+line line(point A, bool extendA = true, point B, bool extendB = true)
+{/*<asyxml></code><documentation>Return the line passing through 'A' and 'B'.
+ If 'extendA' is true, the "line" is infinite in the direction of A.
+ A "line" can be half-line or segment.</documentation></function></asyxml>*/
+ if (A == B) abort("line: the points must be distinct.");
+ line l;
+ l.init(A, extendA, B, extendB);
+ return l;
+}
+
+/*<asyxml><struct signature="segment"><code></asyxml>*/
+struct segment
+{/*<asyxml></code><documentation><look href = "struct line"/>.</documentation></asyxml>*/
+ restricted point A, B;// Extremity.
+ restricted vector u, v;// u = direction vector, v = normal vector.
+ restricted real a, b, c;// Coefficients of the équation ax + by + c = 0
+ restricted real slope, origin;
+ segment copy()
+ {
+ segment s = new segment;
+ s.A = A;
+ s.B = B;
+ s.a = a;
+ s.b = b;
+ s.c = c;
+ s.slope = slope;
+ s.origin = origin;
+ s.u = u;
+ s.v = v;
+ return s;
+ }
+
+ void init(point A, point B)
+ {
+ line l;
+ l.init(A, B);
+ this.A = l.A; this.B = l.B;
+ this.a = l.a; this.b = l.b; this.c = l.c;
+ this.slope = l.slope; this.origin = l.origin;
+ this.u = l.u; this.v = l.v;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="segment" signature="segment(point,point)"><code></asyxml>*/
+segment segment(point A, point B)
+{/*<asyxml></code><documentation>Return the segment whose the extremities are A and B.</documentation></function></asyxml>*/
+ segment s;
+ s.init(A, B);
+ return s;
+}
+
+/*<asyxml><function type="real" signature="length(segment)"><code></asyxml>*/
+real length(segment s)
+{/*<asyxml></code><documentation>Return the length of 's'.</documentation></function></asyxml>*/
+ return abs(s.A - s.B);
+}
+
+/*<asyxml><operator type = "line" signature="cast(segment)"><code></asyxml>*/
+line operator cast(segment s)
+{/*<asyxml></code><documentation>A segment is casted to a "finite line".</documentation></operator></asyxml>*/
+ return line(s.A, false, s.B, false);
+}
+
+/*<asyxml><operator type = "segment" signature="cast(line)"><code></asyxml>*/
+segment operator cast(line l)
+{/*<asyxml></code><documentation>Cast line 'l' to segment [l.A l.B].</documentation></operator></asyxml>*/
+ return segment(l.A, l.B);
+}
+
+/*<asyxml><operator type = "line" signature="*(transform,line)"><code></asyxml>*/
+line operator *(transform t, line l)
+{/*<asyxml></code><documentation>Provide transform * line</documentation></operator></asyxml>*/
+ return line(t * l.A, l.extendA, t * l.B, l.extendB);
+}
+/*<asyxml><operator type = "line" signature="/(line,real)"><code></asyxml>*/
+line operator /(line l, real x)
+{/*<asyxml></code><documentation>Provide l/x.
+ Return the line passing through l.A/x and l.B/x.</documentation></operator></asyxml>*/
+ return line(l.A/x, l.extendA, l.B/x, l.extendB);
+}
+line operator /(line l, int x){return line(l.A/x, l.B/x);}
+/*<asyxml><operator type = "line" signature="*(real,line)"><code></asyxml>*/
+line operator *(real x, line l)
+{/*<asyxml></code><documentation>Provide x * l.
+ Return the line passing through x * l.A and x * l.B.</documentation></operator></asyxml>*/
+ return line(x * l.A, l.extendA, x * l.B, l.extendB);
+}
+line operator *(int x, line l){return line(x * l.A, l.extendA, x * l.B, l.extendB);}
+
+/*<asyxml><operator type = "line" signature="*(point,line)"><code></asyxml>*/
+line operator *(point M, line l)
+{/*<asyxml></code><documentation>Provide point * line.
+ Return the line passing through unit(M) * l.A and unit(M) * l.B.</documentation></operator></asyxml>*/
+ return line(unit(M) * l.A, l.extendA, unit(M) * l.B, l.extendB);
+}
+/*<asyxml><operator type = "line" signature="+(line,point)"><code></asyxml>*/
+line operator +(line l, vector u)
+{/*<asyxml></code><documentation>Provide line + vector (and so line + point).
+ Return the line 'l' shifted by 'u'.</documentation></operator></asyxml>*/
+ return line(l.A + u, l.extendA, l.B + u, l.extendB);
+}
+/*<asyxml><operator type = "line" signature="-(line,vector)"><code></asyxml>*/
+line operator -(line l, vector u)
+{/*<asyxml></code><documentation>Provide line - vector (and so line - point).
+ Return the line 'l' shifted by '-u'.</documentation></operator></asyxml>*/
+ return line(l.A - u, l.extendA, l.B - u, l.extendB);
+}
+
+/*<asyxml><operator type = "line[]" signature="^^(line,line)"><code></asyxml>*/
+line[] operator ^^(line l1, line l2)
+{/*<asyxml></code><documentation>Provide line^^line.
+ Return the line array {l1, l2}.</documentation></operator></asyxml>*/
+ line[] ol;
+ ol.push(l1); ol.push(l2);
+ return ol;
+}
+
+/*<asyxml><operator type = "line[]" signature="^^(line,line[])"><code></asyxml>*/
+line[] operator ^^(line l1, line[] l2)
+{/*<asyxml></code><documentation>Provide line^^line[].
+ Return the line array {l1, l2[0], l2[1]...}.
+ line[]^^line is also defined.</documentation></operator></asyxml>*/
+ line[] ol;
+ ol.push(l1);
+ for (int i = 0; i < l2.length; ++i) {
+ ol.push(l2[i]);
+ }
+ return ol;
+}
+line[] operator ^^(line[] l2, line l1)
+{
+ line[] ol = l2;
+ ol.push(l1);
+ return ol;
+}
+
+/*<asyxml><operator type = "line[]" signature="^^(line,line[])"><code></asyxml>*/
+line[] operator ^^(line l1[], line[] l2)
+{/*<asyxml></code><documentation>Provide line[]^^line[].
+ Return the line array {l1[0], l1[1], ..., l2[0], l2[1], ...}.</documentation></operator></asyxml>*/
+ line[] ol = l1;
+ for (int i = 0; i < l2.length; ++i) {
+ ol.push(l2[i]);
+ }
+ return ol;
+}
+
+/*<asyxml><function type="bool" signature="sameside(point,point,line)"><code></asyxml>*/
+bool sameside(point M, point P, line l)
+{/*<asyxml></code><documentation>Return 'true' iff 'M' and 'N' are same side of the line (or on the line) 'l'.</documentation></function></asyxml>*/
+ pair A = l.A, B = l.B, m = M, p = P;
+ pair mil = (A + B)/2;
+ pair mA = rotate(90, mil) * A;
+ pair mB = rotate(-90, mil) * A;
+ return (abs(m - mA) <= abs(m - mB)) == (abs(p - mA) <= abs(p - mB));
+ // transform proj = projection(l.A, l.B);
+ // point Mp = proj * M;
+ // point Pp = proj * P;
+ // dot(Mp);dot(Pp);
+ // return dot(locate(Mp - M), locate(Pp - P)) >= 0;
+}
+
+/*<asyxml><function type="line" signature="line(segment)"><code></asyxml>*/
+line line(segment s)
+{/*<asyxml></code><documentation>Return the line passing through 's.A'
+ and 's.B'.</documentation></function></asyxml>*/
+ return line(s.A, s.B);
+}
+/*<asyxml><function type="segment" signature="segment(line)"><code></asyxml>*/
+segment segment(line l)
+{/*<asyxml></code><documentation>Return the segment whose extremities
+ are 'l.A' and 'l.B'.</documentation></function></asyxml>*/
+ return segment(l.A, l.B);
+}
+
+/*<asyxml><function type="point" signature="midpoint(segment)"><code></asyxml>*/
+point midpoint(segment s)
+{/*<asyxml></code><documentation>Return the midpoint of 's'.</documentation></function></asyxml>*/
+ return 0.5 * (s.A + s.B);
+}
+
+/*<asyxml><function type="void" signature="write(line)"><code></asyxml>*/
+void write(explicit line l)
+{/*<asyxml></code><documentation>Write some informations about 'l'.</documentation></function></asyxml>*/
+ write("A = "+(string)((pair)l.A));
+ write("Extend A = "+(l.extendA ? "true" : "false"));
+ write("B = "+(string)((pair)l.B));
+ write("Extend B = "+(l.extendB ? "true" : "false"));
+ write("u = "+(string)((pair)l.u));
+ write("v = "+(string)((pair)l.v));
+ write("a = "+(string) l.a);
+ write("b = "+(string) l.b);
+ write("c = "+(string) l.c);
+ write("slope = "+(string) l.slope);
+ write("origin = "+(string) l.origin);
+}
+
+/*<asyxml><function type="void" signature="write(explicit segment)"><code></asyxml>*/
+void write(explicit segment s)
+{/*<asyxml></code><documentation>Write some informations about 's'.</documentation></function></asyxml>*/
+ write("A = "+(string)((pair)s.A));
+ write("B = "+(string)((pair)s.B));
+ write("u = "+(string)((pair)s.u));
+ write("v = "+(string)((pair)s.v));
+ write("a = "+(string) s.a);
+ write("b = "+(string) s.b);
+ write("c = "+(string) s.c);
+ write("slope = "+(string) s.slope);
+ write("origin = "+(string) s.origin);
+}
+
+/*<asyxml><operator type = "bool" signature="==(line,line)"><code></asyxml>*/
+bool operator ==(line l1, line l2)
+{/*<asyxml></code><documentation>Provide the test 'line == line'.</documentation></operator></asyxml>*/
+ return (collinear(l1.u, l2.u) &&
+ abs(ypart((locate(l1.A) - locate(l1.B))/(locate(l1.A) - locate(l2.B)))) < epsgeo &&
+ l1.extendA == l2.extendA && l1.extendB == l2.extendB);
+}
+
+/*<asyxml><operator type = "bool" signature="!=(line,line)"><code></asyxml>*/
+bool operator !=(line l1, line l2)
+{/*<asyxml></code><documentation>Provide the test 'line != line'.</documentation></operator></asyxml>*/
+ return !(l1 == l2);
+}
+
+/*<asyxml><operator type = "bool" signature="@(point,line)"><code></asyxml>*/
+bool operator @(point m, line l)
+{/*<asyxml></code><documentation>Provide the test 'point @ line'.
+ Return true iff 'm' is on the 'l'.</documentation></operator></asyxml>*/
+ point M = changecoordsys(l.A.coordsys, m);
+ if (abs(l.a * M.x + l.b * M.y + l.c) >= epsgeo) return false;
+ if (l.extendA && l.extendB) return true;
+ if (!l.extendA && !l.extendB) return between(l.A, M, l.B);
+ if (l.extendA) return sameside(M, l.A, l.B);
+ return sameside(M, l.B, l.A);
+}
+
+/*<asyxml><function type="coordsys" signature="coordsys(line)"><code></asyxml>*/
+coordsys coordsys(line l)
+{/*<asyxml></code><documentation>Return the coordinate system in which 'l' is defined.</documentation></function></asyxml>*/
+ return l.A.coordsys;
+}
+
+/*<asyxml><function type="line" signature="reverse(line)"><code></asyxml>*/
+line reverse(line l)
+{/*<asyxml></code><documentation>Permute the points 'A' and 'B' of 'l' and so its orientation.</documentation></function></asyxml>*/
+ return line(l.B, l.extendB, l.A, l.extendA);
+}
+
+/*<asyxml><function type="line" signature="extend(line)"><code></asyxml>*/
+line extend(line l)
+{/*<asyxml></code><documentation>Return the infinite line passing through 'l.A' and 'l.B'.</documentation></function></asyxml>*/
+ line ol = l.copy();
+ ol.extendA = true;
+ ol.extendB = true;
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="complementary(explicit line)"><code></asyxml>*/
+line complementary(explicit line l)
+{/*<asyxml></code><documentation>Return the complementary of a half-line with respect of
+ the full line 'l'.</documentation></function></asyxml>*/
+ if (l.extendA && l.extendB)
+ abort("complementary: the parameter is not a half-line.");
+ point origin = l.extendA ? l.B : l.A;
+ point ptdir = l.extendA ?
+ rotate(180, l.B) * l.A : rotate(180, l.A) * l.B;
+ return line(origin, false, ptdir);
+}
+
+/*<asyxml><function type="line[]" signature="complementary(explicit segment)"><code></asyxml>*/
+line[] complementary(explicit segment s)
+{/*<asyxml></code><documentation>Return the two half-lines of origin 's.A' and 's.B' respectively.</documentation></function></asyxml>*/
+ line[] ol = new line[2];
+ ol[0] = complementary(line(s.A, false, s.B));
+ ol[1] = complementary(line(s.A, s.B, false));
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="Ox(coordsys)"><code></asyxml>*/
+line Ox(coordsys R = currentcoordsys)
+{/*<asyxml></code><documentation>Return the x-axis of 'R'.</documentation></function></asyxml>*/
+ return line(point(R, (0, 0)), point(R, E));
+}
+/*<asyxml><constant type = "line" signature="Ox"><code></asyxml>*/
+restricted line Ox = Ox();/*<asyxml></code><documentation>the x-axis of
+ the default coordinate system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="Oy(coordsys)"><code></asyxml>*/
+line Oy(coordsys R = currentcoordsys)
+{/*<asyxml></code><documentation>Return the y-axis of 'R'.</documentation></function></asyxml>*/
+ return line(point(R, (0, 0)), point(R, N));
+}
+/*<asyxml><constant type = "line" signature="Oy"><code></asyxml>*/
+restricted line Oy = Oy();/*<asyxml></code><documentation>the y-axis of
+ the default coordinate system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="line(real,point)"><code></asyxml>*/
+line line(real a, point A = point(currentcoordsys, (0, 0)))
+{/*<asyxml></code><documentation>Return the line passing through 'A' with an
+ angle (in the coordinate system of A) 'a' in degrees.
+ line(point, real) is also defined.</documentation></function></asyxml>*/
+ return line(A, A + point(A.coordsys, A.coordsys.polar(1, radians(a))));
+}
+line line(point A = point(currentcoordsys, (0, 0)), real a)
+{
+ return line(a, A);
+}
+line line(int a, point A = point(currentcoordsys, (0, 0)))
+{
+ return line((real)a, A);
+}
+
+/*<asyxml><function type="line" signature="line(coordsys,real,real)"><code></asyxml>*/
+line line(coordsys R = currentcoordsys, real slope, real origin)
+{/*<asyxml></code><documentation>Return the line defined by slope and y-intercept relative to 'R'.</documentation></function></asyxml>*/
+ if (slope == infinity || slope == -infinity)
+ abort("The slope is infinite. Please, use the routine 'vline'.");
+ return line(point(R, (0, origin)), point(R, (1, origin + slope)));
+}
+
+/*<asyxml><function type="line" signature="line(coordsys,real,real,real)"><code></asyxml>*/
+line line(coordsys R = currentcoordsys, real a, real b, real c)
+{/*<asyxml></code><documentation>Retrun the line defined by equation relative to 'R'.</documentation></function></asyxml>*/
+ if (a == 0 && b == 0) abort("line: inconsistent equation...");
+ pair M;
+ M = (a == 0) ? (0, -c/b) : (-c/a, 0);
+ return line(point(R, M), point(R, M + (-b, a)));
+}
+
+/*<asyxml><function type="line" signature="vline(coordsys)"><code></asyxml>*/
+line vline(coordsys R = currentcoordsys)
+{/*<asyxml></code><documentation>Return a vertical line in 'R' passing through the origin of 'R'.</documentation></function></asyxml>*/
+ point P = point(R, (0, 0));
+ point PP = point(R, (R.O + N)/R);
+ return line(P, PP);
+}
+/*<asyxml><constant type = "line" signature="vline"><code></asyxml>*/
+restricted line vline = vline();/*<asyxml></code><documentation>The vertical line in the current coordinate system passing
+ through the origin of this system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="hline(coordsys)"><code></asyxml>*/
+line hline(coordsys R = currentcoordsys)
+{/*<asyxml></code><documentation>Return a horizontal line in 'R' passing through the origin of 'R'.</documentation></function></asyxml>*/
+ point P = point(R, (0, 0));
+ point PP = point(R, (R.O + E)/R);
+ return line(P, PP);
+}
+/*<asyxml><constant type = "line" signature="hline"><code></asyxml>*/
+line hline = hline();/*<asyxml></code><documentation>The horizontal line in the current coordinate system passing
+ through the origin of this system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="changecoordsys(coordsys,line)"><code></asyxml>*/
+line changecoordsys(coordsys R, line l)
+{/*<asyxml></code><documentation>Return the line 'l' in the coordinate system 'R'.</documentation></function></asyxml>*/
+ point A = changecoordsys(R, l.A);
+ point B = changecoordsys(R, l.B);
+ return line(A, B);
+}
+
+/*<asyxml><function type="transform" signature="scale(real,line,line,bool)"><code></asyxml>*/
+transform scale(real k, line l1, line l2, bool safe = false)
+{/*<asyxml></code><documentation>Return the dilatation with respect to
+ 'l1' in the direction of 'l2'.</documentation></function></asyxml>*/
+ return scale(k, l1.A, l1.B, l2.A, l2.B, safe);
+}
+
+/*<asyxml><function type="transform" signature="reflect(line)"><code></asyxml>*/
+transform reflect(line l)
+{/*<asyxml></code><documentation>Return the reflect about the line 'l'.</documentation></function></asyxml>*/
+ return reflect((pair)l.A, (pair)l.B);
+}
+
+/*<asyxml><function type="transform" signature="reflect(line,line)"><code></asyxml>*/
+transform reflect(line l1, line l2, bool safe = false)
+{/*<asyxml></code><documentation>Return the reflect about the line
+ 'l1' in the direction of 'l2'.</documentation></function></asyxml>*/
+ return scale(-1.0, l1, l2, safe);
+}
+
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,path)"><code></asyxml>*/
+point[] intersectionpoints(line l, path g)
+{/*<asyxml></code><documentation>Return all points of intersection of the line 'l' with the path 'g'.</documentation></function></asyxml>*/
+ // TODO utiliser la version 1.44 de intersections(path g, pair p, pair q)
+ // real [] t = intersections(g, l.A, l.B);
+ // coordsys R = coordsys(l);
+ // return sequence(new point(int n){return point(R, point(g, t[n])/R);}, t.length);
+ real [] t;
+ pair[] op;
+ pair A = l.A;
+ pair B = l.B;
+ real dy = B.y - A.y,
+ dx = A.x - B.x,
+ lg = length(g);
+
+ for (int i = 0; i < lg; ++i)
+ {
+ pair z0 = point(g, i),
+ z1 = point(g, i + 1),
+ c0 = postcontrol(g, i),
+ c1 = precontrol(g, i + 1),
+ t3 = z1 - z0 - 3 * c1 + 3 * c0,
+ t2 = 3 * z0 + 3 * c1 - 6 * c0,
+ t1 = 3 * c0 - 3z0;
+ real a = dy * t3.x + dx * t3.y,
+ b = dy * t2.x + dx * t2.y,
+ c = dy * t1.x + dx * t1.y,
+ d = dy * z0.x + dx * z0.y + A.y * B.x - A.x * B.y;
+
+ t = cubicroots(a, b, c, d);
+ for (int j = 0; j < t.length; ++j)
+ if (
+ t[j]>=0
+ && (
+ t[j]<1
+ || (
+ t[j] == 1
+ && (i == lg - 1)
+ && !cyclic(g)
+ )
+ )
+ ) {
+ op.push(point(g, i + t[j]));
+ }
+ }
+
+ point[] opp;
+ for (int i = 0; i < op.length; ++i)
+ opp.push(point(coordsys(l), op[i]/coordsys(l)));
+ return opp;
+}
+
+/*<asyxml><function type="point" signature="intersectionpoint(line,line)"><code></asyxml>*/
+point intersectionpoint(line l1, line l2)
+{/*<asyxml></code><documentation>Return the point of intersection of line 'l1' with 'l2'.
+ If 'l1' and 'l2' have an infinity or none point of intersection,
+ this routine return (infinity, infinity).</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(l1.A, l1.B, l2.A, l2.B);
+ coordsys R = P[0].coordsys;
+ pair p = extension(P[0], P[1], P[2], P[3]);
+ if(finite(p)){
+ point p = point(R, p/R);
+ if (p @ l1 && p @ l2) return p;
+ }
+ return point(R, (infinity, infinity));
+}
+
+/*<asyxml><function type="line" signature="parallel(point,line)"><code></asyxml>*/
+line parallel(point M, line l)
+{/*<asyxml></code><documentation>Return the line parallel to 'l' passing through 'M'.</documentation></function></asyxml>*/
+ point A, B;
+ if (M.coordsys != coordsys(l))
+ {
+ A = changecoordsys(M.coordsys, l.A);
+ B = changecoordsys(M.coordsys, l.B);
+ } else {A = l.A;B = l.B;}
+ return line(M, M - A + B);
+}
+
+/*<asyxml><function type="line" signature="parallel(point,explicit vector)"><code></asyxml>*/
+line parallel(point M, explicit vector dir)
+{/*<asyxml></code><documentation>Return the line of direction 'dir' and passing through 'M'.</documentation></function></asyxml>*/
+ return line(M, M + locate(dir));
+}
+
+/*<asyxml><function type="line" signature="parallel(point,explicit pair)"><code></asyxml>*/
+line parallel(point M, explicit pair dir)
+{/*<asyxml></code><documentation>Return the line of direction 'dir' and passing through 'M'.</documentation></function></asyxml>*/
+ return line(M, M + vector(currentcoordsys, dir));
+}
+
+/*<asyxml><function type="bool" signature="parallel(line,line)"><code></asyxml>*/
+bool parallel(line l1, line l2, bool strictly = false)
+{/*<asyxml></code><documentation>Return 'true' if 'l1' and 'l2' are (strictly ?) parallel.</documentation></function></asyxml>*/
+ bool coll = collinear(l1.u, l2.u);
+ return strictly ? coll && (l1 != l2) : coll;
+}
+
+/*<asyxml><function type="bool" signature="concurrent(...line[])"><code></asyxml>*/
+bool concurrent(... line[] l)
+{/*<asyxml></code><documentation>Returns true if all the lines 'l' are concurrent.</documentation></function></asyxml>*/
+ if (l.length < 3) abort("'concurrent' needs at least for three lines ...");
+ pair point = intersectionpoint(l[0], l[1]);
+ bool conc;
+ for (int i = 2; i < l.length; ++i) {
+ pair pt = intersectionpoint(l[i - 1], l[i]);
+ conc = simeq(pt, point);
+ if (!conc) break;
+ }
+ return conc;
+}
+
+/*<asyxml><function type="transform" signature="projection(line)"><code></asyxml>*/
+transform projection(line l)
+{/*<asyxml></code><documentation>Return the orthogonal projection on 'l'.</documentation></function></asyxml>*/
+ return projection(l.A, l.B);
+}
+
+/*<asyxml><function type="transform" signature="projection(line,line,bool)"><code></asyxml>*/
+transform projection(line l1, line l2, bool safe = false)
+{/*<asyxml></code><documentation>Return the projection on (AB) in parallel of (CD).
+ If 'safe = true' and (l1)//(l2) return the identity.
+ If 'safe = false' and (l1)//(l2) return a infinity scaling.</documentation></function></asyxml>*/
+ return projection(l1.A, l1.B, l2.A, l2.B, safe);
+}
+
+/*<asyxml><function type="transform" signature="vprojection(line,bool)"><code></asyxml>*/
+transform vprojection(line l, bool safe = false)
+{/*<asyxml></code><documentation>Return the projection on 'l' in parallel of N--S.
+ If 'safe' is 'true' the projected point keeps the same place if 'l'
+ is vertical.</documentation></function></asyxml>*/
+ coordsys R = defaultcoordsys;
+ return projection(l, line(point(R, N), point(R, S)), safe);
+}
+
+/*<asyxml><function type="transform" signature="hprojection(line,bool)"><code></asyxml>*/
+transform hprojection(line l, bool safe = false)
+{/*<asyxml></code><documentation>Return the projection on 'l' in parallel of E--W.
+ If 'safe' is 'true' the projected point keeps the same place if 'l'
+ is horizontal.</documentation></function></asyxml>*/
+ coordsys R = defaultcoordsys;
+ return projection(l, line(point(R, E), point(R, W)), safe);
+}
+
+/*<asyxml><function type="line" signature="perpendicular(point,line)"><code></asyxml>*/
+line perpendicular(point M, line l)
+{/*<asyxml></code><documentation>Return the perpendicular line of 'l' passing through 'M'.</documentation></function></asyxml>*/
+ point Mp = projection(l) * M;
+ point A = Mp == l.A ? l.B : l.A;
+ return line(Mp, rotate(90, Mp) * A);
+}
+
+/*<asyxml><function type="line" signature="perpendicular(point,explicit vector)"><code></asyxml>*/
+line perpendicular(point M, explicit vector normal)
+{/*<asyxml></code><documentation>Return the line passing through 'M'
+ whose normal is \param{normal}.</documentation></function></asyxml>*/
+ return perpendicular(M, line(M, M + locate(normal)));
+}
+
+/*<asyxml><function type="line" signature="perpendicular(point,explicit pair)"><code></asyxml>*/
+line perpendicular(point M, explicit pair normal)
+{/*<asyxml></code><documentation>Return the line passing through 'M'
+ whose normal is \param{normal} (given in the currentcoordsys).</documentation></function></asyxml>*/
+ return perpendicular(M, line(M, M + vector(currentcoordsys, normal)));
+}
+
+/*<asyxml><function type="bool" signature="perpendicular(line,line)"><code></asyxml>*/
+bool perpendicular(line l1, line l2)
+{/*<asyxml></code><documentation>Return 'true' if 'l1' and 'l2' are perpendicular.</documentation></function></asyxml>*/
+ return abs(dot(locate(l1.u), locate(l2.u))) < epsgeo ;
+}
+
+/*<asyxml><function type="real" signature="angle(line,coordsys)"><code></asyxml>*/
+real angle(line l, coordsys R = coordsys(l))
+{/*<asyxml></code><documentation>Return the angle of the oriented line 'l',
+ in radian, in the interval ]-pi, pi] and relatively to 'R'.</documentation></function></asyxml>*/
+ return angle(l.u, R, false);
+}
+
+/*<asyxml><function type="real" signature="degrees(line,coordsys,bool)"><code></asyxml>*/
+real degrees(line l, coordsys R = coordsys(l))
+{/*<asyxml></code><documentation>Returns the angle of the oriented line 'l' in degrees,
+ in the interval [0, 360[ and relatively to 'R'.</documentation></function></asyxml>*/
+ return degrees(angle(l, R));
+}
+
+/*<asyxml><function type="real" signature="sharpangle(line,line)"><code></asyxml>*/
+real sharpangle(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in radians of the sharp angle formed by 'l1' and 'l2'.</documentation></function></asyxml>*/
+ vector u1 = l1.u;
+ vector u2 = (dot(l1.u, l2.u) < 0) ? -l2.u : l2.u;
+ real a12 = angle(locate(u2)) - angle(locate(u1));
+ a12 = a12%(sgnd(a12) * pi);
+ if (a12 <= -pi/2) {
+ a12 += pi;
+ } else if (a12 > pi/2) {
+ a12 -= pi;
+ }
+ return a12;
+}
+
+/*<asyxml><function type="real" signature="angle(line,line)"><code></asyxml>*/
+real angle(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in radians of oriented angle (l1.u, l2.u).</documentation></function></asyxml>*/
+ return angle(locate(l2.u)) - angle(locate(l1.u));
+}
+
+/*<asyxml><function type="real" signature="degrees(line,line)"><code></asyxml>*/
+real degrees(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in degrees of the
+ angle formed by the oriented lines 'l1' and 'l2'.</documentation></function></asyxml>*/
+ return degrees(angle(l1, l2));
+}
+
+/*<asyxml><function type="real" signature="sharpdegrees(line,line)"><code></asyxml>*/
+real sharpdegrees(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in degrees of the sharp angle formed by 'l1' and 'l2'.</documentation></function></asyxml>*/
+ return degrees(sharpangle(l1, l2));
+}
+
+/*<asyxml><function type="line" signature="bisector(line,line,real,bool)"><code></asyxml>*/
+line bisector(line l1, line l2, real angle = 0, bool sharp = true)
+{/*<asyxml></code><documentation>Return the bisector of the angle formed by 'l1' and 'l2'
+ rotated by the angle 'angle' (in degrees) around intersection point of 'l1' with 'l2'.
+ If 'sharp' is true (the default), this routine returns the bisector of the sharp angle.
+ Note that the returned line inherit of coordinate system of 'l1'.</documentation></function></asyxml>*/
+ line ol;
+ if (l1 == l2) return l1;
+ point A = intersectionpoint(l1, l2);
+ if (finite(A)) {
+ if(sharp) ol = rotate(sharpdegrees(l1, l2)/2 + angle, A) * l1;
+ else {
+ coordsys R = coordsys(l1);
+ pair a = A, b = A + l1.u, c = A + l2.u;
+ pair pp = extension(a, a + dir(a--b, a--c), b, b + dir(b--a, b--c));
+ return rotate(angle, A) * line(A, point(R, pp/R));
+ }
+ } else {
+ ol = l1;
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="sector(int,int,line,line,real,bool)"><code></asyxml>*/
+line sector(int n = 2, int p = 1, line l1, line l2, real angle = 0, bool sharp = true)
+{/*<asyxml></code><documentation>Return the p-th nth-sector of the angle
+ formed by the oriented line 'l1' and 'l2'
+ rotated by the angle 'angle' (in degrees) around the intersection point of 'l1' with 'l2'.
+ If 'sharp' is true (the default), this routine returns the bisector of the sharp angle.
+ Note that the returned line inherit of coordinate system of 'l1'.</documentation></function></asyxml>*/
+ line ol;
+ if (l1 == l2) return l1;
+ point A = intersectionpoint(l1, l2);
+ if (finite(A)) {
+ if(sharp) ol = rotate(p * sharpdegrees(l1, l2)/n + angle, A) * l1;
+ else {
+ ol = rotate(p * degrees(l1, l2)/n + angle, A) * l1;
+ }
+ } else {
+ ol = l1;
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="bisector(point,point,point,point,real)"><code></asyxml>*/
+line bisector(point A, point B, point C, point D, real angle = 0, bool sharp = true)
+{/*<asyxml></code><documentation>Return the bisector of the angle formed by the lines (AB) and (CD).
+ <look href = "#bisector(line, line, real, bool)"/>.</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A, B, C, D);
+ return bisector(line(P[0], P[1]), line(P[2], P[3]), angle, sharp);
+}
+
+/*<asyxml><function type="line" signature="bisector(segment,real)"><code></asyxml>*/
+line bisector(segment s, real angle = 0)
+{/*<asyxml></code><documentation>Return the bisector of the segment line 's' rotated by 'angle' (in degrees) around the
+ midpoint of 's'.</documentation></function></asyxml>*/
+ coordsys R = coordsys(s);
+ point m = midpoint(s);
+ vector dir = rotateO(90) * unit(s.A - m);
+ return rotate(angle, m) * line(m + dir, m - dir);
+}
+
+/*<asyxml><function type="line" signature="bisector(point,point,real)"><code></asyxml>*/
+line bisector(point A, point B, real angle = 0)
+{/*<asyxml></code><documentation>Return the bisector of the segment line [AB] rotated by 'angle' (in degrees) around the
+ midpoint of [AB].</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A, B);
+ return bisector(segment(P[0], P[1]), angle);
+}
+
+/*<asyxml><function type="real" signature="distance(point,line)"><code></asyxml>*/
+real distance(point M, line l)
+{/*<asyxml></code><documentation>Return the distance from 'M' to 'l'.
+ distance(line, point) is also defined.</documentation></function></asyxml>*/
+ point A = changecoordsys(defaultcoordsys, l.A);
+ point B = changecoordsys(defaultcoordsys, l.B);
+ line ll = line(A, B);
+ pair m = locate(M);
+ return abs(ll.a * m.x + ll.b * m.y + ll.c)/sqrt(ll.a^2 + ll.b^2);
+}
+
+real distance(line l, point M)
+{
+ return distance(M, l);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,line,bool,bool,align,pen,arrowbar,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label L = "",
+ line l, bool dirA = l.extendA, bool dirB = l.extendB,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None,
+ Label legend = "", marker marker = nomarker,
+ pathModifier pathModifier = NoModifier)
+{/*<asyxml></code><documentation>Draw the line 'l' without altering the size of picture pic.
+ The boolean parameters control the infinite section.
+ The global variable 'linemargin' (default value is 0) allows to modify
+ the bounding box in which the line must be drawn.</documentation></function></asyxml>*/
+ if(!(dirA || dirB)) draw(l.A--l.B, invisible);// l is a segment.
+ Drawline(pic, L, l.A, dirP = dirA, l.B, dirQ = dirB,
+ align, p, arrow,
+ legend, marker, pathModifier);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label[], line[], align,pen[], arrowbar,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label[] L = new Label[], line[] l,
+ align align = NoAlign, pen[] p = new pen[],
+ arrowbar arrow = None,
+ Label[] legend = new Label[], marker marker = nomarker,
+ pathModifier pathModifier = NoModifier)
+{/*<asyxml></code><documentation>Draw each lines with the corresponding pen.</documentation></function></asyxml>*/
+ for (int i = 0; i < l.length; ++i) {
+ draw(pic, L.length>0 ? L[i] : "", l[i],
+ align, p = p.length>0 ? p[i] : currentpen,
+ arrow, legend.length>0 ? legend[i] : "", marker,
+ pathModifier);
+ }
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label[], line[], align,pen,arrowbar,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label[] L = new Label[], line[] l,
+ align align = NoAlign, pen p,
+ arrowbar arrow = None,
+ Label[] legend = new Label[], marker marker = nomarker,
+ pathModifier pathModifier = NoModifier)
+{/*<asyxml></code><documentation>Draw each lines with the same pen 'p'.</documentation></function></asyxml>*/
+ pen[] tp = sequence(new pen(int i){return p;}, l.length);
+ draw(pic, L, l, align, tp, arrow, legend, marker, pathModifier);
+}
+
+/*<asyxml><function type="void" signature="show(picture,line,pen)"><code></asyxml>*/
+void show(picture pic = currentpicture, line l, pen p = red)
+{/*<asyxml></code><documentation>Draw some informations of 'l'.</documentation></function></asyxml>*/
+ dot("$A$", (pair)l.A, align = -locate(l.v), p);
+ dot("$B$", (pair)l.B, align = -locate(l.v), p);
+ draw(l, dotted);
+ draw("$\vec{u}$", locate(l.A)--locate(l.A + l.u), p, Arrow);
+ draw("$\vec{v}$", locate(l.A)--locate(l.A + l.v), p, Arrow);
+}
+
+/*<asyxml><function type="point[]" signature="sameside(point,line,line)"><code></asyxml>*/
+point[] sameside(point M, line l1, line l2)
+{/*<asyxml></code><documentation>Return two points on 'l1' and 'l2' respectively.
+ The first point is from the same side of M relatively to 'l2',
+ the second point is from the same side of M relatively to 'l1'.</documentation></function></asyxml>*/
+ point[] op;
+ coordsys R1 = coordsys(l1);
+ coordsys R2 = coordsys(l2);
+ if (parallel(l1, l2)) {
+ op.push(projection(l1) * M);
+ op.push(projection(l2) * M);
+ } else {
+ point O = intersectionpoint(l1, l2);
+ if (M @ l2) op.push((sameside(M, O + l1.u, l2)) ? O + l1.u : rotate(180, O) * (O + l1.u));
+ else op.push(projection(l1, l2) * M);
+ if (M @ l1) op.push((sameside(M, O + l2.u, l1)) ? O + l2.u : rotate(180, O) * (O + l2.u));
+ else {op.push(projection(l2, l1) * M);}
+ }
+ return op;
+}
+
+/*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,explicit line,explicit line,explicit pair,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/
+void markangle(picture pic = currentpicture,
+ Label L = "", int n = 1, real radius = 0, real space = 0,
+ explicit line l1, explicit line l2, explicit pair align = dir(1),
+ arrowbar arrow = None, pen p = currentpen,
+ filltype filltype = NoFill,
+ margin margin = NoMargin, marker marker = nomarker)
+{/*<asyxml></code><documentation>Mark the angle (l1, l2) aligned in the direction 'align' relative to 'l1'.
+ Commune values for 'align' are dir(real).</documentation></function></asyxml>*/
+ if (parallel(l1, l2, true)) return;
+ real al = degrees(l1, defaultcoordsys);
+ pair O, A, B;
+ if (radius == 0) radius = markangleradius(p);
+ real d = degrees(locate(l1.u));
+ align = rotate(d) * align;
+ if (l1 == l2) {
+ O = midpoint(segment(l1.A, l1.B));
+ A = l1.A;B = l1.B;
+ if (sameside(rotate(sgn(angle(B-A)) * 45, O) * A, O + align, l1)) {radius = -radius;}
+ } else {
+ O = intersectionpoint(extend(l1), extend(l2));
+ pair R = O + align;
+ point [] ss = sameside(point(coordsys(l1), R/coordsys(l1)), l1, l2);
+ A = ss[0];
+ B = ss[1];
+ }
+ markangle(pic = pic, L = L, n = n, radius = radius, space = space,
+ O = O, A = A, B = B,
+ arrow = arrow, p = p, filltype = filltype,
+ margin = margin, marker = marker);
+}
+
+/*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,explicit line,explicit line,explicit vector,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/
+void markangle(picture pic = currentpicture,
+ Label L = "", int n = 1, real radius = 0, real space = 0,
+ explicit line l1, explicit line l2, explicit vector align,
+ arrowbar arrow = None, pen p = currentpen,
+ filltype filltype = NoFill,
+ margin margin = NoMargin, marker marker = nomarker)
+{/*<asyxml></code><documentation>Mark the angle (l1, l2) in the direction 'dir' given relatively to 'l1'.</documentation></function></asyxml>*/
+ markangle(pic, L, n, radius, space, l1, l2, (pair)align, arrow,
+ p, filltype, margin, marker);
+}
+
+/*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,line,line,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/
+// void markangle(picture pic = currentpicture,
+// Label L = "", int n = 1, real radius = 0, real space = 0,
+// explicit line l1, explicit line l2,
+// arrowbar arrow = None, pen p = currentpen,
+// filltype filltype = NoFill,
+// margin margin = NoMargin, marker marker = nomarker)
+// {/*<asyxml></code><documentation>Mark the oriented angle (l1, l2).</documentation></function></asyxml>*/
+// if (parallel(l1, l2, true)) return;
+// real al = degrees(l1, defaultcoordsys);
+// pair O, A, B;
+// if (radius == 0) radius = markangleradius(p);
+// real d = degrees(locate(l1.u));
+// if (l1 == l2) {
+// O = midpoint(segment(l1.A, l1.B));
+// } else {
+// O = intersectionpoint(extend(l1), extend(l2));
+// }
+// A = O + locate(l1.u);
+// B = O + locate(l2.u);
+// markangle(pic = pic, L = L, n = n, radius = radius, space = space,
+// O = O, A = A, B = B,
+// arrow = arrow, p = p, filltype = filltype,
+// margin = margin, marker = marker);
+// }
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,line,line,real,pen,int,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic = currentpicture, line l1, line l2,
+ real size = 0, pen p = currentpen, int quarter = 1,
+ margin margin = NoMargin, filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw a right angle at the intersection point of lines and
+ aligned in the 'quarter' nth quarter of circle formed by 'l1.u' and
+ 'l2.u'.</documentation></function></asyxml>*/
+ point P = intersectionpoint(l1, l2);
+ pair align = rotate(90 * (quarter - 1)) * dir(45);
+ perpendicularmark(P, align, locate(l1.u), size, p, margin, filltype);
+}
+// *.........................LINES.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *........................CONICS.........................*
+/*<asyxml><struct signature="bqe"><code></asyxml>*/
+struct bqe
+{/*<asyxml></code><documentation>Bivariate Quadratic Equation.</documentation></asyxml>*/
+ /*<asyxml><property type = "real[]" signature="a"><code></asyxml>*/
+ real[] a;/*<asyxml></code><documentation>a[0] * x^2 + a[1] * x * y + a[2] * y^2 + a[3] * x + a[4] * y + a[5] = 0</documentation></property><property type = "coordsys" signature="coordsys"><code></asyxml>*/
+ coordsys coordsys;/*<asyxml></code></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="bqe" signature="bqe(coordsys,real,real,real,real,real,real)"><code></asyxml>*/
+bqe bqe(coordsys R = currentcoordsys,
+ real a, real b, real c, real d, real e, real f)
+{/*<asyxml></code><documentation>Return the bivariate quadratic equation
+ a[0] * x^2 + a[1] * x * y + a[2] * y^2 + a[3] * x + a[4] * y + a[5] = 0
+ relatively to the coordinate system R.</documentation></function></asyxml>*/
+ bqe obqe;
+ obqe.coordsys = R;
+ obqe.a = new real[] {a, b, c, d, e, f};
+ return obqe;
+}
+
+/*<asyxml><function type="bqe" signature="changecoordsys(coordsys,bqe)"><code></asyxml>*/
+bqe changecoordsys(coordsys R, bqe bqe)
+{/*<asyxml></code><documentation>Returns the bivariate quadratic equation relatively to 'R'.</documentation></function></asyxml>*/
+ pair i = coordinates(changecoordsys(R, vector(defaultcoordsys,
+ bqe.coordsys.i)));
+ pair j = coordinates(changecoordsys(R, vector(defaultcoordsys,
+ bqe.coordsys.j)));
+ pair O = coordinates(changecoordsys(R, point(defaultcoordsys,
+ bqe.coordsys.O)));
+ real a = bqe.a[0], b = bqe.a[1], c = bqe.a[2], d = bqe.a[3], f = bqe.a[4], g = bqe.a[5];
+ real ux = i.x, uy = i.y;
+ real vx = j.x, vy = j.y;
+ real ox = O.x, oy = O.y;
+ real D = ux * vy - uy * vx;
+ real ap = (a * vy^2 - b * uy * vy + c * uy^2)/D^2;
+ real bpp = (-2 * a * vx * vy + b * ux * vy + b * uy * vx - 2 * c * ux * uy)/D^2;
+ real cp = (a * vx^2 - b * ux * vx + c * ux^2)/D^2;
+ real dp = (-2a * ox * vy^2 + 2a * oy * vx * vy + 2b * ox * uy * vy-
+ b * oy * ux * vy - b * oy * uy * vx - 2c * ox * uy^2 + 2c * oy * uy * ux)/D^2+
+ (d * vy - f * uy)/D;
+ real fp = (2a * ox * vx * vy - b * ox * ux * vy - 2a * oy * vx^2-
+ b * ox * uy * vx + 2 * b * oy * ux * vx + 2c * ox * ux * uy - 2c * oy * ux^2)/D^2+
+ (f * ux - d * vx)/D;
+ g = (a * ox^2 * vy^2 - 2a * ox * oy * vx * vy - b * ox^2 * uy * vy + b * ox * oy * ux * vy+
+ a * oy^2 * vx^2 + b * ox * oy * uy * vx - b * oy^2 * ux * vx + c * ox^2 * uy^2-
+ 2 * c * ox * oy * ux * uy + c * oy^2 * ux^2)/D^2+
+ (d * oy * vx + f * ox * uy - d * ox * vy - f * oy * ux)/D + g;
+ bqe obqe;
+ obqe.a = approximate(new real[] {ap, bpp, cp, dp, fp, g});
+ obqe.coordsys = R;
+ return obqe;
+}
+
+/*<asyxml><function type="bqe" signature="bqe(point,point,point,point,point)"><code></asyxml>*/
+bqe bqe(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the bqe of conic passing through the five points (if possible).</documentation></function></asyxml>*/
+ coordsys R;
+ pair[] pts;
+ if (samecoordsys(M1, M2, M3, M4, M5)) {
+ R = M1.coordsys;
+ pts= new pair[] {M1.coordinates, M2.coordinates, M3.coordinates, M4.coordinates, M5.coordinates};
+ } else {
+ R = defaultcoordsys;
+ pts= new pair[] {M1, M2, M3, M4, M5};
+ }
+ real[][] M;
+ real[] x;
+ bqe bqe;
+ bqe.coordsys = R;
+ for (int i = 0; i < 5; ++i) {// Try a = -1
+ M[i] = new real[] {pts[i].x * pts[i].y, pts[i].y^2, pts[i].x, pts[i].y, 1};
+ x[i] = pts[i].x^2;
+ }
+ if(abs(determinant(M)) < 1e-5) {// Try c = -1
+ for (int i = 0; i < 5; ++i) {
+ M[i] = new real[] {pts[i].x^2, pts[i].x * pts[i].y, pts[i].x, pts[i].y, 1};
+ x[i] = pts[i].y^2;
+ }
+ real[] coef = solve(M, x);
+ bqe.a = new real[] {coef[0], coef[1], -1, coef[2], coef[3], coef[4]};
+ } else {
+ real[] coef = solve(M, x);
+ bqe.a = new real[] {-1, coef[0], coef[1], coef[2], coef[3], coef[4]};
+ }
+ bqe.a = approximate(bqe.a);
+ return bqe;
+}
+
+/*<asyxml><function type="bool" signature="samecoordsys(bool...bqe[])"><code></asyxml>*/
+bool samecoordsys(bool warn = true ... bqe[] bqes)
+{/*<asyxml></code><documentation>Return true if all the bivariate quadratic equations have the same coordinate system.</documentation></function></asyxml>*/
+ bool ret = true;
+ coordsys t = bqes[0].coordsys;
+ for (int i = 1; i < bqes.length; ++i) {
+ ret = (t == bqes[i].coordsys);
+ if(!ret) break;
+ t = bqes[i].coordsys;
+ }
+ if(warn && !ret)
+ warning("coodinatesystem",
+ "the coordinate system of two bivariate quadratic equations are not
+the same. The operation will be done relatively to the default coordinate
+system.");
+ return ret;
+}
+
+/*<asyxml><function type="real[]" signature="realquarticroots(real,real,real,real,real)"><code></asyxml>*/
+real[] realquarticroots(real a, real b, real c, real d, real e)
+{/*<asyxml></code><documentation>Return the real roots of the quartic equation ax^4 + b^x3 + cx^2 + dx = 0.</documentation></function></asyxml>*/
+ static real Fuzz = sqrt(realEpsilon);
+ pair[] zroots = quarticroots(a, b, c, d, e);
+ real[] roots;
+ real p(real x){return a * x^4 + b * x^3 + c * x^2 + d * x + e;}
+ real prime(real x){return 4 * a * x^3 + 3 * b * x^2 + 2 * c * x + d;}
+ real x;
+ bool search = true;
+ int n;
+ void addroot(real x)
+ {
+ bool exist = false;
+ for (int i = 0; i < roots.length; ++i) {
+ if(abs(roots[i]-x) < 1e-5) {exist = true; break;}
+ }
+ if(!exist) roots.push(x);
+ }
+ for(int i = 0; i < zroots.length; ++i) {
+ if(zroots[i].y == 0 || abs(p(zroots[i].x)) < Fuzz) addroot(zroots[i].x);
+ else {
+ if(abs(zroots[i].y) < 1e-3) {
+ x = zroots[i].x;
+ search = true;
+ n = 200;
+ while(search) {
+ real tx = abs(p(x)) < Fuzz ? x : newton(iterations = n, p, prime, x);
+ if(tx < realMax) {
+ if(abs(p(tx)) < Fuzz) {
+ addroot(tx);
+ search = false;
+ } else if(n < 200) n *=2;
+ else {
+ search = false;
+ }
+ } else search = false; //It's not a real root.
+ }
+ }
+ }
+ }
+ return roots;
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(bqe,bqe)"><code></asyxml>*/
+point[] intersectionpoints(bqe bqe1, bqe bqe2)
+{/*<asyxml></code><documentation>Return the interscetion of the two conic sections whose equations are 'bqe1' and 'bqe2'.</documentation></function></asyxml>*/
+ coordsys R = bqe1.coordsys;
+ bqe lbqe1, lbqe2;
+ real[] a, b;
+ if(R != bqe2.coordsys) {
+ R = currentcoordsys;
+ a = changecoordsys(R, bqe1).a;
+ b = changecoordsys(R, bqe2).a;
+ } else {
+ a = bqe1.a;
+ b = bqe2.a;
+ }
+ static real e = 100 * sqrt(realEpsilon);
+ real[] x, y, c;
+ point[] P;
+ if(abs(a[0]-b[0]) > e || abs(a[1]-b[1]) > e || abs(a[2]-b[2]) > e) {
+ c = new real[] {-2 * a[0]*a[2]*b[0]*b[2]+a[0]*a[2]*b[1]^2 - a[0]*a[1]*b[2]*b[1]+a[1]^2 * b[0]*b[2]-
+ a[2]*a[1]*b[0]*b[1]+a[0]^2 * b[2]^2 + a[2]^2 * b[0]^2,
+ -a[2]*a[1]*b[0]*b[4]-a[2]*a[4]*b[0]*b[1]-a[1]*a[3]*b[2]*b[1]+2 * a[0]*a[2]*b[1]*b[4]-
+ a[0]*a[1]*b[2]*b[4]+a[1]^2 * b[2]*b[3]-2 * a[2]*a[3]*b[0]*b[2]-2 * a[0]*a[2]*b[2]*b[3]+
+ a[2]*a[3]*b[1]^2 - a[2]*a[1]*b[1]*b[3]+2 * a[1]*a[4]*b[0]*b[2]+2 * a[2]^2 * b[0]*b[3]-
+ a[0]*a[4]*b[2]*b[1]+2 * a[0]*a[3]*b[2]^2,
+ -a[3]*a[4]*b[2]*b[1]+a[2]*a[5]*b[1]^2 - a[1]*a[5]*b[2]*b[1]-a[1]*a[3]*b[2]*b[4]+
+ a[1]^2 * b[2]*b[5]-2 * a[2]*a[3]*b[2]*b[3]+2 * a[2]^2 * b[0]*b[5]+2 * a[0]*a[5]*b[2]^2 + a[3]^2 * b[2]^2-
+ 2 * a[2]*a[5]*b[0]*b[2]+2 * a[1]*a[4]*b[2]*b[3]-a[2]*a[4]*b[1]*b[3]-2 * a[0]*a[2]*b[2]*b[5]+
+ a[2]^2 * b[3]^2 + 2 * a[2]*a[3]*b[1]*b[4]-a[2]*a[4]*b[0]*b[4]+a[4]^2 * b[0]*b[2]-a[2]*a[1]*b[3]*b[4]-
+ a[2]*a[1]*b[1]*b[5]-a[0]*a[4]*b[2]*b[4]+a[0]*a[2]*b[4]^2,
+ -a[4]*a[5]*b[2]*b[1]+a[2]*a[3]*b[4]^2 + 2 * a[3]*a[5]*b[2]^2 - a[2]*a[1]*b[4]*b[5]-
+ a[2]*a[4]*b[3]*b[4]+2 * a[2]^2 * b[3]*b[5]-2 * a[2]*a[3]*b[2]*b[5]-a[3]*a[4]*b[2]*b[4]-
+ 2 * a[2]*a[5]*b[2]*b[3]-a[2]*a[4]*b[1]*b[5]+2 * a[1]*a[4]*b[2]*b[5]-a[1]*a[5]*b[2]*b[4]+
+ a[4]^2 * b[2]*b[3]+2 * a[2]*a[5]*b[1]*b[4],
+ -2 * a[2]*a[5]*b[2]*b[5]+a[4]^2 * b[2]*b[5]+a[5]^2 * b[2]^2 - a[4]*a[5]*b[2]*b[4]+a[2]*a[5]*b[4]^2+
+ a[2]^2 * b[5]^2 - a[2]*a[4]*b[4]*b[5]};
+ x = realquarticroots(c[0], c[1], c[2], c[3], c[4]);
+ } else {
+ if(abs(b[4]-a[4]) > e){
+ real D = (b[4]-a[4])^2;
+ c = new real[] {(a[0]*b[4]^2 + (-a[1]*b[3]-2 * a[0]*a[4]+a[1]*a[3]) * b[4]+a[2]*b[3]^2+
+ (a[1]*a[4]-2 * a[2]*a[3]) * b[3]+a[0]*a[4]^2 - a[1]*a[3]*a[4]+a[2]*a[3]^2)/D,
+ -((a[1]*b[4]-2 * a[2]*b[3]-a[1]*a[4]+2 * a[2]*a[3]) * b[5]-a[3]*b[4]^2 + (a[4]*b[3]-a[1]*a[5]+a[3]*a[4]) * b[4]+(2 * a[2]*a[5]-a[4]^2) * b[3]+(a[1]*a[4]-2 * a[2]*a[3]) * a[5])/D,
+ a[2]*(a[5]-b[5])^2/D + a[4]*(a[5]-b[5])/(b[4]-a[4]) + a[5]};
+ x = quadraticroots(c[0], c[1], c[2]);
+ } else {
+ if(abs(a[3]-b[3]) > e) {
+ real D = b[3]-a[3];
+ c = new real[] {a[2], (-a[1]*b[5] + a[4]*b[3] + a[1]*a[5] - a[3]*a[4])/D,
+ a[0]*(a[5]-b[5])^2/D^2 + a[3]*(a[5]-b[5])/D + a[5]};
+ y = quadraticroots(c[0], c[1], c[2]);
+ for (int i = 0; i < y.length; ++i) {
+ c = new real[] {a[0], a[1]*y[i]+a[3], a[2]*y[i]^2 + a[4]*y[i]+a[5]};
+ x = quadraticroots(c[0], c[1], c[2]);
+ for (int j = 0; j < x.length; ++j) {
+ if(abs(b[0]*x[j]^2 + b[1]*x[j]*y[i]+b[2]*y[i]^2 + b[3]*x[j]+b[4]*y[i]+b[5]) < 1e-5)
+ P.push(point(R, (x[j], y[i])));
+ }
+ }
+ return P;
+ } else {
+ if(abs(a[5]-b[5]) < e) abort("intersectionpoints: intersection of identical conics.");
+ }
+ }
+ }
+ for (int i = 0; i < x.length; ++i) {
+ c = new real[] {a[2], a[1]*x[i]+a[4], a[0]*x[i]^2 + a[3]*x[i]+a[5]};
+ y = quadraticroots(c[0], c[1], c[2]);
+ for (int j = 0; j < y.length; ++j) {
+ if(abs(b[0]*x[i]^2 + b[1]*x[i]*y[j]+b[2]*y[j]^2 + b[3]*x[i]+b[4]*y[j]+b[5]) < 1e-5)
+ P.push(point(R, (x[i], y[j])));
+ }
+ }
+ return P;
+}
+
+/*<asyxml><struct signature="conic"><code></asyxml>*/
+struct conic
+{/*<asyxml></code><documentation></documentation><property type = "real" signature="e,p,h"><code></asyxml>*/
+ real e, p, h;/*<asyxml></code><documentation>BE CAREFUL: h = distance(F, D) and p = h * e (http://en.wikipedia.org/wiki/Ellipse)
+ While http://mathworld.wolfram.com/ takes p = distance(F,D).</documentation></property><property type = "point" signature="F"><code></asyxml>*/
+ point F;/*<asyxml></code><documentation>Focus.</documentation></property><property type = "line" signature="D"><code></asyxml>*/
+ line D;/*<asyxml></code><documentation>Directrix.</documentation></property><property type = "line" signature="l"><code></asyxml>*/
+ line[] l;/*<asyxml></code><documentation>Case of degenerated conic (not yet implemented !).</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+bool degenerate(conic c)
+{
+ return !finite(c.p) || !finite(c.h);
+}
+
+/*ANCconic conic(point, line, real)ANC*/
+conic conic(point F, line l, real e)
+{/*DOC
+ The conic section define by the eccentricity 'e', the focus 'F'
+ and the directrix 'l'.
+ Note that an eccentricity equal to 0 defines a circle centered at F,
+ with a radius equal at the distance from 'F' to 'l'.
+ If the coordinate system of 'F' and 'l' are not identical, the conic is
+ attached to 'defaultcoordsys'.
+ DOC*/
+ if(e < 0) abort("conic: 'e' can't be negative.");
+ conic oc;
+ point[] P = standardizecoordsys(F, l.A, l.B);
+ line ll;
+ ll = line(P[1], P[2]);
+ oc.e = e < epsgeo ? 0 : e; // Handle case of circle.
+ oc.F = P[0];
+ oc.D = ll;
+ oc.h = distance(P[0], ll);
+ oc.p = abs(e) < epsgeo ? oc.h : e * oc.h;
+ return oc;
+}
+
+/*<asyxml><struct signature="circle"><code></asyxml>*/
+struct circle
+{/*<asyxml></code><documentation>All the calculus with this structure will be as exact as Asymptote can do.
+ For a full precision, you must not cast 'circle' to 'path' excepted for drawing routines.</documentation></asyxml>*/
+ /*<asyxml><property type = "point" signature="C"><code></asyxml>*/
+ point C;/*<asyxml></code><documentation>Center</documentation></property><property><code></asyxml>*/
+ real r;/*<asyxml></code><documentation>Radius</documentation></property><property><code></asyxml>*/
+ line l;/*<asyxml></code><documentation>If the radius is infinite, this line is used instead of circle.</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+bool degenerate(circle c)
+{
+ return !finite(c.r);
+}
+
+line line(circle c){
+ if(finite(c.r)) abort("Circle can not be casted to line here.");
+ return c.l;
+}
+
+/*<asyxml><struct signature="ellipse"><code></asyxml>*/
+struct ellipse
+{/*<asyxml></code><documentation>Look at <html><a href = "http://mathworld.wolfram.com/Ellipse.html">http://mathworld.wolfram.com/Ellipse.html</a></html></documentation></asyxml>*/
+ /*<asyxml><property type = "point" signature="F1,F2,C"><code></asyxml>*/
+ restricted point F1,F2,C;/*<asyxml></code><documentation>Foci and center.</documentation></property><property type = "real" signature="a,b,c,e,p"><code></asyxml>*/
+ restricted real a,b,c,e,p;/*<asyxml></code></property><property type = "real" signature="angle"><code></asyxml>*/
+ restricted real angle;/*<asyxml></code><documentation>Value is degrees(F1 - F2).</documentation></property><property type = "line" signature="D1,D2"><code></asyxml>*/
+ restricted line D1,D2;/*<asyxml></code><documentation>Directrices.</documentation></property><property type = "line" signature="l"><code></asyxml>*/
+ line l;/*<asyxml></code><documentation>If one axis is infinite, this line is used instead of ellipse.</documentation></property></asyxml>*/
+ /*<asyxml><method type = "void" signature="init(point,point,real)"><code></asyxml>*/
+ void init(point f1, point f2, real a)
+ {/*<asyxml></code><documentation>Ellipse given by foci and semimajor axis</documentation></method></asyxml>*/
+ point[] P = standardizecoordsys(f1, f2);
+ this.F1 = P[0];
+ this.F2 = P[1];
+ this.angle = abs(P[1]-P[0]) < 10 * epsgeo ? 0 : degrees(P[1]-P[0]);
+ this.C = (P[0] + P[1])/2;
+ this.a = a;
+ if(!finite(a)) {
+ this.l = line(P[0], P[1]);
+ this.b = infinity;
+ this.e = 0;
+ this.c = 0;
+ } else {
+ this.c = abs(C - P[0]);
+ this.b = this.c < epsgeo ? a : sqrt(a^2 - c^2); // Handle case of circle.
+ this.e = this.c < epsgeo ? 0 : this.c/a; // Handle case of circle.
+ if(this.e >= 1) abort("ellipse.init: wrong parameter: e >= 1.");
+ this.p = a * (1 - this.e^2);
+ if (this.c != 0) {// directrix is not set for a circle.
+ point A = this.C + (a^2/this.c) * unit(P[0]-this.C);
+ this.D1 = line(A, A + rotateO(90) * unit(A - this.C));
+ this.D2 = reverse(rotate(180, C) * D1);
+ }
+ }
+ }
+}/*<asyxml></struct></asyxml>*/
+
+bool degenerate(ellipse el)
+{
+ return (!finite(el.a) || !finite(el.b));
+}
+
+/*<asyxml><struct signature="parabola"><code></asyxml>*/
+struct parabola
+{/*<asyxml></code><documentation>Look at <html><a href = "http://mathworld.wolfram.com/Parabola.html">http://mathworld.wolfram.com/Parabola.html</a></html></documentation><property type = "point" signature="F,V"><code></asyxml>*/
+ restricted point F,V;/*<asyxml></code><documentation>Focus and vertex</documentation></property><property type = "real" signature="a,p,e = 1"><code></asyxml>*/
+ restricted real a,p,e = 1;/*<asyxml></code></property><property type = "real" signature="angle"><code></asyxml>*/
+ restricted real angle;/*<asyxml></code><documentation>Angle, in degrees, of the line (FV).</documentation></property><property type = "line" signature="D"><code></asyxml>*/
+ restricted line D;/*<asyxml></code><documentation>Directrix</documentation></property><property type = "pair" signature="bmin,bmax"><code></asyxml>*/
+ pair bmin, bmax;/*<asyxml></code><documentation>The (left, bottom) and (right, top) coordinates of region bounding box for drawing the parabola.
+ If unset the current picture bounding box is used instead.</documentation></property></asyxml>*/
+
+ /*<asyxml><method type = "void" signature="init(point,line)"><code></asyxml>*/
+ void init(point F, line directrix)
+ {/*<asyxml></code><documentation>Parabola given by focus and directrix.</documentation></method></asyxml>*/
+ point[] P = standardizecoordsys(F, directrix.A, directrix.B);
+ line l = line(P[1], P[2]);
+ this.F = P[0];
+ this.D = l;
+ this.a = distance(P[0], l)/2;
+ this.p = 2 * a;
+ this.V = 0.5 * (F + projection(D) * P[0]);
+ this.angle = degrees(F - V);
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><struct signature="hyperbola"><code></asyxml>*/
+struct hyperbola
+{/*<asyxml></code><documentation><html>Look at <a href = "http://mathworld.wolfram.com/Hyperbola.html">http://mathworld.wolfram.com/Hyperbola.html</a></html></documentation><property type = "point" signature="F1,F2"><code></asyxml>*/
+ restricted point F1,F2;/*<asyxml></code><documentation>Foci.</documentation></property><property type = "point" signature="C,V1,V2"><code></asyxml>*/
+ restricted point C,V1,V2;/*<asyxml></code><documentation>Center and vertices.</documentation></property><property type = "real" signature="a,b,c,e,p"><code></asyxml>*/
+ restricted real a,b,c,e,p;/*<asyxml></code><documentation></documentation></property><property type = "real" signature="angle"><code></asyxml>*/
+ restricted real angle;/*<asyxml></code><documentation>Angle,in degrees,of the line (F1F2).</documentation></property><property type = "line" signature="D1,D2,A1,A2"><code></asyxml>*/
+ restricted line D1,D2,A1,A2;/*<asyxml></code><documentation>Directrices and asymptotes.</documentation></property><property type = "pair" signature="bmin,bmax"><code></asyxml>*/
+ pair bmin, bmax; /*<asyxml></code><documentation>The (left, bottom) and (right, top) coordinates of region bounding box for drawing the hyperbola.
+ If unset the current picture bounding box is used instead.</documentation></property></asyxml>*/
+
+ /*<asyxml><method type = "void" signature="init(point,point,real)"><code></asyxml>*/
+ void init(point f1, point f2, real a)
+ {/*<asyxml></code><documentation>Hyperbola given by foci and semimajor axis.</documentation></method></asyxml>*/
+ point[] P = standardizecoordsys(f1, f2);
+ this.F1 = P[0];
+ this.F2 = P[1];
+ this.angle = degrees(F2 - F1);
+ this.a = a;
+ this.C = (P[0] + P[1])/2;
+ this.c = abs(C - P[0]);
+ this.e = this.c/a;
+ if(this.e <= 1) abort("hyperbola.init: wrong parameter: e <= 1.");
+ this.b = a * sqrt(this.e^2 - 1);
+ this.p = a * (this.e^2 - 1);
+ point A = this.C + (a^2/this.c) * unit(P[0]-this.C);
+ this.D1 = line(A, A + rotateO(90) * unit(A - this.C));
+ this.D2 = reverse(rotate(180, C) * D1);
+ this.V1 = C + a * unit(F1 - C);
+ this.V2 = C + a * unit(F2 - C);
+ this.A1 = line(C, V1 + b * unit(rotateO(-90) * (C - V1)));
+ this.A2 = line(C, V1 + b * unit(rotateO(90) * (C - V1)));
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><variable type="int" signature="conicnodesfactor"><code></asyxml>*/
+int conicnodesfactor = 1;/*<asyxml></code><documentation>Factor for the node number of all conics.</documentation></variable></asyxml>*/
+
+/*<asyxml><variable type="int" signature="circlenodesnumberfactor"><code></asyxml>*/
+int circlenodesnumberfactor = 100;/*<asyxml></code><documentation>Factor for the node number of circles.</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="circlenodesnumber(real)"><code></asyxml>*/
+int circlenodesnumber(real r)
+{/*<asyxml></code><documentation>Return the number of nodes for drawing a circle of radius 'r'.</documentation></function></asyxml>*/
+ if (circlenodesnumberfactor < 100)
+ warning("circlenodesnumberfactor",
+ "variable 'circlenodesnumberfactor' may be too small.");
+ int oi = ceil(circlenodesnumberfactor * abs(r)^0.1);
+ oi = 45 * floor(oi/45);
+ return oi == 0 ? 4 : conicnodesfactor * oi;
+}
+
+/*<asyxml><function type="int" signature="circlenodesnumber(real,real,real)"><code></asyxml>*/
+int circlenodesnumber(real r, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the number of nodes to draw a circle arc.</documentation></function></asyxml>*/
+ return (r > 0) ?
+ ceil(circlenodesnumber(r) * abs(angle1 - angle2)/360) :
+ ceil(circlenodesnumber(r) * abs((1 - abs(angle1 - angle2)/360)));
+}
+
+/*<asyxml><variable type="int" signature="ellispenodesnumberfactor"><code></asyxml>*/
+int ellipsenodesnumberfactor = 250;/*<asyxml></code><documentation>Factor for the node number of ellispe (non-circle).</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="ellipsenodesnumber(real,real)"><code></asyxml>*/
+int ellipsenodesnumber(real a, real b)
+{/*<asyxml></code><documentation>Return the number of nodes to draw a ellipse of axis 'a' and 'b'.</documentation></function></asyxml>*/
+ if (ellipsenodesnumberfactor < 250)
+ write("ellipsenodesnumberfactor",
+ "variable 'ellipsenodesnumberfactor' maybe too small.");
+ int tmp = circlenodesnumberfactor;
+ circlenodesnumberfactor = ellipsenodesnumberfactor;
+ int oi = circlenodesnumber(max(abs(a), abs(b))/min(abs(a), abs(b)));
+ circlenodesnumberfactor = tmp;
+ return conicnodesfactor * oi;
+}
+
+/*<asyxml><function type="int" signature="ellipsenodesnumber(real,real,real)"><code></asyxml>*/
+int ellipsenodesnumber(real a, real b, real angle1, real angle2, bool dir)
+{/*<asyxml></code><documentation>Return the number of nodes to draw an ellipse arc.</documentation></function></asyxml>*/
+ real d;
+ real da = angle2 - angle1;
+ if(dir) {
+ d = angle1 < angle2 ? da : 360 + da;
+ } else {
+ d = angle1 < angle2 ? -360 + da : da;
+ }
+ int n = floor(ellipsenodesnumber(a, b) * abs(d)/360);
+ return n < 5 ? 5 : n;
+}
+
+/*<asyxml><variable type="int" signature="parabolanodesnumberfactor"><code></asyxml>*/
+int parabolanodesnumberfactor = 100;/*<asyxml></code><documentation>Factor for the number of nodes of parabolas.</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="parabolanodesnumber(parabola,real,real)"><code></asyxml>*/
+int parabolanodesnumber(parabola p, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the number of nodes for drawing a parabola.</documentation></function></asyxml>*/
+ return conicnodesfactor * floor(0.01 * parabolanodesnumberfactor * abs(angle1 - angle2));
+}
+
+/*<asyxml><variable type="int" signature="hyperbolanodesnumberfactor"><code></asyxml>*/
+int hyperbolanodesnumberfactor = 100;/*<asyxml></code><documentation>Factor for the number of nodes of hyperbolas.</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="hyperbolanodesnumber(hyperbola,real,real)"><code></asyxml>*/
+int hyperbolanodesnumber(hyperbola h, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the number of nodes for drawing an hyperbola.</documentation></function></asyxml>*/
+ return conicnodesfactor * floor(0.01 * hyperbolanodesnumberfactor * abs(angle1 - angle2)/h.e);
+}
+
+/*<asyxml><operator type = "conic" signature="+(conic,explicit point)"><code></asyxml>*/
+conic operator +(conic c, explicit point M)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F + M, c.D + M, c.e);
+}
+/*<asyxml><operator type = "conic" signature="-(conic,explicit point)"><code></asyxml>*/
+conic operator -(conic c, explicit point M)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F - M, c.D - M, c.e);
+}
+/*<asyxml><operator type = "conic" signature="+(conic,explicit pair)"><code></asyxml>*/
+conic operator +(conic c, explicit pair m)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ point M = point(c.F.coordsys, m);
+ return conic(c.F + M, c.D + M, c.e);
+}
+/*<asyxml><operator type = "conic" signature="-(conic,explicit pair)"><code></asyxml>*/
+conic operator -(conic c, explicit pair m)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ point M = point(c.F.coordsys, m);
+ return conic(c.F - M, c.D - M, c.e);
+}
+/*<asyxml><operator type = "conic" signature="+(conic,vector)"><code></asyxml>*/
+conic operator +(conic c, vector v)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F + v, c.D + v, c.e);
+}
+/*<asyxml><operator type = "conic" signature="-(conic,vector)"><code></asyxml>*/
+conic operator -(conic c, vector v)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F - v, c.D - v, c.e);
+}
+
+/*<asyxml><function type="coordsys" signature="coordsys(conic)"><code></asyxml>*/
+coordsys coordsys(conic co)
+{/*<asyxml></code><documentation>Return the coordinate system of 'co'.</documentation></function></asyxml>*/
+ return co.F.coordsys;
+}
+
+/*<asyxml><function type="conic" signature="changecoordsys(coordsys,conic)"><code></asyxml>*/
+conic changecoordsys(coordsys R, conic co)
+{/*<asyxml></code><documentation>Change the coordinate system of 'co' to 'R'</documentation></function></asyxml>*/
+ line l = changecoordsys(R, co.D);
+ point F = changecoordsys(R, co.F);
+ return conic(F, l, co.e);
+}
+
+/*<asyxml><typedef type = "polarconicroutine" return = "path" params = "conic, real, real, int, bool"><code></asyxml>*/
+typedef path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction);/*<asyxml></code><documentation>Routine type used to draw conics from 'angle1' to 'angle2'</documentation></typedef></asyxml>*/
+
+/*<asyxml><function type="path" signature="arcfromfocus(conic,real,real,int,bool)"><code></asyxml>*/
+path arcfromfocus(conic co, real angle1, real angle2, int n = 400, bool direction = CCW)
+{/*<asyxml></code><documentation>Return the path of the conic section 'co' from angle1 to angle2 in degrees,
+ drawing in the given direction, with n nodes.</documentation></function></asyxml>*/
+ guide op;
+ if (n < 1) return op;
+ if (angle1 > angle2) {
+ path g = arcfromfocus(co, angle2, angle1, n, !direction);
+ return g == nullpath ? g : reverse(g);
+ }
+ point O = projection(co.D) * co.F;
+ pair i = unit(locate(co.F) - locate(O));
+ pair j = rotate(90) * i;
+ coordsys Rp = cartesiansystem(co.F, i, j);
+ real a1 = direction ? radians(angle1) : radians(angle2);
+ real a2 = direction ? radians(angle2) : radians(angle1) + 2 * pi;
+ real step = n == 1 ? 0 : (a2 - a1)/(n - 1);
+ real a, r;
+ for (int i = 0; i < n; ++i) {
+ a = a1 + i * step;
+ if(co.e >= 1) {
+ r = 1 - co.e * cos(a);
+ if(r > epsgeo) {
+ r = co.p/r;
+ op = op--Rp * Rp.polar(r, a);
+ }
+ } else {
+ r = co.p/(1 - co.e * cos(a));
+ op = op..Rp * Rp.polar(r, a);
+ }
+ }
+ if(co.e < 1 && abs(abs(a2 - a1) - 2 * pi) < epsgeo) op = (path)op..cycle;
+
+ return (direction ? op : op == nullpath ? op :reverse(op));
+}
+
+/*<asyxml><variable type="polarconicroutine" signature="currentpolarconicroutine"><code></asyxml>*/
+polarconicroutine currentpolarconicroutine = arcfromfocus;/*<asyxml></code><documentation>Default routine used to cast conic section to path.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="point" signature="angpoint(conic,real)"><code></asyxml>*/
+point angpoint(conic co, real angle)
+{/*<asyxml></code><documentation>Return the point of 'co' whose the angular (in degrees)
+ coordinate is 'angle' (mesured from the focus of 'co', relatively
+ to its 'natural coordinate system').</documentation></function></asyxml>*/
+ coordsys R = coordsys(co);
+ return point(R, point(arcfromfocus(co, angle, angle, 1, CCW), 0)/R);
+}
+
+/*<asyxml><operator type = "bool" signature="@(point,conic)"><code></asyxml>*/
+bool operator @(point M, conic co)
+{/*<asyxml></code><documentation>Return true iff 'M' on 'co'.</documentation></operator></asyxml>*/
+ if(co.e == 0) return abs(abs(co.F - M) - co.p) < 10 * epsgeo;
+ return abs(co.e * distance(M, co.D) - abs(co.F - M)) < 10 * epsgeo;
+}
+
+/*<asyxml><function type="coordsys" signature="coordsys(ellipse)"><code></asyxml>*/
+coordsys coordsys(ellipse el)
+{/*<asyxml></code><documentation>Return the coordinate system of 'el'.</documentation></function></asyxml>*/
+ return el.F1.coordsys;
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(ellipse)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(ellipse el)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of the ellipse 'el'.</documentation></function></asyxml>*/
+ if(degenerate(el)) return cartesiansystem(el.l.A, el.l.u, el.l.v);
+ pair O = locate(el.C);
+ pair i = el.e == 0 ? el.C.coordsys.i : unit(locate(el.F1) - O);
+ pair j = rotate(90) * i;
+ return cartesiansystem(O, i, j);
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(parabola)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(parabola p)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of a parabola,
+ so that Origin = vertex of 'p' and directrix: x = -a.</documentation></function></asyxml>*/
+ point A = projection(p.D) * p.F;
+ pair O = locate((A + p.F)/2);
+ pair i = unit(locate(p.F) - O);
+ pair j = rotate(90) * i;
+ return cartesiansystem(O, i, j);
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(hyperbola)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(hyperbola h)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of an hyperbola.</documentation></function></asyxml>*/
+ pair O = locate(h.C);
+ pair i = unit(locate(h.F2) - O);
+ pair j = rotate(90) * i;
+ return cartesiansystem(O, i, j);
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,point,real)"><code></asyxml>*/
+ellipse ellipse(point F1, point F2, real a)
+{/*<asyxml></code><documentation>Return the ellipse whose the foci are 'F1' and 'F2'
+ and the semimajor axis is 'a'.</documentation></function></asyxml>*/
+ ellipse oe;
+ oe.init(F1, F2, a);
+ return oe;
+}
+
+/*<asyxml><constant type = "bool" signature="byfoci,byvertices"><code></asyxml>*/
+restricted bool byfoci = true, byvertices = false;/*<asyxml></code><documentation>Constants useful for the routine 'hyperbola(point P1, point P2, real ae, bool byfoci = byfoci)'</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(point,point,real,bool)"><code></asyxml>*/
+hyperbola hyperbola(point P1, point P2, real ae, bool byfoci = byfoci)
+{/*<asyxml></code><documentation>if 'byfoci = true':
+ return the hyperbola whose the foci are 'P1' and 'P2'
+ and the semimajor axis is 'ae'.
+ else return the hyperbola whose vertexes are 'P1' and 'P2' with eccentricity 'ae'.</documentation></function></asyxml>*/
+ hyperbola oh;
+ point[] P = standardizecoordsys(P1, P2);
+ if(byfoci) {
+ oh.init(P[0], P[1], ae);
+ } else {
+ real a = abs(P[0]-P[1])/2;
+ vector V = unit(P[0]-P[1]);
+ point F1 = P[0] + a * (ae - 1) * V;
+ point F2 = P[1]-a * (ae - 1) * V;
+ oh.init(F1, F2, a);
+ }
+ return oh;
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,point,point)"><code></asyxml>*/
+ellipse ellipse(point F1, point F2, point M)
+{/*<asyxml></code><documentation>Return the ellipse passing through 'M' whose the foci are 'F1' and 'F2'.</documentation></function></asyxml>*/
+ point P[] = standardizecoordsys(false, F1, F2, M);
+ real a = abs(F1 - M) + abs(F2 - M);
+ return ellipse(F1, F2, finite(a) ? a/2 : a);
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,real,real,real)"><code></asyxml>*/
+ellipse ellipse(point C, real a, real b, real angle = 0)
+{/*<asyxml></code><documentation>Return the ellipse centered at 'C' with semimajor axis 'a' along C--C + dir(angle),
+ semiminor axis 'b' along the perpendicular.</documentation></function></asyxml>*/
+ ellipse oe;
+ coordsys R = C.coordsys;
+ angle += degrees(R.i);
+ if(a < b) {angle += 90; real tmp = a; a = b; b = tmp;}
+ if(finite(a) && finite(b)) {
+ real c = sqrt(abs(a^2 - b^2));
+ point f1, f2;
+ if(abs(a - b) < epsgeo) {
+ f1 = C; f2 = C;
+ } else {
+ f1 = point(R, (locate(C) + rotate(angle) * (-c, 0))/R);
+ f2 = point(R, (locate(C) + rotate(angle) * (c, 0))/R);
+ }
+ oe.init(f1, f2, a);
+ } else {
+ if(finite(b) || !finite(a)) oe.init(C, C + R.polar(1, angle), infinity);
+ else oe.init(C, C + R.polar(1, 90 + angle), infinity);
+ }
+ return oe;
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(bqe)"><code></asyxml>*/
+ellipse ellipse(bqe bqe)
+{/*<asyxml></code><documentation>Return the ellipse a[0] * x^2 + a[1] * xy + a[2] * y^2 + a[3] * x + a[4] * y + a[5] = 0
+ given in the coordinate system of 'bqe' with a[i] = bque.a[i].
+ <url href = "http://mathworld.wolfram.com/QuadraticCurve.html"/>
+ <url href = "http://mathworld.wolfram.com/Ellipse.html"/>.</documentation></function></asyxml>*/
+ bqe lbqe = changecoordsys(defaultcoordsys, bqe);
+ real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5];
+ coordsys R = bqe.coordsys;
+ string message = "ellipse: the given equation is not an equation of an ellipse.";
+ real u = b^2 * g + d^2 * c + f^2 * a;
+ real delta = a * c * g + b * f * d + d * b * f - u;
+ if(abs(delta) < epsgeo) abort(message);
+ real j = b^2 - a * c;
+ real i = a + c;
+ real dd = j * (sgnd(c - a) * sqrt((a - c)^2 + 4 * (b^2)) - c-a);
+ real ddd = j * (-sgnd(c - a) * sqrt((a - c)^2 + 4 * (b^2)) - c-a);
+
+ if(abs(ddd) < epsgeo || abs(dd) < epsgeo ||
+ j >= -epsgeo || delta/sgnd(i) > 0) abort(message);
+
+ real x = (c * d - b * f)/j, y = (a * f - b * d)/j;
+ // real dir = abs(b) < epsgeo ? 0 : pi/2-0.5 * acot(0.5 * (c-a)/b);
+ real dir = abs(b) < epsgeo ? 0 : 0.5 * acot(0.5 * (c - a)/b);
+ if(dir * (c - a) * b < 0) dir = dir < 0 ? dir + pi/2 : dir - pi/2;
+ real cd = cos(dir), sd = sin(dir);
+ real t = a * cd^2 - 2 * b * cd * sd + c * sd^2;
+ real tt = a * sd^2 + 2 * b * cd * sd + c * cd^2;
+ real gg = -g + ((d * cd - f * sd)^2)/t + ((d * sd + f * cd)^2)/tt;
+ t = t/gg; tt = tt/gg;
+ // The equation of the ellipse is t * (x - center.x)^2 + tt * (y - center.y)^2 = 1;
+ real aa, bb;
+ aa = sqrt(2 * (u - 2 * b * d * f - a * c * g)/dd);
+ bb = sqrt(2 * (u - 2 * b * d * f - a * c * g)/ddd);
+ a = t > tt ? max(aa, bb) : min(aa, bb);
+ b = t > tt ? min(aa, bb) : max(aa, bb);
+ return ellipse(point(R, (x, y)/R),
+ a, b, degrees(pi/2 - dir - angle(R.i)));
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,point,point,point,point)"><code></asyxml>*/
+ellipse ellipse(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the ellipse passing through the five points (if possible)</documentation></function></asyxml>*/
+ return ellipse(bqe(M1, M2, M3, M4, M5));
+}
+
+/*<asyxml><function type="bool" signature="inside(ellipse,point)"><code></asyxml>*/
+bool inside(ellipse el, point M)
+{/*<asyxml></code><documentation>Return 'true' iff 'M' is inside 'el'.</documentation></function></asyxml>*/
+ return abs(el.F1 - M) + abs(el.F2 - M) - 2 * el.a < -epsgeo;
+}
+
+/*<asyxml><function type="bool" signature="inside(parabola,point)"><code></asyxml>*/
+bool inside(parabola p, point M)
+{/*<asyxml></code><documentation>Return 'true' if 'M' is inside 'p'.</documentation></function></asyxml>*/
+ return distance(p.D, M) - abs(p.F - M) > epsgeo;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,line)"><code></asyxml>*/
+parabola parabola(point F, line l)
+{/*<asyxml></code><documentation>Return the parabola whose focus is 'F' and directrix is 'l'.</documentation></function></asyxml>*/
+ parabola op;
+ op.init(F, l);
+ return op;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,point)"><code></asyxml>*/
+parabola parabola(point F, point vertex)
+{/*<asyxml></code><documentation>Return the parabola whose focus is 'F' and vertex is 'vertex'.</documentation></function></asyxml>*/
+ parabola op;
+ point[] P = standardizecoordsys(F, vertex);
+ point A = rotate(180, P[1]) * P[0];
+ point B = A + rotateO(90) * unit(P[1]-A);
+ op.init(P[0], line(A, B));
+ return op;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,real,real)"><code></asyxml>*/
+parabola parabola(point F, real a, real angle)
+{/*<asyxml></code><documentation>Return the parabola whose focus is F, latus rectum is 4a and
+ the angle of the axis of symmetry (in the coordinate system of F) is 'angle'.</documentation></function></asyxml>*/
+ parabola op;
+ coordsys R = F.coordsys;
+ point A = F - point(R, R.polar(2a, radians(angle)));
+ point B = A + point(R, R.polar(1, radians(90 + angle)));
+ op.init(F, line(A, B));
+ return op;
+}
+
+/*<asyxml><function type="bool" signature="isparabola(bqe)"><code></asyxml>*/
+bool isparabola(bqe bqe)
+{/*<asyxml></code><documentation>Return true iff 'bqe' is the equation of a parabola.</documentation></function></asyxml>*/
+ bqe lbqe = changecoordsys(defaultcoordsys, bqe);
+ real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5];
+ real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a);
+ return (abs(delta) > epsgeo && abs(b^2 - a * c) < epsgeo);
+}
+
+/*<asyxml><function type="parabola" signature="parabola(bqe)"><code></asyxml>*/
+parabola parabola(bqe bqe)
+{/*<asyxml></code><documentation>Return the parabola a[0]x^2 + a[1]xy + a[2]y^2 + a[3]x + a[4]y + a[5]] = 0 (a[n] means bqe.a[n]).
+ <url href = "http://mathworld.wolfram.com/QuadraticCurve.html"/>
+ <url href = "http://mathworld.wolfram.com/Parabola.html"/></documentation></function></asyxml>*/
+ bqe lbqe = changecoordsys(defaultcoordsys, bqe);
+ real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5];
+ string message = "parabola: the given equation is not an equation of a parabola.";
+ real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a);
+ if(abs(delta) < 10 * epsgeo || abs(b^2 - a * c) > 10 * epsgeo) abort(message);
+ real dir = abs(b) < epsgeo ? 0 : 0.5 * acot(0.5 * (c - a)/b);
+ if(dir * (c - a) * b < 0) dir = dir < 0 ? dir + pi/2 : dir - pi/2;
+ real cd = cos(dir), sd = sin(dir);
+ real ap = a * cd^2 - 2 * b * cd * sd + c * sd^2;
+ real cp = a * sd^2 + 2 * b * cd * sd + c * cd^2;
+ real dp = d * cd - f * sd;
+ real fp = d * sd + f * cd;
+ real gp = g;
+ parabola op;
+ coordsys R = bqe.coordsys;
+ // The equation of the parabola is ap * x'^2 + cp * y'^2 + 2dp * x'+2fp * y'+gp = 0
+ if (abs(ap) < epsgeo) {/* directrix parallel to the rotated(dir) y-axis
+ equation: (y-vertex.y)^2 = 4 * a * (x-vertex)
+ */
+ pair pvertex = rotate(degrees(-dir)) * (0.5(-gp + fp^2/cp)/dp, -fp/cp);
+ real a = -0.5 * dp/cp;
+ point vertex = point(R, pvertex/R);
+ point focus = point(R, (pvertex + a * expi(-dir))/R);
+ op = parabola(focus, vertex);
+
+ } else {/* directrix parallel to the rotated(dir) x-axis
+ equation: (x-vertex)^2 = 4 * a * (y-vertex.y)
+ */
+ pair pvertex = rotate(degrees(-dir)) * (-dp/ap, 0.5 * (-gp + dp^2/ap)/fp);
+ real a = -0.5 * fp/ap;
+ point vertex = point(R, pvertex/R);
+ point focus = point(R, (pvertex + a * expi(pi/2 - dir))/R);
+ op = parabola(focus, vertex);
+ }
+ return op;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,point,point,line)"><code></asyxml>*/
+parabola parabola(point M1, point M2, point M3, line l)
+{/*<asyxml></code><documentation>Return the parabola passing through the three points with its directix
+ parallel to the line 'l'.</documentation></function></asyxml>*/
+ coordsys R;
+ pair[] pts;
+ if (samecoordsys(M1, M2, M3)) {
+ R = M1.coordsys;
+ } else {
+ R = defaultcoordsys;
+ }
+ real gle = degrees(l);
+ coordsys Rp = cartesiansystem(R.O, rotate(gle) * R.i, rotate(gle) * R.j);
+ pts = new pair[] {coordinates(changecoordsys(Rp, M1)),
+ coordinates(changecoordsys(Rp, M2)),
+ coordinates(changecoordsys(Rp, M3))};
+ real[][] M;
+ real[] x;
+ for (int i = 0; i < 3; ++i) {
+ M[i] = new real[] {pts[i].x, pts[i].y, 1};
+ x[i] = -pts[i].x^2;
+ }
+ real[] coef = solve(M, x);
+ return parabola(changecoordsys(R, bqe(Rp, 1, 0, 0, coef[0], coef[1], coef[2])));
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,point,point,point,point)"><code></asyxml>*/
+parabola parabola(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the parabola passing through the five points.</documentation></function></asyxml>*/
+ return parabola(bqe(M1, M2, M3, M4, M5));
+}
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(point,real,real,real)"><code></asyxml>*/
+hyperbola hyperbola(point C, real a, real b, real angle = 0)
+{/*<asyxml></code><documentation>Return the hyperbola centered at 'C' with semimajor axis 'a' along C--C + dir(angle),
+ semiminor axis 'b' along the perpendicular.</documentation></function></asyxml>*/
+ hyperbola oh;
+ coordsys R = C.coordsys;
+ angle += degrees(R.i);
+ real c = sqrt(a^2 + b^2);
+ point f1 = point(R, (locate(C) + rotate(angle) * (-c, 0))/R);
+ point f2 = point(R, (locate(C) + rotate(angle) * (c, 0))/R);
+ oh.init(f1, f2, a);
+ return oh;
+}
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(bqe)"><code></asyxml>*/
+hyperbola hyperbola(bqe bqe)
+{/*<asyxml></code><documentation>Return the hyperbola a[0]x^2 + a[1]xy + a[2]y^2 + a[3]x + a[4]y + a[5]] = 0 (a[n] means bqe.a[n]).
+ <url href = "http://mathworld.wolfram.com/QuadraticCurve.html"/>
+ <url href = "http://mathworld.wolfram.com/Hyperbola.html"/></documentation></function></asyxml>*/
+ bqe lbqe = changecoordsys(defaultcoordsys, bqe);
+ real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5];
+ string message = "hyperbola: the given equation is not an equation of a hyperbola.";
+ real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a);
+ if(abs(delta) < 10 * epsgeo || abs(b^2 - a * c) < 0) abort(message);
+ real dir = abs(b) < epsgeo ? 0 : 0.5 * acot(0.5 * (c - a)/b);
+ real cd = cos(dir), sd = sin(dir);
+ real ap = a * cd^2 - 2 * b * cd * sd + c * sd^2;
+ real cp = a * sd^2 + 2 * b * cd * sd + c * cd^2;
+ real dp = d * cd - f * sd;
+ real fp = d * sd + f * cd;
+ real gp = -g + dp^2/ap + fp^2/cp;
+ hyperbola op;
+ coordsys R = bqe.coordsys;
+ real j = b^2 - a * c;
+ point C = point(R, ((c * d - b * f)/j, (a * f - b * d)/j)/R);
+ real aa = gp/ap, bb = gp/cp;
+ real a = sqrt(abs(aa)), b = sqrt(abs(bb));
+ if(aa < 0) {dir -= pi/2; aa = a; a = b; b = aa;}
+ return hyperbola(C, a, b, degrees(-dir - angle(R.i)));
+}
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(point,point,point,point,point)"><code></asyxml>*/
+hyperbola hyperbola(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the hyperbola passing through the five points (if possible).</documentation></function></asyxml>*/
+ return hyperbola(bqe(M1, M2, M3, M4, M5));
+}
+
+/*<asyxml><function type="hyperbola" signature="conj(hyperbola)"><code></asyxml>*/
+hyperbola conj(hyperbola h)
+{/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/
+ return hyperbola(h.C, h.b, h.a, 90 + h.angle);
+}
+
+/*<asyxml><function type="circle" signature="circle(explicit point,real)"><code></asyxml>*/
+circle circle(explicit point C, real r)
+{/*<asyxml></code><documentation>Circle given by center and radius.</documentation></function></asyxml>*/
+ circle oc = new circle;
+ oc.C = C;
+ oc.r = r;
+ if(!finite(r)) oc.l = line(C, C + vector(C.coordsys, (1, 0)));
+ return oc;
+}
+
+/*<asyxml><function type="circle" signature="circle(point,point)"><code></asyxml>*/
+circle circle(point A, point B)
+{/*<asyxml></code><documentation>Return the circle of diameter AB.</documentation></function></asyxml>*/
+ real r;
+ circle oc;
+ real a = abs(A), b = abs(B);
+ if(finite(a) && finite(b)) {
+ oc = circle((A + B)/2, abs(A - B)/2);
+ } else {
+ oc.r = infinity;
+ if(finite(abs(A))) oc.l = line(A, A + unit(B));
+ else {
+ if(finite(abs(B))) oc.l = line(B, B + unit(A));
+ else if(finite(abs(A - B)/2)) oc = circle((A + B)/2, abs(A - B)/2); else
+ oc.l = line(A, B);
+ }
+ }
+ return oc;
+}
+
+/*<asyxml><function type="circle" signature="circle(segment)"><code></asyxml>*/
+circle circle(segment s)
+{/*<asyxml></code><documentation>Return the circle of diameter 's'.</documentation></function></asyxml>*/
+ return circle(s.A, s.B);
+}
+
+/*<asyxml><function type="point" signature="circumcenter(point,point,point)"><code></asyxml>*/
+point circumcenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the circumcenter of triangle ABC.</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A, B, C);
+ coordsys R = P[0].coordsys;
+ pair a = A, b = B, c = C;
+ pair mAB = (a + b)/2;
+ pair mAC = (a + c)/2;
+ pair pp = extension(mAB, rotate(90, mAB) * a, mAC, rotate(90, mAC) * c);
+ return point(R, pp/R);
+}
+
+/*<asyxml><function type="circle" signature="circle(point,point,point)"><code></asyxml>*/
+circle circle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle ABC.</documentation></function></asyxml>*/
+ if(collinear(A - B, A - C)) {
+ circle oc;
+ oc.r = infinity;
+ oc.C = (A + B + C)/3;
+ oc.l = line(oc.C, oc.C == A ? B : A);
+ return oc;
+ }
+ point c = circumcenter(A, B, C);
+ return circle(c, abs(c - A));
+}
+
+/*<asyxml><function type="circle" signature="circumcircle(point,point,point)"><code></asyxml>*/
+circle circumcircle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle ABC.</documentation></function></asyxml>*/
+ return circle(A, B, C);
+}
+
+/*<asyxml><operator type = "circle" signature="*(real,explicit circle)"><code></asyxml>*/
+circle operator *(real x, explicit circle c)
+{/*<asyxml></code><documentation>Multiply the radius of 'c'.</documentation></operator></asyxml>*/
+ return finite(c.r) ? circle(c.C, x * c.r) : c;
+}
+circle operator *(int x, explicit circle c)
+{
+ return finite(c.r) ? circle(c.C, x * c.r) : c;
+}
+/*<asyxml><operator type = "circle" signature="/(explicit circle,real)"><code></asyxml>*/
+circle operator /(explicit circle c, real x)
+{/*<asyxml></code><documentation>Divide the radius of 'c'</documentation></operator></asyxml>*/
+ return finite(c.r) ? circle(c.C, c.r/x) : c;
+}
+circle operator /(explicit circle c, int x)
+{
+ return finite(c.r) ? circle(c.C, c.r/x) : c;
+}
+/*<asyxml><operator type = "circle" signature="+(explicit circle,explicit point)"><code></asyxml>*/
+circle operator +(explicit circle c, explicit point M)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C + M, c.r);
+}
+/*<asyxml><operator type = "circle" signature="-(explicit circle,explicit point)"><code></asyxml>*/
+circle operator -(explicit circle c, explicit point M)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C - M, c.r);
+}
+/*<asyxml><operator type = "circle" signature="+(explicit circle,pair)"><code></asyxml>*/
+circle operator +(explicit circle c, pair m)
+{/*<asyxml></code><documentation>Translation of 'c'.
+ 'm' represent coordinates in the coordinate system where 'c' is defined.</documentation></operator></asyxml>*/
+ return circle(c.C + m, c.r);
+}
+/*<asyxml><operator type = "circle" signature="-(explicit circle,pair)"><code></asyxml>*/
+circle operator -(explicit circle c, pair m)
+{/*<asyxml></code><documentation>Translation of 'c'.
+ 'm' represent coordinates in the coordinate system where 'c' is defined.</documentation></operator></asyxml>*/
+ return circle(c.C - m, c.r);
+}
+/*<asyxml><operator type = "circle" signature="+(explicit circle,vector)"><code></asyxml>*/
+circle operator +(explicit circle c, vector m)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C + m, c.r);
+}
+/*<asyxml><operator type = "circle" signature="-(explicit circle,vector)"><code></asyxml>*/
+circle operator -(explicit circle c, vector m)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C - m, c.r);
+}
+/*<asyxml><operator type = "real" signature="^(point,explicit circle)"><code></asyxml>*/
+real operator ^(point M, explicit circle c)
+{/*<asyxml></code><documentation>The power of 'M' with respect to the circle 'c'</documentation></operator></asyxml>*/
+ return xpart((abs(locate(M) - locate(c.C)), c.r)^2);
+}
+/*<asyxml><operator type = "bool" signature="@(point,explicit circle)"><code></asyxml>*/
+bool operator @(point M, explicit circle c)
+{/*<asyxml></code><documentation>Return true iff 'M' is on the circle 'c'.</documentation></operator></asyxml>*/
+ return finite(c.r) ?
+ abs(abs(locate(M) - locate(c.C)) - abs(c.r)) <= 10 * epsgeo :
+ M @ c.l;
+}
+
+/*<asyxml><operator type = "ellipse" signature="cast(circle)"><code></asyxml>*/
+ellipse operator cast(circle c)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return finite(c.r) ? ellipse(c.C, c.r, c.r, 0) : ellipse(c.l.A, c.l.B, infinity);
+}
+
+/*<asyxml><operator type = "circle" signature="cast(ellipse)"><code></asyxml>*/
+circle operator cast(ellipse el)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ circle oc;
+ bool infb = (!finite(el.a) || !finite(el.b));
+ if(!infb && abs(el.a - el.b) > epsgeo)
+ abort("Can not cast ellipse with different axis values to circle");
+ oc = circle(el.C, infb ? infinity : el.a);
+ oc.l = el.l.copy();
+ return oc;
+}
+
+/*<asyxml><operator type = "ellipse" signature="cast(conic)"><code></asyxml>*/
+ellipse operator cast(conic co)
+{/*<asyxml></code><documentation>Cast a conic to an ellipse (can be a circle).</documentation></operator></asyxml>*/
+ if(degenerate(co) && co.e < 1) return ellipse(co.l[0].A, co.l[0].B, infinity);
+ ellipse oe;
+ if(co.e < 1) {
+ real a = co.p/(1 - co.e^2);
+ real c = co.e * a;
+ vector v = co.D.v;
+ if(!sameside(co.D.A + v, co.F, co.D)) v = -v;
+ point f2 = co.F + 2 * c * v;
+ f2 = changecoordsys(co.F.coordsys, f2);
+ oe = a == 0 ? ellipse(co.F, co.p, co.p, 0) : ellipse(co.F, f2, a);
+ } else
+ abort("casting: The conic section is not an ellipse.");
+ return oe;
+}
+
+/*<asyxml><operator type = "parabola" signature="cast(conic)"><code></asyxml>*/
+parabola operator cast(conic co)
+{/*<asyxml></code><documentation>Cast a conic to a parabola.</documentation></operator></asyxml>*/
+ parabola op;
+ if(abs(co.e - 1) > epsgeo) abort("casting: The conic section is not a parabola.");
+ op.init(co.F, co.D);
+ return op;
+}
+
+/*<asyxml><operator type = "conic" signature="cast(parabola)"><code></asyxml>*/
+conic operator cast(parabola p)
+{/*<asyxml></code><documentation>Cast a parabola to a conic section.</documentation></operator></asyxml>*/
+ return conic(p.F, p.D, 1);
+}
+
+/*<asyxml><operator type = "hyperbola" signature="cast(conic)"><code></asyxml>*/
+hyperbola operator cast(conic co)
+{/*<asyxml></code><documentation>Cast a conic section to an hyperbola.</documentation></operator></asyxml>*/
+ hyperbola oh;
+ if(co.e > 1) {
+ real a = co.p/(co.e^2 - 1);
+ real c = co.e * a;
+ vector v = co.D.v;
+ if(sameside(co.D.A + v, co.F, co.D)) v = -v;
+ point f2 = co.F + 2 * c * v;
+ f2 = changecoordsys(co.F.coordsys, f2);
+ oh = hyperbola(co.F, f2, a);
+ } else
+ abort("casting: The conic section is not an hyperbola.");
+ return oh;
+}
+
+/*<asyxml><operator type = "conic" signature="cast(hyperbola)"><code></asyxml>*/
+conic operator cast(hyperbola h)
+{/*<asyxml></code><documentation>Hyperbola to conic section.</documentation></operator></asyxml>*/
+ return conic(h.F1, h.D1, h.e);
+}
+
+/*<asyxml><operator type = "conic" signature="cast(ellipse)"><code></asyxml>*/
+conic operator cast(ellipse el)
+{/*<asyxml></code><documentation>Ellipse to conic section.</documentation></operator></asyxml>*/
+ conic oc;
+ if(abs(el.c) > epsgeo) {
+ real x = el.a^2/el.c;
+ point O = (el.F1 + el.F2)/2;
+ point A = O + x * unit(el.F1 - el.F2);
+ oc = conic(el.F1, perpendicular(A, line(el.F1, el.F2)), el.e);
+ } else {//The ellipse is a circle
+ coordsys R = coordsys(el);
+ point M = el.F1 + point(R, R.polar(el.a, 0));
+ line l = line(rotate(90, M) * el.F1, M);
+ oc = conic(el.F1, l, 0);
+ }
+ if(degenerate(el)) {
+ oc.p = infinity;
+ oc.h = infinity;
+ oc.l = new line[]{el.l};
+ }
+ return oc;
+}
+
+/*<asyxml><operator type = "conic" signature="cast(circle)"><code></asyxml>*/
+conic operator cast(circle c)
+{/*<asyxml></code><documentation>Circle to conic section.</documentation></operator></asyxml>*/
+ return (conic)((ellipse)c);
+}
+
+/*<asyxml><operator type = "circle" signature="cast(conic)"><code></asyxml>*/
+circle operator cast(conic c)
+{/*<asyxml></code><documentation>Conic section to circle.</documentation></operator></asyxml>*/
+ ellipse el = (ellipse)c;
+ circle oc;
+ if(abs(el.a - el.b) < epsgeo) {
+ oc = circle(el.C, el.a);
+ if(degenerate(c)) oc.l = c.l[0];
+ }
+ else abort("Can not cast this conic to a circle");
+ return oc;
+}
+
+/*<asyxml><operator type = "ellipse" signature="*(transform,ellipse)"><code></asyxml>*/
+ellipse operator *(transform t, ellipse el)
+{/*<asyxml></code><documentation>Provide transform * ellipse.</documentation></operator></asyxml>*/
+ if(!degenerate(el)) {
+ point[] ep;
+ for (int i = 0; i < 360; i += 72) {
+ ep.push(t * angpoint(el, i));
+ }
+ ellipse oe = ellipse(ep[0], ep[1], ep[2], ep[3], ep[4]);
+ if(angpoint(oe, 0) != ep[0]) return ellipse(oe.F2, oe.F1, oe.a);
+ return oe;
+ }
+ return ellipse(t * el.l.A, t * el.l.B, infinity);
+}
+
+/*<asyxml><operator type = "parabola" signature="*(transform,parabola)"><code></asyxml>*/
+parabola operator *(transform t, parabola p)
+{/*<asyxml></code><documentation>Provide transform * parabola.</documentation></operator></asyxml>*/
+ point[] P;
+ P.push(t * angpoint(p, 45));
+ P.push(t * angpoint(p, -45));
+ P.push(t * angpoint(p, 180));
+ parabola op = parabola(P[0], P[1], P[2], t * p.D);
+ op.bmin = p.bmin;
+ op.bmax = p.bmax;
+
+ return op;
+}
+
+/*<asyxml><operator type = "ellipse" signature="*(transform,circle)"><code></asyxml>*/
+ellipse operator *(transform t, circle c)
+{/*<asyxml></code><documentation>Provide transform * circle.
+ For example, 'circle C = scale(2) * circle' and 'ellipse E = xscale(2) * circle' are valid
+ but 'circle C = xscale(2) * circle' is invalid.</documentation></operator></asyxml>*/
+ return t * ((ellipse)c);
+}
+
+/*<asyxml><operator type = "hyperbola" signature="*(transform,hyperbola)"><code></asyxml>*/
+hyperbola operator *(transform t, hyperbola h)
+{/*<asyxml></code><documentation>Provide transform * hyperbola.</documentation></operator></asyxml>*/
+ if (t == identity()) {
+ return h;
+ }
+
+ point[] ep;
+ for (int i = 90; i <= 270; i += 45) {
+ ep.push(t * angpoint(h, i));
+ }
+
+ hyperbola oe = hyperbola(ep[0], ep[1], ep[2], ep[3], ep[4]);
+ if(angpoint(oe, 90) != ep[0]) {
+ oe = hyperbola(oe.F2, oe.F1, oe.a);
+ }
+
+ oe.bmin = h.bmin;
+ oe.bmax = h.bmax;
+
+ return oe;
+}
+
+/*<asyxml><operator type = "conic" signature="*(transform,conic)"><code></asyxml>*/
+conic operator *(transform t, conic co)
+{/*<asyxml></code><documentation>Provide transform * conic.</documentation></operator></asyxml>*/
+ if(co.e < 1) return (t * ((ellipse)co));
+ if(co.e == 1) return (t * ((parabola)co));
+ return (t * ((hyperbola)co));
+}
+
+/*<asyxml><operator type = "ellipse" signature="*(real,ellipse)"><code></asyxml>*/
+ellipse operator *(real x, ellipse el)
+{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(x, el.C) * el'.</documentation></operator></asyxml>*/
+ return degenerate(el) ? el : ellipse(el.C, x * el.a, x * el.b, el.angle);
+}
+
+/*<asyxml><operator type = "ellipse" signature="/(ellipse,real)"><code></asyxml>*/
+ellipse operator /(ellipse el, real x)
+{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(1/x, el.C) * el'.</documentation></operator></asyxml>*/
+ return degenerate(el) ? el : ellipse(el.C, el.a/x, el.b/x, el.angle);
+}
+
+/*<asyxml><function type="path" signature="arcfromcenter(ellipse,real,real,int,bool)"><code></asyxml>*/
+path arcfromcenter(ellipse el, real angle1, real angle2,
+ bool direction=CCW,
+ int n=ellipsenodesnumber(el.a,el.b,angle1,angle2,direction))
+{/*<asyxml></code><documentation>Return the path of the ellipse 'el' from angle1 to angle2 in degrees,
+ drawing in the given direction, with n nodes.
+ The angles are mesured relatively to the axis (C,x-axis) where C is
+ the center of the ellipse.</documentation></function></asyxml>*/
+ if(degenerate(el)) abort("arcfromcenter: can not convert degenerated ellipse to path.");
+ if (angle1 > angle2)
+ return reverse(arcfromcenter(el, angle2, angle1, !direction, n));
+
+ guide op;
+ coordsys Rp=coordsys(el);
+ if (n < 1) return op;
+
+ interpolate join = operator ..;
+ real stretch = max(el.a/el.b, el.b/el.a);
+
+ if (stretch > 10) {
+ n *= floor(stretch/5);
+ join = operator --;
+ }
+
+ real a1 = direction ? radians(angle1) : radians(angle2);
+ real a2 = direction ? radians(angle2) : radians(angle1) + 2 * pi;
+ real step=(a2 - a1)/(n != 1 ? n-1 : 1);
+ real a, r;
+ real da = radians(el.angle);
+
+ for (int i=0; i < n; ++i) {
+ a = a1 + i * step;
+ r = el.b/sqrt(1 - (el.e * cos(a))^2);
+ op = join(op, Rp*Rp.polar(r, da + a));
+ }
+
+ return shift(el.C.x*Rp.i + el.C.y*Rp.j) * (direction ? op : reverse(op));
+}
+
+/*<asyxml><function type="path" signature="arcfromcenter(hyperbola,real,real,int,bool)"><code></asyxml>*/
+path arcfromcenter(hyperbola h, real angle1, real angle2,
+ int n = hyperbolanodesnumber(h, angle1, angle2),
+ bool direction = CCW)
+{/*<asyxml></code><documentation>Return the path of the hyperbola 'h' from angle1 to angle2 in degrees,
+ drawing in the given direction, with n nodes.
+ The angles are mesured relatively to the axis (C, x-axis) where C is
+ the center of the hyperbola.</documentation></function></asyxml>*/
+ guide op;
+ coordsys Rp = coordsys(h);
+ if (n < 1) return op;
+ if (angle1 > angle2) {
+ path g = reverse(arcfromcenter(h, angle2, angle1, n, !direction));
+ return g == nullpath ? g : reverse(g);
+ }
+ real a1 = direction ? radians(angle1) : radians(angle2);
+ real a2 = direction ? radians(angle2) : radians(angle1) + 2 * pi;
+ real step = (a2 - a1)/(n != 1 ? n - 1 : 1);
+ real a, r;
+ typedef guide interpolate(... guide[]);
+ interpolate join = operator ..;
+ real da = radians(h.angle);
+ for (int i = 0; i < n; ++i) {
+ a = a1 + i * step;
+ r = (h.b * cos(a))^2 - (h.a * sin(a))^2;
+ if(r > epsgeo) {
+ r = sqrt(h.a^2 * h.b^2/r);
+ op = join(op, Rp * Rp.polar(r, a + da));
+ join = operator ..;
+ } else join = operator --;
+ }
+ return shift(h.C.x * Rp.i + h.C.y * Rp.j)*
+ (direction ? op : op == nullpath ? op : reverse(op));
+}
+
+/*<asyxml><function type="path" signature="arcfromcenter(explicit conic,real,real,int,bool)"><code></asyxml>*/
+path arcfromcenter(explicit conic co, real angle1, real angle2,
+ int n, bool direction = CCW)
+{/*<asyxml></code><documentation>Use arcfromcenter(ellipse, ...) or arcfromcenter(hyperbola, ...) depending of
+ the eccentricity of 'co'.</documentation></function></asyxml>*/
+ path g;
+ if(co.e < 1)
+ g = arcfromcenter((ellipse)co, angle1,
+ angle2, direction, n);
+ else if(co.e > 1)
+ g = arcfromcenter((hyperbola)co, angle1,
+ angle2, n, direction);
+ else abort("arcfromcenter: does not exist for a parabola.");
+ return g;
+}
+
+/*<asyxml><constant type = "polarconicroutine" signature="fromCenter"><code></asyxml>*/
+restricted polarconicroutine fromCenter = arcfromcenter;/*<asyxml></code><documentation></documentation></constant></asyxml>*/
+/*<asyxml><constant type = "polarconicroutine" signature="fromFocus"><code></asyxml>*/
+restricted polarconicroutine fromFocus = arcfromfocus;/*<asyxml></code><documentation></documentation></constant></asyxml>*/
+
+/*<asyxml><function type="bqe" signature="equation(ellipse)"><code></asyxml>*/
+bqe equation(ellipse el)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of the ellipse in its coordinate system:
+ bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0.
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ pair[] pts;
+ for (int i = 0; i < 360; i += 72)
+ pts.push(locate(angpoint(el, i)));
+
+ real[][] M;
+ real[] x;
+ for (int i = 0; i < 5; ++i) {
+ M[i] = new real[] {pts[i].x * pts[i].y, pts[i].y^2, pts[i].x, pts[i].y, 1};
+ x[i] = -pts[i].x^2;
+ }
+ real[] coef = solve(M, x);
+ bqe bqe = changecoordsys(coordsys(el),
+ bqe(defaultcoordsys,
+ 1, coef[0], coef[1], coef[2], coef[3], coef[4]));
+ bqe.a = approximate(bqe.a);
+ return bqe;
+}
+
+/*<asyxml><function type="bqe" signature="equation(parabola)"><code></asyxml>*/
+bqe equation(parabola p)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of the parabola in its coordinate system.
+ bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ coordsys R = canonicalcartesiansystem(p);
+ parabola tp = changecoordsys(R, p);
+ point A = projection(tp.D) * point(R, (0, 0));
+ real a = abs(A);
+ return changecoordsys(coordsys(p),
+ bqe(R, 0, 0, 1, -4 * a, 0, 0));
+}
+
+/*<asyxml><function type="bqe" signature="equation(hyperbola)"><code></asyxml>*/
+bqe equation(hyperbola h)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of the hyperbola in its coordinate system.
+ bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ coordsys R = canonicalcartesiansystem(h);
+ return changecoordsys(coordsys(h),
+ bqe(R, 1/h.a^2, 0, -1/h.b^2, 0, 0, -1));
+}
+
+/*<asyxml><operator type = "path" signature="cast(ellipse)"><code></asyxml>*/
+path operator cast(ellipse el)
+{/*<asyxml></code><documentation>Cast ellipse to path.</documentation></operator></asyxml>*/
+ if(degenerate(el))
+ abort("Casting degenerated ellipse to path is not possible.");
+ int n = el.e == 0 ? circlenodesnumber(el.a) : ellipsenodesnumber(el.a, el.b);
+ return arcfromcenter(el, 0.0, 360, CCW, n)&cycle;
+}
+
+/*<asyxml><operator type = "path" signature="cast(circle)"><code></asyxml>*/
+path operator cast(circle c)
+{/*<asyxml></code><documentation>Cast circle to path.</documentation></operator></asyxml>*/
+ return (path)((ellipse)c);
+}
+
+/*<asyxml><function type="real[]" signature="bangles(picture,parabola)"><code></asyxml>*/
+real[] bangles(picture pic = currentpicture, parabola p)
+{/*<asyxml></code><documentation>Return the array {ma, Ma} where 'ma' and 'Ma' are respectively
+ the smaller and the larger angles for which the parabola 'p' is included
+ in the bounding box of the picture 'pic'.</documentation></function></asyxml>*/
+ pair bmin, bmax;
+ pair[] b;
+ if (p.bmin == p.bmax) {
+ bmin = pic.userMin();
+ bmax = pic.userMax();
+ } else {
+ bmin = p.bmin;bmax = p.bmax;
+ }
+ if(bmin.x == bmax.x || bmin.y == bmax.y || !finite(abs(bmin)) || !finite(abs(bmax)))
+ return new real[] {0, 0};
+ b[0] = bmin;
+ b[1] = (bmax.x, bmin.y);
+ b[2] = bmax;
+ b[3] = (bmin.x, bmax.y);
+ real[] eq = changecoordsys(defaultcoordsys, equation(p)).a;
+ pair[] inter;
+ for (int i = 0; i < 4; ++i) {
+ pair[] tmp = intersectionpoints(b[i], b[(i + 1)%4], eq);
+ for (int j = 0; j < tmp.length; ++j) {
+ if(dot(b[i]-tmp[j], b[(i + 1)%4]-tmp[j]) <= epsgeo)
+ inter.push(tmp[j]);
+ }
+ }
+ pair F = p.F, V = p.V;
+ real d = degrees(F - V);
+ real[] a = sequence(new real(int n){
+ return (360 - d + degrees(inter[n]-F))%360;
+ }, inter.length);
+ real ma = a.length != 0 ? min(a) : 0, Ma= a.length != 0 ? max(a) : 0;
+ return new real[] {ma, Ma};
+}
+
+/*<asyxml><function type="real[][]" signature="bangles(picture,hyperbola)"><code></asyxml>*/
+real[][] bangles(picture pic = currentpicture, hyperbola h)
+{/*<asyxml></code><documentation>Return the array {{ma1, Ma1}, {ma2, Ma2}} where 'maX' and 'MaX' are respectively
+ the smaller and the bigger angles (from h.FX) for which the hyperbola 'h' is included
+ in the bounding box of the picture 'pic'.</documentation></function></asyxml>*/
+ pair bmin, bmax;
+ pair[] b;
+ if (h.bmin == h.bmax) {
+ bmin = pic.userMin();
+ bmax = pic.userMax();
+ } else {
+ bmin = h.bmin;bmax = h.bmax;
+ }
+ if(bmin.x == bmax.x || bmin.y == bmax.y || !finite(abs(bmin)) || !finite(abs(bmax)))
+ return new real[][] {{0, 0}, {0, 0}};
+ b[0] = bmin;
+ b[1] = (bmax.x, bmin.y);
+ b[2] = bmax;
+ b[3] = (bmin.x, bmax.y);
+ real[] eq = changecoordsys(defaultcoordsys, equation(h)).a;
+ pair[] inter0, inter1;
+ pair C = locate(h.C);
+ pair F1 = h.F1;
+ for (int i = 0; i < 4; ++i) {
+ pair[] tmp = intersectionpoints(b[i], b[(i + 1)%4], eq);
+ for (int j = 0; j < tmp.length; ++j) {
+ if(dot(b[i]-tmp[j], b[(i + 1)%4]-tmp[j]) <= epsgeo) {
+ if(dot(F1 - C, tmp[j]-C) > 0) inter0.push(tmp[j]);
+ else inter1.push(tmp[j]);
+ }
+ }
+ }
+ real d = degrees(F1 - C);
+ real[] ma, Ma;
+ pair[][] inter = new pair[][] {inter0, inter1};
+ for (int i = 0; i < 2; ++i) {
+ real[] a = sequence(new real(int n){
+ return (360 - d + degrees(inter[i][n]-F1))%360;
+ }, inter[i].length);
+ ma[i] = a.length != 0 ? min(a) : 0;
+ Ma[i] = a.length != 0 ? max(a) : 0;
+ }
+ return new real[][] {{ma[0], Ma[0]}, {ma[1], Ma[1]}};
+}
+
+/*<asyxml><operator type = "path" signature="cast(parabola)"><code></asyxml>*/
+path operator cast(parabola p)
+{/*<asyxml></code><documentation>Cast parabola to path.
+ If possible, the returned path is restricted to the actual bounding box
+ of the current picture if the variables 'p.bmin' and 'p.bmax' are not set else
+ the bounding box of box(p.bmin, p.bmax) is used instead.</documentation></operator></asyxml>*/
+ real[] bangles = bangles(p);
+ int n = parabolanodesnumber(p, bangles[0], bangles[1]);
+ return arcfromfocus(p, bangles[0], bangles[1], n, CCW);
+}
+
+
+/*<asyxml><function type="void" signature="draw(picture,Label,circle,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label L = "", circle c,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None, arrowbar bar = None,
+ margin margin = NoMargin, Label legend = "", marker marker = nomarker)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ if(degenerate(c)) draw(pic, L, c.l, align, p, arrow, legend, marker);
+ else draw(pic, L, (path)c, align, p, arrow, bar, margin, legend, marker);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,ellipse,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label L = "", ellipse el,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None, arrowbar bar = None,
+ margin margin = NoMargin, Label legend = "", marker marker = nomarker)
+{/*<asyxml></code><documentation></documentation>Draw the ellipse 'el' if it is not degenerated else draw 'el.l'.</function></asyxml>*/
+ if(degenerate(el)) draw(pic, L, el.l, align, p, arrow, legend, marker);
+ else draw(pic, L, (path)el, align, p, arrow, bar, margin, legend, marker);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,parabola,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label L = "", parabola parabola,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None, arrowbar bar = None,
+ margin margin = NoMargin, Label legend = "", marker marker = nomarker)
+{/*<asyxml></code><documentation>Draw the parabola 'p' on 'pic' without (if possible) altering the
+ size of picture pic.</documentation></function></asyxml>*/
+ pic.add(new void (frame f, transform t, transform T, pair m, pair M) {
+ // Reduce the bounds by the size of the pen and the margins.
+ m -= min(p); M -= max(p);
+ parabola.bmin = inverse(t) * m;
+ parabola.bmax = inverse(t) * M;
+ picture tmp;
+ path pp = t * ((path) (T * parabola));
+
+ if (pp != nullpath) {
+ draw(tmp, L, pp, align, p, arrow, bar, NoMargin, legend, marker);
+ add(f, tmp.fit());
+ }
+ }, true);
+
+ pair m = pic.userMin(), M = pic.userMax();
+ if(m != M) {
+ pic.addBox(truepoint(SW), truepoint(NE));
+ }
+}
+
+/*<asyxml><operator type = "path" signature="cast(hyperbola)"><code></asyxml>*/
+path operator cast(hyperbola h)
+{/*<asyxml></code><documentation>Cast hyperbola to path.
+ If possible, the returned path is restricted to the actual bounding box
+ of the current picture unless the variables 'h.bmin' and 'h.bmax'
+ are set; in this case the bounding box of box(h.bmin, h.bmax) is used instead.
+ Only the branch on the side of 'h.F1' is considered.</documentation></operator></asyxml>*/
+ real[][] bangles = bangles(h);
+ int n = hyperbolanodesnumber(h, bangles[0][0], bangles[0][1]);
+ return arcfromfocus(h, bangles[0][0], bangles[0][1], n, CCW);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,hyperbola,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label L = "", hyperbola h,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None, arrowbar bar = None,
+ margin margin = NoMargin, Label legend = "", marker marker = nomarker)
+{/*<asyxml></code><documentation>Draw the hyperbola 'h' on 'pic' without (if possible) altering the
+ size of the picture pic.</documentation></function></asyxml>*/
+ pic.add(new void (frame f, transform t, transform T, pair m, pair M) {
+ // Reduce the bounds by the size of the pen and the margins.
+ m -= min(p); M -= max(p);
+ h.bmin = inverse(t) * m;
+ h.bmax = inverse(t) * M;
+ path hp;
+
+ picture tmp;
+ hp = t * ((path) (T * h));
+ if (hp != nullpath) {
+ draw(tmp, L, hp, align, p, arrow, bar, NoMargin, legend, marker);
+ }
+
+ hyperbola ht = hyperbola(h.F2, h.F1, h.a);
+ ht.bmin = h.bmin;
+ ht.bmax = h.bmax;
+
+ hp = t * ((path) (T * ht));
+ if (hp != nullpath) {
+ draw(tmp, "", hp, align, p, arrow, bar, NoMargin, marker);
+ }
+
+ add(f, tmp.fit());
+ }, true);
+
+ pair m = pic.userMin(), M = pic.userMax();
+ if(m != M)
+ pic.addBox(truepoint(SW), truepoint(NE));
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,explicit conic,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label L = "", explicit conic co,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None, arrowbar bar = None,
+ margin margin = NoMargin, Label legend = "", marker marker = nomarker)
+{/*<asyxml></code><documentation>Use one of the routine 'draw(ellipse, ...)',
+ 'draw(parabola, ...)' or 'draw(hyperbola, ...)' depending of the value of eccentricity of 'co'.</documentation></function></asyxml>*/
+ if(co.e == 0)
+ draw(pic, L, (circle)co, align, p, arrow, bar, margin, legend, marker);
+ else
+ if(co.e < 1) draw(pic, L, (ellipse)co, align, p, arrow, bar, margin, legend, marker);
+ else
+ if(co.e == 1) draw(pic, L, (parabola)co, align, p, arrow, bar, margin, legend, marker);
+ else
+ if(co.e > 1) draw(pic, L, (hyperbola)co, align, p, arrow, bar, margin, legend, marker);
+ else abort("draw: unknown conic.");
+}
+
+/*<asyxml><function type="int" signature="conicnodesnumber(conic,real,real)"><code></asyxml>*/
+int conicnodesnumber(conic co, real angle1, real angle2, bool dir = CCW)
+{/*<asyxml></code><documentation>Return the number of node to draw a conic arc.</documentation></function></asyxml>*/
+ int oi;
+ if(co.e == 0) {
+ circle c = (circle)co;
+ oi = circlenodesnumber(c.r, angle1, angle2);
+ } else if(co.e < 1) {
+ ellipse el = (ellipse)co;
+ oi = ellipsenodesnumber(el.a, el.b, angle1, angle2, dir);
+ } else if(co.e == 1) {
+ parabola p = (parabola)co;
+ oi = parabolanodesnumber(p, angle1, angle2);
+ } else {
+ hyperbola h = (hyperbola)co;
+ oi = hyperbolanodesnumber(h, angle1, angle2);
+ }
+ return oi;
+}
+
+/*<asyxml><operator type = "path" signature="cast(conic)"><code></asyxml>*/
+path operator cast(conic co)
+{/*<asyxml></code><documentation>Cast conic section to path.</documentation></operator></asyxml>*/
+ if(co.e < 1) return (path)((ellipse)co);
+ if(co.e == 1) return (path)((parabola)co);
+ return (path)((hyperbola)co);
+}
+
+/*<asyxml><function type="bqe" signature="equation(explicit conic)"><code></asyxml>*/
+bqe equation(explicit conic co)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of conic section in its coordinate system:
+ bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0.
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ bqe obqe;
+ if(co.e == 0)
+ obqe = equation((circle)co);
+ else
+ if(co.e < 1) obqe = equation((ellipse)co);
+ else
+ if(co.e == 1) obqe = equation((parabola)co);
+ else
+ if(co.e > 1) obqe = equation((hyperbola)co);
+ else abort("draw: unknown conic.");
+ return obqe;
+}
+
+/*<asyxml><function type="string" signature="conictype(bqe)"><code></asyxml>*/
+string conictype(bqe bqe)
+{/*<asyxml></code><documentation>Returned values are "ellipse" or "parabola" or "hyperbola"
+ depending of the conic section represented by 'bqe'.</documentation></function></asyxml>*/
+ bqe lbqe = changecoordsys(defaultcoordsys, bqe);
+ string os = "degenerated";
+ real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5];
+ real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a);
+ if(abs(delta) < 10 * epsgeo) return os;
+ real J = a * c - b^2;
+ real I = a + c;
+ if(J > epsgeo) {
+ if(delta/I < -epsgeo);
+ os = "ellipse";
+ } else {
+ if(abs(J) < epsgeo) os = "parabola"; else os = "hyperbola";
+ }
+ return os;
+}
+
+/*<asyxml><function type="conic" signature="conic(point,point,point,point,point)"><code></asyxml>*/
+conic conic(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the conic passing through 'M1', 'M2', 'M3', 'M4' and 'M5' if the conic is not degenerated.</documentation></function></asyxml>*/
+ bqe bqe = bqe(M1, M2, M3, M4, M5);
+ string ct = conictype(bqe);
+ if(ct == "degenerated") abort("conic: degenerated conic passing through five points.");
+ if(ct == "ellipse") return ellipse(bqe);
+ if(ct == "parabola") return parabola(bqe);
+ return hyperbola(bqe);
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(hyperbola)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(explicit conic co)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e < 1) return canonicalcartesiansystem((ellipse)co);
+ else if(co.e == 1) return canonicalcartesiansystem((parabola)co);
+ return canonicalcartesiansystem((hyperbola)co);
+}
+
+/*<asyxml><function type="bqe" signature="canonical(bqe)"><code></asyxml>*/
+bqe canonical(bqe bqe)
+{/*<asyxml></code><documentation>Return the bivariate quadratic equation relative to the
+ canonical coordinate system of the conic section represented by 'bqe'.</documentation></function></asyxml>*/
+ string type = conictype(bqe);
+ if(type == "") abort("canonical: the equation can not be performed.");
+ bqe obqe;
+ if(type == "ellipse") {
+ ellipse el = ellipse(bqe);
+ obqe = changecoordsys(canonicalcartesiansystem(el), equation(el));
+ } else {
+ if(type == "parabola") {
+ parabola p = parabola(bqe);
+ obqe = changecoordsys(canonicalcartesiansystem(p), equation(p));
+ } else {
+ hyperbola h = hyperbola(bqe);
+ obqe = changecoordsys(canonicalcartesiansystem(h), equation(h));
+ }
+ }
+ return obqe;
+}
+
+/*<asyxml><function type="conic" signature="conic(bqe)"><code></asyxml>*/
+conic conic(bqe bqe)
+{/*<asyxml></code><documentation>Return the conic section represented by the bivariate quartic equation 'bqe'.</documentation></function></asyxml>*/
+ string type = conictype(bqe);
+ if(type == "") abort("canonical: the equation can not be performed.");
+ conic oc;
+ if(type == "ellipse") {
+ oc = ellipse(bqe);
+ } else {
+ if(type == "parabola") oc = parabola(bqe); else oc = hyperbola(bqe);
+ }
+ return oc;
+}
+
+/*<asyxml><function type="real" signature="arclength(circle)"><code></asyxml>*/
+real arclength(circle c)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return c.r * 2 * pi;
+}
+
+/*<asyxml><function type="real" signature="focusToCenter(ellipse,real)"><code></asyxml>*/
+real focusToCenter(ellipse el, real a)
+{/*<asyxml></code><documentation>Return the angle relatively to the center of 'el' for the angle 'a'
+ given relatively to the focus of 'el'.</documentation></function></asyxml>*/
+ pair p = point(fromFocus(el, a, a, 1, CCW), 0);
+ pair c = locate(el.C);
+ real d = degrees(p - c) - el.angle;
+ d = abs(d) < epsgeo ? 0 : d; // Avoid -1e-15
+ return d%(sgnd(a) * 360);
+}
+
+/*<asyxml><function type="real" signature="centerToFocus(ellipse,real)"><code></asyxml>*/
+real centerToFocus(ellipse el, real a)
+{/*<asyxml></code><documentation>Return the angle relatively to the focus of 'el' for the angle 'a'
+ given relatively to the center of 'el'.</documentation></function></asyxml>*/
+ pair P = point(fromCenter(el, a, a, 1, CCW), 0);
+ pair F1 = locate(el.F1);
+ pair F2 = locate(el.F2);
+ real d = degrees(P - F1) - degrees(F2 - F1);
+ d = abs(d) < epsgeo ? 0 : d; // Avoid -1e-15
+ return d%(sgnd(a) * 360);
+}
+
+/*<asyxml><function type="real" signature="arclength(ellipse)"><code></asyxml>*/
+real arclength(ellipse el)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return degenerate(el) ? infinity : 4 * el.a * elle(pi/2, el.e);
+}
+
+/*<asyxml><function type="real" signature="arclength(ellipse,real,real,bool,polarconicroutine)"><code></asyxml>*/
+real arclength(ellipse el, real angle1, real angle2,
+ bool direction = CCW,
+ polarconicroutine polarconicroutine = currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the length of the arc of the ellipse between 'angle1'
+ and 'angle2'.
+ 'angle1' and 'angle2' must be in the interval ]-360;+oo[ if polarconicroutine = fromFocus,
+ ]-oo;+oo[ if polarconicroutine = fromCenter.</documentation></function></asyxml>*/
+ if(degenerate(el)) return infinity;
+ if(angle1 > angle2) return arclength(el, angle2, angle1, !direction, polarconicroutine);
+ // path g;int n = 1000;
+ // if(el.e == 0) g = arcfromcenter(el, angle1, angle2, n, direction);
+ // if(el.e != 1) g = polarconicroutine(el, angle1, angle2, n, direction);
+ // write("with path = ", arclength(g));
+ if(polarconicroutine == fromFocus) {
+ // dot(point(fromFocus(el, angle1, angle1, 1, CCW), 0), 2mm + blue);
+ // dot(point(fromFocus(el, angle2, angle2, 1, CCW), 0), 2mm + blue);
+ // write("fromfocus1 = ", angle1);
+ // write("fromfocus2 = ", angle2);
+ real gle1 = focusToCenter(el, angle1);
+ real gle2 = focusToCenter(el, angle2);
+ if((gle1 - gle2) * (angle1 - angle2) > 0) {
+ angle1 = gle1; angle2 = gle2;
+ } else {
+ angle1 = gle2; angle2 = gle1;
+ }
+ // dot(point(fromCenter(el, angle1, angle1, 1, CCW), 0), 1mm + red);
+ // dot(point(fromCenter(el, angle2, angle2, 1, CCW), 0), 1mm + red);
+ // write("fromcenter1 = ", angle1);
+ // write("fromcenter2 = ", angle2);
+ }
+ if(angle1 < 0 || angle2 < 0) return arclength(el, 180 + angle1, 180 + angle2, direction, fromCenter);
+ real a1 = direction ? angle1 : angle2;
+ real a2 = direction ? angle2 : angle1 + 360;
+ real elleq = el.a * elle(pi/2, el.e);
+ real S(real a)
+ {//Return the arclength from 0 to the angle 'a' (in degrees)
+ // given form the center of the ellipse.
+ real gle = atan(el.a * tan(radians(a))/el.b)+
+ pi * (((a%90 == 0 && a != 0) ? floor(a/90) - 1 : floor(a/90)) -
+ ((a%180 == 0) ? 0 : floor(a/180)) -
+ (a%360 == 0 ? floor(a/(360)) : 0));
+ /* // Uncomment to visualize the used branches
+ unitsize(2cm, 1cm);
+ import graph;
+
+ real xmin = 0, xmax = 3pi;
+
+ xlimits( xmin, xmax);
+ ylimits( 0, 10);
+ yaxis( "y" , LeftRight(), RightTicks(pTick=.8red, ptick = lightgrey, extend = true));
+ xaxis( "x - value", BottomTop(), Ticks(Label("$%.2f$", red), Step = pi/2, step = pi/4, pTick=.8red, ptick = lightgrey, extend = true));
+
+ real p2 = pi/2;
+ real f(real t)
+ {
+ return atan(0.6 * tan(t))+
+ pi * ((t%p2 == 0 && t != 0) ? floor(t/p2) - 1 : floor(t/p2)) -
+ ((t%pi == 0) ? 0 : pi * floor(t/pi)) - (t%(2pi) == 0 ? pi * floor(t/(2 * pi)) : 0);
+ }
+
+ draw(graph(f, xmin, xmax, 100));
+ write(degrees(f(pi/2)));
+ write(degrees(f(pi)));
+ write(degrees(f(3pi/2)));
+ write(degrees(f(2pi)));
+ draw(graph(new real(real t){return t;}, xmin, xmax, 3));
+ */
+ return elleq - el.a * elle(pi/2 - gle, el.e);
+ }
+ return S(a2) - S(a1);
+}
+
+/*<asyxml><function type="real" signature="arclength(parabola,real)"><code></asyxml>*/
+real arclength(parabola p, real angle)
+{/*<asyxml></code><documentation>Return the arclength from 180 to 'angle' given from focus in the
+ canonical coordinate system of 'p'.</documentation></function></asyxml>*/
+ real a = p.a; /* In canonicalcartesiansystem(p) the equation of p
+ is x = y^2/(4a) */
+ // integrate(sqrt(1 + (x/(2 * a))^2), x);
+ real S(real t){return 0.5 * t * sqrt(1 + t^2/(4 * a^2)) + a * asinh(t/(2 * a));}
+ real R(real gle){return 2 * a/(1 - Cos(gle));}
+ real t = Sin(angle) * R(angle);
+ return S(t);
+}
+
+/*<asyxml><function type="real" signature="arclength(parabola,real,real)"><code></asyxml>*/
+real arclength(parabola p, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the arclength from 'angle1' to 'angle2' given from
+ focus in the canonical coordinate system of 'p'</documentation></function></asyxml>*/
+ return arclength(p, angle1) - arclength(p, angle2);
+}
+
+/*<asyxml><function type="real" signature="arclength(parabola p)"><code></asyxml>*/
+real arclength(parabola p)
+{/*<asyxml></code><documentation>Return the length of the arc of the parabola bounded to the bounding
+ box of the current picture.</documentation></function></asyxml>*/
+ real[] b = bangles(p);
+ return arclength(p, b[0], b[1]);
+}
+// *........................CONICS.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.......................ABSCISSA........................*
+/*<asyxml><struct signature="abscissa"><code></asyxml>*/
+struct abscissa
+{/*<asyxml></code><documentation>Provide abscissa structure on a curve used in the routine-like 'point(object, abscissa)'
+ where object can be 'line','segment','ellipse','circle','conic'...</documentation><property type = "real" signature="x"><code></asyxml>*/
+ real x;/*<asyxml></code><documentation>The abscissa value.</documentation></property><property type = "int" signature="system"><code></asyxml>*/
+ int system;/*<asyxml></code><documentation>0 = relativesystem; 1 = curvilinearsystem; 2 = angularsystem; 3 = nodesystem</documentation></property><property type = "polarconicroutine" signature="polarconicroutine"><code></asyxml>*/
+ polarconicroutine polarconicroutine = fromCenter;/*<asyxml></code><documentation>The routine used with angular system and two foci conic section.
+ Possible values are 'formCenter' and 'formFocus'.</documentation></property></asyxml>*/
+ /*<asyxml><method type = "abscissa" signature="copy()"><code></asyxml>*/
+ abscissa copy()
+ {/*<asyxml></code><documentation>Return a copy of this abscissa.</documentation></method></asyxml>*/
+ abscissa oa = new abscissa;
+ oa.x = this.x;
+ oa.system = this.system;
+ oa.polarconicroutine = this.polarconicroutine;
+ return oa;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><constant type = "int" signature="relativesystem,curvilinearsystem,angularsystem,nodesystem"><code></asyxml>*/
+restricted int relativesystem = 0, curvilinearsystem = 1, angularsystem = 2, nodesystem = 3;/*<asyxml></code><documentation>Constant used to set the abscissa system.</documentation></constant></asyxml>*/
+
+/*<asyxml><operator type = "abscissa" signature="cast(explicit position)"><code></asyxml>*/
+abscissa operator cast(explicit position position)
+{/*<asyxml></code><documentation>Cast position to abscissa.
+ If 'position' is relative, the abscissa is relative else it's a curvilinear abscissa.</documentation></operator></asyxml>*/
+ abscissa oarcc;
+ oarcc.x = position.position.x;
+ oarcc.system = position.relative ? relativesystem : curvilinearsystem;
+ return oarcc;
+}
+
+/*<asyxml><operator type = "abscissa" signature="+(real,explicit abscissa)"><code></asyxml>*/
+abscissa operator +(real x, explicit abscissa a)
+{/*<asyxml></code><documentation>Provide 'real + abscissa'.
+ Return abscissa b so that b.x = a.x + x.
+ +(explicit abscissa, real), -(real, explicit abscissa) and -(explicit abscissa, real) are also defined.</documentation></operator></asyxml>*/
+ abscissa oa = a.copy();
+ oa.x = a.x + x;
+ return oa;
+}
+
+abscissa operator +(explicit abscissa a, real x)
+{
+ return x + a;
+}
+abscissa operator +(int x, explicit abscissa a)
+{
+ return ((real)x) + a;
+}
+
+/*<asyxml><operator type = "abscissa" signature="-(explicit abscissa a)"><code></asyxml>*/
+abscissa operator -(explicit abscissa a)
+{/*<asyxml></code><documentation>Return the abscissa b so that b.x = -a.x.</documentation></operator></asyxml>*/
+ abscissa oa;
+ oa.system = a.system;
+ oa.x = -a.x;
+ return oa;
+}
+
+abscissa operator -(real x, explicit abscissa a)
+{
+ abscissa oa;
+ oa.system = a.system;
+ oa.x = x - a.x;
+ return oa;
+}
+abscissa operator -(explicit abscissa a, real x)
+{
+ abscissa oa;
+ oa.system = a.system;
+ oa.x = a.x - x;
+ return oa;
+}
+abscissa operator -(int x, explicit abscissa a)
+{
+ return ((real)x) - a;
+}
+
+/*<asyxml><operator type = "abscissa" signature="*(real,abscissa)"><code></asyxml>*/
+abscissa operator *(real x, explicit abscissa a)
+{/*<asyxml></code><documentation>Provide 'real * abscissa'.
+ Return abscissa b so that b.x = x * a.x.
+ *(explicit abscissa, real), /(real, explicit abscissa) and /(explicit abscissa, real) are also defined.</documentation></operator></asyxml>*/
+ abscissa oa;
+ oa.system = a.system;
+ oa.x = a.x * x;
+ return oa;
+}
+abscissa operator *(explicit abscissa a, real x)
+{
+ return x * a;
+}
+
+abscissa operator /(real x, explicit abscissa a)
+{
+ abscissa oa;
+ oa.system = a.system;
+ oa.x = x/a.x;
+ return oa;
+}
+abscissa operator /(explicit abscissa a, real x)
+{
+ abscissa oa;
+ oa.system = a.system;
+ oa.x = a.x/x;
+ return oa;
+}
+
+abscissa operator /(int x, explicit abscissa a)
+{
+ return ((real)x)/a;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(real)"><code></asyxml>*/
+abscissa relabscissa(real x)
+{/*<asyxml></code><documentation>Return a relative abscissa.</documentation></function></asyxml>*/
+ return (abscissa)(Relative(x));
+}
+abscissa relabscissa(int x)
+{
+ return (abscissa)(Relative(x));
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(real)"><code></asyxml>*/
+abscissa curabscissa(real x)
+{/*<asyxml></code><documentation>Return a curvilinear abscissa.</documentation></function></asyxml>*/
+ return (abscissa)((position)x);
+}
+abscissa curabscissa(int x)
+{
+ return (abscissa)((position)x);
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(real,polarconicroutine)"><code></asyxml>*/
+abscissa angabscissa(real x, polarconicroutine polarconicroutine = currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return a angular abscissa.</documentation></function></asyxml>*/
+ abscissa oarcc;
+ oarcc.x = x;
+ oarcc.polarconicroutine = polarconicroutine;
+ oarcc.system = angularsystem;
+ return oarcc;
+}
+abscissa angabscissa(int x, polarconicroutine polarconicroutine = currentpolarconicroutine)
+{
+ return angabscissa((real)x, polarconicroutine);
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(real)"><code></asyxml>*/
+abscissa nodabscissa(real x)
+{/*<asyxml></code><documentation>Return an abscissa as time on the path.</documentation></function></asyxml>*/
+ abscissa oarcc;
+ oarcc.x = x;
+ oarcc.system = nodesystem;
+ return oarcc;
+}
+abscissa nodabscissa(int x)
+{
+ return nodabscissa((real)x);
+}
+
+/*<asyxml><operator type = "abscissa" signature="cast(real)"><code></asyxml>*/
+abscissa operator cast(real x)
+{/*<asyxml></code><documentation>Cast real to abscissa, precisely 'nodabscissa'.</documentation></operator></asyxml>*/
+ return nodabscissa(x);
+}
+abscissa operator cast(int x)
+{
+ return nodabscissa((real)x);
+}
+
+/*<asyxml><function type="point" signature="point(circle,abscissa)"><code></asyxml>*/
+point point(circle c, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'c' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ coordsys R = c.C.coordsys;
+ if (l.system == nodesystem)
+ return point(R, point((path)c, l.x)/R);
+ if (l.system == relativesystem)
+ return c.C + point(R, R.polar(c.r, 2 * pi * l.x));
+ if (l.system == curvilinearsystem)
+ return c.C + point(R, R.polar(c.r, l.x/c.r));
+ if (l.system == angularsystem)
+ return c.C + point(R, R.polar(c.r, radians(l.x)));
+ abort("point: bad abscissa system.");
+ return (0, 0);
+}
+
+/*<asyxml><function type="point" signature="point(ellipse,abscissa)"><code></asyxml>*/
+point point(ellipse el, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'el' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ if(el.e == 0) return point((circle)el, l);
+ coordsys R = coordsys(el);
+ if (l.system == nodesystem)
+ return point(R, point((path)el, l.x)/R);
+ if (l.system == relativesystem) {
+ return point(el, curabscissa((l.x%1) * arclength(el)));
+ }
+ if (l.system == curvilinearsystem) {
+ real a1 = 0, a2 = 360, cx = 0;
+ real aout = a1;
+ real x = abs(l.x)%arclength(el);
+ while (abs(cx - x) > epsgeo) {
+ aout = (a1 + a2)/2;
+ cx = arclength(el, 0, aout, CCW, fromCenter); //fromCenter is speeder
+ if(cx > x) a2 = (a1 + a2)/2; else a1 = (a1 + a2)/2;
+ }
+ path pel = fromCenter(el, sgn(l.x) * aout, sgn(l.x) * aout, 1, CCW);
+ return point(R, point(pel, 0)/R);
+ }
+ if (l.system == angularsystem) {
+ return point(R, point(l.polarconicroutine(el, l.x, l.x, 1, CCW), 0)/R);
+ }
+ abort("point: bad abscissa system.");
+ return (0, 0);
+}
+
+/*<asyxml><function type="point" signature="point(parabola,abscissa)"><code></asyxml>*/
+point point(parabola p, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'p' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ coordsys R = coordsys(p);
+ if (l.system == nodesystem)
+ return point(R, point((path)p, l.x)/R);
+ if (l.system == relativesystem) {
+ real[] b = bangles(p);
+ real al = sgn(l.x) > 0 ? arclength(p, 180, b[1]) : arclength(p, 180, b[0]);
+ return point(p, curabscissa(abs(l.x) * al));
+ }
+ if (l.system == curvilinearsystem) {
+ real a1 = 1e-3, a2 = 360 - 1e-3, cx = infinity;
+ while (abs(cx - l.x) > epsgeo) {
+ cx = arclength(p, 180, (a1 + a2)/2);
+ if(cx > l.x) a2 = (a1 + a2)/2; else a1 = (a1 + a2)/2;
+ }
+ path pp = fromFocus(p, a1, a1, 1, CCW);
+ return point(R, point(pp, 0)/R);
+ }
+ if (l.system == angularsystem) {
+ return point(R, point(fromFocus(p, l.x, l.x, 1, CCW), 0)/R);
+ }
+ abort("point: bad abscissa system.");
+ return (0, 0);
+}
+
+/*<asyxml><function type="point" signature="point(hyperbola,abscissa)"><code></asyxml>*/
+point point(hyperbola h, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'h' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ coordsys R = coordsys(h);
+ if (l.system == nodesystem)
+ return point(R, point((path)h, l.x)/R);
+ if (l.system == relativesystem) {
+ abort("point(hyperbola, relativeSystem) is not implemented...
+Try relpoint((path)your_hyperbola, x);");
+ }
+ if (l.system == curvilinearsystem) {
+ abort("point(hyperbola, curvilinearSystem) is not implemented...");
+ }
+ if (l.system == angularsystem) {
+ return point(R, point(l.polarconicroutine(h, l.x, l.x, 1, CCW), 0)/R);
+ }
+ abort("point: bad abscissa system.");
+ return (0, 0);
+}
+
+/*<asyxml><function type="abscissa" signature="point(conic,point)"><code></asyxml>*/
+point point(explicit conic co, abscissa l)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e == 0) return point((circle)co, l);
+ if(co.e < 1) return point((ellipse)co, l);
+ if(co.e == 1) return point((parabola)co, l);
+ return point((hyperbola)co, l);
+}
+
+
+/*<asyxml><function type="point" signature="point(line,abscissa)"><code></asyxml>*/
+point point(line l, abscissa x)
+{/*<asyxml></code><documentation>Return the point of 'l' which has the abscissa 'l.x' according to the abscissa system 'l.system'.
+ Note that the origin is l.A, and point(l, relabscissa(x)) returns l.A + x.x * vector(l.B - l.A).</documentation></function></asyxml>*/
+ coordsys R = l.A.coordsys;
+ if (x.system == nodesystem)
+ return l.A + (x.x < 0 ? 0 : x.x > 1 ? 1 : x.x) * vector(l.B - l.A);
+ if (x.system == relativesystem)
+ return l.A + x.x * vector(l.B - l.A);
+ if (x.system == curvilinearsystem)
+ return l.A + x.x * l.u;
+ if (x.system == angularsystem)
+ abort("point: what the meaning of angular abscissa on line ?.");
+ abort("point: bad abscissa system.");
+ return (0, 0);
+}
+
+/*<asyxml><function type="point" signature="point(line,real)"><code></asyxml>*/
+point point(line l, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node l.A and l.B (x <= 0 means l.A, x >=1 means l.B).</documentation></function></asyxml>*/
+ return point(l, nodabscissa(x));
+}
+point point(line l, explicit int x)
+{
+ return point(l, nodabscissa(x));
+}
+
+/*<asyxml><function type="circle" signature="point(explicit circle,explicit real)"><code></asyxml>*/
+point point(explicit circle c, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/
+ return point(c, nodabscissa(x));
+}
+point point(explicit circle c, explicit int x)
+{
+ return point(c, nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit ellipse,explicit real)"><code></asyxml>*/
+point point(explicit ellipse el, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/
+ return point(el, nodabscissa(x));
+}
+point point(explicit ellipse el, explicit int x)
+{
+ return point(el, nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit parabola,explicit real)"><code></asyxml>*/
+point point(explicit parabola p, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/
+ return point(p, nodabscissa(x));
+}
+point point(explicit parabola p, explicit int x)
+{
+ return point(p, nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit hyperbola,explicit real)"><code></asyxml>*/
+point point(explicit hyperbola h, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/
+ return point(h, nodabscissa(x));
+}
+point point(explicit hyperbola h, explicit int x)
+{
+ return point(h, nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit conic,explicit real)"><code></asyxml>*/
+point point(explicit conic co, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/
+ point op;
+ if(co.e == 0) op = point((circle)co, nodabscissa(x));
+ else if(co.e < 1) op = point((ellipse)co, nodabscissa(x));
+ else if(co.e == 1) op = point((parabola)co, nodabscissa(x));
+ else op = point((hyperbola)co, nodabscissa(x));
+ return op;
+}
+point point(explicit conic co, explicit int x)
+{
+ return point(co, (real)x);
+}
+
+/*<asyxml><function type="point" signature="relpoint(line,real)"><code></asyxml>*/
+point relpoint(line l, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'l' (0 means l.A,
+ 1 means l.B, x means l.A + x * vector(l.B - l.A) ).</documentation></function></asyxml>*/
+ return point(l, Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit circle,real)"><code></asyxml>*/
+point relpoint(explicit circle c, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'c' (0 means origin, 1 means end).
+ Origin is c.center + c.r * (1, 0).</documentation></function></asyxml>*/
+ return point(c, Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit ellipse,real)"><code></asyxml>*/
+point relpoint(explicit ellipse el, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'el' (0 means origin, 1 means end).</documentation></function></asyxml>*/
+ return point(el, Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit parabola,real)"><code></asyxml>*/
+point relpoint(explicit parabola p, real x)
+{/*<asyxml></code><documentation>Return the relative point of the path of the parabola
+ bounded by the bounding box of the current picture.
+ 0 means origin, 1 means end, where the origin is the vertex of 'p'.</documentation></function></asyxml>*/
+ return point(p, Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit hyperbola,real)"><code></asyxml>*/
+point relpoint(explicit hyperbola h, real x)
+{/*<asyxml></code><documentation>Not yet implemented... <look href = "point(hyperbola, abscissa)"/></documentation></function></asyxml>*/
+ return point(h, Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit conic,explicit real)"><code></asyxml>*/
+point relpoint(explicit conic co, explicit real x)
+{/*<asyxml></code><documentation>Return the relative point of 'co' (0 means origin, 1 means end).</documentation></function></asyxml>*/
+ point op;
+ if(co.e == 0) op = point((circle)co, Relative(x));
+ else if(co.e < 1) op = point((ellipse)co, Relative(x));
+ else if(co.e == 1) op = point((parabola)co, Relative(x));
+ else op = point((hyperbola)co, Relative(x));
+ return op;
+}
+point relpoint(explicit conic co, explicit int x)
+{
+ return relpoint(co, (real)x);
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit circle,real)"><code></asyxml>*/
+point angpoint(explicit circle c, real x)
+{/*<asyxml></code><documentation>Return the point of 'c' in the direction 'x' measured in degrees.</documentation></function></asyxml>*/
+ return point(c, angabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit ellipse,real,polarconicroutine)"><code></asyxml>*/
+point angpoint(explicit ellipse el, real x,
+ polarconicroutine polarconicroutine = currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the point of 'el' in the direction 'x'
+ measured in degrees according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ return el.e == 0 ? angpoint((circle) el, x) : point(el, angabscissa(x, polarconicroutine));
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit parabola,real)"><code></asyxml>*/
+point angpoint(explicit parabola p, real x)
+{/*<asyxml></code><documentation>Return the point of 'p' in the direction 'x' measured in degrees.</documentation></function></asyxml>*/
+ return point(p, angabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit hyperbola,real,polarconicroutine)"><code></asyxml>*/
+point angpoint(explicit hyperbola h, real x,
+ polarconicroutine polarconicroutine = currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the point of 'h' in the direction 'x'
+ measured in degrees according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ return point(h, angabscissa(x, polarconicroutine));
+}
+
+/*<asyxml><function type="point" signature="curpoint(line,real)"><code></asyxml>*/
+point curpoint(line l, real x)
+{/*<asyxml></code><documentation>Return the point of 'l' which has the curvilinear abscissa 'x'.
+ Origin is l.A.</documentation></function></asyxml>*/
+ return point(l, curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(explicit circle,real)"><code></asyxml>*/
+point curpoint(explicit circle c, real x)
+{/*<asyxml></code><documentation>Return the point of 'c' which has the curvilinear abscissa 'x'.
+ Origin is c.center + c.r * (1, 0).</documentation></function></asyxml>*/
+ return point(c, curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(explicit ellipse,real)"><code></asyxml>*/
+point curpoint(explicit ellipse el, real x)
+{/*<asyxml></code><documentation>Return the point of 'el' which has the curvilinear abscissa 'el'.</documentation></function></asyxml>*/
+ return point(el, curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(explicit parabola,real)"><code></asyxml>*/
+point curpoint(explicit parabola p, real x)
+{/*<asyxml></code><documentation>Return the point of 'p' which has the curvilinear abscissa 'x'.
+ Origin is the vertex of 'p'.</documentation></function></asyxml>*/
+ return point(p, curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(conic,real)"><code></asyxml>*/
+point curpoint(conic co, real x)
+{/*<asyxml></code><documentation>Return the point of 'co' which has the curvilinear abscissa 'x'.</documentation></function></asyxml>*/
+ point op;
+ if(co.e == 0) op = point((circle)co, curabscissa(x));
+ else if(co.e < 1) op = point((ellipse)co, curabscissa(x));
+ else if(co.e == 1) op = point((parabola)co, curabscissa(x));
+ else op = point((hyperbola)co, curabscissa(x));
+ return op;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(circle,point)"><code></asyxml>*/
+abscissa angabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("angabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system = angularsystem;
+ oa.x = degrees(M - c.C);
+ if(oa.x < 0) oa.x+=360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(ellipse,point,polarconicroutine)"><code></asyxml>*/
+abscissa angabscissa(ellipse el, point M,
+ polarconicroutine polarconicroutine = currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the ellipse 'el' according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("angabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system = angularsystem;
+ oa.polarconicroutine = polarconicroutine;
+ oa.x = polarconicroutine == fromCenter ? degrees(M - el.C) : degrees(M - el.F1);
+ oa.x -= el.angle;
+ if(oa.x < 0) oa.x += 360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(hyperbola,point,polarconicroutine)"><code></asyxml>*/
+abscissa angabscissa(hyperbola h, point M,
+ polarconicroutine polarconicroutine = currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the hyperbola 'h' according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ if(!(M @ h)) abort("angabscissa: the point is not on the hyperbola.");
+ abscissa oa;
+ oa.system = angularsystem;
+ oa.polarconicroutine = polarconicroutine;
+ oa.x = polarconicroutine == fromCenter ? degrees(M - h.C) : degrees(M - h.F1) + 180;
+ oa.x -= h.angle;
+ if(oa.x < 0) oa.x += 360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(parabola,point)"><code></asyxml>*/
+abscissa angabscissa(parabola p, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the parabola 'p'.</documentation></function></asyxml>*/
+ if(!(M @ p)) abort("angabscissa: the point is not on the parabola.");
+ abscissa oa;
+ oa.system = angularsystem;
+ oa.polarconicroutine = fromFocus;// Not used
+ oa.x = degrees(M - p.F);
+ oa.x -= p.angle;
+ if(oa.x < 0) oa.x += 360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(conic,point)"><code></asyxml>*/
+abscissa angabscissa(explicit conic co, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e == 0) return angabscissa((circle)co, M);
+ if(co.e < 1) return angabscissa((ellipse)co, M);
+ if(co.e == 1) return angabscissa((parabola)co, M);
+ return angabscissa((hyperbola)co, M);
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(line,point)"><code></asyxml>*/
+abscissa curabscissa(line l, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/
+ if(!(M @ extend(l))) abort("curabscissa: the point is not on the line.");
+ abscissa oa;
+ oa.system = curvilinearsystem;
+ oa.x = sgn(dot(M - l.A, l.B - l.A)) * abs(M - l.A);
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(circle,point)"><code></asyxml>*/
+abscissa curabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("curabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system = curvilinearsystem;
+ oa.x = pi * angabscissa(c, M).x * c.r/180;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(ellipse,point)"><code></asyxml>*/
+abscissa curabscissa(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("curabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system = curvilinearsystem;
+ real a = angabscissa(el, M, fromCenter).x;
+ oa.x = arclength(el, 0, a, fromCenter);
+ oa.polarconicroutine = fromCenter;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(parabola,point)"><code></asyxml>*/
+abscissa curabscissa(parabola p, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the parabola 'p'.</documentation></function></asyxml>*/
+ if(!(M @ p)) abort("curabscissa: the point is not on the parabola.");
+ abscissa oa;
+ oa.system = curvilinearsystem;
+ real a = angabscissa(p, M).x;
+ oa.x = arclength(p, 180, a);
+ oa.polarconicroutine = fromFocus; // Not used.
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(conic,point)"><code></asyxml>*/
+abscissa curabscissa(conic co, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e > 1) abort("curabscissa: not implemented for this hyperbola.");
+ if(co.e == 0) return curabscissa((circle)co, M);
+ if(co.e < 1) return curabscissa((ellipse)co, M);
+ return curabscissa((parabola)co, M);
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(line,point)"><code></asyxml>*/
+abscissa nodabscissa(line l, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/
+ if(!(M @ (segment)l)) abort("nodabscissa: the point is not on the segment.");
+ abscissa oa;
+ oa.system = nodesystem;
+ oa.x = abs(M - l.A)/abs(l.A - l.B);
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(circle,point)"><code></asyxml>*/
+abscissa nodabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("nodabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system = nodesystem;
+ oa.x = intersect((path)c, locate(M))[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(ellipse,point)"><code></asyxml>*/
+abscissa nodabscissa(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("nodabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system = nodesystem;
+ oa.x = intersect((path)el, M)[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(parabola,point)"><code></asyxml>*/
+abscissa nodabscissa(parabola p, point M)
+{/*<asyxml></code><documentation>Return the node abscissa OF 'M' on the parabola 'p'.</documentation></function></asyxml>*/
+ if(!(M @ p)) abort("nodabscissa: the point is not on the parabola.");
+ abscissa oa;
+ oa.system = nodesystem;
+ path pg = p;
+ real[] t = intersect(pg, M, 1e-5);
+ if(t.length == 0) abort("nodabscissa: the point is not on the path of the parabola.");
+ oa.x = t[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(conic,point)"><code></asyxml>*/
+abscissa nodabscissa(conic co, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e > 1) abort("nodabscissa: not implemented for hyperbola.");
+ if(co.e == 0) return nodabscissa((circle)co, M);
+ if(co.e < 1) return nodabscissa((ellipse)co, M);
+ return nodabscissa((parabola)co, M);
+}
+
+
+/*<asyxml><function type="abscissa" signature="relabscissa(line,point)"><code></asyxml>*/
+abscissa relabscissa(line l, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/
+ if(!(M @ extend(l))) abort("relabscissa: the point is not on the line.");
+ abscissa oa;
+ oa.system = relativesystem;
+ oa.x = sgn(dot(M - l.A, l.B - l.A)) * abs(M - l.A)/abs(l.A - l.B);
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(circle,point)"><code></asyxml>*/
+abscissa relabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("relabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system = relativesystem;
+ oa.x = angabscissa(c, M).x/360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(ellipse,point)"><code></asyxml>*/
+abscissa relabscissa(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("relabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system = relativesystem;
+ oa.x = curabscissa(el, M).x/arclength(el);
+ oa.polarconicroutine = fromFocus;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(conic,point)"><code></asyxml>*/
+abscissa relabscissa(conic co, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M'
+ on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e > 1) abort("relabscissa: not implemented for hyperbola and parabola.");
+ if(co.e == 1) return relabscissa((parabola)co, M);
+ if(co.e == 0) return relabscissa((circle)co, M);
+ return relabscissa((ellipse)co, M);
+}
+// *.......................ABSCISSA........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.........................ARCS..........................*
+/*<asyxml><struct signature="arc"><code></asyxml>*/
+struct arc {
+ /*<asyxml></code><documentation>Implement oriented ellipse (included circle) arcs.
+ All the calculus with this structure will be as exact as Asymptote can do.
+ For a full precision, you must not cast 'arc' to 'path' excepted for drawing routines.
+ </documentation><property type = "ellipse" signature="el"><code></asyxml>*/
+ ellipse el;/*<asyxml></code><documentation>The support of the arc.</documentation></property><property type = "real" signature="angle0"><code></asyxml>*/
+ restricted real angle0 = 0;/*<asyxml></code><documentation>Internal use: rotating a circle does not modify the origin point,this variable stocks the eventual angle rotation. This value is not used for ellipses which are not circles.</documentation></property><property type = "real" signature="angle1,angle2"><code></asyxml>*/
+ restricted real angle1, angle2;/*<asyxml></code><documentation>Values (in degrees) in ]-360, 360[.</documentation></property><property type = "bool" signature="direction"><code></asyxml>*/
+ bool direction = CCW;/*<asyxml></code><documentation>The arc will be drawn from 'angle1' to 'angle2' rotating in the direction 'direction'.</documentation></property><property type = "polarconicroutine" signature="polarconicroutine"><code></asyxml>*/
+ polarconicroutine polarconicroutine = currentpolarconicroutine;/*<asyxml></code><documentation>The routine to which the angles refer.
+ If 'el' is a circle 'fromCenter' is always used.</documentation></property></asyxml>*/
+
+ /*<asyxml><method type = "void" signature="setangles(real,real,real)"><code></asyxml>*/
+ void setangles(real a0, real a1, real a2)
+ {/*<asyxml></code><documentation>Set the angles.</documentation></method></asyxml>*/
+ if (a1 < 0 && a2 < 0) {
+ a1 += 360;
+ a2 += 360;
+ }
+ this.angle0 = a0%(sgnd(a0) * 360);
+ this.angle1 = a1%(sgnd(a1) * 360);
+ this.angle2 = a2%(sgnd(2) * 360);
+ }
+
+ /*<asyxml><method type = "void" signature="init(ellipse,real,real,real,polarconicroutine,bool)"><code></asyxml>*/
+ void init(ellipse el, real angle0 = 0, real angle1, real angle2,
+ polarconicroutine polarconicroutine,
+ bool direction = CCW)
+ {/*<asyxml></code><documentation>Constructor.</documentation></method></asyxml>*/
+ if(abs(angle1 - angle2) > 360) abort("arc: |angle1 - angle2| > 360.");
+ this.el = el;
+ this.setangles(angle0, angle1, angle2);
+ this.polarconicroutine = polarconicroutine;
+ this.direction = direction;
+ }
+
+ /*<asyxml><method type = "arc" signature="copy()"><code></asyxml>*/
+ arc copy()
+ {/*<asyxml></code><documentation>Copy the arc.</documentation></method></asyxml>*/
+ arc oa = new arc;
+ oa.el = this.el;
+ oa.direction = this.direction;
+ oa.polarconicroutine = this.polarconicroutine;
+ oa.angle1 = this.angle1;
+ oa.angle2 = this.angle2;
+ oa.angle0 = this.angle0;
+ return oa;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="polarconicroutine" signature="polarconicroutine(ellipse)"><code></asyxml>*/
+polarconicroutine polarconicroutine(conic co)
+{/*<asyxml></code><documentation>Return the default routine used to draw a conic.</documentation></function></asyxml>*/
+ if(co.e == 0) return fromCenter;
+ if(co.e == 1) return fromFocus;
+ return currentpolarconicroutine;
+}
+
+/*<asyxml><function type="arc" signature="arc(ellipse,real,real,polarconicroutine,bool)"><code></asyxml>*/
+arc arc(ellipse el, real angle1, real angle2,
+ polarconicroutine polarconicroutine = polarconicroutine(el),
+ bool direction = CCW)
+{/*<asyxml></code><documentation>Return the ellipse arc from 'angle1' to 'angle2' with respect to 'polarconicroutine' and rotating in the direction 'direction'.</documentation></function></asyxml>*/
+ arc oa;
+ oa.init(el, 0, angle1, angle2, polarconicroutine, direction);
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="complementary(arc)"><code></asyxml>*/
+arc complementary(arc a)
+{/*<asyxml></code><documentation>Return the complementary of 'a'.</documentation></function></asyxml>*/
+ arc oa;
+ oa.init(a.el, a.angle0, a.angle2, a.angle1, a.polarconicroutine, a.direction);
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="reverse(arc)"><code></asyxml>*/
+arc reverse(arc a)
+{/*<asyxml></code><documentation>Return arc 'a' oriented in reverse direction.</documentation></function></asyxml>*/
+ arc oa;
+ oa.init(a.el, a.angle0, a.angle2, a.angle1, a.polarconicroutine, !a.direction);
+ return oa;
+}
+
+/*<asyxml><function type="real" signature="degrees(arc)"><code></asyxml>*/
+real degrees(arc a)
+{/*<asyxml></code><documentation>Return the measure in degrees of the oriented arc 'a'.</documentation></function></asyxml>*/
+ real or;
+ real da = a.angle2 - a.angle1;
+ if(a.direction) {
+ or = a.angle1 < a.angle2 ? da : 360 + da;
+ } else {
+ or = a.angle1 < a.angle2 ? -360 + da : da;
+ }
+ return or;
+}
+
+/*<asyxml><function type="real" signature="angle(a)"><code></asyxml>*/
+real angle(arc a)
+{/*<asyxml></code><documentation>Return the measure in radians of the oriented arc 'a'.</documentation></function></asyxml>*/
+ return radians(degrees(a));
+}
+
+/*<asyxml><function type="int" signature="arcnodesnumber(explicit arc)"><code></asyxml>*/
+int arcnodesnumber(explicit arc a)
+{/*<asyxml></code><documentation>Return the number of nodes to draw the arc 'a'.</documentation></function></asyxml>*/
+ return ellipsenodesnumber(a.el.a, a.el.b, a.angle1, a.angle2, a.direction);
+}
+
+private path arctopath(arc a, int n)
+{
+ if(a.el.e == 0) return arcfromcenter(a.el, a.angle0 + a.angle1, a.angle0 + a.angle2, a.direction, n);
+ if(a.el.e != 1) return a.polarconicroutine(a.el, a.angle1, a.angle2, n, a.direction);
+ return arcfromfocus(a.el, a.angle1, a.angle2, n, a.direction);
+}
+
+/*<asyxml><function type="point" signature="angpoint(arc,real)"><code></asyxml>*/
+point angpoint(arc a, real angle)
+{/*<asyxml></code><documentation>Return the point given by its angular position (in degrees) relative to the arc 'a'.
+ If 'angle > degrees(a)' or 'angle < 0' the returned point is on the extended arc.</documentation></function></asyxml>*/
+ pair p;
+ if(a.el.e == 0) {
+ real gle = a.angle0 + a.angle1 + (a.direction ? angle : -angle);
+ p = point(arcfromcenter(a.el, gle, gle, CCW, 1), 0);
+ }
+ else {
+ real gle = a.angle1 + (a.direction ? angle : -angle);
+ p = point(a.polarconicroutine(a.el, gle, gle, 1, CCW), 0);
+ }
+ return point(coordsys(a.el), p/coordsys(a.el));
+}
+
+/*<asyxml><operator type = "path" signature="cast(explicit arc)"><code></asyxml>*/
+path operator cast(explicit arc a)
+{/*<asyxml></code><documentation>Cast arc to path.</documentation></operator></asyxml>*/
+ return arctopath(a, arcnodesnumber(a));
+}
+
+/*<asyxml><operator type = "guide" signature="cast(explicit arc)"><code></asyxml>*/
+guide operator cast(explicit arc a)
+{/*<asyxml></code><documentation>Cast arc to guide.</documentation></operator></asyxml>*/
+ return arctopath(a, arcnodesnumber(a));
+}
+
+/*<asyxml><operator type = "arc" signature="*(transform,explicit arc)"><code></asyxml>*/
+arc operator *(transform t, explicit arc a)
+{/*<asyxml></code><documentation>Provide transform * arc.</documentation></operator></asyxml>*/
+ pair[] P, PP;
+ path g = arctopath(a, 3);
+ real a0, a1 = a.angle1, a2 = a.angle2, ap1, ap2;
+ bool dir = a.direction;
+ P[0] = t * point(g, 0);
+ P[1] = t * point(g, 2);
+ ellipse el = t * a.el;
+ arc oa;
+ a0 = (a.angle0 + angle(shiftless(t)))%360;
+ pair C;
+ if(a.polarconicroutine == fromCenter) C = el.C; else C = el.F1;
+ real d = abs(locate(el.F2 - el.F1)) > epsgeo ?
+ degrees(locate(el.F2 - el.F1)) : a0 + degrees(el.C.coordsys.i);
+ ap1 = (degrees(P[0]-C, false) - d)%360;
+ ap2 = (degrees(P[1]-C, false) - d)%360;
+ oa.init(el, a0, ap1, ap2, a.polarconicroutine, dir);
+ g = arctopath(oa, 3);
+ PP[0] = point(g, 0);
+ PP[1] = point(g, 2);
+ if((a1 - a2) * (ap1 - ap2) < 0) {// Handle reflection.
+ dir=!a.direction;
+ oa.init(el, a0, ap1, ap2, a.polarconicroutine, dir);
+ }
+ return oa;
+}
+
+/*<asyxml><operator type = "arc" signature="*(real,explicit arc)"><code></asyxml>*/
+arc operator *(real x, explicit arc a)
+{/*<asyxml></code><documentation>Provide real * arc.
+ Return the arc subtracting and adding '(x - 1) * degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/
+ real a1, a2, gle;
+ gle = (x - 1) * degrees(a)/2;
+ a1 = a.angle1 - gle;
+ a2 = a.angle2 + gle;
+ arc oa;
+ oa.init(a.el, a.angle0, a1, a2, a.polarconicroutine, a.direction);
+ return oa;
+}
+arc operator *(int x, explicit arc a){return (real)x * a;}
+/*<asyxml><operator type = "arc" signature="/(real,explicit arc)"><code></asyxml>*/
+arc operator /(explicit arc a, real x)
+{/*<asyxml></code><documentation>Provide arc/real.
+ Return the arc subtracting and adding '(1/x - 1) * degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/
+ return (1/x) * a;
+}
+/*<asyxml><operator type = "arc" signature="+(explicit arc,point)"><code></asyxml>*/
+arc operator +(explicit arc a, point M)
+{/*<asyxml></code><documentation>Provide arc + point.
+ Return shifted arc.
+ 'operator +(explicit arc, point)', 'operator +(explicit arc, vector)' and 'operator -(explicit arc, vector)' are also defined.</documentation></operator></asyxml>*/
+ return shift(M) * a;
+}
+arc operator -(explicit arc a, point M){return a + (-M);}
+arc operator +(explicit arc a, vector v){return shift(locate(v)) * a;}
+arc operator -(explicit arc a, vector v){return a + (-v);}
+
+
+/*<asyxml><operator type = "bool" signature="@(point,arc)"><code></asyxml>*/
+bool operator @(point M, arc a)
+{/*<asyxml></code><documentation>Return true iff 'M' is on the arc 'a'.</documentation></operator></asyxml>*/
+ if (!(M @ a.el)) return false;
+ coordsys R = defaultcoordsys;
+ path ap = arctopath(a, 3);
+ line l = line(point(R, point(ap, 0)), point(R, point(ap, 2)));
+ return sameside(M, point(R, point(ap, 1)), l);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,arc,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, Label L = "", arc a,
+ align align = NoAlign, pen p = currentpen,
+ arrowbar arrow = None, arrowbar bar = None, margin margin = NoMargin,
+ Label legend = "", marker marker = nomarker)
+{/*<asyxml></code><documentation>Draw 'arc' adding the pen returned by 'addpenarc(p)' to the pen 'p'.
+ <look href = "#addpenarc"/></documentation></function></asyxml>*/
+ draw(pic, L, (path)a, align, addpenarc(p), arrow, bar, margin, legend, marker);
+}
+
+/*<asyxml><function type="real" signature="arclength(arc)"><code></asyxml>*/
+real arclength(arc a)
+{/*<asyxml></code><documentation>The arc length of 'a'.</documentation></function></asyxml>*/
+ return arclength(a.el, a.angle1, a.angle2, a.direction, a.polarconicroutine);
+}
+
+private point ppoint(arc a, real x)
+{// Return the point of the arc proportionally to its length.
+ point oP;
+ if(a.el.e == 0) { // Case of circle.
+ oP = angpoint(a, x * abs(degrees(a)));
+ } else { // Ellipse and not circle.
+ if(!a.direction) {
+ transform t = reflect(line(a.el.F1, a.el.F2));
+ return t * ppoint(t * a, x);
+ }
+
+ real angle1 = a.angle1, angle2 = a.angle2;
+ if(a.polarconicroutine == fromFocus) {
+ // dot(point(fromFocus(a.el, angle1, angle1, 1, CCW), 0), 2mm + blue);
+ // dot(point(fromFocus(a.el, angle2, angle2, 1, CCW), 0), 2mm + blue);
+ // write("fromfocus1 = ", angle1);
+ // write("fromfocus2 = ", angle2);
+ real gle1 = focusToCenter(a.el, angle1);
+ real gle2 = focusToCenter(a.el, angle2);
+ if((gle1 - gle2) * (angle1 - angle2) > 0) {
+ angle1 = gle1; angle2 = gle2;
+ } else {
+ angle1 = gle2; angle2 = gle1;
+ }
+ // write("fromcenter1 = ", angle1);
+ // write("fromcenter2 = ", angle2);
+ // dot(point(fromCenter(a.el, angle1, angle1, 1, CCW), 0), 1mm + red);
+ // dot(point(fromCenter(a.el, angle2, angle2, 1, CCW), 0), 1mm + red);
+ }
+
+ if(angle1 > angle2) {
+ arc ta = a.copy();
+ ta.polarconicroutine = fromCenter;
+ ta.setangles(a0 = a.angle0, a1 = angle1 - 360, a2 = angle2);
+ return ppoint(ta, x);
+ }
+ ellipse co = a.el;
+ real gle, a1, a2, cx = 0;
+ bool direction;
+ if(x >= 0) {
+ a1 = angle1;
+ a2 = a1 + 360;
+ direction = CCW;
+ } else {
+ a1 = angle1 - 360;
+ a2 = a1 - 360;
+ direction = CW;
+ }
+ gle = a1;
+ real L = arclength(co, angle1, angle2, a.direction, fromCenter);
+ real tx = L * abs(x)%arclength(co);
+ real aout = a1;
+ while(abs(cx - tx) > epsgeo) {
+ aout = (a1 + a2)/2;
+ cx = abs(arclength(co, gle, aout, direction, fromCenter));
+ if(cx > tx) a2 = (a1 + a2)/2 ; else a1 = (a1 + a2)/2;
+ }
+ pair p = point(arcfromcenter(co, aout, aout, CCW, 1), 0);
+ oP = point(coordsys(co), p/coordsys(co));
+ }
+ return oP;
+}
+
+/*<asyxml><function type="point" signature="point(arc,abscissa)"><code></asyxml>*/
+point point(arc a, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'a' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.
+ Note that 'a.polarconicroutine' is used instead of 'l.polarconicroutine'.
+ <look href = "#struct abscissa"/></documentation></function></asyxml>*/
+ real posx;
+ arc ta = a.copy();
+ ellipse co = a.el;
+ if (l.system == relativesystem) {
+ posx = l.x;
+ } else
+ if (l.system == curvilinearsystem) {
+ real tl;
+ if(co.e == 0) {
+ tl = curabscissa(a.el, angpoint(a.el, a.angle0 + a.angle1)).x;
+ return curpoint(a.el, tl + (a.direction ? l.x : -l.x));
+ } else {
+ tl = curabscissa(a.el, angpoint(a.el, a.angle1, a.polarconicroutine)).x;
+ return curpoint(a.el, tl + (a.direction ? l.x : -l.x));
+ }
+ } else
+ if (l.system == nodesystem) {
+ coordsys R = coordsys(co);
+ return point(R, point((path)a, l.x)/R);
+ } else
+ if (l.system == angularsystem) {
+ return angpoint(a, l.x);
+ } else abort("point: bad abscissa system.");
+ return ppoint(ta, posx);
+}
+
+
+/*<asyxml><function type="point" signature="point(arc,real)"><code></asyxml>*/
+point point(arc a, real x)
+{/*<asyxml></code><documentation>Return the point between node floor(t) and floor(t) + 1.</documentation></function></asyxml>*/
+ return point(a, nodabscissa(x));
+}
+pair point(explicit arc a, int x)
+{
+ return point(a, nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(arc,real)"><code></asyxml>*/
+point relpoint(arc a, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'a'.
+ If x > 1 or x < 0, the returned point is on the extended arc.</documentation></function></asyxml>*/
+ return point(a, relabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(arc,real)"><code></asyxml>*/
+point curpoint(arc a, real x)
+{/*<asyxml></code><documentation>Return the point of 'a' which has the curvilinear abscissa 'x'.
+ If x < 0 or x > arclength(a), the returned point is on the extended arc.</documentation></function></asyxml>*/
+ return point(a, curabscissa(x));
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(arc,point)"><code></asyxml>*/
+abscissa angabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' according to the arc 'a'.</documentation></function></asyxml>*/
+ if(!(M @ a.el))
+ abort("angabscissa: the point is not on the extended arc.");
+ abscissa oa;
+ oa.system = angularsystem;
+ oa.polarconicroutine = a.polarconicroutine;
+ real am = angabscissa(a.el, M, a.polarconicroutine).x;
+ oa.x = (am - a.angle1 - (a.el.e == 0 ? a.angle0 : 0))%360;
+ oa.x = a.direction ? oa.x : 360 - oa.x;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(arc,point)"><code></asyxml>*/
+abscissa curabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa according to the arc 'a'.</documentation></function></asyxml>*/
+ ellipse el = a.el;
+ if(!(M @ el))
+ abort("angabscissa: the point is not on the extended arc.");
+ abscissa oa;
+ oa.system = curvilinearsystem;
+ real xm = curabscissa(el, M).x;
+ real a0 = el.e == 0 ? a.angle0 : 0;
+ real am = curabscissa(el, angpoint(el, a.angle1 + a0, a.polarconicroutine)).x;
+ real l = arclength(el);
+ oa.x = (xm - am)%l;
+ oa.x = a.direction ? oa.x : l - oa.x;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(arc,point)"><code></asyxml>*/
+abscissa nodabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the node abscissa according to the arc 'a'.</documentation></function></asyxml>*/
+ if(!(M @ a))
+ abort("nodabscissa: the point is not on the arc.");
+ abscissa oa;
+ oa.system = nodesystem;
+ oa.x = intersect((path)a, M)[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(arc,point)"><code></asyxml>*/
+abscissa relabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa according to the arc 'a'.</documentation></function></asyxml>*/
+ ellipse el = a.el;
+ if(!( M @ el))
+ abort("relabscissa: the point is not on the prolonged arc.");
+ abscissa oa;
+ oa.system = relativesystem;
+ oa.x = curabscissa(a, M).x/arclength(a);
+ return oa;
+}
+
+/*<asyxml><function type="void" signature="markarc(picture,Label,int,real,real,arc,arrowbar,pen,pen,margin,marker)"><code></asyxml>*/
+void markarc(picture pic = currentpicture,
+ Label L = "",
+ int n = 1, real radius = 0, real space = 0,
+ arc a,
+ pen sectorpen = currentpen,
+ pen markpen = sectorpen,
+ margin margin = NoMargin,
+ arrowbar arrow = None,
+ marker marker = nomarker)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ real Da = degrees(a);
+ pair p1 = point(a, 0);
+ pair p2 = relpoint(a, 1);
+ pair c = a.polarconicroutine == fromCenter ? locate(a.el.C) : locate(a.el.F1);
+ if(radius == 0) radius = markangleradius(markpen);
+ if(abs(Da) > 180) radius = -radius;
+ radius = (a.direction ? 1 : -1) * sgnd(Da) * radius;
+ draw(c--p1^^c--p2, sectorpen);
+ markangle(pic = pic, L = L, n = n, radius = radius, space = space,
+ A = p1, O = c, B = p2,
+ arrow = arrow, p = markpen, margin = margin,
+ marker = marker);
+}
+// *.........................ARCS..........................*
+// *=======================================================*
+
+// *=======================================================*
+// *........................MASSES.........................*
+/*<asyxml><struct signature="mass"><code></asyxml>*/
+struct mass {/*<asyxml></code><documentation></documentation><property type = "point" signature="M"><code></asyxml>*/
+ point M;/*<asyxml></code><documentation></documentation></property><property type = "real" signature="m"><code></asyxml>*/
+ real m;/*<asyxml></code><documentation></documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="mass" signature="mass(point,real)"><code></asyxml>*/
+mass mass(point M, real m)
+{/*<asyxml></code><documentation>Constructor of mass point.</documentation></function></asyxml>*/
+ mass om;
+ om.M = M;
+ om.m = m;
+ return om;
+}
+
+/*<asyxml><operator type = "point" signature="cast(mass)"><code></asyxml>*/
+point operator cast(mass m)
+{/*<asyxml></code><documentation>Cast mass point to point.</documentation></operator></asyxml>*/
+ point op;
+ op = m.M;
+ op.m = m.m;
+ return op;
+}
+/*<asyxml><function type="point" signature="point(explicit mass)"><code></asyxml>*/
+point point(explicit mass m){return m;}/*<asyxml></code><documentation>Cast
+ 'm' to point</documentation></function></asyxml>*/
+
+/*<asyxml><operator type = "mass" signature="cast(point)"><code></asyxml>*/
+mass operator cast(point M)
+{/*<asyxml></code><documentation>Cast point to mass point.</documentation></operator></asyxml>*/
+ mass om;
+ om.M = M;
+ om.m = M.m;
+ return om;
+}
+/*<asyxml><function type="mass" signature="mass(explicit point)"><code></asyxml>*/
+mass mass(explicit point P)
+{/*<asyxml></code><documentation>Cast 'P' to mass.</documentation></function></asyxml>*/
+ return mass(P, P.m);
+}
+
+/*<asyxml><operator type = "point[]" signature="cast(mass[])"><code></asyxml>*/
+point[] operator cast(mass[] m)
+{/*<asyxml></code><documentation>Cast mass[] to point[].</documentation></operator></asyxml>*/
+ point[] op;
+ for(mass am : m) op.push(point(am));
+ return op;
+}
+
+/*<asyxml><operator type = "mass[]" signature="cast(point[])"><code></asyxml>*/
+mass[] operator cast(point[] P)
+{/*<asyxml></code><documentation>Cast point[] to mass[].</documentation></operator></asyxml>*/
+ mass[] om;
+ for(point op : P) om.push(mass(op));
+ return om;
+}
+
+/*<asyxml><function type="mass" signature="mass(coordsys,explicit pair,real)"><code></asyxml>*/
+mass mass(coordsys R, explicit pair p, real m)
+{/*<asyxml></code><documentation>Return the mass which has coordinates
+ 'p' with respect to 'R' and weight 'm'.</documentation></function></asyxml>*/
+ return point(R, p, m);// Using casting.
+}
+
+/*<asyxml><operator type = "mass" signature="cast(pair)"><code></asyxml>*/
+mass operator cast(pair m){return mass((point)m, 1);}/*<asyxml></code><documentation>Cast pair to mass point.</documentation></operator></asyxml>*/
+/*<asyxml><operator type = "path" signature="cast(mass)"><code></asyxml>*/
+path operator cast(mass M){return M.M;}/*<asyxml></code><documentation>Cast mass point to path.</documentation></operator></asyxml>*/
+/*<asyxml><operator type = "guide" signature="cast(mass)"><code></asyxml>*/
+guide operator cast(mass M){return M.M;}/*<asyxml></code><documentation>Cast mass to guide.</documentation></operator></asyxml>*/
+
+/*<asyxml><operator type = "mass" signature="+(mass,mass)"><code></asyxml>*/
+mass operator +(mass M1, mass M2)
+{/*<asyxml></code><documentation>Provide mass + mass.
+ mass - mass is also defined.</documentation></operator></asyxml>*/
+ return mass(M1.M + M2.M, M1.m + M2.m);
+}
+mass operator -(mass M1, mass M2)
+{
+ return mass(M1.M - M2.M, M1.m - M2.m);
+}
+
+/*<asyxml><operator type = "mass" signature="*(real,mass)"><code></asyxml>*/
+mass operator *(real x, explicit mass M)
+{/*<asyxml></code><documentation>Provide real * mass.
+ The resulted mass is the mass of 'M' multiplied by 'x' .
+ mass/real, mass + real and mass - real are also defined.</documentation></operator></asyxml>*/
+ return mass(M.M, x * M.m);
+}
+mass operator *(int x, explicit mass M){return mass(M.M, x * M.m);}
+mass operator /(explicit mass M, real x){return mass(M.M, M.m/x);}
+mass operator /(explicit mass M, int x){return mass(M.M, M.m/x);}
+mass operator +(explicit mass M, real x){return mass(M.M, M.m + x);}
+mass operator +(explicit mass M, int x){return mass(M.M, M.m + x);}
+mass operator -(explicit mass M, real x){return mass(M.M, M.m - x);}
+mass operator -(explicit mass M, int x){return mass(M.M, M.m - x);}
+/*<asyxml><operator type = "mass" signature="*(transform,mass)"><code></asyxml>*/
+mass operator *(transform t, mass M)
+{/*<asyxml></code><documentation>Provide transform * mass.</documentation></operator></asyxml>*/
+ return mass(t * M.M, M.m);
+}
+
+/*<asyxml><function type="mass" signature="masscenter(... mass[])"><code></asyxml>*/
+mass masscenter(... mass[] M)
+{/*<asyxml></code><documentation>Return the center of the masses 'M'.</documentation></function></asyxml>*/
+ point[] P;
+ for (int i = 0; i < M.length; ++i)
+ P.push(M[i].M);
+ P = standardizecoordsys(currentcoordsys, true ... P);
+ real m = M[0].m;
+ point oM = M[0].m * P[0];
+ for (int i = 1; i < M.length; ++i) {
+ oM += M[i].m * P[i];
+ m += M[i].m;
+ }
+ if (m == 0) abort("masscenter: the sum of masses is null.");
+ return mass(oM/m, m);
+}
+
+/*<asyxml><function type="string" signature="massformat(string,string,mass)"><code></asyxml>*/
+string massformat(string format = defaultmassformat,
+ string s, mass M)
+{/*<asyxml></code><documentation>Return the string formated by 'format' with the mass value.
+ In the parameter 'format', %L will be replaced by 's'.
+ <look href = "#defaultmassformat"/>.</documentation></function></asyxml>*/
+ return format == "" ? s :
+ format(replace(format, "%L", replace(s, "$", "")), M.m);
+}
+
+/*<asyxml><function type="void" signature="label(picture,Label,explicit mass,align,string,pen,filltype)"><code></asyxml>*/
+void label(picture pic = currentpicture, Label L, explicit mass M,
+ align align = NoAlign, string format = defaultmassformat,
+ pen p = nullpen, filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw label returned by massformat(format, L, M) at coordinates of M.
+ <look href = "#massformat(string, string, mass)"/>.</documentation></function></asyxml>*/
+ Label lL = L.copy();
+ lL.s = massformat(format, lL.s, M);
+ Label L = Label(lL, M.M, align, p, filltype);
+ add(pic, L);
+}
+
+/*<asyxml><function type="void" signature="dot(picture,Label,explicit mass,align,string,pen)"><code></asyxml>*/
+void dot(picture pic = currentpicture, Label L, explicit mass M, align align = NoAlign,
+ string format = defaultmassformat, pen p = currentpen)
+{/*<asyxml></code><documentation>Draw a dot with label 'L' as
+ label(picture, Label, explicit mass, align, string, pen, filltype) does.
+ <look href = "#label(picture, Label, mass, align, string, pen, filltype)"/>.</documentation></function></asyxml>*/
+ Label lL = L.copy();
+ lL.s = massformat(format, lL.s, M);
+ lL.position(locate(M.M));
+ lL.align(align, E);
+ lL.p(p);
+ dot(pic, M.M, p);
+ add(pic, lL);
+}
+// *........................MASSES.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.......................TRIANGLES.......................*
+/*<asyxml><function type="point" signature="orthocentercenter(point,point,point)"><code></asyxml>*/
+point orthocentercenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the orthocenter of the triangle ABC.</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A, B, C);
+ coordsys R = P[0].coordsys;
+ pair pp = extension(A, projection(P[1], P[2]) * P[0], B, projection(P[0], P[2]) * P[1]);
+ return point(R, pp/R);
+}
+
+/*<asyxml><function type="point" signature="centroid(point,point,point)"><code></asyxml>*/
+point centroid(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the centroid of the triangle ABC.</documentation></function></asyxml>*/
+ return (A + B + C)/3;
+}
+
+/*<asyxml><function type="point" signature="incenter(point,point,point)"><code></asyxml>*/
+point incenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the center of the incircle of the triangle ABC.</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A, B, C);
+ coordsys R = P[0].coordsys;
+ pair a = A, b = B, c = C;
+ pair pp = extension(a, a + dir(a--b, a--c), b, b + dir(b--a, b--c));
+ return point(R, pp/R);
+}
+
+/*<asyxml><function type="real" signature="inradius(point,point,point)"><code></asyxml>*/
+real inradius(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the radius of the incircle of the triangle ABC.</documentation></function></asyxml>*/
+ point IC = incenter(A, B, C);
+ return abs(IC - projection(A, B) * IC);
+}
+
+/*<asyxml><function type="circle" signature="incircle(point,point,point)"><code></asyxml>*/
+circle incircle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the incircle of the triangle ABC.</documentation></function></asyxml>*/
+ point IC = incenter(A, B, C);
+ return circle(IC, abs(IC - projection(A, B) * IC));
+}
+
+/*<asyxml><function type="point" signature="excenter(point,point,point)"><code></asyxml>*/
+point excenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the center of the excircle of the triangle tangent with (AB).</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A, B, C);
+ coordsys R = P[0].coordsys;
+ pair a = A, b = B, c = C;
+ pair pp = extension(a, a + rotate(90) * dir(a--b, a--c), b, b + rotate(90) * dir(b--a, b--c));
+ return point(R, pp/R);
+}
+
+/*<asyxml><function type="real" signature="exradius(point,point,point)"><code></asyxml>*/
+real exradius(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the radius of the excircle of the triangle ABC with (AB).</documentation></function></asyxml>*/
+ point EC = excenter(A, B, C);
+ return abs(EC - projection(A, B) * EC);
+}
+
+/*<asyxml><function type="circle" signature="excircle(point,point,point)"><code></asyxml>*/
+circle excircle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the excircle of the triangle ABC tangent with (AB).</documentation></function></asyxml>*/
+ point center = excenter(A, B, C);
+ real radius = abs(center - projection(B, C) * center);
+ return circle(center, radius);
+}
+
+private int[] numarray = {1, 2, 3};
+numarray.cyclic = true;
+
+/*<asyxml><struct signature="triangle"><code></asyxml>*/
+struct triangle {/*<asyxml></code><documentation></documentation></asyxml>*/
+
+ /*<asyxml><struct signature="vertex"><code></asyxml>*/
+ struct vertex {/*<asyxml></code><documentation>Structure used to communicate the vertex of a triangle.</documentation><property type = "int" signature="n"><code></asyxml>*/
+ int n;/*<asyxml></code><documentation>1 means VA,2 means VB,3 means VC,4 means VA etc...</documentation></property><property type = "triangle" signature="triangle"><code></asyxml>*/
+ triangle t;/*<asyxml></code><documentation>The triangle to which the vertex refers.</documentation></property></asyxml>*/
+ }/*<asyxml></struct></asyxml>*/
+
+ /*<asyxml><property type = "point" signature="A,B,C"><code></asyxml>*/
+ restricted point A, B, C;/*<asyxml></code><documentation>The vertices of the triangle (as point).</documentation></property><property type = "vertex" signature="VA, VB, VC"><code></asyxml>*/
+ restricted vertex VA, VB, VC;/*<asyxml></code><documentation>The vertices of the triangle (as vertex).
+ Note that the vertex structure contains the triangle to wish it refers.</documentation></property></asyxml>*/
+ VA.n = 1;VB.n = 2;VC.n = 3;
+
+ /*<asyxml><method type = "vertex" signature="vertex(int)"><code></asyxml>*/
+ vertex vertex(int n)
+ {/*<asyxml></code><documentation>Return numbered vertex.
+ 'n' is 1 means VA, 2 means VB, 3 means VC, 4 means VA etc...</documentation></method></asyxml>*/
+ n = numarray[n - 1];
+ if(n == 1) return VA;
+ else if(n == 2) return VB;
+ return VC;
+ }
+
+ /*<asyxml><method type = "point" signature="point(int)"><code></asyxml>*/
+ point point(int n)
+ {/*<asyxml></code><documentation>Return numbered point.
+ n is 1 means A, 2 means B, 3 means C, 4 means A etc...</documentation></method></asyxml>*/
+ n = numarray[n - 1];
+ if(n == 1) return A;
+ else if(n == 2) return B;
+ return C;
+ }
+
+ /*<asyxml><method type = "void" signature="init(point,point,point)"><code></asyxml>*/
+ void init(point A, point B, point C)
+ {/*<asyxml></code><documentation>Constructor.</documentation></method></asyxml>*/
+ point[] P = standardizecoordsys(A, B, C);
+ this.A = P[0];
+ this.B = P[1];
+ this.C = P[2];
+ VA.t = this; VB.t = this; VC.t = this;
+ }
+
+ /*<asyxml><method type = "void" signature="operator init(point,point,point)"><code></asyxml>*/
+ void operator init(point A, point B, point C)
+ {/*<asyxml></code><documentation>For backward compatibility.
+ Provide the routine 'triangle(point A, point B, point C)'.</documentation></method></asyxml>*/
+ this.init(A, B, C);
+ }
+
+ /*<asyxml><method type = "void" signature="init(real,real,real,real,point)"><code></asyxml>*/
+ void operator init(real b, real alpha, real c, real angle = 0, point A = (0, 0))
+ {/*<asyxml></code><documentation>For backward compatibility.
+ Provide the routine 'triangle(real b, real alpha, real c, real angle = 0, point A = (0, 0))
+ which returns the triangle ABC rotated by 'angle' (in degrees) and where b = AC, degrees(A) = alpha, AB = c.</documentation></method></asyxml>*/
+ coordsys R = A.coordsys;
+ this.init(A, A + R.polar(c, radians(angle)), A + R.polar(b, radians(angle + alpha)));
+ }
+
+ /*<asyxml><method type = "real" signature="a(),b(),c()"><code></asyxml>*/
+ real a()
+ {/*<asyxml></code><documentation>Return the length BC.
+ b() and c() are also defined and return the length AC and AB respectively.</documentation></method></asyxml>*/
+ return length(C - B);
+ }
+ real b() {return length(A - C);}
+ real c() {return length(B - A);}
+
+ private real det(pair a, pair b) {return a.x * b.y - a.y * b.x;}
+
+ /*<asyxml><method type = "real" signature="area()"><code></asyxml>*/
+ real area()
+ {/*<asyxml></code><documentation></documentation></method></asyxml>*/
+ pair a = locate(A), b = locate(B), c = locate(C);
+ return 0.5 * abs(det(a, b) + det(b, c) + det(c, a));
+ }
+
+ /*<asyxml><method type = "real" signature="alpha(),beta(),gamma()"><code></asyxml>*/
+ real alpha()
+ {/*<asyxml></code><documentation>Return the measure (in degrees) of the angle A.
+ beta() and gamma() are also defined and return the measure of the angles B and C respectively.</documentation></method></asyxml>*/
+ return degrees(acos((b()^2 + c()^2 - a()^2)/(2b() * c())));
+ }
+ real beta() {return degrees(acos((c()^2 + a()^2 - b()^2)/(2c() * a())));}
+ real gamma() {return degrees(acos((a()^2 + b()^2 - c()^2)/(2a() * b())));}
+
+ /*<asyxml><method type = "path" signature="Path()"><code></asyxml>*/
+ path Path()
+ {/*<asyxml></code><documentation>The path of the triangle.</documentation></method></asyxml>*/
+ return A--C--B--cycle;
+ }
+
+ /*<asyxml><struct signature="side"><code></asyxml>*/
+ struct side
+ {/*<asyxml></code><documentation>Structure used to communicate the side of a triangle.</documentation><property type = "int" signature="n"><code></asyxml>*/
+ int n;/*<asyxml></code><documentation>1 or 0 means [AB],-1 means [BA],2 means [BC],-2 means [CB] etc.</documentation></property><property type = "triangle" signature="triangle"><code></asyxml>*/
+ triangle t;/*<asyxml></code><documentation>The triangle to which the side refers.</documentation></property></asyxml>*/
+ }/*<asyxml></struct></asyxml>*/
+
+ /*<asyxml><property type = "side" signature="AB"><code></asyxml>*/
+ side AB;/*<asyxml></code><documentation>For the routines using the structure 'side', triangle.AB means 'side AB'.
+ BA, AC, CA etc are also defined.</documentation></property></asyxml>*/
+ AB.n = 1; AB.t = this;
+ side BA; BA.n = -1; BA.t = this;
+ side BC; BC.n = 2; BC.t = this;
+ side CB; CB.n = -2; CB.t = this;
+ side CA; CA.n = 3; CA.t = this;
+ side AC; AC.n = -3; AC.t = this;
+
+ /*<asyxml><method type = "side" signature="side(int)"><code></asyxml>*/
+ side side(int n)
+ {/*<asyxml></code><documentation>Return numbered side.
+ n is 1 means AB, -1 means BA, 2 means BC, -2 means CB, etc.</documentation></method></asyxml>*/
+ if(n == 0) abort('Invalid side number.');
+ int an = numarray[abs(n)-1];
+ if(an == 1) return n > 0 ? AB : BA;
+ else if(an == 2) return n > 0 ? BC : CB;
+ return n > 0 ? CA : AC;
+ }
+
+ /*<asyxml><method type = "line" signature="line(int)"><code></asyxml>*/
+ line line(int n)
+ {/*<asyxml></code><documentation>Return the numbered line.</documentation></method></asyxml>*/
+ if(n == 0) abort('Invalid line number.');
+ int an = numarray[abs(n)-1];
+ if(an == 1) return n > 0 ? line(A, B) : line(B, A);
+ else if(an == 2) return n > 0 ? line(B, C) : line(C, B);
+ return n > 0 ? line(C, A) : line(A, C);
+ }
+
+}/*<asyxml></struct></asyxml>*/
+
+from triangle unravel side; // The structure 'side' is now available outside the triangle structure.
+from triangle unravel vertex; // The structure 'vertex' is now available outside the triangle structure.
+
+triangle[] operator ^^(triangle[] t1, triangle t2)
+{
+ triangle[] T;
+ for (int i = 0; i < t1.length; ++i) T.push(t1[i]);
+ T.push(t2);
+ return T;
+}
+
+triangle[] operator ^^(... triangle[] t)
+{
+ triangle[] T;
+ for (int i = 0; i < t.length; ++i) {
+ T.push(t[i]);
+ }
+ return T;
+}
+
+/*<asyxml><operator type = "line" signature="cast(side)"><code></asyxml>*/
+line operator cast(side side)
+{/*<asyxml></code><documentation>Cast side to (infinite) line.
+ Most routine with line parameters works with side parameters.
+ One can use the code 'segment(a_side)' to obtain a line segment.</documentation></operator></asyxml>*/
+ triangle t = side.t;
+ return t.line(side.n);
+}
+
+/*<asyxml><function type="line" signature="line(explicit side)"><code></asyxml>*/
+line line(explicit side side)
+{/*<asyxml></code><documentation>Return 'side' as line.</documentation></function></asyxml>*/
+ return (line)side;
+}
+
+/*<asyxml><function type="segment" signature="segment(explicit side)"><code></asyxml>*/
+segment segment(explicit side side)
+{/*<asyxml></code><documentation>Return 'side' as segment.</documentation></function></asyxml>*/
+ return (segment)(line)side;
+}
+
+/*<asyxml><operator type = "point" signature="cast(vertex)"><code></asyxml>*/
+point operator cast(vertex V)
+{/*<asyxml></code><documentation>Cast vertex to point.
+ Most routine with point parameters works with vertex parameters.</documentation></operator></asyxml>*/
+ return V.t.point(V.n);
+}
+
+/*<asyxml><function type="point" signature="point(explicit vertex)"><code></asyxml>*/
+point point(explicit vertex V)
+{/*<asyxml></code><documentation>Return the point corresponding to the vertex 'V'.</documentation></function></asyxml>*/
+ return (point)V;
+}
+
+/*<asyxml><function type="side" signature="opposite(vertex)"><code></asyxml>*/
+side opposite(vertex V)
+{/*<asyxml></code><documentation>Return the opposite side of vertex 'V'.</documentation></function></asyxml>*/
+ return V.t.side(numarray[abs(V.n)]);
+}
+
+/*<asyxml><function type="vertex" signature="opposite(side)"><code></asyxml>*/
+vertex opposite(side side)
+{/*<asyxml></code><documentation>Return the opposite vertex of side 'side'.</documentation></function></asyxml>*/
+ return side.t.vertex(numarray[abs(side.n) + 1]);
+}
+
+/*<asyxml><function type="point" signature="midpoint(side)"><code></asyxml>*/
+point midpoint(side side)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return midpoint(segment(side));
+}
+
+/*<asyxml><operator type = "triangle" signature="*(transform,triangle)"><code></asyxml>*/
+triangle operator *(transform T, triangle t)
+{/*<asyxml></code><documentation>Provide transform * triangle.</documentation></operator></asyxml>*/
+ return triangle(T * t.A, T * t.B, T * t.C);
+}
+
+/*<asyxml><function type="triangle" signature="triangleAbc(real,real,real,real,point)"><code></asyxml>*/
+triangle triangleAbc(real alpha, real b, real c, real angle = 0, point A = (0, 0))
+{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BAC = alpha, AC = b and AB = c.</documentation></function></asyxml>*/
+ triangle T;
+ coordsys R = A.coordsys;
+ T.init(A, A + R.polar(c, radians(angle)), A + R.polar(b, radians(angle + alpha)));
+ return T;
+}
+
+/*<asyxml><function type="triangle" signature="triangleabc(real,real,real,real,point)"><code></asyxml>*/
+triangle triangleabc(real a, real b, real c, real angle = 0, point A = (0, 0))
+{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BC = a, AC = b and AB = c.</documentation></function></asyxml>*/
+ triangle T;
+ coordsys R = A.coordsys;
+ T.init(A, A + R.polar(c, radians(angle)), A + R.polar(b, radians(angle) + acos((b^2 + c^2 - a^2)/(2 * b * c))));
+ return T;
+}
+
+/*<asyxml><function type="triangle" signature="triangle(line,line,line)"><code></asyxml>*/
+triangle triangle(line l1, line l2, line l3)
+{/*<asyxml></code><documentation>Return the triangle defined by three line.</documentation></function></asyxml>*/
+ point P1, P2, P3;
+ P1 = intersectionpoint(l1, l2);
+ P2 = intersectionpoint(l1, l3);
+ P3 = intersectionpoint(l2, l3);
+ if(!(defined(P1) && defined(P2) && defined(P3))) abort("triangle: two lines are parallel.");
+ return triangle(P1, P2, P3);
+}
+
+/*<asyxml><function type="point" signature="foot(vertex)"><code></asyxml>*/
+point foot(vertex V)
+{/*<asyxml></code><documentation>Return the endpoint of the altitude from V.</documentation></function></asyxml>*/
+ return projection((line)opposite(V)) * ((point)V);
+}
+
+/*<asyxml><function type="point" signature="foot(side)"><code></asyxml>*/
+point foot(side side)
+{/*<asyxml></code><documentation>Return the endpoint of the altitude on 'side'.</documentation></function></asyxml>*/
+ return projection((line)side) * point(opposite(side));
+}
+
+/*<asyxml><function type="line" signature="altitude(vertex)"><code></asyxml>*/
+line altitude(vertex V)
+{/*<asyxml></code><documentation>Return the altitude passing through 'V'.</documentation></function></asyxml>*/
+ return line(point(V), foot(V));
+}
+
+/*<asyxml><function type="line" signature="altitude(vertex)"><code></asyxml>*/
+line altitude(side side)
+{/*<asyxml></code><documentation>Return the altitude cutting 'side'.</documentation></function></asyxml>*/
+ return altitude(opposite(side));
+}
+
+/*<asyxml><function type="point" signature="orthocentercenter(triangle)"><code></asyxml>*/
+point orthocentercenter(triangle t)
+{/*<asyxml></code><documentation>Return the orthocenter of the triangle t.</documentation></function></asyxml>*/
+ return orthocentercenter(t.A, t.B, t.C);
+}
+
+/*<asyxml><function type="point" signature="centroid(triangle)"><code></asyxml>*/
+point centroid(triangle t)
+{/*<asyxml></code><documentation>Return the centroid of the triangle 't'.</documentation></function></asyxml>*/
+ return (t.A + t.B + t.C)/3;
+}
+
+/*<asyxml><function type="point" signature="circumcenter(triangle)"><code></asyxml>*/
+point circumcenter(triangle t)
+{/*<asyxml></code><documentation>Return the circumcenter of the triangle 't'.</documentation></function></asyxml>*/
+ return circumcenter(t.A, t.B, t.C);
+}
+
+/*<asyxml><function type="circle" signature="circle(triangle)"><code></asyxml>*/
+circle circle(triangle t)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle 't'.</documentation></function></asyxml>*/
+ return circle(t.A, t.B, t.C);
+}
+
+/*<asyxml><function type="circle" signature="circumcircle(triangle)"><code></asyxml>*/
+circle circumcircle(triangle t)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle 't'.</documentation></function></asyxml>*/
+ return circle(t.A, t.B, t.C);
+}
+
+/*<asyxml><function type="point" signature="incenter(triangle)"><code></asyxml>*/
+point incenter(triangle t)
+{/*<asyxml></code><documentation>Return the center of the incircle of the triangle 't'.</documentation></function></asyxml>*/
+ return incenter(t.A, t.B, t.C);
+}
+
+/*<asyxml><function type="real" signature="inradius(triangle)"><code></asyxml>*/
+real inradius(triangle t)
+{/*<asyxml></code><documentation>Return the radius of the incircle of the triangle 't'.</documentation></function></asyxml>*/
+ return inradius(t.A, t.B, t.C);
+}
+
+/*<asyxml><function type="circle" signature="incircle(triangle)"><code></asyxml>*/
+circle incircle(triangle t)
+{/*<asyxml></code><documentation>Return the the incircle of the triangle 't'.</documentation></function></asyxml>*/
+ return incircle(t.A, t.B, t.C);
+}
+
+/*<asyxml><function type="point" signature="excenter(side,triangle)"><code></asyxml>*/
+point excenter(side side)
+{/*<asyxml></code><documentation>Return the center of the excircle tangent with the side 'side' of its triangle.
+ side = 0 means AB, 1 means AC, other means BC.
+ One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/
+ point op;
+ triangle t = side.t;
+ int n = numarray[abs(side.n) - 1];
+ if(n == 1) op = excenter(t.A, t.B, t.C);
+ else if(n == 2) op = excenter(t.B, t.C, t.A);
+ else op = excenter(t.C, t.A, t.B);
+ return op;
+}
+
+/*<asyxml><function type="real" signature="exradius(side,triangle)"><code></asyxml>*/
+real exradius(side side)
+{/*<asyxml></code><documentation>Return radius of the excircle tangent with the side 'side' of its triangle.
+ side = 0 means AB, 1 means BC, other means CA.
+ One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/
+ real or;
+ triangle t = side.t;
+ int n = numarray[abs(side.n) - 1];
+ if(n == 1) or = exradius(t.A, t.B, t.C);
+ else if(n == 2) or = exradius(t.B, t.C, t.A);
+ else or = exradius(t.A, t.C, t.B);
+ return or;
+}
+
+/*<asyxml><function type="circle" signature="excircle(side,triangle)"><code></asyxml>*/
+circle excircle(side side)
+{/*<asyxml></code><documentation>Return the excircle tangent with the side 'side' of its triangle.
+ side = 0 means AB, 1 means AC, other means BC.
+ One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/
+ circle oc;
+ int n = numarray[abs(side.n) - 1];
+ triangle t = side.t;
+ if(n == 1) oc = excircle(t.A, t.B, t.C);
+ else if(n == 2) oc = excircle(t.B, t.C, t.A);
+ else oc = excircle(t.A, t.C, t.B);
+ return oc;
+}
+
+/*<asyxml><struct signature="trilinear"><code></asyxml>*/
+struct trilinear
+{/*<asyxml></code><documentation>Trilinear coordinates 'a:b:c' relative to triangle 't'.
+ <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation><property type = "real" signature="a,b,c"><code></asyxml>*/
+ real a,b,c;/*<asyxml></code><documentation>The trilinear coordinates.</documentation></property><property type = "triangle" signature="t"><code></asyxml>*/
+ triangle t;/*<asyxml></code><documentation>The reference triangle.</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="trilinear" signature="trilinear(triangle,real,real,real)"><code></asyxml>*/
+trilinear trilinear(triangle t, real a, real b, real c)
+{/*<asyxml></code><documentation>Return the trilinear coordinates relative to 't'.
+ <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/
+ trilinear ot;
+ ot.a = a; ot.b = b; ot.c = c;
+ ot.t = t;
+ return ot;
+}
+
+/*<asyxml><function type="trilinear" signature="trilinear(triangle,point)"><code></asyxml>*/
+trilinear trilinear(triangle t, point M)
+{/*<asyxml></code><documentation>Return the trilinear coordinates of 'M' relative to 't'.
+ <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/
+ trilinear ot;
+ pair m = locate(M);
+ int sameside(pair A, pair B, pair m, pair p)
+ {// Return 1 if 'm' and 'p' are same side of line (AB) else return -1.
+ pair mil = (A + B)/2;
+ pair mA = rotate(90, mil) * A;
+ pair mB = rotate(-90, mil) * A;
+ return (abs(m - mA) <= abs(m - mB)) == (abs(p - mA) <= abs(p - mB)) ? 1 : -1;
+ }
+ real det(pair a, pair b) {return a.x * b.y - a.y * b.x;}
+ real area(pair a, pair b, pair c){return 0.5 * abs(det(a, b) + det(b, c) + det(c, a));}
+ pair A = t.A, B = t.B, C = t.C;
+ real t1 = area(B, C, m), t2 = area(C, A, m), t3 = area(A, B, m);
+ ot.a = sameside(B, C, A, m) * t1/t.a();
+ ot.b = sameside(A, C, B, m) * t2/t.b();
+ ot.c = sameside(A, B, C, m) * t3/t.c();
+ ot.t = t;
+ return ot;
+}
+
+/*<asyxml><function type="void" signature="write(trilinear)"><code></asyxml>*/
+void write(trilinear tri)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ write(format("%f : ", tri.a) + format("%f : ", tri.b) + format("%f", tri.c));
+}
+
+/*<asyxml><function type="point" signature="trilinear(triangle,real,real,real)"><code></asyxml>*/
+point point(trilinear tri)
+{/*<asyxml></code><documentation>Return the trilinear coordinates relative to 't'.
+ <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/
+ triangle t = tri.t;
+ return masscenter(0.5 * t.a() * mass(t.A, tri.a),
+ 0.5 * t.b() * mass(t.B, tri.b),
+ 0.5 * t.c() * mass(t.C, tri.c));
+}
+
+/*<asyxml><function type="int[]" signature="tricoef(side)"><code></asyxml>*/
+int[] tricoef(side side)
+{/*<asyxml></code><documentation>Return an array of integer (values are 0 or 1) which represents 'side'.
+ For example, side = t.BC will be represented by {0, 1, 1}.</documentation></function></asyxml>*/
+ int[] oi;
+ int n = numarray[abs(side.n) - 1];
+ oi.push((n == 1 || n == 3) ? 1 : 0);
+ oi.push((n == 1 || n == 2) ? 1 : 0);
+ oi.push((n == 2 || n == 3) ? 1 : 0);
+ return oi;
+}
+
+/*<asyxml><operator type = "point" signature="cast(trilinear)"><code></asyxml>*/
+point operator cast(trilinear tri)
+{/*<asyxml></code><documentation>Cast trilinear to point.
+ One may use the routine 'point(trilinear)' to force the casting.</documentation></operator></asyxml>*/
+ return point(tri);
+}
+
+/*<asyxml><typedef type = "centerfunction" return = "real" params = "real, real, real"><code></asyxml>*/
+typedef real centerfunction(real, real, real);/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></typedef></asyxml>*/
+
+/*<asyxml><function type="trilinear" signature="trilinear(triangle,centerfunction,real,real,real)"><code></asyxml>*/
+trilinear trilinear(triangle t, centerfunction f, real a = t.a(), real b = t.b(), real c = t.c())
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></function></asyxml>*/
+ return trilinear(t, f(a, b, c), f(b, c, a), f(c, a, b));
+}
+
+/*<asyxml><function type="point" signature="symmedian(triangle)"><code></asyxml>*/
+point symmedian(triangle t)
+{/*<asyxml></code><documentation>Return the symmedian point of 't'.</documentation></function></asyxml>*/
+ point A, B, C;
+ real a = t.a(), b = t.b(), c = t.c();
+ A = trilinear(t, 0, b, c);
+ B = trilinear(t, a, 0, c);
+ return intersectionpoint(line(t.A, A), line(t.B, B));
+}
+
+/*<asyxml><function type="point" signature="symmedian(side)"><code></asyxml>*/
+point symmedian(side side)
+{/*<asyxml></code><documentation>The symmedian point on the side 'side'.</documentation></function></asyxml>*/
+ triangle t = side.t;
+ int n = numarray[abs(side.n) - 1];
+ if(n == 1) return trilinear(t, t.a(), t.b(), 0);
+ if(n == 2) return trilinear(t, 0, t.b(), t.c());
+ return trilinear(t, t.a(), 0, t.c());
+}
+
+/*<asyxml><function type="line" signature="symmedian(vertex)"><code></asyxml>*/
+line symmedian(vertex V)
+{/*<asyxml></code><documentation>Return the symmedian passing through 'V'.</documentation></function></asyxml>*/
+ return line(point(V), symmedian(V.t));
+}
+
+/*<asyxml><function type="triangle" signature="cevian(triangle,point)"><code></asyxml>*/
+triangle cevian(triangle t, point P)
+{/*<asyxml></code><documentation>Return the Cevian triangle with respect of 'P'
+ <url href = "http://mathworld.wolfram.com/CevianTriangle.html"/>.</documentation></function></asyxml>*/
+ trilinear tri = trilinear(t, locate(P));
+ point A = point(trilinear(t, 0, tri.b, tri.c));
+ point B = point(trilinear(t, tri.a, 0, tri.c));
+ point C = point(trilinear(t, tri.a, tri.b, 0));
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="point" signature="cevian(side,point)"><code></asyxml>*/
+point cevian(side side, point P)
+{/*<asyxml></code><documentation>Return the Cevian point on 'side' with respect of 'P'.</documentation></function></asyxml>*/
+ triangle t = side.t;
+ trilinear tri = trilinear(t, locate(P));
+ int[] s = tricoef(side);
+ return point(trilinear(t, s[0] * tri.a, s[1] * tri.b, s[2] * tri.c));
+}
+
+/*<asyxml><function type="line" signature="cevian(vertex,point)"><code></asyxml>*/
+line cevian(vertex V, point P)
+{/*<asyxml></code><documentation>Return line passing through 'V' and its Cevian image with respect of 'P'.</documentation></function></asyxml>*/
+ return line(point(V), cevian(opposite(V), P));
+}
+
+/*<asyxml><function type="point" signature="gergonne(triangle)"><code></asyxml>*/
+point gergonne(triangle t)
+{/*<asyxml></code><documentation>Return the Gergonne point of 't'.</documentation></function></asyxml>*/
+ real f(real a, real b, real c){return 1/(a * (b + c - a));}
+ return point(trilinear(t, f));
+}
+
+/*<asyxml><function type="point[]" signature="fermat(triangle)"><code></asyxml>*/
+point[] fermat(triangle t)
+{/*<asyxml></code><documentation>Return the Fermat points of 't'.</documentation></function></asyxml>*/
+ point[] P;
+ real A = t.alpha(), B = t.beta(), C = t.gamma();
+ P.push(point(trilinear(t, 1/Sin(A + 60), 1/Sin(B + 60), 1/Sin(C + 60))));
+ P.push(point(trilinear(t, 1/Sin(A - 60), 1/Sin(B - 60), 1/Sin(C - 60))));
+ return P;
+}
+
+/*<asyxml><function type="point" signature="isotomicconjugate(triangle,point)"><code></asyxml>*/
+point isotomicconjugate(triangle t, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/
+ if(!inside(t.Path(), locate(M))) abort("isotomic: the point must be inside the triangle.");
+ trilinear tr = trilinear(t, M);
+ return point(trilinear(t, 1/(t.a()^2 * tr.a), 1/(t.b()^2 * tr.b), 1/(t.c()^2 * tr.c)));
+}
+
+/*<asyxml><function type="line" signature="isotomic(vertex,point)"><code></asyxml>*/
+line isotomic(vertex V, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/>.</documentation></function></asyxml>*/
+ side op = opposite(V);
+ return line(V, rotate(180, midpoint(op)) * cevian(op, M));
+}
+
+/*<asyxml><function type="point" signature="isotomic(side,point)"><code></asyxml>*/
+point isotomic(side side, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/
+ return intersectionpoint(isotomic(opposite(side), M), side);
+}
+
+/*<asyxml><function type="triangle" signature="isotomic(triangle,point)"><code></asyxml>*/
+triangle isotomic(triangle t, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/
+ return triangle(isotomic(t.BC, M), isotomic(t.CA, M), isotomic(t.AB, M));
+}
+
+/*<asyxml><function type="point" signature="isogonalconjugate(triangle,point)"><code></asyxml>*/
+point isogonalconjugate(triangle t, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ trilinear tr = trilinear(t, M);
+ return point(trilinear(t, 1/tr.a, 1/tr.b, 1/tr.c));
+}
+
+/*<asyxml><function type="point" signature="isogonal(side,point)"><code></asyxml>*/
+point isogonal(side side, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ return cevian(side, isogonalconjugate(side.t, M));
+}
+
+/*<asyxml><function type="line" signature="isogonal(vertex,point)"><code></asyxml>*/
+line isogonal(vertex V, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ return line(V, isogonal(opposite(V), M));
+}
+
+/*<asyxml><function type="triangle" signature="isogonal(triangle,point)"><code></asyxml>*/
+triangle isogonal(triangle t, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ return triangle(isogonal(t.BC, M), isogonal(t.CA, M), isogonal(t.AB, M));
+}
+
+/*<asyxml><function type="triangle" signature="pedal(triangle,point)"><code></asyxml>*/
+triangle pedal(triangle t, point M)
+{/*<asyxml></code><documentation>Return the pedal triangle of 'M' in 't'.
+ <url href = "http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/
+ return triangle(projection(t.BC) * M, projection(t.AC) * M, projection(t.AB) * M);
+}
+
+/*<asyxml><function type="triangle" signature="pedal(triangle,point)"><code></asyxml>*/
+line pedal(side side, point M)
+{/*<asyxml></code><documentation>Return the pedal line of 'M' cutting 'side'.
+ <url href = "http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/
+ return line(M, projection(side) * M);
+}
+
+/*<asyxml><function type="triangle" signature="antipedal(triangle,point)"><code></asyxml>*/
+triangle antipedal(triangle t, point M)
+{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/AntipedalTriangle.html"/></documentation></function></asyxml>*/
+ trilinear Tm = trilinear(t, M);
+ real a = Tm.a, b = Tm.b, c = Tm.c;
+ real CA = Cos(t.alpha()), CB = Cos(t.beta()), CC = Cos(t.gamma());
+ point A = trilinear(t, -(b + a * CC) * (c + a * CB), (c + a * CB) * (a + b * CC), (b + a * CC) * (a + c * CB));
+ point B = trilinear(t, (c + b * CA) * (b + a * CC), -(c + b * CA) * (a + b * CC), (a + b * CC) * (b + c * CA));
+ point C = trilinear(t, (b + c * CA) * (c + a * CB), (a + c * CB) * (c + b * CA), -(a + c * CB) * (b + c * CA));
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="triangle" signature="extouch(triangle)"><code></asyxml>*/
+triangle extouch(triangle t)
+{/*<asyxml></code><documentation>Return the extouch triangle of the triangle 't'.
+ The extouch triangle of 't' is the triangle formed by the points
+ of tangency of a triangle 't' with its excircles.</documentation></function></asyxml>*/
+ point A, B, C;
+ real a = t.a(), b = t.b(), c = t.c();
+ A = trilinear(t, 0, (a - b + c)/b, (a + b - c)/c);
+ B = trilinear(t, (-a + b + c)/a, 0, (a + b - c)/c);
+ C = trilinear(t, (-a + b + c)/a, (a - b + c)/b, 0);
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="triangle" signature="extouch(triangle)"><code></asyxml>*/
+triangle incentral(triangle t)
+{/*<asyxml></code><documentation>Return the incentral triangle of the triangle 't'.
+ It is the triangle whose vertices are determined by the intersections of the
+ reference triangle's angle bisectors with the respective opposite sides.</documentation></function></asyxml>*/
+ point A, B, C;
+ // real a = t.a(), b = t.b(), c = t.c();
+ A = trilinear(t, 0, 1, 1);
+ B = trilinear(t, 1, 0, 1);
+ C = trilinear(t, 1, 1, 0);
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="triangle" signature="extouch(side)"><code></asyxml>*/
+triangle extouch(side side)
+{/*<asyxml></code><documentation>Return the triangle formed by the points of tangency of the triangle referenced by 'side' with its excircles.
+ One vertex of the returned triangle is on the segment 'side'.</documentation></function></asyxml>*/
+ triangle t = side.t;
+ transform p1 = projection((line)t.AB);
+ transform p2 = projection((line)t.AC);
+ transform p3 = projection((line)t.BC);
+ point EP = excenter(side);
+ return triangle(p3 * EP, p2 * EP, p1 * EP);
+}
+
+/*<asyxml><function type="point" signature="bisectorpoint(side)"><code></asyxml>*/
+point bisectorpoint(side side)
+{/*<asyxml></code><documentation>The intersection point of the angle bisector from the
+ opposite point of 'side' with the side 'side'.</documentation></function></asyxml>*/
+ triangle t = side.t;
+ int n = numarray[abs(side.n) - 1];
+ if(n == 1) return trilinear(t, 1, 1, 0);
+ if(n == 2) return trilinear(t, 0, 1, 1);
+ return trilinear(t, 1, 0, 1);
+}
+
+/*<asyxml><function type="line" signature="bisector(vertex,real)"><code></asyxml>*/
+line bisector(vertex V, real angle = 0)
+{/*<asyxml></code><documentation>Return the interior bisector passing through 'V' rotated by angle (in degrees)
+ around 'V'.</documentation></function></asyxml>*/
+ return rotate(angle, point(V)) * line(point(V), incenter(V.t));
+}
+
+/*<asyxml><function type="line" signature="bisector(side)"><code></asyxml>*/
+line bisector(side side)
+{/*<asyxml></code><documentation>Return the bisector of the line segment 'side'.</documentation></function></asyxml>*/
+ return bisector(segment(side));
+}
+
+/*<asyxml><function type="point" signature="intouch(side)"><code></asyxml>*/
+point intouch(side side)
+{/*<asyxml></code><documentation>The point of tangency on the side 'side' of its incircle.</documentation></function></asyxml>*/
+ triangle t = side.t;
+ real a = t.a(), b = t.b(), c = t.c();
+ int n = numarray[abs(side.n) - 1];
+ if(n == 1) return trilinear(t, b * c/(-a + b + c), a * c/(a - b + c), 0);
+ if(n == 2) return trilinear(t, 0, a * c/(a - b + c), a * b/(a + b - c));
+ return trilinear(t, b * c/(-a + b + c), 0, a * b/(a + b - c));
+}
+
+/*<asyxml><function type="triangle" signature="intouch(triangle)"><code></asyxml>*/
+triangle intouch(triangle t)
+{/*<asyxml></code><documentation>Return the intouch triangle of the triangle 't'.
+ The intouch triangle of 't' is the triangle formed by the points
+ of tangency of a triangle 't' with its incircles.</documentation></function></asyxml>*/
+ point A, B, C;
+ real a = t.a(), b = t.b(), c = t.c();
+ A = trilinear(t, 0, a * c/(a - b + c), a * b/(a + b - c));
+ B = trilinear(t, b * c/(-a + b + c), 0, a * b/(a + b - c));
+ C = trilinear(t, b * c/(-a + b + c), a * c/(a - b + c), 0);
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="triangle" signature="tangential(triangle)"><code></asyxml>*/
+triangle tangential(triangle t)
+{/*<asyxml></code><documentation>Return the tangential triangle of the triangle 't'.
+ The tangential triangle of 't' is the triangle formed by the lines
+ tangent to the circumcircle of the given triangle 't' at its vertices.</documentation></function></asyxml>*/
+ point A, B, C;
+ real a = t.a(), b = t.b(), c = t.c();
+ A = trilinear(t, -a, b, c);
+ B = trilinear(t, a, -b, c);
+ C = trilinear(t, a, b, -c);
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="triangle" signature="medial(triangle t)"><code></asyxml>*/
+triangle medial(triangle t)
+{/*<asyxml></code><documentation>Return the triangle whose vertices are midpoints of the sides of 't'.</documentation></function></asyxml>*/
+ return triangle(midpoint(t.BC), midpoint(t.AC), midpoint(t.AB));
+}
+
+/*<asyxml><function type="line" signature="median(vertex)"><code></asyxml>*/
+line median(vertex V)
+{/*<asyxml></code><documentation>Return median from 'V'.</documentation></function></asyxml>*/
+ return line(point(V), midpoint(segment(opposite(V))));
+}
+
+/*<asyxml><function type="line" signature="median(side)"><code></asyxml>*/
+line median(side side)
+{/*<asyxml></code><documentation>Return median from the opposite vertex of 'side'.</documentation></function></asyxml>*/
+ return median(opposite(side));
+}
+
+/*<asyxml><function type="triangle" signature="orthic(triangle)"><code></asyxml>*/
+triangle orthic(triangle t)
+{/*<asyxml></code><documentation>Return the triangle whose vertices are endpoints of the altitudes from each of the vertices of 't'.</documentation></function></asyxml>*/
+ return triangle(foot(t.BC), foot(t.AC), foot(t.AB));
+}
+
+/*<asyxml><function type="triangle" signature="symmedial(triangle)"><code></asyxml>*/
+triangle symmedial(triangle t)
+{/*<asyxml></code><documentation>Return the symmedial triangle of 't'.</documentation></function></asyxml>*/
+ point A, B, C;
+ real a = t.a(), b = t.b(), c = t.c();
+ A = trilinear(t, 0, b, c);
+ B = trilinear(t, a, 0, c);
+ C = trilinear(t, a, b, 0);
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="triangle" signature="anticomplementary(triangle)"><code></asyxml>*/
+triangle anticomplementary(triangle t)
+{/*<asyxml></code><documentation>Return the triangle which has the given triangle 't' as its medial triangle.</documentation></function></asyxml>*/
+ real a = t.a(), b = t.b(), c = t.c();
+ real ab = a * b, bc = b * c, ca = c * a;
+ point A = trilinear(t, -bc, ca, ab);
+ point B = trilinear(t, bc, -ca, ab);
+ point C = trilinear(t, bc, ca, -ab);
+ return triangle(A, B, C);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(triangle,line,bool)"><code></asyxml>*/
+point[] intersectionpoints(triangle t, line l, bool extended = false)
+{/*<asyxml></code><documentation>Return the intersection points.
+ If 'extended' is true, the sides are lines else the sides are segments.
+ intersectionpoints(line, triangle, bool) is also defined.</documentation></function></asyxml>*/
+ point[] OP;
+ void addpoint(point P)
+ {
+ if(defined(P)) {
+ bool exist = false;
+ for (int i = 0; i < OP.length; ++i) {
+ if(P == OP[i]) {exist = true; break;}
+ }
+ if(!exist) OP.push(P);
+ }
+ }
+ if(extended) {
+ for (int i = 1; i <= 3; ++i) {
+ addpoint(intersectionpoint(t.line(i), l));
+ }
+ } else {
+ for (int i = 1; i <= 3; ++i) {
+ addpoint(intersectionpoint((segment)t.line(i), l));
+ }
+ }
+ return OP;
+}
+
+point[] intersectionpoints(line l, triangle t, bool extended = false)
+{
+ return intersectionpoints(t, l, extended);
+}
+
+/*<asyxml><function type="vector" signature="dir(vertex)"><code></asyxml>*/
+vector dir(vertex V)
+{/*<asyxml></code><documentation>The direction (towards the outside of the triangle) of the interior angle bisector of 'V'.</documentation></function></asyxml>*/
+ triangle t = V.t;
+ if(V.n == 1) return vector(defaultcoordsys, (-dir(t.A--t.B, t.A--t.C)));
+ if(V.n == 2) return vector(defaultcoordsys, (-dir(t.B--t.A, t.B--t.C)));
+ return vector(defaultcoordsys, (-dir(t.C--t.A, t.C--t.B)));
+}
+
+/*<asyxml><function type="void" signature="lvoid label(picture,Label,vertex,pair,real,pen,filltype)"><code></asyxml>*/
+void label(picture pic = currentpicture, Label L, vertex V,
+ pair align = dir(V),
+ real alignFactor = 1,
+ pen p = nullpen, filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw 'L' on picture 'pic' at vertex 'V' aligned by 'alignFactor * align'.</documentation></function></asyxml>*/
+ label(pic, L, locate(point(V)), alignFactor * align, p, filltype);
+}
+
+/*<asyxml><function type="void" signature="label(picture,Label,Label,Label,triangle,real,real,pen,filltype)"><code></asyxml>*/
+void label(picture pic = currentpicture, Label LA = "$A$",
+ Label LB = "$B$", Label LC = "$C$",
+ triangle t,
+ real alignAngle = 0,
+ real alignFactor = 1,
+ pen p = nullpen, filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw labels LA, LB and LC aligned in the rotated (by 'alignAngle' in degrees) direction
+ (towards the outside of the triangle) of the interior angle bisector of vertices.
+ One can individually modify the alignment by setting the Label parameter 'align'.</documentation></function></asyxml>*/
+ Label lla = LA.copy();
+ lla.align(lla.align, rotate(alignAngle) * locate(dir(t.VA)));
+ label(pic, LA, t.VA, align = lla.align.dir, alignFactor = alignFactor, p, filltype);
+ Label llb = LB.copy();
+ llb.align(llb.align, rotate(alignAngle) * locate(dir(t.VB)));
+ label(pic, llb, t.VB, align = llb.align.dir, alignFactor = alignFactor, p, filltype);
+ Label llc = LC.copy();
+ llc.align(llc.align, rotate(alignAngle) * locate(dir(t.VC)));
+ label(pic, llc, t.VC, align = llc.align.dir, alignFactor = alignFactor, p, filltype);
+}
+
+/*<asyxml><function type="void" signature="show(picture,Label,Label,Label,Label,Label,Label,triangle,pen,filltype)"><code></asyxml>*/
+void show(picture pic = currentpicture,
+ Label LA = "$A$", Label LB = "$B$", Label LC = "$C$",
+ Label La = "$a$", Label Lb = "$b$", Label Lc = "$c$",
+ triangle t, pen p = currentpen, filltype filltype = NoFill)
+{/*<asyxml></code><documentation>Draw triangle and labels of sides and vertices.</documentation></function></asyxml>*/
+ pair a = locate(t.A), b = locate(t.B), c = locate(t.C);
+ draw(pic, a--b--c--cycle, p);
+ label(pic, LA, a, -dir(a--b, a--c), p, filltype);
+ label(pic, LB, b, -dir(b--a, b--c), p, filltype);
+ label(pic, LC, c, -dir(c--a, c--b), p, filltype);
+ pair aligna = I * unit(c - b), alignb = I * unit(c - a), alignc = I * unit(b - a);
+ pair mAB = locate(midpoint(t.AB)), mAC = locate(midpoint(t.AC)), mBC = locate(midpoint(t.BC));
+ label(pic, La, b--c, align = rotate(dot(a - mBC, aligna) > 0 ? 180 :0) * aligna, p);
+ label(pic, Lb, a--c, align = rotate(dot(b - mAC, alignb) > 0 ? 180 :0) * alignb, p);
+ label(pic, Lc, a--b, align = rotate(dot(c - mAB, alignc) > 0 ? 180 :0) * alignc, p);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,triangle,pen,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, triangle t, pen p = currentpen, marker marker = nomarker)
+{/*<asyxml></code><documentation>Draw sides of the triangle 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/
+ draw(pic, t.Path(), p, marker);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,triangle[],pen,marker)"><code></asyxml>*/
+void draw(picture pic = currentpicture, triangle[] t, pen p = currentpen, marker marker = nomarker)
+{/*<asyxml></code><documentation>Draw sides of the triangles 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/
+ for(int i = 0; i < t.length; ++i) draw(pic, t[i], p, marker);
+}
+
+/*<asyxml><function type="void" signature="drawline(picture,triangle,pen)"><code></asyxml>*/
+void drawline(picture pic = currentpicture, triangle t, pen p = currentpen)
+{/*<asyxml></code><documentation>Draw lines of the triangle 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/
+ draw(t, p);
+ draw(pic, line(t.A, t.B), p);
+ draw(pic, line(t.A, t.C), p);
+ draw(pic, line(t.B, t.C), p);
+}
+
+/*<asyxml><function type="void" signature="dot(picture,triangle,pen)"><code></asyxml>*/
+void dot(picture pic = currentpicture, triangle t, pen p = currentpen)
+{/*<asyxml></code><documentation>Draw a dot at each vertex of 't'.</documentation></function></asyxml>*/
+ dot(pic, t.A^^t.B^^t.C, p);
+}
+// *.......................TRIANGLES.......................*
+// *=======================================================*
+
+// *=======================================================*
+// *.......................INVERSIONS......................*
+/*<asyxml><function type="point" signature="inverse(real k,point,point)"><code></asyxml>*/
+point inverse(real k, point A, point M)
+{/*<asyxml></code><documentation>Return the inverse point of 'M' with respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/
+ return A + k/conj(M - A);
+}
+
+/*<asyxml><function type="point" signature="radicalcenter(circle,circle)"><code></asyxml>*/
+point radicalcenter(circle c1, circle c2)
+{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(c1.C, c2.C);
+ real k = c1.r^2 - c2.r^2;
+ pair C1 = locate(c1.C);
+ pair C2 = locate(c2.C);
+ pair oop = C2 - C1;
+ pair K = (abs(oop) == 0) ?
+ (infinity, infinity) :
+ midpoint(C1--C2) + 0.5 * k * oop/dot(oop, oop);
+ return point(P[0].coordsys, K/P[0].coordsys);
+}
+
+/*<asyxml><function type="line" signature="radicalline(circle,circle)"><code></asyxml>*/
+line radicalline(circle c1, circle c2)
+{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/
+ if (c1.C == c2.C) abort("radicalline: the centers must be distinct");
+ return perpendicular(radicalcenter(c1, c2), line(c1.C, c2.C));
+}
+
+/*<asyxml><function type="point" signature="radicalcenter(circle,circle,circle)"><code></asyxml>*/
+point radicalcenter(circle c1, circle c2, circle c3)
+{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/
+ return intersectionpoint(radicalline(c1, c2), radicalline(c1, c3));
+}
+
+/*<asyxml><struct signature="inversion"><code></asyxml>*/
+struct inversion
+{/*<asyxml></code><documentation>http://mathworld.wolfram.com/Inversion.html</documentation></asyxml>*/
+ point C;
+ real k;
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="inversion" signature="inversion(real,point)"><code></asyxml>*/
+inversion inversion(real k, point C)
+{/*<asyxml></code><documentation>Return the inversion with respect to 'C' having inversion radius 'k'.</documentation></function></asyxml>*/
+ inversion oi;
+ oi.k = k;
+ oi.C = C;
+ return oi;
+}
+/*<asyxml><function type="inversion" signature="inversion(real,point)"><code></asyxml>*/
+inversion inversion(point C, real k)
+{/*<asyxml></code><documentation>Return the inversion with respect to 'C' having inversion radius 'k'.</documentation></function></asyxml>*/
+ return inversion(k, C);
+}
+
+/*<asyxml><function type="inversion" signature="inversion(circle,circle)"><code></asyxml>*/
+inversion inversion(circle c1, circle c2, real sgn = 1)
+{/*<asyxml></code><documentation>Return the inversion which transforms 'c1' to
+ . 'c2' and positive inversion radius if 'sgn > 0';
+ . 'c2' and negative inversion radius if 'sgn < 0';
+ . 'c1' and 'c2' to 'c2' if 'sgn = 0'.</documentation></function></asyxml>*/
+ if(sgn == 0) {
+ point O = radicalcenter(c1, c2);
+ return inversion(O^c1, O);
+ }
+ real a = abs(c1.r/c2.r);
+ if(sgn > 0) {
+ point O = c1.C + a/abs(1 - a) * (c2.C - c1.C);
+ return inversion(a * abs(abs(O - c2.C)^2 - c2.r^2), O);
+ }
+ point O = c1.C + a/abs(1 + a) * (c2.C - c1.C);
+ return inversion(-a * abs(abs(O - c2.C)^2 - c2.r^2), O);
+}
+
+/*<asyxml><function type="inversion" signature="inversion(circle,circle,circle)"><code></asyxml>*/
+inversion inversion(circle c1, circle c2, circle c3)
+{/*<asyxml></code><documentation>Return the inversion which transform 'c1' to 'c1', 'c2' to 'c2' and 'c3' to 'c3'.</documentation></function></asyxml>*/
+ point Rc = radicalcenter(c1, c2, c3);
+ return inversion(Rc, Rc^c1);
+}
+
+circle operator cast(inversion i){return circle(i.C, sgn(i.k) * sqrt(abs(i.k)));}
+/*<asyxml><function type="circle" signature="circle(inversion)"><code></asyxml>*/
+circle circle(inversion i)
+{/*<asyxml></code><documentation>Return the inversion circle of 'i'.</documentation></function></asyxml>*/
+ return i;
+}
+
+inversion operator cast(circle c)
+{
+ return inversion(sgn(c.r) * c.r^2, c.C);
+}
+/*<asyxml><function type="inversion" signature="inversion(circle)"><code></asyxml>*/
+inversion inversion(circle c)
+{/*<asyxml></code><documentation>Return the inversion represented by the circle of 'c'.</documentation></function></asyxml>*/
+ return c;
+}
+
+/*<asyxml><operator type = "point" signature="*(inversion,point)"><code></asyxml>*/
+point operator *(inversion i, point P)
+{/*<asyxml></code><documentation>Provide inversion * point.</documentation></operator></asyxml>*/
+ return inverse(i.k, i.C, P);
+}
+
+void lineinversion()
+{
+ warning("lineinversion", "the inversion of the line is not a circle.
+The returned circle has an infinite radius, circle.l has been set.");
+}
+
+
+/*<asyxml><function type="circle" signature="inverse(real,point,line)"><code></asyxml>*/
+circle inverse(real k, point A, line l)
+{/*<asyxml></code><documentation>Return the inverse circle of 'l' with
+ respect to point 'A' and inversion radius 'k'.</documentation></function></asyxml>*/
+ if(A @ l) {
+ lineinversion();
+ circle C = circle(A, infinity);
+ C.l = l;
+ return C;
+ }
+ point Ap = inverse(k, A, l.A), Bp = inverse(k, A, l.B);
+ return circle(A, Ap, Bp);
+}
+
+/*<asyxml><operator type = "circle" signature="*(inversion,line)"><code></asyxml>*/
+circle operator *(inversion i, line l)
+{/*<asyxml></code><documentation>Provide inversion * line for lines that don't pass through the inversion center.</documentation></operator></asyxml>*/
+ return inverse(i.k, i.C, l);
+}
+
+/*<asyxml><function type="circle" signature="inverse(real,point,circle)"><code></asyxml>*/
+circle inverse(real k, point A, circle c)
+{/*<asyxml></code><documentation>Return the inverse circle of 'c' with
+ respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/
+ if(degenerate(c)) return inverse(k, A, c.l);
+ if(A @ c) {
+ lineinversion();
+ point M = rotate(180, c.C) * A, Mp = rotate(90, c.C) * A;
+ circle oc = circle(A, infinity);
+ oc.l = line(inverse(k, A, M), inverse(k, A, Mp));
+ return oc;
+ }
+ point[] P = standardizecoordsys(A, c.C);
+ real s = k/((P[1].x - P[0].x)^2 + (P[1].y - P[0].y)^2 - c.r^2);
+ return circle(P[0] + s * (P[1]-P[0]), abs(s) * c.r);
+}
+
+/*<asyxml><operator type = "circle" signature="*(inversion,circle)"><code></asyxml>*/
+circle operator *(inversion i, circle c)
+{/*<asyxml></code><documentation>Provide inversion * circle.</documentation></operator></asyxml>*/
+ return inverse(i.k, i.C, c);
+}
+// *.......................INVERSIONS......................*
+// *=======================================================*
+
+// *=======================================================*
+// *........................FOOTER.........................*
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,circle)"><code></asyxml>*/
+point[] intersectionpoints(line l, circle c)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(circle, line) is also defined.</documentation></function></asyxml>*/
+ if(degenerate(c)) return new point[]{intersectionpoint(l, c.l)};
+ point[] op;
+ coordsys R = samecoordsys(l.A, c.C) ?
+ l.A.coordsys : defaultcoordsys;
+ coordsys Rp = defaultcoordsys;
+ circle cc = circle(changecoordsys(Rp, c.C), c.r);
+ point proj = projection(l) * c.C;
+ if(proj @ cc) { // The line is a tangente of the circle.
+ if(proj @ l) op.push(proj);// line may be a segement...
+ } else {
+ coordsys Rc = cartesiansystem(c.C, (1, 0), (0, 1));
+ line ll = changecoordsys(Rc, l);
+ pair[] P = intersectionpoints(ll.A.coordinates, ll.B.coordinates,
+ 1, 0, 1, 0, 0, -c.r^2);
+ for (int i = 0; i < P.length; ++i) {
+ point inter = changecoordsys(R, point(Rc, P[i]));
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(circle c, line l)
+{
+ return intersectionpoints(l, c);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(line l, ellipse el)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(ellipse, line) is also defined.</documentation></function></asyxml>*/
+ if(el.e == 0) return intersectionpoints(l, (circle)el);
+ if(degenerate(el)) return new point[]{intersectionpoint(l, el.l)};
+ point[] op;
+ coordsys R = samecoordsys(l.A, el.C) ? l.A.coordsys : defaultcoordsys;
+ coordsys Rp = defaultcoordsys;
+ line ll = changecoordsys(Rp, l);
+ ellipse ell = changecoordsys(Rp, el);
+ circle C = circle(ell.C, ell.a);
+ point[] Ip = intersectionpoints(ll, C);
+ if (Ip.length > 0 &&
+ (perpendicular(ll, line(ell.F1, Ip[0])) ||
+ perpendicular(ll, line(ell.F2, Ip[0])))) {
+ // http://www.mathcurve.com/courbes2d/ellipse/ellipse.shtml
+ // Définition tangentielle par antipodaire de cercle.
+ // 'l' is a tangent of 'el'
+ transform t = scale(el.a/el.b, el.F1, el.F2, el.C, rotate(90, el.C) * el.F1);
+ point inter = inverse(t) * intersectionpoints(C, t * ll)[0];
+ if(inter @ l) op.push(inter);
+ } else {
+ coordsys Rc = canonicalcartesiansystem(el);
+ line ll = changecoordsys(Rc, l);
+ pair[] P = intersectionpoints(ll.A.coordinates, ll.B.coordinates,
+ 1/el.a^2, 0, 1/el.b^2, 0, 0, -1);
+ for (int i = 0; i < P.length; ++i) {
+ point inter = changecoordsys(R, point(Rc, P[i]));
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(ellipse el, line l)
+{
+ return intersectionpoints(l, el);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,parabola)"><code></asyxml>*/
+point[] intersectionpoints(line l, parabola p)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(parabola, line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ coordsys R = coordsys(p);
+ bool tgt = false;
+ line ll = changecoordsys(R, l),
+ lv = parallel(p.V, p.D);
+ point M = intersectionpoint(lv, ll), tgtp;
+ if(finite(M)) {// Test if 'l' is tangent to 'p'
+ line l1 = bisector(line(M, p.F));
+ line l2 = rotate(90, M) * lv;
+ point P = intersectionpoint(l1, l2);
+ tgtp = rotate(180, P) * p.F;
+ tgt = (tgtp @ l);
+ }
+ if(tgt) {
+ if(tgtp @ l) op.push(tgtp);
+ } else {
+ real[] eq = changecoordsys(defaultcoordsys, equation(p)).a;
+ pair[] tp = intersectionpoints(locate(l.A), locate(l.B), eq);
+ point inter;
+ for (int i = 0; i < tp.length; ++i) {
+ inter = point(R, tp[i]/R);
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(parabola p, line l)
+{
+ return intersectionpoints(l, p);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(line l, hyperbola h)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(hyperbola, line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ coordsys R = coordsys(h);
+ point A = intersectionpoint(l, h.A1), B = intersectionpoint(l, h.A2);
+ point M = midpoint(segment(A, B));
+ bool tgt = M @ h;
+ if(tgt) {
+ if(M @ l) op.push(M);
+ } else {
+ real[] eq = changecoordsys(defaultcoordsys, equation(h)).a;
+ pair[] tp = intersectionpoints(locate(l.A), locate(l.B), eq);
+ point inter;
+ for (int i = 0; i < tp.length; ++i) {
+ inter = point(R, tp[i]/R);
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(hyperbola h, line l)
+{
+ return intersectionpoints(l, h);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,conic)"><code></asyxml>*/
+point[] intersectionpoints(line l, conic co)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(conic, line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ if(co.e < 1) op = intersectionpoints((ellipse)co, l);
+ else
+ if(co.e == 1) op = intersectionpoints((parabola)co, l);
+ else op = intersectionpoints((hyperbola)co, l);
+ return op;
+}
+
+point[] intersectionpoints(conic co, line l)
+{
+ return intersectionpoints(l, co);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(conic,conic)"><code></asyxml>*/
+point[] intersectionpoints(conic co1, conic co2)
+{/*<asyxml></code><documentation>Return the intersection points of the two conics.</documentation></function></asyxml>*/
+ if(degenerate(co1)) return intersectionpoints(co1.l[0], co2);
+ if(degenerate(co2)) return intersectionpoints(co1, co2.l[0]);
+ return intersectionpoints(equation(co1), equation(co2));
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(triangle,conic,bool)"><code></asyxml>*/
+point[] intersectionpoints(triangle t, conic co, bool extended = false)
+{/*<asyxml></code><documentation>Return the intersection points.
+ If 'extended' is true, the sides are lines else the sides are segments.
+ intersectionpoints(conic, triangle, bool) is also defined.</documentation></function></asyxml>*/
+ if(degenerate(co)) return intersectionpoints(t, co.l[0], extended);
+ point[] OP;
+ void addpoint(point P[])
+ {
+ for (int i = 0; i < P.length; ++i) {
+ if(defined(P[i])) {
+ bool exist = false;
+ for (int j = 0; j < OP.length; ++j) {
+ if(P[i] == OP[j]) {exist = true; break;}
+ }
+ if(!exist) OP.push(P[i]);
+ }}}
+ if(extended) {
+ for (int i = 1; i <= 3; ++i) {
+ addpoint(intersectionpoints(t.line(i), co));
+ }
+ } else {
+ for (int i = 1; i <= 3; ++i) {
+ addpoint(intersectionpoints((segment)t.line(i), co));
+ }
+ }
+ return OP;
+}
+
+point[] intersectionpoints(conic co, triangle t, bool extended = false)
+{
+ return intersectionpoints(t, co, extended);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l, b);
+ // if(degenerate(b)) return intersectionpoints(a, b.l);;
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,circle)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, circle b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l, b);
+ // if(degenerate(b)) return intersectionpoints(a, b.l);;
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(circle a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints(b, a);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,parabola)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l, b);
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints(b, a);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l, b);
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints(b, a);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,parabola)"><code></asyxml>*/
+point[] intersectionpoints(circle a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,circle)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, circle b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(circle a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,circle)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, circle b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,parabola)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,parabola)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a, (conic)b);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,circle)"><code></asyxml>*/
+point[] intersectionpoints(circle c1, circle c2)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ if(degenerate(c1))
+ return degenerate(c2) ?
+ new point[]{intersectionpoint(c1.l, c2.l)} : intersectionpoints(c1.l, c2);
+ if(degenerate(c2)) return intersectionpoints(c1, c2.l);
+ return (c1.C == c2.C) ?
+ new point[] :
+ intersectionpoints(radicalline(c1, c2), c1);
+}
+
+/*<asyxml><function type="line" signature="tangent(circle,abscissa)"><code></asyxml>*/
+line tangent(circle c, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'c' at 'point(c, x)'.</documentation></function></asyxml>*/
+ if(c.r == 0) abort("tangent: a circle with a radius equals zero has no tangent.");
+ point M = point(c, x);
+ return line(rotate(90, M) * c.C, M);
+}
+
+/*<asyxml><function type="line[]" signature="tangents(circle,point)"><code></asyxml>*/
+line[] tangents(circle c, point M)
+{/*<asyxml></code><documentation>Return the tangents of 'c' passing through 'M'.</documentation></function></asyxml>*/
+ line[] ol;
+ if(inside(c, M)) return ol;
+ if(M @ c) {
+ ol.push(tangent(c, relabscissa(c, M)));
+ } else {
+ circle cc = circle(c.C, M);
+ point[] inter = intersectionpoints(c, cc);
+ for (int i = 0; i < inter.length; ++i)
+ ol.push(tangents(c, inter[i])[0]);
+ }
+ return ol;
+}
+
+/*<asyxml><function type="point" signature="point(circle,point)"><code></asyxml>*/
+point point(circle c, point M)
+{/*<asyxml></code><documentation>Return the intersection point of 'c'
+ with the half-line '[c.C M)'.</documentation></function></asyxml>*/
+ return intersectionpoints(c, line(c.C, false, M))[0];
+}
+
+/*<asyxml><function type="line" signature="tangent(circle,point)"><code></asyxml>*/
+line tangent(circle c, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'c' at the
+ intersection point of the half-line'[c.C M)'.</documentation></function></asyxml>*/
+ return tangents(c, point(c, M))[0];
+}
+
+/*<asyxml><function type="point" signature="point(circle,explicit vector)"><code></asyxml>*/
+point point(circle c, explicit vector v)
+{/*<asyxml></code><documentation>Return the intersection point of 'c'
+ with the half-line '[c.C v)'.</documentation></function></asyxml>*/
+ return point(c, c.C + v);
+}
+
+/*<asyxml><function type="line" signature="tangent(circle,explicit vector)"><code></asyxml>*/
+line tangent(circle c, explicit vector v)
+{/*<asyxml></code><documentation>Return the tangent of 'c' at the
+ point M so that vec(c.C M) is collinear to 'v' with the same sense.</documentation></function></asyxml>*/
+ line ol = tangent(c, c.C + v);
+ return dot(ol.v, v) > 0 ? ol : reverse(ol);
+}
+
+/*<asyxml><function type="line" signature="tangent(ellipse,abscissa)"><code></asyxml>*/
+line tangent(ellipse el, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'el' at 'point(el, x)'.</documentation></function></asyxml>*/
+ point M = point(el, x);
+ line l1 = line(el.F1, M);
+ line l2 = line(el.F2, M);
+ line ol = (l1 == l2) ? perpendicular(M, l1) : bisector(l1, l2, 90, false);
+ return ol;
+}
+
+/*<asyxml><function type="line[]" signature="tangents(ellipse,point)"><code></asyxml>*/
+line[] tangents(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the tangents of 'el' passing through 'M'.</documentation></function></asyxml>*/
+ line[] ol;
+ if(inside(el, M)) return ol;
+ if(M @ el) {
+ ol.push(tangent(el, relabscissa(el, M)));
+ } else {
+ point Mp = samecoordsys(M, el.F2) ?
+ M : changecoordsys(el.F2.coordsys, M);
+ circle c = circle(Mp, abs(el.F1 - Mp));
+ circle cc = circle(el.F2, 2 * el.a);
+ point[] inter = intersectionpoints(c, cc);
+ for (int i = 0; i < inter.length; ++i) {
+ line tl = line(inter[i], el.F2, false);
+ point[] P = intersectionpoints(tl, el);
+ ol.push(line(Mp, P[0]));
+ }
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="tangent(parabola,abscissa)"><code></asyxml>*/
+line tangent(parabola p, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'p' at 'point(p, x)' (use the Wells method).</documentation></function></asyxml>*/
+ line lt = rotate(90, p.V) * line(p.V, p.F);
+ point P = point(p, x);
+ if(P == p.V) return lt;
+ point M = midpoint(segment(P, p.F));
+ line l = rotate(90, M) * line(P, p.F);
+ return line(P, projection(lt) * M);
+}
+
+/*<asyxml><function type="line[]" signature="tangents(parabola,point)"><code></asyxml>*/
+line[] tangents(parabola p, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'p' at 'M' (use the Wells method).</documentation></function></asyxml>*/
+ line[] ol;
+ if(inside(p, M)) return ol;
+ if(M @ p) {
+ ol.push(tangent(p, angabscissa(p, M)));
+ }
+ else {
+ point Mt = changecoordsys(coordsys(p), M);
+ circle c = circle(Mt, p.F);
+ line l = rotate(90, p.V) * line(p.V, p.F);
+ point[] R = intersectionpoints(l, c);
+ for (int i = 0; i < R.length; ++i) {
+ ol.push(line(Mt, R[i]));
+ }
+ // An other method: http://www.du.edu/~jcalvert/math/parabola.htm
+ // point[] R = intersectionpoints(p.directrix, c);
+ // for (int i = 0; i < R.length; ++i) {
+ // ol.push(bisector(segment(p.F, R[i])));
+ // }
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="tangent(hyperbola,abscissa)"><code></asyxml>*/
+line tangent(hyperbola h, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'h' at 'point(p, x)'.</documentation></function></asyxml>*/
+ point M = point(h, x);
+ line ol = bisector(line(M, h.F1), line(M, h.F2));
+ if(sameside(h.F1, h.F2, ol) || ol == line(h.F1, h.F2)) ol = rotate(90, M) * ol;
+ return ol;
+}
+
+/*<asyxml><function type="line[]" signature="tangents(hyperbola,point)"><code></asyxml>*/
+line[] tangents(hyperbola h, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'h' at 'M'.</documentation></function></asyxml>*/
+ line[] ol;
+ if(M @ h) {
+ ol.push(tangent(h, angabscissa(h, M, fromCenter)));
+ } else {
+ coordsys cano = canonicalcartesiansystem(h);
+ bqe bqe = changecoordsys(cano, equation(h));
+ real a = abs(1/(bqe.a[5] * bqe.a[0])), b = abs(1/(bqe.a[5] * bqe.a[2]));
+ point Mp = changecoordsys(cano, M);
+ real x0 = Mp.x, y0 = Mp.y;
+ if(abs(x0) > epsgeo) {
+ real c0 = a * y0^2/(b * x0)^2 - 1/b,
+ c1 = 2 * a * y0/(b * x0^2), c2 = a/x0^2 - 1;
+ real[] sol = quadraticroots(c0, c1, c2);
+ for (real y:sol) {
+ point tmp = changecoordsys(coordsys(h), point(cano, (a * (1 + y * y0/b)/x0, y)));
+ ol.push(line(M, tmp));
+ }
+ } else if(abs(y0) > epsgeo) {
+ real y = -b/y0, x = sqrt(a * (1 + b/y0^2));
+ ol.push(line(M, changecoordsys(coordsys(h), point(cano, (x, y)))));
+ ol.push(line(M, changecoordsys(coordsys(h), point(cano, (-x, y)))));
+ }}
+ return ol;
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(conic,arc)"><code></asyxml>*/
+point[] intersectionpoints(conic co, arc a)
+{/*<asyxml></code><documentation>intersectionpoints(arc, circle) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ point[] tp = intersectionpoints(co, (conic)a.el);
+ for (int i = 0; i < tp.length; ++i)
+ if(tp[i] @ a) op.push(tp[i]);
+ return op;
+}
+
+point[] intersectionpoints(arc a, conic co)
+{
+ return intersectionpoints(co, a);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(arc,arc)"><code></asyxml>*/
+point[] intersectionpoints(arc a1, arc a2)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ point[] op;
+ point[] tp = intersectionpoints(a1.el, a2.el);
+ for (int i = 0; i < tp.length; ++i)
+ if(tp[i] @ a1 && tp[i] @ a2) op.push(tp[i]);
+ return op;
+}
+
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,arc)"><code></asyxml>*/
+point[] intersectionpoints(line l, arc a)
+{/*<asyxml></code><documentation>intersectionpoints(arc, line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ point[] tp = intersectionpoints(a.el, l);
+ for (int i = 0; i < tp.length; ++i)
+ if(tp[i] @ a && tp[i] @ l) op.push(tp[i]);
+ return op;
+}
+
+point[] intersectionpoints(arc a, line l)
+{
+ return intersectionpoints(l, a);
+}
+
+/*<asyxml><function type="point" signature="arcsubtendedcenter(point,point,real)"><code></asyxml>*/
+point arcsubtendedcenter(point A, point B, real angle)
+{/*<asyxml></code><documentation>Return the center of the arc retuned
+ by the 'arcsubtended' routine.</documentation></function></asyxml>*/
+ point OM;
+ point[] P = standardizecoordsys(A, B);
+ angle = angle%(sgnd(angle) * 180);
+ line bis = bisector(P[0], P[1]);
+ line AB = line(P[0], P[1]);
+ return intersectionpoint(bis, rotate(90 - angle, A) * AB);
+}
+
+/*<asyxml><function type="arc" signature="arcsubtended(point,point,real)"><code></asyxml>*/
+arc arcsubtended(point A, point B, real angle)
+{/*<asyxml></code><documentation>Return the arc circle from which the segment AB is saw with
+ the angle 'angle'.
+ If the point 'M' is on this arc, the oriented angle (MA, MB) is
+ equal to 'angle'.</documentation></function></asyxml>*/
+ point[] P = standardizecoordsys(A, B);
+ line AB = line(P[0], P[1]);
+ angle = angle%(sgnd(angle) * 180);
+ point C = arcsubtendedcenter(P[0], P[1], angle);
+ real BC = degrees(B - C)%360;
+ real AC = degrees(A - C)%360;
+ return arc(circle(C, abs(B - C)), BC, AC, angle > 0 ? CCW : CW);
+}
+
+/*<asyxml><function type="arc" signature="arccircle(point,point,point)"><code></asyxml>*/
+arc arccircle(point A, point M, point B)
+{/*<asyxml></code><documentation>Return the CCW arc circle 'AB' passing through 'M'.</documentation></function></asyxml>*/
+ circle tc = circle(A, M, B);
+ real a = degrees(A - tc.C);
+ real b = degrees(B - tc.C);
+ real m = degrees(M - tc.C);
+
+ arc oa = arc(tc, a, b);
+ // TODO : use cross product to determine CWW or CW
+ if (!(M @ oa)) {
+ oa.direction = !oa.direction;
+ }
+
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="arc(ellipse,abscissa,abscissa,bool)"><code></asyxml>*/
+arc arc(ellipse el, explicit abscissa x1, explicit abscissa x2, bool direction = CCW)
+{/*<asyxml></code><documentation>Return the arc from 'point(c, x1)' to 'point(c, x2)' in the direction 'direction'.</documentation></function></asyxml>*/
+ real a = degrees(point(el, x1) - el.C);
+ real b = degrees(point(el, x2) - el.C);
+ arc oa = arc(el, a - el.angle, b - el.angle, fromCenter, direction);
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="arc(ellipse,point,point,bool)"><code></asyxml>*/
+arc arc(ellipse el, point M, point N, bool direction = CCW)
+{/*<asyxml></code><documentation>Return the arc from 'M' to 'N' in the direction 'direction'.
+ The points 'M' and 'N' must belong to the ellipse 'el'.</documentation></function></asyxml>*/
+ return arc(el, relabscissa(el, M), relabscissa(el, N), direction);
+}
+
+/*<asyxml><function type="arc" signature="arccircle(point,point,real,bool)"><code></asyxml>*/
+arc arccircle(point A, point B, real angle, bool direction = CCW)
+{/*<asyxml></code><documentation>Return the arc circle centered on A
+ from B to rotate(angle, A) * B in the direction 'direction'.</documentation></function></asyxml>*/
+ point M = rotate(angle, A) * B;
+ return arc(circle(A, abs(A - B)), B, M, direction);
+}
+
+/*<asyxml><function type="arc" signature="arc(explicit arc,abscissa,abscissa)"><code></asyxml>*/
+arc arc(explicit arc a, abscissa x1, abscissa x2)
+{/*<asyxml></code><documentation>Return the arc from 'point(a, x1)' to 'point(a, x2)' traversed in the direction of the arc direction.</documentation></function></asyxml>*/
+ real a1 = angabscissa(a.el, point(a, x1), a.polarconicroutine).x;
+ real a2 = angabscissa(a.el, point(a, x2), a.polarconicroutine).x;
+ return arc(a.el, a1, a2, a.polarconicroutine, a.direction);
+}
+
+/*<asyxml><function type="arc" signature="arc(explicit arc,point,point)"><code></asyxml>*/
+arc arc(explicit arc a, point M, point N)
+{/*<asyxml></code><documentation>Return the arc from 'M' to 'N'.
+ The points 'M' and 'N' must belong to the arc 'a'.</documentation></function></asyxml>*/
+ return arc(a, relabscissa(a, M), relabscissa(a, N));
+}
+
+/*<asyxml><function type="arc" signature="inverse(real,point,segment)"><code></asyxml>*/
+arc inverse(real k, point A, segment s)
+{/*<asyxml></code><documentation>Return the inverse arc circle of 's'
+ with respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/
+ point Ap = inverse(k, A, s.A), Bp = inverse(k, A, s.B),
+ M = inverse(k, A, midpoint(s));
+ return arccircle(Ap, M, Bp);
+}
+
+/*<asyxml><operator type = "arc" signature="*(inversion,segment)"><code></asyxml>*/
+arc operator *(inversion i, segment s)
+{/*<asyxml></code><documentation>Provide
+ inversion * segment.</documentation></operator></asyxml>*/
+ return inverse(i.k, i.C, s);
+}
+
+/*<asyxml><operator type = "path" signature="*(inversion,triangle)"><code></asyxml>*/
+path operator *(inversion i, triangle t)
+{/*<asyxml></code><documentation>Provide inversion * triangle.</documentation></operator></asyxml>*/
+ return (path)(i * segment(t.AB))--
+ (path)(i * segment(t.BC))--
+ (path)(i * segment(t.CA))&cycle;
+}
+
+/*<asyxml><function type="path" signature="compassmark(pair,pair,real,real)"><code></asyxml>*/
+path compassmark(pair O, pair A, real position, real angle = 10)
+{/*<asyxml></code><documentation>Return an arc centered on O with the angle 'angle' so that the position
+ of 'A' on this arc makes an angle 'position * angle'.</documentation></function></asyxml>*/
+ real a = degrees(A - O);
+ real pa = (a - position * angle)%360,
+ pb = (a - (position - 1) * angle)%360;
+ real t1 = intersect(unitcircle, (0, 0)--2 * dir(pa))[0];
+ real t2 = intersect(unitcircle, (0, 0)--2 * dir(pb))[0];
+ int n = length(unitcircle);
+ if(t1 >= t2) t1 -= n;
+ return shift(O) * scale(abs(O - A)) * subpath(unitcircle, t1, t2);
+}
+
+/*<asyxml><function type="line" signature="tangent(explicit arc,abscissa)"><code></asyxml>*/
+line tangent(explicit arc a, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'a' at 'point(a, x)'.</documentation></function></asyxml>*/
+ abscissa ag = angabscissa(a, point(a, x));
+ return tangent(a.el, ag + a.angle1 + (a.el.e == 0 ? a.angle0 : 0));
+}
+
+/*<asyxml><function type="line" signature="tangent(explicit arc,point)"><code></asyxml>*/
+line tangent(explicit arc a, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'a' at 'M'.
+ The points 'M' must belong to the arc 'a'.</documentation></function></asyxml>*/
+ return tangent(a, angabscissa(a, M));
+}
+
+// *=======================================================*
+// *.......Routines for compatibility with original geometry module........*
+
+path square(pair z1, pair z2)
+{
+ pair v = z2 - z1;
+ pair z3 = z2 + I * v;
+ pair z4 = z3 - v;
+ return z1--z2--z3--z4--cycle;
+}
+
+// Draw a perpendicular symbol at z aligned in the direction align
+// relative to the path z--z + dir.
+void perpendicular(picture pic = currentpicture, pair z, pair align,
+ pair dir = E, real size = 0, pen p = currentpen,
+ margin margin = NoMargin, filltype filltype = NoFill)
+{
+ perpendicularmark(pic, (point) z, align, dir, size, p, margin, filltype);
+}
+
+
+// Draw a perpendicular symbol at z aligned in the direction align
+// relative to the path z--z + dir(g, 0)
+void perpendicular(picture pic = currentpicture, pair z, pair align, path g,
+ real size = 0, pen p = currentpen, margin margin = NoMargin,
+ filltype filltype = NoFill)
+{
+ perpendicularmark(pic, (point) z, align, dir(g, 0), size, p, margin, filltype);
+}
+
+// Return an interior arc BAC of triangle ABC, given a radius r > 0.
+// If r < 0, return the corresponding exterior arc of radius |r|.
+path arc(explicit pair B, explicit pair A, explicit pair C, real r)
+{
+ real BA = degrees(B - A);
+ real CA = degrees(C - A);
+ return arc(A, abs(r), BA, CA, (r < 0) ^ ((BA-CA) % 360 < 180) ? CW : CCW);
+}
+
+// *.......End of compatibility routines........*
+// *=======================================================*
+
+// *........................FOOTER.........................*
+// *=======================================================*
diff --git a/graphics/asymptote/base/graph.asy b/graphics/asymptote/base/graph.asy
new file mode 100644
index 0000000000..7498ce8bfd
--- /dev/null
+++ b/graphics/asymptote/base/graph.asy
@@ -0,0 +1,2243 @@
+private import math;
+import graph_splinetype;
+import graph_settings;
+
+scaleT Linear;
+
+scaleT Log=scaleT(log10,pow10,logarithmic=true);
+scaleT Logarithmic=Log;
+
+string baselinetemplate="$10^4$";
+
+// A linear scale, with optional autoscaling of minimum and maximum values,
+// scaling factor s and intercept.
+scaleT Linear(bool automin=false, bool automax=automin, real s=1,
+ real intercept=0)
+{
+ real sinv=1/s;
+ scalefcn T,Tinv;
+ if(s == 1 && intercept == 0)
+ T=Tinv=identity;
+ else {
+ T=new real(real x) {return (x-intercept)*s;};
+ Tinv=new real(real x) {return x*sinv+intercept;};
+ }
+ return scaleT(T,Tinv,logarithmic=false,automin,automax);
+}
+
+// A logarithmic scale, with optional autoscaling of minimum and maximum
+// values.
+scaleT Log(bool automin=false, bool automax=automin)
+{
+ return scaleT(Log.T,Log.Tinv,logarithmic=true,automin,automax);
+}
+
+// A "broken" linear axis omitting the segment [a,b].
+scaleT Broken(real a, real b, bool automin=false, bool automax=automin)
+{
+ real skip=b-a;
+ real T(real x) {
+ if(x <= a) return x;
+ if(x <= b) return a;
+ return x-skip;
+ }
+ real Tinv(real x) {
+ if(x <= a) return x;
+ return x+skip;
+ }
+ return scaleT(T,Tinv,logarithmic=false,automin,automax);
+}
+
+// A "broken" logarithmic axis omitting the segment [a,b], where a and b are
+// automatically rounded to the nearest integral power of the base.
+scaleT BrokenLog(real a, real b, bool automin=false, bool automax=automin)
+{
+ real A=round(Log.T(a));
+ real B=round(Log.T(b));
+ a=Log.Tinv(A);
+ b=Log.Tinv(B);
+ real skip=B-A;
+ real T(real x) {
+ if(x <= a) return Log.T(x);
+ if(x <= b) return A;
+ return Log.T(x)-skip;
+ }
+ real Tinv(real x) {
+ real X=Log.Tinv(x);
+ if(X <= a) return X;
+ return Log.Tinv(x+skip);
+ }
+ return scaleT(T,Tinv,logarithmic=true,automin,automax);
+}
+
+Label Break=Label("$\approx$",UnFill(0.2mm));
+
+void scale(picture pic=currentpicture, scaleT x, scaleT y=x, scaleT z=y)
+{
+ pic.scale.x.scale=x;
+ pic.scale.y.scale=y;
+ pic.scale.z.scale=z;
+ pic.scale.x.automin=x.automin;
+ pic.scale.y.automin=y.automin;
+ pic.scale.z.automin=z.automin;
+ pic.scale.x.automax=x.automax;
+ pic.scale.y.automax=y.automax;
+ pic.scale.z.automax=z.automax;
+}
+
+void scale(picture pic=currentpicture, bool xautoscale=false,
+ bool yautoscale=xautoscale, bool zautoscale=yautoscale)
+{
+ scale(pic,Linear(xautoscale,xautoscale),Linear(yautoscale,yautoscale),
+ Linear(zautoscale,zautoscale));
+}
+
+struct scientific
+{
+ int sign;
+ real mantissa;
+ int exponent;
+ int ceil() {return sign*ceil(mantissa);}
+ real scale(real x, real exp) {
+ static real max=0.1*realMax;
+ static real limit=-log10(max);
+ return x*(exp > limit ? 10^-exp : max);
+ }
+ real ceil(real x, real exp) {return ceil(sign*scale(abs(x),exp));}
+ real floor(real x, real exp) {return floor(sign*scale(abs(x),exp));}
+}
+
+// Convert x to scientific notation
+scientific scientific(real x)
+{
+ scientific s;
+ s.sign=sgn(x);
+ x=abs(x);
+ if(x == 0) {s.mantissa=0; s.exponent=-intMax; return s;}
+ real logx=log10(x);
+ s.exponent=floor(logx);
+ s.mantissa=s.scale(x,s.exponent);
+ return s;
+}
+
+// Autoscale limits and tick divisor.
+struct bounds {
+ real min;
+ real max;
+
+ // Possible tick intervals:
+ int[] divisor;
+
+ void operator init(real min, real max, int[] divisor=new int[]) {
+ this.min=min;
+ this.max=max;
+ this.divisor=divisor;
+ }
+}
+
+// Compute tick divisors.
+int[] divisors(int a, int b)
+{
+ int[] dlist;
+ int n=b-a;
+ dlist[0]=1;
+ if(n == 1) {dlist[1]=10; dlist[2]=100; return dlist;}
+ if(n == 2) {dlist[1]=2; return dlist;}
+ int sqrtn=floor(sqrt(n));
+ int i=0;
+ for(int d=2; d <= sqrtn; ++d)
+ if(n % d == 0 && (a*b >= 0 || b % (n/d) == 0)) dlist[++i]=d;
+ for(int d=sqrtn; d >= 1; --d)
+ if(n % d == 0 && (a*b >= 0 || b % d == 0)) dlist[++i]=quotient(n,d);
+ return dlist;
+}
+
+real upscale(real b, real a)
+{
+ if(b <= 5) b=5;
+ else if (b > 10 && a >= 0 && b <= 12) b=12;
+ else if (b > 10 && (a >= 0 || 15 % -a == 0) && b <= 15) b=15;
+ else b=ceil(b/10)*10;
+ return b;
+}
+
+// Compute autoscale limits and tick divisor.
+bounds autoscale(real Min, real Max, scaleT scale=Linear)
+{
+ bounds m;
+ if(scale.logarithmic) {
+ m.min=floor(Min);
+ m.max=ceil(Max);
+ return m;
+ }
+ if(!(finite(Min) && finite(Max)))
+ abort("autoscale requires finite limits");
+ Min=scale.Tinv(Min);
+ Max=scale.Tinv(Max);
+ m.min=Min;
+ m.max=Max;
+ if(Min > Max) {real temp=Min; Min=Max; Max=temp;}
+ if(Min == Max) {
+ if(Min == 0) {m.max=1; return m;}
+ if(Min > 0) {Min=0; Max *= 2;}
+ else {Min *= 2; Max=0;}
+ }
+
+ int sign;
+ if(Min < 0 && Max <= 0) {real temp=-Min; Min=-Max; Max=temp; sign=-1;}
+ else sign=1;
+ scientific sa=scientific(Min);
+ scientific sb=scientific(Max);
+ int exp=max(sa.exponent,sb.exponent);
+ real a=sa.floor(Min,exp);
+ real b=sb.ceil(Max,exp);
+
+ void zoom() {
+ --exp;
+ a=sa.floor(Min,exp);
+ b=sb.ceil(Max,exp);
+ }
+
+ if(sb.mantissa <= 1.5)
+ zoom();
+
+ while((b-a)*10.0^exp > 10*(Max-Min))
+ zoom();
+
+ real bsave=b;
+ if(b-a > (a >= 0 ? 8 : 6)) {
+ b=upscale(b,a);
+ if(a >= 0) {
+ if(a <= 5) a=0; else a=floor(a/10)*10;
+ } else a=-upscale(-a,-1);
+ }
+
+ // Redo b in case the value of a has changed
+ if(bsave-a > (a >= 0 ? 8 : 6))
+ b=upscale(bsave,a);
+
+ if(sign == -1) {real temp=-a; a=-b; b=temp;}
+ real Scale=10.0^exp;
+ m.min=scale.T(a*Scale);
+ m.max=scale.T(b*Scale);
+ if(m.min > m.max) {real temp=m.min; m.min=m.max; m.max=temp;}
+ m.divisor=divisors(round(a),round(b));
+ return m;
+}
+
+typedef string ticklabel(real);
+
+ticklabel Format(string s=defaultformat)
+{
+ return new string(real x) {return format(s,x);};
+}
+
+ticklabel OmitFormat(string s=defaultformat ... real[] x)
+{
+ return new string(real v) {
+ string V=format(s,v);
+ for(real a : x)
+ if(format(s,a) == V) return "";
+ return V;
+ };
+}
+
+string trailingzero="$%#$";
+string signedtrailingzero="$%+#$";
+
+ticklabel DefaultFormat=Format();
+ticklabel NoZeroFormat=OmitFormat(0);
+
+// Format tick values as integral powers of base; otherwise with DefaultFormat.
+ticklabel DefaultLogFormat(int base) {
+ return new string(real x) {
+ string exponent=format("%.4f",log(x)/log(base));
+ return find(exponent,".") == -1 ?
+ "$"+(string) base+"^{"+exponent+"}$" : format(x);
+ };
+}
+
+// Format all tick values as powers of base.
+ticklabel LogFormat(int base) {
+ return new string(real x) {
+ return format("$"+(string) base+"^{%g}$",log(x)/log(base));
+ };
+}
+
+ticklabel LogFormat=LogFormat(10);
+ticklabel DefaultLogFormat=DefaultLogFormat(10);
+
+// The default direction specifier.
+pair zero(real) {return 0;}
+
+struct ticklocate {
+ real a,b; // Tick values at point(g,0), point(g,length(g)).
+ autoscaleT S; // Autoscaling transformation.
+ pair dir(real t); // Absolute 2D tick direction.
+ triple dir3(real t); // Absolute 3D tick direction.
+ real time(real v); // Returns the time corresponding to the value v.
+ ticklocate copy() {
+ ticklocate T=new ticklocate;
+ T.a=a;
+ T.b=b;
+ T.S=S.copy();
+ T.dir=dir;
+ T.dir3=dir3;
+ T.time=time;
+ return T;
+ }
+}
+
+autoscaleT defaultS;
+
+typedef real valuetime(real);
+
+valuetime linear(scalefcn S=identity, real Min, real Max)
+{
+ real factor=Max == Min ? 0.0 : 1.0/(Max-Min);
+ return new real(real v) {return (S(v)-Min)*factor;};
+}
+
+ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, pair dir(real)=zero)
+{
+ if((valuetime) time == null) time=linear(S.T(),a,b);
+ ticklocate locate;
+ locate.a=a;
+ locate.b=b;
+ locate.S=S.copy();
+ if(finite(tickmin)) locate.S.tickMin=tickmin;
+ if(finite(tickmax)) locate.S.tickMax=tickmax;
+ locate.time=time;
+ locate.dir=dir;
+ return locate;
+}
+
+private struct locateT {
+ real t; // tick location time
+ pair Z; // tick location in frame coordinates
+ pair pathdir; // path direction in frame coordinates
+ pair dir; // tick direction in frame coordinates
+
+ void dir(transform T, path g, ticklocate locate, real t) {
+ pathdir=unit(shiftless(T)*dir(g,t));
+ pair Dir=locate.dir(t);
+ dir=Dir == 0 ? -I*pathdir : unit(Dir);
+ }
+ // Locate the desired position of a tick along a path.
+ void calc(transform T, path g, ticklocate locate, real val) {
+ t=locate.time(val);
+ Z=T*point(g,t);
+ dir(T,g,locate,t);
+ }
+}
+
+pair ticklabelshift(pair align, pen p=currentpen)
+{
+ return 0.25*unit(align)*labelmargin(p);
+}
+
+void drawtick(frame f, transform T, path g, path g2, ticklocate locate,
+ real val, real Size, int sign, pen p, bool extend)
+{
+ locateT locate1,locate2;
+ locate1.calc(T,g,locate,val);
+ if(extend && size(g2) > 0) {
+ locate2.calc(T,g2,locate,val);
+ draw(f,locate1.Z--locate2.Z,p);
+ } else
+ if(sign == 0)
+ draw(f,locate1.Z-Size*locate1.dir--locate1.Z+Size*locate1.dir,p);
+ else
+ draw(f,locate1.Z--locate1.Z+Size*sign*locate1.dir,p);
+}
+
+real zerotickfuzz=10*epsilon;
+
+// Label a tick on a frame.
+pair labeltick(frame d, transform T, path g, ticklocate locate, real val,
+ pair side, int sign, real Size, ticklabel ticklabel,
+ Label F, real norm=0)
+{
+ locateT locate1;
+ locate1.calc(T,g,locate,val);
+ pair align=side*locate1.dir;
+ pair perp=I*locate1.pathdir;
+
+ // Adjust tick label alignment
+ pair adjust=unit(align+0.75perp*sgn(dot(align,perp)));
+ // Project align onto adjusted direction.
+ align=adjust*dot(align,adjust);
+ pair shift=dot(align,-sign*locate1.dir) <= 0 ? align*Size :
+ ticklabelshift(align,F.p);
+
+ real label;
+ if(locate.S.scale.logarithmic)
+ label=locate.S.scale.Tinv(val);
+ else {
+ label=val;
+ if(abs(label) < zerotickfuzz*norm) label=0;
+ // Fix epsilon errors at +/-1e-4
+ // default format changes to scientific notation here
+ if(abs(abs(label)-1e-4) < epsilon) label=sgn(label)*1e-4;
+ }
+
+ string s=ticklabel(label);
+ if(s != "")
+ label(d,F.T*baseline(s,baselinetemplate),locate1.Z+shift,align,F.p,
+ F.filltype);
+ return locate1.pathdir;
+}
+
+// Add axis label L to frame f.
+void labelaxis(frame f, transform T, Label L, path g,
+ ticklocate locate=null, int sign=1, bool ticklabels=false)
+{
+ Label L0=L.copy();
+ real t=L0.relative(g);
+ pair z=point(g,t);
+ pair dir=dir(g,t);
+ pair perp=I*dir;
+ if(locate != null) {
+ locateT locate1;
+ locate1.dir(T,g,locate,t);
+ L0.align(L0.align,unit(-sgn(dot(sign*locate1.dir,perp))*perp));
+ }
+ pair align=L0.align.dir;
+ if(L0.align.relative) align *= -perp;
+ pair alignperp=dot(align,perp)*perp;
+ pair offset;
+ if(ticklabels) {
+ if(piecewisestraight(g)) {
+ real angle=degrees(dir,warn=false);
+ transform S=rotate(-angle,z);
+ frame F=S*f;
+ pair Align=rotate(-angle)*alignperp;
+ offset=unit(alignperp-sign*locate.dir(t))*
+ abs((Align.y >= 0 ? max(F).y : (Align.y < 0 ? min(F).y : 0))-z.y);
+ }
+ z += offset;
+ }
+
+ L0.align(align);
+ L0.position(z);
+ frame d;
+ add(d,L0);
+ pair width=0.5*size(d);
+ int n=length(g);
+ real t=L.relative();
+ pair s=realmult(width,dir(g,t));
+ if(t <= 0) {
+ if(L.align.default) s *= -axislabelfactor;
+ d=shift(s)*d;
+ } else if(t >= n) {
+ if(L.align.default) s *= -axislabelfactor;
+ d=shift(-s)*d;
+ } else if(offset == 0 && L.align.default) {
+ pair s=realmult(width,I*dir(g,t));
+ s=axislabelfactor*s;
+ d=shift(s)*d;
+ }
+ add(f,d);
+}
+
+// Check the tick coverage of a linear axis.
+bool axiscoverage(int N, transform T, path g, ticklocate locate, real Step,
+ pair side, int sign, real Size, Label F, ticklabel ticklabel,
+ real norm, real limit)
+{
+ real coverage=0;
+ bool loop=cyclic(g);
+ real a=locate.S.Tinv(locate.a);
+ real b=locate.S.Tinv(locate.b);
+ real tickmin=finite(locate.S.tickMin) ? locate.S.Tinv(locate.S.tickMin) : a;
+ if(Size > 0) {
+ int count=0;
+ if(loop) count=N+1;
+ else {
+ for(int i=0; i <= N; ++i) {
+ real val=tickmin+i*Step;
+ if(val >= a && val <= b)
+ ++count;
+ }
+ }
+ if(count > 0) limit /= count;
+ for(int i=0; i <= N; ++i) {
+ real val=tickmin+i*Step;
+ if(loop || (val >= a && val <= b)) {
+ frame d;
+ pair dir=labeltick(d,T,g,locate,val,side,sign,Size,ticklabel,F,norm);
+ if(abs(dot(size(d),dir)) > limit) return false;
+ }
+ }
+ }
+ return true;
+}
+
+// Check the tick coverage of a logarithmic axis.
+bool logaxiscoverage(int N, transform T, path g, ticklocate locate, pair side,
+ int sign, real Size, Label F, ticklabel ticklabel,
+ real limit, int first, int last)
+{
+ bool loop=cyclic(g);
+ real coverage=0;
+ real a=locate.a;
+ real b=locate.b;
+ int count=0;
+ for(int i=first-1; i <= last+1; i += N) {
+ if(loop || i >= a && i <= b)
+ ++count;
+ }
+ if(count > 0) limit /= count;
+ for(int i=first-1; i <= last+1; i += N) {
+ if(loop || i >= a && i <= b) {
+ frame d;
+ pair dir=labeltick(d,T,g,locate,i,side,sign,Size,ticklabel,F);
+ if(abs(dot(size(d),dir)) > limit) return false;
+ }
+ }
+ return true;
+}
+
+struct tickvalues {
+ real[] major;
+ real[] minor;
+ int N; // For logarithmic axes: number of decades between tick labels.
+}
+
+// Determine a format that distinguishes adjacent pairs of ticks, optionally
+// adding trailing zeros.
+string autoformat(string format="", real norm ... real[] a)
+{
+ bool trailingzero=(format == trailingzero);
+ bool signedtrailingzero=(format == signedtrailingzero);
+ if(!trailingzero && !signedtrailingzero && format != "") return format;
+
+ real[] A=sort(a);
+ real[] a=abs(A);
+
+ bool signchange=(A.length > 1 && A[0] < 0 && A[A.length-1] >= 0);
+
+ for(int i=0; i < A.length; ++i)
+ if(a[i] < zerotickfuzz*norm) A[i]=a[i]=0;
+
+ int n=0;
+
+ bool Fixed=find(a >= 1e4-epsilon | (a > 0 & a <= 1e-4-epsilon)) < 0;
+
+ string Format=defaultformat(4,fixed=Fixed);
+
+ if(Fixed && n < 4) {
+ for(int i=0; i < A.length; ++i) {
+ real a=A[i];
+ while(format(defaultformat(n,fixed=Fixed),a) != format(Format,a))
+ ++n;
+ }
+ }
+
+ string trailing=trailingzero ? (signchange ? "# " : "#") :
+ signedtrailingzero ? "#+" : "";
+
+ string format=defaultformat(n,trailing,Fixed);
+
+ for(int i=0; i < A.length-1; ++i) {
+ real a=A[i];
+ real b=A[i+1];
+ // Check if an extra digit of precision should be added.
+ string fixedformat="%#."+string(n+1)+"f";
+ string A=format(fixedformat,a);
+ string B=format(fixedformat,b);
+ if(substr(A,length(A)-1,1) != "0" || substr(B,length(B)-1,1) != "0") {
+ a *= 0.1;
+ b *= 0.1;
+ }
+ if(a != b) {
+ while(format(format,a) == format(format,b))
+ format=defaultformat(++n,trailing,Fixed);
+ }
+ }
+
+ if(n == 0) return defaultformat;
+ return format;
+}
+
+// Automatic tick generation routine.
+tickvalues generateticks(int sign, Label F="", ticklabel ticklabel=null,
+ int N, int n=0, real Step=0, real step=0,
+ real Size=0, real size=0,
+ transform T, pair side, path g, real limit,
+ pen p, ticklocate locate, int[] divisor,
+ bool opposite)
+{
+ tickvalues tickvalues;
+ sign=opposite ? -sign : sign;
+ if(Size == 0) Size=Ticksize;
+ if(size == 0) size=ticksize;
+ F=F.copy();
+ F.p(p);
+
+ if(F.align.dir != 0) side=F.align.dir;
+ else if(side == 0) side=((sign == 1) ? left : right);
+
+ bool ticklabels=false;
+ path G=T*g;
+
+ if(!locate.S.scale.logarithmic) {
+ real a=locate.S.Tinv(locate.a);
+ real b=locate.S.Tinv(locate.b);
+ real norm=max(abs(a),abs(b));
+ string format=autoformat(F.s,norm,a,b);
+ if(F.s == "%") F.s="";
+ if(ticklabel == null) ticklabel=Format(format);
+
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ if(b-a < 100.0*epsilon*norm) b=a;
+
+ bool autotick=Step == 0 && N == 0;
+
+ real tickmin=finite(locate.S.tickMin) && (autotick || locate.S.automin) ?
+ locate.S.Tinv(locate.S.tickMin) : a;
+ real tickmax=finite(locate.S.tickMax) && (autotick || locate.S.automax) ?
+ locate.S.Tinv(locate.S.tickMax) : b;
+ if(tickmin > tickmax) {real temp=tickmin; tickmin=tickmax; tickmax=temp;}
+
+ real inStep=Step;
+
+ bool calcStep=true;
+ real len=tickmax-tickmin;
+ if(autotick) {
+ N=1;
+ if(divisor.length > 0) {
+ bool autoscale=locate.S.automin && locate.S.automax;
+ real h=0.5*(b-a);
+ if(h > 0) {
+ for(int d=divisor.length-1; d >= 0; --d) {
+ int N0=divisor[d];
+ Step=len/N0;
+ int N1=N0;
+ int m=2;
+ while(Step > h) {
+ N0=m*N1;
+ Step=len/N0;
+ m *= 2;
+ }
+ if(axiscoverage(N0,T,g,locate,Step,side,sign,Size,F,ticklabel,norm,
+ limit)) {
+ N=N0;
+ if(N0 == 1 && !autoscale && d < divisor.length-1) {
+ // Try using 2 ticks (otherwise 1);
+ int div=divisor[d+1];
+ Step=quotient(div,2)*len/div;
+ calcStep=false;
+ if(axiscoverage(2,T,g,locate,Step,side,sign,Size,F,ticklabel,
+ norm,limit)) N=2;
+ else Step=len;
+ }
+ // Found a good divisor; now compute subtick divisor
+ if(n == 0) {
+ if(step != 0) n=ceil(Step/step);
+ else {
+ n=quotient(divisor[divisor.length-1],N);
+ if(N == 1) n=(a*b >= 0) ? 2 : 1;
+ if(n == 1) n=2;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if(inStep != 0 && !locate.S.automin) {
+ tickmin=floor(tickmin/Step)*Step;
+ len=tickmax-tickmin;
+ }
+
+ if(calcStep) {
+ if(N == 1) N=2;
+ if(N == 0) N=(int) (len/Step);
+ else Step=len/N;
+ }
+
+ if(n == 0) {
+ if(step != 0) n=ceil(Step/step);
+ } else step=Step/n;
+
+ b += epsilon*norm;
+
+ if(Size > 0) {
+ for(int i=0; i <= N; ++i) {
+ real val=tickmin+i*Step;
+ if(val >= a && val <= b)
+ tickvalues.major.push(val);
+ if(size > 0 && step > 0) {
+ real iStep=i*Step;
+ real jstop=(len-iStep)/step;
+ for(int j=1; j < n && j <= jstop; ++j) {
+ real val=tickmin+iStep+j*step;
+ if(val >= a && val <= b)
+ tickvalues.minor.push(val);
+ }
+ }
+ }
+ }
+
+ } else { // Logarithmic
+ string format=F.s;
+ if(F.s == "%") F.s="";
+
+ int base=round(locate.S.scale.Tinv(1));
+
+ if(ticklabel == null)
+ ticklabel=format == "%" ? Format("") : DefaultLogFormat(base);
+ real a=locate.S.postscale.Tinv(locate.a);
+ real b=locate.S.postscale.Tinv(locate.b);
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ int first=floor(a-epsilon);
+ int last=ceil(b+epsilon);
+
+ if(N == 0) {
+ N=1;
+ while(N <= last-first) {
+ if(logaxiscoverage(N,T,g,locate,side,sign,Size,F,ticklabel,limit,
+ first,last)) break;
+ ++N;
+ }
+ }
+
+ if(N <= 2 && n == 0) n=base;
+ tickvalues.N=N;
+
+ if(N > 0) {
+ for(int i=first-1; i <= last+1; ++i) {
+ if(i >= a && i <= b)
+ tickvalues.major.push(locate.S.scale.Tinv(i));
+ if(n > 0) {
+ for(int j=2; j < n; ++j) {
+ real val=(i+1+locate.S.scale.T(j/n));
+ if(val >= a && val <= b)
+ tickvalues.minor.push(locate.S.scale.Tinv(val));
+ }
+ }
+ }
+ }
+ }
+ return tickvalues;
+}
+
+// Signature of routines that draw labelled paths with ticks and tick labels.
+typedef void ticks(frame, transform, Label, pair, path, path, pen,
+ arrowbar, margin, ticklocate, int[], bool opposite=false);
+
+// Tick construction routine for a user-specified array of tick values.
+ticks Ticks(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks=new real[], real[] ticks=new real[], int N=1,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(frame f, transform t, Label L, pair side, path g, path g2,
+ pen p, arrowbar arrow, margin margin, ticklocate locate,
+ int[] divisor, bool opposite) {
+ // Use local copy of context variables:
+ int sign=opposite ? -sign : sign;
+ pen pTick=pTick;
+ pen ptick=ptick;
+ ticklabel ticklabel=ticklabel;
+
+ real Size=Size;
+ real size=size;
+ if(Size == 0) Size=Ticksize;
+ if(size == 0) size=ticksize;
+
+ Label L=L.copy();
+ Label F=F.copy();
+ L.p(p);
+ F.p(p);
+ if(pTick == nullpen) pTick=p;
+ if(ptick == nullpen) ptick=pTick;
+
+ if(F.align.dir != 0) side=F.align.dir;
+ else if(side == 0) side=F.T*((sign == 1) ? left : right);
+
+ bool ticklabels=false;
+ path G=t*g;
+ path G2=t*g2;
+
+ scalefcn T;
+
+ real a,b;
+ if(locate.S.scale.logarithmic) {
+ a=locate.S.postscale.Tinv(locate.a);
+ b=locate.S.postscale.Tinv(locate.b);
+ T=locate.S.scale.T;
+ } else {
+ a=locate.S.Tinv(locate.a);
+ b=locate.S.Tinv(locate.b);
+ T=identity;
+ }
+
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ real norm=max(abs(a),abs(b));
+
+ string format=autoformat(F.s,norm...Ticks);
+ if(F.s == "%") F.s="";
+ if(ticklabel == null) {
+ if(locate.S.scale.logarithmic) {
+ int base=round(locate.S.scale.Tinv(1));
+ ticklabel=format == "%" ? Format("") : DefaultLogFormat(base);
+ } else ticklabel=Format(format);
+ }
+
+ begingroup(f);
+ if(opposite) draw(f,G,p);
+ else draw(f,margin(G,p).g,p,arrow);
+ for(int i=(begin ? 0 : 1); i < (end ? Ticks.length : Ticks.length-1); ++i) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(f,t,g,g2,locate,val,Size,sign,pTick,extend);
+ }
+ for(int i=0; i < ticks.length; ++i) {
+ real val=T(ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(f,t,g,g2,locate,val,size,sign,ptick,extend);
+ }
+ endgroup(f);
+
+ if(N == 0) N=1;
+ if(Size > 0 && !opposite) {
+ for(int i=(beginlabel ? 0 : 1);
+ i < (endlabel ? Ticks.length : Ticks.length-1); i += N) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b) {
+ ticklabels=true;
+ labeltick(f,t,g,locate,val,side,sign,Size,ticklabel,F,norm);
+ }
+ }
+ }
+ if(L.s != "" && !opposite)
+ labelaxis(f,t,L,G,locate,sign,ticklabels);
+ };
+}
+
+// Optional routine to allow modification of auto-generated tick values.
+typedef tickvalues tickmodifier(tickvalues);
+tickvalues None(tickvalues v) {return v;}
+
+// Tickmodifier that removes all ticks in the intervals [a[i],b[i]].
+tickmodifier OmitTickIntervals(real[] a, real[] b) {
+ return new tickvalues(tickvalues v) {
+ if(a.length != b.length) abort(differentlengths);
+ void omit(real[] A) {
+ if(A.length != 0) {
+ real norm=max(abs(A));
+ for(int i=0; i < a.length; ++i) {
+ int j;
+ while((j=find(A > a[i]-zerotickfuzz*norm
+ & A < b[i]+zerotickfuzz*norm)) >= 0) {
+ A.delete(j);
+ }
+ }
+ }
+ }
+ omit(v.major);
+ omit(v.minor);
+ return v;
+ };
+}
+
+// Tickmodifier that removes all ticks in the interval [a,b].
+tickmodifier OmitTickInterval(real a, real b) {
+ return OmitTickIntervals(new real[] {a}, new real[] {b});
+}
+
+// Tickmodifier that removes the specified ticks.
+tickmodifier OmitTick(... real[] x) {
+ return OmitTickIntervals(x,x);
+}
+
+tickmodifier NoZero=OmitTick(0);
+
+tickmodifier Break(real, real)=OmitTickInterval;
+
+// Automatic tick construction routine.
+ticks Ticks(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(frame f, transform T, Label L, pair side, path g, path g2,
+ pen p, arrowbar arrow, margin margin, ticklocate locate,
+ int[] divisor, bool opposite) {
+ real limit=Step == 0 ? axiscoverage*arclength(T*g) : 0;
+ tickvalues values=modify(generateticks(sign,F,ticklabel,N,n,Step,step,
+ Size,size,T,side,g,
+ limit,p,locate,divisor,opposite));
+
+ Ticks(sign,F,ticklabel,beginlabel,endlabel,values.major,values.minor,
+ values.N,begin,end,Size,size,extend,pTick,ptick)
+ (f,T,L,side,g,g2,p,arrow,margin,locate,divisor,opposite);
+ };
+}
+
+ticks NoTicks()
+{
+ return new void(frame f, transform T, Label L, pair, path g, path, pen p,
+ arrowbar arrow, margin margin, ticklocate,
+ int[], bool opposite) {
+ path G=T*g;
+ if(opposite) draw(f,G,p);
+ else {
+ draw(f,margin(G,p).g,p,arrow);
+ if(L.s != "") {
+ Label L=L.copy();
+ L.p(p);
+ labelaxis(f,T,L,G);
+ }
+ }
+ };
+}
+
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(-1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks RightTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks Ticks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(0,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(-1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks RightTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks Ticks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(0,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks NoTicks=NoTicks(),
+LeftTicks=LeftTicks(),
+RightTicks=RightTicks(),
+Ticks=Ticks();
+
+pair tickMin(picture pic)
+{
+ return minbound(pic.userMin(),(pic.scale.x.tickMin,pic.scale.y.tickMin));
+}
+
+pair tickMax(picture pic)
+{
+ return maxbound(pic.userMax(),(pic.scale.x.tickMax,pic.scale.y.tickMax));
+}
+
+int Min=-1;
+int Value=0;
+int Max=1;
+int Both=2;
+
+// Structure used to communicate axis and autoscale settings to tick routines.
+struct axisT {
+ int type; // -1 = min, 0 = given value, 1 = max, 2 = min/max
+ int type2; // for 3D axis
+ real value;
+ real value2;
+ pair side; // 2D tick label direction relative to path (left or right)
+ real position; // label position along axis
+ align align; // default axis label alignment and 3D tick label direction
+ int[] xdivisor;
+ int[] ydivisor;
+ int[] zdivisor;
+ bool extend; // extend axis to graph boundary?
+};
+
+axisT axis;
+typedef void axis(picture, axisT);
+
+axis Bottom(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Min;
+ axis.position=0.5;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis Top(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Max;
+ axis.position=0.5;
+ axis.side=left;
+ axis.align=N;
+ axis.extend=extend;
+ };
+}
+
+axis BottomTop(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Both;
+ axis.position=0.5;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis Left(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Min;
+ axis.position=0.5;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis Right(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Max;
+ axis.position=0.5;
+ axis.side=right;
+ axis.align=E;
+ axis.extend=extend;
+ };
+}
+
+axis LeftRight(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Both;
+ axis.position=0.5;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis XEquals(real x, bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.x.T(x);
+ axis.position=1;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis YEquals(real y, bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.y.T(y);
+ axis.position=1;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis XZero(bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.x.T(pic.scale.x.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis YZero(bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.y.T(pic.scale.y.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis Bottom=Bottom(),
+Top=Top(),
+BottomTop=BottomTop(),
+Left=Left(),
+Right=Right(),
+LeftRight=LeftRight(),
+XZero=XZero(),
+YZero=YZero();
+
+// Draw a general axis.
+void axis(picture pic=currentpicture, Label L="", path g, path g2=nullpath,
+ pen p=currentpen, ticks ticks, ticklocate locate,
+ arrowbar arrow=None, margin margin=NoMargin,
+ int[] divisor=new int[], bool above=false, bool opposite=false)
+{
+ Label L=L.copy();
+ real t=reltime(g,0.5);
+ if(L.defaultposition) L.position(t);
+ divisor=copy(divisor);
+ locate=locate.copy();
+ pic.add(new void (frame f, transform t, transform T, pair lb, pair rt) {
+ frame d;
+ ticks(d,t,L,0,g,g2,p,arrow,margin,locate,divisor,opposite);
+ (above ? add : prepend)(f,t*T*inverse(t)*d);
+ });
+
+ pic.addPath(g,p);
+
+ if(L.s != "") {
+ frame f;
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ pair pos=point(g,L.relative()*length(g));
+ pic.addBox(pos,pos,min(f),max(f));
+ }
+}
+
+real xtrans(transform t, real x)
+{
+ return (t*(x,0)).x;
+}
+
+real ytrans(transform t, real y)
+{
+ return (t*(0,y)).y;
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void xaxisAt(picture pic=currentpicture, Label L="", axis axis,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=true, bool opposite=false)
+{
+ real y=axis.value;
+ real y2;
+ Label L=L.copy();
+ int[] divisor=copy(axis.xdivisor);
+ pair side=axis.side;
+ int type=axis.type;
+
+ pic.add(new void (frame f, transform t, transform T, pair lb, pair rt) {
+ transform tinv=inverse(t);
+ pair a=xmin == -infinity ? tinv*(lb.x-min(p).x,ytrans(t,y)) : (xmin,y);
+ pair b=xmax == infinity ? tinv*(rt.x-max(p).x,ytrans(t,y)) : (xmax,y);
+ pair a2=xmin == -infinity ? tinv*(lb.x-min(p).x,ytrans(t,y2)) : (xmin,y2);
+ pair b2=xmax == infinity ? tinv*(rt.x-max(p).x,ytrans(t,y2)) : (xmax,y2);
+
+ if(xmin == -infinity || xmax == infinity) {
+ bounds mx=autoscale(a.x,b.x,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ divisor=mx.divisor;
+ }
+
+ real fuzz=epsilon*max(abs(a.x),abs(b.x));
+ a -= (fuzz,0);
+ b += (fuzz,0);
+
+ frame d;
+ ticks(d,t,L,side,a--b,finite(y2) ? a2--b2 : nullpath,p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x),divisor,opposite);
+ (above ? add : prepend)(f,t*T*tinv*d);
+ });
+
+ void bounds() {
+ if(type == Both) {
+ y2=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax().y;
+ y=opposite ? y2 :
+ (pic.scale.y.automin() ? tickMin(pic).y : pic.userMin().y);
+ }
+ else if(type == Min)
+ y=pic.scale.y.automin() ? tickMin(pic).y : pic.userMin().y;
+ else if(type == Max)
+ y=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax().y;
+
+ real Xmin=finite(xmin) ? xmin : pic.userMin().x;
+ real Xmax=finite(xmax) ? xmax : pic.userMax().x;
+
+ pair a=(Xmin,y);
+ pair b=(Xmax,y);
+ pair a2=(Xmin,y2);
+ pair b2=(Xmax,y2);
+
+ if(finite(a)) {
+ pic.addPoint(a,min(p));
+ pic.addPoint(a,max(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min(p));
+ pic.addPoint(b,max(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ frame d;
+ ticks(d,pic.scaling(warn=false),L,side,
+ (a.x,0)--(b.x,0),(a2.x,0)--(b2.x,0),p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x),divisor,opposite);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ pair pos=a+L.relative()*(b-a);
+ pic.addBox(pos,pos,(min(f).x,min(d).y),(max(f).x,max(d).y));
+ }
+ }
+
+ // Process any queued y axis bound calculation requests.
+ for(int i=0; i < pic.scale.y.bound.length; ++i)
+ pic.scale.y.bound[i]();
+
+ pic.scale.y.bound.delete();
+
+ bounds();
+
+ // Request another x bounds calculation before final picture scaling.
+ pic.scale.x.bound.push(bounds);
+}
+
+// An internal routine to draw a y axis at a particular x value.
+void yaxisAt(picture pic=currentpicture, Label L="", axis axis,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=true, bool opposite=false)
+{
+ real x=axis.value;
+ real x2;
+ Label L=L.copy();
+ int[] divisor=copy(axis.ydivisor);
+ pair side=axis.side;
+ int type=axis.type;
+
+ pic.add(new void (frame f, transform t, transform T, pair lb, pair rt) {
+ transform tinv=inverse(t);
+ pair a=ymin == -infinity ? tinv*(xtrans(t,x),lb.y-min(p).y) : (x,ymin);
+ pair b=ymax == infinity ? tinv*(xtrans(t,x),rt.y-max(p).y) : (x,ymax);
+ pair a2=ymin == -infinity ? tinv*(xtrans(t,x2),lb.y-min(p).y) : (x2,ymin);
+ pair b2=ymax == infinity ? tinv*(xtrans(t,x2),rt.y-max(p).y) : (x2,ymax);
+
+ if(ymin == -infinity || ymax == infinity) {
+ bounds my=autoscale(a.y,b.y,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ divisor=my.divisor;
+ }
+
+ real fuzz=epsilon*max(abs(a.y),abs(b.y));
+ a -= (0,fuzz);
+ b += (0,fuzz);
+
+ frame d;
+ ticks(d,t,L,side,a--b,finite(x2) ? a2--b2 : nullpath,p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y),divisor,opposite);
+ (above ? add : prepend)(f,t*T*tinv*d);
+ });
+
+ void bounds() {
+ if(type == Both) {
+ x2=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax().x;
+ x=opposite ? x2 :
+ (pic.scale.x.automin() ? tickMin(pic).x : pic.userMin().x);
+ } else if(type == Min)
+ x=pic.scale.x.automin() ? tickMin(pic).x : pic.userMin().x;
+ else if(type == Max)
+ x=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax().x;
+
+ real Ymin=finite(ymin) ? ymin : pic.userMin().y;
+ real Ymax=finite(ymax) ? ymax : pic.userMax().y;
+
+ pair a=(x,Ymin);
+ pair b=(x,Ymax);
+ pair a2=(x2,Ymin);
+ pair b2=(x2,Ymax);
+
+ if(finite(a)) {
+ pic.addPoint(a,min(p));
+ pic.addPoint(a,max(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min(p));
+ pic.addPoint(b,max(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ frame d;
+ ticks(d,pic.scaling(warn=false),L,side,
+ (0,a.y)--(0,b.y),(0,a2.y)--(0,b2.y),p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y),divisor,opposite);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ pair pos=a+L.relative()*(b-a);
+ pic.addBox(pos,pos,(min(d).x,min(f).y),(max(d).x,max(f).y));
+ }
+ }
+
+ // Process any queued x axis bound calculation requests.
+ for(int i=0; i < pic.scale.x.bound.length; ++i)
+ pic.scale.x.bound[i]();
+
+ pic.scale.x.bound.delete();
+
+ bounds();
+
+ // Request another y bounds calculation before final picture scaling.
+ pic.scale.y.bound.push(bounds);
+}
+
+// Set the x limits of a picture.
+void xlimits(picture pic=currentpicture, real min=-infinity, real max=infinity,
+ bool crop=NoCrop)
+{
+ if(min > max) return;
+
+ pic.scale.x.automin=min <= -infinity;
+ pic.scale.x.automax=max >= infinity;
+
+ bounds mx;
+ if(pic.scale.x.automin() || pic.scale.x.automax())
+ mx=autoscale(pic.userMin().x,pic.userMax().x,pic.scale.x.scale);
+
+ if(pic.scale.x.automin) {
+ if(pic.scale.x.automin()) pic.userMinx(mx.min);
+ } else pic.userMinx(min(pic.scale.x.T(min),pic.scale.x.T(max)));
+
+ if(pic.scale.x.automax) {
+ if(pic.scale.x.automax()) pic.userMaxx(mx.max);
+ } else pic.userMaxx(max(pic.scale.x.T(min),pic.scale.x.T(max)));
+
+ if(crop) {
+ pair userMin=pic.userMin();
+ pair userMax=pic.userMax();
+ pic.bounds.xclip(userMin.x,userMax.x);
+ pic.clip(userMin, userMax,
+ new void (frame f, transform t, transform T, pair, pair) {
+ frame Tinvf=T == identity() ? f : t*inverse(T)*inverse(t)*f;
+ clip(f,T*box(((t*userMin).x,(min(Tinvf)).y),
+ ((t*userMax).x,(max(Tinvf)).y)));
+ });
+ }
+}
+
+// Set the y limits of a picture.
+void ylimits(picture pic=currentpicture, real min=-infinity, real max=infinity,
+ bool crop=NoCrop)
+{
+ if(min > max) return;
+
+ pic.scale.y.automin=min <= -infinity;
+ pic.scale.y.automax=max >= infinity;
+
+ bounds my;
+ if(pic.scale.y.automin() || pic.scale.y.automax())
+ my=autoscale(pic.userMin().y,pic.userMax().y,pic.scale.y.scale);
+
+ if(pic.scale.y.automin) {
+ if(pic.scale.y.automin()) pic.userMiny(my.min);
+ } else pic.userMiny(min(pic.scale.y.T(min),pic.scale.y.T(max)));
+
+ if(pic.scale.y.automax) {
+ if(pic.scale.y.automax()) pic.userMaxy(my.max);
+ } else pic.userMaxy(max(pic.scale.y.T(min),pic.scale.y.T(max)));
+
+ if(crop) {
+ pair userMin=pic.userMin();
+ pair userMax=pic.userMax();
+ pic.bounds.yclip(userMin.y,userMax.y);
+ pic.clip(userMin, userMax,
+ new void (frame f, transform t, transform T, pair, pair) {
+ frame Tinvf=T == identity() ? f : t*inverse(T)*inverse(t)*f;
+ clip(f,T*box(((min(Tinvf)).x,(t*userMin).y),
+ ((max(Tinvf)).x,(t*userMax).y)));
+ });
+ }
+}
+
+// Crop a picture to the current user-space picture limits.
+void crop(picture pic=currentpicture)
+{
+ xlimits(pic,false);
+ ylimits(pic,false);
+ if(pic.userSetx() && pic.userSety())
+ clip(pic,box(pic.userMin(),pic.userMax()));
+}
+
+// Restrict the x and y limits to box(min,max).
+void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop)
+{
+ xlimits(pic,min.x,max.x);
+ ylimits(pic,min.y,max.y);
+ if(crop && pic.userSetx() && pic.userSety())
+ clip(pic,box(pic.userMin(),pic.userMax()));
+}
+
+// Internal routine to autoscale the user limits of a picture.
+void autoscale(picture pic=currentpicture, axis axis)
+{
+ if(!pic.scale.set) {
+ bounds mx,my;
+ pic.scale.set=true;
+
+ if(pic.userSetx()) {
+ mx=autoscale(pic.userMin().x,pic.userMax().x,pic.scale.x.scale);
+ if(pic.scale.x.scale.logarithmic &&
+ floor(pic.userMin().x) == floor(pic.userMax().x)) {
+ if(pic.scale.x.automin())
+ pic.userMinx2(floor(pic.userMin().x));
+ if(pic.scale.x.automax())
+ pic.userMaxx2(ceil(pic.userMax().x));
+ }
+ } else {mx.min=mx.max=0; pic.scale.set=false;}
+
+ if(pic.userSety()) {
+ my=autoscale(pic.userMin().y,pic.userMax().y,pic.scale.y.scale);
+ if(pic.scale.y.scale.logarithmic &&
+ floor(pic.userMin().y) == floor(pic.userMax().y)) {
+ if(pic.scale.y.automin())
+ pic.userMiny2(floor(pic.userMin().y));
+ if(pic.scale.y.automax())
+ pic.userMaxy2(ceil(pic.userMax().y));
+ }
+ } else {my.min=my.max=0; pic.scale.set=false;}
+
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ axis.xdivisor=mx.divisor;
+ axis.ydivisor=my.divisor;
+ }
+}
+
+// Draw an x axis.
+void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=false)
+{
+ if(xmin > xmax) return;
+
+ if(pic.scale.x.automin && xmin > -infinity) pic.scale.x.automin=false;
+ if(pic.scale.x.automax && xmax < infinity) pic.scale.x.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale(pic,axis);
+ }
+
+ Label L=L.copy();
+ bool newticks=false;
+
+ if(xmin != -infinity) {
+ xmin=pic.scale.x.T(xmin);
+ newticks=true;
+ }
+
+ if(xmax != infinity) {
+ xmax=pic.scale.x.T(xmax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSetx() && ticks != NoTicks) {
+ if(xmin == -infinity) xmin=pic.userMin().x;
+ if(xmax == infinity) xmax=pic.userMax().x;
+ bounds mx=autoscale(xmin,xmax,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ axis.xdivisor=mx.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(xmin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmin=pic.scale.x.automin() ? pic.scale.x.tickMin :
+ max(pic.scale.x.tickMin,pic.userMin().x);
+ else xmin=pic.userMin().x;
+ }
+
+ if(xmax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmax=pic.scale.x.automax() ? pic.scale.x.tickMax :
+ min(pic.scale.x.tickMax,pic.userMax().x);
+ else xmax=pic.userMax().x;
+ }
+
+ if(L.defaultposition) L.position(axis.position);
+ L.align(L.align,axis.align);
+
+ xaxisAt(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above);
+ if(axis.type == Both)
+ xaxisAt(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,true);
+}
+
+// Draw a y axis.
+void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=false, bool autorotate=true)
+{
+ if(ymin > ymax) return;
+
+ if(pic.scale.y.automin && ymin > -infinity) pic.scale.y.automin=false;
+ if(pic.scale.y.automax && ymax < infinity) pic.scale.y.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale(pic,axis);
+ }
+
+ Label L=L.copy();
+ bool newticks=false;
+
+ if(ymin != -infinity) {
+ ymin=pic.scale.y.T(ymin);
+ newticks=true;
+ }
+
+ if(ymax != infinity) {
+ ymax=pic.scale.y.T(ymax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSety() && ticks != NoTicks) {
+ if(ymin == -infinity) ymin=pic.userMin().y;
+ if(ymax == infinity) ymax=pic.userMax().y;
+ bounds my=autoscale(ymin,ymax,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ axis.ydivisor=my.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(ymin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymin=pic.scale.y.automin() ? pic.scale.y.tickMin :
+ max(pic.scale.y.tickMin,pic.userMin().y);
+ else ymin=pic.userMin().y;
+ }
+
+
+ if(ymax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymax=pic.scale.y.automax() ? pic.scale.y.tickMax :
+ min(pic.scale.y.tickMax,pic.userMax().y);
+ else ymax=pic.userMax().y;
+ }
+
+ if(L.defaultposition) L.position(axis.position);
+ L.align(L.align,axis.align);
+
+ if(autorotate && L.defaulttransform) {
+ frame f;
+ add(f,Label(L.s,(0,0),L.p));
+ if(length(max(f)-min(f)) > ylabelwidth*fontsize(L.p))
+ L.transform(rotate(90));
+ }
+
+ yaxisAt(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above);
+ if(axis.type == Both)
+ yaxisAt(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,true);
+}
+
+// Draw x and y axes.
+void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
+ bool extend=true,
+ pair min=(-infinity,-infinity), pair max=(infinity,infinity),
+ pen p=currentpen, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=false)
+{
+ xaxis(pic,xlabel,YZero(extend),min.x,max.x,p,arrow,margin,above);
+ yaxis(pic,ylabel,XZero(extend),min.y,max.y,p,arrow,margin,above);
+}
+
+// Draw a yaxis at x.
+void xequals(picture pic=currentpicture, Label L="", real x,
+ bool extend=false, real ymin=-infinity, real ymax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks,
+ arrowbar arrow=None, margin margin=NoMargin, bool above=true)
+{
+ yaxis(pic,L,XEquals(x,extend),ymin,ymax,p,ticks,arrow,margin,above);
+}
+
+// Draw an xaxis at y.
+void yequals(picture pic=currentpicture, Label L="", real y,
+ bool extend=false, real xmin=-infinity, real xmax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks,
+ arrowbar arrow=None, margin margin=NoMargin, bool above=true)
+{
+ xaxis(pic,L,YEquals(y,extend),xmin,xmax,p,ticks,arrow,margin,above);
+}
+
+pair Scale(picture pic=currentpicture, pair z)
+{
+ return (pic.scale.x.T(z.x),pic.scale.y.T(z.y));
+}
+
+real ScaleX(picture pic=currentpicture, real x)
+{
+ return pic.scale.x.T(x);
+}
+
+real ScaleY(picture pic=currentpicture, real y)
+{
+ return pic.scale.y.T(y);
+}
+
+// Draw a tick of length size at pair z in direction dir using pen p.
+void tick(picture pic=currentpicture, pair z, pair dir, real size=Ticksize,
+ pen p=currentpen)
+{
+ pair z=Scale(pic,z);
+ pic.add(new void (frame f, transform t) {
+ pair tz=t*z;
+ draw(f,tz--tz+unit(dir)*size,p);
+ });
+ pic.addPoint(z,p);
+ pic.addPoint(z,unit(dir)*size,p);
+}
+
+void xtick(picture pic=currentpicture, explicit pair z, pair dir=N,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,z,dir,size,p);
+}
+
+void xtick(picture pic=currentpicture, real x, pair dir=N,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,(x,pic.scale.y.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, explicit pair z, pair dir=E,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,z,dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, real y, pair dir=E,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,(pic.scale.x.scale.logarithmic ? 1 : 0,y),dir,size,p);
+}
+
+void tick(picture pic=currentpicture, Label L, real value, explicit pair z,
+ pair dir, string format="", real size=Ticksize, pen p=currentpen)
+{
+ Label L=L.copy();
+ L.position(Scale(pic,z));
+ L.align(L.align,-dir);
+ if(shift(L.T)*0 == 0)
+ L.T=shift(dot(dir,L.align.dir) > 0 ? dir*size :
+ ticklabelshift(L.align.dir,p))*L.T;
+ L.p(p);
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,value);
+ L.s=baseline(L.s,baselinetemplate);
+ add(pic,L);
+ tick(pic,z,dir,size,p);
+}
+
+void xtick(picture pic=currentpicture, Label L, explicit pair z, pair dir=N,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,z.x,z,dir,format,size,p);
+}
+
+void xtick(picture pic=currentpicture, Label L, real x, pair dir=N,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, Label L, explicit pair z, pair dir=E,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,z.y,z,dir,format,size,p);
+}
+
+void ytick(picture pic=currentpicture, Label L, real y, pair dir=E,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y),dir,format,size,p);
+}
+
+private void label(picture pic, Label L, pair z, real x, align align,
+ string format, pen p)
+{
+ Label L=L.copy();
+ L.position(z);
+ L.align(align);
+ L.p(p);
+ if(shift(L.T)*0 == 0)
+ L.T=shift(ticklabelshift(L.align.dir,L.p))*L.T;
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,x);
+ L.s=baseline(L.s,baselinetemplate);
+ add(pic,L);
+}
+
+// Put a label on the x axis.
+void labelx(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=S, string format="", pen p=currentpen)
+{
+ label(pic,L,Scale(pic,z),z.x,align,format,p);
+}
+
+void labelx(picture pic=currentpicture, Label L="", real x,
+ align align=S, string format="", pen p=currentpen)
+{
+ labelx(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0),align,format,p);
+}
+
+void labelx(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen)
+{
+ labelx(pic,L,L.position.position,format,p);
+}
+
+// Put a label on the y axis.
+void labely(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=W, string format="", pen p=currentpen)
+{
+ label(pic,L,Scale(pic,z),z.y,align,format,p);
+}
+
+void labely(picture pic=currentpicture, Label L="", real y,
+ align align=W, string format="", pen p=currentpen)
+{
+ labely(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y),align,format,p);
+}
+
+void labely(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen)
+{
+ labely(pic,L,L.position.position,format,p);
+}
+
+private string noprimary="Primary axis must be drawn before secondary axis";
+
+// Construct a secondary X axis
+picture secondaryX(picture primary=currentpicture, void f(picture))
+{
+ if(!primary.scale.set) abort(noprimary);
+ picture pic;
+ size(pic,primary);
+ if(primary.userMax().x == primary.userMin().x) return pic;
+ f(pic);
+ if(!pic.userSetx()) return pic;
+ bounds a=autoscale(pic.userMin().x,pic.userMax().x,pic.scale.x.scale);
+ real bmin=pic.scale.x.automin() ? a.min : pic.userMin().x;
+ real bmax=pic.scale.x.automax() ? a.max : pic.userMax().x;
+
+ real denom=bmax-bmin;
+ if(denom != 0) {
+ pic.erase();
+ real m=(primary.userMax().x-primary.userMin().x)/denom;
+ pic.scale.x.postscale=Linear(m,bmin-primary.userMin().x/m);
+ pic.scale.set=true;
+ pic.scale.x.tickMin=pic.scale.x.postscale.T(a.min);
+ pic.scale.x.tickMax=pic.scale.x.postscale.T(a.max);
+ pic.scale.y.tickMin=primary.userMin().y;
+ pic.scale.y.tickMax=primary.userMax().y;
+ axis.xdivisor=a.divisor;
+ f(pic);
+ }
+ pic.userCopy(primary);
+ return pic;
+}
+
+// Construct a secondary Y axis
+picture secondaryY(picture primary=currentpicture, void f(picture))
+{
+ if(!primary.scale.set) abort(noprimary);
+ picture pic;
+ size(pic,primary);
+ if(primary.userMax().y == primary.userMin().y) return pic;
+ f(pic);
+ if(!pic.userSety()) return pic;
+ bounds a=autoscale(pic.userMin().y,pic.userMax().y,pic.scale.y.scale);
+ real bmin=pic.scale.y.automin() ? a.min : pic.userMin().y;
+ real bmax=pic.scale.y.automax() ? a.max : pic.userMax().y;
+
+ real denom=bmax-bmin;
+ if(denom != 0) {
+ pic.erase();
+ real m=(primary.userMax().y-primary.userMin().y)/denom;
+ pic.scale.y.postscale=Linear(m,bmin-primary.userMin().y/m);
+ pic.scale.set=true;
+ pic.scale.x.tickMin=primary.userMin().x;
+ pic.scale.x.tickMax=primary.userMax().x;
+ pic.scale.y.tickMin=pic.scale.y.postscale.T(a.min);
+ pic.scale.y.tickMax=pic.scale.y.postscale.T(a.max);
+ axis.ydivisor=a.divisor;
+ f(pic);
+ }
+ pic.userCopy(primary);
+ return pic;
+}
+
+typedef guide graph(pair f(real), real, real, int);
+typedef guide[] multigraph(pair f(real), real, real, int);
+
+graph graph(interpolate join)
+{
+ return new guide(pair f(real), real a, real b, int n) {
+ real width=b-a;
+ return n == 0 ? join(f(a)) :
+ join(...sequence(new guide(int i) {return f(a+(i/n)*width);},n+1));
+ };
+}
+
+multigraph graph(interpolate join, bool3 cond(real))
+{
+ return new guide[](pair f(real), real a, real b, int n) {
+ real width=b-a;
+ if(n == 0) return new guide[] {join(cond(a) ? f(a) : nullpath)};
+ guide[] G;
+ guide[] g;
+ for(int i=0; i < n+1; ++i) {
+ real t=a+(i/n)*width;
+ bool3 b=cond(t);
+ if(b)
+ g.push(f(t));
+ else {
+ if(g.length > 0) {
+ G.push(join(...g));
+ g=new guide[] {};
+ }
+ if(b == default)
+ g.push(f(t));
+ }
+ }
+ if(g.length > 0)
+ G.push(join(...g));
+ return G;
+ };
+}
+
+guide Straight(... guide[])=operator --;
+guide Spline(... guide[])=operator ..;
+
+interpolate Hermite(splinetype splinetype)
+{
+ return new guide(... guide[] a) {
+ int n=a.length;
+ if(n == 0) return nullpath;
+ real[] x,y;
+ guide G;
+ for(int i=0; i < n; ++i) {
+ guide g=a[i];
+ int m=size(g);
+ if(m == 0) continue;
+ pair z=point(g,0);
+ x.push(z.x);
+ y.push(z.y);
+ if(m > 1) {
+ G=G..hermite(x,y,splinetype) & g;
+ pair z=point(g,m);
+ x=new real[] {z.x};
+ y=new real[] {z.y};
+ }
+ }
+ return G & hermite(x,y,splinetype);
+ };
+}
+
+interpolate Hermite=Hermite(Spline);
+
+guide graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity, interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join)(new pair(real x) {
+ return (x,pic.scale.y.T(f(pic.scale.x.Tinv(x))));},
+ pic.scale.x.T(a),pic.scale.x.T(b),n);
+ else
+ return graph(join)(new pair(real x) {
+ return Scale(pic,(T(x),f(T(x))));},
+ a,b,n);
+}
+
+guide[] graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ bool3 cond(real), interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join,cond)(new pair(real x) {
+ return (x,pic.scale.y.T(f(pic.scale.x.Tinv(x))));},
+ pic.scale.x.T(a),pic.scale.x.T(b),n);
+ else
+ return graph(join,cond)(new pair(real x) {
+ return Scale(pic,(T(x),f(T(x))));},
+ a,b,n);
+}
+
+guide graph(picture pic=currentpicture, real x(real), real y(real), real a,
+ real b, int n=ngraph, real T(real)=identity,
+ interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join)(new pair(real t) {return Scale(pic,(x(t),y(t)));},a,b,n);
+ else
+ return graph(join)(new pair(real t) {
+ return Scale(pic,(x(T(t)),y(T(t))));
+ },a,b,n);
+}
+
+guide[] graph(picture pic=currentpicture, real x(real), real y(real), real a,
+ real b, int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join,cond)(new pair(real t) {return Scale(pic,(x(t),y(t)));},
+ a,b,n);
+ else
+ return graph(join,cond)(new pair(real t) {
+ return Scale(pic,(x(T(t)),y(T(t))));},
+ a,b,n);
+}
+
+guide graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join)(new pair(real t) {return Scale(pic,z(t));},a,b,n);
+ else
+ return graph(join)(new pair(real t) {
+ return Scale(pic,z(T(t)));
+ },a,b,n);
+}
+
+guide[] graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join,cond)(new pair(real t) {return Scale(pic,z(t));},a,b,n);
+ else
+ return graph(join,cond)(new pair(real t) {
+ return Scale(pic,z(T(t)));
+ },a,b,n);
+}
+
+string conditionlength="condition array has different length than data";
+
+void checkconditionlength(int x, int y)
+{
+ checklengths(x,y,conditionlength);
+}
+
+guide graph(picture pic=currentpicture, pair[] z, interpolate join=operator --)
+{
+ int i=0;
+ return graph(join)(new pair(real) {
+ pair w=Scale(pic,z[i]);
+ ++i;
+ return w;
+ },0,0,z.length-1);
+}
+
+guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond,
+ interpolate join=operator --)
+{
+ int n=z.length;
+ int i=0;
+ pair w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool3 b=cond[i];
+ if(b != false) w=Scale(pic,z[i]);
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new pair(real) {return w;},0,0,n-1);
+}
+
+guide graph(picture pic=currentpicture, real[] x, real[] y,
+ interpolate join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ int i=0;
+ return graph(join)(new pair(real) {
+ pair w=Scale(pic,(x[i],y[i]));
+ ++i;
+ return w;
+ },0,0,n-1);
+}
+
+guide[] graph(picture pic=currentpicture, real[] x, real[] y, bool3[] cond,
+ interpolate join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ int i=0;
+ pair w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool3 b=cond[i];
+ if(b != false) w=Scale(pic,(x[i],y[i]));
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new pair(real) {return w;},0,0,n-1);
+}
+
+// Connect points in z into segments corresponding to consecutive true elements
+// of b using interpolation operator join.
+path[] segment(pair[] z, bool[] cond, interpolate join=operator --)
+{
+ checkconditionlength(cond.length,z.length);
+ int[][] segment=segment(cond);
+ return sequence(new path(int i) {return join(...z[segment[i]]);},
+ segment.length);
+}
+
+pair polar(real r, real theta)
+{
+ return r*expi(theta);
+}
+
+guide polargraph(picture pic=currentpicture, real r(real), real a, real b,
+ int n=ngraph, interpolate join=operator --)
+{
+ return graph(join)(new pair(real theta) {
+ return Scale(pic,polar(r(theta),theta));
+ },a,b,n);
+}
+
+guide polargraph(picture pic=currentpicture, real[] r, real[] theta,
+ interpolate join=operator--)
+{
+ int n=r.length;
+ checklengths(n,theta.length);
+ int i=0;
+ return graph(join)(new pair(real) {
+ pair w=Scale(pic,polar(r[i],theta[i]));
+ ++i;
+ return w;
+ },0,0,n-1);
+}
+
+void errorbar(picture pic, pair z, pair dp, pair dm, pen p=currentpen,
+ real size=0)
+{
+ real dmx=-abs(dm.x);
+ real dmy=-abs(dm.y);
+ real dpx=abs(dp.x);
+ real dpy=abs(dp.y);
+ if(dmx != dpx) draw(pic,Scale(pic,z+(dmx,0))--Scale(pic,z+(dpx,0)),p,
+ Bars(size));
+ if(dmy != dpy) draw(pic,Scale(pic,z+(0,dmy))--Scale(pic,z+(0,dpy)),p,
+ Bars(size));
+}
+
+void errorbars(picture pic=currentpicture, pair[] z, pair[] dp, pair[] dm={},
+ bool[] cond={}, pen p=currentpen, real size=0)
+{
+ if(dm.length == 0) dm=dp;
+ int n=z.length;
+ checklengths(n,dm.length);
+ checklengths(n,dp.length);
+ bool all=cond.length == 0;
+ if(!all)
+ checkconditionlength(cond.length,n);
+ for(int i=0; i < n; ++i) {
+ if(all || cond[i])
+ errorbar(pic,z[i],dp[i],dm[i],p,size);
+ }
+}
+
+void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpx, real[] dpy, real[] dmx={}, real[] dmy={},
+ bool[] cond={}, pen p=currentpen, real size=0)
+{
+ if(dmx.length == 0) dmx=dpx;
+ if(dmy.length == 0) dmy=dpy;
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,dpx.length);
+ checklengths(n,dpy.length);
+ checklengths(n,dmx.length);
+ checklengths(n,dmy.length);
+ bool all=cond.length == 0;
+ if(!all)
+ checkconditionlength(cond.length,n);
+ for(int i=0; i < n; ++i) {
+ if(all || cond[i])
+ errorbar(pic,(x[i],y[i]),(dpx[i],dpy[i]),(dmx[i],dmy[i]),p,size);
+ }
+}
+
+void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpy, bool[] cond={}, pen p=currentpen, real size=0)
+{
+ errorbars(pic,x,y,0*x,dpy,cond,p,size);
+}
+
+// Return a vector field on path g, specifying the vector as a function of the
+// relative position along path g in [0,1].
+picture vectorfield(path vector(real), path g, int n, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow,
+ margin margin=PenMargin)
+{
+ picture pic;
+ for(int i=0; i < n; ++i) {
+ real x=(n == 1) ? 0.5 : i/(n-1);
+ if(truesize)
+ draw(relpoint(g,x),pic,vector(x),p,arrow);
+ else
+ draw(pic,shift(relpoint(g,x))*vector(x),p,arrow,margin);
+ }
+ return pic;
+}
+
+real maxlength(pair a, pair b, int nx, int ny)
+{
+ return min((b.x-a.x)/nx,(b.y-a.y)/ny);
+}
+
+// return a vector field over box(a,b).
+picture vectorfield(path vector(pair), pair a, pair b,
+ int nx=nmesh, int ny=nx, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(a,b,nx,ny),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar arrow=Arrow, margin margin=PenMargin)
+{
+ picture pic;
+ real dx=1/nx;
+ real dy=1/ny;
+ bool all=cond == null;
+ real scale;
+
+ if(maxlength > 0) {
+ real size(pair z) {
+ path g=vector(z);
+ return abs(point(g,size(g)-1)-point(g,0));
+ }
+ real max=size(a);
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i*dx);
+ for(int j=0; j <= ny; ++j)
+ max=max(max,size((x,interp(a.y,b.y,j*dy))));
+ }
+ scale=max > 0 ? maxlength/max : 1;
+ } else scale=1;
+
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i*dx);
+ for(int j=0; j <= ny; ++j) {
+ real y=interp(a.y,b.y,j*dy);
+ pair z=(x,y);
+ if(all || cond(z)) {
+ path g=scale(scale)*vector(z);
+ if(truesize)
+ draw(z,pic,g,p,arrow);
+ else
+ draw(pic,shift(z)*g,p,arrow,margin);
+ }
+ }
+ }
+ return pic;
+}
+
+// True arc
+path Arc(pair c, real r, real angle1, real angle2, bool direction,
+ int n=nCircle)
+{
+ angle1=radians(angle1);
+ angle2=radians(angle2);
+ if(direction) {
+ if(angle1 >= angle2) angle1 -= 2pi;
+ } else if(angle2 >= angle1) angle2 -= 2pi;
+ return shift(c)*polargraph(new real(real t){return r;},angle1,angle2,n,
+ operator ..);
+}
+
+path Arc(pair c, real r, real angle1, real angle2, int n=nCircle)
+{
+ return Arc(c,r,angle1,angle2,angle2 >= angle1 ? CCW : CW,n);
+}
+
+path Arc(pair c, explicit pair z1, explicit pair z2, bool direction=CCW,
+ int n=nCircle)
+{
+ return Arc(c,abs(z1-c),degrees(z1-c),degrees(z2-c),direction,n);
+}
+
+// True circle
+path Circle(pair c, real r, int n=nCircle)
+{
+ return Arc(c,r,0,360,n)&cycle;
+}
diff --git a/graphics/asymptote/base/graph3.asy b/graphics/asymptote/base/graph3.asy
new file mode 100644
index 0000000000..ed09830974
--- /dev/null
+++ b/graphics/asymptote/base/graph3.asy
@@ -0,0 +1,2044 @@
+// Three-dimensional graphing routines
+
+private import math;
+import graph;
+import three;
+
+typedef triple direction3(real);
+direction3 Dir(triple dir) {return new triple(real) {return dir;};}
+
+ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, direction3 dir)
+{
+ if((valuetime) time == null) time=linear(S.T(),a,b);
+ ticklocate locate;
+ locate.a=a;
+ locate.b=b;
+ locate.S=S.copy();
+ if(finite(tickmin)) locate.S.tickMin=tickmin;
+ if(finite(tickmax)) locate.S.tickMax=tickmax;
+ locate.time=time;
+ locate.dir=zero;
+ locate.dir3=dir;
+ return locate;
+}
+
+private struct locateT {
+ real t; // tick location time
+ triple V; // tick location in frame coordinates
+ triple pathdir; // path direction in frame coordinates
+ triple dir; // tick direction in frame coordinates
+
+ void dir(transform3 T, path3 g, ticklocate locate, real t) {
+ pathdir=unit(shiftless(T)*dir(g,t));
+ triple Dir=locate.dir3(t);
+ dir=unit(Dir);
+ }
+ // Locate the desired position of a tick along a path.
+ void calc(transform3 T, path3 g, ticklocate locate, real val) {
+ t=locate.time(val);
+ V=T*point(g,t);
+ dir(T,g,locate,t);
+ }
+}
+
+void drawtick(picture pic, transform3 T, path3 g, path3 g2,
+ ticklocate locate, real val, real Size, int sign, pen p,
+ bool extend)
+{
+ locateT locate1,locate2;
+ locate1.calc(T,g,locate,val);
+ path3 G;
+ if(extend && size(g2) > 0) {
+ locate2.calc(T,g2,locate,val);
+ G=locate1.V--locate2.V;
+ } else
+ G=(sign == 0) ?
+ locate1.V-Size*locate1.dir--locate1.V+Size*locate1.dir :
+ locate1.V--locate1.V+Size*sign*locate1.dir;
+ draw(pic,G,p,name="tick");
+}
+
+triple ticklabelshift(triple align, pen p=currentpen)
+{
+ return 0.25*unit(align)*labelmargin(p);
+}
+
+// Signature of routines that draw labelled paths with ticks and tick labels.
+typedef void ticks3(picture, transform3, Label, path3, path3, pen,
+ arrowbar3, margin3, ticklocate, int[], bool opposite=false,
+ bool primary=true);
+
+// Label a tick on a frame.
+void labeltick(picture pic, transform3 T, path3 g,
+ ticklocate locate, real val, int sign, real Size,
+ ticklabel ticklabel, Label F, real norm=0)
+{
+ locateT locate1;
+ locate1.calc(T,g,locate,val);
+ triple align=F.align.dir3;
+ if(align == O) align=sign*locate1.dir;
+
+ triple shift=align*labelmargin(F.p);
+ if(dot(align,sign*locate1.dir) >= 0)
+ shift=sign*(Size)*locate1.dir;
+
+ real label;
+ if(locate.S.scale.logarithmic)
+ label=locate.S.scale.Tinv(val);
+ else {
+ label=val;
+ if(abs(label) < zerotickfuzz*norm) label=0;
+ // Fix epsilon errors at +/-1e-4
+ // default format changes to scientific notation here
+ if(abs(abs(label)-1e-4) < epsilon) label=sgn(label)*1e-4;
+ }
+
+ string s=ticklabel(label);
+ triple v=locate1.V+shift;
+ if(s != "")
+ label(pic,F.defaulttransform3 ? baseline(s,baselinetemplate) : F.T3*s,v,
+ align,F.p);
+}
+
+// Add axis label L to frame f.
+void labelaxis(picture pic, transform3 T, Label L, path3 g,
+ ticklocate locate=null, int sign=1, bool ticklabels=false)
+{
+ triple m=pic.min(identity4);
+ triple M=pic.max(identity4);
+ triple align=L.align.dir3;
+ Label L=L.copy();
+
+ pic.add(new void(frame f, transform3 T, picture pic2, projection P) {
+ path3 g=T*g;
+ real t=relative(L,g);
+ triple v=point(g,t);
+ picture F;
+ if(L.align.dir3 == O)
+ align=unit(invert(L.align.dir,v,P))*abs(L.align.dir);
+
+ if(ticklabels && locate != null && piecewisestraight(g)) {
+ locateT locate1;
+ locate1.dir(T,g,locate,t);
+ triple pathdir=locate1.pathdir;
+
+ triple perp=cross(pathdir,P.normal);
+ if(align == O)
+ align=unit(sgn(dot(sign*locate1.dir,perp))*perp);
+ path[] g=project(box(T*m,T*M),P);
+ pair z=project(v,P);
+ pair Ppathdir=project(v+pathdir,P)-z;
+ pair Perp=unit(I*Ppathdir);
+ real angle=degrees(Ppathdir,warn=false);
+ transform S=rotate(-angle,z);
+ path[] G=S*g;
+ pair Palign=project(v+align,P)-z;
+ pair Align=rotate(-angle)*dot(Palign,Perp)*Perp;
+ pair offset=unit(Palign)*
+ abs((Align.y >= 0 ? max(G).y : (Align.y < 0 ? min(G).y : 0))-z.y);
+ triple normal=cross(pathdir,align);
+ if(normal != O) v=invert(z+offset,normal,v,P);
+ }
+
+ label(F,L,v);
+ add(f,F.fit3(identity4,pic2,P));
+ },exact=false);
+
+ path3[] G=path3(texpath(L,bbox=true));
+ if(G.length > 0) {
+ G=L.align.is3D ? align(G,O,align,L.p) : L.T3*G;
+ triple v=point(g,relative(L,g));
+ pic.addBox(v,v,min(G),max(G));
+ }
+}
+
+// Tick construction routine for a user-specified array of tick values.
+ticks3 Ticks3(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks=new real[], real[] ticks=new real[], int N=1,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(picture pic, transform3 t, Label L, path3 g, path3 g2, pen p,
+ arrowbar3 arrow, margin3 margin, ticklocate locate,
+ int[] divisor, bool opposite, bool primary) {
+ // Use local copy of context variables:
+ int Sign=opposite ? -1 : 1;
+ int sign=Sign*sign;
+ pen pTick=pTick;
+ pen ptick=ptick;
+ ticklabel ticklabel=ticklabel;
+
+ real Size=Size;
+ real size=size;
+ if(Size == 0) Size=Ticksize;
+ if(size == 0) size=ticksize;
+
+ Label L=L.copy();
+ Label F=F.copy();
+ L.p(p);
+ F.p(p);
+ if(pTick == nullpen) pTick=p;
+ if(ptick == nullpen) ptick=pTick;
+
+ bool ticklabels=false;
+ path3 G=t*g;
+ path3 G2=t*g2;
+
+ scalefcn T;
+
+ real a,b;
+ if(locate.S.scale.logarithmic) {
+ a=locate.S.postscale.Tinv(locate.a);
+ b=locate.S.postscale.Tinv(locate.b);
+ T=locate.S.scale.T;
+ } else {
+ a=locate.S.Tinv(locate.a);
+ b=locate.S.Tinv(locate.b);
+ T=identity;
+ }
+
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ real norm=max(abs(a),abs(b));
+
+ string format=autoformat(F.s,norm...Ticks);
+ if(F.s == "%") F.s="";
+ if(ticklabel == null) {
+ if(locate.S.scale.logarithmic) {
+ int base=round(locate.S.scale.Tinv(1));
+ ticklabel=format == "%" ? Format("") : DefaultLogFormat(base);
+ } else ticklabel=Format(format);
+ }
+
+ bool labelaxis=L.s != "" && primary;
+
+ begingroup3(pic,"axis");
+
+ if(primary) draw(pic,margin(G,p).g,p,arrow);
+ else draw(pic,G,p);
+
+ for(int i=(begin ? 0 : 1); i < (end ? Ticks.length : Ticks.length-1); ++i) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(pic,t,g,g2,locate,val,Size,sign,pTick,extend);
+ }
+ for(int i=0; i < ticks.length; ++i) {
+ real val=T(ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(pic,t,g,g2,locate,val,size,sign,ptick,extend);
+ }
+
+ if(N == 0) N=1;
+ if(Size > 0 && primary) {
+ for(int i=(beginlabel ? 0 : 1);
+ i < (endlabel ? Ticks.length : Ticks.length-1); i += N) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b) {
+ ticklabels=true;
+ labeltick(pic,t,g,locate,val,Sign,Size,ticklabel,F,norm);
+ }
+ }
+ }
+ if(labelaxis)
+ labelaxis(pic,t,L,G,locate,Sign,ticklabels);
+
+ endgroup3(pic);
+ };
+}
+
+// Automatic tick construction routine.
+ticks3 Ticks3(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(picture pic, transform3 T, Label L,
+ path3 g, path3 g2, pen p,
+ arrowbar3 arrow, margin3 margin=NoMargin3, ticklocate locate,
+ int[] divisor, bool opposite, bool primary) {
+ path3 G=T*g;
+ real limit=Step == 0 ? axiscoverage*arclength(G) : 0;
+ tickvalues values=modify(generateticks(sign,F,ticklabel,N,n,Step,step,
+ Size,size,identity(),1,
+ project(G,currentprojection),
+ limit,p,locate,divisor,
+ opposite));
+ Ticks3(sign,F,ticklabel,beginlabel,endlabel,values.major,values.minor,
+ values.N,begin,end,Size,size,extend,pTick,ptick)
+ (pic,T,L,g,g2,p,arrow,margin,locate,divisor,opposite,primary);
+ };
+}
+
+ticks3 NoTicks3()
+{
+ return new void(picture pic, transform3 T, Label L, path3 g,
+ path3, pen p, arrowbar3 arrow, margin3 margin,
+ ticklocate, int[], bool opposite, bool primary) {
+ path3 G=T*g;
+ if(primary) draw(pic,margin(G,p).g,p,arrow,margin);
+ else draw(pic,G,p);
+ if(L.s != "" && primary) {
+ Label L=L.copy();
+ L.p(p);
+ labelaxis(pic,T,L,G,opposite ? -1 : 1);
+ }
+ };
+}
+
+ticks3 InTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(-1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks3 OutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks3 InOutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(0,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks3 InTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(-1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks3 OutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks3 InOutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(0,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks3 NoTicks3=NoTicks3(),
+InTicks=InTicks(),
+OutTicks=OutTicks(),
+InOutTicks=InOutTicks();
+
+triple tickMin3(picture pic)
+{
+ return minbound(pic.userMin(),(pic.scale.x.tickMin,pic.scale.y.tickMin,
+ pic.scale.z.tickMin));
+}
+
+triple tickMax3(picture pic)
+{
+ return maxbound(pic.userMax(),(pic.scale.x.tickMax,pic.scale.y.tickMax,
+ pic.scale.z.tickMax));
+}
+
+axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=type;
+ axis.type2=type2;
+ axis.position=0.5;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis YZEquals(real y, real z, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.y.T(y);
+ axis.value2=pic.scale.z.T(z);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XZEquals(real x, real z, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(x);
+ axis.value2=pic.scale.z.T(z);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XYEquals(real x, real y, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(x);
+ axis.value2=pic.scale.y.T(y);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis YZZero(triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.y.T(pic.scale.y.scale.logarithmic ? 1 : 0);
+ axis.value2=pic.scale.z.T(pic.scale.z.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XZZero(triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(pic.scale.x.scale.logarithmic ? 1 : 0);
+ axis.value2=pic.scale.z.T(pic.scale.z.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XYZero(triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(pic.scale.x.scale.logarithmic ? 1 : 0);
+ axis.value2=pic.scale.y.T(pic.scale.y.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis
+Bounds=Bounds(),
+YZZero=YZZero(),
+XZZero=XZZero(),
+XYZero=XYZero();
+
+// Draw a general three-dimensional axis.
+void axis(picture pic=currentpicture, Label L="", path3 g, path3 g2=nullpath3,
+ pen p=currentpen, ticks3 ticks, ticklocate locate,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3,
+ int[] divisor=new int[], bool above=false, bool opposite=false)
+{
+ Label L=L.copy();
+ real t=reltime(g,0.5);
+ if(L.defaultposition) L.position(t);
+ divisor=copy(divisor);
+ locate=locate.copy();
+
+ pic.add(new void (picture f, transform3 t, transform3 T, triple, triple) {
+ picture d;
+ ticks(d,t,L,g,g2,p,arrow,margin,locate,divisor,opposite,true);
+ add(f,t*T*inverse(t)*d);
+ },above=above);
+
+ addPath(pic,g,p);
+
+ if(L.s != "") {
+ frame f;
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ triple pos=point(g,L.relative()*length(g));
+ pic.addBox(pos,pos,min3(f),max3(f));
+ }
+}
+
+real xtrans(transform3 t, real x)
+{
+ return (t*(x,0,0)).x;
+}
+
+real ytrans(transform3 t, real y)
+{
+ return (t*(0,y,0)).y;
+}
+
+real ztrans(transform3 t, real z)
+{
+ return (t*(0,0,z)).z;
+}
+
+private triple defaultdir(triple X, triple Y, triple Z, bool opposite=false,
+ projection P) {
+ triple u=cross(P.normal,Z);
+ return abs(dot(u,X)) > abs(dot(u,Y)) ? -X : (opposite ? Y : -Y);
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void xaxis3At(picture pic=currentpicture, Label L="", axis axis,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=true,
+ bool opposite=false, bool opposite2=false, bool primary=true)
+{
+ int type=axis.type;
+ int type2=axis.type2;
+ triple dir=axis.align.dir3 == O ?
+ defaultdir(Y,Z,X,opposite^opposite2,currentprojection) : axis.align.dir3;
+ Label L=L.copy();
+ if(L.align.dir3 == O && L.align.dir == 0) L.align(opposite ? -dir : dir);
+
+ real y=axis.value;
+ real z=axis.value2;
+ real y2,z2;
+ int[] divisor=copy(axis.xdivisor);
+
+ pic.add(new void(picture f, transform3 t, transform3 T, triple lb,
+ triple rt) {
+ transform3 tinv=inverse(t);
+ triple a=xmin == -infinity ? tinv*(lb.x-min3(p).x,ytrans(t,y),
+ ztrans(t,z)) : (xmin,y,z);
+ triple b=xmax == infinity ? tinv*(rt.x-max3(p).x,ytrans(t,y),
+ ztrans(t,z)) : (xmax,y,z);
+ real y0;
+ real z0;
+ if(abs(dir.y) < abs(dir.z)) {
+ y0=y;
+ z0=z2;
+ } else {
+ y0=y2;
+ z0=z;
+ }
+
+ triple a2=xmin == -infinity ? tinv*(lb.x-min3(p).x,ytrans(t,y0),
+ ztrans(t,z0)) : (xmin,y0,z0);
+ triple b2=xmax == infinity ? tinv*(rt.x-max3(p).x,ytrans(t,y0),
+ ztrans(t,z0)) : (xmax,y0,z0);
+
+ if(xmin == -infinity || xmax == infinity) {
+ bounds mx=autoscale(a.x,b.x,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ divisor=mx.divisor;
+ }
+
+ triple fuzz=X*epsilon*max(abs(a.x),abs(b.x));
+ a -= fuzz;
+ b += fuzz;
+
+ picture d;
+ ticks(d,t,L,a--b,finite(y0) && finite(z0) ? a2--b2 : nullpath3,
+ p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x,Dir(dir)),divisor,
+ opposite,primary);
+ add(f,t*T*tinv*d);
+ },above=above);
+
+ void bounds() {
+ if(type == Min)
+ y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y;
+ else if(type == Max)
+ y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y;
+ else if(type == Both) {
+ y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y;
+ y=opposite ? y2 :
+ (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y);
+ }
+
+ if(type2 == Min)
+ z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z;
+ else if(type2 == Max)
+ z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z;
+ else if(type2 == Both) {
+ z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z;
+ z=opposite2 ? z2 :
+ (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z);
+ }
+
+ real Xmin=finite(xmin) ? xmin : pic.userMin().x;
+ real Xmax=finite(xmax) ? xmax : pic.userMax().x;
+
+ triple a=(Xmin,y,z);
+ triple b=(Xmax,y,z);
+ triple a2=(Xmin,y2,z2);
+ triple b2=(Xmax,y2,z2);
+
+ if(finite(a)) {
+ pic.addPoint(a,min3(p));
+ pic.addPoint(a,max3(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min3(p));
+ pic.addPoint(b,max3(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ picture d;
+ ticks(d,pic.scaling3(warn=false),L,
+ (a.x,0,0)--(b.x,0,0),(a2.x,0,0)--(b2.x,0,0),p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x,Dir(dir)),divisor,
+ opposite,primary);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ triple pos=a+L.relative()*(b-a);
+ triple m=min3(d);
+ triple M=max3(d);
+ pic.addBox(pos,pos,(min3(f).x,m.y,m.z),(max3(f).x,m.y,m.z));
+ }
+ }
+
+ // Process any queued y and z axes bound calculation requests.
+ for(int i=0; i < pic.scale.y.bound.length; ++i)
+ pic.scale.y.bound[i]();
+ for(int i=0; i < pic.scale.z.bound.length; ++i)
+ pic.scale.z.bound[i]();
+
+ pic.scale.y.bound.delete();
+ pic.scale.z.bound.delete();
+
+ bounds();
+
+ // Request another x bounds calculation before final picture scaling.
+ pic.scale.x.bound.push(bounds);
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void yaxis3At(picture pic=currentpicture, Label L="", axis axis,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=true,
+ bool opposite=false, bool opposite2=false, bool primary=true)
+{
+ int type=axis.type;
+ int type2=axis.type2;
+ triple dir=axis.align.dir3 == O ?
+ defaultdir(X,Z,Y,opposite^opposite2,currentprojection) : axis.align.dir3;
+ Label L=L.copy();
+ if(L.align.dir3 == O && L.align.dir == 0) L.align(opposite ? -dir : dir);
+
+ real x=axis.value;
+ real z=axis.value2;
+ real x2,z2;
+ int[] divisor=copy(axis.ydivisor);
+
+ pic.add(new void(picture f, transform3 t, transform3 T, triple lb,
+ triple rt) {
+ transform3 tinv=inverse(t);
+ triple a=ymin == -infinity ? tinv*(xtrans(t,x),lb.y-min3(p).y,
+ ztrans(t,z)) : (x,ymin,z);
+ triple b=ymax == infinity ? tinv*(xtrans(t,x),rt.y-max3(p).y,
+ ztrans(t,z)) : (x,ymax,z);
+ real x0;
+ real z0;
+ if(abs(dir.x) < abs(dir.z)) {
+ x0=x;
+ z0=z2;
+ } else {
+ x0=x2;
+ z0=z;
+ }
+
+ triple a2=ymin == -infinity ? tinv*(xtrans(t,x0),lb.y-min3(p).y,
+ ztrans(t,z0)) : (x0,ymin,z0);
+ triple b2=ymax == infinity ? tinv*(xtrans(t,x0),rt.y-max3(p).y,
+ ztrans(t,z0)) : (x0,ymax,z0);
+
+ if(ymin == -infinity || ymax == infinity) {
+ bounds my=autoscale(a.y,b.y,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ divisor=my.divisor;
+ }
+
+ triple fuzz=Y*epsilon*max(abs(a.y),abs(b.y));
+ a -= fuzz;
+ b += fuzz;
+
+ picture d;
+ ticks(d,t,L,a--b,finite(x0) && finite(z0) ? a2--b2 : nullpath3,
+ p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y,Dir(dir)),divisor,
+ opposite,primary);
+ add(f,t*T*tinv*d);
+ },above=above);
+
+ void bounds() {
+ if(type == Min)
+ x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x;
+ else if(type == Max)
+ x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x;
+ else if(type == Both) {
+ x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x;
+ x=opposite ? x2 :
+ (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x);
+ }
+
+ if(type2 == Min)
+ z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z;
+ else if(type2 == Max)
+ z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z;
+ else if(type2 == Both) {
+ z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z;
+ z=opposite2 ? z2 :
+ (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z);
+ }
+
+ real Ymin=finite(ymin) ? ymin : pic.userMin().y;
+ real Ymax=finite(ymax) ? ymax : pic.userMax().y;
+
+ triple a=(x,Ymin,z);
+ triple b=(x,Ymax,z);
+ triple a2=(x2,Ymin,z2);
+ triple b2=(x2,Ymax,z2);
+
+ if(finite(a)) {
+ pic.addPoint(a,min3(p));
+ pic.addPoint(a,max3(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min3(p));
+ pic.addPoint(b,max3(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ picture d;
+ ticks(d,pic.scaling3(warn=false),L,
+ (0,a.y,0)--(0,b.y,0),(0,a2.y,0)--(0,a2.y,0),p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y,Dir(dir)),divisor,
+ opposite,primary);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ triple pos=a+L.relative()*(b-a);
+ triple m=min3(d);
+ triple M=max3(d);
+ pic.addBox(pos,pos,(m.x,min3(f).y,m.z),(m.x,max3(f).y,m.z));
+ }
+ }
+
+ // Process any queued x and z axis bound calculation requests.
+ for(int i=0; i < pic.scale.x.bound.length; ++i)
+ pic.scale.x.bound[i]();
+ for(int i=0; i < pic.scale.z.bound.length; ++i)
+ pic.scale.z.bound[i]();
+
+ pic.scale.x.bound.delete();
+ pic.scale.z.bound.delete();
+
+ bounds();
+
+ // Request another y bounds calculation before final picture scaling.
+ pic.scale.y.bound.push(bounds);
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void zaxis3At(picture pic=currentpicture, Label L="", axis axis,
+ real zmin=-infinity, real zmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=true,
+ bool opposite=false, bool opposite2=false, bool primary=true)
+{
+ int type=axis.type;
+ int type2=axis.type2;
+ triple dir=axis.align.dir3 == O ?
+ defaultdir(X,Y,Z,opposite^opposite2,currentprojection) : axis.align.dir3;
+ Label L=L.copy();
+ if(L.align.dir3 == O && L.align.dir == 0) L.align(opposite ? -dir : dir);
+
+ real x=axis.value;
+ real y=axis.value2;
+ real x2,y2;
+ int[] divisor=copy(axis.zdivisor);
+
+ pic.add(new void(picture f, transform3 t, transform3 T, triple lb,
+ triple rt) {
+ transform3 tinv=inverse(t);
+ triple a=zmin == -infinity ? tinv*(xtrans(t,x),ytrans(t,y),
+ lb.z-min3(p).z) : (x,y,zmin);
+ triple b=zmax == infinity ? tinv*(xtrans(t,x),ytrans(t,y),
+ rt.z-max3(p).z) : (x,y,zmax);
+ real x0;
+ real y0;
+ if(abs(dir.x) < abs(dir.y)) {
+ x0=x;
+ y0=y2;
+ } else {
+ x0=x2;
+ y0=y;
+ }
+
+ triple a2=zmin == -infinity ? tinv*(xtrans(t,x0),ytrans(t,y0),
+ lb.z-min3(p).z) : (x0,y0,zmin);
+ triple b2=zmax == infinity ? tinv*(xtrans(t,x0),ytrans(t,y0),
+ rt.z-max3(p).z) : (x0,y0,zmax);
+
+ if(zmin == -infinity || zmax == infinity) {
+ bounds mz=autoscale(a.z,b.z,pic.scale.z.scale);
+ pic.scale.z.tickMin=mz.min;
+ pic.scale.z.tickMax=mz.max;
+ divisor=mz.divisor;
+ }
+
+ triple fuzz=Z*epsilon*max(abs(a.z),abs(b.z));
+ a -= fuzz;
+ b += fuzz;
+
+ picture d;
+ ticks(d,t,L,a--b,finite(x0) && finite(y0) ? a2--b2 : nullpath3,
+ p,arrow,margin,
+ ticklocate(a.z,b.z,pic.scale.z,Dir(dir)),divisor,
+ opposite,primary);
+ add(f,t*T*tinv*d);
+ },above=above);
+
+ void bounds() {
+ if(type == Min)
+ x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x;
+ else if(type == Max)
+ x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x;
+ else if(type == Both) {
+ x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x;
+ x=opposite ? x2 :
+ (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x);
+ }
+
+ if(type2 == Min)
+ y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y;
+ else if(type2 == Max)
+ y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y;
+ else if(type2 == Both) {
+ y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y;
+ y=opposite2 ? y2 :
+ (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y);
+ }
+
+ real Zmin=finite(zmin) ? zmin : pic.userMin().z;
+ real Zmax=finite(zmax) ? zmax : pic.userMax().z;
+
+ triple a=(x,y,Zmin);
+ triple b=(x,y,Zmax);
+ triple a2=(x2,y2,Zmin);
+ triple b2=(x2,y2,Zmax);
+
+ if(finite(a)) {
+ pic.addPoint(a,min3(p));
+ pic.addPoint(a,max3(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min3(p));
+ pic.addPoint(b,max3(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ picture d;
+ ticks(d,pic.scaling3(warn=false),L,
+ (0,0,a.z)--(0,0,b.z),(0,0,a2.z)--(0,0,a2.z),p,arrow,margin,
+ ticklocate(a.z,b.z,pic.scale.z,Dir(dir)),divisor,
+ opposite,primary);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ triple pos=a+L.relative()*(b-a);
+ triple m=min3(d);
+ triple M=max3(d);
+ pic.addBox(pos,pos,(m.x,m.y,min3(f).z),(m.x,m.y,max3(f).z));
+ }
+ }
+
+ // Process any queued x and y axes bound calculation requests.
+ for(int i=0; i < pic.scale.x.bound.length; ++i)
+ pic.scale.x.bound[i]();
+ for(int i=0; i < pic.scale.y.bound.length; ++i)
+ pic.scale.y.bound[i]();
+
+ pic.scale.x.bound.delete();
+ pic.scale.y.bound.delete();
+
+ bounds();
+
+ // Request another z bounds calculation before final picture scaling.
+ pic.scale.z.bound.push(bounds);
+}
+
+// Internal routine to autoscale the user limits of a picture.
+void autoscale3(picture pic=currentpicture, axis axis)
+{
+ bool set=pic.scale.set;
+ autoscale(pic,axis);
+
+ if(!set) {
+ bounds mz;
+ if(pic.userSetz()) {
+ mz=autoscale(pic.userMin().z,pic.userMax().z,pic.scale.z.scale);
+ if(pic.scale.z.scale.logarithmic &&
+ floor(pic.userMin().z) == floor(pic.userMax().z)) {
+ if(pic.scale.z.automin())
+ pic.userMinz3(floor(pic.userMin().z));
+ if(pic.scale.z.automax())
+ pic.userMaxz3(ceil(pic.userMax().z));
+ }
+ } else {mz.min=mz.max=0; pic.scale.set=false;}
+
+ pic.scale.z.tickMin=mz.min;
+ pic.scale.z.tickMax=mz.max;
+ axis.zdivisor=mz.divisor;
+ }
+}
+
+// Draw an x axis in three dimensions.
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=false)
+{
+ if(xmin > xmax) return;
+
+ if(pic.scale.x.automin && xmin > -infinity) pic.scale.x.automin=false;
+ if(pic.scale.x.automax && xmax < infinity) pic.scale.x.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale3(pic,axis);
+ }
+
+ bool newticks=false;
+
+ if(xmin != -infinity) {
+ xmin=pic.scale.x.T(xmin);
+ newticks=true;
+ }
+
+ if(xmax != infinity) {
+ xmax=pic.scale.x.T(xmax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSetx() && ticks != NoTicks3) {
+ if(xmin == -infinity) xmin=pic.userMin().x;
+ if(xmax == infinity) xmax=pic.userMax().x;
+ bounds mx=autoscale(xmin,xmax,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ axis.xdivisor=mx.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(xmin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmin=pic.scale.x.automin() ? pic.scale.x.tickMin :
+ max(pic.scale.x.tickMin,pic.userMin().x);
+ else xmin=pic.userMin().x;
+ }
+
+ if(xmax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmax=pic.scale.x.automax() ? pic.scale.x.tickMax :
+ min(pic.scale.x.tickMax,pic.userMax().x);
+ else xmax=pic.userMax().x;
+ }
+
+ if(L.defaultposition) {
+ L=L.copy();
+ L.position(axis.position);
+ }
+
+ bool back=false;
+ if(axis.type == Both) {
+ triple v=currentprojection.normal;
+ back=dot((0,pic.userMax().y-pic.userMin().y,0),v)*sgn(v.z) > 0;
+ }
+
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,false,false,!back);
+ if(axis.type == Both)
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,true,false,back);
+ if(axis.type2 == Both) {
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,false,true,false);
+ if(axis.type == Both)
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,true,true,false);
+ }
+}
+
+// Draw a y axis in three dimensions.
+void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=false)
+{
+ if(ymin > ymax) return;
+
+ if(pic.scale.y.automin && ymin > -infinity) pic.scale.y.automin=false;
+ if(pic.scale.y.automax && ymax < infinity) pic.scale.y.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale3(pic,axis);
+ }
+
+ bool newticks=false;
+
+ if(ymin != -infinity) {
+ ymin=pic.scale.y.T(ymin);
+ newticks=true;
+ }
+
+ if(ymax != infinity) {
+ ymax=pic.scale.y.T(ymax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSety() && ticks != NoTicks3) {
+ if(ymin == -infinity) ymin=pic.userMin().y;
+ if(ymax == infinity) ymax=pic.userMax().y;
+ bounds my=autoscale(ymin,ymax,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ axis.ydivisor=my.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(ymin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymin=pic.scale.y.automin() ? pic.scale.y.tickMin :
+ max(pic.scale.y.tickMin,pic.userMin().y);
+ else ymin=pic.userMin().y;
+ }
+
+
+ if(ymax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymax=pic.scale.y.automax() ? pic.scale.y.tickMax :
+ min(pic.scale.y.tickMax,pic.userMax().y);
+ else ymax=pic.userMax().y;
+ }
+
+ if(L.defaultposition) {
+ L=L.copy();
+ L.position(axis.position);
+ }
+
+ bool back=false;
+ if(axis.type == Both) {
+ triple v=currentprojection.normal;
+ back=dot((pic.userMax().x-pic.userMin().x,0,0),v)*sgn(v.z) > 0;
+ }
+
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,false,false,!back);
+
+ if(axis.type == Both)
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,true,false,back);
+ if(axis.type2 == Both) {
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,false,true,false);
+ if(axis.type == Both)
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,true,true,false);
+ }
+}
+// Draw a z axis in three dimensions.
+void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero,
+ real zmin=-infinity, real zmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=false)
+{
+ if(zmin > zmax) return;
+
+ if(pic.scale.z.automin && zmin > -infinity) pic.scale.z.automin=false;
+ if(pic.scale.z.automax && zmax < infinity) pic.scale.z.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale3(pic,axis);
+ }
+
+ bool newticks=false;
+
+ if(zmin != -infinity) {
+ zmin=pic.scale.z.T(zmin);
+ newticks=true;
+ }
+
+ if(zmax != infinity) {
+ zmax=pic.scale.z.T(zmax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSetz() && ticks != NoTicks3) {
+ if(zmin == -infinity) zmin=pic.userMin().z;
+ if(zmax == infinity) zmax=pic.userMax().z;
+ bounds mz=autoscale(zmin,zmax,pic.scale.z.scale);
+ pic.scale.z.tickMin=mz.min;
+ pic.scale.z.tickMax=mz.max;
+ axis.zdivisor=mz.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(zmin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ zmin=pic.scale.z.automin() ? pic.scale.z.tickMin :
+ max(pic.scale.z.tickMin,pic.userMin().z);
+ else zmin=pic.userMin().z;
+ }
+
+ if(zmax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ zmax=pic.scale.z.automax() ? pic.scale.z.tickMax :
+ min(pic.scale.z.tickMax,pic.userMax().z);
+ else zmax=pic.userMax().z;
+ }
+
+ if(L.defaultposition) {
+ L=L.copy();
+ L.position(axis.position);
+ }
+
+ bool back=false;
+ if(axis.type == Both) {
+ triple v=currentprojection.vector();
+ back=dot((pic.userMax().x-pic.userMin().x,0,0),v)*sgn(v.y) > 0;
+ }
+
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,false,false,!back);
+ if(axis.type == Both)
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,true,false,back);
+ if(axis.type2 == Both) {
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,false,true,false);
+ if(axis.type == Both)
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,true,true,false);
+ }
+}
+
+// Set the z limits of a picture.
+void zlimits(picture pic=currentpicture, real min=-infinity, real max=infinity,
+ bool crop=NoCrop)
+{
+ if(min > max) return;
+
+ pic.scale.z.automin=min <= -infinity;
+ pic.scale.z.automax=max >= infinity;
+
+ bounds mz;
+ if(pic.scale.z.automin() || pic.scale.z.automax())
+ mz=autoscale(pic.userMin().z,pic.userMax().z,pic.scale.z.scale);
+
+ if(pic.scale.z.automin) {
+ if(pic.scale.z.automin()) pic.userMinz(mz.min);
+ } else pic.userMinz(min(pic.scale.z.T(min),pic.scale.z.T(max)));
+
+ if(pic.scale.z.automax) {
+ if(pic.scale.z.automax()) pic.userMaxz(mz.max);
+ } else pic.userMaxz(max(pic.scale.z.T(min),pic.scale.z.T(max)));
+}
+
+// Restrict the x, y, and z limits to box(min,max).
+void limits(picture pic=currentpicture, triple min, triple max)
+{
+ xlimits(pic,min.x,max.x);
+ ylimits(pic,min.y,max.y);
+ zlimits(pic,min.z,max.z);
+}
+
+// Draw x, y and z axes.
+void axes3(picture pic=currentpicture,
+ Label xlabel="", Label ylabel="", Label zlabel="",
+ bool extend=false,
+ triple min=(-infinity,-infinity,-infinity),
+ triple max=(infinity,infinity,infinity),
+ pen p=currentpen, arrowbar3 arrow=None, margin3 margin=NoMargin3)
+{
+ xaxis3(pic,xlabel,YZZero(extend),min.x,max.x,p,arrow,margin);
+ yaxis3(pic,ylabel,XZZero(extend),min.y,max.y,p,arrow,margin);
+ zaxis3(pic,zlabel,XYZero(extend),min.z,max.z,p,arrow,margin);
+}
+
+triple Scale(picture pic=currentpicture, triple v)
+{
+ return (pic.scale.x.T(v.x),pic.scale.y.T(v.y),pic.scale.z.T(v.z));
+}
+
+real ScaleZ(picture pic=currentpicture, real z)
+{
+ return pic.scale.z.T(z);
+}
+
+// Draw a tick of length size at triple v in direction dir using pen p.
+void tick(picture pic=currentpicture, triple v, triple dir, real size=Ticksize,
+ pen p=currentpen)
+{
+ triple v=Scale(pic,v);
+ pic.add(new void (picture f, transform3 t) {
+ triple tv=t*v;
+ draw(f,tv--tv+unit(dir)*size,p);
+ });
+ pic.addPoint(v,p);
+ pic.addPoint(v,unit(dir)*size,p);
+}
+
+void xtick(picture pic=currentpicture, triple v, triple dir=Y,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,v,dir,size,p);
+}
+
+void xtick3(picture pic=currentpicture, real x, triple dir=Y,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,(x,pic.scale.y.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, triple v, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,v,dir,size,p);
+}
+
+void ytick3(picture pic=currentpicture, real y, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,(pic.scale.x.scale.logarithmic ? 1 : 0,y,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ztick(picture pic=currentpicture, triple v, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,v,dir,size,p);
+}
+
+void ztick3(picture pic=currentpicture, real z, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,(pic.scale.x.scale.logarithmic ? 1 : 0,
+ pic.scale.y.scale.logarithmic ? 1 : 0,z),dir,size,p);
+}
+
+void tick(picture pic=currentpicture, Label L, real value, triple v,
+ triple dir, string format="", real size=Ticksize, pen p=currentpen)
+{
+ Label L=L.copy();
+ L.align(L.align,-dir);
+ if(shift(L.T3)*O == O)
+ L.T3=shift(dot(dir,L.align.dir3) > 0 ? dir*size :
+ ticklabelshift(L.align.dir3,p))*L.T3;
+ L.p(p);
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,value);
+ L.s=baseline(L.s,baselinetemplate);
+ label(pic,L,Scale(pic,v));
+ tick(pic,v,dir,size,p);
+}
+
+void xtick(picture pic=currentpicture, Label L, triple v, triple dir=Y,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,v.x,v,dir,format,size,p);
+}
+
+void xtick3(picture pic=currentpicture, Label L, real x, triple dir=Y,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, Label L, triple v, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,v.y,v,dir,format,size,p);
+}
+
+void ytick3(picture pic=currentpicture, Label L, real y, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,format,size,p);
+}
+
+void ztick(picture pic=currentpicture, Label L, triple v, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,v.z,v,dir,format,size,p);
+}
+
+void ztick3(picture pic=currentpicture, Label L, real z, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0,z),dir,format,size,p);
+}
+
+private void label(picture pic, Label L, triple v, real x, align align,
+ string format, pen p)
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ if(shift(L.T3)*O == O)
+ L.T3=shift(ticklabelshift(L.align.dir3,L.p))*L.T3;
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,x);
+ L.s=baseline(L.s,baselinetemplate);
+ label(pic,L,v);
+}
+
+void labelx(picture pic=currentpicture, Label L="", triple v,
+ align align=-Y, string format="", pen p=currentpen)
+{
+ label(pic,L,Scale(pic,v),v.x,align,format,p);
+}
+
+void labelx3(picture pic=currentpicture, Label L="", real x,
+ align align=-Y, string format="", pen p=currentpen)
+{
+ labelx(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0),align,format,p);
+}
+
+void labely(picture pic=currentpicture, Label L="", triple v,
+ align align=-X, string format="", pen p=currentpen)
+{
+ label(pic,L,Scale(pic,v),v.y,align,format,p);
+}
+
+void labely3(picture pic=currentpicture, Label L="", real y,
+ align align=-X, string format="", pen p=currentpen)
+{
+ labely(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y,
+ pic.scale.z.scale.logarithmic ? 1 : 0),align,format,p);
+}
+
+void labelz(picture pic=currentpicture, Label L="", triple v,
+ align align=-X, string format="", pen p=currentpen)
+{
+ label(pic,L,Scale(pic,v),v.z,align,format,p);
+}
+
+void labelz3(picture pic=currentpicture, Label L="", real z,
+ align align=-X, string format="", pen p=currentpen)
+{
+ labelz(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,
+ pic.scale.y.scale.logarithmic ? 1 : 0,z),align,format,p);
+}
+
+typedef guide3 graph(triple F(real), real, real, int);
+typedef guide3[] multigraph(triple F(real), real, real, int);
+
+graph graph(interpolate3 join)
+{
+ return new guide3(triple f(real), real a, real b, int n) {
+ real width=b-a;
+ return n == 0 ? join(f(a)) :
+ join(...sequence(new guide3(int i) {return f(a+(i/n)*width);},n+1));
+ };
+}
+
+multigraph graph(interpolate3 join, bool3 cond(real))
+{
+ return new guide3[](triple f(real), real a, real b, int n) {
+ real width=b-a;
+ if(n == 0) return new guide3[] {join(cond(a) ? f(a) : nullpath3)};
+ guide3[] G;
+ guide3[] g;
+ for(int i=0; i < n+1; ++i) {
+ real t=a+(i/n)*width;
+ bool3 b=cond(t);
+ if(b)
+ g.push(f(t));
+ else {
+ if(g.length > 0) {
+ G.push(join(...g));
+ g=new guide3[] {};
+ }
+ if(b == default)
+ g.push(f(t));
+ }
+ }
+ if(g.length > 0)
+ G.push(join(...g));
+ return G;
+ };
+}
+
+guide3 Straight(... guide3[])=operator --;
+guide3 Spline(... guide3[])=operator ..;
+
+guide3 graph(picture pic=currentpicture, real x(real), real y(real),
+ real z(real), real a, real b, int n=ngraph,
+ interpolate3 join=operator --)
+{
+ return graph(join)(new triple(real t) {return Scale(pic,(x(t),y(t),z(t)));},
+ a,b,n);
+}
+
+guide3[] graph(picture pic=currentpicture, real x(real), real y(real),
+ real z(real), real a, real b, int n=ngraph,
+ bool3 cond(real), interpolate3 join=operator --)
+{
+ return graph(join,cond)(new triple(real t) {
+ return Scale(pic,(x(t),y(t),z(t)));
+ },a,b,n);
+}
+
+guide3 graph(picture pic=currentpicture, triple v(real), real a, real b,
+ int n=ngraph, interpolate3 join=operator --)
+{
+ return graph(join)(new triple(real t) {return Scale(pic,v(t));},a,b,n);
+}
+
+guide3[] graph(picture pic=currentpicture, triple v(real), real a, real b,
+ int n=ngraph, bool3 cond(real), interpolate3 join=operator --)
+{
+ return graph(join,cond)(new triple(real t) {
+ return Scale(pic,v(t));
+ },a,b,n);
+}
+
+guide3 graph(picture pic=currentpicture, triple[] v,
+ interpolate3 join=operator --)
+{
+ int i=0;
+ return graph(join)(new triple(real) {
+ triple w=Scale(pic,v[i]);
+ ++i;
+ return w;
+ },0,0,v.length-1);
+}
+
+guide3[] graph(picture pic=currentpicture, triple[] v, bool3[] cond,
+ interpolate3 join=operator --)
+{
+ int n=v.length;
+ int i=0;
+ triple w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool b=cond[i];
+ if(b) w=Scale(pic,v[i]);
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new triple(real) {return w;},0,0,n-1);
+}
+
+guide3 graph(picture pic=currentpicture, real[] x, real[] y, real[] z,
+ interpolate3 join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,z.length);
+ int i=0;
+ return graph(join)(new triple(real) {
+ triple w=Scale(pic,(x[i],y[i],z[i]));
+ ++i;
+ return w;
+ },0,0,n-1);
+}
+
+guide3[] graph(picture pic=currentpicture, real[] x, real[] y, real[] z,
+ bool3[] cond, interpolate3 join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,z.length);
+ int i=0;
+ triple w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool3 b=cond[i];
+ if(b != false) w=Scale(pic,(x[i],y[i],z[i]));
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new triple(real) {return w;},0,0,n-1);
+}
+
+// The graph of a function along a path.
+guide3 graph(triple F(path, real), path p, int n=1,
+ interpolate3 join=operator --)
+{
+ guide3 g=join(...sequence(new guide3(int i) {
+ return F(p,i/n);
+ },n*length(p)));
+ return cyclic(p) ? join(g,cycle) : join(g,F(p,length(p)));
+}
+
+guide3 graph(triple F(pair), path p, int n=1, interpolate3 join=operator --)
+{
+ return graph(new triple(path p, real position)
+ {return F(point(p,position));},p,n,join);
+}
+
+guide3 graph(picture pic=currentpicture, real f(pair), path p, int n=1,
+ interpolate3 join=operator --)
+{
+ return graph(new triple(pair z) {return Scale(pic,(z.x,z.y,f(z)));},p,n,
+ join);
+}
+
+guide3 graph(real f(pair), path p, int n=1, real T(pair),
+ interpolate3 join=operator --)
+{
+ return graph(new triple(pair z) {pair w=T(z); return (w.x,w.y,f(w));},p,n,
+ join);
+}
+
+// Connect points in v into segments corresponding to consecutive true elements
+// of b using interpolation operator join.
+path3[] segment(triple[] v, bool[] cond, interpolate3 join=operator --)
+{
+ checkconditionlength(cond.length,v.length);
+ int[][] segment=segment(cond);
+ return sequence(new path3(int i) {return join(...v[segment[i]]);},
+ segment.length);
+}
+
+bool uperiodic(triple[][] a) {
+ int n=a.length;
+ if(n == 0) return false;
+ int m=a[0].length;
+ triple[] a0=a[0];
+ triple[] a1=a[n-1];
+ real epsilon=sqrtEpsilon*norm(a);
+ for(int j=0; j < m; ++j)
+ if(abs(a0[j]-a1[j]) > epsilon) return false;
+ return true;
+}
+bool vperiodic(triple[][] a) {
+ int n=a.length;
+ if(n == 0) return false;
+ int m=a[0].length-1;
+ real epsilon=sqrtEpsilon*norm(a);
+ for(int i=0; i < n; ++i)
+ if(abs(a[i][0]-a[i][m]) > epsilon) return false;
+ return true;
+}
+
+// return the surface described by a matrix f
+surface surface(triple[][] f, bool[][] cond={})
+{
+ if(!rectangular(f)) abort("matrix is not rectangular");
+
+ int nx=f.length-1;
+ int ny=nx > 0 ? f[0].length-1 : 0;
+
+ bool all=cond.length == 0;
+
+ int count;
+ if(all)
+ count=nx*ny;
+ else {
+ count=0;
+ for(int i=0; i < nx; ++i) {
+ bool[] condi=cond[i];
+ bool[] condp=cond[i+1];
+ for(int j=0; j < ny; ++j)
+ if(condi[j] && condi[j+1] && condp[j] && condp[j+1]) ++count;
+ }
+ }
+
+ surface s=surface(count);
+ s.index=new int[nx][ny];
+ int k=-1;
+ for(int i=0; i < nx; ++i) {
+ bool[] condi,condp;
+ if(!all) {
+ condi=cond[i];
+ condp=cond[i+1];
+ }
+ triple[] fi=f[i];
+ triple[] fp=f[i+1];
+ int[] indexi=s.index[i];
+ for(int j=0; j < ny; ++j) {
+ if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1]))
+ s.s[++k]=patch(new triple[] {fi[j],fp[j],fp[j+1],fi[j+1]});
+ indexi[j]=k;
+ }
+ }
+
+ if(count == nx*ny) {
+ if(uperiodic(f)) s.ucyclic(true);
+ if(vperiodic(f)) s.vcyclic(true);
+ }
+
+ return s;
+}
+
+surface bispline(real[][] z, real[][] p, real[][] q, real[][] r,
+ real[] x, real[] y, bool[][] cond={})
+{ // z[i][j] is the value at (x[i],y[j])
+ // p and q are the first derivatives with respect to x and y, respectively
+ // r is the second derivative ddu/dxdy
+ int n=x.length-1;
+ int m=y.length-1;
+
+ bool all=cond.length == 0;
+
+ int count;
+ if(all)
+ count=n*m;
+ else {
+ count=0;
+ for(int i=0; i < n; ++i) {
+ bool[] condi=cond[i];
+ for(int j=0; j < m; ++j)
+ if(condi[j]) ++count;
+ }
+ }
+
+ surface s=surface(count);
+ s.index=new int[n][m];
+ int k=0;
+ for(int i=0; i < n; ++i) {
+ int ip=i+1;
+ real xi=x[i];
+ real xp=x[ip];
+ real x1=interp(xi,xp,1/3);
+ real x2=interp(xi,xp,2/3);
+ real hx=x1-xi;
+ real[] zi=z[i];
+ real[] zp=z[ip];
+ real[] ri=r[i];
+ real[] rp=r[ip];
+ real[] pi=p[i];
+ real[] pp=p[ip];
+ real[] qi=q[i];
+ real[] qp=q[ip];
+ int[] indexi=s.index[i];
+ bool[] condi=all ? null : cond[i];
+ for(int j=0; j < m; ++j) {
+ if(all || condi[j]) {
+ real yj=y[j];
+ int jp=j+1;
+ real yp=y[jp];
+ real y1=interp(yj,yp,1/3);
+ real y2=interp(yj,yp,2/3);
+ real hy=y1-yj;
+ real hxy=hx*hy;
+ real zij=zi[j];
+ real zip=zi[jp];
+ real zpj=zp[j];
+ real zpp=zp[jp];
+ real pij=hx*pi[j];
+ real ppj=hx*pp[j];
+ real qip=hy*qi[jp];
+ real qpp=hy*qp[jp];
+ real zippip=zip+hx*pi[jp];
+ real zppmppp=zpp-hx*pp[jp];
+ real zijqij=zij+hy*qi[j];
+ real zpjqpj=zpj+hy*qp[j];
+
+ s.s[k]=patch(new triple[][] {
+ {(xi,yj,zij),(xi,y1,zijqij),(xi,y2,zip-qip),(xi,yp,zip)},
+ {(x1,yj,zij+pij),(x1,y1,zijqij+pij+hxy*ri[j]),
+ (x1,y2,zippip-qip-hxy*ri[jp]),(x1,yp,zippip)},
+ {(x2,yj,zpj-ppj),(x2,y1,zpjqpj-ppj-hxy*rp[j]),
+ (x2,y2,zppmppp-qpp+hxy*rp[jp]),(x2,yp,zppmppp)},
+ {(xp,yj,zpj),(xp,y1,zpjqpj),(xp,y2,zpp-qpp),(xp,yp,zpp)}},copy=false);
+ indexi[j]=k;
+ ++k;
+ }
+ }
+ }
+
+ return s;
+}
+
+// return the surface described by a real matrix f, interpolated with
+// xsplinetype and ysplinetype.
+surface surface(real[][] f, real[] x, real[] y,
+ splinetype xsplinetype=null, splinetype ysplinetype=xsplinetype,
+ bool[][] cond={})
+{
+ real epsilon=sqrtEpsilon*norm(y);
+ if(xsplinetype == null)
+ xsplinetype=(abs(x[0]-x[x.length-1]) <= epsilon) ? periodic : notaknot;
+ if(ysplinetype == null)
+ ysplinetype=(abs(y[0]-y[y.length-1]) <= epsilon) ? periodic : notaknot;
+ int n=x.length; int m=y.length;
+ real[][] ft=transpose(f);
+ real[][] tp=new real[m][];
+ for(int j=0; j < m; ++j)
+ tp[j]=xsplinetype(x,ft[j]);
+ real[][] q=new real[n][];
+ for(int i=0; i < n; ++i)
+ q[i]=ysplinetype(y,f[i]);
+ real[][] qt=transpose(q);
+ real[] d1=xsplinetype(x,qt[0]);
+ real[] d2=xsplinetype(x,qt[m-1]);
+ real[][] r=new real[n][];
+ real[][] p=transpose(tp);
+ for(int i=0; i < n; ++i)
+ r[i]=clamped(d1[i],d2[i])(y,p[i]);
+ surface s=bispline(f,p,q,r,x,y,cond);
+ if(xsplinetype == periodic) s.ucyclic(true);
+ if(ysplinetype == periodic) s.vcyclic(true);
+ return s;
+}
+
+// return the surface described by a real matrix f, interpolated with
+// xsplinetype and ysplinetype.
+surface surface(real[][] f, pair a, pair b, splinetype xsplinetype,
+ splinetype ysplinetype=xsplinetype, bool[][] cond={})
+{
+ if(!rectangular(f)) abort("matrix is not rectangular");
+
+ int nx=f.length-1;
+ int ny=nx > 0 ? f[0].length-1 : 0;
+
+ if(nx == 0 || ny == 0) return nullsurface;
+
+ real[] x=uniform(a.x,b.x,nx);
+ real[] y=uniform(a.y,b.y,ny);
+ return surface(f,x,y,xsplinetype,ysplinetype,cond);
+}
+
+// return the surface described by a real matrix f, interpolated linearly.
+surface surface(real[][] f, pair a, pair b, bool[][] cond={})
+{
+ if(!rectangular(f)) abort("matrix is not rectangular");
+
+ int nx=f.length-1;
+ int ny=nx > 0 ? f[0].length-1 : 0;
+
+ if(nx == 0 || ny == 0) return nullsurface;
+
+ bool all=cond.length == 0;
+
+ triple[][] v=new triple[nx+1][ny+1];
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i/nx);
+ bool[] condi=all ? null : cond[i];
+ triple[] vi=v[i];
+ real[] fi=f[i];
+ for(int j=0; j <= ny; ++j)
+ if(all || condi[j])
+ vi[j]=(x,interp(a.y,b.y,j/ny),fi[j]);
+ }
+ return surface(v,cond);
+}
+
+// return the surface described by a parametric function f over box(a,b),
+// interpolated linearly.
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ bool cond(pair z)=null)
+{
+ if(nu <= 0 || nv <= 0) return nullsurface;
+
+ bool[][] active;
+ bool all=cond == null;
+ if(!all) active=new bool[nu+1][nv+1];
+
+ real du=1/nu;
+ real dv=1/nv;
+ pair Idv=(0,dv);
+ pair dz=(du,dv);
+
+ triple[][] v=new triple[nu+1][nv+1];
+
+ for(int i=0; i <= nu; ++i) {
+ real x=interp(a.x,b.x,i*du);
+ bool[] activei=all ? null : active[i];
+ triple[] vi=v[i];
+ for(int j=0; j <= nv; ++j) {
+ pair z=(x,interp(a.y,b.y,j*dv));
+ if(all || (activei[j]=cond(z))) vi[j]=f(z);
+ }
+ }
+ return surface(v,active);
+}
+
+// return the surface described by a parametric function f over box(a,b),
+// interpolated with usplinetype and vsplinetype.
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
+ bool cond(pair z)=null)
+{
+ return surface(f,uniform(a.x,b.x,nu),uniform(a.y,b.y,nv),
+ usplinetype,vsplinetype,cond);
+}
+
+// return the surface described by a real function f over box(a,b),
+// interpolated linearly.
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ bool cond(pair z)=null)
+{
+ return surface(new triple(pair z) {return (z.x,z.y,f(z));},a,b,nx,ny,cond);
+}
+
+// return the surface described by a real function f over box(a,b),
+// interpolated with xsplinetype and ysplinetype.
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ splinetype xsplinetype, splinetype ysplinetype=xsplinetype,
+ bool cond(pair z)=null)
+{
+ bool[][] active;
+ bool all=cond == null;
+ if(!all) active=new bool[nx+1][ny+1];
+
+ real dx=1/nx;
+ real dy=1/ny;
+ pair Idy=(0,dy);
+ pair dz=(dx,dy);
+
+ real[][] F=new real[nx+1][ny+1];
+ real[] x=uniform(a.x,b.x,nx);
+ real[] y=uniform(a.y,b.y,ny);
+ for(int i=0; i <= nx; ++i) {
+ bool[] activei=all ? null : active[i];
+ real[] Fi=F[i];
+ real x=x[i];
+ for(int j=0; j <= ny; ++j) {
+ pair z=(x,y[j]);
+ Fi[j]=f(z);
+ if(!all) activei[j]=cond(z);
+ }
+ }
+ return surface(F,x,y,xsplinetype,ysplinetype,active);
+}
+
+guide3[][] lift(real f(real x, real y), guide[][] g,
+ interpolate3 join=operator --)
+{
+ guide3[][] G=new guide3[g.length][];
+ for(int cnt=0; cnt < g.length; ++cnt) {
+ guide[] gcnt=g[cnt];
+ guide3[] Gcnt=new guide3[gcnt.length];
+ for(int i=0; i < gcnt.length; ++i) {
+ guide gcnti=gcnt[i];
+ guide3 Gcnti=join(...sequence(new guide3(int j) {
+ pair z=point(gcnti,j);
+ return (z.x,z.y,f(z.x,z.y));
+ },size(gcnti)));
+ if(cyclic(gcnti)) Gcnti=Gcnti..cycle;
+ Gcnt[i]=Gcnti;
+ }
+ G[cnt]=Gcnt;
+ }
+ return G;
+}
+
+guide3[][] lift(real f(pair z), guide[][] g, interpolate3 join=operator --)
+{
+ return lift(new real(real x, real y) {return f((x,y));},g,join);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide3[][] g, pen[] p, light light=currentlight, string name="",
+ render render=defaultrender,
+ interaction interaction=LabelInteraction())
+{
+ pen thin=is3D() ? thin() : defaultpen;
+ bool group=g.length > 1 && (name != "" || render.defaultnames);
+ if(group)
+ begingroup3(pic,name == "" ? "contours" : name,render);
+ for(int cnt=0; cnt < g.length; ++cnt) {
+ guide3[] gcnt=g[cnt];
+ pen pcnt=thin+p[cnt];
+ for(int i=0; i < gcnt.length; ++i)
+ draw(pic,gcnt[i],pcnt,light,name);
+ if(L.length > 0) {
+ Label Lcnt=L[cnt];
+ for(int i=0; i < gcnt.length; ++i) {
+ if(Lcnt.s != "" && size(gcnt[i]) > 1)
+ label(pic,Lcnt,gcnt[i],pcnt,name,interaction);
+ }
+ }
+ }
+ if(group)
+ endgroup3(pic);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide3[][] g, pen p=currentpen, light light=currentlight,
+ string name="", render render=defaultrender,
+ interaction interaction=LabelInteraction())
+{
+ draw(pic,L,g,sequence(new pen(int) {return p;},g.length),light,name,
+ render,interaction);
+}
+
+real maxlength(triple f(pair z), pair a, pair b, int nu, int nv)
+{
+ return min(abs(f((b.x,a.y))-f(a))/nu,abs(f((a.x,b.y))-f(a))/nv);
+}
+
+// return a vector field on a parametric surface f over box(a,b).
+picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b,
+ int nu=nmesh, int nv=nu, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(f,a,b,nu,nv),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3,
+ string name="", render render=defaultrender)
+{
+ picture pic;
+ real du=1/nu;
+ real dv=1/nv;
+ bool all=cond == null;
+ real scale;
+
+ if(maxlength > 0) {
+ real size(pair z) {
+ path3 g=vector(z);
+ return abs(point(g,size(g)-1)-point(g,0));
+ }
+ real max=size((0,0));
+ for(int i=0; i <= nu; ++i) {
+ real x=interp(a.x,b.x,i*du);
+ for(int j=0; j <= nv; ++j)
+ max=max(max,size((x,interp(a.y,b.y,j*dv))));
+ }
+ scale=max > 0 ? maxlength/max : 1;
+ } else scale=1;
+
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(pic,name == "" ? "vectorfield" : name,render);
+ for(int i=0; i <= nu; ++i) {
+ real x=interp(a.x,b.x,i*du);
+ for(int j=0; j <= nv; ++j) {
+ pair z=(x,interp(a.y,b.y,j*dv));
+ if(all || cond(z)) {
+ path3 g=scale3(scale)*vector(z);
+ string name="vector";
+ if(truesize) {
+ picture opic;
+ draw(opic,g,p,arrow,margin,name,render);
+ add(pic,opic,f(z));
+ } else
+ draw(pic,shift(f(z))*g,p,arrow,margin,name,render);
+ }
+ }
+ }
+ if(group)
+ endgroup3(pic);
+ return pic;
+}
+
+triple polar(real r, real theta, real phi)
+{
+ return r*expi(theta,phi);
+}
+
+guide3 polargraph(real r(real,real), real theta(real), real phi(real),
+ int n=ngraph, interpolate3 join=operator --)
+{
+ return graph(join)(new triple(real t) {
+ return polar(r(theta(t),phi(t)),theta(t),phi(t));
+ },0,1,n);
+}
+
+// True arc
+path3 Arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW,
+ int n=nCircle)
+{
+ v1 -= c;
+ real r=abs(v1);
+ v1=unit(v1);
+ v2=unit(v2-c);
+
+ if(normal == O) {
+ normal=cross(v1,v2);
+ if(normal == O) abort("explicit normal required for these endpoints");
+ }
+
+ transform3 T=align(unit(normal));
+ transform3 Tinv=transpose(T);
+ v1=Tinv*v1;
+ v2=Tinv*v2;
+
+ real fuzz=sqrtEpsilon*max(abs(v1),abs(v2));
+ if(abs(v1.z) > fuzz || abs(v2.z) > fuzz)
+ abort("invalid normal vector");
+
+ real phi1=radians(longitude(v1,warn=false));
+ real phi2=radians(longitude(v2,warn=false));
+ if(direction) {
+ if(phi1 >= phi2) phi1 -= 2pi;
+ } else if(phi2 >= phi1) phi2 -= 2pi;
+
+ static real piby2=pi/2;
+ return shift(c)*T*polargraph(new real(real theta, real phi) {return r;},
+ new real(real t) {return piby2;},
+ new real(real t) {return interp(phi1,phi2,t);},
+ n,operator ..);
+}
+
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O, bool direction, int n=nCircle)
+{
+ return Arc(c,c+r*dir(theta1,phi1),c+r*dir(theta2,phi2),normal,direction,n);
+}
+
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O, int n=nCircle)
+{
+ return Arc(c,r,theta1,phi1,theta2,phi2,normal,
+ theta2 > theta1 || (theta2 == theta1 && phi2 >= phi1) ? CCW : CW,
+ n);
+}
+
+// True circle
+path3 Circle(triple c, real r, triple normal=Z, int n=nCircle)
+{
+ static real piby2=pi/2;
+ return shift(c)*align(unit(normal))*
+ polargraph(new real(real theta, real phi) {return r;},
+ new real(real t) {return piby2;},
+ new real(real t) {return interp(0,2pi,t);},n,operator ..);
+
+}
diff --git a/graphics/asymptote/base/graph_settings.asy b/graphics/asymptote/base/graph_settings.asy
new file mode 100644
index 0000000000..f5d04d0797
--- /dev/null
+++ b/graphics/asymptote/base/graph_settings.asy
@@ -0,0 +1,18 @@
+// Number of function samples.
+int ngraph=100;
+int nCircle=400;
+
+// Number of mesh intervals.
+int nmesh=10;
+
+real ticksize=1mm;
+real Ticksize=2*ticksize;
+real ylabelwidth=2.0;
+real axislabelfactor=1.5;
+real axiscoverage=0.8;
+
+real epsilon=10*realEpsilon;
+
+restricted bool Crop=true;
+restricted bool NoCrop=false;
+
diff --git a/graphics/asymptote/base/graph_splinetype.asy b/graphics/asymptote/base/graph_splinetype.asy
new file mode 100644
index 0000000000..02f780ca02
--- /dev/null
+++ b/graphics/asymptote/base/graph_splinetype.asy
@@ -0,0 +1,264 @@
+private import math;
+
+typedef real[] splinetype(real[], real[]);
+
+restricted real[] Spline(real[] x, real[] y);
+restricted splinetype[] Spline;
+
+string morepoints="interpolation requires at least 2 points";
+string differentlengths="arrays have different lengths";
+void checklengths(int x, int y, string text=differentlengths)
+{
+ if(x != y)
+ abort(text+": "+string(x)+" != "+string(y));
+}
+
+void checkincreasing(real[] x)
+{
+ if(!increasing(x,true))
+ abort("strictly increasing array expected");
+}
+
+// Linear interpolation
+real[] linear(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ real[] d=new real[n];
+ for(int i=0; i < n-1; ++i)
+ d[i]=(y[i+1]-y[i])/(x[i+1]-x[i]);
+ d[n-1]=d[n-2];
+ return d;
+}
+
+// Standard cubic spline interpolation with not-a-knot condition:
+// s'''(x_2^-)=s'''(x_2^+) et s'''(x_(n_2)^-)=s'''(x_(n-2)^+)
+// if n=2, linear interpolation is returned
+// if n=3, an interpolation polynomial of degree <= 2 is returned:
+// p(x_1)=y_1, p(x_2)=y_2, p(x_3)=y_3
+real[] notaknot(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checkincreasing(x);
+ real[] d;
+ if(n > 3) {
+ real[] a=new real[n];
+ real[] b=new real[n];
+ real[] c=new real[n];
+ real[] g=new real[n];
+ b[0]=x[2]-x[1];
+ c[0]=x[2]-x[0];
+ a[0]=0;
+ g[0]=((x[1]-x[0])^2*(y[2]-y[1])/b[0]+b[0]*(2*b[0]+3*(x[1]-x[0]))*
+ (y[1]-y[0])/(x[1]-x[0]))/c[0];
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ c[n-1]=0;
+ b[n-1]=x[n-2]-x[n-3];
+ a[n-1]=x[n-1]-x[n-3];
+ g[n-1]=((x[n-1]-x[n-2])^2*(y[n-2]-y[n-3])/b[n-1]+
+ b[n-1]*(2*b[n-1]+3(x[n-1]-x[n-2]))*
+ (y[n-1]-y[n-2])/(x[n-1]-x[n-2]))/a[n-1];
+ d=tridiagonal(a,b,c,g);
+ } else if(n == 2) {
+ real val=(y[1]-y[0])/(x[1]-x[0]);
+ d=new real[] {val,val};
+ } else if(n == 3) {
+ real a=(y[1]-y[0])/(x[1]-x[0]);
+ real b=(y[2]-y[1])/(x[2]-x[1]);
+ real c=(b-a)/(x[2]-x[0]);
+ d=new real[] {a+c*(x[0]-x[1]),a+c*(x[1]-x[0]),a+c*(2*x[2]-x[0]-x[1])};
+ } else abort(morepoints);
+ return d;
+}
+
+// Standard cubic spline interpolation with periodic condition
+// s'(a)=s'(b), s''(a)=s''(b), assuming that f(a)=f(b)
+// if n=2, linear interpolation is returned
+real[] periodic(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checkincreasing(x);
+ if(abs(y[n-1]-y[0]) > sqrtEpsilon*norm(y))
+ abort("function values are not periodic");
+ real[] d;
+ if(n > 2) {
+ real[] a=new real[n-1];
+ real[] b=new real[n-1];
+ real[] c=new real[n-1];
+ real[] g=new real[n-1];
+ c[0]=x[n-1]-x[n-2];
+ a[0]=x[1]-x[0];
+ b[0]=2*(a[0]+c[0]);
+ g[0]=3*c[0]*(y[1]-y[0])/a[0]+3*a[0]*(y[n-1]-y[n-2])/c[0];
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ d=tridiagonal(a,b,c,g);
+ d.push(d[0]);
+ } else if(n == 2) {
+ d=new real[] {0,0};
+ } else abort(morepoints);
+ return d;
+}
+
+// Standard cubic spline interpolation with the natural condition
+// s''(a)=s''(b)=0.
+// if n=2, linear interpolation is returned
+// Don't use the natural type unless the underlying function
+// has zero second end points derivatives.
+real[] natural(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checkincreasing(x);
+ real[] d;
+ if(n > 2) {
+ real[] a=new real[n];
+ real[] b=new real[n];
+ real[] c=new real[n];
+ real[] g=new real[n];
+ b[0]=2*(x[1]-x[0]);
+ c[0]=x[1]-x[0];
+ a[0]=0;
+ g[0]=3*(y[1]-y[0]);
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ c[n-1]=0;
+ a[n-1]=x[n-1]-x[n-2];
+ b[n-1]=2*a[n-1];
+ g[n-1]=3*(y[n-1]-y[n-2]);
+ d=tridiagonal(a,b,c,g);
+ } else if(n == 2) {
+ real val=(y[1]-y[0])/(x[1]-x[0]);
+ d=new real[] {val,val};
+ } else abort(morepoints);
+ return d;
+}
+
+// Standard cubic spline interpolation with clamped conditions f'(a), f'(b)
+splinetype clamped(real slopea, real slopeb)
+{
+ return new real[] (real[] x, real[] y) {
+ int n=x.length;
+ checklengths(n,y.length);
+ checkincreasing(x);
+ real[] d;
+ if(n > 2) {
+ real[] a=new real[n];
+ real[] b=new real[n];
+ real[] c=new real[n];
+ real[] g=new real[n];
+ b[0]=x[1]-x[0];
+ g[0]=b[0]*slopea;
+ c[0]=0;
+ a[0]=0;
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ c[n-1]=0;
+ a[n-1]=0;
+ b[n-1]=x[n-1]-x[n-2];
+ g[n-1]=b[n-1]*slopeb;
+ d=tridiagonal(a,b,c,g);
+ } else if(n == 2) {
+ d=new real[] {slopea,slopeb};
+ } else abort(morepoints);
+ return d;
+ };
+}
+
+// Piecewise Cubic Hermite Interpolating Polynomial (PCHIP)
+// Modified MATLAB code
+// [1] Fritsch, F. N. and R. E. Carlson,
+// "Monotone Piecewise Cubic Interpolation,"
+// SIAM J. Numerical Analysis, Vol. 17, 1980, pp.238-246.
+// [2] Kahaner, David, Cleve Moler, Stephen Nash,
+// Numerical Methods and Software, Prentice Hall, 1988.
+real[] monotonic(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checkincreasing(x);
+ real[] d=new real[n];
+ if(n > 2) {
+ real[] h=new real[n-1];
+ real[] del=new real[n-1];
+ for(int i=0; i < n-1; ++i) {
+ h[i]=x[i+1]-x[i];
+ del[i]=(y[i+1]-y[i])/h[i];
+ }
+ int j=0;
+ int k[]=new int[];
+ for(int i=0; i < n-2; ++i)
+ if((sgn(del[i])*sgn(del[i+1])) > 0) {k[j]=i; j=j+1;}
+
+ real[] hs=new real[j];
+ for(int i=0; i < j; ++i) hs[i]=h[k[i]]+h[k[i]+1];
+ real w1[]=new real[j];
+ real w2[]=new real[j];
+ real dmax[]=new real[j];
+ real dmin[]=new real[j];
+ for(int i=0; i < j; ++i) {
+ w1[i]=(h[k[i]]+hs[i])/(3*hs[i]);
+ w2[i]=(h[k[i]+1]+hs[i])/(3*hs[i]);
+ dmax[i]=max(abs(del[k[i]]),abs(del[k[i]+1]));
+ dmin[i]=min(abs(del[k[i]]),abs(del[k[i]+1]));
+ }
+ for(int i=0; i < n; ++i) d[i]=0;
+ for(int i=0; i < j; ++i)
+ d[k[i]+1]=dmin[i]/(w1[i]*(del[k[i]]/dmax[i])+w2[i]*(del[k[i]+1]/dmax[i]));
+ d[0]=((2*h[0]+h[1])*del[0]-h[0]*del[1])/(h[0]+h[1]);
+ if(sgn(d[0]) != sgn(del[0])) {d[0]=0;}
+ else if((sgn(del[0]) != sgn(del[1])) && (abs(d[0]) > abs(3*del[0])))
+ d[0]=3*del[0];
+
+ d[n-1]=((2*h[n-2]+h[n-3])*del[n-2]-h[n-2]*del[n-2])/(h[n-2]+h[n-3]);
+ if(sgn(d[n-1]) != sgn(del[n-2])) {d[n-1]=0;}
+ else if((sgn(del[n-2]) != sgn(del[n-3])) &&
+ (abs(d[n-1]) > abs(3*del[n-2])))
+ d[n-1]=3*del[n-2];
+ } else if(n == 2) {
+ d[0]=d[1]=(y[1]-y[0])/(x[1]-x[0]);
+ } else abort(morepoints);
+ return d;
+}
+
+// Return standard cubic spline interpolation as a guide
+guide hermite(real[] x, real[] y, splinetype splinetype=null)
+{
+ int n=x.length;
+ if(n == 0) return nullpath;
+
+ guide g=(x[0],y[0]);
+ if(n == 1) return g;
+ if(n == 2) return g--(x[1],y[1]);
+
+ if(splinetype == null)
+ splinetype=(x[0] == x[x.length-1] && y[0] == y[y.length-1]) ?
+ periodic : notaknot;
+
+ real[] dy=splinetype(x,y);
+ for(int i=1; i < n; ++i) {
+ pair z=(x[i],y[i]);
+ real dx=x[i]-x[i-1];
+ g=g..controls((x[i-1],y[i-1])+dx*(1,dy[i-1])/3) and (z-dx*(1,dy[i])/3)..z;
+ }
+ return g;
+}
diff --git a/graphics/asymptote/base/grid3.asy b/graphics/asymptote/base/grid3.asy
new file mode 100644
index 0000000000..98e043a71d
--- /dev/null
+++ b/graphics/asymptote/base/grid3.asy
@@ -0,0 +1,412 @@
+// grid3.asy
+// Author: Philippe Ivaldi (Grids in 3D)
+// http://www.piprime.fr/
+// Created: 10 janvier 2007
+
+import graph3;
+
+struct grid3 {
+ path3 axea,axeb;
+ bounds bds;
+ triple dir;
+ valuetime vt;
+ ticklocate locate;
+ void create(picture pic, path3 axea, path3 axeb, path3 axelevel,
+ real min, real max, position pos, autoscaleT t) {
+ real position=pos.position.x;
+ triple level;
+ if(pos.relative) {
+ position=reltime(axelevel,position);
+ level=point(axelevel,position)-point(axelevel,0);
+ } else {
+ triple v=unit(point(axelevel,1)-point(axelevel,0));
+ triple zerolevel=dot(-point(axelevel,0),v)*v;
+ level=zerolevel+position*v;
+ }
+ this.axea=shift(level)*axea;
+ this.axeb=shift(level)*axeb;
+ bds=autoscale(min,max,t.scale);
+ locate=ticklocate(min,max,t,bds.min,bds.max,
+ Dir(point(axeb,0)-point(axea,0)));
+ }
+};
+
+typedef grid3 grid3routine(picture pic);
+
+triple X(picture pic) {return (pic.userMax().x,pic.userMin().y,pic.userMin().z);}
+triple XY(picture pic) {return (pic.userMax().x,pic.userMax().y,pic.userMin().z);}
+triple Y(picture pic) {return (pic.userMin().x,pic.userMax().y,pic.userMin().z);}
+triple YZ(picture pic) {return (pic.userMin().x,pic.userMax().y,pic.userMax().z);}
+triple Z(picture pic) {return (pic.userMin().x,pic.userMin().y,pic.userMax().z);}
+triple ZX(picture pic) {return (pic.userMax().x,pic.userMin().y,pic.userMax().z);}
+
+grid3routine XYgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ triple m=pic.userMin();
+ triple M=pic.userMax();
+ og.create(pic,m--X(pic),Y(pic)--XY(pic),m--Z(pic),
+ m.x,M.x,pos,pic.scale.x);
+ return og;
+ };
+};
+grid3routine XYgrid=XYgrid();
+
+grid3routine YXgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ triple m=pic.userMin();
+ triple M=pic.userMax();
+ og.create(pic,m--Y(pic),X(pic)--XY(pic),m--Z(pic),
+ m.y,M.y,pos,pic.scale.y);
+ return og;
+ };
+};
+grid3routine YXgrid=YXgrid();
+
+
+grid3routine XZgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ triple m=pic.userMin();
+ triple M=pic.userMax();
+ og.create(pic,m--X(pic),Z(pic)--ZX(pic),m--Y(pic),
+ m.x,M.x,pos,pic.scale.x);
+ return og;
+ };
+};
+grid3routine XZgrid=XZgrid();
+
+grid3routine ZXgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ triple m=pic.userMin();
+ triple M=pic.userMax();
+ og.create(pic,m--Z(pic),X(pic)--ZX(pic),m--Y(pic),
+ m.z,M.z,pos,pic.scale.z);
+ return og;
+ };
+};
+grid3routine ZXgrid=ZXgrid();
+
+grid3routine YZgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ triple m=pic.userMin();
+ triple M=pic.userMax();
+ og.create(pic,m--Y(pic),Z(pic)--YZ(pic),m--X(pic),
+ m.y,M.y,pos,pic.scale.y);
+ return og;
+ };
+};
+grid3routine YZgrid=YZgrid();
+
+grid3routine ZYgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ triple m=pic.userMin();
+ triple M=pic.userMax();
+ og.create(pic,m--Z(pic),Y(pic)--YZ(pic),m--X(pic),
+ m.z,M.z,pos,pic.scale.z);
+ return og;
+ };
+};
+grid3routine ZYgrid=ZYgrid();
+
+typedef grid3routine grid3routines[] ;
+
+grid3routines XYXgrid(position pos=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {XYgrid(pos),YXgrid(pos)};
+ return ogs;
+};
+grid3routines XYXgrid=XYXgrid();
+grid3routines YXYgrid(position pos=Relative(0)) {return XYXgrid(pos);};
+grid3routines YXYgrid=XYXgrid();
+
+grid3routines ZXZgrid(position pos=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {ZXgrid(pos),XZgrid(pos)};
+ return ogs;
+};
+grid3routines ZXZgrid=ZXZgrid();
+grid3routines XZXgrid(position pos=Relative(0)) {return ZXZgrid(pos);};
+grid3routines XZXgrid=XZXgrid();
+
+grid3routines ZYZgrid(position pos=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {ZYgrid(pos),YZgrid(pos)};
+ return ogs;
+};
+grid3routines ZYZgrid=ZYZgrid();
+grid3routines YZYgrid(position pos=Relative(0)) {return ZYZgrid(pos);};
+grid3routines YZYgrid=YZYgrid();
+
+grid3routines XY_XZgrid(position posa=Relative(0), position posb=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {XYgrid(posa),XZgrid(posb)};
+ return ogs;
+};
+grid3routines XY_XZgrid=XY_XZgrid();
+
+grid3routines YX_YZgrid(position posa=Relative(0), position posb=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {YXgrid(posa),YZgrid(posb)};
+ return ogs;
+};
+grid3routines YX_YZgrid=YX_YZgrid();
+
+grid3routines ZX_ZYgrid(position posa=Relative(0), position posb=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {ZXgrid(posa),ZYgrid(posb)};
+ return ogs;
+};
+grid3routines ZX_ZYgrid=ZX_ZYgrid();
+
+typedef grid3routines[] grid3routinetype;
+
+grid3routinetype XYZgrid(position pos=Relative(0))
+{
+ grid3routinetype ogs=new grid3routines[] {YZYgrid(pos),XYXgrid(pos),
+ XZXgrid(pos)};
+ return ogs;
+}
+grid3routinetype XYZgrid=XYZgrid();
+
+grid3routines operator cast(grid3routine gridroutine) {
+ grid3routines og=new grid3routine[] {gridroutine};
+ return og;
+}
+
+grid3routinetype operator cast(grid3routines gridroutine) {
+ grid3routinetype og=new grid3routines[] {gridroutine};
+ return og;
+}
+
+grid3routinetype operator cast(grid3routine gridroutine) {
+ grid3routinetype og=(grid3routinetype)(grid3routines) gridroutine;
+ return og;
+}
+
+void grid3(picture pic=currentpicture,
+ grid3routinetype gridroutine=XYZgrid,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ pen pGrid=grey, pen pgrid=lightgrey,
+ bool above=false)
+{
+ for(int j=0; j < gridroutine.length; ++j) {
+ grid3routines gridroutinej=gridroutine[j];
+ for(int i=0; i < gridroutinej.length; ++i) {
+ grid3 gt=gridroutinej[i](pic);
+ pic.add(new void(picture f, transform3 t, transform3 T, triple, triple) {
+ picture d;
+ ticks3 ticks=Ticks3(1,F="%",ticklabel=null,
+ beginlabel=false,endlabel=false,
+ N=N,n=n,Step=Step,step=step,
+ begin=begin,end=end,
+ Size=0,size=0,extend=true,
+ pTick=pGrid,ptick=pgrid);
+ ticks(d,t,"",gt.axea,gt.axeb,nullpen,None,NoMargin3,gt.locate,
+ gt.bds.divisor,opposite=true,primary=false);
+ add(f,t*T*inverse(t)*d);
+ },above=above);
+ addPath(pic,gt.axea,pGrid);
+ addPath(pic,gt.axeb,pGrid);
+ }
+ }
+}
+
+void grid3(picture pic=currentpicture,
+ grid3routinetype gridroutine,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ pen[] pGrid, pen[] pgrid,
+ bool above=false)
+{
+ if(pGrid.length != gridroutine.length || pgrid.length != gridroutine.length)
+ abort("pen array has different length than grid");
+ for(int i=0; i < gridroutine.length; ++i) {
+ grid3(pic=pic,gridroutine=gridroutine[i],
+ N=N,n=n,Step=Step,step=step,
+ begin=begin,end=end,
+ pGrid=pGrid[i],pgrid=pgrid[i],
+ above=above);
+ }
+}
+
+position top=Relative(1);
+position bottom=Relative(0);
+position middle=Relative(0.5);
+
+// Structure used to communicate ticks and axis settings to grid3 routines.
+struct ticksgridT {
+ ticks3 ticks;
+ // Other arguments of grid3 are define by ticks and axis settings
+ void grid3(picture, bool);
+};
+
+typedef ticksgridT ticksgrid();
+
+
+ticksgrid InOutTicks(Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0,
+ pen pTick=nullpen, pen ptick=nullpen,
+ grid3routinetype gridroutine,
+ pen pGrid=grey, pen pgrid=lightgrey)
+{
+ return new ticksgridT()
+ {
+ ticksgridT otg;
+ otg.ticks=Ticks3(0,F,ticklabel,beginlabel,endlabel,
+ N,n,Step,step,begin,end,
+ Size,size,false,pTick,ptick);
+ otg.grid3=new void(picture pic, bool above) {
+ grid3(pic,gridroutine,N,n,Step,step,begin,end,pGrid,pgrid,above);
+ };
+ return otg;
+ };
+}
+
+ticksgrid InTicks(Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0,
+ pen pTick=nullpen, pen ptick=nullpen,
+ grid3routinetype gridroutine,
+ pen pGrid=grey, pen pgrid=lightgrey)
+{
+ return new ticksgridT()
+ {
+ ticksgridT otg;
+ otg.ticks=Ticks3(-1,F,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,Size,size,false,pTick,ptick);
+ otg.grid3=new void(picture pic, bool above) {
+ grid3(pic,gridroutine,N,n,Step,step,begin,end,pGrid,pgrid,above);
+ };
+ return otg;
+ };
+}
+
+ticksgrid OutTicks(Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0,
+ pen pTick=nullpen, pen ptick=nullpen,
+ grid3routinetype gridroutine,
+ pen pGrid=grey, pen pgrid=lightgrey)
+{
+ return new ticksgridT()
+ {
+ ticksgridT otg;
+ otg.ticks=Ticks3(1,F,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,Size,size,false,pTick,ptick);
+ otg.grid3=new void(picture pic, bool above) {
+ grid3(pic,gridroutine,N,n,Step,step,begin,end,pGrid,pgrid,above);
+ };
+ return otg;
+ };
+}
+
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ pen p=currentpen, ticksgrid ticks,
+ arrowbar3 arrow=None, bool above=false)
+{
+ xaxis3(pic,L,axis,p,ticks().ticks,arrow,above);
+ ticks().grid3(pic,above);
+}
+
+void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero,
+ pen p=currentpen, ticksgrid ticks,
+ arrowbar3 arrow=None, bool above=false)
+{
+ yaxis3(pic,L,axis,p,ticks().ticks,arrow,above);
+ ticks().grid3(pic,above);
+}
+
+void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero,
+ pen p=currentpen, ticksgrid ticks,
+ arrowbar3 arrow=None, bool above=false)
+{
+ zaxis3(pic,L,axis,p,ticks().ticks,arrow,above);
+ ticks().grid3(pic,above);
+}
+
+/* Example:
+
+ import grid3;
+
+ size(8cm,0);
+ currentprojection=orthographic(0.5,1,0.5);
+
+ defaultpen(overwrite(SuppressQuiet));
+
+ scale(Linear, Linear, Log);
+
+ grid3(pic=currentpicture, // picture
+ gridroutine=XYZgrid(// grid3routine
+ // or grid3routine[] (alias grid3routines)
+ // or grid3routines[]:
+ // The routine(s) to draw the grid(s):
+ // *XYgrid: draw grid from X in direction of Y
+ // *YXgrid: draw grid from Y in direction of X, ...
+ // *An array of previous values XYgrid, YXgrid, ...
+ // *XYXgrid: draw XYgrid and YXgrid grids
+ // *YXYgrid: draw XYgrid and YXgrid grids
+ // *ZXZgrid: draw ZXgrid and XZgrid grids
+ // *YX_YZgrid: draw YXgrid and YZgrid grids
+ // *XY_XZgrid: draw XYgrid and XZgrid grids
+ // *YX_YZgrid: draw YXgrid and YZgrid grids
+ // *An array of previous values XYXgrid,...
+ // *XYZgrid: draw XYXgrid, ZYZgrid, XZXgrid grids.
+ pos=Relative(0)),
+ // the position of the grid relative to the axis
+ // perpendicular to the grid; a real number
+ // specifies a coordinate relative to this axis.
+ // Aliases: top=Relative(1), middle=Relative(0.5)
+ // and bottom=Relative(0).
+
+ // These arguments are similar to those of InOutTicks():
+ N=0, // int
+ n=0, // int
+ Step=0, // real
+ step=0, // real
+ begin=true, // bool
+ end=true, // bool
+ pGrid=grey, // pen
+ pgrid=lightgrey, // pen
+ above=false // bool
+ );
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks());
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+*/
+
+/* Other examples:
+
+ int N=10, n=2;
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks(N=N,n=n));
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+ grid3(N=N,n=n);
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks());
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+ grid3(new grid3routines[] {XYXgrid(top),XZXgrid(0)});
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks());
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+ grid3(new grid3routines[] {XYXgrid(-0.5),XYXgrid(1.5)},
+ pGrid=new pen[] {red,blue},
+ pgrid=new pen[] {0.5red,0.5blue});
+
+ // Axes with grids:
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),
+ OutTicks(Step=0.5,gridroutine=XYgrid));
+ yaxis3(Label("$y$",position=EndPoint,align=S),
+ InOutTicks(Label("",align=0.5X),N=8,n=2,gridroutine=YX_YZgrid));
+ zaxis3("$z$",OutTicks(ZYgrid));
+*/
diff --git a/graphics/asymptote/base/interpolate.asy b/graphics/asymptote/base/interpolate.asy
new file mode 100644
index 0000000000..a600c94c12
--- /dev/null
+++ b/graphics/asymptote/base/interpolate.asy
@@ -0,0 +1,140 @@
+// Lagrange and Hermite interpolation in Asymptote
+// Author: Olivier Guibé
+// Acknowledgements: Philippe Ivaldi
+
+// diffdiv(x,y) computes Newton's Divided Difference for
+// Lagrange interpolation with distinct values {x_0,..,x_n} in the array x
+// and values y_0,...,y_n in the array y,
+
+// hdiffdiv(x,y,dyp) computes Newton's Divided Difference for
+// Hermite interpolation where dyp={dy_0,...,dy_n}.
+//
+// fhorner(x,coeff) uses Horner's rule to compute the polynomial
+// a_0+a_1(x-x_0)+a_2(x-x_0)(x-x_1)+...+a_n(x-x_0)..(x-x_{n-1}),
+// where coeff={a_0,a_1,...,a_n}.
+
+// fspline does standard cubic spline interpolation of a function f
+// on the interval [a,b].
+// The points a=x_1 < x_2 < .. < x_n=b form the array x;
+// the points y_1=f(x_1),....,y_n=f(x_n) form the array y
+// We use the Hermite form for the spline.
+
+// The syntax is:
+// s=fspline(x,y); default not_a_knot condition
+// s=fspline(x,y,natural); natural spline
+// s=fspline(x,y,periodic); periodic spline
+// s=fspline(x,y,clamped(1,1)); clamped spline
+// s=fspline(x,y,monotonic); piecewise monotonic spline
+
+// Here s is a real function that is constant on (-infinity,a] and [b,infinity).
+
+private import math;
+import graph_splinetype;
+
+typedef real fhorner(real);
+
+struct horner {
+ // x={x0,..,xn}(not necessarily distinct)
+ // a={a0,..,an} corresponds to the polyonmial
+ // a_0+a_1(x-x_0)+a_2(x-x_0)(x-x_1)+...+a_n(x-x_0)..(x-x_{n-1}),
+ real[] x;
+ real[] a;
+}
+
+// Evaluate p(x)=d0+(x-x0)(d1+(x-x1)+...+(d(n-1)+(x-x(n-1))*dn)))
+// via Horner's rule: n-1 multiplications, 2n-2 additions.
+fhorner fhorner(horner sh)
+{
+ int n=sh.x.length;
+ checklengths(n,sh.a.length);
+ return new real(real x) {
+ real s=sh.a[n-1];
+ for(int k=n-2; k >= 0; --k)
+ s=sh.a[k]+(x-sh.x[k])*s;
+ return s;
+ };
+}
+
+// Newton's Divided Difference method: n(n-1)/2 divisions, n(n-1) additions.
+horner diffdiv(real[] x, real[] y)
+{
+ int n=x.length;
+ horner s;
+ checklengths(n,y.length);
+ for(int i=0; i < n; ++i)
+ s.a[i]=y[i];
+ for(int k=0; k < n-1; ++k) {
+ for(int i=n-1; i > k; --i) {
+ s.a[i]=(s.a[i]-s.a[i-1])/(x[i]-x[i-k-1]);
+ }
+ }
+ s.x=x;
+ return s;
+}
+
+// Newton's Divided Difference for simple Hermite interpolation,
+// where one specifies both p(x_i) and p'(x_i).
+horner hdiffdiv(real[] x, real[] y, real[] dy)
+{
+ int n=x.length;
+ horner s;
+ checklengths(n,y.length);
+ checklengths(n,dy.length);
+ for(int i=0; i < n; ++i) {
+ s.a[2*i]=y[i];
+ s.a[2*i+1]=dy[i];
+ s.x[2*i]=x[i];
+ s.x[2*i+1]=x[i];
+ }
+
+ for(int i=n-1; i > 0; --i)
+ s.a[2*i]=(s.a[2*i]-s.a[2*i-2])/(x[i]-x[i-1]);
+
+ int stop=2*n-1;
+ for(int k=1; k < stop; ++k) {
+ for(int i=stop; i > k; --i) {
+ s.a[i]=(s.a[i]-s.a[i-1])/(s.x[i]-s.x[i-k-1]);
+ }
+ }
+ return s;
+}
+
+typedef real realfunction(real);
+
+// piecewise Hermite interpolation:
+// return the piecewise polynomial p(x), where on [x_i,x_i+1], deg(p) <= 3,
+// p(x_i)=y_i, p(x_{i+1})=y_i+1, p'(x_i)=dy_i, and p'(x_{i+1})=dy_i+1.
+// Outside [x_1,x_n] the returned function is constant: y_1 on (infinity,x_1]
+// and y_n on [x_n,infinity).
+realfunction pwhermite(real[] x, real[] y, real[] dy)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,dy.length);
+ if(n < 2) abort(morepoints);
+ if(!increasing(x,strict=true)) abort("array x is not strictly increasing");
+ return new real(real t) {
+ int i=search(x,t);
+ if(i == n-1) {
+ i=n-2;
+ t=x[n-1];
+ } else if(i == -1) {
+ i=0;
+ t=x[0];
+ }
+ real h=x[i+1]-x[i];
+ real delta=(y[i+1]-y[i])/h;
+ real e=(3*delta-2*dy[i]-dy[i+1])/h;
+ real f=(dy[i]-2*delta+dy[i+1])/h^2;
+ real s=t-x[i];
+ return y[i]+s*(dy[i]+s*(e+s*f));
+ };
+}
+
+realfunction fspline(real[] x, real[] y, splinetype splinetype=notaknot)
+{
+ real[] dy=splinetype(x,y);
+ return new real(real t) {
+ return pwhermite(x,y,dy)(t);
+ };
+}
diff --git a/graphics/asymptote/base/labelpath.asy b/graphics/asymptote/base/labelpath.asy
new file mode 100644
index 0000000000..39c1908efd
--- /dev/null
+++ b/graphics/asymptote/base/labelpath.asy
@@ -0,0 +1,28 @@
+usepackage("pstricks");
+usepackage("pst-text");
+
+string LeftJustified="l";
+string RightJustified="r";
+string Centered="c";
+
+void labelpath(frame f, Label L, path g, string justify=Centered,
+ pen p=currentpen)
+{
+ if(latex() && !pdf()) {
+ _labelpath(f,L.s,L.size,g,justify,(L.T.x,L.T.y+0.5linewidth(p)),p);
+ return;
+ }
+ warning("labelpathlatex","labelpath requires -tex latex");
+}
+
+void labelpath(picture pic=currentpicture, Label L, path g,
+ string justify=Centered, pen p=currentpen)
+{
+ pic.add(new void(frame f, transform t) {
+ labelpath(f,L,t*g,justify,p);
+ });
+ frame f;
+ label(f,Label(L.s,L.size));
+ real w=size(f).y+L.T.y+0.5linewidth(p);
+ pic.addBox(min(g),max(g),-w,w);
+}
diff --git a/graphics/asymptote/base/labelpath3.asy b/graphics/asymptote/base/labelpath3.asy
new file mode 100644
index 0000000000..63b2290f1f
--- /dev/null
+++ b/graphics/asymptote/base/labelpath3.asy
@@ -0,0 +1,83 @@
+// Fit a label to a path3.
+// Author: Jens Schwaiger
+
+import three;
+private real eps=100*realEpsilon;
+
+triple nextnormal(triple p, triple q)
+{
+ triple nw=p-(dot(p,q)*q);
+ return abs(nw) < 0.0001 ? p : unit(nw);
+}
+
+triple[] firstframe(path3 p, triple optional=O)
+{
+ triple[] start=new triple[3];
+ start[0]=dir(p,reltime(p,0));
+ start[1]=(abs(cross(start[0],optional)) < eps) ? perp(start[0]) :
+ unit(cross(start[0],optional));
+ start[2]=cross(start[0],start[1]);
+ return start;
+}
+
+// Modification of the bishop frame construction contained in
+// space_tube.asy (from Philippe Ivaldi's modules).
+// For noncyclic path3s only
+triple[] nextframe(path3 p, real reltimestart, triple[] start, real
+ reltimeend, int subdiv=20)
+{
+ triple[][] bf=new triple[subdiv+1][3];
+ real lg=reltimeend-reltimestart;
+ if(lg <= 0) return start;
+ bf[0]=start;
+ int n=subdiv+1;
+ for(int i=1; i < n; ++i)
+ bf[i][0]=dir(p,reltime(p,reltimestart+(i/subdiv)*lg));
+
+ for(int i=1; i < n; ++i) {
+ bf[i][1]=nextnormal(bf[i-1][1],bf[i][0]);
+ bf[i][2]=cross(bf[i][0],bf[i][1]);
+ }
+ return bf[subdiv];
+}
+
+surface labelpath(string s, path3 p, real angle=90, triple optional=O)
+{
+ real Cos=Cos(angle);
+ real Sin=Sin(angle);
+ path[] text=texpath(Label(s,(0,0),Align,basealign));
+ text=scale(1/(max(text).x-min(text).x))*text;
+ path[][] decompose=containmentTree(text);
+
+ real[][] xpos=new real[decompose.length][2];
+ surface sf;
+ for(int i=0; i < decompose.length; ++i) {// Identify positions along x-axis
+ xpos[i][1]=i;
+ real pos0=0.5(max(decompose[i]).x+min(decompose[i]).x);
+ xpos[i][0]=pos0;
+ }
+ xpos=sort(xpos); // sort by distance from 0;
+ triple[] pos=new triple[decompose.length];
+ real lg=arclength(p);
+ //create frames;
+ triple[] first=firstframe(p,optional);
+ triple[] t0=first;
+ real tm0=0;
+ triple[][] bfr=new triple[decompose.length][3];
+ for(int j=0; j < decompose.length; ++j) {
+ bfr[j]=nextframe(p,tm0,t0,xpos[j][0]);
+ tm0=xpos[j][0]; t0=bfr[j];
+ }
+ transform3[] mt=new transform3[bfr.length];
+ for(int j=0; j < bfr.length; ++j) {
+ triple f2=Cos*bfr[j][1]+Sin*bfr[j][2];
+ triple f3=Sin*bfr[j][1]+Cos*bfr[j][2];
+ mt[j]=shift(relpoint(p,xpos[j][0]))*transform3(bfr[j][0],f2,f3);
+ }
+ for(int j=0; j < bfr.length; ++j) {
+ path[] dc=decompose[(int) xpos[j][1]];
+ pair pos0=(0.5(max(dc).x+min(dc).x),0);
+ sf.append(mt[j]*surface(scale(lg)*shift(-pos0)*dc));
+ }
+ return sf;
+}
diff --git a/graphics/asymptote/base/latin1.asy b/graphics/asymptote/base/latin1.asy
new file mode 100644
index 0000000000..3d76925be2
--- /dev/null
+++ b/graphics/asymptote/base/latin1.asy
@@ -0,0 +1,2 @@
+usepackage("fontenc","T1");
+usepackage("inputenc","latin1");
diff --git a/graphics/asymptote/base/lmfit.asy b/graphics/asymptote/base/lmfit.asy
new file mode 100644
index 0000000000..c3dfddce06
--- /dev/null
+++ b/graphics/asymptote/base/lmfit.asy
@@ -0,0 +1,881 @@
+/*
+ Copyright (c) 2009 Philipp Stephani
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ 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 AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+/*
+ Fitting $n$ data points $(x_1, y_1 \pm \Delta y_1), \dots, (x_n, y_n \pm \Delta y_n)$
+ to a function $f$ that depends on $m$ parameters $a_1, \dots, a_m$ means minimizing
+ the least-squares sum
+ %
+ \begin{equation*}
+ \sum_{i = 1}^n \left( \frac{y_i - f(a_1, \dots, a_m; x_i)}{\Delta y_i} \right)^2
+ \end{equation*}
+ %
+ with respect to the parameters $a_1, \dots, a_m$.
+*/
+
+/*
+ This module provides an implementation of the Levenberg--Marquardt
+ (LM) algorithm, converted from the C lmfit routine by Joachim Wuttke
+ (see http://www.messen-und-deuten.de/lmfit/).
+
+ Implementation strategy: Fortunately, Asymptote's syntax is very
+ similar to C, and the original code cleanly separates the
+ customizable parts (user-provided data, output routines, etc.) from
+ the dirty number crunching. Thus, mst of the code was just copied
+ and slightly modified from the original source files. I have
+ amended the lm_data_type structure and the callback routines with a
+ weight array that can be used to provide experimental errors. I
+ have also created two simple wrapper functions.
+*/
+
+
+// copied from the C code
+private real LM_MACHEP = realEpsilon;
+private real LM_DWARF = realMin;
+private real LM_SQRT_DWARF = sqrt(realMin);
+private real LM_SQRT_GIANT = sqrt(realMax);
+private real LM_USERTOL = 30 * LM_MACHEP;
+
+restricted string lm_infmsg[] = {
+ "improper input parameters",
+ "the relative error in the sum of squares is at most tol",
+ "the relative error between x and the solution is at most tol",
+ "both errors are at most tol",
+ "fvec is orthogonal to the columns of the jacobian to machine precision",
+ "number of calls to fcn has reached or exceeded maxcall*(n+1)",
+ "ftol is too small: no further reduction in the sum of squares is possible",
+ "xtol too small: no further improvement in approximate solution x possible",
+ "gtol too small: no further improvement in approximate solution x possible",
+ "not enough memory",
+ "break requested within function evaluation"
+};
+
+restricted string lm_shortmsg[] = {
+ "invalid input",
+ "success (f)",
+ "success (p)",
+ "success (f,p)",
+ "degenerate",
+ "call limit",
+ "failed (f)",
+ "failed (p)",
+ "failed (o)",
+ "no memory",
+ "user break"
+};
+
+
+// copied from the C code and amended with the weight (user_w) array
+struct lm_data_type {
+ real[] user_t;
+ real[] user_y;
+ real[] user_w;
+ real user_func(real user_t_point, real[] par);
+};
+
+
+// Asymptote has no pointer support, so we need reference wrappers for
+// the int and real types
+struct lm_int_type {
+ int val;
+
+ void operator init(int val) {
+ this.val = val;
+ }
+};
+
+
+struct lm_real_type {
+ real val;
+
+ void operator init(real val) {
+ this.val = val;
+ }
+};
+
+
+// copied from the C code; the lm_initialize_control function turned
+// into a constructor
+struct lm_control_type {
+ real ftol;
+ real xtol;
+ real gtol;
+ real epsilon;
+ real stepbound;
+ real fnorm;
+ int maxcall;
+ lm_int_type nfev;
+ lm_int_type info;
+
+ void operator init() {
+ maxcall = 100;
+ epsilon = LM_USERTOL;
+ stepbound = 100;
+ ftol = LM_USERTOL;
+ xtol = LM_USERTOL;
+ gtol = LM_USERTOL;
+ }
+};
+
+
+// copied from the C code
+typedef void lm_evaluate_ftype(real[] par, int m_dat, real[] fvec, lm_data_type data, lm_int_type info);
+typedef void lm_print_ftype(int n_par, real[] par, int m_dat, real[] fvec, lm_data_type data, int iflag, int iter, int nfev);
+
+
+// copied from the C code
+private real SQR(real x) {
+ return x * x;
+}
+
+
+// Asymptote doesn't support pointers to arbitrary array elements, so
+// we provide an offset parameter.
+private real lm_enorm(int n, real[] x, int offset=0) {
+ real s1 = 0;
+ real s2 = 0;
+ real s3 = 0;
+ real x1max = 0;
+ real x3max = 0;
+ real agiant = LM_SQRT_GIANT / n;
+ real xabs, temp;
+
+ for (int i = 0; i < n; ++i) {
+ xabs = fabs(x[offset + i]);
+ if (xabs > LM_SQRT_DWARF && xabs < agiant) {
+ s2 += SQR(xabs);
+ continue;
+ }
+
+ if (xabs > LM_SQRT_DWARF) {
+ if (xabs > x1max) {
+ temp = x1max / xabs;
+ s1 = 1 + s1 * SQR(temp);
+ x1max = xabs;
+ } else {
+ temp = xabs / x1max;
+ s1 += SQR(temp);
+ }
+ continue;
+ }
+ if (xabs > x3max) {
+ temp = x3max / xabs;
+ s3 = 1 + s3 * SQR(temp);
+ x3max = xabs;
+ } else {
+ if (xabs != 0.0) {
+ temp = xabs / x3max;
+ s3 += SQR(temp);
+ }
+ }
+ }
+
+ if (s1 != 0)
+ return x1max * sqrt(s1 + (s2 / x1max) / x1max);
+ if (s2 != 0) {
+ if (s2 >= x3max)
+ return sqrt(s2 * (1 + (x3max / s2) * (x3max * s3)));
+ else
+ return sqrt(x3max * ((s2 / x3max) + (x3max * s3)));
+ }
+
+ return x3max * sqrt(s3);
+}
+
+
+// This function calculated the vector whose square sum is to be
+// minimized. We use a slight modification of the original code that
+// includes the weight factor. The user may provide different
+// customizations.
+void lm_evaluate_default(real[] par, int m_dat, real[] fvec, lm_data_type data, lm_int_type info) {
+ for (int i = 0; i < m_dat; ++i) {
+ fvec[i] = data.user_w[i] * (data.user_y[i] - data.user_func(data.user_t[i], par));
+ }
+}
+
+
+// Helper functions to print padded strings and numbers (until
+// Asymptote provides a real printf function)
+private string pad(string str, int count, string pad=" ") {
+ string res = str;
+ while (length(res) < count)
+ res = pad + res;
+ return res;
+}
+
+
+private string pad(int num, int digits, string pad=" ") {
+ return pad(string(num), digits, pad);
+}
+
+
+private string pad(real num, int digits, string pad=" ") {
+ return pad(string(num), digits, pad);
+}
+
+
+// Similar to the C code, also prints weights
+void lm_print_default(int n_par, real[] par, int m_dat, real[] fvec, lm_data_type data, int iflag, int iter, int nfev) {
+ real f, y, t, w;
+ int i;
+
+ if (iflag == 2) {
+ write("trying step in gradient direction");
+ } else if (iflag == 1) {
+ write(format("determining gradient (iteration %d)", iter));
+ } else if (iflag == 0) {
+ write("starting minimization");
+ } else if (iflag == -1) {
+ write(format("terminated after %d evaluations", nfev));
+ }
+
+ write(" par: ", none);
+ for (i = 0; i < n_par; ++i) {
+ write(" " + pad(par[i], 12), none);
+ }
+ write(" => norm: " + pad(lm_enorm(m_dat, fvec), 12));
+
+ if (iflag == -1) {
+ write(" fitting data as follows:");
+ for (i = 0; i < m_dat; ++i) {
+ t = data.user_t[i];
+ y = data.user_y[i];
+ w = data.user_w[i];
+ f = data.user_func(t, par);
+ write(format(" t[%2d]=", i) + pad(t, 12) + " y=" + pad(y, 12) + " w=" + pad(w, 12) + " fit=" + pad(f, 12) + " residue=" + pad(y - f, 12));
+ }
+ }
+}
+
+
+// Prints nothing
+void lm_print_quiet(int n_par, real[] par, int m_dat, real[] fvec, lm_data_type data, int iflag, int iter, int nfev) {
+}
+
+
+// copied from the C code
+private void lm_qrfac(int m, int n, real[] a, bool pivot, int[] ipvt, real[] rdiag, real[] acnorm, real[] wa) {
+ int i, j, k, kmax, minmn;
+ real ajnorm, sum, temp;
+ static real p05 = 0.05;
+
+ for (j = 0; j < n; ++j) {
+ acnorm[j] = lm_enorm(m, a, j * m);
+ rdiag[j] = acnorm[j];
+ wa[j] = rdiag[j];
+ if (pivot)
+ ipvt[j] = j;
+ }
+
+ minmn = min(m, n);
+ for (j = 0; j < minmn; ++j) {
+ while (pivot) {
+ kmax = j;
+ for (k = j + 1; k < n; ++k)
+ if (rdiag[k] > rdiag[kmax])
+ kmax = k;
+ if (kmax == j)
+ break;
+
+ for (i = 0; i < m; ++i) {
+ temp = a[j * m + i];
+ a[j * m + i] = a[kmax * m + i];
+ a[kmax * m + i] = temp;
+ }
+ rdiag[kmax] = rdiag[j];
+ wa[kmax] = wa[j];
+ k = ipvt[j];
+ ipvt[j] = ipvt[kmax];
+ ipvt[kmax] = k;
+
+ break;
+ }
+
+ ajnorm = lm_enorm(m - j, a, j * m + j);
+ if (ajnorm == 0.0) {
+ rdiag[j] = 0;
+ continue;
+ }
+
+ if (a[j * m + j] < 0.0)
+ ajnorm = -ajnorm;
+ for (i = j; i < m; ++i)
+ a[j * m + i] /= ajnorm;
+ a[j * m + j] += 1;
+
+ for (k = j + 1; k < n; ++k) {
+ sum = 0;
+
+ for (i = j; i < m; ++i)
+ sum += a[j * m + i] * a[k * m + i];
+
+ temp = sum / a[j + m * j];
+
+ for (i = j; i < m; ++i)
+ a[k * m + i] -= temp * a[j * m + i];
+
+ if (pivot && rdiag[k] != 0.0) {
+ temp = a[m * k + j] / rdiag[k];
+ temp = max(0.0, 1 - SQR(temp));
+ rdiag[k] *= sqrt(temp);
+ temp = rdiag[k] / wa[k];
+ if (p05 * SQR(temp) <= LM_MACHEP) {
+ rdiag[k] = lm_enorm(m - j - 1, a, m * k + j + 1);
+ wa[k] = rdiag[k];
+ }
+ }
+ }
+
+ rdiag[j] = -ajnorm;
+ }
+}
+
+
+// copied from the C code
+private void lm_qrsolv(int n, real[] r, int ldr, int[] ipvt, real[] diag, real[] qtb, real[] x, real[] sdiag, real[] wa) {
+ static real p25 = 0.25;
+ static real p5 = 0.5;
+
+ int i, kk, j, k, nsing;
+ real qtbpj, sum, temp;
+ real _sin, _cos, _tan, _cot;
+
+ for (j = 0; j < n; ++j) {
+ for (i = j; i < n; ++i)
+ r[j * ldr + i] = r[i * ldr + j];
+ x[j] = r[j * ldr + j];
+ wa[j] = qtb[j];
+ }
+
+ for (j = 0; j < n; ++j) {
+ while (diag[ipvt[j]] != 0.0) {
+ for (k = j; k < n; ++k)
+ sdiag[k] = 0.0;
+ sdiag[j] = diag[ipvt[j]];
+
+ qtbpj = 0.;
+ for (k = j; k < n; ++k) {
+ if (sdiag[k] == 0.)
+ continue;
+ kk = k + ldr * k;
+ if (fabs(r[kk]) < fabs(sdiag[k])) {
+ _cot = r[kk] / sdiag[k];
+ _sin = p5 / sqrt(p25 + p25 * _cot * _cot);
+ _cos = _sin * _cot;
+ } else {
+ _tan = sdiag[k] / r[kk];
+ _cos = p5 / sqrt(p25 + p25 * _tan * _tan);
+ _sin = _cos * _tan;
+ }
+
+ r[kk] = _cos * r[kk] + _sin * sdiag[k];
+ temp = _cos * wa[k] + _sin * qtbpj;
+ qtbpj = -_sin * wa[k] + _cos * qtbpj;
+ wa[k] = temp;
+
+ for (i = k + 1; i < n; ++i) {
+ temp = _cos * r[k * ldr + i] + _sin * sdiag[i];
+ sdiag[i] = -_sin * r[k * ldr + i] + _cos * sdiag[i];
+ r[k * ldr + i] = temp;
+ }
+ }
+ break;
+ }
+
+ sdiag[j] = r[j * ldr + j];
+ r[j * ldr + j] = x[j];
+ }
+
+ nsing = n;
+ for (j = 0; j < n; ++j) {
+ if (sdiag[j] == 0.0 && nsing == n)
+ nsing = j;
+ if (nsing < n)
+ wa[j] = 0;
+ }
+
+ for (j = nsing - 1; j >= 0; --j) {
+ sum = 0;
+ for (i = j + 1; i < nsing; ++i)
+ sum += r[j * ldr + i] * wa[i];
+ wa[j] = (wa[j] - sum) / sdiag[j];
+ }
+
+ for (j = 0; j < n; ++j)
+ x[ipvt[j]] = wa[j];
+}
+
+
+// copied from the C code
+private void lm_lmpar(int n, real[] r, int ldr, int[] ipvt, real[] diag, real[] qtb, real delta, lm_real_type par, real[] x, real[] sdiag, real[] wa1, real[] wa2) {
+ static real p1 = 0.1;
+ static real p001 = 0.001;
+
+ int nsing = n;
+ real parl = 0.0;
+
+ int i, iter, j;
+ real dxnorm, fp, fp_old, gnorm, parc, paru;
+ real sum, temp;
+
+ for (j = 0; j < n; ++j) {
+ wa1[j] = qtb[j];
+ if (r[j * ldr + j] == 0 && nsing == n)
+ nsing = j;
+ if (nsing < n)
+ wa1[j] = 0;
+ }
+ for (j = nsing - 1; j >= 0; --j) {
+ wa1[j] = wa1[j] / r[j + ldr * j];
+ temp = wa1[j];
+ for (i = 0; i < j; ++i)
+ wa1[i] -= r[j * ldr + i] * temp;
+ }
+
+ for (j = 0; j < n; ++j)
+ x[ipvt[j]] = wa1[j];
+
+ iter = 0;
+ for (j = 0; j < n; ++j)
+ wa2[j] = diag[j] * x[j];
+ dxnorm = lm_enorm(n, wa2);
+ fp = dxnorm - delta;
+ if (fp <= p1 * delta) {
+ par.val = 0;
+ return;
+ }
+
+ if (nsing >= n) {
+ for (j = 0; j < n; ++j)
+ wa1[j] = diag[ipvt[j]] * wa2[ipvt[j]] / dxnorm;
+
+ for (j = 0; j < n; ++j) {
+ sum = 0.0;
+ for (i = 0; i < j; ++i)
+ sum += r[j * ldr + i] * wa1[i];
+ wa1[j] = (wa1[j] - sum) / r[j + ldr * j];
+ }
+ temp = lm_enorm(n, wa1);
+ parl = fp / delta / temp / temp;
+ }
+
+ for (j = 0; j < n; ++j) {
+ sum = 0;
+ for (i = 0; i <= j; ++i)
+ sum += r[j * ldr + i] * qtb[i];
+ wa1[j] = sum / diag[ipvt[j]];
+ }
+ gnorm = lm_enorm(n, wa1);
+ paru = gnorm / delta;
+ if (paru == 0.0)
+ paru = LM_DWARF / min(delta, p1);
+
+ par.val = max(par.val, parl);
+ par.val = min(par.val, paru);
+ if (par.val == 0.0)
+ par.val = gnorm / dxnorm;
+
+ for (;; ++iter) {
+ if (par.val == 0.0)
+ par.val = max(LM_DWARF, p001 * paru);
+ temp = sqrt(par.val);
+ for (j = 0; j < n; ++j)
+ wa1[j] = temp * diag[j];
+ lm_qrsolv(n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2);
+ for (j = 0; j < n; ++j)
+ wa2[j] = diag[j] * x[j];
+ dxnorm = lm_enorm(n, wa2);
+ fp_old = fp;
+ fp = dxnorm - delta;
+
+ if (fabs(fp) <= p1 * delta || (parl == 0.0 && fp <= fp_old && fp_old < 0.0) || iter == 10)
+ break;
+
+ for (j = 0; j < n; ++j)
+ wa1[j] = diag[ipvt[j]] * wa2[ipvt[j]] / dxnorm;
+
+ for (j = 0; j < n; ++j) {
+ wa1[j] = wa1[j] / sdiag[j];
+ for (i = j + 1; i < n; ++i)
+ wa1[i] -= r[j * ldr + i] * wa1[j];
+ }
+ temp = lm_enorm(n, wa1);
+ parc = fp / delta / temp / temp;
+
+ if (fp > 0)
+ parl = max(parl, par.val);
+ else if (fp < 0)
+ paru = min(paru, par.val);
+
+ par.val = max(parl, par.val + parc);
+ }
+}
+
+
+// copied from the C code; the main function
+void lm_lmdif(int m, int n, real[] x, real[] fvec, real ftol, real xtol, real gtol, int maxfev, real epsfcn, real[] diag, int mode, real factor, lm_int_type info, lm_int_type nfev, real[] fjac, int[] ipvt, real[] qtf, real[] wa1, real[] wa2, real[] wa3, real[] wa4, lm_evaluate_ftype evaluate, lm_print_ftype printout, lm_data_type data) {
+ static real p1 = 0.1;
+ static real p5 = 0.5;
+ static real p25 = 0.25;
+ static real p75 = 0.75;
+ static real p0001 = 1.0e-4;
+
+ nfev.val = 0;
+ int iter = 1;
+ lm_real_type par = lm_real_type(0);
+ real delta = 0;
+ real xnorm = 0;
+ real temp = max(epsfcn, LM_MACHEP);
+ real eps = sqrt(temp);
+ int i, j;
+ real actred, dirder, fnorm, fnorm1, gnorm, pnorm, prered, ratio, step, sum, temp1, temp2, temp3;
+
+ if ((n <= 0) || (m < n) || (ftol < 0.0) || (xtol < 0.0) || (gtol < 0.0) || (maxfev <= 0) || (factor <= 0)) {
+ info.val = 0;
+ return;
+ }
+ if (mode == 2) {
+ for (j = 0; j < n; ++j) {
+ if (diag[j] <= 0.0) {
+ info.val = 0;
+ return;
+ }
+ }
+ }
+
+ info.val = 0;
+ evaluate(x, m, fvec, data, info);
+ if(printout != null) printout(n, x, m, fvec, data, 0, 0, ++nfev.val);
+ if (info.val < 0)
+ return;
+ fnorm = lm_enorm(m, fvec);
+
+ do {
+ for (j = 0; j < n; ++j) {
+ temp = x[j];
+ step = eps * fabs(temp);
+ if (step == 0.0)
+ step = eps;
+ x[j] = temp + step;
+ info.val = 0;
+ evaluate(x, m, wa4, data, info);
+ if(printout != null) printout(n, x, m, wa4, data, 1, iter, ++nfev.val);
+ if (info.val < 0)
+ return;
+ for (i = 0; i < m; ++i)
+ fjac[j * m + i] = (wa4[i] - fvec[i]) / (x[j] - temp);
+ x[j] = temp;
+ }
+
+ lm_qrfac(m, n, fjac, true, ipvt, wa1, wa2, wa3);
+
+ if (iter == 1) {
+ if (mode != 2) {
+ for (j = 0; j < n; ++j) {
+ diag[j] = wa2[j];
+ if (wa2[j] == 0.0)
+ diag[j] = 1.0;
+ }
+ }
+ for (j = 0; j < n; ++j)
+ wa3[j] = diag[j] * x[j];
+ xnorm = lm_enorm(n, wa3);
+ delta = factor * xnorm;
+ if (delta == 0.0)
+ delta = factor;
+ }
+
+ for (i = 0; i < m; ++i)
+ wa4[i] = fvec[i];
+
+ for (j = 0; j < n; ++j) {
+ temp3 = fjac[j * m + j];
+ if (temp3 != 0.0) {
+ sum = 0;
+ for (i = j; i < m; ++i)
+ sum += fjac[j * m + i] * wa4[i];
+ temp = -sum / temp3;
+ for (i = j; i < m; ++i)
+ wa4[i] += fjac[j * m + i] * temp;
+ }
+ fjac[j * m + j] = wa1[j];
+ qtf[j] = wa4[j];
+ }
+
+ gnorm = 0;
+ if (fnorm != 0) {
+ for (j = 0; j < n; ++j) {
+ if (wa2[ipvt[j]] == 0) continue;
+ sum = 0.0;
+ for (i = 0; i <= j; ++i)
+ sum += fjac[j * m + i] * qtf[i] / fnorm;
+ gnorm = max(gnorm, fabs(sum / wa2[ipvt[j]]));
+ }
+ }
+
+ if (gnorm <= gtol) {
+ info.val = 4;
+ return;
+ }
+
+ if (mode != 2) {
+ for (j = 0; j < n; ++j)
+ diag[j] = max(diag[j], wa2[j]);
+ }
+
+ do {
+ lm_lmpar(n, fjac, m, ipvt, diag, qtf, delta, par, wa1, wa2, wa3, wa4);
+
+ for (j = 0; j < n; ++j) {
+ wa1[j] = -wa1[j];
+ wa2[j] = x[j] + wa1[j];
+ wa3[j] = diag[j] * wa1[j];
+ }
+ pnorm = lm_enorm(n, wa3);
+
+ if (nfev.val <= 1 + n)
+ delta = min(delta, pnorm);
+
+ info.val = 0;
+ evaluate(wa2, m, wa4, data, info);
+ if(printout != null) printout(n, x, m, wa4, data, 2, iter, ++nfev.val);
+ if (info.val < 0)
+ return;
+
+ fnorm1 = lm_enorm(m, wa4);
+
+ if (p1 * fnorm1 < fnorm)
+ actred = 1 - SQR(fnorm1 / fnorm);
+ else
+ actred = -1;
+
+ for (j = 0; j < n; ++j) {
+ wa3[j] = 0;
+ for (i = 0; i <= j; ++i)
+ wa3[i] += fjac[j * m + i] * wa1[ipvt[j]];
+ }
+ temp1 = lm_enorm(n, wa3) / fnorm;
+ temp2 = sqrt(par.val) * pnorm / fnorm;
+ prered = SQR(temp1) + 2 * SQR(temp2);
+ dirder = -(SQR(temp1) + SQR(temp2));
+
+ ratio = prered != 0 ? actred / prered : 0;
+
+ if (ratio <= p25) {
+ if (actred >= 0.0)
+ temp = p5;
+ else
+ temp = p5 * dirder / (dirder + p5 * actred);
+ if (p1 * fnorm1 >= fnorm || temp < p1)
+ temp = p1;
+ delta = temp * min(delta, pnorm / p1);
+ par.val /= temp;
+ } else if (par.val == 0.0 || ratio >= p75) {
+ delta = pnorm / p5;
+ par.val *= p5;
+ }
+
+ if (ratio >= p0001) {
+ for (j = 0; j < n; ++j) {
+ x[j] = wa2[j];
+ wa2[j] = diag[j] * x[j];
+ }
+ for (i = 0; i < m; ++i)
+ fvec[i] = wa4[i];
+ xnorm = lm_enorm(n, wa2);
+ fnorm = fnorm1;
+ ++iter;
+ }
+
+ info.val = 0;
+ if (fabs(actred) <= ftol && prered <= ftol && p5 * ratio <= 1)
+ info.val = 1;
+ if (delta <= xtol * xnorm)
+ info.val += 2;
+ if (info.val != 0)
+ return;
+
+ if (nfev.val >= maxfev)
+ info.val = 5;
+ if (fabs(actred) <= LM_MACHEP && prered <= LM_MACHEP && p5 * ratio <= 1)
+ info.val = 6;
+ if (delta <= LM_MACHEP * xnorm)
+ info.val = 7;
+ if (gnorm <= LM_MACHEP)
+ info.val = 8;
+ if (info.val != 0)
+ return;
+ } while (ratio < p0001);
+ } while (true);
+}
+
+
+// copied from the C code; wrapper of lm_lmdif
+void lm_minimize(int m_dat, int n_par, real[] par, lm_evaluate_ftype evaluate, lm_print_ftype printout, lm_data_type data, lm_control_type control) {
+ int n = n_par;
+ int m = m_dat;
+
+ real[] fvec = new real[m];
+ real[] diag = new real[n];
+ real[] qtf = new real[n];
+ real[] fjac = new real[n * m];
+ real[] wa1 = new real[n];
+ real[] wa2 = new real[n];
+ real[] wa3 = new real[n];
+ real[] wa4 = new real[m];
+ int[] ipvt = new int[n];
+
+ control.info.val = 0;
+ control.nfev.val = 0;
+
+ lm_lmdif(m, n, par, fvec, control.ftol, control.xtol, control.gtol, control.maxcall * (n + 1), control.epsilon, diag, 1, control.stepbound, control.info, control.nfev, fjac, ipvt, qtf, wa1, wa2, wa3, wa4, evaluate, printout, data);
+
+ if(printout != null) printout(n, par, m, fvec, data, -1, 0, control.nfev.val);
+ control.fnorm = lm_enorm(m, fvec);
+ if (control.info.val < 0)
+ control.info.val = 10;
+}
+
+
+// convenience functions; wrappers of lm_minimize
+
+/*
+ The structure FitControl specifies various control parameters.
+*/
+struct FitControl {
+ real squareSumTolerance; // relative error desired in the sum of squares
+ real approximationTolerance; // relative error between last two approximations
+ real desiredOrthogonality; // orthogonality desired between the residue vector and its derivatives
+ real epsilon; // step used to calculate the jacobian
+ real stepBound; // initial bound to steps in the outer loop
+ int maxIterations; // maximum number of iterations
+ bool verbose; // whether to print detailed information about every iteration, or nothing
+
+ void operator init(real squareSumTolerance=LM_USERTOL, real approximationTolerance=LM_USERTOL, real desiredOrthogonality=LM_USERTOL, real epsilon=LM_USERTOL, real stepBound=100, int maxIterations=100, bool verbose=false) {
+ this.squareSumTolerance = squareSumTolerance;
+ this.approximationTolerance = approximationTolerance;
+ this.desiredOrthogonality = desiredOrthogonality;
+ this.epsilon = epsilon;
+ this.stepBound = stepBound;
+ this.maxIterations = maxIterations;
+ this.verbose = verbose;
+ }
+
+ FitControl copy() {
+ FitControl result = new FitControl;
+ result.squareSumTolerance = this.squareSumTolerance;
+ result.approximationTolerance = this.approximationTolerance;
+ result.desiredOrthogonality = this.desiredOrthogonality;
+ result.epsilon = this.epsilon;
+ result.stepBound = this.stepBound;
+ result.maxIterations = this.maxIterations;
+ result.verbose = this.verbose;
+ return result;
+ }
+};
+
+FitControl operator init() {
+ return FitControl();
+}
+
+FitControl defaultControl;
+
+
+/*
+ Upon returning, this structure provides information about the fit.
+*/
+struct FitResult {
+ real norm; // norm of the residue vector
+ int iterations; // actual number of iterations
+ int status; // status of minimization
+
+ void operator init(real norm, int iterations, int status) {
+ this.norm = norm;
+ this.iterations = iterations;
+ this.status = status;
+ }
+};
+
+
+/*
+ Fits data points to a function that depends on some parameters.
+
+ Parameters:
+ - xdata: Array of x values.
+ - ydata: Array of y values.
+ - errors: Array of experimental errors; each element must be strictly positive
+ - function: Fit function.
+ - parameters: Parameter array. Before calling fit(), this must contain the initial guesses for the parameters.
+ Upon return, it will contain the solution parameters.
+ - control: object of type FitControl that controls various aspects of the fitting procedure.
+
+ Returns:
+ An object of type FitResult that conveys information about the fitting process.
+*/
+FitResult fit(real[] xdata, real[] ydata, real[] errors, real function(real[], real), real[] parameters, FitControl control=defaultControl) {
+ int m_dat = min(xdata.length, ydata.length);
+ int n_par = parameters.length;
+ lm_evaluate_ftype evaluate = lm_evaluate_default;
+ lm_print_ftype printout = control.verbose ? lm_print_default : lm_print_quiet;
+
+ lm_data_type data;
+ data.user_t = xdata;
+ data.user_y = ydata;
+ data.user_w = 1 / errors;
+ data.user_func = new real(real x, real[] params) {
+ return function(params, x);
+ };
+
+ lm_control_type ctrl;
+ ctrl.ftol = control.squareSumTolerance;
+ ctrl.xtol = control.approximationTolerance;
+ ctrl.gtol = control.desiredOrthogonality;
+ ctrl.epsilon = control.epsilon;
+ ctrl.stepbound = control.stepBound;
+ ctrl.maxcall = control.maxIterations;
+
+ lm_minimize(m_dat, n_par, parameters, evaluate, printout, data, ctrl);
+
+ return FitResult(ctrl.fnorm, ctrl.nfev.val, ctrl.info.val);
+}
+
+
+/*
+ Fits data points to a function that depends on some parameters.
+
+ Parameters:
+ - xdata: Array of x values.
+ - ydata: Array of y values.
+ - function: Fit function.
+ - parameters: Parameter array. Before calling fit(), this must contain the initial guesses for the parameters.
+ Upon return, it will contain the solution parameters.
+ - control: object of type FitControl that controls various aspects of the fitting procedure.
+
+ Returns:
+ An object of type FitResult that conveys information about the fitting process.
+*/
+FitResult fit(real[] xdata, real[] ydata, real function(real[], real), real[] parameters, FitControl control=defaultControl) {
+ return fit(xdata, ydata, array(min(xdata.length, ydata.length), 1.0), function, parameters, control);
+}
+
diff --git a/graphics/asymptote/base/markers.asy b/graphics/asymptote/base/markers.asy
new file mode 100644
index 0000000000..84adc8e6cf
--- /dev/null
+++ b/graphics/asymptote/base/markers.asy
@@ -0,0 +1,218 @@
+// Mark routines and markers written by Philippe Ivaldi.
+// http://www.piprime.fr/
+
+marker operator * (transform T, marker m)
+{
+ marker M=new marker;
+ M.f=T*m.f;
+ M.above=m.above;
+ M.markroutine=m.markroutine;
+ return M;
+}
+
+// Add n frames f midway (in arclength) between n+1 uniformly spaced marks.
+markroutine markinterval(int n=1, frame f, bool rotated=false)
+{
+ return new void(picture pic=currentpicture, frame mark, path g) {
+ markuniform(n+1,rotated)(pic,mark,g);
+ markuniform(centered=true,n,rotated)(pic,f,g);
+ };
+}
+
+// Return a frame containing n copies of the path g shifted by space
+// drawn with pen p.
+frame duplicate(path g, int n=1, pair space=0, pen p=currentpen)
+{
+ if(space == 0) space=dotsize(p);
+ frame f;
+ int pos=0;
+ int sign=1;
+ int m=(n+1) % 2;
+ for(int i=1; i <= n; ++i) {
+ draw(f,shift(space*(pos-0.5*m))*g,p);
+ pos += i*sign;
+ sign *= -1;
+ }
+ return f;
+}
+
+real tildemarksizefactor=5;
+real tildemarksize(pen p=currentpen)
+{
+ static real golden=(1+sqrt(5))/2;
+ return (1mm+tildemarksizefactor*sqrt(linewidth(p)))/golden;
+}
+frame tildeframe(int n=1, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen)
+{
+ size=(size == 0) ? tildemarksize(p) : size;
+ space=(space == 0) ? 1.5*size : space;
+ path g=yscale(1.25)*((-1.5,-0.5)..(-0.75,0.5)..(0,0)..(0.75,-0.5)..(1.5,0.5));
+ return duplicate(shift(offset)*rotate(angle)*scale(size)*g,n,space,p);
+}
+
+frame tildeframe=tildeframe();
+
+real stickmarkspacefactor=4;
+real stickmarksizefactor=10;
+real stickmarksize(pen p=currentpen)
+{
+ return 1mm+stickmarksizefactor*sqrt(linewidth(p));
+}
+real stickmarkspace(pen p=currentpen)
+{
+ return stickmarkspacefactor*sqrt(linewidth(p));
+}
+frame stickframe(int n=1, real size=0, pair space=0, real angle=0,
+ pair offset=0, pen p=currentpen)
+{
+ if(size == 0) size=stickmarksize(p);
+ if(space == 0) space=stickmarkspace(p);
+ return duplicate(shift(offset)*rotate(angle)*scale(0.5*size)*(N--S),n,
+ space,p);
+}
+
+frame stickframe=stickframe();
+
+real circlemarkradiusfactor=stickmarksizefactor/2;
+real circlemarkradius(pen p=currentpen)
+{
+ static real golden=(1+sqrt(5))/2;
+ return (1mm+circlemarkradiusfactor*sqrt(linewidth(p)))/golden;
+}
+real barmarksizefactor=stickmarksizefactor;
+real barmarksize(pen p=currentpen)
+{
+ return 1mm+barmarksizefactor*sqrt(linewidth(p));
+}
+frame circlebarframe(int n=1, real barsize=0,
+ real radius=0,real angle=0,
+ pair offset=0, pen p=currentpen,
+ filltype filltype=NoFill, bool above=false)
+{
+ if(barsize == 0) barsize=barmarksize(p);
+ if(radius == 0) radius=circlemarkradius(p);
+ frame opic;
+ path g=circle(offset,radius);
+ frame f=stickframe(n,barsize,space=2*radius/(n+1),angle,offset,p);
+ if(above) {
+ add(opic,f);
+ filltype.fill(opic,g,p);
+ } else {
+ filltype.fill(opic,g,p);
+ add(opic,f);
+ }
+ return opic;
+}
+
+real crossmarksizefactor=5;
+real crossmarksize(pen p=currentpen)
+{
+ return 1mm+crossmarksizefactor*sqrt(linewidth(p));
+}
+frame crossframe(int n=3, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen)
+{
+ if(size == 0) size=crossmarksize(p);
+ frame opic;
+ draw(opic,shift(offset)*rotate(angle)*scale(size)*cross(n),p);
+ return opic;
+}
+
+real markanglespacefactor=4;
+real markangleradiusfactor=8;
+real markangleradius(pen p=currentpen)
+{
+ return 8mm+markangleradiusfactor*sqrt(linewidth(p));
+}
+real markangleradius=markangleradius();
+real markanglespace(pen p=currentpen)
+{
+ return markanglespacefactor*sqrt(linewidth(p));
+}
+real markanglespace=markanglespace();
+// Mark the oriented angle AOB counterclockwise with optional Label, arrows, and markers.
+// With radius < 0, AOB-2pi is marked clockwise.
+void markangle(picture pic=currentpicture, Label L="",
+ int n=1, real radius=0, real space=0,
+ pair A, pair O, pair B, arrowbar arrow=None,
+ pen p=currentpen, filltype filltype=NoFill,
+ margin margin=NoMargin, marker marker=nomarker)
+{
+ if(space == 0) space=markanglespace(p);
+ if(radius == 0) radius=markangleradius(p);
+ picture lpic,phantom;
+ frame ff;
+ path lpth;
+ p=squarecap+p;
+ pair OB=unit(B-O), OA=unit(A-O);
+ real xoa=degrees(OA,false);
+ real gle=degrees(acos(dot(OA,OB)));
+ if((conj(OA)*OB).y < 0) gle *= -1;
+ bool ccw=radius > 0;
+ if(!ccw) radius=-radius;
+ bool drawarrow = !arrow(phantom,arc((0,0),radius,xoa,xoa+gle,ccw),p,margin);
+ if(drawarrow && margin == NoMargin) margin=TrueMargin(0,0.5linewidth(p));
+ if(filltype != NoFill) {
+ lpth=margin(arc((0,0),radius+(n-1)*space,xoa,xoa+gle,ccw),p).g;
+ pair p0=relpoint(lpth,0), p1=relpoint(lpth,1);
+ pair ac=p0-p0-A+O, bd=p1-p1-B+O, det=(conj(ac)*bd).y;
+ pair op=(det == 0) ? O : p0+(conj(p1-p0)*bd).y*ac/det;
+ filltype.fill(ff,op--lpth--relpoint(lpth,1)--cycle,p);
+ add(lpic,ff);
+ }
+ for(int i=0; i < n; ++i) {
+ lpth=margin(arc((0,0),radius+i*space,xoa,xoa+gle,ccw),p).g;
+ draw(lpic,lpth,p=p,arrow=arrow,margin=NoMargin,marker=marker);
+ }
+ Label lL=L.copy();
+ real position=lL.position.position.x;
+ if(lL.defaultposition) {lL.position.relative=true; position=0.5;}
+ if(lL.position.relative) position=reltime(lpth,position);
+ if(lL.align.default) {
+ lL.align.relative=true;
+ lL.align.dir=unit(point(lpth,position));
+ }
+ label(lpic,lL,point(lpth,position),align=NoAlign, p=p);
+ add(pic,lpic,O);
+}
+
+marker StickIntervalMarker(int i=2, int n=1, real size=0, real space=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,stickframe(n,size,space,angle,offset,p),
+ rotated),above);
+}
+
+
+marker CrossIntervalMarker(int i=2, int n=3, real size=0, real space=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,crossframe(n,size,space,angle,offset,p),
+ rotated=rotated),above);
+}
+
+marker CircleBarIntervalMarker(int i=2, int n=1, real barsize=0, real radius=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, filltype filltype=NoFill,
+ bool circleabove=false, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,circlebarframe(n,barsize,radius,angle,
+ offset,p,filltype,
+ circleabove),
+ rotated),above);
+}
+
+marker TildeIntervalMarker(int i=2, int n=1, real size=0, real space=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,tildeframe(n,size,space,angle,offset,p),
+ rotated),above);
+}
diff --git a/graphics/asymptote/base/math.asy b/graphics/asymptote/base/math.asy
new file mode 100644
index 0000000000..9d10e2b779
--- /dev/null
+++ b/graphics/asymptote/base/math.asy
@@ -0,0 +1,451 @@
+// Asymptote mathematics routines
+
+int quadrant(real degrees)
+{
+ return floor(degrees/90) % 4;
+}
+
+// Roots of unity.
+pair unityroot(int n, int k=1)
+{
+ return expi(2pi*k/n);
+}
+
+real csc(real x) {return 1/sin(x);}
+real sec(real x) {return 1/cos(x);}
+real cot(real x) {return tan(pi/2-x);}
+
+real acsc(real x) {return asin(1/x);}
+real asec(real x) {return acos(1/x);}
+real acot(real x) {return pi/2-atan(x);}
+
+real frac(real x) {return x-(int)x;}
+
+pair exp(explicit pair z) {return exp(z.x)*expi(z.y);}
+pair log(explicit pair z) {return log(abs(z))+I*angle(z);}
+
+// Return an Nx by Ny unit square lattice with lower-left corner at (0,0).
+picture grid(int Nx, int Ny, pen p=currentpen)
+{
+ picture pic;
+ for(int i=0; i <= Nx; ++i) draw(pic,(i,0)--(i,Ny),p);
+ for(int j=0; j <= Ny; ++j) draw(pic,(0,j)--(Nx,j),p);
+ return pic;
+}
+
+bool polygon(path p)
+{
+ return cyclic(p) && piecewisestraight(p);
+}
+
+// Return the intersection time of the point on the line through p and q
+// that is closest to z.
+real intersect(pair p, pair q, pair z)
+{
+ pair u=q-p;
+ real denom=dot(u,u);
+ return denom == 0 ? infinity : dot(z-p,u)/denom;
+}
+
+// Return the intersection time of the extension of the line segment PQ
+// with the plane perpendicular to n and passing through Z.
+real intersect(triple P, triple Q, triple n, triple Z)
+{
+ real d=n.x*Z.x+n.y*Z.y+n.z*Z.z;
+ real denom=n.x*(Q.x-P.x)+n.y*(Q.y-P.y)+n.z*(Q.z-P.z);
+ return denom == 0 ? infinity : (d-n.x*P.x-n.y*P.y-n.z*P.z)/denom;
+}
+
+// Return any point on the intersection of the two planes with normals
+// n0 and n1 passing through points P0 and P1, respectively.
+// If the planes are parallel return (infinity,infinity,infinity).
+triple intersectionpoint(triple n0, triple P0, triple n1, triple P1)
+{
+ real Dx=n0.y*n1.z-n1.y*n0.z;
+ real Dy=n0.z*n1.x-n1.z*n0.x;
+ real Dz=n0.x*n1.y-n1.x*n0.y;
+ if(abs(Dx) > abs(Dy) && abs(Dx) > abs(Dz)) {
+ Dx=1/Dx;
+ real d0=n0.y*P0.y+n0.z*P0.z;
+ real d1=n1.y*P1.y+n1.z*P1.z+n1.x*(P1.x-P0.x);
+ real y=(d0*n1.z-d1*n0.z)*Dx;
+ real z=(d1*n0.y-d0*n1.y)*Dx;
+ return (P0.x,y,z);
+ } else if(abs(Dy) > abs(Dz)) {
+ Dy=1/Dy;
+ real d0=n0.z*P0.z+n0.x*P0.x;
+ real d1=n1.z*P1.z+n1.x*P1.x+n1.y*(P1.y-P0.y);
+ real z=(d0*n1.x-d1*n0.x)*Dy;
+ real x=(d1*n0.z-d0*n1.z)*Dy;
+ return (x,P0.y,z);
+ } else {
+ if(Dz == 0) return (infinity,infinity,infinity);
+ Dz=1/Dz;
+ real d0=n0.x*P0.x+n0.y*P0.y;
+ real d1=n1.x*P1.x+n1.y*P1.y+n1.z*(P1.z-P0.z);
+ real x=(d0*n1.y-d1*n0.y)*Dz;
+ real y=(d1*n0.x-d0*n1.x)*Dz;
+ return (x,y,P0.z);
+ }
+}
+
+// Given a real array a, return its partial sums.
+real[] partialsum(real[] a)
+{
+ real[] b=new real[a.length];
+ real sum=0;
+ for(int i=0; i < a.length; ++i) {
+ sum += a[i];
+ b[i]=sum;
+ }
+ return b;
+}
+
+// Given a real array a, return its partial dx-weighted sums.
+real[] partialsum(real[] a, real[] dx)
+{
+ real[] b=new real[a.length];
+ real sum=0;
+ for(int i=0; i < a.length; ++i) {
+ sum += a[i]*dx[i];
+ b[i]=sum;
+ }
+ return b;
+}
+
+// Given an integer array a, return its partial sums.
+int[] partialsum(int[] a)
+{
+ int[] b=new int[a.length];
+ int sum=0;
+ for(int i=0; i < a.length; ++i) {
+ sum += a[i];
+ b[i]=sum;
+ }
+ return b;
+}
+
+// Given an integer array a, return its partial dx-weighted sums.
+int[] partialsum(int[] a, int[] dx)
+{
+ int[] b=new int[a.length];
+ int sum=0;
+ for(int i=0; i < a.length; ++i) {
+ sum += a[i]*dx[i];
+ b[i]=sum;
+ }
+ return b;
+}
+
+// If strict=false, return whether i > j implies a[i] >= a[j]
+// If strict=true, return whether i > j implies a[i] > a[j]
+bool increasing(real[] a, bool strict=false)
+{
+ real[] ap=copy(a);
+ ap.delete(0);
+ ap.push(0);
+ bool[] b=strict ? (ap > a) : (ap >= a);
+ b[a.length-1]=true;
+ return all(b);
+}
+
+// Return the first and last indices of consecutive true-element segments
+// of bool[] b.
+int[][] segmentlimits(bool[] b)
+{
+ int[][] segment;
+ bool[] n=copy(b);
+ n.delete(0);
+ n.push(!b[b.length-1]);
+ int[] edge=(b != n) ? sequence(1,b.length) : null;
+ edge.insert(0,0);
+ int stop=edge[0];
+ for(int i=1; i < edge.length; ++i) {
+ int start=stop;
+ stop=edge[i];
+ if(b[start])
+ segment.push(new int[] {start,stop-1});
+ }
+ return segment;
+}
+
+// Return the indices of consecutive true-element segments of bool[] b.
+int[][] segment(bool[] b)
+{
+ int[][] S=segmentlimits(b);
+ return sequence(new int[](int i) {
+ return sequence(S[i][0],S[i][1]);
+ },S.length);
+}
+
+// If the sorted array a does not contain x, insert it sequentially,
+// returning the index of x in the resulting array.
+int unique(real[] a, real x) {
+ int i=search(a,x);
+ if(i == -1 || x != a[i]) {
+ ++i;
+ a.insert(i,x);
+ }
+ return i;
+}
+
+int unique(string[] a, string x) {
+ int i=search(a,x);
+ if(i == -1 || x != a[i]) {
+ ++i;
+ a.insert(i,x);
+ }
+ return i;
+}
+
+bool lexorder(pair a, pair b) {
+ return a.x < b.x || (a.x == b.x && a.y < b.y);
+}
+
+bool lexorder(triple a, triple b) {
+ return a.x < b.x || (a.x == b.x && (a.y < b.y || (a.y == b.y && a.z < b.z)));
+}
+
+real[] zero(int n)
+{
+ return sequence(new real(int) {return 0;},n);
+}
+
+real[][] zero(int n, int m)
+{
+ real[][] M=new real[n][];
+ for(int i=0; i < n; ++i)
+ M[i]=sequence(new real(int) {return 0;},m);
+ return M;
+}
+
+bool square(real[][] m)
+{
+ int n=m.length;
+ for(int i=0; i < n; ++i)
+ if(m[i].length != n) return false;
+ return true;
+}
+
+bool rectangular(real[][] m)
+{
+ int n=m.length;
+ if(n > 0) {
+ int m0=m[0].length;
+ for(int i=1; i < n; ++i)
+ if(m[i].length != m0) return false;
+ }
+ return true;
+}
+
+bool rectangular(pair[][] m)
+{
+ int n=m.length;
+ if(n > 0) {
+ int m0=m[0].length;
+ for(int i=1; i < n; ++i)
+ if(m[i].length != m0) return false;
+ }
+ return true;
+}
+
+bool rectangular(triple[][] m)
+{
+ int n=m.length;
+ if(n > 0) {
+ int m0=m[0].length;
+ for(int i=1; i < n; ++i)
+ if(m[i].length != m0) return false;
+ }
+ return true;
+}
+
+// draw the (infinite) line going through P and Q, without altering the
+// size of picture pic.
+void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen)
+{
+ pic.add(new void (frame f, transform t, transform T, pair m, pair M) {
+ // Reduce the bounds by the size of the pen.
+ m -= min(p); M -= max(p);
+
+ // Calculate the points and direction vector in the transformed space.
+ t=t*T;
+ pair z=t*P;
+ pair v=t*Q-z;
+
+ // Handle horizontal and vertical lines.
+ if(v.x == 0) {
+ if(m.x <= z.x && z.x <= M.x)
+ draw(f,(z.x,m.y)--(z.x,M.y),p);
+ } else if(v.y == 0) {
+ if(m.y <= z.y && z.y <= M.y)
+ draw(f,(m.x,z.y)--(M.x,z.y),p);
+ } else {
+ // Calculate the maximum and minimum t values allowed for the
+ // parametric equation z + t*v
+ real mx=(m.x-z.x)/v.x, Mx=(M.x-z.x)/v.x;
+ real my=(m.y-z.y)/v.y, My=(M.y-z.y)/v.y;
+ real tmin=max(v.x > 0 ? mx : Mx, v.y > 0 ? my : My);
+ real tmax=min(v.x > 0 ? Mx : mx, v.y > 0 ? My : my);
+ if(tmin <= tmax)
+ draw(f,z+tmin*v--z+tmax*v,p);
+ }
+ },true);
+}
+
+real interpolate(real[] x, real[] y, real x0, int i)
+{
+ int n=x.length;
+ if(n == 0) abort("Zero data points in interpolate");
+ if(n == 1) return y[0];
+ if(i < 0) {
+ real dx=x[1]-x[0];
+ return y[0]+(y[1]-y[0])/dx*(x0-x[0]);
+ }
+ if(i >= n-1) {
+ real dx=x[n-1]-x[n-2];
+ return y[n-1]+(y[n-1]-y[n-2])/dx*(x0-x[n-1]);
+ }
+
+ real D=x[i+1]-x[i];
+ real B=(x0-x[i])/D;
+ real A=1.0-B;
+ return A*y[i]+B*y[i+1];
+}
+
+// Linearly interpolate data points (x,y) to (x0,y0), where the elements of
+// real[] x are listed in ascending order and return y0. Values outside the
+// available data range are linearly extrapolated using the first derivative
+// at the nearest endpoint.
+real interpolate(real[] x, real[] y, real x0)
+{
+ return interpolate(x,y,x0,search(x,x0));
+}
+
+private string nopoint="point not found";
+
+// Return the nth intersection time of path g with the vertical line through x.
+real time(path g, real x, int n=0)
+{
+ real[] t=times(g,x);
+ if(t.length <= n) abort(nopoint);
+ return t[n];
+}
+
+// Return the nth intersection time of path g with the horizontal line through
+// (0,z.y).
+real time(path g, explicit pair z, int n=0)
+{
+ real[] t=times(g,z);
+ if(t.length <= n) abort(nopoint);
+ return t[n];
+}
+
+// Return the nth y value of g at x.
+real value(path g, real x, int n=0)
+{
+ return point(g,time(g,x,n)).y;
+}
+
+// Return the nth x value of g at y=z.y.
+real value(path g, explicit pair z, int n=0)
+{
+ return point(g,time(g,(0,z.y),n)).x;
+}
+
+// Return the nth slope of g at x.
+real slope(path g, real x, int n=0)
+{
+ pair a=dir(g,time(g,x,n));
+ return a.y/a.x;
+}
+
+// Return the nth slope of g at y=z.y.
+real slope(path g, explicit pair z, int n=0)
+{
+ pair a=dir(g,time(g,(0,z.y),n));
+ return a.y/a.x;
+}
+
+// A quartic complex root solver based on these references:
+// http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormula.html
+// Neumark, S., Solution of Cubic and Quartic Equations, Pergamon Press
+// Oxford (1965).
+pair[] quarticroots(real a, real b, real c, real d, real e)
+{
+ real Fuzz=100000*realEpsilon;
+
+ // Remove roots at numerical infinity.
+ if(abs(a) <= Fuzz*(abs(b)+Fuzz*(abs(c)+Fuzz*(abs(d)+Fuzz*abs(e)))))
+ return cubicroots(b,c,d,e);
+
+ // Detect roots at numerical zero.
+ if(abs(e) <= Fuzz*(abs(d)+Fuzz*(abs(c)+Fuzz*(abs(b)+Fuzz*abs(a)))))
+ return cubicroots(a,b,c,d);
+
+ real ainv=1/a;
+ b *= ainv;
+ c *= ainv;
+ d *= ainv;
+ e *= ainv;
+
+ pair[] roots;
+ real[] T=cubicroots(1,-2c,c^2+b*d-4e,d^2+b^2*e-b*c*d);
+ if(T.length == 0) return roots;
+
+ real t0=T[0];
+ pair[] sum=quadraticroots((1,0),(b,0),(t0,0));
+ pair[] product=quadraticroots((1,0),(t0-c,0),(e,0));
+
+ if(abs(sum[0]*product[0]+sum[1]*product[1]+d) <
+ abs(sum[0]*product[1]+sum[1]*product[0]+d))
+ product=reverse(product);
+
+ for(int i=0; i < 2; ++i)
+ roots.append(quadraticroots((1,0),-sum[i],product[i]));
+
+ return roots;
+}
+
+pair[][] fft(pair[][] a, int sign=1)
+{
+ pair[][] A=new pair[a.length][];
+ int k=0;
+ for(pair[] v : a) {
+ A[k]=fft(v,sign);
+ ++k;
+ }
+ a=transpose(A);
+ k=0;
+ for(pair[] v : a) {
+ A[k]=fft(v,sign);
+ ++k;
+ }
+ return transpose(A);
+}
+
+// Given a matrix A with independent columns, return
+// the unique vector y minimizing |Ay - b|^2 (the L2 norm).
+// If the columns of A are not linearly independent,
+// throw an error (if warn == true) or return an empty array
+// (if warn == false).
+real[] leastsquares(real[][] A, real[] b, bool warn=true)
+{
+ real[] solution=solve(AtA(A),b*A,warn=false);
+ if (solution.length == 0 && warn)
+ abort("Cannot compute least-squares approximation for " +
+ "a matrix with linearly dependent columns.");
+ return solution;
+}
+
+// Namespace
+struct rootfinder_settings {
+ static real roottolerance = 1e-4;
+}
+
+real findroot(real f(real), real a, real b,
+ real tolerance=rootfinder_settings.roottolerance,
+ real fa=f(a), real fb=f(b))
+{
+ return _findroot(f,a,b,tolerance,fa,fb);
+}
diff --git a/graphics/asymptote/base/metapost.asy b/graphics/asymptote/base/metapost.asy
new file mode 100644
index 0000000000..525ffe755e
--- /dev/null
+++ b/graphics/asymptote/base/metapost.asy
@@ -0,0 +1,19 @@
+// MetaPost compatibility routines
+
+path cuttings;
+
+path cutbefore(path p, path q)
+{
+ slice s=firstcut(p,q);
+ cuttings=s.before;
+ return s.after;
+}
+
+path cutafter(path p, path q)
+{
+ slice s=lastcut(p,q);
+ cuttings=s.after;
+ return s.before;
+}
+
+
diff --git a/graphics/asymptote/base/nopapersize.ps b/graphics/asymptote/base/nopapersize.ps
new file mode 100644
index 0000000000..67e3140474
--- /dev/null
+++ b/graphics/asymptote/base/nopapersize.ps
@@ -0,0 +1,3 @@
+@ a4size 0in 0in
+
+@ letterSize 0in 0in
diff --git a/graphics/asymptote/base/obj.asy b/graphics/asymptote/base/obj.asy
new file mode 100644
index 0000000000..8dde9341c4
--- /dev/null
+++ b/graphics/asymptote/base/obj.asy
@@ -0,0 +1,113 @@
+// A module for reading simple obj files with groups.
+// Authors: Jens Schwaiger and John Bowman
+//
+// Here simple means that :
+//
+// 1) all vertex statements should come before the face statements;
+//
+// 2) face informations with respect to texture and/or normal vectors are
+// ignored;
+//
+// 3) face statements only contain positive numbers(no relative positions).
+//
+// The reading process only takes into account lines starting with "v" or
+// "f" or "g"(group).
+
+import three;
+
+struct obj {
+ surface s;
+ material[] surfacepen;
+ pen[] meshpen;
+
+ path3[][] read(string datafile, bool verbose=false) {
+ file in=input(datafile).word().line();
+ triple[] vert;
+ path3[][] g;
+ g[0]=new path3[] ;
+ string[] G;
+ void Vertex(real x,real y ,real z) {vert.push((x,y,z));}
+ void Face(int[] vertnr, int groupnr) {
+ guide3 gh;
+ for(int i=0; i < vertnr.length; ++i)
+ gh=gh--vert[vertnr[i]-1];
+ gh=gh--cycle;
+ g[groupnr].push(gh);
+ }
+ if(verbose) write("Reading data from "+datafile+".");
+ int groupnr;
+ while(true) {
+ string[] str=in;
+ if(str.length == 0) break;
+ str=sequence(new string(int i) {return split(str[i],"/")[0];},str.length);
+ if(str[0] == "g" && str.length > 1) {
+ int tst=find(G == str[1]);
+ if(tst == -1) {
+ G.push(str[1]);
+ groupnr=G.length-1;
+ g[groupnr]=new path3[] ;
+ }
+ if(tst > -1) groupnr=tst;
+ }
+ if(str[0] == "v") Vertex((real) str[1],(real) str[2],(real) str[3]);
+ if(str[0] == "f") {
+ int[] vertnr;
+ for(int i=1; i < str.length; ++i) vertnr[i-1]=(int) str[i];
+ Face(vertnr,groupnr);
+ }
+ if(eof(in)) break;
+ }
+ close(in);
+ if(verbose) {
+ write("Number of groups: ",G.length);
+ write("Groups and their names:");
+ write(G);
+ write("Reading done.");
+ write("Number of faces contained in the groups: ");
+ for(int j=0; j < G.length; ++j)
+ write(G[j],": ",(string) g[j].length);
+ }
+ return g;
+ }
+
+ void operator init(path3[][] g, material[] surfacepen, pen[] meshpen) {
+ for(int i=0; i < g.length; ++i) {
+ path3[] gi=g[i];
+ for(int j=0; j < gi.length; ++j) {
+ // Treat all faces as planar to avoid subdivision cracks.
+ surface sij=surface(gi[j],planar=true);
+ s.append(sij);
+ this.surfacepen.append(array(sij.s.length,surfacepen[i]));
+ this.meshpen.append(array(sij.s.length,meshpen[i]));
+ }
+ }
+ }
+
+ void operator init(string datafile, bool verbose=false,
+ material[] surfacepen, pen[] meshpen=nullpens) {
+ operator init(read(datafile,verbose),surfacepen,meshpen);
+ }
+
+ void operator init(string datafile, bool verbose=false,
+ material surfacepen, pen meshpen=nullpen) {
+ material[] surfacepen={surfacepen};
+ pen[] meshpen={meshpen};
+ surfacepen.cyclic=true;
+ meshpen.cyclic=true;
+ operator init(read(datafile,verbose),surfacepen,meshpen);
+ }
+}
+
+obj operator * (transform3 T, obj o)
+{
+ obj ot;
+ ot.s=T*o.s;
+ ot.surfacepen=copy(o.surfacepen);
+ ot.meshpen=copy(o.meshpen);
+ return ot;
+}
+
+void draw(picture pic=currentpicture, obj o, light light=currentlight)
+{
+ draw(pic,o.s,o.surfacepen,o.meshpen,light);
+}
diff --git a/graphics/asymptote/base/ode.asy b/graphics/asymptote/base/ode.asy
new file mode 100644
index 0000000000..7104a8d153
--- /dev/null
+++ b/graphics/asymptote/base/ode.asy
@@ -0,0 +1,457 @@
+real stepfactor=2; // Maximum dynamic step size adjustment factor.
+
+struct coefficients
+{
+ real[] steps;
+ real[] factors;
+ real[][] weights;
+ real[] highOrderWeights;
+ real[] lowOrderWeights;
+}
+
+struct RKTableau
+{
+ int order;
+ coefficients a;
+ void stepDependence(real h, real c, coefficients a) {}
+
+ real pgrow;
+ real pshrink;
+ bool exponential;
+
+ void operator init(int order, real[][] weights, real[] highOrderWeights,
+ real[] lowOrderWeights=new real[],
+ real[] steps=sequence(new real(int i) {
+ return sum(weights[i]);},weights.length),
+ void stepDependence(real, real, coefficients)=null) {
+ this.order=order;
+ a.steps=steps;
+ a.factors=array(a.steps.length+1,1);
+ a.weights=weights;
+ a.highOrderWeights=highOrderWeights;
+ a.lowOrderWeights=lowOrderWeights;
+ if(stepDependence != null) {
+ this.stepDependence=stepDependence;
+ exponential=true;
+ }
+ pgrow=(order > 0) ? 1/order : 0;
+ pshrink=(order > 1) ? 1/(order-1) : pgrow;
+ }
+}
+
+real[] Coeff={1,1/2,1/6,1/24,1/120,1/720,1/5040,1/40320,1/362880,1/3628800,
+ 1/39916800.0,1/479001600.0,1/6227020800.0,1/87178291200.0,
+ 1/1307674368000.0,1/20922789888000.0,1/355687428096000.0,
+ 1/6402373705728000.0,1/121645100408832000.0,
+ 1/2432902008176640000.0,1/51090942171709440000.0,
+ 1/1124000727777607680000.0};
+
+real phi1(real x) {return x != 0 ? expm1(x)/x : 1;}
+
+real phi2(real x)
+{
+ real x2=x*x;
+ if(fabs(x) > 1) return (exp(x)-x-1)/x2;
+ real x3=x2*x;
+ real x5=x2*x3;
+ if(fabs(x) < 0.1)
+ return Coeff[1]+x*Coeff[2]+x2*Coeff[3]+x3*Coeff[4]+x2*x2*Coeff[5]
+ +x5*Coeff[6]+x3*x3*Coeff[7]+x5*x2*Coeff[8]+x5*x3*Coeff[9];
+ else {
+ real x7=x5*x2;
+ real x8=x7*x;
+ return Coeff[1]+x*Coeff[2]+x2*Coeff[3]+x3*Coeff[4]+x2*x2*Coeff[5]
+ +x5*Coeff[6]+x3*x3*Coeff[7]+x7*Coeff[8]+x8*Coeff[9]
+ +x8*x*Coeff[10]+x5*x5*Coeff[11]+x8*x3*Coeff[12]+x7*x5*Coeff[13]+
+ x8*x5*Coeff[14]+x7*x7*Coeff[15]+x8*x7*Coeff[16]+x8*x8*Coeff[17];
+ }
+}
+
+real phi3(real x)
+{
+ real x2=x*x;
+ real x3=x2*x;
+ if(fabs(x) > 1.6) return (exp(x)-0.5*x2-x-1)/x3;
+ real x5=x2*x3;
+ if(fabs(x) < 0.1)
+ return Coeff[2]+x*Coeff[3]+x2*Coeff[4]+x3*Coeff[5]
+ +x2*x2*Coeff[6]+x5*Coeff[7]+x3*x3*Coeff[8]+x5*x2*Coeff[9]
+ +x5*x3*Coeff[10];
+ else {
+ real x7=x5*x2;
+ real x8=x7*x;
+ real x16=x8*x8;
+ return Coeff[2]+x*Coeff[3]+x2*Coeff[4]+x3*Coeff[5]
+ +x2*x2*Coeff[6]+x5*Coeff[7]+x3*x3*Coeff[8]+x5*x2*Coeff[9]
+ +x5*x3*Coeff[10]+x8*x*Coeff[11]
+ +x5*x5*Coeff[12]+x8*x3*Coeff[13]+x7*x5*Coeff[14]
+ +x8*x5*Coeff[15]+x7*x7*Coeff[16]+x8*x7*Coeff[17]+x16*Coeff[18]
+ +x16*x*Coeff[19]+x16*x2*Coeff[20];
+ }
+}
+
+void expfactors(real x, coefficients a)
+{
+ for(int i=0; i < a.steps.length; ++i)
+ a.factors[i]=exp(x*a.steps[i]);
+ a.factors[a.steps.length]=exp(x);
+}
+
+// First-Order Euler
+RKTableau Euler=RKTableau(1,new real[][], new real[] {1});
+
+// First-Order Exponential Euler
+RKTableau E_Euler=RKTableau(1,new real[][], new real[] {1},
+ new void(real h, real c, coefficients a) {
+ real x=-c*h;
+ expfactors(x,a);
+ a.highOrderWeights[0]=phi1(x);
+ });
+
+// Second-Order Runge-Kutta
+RKTableau RK2=RKTableau(2,new real[][] {{1/2}},
+ new real[] {0,1}, // 2nd order
+ new real[] {1,0}); // 1st order
+
+// Second-Order Exponential Runge-Kutta
+RKTableau E_RK2=RKTableau(2,new real[][] {{1/2}},
+ new real[] {0,1}, // 2nd order
+ new real[] {1,0}, // 1st order
+ new void(real h, real c, coefficients a) {
+ real x=-c*h;
+ expfactors(x,a);
+ a.weights[0][0]=1/2*phi1(x/2);
+ real w=phi1(x);
+ a.highOrderWeights[0]=0;
+ a.highOrderWeights[1]=w;
+ a.lowOrderWeights[0]=w;
+ });
+
+// Second-Order Predictor-Corrector
+RKTableau PC=RKTableau(2,new real[][] {{1}},
+ new real[] {1/2,1/2}, // 2nd order
+ new real[] {1,0}); // 1st order
+
+// Second-Order Exponential Predictor-Corrector
+RKTableau E_PC=RKTableau(2,new real[][] {{1}},
+ new real[] {1/2,1/2}, // 2nd order
+ new real[] {1,0}, // 1st order
+ new void(real h, real c, coefficients a) {
+ real x=-c*h;
+ expfactors(x,a);
+ real w=phi1(x);
+ a.weights[0][0]=w;
+ a.highOrderWeights[0]=w/2;
+ a.highOrderWeights[1]=w/2;
+ a.lowOrderWeights[0]=w;
+ });
+
+// Third-Order Classical Runge-Kutta
+RKTableau RK3=RKTableau(3,new real[][] {{1/2},{-1,2}},
+ new real[] {1/6,2/3,1/6});
+
+// Third-Order Bogacki-Shampine Runge-Kutta
+RKTableau RK3BS=RKTableau(3,new real[][] {{1/2},{0,3/4}},
+ new real[] {2/9,1/3,4/9}, // 3rd order
+ new real[] {7/24,1/4,1/3,1/8}); // 2nd order
+
+// Third-Order Exponential Bogacki-Shampine Runge-Kutta
+RKTableau E_RK3BS=RKTableau(3,new real[][] {{1/2},{0,3/4}},
+ new real[] {2/9,1/3,4/9}, // 3rd order
+ new real[] {7/24,1/4,1/3,1/8}, // 2nd order
+ new void(real h, real c, coefficients a) {
+ real x=-c*h;
+ expfactors(x,a);
+ real w=phi1(x);
+ real w2=phi2(x);
+ a.weights[0][0]=1/2*phi1(x/2);
+ real a11=9/8*phi2(3/4*x)+3/8*phi2(x/2);
+ a.weights[1][0]=3/4*phi1(3/4*x)-a11;
+ a.weights[1][1]=a11;
+ real a21=1/3*w;
+ real a22=4/3*w2-2/9*w;
+ a.highOrderWeights[0]=w-a21-a22;
+ a.highOrderWeights[1]=a21;
+ a.highOrderWeights[2]=a22;
+ a.lowOrderWeights[0]=w-17/12*w2;
+ a.lowOrderWeights[1]=w2/2;
+ a.lowOrderWeights[2]=2/3*w2;
+ a.lowOrderWeights[3]=w2/4;
+ });
+
+// Fourth-Order Classical Runge-Kutta
+RKTableau RK4=RKTableau(4,new real[][] {{1/2},{0,1/2},{0,0,1}},
+ new real[] {1/6,1/3,1/3,1/6});
+
+// Fifth-Order Cash-Karp Runge-Kutta
+RKTableau RK5=RKTableau(5,new real[][] {{1/5},
+ {3/40,9/40},
+ {3/10,-9/10,6/5},
+ {-11/54,5/2,-70/27,35/27},
+ {1631/55296,175/512,575/13824,
+ 44275/110592,253/4096}},
+ new real[] {37/378,0,250/621,125/594,
+ 0,512/1771}, // 5th order
+ new real[] {2825/27648,0,18575/48384,13525/55296,
+ 277/14336,1/4}); // 4th order
+
+// Fifth-Order Fehlberg Runge-Kutta
+RKTableau RK5F=RKTableau(5,new real[][] {{1/4},
+ {3/32,9/32},
+ {1932/2197,-7200/2197,7296/2197},
+ {439/216,-8,3680/513,-845/4104},
+ {-8/27,2,-3544/2565,1859/4104,
+ -11/40}},
+ new real[] {16/135,0,6656/12825,28561/56430,-9/50,2/55}, // 5th order
+ new real[] {25/216,0,1408/2565,2197/4104,-1/5,0}); // 4th order
+
+// Fifth-Order Dormand-Prince Runge-Kutta
+RKTableau RK5DP=RKTableau(5,new real[][] {{1/5},
+ {3/40,9/40},
+ {44/45,-56/15,32/9},
+ {19372/6561,-25360/2187,64448/6561,
+ -212/729},
+ {9017/3168,-355/33,46732/5247,49/176,
+ -5103/18656}},
+ new real[] {35/384,0,500/1113,125/192,-2187/6784,
+ 11/84}, // 5th order
+ new real[] {5179/57600,0,7571/16695,393/640,
+ -92097/339200,187/2100,1/40}); // 4th order
+
+real error(real error, real initial, real lowOrder, real norm, real diff)
+{
+ if(initial != 0 && lowOrder != initial) {
+ static real epsilon=realMin/realEpsilon;
+ real denom=max(abs(norm),abs(initial))+epsilon;
+ return max(error,max(abs(diff)/denom));
+ }
+ return error;
+}
+
+void report(real old, real h, real t)
+{
+ write("Time step changed from "+(string) old+" to "+(string) h+" at t="+
+ (string) t+".");
+}
+
+real adjust(real h, real error, real tolmin, real tolmax, RKTableau tableau)
+{
+ if(error > tolmax)
+ h *= max((tolmin/error)^tableau.pshrink,1/stepfactor);
+ else if(error > 0 && error < tolmin)
+ h *= min((tolmin/error)^tableau.pgrow,stepfactor);
+ return h;
+}
+
+struct solution
+{
+ real[] t;
+ real[] y;
+}
+
+void write(solution S)
+{
+ for(int i=0; i < S.t.length; ++i)
+ write(S.t[i],S.y[i]);
+}
+
+// Integrate dy/dt+cy=f(t,y) from a to b using initial conditions y,
+// specifying either the step size h or the number of steps n.
+solution integrate(real y, real c=0, real f(real t, real y), real a, real b=a,
+ real h=0, int n=0, bool dynamic=false, real tolmin=0,
+ real tolmax=0, real dtmin=0, real dtmax=realMax,
+ RKTableau tableau, bool verbose=false)
+{
+ solution S;
+ S.t=new real[] {a};
+ S.y=new real[] {y};
+
+ if(h == 0) {
+ if(b == a) return S;
+ if(n == 0) abort("Either n or h must be specified");
+ else h=(b-a)/n;
+ }
+
+ real F(real t, real y)=(c == 0 || tableau.exponential) ? f :
+ new real(real t, real y) {return f(t,y)-c*y;};
+
+ tableau.stepDependence(h,c,tableau.a);
+
+ real t=a;
+ real f0;
+ if(tableau.a.lowOrderWeights.length == 0) dynamic=false;
+ bool fsal=dynamic &&
+ (tableau.a.lowOrderWeights.length > tableau.a.highOrderWeights.length);
+ if(fsal) f0=F(t,y);
+
+ real dt=h;
+ while(t < b) {
+ h=min(h,b-t);
+ if(t+h == t) break;
+ if(h != dt) {
+ if(verbose) report(dt,h,t);
+ tableau.stepDependence(h,c,tableau.a);
+ dt=h;
+ }
+
+ real[] predictions={fsal ? f0 : F(t,y)};
+ for(int i=0; i < tableau.a.steps.length; ++i)
+ predictions.push(F(t+h*tableau.a.steps[i],
+ tableau.a.factors[i]*y+h*dot(tableau.a.weights[i],
+ predictions)));
+
+ real highOrder=h*dot(tableau.a.highOrderWeights,predictions);
+ real y0=tableau.a.factors[tableau.a.steps.length]*y;
+ if(dynamic) {
+ real f1;
+ if(fsal) {
+ f1=F(t+h,y0+highOrder);
+ predictions.push(f1);
+ }
+ real lowOrder=h*dot(tableau.a.lowOrderWeights,predictions);
+ real error;
+ error=error(error,y,y0+lowOrder,y0+highOrder,highOrder-lowOrder);
+ h=adjust(h,error,tolmin,tolmax,tableau);
+ if(h >= dt) {
+ t += dt;
+ y=y0+highOrder;
+ S.t.push(t);
+ S.y.push(y);
+ f0=f1;
+ }
+ h=min(max(h,dtmin),dtmax);
+ } else {
+ t += h;
+ y=y0+highOrder;
+ S.t.push(t);
+ S.y.push(y);
+ }
+ }
+ return S;
+}
+
+struct Solution
+{
+ real[] t;
+ real[][] y;
+}
+
+void write(Solution S)
+{
+ for(int i=0; i < S.t.length; ++i) {
+ write(S.t[i],tab);
+ for(real y : S.y[i])
+ write(y,tab);
+ write();
+ }
+}
+
+// Integrate a set of equations, dy/dt=f(t,y), from a to b using initial
+// conditions y, specifying either the step size h or the number of steps n.
+Solution integrate(real[] y, real[] f(real t, real[] y), real a, real b=a,
+ real h=0, int n=0, bool dynamic=false,
+ real tolmin=0, real tolmax=0, real dtmin=0,
+ real dtmax=realMax, RKTableau tableau, bool verbose=false)
+{
+ Solution S;
+ S.t=new real[] {a};
+ S.y=new real[][] {copy(y)};
+
+ if(h == 0) {
+ if(b == a) return S;
+ if(n == 0) abort("Either n or h must be specified");
+ else h=(b-a)/n;
+ }
+ real t=a;
+ real[] f0;
+ if(tableau.a.lowOrderWeights.length == 0) dynamic=false;
+ bool fsal=dynamic &&
+ (tableau.a.lowOrderWeights.length > tableau.a.highOrderWeights.length);
+ if(fsal) f0=f(t,y);
+
+ real dt=h;
+ while(t < b) {
+ h=min(h,b-t);
+ if(t+h == t) break;
+ if(h != dt) {
+ if(verbose) report(dt,h,t);
+ dt=h;
+ }
+
+ real[][] predictions={fsal ? f0 : f(t,y)};
+ for(int i=0; i < tableau.a.steps.length; ++i)
+ predictions.push(f(t+h*tableau.a.steps[i],
+ y+h*tableau.a.weights[i]*predictions));
+
+ real[] highOrder=h*tableau.a.highOrderWeights*predictions;
+ if(dynamic) {
+ real[] f1;
+ if(fsal) {
+ f1=f(t+h,y+highOrder);
+ predictions.push(f1);
+ }
+ real[] lowOrder=h*tableau.a.lowOrderWeights*predictions;
+ real error;
+ for(int i=0; i < y.length; ++i)
+ error=error(error,y[i],y[i]+lowOrder[i],y[i]+highOrder[i],
+ highOrder[i]-lowOrder[i]);
+ h=adjust(h,error,tolmin,tolmax,tableau);
+ if(h >= dt) {
+ t += dt;
+ y += highOrder;
+ S.t.push(t);
+ S.y.push(y);
+ f0=f1;
+ }
+ h=min(max(h,dtmin),dtmax);
+ } else {
+ t += h;
+ y += highOrder;
+ S.t.push(t);
+ S.y.push(y);
+ }
+ }
+ return S;
+}
+
+real[][] finiteDifferenceJacobian(real[] f(real[]), real[] t,
+ real[] h=sqrtEpsilon*abs(t))
+{
+ real[] ft=f(t);
+ real[][] J=new real[t.length][ft.length];
+ real[] ti=copy(t);
+ real tlast=ti[0];
+ ti[0] += h[0];
+ J[0]=(f(ti)-ft)/h[0];
+ for(int i=1; i < t.length; ++i) {
+ ti[i-1]=tlast;
+ tlast=ti[i];
+ ti[i] += h[i];
+ J[i]=(f(ti)-ft)/h[i];
+ }
+ return transpose(J);
+}
+
+// Solve simultaneous nonlinear system by Newton's method.
+real[] newton(int iterations=100, real[] f(real[]), real[][] jacobian(real[]),
+ real[] t)
+{
+ real[] t=copy(t);
+ for(int i=0; i < iterations; ++i)
+ t += solve(jacobian(t),-f(t));
+ return t;
+}
+
+real[] solveBVP(real[] f(real, real[]), real a, real b=a, real h=0, int n=0,
+ bool dynamic=false, real tolmin=0, real tolmax=0, real dtmin=0,
+ real dtmax=realMax, RKTableau tableau, bool verbose=false,
+ real[] initial(real[]), real[] discrepancy(real[]),
+ real[] guess, int iterations=100)
+{
+ real[] g(real[] t) {
+ real[][] y=integrate(initial(t),f,a,b,h,n,dynamic,tolmin,tolmax,dtmin,dtmax,
+ tableau,verbose).y;return discrepancy(y[y.length-1]);
+ }
+ real[][] jacobian(real[] t) {return finiteDifferenceJacobian(g,t);}
+ return initial(newton(iterations,g,jacobian,guess));
+}
diff --git a/graphics/asymptote/base/palette.asy b/graphics/asymptote/base/palette.asy
new file mode 100644
index 0000000000..2cb6e7c547
--- /dev/null
+++ b/graphics/asymptote/base/palette.asy
@@ -0,0 +1,530 @@
+private import graph;
+
+private transform swap=(0,0,0,1,1,0);
+
+typedef bounds range(picture pic, real min, real max);
+
+range Range(bool automin=false, real min=-infinity,
+ bool automax=false, real max=infinity)
+{
+ return new bounds(picture pic, real dmin, real dmax) {
+ // autoscale routine finds reasonable limits
+ bounds mz=autoscale(pic.scale.z.T(dmin),
+ pic.scale.z.T(dmax),
+ pic.scale.z.scale);
+ // If automin/max, use autoscale result, else
+ // if min/max is finite, use specified value, else
+ // use minimum/maximum data value
+ real pmin=automin ? pic.scale.z.Tinv(mz.min) : (finite(min) ? min : dmin);
+ real pmax=automax ? pic.scale.z.Tinv(mz.max) : (finite(max) ? max : dmax);
+ return bounds(pmin,pmax);
+ };
+}
+
+range Automatic=Range(true,true);
+range Full=Range();
+
+void image(frame f, real[][] data, pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ transform t=identity(), bool copy=true, bool antialias=false)
+{
+ transform T=transpose ? swap : identity();
+ _image(f,copy ? copy(data) : data,T*initial,T*final,palette,t*T,copy=false,
+ antialias=antialias);
+}
+
+void image(frame f, pen[][] data, pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ transform t=identity(), bool copy=true, bool antialias=false)
+{
+ transform T=transpose ? swap : identity();
+ _image(f,copy ? copy(data) : data,T*initial,T*final,t*T,copy=false,
+ antialias=antialias);
+}
+
+// Reduce color palette to approximate range of data relative to "display"
+// range => errors of 1/palette.length in resulting color space.
+pen[] adjust(picture pic, real min, real max, real rmin, real rmax,
+ pen[] palette)
+{
+ real dmin=pic.scale.z.T(min);
+ real dmax=pic.scale.z.T(max);
+ real delta=rmax-rmin;
+ if(delta > 0) {
+ real factor=palette.length/delta;
+ int minindex=floor(factor*(dmin-rmin));
+ if(minindex < 0) minindex=0;
+ int maxindex=ceil(factor*(dmax-rmin));
+ if(maxindex > palette.length) maxindex=palette.length;
+ if(minindex > 0 || maxindex < palette.length)
+ return palette[minindex:maxindex];
+ }
+ return palette;
+}
+
+private real[] sequencereal;
+
+bounds image(picture pic=currentpicture, real[][] f, range range=Full,
+ pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false)
+{
+ if(copy) f=copy(f);
+ if(copy) palette=copy(palette);
+
+ real m=min(f);
+ real M=max(f);
+ bounds bounds=range(pic,m,M);
+ real rmin=pic.scale.z.T(bounds.min);
+ real rmax=pic.scale.z.T(bounds.max);
+ palette=adjust(pic,m,M,rmin,rmax,palette);
+
+ // Crop data to allowed range and scale
+ if(range != Full || pic.scale.z.scale.T != identity ||
+ pic.scale.z.postscale.T != identity) {
+ scalefcn T=pic.scale.z.T;
+ real m=bounds.min;
+ real M=bounds.max;
+ for(int i=0; i < f.length; ++i)
+ f[i]=map(new real(real x) {return T(min(max(x,m),M));},f[i]);
+ }
+
+ initial=Scale(pic,initial);
+ final=Scale(pic,final);
+
+ pic.addBox(initial,final);
+
+ transform T;
+ if(transpose) {
+ T=swap;
+ initial=T*initial;
+ final=T*final;
+ }
+
+ pic.add(new void(frame F, transform t) {
+ _image(F,f,initial,final,palette,t*T,copy=false,antialias=antialias);
+ },true);
+ return bounds; // Return bounds used for color space
+}
+
+bounds image(picture pic=currentpicture, real f(real, real),
+ range range=Full, pair initial, pair final,
+ int nx=ngraph, int ny=nx, pen[] palette, bool antialias=false)
+{
+ // Generate data, taking scaling into account
+ real xmin=pic.scale.x.T(initial.x);
+ real xmax=pic.scale.x.T(final.x);
+ real ymin=pic.scale.y.T(initial.y);
+ real ymax=pic.scale.y.T(final.y);
+ real[][] data=new real[ny][nx];
+ for(int j=0; j < ny; ++j) {
+ real y=pic.scale.y.Tinv(interp(ymin,ymax,(j+0.5)/ny));
+ scalefcn Tinv=pic.scale.x.Tinv;
+ // Take center point of each bin
+ data[j]=sequence(new real(int i) {
+ return f(Tinv(interp(xmin,xmax,(i+0.5)/nx)),y);
+ },nx);
+ }
+ return image(pic,data,range,initial,final,palette,transpose=false,
+ copy=false,antialias=antialias);
+}
+
+void image(picture pic=currentpicture, pen[][] data, pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false)
+{
+ if(copy) data=copy(data);
+
+ initial=Scale(pic,initial);
+ final=Scale(pic,final);
+
+ pic.addBox(initial,final);
+
+ transform T;
+ if(transpose) {
+ T=swap;
+ initial=T*initial;
+ final=T*final;
+ }
+
+ pic.add(new void(frame F, transform t) {
+ _image(F,data,initial,final,t*T,copy=false,antialias=antialias);
+ },true);
+}
+
+void image(picture pic=currentpicture, pen f(int, int), int width, int height,
+ pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool antialias=false)
+{
+ initial=Scale(pic,initial);
+ final=Scale(pic,final);
+
+ pic.addBox(initial,final);
+
+ transform T;
+ if(transpose) {
+ T=swap;
+ int temp=width;
+ width=height;
+ height=temp;
+ initial=T*initial;
+ final=T*final;
+ }
+
+ pic.add(new void(frame F, transform t) {
+ _image(F,f,width,height,initial,final,t*T,antialias=antialias);
+ },true);
+}
+
+bounds image(picture pic=currentpicture, pair[] z, real[] f,
+ range range=Full, pen[] palette)
+{
+ if(z.length != f.length)
+ abort("z and f arrays have different lengths");
+
+ real m=min(f);
+ real M=max(f);
+ bounds bounds=range(pic,m,M);
+ real rmin=pic.scale.z.T(bounds.min);
+ real rmax=pic.scale.z.T(bounds.max);
+
+ palette=adjust(pic,m,M,rmin,rmax,palette);
+ rmin=max(rmin,m);
+ rmax=min(rmax,M);
+
+ // Crop data to allowed range and scale
+ if(range != Full || pic.scale.z.scale.T != identity ||
+ pic.scale.z.postscale.T != identity) {
+ scalefcn T=pic.scale.z.T;
+ real m=bounds.min;
+ real M=bounds.max;
+ f=map(new real(real x) {return T(min(max(x,m),M));},f);
+ }
+
+ int[] edges={0,0,1};
+ int N=palette.length-1;
+
+ int[][] trn=triangulate(z);
+ real step=rmax == rmin ? 0.0 : N/(rmax-rmin);
+ for(int i=0; i < trn.length; ++i) {
+ int[] trni=trn[i];
+ int i0=trni[0], i1=trni[1], i2=trni[2];
+ pen color(int i) {return palette[round((f[i]-rmin)*step)];}
+ gouraudshade(pic,z[i0]--z[i1]--z[i2]--cycle,
+ new pen[] {color(i0),color(i1),color(i2)},edges);
+ }
+ return bounds; // Return bounds used for color space
+}
+
+bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f,
+ range range=Full, pen[] palette)
+{
+ int n=x.length;
+ if(n != y.length)
+ abort("x and y arrays have different lengths");
+
+ pair[] z=sequence(new pair(int i) {return (x[i],y[i]);},n);
+ return image(pic,z,f,range,palette);
+}
+
+// Construct a pen[] array from f using the specified palette.
+pen[] palette(real[] f, pen[] palette)
+{
+ real Min=min(f);
+ real Max=max(f);
+ if(palette.length == 0) return new pen[];
+ real step=Max == Min ? 0.0 : (palette.length-1)/(Max-Min);
+ return sequence(new pen(int i) {return palette[round((f[i]-Min)*step)];},
+ f.length);
+}
+
+// Construct a pen[][] array from f using the specified palette.
+pen[][] palette(real[][] f, pen[] palette)
+{
+ real Min=min(f);
+ real Max=max(f);
+ int n=f.length;
+ pen[][] p=new pen[n][];
+ real step=(Max == Min) ? 0.0 : (palette.length-1)/(Max-Min);
+ for(int i=0; i < n; ++i) {
+ real[] fi=f[i];
+ p[i]=sequence(new pen(int j) {return palette[round((fi[j]-Min)*step)];},
+ f[i].length);
+ }
+ return p;
+}
+
+typedef ticks paletteticks(int sign=-1);
+
+paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new ticks(int sign=-1) {
+ format.align(sign > 0 ? RightSide : LeftSide);
+ return Ticks(sign,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ true,true,extend=true,pTick,ptick);
+ };
+}
+
+paletteticks PaletteTicks=PaletteTicks();
+paletteticks NoTicks=new ticks(int sign=-1) {return NoTicks;};
+
+void palette(picture pic=currentpicture, Label L="", bounds bounds,
+ pair initial, pair final, axis axis=Right, pen[] palette,
+ pen p=currentpen, paletteticks ticks=PaletteTicks,
+ bool copy=true, bool antialias=false)
+{
+ real initialz=pic.scale.z.T(bounds.min);
+ real finalz=pic.scale.z.T(bounds.max);
+ bounds mz=autoscale(initialz,finalz,pic.scale.z.scale);
+
+ axisT axis;
+ axis(pic,axis);
+ real angle=degrees(axis.align.dir);
+
+ initial=Scale(pic,initial);
+ final=Scale(pic,final);
+
+ pair lambda=final-initial;
+ bool vertical=(floor((angle+45)/90) % 2 == 0);
+ pair perp,par;
+
+ if(vertical) {perp=E; par=N;} else {perp=N; par=E;}
+
+ path g=(final-dot(lambda,par)*par)--final;
+ path g2=initial--final-dot(lambda,perp)*perp;
+
+ if(sgn(dot(lambda,perp)*dot(axis.align.dir,perp)) == -1) {
+ path tmp=g;
+ g=g2;
+ g2=tmp;
+ }
+
+ if(copy) palette=copy(palette);
+ Label L=L.copy();
+ if(L.defaultposition) L.position(0.5);
+ L.align(axis.align);
+ L.p(p);
+ if(vertical && L.defaulttransform) {
+ frame f;
+ add(f,Label(L.s,(0,0),L.p));
+ if(length(max(f)-min(f)) > ylabelwidth*fontsize(L.p))
+ L.transform(rotate(90));
+ }
+ real[][] pdata={sequence(palette.length)};
+
+ transform T;
+ pair Tinitial,Tfinal;
+ if(vertical) {
+ T=swap;
+ Tinitial=T*initial;
+ Tfinal=T*final;
+ } else {
+ Tinitial=initial;
+ Tfinal=final;
+ }
+
+ pic.add(new void(frame f, transform t) {
+ _image(f,pdata,Tinitial,Tfinal,palette,t*T,copy=false,
+ antialias=antialias);
+ },true);
+
+ ticklocate locate=ticklocate(initialz,finalz,pic.scale.z,mz.min,mz.max);
+ axis(pic,L,g,g2,p,ticks(sgn(axis.side.x*dot(lambda,par))),locate,mz.divisor,
+ true);
+
+ pic.add(new void(frame f, transform t) {
+ pair Z0=t*initial;
+ pair Z1=t*final;
+ draw(f,Z0--(Z0.x,Z1.y)--Z1--(Z1.x,Z0.y)--cycle,p);
+ },true);
+
+ pic.addBox(initial,final);
+}
+
+// A grayscale palette
+pen[] Grayscale(int NColors=256)
+{
+ real ninv=1.0/(NColors-1.0);
+ return sequence(new pen(int i) {return gray(i*ninv);},NColors);
+}
+
+// A color wheel palette
+pen[] Wheel(int NColors=32766)
+{
+ if(settings.gray) return Grayscale(NColors);
+
+ int nintervals=6;
+ int n=-quotient(NColors,-nintervals);
+
+ pen[] Palette;
+ if(n == 0) return Palette;
+
+ Palette=new pen[n*nintervals];
+ real ninv=1.0/n;
+
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[i]=rgb(1.0,0.0,ininv);
+ Palette[n+i]=rgb(ininv1,0.0,1.0);
+ Palette[2n+i]=rgb(0.0,ininv,1.0);
+ Palette[3n+i]=rgb(0.0,1.0,ininv1);
+ Palette[4n+i]=rgb(ininv,1.0,0.0);
+ Palette[5n+i]=rgb(1.0,ininv1,0.0);
+ }
+ return Palette;
+}
+
+// A rainbow palette
+pen[] Rainbow(int NColors=32766)
+{
+ if(settings.gray) return Grayscale(NColors);
+
+ int offset=1;
+ int nintervals=5;
+ int n=-quotient(NColors-1,-nintervals);
+
+ pen[] Palette;
+ if(n == 0) return Palette;
+
+ Palette=new pen[n*nintervals+offset];
+ real ninv=1.0/n;
+
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[i]=rgb(ininv1,0.0,1.0);
+ Palette[n+i]=rgb(0.0,ininv,1.0);
+ Palette[2n+i]=rgb(0.0,1.0,ininv1);
+ Palette[3n+i]=rgb(ininv,1.0,0.0);
+ Palette[4n+i]=rgb(1.0,ininv1,0.0);
+ }
+ Palette[4n+n]=rgb(1.0,0.0,0.0);
+
+ return Palette;
+}
+
+private pen[] BWRainbow(int NColors, bool two)
+{
+ if(settings.gray) return Grayscale(NColors);
+
+ int offset=1;
+ int nintervals=6;
+ int divisor=3;
+
+ if(two) nintervals += 6;
+
+ int num=NColors-offset;
+ int n=-quotient(num,-nintervals*divisor)*divisor;
+ NColors=n*nintervals+offset;
+
+ pen[] Palette;
+ if(n == 0) return Palette;
+
+ Palette=new pen[NColors];
+ real ninv=1.0/n;
+
+ int k=0;
+
+ if(two) {
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[i]=rgb(ininv1,0.0,1.0);
+ Palette[n+i]=rgb(0.0,ininv,1.0);
+ Palette[2n+i]=rgb(0.0,1.0,ininv1);
+ Palette[3n+i]=rgb(ininv,1.0,0.0);
+ Palette[4n+i]=rgb(1.0,ininv1,0.0);
+ Palette[5n+i]=rgb(1.0,0.0,ininv);
+ }
+ k += 6n;
+ }
+
+ if(two)
+ for(int i=0; i < n; ++i)
+ Palette[k+i]=rgb(1.0-i*ninv,0.0,1.0);
+ else {
+ int n3=-quotient(n,-3);
+ int n23=2*n3;
+ real third=n3*ninv;
+ real twothirds=n23*ninv;
+ for(int i=0; i < n3; ++i) {
+ real ininv=i*ninv;
+ Palette[k+i]=rgb(ininv,0.0,ininv);
+ Palette[k+n3+i]=rgb(third,0.0,third+ininv);
+ Palette[k+n23+i]=rgb(third-ininv,0.0,twothirds+ininv);
+ }
+ }
+ k += n;
+
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[k+i]=rgb(0.0,ininv,1.0);
+ Palette[k+n+i]=rgb(0.0,1.0,ininv1);
+ Palette[k+2n+i]=rgb(ininv,1.0,0.0);
+ Palette[k+3n+i]=rgb(1.0,ininv1,0.0);
+ Palette[k+4n+i]=rgb(1.0,ininv,ininv);
+ }
+ Palette[k+5n]=rgb(1.0,1.0,1.0);
+
+ return Palette;
+}
+
+// Quantize palette to exactly n values
+pen[] quantize(pen[] Palette, int n)
+{
+ if(Palette.length == 0) abort("cannot quantize empty palette");
+ if(n <= 1) abort("palette must contain at least two pens");
+ real step=(Palette.length-1)/(n-1);
+ return sequence(new pen(int i) {
+ return Palette[round(i*step)];
+ },n);
+}
+
+// A rainbow palette tapering off to black/white at the spectrum ends,
+pen[] BWRainbow(int NColors=32761)
+{
+ return BWRainbow(NColors,false);
+}
+
+// A double rainbow palette tapering off to black/white at the spectrum ends,
+// with a linearly scaled intensity.
+pen[] BWRainbow2(int NColors=32761)
+{
+ pen[] Palette=BWRainbow(NColors,true);
+ int n=Palette.length;
+ real ninv=1.0/n;
+ for(int i=0; i < n; ++i)
+ Palette[i]=i*ninv*Palette[i];
+ return Palette;
+}
+
+//A palette varying linearly over the specified array of pens, using
+// NColors in each interpolation interval.
+pen[] Gradient(int NColors=256 ... pen[] p)
+{
+ pen[] P;
+ if(p.length < 2) abort("at least 2 colors must be specified");
+ real step=NColors > 1 ? (1/(NColors-1)) : 1;
+ for(int i=0; i < p.length-1; ++i) {
+ pen begin=p[i];
+ pen end=p[i+1];
+ P.append(sequence(new pen(int j) {
+ return interp(begin,end,j*step);
+ },NColors));
+ }
+ return P;
+}
+
+pen[] cmyk(pen[] Palette)
+{
+ int n=Palette.length;
+ for(int i=0; i < n; ++i)
+ Palette[i]=cmyk(Palette[i]);
+ return Palette;
+}
diff --git a/graphics/asymptote/base/patterns.asy b/graphics/asymptote/base/patterns.asy
new file mode 100644
index 0000000000..56fa3bf4a2
--- /dev/null
+++ b/graphics/asymptote/base/patterns.asy
@@ -0,0 +1,102 @@
+// Create a tiling named name from picture pic
+// with optional left-bottom margin lb and right-top margin rt.
+frame tiling(string name, picture pic, pair lb=0, pair rt=0)
+{
+ frame tiling;
+ frame f=pic.fit(identity());
+ pair pmin=min(f)-lb;
+ pair pmax=max(f)+rt;
+ string s="%.6f";
+ postscript(tiling,"<< /PaintType 1 /PatternType 1 /TilingType 1
+/BBox ["+format(s,pmin.x,"C")+" "+format(s,pmin.y,"C")+" "+
+ format(s,pmax.x,"C")+" "+format(s,pmax.y,"C")+"]
+/XStep "+format(s,pmax.x-pmin.x,"C")+"
+/YStep "+format(s,pmax.y-pmin.y,"C")+"
+/PaintProc {pop");
+ add(tiling,f);
+ postscript(tiling,"} >>
+ matrix makepattern
+/"+name+" exch def");
+ return tiling;
+}
+
+// Add to frame preamble a tiling name constructed from picture pic
+// with optional left-bottom margin lb and right-top margin rt.
+void add(string name, picture pic, pair lb=0, pair rt=0)
+{
+ add(currentpatterns,tiling(name,pic,lb,rt));
+}
+
+picture tile(real Hx=5mm, real Hy=0, pen p=currentpen,
+ filltype filltype=NoFill)
+{
+ picture tiling;
+ if(Hy == 0) Hy=Hx;
+ path tile=box((0,0),(Hx,Hy));
+ tiling.add(new void (frame f, transform t) {
+ filltype.fill(f,t*tile,p);
+ });
+ clip(tiling,tile);
+ return tiling;
+}
+
+picture checker(real Hx=5mm, real Hy=0, pen p=currentpen)
+{
+ picture tiling;
+ if(Hy == 0) Hy=Hx;
+ path tile=box((0,0),(Hx,Hy));
+ fill(tiling,tile,p);
+ fill(tiling,shift(Hx,Hy)*tile,p);
+ clip(tiling,box((0,0),(2Hx,2Hy)));
+ return tiling;
+}
+
+picture brick(real Hx=5mm, real Hy=0, pen p=currentpen)
+{
+ picture tiling;
+ if(Hy == 0) Hy=Hx/2;
+ path tile=box((0,0),(Hx,Hy));
+ draw(tiling,tile,p);
+ draw(tiling,(Hx/2,Hy)--(Hx/2,2Hy),p);
+ draw(tiling,(0,2Hy)--(Hx,2Hy),p);
+ clip(tiling,box((0,0),(Hx,2Hy)));
+ return tiling;
+}
+
+real hatchepsilon=1e-4;
+picture hatch(real H=5mm, pair dir=NE, pen p=currentpen)
+{
+ picture tiling;
+ real theta=angle(dir);
+ real s=sin(theta);
+ real c=cos(theta);
+ if(abs(s) <= hatchepsilon) {
+ path g=(0,0)--(H,0);
+ draw(tiling,g,p);
+ draw(tiling,shift(0,H)*g,p);
+ clip(tiling,scale(H)*unitsquare);
+ } else if(abs(c) <= hatchepsilon) {
+ path g=(0,0)--(0,H);
+ draw(tiling,g,p);
+ draw(tiling,shift(H,0)*g,p);
+ clip(tiling,scale(H)*unitsquare);
+ } else {
+ real h=H/s;
+ real y=H/c;
+ path g=(0,0)--(h,y);
+ draw(tiling,g,p);
+ draw(tiling,shift(-h/2,y/2)*g,p);
+ draw(tiling,shift(h/2,-y/2)*g,p);
+ clip(tiling,box((0,0),(h,y)));
+ }
+ return tiling;
+}
+
+picture crosshatch(real H=5mm, pen p=currentpen)
+{
+ picture tiling;
+ add(tiling,hatch(H,p));
+ add(tiling,shift(H*sqrt(2))*rotate(90)*hatch(H,p));
+ return tiling;
+}
+
diff --git a/graphics/asymptote/base/plain.asy b/graphics/asymptote/base/plain.asy
new file mode 100644
index 0000000000..4afe3cb3de
--- /dev/null
+++ b/graphics/asymptote/base/plain.asy
@@ -0,0 +1,302 @@
+/*****
+ * plain.asy
+ * Andy Hammerlindl and John Bowman 2004/08/19
+ *
+ * A package for general purpose drawing, with automatic sizing of pictures.
+ *
+ *****/
+
+access settings;
+
+if(settings.command != "") {
+ string s=settings.command;
+ settings.command="";
+ settings.multipleView=settings.batchView=settings.interactiveView;
+ _eval(s+";",false,true);
+ exit();
+}
+
+include plain_constants;
+
+access version;
+if(version.VERSION != VERSION) {
+ warning("version","using possibly incompatible version "+
+ version.VERSION+" of plain.asy"+'\n');
+ nowarn("version");
+}
+
+include plain_strings;
+include plain_pens;
+include plain_paths;
+include plain_filldraw;
+include plain_margins;
+include plain_picture;
+include plain_Label;
+include plain_shipout;
+include plain_arcs;
+include plain_boxes;
+include plain_markers;
+include plain_arrows;
+include plain_debugger;
+
+typedef void exitfcn();
+
+void updatefunction()
+{
+ implicitshipout=true;
+ if(!currentpicture.uptodate) shipout();
+ implicitshipout=false;
+}
+
+void exitfunction()
+{
+ implicitshipout=true;
+ if(!currentpicture.empty())
+ shipout();
+ implicitshipout=false;
+}
+
+atupdate(updatefunction);
+atexit(exitfunction);
+
+// A restore thunk is a function, that when called, restores the graphics state
+// to what it was when the restore thunk was created.
+typedef void restoreThunk();
+typedef restoreThunk saveFunction();
+saveFunction[] saveFunctions={};
+
+// When save is called, this will be redefined to do the corresponding restore.
+void restore()
+{
+ warning("nomatchingsave","restore called with no matching save");
+}
+
+void addSaveFunction(saveFunction s)
+{
+ saveFunctions.push(s);
+}
+
+restoreThunk buildRestoreThunk()
+{
+ // Call the save functions in reverse order, storing their restore thunks.
+ restoreThunk[] thunks={};
+ for (int i=saveFunctions.length-1; i >= 0; --i)
+ thunks.push(saveFunctions[i]());
+
+ return new void() {
+ // Call the restore thunks in an order matching the saves.
+ for (int i=thunks.length-1; i >= 0; --i)
+ thunks[i]();
+ };
+}
+
+// Add the default save function.
+addSaveFunction(new restoreThunk () {
+ pen defaultpen=defaultpen();
+ pen p=currentpen;
+ picture pic=currentpicture.copy();
+ restoreThunk r=restore;
+ return new void() {
+ defaultpen(defaultpen);
+ currentpen=p;
+ currentpicture=pic;
+ currentpicture.uptodate=false;
+ restore=r;
+ };
+ });
+
+// Save the current state, so that restore will put things back in that state.
+restoreThunk save()
+{
+ return restore=buildRestoreThunk();
+}
+
+void restoredefaults()
+{
+ warning("nomatchingsavedefaults",
+ "restoredefaults called with no matching savedefaults");
+}
+
+restoreThunk buildRestoreDefaults()
+{
+ pen defaultpen=defaultpen();
+ exitfcn atupdate=atupdate();
+ exitfcn atexit=atexit();
+ restoreThunk r=restoredefaults;
+ return new void() {
+ defaultpen(defaultpen);
+ atupdate(atupdate);
+ atexit(atexit);
+ restoredefaults=r;
+ };
+}
+
+// Save the current state, so that restore will put things back in that state.
+restoreThunk savedefaults()
+{
+ return restoredefaults=buildRestoreDefaults();
+}
+
+void initdefaults()
+{
+ savedefaults();
+ resetdefaultpen();
+ atupdate(null);
+ atexit(null);
+}
+
+// Return the sequence n,...m
+int[] sequence(int n, int m)
+{
+ return sequence(new int(int x){return x;},m-n+1)+n;
+}
+
+int[] reverse(int n) {return sequence(new int(int x){return n-1-x;},n);}
+bool[] reverse(bool[] a) {return a[reverse(a.length)];}
+int[] reverse(int[] a) {return a[reverse(a.length)];}
+real[] reverse(real[] a) {return a[reverse(a.length)];}
+pair[] reverse(pair[] a) {return a[reverse(a.length)];}
+triple[] reverse(triple[] a) {return a[reverse(a.length)];}
+string[] reverse(string[] a) {return a[reverse(a.length)];}
+
+// Return a uniform partition dividing [a,b] into n subintervals.
+real[] uniform(real a, real b, int n)
+{
+ if(n <= 0) return new real[];
+ return a+(b-a)/n*sequence(n+1);
+}
+
+void eval(string s, bool embedded=false)
+{
+ if(!embedded) initdefaults();
+ _eval(s+";",embedded);
+ if(!embedded) restoredefaults();
+}
+
+void eval(code s, bool embedded=false)
+{
+ if(!embedded) initdefaults();
+ _eval(s,embedded);
+ if(!embedded) restoredefaults();
+}
+
+// Evaluate user command line option.
+void usersetting()
+{
+ eval(settings.user,true);
+}
+
+string stripsuffix(string f, string suffix=".asy")
+{
+ int n=rfind(f,suffix);
+ if(n != -1) f=erase(f,n,-1);
+ return f;
+}
+
+// Conditionally process each file name in array s in a new environment.
+void asy(string format, bool overwrite=false ... string[] s)
+{
+ for(string f : s) {
+ f=stripsuffix(f);
+ string suffix="."+format;
+ string fsuffix=f+suffix;
+ if(overwrite || error(input(fsuffix,check=false))) {
+ string outformat=settings.outformat;
+ bool interactiveView=settings.interactiveView;
+ bool batchView=settings.batchView;
+ settings.outformat=format;
+ settings.interactiveView=false;
+ settings.batchView=false;
+ string outname=outname();
+ delete(outname+"_"+".aux");
+ eval("import \""+f+"\" as dummy");
+ rename(stripsuffix(outname)+suffix,fsuffix);
+ settings.outformat=outformat;
+ settings.interactiveView=interactiveView;
+ settings.batchView=batchView;
+ }
+ }
+}
+
+void beep()
+{
+ write('\7',flush);
+}
+
+struct processtime {
+ real user;
+ real system;
+}
+
+struct cputime {
+ processtime parent;
+ processtime child;
+ processtime change;
+}
+
+cputime cputime()
+{
+ static processtime last;
+ real [] a=_cputime();
+ cputime cputime;
+ cputime.parent.user=a[0];
+ cputime.parent.system=a[1];
+ cputime.child.user=a[2];
+ cputime.child.system=a[3];
+ real user=a[0]+a[2];
+ real system=a[1]+a[3];
+ cputime.change.user=user-last.user;
+ cputime.change.system=system-last.system;
+ last.user=user;
+ last.system=system;
+ return cputime;
+}
+
+string cputimeformat="%#.2f";
+
+void write(file file, string s="", cputime c, string format=cputimeformat,
+ suffix suffix=none)
+{
+ write(file,s,
+ format(format,c.change.user)+"u "+
+ format(format,c.change.system)+"s "+
+ format(format,c.parent.user+c.child.user)+"U "+
+ format(format,c.parent.system+c.child.system)+"S ",suffix);
+}
+
+void write(string s="", cputime c, string format=cputimeformat,
+ suffix suffix=endl)
+{
+ write(stdout,s,c,format,suffix);
+}
+
+if(settings.autoimport != "") {
+ string s=settings.autoimport;
+ settings.autoimport="";
+ eval("import \""+s+"\" as dummy",true);
+ atupdate(updatefunction);
+ atexit(exitfunction);
+ settings.autoimport=s;
+}
+
+cputime();
+
+void nosetpagesize()
+{
+ static bool initialized=false;
+ if(!initialized && latex()) {
+ // Portably pass nosetpagesize option to graphicx package.
+ texpreamble("\usepackage{ifluatex}\ifluatex
+\ifx\pdfpagewidth\undefined\let\pdfpagewidth\paperwidth\fi
+\ifx\pdfpageheight\undefined\let\pdfpageheight\paperheight\fi\else
+\let\paperwidthsave\paperwidth\let\paperwidth\undefined
+\usepackage{graphicx}
+\let\paperwidth\paperwidthsave\fi");
+ initialized=true;
+ }
+}
+
+nosetpagesize();
+
+if(settings.tex == "luatex")
+ texpreamble("\input luatex85.sty");
diff --git a/graphics/asymptote/base/plain_Label.asy b/graphics/asymptote/base/plain_Label.asy
new file mode 100644
index 0000000000..c50ce003be
--- /dev/null
+++ b/graphics/asymptote/base/plain_Label.asy
@@ -0,0 +1,691 @@
+real angle(transform t)
+{
+ pair z=(2t.xx*t.yy,t.yx*t.yy-t.xx*t.xy);
+ if(t.xx < 0 || t.yy < 0) z=-z;
+ return degrees(z,warn=false);
+}
+
+transform rotation(transform t)
+{
+ return rotate(angle(t));
+}
+
+transform scaleless(transform t)
+{
+ real a=t.xx, b=t.xy, c=t.yx, d=t.yy;
+ real arg=(a-d)^2+4b*c;
+ pair delta=arg >= 0 ? sqrt(arg) : I*sqrt(-arg);
+ real trace=a+d;
+ pair l1=0.5(trace+delta);
+ pair l2=0.5(trace-delta);
+
+ if(abs(delta) < sqrtEpsilon*max(abs(l1),abs(l2))) {
+ real s=abs(0.5trace);
+ return (s != 0) ? scale(1/s)*t : t;
+ }
+
+ if(abs(l1-d) < abs(l2-d)) {pair temp=l1; l1=l2; l2=temp;}
+
+ pair dot(pair[] u, pair[] v) {return conj(u[0])*v[0]+conj(u[1])*v[1];}
+
+ pair[] unit(pair[] u) {
+ real norm2=abs(u[0])^2+abs(u[1])^2;
+ return norm2 != 0 ? u/sqrt(norm2) : u;
+ }
+
+ pair[] u={l1-d,b};
+ pair[] v={c,l2-a};
+ u=unit(u);
+ pair d=dot(u,u);
+ if(d != 0) v -= dot(u,v)/d*u;
+ v=unit(v);
+
+ pair[][] U={{u[0],v[0]},{u[1],v[1]}};
+ pair[][] A={{a,b},{c,d}};
+
+ pair[][] operator *(pair[][] a, pair[][] b) {
+ pair[][] c=new pair[2][2];
+ for(int i=0; i < 2; ++i) {
+ for(int j=0; j < 2; ++j) {
+ c[i][j]=a[i][0]*b[0][j]+a[i][1]*b[1][j];
+ }
+ }
+ return c;
+ }
+
+ pair[][] conj(pair[][] a) {
+ pair[][] c=new pair[2][2];
+ for(int i=0; i < 2; ++i) {
+ for(int j=0; j < 2; ++j) {
+ c[i][j]=conj(a[j][i]);
+ }
+ }
+ return c;
+ }
+
+ A=conj(U)*A*U;
+
+ real D=abs(A[0][0]);
+ if(D != 0) {
+ A[0][0] /= D;
+ A[0][1] /= D;
+ }
+
+ D=abs(A[1][1]);
+ if(D != 0) {
+ A[1][0] /= D;
+ A[1][1] /= D;
+ }
+
+ A=U*A*conj(U);
+
+ return (0,0,A[0][0].x,A[0][1].x,A[1][0].x,A[1][1].x);
+}
+
+struct align {
+ pair dir;
+ triple dir3;
+ bool relative=false;
+ bool default=true;
+ bool is3D=false;
+ void init(pair dir=0, bool relative=false, bool default=false) {
+ this.dir=dir;
+ this.relative=relative;
+ this.default=default;
+ is3D=false;
+ }
+ void init(triple dir=(0,0,0), bool relative=false, bool default=false) {
+ this.dir3=dir;
+ this.relative=relative;
+ this.default=default;
+ is3D=true;
+ }
+ align copy() {
+ align align=new align;
+ align.init(dir,relative,default);
+ align.dir3=dir3;
+ align.is3D=is3D;
+ return align;
+ }
+ void align(align align) {
+ if(!align.default) {
+ bool is3D=align.is3D;
+ init(align.dir,align.relative);
+ dir3=align.dir3;
+ this.is3D=is3D;
+ }
+ }
+ void align(align align, align default) {
+ align(align);
+ if(this.default) {
+ init(default.dir,default.relative,default.default);
+ dir3=default.dir3;
+ is3D=default.is3D;
+ }
+ }
+ void write(file file=stdout, suffix suffix=endl) {
+ if(!default) {
+ if(relative) {
+ write(file,"Relative(");
+ if(is3D)
+ write(file,dir3);
+ else
+ write(file,dir);
+ write(file,")",suffix);
+ } else {
+ if(is3D)
+ write(file,dir3,suffix);
+ else
+ write(file,dir,suffix);
+ }
+ }
+ }
+ bool Center() {
+ return relative && (is3D ? dir3 == (0,0,0) : dir == 0);
+ }
+}
+
+struct side {
+ pair align;
+}
+
+side Relative(explicit pair align)
+{
+ side s;
+ s.align=align;
+ return s;
+}
+
+restricted side NoSide;
+restricted side LeftSide=Relative(W);
+restricted side Center=Relative((0,0));
+restricted side RightSide=Relative(E);
+
+side operator * (real x, side s)
+{
+ side S;
+ S.align=x*s.align;
+ return S;
+}
+
+align operator cast(pair dir) {align A; A.init(dir,false); return A;}
+align operator cast(triple dir) {align A; A.init(dir,false); return A;}
+align operator cast(side side) {align A; A.init(side.align,true); return A;}
+restricted align NoAlign;
+
+void write(file file=stdout, align align, suffix suffix=endl)
+{
+ align.write(file,suffix);
+}
+
+struct position {
+ pair position;
+ bool relative;
+}
+
+position Relative(real position)
+{
+ position p;
+ p.position=position;
+ p.relative=true;
+ return p;
+}
+
+restricted position BeginPoint=Relative(0);
+restricted position MidPoint=Relative(0.5);
+restricted position EndPoint=Relative(1);
+
+position operator cast(pair x) {position P; P.position=x; return P;}
+position operator cast(real x) {return (pair) x;}
+position operator cast(int x) {return (pair) x;}
+
+pair operator cast(position P) {return P.position;}
+
+typedef transform embed(transform);
+transform Shift(transform t) {return identity();}
+transform Rotate(transform t) {return rotation(t);}
+transform Slant(transform t) {return scaleless(t);}
+transform Scale(transform t) {return t;}
+
+embed Rotate(pair z) {
+ return new transform(transform t) {return rotate(degrees(shiftless(t)*z,
+ warn=false));};
+}
+
+path[] texpath(string s, pen p, bool tex=settings.tex != "none",
+ bool bbox=false);
+
+struct Label {
+ string s,size;
+ position position;
+ bool defaultposition=true;
+ align align;
+ pen p=nullpen;
+ transform T;
+ transform3 T3=identity(4);
+ bool defaulttransform=true;
+ bool defaulttransform3=true;
+ embed embed=Rotate; // Shift, Rotate, Slant, or Scale with embedded picture
+ filltype filltype=NoFill;
+
+ void init(string s="", string size="", position position=0,
+ bool defaultposition=true, align align=NoAlign, pen p=nullpen,
+ transform T=identity(), transform3 T3=identity4,
+ bool defaulttransform=true, bool defaulttransform3=true,
+ embed embed=Rotate, filltype filltype=NoFill) {
+ this.s=s;
+ this.size=size;
+ this.position=position;
+ this.defaultposition=defaultposition;
+ this.align=align.copy();
+ this.p=p;
+ this.T=T;
+ this.T3=copy(T3);
+ this.defaulttransform=defaulttransform;
+ this.defaulttransform3=defaulttransform3;
+ this.embed=embed;
+ this.filltype=filltype;
+ }
+
+ void initalign(string s="", string size="", align align, pen p=nullpen,
+ embed embed=Rotate, filltype filltype=NoFill) {
+ init(s,size,align,p,embed,filltype);
+ }
+
+ void transform(transform T) {
+ this.T=T;
+ defaulttransform=false;
+ }
+
+ void transform3(transform3 T) {
+ this.T3=copy(T);
+ defaulttransform3=false;
+ }
+
+ Label copy(transform3 T3=this.T3) {
+ Label L=new Label;
+ L.init(s,size,position,defaultposition,align,p,T,T3,defaulttransform,
+ defaulttransform3,embed,filltype);
+ return L;
+ }
+
+ void position(position pos) {
+ this.position=pos;
+ defaultposition=false;
+ }
+
+ void align(align a) {
+ align.align(a);
+ }
+ void align(align a, align default) {
+ align.align(a,default);
+ }
+
+ void p(pen p0) {
+ if(this.p == nullpen) this.p=p0;
+ }
+
+ void filltype(filltype filltype0) {
+ if(this.filltype == NoFill) this.filltype=filltype0;
+ }
+
+ void label(frame f, transform t=identity(), pair position, pair align) {
+ pen p0=p == nullpen ? currentpen : p;
+ align=length(align)*unit(rotation(t)*align);
+ pair S=t*position+align*labelmargin(p0)+shift(T)*0;
+ if(settings.tex != "none")
+ label(f,s,size,embed(t)*shiftless(T),S,align,p0);
+ else
+ fill(f,align(texpath(s,p0),S,align,p0),p0);
+ }
+
+ void out(frame f, transform t=identity(), pair position=position.position,
+ pair align=align.dir) {
+ if(filltype == NoFill)
+ label(f,t,position,align);
+ else {
+ frame d;
+ label(d,t,position,align);
+ add(f,d,filltype);
+ }
+ }
+
+ void label(picture pic=currentpicture, pair position, pair align) {
+ if(s == "") return;
+ pic.add(new void (frame f, transform t) {
+ out(f,t,position,align);
+ },true);
+ frame f;
+ // Create a picture with label at the origin to extract its bbox truesize.
+ label(f,(0,0),align);
+ pic.addBox(position,position,min(f),max(f));
+ }
+
+ void out(picture pic=currentpicture) {
+ label(pic,position.position,align.dir);
+ }
+
+ void out(picture pic=currentpicture, path g) {
+ bool relative=position.relative;
+ real position=position.position.x;
+ pair Align=align.dir;
+ bool alignrelative=align.relative;
+ if(defaultposition) {relative=true; position=0.5;}
+ if(relative) position=reltime(g,position);
+ if(align.default) {
+ alignrelative=true;
+ Align=position <= sqrtEpsilon ? S :
+ position >= length(g)-sqrtEpsilon ? N : E;
+ }
+
+ pic.add(new void (frame f, transform t) {
+ out(f,t,point(g,position),alignrelative ?
+ inverse(rotation(t))*-Align*dir(t*g,position)*I : Align);
+ },!alignrelative);
+
+ frame f;
+ pair align=alignrelative ? -Align*dir(g,position)*I : Align;
+ label(f,(0,0),align);
+ pair position=point(g,position);
+ pic.addBox(position,position,min(f),max(f));
+ }
+
+ void write(file file=stdout, suffix suffix=endl) {
+ write(file,"\""+s+"\"");
+ if(!defaultposition) write(file,", position=",position.position);
+ if(!align.default) write(file,", align=");
+ write(file,align);
+ if(p != nullpen) write(file,", pen=",p);
+ if(!defaulttransform)
+ write(file,", transform=",T);
+ if(!defaulttransform3) {
+ write(file,", transform3=",endl);
+ write(file,T3);
+ }
+ write(file,"",suffix);
+ }
+
+ real relative() {
+ return defaultposition ? 0.5 : position.position.x;
+ };
+
+ real relative(path g) {
+ return position.relative ? reltime(g,relative()) : relative();
+ };
+}
+
+Label Label;
+
+void add(frame f, transform t=identity(), Label L)
+{
+ L.out(f,t);
+}
+
+void add(picture pic=currentpicture, Label L)
+{
+ L.out(pic);
+}
+
+Label operator * (transform t, Label L)
+{
+ Label tL=L.copy();
+ tL.align.dir=L.align.dir;
+ tL.transform(t*L.T);
+ return tL;
+}
+
+Label operator * (transform3 t, Label L)
+{
+ Label tL=L.copy(t*L.T3);
+ tL.align.dir=L.align.dir;
+ tL.defaulttransform3=false;
+ return tL;
+}
+
+Label Label(string s, string size="", explicit position position,
+ align align=NoAlign, pen p=nullpen, embed embed=Rotate,
+ filltype filltype=NoFill)
+{
+ Label L;
+ L.init(s,size,position,false,align,p,embed,filltype);
+ return L;
+}
+
+Label Label(string s, string size="", pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill)
+{
+ return Label(s,size,(position) position,align,p,embed,filltype);
+}
+
+Label Label(explicit pair position, align align=NoAlign, pen p=nullpen,
+ embed embed=Rotate, filltype filltype=NoFill)
+{
+ return Label((string) position,position,align,p,embed,filltype);
+}
+
+Label Label(string s="", string size="", align align=NoAlign, pen p=nullpen,
+ embed embed=Rotate, filltype filltype=NoFill)
+{
+ Label L;
+ L.initalign(s,size,align,p,embed,filltype);
+ return L;
+}
+
+Label Label(Label L, align align=NoAlign, pen p=nullpen, embed embed=L.embed,
+ filltype filltype=NoFill)
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ L.embed=embed;
+ L.filltype(filltype);
+ return L;
+}
+
+Label Label(Label L, explicit position position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill)
+{
+ Label L=Label(L,align,p,embed,filltype);
+ L.position(position);
+ return L;
+}
+
+Label Label(Label L, pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill)
+{
+ return Label(L,(position) position,align,p,embed,filltype);
+}
+
+void write(file file=stdout, Label L, suffix suffix=endl)
+{
+ L.write(file,suffix);
+}
+
+void label(frame f, Label L, pair position, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ add(f,Label(L,position,align,p,filltype));
+}
+
+void label(frame f, Label L, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ add(f,Label(L,L.position,align,p,filltype));
+}
+
+void label(picture pic=currentpicture, Label L, pair position,
+ align align=NoAlign, pen p=currentpen, filltype filltype=NoFill)
+{
+ Label L=Label(L,position,align,p,filltype);
+ add(pic,L);
+}
+
+void label(picture pic=currentpicture, Label L, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ label(pic,L,L.position,align,p,filltype);
+}
+
+// Label, but with postscript coords instead of asy
+void label(pair origin, picture pic=currentpicture, Label L, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ picture opic;
+ label(opic,L,L.position,align,p,filltype);
+ add(pic,opic,origin);
+}
+
+void label(picture pic=currentpicture, Label L, explicit path g,
+ align align=NoAlign, pen p=currentpen, filltype filltype=NoFill)
+{
+ Label L=Label(L,align,p,filltype);
+ L.out(pic,g);
+}
+
+void label(picture pic=currentpicture, Label L, explicit guide g,
+ align align=NoAlign, pen p=currentpen, filltype filltype=NoFill)
+{
+ label(pic,L,(path) g,align,p,filltype);
+}
+
+Label operator cast(string s) {return Label(s);}
+
+// A structure that a string, Label, or frame can be cast to.
+struct object {
+ frame f;
+ Label L=Label;
+ path g; // Bounding path
+
+ void operator init(frame f) {
+ this.f=f;
+ g=box(min(f),max(f));
+ }
+
+ void operator init(Label L) {
+ this.L=L.copy();
+ if(L != Label) L.out(f);
+ g=box(min(f),max(f));
+ }
+}
+
+object operator cast(frame f) {
+ return object(f);
+}
+
+object operator cast(Label L)
+{
+ return object(L);
+}
+
+object operator cast(string s)
+{
+ return object(s);
+}
+
+Label operator cast(object F)
+{
+ return F.L;
+}
+
+frame operator cast(object F)
+{
+ return F.f;
+}
+
+object operator * (transform t, explicit object F)
+{
+ object f;
+ f.f=t*F.f;
+ f.L=t*F.L;
+ f.g=t*F.g;
+ return f;
+}
+
+// Returns a copy of object F aligned in the direction align
+object align(object F, pair align)
+{
+ return shift(F.f,align)*F;
+}
+
+void add(picture dest=currentpicture, object F, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ add(dest,F.f,position,group,filltype,above);
+}
+
+// Pack a list of objects into a frame.
+frame pack(pair align=2S ... object inset[])
+{
+ frame F;
+ int n=inset.length;
+ pair z;
+ for (int i=0; i < n; ++i) {
+ add(F,inset[i].f,z);
+ z += align+realmult(unit(align),size(inset[i].f));
+ }
+ return F;
+}
+
+path[] texpath(Label L, bool tex=settings.tex != "none", bool bbox=false)
+{
+ struct stringfont
+ {
+ string s;
+ real fontsize;
+ string font;
+
+ void operator init(Label L)
+ {
+ s=replace(L.s,'\n',' ');
+ fontsize=fontsize(L.p);
+ font=font(L.p);
+ }
+
+ pen pen() {return fontsize(fontsize)+fontcommand(font);}
+ }
+
+ bool lexorder(stringfont a, stringfont b) {
+ return a.s < b.s || (a.s == b.s && (a.fontsize < b.fontsize ||
+ (a.fontsize == b.fontsize &&
+ a.font < b.font)));
+ }
+
+ static stringfont[] stringcache;
+ static path[][] pathcache;
+
+ static stringfont[] stringlist;
+ static bool adjust[];
+
+ path[] G;
+
+ stringfont s=stringfont(L);
+ pen p=s.pen();
+
+ int i=search(stringcache,s,lexorder);
+ if(i == -1 || lexorder(stringcache[i],s)) {
+ int k=search(stringlist,s,lexorder);
+ if(k == -1 || lexorder(stringlist[k],s)) {
+ ++k;
+ stringlist.insert(k,s);
+ // PDF tex engines lose track of the baseline.
+ adjust.insert(k,tex && basealign(L.p) == 1 && pdf());
+ }
+ }
+
+ path[] transform(path[] g, Label L) {
+ if(g.length == 0) return g;
+ pair m=min(g);
+ pair M=max(g);
+ pair dir=rectify(inverse(L.T)*-L.align.dir);
+ if(tex && basealign(L.p) == 1)
+ dir -= (0,(1-dir.y)*m.y/(M.y-m.y));
+ pair a=m+realmult(dir,M-m);
+
+ return shift(L.position+L.align.dir*labelmargin(L.p))*L.T*shift(-a)*g;
+ }
+
+ if(tex && bbox) {
+ frame f;
+ label(f,L);
+ return transform(box(min(f),max(f)),L);
+ }
+
+ if(stringlist.length > 0) {
+ path[][] g;
+ int n=stringlist.length;
+ string[] s=new string[n];
+ pen[] p=new pen[n];
+ for(int i=0; i < n; ++i) {
+ stringfont S=stringlist[i];
+ s[i]=adjust[i] ? "."+S.s : S.s;
+ p[i]=adjust[i] ? S.pen()+basealign : S.pen();
+ }
+
+ g=tex ? _texpath(s,p) : textpath(s,p);
+
+ if(tex)
+ for(int i=0; i < n; ++i)
+ if(adjust[i]) {
+ real y=min(g[i][0]).y;
+ g[i].delete(0);
+ g[i]=shift(0,-y)*g[i];
+ }
+
+
+ for(int i=0; i < stringlist.length; ++i) {
+ stringfont s=stringlist[i];
+ int j=search(stringcache,s,lexorder)+1;
+ stringcache.insert(j,s);
+ pathcache.insert(j,g[i]);
+ }
+ stringlist.delete();
+ adjust.delete();
+ }
+
+ return transform(pathcache[search(stringcache,stringfont(L),lexorder)],L);
+}
+
+texpath=new path[](string s, pen p, bool tex=settings.tex != "none", bool bbox=false)
+{
+ return texpath(Label(s,p));
+};
diff --git a/graphics/asymptote/base/plain_arcs.asy b/graphics/asymptote/base/plain_arcs.asy
new file mode 100644
index 0000000000..140bc3cff1
--- /dev/null
+++ b/graphics/asymptote/base/plain_arcs.asy
@@ -0,0 +1,44 @@
+bool CCW=true;
+bool CW=false;
+
+path circle(pair c, real r)
+{
+ return shift(c)*scale(r)*unitcircle;
+}
+
+path ellipse(pair c, real a, real b)
+{
+ return shift(c)*scale(a,b)*unitcircle;
+}
+
+// return an arc centered at c from pair z1 to z2 (assuming |z2-c|=|z1-c|),
+// drawing in the given direction.
+path arc(pair c, explicit pair z1, explicit pair z2, bool direction=CCW)
+{
+ z1 -= c;
+ real r=abs(z1);
+ z1=unit(z1);
+ z2=unit(z2-c);
+
+ real t1=intersect(unitcircle,(0,0)--2*z1)[0];
+ real t2=intersect(unitcircle,(0,0)--2*z2)[0];
+ static int n=length(unitcircle);
+ if(direction) {
+ if (t1 >= t2) t1 -= n;
+ } else if(t2 >= t1) t2 -= n;
+ return shift(c)*scale(r)*subpath(unitcircle,t1,t2);
+}
+
+// return an arc centered at c with radius r from angle1 to angle2 in degrees,
+// drawing in the given direction.
+path arc(pair c, real r, real angle1, real angle2, bool direction)
+{
+ return arc(c,c+r*dir(angle1),c+r*dir(angle2),direction);
+}
+
+// return an arc centered at c with radius r > 0 from angle1 to angle2 in
+// degrees, drawing counterclockwise if angle2 >= angle1 (otherwise clockwise).
+path arc(pair c, real r, real angle1, real angle2)
+{
+ return arc(c,r,angle1,angle2,angle2 >= angle1 ? CCW : CW);
+}
diff --git a/graphics/asymptote/base/plain_arrows.asy b/graphics/asymptote/base/plain_arrows.asy
new file mode 100644
index 0000000000..d7d79217dd
--- /dev/null
+++ b/graphics/asymptote/base/plain_arrows.asy
@@ -0,0 +1,631 @@
+real arrowlength=0.75cm;
+real arrowfactor=15;
+real arrowangle=15;
+real arcarrowfactor=0.5*arrowfactor;
+real arcarrowangle=2*arrowangle;
+real arrowsizelimit=0.5;
+real arrow2sizelimit=1/3;
+real arrowdir=5;
+real arrowbarb=3;
+real arrowhookfactor=1.5;
+real arrowtexfactor=1;
+
+real barfactor=arrowfactor;
+
+real arrowsize(pen p=currentpen)
+{
+ return arrowfactor*linewidth(p);
+}
+
+real arcarrowsize(pen p=currentpen)
+{
+ return arcarrowfactor*linewidth(p);
+}
+
+real barsize(pen p=currentpen)
+{
+ return barfactor*linewidth(p);
+}
+
+struct arrowhead
+{
+ path head(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle);
+ real size(pen p)=arrowsize;
+ real arcsize(pen p)=arcarrowsize;
+ filltype defaultfilltype(pen) {return FillDraw;}
+}
+
+real[] arrowbasepoints(path base, path left, path right, real default=0)
+{
+ real[][] Tl=transpose(intersections(left,base));
+ real[][] Tr=transpose(intersections(right,base));
+ return new real[] {Tl.length > 0 ? Tl[0][0] : default,
+ Tr.length > 0 ? Tr[0][0] : default};
+}
+
+path arrowbase(path r, pair y, real t, real size)
+{
+ pair perp=2*size*I*dir(r,t);
+ return size == 0 ? y : y+perp--y-perp;
+}
+
+arrowhead DefaultHead;
+DefaultHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ if(size == 0) size=DefaultHead.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ path base=arrowbase(r,y,t,size);
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ pair denom=point(right,T[1])-y;
+ real factor=denom != 0 ? length((point(left,T[0])-y)/denom) : 1;
+ path left=rotate(-angle*factor,x)*r;
+ path right=rotate(angle*factor,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ return subpath(left,0,T[0])--subpath(right,T[1],0)&cycle;
+};
+
+arrowhead SimpleHead;
+SimpleHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ if(size == 0) size=SimpleHead.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle,x)*r;
+ return subpath(left,t,0)--subpath(right,0,t);
+};
+
+arrowhead HookHead(real dir=arrowdir, real barb=arrowbarb)
+{
+ arrowhead a;
+ a.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle)
+ {
+ if(size == 0) size=a.size(p);
+ angle=min(angle*arrowhookfactor,45);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ path base=arrowbase(r,y,t,size);
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle,x)*r;
+ real[] T=arrowbasepoints(base,left,right,1);
+ pair denom=point(right,T[1])-y;
+ real factor=denom != 0 ? length((point(left,T[0])-y)/denom) : 1;
+ path left=rotate(-angle*factor,x)*r;
+ path right=rotate(angle*factor,x)*r;
+ real[] T=arrowbasepoints(base,left,right,1);
+ left=subpath(left,0,T[0]);
+ right=subpath(right,T[1],0);
+ pair pl0=point(left,0), pl1=relpoint(left,1);
+ pair pr0=relpoint(right,0), pr1=relpoint(right,1);
+ pair M=(pl1+pr0)/2;
+ pair v=barb*unit(M-pl0);
+ pl1=pl1+v; pr0=pr0+v;
+ left=pl0{dir(-dir+degrees(M-pl0,false))}..pl1--M;
+ right=M--pr0..pr1{dir(dir+degrees(pr1-M,false))};
+ return left--right&cycle;
+ };
+ return a;
+}
+arrowhead HookHead=HookHead();
+
+arrowhead TeXHead;
+TeXHead.size=new real(pen p)
+{
+ static real hcoef=2.1; // 84/40=abs(base-hint)/base_height
+ return hcoef*arrowtexfactor*linewidth(p);
+};
+TeXHead.arcsize=TeXHead.size;
+
+TeXHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ static real wcoef=1/84; // 1/abs(base-hint)
+ static path texhead=scale(wcoef)*
+ ((0,20) .. controls (-75,75) and (-108,158) ..
+ (-108,166) .. controls (-108,175) and (-100,178) ..
+ (-93,178) .. controls (-82,178) and (-80,173) ..
+ (-77,168) .. controls (-62,134) and (-30,61) ..
+ (70,14) .. controls (82,8) and (84,7) ..
+ (84,0) .. controls (84,-7) and (82,-8) ..
+ (70,-14) .. controls (-30,-61) and (-62,-134) ..
+ (-77,-168) .. controls (-80,-173) and (-82,-178) ..
+ (-93,-178) .. controls (-100,-178) and (-108,-175)..
+ (-108,-166).. controls (-108,-158) and (-75,-75) ..
+ (0,-20)--cycle);
+ if(size == 0) size=TeXHead.size(p);
+ path gp=scale(size)*texhead;
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair y=point(r,arctime(r,size));
+ return shift(y)*rotate(degrees(-dir(r,arctime(r,0.5*size))))*gp;
+};
+TeXHead.defaultfilltype=new filltype(pen p) {return Fill(p);};
+
+private real position(position position, real size, path g, bool center)
+{
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) {
+ position *= arclength(g);
+ if(center) position += 0.5*size;
+ position=arctime(g,position);
+ } else if(center)
+ position=arctime(g,arclength(subpath(g,0,position))+0.5*size);
+ return position;
+}
+
+void drawarrow(frame f, arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle,
+ filltype filltype=null,
+ position position=EndPoint, bool forwards=true,
+ margin margin=NoMargin, bool center=false)
+{
+ if(size == 0) size=arrowhead.size(p);
+ if(filltype == null) filltype=arrowhead.defaultfilltype(p);
+ size=min(arrowsizelimit*arclength(g),size);
+ real position=position(position,size,g,center);
+
+ g=margin(g,p).g;
+ int L=length(g);
+ if(!forwards) {
+ g=reverse(g);
+ position=L-position;
+ }
+ path r=subpath(g,position,0);
+ size=min(arrowsizelimit*arclength(r),size);
+ path head=arrowhead.head(g,position,p,size,angle);
+ bool endpoint=position > L-sqrtEpsilon;
+ if(cyclic(head) && (filltype == NoFill || endpoint)) {
+ if(position > 0)
+ draw(f,subpath(r,arctime(r,size),length(r)),p);
+ if(!endpoint)
+ draw(f,subpath(g,position,L),p);
+ } else draw(f,g,p);
+ filltype.fill(f,head,p+solid);
+}
+
+void drawarrow2(frame f, arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ margin margin=NoMargin)
+{
+ if(size == 0) size=arrowhead.size(p);
+ if(filltype == null) filltype=arrowhead.defaultfilltype(p);
+ g=margin(g,p).g;
+ size=min(arrow2sizelimit*arclength(g),size);
+
+ path r=reverse(g);
+ int L=length(g);
+ path head=arrowhead.head(g,L,p,size,angle);
+ path tail=arrowhead.head(r,L,p,size,angle);
+ if(cyclic(head))
+ draw(f,subpath(r,arctime(r,size),L-arctime(g,size)),p);
+ else draw(f,g,p);
+ filltype.fill(f,head,p+solid);
+ filltype.fill(f,tail,p+solid);
+}
+
+// Add to picture an estimate of the bounding box contribution of arrowhead
+// using the local slope at endpoint and ignoring margin.
+void addArrow(picture pic, arrowhead arrowhead, path g, pen p, real size,
+ real angle, filltype filltype, real position)
+{
+ if(filltype == null) filltype=arrowhead.defaultfilltype(p);
+ pair z=point(g,position);
+ path g=z-(size+linewidth(p))*dir(g,position)--z;
+ frame f;
+ filltype.fill(f,arrowhead.head(g,position,p,size,angle),p);
+ pic.addBox(z,z,min(f)-z,max(f)-z);
+}
+
+picture arrow(arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ position position=EndPoint, bool forwards=true,
+ margin margin=NoMargin, bool center=false)
+{
+ if(size == 0) size=arrowhead.size(p);
+ picture pic;
+ pic.add(new void(frame f, transform t) {
+ drawarrow(f,arrowhead,t*g,p,size,angle,filltype,position,forwards,margin,
+ center);
+ });
+
+ pic.addPath(g,p);
+
+ real position=position(position,size,g,center);
+ path G;
+ if(!forwards) {
+ G=reverse(g);
+ position=length(g)-position;
+ } else G=g;
+ addArrow(pic,arrowhead,G,p,size,angle,filltype,position);
+
+ return pic;
+}
+
+picture arrow2(arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ margin margin=NoMargin)
+{
+ if(size == 0) size=arrowhead.size(p);
+ picture pic;
+ pic.add(new void(frame f, transform t) {
+ drawarrow2(f,arrowhead,t*g,p,size,angle,filltype,margin);
+ });
+
+ pic.addPath(g,p);
+
+ int L=length(g);
+ addArrow(pic,arrowhead,g,p,size,angle,filltype,L);
+ addArrow(pic,arrowhead,reverse(g),p,size,angle,filltype,L);
+
+ return pic;
+}
+
+void bar(picture pic, pair a, pair d, pen p=currentpen)
+{
+ picture opic;
+ Draw(opic,-0.5d--0.5d,p+solid);
+ add(pic,opic,a);
+}
+
+picture bar(pair a, pair d, pen p=currentpen)
+{
+ picture pic;
+ bar(pic,a,d,p);
+ return pic;
+}
+
+typedef bool arrowbar(picture, path, pen, margin);
+
+bool Blank(picture, path, pen, margin)
+{
+ return false;
+}
+
+bool None(picture, path, pen, margin)
+{
+ return true;
+}
+
+arrowbar BeginArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=BeginPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,forwards=false,
+ margin));
+ return false;
+ };
+}
+
+arrowbar Arrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,margin));
+ return false;
+ };
+}
+
+arrowbar EndArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint)=Arrow;
+
+arrowbar MidArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle, filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,MidPoint,margin,
+ center=true));
+ return false;
+ };
+}
+
+arrowbar Arrows(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow2(arrowhead,g,p,size,angle,filltype,margin));
+ return false;
+ };
+}
+
+arrowbar BeginArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=BeginPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,
+ forwards=false,margin));
+ return false;
+ };
+}
+
+arrowbar ArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=EndPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,margin));
+ return false;
+ };
+}
+
+arrowbar EndArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null,
+ position position=EndPoint)=ArcArrow;
+
+arrowbar MidArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,MidPoint,margin,
+ center=true));
+ return false;
+ };
+}
+
+arrowbar ArcArrows(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow2(arrowhead,g,p,size,angle,filltype,margin));
+ return false;
+ };
+}
+
+arrowbar BeginBar(real size=0)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? barsize(p) : size;
+ bar(pic,point(g,0),size*dir(g,0)*I,p);
+ return true;
+ };
+}
+
+arrowbar Bar(real size=0)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ int L=length(g);
+ real size=size == 0 ? barsize(p) : size;
+ bar(pic,point(g,L),size*dir(g,L)*I,p);
+ return true;
+ };
+}
+
+arrowbar EndBar(real size=0)=Bar;
+
+arrowbar Bars(real size=0)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? barsize(p) : size;
+ BeginBar(size)(pic,g,p,margin);
+ EndBar(size)(pic,g,p,margin);
+ return true;
+ };
+}
+
+arrowbar BeginArrow=BeginArrow(),
+MidArrow=MidArrow(),
+Arrow=Arrow(),
+EndArrow=Arrow(),
+Arrows=Arrows(),
+BeginArcArrow=BeginArcArrow(),
+MidArcArrow=MidArcArrow(),
+ArcArrow=ArcArrow(),
+EndArcArrow=ArcArrow(),
+ArcArrows=ArcArrows(),
+BeginBar=BeginBar(),
+Bar=Bar(),
+EndBar=Bar(),
+Bars=Bars();
+
+void draw(frame f, path g, pen p=currentpen, arrowbar arrow)
+{
+ picture pic;
+ if(arrow(pic,g,p,NoMargin))
+ draw(f,g,p);
+ add(f,pic.fit());
+}
+
+void draw(picture pic=currentpicture, Label L=null, path g,
+ align align=NoAlign, pen p=currentpen, arrowbar arrow=None,
+ arrowbar bar=None, margin margin=NoMargin, Label legend=null,
+ marker marker=nomarker)
+{
+ // These if statements are ordered in such a way that the most common case
+ // (with just a path and a pen) executes the least bytecode.
+ if (marker == nomarker)
+ {
+ if (arrow == None && bar == None)
+ {
+ if (margin == NoMargin && size(nib(p)) == 0)
+ {
+ pic.addExactAbove(
+ new void(frame f, transform t, transform T, pair, pair) {
+ _draw(f,t*T*g,p);
+ });
+ pic.addPath(g,p);
+
+ // Jumping over else clauses takes time, so test if we can return
+ // here.
+ if (L == null && legend == null)
+ return;
+ }
+ else // With margin or polygonal pen.
+ {
+ _draw(pic, g, p, margin);
+ }
+ }
+ else /* arrow or bar */
+ {
+ // Note we are using & instead of && as both arrow and bar need to be
+ // called.
+ if (arrow(pic, g, p, margin) & bar(pic, g, p, margin))
+ _draw(pic, g, p, margin);
+ }
+
+ if(L != null && L.s != "") {
+ L=L.copy();
+ L.align(align);
+ L.p(p);
+ L.out(pic,g);
+ }
+
+ if(legend != null && legend.s != "") {
+ legend.p(p);
+ pic.legend.push(Legend(legend.s,legend.p,p,marker.f,marker.above));
+ }
+ }
+ else /* marker != nomarker */
+ {
+ if(marker != nomarker && !marker.above) marker.mark(pic,g);
+
+ // Note we are using & instead of && as both arrow and bar need to be
+ // called.
+ if ((arrow == None || arrow(pic, g, p, margin)) &
+ (bar == None || bar(pic, g, p, margin)))
+ {
+ _draw(pic, g, p, margin);
+ }
+
+ if(L != null && L.s != "") {
+ L=L.copy();
+ L.align(align);
+ L.p(p);
+ L.out(pic,g);
+ }
+
+ if(legend != null && legend.s != "") {
+ legend.p(p);
+ pic.legend.push(Legend(legend.s,legend.p,p,marker.f,marker.above));
+ }
+
+ if(marker != nomarker && marker.above) marker.mark(pic,g);
+ }
+}
+
+// Draw a fixed-size line about the user-coordinate 'origin'.
+void draw(pair origin, picture pic=currentpicture, Label L=null, path g,
+ align align=NoAlign, pen p=currentpen, arrowbar arrow=None,
+ arrowbar bar=None, margin margin=NoMargin, Label legend=null,
+ marker marker=nomarker)
+{
+ picture opic;
+ draw(opic,L,g,align,p,arrow,bar,margin,legend,marker);
+ add(pic,opic,origin);
+}
+
+void draw(picture pic=currentpicture, explicit path[] g, pen p=currentpen,
+ Label legend=null, marker marker=nomarker)
+{
+ // This could be optimized to size and draw the entire array as a batch.
+ for(int i=0; i < g.length-1; ++i)
+ draw(pic,g[i],p,marker);
+ if(g.length > 0) draw(pic,g[g.length-1],p,legend,marker);
+}
+
+void draw(picture pic=currentpicture, guide[] g, pen p=currentpen,
+ Label legend=null, marker marker=nomarker)
+{
+ draw(pic,(path[]) g,p,legend,marker);
+}
+
+void draw(pair origin, picture pic=currentpicture, explicit path[] g,
+ pen p=currentpen, Label legend=null, marker marker=nomarker)
+{
+ picture opic;
+ draw(opic,g,p,legend,marker);
+ add(pic,opic,origin);
+}
+
+void draw(pair origin, picture pic=currentpicture, guide[] g, pen p=currentpen,
+ Label legend=null, marker marker=nomarker)
+{
+ draw(origin,pic,(path[]) g,p,legend,marker);
+}
+
+// Align an arrow pointing to b from the direction dir. The arrow is
+// 'length' PostScript units long.
+void arrow(picture pic=currentpicture, Label L=null, pair b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar arrow=Arrow, margin margin=EndMargin)
+{
+ if(L != null && L.s != "") {
+ L=L.copy();
+ if(L.defaultposition) L.position(0);
+ L.align(L.align,dir);
+ L.p(p);
+ }
+ marginT margin=margin(b--b,p); // Extract margin.begin and margin.end
+ pair a=(margin.begin+length+margin.end)*unit(dir);
+ draw(b,pic,L,a--(0,0),align,p,arrow,margin);
+}
+
+// Fit an array of pictures simultaneously using the sizing of picture all.
+frame[] fit2(picture[] pictures, picture all)
+{
+ frame[] out;
+ if(!all.empty2()) {
+ transform t=all.calculateTransform();
+ pair m=all.min(t);
+ pair M=all.max(t);
+ for(picture pic : pictures) {
+ frame f=pic.fit(t);
+ draw(f,m,nullpen);
+ draw(f,M,nullpen);
+ out.push(f);
+ }
+ }
+ return out;
+}
+
+// Fit an array of pictures simultaneously using the size of the first picture.
+// TODO: Remove unused arguments.
+frame[] fit(string prefix="", picture[] pictures, string format="",
+ bool view=true, string options="", string script="",
+ projection P=currentprojection)
+{
+ if(pictures.length == 0)
+ return new frame[];
+
+ picture all;
+ size(all,pictures[0]);
+ for(picture pic : pictures)
+ add(all,pic);
+
+ return fit2(pictures,all);
+}
diff --git a/graphics/asymptote/base/plain_bounds.asy b/graphics/asymptote/base/plain_bounds.asy
new file mode 100644
index 0000000000..b74a6ceee6
--- /dev/null
+++ b/graphics/asymptote/base/plain_bounds.asy
@@ -0,0 +1,788 @@
+include plain_scaling;
+
+// After a transformation, produce new coordinate bounds. For paths that
+// have been added, this is only an approximation since it takes the bounds of
+// their transformed bounding box.
+private void addTransformedCoords(coords2 dest, transform t,
+ coords2 point, coords2 min, coords2 max)
+{
+ dest.push(t, point, point);
+
+ // Add in all 4 corner coords, to properly size rectangular pictures.
+ dest.push(t,min,min);
+ dest.push(t,min,max);
+ dest.push(t,max,min);
+ dest.push(t,max,max);
+}
+
+// Adds another sizing restriction to the coordinates, but only if it is
+// maximal, that is, if under some scaling, this coordinate could be the
+// largest.
+private void addIfMaximal(coord[] coords, real user, real truesize) {
+ // TODO: Test promoting coordinates for efficiency.
+
+ for (coord c : coords)
+ if (user <= c.user && truesize <= c.truesize)
+ // Not maximal.
+ return;
+
+ // The coordinate is not dominated by any existing extreme, so it is
+ // maximal and will be added, but first remove any coords it now dominates.
+ int i = 0;
+ while (i < coords.length) {
+ coord c = coords[i];
+ if (c.user <= user && c.truesize <= truesize)
+ coords.delete(i);
+ else
+ ++i;
+ }
+
+ // Add the coordinate to the extremes.
+ coords.push(coord.build(user, truesize));
+}
+
+private void addIfMaximal(coord[] dest, coord[] src)
+{
+ // This may be inefficient, as it rebuilds the coord struct when adding it.
+ for (coord c : src)
+ addIfMaximal(dest, c.user, c.truesize);
+}
+
+// Same as addIfMaximal, but testing for minimal coords.
+private void addIfMinimal(coord[] coords, real user, real truesize) {
+ for (coord c : coords)
+ if (user >= c.user && truesize >= c.truesize)
+ return;
+
+ int i = 0;
+ while (i < coords.length) {
+ coord c = coords[i];
+ if (c.user >= user && c.truesize >= truesize)
+ coords.delete(i);
+ else
+ ++i;
+ }
+
+ coords.push(coord.build(user, truesize));
+}
+
+private void addIfMinimal(coord[] dest, coord[] src)
+{
+ for (coord c : src)
+ addIfMinimal(dest, c.user, c.truesize);
+}
+
+// This stores a list of sizing bounds for picture data. If the object is
+// frozen, then it cannot be modified further, and therefore can be safely
+// passed by reference and stored in the sizing data for multiple pictures.
+private struct freezableBounds {
+ restricted bool frozen = false;
+ void freeze() {
+ frozen = true;
+ }
+
+ // Optional links to further (frozen) sizing data.
+ private freezableBounds[] links;
+
+ // Links to (frozen) sizing data that is transformed when added here.
+ private static struct transformedBounds {
+ transform t;
+ freezableBounds link;
+ };
+ private transformedBounds[] tlinks;
+
+ // The sizing data. It cannot be modified once this object is frozen.
+ private coords2 point, min, max;
+
+ // A bound represented by a path. Using the path instead of the bounding
+ // box means it will be accurate after a transformation by coordinates.
+ private path[] pathBounds;
+
+ // A bound represented by a path and a pen.
+ // As often many paths use the same pen, we store an array of paths.
+ private static struct pathpen {
+ path[] g; pen p;
+
+ void operator init(path g, pen p) {
+ this.g.push(g);
+ this.p = p;
+ }
+ }
+ private static pathpen operator *(transform t, pathpen pp) {
+ // Should the pen be transformed?
+ pathpen newpp;
+ for (path g : pp.g)
+ newpp.g.push(t*g);
+ newpp.p = pp.p;
+ return newpp;
+ }
+
+ // WARNING: Due to crazy optimizations, if this array is changed between an
+ // empty and non-empty state, the assignment of a method to
+ // addPath(path,pen) must also change.
+ private pathpen[] pathpenBounds;
+
+ // Once frozen, the sizing is immutable, and therefore we can compute and
+ // store the extremal coordinates.
+ public static struct extremes {
+ coord[] left, bottom, right, top;
+
+ void operator init(coord[] left, coord[] bottom,
+ coord[] right, coord[] top) {
+ this.left = left;
+ this.bottom = bottom;
+ this.right = right;
+ this.top = top;
+ }
+
+ }
+ private static void addMaxToExtremes(extremes e, pair user, pair truesize) {
+ addIfMaximal(e.right, user.x, truesize.x);
+ addIfMaximal(e.top, user.y, truesize.y);
+ }
+ private static void addMinToExtremes(extremes e, pair user, pair truesize) {
+ addIfMinimal(e.left, user.x, truesize.x);
+ addIfMinimal(e.bottom, user.y, truesize.y);
+ }
+ private static void addMaxToExtremes(extremes e, coords2 coords) {
+ addIfMaximal(e.right, coords.x);
+ addIfMaximal(e.top, coords.y);
+ }
+ private static void addMinToExtremes(extremes e, coords2 coords) {
+ addIfMinimal(e.left, coords.x);
+ addIfMinimal(e.bottom, coords.y);
+ }
+
+ private extremes cachedExtremes = null;
+
+ // Once frozen, getMutable returns a new object based on this one, which can
+ // be modified.
+ freezableBounds getMutable() {
+ assert(frozen);
+ var f = new freezableBounds;
+ f.links.push(this);
+ return f;
+ }
+
+ freezableBounds transformed(transform t) {
+ // Freeze these bounds, as we are storing a reference to them.
+ freeze();
+
+ var tlink = new transformedBounds;
+ tlink.t = t;
+ tlink.link = this;
+
+ var b = new freezableBounds;
+ b.tlinks.push(tlink);
+
+ return b;
+ }
+
+ void append(freezableBounds b) {
+ // Check that we can modify the object.
+ assert(!frozen);
+
+ //TODO: If b is "small", ie. a single tlink or cliplink, just copy the
+ //link.
+
+ // As we only reference b, we must freeze it to ensure it does not change.
+ b.freeze();
+ links.push(b);
+ }
+
+ void addPoint(pair user, pair truesize) {
+ assert(!frozen);
+ point.push(user, truesize);
+ }
+
+ void addBox(pair userMin, pair userMax, pair trueMin, pair trueMax) {
+ assert(!frozen);
+ this.min.push(userMin, trueMin);
+ this.max.push(userMax, trueMax);
+ }
+
+ void addPath(path g) {
+ // This, and other asserts have been removed to speed things up slightly.
+ //assert(!frozen);
+ this.pathBounds.push(g);
+ }
+
+ void addPath(path[] g) {
+ //assert(!frozen);
+ this.pathBounds.append(g);
+ }
+
+ // To squeeze out a bit more performance, this method is either assigned
+ // addPathToNonEmptyArray or addPathToEmptyArray depending on the state of
+ // the pathpenBounds array.
+ void addPath(path g, pen p);
+
+ private void addPathToNonEmptyArray(path g, pen p) {
+ //assert(!frozen);
+ //assert(!pathpenBounds.empty());
+ var pp = pathpenBounds[0];
+
+ // Test if the pens are equal or have the same bounds.
+ if (pp.p == p || (min(pp.p) == min(p) && max(pp.p) == max(p))) {
+ // If this path has the same pen as the last one, just add it to the
+ // array corresponding to that pen.
+ pp.g.push(g);
+ }
+ else {
+ // A different pen. Start a new bound and put it on the front. Put
+ // the old bound at the end of the array.
+ pathpenBounds[0] = pathpen(g,p);
+ pathpenBounds.push(pp);
+ }
+ }
+ void addPathToEmptyArray(path g, pen p) {
+ //assert(!frozen);
+ //assert(pathpenBounds.empty());
+
+ pathpenBounds.push(pathpen(g,p));
+ addPath = addPathToNonEmptyArray;
+ }
+
+ // Initial setting for addPath.
+ addPath = addPathToEmptyArray;
+
+ // Transform the sizing info by t then add the result to the coords
+ // structure.
+ private void accumulateCoords(transform t, coords2 coords) {
+ for (var link : links)
+ link.accumulateCoords(t, coords);
+
+ for (var tlink : tlinks)
+ tlink.link.accumulateCoords(t*tlink.t, coords);
+
+ addTransformedCoords(coords, t, this.point, this.min, this.max);
+
+ for (var g : pathBounds) {
+ g = t*g;
+ coords.push(min(g), (0,0));
+ coords.push(max(g), (0,0));
+ }
+
+ for (var pp: pathpenBounds) {
+ pair pm = min(pp.p), pM = max(pp.p);
+ for (var g : pp.g) {
+ g = t*g;
+ coords.push(min(g), pm);
+ coords.push(max(g), pM);
+ }
+ }
+ }
+
+ // Add all of the sizing info to the given coords structure.
+ private void accumulateCoords(coords2 coords) {
+ for (var link : links)
+ link.accumulateCoords(coords);
+
+ for (var tlink : tlinks)
+ tlink.link.accumulateCoords(tlink.t, coords);
+
+ coords.append(this.point);
+ coords.append(this.min);
+ coords.append(this.max);
+
+ for (var g : pathBounds) {
+ coords.push(min(g), (0,0));
+ coords.push(max(g), (0,0));
+ }
+
+ for (var pp: pathpenBounds) {
+ pair pm = min(pp.p), pM = max(pp.p);
+ for (var g : pp.g) {
+ coords.push(min(g), pm);
+ coords.push(max(g), pM);
+ }
+ }
+ }
+
+ // Returns all of the coords that this sizing data represents.
+ private coords2 allCoords() {
+ coords2 coords;
+ accumulateCoords(coords);
+ return coords;
+ }
+
+ private void addLocalsToExtremes(transform t, extremes e) {
+ coords2 coords;
+ addTransformedCoords(coords, t, this.point, this.min, this.max);
+ addMinToExtremes(e, coords);
+ addMaxToExtremes(e, coords);
+
+ if (pathBounds.length > 0) {
+ addMinToExtremes(e, minAfterTransform(t, pathBounds), (0,0));
+ addMaxToExtremes(e, maxAfterTransform(t, pathBounds), (0,0));
+ }
+
+ for (var pp : pathpenBounds) {
+ if (pp.g.length > 0) {
+ addMinToExtremes(e, minAfterTransform(t, pp.g), min(pp.p));
+ addMaxToExtremes(e, maxAfterTransform(t, pp.g), max(pp.p));
+ }
+ }
+ }
+
+ private void addToExtremes(transform t, extremes e) {
+ for (var link : links)
+ link.addToExtremes(t, e);
+
+ for (var tlink : tlinks)
+ tlink.link.addToExtremes(t*tlink.t, e);
+
+ addLocalsToExtremes(t, e);
+ }
+
+ private void addLocalsToExtremes(extremes e) {
+ addMinToExtremes(e, point);
+ addMaxToExtremes(e, point);
+ addMinToExtremes(e, min);
+ addMaxToExtremes(e, max);
+
+ if (pathBounds.length > 0) {
+ addMinToExtremes(e, min(pathBounds), (0,0));
+ addMaxToExtremes(e, max(pathBounds), (0,0));
+ }
+
+ for(var pp : pathpenBounds) {
+ pair m=min(pp.p);
+ pair M=max(pp.p);
+ for(path gg : pp.g) {
+ if (size(gg) > 0) {
+ addMinToExtremes(e,min(gg),m);
+ addMaxToExtremes(e,max(gg),M);
+ }
+ }
+ }
+ }
+
+ private void addToExtremes(extremes e) {
+ for (var link : links)
+ link.addToExtremes(e);
+
+ for (var tlink : tlinks)
+ tlink.link.addToExtremes(tlink.t, e);
+
+ addLocalsToExtremes(e);
+ }
+
+ private static void write(extremes e) {
+ static void write(coord[] coords) {
+ for (coord c : coords)
+ write(" " + (string)c.user + " u + " + (string)c.truesize);
+ }
+ write("left:");
+ write(e.left);
+ write("bottom:");
+ write(e.bottom);
+ write("right:");
+ write(e.right);
+ write("top:");
+ write(e.top);
+ }
+
+ // Returns the extremal coordinates of the sizing data.
+ public extremes extremes() {
+ if (cachedExtremes == null) {
+ freeze();
+
+ extremes e;
+ addToExtremes(e);
+ cachedExtremes = e;
+ }
+
+ return cachedExtremes;
+ }
+
+ // Helper functions for computing the usersize bounds. usermin and usermax
+ // would be easily computable from extremes, except that the picture
+ // interface actually allows calls that manually change the usermin and
+ // usermax values. Therefore, we have to compute these values separately.
+ private static struct userbounds {
+ bool areSet=false;
+ pair min;
+ pair max;
+ }
+ private static struct boundsAccumulator {
+ pair[] mins;
+ pair[] maxs;
+
+ void push(pair m, pair M) {
+ mins.push(m);
+ maxs.push(M);
+ }
+
+ void push(userbounds b) {
+ if (b.areSet)
+ push(b.min, b.max);
+ }
+
+ void push(transform t, userbounds b) {
+ if (b.areSet) {
+ pair[] box = { t*(b.min.x,b.max.y), t*b.max,
+ t*b.min, t*(b.max.x,b.min.y) };
+ for (var z : box)
+ push(z,z);
+ }
+ }
+
+ void pushUserCoords(coords2 min, coords2 max) {
+ int n = min.x.length;
+ assert(min.y.length == n);
+ assert(max.x.length == n);
+ assert(max.y.length == n);
+
+ for (int i = 0; i < n; ++i)
+ push((min.x[i].user, min.y[i].user),
+ (max.x[i].user, max.y[i].user));
+ }
+
+ userbounds collapse() {
+ userbounds b;
+ if (mins.length > 0) {
+ b.areSet = true;
+ b.min = minbound(mins);
+ b.max = maxbound(maxs);
+ }
+ else {
+ b.areSet = false;
+ }
+ return b;
+ }
+ }
+
+ // The user bounds already calculated for this data.
+ private userbounds storedUserBounds = null;
+
+ private void accumulateUserBounds(boundsAccumulator acc)
+ {
+ if (storedUserBounds != null) {
+ assert(frozen);
+ acc.push(storedUserBounds);
+ } else {
+ acc.pushUserCoords(point, point);
+ acc.pushUserCoords(min, max);
+ if (pathBounds.length > 0)
+ acc.push(min(pathBounds), max(pathBounds));
+ for (var pp : pathpenBounds)
+ if(size(pp.g) > 0)
+ acc.push(min(pp.g), max(pp.g));
+ for (var link : links)
+ link.accumulateUserBounds(acc);
+
+ // Transforms are handled as they were in the old system.
+ for (var tlink : tlinks) {
+ boundsAccumulator tacc;
+ tlink.link.accumulateUserBounds(tacc);
+ acc.push(tlink.t, tacc.collapse());
+ }
+ }
+ }
+
+ private void computeUserBounds() {
+ freeze();
+ boundsAccumulator acc;
+ accumulateUserBounds(acc);
+ storedUserBounds = acc.collapse();
+ }
+
+ private userbounds userBounds() {
+ if (storedUserBounds == null)
+ computeUserBounds();
+
+ assert(storedUserBounds != null);
+ return storedUserBounds;
+ }
+
+ // userMin/userMax returns the minimal/maximal userspace coordinate of the
+ // sizing data. As coordinates for objects such as labels can have
+ // significant truesize dimensions, this userMin/userMax values may not
+ // correspond closely to the end of the screen, and are of limited use.
+ // userSetx and userSety determine if there is sizing data in order to even
+ // have userMin/userMax defined.
+ public bool userBoundsAreSet() {
+ return userBounds().areSet;
+ }
+
+ public pair userMin() {
+ return userBounds().min;
+ }
+ public pair userMax() {
+ return userBounds().max;
+ }
+
+ // To override the true userMin and userMax bounds, first compute the
+ // userBounds as they should be at this point, then change the values.
+ public void alterUserBound(string which, real val) {
+ // We are changing the bounds data, so it cannot be frozen yet. After the
+ // user bounds are set, however, the sizing data cannot change, so it will
+ // be frozen.
+ assert(!frozen);
+ computeUserBounds();
+ assert(frozen);
+
+ var b = storedUserBounds;
+ if (which == "minx")
+ b.min = (val, b.min.y);
+ else if (which == "miny")
+ b.min = (b.min.x, val);
+ else if (which == "maxx")
+ b.max = (val, b.max.y);
+ else {
+ assert(which == "maxy");
+ b.max = (b.max.x, val);
+ }
+ }
+
+ // A temporary measure. Stuffs all of the data from the links and paths
+ // into the coords.
+ private void flatten() {
+ assert(!frozen);
+
+ // First, compute the user bounds, taking into account any manual
+ // alterations.
+ computeUserBounds();
+
+ // Calculate all coordinates.
+ coords2 coords = allCoords();
+
+ // Erase all the old data.
+ point.erase();
+ min.erase();
+ max.erase();
+ pathBounds.delete();
+ pathpenBounds.delete();
+ addPath = addPathToEmptyArray;
+ links.delete();
+ tlinks.delete();
+
+ // Put all of the coordinates into point.
+ point = coords;
+ }
+
+ void xclip(real Min, real Max) {
+ assert(!frozen);
+ flatten();
+ point.xclip(Min,Max);
+ min.xclip(Min,Max);
+ max.xclip(Min,Max);
+
+ // Cap the userBounds.
+ userbounds b = storedUserBounds;
+ b.min = (max(Min, b.min.x), b.min.y);
+ b.max = (min(Max, b.max.x), b.max.y);
+ }
+
+ void yclip(real Min, real Max) {
+ assert(!frozen);
+ flatten();
+ point.yclip(Min,Max);
+ min.yclip(Min,Max);
+ max.yclip(Min,Max);
+
+ // Cap the userBounds.
+ userbounds b = storedUserBounds;
+ b.min = (b.min.x, max(Min, b.min.y));
+ b.max = (b.max.x, min(Max, b.max.y));
+ }
+
+ // Calculate the min for the final frame, given the coordinate transform.
+ pair min(transform t) {
+ extremes e = extremes();
+ if (e.left.length == 0)
+ return 0;
+
+ pair a=t*(1,1)-t*(0,0), b=t*(0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+
+ return (min(infinity, xs, e.left), min(infinity, ys, e.bottom));
+ }
+
+ // Calculate the max for the final frame, given the coordinate transform.
+ pair max(transform t) {
+ extremes e = extremes();
+ if (e.right.length == 0)
+ return 0;
+
+ pair a=t*(1,1)-t*(0,0), b=t*(0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+
+ return (max(-infinity, xs, e.right), max(-infinity, ys, e.top));
+ }
+
+ // Returns the transform for turning user-space pairs into true-space pairs.
+ transform scaling(real xsize, real ysize,
+ real xunitsize, real yunitsize,
+ bool keepAspect, bool warn) {
+ if(xsize == 0 && xunitsize == 0 && ysize == 0 && yunitsize == 0)
+ return identity();
+
+ // Get the extremal coordinates.
+ extremes e = extremes();
+
+ real sx;
+ if(xunitsize == 0) {
+ if(xsize != 0) sx=calculateScaling("x",e.left,e.right,xsize,warn);
+ } else sx=xunitsize;
+
+ /* Possible alternative code :
+ real sx = xunitsize != 0 ? xunitsize :
+ xsize != 0 ? calculateScaling("x", Coords.x, xsize, warn) :
+ 0; */
+
+ real sy;
+ if(yunitsize == 0) {
+ if(ysize != 0) sy=calculateScaling("y",e.bottom,e.top,ysize,warn);
+ } else sy=yunitsize;
+
+ if(sx == 0) {
+ sx=sy;
+ if(sx == 0)
+ return identity();
+ } else if(sy == 0) sy=sx;
+
+
+ if(keepAspect && (xunitsize == 0 || yunitsize == 0))
+ return scale(min(sx,sy));
+ else
+ return scale(sx,sy);
+ }
+}
+
+struct bounds {
+ private var base = new freezableBounds;
+
+ // We should probably put this back into picture.
+ bool exact = true;
+
+ // Called just before modifying the sizing data. It ensures base is
+ // non-frozen.
+ // Note that this is manually inlined for speed reasons in a couple often
+ // called methods below.
+ private void makeMutable() {
+ if (base.frozen)
+ base = base.getMutable();
+ //assert(!base.frozen); // Disabled for speed reasons.
+ }
+
+ void erase() {
+ // Just discard the old bounds.
+ base = new freezableBounds;
+
+ // We don't reset the 'exact' field, for backward compatibility.
+ }
+
+ bounds copy() {
+ // Freeze the underlying bounds and make a shallow copy.
+ base.freeze();
+
+ var b = new bounds;
+ b.base = this.base;
+ b.exact = this.exact;
+ return b;
+ }
+
+ bounds transformed(transform t) {
+ var b = new bounds;
+ b.base = base.transformed(t);
+ b.exact = this.exact;
+ return b;
+ }
+
+ void append(bounds b) {
+ makeMutable();
+ base.append(b.base);
+ }
+
+ void append(transform t, bounds b) {
+ // makeMutable will be called by append.
+ if (t == identity())
+ append(b);
+ else
+ append(b.transformed(t));
+ }
+
+ void addPoint(pair user, pair truesize) {
+ makeMutable();
+ base.addPoint(user, truesize);
+ }
+
+ void addBox(pair userMin, pair userMax, pair trueMin, pair trueMax) {
+ makeMutable();
+ base.addBox(userMin, userMax, trueMin, trueMax);
+ }
+
+ void addPath(path g) {
+ //makeMutable(); // Manually inlined here for speed reasons.
+ if (base.frozen)
+ base = base.getMutable();
+ base.addPath(g);
+ }
+
+ void addPath(path[] g) {
+ //makeMutable(); // Manually inlined here for speed reasons.
+ if (base.frozen)
+ base = base.getMutable();
+ base.addPath(g);
+ }
+
+ void addPath(path g, pen p) {
+ //makeMutable(); // Manually inlined here for speed reasons.
+ if (base.frozen)
+ base = base.getMutable();
+ base.addPath(g, p);
+ }
+
+ public bool userBoundsAreSet() {
+ return base.userBoundsAreSet();
+ }
+ public pair userMin() {
+ return base.userMin();
+ }
+ public pair userMax() {
+ return base.userMax();
+ }
+ public void alterUserBound(string which, real val) {
+ makeMutable();
+ base.alterUserBound(which, val);
+ }
+
+ void xclip(real Min, real Max) {
+ makeMutable();
+ base.xclip(Min,Max);
+ }
+
+ void yclip(real Min, real Max) {
+ makeMutable();
+ base.yclip(Min,Max);
+ }
+
+ void clip(pair Min, pair Max) {
+ // TODO: If the user bounds have been manually altered, they may be
+ // incorrect after the clip.
+ xclip(Min.x,Max.x);
+ yclip(Min.y,Max.y);
+ }
+
+ pair min(transform t) {
+ return base.min(t);
+ }
+
+ pair max(transform t) {
+ return base.max(t);
+ }
+
+ transform scaling(real xsize, real ysize,
+ real xunitsize, real yunitsize,
+ bool keepAspect, bool warn) {
+ return base.scaling(xsize, ysize, xunitsize, yunitsize, keepAspect, warn);
+ }
+}
+
+bounds operator *(transform t, bounds b) {
+ return b.transformed(t);
+}
diff --git a/graphics/asymptote/base/plain_boxes.asy b/graphics/asymptote/base/plain_boxes.asy
new file mode 100644
index 0000000000..c675ab4cde
--- /dev/null
+++ b/graphics/asymptote/base/plain_boxes.asy
@@ -0,0 +1,139 @@
+// Draw and/or fill a box on frame dest using the dimensions of frame src.
+path box(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ pair z=(xmargin,ymargin);
+ int sign=filltype == NoFill ? 1 : -1;
+ pair h=0.5*sign*(max(p)-min(p));
+ path g=box(min(src)-h-z,max(src)+h+z);
+ frame F;
+ if(above == false) {
+ filltype.fill(F,g,p);
+ prepend(dest,F);
+ } else filltype.fill(dest,g,p);
+ return g;
+}
+
+path roundbox(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ pair m=min(src);
+ pair M=max(src);
+ pair bound=M-m;
+ int sign=filltype == NoFill ? 1 : -1;
+ real a=bound.x+2*xmargin;
+ real b=bound.y+2*ymargin;
+ real ds=0;
+ real dw=min(a,b)*0.3;
+ path g=shift(m-(xmargin,ymargin))*((0,dw)--(0,b-dw){up}..{right}
+ (dw,b)--(a-dw,b){right}..{down}
+ (a,b-dw)--(a,dw){down}..{left}
+ (a-dw,0)--(dw,0){left}..{up}cycle);
+
+ frame F;
+ if(above == false) {
+ filltype.fill(F,g,p);
+ prepend(dest,F);
+ } else filltype.fill(dest,g,p);
+ return g;
+}
+
+path ellipse(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ pair m=min(src);
+ pair M=max(src);
+ pair D=M-m;
+ static real factor=0.5*sqrt(2);
+ int sign=filltype == NoFill ? 1 : -1;
+ pair h=0.5*sign*(max(p)-min(p));
+ path g=ellipse(0.5*(M+m),factor*D.x+h.x+xmargin,factor*D.y+h.y+ymargin);
+ frame F;
+ if(above == false) {
+ filltype.fill(F,g,p);
+ prepend(dest,F);
+ } else filltype.fill(dest,g,p);
+ return g;
+}
+
+path box(frame f, Label L, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ add(f,L);
+ return box(f,xmargin,ymargin,p,filltype,above);
+}
+
+path roundbox(frame f, Label L, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ add(f,L);
+ return roundbox(f,xmargin,ymargin,p,filltype,above);
+}
+
+path ellipse(frame f, Label L, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ add(f,L);
+ return ellipse(f,xmargin,ymargin,p,filltype,above);
+}
+
+typedef path envelope(frame dest, frame src=dest, real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+
+object object(Label L, envelope e, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ object F;
+ F.L=L.copy();
+ Label L0=L.copy();
+ L0.position(0);
+ L0.p(p);
+ add(F.f,L0);
+ F.g=e(F.f,xmargin,ymargin,p,filltype);
+ return F;
+}
+
+object draw(picture pic=currentpicture, Label L, envelope e,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true)
+{
+ object F=object(L,e,xmargin,ymargin,p,filltype,above);
+ pic.add(new void (frame f, transform t) {
+ frame d;
+ add(d,t,F.L);
+ e(f,d,xmargin,ymargin,p,filltype,above);
+ add(f,d);
+ },true);
+ pic.addBox(L.position,L.position,min(F.f),max(F.f));
+ return F;
+}
+
+object draw(picture pic=currentpicture, Label L, envelope e, pair position,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true)
+{
+ return draw(pic,Label(L,position),e,xmargin,ymargin,p,filltype,above);
+}
+
+pair point(object F, pair dir, transform t=identity())
+{
+ pair m=min(F.g);
+ pair M=max(F.g);
+ pair c=0.5*(m+M);
+ pair z=t*F.L.position;
+ real[] T=intersect(F.g,c--2*(m+realmult(rectify(dir),M-m))-c);
+ if(T.length == 0) return z;
+ return z+point(F.g,T[0]);
+}
+
+frame bbox(picture pic=currentpicture,
+ real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ real penwidth=linewidth(p);
+ frame f=pic.fit(max(pic.xsize-2*(xmargin+penwidth),0),
+ max(pic.ysize-2*(ymargin+penwidth),0));
+ box(f,xmargin,ymargin,p,filltype,above=false);
+ return f;
+}
diff --git a/graphics/asymptote/base/plain_constants.asy b/graphics/asymptote/base/plain_constants.asy
new file mode 100644
index 0000000000..136b354021
--- /dev/null
+++ b/graphics/asymptote/base/plain_constants.asy
@@ -0,0 +1,169 @@
+restricted int undefined=(intMax % 2 == 1) ? intMax : intMax-1;
+
+restricted real inches=72;
+restricted real inch=inches;
+restricted real cm=inches/2.54;
+restricted real mm=0.1cm;
+restricted real bp=1; // A PostScript point.
+restricted real pt=72.0/72.27; // A TeX pt; smaller than a PostScript bp.
+restricted pair I=(0,1);
+
+restricted pair right=(1,0);
+restricted pair left=(-1,0);
+restricted pair up=(0,1);
+restricted pair down=(0,-1);
+
+restricted pair E=(1,0);
+restricted pair N=(0,1);
+restricted pair W=(-1,0);
+restricted pair S=(0,-1);
+
+restricted pair NE=unit(N+E);
+restricted pair NW=unit(N+W);
+restricted pair SW=unit(S+W);
+restricted pair SE=unit(S+E);
+
+restricted pair ENE=unit(E+NE);
+restricted pair NNE=unit(N+NE);
+restricted pair NNW=unit(N+NW);
+restricted pair WNW=unit(W+NW);
+restricted pair WSW=unit(W+SW);
+restricted pair SSW=unit(S+SW);
+restricted pair SSE=unit(S+SE);
+restricted pair ESE=unit(E+SE);
+
+restricted real sqrtEpsilon=sqrt(realEpsilon);
+restricted pair Align=sqrtEpsilon*NE;
+restricted int mantissaBits=ceil(-log(realEpsilon)/log(2))+1;
+
+restricted transform identity;
+restricted transform zeroTransform=(0,0,0,0,0,0);
+
+int min(... int[] a) {return min(a);}
+int max(... int[] a) {return max(a);}
+
+real min(... real[] a) {return min(a);}
+real max(... real[] a) {return max(a);}
+
+bool finite(real x)
+{
+ return abs(x) < infinity;
+}
+
+bool finite(pair z)
+{
+ return abs(z.x) < infinity && abs(z.y) < infinity;
+}
+
+bool finite(triple v)
+{
+ return abs(v.x) < infinity && abs(v.y) < infinity && abs(v.z) < infinity;
+}
+
+restricted file stdin=input();
+restricted file stdout=output();
+
+void none(file file) {}
+void endl(file file) {write(file,'\n',flush);}
+void newl(file file) {write(file,'\n');}
+void DOSendl(file file) {write(file,'\r\n',flush);}
+void DOSnewl(file file) {write(file,'\r\n');}
+void tab(file file) {write(file,'\t');}
+void comma(file file) {write(file,',');}
+typedef void suffix(file);
+
+// Used by interactive write to warn that the outputted type is the resolution
+// of an overloaded name.
+void overloadedMessage(file file) {
+ write(file,' <overloaded>');
+ endl(file);
+}
+
+void write(suffix suffix=endl) {suffix(stdout);}
+void write(file file, suffix suffix=none) {suffix(file);}
+
+path box(pair a, pair b)
+{
+ return a--(b.x,a.y)--b--(a.x,b.y)--cycle;
+}
+
+restricted path unitsquare=box((0,0),(1,1));
+
+restricted path unitcircle=E..N..W..S..cycle;
+restricted real circleprecision=0.0006;
+
+restricted transform invert=reflect((0,0),(1,0));
+
+restricted pen defaultpen;
+
+// A type that takes on one of the values true, false, or default.
+struct bool3 {
+ bool value;
+ bool set;
+}
+
+void write(file file, string s="", bool3 b, suffix suffix=none)
+{
+ if(b.set) write(b.value,suffix);
+ else write("default",suffix);
+}
+
+void write(string s="", bool3 b, suffix suffix=endl)
+{
+ write(stdout,s,b,suffix);
+}
+
+restricted bool3 default;
+
+bool operator cast(bool3 b)
+{
+ return b.set && b.value;
+}
+
+bool3 operator cast(bool b)
+{
+ bool3 B;
+ B.value=b;
+ B.set=true;
+ return B;
+}
+
+bool operator == (bool3 a, bool3 b)
+{
+ return a.set == b.set && (!a.set || (a.value == b.value));
+}
+
+bool operator != (bool3 a, bool3 b)
+{
+ return a.set != b.set || (a.set && (a.value != b.value));
+}
+
+bool operator == (bool3 a, bool b)
+{
+ return a.set && a.value == b;
+}
+
+bool operator != (bool3 a, bool b)
+{
+ return !a.set || a.value != b;
+}
+
+bool operator == (bool a, bool3 b)
+{
+ return b.set && b.value == a;
+}
+
+bool operator != (bool a, bool3 b)
+{
+ return !b.set || b.value != a;
+}
+
+bool[] operator cast(bool3[] b)
+{
+ return sequence(new bool(int i) {return b[i];},b.length);
+}
+
+bool3[] operator cast(bool[] b)
+{
+ return sequence(new bool3(int i) {return b[i];},b.length);
+}
diff --git a/graphics/asymptote/base/plain_debugger.asy b/graphics/asymptote/base/plain_debugger.asy
new file mode 100644
index 0000000000..8568ee0bd8
--- /dev/null
+++ b/graphics/asymptote/base/plain_debugger.asy
@@ -0,0 +1,86 @@
+int debuggerlines=5;
+
+int sourceline(string file, string text)
+{
+ string file=locatefile(file);
+ string[] source=input(file);
+ for(int line=0; line < source.length; ++line)
+ if(find(source[line],text) >= 0) return line+1;
+ write("no matching line in "+file+": \""+text+"\"");
+ return 0;
+}
+
+void stop(string file, string text, code s=quote{})
+{
+ int line=sourceline(file,text);
+ if(line > 0) stop(file,line,s);
+}
+
+void clear(string file, string text)
+{
+ int line=sourceline(file,text);
+ if(line > 0) clear(file,line);
+}
+
+// Enable debugging.
+bool debugging=true;
+
+// Variables used by conditional expressions:
+// e.g. stop("test",2,quote{ignore=(++count <= 10);});
+
+bool ignore;
+int count=0;
+
+string debugger(string file, int line, int column, code s=quote{})
+{
+ int verbose=settings.verbose;
+ settings.verbose=0;
+ _eval(s,true);
+ if(ignore) {
+ ignore=false;
+ settings.verbose=verbose;
+ return "c";
+ }
+ static string s;
+ if(debugging) {
+ static string lastfile;
+ static string[] source;
+ bool help=false;
+ while(true) {
+ if(file != lastfile && file != "-") {source=input(file); lastfile=file;}
+ write();
+ for(int i=max(line-debuggerlines,0); i < min(line,source.length); ++i)
+ write(source[i]);
+ for(int i=0; i < column-1; ++i)
+ write(" ",none);
+ write("^"+(verbose == 5 ? " trace" : ""));
+
+ if(help) {
+ write("c:continue f:file h:help i:inst n:next r:return s:step t:trace q:quit x:exit");
+ help=false;
+ }
+
+ string Prompt=file+": "+(string) line+"."+(string) column;
+ Prompt += "? [%s] ";
+ s=getstring(name="debug",default="h",prompt=Prompt,store=false);
+ if(s == "h" || s == "?") {help=true; continue;}
+ if(s == "c" || s == "s" || s == "n" || s == "i" || s == "f" || s == "r")
+ break;
+ if(s == "q") {debugging=false; abort();} // quit
+ if(s == "x") {debugging=false; return "";} // exit
+ if(s == "t") { // trace
+ if(verbose == 0) {
+ verbose=5;
+ } else {
+ verbose=0;
+ }
+ continue;
+ }
+ _eval(s+";",true);
+ }
+ }
+ settings.verbose=verbose;
+ return s;
+}
+
+atbreakpoint(debugger);
diff --git a/graphics/asymptote/base/plain_filldraw.asy b/graphics/asymptote/base/plain_filldraw.asy
new file mode 100644
index 0000000000..026f2cee6c
--- /dev/null
+++ b/graphics/asymptote/base/plain_filldraw.asy
@@ -0,0 +1,248 @@
+// Draw path g on frame f with user-constructed pen p.
+void makedraw(frame f, path g, pen p, int depth=mantissaBits)
+{
+ if(depth == 0) return;
+ --depth;
+
+ path n=nib(p);
+ for(int i=0; i < size(g); ++i)
+ fill(f,shift(point(g,i))*n,p);
+
+ static real epsilon=1000*realEpsilon;
+ int L=length(g);
+ real stop=L-epsilon;
+ int N=length(n);
+ pair first=point(n,0);
+ pair n0=first;
+
+ for(int i=0; i < N; ++i) {
+ pair n1=point(n,i+1);
+ pair dir=unit(n1-n0);
+ real t=dirtime(g,-dir)-epsilon;
+ if(straight(g,(int) t)) t=ceil(t);
+ if(t > epsilon && t < stop) {
+ makedraw(f,subpath(g,0,t),p,depth);
+ makedraw(f,subpath(g,t,L),p,depth);
+ return;
+ }
+ real t=dirtime(g,dir);
+ if(straight(g,(int) t)) t=ceil(t);
+ if(t > epsilon && t < stop) {
+ makedraw(f,subpath(g,0,t),p,depth);
+ makedraw(f,subpath(g,t,L),p,depth);
+ return;
+ }
+ n0=n1;
+ }
+
+ n0=first;
+ for(int i=0; i < N; ++i) {
+ pair n1=point(n,i+1);
+ fill(f,shift(n0)*g--shift(n1)*reverse(g)--cycle,p);
+ n0=n1;
+ }
+}
+
+void draw(frame f, path g, pen p=currentpen)
+{
+ if(size(nib(p)) == 0) _draw(f,g,p);
+ else {
+ begingroup(f);
+ makedraw(f,g,p);
+ endgroup(f);
+ }
+}
+
+void draw(frame f, explicit path[] g, pen p=currentpen)
+{
+ for(int i=0; i < g.length; ++i) draw(f,g[i],p);
+}
+
+void draw(frame f, guide[] g, pen p=currentpen)
+{
+ for(int i=0; i < g.length; ++i) draw(f,g[i],p);
+}
+
+void filldraw(frame f, path[] g, pen fillpen=currentpen,
+ pen drawpen=currentpen)
+{
+ begingroup(f);
+ fill(f,g,fillpen);
+ draw(f,g,drawpen);
+ endgroup(f);
+}
+
+path[] complement(frame f, path[] g)
+{
+ static pair margin=(0.5,0.5);
+ return box(minbound(min(f),min(g))-margin,maxbound(max(f),max(g))+margin)^^g;
+}
+
+void unfill(frame f, path[] g, bool copy=true)
+{
+ clip(f,complement(f,g),evenodd,copy);
+}
+
+void filloutside(frame f, path[] g, pen p=currentpen, bool copy=true)
+{
+ fill(f,complement(f,g),p+evenodd,copy);
+}
+
+struct filltype
+{
+ typedef void fill2(frame f, path[] g, pen fillpen);
+ fill2 fill2;
+ pen fillpen;
+ pen drawpen;
+
+ int type;
+ static int Fill=1;
+ static int FillDraw=2;
+ static int Draw=3;
+ static int NoFill=4;
+ static int UnFill=5;
+
+ void operator init(int type=0, pen fillpen=nullpen, pen drawpen=nullpen,
+ fill2 fill2) {
+ this.type=type;
+ this.fillpen=fillpen;
+ this.drawpen=drawpen;
+ this.fill2=fill2;
+ }
+ void fill(frame f, path[] g, pen p) {fill2(f,g,p);}
+}
+
+path[] margin(path[] g, real xmargin, real ymargin)
+{
+ if(xmargin != 0 || ymargin != 0) {
+ pair M=max(g);
+ pair m=min(g);
+ real width=M.x-m.x;
+ real height=M.y-m.y;
+ real xfactor=width > 0 ? (width+2xmargin)/width : 1;
+ real yfactor=height > 0 ? (height+2ymargin)/height : 1;
+ g=scale(xfactor,yfactor)*g;
+ g=shift(0.5*(M+m)-0.5*(max(g)+min(g)))*g;
+ }
+ return g;
+}
+
+filltype Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+{
+ return filltype(filltype.Fill,p,new void(frame f, path[] g, pen fillpen) {
+ if(p != nullpen) fillpen=p;
+ if(fillpen == nullpen) fillpen=currentpen;
+ fill(f,margin(g,xmargin,ymargin),fillpen);
+ });
+}
+
+filltype FillDraw(real xmargin=0, real ymargin=xmargin,
+ pen fillpen=nullpen, pen drawpen=nullpen)
+{
+ return filltype(filltype.FillDraw,fillpen,drawpen,
+ new void(frame f, path[] g, pen Drawpen) {
+ if(drawpen != nullpen) Drawpen=drawpen;
+ pen Fillpen=fillpen == nullpen ? Drawpen : fillpen;
+ if(Fillpen == nullpen) Fillpen=currentpen;
+ if(Drawpen == nullpen) Drawpen=Fillpen;
+ if(cyclic(g[0]))
+ filldraw(f,margin(g,xmargin,ymargin),Fillpen,Drawpen);
+ else
+ draw(f,margin(g,xmargin,ymargin),Drawpen);
+ });
+}
+
+filltype Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+{
+ return filltype(filltype.Draw,drawpen=p,
+ new void(frame f, path[] g, pen drawpen) {
+ pen drawpen=p == nullpen ? drawpen : p;
+ if(drawpen == nullpen) drawpen=currentpen;
+ draw(f,margin(g,xmargin,ymargin),drawpen);
+ });
+}
+
+filltype NoFill=filltype(filltype.NoFill,new void(frame f, path[] g, pen p) {
+ draw(f,g,p);
+ });
+
+
+filltype UnFill(real xmargin=0, real ymargin=xmargin)
+{
+ return filltype(filltype.UnFill,new void(frame f, path[] g, pen) {
+ unfill(f,margin(g,xmargin,ymargin));
+ });
+}
+
+filltype FillDraw=FillDraw(), Fill=Fill(), Draw=Draw(), UnFill=UnFill();
+
+// Fill varying radially from penc at the center of the bounding box to
+// penr at the edge.
+filltype RadialShade(pen penc, pen penr)
+{
+ return filltype(new void(frame f, path[] g, pen) {
+ pair c=(min(g)+max(g))/2;
+ radialshade(f,g,penc,c,0,penr,c,abs(max(g)-min(g))/2);
+ });
+}
+
+filltype RadialShadeDraw(real xmargin=0, real ymargin=xmargin,
+ pen penc, pen penr, pen drawpen=nullpen)
+{
+ return filltype(new void(frame f, path[] g, pen Drawpen) {
+ if(drawpen != nullpen) Drawpen=drawpen;
+ if(Drawpen == nullpen) Drawpen=penc;
+ pair c=(min(g)+max(g))/2;
+ if(cyclic(g[0]))
+ radialshade(f,margin(g,xmargin,ymargin),penc,c,0,penr,c,
+ abs(max(g)-min(g))/2);
+ draw(f,margin(g,xmargin,ymargin),Drawpen);
+ });
+}
+
+// Fill the region in frame dest underneath frame src and return the
+// boundary of src.
+path fill(frame dest, frame src, filltype filltype=NoFill,
+ real xmargin=0, real ymargin=xmargin)
+{
+ pair z=(xmargin,ymargin);
+ path g=box(min(src)-z,max(src)+z);
+ filltype.fill(dest,g,nullpen);
+ return g;
+}
+
+// Add frame dest to frame src with optional grouping and background fill.
+void add(frame dest, frame src, bool group, filltype filltype=NoFill,
+ bool above=true)
+{
+ if(above) {
+ if(filltype != NoFill) fill(dest,src,filltype);
+ if(group) begingroup(dest);
+ add(dest,src);
+ if(group) endgroup(dest);
+ } else {
+ if(group) {
+ frame f;
+ endgroup(f);
+ prepend(dest,f);
+ }
+ prepend(dest,src);
+ if(group) {
+ frame f;
+ begingroup(f);
+ prepend(dest,f);
+ }
+ if(filltype != NoFill) {
+ frame f;
+ fill(f,src,filltype);
+ prepend(dest,f);
+ }
+ }
+}
+
+void add(frame dest, frame src, filltype filltype,
+ bool above=filltype.type != filltype.UnFill)
+{
+ if(filltype != NoFill) fill(dest,src,filltype);
+ (above ? add : prepend)(dest,src);
+}
diff --git a/graphics/asymptote/base/plain_margins.asy b/graphics/asymptote/base/plain_margins.asy
new file mode 100644
index 0000000000..c452275448
--- /dev/null
+++ b/graphics/asymptote/base/plain_margins.asy
@@ -0,0 +1,99 @@
+struct marginT {
+ path g;
+ real begin,end;
+};
+
+typedef marginT margin(path, pen);
+
+path trim(path g, real begin, real end) {
+ real a=arctime(g,begin);
+ real b=arctime(g,arclength(g)-end);
+ return a <= b ? subpath(g,a,b) : point(g,a);
+}
+
+margin operator +(margin ma, margin mb)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real ba=ma(g,p).begin < 0 ? 0 : ma(g,p).begin;
+ real bb=mb(g,p).begin < 0 ? 0 : mb(g,p).begin;
+ real ea=ma(g,p).end < 0 ? 0 : ma(g,p).end;
+ real eb=mb(g,p).end < 0 ? 0 : mb(g,p).end;
+ margin.begin=ba+bb;
+ margin.end=ea+eb;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin NoMargin()
+{
+ return new marginT(path g, pen) {
+ marginT margin;
+ margin.begin=margin.end=0;
+ margin.g=g;
+ return margin;
+ };
+}
+
+margin Margin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real factor=labelmargin(p);
+ margin.begin=begin*factor;
+ margin.end=end*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin PenMargin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real factor=linewidth(p);
+ margin.begin=(begin+0.5)*factor;
+ margin.end=(end+0.5)*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin DotMargin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real margindot(real x) {return x > 0 ? dotfactor*x : x;}
+ real factor=linewidth(p);
+ margin.begin=(margindot(begin)+0.5)*factor;
+ margin.end=(margindot(end)+0.5)*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin TrueMargin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ margin.begin=begin;
+ margin.end=end;
+ margin.g=trim(g,begin,end);
+ return margin;
+ };
+}
+
+margin NoMargin=NoMargin(),
+ BeginMargin=Margin(1,0),
+ Margin=Margin(0,1),
+ EndMargin=Margin,
+ Margins=Margin(1,1),
+ BeginPenMargin=PenMargin(0.5,-0.5),
+ PenMargin=PenMargin(-0.5,0.5),
+ EndPenMargin=PenMargin,
+ PenMargins=PenMargin(0.5,0.5),
+ BeginDotMargin=DotMargin(0.5,-0.5),
+ DotMargin=DotMargin(-0.5,0.5),
+ EndDotMargin=DotMargin,
+ DotMargins=DotMargin(0.5,0.5);
diff --git a/graphics/asymptote/base/plain_markers.asy b/graphics/asymptote/base/plain_markers.asy
new file mode 100644
index 0000000000..250e1701eb
--- /dev/null
+++ b/graphics/asymptote/base/plain_markers.asy
@@ -0,0 +1,401 @@
+real legendlinelength=50;
+real legendhskip=1.2;
+real legendvskip=legendhskip;
+real legendmargin=10;
+real legendmaxrelativewidth=1;
+
+// Return a unit polygon with n sides.
+path polygon(int n)
+{
+ guide g;
+ for(int i=0; i < n; ++i) g=g--expi(2pi*(i+0.5)/n-0.5*pi);
+ return g--cycle;
+}
+
+// Return a unit n-point cyclic cross, with optional inner radius r and
+// end rounding.
+path cross(int n, bool round=true, real r=0)
+{
+ assert(n > 1);
+ real r=min(r,1);
+ real theta=pi/n;
+ real s=sin(theta);
+ real c=cos(theta);
+ pair z=(c,s);
+ transform mirror=reflect(0,z);
+ pair p1=(r,0);
+ path elementary;
+ if(round) {
+ pair e1=p1+z*max(1-r*(s+c),0);
+ elementary=p1--e1..(c,s)..mirror*e1--mirror*p1;
+ } else {
+ pair p2=p1+z*(max(sqrt(1-(r*s)^2)-r*c),0);
+ elementary=p1--p2--mirror*p2--mirror*p1;
+ }
+
+ guide g;
+ real step=360/n;
+ for(int i=0; i < n; ++i)
+ g=g--rotate(i*step-90)*elementary;
+
+ return g--cycle;
+}
+
+path[] plus=(-1,0)--(1,0)^^(0,-1)--(0,1);
+
+typedef void markroutine(picture pic=currentpicture, frame f, path g);
+
+// On picture pic, add frame f about every node of path g.
+void marknodes(picture pic=currentpicture, frame f, path g) {
+ for(int i=0; i < size(g); ++i)
+ add(pic,f,point(g,i));
+}
+
+// On picture pic, add n copies of frame f to path g, evenly spaced in
+// arclength.
+// If rotated=true, the frame will be rotated by the angle of the tangent
+// to the path at the points where the frame will be added.
+// If centered is true, center the frames within n evenly spaced arclength
+// intervals.
+markroutine markuniform(bool centered=false, int n, bool rotated=false) {
+ return new void(picture pic=currentpicture, frame f, path g) {
+ if(n <= 0) return;
+ void add(real x) {
+ real t=reltime(g,x);
+ add(pic,rotated ? rotate(degrees(dir(g,t)))*f : f,point(g,t));
+ }
+ if(centered) {
+ real width=1/n;
+ for(int i=0; i < n; ++i) add((i+0.5)*width);
+ } else {
+ if(n == 1) add(0.5);
+ else {
+ real width=1/(n-1);
+ for(int i=0; i < n; ++i)
+ add(i*width);
+ }
+ }
+ };
+}
+
+// On picture pic, add frame f at points z(t) for n evenly spaced values of
+// t in [a,b].
+markroutine markuniform(pair z(real t), real a, real b, int n)
+{
+ return new void(picture pic=currentpicture, frame f, path) {
+ real width=b-a;
+ for(int i=0; i <= n; ++i) {
+ add(pic,f,z(a+i/n*width));
+ }
+ };
+}
+
+struct marker {
+ frame f;
+ bool above=true;
+ markroutine markroutine=marknodes;
+ void mark(picture pic=currentpicture, path g) {
+ markroutine(pic,f,g);
+ };
+}
+
+marker marker(frame f=newframe, markroutine markroutine=marknodes,
+ bool above=true)
+{
+ marker m=new marker;
+ m.f=f;
+ m.above=above;
+ m.markroutine=markroutine;
+ return m;
+}
+
+marker marker(path[] g, markroutine markroutine=marknodes, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true)
+{
+ frame f;
+ filltype.fill(f,g,p);
+ return marker(f,markroutine,above);
+}
+
+// On picture pic, add path g with opacity thinning about every node.
+marker markthin(path g, pen p=currentpen,
+ real thin(real fraction)=new real(real x) {return x^2;},
+ filltype filltype=NoFill) {
+ marker M=new marker;
+ M.above=true;
+ filltype.fill(M.f,g,p);
+ real factor=1/abs(size(M.f));
+ M.markroutine=new void(picture pic=currentpicture, frame, path G) {
+ transform t=pic.calculateTransform();
+ int n=size(G);
+ for(int i=0; i < n; ++i) {
+ pair z=point(G,i);
+ frame f;
+ real fraction=1;
+ if(i > 0) fraction=min(fraction,abs(t*(z-point(G,i-1)))*factor);
+ if(i < n-1) fraction=min(fraction,abs(t*(point(G,i+1)-z))*factor);
+ filltype.fill(f,g,p+opacity(thin(fraction)));
+ add(pic,f,point(G,i));
+ }
+ };
+ return M;
+}
+
+marker nomarker;
+
+real circlescale=0.85;
+
+path[] MarkPath={scale(circlescale)*unitcircle,
+ polygon(3),polygon(4),polygon(5),invert*polygon(3),
+ cross(4),cross(6)};
+
+marker[] Mark=sequence(new marker(int i) {return marker(MarkPath[i]);},
+ MarkPath.length);
+
+marker[] MarkFill=sequence(new marker(int i) {return marker(MarkPath[i],Fill);},
+ MarkPath.length-2);
+
+marker Mark(int n)
+{
+ n=n % (Mark.length+MarkFill.length);
+ if(n < Mark.length) return Mark[n];
+ else return MarkFill[n-Mark.length];
+}
+
+picture legenditem(Legend legenditem, real linelength)
+{
+ picture pic;
+ pair z1=(0,0);
+ pair z2=z1+(linelength,0);
+ if(!legenditem.above && !empty(legenditem.mark))
+ marknodes(pic,legenditem.mark,interp(z1,z2,0.5));
+ if(linelength > 0)
+ Draw(pic,z1--z2,legenditem.p);
+ if(legenditem.above && !empty(legenditem.mark))
+ marknodes(pic,legenditem.mark,interp(z1,z2,0.5));
+ if(legenditem.plabel != invisible)
+ label(pic,legenditem.label,z2,E,legenditem.plabel);
+ else
+ label(pic,legenditem.label,z2,E,currentpen);
+ return pic;
+}
+
+picture legend(Legend[] Legend, int perline=1, real linelength,
+ real hskip, real vskip, real maxwidth=0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false)
+{
+ if(maxwidth <= 0) hstretch=false;
+ if(maxheight <= 0) vstretch=false;
+ if(Legend.length <= 1) vstretch=hstretch=false;
+
+ picture inset;
+ size(inset,0,0,IgnoreAspect);
+
+ if(Legend.length == 0)
+ return inset;
+
+ // Check for legend entries with lines:
+ bool bLineEntriesAvailable=false;
+ for(int i=0; i < Legend.length; ++i) {
+ if(Legend[i].p != invisible) {
+ bLineEntriesAvailable=true;
+ break;
+ }
+ }
+
+ real markersize=0;
+ for(int i=0; i < Legend.length; ++i)
+ markersize=max(markersize,size(Legend[i].mark).x);
+
+ // If no legend has a line, set the line length to zero
+ if(!bLineEntriesAvailable)
+ linelength=0;
+
+ linelength=max(linelength,markersize*(linelength == 0 ? 1 : 2));
+
+ // Get the maximum dimensions per legend entry;
+ // calculate line length for a one-line legend
+ real heightPerEntry=0;
+ real widthPerEntry=0;
+ real totalwidth=0;
+ for(int i=0; i < Legend.length; ++i) {
+ picture pic=legenditem(Legend[i],linelength);
+ pair lambda=size(pic);
+ heightPerEntry=max(heightPerEntry,lambda.y);
+ widthPerEntry=max(widthPerEntry,lambda.x);
+ if(Legend[i].p != invisible)
+ totalwidth += lambda.x;
+ else {
+ // Legend entries without leading line need less space in one-line legends
+ picture pic=legenditem(Legend[i],0);
+ totalwidth += size(pic).x;
+ }
+ }
+ // Does everything fit into one line?
+ if(((perline < 1) || (perline >= Legend.length)) &&
+ (maxwidth >= totalwidth+(totalwidth/Legend.length)*
+ (Legend.length-1)*(hskip-1))) {
+ // One-line legend
+ real currPosX=0;
+ real itemDistance;
+ if(hstretch)
+ itemDistance=(maxwidth-totalwidth)/(Legend.length-1);
+ else
+ itemDistance=(totalwidth/Legend.length)*(hskip-1);
+ for(int i=0; i < Legend.length; ++i) {
+ picture pic=legenditem(Legend[i],
+ Legend[i].p == invisible ? 0 : linelength);
+ add(inset,pic,(currPosX,0));
+ currPosX += size(pic).x+itemDistance;
+ }
+ } else {
+ // multiline legend
+ if(maxwidth > 0) {
+ int maxperline=floor(maxwidth/(widthPerEntry*hskip));
+ if((perline < 1) || (perline > maxperline))
+ perline=maxperline;
+ }
+ if(perline < 1) // This means: maxwidth < widthPerEntry
+ perline=1;
+
+ if(perline <= 1) hstretch=false;
+ if(hstretch) hskip=(maxwidth/widthPerEntry-perline)/(perline-1)+1;
+ if(vstretch) {
+ int rows=ceil(Legend.length/perline);
+ vskip=(maxheight/heightPerEntry-rows)/(rows-1)+1;
+ }
+
+ if(hstretch && (perline == 1)) {
+ Draw(inset,(0,0)--(maxwidth,0),invisible());
+ for(int i=0; i < Legend.length; ++i)
+ add(inset,legenditem(Legend[i],linelength),
+ (0.5*(maxwidth-widthPerEntry),
+ -quotient(i,perline)*heightPerEntry*vskip));
+ } else
+ for(int i=0; i < Legend.length; ++i)
+ add(inset,legenditem(Legend[i],linelength),
+ ((i%perline)*widthPerEntry*hskip,
+ -quotient(i,perline)*heightPerEntry*vskip));
+ }
+
+ return inset;
+}
+
+frame legend(picture pic=currentpicture, int perline=1,
+ real xmargin=legendmargin, real ymargin=xmargin,
+ real linelength=legendlinelength,
+ real hskip=legendhskip, real vskip=legendvskip,
+ real maxwidth=perline == 0 ?
+ legendmaxrelativewidth*size(pic).x : 0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false, pen p=currentpen)
+{
+ frame F;
+ if(pic.legend.length == 0) return F;
+ F=legend(pic.legend,perline,linelength,hskip,vskip,
+ max(maxwidth-2xmargin,0),
+ max(maxheight-2ymargin,0),
+ hstretch,vstretch).fit();
+ box(F,xmargin,ymargin,p);
+ return F;
+}
+
+pair[] pairs(real[] x, real[] y)
+{
+ if(x.length != y.length) abort("arrays have different lengths");
+ return sequence(new pair(int i) {return (x[i],y[i]);},x.length);
+}
+
+filltype dotfilltype = Fill;
+
+void dot(frame f, pair z, pen p=currentpen, filltype filltype=dotfilltype)
+{
+ if(filltype == Fill)
+ draw(f,z,dotsize(p)+p);
+ else {
+ real s=0.5*(dotsize(p)-linewidth(p));
+ if(s <= 0) return;
+ path g=shift(z)*scale(s)*unitcircle;
+ begingroup(f);
+ filltype.fill(f,g,p);
+ draw(f,g,p);
+ endgroup(f);
+ }
+}
+
+void dot(picture pic=currentpicture, pair z, pen p=currentpen,
+ filltype filltype=dotfilltype)
+{
+ pic.add(new void(frame f, transform t) {
+ dot(f,t*z,p,filltype);
+ },true);
+ pic.addPoint(z,dotsize(p)+p);
+}
+
+void dot(picture pic=currentpicture, Label L, pair z, align align=NoAlign,
+ string format=defaultformat, pen p=currentpen, filltype filltype=dotfilltype)
+{
+ Label L=L.copy();
+ L.position(z);
+ if(L.s == "") {
+ if(format == "") format=defaultformat;
+ L.s="("+format(format,z.x)+","+format(format,z.y)+")";
+ }
+ L.align(align,E);
+ L.p(p);
+ dot(pic,z,p,filltype);
+ add(pic,L);
+}
+
+void dot(picture pic=currentpicture, Label[] L=new Label[], pair[] z,
+ align align=NoAlign, string format=defaultformat, pen p=currentpen,
+ filltype filltype=dotfilltype)
+{
+ int stop=min(L.length,z.length);
+ for(int i=0; i < stop; ++i)
+ dot(pic,L[i],z[i],align,format,p,filltype);
+ for(int i=stop; i < z.length; ++i)
+ dot(pic,z[i],p,filltype);
+}
+
+void dot(picture pic=currentpicture, Label[] L=new Label[],
+ explicit path g, align align=RightSide, string format=defaultformat,
+ pen p=currentpen, filltype filltype=dotfilltype)
+{
+ int n=size(g);
+ int stop=min(L.length,n);
+ for(int i=0; i < stop; ++i)
+ dot(pic,L[i],point(g,i),-sgn(align.dir.x)*I*dir(g,i),format,p,filltype);
+ for(int i=stop; i < n; ++i)
+ dot(pic,point(g,i),p,filltype);
+}
+
+void dot(picture pic=currentpicture, path[] g, pen p=currentpen,
+ filltype filltype=dotfilltype)
+{
+ for(int i=0; i < g.length; ++i)
+ dot(pic,g[i],p,filltype);
+}
+
+void dot(picture pic=currentpicture, Label L, pen p=currentpen,
+ filltype filltype=dotfilltype)
+{
+ dot(pic,L,L.position,p,filltype);
+}
+
+// A dot in a frame.
+frame dotframe(pen p=currentpen, filltype filltype=dotfilltype)
+{
+ frame f;
+ dot(f,(0,0),p,filltype);
+ return f;
+}
+
+frame dotframe=dotframe();
+
+marker dot(pen p=currentpen, filltype filltype=dotfilltype)
+{
+ return marker(dotframe(p,filltype));
+}
+
+marker dot=dot();
+
diff --git a/graphics/asymptote/base/plain_paths.asy b/graphics/asymptote/base/plain_paths.asy
new file mode 100644
index 0000000000..8bb5250db5
--- /dev/null
+++ b/graphics/asymptote/base/plain_paths.asy
@@ -0,0 +1,397 @@
+path nullpath;
+
+typedef guide interpolate(... guide[]);
+
+// These numbers identify the side of a specifier in an operator spec or
+// operator curl expression:
+// a{out} .. {in}b
+restricted int JOIN_OUT=0;
+restricted int JOIN_IN=1;
+
+// Define a.. tension t ..b to be equivalent to
+// a.. tension t and t ..b
+// and likewise with controls.
+tensionSpecifier operator tension(real t, bool atLeast)
+{
+ return operator tension(t,t,atLeast);
+}
+
+guide operator controls(pair z)
+{
+ return operator controls(z,z);
+}
+
+guide[] operator cast(pair[] z)
+{
+ return sequence(new guide(int i) {return z[i];},z.length);
+}
+
+path[] operator cast(pair[] z)
+{
+ return sequence(new path(int i) {return z[i];},z.length);
+}
+
+path[] operator cast(guide[] g)
+{
+ return sequence(new path(int i) {return g[i];},g.length);
+}
+
+guide[] operator cast(path[] g)
+{
+ return sequence(new guide(int i) {return g[i];},g.length);
+}
+
+path[] operator cast(path p)
+{
+ return new path[] {p};
+}
+
+path[] operator cast(guide g)
+{
+ return new path[] {(path) g};
+}
+
+path[] operator ^^ (path p, path q)
+{
+ return new path[] {p,q};
+}
+
+path[] operator ^^ (path p, explicit path[] q)
+{
+ return concat(new path[] {p},q);
+}
+
+path[] operator ^^ (explicit path[] p, path q)
+{
+ return concat(p,new path[] {q});
+}
+
+path[] operator ^^ (explicit path[] p, explicit path[] q)
+{
+ return concat(p,q);
+}
+
+path[] operator * (transform t, explicit path[] p)
+{
+ return sequence(new path(int i) {return t*p[i];},p.length);
+}
+
+pair[] operator * (transform t, pair[] z)
+{
+ return sequence(new pair(int i) {return t*z[i];},z.length);
+}
+
+void write(file file, string s="", explicit path[] x, suffix suffix=none)
+{
+ write(file,s);
+ if(x.length > 0) write(file,x[0]);
+ for(int i=1; i < x.length; ++i) {
+ write(file,endl);
+ write(file," ^^");
+ write(file,x[i]);
+ }
+ write(file,suffix);
+}
+
+void write(string s="", explicit path[] x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+void write(file file, string s="", explicit guide[] x, suffix suffix=none)
+{
+ write(file,s);
+ if(x.length > 0) write(file,x[0]);
+ for(int i=1; i < x.length; ++i) {
+ write(file,endl);
+ write(file," ^^");
+ write(file,x[i]);
+ }
+ write(file,suffix);
+}
+
+void write(string s="", explicit guide[] x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+interpolate operator ..(tensionSpecifier t)
+{
+ return new guide(... guide[] a) {
+ if(a.length == 0) return nullpath;
+ guide g=a[0];
+ for(int i=1; i < a.length; ++i)
+ g=g..t..a[i];
+ return g;
+ };
+}
+
+interpolate operator ::=operator ..(operator tension(1,true));
+interpolate operator ---=operator ..(operator tension(infinity,true));
+
+// return an arbitrary intersection point of paths p and q
+pair intersectionpoint(path p, path q, real fuzz=-1)
+{
+ real[] t=intersect(p,q,fuzz);
+ if(t.length == 0) abort("paths do not intersect");
+ return point(p,t[0]);
+}
+
+// return an array containing all intersection points of the paths p and q
+pair[] intersectionpoints(path p, path q, real fuzz=-1)
+{
+ real[][] t=intersections(p,q,fuzz);
+ return sequence(new pair(int i) {return point(p,t[i][0]);},t.length);
+}
+
+pair[] intersectionpoints(explicit path[] p, explicit path[] q, real fuzz=-1)
+{
+ pair[] z;
+ for(int i=0; i < p.length; ++i)
+ for(int j=0; j < q.length; ++j)
+ z.append(intersectionpoints(p[i],q[j],fuzz));
+ return z;
+}
+
+struct slice {
+ path before,after;
+}
+
+slice cut(path p, path knife, int n)
+{
+ slice s;
+ real[][] T=intersections(p,knife);
+ if(T.length == 0) {s.before=p; s.after=nullpath; return s;}
+ T.cyclic=true;
+ real t=T[n][0];
+ s.before=subpath(p,0,t);
+ s.after=subpath(p,t,length(p));
+ return s;
+}
+
+slice firstcut(path p, path knife)
+{
+ return cut(p,knife,0);
+}
+
+slice lastcut(path p, path knife)
+{
+ return cut(p,knife,-1);
+}
+
+pair dir(path p)
+{
+ return dir(p,length(p));
+}
+
+pair dir(path p, path q)
+{
+ return unit(dir(p)+dir(q));
+}
+
+// return the point on path p at arclength L
+pair arcpoint(path p, real L)
+{
+ return point(p,arctime(p,L));
+}
+
+// return the direction on path p at arclength L
+pair arcdir(path p, real L)
+{
+ return dir(p,arctime(p,L));
+}
+
+// return the time on path p at the relative fraction l of its arclength
+real reltime(path p, real l)
+{
+ return arctime(p,l*arclength(p));
+}
+
+// return the point on path p at the relative fraction l of its arclength
+pair relpoint(path p, real l)
+{
+ return point(p,reltime(p,l));
+}
+
+// return the direction of path p at the relative fraction l of its arclength
+pair reldir(path p, real l)
+{
+ return dir(p,reltime(p,l));
+}
+
+// return the initial point of path p
+pair beginpoint(path p)
+{
+ return point(p,0);
+}
+
+// return the point on path p at half of its arclength
+pair midpoint(path p)
+{
+ return relpoint(p,0.5);
+}
+
+// return the final point of path p
+pair endpoint(path p)
+{
+ return point(p,length(p));
+}
+
+path operator &(path p, cycleToken tok)
+{
+ int n=length(p);
+ if(n < 0) return nullpath;
+ if(n == 0) return p--cycle;
+ if(cyclic(p)) return p;
+ return straight(p,n-1) ? subpath(p,0,n-1)--cycle :
+ subpath(p,0,n-1)..controls postcontrol(p,n-1) and precontrol(p,n)..cycle;
+}
+
+// return a cyclic path enclosing a region bounded by a list of two or more
+// consecutively intersecting paths
+path buildcycle(... path[] p)
+{
+ int n=p.length;
+ if(n < 2) return nullpath;
+ real[] ta=new real[n];
+ real[] tb=new real[n];
+ if(n == 2) {
+ real[][] t=intersections(p[0],p[1]);
+ if(t.length < 2)
+ return nullpath;
+ int k=t.length-1;
+ ta[0]=t[0][0]; tb[0]=t[k][0];
+ ta[1]=t[k][1]; tb[1]=t[0][1];
+ } else {
+ int j=n-1;
+ for(int i=0; i < n; ++i) {
+ real[][] t=intersections(p[i],p[j]);
+ if(t.length == 0)
+ return nullpath;
+ ta[i]=t[0][0]; tb[j]=t[0][1];
+ j=i;
+ }
+ }
+
+ pair c;
+ for(int i=0; i < n ; ++i)
+ c += point(p[i],ta[i]);
+ c /= n;
+
+ path G;
+ for(int i=0; i < n ; ++i) {
+ real Ta=ta[i];
+ real Tb=tb[i];
+ if(cyclic(p[i])) {
+ int L=length(p[i]);
+ real t=Tb-L;
+ if(abs(c-point(p[i],0.5(Ta+t))) <
+ abs(c-point(p[i],0.5(Ta+Tb)))) Tb=t;
+ while(Tb < Ta) Tb += L;
+ }
+ G=G&subpath(p[i],Ta,Tb);
+ }
+ return G&cycle;
+}
+
+// return 1 if p strictly contains q,
+// -1 if q strictly contains p,
+// 0 otherwise.
+int inside(path p, path q, pen fillrule=currentpen)
+{
+ if(intersect(p,q).length > 0) return 0;
+ if(cyclic(p) && inside(p,point(q,0),fillrule)) return 1;
+ if(cyclic(q) && inside(q,point(p,0),fillrule)) return -1;
+ return 0;
+}
+
+// Return an arbitrary point strictly inside a cyclic path p according to
+// the specified fill rule.
+pair inside(path p, pen fillrule=currentpen)
+{
+ if(!cyclic(p)) abort("path is not cyclic");
+ int n=length(p);
+ for(int i=0; i < n; ++i) {
+ pair z=point(p,i);
+ pair dir=dir(p,i);
+ if(dir == 0) continue;
+ real[] T=intersections(p,z,z+I*dir);
+ // Check midpoints of line segments formed between the
+ // corresponding intersection points and z.
+ for(int j=0; j < T.length; ++j) {
+ if(T[j] != i) {
+ pair w=point(p,T[j]);
+ pair m=0.5*(z+w);
+ if(interior(windingnumber(p,m),fillrule)) return m;
+ }
+ }
+ }
+ // cannot find an interior point: path is degenerate
+ return point(p,0);
+}
+
+// Return all intersection times of path g with the vertical line through (x,0).
+real[] times(path p, real x)
+{
+ return intersections(p,(x,0),(x,1));
+}
+
+// Return all intersection times of path g with the horizontal line through
+// (0,z.y).
+real[] times(path p, explicit pair z)
+{
+ return intersections(p,(0,z.y),(1,z.y));
+}
+
+path randompath(int n, bool cumulate=true, interpolate join=operator ..)
+{
+ guide g;
+ pair w;
+ for(int i=0; i <= n; ++i) {
+ pair z=(unitrand()-0.5,unitrand()-0.5);
+ if(cumulate) w += z;
+ else w=z;
+ g=join(g,w);
+ }
+ return g;
+}
+
+path[] strokepath(path g, pen p=currentpen)
+{
+ path[] G=_strokepath(g,p);
+ if(G.length == 0) return G;
+ pair center(path g) {return 0.5*(min(g)+max(g));}
+ pair center(path[] g) {return 0.5*(min(g)+max(g));}
+ return shift(center(g)-center(G))*G;
+}
+
+real braceinnerangle=radians(60);
+real braceouterangle=radians(70);
+real bracemidangle=radians(0);
+real bracedefaultratio=0.14;
+path brace(pair a, pair b, real amplitude=bracedefaultratio*length(b-a))
+{
+ real length=length(b-a);
+ real sign=sgn(amplitude);
+ real hamplitude=0.5*amplitude;
+ real hlength=0.5*length;
+ path brace;
+ if(abs(amplitude) < bracedefaultratio*length) {
+ real slope=2*bracedefaultratio;
+ real controldist=(abs(hamplitude))/slope;
+ brace=(0,0){expi(sign*braceouterangle)}::
+ {expi(sign*bracemidangle)}(controldist,hamplitude)::
+ {expi(sign*bracemidangle)}(hlength-controldist,hamplitude)::
+ {expi(sign*braceinnerangle)}(hlength,amplitude) {expi(-sign*braceinnerangle)}::
+ {expi(-sign*bracemidangle)}(hlength+controldist,hamplitude)::
+ {expi(-sign*bracemidangle)}(length-controldist,hamplitude)::
+ {expi(-sign*braceouterangle)}(length,0);
+ } else {
+ brace=(0,0){expi(sign*braceouterangle)}::
+ {expi(sign*bracemidangle)}(0.25*length,hamplitude)::
+ {expi(sign*braceinnerangle)}(hlength,amplitude){expi(-sign*braceinnerangle)}::
+ {expi(-sign*bracemidangle)}(0.75*length,hamplitude)::
+ {expi(-sign*braceouterangle)}(length,0);
+ }
+ return shift(a)*rotate(degrees(b-a,warn=false))*brace;
+}
diff --git a/graphics/asymptote/base/plain_pens.asy b/graphics/asymptote/base/plain_pens.asy
new file mode 100644
index 0000000000..b846569658
--- /dev/null
+++ b/graphics/asymptote/base/plain_pens.asy
@@ -0,0 +1,368 @@
+real labelmargin=0.3;
+real dotfactor=6;
+
+pen solid=linetype(new real[]);
+pen dotted=linetype(new real[] {0,4});
+pen dashed=linetype(new real[] {8,8});
+pen longdashed=linetype(new real[] {24,8});
+pen dashdotted=linetype(new real[] {8,8,0,8});
+pen longdashdotted=linetype(new real[] {24,8,0,8});
+
+pen linetype(string pattern, real offset=0, bool scale=true, bool adjust=true)
+{
+ return linetype((real[]) split(pattern),offset,scale,adjust);
+}
+
+void defaultpen(real w) {defaultpen(linewidth(w));}
+pen operator +(pen p, real w) {return p+linewidth(w);}
+pen operator +(real w, pen p) {return linewidth(w)+p;}
+
+pen Dotted(pen p=currentpen) {return linetype(new real[] {0,3})+2*linewidth(p);}
+pen Dotted=Dotted();
+
+restricted pen squarecap=linecap(0);
+restricted pen roundcap=linecap(1);
+restricted pen extendcap=linecap(2);
+
+restricted pen miterjoin=linejoin(0);
+restricted pen roundjoin=linejoin(1);
+restricted pen beveljoin=linejoin(2);
+
+restricted pen zerowinding=fillrule(0);
+restricted pen evenodd=fillrule(1);
+
+bool interior(int windingnumber, pen fillrule)
+{
+ return windingnumber != undefined &&
+ (fillrule(fillrule) == 1 ? windingnumber % 2 == 1 : windingnumber != 0);
+}
+
+restricted pen nobasealign=basealign(0);
+restricted pen basealign=basealign(1);
+
+pen invisible=invisible();
+pen thin() {return settings.thin ? linewidth(0) : defaultpen;}
+pen thick(pen p=currentpen) {return linewidth(linewidth(p));}
+pen nullpen=linewidth(0)+invisible;
+
+pen black=gray(0);
+pen white=gray(1);
+pen gray=gray(0.5);
+
+pen red=rgb(1,0,0);
+pen green=rgb(0,1,0);
+pen blue=rgb(0,0,1);
+
+pen Cyan=cmyk(1,0,0,0);
+pen Magenta=cmyk(0,1,0,0);
+pen Yellow=cmyk(0,0,1,0);
+pen Black=cmyk(0,0,0,1);
+
+pen cyan=rgb(0,1,1);
+pen magenta=rgb(1,0,1);
+pen yellow=rgb(1,1,0);
+
+pen palered=rgb(1,0.75,0.75);
+pen palegreen=rgb(0.75,1,0.75);
+pen paleblue=rgb(0.75,0.75,1);
+pen palecyan=rgb(0.75,1,1);
+pen palemagenta=rgb(1,0.75,1);
+pen paleyellow=rgb(1,1,0.75);
+pen palegray=gray(0.95);
+
+pen lightred=rgb(1,0.5,0.5);
+pen lightgreen=rgb(0.5,1,0.5);
+pen lightblue=rgb(0.5,0.5,1);
+pen lightcyan=rgb(0.5,1,1);
+pen lightmagenta=rgb(1,0.5,1);
+pen lightyellow=rgb(1,1,0.5);
+pen lightgray=gray(0.9);
+
+pen mediumred=rgb(1,0.25,0.25);
+pen mediumgreen=rgb(0.25,1,0.25);
+pen mediumblue=rgb(0.25,0.25,1);
+pen mediumcyan=rgb(0.25,1,1);
+pen mediummagenta=rgb(1,0.25,1);
+pen mediumyellow=rgb(1,1,0.25);
+pen mediumgray=gray(0.75);
+
+pen heavyred=rgb(0.75,0,0);
+pen heavygreen=rgb(0,0.75,0);
+pen heavyblue=rgb(0,0,0.75);
+pen heavycyan=rgb(0,0.75,0.75);
+pen heavymagenta=rgb(0.75,0,0.75);
+pen lightolive=rgb(0.75,0.75,0);
+pen heavygray=gray(0.25);
+
+pen deepred=rgb(0.5,0,0);
+pen deepgreen=rgb(0,0.5,0);
+pen deepblue=rgb(0,0,0.5);
+pen deepcyan=rgb(0,0.5,0.5);
+pen deepmagenta=rgb(0.5,0,0.5);
+pen deepyellow=rgb(0.5,0.5,0);
+pen deepgray=gray(0.1);
+
+pen darkred=rgb(0.25,0,0);
+pen darkgreen=rgb(0,0.25,0);
+pen darkblue=rgb(0,0,0.25);
+pen darkcyan=rgb(0,0.25,0.25);
+pen darkmagenta=rgb(0.25,0,0.25);
+pen darkolive=rgb(0.25,0.25,0);
+pen darkgray=gray(0.05);
+
+pen orange=rgb(1,0.5,0);
+pen fuchsia=rgb(1,0,0.5);
+
+pen chartreuse=rgb(0.5,1,0);
+pen springgreen=rgb(0,1,0.5);
+
+pen purple=rgb(0.5,0,1);
+pen royalblue=rgb(0,0.5,1);
+
+// Synonyms:
+
+pen salmon=lightred;
+pen brown=deepred;
+pen olive=deepyellow;
+pen darkbrown=darkred;
+pen pink=palemagenta;
+pen palegrey=palegray;
+pen lightgrey=lightgray;
+pen mediumgrey=mediumgray;
+pen grey=gray;
+pen heavygrey=heavygray;
+pen deepgrey=deepgray;
+pen darkgrey=darkgray;
+
+// Options for handling label overwriting
+restricted int Allow=0;
+restricted int Suppress=1;
+restricted int SuppressQuiet=2;
+restricted int Move=3;
+restricted int MoveQuiet=4;
+
+pen[] colorPen={red,blue,green,magenta,cyan,orange,purple,brown,
+ deepblue,deepgreen,chartreuse,fuchsia,lightred,
+ lightblue,black,pink,yellow,gray};
+
+colorPen.cyclic=true;
+
+pen[] monoPen={solid,dashed,dotted,longdashed,dashdotted,
+ longdashdotted};
+monoPen.cyclic=true;
+
+pen Pen(int n)
+{
+ return (settings.gray || settings.bw) ? monoPen[n] : colorPen[n];
+}
+
+pen Pentype(int n)
+{
+ return (settings.gray || settings.bw) ? monoPen[n] : monoPen[n]+colorPen[n];
+}
+
+real dotsize(pen p=currentpen)
+{
+ return dotfactor*linewidth(p);
+}
+
+pen fontsize(real size)
+{
+ return fontsize(size,1.2*size);
+}
+
+real labelmargin(pen p=currentpen)
+{
+ return labelmargin*fontsize(p);
+}
+
+void write(file file=stdout, string s="", pen[] p)
+{
+ for(int i=0; i < p.length; ++i)
+ write(file,s,p[i],endl);
+}
+
+void usetypescript(string s, string encoding="")
+{
+ string s="\usetypescript["+s+"]";
+ if(encoding != "") s +="["+encoding+"]";
+ texpreamble(s);
+}
+
+pen font(string name, string options="")
+{
+ // Work around misalignment in ConTeXt switchtobodyfont if font is not found.
+ return fontcommand(settings.tex == "context" ?
+ "\switchtobodyfont["+name+
+ (options == "" ? "" : ","+options)+
+ "]\removeunwantedspaces" :
+ "\font\ASYfont="+name+"\ASYfont");
+}
+
+pen font(string name, real size, string options="")
+{
+ string s=(string) (size/pt)+"pt";
+ if(settings.tex == "context")
+ return fontsize(size)+font(name+","+s,options);
+ return fontsize(size)+font(name+" at "+s);
+}
+
+pen font(string encoding, string family, string series, string shape)
+{
+ return fontcommand("\usefont{"+encoding+"}{"+family+"}{"+series+"}{"+shape+
+ "}");
+}
+
+pen AvantGarde(string series="m", string shape="n")
+{
+ return font("OT1","pag",series,shape);
+}
+pen Bookman(string series="m", string shape="n")
+{
+ return font("OT1","pbk",series,shape);
+}
+pen Courier(string series="m", string shape="n")
+{
+ return font("OT1","pcr",series,shape);
+}
+pen Helvetica(string series="m", string shape="n")
+{
+ return font("OT1","phv",series,shape);
+}
+pen NewCenturySchoolBook(string series="m", string shape="n")
+{
+ return font("OT1","pnc",series,shape);
+}
+pen Palatino(string series="m", string shape="n")
+{
+ return font("OT1","ppl",series,shape);
+}
+pen TimesRoman(string series="m", string shape="n")
+{
+ return font("OT1","ptm",series,shape);
+}
+pen ZapfChancery(string series="m", string shape="n")
+{
+ return font("OT1","pzc",series,shape);
+}
+pen Symbol(string series="m", string shape="n")
+{
+ return font("OT1","psy",series,shape);
+}
+pen ZapfDingbats(string series="m", string shape="n")
+{
+ return font("OT1","pzd",series,shape);
+}
+
+pen squarepen=makepen(shift(-0.5,-0.5)*unitsquare);
+
+struct hsv {
+ real h;
+ real v;
+ real s;
+ void operator init(real h, real s, real v) {
+ this.h=h;
+ this.s=s;
+ this.v=v;
+ }
+ void operator init(pen p) {
+ real[] c=colors(rgb(p));
+ real r=c[0];
+ real g=c[1];
+ real b=c[2];
+ real M=max(r,g,b);
+ real m=min(r,g,b);
+ if(M == m) this.h=0;
+ else {
+ real denom=1/(M-m);
+ if(M == r) {
+ this.h=60*(g-b)*denom;
+ if(g < b) h += 360;
+ } else if(M == g) {
+ this.h=60*(b-r)*denom+120;
+ } else
+ this.h=60*(r-g)*denom+240;
+ }
+ this.s=M == 0 ? 0 : 1-m/M;
+ this.v=M;
+ }
+ // return an rgb pen corresponding to h in [0,360) and s and v in [0,1].
+ pen rgb() {
+ real H=(h % 360)/60;
+ int i=floor(H) % 6;
+ real f=H-i;
+ real[] V={v,v*(1-s),v*(1-(i % 2 == 0 ? 1-f : f)*s)};
+ int[] a={0,2,1,1,2,0};
+ int[] b={2,0,0,2,1,1};
+ int[] c={1,1,2,0,0,2};
+ return rgb(V[a[i]],V[b[i]],V[c[i]]);
+ }
+}
+
+pen operator cast(hsv hsv)
+{
+ return hsv.rgb();
+}
+
+hsv operator cast(pen p)
+{
+ return hsv(p);
+}
+
+real[] rgba(pen p)
+{
+ real[] a=colors(rgb(p));
+ a.push(opacity(p));
+ return a;
+}
+
+pen rgba(real[] a)
+{
+ return rgb(a[0],a[1],a[2])+opacity(a[3]);
+}
+
+// Return a pen corresponding to a given 6-character RGB hexadecimal string.
+pen rgb(string s)
+{
+ int offset=substr(s,0,1) == '#' ? 1 : 0;
+ real value(string s, int i) {return hex(substr(s,2i+offset,2))/255;}
+ return rgb(value(s,0),value(s,1),value(s,2));
+}
+
+pen RGB(int r, int g, int b)
+{
+ return rgb(r/255,g/255,b/255);
+}
+
+pen[] operator +(pen[] a, pen b)
+{
+ return sequence(new pen(int i) {return a[i]+b;},a.length);
+}
+
+pen[] operator +(pen a, pen[] b)
+{
+ return sequence(new pen(int i) {return a+b[i];},b.length);
+}
+
+// Interpolate an array of pens in rgb space using by default their minimum
+// opacity.
+pen mean(pen[] p, real opacity(real[])=min)
+{
+ if(p.length == 0) return nullpen;
+ real[] a=rgba(p[0]);
+ real[] t=new real[p.length];
+ t[0]=a[3];
+ for(int i=1; i < p.length; ++i) {
+ real[] b=rgba(p[i]);
+ a += b;
+ t[i]=b[3];
+ }
+ a /= p.length;
+ return rgb(a[0],a[1],a[2])+opacity(opacity(t));
+}
+
+pen[] mean(pen[][] palette, real opacity(real[])=min)
+{
+ return sequence(new pen(int i) {return mean(palette[i],opacity);},
+ palette.length);
+}
diff --git a/graphics/asymptote/base/plain_picture.asy b/graphics/asymptote/base/plain_picture.asy
new file mode 100644
index 0000000000..025e6741cf
--- /dev/null
+++ b/graphics/asymptote/base/plain_picture.asy
@@ -0,0 +1,1694 @@
+// Pre picture <<<1
+import plain_scaling;
+import plain_bounds;
+
+include plain_prethree;
+
+// This variable is required by asymptote.sty.
+pair viewportsize=0; // Horizontal and vertical viewport limits.
+
+restricted bool Aspect=true;
+restricted bool IgnoreAspect=false;
+
+struct coords3 {
+ coord[] x,y,z;
+ void erase() {
+ x.delete();
+ y.delete();
+ z.delete();
+ }
+ // Only a shallow copy of the individual elements of x and y
+ // is needed since, once entered, they are never modified.
+ coords3 copy() {
+ coords3 c=new coords3;
+ c.x=copy(x);
+ c.y=copy(y);
+ c.z=copy(z);
+ return c;
+ }
+ void append(coords3 c) {
+ x.append(c.x);
+ y.append(c.y);
+ z.append(c.z);
+ }
+ void push(triple user, triple truesize) {
+ x.push(coord.build(user.x,truesize.x));
+ y.push(coord.build(user.y,truesize.y));
+ z.push(coord.build(user.z,truesize.z));
+ }
+ void push(coord cx, coord cy, coord cz) {
+ x.push(cx);
+ y.push(cy);
+ z.push(cz);
+ }
+ void push(transform3 t, coords3 c1, coords3 c2, coords3 c3) {
+ for(int i=0; i < c1.x.length; ++i) {
+ coord cx=c1.x[i], cy=c2.y[i], cz=c3.z[i];
+ triple tinf=shiftless(t)*(0,0,0);
+ triple z=t*(cx.user,cy.user,cz.user);
+ triple w=(cx.truesize,cy.truesize,cz.truesize);
+ w=length(w)*unit(shiftless(t)*w);
+ coord Cx,Cy,Cz;
+ Cx.user=z.x;
+ Cy.user=z.y;
+ Cz.user=z.z;
+ Cx.truesize=w.x;
+ Cy.truesize=w.y;
+ Cz.truesize=w.z;
+ push(Cx,Cy,Cz);
+ }
+ }
+}
+
+// scaleT and Legend <<<
+typedef real scalefcn(real x);
+
+struct scaleT {
+ scalefcn T,Tinv;
+ bool logarithmic;
+ bool automin,automax;
+ void operator init(scalefcn T, scalefcn Tinv, bool logarithmic=false,
+ bool automin=false, bool automax=false) {
+ this.T=T;
+ this.Tinv=Tinv;
+ this.logarithmic=logarithmic;
+ this.automin=automin;
+ this.automax=automax;
+ }
+ scaleT copy() {
+ scaleT dest=scaleT(T,Tinv,logarithmic,automin,automax);
+ return dest;
+ }
+};
+
+scaleT operator init()
+{
+ scaleT S=scaleT(identity,identity);
+ return S;
+}
+
+typedef void boundRoutine();
+
+struct autoscaleT {
+ scaleT scale;
+ scaleT postscale;
+ real tickMin=-infinity, tickMax=infinity;
+ boundRoutine[] bound; // Optional routines to recompute the bounding box.
+ bool automin=false, automax=false;
+ bool automin() {return automin && scale.automin;}
+ bool automax() {return automax && scale.automax;}
+
+ real T(real x) {return postscale.T(scale.T(x));}
+ scalefcn T() {return scale.logarithmic ? postscale.T : T;}
+ real Tinv(real x) {return scale.Tinv(postscale.Tinv(x));}
+
+ autoscaleT copy() {
+ autoscaleT dest=new autoscaleT;
+ dest.scale=scale.copy();
+ dest.postscale=postscale.copy();
+ dest.tickMin=tickMin;
+ dest.tickMax=tickMax;
+ dest.bound=copy(bound);
+ dest.automin=(bool) automin;
+ dest.automax=(bool) automax;
+ return dest;
+ }
+}
+
+struct ScaleT {
+ bool set;
+ autoscaleT x;
+ autoscaleT y;
+ autoscaleT z;
+
+ ScaleT copy() {
+ ScaleT dest=new ScaleT;
+ dest.set=set;
+ dest.x=x.copy();
+ dest.y=y.copy();
+ dest.z=z.copy();
+ return dest;
+ }
+};
+
+struct Legend {
+ string label;
+ pen plabel;
+ pen p;
+ frame mark;
+ bool above;
+ void operator init(string label, pen plabel=currentpen, pen p=nullpen,
+ frame mark=newframe, bool above=true) {
+ this.label=label;
+ this.plabel=plabel;
+ this.p=(p == nullpen) ? plabel : p;
+ this.mark=mark;
+ this.above=above;
+ }
+}
+
+// >>>
+
+// Frame Alignment was here
+
+triple min3(pen p)
+{
+ return linewidth(p)*(-0.5,-0.5,-0.5);
+}
+
+triple max3(pen p)
+{
+ return linewidth(p)*(0.5,0.5,0.5);
+}
+
+// A function that draws an object to frame pic, given that the transform
+// from user coordinates to true-size coordinates is t.
+typedef void drawer(frame f, transform t);
+
+// A generalization of drawer that includes the final frame's bounds.
+// TODO: Add documentation as to what T is.
+typedef void drawerBound(frame f, transform t, transform T, pair lb, pair rt);
+
+struct node {
+ drawerBound d;
+ string key;
+ void operator init(drawerBound d, string key=xasyKEY()) {
+ this.d=d;
+ this.key=key;
+ }
+}
+
+// PairOrTriple <<<1
+// This struct is used to represent a userMin/userMax which serves as both a
+// pair and a triple depending on the context.
+struct pairOrTriple {
+ real x,y,z;
+ void init() { x = y = z = 0; }
+};
+void copyPairOrTriple(pairOrTriple dest, pairOrTriple src)
+{
+ dest.x = src.x;
+ dest.y = src.y;
+ dest.z = src.z;
+}
+pair operator cast (pairOrTriple a) {
+ return (a.x, a.y);
+};
+triple operator cast (pairOrTriple a) {
+ return (a.x, a.y, a.z);
+}
+void write(pairOrTriple a) {
+ write((triple) a);
+}
+
+struct picture { // <<<1
+ // Nodes <<<2
+ // Three-dimensional version of drawer and drawerBound:
+ typedef void drawer3(frame f, transform3 t, picture pic, projection P);
+ typedef void drawerBound3(frame f, transform3 t, transform3 T,
+ picture pic, projection P, triple lb, triple rt);
+
+ struct node3 {
+ drawerBound3 d;
+ string key;
+ void operator init(drawerBound3 d, string key=xasyKEY()) {
+ this.d=d;
+ this.key=key;
+ }
+ }
+
+ // The functions to do the deferred drawing.
+ node[] nodes;
+ node3[] nodes3;
+
+ bool uptodate=true;
+
+ struct bounds3 {
+ coords3 point,min,max;
+ bool exact=true; // An accurate picture bounds is provided by the user.
+ void erase() {
+ point.erase();
+ min.erase();
+ max.erase();
+ }
+ bounds3 copy() {
+ bounds3 b=new bounds3;
+ b.point=point.copy();
+ b.min=min.copy();
+ b.max=max.copy();
+ b.exact=exact;
+ return b;
+ }
+ }
+
+ bounds bounds;
+ bounds3 bounds3;
+
+ // Other Fields <<<2
+ // Transform to be applied to this picture.
+ transform T;
+ transform3 T3;
+
+ // The internal representation of the 3D user bounds.
+ private pairOrTriple umin, umax;
+ private bool usetx, usety, usetz;
+
+ ScaleT scale; // Needed by graph
+ Legend[] legend;
+
+ pair[] clipmax; // Used by beginclip/endclip
+ pair[] clipmin;
+
+ // The maximum sizes in the x, y, and z directions; zero means no restriction.
+ real xsize=0, ysize=0;
+
+ real xsize3=0, ysize3=0, zsize3=0;
+
+ // Fixed unitsizes in the x y, and z directions; zero means use
+ // xsize, ysize, and zsize.
+ real xunitsize=0, yunitsize=0, zunitsize=0;
+
+ // If true, the x and y directions must be scaled by the same amount.
+ bool keepAspect=true;
+
+ // A fixed scaling transform.
+ bool fixed;
+ transform fixedscaling;
+
+ // Init and erase <<<2
+ void init() {
+ umin.init();
+ umax.init();
+ usetx=usety=usetz=false;
+ T3=identity(4);
+ }
+ init();
+
+ // Erase the current picture, retaining bounds.
+ void clear() {
+ nodes.delete();
+ nodes3.delete();
+ legend.delete();
+ }
+
+ // Erase the current picture, retaining any size specification.
+ void erase() {
+ clear();
+ bounds.erase();
+ bounds3.erase();
+ T=identity();
+ scale=new ScaleT;
+ init();
+ }
+
+ // Empty <<<2
+ bool empty2() {
+ return nodes.length == 0;
+ }
+
+ bool empty3() {
+ return nodes3.length == 0;
+ }
+
+ bool empty() {
+ return empty2() && empty3();
+ }
+
+ // User min/max <<<2
+ pair userMin2() {return bounds.userMin(); }
+ pair userMax2() {return bounds.userMax(); }
+
+ bool userSetx2() { return bounds.userBoundsAreSet(); }
+ bool userSety2() { return bounds.userBoundsAreSet(); }
+
+ triple userMin3() { return umin; }
+ triple userMax3() { return umax; }
+
+ bool userSetx3() { return usetx; }
+ bool userSety3() { return usety; }
+ bool userSetz3() { return usetz; }
+
+ private typedef real binop(real, real);
+
+ // Helper functions for finding the minimum/maximum of two data, one of
+ // which may not be defined.
+ private static real merge(real x1, bool set1, real x2, bool set2, binop m)
+ {
+ return set1 ? (set2 ? m(x1,x2) : x1) : x2;
+ }
+ private pairOrTriple userExtreme(pair u2(), triple u3(), binop m)
+ {
+ bool setx2 = userSetx2();
+ bool sety2 = userSety2();
+ bool setx3 = userSetx3();
+ bool sety3 = userSety3();
+
+ pair p;
+ if (setx2 || sety2)
+ p = u2();
+ triple t = u3();
+
+ pairOrTriple r;
+ r.x = merge(p.x, setx2, t.x, setx3, m);
+ r.y = merge(p.y, sety2, t.y, sety3, m);
+ r.z = t.z;
+
+ return r;
+ }
+
+ // The combination of 2D and 3D data.
+ pairOrTriple userMin() {
+ return userExtreme(userMin2, userMin3, min);
+ }
+ pairOrTriple userMax() {
+ return userExtreme(userMax2, userMax3, max);
+ }
+
+ bool userSetx() { return userSetx2() || userSetx3(); }
+ bool userSety() { return userSety2() || userSety3(); }
+ bool userSetz() = userSetz3;
+
+ // Functions for setting the user bounds.
+ void userMinx3(real x) {
+ umin.x=x;
+ usetx=true;
+ }
+
+ void userMiny3(real y) {
+ umin.y=y;
+ usety=true;
+ }
+
+ void userMinz3(real z) {
+ umin.z=z;
+ usetz=true;
+ }
+
+ void userMaxx3(real x) {
+ umax.x=x;
+ usetx=true;
+ }
+
+ void userMaxy3(real y) {
+ umax.y=y;
+ usety=true;
+ }
+
+ void userMaxz3(real z) {
+ umax.z=z;
+ usetz=true;
+ }
+
+ void userMinx2(real x) { bounds.alterUserBound("minx", x); }
+ void userMinx(real x) { userMinx2(x); userMinx3(x); }
+ void userMiny2(real y) { bounds.alterUserBound("miny", y); }
+ void userMiny(real y) { userMiny2(y); userMiny3(y); }
+ void userMaxx2(real x) { bounds.alterUserBound("maxx", x); }
+ void userMaxx(real x) { userMaxx2(x); userMaxx3(x); }
+ void userMaxy2(real y) { bounds.alterUserBound("maxy", y); }
+ void userMaxy(real y) { userMaxy2(y); userMaxy3(y); }
+ void userMinz(real z) = userMinz3;
+ void userMaxz(real z) = userMaxz3;
+
+ void userCorners3(triple c000, triple c001, triple c010, triple c011,
+ triple c100, triple c101, triple c110, triple c111) {
+ umin.x = min(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x);
+ umin.y = min(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y);
+ umin.z = min(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z);
+ umax.x = max(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x);
+ umax.y = max(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y);
+ umax.z = max(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z);
+ }
+
+ // Cache the current user-space bounding box x coodinates
+ void userBoxX3(real min, real max, binop m=min, binop M=max) {
+ if (usetx) {
+ umin.x=m(umin.x,min);
+ umax.x=M(umax.x,max);
+ } else {
+ umin.x=min;
+ umax.x=max;
+ usetx=true;
+ }
+ }
+
+ // Cache the current user-space bounding box y coodinates
+ void userBoxY3(real min, real max, binop m=min, binop M=max) {
+ if (usety) {
+ umin.y=m(umin.y,min);
+ umax.y=M(umax.y,max);
+ } else {
+ umin.y=min;
+ umax.y=max;
+ usety=true;
+ }
+ }
+
+ // Cache the current user-space bounding box z coodinates
+ void userBoxZ3(real min, real max, binop m=min, binop M=max) {
+ if (usetz) {
+ umin.z=m(umin.z,min);
+ umax.z=M(umax.z,max);
+ } else {
+ umin.z=min;
+ umax.z=max;
+ usetz=true;
+ }
+ }
+
+ // Cache the current user-space bounding box
+ void userBox3(triple min, triple max) {
+ userBoxX3(min.x,max.x);
+ userBoxY3(min.y,max.y);
+ userBoxZ3(min.z,max.z);
+ }
+
+ // Add drawer <<<2
+ void add(drawerBound d, bool exact=false, bool above=true) {
+ uptodate=false;
+ if(!exact) bounds.exact=false;
+ if(above)
+ nodes.push(node(d));
+ else
+ nodes.insert(0,node(d));
+ }
+
+ // Faster implementation of most common case.
+ void addExactAbove(drawerBound d) {
+ uptodate=false;
+ nodes.push(node(d));
+ }
+
+ void add(drawer d, bool exact=false, bool above=true) {
+ add(new void(frame f, transform t, transform T, pair, pair) {
+ d(f,t*T);
+ },exact,above);
+ }
+
+ void add(drawerBound3 d, bool exact=false, bool above=true) {
+ uptodate=false;
+ if(!exact) bounds.exact=false;
+ if(above)
+ nodes3.push(node3(d));
+ else
+ nodes3.insert(0,node3(d));
+ }
+
+ void add(drawer3 d, bool exact=false, bool above=true) {
+ add(new void(frame f, transform3 t, transform3 T, picture pic,
+ projection P, triple, triple) {
+ d(f,t*T,pic,P);
+ },exact,above);
+ }
+
+ // Clip <<<2
+ void clip(pair min, pair max, drawer d, bool exact=false) {
+ bounds.clip(min, max);
+ this.add(d,exact);
+ }
+
+ void clip(pair min, pair max, drawerBound d, bool exact=false) {
+ bounds.clip(min, max);
+ this.add(d,exact);
+ }
+
+ // Add sizing <<<2
+ // Add a point to the sizing.
+ void addPoint(pair user, pair truesize=0) {
+ bounds.addPoint(user,truesize);
+ //userBox(user,user);
+ }
+
+ // Add a point to the sizing, accounting also for the size of the pen.
+ void addPoint(pair user, pair truesize=0, pen p) {
+ addPoint(user,truesize+min(p));
+ addPoint(user,truesize+max(p));
+ }
+
+ void addPoint(triple user, triple truesize=(0,0,0)) {
+ bounds3.point.push(user,truesize);
+ userBox3(user,user);
+ }
+
+ void addPoint(triple user, triple truesize=(0,0,0), pen p) {
+ addPoint(user,truesize+min3(p));
+ addPoint(user,truesize+max3(p));
+ }
+
+ // Add a box to the sizing.
+ void addBox(pair userMin, pair userMax, pair trueMin=0, pair trueMax=0) {
+ bounds.addBox(userMin, userMax, trueMin, trueMax);
+ }
+
+ void addBox(triple userMin, triple userMax, triple trueMin=(0,0,0),
+ triple trueMax=(0,0,0)) {
+ bounds3.min.push(userMin,trueMin);
+ bounds3.max.push(userMax,trueMax);
+ userBox3(userMin,userMax);
+ }
+
+ // For speed reason, we unravel the addPath routines from bounds. This
+ // avoids an extra function call.
+ from bounds unravel addPath;
+
+ // Size commands <<<2
+ void size(real x, real y=x, bool keepAspect=this.keepAspect) {
+ if(!empty()) uptodate=false;
+ xsize=x;
+ ysize=y;
+ this.keepAspect=keepAspect;
+ }
+
+ void size3(real x, real y=x, real z=y, bool keepAspect=this.keepAspect) {
+ if(!empty3()) uptodate=false;
+ xsize3=x;
+ ysize3=y;
+ zsize3=z;
+ this.keepAspect=keepAspect;
+ }
+
+ void unitsize(real x, real y=x, real z=y) {
+ uptodate=false;
+ xunitsize=x;
+ yunitsize=y;
+ zunitsize=z;
+ }
+
+ // min/max of picture <<<2
+ // Calculate the min for the final frame, given the coordinate transform.
+ pair min(transform t) {
+ return bounds.min(t);
+ }
+
+ // Calculate the max for the final frame, given the coordinate transform.
+ pair max(transform t) {
+ return bounds.max(t);
+ }
+
+ // Calculate the min for the final frame, given the coordinate transform.
+ triple min(transform3 t) {
+ if(bounds3.min.x.length == 0 && bounds3.point.x.length == 0 &&
+ bounds3.max.x.length == 0) return (0,0,0);
+ triple a=t*(1,1,1)-t*(0,0,0), b=t*(0,0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+ scaling zs=scaling.build(a.z,b.z);
+ return (min(min(min(infinity,xs,bounds3.point.x),xs,bounds3.min.x),
+ xs,bounds3.max.x),
+ min(min(min(infinity,ys,bounds3.point.y),ys,bounds3.min.y),
+ ys,bounds3.max.y),
+ min(min(min(infinity,zs,bounds3.point.z),zs,bounds3.min.z),
+ zs,bounds3.max.z));
+ }
+
+ // Calculate the max for the final frame, given the coordinate transform.
+ triple max(transform3 t) {
+ if(bounds3.min.x.length == 0 && bounds3.point.x.length == 0 &&
+ bounds3.max.x.length == 0) return (0,0,0);
+ triple a=t*(1,1,1)-t*(0,0,0), b=t*(0,0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+ scaling zs=scaling.build(a.z,b.z);
+ return (max(max(max(-infinity,xs,bounds3.point.x),xs,bounds3.min.x),
+ xs,bounds3.max.x),
+ max(max(max(-infinity,ys,bounds3.point.y),ys,bounds3.min.y),
+ ys,bounds3.max.y),
+ max(max(max(-infinity,zs,bounds3.point.z),zs,bounds3.min.z),
+ zs,bounds3.max.z));
+ }
+
+ void append(coords3 point, coords3 min, coords3 max, transform3 t,
+ bounds3 bounds)
+ {
+ // Add the coord info to this picture.
+ if(t == identity4) {
+ point.append(bounds.point);
+ min.append(bounds.min);
+ max.append(bounds.max);
+ } else {
+ point.push(t,bounds.point,bounds.point,bounds.point);
+ // Add in all 8 corner points, to properly size cuboid pictures.
+ point.push(t,bounds.min,bounds.min,bounds.min);
+ point.push(t,bounds.min,bounds.min,bounds.max);
+ point.push(t,bounds.min,bounds.max,bounds.min);
+ point.push(t,bounds.min,bounds.max,bounds.max);
+ point.push(t,bounds.max,bounds.min,bounds.min);
+ point.push(t,bounds.max,bounds.min,bounds.max);
+ point.push(t,bounds.max,bounds.max,bounds.min);
+ point.push(t,bounds.max,bounds.max,bounds.max);
+ }
+ }
+
+ // Scaling and Fit <<<2
+ // Returns the transform for turning user-space pairs into true-space pairs.
+ transform scaling(real xsize, real ysize, bool keepAspect=true,
+ bool warn=true) {
+ bounds b = (T == identity()) ? this.bounds : T * this.bounds;
+
+ return b.scaling(xsize, ysize, xunitsize, yunitsize, keepAspect, warn);
+ }
+
+ transform scaling(bool warn=true) {
+ return scaling(xsize,ysize,keepAspect,warn);
+ }
+
+ // Returns the transform for turning user-space pairs into true-space triples.
+ transform3 scaling(real xsize, real ysize, real zsize, bool keepAspect=true,
+ bool warn=true) {
+ if(xsize == 0 && xunitsize == 0 && ysize == 0 && yunitsize == 0
+ && zsize == 0 && zunitsize == 0)
+ return identity(4);
+
+ coords3 Coords;
+
+ append(Coords,Coords,Coords,T3,bounds3);
+
+ real sx;
+ if(xunitsize == 0) {
+ if(xsize != 0) sx=calculateScaling("x",Coords.x,xsize,warn);
+ } else sx=xunitsize;
+
+ real sy;
+ if(yunitsize == 0) {
+ if(ysize != 0) sy=calculateScaling("y",Coords.y,ysize,warn);
+ } else sy=yunitsize;
+
+ real sz;
+ if(zunitsize == 0) {
+ if(zsize != 0) sz=calculateScaling("z",Coords.z,zsize,warn);
+ } else sz=zunitsize;
+
+ if(sx == 0) {
+ sx=max(sy,sz);
+ if(sx == 0)
+ return identity(4);
+ }
+ if(sy == 0) sy=max(sz,sx);
+ if(sz == 0) sz=max(sx,sy);
+
+ if(keepAspect && (xunitsize == 0 || yunitsize == 0 || zunitsize == 0))
+ return scale3(min(sx,sy,sz));
+ else
+ return scale(sx,sy,sz);
+ }
+
+ transform3 scaling3(bool warn=true) {
+ return scaling(xsize3,ysize3,zsize3,keepAspect,warn);
+ }
+
+ frame fit(transform t, transform T0=T, pair m, pair M) {
+ frame f;
+ for(node n : nodes) {
+ xasyKEY(n.key);
+ n.d(f,t,T0,m,M);
+ }
+ return f;
+ }
+
+ frame fit3(transform3 t, transform3 T0=T3, picture pic, projection P,
+ triple m, triple M) {
+ frame f;
+ for(node3 n : nodes3) {
+ xasyKEY(n.key);
+ n.d(f,t,T0,pic,P,m,M);
+ }
+ return f;
+ }
+
+ // Returns a rigid version of the picture using t to transform user coords
+ // into truesize coords.
+ frame fit(transform t) {
+ return fit(t,min(t),max(t));
+ }
+
+ frame fit3(transform3 t, picture pic, projection P) {
+ return fit3(t,pic,P,min(t),max(t));
+ }
+
+ // Add drawer wrappers <<<2
+ void add(void d(picture, transform), bool exact=false) {
+ add(new void(frame f, transform t) {
+ picture opic=new picture;
+ d(opic,t);
+ add(f,opic.fit(identity()));
+ },exact);
+ }
+
+ void add(void d(picture, transform3), bool exact=false, bool above=true) {
+ add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic=new picture;
+ d(opic,t);
+ add(f,opic.fit3(identity4,pic2,P));
+ },exact,above);
+ }
+
+ void add(void d(picture, transform3, transform3, triple, triple),
+ bool exact=false, bool above=true) {
+ add(new void(frame f, transform3 t, transform3 T, picture pic2,
+ projection P, triple lb, triple rt) {
+ picture opic=new picture;
+ d(opic,t,T,lb,rt);
+ add(f,opic.fit3(identity4,pic2,P));
+ },exact,above);
+ }
+
+ // More scaling <<<2
+ frame scaled() {
+ frame f=fit(fixedscaling);
+ pair d=size(f);
+ static real epsilon=100*realEpsilon;
+ if(d.x > xsize*(1+epsilon))
+ warning("xlimit","frame exceeds xlimit: "+(string) d.x+" > "+
+ (string) xsize);
+ if(d.y > ysize*(1+epsilon))
+ warning("ylimit","frame exceeds ylimit: "+(string) d.y+" > "+
+ (string) ysize);
+ return f;
+ }
+
+ // Calculate additional scaling required if only an approximate picture
+ // size estimate is available.
+ transform scale(frame f, real xsize=this.xsize, real ysize=this.ysize,
+ bool keepaspect=this.keepAspect) {
+ if(bounds.exact) return identity();
+ pair m=min(f);
+ pair M=max(f);
+ real width=M.x-m.x;
+ real height=M.y-m.y;
+ real xgrow=xsize == 0 || width == 0 ? 1 : xsize/width;
+ real ygrow=ysize == 0 || height == 0 ? 1 : ysize/height;
+ if(keepAspect) {
+ real[] grow;
+ if(xsize > 0) grow.push(xgrow);
+ if(ysize > 0) grow.push(ygrow);
+ return scale(grow.length == 0 ? 1 : min(grow));
+ } else return scale(xgrow,ygrow);
+
+ }
+
+ // Calculate additional scaling required if only an approximate picture
+ // size estimate is available.
+ transform3 scale3(frame f, real xsize3=this.xsize3,
+ real ysize3=this.ysize3, real zsize3=this.zsize3,
+ bool keepaspect=this.keepAspect) {
+ if(bounds3.exact) return identity(4);
+ triple m=min3(f);
+ triple M=max3(f);
+ real width=M.x-m.x;
+ real height=M.y-m.y;
+ real depth=M.z-m.z;
+ real xgrow=xsize3 == 0 || width == 0 ? 1 : xsize3/width;
+ real ygrow=ysize3 == 0 || height == 0 ? 1 : ysize3/height;
+ real zgrow=zsize3 == 0 || depth == 0 ? 1 : zsize3/depth;
+ if(keepAspect) {
+ real[] grow;
+ if(xsize3 > 0) grow.push(xgrow);
+ if(ysize3 > 0) grow.push(ygrow);
+ if(zsize3 > 0) grow.push(zgrow);
+ return scale3(grow.length == 0 ? 1 : min(grow));
+ } else return scale(xgrow,ygrow,zgrow);
+ }
+
+ // calculateTransform with scaling <<<2
+ // Return the transform that would be used to fit the picture to a frame
+ transform calculateTransform(real xsize, real ysize, bool keepAspect=true,
+ bool warn=true) {
+ transform t=scaling(xsize,ysize,keepAspect,warn);
+ return scale(fit(t),xsize,ysize,keepAspect)*t;
+ }
+
+ transform calculateTransform(bool warn=true) {
+ if(fixed) return fixedscaling;
+ return calculateTransform(xsize,ysize,keepAspect,warn);
+ }
+
+ transform3 calculateTransform3(real xsize=xsize3, real ysize=ysize3,
+ real zsize=zsize3,
+ bool keepAspect=true, bool warn=true,
+ projection P=currentprojection) {
+ transform3 t=scaling(xsize,ysize,zsize,keepAspect,warn);
+ return scale3(fit3(t,null,P),keepAspect)*t;
+ }
+
+ // min/max with xsize and ysize <<<2
+ // NOTE: These are probably very slow as implemented.
+ pair min(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect, bool warn=true) {
+ return min(calculateTransform(xsize,ysize,keepAspect,warn));
+ }
+
+ pair max(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect, bool warn=true) {
+ return max(calculateTransform(xsize,ysize,keepAspect,warn));
+ }
+
+ triple min3(real xsize=this.xsize3, real ysize=this.ysize3,
+ real zsize=this.zsize3, bool keepAspect=this.keepAspect,
+ bool warn=true, projection P) {
+ return min(calculateTransform3(xsize,ysize,zsize,keepAspect,warn,P));
+ }
+
+ triple max3(real xsize=this.xsize3, real ysize=this.ysize3,
+ real zsize=this.zsize3, bool keepAspect=this.keepAspect,
+ bool warn=true, projection P) {
+ return max(calculateTransform3(xsize,ysize,zsize,keepAspect,warn,P));
+ }
+
+ // More Fitting <<<2
+ // Returns the 2D picture fit to the requested size.
+ frame fit2(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect) {
+ if(fixed) return scaled();
+ if(empty2())
+ return newframe;
+
+ transform t=scaling(xsize,ysize,keepAspect);
+ frame f=fit(t);
+ transform s=scale(f,xsize,ysize,keepAspect);
+ if(s == identity()) return f;
+ return fit(s*t);
+ }
+
+ static frame fitter(string,picture,string,real,real,bool,bool,string,string,
+ light,projection);
+ frame fit(string prefix="", string format="",
+ real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect, bool view=false,
+ string options="", string script="", light light=currentlight,
+ projection P=currentprojection) {
+ return fitter == null ? fit2(xsize,ysize,keepAspect) :
+ fitter(prefix,this,format,xsize,ysize,keepAspect,view,options,script,
+ light,P);
+ }
+
+ // Fit a 3D picture.
+ frame fit3(projection P=currentprojection) {
+ if(settings.render == 0) return fit(P);
+ if(fixed) return scaled();
+ if(empty3()) return newframe;
+ transform3 t=scaling(xsize3,ysize3,zsize3,keepAspect);
+ frame f=fit3(t,null,P);
+ transform3 s=scale3(f,xsize3,ysize3,zsize3,keepAspect);
+ if(s == identity4) return f;
+ return fit3(s*t,null,P);
+ }
+
+ // In case only an approximate picture size estimate is available, return the
+ // fitted frame slightly scaled (including labels and true size distances)
+ // so that it precisely meets the given size specification.
+ frame scale(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect) {
+ frame f=fit(xsize,ysize,keepAspect);
+ transform s=scale(f,xsize,ysize,keepAspect);
+ if(s == identity()) return f;
+ return s*f;
+ }
+
+ // Copying <<<2
+
+ // Copies enough information to yield the same userMin/userMax.
+ void userCopy2(picture pic) {
+ userMinx2(pic.userMin2().x);
+ userMiny2(pic.userMin2().y);
+ userMaxx2(pic.userMax2().x);
+ userMaxy2(pic.userMax2().y);
+ }
+
+ void userCopy3(picture pic) {
+ copyPairOrTriple(umin, pic.umin);
+ copyPairOrTriple(umax, pic.umax);
+ usetx=pic.usetx;
+ usety=pic.usety;
+ usetz=pic.usetz;
+ }
+
+ void userCopy(picture pic) {
+ userCopy2(pic);
+ userCopy3(pic);
+ }
+
+ // Copies the drawing information, but not the sizing information into a new
+ // picture. Fitting this picture will not scale as the original picture would.
+ picture drawcopy() {
+ picture dest=new picture;
+ dest.nodes=copy(nodes);
+ dest.nodes3=copy(nodes3);
+ dest.T=T;
+ dest.T3=T3;
+
+ // TODO: User bounds are sizing info, which probably shouldn't be part of
+ // a draw copy. Should we move this down to copy()?
+ dest.userCopy3(this);
+
+ dest.scale=scale.copy();
+ dest.legend=copy(legend);
+
+ return dest;
+ }
+
+ // A deep copy of this picture. Modifying the copied picture will not affect
+ // the original.
+ picture copy() {
+ picture dest=drawcopy();
+
+ dest.uptodate=uptodate;
+ dest.bounds=bounds.copy();
+ dest.bounds3=bounds3.copy();
+
+ dest.xsize=xsize; dest.ysize=ysize;
+ dest.xsize3=xsize; dest.ysize3=ysize3; dest.zsize3=zsize3;
+ dest.keepAspect=keepAspect;
+ dest.xunitsize=xunitsize; dest.yunitsize=yunitsize;
+ dest.zunitsize=zunitsize;
+ dest.fixed=fixed; dest.fixedscaling=fixedscaling;
+
+ return dest;
+ }
+
+ // Helper function for defining transformed pictures. Do not call it
+ // directly.
+ picture transformed(transform t) {
+ picture dest=drawcopy();
+
+ // Replace nodes with a single drawer that realizes the transform.
+ node[] oldnodes = dest.nodes;
+ void drawAll(frame f, transform tt, transform T, pair lb, pair rt) {
+ transform Tt = T*t;
+ for (node n : oldnodes) {
+ xasyKEY(n.key);
+ n.d(f,tt,Tt,lb,rt);
+ }
+ }
+ dest.nodes = new node[] {node(drawAll)};
+
+ dest.uptodate=uptodate;
+ dest.bounds=bounds.transformed(t);
+ dest.bounds3=bounds3.copy();
+
+ dest.bounds.exact=false;
+
+ dest.xsize=xsize; dest.ysize=ysize;
+ dest.xsize3=xsize; dest.ysize3=ysize3; dest.zsize3=zsize3;
+ dest.keepAspect=keepAspect;
+ dest.xunitsize=xunitsize; dest.yunitsize=yunitsize;
+ dest.zunitsize=zunitsize;
+ dest.fixed=fixed; dest.fixedscaling=fixedscaling;
+
+ return dest;
+ }
+
+ // Add Picture <<<2
+ // Add a picture to this picture, such that the user coordinates will be
+ // scaled identically when fitted
+ void add(picture src, bool group=true, filltype filltype=NoFill,
+ bool above=true) {
+ // Copy the picture. Only the drawing function closures are needed, so we
+ // only copy them. This needs to be a deep copy, as src could later have
+ // objects added to it that should not be included in this picture.
+
+ if(src == this) abort("cannot add picture to itself");
+
+ uptodate=false;
+
+ picture srcCopy=src.drawcopy();
+ // Draw by drawing the copied picture.
+ if(srcCopy.nodes.length > 0) {
+ nodes.push(node(new void(frame f, transform t, transform T,
+ pair m, pair M) {
+ add(f,srcCopy.fit(t,T*srcCopy.T,m,M),group,filltype,above);
+ }));
+ }
+
+ if(srcCopy.nodes3.length > 0) {
+ nodes3.push(node3(new void(frame f, transform3 t, transform3 T3,
+ picture pic, projection P, triple m, triple M)
+ {
+ add(f,srcCopy.fit3(t,T3*srcCopy.T3,pic,P,m,M),group,above);
+ }));
+ }
+
+ legend.append(src.legend);
+
+ if(src.usetx) userBoxX3(src.umin.x,src.umax.x);
+ if(src.usety) userBoxY3(src.umin.y,src.umax.y);
+ if(src.usetz) userBoxZ3(src.umin.z,src.umax.z);
+
+ bounds.append(srcCopy.T, src.bounds);
+ //append(bounds.point,bounds.min,bounds.max,srcCopy.T,src.bounds);
+ append(bounds3.point,bounds3.min,bounds3.max,srcCopy.T3,src.bounds3);
+
+ //if(!src.bounds.exact) bounds.exact=false;
+ if(!src.bounds3.exact) bounds3.exact=false;
+ }
+}
+
+// Post Struct <<<1
+picture operator * (transform t, picture orig)
+{
+ return orig.transformed(t);
+}
+
+picture operator * (transform3 t, picture orig)
+{
+ picture pic=orig.copy();
+ pic.T3=t*pic.T3;
+ triple umin=pic.userMin3(), umax=pic.userMax3();
+ pic.userCorners3(t*umin,
+ t*(umin.x,umin.y,umax.z),
+ t*(umin.x,umax.y,umin.z),
+ t*(umin.x,umax.y,umax.z),
+ t*(umax.x,umin.y,umin.z),
+ t*(umax.x,umin.y,umax.z),
+ t*(umax.x,umax.y,umin.z),
+ t*umax);
+ pic.bounds3.exact=false;
+ return pic;
+}
+
+picture currentpicture;
+
+void size(picture pic=currentpicture, real x, real y=x,
+ bool keepAspect=pic.keepAspect)
+{
+ pic.size(x,y,keepAspect);
+}
+
+void size(picture pic=currentpicture, transform t)
+{
+ if(pic.empty3()) {
+ pair z=size(pic.fit(t));
+ pic.size(z.x,z.y);
+ }
+}
+
+void size3(picture pic=currentpicture, real x, real y=x, real z=y,
+ bool keepAspect=pic.keepAspect)
+{
+ pic.size3(x,y,z,keepAspect);
+}
+
+void unitsize(picture pic=currentpicture, real x, real y=x, real z=y)
+{
+ pic.unitsize(x,y,z);
+}
+
+void size(picture pic=currentpicture, real xsize, real ysize,
+ pair min, pair max)
+{
+ pair size=max-min;
+ pic.unitsize(size.x != 0 ? xsize/size.x : 0,
+ size.y != 0 ? ysize/size.y : 0);
+}
+
+void size(picture dest, picture src)
+{
+ dest.size(src.xsize,src.ysize,src.keepAspect);
+ dest.size3(src.xsize3,src.ysize3,src.zsize3,src.keepAspect);
+ dest.unitsize(src.xunitsize,src.yunitsize,src.zunitsize);
+}
+
+pair min(picture pic, bool user=false)
+{
+ transform t=pic.calculateTransform();
+ pair z=pic.min(t);
+ return user ? inverse(t)*z : z;
+}
+
+pair max(picture pic, bool user=false)
+{
+ transform t=pic.calculateTransform();
+ pair z=pic.max(t);
+ return user ? inverse(t)*z : z;
+}
+
+pair size(picture pic, bool user=false)
+{
+ transform t=pic.calculateTransform();
+ pair M=pic.max(t);
+ pair m=pic.min(t);
+ if(!user) return M-m;
+ t=inverse(t);
+ return t*M-t*m;
+}
+
+// Frame Alignment <<<
+pair rectify(pair dir)
+{
+ real scale=max(abs(dir.x),abs(dir.y));
+ if(scale != 0) dir *= 0.5/scale;
+ dir += (0.5,0.5);
+ return dir;
+}
+
+pair point(frame f, pair dir)
+{
+ pair m=min(f);
+ pair M=max(f);
+ return m+realmult(rectify(dir),M-m);
+}
+
+path[] align(path[] g, transform t=identity(), pair position,
+ pair align, pen p=currentpen)
+{
+ if(g.length == 0) return g;
+ pair m=min(g);
+ pair M=max(g);
+ pair dir=rectify(inverse(t)*-align);
+ if(basealign(p) == 1)
+ dir -= (0,m.y/(M.y-m.y));
+ pair a=m+realmult(dir,M-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a)*g;
+}
+
+// Returns a transform for aligning frame f in the direction align
+transform shift(frame f, pair align)
+{
+ return shift(align-point(f,-align));
+}
+
+// Returns a copy of frame f aligned in the direction align
+frame align(frame f, pair align)
+{
+ return shift(f,align)*f;
+}
+// >>>
+
+pair point(picture pic=currentpicture, pair dir, bool user=true)
+{
+ pair umin = pic.userMin2();
+ pair umax = pic.userMax2();
+
+ pair z=umin+realmult(rectify(dir),umax-umin);
+ return user ? z : pic.calculateTransform()*z;
+}
+
+pair truepoint(picture pic=currentpicture, pair dir, bool user=true)
+{
+ transform t=pic.calculateTransform();
+ pair m=pic.min(t);
+ pair M=pic.max(t);
+ pair z=m+realmult(rectify(dir),M-m);
+ return user ? inverse(t)*z : z;
+}
+
+// Transform coordinate in [0,1]x[0,1] to current user coordinates.
+pair relative(picture pic=currentpicture, pair z)
+{
+ return pic.userMin2()+realmult(z,pic.userMax2()-pic.userMin2());
+}
+
+void add(picture pic=currentpicture, drawer d, bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+typedef void drawer3(frame f, transform3 t, picture pic, projection P);
+void add(picture pic=currentpicture, drawer3 d, bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+void add(picture pic=currentpicture, void d(picture,transform),
+ bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+void add(picture pic=currentpicture, void d(picture,transform3),
+ bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+void begingroup(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ begingroup(f);
+ },true);
+}
+
+void endgroup(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ endgroup(f);
+ },true);
+}
+
+void Draw(picture pic=currentpicture, path g, pen p=currentpen)
+{
+ pic.add(new void(frame f, transform t) {
+ draw(f,t*g,p);
+ },true);
+ pic.addPath(g,p);
+}
+
+// Default arguments have been removed to increase speed.
+void _draw(picture pic, path g, pen p, margin margin)
+{
+ if (size(nib(p)) == 0 && margin==NoMargin) {
+ // Inline the drawerBound wrapper for speed.
+ pic.addExactAbove(new void(frame f, transform t, transform T, pair, pair) {
+ _draw(f,t*T*g,p);
+ });
+ } else {
+ pic.add(new void(frame f, transform t) {
+ draw(f,margin(t*g,p).g,p);
+ },true);
+ }
+ pic.addPath(g,p);
+}
+
+void Draw(picture pic=currentpicture, explicit path[] g, pen p=currentpen)
+{
+ // Could optimize this by adding one drawer.
+ for(int i=0; i < g.length; ++i) Draw(pic,g[i],p);
+}
+
+void fill(picture pic=currentpicture, path[] g, pen p=currentpen,
+ bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ fill(f,t*g,p,false);
+ },true);
+ pic.addPath(g);
+}
+
+void drawstrokepath(picture pic=currentpicture, path g, pen strokepen,
+ pen p=currentpen)
+{
+ pic.add(new void(frame f, transform t) {
+ draw(f,strokepath(t*g,strokepen),p);
+ },true);
+ pic.addPath(g,p);
+}
+
+void latticeshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ }
+ pic.add(new void(frame f, transform t) {
+ latticeshade(f,t*g,stroke,fillrule,p,t,false);
+ },true);
+ pic.addPath(g);
+}
+
+void axialshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen pena, pair a, bool extenda=true,
+ pen penb, pair b, bool extendb=true, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ axialshade(f,t*g,stroke,pena,t*a,extenda,penb,t*b,extendb,false);
+ },true);
+ pic.addPath(g);
+}
+
+void radialshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen pena, pair a, real ra, bool extenda=true,
+ pen penb, pair b, real rb, bool extendb=true, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ pair A=t*a, B=t*b;
+ real RA=abs(t*(a+ra)-A);
+ real RB=abs(t*(b+rb)-B);
+ radialshade(f,t*g,stroke,pena,A,RA,extenda,penb,B,RB,extendb,false);
+ },true);
+ pic.addPath(g);
+}
+
+void gouraudshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, pair[] z, int[] edges,
+ bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ z=copy(z);
+ edges=copy(edges);
+ }
+ pic.add(new void(frame f, transform t) {
+ gouraudshade(f,t*g,stroke,fillrule,p,t*z,edges,false);
+ },true);
+ pic.addPath(g);
+}
+
+void gouraudshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, int[] edges, bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ edges=copy(edges);
+ }
+ pic.add(new void(frame f, transform t) {
+ gouraudshade(f,t*g,stroke,fillrule,p,edges,false);
+ },true);
+ pic.addPath(g);
+}
+
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, path[] b=g,
+ pair[][] z=new pair[][], bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ b=copy(b);
+ z=copy(z);
+ }
+ pic.add(new void(frame f, transform t) {
+ pair[][] Z=new pair[z.length][];
+ for(int i=0; i < z.length; ++i)
+ Z[i]=t*z[i];
+ tensorshade(f,t*g,stroke,fillrule,p,t*b,Z,false);
+ },true);
+ pic.addPath(g);
+}
+
+void tensorshade(frame f, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath)
+{
+ tensorshade(f,g,stroke,fillrule,new pen[][] {p},b);
+}
+
+void tensorshade(frame f, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath, pair[] z)
+{
+ tensorshade(f,g,stroke,fillrule,new pen[][] {p},b,new pair[][] {z});
+}
+
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath)
+{
+ tensorshade(pic,g,stroke,fillrule,new pen[][] {p},b);
+}
+
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath, pair[] z)
+{
+ tensorshade(pic,g,stroke,fillrule,new pen[][] {p},b,new pair[][] {z});
+}
+
+// Smoothly shade the regions between consecutive paths of a sequence using a
+// given array of pens:
+void draw(picture pic=currentpicture, path[] g, pen fillrule=currentpen,
+ pen[] p)
+{
+ path[] G;
+ pen[][] P;
+ string differentlengths="arrays have different lengths";
+ if(g.length != p.length) abort(differentlengths);
+ for(int i=0; i < g.length-1; ++i) {
+ path g0=g[i];
+ path g1=g[i+1];
+ if(length(g0) != length(g1)) abort(differentlengths);
+ for(int j=0; j < length(g0); ++j) {
+ G.push(subpath(g0,j,j+1)--reverse(subpath(g1,j,j+1))--cycle);
+ P.push(new pen[] {p[i],p[i],p[i+1],p[i+1]});
+ }
+ }
+ tensorshade(pic,G,fillrule,P);
+}
+
+void functionshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, string shader, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ functionshade(f,t*g,stroke,fillrule,shader);
+ },true);
+ pic.addPath(g);
+}
+
+void filldraw(picture pic=currentpicture, path[] g, pen fillpen=currentpen,
+ pen drawpen=currentpen)
+{
+ begingroup(pic);
+ fill(pic,g,fillpen);
+ Draw(pic,g,drawpen);
+ endgroup(pic);
+}
+
+void clip(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.clip(min(g), max(g),
+ new void(frame f, transform t) {
+ clip(f,t*g,stroke,fillrule,false);
+ },
+ true);
+}
+
+void beginclip(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+
+ pic.clipmin.push(min(g));
+ pic.clipmax.push(max(g));
+
+ pic.add(new void(frame f, transform t) {
+ beginclip(f,t*g,stroke,fillrule,false);
+ },true);
+}
+
+void endclip(picture pic=currentpicture)
+{
+ pair min,max;
+ if (pic.clipmin.length > 0 && pic.clipmax.length > 0)
+ {
+ min = pic.clipmin.pop();
+ max = pic.clipmax.pop();
+ }
+ else
+ {
+ // We should probably abort here, since the PostScript output will be
+ // garbage.
+ warning("endclip", "endclip without beginclip");
+ min = pic.userMin2();
+ max = pic.userMax2();
+ }
+
+ pic.clip(min, max,
+ new void(frame f, transform) {
+ endclip(f);
+ },
+ true);
+}
+
+void unfill(picture pic=currentpicture, path[] g, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ unfill(f,t*g,false);
+ },true);
+}
+
+void filloutside(picture pic=currentpicture, path[] g, pen p=currentpen,
+ bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ filloutside(f,t*g,p,false);
+ },true);
+ pic.addPath(g);
+}
+
+// Use a fixed scaling to map user coordinates in box(min,max) to the
+// desired picture size.
+transform fixedscaling(picture pic=currentpicture, pair min, pair max,
+ pen p=nullpen, bool warn=false)
+{
+ Draw(pic,min,p+invisible);
+ Draw(pic,max,p+invisible);
+ pic.fixed=true;
+ return pic.fixedscaling=pic.calculateTransform(pic.xsize,pic.ysize,
+ pic.keepAspect);
+}
+
+// Add frame src to frame dest about position with optional grouping.
+void add(frame dest, frame src, pair position, bool group=false,
+ filltype filltype=NoFill, bool above=true)
+{
+ add(dest,shift(position)*src,group,filltype,above);
+}
+
+// Add frame src to picture dest about position with optional grouping.
+void add(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ if(is3D(src)) {
+ dest.add(new void(frame f, transform3, picture, projection) {
+ add(f,src); // always add about 3D origin (ignore position)
+ },true);
+ dest.addBox((0,0,0),(0,0,0),min3(src),max3(src));
+ } else {
+ dest.add(new void(frame f, transform t) {
+ add(f,shift(t*position)*src,group,filltype,above);
+ },true);
+ dest.addBox(position,position,min(src),max(src));
+ }
+}
+
+// Like add(picture,frame,pair) but extend picture to accommodate frame.
+void attach(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ transform t=dest.calculateTransform();
+ add(dest,src,position,group,filltype,above);
+ pair s=size(dest.fit(t));
+ size(dest,dest.xsize != 0 ? s.x : 0,dest.ysize != 0 ? s.y : 0);
+}
+
+// Like add(picture,frame,pair) but align frame in direction align.
+void add(picture dest=currentpicture, frame src, pair position, pair align,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ add(dest,align(src,align),position,group,filltype,above);
+}
+
+// Like add(frame,frame,pair) but align frame in direction align.
+void add(frame dest, frame src, pair position, pair align,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ add(dest,align(src,align),position,group,filltype,above);
+}
+
+// Like add(picture,frame,pair,pair) but extend picture to accommodate frame;
+void attach(picture dest=currentpicture, frame src, pair position,
+ pair align, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ attach(dest,align(src,align),position,group,filltype,above);
+}
+
+// Add a picture to another such that user coordinates in both will be scaled
+// identically in the shipout.
+void add(picture dest, picture src, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ dest.add(src,group,filltype,above);
+}
+
+void add(picture src, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ currentpicture.add(src,group,filltype,above);
+}
+
+// Fit the picture src using the identity transformation (so user
+// coordinates and truesize coordinates agree) and add it about the point
+// position to picture dest.
+void add(picture dest, picture src, pair position, bool group=true,
+ filltype filltype=NoFill, bool above=true)
+{
+ add(dest,src.fit(identity()),position,group,filltype,above);
+}
+
+void add(picture src, pair position, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ add(currentpicture,src,position,group,filltype,above);
+}
+
+// Fill a region about the user-coordinate 'origin'.
+void fill(pair origin, picture pic=currentpicture, path[] g, pen p=currentpen)
+{
+ picture opic;
+ fill(opic,g,p);
+ add(pic,opic,origin);
+}
+
+void postscript(picture pic=currentpicture, string s)
+{
+ pic.add(new void(frame f, transform) {
+ postscript(f,s);
+ },true);
+}
+
+void postscript(picture pic=currentpicture, string s, pair min, pair max)
+{
+ pic.add(new void(frame f, transform t) {
+ postscript(f,s,t*min,t*max);
+ },true);
+}
+
+void tex(picture pic=currentpicture, string s)
+{
+ // Force TeX string s to be evaluated immediately (in case it is a macro).
+ frame g;
+ tex(g,s);
+ size(g);
+ pic.add(new void(frame f, transform) {
+ tex(f,s);
+ },true);
+}
+
+void tex(picture pic=currentpicture, string s, pair min, pair max)
+{
+ frame g;
+ tex(g,s);
+ size(g);
+ pic.add(new void(frame f, transform t) {
+ tex(f,s,t*min,t*max);
+ },true);
+}
+
+void layer(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ layer(f);
+ },true);
+}
+
+void erase(picture pic=currentpicture)
+{
+ pic.uptodate=false;
+ pic.erase();
+}
+
+void begin(picture pic=currentpicture, string name, string id="",
+ bool visible=true)
+{
+ if(!latex() || !pdf()) return;
+ settings.twice=true;
+ if(id == "") id=string(++ocgindex);
+ tex(pic,"\begin{ocg}{"+name+"}{"+id+"}{"+(visible ? "1" : "0")+"}");
+ layer(pic);
+}
+
+void end(picture pic=currentpicture)
+{
+ if(!latex() || !pdf()) return;
+ tex(pic,"\end{ocg}");
+ layer(pic);
+}
+
+// For users of the LaTeX babel package.
+void deactivatequote(picture pic=currentpicture)
+{
+ tex(pic,"\catcode`\"=12");
+}
+
+void activatequote(picture pic=currentpicture)
+{
+ tex(pic,"\catcode`\"=13");
+}
diff --git a/graphics/asymptote/base/plain_prethree.asy b/graphics/asymptote/base/plain_prethree.asy
new file mode 100644
index 0000000000..bc40792cf0
--- /dev/null
+++ b/graphics/asymptote/base/plain_prethree.asy
@@ -0,0 +1,216 @@
+// Critical definitions for transform3 needed by projection and picture.
+
+pair viewportmargin=(0.1,0.1); // Horizontal and vertical 3D viewport margins.
+
+typedef real[][] transform3;
+restricted transform3 identity4=identity(4);
+
+// A uniform 3D scaling.
+transform3 scale3(real s)
+{
+ transform3 t=identity(4);
+ t[0][0]=t[1][1]=t[2][2]=s;
+ return t;
+}
+
+// Simultaneous 3D scalings in the x, y, and z directions.
+transform3 scale(real x, real y, real z)
+{
+ transform3 t=identity(4);
+ t[0][0]=x;
+ t[1][1]=y;
+ t[2][2]=z;
+ return t;
+}
+
+transform3 shiftless(transform3 t)
+{
+ transform3 T=copy(t);
+ T[0][3]=T[1][3]=T[2][3]=0;
+ return T;
+}
+
+real camerafactor=2; // Factor used for camera adjustment.
+
+struct transformation {
+ transform3 modelview; // For orientation and positioning
+ transform3 projection; // For 3D to 2D projection
+ bool infinity;
+ void operator init(transform3 modelview) {
+ this.modelview=modelview;
+ this.projection=identity4;
+ infinity=true;
+ }
+ void operator init(transform3 modelview, transform3 projection) {
+ this.modelview=modelview;
+ this.projection=projection;
+ infinity=false;
+ }
+ transform3 compute() {
+ return infinity ? modelview : projection*modelview;
+ }
+ transformation copy() {
+ transformation T=new transformation;
+ T.modelview=copy(modelview);
+ T.projection=copy(projection);
+ T.infinity=infinity;
+ return T;
+ }
+}
+
+struct projection {
+ transform3 t; // projection*modelview (cached)
+ bool infinity;
+ bool absolute=false;
+ triple camera; // Position of camera.
+ triple up; // A vector that should be projected to direction (0,1).
+ triple target; // Point where camera is looking at.
+ triple normal; // Normal vector from target to projection plane.
+ pair viewportshift; // Fractional viewport shift.
+ real zoom=1; // Zoom factor.
+ real angle; // Lens angle (for perspective projection).
+ bool showtarget=true; // Expand bounding volume to include target?
+ typedef transformation projector(triple camera, triple up, triple target);
+ projector projector;
+ bool autoadjust=true; // Adjust camera to lie outside bounding volume?
+ bool center=false; // Center target within bounding volume?
+ int ninterpolate; // Used for projecting nurbs to 2D Bezier curves.
+ bool bboxonly=true; // Typeset label bounding box only.
+
+ transformation T;
+
+ void calculate() {
+ T=projector(camera,up,target);
+ t=T.compute();
+ infinity=T.infinity;
+ ninterpolate=infinity ? 1 : 16;
+ }
+
+ triple vector() {
+ return camera-target;
+ }
+
+ void operator init(triple camera, triple up=(0,0,1), triple target=(0,0,0),
+ triple normal=camera-target,
+ real zoom=1, real angle=0, pair viewportshift=0,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=false, projector projector) {
+ this.camera=camera;
+ this.up=up;
+ this.target=target;
+ this.normal=normal;
+ this.zoom=zoom;
+ this.angle=angle;
+ this.viewportshift=viewportshift;
+ this.showtarget=showtarget;
+ this.autoadjust=autoadjust;
+ this.center=center;
+ this.projector=projector;
+ calculate();
+ }
+
+ projection copy() {
+ projection P=new projection;
+ P.t=t;
+ P.infinity=infinity;
+ P.absolute=absolute;
+ P.camera=camera;
+ P.up=up;
+ P.target=target;
+ P.normal=normal;
+ P.zoom=zoom;
+ P.angle=angle;
+ P.viewportshift=viewportshift;
+ P.showtarget=showtarget;
+ P.autoadjust=autoadjust;
+ P.center=center;
+ P.projector=projector;
+ P.ninterpolate=ninterpolate;
+ P.bboxonly=bboxonly;
+ P.T=T.copy();
+ return P;
+ }
+
+ // Return the maximum distance of box(m,M) from target.
+ real distance(triple m, triple M) {
+ triple[] c={m,(m.x,m.y,M.z),(m.x,M.y,m.z),(m.x,M.y,M.z),
+ (M.x,m.y,m.z),(M.x,m.y,M.z),(M.x,M.y,m.z),M};
+ return max(abs(c-target));
+ }
+
+
+ // This is redefined here to make projection as self-contained as possible.
+ static private real sqrtEpsilon = sqrt(realEpsilon);
+
+ // Move the camera so that the box(m,M) rotated about target will always
+ // lie in front of the clipping plane.
+ bool adjust(triple m, triple M) {
+ triple v=camera-target;
+ real d=distance(m,M);
+ static real lambda=camerafactor*(1-sqrtEpsilon);
+ if(lambda*d >= abs(v)) {
+ camera=target+camerafactor*d*unit(v);
+ calculate();
+ return true;
+ }
+ return false;
+ }
+}
+
+projection currentprojection;
+
+struct light {
+ real[][] diffuse;
+ real[][] specular;
+ pen background=nullpen; // Background color of the 3D canvas.
+ real specularfactor;
+ triple[] position; // Only directional lights are currently implemented.
+
+ transform3 T=identity(4); // Transform to apply to normal vectors.
+
+ bool on() {return position.length > 0;}
+
+ void operator init(pen[] diffuse,
+ pen[] specular=diffuse, pen background=nullpen,
+ real specularfactor=1,
+ triple[] position) {
+ int n=diffuse.length;
+ assert(specular.length == n && position.length == n);
+
+ this.diffuse=new real[n][];
+ this.specular=new real[n][];
+ this.background=background;
+ this.position=new triple[n];
+ for(int i=0; i < position.length; ++i) {
+ this.diffuse[i]=rgba(diffuse[i]);
+ this.specular[i]=rgba(specular[i]);
+ this.position[i]=unit(position[i]);
+ }
+ this.specularfactor=specularfactor;
+ }
+
+ void operator init(pen diffuse=white, pen specular=diffuse,
+ pen background=nullpen, real specularfactor=1 ...triple[] position) {
+ int n=position.length;
+ operator init(array(n,diffuse),array(n,specular),
+ background,specularfactor,position);
+ }
+
+ void operator init(pen diffuse=white, pen specular=diffuse,
+ pen background=nullpen, real x, real y, real z) {
+ operator init(diffuse,specular,background,(x,y,z));
+ }
+
+ void operator init(explicit light light) {
+ diffuse=copy(light.diffuse);
+ specular=copy(light.specular);
+ background=light.background;
+ specularfactor=light.specularfactor;
+ position=copy(light.position);
+ }
+
+ real[] background() {return rgba(background == nullpen ? white : background);}
+}
+
+light currentlight;
+
diff --git a/graphics/asymptote/base/plain_scaling.asy b/graphics/asymptote/base/plain_scaling.asy
new file mode 100644
index 0000000000..5bed3338e9
--- /dev/null
+++ b/graphics/asymptote/base/plain_scaling.asy
@@ -0,0 +1,258 @@
+real expansionfactor=sqrt(2);
+
+// A coordinate in "flex space." A linear combination of user and true-size
+// coordinates.
+struct coord {
+ real user,truesize;
+
+ // Build a coord.
+ static coord build(real user, real truesize) {
+ coord c=new coord;
+ c.user=user;
+ c.truesize=truesize;
+ return c;
+ }
+
+ // Deep copy of coordinate. Users may add coords to the picture, but then
+ // modify the struct. To prevent this from yielding unexpected results, deep
+ // copying is used.
+ coord copy() {
+ return build(user, truesize);
+ }
+
+ void clip(real min, real max) {
+ user=min(max(user,min),max);
+ truesize=0;
+ }
+}
+
+bool operator <= (coord a, coord b)
+{
+ return a.user <= b.user && a.truesize <= b.truesize;
+}
+
+bool operator >= (coord a, coord b)
+{
+ return a.user >= b.user && a.truesize >= b.truesize;
+}
+
+// Find the maximal elements of the input array, using the partial ordering
+// given.
+coord[] maxcoords(coord[] in, bool operator <= (coord,coord))
+{
+ // As operator <= is defined in the parameter list, it has a special
+ // meaning in the body of the function.
+
+ coord best;
+ coord[] c;
+
+ int n=in.length;
+
+ if(n == 0)
+ return c;
+
+ int first=0;
+ // Add the first coord without checking restrictions (as there are none).
+ best=in[first];
+ c.push(best);
+
+ static int NONE=-1;
+
+ int dominator(coord x)
+ {
+ // This assumes it has already been checked against the best.
+ for(int i=1; i < c.length; ++i)
+ if(x <= c[i])
+ return i;
+ return NONE;
+ }
+
+ void promote(int i)
+ {
+ // Swap with the top
+ coord x=c[i];
+ c[i]=best;
+ best=c[0]=x;
+ }
+
+ void addmaximal(coord x)
+ {
+ coord[] newc;
+
+ // Check if it beats any others.
+ for(int i=0; i < c.length; ++i) {
+ coord y=c[i];
+ if(!(y <= x))
+ newc.push(y);
+ }
+ newc.push(x);
+ c=newc;
+ best=c[0];
+ }
+
+ void add(coord x)
+ {
+ if(x <= best)
+ return;
+ else {
+ int i=dominator(x);
+ if(i == NONE)
+ addmaximal(x);
+ else
+ promote(i);
+ }
+ }
+
+ for(int i=1; i < n; ++i)
+ add(in[i]);
+
+ return c;
+}
+
+struct coords2 {
+ coord[] x,y;
+ void erase() {
+ x.delete();
+ y.delete();
+ }
+ // Only a shallow copy of the individual elements of x and y
+ // is needed since, once entered, they are never modified.
+ coords2 copy() {
+ coords2 c=new coords2;
+ c.x=copy(x);
+ c.y=copy(y);
+ return c;
+ }
+ void append(coords2 c) {
+ x.append(c.x);
+ y.append(c.y);
+ }
+ void push(pair user, pair truesize) {
+ x.push(coord.build(user.x,truesize.x));
+ y.push(coord.build(user.y,truesize.y));
+ }
+ void push(coord cx, coord cy) {
+ x.push(cx);
+ y.push(cy);
+ }
+ void push(transform t, coords2 c1, coords2 c2) {
+ for(int i=0; i < c1.x.length; ++i) {
+ coord cx=c1.x[i], cy=c2.y[i];
+ pair tinf=shiftless(t)*(0,0);
+ pair z=t*(cx.user,cy.user);
+ pair w=(cx.truesize,cy.truesize);
+ w=length(w)*unit(shiftless(t)*w);
+ coord Cx,Cy;
+ Cx.user=z.x;
+ Cy.user=z.y;
+ Cx.truesize=w.x;
+ Cy.truesize=w.y;
+ push(Cx,Cy);
+ }
+ }
+ void xclip(real min, real max) {
+ for(int i=0; i < x.length; ++i)
+ x[i].clip(min,max);
+ }
+ void yclip(real min, real max) {
+ for(int i=0; i < y.length; ++i)
+ y[i].clip(min,max);
+ }
+}
+
+// The scaling in one dimension: x --> a*x + b
+struct scaling {
+ real a,b;
+ static scaling build(real a, real b) {
+ scaling s=new scaling;
+ s.a=a; s.b=b;
+ return s;
+ }
+ real scale(real x) {
+ return a*x+b;
+ }
+ real scale(coord c) {
+ return scale(c.user) + c.truesize;
+ }
+}
+
+// Calculate the minimum point in scaling the coords.
+real min(real m, scaling s, coord[] c) {
+ for(int i=0; i < c.length; ++i)
+ if(s.scale(c[i]) < m)
+ m=s.scale(c[i]);
+ return m;
+}
+
+// Calculate the maximum point in scaling the coords.
+real max(real M, scaling s, coord[] c) {
+ for(int i=0; i < c.length; ++i)
+ if(s.scale(c[i]) > M)
+ M=s.scale(c[i]);
+ return M;
+}
+
+import simplex;
+
+/*
+ Calculate the sizing constants for the given array and maximum size.
+ Solve the two-variable linear programming problem using the simplex method.
+ This problem is specialized in that the second variable, "b", does not have
+ a non-negativity condition, and the first variable, "a", is the quantity
+ being maximized.
+*/
+real calculateScaling(string dir, coord[] m, coord[] M, real size,
+ bool warn=true) {
+ real[][] A;
+ real[] b;
+ real[] c=new real[] {-1,0,0};
+
+ void addMinCoord(coord c) {
+ // (a*user + b) + truesize >= 0:
+ A.push(new real[] {c.user,1,-1});
+ b.push(-c.truesize);
+ }
+ void addMaxCoord(coord c) {
+ // (a*user + b) + truesize <= size:
+ A.push(new real[] {-c.user,-1,1});
+ b.push(c.truesize-size);
+ }
+
+ for (int i=0; i < m.length; ++i)
+ addMinCoord(m[i]);
+ for (int i=0; i < M.length; ++i)
+ addMaxCoord(M[i]);
+
+ int[] s=array(A.length,1);
+ simplex S=simplex(c,A,s,b);
+
+ if(S.case == S.OPTIMAL) {
+ return S.x[0];
+ } else if(S.case == S.UNBOUNDED) {
+ if(warn) warning("unbounded",dir+" scaling in picture unbounded");
+ return 0;
+ } else {
+ if(!warn) return 1;
+
+ bool userzero(coord[] coords) {
+ for(var coord : coords)
+ if(coord.user != 0) return false;
+ return true;
+ }
+
+ if((userzero(m) && userzero(M)) || size >= infinity) return 1;
+
+ warning("cannotfit","cannot fit picture to "+dir+"size "+(string) size
+ +"...enlarging...");
+
+ return calculateScaling(dir,m,M,expansionfactor*size,warn);
+ }
+}
+
+real calculateScaling(string dir, coord[] coords, real size, bool warn=true)
+{
+ coord[] m=maxcoords(coords,operator >=);
+ coord[] M=maxcoords(coords,operator <=);
+
+ return calculateScaling(dir, m, M, size, warn);
+}
diff --git a/graphics/asymptote/base/plain_shipout.asy b/graphics/asymptote/base/plain_shipout.asy
new file mode 100644
index 0000000000..4562205966
--- /dev/null
+++ b/graphics/asymptote/base/plain_shipout.asy
@@ -0,0 +1,145 @@
+// Default file prefix used for inline LaTeX mode
+string defaultfilename;
+
+file _outpipe;
+if(settings.xasy)
+ _outpipe=output(mode="pipe");
+
+string[] file3;
+
+string outprefix(string prefix=defaultfilename) {
+ return stripextension(prefix != "" ? prefix : outname());
+}
+
+string outformat(string format="")
+{
+ if(format == "") format=settings.outformat;
+ if(format == "") format=nativeformat();
+ return format;
+}
+
+frame currentpatterns;
+
+frame Portrait(frame f) {return f;};
+frame Landscape(frame f) {return rotate(90)*f;};
+frame UpsideDown(frame f) {return rotate(180)*f;};
+frame Seascape(frame f) {return rotate(-90)*f;};
+typedef frame orientation(frame);
+orientation orientation=Portrait;
+
+// Forward references to functions defined in module three.
+object embed3(string, frame, string, string, string, light, projection);
+string Embed(string name, string text="", string options="", real width=0,
+ real height=0);
+
+bool prconly(string format="")
+{
+ return outformat(format) == "prc";
+}
+
+bool prc0(string format="")
+{
+ return settings.prc && (outformat(format) == "pdf" || prconly() || settings.inlineimage );
+}
+
+bool prc(string format="") {
+ return prc0(format) && Embed != null;
+}
+
+bool is3D(string format="")
+{
+ return prc(format) || settings.render != 0;
+}
+
+frame enclose(string prefix=defaultfilename, object F, string format="")
+{
+ if(prc(format)) {
+ frame f;
+ label(f,F.L);
+ return f;
+ } return F.f;
+}
+
+void deconstruct(picture pic=currentpicture)
+{
+ frame f;
+ transform t=pic.calculateTransform();
+ if(currentpicture.fitter == null)
+ f=pic.fit(t);
+ else
+ f=pic.fit();
+ deconstruct(f,currentpatterns,t);
+}
+
+bool implicitshipout=false;
+
+void shipout(string prefix=defaultfilename, frame f,
+ string format="", bool wait=false, bool view=true,
+ string options="", string script="",
+ light light=currentlight, projection P=currentprojection,
+ transform t=identity)
+{
+ if(is3D(f)) {
+ f=enclose(prefix,embed3(prefix,f,format,options,script,light,P));
+ if(settings.render != 0 && !prc(format)) {
+ return;
+ }
+ }
+
+ if(settings.xasy || (!implicitshipout && prefix == defaultfilename)) {
+ if(prefix == defaultfilename) {
+ currentpicture.clear();
+ add(f,group=false);
+ }
+ return;
+ }
+
+ // Applications like LaTeX cannot handle large PostScript coordinates.
+ pair m=min(f);
+ int limit=2000;
+ if(abs(m.x) > limit || abs(m.y) > limit) f=shift(-m)*f;
+
+ _shipout(prefix,f,currentpatterns,format,wait,view,t);
+}
+
+void shipout(string prefix=defaultfilename, picture pic=currentpicture,
+ orientation orientation=orientation,
+ string format="", bool wait=false, bool view=true,
+ string options="", string script="",
+ light light=currentlight, projection P=currentprojection)
+{
+ pic.uptodate=true;
+ if(!uptodate()) {
+ bool inlinetex=settings.inlinetex;
+ bool prc=prc(format);
+ bool empty3=pic.empty3();
+ if(prc && !empty3) {
+ if(settings.render == 0) {
+ string image=outprefix(prefix)+"+"+(string) file3.length;
+ if(settings.inlineimage) image += "_0";
+ settings.inlinetex=false;
+ settings.prc=false;
+ shipout(image,pic,orientation,nativeformat(),view=false,light,P);
+ settings.prc=true;
+ }
+ settings.inlinetex=settings.inlineimage;
+ }
+ frame f;
+ transform t=pic.calculateTransform();
+ if(currentpicture.fitter == null)
+ f=pic.fit(t);
+ else
+ f=pic.fit(prefix,format,view=view,options,script,light,P);
+
+ if(!prconly() && (!pic.empty2() || settings.render == 0 || prc || empty3))
+ shipout(prefix,orientation(f),format,wait,view,t);
+ settings.inlinetex=inlinetex;
+ }
+}
+
+void newpage(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ newpage(f);
+ },true);
+}
diff --git a/graphics/asymptote/base/plain_strings.asy b/graphics/asymptote/base/plain_strings.asy
new file mode 100644
index 0000000000..c109fc491f
--- /dev/null
+++ b/graphics/asymptote/base/plain_strings.asy
@@ -0,0 +1,264 @@
+string defaultformat(int n, string trailingzero="", bool fixed=false,
+ bool signed=true)
+{
+ return "$%"+trailingzero+"."+string(n)+(fixed ? "f" : "g")+"$";
+}
+
+string defaultformat=defaultformat(4);
+string defaultseparator="\!\times\!";
+
+string ask(string prompt)
+{
+ write(stdout,prompt);
+ return stdin;
+}
+
+string getstring(string name="", string default="", string prompt="",
+ bool store=true)
+{
+ string[] history=history(name,1);
+ if(history.length > 0) default=history[0];
+ if(prompt == "") prompt=name+"? [%s] ";
+ prompt=replace(prompt,new string[][] {{"%s",default}});
+ string s=readline(prompt,name);
+ if(s == "") s=default;
+ else saveline(name,s,store);
+ return s;
+}
+
+int getint(string name="", int default=0, string prompt="", bool store=true)
+{
+ return (int) getstring(name,(string) default,prompt,store);
+}
+
+real getreal(string name="", real default=0, string prompt="", bool store=true)
+{
+ return (real) getstring(name,(string) default,prompt,store);
+}
+
+pair getpair(string name="", pair default=0, string prompt="", bool store=true)
+{
+ return (pair) getstring(name,(string) default,prompt,store);
+}
+
+triple gettriple(string name="", triple default=(0,0,0), string prompt="",
+ bool store=true)
+{
+ return (triple) getstring(name,(string) default,prompt,store);
+}
+
+// returns a string with all occurrences of string 'before' in string 's'
+// changed to string 'after'.
+string replace(string s, string before, string after)
+{
+ return replace(s,new string[][] {{before,after}});
+}
+
+// Like texify but don't convert embedded TeX commands: \${}
+string TeXify(string s)
+{
+ static string[][] t={{"&","\&"},{"%","\%"},{"_","\_"},{"#","\#"},{"<","$<$"},
+ {">","$>$"},{"|","$|$"},{"^","$\hat{\ }$"},
+ {"~","$\tilde{\ }$"},{" ","\phantom{ }"}};
+ return replace(s,t);
+}
+
+private string[][] trans1={{'\\',"\backslash "},
+ {"$","\$"},{"{","\{"},{"}","\}"}};
+private string[][] trans2={{"\backslash ","$\backslash$"}};
+
+// Convert string to TeX
+string texify(string s)
+{
+ return TeXify(replace(replace(s,trans1),trans2));
+}
+
+// Convert string to TeX, preserving newlines
+string verbatim(string s)
+{
+ bool space=substr(s,0,1) == '\n';
+ static string[][] t={{'\n',"\\"}};
+ t.append(trans1);
+ s=TeXify(replace(replace(s,t),trans2));
+ return space ? "\ "+s : s;
+}
+
+// Split a string into an array of substrings delimited by delimiter
+// If delimiter is an empty string, use space delimiter but discard empty
+// substrings. TODO: Move to C++ code.
+string[] split(string s, string delimiter="")
+{
+ bool prune=false;
+ if(delimiter == "") {
+ prune=true;
+ delimiter=" ";
+ }
+
+ string[] S;
+ int last=0;
+ int i;
+ int N=length(delimiter);
+ int n=length(s);
+ while((i=find(s,delimiter,last)) >= 0) {
+ if(i > last || (i == last && !prune))
+ S.push(substr(s,last,i-last));
+ last=i+N;
+ }
+ if(n > last || (n == last && !prune))
+ S.push(substr(s,last,n-last));
+ return S;
+}
+
+// Returns an array of strings obtained by splitting s into individual
+// characters. TODO: Move to C++ code.
+string[] array(string s)
+{
+ int len=length(s);
+ string[] S=new string[len];
+ for(int i=0; i < len; ++i)
+ S[i]=substr(s,i,1);
+ return S;
+}
+
+// Concatenate an array of strings into a single string.
+// TODO: Move to C++ code.
+string operator +(...string[] a)
+{
+ string S;
+ for(string s : a)
+ S += s;
+ return S;
+}
+
+int system(string s)
+{
+ return system(split(s));
+}
+
+int[] operator ecast(string[] a)
+{
+ return sequence(new int(int i) {return (int) a[i];},a.length);
+}
+
+real[] operator ecast(string[] a)
+{
+ return sequence(new real(int i) {return (real) a[i];},a.length);
+}
+
+// Read contents of file as a string.
+string file(string s)
+{
+ file f=input(s);
+ string s;
+ while(!eof(f)) {
+ s += f+'\n';
+ }
+ return s;
+}
+
+string italic(string s)
+{
+ return s != "" ? "{\it "+s+"}" : s;
+}
+
+string baseline(string s, string template="\strut")
+{
+ return s != "" && settings.tex != "none" ? "\vphantom{"+template+"}"+s : s;
+}
+
+string math(string s)
+{
+ return s != "" ? "$"+s+"$" : s;
+}
+
+private void notimplemented(string text)
+{
+ abort(text+" is not implemented for the '"+settings.tex+"' TeX engine");
+}
+
+string jobname(string name)
+{
+ int pos=rfind(name,"-");
+ return pos >= 0 ? "\ASYprefix\jobname"+substr(name,pos) : name;
+}
+
+string graphic(string name, string options="")
+{
+ if(latex()) {
+ if(options != "") options="["+options+"]";
+ bool pdf=pdf();
+ string includegraphics="\includegraphics"+options;
+ if(settings.inlinetex)
+ return includegraphics+"{"+jobname(name)+"}";
+ else
+ return includegraphics+
+ (find(name," ") < 0 ? "{"+name+"}" :
+ (pdf ? "{\""+stripextension(name)+"\".pdf}" : "{\""+name+"\"}"));
+ }
+ if(settings.tex != "context")
+ notimplemented("graphic");
+ return "\externalfigure["+name+"]["+options+"]";
+}
+
+string graphicscale(real x)
+{
+ return string(settings.tex == "context" ? 1000*x : x);
+}
+
+string minipage(string s, real width=100bp)
+{
+ if(latex())
+ return "\begin{minipage}{"+(string) (width/pt)+"pt}"+s+"\end{minipage}";
+ if(settings.tex != "context")
+ notimplemented("minipage");
+ return "\startframedtext[none][frame=off,width="+(string) (width/pt)+
+ "pt]"+s+"\stopframedtext";
+}
+
+void usepackage(string s, string options="")
+{
+ if(!latex()) notimplemented("usepackage");
+ string usepackage="\usepackage";
+ if(options != "") usepackage += "["+options+"]";
+ texpreamble(usepackage+"{"+s+"}");
+}
+
+void pause(string w="Hit enter to continue")
+{
+ write(w);
+ w=stdin;
+}
+
+string format(string format=defaultformat, bool forcemath=false, real x,
+ string locale="")
+{
+ return format(format,forcemath,defaultseparator,x,locale);
+}
+
+string phantom(string s)
+{
+ return settings.tex != "none" ? "\phantom{"+s+"}" : "";
+}
+
+string[] spinner=new string[] {'|','/','-','\\'};
+spinner.cyclic=true;
+
+void progress(bool3 init=default)
+{
+ static int count=-1;
+ static int lastseconds=-1;
+ if(init == true) {
+ lastseconds=0;
+ write(stdout,' ',flush);
+ } else
+ if(init == default) {
+ int seconds=seconds();
+ if(seconds > lastseconds) {
+ lastseconds=seconds;
+ write(stdout,'\b'+spinner[++count],flush);
+ }
+ } else
+ write(stdout,'\b',flush);
+}
+
+restricted int ocgindex=0;
diff --git a/graphics/asymptote/base/pstoedit.asy b/graphics/asymptote/base/pstoedit.asy
new file mode 100644
index 0000000000..7baccd3ed6
--- /dev/null
+++ b/graphics/asymptote/base/pstoedit.asy
@@ -0,0 +1,18 @@
+pen textpen=basealign;
+pair align=Align;
+
+// Compatibility routines for the pstoedit (version 3.43 or later) backend.
+void gsave(picture pic=currentpicture)
+{
+ pic.add(new void (frame f, transform) {
+ gsave(f);
+ },true);
+}
+
+void grestore(picture pic=currentpicture)
+{
+ pic.add(new void (frame f, transform) {
+ grestore(f);
+ },true);
+}
+
diff --git a/graphics/asymptote/base/rational.asy b/graphics/asymptote/base/rational.asy
new file mode 100644
index 0000000000..d24da0d664
--- /dev/null
+++ b/graphics/asymptote/base/rational.asy
@@ -0,0 +1,269 @@
+// Asymptote module implementing rational arithmetic.
+
+int gcd(int m, int n)
+{
+ if(m < n) {
+ int temp=m;
+ m=n;
+ n=temp;
+ }
+ while(n != 0) {
+ int r=m % n;
+ m=n;
+ n=r;
+ }
+ return m;
+}
+
+int lcm(int m, int n)
+{
+ return m#gcd(m,n)*n;
+}
+
+struct rational {
+ int p=0,q=1;
+ void reduce() {
+ int d=gcd(p,q);
+ if(abs(d) > 1) {
+ p #= d;
+ q #= d;
+ }
+ if(q <= 0) {
+ if(q == 0) abort("Division by zero");
+ p=-p;
+ q=-q;
+ }
+ }
+ void operator init(int p=0, int q=1, bool reduce=true) {
+ this.p=p;
+ this.q=q;
+ if(reduce) reduce();
+ }
+}
+
+rational operator cast(int p) {
+ return rational(p,false);
+}
+
+rational[] operator cast(int[] a) {
+ return sequence(new rational(int i) {return a[i];},a.length);
+}
+
+rational[][] operator cast(int[][] a) {
+ return sequence(new rational[](int i) {return a[i];},a.length);
+}
+
+real operator ecast(rational r) {
+ return r.p/r.q;
+}
+
+rational operator -(rational r)
+{
+ return rational(-r.p,r.q,false);
+}
+
+rational operator +(rational r, rational s)
+{
+ return rational(r.p*s.q+s.p*r.q,r.q*s.q);
+}
+
+rational operator -(rational r, rational s)
+{
+ return rational(r.p*s.q-s.p*r.q,r.q*s.q);
+}
+
+rational operator *(rational r, rational s)
+{
+ return rational(r.p*s.p,r.q*s.q);
+}
+
+rational operator /(rational r, rational s)
+{
+ return rational(r.p*s.q,r.q*s.p);
+}
+
+bool operator ==(rational r, rational s)
+{
+ return r.p == s.p && r.q == s.q;
+}
+
+bool operator !=(rational r, rational s)
+{
+ return r.p != s.p || r.q != s.q;
+}
+
+bool operator <(rational r, rational s)
+{
+ return r.p*s.q-s.p*r.q < 0;
+}
+
+bool operator >(rational r, rational s)
+{
+ return r.p*s.q-s.p*r.q > 0;
+}
+
+bool operator <=(rational r, rational s)
+{
+ return r.p*s.q-s.p*r.q <= 0;
+}
+
+bool operator >=(rational r, rational s)
+{
+ return r.p*s.q-s.p*r.q >= 0;
+}
+
+bool[] operator ==(rational[] r, rational s)
+{
+ return sequence(new bool(int i) {return r[i] == s;},r.length);
+}
+
+bool operator ==(rational[] r, rational[] s)
+{
+ if(r.length != s.length)
+ abort(" operation attempted on arrays of different lengths: "+
+ string(r.length)+" != "+string(s.length));
+ return all(sequence(new bool(int i) {return r[i] == s[i];},r.length));
+}
+
+bool operator ==(rational[][] r, rational[][] s)
+{
+ if(r.length != s.length)
+ abort(" operation attempted on arrays of different lengths: "+
+ string(r.length)+" != "+string(s.length));
+ return all(sequence(new bool(int i) {return r[i] == s[i];},r.length));
+}
+
+bool[] operator <(rational[] r, rational s)
+{
+ return sequence(new bool(int i) {return r[i] < s;},r.length);
+}
+
+bool[] operator >(rational[] r, rational s)
+{
+ return sequence(new bool(int i) {return r[i] > s;},r.length);
+}
+
+bool[] operator <=(rational[] r, rational s)
+{
+ return sequence(new bool(int i) {return r[i] <= s;},r.length);
+}
+
+bool[] operator >=(rational[] r, rational s)
+{
+ return sequence(new bool(int i) {return r[i] >= s;},r.length);
+}
+
+rational min(rational a, rational b)
+{
+ return a <= b ? a : b;
+}
+
+rational max(rational a, rational b)
+{
+ return a >= b ? a : b;
+}
+
+string string(rational r)
+{
+ return r.q == 1 ? string(r.p) : string(r.p)+"/"+string(r.q);
+}
+
+string texstring(rational r)
+{
+ if(r.q == 1) return string(r.p);
+ string s;
+ if(r.p < 0) s="-";
+ return s+"\frac{"+string(abs(r.p))+"}{"+string(r.q)+"}";
+}
+
+void write(file fout=stdout, string s="", rational r, suffix suffix=none)
+{
+ write(fout,s+string(r),suffix);
+}
+
+void write(file fout=stdout, string s="", rational[] a, suffix suffix=none)
+{
+ if(s != "")
+ write(fout,s);
+ for(int i=0; i < a.length; ++i) {
+ write(fout,i,none);
+ write(fout,':\t',a[i],endl);
+ }
+ write(fout,suffix);
+}
+
+void write(file fout=stdout, string s="", rational[][] a, suffix suffix=none)
+{
+ if(s != "")
+ write(fout,s);
+ for(int i=0; i < a.length; ++i) {
+ rational[] ai=a[i];
+ for(int j=0; j < ai.length; ++j) {
+ write(fout,ai[j],tab);
+ }
+ write(fout,endl);
+ }
+ write(fout,suffix);
+}
+
+bool rectangular(rational[][] m)
+{
+ int n=m.length;
+ if(n > 0) {
+ int m0=m[0].length;
+ for(int i=1; i < n; ++i)
+ if(m[i].length != m0) return false;
+ }
+ return true;
+}
+
+rational sum(rational[] a)
+{
+ rational sum;
+ for(rational r:a)
+ sum += r;
+ return sum;
+}
+
+rational max(rational[] a)
+{
+ rational M=a[0];
+ for(rational r:a)
+ M=max(M,r);
+ return M;
+}
+
+rational abs(rational r)
+{
+ return rational(abs(r.p),r.q,false);
+}
+
+rational[] operator -(rational[] r)
+{
+ return sequence(new rational(int i) {return -r[i];},r.length);
+}
+
+rational[][] rationalidentity(int n)
+{
+ return sequence(new rational[](int i) {return sequence(new rational(int j) {return j == i ? 1 : 0;},n);},n);
+}
+
+/*
+rational r=rational(1,3)+rational(1,4);
+write(r == rational(1,12));
+write(r);
+real x=r;
+write(x);
+
+rational r=3;
+write(r);
+
+write(gcd(-8,12));
+write(rational(-36,-14));
+
+int[][] a=new int[][] {{1,2},{3,4}};
+rational[][] r=a;
+write(r);
+
+*/
+
diff --git a/graphics/asymptote/base/rationalSimplex.asy b/graphics/asymptote/base/rationalSimplex.asy
new file mode 100644
index 0000000000..5175b87ba7
--- /dev/null
+++ b/graphics/asymptote/base/rationalSimplex.asy
@@ -0,0 +1,362 @@
+// Rational simplex solver written by John C. Bowman and Pouria Ramazi, 2018.
+import rational;
+
+void simplexTableau(rational[][] E, int[] Bindices, int I=-1, int J=-1) {}
+void simplexPhase2() {}
+
+void simplexWrite(rational[][] E, int[] Bindicies, int, int)
+{
+ int m=E.length-1;
+ int n=E[0].length-1;
+
+ write(E[m][n],tab);
+ for(int j=0; j < n; ++j)
+ write(E[m][j],tab);
+ write();
+
+ for(int i=0; i < m; ++i) {
+ write(E[i][n],tab);
+ for(int j=0; j < n; ++j) {
+ write(E[i][j],tab);
+ }
+ write();
+ }
+ write();
+};
+
+struct simplex {
+ static int OPTIMAL=0;
+ static int UNBOUNDED=1;
+ static int INFEASIBLE=2;
+
+ int case;
+ rational[] x;
+ rational cost;
+
+ int m,n;
+ int J;
+
+ // Row reduce based on pivot E[I][J]
+ void rowreduce(rational[][] E, int N, int I, int J) {
+ rational[] EI=E[I];
+ rational v=EI[J];
+ for(int j=0; j < J; ++j) EI[j] /= v;
+ EI[J]=1;
+ for(int j=J+1; j <= N; ++j) EI[j] /= v;
+
+ for(int i=0; i < I; ++i) {
+ rational[] Ei=E[i];
+ rational EiJ=Ei[J];
+ for(int j=0; j < J; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ Ei[J]=0;
+ for(int j=J+1; j <= N; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ }
+ for(int i=I+1; i <= m; ++i) {
+ rational[] Ei=E[i];
+ rational EiJ=Ei[J];
+ for(int j=0; j < J; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ Ei[J]=0;
+ for(int j=J+1; j <= N; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ }
+ }
+
+ int iterate(rational[][] E, int N, int[] Bindices) {
+ while(true) {
+ // Find first negative entry in bottom (reduced cost) row
+ rational[] Em=E[m];
+ for(J=0; J < N; ++J)
+ if(Em[J] < 0) break;
+
+ if(J == N)
+ break;
+
+ int I=-1;
+ rational M;
+ for(int i=0; i < m; ++i) {
+ rational e=E[i][J];
+ if(e > 0) {
+ M=E[i][N]/e;
+ I=i;
+ break;
+ }
+ }
+ for(int i=I+1; i < m; ++i) {
+ rational e=E[i][J];
+ if(e > 0) {
+ rational v=E[i][N]/e;
+ if(v < M) {M=v; I=i;} // Bland's rule: choose smallest argmin
+ }
+ }
+ if(I == -1)
+ return UNBOUNDED; // Can only happen in Phase 2.
+
+ simplexTableau(E,Bindices,I,J);
+
+ // Generate new tableau
+ Bindices[I]=J;
+ rowreduce(E,N,I,J);
+ }
+ return OPTIMAL;
+ }
+
+ int iterateDual(rational[][] E, int N, int[] Bindices) {
+ while(true) {
+ // Find first negative entry in right (basic variable) column
+ rational[] Em=E[m];
+ int I;
+ for(I=0; I < m; ++I) {
+ if(E[I][N] < 0) break;
+ }
+
+ if(I == m)
+ break;
+
+ int J=-1;
+ rational M;
+ for(int j=0; j < N; ++j) {
+ rational e=E[I][j];
+ if(e < 0) {
+ M=-E[m][j]/e;
+ J=j;
+ break;
+ }
+ }
+ for(int j=J+1; j < N; ++j) {
+ rational e=E[I][j];
+ if(e < 0) {
+ rational v=-E[m][j]/e;
+ if(v < M) {M=v; J=j;} // Bland's rule: choose smallest argmin
+ }
+ }
+ if(J == -1)
+ return INFEASIBLE; // Can only happen in Phase 2.
+
+ simplexTableau(E,Bindices,I,J);
+
+ // Generate new tableau
+ Bindices[I]=J;
+ rowreduce(E,N,I,J);
+ }
+ return OPTIMAL;
+ }
+
+ // Try to find a solution x to Ax=b that minimizes the cost c^T x,
+ // where A is an m x n matrix, x is a vector of n non-negative numbers,
+ // b is a vector of length m, and c is a vector of length n.
+ // Can set phase1=false if the last m columns of A form the identity matrix.
+ void operator init(rational[] c, rational[][] A, rational[] b,
+ bool phase1=true, bool dual=false) {
+ if(dual) phase1=false;
+ // Phase 1
+ m=A.length;
+ if(m == 0) {case=INFEASIBLE; return;}
+ n=A[0].length;
+ if(n == 0) {case=INFEASIBLE; return;}
+
+ int N=phase1 ? n+m : n;
+ rational[][] E=new rational[m+1][N+1];
+ rational[] Em=E[m];
+
+ for(int j=0; j < n; ++j)
+ Em[j]=0;
+
+ for(int i=0; i < m; ++i) {
+ rational[] Ai=A[i];
+ rational[] Ei=E[i];
+ if(b[i] >= 0 || dual) {
+ for(int j=0; j < n; ++j) {
+ rational Aij=Ai[j];
+ Ei[j]=Aij;
+ Em[j] -= Aij;
+ }
+ } else {
+ for(int j=0; j < n; ++j) {
+ rational Aij=-Ai[j];
+ Ei[j]=Aij;
+ Em[j] -= Aij;
+ }
+ }
+ }
+
+ if(phase1) {
+ for(int i=0; i < m; ++i) {
+ rational[] Ei=E[i];
+ for(int j=0; j < i; ++j)
+ Ei[n+j]=0;
+ Ei[n+i]=1;
+ for(int j=i+1; j < m; ++j)
+ Ei[n+j]=0;
+ }
+ }
+
+ rational sum=0;
+ for(int i=0; i < m; ++i) {
+ rational B=dual ? b[i] : abs(b[i]);
+ E[i][N]=B;
+ sum -= B;
+ }
+ Em[N]=sum;
+
+ if(phase1)
+ for(int j=0; j < m; ++j)
+ Em[n+j]=0;
+
+ int[] Bindices;
+
+ if(phase1) {
+ Bindices=sequence(new int(int x){return x;},m)+n;
+ iterate(E,N,Bindices);
+
+ if(Em[J] != 0) {
+ simplexTableau(E,Bindices);
+ case=INFEASIBLE;
+ return;
+ }
+ } else Bindices=sequence(new int(int x){return x;},m)+n-m;
+
+ rational[] cB=phase1 ? new rational[m] : c[n-m:n];
+ rational[][] D=phase1 ? new rational[m+1][n+1] : E;
+ if(phase1) {
+ bool output=true;
+ // Drive artificial variables out of basis.
+ for(int i=0; i < m; ++i) {
+ int k=Bindices[i];
+ if(k >= n) {
+ rational[] Ei=E[i];
+ int j;
+ for(j=0; j < n; ++j)
+ if(Ei[j] != 0) break;
+ if(j == n) continue;
+ output=false;
+ simplexTableau(E,Bindices,i,j);
+ Bindices[i]=j;
+ rowreduce(E,n,i,j);
+ }
+ }
+ if(output) simplexTableau(E,Bindices);
+ int ip=0; // reduced i
+ for(int i=0; i < m; ++i) {
+ int k=Bindices[i];
+ if(k >= n) continue;
+ Bindices[ip]=k;
+ cB[ip]=c[k];
+ rational[] Dip=D[ip];
+ rational[] Ei=E[i];
+ for(int j=0; j < n; ++j)
+ Dip[j]=Ei[j];
+ Dip[n]=Ei[N];
+ ++ip;
+ }
+
+ rational[] Dip=D[ip];
+ rational[] Em=E[m];
+ for(int j=0; j < n; ++j)
+ Dip[j]=Em[j];
+ Dip[n]=Em[N];
+
+ if(m > ip) {
+ Bindices.delete(ip,m-1);
+ D.delete(ip,m-1);
+ m=ip;
+ }
+ if(!output) simplexTableau(D,Bindices);
+ }
+
+ rational[] Dm=D[m];
+ for(int j=0; j < n; ++j) {
+ rational sum=0;
+ for(int k=0; k < m; ++k)
+ sum += cB[k]*D[k][j];
+ Dm[j]=c[j]-sum;
+ }
+
+ rational sum=0;
+ for(int k=0; k < m; ++k)
+ sum += cB[k]*D[k][n];
+ Dm[n]=-sum;
+
+ simplexPhase2();
+
+ case=(dual ? iterateDual : iterate)(D,n,Bindices);
+ simplexTableau(D,Bindices);
+ if(case != OPTIMAL)
+ return;
+
+ for(int j=0; j < n; ++j)
+ x[j]=0;
+
+ for(int k=0; k < m; ++k)
+ x[Bindices[k]]=D[k][n];
+
+ cost=-Dm[n];
+ }
+
+ // Try to find a solution x to sgn(Ax-b)=sgn(s) that minimizes the cost
+ // c^T x, where A is an m x n matrix, x is a vector of n non-negative
+ // numbers, b is a vector of length m, and c is a vector of length n.
+ void operator init(rational[] c, rational[][] A, int[] s, rational[] b) {
+ int m=A.length;
+ if(m == 0) {case=INFEASIBLE; return;}
+ int n=A[0].length;
+ if(n == 0) {case=INFEASIBLE; return;}
+
+ int count=0;
+ for(int i=0; i < m; ++i)
+ if(s[i] != 0) ++count;
+
+ rational[][] a=new rational[m][n+count];
+
+ for(int i=0; i < m; ++i) {
+ rational[] ai=a[i];
+ rational[] Ai=A[i];
+ for(int j=0; j < n; ++j) {
+ ai[j]=Ai[j];
+ }
+ }
+
+ int k=0;
+
+ bool phase1=false;
+ bool dual=count == m && all(c >= 0);
+
+ for(int i=0; i < m; ++i) {
+ rational[] ai=a[i];
+ for(int j=0; j < k; ++j)
+ ai[n+j]=0;
+ if(k < count)
+ ai[n+k]=-s[i];
+ for(int j=k+1; j < count; ++j)
+ ai[n+j]=0;
+ int si=s[i];
+ if(si == 0) phase1=true;
+ else {
+ ++k;
+ rational bi=b[i];
+ if(bi == 0) {
+ if(si == 1) {
+ s[i]=-1;
+ for(int j=0; j < n+count; ++j)
+ ai[j]=-ai[j];
+ }
+ } else if(si*bi > 0) {
+ if(dual && si == 1) {
+ b[i]=-bi;
+ s[i]=-1;
+ for(int j=0; j < n+count; ++j)
+ ai[j]=-ai[j];
+ } else
+ phase1=true;
+ }
+ }
+ }
+
+ operator init(concat(c,array(count,rational(0))),a,b,phase1,dual);
+
+ if(case == OPTIMAL && count > 0)
+ x.delete(n,n+count-1);
+ }
+}
diff --git a/graphics/asymptote/base/reload.js b/graphics/asymptote/base/reload.js
new file mode 100644
index 0000000000..a652680305
--- /dev/null
+++ b/graphics/asymptote/base/reload.js
@@ -0,0 +1,23 @@
+// Load/reload the document associated with a given path.
+
+// UNIX: Copy to ~/.adobe/Acrobat/x.x/JavaScripts/
+// To avoid random window placement we recommend specifying an acroread
+// geometry option, for example: -geometry +0+0
+
+// MSWindows: Copy to %APPDATA%/Adobe/Acrobat/x.x/JavaScripts/
+
+// Note: x.x represents the appropriate Acrobat Reader version number.
+
+reload = app.trustedFunction(function(path) {
+ app.beginPriv();
+ n=app.activeDocs.length;
+ for(i=app.activeDocs.length-1; i >= 0; --i) {
+ Doc=app.activeDocs[i];
+ if(Doc.path == path && Doc != this) {
+ Doc.closeDoc();
+ break;
+ }
+ }
+ app.openDoc(path);
+ app.endPriv();
+ });
diff --git a/graphics/asymptote/base/res/notes.txt b/graphics/asymptote/base/res/notes.txt
new file mode 100644
index 0000000000..6b84573510
--- /dev/null
+++ b/graphics/asymptote/base/res/notes.txt
@@ -0,0 +1,7 @@
+For now, I decide not to commit in the *.hdr reflectance image files
+because of the size and that they are binary format. Meanwhile, the
+images I use (temporarily) can be found at:
+- <https://www.deviantart.com/zbyg/art/HDRi-Pack-1-97402522>
+- <https://hdrihaven.com/>
+
+-- Supakorn "Jamie" \ No newline at end of file
diff --git a/graphics/asymptote/base/roundedpath.asy b/graphics/asymptote/base/roundedpath.asy
new file mode 100644
index 0000000000..1a426f91dc
--- /dev/null
+++ b/graphics/asymptote/base/roundedpath.asy
@@ -0,0 +1,84 @@
+// a function to round sharp edges of open and cyclic paths
+// written by stefan knorr
+
+path roundedpath(path A, real R, real S = 1)
+// create rounded path from path A with radius R and scale S = 1
+{
+ path RoundPath; // returned path
+ path LocalPath; // local straight subpath
+ path LocalCirc; // local edge circle for intersection
+ real LocalTime; // local intersectiontime between . and ..
+ pair LocalPair; // local point to be added to 'RoundPath'
+
+ int len=length(A); // length of given path 'A'
+ bool PathClosed=cyclic(A); // true, if given path 'A' is cyclic
+
+ // initialisation: define first Point of 'RoundPath' as
+ if (PathClosed) // ? is 'A' cyclic
+ RoundPath=scale(S)*point(point(A,0)--point(A,1), 0.5); // centerpoint of first straight subpath of 'A'
+ else
+ RoundPath=scale(S)*point(A,0); // first point of 'A'
+
+ // doing everything between start and end
+ // create round paths subpath by subpath for every i-th edge
+ for(int i=1; i < len; ++i)
+ {
+ // straight subpath towards i-th edge
+ LocalPath=point(A,i-1)---point(A,i);
+ // circle with radius 'R' around i-th edge
+ LocalCirc=circle(point(A,i),R);
+ // calculate intersection time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add straight subpath towards i-th curvature to 'RoundPath'
+ RoundPath=RoundPath--scale(S)*LocalPair;
+ }
+
+ // straight subpath from i-th edge to (i+1)-th edge
+ LocalPath=point(A,i)---point(A,i+1);
+ // calculate intersection-time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add curvature near i-th edge to 'RoundPath'
+ RoundPath=RoundPath..scale(S)*LocalPair;
+ }
+ }
+
+ // final steps to have a correct termination
+ if(PathClosed) { // Is 'A' cyclic?
+ // straight subpath towards 0-th edge
+ LocalPath=point(A,len-1)---point(A,0);
+ // circle with radius 'R' around 0-th edge
+ LocalCirc=circle(point(A,0),R);
+ // calculate intersection-time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add straight subpath towards 0-th curvature to 'RoundPath'
+ RoundPath=RoundPath--scale(S)*LocalPair;
+ }
+
+
+ // straight subpath from 0-th edge to 1st edge
+ LocalPath=point(A,0)---point(A,1);
+ // calculate intersection-time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add curvature near 0-th edge to 'RoundPath' and close path
+ RoundPath=RoundPath..scale(S)*LocalPair--cycle;
+ }
+ } else
+ RoundPath=RoundPath--scale(S)*point(A,len);
+ return RoundPath;
+}
diff --git a/graphics/asymptote/base/shaders/fragment.glsl b/graphics/asymptote/base/shaders/fragment.glsl
new file mode 100644
index 0000000000..38a6a53fbb
--- /dev/null
+++ b/graphics/asymptote/base/shaders/fragment.glsl
@@ -0,0 +1,237 @@
+struct Material
+{
+ vec4 diffuse,emissive,specular;
+ vec4 parameters;
+};
+
+struct Light
+{
+ vec4 direction;
+ vec4 diffuse,specular;
+};
+
+uniform int nlights;
+uniform Light lights[Nlights];
+
+uniform MaterialBuffer {
+ Material Materials[Nmaterials];
+};
+
+
+#ifdef NORMAL
+in vec3 Normal;
+vec3 normal;
+#endif
+
+#ifdef EXPLICIT_COLOR
+in vec4 Color;
+#endif
+
+flat in int materialIndex;
+out vec4 outColor;
+
+// PBR material parameters
+vec3 PBRBaseColor; // Diffuse for nonmetals, reflectance for metals.
+vec3 PBRSpecular; // Specular tint for nonmetals
+float PBRMetallic; // Metallic/Nonmetals switch flag
+float PBRF0; // Fresnel at zero for nonmetals
+float PBRRoughness; // Roughness.
+float PBRRoughnessSq; // used value of roughness, for a little bit more "smoothing"
+
+uniform sampler2D environmentMap;
+const float PI = acos(-1.0);
+#ifdef ENABLE_TEXTURE
+const float twopi=2*PI;
+const float halfpi=PI/2;
+
+const int numSamples=7;
+
+// (x,y,z) -> (r, theta, phi);
+// theta -> [0,\pi], "height" angle
+// phi -> [0, 2\pi], rotation agnle
+vec3 cart2spher(vec3 cart) {
+ float x = cart.z;
+ float y = cart.x;
+ float z = cart.y;
+
+ float r = length(cart);
+ float phi = atan(y,x);
+ float theta = acos(z/r);
+
+ return vec3(r,phi,theta);
+}
+
+vec2 normalizedAngle(vec3 cartVec) {
+ vec3 sphericalVec = cart2spher(cartVec);
+ sphericalVec.y = sphericalVec.y / (2 * PI) - 0.25;
+ sphericalVec.z = sphericalVec.z / PI;
+ // sphericalVec.z = - sphericalVec.z;
+ return sphericalVec.yz;
+}
+#endif
+
+#ifdef NORMAL
+// h is the halfway vector between normal and light direction
+// GGX Trowbridge-Reitz Approximation
+float NDF_TRG(vec3 h, float roughness) {
+ float ndoth = max(dot(normal, h), 0);
+ float alpha2 = PBRRoughnessSq * PBRRoughnessSq;
+
+ float denom = pow(ndoth * ndoth * (alpha2-1) + 1, 2);
+ return alpha2/denom;
+}
+
+float GGX_Geom(vec3 v) {
+ float ndotv = max(dot(v,normal), 0);
+ float ap = pow((1+PBRRoughness),2);
+ float k = ap/8;
+
+ return ndotv/((ndotv * (1-k)) + k);
+}
+
+float Geom(vec3 v, vec3 l) {
+ return GGX_Geom(v) * GGX_Geom(l);
+}
+
+// Schlick's approximation
+float Fresnel(vec3 h, vec3 v, float F0) {
+ float hdotv = max(dot(h,v), 0.0);
+
+ return F0 + (1-F0)*pow((1-hdotv),5);
+}
+
+vec3 BRDF(vec3 viewDirection, vec3 lightDirection) {
+ // Lambertian diffuse
+ vec3 lambertian = PBRBaseColor;
+ // Cook-Torrance model
+ vec3 h = normalize(lightDirection + viewDirection);
+
+ float omegain = max(dot(viewDirection, normal),0);
+ float omegaln = max(dot(lightDirection, normal),0);
+
+ float D = NDF_TRG(h, PBRRoughness);
+ float G = Geom(viewDirection, lightDirection);
+ float F = Fresnel(h, viewDirection, PBRF0);
+
+ float denom=4*omegain*omegaln;
+ float rawReflectance=denom > 0 ? (D*G)/denom : 0;
+
+ vec3 dielectric = mix(lambertian, rawReflectance * PBRSpecular, F);
+ vec3 metal = rawReflectance * PBRBaseColor;
+
+ return mix(dielectric, metal, PBRMetallic);
+}
+#endif
+
+void main()
+{
+vec4 Diffuse;
+vec4 Emissive;
+vec4 Specular;
+vec4 parameters;
+
+#ifdef EXPLICIT_COLOR
+ if(materialIndex < 0) {
+ int index=-materialIndex-1;
+ Material m=Materials[index];
+ Diffuse=Color;
+ Emissive=vec4(0);
+ Specular=m.specular;
+ parameters=m.parameters;
+ } else {
+ Material m=Materials[materialIndex];
+ Diffuse=m.diffuse;
+ Emissive=m.emissive;
+ Specular=m.specular;
+ parameters=m.parameters;
+ }
+#else
+ Material m=Materials[materialIndex];
+ Diffuse=m.diffuse;
+ Emissive=m.emissive;
+ Specular=m.specular;
+ parameters=m.parameters;
+#endif
+
+ PBRRoughness=1-parameters[0];
+ PBRMetallic=parameters[1];
+ PBRF0=parameters[2];
+
+ PBRBaseColor = Diffuse.rgb;
+ PBRRoughnessSq = PBRRoughness * PBRRoughness;
+ PBRSpecular = Specular.rgb;
+
+ // Formally, the formula given a point x and direction \omega,
+ // L_i = \int_{\Omega} f(x, \omega_i, \omega) L(x,\omega_i) (\hat{n}\cdot \omega_i) d \omega_i
+ // where \Omega is the hemisphere covering a point, f is the BRDF function
+ // L is the radiance from a given angle and position.
+
+ vec3 color=Emissive.rgb;
+#ifdef NORMAL
+ vec3 Z=vec3(0,0,1);
+ vec3 pointLightRadiance=vec3(0,0,0);
+
+ normal=normalize(Normal);
+ normal=gl_FrontFacing ? normal : -normal;
+ // as a finite point light, we have some simplification to the rendering equation.
+ if(nlights > 0) {
+ for(int i=0; i < nlights; ++i) {
+ vec3 L = normalize(lights[i].direction.xyz);
+ // what if we use the acutal view from (0,0,0) instead?
+ // vec3 viewDirection = Z;
+ vec3 viewDirection = -normalize(Z);
+ float cosTheta = max(dot(normal, L), 0); // $\omega_i \cdot n$ term
+ float attn = 1; // if we have a good light position.
+ vec3 radiance = cosTheta * attn * lights[i].diffuse.rgb;
+ pointLightRadiance += BRDF(Z, L) * radiance;
+ }
+ color += pointLightRadiance.rgb;
+
+#ifdef ENABLE_TEXTURE
+#ifndef EXPLICIT_COLOR
+ // Experimental environment radiance using Riemann sums;
+ // can also do importance sampling.
+ vec3 envRadiance=vec3(0,0,0);
+
+ vec3 normalPerp = vec3(-normal.y, normal.x, 0);
+ if (length(normalPerp) == 0) { // x, y = 0.
+
+ normalPerp = vec3(1, 0, 0);
+ }
+ // we now have a normal basis;
+ normalPerp = normalize(normalPerp);
+ vec3 normalPerp2 = normalize(cross(normal, normalPerp));
+
+ const float step=1.0/numSamples;
+ const float phistep=twopi*step;
+ const float thetastep=halfpi*step;
+ for (int iphi=0; iphi < numSamples; ++iphi) {
+ float phi=iphi*phistep;
+ for (int itheta=0; itheta < numSamples; ++itheta) {
+ float theta=itheta*thetastep;
+
+ vec3 azimuth=cos(phi)*normalPerp+sin(phi)*normalPerp2;
+ vec3 L=sin(theta)*azimuth+cos(theta)*normal;
+
+ vec3 rawRadiance=texture(environmentMap,normalizedAngle(L)).rgb;
+ vec3 surfRefl=BRDF(Z,L);
+ envRadiance += surfRefl*rawRadiance*sin(2.0*theta);
+ }
+ }
+ envRadiance *= halfpi*step*step;
+
+ // vec3 lightVector = normalize(reflect(-Z, normal));
+ // vec2 anglemap = normalizedAngle(lightVector);
+ // vec3 color = texture(environmentMap, anglemap).rgb;
+ color += envRadiance.rgb;
+#endif
+#endif
+ outColor=vec4(color,Diffuse.a);
+ } else {
+ outColor=Diffuse;
+ }
+#else
+ outColor=Emissive;
+#endif
+}
+
diff --git a/graphics/asymptote/base/shaders/vertex.glsl b/graphics/asymptote/base/shaders/vertex.glsl
new file mode 100644
index 0000000000..815145461e
--- /dev/null
+++ b/graphics/asymptote/base/shaders/vertex.glsl
@@ -0,0 +1,49 @@
+in vec3 position;
+
+#ifdef NORMAL
+in vec3 normal;
+#endif
+
+#ifdef EXPLICIT_COLOR
+in uint color;
+#endif
+
+#ifdef WIDTH
+in float width;
+#endif
+
+in int material;
+
+uniform mat4 projViewMat;
+uniform mat4 viewMat;
+uniform mat4 normMat;
+
+out vec3 ViewPosition;
+#ifdef NORMAL
+out vec3 Normal;
+#endif
+
+#ifdef EXPLICIT_COLOR
+out vec4 Color;
+#endif
+
+flat out int materialIndex;
+
+void main()
+{
+ gl_Position=projViewMat*vec4(position,1.0);
+ ViewPosition=(viewMat*vec4(position,1.0)).xyz;
+#ifdef NORMAL
+ Normal=(normMat*vec4(normal,0)).xyz;
+#endif
+
+#ifdef EXPLICIT_COLOR
+ Color=unpackUnorm4x8(color);
+#endif
+
+#ifdef WIDTH
+ gl_PointSize=width;
+#endif
+
+ materialIndex=material;
+}
diff --git a/graphics/asymptote/base/simplex.asy b/graphics/asymptote/base/simplex.asy
new file mode 100644
index 0000000000..040621dd90
--- /dev/null
+++ b/graphics/asymptote/base/simplex.asy
@@ -0,0 +1,329 @@
+// Real simplex solver written by John C. Bowman and Pouria Ramazi, 2018.
+
+struct simplex {
+ static int OPTIMAL=0;
+ static int UNBOUNDED=1;
+ static int INFEASIBLE=2;
+
+ int case;
+ real[] x;
+ real cost;
+
+ int m,n;
+ int J;
+ real epsilonA;
+
+ // Row reduce based on pivot E[I][J]
+ void rowreduce(real[][] E, int N, int I, int J) {
+ real[] EI=E[I];
+ real v=EI[J];
+ for(int j=0; j < J; ++j) EI[j] /= v;
+ EI[J]=1.0;
+ for(int j=J+1; j <= N; ++j) EI[j] /= v;
+
+ for(int i=0; i < I; ++i) {
+ real[] Ei=E[i];
+ real EiJ=Ei[J];
+ for(int j=0; j < J; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ Ei[J]=0.0;
+ for(int j=J+1; j <= N; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ }
+ for(int i=I+1; i <= m; ++i) {
+ real[] Ei=E[i];
+ real EiJ=Ei[J];
+ for(int j=0; j < J; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ Ei[J]=0.0;
+ for(int j=J+1; j <= N; ++j)
+ Ei[j] -= EI[j]*EiJ;
+ }
+ }
+
+ int iterate(real[][] E, int N, int[] Bindices) {
+ while(true) {
+ // Find first negative entry in bottom (reduced cost) row
+ real[] Em=E[m];
+ for(J=0; J < N; ++J)
+ if(Em[J] < 0) break;
+
+ if(J == N)
+ break;
+
+ int I=-1;
+ real M;
+ for(int i=0; i < m; ++i) {
+ real e=E[i][J];
+ if(e > epsilonA) {
+ M=E[i][N]/e;
+ I=i;
+ break;
+ }
+ }
+ for(int i=I+1; i < m; ++i) {
+ real e=E[i][J];
+ if(e > epsilonA) {
+ real v=E[i][N]/e;
+ if(v < M) {M=v; I=i;} // Bland's rule: choose smallest argmin
+ }
+ }
+ if(I == -1)
+ return UNBOUNDED; // Can only happen in Phase 2.
+
+ // Generate new tableau
+ Bindices[I]=J;
+ rowreduce(E,N,I,J);
+ }
+ return OPTIMAL;
+ }
+
+ int iterateDual(real[][] E, int N, int[] Bindices) {
+ while(true) {
+ // Find first negative entry in right (basic variable) column
+ real[] Em=E[m];
+ int I;
+ for(I=0; I < m; ++I) {
+ if(E[I][N] < 0) break;
+ }
+
+ if(I == m)
+ break;
+
+ int J=-1;
+ real M;
+ for(int j=0; j < N; ++j) {
+ real e=E[I][j];
+ if(e < epsilonA) {
+ M=-E[m][j]/e;
+ J=j;
+ break;
+ }
+ }
+ for(int j=J+1; j < N; ++j) {
+ real e=E[I][j];
+ if(e < epsilonA) {
+ real v=-E[m][j]/e;
+ if(v < M) {M=v; J=j;} // Bland's rule: choose smallest argmin
+ }
+ }
+ if(J == -1)
+ return INFEASIBLE; // Can only happen in Phase 2.
+
+ // Generate new tableau
+ Bindices[I]=J;
+ rowreduce(E,N,I,J);
+ }
+ return OPTIMAL;
+ }
+
+ // Try to find a solution x to Ax=b that minimizes the cost c^T x,
+ // where A is an m x n matrix, x is a vector of n non-negative numbers,
+ // b is a vector of length m, and c is a vector of length n.
+ // Can set phase1=false if the last m columns of A form the identity matrix.
+ void operator init(real[] c, real[][] A, real[] b, bool phase1=true,
+ bool dual=false) {
+ if(dual) phase1=false;
+ static real epsilon=sqrt(realEpsilon);
+ epsilonA=epsilon*norm(A);
+
+ // Phase 1
+ m=A.length;
+ if(m == 0) {case=INFEASIBLE; return;}
+ n=A[0].length;
+ if(n == 0) {case=INFEASIBLE; return;}
+
+ int N=phase1 ? n+m : n;
+ real[][] E=new real[m+1][N+1];
+ real[] Em=E[m];
+
+ for(int j=0; j < n; ++j)
+ Em[j]=0;
+
+ for(int i=0; i < m; ++i) {
+ real[] Ai=A[i];
+ real[] Ei=E[i];
+ if(b[i] >= 0 || dual) {
+ for(int j=0; j < n; ++j) {
+ real Aij=Ai[j];
+ Ei[j]=Aij;
+ Em[j] -= Aij;
+ }
+ } else {
+ for(int j=0; j < n; ++j) {
+ real Aij=-Ai[j];
+ Ei[j]=Aij;
+ Em[j] -= Aij;
+ }
+ }
+ }
+
+ if(phase1) {
+ for(int i=0; i < m; ++i) {
+ real[] Ei=E[i];
+ for(int j=0; j < i; ++j)
+ Ei[n+j]=0.0;
+ Ei[n+i]=1.0;
+ for(int j=i+1; j < m; ++j)
+ Ei[n+j]=0.0;
+ }
+ }
+
+ real sum=0;
+ for(int i=0; i < m; ++i) {
+ real B=dual ? b[i] : abs(b[i]);
+ E[i][N]=B;
+ sum -= B;
+ }
+ Em[N]=sum;
+
+ if(phase1)
+ for(int j=0; j < m; ++j)
+ Em[n+j]=0.0;
+
+ int[] Bindices;
+
+ if(phase1) {
+ Bindices=sequence(new int(int x){return x;},m)+n;
+ iterate(E,N,Bindices);
+
+ if(abs(Em[J]) > epsilonA) {
+ case=INFEASIBLE;
+ return;
+ }
+ } else Bindices=sequence(new int(int x){return x;},m)+n-m;
+
+ real[] cB=phase1 ? new real[m] : c[n-m:n];
+ real[][] D=phase1 ? new real[m+1][n+1] : E;
+ if(phase1) {
+ // Drive artificial variables out of basis.
+ for(int i=0; i < m; ++i) {
+ int k=Bindices[i];
+ if(k >= n) {
+ real[] Ei=E[i];
+ int j;
+ for(j=0; j < n; ++j)
+ if(Ei[j] != 0) break;
+ if(j == n) continue;
+ Bindices[i]=j;
+ rowreduce(E,n,i,j);
+ }
+ }
+ int ip=0; // reduced i
+ for(int i=0; i < m; ++i) {
+ int k=Bindices[i];
+ if(k >= n) continue;
+ Bindices[ip]=k;
+ cB[ip]=c[k];
+ real[] Dip=D[ip];
+ real[] Ei=E[i];
+ for(int j=0; j < n; ++j)
+ Dip[j]=Ei[j];
+ Dip[n]=Ei[N];
+ ++ip;
+ }
+
+ real[] Dip=D[ip];
+ real[] Em=E[m];
+ for(int j=0; j < n; ++j)
+ Dip[j]=Em[j];
+ Dip[n]=Em[N];
+
+ if(m > ip) {
+ Bindices.delete(ip,m-1);
+ D.delete(ip,m-1);
+ m=ip;
+ }
+ }
+
+ real[] Dm=D[m];
+ for(int j=0; j < n; ++j) {
+ real sum=0;
+ for(int k=0; k < m; ++k)
+ sum += cB[k]*D[k][j];
+ Dm[j]=c[j]-sum;
+ }
+
+ real sum=0;
+ for(int k=0; k < m; ++k)
+ sum += cB[k]*D[k][n];
+ Dm[n]=-sum;
+
+ case=(dual ? iterateDual : iterate)(D,n,Bindices);
+ if(case != OPTIMAL)
+ return;
+
+ for(int j=0; j < n; ++j)
+ x[j]=0;
+
+ for(int k=0; k < m; ++k)
+ x[Bindices[k]]=D[k][n];
+
+ cost=-Dm[n];
+ }
+
+ // Try to find a solution x to sgn(Ax-b)=sgn(s) that minimizes the cost
+ // c^T x, where A is an m x n matrix, x is a vector of n non-negative
+ // numbers, b is a vector of length m, and c is a vector of length n.
+ void operator init(real[] c, real[][] A, int[] s, real[] b) {
+ int m=A.length;
+ if(m == 0) {case=INFEASIBLE; return;}
+ int n=A[0].length;
+ if(n == 0) {case=INFEASIBLE; return;}
+
+ int count=0;
+ for(int i=0; i < m; ++i)
+ if(s[i] != 0) ++count;
+
+ real[][] a=new real[m][n+count];
+
+ for(int i=0; i < m; ++i) {
+ real[] ai=a[i];
+ real[] Ai=A[i];
+ for(int j=0; j < n; ++j) {
+ ai[j]=Ai[j];
+ }
+ }
+
+ int k=0;
+
+ bool phase1=false;
+ bool dual=count == m && all(c >= 0);
+
+ for(int i=0; i < m; ++i) {
+ real[] ai=a[i];
+ for(int j=0; j < k; ++j)
+ ai[n+j]=0;
+ if(k < count)
+ ai[n+k]=-s[i];
+ for(int j=k+1; j < count; ++j)
+ ai[n+j]=0;
+ int si=s[i];
+ if(si == 0) phase1=true;
+ else {
+ ++k;
+ real bi=b[i];
+ if(bi == 0) {
+ if(si == 1) {
+ s[i]=-1;
+ for(int j=0; j < n+count; ++j)
+ ai[j]=-ai[j];
+ }
+ } else if(si*bi > 0) {
+ if(dual && si == 1) {
+ b[i]=-bi;
+ s[i]=-1;
+ for(int j=0; j < n+count; ++j)
+ ai[j]=-ai[j];
+ } else
+ phase1=true;
+ }
+ }
+ }
+
+ operator init(concat(c,array(count,0.0)),a,b,phase1,dual);
+
+ if(case == OPTIMAL && count > 0)
+ x.delete(n,n+count-1);
+ }
+}
diff --git a/graphics/asymptote/base/size10.asy b/graphics/asymptote/base/size10.asy
new file mode 100644
index 0000000000..3bbd31227a
--- /dev/null
+++ b/graphics/asymptote/base/size10.asy
@@ -0,0 +1,12 @@
+texpreamble("\makeatletter%
+\renewcommand\normalsize{\@setfontsize\normalsize\@xpt\@xiipt}%
+\renewcommand\small{\@setfontsize\small\@ixpt{11}}%
+\renewcommand\footnotesize{\@setfontsize\footnotesize\@viiipt{9.5}}%
+\renewcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt}%
+\renewcommand\tiny{\@setfontsize\tiny\@vpt\@vipt}%
+\renewcommand\large{\@setfontsize\large\@xiipt{14}}%
+\renewcommand\Large{\@setfontsize\Large\@xivpt{18}}%
+\renewcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}}%
+\renewcommand\huge{\@setfontsize\huge\@xxpt{25}}%
+\renewcommand\Huge{\@setfontsize\Huge\@xxvpt{30}}%
+\makeatother");
diff --git a/graphics/asymptote/base/size11.asy b/graphics/asymptote/base/size11.asy
new file mode 100644
index 0000000000..9371228815
--- /dev/null
+++ b/graphics/asymptote/base/size11.asy
@@ -0,0 +1,12 @@
+texpreamble("\makeatletter%
+\renewcommand\normalsize{\@setfontsize\normalsize\@xipt{13.6}}%
+\renewcommand\small{\@setfontsize\small\@xpt\@xiipt}%
+\renewcommand\footnotesize{\@setfontsize\footnotesize\@ixpt{11}}%
+\renewcommand\scriptsize{\@setfontsize\scriptsize\@viiipt{9.5}}
+\renewcommand\tiny{\@setfontsize\tiny\@vipt\@viipt}
+\renewcommand\large{\@setfontsize\large\@xiipt{14}}
+\renewcommand\Large{\@setfontsize\Large\@xivpt{18}}
+\renewcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}}
+\renewcommand\huge{\@setfontsize\huge\@xxpt{25}}
+\renewcommand\Huge{\@setfontsize\Huge\@xxvpt{30}}
+\makeatother");
diff --git a/graphics/asymptote/base/slide.asy b/graphics/asymptote/base/slide.asy
new file mode 100644
index 0000000000..8a787c37a5
--- /dev/null
+++ b/graphics/asymptote/base/slide.asy
@@ -0,0 +1,620 @@
+import fontsize;
+usepackage("asycolors");
+
+bool reverse=false; // Set to true to enable reverse video.
+bool stepping=false; // Set to true to enable stepping.
+bool itemstep=true; // Set to false to disable stepping on each item.
+
+settings.toolbar=false; // Disable 3D toolbar by default.
+if(settings.render < 0) settings.render=4;
+
+bool allowstepping=false; // Allow stepping for current slide.
+
+real pagemargin=0.5cm;
+real pagewidth=-2pagemargin;
+real pageheight=-2pagemargin;
+
+bool landscape=orientation == Landscape || orientation == Seascape;
+
+if(landscape) {
+ orientation=Portrait;
+ pagewidth += settings.paperheight;
+ pageheight += settings.paperwidth;
+} else {
+ pagewidth += settings.paperwidth;
+ pageheight += settings.paperheight;
+}
+
+size(pagewidth,pageheight,IgnoreAspect);
+picture background;
+
+real minipagemargin=1inch;
+real minipagewidth=pagewidth-2minipagemargin;
+
+transform tinv=inverse(fixedscaling((-1,-1),(1,1),currentpen));
+
+pen itempen=fontsize(24pt);
+pen codepen=fontsize(20pt);
+pen titlepagepen=fontsize(36pt);
+pen authorpen=fontsize(24pt);
+pen institutionpen=authorpen;
+pen datepen=fontsize(18pt);
+pen urlpen=datepen;
+
+real itemskip=0.5;
+real codeskip=0.25;
+real aboveequationskip=-1.25;
+
+pair dateskip=(0,0.1);
+pair urlskip=(0,0.2);
+
+pair titlealign=3S;
+pen titlepen=fontsize(32pt);
+real titleskip=0.5;
+
+string oldbulletcolor;
+string newbulletcolor="red";
+string bullet="{\bulletcolor\textbullet}";
+
+pair pagenumberposition=S+E;
+pair pagenumberalign=4NW;
+pen pagenumberpen=fontsize(12);
+pen steppagenumberpen=colorless(pagenumberpen);
+
+real figureborder=0.25cm;
+pen figuremattpen;
+
+pen backgroundcolor;
+pen foregroundcolor;
+
+pair titlepageposition=(-0.8,0.4);
+pair startposition=(-0.8,0.9);
+pair currentposition=startposition;
+
+string bulletcolor(string color)
+{
+ return "\def\bulletcolor{"+'\\'+"color{"+color+"}}%";
+}
+
+int[] firstnode=new int[] {currentpicture.nodes.length};
+int[] lastnode;
+bool firststep=true;
+
+int page=0;
+bool havepagenumber=true;
+
+int preamblenodes=2;
+
+bool empty()
+{
+ return currentpicture.nodes.length <= preamblenodes;
+}
+
+void background()
+{
+ if(!background.empty()) {
+ add(background);
+ layer();
+ preamblenodes += 2;
+ }
+}
+
+void color(string name, string color)
+{
+ texpreamble("\def"+'\\'+name+"#1{{\color{"+color+"}#1}}%");
+}
+
+string texcolor(pen p)
+{
+ real[] colors=colors(p);
+ string s;
+ if(colors.length > 0) {
+ s="{"+colorspace(p)+"}{";
+ for(int i=0; i < colors.length-1; ++i)
+ s += format("%.6f",colors[i],"C")+",";
+ s += format("%.6f",colors[colors.length-1],"C")+"}";
+ }
+ return s;
+}
+
+void setpens(pen red=red, pen blue=blue, pen steppen=red)
+{
+ itempen=colorless(itempen);
+ codepen=colorless(codepen);
+ pagenumberpen=colorless(pagenumberpen);
+ steppagenumberpen=colorless(steppagenumberpen)+steppen;
+ titlepagepen=colorless(titlepagepen)+red;
+ authorpen=colorless(authorpen)+blue;
+ institutionpen=colorless(institutionpen)+blue;
+ datepen=colorless(datepen);
+ urlpen=colorless(urlpen);
+}
+
+void reversevideo()
+{
+ backgroundcolor=black;
+ foregroundcolor=white;
+ fill(background,box((-1,-1),(1,1)),backgroundcolor);
+ setpens(mediumred,paleblue,mediumblue);
+ // Work around pdflatex bug, in which white is mapped to black!
+ figuremattpen=pdf() ? cmyk(0,0,0,1/255) : white;
+ color("Red","mediumred");
+ color("Green","green");
+ color("Blue","paleblue");
+ color("Foreground","white");
+ color("Background","black");
+ oldbulletcolor="white";
+ defaultpen(itempen+foregroundcolor);
+}
+
+void normalvideo() {
+ backgroundcolor=invisible;
+ foregroundcolor=black;
+ background=new picture;
+ size(background,currentpicture);
+ setpens();
+ figuremattpen=invisible;
+ color("Red","red");
+ color("Green","heavygreen");
+ color("Blue","blue");
+ color("Foreground","black");
+ color("Background","white");
+ oldbulletcolor="black";
+ defaultpen(itempen+foregroundcolor);
+}
+
+normalvideo();
+
+texpreamble(bulletcolor(newbulletcolor));
+texpreamble("\hyphenpenalty=10000\tolerance=1000");
+texpreamble("\usepackage{amsmath}");
+
+// Evaluate user command line option.
+void usersetting()
+{
+ plain.usersetting();
+ if(reverse) { // Black background
+ reversevideo();
+ } else { // White background
+ normalvideo();
+ }
+}
+
+void numberpage(pen p=pagenumberpen)
+{
+ if(havepagenumber) {
+ label((string) page,pagenumberposition,pagenumberalign,p);
+ }
+}
+
+void nextpage(pen p=pagenumberpen)
+{
+ if(!empty()) {
+ numberpage(p);
+ newpage();
+ }
+ background();
+ firststep=true;
+}
+
+void newslide(bool stepping=true)
+{
+ allowstepping=stepping;
+ nextpage();
+ ++page;
+ havepagenumber=true;
+ currentposition=startposition;
+ firstnode=new int[] {currentpicture.nodes.length};
+ lastnode.delete();
+}
+
+bool checkposition()
+{
+ if(abs(currentposition.x) > 1 || abs(currentposition.y) > 1) {
+ newslide();
+ return false;
+ }
+ return true;
+}
+
+void erasestep(int erasenode) {
+ if(!stepping || !allowstepping) return;
+ if(!checkposition()) return;
+ lastnode.push(erasenode);
+ nextpage(steppagenumberpen);
+ for(int i=0; i < firstnode.length; ++i) {
+ for(int j=firstnode[i]; j <= lastnode[i]; ++j) {
+ tex(bulletcolor(oldbulletcolor));
+ currentpicture.add(currentpicture.nodes[j].d);
+ }
+ }
+ firstnode.push(currentpicture.nodes.length-1);
+ tex(bulletcolor(newbulletcolor));
+}
+
+void step()
+{
+ // Step without erasing anything.
+ erasestep(currentpicture.nodes.length-1);
+}
+
+void incrementposition(pair z)
+{
+ currentposition += z;
+}
+
+void title(string s, pair position=N, pair align=titlealign,
+ pen p=titlepen, bool newslide=true)
+{
+ if(newslide) newslide();
+ checkposition();
+ frame f;
+ if(s != "") label(f,minipage("\center "+s,minipagewidth),(0,0),align,p);
+ add(f,position,labelmargin(p)*align);
+ currentposition=(currentposition.x,position.y+
+ (tinv*(min(f)-titleskip*I*lineskip(p)*pt)).y);
+}
+
+void outline(string s="Outline", pair position=N, pair align=titlealign,
+ pen p=titlepen)
+{
+ newslide(stepping=false);
+ title(s,position,align,p,newslide=false);
+}
+
+void remark(bool center=false, string s, pair align=0, pen p=itempen,
+ real indent=0, bool minipage=true, real skip=itemskip,
+ filltype filltype=NoFill, bool step=false)
+{
+ checkposition();
+ if(minipage) s=minipage(s,minipagewidth);
+
+ pair offset;
+ if(center) {
+ if(align == 0) align=S;
+ offset=(0,currentposition.y);
+ } else {
+ if(align == 0) align=SE;
+ offset=currentposition;
+ }
+
+ frame f;
+ label(f,s,(indent,0),align,p,filltype);
+ pair m=tinv*min(f);
+ pair M=tinv*min(f);
+
+ if(abs(offset.x+M.x) > 1)
+ warning("slidetoowide","slide too wide on page "+(string) page+':\n'+
+ (string) s);
+
+ if(abs(offset.y+M.y) > 1) {
+ void toohigh() {
+ warning("slidetoohigh","slide too high on page "+(string) page+':\n'+
+ (string) s);
+ }
+ if(M.y-m.y < 2) {
+ newslide(); offset=(offset.x,currentposition.y);
+ if(offset.y+M.y > 1 || offset.y+m.y < -1) toohigh();
+ } else toohigh();
+ }
+
+ if(step) {
+ if(!firststep) step();
+ firststep=false;
+ }
+
+ add(f,offset);
+ incrementposition((0,(tinv*(min(f)-skip*I*lineskip(p)*pt)).y));
+}
+
+void center(string s, pen p=itempen)
+{
+ remark("\center "+s,p);
+}
+
+void vbox(string s, pen p=itempen)
+{
+ remark(center=true,"\vbox{"+s+"}",p,minipage=false,skip=0);
+}
+
+void skip(real n=1)
+{
+ incrementposition((0,(tinv*(-n*itemskip*I*lineskip(itempen)*pt)).y));
+}
+
+void equation(string s, pen p=itempen)
+{
+ skip(aboveequationskip);
+ vbox("\begin{gather*}"+s+"\end{gather*}",p);
+}
+
+void equations(string s, pen p=itempen)
+{
+ skip(aboveequationskip);
+ if(find(s,"&") >= 0)
+ vbox("\begin{align*}"+s+"\end{align*}",p);
+ else
+ vbox("\begin{gather*}"+s+"\end{gather*}",p);
+}
+
+void display(frame[] f, real margin=0, pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen, bool final=true)
+{
+ if(f.length == 0) return;
+ real[] width=new real[f.length];
+ real sum;
+ for(int i=0; i < f.length; ++i) {
+ width[i]=size(f[i]).x;
+ sum += width[i];
+ }
+ if(sum > pagewidth)
+ warning("toowide","slide too wide on page "+(string) page);
+ else margin=(pagewidth-sum)/(f.length+1);
+ real pos;
+ frame F;
+ for(int i=0; i < f.length; ++i) {
+ real w=0.5*(margin+width[i]);
+ pos += w;
+ add(F,f[i],(pos,0),Fill(figureborder,figuremattpen));
+ pos += w;
+ }
+ add(F,(0,currentposition.y),align);
+ if (final) {
+ real a=0.5(unit(align).y-1);
+ incrementposition(
+ (0, (tinv*(a*(max(F)-min(F))-itemskip*I*lineskip(p)*pt)).y));
+ }
+}
+
+void display(frame f, real margin=0, pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen, bool final=true)
+{
+ display(new frame[] {f},margin,align,p,figuremattpen, final);
+}
+
+void display(string[] s, real margin=0, string[] captions=new string[],
+ string caption="", pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen, bool final=true)
+{
+ frame[] f=new frame[s.length];
+ frame F;
+ for(int i=0; i < s.length; ++i) {
+ f[i]=newframe;
+ label(f[i],s[i]);
+ add(F,f[i],(0,0));
+ }
+ real y=point(F,S).y;
+ int stop=min(s.length,captions.length);
+ for(int i=0; i < stop; ++i) {
+ if(captions[i] != "")
+ label(f[i],captions[i],point(f[i],S).x+I*y,S);
+ }
+ display(f,margin,align,p,figuremattpen, final);
+ if(caption != "") center(caption,p);
+}
+
+void display(string s, string caption="", pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen, bool final=true)
+{
+ display(new string[] {s},caption,align,p,figuremattpen, final);
+}
+
+void figure(string[] s, string options="", real margin=0,
+ string[] captions=new string[], string caption="",
+ pair align=S, pen p=itempen, pen figuremattpen=figuremattpen,
+ bool final=true)
+{
+ string[] S;
+ for(int i=0; i < s.length; ++i) {
+ S[i]=graphic(s[i],options);
+ }
+
+ display(S,margin,captions,caption,align,itempen,figuremattpen,final);
+}
+
+void figure(string s, string options="", string caption="", pair align=S,
+ pen p=itempen, pen figuremattpen=figuremattpen, bool final=true)
+{
+ figure(new string[] {s},options,caption,align,p,figuremattpen,final);
+}
+
+void multifigure(string[] slist, string options="", string caption="",
+ pair align=S, pen p=itempen, pen figuremattpen=figuremattpen,
+ bool step=itemstep)
+{
+ if(step) {
+ int lastnode=currentpicture.nodes.length-1;
+ for (int i=0; i<slist.length-1; ++i) {
+ figure(slist[i],options,caption,align,p,figuremattpen,final=false);
+ erasestep(lastnode);
+ }
+ }
+ figure(slist[slist.length-1],options,caption,align,p,figuremattpen,final=true);
+
+ if(!firststep) step();
+ firststep=false;
+}
+
+void indexedfigure(string prefix, int first, int last,
+ string options="", string caption="",
+ pair align=S, pen p=itempen, pen figuremattpen=figuremattpen,
+ bool step=itemstep)
+{
+ bool Stepping=stepping;
+ stepping=true;
+ string[] s;
+ for(int i=first; i <= last; ++i)
+ s.push(prefix+string(i));
+ multifigure(s,options,caption,align,p,figuremattpen,step=step);
+ stepping=Stepping;
+}
+
+string[] codefile;
+
+void asyinclude(string s, real xsize=0, real ysize=xsize)
+{
+ picture currentpictureSave=currentpicture;
+ currentpicture=new picture;
+ _eval("include \""+s+"\";",true);
+ s=stripdirectory(outprefix()+"_"+s);
+ codefile.push(s);
+ frame f=(xsize > 0 || ysize > 0) ?
+ currentpicture.fit(xsize,ysize) : currentpicture.fit();
+ currentpicture=currentpictureSave;
+ display(f);
+}
+
+string cropcode(string s)
+{
+ while(substr(s,0,1) == '\n') s=substr(s,1,length(s));
+ while(substr(s,length(s)-1,1) == '\n') s=substr(s,0,length(s)-1);
+ return s;
+}
+
+void code(bool center=false, string s, pen p=codepen,
+ real indent=0, real skip=codeskip,
+ filltype filltype=NoFill)
+{
+ remark(center,"{\tt "+verbatim(cropcode(s))+"}",p,indent,skip,filltype);
+}
+
+void filecode(bool center=false, string s, pen p=codepen, real indent=0,
+ real skip=codeskip, filltype filltype=NoFill)
+{
+ code(center,file(s),p,indent,skip,filltype);
+}
+
+void asyfigure(string s, string options="", string caption="", pair align=S,
+ pen p=codepen, pen figuremattpen=figuremattpen,
+ filltype filltype=NoFill, bool newslide=false)
+{
+ string a=s+".asy";
+ asy(nativeformat(),s);
+ s += "."+nativeformat();
+ if(newslide && !empty()) {
+ newslide();
+ currentposition=(currentposition.x,0);
+ align=0;
+ }
+ figure(s,options,caption,align,p,figuremattpen);
+}
+
+string asywrite(string s, string preamble="")
+{
+ static int count=0;
+ string name=outprefix()+"_slide"+(string) count;
+ ++count;
+ file temp=output(name+".asy");
+ write(temp,preamble);
+ write(temp,s);
+ close(temp);
+ codefile.push(name);
+ return name;
+}
+
+void asycode(bool center=false, string s, string options="",
+ string caption="", string preamble="",
+ pair align=S, pen p=codepen, pen figuremattpen=figuremattpen,
+ real indent=0, real skip=codeskip,
+ filltype filltype=NoFill, bool newslide=false)
+{
+ code(center,s,p,indent,skip,filltype);
+ asyfigure(asywrite(s,preamble),options,caption,align,p,figuremattpen,filltype,
+ newslide);
+}
+
+void asyfilecode(bool center=false, string s, string options="",
+ string caption="",
+ pair align=S, pen p=codepen, pen figuremattpen=figuremattpen,
+ real indent=0, real skip=codeskip,
+ filltype filltype=NoFill, bool newslide=false)
+{
+ filecode(center,s+".asy",p,indent,skip,filltype);
+ asyfigure(s,options,caption,align,p,figuremattpen,filltype,newslide);
+}
+
+void item(string s, pen p=itempen, bool step=itemstep)
+{
+ frame b;
+ label(b,bullet,(0,0),p);
+ real bulletwidth=max(b).x-min(b).x;
+ remark(bullet+"\hangindent"+(string) (bulletwidth/pt)+"pt$\,$"+s,p,
+ -bulletwidth,step=step);
+}
+
+void subitem(string s, pen p=itempen)
+{
+ remark("\quad -- "+s,p);
+}
+
+void titlepage(string title, string author, string institution="",
+ string date="", string url="", bool newslide=false)
+{
+ newslide();
+ currentposition=titlepageposition;
+ center(title,titlepagepen);
+ center(author,authorpen);
+ if(institution != "") center(institution,institutionpen);
+ currentposition -= dateskip;
+ if(date != "") center(date,datepen);
+ currentposition -= urlskip;
+ if(url != "") center("{\tt "+url+"}",urlpen);
+}
+
+// Resolve optional bibtex citations:
+void bibliographystyle(string name)
+{
+ settings.twice=true;
+ settings.keepaux=true;
+ texpreamble("\bibliographystyle{"+name+"}");
+}
+
+void bibliography(string name)
+{
+ numberpage();
+ havepagenumber=false;
+ string s=texcolor(backgroundcolor);
+ if(s != "") tex("\definecolor{Background}"+s+"\pagecolor{Background}%");
+ label("",itempen);
+ tex("\eject\def\refname{\fontsize{"+string(fontsize(titlepen))+"}{"+
+ string(lineskip(titlepen))+"}\selectfont References}%");
+ real hmargin,vmargin;
+ if(pdf()) {
+ hmargin=1;
+ vmargin=0;
+ } else {
+ hmargin=1.5;
+ vmargin=1;
+ }
+ string s;
+ if(landscape) {
+ s="{\centering\textheight="+string(pageheight-1inch)+"bp\textwidth="+
+ string(pagewidth-1.5inches)+"bp"+
+ "\vsize=\textheight\hsize=\textwidth\linewidth=\hsize"+
+ "\topmargin="+string(vmargin)+"in\oddsidemargin="+string(hmargin)+"in";
+ } else
+ s="{\centering\textheight="+string(pageheight-0.5inches)+"bp\textwidth="+
+ string(pagewidth-0.5inches)+
+ "bp\hsize=\textwidth\linewidth=\textwidth\vsize=\textheight"+
+ "\topmargin=0.5in\oddsidemargin=1in";
+ s += "\evensidemargin=\oddsidemargin\bibliography{"+name+"}\eject}";
+ tex(s);
+}
+
+exitfcn currentexitfunction=atexit();
+
+void exitfunction()
+{
+ numberpage();
+ if(currentexitfunction != null) currentexitfunction();
+ if(!settings.keep)
+ for(int i=0; i < codefile.length; ++i) {
+ string name=codefile[i];
+ delete(name+"."+nativeformat());
+ delete(name+"_.aux");
+ delete(name+".asy");
+ }
+ codefile=new string[];
+}
+
+atexit(exitfunction);
diff --git a/graphics/asymptote/base/slopefield.asy b/graphics/asymptote/base/slopefield.asy
new file mode 100644
index 0000000000..bdbb025267
--- /dev/null
+++ b/graphics/asymptote/base/slopefield.asy
@@ -0,0 +1,87 @@
+import graph_settings;
+real stepfraction=0.05;
+
+picture slopefield(real f(real,real), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ real tickfactor=0.5, pen p=currentpen, arrowbar arrow=None)
+{
+ picture pic;
+ real dx=(b.x-a.x)/nx;
+ real dy=(b.y-a.y)/ny;
+ real step=0.5*tickfactor*min(dx,dy);
+
+ for(int i=0; i <= nx; ++i) {
+ real x=a.x+i*dx;
+ for(int j=0; j <= ny; ++j) {
+ pair cp=(x,a.y+j*dy);
+ real slope=f(cp.x,cp.y);
+ real mp=step/sqrt(1+slope^2);
+ draw(pic,(cp.x-mp,cp.y-mp*slope)--(cp.x+mp,cp.y+mp*slope),p,arrow);
+ }
+ }
+ clip(pic,box(a,b));
+ return pic;
+}
+
+picture slopefield(real f(real), pair a, pair b,
+ int nx=nmesh, int ny=nx, pen p=currentpen,
+ arrowbar arrow=None)
+{
+ return slopefield(new real(real x, real y) {return f(x);},a,b,nx,ny,p,arrow);
+}
+
+path curve(pair c, real f(real,real), pair a, pair b)
+{
+ real step=stepfraction*(b.x-a.x);
+ real halfstep=0.5*step;
+ real sixthstep=step/6;
+
+ path follow(real sign) {
+ pair cp=c;
+ guide g=cp;
+ real dx,dy;
+ real factor=1;
+ do {
+ real slope;
+ pair S(pair z) {
+ slope=f(z.x,z.y);
+ return factor*sign/sqrt(1+slope^2)*(1,slope);
+ }
+ pair S3;
+ pair advance() {
+ pair S0=S(cp);
+ pair S1=S(cp+halfstep*S0);
+ pair S2=S(cp+halfstep*S1);
+ S3=S(cp+step*S2);
+ pair cp0=cp+sixthstep*(S0+2S1+2S2+S3);
+ dx=min(cp0.x-a.x,b.x-cp0.x);
+ dy=min(cp0.y-a.y,b.y-cp0.y);
+ return cp0;
+ }
+ pair cp0=advance();
+ if(dx < 0) {
+ factor=(step+dx)/step;
+ cp0=advance();
+ g=g..{S3}cp0{S3};
+ break;
+ }
+ if(dy < 0) {
+ factor=(step+dy)/step;
+ cp0=advance();
+ g=g..{S3}cp0{S3};
+ break;
+ }
+ cp=cp0;
+ g=g..{S3}cp{S3};
+ } while (dx > 0 && dy > 0);
+ return g;
+ }
+
+ return reverse(follow(-1))&follow(1);
+}
+
+path curve(pair c, real f(real), pair a, pair b)
+{
+ return curve(c,new real(real x, real y){return f(x);},a,b);
+}
+
diff --git a/graphics/asymptote/base/smoothcontour3.asy b/graphics/asymptote/base/smoothcontour3.asy
new file mode 100644
index 0000000000..be6f900a4d
--- /dev/null
+++ b/graphics/asymptote/base/smoothcontour3.asy
@@ -0,0 +1,1582 @@
+// Copyright 2015 Charles Staats III
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// smoothcontour3
+// An Asymptote module for drawing smooth implicitly defined surfaces
+// author: Charles Staats III
+// charles dot staats dot iii at gmail dot com
+
+import graph_settings; // for nmesh
+import three;
+import math;
+
+/***********************************************/
+/******** CREATING BEZIER PATCHES **************/
+/******** WITH SPECIFIED NORMALS **************/
+/***********************************************/
+
+// The weight given to minimizing the sum of squares of
+// the mixed partials at the corners of the bezier patch.
+// If this weight is zero, the result is undefined in
+// places and can be rather wild even where it is
+// defined.
+// The struct is used to as a namespace.
+struct pathwithnormals_settings {
+ static real wildnessweight = 1e-3;
+}
+private from pathwithnormals_settings unravel wildnessweight;
+
+// The Bernstein basis polynomials of degree 3:
+real B03(real t) { return (1-t)^3; }
+real B13(real t) { return 3*t*(1-t)^2; }
+real B23(real t) { return 3*t^2*(1-t); }
+real B33(real t) { return t^3; }
+
+private typedef real function(real);
+function[] bernstein = new function[] {B03, B13, B23, B33};
+
+// This function attempts to produce a Bezier patch
+// with the specified boundary path and normal directions.
+// For instance, the patch should be normal to
+// u0normals[0] at (0, 0.25),
+// normal to u0normals[1] at (0, 0.5), and
+// normal to u0normals[2] at (0, 0.75).
+// The actual normal (as computed by the patch.normal() function)
+// may be parallel to the specified normal, antiparallel, or
+// even zero.
+//
+// A small amount of deviation is allowed in order to stabilize
+// the algorithm (by keeping the mixed partials at the corners from
+// growing too large).
+//
+// Note that the specified normals are projected to be orthogonal to
+// the specified boundary path. However, the entries in the array
+// remain intact.
+patch patchwithnormals(path3 external, triple[] u0normals, triple[] u1normals,
+ triple[] v0normals, triple[] v1normals)
+{
+ assert(cyclic(external));
+ assert(length(external) == 4);
+ assert(u0normals.length == 3);
+ assert(u1normals.length == 3);
+ assert(v0normals.length == 3);
+ assert(v1normals.length == 3);
+
+ triple[][] controlpoints = new triple[4][4];
+ controlpoints[0][0] = point(external,0);
+ controlpoints[1][0] = postcontrol(external,0);
+ controlpoints[2][0] = precontrol(external,1);
+ controlpoints[3][0] = point(external,1);
+ controlpoints[3][1] = postcontrol(external,1);
+ controlpoints[3][2] = precontrol(external,2);
+ controlpoints[3][3] = point(external,2);
+ controlpoints[2][3] = postcontrol(external,2);
+ controlpoints[1][3] = precontrol(external,3);
+ controlpoints[0][3] = point(external,3);
+ controlpoints[0][2] = postcontrol(external,3);
+ controlpoints[0][1] = precontrol(external, 4);
+
+ real[][] matrix = new real[24][12];
+ for (int i = 0; i < matrix.length; ++i)
+ for (int j = 0; j < matrix[i].length; ++j)
+ matrix[i][j] = 0;
+ real[] rightvector = new real[24];
+ for (int i = 0; i < rightvector.length; ++i)
+ rightvector[i] = 0;
+
+ void addtocoeff(int i, int j, int count, triple coeffs) {
+ if (1 <= i && i <= 2 && 1 <= j && j <= 2) {
+ int position = 3 * (2 * (i-1) + (j-1));
+ matrix[count][position] += coeffs.x;
+ matrix[count][position+1] += coeffs.y;
+ matrix[count][position+2] += coeffs.z;
+ } else {
+ rightvector[count] -= dot(controlpoints[i][j], coeffs);
+ }
+ }
+
+ void addtocoeff(int i, int j, int count, real coeff) {
+ if (1 <= i && i <= 2 && 1 <= j && j <= 2) {
+ int position = 3 * (2 * (i-1) + (j-1));
+ matrix[count][position] += coeff;
+ matrix[count+1][position+1] += coeff;
+ matrix[count+2][position+2] += coeff;
+ } else {
+ rightvector[count] -= controlpoints[i][j].x * coeff;
+ rightvector[count+1] -= controlpoints[i][j].y * coeff;
+ rightvector[count+2] -= controlpoints[i][j].z * coeff;
+ }
+ }
+
+ int count = 0;
+
+ void apply_u0(int j, real a, triple n) {
+ real factor = 3 * bernstein[j](a);
+ addtocoeff(0,j,count,-factor*n);
+ addtocoeff(1,j,count,factor*n);
+ }
+ void apply_u0(real a, triple n) {
+ triple tangent = dir(external, 4-a);
+ n -= dot(n,tangent)*tangent;
+ n = unit(n);
+ for (int j = 0; j < 4; ++j) {
+ apply_u0(j,a,n);
+ }
+ ++count;
+ }
+ apply_u0(0.25, u0normals[0]);
+ apply_u0(0.5, u0normals[1]);
+ apply_u0(0.75, u0normals[2]);
+
+ void apply_u1(int j, real a, triple n) {
+ real factor = 3 * bernstein[j](a);
+ addtocoeff(3,j,count,factor*n);
+ addtocoeff(2,j,count,-factor*n);
+ }
+ void apply_u1(real a, triple n) {
+ triple tangent = dir(external, 1+a);
+ n -= dot(n,tangent)*tangent;
+ n = unit(n);
+ for (int j = 0; j < 4; ++j)
+ apply_u1(j,a,n);
+ ++count;
+ }
+ apply_u1(0.25, u1normals[0]);
+ apply_u1(0.5, u1normals[1]);
+ apply_u1(0.75, u1normals[2]);
+
+ void apply_v0(int i, real a, triple n) {
+ real factor = 3 * bernstein[i](a);
+ addtocoeff(i,0,count,-factor*n);
+ addtocoeff(i,1,count,factor*n);
+ }
+ void apply_v0(real a, triple n) {
+ triple tangent = dir(external, a);
+ n -= dot(n,tangent) * tangent;
+ n = unit(n);
+ for (int i = 0; i < 4; ++i)
+ apply_v0(i,a,n);
+ ++count;
+ }
+ apply_v0(0.25, v0normals[0]);
+ apply_v0(0.5, v0normals[1]);
+ apply_v0(0.75, v0normals[2]);
+
+ void apply_v1(int i, real a, triple n) {
+ real factor = 3 * bernstein[i](a);
+ addtocoeff(i,3,count,factor*n);
+ addtocoeff(i,2,count,-factor*n);
+ }
+ void apply_v1(real a, triple n) {
+ triple tangent = dir(external, 3-a);
+ n -= dot(n,tangent)*tangent;
+ n = unit(n);
+ for (int i = 0; i < 4; ++i)
+ apply_v1(i,a,n);
+ ++count;
+ }
+ apply_v1(0.25, v1normals[0]);
+ apply_v1(0.5, v1normals[1]);
+ apply_v1(0.75, v1normals[2]);
+
+ addtocoeff(0,0,count,9*wildnessweight);
+ addtocoeff(1,1,count,9*wildnessweight);
+ addtocoeff(0,1,count,-9*wildnessweight);
+ addtocoeff(1,0,count,-9*wildnessweight);
+ count+=3;
+ addtocoeff(3,3,count,9*wildnessweight);
+ addtocoeff(2,2,count,9*wildnessweight);
+ addtocoeff(3,2,count,-9*wildnessweight);
+ addtocoeff(2,3,count,-9*wildnessweight);
+ count+=3;
+ addtocoeff(0,3,count,9*wildnessweight);
+ addtocoeff(1,2,count,9*wildnessweight);
+ addtocoeff(1,3,count,-9*wildnessweight);
+ addtocoeff(0,2,count,-9*wildnessweight);
+ count += 3;
+ addtocoeff(3,0,count,9*wildnessweight);
+ addtocoeff(2,1,count,9*wildnessweight);
+ addtocoeff(3,1,count,-9*wildnessweight);
+ addtocoeff(2,0,count,-9*wildnessweight);
+ count += 3;
+
+ real[] solution = leastsquares(matrix, rightvector, warn=false);
+ if (solution.length == 0) { // if the matrix was singular
+ write("Warning: unable to solve matrix for specifying edge normals "
+ + "on bezier patch. Using coons patch.");
+ return patch(external);
+ }
+
+ for (int i = 1; i <= 2; ++i) {
+ for (int j = 1; j <= 2; ++j) {
+ int position = 3 * (2 * (i-1) + (j-1));
+ controlpoints[i][j] = (solution[position],
+ solution[position+1],
+ solution[position+2]);
+ }
+ }
+
+ return patch(controlpoints);
+}
+
+// This function attempts to produce a Bezier triangle
+// with the specified boundary path and normal directions at the
+// edge midpoints. The bezier triangle should be normal to
+// n1 at point(external, 0.5),
+// normal to n2 at point(external, 1.5), and
+// normal to n3 at point(external, 2.5).
+// The actual normal (as computed by the patch.normal() function)
+// may be parallel to the specified normal, antiparallel, or
+// even zero.
+//
+// A small amount of deviation is allowed in order to stabilize
+// the algorithm (by keeping the mixed partials at the corners from
+// growing too large).
+patch trianglewithnormals(path3 external, triple n1,
+ triple n2, triple n3) {
+ assert(cyclic(external));
+ assert(length(external) == 3);
+ // Use the formal symbols a3, a2b, abc, etc. to denote the control points,
+ // following the Wikipedia article on Bezier triangles.
+ triple a3 = point(external, 0), a2b = postcontrol(external, 0),
+ ab2 = precontrol(external, 1), b3 = point(external, 1),
+ b2c = postcontrol(external, 1), bc2 = precontrol(external, 2),
+ c3 = point(external, 2), ac2 = postcontrol(external, 2),
+ a2c = precontrol(external, 0);
+
+ // Use orthogonal projection to ensure that the normal vectors are
+ // actually normal to the boundary path.
+ triple tangent = dir(external, 0.5);
+ n1 -= dot(n1,tangent)*tangent;
+ n1 = unit(n1);
+
+ tangent = dir(external, 1.5);
+ n2 -= dot(n2,tangent)*tangent;
+ n2 = unit(n2);
+
+ tangent = dir(external, 2.5);
+ n3 -= dot(n3,tangent)*tangent;
+ n3 = unit(n3);
+
+ real wild = 2 * wildnessweight;
+ real[][] matrix = { {n1.x, n1.y, n1.z},
+ {n2.x, n2.y, n2.z},
+ {n3.x, n3.y, n3.z},
+ { wild, 0, 0},
+ { 0, wild, 0},
+ { 0, 0, wild} };
+ real[] rightvector =
+ { dot(n1, (a3 + 3a2b + 3ab2 + b3 - 2a2c - 2b2c)) / 4,
+ dot(n2, (b3 + 3b2c + 3bc2 + c3 - 2ab2 - 2ac2)) / 4,
+ dot(n3, (c3 + 3ac2 + 3a2c + a3 - 2bc2 - 2a2b)) / 4 };
+
+ // The inner control point that minimizes the sum of squares of
+ // the mixed partials on the corners.
+ triple tameinnercontrol =
+ ((a2b + a2c - a3) + (ab2 + b2c - b3) + (ac2 + bc2 - c3)) / 3;
+ rightvector.append(wild * new real[]
+ {tameinnercontrol.x, tameinnercontrol.y, tameinnercontrol.z});
+ real[] solution = leastsquares(matrix, rightvector, warn=false);
+ if (solution.length == 0) { // if the matrix was singular
+ write("Warning: unable to solve matrix for specifying edge normals "
+ + "on bezier triangle. Using coons triangle.");
+ return patch(external);
+ }
+ triple innercontrol = (solution[0], solution[1], solution[2]);
+ return patch(external, innercontrol);
+}
+
+// A wrapper for the previous functions when the normal direction
+// is given as a function of direction. The wrapper can also
+// accommodate cyclic boundary paths of between one and four
+// segments, although the results are best by far when there
+// are three or four segments.
+patch patchwithnormals(path3 external, triple normalat(triple)) {
+ assert(cyclic(external));
+ assert(1 <= length(external) && length(external) <= 4);
+ if (length(external) == 3) {
+ triple n1 = normalat(point(external, 0.5));
+ triple n2 = normalat(point(external, 1.5));
+ triple n3 = normalat(point(external, 2.5));
+ return trianglewithnormals(external, n1, n2, n3);
+ }
+ while (length(external) < 4) external = external -- cycle;
+ triple[] u0normals = new triple[3];
+ triple[] u1normals = new triple[3];
+ triple[] v0normals = new triple[3];
+ triple[] v1normals = new triple[3];
+ for (int i = 1; i <= 3; ++i) {
+ v0normals[i-1] = unit(normalat(point(external, i/4)));
+ u1normals[i-1] = unit(normalat(point(external, 1 + i/4)));
+ v1normals[i-1] = unit(normalat(point(external, 3 - i/4)));
+ u0normals[i-1] = unit(normalat(point(external, 4 - i/4)));
+ }
+ return patchwithnormals(external, u0normals, u1normals, v0normals, v1normals);
+}
+
+/***********************************************/
+/********* DUAL CUBE GRAPH UTILITY *************/
+/***********************************************/
+
+// Suppose a plane intersects a (hollow) cube, and
+// does not intersect any vertices. Then its intersection
+// with cube forms a cycle. The goal of the code below
+// is to reconstruct the order of the cycle
+// given only an unordered list of which edges the plane
+// intersects.
+//
+// Basically, the question is this: If we know the points
+// in which a more-or-less planar surface intersects the
+// edges of cube, how do we connect those points?
+//
+// When I wrote the code, I was thinking in terms of the
+// dual graph of a cube, in which "vertices" are really
+// faces of the cube and "edges" connect those "vertices."
+
+// An enum for the different "vertices" (i.e. faces)
+// available. NULL_VERTEX is primarily intended as a
+// return value to indicate the absence of a desired
+// vertex.
+private int NULL_VERTEX = -1;
+private int XHIGH = 0;
+private int XLOW = 1;
+private int YHIGH = 2;
+private int YLOW = 3;
+private int ZHIGH = 4;
+private int ZLOW = 5;
+
+// An unordered set of nonnegative integers.
+// Since the intent is to use
+// only the six values from the enum above, no effort
+// was made to use scalable algorithms.
+struct intset {
+ private bool[] ints = new bool[0];
+ private int size = 0;
+
+ bool contains(int item) {
+ assert(item >= 0);
+ if (item >= ints.length) return false;
+ return ints[item];
+ }
+
+ // Returns true if the item was added (i.e., was
+ // not already present).
+ bool add(int item) {
+ assert(item >= 0);
+ while (item >= ints.length) ints.push(false);
+ if (ints[item]) return false;
+ ints[item] = true;
+ ++size;
+ return true;
+ }
+
+ int[] elements() {
+ int[] toreturn;
+ for (int i = 0; i < ints.length; ++i) {
+ if (ints[i]) toreturn.push(i);
+ }
+ return toreturn;
+ }
+
+ int size() { return size; }
+}
+
+// A map from integers to sets of integers. Again, no
+// attempt is made to use scalable data structures.
+struct int_to_intset {
+ int[] keys = new int[0];
+ intset[] values = new intset[0];
+
+ void add(int key, int value) {
+ for (int i = 0; i < keys.length; ++i) {
+ if (keys[i] == key) {
+ values[i].add(value);
+ return;
+ }
+ }
+ keys.push(key);
+ intset newset;
+ values.push(newset);
+ newset.add(value);
+ }
+
+ private int indexOf(int key) {
+ for (int i = 0; i < keys.length; ++i) {
+ if (keys[i] == key) return i;
+ }
+ return -1;
+ }
+
+ int[] get(int key) {
+ int i = indexOf(key);
+ if (i < 0) return new int[0];
+ else return values[i].elements();
+ }
+
+ int numvalues(int key) {
+ int i = indexOf(key);
+ if (i < 0) return 0;
+ else return values[i].size();
+ }
+
+ int numkeys() {
+ return keys.length;
+ }
+}
+
+// A struct intended to represent an undirected edge between
+// two "vertices."
+struct edge {
+ int start;
+ int end;
+ void operator init(int a, int b) {
+ start = a;
+ end = b;
+ }
+ bool bordersvertex(int v) { return start == v || end == v; }
+}
+
+string operator cast(edge e) {
+ int a, b;
+ if (e.start <= e.end) {a = e.start; b = e.end;}
+ else {a = e.end; b = e.start; }
+ return (string)a + " <-> " + (string)b;
+}
+
+bool operator == (edge a, edge b) {
+ if (a.start == b.start && a.end == b.end) return true;
+ if (a.start == b.end && a.end == b.start) return true;
+ return false;
+}
+
+string operator cast(edge[] edges) {
+ string toreturn = "{ ";
+ for (int i = 0; i < edges.length; ++i) {
+ toreturn += edges[i];
+ if (i < edges.length-1) toreturn += ", ";
+ }
+ return toreturn + " }";
+}
+
+// Finally, the function that strings together a list of edges
+// into a cycle. It makes assumptions that hold true if the
+// list of edges did in fact come from a plane intersection
+// containing no vertices of the cube. For instance, such a
+// plane can contain at most two noncollinear points of any
+// one face; consequently, no face can border more than two of
+// the selected edges.
+//
+// If the underlying assumptions prove to be false, the function
+// returns null.
+int[] makecircle(edge[] edges) {
+ if (edges.length == 0) return new int[0];
+ int_to_intset graph;
+ for (edge e : edges) {
+ graph.add(e.start, e.end);
+ graph.add(e.end, e.start);
+ }
+ int currentvertex = edges[0].start;
+ int startvertex = currentvertex;
+ int lastvertex = NULL_VERTEX;
+ int[] toreturn = new int[0];
+ do {
+ toreturn.push(currentvertex);
+ int[] adjacentvertices = graph.get(currentvertex);
+ if (adjacentvertices.length != 2) return null;
+ for (int v : adjacentvertices) {
+ if (v != lastvertex) {
+ lastvertex = currentvertex;
+ currentvertex = v;
+ break;
+ }
+ }
+ } while (currentvertex != startvertex);
+ if (toreturn.length != graph.numkeys()) return null;
+ toreturn.cyclic = true;
+ return toreturn;
+}
+
+/***********************************************/
+/********** PATHS BETWEEN POINTS ***************/
+/***********************************************/
+// Construct paths between two points with additional
+// constraints; for instance, the path must be orthogonal
+// to a certain vector at each of the endpoints, must
+// lie within a specified plane or a specified face
+// of a rectangular solid,....
+
+// A vector (typically a normal vector) at a specified position.
+struct positionedvector {
+ triple position;
+ triple direction;
+ void operator init(triple position, triple direction) {
+ this.position = position;
+ this.direction = direction;
+ }
+}
+
+string operator cast(positionedvector vv) {
+ return "position: " + (string)(vv.position) + " vector: " + (string)vv.direction;
+}
+
+// The angle, in degrees, between two vectors.
+real angledegrees(triple a, triple b) {
+ real dotprod = dot(a,b);
+ real lengthprod = max(abs(a) * abs(b), abs(dotprod));
+ if (lengthprod == 0) return 0;
+ return aCos(dotprod / lengthprod);
+}
+
+// A path (single curved segment) between two points. At each point
+// is specified a vector orthogonal to the path.
+path3 pathbetween(positionedvector v1, positionedvector v2) {
+ triple n1 = unit(v1.direction);
+ triple n2 = unit(v2.direction);
+
+ triple p1 = v1.position;
+ triple p2 = v2.position;
+ triple delta = p2-p1;
+
+ triple dir1 = delta - dot(delta, n1)*n1;
+ triple dir2 = delta - dot(delta, n2)*n2;
+ return p1 {dir1} .. {dir2} p2;
+}
+
+// Assuming v1 and v2 are linearly independent, returns an array {a, b}
+// such that a v1 + b v2 is the orthogonal projection of toproject onto
+// the span of v1 and v2. If v1 and v2 are dependent, returns an empty array
+// (if warn==false) or throws an error (if warn==true).
+real[] projecttospan_findcoeffs(triple toproject, triple v1, triple v2,
+ bool warn=false) {
+ real[][] matrix = {{v1.x, v2.x},
+ {v1.y, v2.y},
+ {v1.z, v2.z}};
+ real[] desiredanswer = {toproject.x, toproject.y, toproject.z};
+ return leastsquares(matrix, desiredanswer, warn=warn);
+}
+
+// Project the triple toproject into the span of a and b, but restrict
+// to the quarter-plane of linear combinations a v1 + b v2 such that
+// a >= mincoeff and b >= mincoeff. If v1 and v2 are linearly dependent,
+// return a random (positive) linear combination.
+triple projecttospan(triple toproject, triple v1, triple v2,
+ real mincoeff = 0.05) {
+ real[] coeffs = projecttospan_findcoeffs(toproject, v1, v2, warn=false);
+ real a, b;
+ if (coeffs.length == 0) {
+ a = mincoeff + unitrand();
+ b = mincoeff + unitrand();
+ } else {
+ a = max(coeffs[0], mincoeff);
+ b = max(coeffs[1], mincoeff);
+ }
+ return a*v1 + b*v2;
+}
+
+// A path between two specified vertices of a cyclic path. The
+// path tangent at each endpoint is guaranteed to lie within the
+// quarter-plane spanned by positive linear combinations of the
+// tangents of the two outgoing paths at that endpoint.
+path3 pathbetween(path3 edgecycle, int vertex1, int vertex2) {
+ triple point1 = point(edgecycle, vertex1);
+ triple point2 = point(edgecycle, vertex2);
+
+ triple v1 = -dir(edgecycle, vertex1, sign=-1);
+ triple v2 = dir(edgecycle, vertex1, sign= 1);
+ triple direction1 = projecttospan(unit(point2-point1), v1, v2);
+
+ v1 = -dir(edgecycle, vertex2, sign=-1);
+ v2 = dir(edgecycle, vertex2, sign= 1);
+ triple direction2 = projecttospan(unit(point1-point2), v1, v2);
+
+ return point1 {direction1} .. {-direction2} point2;
+}
+
+// This function applies a heuristic to choose two "opposite"
+// vertices (separated by three segments) of edgecycle, which
+// is required to be a cyclic path consisting of 5 or 6 segments.
+// The two chosen vertices are pushed to savevertices.
+//
+// The function returns a path between the two chosen vertices. The
+// path tangent at each endpoint is guaranteed to lie within the
+// quarter-plane spanned by positive linear combinations of the
+// tangents of the two outgoing paths at that endpoint.
+path3 bisector(path3 edgecycle, int[] savevertices) {
+ real mincoeff = 0.05;
+ assert(cyclic(edgecycle));
+ int n = length(edgecycle);
+ assert(n >= 5 && n <= 6);
+ triple[] forwarddirections = sequence(new triple(int i) {
+ return dir(edgecycle, i, sign=1);
+ }, n);
+ forwarddirections.cyclic = true;
+ triple[] backwarddirections = sequence(new triple(int i) {
+ return -dir(edgecycle, i, sign=-1);
+ }, n);
+ backwarddirections.cyclic = true;
+ real[] angles = sequence(new real(int i) {
+ return angledegrees(forwarddirections[i], backwarddirections[i]);
+ }, n);
+ angles.cyclic = true;
+ int lastindex = (n == 5 ? 4 : 2);
+ real maxgoodness = 0;
+ int chosenindex = -1;
+ triple directionout, directionin;
+ for (int i = 0; i <= lastindex; ++i) {
+ int opposite = i + 3;
+ triple vec = unit(point(edgecycle, opposite) - point(edgecycle, i));
+ real[] coeffsbegin = projecttospan_findcoeffs(vec, forwarddirections[i],
+ backwarddirections[i]);
+ if (coeffsbegin.length == 0) continue;
+ coeffsbegin[0] = max(coeffsbegin[0], mincoeff);
+ coeffsbegin[1] = max(coeffsbegin[1], mincoeff);
+
+ real[] coeffsend = projecttospan_findcoeffs(-vec, forwarddirections[opposite],
+ backwarddirections[opposite]);
+ if (coeffsend.length == 0) continue;
+ coeffsend[0] = max(coeffsend[0], mincoeff);
+ coeffsend[1] = max(coeffsend[1], mincoeff);
+
+ real goodness = angles[i] * angles[opposite] * coeffsbegin[0] * coeffsend[0]
+ * coeffsbegin[1] * coeffsend[1];
+ if (goodness > maxgoodness) {
+ maxgoodness = goodness;
+ directionout = coeffsbegin[0] * forwarddirections[i] +
+ coeffsbegin[1] * backwarddirections[i];
+ directionin = -(coeffsend[0] * forwarddirections[opposite] +
+ coeffsend[1] * backwarddirections[opposite]);
+ chosenindex = i;
+ }
+ }
+ if (chosenindex == -1) {
+ savevertices.push(0);
+ savevertices.push(3);
+ return pathbetween(edgecycle, 0, 3);
+ } else {
+ savevertices.push(chosenindex);
+ savevertices.push(chosenindex+3);
+ return point(edgecycle, chosenindex) {directionout} ..
+ {directionin} point(edgecycle, chosenindex + 3);
+ }
+}
+
+// A path between two specified points (with specified normals) that lies
+// within a specified face of a rectangular solid.
+path3 pathinface(positionedvector v1, positionedvector v2,
+ triple facenorm, triple edge1normout, triple edge2normout)
+{
+ triple dir1 = cross(v1.direction, facenorm);
+ real dotprod = dot(dir1, edge1normout);
+ if (dotprod > 0) dir1 = -dir1;
+ // Believe it or not, this "tiebreaker" is actually relevant at times,
+ // for instance, when graphing the cone x^2 + y^2 = z^2 over the region
+ // -1 <= x,y,z <= 1.
+ else if (dotprod == 0 && dot(dir1, v2.position - v1.position) < 0) dir1 = -dir1;
+
+ triple dir2 = cross(v2.direction, facenorm);
+ dotprod = dot(dir2, edge2normout);
+ if (dotprod < 0) dir2 = -dir2;
+ else if (dotprod == 0 && dot(dir2, v2.position - v1.position) < 0) dir2 = -dir2;
+
+ return v1.position {dir1} .. {dir2} v2.position;
+}
+
+triple normalout(int face) {
+ if (face == XHIGH) return X;
+ else if (face == YHIGH) return Y;
+ else if (face == ZHIGH) return Z;
+ else if (face == XLOW) return -X;
+ else if (face == YLOW) return -Y;
+ else if (face == ZLOW) return -Z;
+ else return O;
+}
+
+// A path between two specified points (with specified normals) that lies
+// within a specified face of a rectangular solid.
+path3 pathinface(positionedvector v1, positionedvector v2,
+ int face, int edge1face, int edge2face) {
+ return pathinface(v1, v2, normalout(face), normalout(edge1face),
+ normalout(edge2face));
+}
+
+/***********************************************/
+/******** DRAWING IMPLICIT SURFACES ************/
+/***********************************************/
+
+// DEPRECATED
+// Quadrilateralization:
+// Produce a surface (array of *nondegenerate* Bezier patches) with a
+// specified three-segment boundary. The surface should approximate the
+// zero locus of the specified f with its specified gradient.
+//
+// If it is not possible to produce the desired result without leaving the
+// specified rectangular region, returns a length-zero array.
+//
+// Dividing a triangle into smaller quadrilaterals this way is opposite
+// the usual trend in mathematics. However, *before the introduction of bezier
+// triangles,* the pathwithnormals algorithm
+// did a poor job of choosing a good surface when the boundary path did
+// not consist of four positive-length segments.
+patch[] triangletoquads(path3 external, real f(triple), triple grad(triple),
+ triple a, triple b) {
+ static real epsilon = 1e-3;
+ assert(length(external) == 3);
+ assert(cyclic(external));
+
+ triple c0 = point(external, 0);
+ triple c1 = point(external, 1);
+ triple c2 = point(external, 2);
+
+ triple center = (c0 + c1 + c2) / 3;
+ triple n = unit(cross(c1-c0, c2-c0));
+
+ real g(real t) { return f(center + t*n); }
+
+ real tmin = -realMax, tmax = realMax;
+ void absorb(real t) {
+ if (t < 0) tmin = max(t,tmin);
+ else tmax = min(t,tmax);
+ }
+ if (n.x != 0) {
+ absorb((a.x - center.x) / n.x);
+ absorb((b.x - center.x) / n.x);
+ }
+ if (n.y != 0) {
+ absorb((a.y - center.y) / n.y);
+ absorb((b.y - center.y) / n.y);
+ }
+ if (n.z != 0) {
+ absorb((a.z - center.z) / n.z);
+ absorb((b.z - center.z) / n.z);
+ }
+
+ real fa = g(tmin);
+ real fb = g(tmax);
+ if ((fa > 0 && fb > 0) || (fa < 0 && fb < 0)) {
+ return new patch[0];
+ } else {
+ real t = findroot(g, tmin, tmax, fa=fa, fb=fb);
+ center += t * n;
+ }
+
+ n = unit(grad(center));
+
+ triple m0 = point(external, 0.5);
+ positionedvector m0 = positionedvector(m0, unit(grad(m0)));
+ triple m1 = point(external, 1.5);
+ positionedvector m1 = positionedvector(m1, unit(grad(m1)));
+ triple m2 = point(external, 2.5);
+ positionedvector m2 = positionedvector(m2, unit(grad(m2)));
+ positionedvector c = positionedvector(center, unit(grad(center)));
+
+ path3 pathto_m0 = pathbetween(c, m0);
+ path3 pathto_m1 = pathbetween(c, m1);
+ path3 pathto_m2 = pathbetween(c, m2);
+
+ path3 quad0 = subpath(external, 0, 0.5)
+ & reverse(pathto_m0)
+ & pathto_m2
+ & subpath(external, -0.5, 0)
+ & cycle;
+ path3 quad1 = subpath(external, 1, 1.5)
+ & reverse(pathto_m1)
+ & pathto_m0
+ & subpath(external, 0.5, 1)
+ & cycle;
+ path3 quad2 = subpath(external, 2, 2.5)
+ & reverse(pathto_m2)
+ & pathto_m1
+ & subpath(external, 1.5, 2)
+ & cycle;
+
+ return new patch[] {patchwithnormals(quad0, grad),
+ patchwithnormals(quad1, grad),
+ patchwithnormals(quad2, grad)};
+}
+
+// Attempts to fill the path external (which should by a cyclic path consisting of
+// three segments) with bezier triangle(s). Returns an empty array if it fails.
+//
+// In more detail: A single bezier triangle is computed using trianglewithnormals. The normals of
+// the resulting triangle at the midpoint of each edge are computed. If any of these normals
+// is in the negative f direction, the external triangle is subdivided into four external triangles
+// and the same procedure is applied to each. If one or more of them has an incorrectly oriented
+// edge normal, the function gives up and returns an empty array.
+//
+// Thus, the returned array consists of 0, 1, or 4 bezier triangles; no other array lengths
+// are possible.
+//
+// This function assumes that the path orientation is consistent with f (and its gradient)
+// -- i.e., that
+// at a corner, (tangent in) x (tangent out) is in the positive f direction.
+patch[] maketriangle(path3 external, real f(triple),
+ triple grad(triple), bool allowsubdivide = true) {
+ assert(cyclic(external));
+ assert(length(external) == 3);
+ triple m1 = point(external, 0.5);
+ triple n1 = unit(grad(m1));
+ triple m2 = point(external, 1.5);
+ triple n2 = unit(grad(m2));
+ triple m3 = point(external, 2.5);
+ triple n3 = unit(grad(m3));
+ patch beziertriangle = trianglewithnormals(external, n1, n2, n3);
+ if (dot(n1, beziertriangle.normal(0.5, 0)) >= 0 &&
+ dot(n2, beziertriangle.normal(0.5, 0.5)) >= 0 &&
+ dot(n3, beziertriangle.normal(0, 0.5)) >= 0)
+ return new patch[] {beziertriangle};
+
+ if (!allowsubdivide) return new patch[0];
+
+ positionedvector m1 = positionedvector(m1, n1);
+ positionedvector m2 = positionedvector(m2, n2);
+ positionedvector m3 = positionedvector(m3, n3);
+ path3 p12 = pathbetween(m1, m2);
+ path3 p23 = pathbetween(m2, m3);
+ path3 p31 = pathbetween(m3, m1);
+ patch[] triangles = maketriangle(p12 & p23 & p31 & cycle, f, grad=grad,
+ allowsubdivide=false);
+ if (triangles.length < 1) return new patch[0];
+
+ triangles.append(maketriangle(subpath(external, -0.5, 0.5) & reverse(p31) & cycle,
+ f, grad=grad, allowsubdivide=false));
+ if (triangles.length < 2) return new patch[0];
+
+ triangles.append(maketriangle(subpath(external, 0.5, 1.5) & reverse(p12) & cycle,
+ f, grad=grad, allowsubdivide=false));
+ if (triangles.length < 3) return new patch[0];
+
+ triangles.append(maketriangle(subpath(external, 1.5, 2.5) & reverse(p23) & cycle,
+ f, grad=grad, allowsubdivide=false));
+ if (triangles.length < 4) return new patch[0];
+
+ return triangles;
+}
+
+
+// Returns true if the point is "nonsingular" (in the sense that the magnitude
+// of the gradient is not too small) AND very close to the zero locus of f
+// (assuming f is locally linear).
+bool check_fpt_zero(triple testpoint, real f(triple), triple grad(triple)) {
+ real testval = f(testpoint);
+ real slope = abs(grad(testpoint));
+ static real tolerance = 2*rootfinder_settings.roottolerance;
+ return !(slope > tolerance && abs(testval) / slope > tolerance);
+}
+
+// Returns true if pt lies within the rectangular solid with
+// opposite corners at a and b.
+bool checkptincube(triple pt, triple a, triple b) {
+ real xmin = a.x;
+ real xmax = b.x;
+ real ymin = a.y;
+ real ymax = b.y;
+ real zmin = a.z;
+ real zmax = b.z;
+ if (xmin > xmax) { real t = xmax; xmax=xmin; xmin=t; }
+ if (ymin > ymax) { real t = ymax; ymax=ymin; ymin=t; }
+ if (zmin > zmax) { real t = zmax; zmax=zmin; zmin=t; }
+
+ return ((xmin <= pt.x) && (pt.x <= xmax) &&
+ (ymin <= pt.y) && (pt.y <= ymax) &&
+ (zmin <= pt.z) && (pt.z <= zmax));
+
+}
+
+// A convenience function for combining the previous two tests.
+bool checkpt(triple testpt, real f(triple), triple grad(triple),
+ triple a, triple b) {
+ return checkptincube(testpt, a, b) &&
+ check_fpt_zero(testpt, f, grad);
+}
+
+// Attempts to fill in the boundary cycle with a collection of
+// patches to approximate smoothly the zero locus of f. If unable to
+// do so while satisfying certain checks, returns null.
+// This is distinct from returning an empty
+// array, which merely indicates that the boundary cycle is too small
+// to be worth filling in.
+patch[] quadpatches(path3 edgecycle, positionedvector[] corners,
+ real f(triple), triple grad(triple),
+ triple a, triple b, bool usetriangles) {
+ assert(corners.cyclic);
+
+ // The tolerance for considering two points "essentially identical."
+ static real tolerance = 2.5 * rootfinder_settings.roottolerance;
+
+ // If there are two neighboring vertices that are essentially identical,
+ // unify them into one.
+ for (int i = 0; i < corners.length; ++i) {
+ if (abs(corners[i].position - corners[i+1].position) < tolerance) {
+ if (corners.length == 2) return new patch[0];
+ corners.delete(i);
+ edgecycle = subpath(edgecycle, 0, i)
+ & subpath(edgecycle, i+1, length(edgecycle))
+ & cycle;
+ --i;
+ assert(length(edgecycle) == corners.length);
+ }
+ }
+
+ static real areatolerance = tolerance^2;
+
+ assert(corners.length >= 2);
+ if (corners.length == 2) {
+ // If the area is too small, just ignore it; otherwise, subdivide.
+ real area0 = abs(cross(-dir(edgecycle, 0, sign=-1, normalize=false),
+ dir(edgecycle, 0, sign=1, normalize=false)));
+ real area1 = abs(cross(-dir(edgecycle, 1, sign=-1, normalize=false),
+ dir(edgecycle, 1, sign=1, normalize=false)));
+ if (area0 < areatolerance && area1 < areatolerance) return new patch[0];
+ else return null;
+ }
+ if (length(edgecycle) > 6) abort("too many edges: not possible.");
+
+ for (int i = 0; i < length(edgecycle); ++i) {
+ if (angledegrees(dir(edgecycle,i,sign=1),
+ dir(edgecycle,i+1,sign=-1)) > 80) {
+ return null;
+ }
+ }
+
+ if (length(edgecycle) == 3) {
+ patch[] toreturn = usetriangles ? maketriangle(edgecycle, f, grad)
+ : triangletoquads(edgecycle, f, grad, a, b);
+ if (toreturn.length == 0) return null;
+ else return toreturn;
+ }
+ if (length(edgecycle) == 4) {
+ return new patch[] {patchwithnormals(edgecycle, grad)};
+ }
+
+ int[] bisectorindices;
+ path3 middleguide = bisector(edgecycle, bisectorindices);
+
+ triple testpoint = point(middleguide, 0.5);
+ if (!checkpt(testpoint, f, grad, a, b)) {
+ return null;
+ }
+
+ patch[] toreturn = null;
+ path3 firstpatch = subpath(edgecycle, bisectorindices[0], bisectorindices[1])
+ & reverse(middleguide) & cycle;
+ if (length(edgecycle) == 5) {
+ path3 secondpatch = middleguide
+ & subpath(edgecycle, bisectorindices[1], 5+bisectorindices[0]) & cycle;
+ toreturn = usetriangles ? maketriangle(secondpatch, f, grad)
+ : triangletoquads(secondpatch, f, grad, a, b);
+ if (toreturn.length == 0) return null;
+ toreturn.push(patchwithnormals(firstpatch, grad));
+ } else {
+ // now length(edgecycle) == 6
+ path3 secondpatch = middleguide
+ & subpath(edgecycle, bisectorindices[1], 6+bisectorindices[0])
+ & cycle;
+ toreturn = new patch[] {patchwithnormals(firstpatch, grad),
+ patchwithnormals(secondpatch, grad)};
+ }
+ return toreturn;
+}
+
+// Numerical gradient of a function
+typedef triple vectorfunction(triple);
+vectorfunction nGrad(real f(triple)) {
+ static real epsilon = 1e-3;
+ return new triple(triple v) {
+ return ( (f(v + epsilon*X) - f(v - epsilon*X)) / (2 epsilon),
+ (f(v + epsilon*Y) - f(v - epsilon*Y)) / (2 epsilon),
+ (f(v + epsilon*Z) - f(v - epsilon*Z)) / (2 epsilon) );
+ };
+}
+
+// A point together with a value at that location.
+struct evaluatedpoint {
+ triple pt;
+ real value;
+ void operator init(triple pt, real value) {
+ this.pt = pt;
+ this.value = value;
+ }
+}
+
+triple operator cast(evaluatedpoint p) { return p.pt; }
+
+// Compute the values of a function at every vertex of an nx by ny by nz
+// array of rectangular solids.
+evaluatedpoint[][][] make3dgrid(triple a, triple b, int nx, int ny, int nz,
+ real f(triple), bool allowzero = false)
+{
+ evaluatedpoint[][][] toreturn = new evaluatedpoint[nx+1][ny+1][nz+1];
+ for (int i = 0; i <= nx; ++i) {
+ for (int j = 0; j <= ny; ++j) {
+ for (int k = 0; k <= nz; ++k) {
+ triple pt = (interp(a.x, b.x, i/nx),
+ interp(a.y, b.y, j/ny),
+ interp(a.z, b.z, k/nz));
+ real value = f(pt);
+ if (value == 0 && !allowzero) value = 1e-5;
+ toreturn[i][j][k] = evaluatedpoint(pt, value);
+ }
+ }
+ }
+ return toreturn;
+}
+
+// The following utilities make, for instance, slice(A, i, j, k, l)
+// equivalent to what A[i:j][k:l] ought to mean for two- and three-
+// -dimensional arrays of evaluatedpoints and of positionedvectors.
+typedef evaluatedpoint T;
+T[][] slice(T[][] a, int start1, int end1, int start2, int end2) {
+ T[][] toreturn = new T[end1-start1][];
+ for (int i = start1; i < end1; ++i) {
+ toreturn[i-start1] = a[i][start2:end2];
+ }
+ return toreturn;
+}
+T[][][] slice(T[][][] a, int start1, int end1,
+ int start2, int end2,
+ int start3, int end3) {
+ T[][][] toreturn = new T[end1-start1][][];
+ for (int i = start1; i < end1; ++i) {
+ toreturn[i-start1] = slice(a[i], start2, end2, start3, end3);
+ }
+ return toreturn;
+}
+typedef positionedvector T;
+T[][] slice(T[][] a, int start1, int end1, int start2, int end2) {
+ T[][] toreturn = new T[end1-start1][];
+ for (int i = start1; i < end1; ++i) {
+ toreturn[i-start1] = a[i][start2:end2];
+ }
+ return toreturn;
+}
+T[][][] slice(T[][][] a, int start1, int end1,
+ int start2, int end2,
+ int start3, int end3) {
+ T[][][] toreturn = new T[end1-start1][][];
+ for (int i = start1; i < end1; ++i) {
+ toreturn[i-start1] = slice(a[i], start2, end2, start3, end3);
+ }
+ return toreturn;
+}
+
+// An object of class gridwithzeros stores the values of a function at each vertex
+// of a three-dimensional grid, together with zeros of the function along edges
+// of the grid and the gradient of the function at each such zero.
+struct gridwithzeros {
+ int nx, ny, nz;
+ evaluatedpoint[][][] corners;
+ positionedvector[][][] xdirzeros;
+ positionedvector[][][] ydirzeros;
+ positionedvector[][][] zdirzeros;
+ triple grad(triple);
+ real f(triple);
+ int maxdepth;
+ bool usetriangles;
+
+ // Populate the edges with zeros that have a sign change and are not already
+ // populated.
+ void fillzeros() {
+ for (int j = 0; j < ny+1; ++j) {
+ for (int k = 0; k < nz+1; ++k) {
+ real y = corners[0][j][k].pt.y;
+ real z = corners[0][j][k].pt.z;
+ real f_along_x(real t) { return f((t, y, z)); }
+ for (int i = 0; i < nx; ++i) {
+ if (xdirzeros[i][j][k] != null) continue;
+ evaluatedpoint start = corners[i][j][k];
+ evaluatedpoint end = corners[i+1][j][k];
+ if ((start.value > 0 && end.value > 0) || (start.value < 0 && end.value < 0))
+ xdirzeros[i][j][k] = null;
+ else {
+ triple root = (0,y,z);
+ root += X * findroot(f_along_x, start.pt.x, end.pt.x,
+ fa=start.value, fb=end.value);
+ triple normal = grad(root);
+ xdirzeros[i][j][k] = positionedvector(root, normal);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < nx+1; ++i) {
+ for (int k = 0; k < nz+1; ++k) {
+ real x = corners[i][0][k].pt.x;
+ real z = corners[i][0][k].pt.z;
+ real f_along_y(real t) { return f((x, t, z)); }
+ for (int j = 0; j < ny; ++j) {
+ if (ydirzeros[i][j][k] != null) continue;
+ evaluatedpoint start = corners[i][j][k];
+ evaluatedpoint end = corners[i][j+1][k];
+ if ((start.value > 0 && end.value > 0) || (start.value < 0 && end.value < 0))
+ ydirzeros[i][j][k] = null;
+ else {
+ triple root = (x,0,z);
+ root += Y * findroot(f_along_y, start.pt.y, end.pt.y,
+ fa=start.value, fb=end.value);
+ triple normal = grad(root);
+ ydirzeros[i][j][k] = positionedvector(root, normal);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < nx+1; ++i) {
+ for (int j = 0; j < ny+1; ++j) {
+ real x = corners[i][j][0].pt.x;
+ real y = corners[i][j][0].pt.y;
+ real f_along_z(real t) { return f((x, y, t)); }
+ for (int k = 0; k < nz; ++k) {
+ if (zdirzeros[i][j][k] != null) continue;
+ evaluatedpoint start = corners[i][j][k];
+ evaluatedpoint end = corners[i][j][k+1];
+ if ((start.value > 0 && end.value > 0) || (start.value < 0 && end.value < 0))
+ zdirzeros[i][j][k] = null;
+ else {
+ triple root = (x,y,0);
+ root += Z * findroot(f_along_z, start.pt.z, end.pt.z,
+ fa=start.value, fb=end.value);
+ triple normal = grad(root);
+ zdirzeros[i][j][k] = positionedvector(root, normal);
+ }
+ }
+ }
+ }
+ }
+
+ // Fill in the grid vertices and the zeros along edges. Each cube starts at
+ // depth one and the depth increases each time it subdivides; maxdepth is the
+ // maximum subdivision depth. When a cube at maxdepth cannot be resolved to
+ // patches, it is left empty.
+ void operator init(int nx, int ny, int nz,
+ real f(triple), triple a, triple b,
+ int maxdepth = 6, bool usetriangles) {
+ this.nx = nx;
+ this.ny = ny;
+ this.nz = nz;
+ grad = nGrad(f);
+ this.f = f;
+ this.maxdepth = maxdepth;
+ this.usetriangles = usetriangles;
+ corners = make3dgrid(a, b, nx, ny, nz, f);
+ xdirzeros = new positionedvector[nx][ny+1][nz+1];
+ ydirzeros = new positionedvector[nx+1][ny][nz+1];
+ zdirzeros = new positionedvector[nx+1][ny+1][nz];
+
+ for (int i = 0; i <= nx; ++i) {
+ for (int j = 0; j <= ny; ++j) {
+ for (int k = 0; k <= nz; ++k) {
+ if (i < nx) xdirzeros[i][j][k] = null;
+ if (j < ny) ydirzeros[i][j][k] = null;
+ if (k < nz) zdirzeros[i][j][k] = null;
+ }
+ }
+ }
+
+ fillzeros();
+ }
+
+ // Doubles nx, ny, and nz by halving the sizes of the cubes along the x, y, and z
+ // directions (resulting in 8 times as many cubes). Already existing data about
+ // function values and zeros is copied; vertices and edges with no such pre-existing
+ // data are populated.
+ //
+ // Returns true if subdivide succeeded, false if it failed (because maxdepth
+ // was exceeded).
+ bool subdivide() {
+ if (maxdepth <= 1) {
+ return false;
+ }
+ --maxdepth;
+ triple a = corners[0][0][0];
+ triple b = corners[nx][ny][nz];
+ nx *= 2;
+ ny *= 2;
+ nz *= 2;
+ evaluatedpoint[][][] oldcorners = corners;
+ corners = new evaluatedpoint[nx+1][ny+1][nz+1];
+ for (int i = 0; i <= nx; ++i) {
+ for (int j = 0; j <= ny; ++j) {
+ for (int k = 0; k <= nz; ++k) {
+ if (i % 2 == 0 && j % 2 == 0 && k % 2 == 0) {
+ corners[i][j][k] = oldcorners[quotient(i,2)][quotient(j,2)][quotient(k,2)];
+ } else {
+ triple pt = (interp(a.x, b.x, i/nx),
+ interp(a.y, b.y, j/ny),
+ interp(a.z, b.z, k/nz));
+ real value = f(pt);
+ if (value == 0) value = 1e-5;
+ corners[i][j][k] = evaluatedpoint(pt, value);
+ }
+ }
+ }
+ }
+
+ positionedvector[][][] oldxdir = xdirzeros;
+ xdirzeros = new positionedvector[nx][ny+1][nz+1];
+ for (int i = 0; i < nx; ++i) {
+ for (int j = 0; j < ny + 1; ++j) {
+ for (int k = 0; k < nz + 1; ++k) {
+ if (j % 2 != 0 || k % 2 != 0) {
+ xdirzeros[i][j][k] = null;
+ } else {
+ positionedvector zero = oldxdir[quotient(i,2)][quotient(j,2)][quotient(k,2)];
+ if (zero == null) {
+ xdirzeros[i][j][k] = null;
+ continue;
+ }
+ real x = zero.position.x;
+ if (x > interp(a.x, b.x, i/nx) && x < interp(a.x, b.x, (i+1)/nx)) {
+ xdirzeros[i][j][k] = zero;
+ } else {
+ xdirzeros[i][j][k] = null;
+ }
+ }
+ }
+ }
+ }
+
+ positionedvector[][][] oldydir = ydirzeros;
+ ydirzeros = new positionedvector[nx+1][ny][nz+1];
+ for (int i = 0; i < nx+1; ++i) {
+ for (int j = 0; j < ny; ++j) {
+ for (int k = 0; k < nz + 1; ++k) {
+ if (i % 2 != 0 || k % 2 != 0) {
+ ydirzeros[i][j][k] = null;
+ } else {
+ positionedvector zero = oldydir[quotient(i,2)][quotient(j,2)][quotient(k,2)];
+ if (zero == null) {
+ ydirzeros[i][j][k] = null;
+ continue;
+ }
+ real y = zero.position.y;
+ if (y > interp(a.y, b.y, j/ny) && y < interp(a.y, b.y, (j+1)/ny)) {
+ ydirzeros[i][j][k] = zero;
+ } else {
+ ydirzeros[i][j][k] = null;
+ }
+ }
+ }
+ }
+ }
+
+ positionedvector[][][] oldzdir = zdirzeros;
+ zdirzeros = new positionedvector[nx+1][ny+1][nz];
+ for (int i = 0; i < nx + 1; ++i) {
+ for (int j = 0; j < ny + 1; ++j) {
+ for (int k = 0; k < nz; ++k) {
+ if (i % 2 != 0 || j % 2 != 0) {
+ zdirzeros[i][j][k] = null;
+ } else {
+ positionedvector zero = oldzdir[quotient(i,2)][quotient(j,2)][quotient(k,2)];
+ if (zero == null) {
+ zdirzeros[i][j][k] = null;
+ continue;
+ }
+ real z = zero.position.z;
+ if (z > interp(a.z, b.z, k/nz) && z < interp(a.z, b.z, (k+1)/nz)) {
+ zdirzeros[i][j][k] = zero;
+ } else {
+ zdirzeros[i][j][k] = null;
+ }
+ }
+ }
+ }
+ }
+
+ fillzeros();
+ return true;
+ }
+
+ // Forward declaration of the draw method, which will be called by drawcube().
+ patch[] draw(bool[] reportactive = null);
+
+ // Construct the patches, assuming that we are working
+ // with a single cube (nx = ny = nz = 1). This method will subdivide the
+ // cube if necessary. The parameter reportactive should be an array of
+ // length 6. Setting an entry to true indicates that the surface abuts the
+ // corresponding face (according to the earlier enum), and thus that the
+ // algorithm should be sure that something is drawn in the cube sharing
+ // that face--even if all the vertices of that cube have the same sign.
+ patch[] drawcube(bool[] reportactive = null) {
+ // First, determine which edges (if any) actually have zeros on them.
+ edge[] zeroedges = new edge[0];
+ positionedvector[] zeros = new positionedvector[0];
+
+ int currentface, nextface;
+
+ void pushifnonnull(positionedvector v) {
+ if (v != null) {
+ zeroedges.push(edge(currentface, nextface));
+ zeros.push(v);
+ }
+ }
+ positionedvector findzero(int face1, int face2) {
+ edge e = edge(face1, face2);
+ for (int i = 0; i < zeroedges.length; ++i) {
+ if (zeroedges[i] == e) return zeros[i];
+ }
+ return null;
+ }
+
+ currentface = XLOW;
+ nextface = YHIGH;
+ pushifnonnull(zdirzeros[0][1][0]);
+ nextface = YLOW;
+ pushifnonnull(zdirzeros[0][0][0]);
+ nextface = ZHIGH;
+ pushifnonnull(ydirzeros[0][0][1]);
+ nextface = ZLOW;
+ pushifnonnull(ydirzeros[0][0][0]);
+
+ currentface = XHIGH;
+ nextface = YHIGH;
+ pushifnonnull(zdirzeros[1][1][0]);
+ nextface = YLOW;
+ pushifnonnull(zdirzeros[1][0][0]);
+ nextface = ZHIGH;
+ pushifnonnull(ydirzeros[1][0][1]);
+ nextface = ZLOW;
+ pushifnonnull(ydirzeros[1][0][0]);
+
+ currentface = YHIGH;
+ nextface = ZHIGH;
+ pushifnonnull(xdirzeros[0][1][1]);
+ currentface = ZHIGH;
+ nextface = YLOW;
+ pushifnonnull(xdirzeros[0][0][1]);
+ currentface = YLOW;
+ nextface = ZLOW;
+ pushifnonnull(xdirzeros[0][0][0]);
+ currentface = ZLOW;
+ nextface = YHIGH;
+ pushifnonnull(xdirzeros[0][1][0]);
+
+ //Now, string those edges together to make a circle.
+
+ patch[] subdividecube() {
+ if (!subdivide()) {
+ return new patch[0];
+ }
+ return draw(reportactive);
+ }
+ if (zeroedges.length < 3) {
+ return subdividecube();
+ }
+ int[] faceorder = makecircle(zeroedges);
+ if (alias(faceorder,null)) {
+ return subdividecube();
+ }
+ positionedvector[] patchcorners = new positionedvector[0];
+ for (int i = 0; i < faceorder.length; ++i) {
+ patchcorners.push(findzero(faceorder[i], faceorder[i+1]));
+ }
+ patchcorners.cyclic = true;
+
+ //Now, produce the cyclic path around the edges.
+ path3 edgecycle;
+ for (int i = 0; i < faceorder.length; ++i) {
+ path3 currentpath = pathinface(patchcorners[i], patchcorners[i+1],
+ faceorder[i+1], faceorder[i],
+ faceorder[i+2]);
+ triple testpoint = point(currentpath, 0.5);
+ if (!checkpt(testpoint, f, grad, corners[0][0][0], corners[1][1][1])) {
+ return subdividecube();
+ }
+
+ edgecycle = edgecycle & currentpath;
+ }
+ edgecycle = edgecycle & cycle;
+
+
+ { // Ensure the outward normals are pointing in the same direction as the gradient.
+ triple tangentin = patchcorners[0].position - precontrol(edgecycle, 0);
+ triple tangentout = postcontrol(edgecycle, 0) - patchcorners[0].position;
+ triple normal = cross(tangentin, tangentout);
+ if (dot(normal, patchcorners[0].direction) < 0) {
+ edgecycle = reverse(edgecycle);
+ patchcorners = patchcorners[-sequence(patchcorners.length)];
+ patchcorners.cyclic = true;
+ }
+ }
+
+ patch[] toreturn = quadpatches(edgecycle, patchcorners, f, grad,
+ corners[0][0][0], corners[1][1][1], usetriangles);
+ if (alias(toreturn, null)) return subdividecube();
+ return toreturn;
+ }
+
+ // Extracts the specified cube as a gridwithzeros object with
+ // nx = ny = nz = 1.
+ gridwithzeros getcube(int i, int j, int k) {
+ gridwithzeros cube = new gridwithzeros;
+ cube.grad = grad;
+ cube.f = f;
+ cube.nx = 1;
+ cube.ny = 1;
+ cube.nz = 1;
+ cube.maxdepth = maxdepth;
+ cube.usetriangles = usetriangles;
+ cube.corners = slice(corners,i,i+2,j,j+2,k,k+2);
+ cube.xdirzeros = slice(xdirzeros,i,i+1,j,j+2,k,k+2);
+ cube.ydirzeros = slice(ydirzeros,i,i+2,j,j+1,k,k+2);
+ cube.zdirzeros = slice(zdirzeros,i,i+2,j,j+2,k,k+1);
+ return cube;
+ }
+
+ // Returns an array of patches representing the surface.
+ // The parameter reportactive should be an array of
+ // length 6. Setting an entry to true indicates that the surface abuts the
+ // corresponding face of the cube that bounds the entire grid.
+ //
+ // If reportactive == null, it is assumed that this is a top-level call;
+ // a dot is printed to stdout for each cube drawn as a very rough
+ // progress indicator.
+ //
+ // If reportactive != null, then it is assumed that the caller had a strong
+ // reason to believe that this grid contains a part of the surface; the
+ // grid will subdivide all the way to maxdepth if necessary to find points
+ // on the surface.
+ draw = new patch[](bool[] reportactive = null) {
+ if (alias(reportactive, null)) progress(true);
+ // A list of all the patches not already drawn but known
+ // to contain part of the surface. This "queue" is
+ // actually implemented as stack for simplicity, since
+ // it does not make any difference. In a multi-threaded
+ // version of the algorithm, a queue (shared across all threads)
+ // would make more sense than a stack.
+ triple[] queue = new triple[0];
+ bool[][][] enqueued = new bool[nx][ny][nz];
+ for (int i = 0; i < enqueued.length; ++i) {
+ for (int j = 0; j < enqueued[i].length; ++j) {
+ for (int k = 0; k < enqueued[i][j].length; ++k) {
+ enqueued[i][j][k] = false;
+ }
+ }
+ }
+
+ void enqueue(int i, int j, int k) {
+ if (i >= 0 && i < nx
+ && j >= 0 && j < ny
+ && k >= 0 && k < nz
+ && !enqueued[i][j][k]) {
+ queue.push((i,j,k));
+ enqueued[i][j][k] = true;
+ }
+ if (!alias(reportactive, null)) {
+ if (i < 0) reportactive[XLOW] = true;
+ if (i >= nx) reportactive[XHIGH] = true;
+ if (j < 0) reportactive[YLOW] = true;
+ if (j >= ny) reportactive[YHIGH] = true;
+ if (k < 0) reportactive[ZLOW] = true;
+ if (k >= nz) reportactive[ZHIGH] = true;
+ }
+ }
+
+ for (int i = 0; i < nx+1; ++i) {
+ for (int j = 0; j < ny+1; ++j) {
+ for (int k = 0; k < nz+1; ++k) {
+ if (i < nx && xdirzeros[i][j][k] != null) {
+ for (int jj = j-1; jj <= j; ++jj)
+ for (int kk = k-1; kk <= k; ++kk)
+ enqueue(i, jj, kk);
+ }
+ if (j < ny && ydirzeros[i][j][k] != null) {
+ for (int ii = i-1; ii <= i; ++ii)
+ for (int kk = k-1; kk <= k; ++kk)
+ enqueue(ii, j, kk);
+ }
+ if (k < nz && zdirzeros[i][j][k] != null) {
+ for (int ii = i-1; ii <= i; ++ii)
+ for (int jj = j-1; jj <= j; ++jj)
+ enqueue(ii, jj, k);
+ }
+ }
+ }
+ }
+
+ if (!alias(reportactive, null) && queue.length == 0) {
+ if (subdivide()) return draw(reportactive);
+ }
+
+ patch[] surface = new patch[0];
+
+ while (queue.length > 0) {
+ triple coord = queue.pop();
+ int i = floor(coord.x);
+ int j = floor(coord.y);
+ int k = floor(coord.z);
+ bool[] reportface = array(6, false);
+ patch[] toappend = getcube(i,j,k).drawcube(reportface);
+ if (reportface[XLOW]) enqueue(i-1,j,k);
+ if (reportface[XHIGH]) enqueue(i+1,j,k);
+ if (reportface[YLOW]) enqueue(i,j-1,k);
+ if (reportface[YHIGH]) enqueue(i,j+1,k);
+ if (reportface[ZLOW]) enqueue(i,j,k-1);
+ if (reportface[ZHIGH]) enqueue(i,j,k+1);
+ surface.append(toappend);
+ if (alias(reportactive, null)) progress();
+ }
+ if (alias(reportactive, null)) progress(false);
+ return surface;
+ };
+}
+
+// The external interface of this whole module. Accepts exactly one
+// function (throws an error if two or zero functions are specified).
+// The function should be differentiable. (Whatever you do, do not
+// pass in an indicator function!) Ideally, the zero locus of the
+// function should be smooth; singularities will significantly slow
+// down the algorithm and potentially give bad results.
+//
+// Returns a plot of the zero locus of the function within the
+// rectangular solid with opposite corners at a and b.
+//
+// Additional parameters:
+// n - the number of initial segments in each of the x, y, z directions.
+// overlapedges - if true, the patches of the surface are slightly enlarged
+// to compensate for an artifact in which the viewer can see through the
+// boundary between patches. (Some of this may actually be a result of
+// edges not lining up perfectly, but I'm fairly sure a lot of it arises
+// purely as a rendering artifact.)
+// nx - override n in the x direction
+// ny - override n in the y direction
+// nz - override n in the z direction
+// maxdepth - the maximum depth to which the algorithm will subdivide in
+// an effort to find patches that closely approximate the true surface.
+surface implicitsurface(real f(triple) = null, real ff(real,real,real) = null,
+ triple a, triple b,
+ int n = nmesh,
+ bool keyword overlapedges = false,
+ int keyword nx=n, int keyword ny=n,
+ int keyword nz=n,
+ int keyword maxdepth = 8,
+ bool keyword usetriangles=true) {
+ if (f == null && ff == null)
+ abort("implicitsurface called without specifying a function.");
+ if (f != null && ff != null)
+ abort("Only specify one function when calling implicitsurface.");
+ if (f == null) f = new real(triple w) { return ff(w.x, w.y, w.z); };
+ gridwithzeros grid = gridwithzeros(nx, ny, nz, f, a, b, maxdepth=maxdepth,
+ usetriangles=usetriangles);
+ patch[] patches = grid.draw();
+ if (overlapedges) {
+ for (int i = 0; i < patches.length; ++i) {
+ triple center = (patches[i].triangular ?
+ patches[i].point(1/3, 1/3) : patches[i].point(1/2,1/2));
+ transform3 T=shift(center) * scale3(1.03) * shift(-center);
+ patches[i] = T * patches[i];
+ }
+ }
+ return surface(...patches);
+}
diff --git a/graphics/asymptote/base/solids.asy b/graphics/asymptote/base/solids.asy
new file mode 100644
index 0000000000..942a7fe233
--- /dev/null
+++ b/graphics/asymptote/base/solids.asy
@@ -0,0 +1,412 @@
+import graph3;
+
+pen defaultbackpen=linetype(new real[] {4,4},4,scale=false);
+
+// A solid geometry package.
+
+// Try to find a bounding tangent line between two paths.
+real[] tangent(path p, path q, bool side)
+{
+ static real fuzz=1.0e-5;
+
+ if((cyclic(p) && inside(p,point(q,0)) ||
+ cyclic(q) && inside(q,point(p,0))) &&
+ intersect(p,q,fuzz).length == 0) return new real[];
+
+ for(int i=0; i < 100; ++i) {
+ real ta=side ? mintimes(p)[1] : maxtimes(p)[1];
+ real tb=side ? mintimes(q)[1] : maxtimes(q)[1];
+ pair a=point(p,ta);
+ pair b=point(q,tb);
+ real angle=angle(b-a,warn=false);
+ if(abs(angle) <= sqrtEpsilon || abs(abs(0.5*angle)-pi) <= sqrtEpsilon)
+ return new real[] {ta,tb};
+ transform t=rotate(-degrees(angle));
+ p=t*p;
+ q=t*q;
+ }
+ return new real[];
+}
+
+path line(path p, path q, real[] t)
+{
+ return point(p,t[0])--point(q,t[1]);
+}
+
+// Return the projection of a generalized cylinder of height h constructed
+// from area base in the XY plane and aligned with axis.
+path[] cylinder(path3 base, real h, triple axis=Z, projection P)
+{
+ base=rotate(-colatitude(axis),cross(axis,Z))*base;
+ path3 top=shift(h*axis)*base;
+ path Base=project(base,P);
+ path Top=project(top,P);
+ real[] t1=tangent(Base,Top,true);
+ real[] t2=tangent(Base,Top,false);
+ path p=subpath(Base,t1[0]/P.ninterpolate,t2[0]/P.ninterpolate);
+ path q=subpath(Base,t2[0]/P.ninterpolate,t1[0]/P.ninterpolate);
+ return Base^^Top^^line(Base,Top,t1)^^line(Base,Top,t2);
+}
+
+// The three-dimensional "wireframe" used to visualize a volume of revolution
+struct skeleton {
+ struct curve {
+ path3[] front;
+ path3[] back;
+ }
+ // transverse skeleton (perpendicular to axis of revolution)
+ curve transverse;
+ // longitudinal skeleton (parallel to axis of revolution)
+ curve longitudinal;
+}
+
+// A surface of revolution generated by rotating a planar path3 g
+// from angle1 to angle2 about c--c+axis.
+struct revolution {
+ triple c;
+ path3 g;
+ triple axis;
+ real angle1,angle2;
+ triple M;
+ triple m;
+
+ static real epsilon=10*sqrtEpsilon;
+
+ void operator init(triple c=O, path3 g, triple axis=Z, real angle1=0,
+ real angle2=360) {
+ this.c=c;
+ this.g=g;
+ this.axis=unit(axis);
+ this.angle1=angle1;
+ this.angle2=angle2;
+ M=max(g);
+ m=min(g);
+ }
+
+
+ revolution copy() {
+ return revolution(c,g,axis,angle1,angle2);
+ }
+
+ triple vertex(int i, real j) {
+ triple v=point(g,i);
+ triple center=c+dot(v-c,axis)*axis;
+ triple perp=v-center;
+ triple normal=cross(axis,perp);
+ return center+Cos(j)*perp+Sin(j)*normal;
+ }
+
+ // Construct the surface of rotation generated by rotating g
+ // from angle1 to angle2 sampled n times about the line c--c+axis.
+ // An optional surface pen color(int i, real j) may be specified
+ // to override the color at vertex(i,j).
+ surface surface(int n=nslice, pen color(int i, real j)=null) {
+ return surface(c,g,axis,n,angle1,angle2,color);
+ }
+
+ path3 slice(real position, int n=nCircle) {
+ triple v=point(g,position);
+ triple center=c+dot(v-c,axis)*axis;
+ triple perp=v-center;
+ if(abs(perp) <= epsilon*max(abs(m),abs(M))) return center;
+ triple v1=center+rotate(angle1,axis)*perp;
+ triple v2=center+rotate(angle2,axis)*perp;
+ path3 p=Arc(center,v1,v2,axis,n);
+ return (angle2-angle1) % 360 == 0 ? p&cycle : p;
+ }
+
+ triple camera(projection P) {
+ triple camera=P.camera;
+ if(P.infinity) {
+ real s=abs(M-m)+abs(m-P.target);
+ camera=P.target+camerafactor*s*unit(P.vector());
+ }
+ return camera;
+ }
+
+ // add transverse slice to skeleton s;
+ void transverse(skeleton s, real t, int n=nslice, projection P) {
+ skeleton.curve s=s.transverse;
+ path3 S=slice(t,n);
+ triple camera=camera(P);
+ int L=length(g);
+ real midtime=0.5*L;
+ real sign=sgn(dot(axis,camera-P.target))*sgn(dot(axis,dir(g,midtime)));
+ if(dot(M-m,axis) == 0 || (t <= epsilon && sign < 0) ||
+ (t >= L-epsilon && sign > 0))
+ s.front.push(S);
+ else {
+ path3 Sp=slice(t+epsilon,n);
+ path3 Sm=slice(t-epsilon,n);
+ path sp=project(Sp,P);
+ path sm=project(Sm,P);
+ real[] t1=tangent(sp,sm,true);
+ real[] t2=tangent(sp,sm,false);
+ if(t1.length > 1 && t2.length > 1) {
+ real t1=t1[0]/P.ninterpolate;
+ real t2=t2[0]/P.ninterpolate;
+ int len=length(S);
+ if(t2 < t1) {
+ real temp=t1;
+ t1=t2;
+ t2=temp;
+ }
+ path3 p1=subpath(S,t1,t2);
+ path3 p2=subpath(S,t2,len);
+ path3 P2=subpath(S,0,t1);
+ if(abs(midpoint(p1)-camera) <= abs(midpoint(p2)-camera)) {
+ s.front.push(p1);
+ if(cyclic(S))
+ s.back.push(p2 & P2);
+ else {
+ s.back.push(p2);
+ s.back.push(P2);
+ }
+ } else {
+ if(cyclic(S))
+ s.front.push(p2 & P2);
+ else {
+ s.front.push(p2);
+ s.front.push(P2);
+ }
+ s.back.push(p1);
+ }
+ } else {
+ if((t <= midtime && sign < 0) || (t >= midtime && sign > 0))
+ s.front.push(S);
+ else
+ s.back.push(S);
+ }
+ }
+ }
+
+ // add m evenly spaced transverse slices to skeleton s
+ void transverse(skeleton s, int m=0, int n=nslice, projection P) {
+ if(m == 0) {
+ int N=size(g);
+ for(int i=0; i < N; ++i)
+ transverse(s,(real) i,n,P);
+ } else if(m == 1)
+ transverse(s,reltime(g,0.5),n,P);
+ else {
+ real factor=1/(m-1);
+ for(int i=0; i < m; ++i)
+ transverse(s,reltime(g,i*factor),n,P);
+ }
+ }
+
+ // return approximate silhouette based on m evenly spaced transverse slices;
+ // must be recomputed if camera is adjusted
+ path3[] silhouette(int m=64, projection P=currentprojection) {
+ if(is3D())
+ warning("2Dsilhouette",
+ "silhouette routine is intended only for 2d projections");
+ path3 G,H;
+ int N=size(g);
+ int M=(m == 0) ? N : m;
+ real factor=m == 1 ? 0 : 1/(m-1);
+ int n=nslice;
+
+ real tfirst=-1;
+ real tlast;
+ for(int i=0; i < M; ++i) {
+ real t=(m == 0) ? i : reltime(g,i*factor);
+ path3 S=slice(t,n);
+ triple camera=camera(P);
+ path3 Sp=slice(t+epsilon,n);
+ path3 Sm=slice(t-epsilon,n);
+ path sp=project(Sp,P);
+ path sm=project(Sm,P);
+ real[] t1=tangent(sp,sm,true);
+ real[] t2=tangent(sp,sm,false);
+ if(t1.length > 1 && t2.length > 1) {
+ real t1=t1[0]/P.ninterpolate;
+ real t2=t2[0]/P.ninterpolate;
+ if(t1 != t2) {
+ G=G..point(S,t1);
+ H=point(S,t2)..H;
+ if(tfirst < 0) tfirst=t;
+ tlast=t;
+ }
+ }
+ }
+ int L=length(g);
+ real midtime=0.5*L;
+ triple camera=camera(P);
+ real sign=sgn(dot(axis,camera-P.target))*sgn(dot(axis,dir(g,midtime)));
+
+ skeleton sfirst;
+ transverse(sfirst,tfirst,n,P);
+ triple delta=this.M-this.m;
+ path3 cap;
+ if(dot(delta,axis) == 0 || (tfirst <= epsilon && sign < 0)) {
+ cap=sfirst.transverse.front[0];
+ } else {
+ if(sign > 0) {
+ if(sfirst.transverse.front.length > 0)
+ G=reverse(sfirst.transverse.front[0])..G;
+ } else {
+ if(sfirst.transverse.back.length > 0)
+ G=sfirst.transverse.back[0]..G;
+ }
+ }
+
+ skeleton slast;
+ transverse(slast,tlast,n,P);
+ if(dot(delta,axis) == 0 || (tlast >= L-epsilon && sign > 0)) {
+ cap=slast.transverse.front[0];
+ } else {
+ if(sign > 0) {
+ if(slast.transverse.back.length > 0)
+ H=reverse(slast.transverse.back[0])..H;
+ } else {
+ if(slast.transverse.front.length > 0)
+ H=slast.transverse.front[0]..H;
+ }
+ }
+
+ return size(cap) == 0 ? G^^H : G^^H^^cap;
+ }
+
+ // add longitudinal curves to skeleton;
+ void longitudinal(skeleton s, int n=nslice, projection P) {
+ real t, d=0;
+ // Find a point on g of maximal distance from the axis.
+ int N=size(g);
+ for(int i=0; i < N; ++i) {
+ triple v=point(g,i);
+ triple center=c+dot(v-c,axis)*axis;
+ real r=abs(v-center);
+ if(r > d) {
+ t=i;
+ d=r;
+ }
+ }
+ path3 S=slice(t,n);
+ path3 Sm=slice(t+epsilon,n);
+ path3 Sp=slice(t-epsilon,n);
+ path sp=project(Sp,P);
+ path sm=project(Sm,P);
+ real[] t1=tangent(sp,sm,true);
+ real[] t2=tangent(sp,sm,false);
+ transform3 T=transpose(align(axis));
+ real Longitude(triple v) {return longitude(T*(v-c),warn=false);}
+ real ref=Longitude(point(g,t));
+ real angle(real t) {return Longitude(point(S,t/P.ninterpolate))-ref;}
+ triple camera=camera(P);
+ void push(real[] T) {
+ if(T.length > 1) {
+ path3 p=rotate(angle(T[0]),c,c+axis)*g;
+ path3 p1=subpath(p,0,t);
+ path3 p2=subpath(p,t,length(p));
+ if(length(p1) > 0 &&
+ (length(p2) == 0 ||
+ abs(midpoint(p1)-camera) <= abs(midpoint(p2)-camera))) {
+ s.longitudinal.front.push(p1);
+ s.longitudinal.back.push(p2);
+ } else {
+ s.longitudinal.back.push(p1);
+ s.longitudinal.front.push(p2);
+ }
+ }
+ }
+ push(t1);
+ push(t2);
+ }
+
+ skeleton skeleton(int m=0, int n=nslice, projection P) {
+ skeleton s;
+ transverse(s,m,n,P);
+ longitudinal(s,n,P);
+ return s;
+ }
+}
+
+revolution operator * (transform3 t, revolution r)
+{
+ triple trc=t*r.c;
+ return revolution(trc,t*r.g,t*(r.c+r.axis)-trc,r.angle1,r.angle2);
+}
+
+surface surface(revolution r, int n=nslice, pen color(int i, real j)=null)
+{
+ return r.surface(n,color);
+}
+
+// Draw on picture pic the skeleton of the surface of revolution r.
+// Draw the front portion of each of the m transverse slices with pen p and
+// the back portion with pen backpen. Rotational arcs are based on
+// n-point approximations to the unit circle.
+void draw(picture pic=currentpicture, revolution r, int m=0, int n=nslice,
+ pen frontpen=currentpen, pen backpen=frontpen,
+ pen longitudinalpen=frontpen, pen longitudinalbackpen=backpen,
+ light light=currentlight, string name="",
+ render render=defaultrender, projection P=currentprojection)
+{
+ if(is3D()) {
+ pen thin=thin();
+ void drawskeleton(frame f, transform3 t, projection P) {
+ skeleton s=(t*r).skeleton(m,n,P);
+ if(frontpen != nullpen) {
+ draw(f,s.transverse.back,thin+defaultbackpen+backpen,light);
+ draw(f,s.transverse.front,thin+frontpen,light);
+ }
+ if(longitudinalpen != nullpen) {
+ draw(f,s.longitudinal.back,thin+defaultbackpen+longitudinalbackpen,
+ light);
+ draw(f,s.longitudinal.front,thin+longitudinalpen,light);
+ }
+ }
+
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(pic,name == "" ? "skeleton" : name,render);
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ drawskeleton(f,t,P);
+ if(pic != null)
+ pic.addBox(min(f,P),max(f,P),min(frontpen),max(frontpen));
+ });
+ frame f;
+ drawskeleton(f,identity4,P);
+ pic.addBox(min3(f),max3(f));
+ if(group)
+ endgroup3(pic);
+ } else {
+ skeleton s=r.skeleton(m,n,P);
+ if(frontpen != nullpen) {
+ draw(pic,s.transverse.back,defaultbackpen+backpen,light);
+ draw(pic,s.transverse.front,frontpen,light);
+ }
+ if(longitudinalpen != nullpen) {
+ draw(pic,s.longitudinal.back,defaultbackpen+longitudinalbackpen,
+ light);
+ draw(pic,s.longitudinal.front,longitudinalpen,light);
+ }
+ }
+}
+
+// Return a right circular cylinder of height h in the direction of axis
+// based on a circle centered at c with radius r.
+revolution cylinder(triple c=O, real r, real h, triple axis=Z)
+{
+ triple C=c+r*perp(axis);
+ axis=h*unit(axis);
+ return revolution(c,C--C+axis,axis);
+}
+
+// Return a right circular cone of height h in the direction of axis
+// based on a circle centered at c with radius r. The parameter n
+// controls the accuracy near the degenerate point at the apex.
+revolution cone(triple c=O, real r, real h, triple axis=Z, int n=nslice)
+{
+ axis=unit(axis);
+ return revolution(c,approach(c+r*perp(axis)--c+h*axis,n),axis);
+}
+
+// Return an approximate sphere of radius r centered at c obtained by rotating
+// an (n+1)-point approximation to a half circle about the Z axis.
+// Note: unitsphere provides a smoother and more efficient surface.
+revolution sphere(triple c=O, real r, int n=nslice)
+{
+ return revolution(c,Arc(c,r,180-sqrtEpsilon,0,sqrtEpsilon,0,Y,n),Z);
+}
diff --git a/graphics/asymptote/base/stats.asy b/graphics/asymptote/base/stats.asy
new file mode 100644
index 0000000000..be9efdfa42
--- /dev/null
+++ b/graphics/asymptote/base/stats.asy
@@ -0,0 +1,292 @@
+private import graph;
+
+real legendmarkersize=2mm;
+
+real mean(real A[])
+{
+ return sum(A)/A.length;
+}
+
+// unbiased estimate
+real variance(real A[])
+{
+ return sum((A-mean(A))^2)/(A.length-1);
+}
+
+real variancebiased(real A[])
+{
+ return sum((A-mean(A))^2)/A.length;
+}
+
+// unbiased estimate
+real stdev(real A[])
+{
+ return sqrt(variance(A));
+}
+
+real rms(real A[])
+{
+ return sqrt(sum(A^2)/A.length);
+}
+
+real skewness(real A[])
+{
+ real[] diff=A-mean(A);
+ return sum(diff^3)/sqrt(sum(diff^2)^3/A.length);
+}
+
+real kurtosis(real A[])
+{
+ real[] diff=A-mean(A);
+ return sum(diff^4)/sum(diff^2)^2*A.length;
+}
+
+real kurtosisexcess(real A[])
+{
+ return kurtosis(A)-3;
+}
+
+real Gaussian(real x, real sigma)
+{
+ static real sqrt2pi=sqrt(2pi);
+ return exp(-0.5*(x/sigma)^2)/(sigma*sqrt2pi);
+}
+
+real Gaussian(real x)
+{
+ static real invsqrt2pi=1/sqrt(2pi);
+ return exp(-0.5*x^2)*invsqrt2pi;
+}
+
+// Return frequency count of data in [bins[i],bins[i+1]) for i=0,...,n-1.
+int[] frequency(real[] data, real[] bins)
+{
+ int n=bins.length-1;
+ int[] freq=new int[n];
+ for(int i=0; i < n; ++i)
+ freq[i]=sum(bins[i] <= data & data < bins[i+1]);
+ return freq;
+}
+
+// Return frequency count in n uniform bins from a to b
+// (faster than the above more general algorithm).
+int[] frequency(real[] data, real a, real b, int n)
+{
+ int[] freq=sequence(new int(int x) {return 0;},n);
+ real h=n/(b-a);
+ for(int i=0; i < data.length; ++i) {
+ int I=Floor((data[i]-a)*h);
+ if(I >= 0 && I < n)
+ ++freq[I];
+ }
+ return freq;
+}
+
+// Return frequency count in [xbins[i],xbins[i+1]) and [ybins[j],ybins[j+1]).
+int[][] frequency(real[] x, real[] y, real[] xbins, real[] ybins)
+{
+ int n=xbins.length-1;
+ int m=ybins.length-1;
+ int[][] freq=new int[n][m];
+ bool[][] inybin=new bool[m][y.length];
+ for(int j=0; j < m; ++j)
+ inybin[j]=ybins[j] <= y & y < ybins[j+1];
+ for(int i=0; i < n; ++i) {
+ bool[] inxbini=xbins[i] <= x & x < xbins[i+1];
+ int[] freqi=freq[i];
+ for(int j=0; j < m; ++j)
+ freqi[j]=sum(inxbini & inybin[j]);
+ }
+ return freq;
+}
+
+// Return frequency count in nx by ny uniform bins in box(a,b).
+int[][] frequency(real[] x, real[] y, pair a, pair b, int nx, int ny=nx)
+{
+ int[][] freq=new int[nx][];
+ for(int i=0; i < nx; ++i)
+ freq[i]=sequence(new int(int x) {return 0;},ny);
+ real hx=nx/(b.x-a.x);
+ real hy=ny/(b.y-a.y);
+ real ax=a.x;
+ real ay=a.y;
+ for(int i=0; i < x.length; ++i) {
+ int I=Floor((x[i]-ax)*hx);
+ int J=Floor((y[i]-ay)*hy);
+ if(I >= 0 && I <= nx && J >= 0 && J <= ny)
+ ++freq[I][J];
+ }
+ return freq;
+}
+
+int[][] frequency(pair[] z, pair a, pair b, int nx, int ny=nx)
+{
+ int[][] freq=new int[nx][];
+ for(int i=0; i < nx; ++i)
+ freq[i]=sequence(new int(int x) {return 0;},ny);
+ real hx=nx/(b.x-a.x);
+ real hy=ny/(b.y-a.y);
+ real ax=a.x;
+ real ay=a.y;
+ for(int i=0; i < z.length; ++i) {
+ int I=Floor((z[i].x-ax)*hx);
+ int J=Floor((z[i].y-ay)*hy);
+ if(I >= 0 && I < nx && J >= 0 && J < ny)
+ ++freq[I][J];
+ }
+ return freq;
+}
+
+path halfbox(pair a, pair b)
+{
+ return a--(a.x,b.y)--b;
+}
+
+path topbox(pair a, pair b)
+{
+ return a--(a.x,b.y)--b--(b.x,a.y);
+}
+
+// Draw a histogram for bin boundaries bin[n+1] of frequency data in count[n].
+void histogram(picture pic=currentpicture, real[] bins, real[] count,
+ real low=-infinity,
+ pen fillpen=nullpen, pen drawpen=nullpen, bool bars=false,
+ Label legend="", real markersize=legendmarkersize)
+{
+ if((fillpen == nullpen || bars == true) && drawpen == nullpen)
+ drawpen=currentpen;
+ bool[] valid=count > 0;
+ real m=min(valid ? count : null);
+ real M=max(valid ? count : null);
+ bounds my=autoscale(pic.scale.y.scale.T(m),pic.scale.y.T(M),
+ pic.scale.y.scale);
+ if(low == -infinity) low=pic.scale.y.scale.Tinv(my.min);
+ real last=low;
+ int n=count.length;
+ begingroup(pic);
+ for(int i=0; i < n; ++i) {
+ if(valid[i]) {
+ real c=count[i];
+ pair b=Scale(pic,(bins[i+1],c));
+ pair a=Scale(pic,(bins[i],low));
+ if(fillpen != nullpen) {
+ fill(pic,box(a,b),fillpen);
+ if(!bars) draw(pic,b--(b.x,a.y),fillpen);
+ }
+ if(!bars)
+ draw(pic,halfbox(Scale(pic,(bins[i],last)),b),drawpen);
+ else draw(pic,topbox(a,b),drawpen);
+ last=c;
+ } else {
+ if(!bars && last != low) {
+ draw(pic,Scale(pic,(bins[i],last))--Scale(pic,(bins[i],low)),drawpen);
+ last=low;
+ }
+ }
+ }
+ if(!bars && last != low)
+ draw(pic,Scale(pic,(bins[n],last))--Scale(pic,(bins[n],low)),drawpen);
+ endgroup(pic);
+
+ if(legend.s != "") {
+ marker m=marker(scale(markersize)*shift((-0.5,-0.5))*unitsquare,
+ drawpen,fillpen == nullpen ? Draw :
+ (drawpen == nullpen ? Fill(fillpen) : FillDraw(fillpen)));
+ legend.p(drawpen);
+ pic.legend.push(Legend(legend.s,legend.p,invisible,m.f));
+ }
+}
+
+// Draw a histogram for data in n uniform bins between a and b
+// (optionally normalized).
+void histogram(picture pic=currentpicture, real[] data, real a, real b, int n,
+ bool normalize=false, real low=-infinity,
+ pen fillpen=nullpen, pen drawpen=nullpen, bool bars=false,
+ Label legend="", real markersize=legendmarkersize)
+{
+ real dx=(b-a)/n;
+ real[] freq=frequency(data,a,b,n);
+ if(normalize) freq /= dx*sum(freq);
+ histogram(pic,a+sequence(n+1)*dx,freq,low,fillpen,drawpen,bars,legend,
+ markersize);
+}
+
+// Method of Shimazaki and Shinomoto for selecting the optimal number of bins.
+// Shimazaki H. and Shinomoto S., A method for selecting the bin size of a
+// time histogram, Neural Computation (2007), Vol. 19(6), 1503-1527.
+// cf. http://www.ton.scphys.kyoto-u.ac.jp/~hideaki/res/histogram.html
+int bins(real[] data, int max=100)
+{
+ real m=min(data);
+ real M=max(data)*(1+epsilon);
+ real n=data.length;
+ int bins=1;
+ real minC=2n-n^2; // Cost function for N=1.
+ for(int N=2; N <= max; ++N) {
+ real C=N*(2n-sum(frequency(data,m,M,N)^2));
+ if(C < minC) {
+ minC=C;
+ bins=N;
+ }
+ }
+
+ return bins;
+}
+
+// return a pair of central Gaussian random numbers with unit variance
+pair Gaussrandpair()
+{
+ real r2,v1,v2;
+ do {
+ v1=2.0*unitrand()-1.0;
+ v2=2.0*unitrand()-1.0;
+ r2=v1*v1+v2*v2;
+ } while(r2 >= 1.0 || r2 == 0.0);
+ return (v1,v2)*sqrt(-log(r2)/r2);
+}
+
+// return a central Gaussian random number with unit variance
+real Gaussrand()
+{
+ static real sqrt2=sqrt(2.0);
+ static pair z;
+ static bool cached=true;
+ cached=!cached;
+ if(cached) return sqrt2*z.y;
+ z=Gaussrandpair();
+ return sqrt2*z.x;
+}
+
+struct linefit {
+ real m,b; // slope, intercept
+ real dm,db; // standard error in slope, intercept
+ real r; // correlation coefficient
+ real fit(real x) {
+ return m*x+b;
+ }
+}
+
+// Do a least-squares fit of data in real arrays x and y to the line y=m*x+b
+linefit leastsquares(real[] x, real[] y)
+{
+ linefit L;
+ int n=x.length;
+ if(n == 1) abort("Least squares fit requires at least 2 data points");
+ real sx=sum(x);
+ real sy=sum(y);
+ real sxx=n*sum(x^2)-sx^2;
+ real sxy=n*sum(x*y)-sx*sy;
+ L.m=sxy/sxx;
+ L.b=(sy-L.m*sx)/n;
+ if(n > 2) {
+ real syy=n*sum(y^2)-sy^2;
+ if(sxx == 0 || syy == 0) return L;
+ L.r=sxy/sqrt(sxx*syy);
+ real arg=syy-sxy^2/sxx;
+ if(arg <= 0) return L;
+ real s=sqrt(arg/(n-2));
+ L.dm=s*sqrt(1/sxx);
+ L.db=s*sqrt(1+sx^2/sxx)/n;
+ }
+ return L;
+}
diff --git a/graphics/asymptote/base/syzygy.asy b/graphics/asymptote/base/syzygy.asy
new file mode 100644
index 0000000000..93889b252e
--- /dev/null
+++ b/graphics/asymptote/base/syzygy.asy
@@ -0,0 +1,926 @@
+/***** syzygy.asy {{{1
+ * Andy Hammerlindl 2006/12/02
+ *
+ * Automates the drawing of braids, relations, and syzygies, along with the
+ * corresponding equations.
+ *
+ * See
+ * http://katlas.math.toronto.edu/drorbn/index.php?title=06-1350/Syzygies_in_Asymptote
+ * For more information.
+ *****/
+struct Component { // {{{1
+ // The number of strings coming in or out of the component.
+ int in;
+ int out;
+
+ // Which 'out' string each 'in' string is connected to. For deriving
+ // equations.
+ int[] connections;
+
+ string symbol; // For pullback notation.
+ string lsym; // For linear equations.
+ string codename; // For Mathematica code.
+
+ guide[] draw(picture pic, guide[] ins);
+}
+
+// Utility functions {{{1
+pair[] endpoints(guide[] a) {
+ pair[] z;
+ for (int i=0; i<a.length; ++i)
+ z.push(endpoint(a[i]));
+ return z;
+}
+
+pair min(pair[] z) {
+ pair m=(infinity, infinity);
+ for (int i=0; i<z.length; ++i) {
+ if (z[i].x < m.x)
+ m=(z[i].x,m.y);
+ if (z[i].y < m.y)
+ m=(m.x,z[i].y);
+ }
+ return m;
+}
+
+pair max(pair[] z) {
+ pair M=(-infinity, -infinity);
+ for (int i=0; i<z.length; ++i) {
+ if (z[i].x > M.x)
+ M=(z[i].x,M.y);
+ if (z[i].y > M.y)
+ M=(M.x,z[i].y);
+ }
+ return M;
+}
+
+// Component Definitions {{{1
+real hwratio=1.4;
+real gapfactor=6;
+
+Component bp=new Component;
+bp.in=2; bp.out=2;
+bp.connections=new int[] {1,0};
+bp.symbol="B^+"; bp.lsym="b^+"; bp.codename="bp";
+bp.draw=new guide[] (picture pic, guide[] ins) {
+ pair[] z=endpoints(ins);
+ pair m=min(z), M=max(z);
+ real w=M.x-m.x, h=hwratio*w;
+ pair centre=(0.5(m.x+M.x),M.y+h/2);
+
+ /*
+ return new guide[] {ins[1]..centre{NW}..z[0]+h*N,
+ ins[0]..centre{NE}..z[1]+h*N};
+ */
+
+ real offset=gapfactor*linewidth(currentpen);
+ draw(pic, ins[1]..(centre-offset*NW){NW});
+ return new guide[] {(centre+offset*NW){NW}..z[0]+h*N,
+ ins[0]..centre{NE}..z[1]+h*N};
+};
+
+Component bm=new Component;
+bm.in=2; bm.out=2;
+bm.connections=new int[] {1,0};
+bm.symbol="B^-"; bm.lsym="b^-"; bm.codename="bm";
+bm.draw=new guide[] (picture pic, guide[] ins) {
+ pair[] z=endpoints(ins);
+ pair m=min(z), M=max(z);
+ real w=M.x-m.x, h=hwratio*w;
+ pair centre=(0.5(m.x+M.x),M.y+h/2);
+
+ /*
+ return new guide[] {ins[1]..centre{NW}..z[0]+h*N,
+ ins[0]..centre{NE}..z[1]+h*N};
+ */
+
+ real offset=gapfactor*linewidth(currentpen);
+ draw(pic, ins[0]..(centre-offset*NE){NE});
+ return new guide[] {ins[1]..centre{NW}..z[0]+h*N,
+ (centre+offset*NE){NE}..z[1]+h*N};
+};
+
+Component phi=new Component;
+phi.in=2; phi.out=1;
+phi.connections=new int[] {0,0};
+phi.symbol="\Phi"; phi.lsym="\phi"; phi.codename="phi";
+phi.draw=new guide[] (picture pic, guide[] ins) {
+ pair[] z=endpoints(ins);
+ pair m=min(z), M=max(z);
+ real w=M.x-m.x, h=hwratio*w;
+ pair centre=(0.5(m.x+M.x),M.y+h/2);
+
+
+ //real offset=4*linewidth(currentpen);
+ draw(pic, ins[0]..centre{NE});
+ draw(pic, ins[1]..centre{NW});
+ draw(pic, centre,linewidth(5*linewidth(currentpen)));
+ dot(pic, centre);
+ return new guide[] {centre..centre+0.5h*N};
+};
+
+Component wye=new Component;
+wye.in=1; wye.out=2;
+wye.connections=null; // TODO: Fix this!
+wye.symbol="Y"; wye.lsym="y"; wye.codename="wye";
+wye.draw=new guide[] (picture pic, guide[] ins) {
+ pair z=endpoint(ins[0]);
+ real w=10, h=hwratio*w; // The 10 is a guess here, and may produce badness.
+ pair centre=(z.x,z.y+h/2);
+
+
+ draw(pic, ins[0]..centre);
+ draw(pic, centre,linewidth(5*linewidth(currentpen)));
+ return new guide[] {centre{NW}..centre+(-0.5w,0.5h),
+ centre{NE}..centre+(0.5w,0.5h)};
+};
+
+
+struct Braid { // {{{1
+ // Members {{{2
+ // Number of lines initially.
+ int n;
+
+ struct Placement {
+ Component c;
+ int place;
+
+ Placement copy() {
+ Placement p=new Placement;
+ p.c=this.c; p.place=this.place;
+ return p;
+ }
+ }
+ Placement[] places;
+
+ void add(Component c, int place) {
+ Placement p=new Placement;
+ p.c=c; p.place=place;
+ places.push(p);
+ }
+
+ void add(Braid sub, int place) {
+ for (int i=0; i<sub.places.length; ++i)
+ add(sub.places[i].c,sub.places[i].place+place);
+ }
+
+ // Drawing {{{2
+ guide[] drawStep(picture pic, Placement p, guide[] ins) {
+ int i=0,j=0;
+
+ // Draw the component.
+ Component c=p.c;
+ //write("drawing "+c.symbol+" at place "+(string)p.place);
+ guide[] couts=c.draw(pic, ins[sequence(c.in)+p.place]);
+
+ pair M=max(endpoints(couts));
+
+ // Extend lines not in the component.
+ guide[] outs;
+ pair[] z=endpoints(ins);
+ while (i<p.place) {
+ outs.push(ins[i]..(z[i].x,M.y));
+ ++i;
+ }
+
+ outs.append(couts);
+ i+=c.in;
+
+ while (i<ins.length) {
+ outs.push(ins[i]..(z[i].x,M.y));
+ ++i;
+ }
+
+ return outs;
+ }
+
+ void drawEnd(picture pic, guide[] ins, real minheight=0) {
+ pair[] z=endpoints(ins);
+ for (int i=0; i<ins.length; ++i) {
+ draw(pic, z[i].y >= minheight ? ins[i] : ins[i]..(z[i].x,minheight));
+ }
+ }
+
+ void draw(picture pic, guide[] ins, real minheight=0) {
+ int steps=places.length;
+
+ guide[] nodes=ins;
+ for (int i=0; i<steps; ++i) {
+ Placement p=places[i];
+ nodes=drawStep(pic, places[i], nodes);
+ }
+
+ drawEnd(pic, nodes, minheight);
+ }
+
+ void draw(picture pic=currentpicture, real spacing=15,
+ real minheight=2hwratio*spacing) {
+ pair[] ins;
+ for (int i=0; i<n; ++i)
+ ins.push((spacing*i,0));
+
+ draw(pic, ins, minheight);
+ }
+
+ // Utilities {{{2
+ int in() {
+ return n;
+ }
+ int out() {
+ int steps=places.length;
+ int num=n; // The number of nodes at this step.
+
+ for (int i=0; i<steps; ++i) {
+ Placement p=places[i];
+ int nextNum=num-p.c.in+p.c.out;
+ num=nextNum;
+ }
+ return num;
+ }
+
+ // Deep copy of a braid.
+ Braid copy() {
+ Braid b=new Braid;
+ b.n=this.n;
+ for (int i=0; i<this.places.length; ++i)
+ b.add(this.places[i].c,this.places[i].place);
+ return b;
+ }
+
+ // Matching {{{2
+ // Tests if a component p can be swapped with a component q which is assumed
+ // to be directly above it.
+ static bool swapable(Placement p, Placement q) {
+ return p.place + p.c.out <= q.place || // p is left of q or
+ q.place + q.c.in <= p.place; // q is left of p
+ }
+
+ // Creates a new braid with a transposition of two components.
+ Braid swap(int i, int j) {
+ if (i>j)
+ return swap(j,i);
+ else {
+ assert(j==i+1); assert(swapable(places[i],places[j]));
+
+ Placement p=places[i].copy();
+ Placement q=places[j].copy();
+ /*write("swap:");
+ write("p originally at " + (string)p.place);
+ write("q originally at " + (string)q.place);
+ write("p.c.in: " + (string)p.c.in + " p.c.out: " + (string)p.c.out);
+ write("q.c.in: " + (string)q.c.in + " q.c.out: " + (string)q.c.out);*/
+ if (q.place + q.c.in <= p.place)
+ // q is left of p - adjust for q renumbering strings.
+ p.place+=q.c.out-q.c.in;
+ else if (p.place + p.c.out <= q.place)
+ // q is right of p - adjust for p renumbering strings.
+ q.place+=p.c.in-p.c.out;
+ else
+ // q is directly on top of p
+ assert(false, "swapable");
+
+ /*write("q now at " + (string)q.place);
+ write("p now at " + (string)p.place);*/
+
+ Braid b=this.copy();
+ b.places[i]=q;
+ b.places[j]=p;
+ return b;
+ }
+ }
+
+ // Tests if the component at index 'start' can be moved to index 'end'
+ // without interfering with other components.
+ bool moveable(int start, int end) {
+ assert(start<places.length); assert(end<places.length);
+ if (start==end)
+ return true;
+ else if (end<start)
+ return moveable(end,start);
+ else {
+ assert(start<end);
+ Placement p=places[start].copy();
+ for (int step=start; step<end; ++step) {
+ Placement q=places[step+1];
+ if (q.place + q.c.in <= p.place)
+ // q is left of p - adjust for q renumbering strings.
+ p.place+=q.c.out-q.c.in;
+ else if (p.place + p.c.out <= q.place)
+ // q is right of p - nothing to do.
+ continue;
+ else
+ // q is directly on top of p
+ return false;
+ }
+ return true;
+ }
+ }
+
+ bool matchComponent(Braid sub, int subindex, int place, int step) {
+ int i=subindex;
+ return sub.places[i].c == this.places[step].c &&
+ sub.places[i].place + place == this.places[step].place;
+ }
+
+ // Returns true if a sub-braid occurs within the one at the specified
+ // coordinates with no component occuring anywhere inbetween.
+ bool exactMatch(Braid sub, int place, int step) {
+ for (int i=0; i<sub.places.length; ++i) {
+ if (!matchComponent(sub, i, place, i+step)) {
+ write("match failed at iteration: ", i);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ bool findSubsequence(Braid sub, int place, int size, int[] acc) {
+ // If we've matched all the components, we've won.
+ if (acc.length >= sub.places.length)
+ return true;
+
+ // The next component to match.
+ Placement p=sub.places[acc.length];
+
+ // Start looking immediately after the last match.
+ for (int step=acc[acc.length-1]+1; step<this.places.length; ++step) {
+ Placement q=this.places[step];
+ */
+
+ bool tryMatch(Braid sub, int place, int size, int[] acc) {
+ // If we've matched all the components, we've won.
+ if (acc.length >= sub.places.length)
+ return true;
+
+ // The next component to match.
+ Placement p=sub.places[acc.length];
+
+ // Start looking immediately after the last match.
+ for (int step=acc[acc.length-1]+1; step<this.places.length; ++step) {
+ Placement q=this.places[step];
+ // Check if the next component is in the set of strings used by the
+ // subbraid.
+ if (q.place + q.c.in > place && q.place < place + size) {
+ // It's in the window, so it must match the next component in the
+ // subbraid.
+ if (p.c==q.c && p.place+place==q.place) {
+ // A match - go on to the next component.
+ acc.push(step);
+ return tryMatch(sub, place, size, acc); // TODO: Adjust place/size.
+ }
+ else
+ return false;
+ }
+
+ // TODO: Adjust place and size.
+ }
+
+ // We've run out of components to match.
+ return false;
+ }
+
+
+ // This attempts to find a subbraid within the braid. It allows other
+ // components to be interspersed with the components of the subbraid so long
+ // as they don't occur on the same string as the ones the subbraid lies on.
+ // Returns null on failure.
+ int[] match(Braid sub, int place) {
+ for (int i=0; i<=this.places.length-sub.places.length; ++i) {
+ // Find where the first component of the subbraid matches and try to
+ // match the rest of the braid starting from there.
+ if (matchComponent(sub, 0, place, i)) {
+ int[] result;
+ result.push(i);
+ if (tryMatch(sub,place,sub.n,result))
+ return result;
+ }
+ }
+ return null;
+ }
+
+ // Equations {{{2
+ // Returns the string that 'place' moves to when going through the section
+ // with Placement p.
+ static int advancePast(Placement p, int place) {
+ // If it's to the left of the component, it is unaffected.
+ return place<p.place ? place :
+ // If it's to the right of the component, adjust the numbering due
+ // to the change of the number of strings in the component.
+ p.place+p.c.in <= place ? place - p.c.in + p.c.out :
+ // If it's in the component, ask the component to do the work.
+ p.place + p.c.connections[place-p.place];
+ }
+
+ // Adjust the place (at step 0) to the step given, to find which string it is
+ // on in that part of the diagram.
+ int advanceToStep(int step, int place) {
+ assert(place>=0 && place<n);
+ assert(step>=0 && step<places.length);
+
+ for (int i=0; i<step; ++i)
+ place=advancePast(places[i], place);
+
+ return place;
+ }
+
+ int pullbackWindowPlace(int step, int place,
+ int w_place, int w_size) {
+ place=advanceToStep(step,place);
+ return place < w_place ? 1 : // The shielding.
+ w_place + w_size <= place ? 0 : // The string doesn't touch it.
+ place-w_place+2;
+ }
+
+ int pullbackPlace(int step, int place) {
+ // Move to the right step.
+ //write("advance: ", step, place, advanceToStep(step,place));
+ //place=advanceToStep(step,place);
+ Placement p=places[step];
+ return pullbackWindowPlace(step,place, p.place, p.c.in);
+ /*return place < p.place ? 1 : // The shielding.
+ p.place + p.c.in <= place ? 0 : // The string doesn't touch it.
+ place-p.place+2;*/
+ }
+
+ int[] pullbackWindow(int step, int w_place, int w_size) {
+ int[] a={1};
+ for (int place=0; place<n; ++place)
+ a.push(pullbackWindowPlace(step, place, w_place, w_size));
+ return a;
+ }
+
+ int[] pullback(int step) {
+ Placement p=places[step];
+ return pullbackWindow(step, p.place, p.c.in);
+ /*int[] a={1};
+ for (int place=0; place<n; ++place)
+ a.push(pullbackPlace(step, place));
+ return a;*/
+ }
+
+ string stepToFormula(int step) {
+ // Determine the pullbacks.
+ string s="(1";
+ for (int place=0; place<n; ++place)
+ //write("pullback: ", step, place, pullbackString(step,place));
+ s+=(string)pullbackPlace(step, place);
+ s+=")^\star "+places[step].c.symbol;
+ return s;
+ }
+
+ // Write it as a formula with pullback notation.
+ string toFormula() {
+ if (places.length==0)
+ return "1";
+ else {
+ string s;
+ for (int step=0; step<places.length; ++step) {
+ if (step>0)
+ s+=" ";
+ s+=stepToFormula(step);
+ }
+ return s;
+ }
+ }
+
+ string windowToLinear(int step, int w_place, int w_size) {
+ int[] a=pullbackWindow(step, w_place, w_size);
+ string s="(";
+ for (int arg=1; arg<=w_size+1; ++arg) {
+ if (arg>1)
+ s+=",";
+ bool first=true;
+ for (int var=0; var<a.length; ++var) {
+ if (a[var]==arg) {
+ if (first)
+ first=false;
+ else
+ s+="+";
+ s+="x_"+(string)(var+1);
+ }
+ }
+ }
+ return s+")";
+ }
+
+ string windowToCode(int step, int w_place, int w_size) {
+ int[] a=pullbackWindow(step, w_place, w_size);
+ string s="[";
+ for (int arg=1; arg<=w_size+1; ++arg) {
+ if (arg>1)
+ s+=", ";
+ bool first=true;
+ for (int var=0; var<a.length; ++var) {
+ if (a[var]==arg) {
+ if (first)
+ first=false;
+ else
+ s+=" + ";
+ s+="x"+(string)(var+1);
+ }
+ }
+ }
+ return s+"]";
+ }
+
+ string stepToLinear(int step) {
+ //int[] a=pullback(step);
+ Placement p=places[step];
+ return p.c.lsym+windowToLinear(step, p.place, p.c.in);
+
+ /*string s=p.c.lsym+"(";
+ for (int arg=1; arg<=p.c.in+1; ++arg) {
+ if (arg>1)
+ s+=",";
+ bool first=true;
+ for (int var=0; var<a.length; ++var) {
+ if (a[var]==arg) {
+ if (first)
+ first=false;
+ else
+ s+="+";
+ s+="x_"+(string)(var+1);
+ }
+ }
+ }
+ return s+")";*/
+ }
+
+ string stepToCode(int step) {
+ Placement p=places[step];
+ return p.c.codename+windowToCode(step, p.place, p.c.in);
+ }
+
+ string toLinear(bool subtract=false) {
+ if (places.length==0)
+ return subtract ? "0" : ""; // or "1" ?
+ else {
+ string s = subtract ? " - " : "";
+ for (int step=0; step<places.length; ++step) {
+ if (step>0)
+ s+= subtract ? " - " : " + ";
+ s+=stepToLinear(step);
+ }
+ return s;
+ }
+ }
+
+ string toCode(bool subtract=false) {
+ if (places.length==0)
+ return subtract ? "0" : ""; // or "1" ?
+ else {
+ string s = subtract ? " - " : "";
+ for (int step=0; step<places.length; ++step) {
+ if (step>0)
+ s+= subtract ? " - " : " + ";
+ s+=stepToCode(step);
+ }
+ return s;
+ }
+ }
+}
+
+struct Relation { // {{{1
+ Braid lhs, rhs;
+
+ string lsym, codename;
+ bool inverted=false;
+
+ string toFormula() {
+ return lhs.toFormula() + " = " + rhs.toFormula();
+ }
+
+ string linearName() {
+ assert(lhs.n==rhs.n);
+ assert(lsym!="");
+
+ string s=(inverted ? "-" : "") + lsym+"(";
+ for (int i=1; i<=lhs.n+1; ++i) {
+ if (i>1)
+ s+=",";
+ s+="x_"+(string)i;
+ }
+ return s+")";
+ }
+
+ string fullCodeName() {
+ assert(lhs.n==rhs.n);
+ assert(codename!="");
+
+ string s=(inverted ? "minus" : "") + codename+"[";
+ for (int i=1; i<=lhs.n+1; ++i) {
+ if (i>1)
+ s+=", ";
+ s+="x"+(string)i+"_";
+ }
+ return s+"]";
+ }
+
+ string toLinear() {
+ return linearName() + " = " + lhs.toLinear() + rhs.toLinear(true);
+ }
+
+ string toCode() {
+ return fullCodeName() + " :> " + lhs.toCode() + rhs.toCode(true);
+ }
+
+ void draw(picture pic=currentpicture) {
+ picture left; lhs.draw(left);
+ frame l=left.fit();
+ picture right; rhs.draw(right);
+ frame r=right.fit();
+
+ real xpad=30;
+
+ add(pic, l);
+ label(pic, "=", (max(l).x + 0.5xpad, 0.25(max(l).y+max(r).y)));
+ add(pic, r, (max(l).x+xpad,0));
+ }
+}
+
+Relation operator- (Relation r) {
+ Relation opposite;
+ opposite.lhs=r.rhs;
+ opposite.rhs=r.lhs;
+ opposite.lsym=r.lsym;
+ opposite.codename=r.codename;
+ opposite.inverted=!r.inverted;
+ return opposite;
+}
+
+
+Braid apply(Relation r, Braid b, int step, int place) {
+ bool valid=b.exactMatch(r.lhs,place,step);
+ if (valid) {
+ Braid result=new Braid;
+ result.n=b.n;
+ for (int i=0; i<step; ++i)
+ result.places.push(b.places[i]);
+ result.add(r.rhs,place);
+ for (int i=step+r.lhs.places.length; i<b.places.length; ++i)
+ result.places.push(b.places[i]);
+ return result;
+ }
+ else {
+ write("Invalid match!");
+ return null;
+ }
+}
+
+// Tableau {{{1
+
+// Draw a number of frames in a nice circular arrangement.
+picture tableau(frame[] cards, bool number=false) {
+ int n=cards.length;
+
+ // Calculate the max height and width of the frames (assuming min(f)=(0,0)).
+ pair M=(0,0);
+ for (int i=0; i<n; ++i) {
+ pair z=max(cards[i]);
+ if (z.x > M.x)
+ M=(z.x,M.y);
+ if (z.y > M.y)
+ M=(M.x,z.y);
+ }
+
+ picture pic;
+ real xpad=2.0, ypad=1.3;
+ void place(int index, real row, real column) {
+ pair z=((M.x*xpad)*column,(M.y*ypad)*row);
+ add(pic, cards[index], z);
+ if (number) {
+ label(pic,(string)index, z+(0.5M.x,0), S);
+ }
+ }
+
+ // Handle small collections.
+ if (n<=4) {
+ for (int i=0; i<n; ++i)
+ place(i,0,i);
+ }
+ else {
+ int rows=quotient(n-1,2), columns=3;
+
+ // Add the top middle card.
+ place(0,rows-1,1);
+
+ // place cards down the right side.
+ for (int i=1; i<rows; ++i)
+ place(i, rows-i,2);
+
+ // place cards at the bottom.
+ if (n%2==0) {
+ place(rows,0,2);
+ place(rows+1,0,1);
+ place(rows+2,0,0);
+ }
+ else {
+ place(rows,0,1.5);
+ place(rows+1,0,0.5);
+ }
+
+ // place cards up the left side.
+ for (int i=1; i<rows; ++i)
+ place(i+n-rows,i,0);
+ }
+
+ return pic;
+}
+
+struct Syzygy { // {{{1
+ // Setup {{{2
+ Braid initial=null;
+ bool cyclic=true;
+ bool showall=false;
+ bool number=false; // Number the diagrams when drawn.
+
+ string lsym, codename;
+
+ bool watched=false;
+ bool uptodate=true;
+
+ struct Move {
+ Braid action(Braid);
+ Relation rel;
+ int place, step;
+ }
+
+ Move[] moves;
+
+ void apply(Relation r, int step, int place) {
+ Move m=new Move;
+ m.rel=r;
+ m.place=place; m.step=step;
+ m.action=new Braid (Braid b) {
+ return apply(r, b, step, place);
+ };
+ moves.push(m);
+
+ uptodate = false;
+ }
+
+ void swap(int i, int j) {
+ Move m=new Move;
+ m.rel=null;
+ m.action=new Braid (Braid b) {
+ return b.swap(i, j);
+ };
+ moves.push(m);
+
+ uptodate = false;
+ }
+
+ // Drawing {{{2
+ picture[] drawMoves() {
+ picture[] pics;
+
+ assert(initial!=null, "must set initial braid");
+ Braid b=initial;
+
+ picture pic;
+ b.draw(pic);
+ pics.push(pic);
+
+ for (int i=0; i<moves.length; ++i) {
+ b=moves[i].action(b);
+ if (showall || moves[i].rel != null) {
+ picture pic;
+ b.draw(pic);
+ pics.push(pic);
+ }
+ }
+
+ // Remove the last picture.
+ if (this.cyclic)
+ pics.pop();
+
+ return pics;
+ }
+
+ void draw(picture pic=currentpicture) {
+ pic.add(tableau(fit(drawMoves()), this.number));
+ }
+
+ void updatefunction() {
+ if (!uptodate) {
+ picture pic; this.draw(pic);
+ shipout(pic);
+ uptodate = true;
+ }
+ }
+
+ void oldupdatefunction() = null;
+
+ void watch() {
+ if (!watched) {
+ watched = true;
+ oldupdatefunction = atupdate();
+ atupdate(this.updatefunction);
+ uptodate = false;
+ }
+ }
+
+ void unwatch() {
+ assert(watched == true);
+ atupdate(oldupdatefunction);
+ uptodate = false;
+ }
+
+ // Writing {{{2
+ string linearName() {
+ assert(lsym!="");
+
+ string s=lsym+"(";
+ for (int i=1; i<=initial.n+1; ++i) {
+ if (i>1)
+ s+=",";
+ s+="x_"+(string)i;
+ }
+ return s+")";
+ }
+
+ string fullCodeName() {
+ assert(codename!="");
+
+ string s=codename+"[";
+ for (int i=1; i<=initial.n+1; ++i) {
+ if (i>1)
+ s+=", ";
+ s+="x"+(string)i+"_";
+ }
+ return s+"]";
+ }
+
+ string toLinear() {
+ string s=linearName()+" = ";
+
+ Braid b=initial;
+ bool first=true;
+ for (int i=0; i<moves.length; ++i) {
+ Move m=moves[i];
+ if (m.rel != null) {
+ if (first) {
+ first=false;
+ if (m.rel.inverted)
+ s+=" - ";
+ }
+ else
+ s+=m.rel.inverted ? " - " : " + ";
+ s+=m.rel.lsym+b.windowToLinear(m.step, m.place, m.rel.lhs.n);
+ }
+ b=m.action(b);
+ }
+
+ return s;
+ }
+
+ string toCode() {
+ string s=fullCodeName()+" :> ";
+
+ Braid b=initial;
+ bool first=true;
+ for (int i=0; i<moves.length; ++i) {
+ Move m=moves[i];
+ if (m.rel != null) {
+ if (first) {
+ first=false;
+ if (m.rel.inverted)
+ s+=" - ";
+ }
+ else
+ s+=m.rel.inverted ? " - " : " + ";
+ s+=m.rel.codename+b.windowToCode(m.step, m.place, m.rel.lhs.n);
+ }
+ b=m.action(b);
+ }
+
+ return s;
+ }
+
+}
+
+// Relation definitions {{{1
+// If you define more relations that you think would be useful, please email
+// them to me, and I'll add them to the script. --Andy.
+Relation r3;
+r3.lhs.n=3;
+r3.lsym="\rho_3"; r3.codename="rho3";
+r3.lhs.add(bp,0); r3.lhs.add(bp,1); r3.lhs.add(bp,0);
+r3.rhs.n=3;
+r3.rhs.add(bp,1); r3.rhs.add(bp,0); r3.rhs.add(bp,1);
+
+Relation r4a;
+r4a.lhs.n=3;
+r4a.lsym="\rho_{4a}"; r4a.codename="rho4a";
+r4a.lhs.add(bp,0); r4a.lhs.add(bp,1); r4a.lhs.add(phi,0);
+r4a.rhs.n=3;
+r4a.rhs.add(phi,1); r4a.rhs.add(bp,0);
+
+Relation r4b;
+r4b.lhs.n=3;
+r4b.lsym="\rho_{4b}"; r4b.codename="rho4b";
+r4b.lhs.add(bp,1); r4b.lhs.add(bp,0); r4b.lhs.add(phi,1);
+r4b.rhs.n=3;
+r4b.rhs.add(phi,0); r4b.rhs.add(bp,0);
+
diff --git a/graphics/asymptote/base/texcolors.asy b/graphics/asymptote/base/texcolors.asy
new file mode 100644
index 0000000000..90d9606cb7
--- /dev/null
+++ b/graphics/asymptote/base/texcolors.asy
@@ -0,0 +1,68 @@
+pen GreenYellow=cmyk(0.15,0,0.69,0);
+pen Yellow=cmyk(0,0,1,0);
+pen Goldenrod=cmyk(0,0.10,0.84,0);
+pen Dandelion=cmyk(0,0.29,0.84,0);
+pen Apricot=cmyk(0,0.32,0.52,0);
+pen Peach=cmyk(0,0.50,0.70,0);
+pen Melon=cmyk(0,0.46,0.50,0);
+pen YellowOrange=cmyk(0,0.42,1,0);
+pen Orange=cmyk(0,0.61,0.87,0);
+pen BurntOrange=cmyk(0,0.51,1,0);
+pen Bittersweet=cmyk(0,0.75,1,0.24);
+pen RedOrange=cmyk(0,0.77,0.87,0);
+pen Mahogany=cmyk(0,0.85,0.87,0.35);
+pen Maroon=cmyk(0,0.87,0.68,0.32);
+pen BrickRed=cmyk(0,0.89,0.94,0.28);
+pen Red=cmyk(0,1,1,0);
+pen OrangeRed=cmyk(0,1,0.50,0);
+pen RubineRed=cmyk(0,1,0.13,0);
+pen WildStrawberry=cmyk(0,0.96,0.39,0);
+pen Salmon=cmyk(0,0.53,0.38,0);
+pen CarnationPink=cmyk(0,0.63,0,0);
+pen Magenta=cmyk(0,1,0,0);
+pen VioletRed=cmyk(0,0.81,0,0);
+pen Rhodamine=cmyk(0,0.82,0,0);
+pen Mulberry=cmyk(0.34,0.90,0,0.02);
+pen RedViolet=cmyk(0.07,0.90,0,0.34);
+pen Fuchsia=cmyk(0.47,0.91,0,0.08);
+pen Lavender=cmyk(0,0.48,0,0);
+pen Thistle=cmyk(0.12,0.59,0,0);
+pen Orchid=cmyk(0.32,0.64,0,0);
+pen DarkOrchid=cmyk(0.40,0.80,0.20,0);
+pen Purple=cmyk(0.45,0.86,0,0);
+pen Plum=cmyk(0.50,1,0,0);
+pen Violet=cmyk(0.79,0.88,0,0);
+pen RoyalPurple=cmyk(0.75,0.90,0,0);
+pen BlueViolet=cmyk(0.86,0.91,0,0.04);
+pen Periwinkle=cmyk(0.57,0.55,0,0);
+pen CadetBlue=cmyk(0.62,0.57,0.23,0);
+pen CornflowerBlue=cmyk(0.65,0.13,0,0);
+pen MidnightBlue=cmyk(0.98,0.13,0,0.43);
+pen NavyBlue=cmyk(0.94,0.54,0,0);
+pen RoyalBlue=cmyk(1,0.50,0,0);
+pen Blue=cmyk(1,1,0,0);
+pen Cerulean=cmyk(0.94,0.11,0,0);
+pen Cyan=cmyk(1,0,0,0);
+pen ProcessBlue=cmyk(0.96,0,0,0);
+pen SkyBlue=cmyk(0.62,0,0.12,0);
+pen Turquoise=cmyk(0.85,0,0.20,0);
+pen TealBlue=cmyk(0.86,0,0.34,0.02);
+pen Aquamarine=cmyk(0.82,0,0.30,0);
+pen BlueGreen=cmyk(0.85,0,0.33,0);
+pen Emerald=cmyk(1,0,0.50,0);
+pen JungleGreen=cmyk(0.99,0,0.52,0);
+pen SeaGreen=cmyk(0.69,0,0.50,0);
+pen Green=cmyk(1,0,1,0);
+pen ForestGreen=cmyk(0.91,0,0.88,0.12);
+pen PineGreen=cmyk(0.92,0,0.59,0.25);
+pen LimeGreen=cmyk(0.50,0,1,0);
+pen YellowGreen=cmyk(0.44,0,0.74,0);
+pen SpringGreen=cmyk(0.26,0,0.76,0);
+pen OliveGreen=cmyk(0.64,0,0.95,0.40);
+pen RawSienna=cmyk(0,0.72,1,0.45);
+pen Sepia=cmyk(0,0.83,1,0.70);
+pen Brown=cmyk(0,0.81,1,0.60);
+pen Tan=cmyk(0.14,0.42,0.56,0);
+pen Gray=cmyk(0,0,0,0.50);
+pen Black=cmyk(0,0,0,1);
+pen White=cmyk(0,0,0,0);
diff --git a/graphics/asymptote/base/three.asy b/graphics/asymptote/base/three.asy
new file mode 100644
index 0000000000..866137b1db
--- /dev/null
+++ b/graphics/asymptote/base/three.asy
@@ -0,0 +1,3251 @@
+private import math;
+
+if(settings.xasy)
+ settings.render=0;
+
+if(prc0()) {
+ if(!latex()) settings.prc=false;
+ else {
+ access embed;
+ Embed=embed.embedplayer;
+ }
+}
+
+// Useful lossy compression values.
+restricted real Zero=0;
+restricted real Low=0.0001;
+restricted real Medium=0.001;
+restricted real High=0.01;
+
+restricted int PRCsphere=0; // Renders slowly but produces smaller PRC files.
+restricted int NURBSsphere=1; // Renders fast but produces larger PRC files.
+
+struct render
+{
+ // PRC parameters:
+ real compression; // lossy compression parameter (0=no compression)
+ real granularity; // PRC rendering granularity
+
+ bool closed; // use one-sided rendering?
+ bool tessellate; // use tessellated mesh to store straight patches?
+
+ bool3 merge; // merge nodes before rendering, for faster but
+ // lower quality PRC rendering (the value default means
+ // merge opaque patches only).
+
+ int sphere; // PRC sphere type (PRCsphere or NURBSsphere).
+
+ // General parameters:
+ real margin; // shrink amount for rendered openGL viewport, in bp.
+ real tubegranularity; // granularity for rendering tubes
+ bool labelfill; // fill subdivision cracks in unlighted labels
+
+ bool partnames; // assign part name indices to compound objects
+ bool defaultnames; // assign default names to unnamed objects
+
+ static render defaultrender;
+
+ void operator init(real compression=defaultrender.compression,
+ real granularity=defaultrender.granularity,
+ bool closed=defaultrender.closed,
+ bool tessellate=defaultrender.tessellate,
+ bool3 merge=defaultrender.merge,
+ int sphere=defaultrender.sphere,
+ real margin=defaultrender.margin,
+ real tubegranularity=defaultrender.tubegranularity,
+ bool labelfill=defaultrender.labelfill,
+ bool partnames=defaultrender.partnames,
+ bool defaultnames=defaultrender.defaultnames)
+ {
+ this.compression=compression;
+ this.granularity=granularity;
+ this.closed=closed;
+ this.tessellate=tessellate;
+ this.merge=merge;
+ this.sphere=sphere;
+ this.margin=margin;
+ this.tubegranularity=tubegranularity;
+ this.labelfill=labelfill;
+ this.partnames=partnames;
+ this.defaultnames=defaultnames;
+ }
+}
+
+render operator init() {return render();}
+
+render defaultrender=render.defaultrender=new render;
+defaultrender.compression=High;
+defaultrender.granularity=Medium;
+defaultrender.closed=false;
+defaultrender.tessellate=false;
+defaultrender.merge=false;
+defaultrender.margin=0.02;
+defaultrender.tubegranularity=0.001;
+defaultrender.sphere=NURBSsphere;
+defaultrender.labelfill=true;
+defaultrender.partnames=false;
+defaultrender.defaultnames=true;
+
+real defaultshininess=0.7;
+real defaultmetallic=0.0;
+real defaultfresnel0=0.04;
+
+
+
+real angleprecision=1e-5; // Precision for centering perspective projections.
+int maxangleiterations=25;
+
+string defaultembed3Doptions="3Dmenu";
+string defaultembed3Dscript;
+real defaulteyetoview=63mm/1000mm;
+
+string partname(int i, render render=defaultrender)
+{
+ return render.partnames ? string(i+1) : "";
+}
+
+triple O=(0,0,0);
+triple X=(1,0,0), Y=(0,1,0), Z=(0,0,1);
+
+// A translation in 3D space.
+transform3 shift(triple v)
+{
+ transform3 t=identity(4);
+ t[0][3]=v.x;
+ t[1][3]=v.y;
+ t[2][3]=v.z;
+ return t;
+}
+
+// Avoid two parentheses.
+transform3 shift(real x, real y, real z)
+{
+ return shift((x,y,z));
+}
+
+transform3 shift(transform3 t)
+{
+ transform3 T=identity(4);
+ T[0][3]=t[0][3];
+ T[1][3]=t[1][3];
+ T[2][3]=t[2][3];
+ return T;
+}
+
+// A 3D scaling in the x direction.
+transform3 xscale3(real x)
+{
+ transform3 t=identity(4);
+ t[0][0]=x;
+ return t;
+}
+
+// A 3D scaling in the y direction.
+transform3 yscale3(real y)
+{
+ transform3 t=identity(4);
+ t[1][1]=y;
+ return t;
+}
+
+// A 3D scaling in the z direction.
+transform3 zscale3(real z)
+{
+ transform3 t=identity(4);
+ t[2][2]=z;
+ return t;
+}
+
+// A 3D scaling by s in the v direction.
+transform3 scale(triple v, real s)
+{
+ v=unit(v);
+ s -= 1;
+ return new real[][] {
+ {1+s*v.x^2, s*v.x*v.y, s*v.x*v.z, 0},
+ {s*v.x*v.y, 1+s*v.y^2, s*v.y*v.z, 0},
+ {s*v.x*v.z, s*v.y*v.z, 1+s*v.z^2, 0},
+ {0, 0, 0, 1}};
+}
+
+// A transformation representing rotation by an angle in degrees about
+// an axis v through the origin (in the right-handed direction).
+transform3 rotate(real angle, triple v)
+{
+ if(v == O) abort("cannot rotate about the zero vector");
+ v=unit(v);
+ real x=v.x, y=v.y, z=v.z;
+ real s=Sin(angle), c=Cos(angle), t=1-c;
+
+ return new real[][] {
+ {t*x^2+c, t*x*y-s*z, t*x*z+s*y, 0},
+ {t*x*y+s*z, t*y^2+c, t*y*z-s*x, 0},
+ {t*x*z-s*y, t*y*z+s*x, t*z^2+c, 0},
+ {0, 0, 0, 1}};
+}
+
+// A transformation representing rotation by an angle in degrees about
+// the line u--v (in the right-handed direction).
+transform3 rotate(real angle, triple u, triple v)
+{
+ return shift(u)*rotate(angle,v-u)*shift(-u);
+}
+
+// Reflects about the plane through u, v, and w.
+transform3 reflect(triple u, triple v, triple w)
+{
+ triple n=unit(cross(v-u,w-u));
+ if(n == O)
+ abort("points determining reflection plane cannot be colinear");
+
+ return new real[][] {
+ {1-2*n.x^2, -2*n.x*n.y, -2*n.x*n.z, u.x},
+ {-2*n.x*n.y, 1-2*n.y^2, -2*n.y*n.z, u.y},
+ {-2*n.x*n.z, -2*n.y*n.z, 1-2*n.z^2, u.z},
+ {0, 0, 0, 1}
+ }*shift(-u);
+}
+
+// Project u onto v.
+triple project(triple u, triple v)
+{
+ v=unit(v);
+ return dot(u,v)*v;
+}
+
+// Return a unit vector perpendicular to a given unit vector v.
+triple perp(triple v)
+{
+ triple u=cross(v,Y);
+ if(abs(u) > sqrtEpsilon) return unit(u);
+ u=cross(v,Z);
+ return (abs(u) > sqrtEpsilon) ? unit(u) : X;
+}
+
+// Return the transformation corresponding to moving the camera from the target
+// (looking in the negative z direction) to the point 'eye' (looking at target,
+// orienting the camera so that direction 'up' points upwards.
+// Since, in actuality, we are transforming the points instead of the camera,
+// we calculate the inverse matrix.
+// Based on the gluLookAt implementation in the OpenGL manual.
+transform3 look(triple eye, triple up=Z, triple target=O)
+{
+ triple f=unit(target-eye);
+ if(f == O)
+ f=-Z; // The eye is already at the origin: look down.
+
+ triple s=cross(f,up);
+
+ // If the eye is pointing either directly up or down, there is no
+ // preferred "up" direction. Pick one arbitrarily.
+ s=s != O ? unit(s) : perp(f);
+
+ triple u=cross(s,f);
+
+ transform3 M={{ s.x, s.y, s.z, 0},
+ { u.x, u.y, u.z, 0},
+ {-f.x, -f.y, -f.z, 0},
+ { 0, 0, 0, 1}};
+
+ return M*shift(-eye);
+}
+
+// Return a matrix to do perspective distortion based on a triple v.
+transform3 distort(triple v)
+{
+ transform3 t=identity(4);
+ real d=length(v);
+ if(d == 0) return t;
+ t[3][2]=-1/d;
+ t[3][3]=0;
+ return t;
+}
+
+projection operator * (transform3 t, projection P)
+{
+ projection P=P.copy();
+ if(!P.absolute) {
+ P.camera=t*P.camera;
+ triple target=P.target;
+ P.target=t*P.target;
+ if(P.infinity)
+ P.normal=t*(target+P.normal)-P.target;
+ else
+ P.normal=P.vector();
+ P.calculate();
+ }
+ return P;
+}
+
+// With this, save() and restore() in plain also save and restore the
+// currentprojection.
+addSaveFunction(new restoreThunk() {
+ projection P=currentprojection.copy();
+ return new void() {
+ currentprojection=P;
+ };
+ });
+
+pair project(triple v, projection P=currentprojection)
+{
+ return project(v,P.t);
+}
+
+pair dir(triple v, triple dir, projection P)
+{
+ return unit(project(v+0.5dir,P)-project(v-0.5*dir,P));
+}
+
+// Uses the homogenous coordinate to perform perspective distortion.
+// When combined with a projection to the XY plane, this effectively maps
+// points in three space to a plane through target and
+// perpendicular to the vector camera-target.
+projection perspective(triple camera, triple up=Z, triple target=O,
+ real zoom=1, real angle=0, pair viewportshift=0,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=autoadjust)
+{
+ if(camera == target)
+ abort("camera cannot be at target");
+ return projection(camera,up,target,zoom,angle,viewportshift,
+ showtarget,autoadjust,center,
+ new transformation(triple camera, triple up, triple target)
+ {return transformation(look(camera,up,target),
+ distort(camera-target));});
+}
+
+projection perspective(real x, real y, real z, triple up=Z, triple target=O,
+ real zoom=1, real angle=0, pair viewportshift=0,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=autoadjust)
+{
+ return perspective((x,y,z),up,target,zoom,angle,viewportshift,showtarget,
+ autoadjust,center);
+}
+
+projection orthographic(triple camera, triple up=Z, triple target=O,
+ real zoom=1, pair viewportshift=0,
+ bool showtarget=true, bool center=false)
+{
+ return projection(camera,up,target,zoom,viewportshift,showtarget,
+ center=center,new transformation(triple camera, triple up,
+ triple target) {
+ return transformation(look(camera,up,target));});
+}
+
+projection orthographic(real x, real y, real z, triple up=Z,
+ triple target=O, real zoom=1, pair viewportshift=0,
+ bool showtarget=true, bool center=false)
+{
+ return orthographic((x,y,z),up,target,zoom,viewportshift,showtarget,
+ center=center);
+}
+
+// Compute camera position with x axis below the horizontal at angle alpha,
+// y axis below the horizontal at angle beta, and z axis up.
+triple camera(real alpha, real beta)
+{
+ real denom=Tan(alpha+beta);
+ real Tanalpha=Tan(alpha);
+ real Tanbeta=Tan(beta);
+ return (sqrt(Tanalpha/denom),sqrt(Tanbeta/denom),sqrt(Tanalpha*Tanbeta));
+}
+
+projection oblique(real angle=45)
+{
+ transform3 t=identity(4);
+ real c2=Cos(angle)^2;
+ real s2=1-c2;
+ t[0][2]=-c2;
+ t[1][2]=-s2;
+ t[2][2]=1;
+ t[2][3]=-1;
+ return projection((c2,s2,1),up=Y,normal=(0,0,1),
+ new transformation(triple,triple,triple) {
+ return transformation(t);});
+}
+
+projection obliqueZ(real angle=45) {return oblique(angle);}
+
+projection obliqueX(real angle=45)
+{
+ transform3 t=identity(4);
+ real c2=Cos(angle)^2;
+ real s2=1-c2;
+ t[0][0]=-c2;
+ t[1][0]=-s2;
+ t[1][1]=0;
+ t[0][1]=1;
+ t[1][2]=1;
+ t[2][2]=0;
+ t[2][0]=1;
+ t[2][3]=-1;
+ return projection((1,c2,s2),normal=(1,0,0),
+ new transformation(triple,triple,triple) {
+ return transformation(t);});
+}
+
+projection obliqueY(real angle=45)
+{
+ transform3 t=identity(4);
+ real c2=Cos(angle)^2;
+ real s2=1-c2;
+ t[0][1]=c2;
+ t[1][1]=s2;
+ t[1][2]=1;
+ t[2][1]=-1;
+ t[2][2]=0;
+ t[2][3]=-1;
+ return projection((c2,-1,s2),normal=(0,-1,0),
+ new transformation(triple,triple,triple) {
+ return transformation(t);});
+}
+
+projection oblique=oblique();
+projection obliqueX=obliqueX(), obliqueY=obliqueY(), obliqueZ=obliqueZ();
+
+projection LeftView=orthographic(-X,showtarget=true);
+projection RightView=orthographic(X,showtarget=true);
+projection FrontView=orthographic(-Y,showtarget=true);
+projection BackView=orthographic(Y,showtarget=true);
+projection BottomView=orthographic(-Z,up=-Y,showtarget=true);
+projection TopView=orthographic(Z,up=Y,showtarget=true);
+
+currentprojection=perspective(5,4,2);
+
+projection projection()
+{
+ projection P;
+ real[] a=_projection();
+ if(a.length == 0 || a[10] == 0.0) return currentprojection;
+ int k=0;
+ return a[0] == 1 ?
+ orthographic((a[++k],a[++k],a[++k]),(a[++k],a[++k],a[++k]),
+ (a[++k],a[++k],a[++k]),a[++k],(a[k += 2],a[++k])) :
+ perspective((a[++k],a[++k],a[++k]),(a[++k],a[++k],a[++k]),
+ (a[++k],a[++k],a[++k]),a[++k],a[++k],(a[++k],a[++k]));
+}
+
+// Map pair z to a triple by inverting the projection P onto the
+// plane perpendicular to normal and passing through point.
+triple invert(pair z, triple normal, triple point,
+ projection P=currentprojection)
+{
+ transform3 t=P.t;
+ real[][] A={{t[0][0]-z.x*t[3][0],t[0][1]-z.x*t[3][1],t[0][2]-z.x*t[3][2]},
+ {t[1][0]-z.y*t[3][0],t[1][1]-z.y*t[3][1],t[1][2]-z.y*t[3][2]},
+ {normal.x,normal.y,normal.z}};
+ real[] b={z.x*t[3][3]-t[0][3],z.y*t[3][3]-t[1][3],dot(normal,point)};
+ real[] x=solve(A,b,warn=false);
+ return x.length > 0 ? (x[0],x[1],x[2]) : P.camera;
+}
+
+// Map pair to a triple on the projection plane.
+triple invert(pair z, projection P=currentprojection)
+{
+ return invert(z,P.normal,P.target,P);
+}
+
+// Map pair dir to a triple direction at point v on the projection plane.
+triple invert(pair dir, triple v, projection P=currentprojection)
+{
+ return invert(project(v,P)+dir,P.normal,v,P)-v;
+}
+
+pair xypart(triple v)
+{
+ return (v.x,v.y);
+}
+
+struct control {
+ triple post,pre;
+ bool active=false;
+ bool straight=true;
+ void operator init(triple post, triple pre, bool straight=false) {
+ this.post=post;
+ this.pre=pre;
+ active=true;
+ this.straight=straight;
+ }
+}
+
+control nocontrol;
+
+control operator * (transform3 t, control c)
+{
+ control C;
+ C.post=t*c.post;
+ C.pre=t*c.pre;
+ C.active=c.active;
+ C.straight=c.straight;
+ return C;
+}
+
+void write(file file, control c)
+{
+ write(file,".. controls ");
+ write(file,c.post);
+ write(file," and ");
+ write(file,c.pre);
+}
+
+struct Tension {
+ real out,in;
+ bool atLeast;
+ bool active;
+ void operator init(real out=1, real in=1, bool atLeast=false,
+ bool active=true) {
+ real check(real val) {
+ if(val < 0.75) abort("tension cannot be less than 3/4");
+ return val;
+ }
+ this.out=check(out);
+ this.in=check(in);
+ this.atLeast=atLeast;
+ this.active=active;
+ }
+}
+
+Tension operator init()
+{
+ return Tension();
+}
+
+Tension noTension;
+noTension.active=false;
+
+void write(file file, Tension t)
+{
+ write(file,"..tension ");
+ if(t.atLeast) write(file,"atleast ");
+ write(file,t.out);
+ write(file," and ");
+ write(file,t.in);
+}
+
+struct dir {
+ triple dir;
+ real gamma=1; // endpoint curl
+ bool Curl; // curl specified
+ bool active() {
+ return dir != O || Curl;
+ }
+ void init(triple v) {
+ this.dir=v;
+ }
+ void init(real gamma) {
+ if(gamma < 0) abort("curl cannot be less than 0");
+ this.gamma=gamma;
+ this.Curl=true;
+ }
+ void init(dir d) {
+ dir=d.dir;
+ gamma=d.gamma;
+ Curl=d.Curl;
+ }
+ void default(triple v) {
+ if(!active()) init(v);
+ }
+ void default(dir d) {
+ if(!active()) init(d);
+ }
+ dir copy() {
+ dir d=new dir;
+ d.init(this);
+ return d;
+ }
+}
+
+void write(file file, dir d)
+{
+ if(d.dir != O) {
+ write(file,"{"); write(file,unit(d.dir)); write(file,"}");
+ } else if(d.Curl) {
+ write(file,"{curl "); write(file,d.gamma); write(file,"}");
+ }
+}
+
+dir operator * (transform3 t, dir d)
+{
+ dir D=d.copy();
+ D.init(unit(shiftless(t)*d.dir));
+ return D;
+}
+
+void checkEmpty(int n) {
+ if(n == 0)
+ abort("nullpath3 has no points");
+}
+
+int adjustedIndex(int i, int n, bool cycles)
+{
+ checkEmpty(n);
+ if(cycles)
+ return i % n;
+ else if(i < 0)
+ return 0;
+ else if(i >= n)
+ return n-1;
+ else
+ return i;
+}
+
+struct flatguide3 {
+ triple[] nodes;
+ bool[] cyclic; // true if node is really a cycle
+ control[] control; // control points for segment starting at node
+ Tension[] Tension; // Tension parameters for segment starting at node
+ dir[] in,out; // in and out directions for segment starting at node
+
+ bool cyclic() {int n=cyclic.length; return n > 0 ? cyclic[n-1] : false;}
+ bool precyclic() {int i=find(cyclic); return i >= 0 && i < cyclic.length-1;}
+
+ int size() {
+ return cyclic() ? nodes.length-1 : nodes.length;
+ }
+
+ void node(triple v, bool b=false) {
+ nodes.push(v);
+ control.push(nocontrol);
+ Tension.push(noTension);
+ in.push(new dir);
+ out.push(new dir);
+ cyclic.push(b);
+ }
+
+ void control(triple post, triple pre) {
+ if(control.length > 0) {
+ control c=control(post,pre,false);
+ control[control.length-1]=c;
+ }
+ }
+
+ void Tension(real out, real in, bool atLeast) {
+ if(Tension.length > 0)
+ Tension[Tension.length-1]=Tension(out,in,atLeast,true);
+ }
+
+ void in(triple v) {
+ if(in.length > 0) {
+ in[in.length-1].init(v);
+ }
+ }
+
+ void out(triple v) {
+ if(out.length > 0) {
+ out[out.length-1].init(v);
+ }
+ }
+
+ void in(real gamma) {
+ if(in.length > 0) {
+ in[in.length-1].init(gamma);
+ }
+ }
+
+ void out(real gamma) {
+ if(out.length > 0) {
+ out[out.length-1].init(gamma);
+ }
+ }
+
+ void cycleToken() {
+ if(nodes.length > 0)
+ node(nodes[0],true);
+ }
+
+ // Return true if outgoing direction at node i is known.
+ bool solved(int i) {
+ return out[i].active() || control[i].active;
+ }
+}
+
+void write(file file, string s="", explicit flatguide3 x, suffix suffix=none)
+{
+ write(file,s);
+ if(x.size() == 0) write(file,"<nullpath3>");
+ else for(int i=0; i < x.nodes.length; ++i) {
+ if(i > 0) write(file,endl);
+ if(x.cyclic[i]) write(file,"cycle");
+ else write(file,x.nodes[i]);
+ if(i < x.nodes.length-1) {
+ // Explicit control points trump other specifiers
+ if(x.control[i].active)
+ write(file,x.control[i]);
+ else {
+ write(file,x.out[i]);
+ if(x.Tension[i].active) write(file,x.Tension[i]);
+ }
+ write(file,"..");
+ if(!x.control[i].active) write(file,x.in[i]);
+ }
+ }
+ write(file,suffix);
+}
+
+void write(string s="", flatguide3 x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+// A guide3 is most easily represented as something that modifies a flatguide3.
+typedef void guide3(flatguide3);
+
+restricted void nullpath3(flatguide3) {};
+
+guide3 operator init() {return nullpath3;}
+
+guide3 operator cast(triple v)
+{
+ return new void(flatguide3 f) {
+ f.node(v);
+ };
+}
+
+guide3 operator cast(cycleToken) {
+ return new void(flatguide3 f) {
+ f.cycleToken();
+ };
+}
+
+guide3 operator controls(triple post, triple pre)
+{
+ return new void(flatguide3 f) {
+ f.control(post,pre);
+ };
+};
+
+guide3 operator controls(triple v)
+{
+ return operator controls(v,v);
+}
+
+guide3 operator cast(tensionSpecifier t)
+{
+ return new void(flatguide3 f) {
+ f.Tension(t.out, t.in, t.atLeast);
+ };
+}
+
+guide3 operator cast(curlSpecifier spec)
+{
+ return new void(flatguide3 f) {
+ if(spec.side == JOIN_OUT) f.out(spec.value);
+ else if(spec.side == JOIN_IN) f.in(spec.value);
+ else
+ abort("invalid curl specifier");
+ };
+}
+
+guide3 operator spec(triple v, int side)
+{
+ return new void(flatguide3 f) {
+ if(side == JOIN_OUT) f.out(v);
+ else if(side == JOIN_IN) f.in(v);
+ else
+ abort("invalid direction specifier");
+ };
+}
+
+guide3 operator -- (... guide3[] g)
+{
+ return new void(flatguide3 f) {
+ if(g.length > 0) {
+ for(int i=0; i < g.length-1; ++i) {
+ g[i](f);
+ f.out(1);
+ f.in(1);
+ }
+ g[g.length-1](f);
+ }
+ };
+}
+
+guide3 operator .. (... guide3[] g)
+{
+ return new void(flatguide3 f) {
+ for(int i=0; i < g.length; ++i)
+ g[i](f);
+ };
+}
+
+typedef guide3 interpolate3(... guide3[]);
+
+interpolate3 join3(tensionSpecifier t)
+{
+ return new guide3(... guide3[] a) {
+ if(a.length == 0) return nullpath3;
+ guide3 g=a[0];
+ for(int i=1; i < a.length; ++i)
+ g=g..t..a[i];
+ return g;
+ };
+}
+
+interpolate3 operator ::=join3(operator tension(1,true));
+interpolate3 operator ---=join3(operator tension(infinity,true));
+
+flatguide3 operator cast(guide3 g)
+{
+ flatguide3 f;
+ g(f);
+ return f;
+}
+
+flatguide3[] operator cast(guide3[] g)
+{
+ flatguide3[] p=new flatguide3[g.length];
+ for(int i=0; i < g.length; ++i) {
+ flatguide3 f;
+ g[i](f);
+ p[i]=f;
+ }
+ return p;
+}
+
+// A version of asin that tolerates numerical imprecision
+real asin1(real x)
+{
+ return asin(min(max(x,-1),1));
+}
+
+// A version of acos that tolerates numerical imprecision
+real acos1(real x)
+{
+ return acos(min(max(x,-1),1));
+}
+
+struct Controls {
+ triple c0,c1;
+
+ // 3D extension of John Hobby's control point formula
+ // (cf. The MetaFont Book, page 131),
+ // as described in John C. Bowman and A. Hammerlindl,
+ // TUGBOAT: The Communications of the TeX Users Group 29:2 (2008).
+
+ void operator init(triple v0, triple v1, triple d0, triple d1, real tout,
+ real tin, bool atLeast) {
+ triple v=v1-v0;
+ triple u=unit(v);
+ real L=length(v);
+ d0=unit(d0);
+ d1=unit(d1);
+ real theta=acos1(dot(d0,u));
+ real phi=acos1(dot(d1,u));
+ if(dot(cross(d0,v),cross(v,d1)) < 0) phi=-phi;
+ c0=v0+d0*L*relativedistance(theta,phi,tout,atLeast);
+ c1=v1-d1*L*relativedistance(phi,theta,tin,atLeast);
+ }
+}
+
+private triple cross(triple d0, triple d1, triple reference)
+{
+ triple normal=cross(d0,d1);
+ return normal == O ? reference : normal;
+}
+
+private triple dir(real theta, triple d0, triple d1, triple reference)
+{
+ triple normal=cross(d0,d1,reference);
+ if(normal == O) return d1;
+ return rotate(degrees(theta),dot(normal,reference) >= 0 ? normal : -normal)*
+ d1;
+}
+
+private real angle(triple d0, triple d1, triple reference)
+{
+ real theta=acos1(dot(unit(d0),unit(d1)));
+ return dot(cross(d0,d1,reference),reference) >= 0 ? theta : -theta;
+}
+
+// 3D extension of John Hobby's angle formula (The MetaFont Book, page 131).
+// Notational differences: here psi[i] is the turning angle at z[i+1],
+// beta[i] is the tension for segment i, and in[i] is the incoming
+// direction for segment i (where segment i begins at node i).
+
+real[] theta(triple[] v, real[] alpha, real[] beta,
+ triple dir0, triple dirn, real g0, real gn, triple reference)
+{
+ real[] a,b,c,f,l,psi;
+ int n=alpha.length;
+ bool cyclic=v.cyclic;
+ for(int i=0; i < n; ++i)
+ l[i]=1/length(v[i+1]-v[i]);
+ int i0,in;
+ if(cyclic) {i0=0; in=n;}
+ else {i0=1; in=n-1;}
+ for(int i=0; i < in; ++i)
+ psi[i]=angle(v[i+1]-v[i],v[i+2]-v[i+1],reference);
+ if(cyclic) {
+ l.cyclic=true;
+ psi.cyclic=true;
+ } else {
+ psi[n-1]=0;
+ if(dir0 == O) {
+ real a0=alpha[0];
+ real b0=beta[0];
+ real chi=g0*(b0/a0)^2;
+ a[0]=0;
+ b[0]=3a0-a0/b0+chi;
+ real C=chi*(3a0-1)+a0/b0;
+ c[0]=C;
+ f[0]=-C*psi[0];
+ } else {
+ a[0]=c[0]=0;
+ b[0]=1;
+ f[0]=angle(v[1]-v[0],dir0,reference);
+ }
+ if(dirn == O) {
+ real an=alpha[n-1];
+ real bn=beta[n-1];
+ real chi=gn*(an/bn)^2;
+ a[n]=chi*(3bn-1)+bn/an;
+ b[n]=3bn-bn/an+chi;
+ c[n]=f[n]=0;
+ } else {
+ a[n]=c[n]=0;
+ b[n]=1;
+ f[n]=angle(v[n]-v[n-1],dirn,reference);
+ }
+ }
+
+ for(int i=i0; i < n; ++i) {
+ real in=beta[i-1]^2*l[i-1];
+ real A=in/alpha[i-1];
+ a[i]=A;
+ real B=3*in-A;
+ real out=alpha[i]^2*l[i];
+ real C=out/beta[i];
+ b[i]=B+3*out-C;
+ c[i]=C;
+ f[i]=-B*psi[i-1]-C*psi[i];
+ }
+
+ return tridiagonal(a,b,c,f);
+}
+
+triple reference(triple[] v, int n, triple d0, triple d1)
+{
+ triple[] V=sequence(new triple(int i) {
+ return cross(v[i+1]-v[i],v[i+2]-v[i+1]);
+ },n-1);
+ if(n > 0) {
+ V.push(cross(d0,v[1]-v[0]));
+ V.push(cross(v[n]-v[n-1],d1));
+ }
+
+ triple max=V[0];
+ real M=abs(max);
+ for(int i=1; i < V.length; ++i) {
+ triple vi=V[i];
+ real a=abs(vi);
+ if(a > M) {
+ M=a;
+ max=vi;
+ }
+ }
+
+ triple reference;
+ for(int i=0; i < V.length; ++i) {
+ triple u=unit(V[i]);
+ reference += dot(u,max) < 0 ? -u : u;
+ }
+
+ return reference;
+}
+
+// Fill in missing directions for n cyclic nodes.
+void aim(flatguide3 g, int N)
+{
+ bool cyclic=true;
+ int start=0, end=0;
+
+ // If the cycle contains one or more direction specifiers, break the loop.
+ for(int k=0; k < N; ++k)
+ if(g.solved(k)) {cyclic=false; end=k; break;}
+ for(int k=N-1; k >= 0; --k)
+ if(g.solved(k)) {cyclic=false; start=k; break;}
+ while(start < N && g.control[start].active) ++start;
+
+ int n=N-(start-end);
+ if(n <= 1 || (cyclic && n <= 2)) return;
+
+ triple[] v=new triple[cyclic ? n : n+1];
+ real[] alpha=new real[n];
+ real[] beta=new real[n];
+ for(int k=0; k < n; ++k) {
+ int K=(start+k) % N;
+ v[k]=g.nodes[K];
+ alpha[k]=g.Tension[K].out;
+ beta[k]=g.Tension[K].in;
+ }
+ if(cyclic) {
+ v.cyclic=true;
+ alpha.cyclic=true;
+ beta.cyclic=true;
+ } else v[n]=g.nodes[(start+n) % N];
+ int final=(end-1) % N;
+
+ triple d0=g.out[start].dir;
+ triple d1=g.in[final].dir;
+
+ triple reference=reference(v,n,d0,d1);
+
+ real[] theta=theta(v,alpha,beta,d0,d1,g.out[start].gamma,g.in[final].gamma,
+ reference);
+
+ v.cyclic=true;
+ theta.cyclic=true;
+
+ for(int k=1; k < (cyclic ? n+1 : n); ++k) {
+ triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference);
+ g.in[(start+k-1) % N].init(w);
+ g.out[(start+k) % N].init(w);
+ }
+
+ if(g.out[start].dir == O)
+ g.out[start].init(dir(theta[0],v[0]-g.nodes[(start-1) % N],v[1]-v[0],
+ reference));
+ if(g.in[final].dir == O)
+ g.in[final].init(dir(theta[n],v[n-1]-v[n-2],v[n]-v[n-1],reference));
+}
+
+// Fill in missing directions for the sequence of nodes i...n.
+void aim(flatguide3 g, int i, int n)
+{
+ int j=n-i;
+ if(j > 1 || g.out[i].dir != O || g.in[i].dir != O) {
+ triple[] v=new triple[j+1];
+ real[] alpha=new real[j];
+ real[] beta=new real[j];
+ for(int k=0; k < j; ++k) {
+ v[k]=g.nodes[i+k];
+ alpha[k]=g.Tension[i+k].out;
+ beta[k]=g.Tension[i+k].in;
+ }
+ v[j]=g.nodes[n];
+
+ triple d0=g.out[i].dir;
+ triple d1=g.in[n-1].dir;
+
+ triple reference=reference(v,j,d0,d1);
+
+ real[] theta=theta(v,alpha,beta,d0,d1,g.out[i].gamma,g.in[n-1].gamma,
+ reference);
+
+ for(int k=1; k < j; ++k) {
+ triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference);
+ g.in[i+k-1].init(w);
+ g.out[i+k].init(w);
+ }
+ if(g.out[i].dir == O) {
+ triple w=dir(theta[0],g.in[i].dir,v[1]-v[0],reference);
+ if(i > 0) g.in[i-1].init(w);
+ g.out[i].init(w);
+ }
+ if(g.in[n-1].dir == O) {
+ triple w=dir(theta[j],g.out[n-1].dir,v[j]-v[j-1],reference);
+ g.in[n-1].init(w);
+ g.out[n].init(w);
+ }
+ }
+}
+
+private real Fuzz=10*realEpsilon;
+
+triple XYplane(pair z) {return (z.x,z.y,0);}
+triple YZplane(pair z) {return (0,z.x,z.y);}
+triple ZXplane(pair z) {return (z.y,0,z.x);}
+
+bool cyclic(guide3 g) {flatguide3 f; g(f); return f.cyclic();}
+int size(guide3 g) {flatguide3 f; g(f); return f.size();}
+int length(guide3 g) {flatguide3 f; g(f); return f.nodes.length-1;}
+
+triple dir(path3 p)
+{
+ return dir(p,length(p));
+}
+
+triple dir(path3 p, path3 h)
+{
+ return 0.5*(dir(p)+dir(h));
+}
+
+// return the point on path3 p at arclength L
+triple arcpoint(path3 p, real L)
+{
+ return point(p,arctime(p,L));
+}
+
+// return the direction on path3 p at arclength L
+triple arcdir(path3 p, real L)
+{
+ return dir(p,arctime(p,L));
+}
+
+// return the time on path3 p at the relative fraction l of its arclength
+real reltime(path3 p, real l)
+{
+ return arctime(p,l*arclength(p));
+}
+
+// return the point on path3 p at the relative fraction l of its arclength
+triple relpoint(path3 p, real l)
+{
+ return point(p,reltime(p,l));
+}
+
+// return the direction of path3 p at the relative fraction l of its arclength
+triple reldir(path3 p, real l)
+{
+ return dir(p,reltime(p,l));
+}
+
+// return the initial point of path3 p
+triple beginpoint(path3 p)
+{
+ return point(p,0);
+}
+
+// return the point on path3 p at half of its arclength
+triple midpoint(path3 p)
+{
+ return relpoint(p,0.5);
+}
+
+// return the final point of path3 p
+triple endpoint(path3 p)
+{
+ return point(p,length(p));
+}
+
+path3 path3(triple v)
+{
+ triple[] point={v};
+ return path3(point,point,point,new bool[] {false},false);
+}
+
+path3 path3(path p, triple plane(pair)=XYplane)
+{
+ int n=size(p);
+ return path3(sequence(new triple(int i) {return plane(precontrol(p,i));},n),
+ sequence(new triple(int i) {return plane(point(p,i));},n),
+ sequence(new triple(int i) {return plane(postcontrol(p,i));},n),
+ sequence(new bool(int i) {return straight(p,i);},n),
+ cyclic(p));
+}
+
+path3[] path3(explicit path[] g, triple plane(pair)=XYplane)
+{
+ return sequence(new path3(int i) {return path3(g[i],plane);},g.length);
+}
+
+path3 invert(path p, triple normal, triple point,
+ projection P=currentprojection)
+{
+ return path3(p,new triple(pair z) {return invert(z,normal,point,P);});
+}
+
+path3 invert(path p, triple point, projection P=currentprojection)
+{
+ return path3(p,new triple(pair z) {return invert(z,P.normal,point,P);});
+}
+
+path3 invert(path p, projection P=currentprojection)
+{
+ return path3(p,new triple(pair z) {return invert(z,P.normal,P.target,P);});
+}
+
+// Construct a path from a path3 by applying P to each control point.
+path path(path3 p, pair P(triple)=xypart)
+{
+ int n=length(p);
+ if(n < 0) return nullpath;
+ guide g=P(point(p,0));
+ if(n == 0) return g;
+ for(int i=1; i < n; ++i)
+ g=straight(p,i-1) ? g--P(point(p,i)) :
+ g..controls P(postcontrol(p,i-1)) and P(precontrol(p,i))..P(point(p,i));
+
+ if(straight(p,n-1))
+ return cyclic(p) ? g--cycle : g--P(point(p,n));
+
+ pair post=P(postcontrol(p,n-1));
+ pair pre=P(precontrol(p,n));
+ return cyclic(p) ? g..controls post and pre..cycle :
+ g..controls post and pre..P(point(p,n));
+}
+
+void write(file file, string s="", explicit path3 x, suffix suffix=none)
+{
+ write(file,s);
+ int n=length(x);
+ if(n < 0) write("<nullpath3>");
+ else {
+ for(int i=0; i < n; ++i) {
+ write(file,point(x,i));
+ if(i < length(x)) {
+ if(straight(x,i)) write(file,"--");
+ else {
+ write(file,".. controls ");
+ write(file,postcontrol(x,i));
+ write(file," and ");
+ write(file,precontrol(x,i+1),newl);
+ write(file," ..");
+ }
+ }
+ }
+ if(cyclic(x))
+ write(file,"cycle",suffix);
+ else
+ write(file,point(x,n),suffix);
+ }
+}
+
+void write(string s="", explicit path3 x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+void write(file file, string s="", explicit path3[] x, suffix suffix=none)
+{
+ write(file,s);
+ if(x.length > 0) write(file,x[0]);
+ for(int i=1; i < x.length; ++i) {
+ write(file,endl);
+ write(file," ^^");
+ write(file,x[i]);
+ }
+ write(file,suffix);
+}
+
+void write(string s="", explicit path3[] x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+path3 solve(flatguide3 g)
+{
+ int n=g.nodes.length-1;
+
+ // If duplicate points occur consecutively, add dummy controls (if absent).
+ for(int i=0; i < n; ++i) {
+ if(g.nodes[i] == g.nodes[i+1] && !g.control[i].active)
+ g.control[i]=control(g.nodes[i],g.nodes[i],straight=true);
+ }
+
+ // Fill in empty direction specifiers inherited from explicit control points.
+ for(int i=0; i < n; ++i) {
+ if(g.control[i].active) {
+ g.out[i].init(g.control[i].post-g.nodes[i]);
+ g.in[i].init(g.nodes[i+1]-g.control[i].pre);
+ }
+ }
+
+ // Propagate directions across nodes.
+ for(int i=0; i < n; ++i) {
+ int next=g.cyclic[i+1] ? 0 : i+1;
+ if(g.out[next].active())
+ g.in[i].default(g.out[next]);
+ if(g.in[i].active()) {
+ g.out[next].default(g.in[i]);
+ g.out[i+1].default(g.in[i]);
+ }
+ }
+
+ // Compute missing 3D directions.
+ // First, resolve cycles
+ int i=find(g.cyclic);
+ if(i > 0) {
+ aim(g,i);
+ // All other cycles can now be reduced to sequences.
+ triple v=g.out[0].dir;
+ for(int j=i; j <= n; ++j) {
+ if(g.cyclic[j]) {
+ g.in[j-1].default(v);
+ g.out[j].default(v);
+ if(g.nodes[j-1] == g.nodes[j] && !g.control[j-1].active)
+ g.control[j-1]=control(g.nodes[j-1],g.nodes[j-1]);
+ }
+ }
+ }
+
+ // Next, resolve sequences.
+ int i=0;
+ int start=0;
+ while(i < n) {
+ // Look for a missing outgoing direction.
+ while(i <= n && g.solved(i)) {start=i; ++i;}
+ if(i > n) break;
+ // Look for the end of the sequence.
+ while(i < n && !g.solved(i)) ++i;
+
+ while(start < i && g.control[start].active) ++start;
+
+ if(start < i)
+ aim(g,start,i);
+ }
+
+ // Compute missing 3D control points.
+ for(int i=0; i < n; ++i) {
+ int next=g.cyclic[i+1] ? 0 : i+1;
+ if(!g.control[i].active) {
+ control c;
+ if((g.out[i].Curl && g.in[i].Curl) ||
+ (g.out[i].dir == O && g.in[i].dir == O)) {
+ // fill in straight control points for path3 functions
+ triple delta=(g.nodes[i+1]-g.nodes[i])/3;
+ c=control(g.nodes[i]+delta,g.nodes[i+1]-delta,straight=true);
+ } else {
+ Controls C=Controls(g.nodes[i],g.nodes[next],g.out[i].dir,g.in[i].dir,
+ g.Tension[i].out,g.Tension[i].in,
+ g.Tension[i].atLeast);
+ c=control(C.c0,C.c1);
+ }
+ g.control[i]=c;
+ }
+ }
+
+ // Convert to Knuth's format (control points stored with nodes)
+ int n=g.nodes.length;
+ bool cyclic;
+ if(n > 0) {
+ cyclic=g.cyclic[n-1];
+ if(cyclic) --n;
+ }
+ triple[] pre=new triple[n];
+ triple[] point=new triple[n];
+ triple[] post=new triple[n];
+ bool[] straight=new bool[n];
+ if(n > 0) {
+ for(int i=0; i < n-1; ++i) {
+ point[i]=g.nodes[i];
+ post[i]=g.control[i].post;
+ pre[i+1]=g.control[i].pre;
+ straight[i]=g.control[i].straight;
+ }
+ point[n-1]=g.nodes[n-1];
+ if(cyclic) {
+ pre[0]=g.control[n-1].pre;
+ post[n-1]=g.control[n-1].post;
+ straight[n-1]=g.control[n-1].straight;
+ } else {
+ pre[0]=point[0];
+ post[n-1]=point[n-1];
+ straight[n-1]=false;
+ }
+ }
+
+ return path3(pre,point,post,straight,cyclic);
+}
+
+path nurb(path3 p, projection P, int ninterpolate=P.ninterpolate)
+{
+ triple f=P.camera;
+ triple u=unit(P.normal);
+ transform3 t=P.t;
+
+ path nurb(triple v0, triple v1, triple v2, triple v3) {
+ return nurb(project(v0,t),project(v1,t),project(v2,t),project(v3,t),
+ dot(u,f-v0),dot(u,f-v1),dot(u,f-v2),dot(u,f-v3),ninterpolate);
+ }
+
+ path g;
+
+ if(straight(p,0))
+ g=project(point(p,0),t);
+
+ int last=length(p);
+ for(int i=0; i < last; ++i) {
+ if(straight(p,i))
+ g=g--project(point(p,i+1),t);
+ else
+ g=g&nurb(point(p,i),postcontrol(p,i),precontrol(p,i+1),point(p,i+1));
+ }
+
+ int n=length(g);
+ if(cyclic(p)) g=g&cycle;
+
+ return g;
+}
+
+path project(path3 p, projection P=currentprojection,
+ int ninterpolate=P.ninterpolate)
+{
+ guide g;
+
+ int last=length(p);
+ if(last < 0) return g;
+
+ transform3 t=P.t;
+
+ if(ninterpolate == 1 || piecewisestraight(p)) {
+ g=project(point(p,0),t);
+ // Construct the path.
+ int stop=cyclic(p) ? last-1 : last;
+ for(int i=0; i < stop; ++i) {
+ if(straight(p,i))
+ g=g--project(point(p,i+1),t);
+ else {
+ g=g..controls project(postcontrol(p,i),t) and
+ project(precontrol(p,i+1),t)..project(point(p,i+1),t);
+ }
+ }
+ } else return nurb(p,P);
+
+ if(cyclic(p))
+ g=straight(p,last-1) ? g--cycle :
+ g..controls project(postcontrol(p,last-1),t) and
+ project(precontrol(p,last),t)..cycle;
+ return g;
+}
+
+pair[] project(triple[] v, projection P=currentprojection)
+{
+ return sequence(new pair(int i) {return project(v[i],P.t);},v.length);
+}
+
+path[] project(explicit path3[] g, projection P=currentprojection)
+{
+ return sequence(new path(int i) {return project(g[i],P);},g.length);
+}
+
+guide3 operator cast(path3 p)
+{
+ int last=length(p);
+
+ bool cyclic=cyclic(p);
+ int stop=cyclic ? last-1 : last;
+ return new void(flatguide3 f) {
+ if(last >= 0) {
+ f.node(point(p,0));
+ for(int i=0; i < stop; ++i) {
+ if(straight(p,i)) {
+ f.out(1);
+ f.in(1);
+ } else
+ f.control(postcontrol(p,i),precontrol(p,i+1));
+ f.node(point(p,i+1));
+ }
+ if(cyclic) {
+ if(straight(p,stop)) {
+ f.out(1);
+ f.in(1);
+ } else
+ f.control(postcontrol(p,stop),precontrol(p,last));
+ f.cycleToken();
+ }
+ }
+ };
+}
+
+// Return a unit normal vector to a planar path p (or O if the path is
+// nonplanar).
+triple normal(path3 p)
+{
+ triple normal;
+ real fuzz=sqrtEpsilon*abs(max(p)-min(p));
+ real absnormal;
+ real theta;
+
+ bool Cross(triple a, triple b) {
+ if(abs(a) >= fuzz && abs(b) >= fuzz) {
+ triple n=cross(unit(a),unit(b));
+ real absn=abs(n);
+ if(absn < sqrtEpsilon) return false;
+ n=unit(n);
+ if(absnormal > 0 &&
+ abs(normal-n) > sqrtEpsilon && abs(normal+n) > sqrtEpsilon)
+ return true;
+ else {
+ int sign=dot(n,normal) >= 0 ? 1 : -1;
+ theta += sign*asin1(absn);
+ if(absn > absnormal) {
+ absnormal=absn;
+ normal=n;
+ theta=sign*theta;
+ }
+ }
+ }
+ return false;
+ }
+
+ int L=length(p);
+ if(L <= 0) return O;
+
+ triple zi=point(p,0);
+ triple v0=zi-precontrol(p,0);
+ for(int i=0; i < L; ++i) {
+ triple c0=postcontrol(p,i);
+ triple c1=precontrol(p,i+1);
+ triple zp=point(p,i+1);
+ triple v1=c0-zi;
+ triple v2=c1-c0;
+ triple v3=zp-c1;
+ if(Cross(v0,v1) || Cross(v1,v2) || Cross(v2,v3)) return O;
+ v0=v3;
+ zi=zp;
+ }
+ return theta >= 0 ? normal : -normal;
+}
+
+// Return a unit normal vector to a polygon with vertices in p.
+triple normal(triple[] p)
+{
+ triple normal;
+ real fuzz=sqrtEpsilon*abs(maxbound(p)-minbound(p));
+ real absnormal;
+ real theta;
+
+ bool Cross(triple a, triple b) {
+ if(abs(a) >= fuzz && abs(b) >= fuzz) {
+ triple n=cross(unit(a),unit(b));
+ real absn=abs(n);
+ n=unit(n);
+ if(absnormal > 0 && absn > sqrtEpsilon &&
+ abs(normal-n) > sqrtEpsilon && abs(normal+n) > sqrtEpsilon)
+ return true;
+ else {
+ int sign=dot(n,normal) >= 0 ? 1 : -1;
+ theta += sign*asin1(absn);
+ if(absn > absnormal) {
+ absnormal=absn;
+ normal=n;
+ theta=sign*theta;
+ }
+ }
+ }
+ return false;
+ }
+
+ if(p.length <= 0) return O;
+
+ triple zi=p[0];
+ triple v0=zi-p[p.length-1];
+ for(int i=0; i < p.length-1; ++i) {
+ triple zp=p[i+1];
+ triple v1=zp-zi;
+ if(Cross(v0,v1)) return O;
+ v0=v1;
+ zi=zp;
+ }
+ return theta >= 0 ? normal : -normal;
+}
+
+// Transforms that map XY plane to YX, YZ, ZY, ZX, and XZ planes.
+restricted transform3 XY=identity4;
+restricted transform3 YX=rotate(-90,O,Z);
+restricted transform3 YZ=rotate(90,O,Z)*rotate(90,O,X);
+restricted transform3 ZY=rotate(-90,O,X)*YZ;
+restricted transform3 ZX=rotate(-90,O,Z)*rotate(-90,O,Y);
+restricted transform3 XZ=rotate(-90,O,Y)*ZX;
+
+private transform3 flip(transform3 t, triple X, triple Y, triple Z,
+ projection P)
+{
+ static transform3 flip(triple v) {
+ static real s(real x) {return x > 0 ? -1 : 1;}
+ return scale(s(v.x),s(v.y),s(v.z));
+ }
+
+ triple u=unit(P.normal);
+ triple up=unit(perp(P.up,u));
+ bool upright=dot(Z,u) >= 0;
+ if(dot(Y,up) < 0) {
+ t=flip(Y)*t;
+ upright=!upright;
+ }
+ return upright ? t : flip(X)*t;
+}
+
+restricted transform3 XY(projection P=currentprojection)
+{
+ return flip(XY,X,Y,Z,P);
+}
+
+restricted transform3 YX(projection P=currentprojection)
+{
+ return flip(YX,Y,X,Z,P);
+}
+
+restricted transform3 YZ(projection P=currentprojection)
+{
+ return flip(YZ,Y,Z,X,P);
+}
+
+restricted transform3 ZY(projection P=currentprojection)
+{
+ return flip(ZY,Z,Y,X,P);
+}
+
+restricted transform3 ZX(projection P=currentprojection)
+{
+ return flip(ZX,Z,X,Y,P);
+}
+
+restricted transform3 XZ(projection P=currentprojection)
+{
+ return flip(XZ,X,Z,Y,P);
+}
+
+// Transform3 that projects in direction dir onto plane with normal n
+// through point O.
+transform3 planeproject(triple n, triple O=O, triple dir=n)
+{
+ real a=n.x, b=n.y, c=n.z;
+ real u=dir.x, v=dir.y, w=dir.z;
+ real delta=1.0/(a*u+b*v+c*w);
+ real d=-(a*O.x+b*O.y+c*O.z)*delta;
+ return new real[][] {
+ {(b*v+c*w)*delta,-b*u*delta,-c*u*delta,-d*u},
+ {-a*v*delta,(a*u+c*w)*delta,-c*v*delta,-d*v},
+ {-a*w*delta,-b*w*delta,(a*u+b*v)*delta,-d*w},
+ {0,0,0,1}
+ };
+}
+
+// Transform3 that projects in direction dir onto plane defined by p.
+transform3 planeproject(path3 p, triple dir=O)
+{
+ triple n=normal(p);
+ return planeproject(n,point(p,0),dir == O ? n : dir);
+}
+
+// Transform for projecting onto plane through point O with normal cross(u,v).
+transform transform(triple u, triple v, triple O=O,
+ projection P=currentprojection)
+{
+ transform3 t=P.t;
+ real[] tO=t*new real[] {O.x,O.y,O.z,1};
+ real tO3=tO[3];
+ real factor=1/tO3^2;
+ real[] x=(tO3*t[0]-tO[0]*t[3])*factor;
+ real[] y=(tO3*t[1]-tO[1]*t[3])*factor;
+ triple x=(x[0],x[1],x[2]);
+ triple y=(y[0],y[1],y[2]);
+ u=unit(u);
+ v=unit(v);
+ return (0,0,dot(u,x),dot(v,x),dot(u,y),dot(v,y));
+}
+
+// Project Label onto plane through point O with normal cross(u,v).
+Label project(Label L, triple u, triple v, triple O=O,
+ projection P=currentprojection) {
+ Label L=L.copy();
+ L.position=project(O,P.t);
+ L.transform(transform(u,v,O,P));
+ return L;
+}
+
+path3 operator cast(guide3 g) {return solve(g);}
+path3 operator cast(triple v) {return path3(v);}
+
+guide3[] operator cast(triple[] v)
+{
+ return sequence(new guide3(int i) {return v[i];},v.length);
+}
+
+path3[] operator cast(triple[] v)
+{
+ return sequence(new path3(int i) {return v[i];},v.length);
+}
+
+path3[] operator cast(guide3[] g)
+{
+ return sequence(new path3(int i) {return solve(g[i]);},g.length);
+}
+
+guide3[] operator cast(path3[] g)
+{
+ return sequence(new guide3(int i) {return g[i];},g.length);
+}
+
+void write(file file, string s="", explicit guide3[] x, suffix suffix=none)
+{
+ write(file,s,(path3[]) x,suffix);
+}
+
+void write(string s="", explicit guide3[] x, suffix suffix=endl)
+{
+ write(stdout,s,(path3[]) x,suffix);
+}
+
+triple point(explicit guide3 g, int t) {
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ return f.nodes[adjustedIndex(t,n,f.cyclic())];
+}
+
+triple[] dirSpecifier(guide3 g, int t)
+{
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return new triple[];
+ return new triple[] {f.out[t].dir,f.in[t].dir};
+}
+
+triple[] controlSpecifier(guide3 g, int t) {
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return new triple[];
+ control c=f.control[t];
+ if(c.active) return new triple[] {c.post,c.pre};
+ else return new triple[];
+}
+
+tensionSpecifier tensionSpecifier(guide3 g, int t)
+{
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return operator tension(1,1,false);
+ Tension T=f.Tension[t];
+ return operator tension(T.out,T.in,T.atLeast);
+}
+
+real[] curlSpecifier(guide3 g, int t)
+{
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return new real[];
+ return new real[] {f.out[t].gamma,f.in[t].gamma};
+}
+
+guide3 reverse(guide3 g)
+{
+ flatguide3 f;
+ bool cyclic=cyclic(g);
+ g(f);
+
+ if(f.precyclic())
+ return reverse(solve(g));
+
+ int n=f.size();
+ checkEmpty(n);
+ guide3 G;
+ if(n >= 0) {
+ int start=cyclic ? n : n-1;
+ for(int i=start; i > 0; --i) {
+ G=G..f.nodes[i];
+ control c=f.control[i-1];
+ if(c.active)
+ G=G..operator controls(c.pre,c.post);
+ else {
+ dir in=f.in[i-1];
+ triple d=in.dir;
+ if(d != O) G=G..operator spec(-d,JOIN_OUT);
+ else if(in.Curl) G=G..operator curl(in.gamma,JOIN_OUT);
+ dir out=f.out[i-1];
+ triple d=out.dir;
+ if(d != O) G=G..operator spec(-d,JOIN_IN);
+ else if(out.Curl) G=G..operator curl(out.gamma,JOIN_IN);
+ }
+ }
+ if(cyclic) G=G..cycle;
+ else G=G..f.nodes[0];
+ }
+ return G;
+}
+
+triple intersectionpoint(path3 p, path3 q, real fuzz=-1)
+{
+ real[] t=intersect(p,q,fuzz);
+ if(t.length == 0) abort("paths do not intersect");
+ return point(p,t[0]);
+}
+
+// return an array containing all intersection points of p and q
+triple[] intersectionpoints(path3 p, path3 q, real fuzz=-1)
+{
+ real[][] t=intersections(p,q,fuzz);
+ return sequence(new triple(int i) {return point(p,t[i][0]);},t.length);
+}
+
+triple[] intersectionpoints(explicit path3[] p, explicit path3[] q,
+ real fuzz=-1)
+{
+ triple[] v;
+ for(int i=0; i < p.length; ++i)
+ for(int j=0; j < q.length; ++j)
+ v.append(intersectionpoints(p[i],q[j],fuzz));
+ return v;
+}
+
+path3 operator &(path3 p, cycleToken tok)
+{
+ int n=length(p);
+ if(n < 0) return nullpath3;
+ triple a=point(p,0);
+ triple b=point(p,n);
+ return subpath(p,0,n-1)..controls postcontrol(p,n-1) and precontrol(p,n)..
+ cycle;
+}
+
+// return the point on path3 p at arclength L
+triple arcpoint(path3 p, real L)
+{
+ return point(p,arctime(p,L));
+}
+
+// return the point on path3 p at arclength L
+triple arcpoint(path3 p, real L)
+{
+ return point(p,arctime(p,L));
+}
+
+// return the direction on path3 p at arclength L
+triple arcdir(path3 p, real L)
+{
+ return dir(p,arctime(p,L));
+}
+
+// return the time on path3 p at the relative fraction l of its arclength
+real reltime(path3 p, real l)
+{
+ return arctime(p,l*arclength(p));
+}
+
+// return the point on path3 p at the relative fraction l of its arclength
+triple relpoint(path3 p, real l)
+{
+ return point(p,reltime(p,l));
+}
+
+// return the direction of path3 p at the relative fraction l of its arclength
+triple reldir(path3 p, real l)
+{
+ return dir(p,reltime(p,l));
+}
+
+// return the point on path3 p at half of its arclength
+triple midpoint(path3 p)
+{
+ return relpoint(p,0.5);
+}
+
+real relative(Label L, path3 g)
+{
+ return L.position.relative ? reltime(g,L.relative()) : L.relative();
+}
+
+// return the linear transformation that maps X,Y,Z to u,v,w.
+transform3 transform3(triple u, triple v, triple w=cross(u,v))
+{
+ return new real[][] {
+ {u.x,v.x,w.x,0},
+ {u.y,v.y,w.y,0},
+ {u.z,v.z,w.z,0},
+ {0,0,0,1}
+ };
+}
+
+// return the rotation that maps Z to a unit vector u about cross(u,Z),
+transform3 align(triple u)
+{
+ real a=u.x;
+ real b=u.y;
+ real c=u.z;
+ real d=a^2+b^2;
+
+ if(d != 0) {
+ d=sqrt(d);
+ real e=1/d;
+ return new real[][] {
+ {-b*e,-a*c*e,a,0},
+ {a*e,-b*c*e,b,0},
+ {0,d,c,0},
+ {0,0,0,1}};
+ }
+ return c >= 0 ? identity(4) : diagonal(1,-1,-1,1);
+}
+
+// return a rotation that maps X,Y to the projection plane.
+transform3 transform3(projection P=currentprojection)
+{
+ triple w=unit(P.normal);
+ triple v=unit(perp(P.up,w));
+ if(v == O) v=cross(perp(w),w);
+ triple u=cross(v,w);
+ return u != O ? transform3(u,v,w) : identity(4);
+}
+
+triple[] triples(real[] x, real[] y, real[] z)
+{
+ if(x.length != y.length || x.length != z.length)
+ abort("arrays have different lengths");
+ return sequence(new triple(int i) {return (x[i],y[i],z[i]);},x.length);
+}
+
+path3[] operator cast(path3 p)
+{
+ return new path3[] {p};
+}
+
+path3[] operator cast(guide3 g)
+{
+ return new path3[] {(path3) g};
+}
+
+path3[] operator ^^ (path3 p, path3 q)
+{
+ return new path3[] {p,q};
+}
+
+path3[] operator ^^ (path3 p, explicit path3[] q)
+{
+ return concat(new path3[] {p},q);
+}
+
+path3[] operator ^^ (explicit path3[] p, path3 q)
+{
+ return concat(p,new path3[] {q});
+}
+
+path3[] operator ^^ (explicit path3[] p, explicit path3[] q)
+{
+ return concat(p,q);
+}
+
+path3[] operator * (transform3 t, explicit path3[] p)
+{
+ return sequence(new path3(int i) {return t*p[i];},p.length);
+}
+
+triple[] operator * (transform3 t, triple[] v)
+{
+ return sequence(new triple(int i) {return t*v[i];},v.length);
+}
+
+triple[][] operator * (transform3 t, triple[][] v)
+{
+ triple[][] V=new triple[v.length][];
+ for(int i=0; i < v.length; ++i) {
+ triple[] vi=v[i];
+ V[i]=sequence(new triple(int j) {return t*vi[j];},vi.length);
+ }
+ return V;
+}
+
+triple min(explicit path3[] p)
+{
+ checkEmpty(p.length);
+ triple minp=min(p[0]);
+ for(int i=1; i < p.length; ++i)
+ minp=minbound(minp,min(p[i]));
+ return minp;
+}
+
+triple max(explicit path3[] p)
+{
+ checkEmpty(p.length);
+ triple maxp=max(p[0]);
+ for(int i=1; i < p.length; ++i)
+ maxp=maxbound(maxp,max(p[i]));
+ return maxp;
+}
+
+path3 randompath3(int n, bool cumulate=true, interpolate3 join=operator ..)
+{
+ guide3 g;
+ triple w;
+ for(int i=0; i <= n; ++i) {
+ triple z=(unitrand()-0.5,unitrand()-0.5,unitrand()-0.5);
+ if(cumulate) w += z;
+ else w=z;
+ g=join(g,w);
+ }
+ return g;
+}
+
+path3[] box(triple v1, triple v2)
+{
+ return
+ (v1.x,v1.y,v1.z)--
+ (v1.x,v1.y,v2.z)--
+ (v1.x,v2.y,v2.z)--
+ (v1.x,v2.y,v1.z)--
+ (v1.x,v1.y,v1.z)--
+ (v2.x,v1.y,v1.z)--
+ (v2.x,v1.y,v2.z)--
+ (v2.x,v2.y,v2.z)--
+ (v2.x,v2.y,v1.z)--
+ (v2.x,v1.y,v1.z)^^
+ (v2.x,v2.y,v1.z)--
+ (v1.x,v2.y,v1.z)^^
+ (v1.x,v2.y,v2.z)--
+ (v2.x,v2.y,v2.z)^^
+ (v2.x,v1.y,v2.z)--
+ (v1.x,v1.y,v2.z);
+}
+
+restricted path3[] unitbox=box(O,(1,1,1));
+restricted path3 unitcircle3=X..Y..-X..-Y..cycle;
+restricted path3 unitsquare3=O--X--X+Y--Y--cycle;
+
+path3 circle(triple c, real r, triple normal=Z)
+{
+ path3 p=normal == Z ? unitcircle3 : align(unit(normal))*unitcircle3;
+ return shift(c)*scale3(r)*p;
+}
+
+// return an arc centered at c from triple v1 to v2 (assuming |v2-c|=|v1-c|),
+// drawing in the given direction.
+// The normal must be explicitly specified if c and the endpoints are colinear.
+path3 arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW)
+{
+ v1 -= c;
+ real r=abs(v1);
+ v1=unit(v1);
+ v2=unit(v2-c);
+
+ if(normal == O) {
+ normal=cross(v1,v2);
+ if(normal == O) abort("explicit normal required for these endpoints");
+ }
+
+ transform3 T;
+ bool align=normal != Z;
+ if(align) {
+ T=align(unit(normal));
+ transform3 Tinv=transpose(T);
+ v1=Tinv*v1;
+ v2=Tinv*v2;
+ }
+
+ string invalidnormal="invalid normal vector";
+ real fuzz=sqrtEpsilon;
+ if(abs(v1.z) > fuzz || abs(v2.z) > fuzz)
+ abort(invalidnormal);
+
+ real[] t1=intersect(unitcircle3,O--2*(v1.x,v1.y,0));
+ real[] t2=intersect(unitcircle3,O--2*(v2.x,v2.y,0));
+
+ if(t1.length == 0 || t2.length == 0)
+ abort(invalidnormal);
+
+ real t1=t1[0];
+ real t2=t2[0];
+ int n=length(unitcircle3);
+ if(direction) {
+ if(t1 >= t2) t1 -= n;
+ } else if(t2 >= t1) t2 -= n;
+
+ path3 p=subpath(unitcircle3,t1,t2);
+ if(align) p=T*p;
+ return shift(c)*scale3(r)*p;
+}
+
+// return an arc centered at c with radius r from c+r*dir(theta1,phi1) to
+// c+r*dir(theta2,phi2) in degrees, drawing in the given direction
+// relative to the normal vector cross(dir(theta1,phi1),dir(theta2,phi2)).
+// The normal must be explicitly specified if c and the endpoints are colinear.
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O, bool direction)
+{
+ return arc(c,c+r*dir(theta1,phi1),c+r*dir(theta2,phi2),normal,direction);
+}
+
+// return an arc centered at c with radius r from c+r*dir(theta1,phi1) to
+// c+r*dir(theta2,phi2) in degrees, drawing drawing counterclockwise
+// relative to the normal vector cross(dir(theta1,phi1),dir(theta2,phi2))
+// iff theta2 > theta1 or (theta2 == theta1 and phi2 >= phi1).
+// The normal must be explicitly specified if c and the endpoints are colinear.
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O)
+{
+ return arc(c,r,theta1,phi1,theta2,phi2,normal,
+ theta2 > theta1 || (theta2 == theta1 && phi2 >= phi1) ? CCW : CW);
+}
+
+private real epsilon=1000*realEpsilon;
+
+// Return a representation of the plane through point O with normal cross(u,v).
+path3 plane(triple u, triple v, triple O=O)
+{
+ return O--O+u--O+u+v--O+v--cycle;
+}
+
+// PRC/OpenGL support
+
+include three_light;
+
+void draw(frame f, path3 g, material p=currentpen, light light=nolight,
+ string name="", render render=defaultrender,
+ projection P=currentprojection);
+
+void begingroup3(frame f, string name="", render render=defaultrender,
+ triple center=O, int interaction=0)
+{
+ _begingroup3(f,name,render.compression,render.granularity,render.closed,
+ render.tessellate,render.merge == false,
+ render.merge == true,center,interaction);
+}
+
+void begingroup3(picture pic=currentpicture, string name="",
+ render render=defaultrender,
+ triple center=O, int interaction=0)
+{
+ pic.add(new void(frame f, transform3, picture pic, projection) {
+ if(is3D())
+ begingroup3(f,name,render,center,interaction);
+ if(pic != null)
+ begingroup(pic);
+ },true);
+}
+
+void endgroup3(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform3, picture pic, projection) {
+ if(is3D())
+ endgroup3(f);
+ if(pic != null)
+ endgroup(pic);
+ },true);
+}
+
+void addPath(picture pic, path3 g, pen p)
+{
+ if(size(g) > 0)
+ pic.addBox(min(g),max(g),min3(p),max3(p));
+}
+
+include three_surface;
+include three_margins;
+
+pair min(path3 p, projection P)
+{
+ path3 q=P.T.modelview*p;
+ if(P.infinity)
+ return xypart(min(q));
+ return maxratio(q)/P.T.projection[3][2];
+}
+
+pair max(path3 p, projection P)
+{
+ path3 q=P.T.modelview*p;
+ if(P.infinity)
+ return xypart(max(q));
+ return minratio(q)/P.T.projection[3][2];
+}
+
+pair min(frame f, projection P)
+{
+ frame g=P.T.modelview*f;
+ if(P.infinity)
+ return xypart(min3(g));
+ return maxratio(g)/P.T.projection[3][2];
+}
+
+pair max(frame f, projection P)
+{
+ frame g=P.T.modelview*f;
+ if(P.infinity)
+ return xypart(max3(g));
+ return minratio(g)/P.T.projection[3][2];
+}
+
+void draw(picture pic=currentpicture, Label L="", path3 g,
+ align align=NoAlign, material p=currentpen, margin3 margin=NoMargin3,
+ light light=nolight, string name="", render render=defaultrender)
+{
+ pen q=(pen) p;
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ path3 G=margin(t*g,q).g;
+ if(is3D()) {
+ draw(f,G,p,light,name,render,null);
+ if(pic != null && size(G) > 0)
+ pic.addBox(min(G,P),max(G,P),min(q),max(q));
+ }
+ if(pic != null)
+ draw(pic,project(G,P),q);
+ },true);
+ Label L=L.copy();
+ L.align(align);
+ if(L.s != "") {
+ L.p(q);
+ label(pic,L,g);
+ }
+ addPath(pic,g,q);
+}
+
+include three_tube;
+
+draw=new void(frame f, path3 g, material p=currentpen,
+ light light=nolight, string name="",
+ render render=defaultrender,
+ projection P=currentprojection) {
+ pen q=(pen) p;
+ if(is3D()) {
+ p=material(p);
+ real width=linewidth(q);
+ void drawthick(path3 g) {
+ if(settings.thick) {
+ if(width > 0) {
+ bool prc=prc();
+ void cylinder(transform3) {};
+ void sphere(transform3, bool half) {};
+ void disk(transform3) {};
+ void pipe(path3, path3);
+ if(prc) {
+ cylinder=new void(transform3 t) {drawPRCcylinder(f,t,p,light);};
+ sphere=new void(transform3 t, bool half)
+ {drawPRCsphere(f,t,half,p,light,render);};
+ disk=new void(transform3 t) {draw(f,t*unitdisk,p,light,render);};
+ pipe=new void(path3 center, path3 g)
+ {drawPRCtube(f,center,g,p,light);};
+ }
+ real linecap=linecap(q);
+ real r=0.5*width;
+ bool open=!cyclic(g);
+ int L=length(g);
+ triple g0=point(g,0);
+ triple gL=point(g,L);
+ if(open && L > 0) {
+ if(linecap == 2) {
+ g0 -= r*dir(g,0);
+ gL += r*dir(g,L);
+ g=g0..g..gL;
+ L += 2;
+ }
+ }
+ tube T=tube(g,width,render,cylinder,sphere,pipe);
+ path3 c=T.center;
+ if(L >= 0) {
+ if(open) {
+ int Lc=length(c);
+ triple c0=point(c,0);
+ triple cL=point(c,Lc);
+ triple dir0=dir(g,0);
+ triple dirL=dir(g,L);
+ triple dirc0=dir(c,0);
+ triple dircL=dir(c,Lc);
+ transform3 t0=shift(g0)*align(-dir0);
+ transform3 tL=shift(gL)*align(dirL);
+ transform3 tc0=shift(c0)*align(-dirc0);
+ transform3 tcL=shift(cL)*align(dircL);
+ if(linecap == 0 || linecap == 2) {
+ transform3 scale2r=scale(r,r,1);
+ T.s.append(t0*scale2r*unitdisk);
+ disk(tc0*scale2r);
+ if(L > 0) {
+ T.s.append(tL*scale2r*unitdisk);
+ disk(tcL*scale2r);
+ }
+ } else if(linecap == 1) {
+ transform3 scale3r=scale3(r);
+ T.s.append(t0*scale3r*
+ (dir0 != O ? unithemisphere : unitsphere));
+ sphere(tc0*scale3r,half=straight(c,0));
+ if(L > 0) {
+ T.s.append(tL*scale3r*
+ (dirL != O ? unithemisphere : unitsphere));
+ sphere(tcL*scale3r,half=straight(c,Lc-1));
+ }
+ }
+ }
+ if(opacity(q) == 1)
+ _draw(f,c,q);
+ }
+ for(patch s : T.s.s)
+ draw3D(f,s,p,light,prc=false);
+ } else _draw(f,g,q);
+ } else _draw(f,g,q);
+ }
+ bool group=q != nullpen && (name != "" || render.defaultnames);
+ if(group)
+ begingroup3(f,name == "" ? "curve" : name,render);
+ if(linetype(q).length == 0) drawthick(g);
+ else {
+ real[] dash=linetype(adjust(q,arclength(g),cyclic(g)));
+ if(sum(dash) > 0) {
+ dash.cyclic=true;
+ real offset=offset(q);
+ real L=arclength(g);
+ int i=0;
+ real l=offset;
+ while(l <= L) {
+ real t1=arctime(g,l);
+ l += dash[i];
+ real t2=arctime(g,min(l,L));
+ drawthick(subpath(g,t1,t2));
+ ++i;
+ l += dash[i];
+ ++i;
+ }
+ }
+ }
+ if(group)
+ endgroup3(f);
+ } else draw(f,project(g,P),q);
+};
+
+void draw(frame f, explicit path3[] g, material p=currentpen,
+ light light=nolight, string name="",
+ render render=defaultrender, projection P=currentprojection)
+{
+ bool group=g.length > 1 && (name != "" || render.defaultnames);
+ if(group)
+ begingroup3(f,name == "" ? "curves" : name,render);
+ for(int i=0; i < g.length; ++i)
+ draw(f,g[i],p,light,partname(i,render),render,P);
+ if(group)
+ endgroup3(f);
+}
+
+void draw(picture pic=currentpicture, explicit path3[] g,
+ material p=currentpen, margin3 margin=NoMargin3, light light=nolight,
+ string name="", render render=defaultrender)
+{
+ bool group=g.length > 1 && (name != "" || render.defaultnames);
+ if(group)
+ begingroup3(pic,name == "" ? "curves" : name,render);
+ for(int i=0; i < g.length; ++i)
+ draw(pic,g[i],p,margin,light,partname(i,render),render);
+ if(group)
+ endgroup3(pic);
+}
+
+include three_arrows;
+
+void draw(picture pic=currentpicture, Label L="", path3 g,
+ align align=NoAlign, material p=currentpen, arrowbar3 arrow,
+ arrowbar3 bar=None, margin3 margin=NoMargin3, light light=nolight,
+ light arrowheadlight=currentlight, string name="",
+ render render=defaultrender)
+{
+ bool group=arrow != None || bar != None;
+ if(group)
+ begingroup3(pic,name,render);
+ bool drawpath=arrow(pic,g,p,margin,light,arrowheadlight);
+ if(bar(pic,g,p,margin,light,arrowheadlight) && drawpath)
+ draw(pic,L,g,align,p,margin,light,render);
+ if(group)
+ endgroup3(pic);
+ if(L.s != "")
+ label(pic,L,g,align,(pen) p);
+}
+
+void draw(frame f, path3 g, material p=currentpen, arrowbar3 arrow,
+ light light=nolight, light arrowheadlight=currentlight,
+ string name="", render render=defaultrender,
+ projection P=currentprojection)
+{
+ picture pic;
+ bool group=arrow != None;
+ if(group)
+ begingroup3(f,name,render);
+ if(arrow(pic,g,p,NoMargin3,light,arrowheadlight))
+ draw(f,g,p,light,render,P);
+ add(f,pic.fit());
+ if(group)
+ endgroup3(f);
+}
+
+void add(picture pic=currentpicture, void d(picture,transform3),
+ bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+// Fit the picture src using the identity transformation (so user
+// coordinates and truesize coordinates agree) and add it about the point
+// position to picture dest.
+void add(picture dest, picture src, triple position, bool group=true,
+ bool above=true)
+{
+ dest.add(new void(picture f, transform3 t) {
+ f.add(shift(t*position)*src,group,above);
+ });
+}
+
+void add(picture src, triple position, bool group=true, bool above=true)
+{
+ add(currentpicture,src,position,group,above);
+}
+
+// Align an arrow pointing to b from the direction dir. The arrow is
+// 'length' PostScript units long.
+void arrow(picture pic=currentpicture, Label L="", triple b, triple dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar3 arrow=Arrow3, margin3 margin=EndMargin3,
+ light light=nolight, light arrowheadlight=currentlight,
+ string name="", render render=defaultrender)
+{
+ Label L=L.copy();
+ if(L.defaultposition) L.position(0);
+ L.align(L.align,dir);
+ L.p(p);
+ picture opic;
+ marginT3 margin=margin(b--b,p); // Extract margin.begin and margin.end
+ triple a=(margin.begin+length+margin.end)*unit(dir);
+ draw(opic,L,a--O,align,p,arrow,margin,light,arrowheadlight,name,render);
+ add(pic,opic,b);
+}
+
+void arrow(picture pic=currentpicture, Label L="", triple b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar3 arrow=Arrow3, margin3 margin=EndMargin3,
+ light light=nolight, light arrowheadlight=currentlight,
+ string name="", render render=defaultrender,
+ projection P=currentprojection)
+{
+ arrow(pic,L,b,invert(dir,b,P),length,align,p,arrow,margin,light,
+ arrowheadlight,name,render);
+}
+
+triple min3(picture pic, projection P=currentprojection)
+{
+ return pic.min3(P);
+}
+
+triple max3(picture pic, projection P=currentprojection)
+{
+ return pic.max3(P);
+}
+
+triple size3(picture pic, bool user=false, projection P=currentprojection)
+{
+ transform3 t=pic.calculateTransform3(P);
+ triple M=pic.max(t);
+ triple m=pic.min(t);
+ if(!user) return M-m;
+ t=inverse(t);
+ return t*M-t*m;
+}
+
+triple point(frame f, triple dir)
+{
+ triple m=min3(f);
+ triple M=max3(f);
+ return m+realmult(rectify(dir),M-m);
+}
+
+triple point(picture pic=currentpicture, triple dir, bool user=true,
+ projection P=currentprojection)
+{
+ triple min = pic.userMin(), max = pic.userMax();
+ triple v=min+realmult(rectify(dir),max-min);
+ return user ? v : pic.calculateTransform3(P)*v;
+}
+
+triple truepoint(picture pic=currentpicture, triple dir, bool user=true,
+ projection P=currentprojection)
+{
+ transform3 t=pic.calculateTransform3(P);
+ triple m=pic.min(t);
+ triple M=pic.max(t);
+ triple v=m+realmult(rectify(dir),M-m);
+ return user ? inverse(t)*v : v;
+}
+
+void add(picture dest=currentpicture, object src, pair position=0, pair align=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ if(prc())
+ label(dest,src,position,align);
+ else if(settings.render == 0)
+ plain.add(dest,src,position,align,group,filltype,above);
+}
+
+private struct viewpoint {
+ triple target,camera,up;
+ real angle;
+ void operator init(string s) {
+ s=replace(s,'\n'," ");
+ string[] S=split(s);
+ int pos(string s, string key) {
+ int pos=find(s,key);
+ if(pos < 0) return -1;
+ pos += length(key);
+ while(substr(s,pos,1) == " ") ++pos;
+ if(substr(s,pos,1) == "=")
+ return pos+1;
+ return -1;
+ }
+ triple C2C=X;
+ real ROO=1;
+ real ROLL=0;
+ angle=30;
+ int pos;
+ for(int k=0; k < S.length; ++k) {
+ if((pos=pos(S[k],"COO")) >= 0)
+ target=((real) substr(S[k],pos),(real) S[++k],(real) S[++k]);
+ else if((pos=pos(S[k],"C2C")) >= 0)
+ C2C=((real) substr(S[k],pos),(real) S[++k],(real) S[++k]);
+ else if((pos=pos(S[k],"ROO")) >= 0)
+ ROO=(real) substr(S[k],pos);
+ else if((pos=pos(S[k],"ROLL")) >= 0)
+ ROLL=(real) substr(S[k],pos);
+ else if((pos=pos(S[k],"AAC")) >= 0)
+ angle=(real) substr(S[k],pos);
+ }
+ camera=target+ROO*C2C;
+ triple u=unit(target-camera);
+ triple w=unit(Z-u.z*u);
+ up=rotate(ROLL,O,u)*w;
+ }
+}
+
+projection perspective(string s)
+{
+ viewpoint v=viewpoint(s);
+ projection P=perspective(v.camera,v.up,v.target);
+ P.angle=v.angle;
+ P.absolute=true;
+ return P;
+}
+
+projection absorthographic(triple camera=Z, triple target=O, real roll=0)
+{
+ triple u=unit(target-camera);
+ triple w=unit(Z-u.z*u);
+ triple up=rotate(roll,O,u)*w;
+ projection P=
+ projection(camera,up,target,1,0,false,false,
+ new transformation(triple camera, triple up, triple target)
+ {return transformation(look(camera,up,target));});
+ P.absolute=true;
+ return P;
+}
+
+projection absperspective(triple camera=Z, triple target=O, real roll=0,
+ real angle=30)
+{
+ triple u=unit(target-camera);
+ triple w=unit(Z-u.z*u);
+ triple up=rotate(roll,O,u)*w;
+ projection P=perspective(camera,up,target);
+ P.angle=angle;
+ P.absolute=true;
+ return P;
+}
+
+private string Format(real x)
+{
+ assert(abs(x) < 1e17,"Number too large: "+string(x));
+ return format("%.9f",x,"C");
+}
+
+private string Format(triple v, string sep=" ")
+{
+ return Format(v.x)+sep+Format(v.y)+sep+Format(v.z);
+}
+
+private string Format(real[] c)
+{
+ return Format((c[0],c[1],c[2]));
+}
+
+private string format(triple v, string sep=" ")
+{
+ return string(v.x)+sep+string(v.y)+sep+string(v.z);
+}
+
+private string Format(transform3 t, string sep=" ")
+{
+ return
+ Format(t[0][0])+sep+Format(t[1][0])+sep+Format(t[2][0])+sep+
+ Format(t[0][1])+sep+Format(t[1][1])+sep+Format(t[2][1])+sep+
+ Format(t[0][2])+sep+Format(t[1][2])+sep+Format(t[2][2])+sep+
+ Format(t[0][3])+sep+Format(t[1][3])+sep+Format(t[2][3]);
+}
+
+void writeJavaScript(string name, string preamble, string script)
+{
+ file out=output(name);
+ write(out,preamble);
+ if(script != "") {
+ write(out,endl);
+ file in=input(script);
+ while(true) {
+ string line=in;
+ if(eof(in)) break;
+ write(out,line,endl);
+ }
+ }
+ close(out);
+ if(settings.verbose > 1) write("Wrote "+name);
+ if(!settings.inlinetex)
+ file3.push(name);
+}
+
+pair viewportmargin(pair lambda)
+{
+ return maxbound(0.5*(viewportsize-lambda),viewportmargin);
+}
+
+string embed3D(string prefix, string label=prefix, string text=label,
+ frame f, string format="",
+ real width=0, real height=0,
+ string options="", string script="",
+ light light=currentlight, projection P=currentprojection,
+ real viewplanesize=0)
+{
+ if(!prc(format) || Embed == null) return "";
+
+ if(width == 0) width=settings.paperwidth;
+ if(height == 0) height=settings.paperheight;
+
+ if(script == "") script=defaultembed3Dscript;
+
+ if(P.infinity) {
+ if(viewplanesize==0) {
+ triple lambda=max3(f)-min3(f);
+ pair margin=viewportmargin((lambda.x,lambda.y));
+ viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/P.zoom;
+ }
+ } else
+ if(!P.absolute) P.angle=2*aTan(Tan(0.5*P.angle));
+
+ shipout3(prefix,f);
+
+ string name=prefix+".js";
+
+ if(!settings.inlinetex && !prconly())
+ file3.push(prefix+".prc");
+
+ static transform3 flipxz=xscale3(-1)*zscale3(-1);
+ transform3 inv=inverse(flipxz*P.T.modelview);
+
+ string options3="3Dlights="+
+ (light.on() ? "Headlamp" : "None");
+ if(defaultembed3Doptions != "") options3 += ","+defaultembed3Doptions;
+
+ if((settings.render < 0 || !settings.embed) && settings.auto3D)
+ options3 += ",activate=pagevisible";
+ options3 += ",3Dtoolbar="+(settings.toolbar ? "true" : "false")+
+ ",label="+label+
+ (P.infinity ? ",3Dortho="+Format(1/viewplanesize) :
+ ",3Daac="+Format(P.angle))+
+ ",3Dc2w="+Format(inv)+
+ ",3Droo="+Format(abs(P.vector()))+
+ ",3Dpsob="+(P.infinity ? "Max" : "H")+
+ ",3Dbg="+Format(light.background());
+ if(options != "") options3 += ","+options;
+ if(settings.inlinetex)
+ prefix=jobname(prefix);
+ options3 += ",add3Djscript=asylabels.js";
+
+ return text == "" ? Embed(prefix+".prc","",options3,width,height) :
+ "\hbox to 0pt{"+text+"\hss}"+Embed(prefix+".prc","\phantom{"+text+"}",
+ options3);
+}
+
+struct scene
+{
+ frame f;
+ transform3 t;
+ projection P;
+ bool adjusted;
+ real width,height;
+ pair viewportmargin;
+ transform3 T=identity4;
+ picture pic2;
+
+ void operator init(frame f, real width, real height,
+ projection P=currentprojection) {
+ this.f=f;
+ this.t=identity4;
+ this.P=P;
+ this.width=width;
+ this.height=height;
+ }
+
+ void operator init(picture pic, real xsize=pic.xsize, real ysize=pic.ysize,
+ bool keepAspect=pic.keepAspect, bool is3D=true,
+ projection P=currentprojection) {
+ real xsize3=pic.xsize3, ysize3=pic.ysize3, zsize3=pic.zsize3;
+ bool warn=true;
+
+ if(xsize3 == 0 && ysize3 == 0 && zsize3 == 0) {
+ xsize3=ysize3=zsize3=max(xsize,ysize);
+ warn=false;
+ }
+
+ if(P.absolute)
+ this.P=P.copy();
+ else if(P.showtarget)
+ draw(pic,P.target,nullpen);
+
+ t=pic.scaling(xsize3,ysize3,zsize3,keepAspect,warn);
+ adjusted=false;
+ triple m=pic.min(t);
+ triple M=pic.max(t);
+
+ if(!P.absolute) {
+ this.P=t*P;
+ if(this.P.center && settings.render != 0) {
+ triple target=0.5*(m+M);
+ this.P.target=target;
+ this.P.calculate();
+ }
+ if(this.P.autoadjust || this.P.infinity)
+ adjusted=adjusted | this.P.adjust(m,M);
+ }
+
+ bool scale=xsize != 0 || ysize != 0;
+ bool scaleAdjust=scale && this.P.autoadjust;
+ bool noAdjust=(this.P.absolute || !scaleAdjust);
+
+ if(pic.bounds3.exact && noAdjust)
+ this.P.bboxonly=false;
+
+ f=pic.fit3(t,pic.bounds3.exact ? pic2 : null,this.P);
+
+ if(!pic.bounds3.exact) {
+ if(noAdjust)
+ this.P.bboxonly=false;
+
+ transform3 s=pic.scale3(f,xsize3,ysize3,zsize3,keepAspect);
+ t=s*t;
+ this.P=s*this.P;
+ f=pic.fit3(t,pic2,this.P);
+ }
+
+ if(is3D || scale) {
+ pic2.bounds.exact=true;
+ transform s=pic2.scaling(xsize,ysize,keepAspect);
+
+ pair m2=pic2.min(s);
+ pair M2=pic2.max(s);
+ pair lambda=M2-m2;
+ viewportmargin=viewportmargin(lambda);
+ width=ceil(lambda.x+2*viewportmargin.x);
+ height=ceil(lambda.y+2*viewportmargin.y);
+
+ if(!this.P.absolute) {
+ if(scaleAdjust) {
+ pair v=(s.xx,s.yy);
+ transform3 T=this.P.t;
+ pair x=project(X,T);
+ pair y=project(Y,T);
+ pair z=project(Z,T);
+ real f(pair a, pair b) {
+ return b == 0 ? (0.5*(a.x+a.y)) :
+ (b.x^2*a.x+b.y^2*a.y)/(b.x^2+b.y^2);
+ }
+ transform3 s=keepAspect ? scale3(min(f(v,x),f(v,y),f(v,z))) :
+ xscale3(f(v,x))*yscale3(f(v,y))*zscale3(f(v,z));
+ s=shift(this.P.target)*s*shift(-this.P.target);
+ t=s*t;
+ this.P=s*this.P;
+ this.P.bboxonly=false;
+ if(!is3D) pic2.erase();
+ f=pic.fit3(t,is3D ? null : pic2,this.P);
+ }
+
+ if(this.P.autoadjust || this.P.infinity)
+ adjusted=adjusted | this.P.adjust(min3(f),max3(f));
+ }
+ }
+ }
+
+ // Choose the angle to be just large enough to view the entire image.
+ real angle(projection P) {
+ T=identity4;
+ real h=-0.5*P.target.z;
+ pair r,R;
+ real diff=realMax;
+ pair s;
+ int i;
+ do {
+ r=minratio(f);
+ R=maxratio(f);
+ pair lasts=s;
+ if(P.autoadjust) {
+ s=r+R;
+ if(s != 0) {
+ transform3 t=shift(h*s.x,h*s.y,0);
+ f=t*f;
+ T=t*T;
+ adjusted=true;
+ }
+ }
+ diff=abs(s-lasts);
+ ++i;
+ } while (diff > angleprecision && i < maxangleiterations);
+ real aspect=width > 0 ? height/width : 1;
+ real rx=-r.x*aspect;
+ real Rx=R.x*aspect;
+ real ry=-r.y;
+ real Ry=R.y;
+ if(!P.autoadjust) {
+ if(rx > Rx) Rx=rx;
+ else rx=Rx;
+ if(ry > Ry) Ry=ry;
+ else ry=Ry;
+ }
+ return (1+angleprecision)*max(aTan(rx)+aTan(Rx),aTan(ry)+aTan(Ry));
+ }
+}
+
+object embed(string prefix=outprefix(), string label=prefix,
+ string text=label, scene S, string format="", bool view=true,
+ string options="", string script="", light light=currentlight)
+{
+ object F;
+ transform3 modelview;
+ projection P=S.P;
+ transform3 tinv=inverse(S.t);
+
+ projection Q;
+ triple orthoshift;
+ modelview=P.T.modelview;
+ transform3 inv;
+ if(P.absolute) {
+ Q=modelview*P;
+ inv=inverse(modelview);
+ } else {
+ triple target=P.target;
+ S.f=modelview*S.f;
+ P=modelview*P;
+ Q=P.copy();
+
+ if(Q.t[2][3] == -1) // PRC can't handle oblique projections
+ Q=orthographic(P.camera,P.up,P.target,P.zoom,P.viewportshift,
+ P.showtarget,P.center);
+ if(P.infinity) {
+ triple m=min3(S.f);
+ triple M=max3(S.f);
+ triple lambda=M-m;
+ S.viewportmargin=viewportmargin((lambda.x,lambda.y));
+ S.width=ceil(lambda.x+2*S.viewportmargin.x);
+ S.height=ceil(lambda.y+2*S.viewportmargin.y);
+ orthoshift=(-0.5(m.x+M.x),-0.5*(m.y+M.y),0);
+ S.f=shift(orthoshift)*S.f; // Eye will be at (0,0,0)
+ inv=inverse(modelview);
+ } else {
+ if(P.angle == 0) {
+ P.angle=S.angle(P);
+ modelview=S.T*modelview;
+ if(S.viewportmargin.y != 0)
+ P.angle=2*aTan(Tan(0.5*P.angle)-S.viewportmargin.y/P.target.z);
+ }
+ inv=inverse(modelview);
+ Q.angle=P.angle;
+ if(settings.verbose > 0) {
+ if(S.adjusted)
+ write("adjusting camera to ",tinv*inv*P.camera);
+ target=inv*P.target;
+ }
+ P=S.T*P;
+ }
+ if(settings.verbose > 0) {
+ if((P.center && settings.render != 0) || (!P.infinity && P.autoadjust))
+ write("adjusting target to ",tinv*target);
+ }
+ }
+ light Light=modelview*light;
+
+ if(prefix == "") prefix=outprefix();
+ bool prc=prc(format);
+ bool preview=settings.render > 0 && !prconly();
+ if(prc) {
+ // The media9.sty package cannot handle spaces or dots in filenames.
+ string dir=stripfile(prefix);
+ prefix=dir+replace(stripdirectory(prefix),
+ new string[][]{{" ","_"},{".","_"}});
+ if((settings.embed || nativeformat() == "pdf") && !prconly())
+ prefix += "+"+(string) file3.length;
+ } else
+ preview=false;
+ if(preview || (!prc && settings.render != 0)) {
+ frame f=S.f;
+ triple m,M;
+ real zcenter;
+ real r;
+ if(P.absolute) {
+ f=modelview*f;
+ m=min3(f);
+ M=max3(f);
+ r=0.5*abs(M-m);
+ zcenter=0.5*(M.z+m.z);
+ } else {
+ m=min3(f);
+ M=max3(f);
+ zcenter=P.target.z;
+ r=P.distance(m,M);
+ }
+ M=(M.x,M.y,zcenter+r);
+ m=(m.x,m.y,zcenter-r);
+
+ if(P.infinity) {
+ triple margin=(S.viewportmargin.x,S.viewportmargin.y,0);
+ M += margin;
+ m -= margin;
+ } else if(M.z >= 0) abort("camera too close");
+
+ shipout3(prefix,f,preview ? nativeformat() : format,
+ S.width-defaultrender.margin,S.height-defaultrender.margin,
+ P.infinity ? 0 : 2aTan(Tan(0.5*P.angle)*P.zoom),
+ P.zoom,m,M,P.viewportshift,
+ tinv*inv*shift(0,0,zcenter),Light.background(),Light.position,
+ Light.diffuse,Light.specular,
+ view && !preview);
+ if(!preview) return F;
+ }
+
+ string image;
+ if((preview || (prc && settings.render == 0)) && settings.embed) {
+ image=prefix;
+ if(settings.inlinetex) image += "_0";
+ if(!preview && !S.pic2.empty2()) {
+ transform T=S.pic2.scaling(S.width,S.height);
+ _shipout(image,S.pic2.fit(T),newframe,nativeformat(),false,false);
+ }
+
+ image += "."+nativeformat();
+ if(!settings.inlinetex) file3.push(image);
+ image=graphic(image,"hiresbb");
+ }
+ if(prc) {
+ if(P.viewportshift != 0) {
+ if(!P.infinity)
+ warning("offaxis",
+ "PRC does not support off-axis projections; use pan instead of
+shift");
+
+ triple lambda=max3(S.f)-min3(S.f);
+ Q.target -= (P.viewportshift.x*lambda.x/P.zoom,
+ P.viewportshift.y*lambda.y/P.zoom,0);
+ }
+
+ real viewplanesize=0;
+ if(P.absolute) {
+ if(P.infinity) {
+ S.f=modelview*S.f;
+ triple lambda=max3(S.f)-min3(S.f);
+ pair margin=viewportmargin((lambda.x,lambda.y));
+ viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/Q.zoom;
+ S.f=inv*S.f;
+ }
+ Q=inv*Q;
+ } else {
+ if(P.infinity) {
+ triple lambda=max3(S.f)-min3(S.f);
+ pair margin=viewportmargin((lambda.x,lambda.y));
+ viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/(Q.zoom);
+ transform3 t=inv*shift(-orthoshift);
+ Q=t*Q;
+ S.f=t*S.f;
+ } else {
+ Q=inv*Q;
+ S.f=inv*S.f;
+ }
+ }
+ F.L=embed3D(prefix,label,text=image,S.f,format,
+ S.width-2,S.height-2,options,script,light,Q,viewplanesize);
+ }
+ return F;
+}
+
+object embed(string prefix=outprefix(), string label=prefix,
+ string text=label, picture pic, string format="",
+ real xsize=pic.xsize, real ysize=pic.ysize,
+ bool keepAspect=pic.keepAspect, bool view=true, string options="",
+ string script="", light light=currentlight,
+ projection P=currentprojection)
+{
+ bool is3D=is3D(format);
+ scene S=scene(pic,xsize,ysize,keepAspect,is3D,P);
+ if(is3D)
+ return embed(prefix,label,text,S,format,view,options,script,light);
+ else {
+ object F;
+ transform T=S.pic2.scaling(xsize,ysize,keepAspect);
+ F.f=pic.fit(scale(S.t[0][0])*T);
+ add(F.f,S.pic2.fit());
+ return F;
+ }
+}
+
+object embed(string prefix=outprefix(), string label=prefix,
+ string text=label,
+ frame f, string format="", real width=0, real height=0,
+ bool view=true, string options="", string script="",
+ light light=currentlight, projection P=currentprojection)
+{
+ if(is3D(format))
+ return embed(label,text,prefix,scene(f,width,height,P),format,view,options,
+ script,light);
+ else {
+ object F;
+ F.f=f;
+ return F;
+ }
+}
+
+embed3=new object(string prefix, frame f, string format, string options,
+ string script, light light, projection P) {
+ return embed(prefix=prefix,f,format,options,script,light,P);
+};
+
+frame embedder(object embedder(string prefix, string format),
+ string prefix, string format, bool view, light light)
+{
+ frame f;
+ bool prc=prc(format);
+ if(!prc && settings.render != 0 && !view) {
+ static int previewcount=0;
+ bool keep=prefix != "";
+ prefix=outprefix(prefix)+"+"+(string) previewcount;
+ ++previewcount;
+ format=nativeformat();
+ if(!keep) file3.push(prefix+"."+format);
+ }
+ object F=embedder(prefix,format);
+ if(prc)
+ label(f,F.L);
+ else {
+ if(settings.render == 0) {
+ add(f,F.f);
+ if(light.background != nullpen)
+ box(f,light.background,Fill,above=false);
+ } else if(!view)
+ label(f,graphic(prefix,"hiresbb"));
+ }
+ return f;
+}
+
+currentpicture.fitter=new frame(string prefix, picture pic, string format,
+ real xsize, real ysize, bool keepAspect,
+ bool view, string options, string script,
+ light light, projection P) {
+ frame f;
+ bool empty3=pic.empty3();
+ if(!empty3) f=embedder(new object(string prefix, string format) {
+ return embed(prefix=prefix,pic,format,xsize,ysize,keepAspect,view,
+ options,script,light,P);
+ },prefix,format,view,light);
+ if(is3D(format) || empty3) add(f,pic.fit2(xsize,ysize,keepAspect));
+ return f;
+};
+
+frame embedder(string prefix, frame f, string format, real width, real height,
+ bool view, string options, string script, light light,
+ projection P)
+{
+ return embedder(new object(string prefix, string format) {
+ return embed(prefix=prefix,f,format,width,height,view,options,script,
+ light,P);
+ },prefix,format,view,light);
+}
+
+projection[][] ThreeViewsUS={{TopView},
+ {FrontView,RightView}};
+
+projection[][] SixViewsUS={{null,TopView},
+ {LeftView,FrontView,RightView,BackView},
+ {null,BottomView}};
+
+projection[][] ThreeViewsFR={{RightView,FrontView},
+ {null,TopView}};
+
+projection[][] SixViewsFR={{null,BottomView},
+ {RightView,FrontView,LeftView,BackView},
+ {null,TopView}};
+
+projection[][] ThreeViews={{FrontView,TopView,RightView}};
+
+projection[][] SixViews={{FrontView,TopView,RightView},
+ {BackView,BottomView,LeftView}};
+
+void addViews(picture dest, picture src, projection[][] views=SixViewsUS,
+ bool group=true, filltype filltype=NoFill)
+{
+ frame[][] F=array(views.length,new frame[]);
+ pair[][] M=array(views.length,new pair[]);
+ pair[][] m=array(views.length,new pair[]);
+
+ for(int i=0; i < views.length; ++i) {
+ projection[] viewsi=views[i];
+ frame[] Fi=F[i];
+ pair[] Mi=M[i];
+ pair[] mi=m[i];
+ for(projection P : viewsi) {
+ if(P != null) {
+ frame f=src.fit(P);
+ mi.push(min(f));
+ Mi.push(max(f));
+ Fi.push(f);
+ } else {
+ pair Infinity=(infinity,infinity);
+ mi.push(Infinity);
+ Mi.push(-Infinity);
+ Fi.push(newframe);
+ }
+ }
+ }
+
+ real[] my=new real[views.length];
+ real[] My=new real[views.length];
+
+ int Nj=0;
+ for(int i=0; i < views.length; ++i) {
+ my[i]=minbound(m[i]).y;
+ My[i]=maxbound(M[i]).y;
+ Nj=max(Nj,views[i].length);
+ }
+
+ real[] mx=array(Nj,infinity);
+ real[] Mx=array(Nj,-infinity);
+ for(int i=0; i < views.length; ++i) {
+ pair[] mi=m[i];
+ pair[] Mi=M[i];
+ for(int j=0; j < views[i].length; ++j) {
+ mx[j]=min(mx[j],mi[j].x);
+ Mx[j]=max(Mx[j],Mi[j].x);
+ }
+ }
+
+ if(group) begingroup(dest);
+
+ real y;
+ for(int i=0; i < views.length; ++i) {
+ real x;
+ pair[] mi=m[i];
+ for(int j=0; j < views[i].length; ++j) {
+ if(size(F[i][j]) != 0)
+ add(dest,shift(x-mx[j],y+my[i])*F[i][j],filltype);
+ x += (Mx[j]-mx[j]);
+ }
+ y -= (My[i]-my[i]);
+ }
+
+ if(group) endgroup(dest);
+}
+
+void addViews(picture src, projection[][] views=SixViewsUS, bool group=true,
+ filltype filltype=NoFill)
+{
+ addViews(currentpicture,src,views,group,filltype);
+}
+
+void addStereoViews(picture dest, picture src, bool group=true,
+ filltype filltype=NoFill, real eyetoview=defaulteyetoview,
+ bool leftright=true, projection P=currentprojection)
+{
+ triple v=P.vector();
+ triple h=0.5*abs(v)*eyetoview*unit(cross(P.up,v));
+ projection leftEye=P.copy();
+ leftEye.camera -= h;
+ leftEye.calculate();
+ projection rightEye=P.copy();
+ rightEye.camera += h;
+ rightEye.calculate();
+ addViews(dest,src,leftright ?
+ new projection[][] {{leftEye,rightEye}} :
+ new projection[][] {{rightEye,leftEye}},group,filltype);
+}
+
+void addStereoViews(picture src, bool group=true,
+ filltype filltype=NoFill,
+ real eyetoview=defaulteyetoview, bool leftright=true,
+ projection P=currentprojection)
+{
+ addStereoViews(currentpicture,src,group,filltype,eyetoview,leftright,P);
+}
+
+// Fit an array of 3D pictures simultaneously using the sizing of picture all.
+frame[] fit3(string prefix="", picture[] pictures, picture all,
+ string format="", bool view=true, string options="",
+ string script="", light light=currentlight,
+ projection P=currentprojection)
+{
+ frame[] out;
+ scene S=scene(all,P);
+ triple m=all.min(S.t);
+ triple M=all.max(S.t);
+ out=new frame[pictures.length];
+ int i=0;
+ bool reverse=settings.reverse;
+ settings.animating=true;
+
+ for(picture pic : pictures) {
+ picture pic2;
+ frame f=pic.fit3(S.t,pic2,S.P);
+ if(settings.interrupt) break;
+ add(f,pic2.fit2());
+ draw(f,m,nullpen);
+ draw(f,M,nullpen);
+ out[i]=f;
+ ++i;
+ }
+
+ while(!settings.interrupt) {
+ for(int i=settings.reverse ? pictures.length-1 : 0;
+ i >= 0 && i < pictures.length && !settings.interrupt;
+ settings.reverse ? --i : ++i) {
+ frame f=embedder(prefix,out[i],format,S.width,S.height,view,options,
+ script,light,S.P);
+ if(!settings.loop) out[i]=f;
+ }
+ if(!settings.loop) break;
+ }
+
+ settings.animating=false;
+ settings.interrupt=false;
+ settings.reverse=reverse;
+
+ return out;
+}
+
+// Fit an array of pictures simultaneously using the size of the first picture.
+fit=new frame[](string prefix="", picture[] pictures, string format="",
+ bool view=true, string options="", string script="",
+ projection P=currentprojection) {
+ if(pictures.length == 0)
+ return new frame[];
+
+ picture all;
+ size(all,pictures[0]);
+ for(picture pic : pictures)
+ add(all,pic);
+
+ return all.empty3() ? fit2(pictures,all) :
+ fit3(prefix,pictures,all,format,view,options,script,P);
+};
+
+// Add frame src to picture dest about position.
+void add(picture dest=currentpicture, frame src, triple position)
+{
+ if(is3D(src)) {
+ dest.add(new void(frame f, transform3 t, picture, projection) {
+ add(f,shift(t*position)*src);
+ },true);
+ } else {
+ dest.add(new void(frame, transform3 t, picture pic, projection P) {
+ if(pic != null) {
+ pic.add(new void(frame f, transform T) {
+ add(f,T*shift(project(t*position,P))*src);
+ },true);
+ }
+ },true);
+ }
+ dest.addBox(position,position,min3(src),max3(src));
+}
+
+exitfcn currentexitfunction=atexit();
+
+void exitfunction()
+{
+ if(currentexitfunction != null) currentexitfunction();
+ if(!settings.keep)
+ for(int i=0; i < file3.length; ++i)
+ delete(file3[i]);
+ file3=new string[];
+}
+
+atexit(exitfunction);
diff --git a/graphics/asymptote/base/three_arrows.asy b/graphics/asymptote/base/three_arrows.asy
new file mode 100644
index 0000000000..4398b9bd78
--- /dev/null
+++ b/graphics/asymptote/base/three_arrows.asy
@@ -0,0 +1,723 @@
+// A transformation that bends points along a path
+transform3 bend(path3 g, real t)
+{
+ triple dir=dir(g,t);
+ triple a=point(g,0), b=postcontrol(g,0);
+ triple c=precontrol(g,1), d=point(g,1);
+ triple dir1=b-a;
+ triple dir2=c-b;
+ triple dir3=d-c;
+
+ triple u = unit(cross(dir1,dir3));
+ real eps=1000*realEpsilon;
+ if(abs(u) < eps) {
+ u = unit(cross(dir1,dir2));
+ if(abs(u) < eps) {
+ u = unit(cross(dir2,dir3));
+ if(abs(u) < eps)
+ // linear segment: use any direction perpendicular to initial direction
+ u = perp(dir1);
+ }
+ }
+ u = unit(perp(u,dir));
+
+ triple w=cross(dir,u);
+ triple q=point(g,t);
+ return new real[][] {
+ {u.x,w.x,dir.x,q.x},
+ {u.y,w.y,dir.y,q.y},
+ {u.z,w.z,dir.z,q.z},
+ {0,0,0,1}
+ };
+}
+
+// bend a point along a path; assumes that p.z is in [0,scale]
+triple bend(triple p, path3 g, real scale)
+{
+ return bend(g,arctime(g,arclength(g)+p.z-scale))*(p.x,p.y,0);
+}
+
+void bend(surface s, path3 g, real L)
+{
+ for(patch p : s.s) {
+ for(int i=0; i < 4; ++i) {
+ for(int j=0; j < 4; ++j) {
+ p.P[i][j]=bend(p.P[i][j],g,L);
+ }
+ }
+ }
+}
+
+// Refine a noncyclic path3 g so that it approaches its endpoint in
+// geometrically spaced steps.
+path3 approach(path3 p, int n, real radix=3)
+{
+ guide3 G;
+ real L=length(p);
+ real tlast=0;
+ real r=1/radix;
+ for(int i=1; i < n; ++i) {
+ real t=L*(1-r^i);
+ G=G&subpath(p,tlast,t);
+ tlast=t;
+ }
+ return G&subpath(p,tlast,L);
+}
+
+struct arrowhead3
+{
+ arrowhead arrowhead2=DefaultHead;
+ real size(pen p)=arrowsize;
+ real arcsize(pen p)=arcarrowsize;
+ real gap=1;
+ real size;
+ bool splitpath=true;
+
+ surface head(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection);
+
+ static surface surface(path3 g, position position, real size,
+ path[] h, pen p, filltype filltype,
+ triple normal, projection P) {
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ if(filltype == null) filltype=FillDraw(p);
+ bool draw=filltype.type != filltype.Fill;
+ triple v=point(s,length(s));
+ triple N=normal == O ? P.normal : normal;
+ triple w=unit(v-point(s,0));
+ transform3 t=transform3(w,unit(cross(w,N)));
+ path3[] H=t*path3(h);
+ surface s;
+ real width=linewidth(p);
+ if(filltype != NoFill && filltype.type != filltype.UnFill &&
+ filltype.type != filltype.Draw) {
+ triple n=0.5*width*unit(t*Z);
+ s=surface(shift(n)*H,planar=true);
+ s.append(surface(shift(-n)*H,planar=true));
+ if(!draw)
+ for(path g : h)
+ s.append(shift(-n)*t*extrude(g,width*Z));
+ }
+ if(draw)
+ for(path3 g : H)
+ s.append(tube(g,width).s);
+ return shift(v)*s;
+ }
+
+ static path project(path3 g, bool forwards, projection P) {
+ path h=project(forwards ? g : reverse(g),P);
+ return shift(-point(h,length(h)))*h;
+ }
+
+ static path[] align(path H, path h) {
+ static real fuzz=1000*realEpsilon;
+ real[][] t=intersections(H,h,fuzz*max(abs(max(h)),abs(min(h))));
+ return t.length >= 2 ?
+ rotate(-degrees(point(H,t[0][0])-point(H,t[1][0]),warn=false))*H : H;
+ }
+}
+
+arrowhead3 DefaultHead3;
+DefaultHead3.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ bool forwards=true,
+ projection P=currentprojection)
+{
+ if(size == 0) size=DefaultHead3.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ int n=length(s);
+ bool straight1=n == 1 && straight(g,0);
+ real aspect=Tan(angle);
+ real width=size*aspect;
+ surface head;
+ if(straight1) {
+ triple v=point(s,0);
+ triple u=point(s,1)-v;
+ return shift(v)*align(unit(u))*scale(width,width,size)*unitsolidcone;
+ } else {
+ real remainL=size;
+ bool first=true;
+ for(int i=0; i < n; ++i) {
+ render(subpath(s,i,i+1),new void(path3 q, real) {
+ if(remainL > 0) {
+ real l=arclength(q);
+ real w=remainL*aspect;
+ surface segment=scale(w,w,l)*unitcylinder;
+ if(first) { // add base
+ first=false;
+ segment.append(scale(w,w,1)*unitdisk);
+ }
+ for(patch p : segment.s) {
+ for(int i=0; i < 4; ++i) {
+ for(int j=0; j < 4; ++j) {
+ real k=1-p.P[i][j].z/remainL;
+ p.P[i][j]=bend((k*p.P[i][j].x,k*p.P[i][j].y,p.P[i][j].z),q,l);
+ }
+ }
+ }
+ head.append(segment);
+ remainL -= l;
+ }
+ });
+ }
+ }
+ return head;
+};
+
+arrowhead3 HookHead3(real dir=arrowdir, real barb=arrowbarb)
+{
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ bool straight1=length(s) == 1 && straight(g,0);
+ path3 H=path3(HookHead(dir,barb).head((0,0)--(0,size),p,size,angle),
+ YZplane);
+ surface head=surface(O,reverse(approach(subpath(H,1,0),7,1.5))&
+ approach(subpath(H,1,2),4,2),Z);
+
+ if(straight1) {
+ triple v=point(s,0);
+ triple u=point(s,1)-v;
+ return shift(v)*align(unit(u))*head;
+ } else {
+ bend(head,s,size);
+ return head;
+ }
+ };
+ a.arrowhead2=HookHead;
+ a.gap=0.7;
+ return a;
+}
+arrowhead3 HookHead3=HookHead3();
+
+arrowhead3 TeXHead3;
+TeXHead3.size=TeXHead.size;
+TeXHead3.arcsize=TeXHead.size;
+TeXHead3.arrowhead2=TeXHead;
+TeXHead3.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection)
+{
+ real texsize=TeXHead3.size(p);
+ if(size == 0) size=texsize;
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ bool straight1=length(s) == 1 && straight(g,0);
+
+ surface head=surface(O,approach(subpath(path3(TeXHead.head((0,0)--(0,1),p,
+ size),
+ YZplane),5,0),8,1.5),Z);
+ if(straight1) {
+ triple v=point(s,0);
+ triple u=point(s,1)-v;
+ return shift(v)*align(unit(u))*head;
+ } else {
+ path3 s=subpath(r,arctime(r,size/texsize*arrowsize(p)),0);
+ bend(head,s,size);
+ return head;
+ }
+};
+
+path3 arrowbase(path3 r, triple y, real t, real size)
+{
+ triple perp=2*size*perp(dir(r,t));
+ return size == 0 ? y : y+perp--y-perp;
+}
+
+arrowhead3 DefaultHead2(triple normal=O) {
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0,
+ real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+ path h=a.project(g,forwards,P);
+ a.size=min(size,arclength(h));
+ path[] H=a.align(DefaultHead.head(h,p,size,angle),h);
+ H=forwards ? yscale(-1)*H : H;
+ return a.surface(g,position,size,H,p,filltype,normal,P);
+ };
+ a.gap=1.005;
+ return a;
+}
+arrowhead3 DefaultHead2=DefaultHead2();
+
+arrowhead3 HookHead2(real dir=arrowdir, real barb=arrowbarb, triple normal=O)
+{
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+ path h=a.project(g,forwards,P);
+ a.size=min(size,arclength(h));
+ path[] H=a.align(HookHead.head(h,p,size,angle),h);
+ H=forwards ? yscale(-1)*H : H;
+ return a.surface(g,position,size,H,p,filltype,normal,P);
+ };
+ a.arrowhead2=HookHead;
+ a.gap=1.005;
+ return a;
+}
+arrowhead3 HookHead2=HookHead2();
+
+arrowhead3 TeXHead2(triple normal=O) {
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ bool forwards=true, projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+ path h=a.project(g,forwards,P);
+ a.size=min(size,arclength(h));
+ h=rotate(-degrees(dir(h,length(h)),warn=false))*h;
+ path[] H=TeXHead.head(h,p,size,angle);
+ H=forwards ? yscale(-1)*H : H;
+ return a.surface(g,position,size,H,p,
+ filltype == null ? TeXHead.defaultfilltype(p) : filltype,
+ normal,P);
+ };
+ a.arrowhead2=TeXHead;
+ a.size=TeXHead.size;
+ a.splitpath=false;
+ a.gap=1.005;
+ return a;
+}
+arrowhead3 TeXHead2=TeXHead2();
+
+private real position(position position, real size, path3 g, bool center)
+{
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) {
+ position *= arclength(g);
+ if(center) position += 0.5*size;
+ position=arctime(g,position);
+ } else if(center)
+ position=arctime(g,arclength(subpath(g,0,position))+0.5*size);
+ return position;
+}
+
+void drawarrow(picture pic, arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=nullpen,
+ real size=0, real angle=arrowangle, position position=EndPoint,
+ filltype filltype=null, bool forwards=true,
+ margin3 margin=NoMargin3, bool center=false, light light=nolight,
+ light arrowheadlight=currentlight,
+ projection P=currentprojection)
+{
+ pen q=(pen) p;
+ if(filltype != null) {
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.fillpen;
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.drawpen;
+ }
+ if(arrowheadpen == nullpen) arrowheadpen=p;
+ if(size == 0) size=arrowhead.size(q);
+ size=min(arrowsizelimit*arclength(g),size);
+ real position=position(position,size,g,center);
+
+ g=margin(g,q).g;
+ int L=length(g);
+ if(!forwards) {
+ g=reverse(g);
+ position=L-position;
+ }
+ path3 r=subpath(g,position,0);
+ size=min(arrowsizelimit*arclength(r),size);
+ surface head=arrowhead.head(g,position,q,size,angle,filltype,forwards,P);
+ if(arrowhead.size > 0) size=arrowhead.size;
+ bool endpoint=position > L-sqrtEpsilon;
+ if(arrowhead.splitpath || endpoint) {
+ if(position > 0) {
+ real Size=size*arrowhead.gap;
+ draw(pic,subpath(r,arctime(r,Size),length(r)),p,light);
+ }
+ if(!endpoint)
+ draw(pic,subpath(g,position,L),p,light);
+ } else draw(pic,g,p,light);
+ draw(pic,head,arrowheadpen,arrowheadlight);
+}
+
+void drawarrow2(picture pic, arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=nullpen,
+ real size=0, real angle=arrowangle, filltype filltype=null,
+ margin3 margin=NoMargin3, light light=nolight,
+ light arrowheadlight=currentlight,
+ projection P=currentprojection)
+{
+ pen q=(pen) p;
+ if(filltype != null) {
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.fillpen;
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.drawpen;
+ }
+ if(arrowheadpen == nullpen) arrowheadpen=p;
+ if(size == 0) size=arrowhead.size(q);
+ g=margin(g,q).g;
+ size=min(arrow2sizelimit*arclength(g),size);
+
+ path3 r=reverse(g);
+ int L=length(g);
+ real Size=size*arrowhead.gap;
+ draw(pic,subpath(r,arctime(r,Size),L-arctime(g,Size)),p,light);
+ draw(pic,arrowhead.head(g,L,q,size,angle,filltype,forwards=true,P),
+ arrowheadpen,arrowheadlight);
+ draw(pic,arrowhead.head(r,L,q,size,angle,filltype,forwards=false,P),
+ arrowheadpen,arrowheadlight);
+}
+
+// Add to picture an estimate of the bounding box contribution of arrowhead
+// using the local slope at endpoint.
+void addArrow(picture pic, arrowhead3 arrowhead, path3 g, pen p, real size,
+ real angle, filltype filltype, real position)
+{
+ triple v=point(g,position);
+ path3 g=v-(size+linewidth(p))*dir(g,position)--v;
+ surface s=arrowhead.head(g,position,p,size,angle);
+ if(s.s.length > 0) {
+ pic.addPoint(v,min(s)-v);
+ pic.addPoint(v,max(s)-v);
+ } else pic.addPoint(v);
+}
+
+picture arrow(arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=p,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint,
+ bool forwards=true, margin3 margin=NoMargin3,
+ bool center=false, light light=nolight,
+ light arrowheadlight=currentlight)
+{
+ pen q=(pen) p;
+ if(size == 0) size=arrowhead.size(q);
+ picture pic;
+ if(is3D())
+ pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic;
+ drawarrow(opic,arrowhead,t*g,p,arrowheadpen,size,angle,position,
+ filltype,forwards,margin,center,light,arrowheadlight,P);
+ add(f,opic.fit3(identity4,pic2,P));
+ });
+
+ addPath(pic,g,q);
+
+ real position=position(position,size,g,center);
+ path3 G;
+ if(!forwards) {
+ G=reverse(g);
+ position=length(g)-position;
+ } else G=g;
+ addArrow(pic,arrowhead,G,q,size,angle,filltype,position);
+
+ return pic;
+}
+
+picture arrow2(arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=p,
+ real size=0, real angle=arrowangle, filltype filltype=null,
+ margin3 margin=NoMargin3, light light=nolight,
+ light arrowheadlight=currentlight)
+{
+ pen q=(pen) p;
+ if(size == 0) size=arrowhead.size(q);
+ picture pic;
+
+ if(is3D())
+ pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic;
+ drawarrow2(opic,arrowhead,t*g,p,arrowheadpen,size,angle,filltype,
+ margin,light,arrowheadlight,P);
+ add(f,opic.fit3(identity4,pic2,P));
+ });
+
+ addPath(pic,g,q);
+
+ int L=length(g);
+ addArrow(pic,arrowhead,g,q,size,angle,filltype,L);
+ addArrow(pic,arrowhead,reverse(g),q,size,angle,filltype,L);
+
+ return pic;
+}
+
+void add(picture pic, arrowhead3 arrowhead, real size, real angle,
+ filltype filltype, position position, material arrowheadpen,
+ path3 g, material p, bool forwards=true, margin3 margin,
+ bool center=false, light light, light arrowheadlight)
+{
+ add(pic,arrow(arrowhead,g,p,arrowheadpen,size,angle,filltype,position,
+ forwards,margin,center,light,arrowheadlight));
+ if(!is3D()) {
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ if(pic != null) {
+ pen q=(pen) p;
+ path3 G=t*g;
+ marginT3 m=margin(G,q);
+ add(pic,arrow(arrowhead.arrowhead2,project(G,P),q,size,angle,
+ filltype == null ?
+ arrowhead.arrowhead2.defaultfilltype
+ ((pen) arrowheadpen) : filltype,position,
+ forwards,TrueMargin(m.begin,m.end),center));
+ }
+ },true);
+ }
+}
+
+void add2(picture pic, arrowhead3 arrowhead, real size, real angle,
+ filltype filltype, material arrowheadpen, path3 g, material p,
+ margin3 margin, light light, light arrowheadlight)
+{
+ add(pic,arrow2(arrowhead,g,p,arrowheadpen,size,angle,filltype,margin,light,
+ arrowheadlight));
+ if(!is3D()) {
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ if(pic != null) {
+ pen q=(pen) p;
+ path3 G=t*g;
+ marginT3 m=margin(G,q);
+ add(pic,arrow2(arrowhead.arrowhead2,project(G,P),q,size,angle,
+ filltype == null ?
+ arrowhead.arrowhead2.defaultfilltype
+ ((pen) arrowheadpen) : filltype,
+ TrueMargin(m.begin,m.end)));
+ }
+ },true);
+ }
+}
+
+void bar(picture pic, triple a, triple d, triple perp=O,
+ material p=currentpen, light light=nolight)
+{
+ d *= 0.5;
+ perp *= 0.5;
+ pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic;
+ triple A=t*a;
+ triple v=d == O ? abs(perp)*unit(cross(P.normal,perp)) : d;
+ draw(opic,A-v--A+v,p,light);
+ add(f,opic.fit3(identity4,pic2,P));
+ });
+ triple v=d == O ? cross(currentprojection.normal,perp) : d;
+ pen q=(pen) p;
+ triple m=min3(q);
+ triple M=max3(q);
+ pic.addPoint(a,-v-m);
+ pic.addPoint(a,-v+m);
+ pic.addPoint(a,v-M);
+ pic.addPoint(a,v+M);
+}
+
+picture bar(triple a, triple dir, triple perp=O, material p=currentpen)
+{
+ picture pic;
+ bar(pic,a,dir,perp,p);
+ return pic;
+}
+
+typedef bool arrowbar3(picture, path3, material, margin3, light, light);
+
+bool Blank(picture, path3, material, margin3, light, light)
+{
+ return false;
+}
+
+bool None(picture, path3, material, margin3, light, light)
+{
+ return true;
+}
+
+arrowbar3 BeginArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=BeginPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,
+ forwards=false,margin,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 Arrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,margin,
+ light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 EndArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint,
+ material arrowheadpen=nullpen)=Arrow3;
+
+arrowbar3 MidArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add(pic,arrowhead,size,angle,filltype,MidPoint,
+ arrowheadpen,g,p,margin,center=true,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 Arrows3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add2(pic,arrowhead,size,angle,filltype,arrowheadpen,g,p,margin,light,
+ arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 BeginArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=BeginPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,
+ forwards=false,margin,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 ArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=EndPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,margin,
+ light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 EndArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null,
+ position position=EndPoint,
+ material arrowheadpen=nullpen)=ArcArrow3;
+
+
+arrowbar3 MidArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add(pic,arrowhead,size,angle,filltype,MidPoint,arrowheadpen,g,p,margin,
+ center=true,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 ArcArrows3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add2(pic,arrowhead,size,angle,filltype,arrowheadpen,g,p,margin,light,
+ arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 BeginBar3(real size=0, triple dir=O)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin, light light,
+ light) {
+ real size=size == 0 ? barsize((pen) p) : size;
+ bar(pic,point(g,0),size*unit(dir),size*dir(g,0),p,light);
+ return true;
+ };
+}
+
+arrowbar3 Bar3(real size=0, triple dir=O)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin, light light,
+ light) {
+ int L=length(g);
+ real size=size == 0 ? barsize((pen) p) : size;
+ bar(pic,point(g,L),size*unit(dir),size*dir(g,L),p,light);
+ return true;
+ };
+}
+
+arrowbar3 EndBar3(real size=0, triple dir=O)=Bar3;
+
+arrowbar3 Bars3(real size=0, triple dir=O)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin, light light,
+ light) {
+ real size=size == 0 ? barsize((pen) p) : size;
+ BeginBar3(size,dir)(pic,g,p,margin,light,nolight);
+ EndBar3(size,dir)(pic,g,p,margin,light,nolight);
+ return true;
+ };
+}
+
+arrowbar3 BeginArrow3=BeginArrow3(),
+MidArrow3=MidArrow3(),
+Arrow3=Arrow3(),
+EndArrow3=Arrow3(),
+Arrows3=Arrows3(),
+BeginArcArrow3=BeginArcArrow3(),
+MidArcArrow3=MidArcArrow3(),
+ArcArrow3=ArcArrow3(),
+EndArcArrow3=ArcArrow3(),
+ArcArrows3=ArcArrows3(),
+BeginBar3=BeginBar3(),
+Bar3=Bar3(),
+EndBar3=Bar3(),
+Bars3=Bars3();
diff --git a/graphics/asymptote/base/three_light.asy b/graphics/asymptote/base/three_light.asy
new file mode 100644
index 0000000000..6e0bc366c7
--- /dev/null
+++ b/graphics/asymptote/base/three_light.asy
@@ -0,0 +1,133 @@
+struct material {
+ pen[] p; // diffusepen,emissivepen,specularpen
+ real opacity;
+ real shininess;
+ real metallic;
+ real fresnel0; // Reflectance rate at a perfect normal angle.
+
+ void operator init(pen diffusepen=black,
+ pen emissivepen=black, pen specularpen=mediumgray,
+ real opacity=opacity(diffusepen),
+ real shininess=defaultshininess,
+ real metallic=defaultmetallic,
+ real fresnel0=defaultfresnel0) {
+
+ p=new pen[] {diffusepen,emissivepen,specularpen};
+ this.opacity=opacity;
+ this.shininess=shininess;
+ this.metallic=metallic;
+ this.fresnel0=fresnel0;
+ }
+ void operator init(material m) {
+ p=copy(m.p);
+ opacity=m.opacity;
+ shininess=m.shininess;
+ metallic=m.metallic;
+ fresnel0=m.fresnel0;
+ }
+ pen diffuse() {return p[0];}
+ pen emissive() {return p[1];}
+ pen specular() {return p[2];}
+
+ void diffuse(pen q) {p[0]=q;}
+ void emissive(pen q) {p[1]=q;}
+ void specular(pen q) {p[2]=q;}
+}
+
+material operator init()
+{
+ return material();
+}
+
+void write(file file, string s="", material x, suffix suffix=none)
+{
+ write(file,s);
+ write(file,"{");
+ write(file,"diffuse=",x.diffuse());
+ write(file,", emissive=",x.emissive());
+ write(file,", specular=",x.specular());
+ write(file,", opacity=",x.opacity);
+ write(file,", shininess=",x.shininess);
+ write(file,", metallic=",x.metallic);
+ write(file,", F0=",x.fresnel0);
+ write(file,"}",suffix);
+}
+
+void write(string s="", material x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+bool operator == (material m, material n)
+{
+ return all(m.p == n.p) && m.opacity == n.opacity &&
+ m.shininess == n.shininess && m.metallic == n.metallic &&
+ m.fresnel0 == n.fresnel0;
+}
+
+material operator cast(pen p)
+{
+ return material(p);
+}
+
+material[] operator cast(pen[] p)
+{
+ return sequence(new material(int i) {return p[i];},p.length);
+}
+
+pen operator ecast(material m)
+{
+ return m.p.length > 0 ? m.diffuse() : nullpen;
+}
+
+material emissive(material m)
+{
+ return material(black+opacity(m.opacity),m.diffuse(),black,m.opacity,1);
+}
+
+pen color(triple normal, material m, light light, transform3 T=light.T) {
+ triple[] position=light.position;
+ if(invisible((pen) m)) return invisible;
+ if(position.length == 0) return m.diffuse();
+ normal=unit(transpose(inverse(shiftless(T)))*normal);
+ if(settings.twosided) normal *= sgn(normal.z);
+ real s=m.shininess*128;
+ real[] Diffuse=rgba(m.diffuse());
+ real[] Specular=rgba(m.specular());
+ real[] p=rgba(m.emissive());
+ real[] diffuse={0,0,0,0};
+ real[] specular={0,0,0,0};
+ for(int i=0; i < position.length; ++i) {
+ triple L=position[i];
+ real dotproduct=abs(dot(normal,L));
+ diffuse += dotproduct*light.diffuse[i];
+ dotproduct=abs(dot(normal,unit(L+Z)));
+ // Phong-Blinn model of specular reflection
+ specular += dotproduct^s*light.specular[i];
+ }
+ p += diffuse*Diffuse;
+ // Apply specularfactor to partially compensate non-pixel-based rendering.
+ p += specular*Specular*light.specularfactor;
+ return rgb(p[0],p[1],p[2])+opacity(opacity(m.diffuse()));
+}
+
+light operator * (transform3 t, light light)
+{
+ light light=light(light);
+ return light;
+}
+
+light operator cast(triple v) {return light(v);}
+
+light Viewport=light(specularfactor=3,(0.25,-0.25,1));
+
+light White=light(new pen[] {rgb(0.38,0.38,0.45),rgb(0.6,0.6,0.67),
+ rgb(0.5,0.5,0.57)},specularfactor=3,
+ new triple[] {(-2,-1.5,-0.5),(2,1.1,-2.5),(-0.5,0,2)});
+
+light Headlamp=light(gray(0.8),specular=gray(0.7),
+ specularfactor=3,dir(42,48));
+
+currentlight=Headlamp;
+
+light nolight;
diff --git a/graphics/asymptote/base/three_margins.asy b/graphics/asymptote/base/three_margins.asy
new file mode 100644
index 0000000000..b6f286ee4f
--- /dev/null
+++ b/graphics/asymptote/base/three_margins.asy
@@ -0,0 +1,104 @@
+struct marginT3 {
+ path3 g;
+ real begin,end;
+};
+
+typedef marginT3 margin3(path3, pen);
+
+path3 trim(path3 g, real begin, real end) {
+ real a=arctime(g,begin);
+ real b=arctime(g,arclength(g)-end);
+ return a <= b ? subpath(g,a,b) : point(g,a);
+}
+
+margin3 operator +(margin3 ma, margin3 mb)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real ba=ma(g,p).begin < 0 ? 0 : ma(g,p).begin;
+ real bb=mb(g,p).begin < 0 ? 0 : mb(g,p).begin;
+ real ea=ma(g,p).end < 0 ? 0 : ma(g,p).end;
+ real eb=mb(g,p).end < 0 ? 0 : mb(g,p).end;
+ margin.begin=ba+bb;
+ margin.end=ea+eb;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 NoMargin3()
+{
+ return new marginT3(path3 g, pen) {
+ marginT3 margin;
+ margin.begin=margin.end=0;
+ margin.g=g;
+ return margin;
+ };
+}
+
+margin3 Margin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real factor=labelmargin(p);
+ real w=0.5*linewidth(p);
+ margin.begin=begin*factor-w;
+ margin.end=end*factor-w;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 PenMargin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real factor=linewidth(p);
+ margin.begin=begin*factor;
+ margin.end=end*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 DotMargin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real margindot(real x) {return x > 0 ? dotfactor*x : x;}
+ real factor=linewidth(p);
+ margin.begin=margindot(begin)*factor;
+ margin.end=margindot(end)*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 TrueMargin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ margin.begin=begin;
+ margin.end=end;
+ margin.g=trim(g,begin,end);
+ return margin;
+ };
+}
+
+margin3 NoMargin3=NoMargin3(),
+ BeginMargin3=Margin3(1,0),
+ Margin3=Margin3(0,1),
+ EndMargin3=Margin3,
+ Margins3=Margin3(1,1),
+ BeginPenMargin3=PenMargin3(0.5,-0.5),
+ BeginPenMargin2=PenMargin3(1.0,-0.5),
+ PenMargin3=PenMargin3(-0.5,0.5),
+ PenMargin2=PenMargin3(-0.5,1.0),
+ EndPenMargin3=PenMargin3,
+ EndPenMargin2=PenMargin2,
+ PenMargins3=PenMargin3(0.5,0.5),
+ PenMargins2=PenMargin3(1.0,1.0),
+ BeginDotMargin3=DotMargin3(0.5,-0.5),
+ DotMargin3=DotMargin3(-0.5,0.5),
+ EndDotMargin3=DotMargin3,
+ DotMargins3=DotMargin3(0.5,0.5);
diff --git a/graphics/asymptote/base/three_surface.asy b/graphics/asymptote/base/three_surface.asy
new file mode 100644
index 0000000000..bdb56cb0ca
--- /dev/null
+++ b/graphics/asymptote/base/three_surface.asy
@@ -0,0 +1,2455 @@
+import bezulate;
+private import interpolate;
+
+int nslice=12;
+real camerafactor=1.2;
+
+string meshname(string name) {return name+" mesh";}
+
+private real Fuzz=10.0*realEpsilon;
+private real nineth=1/9;
+
+// Return the default Coons interior control point for a Bezier triangle
+// based on the cyclic path3 external.
+triple coons3(path3 external) {
+ return 0.25*(precontrol(external,0)+postcontrol(external,0)+
+ precontrol(external,1)+postcontrol(external,1)+
+ precontrol(external,2)+postcontrol(external,2))-
+ (point(external,0)+point(external,1)+point(external,2))/6;
+}
+
+struct patch {
+ triple[][] P;
+ pen[] colors; // Optionally specify 4 corner colors.
+ bool straight; // Patch is based on a piecewise straight external path.
+ bool3 planar; // Patch is planar.
+ bool triangular; // Patch is a Bezier triangle.
+
+ path3 external() {
+ return straight ? P[0][0]--P[3][0]--P[3][3]--P[0][3]--cycle :
+ P[0][0]..controls P[1][0] and P[2][0]..
+ P[3][0]..controls P[3][1] and P[3][2]..
+ P[3][3]..controls P[2][3] and P[1][3]..
+ P[0][3]..controls P[0][2] and P[0][1]..cycle;
+ }
+
+ path3 externaltriangular() {
+ return
+ P[0][0]..controls P[1][0] and P[2][0]..
+ P[3][0]..controls P[3][1] and P[3][2]..
+ P[3][3]..controls P[2][2] and P[1][1]..cycle;
+ }
+
+ triple[] internal() {
+ return new triple[] {P[1][1],P[2][1],P[2][2],P[1][2]};
+ }
+
+ triple[] internaltriangular() {
+ return new triple[] {P[2][1]};
+ }
+
+ triple cornermean() {
+ return 0.25*(P[0][0]+P[0][3]+P[3][0]+P[3][3]);
+ }
+
+ triple cornermeantriangular() {
+ return (P[0][0]+P[3][0]+P[3][3])/3;
+ }
+
+ triple[] corners() {return new triple[] {P[0][0],P[3][0],P[3][3],P[0][3]};}
+ triple[] cornerstriangular() {return new triple[] {P[0][0],P[3][0],P[3][3]};}
+
+ real[] map(real f(triple)) {
+ return new real[] {f(P[0][0]),f(P[3][0]),f(P[3][3]),f(P[0][3])};
+ }
+
+ real[] maptriangular(real f(triple)) {
+ return new real[] {f(P[0][0]),f(P[3][0]),f(P[3][3])};
+ }
+
+ triple Bu(int j, real u) {return bezier(P[0][j],P[1][j],P[2][j],P[3][j],u);}
+ triple BuP(int j, real u) {
+ return bezierP(P[0][j],P[1][j],P[2][j],P[3][j],u);
+ }
+ triple BuPP(int j, real u) {
+ return bezierPP(P[0][j],P[1][j],P[2][j],P[3][j],u);
+ }
+ triple BuPPP(int j) {return bezierPPP(P[0][j],P[1][j],P[2][j],P[3][j]);}
+
+ path3 uequals(real u) {
+ triple z0=Bu(0,u);
+ triple z1=Bu(3,u);
+ return path3(new triple[] {z0,Bu(2,u)},new triple[] {z0,z1},
+ new triple[] {Bu(1,u),z1},new bool[] {straight,false},false);
+ }
+
+ triple Bv(int i, real v) {return bezier(P[i][0],P[i][1],P[i][2],P[i][3],v);}
+ triple BvP(int i, real v) {
+ return bezierP(P[i][0],P[i][1],P[i][2],P[i][3],v);
+ }
+ triple BvPP(int i, real v) {
+ return bezierPP(P[i][0],P[i][1],P[i][2],P[i][3],v);
+ }
+ triple BvPPP(int i) {return bezierPPP(P[i][0],P[i][1],P[i][2],P[i][3]);}
+
+ path3 vequals(real v) {
+ triple z0=Bv(0,v);
+ triple z1=Bv(3,v);
+ return path3(new triple[] {z0,Bv(2,v)},new triple[] {z0,z1},
+ new triple[] {Bv(1,v),z1},new bool[] {straight,false},false);
+ }
+
+ triple point(real u, real v) {
+ return bezier(Bu(0,u),Bu(1,u),Bu(2,u),Bu(3,u),v);
+ }
+
+ // compute normal vectors for degenerate cases
+ private triple normal0(real u, real v, real epsilon) {
+ triple n=0.5*(cross(bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v),
+ bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u))+
+ cross(bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v),
+ bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u)));
+ return abs(n) > epsilon ? n :
+ 0.25*cross(bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v),
+ bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u))+
+ 1/6*(cross(bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v),
+ bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u))+
+ cross(bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v),
+ bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u)))+
+ 1/12*(cross(bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v),
+ bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u))+
+ cross(bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v),
+ bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u)))+
+ 1/36*cross(bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v),
+ bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u));
+ }
+
+ static real fuzz=1000*realEpsilon;
+
+ triple partialu(real u, real v) {
+ return bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v);
+ }
+
+ triple partialv(real u, real v) {
+ return bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u);
+ }
+
+ triple normal(real u, real v) {
+ triple n=cross(partialu(u,v),partialv(u,v));
+ real epsilon=fuzz*change2(P);
+ return (abs(n) > epsilon) ? n : normal0(u,v,epsilon);
+ }
+
+ triple normal00() {
+ triple n=9*cross(P[1][0]-P[0][0],P[0][1]-P[0][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(0,0,epsilon);
+ }
+
+ triple normal10() {
+ triple n=9*cross(P[3][0]-P[2][0],P[3][1]-P[3][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(1,0,epsilon);
+ }
+
+ triple normal11() {
+ triple n=9*cross(P[3][3]-P[2][3],P[3][3]-P[3][2]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(1,1,epsilon);
+ }
+
+ triple normal01() {
+ triple n=9*cross(P[1][3]-P[0][3],P[0][3]-P[0][2]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(0,1,epsilon);
+ }
+
+ triple pointtriangular(real u, real v) {
+ real w=1-u-v;
+ return w^2*(w*P[0][0]+3*(u*P[1][0]+v*P[1][1]))+
+ u^2*(3*(w*P[2][0]+v*P[3][1])+u*P[3][0])+
+ 6*u*v*w*P[2][1]+v^2*(3*(w*P[2][2]+u*P[3][2])+v*P[3][3]);
+ }
+
+ triple bu(real u, real v) {
+ // Compute one-third of the directional derivative of a Bezier triangle
+ // in the u direction at (u,v).
+ real w=1-u-v;
+ return -w^2*P[0][0]+w*(w-2*u)*P[1][0]-2*w*v*P[1][1]+u*(2*w-u)*P[2][0]+
+ 2*v*(w-u)*P[2][1]-v^2*P[2][2]+u^2*P[3][0]+2*u*v*P[3][1]+v^2*P[3][2];
+ }
+
+ triple buu(real u, real v) {
+ // Compute one-sixth of the second directional derivative of a Bezier
+ // triangle in the u direction at (u,v).
+ real w=1-u-v;
+ return w*P[0][0]+(u-2*w)*P[1][0]+v*P[1][1]+(w-2*u)*P[2][0]-2*v*P[2][1]+
+ u*P[3][0]+v*P[3][1];
+ }
+
+ triple buuu() {
+ // Compute one-sixth of the third directional derivative of a Bezier
+ // triangle in the u direction at (u,v).
+ return -P[0][0]+3*P[1][0]-3*P[2][0]+P[3][0];
+ }
+
+ triple bv(real u, real v) {
+ // Compute one-third of the directional derivative of a Bezier triangle
+ // in the v direction at (u,v).
+ real w=1-u-v;
+ return -w^2*P[0][0]-2*u*w*P[1][0]+w*(w-2*v)*P[1][1]-u^2*P[2][0]+
+ 2*u*(w-v)*P[2][1]+v*(2*w-v)*P[2][2]+u*u*P[3][1]+2*u*v*P[3][2]+
+ v^2*P[3][3];
+ }
+
+ triple bvv(real u, real v) {
+ // Compute one-sixth of the second directional derivative of a Bezier
+ // triangle in the v direction at (u,v).
+ real w=1-u-v;
+ return w*P[0][0]+u*P[1][0]+(v-2*w)*P[1][1]-2*u*P[2][1]+(w-2*v)*P[2][2]+
+ u*P[3][2]+v*P[3][3];
+ }
+
+ triple bvvv() {
+ // Compute one-sixth of the third directional derivative of a Bezier
+ // triangle in the v direction at (u,v).
+ return -P[0][0]+3*P[1][1]-3*P[2][2]+P[3][3];
+ }
+
+ // compute normal vectors for a degenerate Bezier triangle
+ private triple normaltriangular0(real u, real v, real epsilon) {
+ triple n=9*(cross(buu(u,v),bv(u,v))+
+ cross(bu(u,v),bvv(u,v)));
+ return abs(n) > epsilon ? n :
+ 9*cross(buu(u,v),bvv(u,v))+
+ 3*(cross(buuu(),bv(u,v))+cross(bu(u,v),bvvv())+
+ cross(buuu(),bvv(u,v))+cross(buu(u,v),bvvv()))+
+ cross(buuu(),bvvv());
+ }
+
+ // Compute the normal of a Bezier triangle at (u,v)
+ triple normaltriangular(real u, real v) {
+ triple n=9*cross(bu(u,v),bv(u,v));
+ real epsilon=fuzz*change2(P);
+ return (abs(n) > epsilon) ? n : normal0(u,v,epsilon);
+ }
+
+ triple normal00triangular() {
+ triple n=9*cross(P[1][0]-P[0][0],P[1][1]-P[0][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normaltriangular0(0,0,epsilon);
+ }
+
+ triple normal10triangular() {
+ triple n=9*cross(P[3][0]-P[2][0],P[3][1]-P[2][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normaltriangular0(1,0,epsilon);
+ }
+
+ triple normal01triangular() {
+ triple n=9*cross(P[3][2]-P[2][2],P[3][3]-P[2][2]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normaltriangular0(0,1,epsilon);
+ }
+
+ pen[] colors(material m, light light=currentlight) {
+ bool nocolors=colors.length == 0;
+ if(planar) {
+ triple normal=normal(0.5,0.5);
+ return new pen[] {color(normal,nocolors ? m : colors[0],light),
+ color(normal,nocolors ? m : colors[1],light),
+ color(normal,nocolors ? m : colors[2],light),
+ color(normal,nocolors ? m : colors[3],light)};
+ }
+ return new pen[] {color(normal00(),nocolors ? m : colors[0],light),
+ color(normal10(),nocolors ? m : colors[1],light),
+ color(normal11(),nocolors ? m : colors[2],light),
+ color(normal01(),nocolors ? m : colors[3],light)};
+ }
+
+ pen[] colorstriangular(material m, light light=currentlight) {
+ bool nocolors=colors.length == 0;
+ if(planar) {
+ triple normal=normal(1/3,1/3);
+ return new pen[] {color(normal,nocolors ? m : colors[0],light),
+ color(normal,nocolors ? m : colors[1],light),
+ color(normal,nocolors ? m : colors[2],light)};
+ }
+ return new pen[] {color(normal00(),nocolors ? m : colors[0],light),
+ color(normal10(),nocolors ? m : colors[1],light),
+ color(normal01(),nocolors ? m : colors[2],light)};
+ }
+
+ triple min3,max3;
+ bool havemin3,havemax3;
+
+ void init() {
+ havemin3=false;
+ havemax3=false;
+ if(triangular) {
+ external=externaltriangular;
+ internal=internaltriangular;
+ cornermean=cornermeantriangular;
+ corners=cornerstriangular;
+ map=maptriangular;
+ point=pointtriangular;
+ normal=normaltriangular;
+ normal00=normal00triangular;
+ normal10=normal10triangular;
+ normal01=normal01triangular;
+ colors=colorstriangular;
+ uequals=new path3(real u) {return nullpath3;};
+ vequals=new path3(real u) {return nullpath3;};
+ }
+ }
+
+ triple min(triple bound=P[0][0]) {
+ if(havemin3) return minbound(min3,bound);
+ havemin3=true;
+ return min3=minbezier(P,bound);
+ }
+
+ triple max(triple bound=P[0][0]) {
+ if(havemax3) return maxbound(max3,bound);
+ havemax3=true;
+ return max3=maxbezier(P,bound);
+ }
+
+ triple center() {
+ return 0.5*(this.min()+this.max());
+ }
+
+ pair min(projection P, pair bound=project(this.P[0][0],P.t)) {
+ triple[][] Q=P.T.modelview*this.P;
+ if(P.infinity)
+ return xypart(minbezier(Q,(bound.x,bound.y,0)));
+ real d=P.T.projection[3][2];
+ return maxratio(Q,d*bound)/d; // d is negative
+ }
+
+ pair max(projection P, pair bound=project(this.P[0][0],P.t)) {
+ triple[][] Q=P.T.modelview*this.P;
+ if(P.infinity)
+ return xypart(maxbezier(Q,(bound.x,bound.y,0)));
+ real d=P.T.projection[3][2];
+ return minratio(Q,d*bound)/d; // d is negative
+ }
+
+ void operator init(triple[][] P,
+ pen[] colors=new pen[], bool straight=false,
+ bool3 planar=default, bool triangular=false,
+ bool copy=true) {
+ this.P=copy ? copy(P) : P;
+ if(colors.length != 0)
+ this.colors=copy(colors);
+ this.straight=straight;
+ this.planar=planar;
+ this.triangular=triangular;
+ init();
+ }
+
+ void operator init(pair[][] P, triple plane(pair)=XYplane,
+ bool straight=false, bool triangular=false) {
+ triple[][] Q=new triple[4][];
+ for(int i=0; i < 4; ++i) {
+ pair[] Pi=P[i];
+ Q[i]=sequence(new triple(int j) {return plane(Pi[j]);},4);
+ }
+ operator init(Q,straight,planar=true,triangular);
+ }
+
+ void operator init(patch s) {
+ operator init(s.P,s.colors,s.straight,s.planar,s.triangular);
+ }
+
+ // A constructor for a cyclic path3 of length 3 with a specified
+ // internal point, corner normals, and pens (rendered as a Bezier triangle).
+ void operator init(path3 external, triple internal, pen[] colors=new pen[],
+ bool3 planar=default) {
+ triangular=true;
+ this.planar=planar;
+ init();
+ if(colors.length != 0)
+ this.colors=copy(colors);
+
+ P=new triple[][] {
+ {point(external,0)},
+ {postcontrol(external,0),precontrol(external,0)},
+ {precontrol(external,1),internal,postcontrol(external,2)},
+ {point(external,1),postcontrol(external,1),precontrol(external,2),
+ point(external,2)}
+ };
+ }
+
+ // A constructor for a convex cyclic path3 of length <= 4 with optional
+ // arrays of internal points (4 for a Bezier patch, 1 for a Bezier
+ // triangle), and pens.
+ void operator init(path3 external, triple[] internal=new triple[],
+ pen[] colors=new pen[], bool3 planar=default) {
+ if(internal.length == 0 && planar == default)
+ this.planar=normal(external) != O;
+ else this.planar=planar;
+
+ int L=length(external);
+
+ if(L == 3) {
+ operator init(external,internal.length == 1 ? internal[0] :
+ coons3(external),colors,this.planar);
+ straight=piecewisestraight(external);
+ return;
+ }
+
+ if(L > 4 || !cyclic(external))
+ abort("cyclic path3 of length <= 4 expected");
+ if(L == 1) {
+ external=external--cycle--cycle--cycle;
+ if(colors.length > 0) colors.append(array(3,colors[0]));
+ } else if(L == 2) {
+ external=external--cycle--cycle;
+ if(colors.length > 0) colors.append(array(2,colors[0]));
+ }
+
+ init();
+ if(colors.length != 0)
+ this.colors=copy(colors);
+
+ if(internal.length == 0) {
+ straight=piecewisestraight(external);
+ internal=new triple[4];
+ for(int j=0; j < 4; ++j)
+ internal[j]=nineth*(-4*point(external,j)
+ +6*(precontrol(external,j)+postcontrol(external,j))
+ -2*(point(external,j-1)+point(external,j+1))
+ +3*(precontrol(external,j-1)+
+ postcontrol(external,j+1))
+ -point(external,j+2));
+ }
+
+ P=new triple[][] {
+ {point(external,0),precontrol(external,0),postcontrol(external,3),
+ point(external,3)},
+ {postcontrol(external,0),internal[0],internal[3],precontrol(external,3)},
+ {precontrol(external,1),internal[1],internal[2],postcontrol(external,2)},
+ {point(external,1),postcontrol(external,1),precontrol(external,2),
+ point(external,2)}
+ };
+ }
+
+ // A constructor for a convex quadrilateral.
+ void operator init(triple[] external, triple[] internal=new triple[],
+ pen[] colors=new pen[], bool3 planar=default) {
+ init();
+
+ if(internal.length == 0 && planar == default)
+ this.planar=normal(external) != O;
+ else this.planar=planar;
+
+ if(colors.length != 0)
+ this.colors=copy(colors);
+
+ if(internal.length == 0) {
+ internal=new triple[4];
+ for(int j=0; j < 4; ++j)
+ internal[j]=nineth*(4*external[j]+2*external[(j+1)%4]+
+ external[(j+2)%4]+2*external[(j+3)%4]);
+ }
+
+ straight=true;
+
+ triple delta[]=new triple[4];
+ for(int j=0; j < 4; ++j)
+ delta[j]=(external[(j+1)% 4]-external[j])/3;
+
+ P=new triple[][] {
+ {external[0],external[0]-delta[3],external[3]+delta[3],external[3]},
+ {external[0]+delta[0],internal[0],internal[3],external[3]-delta[2]},
+ {external[1]-delta[0],internal[1],internal[2],external[2]+delta[2]},
+ {external[1],external[1]+delta[1],external[2]-delta[1],external[2]}
+ };
+ }
+}
+
+patch operator * (transform3 t, patch s)
+{
+ patch S;
+ S.P=new triple[s.P.length][];
+ for(int i=0; i < s.P.length; ++i) {
+ triple[] si=s.P[i];
+ triple[] Si=S.P[i];
+ for(int j=0; j < si.length; ++j)
+ Si[j]=t*si[j];
+ }
+
+ S.colors=copy(s.colors);
+ S.planar=s.planar;
+ S.straight=s.straight;
+ S.triangular=s.triangular;
+ S.init();
+ return S;
+}
+
+patch reverse(patch s)
+{
+ assert(!s.triangular);
+ patch S;
+ S.P=transpose(s.P);
+ if(s.colors.length > 0)
+ S.colors=new pen[] {s.colors[0],s.colors[3],s.colors[2],s.colors[1]};
+ S.straight=s.straight;
+ S.planar=s.planar;
+ return S;
+}
+
+// Return a degenerate tensor patch representation of a Bezier triangle.
+patch tensor(patch s) {
+ if(!s.triangular) return patch(s);
+ triple[][] P=s.P;
+ return patch(new triple[][] {{P[0][0],P[0][0],P[0][0],P[0][0]},
+ {P[1][0],P[1][0]*2/3+P[1][1]/3,P[1][0]/3+P[1][1]*2/3,P[1][1]},
+ {P[2][0],P[2][0]/3+P[2][1]*2/3,P[2][1]*2/3+P[2][2]/3,P[2][2]},
+ {P[3][0],P[3][1],P[3][2],P[3][3]}},
+ s.colors.length > 0 ? new pen[] {s.colors[0],s.colors[1],s.colors[2],s.colors[0]} : new pen[],
+ s.straight,s.planar,false,false);
+}
+
+// Return the tensor product patch control points corresponding to path p
+// and points internal.
+pair[][] tensor(path p, pair[] internal)
+{
+ return new pair[][] {
+ {point(p,0),precontrol(p,0),postcontrol(p,3),point(p,3)},
+ {postcontrol(p,0),internal[0],internal[3],precontrol(p,3)},
+ {precontrol(p,1),internal[1],internal[2],postcontrol(p,2)},
+ {point(p,1),postcontrol(p,1),precontrol(p,2),point(p,2)}
+ };
+}
+
+// Return the Coons patch control points corresponding to path p.
+pair[][] coons(path p)
+{
+ int L=length(p);
+ if(L == 1)
+ p=p--cycle--cycle--cycle;
+ else if(L == 2)
+ p=p--cycle--cycle;
+ else if(L == 3)
+ p=p--cycle;
+
+ pair[] internal=new pair[4];
+ for(int j=0; j < 4; ++j) {
+ internal[j]=nineth*(-4*point(p,j)
+ +6*(precontrol(p,j)+postcontrol(p,j))
+ -2*(point(p,j-1)+point(p,j+1))
+ +3*(precontrol(p,j-1)+postcontrol(p,j+1))
+ -point(p,j+2));
+ }
+ return tensor(p,internal);
+}
+
+// Decompose a possibly nonconvex cyclic path into an array of paths that
+// yield nondegenerate Coons patches.
+path[] regularize(path p, bool checkboundary=true)
+{
+ path[] s;
+
+ if(!cyclic(p))
+ abort("cyclic path expected");
+
+ int L=length(p);
+
+ if(L > 4) {
+ for(path g : bezulate(p))
+ s.append(regularize(g,checkboundary));
+ return s;
+ }
+
+ bool straight=piecewisestraight(p);
+ if(L <= 3 && straight) {
+ return new path[] {p};
+ }
+
+ // Split p along the angle bisector at t.
+ bool split(path p, real t) {
+ pair dir=dir(p,t);
+ if(dir != 0) {
+ path g=subpath(p,t,t+length(p));
+ int L=length(g);
+ pair z=point(g,0);
+ real[] T=intersections(g,z,z+I*dir);
+ for(int i=0; i < T.length; ++i) {
+ real cut=T[i];
+ if(cut > sqrtEpsilon && cut < L-sqrtEpsilon) {
+ pair w=point(g,cut);
+ if(!inside(p,0.5*(z+w),zerowinding)) continue;
+ pair delta=sqrtEpsilon*(w-z);
+ if(intersections(g,z-delta--w+delta).length != 2) continue;
+ s.append(regularize(subpath(g,0,cut)--cycle,checkboundary));
+ s.append(regularize(subpath(g,cut,L)--cycle,checkboundary));
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ // Ensure that all interior angles are less than 180 degrees.
+ real fuzz=1e-4;
+ int sign=sgn(windingnumber(p,inside(p,zerowinding)));
+ for(int i=0; i < L; ++i) {
+ if(sign*(conj(dir(p,i,-1))*dir(p,i,1)).y < -fuzz) {
+ if(split(p,i)) return s;
+ }
+ }
+
+ if(straight)
+ return new path[] {p};
+
+ pair[][] P=coons(p);
+
+ // Check for degeneracy.
+ pair[][] U=new pair[3][4];
+ pair[][] V=new pair[4][3];
+
+ for(int i=0; i < 3; ++i) {
+ for(int j=0; j < 4; ++j)
+ U[i][j]=P[i+1][j]-P[i][j];
+ }
+
+ for(int i=0; i < 4; ++i) {
+ for(int j=0; j < 3; ++j)
+ V[i][j]=P[i][j+1]-P[i][j];
+ }
+
+ int[] choose2={1,2,1};
+ int[] choose3={1,3,3,1};
+
+ real T[][]=new real[6][6];
+ for(int p=0; p < 6; ++p) {
+ int kstart=max(p-2,0);
+ int kstop=min(p,3);
+ real[] Tp=T[p];
+ for(int q=0; q < 6; ++q) {
+ real Tpq;
+ int jstop=min(q,3);
+ int jstart=max(q-2,0);
+ for(int k=kstart; k <= kstop; ++k) {
+ int choose3k=choose3[k];
+ for(int j=jstart; j <= jstop; ++j) {
+ int i=p-k;
+ int l=q-j;
+ Tpq += (conj(U[i][j])*V[k][l]).y*
+ choose2[i]*choose3k*choose3[j]*choose2[l];
+ }
+ }
+ Tp[q]=Tpq;
+ }
+ }
+
+ bool3 aligned=default;
+ bool degenerate=false;
+
+ for(int p=0; p < 6; ++p) {
+ for(int q=0; q < 6; ++q) {
+ if(aligned == default) {
+ if(T[p][q] > sqrtEpsilon) aligned=true;
+ if(T[p][q] < -sqrtEpsilon) aligned=false;
+ } else {
+ if((T[p][q] > sqrtEpsilon && aligned == false) ||
+ (T[p][q] < -sqrtEpsilon && aligned == true)) degenerate=true;
+ }
+ }
+ }
+
+ if(!degenerate) {
+ if(aligned == (sign >= 0))
+ return new path[] {p};
+ return s;
+ }
+
+ if(checkboundary) {
+ // Polynomial coefficients of (B_i'' B_j + B_i' B_j')/3.
+ static real[][][] fpv0={
+ {{5, -20, 30, -20, 5},
+ {-3, 24, -54, 48, -15},
+ {0, -6, 27, -36, 15},
+ {0, 0, -3, 8, -5}},
+ {{-7, 36, -66, 52, -15},
+ {3, -36, 108, -120, 45},
+ {0, 6, -45, 84, -45},
+ {0, 0, 3, -16, 15}},
+ {{2, -18, 45, -44, 15},
+ {0, 12, -63, 96, -45},
+ {0, 0, 18, -60, 45},
+ {0, 0, 0, 8, -15}},
+ {{0, 2, -9, 12, -5},
+ {0, 0, 9, -24, 15},
+ {0, 0, 0, 12, -15},
+ {0, 0, 0, 0, 5}}
+ };
+
+ // Compute one-ninth of the derivative of the Jacobian along the boundary.
+ real[][] c=array(4,array(5,0.0));
+ for(int i=0; i < 4; ++i) {
+ real[][] fpv0i=fpv0[i];
+ for(int j=0; j < 4; ++j) {
+ real[] w=fpv0i[j];
+ c[0] += w*(conj(P[i][0])*(P[j][1]-P[j][0])).y; // v=0
+ c[1] += w*(conj(P[3][j]-P[2][j])*P[3][i]).y; // u=1
+ c[2] += w*(conj(P[i][3])*(P[j][3]-P[j][2])).y; // v=1
+ c[3] += w*(conj(P[0][j]-P[1][j])*P[0][i]).y; // u=0
+ }
+ }
+
+ pair BuP(int j, real u) {
+ return bezierP(P[0][j],P[1][j],P[2][j],P[3][j],u);
+ }
+ pair BvP(int i, real v) {
+ return bezierP(P[i][0],P[i][1],P[i][2],P[i][3],v);
+ }
+ real normal(real u, real v) {
+ return (conj(bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v))*
+ bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u)).y;
+ }
+
+ // Use Rolle's theorem to check for degeneracy on the boundary.
+ real M=0;
+ real cut;
+ for(int i=0; i < 4; ++i) {
+ if(!straight(p,i)) {
+ real[] ci=c[i];
+ pair[] R=quarticroots(ci[4],ci[3],ci[2],ci[1],ci[0]);
+ for(pair r : R) {
+ if(fabs(r.y) < sqrtEpsilon) {
+ real t=r.x;
+ if(0 <= t && t <= 1) {
+ real[] U={t,1,t,0};
+ real[] V={0,t,1,t};
+ real[] T={t,t,1-t,1-t};
+ real N=sign*normal(U[i],V[i]);
+ if(N < M) {
+ M=N; cut=i+T[i];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Split at the worst boundary degeneracy.
+ if(M < 0 && split(p,cut)) return s;
+ }
+
+ // Split arbitrarily to resolve any remaining (internal) degeneracy.
+ checkboundary=false;
+ for(int i=0; i < L; ++i)
+ if(!straight(p,i) && split(p,i+0.5)) return s;
+
+ while(true)
+ for(int i=0; i < L; ++i)
+ if(!straight(p,i) && split(p,i+unitrand())) return s;
+
+ return s;
+}
+
+struct surface {
+ patch[] s;
+ int index[][];// Position of patch corresponding to major U,V parameter in s.
+ bool vcyclic;
+
+ bool empty() {
+ return s.length == 0;
+ }
+
+ void operator init(int n) {
+ s=new patch[n];
+ }
+
+ void operator init(... patch[] s) {
+ this.s=s;
+ }
+
+ void operator init(surface s) {
+ this.s=new patch[s.s.length];
+ for(int i=0; i < s.s.length; ++i)
+ this.s[i]=patch(s.s[i]);
+ this.index=copy(s.index);
+ this.vcyclic=s.vcyclic;
+ }
+
+ void operator init(triple[][][] P, pen[][] colors=new pen[][],
+ bool3 planar=default, bool triangular=false) {
+ s=sequence(new patch(int i) {
+ return patch(P[i],colors.length == 0 ? new pen[] : colors[i],planar,
+ triangular);
+ },P.length);
+ }
+
+ void colors(pen[][] palette) {
+ for(int i=0; i < s.length; ++i)
+ s[i].colors=copy(palette[i]);
+ }
+
+ triple[][] corners() {
+ triple[][] a=new triple[s.length][];
+ for(int i=0; i < s.length; ++i)
+ a[i]=s[i].corners();
+ return a;
+ }
+
+ real[][] map(real f(triple)) {
+ real[][] a=new real[s.length][];
+ for(int i=0; i < s.length; ++i)
+ a[i]=s[i].map(f);
+ return a;
+ }
+
+ triple[] cornermean() {
+ return sequence(new triple(int i) {return s[i].cornermean();},s.length);
+ }
+
+ triple point(real u, real v) {
+ int U=floor(u);
+ int V=floor(v);
+ int index=index.length == 0 ? U+V : index[U][V];
+ return s[index].point(u-U,v-V);
+ }
+
+ triple normal(real u, real v) {
+ int U=floor(u);
+ int V=floor(v);
+ int index=index.length == 0 ? U+V : index[U][V];
+ return s[index].normal(u-U,v-V);
+ }
+
+ void ucyclic(bool f)
+ {
+ index.cyclic=f;
+ }
+
+ void vcyclic(bool f)
+ {
+ for(int[] i : index)
+ i.cyclic=f;
+ vcyclic=f;
+ }
+
+ bool ucyclic()
+ {
+ return index.cyclic;
+ }
+
+ bool vcyclic()
+ {
+ return vcyclic;
+ }
+
+ path3 uequals(real u) {
+ if(index.length == 0) return nullpath3;
+ int U=floor(u);
+ int[] index=index[U];
+ path3 g;
+ for(int i : index)
+ g=g&s[i].uequals(u-U);
+ return vcyclic() ? g&cycle : g;
+ }
+
+ path3 vequals(real v) {
+ if(index.length == 0) return nullpath3;
+ int V=floor(v);
+ path3 g;
+ for(int[] i : index)
+ g=g&s[i[V]].vequals(v-V);
+ return ucyclic() ? g&cycle : g;
+ }
+
+ // A constructor for a possibly nonconvex simple cyclic path in a given
+ // plane.
+ void operator init(path p, triple plane(pair)=XYplane) {
+ for(path g : regularize(p)) {
+ if(length(g) == 3) {
+ path3 G=path3(g,plane);
+ s.push(patch(G,coons3(G),planar=true));
+ } else
+ s.push(patch(coons(g),plane,piecewisestraight(g)));
+ }
+ }
+
+ void operator init(explicit path[] g, triple plane(pair)=XYplane) {
+ for(path p : bezulate(g))
+ s.append(surface(p,plane).s);
+ }
+
+ // A general surface constructor for both planar and nonplanar 3D paths.
+ void construct(path3 external, triple[] internal=new triple[],
+ pen[] colors=new pen[], bool3 planar=default) {
+ int L=length(external);
+ if(!cyclic(external)) abort("cyclic path expected");
+
+ if(L <= 3 && piecewisestraight(external)) {
+ s.push(patch(external,internal,colors,planar));
+ return;
+ }
+
+ // Construct a surface from a possibly nonconvex planar cyclic path3.
+ if(planar != false && internal.length == 0 && colors.length == 0) {
+ triple n=normal(external);
+ if(n != O) {
+ transform3 T=align(n);
+ external=transpose(T)*external;
+ T *= shift(0,0,point(external,0).z);
+ for(patch p : surface(path(external)).s)
+ s.push(T*p);
+ return;
+ }
+ }
+
+ if(L <= 4 || internal.length > 0) {
+ s.push(patch(external,internal,colors,planar));
+ return;
+ }
+
+ // Path is not planar; split into patches.
+ real factor=1/L;
+ pen[] p;
+ triple[] n;
+ bool nocolors=colors.length == 0;
+ triple center;
+ for(int i=0; i < L; ++i)
+ center += point(external,i);
+ center *= factor;
+ if(!nocolors)
+ p=new pen[] {mean(colors)};
+ // Use triangles for nonplanar surfaces.
+ int step=normal(external) == O ? 1 : 2;
+ int i=0;
+ int end;
+ while((end=i+step) < L) {
+ s.push(patch(subpath(external,i,end)--center--cycle,
+ nocolors ? p : concat(colors[i:end+1],p),planar));
+ i=end;
+ }
+ s.push(patch(subpath(external,i,L)--center--cycle,
+ nocolors ? p : concat(colors[i:],colors[0:1],p),planar));
+ }
+
+ void operator init(path3 external, triple[] internal=new triple[],
+ pen[] colors=new pen[], bool3 planar=default) {
+ s=new patch[];
+ construct(external,internal,colors,planar);
+ }
+
+ void operator init(explicit path3[] external,
+ triple[][] internal=new triple[][],
+ pen[][] colors=new pen[][], bool3 planar=default) {
+ s=new patch[];
+ if(planar == true) {// Assume all path3 elements share a common normal.
+ if(external.length != 0) {
+ triple n=normal(external[0]);
+ if(n != O) {
+ transform3 T=align(n);
+ external=transpose(T)*external;
+ T *= shift(0,0,point(external[0],0).z);
+ path[] g=sequence(new path(int i) {return path(external[i]);},
+ external.length);
+ for(patch p : surface(g).s)
+ s.push(T*p);
+ return;
+ }
+ }
+ }
+
+ for(int i=0; i < external.length; ++i)
+ construct(external[i],
+ internal.length == 0 ? new triple[] : internal[i],
+ colors.length == 0 ? new pen[] : colors[i],planar);
+ }
+
+ void push(path3 external, triple[] internal=new triple[],
+ pen[] colors=new pen[], bool3 planar=default) {
+ s.push(patch(external,internal,colors,planar));
+ }
+
+ // Construct the surface of rotation generated by rotating g
+ // from angle1 to angle2 sampled n times about the line c--c+axis.
+ // An optional surface pen color(int i, real j) may be specified
+ // to override the color at vertex(i,j).
+ void operator init(triple c, path3 g, triple axis, int n=nslice,
+ real angle1=0, real angle2=360,
+ pen color(int i, real j)=null) {
+ axis=unit(axis);
+ real w=(angle2-angle1)/n;
+ int L=length(g);
+ s=new patch[L*n];
+ index=new int[n][L];
+ int m=-1;
+ transform3[] T=new transform3[n+1];
+ transform3 t=rotate(w,c,c+axis);
+ T[0]=rotate(angle1,c,c+axis);
+ for(int k=1; k <= n; ++k)
+ T[k]=T[k-1]*t;
+
+ typedef pen colorfcn(int i, real j);
+ bool defaultcolors=(colorfcn) color == null;
+
+ for(int i=0; i < L; ++i) {
+ path3 h=subpath(g,i,i+1);
+ path3 r=reverse(h);
+ path3 H=shift(-c)*h;
+ real M=0;
+ triple perp;
+ void test(real[] t) {
+ for(int i=0; i < 3; ++i) {
+ triple v=point(H,t[i]);
+ triple V=v-dot(v,axis)*axis;
+ real a=abs(V);
+ if(a > M) {M=a; perp=V;}
+ }
+ }
+ test(maxtimes(H));
+ test(mintimes(H));
+
+ perp=unit(perp);
+ triple normal=unit(cross(axis,perp));
+ triple dir(real j) {return Cos(j)*normal-Sin(j)*perp;}
+ real j=angle1;
+ transform3 Tk=T[0];
+ triple dirj=dir(j);
+ for(int k=0; k < n; ++k, j += w) {
+ transform3 Tp=T[k+1];
+ triple dirp=dir(j+w);
+ path3 G=reverse(Tk*h{dirj}..{dirp}Tp*r{-dirp}..{-dirj}cycle);
+ Tk=Tp;
+ dirj=dirp;
+ s[++m]=defaultcolors ? patch(G) :
+ patch(G,new pen[] {color(i,j),color(i,j+w),color(i+1,j+w),
+ color(i+1,j)});
+ index[k][i]=m;
+ }
+ ucyclic((angle2-angle1) % 360 == 0);
+ vcyclic(cyclic(g));
+ }
+ }
+
+ void push(patch s) {
+ this.s.push(s);
+ }
+
+ void append(surface s) {
+ this.s.append(s.s);
+ }
+
+ void operator init(... surface[] s) {
+ for(surface S : s)
+ this.s.append(S.s);
+ }
+}
+
+surface operator * (transform3 t, surface s)
+{
+ surface S;
+ S.s=new patch[s.s.length];
+ for(int i=0; i < s.s.length; ++i)
+ S.s[i]=t*s.s[i];
+ S.index=copy(s.index);
+ S.vcyclic=(bool) s.vcyclic;
+
+ return S;
+}
+
+private string nullsurface="null surface";
+
+triple min(surface s)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ triple bound=s.s[0].min();
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].min(bound);
+ return bound;
+}
+
+triple max(surface s)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ triple bound=s.s[0].max();
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].max(bound);
+ return bound;
+}
+
+pair min(surface s, projection P)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ pair bound=s.s[0].min(P);
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].min(P,bound);
+ return bound;
+}
+
+pair max(surface s, projection P)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ pair bound=s.s[0].max(P);
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].max(P,bound);
+ return bound;
+}
+
+private triple[] split(triple z0, triple c0, triple c1, triple z1, real t=0.5)
+{
+ triple m0=interp(z0,c0,t);
+ triple m1=interp(c0,c1,t);
+ triple m2=interp(c1,z1,t);
+ triple m3=interp(m0,m1,t);
+ triple m4=interp(m1,m2,t);
+ triple m5=interp(m3,m4,t);
+
+ return new triple[] {m0,m3,m5,m4,m2};
+}
+
+// Return the control points of the subpatches
+// produced by a horizontal split of P
+triple[][][] hsplit(triple[][] P, real v=0.5)
+{
+ // get control points in rows
+ triple[] P0=P[0];
+ triple[] P1=P[1];
+ triple[] P2=P[2];
+ triple[] P3=P[3];
+
+ triple[] c0=split(P0[0],P0[1],P0[2],P0[3],v);
+ triple[] c1=split(P1[0],P1[1],P1[2],P1[3],v);
+ triple[] c2=split(P2[0],P2[1],P2[2],P2[3],v);
+ triple[] c3=split(P3[0],P3[1],P3[2],P3[3],v);
+ // bottom, top
+ return new triple[][][] {
+ {{P0[0],c0[0],c0[1],c0[2]},
+ {P1[0],c1[0],c1[1],c1[2]},
+ {P2[0],c2[0],c2[1],c2[2]},
+ {P3[0],c3[0],c3[1],c3[2]}},
+ {{c0[2],c0[3],c0[4],P0[3]},
+ {c1[2],c1[3],c1[4],P1[3]},
+ {c2[2],c2[3],c2[4],P2[3]},
+ {c3[2],c3[3],c3[4],P3[3]}}
+ };
+}
+
+// Return the control points of the subpatches
+// produced by a vertical split of P
+triple[][][] vsplit(triple[][] P, real u=0.5)
+{
+ // get control points in rows
+ triple[] P0=P[0];
+ triple[] P1=P[1];
+ triple[] P2=P[2];
+ triple[] P3=P[3];
+
+ triple[] c0=split(P0[0],P1[0],P2[0],P3[0],u);
+ triple[] c1=split(P0[1],P1[1],P2[1],P3[1],u);
+ triple[] c2=split(P0[2],P1[2],P2[2],P3[2],u);
+ triple[] c3=split(P0[3],P1[3],P2[3],P3[3],u);
+ // left, right
+ return new triple[][][] {
+ {{P0[0],P0[1],P0[2],P0[3]},
+ {c0[0],c1[0],c2[0],c3[0]},
+ {c0[1],c1[1],c2[1],c3[1]},
+ {c0[2],c1[2],c2[2],c3[2]}},
+ {{c0[2],c1[2],c2[2],c3[2]},
+ {c0[3],c1[3],c2[3],c3[3]},
+ {c0[4],c1[4],c2[4],c3[4]},
+ {P3[0],P3[1],P3[2],P3[3]}}
+ };
+}
+
+// Return a 2D array of the control point arrays of the subpatches
+// produced by horizontal and vertical splits of P at u and v
+triple[][][][] split(triple[][] P, real u=0.5, real v=0.5)
+{
+ triple[] P0=P[0];
+ triple[] P1=P[1];
+ triple[] P2=P[2];
+ triple[] P3=P[3];
+
+ // slice horizontally
+ triple[] c0=split(P0[0],P0[1],P0[2],P0[3],v);
+ triple[] c1=split(P1[0],P1[1],P1[2],P1[3],v);
+ triple[] c2=split(P2[0],P2[1],P2[2],P2[3],v);
+ triple[] c3=split(P3[0],P3[1],P3[2],P3[3],v);
+
+ // bottom patch
+ triple[] c4=split(P0[0],P1[0],P2[0],P3[0],u);
+ triple[] c5=split(c0[0],c1[0],c2[0],c3[0],u);
+ triple[] c6=split(c0[1],c1[1],c2[1],c3[1],u);
+ triple[] c7=split(c0[2],c1[2],c2[2],c3[2],u);
+
+ // top patch
+ triple[] c8=split(c0[3],c1[3],c2[3],c3[3],u);
+ triple[] c9=split(c0[4],c1[4],c2[4],c3[4],u);
+ triple[] cA=split(P0[3],P1[3],P2[3],P3[3],u);
+
+ // {{bottom-left, top-left}, {bottom-right, top-right}}
+ return new triple[][][][] {
+ {{{P0[0],c0[0],c0[1],c0[2]},
+ {c4[0],c5[0],c6[0],c7[0]},
+ {c4[1],c5[1],c6[1],c7[1]},
+ {c4[2],c5[2],c6[2],c7[2]}},
+ {{c0[2],c0[3],c0[4],P0[3]},
+ {c7[0],c8[0],c9[0],cA[0]},
+ {c7[1],c8[1],c9[1],cA[1]},
+ {c7[2],c8[2],c9[2],cA[2]}}},
+ {{{c4[2],c5[2],c6[2],c7[2]},
+ {c4[3],c5[3],c6[3],c7[3]},
+ {c4[4],c5[4],c6[4],c7[4]},
+ {P3[0],c3[0],c3[1],c3[2]}},
+ {{c7[2],c8[2],c9[2],cA[2]},
+ {c7[3],c8[3],c9[3],cA[3]},
+ {c7[4],c8[4],c9[4],cA[4]},
+ {c3[2],c3[3],c3[4],P3[3]}}}
+ };
+}
+
+// Return the control points for a subpatch of P on [u,1] x [v,1].
+triple[][] subpatchend(triple[][] P, real u, real v)
+{
+ triple[] P0=P[0];
+ triple[] P1=P[1];
+ triple[] P2=P[2];
+ triple[] P3=P[3];
+
+ triple[] c0=split(P0[0],P0[1],P0[2],P0[3],v);
+ triple[] c1=split(P1[0],P1[1],P1[2],P1[3],v);
+ triple[] c2=split(P2[0],P2[1],P2[2],P2[3],v);
+ triple[] c3=split(P3[0],P3[1],P3[2],P3[3],v);
+
+ triple[] c7=split(c0[2],c1[2],c2[2],c3[2],u);
+ triple[] c8=split(c0[3],c1[3],c2[3],c3[3],u);
+ triple[] c9=split(c0[4],c1[4],c2[4],c3[4],u);
+ triple[] cA=split(P0[3],P1[3],P2[3],P3[3],u);
+
+ return new triple[][] {
+ {c7[2],c8[2],c9[2],cA[2]},
+ {c7[3],c8[3],c9[3],cA[3]},
+ {c7[4],c8[4],c9[4],cA[4]},
+ {c3[2],c3[3],c3[4],P3[3]}};
+}
+
+// Return the control points for a subpatch of P on [0,u] x [0,v].
+triple[][] subpatchbegin(triple[][] P, real u, real v)
+{
+ triple[] P0=P[0];
+ triple[] P1=P[1];
+ triple[] P2=P[2];
+ triple[] P3=P[3];
+
+ triple[] c0=split(P0[0],P0[1],P0[2],P0[3],v);
+ triple[] c1=split(P1[0],P1[1],P1[2],P1[3],v);
+ triple[] c2=split(P2[0],P2[1],P2[2],P2[3],v);
+ triple[] c3=split(P3[0],P3[1],P3[2],P3[3],v);
+
+ triple[] c4=split(P0[0],P1[0],P2[0],P3[0],u);
+ triple[] c5=split(c0[0],c1[0],c2[0],c3[0],u);
+ triple[] c6=split(c0[1],c1[1],c2[1],c3[1],u);
+ triple[] c7=split(c0[2],c1[2],c2[2],c3[2],u);
+
+ return new triple[][] {
+ {P0[0],c0[0],c0[1],c0[2]},
+ {c4[0],c5[0],c6[0],c7[0]},
+ {c4[1],c5[1],c6[1],c7[1]},
+ {c4[2],c5[2],c6[2],c7[2]}};
+}
+
+triple[][] subpatch(triple[][] P, pair a, pair b)
+{
+ return subpatchend(subpatchbegin(P,b.x,b.y),a.x/b.x,a.y/b.y);
+}
+
+patch subpatch(patch s, pair a, pair b)
+{
+ assert(a.x >= 0 && a.y >= 0 && b.x <= 1 && b.y <= 1 &&
+ a.x < b.x && a.y < b.y && !s.triangular);
+ return patch(subpatch(s.P,a,b),s.straight,s.planar);
+}
+
+private string triangular=
+ "Intersection of path3 with Bezier triangle is not yet implemented";
+
+// return an array containing the times for one intersection of path p and
+// patch s.
+real[] intersect(path3 p, patch s, real fuzz=-1)
+{
+ if(s.triangular) abort(triangular);
+ return intersect(p,s.P,fuzz);
+}
+
+// return an array containing the times for one intersection of path p and
+// surface s.
+real[] intersect(path3 p, surface s, real fuzz=-1)
+{
+ for(int i=0; i < s.s.length; ++i) {
+ real[] T=intersect(p,s.s[i],fuzz);
+ if(T.length > 0) return T;
+ }
+ return new real[];
+}
+
+// return an array containing all intersection times of path p and patch s.
+real[][] intersections(path3 p, patch s, real fuzz=-1)
+{
+ if(s.triangular) abort(triangular);
+ return sort(intersections(p,s.P,fuzz));
+}
+
+// return an array containing all intersection times of path p and surface s.
+real[][] intersections(path3 p, surface s, real fuzz=-1)
+{
+ real[][] T;
+ if(length(p) < 0) return T;
+ for(int i=0; i < s.s.length; ++i)
+ for(real[] s: intersections(p,s.s[i],fuzz))
+ T.push(s);
+
+ static real Fuzz=1000*realEpsilon;
+ real fuzz=max(10*fuzz,Fuzz*max(abs(min(s)),abs(max(s))));
+
+ // Remove intrapatch duplicate points.
+ for(int i=0; i < T.length; ++i) {
+ triple v=point(p,T[i][0]);
+ for(int j=i+1; j < T.length;) {
+ if(abs(v-point(p,T[j][0])) < fuzz)
+ T.delete(j);
+ else ++j;
+ }
+ }
+ return sort(T);
+}
+
+// return an array containing all intersection points of path p and surface s.
+triple[] intersectionpoints(path3 p, patch s, real fuzz=-1)
+{
+ real[][] t=intersections(p,s,fuzz);
+ return sequence(new triple(int i) {return point(p,t[i][0]);},t.length);
+}
+
+// return an array containing all intersection points of path p and surface s.
+triple[] intersectionpoints(path3 p, surface s, real fuzz=-1)
+{
+ real[][] t=intersections(p,s,fuzz);
+ return sequence(new triple(int i) {return point(p,t[i][0]);},t.length);
+}
+
+// Return true iff the control point bounding boxes of patches p and q overlap.
+bool overlap(triple[][] p, triple[][] q, real fuzz=-1)
+{
+ triple pmin=minbound(p);
+ triple pmax=maxbound(p);
+ triple qmin=minbound(q);
+ triple qmax=maxbound(q);
+
+ if(fuzz == -1)
+ fuzz=1000*realEpsilon*max(abs(pmin),abs(pmax),abs(qmin),abs(qmax));
+
+ return
+ pmax.x+fuzz >= qmin.x &&
+ pmax.y+fuzz >= qmin.y &&
+ pmax.z+fuzz >= qmin.z &&
+ qmax.x+fuzz >= pmin.x &&
+ qmax.y+fuzz >= pmin.y &&
+ qmax.z+fuzz >= pmin.z; // Overlapping bounding boxes?
+}
+
+triple point(patch s, real u, real v)
+{
+ return s.point(u,v);
+}
+
+real PRCshininess(real shininess)
+{
+ // Empirical translation table from Phong-Blinn to PRC shininess model:
+ static real[] x={0.015,0.025,0.05,0.07,0.1,0.14,0.23,0.5,0.65,0.75,0.85,
+ 0.875,0.9,1};
+ static real[] y={0.05,0.1,0.15,0.2,0.25,0.3,0.4,0.5,0.55,0.6,0.7,0.8,0.9,1};
+ static realfunction s=fspline(x,y,monotonic);
+ return s(shininess);
+}
+
+struct interaction
+{
+ int type;
+ bool targetsize;
+ void operator init(int type, bool targetsize=false) {
+ this.type=type;
+ this.targetsize=targetsize;
+ }
+}
+
+restricted interaction Embedded=interaction(0);
+restricted interaction Billboard=interaction(1);
+
+interaction LabelInteraction()
+{
+ return settings.autobillboard ? Billboard : Embedded;
+}
+
+material material(material m, light light)
+{
+ return light.on() || invisible((pen) m) ? m : emissive(m);
+}
+
+void draw3D(frame f, int type=0, patch s, triple center=O, material m,
+ light light=currentlight, interaction interaction=Embedded,
+ bool prc=true)
+{
+ if(s.colors.length > 0)
+ m=mean(s.colors);
+ m=material(m,light);
+ real PRCshininess;
+ if(prc())
+ PRCshininess=PRCshininess(m.shininess);
+
+ (s.triangular ? drawbeziertriangle : draw)
+ (f,s.P,center,s.straight && s.planar,m.p,m.opacity,m.shininess,
+ m.metallic,m.fresnel0,PRCshininess,s.colors,interaction.type,prc);
+}
+
+int computeNormals(triple[] v, int[][] vi, triple[] n, int[][] ni)
+{
+ triple lastnormal=O;
+ for(int i=0; i < vi.length; ++i) {
+ int[] vii=vi[i];
+ int[] nii=ni[i];
+ triple normal=normal(new triple[] {v[vii[0]],v[vii[1]],v[vii[2]]});
+ if(normal != lastnormal || n.length == 0) {
+ n.push(normal);
+ lastnormal=normal;
+ }
+ nii[0]=nii[1]=nii[2]=n.length-1;
+ }
+ return ni.length;
+}
+
+// Draw triangles on a frame.
+void draw(frame f, triple[] v, int[][] vi,
+ triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
+ int[][] pi={}, light light=currentlight)
+{
+ bool normals=ni.length > 0;
+ if(!normals) {
+ ni=new int[vi.length][3];
+ normals=computeNormals(v,vi,n,ni) > 0;
+ }
+ if(p.length > 0)
+ m=mean(p);
+ m=material(m,light);
+ real PRCshininess;
+ if(prc())
+ PRCshininess=PRCshininess(m.shininess);
+ draw(f,v,vi,n,ni,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+ PRCshininess,p,pi);
+}
+
+// Draw triangles on a picture.
+void draw(picture pic=currentpicture, triple[] v, int[][] vi,
+ triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
+ int[][] pi={}, light light=currentlight)
+{
+ bool normals=ni.length > 0;
+ if(!normals) {
+ ni=new int[vi.length][3];
+ normals=computeNormals(v,vi,n,ni) > 0;
+ }
+ bool colors=pi.length > 0;
+
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ triple[] v=t*v;
+ triple[] n=t*n;
+
+ if(is3D()) {
+ draw(f,v,vi,n,ni,m,p,pi,light);
+ if(pic != null) {
+ for(int[] vii : vi)
+ for(int viij : vii)
+ pic.addPoint(project(v[viij],P));
+ }
+ } else if(pic != null) {
+ static int[] edges={0,0,1};
+ if(colors) {
+ for(int i=0; i < vi.length; ++i) {
+ int[] vii=vi[i];
+ int[] pii=pi[i];
+ gouraudshade(pic,project(v[vii[0]],P)--project(v[vii[1]],P)--
+ project(v[vii[2]],P)--cycle,
+ new pen[] {p[pii[0]],p[pii[1]],p[pii[2]]},edges);
+ }
+ } else {
+ if(normals) {
+ for(int i=0; i < vi.length; ++i) {
+ int[] vii=vi[i];
+ int[] nii=ni[i];
+ gouraudshade(pic,project(v[vii[0]],P)--project(v[vii[1]],P)--
+ project(v[vii[2]],P)--cycle,
+ new pen[] {color(n[nii[0]],m,light),
+ color(n[nii[1]],m,light),
+ color(n[nii[2]],m,light)},edges);
+ }
+ } else {
+ for(int i=0; i < vi.length; ++i) {
+ int[] vii=vi[i];
+ path g=project(v[vii[0]],P)--project(v[vii[1]],P)--
+ project(v[vii[2]],P)--cycle;
+ pen p=color(n[ni[i][0]],m,light);
+ fill(pic,g,p);
+ if(opacity(m.diffuse()) == 1) // Fill subdivision cracks
+ draw(pic,g,p);
+ }
+ }
+ }
+ }
+ },true);
+
+ for(int[] vii : vi)
+ for(int viij : vii)
+ pic.addPoint(v[viij]);
+}
+
+void drawPRCsphere(frame f, transform3 t=identity4, bool half=false,
+ material m, light light=currentlight,
+ render render=defaultrender)
+{
+ m=material(m,light);
+ drawPRCsphere(f,t,half,m.p,m.opacity,PRCshininess(m.shininess),
+ render.sphere);
+}
+
+void drawPRCcylinder(frame f, transform3 t=identity4, material m,
+ light light=currentlight)
+{
+ m=material(m,light);
+ drawPRCcylinder(f,t,m.p,m.opacity,PRCshininess(m.shininess));
+}
+
+void drawPRCdisk(frame f, transform3 t=identity4, material m,
+ light light=currentlight)
+{
+ m=material(m,light);
+ drawPRCdisk(f,t,m.p,m.opacity,PRCshininess(m.shininess));
+}
+
+void drawPRCtube(frame f, path3 center, path3 g, material m,
+ light light=currentlight)
+{
+ m=material(m,light);
+ drawPRCtube(f,center,g,m.p,m.opacity,PRCshininess(m.shininess));
+}
+
+void tensorshade(transform t=identity(), frame f, patch s,
+ material m, light light=currentlight, projection P)
+{
+
+ pen[] p;
+ if(s.triangular) {
+ p=s.colorstriangular(m,light);
+ p.push(p[0]);
+ s=tensor(s);
+ } else p=s.colors(m,light);
+ tensorshade(f,box(t*s.min(P),t*s.max(P)),m.diffuse(),
+ p,t*project(s.external(),P,1),t*project(s.internal(),P));
+}
+
+restricted pen[] nullpens={nullpen};
+nullpens.cyclic=true;
+
+void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender, projection P=currentprojection)
+{
+ bool is3D=is3D();
+ if(is3D) {
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(f,name == "" ? "surface" : name,render);
+
+ // Sort patches by mean distance from camera
+ triple camera=P.camera;
+ if(P.infinity) {
+ triple m=min(s);
+ triple M=max(s);
+ camera=P.target+camerafactor*(abs(M-m)+abs(m-P.target))*unit(P.vector());
+ }
+
+ real[][] depth=new real[s.s.length][];
+ for(int i=0; i < depth.length; ++i)
+ depth[i]=new real[] {dot(P.normal,camera-s.s[i].cornermean()),i};
+
+ depth=sort(depth);
+
+ for(int p=depth.length-1; p >= 0; --p) {
+ real[] a=depth[p];
+ int k=round(a[1]);
+ draw3D(f,s.s[k],surfacepen[k],light);
+ }
+
+ if(group)
+ endgroup3(f);
+
+ pen modifiers=thin()+squarecap;
+ for(int p=depth.length-1; p >= 0; --p) {
+ real[] a=depth[p];
+ int k=round(a[1]);
+ patch S=s.s[k];
+ pen meshpen=meshpen[k];
+ if(!invisible(meshpen) && !S.triangular) {
+ if(group)
+ begingroup3(f,meshname(name),render);
+ meshpen=modifiers+meshpen;
+ real step=nu == 0 ? 0 : 1/nu;
+ for(int i=0; i <= nu; ++i)
+ draw(f,S.uequals(i*step),meshpen,meshlight,partname(i,render),
+ render);
+ step=nv == 0 ? 0 : 1/nv;
+ for(int j=0; j <= nv; ++j)
+ draw(f,S.vequals(j*step),meshpen,meshlight,partname(j,render),
+ render);
+ if(group)
+ endgroup3(f);
+ }
+ }
+ }
+ if(!is3D || settings.render == 0) {
+ begingroup(f);
+ // Sort patches by mean distance from camera
+ triple camera=P.camera;
+ if(P.infinity) {
+ triple m=min(s);
+ triple M=max(s);
+ camera=P.target+camerafactor*(abs(M-m)+abs(m-P.target))*unit(P.vector());
+ }
+
+ real[][] depth=new real[s.s.length][];
+ for(int i=0; i < depth.length; ++i)
+ depth[i]=new real[] {dot(P.normal,camera-s.s[i].cornermean()),i};
+
+ depth=sort(depth);
+
+ light.T=shiftless(P.T.modelview);
+
+ // Draw from farthest to nearest
+ for(int p=depth.length-1; p >= 0; --p) {
+ real[] a=depth[p];
+ int k=round(a[1]);
+ tensorshade(t,f,s.s[k],surfacepen[k],light,P);
+ pen meshpen=meshpen[k];
+ if(!invisible(meshpen))
+ draw(f,t*project(s.s[k].external(),P),meshpen);
+ }
+ endgroup(f);
+ }
+}
+
+void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender, projection P=currentprojection)
+{
+ material[] surfacepen={surfacepen};
+ pen[] meshpen={meshpen};
+ surfacepen.cyclic=true;
+ meshpen.cyclic=true;
+ draw(t,f,s,nu,nv,surfacepen,meshpen,light,meshlight,name,render,P);
+}
+
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender)
+{
+ if(s.empty()) return;
+
+ bool cyclic=surfacepen.cyclic;
+ surfacepen=copy(surfacepen);
+ surfacepen.cyclic=cyclic;
+ cyclic=meshpen.cyclic;
+ meshpen=copy(meshpen);
+ meshpen.cyclic=cyclic;
+
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ surface S=t*s;
+ if(is3D())
+ draw(f,S,nu,nv,surfacepen,meshpen,light,meshlight,name,render);
+ if(pic != null) {
+ pic.add(new void(frame f, transform T) {
+ draw(T,f,S,nu,nv,surfacepen,meshpen,light,meshlight,P);
+ },true);
+ pic.addPoint(min(S,P));
+ pic.addPoint(max(S,P));
+ }
+ },true);
+ pic.addPoint(min(s));
+ pic.addPoint(max(s));
+
+ pen modifiers;
+ if(is3D()) modifiers=thin()+squarecap;
+ for(int k=0; k < s.s.length; ++k) {
+ patch S=s.s[k];
+ pen meshpen=meshpen[k];
+ if(!invisible(meshpen) && !S.triangular) {
+ meshpen=modifiers+meshpen;
+ real step=nu == 0 ? 0 : 1/nu;
+ for(int i=0; i <= nu; ++i)
+ addPath(pic,s.s[k].uequals(i*step),meshpen);
+ step=nv == 0 ? 0 : 1/nv;
+ for(int j=0; j <= nv; ++j)
+ addPath(pic,s.s[k].vequals(j*step),meshpen);
+ }
+ }
+}
+
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender)
+{
+ material[] surfacepen={surfacepen};
+ pen[] meshpen={meshpen};
+ surfacepen.cyclic=true;
+ meshpen.cyclic=true;
+ draw(pic,s,nu,nv,surfacepen,meshpen,light,meshlight,name,render);
+}
+
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen meshpen,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender)
+{
+ pen[] meshpen={meshpen};
+ meshpen.cyclic=true;
+ draw(pic,s,nu,nv,surfacepen,meshpen,light,meshlight,name,render);
+}
+
+surface extrude(path3 p, path3 q)
+{
+ static patch[] allocate;
+ return surface(...sequence(new patch(int i) {
+ return patch(subpath(p,i,i+1)--subpath(q,i+1,i)--cycle);
+ },length(p)));
+}
+
+surface extrude(path3 p, triple axis=Z)
+{
+ return extrude(p,shift(axis)*p);
+}
+
+surface extrude(path p, triple plane(pair)=XYplane, triple axis=Z)
+{
+ return extrude(path3(p,plane),axis);
+}
+
+surface extrude(explicit path[] p, triple axis=Z)
+{
+ surface s;
+ for(path g:p)
+ s.append(extrude(g,axis));
+ return s;
+}
+
+triple rectify(triple dir)
+{
+ real scale=max(abs(dir.x),abs(dir.y),abs(dir.z));
+ if(scale != 0) dir *= 0.5/scale;
+ dir += (0.5,0.5,0.5);
+ return dir;
+}
+
+path3[] align(path3[] g, transform3 t=identity4, triple position,
+ triple align, pen p=currentpen)
+{
+ if(determinant(t) == 0 || g.length == 0) return g;
+ triple m=min(g);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(g)-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a)*g;
+}
+
+surface align(surface s, transform3 t=identity4, triple position,
+ triple align, pen p=currentpen)
+{
+ if(determinant(t) == 0 || s.s.length == 0) return s;
+ triple m=min(s);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(s)-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a)*s;
+}
+
+surface surface(Label L, triple position=O, bool bbox=false)
+{
+ surface s=surface(texpath(L,bbox=bbox));
+ return L.align.is3D ? align(s,L.T3,position,L.align.dir3,L.p) :
+ shift(position)*L.T3*s;
+}
+
+private path[] path(Label L, pair z=0, projection P)
+{
+ path[] g=texpath(L,bbox=P.bboxonly);
+ return L.align.is3D ? align(g,z,project(L.align.dir3,P)-project(O,P),L.p) :
+ shift(z)*g;
+}
+
+transform3 alignshift(path3[] g, transform3 t=identity4, triple position,
+ triple align)
+{
+ if(determinant(t) == 0) return identity4;
+ triple m=min(g);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(g)-m);
+ return shift(-a);
+}
+
+transform3 alignshift(surface s, transform3 t=identity4, triple position,
+ triple align)
+{
+ if(determinant(t) == 0) return identity4;
+ triple m=min(s);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(s)-m);
+ return shift(-a);
+}
+
+transform3 aligntransform(path3[] g, transform3 t=identity4, triple position,
+ triple align, pen p=currentpen)
+{
+ if(determinant(t) == 0) return identity4;
+ triple m=min(g);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(g)-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a);
+}
+
+transform3 aligntransform(surface s, transform3 t=identity4, triple position,
+ triple align, pen p=currentpen)
+{
+ if(determinant(t) == 0) return identity4;
+ triple m=min(s);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(s)-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a);
+}
+
+void label(frame f, Label L, triple position, align align=NoAlign,
+ pen p=currentpen, light light=nolight,
+ string name="", render render=defaultrender,
+ interaction interaction=LabelInteraction(),
+ projection P=currentprojection)
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ if(interaction.targetsize && settings.render != 0)
+ L.T=L.T*scale(abs(P.camera-position)/abs(P.vector()));
+ transform3 T=transform3(P);
+ if(L.defaulttransform3)
+ L.T3=T;
+
+ if(is3D()) {
+ bool lighton=light.on();
+ if(name == "") name=L.s;
+ if(prc() && interaction.type == Billboard.type) {
+ surface s=surface(texpath(L));
+ transform3 centering=L.align.is3D ?
+ alignshift(s,L.T3,position,L.align.dir3) : identity4;
+ transform3 positioning=
+ shift(L.align.is3D ? position+L.align.dir3*labelmargin(L.p) : position);
+ frame f1,f2,f3;
+ begingroup3(f1,name,render);
+ if(L.defaulttransform3)
+ begingroup3(f3,render,position,interaction.type);
+ else {
+ begingroup3(f2,render,position,interaction.type);
+ begingroup3(f3,render,position);
+ }
+ for(patch S : s.s) {
+ S=centering*S;
+ draw3D(f3,S,position,L.p,light,interaction);
+ // Fill subdivision cracks
+ if(render.labelfill && opacity(L.p) == 1 && !lighton)
+ _draw(f3,S.external(),position,L.p,interaction.type);
+ }
+ endgroup3(f3);
+ if(L.defaulttransform3)
+ add(f1,T*f3);
+ else {
+ add(f2,inverse(T)*L.T3*f3);
+ endgroup3(f2);
+ add(f1,T*f2);
+ }
+ endgroup3(f1);
+ add(f,positioning*f1);
+ } else {
+ begingroup3(f,name,render);
+ for(patch S : surface(L,position).s) {
+ triple V=L.align.is3D ? position+L.align.dir3*labelmargin(L.p) :
+ position;
+ draw3D(f,S,V,L.p,light,interaction);
+ // Fill subdivision cracks
+ if(render.labelfill && opacity(L.p) == 1 && !lighton)
+ _draw(f,S.external(),V,L.p,interaction.type);
+ }
+ endgroup3(f);
+ }
+ } else {
+ pen p=color(L.T3*Z,L.p,light,shiftless(P.T.modelview));
+ if(L.defaulttransform3) {
+ if(L.filltype == NoFill)
+ fill(f,path(L,project(position,P.t),P),p);
+ else {
+ frame d;
+ fill(d,path(L,project(position,P.t),P),p);
+ add(f,d,L.filltype);
+ }
+ } else
+ for(patch S : surface(L,position).s)
+ fill(f,project(S.external(),P,1),p);
+ }
+}
+
+void label(picture pic=currentpicture, Label L, triple position,
+ align align=NoAlign, pen p=currentpen,
+ light light=nolight, string name="",
+ render render=defaultrender,
+ interaction interaction=LabelInteraction())
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ L.position(0);
+
+ pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
+ // Handle relative projected 3D alignments.
+ Label L=L.copy();
+ triple v=t*position;
+ if(!align.is3D && L.align.relative && L.align.dir3 != O &&
+ determinant(P.t) != 0)
+ L.align(L.align.dir*unit(project(v+L.align.dir3,P.t)-project(v,P.t)));
+
+ if(interaction.targetsize && settings.render != 0)
+ L.T=L.T*scale(abs(P.camera-v)/abs(P.vector()));
+ transform3 T=transform3(P);
+ if(L.defaulttransform3)
+ L.T3=T;
+
+ if(is3D()) {
+ bool lighton=light.on();
+ if(name == "") name=L.s;
+ if(prc() && interaction.type == Billboard.type) {
+ surface s=surface(texpath(L,bbox=P.bboxonly));
+ transform3 centering=L.align.is3D ?
+ alignshift(s,L.T3,v,L.align.dir3) : identity4;
+ transform3 positioning=
+ shift(L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v);
+ frame f1,f2,f3;
+ begingroup3(f1,name,render);
+ if(L.defaulttransform3)
+ begingroup3(f3,render,v,interaction.type);
+ else {
+ begingroup3(f2,render,v,interaction.type);
+ begingroup3(f3,render,v);
+ }
+ for(patch S : s.s) {
+ S=centering*S;
+ draw3D(f3,S,v,L.p,light,interaction);
+ // Fill subdivision cracks
+ if(render.labelfill && opacity(L.p) == 1 && !lighton)
+ _draw(f3,S.external(),v,L.p,interaction.type);
+ }
+ endgroup3(f3);
+ if(L.defaulttransform3)
+ add(f1,T*f3);
+ else {
+ add(f2,inverse(T)*L.T3*f3);
+ endgroup3(f2);
+ add(f1,T*f2);
+ }
+ endgroup3(f1);
+ add(f,positioning*f1);
+ } else {
+ begingroup3(f,name,render);
+ for(patch S : surface(L,v,bbox=P.bboxonly).s) {
+ triple V=L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v;
+ draw3D(f,S,V,L.p,light,interaction);
+ // Fill subdivision cracks
+ if(render.labelfill && opacity(L.p) == 1 && !lighton)
+ _draw(f,S.external(),V,L.p,interaction.type);
+ }
+ endgroup3(f);
+ }
+ }
+
+ if(pic2 != null) {
+ pen p=color(L.T3*Z,L.p,light,shiftless(P.T.modelview));
+ if(L.defaulttransform3) {
+ if(L.filltype == NoFill)
+ fill(project(v,P.t),pic2,path(L,P),p);
+ else {
+ picture d;
+ fill(project(v,P.t),d,path(L,P),p);
+ add(pic2,d,L.filltype);
+ }
+ } else
+ pic2.add(new void(frame f, transform T) {
+ for(patch S : surface(L,v).s)
+ fill(f,T*project(S.external(),P,1),p);
+ });
+ }
+
+ },!L.defaulttransform3);
+
+ Label L=L.copy();
+
+ if(interaction.targetsize && settings.render != 0)
+ L.T=L.T*scale(abs(currentprojection.camera-position)/
+ abs(currentprojection.vector()));
+ path[] g=texpath(L,bbox=true);
+ if(g.length == 0 || (g.length == 1 && size(g[0]) == 0)) return;
+ if(L.defaulttransform3)
+ L.T3=transform3(currentprojection);
+ path3[] G=path3(g);
+ G=L.align.is3D ? align(G,L.T3,O,L.align.dir3,L.p) : L.T3*G;
+ pic.addBox(position,position,min(G),max(G));
+}
+
+void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign,
+ pen p=currentpen, light light=nolight, string name="",
+ interaction interaction=LabelInteraction())
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ bool relative=L.position.relative;
+ real position=L.position.position.x;
+ if(L.defaultposition) {relative=true; position=0.5;}
+ if(relative) position=reltime(g,position);
+ if(L.align.default) {
+ align a;
+ a.init(-I*(position <= sqrtEpsilon ? S :
+ position >= length(g)-sqrtEpsilon ? N : E),relative=true);
+ a.dir3=dir(g,position); // Pass 3D direction via unused field.
+ L.align(a);
+ }
+ label(pic,L,point(g,position),light,name,interaction);
+}
+
+surface extrude(Label L, triple axis=Z)
+{
+ Label L=L.copy();
+ path[] g=texpath(L);
+ surface S=extrude(g,axis);
+ surface s=surface(g);
+ S.append(s);
+ S.append(shift(axis)*s);
+ return S;
+}
+
+restricted surface nullsurface;
+
+// Embed a Label onto a surface.
+surface surface(Label L, surface s, real uoffset, real voffset,
+ real height=0, bool bottom=true, bool top=true)
+{
+ int nu=s.index.length;
+ int nv;
+ if(nu == 0) nu=nv=1;
+ else {
+ nv=s.index[0].length;
+ if(nv == 0) nv=1;
+ }
+
+ path[] g=texpath(L);
+ pair m=min(g);
+ pair M=max(g);
+ pair lambda=inverse(L.T*scale(nu-epsilon,nv-epsilon))*(M-m);
+ lambda=(abs(lambda.x),abs(lambda.y));
+ path[] G=bezulate(g);
+
+ path3 transpath(path p, real height) {
+ return path3(unstraighten(p),new triple(pair z) {
+ real u=uoffset+(z.x-m.x)/lambda.x;
+ real v=voffset+(z.y-m.y)/lambda.y;
+ if(((u < 0 || u >= nu) && !s.ucyclic()) ||
+ ((v < 0 || v >= nv) && !s.vcyclic())) {
+ warning("cannotfit","cannot fit string to surface");
+ u=v=0;
+ }
+ return s.point(u,v)+height*unit(s.normal(u,v));
+ });
+ }
+
+ surface s;
+ for(path p : G) {
+ for(path g : regularize(p)) {
+ path3 b;
+ bool extrude=height > 0;
+ if(bottom || extrude)
+ b=transpath(g,0);
+ if(bottom) s.s.push(patch(b));
+ if(top || extrude) {
+ path3 h=transpath(g,height);
+ if(top) s.s.push(patch(h));
+ if(extrude) s.append(extrude(b,h));
+ }
+ }
+ }
+ return s;
+}
+
+private real a=4/3*(sqrt(2)-1);
+private transform3 t1=rotate(90,O,Z);
+private transform3 t2=t1*t1;
+private transform3 t3=t2*t1;
+private transform3 i=xscale3(-1)*zscale3(-1);
+
+restricted patch octant1=patch(X{Y}..{-X}Y{Z}..{-Y}Z..Z{X}..{-Z}cycle,
+ new triple[] {(1,a,a),(a,1,a),(a^2,a,1),
+ (a,a^2,1)});
+
+restricted surface unithemisphere=surface(octant1,t1*octant1,t2*octant1,
+ t3*octant1);
+restricted surface unitsphere=surface(octant1,t1*octant1,t2*octant1,t3*octant1,
+ i*octant1,i*t1*octant1,i*t2*octant1,
+ i*t3*octant1);
+
+restricted patch unitfrustum(real t1, real t2)
+{
+ real s1=interp(t1,t2,1/3);
+ real s2=interp(t1,t2,2/3);
+ return patch(interp(Z,X,t2){Y}..{-X}interp(Z,Y,t2)--interp(Z,Y,t1){X}..{-Y}
+ interp(Z,X,t1)--cycle,
+ new triple[] {(s2,s2*a,1-s2),(s2*a,s2,1-s2),(s1*a,s1,1-s1),
+ (s1,s1*a,1-s1)});
+}
+
+// Return a unitcone constructed from n frusta (the final one being degenerate)
+surface unitcone(int n=6)
+{
+ surface unitcone;
+ unitcone.s=new patch[4*n];
+ real r=1/3;
+ for(int i=0; i < n; ++i) {
+ patch s=unitfrustum(i < n-1 ? r^(i+1) : 0,r^i);
+ unitcone.s[i]=s;
+ unitcone.s[n+i]=t1*s;
+ unitcone.s[2n+i]=t2*s;
+ unitcone.s[3n+i]=t3*s;
+ }
+ return unitcone;
+}
+
+restricted surface unitcone=unitcone();
+restricted surface unitsolidcone=surface(patch(unitcircle3)...unitcone.s);
+
+// Construct an approximate cone over an arbitrary base.
+surface cone(path3 base, triple vertex) {return extrude(base,vertex--cycle);}
+
+private patch unitcylinder1=patch(X{Y}..{-X}Y--Y+Z{X}..{-Y}X+Z--cycle);
+
+restricted surface unitcylinder=surface(unitcylinder1,t1*unitcylinder1,
+ t2*unitcylinder1,t3*unitcylinder1);
+
+private patch unitplane=patch(new triple[] {O,X,X+Y,Y});
+restricted surface unitcube=surface(reverse(unitplane),
+ rotate(90,O,X)*unitplane,
+ rotate(-90,O,Y)*unitplane,
+ shift(Z)*unitplane,
+ rotate(90,X,X+Y)*unitplane,
+ rotate(-90,Y,X+Y)*unitplane);
+restricted surface unitplane=surface(unitplane);
+restricted surface unitdisk=surface(unitcircle3);
+
+void dot(frame f, triple v, material p=currentpen,
+ light light=nolight, string name="",
+ render render=defaultrender, projection P=currentprojection)
+{
+ pen q=(pen) p;
+ if(is3D()) {
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(f,name == "" ? "dot" : name,render);
+ real size=0.5*linewidth(dotsize(q)+q);
+ transform3 T=shift(v)*scale3(size);
+ for(patch s : unitsphere.s)
+ draw3D(f,T*s,v,p,light,prc=false);
+ if(prc())
+ drawPRCsphere(f,T,p,light);
+ if(group)
+ endgroup3(f);
+ } else dot(f,project(v,P.t),q);
+}
+
+void dot(frame f, triple[] v, material p=currentpen, light light=nolight,
+ string name="", render render=defaultrender,
+ projection P=currentprojection)
+{
+ if(v.length > 0) {
+ // Remove duplicate points.
+ v=sort(v,lexorder);
+
+ triple last=v[0];
+ dot(f,last,p,light,name,render,P);
+ for(int i=1; i < v.length; ++i) {
+ triple V=v[i];
+ if(V != last) {
+ dot(f,V,p,light,name,render,P);
+ last=V;
+ }
+ }
+ }
+}
+
+void dot(frame f, path3 g, material p=currentpen, light light=nolight,
+ string name="", render render=defaultrender,
+ projection P=currentprojection)
+{
+ dot(f,sequence(new triple(int i) {return point(g,i);},size(g)),
+ p,light,name,render,P);
+}
+
+void dot(frame f, path3[] g, material p=currentpen, light light=nolight,
+ string name="", render render=defaultrender,
+ projection P=currentprojection)
+{
+ int sum;
+ for(path3 G : g)
+ sum += size(G);
+ int i,j;
+ dot(f,sequence(new triple(int) {
+ while(j >= size(g[i])) {
+ ++i;
+ j=0;
+ }
+ triple v=point(g[i],j);
+ ++j;
+ return v;
+ },sum),p,light,name,render,P);
+}
+
+void dot(picture pic=currentpicture, triple v, material p=currentpen,
+ light light=nolight, string name="", render render=defaultrender)
+{
+ pen q=(pen) p;
+ real size=0.5*linewidth(dotsize(q)+q);
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ triple V=t*v;
+ if(is3D()) {
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(f,name == "" ? "dot" : name,render);
+ transform3 T=shift(V)*scale3(size);
+ for(patch s : unitsphere.s)
+ draw3D(f,T*s,V,p,light,prc=false);
+ if(prc())
+ drawPRCsphere(f,T,p,light,render);
+ if(group)
+ endgroup3(f);
+ }
+ if(pic != null)
+ dot(pic,project(V,P.t),q);
+ },true);
+ triple R=size*(1,1,1);
+ pic.addBox(v,v,-R,R);
+}
+
+void dot(picture pic=currentpicture, triple[] v, material p=currentpen,
+ light light=nolight, string name="", render render=defaultrender)
+{
+ if(v.length > 0) {
+ // Remove duplicate points.
+ v=sort(v,lexorder);
+
+ triple last=v[0];
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(pic,name == "" ? "dots" : name,render);
+ dot(pic,last,p,light,partname(0,render),render);
+ int k=0;
+ for(int i=1; i < v.length; ++i) {
+ triple V=v[i];
+ if(V != last) {
+ dot(pic,V,p,light,partname(++k,render),render);
+ last=V;
+ }
+ }
+ if(group)
+ endgroup3(pic);
+ }
+}
+
+void dot(picture pic=currentpicture, explicit path3 g, material p=currentpen,
+ light light=nolight, string name="",
+ render render=defaultrender)
+{
+ dot(pic,sequence(new triple(int i) {return point(g,i);},size(g)),
+ p,light,name,render);
+}
+
+void dot(picture pic=currentpicture, path3[] g, material p=currentpen,
+ light light=nolight, string name="", render render=defaultrender)
+{
+ int sum;
+ for(path3 G : g)
+ sum += size(G);
+ int i,j;
+ dot(pic,sequence(new triple(int) {
+ while(j >= size(g[i])) {
+ ++i;
+ j=0;
+ }
+ triple v=point(g[i],j);
+ ++j;
+ return v;
+ },sum),p,light,name,render);
+}
+
+void dot(picture pic=currentpicture, Label L, triple v, align align=NoAlign,
+ string format=defaultformat, material p=currentpen,
+ light light=nolight, string name="", render render=defaultrender)
+{
+ Label L=L.copy();
+ if(L.s == "") {
+ if(format == "") format=defaultformat;
+ L.s="("+format(format,v.x)+","+format(format,v.y)+","+
+ format(format,v.z)+")";
+ }
+ L.align(align,E);
+ L.p((pen) p);
+ dot(pic,v,p,light,name,render);
+ label(pic,L,v,render);
+}
+
+void pixel(picture pic=currentpicture, triple v, pen p=currentpen,
+ real width=1)
+{
+ real h=0.5*width;
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ triple V=t*v;
+ if(is3D())
+ drawpixel(f,V,p,width);
+ if(pic != null) {
+ triple R=h*unit(cross(unit(P.vector()),P.up));
+ pair z=project(V,P.t);
+ real h=0.5*abs(project(V+R,P.t)-project(V-R,P.t));
+ pair r=h*(1,1)/mm;
+ fill(pic,box(z-r,z+r),p,false);
+ }
+ },true);
+ triple R=h*(1,1,1);
+ pic.addBox(v,v,-R,R);
+}
+
+pair minbound(triple[] A, projection P)
+{
+ pair b=project(A[0],P);
+ for(triple v : A)
+ b=minbound(b,project(v,P.t));
+ return b;
+}
+
+pair maxbound(triple[] A, projection P)
+{
+ pair b=project(A[0],P);
+ for(triple v : A)
+ b=maxbound(b,project(v,P.t));
+ return b;
+}
+
+pair minbound(triple[][] A, projection P)
+{
+ pair b=project(A[0][0],P);
+ for(triple[] a : A) {
+ for(triple v : a) {
+ b=minbound(b,project(v,P.t));
+ }
+ }
+ return b;
+}
+
+pair maxbound(triple[][] A, projection P)
+{
+ pair b=project(A[0][0],P);
+ for(triple[] a : A) {
+ for(triple v : a) {
+ b=maxbound(b,project(v,P.t));
+ }
+ }
+ return b;
+}
+
+triple[][] operator / (triple[][] a, real[][] b)
+{
+ triple[][] A=new triple[a.length][];
+ for(int i=0; i < a.length; ++i) {
+ triple[] ai=a[i];
+ real[] bi=b[i];
+ A[i]=sequence(new triple(int j) {return ai[j]/bi[j];},ai.length);
+ }
+ return A;
+}
+
+// Draw a NURBS curve.
+void draw(picture pic=currentpicture, triple[] P, real[] knot,
+ real[] weights=new real[], pen p=currentpen, string name="",
+ render render=defaultrender)
+{
+ P=copy(P);
+ knot=copy(knot);
+ weights=copy(weights);
+ pic.add(new void(frame f, transform3 t, picture pic, projection Q) {
+ if(is3D()) {
+ triple[] P=t*P;
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(f,name == "" ? "curve" : name,render);
+ draw(f,P,knot,weights,p);
+ if(group)
+ endgroup3(f);
+ if(pic != null)
+ pic.addBox(minbound(P,Q),maxbound(P,Q));
+ }
+ },true);
+ pic.addBox(minbound(P),maxbound(P));
+}
+
+// Draw a NURBS surface.
+void draw(picture pic=currentpicture, triple[][] P, real[] uknot, real[] vknot,
+ real[][] weights=new real[][], material m=currentpen,
+ pen[] colors=new pen[], light light=currentlight, string name="",
+ render render=defaultrender)
+{
+ if(colors.length > 0)
+ m=mean(colors);
+ m=material(m,light);
+ bool lighton=light.on();
+ P=copy(P);
+ uknot=copy(uknot);
+ vknot=copy(vknot);
+ weights=copy(weights);
+ colors=copy(colors);
+ pic.add(new void(frame f, transform3 t, picture pic, projection Q) {
+ if(is3D()) {
+ bool group=name != "" || render.defaultnames;
+ if(group)
+ begingroup3(f,name == "" ? "surface" : name,render);
+ triple[][] P=t*P;
+ real PRCshininess;
+ if(prc())
+ PRCshininess=PRCshininess(m.shininess);
+ draw(f,P,uknot,vknot,weights,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+ PRCshininess,colors);
+ if(group)
+ endgroup3(f);
+ if(pic != null)
+ pic.addBox(minbound(P,Q),maxbound(P,Q));
+ }
+ },true);
+ pic.addBox(minbound(P),maxbound(P));
+}
diff --git a/graphics/asymptote/base/three_tube.asy b/graphics/asymptote/base/three_tube.asy
new file mode 100644
index 0000000000..25bb9385ec
--- /dev/null
+++ b/graphics/asymptote/base/three_tube.asy
@@ -0,0 +1,426 @@
+void render(path3 s, void f(path3, real), render render=defaultrender)
+{
+ real granularity=render.tubegranularity;
+ void Split(triple z0, triple c0, triple c1, triple z1, real t0=0, real t1=1,
+ real depth=mantissaBits) {
+ if(depth > 0) {
+ real S=straightness(z0,c0,c1,z1);
+ if(S > 0) {
+ --depth;
+ if(S > max(granularity*max(abs(z0),abs(c0),abs(c1),abs(z1)))) {
+ triple m0=0.5*(z0+c0);
+ triple m1=0.5*(c0+c1);
+ triple m2=0.5*(c1+z1);
+ triple m3=0.5*(m0+m1);
+ triple m4=0.5*(m1+m2);
+ triple m5=0.5*(m3+m4);
+ real tm=0.5*(t0+t1);
+ Split(z0,m0,m3,m5,t0,tm,depth);
+ Split(m5,m4,m2,z1,tm,t1,depth);
+ return;
+ }
+ }
+ }
+ f(z0..controls c0 and c1..z1,t0);
+ }
+ Split(point(s,0),postcontrol(s,0),precontrol(s,1),point(s,1));
+}
+
+struct rmf
+{
+ triple p,r,t,s;
+ void operator init(triple p, triple r, triple t)
+ {
+ this.p=p;
+ this.r=r;
+ this.t=t;
+ s=cross(t,r);
+ }
+}
+
+// Rotation minimizing frame
+// http://www.cs.hku.hk/research/techreps/document/TR-2007-07.pdf
+rmf[] rmf(path3 g, real[] t)
+{
+ rmf[] R=new rmf[t.length];
+ triple d=dir(g,0);
+ R[0]=rmf(point(g,0),perp(d),d);
+ for(int i=1; i < t.length; ++i) {
+ rmf Ri=R[i-1];
+ real t=t[i];
+ triple p=point(g,t);
+ triple v1=p-Ri.p;
+ if(v1 != O) {
+ triple r=Ri.r;
+ triple u1=unit(v1);
+ triple ti=Ri.t;
+ triple tp=ti-2*dot(u1,ti)*u1;
+ ti=dir(g,t);
+ triple rp=r-2*dot(u1,r)*u1;
+ triple u2=unit(ti-tp);
+ rp=rp-2*dot(u2,rp)*u2;
+ R[i]=rmf(p,unit(rp),unit(ti));
+ } else
+ R[i]=R[i-1];
+ }
+ return R;
+}
+
+private real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r,
+ real[] x, real[] y, bool[][] cond={})
+{ // z[i][j] is the value at (x[i],y[j])
+ // p and q are the first derivatives with respect to x and y, respectively
+ // r is the second derivative ddu/dxdy
+ int n=x.length-1;
+ int m=y.length-1;
+
+ bool all=cond.length == 0;
+
+ int count;
+ if(all)
+ count=n*m;
+ else {
+ count=0;
+ for(int i=0; i < n; ++i) {
+ bool[] condi=cond[i];
+ bool[] condp=cond[i+1];
+ for(int j=0; j < m; ++j)
+ if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1]))
+ ++count;
+ }
+ }
+
+ real[][][] s=new real[count][][];
+ int k=0;
+ for(int i=0; i < n; ++i) {
+ int ip=i+1;
+ real xi=x[i];
+ real xp=x[ip];
+ real hx=(xp-xi)/3;
+ real[] zi=z[i];
+ real[] zp=z[ip];
+ real[] ri=r[i];
+ real[] rp=r[ip];
+ real[] pi=p[i];
+ real[] pp=p[ip];
+ real[] qi=q[i];
+ real[] qp=q[ip];
+ bool[] condi=all ? null : cond[i];
+ bool[] condp=all ? null : cond[i+1];
+ for(int j=0; j < m; ++j) {
+ if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1])) {
+ real yj=y[j];
+ int jp=j+1;
+ real yp=y[jp];
+ real hy=(yp-yj)/3;
+ real hxy=hx*hy;
+ real zij=zi[j];
+ real zip=zi[jp];
+ real zpj=zp[j];
+ real zpp=zp[jp];
+ real pij=hx*pi[j];
+ real ppj=hx*pp[j];
+ real qip=hy*qi[jp];
+ real qpp=hy*qp[jp];
+ real zippip=zip+hx*pi[jp];
+ real zppmppp=zpp-hx*pp[jp];
+ real zijqij=zij+hy*qi[j];
+ real zpjqpj=zpj+hy*qp[j];
+
+ s[k]=new real[][] {{zij,zijqij,zip-qip,zip},
+ {zij+pij,zijqij+pij+hxy*ri[j],
+ zippip-qip-hxy*ri[jp],zippip},
+ {zpj-ppj,zpjqpj-ppj-hxy*rp[j],
+ zppmppp-qpp+hxy*rp[jp],zppmppp},
+ {zpj,zpjqpj,zpp-qpp,zpp}};
+ ++k;
+ }
+ }
+ }
+
+ return s;
+}
+
+// return the surface values described by a real matrix f, interpolated with
+// xsplinetype and ysplinetype.
+real[][][] bispline(real[][] f, real[] x, real[] y,
+ splinetype xsplinetype=null,
+ splinetype ysplinetype=xsplinetype, bool[][] cond={})
+{
+ real epsilon=sqrtEpsilon*norm(y);
+ if(xsplinetype == null)
+ xsplinetype=(abs(x[0]-x[x.length-1]) <= epsilon) ? periodic : notaknot;
+ if(ysplinetype == null)
+ ysplinetype=(abs(y[0]-y[y.length-1]) <= epsilon) ? periodic : notaknot;
+ int n=x.length; int m=y.length;
+ real[][] ft=transpose(f);
+ real[][] tp=new real[m][];
+ for(int j=0; j < m; ++j)
+ tp[j]=xsplinetype(x,ft[j]);
+ real[][] q=new real[n][];
+ for(int i=0; i < n; ++i)
+ q[i]=ysplinetype(y,f[i]);
+ real[][] qt=transpose(q);
+ real[] d1=xsplinetype(x,qt[0]);
+ real[] d2=xsplinetype(x,qt[m-1]);
+ real[][] r=new real[n][];
+ real[][] p=transpose(tp);
+ for(int i=0; i < n; ++i)
+ r[i]=clamped(d1[i],d2[i])(y,p[i]);
+ return bispline0(f,p,q,r,x,y,cond);
+}
+
+bool uperiodic(real[][] a) {
+ int n=a.length;
+ if(n == 0) return false;
+ int m=a[0].length;
+ real[] a0=a[0];
+ real[] a1=a[n-1];
+ for(int j=0; j < m; ++j) {
+ real norm=0;
+ for(int i=0; i < n; ++i)
+ norm=max(norm,abs(a[i][j]));
+ real epsilon=sqrtEpsilon*norm;
+ if(abs(a0[j]-a1[j]) > epsilon) return false;
+ }
+ return true;
+}
+bool vperiodic(real[][] a) {
+ int n=a.length;
+ if(n == 0) return false;
+ int m=a[0].length-1;
+ for(int i=0; i < n; ++i) {
+ real[] ai=a[i];
+ real epsilon=sqrtEpsilon*norm(ai);
+ if(abs(ai[0]-ai[m]) > epsilon) return false;
+ }
+ return true;
+}
+
+// return the surface described by a parametric function f evaluated at u and v
+// and interpolated with usplinetype and vsplinetype.
+surface surface(triple f(pair z), real[] u, real[] v,
+ splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
+ bool cond(pair z)=null)
+{
+ int nu=u.length-1;
+ int nv=v.length-1;
+ real[] ipt=sequence(u.length);
+ real[] jpt=sequence(v.length);
+ real[][] fx=new real[u.length][v.length];
+ real[][] fy=new real[u.length][v.length];
+ real[][] fz=new real[u.length][v.length];
+
+ bool[][] active;
+ bool all=cond == null;
+ if(!all) active=new bool[u.length][v.length];
+
+ for(int i=0; i <= nu; ++i) {
+ real ui=u[i];
+ real[] fxi=fx[i];
+ real[] fyi=fy[i];
+ real[] fzi=fz[i];
+ bool[] activei=all ? null : active[i];
+ for(int j=0; j <= nv; ++j) {
+ pair z=(ui,v[j]);
+ if(!all) activei[j]=cond(z);
+ triple f=f(z);
+ fxi[j]=f.x;
+ fyi[j]=f.y;
+ fzi[j]=f.z;
+ }
+ }
+
+ if(usplinetype.length == 0) {
+ usplinetype=new splinetype[] {uperiodic(fx) ? periodic : notaknot,
+ uperiodic(fy) ? periodic : notaknot,
+ uperiodic(fz) ? periodic : notaknot};
+ } else if(usplinetype.length != 3) abort("usplinetype must have length 3");
+
+ if(vsplinetype.length == 0) {
+ vsplinetype=new splinetype[] {vperiodic(fx) ? periodic : notaknot,
+ vperiodic(fy) ? periodic : notaknot,
+ vperiodic(fz) ? periodic : notaknot};
+ } else if(vsplinetype.length != 3) abort("vsplinetype must have length 3");
+
+ real[][][] sx=bispline(fx,ipt,jpt,usplinetype[0],vsplinetype[0],active);
+ real[][][] sy=bispline(fy,ipt,jpt,usplinetype[1],vsplinetype[1],active);
+ real[][][] sz=bispline(fz,ipt,jpt,usplinetype[2],vsplinetype[2],active);
+
+ surface s=surface(sx.length);
+ s.index=new int[nu][nv];
+ int k=-1;
+ for(int i=0; i < nu; ++i) {
+ int[] indexi=s.index[i];
+ for(int j=0; j < nv; ++j)
+ indexi[j]=++k;
+ }
+
+ for(int k=0; k < sx.length; ++k) {
+ triple[][] Q=new triple[4][];
+ real[][] Px=sx[k];
+ real[][] Py=sy[k];
+ real[][] Pz=sz[k];
+ for(int i=0; i < 4 ; ++i) {
+ real[] Pxi=Px[i];
+ real[] Pyi=Py[i];
+ real[] Pzi=Pz[i];
+ Q[i]=new triple[] {(Pxi[0],Pyi[0],Pzi[0]),
+ (Pxi[1],Pyi[1],Pzi[1]),
+ (Pxi[2],Pyi[2],Pzi[2]),
+ (Pxi[3],Pyi[3],Pzi[3])};
+ }
+ s.s[k]=patch(Q);
+ }
+
+ if(usplinetype[0] == periodic && usplinetype[1] == periodic &&
+ usplinetype[1] == periodic) s.ucyclic(true);
+
+ if(vsplinetype[0] == periodic && vsplinetype[1] == periodic &&
+ vsplinetype[1] == periodic) s.vcyclic(true);
+
+ return s;
+}
+
+path3 interp(path3 a, path3 b, real t)
+{
+ int n=size(a);
+ return path3(sequence(new triple(int i) {
+ return interp(precontrol(a,i),precontrol(b,i),t);},n),
+ sequence(new triple(int i) {return interp(point(a,i),point(b,i),t);},n),
+ sequence(new triple(int i) {return interp(postcontrol(a,i),
+ postcontrol(b,i),t);},n),
+ sequence(new bool(int i) {return straight(a,i) && straight(b,i);},n),
+ cyclic(a) && cyclic(b));
+}
+
+struct tube
+{
+ surface s;
+ path3 center; // tube axis
+
+ void Null(transform3) {}
+ void Null(transform3, bool) {}
+
+ void operator init(path3 p, real width, render render=defaultrender,
+ void cylinder(transform3)=Null,
+ void sphere(transform3, bool half)=Null,
+ void pipe(path3, path3)=null) {
+ real r=0.5*width;
+
+ void generate(path3 p) {
+ int n=length(p);
+ if(piecewisestraight(p)) {
+ for(int i=0; i < n; ++i) {
+ triple v=point(p,i);
+ triple u=point(p,i+1)-v;
+ transform3 t=shift(v)*align(unit(u))*scale(r,r,abs(u));
+ s.append(t*unitcylinder);
+ cylinder(t);
+ }
+ center=center&p;
+ } else {
+ real[] T;
+ path3 G;
+ for(int i=0; i < n; ++i)
+ render(subpath(p,i,i+1),
+ new void(path3 g, real s) {
+ G=G&g;
+ T.push(i+s);
+ },render);
+ T.push(n);
+ T.cyclic=cyclic(p);
+ rmf[] rmf=rmf(p,T);
+ triple f(pair t) {
+ rmf R=rmf[round(t.x)];
+ int n=round(t.y);
+ static real[] x={1,0,-1,0};
+ static real[] y={0,1,0,-1};
+ return point(G,t.x)+r*(R.r*x[n]-R.s*y[n]);
+ }
+
+ static real[] v={0,1,2,3,0};
+ static real[] circular(real[] x, real[] y) {
+ static real a=8/3*(sqrt(2)-1);
+ return a*periodic(x,y);
+ }
+
+ static splinetype[] Monotonic={monotonic,monotonic,monotonic};
+ static splinetype[] Circular={circular,circular,circular};
+ if(T.length > 0) {
+ surface S=surface(f,sequence(T.length),v,Monotonic,Circular);
+ s.append(S);
+
+ // Compute center of tube:
+ int n=S.index.length;
+ if(T.cyclic) --n;
+ triple[] pre=new triple[n+1];
+ triple[] point=new triple[n+1];
+ triple[] post=new triple[n+1];
+
+ int[] index=S.index[0];
+ triple Point;
+ for(int m=0; m < 4; ++m)
+ Point += S.s[index[m]].P[0][0];
+ pre[0]=point[0]=0.25*Point;
+
+ for(int i=0; i < n; ++i) {
+ index=S.index[i];
+ triple Pre,Point,Post;
+ for(int m=0; m < 4; ++m) {
+ triple [][] P=S.s[index[m]].P;
+ Post += P[1][0];
+ Pre += P[2][0];
+ Point += P[3][0];
+ }
+ post[i]=0.25*Post;
+ pre[i+1]=0.25*Pre;
+ point[i+1]=0.25*Point;
+
+ }
+
+ index=S.index[n-1];
+ triple Post;
+ for(int m=0; m < 4; ++m)
+ Post += S.s[index[m]].P[3][0];
+ post[n]=0.25*Post;
+
+ bool[] b=array(n+1,false);
+ path3 Center=path3(pre,point,post,b,T.cyclic);
+ center=center&Center;
+
+ if(pipe != null) { // Compute path along tube
+ triple[] pre=new triple[n+1];
+ triple[] point=new triple[n+1];
+ triple[] post=new triple[n+1];
+ pre[0]=point[0]=S.s[S.index[0][0]].P[0][0];
+ for(int i=0; i < n; ++i) {
+ triple [][] P=S.s[S.index[i][0]].P;
+ post[i]=P[1][0];
+ pre[i+1]=P[2][0];
+ point[i+1]=P[3][0];
+ }
+ post[n]=S.s[S.index[n-1][0]].P[3][0];
+ pipe(Center,path3(pre,point,post,b,T.cyclic));
+ }
+ }
+ }
+ }
+
+ transform3 t=scale3(r);
+ bool cyclic=cyclic(p);
+ int begin=0;
+ int n=length(p);
+ for(int i=cyclic ? 0 : 1; i < n; ++i)
+ if(abs(dir(p,i,1)-dir(p,i,-1)) > sqrtEpsilon) {
+ generate(subpath(p,begin,i));
+ triple dir=dir(p,i,-1);
+ transform3 T=t*align(dir);
+ s.append(shift(point(p,i))*T*(dir != O ? unithemisphere : unitsphere));
+ sphere(shift(point(center,length(center)))*T,
+ half=straight(p,i-1) && straight(p,i));
+ begin=i;
+ }
+ generate(subpath(p,begin,n));
+ }
+}
diff --git a/graphics/asymptote/base/tree.asy b/graphics/asymptote/base/tree.asy
new file mode 100644
index 0000000000..1e603ec4b6
--- /dev/null
+++ b/graphics/asymptote/base/tree.asy
@@ -0,0 +1,86 @@
+/*****
+ * treedef.asy
+ * Andy Hammerlindl 2003/10/25
+ *
+ * Implements a dynamic binary search tree.
+ *****/
+
+struct tree
+{
+ tree left;
+ tree right;
+ int key = 0;
+ int value = 0;
+}
+
+tree newtree()
+{
+ return null;
+}
+
+tree add(tree t, int key, int value)
+{
+ if (t == null) {
+ tree tt;
+ tt.key = key; tt.value = value;
+ return tt;
+ }
+ else if (key == t.key) {
+ return t;
+ }
+ else if (key < t.key) {
+ tree tt;
+ tt.left = add(t.left, key, value);
+ tt.key = t.key;
+ tt.value = t.value;
+ tt.right = t.right;
+ return tt;
+ }
+ else {
+ tree tt;
+ tt.left = t.left;
+ tt.key = t.key;
+ tt.value = t.value;
+ tt.right = add(t.right, key, value);
+ return tt;
+ }
+}
+
+bool contains(tree t, int key)
+{
+ if (t == null)
+ return false;
+ else if (key == t.key)
+ return true;
+ else if (key < t.key)
+ return contains(t.left, key);
+ else
+ return contains(t.right, key);
+}
+
+int lookup(tree t, int key)
+{
+ if (t == null)
+ return 0;
+ else if (key == t.key)
+ return t.value;
+ else if (key < t.key)
+ return lookup(t.left, key);
+ else
+ return lookup(t.right, key);
+}
+
+void write(file out=stdout, tree t)
+{
+ if (t != null) {
+ if(t.left != null) {
+ write(out,t.left);
+ }
+ write(out,t.key);
+ write(out,"->");
+ write(out,t.value,endl);
+ if (t.right != null) {
+ write(out,t.right);
+ }
+ }
+}
diff --git a/graphics/asymptote/base/trembling.asy b/graphics/asymptote/base/trembling.asy
new file mode 100644
index 0000000000..f9f0d6a747
--- /dev/null
+++ b/graphics/asymptote/base/trembling.asy
@@ -0,0 +1,199 @@
+// Copyright(c) 2008, Philippe Ivaldi.
+// Simplified by John Bowman 02Feb2011
+// http: //www.piprime.fr/
+// trembling.asy: handwriting package for the software Asymptote.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+//(at your option) any later version.
+
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+// COMMENTARY:
+
+// THANKS:
+
+// BUGS:
+// magnetic points are experimental...
+
+// CODE:
+
+real magneticRadius=1; // unit is bp in postscript coordinates.
+real trembleFuzz(){return min(1e-3,magneticRadius/10);}
+
+real trembleAngle=4, trembleFrequency=0.5, trembleRandom=2;
+
+struct tremble
+{
+ static real test=5;
+
+ real angle,frequency,random,fuzz;
+
+ pair[] single(pair[] P)
+ {
+ pair[] op;
+ bool allow;
+ for(int i=0; i < P.length-1; ++i) {
+ allow=true;
+ for(int j=i+1; j < P.length; ++j) {
+ if(abs(P[i]-P[j]) < magneticRadius) {
+ allow=false;
+ break;
+ }
+ }
+ if(allow) op.push(P[i]);
+ }
+ if(P.length > 0) op.push(P[P.length-1]);
+ return op;
+ }
+
+ real atime(pair m, path g, real fuzz=trembleFuzz())
+ {// Return the time of the point on path g nearest to m, within fuzz.
+ if(length(g) == 0) return 0.0;
+ real[] t=intersect(m,g,fuzz);
+ if(t.length > 0) return t[1];
+ real ot;
+ static real eps=sqrt(realEpsilon);
+ real abmax=abs(max(g)-m), abmin=abs(min(g)-m);
+ real initr=abs(m-midpoint(g));
+ real maxR=2*max(abmax,abmin), step=eps, r=initr;
+ real shx=1e-4;
+ transform T=shift(m);
+ path ig;
+ if(t.length > 0) ot=t[1];
+ real rm=0, rM=r;
+ while(rM-rm > eps) {
+ r=(rm+rM)/2;
+ t=intersect(T*scale(r)*unitcircle,g,fuzz);
+ if(t.length <= 0) {
+ rm=r;
+ } else {
+ rM=r;
+ ot=t[1];
+ }
+ }
+ return ot;
+ }
+
+ path addnode(path g, real t)
+ {// Add a node to 'g' at point(g,t).
+ real l=length(g);
+ real rt=t % 1;
+ if(l == 0 || (t > l && !cyclic(g)) || rt == 0) return g;
+ if(cyclic(g)) t=t % l;
+ int t0=floor(t);
+ int t1=t0+1;
+ pair z0=point(g,t0), z1=point(g,t1),
+ c0=postcontrol(g,t0), c1=precontrol(g,t1),
+ m0=(1-rt)*z0+rt*c0, m1=(1-rt)*c0+rt*c1,
+ m2=(1-rt)*c1+rt*z1, m3=(1-rt)*m0+rt*m1,
+ m4=(1-rt)*m1+rt*m2;
+ guide og=subpath(g,0,t0)..controls m0 and m3..point(g,t);
+ if(cyclic(g)) {
+ if(t1 < l)
+ og=og..controls m4 and m2..subpath(g,t1,l)&cycle;
+ else og=og..controls m4 and m2..cycle;
+ } else og=og..controls m4 and m2..subpath(g,t1,l);
+ return og;
+ }
+
+ path addnodes(path g, real fuzz=trembleFuzz()...pair[] P)
+ {
+ pair[] P=single(P);
+ if(length(g) == 0 || P.length == 0 || magneticRadius <= 0) return g;
+ path og=g;
+ for(pair tp: P) {
+ real t=atime(tp,og,fuzz);
+ real d=abs(tp-point(og,t));
+ if(d < magneticRadius) og=addnode(og,t);
+ }
+ return og;
+ }
+
+ path addnodes(path g, int n)
+ {// Add 'n' nodes between each node of 'g'.
+ real l=length(g);
+ if(n == 0 || l == 0) return g;
+ path og=g;
+ int np=0;
+ for(int i=0; i < l; ++i) {
+ real step=1/(n+1);
+ for(int j=0; j < n; ++j) {
+ og=addnode(og,i*(n+1)+j+step);
+ step=1/(n-j);
+ }
+ }
+ return og;
+ }
+
+ void operator init(real angle=trembleAngle, real frequency=trembleFrequency,
+ real random=trembleRandom, real fuzz=trembleFuzz()) {
+ this.angle=angle;
+ this.frequency=frequency;
+ this.random=random;
+ this.fuzz=fuzz;
+ }
+
+ path deform(path g...pair[] magneticPoints) {
+ /* Return g as it was handwriting.
+ The postcontrols and precontrols of the nodes of g will be rotated
+ by an angle proportional to 'angle'(in degrees).
+ If frequency < 1, floor(1/frequency) nodes will be added to g to
+ increase the control points.
+ If frequency>= 1, one point for floor(frequency) will be used to deform
+ the path.
+ 'random' controls the randomized coefficient which will be multiplied
+ by 'angle'.
+ random is 0 means don't use randomized coefficient;
+ The higher 'random' is, the more the trembling is randomized. */
+ if(length(g) == 0) return g;
+ g=addnodes(g,fuzz*abs(max(g)-min(g))...magneticPoints);
+ path tg=g;
+ frequency=abs(frequency);
+ int f=abs(floor(1/frequency)-1);
+ tg=addnodes(tg,f);
+ int frequency=floor(frequency);
+ int tf=(frequency == 0) ? 1 : frequency;
+ int l=length(tg);
+ guide og=point(tg,0);
+ random=abs(random);
+ int rsgn(real x){
+ int d2=floor(100*x)-10*floor(10*x);
+ if(d2 == 0) return 1;
+ return 2 % d2 == 0 ? 1 : -1;
+ }
+ real randf()
+ {
+ real or;
+ if(random != 0) {
+ if(1 % tf != 0) or=0;
+ else {
+ real ur=unitrand();
+ or=rsgn(ur)*angle*(1+ur^(1/random));
+ }
+ } else or=rsgn(unitrand())*1.5*angle;
+ return or;
+ }
+
+ real first=randf();
+ for(int i=1; i <= l; ++i) {
+ pair P=point(tg,i);
+ real a=randf();
+ pair post=rotate(a,point(tg,i-1))*postcontrol(tg,i-1);
+ pair pre=rotate((a+randf())/2,P)*precontrol(tg,i);
+ if(i == l && (cyclic(tg)))
+ og=og..controls post and pre..cycle;
+ else
+ og=og..controls post and pre..P;
+ }
+ return og;
+ }
+}
diff --git a/graphics/asymptote/base/tube.asy b/graphics/asymptote/base/tube.asy
new file mode 100644
index 0000000000..33e2ea3c86
--- /dev/null
+++ b/graphics/asymptote/base/tube.asy
@@ -0,0 +1,167 @@
+// Author: Philippe Ivaldi
+// http://www.piprime.fr/
+// Based on this paper:
+// http://www.cs.hku.hk/research/techreps/document/TR-2007-07.pdf
+// Note: the additional rotation for a cyclic smooth spine curve is not
+// yet properly determined.
+// TODO: Implement variational principles for RMF with boundary conditions:
+// minimum total angular speed OR minimum total squared angular speed
+
+import three;
+
+// A 3D version of roundedpath(path, real).
+path3 roundedpath(path3 A, real r)
+{
+ // Author of this routine: Jens Schwaiger
+ guide3 rounded;
+ triple before, after, indir, outdir;
+ int len=length(A);
+ bool cyclic=cyclic(A);
+ if(len < 2) {return A;};
+ if(cyclic) {rounded=point(point(A,0)--point(A,1),r);}
+ else {rounded=point(A,0);}
+ for(int i=1; i < len; i=i+1) {
+ before=point(point(A,i)--point(A,i-1),r);
+ after=point(point(A,i)--point(A,i+1),r);
+ indir=dir(point(A,i-1)--point(A,i),1);
+ outdir=dir(point(A,i)--point(A,i+1),1);
+ rounded=rounded--before{indir}..{outdir}after;
+ }
+ if(cyclic) {
+ before=point(point(A,0)--point(A,len-1),r);
+ indir=dir(point(A,len-1)--point(A,0),1);
+ outdir=dir(point(A,0)--point(A,1),1);
+ rounded=rounded--before{indir}..{outdir}cycle;
+ } else rounded=rounded--point(A,len);
+
+ return rounded;
+}
+
+real[] sample(path3 g, real r, real relstep=0)
+{
+ real[] t;
+ int n=length(g);
+ if(relstep <= 0) {
+ for(int i=0; i < n; ++i) {
+ real S=straightness(g,i);
+ if(S < sqrtEpsilon*r)
+ t.push(i);
+ else
+ render(subpath(g,i,i+1),new void(path3, real s) {t.push(i+s);});
+ }
+ t.push(n);
+ } else {
+ int nb=ceil(1/relstep);
+ relstep=n/nb;
+ for(int i=0; i <= nb; ++i)
+ t.push(i*relstep);
+ }
+ return t;
+}
+
+real degrees(rmf a, rmf b)
+{
+ real d=degrees(acos1(dot(a.r,b.r)));
+ real dt=dot(cross(a.r,b.r),a.t);
+ d=dt > 0 ? d : 360-d;
+ return d%360;
+}
+
+restricted int coloredNodes=1;
+restricted int coloredSegments=2;
+
+struct coloredpath
+{
+ path p;
+ pen[] pens(real);
+ bool usepens=false;
+ int colortype=coloredSegments;
+
+ void operator init(path p, pen[] pens=new pen[] {currentpen},
+ int colortype=coloredSegments)
+ {
+ this.p=p;
+ this.pens=new pen[] (real t) {return pens;};
+ this.usepens=true;
+ this.colortype=colortype;
+ }
+
+ void operator init(path p, pen[] pens(real), int colortype=coloredSegments)
+ {
+ this.p=p;
+ this.pens=pens;
+ this.usepens=true;
+ this.colortype=colortype;
+ }
+
+ void operator init(path p, pen pen(real))
+ {
+ this.p=p;
+ this.pens=new pen[] (real t) {return new pen[] {pen(t)};};
+ this.usepens=true;
+ this.colortype=coloredSegments;
+ }
+}
+
+coloredpath operator cast(path p)
+{
+ coloredpath cp=coloredpath(p);
+ cp.usepens=false;
+ return cp;
+}
+
+coloredpath operator cast(guide p)
+{
+ return coloredpath(p);
+}
+
+private surface surface(rmf[] R, real[] t, coloredpath cp, transform T(real),
+ bool cyclic)
+{
+ path g=cp.p;
+ int l=length(g);
+ bool[] planar;
+ for(int i=0; i < l; ++i)
+ planar[i]=straight(g,i);
+
+ surface s;
+ path3 sec=path3(T(t[0]/l)*g);
+ real adjust=0;
+ if(cyclic) adjust=-degrees(R[0],R[R.length-1])/(R.length-1);
+ path3 sec1=shift(R[0].p)*transform3(R[0].r,R[0].s,R[0].t)*sec,
+ sec2;
+
+ for(int i=1; i < R.length; ++i) {
+ sec=path3(T(t[i]/l)*g);
+ sec2=shift(R[i].p)*transform3(R[i].r,cross(R[i].t,R[i].r),R[i].t)*
+ rotate(i*adjust,Z)*sec;
+ for(int j=0; j < l; ++j) {
+ surface st=surface(subpath(sec1,j,j+1)--subpath(sec2,j+1,j)--cycle,
+ planar=planar[j]);
+ if(cp.usepens) {
+ pen[] tp1=cp.pens(t[i-1]/l), tp2=cp.pens(t[i]/l);
+ tp1.cyclic=true; tp2.cyclic=true;
+ if(cp.colortype == coloredSegments) {
+ st.colors(new pen[][] {{tp1[j],tp1[j],tp2[j],tp2[j]}});
+ } else {
+ st.colors(new pen[][] {{tp1[j],tp1[j+1],tp2[j+1],tp2[j]}});
+ }
+ }
+ s.append(st);
+ }
+ sec1=sec2;
+ }
+ return s;
+}
+
+surface tube(path3 g, coloredpath section,
+ transform T(real)=new transform(real t) {return identity();},
+ real corner=1, real relstep=0)
+{
+ pair M=max(section.p), m=min(section.p);
+ real[] t=sample(g,max(M.x-m.x,M.y-m.y)/max(realEpsilon,abs(corner)),
+ min(abs(relstep),1));
+ bool cyclic=cyclic(g);
+ t.cyclic=cyclic;
+ return surface(rmf(g,t),t,section,T,cyclic);
+}
diff --git a/graphics/asymptote/base/unicode.asy b/graphics/asymptote/base/unicode.asy
new file mode 100644
index 0000000000..33571e8341
--- /dev/null
+++ b/graphics/asymptote/base/unicode.asy
@@ -0,0 +1,2 @@
+usepackage("ucs");
+usepackage("inputenc","utf8x");
diff --git a/graphics/asymptote/base/x11colors.asy b/graphics/asymptote/base/x11colors.asy
new file mode 100644
index 0000000000..77e0401f06
--- /dev/null
+++ b/graphics/asymptote/base/x11colors.asy
@@ -0,0 +1,145 @@
+pen rgbint(int r, int g, int b)
+{
+ return rgb(r/255,g/255,b/255);
+}
+
+pen AliceBlue=rgbint(240,248,255);
+pen AntiqueWhite=rgbint(250,235,215);
+pen Aqua=rgbint(0,255,255);
+pen Aquamarine=rgbint(127,255,212);
+pen Azure=rgbint(240,255,255);
+pen Beige=rgbint(245,245,220);
+pen Bisque=rgbint(255,228,196);
+pen Black=rgbint(0,0,0);
+pen BlanchedAlmond=rgbint(255,235,205);
+pen Blue=rgbint(0,0,255);
+pen BlueViolet=rgbint(138,43,226);
+pen Brown=rgbint(165,42,42);
+pen BurlyWood=rgbint(222,184,135);
+pen CadetBlue=rgbint(95,158,160);
+pen Chartreuse=rgbint(127,255,0);
+pen Chocolate=rgbint(210,105,30);
+pen Coral=rgbint(255,127,80);
+pen CornflowerBlue=rgbint(100,149,237);
+pen Cornsilk=rgbint(255,248,220);
+pen Crimson=rgbint(220,20,60);
+pen Cyan=rgbint(0,255,255);
+pen DarkBlue=rgbint(0,0,139);
+pen DarkCyan=rgbint(0,139,139);
+pen DarkGoldenrod=rgbint(184,134,11);
+pen DarkGray=rgbint(169,169,169);
+pen DarkGreen=rgbint(0,100,0);
+pen DarkKhaki=rgbint(189,183,107);
+pen DarkMagenta=rgbint(139,0,139);
+pen DarkOliveGreen=rgbint(85,107,47);
+pen DarkOrange=rgbint(255,140,0);
+pen DarkOrchid=rgbint(153,50,204);
+pen DarkRed=rgbint(139,0,0);
+pen DarkSalmon=rgbint(233,150,122);
+pen DarkSeaGreen=rgbint(143,188,143);
+pen DarkSlateBlue=rgbint(72,61,139);
+pen DarkSlateGray=rgbint(47,79,79);
+pen DarkTurquoise=rgbint(0,206,209);
+pen DarkViolet=rgbint(148,0,211);
+pen DeepPink=rgbint(255,20,147);
+pen DeepSkyBlue=rgbint(0,191,255);
+pen DimGray=rgbint(105,105,105);
+pen DodgerBlue=rgbint(30,144,255);
+pen FireBrick=rgbint(178,34,34);
+pen FloralWhite=rgbint(255,250,240);
+pen ForestGreen=rgbint(34,139,34);
+pen Fuchsia=rgbint(255,0,255);
+pen Gainsboro=rgbint(220,220,220);
+pen GhostWhite=rgbint(248,248,255);
+pen Gold=rgbint(255,215,0);
+pen Goldenrod=rgbint(218,165,32);
+pen Gray=rgbint(128,128,128);
+pen Green=rgbint(0,128,0);
+pen GreenYellow=rgbint(173,255,47);
+pen Honeydew=rgbint(240,255,240);
+pen HotPink=rgbint(255,105,180);
+pen IndianRed=rgbint(205,92,92);
+pen Indigo=rgbint(75,0,130);
+pen Ivory=rgbint(255,255,240);
+pen Khaki=rgbint(240,230,140);
+pen Lavender=rgbint(230,230,250);
+pen LavenderBlush=rgbint(255,240,245);
+pen LawnGreen=rgbint(124,252,0);
+pen LemonChiffon=rgbint(255,250,205);
+pen LightBlue=rgbint(173,216,230);
+pen LightCoral=rgbint(240,128,128);
+pen LightCyan=rgbint(224,255,255);
+pen LightGoldenrodYellow=rgbint(250,250,210);
+pen LightGreen=rgbint(144,238,144);
+pen LightGrey=rgbint(211,211,211);
+pen LightPink=rgbint(255,182,193);
+pen LightSalmon=rgbint(255,160,122);
+pen LightSeaGreen=rgbint(32,178,170);
+pen LightSkyBlue=rgbint(135,206,250);
+pen LightSlateGray=rgbint(119,136,153);
+pen LightSteelBlue=rgbint(176,196,222);
+pen LightYellow=rgbint(255,255,224);
+pen Lime=rgbint(0,255,0);
+pen LimeGreen=rgbint(50,205,50);
+pen Linen=rgbint(250,240,230);
+pen Magenta=rgbint(255,0,255);
+pen Maroon=rgbint(128,0,0);
+pen MediumAquamarine=rgbint(102,205,170);
+pen MediumBlue=rgbint(0,0,205);
+pen MediumOrchid=rgbint(186,85,211);
+pen MediumPurple=rgbint(147,112,219);
+pen MediumSeaGreen=rgbint(60,179,113);
+pen MediumSlateBlue=rgbint(123,104,238);
+pen MediumSpringGreen=rgbint(0,250,154);
+pen MediumTurquoise=rgbint(72,209,204);
+pen MediumVioletRed=rgbint(199,21,133);
+pen MidnightBlue=rgbint(25,25,112);
+pen MintCream=rgbint(245,255,250);
+pen MistyRose=rgbint(255,228,225);
+pen Moccasin=rgbint(255,228,181);
+pen NavajoWhite=rgbint(255,222,173);
+pen Navy=rgbint(0,0,128);
+pen OldLace=rgbint(253,245,230);
+pen Olive=rgbint(128,128,0);
+pen OliveDrab=rgbint(107,142,35);
+pen Orange=rgbint(255,165,0);
+pen OrangeRed=rgbint(255,69,0);
+pen Orchid=rgbint(218,112,214);
+pen PaleGoldenrod=rgbint(238,232,170);
+pen PaleGreen=rgbint(152,251,152);
+pen PaleTurquoise=rgbint(175,238,238);
+pen PaleVioletRed=rgbint(219,112,147);
+pen PapayaWhip=rgbint(255,239,213);
+pen PeachPuff=rgbint(255,218,185);
+pen Peru=rgbint(205,133,63);
+pen Pink=rgbint(255,192,203);
+pen Plum=rgbint(221,160,221);
+pen PowderBlue=rgbint(176,224,230);
+pen Purple=rgbint(128,0,128);
+pen Red=rgbint(255,0,0);
+pen RosyBrown=rgbint(188,143,143);
+pen RoyalBlue=rgbint(65,105,225);
+pen SaddleBrown=rgbint(139,69,19);
+pen Salmon=rgbint(250,128,114);
+pen SandyBrown=rgbint(244,164,96);
+pen SeaGreen=rgbint(46,139,87);
+pen Seashell=rgbint(255,245,238);
+pen Sienna=rgbint(160,82,45);
+pen Silver=rgbint(192,192,192);
+pen SkyBlue=rgbint(135,206,235);
+pen SlateBlue=rgbint(106,90,205);
+pen SlateGray=rgbint(112,128,144);
+pen Snow=rgbint(255,250,250);
+pen SpringGreen=rgbint(0,255,127);
+pen SteelBlue=rgbint(70,130,180);
+pen Tan=rgbint(210,180,140);
+pen Teal=rgbint(0,128,128);
+pen Thistle=rgbint(216,191,216);
+pen Tomato=rgbint(255,99,71);
+pen Turquoise=rgbint(64,224,208);
+pen Violet=rgbint(238,130,238);
+pen Wheat=rgbint(245,222,179);
+pen White=rgbint(255,255,255);
+pen WhiteSmoke=rgbint(245,245,245);
+pen Yellow=rgbint(255,255,0);
+pen YellowGreen=rgbint(154,205,50);
diff --git a/graphics/asymptote/bbox.h b/graphics/asymptote/bbox.h
new file mode 100644
index 0000000000..dcb4d98b75
--- /dev/null
+++ b/graphics/asymptote/bbox.h
@@ -0,0 +1,244 @@
+/*****
+ * bbox.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a rectangle that encloses a drawing object.
+ *****/
+
+#ifndef BBOX_H
+#define BBOX_H
+
+#include "pair.h"
+#include "settings.h"
+
+namespace camp {
+
+template<class T>
+inline T min(T a, T b)
+{
+ return (a < b) ? a : b;
+}
+
+template<class T>
+inline T max(T a, T b)
+{
+ return (a > b) ? a : b;
+}
+
+// The box that encloses a path
+struct bbox {
+ bool empty;
+ double left;
+ double bottom;
+ double right;
+ double top;
+
+ // Start bbox about the origin
+ bbox()
+ : empty(true), left(0.0), bottom(0.0), right(0.0), top(0.0)
+ {
+ }
+
+ bbox(double left, double bottom, double right, double top)
+ : empty(false), left(left), bottom(bottom), right(right), top(top)
+ {
+ }
+
+ // Start a bbox with a point
+ bbox(const pair& z)
+ : empty(false), left(z.getx()), bottom(z.gety()),
+ right(z.getx()), top(z.gety())
+ {
+ }
+
+ bool nonempty() const {
+ return !empty;
+ }
+
+ // Add a point to a bbox
+ bbox add(const pair& z)
+ {
+ double x = z.getx(), y = z.gety();
+
+ if (empty) {
+ left = right = x;
+ top = bottom = y;
+ empty = false;
+ }
+ else {
+ if (x < left)
+ left = x;
+ else if (x > right)
+ right = x;
+ if (y < bottom)
+ bottom = y;
+ else if (y > top)
+ top = y;
+ }
+
+ return *this;
+ }
+
+ // Add a point to a nonempty bbox
+ void addnonempty(const pair& z)
+ {
+ double x = z.getx(), y = z.gety();
+ if (x < left)
+ left = x;
+ else if (x > right)
+ right = x;
+ if (y < bottom)
+ bottom = y;
+ else if (y > top)
+ top = y;
+ }
+
+ // Add a point to a nonempty bbox, updating bounding times
+ void addnonempty(const pair& z, bbox& times, double t)
+ {
+ double x = z.getx(), y = z.gety();
+
+ if (x < left) {
+ left = x;
+ times.left = t;
+ }
+ else if (x > right) {
+ right = x;
+ times.right = t;
+ }
+ if (y < bottom) {
+ bottom = y;
+ times.bottom = t;
+ }
+ else if (y > top) {
+ top = y;
+ times.top = t;
+ }
+ }
+
+ bbox operator+= (const pair& z)
+ {
+ add(z);
+ return *this;
+ }
+
+ bbox operator*= (double x)
+ {
+ left *= x;
+ right *= x;
+ top *= x;
+ bottom *=x;
+ return *this;
+ }
+
+ // Add two bounding boxes
+ friend bbox operator+ (const bbox& b1, const bbox& b2)
+ {
+ if (b1.empty)
+ return b2;
+ else if (b2.empty)
+ return b1;
+ else
+ return bbox(min(b1.left, b2.left),
+ max(b1.right, b2.right),
+ min(b1.bottom, b2.bottom),
+ max(b1.top, b2.top));
+ }
+
+ // Add one bounding box to another
+ void add(const bbox& b)
+ {
+ if (this->empty)
+ *this = b;
+ else if (!b.empty) {
+ left = min(left, b.left);
+ right = max(right, b.right);
+ bottom = min(bottom, b.bottom);
+ top = max(top, b.top);
+ }
+ }
+
+ bbox operator+= (const bbox& b)
+ {
+ add(b);
+ return *this;
+ }
+
+ void clip(const bbox& b) {
+ if(this->empty) return;
+ left = max(left, b.left);
+ right = min(right, b.right);
+ bottom = max(bottom, b.bottom);
+ top = min(top, b.top);
+ if(left > right || bottom > top)
+ *this=bbox();
+ }
+
+ void shift(const pair& p) {
+ left += p.getx();
+ right += p.getx();
+ bottom += p.gety();
+ top += p.gety();
+ }
+
+ pair Min() const {
+ return pair(left,bottom);
+ }
+
+ pair Max() const {
+ return pair(right,top);
+ }
+
+ double diameter() {
+ return (Max()-Min()).length();
+ }
+
+ bbox LowRes() const
+ {
+ return bbox(floor(left),floor(bottom),ceil(right),ceil(top));
+ }
+
+ friend ostream& operator<< (ostream& out, const bbox& b)
+ {
+ out << b.left << " " << b.bottom << " " << b.right << " " << b.top;
+ return out;
+ }
+};
+
+// Add results of both bounding boxes, say for a path and a pen.
+inline bbox pad(bbox b1, bbox b2)
+{
+ if (b1.empty)
+ return b2;
+ else if (b2.empty)
+ return b1;
+ else {
+ bbox b;
+ b.empty = false;
+ b.left = b1.left + b2.left;
+ b.right = b1.right + b2.right;
+ b.top = b1.top + b2.top;
+ b.bottom = b1.bottom + b2.bottom;
+ return b;
+ }
+}
+
+inline bbox svgbbox(const bbox& B, pair shift=pair(0,0))
+{
+ bbox b=B;
+ double height=b.top-b.bottom;
+ double threshold=12.0*settings::tex2ps;
+ if(height < threshold) {
+ double offset=threshold-height;
+ b.top += offset;
+ b.bottom += offset;
+ }
+ b.shift(pair(1.99*settings::cm,1.9*settings::cm)+shift);
+ return b;
+}
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::bbox);
+
+#endif
diff --git a/graphics/asymptote/bbox3.h b/graphics/asymptote/bbox3.h
new file mode 100644
index 0000000000..b531be4e91
--- /dev/null
+++ b/graphics/asymptote/bbox3.h
@@ -0,0 +1,191 @@
+/*****
+ * bbox3.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a rectangle that encloses a drawing object.
+ *****/
+
+#ifndef BBOX3_H
+#define BBOX3_H
+
+#include "triple.h"
+
+namespace camp {
+
+// The box that encloses a path
+struct bbox3 {
+ bool empty;
+ double left;
+ double bottom;
+ double lower;
+ double right;
+ double top;
+ double upper;
+
+ // Start bbox3 about the origin
+ bbox3()
+ : empty(true), left(0.0), bottom(0.0), lower(0.0),
+ right(0.0), top(0.0), upper(0.0)
+ {
+ }
+
+ bbox3(double left, double bottom, double lower,
+ double right, double top, double upper)
+ : empty(false), left(left), bottom(bottom), lower(lower),
+ right(right), top(top), upper(upper)
+ {
+ }
+
+ // Start a bbox3 with a point
+ bbox3(double x, double y, double z)
+ : empty(false), left(x), bottom(y), lower(z), right(x), top(y), upper(z)
+ {
+ }
+
+ // Start a bbox3 with a point
+ bbox3(const triple& v)
+ : empty(false), left(v.getx()), bottom(v.gety()), lower(v.getz()),
+ right(v.getx()), top(v.gety()), upper(v.getz())
+ {
+ }
+
+ // Start a bbox3 with 2 points
+ bbox3(const triple& m, const triple& M)
+ : empty(false),
+ left(m.getx()), bottom(m.gety()), lower(m.getz()),
+ right(M.getx()), top(M.gety()), upper(M.getz())
+ {
+ }
+
+ // Add a point to a bbox3
+ void add(const triple& v)
+ {
+ const double x = v.getx(), y = v.gety(), z = v.getz();
+ add(x,y,z);
+ }
+ void add(double x, double y, double z)
+ {
+ if (empty) {
+ left = right = x;
+ top = bottom = y;
+ lower = upper = z;
+ empty = false;
+ }
+ else {
+ if(x < left)
+ left = x;
+ else if(x > right)
+ right = x;
+ if(y < bottom)
+ bottom = y;
+ else if(y > top)
+ top = y;
+ if(z < lower)
+ lower = z;
+ else if(z > upper)
+ upper = z;
+ }
+ }
+
+ // Add a point to a nonempty bbox3
+ void addnonempty(double x, double y, double z)
+ {
+ if(x < left)
+ left = x;
+ else if(x > right)
+ right = x;
+ if(y < bottom)
+ bottom = y;
+ else if(y > top)
+ top = y;
+ if(z < lower)
+ lower = z;
+ else if(z > upper)
+ upper = z;
+ }
+
+ // Add a point to a nonempty bbox3
+ void addnonempty(const triple& v)
+ {
+ addnonempty(v.getx(),v.gety(),v.getz());
+ }
+
+ // Add a point to a nonempty bbox, updating bounding times
+ void addnonempty(const triple& v, bbox3& times, double t)
+ {
+ double x = v.getx(), y = v.gety(), z = v.getz();
+
+ if(x < left) {
+ left = x;
+ times.left = t;
+ }
+ else if(x > right) {
+ right = x;
+ times.right = t;
+ }
+ if(y < bottom) {
+ bottom = y;
+ times.bottom = t;
+ }
+ else if(y > top) {
+ top = y;
+ times.top = t;
+ }
+ if(z < lower) {
+ lower = z;
+ times.lower=t;
+ }
+ else if(z > upper) {
+ upper = z;
+ times.upper=t;
+ }
+ }
+
+ bbox3 operator+= (const triple& v)
+ {
+ add(v);
+ return *this;
+ }
+
+ triple Min() const {
+ return triple(left,bottom,lower);
+ }
+
+ triple Max() const {
+ return triple(right,top,upper);
+ }
+
+ // transform bbox3 by 4x4 matrix
+ void transform(const double* m)
+ {
+ const double xmin = left;
+ const double ymin = bottom;
+ const double zmin = lower;
+ const double xmax = right;
+ const double ymax = top;
+ const double zmax = upper;
+
+ empty = true;
+ add(m*triple(xmin,ymin,zmin));
+ addnonempty(m*triple(xmin,ymin,zmax));
+ addnonempty(m*triple(xmin,ymax,zmin));
+ addnonempty(m*triple(xmin,ymax,zmax));
+ addnonempty(m*triple(xmax,ymin,zmin));
+ addnonempty(m*triple(xmax,ymin,zmax));
+ addnonempty(m*triple(xmax,ymax,zmin));
+ addnonempty(m*triple(xmax,ymax,zmax));
+ }
+
+ friend ostream& operator << (ostream& out, const bbox3& b)
+ {
+ out << "Min " << b.Min() << " Max " << b.Max();
+ return out;
+ }
+
+};
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::bbox3);
+
+#endif
diff --git a/graphics/asymptote/beziercurve.cc b/graphics/asymptote/beziercurve.cc
new file mode 100644
index 0000000000..ccf3267e6e
--- /dev/null
+++ b/graphics/asymptote/beziercurve.cc
@@ -0,0 +1,181 @@
+/*****
+ * drawbezierpatch.cc
+ * Author: John C. Bowman
+ *
+ * Render a Bezier curve.
+ *****/
+
+#include "bezierpatch.h"
+#include "beziercurve.h"
+
+namespace camp {
+
+#ifdef HAVE_GL
+
+std::vector<vertexData1> BezierCurve::vertexbuffer;
+std::vector<GLuint> BezierCurve::indices;
+
+std::vector<pixelData> Pixel::vertexbuffer;
+
+GLuint BezierCurve::vertsBufferIndex;
+GLuint BezierCurve::elemBufferIndex;
+
+void BezierCurve::init(double res, const triple& Min, const triple& Max)
+{
+ this->res=res;
+ res2=res*res;
+ this->Min=Min;
+ this->Max=Max;
+
+ const size_t nbuffer=10000;
+ vertexbuffer.reserve(nbuffer);
+ indices.reserve(nbuffer);
+}
+
+// Use a uniform partition to draw a Bezier patch.
+// p is an array of 4 triples representing the control points.
+// Ii are the vertices indices.
+void BezierCurve::render(const triple *p, GLuint I0, GLuint I1)
+{
+ triple p0=p[0];
+ triple p1=p[1];
+ triple p2=p[2];
+ triple p3=p[3];
+ if(Distance1(p0,p1,p2,p3) < res2) { // Segment is flat
+ triple P[]={p0,p3};
+ if(!offscreen(2,P)) {
+ indices.push_back(I0);
+ indices.push_back(I1);
+ }
+ } else { // Segment is not flat
+ if(offscreen(4,p)) return;
+ triple m0=0.5*(p0+p1);
+ triple m1=0.5*(p1+p2);
+ triple m2=0.5*(p2+p3);
+ triple m3=0.5*(m0+m1);
+ triple m4=0.5*(m1+m2);
+ triple m5=0.5*(m3+m4);
+
+ triple s0[]={p0,m0,m3,m5};
+ triple s1[]={m5,m4,m2,p3};
+
+ GLuint i0=vertex(m5);
+
+ render(s0,I0,i0);
+ render(s1,i0,I1);
+ }
+}
+
+void BezierCurve::render(const triple *p, bool straight)
+{
+ GLuint i0=vertex(p[0]);
+ GLuint i3=vertex(p[3]);
+
+ if(straight) {
+ indices.push_back(i0);
+ indices.push_back(i3);
+ } else
+ render(p,i0,i3);
+}
+
+void BezierCurve::draw()
+{
+ if(indices.size() == 0)
+ return;
+
+ const size_t size=sizeof(GLfloat);
+ static const size_t bytestride=sizeof(vertexData1);
+
+ GLuint vao;
+ glGenVertexArrays(1,&vao);
+ glBindVertexArray(vao);
+ createBuffers();
+
+ glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
+
+ camp::setUniforms(noNormalShader);
+
+ const GLint posAttrib=glGetAttribLocation(noNormalShader, "position");
+ const GLint materialAttrib=glGetAttribLocation(noNormalShader,"material");
+
+ glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void *) 0);
+ glEnableVertexAttribArray(posAttrib);
+
+ glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,(void *) (3*size));
+ glEnableVertexAttribArray(materialAttrib);
+
+ glFlush(); // Workaround broken MSWindows drivers for Intel GPU
+ glDrawElements(GL_LINES,indices.size(),GL_UNSIGNED_INT,(void*)(0));
+
+ glDisableVertexAttribArray(posAttrib);
+ glDisableVertexAttribArray(materialAttrib);
+
+ deleteUniforms();
+
+ glBindBuffer(GL_ARRAY_BUFFER,0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+
+ glBindVertexArray(0);
+ glDeleteVertexArrays(1,&vao);
+
+ glDeleteBuffers(1,&vertsBufferIndex);
+ glDeleteBuffers(1,&elemBufferIndex);
+}
+
+void Pixel::queue(const triple& p, double width)
+{
+ vertex(p,width);
+}
+
+void Pixel::draw()
+{
+ if(vertexbuffer.size() == 0)
+ return;
+
+ const size_t size=sizeof(GLfloat);
+ static const size_t bytestride=sizeof(pixelData);
+
+ GLuint vbo;
+ glGenBuffers(1,&vbo);
+
+ GLuint vao;
+ glGenVertexArrays(1,&vao);
+ glBindVertexArray(vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER,vbo);
+ glBufferData(GL_ARRAY_BUFFER,bytestride*vertexbuffer.size(),
+ vertexbuffer.data(),GL_STATIC_DRAW);
+
+ camp::setUniforms(pixelShader);
+
+ const GLint posAttrib=glGetAttribLocation(pixelShader, "position");
+ const GLint materialAttrib=glGetAttribLocation(pixelShader,"material");
+ const GLint widthAttrib=glGetAttribLocation(pixelShader,"width");
+
+ glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void*)(0));
+ glEnableVertexAttribArray(posAttrib);
+
+ glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,(void *) (3*size));
+ glEnableVertexAttribArray(materialAttrib);
+
+ glVertexAttribPointer(widthAttrib,1,GL_FLOAT,GL_FALSE,bytestride,(void *) (4*size));
+ glEnableVertexAttribArray(widthAttrib);
+
+ glDrawArrays(GL_POINTS,0,vertexbuffer.size());
+
+ glDisableVertexAttribArray(posAttrib);
+ glDisableVertexAttribArray(materialAttrib);
+ glDisableVertexAttribArray(widthAttrib);
+
+ deleteUniforms();
+
+ glBindBuffer(GL_ARRAY_BUFFER,0);
+
+ glBindVertexArray(0);
+ glDeleteVertexArrays(1,&vao);
+}
+
+#endif
+
+} //namespace camp
diff --git a/graphics/asymptote/beziercurve.h b/graphics/asymptote/beziercurve.h
new file mode 100644
index 0000000000..573b48a792
--- /dev/null
+++ b/graphics/asymptote/beziercurve.h
@@ -0,0 +1,137 @@
+/*****
+ * beziercurve.h
+ * Author: John C. Bowman
+ *
+ * Render a Bezier curve.
+ *****/
+
+#ifndef BEZIERCURVE_H
+#define BEZIERCURVE_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+#ifdef HAVE_GL
+
+extern const double Fuzz;
+extern const double Fuzz2;
+
+class vertexData1 {
+public:
+ GLfloat position[3];
+ GLint material;
+ vertexData1() {};
+ vertexData1(const triple& v) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ material=drawElement::materialIndex;
+ }
+};
+
+class pixelData {
+public:
+ GLfloat position[3];
+ GLint material;
+ GLfloat width;
+ pixelData() {};
+ pixelData(const triple& v, double width) : width(width) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ material=drawElement::materialIndex;
+ }
+};
+
+struct BezierCurve
+{
+ static std::vector<vertexData1> vertexbuffer;
+ static std::vector<GLuint> indices;
+ double res,res2;
+ triple Min,Max;
+
+ static GLuint vertsBufferIndex;
+ static GLuint elemBufferIndex;
+
+ void init(double res, const triple& Min, const triple& Max);
+
+// Store the vertex v in the buffer.
+ static GLuint vertex(const triple &v) {
+ size_t nvertices=vertexbuffer.size();
+ vertexbuffer.push_back(vertexData1(v));
+ return nvertices;
+ }
+
+ void createBuffers() {
+ glGenBuffers(1,&vertsBufferIndex);
+ glGenBuffers(1,&elemBufferIndex);
+
+ //vbo
+ registerBuffer(vertexbuffer,vertsBufferIndex);
+
+ //ebo
+ registerBuffer(indices,elemBufferIndex);
+ }
+
+// Approximate bounds by bounding box of control polyhedron.
+ bool offscreen(size_t n, const triple *v) {
+ double x,y,z;
+ double X,Y,Z;
+
+ boundstriples(x,y,z,X,Y,Z,n,v);
+ return
+ X < Min.getx() || x > Max.getx() ||
+ Y < Min.gety() || y > Max.gety() ||
+ Z < Min.getz() || z > Max.getz();
+ }
+
+ static void clear() {
+ vertexbuffer.clear();
+ indices.clear();
+ }
+
+ ~BezierCurve() {}
+
+ void render(const triple *p, GLuint I0, GLuint I1);
+ void render(const triple *p, bool straight);
+
+ void queue(const triple *g, bool straight, double ratio,
+ const triple& Min, const triple& Max) {
+ init(pixel*ratio,Min,Max);
+ render(g,straight);
+ }
+
+ void draw();
+ void draw(const triple *g, bool straight, double ratio,
+ const triple& Min, const triple& Max) {
+ queue(g,straight,ratio,Min,Max);
+ draw();
+ }
+};
+
+struct Pixel
+{
+ static std::vector<pixelData> vertexbuffer;
+
+// Store the vertex v in the buffer.
+ static void vertex(const triple &v, double width) {
+ vertexbuffer.push_back(pixelData(v,width));
+ }
+
+ static void clear() {
+ vertexbuffer.clear();
+ }
+
+ Pixel() {}
+ ~Pixel() {}
+
+ void queue(const triple& p, double width);
+ void draw();
+};
+
+#endif
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/bezierpatch.cc b/graphics/asymptote/bezierpatch.cc
new file mode 100644
index 0000000000..c97887ef64
--- /dev/null
+++ b/graphics/asymptote/bezierpatch.cc
@@ -0,0 +1,1107 @@
+/*****
+ * drawbezierpatch.cc
+ * Authors: John C. Bowman and Jesse Frohlich
+ *
+ * Render Bezier patches and triangles.
+ *****/
+
+#include "bezierpatch.h"
+#include "predicates.h"
+
+namespace camp {
+
+using ::orient2d;
+using ::orient3d;
+
+#ifdef HAVE_GL
+
+const size_t nbuffer=10000; // Initial size of dynamic buffers
+
+std::vector<vertexData> BezierPatch::vertexbuffer;
+std::vector<VertexData> BezierPatch::Vertexbuffer;
+std::vector<VertexData> BezierPatch::tVertexbuffer;
+std::vector<GLuint> BezierPatch::indices;
+std::vector<GLuint> BezierPatch::Indices;
+std::vector<GLuint> BezierPatch::tIndices;
+
+GLuint BezierPatch::nvertices=0;
+GLuint BezierPatch::Nvertices=0;
+GLuint BezierPatch::Ntvertices=0;
+
+//std::vector<GLuint>& I=BezierPatch::tIndices;
+//std::vector<VertexData>& V=BezierPatch::tVertexbuffer;
+bool colors;
+
+std::vector<GLfloat> zbuffer;
+std::vector<GLfloat> xbuffer;
+std::vector<GLfloat> ybuffer;
+
+std::vector<GLfloat> xmin,ymin,zmin;
+std::vector<GLfloat> xmax,ymax,zmax;
+std::vector<GLfloat> zsum;
+
+inline double min(double a, double b, double c)
+{
+ return min(min(a,b),c);
+}
+
+inline double max(double a, double b, double c)
+{
+ return max(max(a,b),c);
+}
+
+struct iz {
+ unsigned i;
+ double z;
+ iz() {}
+ void minimum(unsigned i, const std::vector<GLuint>& I) {
+ this->i=i;
+ unsigned i3=3*i;
+ z=min(zbuffer[I[i3]],zbuffer[I[i3+1]],zbuffer[I[i3+2]]);
+ }
+};
+
+std::vector<iz> IZ;
+
+const double FillFactor=0.1;
+const double BezierFactor=0.4;
+
+inline int sgn1(double x)
+{
+ return x >= 0.0 ? 1 : -1;
+}
+
+inline int sgn(double x)
+{
+ return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0));
+}
+
+bool sameside(const double *a, const double *b, int s0, const double *A,
+ const double *B, const double *C)
+{
+ if(sgn(orient2d(a,b,A)) == s0) return true;
+ if(sgn(orient2d(a,b,B)) == s0) return true;
+ if(sgn(orient2d(a,b,C)) == s0) return true;
+ return false;
+}
+
+// returns true iff 2D triangles abc and ABC intersect
+bool intersect2D(const double *a, const double *b, const double *c,
+ const double *A, const double *B, const double *C)
+{
+ int s0=sgn(orient2d(a,b,c)); // Optimize away
+ int S0=sgn(orient2d(A,B,C)); // Optimize away
+ return
+ sameside(a,b,s0,A,B,C) &&
+ sameside(b,c,s0,A,B,C) &&
+ sameside(c,a,s0,A,B,C) &&
+ sameside(A,B,S0,a,b,c) &&
+ sameside(B,C,S0,a,b,c) &&
+ sameside(C,A,S0,a,b,c);
+}
+
+// returns true iff triangle abc is pierced by line segment AB.
+bool pierce(const double *a, const double *b, const double *c, const double *A, const double *B)
+{
+ int sa=sgn(orient3d(A,b,c,B));
+ int sb=sgn(orient3d(A,c,a,B));
+ int sc=sgn(orient3d(A,a,b,B));
+ return sa == sb && sb == sc;
+}
+
+// returns true iff triangle abc is pierced by an edge of triangle ABC
+bool intersect0(const double *a, const double *b, const double *c,
+ const double *A, const double *B, const double *C,
+ int sA, int sB, int sC)
+{
+ if(sA != sB) {
+ if(pierce(a,b,c,A,B)) return true;
+ if(sC != sA) {
+ if(pierce(a,b,c,C,A)) return true;
+ } else {
+ if(pierce(a,b,c,B,C)) return true;
+ }
+ } else {
+ if(pierce(a,b,c,B,C)) return true;
+ if(pierce(a,b,c,C,A)) return true;
+ }
+ return false;
+}
+
+// returns true iff triangle abc intersects triangle ABC
+bool intersect3D(const double *a, const double *b, const double *c,
+ const double *A, const double *B, const double *C)
+{
+ int sA=sgn(orient3d(a,b,c,A));
+ int sB=sgn(orient3d(a,b,c,B));
+ int sC=sgn(orient3d(a,b,c,C));
+ if(sA == sB && sB == sC) return false;
+
+ int sa=sgn(orient3d(A,B,C,a));
+ int sb=sgn(orient3d(A,B,C,b));
+ int sc=sgn(orient3d(A,B,C,c));
+ if(sa == sb && sb == sc) return false;
+
+ return intersect0(a,b,c,A,B,C,sA,sB,sC) || intersect0(A,B,C,a,b,c,sa,sb,sc);
+}
+
+// Return the intersection time of the extension of the line segment PQ
+// with the plane perpendicular to n and passing through Z.
+inline double intersect(const double *P, const double *Q, const double *n,
+ const double *Z)
+{
+ double d=n[0]*Z[0]+n[1]*Z[1]+n[2]*Z[2];
+ double denom=n[0]*(Q[0]-P[0])+n[1]*(Q[1]-P[1])+n[2]*(Q[2]-P[2]);
+ return denom == 0 ? DBL_MAX : (d-n[0]*P[0]-n[1]*P[1]-n[2]*P[2])/denom;
+}
+
+inline triple interp(const double *a, const double *b, double t)
+{
+ return triple(a[0]+t*(b[0]-a[0]),a[1]+t*(b[1]-a[1]),a[2]+t*(b[2]-a[2]));
+}
+
+inline void interp(GLfloat *dest,
+ const GLfloat *a, const GLfloat *b, double t)
+{
+ double onemt=1.0-t;
+ for(size_t i=0; i < 4; ++i)
+ dest[i]=onemt*a[i]+t*b[i];
+}
+
+inline triple interp(const triple& a, const triple& b, double t)
+{
+ return a+(b-a)*t;
+}
+
+inline void cross(double *dest, const double *u, const double *v,
+ const double *w)
+{
+ double u0=u[0]-w[0];
+ double u1=u[1]-w[1];
+ double u2=u[2]-w[2];
+ double v0=v[0]-w[0];
+ double v1=v[1]-w[1];
+ double v2=v[2]-w[2];
+ dest[0]=u1*v2-u2*v1;
+ dest[1]=u2*v0-u0*v2;
+ dest[2]=u0*v1-u1*v0;
+}
+
+unsigned n;
+unsigned int count;
+
+// Sort nonintersecting triangles by depth.
+int compare(const void *p, const void *P)
+{
+ unsigned Ia=((GLuint *) p)[0];
+ unsigned Ib=((GLuint *) p)[1];
+ unsigned Ic=((GLuint *) p)[2];
+
+ unsigned IA=((GLuint *) P)[0];
+ unsigned IB=((GLuint *) P)[1];
+ unsigned IC=((GLuint *) P)[2];
+
+ return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] <
+ zbuffer[IA]+zbuffer[IB]+zbuffer[IC] ? -1 : 1;
+
+ /*
+ double a[]={xbuffer[Ia],ybuffer[Ia],zbuffer[Ia]};
+ double b[]={xbuffer[Ib],ybuffer[Ib],zbuffer[Ib]};
+ double c[]={xbuffer[Ic],ybuffer[Ic],zbuffer[Ic]};
+
+ double A[]={xbuffer[IA],ybuffer[IA],zbuffer[IA]};
+ double B[]={xbuffer[IB],ybuffer[IB],zbuffer[IB]};
+ double C[]={xbuffer[IC],ybuffer[IC],zbuffer[IC]};
+
+ double viewpoint[]={0,0,100000};
+
+ double sa=-orient3d(A,B,C,a);
+ double sb=-orient3d(A,B,C,b);
+ double sc=-orient3d(A,B,C,c);
+ double s=min(sa,sb,sc);
+ double S=max(sa,sb,sc);
+ double eps=1000;
+
+ if(s < -eps && S > eps) { //swap
+ double sA=-orient3d(a,b,c,A);
+ double sB=-orient3d(a,b,c,B);
+ double sC=-orient3d(a,b,c,C);
+ double s=min(sA,sB,sC);
+ double S=max(sA,sB,sC);
+ if(S < -s) S=s;
+ int sz=sgn1(orient3d(a,b,c,viewpoint));
+ if(S < -eps) return -sz;
+ if(S > eps) return sz;
+ }
+ if(S < -s) S=s;
+ int sz=sgn1(orient3d(A,B,C,viewpoint));
+ if(S < -eps) return sz;
+ if(S > eps) return -sz;
+ return a[2]+b[2]+c[2] < A[2]+B[2]+C[2] ? -1 : 1;
+ */
+}
+
+#if 0
+void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic,
+ double *a, double *b, double *c, double *N, double *A) {
+ double td=intersect(a,b,N,A);
+ double te=intersect(a,c,N,A);
+
+ triple d=interp(a,b,td);
+ triple e=interp(a,c,te);
+
+ GLuint Ia=tstride*ia;
+ GLuint Ib=tstride*ib;
+ GLuint Ic=tstride*ic;
+
+ triple na=triple(V[Ia+3],V[Ia+4],V[Ia+5]);
+ triple nb=triple(V[Ib+3],V[Ib+4],V[Ib+5]);
+ triple nc=triple(V[Ic+3],V[Ic+4],V[Ic+5]);
+
+ triple nd=interp(na,nb,td);
+ triple ne=interp(na,nc,te);
+
+ GLuint id,ie;
+
+ if(colors) {
+ GLfloat *ca=&V[Ia+6];
+ GLfloat *cb=&V[Ib+6];
+ GLfloat *cc=&V[Ic+6];
+
+ GLfloat cd[4],ce[4];
+ interp(cd,ca,cb,td);
+ interp(ce,ca,cc,te);
+
+ id=BezierPatch::tVertex(d,nd,cd);
+ ie=BezierPatch::tVertex(e,ne,ce);
+ } else {
+ id=BezierPatch::tVertex(d,nd);
+ ie=BezierPatch::tVertex(e,ne);
+ }
+
+ I[i3]=ia;
+ I[i3+1]=id;
+ I[i3+2]=ie;
+
+ I.push_back(id);
+ I.push_back(ib);
+ I.push_back(ie);
+
+ I.push_back(ie);
+ I.push_back(ib);
+ I.push_back(ic);
+}
+#endif
+
+void BezierPatch::init(double res, const triple& Min, const triple& Max,
+ bool transparent, GLfloat *colors)
+{
+ res2=res*res;
+ Res2=BezierFactor*BezierFactor*res2;
+ Epsilon=FillFactor*res;
+
+ this->Min=Min;
+ this->Max=Max;
+
+ if(transparent) {
+ tVertexbuffer.reserve(nbuffer);
+ tIndices.reserve(nbuffer);
+ pindices=&tIndices;
+ pvertex=&tvertex;
+ pVertex=&tVertex;
+ } else {
+ if(colors) {
+ Vertexbuffer.reserve(nbuffer);
+ Indices.reserve(nbuffer);
+ pindices=&Indices;
+ pVertex=&Vertex;
+ } else {
+ vertexbuffer.reserve(nbuffer);
+ indices.reserve(nbuffer);
+ pindices=&indices;
+ pvertex=&vertex;
+ }
+ }
+}
+
+// Use a uniform partition to draw a Bezier patch.
+// p is an array of 16 triples representing the control points.
+// Pi are the (possibly) adjusted vertices indexed by Ii.
+// The 'flati' are flatness flags for each boundary.
+void BezierPatch::render(const triple *p,
+ GLuint I0, GLuint I1, GLuint I2, GLuint I3,
+ triple P0, triple P1, triple P2, triple P3,
+ bool flat0, bool flat1, bool flat2, bool flat3,
+ GLfloat *C0, GLfloat *C1, GLfloat *C2, GLfloat *C3)
+{
+ if(Distance(p) < res2) { // Patch is flat
+ triple P[]={P0,P1,P2,P3};
+ if(!offscreen(4,P)) {
+ std::vector<GLuint> &p=*pindices;
+ p.push_back(I0);
+ p.push_back(I1);
+ p.push_back(I2);
+ p.push_back(I0);
+ p.push_back(I2);
+ p.push_back(I3);
+ }
+ } else { // Patch is not flat
+ if(offscreen(16,p)) return;
+ /* Control points are indexed as follows:
+
+ Coordinate
+ +-----
+ Index
+
+
+ 03 13 23 33
+ +-----+-----+-----+
+ |3 |7 |11 |15
+ | | | |
+ |02 |12 |22 |32
+ +-----+-----+-----+
+ |2 |6 |10 |14
+ | | | |
+ |01 |11 |21 |31
+ +-----+-----+-----+
+ |1 |5 |9 |13
+ | | | |
+ |00 |10 |20 |30
+ +-----+-----+-----+
+ 0 4 8 12
+
+
+ Subdivision:
+ P refers to a corner
+ m refers to a midpoint
+ s refers to a subpatch
+
+ m2
+ +--------+--------+
+ |P3 | P2|
+ | | |
+ | s3 | s2 |
+ | | |
+ | |m4 |
+ m3+--------+--------+m1
+ | | |
+ | | |
+ | s0 | s1 |
+ | | |
+ |P0 | P1|
+ +--------+--------+
+ m0
+ */
+
+ // Subdivide patch:
+ triple p0=p[0];
+ triple p3=p[3];
+ triple p12=p[12];
+ triple p15=p[15];
+
+ Split3 c0(p0,p[1],p[2],p3);
+ Split3 c1(p[4],p[5],p[6],p[7]);
+ Split3 c2(p[8],p[9],p[10],p[11]);
+ Split3 c3(p12,p[13],p[14],p15);
+
+ Split3 c4(p0,p[4],p[8],p12);
+ Split3 c5(c0.m0,c1.m0,c2.m0,c3.m0);
+ Split3 c6(c0.m3,c1.m3,c2.m3,c3.m3);
+ Split3 c7(c0.m5,c1.m5,c2.m5,c3.m5);
+ Split3 c8(c0.m4,c1.m4,c2.m4,c3.m4);
+ Split3 c9(c0.m2,c1.m2,c2.m2,c3.m2);
+ Split3 c10(p3,p[7],p[11],p15);
+
+ triple s0[]={p0,c0.m0,c0.m3,c0.m5,c4.m0,c5.m0,c6.m0,c7.m0,
+ c4.m3,c5.m3,c6.m3,c7.m3,c4.m5,c5.m5,c6.m5,c7.m5};
+ triple s1[]={c4.m5,c5.m5,c6.m5,c7.m5,c4.m4,c5.m4,c6.m4,c7.m4,
+ c4.m2,c5.m2,c6.m2,c7.m2,p12,c3.m0,c3.m3,c3.m5};
+ triple s2[]={c7.m5,c8.m5,c9.m5,c10.m5,c7.m4,c8.m4,c9.m4,c10.m4,
+ c7.m2,c8.m2,c9.m2,c10.m2,c3.m5,c3.m4,c3.m2,p15};
+ triple s3[]={c0.m5,c0.m4,c0.m2,p3,c7.m0,c8.m0,c9.m0,c10.m0,
+ c7.m3,c8.m3,c9.m3,c10.m3,c7.m5,c8.m5,c9.m5,c10.m5};
+
+ triple m4=s0[15];
+
+ triple n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
+ if(n0 == 0.0) {
+ n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
+ if(n0 == 0.0) n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
+ }
+
+ triple n1=normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]);
+ if(n1 == 0.0) {
+ n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
+ if(n1 == 0.0) n1=normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]);
+ }
+
+ triple n2=normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]);
+ if(n2 == 0.0) {
+ n2=normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]);
+ if(n2 == 0.0) n2=normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]);
+ }
+
+ triple n3=normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]);
+ if(n3 == 0.0) {
+ n3=normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]);
+ if(n3 == 0.0) n3=normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]);
+ }
+
+ triple n4=normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]);
+
+ // A kludge to remove subdivision cracks, only applied the first time
+ // an edge is found to be flat before the rest of the subpatch is.
+
+ triple m0=0.5*(P0+P1);
+ if(!flat0) {
+ if((flat0=Straightness(p0,p[4],p[8],p12) < res2))
+ m0 -= Epsilon*unit(derivative(s1[0],s1[1],s1[2],s1[3]));
+ else m0=s0[12];
+ }
+
+ triple m1=0.5*(P1+P2);
+ if(!flat1) {
+ if((flat1=Straightness(p12,p[13],p[14],p15) < res2))
+ m1 -= Epsilon*unit(derivative(s2[12],s2[8],s2[4],s2[0]));
+ else m1=s1[15];
+ }
+
+ triple m2=0.5*(P2+P3);
+ if(!flat2) {
+ if((flat2=Straightness(p15,p[11],p[7],p3) < res2))
+ m2 -= Epsilon*unit(derivative(s3[15],s2[14],s2[13],s1[12]));
+ else m2=s2[3];
+ }
+
+ triple m3=0.5*(P3+P0);
+ if(!flat3) {
+ if((flat3=Straightness(p0,p[1],p[2],p3) < res2))
+ m3 -= Epsilon*unit(derivative(s0[3],s0[7],s0[11],s0[15]));
+ else m3=s3[0];
+ }
+
+ if(C0) {
+ GLfloat c0[4],c1[4],c2[4],c3[4],c4[4];
+ for(size_t i=0; i < 4; ++i) {
+ c0[i]=0.5*(C0[i]+C1[i]);
+ c1[i]=0.5*(C1[i]+C2[i]);
+ c2[i]=0.5*(C2[i]+C3[i]);
+ c3[i]=0.5*(C3[i]+C0[i]);
+ c4[i]=0.5*(c0[i]+c2[i]);
+ }
+
+ GLuint i0=pVertex(m0,n0,c0);
+ GLuint i1=pVertex(m1,n1,c1);
+ GLuint i2=pVertex(m2,n2,c2);
+ GLuint i3=pVertex(m3,n3,c3);
+ GLuint i4=pVertex(m4,n4,c4);
+ render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,
+ C0,c0,c4,c3);
+ render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,
+ c0,C1,c1,c4);
+ render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false,
+ c4,c1,C2,c2);
+ render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3,
+ c3,c4,c2,C3);
+ } else {
+ GLuint i0=pvertex(m0,n0);
+ GLuint i1=pvertex(m1,n1);
+ GLuint i2=pvertex(m2,n2);
+ GLuint i3=pvertex(m3,n3);
+ GLuint i4=pvertex(m4,n4);
+ render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3);
+ render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false);
+ render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false);
+ render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3);
+ }
+ }
+}
+
+void BezierPatch::render(const triple *p, bool straight, GLfloat *c0)
+{
+ triple p0=p[0];
+ epsilon=0;
+ for(unsigned i=1; i < 16; ++i)
+ epsilon=max(epsilon,abs2(p[i]-p0));
+
+ epsilon *= Fuzz4;
+
+ triple p3=p[3];
+ triple p12=p[12];
+ triple p15=p[15];
+
+ triple n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12);
+ if(n0 == 0.0) n0=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
+ if(n0 == 0.0) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
+
+ triple n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15);
+ if(n1 == 0.0) n1=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
+ if(n1 == 0.0) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
+
+ triple n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3);
+ if(n2 == 0.0) n2=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+ if(n2 == 0.0) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
+
+ triple n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0);
+ if(n3 == 0.0) n3=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
+ if(n3 == 0.0) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+
+ GLuint I0,I1,I2,I3;
+
+ if(c0) {
+ GLfloat *c1=c0+4;
+ GLfloat *c2=c0+8;
+ GLfloat *c3=c0+12;
+
+ I0=pVertex(p0,n0,c0);
+ I1=pVertex(p12,n1,c1);
+ I2=pVertex(p15,n2,c2);
+ I3=pVertex(p3,n3,c3);
+
+ if(!straight)
+ render(p,I0,I1,I2,I3,p0,p12,p15,p3,false,false,false,false,
+ c0,c1,c2,c3);
+ } else {
+ I0=pvertex(p0,n0);
+ I1=pvertex(p12,n1);
+ I2=pvertex(p15,n2);
+ I3=pvertex(p3,n3);
+
+ if(!straight)
+ render(p,I0,I1,I2,I3,p0,p12,p15,p3,false,false,false,false);
+ }
+
+ if(straight) {
+ pindices->push_back(I0);
+ pindices->push_back(I1);
+ pindices->push_back(I2);
+ pindices->push_back(I0);
+ pindices->push_back(I2);
+ pindices->push_back(I3);
+ }
+}
+
+// Use a uniform partition to draw a Bezier triangle.
+// p is an array of 10 triples representing the control points.
+// Pi are the (possibly) adjusted vertices indexed by Ii.
+// The 'flati' are flatness flags for each boundary.
+void BezierTriangle::render(const triple *p,
+ GLuint I0, GLuint I1, GLuint I2,
+ triple P0, triple P1, triple P2,
+ bool flat0, bool flat1, bool flat2,
+ GLfloat *C0, GLfloat *C1, GLfloat *C2)
+{
+ if(Distance(p) < Res2) { // Triangle is flat
+ triple P[]={P0,P1,P2};
+ if(!offscreen(3,P)) {
+ std::vector<GLuint> &p=*pindices;
+ p.push_back(I0);
+ p.push_back(I1);
+ p.push_back(I2);
+ }
+ } else { // Triangle is not flat
+ if(offscreen(10,p)) return;
+ /* Control points are indexed as follows:
+
+ Coordinate
+ Index
+
+ 030
+ 9
+ /\
+ / \
+ / \
+ / \
+ / \
+ 021 + + 120
+ 5 / \ 8
+ / \
+ / \
+ / \
+ / \
+ 012 + + + 210
+ 2 / 111 \ 7
+ / 4 \
+ / \
+ / \
+ / \
+ /__________________________________\
+ 003 102 201 300
+ 0 1 3 6
+
+
+ Subdivision:
+ P2
+ 030
+ /\
+ / \
+ / \
+ / \
+ / \
+ / up \
+ / \
+ / \
+ p1 /________________\ p0
+ /\ / \
+ / \ / \
+ / \ / \
+ / \ center / \
+ / \ / \
+ / \ / \
+ / left \ / right \
+ / \ / \
+ /________________V_________________\
+ 003 p2 300
+ P0 P1
+ */
+
+ // Subdivide triangle:
+ triple l003=p[0];
+ triple p102=p[1];
+ triple p012=p[2];
+ triple p201=p[3];
+ triple p111=p[4];
+ triple p021=p[5];
+ triple r300=p[6];
+ triple p210=p[7];
+ triple p120=p[8];
+ triple u030=p[9];
+
+ triple u021=0.5*(u030+p021);
+ triple u120=0.5*(u030+p120);
+
+ triple p033=0.5*(p021+p012);
+ triple p231=0.5*(p120+p111);
+ triple p330=0.5*(p120+p210);
+
+ triple p123=0.5*(p012+p111);
+
+ triple l012=0.5*(p012+l003);
+ triple p312=0.5*(p111+p201);
+ triple r210=0.5*(p210+r300);
+
+ triple l102=0.5*(l003+p102);
+ triple p303=0.5*(p102+p201);
+ triple r201=0.5*(p201+r300);
+
+ triple u012=0.5*(u021+p033);
+ triple u210=0.5*(u120+p330);
+ triple l021=0.5*(p033+l012);
+ triple p4xx=0.5*p231+0.25*(p111+p102);
+ triple r120=0.5*(p330+r210);
+ triple px4x=0.5*p123+0.25*(p111+p210);
+ triple pxx4=0.25*(p021+p111)+0.5*p312;
+ triple l201=0.5*(l102+p303);
+ triple r102=0.5*(p303+r201);
+
+ triple l210=0.5*(px4x+l201); // =c120
+ triple r012=0.5*(px4x+r102); // =c021
+ triple l300=0.5*(l201+r102); // =r003=c030
+
+ triple r021=0.5*(pxx4+r120); // =c012
+ triple u201=0.5*(u210+pxx4); // =c102
+ triple r030=0.5*(u210+r120); // =u300=c003
+
+ triple u102=0.5*(u012+p4xx); // =c201
+ triple l120=0.5*(l021+p4xx); // =c210
+ triple l030=0.5*(u012+l021); // =u003=c300
+
+ triple l111=0.5*(p123+l102);
+ triple r111=0.5*(p312+r210);
+ triple u111=0.5*(u021+p231);
+ triple c111=0.25*(p033+p330+p303+p111);
+
+ triple l[]={l003,l102,l012,l201,l111,l021,l300,l210,l120,l030}; // left
+ triple r[]={l300,r102,r012,r201,r111,r021,r300,r210,r120,r030}; // right
+ triple u[]={l030,u102,u012,u201,u111,u021,r030,u210,u120,u030}; // up
+ triple c[]={r030,u201,r021,u102,c111,r012,l030,l120,l210,l300}; // center
+
+ triple n0=normal(l300,r012,r021,r030,u201,u102,l030);
+ triple n1=normal(r030,u201,u102,l030,l120,l210,l300);
+ triple n2=normal(l030,l120,l210,l300,r012,r021,r030);
+
+ // A kludge to remove subdivision cracks, only applied the first time
+ // an edge is found to be flat before the rest of the subpatch is.
+
+ triple p0=0.5*(P1+P2);
+ if(!flat0) {
+ if((flat0=Straightness(r300,p210,p120,u030) < res2))
+ p0 -= Epsilon*unit(derivative(c[0],c[2],c[5],c[9])+
+ derivative(c[0],c[1],c[3],c[6]));
+ else p0=r030;
+ }
+
+ triple p1=0.5*(P2+P0);
+ if(!flat1) {
+ if((flat1=Straightness(l003,p012,p021,u030) < res2))
+ p1 -= Epsilon*unit(derivative(c[6],c[3],c[1],c[0])+
+ derivative(c[6],c[7],c[8],c[9]));
+ else p1=l030;
+ }
+
+ triple p2=0.5*(P0+P1);
+ if(!flat2) {
+ if((flat2=Straightness(l003,p102,p201,r300) < res2))
+ p2 -= Epsilon*unit(derivative(c[9],c[8],c[7],c[6])+
+ derivative(c[9],c[5],c[2],c[0]));
+ else p2=l300;
+ }
+
+ if(C0) {
+ GLfloat c0[4],c1[4],c2[4];
+ for(int i=0; i < 4; ++i) {
+ c0[i]=0.5*(C1[i]+C2[i]);
+ c1[i]=0.5*(C0[i]+C2[i]);
+ c2[i]=0.5*(C0[i]+C1[i]);
+ }
+
+ GLuint i0=pVertex(p0,n0,c0);
+ GLuint i1=pVertex(p1,n1,c1);
+ GLuint i2=pVertex(p2,n2,c2);
+
+ render(l,I0,i2,i1,P0,p2,p1,false,flat1,flat2,C0,c2,c1);
+ render(r,i2,I1,i0,p2,P1,p0,flat0,false,flat2,c2,C1,c0);
+ render(u,i1,i0,I2,p1,p0,P2,flat0,flat1,false,c1,c0,C2);
+ render(c,i0,i1,i2,p0,p1,p2,false,false,false,c0,c1,c2);
+ } else {
+ GLuint i0=pvertex(p0,n0);
+ GLuint i1=pvertex(p1,n1);
+ GLuint i2=pvertex(p2,n2);
+
+ render(l,I0,i2,i1,P0,p2,p1,false,flat1,flat2);
+ render(r,i2,I1,i0,p2,P1,p0,flat0,false,flat2);
+ render(u,i1,i0,I2,p1,p0,P2,flat0,flat1,false);
+ render(c,i0,i1,i2,p0,p1,p2,false,false,false);
+ }
+ }
+}
+
+void BezierTriangle::render(const triple *p, bool straight, GLfloat *c0)
+{
+ triple p0=p[0];
+ epsilon=0;
+ for(int i=1; i < 10; ++i)
+ epsilon=max(epsilon,abs2(p[i]-p0));
+
+ epsilon *= Fuzz4;
+
+ GLuint I0,I1,I2;
+
+ triple p6=p[6];
+ triple p9=p[9];
+
+ triple n0=normal(p9,p[5],p[2],p0,p[1],p[3],p6);
+ triple n1=normal(p0,p[1],p[3],p6,p[7],p[8],p9);
+ triple n2=normal(p6,p[7],p[8],p9,p[5],p[2],p0);
+
+ if(c0) {
+ GLfloat *c1=c0+4;
+ GLfloat *c2=c0+8;
+
+ I0=pVertex(p0,n0,c0);
+ I1=pVertex(p6,n1,c1);
+ I2=pVertex(p9,n2,c2);
+
+ if(!straight)
+ render(p,I0,I1,I2,p0,p6,p9,false,false,false,c0,c1,c2);
+ } else {
+ I0=pvertex(p0,n0);
+ I1=pvertex(p6,n1);
+ I2=pvertex(p9,n2);
+
+ if(!straight)
+ render(p,I0,I1,I2,p0,p6,p9,false,false,false);
+ }
+
+ if(straight) {
+ pindices->push_back(I0);
+ pindices->push_back(I1);
+ pindices->push_back(I2);
+ }
+}
+
+void transform(const std::vector<VertexData>& b)
+{
+ unsigned n=b.size();
+// xbuffer.resize(n);
+// ybuffer.resize(n);
+ zbuffer.resize(n);
+
+ for(unsigned i=0; i < n; ++i) {
+ const GLfloat *v=b[i].position;
+// xbuffer[i]=Tx[0]*b[j]+Tx[1]*b[j+1]+Tx[2]*b[j+2];
+// ybuffer[i]=Ty[0]*b[j]+Ty[1]*b[j+1]+Ty[2]*b[j+2];
+ zbuffer[i]=Tz[0]*v[0]+Tz[1]*v[1]+Tz[2]*v[2];
+ }
+}
+
+// precompute min and max bounds of each triangle
+void bounds(const std::vector<GLuint>& I)
+{
+ unsigned n=I.size()/3;
+/*
+ xmin.resize(n);
+ xmax.resize(n);
+ ymin.resize(n);
+ ymax.resize(n);
+*/
+
+ zmin.resize(n);
+ zmax.resize(n);
+
+ for(unsigned i=0; i < n; ++i) {
+ unsigned i3=3*i;
+ unsigned Ia=I[i3];
+ unsigned Ib=I[i3+1];
+ unsigned Ic=I[i3+2];
+
+
+ /*
+ double xa=xbuffer[Ia];
+ double xb=xbuffer[Ib];
+ double xc=xbuffer[Ic];
+
+ double ya=ybuffer[Ia];
+ double yb=ybuffer[Ib];
+ double yc=ybuffer[Ic];
+ */
+
+ double za=zbuffer[Ia];
+ double zb=zbuffer[Ib];
+ double zc=zbuffer[Ic];
+
+ /*
+ xmin[i]=min(xa,xb,xc);
+ xmax[i]=max(xa,xb,xc);
+
+ ymin[i]=min(ya,yb,yc);
+ ymax[i]=max(ya,yb,yc);
+ */
+
+ zmin[i]=min(za,zb,zc);
+ zmax[i]=max(za,zb,zc);
+ }
+}
+
+void BezierPatch::drawMaterials()
+{
+ if(indices.size() == 0)
+ return;
+
+ static const size_t size=sizeof(GLfloat);
+ static const size_t bytestride=sizeof(vertexData);
+
+ GLuint vertsBufferIndex;
+ GLuint elemBufferIndex;
+
+ GLuint vao;
+
+ glGenVertexArrays(1,&vao);
+ glBindVertexArray(vao);
+
+ glGenBuffers(1,&vertsBufferIndex);
+ glGenBuffers(1,&elemBufferIndex);
+
+ registerBuffer(vertexbuffer,vertsBufferIndex);
+ registerBuffer(indices,elemBufferIndex);
+
+ glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
+
+ camp::setUniforms(materialShader);
+
+ const GLint posAttrib=glGetAttribLocation(materialShader,"position");
+ const GLint normalAttrib=glGetAttribLocation(materialShader,"normal");
+ const GLint materialAttrib=glGetAttribLocation(materialShader,"material");
+
+ glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,(void *) 0);
+ glEnableVertexAttribArray(posAttrib);
+
+ glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
+ (void *) (3*size));
+ glEnableVertexAttribArray(normalAttrib);
+
+ glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,
+ (void *) (6*size));
+ glEnableVertexAttribArray(materialAttrib);
+
+ glFlush(); // Workaround broken MSWindows drivers for Intel GPU
+ glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,(void *) 0);
+
+ glDisableVertexAttribArray(posAttrib);
+ glDisableVertexAttribArray(normalAttrib);
+ glDisableVertexAttribArray(materialAttrib);
+
+ deleteUniforms();
+
+ glBindBuffer(GL_ARRAY_BUFFER,0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+
+ glBindVertexArray(0);
+ glDeleteVertexArrays(1,&vao);
+
+ glDeleteBuffers(1,&vertsBufferIndex);
+ glDeleteBuffers(1,&elemBufferIndex);
+}
+
+void BezierPatch::drawColors(GLuint& Nvertices,
+ std::vector<VertexData>& Vertexbuffer,
+ std::vector<GLuint>& Indices)
+{
+ if(Indices.size() == 0)
+ return;
+
+ static const size_t size=sizeof(GLfloat);
+ static const size_t bytestride=sizeof(VertexData);
+
+ GLuint vertsBufferIndex;
+ GLuint elemBufferIndex;
+
+ GLuint vao;
+
+ glGenVertexArrays(1,&vao);
+ glBindVertexArray(vao);
+
+ glGenBuffers(1,&vertsBufferIndex);
+ glGenBuffers(1,&elemBufferIndex);
+
+ registerBuffer(Vertexbuffer,vertsBufferIndex);
+ registerBuffer(Indices,elemBufferIndex);
+
+ glBindBuffer(GL_ARRAY_BUFFER,vertsBufferIndex);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elemBufferIndex);
+
+ camp::setUniforms(colorShader);
+
+ const GLint posAttrib=glGetAttribLocation(colorShader,"position");
+ const GLint normalAttrib=glGetAttribLocation(colorShader,"normal");
+ const GLint colorAttrib=glGetAttribLocation(colorShader,"color");
+ const GLint materialAttrib=glGetAttribLocation(colorShader,"material");
+
+ glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
+ (void *) 0);
+ glEnableVertexAttribArray(posAttrib);
+
+ glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
+ (void *) (3*size));
+ glEnableVertexAttribArray(normalAttrib);
+
+ glVertexAttribIPointer(colorAttrib,1,GL_UNSIGNED_INT,bytestride,
+ (void *) (6*size));
+ glEnableVertexAttribArray(colorAttrib);
+
+ glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride,
+ (void *) (6*size+sizeof(GLuint)));
+ glEnableVertexAttribArray(materialAttrib);
+
+ glFlush(); // Workaround broken MSWindows drivers for Intel GPU
+ glDrawElements(GL_TRIANGLES,Indices.size(),GL_UNSIGNED_INT,(void *) 0);
+
+ glDisableVertexAttribArray(posAttrib);
+ glDisableVertexAttribArray(normalAttrib);
+ glDisableVertexAttribArray(colorAttrib);
+ glDisableVertexAttribArray(materialAttrib);
+
+ deleteUniforms();
+
+ glBindBuffer(GL_ARRAY_BUFFER,0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
+
+ glBindVertexArray(0);
+ glDeleteVertexArrays(1,&vao);
+
+ glDeleteBuffers(1,&vertsBufferIndex);
+ glDeleteBuffers(1,&elemBufferIndex);
+}
+
+void BezierPatch::sortTriangles()
+{
+ if(Ntvertices > 0) {
+ transform(tVertexbuffer);
+ bounds(tIndices);
+ qsort(&tIndices[0],tIndices.size()/3,3*sizeof(GLuint),compare);
+ }
+}
+
+void Triangles::queue(size_t nP, triple* P, size_t nN, triple* N,
+ size_t nC, prc::RGBAColour* C, size_t nI,
+ uint32_t (*PI)[3], uint32_t (*NI)[3], uint32_t (*CI)[3],
+ bool transparent)
+{
+ if(!nN) return;
+ const size_t indexstride=3;
+ size_t nindices=indexstride*nI;
+ size_t index0;
+
+ if(transparent) {
+ tVertexbuffer.reserve(nbuffer);
+ tVertexbuffer.resize(Ntvertices+nP);
+ tIndices.reserve(nbuffer);
+ index0=tIndices.size();
+ tIndices.resize(index0+nindices);
+ } else {
+ if(nC) {
+ Vertexbuffer.reserve(nbuffer);
+ Vertexbuffer.resize(Nvertices+nP);
+ Indices.reserve(nbuffer);
+ index0=Indices.size();
+ Indices.resize(index0+nindices);
+ } else {
+ vertexbuffer.reserve(nbuffer);
+ vertexbuffer.resize(nvertices+nP);
+ indices.reserve(nbuffer);
+ index0=indices.size();
+ indices.resize(index0+nindices);
+ }
+ }
+
+ uint32_t *P0=(uint32_t *) PI;
+ uint32_t *N0=(uint32_t *) NI;
+ uint32_t *C0=(uint32_t *) CI;
+
+ if(transparent) {
+ if(nC) {
+ for(size_t i=0; i < nindices; ++i) {
+ uint32_t i0=P0[i];
+ prc::RGBAColour c=C[C0[i]];
+ GLfloat c0[]={(GLfloat) c.R,(GLfloat) c.G,(GLfloat) c.B,(GLfloat) c.A};
+ GLuint index=Ntvertices+i0;
+ tVertexbuffer[index]=VertexData(P[i0],N[N0[i]],c0);
+ tIndices[index0+i]=index;
+ }
+ } else {
+ for(size_t i=0; i < nindices; ++i) {
+ uint32_t i0=P0[i];
+ GLuint index=Ntvertices+i0;
+ tVertexbuffer[index]=VertexData(P[i0],N[N0[i]]);
+ tIndices[index0+i]=index;
+ }
+ }
+ Ntvertices += nP;
+ } else {
+ if(nC) {
+ for(size_t i=0; i < nindices; ++i) {
+ uint32_t i0=P0[i];
+ prc::RGBAColour c=C[C0[i]];
+ GLfloat c0[]={(GLfloat) c.R,(GLfloat) c.G,(GLfloat) c.B,
+ (GLfloat) c.A};
+ GLuint index=Nvertices+i0;
+ Vertexbuffer[index]=VertexData(P[i0],N[N0[i]],c0);
+ Indices[index0+i]=index;
+ }
+ Nvertices += nP;
+ } else {
+ for(size_t i=0; i < nindices; ++i) {
+ uint32_t i0=P0[i];
+ GLuint index=nvertices+i0;
+ vertexbuffer[index]=vertexData(P[i0],N[N0[i]]);
+ indices[index0+i]=index;
+ }
+ nvertices += nP;
+ }
+ }
+}
+
+#endif
+
+} //namespace camp
diff --git a/graphics/asymptote/bezierpatch.h b/graphics/asymptote/bezierpatch.h
new file mode 100644
index 0000000000..b8c23574d7
--- /dev/null
+++ b/graphics/asymptote/bezierpatch.h
@@ -0,0 +1,315 @@
+/*****
+ * bezierpatch.h
+ * Authors: John C. Bowman and Jesse Frohlich
+ *
+ * Render Bezier patches and triangles.
+ *****/
+
+#ifndef BEZIERPATCH_H
+#define BEZIERPATCH_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+#ifdef HAVE_GL
+
+extern const double Fuzz4;
+
+class vertexData {
+public:
+ GLfloat position[3];
+ GLfloat normal[3];
+ GLint material;
+ vertexData() {};
+ vertexData(const triple& v, const triple& n) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ normal[0]=n.getx();
+ normal[1]=n.gety();
+ normal[2]=n.getz();
+ material=drawElement::materialIndex;
+ }
+};
+
+class VertexData {
+public:
+ GLfloat position[3];
+ GLfloat normal[3];
+ GLuint color;
+ GLint material;
+ VertexData() {};
+ VertexData(const triple& v, const triple& n) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ normal[0]=n.getx();
+ normal[1]=n.gety();
+ normal[2]=n.getz();
+ color=0;
+ material=drawElement::materialIndex;
+ }
+ VertexData(const triple& v, const triple& n, GLfloat *c) {
+ position[0]=v.getx();
+ position[1]=v.gety();
+ position[2]=v.getz();
+ normal[0]=n.getx();
+ normal[1]=n.gety();
+ normal[2]=n.getz();
+ color=glm::packUnorm4x8(glm::vec4(c[0],c[1],c[2],c[3]));
+ material=-(int) drawElement::materialIndex-1; // request explicit color
+ }
+
+};
+
+struct BezierPatch
+{
+ static std::vector<vertexData> vertexbuffer;
+ static std::vector<VertexData> Vertexbuffer;
+ static std::vector<VertexData> tVertexbuffer; // for transparent surfaces
+ static std::vector<GLuint> indices;
+ static std::vector<GLuint> Indices;
+ static std::vector<GLuint> tIndices;
+ static GLuint nvertices;
+ static GLuint Nvertices;
+ static GLuint Ntvertices;
+
+ static GLuint vertsBufferIndex;
+ static GLuint VertsBufferIndex;
+ static GLuint tVertsBufferIndex;
+
+ static GLuint elemBufferIndex;
+ static GLuint ElemBufferIndex;
+ static GLuint tElemBufferIndex;
+
+ std::vector<GLuint> *pindices;
+ triple u,v,w;
+ double epsilon;
+ double Epsilon;
+ double res2;
+ double Res2; // Reduced resolution for Bezier triangles flatness test.
+ triple Min,Max;
+ typedef GLuint vertexFunction(const triple &v, const triple& n);
+ typedef GLuint VertexFunction(const triple &v, const triple& n, GLfloat *c);
+ vertexFunction *pvertex;
+ VertexFunction *pVertex;
+
+ BezierPatch() {}
+
+ void init(double res, const triple& Min, const triple& Max,
+ bool transparent, GLfloat *colors=NULL);
+
+// Store the vertex v and its normal vector n in the buffer.
+ static GLuint vertex(const triple &v, const triple& n) {
+ vertexbuffer.push_back(vertexData(v,n));
+ return nvertices++;
+ }
+
+// Store the vertex v and its normal vector n and colour c in the buffer.
+ static GLuint Vertex(const triple& v, const triple& n, GLfloat *c) {
+ Vertexbuffer.push_back(VertexData(v,n,c));
+ return Nvertices++;
+ }
+
+ static GLuint tvertex(const triple &v, const triple& n) {
+ tVertexbuffer.push_back(VertexData(v,n));
+ return Ntvertices++;
+ }
+
+ static GLuint tVertex(const triple& v, const triple& n, GLfloat *c) {
+ tVertexbuffer.push_back(VertexData(v,n,c));
+ return Ntvertices++;
+ }
+
+ triple normal(triple left3, triple left2, triple left1, triple middle,
+ triple right1, triple right2, triple right3) {
+ triple rp=right1-middle;
+ triple lp=left1-middle;
+ triple n=triple(rp.gety()*lp.getz()-rp.getz()*lp.gety(),
+ rp.getz()*lp.getx()-rp.getx()*lp.getz(),
+ rp.getx()*lp.gety()-rp.gety()*lp.getx());
+ if(abs2(n) > epsilon)
+ return unit(n);
+
+ triple lpp=bezierPP(middle,left1,left2);
+ triple rpp=bezierPP(middle,right1,right2);
+ n=cross(rpp,lp)+cross(rp,lpp);
+ if(abs2(n) > epsilon)
+ return unit(n);
+
+ triple lppp=bezierPPP(middle,left1,left2,left3);
+ triple rppp=bezierPPP(middle,right1,right2,right3);
+
+ return unit(9.0*cross(rpp,lpp)+
+ 3.0*(cross(rp,lppp)+cross(rppp,lp)+
+ cross(rppp,lpp)+cross(rpp,lppp))+
+ cross(rppp,lppp));
+ }
+
+ triple derivative(triple p0, triple p1, triple p2, triple p3) {
+ triple lp=p1-p0;
+ if(abs2(lp) > epsilon)
+ return lp;
+
+ triple lpp=bezierPP(p0,p1,p2);
+ if(abs2(lpp) > epsilon)
+ return lpp;
+
+ return bezierPPP(p0,p1,p2,p3);
+ }
+
+ virtual double Distance(const triple *p) {
+ triple p0=p[0];
+ triple p3=p[3];
+ triple p12=p[12];
+ triple p15=p[15];
+
+ // Check the flatness of the quad.
+ double d=Distance2(p15,p0,normal(p3,p[2],p[1],p0,p[4],p[8],p12));
+
+ // Determine how straight the edges are.
+ d=max(d,Straightness(p0,p[1],p[2],p3));
+ d=max(d,Straightness(p0,p[4],p[8],p12));
+ d=max(d,Straightness(p3,p[7],p[11],p15));
+ d=max(d,Straightness(p12,p[13],p[14],p15));
+
+ // Determine how straight the interior control curves are.
+ d=max(d,Straightness(p[4],p[5],p[6],p[7]));
+ d=max(d,Straightness(p[8],p[9],p[10],p[11]));
+ d=max(d,Straightness(p[1],p[5],p[9],p[13]));
+ return max(d,Straightness(p[2],p[6],p[10],p[14]));
+ }
+
+ struct Split3 {
+ triple m0,m2,m3,m4,m5;
+ Split3() {}
+ Split3(triple z0, triple c0, triple c1, triple z1) {
+ m0=0.5*(z0+c0);
+ triple m1=0.5*(c0+c1);
+ m2=0.5*(c1+z1);
+ m3=0.5*(m0+m1);
+ m4=0.5*(m1+m2);
+ m5=0.5*(m3+m4);
+ }
+ };
+
+// Approximate bounds by bounding box of control polyhedron.
+ bool offscreen(size_t n, const triple *v) {
+ double x,y,z;
+ double X,Y,Z;
+
+ boundstriples(x,y,z,X,Y,Z,n,v);
+ return
+ X < Min.getx() || x > Max.getx() ||
+ Y < Min.gety() || y > Max.gety() ||
+ Z < Min.getz() || z > Max.getz();
+ }
+
+ static void clear() {
+ nvertices=0;
+ vertexbuffer.clear();
+ indices.clear();
+ }
+
+ static void Clear() {
+ Nvertices=0;
+ Vertexbuffer.clear();
+ Indices.clear();
+ }
+
+ static void tClear() {
+ Ntvertices=0;
+ tVertexbuffer.clear();
+ tIndices.clear();
+ }
+
+ ~BezierPatch() {}
+
+ void render(const triple *p,
+ GLuint I0, GLuint I1, GLuint I2, GLuint I3,
+ triple P0, triple P1, triple P2, triple P3,
+ bool flat0, bool flat1, bool flat2, bool flat3,
+ GLfloat *C0=NULL, GLfloat *C1=NULL, GLfloat *C2=NULL,
+ GLfloat *C3=NULL);
+ virtual void render(const triple *p, bool straight, GLfloat *c0=NULL);
+
+ void queue(const triple *g, bool straight, double ratio,
+ const triple& Min, const triple& Max, bool transparent,
+ GLfloat *colors=NULL) {
+ init(pixel*ratio,Min,Max,transparent,colors);
+ render(g,straight,colors);
+ }
+
+ void drawMaterials();
+ void drawColors(GLuint& Nvertices,
+ std::vector<VertexData>& Vertexbuffer,
+ std::vector<GLuint>& Indices);
+ void sortTriangles();
+
+ void drawColors() {
+ drawColors(Nvertices,Vertexbuffer,Indices);
+ }
+
+ void drawOpaque() {
+ drawMaterials();
+ drawColors();
+ }
+
+ void drawTransparent() {
+ glDepthMask(GL_FALSE);
+ sortTriangles();
+ drawColors(Ntvertices,tVertexbuffer,tIndices);
+ glDepthMask(GL_TRUE);
+ }
+
+ void draw() {
+ drawOpaque();
+ drawTransparent();
+ }
+
+};
+
+struct BezierTriangle : public BezierPatch {
+public:
+ BezierTriangle() : BezierPatch() {}
+
+ double Distance(const triple *p) {
+ triple p0=p[0];
+ triple p6=p[6];
+ triple p9=p[9];
+
+ // Check how far the internal point is from the centroid of the vertices.
+ double d=abs2((p0+p6+p9)*third-p[4]);
+
+ // Determine how straight the edges are.
+ d=max(d,Straightness(p0,p[1],p[3],p6));
+ d=max(d,Straightness(p0,p[2],p[5],p9));
+ return max(d,Straightness(p6,p[7],p[8],p9));
+ }
+
+ void render(const triple *p,
+ GLuint I0, GLuint I1, GLuint I2,
+ triple P0, triple P1, triple P2,
+ bool flat0, bool flat1, bool flat2,
+ GLfloat *C0=NULL, GLfloat *C1=NULL, GLfloat *C2=NULL);
+ void render(const triple *p, bool straight, GLfloat *c0=NULL);
+};
+
+
+struct Triangles : public BezierPatch {
+public:
+ Triangles() : BezierPatch() {}
+
+ void queue(size_t nP, triple* P, size_t nN, triple* N,
+ size_t nC, prc::RGBAColour* C, size_t nI,
+ uint32_t (*PI)[3], uint32_t (*NI)[3], uint32_t (*CI)[3],
+ bool transparent);
+};
+
+
+#endif
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/binaries/i386-windows/README b/graphics/asymptote/binaries/i386-windows/README
new file mode 100644
index 0000000000..77e7edfb59
--- /dev/null
+++ b/graphics/asymptote/binaries/i386-windows/README
@@ -0,0 +1,66 @@
+ ASYMPTOTE
+ Copyright 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince
+
+Asymptote is a powerful descriptive vector graphics language for technical
+drawing, inspired by MetaPost but with an improved C++-like
+syntax. Asymptote provides for figures the same high-quality level of
+typesetting that LaTeX does for scientific text.
+
+Installation instructions, documentation, binaries, and source code are
+available at:
+
+http://asymptote.sourceforge.net
+
+Bugs/Patches/Feature Requests can be submitted to
+
+https://github.com/vectorgraphics/asymptote/issues
+
+Questions and comments should be sent to the Asymptote Forum:
+
+http://sourceforge.net/p/asymptote/discussion/409349
+
+All source files in the Asymptote project, unless explicitly noted otherwise,
+are released under version 3 (or later) of the GNU Lesser General Public
+License (see the files LICENSE.LESSER and LICENSE in the top-level source
+directory).
+
+========================================================================
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+========================================================================
+
+Note that the MSWindows executable version of Asymptote can only be
+released under the GNU General Public License (GPL) as it is linked against
+the GNU Scientific Library, GNU Readline library, and other GPL
+libraries. This version of Asymptote also ships with the cygwin1.dll libraries
+noted below.
+
+========================================================================
+
+Source code for the x86_64 and i386 3.0.4 cygwin1.dll libraries is
+available under the GPL license:
+https://cygwin.com/snapshots/
+
+Source for various icons is available under the MIT license from
+https://github.com/driftyco/ionicons/archive/v2.0.1.zip
+https://github.com/iconic/open-iconic/archive/master.zip
+under the CC-BY-SA 4.0 license:
+http://www.entypo.com/
+and under a CC license:
+http://www.zondicons.com/zondicons.zip
+
+Uses OpenImageIO, which the source is available at
+https://github.com/OpenImageIO/oiio.
+Copyright 2008-2018 Larry Gritz et al. All Rights Reserved. \ No newline at end of file
diff --git a/graphics/asymptote/binaries/i386-windows/cygwin1.dll b/graphics/asymptote/binaries/i386-windows/cygwin1.dll
new file mode 100755
index 0000000000..b609c0425e
--- /dev/null
+++ b/graphics/asymptote/binaries/i386-windows/cygwin1.dll
Binary files differ
diff --git a/graphics/asymptote/binaries/i386-windows/texlive/README b/graphics/asymptote/binaries/i386-windows/texlive/README
new file mode 100644
index 0000000000..8e4192121d
--- /dev/null
+++ b/graphics/asymptote/binaries/i386-windows/texlive/README
@@ -0,0 +1,5 @@
+The Asymptote executable for MSWindows can only be released under the GNU
+General Public License (GPL) as it is linked against the GNU Scientific
+Library, GNU Readline library, and other GPL libraries. The Asymptote
+source itself is released under the GNU Lesser General Public License.
+
diff --git a/graphics/asymptote/binaries/x86_64-windows/README b/graphics/asymptote/binaries/x86_64-windows/README
new file mode 100644
index 0000000000..77e7edfb59
--- /dev/null
+++ b/graphics/asymptote/binaries/x86_64-windows/README
@@ -0,0 +1,66 @@
+ ASYMPTOTE
+ Copyright 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince
+
+Asymptote is a powerful descriptive vector graphics language for technical
+drawing, inspired by MetaPost but with an improved C++-like
+syntax. Asymptote provides for figures the same high-quality level of
+typesetting that LaTeX does for scientific text.
+
+Installation instructions, documentation, binaries, and source code are
+available at:
+
+http://asymptote.sourceforge.net
+
+Bugs/Patches/Feature Requests can be submitted to
+
+https://github.com/vectorgraphics/asymptote/issues
+
+Questions and comments should be sent to the Asymptote Forum:
+
+http://sourceforge.net/p/asymptote/discussion/409349
+
+All source files in the Asymptote project, unless explicitly noted otherwise,
+are released under version 3 (or later) of the GNU Lesser General Public
+License (see the files LICENSE.LESSER and LICENSE in the top-level source
+directory).
+
+========================================================================
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+========================================================================
+
+Note that the MSWindows executable version of Asymptote can only be
+released under the GNU General Public License (GPL) as it is linked against
+the GNU Scientific Library, GNU Readline library, and other GPL
+libraries. This version of Asymptote also ships with the cygwin1.dll libraries
+noted below.
+
+========================================================================
+
+Source code for the x86_64 and i386 3.0.4 cygwin1.dll libraries is
+available under the GPL license:
+https://cygwin.com/snapshots/
+
+Source for various icons is available under the MIT license from
+https://github.com/driftyco/ionicons/archive/v2.0.1.zip
+https://github.com/iconic/open-iconic/archive/master.zip
+under the CC-BY-SA 4.0 license:
+http://www.entypo.com/
+and under a CC license:
+http://www.zondicons.com/zondicons.zip
+
+Uses OpenImageIO, which the source is available at
+https://github.com/OpenImageIO/oiio.
+Copyright 2008-2018 Larry Gritz et al. All Rights Reserved. \ No newline at end of file
diff --git a/graphics/asymptote/binaries/x86_64-windows/cygwin1.dll b/graphics/asymptote/binaries/x86_64-windows/cygwin1.dll
new file mode 100644
index 0000000000..e8577981dc
--- /dev/null
+++ b/graphics/asymptote/binaries/x86_64-windows/cygwin1.dll
Binary files differ
diff --git a/graphics/asymptote/binaries/x86_64-windows/texlive/README b/graphics/asymptote/binaries/x86_64-windows/texlive/README
new file mode 100644
index 0000000000..8e4192121d
--- /dev/null
+++ b/graphics/asymptote/binaries/x86_64-windows/texlive/README
@@ -0,0 +1,5 @@
+The Asymptote executable for MSWindows can only be released under the GNU
+General Public License (GPL) as it is linked against the GNU Scientific
+Library, GNU Readline library, and other GPL libraries. The Asymptote
+source itself is released under the GNU Lesser General Public License.
+
diff --git a/graphics/asymptote/build-scripts/HOWTO-MSWindows b/graphics/asymptote/build-scripts/HOWTO-MSWindows
new file mode 100644
index 0000000000..609c6fd769
--- /dev/null
+++ b/graphics/asymptote/build-scripts/HOWTO-MSWindows
@@ -0,0 +1,63 @@
+ Compiling MSWindows binary of Asymptote under CYGWIN-x86_64
+
+First run build-asymptote on Linux. This will build the documentation
+and source tar ball and copy them to a directory ~/shared which needs to be
+shared via virtualbox to the cygwin build environment.
+
+Install TeXLive and required Cygwin packages:
+
+setup-x86_64.exe -q -P git,wget,make,patch,gcc-g++,autoconf2.5,bison,flex,w32api-headers,w32api-runtime,zlib-devel,glm-devel,automake1.15,libtool
+
+setup-x86_64.exe -q -I -P libtirpc-devel,libreadline-devel,libfftw3-devel,libgsl-devel
+
+Build and install static libraries from /usr/local/src:
+
+gsl-devel:
+./configure --prefix=/usr
+make install
+
+readline-devel:
+./configure --prefix=/usr --without-curses --disable-shared
+make install
+
+fftw3-devel:
+./configure --prefix=/usr --enable-shared
+make install
+
+tirpc-devel:
+./configure --prefix=/usr --disable-gssapi
+make install
+ln -s /usr/include/tirpc/rpc /usr/include/rpc
+ln -s /usr/include/tirpc/netconfig.h /usr/include/netconfig.h
+ln -s /usr/lib/libtirpc.a /usr/lib/librpc.a
+
+termcap-1.3.1:
+./configure --prefix=/usr
+make install
+
+git clone http://github.com/vectorgraphics/asymptote
+
+freeglut-3.0.0:
+patch -p1 < ~/asymptote/patches/cygwin_freeglut-3.0.0.patch
+cmake CMakeLists.txt
+make
+cp lib/libfreeglut_static.a /usr/lib/libfreeglut.a
+cp -a include/GL/*.h /usr/include/w32api/GL/
+
+mkdir -p ~/dll/cygwin
+cp /usr/bin/cygwin1.dll ~/dll/cygwin
+
+mkdir ~/CTAN
+cp -a ~/asymptote/build-scripts/README-binaries ~/CTAN
+
+GCVERSION=7.6.2
+wget http://hboehm.info/gc/gc_source/gc-$GCVERSION.tar.gz
+wget http://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-$GCVERSION.tar.gz
+tar -zxf gc-$GCVERSION.tar.gz
+tar -zxf libatomic_ops-$GCVERSION.tar.gz
+mv libatomic_ops-$GCVERSION gc-$GCVERSION/libatomic_ops
+cd gc-$GCVERSION
+./configure --disable-shared
+make check
+
+~/asymptote/build-scripts/build-asymptote.dos 2.48
diff --git a/graphics/asymptote/build-scripts/README-binaries b/graphics/asymptote/build-scripts/README-binaries
new file mode 100644
index 0000000000..8e4192121d
--- /dev/null
+++ b/graphics/asymptote/build-scripts/README-binaries
@@ -0,0 +1,5 @@
+The Asymptote executable for MSWindows can only be released under the GNU
+General Public License (GPL) as it is linked against the GNU Scientific
+Library, GNU Readline library, and other GPL libraries. The Asymptote
+source itself is released under the GNU Lesser General Public License.
+
diff --git a/graphics/asymptote/build-scripts/build-asymptote b/graphics/asymptote/build-scripts/build-asymptote
new file mode 100755
index 0000000000..e3553fbfd0
--- /dev/null
+++ b/graphics/asymptote/build-scripts/build-asymptote
@@ -0,0 +1,74 @@
+#!/bin/sh -x
+# Usage: build-asymptote [suffix]
+
+HOME=~bowman
+SHARED=$HOME/shared/asy
+
+GCVERSION=8.0.4
+ATOMICVERSION=7.6.10
+GC=gc-$GCVERSION
+
+MAKEFLAGS=-j8
+export MAKEFLAGS
+ASYMPTOTE=$HOME/asymptote
+BUILD=/usr/local/src
+BINDIR=usr
+test /usr -ef $BUILD/$BINDIR && exit
+LATEXDIR=$BUILD/$BINDIR/share/texmf/tex/latex/asymptote
+cd $BUILD
+rm -rf asymptote
+git clone http://github.com/vectorgraphics/asymptote
+cd asymptote
+git log > ChangeLog
+VERSIONgit=`grep AC_INIT configure.ac | cut -s -d[ -f3 | cut -s -d] -f1`
+VERSION=${VERSIONgit/git/}
+cat configure.ac | sed -e "s/$VERSIONgit/$VERSION/" > configure.ac_
+mv configure.ac_ configure.ac
+cat $ASYMPTOTE/asymptote.spec | sed -e "s|Version:.*|Version: $VERSION|" > asymptote.spec
+SRC=asymptote-$VERSION.src.tgz
+if [ $# == 0 ]; then
+ cp asymptote.spec $ASYMPTOTE
+fi
+cd $BUILD
+rm -rf asymptote-$VERSION
+rm -rf $BUILD/$BINDIR
+mv asymptote asymptote-$VERSION
+wget https://github.com/ivmai/bdwgc/releases/download/v$GCVERSION/gc-$GCVERSION.tar.gz
+wget https://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-$ATOMICVERSION.tar.gz
+cp /usr/local/src/$GC.tar.gz asymptote-$VERSION
+cp /usr/local/src/libatomic_ops-$ATOMICVERSION.tar.gz asymptote-$VERSION
+chown -R root.root asymptote-$VERSION
+cd asymptote-$VERSION
+find . -type d -exec /bin/bash -c "cd '{}';rm -rf .git" \;
+rm -rf .gitignore .vscode
+./autogen.sh
+./configure
+make $MAKEFLAGS check || exit
+make uninstall
+make $MAKEFLAGS asy
+make -j1 all
+make -j1 install
+#rm asy
+#make LFLAGS=-static
+strip asy
+make DESTDIR="$BUILD/" latexdir=$LATEXDIR install
+#rm $GC.tar.gz
+rm $BUILD/$BINDIR/local/info/dir
+cp -a $BUILD/asymptote-$VERSION/ChangeLog .
+cp -a $ASYMPTOTE/ReleaseNotes .
+make distclean
+rm -rf autom4te.cache
+cd /usr/local/share/doc/asymptote
+rm -rf $SHARED/asydoc
+mkdir -p $SHARED/asydoc/png
+mkdir -p $SHARED/asydoc/FAQ
+cp -a *.pdf ../../man/man1/asy.1 $SHARED/asydoc
+cp -a /usr/local/share/info/asymptote/asymptote.info $SHARED/asydoc/png
+cp -a /usr/local/share/info/asy-faq.info $SHARED/asydoc/FAQ
+cd $BUILD
+tar cfz $SRC asymptote-$VERSION
+tar cfz asymptote-$VERSION.x86_64.tgz $BINDIR
+cp $SRC $SHARED
+rm -rf $BUILD/$BINDIR
+tar -zxf asymptote-$VERSION.x86_64.tgz
+su rpmbuild -c "rpmbuild -ta --nodeps $SRC && rm -rf ~/rpms/BUILD/asymptote-$VERSION&&chmod -R g+r /u/rpmbuild/rpms/RPMS/"
diff --git a/graphics/asymptote/build-scripts/build-asymptote.dos b/graphics/asymptote/build-scripts/build-asymptote.dos
new file mode 100755
index 0000000000..943c7ca0a1
--- /dev/null
+++ b/graphics/asymptote/build-scripts/build-asymptote.dos
@@ -0,0 +1,97 @@
+#!/bin/sh -x
+GC=7.6.2
+
+MACHINE=`uname -m`
+if [ $MACHINE == i686 ]; then
+BINDIR=i386-windows
+else
+BINDIR=x86_64-windows
+fi
+SHARED=~/shared/asy
+MAKEFLAGS=-j8
+export MAKEFLAGS
+VERSION=$1
+if [ -z $VERSION ]; then
+VERSION=`grep AC_INIT configure.ac | cut -s -d[ -f3 | cut -s -d] -f1`
+if [ -z $VERSION ]; then
+echo Usage: $0 VERSION
+exit
+fi
+else
+echo Building asymptote-$VERSION
+cd ~/
+rm -rf asymptote-$VERSION
+mkdir -p CTAN
+rm -rf CTAN/asymptote-$VERSION
+tar -zxf $SHARED/asymptote-$VERSION.src.tgz -C CTAN
+tar -zxf $SHARED/asymptote-$VERSION.src.tgz
+mkdir -p CTAN/asymptote-$VERSION/binaries/$BINDIR/texlive
+cd asymptote-$VERSION
+fi
+BUILD=build-$VERSION
+ln -sf ../gc-$GC.tar.gz .
+ln -sf ../gc-$GC .
+make -n MSDOS=1 >& /dev/null || ./configure --enable-gc=$GC --with-latex=/usr/local/share --with-context=/usr/local/share
+rm -rf $BUILD
+mkdir -p $BUILD
+cp -a $HOME/dll/cygwin/*.dll $BUILD
+chmod 0644 $BUILD/*.dll
+cp -a $BUILD/*.dll ~/CTAN/asymptote-$VERSION/binaries/$BINDIR/
+make MSDOS=1 DESTDIR="$BUILD/" docdir="$BUILD/"
+test -f asy.list || make MSDOS=1 keywords DESTDIR="$BUILD/" docdir="$BUILD/"
+make MSDOS=1 install-asy DESTDIR="$BUILD/" docdir="$BUILD/"
+cp asy.ico README LICENSE* $BUILD
+pushd $BUILD
+mv usr/local/bin/* .
+mv usr/local/share/asymptote/GUI .
+rm -rf usr/local/share/asymptote/GUI
+mv usr/local/share/asymptote/* .
+cp $SHARED/asydoc/*.pdf .
+rm -rf bin share doc usr
+popd
+echo \!define PRODUCT_VERSION \"$VERSION\" > AsymptoteInstallInfo.nsi
+# generate uninstallation commands
+ls -p1 $BUILD \
+ | awk '{ if(index($0,"/")==length($0)) print "RMDir /r $INSTDIR\\" substr($0,0,length($0)-1); else print "Delete $INSTDIR\\" $0 }' \
+ > AsymptoteUninstallList.nsi
+
+if [ $MACHINE == i686 ]; then
+sed asymptote.nsi -e 's/$PROGRAMFILES64/$PROGRAMFILES/g' > asymptote32.nsi
+/cygdrive/c/Program\ Files\ \(x86\)/NSIS/makensis.exe asymptote32.nsi
+SUFFIX=-i386_32
+else
+/cygdrive/c/Program\ Files\ \(x86\)/NSIS/makensis.exe asymptote.nsi
+SUFFIX=
+fi
+cp -a --no-preserve=mode asymptote-$VERSION-setup.exe $SHARED/asymptote-$VERSION-setup$SUFFIX.exe
+mv asymptote-$VERSION-setup.exe ~/asymptote-$VERSION-setup$SUFFIX.exe
+
+cd ~/
+rm -rf asymptote-${VERSION}TL || exit
+cp -a asymptote-$VERSION asymptote-${VERSION}TL
+sed asymptote-$VERSION/config.h -e 's/ASYMPTOTE_SYSDIR ".*"/ASYMPTOTE_SYSDIR ""/g' > asymptote-${VERSION}TL/config.h
+#sed asymptote-$VERSION/configure.ac -e 's/\-std=c++11//g' > asymptote-${VERSION}TL/configure.ac
+touch -r asymptote-$VERSION/config.h asymptote-${VERSION}TL/config.h
+touch -r asymptote-$VERSION/configure.ac asymptote-${VERSION}TL/configure.ac
+cd asymptote-${VERSION}TL
+rm settings.o
+rm -f doc/*.aux doc/*.log doc/*.dvi
+make MSDOS=1 DESTDIR="$BUILD/"
+make MSDOS=1 install-asy DESTDIR="$BUILD/"
+mv $BUILD/usr/local/bin/asy.exe $BUILD
+cp $BUILD/asy.exe ~/CTAN/asymptote-$VERSION/binaries/$BINDIR/texlive
+cp -a configure.ac ~/CTAN/asymptote-$VERSION/
+cp -a $SHARED/asydoc/* ~/CTAN/asymptote-$VERSION/doc
+cd ~/CTAN/asymptote-$VERSION/binaries/$BINDIR
+cp -a ../../README .
+cd ~/CTAN
+cp -a ~/asymptote/build-scripts/README-binaries asymptote-$VERSION/binaries/$BINDIR/texlive/README
+SHAREDBIN=$SHARED/CTAN/asymptote-$VERSION
+if [ $MACHINE == i686 ]; then
+mkdir -p $SHAREDBIN
+cp -a asymptote-$VERSION/binaries/$BINDIR $SHAREDBIN
+else
+cp -a $SHAREDBIN/i386-windows ~/CTAN/asymptote-$VERSION/binaries
+fi
+tar cfz asymptote-$VERSION-CTAN.tgz asymptote-$VERSION
+cp -a --no-preserve=mode asymptote-$VERSION-CTAN.tgz $SHARED
diff --git a/graphics/asymptote/build-scripts/build-freeglut b/graphics/asymptote/build-scripts/build-freeglut
new file mode 100755
index 0000000000..95d4cbfb4b
--- /dev/null
+++ b/graphics/asymptote/build-scripts/build-freeglut
@@ -0,0 +1,22 @@
+#!/bin/sh -x
+#Be sure to remove /usr/include/GL
+wget http://prdownloads.sourceforge.net/freeglut/freeglut-2.8.1.tar.gz
+ln -sf /usr/bin/cyggcc_s-1.dll /usr/lib/libgcc_s.a
+tar -zxf freeglut-2.8.1.tar.gz
+cd freeglut-2.8.1
+patch -p1 < ~/asymptote/patches/cygwin_freeglut-2.8.1.patch
+./configure --prefix=/usr --without-x
+make
+cd src
+gcc -s -static -shared -o freeglut.dll *.o -Wl,--out-implib=libfreeglut.a -lglu32 -lopengl32 -lgdi32 -lwinmm
+cp freeglut.dll /lib
+mkdir -p ~/dll
+cp freeglut.dll ~/dll
+gcc -s -shared -o freeglut.dll *.o -Wl,--out-implib=libfreeglut.a -lglu32 -lopengl32 -lgdi32 -lwinmm
+cp libfreeglut.a /lib
+cd ..
+cp -a include/GL/*.h /usr/include/w32api/GL/
+
+#OPTIONAL: To compile manually in src:
+#gcc -O2 -c -D_WIN32 -DHAVE_CONFIG_H -DFREEGLUT_EXPORTS *.c -I.. -I../include
+
diff --git a/graphics/asymptote/builtin.cc b/graphics/asymptote/builtin.cc
new file mode 100644
index 0000000000..ee0c323894
--- /dev/null
+++ b/graphics/asymptote/builtin.cc
@@ -0,0 +1,966 @@
+/*****
+ * builtin.cc
+ * Tom Prince 2004/08/25
+ *
+ * Initialize builtins.
+ *****/
+
+#include <cmath>
+
+#include "builtin.h"
+#include "entry.h"
+
+#include "runtime.h"
+#include "runpicture.h"
+#include "runlabel.h"
+#include "runhistory.h"
+#include "runarray.h"
+#include "runfile.h"
+#include "runsystem.h"
+#include "runstring.h"
+#include "runpair.h"
+#include "runtriple.h"
+#include "runpath.h"
+#include "runpath3d.h"
+#include "runmath.h"
+
+#include "types.h"
+
+#include "castop.h"
+#include "mathop.h"
+#include "arrayop.h"
+#include "vm.h"
+
+#include "coder.h"
+#include "exp.h"
+#include "refaccess.h"
+#include "settings.h"
+
+#include "opsymbols.h"
+
+#ifndef NOSYM
+#include "builtin.symbols.h"
+#endif
+
+namespace vm {
+ // Defined in stack.cc
+ extern vm::frame *make_dummyframe(string name);
+}
+
+using namespace types;
+using namespace camp;
+using namespace vm;
+
+namespace trans {
+using camp::transform;
+using camp::pair;
+using vm::bltin;
+using run::divide;
+using run::less;
+using run::greater;
+using run::plus;
+using run::minus;
+
+using namespace run;
+
+void gen_runtime_venv(venv &ve);
+void gen_runbacktrace_venv(venv &ve);
+void gen_runpicture_venv(venv &ve);
+void gen_runlabel_venv(venv &ve);
+void gen_runhistory_venv(venv &ve);
+void gen_runarray_venv(venv &ve);
+void gen_runfile_venv(venv &ve);
+void gen_runsystem_venv(venv &ve);
+void gen_runstring_venv(venv &ve);
+void gen_runpair_venv(venv &ve);
+void gen_runtriple_venv(venv &ve);
+void gen_runpath_venv(venv &ve);
+void gen_runpath3d_venv(venv &ve);
+void gen_runmath_venv(venv &ve);
+void gen_rungsl_venv(venv &ve);
+
+void addType(tenv &te, symbol name, ty *t)
+{
+ te.enter(name, new tyEntry(t,0,0,position()));
+}
+
+// The base environments for built-in types and functions
+void base_tenv(tenv &te)
+{
+#define PRIMITIVE(name,Name,asyName) \
+ addType(te, symbol::trans(#asyName), prim##Name());
+#include "primitives.h"
+#undef PRIMITIVE
+}
+
+const formal noformal(0);
+
+function *functionFromFormals(ty *result,
+ formal f1=noformal, formal f2=noformal, formal f3=noformal,
+ formal f4=noformal, formal f5=noformal, formal f6=noformal,
+ formal f7=noformal, formal f8=noformal, formal f9=noformal,
+ formal fA=noformal, formal fB=noformal, formal fC=noformal,
+ formal fD=noformal, formal fE=noformal, formal fF=noformal,
+ formal fG=noformal, formal fH=noformal, formal fI=noformal)
+{
+ function *fun = new function(result);
+
+ if (f1.t) fun->add(f1);
+ if (f2.t) fun->add(f2);
+ if (f3.t) fun->add(f3);
+ if (f4.t) fun->add(f4);
+ if (f5.t) fun->add(f5);
+ if (f6.t) fun->add(f6);
+ if (f7.t) fun->add(f7);
+ if (f8.t) fun->add(f8);
+ if (f9.t) fun->add(f9);
+ if (fA.t) fun->add(fA);
+ if (fB.t) fun->add(fB);
+ if (fC.t) fun->add(fC);
+ if (fD.t) fun->add(fD);
+ if (fE.t) fun->add(fE);
+ if (fF.t) fun->add(fF);
+ if (fG.t) fun->add(fG);
+ if (fH.t) fun->add(fH);
+ if (fI.t) fun->add(fI);
+
+ return fun;
+}
+
+void addFunc(venv &ve, access *a, ty *result, symbol id,
+ formal f1=noformal, formal f2=noformal, formal f3=noformal,
+ formal f4=noformal, formal f5=noformal, formal f6=noformal,
+ formal f7=noformal, formal f8=noformal, formal f9=noformal,
+ formal fA=noformal, formal fB=noformal, formal fC=noformal,
+ formal fD=noformal, formal fE=noformal, formal fF=noformal,
+ formal fG=noformal, formal fH=noformal, formal fI=noformal)
+{
+ function *fun = functionFromFormals(result,f1,f2,f3,f4,f5,f6,f7,f8,f9,
+ fA,fB,fC,fD,fE,fF,fG,fH,fI);
+
+ // NOTE: If the function is a field, we should encode the defining record in
+ // the entry
+ varEntry *ent = new varEntry(fun, a, 0, position());
+
+ ve.enter(id, ent);
+}
+
+// Add a function with one or more default arguments.
+void addFunc(venv &ve, bltin f, ty *result, symbol name,
+ formal f1, formal f2, formal f3, formal f4, formal f5, formal f6,
+ formal f7, formal f8, formal f9, formal fA, formal fB, formal fC,
+ formal fD, formal fE, formal fF, formal fG, formal fH, formal fI)
+{
+#ifdef DEBUG_BLTIN
+ // If the function is an operator, print out the whole signature with the
+ // types, as operators are heavily overloaded. min and max are also heavily
+ // overloaded, so we check for them too. Many builtin functions have so
+ // many arguments that it is noise to print out their full signatures.
+ string s = name;
+ if (s.find("operator ", 0) == 0 || s == "min" || s == "max")
+ {
+ function *fun = functionFromFormals(result,f1,f2,f3,f4,f5,f6,f7,f8,f9,
+ fA,fB,fC,fD,fE,fF,fG,fH,fI);
+ ostringstream out;
+ fun->printVar(out, name);
+ REGISTER_BLTIN(f, out.str());
+ }
+ else {
+ REGISTER_BLTIN(f, name);
+ }
+#endif
+
+ access *a = new bltinAccess(f);
+ addFunc(ve,a,result,name,f1,f2,f3,f4,f5,f6,f7,f8,f9,
+ fA,fB,fC,fD,fE,fF,fG,fH,fI);
+}
+
+void addOpenFunc(venv &ve, bltin f, ty *result, symbol name)
+{
+ function *fun = new function(result, signature::OPEN);
+
+ REGISTER_BLTIN(f, name);
+ access *a= new bltinAccess(f);
+
+ varEntry *ent = new varEntry(fun, a, 0, position());
+
+ ve.enter(name, ent);
+}
+
+
+// Add a rest function with zero or more default/explicit arguments.
+void addRestFunc(venv &ve, bltin f, ty *result, symbol name, formal frest,
+ formal f1=noformal, formal f2=noformal, formal f3=noformal,
+ formal f4=noformal, formal f5=noformal, formal f6=noformal,
+ formal f7=noformal, formal f8=noformal, formal f9=noformal)
+{
+ REGISTER_BLTIN(f, name);
+ access *a = new bltinAccess(f);
+ function *fun = new function(result);
+
+ if (f1.t) fun->add(f1);
+ if (f2.t) fun->add(f2);
+ if (f3.t) fun->add(f3);
+ if (f4.t) fun->add(f4);
+ if (f5.t) fun->add(f5);
+ if (f6.t) fun->add(f6);
+ if (f7.t) fun->add(f7);
+ if (f8.t) fun->add(f8);
+ if (f9.t) fun->add(f9);
+
+ if (frest.t) fun->addRest(frest);
+
+ varEntry *ent = new varEntry(fun, a, 0, position());
+
+ ve.enter(name, ent);
+}
+
+void addRealFunc0(venv &ve, bltin fcn, symbol name)
+{
+ addFunc(ve, fcn, primReal(), name);
+}
+
+template<double (*fcn)(double)>
+void addRealFunc(venv &ve, symbol name)
+{
+ addFunc(ve, realReal<fcn>, primReal(), name, formal(primReal(),SYM(x)));
+ addFunc(ve, arrayFunc<double,double,fcn>, realArray(), name,
+ formal(realArray(),SYM(a)));
+}
+
+#define addRealFunc(fcn, sym) addRealFunc<fcn>(ve, sym);
+
+void addRealFunc2(venv &ve, bltin fcn, symbol name)
+{
+ addFunc(ve,fcn,primReal(),name,formal(primReal(),SYM(a)),
+ formal(primReal(),SYM(b)));
+}
+
+template <double (*func)(double, int)>
+void realRealInt(vm::stack *s) {
+ Int n = pop<Int>(s);
+ double x = pop<double>(s);
+ s->push(func(x, intcast(n)));
+}
+
+template<double (*fcn)(double, int)>
+void addRealIntFunc(venv& ve, symbol name, symbol arg1,
+ symbol arg2) {
+ addFunc(ve, realRealInt<fcn>, primReal(), name, formal(primReal(), arg1),
+ formal(primInt(), arg2));
+}
+
+void addInitializer(venv &ve, ty *t, access *a)
+{
+ addFunc(ve, a, t, symbol::initsym);
+}
+
+void addInitializer(venv &ve, ty *t, bltin f)
+{
+#ifdef DEBUG_BLTIN
+ ostringstream s;
+ s << "initializer for " << *t;
+ REGISTER_BLTIN(f, s.str());
+#endif
+ access *a = new bltinAccess(f);
+ addInitializer(ve, t, a);
+}
+
+// Specifies that source may be cast to target, but only if an explicit
+// cast expression is used.
+void addExplicitCast(venv &ve, ty *target, ty *source, access *a) {
+ addFunc(ve, a, target, symbol::ecastsym, source);
+}
+
+// Specifies that source may be implicitly cast to target by the
+// function or instruction stores at a.
+void addCast(venv &ve, ty *target, ty *source, access *a) {
+ //addExplicitCast(target,source,a);
+ addFunc(ve, a, target, symbol::castsym, source);
+}
+
+void addExplicitCast(venv &ve, ty *target, ty *source, bltin f) {
+#ifdef DEBUG_BLTIN
+ ostringstream s;
+ s << "explicit cast from " << *source << " to " << *target;
+ REGISTER_BLTIN(f, s.str());
+#endif
+ addExplicitCast(ve, target, source, new bltinAccess(f));
+}
+
+void addCast(venv &ve, ty *target, ty *source, bltin f) {
+#ifdef DEBUG_BLTIN
+ ostringstream s;
+ s << "cast from " << *source << " to " << *target;
+ REGISTER_BLTIN(f, s.str());
+#endif
+ addCast(ve, target, source, new bltinAccess(f));
+}
+
+template<class T>
+void addVariable(venv &ve, T *ref, ty *t, symbol name,
+ record *module=settings::getSettingsModule()) {
+ access *a = new refAccess<T>(ref);
+ varEntry *ent = new varEntry(t, a, PUBLIC, module, 0, position());
+ ve.enter(name, ent);
+}
+
+template<class T>
+void addVariable(venv &ve, T value, ty *t, symbol name,
+ record *module=settings::getSettingsModule(),
+ permission perm=PUBLIC) {
+ item* ref=new item;
+ *ref=value;
+ access *a = new itemRefAccess(ref);
+ varEntry *ent = new varEntry(t, a, perm, module, 0, position());
+ ve.enter(name, ent);
+}
+
+template<class T>
+void addConstant(venv &ve, T value, ty *t, symbol name,
+ record *module=settings::getSettingsModule()) {
+ addVariable(ve,value,t,name,module,RESTRICTED);
+}
+
+// The identity access, i.e. no instructions are encoded for a cast or
+// operation, and no functions are called.
+identAccess id;
+
+function *IntRealFunction()
+{
+ return new function(primInt(),primReal());
+}
+
+function *realPairFunction()
+{
+ return new function(primReal(),primPair());
+}
+
+function *voidFileFunction()
+{
+ return new function(primVoid(),primFile());
+}
+
+void addInitializers(venv &ve)
+{
+ addInitializer(ve, primBoolean(), boolFalse);
+ addInitializer(ve, primInt(), IntZero);
+ addInitializer(ve, primReal(), realZero);
+
+ addInitializer(ve, primString(), emptyString);
+ addInitializer(ve, primPair(), pairZero);
+ addInitializer(ve, primTriple(), tripleZero);
+ addInitializer(ve, primTransform(), transformIdentity);
+ addInitializer(ve, primGuide(), nullGuide);
+ addInitializer(ve, primPath(), nullPath);
+ addInitializer(ve, primPath3(), nullPath3);
+ addInitializer(ve, primPen(), newPen);
+ addInitializer(ve, primPicture(), newPicture);
+ addInitializer(ve, primFile(), nullFile);
+}
+
+void addCasts(venv &ve)
+{
+ addExplicitCast(ve, primString(), primInt(), stringCast<Int>);
+ addExplicitCast(ve, primString(), primReal(), stringCast<double>);
+ addExplicitCast(ve, primString(), primPair(), stringCast<pair>);
+ addExplicitCast(ve, primString(), primTriple(), stringCast<triple>);
+ addExplicitCast(ve, primInt(), primString(), castString<Int>);
+ addExplicitCast(ve, primReal(), primString(), castString<double>);
+ addExplicitCast(ve, primPair(), primString(), castString<pair>);
+ addExplicitCast(ve, primTriple(), primString(), castString<triple>);
+
+ addExplicitCast(ve, primInt(), primReal(), castDoubleInt);
+
+ addCast(ve, primReal(), primInt(), cast<Int,double>);
+ addCast(ve, primPair(), primInt(), cast<Int,pair>);
+ addCast(ve, primPair(), primReal(), cast<double,pair>);
+
+ addCast(ve, primPath(), primPair(), cast<pair,path>);
+ addCast(ve, primGuide(), primPair(), pairToGuide);
+ addCast(ve, primGuide(), primPath(), pathToGuide);
+ addCast(ve, primPath(), primGuide(), guideToPath);
+
+ addCast(ve, primFile(), primNull(), nullFile);
+
+ // Vectorized casts.
+ addExplicitCast(ve, IntArray(), realArray(), arrayToArray<double,Int>);
+
+ addCast(ve, realArray(), IntArray(), arrayToArray<Int,double>);
+ addCast(ve, pairArray(), IntArray(), arrayToArray<Int,pair>);
+ addCast(ve, pairArray(), realArray(), arrayToArray<double,pair>);
+
+ addCast(ve, realArray2(), IntArray2(), array2ToArray2<Int,double>);
+ addCast(ve, pairArray2(), IntArray2(), array2ToArray2<Int,pair>);
+ addCast(ve, pairArray2(), realArray2(), array2ToArray2<double,pair>);
+}
+
+void addTupleOperators(venv &ve)
+{
+ addFunc(ve, realRealToPair, primPair(), SYM_TUPLE,
+ formal(primReal(), SYM(x)),
+ formal(primReal(), SYM(y)));
+ addFunc(ve, realRealRealToTriple, primTriple(), SYM_TUPLE,
+ formal(primReal(), SYM(x)),
+ formal(primReal(), SYM(y)),
+ formal(primReal(), SYM(z)));
+ addFunc(ve, real6ToTransform, primTransform(), SYM_TUPLE,
+ formal(primReal(), SYM(x)),
+ formal(primReal(), SYM(y)),
+ formal(primReal(), SYM(xx)),
+ formal(primReal(), SYM(xy)),
+ formal(primReal(), SYM(yx)),
+ formal(primReal(), SYM(yy)));
+}
+
+void addGuideOperators(venv &ve)
+{
+ // The guide operators .. and -- take an array of guides, and turn them
+ // into a single guide.
+ addRestFunc(ve, dotsGuide, primGuide(), SYM_DOTS, guideArray());
+ addRestFunc(ve, dashesGuide, primGuide(), SYM_DASHES, guideArray());
+}
+
+/* Avoid typing the same type three times. */
+void addSimpleOperator(venv &ve, bltin f, ty *t, symbol name)
+{
+ addFunc(ve,f,t,name,formal(t,SYM(a)),formal(t,SYM(b)));
+}
+void addBooleanOperator(venv &ve, bltin f, ty *t, symbol name)
+{
+ addFunc(ve,f,primBoolean(),name,formal(t,SYM(a)),formal(t,SYM(b)));
+}
+
+template<class T, template <class S> class op>
+void addArray2Array2Op(venv &ve, ty *t3, symbol name)
+{
+ addFunc(ve,array2Array2Op<T,op>,t3,name,formal(t3,SYM(a)),formal(t3,SYM(b)));
+}
+
+template<class T, template <class S> class op>
+void addOpArray2(venv &ve, ty *t1, symbol name, ty *t3)
+{
+ addFunc(ve,opArray2<T,T,op>,t3,name,formal(t1,SYM(a)),formal(t3,SYM(b)));
+}
+
+template<class T, template <class S> class op>
+void addArray2Op(venv &ve, ty *t1, symbol name, ty *t3)
+{
+ addFunc(ve,array2Op<T,T,op>,t3,name,formal(t3,SYM(a)),formal(t1,SYM(b)));
+}
+
+template<class T, template <class S> class op>
+void addOps(venv &ve, ty *t1, symbol name, ty *t2)
+{
+ addSimpleOperator(ve,binaryOp<T,op>,t1,name);
+ addFunc(ve,opArray<T,T,op>,t2,name,formal(t1,SYM(a)),formal(t2,SYM(b)));
+ addFunc(ve,arrayOp<T,T,op>,t2,name,formal(t2,SYM(a)),formal(t1,SYM(b)));
+ addSimpleOperator(ve,arrayArrayOp<T,op>,t2,name);
+}
+
+template<class T, template <class S> class op>
+void addBooleanOps(venv &ve, ty *t1, symbol name, ty *t2)
+{
+ addBooleanOperator(ve,binaryOp<T,op>,t1,name);
+ addFunc(ve,opArray<T,T,op>,
+ booleanArray(),name,formal(t1,SYM(a)),formal(t2,SYM(b)));
+ addFunc(ve,arrayOp<T,T,op>,
+ booleanArray(),name,formal(t2,SYM(a)),formal(t1,SYM(b)));
+ addFunc(ve,arrayArrayOp<T,op>,booleanArray(),name,formal(t2,SYM(a)),
+ formal(t2,SYM(b)));
+}
+
+void addWrite(venv &ve, bltin f, ty *t1, ty *t2)
+{
+ addRestFunc(ve,f,primVoid(),SYM(write),t2,
+ formal(primFile(),SYM(file),true),
+ formal(primString(),SYM(s),true),
+ formal(t1,SYM(x)),formal(voidFileFunction(),SYM(suffix),true));
+}
+
+template<class T>
+void addUnorderedOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4)
+{
+ addBooleanOps<T,equals>(ve,t1,SYM_EQ,t2);
+ addBooleanOps<T,notequals>(ve,t1,SYM_NEQ,t2);
+
+ addFunc(ve, run::array2Equals<T>, primBoolean(), SYM_EQ, formal(t3, SYM(a)),
+ formal(t3, SYM(b)));
+ addFunc(ve, run::array2NotEquals<T>, primBoolean(),
+ SYM_NEQ, formal(t3, SYM(a)),
+ formal(t3, SYM(b)));
+
+ addCast(ve,t1,primFile(),read<T>);
+ addCast(ve,t2,primFile(),readArray1<T>);
+ addCast(ve,t3,primFile(),readArray2<T>);
+ addCast(ve,t4,primFile(),readArray3<T>);
+
+ addWrite(ve,write<T>,t1,t2);
+ addRestFunc(ve,writeArray<T>,primVoid(),SYM(write),t3,
+ formal(primFile(),SYM(file),true),
+ formal(primString(),SYM(s),true),
+ formal(t2,SYM(a),false,true));
+ addFunc(ve,writeArray2<T>,primVoid(),SYM(write),
+ formal(primFile(),SYM(file),true),t3);
+ addFunc(ve,writeArray3<T>,primVoid(),SYM(write),
+ formal(primFile(),SYM(file),true),t4);
+}
+
+inline double abs(pair z) {
+ return z.length();
+}
+
+inline double abs(triple v) {
+ return v.length();
+}
+
+inline pair conjugate(pair z) {
+ return conj(z);
+}
+
+template<class T>
+inline T negate(T x) {
+ return -x;
+}
+
+template<class T, template <class S> class op>
+void addBinOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, symbol name)
+{
+ addFunc(ve,binopArray<T,op>,t1,name,formal(t2,SYM(a)));
+ addFunc(ve,binopArray2<T,op>,t1,name,formal(t3,SYM(a)));
+ addFunc(ve,binopArray3<T,op>,t1,name,formal(t4,SYM(a)));
+}
+
+template<class T>
+void addOrderedOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4)
+{
+ addBooleanOps<T,less>(ve,t1,SYM_LT,t2);
+ addBooleanOps<T,lessequals>(ve,t1,SYM_LE,t2);
+ addBooleanOps<T,greaterequals>(ve,t1,SYM_GE,t2);
+ addBooleanOps<T,greater>(ve,t1,SYM_GT,t2);
+
+ addOps<T,run::min>(ve,t1,SYM(min),t2);
+ addOps<T,run::max>(ve,t1,SYM(max),t2);
+ addBinOps<T,run::min>(ve,t1,t2,t3,t4,SYM(min));
+ addBinOps<T,run::max>(ve,t1,t2,t3,t4,SYM(max));
+
+ addFunc(ve,sortArray<T>,t2,SYM(sort),formal(t2,SYM(a)));
+ addFunc(ve,sortArray2<T>,t3,SYM(sort),formal(t3,SYM(a)));
+
+ addFunc(ve,searchArray<T>,primInt(),SYM(search),formal(t2,SYM(a)),
+ formal(t1,SYM(key)));
+}
+
+template<class T>
+void addBasicOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, bool integer=false,
+ bool Explicit=false)
+{
+ addOps<T,plus>(ve,t1,SYM_PLUS,t2);
+ addOps<T,minus>(ve,t1,SYM_MINUS,t2);
+ addFunc(ve,initialized,primBoolean(),SYM(initialized),formal(t1,SYM(a)));
+
+ addArray2Array2Op<T,plus>(ve,t3,SYM_PLUS);
+ addArray2Array2Op<T,minus>(ve,t3,SYM_MINUS);
+
+ addFunc(ve,&id,t1,SYM_PLUS,formal(t1,SYM(a)));
+ addFunc(ve,&id,t2,SYM_PLUS,formal(t2,SYM(a)));
+ addFunc(ve,Negate<T>,t1,SYM_MINUS,formal(t1,SYM(a)));
+ addFunc(ve,arrayFunc<T,T,negate>,t2,SYM_MINUS,formal(t2,SYM(a)));
+ addFunc(ve,arrayFunc2<T,T,negate>,t3,SYM_MINUS,formal(t3,SYM(a)));
+ if(!integer) addFunc(ve,interp<T>,t1,SYM(interp),
+ formal(t1,SYM(a),false,Explicit),
+ formal(t1,SYM(b),false,Explicit),
+ formal(primReal(),SYM(t)));
+
+ addFunc(ve,sumArray<T>,t1,SYM(sum),formal(t2,SYM(a)));
+ addUnorderedOps<T>(ve,t1,t2,t3,t4);
+}
+
+template<class T>
+void addOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, bool integer=false,
+ bool Explicit=false)
+{
+ addBasicOps<T>(ve,t1,t2,t3,t4,integer,Explicit);
+
+ addOps<T,times>(ve,t1,SYM_TIMES,t2);
+ addOpArray2<T,times>(ve,t1,SYM_TIMES,t3);
+ addArray2Op<T,times>(ve,t1,SYM_TIMES,t3);
+
+ if(!integer) {
+ addOps<T,run::divide>(ve,t1,SYM_DIVIDE,t2);
+ addArray2Op<T,run::divide>(ve,t1,SYM_DIVIDE,t3);
+ }
+
+ addOps<T,power>(ve,t1,SYM_CARET,t2);
+}
+
+
+// Adds standard functions for a newly added array type.
+void addArrayOps(venv &ve, types::array *t)
+{
+ ty *ct = t->celltype;
+
+ // Check for the alias function to see if these operation have already been
+ // added, if they have, don't add them again.
+ static types::function aliasType(primBoolean(), primVoid(), primVoid());
+ aliasType.sig.formals[0].t = t;
+ aliasType.sig.formals[1].t = t;
+
+ if (ve.lookByType(SYM(alias), &aliasType))
+ return;
+
+ addFunc(ve, run::arrayAlias,
+ primBoolean(), SYM(alias), formal(t, SYM(a)), formal(t, SYM(b)));
+
+ size_t depth=(size_t) t->depth();
+
+ // Define an array constructor. This needs to know the depth of the array,
+ // which may not be known at runtime. Therefore, the depth, which is known
+ // here at compile-time, is pushed on the stack beforehand by use of a
+ // thunk.
+ callable *copyValueFunc = new thunk(new vm::bfunc(run::copyArrayValue),(Int) depth-1);
+ addFunc(ve, new callableAccess(copyValueFunc),
+ t, SYM(array), formal(primInt(), SYM(n)),
+ formal(ct, SYM(value)),
+ formal(primInt(), SYM(depth), true));
+
+ callable *copyFunc = new thunk(new vm::bfunc(run::copyArray),(Int) depth);
+ addFunc(ve, new callableAccess(copyFunc),
+ t, SYM(copy), formal(t, SYM(a)), formal(primInt(), SYM(depth), true));
+
+ addFunc(ve, run::arrayFunction,
+ t, SYM(map), formal(new function(ct, ct), SYM(f)), formal(t, SYM(a)));
+
+ addFunc(ve, run::arraySequence,
+ t, SYM(sequence), formal(new function(ct, primInt()), SYM(f)),
+ formal(primInt(), SYM(n)));
+
+ addFunc(ve, run::arraySort,
+ t, SYM(sort), formal(t, SYM(a)),
+ formal(new function(primBoolean(), ct, ct), SYM(less)),
+ formal(primBoolean(), SYM(stable), true));
+
+ switch (depth) {
+ case 1:
+ addRestFunc(ve, run::arrayConcat, t, SYM(concat), new types::array(t));
+ addFunc(ve, run::arraySearch,
+ primInt(), SYM(search), formal(t, SYM(a)), formal(ct, SYM(key)),
+ formal(new function(primBoolean(), ct, ct), SYM(less)));
+ break;
+ case 2:
+ addFunc(ve, run::array2Transpose, t, SYM(transpose), formal(t, SYM(a)));
+ break;
+ case 3:
+ addFunc(ve, run::array3Transpose, t, SYM(transpose), formal(t, SYM(a)),
+ formal(IntArray(),SYM(perm)));
+ break;
+ default:
+ break;
+ }
+}
+
+void addRecordOps(venv &ve, record *r)
+{
+ addFunc(ve, run::boolMemEq, primBoolean(), SYM(alias), formal(r, SYM(a)),
+ formal(r, SYM(b)));
+ addFunc(ve, run::boolMemEq, primBoolean(), SYM_EQ, formal(r, SYM(a)),
+ formal(r, SYM(b)));
+ addFunc(ve, run::boolMemNeq, primBoolean(), SYM_NEQ, formal(r, SYM(a)),
+ formal(r, SYM(b)));
+}
+
+void addFunctionOps(venv &ve, function *f)
+{
+ // No function ops.
+}
+
+
+void addOperators(venv &ve)
+{
+ addSimpleOperator(ve,binaryOp<string,plus>,primString(),SYM_PLUS);
+
+ addBooleanOps<bool,And>(ve,primBoolean(),SYM_AMPERSAND,booleanArray());
+ addBooleanOps<bool,Or>(ve,primBoolean(),SYM_BAR,booleanArray());
+ addBooleanOps<bool,Xor>(ve,primBoolean(),SYM_CARET,booleanArray());
+
+ addUnorderedOps<bool>(ve,primBoolean(),booleanArray(),booleanArray2(),
+ booleanArray3());
+ addOps<Int>(ve,primInt(),IntArray(),IntArray2(),IntArray3(),true);
+ addOps<double>(ve,primReal(),realArray(),realArray2(),realArray3());
+ addOps<pair>(ve,primPair(),pairArray(),pairArray2(),pairArray3(),false,true);
+ addBasicOps<triple>(ve,primTriple(),tripleArray(),tripleArray2(),
+ tripleArray3());
+ addFunc(ve,opArray<double,triple,times>,tripleArray(),SYM_TIMES,
+ formal(primReal(),SYM(a)),formal(tripleArray(),SYM(b)));
+ addFunc(ve,opArray2<double,triple,timesR>,tripleArray2(),SYM_TIMES,
+ formal(primReal(),SYM(a)),formal(tripleArray2(),SYM(b)));
+ addFunc(ve,arrayOp<triple,double,timesR>,tripleArray(),SYM_TIMES,
+ formal(tripleArray(),SYM(a)),formal(primReal(),SYM(b)));
+ addFunc(ve,array2Op<triple,double,timesR>,tripleArray2(),SYM_TIMES,
+ formal(tripleArray2(),SYM(a)),formal(primReal(),SYM(b)));
+ addFunc(ve,arrayOp<triple,double,divide>,tripleArray(),SYM_DIVIDE,
+ formal(tripleArray(),SYM(a)),formal(primReal(),SYM(b)));
+
+ addUnorderedOps<string>(ve,primString(),stringArray(),stringArray2(),
+ stringArray3());
+
+ addSimpleOperator(ve,binaryOp<pair,minbound>,primPair(),SYM(minbound));
+ addSimpleOperator(ve,binaryOp<pair,maxbound>,primPair(),SYM(maxbound));
+ addSimpleOperator(ve,binaryOp<triple,minbound>,primTriple(),SYM(minbound));
+ addSimpleOperator(ve,binaryOp<triple,maxbound>,primTriple(),SYM(maxbound));
+ addBinOps<pair,minbound>(ve,primPair(),pairArray(),pairArray2(),pairArray3(),
+ SYM(minbound));
+ addBinOps<pair,maxbound>(ve,primPair(),pairArray(),pairArray2(),pairArray3(),
+ SYM(maxbound));
+ addBinOps<triple,minbound>(ve,primTriple(),tripleArray(),tripleArray2(),
+ tripleArray3(),SYM(minbound));
+ addBinOps<triple,maxbound>(ve,primTriple(),tripleArray(),tripleArray2(),
+ tripleArray3(),SYM(maxbound));
+
+ addFunc(ve,arrayFunc<double,pair,abs>,realArray(),SYM(abs),
+ formal(pairArray(),SYM(a)));
+ addFunc(ve,arrayFunc<double,triple,abs>,realArray(),SYM(abs),
+ formal(tripleArray(),SYM(a)));
+
+ addFunc(ve,arrayFunc<pair,pair,conjugate>,pairArray(),SYM(conj),
+ formal(pairArray(),SYM(a)));
+ addFunc(ve,arrayFunc2<pair,pair,conjugate>,pairArray2(),SYM(conj),
+ formal(pairArray2(),SYM(a)));
+
+ addFunc(ve,binaryOp<Int,divide>,primReal(),SYM_DIVIDE,
+ formal(primInt(),SYM(a)),formal(primInt(),SYM(b)));
+ addFunc(ve,arrayOp<Int,Int,divide>,realArray(),SYM_DIVIDE,
+ formal(IntArray(),SYM(a)),formal(primInt(),SYM(b)));
+ addFunc(ve,opArray<Int,Int,divide>,realArray(),SYM_DIVIDE,
+ formal(primInt(),SYM(a)),formal(IntArray(),SYM(b)));
+ addFunc(ve,arrayArrayOp<Int,divide>,realArray(),SYM_DIVIDE,
+ formal(IntArray(),SYM(a)),formal(IntArray(),SYM(b)));
+
+ addOrderedOps<Int>(ve,primInt(),IntArray(),IntArray2(),IntArray3());
+ addOrderedOps<double>(ve,primReal(),realArray(),realArray2(),realArray3());
+ addOrderedOps<string>(ve,primString(),stringArray(),stringArray2(),
+ stringArray3());
+
+ addOps<Int,mod>(ve,primInt(),SYM_MOD,IntArray());
+ addOps<Int,quotient>(ve,primInt(),SYM_QUOTIENT,IntArray());
+ addOps<double,mod>(ve,primReal(),SYM_MOD,realArray());
+
+ addRestFunc(ve,diagonal<Int>,IntArray2(),SYM(diagonal),IntArray());
+ addRestFunc(ve,diagonal<double>,realArray2(),SYM(diagonal),realArray());
+ addRestFunc(ve,diagonal<pair>,pairArray2(),SYM(diagonal),pairArray());
+}
+
+dummyRecord *createDummyRecord(venv &ve, symbol name)
+{
+ dummyRecord *r=new dummyRecord(name);
+ vm::frame *f = make_dummyframe(name);
+ addConstant(ve, f, r, name);
+ addRecordOps(ve, r);
+ return r;
+}
+
+double identity(double x) {return x;}
+double pow10(double x) {return run::pow(10.0,x);}
+
+// An example of an open function.
+#ifdef OPENFUNCEXAMPLE
+void openFunc(stack *Stack)
+{
+ vm::array *a=vm::pop<vm::array *>(Stack);
+ size_t numArgs=checkArray(a);
+ for (size_t k=0; k<numArgs; ++k)
+ cout << k << ": " << (*a)[k];
+
+ Stack->push<Int>((Int)numArgs);
+}
+#endif
+
+// A function accessible in asy code print the bytecode of a function.
+void printBytecode(stack *Stack)
+{
+ // As arbitrary addresses can be sent to printBytecode, it should not be run
+ // in safe mode.
+ if (settings::safe) {
+ cerr << "use -nosafe flag to enable printBytecode" << endl;
+ return;
+ }
+
+ vm::array *a=vm::pop<vm::array *>(Stack);
+ size_t numArgs=checkArray(a);
+ if (numArgs != 1)
+ cerr << "printBytecode takes one argument" << endl;
+
+ // TODO: Add a reliable test for the object being a func.
+ callable *c = a->read<callable *>(0);
+ if (func *f = dynamic_cast<func *>(c))
+ print(cout, f->body->code);
+ else
+ cout << "callable is not a standard function";
+}
+
+
+
+
+// NOTE: We should move all of these into a "builtin" module.
+void base_venv(venv &ve)
+{
+ // Register the name of arrayDeleteHelper for debugging in "asy -s" mode.
+ // This is done automatically for other function, but because
+ // arrayDeleteHelper is not defined in the usual way, it must be done
+ // explicitly, and here is as good a place as any.
+ REGISTER_BLTIN(arrayDeleteHelper, "arrayDeleteHelper");
+
+ addInitializers(ve);
+ addCasts(ve);
+ addOperators(ve);
+ addTupleOperators(ve);
+ addGuideOperators(ve);
+
+ addRealFunc(sin,SYM(sin));
+ addRealFunc(cos,SYM(cos));
+ addRealFunc(tan,SYM(tan));
+ addRealFunc(asin,SYM(asin));
+ addRealFunc(acos,SYM(acos));
+ addRealFunc(atan,SYM(atan));
+ addRealFunc(exp,SYM(exp));
+ addRealFunc(log,SYM(log));
+ addRealFunc(log10,SYM(log10));
+ addRealFunc(sinh,SYM(sinh));
+ addRealFunc(cosh,SYM(cosh));
+ addRealFunc(tanh,SYM(tanh));
+ addRealFunc(asinh,SYM(asinh));
+ addRealFunc(acosh,SYM(acosh));
+ addRealFunc(atanh,SYM(atanh));
+ addRealFunc(sqrt,SYM(sqrt));
+ addRealFunc(cbrt,SYM(cbrt));
+ addRealFunc(fabs,SYM(fabs));
+ addRealFunc<fabs>(ve,SYM(abs));
+ addRealFunc(expm1,SYM(expm1));
+ addRealFunc(log1p,SYM(log1p));
+ addRealIntFunc<ldexp>(ve, SYM(ldexp), SYM(x), SYM(e));
+
+ addRealFunc(pow10,SYM(pow10));
+ addRealFunc(identity,SYM(identity));
+
+#ifdef STRUCTEXAMPLE
+ dummyRecord *fun=createDummyRecord(ve, SYM(test));
+ addFunc(fun->e.ve,realReal<sin>,primReal(),SYM(f),formal(primReal(),SYM(x)));
+ addVariable<Int>(fun->e.ve,1,primInt(),SYM(x));
+#endif
+
+ addFunc(ve,writestring,primVoid(),SYM(write),
+ formal(primFile(),SYM(file),true),
+ formal(primString(),SYM(s)),
+ formal(voidFileFunction(),SYM(suffix),true));
+
+ addWrite(ve,write<transform>,primTransform(),transformArray());
+ addWrite(ve,write<guide *>,primGuide(),guideArray());
+ addWrite(ve,write<pen>,primPen(),penArray());
+ addFunc(ve,arrayArrayOp<pen,equals>,booleanArray(),SYM_EQ,
+ formal(penArray(),SYM(a)),formal(penArray(),SYM(b)));
+ addFunc(ve,arrayArrayOp<pen,notequals>,booleanArray(),SYM_NEQ,
+ formal(penArray(),SYM(a)),formal(penArray(),SYM(b)));
+
+ addFunc(ve,arrayFunction,realArray(),SYM(map),
+ formal(realPairFunction(),SYM(f)),
+ formal(pairArray(),SYM(a)));
+ addFunc(ve,arrayFunction,IntArray(),SYM(map),
+ formal(IntRealFunction(),SYM(f)),
+ formal(realArray(),SYM(a)));
+
+ addConstant<Int>(ve, Int_MAX, primInt(), SYM(intMax));
+ addConstant<Int>(ve, Int_MIN, primInt(), SYM(intMin));
+ addConstant<double>(ve, HUGE_VAL, primReal(), SYM(inf));
+ addConstant<double>(ve, run::infinity, primReal(), SYM(infinity));
+ addConstant<double>(ve, nan(""), primReal(), SYM(nan));
+ addConstant<double>(ve, DBL_MAX, primReal(), SYM(realMax));
+ addConstant<double>(ve, DBL_MIN, primReal(), SYM(realMin));
+ addConstant<double>(ve, DBL_EPSILON, primReal(), SYM(realEpsilon));
+ addConstant<Int>(ve, DBL_DIG, primInt(), SYM(realDigits));
+ addConstant<Int>(ve, RANDOM_MAX, primInt(), SYM(randMax));
+ addConstant<double>(ve, PI, primReal(), SYM(pi));
+ addConstant<string>(ve, string(REVISION),primString(),SYM(VERSION));
+
+ addVariable<pen>(ve, &processData().currentpen, primPen(), SYM(currentpen));
+
+#ifdef OPENFUNCEXAMPLE
+ addOpenFunc(ve, openFunc, primInt(), SYM(openFunc));
+#endif
+
+ addOpenFunc(ve, printBytecode, primVoid(), SYM(printBytecode));
+
+ gen_runtime_venv(ve);
+ gen_runbacktrace_venv(ve);
+ gen_runpicture_venv(ve);
+ gen_runlabel_venv(ve);
+ gen_runhistory_venv(ve);
+ gen_runarray_venv(ve);
+ gen_runfile_venv(ve);
+ gen_runsystem_venv(ve);
+ gen_runstring_venv(ve);
+ gen_runpair_venv(ve);
+ gen_runtriple_venv(ve);
+ gen_runpath_venv(ve);
+ gen_runpath3d_venv(ve);
+ gen_runmath_venv(ve);
+
+#ifdef HAVE_LIBGSL
+ gen_rungsl_venv(ve);
+#endif
+}
+
+} //namespace trans
+
+namespace run {
+
+double infinity=cbrt(DBL_MAX); // Reduced for tension atleast infinity
+
+void arrayDeleteHelper(stack *Stack)
+{
+ array *a=pop<array *>(Stack);
+ item itj=pop(Stack);
+ bool jdefault=isdefault(itj);
+ item iti=pop(Stack);
+ Int i,j;
+ if(isdefault(iti)) {
+ if(jdefault) {
+ (*a).clear();
+ return;
+ } else i=j=get<Int>(itj);
+ } else {
+ i=get<Int>(iti);
+ j=jdefault ? i : get<Int>(itj);
+ }
+
+ size_t asize=checkArray(a);
+ if(a->cyclic() && asize > 0) {
+ if(j-i+1 >= (Int) asize) {
+ (*a).clear();
+ return;
+ }
+ i=imod(i,asize);
+ j=imod(j,asize);
+ if(j >= i)
+ (*a).erase((*a).begin()+i,(*a).begin()+j+1);
+ else {
+ (*a).erase((*a).begin()+i,(*a).end());
+ (*a).erase((*a).begin(),(*a).begin()+j+1);
+ }
+ return;
+ }
+
+ if(i < 0 || i >= (Int) asize || i > j || j >= (Int) asize) {
+ ostringstream buf;
+ buf << "delete called on array of length " << (Int) asize
+ << " with out-of-bounds index range [" << i << "," << j << "]";
+ error(buf);
+ }
+
+ (*a).erase((*a).begin()+i,(*a).begin()+j+1);
+}
+
+// Used by coder to optimize conditional jumps.
+const bltin intLess = binaryOp<Int,less>;
+const bltin intGreater = binaryOp<Int,greater>;
+
+}
diff --git a/graphics/asymptote/builtin.h b/graphics/asymptote/builtin.h
new file mode 100644
index 0000000000..f29a97ccd4
--- /dev/null
+++ b/graphics/asymptote/builtin.h
@@ -0,0 +1,60 @@
+/*****
+ * builtin.h
+ * Tom Prince 2004/08/25
+ *
+ * Initialize builtins.
+ *****/
+#ifndef BUILTIN_H
+#define BUILTIN_H
+
+#include "vm.h"
+#include "types.h"
+#include "arrayop.h"
+
+namespace trans {
+
+class tenv;
+class venv;
+
+// The base environments for built-in types and functions
+void base_tenv(tenv &);
+void base_venv(venv &);
+
+extern const types::formal noformal;
+
+// Add a function with one or more default arguments.
+void addFunc(venv &ve, vm::bltin f, types::ty *result, symbol name,
+ types::formal f1=noformal, types::formal f2=noformal,
+ types::formal f3=noformal, types::formal f4=noformal,
+ types::formal f5=noformal, types::formal f6=noformal,
+ types::formal f7=noformal, types::formal f8=noformal,
+ types::formal f9=noformal, types::formal fA=noformal,
+ types::formal fB=noformal, types::formal fC=noformal,
+ types::formal fD=noformal, types::formal fE=noformal,
+ types::formal fF=noformal, types::formal fG=noformal,
+ types::formal fH=noformal, types::formal fI=noformal);
+
+// Adds standard functions for a newly added types.
+void addArrayOps(venv &ve, types::array *t);
+void addRecordOps(venv &ve, types::record *r);
+void addFunctionOps(venv &ve, types::function *f);
+
+#ifdef HAVE_LIBGSL
+types::record *getGSLModule();
+void GSLrngFree();
+#endif
+
+} //namespace trans
+
+namespace run {
+extern double infinity;
+
+void single(vm::stack *Stack);
+void arrayDeleteHelper(vm::stack *Stack);
+
+// Used by to optimize conditional jumps.
+extern const vm::bltin intLess;
+extern const vm::bltin intGreater;
+}
+
+#endif //BUILTIN_H
diff --git a/graphics/asymptote/callable.cc b/graphics/asymptote/callable.cc
new file mode 100644
index 0000000000..581c3af2c1
--- /dev/null
+++ b/graphics/asymptote/callable.cc
@@ -0,0 +1,75 @@
+/*****
+ * callable.cc
+ * Tom Prince 2005/06/19
+ *
+ * Runtime representation of functions.
+ *****/
+
+#include "stack.h"
+#include "callable.h"
+
+namespace vm {
+
+callable::~callable()
+{}
+
+void func::call(stack *s)
+{
+ s->run(this);
+}
+
+void nullfunc::print(ostream& out) {
+ out << "nullfunc";
+}
+
+bool func::compare(callable* F)
+{
+ if (func* f=dynamic_cast<func*>(F))
+ return (body == f->body) && (closure == f->closure);
+ else return false;
+}
+
+void func::print(ostream& out) {
+ out << "func with lambda";
+#ifdef DEBUG_FRAME
+ out << " " << body->name;
+#endif
+}
+
+bool bfunc::compare(callable* F)
+{
+ if (bfunc* f=dynamic_cast<bfunc*>(F))
+ return (func == f->func);
+ else return false;
+}
+
+void bfunc::print(ostream& out) {
+ out << "bltin";
+#ifdef DEBUG_BLTIN
+ out << " " << lookupBltin(func);
+#endif
+}
+
+void thunk::call(stack *s)
+{
+ s->push(arg);
+ func->call(s);
+}
+
+void thunk::print(ostream& out) {
+ out << "thunk on " << arg << " with ";
+ func->print(out);
+}
+
+nullfunc nullfunc::func;
+void nullfunc::call(stack *)
+{
+ error("dereference of null function");
+}
+
+bool nullfunc::compare(callable* f)
+{
+ return f == &func;
+}
+
+} // namespace vm
diff --git a/graphics/asymptote/callable.h b/graphics/asymptote/callable.h
new file mode 100644
index 0000000000..851ccb4623
--- /dev/null
+++ b/graphics/asymptote/callable.h
@@ -0,0 +1,91 @@
+/*****
+ * callable.h
+ * Tom Prince 2005/06/19
+ *
+ * Runtime representation of functions.
+ *****/
+
+#ifndef CALLABLE_H
+#define CALLABLE_H
+
+#include "common.h"
+#include "item.h"
+#include "inst.h"
+
+namespace vm {
+
+class stack;
+typedef void (*bltin)(stack *s);
+
+struct callable : public gc
+{
+ virtual void call(stack *) = 0;
+ virtual ~callable();
+ virtual bool compare(callable*) { return false; }
+
+ // For debugging:
+ virtual void print(ostream& out) = 0;
+};
+
+class nullfunc : public callable
+{
+private:
+ nullfunc() {}
+ static nullfunc func;
+public:
+ virtual void call (stack*);
+ virtual bool compare(callable*);
+ static callable* instance() { return &func; }
+
+ void print(ostream& out);
+};
+
+// How a function reference to a non-builtin function is stored.
+struct func : public callable {
+ lambda *body;
+ frame *closure;
+ func () : body(), closure() {}
+ virtual void call (stack*);
+ virtual bool compare(callable*);
+
+ void print(ostream& out);
+};
+
+class bfunc : public callable
+{
+public:
+ bfunc(bltin b) : func(b) {}
+ virtual void call (stack *s) { func(s); }
+ virtual bool compare(callable*);
+
+ void print(ostream& out);
+private:
+ bltin func;
+};
+
+class thunk : public callable
+{
+public:
+ thunk(callable *f, item i) : func(f), arg(i) {}
+ virtual void call (stack*);
+
+ void print(ostream& out);
+private:
+ callable *func;
+ item arg;
+};
+
+inline ostream& operator<< (ostream& out, callable &c) {
+ c.print(out);
+ return out;
+}
+
+} // namespace vm
+
+GC_DECLARE_PTRFREE(vm::nullfunc);
+
+// I believe this is safe, as pointers to C++ functions do not point to
+// the heap.
+GC_DECLARE_PTRFREE(vm::bfunc);
+
+#endif // CALLABLE_H
diff --git a/graphics/asymptote/camp.l b/graphics/asymptote/camp.l
new file mode 100644
index 0000000000..041939ffa5
--- /dev/null
+++ b/graphics/asymptote/camp.l
@@ -0,0 +1,444 @@
+%{
+/*****
+ * camp.l
+ * Andy Hammerlindl 2002/06/14
+ *
+ * The lexical analyzer of the Asymptote language.
+ *****/
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cstring>
+
+#include "util.h"
+#include "modifier.h"
+#include "exp.h"
+#include "stm.h"
+#include "fundec.h"
+#include "errormsg.h"
+#include "interact.h"
+#include "lexical.h"
+
+using namespace absyntax;
+using mem::string;
+
+#include "camp.tab.h"
+
+#include "opsymbols.h"
+
+#define YY_NO_INPUT
+
+static void yyunput(int, char *);
+void (*unused)(int,char *) = yyunput;
+
+fileinfo* fi;
+Int tokPos;
+Int charPos;
+//int commentDepth = 0;
+
+bool eof;
+string eofMessage;
+
+extern errorstream em;
+
+extern "C" int yywrap(void)
+{
+ charPos=1;
+ return 1;
+}
+
+typedef size_t (*input_f) (char* bif, size_t max_size);
+
+input_f yy_input = NULL;
+
+void setlexer(input_f input, string filename)
+{
+ YY_FLUSH_BUFFER;
+ yywrap();
+ fi = new fileinfo(filename);
+ yy_input = input;
+ tokPos = charPos = 1;
+
+ eof=false;
+ eofMessage="<no eof>";
+}
+
+#define YY_INPUT(buf,result,max_size) {result=yy_input(buf,max_size);}
+
+position lexerPos()
+{
+ position p;
+ p.init(fi, tokPos);
+ return p;
+}
+
+namespace {
+position here()
+
+{
+ return lexerPos();
+}
+
+void adjust()
+{
+ tokPos = charPos;
+ charPos += yyleng;
+ yylval.pos = here();
+}
+
+void savesymbol(symbol name)
+{
+ adjust();
+ yylval.ps.pos=yylval.pos; // avoid invoking here() twice
+ yylval.ps.sym=name;
+}
+
+/* For optimization reasons, the operator names are translated into symbols
+ * just once, and can be accessed throughout the code as SYM_PLUS, SYM_DASHES,
+ * etc. Following the Don't Repeat Yourself principle, the mapping from
+ * strings to names is defined only here in camp.l (because we can't produce
+ * lex rules from a C style macro).
+ * The script opsymbols.pl reads this file scanning for rules using DEFSYMBOL
+ * and creates opsymbols.h which defines the names for use in C++ code.
+ */
+#define DEFSYMBOL(name) \
+ savesymbol(name)
+
+ /* Extra symbols can be added by EXTRASYMBOL */
+#define EXTRASYMBOL(chars, codename) /* blank */
+
+EXTRASYMBOL(tuple, SYM_TUPLE);
+
+void makesymbol()
+{
+ assert(strlen(yytext) == (size_t)yyleng);
+ savesymbol(symbol::rawTrans(yytext, yyleng+1));
+}
+
+void makeopsymbol()
+{
+ savesymbol(symbol::opTrans(yytext));
+}
+
+void makemod(trans::modifier mod) {
+ yylval.mod.pos=here();
+ yylval.mod.val=mod;
+}
+
+void makeperm(trans::permission perm) {
+ yylval.perm.pos=here();
+ yylval.perm.val=perm;
+}
+
+void newline()
+{
+ fi->newline();
+ charPos = tokPos = 1;
+}
+
+void error(void)
+{
+ em.error(here());
+}
+
+}
+
+
+// Used by the lexer rules to flag an unexpected end of input. The message is
+// the error message that should be reported, and may differ if, say the input
+// ends in the middle of a string or comment.
+void setEOF(string message) {
+ eof=true;
+ eofMessage=message;
+}
+
+// Called by code outside of the lexer to see if a parse error was caused by
+// running out of input.
+bool lexerEOF()
+{
+ return eof;
+}
+
+// Called by code outside of the lexer when it wants to report the unexpected
+// eof as an error (instead of looking for more input).
+void reportEOF() {
+ assert(eof);
+ error();
+ em << eofMessage;
+ em.sync();
+}
+
+position stringpos; // The position of the start of the string.
+string stringbuild; // Stores the string literal as it is read.
+
+namespace {
+void startstring()
+{
+ adjust();
+ stringpos = here();
+}
+
+void append(char c)
+{
+ stringbuild.push_back(c);
+ yylval.pos = here();
+}
+
+void getstring(void)
+{
+ // NOTE: Replace here() with a position at the start of the string.
+ yylval.stre = new stringExp(stringpos, stringbuild);
+ string().swap(stringbuild);
+}
+}
+
+%}
+
+%x lexcomment
+%x texstring
+%x cstring
+%x lexformat
+%x opname
+
+LETTER [_A-Za-z]
+ESC \\
+ENDL \\?(\r\n|\n|\r)
+EXTRAOPS <<|>>|$|$$|@|@@|~|<>
+
+%%
+
+<lexcomment>{
+\/\* {adjust(); /*commentDepth++;*/}
+\*\/ {adjust(); /*commentDepth--;*/
+ /*if (commentDepth == 0)*/ BEGIN INITIAL; }
+\r\n|\n|\r {adjust(); newline(); continue; }
+<<EOF>> {adjust();
+ setEOF("comment not terminated");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+. {adjust(); continue; }
+}
+
+<texstring>{
+\"/([ \t]|{ENDL})*[\"\'] {adjust(); BEGIN INITIAL;}
+\" {adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+<<EOF>> {adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+{ENDL} {adjust(); newline(); append('\n'); continue; }
+{ESC}{ESC} {adjust(); append('\\'); append('\\'); continue; }
+{ESC}\" {adjust(); append('\"'); continue; }
+. {adjust(); append(*yytext); }
+}
+
+<cstring>{
+\'/([ \t]|{ENDL})*[\"\'] {adjust(); BEGIN INITIAL;}
+\' {adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+<<EOF>> {adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+{ENDL} {adjust(); newline(); append('\n'); continue; }
+{ESC}(\'|\"|\?|\\) {adjust(); append(yytext[1]); continue; }
+{ESC}a {adjust(); append('\a'); continue; }
+{ESC}b {adjust(); append('\b'); continue; }
+{ESC}f {adjust(); append('\f'); continue; }
+{ESC}n {adjust(); append('\n'); continue; }
+{ESC}r {adjust(); append('\r'); continue; }
+{ESC}t {adjust(); append('\t'); continue; }
+{ESC}v {adjust(); append('\v'); continue; }
+{ESC}[0-7] {adjust();
+ char x=(char)(yytext[1]-'0');
+ append(x);
+ continue;
+ }
+{ESC}[0-7][0-7] {adjust();
+ char x=(char)((yytext[1]-'0')*8+yytext[2]-'0');
+ append(x);
+ continue;
+ }
+{ESC}[0-3][0-7][0-7] {adjust();
+ char x=(char)((yytext[1]-'0')*64+(yytext[2]-'0')*8
+ +yytext[3]-'0');
+ append(x);
+ continue;
+ }
+{ESC}x[0-9,A-F] {adjust();
+ char x=(char) (yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A');
+ append(x);
+ continue;
+ }
+{ESC}x[0-9,A-F][0-9,A-F] {adjust();
+ char x=(char) ((yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A')*16
+ +(yytext[3] <= '9' ? yytext[3]-'0' :
+ 10+yytext[3]-'A'));
+ append(x);
+ continue;
+ }
+. {adjust(); append(*yytext); }
+}
+
+[ \t] {adjust(); continue;}
+{ENDL} {adjust(); newline(); continue;}
+\/\/[^\n]* {adjust(); continue;}
+"," {adjust(); return ','; }
+":" {adjust(); return ':'; }
+";" {adjust(); return ';'; }
+"(" {adjust(); return '('; }
+")" {adjust(); return ')'; }
+"[" {adjust(); return '['; }
+"]" {adjust(); return ']'; }
+"{" {adjust(); return '{'; }
+"}" {adjust(); return '}'; }
+"." {adjust(); return '.'; }
+"..." {adjust(); return ELLIPSIS; }
+
+"+" {DEFSYMBOL(SYM_PLUS); return '+'; }
+"-" {DEFSYMBOL(SYM_MINUS); return '-'; }
+"*" {DEFSYMBOL(SYM_TIMES); return '*'; }
+"/" {DEFSYMBOL(SYM_DIVIDE); return '/'; }
+"#" {DEFSYMBOL(SYM_QUOTIENT); return '#'; }
+"%" {DEFSYMBOL(SYM_MOD); return '%'; }
+"^" {DEFSYMBOL(SYM_CARET); return '^'; }
+"**" {savesymbol(SYM_CARET); return '^'; }
+"?" {adjust(); return '?'; }
+"=" {adjust(); return ASSIGN; }
+"==" {DEFSYMBOL(SYM_EQ); return EQ; }
+"!=" {DEFSYMBOL(SYM_NEQ); return NEQ; }
+"<" {DEFSYMBOL(SYM_LT); return LT; }
+"<=" {DEFSYMBOL(SYM_LE); return LE; }
+">" {DEFSYMBOL(SYM_GT); return GT; }
+">=" {DEFSYMBOL(SYM_GE); return GE; }
+"&&" {DEFSYMBOL(SYM_CAND); return CAND; }
+"||" {DEFSYMBOL(SYM_COR); return COR; }
+"!" {DEFSYMBOL(SYM_LOGNOT); return OPERATOR; }
+"^^" {DEFSYMBOL(SYM_CARETS); return CARETS; }
+"::" {DEFSYMBOL(SYM_COLONS); return COLONS; }
+"++" {DEFSYMBOL(SYM_INCR); return INCR; }
+".." {DEFSYMBOL(SYM_DOTS); return DOTS; }
+"--" {DEFSYMBOL(SYM_DASHES); return DASHES; }
+"---" {DEFSYMBOL(SYM_LONGDASH); return LONGDASH; }
+"&" {DEFSYMBOL(SYM_AMPERSAND); return AMPERSAND; }
+"|" {DEFSYMBOL(SYM_BAR); return BAR; }
+{EXTRAOPS} {makeopsymbol(); return OPERATOR; }
+
+"+=" {savesymbol(SYM_PLUS); return SELFOP; }
+"-=" {savesymbol(SYM_MINUS); return SELFOP; }
+"*=" {savesymbol(SYM_TIMES); return SELFOP; }
+"/=" {savesymbol(SYM_DIVIDE); return SELFOP; }
+"#=" {savesymbol(SYM_QUOTIENT); return SELFOP; }
+"%=" {savesymbol(SYM_MOD); return SELFOP; }
+"^=" {savesymbol(SYM_CARET); return SELFOP; }
+
+and {adjust(); return AND; }
+controls {DEFSYMBOL(SYM_CONTROLS); return CONTROLS; }
+tension {DEFSYMBOL(SYM_TENSION); return TENSION; }
+atleast {DEFSYMBOL(SYM_ATLEAST); return ATLEAST; }
+curl {DEFSYMBOL(SYM_CURL); return CURL; }
+
+if {adjust(); return IF; }
+else {adjust(); return ELSE; }
+while {adjust(); return WHILE; }
+for {adjust(); return FOR; }
+do {adjust(); return DO; }
+return {adjust(); return RETURN_; }
+break {adjust(); return BREAK; }
+continue {adjust(); return CONTINUE; }
+struct {adjust(); return STRUCT; }
+typedef {adjust(); return TYPEDEF; }
+new {adjust(); return NEW; }
+access {adjust(); return ACCESS; }
+import {adjust(); return IMPORT; }
+unravel {adjust(); return UNRAVEL; }
+from {adjust(); return FROM; }
+include {adjust(); return INCLUDE; }
+quote {adjust(); return QUOTE; }
+static {adjust(); makemod(trans::EXPLICIT_STATIC);
+ return MODIFIER; }
+public {adjust(); makeperm(trans::PUBLIC); return PERM; }
+private {adjust(); makeperm(trans::PRIVATE); return PERM; }
+restricted {adjust(); makeperm(trans::RESTRICTED); return PERM; }
+this {adjust(); return THIS; }
+explicit {adjust(); return EXPLICIT; }
+
+
+[0-9]+ try {
+ adjust(); yylval.e= new intExp(here(), lexical::cast<Int>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid integer";
+ yylval.e= new intExp(here(), 0);
+ } return LIT;
+([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)|([0-9]*\.*[0-9]+e[-+]*[0-9]+)|([0-9]+\.[0-9]*e[-+]*[0-9]+) try {
+ adjust(); yylval.e= new realExp(here(), lexical::cast<double>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid real";
+ yylval.e= new realExp(here(), 0);
+ } return LIT;
+true {
+ adjust(); yylval.e= new booleanExp(here(), true); return LIT; }
+false {
+ adjust(); yylval.e= new booleanExp(here(), false); return LIT; }
+null {
+ adjust(); yylval.e= new nullExp(here()); return LIT; }
+cycle {
+ adjust(); yylval.e= new cycleExp(here()); return LIT; }
+newframe {
+ adjust(); yylval.e= new newPictureExp(here()); return LIT; }
+
+operator {adjust(); BEGIN opname; }
+<opname>{
+[ \t\r] {adjust(); continue;}
+{ENDL} {adjust(); newline(); continue;}
+<<EOF>> {adjust();
+ setEOF("missing operator name");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+"**" { savesymbol(SYM_CARET);
+ BEGIN INITIAL;
+ return ID;
+ }
+[-+*/#%^!<>]|==|!=|<=|>=|&|\||\^\^|\.\.|::|--|---|\+\+|{EXTRAOPS} {
+ makeopsymbol();
+ BEGIN INITIAL;
+ return ID;}
+{LETTER}({LETTER}|[0-9])* {
+ makeopsymbol();
+ BEGIN INITIAL;
+ return ID; }
+. {}
+}
+
+{LETTER}({LETTER}|[0-9])* {
+ makesymbol();
+ return ID; }
+
+\/\* {adjust(); /*commentDepth = 1;*/ BEGIN lexcomment; }
+\" {startstring(); BEGIN texstring; }
+\' {startstring(); BEGIN cstring; }
+
+<<EOF>> { setEOF("unexpected end of input"); yyterminate(); }
+
+. {adjust();
+ error();
+ em << "invalid token";
+ if (isgraph(yytext[0]))
+ em << " '" << yytext[0] << "'";
+ }
diff --git a/graphics/asymptote/camp.tab.cc b/graphics/asymptote/camp.tab.cc
new file mode 100644
index 0000000000..2ced391e89
--- /dev/null
+++ b/graphics/asymptote/camp.tab.cc
@@ -0,0 +1,3404 @@
+/* A Bison parser, made by GNU Bison 3.0.5. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.0.5"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 1 "camp.y" /* yacc.c:339 */
+
+/*****
+ * camp.y
+ * Andy Hammerlindl 08/12/2002
+ *
+ * The grammar of the camp language.
+ *****/
+
+#include "errormsg.h"
+#include "exp.h"
+#include "newexp.h"
+#include "dec.h"
+#include "fundec.h"
+#include "stm.h"
+#include "modifier.h"
+#include "opsymbols.h"
+
+// Avoid error messages with unpatched bison-1.875:
+#ifndef __attribute__
+#define __attribute__(x)
+#endif
+
+// Used when a position needs to be determined and no token is
+// available. Defined in camp.l.
+position lexerPos();
+
+bool lexerEOF();
+
+int yylex(void); /* function prototype */
+
+void yyerror(const char *s)
+{
+ if (!lexerEOF()) {
+ em.error(lexerPos());
+ em << s;
+ em.cont();
+ }
+}
+
+// Check if the symbol given is "keyword". Returns true in this case and
+// returns false and reports an error otherwise.
+bool checkKeyword(position pos, symbol sym)
+{
+ if (sym != symbol::trans("keyword")) {
+ em.error(pos);
+ em << "expected 'keyword' here";
+
+ return false;
+ }
+ return true;
+}
+
+namespace absyntax { file *root; }
+
+using namespace absyntax;
+using sym::symbol;
+using mem::string;
+
+#line 125 "camp.tab.c" /* yacc.c:339 */
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "camp.tab.h". */
+#ifndef YY_YY_CAMP_TAB_H_INCLUDED
+# define YY_YY_CAMP_TAB_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ ID = 258,
+ SELFOP = 259,
+ DOTS = 260,
+ COLONS = 261,
+ DASHES = 262,
+ INCR = 263,
+ LONGDASH = 264,
+ CONTROLS = 265,
+ TENSION = 266,
+ ATLEAST = 267,
+ CURL = 268,
+ COR = 269,
+ CAND = 270,
+ BAR = 271,
+ AMPERSAND = 272,
+ EQ = 273,
+ NEQ = 274,
+ LT = 275,
+ LE = 276,
+ GT = 277,
+ GE = 278,
+ CARETS = 279,
+ OPERATOR = 280,
+ LOOSE = 281,
+ ASSIGN = 282,
+ DIRTAG = 283,
+ JOIN_PREC = 284,
+ AND = 285,
+ ELLIPSIS = 286,
+ ACCESS = 287,
+ UNRAVEL = 288,
+ IMPORT = 289,
+ INCLUDE = 290,
+ FROM = 291,
+ QUOTE = 292,
+ STRUCT = 293,
+ TYPEDEF = 294,
+ NEW = 295,
+ IF = 296,
+ ELSE = 297,
+ WHILE = 298,
+ DO = 299,
+ FOR = 300,
+ BREAK = 301,
+ CONTINUE = 302,
+ RETURN_ = 303,
+ THIS = 304,
+ EXPLICIT = 305,
+ GARBAGE = 306,
+ LIT = 307,
+ STRING = 308,
+ PERM = 309,
+ MODIFIER = 310,
+ UNARY = 311,
+ EXP_IN_PARENS_RULE = 312
+ };
+#endif
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+union YYSTYPE
+{
+#line 60 "camp.y" /* yacc.c:355 */
+
+ position pos;
+ bool boo;
+ struct {
+ position pos;
+ sym::symbol sym;
+ } ps;
+ absyntax::name *n;
+ absyntax::varinit *vi;
+ absyntax::arrayinit *ai;
+ absyntax::exp *e;
+ absyntax::stringExp *stre;
+ absyntax::specExp *se;
+ absyntax::joinExp *j;
+ absyntax::explist *elist;
+ absyntax::argument arg;
+ absyntax::arglist *alist;
+ absyntax::slice *slice;
+ absyntax::dimensions *dim;
+ absyntax::ty *t;
+ absyntax::decid *di;
+ absyntax::decidlist *dil;
+ absyntax::decidstart *dis;
+ absyntax::runnable *run;
+ struct {
+ position pos;
+ trans::permission val;
+ } perm;
+ struct {
+ position pos;
+ trans::modifier val;
+ } mod;
+ absyntax::modifierList *ml;
+ //absyntax::program *prog;
+ absyntax::vardec *vd;
+ //absyntax::vardecs *vds;
+ absyntax::dec *d;
+ absyntax::idpair *ip;
+ absyntax::idpairlist *ipl;
+ absyntax::stm *s;
+ absyntax::block *b;
+ absyntax::stmExpList *sel;
+ //absyntax::funheader *fh;
+ absyntax::formal *fl;
+ absyntax::formals *fls;
+
+#line 270 "camp.tab.c" /* yacc.c:355 */
+};
+
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+int yyparse (void);
+
+#endif /* !YY_YY_CAMP_TAB_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 287 "camp.tab.c" /* yacc.c:358 */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 3
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 1979
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 76
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 50
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 200
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 376
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 312
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 30, 2, 29, 2, 2,
+ 42, 43, 27, 25, 45, 26, 44, 28, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 36, 48,
+ 2, 2, 2, 35, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 46, 2, 47, 31, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 40, 2, 41, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 32, 33, 34, 37, 38, 39, 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
+};
+
+#if YYDEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 191, 191, 195, 196, 201, 202, 207, 208, 209,
+ 214, 215, 216, 218, 223, 224, 225, 227, 232, 233,
+ 234, 235, 237, 239, 241, 242, 244, 246, 248, 249,
+ 254, 256, 260, 261, 266, 267, 272, 274, 278, 279,
+ 284, 288, 292, 293, 297, 301, 302, 306, 307, 312,
+ 313, 318, 319, 324, 325, 326, 328, 333, 334, 338,
+ 343, 344, 346, 348, 353, 354, 355, 359, 361, 366,
+ 367, 368, 370, 375, 376, 380, 382, 384, 387, 390,
+ 396, 398, 403, 404, 408, 409, 410, 411, 415, 416,
+ 418, 419, 421, 422, 425, 429, 430, 432, 434, 436,
+ 440, 441, 445, 446, 448, 450, 456, 457, 461, 462,
+ 463, 464, 466, 467, 469, 471, 473, 475, 476, 477,
+ 478, 479, 480, 481, 482, 483, 484, 485, 486, 487,
+ 488, 489, 490, 491, 492, 493, 494, 495, 496, 498,
+ 500, 502, 504, 506, 508, 513, 515, 520, 522, 523,
+ 524, 526, 532, 534, 537, 539, 540, 547, 548, 550,
+ 553, 556, 562, 563, 564, 567, 573, 574, 576, 578,
+ 579, 583, 585, 588, 591, 597, 598, 603, 604, 605,
+ 606, 608, 610, 612, 614, 616, 618, 619, 620, 621,
+ 625, 629, 633, 634, 635, 639, 640, 644, 645, 649,
+ 650
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 0
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "ID", "SELFOP", "DOTS", "COLONS",
+ "DASHES", "INCR", "LONGDASH", "CONTROLS", "TENSION", "ATLEAST", "CURL",
+ "COR", "CAND", "BAR", "AMPERSAND", "EQ", "NEQ", "LT", "LE", "GT", "GE",
+ "CARETS", "'+'", "'-'", "'*'", "'/'", "'%'", "'#'", "'^'", "OPERATOR",
+ "LOOSE", "ASSIGN", "'?'", "':'", "DIRTAG", "JOIN_PREC", "AND", "'{'",
+ "'}'", "'('", "')'", "'.'", "','", "'['", "']'", "';'", "ELLIPSIS",
+ "ACCESS", "UNRAVEL", "IMPORT", "INCLUDE", "FROM", "QUOTE", "STRUCT",
+ "TYPEDEF", "NEW", "IF", "ELSE", "WHILE", "DO", "FOR", "BREAK",
+ "CONTINUE", "RETURN_", "THIS", "EXPLICIT", "GARBAGE", "LIT", "STRING",
+ "PERM", "MODIFIER", "UNARY", "EXP_IN_PARENS_RULE", "$accept", "file",
+ "fileblock", "bareblock", "name", "runnable", "modifiers", "dec",
+ "idpair", "idpairlist", "strid", "stridpair", "stridpairlist", "vardec",
+ "barevardec", "type", "celltype", "dims", "dimexps", "decidlist",
+ "decid", "decidstart", "varinit", "block", "arrayinit", "basearrayinit",
+ "varinits", "formals", "explicitornot", "formal", "fundec", "typedec",
+ "slice", "value", "argument", "arglist", "tuple", "exp", "join", "dir",
+ "basicjoin", "tension", "controls", "stm", "stmexp", "blockstm",
+ "forinit", "fortest", "forupdate", "stmexplist", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 43, 45, 42, 47, 37,
+ 35, 94, 280, 281, 282, 63, 58, 283, 284, 285,
+ 123, 125, 40, 41, 46, 44, 91, 93, 59, 286,
+ 287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+ 297, 298, 299, 300, 301, 302, 303, 304, 305, 306,
+ 307, 308, 309, 310, 311, 312
+};
+# endif
+
+#define YYPACT_NINF -285
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-285)))
+
+#define YYTABLE_NINF -45
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] =
+{
+ -285, 41, 472, -285, -285, 873, 873, 873, 873, -285,
+ 873, -285, 873, -285, 14, 20, 14, 16, 8, 23,
+ 31, 20, 20, 26, 49, 614, 56, 86, 91, 687,
+ -285, 141, -285, -285, -285, 18, -285, 543, -285, -285,
+ 100, 53, -285, -285, -285, -285, 122, 1545, -285, 125,
+ -285, 224, 148, 148, 148, 148, 1931, 330, 203, 60,
+ 1146, 190, -285, 194, -285, 88, 0, 155, 161, 166,
+ 168, -1, 169, -285, 180, 34, -285, 236, 207, 15,
+ 873, 873, 193, 873, -285, -285, -285, 961, 148, 235,
+ 254, 616, 212, -285, -285, -285, -285, -285, 35, 217,
+ -285, 229, 685, 262, 741, 873, 79, -285, -285, 141,
+ -285, 873, 873, 873, 873, 873, 873, 873, 873, 873,
+ 873, 873, 873, 873, 873, 873, 873, 873, 873, 873,
+ 873, 873, 761, 873, -285, 231, -285, 741, -285, -285,
+ 141, 114, -285, 873, -285, 873, 270, 14, -285, -285,
+ -285, -285, -285, 24, 39, 401, -285, 227, 134, -14,
+ 797, 105, 234, 1272, 1312, 233, -285, 278, -285, 243,
+ 237, -285, 249, -285, 893, -285, 107, 1545, -285, 873,
+ -285, 245, 998, 247, -10, 212, 236, 817, -285, 118,
+ -285, 248, 1035, 1545, 873, 853, 291, 292, 197, 1763,
+ 1791, 1819, 1847, 1875, 1875, 1903, 1903, 1903, 1903, 1939,
+ 258, 258, 148, 148, 148, 148, 148, 1931, 1545, 1508,
+ 873, 1188, 197, 231, -285, -285, 873, 1545, 1545, -285,
+ -285, 295, 252, -285, 136, 253, 162, -285, -3, 180,
+ 239, -285, 149, 20, -285, 1072, 146, 94, -285, 797,
+ 212, 614, 614, 873, 46, 873, 873, 873, -285, -285,
+ 893, 893, 1545, -285, 873, -285, -285, 180, 157, -285,
+ -285, -285, 1545, -285, -285, -285, 1580, 873, 1617, -285,
+ -285, 873, 1432, -285, 873, -285, -285, 300, -285, 301,
+ -285, -285, -285, -285, 186, -285, -285, 180, 239, 239,
+ 305, -285, -285, -285, 817, -285, 4, 265, 180, 191,
+ 1109, 251, -285, 1352, 873, 1545, 264, -285, 1545, -285,
+ -285, 1545, -285, 180, 873, 1654, 873, 1727, -285, 1230,
+ -285, -285, -285, -285, -285, -285, 27, 279, 273, -285,
+ 817, 817, -285, 180, -285, 614, 267, 1392, 873, -285,
+ 1691, 873, 1691, -285, 873, 282, 817, -285, 276, -285,
+ -285, -285, -285, 614, 275, 237, 1691, 1470, 817, -285,
+ -285, -285, 614, -285, -285, -285
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 3, 0, 2, 1, 7, 0, 0, 0, 0, 9,
+ 0, 5, 0, 177, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 99, 110, 111, 15, 14, 108, 4, 0, 10, 18,
+ 0, 0, 42, 191, 19, 20, 109, 190, 11, 0,
+ 178, 108, 153, 152, 115, 116, 117, 0, 108, 0,
+ 0, 36, 35, 0, 38, 0, 0, 0, 0, 0,
+ 7, 0, 0, 3, 0, 44, 83, 0, 44, 138,
+ 0, 0, 0, 192, 186, 187, 188, 0, 112, 0,
+ 0, 0, 43, 17, 16, 12, 13, 40, 53, 41,
+ 49, 51, 0, 0, 0, 0, 166, 169, 157, 154,
+ 170, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 151, 158, 179, 0, 59, 6,
+ 98, 0, 149, 0, 97, 0, 0, 0, 21, 24,
+ 27, 28, 29, 0, 0, 0, 82, 0, 53, 74,
+ 0, 141, 139, 0, 0, 0, 194, 0, 199, 0,
+ 193, 189, 7, 93, 0, 102, 0, 100, 8, 84,
+ 45, 0, 0, 0, 74, 54, 0, 0, 95, 0,
+ 88, 0, 0, 155, 0, 0, 0, 0, 137, 132,
+ 131, 135, 134, 129, 130, 125, 126, 127, 128, 133,
+ 118, 119, 120, 121, 122, 123, 124, 136, 148, 0,
+ 0, 0, 150, 159, 160, 113, 0, 107, 106, 37,
+ 39, 30, 0, 32, 0, 0, 0, 156, 74, 0,
+ 74, 73, 0, 0, 69, 0, 0, 74, 142, 0,
+ 140, 0, 0, 0, 53, 195, 0, 0, 103, 94,
+ 0, 0, 86, 91, 85, 89, 46, 55, 0, 50,
+ 52, 58, 57, 96, 92, 90, 175, 0, 171, 167,
+ 168, 0, 0, 163, 0, 161, 114, 0, 23, 0,
+ 22, 26, 25, 55, 0, 143, 70, 0, 74, 74,
+ 75, 47, 60, 64, 0, 67, 0, 65, 0, 0,
+ 0, 180, 182, 0, 0, 196, 0, 200, 101, 104,
+ 105, 87, 80, 56, 0, 173, 0, 147, 162, 0,
+ 31, 33, 56, 145, 71, 72, 53, 76, 0, 62,
+ 0, 66, 144, 0, 48, 0, 0, 0, 197, 81,
+ 176, 0, 172, 164, 0, 78, 0, 61, 0, 68,
+ 146, 181, 183, 0, 0, 198, 174, 0, 0, 77,
+ 63, 185, 0, 165, 79, 184
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -285, -285, 250, -285, 10, 263, -285, 285, 36, 170,
+ 309, -6, -285, 307, 246, -13, 308, -20, -285, -285,
+ 145, -284, -210, 260, 171, -285, -285, -164, -285, -227,
+ -285, -285, 238, -285, -165, 241, -285, -5, -285, -121,
+ 205, -285, -285, -19, -79, -138, -285, -285, -285, -8
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 1, 2, 57, 51, 36, 37, 38, 233, 234,
+ 63, 64, 65, 39, 40, 41, 42, 185, 162, 99,
+ 100, 101, 270, 43, 271, 306, 307, 242, 243, 244,
+ 44, 45, 181, 46, 175, 176, 59, 47, 133, 134,
+ 135, 196, 197, 48, 49, 50, 169, 316, 364, 170
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int16 yytable[] =
+{
+ 52, 53, 54, 55, 168, 56, 82, 60, 77, 258,
+ 67, 70, 35, 296, 224, 92, 337, 61, 96, 68,
+ 268, -44, 58, 4, 87, 66, 88, 231, 71, 239,
+ 158, 75, 78, 267, 74, 240, 305, 9, 141, 240,
+ 293, 3, 231, 90, 90, 339, 240, 35, 149, 9,
+ 153, 232, 355, 340, 241, 92, 98, 159, 241, 161,
+ 89, 160, 90, 73, 91, 241, 235, 35, 80, 238,
+ 167, 334, 335, 157, 294, 163, 164, 184, 90, 62,
+ 157, 157, 314, 309, 177, 62, 182, 69, 238, 194,
+ 195, 81, 157, 35, 338, 319, 320, 177, 83, 192,
+ 193, 295, 285, 142, 198, 143, 199, 200, 201, 202,
+ 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
+ 213, 214, 215, 216, 217, 218, 219, 221, 222, 322,
+ 358, 359, 182, 147, 84, 225, 148, 308, 227, 85,
+ 228, 230, 250, 240, 4, 246, 369, 247, 97, 4,
+ 259, 183, 260, 5, 6, 245, 261, 226, 374, 333,
+ 183, 273, 241, 260, 102, 35, 103, 261, 104, 177,
+ 342, 7, 8, 136, 262, 9, 238, 317, 10, 128,
+ 157, 289, 272, 12, 290, 349, 246, 302, 12, 276,
+ 278, 303, 297, -34, 298, 304, 19, 146, 299, 22,
+ 323, 19, 298, 150, 22, 360, 299, 289, 30, 151,
+ 292, 31, 32, 30, 152, 282, 31, 32, -34, 154,
+ 11, 286, 122, 123, 124, 125, 126, 127, 128, 332,
+ 300, 298, 311, 312, 343, 299, 298, 132, 172, 158,
+ 299, 272, 5, 6, 310, 89, 140, 90, 313, 91,
+ 315, 90, 318, 75, 165, 177, 177, 178, 183, 321,
+ 7, 8, 186, 187, 9, 190, 89, 10, 90, 168,
+ 137, 132, 325, 229, 180, 253, 327, 12, 173, 329,
+ 249, 254, 256, 257, 174, 124, 125, 126, 127, 128,
+ 19, 255, 263, 22, 266, 274, 279, 280, 287, 272,
+ 288, 291, 30, 330, 231, 31, 32, 241, 336, 347,
+ 341, 345, 348, 356, 357, 362, 368, 370, 372, 350,
+ 139, 352, 95, 155, 236, 331, 361, 72, 76, 166,
+ 79, 269, 248, 4, 156, 272, 272, 5, 6, 223,
+ 365, 0, 191, 189, 371, 0, 366, 0, 0, 367,
+ 0, 272, 0, 375, 0, 7, 8, 0, 0, 9,
+ 0, 0, 10, 272, 0, 0, 0, 0, 0, 0,
+ 11, 138, 12, 0, 0, 0, 0, 0, 13, 0,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 0, 24, 25, 26, 27, 28, 29, 30, 0, 0,
+ 31, 32, 33, 34, 4, 0, 0, 0, 5, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 8, 0, 0,
+ 9, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0, 11, 237, 12, 0, 0, 0, 0, 0, 13,
+ 0, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 0, 24, 25, 26, 27, 28, 29, 30, 0,
+ 0, 31, 32, 33, 34, 4, 0, 0, 0, 5,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 8, 0,
+ 0, 9, 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0, 11, 0, 12, 0, 0, 0, 0, 0,
+ 13, 0, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 0, 24, 25, 26, 27, 28, 29, 30,
+ 0, 0, 31, 32, 33, 34, 4, 0, 0, 0,
+ 5, 6, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 7, 8,
+ 0, 0, 9, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 11, 0, 12, 0, 0, 0, 0,
+ 0, 13, 0, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 0, 24, 25, 26, 27, 28, 29,
+ 30, 0, 0, 31, 32, 93, 94, 4, 0, 4,
+ 0, 5, 6, 5, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 8, 7, 8, 9, 0, 9, 10, 0, 10, 0,
+ 0, 0, 179, 0, 11, 0, 12, 0, 12, 0,
+ 0, 0, 13, 180, 0, 0, 0, 0, 0, 19,
+ 0, 19, 22, 23, 22, 24, 25, 26, 27, 28,
+ 29, 30, 0, 30, 31, 32, 31, 32, 172, 0,
+ 4, 0, 5, 6, 5, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 8, 7, 8, 9, 0, 9, 10, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 12, 188, 12,
+ 0, 0, 0, 0, 174, 86, 0, 0, 0, 0,
+ 19, 0, 19, 22, 4, 22, 0, 0, 5, 6,
+ 0, 0, 30, 0, 30, 31, 32, 31, 32, 0,
+ 0, 0, 0, 0, 4, 0, 7, 8, 5, 6,
+ 9, 0, 0, 10, 220, 0, 0, 179, 0, 0,
+ 0, 0, 0, 12, 0, 0, 7, 8, 0, 0,
+ 9, 0, 0, 10, 0, 0, 19, 0, 0, 22,
+ 4, 0, 0, 12, 5, 6, 0, 0, 30, 0,
+ 0, 31, 32, 0, 0, 0, 19, 0, 0, 22,
+ 4, 0, 7, 8, 5, 6, 9, 0, 30, 10,
+ 0, 31, 32, 0, 0, 0, 0, 0, 0, 12,
+ 0, 0, 7, 8, 180, 0, 9, 0, 0, 10,
+ 0, 0, 19, 0, 0, 22, 4, 246, 0, 12,
+ 5, 6, 0, 0, 30, 277, 0, 31, 32, 0,
+ 0, 0, 19, 0, 0, 22, 4, 0, 7, 8,
+ 5, 6, 9, 0, 30, 10, 0, 31, 32, 0,
+ 0, 0, 0, 0, 0, 12, 172, 0, 7, 8,
+ 5, 6, 9, 0, 0, 10, 0, 0, 19, 0,
+ 0, 22, 0, 0, 0, 12, 0, 0, 7, 8,
+ 30, 0, 9, 31, 32, 10, 0, 0, 19, 0,
+ 0, 22, 0, 0, 0, 12, 0, 0, 0, 0,
+ 30, 0, 0, 31, 32, 0, 0, 0, 19, 0,
+ 0, 22, 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 0, 0, 31, 32, 105, 106, 107, 108, 109,
+ 110, 0, 0, 0, 0, 111, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 0, 130, 131, 0, 0, 0,
+ 0, 132, 105, 106, 107, 108, 109, 110, 0, 171,
+ 0, 0, 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 0, 130, 131, 264, 0, 0, 0, 132, 105,
+ 106, 107, 108, 109, 110, 265, 0, 0, 0, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 0, 130,
+ 131, 264, 0, 0, 0, 132, 105, 106, 107, 108,
+ 109, 110, 275, 0, 0, 0, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 0, 130, 131, 0, 0,
+ 0, 0, 132, 105, 106, 107, 108, 109, 110, 301,
+ 0, 0, 0, 111, 112, 113, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 0, 130, 131, 0, 0, 0, 0, 132,
+ 105, 106, 107, 108, 109, 110, 344, 0, 0, 0,
+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 0,
+ 130, 131, 0, 0, 0, 0, 132, 0, 0, 144,
+ 0, 145, 105, 106, 107, 108, 109, 110, 0, 0,
+ 0, 0, 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 0, 130, 131, 0, 0, 0, 0, 132, 283,
+ 0, 0, 0, 284, 105, 106, 107, 108, 109, 110,
+ 0, 0, 0, 0, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 0, 130, 131, 0, 0, 0, 0,
+ 132, 353, 0, 0, 0, 354, 105, 106, 107, 108,
+ 109, 110, 0, 0, 0, 0, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 0, 130, 131, 0, 0,
+ 0, 0, 132, 0, 0, 251, 105, 106, 107, 108,
+ 109, 110, 0, 0, 0, 0, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 0, 130, 131, 0, 0,
+ 0, 0, 132, 0, 0, 252, 105, 106, 107, 108,
+ 109, 110, 0, 0, 0, 0, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 0, 130, 131, 0, 0,
+ 0, 0, 132, 0, 0, 346, 105, 106, 107, 108,
+ 109, 110, 0, 0, 0, 0, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 0, 130, 131, 0, 0,
+ 0, 0, 132, 0, 0, 363, 105, 106, 107, 108,
+ 109, 110, 0, 0, 0, 0, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 0, 130, 131, 0, 0,
+ 0, 0, 132, 328, 105, 106, 107, 108, 109, 110,
+ 0, 0, 0, 0, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 0, 130, 131, 0, 0, 0, 0,
+ 132, 373, 105, 106, 107, 108, 109, 110, 0, 0,
+ 0, 0, 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 0, 130, 131, 281, 0, 0, 0, 132, 105,
+ 106, 107, 108, 109, 110, 0, 0, 0, 0, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 0, 130,
+ 131, 0, 0, 0, 105, 132, 107, 108, 109, 110,
+ 0, 0, 0, 0, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 0, 130, 131, 0, 0, 0, 324,
+ 132, 105, 0, 107, 108, 109, 110, 0, 0, 0,
+ 0, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 0, 130, 131, 0, 0, 0, 326, 132, 105, 0,
+ 107, 108, 109, 110, 0, 0, 0, 0, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+ 123, 124, 125, 126, 127, 128, 129, 0, 130, 131,
+ 0, 0, 0, 351, 132, 105, 0, 107, 108, 109,
+ 110, 0, 0, 0, 0, 111, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 0, 130, 131, 0, 0, 0,
+ 0, 132, 106, 107, 108, 109, 110, 0, 0, 0,
+ 0, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 0, 0, 131, 0, 0, 0, 0, 132, 106, 107,
+ 108, 109, 110, 0, 0, 0, 0, 0, 112, 113,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 106, 107, 108, 109,
+ 110, 0, 0, 132, 0, 0, 0, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 106, 107, 108, 109, 110, 0,
+ 0, 132, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 106, 107, 108, 109, 110, 0, 0, 132,
+ 0, 0, 0, 0, 0, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 106, 107, 108, 109, 110, 0, 0, 132, 0, 0,
+ 0, 0, 0, 0, 0, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 106, 107,
+ 108, 109, 110, 0, 0, 132, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 106, 107, 108, 109,
+ 110, 0, 0, 132, 106, 107, 108, 109, 110, 0,
+ 0, 0, 0, 0, 0, 121, 122, 123, 124, 125,
+ 126, 127, 128, 0, 122, 123, 124, 125, 126, 127,
+ 128, 132, 0, 0, 0, 0, 0, 0, 0, 132
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 5, 6, 7, 8, 83, 10, 25, 12, 21, 174,
+ 16, 3, 2, 240, 135, 35, 300, 3, 37, 3,
+ 184, 3, 12, 3, 29, 15, 31, 3, 18, 43,
+ 3, 21, 22, 43, 3, 49, 246, 29, 58, 49,
+ 43, 0, 3, 44, 44, 41, 49, 37, 48, 29,
+ 51, 27, 336, 49, 68, 75, 3, 42, 68, 79,
+ 42, 46, 44, 40, 46, 68, 27, 57, 42, 42,
+ 83, 298, 299, 46, 238, 80, 81, 42, 44, 71,
+ 46, 46, 36, 247, 89, 71, 91, 71, 42, 10,
+ 11, 42, 46, 83, 304, 260, 261, 102, 42, 104,
+ 105, 239, 223, 43, 109, 45, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 267,
+ 340, 341, 137, 45, 48, 140, 48, 43, 143, 48,
+ 145, 147, 162, 49, 3, 40, 356, 42, 48, 3,
+ 43, 46, 45, 7, 8, 160, 49, 43, 368, 297,
+ 46, 43, 68, 45, 42, 155, 44, 49, 46, 174,
+ 308, 25, 26, 48, 179, 29, 42, 256, 32, 31,
+ 46, 45, 187, 42, 48, 323, 40, 41, 42, 194,
+ 195, 45, 43, 3, 45, 49, 55, 3, 49, 58,
+ 43, 55, 45, 48, 58, 343, 49, 45, 67, 48,
+ 48, 70, 71, 67, 48, 220, 70, 71, 50, 50,
+ 40, 226, 25, 26, 27, 28, 29, 30, 31, 43,
+ 243, 45, 251, 252, 43, 49, 45, 40, 3, 3,
+ 49, 246, 7, 8, 249, 42, 43, 44, 253, 46,
+ 255, 44, 257, 243, 61, 260, 261, 3, 46, 264,
+ 25, 26, 45, 34, 29, 3, 42, 32, 44, 348,
+ 46, 40, 277, 3, 47, 42, 281, 42, 43, 284,
+ 46, 3, 45, 34, 49, 27, 28, 29, 30, 31,
+ 55, 48, 47, 58, 47, 47, 5, 5, 3, 304,
+ 48, 48, 67, 3, 3, 70, 71, 68, 3, 314,
+ 45, 60, 48, 34, 41, 48, 34, 41, 43, 324,
+ 57, 326, 37, 73, 154, 289, 345, 18, 21, 83,
+ 22, 186, 161, 3, 74, 340, 341, 7, 8, 134,
+ 348, -1, 104, 102, 363, -1, 351, -1, -1, 354,
+ -1, 356, -1, 372, -1, 25, 26, -1, -1, 29,
+ -1, -1, 32, 368, -1, -1, -1, -1, -1, -1,
+ 40, 41, 42, -1, -1, -1, -1, -1, 48, -1,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ -1, 61, 62, 63, 64, 65, 66, 67, -1, -1,
+ 70, 71, 72, 73, 3, -1, -1, -1, 7, 8,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 25, 26, -1, -1,
+ 29, -1, -1, 32, -1, -1, -1, -1, -1, -1,
+ -1, 40, 41, 42, -1, -1, -1, -1, -1, 48,
+ -1, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, -1, 61, 62, 63, 64, 65, 66, 67, -1,
+ -1, 70, 71, 72, 73, 3, -1, -1, -1, 7,
+ 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 25, 26, -1,
+ -1, 29, -1, -1, 32, -1, -1, -1, -1, -1,
+ -1, -1, 40, -1, 42, -1, -1, -1, -1, -1,
+ 48, -1, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, -1, 61, 62, 63, 64, 65, 66, 67,
+ -1, -1, 70, 71, 72, 73, 3, -1, -1, -1,
+ 7, 8, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 25, 26,
+ -1, -1, 29, -1, -1, 32, -1, -1, -1, -1,
+ -1, -1, -1, 40, -1, 42, -1, -1, -1, -1,
+ -1, 48, -1, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, -1, 61, 62, 63, 64, 65, 66,
+ 67, -1, -1, 70, 71, 72, 73, 3, -1, 3,
+ -1, 7, 8, 7, 8, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 25,
+ 26, 25, 26, 29, -1, 29, 32, -1, 32, -1,
+ -1, -1, 36, -1, 40, -1, 42, -1, 42, -1,
+ -1, -1, 48, 47, -1, -1, -1, -1, -1, 55,
+ -1, 55, 58, 59, 58, 61, 62, 63, 64, 65,
+ 66, 67, -1, 67, 70, 71, 70, 71, 3, -1,
+ 3, -1, 7, 8, 7, 8, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 25, 26, 25, 26, 29, -1, 29, 32, -1, 32,
+ -1, -1, -1, -1, -1, -1, -1, 42, 43, 42,
+ -1, -1, -1, -1, 49, 48, -1, -1, -1, -1,
+ 55, -1, 55, 58, 3, 58, -1, -1, 7, 8,
+ -1, -1, 67, -1, 67, 70, 71, 70, 71, -1,
+ -1, -1, -1, -1, 3, -1, 25, 26, 7, 8,
+ 29, -1, -1, 32, 13, -1, -1, 36, -1, -1,
+ -1, -1, -1, 42, -1, -1, 25, 26, -1, -1,
+ 29, -1, -1, 32, -1, -1, 55, -1, -1, 58,
+ 3, -1, -1, 42, 7, 8, -1, -1, 67, -1,
+ -1, 70, 71, -1, -1, -1, 55, -1, -1, 58,
+ 3, -1, 25, 26, 7, 8, 29, -1, 67, 32,
+ -1, 70, 71, -1, -1, -1, -1, -1, -1, 42,
+ -1, -1, 25, 26, 47, -1, 29, -1, -1, 32,
+ -1, -1, 55, -1, -1, 58, 3, 40, -1, 42,
+ 7, 8, -1, -1, 67, 12, -1, 70, 71, -1,
+ -1, -1, 55, -1, -1, 58, 3, -1, 25, 26,
+ 7, 8, 29, -1, 67, 32, -1, 70, 71, -1,
+ -1, -1, -1, -1, -1, 42, 3, -1, 25, 26,
+ 7, 8, 29, -1, -1, 32, -1, -1, 55, -1,
+ -1, 58, -1, -1, -1, 42, -1, -1, 25, 26,
+ 67, -1, 29, 70, 71, 32, -1, -1, 55, -1,
+ -1, 58, -1, -1, -1, 42, -1, -1, -1, -1,
+ 67, -1, -1, 70, 71, -1, -1, -1, 55, -1,
+ -1, 58, -1, -1, -1, -1, -1, -1, -1, -1,
+ 67, -1, -1, 70, 71, 4, 5, 6, 7, 8,
+ 9, -1, -1, -1, -1, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, -1, 34, 35, -1, -1, -1,
+ -1, 40, 4, 5, 6, 7, 8, 9, -1, 48,
+ -1, -1, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, -1, 34, 35, 36, -1, -1, -1, 40, 4,
+ 5, 6, 7, 8, 9, 47, -1, -1, -1, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, 34,
+ 35, 36, -1, -1, -1, 40, 4, 5, 6, 7,
+ 8, 9, 47, -1, -1, -1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, -1, 34, 35, -1, -1,
+ -1, -1, 40, 4, 5, 6, 7, 8, 9, 47,
+ -1, -1, -1, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, -1, 34, 35, -1, -1, -1, -1, 40,
+ 4, 5, 6, 7, 8, 9, 47, -1, -1, -1,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, -1,
+ 34, 35, -1, -1, -1, -1, 40, -1, -1, 43,
+ -1, 45, 4, 5, 6, 7, 8, 9, -1, -1,
+ -1, -1, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, -1, 34, 35, -1, -1, -1, -1, 40, 41,
+ -1, -1, -1, 45, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, -1, 34, 35, -1, -1, -1, -1,
+ 40, 41, -1, -1, -1, 45, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, -1, 34, 35, -1, -1,
+ -1, -1, 40, -1, -1, 43, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, -1, 34, 35, -1, -1,
+ -1, -1, 40, -1, -1, 43, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, -1, 34, 35, -1, -1,
+ -1, -1, 40, -1, -1, 43, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, -1, 34, 35, -1, -1,
+ -1, -1, 40, -1, -1, 43, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, -1, 34, 35, -1, -1,
+ -1, -1, 40, 41, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, -1, 34, 35, -1, -1, -1, -1,
+ 40, 41, 4, 5, 6, 7, 8, 9, -1, -1,
+ -1, -1, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, -1, 34, 35, 36, -1, -1, -1, 40, 4,
+ 5, 6, 7, 8, 9, -1, -1, -1, -1, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, 34,
+ 35, -1, -1, -1, 4, 40, 6, 7, 8, 9,
+ -1, -1, -1, -1, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, -1, 34, 35, -1, -1, -1, 39,
+ 40, 4, -1, 6, 7, 8, 9, -1, -1, -1,
+ -1, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, 34, 35, -1, -1, -1, 39, 40, 4, -1,
+ 6, 7, 8, 9, -1, -1, -1, -1, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, -1, 34, 35,
+ -1, -1, -1, 39, 40, 4, -1, 6, 7, 8,
+ 9, -1, -1, -1, -1, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, -1, 34, 35, -1, -1, -1,
+ -1, 40, 5, 6, 7, 8, 9, -1, -1, -1,
+ -1, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, -1, 35, -1, -1, -1, -1, 40, 5, 6,
+ 7, 8, 9, -1, -1, -1, -1, -1, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 5, 6, 7, 8,
+ 9, -1, -1, 40, -1, -1, -1, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 5, 6, 7, 8, 9, -1,
+ -1, 40, -1, -1, -1, -1, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 5, 6, 7, 8, 9, -1, -1, 40,
+ -1, -1, -1, -1, -1, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 5, 6, 7, 8, 9, -1, -1, 40, -1, -1,
+ -1, -1, -1, -1, -1, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 5, 6,
+ 7, 8, 9, -1, -1, 40, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 5, 6, 7, 8,
+ 9, -1, -1, 40, 5, 6, 7, 8, 9, -1,
+ -1, -1, -1, -1, -1, 24, 25, 26, 27, 28,
+ 29, 30, 31, -1, 25, 26, 27, 28, 29, 30,
+ 31, 40, -1, -1, -1, -1, -1, -1, -1, 40
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 77, 78, 0, 3, 7, 8, 25, 26, 29,
+ 32, 40, 42, 48, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 61, 62, 63, 64, 65, 66,
+ 67, 70, 71, 72, 73, 80, 81, 82, 83, 89,
+ 90, 91, 92, 99, 106, 107, 109, 113, 119, 120,
+ 121, 80, 113, 113, 113, 113, 113, 79, 80, 112,
+ 113, 3, 71, 86, 87, 88, 80, 87, 3, 71,
+ 3, 80, 86, 40, 3, 80, 89, 91, 80, 92,
+ 42, 42, 119, 42, 48, 48, 48, 113, 113, 42,
+ 44, 46, 93, 72, 73, 83, 119, 48, 3, 95,
+ 96, 97, 42, 44, 46, 4, 5, 6, 7, 8,
+ 9, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 34, 35, 40, 114, 115, 116, 48, 46, 41, 81,
+ 43, 93, 43, 45, 43, 45, 3, 45, 48, 48,
+ 48, 48, 48, 51, 50, 78, 99, 46, 3, 42,
+ 46, 93, 94, 113, 113, 61, 90, 91, 120, 122,
+ 125, 48, 3, 43, 49, 110, 111, 113, 3, 36,
+ 47, 108, 113, 46, 42, 93, 45, 34, 43, 111,
+ 3, 108, 113, 113, 10, 11, 117, 118, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 13, 113, 113, 116, 115, 113, 43, 113, 113, 3,
+ 87, 3, 27, 84, 85, 27, 85, 41, 42, 43,
+ 49, 68, 103, 104, 105, 113, 40, 42, 100, 46,
+ 93, 43, 43, 42, 3, 48, 45, 34, 110, 43,
+ 45, 49, 113, 47, 36, 47, 47, 43, 103, 96,
+ 98, 100, 113, 43, 47, 47, 113, 12, 113, 5,
+ 5, 36, 113, 41, 45, 115, 113, 3, 48, 45,
+ 48, 48, 48, 43, 103, 121, 105, 43, 45, 49,
+ 91, 47, 41, 45, 49, 98, 101, 102, 43, 103,
+ 113, 119, 119, 113, 36, 113, 123, 120, 113, 110,
+ 110, 113, 121, 43, 39, 113, 39, 113, 41, 113,
+ 3, 84, 43, 121, 105, 105, 3, 97, 98, 41,
+ 49, 45, 121, 43, 47, 60, 43, 113, 48, 121,
+ 113, 39, 113, 41, 45, 97, 34, 41, 98, 98,
+ 121, 119, 48, 43, 124, 125, 113, 113, 34, 98,
+ 41, 119, 43, 41, 98, 119
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 76, 77, 78, 78, 79, 79, 80, 80, 80,
+ 81, 81, 81, 81, 82, 82, 82, 82, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 84, 84, 85, 85, 86, 86, 87, 87, 88, 88,
+ 89, 90, 91, 91, 92, 93, 93, 94, 94, 95,
+ 95, 96, 96, 97, 97, 97, 97, 98, 98, 99,
+ 100, 100, 100, 100, 101, 101, 101, 102, 102, 103,
+ 103, 103, 103, 104, 104, 105, 105, 105, 105, 105,
+ 106, 106, 107, 107, 108, 108, 108, 108, 109, 109,
+ 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
+ 110, 110, 111, 111, 111, 111, 112, 112, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 114, 114, 114,
+ 114, 114, 115, 115, 115, 115, 116, 116, 116, 116,
+ 116, 117, 117, 117, 117, 118, 118, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 120, 121, 122, 122, 122, 123, 123, 124, 124, 125,
+ 125
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 0, 2, 0, 2, 1, 3, 1,
+ 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
+ 1, 3, 5, 5, 3, 5, 5, 3, 3, 3,
+ 1, 3, 1, 3, 1, 1, 1, 3, 1, 3,
+ 2, 2, 1, 2, 1, 2, 3, 3, 4, 1,
+ 3, 1, 3, 1, 2, 3, 4, 1, 1, 3,
+ 2, 4, 3, 5, 1, 1, 2, 1, 3, 1,
+ 2, 3, 3, 1, 0, 2, 3, 5, 4, 6,
+ 5, 6, 3, 2, 1, 2, 2, 3, 3, 4,
+ 4, 4, 4, 3, 4, 3, 4, 3, 3, 1,
+ 1, 3, 1, 2, 3, 3, 3, 3, 1, 1,
+ 1, 1, 2, 4, 5, 2, 2, 2, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 2, 3,
+ 4, 3, 4, 5, 6, 6, 7, 5, 3, 3,
+ 3, 2, 2, 2, 2, 3, 4, 1, 1, 2,
+ 2, 3, 4, 3, 5, 7, 1, 3, 3, 1,
+ 1, 2, 4, 3, 5, 2, 4, 1, 1, 2,
+ 5, 7, 5, 7, 9, 8, 2, 2, 2, 3,
+ 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,
+ 3
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
+{
+ unsigned long int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ default: /* Avoid compiler warnings. */
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+{
+ YYUSE (yyvaluep);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 191 "camp.y" /* yacc.c:1648 */
+ { absyntax::root = (yyvsp[0].b); }
+#line 1955 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 3:
+#line 195 "camp.y" /* yacc.c:1648 */
+ { (yyval.b) = new file(lexerPos(), false); }
+#line 1961 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 4:
+#line 197 "camp.y" /* yacc.c:1648 */
+ { (yyval.b) = (yyvsp[-1].b); (yyval.b)->add((yyvsp[0].run)); }
+#line 1967 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 5:
+#line 201 "camp.y" /* yacc.c:1648 */
+ { (yyval.b) = new block(lexerPos(), true); }
+#line 1973 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 6:
+#line 203 "camp.y" /* yacc.c:1648 */
+ { (yyval.b) = (yyvsp[-1].b); (yyval.b)->add((yyvsp[0].run)); }
+#line 1979 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 7:
+#line 207 "camp.y" /* yacc.c:1648 */
+ { (yyval.n) = new simpleName((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 1985 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 8:
+#line 208 "camp.y" /* yacc.c:1648 */
+ { (yyval.n) = new qualifiedName((yyvsp[-1].pos), (yyvsp[-2].n), (yyvsp[0].ps).sym); }
+#line 1991 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 9:
+#line 209 "camp.y" /* yacc.c:1648 */
+ { (yyval.n) = new simpleName((yyvsp[0].ps).pos,
+ symbol::trans("operator answer")); }
+#line 1998 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 10:
+#line 214 "camp.y" /* yacc.c:1648 */
+ { (yyval.run) = (yyvsp[0].d); }
+#line 2004 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 11:
+#line 215 "camp.y" /* yacc.c:1648 */
+ { (yyval.run) = (yyvsp[0].s); }
+#line 2010 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 12:
+#line 217 "camp.y" /* yacc.c:1648 */
+ { (yyval.run) = new modifiedRunnable((yyvsp[-1].ml)->getPos(), (yyvsp[-1].ml), (yyvsp[0].d)); }
+#line 2016 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 13:
+#line 219 "camp.y" /* yacc.c:1648 */
+ { (yyval.run) = new modifiedRunnable((yyvsp[-1].ml)->getPos(), (yyvsp[-1].ml), (yyvsp[0].s)); }
+#line 2022 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 14:
+#line 223 "camp.y" /* yacc.c:1648 */
+ { (yyval.ml) = new modifierList((yyvsp[0].mod).pos); (yyval.ml)->add((yyvsp[0].mod).val); }
+#line 2028 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 15:
+#line 224 "camp.y" /* yacc.c:1648 */
+ { (yyval.ml) = new modifierList((yyvsp[0].perm).pos); (yyval.ml)->add((yyvsp[0].perm).val); }
+#line 2034 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 16:
+#line 226 "camp.y" /* yacc.c:1648 */
+ { (yyval.ml) = (yyvsp[-1].ml); (yyval.ml)->add((yyvsp[0].mod).val); }
+#line 2040 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 17:
+#line 228 "camp.y" /* yacc.c:1648 */
+ { (yyval.ml) = (yyvsp[-1].ml); (yyval.ml)->add((yyvsp[0].perm).val); }
+#line 2046 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 18:
+#line 232 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = (yyvsp[0].vd); }
+#line 2052 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 19:
+#line 233 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = (yyvsp[0].d); }
+#line 2058 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 20:
+#line 234 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = (yyvsp[0].d); }
+#line 2064 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 21:
+#line 236 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new accessdec((yyvsp[-2].pos), (yyvsp[-1].ipl)); }
+#line 2070 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 22:
+#line 238 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new unraveldec((yyvsp[-4].pos), (yyvsp[-3].n), (yyvsp[-1].ipl)); }
+#line 2076 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 23:
+#line 240 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new unraveldec((yyvsp[-4].pos), (yyvsp[-3].n), WILDCARD); }
+#line 2082 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 24:
+#line 241 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new unraveldec((yyvsp[-2].pos), (yyvsp[-1].n), WILDCARD); }
+#line 2088 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 25:
+#line 243 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new fromaccessdec((yyvsp[-4].pos), (yyvsp[-3].ps).sym, (yyvsp[-1].ipl)); }
+#line 2094 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 26:
+#line 245 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new fromaccessdec((yyvsp[-4].pos), (yyvsp[-3].ps).sym, WILDCARD); }
+#line 2100 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 27:
+#line 247 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new importdec((yyvsp[-2].pos), (yyvsp[-1].ip)); }
+#line 2106 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 28:
+#line 248 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new includedec((yyvsp[-2].pos), (yyvsp[-1].ps).sym); }
+#line 2112 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 29:
+#line 250 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new includedec((yyvsp[-2].pos), (yyvsp[-1].stre)->getString()); }
+#line 2118 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 30:
+#line 254 "camp.y" /* yacc.c:1648 */
+ { (yyval.ip) = new idpair((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2124 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 31:
+#line 256 "camp.y" /* yacc.c:1648 */
+ { (yyval.ip) = new idpair((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].ps).sym , (yyvsp[0].ps).sym); }
+#line 2130 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 32:
+#line 260 "camp.y" /* yacc.c:1648 */
+ { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2136 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 33:
+#line 262 "camp.y" /* yacc.c:1648 */
+ { (yyval.ipl) = (yyvsp[-2].ipl); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2142 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 34:
+#line 266 "camp.y" /* yacc.c:1648 */
+ { (yyval.ps) = (yyvsp[0].ps); }
+#line 2148 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 35:
+#line 267 "camp.y" /* yacc.c:1648 */
+ { (yyval.ps).pos = (yyvsp[0].stre)->getPos();
+ (yyval.ps).sym = symbol::literalTrans((yyvsp[0].stre)->getString()); }
+#line 2155 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 36:
+#line 272 "camp.y" /* yacc.c:1648 */
+ { (yyval.ip) = new idpair((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2161 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 37:
+#line 274 "camp.y" /* yacc.c:1648 */
+ { (yyval.ip) = new idpair((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].ps).sym , (yyvsp[0].ps).sym); }
+#line 2167 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 38:
+#line 278 "camp.y" /* yacc.c:1648 */
+ { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2173 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 39:
+#line 280 "camp.y" /* yacc.c:1648 */
+ { (yyval.ipl) = (yyvsp[-2].ipl); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2179 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 40:
+#line 284 "camp.y" /* yacc.c:1648 */
+ { (yyval.vd) = (yyvsp[-1].vd); }
+#line 2185 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 41:
+#line 288 "camp.y" /* yacc.c:1648 */
+ { (yyval.vd) = new vardec((yyvsp[-1].t)->getPos(), (yyvsp[-1].t), (yyvsp[0].dil)); }
+#line 2191 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 42:
+#line 292 "camp.y" /* yacc.c:1648 */
+ { (yyval.t) = (yyvsp[0].t); }
+#line 2197 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 43:
+#line 293 "camp.y" /* yacc.c:1648 */
+ { (yyval.t) = new arrayTy((yyvsp[-1].n), (yyvsp[0].dim)); }
+#line 2203 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 44:
+#line 297 "camp.y" /* yacc.c:1648 */
+ { (yyval.t) = new nameTy((yyvsp[0].n)); }
+#line 2209 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 45:
+#line 301 "camp.y" /* yacc.c:1648 */
+ { (yyval.dim) = new dimensions((yyvsp[-1].pos)); }
+#line 2215 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 46:
+#line 302 "camp.y" /* yacc.c:1648 */
+ { (yyval.dim) = (yyvsp[-2].dim); (yyval.dim)->increase(); }
+#line 2221 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 47:
+#line 306 "camp.y" /* yacc.c:1648 */
+ { (yyval.elist) = new explist((yyvsp[-2].pos)); (yyval.elist)->add((yyvsp[-1].e)); }
+#line 2227 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 48:
+#line 308 "camp.y" /* yacc.c:1648 */
+ { (yyval.elist) = (yyvsp[-3].elist); (yyval.elist)->add((yyvsp[-1].e)); }
+#line 2233 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 49:
+#line 312 "camp.y" /* yacc.c:1648 */
+ { (yyval.dil) = new decidlist((yyvsp[0].di)->getPos()); (yyval.dil)->add((yyvsp[0].di)); }
+#line 2239 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 50:
+#line 314 "camp.y" /* yacc.c:1648 */
+ { (yyval.dil) = (yyvsp[-2].dil); (yyval.dil)->add((yyvsp[0].di)); }
+#line 2245 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 51:
+#line 318 "camp.y" /* yacc.c:1648 */
+ { (yyval.di) = new decid((yyvsp[0].dis)->getPos(), (yyvsp[0].dis)); }
+#line 2251 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 52:
+#line 320 "camp.y" /* yacc.c:1648 */
+ { (yyval.di) = new decid((yyvsp[-2].dis)->getPos(), (yyvsp[-2].dis), (yyvsp[0].vi)); }
+#line 2257 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 53:
+#line 324 "camp.y" /* yacc.c:1648 */
+ { (yyval.dis) = new decidstart((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2263 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 54:
+#line 325 "camp.y" /* yacc.c:1648 */
+ { (yyval.dis) = new decidstart((yyvsp[-1].ps).pos, (yyvsp[-1].ps).sym, (yyvsp[0].dim)); }
+#line 2269 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 55:
+#line 326 "camp.y" /* yacc.c:1648 */
+ { (yyval.dis) = new fundecidstart((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, 0,
+ new formals((yyvsp[-1].pos))); }
+#line 2276 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 56:
+#line 329 "camp.y" /* yacc.c:1648 */
+ { (yyval.dis) = new fundecidstart((yyvsp[-3].ps).pos, (yyvsp[-3].ps).sym, 0, (yyvsp[-1].fls)); }
+#line 2282 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 57:
+#line 333 "camp.y" /* yacc.c:1648 */
+ { (yyval.vi) = (yyvsp[0].e); }
+#line 2288 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 58:
+#line 334 "camp.y" /* yacc.c:1648 */
+ { (yyval.vi) = (yyvsp[0].ai); }
+#line 2294 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 59:
+#line 339 "camp.y" /* yacc.c:1648 */
+ { (yyval.b) = (yyvsp[-1].b); }
+#line 2300 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 60:
+#line 343 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = new arrayinit((yyvsp[-1].pos)); }
+#line 2306 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 61:
+#line 345 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = new arrayinit((yyvsp[-3].pos)); (yyval.ai)->addRest((yyvsp[-1].vi)); }
+#line 2312 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 62:
+#line 347 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = (yyvsp[-1].ai); }
+#line 2318 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 63:
+#line 349 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = (yyvsp[-3].ai); (yyval.ai)->addRest((yyvsp[-1].vi)); }
+#line 2324 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 64:
+#line 353 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = new arrayinit((yyvsp[0].pos)); }
+#line 2330 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 65:
+#line 354 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = (yyvsp[0].ai); }
+#line 2336 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 66:
+#line 355 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = (yyvsp[-1].ai); }
+#line 2342 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 67:
+#line 359 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = new arrayinit((yyvsp[0].vi)->getPos());
+ (yyval.ai)->add((yyvsp[0].vi));}
+#line 2349 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 68:
+#line 362 "camp.y" /* yacc.c:1648 */
+ { (yyval.ai) = (yyvsp[-2].ai); (yyval.ai)->add((yyvsp[0].vi)); }
+#line 2355 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 69:
+#line 366 "camp.y" /* yacc.c:1648 */
+ { (yyval.fls) = new formals((yyvsp[0].fl)->getPos()); (yyval.fls)->add((yyvsp[0].fl)); }
+#line 2361 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 70:
+#line 367 "camp.y" /* yacc.c:1648 */
+ { (yyval.fls) = new formals((yyvsp[-1].pos)); (yyval.fls)->addRest((yyvsp[0].fl)); }
+#line 2367 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 71:
+#line 369 "camp.y" /* yacc.c:1648 */
+ { (yyval.fls) = (yyvsp[-2].fls); (yyval.fls)->add((yyvsp[0].fl)); }
+#line 2373 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 72:
+#line 371 "camp.y" /* yacc.c:1648 */
+ { (yyval.fls) = (yyvsp[-2].fls); (yyval.fls)->addRest((yyvsp[0].fl)); }
+#line 2379 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 73:
+#line 375 "camp.y" /* yacc.c:1648 */
+ { (yyval.boo) = true; }
+#line 2385 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 74:
+#line 376 "camp.y" /* yacc.c:1648 */
+ { (yyval.boo) = false; }
+#line 2391 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 75:
+#line 381 "camp.y" /* yacc.c:1648 */
+ { (yyval.fl) = new formal((yyvsp[0].t)->getPos(), (yyvsp[0].t), 0, 0, (yyvsp[-1].boo), 0); }
+#line 2397 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 76:
+#line 383 "camp.y" /* yacc.c:1648 */
+ { (yyval.fl) = new formal((yyvsp[-1].t)->getPos(), (yyvsp[-1].t), (yyvsp[0].dis), 0, (yyvsp[-2].boo), 0); }
+#line 2403 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 77:
+#line 385 "camp.y" /* yacc.c:1648 */
+ { (yyval.fl) = new formal((yyvsp[-3].t)->getPos(), (yyvsp[-3].t), (yyvsp[-2].dis), (yyvsp[0].vi), (yyvsp[-4].boo), 0); }
+#line 2409 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 78:
+#line 388 "camp.y" /* yacc.c:1648 */
+ { bool k = checkKeyword((yyvsp[-1].ps).pos, (yyvsp[-1].ps).sym);
+ (yyval.fl) = new formal((yyvsp[-2].t)->getPos(), (yyvsp[-2].t), (yyvsp[0].dis), 0, (yyvsp[-3].boo), k); }
+#line 2416 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 79:
+#line 391 "camp.y" /* yacc.c:1648 */
+ { bool k = checkKeyword((yyvsp[-3].ps).pos, (yyvsp[-3].ps).sym);
+ (yyval.fl) = new formal((yyvsp[-4].t)->getPos(), (yyvsp[-4].t), (yyvsp[-2].dis), (yyvsp[0].vi), (yyvsp[-5].boo), k); }
+#line 2423 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 80:
+#line 397 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new fundec((yyvsp[-2].pos), (yyvsp[-4].t), (yyvsp[-3].ps).sym, new formals((yyvsp[-2].pos)), (yyvsp[0].s)); }
+#line 2429 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 81:
+#line 399 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new fundec((yyvsp[-3].pos), (yyvsp[-5].t), (yyvsp[-4].ps).sym, (yyvsp[-2].fls), (yyvsp[0].s)); }
+#line 2435 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 82:
+#line 403 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new recorddec((yyvsp[-2].pos), (yyvsp[-1].ps).sym, (yyvsp[0].b)); }
+#line 2441 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 83:
+#line 404 "camp.y" /* yacc.c:1648 */
+ { (yyval.d) = new typedec((yyvsp[-1].pos), (yyvsp[0].vd)); }
+#line 2447 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 84:
+#line 408 "camp.y" /* yacc.c:1648 */
+ { (yyval.slice) = new slice((yyvsp[0].pos), 0, 0); }
+#line 2453 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 85:
+#line 409 "camp.y" /* yacc.c:1648 */
+ { (yyval.slice) = new slice((yyvsp[0].pos), (yyvsp[-1].e), 0); }
+#line 2459 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 86:
+#line 410 "camp.y" /* yacc.c:1648 */
+ { (yyval.slice) = new slice((yyvsp[-1].pos), 0, (yyvsp[0].e)); }
+#line 2465 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 87:
+#line 411 "camp.y" /* yacc.c:1648 */
+ { (yyval.slice) = new slice((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].e)); }
+#line 2471 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 88:
+#line 415 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new fieldExp((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].ps).sym); }
+#line 2477 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 89:
+#line 416 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new subscriptExp((yyvsp[-2].pos),
+ new nameExp((yyvsp[-3].n)->getPos(), (yyvsp[-3].n)), (yyvsp[-1].e)); }
+#line 2484 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 90:
+#line 418 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new subscriptExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].e)); }
+#line 2490 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 91:
+#line 419 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new sliceExp((yyvsp[-2].pos),
+ new nameExp((yyvsp[-3].n)->getPos(), (yyvsp[-3].n)), (yyvsp[-1].slice)); }
+#line 2497 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 92:
+#line 421 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new sliceExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].slice)); }
+#line 2503 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 93:
+#line 422 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new callExp((yyvsp[-1].pos),
+ new nameExp((yyvsp[-2].n)->getPos(), (yyvsp[-2].n)),
+ new arglist()); }
+#line 2511 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 94:
+#line 426 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new callExp((yyvsp[-2].pos),
+ new nameExp((yyvsp[-3].n)->getPos(), (yyvsp[-3].n)),
+ (yyvsp[-1].alist)); }
+#line 2519 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 95:
+#line 429 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new callExp((yyvsp[-1].pos), (yyvsp[-2].e), new arglist()); }
+#line 2525 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 96:
+#line 431 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new callExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].alist)); }
+#line 2531 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 97:
+#line 433 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = (yyvsp[-1].e); }
+#line 2537 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 98:
+#line 435 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new nameExp((yyvsp[-1].n)->getPos(), (yyvsp[-1].n)); }
+#line 2543 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 99:
+#line 436 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new thisExp((yyvsp[0].pos)); }
+#line 2549 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 100:
+#line 440 "camp.y" /* yacc.c:1648 */
+ { (yyval.arg).name = symbol::nullsym; (yyval.arg).val=(yyvsp[0].e); }
+#line 2555 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 101:
+#line 441 "camp.y" /* yacc.c:1648 */
+ { (yyval.arg).name = (yyvsp[-2].ps).sym; (yyval.arg).val=(yyvsp[0].e); }
+#line 2561 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 102:
+#line 445 "camp.y" /* yacc.c:1648 */
+ { (yyval.alist) = new arglist(); (yyval.alist)->add((yyvsp[0].arg)); }
+#line 2567 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 103:
+#line 447 "camp.y" /* yacc.c:1648 */
+ { (yyval.alist) = new arglist(); (yyval.alist)->addRest((yyvsp[0].arg)); }
+#line 2573 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 104:
+#line 449 "camp.y" /* yacc.c:1648 */
+ { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->add((yyvsp[0].arg)); }
+#line 2579 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 105:
+#line 451 "camp.y" /* yacc.c:1648 */
+ { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->addRest((yyvsp[0].arg)); }
+#line 2585 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 106:
+#line 456 "camp.y" /* yacc.c:1648 */
+ { (yyval.alist) = new arglist(); (yyval.alist)->add((yyvsp[-2].e)); (yyval.alist)->add((yyvsp[0].e)); }
+#line 2591 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 107:
+#line 457 "camp.y" /* yacc.c:1648 */
+ { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->add((yyvsp[0].e)); }
+#line 2597 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 108:
+#line 461 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new nameExp((yyvsp[0].n)->getPos(), (yyvsp[0].n)); }
+#line 2603 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 109:
+#line 462 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = (yyvsp[0].e); }
+#line 2609 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 110:
+#line 463 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = (yyvsp[0].e); }
+#line 2615 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 111:
+#line 464 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = (yyvsp[0].stre); }
+#line 2621 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 112:
+#line 466 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new scaleExp((yyvsp[-1].e)->getPos(), (yyvsp[-1].e), (yyvsp[0].e)); }
+#line 2627 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 113:
+#line 468 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new castExp((yyvsp[-2].n)->getPos(), new nameTy((yyvsp[-2].n)), (yyvsp[0].e)); }
+#line 2633 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 114:
+#line 470 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new castExp((yyvsp[-3].n)->getPos(), new arrayTy((yyvsp[-3].n), (yyvsp[-2].dim)), (yyvsp[0].e)); }
+#line 2639 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 115:
+#line 472 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 2645 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 116:
+#line 474 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 2651 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 117:
+#line 475 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 2657 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 118:
+#line 476 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2663 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 119:
+#line 477 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2669 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 120:
+#line 478 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2675 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 121:
+#line 479 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2681 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 122:
+#line 480 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2687 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 123:
+#line 481 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2693 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 124:
+#line 482 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2699 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 125:
+#line 483 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2705 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 126:
+#line 484 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2711 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 127:
+#line 485 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2717 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 128:
+#line 486 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2723 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 129:
+#line 487 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new equalityExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2729 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 130:
+#line 488 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new equalityExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2735 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 131:
+#line 489 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new andExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2741 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 132:
+#line 490 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new orExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2747 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 133:
+#line 491 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2753 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 134:
+#line 492 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2759 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 135:
+#line 493 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2765 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 136:
+#line 494 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2771 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 137:
+#line 495 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2777 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 138:
+#line 497 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newRecordExp((yyvsp[-1].pos), (yyvsp[0].t)); }
+#line 2783 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 139:
+#line 499 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newArrayExp((yyvsp[-2].pos), (yyvsp[-1].t), (yyvsp[0].elist), 0, 0); }
+#line 2789 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 140:
+#line 501 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newArrayExp((yyvsp[-3].pos), (yyvsp[-2].t), (yyvsp[-1].elist), (yyvsp[0].dim), 0); }
+#line 2795 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 141:
+#line 503 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newArrayExp((yyvsp[-2].pos), (yyvsp[-1].t), 0, (yyvsp[0].dim), 0); }
+#line 2801 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 142:
+#line 505 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newArrayExp((yyvsp[-3].pos), (yyvsp[-2].t), 0, (yyvsp[-1].dim), (yyvsp[0].ai)); }
+#line 2807 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 143:
+#line 507 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newFunctionExp((yyvsp[-4].pos), (yyvsp[-3].t), new formals((yyvsp[-2].pos)), (yyvsp[0].s)); }
+#line 2813 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 144:
+#line 509 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newFunctionExp((yyvsp[-5].pos),
+ new arrayTy((yyvsp[-4].t)->getPos(), (yyvsp[-4].t), (yyvsp[-3].dim)),
+ new formals((yyvsp[-2].pos)),
+ (yyvsp[0].s)); }
+#line 2822 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 145:
+#line 514 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newFunctionExp((yyvsp[-5].pos), (yyvsp[-4].t), (yyvsp[-2].fls), (yyvsp[0].s)); }
+#line 2828 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 146:
+#line 516 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new newFunctionExp((yyvsp[-6].pos),
+ new arrayTy((yyvsp[-5].t)->getPos(), (yyvsp[-5].t), (yyvsp[-4].dim)),
+ (yyvsp[-2].fls),
+ (yyvsp[0].s)); }
+#line 2837 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 147:
+#line 521 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new conditionalExp((yyvsp[-3].pos), (yyvsp[-4].e), (yyvsp[-2].e), (yyvsp[0].e)); }
+#line 2843 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 148:
+#line 522 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new assignExp((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].e)); }
+#line 2849 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 149:
+#line 523 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new callExp((yyvsp[-2].pos), new nameExp((yyvsp[-2].pos), SYM_TUPLE), (yyvsp[-1].alist)); }
+#line 2855 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 150:
+#line 525 "camp.y" /* yacc.c:1648 */
+ { (yyvsp[-1].j)->pushFront((yyvsp[-2].e)); (yyvsp[-1].j)->pushBack((yyvsp[0].e)); (yyval.e) = (yyvsp[-1].j); }
+#line 2861 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 151:
+#line 527 "camp.y" /* yacc.c:1648 */
+ { (yyvsp[0].se)->setSide(camp::OUT);
+ joinExp *jexp =
+ new joinExp((yyvsp[0].se)->getPos(), SYM_DOTS);
+ (yyval.e)=jexp;
+ jexp->pushBack((yyvsp[-1].e)); jexp->pushBack((yyvsp[0].se)); }
+#line 2871 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 152:
+#line 533 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new prefixExp((yyvsp[-1].ps).pos, (yyvsp[0].e), SYM_PLUS); }
+#line 2877 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 153:
+#line 535 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new prefixExp((yyvsp[-1].ps).pos, (yyvsp[0].e), SYM_MINUS); }
+#line 2883 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 154:
+#line 538 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new postfixExp((yyvsp[0].ps).pos, (yyvsp[-1].e), SYM_PLUS); }
+#line 2889 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 155:
+#line 539 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new selfExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2895 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 156:
+#line 541 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new quoteExp((yyvsp[-3].pos), (yyvsp[-1].b)); }
+#line 2901 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 157:
+#line 547 "camp.y" /* yacc.c:1648 */
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos,(yyvsp[0].ps).sym); }
+#line 2907 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 158:
+#line 549 "camp.y" /* yacc.c:1648 */
+ { (yyval.j) = (yyvsp[0].j); }
+#line 2913 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 159:
+#line 551 "camp.y" /* yacc.c:1648 */
+ { (yyvsp[-1].se)->setSide(camp::OUT);
+ (yyval.j) = (yyvsp[0].j); (yyval.j)->pushFront((yyvsp[-1].se)); }
+#line 2920 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 160:
+#line 554 "camp.y" /* yacc.c:1648 */
+ { (yyvsp[0].se)->setSide(camp::IN);
+ (yyval.j) = (yyvsp[-1].j); (yyval.j)->pushBack((yyvsp[0].se)); }
+#line 2927 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 161:
+#line 557 "camp.y" /* yacc.c:1648 */
+ { (yyvsp[-2].se)->setSide(camp::OUT); (yyvsp[0].se)->setSide(camp::IN);
+ (yyval.j) = (yyvsp[-1].j); (yyval.j)->pushFront((yyvsp[-2].se)); (yyval.j)->pushBack((yyvsp[0].se)); }
+#line 2934 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 162:
+#line 562 "camp.y" /* yacc.c:1648 */
+ { (yyval.se) = new specExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].e)); }
+#line 2940 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 163:
+#line 563 "camp.y" /* yacc.c:1648 */
+ { (yyval.se) = new specExp((yyvsp[-2].pos), symbol::opTrans("spec"), (yyvsp[-1].e)); }
+#line 2946 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 164:
+#line 565 "camp.y" /* yacc.c:1648 */
+ { (yyval.se) = new specExp((yyvsp[-4].pos), symbol::opTrans("spec"),
+ new pairExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].e))); }
+#line 2953 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 165:
+#line 568 "camp.y" /* yacc.c:1648 */
+ { (yyval.se) = new specExp((yyvsp[-6].pos), symbol::opTrans("spec"),
+ new tripleExp((yyvsp[-4].pos), (yyvsp[-5].e), (yyvsp[-3].e), (yyvsp[-1].e))); }
+#line 2960 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 166:
+#line 573 "camp.y" /* yacc.c:1648 */
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2966 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 167:
+#line 575 "camp.y" /* yacc.c:1648 */
+ { (yyval.j) = new joinExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym); (yyval.j)->pushBack((yyvsp[-1].e)); }
+#line 2972 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 168:
+#line 577 "camp.y" /* yacc.c:1648 */
+ { (yyval.j) = new joinExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym); (yyval.j)->pushBack((yyvsp[-1].e)); }
+#line 2978 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 169:
+#line 578 "camp.y" /* yacc.c:1648 */
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2984 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 170:
+#line 579 "camp.y" /* yacc.c:1648 */
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2990 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 171:
+#line 583 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym,
+ new booleanExp((yyvsp[-1].ps).pos, false)); }
+#line 2997 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 172:
+#line 586 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new ternaryExp((yyvsp[-3].ps).pos, (yyvsp[-2].e), (yyvsp[-3].ps).sym, (yyvsp[0].e),
+ new booleanExp((yyvsp[-3].ps).pos, false)); }
+#line 3004 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 173:
+#line 589 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-2].ps).pos, (yyvsp[0].e), (yyvsp[-2].ps).sym,
+ new booleanExp((yyvsp[-1].ps).pos, true)); }
+#line 3011 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 174:
+#line 592 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new ternaryExp((yyvsp[-4].ps).pos, (yyvsp[-2].e), (yyvsp[-4].ps).sym, (yyvsp[0].e),
+ new booleanExp((yyvsp[-3].ps).pos, true)); }
+#line 3018 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 175:
+#line 597 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 3024 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 176:
+#line 599 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = new binaryExp((yyvsp[-3].ps).pos, (yyvsp[-2].e), (yyvsp[-3].ps).sym, (yyvsp[0].e)); }
+#line 3030 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 177:
+#line 603 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new emptyStm((yyvsp[0].pos)); }
+#line 3036 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 178:
+#line 604 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = (yyvsp[0].s); }
+#line 3042 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 179:
+#line 605 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = (yyvsp[-1].s); }
+#line 3048 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 180:
+#line 607 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new ifStm((yyvsp[-4].pos), (yyvsp[-2].e), (yyvsp[0].s)); }
+#line 3054 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 181:
+#line 609 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new ifStm((yyvsp[-6].pos), (yyvsp[-4].e), (yyvsp[-2].s), (yyvsp[0].s)); }
+#line 3060 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 182:
+#line 611 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new whileStm((yyvsp[-4].pos), (yyvsp[-2].e), (yyvsp[0].s)); }
+#line 3066 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 183:
+#line 613 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new doStm((yyvsp[-6].pos), (yyvsp[-5].s), (yyvsp[-2].e)); }
+#line 3072 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 184:
+#line 615 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new forStm((yyvsp[-8].pos), (yyvsp[-6].run), (yyvsp[-4].e), (yyvsp[-2].sel), (yyvsp[0].s)); }
+#line 3078 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 185:
+#line 617 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new extendedForStm((yyvsp[-7].pos), (yyvsp[-5].t), (yyvsp[-4].ps).sym, (yyvsp[-2].e), (yyvsp[0].s)); }
+#line 3084 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 186:
+#line 618 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new breakStm((yyvsp[-1].pos)); }
+#line 3090 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 187:
+#line 619 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new continueStm((yyvsp[-1].pos)); }
+#line 3096 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 188:
+#line 620 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new returnStm((yyvsp[-1].pos)); }
+#line 3102 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 189:
+#line 621 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new returnStm((yyvsp[-2].pos), (yyvsp[-1].e)); }
+#line 3108 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 190:
+#line 625 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new expStm((yyvsp[0].e)->getPos(), (yyvsp[0].e)); }
+#line 3114 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 191:
+#line 629 "camp.y" /* yacc.c:1648 */
+ { (yyval.s) = new blockStm((yyvsp[0].b)->getPos(), (yyvsp[0].b)); }
+#line 3120 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 192:
+#line 633 "camp.y" /* yacc.c:1648 */
+ { (yyval.run) = 0; }
+#line 3126 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 193:
+#line 634 "camp.y" /* yacc.c:1648 */
+ { (yyval.run) = (yyvsp[0].sel); }
+#line 3132 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 194:
+#line 635 "camp.y" /* yacc.c:1648 */
+ { (yyval.run) = (yyvsp[0].vd); }
+#line 3138 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 195:
+#line 639 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = 0; }
+#line 3144 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 196:
+#line 640 "camp.y" /* yacc.c:1648 */
+ { (yyval.e) = (yyvsp[0].e); }
+#line 3150 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 197:
+#line 644 "camp.y" /* yacc.c:1648 */
+ { (yyval.sel) = 0; }
+#line 3156 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 198:
+#line 645 "camp.y" /* yacc.c:1648 */
+ { (yyval.sel) = (yyvsp[0].sel); }
+#line 3162 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 199:
+#line 649 "camp.y" /* yacc.c:1648 */
+ { (yyval.sel) = new stmExpList((yyvsp[0].s)->getPos()); (yyval.sel)->add((yyvsp[0].s)); }
+#line 3168 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+ case 200:
+#line 651 "camp.y" /* yacc.c:1648 */
+ { (yyval.sel) = (yyvsp[-2].sel); (yyval.sel)->add((yyvsp[0].s)); }
+#line 3174 "camp.tab.c" /* yacc.c:1648 */
+ break;
+
+
+#line 3178 "camp.tab.c" /* yacc.c:1648 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
diff --git a/graphics/asymptote/camp.tab.h b/graphics/asymptote/camp.tab.h
new file mode 100644
index 0000000000..b3ffe25774
--- /dev/null
+++ b/graphics/asymptote/camp.tab.h
@@ -0,0 +1,171 @@
+/* A Bison parser, made by GNU Bison 3.0.5. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY_YY_CAMP_TAB_H_INCLUDED
+# define YY_YY_CAMP_TAB_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ ID = 258,
+ SELFOP = 259,
+ DOTS = 260,
+ COLONS = 261,
+ DASHES = 262,
+ INCR = 263,
+ LONGDASH = 264,
+ CONTROLS = 265,
+ TENSION = 266,
+ ATLEAST = 267,
+ CURL = 268,
+ COR = 269,
+ CAND = 270,
+ BAR = 271,
+ AMPERSAND = 272,
+ EQ = 273,
+ NEQ = 274,
+ LT = 275,
+ LE = 276,
+ GT = 277,
+ GE = 278,
+ CARETS = 279,
+ OPERATOR = 280,
+ LOOSE = 281,
+ ASSIGN = 282,
+ DIRTAG = 283,
+ JOIN_PREC = 284,
+ AND = 285,
+ ELLIPSIS = 286,
+ ACCESS = 287,
+ UNRAVEL = 288,
+ IMPORT = 289,
+ INCLUDE = 290,
+ FROM = 291,
+ QUOTE = 292,
+ STRUCT = 293,
+ TYPEDEF = 294,
+ NEW = 295,
+ IF = 296,
+ ELSE = 297,
+ WHILE = 298,
+ DO = 299,
+ FOR = 300,
+ BREAK = 301,
+ CONTINUE = 302,
+ RETURN_ = 303,
+ THIS = 304,
+ EXPLICIT = 305,
+ GARBAGE = 306,
+ LIT = 307,
+ STRING = 308,
+ PERM = 309,
+ MODIFIER = 310,
+ UNARY = 311,
+ EXP_IN_PARENS_RULE = 312
+ };
+#endif
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+union YYSTYPE
+{
+#line 60 "camp.y" /* yacc.c:1910 */
+
+ position pos;
+ bool boo;
+ struct {
+ position pos;
+ sym::symbol sym;
+ } ps;
+ absyntax::name *n;
+ absyntax::varinit *vi;
+ absyntax::arrayinit *ai;
+ absyntax::exp *e;
+ absyntax::stringExp *stre;
+ absyntax::specExp *se;
+ absyntax::joinExp *j;
+ absyntax::explist *elist;
+ absyntax::argument arg;
+ absyntax::arglist *alist;
+ absyntax::slice *slice;
+ absyntax::dimensions *dim;
+ absyntax::ty *t;
+ absyntax::decid *di;
+ absyntax::decidlist *dil;
+ absyntax::decidstart *dis;
+ absyntax::runnable *run;
+ struct {
+ position pos;
+ trans::permission val;
+ } perm;
+ struct {
+ position pos;
+ trans::modifier val;
+ } mod;
+ absyntax::modifierList *ml;
+ //absyntax::program *prog;
+ absyntax::vardec *vd;
+ //absyntax::vardecs *vds;
+ absyntax::dec *d;
+ absyntax::idpair *ip;
+ absyntax::idpairlist *ipl;
+ absyntax::stm *s;
+ absyntax::block *b;
+ absyntax::stmExpList *sel;
+ //absyntax::funheader *fh;
+ absyntax::formal *fl;
+ absyntax::formals *fls;
+
+#line 159 "camp.tab.h" /* yacc.c:1910 */
+};
+
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+int yyparse (void);
+
+#endif /* !YY_YY_CAMP_TAB_H_INCLUDED */
diff --git a/graphics/asymptote/camp.y b/graphics/asymptote/camp.y
new file mode 100644
index 0000000000..01bd47ecbc
--- /dev/null
+++ b/graphics/asymptote/camp.y
@@ -0,0 +1,652 @@
+%{
+/*****
+ * camp.y
+ * Andy Hammerlindl 08/12/2002
+ *
+ * The grammar of the camp language.
+ *****/
+
+#include "errormsg.h"
+#include "exp.h"
+#include "newexp.h"
+#include "dec.h"
+#include "fundec.h"
+#include "stm.h"
+#include "modifier.h"
+#include "opsymbols.h"
+
+// Avoid error messages with unpatched bison-1.875:
+#ifndef __attribute__
+#define __attribute__(x)
+#endif
+
+// Used when a position needs to be determined and no token is
+// available. Defined in camp.l.
+position lexerPos();
+
+bool lexerEOF();
+
+int yylex(void); /* function prototype */
+
+void yyerror(const char *s)
+{
+ if (!lexerEOF()) {
+ em.error(lexerPos());
+ em << s;
+ em.cont();
+ }
+}
+
+// Check if the symbol given is "keyword". Returns true in this case and
+// returns false and reports an error otherwise.
+bool checkKeyword(position pos, symbol sym)
+{
+ if (sym != symbol::trans("keyword")) {
+ em.error(pos);
+ em << "expected 'keyword' here";
+
+ return false;
+ }
+ return true;
+}
+
+namespace absyntax { file *root; }
+
+using namespace absyntax;
+using sym::symbol;
+using mem::string;
+%}
+
+%union {
+ position pos;
+ bool boo;
+ struct {
+ position pos;
+ sym::symbol sym;
+ } ps;
+ absyntax::name *n;
+ absyntax::varinit *vi;
+ absyntax::arrayinit *ai;
+ absyntax::exp *e;
+ absyntax::stringExp *stre;
+ absyntax::specExp *se;
+ absyntax::joinExp *j;
+ absyntax::explist *elist;
+ absyntax::argument arg;
+ absyntax::arglist *alist;
+ absyntax::slice *slice;
+ absyntax::dimensions *dim;
+ absyntax::ty *t;
+ absyntax::decid *di;
+ absyntax::decidlist *dil;
+ absyntax::decidstart *dis;
+ absyntax::runnable *run;
+ struct {
+ position pos;
+ trans::permission val;
+ } perm;
+ struct {
+ position pos;
+ trans::modifier val;
+ } mod;
+ absyntax::modifierList *ml;
+ //absyntax::program *prog;
+ absyntax::vardec *vd;
+ //absyntax::vardecs *vds;
+ absyntax::dec *d;
+ absyntax::idpair *ip;
+ absyntax::idpairlist *ipl;
+ absyntax::stm *s;
+ absyntax::block *b;
+ absyntax::stmExpList *sel;
+ //absyntax::funheader *fh;
+ absyntax::formal *fl;
+ absyntax::formals *fls;
+}
+
+%token <ps> ID SELFOP
+ DOTS COLONS DASHES INCR LONGDASH
+ CONTROLS TENSION ATLEAST CURL
+ COR CAND BAR AMPERSAND EQ NEQ LT LE GT GE CARETS
+ '+' '-' '*' '/' '%' '#' '^' OPERATOR
+%token <pos> LOOSE ASSIGN '?' ':'
+ DIRTAG JOIN_PREC AND
+ '{' '}' '(' ')' '.' ',' '[' ']' ';' ELLIPSIS
+ ACCESS UNRAVEL IMPORT INCLUDE FROM QUOTE STRUCT TYPEDEF NEW
+ IF ELSE WHILE DO FOR BREAK CONTINUE RETURN_
+ THIS EXPLICIT
+ GARBAGE
+%token <e> LIT
+%token <stre> STRING
+%token <perm> PERM
+%token <mod> MODIFIER
+
+%right ASSIGN SELFOP
+%right '?' ':'
+%left COR
+%left CAND
+%left BAR
+%left AMPERSAND
+%left EQ NEQ
+%left LT LE GT GE
+%left OPERATOR
+
+%left CARETS
+%left JOIN_PREC DOTS COLONS DASHES INCR LONGDASH
+%left DIRTAG CONTROLS TENSION ATLEAST AND
+%left CURL '{' '}'
+
+%left '+' '-'
+%left '*' '/' '%' '#' LIT
+%left UNARY
+%right '^'
+%left EXP_IN_PARENS_RULE
+%left '(' ')'
+
+%type <b> fileblock bareblock block
+%type <n> name
+%type <run> runnable
+%type <ml> modifiers
+%type <d> dec fundec typedec
+%type <ps> strid
+%type <ip> idpair stridpair
+%type <ipl> idpairlist stridpairlist
+%type <vd> vardec barevardec
+%type <t> type celltype
+%type <dim> dims
+%type <dil> decidlist
+%type <di> decid
+%type <dis> decidstart
+%type <vi> varinit
+%type <ai> arrayinit basearrayinit varinits
+%type <fl> formal
+%type <fls> formals
+%type <e> value exp fortest
+%type <arg> argument
+%type <slice> slice
+%type <j> join basicjoin
+%type <e> tension controls
+%type <se> dir
+%type <elist> dimexps
+%type <alist> arglist tuple
+%type <s> stm stmexp blockstm
+%type <run> forinit
+%type <sel> forupdate stmexplist
+%type <boo> explicitornot
+
+/* There are four shift/reduce conflicts:
+ * the dangling ELSE in IF (exp) IF (exp) stm ELSE stm
+ * new ID
+ * the argument id=exp is taken as an argument instead of an assignExp
+ * explicit cast
+ */
+%expect 4
+
+/* Enable grammar debugging. */
+/*%debug*/
+
+%%
+
+file:
+ fileblock { absyntax::root = $1; }
+;
+
+fileblock:
+ /* empty */ { $$ = new file(lexerPos(), false); }
+| fileblock runnable
+ { $$ = $1; $$->add($2); }
+;
+
+bareblock:
+ /* empty */ { $$ = new block(lexerPos(), true); }
+| bareblock runnable
+ { $$ = $1; $$->add($2); }
+;
+
+name:
+ ID { $$ = new simpleName($1.pos, $1.sym); }
+| name '.' ID { $$ = new qualifiedName($2, $1, $3.sym); }
+| '%' { $$ = new simpleName($1.pos,
+ symbol::trans("operator answer")); }
+;
+
+runnable:
+ dec { $$ = $1; }
+| stm { $$ = $1; }
+| modifiers dec
+ { $$ = new modifiedRunnable($1->getPos(), $1, $2); }
+| modifiers stm
+ { $$ = new modifiedRunnable($1->getPos(), $1, $2); }
+;
+
+modifiers:
+ MODIFIER { $$ = new modifierList($1.pos); $$->add($1.val); }
+| PERM { $$ = new modifierList($1.pos); $$->add($1.val); }
+| modifiers MODIFIER
+ { $$ = $1; $$->add($2.val); }
+| modifiers PERM
+ { $$ = $1; $$->add($2.val); }
+;
+
+dec:
+ vardec { $$ = $1; }
+| fundec { $$ = $1; }
+| typedec { $$ = $1; }
+| ACCESS stridpairlist ';'
+ { $$ = new accessdec($1, $2); }
+| FROM name UNRAVEL idpairlist ';'
+ { $$ = new unraveldec($1, $2, $4); }
+| FROM name UNRAVEL '*' ';'
+ { $$ = new unraveldec($1, $2, WILDCARD); }
+| UNRAVEL name ';' { $$ = new unraveldec($1, $2, WILDCARD); }
+| FROM strid ACCESS idpairlist ';'
+ { $$ = new fromaccessdec($1, $2.sym, $4); }
+| FROM strid ACCESS '*' ';'
+ { $$ = new fromaccessdec($1, $2.sym, WILDCARD); }
+| IMPORT stridpair ';'
+ { $$ = new importdec($1, $2); }
+| INCLUDE ID ';' { $$ = new includedec($1, $2.sym); }
+| INCLUDE STRING ';'
+ { $$ = new includedec($1, $2->getString()); }
+;
+
+idpair:
+ ID { $$ = new idpair($1.pos, $1.sym); }
+/* ID 'as' ID */
+| ID ID ID { $$ = new idpair($1.pos, $1.sym, $2.sym , $3.sym); }
+;
+
+idpairlist:
+ idpair { $$ = new idpairlist(); $$->add($1); }
+| idpairlist ',' idpair
+ { $$ = $1; $$->add($3); }
+;
+
+strid:
+ ID { $$ = $1; }
+| STRING { $$.pos = $1->getPos();
+ $$.sym = symbol::literalTrans($1->getString()); }
+;
+
+stridpair:
+ ID { $$ = new idpair($1.pos, $1.sym); }
+/* strid 'as' ID */
+| strid ID ID { $$ = new idpair($1.pos, $1.sym, $2.sym , $3.sym); }
+;
+
+stridpairlist:
+ stridpair { $$ = new idpairlist(); $$->add($1); }
+| stridpairlist ',' stridpair
+ { $$ = $1; $$->add($3); }
+;
+
+vardec:
+ barevardec ';' { $$ = $1; }
+;
+
+barevardec:
+ type decidlist { $$ = new vardec($1->getPos(), $1, $2); }
+;
+
+type:
+ celltype { $$ = $1; }
+| name dims { $$ = new arrayTy($1, $2); }
+;
+
+celltype:
+ name { $$ = new nameTy($1); }
+;
+
+dims:
+ '[' ']' { $$ = new dimensions($1); }
+| dims '[' ']' { $$ = $1; $$->increase(); }
+;
+
+dimexps:
+ '[' exp ']' { $$ = new explist($1); $$->add($2); }
+| dimexps '[' exp ']'
+ { $$ = $1; $$->add($3); }
+;
+
+decidlist:
+ decid { $$ = new decidlist($1->getPos()); $$->add($1); }
+| decidlist ',' decid
+ { $$ = $1; $$->add($3); }
+;
+
+decid:
+ decidstart { $$ = new decid($1->getPos(), $1); }
+| decidstart ASSIGN varinit
+ { $$ = new decid($1->getPos(), $1, $3); }
+;
+
+decidstart:
+ ID { $$ = new decidstart($1.pos, $1.sym); }
+| ID dims { $$ = new decidstart($1.pos, $1.sym, $2); }
+| ID '(' ')' { $$ = new fundecidstart($1.pos, $1.sym, 0,
+ new formals($2)); }
+| ID '(' formals ')'
+ { $$ = new fundecidstart($1.pos, $1.sym, 0, $3); }
+;
+
+varinit:
+ exp { $$ = $1; }
+| arrayinit { $$ = $1; }
+;
+
+block:
+ '{' bareblock '}'
+ { $$ = $2; }
+;
+
+arrayinit:
+ '{' '}' { $$ = new arrayinit($1); }
+| '{' ELLIPSIS varinit '}'
+ { $$ = new arrayinit($1); $$->addRest($3); }
+| '{' basearrayinit '}'
+ { $$ = $2; }
+| '{' basearrayinit ELLIPSIS varinit '}'
+ { $$ = $2; $$->addRest($4); }
+;
+
+basearrayinit:
+ ',' { $$ = new arrayinit($1); }
+| varinits { $$ = $1; }
+| varinits ',' { $$ = $1; }
+;
+
+varinits:
+ varinit { $$ = new arrayinit($1->getPos());
+ $$->add($1);}
+| varinits ',' varinit
+ { $$ = $1; $$->add($3); }
+;
+
+formals:
+ formal { $$ = new formals($1->getPos()); $$->add($1); }
+| ELLIPSIS formal { $$ = new formals($1); $$->addRest($2); }
+| formals ',' formal
+ { $$ = $1; $$->add($3); }
+| formals ELLIPSIS formal
+ { $$ = $1; $$->addRest($3); }
+;
+
+explicitornot:
+ EXPLICIT { $$ = true; }
+| { $$ = false; }
+;
+
+formal:
+ explicitornot type
+ { $$ = new formal($2->getPos(), $2, 0, 0, $1, 0); }
+| explicitornot type decidstart
+ { $$ = new formal($2->getPos(), $2, $3, 0, $1, 0); }
+| explicitornot type decidstart ASSIGN varinit
+ { $$ = new formal($2->getPos(), $2, $3, $5, $1, 0); }
+/* The uses of ID below are 'keyword' qualifiers before the parameter name. */
+| explicitornot type ID decidstart
+ { bool k = checkKeyword($3.pos, $3.sym);
+ $$ = new formal($2->getPos(), $2, $4, 0, $1, k); }
+| explicitornot type ID decidstart ASSIGN varinit
+ { bool k = checkKeyword($3.pos, $3.sym);
+ $$ = new formal($2->getPos(), $2, $4, $6, $1, k); }
+;
+
+fundec:
+ type ID '(' ')' blockstm
+ { $$ = new fundec($3, $1, $2.sym, new formals($3), $5); }
+| type ID '(' formals ')' blockstm
+ { $$ = new fundec($3, $1, $2.sym, $4, $6); }
+;
+
+typedec:
+ STRUCT ID block { $$ = new recorddec($1, $2.sym, $3); }
+| TYPEDEF vardec { $$ = new typedec($1, $2); }
+;
+
+slice:
+ ':' { $$ = new slice($1, 0, 0); }
+| exp ':' { $$ = new slice($2, $1, 0); }
+| ':' exp { $$ = new slice($1, 0, $2); }
+| exp ':' exp { $$ = new slice($2, $1, $3); }
+;
+
+value:
+ value '.' ID { $$ = new fieldExp($2, $1, $3.sym); }
+| name '[' exp ']' { $$ = new subscriptExp($2,
+ new nameExp($1->getPos(), $1), $3); }
+| value '[' exp ']'{ $$ = new subscriptExp($2, $1, $3); }
+| name '[' slice ']' { $$ = new sliceExp($2,
+ new nameExp($1->getPos(), $1), $3); }
+| value '[' slice ']'{ $$ = new sliceExp($2, $1, $3); }
+| name '(' ')' { $$ = new callExp($2,
+ new nameExp($1->getPos(), $1),
+ new arglist()); }
+| name '(' arglist ')'
+ { $$ = new callExp($2,
+ new nameExp($1->getPos(), $1),
+ $3); }
+| value '(' ')' { $$ = new callExp($2, $1, new arglist()); }
+| value '(' arglist ')'
+ { $$ = new callExp($2, $1, $3); }
+| '(' exp ')' %prec EXP_IN_PARENS_RULE
+ { $$ = $2; }
+| '(' name ')' %prec EXP_IN_PARENS_RULE
+ { $$ = new nameExp($2->getPos(), $2); }
+| THIS { $$ = new thisExp($1); }
+;
+
+argument:
+ exp { $$.name = symbol::nullsym; $$.val=$1; }
+| ID ASSIGN exp { $$.name = $1.sym; $$.val=$3; }
+;
+
+arglist:
+ argument { $$ = new arglist(); $$->add($1); }
+| ELLIPSIS argument
+ { $$ = new arglist(); $$->addRest($2); }
+| arglist ',' argument
+ { $$ = $1; $$->add($3); }
+| arglist ELLIPSIS argument
+ { $$ = $1; $$->addRest($3); }
+;
+
+/* A list of two or more expressions, separated by commas. */
+tuple:
+ exp ',' exp { $$ = new arglist(); $$->add($1); $$->add($3); }
+| tuple ',' exp { $$ = $1; $$->add($3); }
+;
+
+exp:
+ name { $$ = new nameExp($1->getPos(), $1); }
+| value { $$ = $1; }
+| LIT { $$ = $1; }
+| STRING { $$ = $1; }
+/* This is for scaling expressions such as 105cm */
+| LIT exp { $$ = new scaleExp($1->getPos(), $1, $2); }
+| '(' name ')' exp
+ { $$ = new castExp($2->getPos(), new nameTy($2), $4); }
+| '(' name dims ')' exp
+ { $$ = new castExp($2->getPos(), new arrayTy($2, $3), $5); }
+| '+' exp %prec UNARY
+ { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| '-' exp %prec UNARY
+ { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| OPERATOR exp { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| exp '+' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '-' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '*' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '/' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '%' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '#' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '^' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp LT exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp LE exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp GT exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp GE exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp EQ exp { $$ = new equalityExp($2.pos, $1, $2.sym, $3); }
+| exp NEQ exp { $$ = new equalityExp($2.pos, $1, $2.sym, $3); }
+| exp CAND exp { $$ = new andExp($2.pos, $1, $2.sym, $3); }
+| exp COR exp { $$ = new orExp($2.pos, $1, $2.sym, $3); }
+| exp CARETS exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp AMPERSAND exp{ $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp BAR exp{ $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp OPERATOR exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp INCR exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| NEW celltype
+ { $$ = new newRecordExp($1, $2); }
+| NEW celltype dimexps
+ { $$ = new newArrayExp($1, $2, $3, 0, 0); }
+| NEW celltype dimexps dims
+ { $$ = new newArrayExp($1, $2, $3, $4, 0); }
+| NEW celltype dims
+ { $$ = new newArrayExp($1, $2, 0, $3, 0); }
+| NEW celltype dims arrayinit
+ { $$ = new newArrayExp($1, $2, 0, $3, $4); }
+| NEW celltype '(' ')' blockstm
+ { $$ = new newFunctionExp($1, $2, new formals($3), $5); }
+| NEW celltype dims '(' ')' blockstm
+ { $$ = new newFunctionExp($1,
+ new arrayTy($2->getPos(), $2, $3),
+ new formals($4),
+ $6); }
+| NEW celltype '(' formals ')' blockstm
+ { $$ = new newFunctionExp($1, $2, $4, $6); }
+| NEW celltype dims '(' formals ')' blockstm
+ { $$ = new newFunctionExp($1,
+ new arrayTy($2->getPos(), $2, $3),
+ $5,
+ $7); }
+| exp '?' exp ':' exp
+ { $$ = new conditionalExp($2, $1, $3, $5); }
+| exp ASSIGN exp { $$ = new assignExp($2, $1, $3); }
+| '(' tuple ')' { $$ = new callExp($1, new nameExp($1, SYM_TUPLE), $2); }
+| exp join exp %prec JOIN_PREC
+ { $2->pushFront($1); $2->pushBack($3); $$ = $2; }
+| exp dir %prec DIRTAG
+ { $2->setSide(camp::OUT);
+ joinExp *jexp =
+ new joinExp($2->getPos(), SYM_DOTS);
+ $$=jexp;
+ jexp->pushBack($1); jexp->pushBack($2); }
+| INCR exp %prec UNARY
+ { $$ = new prefixExp($1.pos, $2, SYM_PLUS); }
+| DASHES exp %prec UNARY
+ { $$ = new prefixExp($1.pos, $2, SYM_MINUS); }
+/* Illegal - will be caught during translation. */
+| exp INCR %prec UNARY
+ { $$ = new postfixExp($2.pos, $1, SYM_PLUS); }
+| exp SELFOP exp { $$ = new selfExp($2.pos, $1, $2.sym, $3); }
+| QUOTE '{' fileblock '}'
+ { $$ = new quoteExp($1, $3); }
+;
+
+// This verbose definition is because leaving empty as an expansion for dir
+// made a whack of reduce/reduce errors.
+join:
+ DASHES { $$ = new joinExp($1.pos,$1.sym); }
+| basicjoin %prec JOIN_PREC
+ { $$ = $1; }
+| dir basicjoin %prec JOIN_PREC
+ { $1->setSide(camp::OUT);
+ $$ = $2; $$->pushFront($1); }
+| basicjoin dir %prec JOIN_PREC
+ { $2->setSide(camp::IN);
+ $$ = $1; $$->pushBack($2); }
+| dir basicjoin dir %prec JOIN_PREC
+ { $1->setSide(camp::OUT); $3->setSide(camp::IN);
+ $$ = $2; $$->pushFront($1); $$->pushBack($3); }
+;
+
+dir:
+ '{' CURL exp '}' { $$ = new specExp($2.pos, $2.sym, $3); }
+| '{' exp '}' { $$ = new specExp($1, symbol::opTrans("spec"), $2); }
+| '{' exp ',' exp '}'
+ { $$ = new specExp($1, symbol::opTrans("spec"),
+ new pairExp($3, $2, $4)); }
+| '{' exp ',' exp ',' exp '}'
+ { $$ = new specExp($1, symbol::opTrans("spec"),
+ new tripleExp($3, $2, $4, $6)); }
+;
+
+basicjoin:
+ DOTS { $$ = new joinExp($1.pos, $1.sym); }
+| DOTS tension DOTS
+ { $$ = new joinExp($1.pos, $1.sym); $$->pushBack($2); }
+| DOTS controls DOTS
+ { $$ = new joinExp($1.pos, $1.sym); $$->pushBack($2); }
+| COLONS { $$ = new joinExp($1.pos, $1.sym); }
+| LONGDASH { $$ = new joinExp($1.pos, $1.sym); }
+;
+
+tension:
+ TENSION exp { $$ = new binaryExp($1.pos, $2, $1.sym,
+ new booleanExp($1.pos, false)); }
+| TENSION exp AND exp
+ { $$ = new ternaryExp($1.pos, $2, $1.sym, $4,
+ new booleanExp($1.pos, false)); }
+| TENSION ATLEAST exp
+ { $$ = new binaryExp($1.pos, $3, $1.sym,
+ new booleanExp($2.pos, true)); }
+| TENSION ATLEAST exp AND exp
+ { $$ = new ternaryExp($1.pos, $3, $1.sym, $5,
+ new booleanExp($2.pos, true)); }
+;
+
+controls:
+ CONTROLS exp { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| CONTROLS exp AND exp
+ { $$ = new binaryExp($1.pos, $2, $1.sym, $4); }
+;
+
+stm:
+ ';' { $$ = new emptyStm($1); }
+| blockstm { $$ = $1; }
+| stmexp ';' { $$ = $1; }
+| IF '(' exp ')' stm
+ { $$ = new ifStm($1, $3, $5); }
+| IF '(' exp ')' stm ELSE stm
+ { $$ = new ifStm($1, $3, $5, $7); }
+| WHILE '(' exp ')' stm
+ { $$ = new whileStm($1, $3, $5); }
+| DO stm WHILE '(' exp ')' ';'
+ { $$ = new doStm($1, $2, $5); }
+| FOR '(' forinit ';' fortest ';' forupdate ')' stm
+ { $$ = new forStm($1, $3, $5, $7, $9); }
+| FOR '(' type ID ':' exp ')' stm
+ { $$ = new extendedForStm($1, $3, $4.sym, $6, $8); }
+| BREAK ';' { $$ = new breakStm($1); }
+| CONTINUE ';' { $$ = new continueStm($1); }
+| RETURN_ ';' { $$ = new returnStm($1); }
+| RETURN_ exp ';' { $$ = new returnStm($1, $2); }
+;
+
+stmexp:
+ exp { $$ = new expStm($1->getPos(), $1); }
+;
+
+blockstm:
+ block { $$ = new blockStm($1->getPos(), $1); }
+;
+
+forinit:
+ /* empty */ { $$ = 0; }
+| stmexplist { $$ = $1; }
+| barevardec { $$ = $1; }
+;
+
+fortest:
+ /* empty */ { $$ = 0; }
+| exp { $$ = $1; }
+;
+
+forupdate:
+ /* empty */ { $$ = 0; }
+| stmexplist { $$ = $1; }
+;
+
+stmexplist:
+ stmexp { $$ = new stmExpList($1->getPos()); $$->add($1); }
+| stmexplist ',' stmexp
+ { $$ = $1; $$->add($3); }
+;
diff --git a/graphics/asymptote/camperror.cc b/graphics/asymptote/camperror.cc
new file mode 100644
index 0000000000..8fb782b415
--- /dev/null
+++ b/graphics/asymptote/camperror.cc
@@ -0,0 +1,64 @@
+/*****
+ * camperror.cc
+ * 2003/02/25 Andy Hammerlindl
+ *
+ * Provides a way for the classes in camp to report errors in
+ * computation elegantly. After running a method on a camp object that
+ * could encounter an error, the program should call camp::errors to see
+ * if any errors were encountered.
+ *****/
+
+#include <cassert>
+#include <sstream>
+
+#include "camperror.h"
+#include "vm.h"
+#include "errormsg.h"
+
+namespace camp {
+
+// Used internally to report an error in an operation.
+void reportError(const string& desc)
+{
+ em.runtime(vm::getPos());
+ em << desc;
+ em.sync();
+ throw handled_error();
+}
+
+// Used internally to report a warning in an operation.
+void reportWarning(const string& desc)
+{
+ em.warning(vm::getPos());
+ em << desc;
+ em.sync();
+}
+
+void reportFatal(const string& desc)
+{
+ em.fatal(vm::getPos());
+ em << desc;
+ em.sync();
+ em.statusError();
+ try {
+ throw quit();
+ } catch(handled_error) {
+ }
+}
+
+void reportError(const ostringstream& desc)
+{
+ reportError(desc.str());
+}
+
+void reportWarning(const ostringstream& desc)
+{
+ reportWarning(desc.str());
+}
+
+void reportFatal(const ostringstream& desc)
+{
+ reportFatal(desc.str());
+}
+
+} // namespace camp
diff --git a/graphics/asymptote/camperror.h b/graphics/asymptote/camperror.h
new file mode 100644
index 0000000000..b6adaaf63f
--- /dev/null
+++ b/graphics/asymptote/camperror.h
@@ -0,0 +1,34 @@
+/*****
+ * camperror.h
+ * 2003/02/25 Andy Hammerlindl
+ *
+ * Provides a way for the classes in camp to report errors in
+ * computation elegantly. After running a method on a camp object that
+ * could encounter an error, the program should call camp::errors to see
+ * if any errors were encountered.
+ *****/
+
+#ifndef CAMPERROR_H
+#define CAMPERROR_H
+
+#include <iostream>
+
+#include "common.h"
+
+namespace camp {
+
+// Used internally to report an error in an operation.
+void reportError(const string& desc);
+void reportError(const ostringstream& desc);
+
+void reportWarning(const string& desc);
+void reportWarning(const ostringstream& desc);
+
+void reportFatal(const string& desc);
+void reportFatal(const ostringstream& desc);
+
+inline std::ostream& newl(std::ostream& s) {s << '\n'; return s;}
+
+} // namespace camp
+
+#endif
diff --git a/graphics/asymptote/castop.h b/graphics/asymptote/castop.h
new file mode 100644
index 0000000000..1c788687ab
--- /dev/null
+++ b/graphics/asymptote/castop.h
@@ -0,0 +1,216 @@
+/*****
+ * castop.h
+ * Tom Prince 2005/3/18
+ *
+ * Defines some runtime functions used by the stack machine.
+ *
+ *****/
+
+#ifndef CASTOP_H
+#define CASTOP_H
+
+#include <cfloat>
+
+#include "common.h"
+#include "stack.h"
+#include "fileio.h"
+#include "lexical.h"
+#include "mathop.h"
+#include "array.h"
+
+namespace run {
+
+using vm::read;
+using vm::pop;
+
+template<class T, class S>
+void cast(vm::stack *s)
+{
+ s->push((S) pop<T>(s));
+}
+
+void castDoubleInt(vm::stack *s)
+{
+ double x=pop<double>(s);
+ s->push(Intcast(x));
+}
+
+template<class T>
+void stringCast(vm::stack *s)
+{
+ ostringstream buf;
+ buf.precision(DBL_DIG);
+ buf << pop<T>(s);
+ s->push(buf.str());
+}
+
+template<class T>
+void castString(vm::stack *s)
+{
+ string *S=pop<string*>(s);
+ if(S->empty()) {
+ T x=0;
+ s->push(x);
+ } else {
+ try {
+ s->push(lexical::cast<T>(*S));
+ } catch (lexical::bad_cast&) {
+ s->push(vm::Default);
+ }
+ }
+}
+
+void initialized(vm::stack *s)
+{
+ s->push(!vm::isdefault(pop(s)));
+}
+
+template<class T, class S>
+void arrayToArray(vm::stack *s)
+{
+ vm::array *a=pop<vm::array*>(s);
+ size_t size=checkArray(a);
+ vm::array *c=new vm::array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=(S) read<T>(a,i);
+ s->push(c);
+}
+
+template<class T, class S>
+void array2ToArray2(vm::stack *s)
+{
+ vm::array *a=pop<vm::array*>(s);
+ size_t size=checkArray(a);
+ vm::array *c=new vm::array(size);
+ for(size_t i=0; i < size; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t aisize=checkArray(ai);
+ vm::array *ci=new vm::array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; ++j)
+ (*ci)[j]=(S) read<T>(ai,j);
+ }
+ s->push(c);
+}
+
+template<class T>
+void read(vm::stack *s)
+{
+ camp::file *f = pop<camp::file*>(s);
+ T val=T();
+ if(f->isOpen()) {
+ f->read(val);
+ if(f->LineMode()) f->nexteol();
+ if(interact::interactive) f->purgeStandard(val);
+ }
+ s->push(val);
+}
+
+inline Int Limit(Int nx) {return nx == 0 ? Int_MAX : nx;}
+inline void reportEof(camp::file *f, Int count)
+{
+ if(count > 0) {
+ ostringstream buf;
+ buf << "EOF after reading " << count
+ << " values from file '" << f->filename() << "'.";
+ vm::error(buf);
+ }
+}
+
+template<class T>
+void readArray(vm::stack *s, Int nx=-1, Int ny=-1, Int nz=-1)
+{
+ camp::file *f = pop<camp::file*>(s);
+ vm::array *c=new vm::array(0);
+ if(f->isOpen()) {
+ if(nx != -1 && f->Nx() != -1) nx=f->Nx();
+ if(nx == -2) {f->read(nx); f->Nx(-1); if(nx == 0) {s->push(c); return;}}
+ if(ny != -1 && f->Ny() != -1) ny=f->Ny();
+ if(ny == -2) {f->read(ny); f->Ny(-1); if(ny == 0) {s->push(c); return;}}
+ if(nz != -1 && f->Nz() != -1) nz=f->Nz();
+ if(nz == -2) {f->read(nz); f->Nz(-1); if(nz == 0) {s->push(c); return;}}
+ T v;
+ if(nx >= 0) {
+ for(Int i=0; i < Limit(nx); i++) {
+ if(ny >= 0) {
+ vm::array *ci=new vm::array(0);
+ for(Int j=0; j < Limit(ny); j++) {
+ if(nz >= 0) {
+ vm::array *cij=new vm::array(0);
+ bool break2=false;
+ for(Int k=0; k < Limit(nz); k++) {
+ f->read(v);
+ if(f->error()) {
+ if(nx && ny && nz) reportEof(f,(i*ny+j)*nz+k);
+ s->push(c);
+ return;
+ }
+ if(k == 0) {
+ if(j == 0) c->push(ci);
+ ci->push(cij);
+ }
+ cij->push(v);
+ if(f->LineMode() && f->nexteol()) {
+ if(f->nexteol()) break2=true;
+ break;
+ }
+ }
+ if(break2) break;
+ } else {
+ f->read(v);
+ if(f->error()) {
+ if(nx && ny) reportEof(f,i*ny+j);
+ s->push(c);
+ return;
+ }
+ if(j == 0) c->push(ci);
+ ci->push(v);
+ if(f->LineMode() && f->nexteol()) break;
+ }
+ }
+ } else {
+ f->read(v);
+ if(f->error()) {
+ if(nx) reportEof(f,i);
+ s->push(c);
+ return;
+ }
+ c->push(v);
+ if(f->LineMode() && f->nexteol()) break;
+ }
+ }
+ } else {
+ for(;;) {
+ f->read(v);
+ if(f->error()) break;
+ c->push(v);
+ if(f->LineMode() && f->nexteol()) break;
+ }
+ }
+ if(interact::interactive) f->purgeStandard(v);
+ }
+ s->push(c);
+}
+
+template<class T>
+void readArray1(vm::stack *s)
+{
+ readArray<T>(s,0);
+}
+
+template<class T>
+void readArray2(vm::stack *s)
+{
+ readArray<T>(s,0,0);
+}
+
+template<class T>
+void readArray3(vm::stack *s)
+{
+ readArray<T>(s,0,0,0);
+}
+
+} // namespace run
+
+#endif // CASTOP_H
+
diff --git a/graphics/asymptote/coder.cc b/graphics/asymptote/coder.cc
new file mode 100644
index 0000000000..02bb27599f
--- /dev/null
+++ b/graphics/asymptote/coder.cc
@@ -0,0 +1,376 @@
+/*****
+ * coder.cc
+ * Andy Hammerlindl 2004/11/06
+ *
+ * Handles encoding of syntax into programs. It's methods are called by
+ * abstract syntax objects during translation to construct the virtual machine
+ * code.
+ *****/
+
+#include <utility>
+
+#include "errormsg.h"
+#include "coder.h"
+#include "genv.h"
+#include "entry.h"
+#include "builtin.h"
+
+using namespace sym;
+using namespace types;
+
+namespace trans {
+
+namespace {
+function *inittype();
+function *bootuptype();
+}
+
+vm::lambda *newLambda(string name) {
+ assert(!name.empty());
+ vm::lambda *l = new vm::lambda;
+#ifdef DEBUG_FRAME
+ l->name = name;
+#endif
+ return l;
+}
+
+
+// Used purely for global variables and static code blocks of file
+// level modules.
+coder::coder(position pos, string name, modifier sord)
+#if SIMPLE_FRAME
+ : level(frame::indirect_frame(name)),
+#else
+ : level(new frame(name, 0, 0)),
+#endif
+ recordLevel(0),
+ recordType(0),
+ isCodelet(false),
+ l(newLambda(name)),
+ funtype(bootuptype()),
+ parent(0),
+ sord(sord),
+ perm(DEFAULT_PERM),
+ program(new vm::program),
+ curPos(pos)
+{
+ sord_stack.push(sord);
+}
+
+// Defines a new function environment.
+coder::coder(position pos, string name, function *t, coder *parent,
+ modifier sord, bool reframe)
+ : level(reframe ? new frame(name,
+ parent->getFrame(),
+ t->sig.getNumFormals()) :
+ parent->getFrame()),
+ recordLevel(parent->recordLevel),
+ recordType(parent->recordType),
+ isCodelet(!reframe),
+ l(newLambda(name)),
+ funtype(t),
+ parent(parent),
+ sord(sord),
+ perm(DEFAULT_PERM),
+ program(new vm::program),
+ curPos(pos)
+{
+ sord_stack.push(sord);
+}
+
+// Start encoding the body of the record. The function being encoded
+// is the record's initializer.
+coder::coder(position pos, record *t, coder *parent, modifier sord)
+ : level(t->getLevel()),
+ recordLevel(t->getLevel()),
+ recordType(t),
+ isCodelet(false),
+ l(t->getInit()),
+ funtype(inittype()),
+ parent(parent),
+ sord(sord),
+ perm(DEFAULT_PERM),
+ program(new vm::program),
+ curPos(pos)
+{
+ sord_stack.push(sord);
+}
+
+coder coder::newFunction(position pos, string name, function *t, modifier sord)
+{
+ return coder(pos, name, t, this, sord);
+}
+
+coder coder::newCodelet(position pos)
+{
+ return coder(pos, "<codelet>", new function(primVoid()), this,
+ DEFAULT_DYNAMIC, false);
+}
+
+record *coder::newRecord(symbol id)
+{
+ frame *underlevel = getFrame();
+
+ frame *level = new frame(id, underlevel, 0);
+
+ record *r = new record(id, level);
+
+ return r;
+}
+
+coder coder::newRecordInit(position pos, record *r, modifier sord)
+{
+ return coder(pos, r, this, sord);
+}
+
+#ifdef DEBUG_BLTIN
+void assertBltinLookup(inst::opcode op, item it)
+{
+ if (op == inst::builtin) {
+ string name=lookupBltin(vm::get<vm::bltin>(it));
+ assert(!name.empty());
+ }
+}
+#endif
+
+
+void coder::encodePop()
+{
+ if (isStatic() && !isTopLevel()) {
+ assert(parent);
+ parent->encodePop();
+ }
+ else {
+#ifdef COMBO
+ vm::program::label end = program->end();
+ --end;
+ inst& lastInst = *end;
+ if (lastInst.op == inst::varsave) {
+ lastInst.op = inst::varpop;
+ return;
+ }
+ if (lastInst.op == inst::fieldsave) {
+ lastInst.op = inst::fieldpop;
+ return;
+ }
+ // TODO: push+pop into no op.
+#endif
+
+ // No combo applicable. Just encode a usual pop.
+ encode(inst::pop);
+ }
+}
+
+
+bool coder::encode(frame *f)
+{
+ frame *toplevel = getFrame();
+
+ if (f == 0) {
+ encode(inst::constpush,(item)0);
+ return true;
+ }
+ else if (f == toplevel) {
+ encode(inst::pushclosure);
+ return true;
+ }
+ else {
+ encode(inst::varpush,toplevel->parentIndex());
+ return encode(f, toplevel->getParent());
+ }
+}
+
+bool coder::encode(frame *dest, frame *top)
+{
+ if (dest == 0) {
+ // Change to encodePop?
+ encode(inst::pop);
+ encode(inst::constpush,(item)0);
+ }
+ else {
+ frame *level = top;
+ while (level != dest) {
+ if (level == 0) {
+ // Frame request was in an improper scope.
+ return false;
+ }
+
+ encode(inst::fieldpush, level->parentIndex());
+
+ level = level->getParent();
+ }
+ }
+
+ //cerr << "succeeded\n";
+ return true;
+}
+
+vm::program::label coder::encodeEmptyJump(inst::opcode op)
+{
+ // Get the end position before encoding the label. Once encoded, this will
+ // point to the instruction.
+ vm::program::label pos = program->end();
+
+ encode(op);
+
+ return pos;
+}
+
+void replaceEmptyJump(vm::program::label from, vm::program::label to)
+{
+ from->ref = to;
+}
+
+label coder::defNewLabel()
+{
+ if (isStatic())
+ return parent->defNewLabel();
+
+ label l = new label_t();
+ assert(!l->location.defined());
+ assert(!l->firstUse.defined());
+ return defLabel(l);
+}
+
+label coder::defLabel(label label)
+{
+ if (isStatic())
+ return parent->defLabel(label);
+
+ //cout << "defining label " << label << endl;
+
+ assert(!label->location.defined());
+ //vm::program::label here = program->end();
+ label->location = program->end();
+ assert(label->location.defined());
+
+ if (label->firstUse.defined()) {
+ replaceEmptyJump(label->firstUse, program->end());
+ //vm::printInst(cout, label->firstUse, program->begin());
+ //cout << endl;
+
+ if (label->moreUses) {
+ typedef label_t::useVector useVector;
+ useVector& v = *label->moreUses;
+ for (useVector::iterator p = v.begin(); p != v.end(); ++p) {
+ replaceEmptyJump(*p, program->end());
+ }
+ }
+ }
+
+ return label;
+}
+
+
+void coder::useLabel(inst::opcode op, label label)
+{
+ if (isStatic())
+ return parent->useLabel(op,label);
+
+ if (label->location.defined()) {
+ encode(op, label->location);
+ } else {
+ if (label->firstUse.defined()) {
+ // Store additional uses in the moreUses array.
+ if (!label->moreUses)
+ label->moreUses = new label_t::useVector;
+ label->moreUses->push_back(encodeEmptyJump(op));
+ }
+ else {
+ label->firstUse = encodeEmptyJump(op);
+ assert(label->firstUse.defined());
+ assert(!label->location.defined());
+ }
+ }
+}
+label coder::fwdLabel()
+{
+ if (isStatic())
+ return parent->fwdLabel();
+
+ // Create a new label without specifying its position.
+ label l = new label_t();
+ assert(!l->location.defined());
+ assert(!l->firstUse.defined());
+
+ //cout << "forward label " << l << endl;
+
+ return l;
+}
+
+bool coder::usesClosureSinceLabel(label l)
+{
+ assert(l->location.defined());
+ for (vm::program::label i = l->location; i != program->end(); ++i)
+ if (i->op == inst::pushclosure)
+ return true;
+ return false;
+}
+
+void coder::encodePatch(label from, label to)
+{
+ assert(from->location.defined());
+ assert(to->location.defined());
+
+ assert(from->location->op == inst::nop);
+
+ from->location->op = inst::jmp;
+ from->location->ref = to->location;
+}
+
+void coder::markPos(position pos)
+{
+ curPos = pos;
+}
+
+// When translating the function is finished, this ties up loose ends
+// and returns the lambda.
+vm::lambda *coder::close() {
+ // These steps must be done dynamically, not statically.
+ sord = EXPLICIT_DYNAMIC;
+ sord_stack.push(sord);
+
+ // Add a return for void types; may be redundant.
+ if (funtype->result->kind == types::ty_void)
+ encode(inst::ret);
+
+ l->code = program;
+
+ l->parentIndex = level->parentIndex();
+
+ l->framesize = level->size();
+
+ sord_stack.pop();
+ sord = sord_stack.top();
+
+ return l;
+}
+
+void coder::closeRecord()
+{
+ // Put record into finished state.
+ encode(inst::pushclosure);
+ close();
+}
+
+bool coder::isRecord()
+{
+ return (funtype==inittype());
+}
+
+namespace {
+function *inittype()
+{
+ static function t(types::primVoid());
+ return &t;
+}
+
+function *bootuptype()
+{
+ static function t(types::primVoid());
+ return &t;
+}
+} // private
+
+} // namespace trans
+
diff --git a/graphics/asymptote/coder.h b/graphics/asymptote/coder.h
new file mode 100644
index 0000000000..df44b0310e
--- /dev/null
+++ b/graphics/asymptote/coder.h
@@ -0,0 +1,428 @@
+/*****
+ * coder.h
+ * Andy Hammerlindl 2004/11/06
+ *
+ * Handles encoding of syntax into programs. It's methods are called by
+ * abstract syntax objects during translation to construct the virtual machine
+ * code.
+ *****/
+
+#ifndef CODER_H
+#define CODER_H
+
+#include "errormsg.h"
+#include "entry.h"
+#include "types.h"
+#include "record.h"
+#include "frame.h"
+#include "program.h"
+#include "util.h"
+#include "modifier.h"
+#include "inst.h"
+
+namespace trans {
+
+using sym::symbol;
+using types::ty;
+using types::function;
+using types::record;
+
+using vm::bltin;
+using vm::inst;
+using vm::item;
+
+#ifdef DEBUG_BLTIN
+void assertBltinLookup(inst::opcode op, item it);
+#endif
+
+// Labels used by the coder class to denote where in the code a jump
+// instruction should go to. Label can be used before their exact location is
+// known.
+// Declared outside of the coder class, so that it can be declared in exp.h.
+struct label_t : public gc {
+ vm::program::label location;
+ vm::program::label firstUse;
+
+ // Most labels are used only once, and so we optimize for that case. We do,
+ // however, have to handle labels which are used multiple times (such as
+ // break locations in a loop), and so a useVector is allocated to store
+ // these if necessary.
+ typedef mem::vector<vm::program::label> useVector;
+ useVector *moreUses;
+
+ // Only the constructor is defined. Everything else is handles by methods
+ // of the coder class.
+ label_t() : location(), firstUse(), moreUses(0) {}
+};
+typedef label_t *label;
+
+class coder {
+ // The frame of the function we are currently encoding. This keeps
+ // track of local variables, and parameters with respect to the stack.
+ frame *level;
+
+ // The frame of the enclosing record that the "this" expression yields. ie.
+ // the highest frame that is a record, not a function.
+ frame *recordLevel;
+
+ // The type of the enclosing record. Also needed for the "this" expression.
+ record *recordType;
+
+ // Are we translating a codelet?
+ bool isCodelet;
+
+ // The lambda being constructed. In some cases, this lambda is needed
+ // before full translation of the function, so it is stored,
+ // incomplete, here.
+ vm::lambda *l;
+
+ // The type of the function being translated.
+ const function *funtype;
+
+ // The enclosing environment. Null if this is a file-level module.
+ coder *parent;
+
+ // The mode of encoding, either static or dynamic. sord is used as an
+ // acronym for Static OR Dynamic.
+ // Once something is static, no amount of dynamic modifiers can change
+ // that, so once a stack is EXPLICIT_STATIC, additional modifiers will
+ // be pushed on as EXPLICIT_STATIC.
+ modifier sord;
+ std::stack<modifier> sord_stack;
+
+ // What permissions will be given to a new access.
+ // TODO: Ensure private fields don't show up calling lookup for a
+ // record.
+ permission perm;
+
+ // The function code as its being written. Code points to next place in
+ // array to write.
+ vm::program *program;
+
+ // Some loops allocate nested frames, in case variables in an
+ // iteration escape in a closure. This stack keeps track of where the
+ // pushframe instructions are, so the size of the frame can be encoded.
+ std::stack<vm::program::label> pushframeLabels;
+
+ // Loops need to store labels to where break and continue statements
+ // should pass control. Since loops can be nested, this needs to
+ // be stored as a stack. We also store which of the loops are being encoded
+ // with an additional frame for variables. This is needed to know if the
+ // break and continue statements need to pop the frame.
+ struct loopdata_t : gc {
+ label continueLabel;
+ label breakLabel;
+ bool pushedFrame;
+
+ loopdata_t(label c, label b)
+ : continueLabel(c), breakLabel(b), pushedFrame(false) {}
+ };
+ mem::stack<loopdata_t> loopdata;
+
+ // Current File Position
+ position curPos;
+
+public:
+ // Define a new function coder. If reframe is true, this gives the function
+ // its own frame, which is the usual (sensible) thing to do. It is set to
+ // false for a line-at-a-time codelet, where variables should be allocated in
+ // the lower frame.
+ coder(position pos,
+ string name, function *t, coder *parent,
+ modifier sord = DEFAULT_DYNAMIC,
+ bool reframe=true);
+
+ // Start encoding the body of the record. The function being encoded
+ // is the record's initializer.
+ coder(position pos,
+ record *t, coder *parent, modifier sord = DEFAULT_DYNAMIC);
+
+ coder(position pos,
+ string name, modifier sord = DEFAULT_DYNAMIC);
+
+ coder(const coder&);
+
+ /* Add a static or dynamic modifier. */
+ void pushModifier(modifier s)
+ {
+ /* Default setting should only be used in the constructor. */
+ assert(s != DEFAULT_STATIC && s != DEFAULT_DYNAMIC);
+
+ /* Non-default static overrules. */
+ if (sord != EXPLICIT_STATIC)
+ sord = s;
+
+ sord_stack.push(sord);
+ }
+
+ /* Tests if encoding mode is currently static. */
+ bool isStatic()
+ {
+ switch(sord) {
+ case DEFAULT_STATIC:
+ case EXPLICIT_STATIC:
+ return true;
+ case DEFAULT_DYNAMIC:
+ case EXPLICIT_DYNAMIC:
+ return false;
+ default:
+ assert(False);
+ return false;
+ }
+ }
+
+
+ /* Remove a modifier. */
+ void popModifier()
+ {
+ assert(!sord_stack.empty());
+ sord_stack.pop();
+
+ assert(!sord_stack.empty());
+ sord = sord_stack.top();
+ }
+
+ /* Set/get/clear permissions. */
+ void setPermission(permission p)
+ {
+ perm = p;
+ }
+ permission getPermission()
+ {
+ return perm;
+ }
+ void clearPermission()
+ {
+ perm = DEFAULT_PERM;
+ }
+
+
+ // Says what the return type of the function is.
+ ty *getReturnType() {
+ return funtype->result;
+ }
+
+ bool isRecord();
+
+ // Creates a new coder to handle the translation of a new function.
+ coder newFunction(position pos,
+ string name, function *t, modifier sord=DEFAULT_DYNAMIC);
+
+ // Creates a new record type.
+ record *newRecord(symbol id);
+
+ // Create a coder for the initializer of the record.
+ coder newRecordInit(position pos, record *r, modifier sord=DEFAULT_DYNAMIC);
+
+ // Create a coder for translating a small piece of code. Used for
+ // line-at-a-time mode.
+ coder newCodelet(position pos);
+
+ frame *getFrame()
+ {
+ if (isStatic() && !isTopLevel()) {
+ assert(parent->getFrame());
+ return parent->getFrame();
+ }
+ else
+ return level;
+ }
+
+ // Tests if the function or record with the given frame is currently under
+ // translation (either by this coder or an ancestor).
+ bool inTranslation(frame *f) {
+ frame *level=this->level;
+ while (level) {
+ if (f==level)
+ return true;
+ level=level->getParent();
+ }
+ return parent && parent->inTranslation(f);
+ }
+
+ // Allocates space in the function or record frame for a new local variable.
+ access *allocLocal()
+ {
+ return getFrame()->allocLocal();
+ }
+
+ // Get the access in the frame for a specified formal parameter.
+ access *accessFormal(Int index)
+ {
+ // NOTE: This hasn't been extended to handle frames for loops, but is
+ // currently only called when starting to translate a function, where there
+ // can be no loops.
+ return level->accessFormal(index);
+ }
+
+ // Checks if we are at the top level, which is true for a file-level module or
+ // a codelet.
+ bool isTopLevel() {
+ return parent==0 || isCodelet;
+ }
+
+ // The encode functions add instructions and operands on to the code array.
+private:
+ void encode(inst i)
+ {
+ i.pos = curPos;
+ // Static code is put into the enclosing coder, unless we are translating a
+ // codelet.
+ if (isStatic() && !isTopLevel()) {
+ assert(parent);
+ parent->encode(i);
+ }
+ else {
+ program->encode(i);
+ }
+ }
+
+ // Encode a jump to a not yet known location.
+ vm::program::label encodeEmptyJump(inst::opcode op);
+
+public:
+ void encode(inst::opcode op)
+ {
+ inst i; i.op = op; i.pos = nullPos;
+ encode(i);
+ }
+ void encode(inst::opcode op, item it)
+ {
+#ifdef DEBUG_BLTIN
+ assertBltinLookup(op, it);
+#endif
+ inst i; i.op = op; i.pos = nullPos; i.ref = it;
+ encode(i);
+ }
+
+ // Encodes a pop instruction, or merges the pop into the previous
+ // instruction (ex. varsave+pop becomes varpop).
+ void encodePop();
+
+ // Puts the requested frame on the stack. If the frame is not that of
+ // this coder or its ancestors, false is returned.
+ bool encode(frame *f);
+
+ // Puts the frame corresponding to the expression "this" on the stack.
+ bool encodeThis()
+ {
+ assert(recordLevel);
+ return encode(recordLevel);
+ }
+
+ // An access that encodes the frame corresponding to "this".
+ access *thisLocation()
+ {
+ assert(recordLevel);
+ return new frameAccess(recordLevel);
+ }
+
+ // Returns the type of the enclosing record.
+ record *thisType()
+ {
+ return recordType;
+ }
+
+ // Puts the 'dest' frame on the stack, assuming the frame 'top' is on
+ // top of the stack. If 'dest' is not an ancestor frame of 'top',
+ // false is returned.
+ bool encode(frame *dest, frame *top);
+
+
+ // Assigns a handle to the current point in the list of bytecode
+ // instructions and returns that handle.
+ label defNewLabel();
+
+ // Sets the handle given by label to the current point in the list of
+ // instructions.
+ label defLabel(label label);
+
+ // Encodes the address pointed to by the handle label into the
+ // sequence of instructions. This is useful for a jump instruction to
+ // jump to where a label was defined.
+ void useLabel(inst::opcode op, label label);
+
+ // If an address has to be used for a jump instruction before it is
+ // actually encoded, a handle can be given to it by this function.
+ // When that handle's label is later defined, the proper address will
+ // be inserted into the code where the handle was used.
+ label fwdLabel();
+
+ void pushLoop(label c, label b) {
+ loopdata.push(loopdata_t(c,b));
+ }
+ void popLoop() {
+ loopdata.pop();
+ }
+ void loopPushesFrame()
+ {
+ assert(!loopdata.empty());
+ loopdata_t& d = loopdata.top();
+ d.pushedFrame = true;
+ }
+ bool encodeBreak() {
+ if (loopdata.empty())
+ return false;
+ else {
+ loopdata_t& d = loopdata.top();
+ if (d.pushedFrame)
+ encode(inst::popframe);
+ useLabel(inst::jmp,d.breakLabel);
+ return true;
+ }
+ }
+ bool encodeContinue() {
+ if (loopdata.empty())
+ return false;
+ else {
+ loopdata_t& d = loopdata.top();
+ if (d.pushedFrame)
+ encode(inst::popframe);
+ useLabel(inst::jmp,d.continueLabel);
+ return true;
+ }
+ }
+
+ // Returns true if a pushclosure has been encoded since the definition of
+ // the label.
+ bool usesClosureSinceLabel(label l);
+
+ // Turn a no-op into a jump to bypass incorrect code.
+ void encodePatch(label from, label to);
+
+public:
+ void encodePushFrame() {
+ pushframeLabels.push(program->end());
+ encode(inst::pushframe, (Int)0);
+
+ level = new frame("encodePushFrame", level, 0);
+ }
+
+ void encodePopFrame() {
+ pushframeLabels.top()->ref = level->size();
+ pushframeLabels.pop();
+
+ encode(inst::popframe);
+
+ level = level->getParent();
+ }
+
+ // Adds an entry into the position list, linking the given point in the
+ // source code to the current position in the virtual machine code. This is
+ // used to print positions at runtime.
+ void markPos(position pos);
+
+ // When translation of the function is finished, this ties up loose ends
+ // and returns the lambda.
+ vm::lambda *close();
+
+ // Finishes translating the initializer of a record.
+ void closeRecord();
+
+private: // Non-copyable
+ void operator=(const coder&);
+};
+
+} // namespace trans
+
+#endif
diff --git a/graphics/asymptote/coenv.cc b/graphics/asymptote/coenv.cc
new file mode 100644
index 0000000000..e281b66696
--- /dev/null
+++ b/graphics/asymptote/coenv.cc
@@ -0,0 +1,47 @@
+/*****
+ * coenv.cc
+ * Andy Hammerlindl 2004/11/18
+ *
+ * Bundles the env and coder classes needed in translating the abstract syntax
+ * tree. It also also implements some functions that involve both the env and
+ * coder, such as implicitCast().
+ *****/
+
+#include "coenv.h"
+
+namespace trans {
+
+// Prints out error messages for the cast methods.
+static inline void castError(position pos, ty *target, ty *source)
+{
+ em.error(pos);
+ em << "cannot convert \'" << *source
+ << "\' to \'" << *target << "\'";
+}
+
+static inline bool accessCast(position pos, ty *target, ty *source,
+ access *a, coder& c)
+{
+ if (a) {
+ a->encode(CALL, pos, c);
+ return true;
+ }
+ else {
+ castError(pos, target, source);
+ return false;
+ }
+}
+
+bool coenv::implicitCast(position pos, ty *target, ty *source)
+{
+ return accessCast(pos, target, source,
+ e.lookupCast(target, source, symbol::castsym), c);
+}
+
+bool coenv::explicitCast(position pos, ty *target, ty *source)
+{
+ return accessCast(pos, target, source,
+ e.lookupCast(target, source, symbol::ecastsym), c);
+}
+
+}
diff --git a/graphics/asymptote/coenv.h b/graphics/asymptote/coenv.h
new file mode 100644
index 0000000000..b8d751570e
--- /dev/null
+++ b/graphics/asymptote/coenv.h
@@ -0,0 +1,40 @@
+/*****
+ * coenv.h
+ * Andy Hammerlindl 2004/11/18
+ *
+ * Bundles the env and coder classes needed in translating the abstract syntax
+ * tree. It also also implements some functions that involve both the env and
+ * coder, such as implicitCast().
+ *****/
+
+#ifndef COENV_H
+#define COENV_H
+
+#include "env.h"
+#include "coder.h"
+
+namespace trans {
+
+class coenv {
+public:
+ coder &c;
+ env &e;
+
+ coenv(coder &c, env &e)
+ : c(c), e(e) {}
+
+ // This is used when an expression of type source needs to be an
+ // expression of type target.
+ // If it is allowed, the casting instructions (if any) will be added.
+ // Otherwise, an appropriate error message will be printed.
+ bool implicitCast(position pos, ty *target, ty *source);
+ bool explicitCast(position pos, ty *target, ty *source);
+
+ void add(protoenv &source, varEntry *qualifier) {
+ e.add(source, qualifier, c);
+ }
+};
+
+} // namespace trans
+
+#endif
diff --git a/graphics/asymptote/common.h b/graphics/asymptote/common.h
new file mode 100644
index 0000000000..541a43d3ce
--- /dev/null
+++ b/graphics/asymptote/common.h
@@ -0,0 +1,86 @@
+/****
+ * common.h
+ *
+ * Definitions common to all files.
+ *****/
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#undef NDEBUG
+
+#include <iostream>
+#include <climits>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if !defined(FOR_SHARED) && \
+ ((defined(HAVE_LIBGL) && defined(HAVE_LIBGLUT) && defined(HAVE_LIBGLM)) || defined(HAVE_LIBOSMESA))
+#define HAVE_GL
+#endif
+
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
+#include "memory.h"
+
+#if defined(HAVE_LONG_LONG) && defined(LLONG_MAX) && defined(LLONG_MIN)
+#define Int_MAX2 LLONG_MAX
+#define Int_MIN LLONG_MIN
+typedef long long Int;
+typedef unsigned long long unsignedInt;
+#else
+#undef HAVE_LONG_LONG
+#ifdef HAVE_LONG
+#define Int_MAX2 LONG_MAX
+#define Int_MIN LONG_MIN
+typedef long Int;
+typedef unsigned long unsignedInt;
+#else
+#define Int_MAX2 INT_MAX
+#define Int_MIN INT_MIN
+typedef int Int;
+typedef unsigned int unsignedInt;
+#endif
+#endif
+
+#ifndef COMPACT
+#if Int_MAX2 >= 0x7fffffffffffffffLL
+#define COMPACT 1
+#else
+#define COMPACT 0
+#endif
+#endif
+
+#if COMPACT
+// Reserve highest two values for DefaultValue and Undefined states.
+#define Int_MAX (Int_MAX2-2)
+#define int_MAX (LONG_MAX-2)
+#else
+#define Int_MAX Int_MAX2
+#define int_MAX LONG_MAX
+#endif
+
+#define int_MIN LONG_MIN
+
+#ifndef RANDOM_MAX
+#define RANDOM_MAX 0x7FFFFFFF
+#endif
+
+using std::cout;
+using std::cin;
+using std::cerr;
+using std::endl;
+using std::istream;
+using std::ostream;
+
+using mem::string;
+using mem::stringstream;
+using mem::istringstream;
+using mem::ostringstream;
+using mem::stringbuf;
+
+#endif
diff --git a/graphics/asymptote/config.guess b/graphics/asymptote/config.guess
new file mode 100644
index 0000000000..256083a70d
--- /dev/null
+++ b/graphics/asymptote/config.guess
@@ -0,0 +1,1476 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2018 Free Software Foundation, Inc.
+
+timestamp='2018-03-08'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Options:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2018 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > "$dummy.c" ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "$UNAME_SYSTEM" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval "$set_cc_for_build"
+ cat <<-EOF > "$dummy.c"
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+
+ # If ldd exists, use it to detect musl libc.
+ if command -v ldd >/dev/null && \
+ ldd --version 2>&1 | grep -q ^musl
+ then
+ LIBC=musl
+ fi
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ "/sbin/$sysctl" 2>/dev/null || \
+ "/usr/sbin/$sysctl" 2>/dev/null || \
+ echo unknown)`
+ case "$UNAME_MACHINE_ARCH" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine="${arch}${endian}"-unknown
+ ;;
+ *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently (or will in the future) and ABI.
+ case "$UNAME_MACHINE_ARCH" in
+ earm*)
+ os=netbsdelf
+ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval "$set_cc_for_build"
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # Determine ABI tags.
+ case "$UNAME_MACHINE_ARCH" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "$UNAME_VERSION" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "$machine-${os}${release}${abi}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
+ exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+ exit ;;
+ *:MidnightBSD:*:*)
+ echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
+ exit ;;
+ *:SolidBSD:*:*)
+ echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
+ exit ;;
+ *:MirBSD:*:*)
+ echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
+ exit ;;
+ *:Sortix:*:*)
+ echo "$UNAME_MACHINE"-unknown-sortix
+ exit ;;
+ *:Redox:*:*)
+ echo "$UNAME_MACHINE"-unknown-redox
+ exit ;;
+ mips:OSF1:*.*)
+ echo mips-dec-osf1
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE=alpha ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE=alpha ;;
+ "EV5 (21164)")
+ UNAME_MACHINE=alphaev5 ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE=alphaev56 ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE=alphapca56 ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE=alphapca57 ;;
+ "EV6 (21264)")
+ UNAME_MACHINE=alphaev6 ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE=alphaev67 ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE=alphaev68 ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE=alphaev69 ;;
+ "EV7 (21364)")
+ UNAME_MACHINE=alphaev7 ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE=alphaev79 ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo "$UNAME_MACHINE"-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo "$UNAME_MACHINE"-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix"$UNAME_RELEASE"
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux"$UNAME_RELEASE"
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval "$set_cc_for_build"
+ SUN_ARCH=i386
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH=x86_64
+ fi
+ fi
+ echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos"$UNAME_RELEASE"
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos"$UNAME_RELEASE"
+ ;;
+ sun4)
+ echo sparc-sun-sunos"$UNAME_RELEASE"
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos"$UNAME_RELEASE"
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint"$UNAME_RELEASE"
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint"$UNAME_RELEASE"
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint"$UNAME_RELEASE"
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint"$UNAME_RELEASE"
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint"$UNAME_RELEASE"
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint"$UNAME_RELEASE"
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten"$UNAME_RELEASE"
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten"$UNAME_RELEASE"
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix"$UNAME_RELEASE"
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix"$UNAME_RELEASE"
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix"$UNAME_RELEASE"
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos"$UNAME_RELEASE"
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
+ then
+ if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+ [ "$TARGET_BINARY_INTERFACE"x = x ]
+ then
+ echo m88k-dg-dgux"$UNAME_RELEASE"
+ else
+ echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+ fi
+ else
+ echo i586-dg-dgux"$UNAME_RELEASE"
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ fi
+ echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ fi
+ echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ case "$UNAME_MACHINE" in
+ 9000/31?) HP_ARCH=m68000 ;;
+ 9000/[34]??) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "$sc_cpu_version" in
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "$sc_kernel_bits" in
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "$HP_ARCH" = "" ]; then
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ "$HP_ARCH" = hppa2.0w ]
+ then
+ eval "$set_cc_for_build"
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH=hppa2.0w
+ else
+ HP_ARCH=hppa64
+ fi
+ fi
+ echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux"$HPUX_REV"
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo "$UNAME_MACHINE"-unknown-osf1mk
+ else
+ echo "$UNAME_MACHINE"-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi"$UNAME_RELEASE"
+ exit ;;
+ *:BSD/OS:*:*)
+ echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case "$UNAME_PROCESSOR" in
+ amd64)
+ UNAME_PROCESSOR=x86_64 ;;
+ i386)
+ UNAME_PROCESSOR=i586 ;;
+ esac
+ echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+ exit ;;
+ i*:CYGWIN*:*)
+ echo "$UNAME_MACHINE"-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo "$UNAME_MACHINE"-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo "$UNAME_MACHINE"-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo "$UNAME_MACHINE"-pc-msys
+ exit ;;
+ i*:PW*:*)
+ echo "$UNAME_MACHINE"-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case "$UNAME_MACHINE" in
+ x86)
+ echo i586-pc-interix"$UNAME_RELEASE"
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix"$UNAME_RELEASE"
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix"$UNAME_RELEASE"
+ exit ;;
+ esac ;;
+ i*:UWIN*:*)
+ echo "$UNAME_MACHINE"-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
+ exit ;;
+ i*86:Minix:*:*)
+ echo "$UNAME_MACHINE"-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ arm*:Linux:*:*)
+ eval "$set_cc_for_build"
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+ else
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ cris:Linux:*:*)
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+ exit ;;
+ crisv32:Linux:*:*)
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+ exit ;;
+ e2k:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ frv:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ hexagon:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ i*86:Linux:*:*)
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+ exit ;;
+ ia64:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ k1om:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ m32r*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ m68*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
+ test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
+ ;;
+ mips64el:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-"$LIBC"
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-"$LIBC"
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-"$LIBC"
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+ PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+ *) echo hppa-unknown-linux-"$LIBC" ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-"$LIBC"
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-"$LIBC"
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-"$LIBC"
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-"$LIBC"
+ exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
+ exit ;;
+ sh64*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ sh*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ tile*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ vax:Linux:*:*)
+ echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
+ exit ;;
+ x86_64:Linux:*:*)
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo "$UNAME_MACHINE"-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo "$UNAME_MACHINE"-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo "$UNAME_MACHINE"-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo "$UNAME_MACHINE"-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos"$UNAME_RELEASE"
+ exit ;;
+ i*86:*DOS:*:*)
+ echo "$UNAME_MACHINE"-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:*)
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+ else
+ echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+ else
+ echo "$UNAME_MACHINE"-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configure will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos"$UNAME_RELEASE"
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos"$UNAME_RELEASE"
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos"$UNAME_RELEASE"
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos"$UNAME_RELEASE"
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv"$UNAME_RELEASE"
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo "$UNAME_MACHINE"-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo "$UNAME_MACHINE"-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux"$UNAME_RELEASE"
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv"$UNAME_RELEASE"
+ else
+ echo mips-unknown-sysv"$UNAME_RELEASE"
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody"$UNAME_RELEASE"
+ exit ;;
+ *:Rhapsody:*:*)
+ echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval "$set_cc_for_build"
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+ if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_PPC >/dev/null
+ then
+ UNAME_PROCESSOR=powerpc
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = x86; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-*:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSR-*:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSV-*:NONSTOP_KERNEL:*:*)
+ echo nsv-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSX-*:NONSTOP_KERNEL:*:*)
+ echo nsx-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = 386; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo "$UNAME_MACHINE"-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux"$UNAME_RELEASE"
+ exit ;;
+ *:DragonFly:*:*)
+ echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "$UNAME_MACHINE" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
+ exit ;;
+ i*86:rdos:*:*)
+ echo "$UNAME_MACHINE"-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo "$UNAME_MACHINE"-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo "$UNAME_MACHINE"-unknown-esx
+ exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
+ exit ;;
+esac
+
+echo "$0: unable to guess system type" >&2
+
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+ mips:Linux | mips64:Linux)
+ # If we got here on MIPS GNU/Linux, output extra information.
+ cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+ ;;
+esac
+
+cat >&2 <<EOF
+
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
+
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+and
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/graphics/asymptote/config.h.in b/graphics/asymptote/config.h.in
new file mode 100644
index 0000000000..a178b67d1c
--- /dev/null
+++ b/graphics/asymptote/config.h.in
@@ -0,0 +1,249 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Directory for documentation */
+#undef ASYMPTOTE_DOCDIR
+
+/* System directory for global .asy files */
+#undef ASYMPTOTE_SYSDIR
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the `feenableexcept' function. */
+#undef HAVE_FEENABLEEXCEPT
+
+/* Define to 1 if you have the <fenv.h> header file. */
+#undef HAVE_FENV_H
+
+/* Define to 1 if you have the `floor' function. */
+#undef HAVE_FLOOR
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the <fpu_control.h> header file. */
+#undef HAVE_FPU_CONTROL_H
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have GNU <getopt.h>. */
+#undef HAVE_GNU_GETOPT_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `ncurses' library (-lncurses). */
+#undef HAVE_LIBCURSES
+
+/* Define to 1 if you have the `fftw3' library (-lfftw3). */
+#undef HAVE_LIBFFTW3
+
+/* Define to 1 if you have the `gccpp' library (-lgccpp). */
+#undef HAVE_LIBGCCPP
+
+/* Define to 1 if you have the `GL' library (-lGL). */
+#undef HAVE_LIBGL
+
+/* Define to 1 if you have the <glm/glm.hpp> header. */
+#undef HAVE_LIBGLM
+
+/* Define to 1 if you have the `glut' library (-lglut). */
+#undef HAVE_LIBGLUT
+
+/* Define to 1 if you have the `' library (-l). gsl */
+#undef HAVE_LIBGSL
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the `ncurses' library (-lncurses). */
+#undef HAVE_LIBNCURSES
+
+/* Define to 1 if you have the `OpenImageIO' library (-lOpenImageIO). */
+#undef HAVE_LIBOPENIMAGEIO
+
+/* Define to 1 if you have the `OSMesa' library (-lOSMesa). */
+#undef HAVE_LIBOSMESA
+
+/* Define to 1 if you have the `readline' library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+#undef HAVE_LIBRT
+
+/* Define to 1 if you have the `sigsegv' library (-lsigsegv). */
+#undef HAVE_LIBSIGSEGV
+
+/* Define to 1 if you have the `tinfo' library (-ltinfo). */
+#undef HAVE_LIBTINFO
+
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
+/* Define to 1 if the system has the type `long'. */
+#undef HAVE_LONG
+
+/* Define to 1 if the system has the type `long long'. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memrchr' function. */
+#undef HAVE_MEMRCHR
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#undef HAVE_NCURSES_CURSES_H
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#undef HAVE_PTRDIFF_T
+
+/* Define to 1 if you have a working <tirpc/rpc/rpc.h> header. */
+#undef HAVE_RPC_RPC_H
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strptime' function. */
+#undef HAVE_STRPTIME
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the `tgamma' function. */
+#undef HAVE_TGAMMA
+
+/* Define to 1 if you have <tr1/unordered_map>. */
+#undef HAVE_TR1_UNORDERED_MAP
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have <unordered_map>. */
+#undef HAVE_UNORDERED_MAP
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
diff --git a/graphics/asymptote/config.sub b/graphics/asymptote/config.sub
new file mode 100644
index 0000000000..9ccf09a7a3
--- /dev/null
+++ b/graphics/asymptote/config.sub
@@ -0,0 +1,1801 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2018 Free Software Foundation, Inc.
+
+timestamp='2018-03-08'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+Canonicalize a configuration name.
+
+Options:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2018 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo "$1"
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | cloudabi*-eabi* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
+ if [ "$basic_machine" != "$1" ]
+ then os=`echo "$1" | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | ba \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia16 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pru \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | wasm32 \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | ba-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pru-* \
+ | pyramid-* \
+ | riscv32-* | riscv64-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | wasm32-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-pc
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2*)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
+ ;;
+ e500v[12]-*)
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=$os"spe"
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next)
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ nsv-tandem)
+ basic_machine=nsv-tandem
+ ;;
+ nsx-tandem)
+ basic_machine=nsx-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ x64)
+ basic_machine=x86_64-pc
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases that might get confused
+ # with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # es1800 is here to avoid being matched by es* (a different OS)
+ -es1800*)
+ os=-ose
+ ;;
+ # Now accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST end in a * to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \
+ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
+ | -midnightbsd*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -xray | -os68k* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo "$os" | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2)
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $basic_machine in
+ arm*)
+ os=-eabi
+ ;;
+ *)
+ os=-elf
+ ;;
+ esac
+ ;;
+ -nacl*)
+ ;;
+ -ios)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ pru-*)
+ os=-elf
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next)
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo "$basic_machine$os"
+exit
+
+# Local variables:
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/graphics/asymptote/configure b/graphics/asymptote/configure
new file mode 100755
index 0000000000..e1cbe29de1
--- /dev/null
+++ b/graphics/asymptote/configure
@@ -0,0 +1,9841 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for Asymptote 2.53.
+#
+# Report bugs to <http://sourceforge.net/projects/asymptote>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: http://sourceforge.net/projects/asymptote about your
+$0: system, including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Asymptote'
+PACKAGE_TARNAME='asymptote'
+PACKAGE_VERSION='2.53'
+PACKAGE_STRING='Asymptote 2.53'
+PACKAGE_BUGREPORT='http://sourceforge.net/projects/asymptote'
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_unique_file="absyn.cc"
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+ax_pthread_config
+OPTIONS
+INCL
+GCPPLIB
+GCLIB
+GCOPTIONS
+ATOMICVERSION
+GCVERSION
+getopt
+CXXCPP
+YFLAGS
+YACC
+SET_MAKE
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LEXLIB
+ac_ct_CXX
+CXXFLAGS
+CXX
+LEX_OUTPUT_ROOT
+LEX
+contextdir
+latexdir
+TEXI2DVI
+kpsewhich
+Datadir
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+VERSION
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_latex
+with_context
+with_docdir
+enable_texlive_build
+enable_gc
+enable_gc_debug
+enable_gc_full_debug
+enable_sigsegv
+enable_readline
+enable_static
+enable_fftw
+enable_gsl
+enable_gl
+enable_offscreen
+enable_OpenImageIO
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+YACC
+YFLAGS
+CXXCPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures Asymptote 2.53 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/asymptote]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of Asymptote 2.53:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-texlive-build automatically determine sysdir from kpsewhich
+ --enable-gc[=system] enable system Boehm garbage collector
+ [=VERSION] enable local VERSION of Boehm garbage collector
+ [=PREFIX] use Boehm garbage collector installed in PREFIX
+ --enable-gc-debug enable (slow) garbage collector debugging
+ --enable-gc-full-debug enable (very slow) garbage collector backtrace
+ --enable-sigsegv[=yes] enable GNU Stack Overflow Handler
+ --enable-readline[=yes] enable GNU Readline Library
+ --enable-static[=no] link against static libraries
+ --enable-fftw[=yes] enable FFTW Library
+ --enable-gsl[=yes] enable GNU Scientific Library
+ --enable-gl[=yes] enable OpenGL Library
+ --enable-offscreen[=no] enable experimental offscreen rendering using OSMesa
+ library
+ --enable-openimageio[=no]
+ enable experimental OpenImageIO Library
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-latex=PATH specify path to LaTeX installation
+ --with-context=PATH specify path to ConTeXt installation
+ --with-docdir=PATH alternate documentation installation directory
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ YACC The `Yet Another Compiler Compiler' implementation to use.
+ Defaults to the first program found out of: `bison -y', `byacc',
+ `yacc'.
+ YFLAGS The list of arguments that will be passed by default to $YACC.
+ This script will default YFLAGS to the empty string to avoid a
+ default value of `-d' given by some make applications.
+ CXXCPP C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <http://sourceforge.net/projects/asymptote>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+Asymptote configure 2.53
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_cxx_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_func
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES
+# ---------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_cxx_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_type
+
+# ac_fn_cxx_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_cxx_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_run
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Asymptote $as_me 2.53, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+VERSION=$PACKAGE_VERSION
+
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise). (This
+# is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also link it with them as well. e.g. you should link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threads programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 18
+
+# This is what autoupdate's m4 run will expand. It fires
+# the warning (with _au_warn_XXX), outputs it into the
+# updated configure.ac (with AC_DIAGNOSE), and then outputs
+# the replacement expansion.
+
+
+# This is an auxiliary macro that is also run when
+# autoupdate runs m4. It simply calls m4_warning, but
+# we need a wrapper so that each warning is emitted only
+# once. We break the quoting in m4_warning's argument in
+# order to expand this macro's arguments, not AU_DEFUN's.
+
+
+# Finally, this is the expansion that is picked up by
+# autoconf. It tells the user to run autoupdate, and
+# then outputs the replacement expansion. We do not care
+# about autoupdate's warning because that contains
+# information on what to do *after* running autoupdate.
+
+
+
+test "$CXXFLAGS" || CXXFLAGS="-std=c++11"
+
+test "$CFLAGS" || CFLAGS="-g -O3"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+test "$prefix" = NONE && prefix=/usr/local
+Datadir=$datadir
+test "$Datadir" = '${datarootdir}' && Datadir=$datarootdir
+test "$Datadir" = '${prefix}/share' && Datadir=$prefix/share
+
+
+
+# Check whether --with-latex was given.
+if test "${with_latex+set}" = set; then :
+ withval=$with_latex; if test "x$withval" != "x" ; then
+ latexdir=$withval
+ fi
+
+else
+
+# Extract the first word of "kpsewhich", so it can be a program name with args.
+set dummy kpsewhich; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_kpsewhich+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$kpsewhich"; then
+ ac_cv_prog_kpsewhich="$kpsewhich" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_kpsewhich="true"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+kpsewhich=$ac_cv_prog_kpsewhich
+if test -n "$kpsewhich"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpsewhich" >&5
+$as_echo "$kpsewhich" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$kpsewhich" = "xtrue"; then
+ latexdir=`kpsewhich -expand-var='$TEXMFLOCAL'/tex/latex`
+else
+ latexdir=$prefix/share/texmf/tex/latex
+ as_ac_File=`$as_echo "ac_cv_file_$latexdir/base/latex.ltx" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $latexdir/base/latex.ltx" >&5
+$as_echo_n "checking for $latexdir/base/latex.ltx... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "$latexdir/base/latex.ltx"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+eval ac_res=\$$as_ac_File
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
+
+else
+ latexdir=/usr/share/texmf/tex/latex
+ as_ac_File=`$as_echo "ac_cv_file_$latexdir/base/latex.ltx" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $latexdir/base/latex.ltx" >&5
+$as_echo_n "checking for $latexdir/base/latex.ltx... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "$latexdir/base/latex.ltx"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+eval ac_res=\$$as_ac_File
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
+
+fi
+
+fi
+
+fi
+
+fi
+
+
+
+# Check whether --with-context was given.
+if test "${with_context+set}" = set; then :
+ withval=$with_context; if test "x$withval" != "x" ; then
+ contextdir=$withval
+ fi
+
+else
+
+# Extract the first word of "kpsewhich", so it can be a program name with args.
+set dummy kpsewhich; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_kpsewhich+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$kpsewhich"; then
+ ac_cv_prog_kpsewhich="$kpsewhich" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_kpsewhich="true"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+kpsewhich=$ac_cv_prog_kpsewhich
+if test -n "$kpsewhich"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpsewhich" >&5
+$as_echo "$kpsewhich" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$kpsewhich" = "xtrue"; then
+ contextdir=`kpsewhich -expand-var='$TEXMFLOCAL'/tex/context/third`
+else
+ contextdir=$prefix/share/texmf/tex/context/third
+fi
+
+fi
+
+
+for ac_prog in texi2dvi
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_TEXI2DVI+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$TEXI2DVI"; then
+ ac_cv_prog_TEXI2DVI="$TEXI2DVI" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_TEXI2DVI="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+TEXI2DVI=$ac_cv_prog_TEXI2DVI
+if test -n "$TEXI2DVI"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXI2DVI" >&5
+$as_echo "$TEXI2DVI" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$TEXI2DVI" && break
+done
+test -n "$TEXI2DVI" || TEXI2DVI="@echo \*\*\*\*\*\*\*\*\*\* Please install texi2dvi or put http://asymptote.sourceforge.net/asymptote.pdf in the doc directory: cannot execute texi2dvi"
+
+
+
+
+latexdir=$latexdir/asymptote
+contextdir=$contextdir/asymptote
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Using $latexdir for LaTeX style file" >&5
+$as_echo "$as_me: Using $latexdir for LaTeX style file" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Using $contextdir for ConTeXT style file" >&5
+$as_echo "$as_me: Using $contextdir for ConTeXT style file" >&6;}
+
+
+
+
+docdir=$Datadir/doc/asymptote
+
+
+# Check whether --with-docdir was given.
+if test "${with_docdir+set}" = set; then :
+ withval=$with_docdir; if test "x$withval" != "x" ; then
+ docdir=$withval
+ fi
+
+fi
+
+
+
+sysdir=$Datadir/asymptote
+
+# Check whether --enable-texlive-build was given.
+if test "${enable_texlive_build+set}" = set; then :
+ enableval=$enable_texlive_build; if test "x$enableval" = "xyes" ; then
+ sysdir=""
+ fi
+
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define ASYMPTOTE_SYSDIR "$sysdir"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define ASYMPTOTE_DOCDIR "$docdir"
+_ACEOF
+
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+# Checks for programs.
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+for ac_prog in flex lex
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LEX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LEX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5
+$as_echo "$LEX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test "x$LEX" != "x:"; then
+ cat >conftest.l <<_ACEOF
+%%
+a { ECHO; }
+b { REJECT; }
+c { yymore (); }
+d { yyless (1); }
+e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */
+ yyless ((input () != 0)); }
+f { unput (yytext[0]); }
+. { BEGIN INITIAL; }
+%%
+#ifdef YYTEXT_POINTER
+extern char *yytext;
+#endif
+int
+main (void)
+{
+ return ! yylex () + ! yywrap ();
+}
+_ACEOF
+{ { ac_try="$LEX conftest.l"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$LEX conftest.l") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5
+$as_echo_n "checking lex output file root... " >&6; }
+if ${ac_cv_prog_lex_root+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5
+$as_echo "$ac_cv_prog_lex_root" >&6; }
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+if test -z "${LEXLIB+set}"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5
+$as_echo_n "checking lex library... " >&6; }
+if ${ac_cv_lib_lex+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_save_LIBS=$LIBS
+ ac_cv_lib_lex='none needed'
+ for ac_lib in '' -lfl -ll; do
+ LIBS="$ac_lib $ac_save_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_lex=$ac_lib
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ test "$ac_cv_lib_lex" != 'none needed' && break
+ done
+ LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5
+$as_echo "$ac_cv_lib_lex" >&6; }
+ test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5
+$as_echo_n "checking whether yytext is a pointer... " >&6; }
+if ${ac_cv_prog_lex_yytext_pointer+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+ac_save_LIBS=$LIBS
+LIBS="$LEXLIB $ac_save_LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #define YYTEXT_POINTER 1
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_prog_lex_yytext_pointer=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5
+$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; }
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h
+
+fi
+rm -f conftest.l $LEX_OUTPUT_ROOT.c
+
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_YACC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_YACC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5
+$as_echo "$YACC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+
+if test "$GXX" = yes ; then
+ ac_gcc_version=`echo __GNUC__ | $CC -E - | grep -v ^\#`
+ ac_clang=`echo __clang__ | $CC -E - | grep -v ^\#`
+ if test "$ac_gcc_version" -lt 4; then
+ CFLAGS=$CFLAGS" -finline-limit=400"
+ else
+ if test "$ac_clang" != 1; then
+ CFLAGS=$CFLAGS" -fno-var-tracking"
+ fi
+ fi
+fi
+
+
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if ${ac_cv_prog_CXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_fn_cxx_check_header_mongrel "$LINENO" "tr1/unordered_map" "ac_cv_header_tr1_unordered_map" "$ac_includes_default"
+if test "x$ac_cv_header_tr1_unordered_map" = xyes; then :
+
+$as_echo "#define HAVE_TR1_UNORDERED_MAP 1" >>confdefs.h
+
+else
+ ac_fn_cxx_check_header_mongrel "$LINENO" "unordered_map" "ac_cv_header_unordered_map" "$ac_includes_default"
+if test "x$ac_cv_header_unordered_map" = xyes; then :
+
+$as_echo "#define HAVE_UNORDERED_MAP 1" >>confdefs.h
+
+else
+ ac_fn_cxx_check_header_mongrel "$LINENO" "ext/hash_map" "ac_cv_header_ext_hash_map" "$ac_includes_default"
+if test "x$ac_cv_header_ext_hash_map" = xyes; then :
+
+else
+ OPTIONS=$OPTIONS"-DNOHASH "
+fi
+
+
+fi
+
+
+fi
+
+
+
+GCVERSION=8.0.4
+ATOMICVERSION=7.6.10
+
+GCFILE=gc-$GCVERSION
+ac_cv_use_gc="system"
+
+as_ac_File=`$as_echo "ac_cv_file_$GCFILE.tar.gz" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $GCFILE.tar.gz" >&5
+$as_echo_n "checking for $GCFILE.tar.gz... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "$GCFILE.tar.gz"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+eval ac_res=\$$as_ac_File
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
+ ac_cv_use_gc=$GCVERSION
+fi
+
+# Check whether --enable-gc was given.
+if test "${enable_gc+set}" = set; then :
+ enableval=$enable_gc;
+ if test "x$enableval" != "xyes" ; then
+ ac_cv_use_gc=$enableval
+ fi
+
+fi
+
+
+OPTIONS="-D_FILE_OFFSET_BITS=64 "
+GCLIB=
+GCPPLIB=
+INCL="-I."
+GCNAME="Boehm Garbage Collector"
+GCOPTIONS="--disable-shared"
+if test "x$ac_cv_use_gc" != "xno" ; then
+ OPTIONS=$OPTIONS"-DUSEGC "
+ case _$ac_cv_use_gc in
+ _|_system|_*[\\/]*)
+ if test "x$ac_cv_use_gc" = "xsystem" ; then
+ INCL="-I. -I$prefix/include/gc -I/usr/include/gc"
+ LIBS=$LIBS"-L$prefix/lib "
+ else
+ INCL="-I$ac_cv_use_gc/include/gc"
+ LIBS=$LIBS"-L$ac_cv_use_gc/lib "
+ fi
+ CPPFLAGS_SAVE=$CPPFLAGS
+ CPPFLAGS=$CPPFLAGS" $INCL"
+ ac_fn_cxx_check_header_mongrel "$LINENO" "gc.h" "ac_cv_header_gc_h" "$ac_includes_default"
+if test "x$ac_cv_header_gc_h" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GC_malloc in -lgc" >&5
+$as_echo_n "checking for GC_malloc in -lgc... " >&6; }
+if ${ac_cv_lib_gc_GC_malloc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgc $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GC_malloc ();
+int
+main ()
+{
+return GC_malloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_gc_GC_malloc=yes
+else
+ ac_cv_lib_gc_GC_malloc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gc_GC_malloc" >&5
+$as_echo "$ac_cv_lib_gc_GC_malloc" >&6; }
+if test "x$ac_cv_lib_gc_GC_malloc" = xyes; then :
+
+ LIBS=$LIBS"-lgc "
+ { $as_echo "$as_me:${as_lineno-$LINENO}: enabling system $GCNAME" >&5
+$as_echo "$as_me: enabling system $GCNAME" >&6;}
+else
+
+ GCDIR=$GCFILE
+ INCL="-I. -I\$(GC)/include"
+ GCLIB="\$(GC)/.libs/libgc.a"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $GCNAME library not found" >&5
+$as_echo "$as_me: $GCNAME library not found" >&6;}
+fi
+
+else
+ GCDIR=$GCFILE
+ GCLIB="\$(GC)/.libs/libgc.a"
+ INCL="-I. -I\$(GC)/include"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $GCNAME header file not found" >&5
+$as_echo "$as_me: $GCNAME header file not found" >&6;}
+fi
+
+
+ CPPFLAGS=$CPPFLAGS_SAVE
+ ;;
+ *)
+ GCVERSION=$ac_cv_use_gc
+ GCFILE=gc-$GCVERSION
+ GCDIR=$GCFILE
+ { $as_echo "$as_me:${as_lineno-$LINENO}: enabling local $GCNAME $GCDIR" >&5
+$as_echo "$as_me: enabling local $GCNAME $GCDIR" >&6;}
+ GCLIB="\$(GC)/.libs/libgc.a"
+ INCL="-I. -I\$(GC)/include"
+ ;;
+ esac
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: disabling the $GCNAME" >&5
+$as_echo "$as_me: disabling the $GCNAME" >&6;}
+fi
+
+# Check whether --enable-gc-debug was given.
+if test "${enable_gc_debug+set}" = set; then :
+ enableval=$enable_gc_debug; if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG "
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Enabling GC debugging: remember to make clean ***" >&5
+$as_echo "$as_me: *** Enabling GC debugging: remember to make clean ***" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Set the environment variable GC_FIND_LEAK at runtime ***" >&5
+$as_echo "$as_me: *** Set the environment variable GC_FIND_LEAK at runtime ***" >&6;}
+ fi
+ fi
+
+fi
+
+
+# Check whether --enable-gc-full-debug was given.
+if test "${enable_gc_full_debug+set}" = set; then :
+ enableval=$enable_gc_full_debug; if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG -DGC_BACKTRACE "
+ GCOPTIONS=$GCOPTIONS"--enable-gc-debug "
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Enabling GC backtrace debugging; remember to make gc-clean ***" >&5
+$as_echo "$as_me: *** Enabling GC backtrace debugging; remember to make gc-clean ***" >&6;}
+ fi
+ fi
+
+fi
+
+
+INCL=$INCL" -I/usr/include/tirpc"
+
+if test "$OSTYPE" = "cygwin"; then
+CPPFLAGS=$CPPFLAGS" -D__MSDOS__ -I/usr/include/w32api -I/usr/include -DCALLBACK=__stdcall $INCL"
+else
+CPPFLAGS=$CPPFLAGS" $INCL"
+fi
+
+ac_fn_cxx_check_func "$LINENO" "getopt_long_only" "ac_cv_func_getopt_long_only"
+if test "x$ac_cv_func_getopt_long_only" = xyes; then :
+
+$as_echo "#define HAVE_GNU_GETOPT_H 1" >>confdefs.h
+
+else
+ getopt="getopt getopt1"
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Checks for libraries.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing lgamma" >&5
+$as_echo_n "checking for library containing lgamma... " >&6; }
+if ${ac_cv_search_lgamma+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char lgamma ();
+int
+main ()
+{
+return lgamma ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' m c; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_lgamma=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_lgamma+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_lgamma+:} false; then :
+
+else
+ ac_cv_search_lgamma=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_lgamma" >&5
+$as_echo "$ac_cv_search_lgamma" >&6; }
+ac_res=$ac_cv_search_lgamma
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ as_fn_error $? "*** Please install libm on your system ***" "$LINENO" 5
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5
+$as_echo_n "checking for deflate in -lz... " >&6; }
+if ${ac_cv_lib_z_deflate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char deflate ();
+int
+main ()
+{
+return deflate ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_z_deflate=yes
+else
+ ac_cv_lib_z_deflate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5
+$as_echo "$ac_cv_lib_z_deflate" >&6; }
+if test "x$ac_cv_lib_z_deflate" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+ LIBS="-lz $LIBS"
+
+else
+ as_fn_error $? "*** Please install libz or zlib-devel on your system ***" "$LINENO" 5
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+ if test x"$ax_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+ ;;
+
+ darwin*)
+ ax_pthread_flags="-pthread $ax_pthread_flags"
+ ;;
+esac
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+ case $flag in
+ none)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+ ;;
+
+ -*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ax_pthread_config+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ax_pthread_config"; then
+ ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ax_pthread_config="yes"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
+fi
+fi
+ax_pthread_config=$ac_cv_prog_ax_pthread_config
+if test -n "$ax_pthread_config"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
+$as_echo "$ax_pthread_config" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test x"$ax_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }
+int
+main ()
+{
+pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+ if test "x$ax_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+int attr = $attr; return attr /* ; */
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ attr_name=$attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+ flag=no
+ case ${host_os} in
+ aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+ osf* | hpux*) flag="-D_REENTRANT";;
+ solaris*)
+ if test "$GCC" = "yes"; then
+ flag="-D_REENTRANT"
+ else
+ flag="-mt -D_REENTRANT"
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
+$as_echo "${flag}" >&6; }
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
+$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
+if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <pthread.h>
+int
+main ()
+{
+int i = PTHREAD_PRIO_INHERIT;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_PTHREAD_PRIO_INHERIT=yes
+else
+ ax_cv_PTHREAD_PRIO_INHERIT=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
+$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
+ if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then :
+
+$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
+
+fi
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: must compile with xlc_r or cc_r
+ if test x"$GCC" != xyes; then
+ for ac_prog in xlc_r cc_r
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PTHREAD_CC"; then
+ ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PTHREAD_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}"
+
+ else
+ PTHREAD_CC=$CC
+ fi
+else
+ PTHREAD_CC="$CC"
+fi
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+ :
+else
+ ax_pthread_ok=no
+
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+# Check whether --enable-sigsegv was given.
+if test "${enable_sigsegv+set}" = set; then :
+ enableval=$enable_sigsegv;
+fi
+
+
+if test "x$enable_sigsegv" != "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stackoverflow_install_handler in -lsigsegv" >&5
+$as_echo_n "checking for stackoverflow_install_handler in -lsigsegv... " >&6; }
+if ${ac_cv_lib_sigsegv_stackoverflow_install_handler+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsigsegv $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char stackoverflow_install_handler ();
+int
+main ()
+{
+return stackoverflow_install_handler ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_sigsegv_stackoverflow_install_handler=yes
+else
+ ac_cv_lib_sigsegv_stackoverflow_install_handler=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sigsegv_stackoverflow_install_handler" >&5
+$as_echo "$ac_cv_lib_sigsegv_stackoverflow_install_handler" >&6; }
+if test "x$ac_cv_lib_sigsegv_stackoverflow_install_handler" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSIGSEGV 1
+_ACEOF
+
+ LIBS="-lsigsegv $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_yield in -lrt" >&5
+$as_echo_n "checking for sched_yield in -lrt... " >&6; }
+if ${ac_cv_lib_rt_sched_yield+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sched_yield ();
+int
+main ()
+{
+return sched_yield ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_rt_sched_yield=yes
+else
+ ac_cv_lib_rt_sched_yield=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_sched_yield" >&5
+$as_echo "$ac_cv_lib_rt_sched_yield" >&6; }
+if test "x$ac_cv_lib_rt_sched_yield" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRT 1
+_ACEOF
+
+ LIBS="-lrt $LIBS"
+
+fi
+
+
+# Check whether --enable-readline was given.
+if test "${enable_readline+set}" = set; then :
+ enableval=$enable_readline;
+fi
+
+
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static;
+fi
+
+
+LDSTATIC=""
+STATIC=""
+DYNAMIC=""
+if test "x$enable_static" = "xyes"; then
+ LDSTATIC="-static "
+ STATIC="-Wl,-Bstatic "
+ DYNAMIC="-Wl,-Bdynamic "
+fi
+
+
+
+
+
+
+
+if test "x$enable_readline" != "xno"; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <readline/readline.h>
+
+int
+main ()
+{
+
+#ifndef RL_READLINE_VERSION
+abort
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+LDFLAGS0=$LDFLAGS
+LDFLAGS=$LDFLAGS$LDSTATIC
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for history_list in -lreadline" >&5
+$as_echo_n "checking for history_list in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_history_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char history_list ();
+int
+main ()
+{
+return history_list ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_readline_history_list=yes
+else
+ ac_cv_lib_readline_history_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_history_list" >&5
+$as_echo "$ac_cv_lib_readline_history_list" >&6; }
+if test "x$ac_cv_lib_readline_history_list" = xyes; then :
+
+
+$as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h
+
+LIBS=$LIBS$STATIC"-lreadline "$DYNAMIC
+
+else
+ if test "x$enable_static" = "xyes"; then
+
+{ ac_cv_lib_readline_history_list=; unset ac_cv_lib_readline_history_list;}
+LDFLAGS=$LDFLAGS0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for history_list in -lreadline" >&5
+$as_echo_n "checking for history_list in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_history_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char history_list ();
+int
+main ()
+{
+return history_list ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_readline_history_list=yes
+else
+ ac_cv_lib_readline_history_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_history_list" >&5
+$as_echo "$ac_cv_lib_readline_history_list" >&6; }
+if test "x$ac_cv_lib_readline_history_list" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBREADLINE 1
+_ACEOF
+
+ LIBS="-lreadline $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&5
+$as_echo "$as_me: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&6;}
+
+fi
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&5
+$as_echo "$as_me: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&6;}
+
+fi
+
+fi
+
+LDFLAGS=$LDFLAGS0
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&5
+$as_echo "$as_me: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&6;}
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+LDFLAGS0=$LDFLAGS
+LDFLAGS=$LDFLAGS$LDSTATIC
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5
+$as_echo_n "checking for tgetent in -ltinfo... " >&6; }
+if ${ac_cv_lib_tinfo_tgetent+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltinfo $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tgetent ();
+int
+main ()
+{
+return tgetent ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_tinfo_tgetent=yes
+else
+ ac_cv_lib_tinfo_tgetent=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5
+$as_echo "$ac_cv_lib_tinfo_tgetent" >&6; }
+if test "x$ac_cv_lib_tinfo_tgetent" = xyes; then :
+
+
+$as_echo "#define HAVE_LIBTINFO 1" >>confdefs.h
+
+LIBS=$LIBS$STATIC"-ltinfo "$DYNAMIC
+
+else
+ if test "x$enable_static" = "xyes"; then
+
+{ ac_cv_lib_tinfo_tgetent=; unset ac_cv_lib_tinfo_tgetent;}
+LDFLAGS=$LDFLAGS0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5
+$as_echo_n "checking for tgetent in -ltinfo... " >&6; }
+if ${ac_cv_lib_tinfo_tgetent+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltinfo $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tgetent ();
+int
+main ()
+{
+return tgetent ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_tinfo_tgetent=yes
+else
+ ac_cv_lib_tinfo_tgetent=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5
+$as_echo "$ac_cv_lib_tinfo_tgetent" >&6; }
+if test "x$ac_cv_lib_tinfo_tgetent" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBTINFO 1
+_ACEOF
+
+ LIBS="-ltinfo $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: perhaps tgetent is in -lncurses" >&5
+$as_echo "$as_me: perhaps tgetent is in -lncurses" >&6;}
+fi
+
+
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: perhaps tgetent is in -lncurses" >&5
+$as_echo "$as_me: perhaps tgetent is in -lncurses" >&6;}
+fi
+
+fi
+
+LDFLAGS=$LDFLAGS0
+
+
+for ac_header in ncurses/curses.h ncurses.h curses.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+
+LDFLAGS0=$LDFLAGS
+LDFLAGS=$LDFLAGS$LDSTATIC
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setupterm in -lncurses" >&5
+$as_echo_n "checking for setupterm in -lncurses... " >&6; }
+if ${ac_cv_lib_ncurses_setupterm+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setupterm ();
+int
+main ()
+{
+return setupterm ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_ncurses_setupterm=yes
+else
+ ac_cv_lib_ncurses_setupterm=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_setupterm" >&5
+$as_echo "$ac_cv_lib_ncurses_setupterm" >&6; }
+if test "x$ac_cv_lib_ncurses_setupterm" = xyes; then :
+
+
+$as_echo "#define HAVE_LIBCURSES 1" >>confdefs.h
+
+LIBS=$LIBS$STATIC"-lncurses "$DYNAMIC
+
+else
+ if test "x$enable_static" = "xyes"; then
+
+{ ac_cv_lib_ncurses_setupterm=; unset ac_cv_lib_ncurses_setupterm;}
+LDFLAGS=$LDFLAGS0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setupterm in -lncurses" >&5
+$as_echo_n "checking for setupterm in -lncurses... " >&6; }
+if ${ac_cv_lib_ncurses_setupterm+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setupterm ();
+int
+main ()
+{
+return setupterm ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_ncurses_setupterm=yes
+else
+ ac_cv_lib_ncurses_setupterm=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_setupterm" >&5
+$as_echo "$ac_cv_lib_ncurses_setupterm" >&6; }
+if test "x$ac_cv_lib_ncurses_setupterm" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNCURSES 1
+_ACEOF
+
+ LIBS="-lncurses $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setupterm in -lcurses" >&5
+$as_echo_n "checking for setupterm in -lcurses... " >&6; }
+if ${ac_cv_lib_curses_setupterm+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setupterm ();
+int
+main ()
+{
+return setupterm ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_curses_setupterm=yes
+else
+ ac_cv_lib_curses_setupterm=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_setupterm" >&5
+$as_echo "$ac_cv_lib_curses_setupterm" >&6; }
+if test "x$ac_cv_lib_curses_setupterm" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+ LIBS="-lcurses $LIBS"
+
+fi
+
+fi
+
+
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setupterm in -lcurses" >&5
+$as_echo_n "checking for setupterm in -lcurses... " >&6; }
+if ${ac_cv_lib_curses_setupterm+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setupterm ();
+int
+main ()
+{
+return setupterm ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_curses_setupterm=yes
+else
+ ac_cv_lib_curses_setupterm=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_setupterm" >&5
+$as_echo "$ac_cv_lib_curses_setupterm" >&6; }
+if test "x$ac_cv_lib_curses_setupterm" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+ LIBS="-lcurses $LIBS"
+
+fi
+
+fi
+
+fi
+
+LDFLAGS=$LDFLAGS0
+
+fi
+
+# Check whether --enable-fftw was given.
+if test "${enable_fftw+set}" = set; then :
+ enableval=$enable_fftw;
+fi
+
+
+if test "x$enable_fftw" != "xno"; then
+
+ac_fn_cxx_check_header_mongrel "$LINENO" "fftw3.h" "ac_cv_header_fftw3_h" "$ac_includes_default"
+if test "x$ac_cv_header_fftw3_h" = xyes; then :
+
+LDFLAGS0=$LDFLAGS
+LDFLAGS=$LDFLAGS$LDSTATIC
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw_execute in -lfftw3" >&5
+$as_echo_n "checking for fftw_execute in -lfftw3... " >&6; }
+if ${ac_cv_lib_fftw3_fftw_execute+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfftw3 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fftw_execute ();
+int
+main ()
+{
+return fftw_execute ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_fftw3_fftw_execute=yes
+else
+ ac_cv_lib_fftw3_fftw_execute=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw3_fftw_execute" >&5
+$as_echo "$ac_cv_lib_fftw3_fftw_execute" >&6; }
+if test "x$ac_cv_lib_fftw3_fftw_execute" = xyes; then :
+
+
+$as_echo "#define HAVE_LIBFFTW3 1" >>confdefs.h
+
+LIBS=$LIBS$STATIC"-lfftw3 "$DYNAMIC
+
+else
+ if test "x$enable_static" = "xyes"; then
+
+{ ac_cv_lib_fftw3_fftw_execute=; unset ac_cv_lib_fftw3_fftw_execute;}
+LDFLAGS=$LDFLAGS0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw_execute in -lfftw3" >&5
+$as_echo_n "checking for fftw_execute in -lfftw3... " >&6; }
+if ${ac_cv_lib_fftw3_fftw_execute+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfftw3 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fftw_execute ();
+int
+main ()
+{
+return fftw_execute ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_fftw3_fftw_execute=yes
+else
+ ac_cv_lib_fftw3_fftw_execute=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw3_fftw_execute" >&5
+$as_echo "$ac_cv_lib_fftw3_fftw_execute" >&6; }
+if test "x$ac_cv_lib_fftw3_fftw_execute" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBFFTW3 1
+_ACEOF
+
+ LIBS="-lfftw3 $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libfftw3: will compile without optional fast Fourier transforms. ***" >&5
+$as_echo "$as_me: *** Could not find libfftw3: will compile without optional fast Fourier transforms. ***" >&6;}
+fi
+
+
+else
+{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libfftw3: will compile without optional fast Fourier transforms. ***" >&5
+$as_echo "$as_me: *** Could not find libfftw3: will compile without optional fast Fourier transforms. ***" >&6;}
+fi
+
+fi
+
+LDFLAGS=$LDFLAGS0
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Header file fftw3.h not found: will compile without optional fast Fourier transforms. ***" >&5
+$as_echo "$as_me: *** Header file fftw3.h not found: will compile without optional fast Fourier transforms. ***" >&6;}
+fi
+
+
+fi
+
+# Checks for header files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if ${ac_cv_header_sys_wait_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+ int s;
+ wait (&s);
+ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_header_sys_wait_h=yes
+else
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
+
+$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+for ac_header in fenv.h stddef.h libintl.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in fpu_control.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "fpu_control.h" "ac_cv_header_fpu_control_h" "$ac_includes_default"
+if test "x$ac_cv_header_fpu_control_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FPU_CONTROL_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in feenableexcept
+do :
+ ac_fn_cxx_check_func "$LINENO" "feenableexcept" "ac_cv_func_feenableexcept"
+if test "x$ac_cv_func_feenableexcept" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FEENABLEEXCEPT 1
+_ACEOF
+
+fi
+done
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include "xstream.h"
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing xdrstdio_create" >&5
+$as_echo_n "checking for library containing xdrstdio_create... " >&6; }
+if ${ac_cv_search_xdrstdio_create+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xdrstdio_create ();
+int
+main ()
+{
+return xdrstdio_create ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl tirpc; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_xdrstdio_create=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_xdrstdio_create+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_xdrstdio_create+:} false; then :
+
+else
+ ac_cv_search_xdrstdio_create=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_xdrstdio_create" >&5
+$as_echo "$ac_cv_search_xdrstdio_create" >&6; }
+ac_res=$ac_cv_search_xdrstdio_create
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+$as_echo "#define HAVE_RPC_RPC_H 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Broken rpc headers; XDR support disabled ***" >&5
+$as_echo "$as_me: WARNING: *** Broken rpc headers; XDR support disabled ***" >&2;}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check whether --enable-gsl was given.
+if test "${enable_gsl+set}" = set; then :
+ enableval=$enable_gsl;
+fi
+
+
+if test "x$enable_gsl" != "xno"; then
+ ac_fn_cxx_check_header_mongrel "$LINENO" "gsl/gsl_sf.h" "ac_cv_header_gsl_gsl_sf_h" "$ac_includes_default"
+if test "x$ac_cv_header_gsl_gsl_sf_h" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gsl_sf_debye_6 in -lgsl" >&5
+$as_echo_n "checking for gsl_sf_debye_6 in -lgsl... " >&6; }
+if ${ac_cv_lib_gsl_gsl_sf_debye_6+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgsl -lgslcblas $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gsl_sf_debye_6 ();
+int
+main ()
+{
+return gsl_sf_debye_6 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_gsl_gsl_sf_debye_6=yes
+else
+ ac_cv_lib_gsl_gsl_sf_debye_6=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gsl_gsl_sf_debye_6" >&5
+$as_echo "$ac_cv_lib_gsl_gsl_sf_debye_6" >&6; }
+if test "x$ac_cv_lib_gsl_gsl_sf_debye_6" = xyes; then :
+
+$as_echo "#define HAVE_LIBGSL 1" >>confdefs.h
+ LIBS=$LIBS"-lgsl -lgslcblas "
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libgsl: will compile without optional special functions. ***" >&5
+$as_echo "$as_me: *** Could not find libgsl: will compile without optional special functions. ***" >&6;}
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Header file gsl_sf.h not found: will compile without optional special functions. ***" >&5
+$as_echo "$as_me: *** Header file gsl_sf.h not found: will compile without optional special functions. ***" >&6;}
+fi
+
+
+fi
+
+# Check whether --enable-gl was given.
+if test "${enable_gl+set}" = set; then :
+ enableval=$enable_gl;
+fi
+
+
+# Check whether --enable-offscreen was given.
+if test "${enable_offscreen+set}" = set; then :
+ enableval=$enable_offscreen;
+fi
+
+
+# Check whether --enable-OpenImageIO was given.
+if test "${enable_OpenImageIO+set}" = set; then :
+ enableval=$enable_OpenImageIO;
+fi
+
+
+if test "x$enable_gl" != "xno"; then
+ ac_fn_cxx_check_header_mongrel "$LINENO" "glm/glm.hpp" "ac_cv_header_glm_glm_hpp" "$ac_includes_default"
+if test "x$ac_cv_header_glm_glm_hpp" = xyes; then :
+
+$as_echo "#define HAVE_LIBGLM 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find glm header files: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find glm header files: will compile without OpenGL support ***" >&6;}
+fi
+
+
+ for ac_header in ncurses/curses.h ncurses.h curses.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+if test "x$enable_openimageio" = "xyes"; then
+ ac_fn_cxx_check_header_mongrel "$LINENO" "OpenEXR/ImathVec.h" "ac_cv_header_OpenEXR_ImathVec_h" "$ac_includes_default"
+if test "x$ac_cv_header_OpenEXR_ImathVec_h" = xyes; then :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "OpenImageIO/imageio.h" "ac_cv_header_OpenImageIO_imageio_h" "$ac_includes_default"
+if test "x$ac_cv_header_OpenImageIO_imageio_h" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for open in -lOpenImageIO" >&5
+$as_echo_n "checking for open in -lOpenImageIO... " >&6; }
+if ${ac_cv_lib_OpenImageIO_open+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lOpenImageIO $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char open ();
+int
+main ()
+{
+return open ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_OpenImageIO_open=yes
+else
+ ac_cv_lib_OpenImageIO_open=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_OpenImageIO_open" >&5
+$as_echo "$ac_cv_lib_OpenImageIO_open" >&6; }
+if test "x$ac_cv_lib_OpenImageIO_open" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBOPENIMAGEIO 1
+_ACEOF
+
+ LIBS="-lOpenImageIO $LIBS"
+
+fi
+
+fi
+
+
+fi
+
+
+fi
+
+case "$OSTYPE" in
+ cygwin)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GC_throw_bad_alloc in -lgccpp" >&5
+$as_echo_n "checking for GC_throw_bad_alloc in -lgccpp... " >&6; }
+if ${ac_cv_lib_gccpp_GC_throw_bad_alloc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgccpp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GC_throw_bad_alloc ();
+int
+main ()
+{
+return GC_throw_bad_alloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_gccpp_GC_throw_bad_alloc=yes
+else
+ ac_cv_lib_gccpp_GC_throw_bad_alloc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gccpp_GC_throw_bad_alloc" >&5
+$as_echo "$ac_cv_lib_gccpp_GC_throw_bad_alloc" >&6; }
+if test "x$ac_cv_lib_gccpp_GC_throw_bad_alloc" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGCCPP 1
+_ACEOF
+
+ LIBS="-lgccpp $LIBS"
+
+fi
+
+ ac_fn_cxx_check_header_mongrel "$LINENO" "GL/glut.h" "ac_cv_header_GL_glut_h" "$ac_includes_default"
+if test "x$ac_cv_header_GL_glut_h" = xyes; then :
+
+$as_echo "#define HAVE_LIBGLUT 1" >>confdefs.h
+
+ LIBS=$LIBS"-lfreeglut "
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libfreeglut: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find libfreeglut: will compile without OpenGL support ***" >&6;}
+fi
+
+
+ ac_fn_cxx_check_header_mongrel "$LINENO" "GL/gl.h" "ac_cv_header_GL_gl_h" "$ac_includes_default"
+if test "x$ac_cv_header_GL_gl_h" = xyes; then :
+
+$as_echo "#define HAVE_LIBGL 1" >>confdefs.h
+
+ LIBS=$LIBS"-lopengl32 glew.o"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libopengl32: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find libopengl32: will compile without OpenGL support ***" >&6;}
+fi
+
+
+ ;;
+ darwin*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GC_throw_bad_alloc in -lgccpp" >&5
+$as_echo_n "checking for GC_throw_bad_alloc in -lgccpp... " >&6; }
+if ${ac_cv_lib_gccpp_GC_throw_bad_alloc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgccpp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GC_throw_bad_alloc ();
+int
+main ()
+{
+return GC_throw_bad_alloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_gccpp_GC_throw_bad_alloc=yes
+else
+ ac_cv_lib_gccpp_GC_throw_bad_alloc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gccpp_GC_throw_bad_alloc" >&5
+$as_echo "$ac_cv_lib_gccpp_GC_throw_bad_alloc" >&6; }
+if test "x$ac_cv_lib_gccpp_GC_throw_bad_alloc" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGCCPP 1
+_ACEOF
+
+ LIBS="-lgccpp $LIBS"
+
+fi
+
+ ac_fn_cxx_check_header_mongrel "$LINENO" "OpenGL/gl.h" "ac_cv_header_OpenGL_gl_h" "$ac_includes_default"
+if test "x$ac_cv_header_OpenGL_gl_h" = xyes; then :
+
+$as_echo "#define HAVE_LIBGL 1" >>confdefs.h
+
+fi
+
+
+ ac_fn_cxx_check_header_mongrel "$LINENO" "GLUT/glut.h" "ac_cv_header_GLUT_glut_h" "$ac_includes_default"
+if test "x$ac_cv_header_GLUT_glut_h" = xyes; then :
+
+$as_echo "#define HAVE_LIBGLUT 1" >>confdefs.h
+
+ LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa glew.o "
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GLUT: will compile without OpenGLLUT support ***" >&5
+$as_echo "$as_me: *** Could not find GLUT: will compile without OpenGLLUT support ***" >&6;}
+fi
+
+
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GC_throw_bad_alloc in -lgccpp" >&5
+$as_echo_n "checking for GC_throw_bad_alloc in -lgccpp... " >&6; }
+if ${ac_cv_lib_gccpp_GC_throw_bad_alloc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgccpp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GC_throw_bad_alloc ();
+int
+main ()
+{
+return GC_throw_bad_alloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_gccpp_GC_throw_bad_alloc=yes
+else
+ ac_cv_lib_gccpp_GC_throw_bad_alloc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gccpp_GC_throw_bad_alloc" >&5
+$as_echo "$ac_cv_lib_gccpp_GC_throw_bad_alloc" >&6; }
+if test "x$ac_cv_lib_gccpp_GC_throw_bad_alloc" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGCCPP 1
+_ACEOF
+
+ LIBS="-lgccpp $LIBS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glutMainLoop in -lglut" >&5
+$as_echo_n "checking for glutMainLoop in -lglut... " >&6; }
+if ${ac_cv_lib_glut_glutMainLoop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lglut $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char glutMainLoop ();
+int
+main ()
+{
+return glutMainLoop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_glut_glutMainLoop=yes
+else
+ ac_cv_lib_glut_glutMainLoop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glut_glutMainLoop" >&5
+$as_echo "$ac_cv_lib_glut_glutMainLoop" >&6; }
+if test "x$ac_cv_lib_glut_glutMainLoop" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGLUT 1
+_ACEOF
+
+ LIBS="-lglut $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libglut: will compile without GLUT support ***" >&5
+$as_echo "$as_me: *** Could not find libglut: will compile without GLUT support ***" >&6;}
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glDepthMask in -lGL" >&5
+$as_echo_n "checking for glDepthMask in -lGL... " >&6; }
+if ${ac_cv_lib_GL_glDepthMask+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lGL $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char glDepthMask ();
+int
+main ()
+{
+return glDepthMask ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_GL_glDepthMask=yes
+else
+ ac_cv_lib_GL_glDepthMask=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glDepthMask" >&5
+$as_echo "$ac_cv_lib_GL_glDepthMask" >&6; }
+if test "x$ac_cv_lib_GL_glDepthMask" = xyes; then :
+
+$as_echo "#define HAVE_LIBGL 1" >>confdefs.h
+
+ LIBS=$LIBS"-lGL glew.o "
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libGL: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find libGL: will compile without OpenGL support ***" >&6;}
+fi
+
+esac
+ if test "x$enable_offscreen" = "xyes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSMesaCreateContext in -lOSMesa" >&5
+$as_echo_n "checking for OSMesaCreateContext in -lOSMesa... " >&6; }
+if ${ac_cv_lib_OSMesa_OSMesaCreateContext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lOSMesa $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char OSMesaCreateContext ();
+int
+main ()
+{
+return OSMesaCreateContext ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_OSMesa_OSMesaCreateContext=yes
+else
+ ac_cv_lib_OSMesa_OSMesaCreateContext=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_OSMesa_OSMesaCreateContext" >&5
+$as_echo "$ac_cv_lib_OSMesa_OSMesaCreateContext" >&6; }
+if test "x$ac_cv_lib_OSMesa_OSMesaCreateContext" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBOSMESA 1
+_ACEOF
+
+ LIBS="-lOSMesa $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libOSMesa: will compile without offscreen rendering support ***" >&5
+$as_echo "$as_me: *** Could not find libOSMesa: will compile without offscreen rendering support ***" >&6;}
+fi
+
+ fi
+fi
+
+# Checks for typedefs, structures, and compiler characteristics.
+ac_fn_cxx_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_cxx_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default"
+if test "x$ac_cv_type_ptrdiff_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PTRDIFF_T 1
+_ACEOF
+
+
+fi
+
+ac_fn_cxx_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
+if test "x$ac_cv_type_long_long" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG_LONG 1
+_ACEOF
+
+
+fi
+
+ac_fn_cxx_check_type "$LINENO" "long" "ac_cv_type_long" "$ac_includes_default"
+if test "x$ac_cv_type_long" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG 1
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if ${ac_cv_type_signal+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_type_signal=int
+else
+ ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+
+
+# Checks for library functions.
+for ac_header in vfork.h
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
+if test "x$ac_cv_header_vfork_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VFORK_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in fork vfork
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if ${ac_cv_func_fork_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_fork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* By Ruediger Kuhlmann. */
+ return fork () < 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+ ac_cv_func_fork_works=yes
+else
+ ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+ ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+ case $host in
+ *-*-amigaos* | *-*-msdosdjgpp*)
+ # Override, as these systems have only a dummy fork() stub
+ ac_cv_func_fork_works=no
+ ;;
+ *)
+ ac_cv_func_fork_works=yes
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if ${ac_cv_func_vfork_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_vfork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Thanks to Paul Eggert for this test. */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent. The compiler
+ is told about this with #include <vfork.h>, but some compilers
+ (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
+ static variable whose address is put into a register that is
+ clobbered by the vfork. */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+
+int
+main ()
+{
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test (0);
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems. This
+ test uses lots of local variables, at least as many local
+ variables as main has allocated so far including compiler
+ temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
+ 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
+ reuse the register of parent for one of the local variables,
+ since it will think that parent can't possibly be used any more
+ in this routine. Assigning to the local variable will thus
+ munge parent in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+ from child file descriptors. If the child closes a descriptor
+ before it execs or exits, this munges the parent's descriptor
+ as well. Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ return (
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+ ac_cv_func_vfork_works=yes
+else
+ ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+ ac_cv_func_vfork_works=$ac_cv_func_vfork
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+$as_echo "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+for ac_func in dup2 floor memset pow sqrt strchr tgamma memrchr
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strftime
+do :
+ ac_fn_cxx_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
+if test "x$ac_cv_func_strftime" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRFTIME 1
+_ACEOF
+
+else
+ # strftime is in -lintl on SCO UNIX.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5
+$as_echo_n "checking for strftime in -lintl... " >&6; }
+if ${ac_cv_lib_intl_strftime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strftime ();
+int
+main ()
+{
+return strftime ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_intl_strftime=yes
+else
+ ac_cv_lib_intl_strftime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5
+$as_echo "$ac_cv_lib_intl_strftime" >&6; }
+if test "x$ac_cv_lib_intl_strftime" = xyes; then :
+ $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h
+
+LIBS="-lintl $LIBS"
+fi
+
+fi
+done
+
+
+ for ac_func in strptime
+do :
+ ac_fn_cxx_check_func "$LINENO" "strptime" "ac_cv_func_strptime"
+if test "x$ac_cv_func_strptime" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRPTIME 1
+_ACEOF
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
+$as_echo_n "checking for error_at_line... " >&6; }
+if ${ac_cv_lib_error_at_line+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <error.h>
+int
+main ()
+{
+error_at_line (0, 0, "", 0, "an error occurred");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_error_at_line=yes
+else
+ ac_cv_lib_error_at_line=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5
+$as_echo "$ac_cv_lib_error_at_line" >&6; }
+if test $ac_cv_lib_error_at_line = no; then
+ case " $LIBOBJS " in
+ *" error.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS error.$ac_objext"
+ ;;
+esac
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_source+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGEFILE_SOURCE 1
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_cv_sys_largefile_source=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
+$as_echo "$ac_cv_sys_largefile_source" >&6; }
+case $ac_cv_sys_largefile_source in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+;;
+esac
+rm -rf conftest*
+
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+if test $ac_cv_sys_largefile_source != unknown; then
+
+$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
+
+fi
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+ac_config_files="$ac_config_files Makefile doc/Makefile doc/png/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Asymptote $as_me 2.53, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <http://sourceforge.net/projects/asymptote>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+Asymptote config.status 2.53
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "doc/png/Makefile") CONFIG_FILES="$CONFIG_FILES doc/png/Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+if test "x$GCDIR" != "x" ; then
+ as_ac_File=`$as_echo "ac_cv_file_$GCDIR.tar.gz" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $GCDIR.tar.gz" >&5
+$as_echo_n "checking for $GCDIR.tar.gz... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "$GCDIR.tar.gz"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+eval ac_res=\$$as_ac_File
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
+
+else
+
+ echo
+ echo Please put the Boehm garbage collector tar.gz files in the asymptote directory.
+ echo FOR EXAMPLE, USE THE COMMANDS:
+ echo
+ echo wget https://github.com/ivmai/bdwgc/releases/download/v$GCVERSION/$GCFILE.tar.gz
+ echo wget http://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-$ATOMICVERSION.tar.gz
+
+ echo
+ exit 1
+
+fi
+
+fi
diff --git a/graphics/asymptote/configure.ac b/graphics/asymptote/configure.ac
new file mode 100644
index 0000000000..92dd1ded2b
--- /dev/null
+++ b/graphics/asymptote/configure.ac
@@ -0,0 +1,455 @@
+# -*- Autoconf -*-
+# Run autoheader and autoconf to produce a header and configure script from
+# this file.
+
+AC_PREREQ(2)
+AC_INIT([Asymptote],[2.53],[http://sourceforge.net/projects/asymptote])
+VERSION=$PACKAGE_VERSION
+AC_SUBST(VERSION)
+m4_include([ax_pthread.m4])
+
+test "$CXXFLAGS" || CXXFLAGS="-std=c++11"
+
+test "$CFLAGS" || CFLAGS="-g -O3"
+
+AC_C_BIGENDIAN
+AC_CANONICAL_HOST
+
+test "$prefix" = NONE && prefix=/usr/local
+Datadir=$datadir
+test "$Datadir" = '${datarootdir}' && Datadir=$datarootdir
+test "$Datadir" = '${prefix}/share' && Datadir=$prefix/share
+AC_SUBST(Datadir)
+
+AC_ARG_WITH(latex,
+ [AS_HELP_STRING(--with-latex=PATH,
+ specify path to LaTeX installation)],
+ [if test "x$withval" != "x" ; then
+ latexdir=$withval
+ fi
+ ],[
+AC_CHECK_PROG(kpsewhich,kpsewhich,true)
+if test "x$kpsewhich" = "xtrue"; then
+ latexdir=`kpsewhich -expand-var='$TEXMFLOCAL'/tex/latex`
+else
+ latexdir=$prefix/share/texmf/tex/latex
+ AC_CHECK_FILE($latexdir/base/latex.ltx,,
+ [latexdir=/usr/share/texmf/tex/latex
+ AC_CHECK_FILE($latexdir/base/latex.ltx,,)])
+fi
+])
+
+AC_ARG_WITH(context,
+ [AS_HELP_STRING(--with-context=PATH,
+ specify path to ConTeXt installation)],
+ [if test "x$withval" != "x" ; then
+ contextdir=$withval
+ fi
+ ],[
+AC_CHECK_PROG(kpsewhich,kpsewhich,true)
+if test "x$kpsewhich" = "xtrue"; then
+ contextdir=`kpsewhich -expand-var='$TEXMFLOCAL'/tex/context/third`
+else
+ contextdir=$prefix/share/texmf/tex/context/third
+fi
+])
+
+AC_CHECK_PROGS(TEXI2DVI,[texi2dvi],
+[@echo \*\*\*\*\*\*\*\*\*\* Please install texi2dvi or put http://asymptote.sourceforge.net/asymptote.pdf in the doc directory: cannot execute texi2dvi])
+
+AC_SUBST(TEXI2DVI)
+
+latexdir=$latexdir/asymptote
+contextdir=$contextdir/asymptote
+
+AC_MSG_NOTICE([Using $latexdir for LaTeX style file])
+AC_MSG_NOTICE([Using $contextdir for ConTeXT style file])
+
+AC_SUBST(latexdir)
+AC_SUBST(contextdir)
+
+docdir=$Datadir/doc/asymptote
+
+AC_ARG_WITH(docdir,
+ [AS_HELP_STRING(--with-docdir=PATH,
+alternate documentation installation directory)],
+ [if test "x$withval" != "x" ; then
+ docdir=$withval
+ fi
+ ])
+AC_SUBST(docdir)
+
+sysdir=$Datadir/asymptote
+
+AC_ARG_ENABLE(texlive-build,
+[AS_HELP_STRING(--enable-texlive-build,
+automatically determine sysdir from kpsewhich)],
+[ if test "x$enableval" = "xyes" ; then
+ sysdir=""
+ fi
+])
+
+AC_DEFINE_UNQUOTED(ASYMPTOTE_SYSDIR,"$sysdir",
+ [System directory for global .asy files])
+AC_DEFINE_UNQUOTED(ASYMPTOTE_DOCDIR,"$docdir",
+ [Directory for documentation])
+
+AC_CONFIG_SRCDIR([absyn.cc])
+
+AC_LANG([C++])
+
+# Checks for programs.
+AC_PROG_LEX
+AC_PROG_CXX
+AC_PROG_INSTALL
+AC_PROG_CC
+AC_PROG_MAKE_SET
+AC_PROG_YACC
+
+if test "$GXX" = yes ; then
+ ac_gcc_version=`echo __GNUC__ | $CC -E - | grep -v ^\#`
+ ac_clang=`echo __clang__ | $CC -E - | grep -v ^\#`
+ if test "$ac_gcc_version" -lt 4; then
+ CFLAGS=$CFLAGS" -finline-limit=400"
+ else
+ if test "$ac_clang" != 1; then
+ CFLAGS=$CFLAGS" -fno-var-tracking"
+ fi
+ fi
+fi
+
+AC_DEFUN([DEFINE],[
+Define to 1 if you have $1.
+])
+
+AC_DEFUN([DEFINE_LIB],[
+Define to 1 if you have the `$1' library (-l$1).
+])
+
+AC_CHECK_HEADER(tr1/unordered_map,AC_DEFINE(HAVE_TR1_UNORDERED_MAP,1,
+ DEFINE([<tr1/unordered_map>])),
+ [AC_CHECK_HEADER(unordered_map,AC_DEFINE(HAVE_UNORDERED_MAP,1,
+ DEFINE([<unordered_map>])),
+ [AC_CHECK_HEADER(ext/hash_map,,OPTIONS=$OPTIONS"-DNOHASH ")])])
+
+GCVERSION=8.0.4
+ATOMICVERSION=7.6.10
+
+GCFILE=gc-$GCVERSION
+ac_cv_use_gc="system"
+
+AC_CHECK_FILE($GCFILE.tar.gz,
+ac_cv_use_gc=$GCVERSION)
+AC_ARG_ENABLE(gc,
+ [AS_HELP_STRING(--enable-gc[[[=system]]],
+enable system Boehm garbage collector)]
+ [ [[=VERSION]] enable local VERSION of Boehm garbage collector]
+ [ [[=PREFIX]] use Boehm garbage collector installed in PREFIX],
+ [
+ if test "x$enableval" != "xyes" ; then
+ ac_cv_use_gc=$enableval
+ fi
+ ])
+
+OPTIONS="-D_FILE_OFFSET_BITS=64 "
+GCLIB=
+GCPPLIB=
+INCL="-I."
+GCNAME="Boehm Garbage Collector"
+GCOPTIONS="--disable-shared"
+if test "x$ac_cv_use_gc" != "xno" ; then
+ OPTIONS=$OPTIONS"-DUSEGC "
+ case _$ac_cv_use_gc in
+ _|_system|_*[[\\/]]*)
+ if test "x$ac_cv_use_gc" = "xsystem" ; then
+ INCL="-I. -I$prefix/include/gc -I/usr/include/gc"
+ LIBS=$LIBS"-L$prefix/lib "
+ else
+ INCL="-I$ac_cv_use_gc/include/gc"
+ LIBS=$LIBS"-L$ac_cv_use_gc/lib "
+ fi
+ CPPFLAGS_SAVE=$CPPFLAGS
+ CPPFLAGS=$CPPFLAGS" $INCL"
+ AC_CHECK_HEADER(gc.h,
+ AC_CHECK_LIB([gc],[GC_malloc],[
+ LIBS=$LIBS"-lgc "
+ AC_MSG_NOTICE([enabling system $GCNAME])],[
+ GCDIR=$GCFILE
+ INCL="-I. -I\$(GC)/include"
+ GCLIB="\$(GC)/.libs/libgc.a"
+ AC_MSG_NOTICE($GCNAME library not found)]),
+ GCDIR=$GCFILE
+ GCLIB="\$(GC)/.libs/libgc.a"
+ INCL="-I. -I\$(GC)/include"
+ AC_MSG_NOTICE($GCNAME header file not found))
+ CPPFLAGS=$CPPFLAGS_SAVE
+ ;;
+ *)
+ GCVERSION=$ac_cv_use_gc
+ GCFILE=gc-$GCVERSION
+ GCDIR=$GCFILE
+ AC_MSG_NOTICE([enabling local $GCNAME $GCDIR])
+ GCLIB="\$(GC)/.libs/libgc.a"
+ INCL="-I. -I\$(GC)/include"
+ ;;
+ esac
+else
+ AC_MSG_NOTICE([disabling the $GCNAME])
+fi
+
+AC_ARG_ENABLE(gc-debug,
+[AS_HELP_STRING(--enable-gc-debug,enable (slow) garbage collector debugging)],
+[ if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG "
+ AC_MSG_NOTICE([*** Enabling GC debugging: remember to make clean ***])
+ AC_MSG_NOTICE([*** Set the environment variable GC_FIND_LEAK at runtime ***])
+ fi
+ fi
+])
+
+AC_ARG_ENABLE(gc-full-debug,
+[AS_HELP_STRING(--enable-gc-full-debug,enable (very slow) garbage collector backtrace)],
+[ if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG -DGC_BACKTRACE "
+ GCOPTIONS=$GCOPTIONS"--enable-gc-debug "
+ AC_MSG_NOTICE([*** Enabling GC backtrace debugging; remember to make gc-clean ***])
+ fi
+ fi
+])
+
+INCL=$INCL" -I/usr/include/tirpc"
+
+if test "$OSTYPE" = "cygwin"; then
+CPPFLAGS=$CPPFLAGS" -D__MSDOS__ -I/usr/include/w32api -I/usr/include -DCALLBACK=__stdcall $INCL"
+else
+CPPFLAGS=$CPPFLAGS" $INCL"
+fi
+
+AC_CHECK_FUNC(getopt_long_only, AC_DEFINE(HAVE_GNU_GETOPT_H, 1,
+ DEFINE([GNU <getopt.h>])),
+ getopt="getopt getopt1",)
+
+AC_SUBST(getopt)
+AC_SUBST(GCVERSION)
+AC_SUBST(ATOMICVERSION)
+AC_SUBST(GCOPTIONS)
+AC_SUBST(GCLIB)
+AC_SUBST(GCPPLIB)
+AC_SUBST(INCL)
+AC_SUBST(OPTIONS)
+
+# Checks for libraries.
+AC_SEARCH_LIBS([lgamma],[m c],,
+AC_MSG_ERROR([*** Please install libm on your system ***]))
+AC_CHECK_LIB([z], [deflate],,
+AC_MSG_ERROR([*** Please install libz or zlib-devel on your system ***]))
+AX_PTHREAD
+
+AC_ARG_ENABLE(sigsegv,
+[AS_HELP_STRING(--enable-sigsegv[[[=yes]]],enable GNU Stack Overflow Handler)])
+
+if test "x$enable_sigsegv" != "xno"; then
+ AC_CHECK_LIB([sigsegv], [stackoverflow_install_handler])
+fi
+
+AC_CHECK_LIB([rt], [sched_yield])
+
+AC_ARG_ENABLE(readline,
+[AS_HELP_STRING(--enable-readline[[[=yes]]],enable GNU Readline Library)])
+
+AC_ARG_ENABLE(static,
+[AS_HELP_STRING(--enable-static[[[=no]]],link against static libraries)])
+
+LDSTATIC=""
+STATIC=""
+DYNAMIC=""
+if test "x$enable_static" = "xyes"; then
+ LDSTATIC="-static "
+ STATIC="-Wl,-Bstatic "
+ DYNAMIC="-Wl,-Bdynamic "
+fi
+
+AC_DEFUN([READLINE],[
+AC_MSG_NOTICE([*** Could not find GNU readline 4.3 or later: will compile without readline support ***])
+])
+
+AC_DEFUN([CHECK_FOUND_STATIC],[
+AC_DEFINE($1,1,DEFINE_LIB($2))
+LIBS=$LIBS$STATIC"-l$2 "$DYNAMIC
+])
+
+AC_DEFUN([AC_CHECK_LIB_STATIC],[
+LDFLAGS0=$LDFLAGS
+LDFLAGS=$LDFLAGS$LDSTATIC
+AC_CHECK_LIB($1,$2,CHECK_FOUND_STATIC($3,$1),
+if test "x$enable_static" = "xyes"; then
+[
+AS_UNSET([ac_cv_lib_$1_$2])
+LDFLAGS=$LDFLAGS0
+AC_CHECK_LIB($1,$2,,$4)
+]
+else
+$4
+fi
+)
+LDFLAGS=$LDFLAGS0
+])
+
+if test "x$enable_readline" != "xno"; then
+AC_COMPILE_IFELSE([
+AC_LANG_PROGRAM([
+#include <stdio.h>
+#include <unistd.h>
+#include <readline/readline.h>
+],[
+#ifndef RL_READLINE_VERSION
+abort
+#endif
+])],
+AC_CHECK_LIB_STATIC(readline,history_list,HAVE_LIBREADLINE,READLINE),
+READLINE)
+
+AC_CHECK_LIB_STATIC(tinfo,tgetent,HAVE_LIBTINFO,AC_MSG_NOTICE([perhaps tgetent is in -lncurses]))
+
+AC_CHECK_HEADERS([ncurses/curses.h ncurses.h curses.h],[break])
+AC_CHECK_LIB_STATIC([ncurses],[setupterm],HAVE_LIBCURSES,
+ AC_CHECK_LIB([curses],[setupterm]))
+fi
+
+AC_ARG_ENABLE(fftw,
+[AS_HELP_STRING(--enable-fftw[[[=yes]]],enable FFTW Library)])
+
+if test "x$enable_fftw" != "xno"; then
+
+AC_CHECK_HEADER(fftw3.h,
+AC_CHECK_LIB_STATIC([fftw3],[fftw_execute],HAVE_LIBFFTW3,
+ AC_MSG_NOTICE([*** Could not find libfftw3: will compile without optional fast Fourier transforms. ***])),
+ AC_MSG_NOTICE([*** Header file fftw3.h not found: will compile without optional fast Fourier transforms. ***]))
+fi
+
+# Checks for header files.
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([fenv.h stddef.h libintl.h])
+AC_CHECK_HEADERS(fpu_control.h)
+AC_CHECK_FUNCS([feenableexcept])
+
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include "xstream.h"])],
+ [AC_SEARCH_LIBS([xdrstdio_create],[nsl tirpc])
+ AC_DEFINE(HAVE_RPC_RPC_H,1,
+ DEFINE([a working <tirpc/rpc/rpc.h> header]))],
+ AC_MSG_WARN([*** Broken rpc headers; XDR support disabled ***]))
+
+AC_ARG_ENABLE(gsl,
+[AS_HELP_STRING(--enable-gsl[[[=yes]]],enable GNU Scientific Library)])
+
+if test "x$enable_gsl" != "xno"; then
+ AC_CHECK_HEADER(gsl/gsl_sf.h,
+ AC_CHECK_LIB([gsl], gsl_sf_debye_6, [AC_DEFINE(HAVE_LIBGSL,1,
+ DEFINE_LIB[gsl]) LIBS=$LIBS"-lgsl -lgslcblas "],
+ AC_MSG_NOTICE([*** Could not find libgsl: will compile without optional special functions. ***]),[-lgslcblas]),
+ AC_MSG_NOTICE([*** Header file gsl_sf.h not found: will compile without optional special functions. ***]))
+fi
+
+AC_ARG_ENABLE(gl,
+[AS_HELP_STRING(--enable-gl[[[=yes]]],enable OpenGL Library)])
+
+AC_ARG_ENABLE(offscreen,
+[AS_HELP_STRING(--enable-offscreen[[[=no]]],enable experimental offscreen rendering using OSMesa library)])
+
+AC_ARG_ENABLE(OpenImageIO,
+[AS_HELP_STRING(--enable-openimageio[[[=no]]],enable experimental OpenImageIO Library)])
+
+if test "x$enable_gl" != "xno"; then
+ AC_CHECK_HEADER(glm/glm.hpp,
+ [AC_DEFINE(HAVE_LIBGLM,1,
+ DEFINE([the <glm/glm.hpp> header]))],AC_MSG_NOTICE([*** Could not find glm header files: will compile without OpenGL support ***]))
+ AC_CHECK_HEADERS([ncurses/curses.h ncurses.h curses.h],[break])
+if test "x$enable_openimageio" = "xyes"; then
+ AC_CHECK_HEADER([OpenEXR/ImathVec.h],
+ AC_CHECK_HEADER([OpenImageIO/imageio.h],
+ AC_CHECK_LIB([OpenImageIO],[open])))
+fi
+
+case "$OSTYPE" in
+ cygwin)
+ AC_CHECK_LIB([gccpp],[GC_throw_bad_alloc])
+ AC_CHECK_HEADER(GL/glut.h,
+ [AC_DEFINE(HAVE_LIBGLUT,1,
+ DEFINE_LIB[freeglut])
+ LIBS=$LIBS"-lfreeglut "],
+ AC_MSG_NOTICE([*** Could not find libfreeglut: will compile without OpenGL support ***]))
+ AC_CHECK_HEADER(GL/gl.h,
+ [AC_DEFINE(HAVE_LIBGL,1,
+ DEFINE_LIB[opengl32])
+ LIBS=$LIBS"-lopengl32 glew.o"],
+ AC_MSG_NOTICE([*** Could not find libopengl32: will compile without OpenGL support ***]))
+ ;;
+ darwin*)
+ AC_CHECK_LIB([gccpp],[GC_throw_bad_alloc])
+ AC_CHECK_HEADER(OpenGL/gl.h,
+ [AC_DEFINE(HAVE_LIBGL,1,
+ DEFINE([<gl.h> header]))])
+ AC_CHECK_HEADER(GLUT/glut.h, [AC_DEFINE(HAVE_LIBGLUT,1,
+ DEFINE_LIB[GLUT])
+ LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa glew.o "],
+ AC_MSG_NOTICE([*** Could not find GLUT: will compile without OpenGLLUT support ***]))
+ ;;
+ *)
+ AC_CHECK_LIB([gccpp],[GC_throw_bad_alloc])
+ AC_CHECK_LIB([glut], [glutMainLoop],,
+ AC_MSG_NOTICE([*** Could not find libglut: will compile without GLUT support ***]))
+ AC_CHECK_LIB([GL], [glDepthMask],
+ [AC_DEFINE(HAVE_LIBGL,1,
+ DEFINE_LIB([GL]))
+ LIBS=$LIBS"-lGL glew.o "],
+ AC_MSG_NOTICE([*** Could not find libGL: will compile without OpenGL support ***]))
+esac
+ if test "x$enable_offscreen" = "xyes"; then
+ AC_CHECK_LIB([OSMesa],OSMesaCreateContext,,
+ AC_MSG_NOTICE([*** Could not find libOSMesa: will compile without offscreen rendering support ***]))
+ fi
+fi
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_CHECK_TYPES([ptrdiff_t])
+AC_CHECK_TYPES([long long])
+AC_CHECK_TYPES([long])
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIGNAL
+
+AC_DEFUN([ac_FUNC_STRPTIME], [
+ AC_CHECK_FUNCS(strptime)
+])
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_CHECK_FUNCS([dup2 floor memset pow sqrt strchr tgamma memrchr])
+AC_FUNC_STRFTIME
+ac_FUNC_STRPTIME
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FSEEKO
+
+AC_CONFIG_HEADERS(config.h)
+
+AC_CONFIG_FILES([Makefile doc/Makefile doc/png/Makefile])
+AC_OUTPUT
+
+if test "x$GCDIR" != "x" ; then
+ AC_CHECK_FILE($GCDIR.tar.gz,,[
+ echo
+ echo Please put the Boehm garbage collector tar.gz files in the asymptote directory.
+ echo FOR EXAMPLE, USE THE COMMANDS:
+ echo
+ echo wget https://github.com/ivmai/bdwgc/releases/download/v$GCVERSION/$GCFILE.tar.gz
+ echo wget http://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-$ATOMICVERSION.tar.gz
+
+ echo
+ exit 1
+ ])
+fi
diff --git a/graphics/asymptote/constructor.cc b/graphics/asymptote/constructor.cc
new file mode 100644
index 0000000000..87960f1842
--- /dev/null
+++ b/graphics/asymptote/constructor.cc
@@ -0,0 +1,143 @@
+/*****
+ * constructor.cc
+ * Andy Hammerlindl 2007/05/12
+ *
+ * Using
+ *
+ * void operator init(<args>)
+ *
+ * as a field in the definition structure named Foo implicitly creates a
+ * function that could be explicitly defined with code similar to
+ *
+ * static Foo Foo(<args>) {
+ * Foo a=new Foo;
+ * a.operator init(<args>);
+ * return a;
+ * }
+ *
+ * This function is usable within further code in the structure definition and,
+ * after the end of the structure definition, is carried over into the enclosing
+ * scope so that it lasts as long as the type definition.
+ *****/
+
+#include "stack.h"
+#include "entry.h"
+#include "coenv.h"
+#include "dec.h"
+#include "newexp.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+
+// Defined in dec.cc.
+varEntry *makeVarEntry(position pos, coenv &e, record *r, types::ty *t);
+
+bool definesImplicitConstructor(coenv &e, record *r, varEntry *v, symbol id)
+{
+ if (id == symbol::initsym &&
+ r != 0 &&
+ v->getType()->kind == ty_function &&
+ e.c.isStatic() == false &&
+ e.c.isTopLevel() == false)
+ {
+ function *ft=dynamic_cast<function *>(v->getType());
+ if (ft->getResult()->kind == ty_void)
+ return true;
+ }
+
+ return false;
+}
+
+// Given the coenv of the body of the constructor, encode the neccessary
+// instructions to make a new initialized object.
+void transConstructorBody(position pos, coenv &e, record *r, varEntry *init)
+{
+ assert(r);
+ assert(init);
+
+ // Create a varEntry to hold the new object. Foo a;
+ varEntry *v=makeVarEntry(pos, e, 0 /* not a field */, r);
+
+ // Initialize the object. a=new Foo;
+ newRecordExp::transFromTyEntry(pos, e, new tyEntry(r, 0, 0, position()));
+ v->encode(WRITE, pos, e.c);
+ e.c.encodePop();
+
+ // Push the args onto the stack.
+ size_t numArgs=init->getSignature()->getNumFormals();
+ for (size_t i=0; i<numArgs; ++i) {
+ access *a=e.c.accessFormal((Int)i);
+ a->encode(READ, pos, e.c);
+ }
+
+ // Push the object on the stack.
+ v->encode(READ, pos, e.c);
+
+ // Call the 'operator init' field of the object.
+ init->encode(CALL, pos, e.c, v->getLevel());
+
+ // Push the object again.
+ v->encode(READ, pos, e.c);
+
+ // Return the initialized object.
+ e.c.encode(inst::ret);
+}
+
+varEntry *constructorFromInitializer(position pos, coenv &e, record *r,
+ varEntry *init)
+{
+ assert(r);
+
+ types::function *ft=new types::function(r, init->getSignature());
+
+ ostringstream out;
+ ft->printVar(out, symbol::trans("<constructor>"));
+
+ // Create a new function environment.
+ coder fc = e.c.newFunction(pos, out.str(), ft);
+ coenv fe(fc,e.e);
+
+ // Translate the function.
+ fe.e.beginScope();
+
+ transConstructorBody(pos, fe, r, init);
+
+ fe.e.endScope();
+
+ // Put an instance of the new function on the stack.
+ vm::lambda *l = fe.c.close();
+ e.c.encode(inst::pushclosure);
+ e.c.encode(inst::makefunc, l);
+
+ // Save it into a varEntry.
+ varEntry *v=makeVarEntry(pos, e, r, ft);
+ v->encode(WRITE, pos, e.c);
+ e.c.encodePop();
+
+ return v;
+}
+
+void addConstructorFromInitializer(position pos, coenv &e, record *r,
+ varEntry *init)
+{
+ assert(r);
+
+ // Constructors are declared statically.
+ e.c.pushModifier(EXPLICIT_STATIC);
+
+ varEntry *v=constructorFromInitializer(pos, e, r, init);
+
+ // Add the constructor function under the same name as the record.
+ addVar(e, r, v, r->getName());
+
+ // Add to the "post definition environment" of the record, so it will also be
+ // added to the enclosing scope when the record definition ends.
+ r->postdefenv.addVar(r->getName(), v);
+
+ e.c.popModifier();
+}
+
+} // namespace absyntax
+
diff --git a/graphics/asymptote/dec.cc b/graphics/asymptote/dec.cc
new file mode 100644
index 0000000000..dc15b9d24d
--- /dev/null
+++ b/graphics/asymptote/dec.cc
@@ -0,0 +1,909 @@
+/*****
+ * dec.cc
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Represents the abstract syntax tree for declarations in the language.
+ * Also included is an abstract syntax for types as they are most often
+ * used with declarations.
+ *****/
+
+#include "errormsg.h"
+#include "coenv.h"
+#include "dec.h"
+#include "fundec.h"
+#include "newexp.h"
+#include "stm.h"
+#include "exp.h"
+#include "modifier.h"
+#include "runtime.h"
+#include "parser.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+
+using mem::list;
+
+trans::tyEntry *ty::transAsTyEntry(coenv &e, record *where)
+{
+ return new trans::tyEntry(trans(e, false), 0, where, getPos());
+}
+
+
+void nameTy::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nameTy",indent);
+
+ id->prettyprint(out, indent+1);
+}
+
+types::ty *nameTy::trans(coenv &e, bool tacit)
+{
+ return id->typeTrans(e, tacit);
+}
+
+trans::tyEntry *nameTy::transAsTyEntry(coenv &e, record *)
+{
+ return id->tyEntryTrans(e);
+}
+
+
+void dimensions::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "dimensions (" << depth << ")\n";
+}
+
+types::array *dimensions::truetype(types::ty *base)
+{
+ if (base->kind == ty_void) {
+ em.error(getPos());
+ em << "cannot declare array of type void";
+ }
+
+ assert(depth >= 1);
+ size_t d=depth;
+ types::array *a=new types::array(base); d--;
+ for (; d > 0; d--) {
+ a = new types::array(a);
+ }
+ return a;
+}
+
+
+void arrayTy::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "arrayTy",indent);
+
+ cell->prettyprint(out, indent+1);
+ dims->prettyprint(out, indent+1);
+}
+
+// NOTE: Can this be merged with trans somehow?
+void arrayTy::addOps(coenv &e, record *r)
+{
+ types::ty *t=trans(e, true);
+
+ // Only add ops if it is an array (and not, say, an error)
+ if (t->kind == types::ty_array) {
+ types::array *at=dynamic_cast<types::array *>(t);
+ assert(at);
+ e.e.addArrayOps(at);
+ if (r)
+ r->e.addArrayOps(at);
+ }
+}
+
+types::ty *arrayTy::trans(coenv &e, bool tacit)
+{
+ types::ty *ct = cell->trans(e, tacit);
+ assert(ct);
+
+ // Don't make an array of errors.
+ if (ct->kind == types::ty_error)
+ return ct;
+
+ types::array *t = dims->truetype(ct);
+ assert(t);
+
+ return t;
+}
+
+tyEntryTy::tyEntryTy(position pos, types::ty *t)
+ : ty(pos), ent(new trans::tyEntry(t, 0, 0, position()))
+{
+}
+
+void tyEntryTy::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "tyEntryTy: " << *(ent->t) << "\n";
+}
+
+types::ty *tyEntryTy::trans(coenv &, bool) {
+ return ent->t;
+}
+
+
+vm::lambda *runnable::transAsCodelet(coenv &e)
+{
+ coder c=e.c.newCodelet(getPos());
+ coenv ce(c, e.e);
+ markTrans(ce);
+ return c.close();
+}
+
+
+void block::prettystms(ostream &out, Int indent)
+{
+ for (list<runnable *>::iterator p = stms.begin(); p != stms.end(); ++p)
+ (*p)->prettyprint(out, indent);
+}
+
+void block::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"block",indent);
+ prettystms(out, indent+1);
+}
+
+void block::trans(coenv &e)
+{
+ if (scope) e.e.beginScope();
+ for (list<runnable *>::iterator p = stms.begin(); p != stms.end(); ++p) {
+ (*p)->markTrans(e);
+ }
+ if (scope) e.e.endScope();
+}
+
+void block::transAsField(coenv &e, record *r)
+{
+ if (scope) e.e.beginScope();
+ for (list<runnable *>::iterator p = stms.begin(); p != stms.end(); ++p) {
+ (*p)->markTransAsField(e, r);
+ }
+ if (scope) e.e.endScope();
+}
+
+void block::transAsRecordBody(coenv &e, record *r)
+{
+ transAsField(e, r);
+ e.c.closeRecord();
+}
+
+record *block::transAsFile(genv& ge, symbol id)
+{
+ // Create the new module.
+ record *r = new record(id, new frame(id,0,0));
+
+ // Create coder and environment to translate the module.
+ // File-level modules have dynamic fields by default.
+ coder c(getPos(), r, 0);
+ env e(ge);
+ coenv ce(c, e);
+
+ // Translate the abstract syntax.
+ if (settings::getSetting<bool>("autoplain")) {
+ autoplainRunnable()->transAsField(ce, r);
+ }
+ transAsRecordBody(ce, r);
+ em.sync();
+
+ return r;
+}
+
+bool block::returns() {
+ // Search for a returning runnable, starting at the end for efficiency.
+ for (list<runnable *>::reverse_iterator p=stms.rbegin();
+ p != stms.rend();
+ ++p)
+ if ((*p)->returns())
+ return true;
+ return false;
+}
+
+vardec *block::asVardec()
+{
+ vardec *var = 0;
+ for (list<runnable *>::iterator p=stms.begin();
+ p != stms.end();
+ ++p)
+ {
+ vardec *v = dynamic_cast<vardec *>(*p);
+ if (v) {
+ if (var)
+ // Multiple vardecs.
+ return 0;
+ var = v;
+ }
+ else if (!dynamic_cast<emptyStm *>(*p))
+ // Failure due to another runnable in the block.
+ return 0;
+ }
+
+ return var;
+}
+
+
+void dec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "dec", indent);
+}
+
+
+void modifierList::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "modifierList (";
+
+ for (list<modifier>::iterator p = mods.begin(); p != mods.end(); ++p) {
+ if (p != mods.begin())
+ out << ", ";
+ switch (*p) {
+ case EXPLICIT_STATIC:
+ out << "static";
+ break;
+#if 0
+ case EXPLICIT_DYNAMIC:
+ out << "dynamic";
+ break;
+#endif
+ default:
+ out << "invalid code";
+ }
+ }
+
+ for (list<permission>::iterator p = perms.begin(); p != perms.end(); ++p) {
+ if (p != perms.begin() || !mods.empty())
+ out << ", ";
+ switch (*p) {
+ case PUBLIC:
+ out << "public";
+ break;
+ case PRIVATE:
+ out << "private";
+ break;
+ default:
+ out << "invalid code";
+ }
+ }
+
+ out << ")\n";
+}
+
+bool modifierList::staticSet()
+{
+ return !mods.empty();
+}
+
+modifier modifierList::getModifier()
+{
+ if (mods.size() > 1) {
+ em.error(getPos());
+ em << "too many modifiers";
+ }
+
+ assert(staticSet());
+ return mods.front();
+}
+
+permission modifierList::getPermission()
+{
+ if (perms.size() > 1) {
+ em.error(getPos());
+ em << "too many modifiers";
+ }
+
+ return perms.empty() ? DEFAULT_PERM : perms.front();
+}
+
+
+void modifiedRunnable::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "modifierRunnable",indent);
+
+ mods->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void modifiedRunnable::transAsField(coenv &e, record *r)
+{
+ if (mods->staticSet()) {
+ if (e.c.isTopLevel()) {
+ em.warning(getPos());
+ em << "static modifier is meaningless at top level";
+ }
+ e.c.pushModifier(mods->getModifier());
+ }
+
+ permission p = mods->getPermission();
+#if 0 // This is innocuous
+ if (p != DEFAULT_PERM && (!r || !body->allowPermissions())) {
+ em.warning(pos);
+ em << "permission modifier is meaningless";
+ }
+#endif
+ e.c.setPermission(p);
+
+ body->transAsField(e,r);
+
+ e.c.clearPermission();
+ if (mods->staticSet())
+ e.c.popModifier();
+}
+
+
+void decidstart::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "decidstart '" << id << "'\n";
+
+ if (dims)
+ dims->prettyprint(out, indent+1);
+}
+
+types::ty *decidstart::getType(types::ty *base, coenv &, bool)
+{
+ return dims ? dims->truetype(base) : base;
+}
+
+trans::tyEntry *decidstart::getTyEntry(trans::tyEntry *base, coenv &e,
+ record *where)
+{
+ return dims ? new trans::tyEntry(getType(base->t,e,false), 0,
+ where, getPos()) :
+ base;
+}
+
+void decidstart::addOps(types::ty *base, coenv &e, record *r)
+{
+ if (dims) {
+ e.e.addArrayOps(dims->truetype(base));
+ if (r)
+ r->e.addArrayOps(dims->truetype(base));
+ }
+}
+
+
+void fundecidstart::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fundecidstart '" << id << "'\n";
+
+ if (dims)
+ dims->prettyprint(out, indent+1);
+ if (params)
+ params->prettyprint(out, indent+1);
+}
+
+types::ty *fundecidstart::getType(types::ty *base, coenv &e, bool tacit)
+{
+ types::ty *result = decidstart::getType(base, e, tacit);
+
+ if (params) {
+ return params->getType(result, e, true, tacit);
+ }
+ else {
+ types::ty *t = new function(base);
+ return t;
+ }
+}
+
+trans::tyEntry *fundecidstart::getTyEntry(trans::tyEntry *base, coenv &e,
+ record *where)
+{
+ return new trans::tyEntry(getType(base->t,e,false), 0, where, getPos());
+}
+
+void fundecidstart::addOps(types::ty *base, coenv &e, record *r)
+{
+ decidstart::addOps(base, e, r);
+
+ params->addOps(e, r);
+
+ types::function *ft=dynamic_cast<types::function *>(getType(base, e, true));
+ assert(ft);
+
+ e.e.addFunctionOps(ft);
+ if (r)
+ r->e.addFunctionOps(ft);
+}
+
+
+void decid::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "decid",indent);
+
+ start->prettyprint(out, indent+1);
+ if (init)
+ init->prettyprint(out, indent+1);
+}
+
+
+varEntry *makeVarEntryWhere(coenv &e, record *r, types::ty *t,
+ record *where, position pos)
+{
+ access *a = r ? r->allocField(e.c.isStatic()) :
+ e.c.allocLocal();
+
+ return r ? new varEntry(t, a, e.c.getPermission(), r, where, pos) :
+ new varEntry(t, a, where, pos);
+}
+
+varEntry *makeVarEntry(position pos, coenv &e, record *r, types::ty *t) {
+ return makeVarEntryWhere(e, r, t, r, pos);
+}
+
+
+// Defined in constructor.cc.
+bool definesImplicitConstructor(coenv &e, record *r, varEntry *v, symbol id);
+void addConstructorFromInitializer(position pos, coenv &e, record *r,
+ varEntry *init);
+
+void addVar(coenv &e, record *r, varEntry *v, symbol id)
+{
+ // Test for 'operator init' definitions that implicitly define constructors:
+ if (definesImplicitConstructor(e, r, v, id))
+ addConstructorFromInitializer(position(), e, r, v);
+
+ // Add to the record so it can be accessed when qualified; add to the
+ // environment so it can be accessed unqualified in the scope of the
+ // record definition.
+ if (r)
+ r->e.addVar(id, v);
+ e.e.addVar(id, v);
+}
+
+void initializeVar(position pos, coenv &e, varEntry *v, varinit *init)
+{
+ types::ty *t=v->getType();
+
+ if (init)
+ init->transToType(e, t);
+ else {
+ definit d(pos);
+ d.transToType(e, t);
+ }
+
+ v->getLocation()->encode(WRITE, pos, e.c);
+ e.c.encodePop();
+}
+
+types::ty *inferType(position pos, coenv &e, varinit *init)
+{
+ if (!init) {
+ em.error(pos);
+ em << "inferred variable declaration without initializer";
+ return primError();
+ }
+
+ exp *base = dynamic_cast<exp *>(init);
+ if (base) {
+ types::ty *t = base->cgetType(e);
+ if (t->kind != ty_overloaded)
+ return t;
+ }
+
+ em.error(pos);
+ em << "could not infer type of initializer";
+ return primError();
+}
+
+void createVar(position pos, coenv &e, record *r,
+ symbol id, types::ty *t, varinit *init)
+{
+ // I'm not sure how to handle inferred types in these cases.
+ assert(t->kind != types::ty_inferred);
+
+ varEntry *v=makeVarEntry(pos, e, r, t);
+ addVar(e, r, v, id);
+ initializeVar(pos, e, v, init);
+}
+
+void createVarOutOfOrder(position pos, coenv &e, record *r,
+ symbol id, types::ty *t, varinit *init)
+{
+ /* For declarations such as "var x = 5;", infer the type from the
+ * initializer.
+ */
+ if (t->kind == types::ty_inferred)
+ t = inferType(pos, e, init);
+
+ varEntry *v=makeVarEntry(pos, e, r, t);
+ initializeVar(pos, e, v, init);
+ addVar(e, r, v, id);
+}
+
+void addTypeWithPermission(coenv &e, record *r, tyEntry *base, symbol id)
+{
+ // Only bother encoding permissions for private types.
+ tyEntry *ent = (r && e.c.getPermission()==PRIVATE) ?
+ new trans::tyEntry(base, PRIVATE, r) :
+ base;
+
+ if (r)
+ r->e.addType(id, ent);
+ e.e.addType(id, ent);
+}
+
+
+void decid::transAsField(coenv &e, record *r, types::ty *base)
+{
+ types::ty *t = start->getType(base, e);
+ assert(t);
+ if (t->kind == ty_void) {
+ em.error(getPos());
+ em << "cannot declare variable of type void";
+ }
+
+ start->addOps(base, e, r);
+
+ createVarOutOfOrder(getPos(), e, r, start->getName(), t, init);
+}
+
+void decid::transAsTypedefField(coenv &e, trans::tyEntry *base, record *r)
+{
+ trans::tyEntry *ent = start->getTyEntry(base, e, r);
+ assert(ent && ent->t);
+
+ if (init) {
+ em.error(getPos());
+ em << "type definition cannot have initializer";
+ }
+
+ start->addOps(base->t, e, r);
+
+ addTypeWithPermission(e, r, ent, start->getName());
+}
+
+
+void decidlist::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "decidlist",indent);
+
+ for (list<decid *>::iterator p = decs.begin(); p != decs.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+void decidlist::transAsField(coenv &e, record *r, types::ty *base)
+{
+ for (list<decid *>::iterator p = decs.begin(); p != decs.end(); ++p)
+ (*p)->transAsField(e, r, base);
+}
+
+void decidlist::transAsTypedefField(coenv &e, trans::tyEntry *base, record *r)
+{
+ for (list<decid *>::iterator p = decs.begin(); p != decs.end(); ++p)
+ (*p)->transAsTypedefField(e, base, r);
+}
+
+
+void vardec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "vardec",indent);
+
+ base->prettyprint(out, indent+1);
+ decs->prettyprint(out, indent+1);
+}
+
+void vardec::transAsTypedefField(coenv &e, record *r)
+{
+ base->addOps(e, r);
+ decs->transAsTypedefField(e, base->transAsTyEntry(e, r), r);
+}
+
+symbol vardec::singleName()
+{
+ decid *did = decs->singleEntry();
+ if (!did)
+ return symbol::nullsym;
+ return did->getStart()->getName();
+}
+
+types::ty *vardec::singleGetType(coenv &e)
+{
+ decid *did = decs->singleEntry();
+ if (!did)
+ return 0;
+ return did->getStart()->getType(base->trans(e), e);
+}
+
+
+// Helper class for imports. This essentially evaluates to the run::loadModule
+// function. However, that function returns different types of records
+// depending on the filename given to it, so we cannot add it to the
+// environment. Instead, we explicitly tell it what types::record it is
+// returning for each use.
+class loadModuleExp : public exp {
+ record *imp;
+ function *ft;
+
+public:
+ loadModuleExp(position pos, record *imp)
+ : exp(pos), imp(imp), ft(new function(imp,primString())) {}
+
+ void prettyprint(ostream &out, Int indent) {
+ prettyname(out, "loadModuleExp", indent);
+ }
+
+ types::ty *trans(coenv &) {
+ em.compiler(getPos());
+ em << "trans called for loadModuleExp";
+ return primError();
+ }
+
+ void transCall(coenv &e, types::ty *t) {
+ assert(equivalent(t, ft));
+ e.c.encode(inst::builtin, run::loadModule);
+ }
+
+ types::ty *getType(coenv &) {
+ return ft;
+ }
+
+ exp *evaluate(coenv &, types::ty *) {
+ // Don't alias.
+ return this;
+ }
+};
+
+// Creates a local variable to hold the import and translate the accessing of
+// the import, but doesn't add the import to the environment.
+varEntry *accessModule(position pos, coenv &e, record *r, symbol id)
+{
+ record *imp=e.e.getModule(id, (string)id);
+ if (!imp) {
+ em.error(pos);
+ em << "could not load module '" << id << "'";
+ em.sync();
+ return 0;
+ }
+ else {
+ // Create a varinit that evaluates to the module.
+ // This is effectively the expression "loadModule(filename)".
+ callExp init(pos, new loadModuleExp(pos, imp),
+ new stringExp(pos, (string)id));
+
+ // The varEntry should have whereDefined()==0 as it is not defined inside
+ // the record r.
+ varEntry *v=makeVarEntryWhere(e, r, imp, 0, pos);
+ initializeVar(pos, e, v, &init);
+ return v;
+ }
+}
+
+
+void idpair::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "idpair (" << "'" << src << "' as " << dest << ")\n";
+}
+
+void idpair::transAsAccess(coenv &e, record *r)
+{
+ checkValidity();
+
+ varEntry *v=accessModule(getPos(), e, r, src);
+ if (v)
+ addVar(e, r, v, dest);
+}
+
+void idpair::transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier)
+{
+ checkValidity();
+
+ if (r)
+ r->e.add(src, dest, source, qualifier, e.c);
+ if (!e.e.add(src, dest, source, qualifier, e.c)) {
+ em.error(getPos());
+ em << "no matching types or fields of name '" << src << "'";
+ }
+}
+
+
+void idpairlist::prettyprint(ostream &out, Int indent)
+{
+ for (list<idpair *>::iterator p=base.begin();
+ p != base.end();
+ ++p)
+ (*p)->prettyprint(out, indent);
+}
+
+void idpairlist::transAsAccess(coenv &e, record *r)
+{
+ for (list<idpair *>::iterator p=base.begin();
+ p != base.end();
+ ++p)
+ (*p)->transAsAccess(e,r);
+}
+
+void idpairlist::transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier)
+{
+ for (list<idpair *>::iterator p=base.begin();
+ p != base.end();
+ ++p)
+ (*p)->transAsUnravel(e,r,source,qualifier);
+}
+
+idpairlist * const WILDCARD = 0;
+
+void accessdec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "accessdec", indent);
+ base->prettyprint(out, indent+1);
+}
+
+
+void fromdec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "fromdec", indent);
+ fields->prettyprint(out, indent+1);
+}
+
+void fromdec::transAsField(coenv &e, record *r)
+{
+ qualifier q=getQualifier(e,r);
+ if (q.t) {
+ if (fields==WILDCARD) {
+ if (r)
+ r->e.add(q.t->e, q.v, e.c);
+ e.e.add(q.t->e, q.v, e.c);
+ }
+ else
+ fields->transAsUnravel(e, r, q.t->e, q.v);
+ }
+}
+
+
+void unraveldec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "unraveldec", indent);
+ id->prettyprint(out, indent+1);
+ idpairlist *f=this->fields;
+ if(f) f->prettyprint(out, indent+1);
+}
+
+fromdec::qualifier unraveldec::getQualifier(coenv &e, record *)
+{
+ // getType is where errors in the qualifier are reported.
+ record *qt=dynamic_cast<record *>(id->getType(e, false));
+ if (!qt) {
+ em.error(getPos());
+ em << "qualifier is not a record";
+ }
+
+ return qualifier(qt,id->getVarEntry(e));
+}
+
+void fromaccessdec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fromaccessdec '" << id << "'\n";
+ idpairlist *f=this->fields;
+ if(f) f->prettyprint(out, indent+1);
+}
+
+fromdec::qualifier fromaccessdec::getQualifier(coenv &e, record *r)
+{
+ varEntry *v=accessModule(getPos(), e, r, id);
+ if (v) {
+ record *qt=dynamic_cast<record *>(v->getType());
+ if (!qt) {
+ em.compiler(getPos());
+ em << "qualifier is not a record";
+ }
+ return qualifier(qt, v);
+ }
+ else
+ return qualifier(0,0);
+}
+
+void importdec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "importdec", indent);
+ base.prettyprint(out, indent+1);
+}
+
+void includedec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "includedec ('" << filename << "')\n";
+}
+
+void includedec::loadFailed(coenv &)
+{
+ em.warning(getPos());
+ em << "could not parse file of name '" << filename << "'";
+ em.sync();
+}
+
+void includedec::transAsField(coenv &e, record *r)
+{
+ file *ast = parser::parseFile(filename,"Including");
+ em.sync();
+
+ // The runnables will be translated, one at a time, without any additional
+ // scoping.
+ ast->transAsField(e, r);
+}
+
+
+void typedec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "typedec",indent);
+
+ body->prettyprint(out, indent+1);
+}
+
+
+void recorddec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "structdec '" << id << "'\n";
+
+ body->prettyprint(out, indent+1);
+}
+
+void recorddec::transRecordInitializer(coenv &e, record *parent)
+{
+ position here=getPos();
+
+ // This is equivalent to the code
+ // A operator init() { return new A; }
+ // where A is the name of the record.
+ formals formals(here);
+ simpleName recordName(here, id);
+ nameTy result(here, &recordName);
+ newRecordExp exp(here, &result);
+ returnStm stm(here, &exp);
+ fundec init(here, &result, symbol::opTrans("init"), &formals, &stm);
+
+ init.transAsField(e, parent);
+}
+
+void recorddec::addPostRecordEnvironment(coenv &e, record *r, record *parent) {
+ if (parent)
+ parent->e.add(r->postdefenv, 0, e.c);
+ e.e.add(r->postdefenv, 0, e.c);
+}
+
+void recorddec::transAsField(coenv &e, record *parent)
+{
+ record *r = parent ? parent->newRecord(id, e.c.isStatic()) :
+ e.c.newRecord(id);
+
+ addTypeWithPermission(e, parent, new trans::tyEntry(r,0,parent,getPos()), id);
+ e.e.addRecordOps(r);
+ if (parent)
+ parent->e.addRecordOps(r);
+
+ // Start translating the initializer.
+ coder c=e.c.newRecordInit(getPos(), r);
+ coenv re(c,e.e);
+
+ body->transAsRecordBody(re, r);
+
+ // After the record is translated, add a default initializer so that a
+ // variable of the type of the record is initialized to a new instance by
+ // default.
+ transRecordInitializer(e, parent);
+
+ // Add types and variables defined during the record that should be added to
+ // the enclosing environment. These are the implicit constructors defined by
+ // "operator init".
+ addPostRecordEnvironment(e, r, parent);
+}
+
+runnable *autoplainRunnable() {
+ // Abstract syntax for the code:
+ // private import plain;
+ position pos=position();
+ static importdec ap(pos, new idpair(pos, symbol::trans("plain")));
+ static modifiedRunnable mr(pos, trans::PRIVATE, &ap);
+
+ return &mr;
+}
+
+} // namespace absyntax
diff --git a/graphics/asymptote/dec.h b/graphics/asymptote/dec.h
new file mode 100644
index 0000000000..5b7f0756cc
--- /dev/null
+++ b/graphics/asymptote/dec.h
@@ -0,0 +1,662 @@
+/*****
+ * dec.h
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Represents the abstract syntax tree for declatations in the language.
+ * Also included is abstract syntax for types as they are most often
+ * used with declarations.
+ *****/
+
+#ifndef DEC_H
+#define DEC_H
+
+#include "symbol.h"
+#include "absyn.h"
+#include "name.h"
+#include "varinit.h"
+#include "modifier.h"
+
+namespace trans {
+class coenv;
+class genv;
+class protoenv;
+class varEntry;
+class access;
+}
+
+namespace types {
+class ty;
+struct formal;
+struct signature;
+struct function;
+}
+
+namespace vm {
+struct lambda;
+}
+namespace absyntax {
+
+using trans::genv;
+using trans::coenv;
+using trans::protoenv;
+using trans::varEntry;
+using trans::access;
+using sym::symbol;
+
+class vardec;
+
+class ty : public absyn {
+public:
+ ty(position pos)
+ : absyn(pos) {}
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+
+ // If we introduced a new type, automatically add corresponding functions for
+ // that type.
+ virtual void addOps(coenv &, record *) {}
+
+ // Returns the internal representation of the type. This method can
+ // be called by exp::getType which does not report errors, so tacit is
+ // needed to silence errors in this case.
+ virtual types::ty *trans(coenv &e, bool tacit = false) = 0;
+
+ virtual trans::tyEntry *transAsTyEntry(coenv &e, record *where);
+};
+
+class nameTy : public ty {
+ name *id;
+
+public:
+ nameTy(position pos, name *id)
+ : ty(pos), id(id) {}
+
+ nameTy(name *id)
+ : ty(id->getPos()), id(id) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e, bool tacit = false);
+ trans::tyEntry *transAsTyEntry(coenv &e, record *where);
+};
+
+class dimensions : public absyn {
+ size_t depth;
+public:
+ dimensions(position pos)
+ : absyn(pos), depth(1) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void increase()
+ { depth++; }
+
+ size_t size() {
+ return depth;
+ }
+
+ types::array *truetype(types::ty *base);
+};
+
+class arrayTy : public ty {
+ ty *cell;
+ dimensions *dims;
+
+public:
+ arrayTy(position pos, ty *cell, dimensions *dims)
+ : ty(pos), cell(cell), dims(dims) {}
+
+ arrayTy(name *id, dimensions *dims)
+ : ty(dims->getPos()), cell(new nameTy(id)), dims(dims) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void addOps(coenv &e, record *r);
+
+ types::ty *trans(coenv &e, bool tacit = false);
+};
+
+// Similar to varEntryExp, this helper class always translates to the same fixed
+// type.
+class tyEntryTy : public ty {
+ trans::tyEntry *ent;
+public:
+ tyEntryTy(position pos, trans::tyEntry *ent)
+ : ty(pos), ent(ent) {}
+
+ tyEntryTy(position pos, types::ty *t);
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e, bool tacit = false);
+ trans::tyEntry *transAsTyEntry(coenv &, record *) {
+ return ent;
+ }
+};
+
+// Runnable is anything that can be executed by the program, including
+// any declaration or statement.
+class runnable : public absyn {
+public:
+ runnable(position pos)
+ : absyn(pos) {}
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+
+ void markTrans(coenv &e)
+ {
+ markPos(e);
+ trans(e);
+ }
+
+ /* Translates the stm or dec as if it were in a function definition. */
+ virtual void trans(coenv &e) {
+ transAsField(e, 0);
+ }
+
+ /* This can be overridden, to specify a special way of translating the code
+ * when it is run at the top of the interactive prompt.
+ */
+ virtual void interactiveTrans(coenv &e) {
+ trans(e);
+ }
+
+ void markTransAsField(coenv &e, record *r)
+ {
+ markPos(e);
+ transAsField(e,r);
+ }
+
+ /* Translate the runnable as in the lowest lexical scope of a record
+ * definition. If it is simply a statement, it will be added to the
+ * record's initializer. A declaration, however, will also have to
+ * add a new type or field to the record.
+ */
+ virtual void transAsField(coenv &e, record *) = 0;
+
+ virtual vm::lambda *transAsCodelet(coenv &e);
+
+ // For functions that return a value, we must guarantee that they end
+ // with a return statement. This checks for that condition.
+ virtual bool returns()
+ { return false; }
+
+ // Returns true if it is syntatically allowable to modify this
+ // runnable by a PUBLIC or PRIVATE modifier.
+ virtual bool allowPermissions()
+ { return false; }
+};
+
+class block : public runnable {
+public:
+ mem::list<runnable *> stms;
+
+ // If the runnables should be interpreted in their own scope.
+ bool scope;
+
+protected:
+ void prettystms(ostream &out, Int indent);
+
+public:
+ block(position pos, bool scope=true)
+ : runnable(pos), scope(scope) {}
+
+ // To ensure list deallocates properly.
+ virtual ~block() {}
+
+ void add(runnable *r) {
+ stms.push_back(r);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ void transAsField(coenv &e, record *r);
+
+ void transAsRecordBody(coenv &e, record *r);
+
+ types::record *transAsFile(genv& ge, symbol id);
+
+ // If the block can be interpreted as a single vardec, return that vardec
+ // (otherwise 0).
+ vardec *asVardec();
+
+ // A block is guaranteed to return iff one of the runnables is guaranteed to
+ // return.
+ // This is conservative in that
+ //
+ // int f(int x)
+ // {
+ // if (x==1) return 0;
+ // if (x!=1) return 1;
+ // }
+ //
+ // is not guaranteed to return.
+ bool returns();
+};
+
+class modifierList : public absyn {
+ mem::list<trans::permission> perms;
+ mem::list<trans::modifier> mods;
+
+public:
+ modifierList(position pos)
+ : absyn(pos) {}
+
+ virtual ~modifierList()
+ {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void add(trans::permission p)
+ {
+ perms.push_back(p);
+ }
+
+ void add(trans::modifier m)
+ {
+ mods.push_back(m);
+ }
+
+ /* True if a static or dynamic modifier is present.
+ */
+ bool staticSet();
+
+ /* Says if the modifiers indicate static or dynamic. Prints error if
+ * there are duplicates.
+ */
+ trans::modifier getModifier();
+
+ /* Says if it is declared public, private, or read-only (default).
+ * Prints error if there are duplicates.
+ */
+ trans::permission getPermission();
+};
+
+// Modifiers of static or dynamic can change the way declarations and
+// statements are encoded.
+class modifiedRunnable : public runnable {
+ modifierList *mods;
+ runnable *body;
+
+public:
+ modifiedRunnable(position pos, modifierList *mods, runnable *body)
+ : runnable(pos), mods(mods), body(body) {}
+
+ modifiedRunnable(position pos, trans::permission perm, runnable *body)
+ : runnable(pos), mods(new modifierList(pos)), body(body) {
+ mods->add(perm);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r);
+
+ bool returns()
+ { return body->returns(); }
+};
+
+
+class decidstart : public absyn {
+protected:
+ symbol id;
+ dimensions *dims;
+
+public:
+ decidstart(position pos, symbol id, dimensions *dims = 0)
+ : absyn(pos), id(id), dims(dims) {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual types::ty *getType(types::ty *base, coenv &, bool = false);
+ virtual trans::tyEntry *getTyEntry(trans::tyEntry *base, coenv &e,
+ record *where);
+
+ // If a new type is formed by adding dimensions (or a function signature)
+ // after the id, this will add the standard functions for that new type.
+ virtual void addOps(types::ty *base, coenv &e, record *r);
+
+ virtual symbol getName()
+ { return id; }
+};
+
+// Forward declaration.
+class formals;
+
+class fundecidstart : public decidstart {
+ formals *params;
+
+public:
+ fundecidstart(position pos,
+ symbol id,
+ dimensions *dims = 0,
+ formals *params = 0)
+ : decidstart(pos, id, dims), params(params) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *getType(types::ty *base, coenv &e, bool tacit = false);
+ trans::tyEntry *getTyEntry(trans::tyEntry *base, coenv &e, record *where);
+ void addOps(types::ty *base, coenv &e, record *r);
+};
+
+class decid : public absyn {
+ decidstart *start;
+ varinit *init;
+
+ // Returns the default initializer for the type.
+ access *defaultInit(coenv &e, types::ty *t);
+
+public:
+ decid(position pos, decidstart *start, varinit *init = 0)
+ : absyn(pos), start(start), init(init) {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual void transAsField(coenv &e, record *r, types::ty *base);
+
+ // Translate, but add the names in as types rather than variables.
+ virtual void transAsTypedefField(coenv &e, trans::tyEntry *base, record *r);
+
+ decidstart *getStart() { return start; }
+};
+
+class decidlist : public absyn {
+ mem::list<decid *> decs;
+
+public:
+ decidlist(position pos)
+ : absyn(pos) {}
+
+ virtual ~decidlist() {}
+
+ void add(decid *p) {
+ decs.push_back(p);
+ }
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual void transAsField(coenv &e, record *r, types::ty *base);
+
+ // Translate, but add the names in as types rather than variables.
+ virtual void transAsTypedefField(coenv &e, trans::tyEntry *base, record *r);
+
+ // If the list consists of a single entry, return it.
+ decid *singleEntry()
+ {
+ if (decs.size() == 1)
+ return decs.front();
+ else
+ return 0;
+ }
+};
+
+class dec : public runnable {
+public:
+ dec(position pos)
+ : runnable(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Declarations can be public or private.
+ bool allowPermissions()
+ { return true; }
+};
+
+void createVar(position pos, coenv &e, record *r,
+ symbol id, types::ty *t, varinit *init);
+
+class vardec : public dec {
+ ty *base;
+ decidlist *decs;
+
+public:
+ vardec(position pos, ty *base, decidlist *decs)
+ : dec(pos), base(base), decs(decs) {}
+
+ vardec(position pos, ty *base, decid *di)
+ : dec(pos), base(base), decs(new decidlist(pos))
+ {
+ decs->add(di);
+ }
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r)
+ {
+ base->addOps(e, r);
+ decs->transAsField(e, r, base->trans(e));
+ }
+
+ // Translate, but add the names in as types rather than variables.
+ virtual void transAsTypedefField(coenv &e, record *r);
+
+ // If the vardec encodes a single declaration, return the name of that
+ // declaration (otherwise nullsym).
+ symbol singleName();
+
+ // If the vardec encodes a single declaration, return the type of that
+ // declaration (otherwise 0).
+ types::ty *singleGetType(coenv& e);
+};
+
+struct idpair : public absyn {
+ symbol src; // The name of the module to access.
+ symbol dest; // What to call it in the local environment.
+ bool valid; // If it parsed properly.
+
+ idpair(position pos, symbol id)
+ : absyn(pos), src(id), dest(id), valid(true) {}
+
+ idpair(position pos, symbol src, symbol as, symbol dest)
+ : absyn(pos), src(src), dest(dest), valid(as==symbol::trans("as")) {}
+
+ idpair(position pos, string src, symbol as, symbol dest)
+ : absyn(pos), src(symbol::trans(src)), dest(dest),
+ valid(as==symbol::trans("as")) {}
+
+ void checkValidity() {
+ if (!valid) {
+ em.error(getPos());
+ em << "expected 'as'";
+ }
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Translates as: access src as dest;
+ void transAsAccess(coenv &e, record *r);
+
+ // Translates as: from _ unravel src as dest;
+ // where _ is the qualifier record with source as its fields and types.
+ void transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier);
+};
+
+struct idpairlist : public gc {
+ mem::list<idpair *> base;
+
+ void add(idpair *x) {
+ base.push_back(x);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsAccess(coenv &e, record *r);
+
+ void transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier);
+};
+
+extern idpairlist * const WILDCARD;
+
+
+class accessdec : public dec {
+ idpairlist *base;
+
+public:
+ accessdec(position pos, idpairlist *base)
+ : dec(pos), base(base) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r) {
+ base->transAsAccess(e,r);
+ }
+};
+
+// Abstract base class for
+// from _ access _; (fromaccessdec)
+// and
+// from _ unravel _; (unraveldec)
+class fromdec : public dec {
+protected:
+ struct qualifier {
+ // The varEntry holds the location and the type of the highest framed
+ // structure that can be put on the stack. The record holds the actual type
+ // of the qualifier.
+ // For example:
+ // struct A {
+ // struct B {
+ // static int x;
+ // }
+ // }
+ // A a=new A;
+ // from a.B unravel x;
+ //
+ // Here, v->getType() will yield A and v->getLocation() will yield the
+ // location of the the variable a, but the record type t will be B.
+ record *t;
+ varEntry *v;
+
+ qualifier(record *t, varEntry *v)
+ : t(t), v(v) {}
+ };
+
+ // Return the qualifier from which the fields are taken. If t==0, it is
+ // assumed that an error occurred and was reported.
+ virtual qualifier getQualifier(coenv &e, record *r) = 0;
+ idpairlist *fields;
+
+public:
+ fromdec(position pos, idpairlist *fields)
+ : dec(pos), fields(fields) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r);
+};
+
+// An unravel declaration dumps fields and types of a record into the local
+// scope.
+class unraveldec : public fromdec {
+ name *id;
+
+ qualifier getQualifier(coenv &e, record *);
+public:
+ unraveldec(position pos, name *id, idpairlist *fields)
+ : fromdec(pos, fields), id(id) {}
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+// A fromaccess declaration dumps fields and types of a module into the local
+// scope. It does not add the module as a variable in the local scope.
+class fromaccessdec : public fromdec {
+ symbol id;
+
+ qualifier getQualifier(coenv &e, record *r);
+public:
+ fromaccessdec(position pos, symbol id, idpairlist *fields)
+ : fromdec(pos, fields), id(id) {}
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+// An import declaration dumps fields and types of a module into the local
+// scope. It also adds the module as a variable in the local scope.
+class importdec : public dec {
+ block base;
+
+public:
+ importdec(position pos, idpair *id)
+ : dec(pos), base(pos, false) {
+ idpairlist *i=new idpairlist;
+ i->add(id);
+ base.add(new accessdec(pos, i));
+ base.add(new unraveldec(pos, new simpleName(pos, id->dest), WILDCARD));
+ }
+
+ void trans(coenv &e) {
+ base.trans(e);
+ }
+
+ void transAsField(coenv &e, record *r) {
+ base.transAsField(e, r);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+// Parses the file given, and translates the resulting runnables as if they
+// occurred at this place in the code.
+class includedec : public dec {
+ string filename;
+
+public:
+ includedec(position pos, string filename)
+ : dec(pos), filename(filename) {}
+ includedec(position pos, symbol id)
+ : dec(pos), filename(id) {}
+
+ void prettyprint(ostream &out, Int indent);
+ void loadFailed(coenv &e);
+
+ void transAsField(coenv &e, record *r);
+};
+
+// Types defined from others in typedef.
+class typedec : public dec {
+ vardec *body;
+
+public:
+ typedec(position pos, vardec *body)
+ : dec(pos), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r) {
+ body->transAsTypedefField(e,r);
+ }
+};
+
+
+// A struct declaration.
+class recorddec : public dec {
+ symbol id;
+ block *body;
+
+ void transRecordInitializer(coenv &e, record *parent);
+ void addPostRecordEnvironment(coenv &e, record *r, record *parent);
+
+public:
+ recorddec(position pos, symbol id, block *body)
+ : dec(pos), id(id), body(body) {}
+
+ virtual ~recorddec()
+ {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *parent);
+};
+
+// Returns a runnable that facilitates the autoplain feature.
+runnable *autoplainRunnable();
+
+void addVar(coenv &e, record *r, varEntry *v, symbol id);
+
+} // namespace absyntax
+
+#endif
+
diff --git a/graphics/asymptote/doc/Bode.asy b/graphics/asymptote/doc/Bode.asy
new file mode 100644
index 0000000000..6cc634299f
--- /dev/null
+++ b/graphics/asymptote/doc/Bode.asy
@@ -0,0 +1,27 @@
+import graph;
+texpreamble("\def\Arg{\mathop {\rm Arg}\nolimits}");
+
+size(10cm,5cm,IgnoreAspect);
+
+real ampl(real x) {return 2.5/sqrt(1+x^2);}
+real phas(real x) {return -atan(x)/pi;}
+
+scale(Log,Log);
+draw(graph(ampl,0.01,10));
+ylimits(0.001,100);
+
+xaxis("$\omega\tau_0$",BottomTop,LeftTicks);
+yaxis("$|G(\omega\tau_0)|$",Left,RightTicks);
+
+picture q=secondaryY(new void(picture pic) {
+ scale(pic,Log,Linear);
+ draw(pic,graph(pic,phas,0.01,10),red);
+ ylimits(pic,-1.0,1.5);
+ yaxis(pic,"$\Arg G/\pi$",Right,red,
+ LeftTicks("$% #.1f$",
+ begin=false,end=false));
+ yequals(pic,1,Dotted);
+ });
+label(q,"(1,0)",Scale(q,(1,0)),red);
+add(q);
+
diff --git a/graphics/asymptote/doc/CAD.pdf b/graphics/asymptote/doc/CAD.pdf
new file mode 100644
index 0000000000..84fbc4399e
--- /dev/null
+++ b/graphics/asymptote/doc/CAD.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/CAD.tex b/graphics/asymptote/doc/CAD.tex
new file mode 100644
index 0000000000..270c528b85
--- /dev/null
+++ b/graphics/asymptote/doc/CAD.tex
@@ -0,0 +1,256 @@
+\documentclass{ltxguide}
+\usepackage{graphicx}
+
+
+
+\begin{document}
+
+
+
+\title{Asymptote package CAD.asy\footnote{This document describes version 1.0.}}
+\author{Mark Henning, Germany\thanks{URL: http://www.markhenning.de}}
+\date{29 September 2006}
+\maketitle
+
+
+
+\tableofcontents
+
+
+
+\section{Introduction}
+
+The package {\tt CAD.asy} provides basic pen definitions and measurement functions for simple 2D CAD drawings according to DIN 15.
+
+
+
+\section{Important rules for using this package}
+
+If a function is declared like this:
+%
+\begin{verbatim}
+void foo(int nParam1, string strParam2)
+\end{verbatim}
+%
+You may call it \verb\foo(0, 'abc');\ or \verb\foo(nParam1=0, strParam2='abc');\. The definitions of the functions in this package may change in future version: the order of the parameters may be changed, new parameters may be inserted. Therefore it is \emph{strongly recommended} always calling the functions \verb\foo(nParam1=0, strParam2='abc');\.
+
+
+
+\section{Usage}
+
+To use the capabilities of the package, import it:
+%
+\begin{verbatim}
+import CAD;
+\end{verbatim}
+%
+All functions are encapsulated in the structure \verb\sCAD\. As the pen definitions may differ depending on the size of your drawing, you have to initialize the structure before drawing:
+
+\begin{verbatim}
+static sCAD Create(int nLineGroup = 1)
+\end{verbatim}
+%
+The parameter \verb\nLineGroup\ depends on the size of your drawing. It specifies the line group to define the pens and thus the width used for the lines. The parameter has to be within the range $[0;3]$. The larger the value, the thicker the lines. Code example:
+%
+\begin{quote}\begin{verbatim}
+sCAD cad = sCAD.Create();
+\end{verbatim}\end{quote}
+
+The created variable \verb\cad\ then provides the most important pens. Available pens are:
+%
+\begin{itemize}
+\item The pens of group A:
+ \begin{itemize}
+ \item\verb\pA\
+ \item\verb\pVisibleEdge\
+ \item\verb\pVisibleContour\
+ \item\verb\pUsableWindingLength\
+ \item\verb\pSystemLine\
+ \item\verb\pDiagramCurve\
+ \item\verb\pSurfaceStructure\
+ \end{itemize}
+\item The pens of group B:
+ \begin{itemize}
+ \item\verb\pB\
+ \item\verb\pLightEdge\
+ \item\verb\pMeasureLine\
+ \item\verb\pMeasureHelpLine\
+ \item\verb\pMeasureLineBound\
+ \item\verb\pReferenceLine\
+ \item\verb\pHatch\
+ \item\verb\pWindingGround\
+ \item\verb\pDiagonalCross\
+ \item\verb\pBendLine\
+ \item\verb\pProjectionLine\
+ \item\verb\pGrid\
+ \end{itemize}
+\item The pens of group C:
+ \begin{itemize}
+ \item\verb\pC\
+ \item\verb\pFreehand\
+ \end{itemize}
+\item The pens of group E:
+ \begin{itemize}
+ \item\verb\pE\
+ \item\verb\pSurfaceTreatmentAllowed\
+ \end{itemize}
+\item The pens of group F:
+ \begin{itemize}
+ \item\verb\pF\
+ \item\verb\pInvisibleEdge\
+ \item\verb\pInvisibleContour\
+ \end{itemize}
+\item The pens of group G:
+ \begin{itemize}
+ \item\verb\pG\
+ \item\verb\pMiddleLine\
+ \item\verb\pSymmetryLine\
+ \item\verb\pPartialCircle\
+ \item\verb\pCircularHole\
+ \item\verb\pDivisionPlane\
+ \item\verb\pTransferLine\
+ \end{itemize}
+\item The pens of group J:
+ \begin{itemize}
+ \item\verb\pJ\
+ \item\verb\pCuttingPlane\
+ \item\verb\pSurfaceTreatmentRequested\
+ \end{itemize}
+\item The pens of group K:
+ \begin{itemize}
+ \item\verb\pK\
+ \item\verb\pContourBeforeDeformation\
+ \item\verb\pAdjacentPartContour\
+ \item\verb\pEndShapeRawMaterial\
+ \item\verb\pContourEligibleType\
+ \item\verb\pPartInFrontOfCuttingPlane\
+ \end{itemize}
+\end{itemize}
+%
+All pens of one group are the same. So there is no difference between the pen \verb\pA\ and the pen \verb\pVisibleEdge\. You may use the short names or the descriptive ones. The list of groups is not complete. I had no idea how to implement the pens of group D. For me, group H seems to be obsolete, and there is no group I contained in DIN 15. In the case I did something wrong translating the German names into English, the source file also contains the original German names of each pen. Whenever a drawing function does not allow you to select the pen, the right pen is selected automatically.
+
+
+
+\begin{verbatim}
+void MeasureLine(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+\end{verbatim}
+%
+This is the basic function to draw labeled straight measurement lines. \verb\pic\ denotes the picture the line has to be drawn into, \verb\L\ is the label of the line. The pairs \verb\pFrom\ and \verb\pTo\ are the start and the end point of the distance to measure, respectively. Note, that these two points do \emph{not} refer to the start and end point of the line, as it may be longer than the measured distance.
+
+The line is extended on its left side (= the part of the line 'before' the start point) by the distance \verb\dblLeft\. On its right side (= the part of the line 'behind' the end point) it is extended by the distance \verb\dblRight\. \verb\dblLeft\ and \verb\dblRight\ must be $\leq 0$. If only one of both values is zero, it is set to the value of the other one, because according to DIN 15 it is not allowed to draw a measurement line asymmetrically. The position of the arrows indicating begin and end of the distance depends on \verb\dblLeft\ and \verb\dblRight\. If both values are 0, the measurement arrows are drawn within the measurement distance. Otherwise they are drawn outside.
+
+The parameter \verb\dblRelPosition\ refers to the relative position of the label between the start and end point. This means: The value 0 positions the label at the start point, 0.5 refers to the center between the start and the end point. Finally, the value 1 will position the label at the end point. If \verb\dblLeft\ or \verb\dblRight\ are nonzero, you may position the label at the left side of the start point ($< 0$) or at the right side of the start point ($> 1$).
+
+Usually, there is enough space to draw the measurement arrows. If you wish to use small circles instead of the arrows, set \verb\bSmallBound\ to \verb\true\.
+
+
+
+\begin{verbatim}
+real GetMeasurementBoundSize(bool bSmallBound = false)
+\end{verbatim}
+%
+Returns the size of the arrow or the small bound circle used for measurement lines.
+
+
+
+\begin{verbatim}
+guide GetMeasurementBound(bool bSmallBound = false)
+\end{verbatim}
+%
+Returns the correctly scaled guide of the arrow or the small bound circle used for measurement lines.
+
+
+
+\begin{verbatim}
+void MeasureParallel(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblDistance,
+ // Variables from MeasureLine
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+\end{verbatim}
+%
+Usually, measurement lines are placed outside the drawing with reference lines to the measured distance. \verb\pFrom\ and \verb\pTo\ denote the points of the drawing marking the begin and the end of the distance to measure, and not the begin and the end of the measurement line as in the case of the function \verb\MeasureLine\. The measurement line is placed \verb\dblDistance\ away from the distance to measure. If you would be at \verb\pFrom\ and look into the direction \verb\pTo\, it is placed on the left for positive values of \verb\dblDistance\. For negative values, it is positioned on the right. For the meaning of the other parameters see the function \verb\MeasureLine\.
+
+
+
+\begin{verbatim}
+guide MakeFreehand(pair pFrom, pair pTo,
+ real dblRelDivisionLength = 12.5,
+ real dblRelDistortion = 2.5,
+ bool bIncludeTo = true)
+\end{verbatim}
+%
+To draw a line between two points, which is not straight, but more like a freehand line, use this function. The pairs \verb\pFrom\ and \verb\pTo\ denote start and end point, respectively. \verb\dblRelDivisionLength\ is the length of the parts, the line is subdivided into. \verb\dblRelDistortion\ is the amount of distortion. Both sizes are given relative to the width of a freehand line. If \verb\bIncludeTo\ is \verb\true\, the point \verb\pTo\ is added to the path. Otherwise it is not. This may be useful for converting a guide containing more than two points to a freehand line.
+
+
+
+\section{Example}
+
+\begin{figure}
+\includegraphics{CAD1}
+\caption{Example showing the measurement capabilities and a small freehand line.\label{fig:example1}}
+\end{figure}
+
+To produce figure \ref{fig:example1}, use this code:
+\begin{quote}
+\begin{verbatim}
+import CAD;
+
+sCAD cad = sCAD.Create();
+
+// Freehand line
+draw(g = cad.MakeFreehand(pFrom = (3, -1)*cm, (6, -1)*cm),
+ p = cad.pFreehand);
+
+// Standard measurement lines
+draw(g = box((0, 0)*cm, (1, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "$\sqrt{2}$",
+ pFrom = (0, 1)*cm,
+ pTo = (1, 0)*cm,
+ dblDistance = -15mm);
+
+// Label inside, shifted to the right; arrows outside
+draw(g = box((2, 0)*cm, (3, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "1",
+ pFrom = (2, 1)*cm,
+ pTo = (3, 1)*cm,
+ dblDistance = 5mm,
+ dblLeft = 5mm,
+ dblRelPosition = 0.75);
+
+// Label and arrows outside
+draw(g = box((5, 0)*cm, (5.5, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "0.5",
+ pFrom = (5, 1)*cm,
+ pTo = (5.5, 1)*cm,
+ dblDistance = 5mm,
+ dblLeft = 10mm,
+ dblRelPosition = -1);
+
+// Small bounds, asymmetric measurement line
+draw(g = box((7, 0)*cm, (7.5, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "0.5",
+ pFrom = (7, 1)*cm,
+ pTo = (7.5, 1)*cm,
+ dblDistance = 5mm,
+ dblLeft = 2*cad.GetMeasurementBoundSize(
+ bSmallBound = true),
+ dblRight = 10mm,
+ dblRelPosition = 2,
+ bSmallBound = true);
+\end{verbatim}
+\end{quote}
+
+\end{document}
diff --git a/graphics/asymptote/doc/CAD1.asy b/graphics/asymptote/doc/CAD1.asy
new file mode 100644
index 0000000000..26184aaad2
--- /dev/null
+++ b/graphics/asymptote/doc/CAD1.asy
@@ -0,0 +1,43 @@
+import CAD;
+
+sCAD cad=sCAD.Create();
+
+// Freehand line
+draw(g=cad.MakeFreehand(pFrom=(3,-1)*cm,(6,-1)*cm),
+ p=cad.pFreehand);
+
+// Standard measurement lines
+draw(g=box((0,0)*cm,(1,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="$\sqrt{2}$",
+ pFrom=(0,1)*cm,
+ pTo=(1,0)*cm,
+ dblDistance=-15mm);
+
+// Label inside,shifted to the right; arrows outside
+draw(g=box((2,0)*cm,(3,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="1",
+ pFrom=(2,1)*cm,
+ pTo=(3,1)*cm,
+ dblDistance=5mm,
+ dblLeft=5mm,
+ dblRelPosition=0.75);
+
+// Label and arrows outside
+draw(g=box((5,0)*cm,(5.5,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="0.5",
+ pFrom=(5,1)*cm,
+ pTo=(5.5,1)*cm,
+ dblDistance=5mm,
+ dblLeft=10mm,
+ dblRelPosition=-1);
+
+// Small bounds,asymmetric measurement line
+draw(g=box((7,0)*cm,(7.5,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="0.5",
+ pFrom=(7,1)*cm,
+ pTo=(7.5,1)*cm,
+ dblDistance=5mm,
+ dblLeft=2*cad.GetMeasurementBoundSize(bSmallBound=true),
+ dblRight=10mm,
+ dblRelPosition=2,
+ bSmallBound=true);
diff --git a/graphics/asymptote/doc/CDlabel.asy b/graphics/asymptote/doc/CDlabel.asy
new file mode 100644
index 0000000000..3dd59699e4
--- /dev/null
+++ b/graphics/asymptote/doc/CDlabel.asy
@@ -0,0 +1,14 @@
+size(11.7cm,11.7cm);
+asy(nativeformat(),"logo");
+fill(unitcircle^^(scale(2/11.7)*unitcircle),
+ evenodd+rgb(124/255,205/255,124/255));
+label(scale(1.1)*minipage(
+"\centering\scriptsize \textbf{\LARGE {\tt Asymptote}\\
+\smallskip
+\small The Vector Graphics Language}\\
+\smallskip
+\textsc{Andy Hammerlindl, John Bowman, and Tom Prince}
+http://asymptote.sourceforge.net\\
+",8cm),(0,0.6));
+label(graphic("logo."+nativeformat(),"height=7cm"),(0,-0.22));
+clip(unitcircle^^(scale(2/11.7)*unitcircle),evenodd);
diff --git a/graphics/asymptote/doc/FAQ/Makefile b/graphics/asymptote/doc/FAQ/Makefile
new file mode 100644
index 0000000000..07d40b0ace
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/Makefile
@@ -0,0 +1,40 @@
+BFNNCONV = bfnnconv.pl m-ascii.pl m-html.pl m-info.pl m-lout.pl m-post.pl
+
+all: faq
+
+faq: $(BFNNCONV) asy-faq.bfnn
+ mkdir -p asy-faq.html
+ perl bfnnconv.pl asy-faq.bfnn
+ perl bfnnconv.pl asy-faq.bfnn
+
+clean: FORCE
+ -rm -f *~ core a.out *.lout *.ps *.info *.ascii *.xrefdb *.post
+ -rm -rf *.html
+
+install-all: install
+
+install: faq install-prebuilt
+ ${INSTALL} -d -m 755 $(docdir) $(docdir)/asy-faq.html
+ ${INSTALL} -p -m 644 asy-faq.ascii $(docdir)
+ ${INSTALL} -p -m 644 asy-faq.html/* $(docdir)/asy-faq.html
+
+install-prebuilt:
+ ${INSTALL} -d -m 755 $(infodir)
+ ${INSTALL} -p -m 644 asy-faq.info $(infodir)
+ -if test -z "$(DESTDIR)"; then \
+ install-info --infodir=$(infodir) asy-faq.info; \
+ fi
+
+install-info: faq install-prebuilt
+
+uninstall: uninstall-all
+
+uninstall-all:
+ -cd $(docdir)/asy-faq.html && rm -rf *.html
+ -cd $(docdir) && rmdir asy-faq.html && rm asy-faq.ascii
+ -install-info --remove --infodir=$(infodir) asy-faq.info
+ -rm -f $(infodir)/asy-faq.info
+
+distclean: FORCE clean
+
+FORCE:
diff --git a/graphics/asymptote/doc/FAQ/asy-faq.bfnn b/graphics/asymptote/doc/FAQ/asy-faq.bfnn
new file mode 100644
index 0000000000..2d3955af07
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/asy-faq.bfnn
@@ -0,0 +1,1287 @@
+\comment This is the source for the Asymptote FAQ list, in
+\comment the Bizarre Format With No Name. It is turned into Lout
+\comment input, HTML, plain ASCII and an Info document by a Perl script.
+\comment
+\comment The format and scripts come from the Linux FAQ, by
+\comment Ian Jackson.
+\set brieftitle Asymptote FAQ
+\set author <A href="http://asymptote.sourceforge.net">Asymptote</A>
+\set title Asymptote Frequently Asked Questions
+\copyto ASCII
+ ASYMPTOTE FREQUENTLY ASKED QUESTIONS
+ `date '+%d %h %Y'`
+
+\endcopy
+\copyto INFO
+INFO-DIR-SECTION Languages
+START-INFO-DIR-ENTRY
+* asymptote FAQ: (asy-faq). Asymptote Frequently Asked Questions.
+END-INFO-DIR-ENTRY
+
+
+File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir)
+
+ ASYMPTOTE FREQUENTLY ASKED QUESTIONS
+ `date '+%d %h %Y'`
+
+\endcopy
+
+This is the list of Frequently Asked Questions about Asymptote (asy).
+
+\section Index
+
+\index
+
+\comment ######################################################################
+
+\section About Asymptote
+
+\question 26jun:whatisasy What is Asymptote?
+
+Asymptote is a vector graphics language designed for
+technical graphics, inspired by MetaPost but with IEEE floating-point numerics,
+native three-dimensional graphics, Grayscale/RGB/CMYK colourspaces, and a
+C++-like syntax. Unlike MetaPost, it natively supports multiple-segment paths
+(and hence regions other than simply connected ones), tiling patterns, Gouraud
+ shading, tensor patch shading, and PostScript images.
+
+\question 22jun:whereisasy How do I obtain Asymptote?
+
+Binary releases are available for Linux, MacOS X, and Microsoft Windows
+platforms, in addition to full source code, from the website
+\docref{http://asymptote.sourceforge.net/\}. Many Linux distributions
+(such as RedHat and Debian) now include an Asymptote package (check your
+distribution's documentation for further information about this).
+
+\question 28jun:beforeasking Where can I ask questions about Asymptote?
+
+If you have a question, please try to find an answer in this FAQ, in the
+extensive Asymptote documentation at
+\docref{http://asymptote.sourceforge.net/doc/\}, or search the forum:
+\docref{http://sourceforge.net/forum/forum.php?forum_id=409349\}.
+
+\question 02sep:whyasy Why was the name Asymptote chosen?
+
+Well, it isn't the perfect graphics package, but we do think it is getting there
+asymptotically...
+
+\question 02sep:whycamp In the internal Asymptote source code, what does the name \courier{camp\} refer to?
+
+That was our original tentative name for this project, which stood for
+"C's Answer to MetaPost" (the language that inspired Asymptote).
+However, we eventually decided that the name \courier{Asymptote\} better
+emphasizes the mathematical and graphical nature of this language.
+
+\comment ######################################################################
+
+\section Questions about installation and setup
+
+\question 26jun:osx Is it possible to install Asymptote on Mac OS X?
+
+It is easy to compile Asymptote directly from the source code at
+\docref{http://sourceforge.net/project/showfiles.php?group_id=120000\}
+We recommend first upgrading to the latest GNU readline library, unless you
+don't care about interactive readline support (in which case configure will
+automatically detect and disable obsolete versions of the readline library).
+Marius Schamschula also maintains a binary package for various MacOS X
+platforms
+\docref{http://www.hmug.org/pub/MacOS_X/X/Applications/Publishing/asymptote\}.
+
+\question 26jun:osxbadCPU Why do I get the error \courier{Bad CPU type in executable\} on installing Asymptote from the MAC OS binary?
+
+This means either that you have a binary distribution for another MAC
+architecture, or (according to Marius Schamschula) that you may have a missing
+library. The simplest solution is to compile Asymptote directly from the
+official source:
+\docref{http://sourceforge.net/project/showfiles.php?group_id=120000\}.
+
+\question 04nov:brokenpdftex What do I do if I get the error: \courier{Error: pdfetex (file pdftex.cfg): cannot open config file...texinfo.tex appears to be broken\}?
+
+Simply put \docref{http://asymptote.sourceforge.net/asymptote.pdf\}
+in the directory \courier{doc\} and repeat the command \courier{make all\}.
+Or, if you don't want to build a local copy of the documentation, simply
+proceed with \courier{make install-asy\}.
+
+\question 04nov:brokentexinfo What do I do if I get the error: \courier{! Undefined control sequence. l.6 @copying\}?
+
+Either upgrade your \courier{texinfo\} package or follow one of the easy work arounds in \qref brokenpdftex.
+
+\question 27jun:latexintegration Is it possible to integrate Asymptote into LaTeX?
+
+Yes, see the example latexusage.tex. Dario Teixeira has also written a detailed
+guide on the topic. You can download it from
+\docref{http://dario.dse.nl/projects/asylatex/\}.
+
+Philippe Ivaldi has contributed an Asymptote mode for Emacs users
+\docref{http://asymptote.sourceforge.net/doc/Editing-modes.html\},
+which includes a \courier{lasy-mode\} that allows one to compile and view
+the output of one \\begin{asy}...\\end{asy} section at a time.
+
+\question 02sep:pdflatex Is it possible to integrate Asymptote into latex or pdflatex?
+
+Yes, as of version 1.14, Asymptote supports latex and pdflatex (both in
+EPS/PDF and inline mode), as illustrated by the example
+\courier{latexusage.tex\}:
+
+\verbatim
+pdflatex latexusage
+asy latexusage
+pdflatex latexusage
+\endverbatim
+
+\question 02sep:tkinterdepend Do I need the \courier{tkinter\} package to install an Asymptote rpm binary?
+
+No, you don't need \courier{tkinter\} unless you want to try out the GUI \courier{xasy\}. Try
+
+\verbatim
+rpm -Uvh --nodeps asymptote-x.xx-1.i386.rpm
+\endverbatim
+
+where \courier{x.xx\} represents the version number.
+
+\question 26jun:windir What does the path \courier{%USERPROFILE%\\.asy\\config.asy\} mean?
+
+That is the way that Microsoft Windows refers to the user profile directory.
+There's nothing really to understand here, just put your configuration
+commands in the file \courier{config.asy\} in a new folder \courier{%USERPROFILE%\\.asy\}.
+
+\question 25dec:escapechar Why do I get the error "string not terminated" when I try to set \courier{settings.dir="C:\\asymptote\\";\}?
+
+The backslash is an escape character here, so
+\courier{\\"\} is interpreted as a verbatim quotation mark, leaving the string
+without a terminating quotation mark. Fortunately, this is the
+only escaped character in double-quoted strings. A final backslash isn't
+needed here anyway, but should you really want one somewhere, you can say:
+\courier{settings.dir="C:\\asymptote"+'\\\\';\}.
+
+\question 27jun:winglobal How do I change environment variables in Microsoft Windows, for example, in order to change the default PostScript viewer?
+
+While it is easier to set the corresponding Asymptote configuration
+variable in your \courier{config.asy\} file, here is the procedure for changing
+Microsoft Windows environment variables:
+
+Click on the [Start] button
+
+* RIGHT-click on 'My Computer'
+
+* Choose 'Properties' from the popup menu
+
+* Click the 'Advanced' tab
+
+* Click the 'Environment Variables' button.
+
+\question 02sep:convert Under Microsoft Windows XP, why do I get an error like "Invalid Parameter - 432x432"?
+
+This means that ImageMagick wasn't properly installed and you are using the
+MSDOS convert program rather than the ImageMagick one. Or you may have
+installed ImageMagick but ran Asymptote from an existing MSDOS window.
+In that case, simply open a new window and try again. If that doesn't work,
+check that
+
+\verbatim
+convert --version
+\endverbatim
+
+returns something like
+
+\verbatim
+Version: ImageMagick 6.2.8 06/27/06 Q16 http://www.imagemagick.org
+\endverbatim
+
+\question 26jun:miktex Why does Asymptote freeze upon trying to draw a label with my MikTex installation under Microsoft Windows?
+
+Likely, this means that latex and dvips are not in your default path.
+Try adding the appropriate paths in your \courier{config.asy\} file,
+for example:
+
+\verbatim
+import settings;
+latex="C:\Program Files\MiKTeX 2.7\miktex\bin\latex.exe";
+dvips="C:\Program Files\MiKTeX 2.7\miktex\bin\dvips.exe";
+\endverbatim
+
+\comment #####################################################################
+
+\section Questions about paths
+
+\question 02sep:tensionsyntax Why do I get a syntax error message when I specify an integer value for the path tension?
+
+What is happening here is that
+
+\verbatim
+draw((0,0)..tension 2..(0,50)..(100,100));
+\endverbatim
+
+is read as
+
+\verbatim
+draw((0,0)..tension 2. .(0,50)..(100,100));
+\endverbatim
+
+So the first . after the two is treated as a decimal point.
+Just put a space after the integer tension value:
+
+\verbatim
+draw((0,0)..tension 2 ..(0,50)..(100,100));
+\endverbatim
+
+\question 27jun:dots Shouldn't dots always be the same size?
+
+From the documentation:
+
+"The dot command defined in the module plain draws a dot having a diameter
+equal to an explicit pen linewidth or the default linewidth magnified by
+dotfactor (6 by default)."
+
+Thus, when you use the default pen, the dot will have size 6*linewidth,
+but when you give a pen with an explicit width specified, you will
+have a dot of size linewidth. If you want the first case to behave like the
+second, you may set dotfactor=1.
+
+\comment #####################################################################
+
+\section Questions about labels
+
+\question 02sep:greek How do I get Greek letters like omega to show up in my labels?
+
+In (La)TeX, Greek letters can be obtained in math mode by prepending a
+backslash to the letter name. So for a omega symbol, use "$\\omega$". Everything
+between the dollar signs is considered to be a math formula. Uppercase Greek
+letters can be used by capitalizing the first letter of the name:
+
+\verbatim
+label("$\omega$",(0,0));
+label("$\Omega$",(20,0));
+\endverbatim
+
+\question 29jun:matlabels Can Asymptote use matrices as labels?
+
+Yes:
+\verbatim
+usepackage("amsmath");
+label("$\begin{matrix} 1 & 2 \\\ 1 & 1 \end{matrix}$",(0,0));
+\endverbatim
+
+\question 27jun:latexpackage How do I tell Asymptote to load a particular LaTeX package, like \courier{mathptmx\}?
+
+Put
+
+\verbatim
+usepackage("mathptmx");
+\endverbatim
+
+at the beginning of your file. Note: to enable the Adobe Times Roman font
+for text, you will also need to say:
+\verbatim
+defaultpen(TimesRoman());
+\endverbatim
+
+
+\question 28jun:internatfonts How can I use international fonts in Asymptote labels?
+
+See \docref{http://asymptote.sourceforge.net/doc/unicode.html\}.
+
+\question 10jul:Fourier How can I use Fourier fonts?
+
+\verbatim
+usepackage("fourier");
+defaultpen(font("T1","fut\textfamilyextension","m","n"));
+\endverbatim
+
+\question 26jun:decsep Is there any way to change the default appearance of the decimal separator, using a comma instead of a dot?
+
+Just set your locale appropriately:
+
+\verbatim
+locale("it_IT");
+usepackage("icomma");
+label(format(0.5));
+\endverbatim
+
+\question 02sep:rotatelabel How can I get a rotated label with the filled box rotated as well so that it fits the text?
+
+\verbatim
+frame f;
+label(f,"This is some text",white,Fill(blue));
+add(rotate(65)*f);
+\endverbatim
+
+
+\question 02sep:rotatelabel3D How can I rotate labels in a 3D figure?
+
+You need to first project the triple to a pair like this:
+
+\verbatim
+import three;
+size(100,100);
+
+draw(rotate(90,project(Z))*"A",O--X);
+\endverbatim
+
+\question 02sep:fixedsize How can I draw some squares and circles of a fixed size and put a label in the middle of them?
+
+Fixed-size objects should be drawn on a separate picture and then added to
+currentpicture. Here is one way (see also \docref{http://asymptote.sourceforge.net/gallery/subpictures.asy\} and \docref{http://asymptote.sourceforge.net/gallery/mosquito.asy\}):
+
+\verbatim
+real u=2cm;
+
+picture square;
+draw(square,scale(u)*shift(-0.5,-0.5)*unitsquare);
+
+picture circle;
+draw(circle,scale(0.5u)*unitcircle);
+
+void add(picture pic=currentpicture, Label L, picture object, pair z) {
+add(pic,object,z);
+label(pic,L,z);
+}
+
+add("square",square,(0,0));
+add("circle",circle,(5cm,0));
+\endverbatim
+
+\question 27jun:colorssaturation The binary operator * can be used to scale the color of a pen by a real number. Does this scaling factor have to be less than 1?
+
+The scaling factor can be greater than 1. But keep in mind that the rgb color
+components saturate at 1.
+
+Try
+\verbatim
+write(cyan); write(0.8*cyan); write(1.5*cyan);
+\endverbatim
+and you will quickly see what is going on.
+
+To get a lighter cyan you can say white+cyan,
+which yields rgb(0.5,1,1). If you want something even lighter specify the
+rgb colors directly,
+for example, rgb(0.9,1,1).
+
+Alternatively, work in cmyk colour space, which is nicer in that it handles
+saturation separately from hue:
+
+0.1*Cyan is light and 0.9*Cyan is dark.
+You can also say 0.1*cmyk(red).
+
+\question 05mar:commadecimalseparator Why is the space after the comma decimal separator in my locale so large?
+
+LaTeX is treating the comma as punctuation and not as a decimal separator.
+The solution is to load the \courier{icomma\} package near the beginning of your file:
+\verbatim
+usepackage("icomma");
+\endverbatim
+
+\question 11mar:hyperref How can I prevent \courier{texpreamble("\\usepackage[pdftex]{hyperref}")\} from changing the page size?
+
+\verbatim
+texpreamble("\usepackage[pdftex,setpagesize=false]{hyperref}");
+\endverbatim
+
+\comment #####################################################################
+
+\section Questions about arrows
+
+\question 02sep:doublearrows How do I draw two arrows at arbitrary positions along a path?
+
+Assuming that at least one of the arrowheads is to be filled, you can do this:
+
+\verbatim
+size(200);
+path g = (0,0)..(1,3)..(3,0);
+draw(g,Arrow(Relative(0.9)));
+add(arrow(g,invisible,FillDraw(black),Relative(0.5)));
+add(arrow(reverse(g),invisible,FillDraw(white,black),Relative(0.9)));
+\endverbatim
+
+If both of the arrowheads are to be drawn with filltype NoFill,
+one will need to create a specialized version of the arrow routine in
+\courier{plain_arrows.asy\}:
+
+\verbatim
+void arrow(frame f, arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=arrowhead.defaultfilltype,
+ position position=EndPoint, bool forwards=true,
+ margin margin=NoMargin, bool center=false);
+\endverbatim
+
+\question 02sep:reversearrow How do I reverse the direction of an arrowhead?
+
+Simply reverse the direction of the path.
+
+\verbatim
+path g=((0,0)--(5cm,0));
+draw(reverse(g),Arrow(Relative(0.55)));
+\endverbatim
+
+\question 02sep:reversearrow How do I change the size of all arrows?
+
+To override the arrowsize you can give every Arrow drawing attribute a real
+size argument. If you want to do this globally, you can override the
+pen-dependent arrowsize function like this:
+
+\verbatim
+DefaultHead.size=new real(pen p=currentpen) {return 2mm;};
+\endverbatim
+
+\question 26jun:arrowhead Can I create other arrowhead styles?
+
+Yes, you can build custom arrowheads like this (see the predefined
+arrowhead styles in \courier{plain_arrows.asy\} for further examples):
+
+\verbatim
+arrowhead DotHead;
+DotHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ if(size == 0) size=DotHead.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ return circle(0.5(x+y),0.5size);
+};
+
+size(100);
+draw((0,0)..(1,1)..(2,0),Arrow(DotHead));
+dot((2,0),red);
+\endverbatim
+
+If you submit your alternate arrowheads to the Forum or the Patch
+Tracking System, we'll consider including them in a future release.
+
+\comment #####################################################################
+
+\section Questions about 2D graphs
+
+\question 02sep:axisticks How can I draw x axis ticks on the right side, with the tick labels on the left side (relative to the axis path)?
+
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis("$x$",RightTicks(Label(align=left)));
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 02sep:axislabel How can I reposition the x axis label to three-quarters along the axis length?
+
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis(Label("$x$",0.75),LeftTicks);
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 02sep:axislabeldown How can I move the x axis label down 10bp?
+
+\verbatim
+import graph;
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis(shift(0,-10)*"$x$",LeftTicks);
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 02sep:threeaxispens Can I use different pens for the axis, the axis label, and the tick labels?
+
+Yes:
+
+\verbatim
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis(Label("$x$",MidPoint,red),Bottom,blue,LeftTicks(green));
+yaxis("$y$",Left,RightTicks);
+\endverbatim
+
+\question 02sep:axislabelfont How can I change the font type of the axes label?
+
+\verbatim
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis("x",Bottom,Courier("m","n"),LeftTicks);
+yaxis("$y$",Left,RightTicks);
+\endverbatim
+
+\question 02sep:axisticklabelfont How can I change the font type of the tick labels on an axis?
+
+Tick labels are by default typeset in (TeX) math mode, so to use other
+fonts you need to override the default tick format:
+
+\verbatim
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis("$x$",Bottom,LeftTicks("%.4g",Courier("m","n")+fontsize(12)));
+yaxis("$y$",Left,RightTicks);
+\endverbatim
+
+\question 26jun:overlappingticklabels How can I prevent axes tick labels from rendering on top of each other?
+
+Either:
+
+(i) give LeftTicks/RightTicks/Ticks the arguments beginlabel=false
+and/or endlabel=false;
+
+(ii) explicitly remove specific ticks and their labels (drawing them manually;
+see \docref{http://www.github.com/vectorgraphics/asymptote/base/graph.asy\} for the definition of NoZero):
+
+\verbatim
+import graph;
+
+size(10cm);
+
+real f(real x) {return x^2;}
+
+draw(graph(f,-2,2));
+
+xaxis(Ticks(NoZero));
+yaxis(Ticks(NoZero));
+
+label("$0$",(0,0),SW);
+\endverbatim
+
+(iii) explicitly remove specific tick labels and draw them manually
+(see \docref{http://www.github.com/vectorgraphics/asymptote/base/graph.asy\} for the definition of NoZeroFormat):
+
+\verbatim
+import graph;
+
+size(10cm);
+
+real f(real x) {return x^2;}
+
+draw(graph(f,-2,2));
+
+xaxis(Ticks(NoZeroFormat));
+yaxis(Ticks(NoZeroFormat));
+
+label("$0$",(0,0),SW);
+\endverbatim
+
+(iv) use the xasy GUI to move overlapping labels;
+
+(v) change the Label argument of LeftTicks, RightTicks, or Ticks to:
+
+\verbatim
+Label(currentpen+overwrite(Move))
+\endverbatim
+
+Solution (v) will move labels that might otherwise overwrite a previous
+label. Other possible overwrite arguments are Allow (allows overlapping
+labels; the default), Suppress (an overlapping label will not be written at
+all), SuppressQuiet, and MoveQuiet. The last two achieve the same result as
+the non-quiet types, but will not notify you which labels are overlapping. See:
+\docref{http://asymptote.sourceforge.net/doc/Pens.html\}.
+
+In the case of a user-specified tick array, you can change which labels get
+suppressed/moved by changing the order of array entries.
+
+\question 04nov:fixedsizegraphs How do I make the plot region of a graph, ignoring labels and legends, have a fixed size?
+
+Either:
+
+i) Specify an explicit unitsize, which overrides any call to \courier{size\}:
+\verbatim
+unitsize(x=1cm,y=2cm);
+\endverbatim
+
+ii) Explicitly tell Asymptote to map the plot region to a specific size:
+\verbatim
+import graph;
+real[] x={0,1,2,3};
+real[] y=x^2;
+draw(graph(x,y),red);
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+size(5cm,5cm,point(SW),point(NE));
+
+label("$f_\mathrm{T}$",point(N),2N);
+\endverbatim
+
+iii) Specify the points in user coordinates that should correspond to a
+given picture size:
+
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+fixedscaling((-1.5,-0.5),(1.5,3.5));
+\endverbatim
+
+In this example, the user coordinate \courier{(-1.5,-0.5)\} will end up
+being the lower left corner of the figure and \courier{(1.5,3.5)\} will be
+the upper right corner. You can use this option to ensure multiple figures
+have the same scaling and same resulting figure size (just ensure the two
+coordinates given to \courier{fixedscaling()\} leaves room for any labels).
+
+See also
+\docref{http://asymptote.sourceforge.net/doc/Frames-and-pictures.html\}.
+
+\question 26jun:graphlimits How can I plot a function f(x) within [0,1]x[0,2] without explicitly calculating the x values for which f(x) hits the boundary?
+
+Call \courier{limits\} with the \courier{Crop\} option before drawing the graph:
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+limits((0,0),(1,2),Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+\endverbatim
+
+See also \docref{http://asymptote.sourceforge.net/doc/graph.html\}.
+
+\question 26jun:custompalettes Is it possible to define customized palettes?
+
+Yes, you may generate your own pen[] array. For example:
+
+\verbatim
+int NColors=32768;
+pen[] MyPalette=new pen[NColors];
+real step=1/(NColors-1.0);
+// Start at black: rgb(0,0,0)
+// End at yellow: rgb(1,1,0)
+for(int i=0; i < NColors; ++i) {
+ real rgval=i*step;
+ MyPalette[i]=rgb(rgval,rgval,0.0);
+}
+\endverbatim
+
+\question 26jun:factorial Is there an easy way to graph factorial functions nicely?
+
+The example below shows a continuous function and two methods for placing
+markers at integer values of x:
+
+\verbatim
+import graph;
+
+size(200,200,IgnoreAspect);
+
+real factorial(real t) {return gamma(t+1);}
+
+scale(Linear,Log);
+
+// Graph the factorial function.
+draw(graph(factorial,0,10));
+
+// Method 1: Draw nodes, but hide line
+pair F(int t) {return (t,factorial(t));}
+// Graph of factorial function from 0 to 10
+pair[] z=sequence(F,11);
+draw(graph(z),invisible,marker(scale(0.8mm)*unitcircle,blue,Fill));
+
+// Method 2: Nongraphing routines require explicit scaling:
+pair dotloc(int t) {return Scale(F(t));}
+pair[] dotlocs=sequence(dotloc,11);
+dot(dotlocs);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+\endverbatim
+
+\question 26jun:length How do I indicate that a certain length should be exactly the size I prescribe with no rescaling, within a picture which has its own size?
+
+Here's an easy way to do this.
+
+\verbatim
+size(12cm,0);
+
+void distance(picture pic=currentpicture, pair A, pair B, Label L="", real n=0,
+ pen p=currentpen)
+{
+ real d=3mm;
+ path g=A--B;
+ transform T=shift(-n*d*unit(B-A)*I);
+ pic.add(new void(frame f, transform t) {
+ picture opic;
+ path G=T*t*g;
+ draw(opic,Label(L,Center,UnFill(1)),G,p,Arrows(NoFill),Bars,PenMargins);
+ add(f,opic.fit());
+ });
+ pic.addBox(min(g),max(g),T*min(p),T*max(p));
+}
+
+pair A=(0,0), B=(3,3);
+
+dot(A);
+dot(B);
+
+distance(A,B,"$\ell$",1);
+\endverbatim
+
+\question 26jun:log2 How can I make the y axis display base-2 logarithmic values?
+
+See the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/log2graph.asy\}.
+
+\question 27jun:align How can I align the x axes of two graphs on the same figure?
+
+An easy way to do this, if the axes to be aligned have the same scaling
+and size, is illustrated in the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/alignedaxis.asy\}.
+
+Here is a more general solution to the problem of aligning two arbitrary axes.
+One fits the second picture to a frame based on the horizontal scaling for
+the first picture:
+
+\verbatim
+import graph;
+
+real width=15cm;
+real aspect=0.3;
+
+picture pic1,pic2;
+
+size(pic1,width,aspect*width,IgnoreAspect);
+size(pic2,width,aspect*width,IgnoreAspect);
+
+scale(pic1,false);
+scale(pic2,false);
+
+real xmin1=6;
+real xmax1=9;
+real xmin2=8;
+real xmax2=16;
+
+real a1=1;
+real a2=0.001;
+
+real f1(real x) {return a1*sin(x/2*pi);}
+real f2(real x) {return a2*sin(x/4*pi);}
+
+draw(pic1,graph(pic1,f1,xmin1,xmax1));
+draw(pic2,graph(pic2,f2,xmin2,xmax2));
+
+xaxis(pic1,Bottom,LeftTicks());
+yaxis(pic1,"$f_1(x)$",Left,RightTicks);
+
+xaxis(pic2,"$x$",Bottom,LeftTicks(Step=4));
+yaxis(pic2,"$f_2(x)$",Left,RightTicks);
+
+yequals(pic1,0,Dotted);
+yequals(pic2,0,Dotted);
+
+pair min1=point(pic1,SW);
+pair max1=point(pic1,NE);
+
+pair min2=point(pic2,SW);
+pair max2=point(pic2,NE);
+
+real scale=(max1.x-min1.x)/(max2.x-min2.x);
+real shift=min1.x/scale-min2.x;
+
+transform t1=pic1.calculateTransform();
+transform t2=pic2.calculateTransform();
+transform T=xscale(scale*t1.xx)*yscale(t2.yy);
+
+add(pic1.fit());
+real height=truepoint(N,user=false).y-truepoint(S,user=false).y;
+add(shift(0,-height)*(shift(shift)*pic2).fit(T));
+\endverbatim
+
+\question 27jun:changeaxis How can I change the direction of the y-axis, such that negatives values are on the upper y-axis?
+
+Here is a simple example (see also the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/diatom.asy\} or the discussion
+of Linear(-1) in the documentation):
+
+\verbatim
+import graph;
+size(250,200,IgnoreAspect);
+
+scale(Linear,Linear(-1));
+
+draw(graph(log,0.1,10),red);
+
+xaxis("$x$",LeftTicks);
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 27jun:functioncolor How can I fill a path with a function that defines the color of each location?
+
+Use \courier{functionshade\} with a PDF tex engine, as illustrated
+by the example {functionshading.asy}.
+
+If you want to produce PostScript output, an approximate solution for now
+would be to superimpose a fine grid and specify colors to
+\courier{latticeshade\} that depend on position as a single pen[][]
+lattice. Alternatively, it may be more efficient to use \courier{tensorshade}.
+
+\question 27jun:nonexplicitfun Is there a way to draw a function that is not explicitly given, such as (y - 2)^2 = x - 1 ?
+
+Yes, use the parametric form
+
+\verbatim
+y=t
+x=(t-2)^2+1
+\endverbatim
+
+See the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/parametricgraph.asy\}.
+
+\question 27jun:scalesecondaryaxis Is it possible to reverse or stretch an axis?
+
+The real scaling argument to Linear is used to stretch (or reverse) the axis.
+To see the effect of axis stretching, be sure not to specify IgnoreAspect in
+the picture size command.
+
+A secondary axis has the same length as the primary axis, so stretching cannot
+have any effect. But one can still reverse the axis, with Linear(-1).
+
+\question 02sep:emptymarkers Why can't I use the UnFill option to draw graphs with empty markers?
+
+UnFill won't work here because it only affects the local frame the markers
+are initially drawn on, before being added to currentpicture.
+Here is a way of achieving the desired effect (assuming a white background):
+
+\verbatim
+import graph;
+size(10cm,0);
+pair[] z={(0,0),(0.5,0.5),(1,1)};
+path g=graph(z);
+
+draw(shift(0,.5)*g,marker(scale(5)*unitcircle,FillDraw(white)));
+
+xaxis(BottomTop,LeftTicks);
+yaxis(LeftRight,RightTicks);
+\endverbatim
+
+\question 02sep:paletterange How can I force several images to use the same palette range (e.g. the entire 0-255 grayscale range)?
+
+The palette color space corresponds to a range of values specified by the
+argument range, which can be \courier{Full\}, \courier{Automatic\} or an
+explicit range \courier{Range(pair min, pair max)\}. Here \courier{Full}
+specifies a range varying from the minimum to maximum values of the
+function over the sampling interval, while \courier{Automatic\} selects
+"nice" limits.
+
+\comment #####################################################################
+
+\section Questions about programming
+
+\question 27jun:comporint Is Asymptote an interpreter or a compiler?
+
+Asymptote compiles Asymptote commands into its own virtual machine code. It
+then runs this pseudocode on a virtual machine to produce PostScript code.
+
+\question 05sep:framepicture What is the difference between a frame and a picture?
+
+Frames are canvases for drawing in PostScript coordinates. While working
+with frames directly is occasionally necessary for constructing deferred
+drawing routines, pictures are usually more convenient to work with.
+See \qref unitsizes.
+
+\question 05sep:pathguide What is the difference between a path and a guide?
+
+A path is a cubic spline with fixed endpoint conditions.
+
+A guide is an unresolved cubic spline (list of cubic-spline nodes and
+control points). A guide is like a path except that the computation of the cubic
+spline is deferred until drawing time (when it is resolved into a path);
+this allows two guides with free endpoint conditions to be joined together
+smoothly.
+
+\question 27jun:picarray What is a convenient way to declare and initialize an array of pictures?
+
+You could write yourself a routine such as:
+\verbatim
+picture[] picture(int n) {
+ picture[] pic;
+ for(int i=0; i < n; ++i) {
+ pic[i]=new picture;
+ size(pic[i],19cm,0);
+ }
+ return pic;
+}
+
+picture[] pic=picture(6);
+\endverbatim
+
+\question 27jun:genarrays Is there a way to define functions that act on arrays in general (i.e. work for arrays of any type)?
+
+Generic types aren't yet implemented.
+
+But for now you can at least say
+\verbatim
+typedef string T;
+include F;
+
+typedef real T;
+include F;
+\endverbatim
+
+where \courier{F.asy\} contains some type-dependent code like
+\verbatim
+T[] operator $(T A, T B) {return new T[] {A,B};}
+\endverbatim
+
+\question 27jun:cirdep Is there any way to declare structures ahead of their definition, e.g. where struct A performs some operation on struct B, but B contains an A member?
+
+Asymptote does not support forward declaration of types. You can, however,
+nest structures, so that both types are visible for parts of the bodies of
+both structure definitions. For example:
+
+\verbatim
+struct B {
+ typedef void someroutine(B b);
+
+ static struct A {
+ someroutine routine;
+ void operator init(someroutine routine) {
+ this.routine=routine;
+ }
+ }
+
+ string test="Testing";
+}
+
+typedef B.A A;
+
+A a=B.A(new void(B b){write(b.test);});
+
+B b;
+a.routine(b);
+\endverbatim
+
+\question 04nov:static Where are static variables in for loops allocated?
+
+In the example
+
+\verbatim
+void f() {
+ for(int i=0; i < 3; ++i) {
+ static int n;
+ ++n;
+ write(n);
+ }
+}
+
+f(); // Writes 1, 2, 3
+\endverbatim
+
+the static qualifier means that \courier{n\} is allocated not just outside
+of the for loop, but also outside the function. This is clear if you call
+\courier{f\} multiple times; there is still only one instance of \courier{n\}.
+
+The "level" of a variable (where it is allocated) has nothing to do with
+the "scope" of a variable (how long it can be referred to by name).
+The curly braces enclosing a block affect only a variable's scope, not
+its level.
+
+Static modifiers are meaningless at the top level; they generate a warning
+and are simply ignored:
+
+\verbatim
+for(int i=0; i < 3; ++i) {
+ static int n;
+ ++n;
+ write(n);
+}
+// Writes warning about top-level static modifier and then 1, 1, 1
+\endverbatim
+
+Since version 1.22, non-static variables allocated in a loop body are allocated
+anew every iteration. This is only noticable in obscure cases where a variable
+in a loop is accessed in the closure of a function defined in the loop:
+
+\verbatim
+int f();
+
+for(int i=0; i < 10; ++i) {
+ int j=10*i;
+ if(i == 5)
+ f=new int() {return j;};
+}
+
+write(f()); // Writes 50
+\endverbatim
+
+Variables in the body of a loop last as long as that iteration of the loop,
+unless they are kept alive by a function closure as in the example above. In a
+function body, variables will last at least as long as the function call, though
+because of closures and garbage collection, they may last longer than that. If
+defined at the top level of a file or at the interactive prompt, they will last
+at least until the end of the file or prompt's run.
+
+\question 26jun:debug Is there a debugger for asy?
+
+Yes, Asymptote includes a line-based debugger:
+
+\docref{http://asymptote.sourceforge.net/doc/Debugger.html\}
+
+\question 27jun:patches Do you accept patches for Asymptote?
+
+Yes, in fact we would prefer that users submit patches for customized features
+(to \docref{http://sourceforge.net/tracker/?atid=685685&group_id=120000\})
+instead of relying on us to do all of the coding. Development will proceed
+faster that way.
+
+\comment #####################################################################
+
+\section Questions about differences between Asymptote and MetaPost
+
+\question 29jun:interp What is the equivalent of the MetaPost c[a,b] interpolation operator?
+
+\verbatim
+interp(a,b,c);
+\endverbatim
+
+\question 02sep:automaticscaling How does picture scaling differ in Asymptote and MetaPost?
+
+Asymptote includes an optional facility to do automatic scaling of pictures
+to achieve a given overall picture size, whereas Metapost only supports manual
+scaling. Asymptote defers drawing of objects drawn to pictures and
+distinguishes between true-size objects and objects that should scale with
+the picture size. The resulting linear programming problem is solved via
+the Simplex method.
+
+See the \docref{http://asymptote.sourceforge.net/gallery/dimension.asy\} example for an example of how deferred drawing is
+used to accomodate both user and true-size (PostScript) coordinates.
+
+\question 02sep:manualscaling How can I avoid automatic scaling of a picture?
+
+If you really like Metapost-style manual (hard-wired) scaling either:
+
+(i) use the default size(0,0) for the entire picture and do all of the
+scaling by hand, just like in MetaPost;
+
+(ii) draw to a separate picture pic and add(pic.fit());
+
+(iii) use frames.
+
+\question 23jun:mp3dots What is the equivalent of MetaPost ... command?
+
+The connector \courier{::\} is a macro for tension atleast 1:
+
+\verbatim
+size(100);
+pair z0=(0,0);
+pair z1=(1,0.25);
+pair z2=(2,0);
+draw(z0{up}::z1{right}::z2{down});
+\endverbatim
+
+\question 23jun:mppickup What is the equivalent of the MetaPost pickup command?
+
+Just say, for example:
+
+\verbatim
+currentpen=red;
+\endverbatim
+
+\question 29aug:whatever What is the equivalent of the MetaPost whatever command?
+
+Asymptote does not implicitly solve linear equations and therefore does not
+have the notion of a \courier{whatever\} unknown. Such a facility could
+certainly be added (perhaps using the notation \courier{?=\} since
+\courier{=\} means assignment).
+However, the most common uses of \courier{whatever\} in MetaPost are covered by
+functions like \courier{extension\} in \courier{math.asy\}:
+\verbatim
+pair extension(pair P, pair Q, pair p, pair q);
+\endverbatim
+this returns the intersection point of the extensions of the line segments
+\courier{PQ\} and \courier{pq\}. We find using routines like
+\courier{extension\} more explicit and less confusing to new users. But we
+could be persuaded to add something similar if someone can justify the
+need. In the meantime, one can always use the explicit built-in linear
+solver \courier{solve\} (see
+\docref{http://asymptote.sourceforge.net/doc/solve.html\}), which uses LU
+decomposition.
+
+\question 23jun:lray What is the equivalent for the MetaPost command for \courier{lray - horiz*v - verti*u = whatever*(LightSource - R)\}, a system of three linear equations for three unknowns: \courier{horiz, verti, whatever\}?
+
+Since \courier{horiz*v+verti*u\} spans a plane, you could use
+\verbatim
+real intersect(vector P, vector Q, vector n, vector Z);
+\endverbatim
+
+to find the intersection time for the line
+\courier{lray-whatever*(LightSource - R)\}
+and then extract the three desired values from there. (You'll still need to
+use the built-in explicit linear solver to solve a 2x2 system to get
+\courier{horiz\} and \courier{verti\}.)
+
+\question 27jun:unitsizes In MetaPost, it is possible to have a drawing remain the same size in different pictures by defining a unit \courier{u\} and explicitly multiply all the coordinates by \courier{u\}. Is there a better way to do this in Asymptote?
+
+Yes, Asymptote has a better way: you definitely don't want to manually scale
+all of your coordinates. To make the user coordinates represent multiples
+of exactly \courier{1cm\}:
+
+\verbatim
+unitsize(1cm);
+draw(unitsquare);
+\endverbatim
+
+One can also specify different x and y unit sizes:
+
+\verbatim
+unitsize(x=1cm,y=2cm);
+draw(unitsquare);
+\endverbatim
+
+Another way is to draw your fixed size object to a frame and add it to
+currentpicture like this:
+
+\verbatim
+path p=(0,0)--(1,0);
+frame object;
+draw(object,scale(100)*p);
+
+add(object);
+add(object,(0,-10));
+\endverbatim
+
+To understand the difference between frames and pictures, try this:
+
+\verbatim
+size(300,300);
+
+path p=(0,0)--(1,0);
+picture object;
+draw(object,scale(100)*p);
+
+add(object);
+add(object,(0,-10)); // Adds truesize object to currentpicture
+\endverbatim
+
+\question 28jun:tiles In MetaPost, one could produce tiling pictures by generating a picture, and then clipping the picture to a rectangle of fixed dimensions around the center of the picture. How is that done in Asymptote?
+
+If you are using currentpicture the way one would in MetaPost (drawing in
+raw PostScript coordinates), you can simply do something like:
+
+\verbatim
+fill((0,0)--(100,100)--(200,0)--cycle);
+
+pair center(picture pic=currentpicture) {return 0.5*(pic.min()+pic.max());}
+
+real height=100;
+real width=100;
+pair delta=0.5(width,height);
+pair c=center();
+clip(box(c-delta,c+delta));
+\endverbatim
+
+However, drawing in PostScript coordinates is often inconvenient. Here's the
+Asymptote way of doing the same thing, using deferred drawing:
+
+\verbatim
+size(200,100);
+fill((0,0)--(1,1)--(2,0)--cycle);
+
+void clip(picture pic=currentpicture, real width, real height)
+{
+ pic.clip(new void (frame f, transform) {
+ pair center=0.5(min(f)+max(f));
+ pair delta=0.5(width,height);
+ clip(f,box(center-delta,center+delta));
+ });
+}
+
+clip(100,100);
+\endverbatim
+
+See also the discussion of tilings in the documentation:
+\docref{http://asymptote.sourceforge.net/doc/Pens.html\}.
+
+\comment ######################################################################
+
+\section Questions about output
+
+\question 27jun:psviewer How can I disable automatic invocation of the PS viewer after an asy file is done processing?
+
+It's actually not on by default, unless you happen to be using Microsoft
+Windows (because that is what most Microsoft Windows users
+expect). Microsoft Windows users can turn this feature off with the
+command-line option -noV or by putting
+
+\verbatim
+import settings;
+interactiveView=false;
+batchView=false;
+\endverbatim
+
+in their \courier{config.asy\} file. See
+\docref{http://asymptote.sourceforge.net/doc/Options.html\}.
+
+\question 26jun:jpeg How do I output jpeg images?
+
+If you have the ImageMagick convert program installed, simply type
+
+\verbatim
+asy -f jpg test.asy
+\endverbatim
+
+\question 27jun:embedbitmaps Can I embed bitmaps (photos) into my drawings and position and scale them?
+
+Convert them to eps format and use the graphic(string) function just like a
+Label:
+
+\verbatim
+label(graphic("file"),(0,0));
+\endverbatim
+
+See the example \docref{http://asymptote.sourceforge.net/gallery/orthocenter.asy\} and
+\docref{http://asymptote.sourceforge.net/doc/label.html\}.
+
+\question 28jun:directpdf Does Asymptote support direct PDF output?
+
+Yes, PDF output can be produced by the -f pdf option or -tex pdflatex option.
+This supports transparency, annotations, embedded movies, and U3D/PRC content.
+
+\question 28jun:bigpictures How to I produce large pictures of high quality in raster format (e.g. png, giff etc).
+
+Try using some of the options to convert, mainly -geometry and -density. For example:
+\verbatim
+convert -geometry 1000x3000 example.eps example.png
+\endverbatim
+
+You can also change the default resolution of the image with:
+\verbatim
+convert -geometry 1000x3000 -density 300 -units PixelsPerInch example.eps example.png
+\endverbatim
+This does not change the number of pixels in the image, but just gives a hint
+as to how large each pixel should be displayed.
+
+If you include the -density option without the -geometry option, convert will
+keep the image size constant (so a 4cm x 3cm eps figure will generate a 4cm x
+3cm png
+image).
+
+\question 28jun:multipage Is it possible to produce multi-page documents with asymptote?
+
+Yes, simply call the newpage() function. This is used by the
+\courier{slide.asy\} package to produce high-quality slide presentations
+(easier to use than Prosper).
+
+\comment Here it ends!
diff --git a/graphics/asymptote/doc/FAQ/asy-faq.info b/graphics/asymptote/doc/FAQ/asy-faq.info
new file mode 100644
index 0000000000..717734ca0b
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/asy-faq.info
@@ -0,0 +1,1671 @@
+Info file: asy-faq.info, -*-Text-*-
+produced by bfnnconv.pl from the Bizarre Format With No Name.
+
+INFO-DIR-SECTION Languages
+START-INFO-DIR-ENTRY
+* asymptote FAQ: (asy-faq). Asymptote Frequently Asked Questions.
+END-INFO-DIR-ENTRY
+
+
+File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir)
+
+ ASYMPTOTE FREQUENTLY ASKED QUESTIONS
+ 20 Aug 2019
+
+This is the list of Frequently Asked Questions about Asymptote (asy).
+
+Index
+
+* Menu:
+* Section 1:: About Asymptote
+* Section 2:: Questions about installation and setup
+* Section 3:: Questions about paths
+* Section 4:: Questions about labels
+* Section 5:: Questions about arrows
+* Section 6:: Questions about 2D graphs
+* Section 7:: Questions about programming
+* Section 8:: Questions about differences between Asymptote and
+ MetaPost
+* Section 9:: Questions about output
+
+Section 1, About Asymptote
+* Question 1.1:: What is Asymptote?
+* Question 1.2:: How do I obtain Asymptote?
+* Question 1.3:: Where can I ask questions about Asymptote?
+* Question 1.4:: Why was the name Asymptote chosen?
+* Question 1.5:: In the internal Asymptote source code, what does the
+ name camp refer to?
+
+Section 2, Questions about installation and setup
+* Question 2.1:: Is it possible to install Asymptote on Mac OS X?
+* Question 2.2:: Why do I get the error Bad CPU type in executable on
+ installing Asymptote from the MAC OS binary?
+* Question 2.3:: What do I do if I get the error: Error: pdfetex (file
+ pdftex.cfg): cannot open config file...texinfo.tex
+ appears to be broken?
+* Question 2.4:: What do I do if I get the error: ! Undefined control
+ sequence. l.6 @copying?
+* Question 2.5:: Is it possible to integrate Asymptote into LaTeX?
+* Question 2.6:: Is it possible to integrate Asymptote into latex or
+ pdflatex?
+* Question 2.7:: Do I need the tkinter package to install an Asymptote
+ rpm binary?
+* Question 2.8:: What does the path %USERPROFILE%\.asy\config.asy mean?
+* Question 2.9:: Why do I get the error "string not terminated" when I
+ try to set settings.dir="C:\asymptote\";?
+* Question 2.10:: How do I change environment variables in Microsoft
+ Windows, for example, in order to change the default
+ PostScript viewer?
+* Question 2.11:: Under Microsoft Windows XP, why do I get an error like
+ "Invalid Parameter - 432x432"?
+* Question 2.12:: Why does Asymptote freeze upon trying to draw a label
+ with my MikTex installation under Microsoft Windows?
+
+Section 3, Questions about paths
+* Question 3.1:: Why do I get a syntax error message when I specify an
+ integer value for the path tension?
+* Question 3.2:: Shouldn't dots always be the same size?
+
+Section 4, Questions about labels
+* Question 4.1:: How do I get Greek letters like omega to show up in my
+ labels?
+* Question 4.2:: Can Asymptote use matrices as labels?
+* Question 4.3:: How do I tell Asymptote to load a particular LaTeX
+ package, like mathptmx?
+* Question 4.4:: How can I use international fonts in Asymptote labels?
+* Question 4.5:: How can I use Fourier fonts?
+* Question 4.6:: Is there any way to change the default appearance of
+ the decimal separator, using a comma instead of a dot?
+* Question 4.7:: How can I get a rotated label with the filled box
+ rotated as well so that it fits the text?
+* Question 4.8:: How can I rotate labels in a 3D figure?
+* Question 4.9:: How can I draw some squares and circles of a fixed
+ size and put a label in the middle of them?
+* Question 4.10:: The binary operator * can be used to scale the color
+ of a pen by a real number. Does this scaling factor
+ have to be less than 1?
+* Question 4.11:: Why is the space after the comma decimal separator in
+ my locale so large?
+* Question 4.12:: How can I prevent
+ texpreamble("\usepackage[pdftex]{hyperref}") from
+ changing the page size?
+
+Section 5, Questions about arrows
+* Question 5.1:: How do I draw two arrows at arbitrary positions along
+ a path?
+* Question 5.2:: How do I reverse the direction of an arrowhead?
+* Question 5.3:: How do I change the size of all arrows?
+* Question 5.4:: Can I create other arrowhead styles?
+
+Section 6, Questions about 2D graphs
+* Question 6.1:: How can I draw x axis ticks on the right side, with
+ the tick labels on the left side (relative to the axis
+ path)?
+* Question 6.2:: How can I reposition the x axis label to
+ three-quarters along the axis length?
+* Question 6.3:: How can I move the x axis label down 10bp?
+* Question 6.4:: Can I use different pens for the axis, the axis label,
+ and the tick labels?
+* Question 6.5:: How can I change the font type of the axes label?
+* Question 6.6:: How can I change the font type of the tick labels on
+ an axis?
+* Question 6.7:: How can I prevent axes tick labels from rendering on
+ top of each other?
+* Question 6.8:: How do I make the plot region of a graph, ignoring
+ labels and legends, have a fixed size?
+* Question 6.9:: How can I plot a function f(x) within [0,1]x[0,2]
+ without explicitly calculating the x values for which
+ f(x) hits the boundary?
+* Question 6.10:: Is it possible to define customized palettes?
+* Question 6.11:: Is there an easy way to graph factorial functions
+ nicely?
+* Question 6.12:: How do I indicate that a certain length should be
+ exactly the size I prescribe with no rescaling, within
+ a picture which has its own size?
+* Question 6.13:: How can I make the y axis display base-2 logarithmic
+ values?
+* Question 6.14:: How can I align the x axes of two graphs on the same
+ figure?
+* Question 6.15:: How can I change the direction of the y-axis, such
+ that negatives values are on the upper y-axis?
+* Question 6.16:: How can I fill a path with a function that defines the
+ color of each location?
+* Question 6.17:: Is there a way to draw a function that is not
+ explicitly given, such as (y - 2)^2 = x - 1 ?
+* Question 6.18:: Is it possible to reverse or stretch an axis?
+* Question 6.19:: Why can't I use the UnFill option to draw graphs with
+ empty markers?
+* Question 6.20:: How can I force several images to use the same palette
+ range (e.g. the entire 0-255 grayscale range)?
+
+Section 7, Questions about programming
+* Question 7.1:: Is Asymptote an interpreter or a compiler?
+* Question 7.2:: What is the difference between a frame and a picture?
+* Question 7.3:: What is the difference between a path and a guide?
+* Question 7.4:: What is a convenient way to declare and initialize an
+ array of pictures?
+* Question 7.5:: Is there a way to define functions that act on arrays
+ in general (i.e. work for arrays of any type)?
+* Question 7.6:: Is there any way to declare structures ahead of their
+ definition, e.g. where struct A performs some
+ operation on struct B, but B contains an A member?
+* Question 7.7:: Where are static variables in for loops allocated?
+* Question 7.8:: Is there a debugger for asy?
+* Question 7.9:: Do you accept patches for Asymptote?
+
+Section 8, Questions about differences between Asymptote and
+ MetaPost
+* Question 8.1:: What is the equivalent of the MetaPost c[a,b]
+ interpolation operator?
+* Question 8.2:: How does picture scaling differ in Asymptote and
+ MetaPost?
+* Question 8.3:: How can I avoid automatic scaling of a picture?
+* Question 8.4:: What is the equivalent of MetaPost ... command?
+* Question 8.5:: What is the equivalent of the MetaPost pickup command?
+* Question 8.6:: What is the equivalent of the MetaPost whatever
+ command?
+* Question 8.7:: What is the equivalent for the MetaPost command for
+ lray - horiz*v - verti*u = whatever*(LightSource - R),
+ a system of three linear equations for three unknowns:
+ horiz, verti, whatever?
+* Question 8.8:: In MetaPost, it is possible to have a drawing remain
+ the same size in different pictures by defining a unit
+ u and explicitly multiply all the coordinates by u. Is
+ there a better way to do this in Asymptote?
+* Question 8.9:: In MetaPost, one could produce tiling pictures by
+ generating a picture, and then clipping the picture to
+ a rectangle of fixed dimensions around the center of
+ the picture. How is that done in Asymptote?
+
+Section 9, Questions about output
+* Question 9.1:: How can I disable automatic invocation of the PS
+ viewer after an asy file is done processing?
+* Question 9.2:: How do I output jpeg images?
+* Question 9.3:: Can I embed bitmaps (photos) into my drawings and
+ position and scale them?
+* Question 9.4:: Does Asymptote support direct PDF output?
+* Question 9.5:: How to I produce large pictures of high quality in
+ raster format (e.g. png, giff etc).
+* Question 9.6:: Is it possible to produce multi-page documents with
+ asymptote?
+
+
+
+File: asy-faq.info, Node: Section 1, Next: Section 2, Previous: Top, Up: Top
+
+About Asymptote
+
+* Menu:
+* Question 1.1:: What is Asymptote?
+* Question 1.2:: How do I obtain Asymptote?
+* Question 1.3:: Where can I ask questions about Asymptote?
+* Question 1.4:: Why was the name Asymptote chosen?
+* Question 1.5:: In the internal Asymptote source code, what does the
+ name camp refer to?
+
+
+
+File: asy-faq.info, Node: Question 1.1, Next: Question 1.2, Previous: Top, Up: Section 1
+
+Question 1.1. What is Asymptote?
+
+Asymptote is a vector graphics language designed for technical graphics,
+inspired by MetaPost but with IEEE floating-point numerics, native
+three-dimensional graphics, Grayscale/RGB/CMYK colourspaces, and a
+C++-like syntax. Unlike MetaPost, it natively supports multiple-segment
+paths (and hence regions other than simply connected ones), tiling
+patterns, Gouraud shading, tensor patch shading, and PostScript images.
+
+
+File: asy-faq.info, Node: Question 1.2, Next: Question 1.3, Previous: Question 1.1, Up: Section 1
+
+Question 1.2. How do I obtain Asymptote?
+
+Binary releases are available for Linux, MacOS X, and Microsoft Windows
+platforms, in addition to full source code, from the website
+http://asymptote.sourceforge.net/. Many Linux distributions (such as
+RedHat and Debian) now include an Asymptote package (check your
+distribution's documentation for further information about this).
+
+
+File: asy-faq.info, Node: Question 1.3, Next: Question 1.4, Previous: Question 1.2, Up: Section 1
+
+Question 1.3. Where can I ask questions about Asymptote?
+
+If you have a question, please try to find an answer in this FAQ, in the
+extensive Asymptote documentation at
+http://asymptote.sourceforge.net/doc/, or search the forum:
+http://sourceforge.net/forum/forum.php?forum_id=409349.
+
+
+File: asy-faq.info, Node: Question 1.4, Next: Question 1.5, Previous: Question 1.3, Up: Section 1
+
+Question 1.4. Why was the name Asymptote chosen?
+
+Well, it isn't the perfect graphics package, but we do think it is getting
+there asymptotically...
+
+
+File: asy-faq.info, Node: Question 1.5, Next: Question 2.1, Previous: Question 1.4, Up: Section 1
+
+Question 1.5. In the internal Asymptote source code, what does the name camp refer to?
+
+That was our original tentative name for this project, which stood for
+"C's Answer to MetaPost" (the language that inspired Asymptote). However,
+we eventually decided that the name Asymptote better emphasizes the
+mathematical and graphical nature of this language.
+
+
+File: asy-faq.info, Node: Section 2, Next: Section 3, Previous: Section 1, Up: Top
+
+Questions about installation and setup
+
+* Menu:
+* Question 2.1:: Is it possible to install Asymptote on Mac OS X?
+* Question 2.2:: Why do I get the error Bad CPU type in executable on
+ installing Asymptote from the MAC OS binary?
+* Question 2.3:: What do I do if I get the error: Error: pdfetex (file
+ pdftex.cfg): cannot open config file...texinfo.tex
+ appears to be broken?
+* Question 2.4:: What do I do if I get the error: ! Undefined control
+ sequence. l.6 @copying?
+* Question 2.5:: Is it possible to integrate Asymptote into LaTeX?
+* Question 2.6:: Is it possible to integrate Asymptote into latex or
+ pdflatex?
+* Question 2.7:: Do I need the tkinter package to install an Asymptote
+ rpm binary?
+* Question 2.8:: What does the path %USERPROFILE%\.asy\config.asy mean?
+* Question 2.9:: Why do I get the error "string not terminated" when I
+ try to set settings.dir="C:\asymptote\";?
+* Question 2.10:: How do I change environment variables in Microsoft
+ Windows, for example, in order to change the default
+ PostScript viewer?
+* Question 2.11:: Under Microsoft Windows XP, why do I get an error like
+ "Invalid Parameter - 432x432"?
+* Question 2.12:: Why does Asymptote freeze upon trying to draw a label
+ with my MikTex installation under Microsoft Windows?
+
+
+
+File: asy-faq.info, Node: Question 2.1, Next: Question 2.2, Previous: Question 1.5, Up: Section 2
+
+Question 2.1. Is it possible to install Asymptote on Mac OS X?
+
+It is easy to compile Asymptote directly from the source code at
+http://sourceforge.net/project/showfiles.php?group_id=120000 We recommend
+first upgrading to the latest GNU readline library, unless you don't care
+about interactive readline support (in which case configure will
+automatically detect and disable obsolete versions of the readline
+library). Marius Schamschula also maintains a binary package for various
+MacOS X platforms
+http://www.hmug.org/pub/MacOS_X/X/Applications/Publishing/asymptote.
+
+
+File: asy-faq.info, Node: Question 2.2, Next: Question 2.3, Previous: Question 2.1, Up: Section 2
+
+Question 2.2. Why do I get the error Bad CPU type in executable on installing Asymptote from the MAC OS binary?
+
+This means either that you have a binary distribution for another MAC
+architecture, or (according to Marius Schamschula) that you may have a
+missing library. The simplest solution is to compile Asymptote directly
+from the official source:
+http://sourceforge.net/project/showfiles.php?group_id=120000.
+
+
+File: asy-faq.info, Node: Question 2.3, Next: Question 2.4, Previous: Question 2.2, Up: Section 2
+
+Question 2.3. What do I do if I get the error: Error: pdfetex (file pdftex.cfg): cannot open config file...texinfo.tex appears to be broken?
+
+Simply put http://asymptote.sourceforge.net/asymptote.pdf in the directory
+doc and repeat the command make all. Or, if you don't want to build a
+local copy of the documentation, simply proceed with make install-asy.
+
+
+File: asy-faq.info, Node: Question 2.4, Next: Question 2.5, Previous: Question 2.3, Up: Section 2
+
+Question 2.4. What do I do if I get the error: ! Undefined control sequence. l.6 @copying?
+
+Either upgrade your texinfo package or follow one of the easy work arounds
+in *Note Question 2.3:: `What do I do if I get the error: Error: pdfetex
+(file pdftex.cfg): cannot open config file...texinfo.tex appears to be
+broken?'.
+
+
+File: asy-faq.info, Node: Question 2.5, Next: Question 2.6, Previous: Question 2.4, Up: Section 2
+
+Question 2.5. Is it possible to integrate Asymptote into LaTeX?
+
+Yes, see the example latexusage.tex. Dario Teixeira has also written a
+detailed guide on the topic. You can download it from
+http://dario.dse.nl/projects/asylatex/.
+
+Philippe Ivaldi has contributed an Asymptote mode for Emacs users
+http://asymptote.sourceforge.net/doc/Editing-modes.html, which includes a
+lasy-mode that allows one to compile and view the output of one
+\begin{asy}...\end{asy} section at a time.
+
+
+File: asy-faq.info, Node: Question 2.6, Next: Question 2.7, Previous: Question 2.5, Up: Section 2
+
+Question 2.6. Is it possible to integrate Asymptote into latex or pdflatex?
+
+Yes, as of version 1.14, Asymptote supports latex and pdflatex (both in
+EPS/PDF and inline mode), as illustrated by the example latexusage.tex:
+
+pdflatex latexusage
+asy latexusage
+pdflatex latexusage
+
+File: asy-faq.info, Node: Question 2.7, Next: Question 2.8, Previous: Question 2.6, Up: Section 2
+
+Question 2.7. Do I need the tkinter package to install an Asymptote rpm binary?
+
+No, you don't need tkinter unless you want to try out the GUI xasy. Try
+
+rpm -Uvh --nodeps asymptote-x.xx-1.i386.rpm
+where x.xx represents the version number.
+
+
+File: asy-faq.info, Node: Question 2.8, Next: Question 2.9, Previous: Question 2.7, Up: Section 2
+
+Question 2.8. What does the path %USERPROFILE%\.asy\config.asy mean?
+
+That is the way that Microsoft Windows refers to the user profile
+directory. There's nothing really to understand here, just put your
+configuration commands in the file config.asy in a new folder
+%USERPROFILE%\.asy.
+
+
+File: asy-faq.info, Node: Question 2.9, Next: Question 2.10, Previous: Question 2.8, Up: Section 2
+
+Question 2.9. Why do I get the error "string not terminated" when I try to set settings.dir="C:\asymptote\";?
+
+The backslash is an escape character here, so \" is interpreted as a
+verbatim quotation mark, leaving the string without a terminating
+quotation mark. Fortunately, this is the only escaped character in
+double-quoted strings. A final backslash isn't needed here anyway, but
+should you really want one somewhere, you can say:
+settings.dir="C:\asymptote"+'\\';.
+
+
+File: asy-faq.info, Node: Question 2.10, Next: Question 2.11, Previous: Question 2.9, Up: Section 2
+
+Question 2.10. How do I change environment variables in Microsoft Windows, for example, in order to change the default PostScript viewer?
+
+While it is easier to set the corresponding Asymptote configuration
+variable in your config.asy file, here is the procedure for changing
+Microsoft Windows environment variables:
+
+Click on the [Start] button
+
+* RIGHT-click on 'My Computer'
+
+* Choose 'Properties' from the popup menu
+
+* Click the 'Advanced' tab
+
+* Click the 'Environment Variables' button.
+
+
+File: asy-faq.info, Node: Question 2.11, Next: Question 2.12, Previous: Question 2.10, Up: Section 2
+
+Question 2.11. Under Microsoft Windows XP, why do I get an error like "Invalid Parameter - 432x432"?
+
+This means that ImageMagick wasn't properly installed and you are using
+the MSDOS convert program rather than the ImageMagick one. Or you may have
+installed ImageMagick but ran Asymptote from an existing MSDOS window. In
+that case, simply open a new window and try again. If that doesn't work,
+check that
+
+convert --version
+returns something like
+
+Version: ImageMagick 6.2.8 06/27/06 Q16 http://www.imagemagick.org
+
+File: asy-faq.info, Node: Question 2.12, Next: Question 3.1, Previous: Question 2.11, Up: Section 2
+
+Question 2.12. Why does Asymptote freeze upon trying to draw a label with my MikTex installation under Microsoft Windows?
+
+Likely, this means that latex and dvips are not in your default path. Try
+adding the appropriate paths in your config.asy file, for example:
+
+import settings;
+latex="C:\Program Files\MiKTeX 2.7\miktex\bin\latex.exe";
+dvips="C:\Program Files\MiKTeX 2.7\miktex\bin\dvips.exe";
+
+File: asy-faq.info, Node: Section 3, Next: Section 4, Previous: Section 2, Up: Top
+
+Questions about paths
+
+* Menu:
+* Question 3.1:: Why do I get a syntax error message when I specify an
+ integer value for the path tension?
+* Question 3.2:: Shouldn't dots always be the same size?
+
+
+
+File: asy-faq.info, Node: Question 3.1, Next: Question 3.2, Previous: Question 2.12, Up: Section 3
+
+Question 3.1. Why do I get a syntax error message when I specify an integer value for the path tension?
+
+What is happening here is that
+
+draw((0,0)..tension 2..(0,50)..(100,100));
+is read as
+
+draw((0,0)..tension 2. .(0,50)..(100,100));
+So the first . after the two is treated as a decimal point. Just put a
+space after the integer tension value:
+
+draw((0,0)..tension 2 ..(0,50)..(100,100));
+
+File: asy-faq.info, Node: Question 3.2, Next: Question 4.1, Previous: Question 3.1, Up: Section 3
+
+Question 3.2. Shouldn't dots always be the same size?
+
+From the documentation:
+
+"The dot command defined in the module plain draws a dot having a diameter
+equal to an explicit pen linewidth or the default linewidth magnified by
+dotfactor (6 by default)."
+
+Thus, when you use the default pen, the dot will have size 6*linewidth,
+but when you give a pen with an explicit width specified, you will have a
+dot of size linewidth. If you want the first case to behave like the
+second, you may set dotfactor=1.
+
+
+File: asy-faq.info, Node: Section 4, Next: Section 5, Previous: Section 3, Up: Top
+
+Questions about labels
+
+* Menu:
+* Question 4.1:: How do I get Greek letters like omega to show up in my
+ labels?
+* Question 4.2:: Can Asymptote use matrices as labels?
+* Question 4.3:: How do I tell Asymptote to load a particular LaTeX
+ package, like mathptmx?
+* Question 4.4:: How can I use international fonts in Asymptote labels?
+* Question 4.5:: How can I use Fourier fonts?
+* Question 4.6:: Is there any way to change the default appearance of
+ the decimal separator, using a comma instead of a dot?
+* Question 4.7:: How can I get a rotated label with the filled box
+ rotated as well so that it fits the text?
+* Question 4.8:: How can I rotate labels in a 3D figure?
+* Question 4.9:: How can I draw some squares and circles of a fixed
+ size and put a label in the middle of them?
+* Question 4.10:: The binary operator * can be used to scale the color
+ of a pen by a real number. Does this scaling factor
+ have to be less than 1?
+* Question 4.11:: Why is the space after the comma decimal separator in
+ my locale so large?
+* Question 4.12:: How can I prevent
+ texpreamble("\usepackage[pdftex]{hyperref}") from
+ changing the page size?
+
+
+
+File: asy-faq.info, Node: Question 4.1, Next: Question 4.2, Previous: Question 3.2, Up: Section 4
+
+Question 4.1. How do I get Greek letters like omega to show up in my labels?
+
+In (La)TeX, Greek letters can be obtained in math mode by prepending a
+backslash to the letter name. So for a omega symbol, use "$\omega$".
+Everything between the dollar signs is considered to be a math formula.
+Uppercase Greek letters can be used by capitalizing the first letter of
+the name:
+
+label("$\omega$",(0,0));
+label("$\Omega$",(20,0));
+
+File: asy-faq.info, Node: Question 4.2, Next: Question 4.3, Previous: Question 4.1, Up: Section 4
+
+Question 4.2. Can Asymptote use matrices as labels?
+
+Yes:
+usepackage("amsmath");
+label("$\begin{matrix} 1 & 2 \\\ 1 & 1 \end{matrix}$",(0,0));
+
+File: asy-faq.info, Node: Question 4.3, Next: Question 4.4, Previous: Question 4.2, Up: Section 4
+
+Question 4.3. How do I tell Asymptote to load a particular LaTeX package, like mathptmx?
+
+Put
+
+usepackage("mathptmx");
+at the beginning of your file. Note: to enable the Adobe Times Roman font
+for text, you will also need to say:
+defaultpen(TimesRoman());
+
+File: asy-faq.info, Node: Question 4.4, Next: Question 4.5, Previous: Question 4.3, Up: Section 4
+
+Question 4.4. How can I use international fonts in Asymptote labels?
+
+See http://asymptote.sourceforge.net/doc/unicode.html.
+
+
+File: asy-faq.info, Node: Question 4.5, Next: Question 4.6, Previous: Question 4.4, Up: Section 4
+
+Question 4.5. How can I use Fourier fonts?
+
+usepackage("fourier");
+defaultpen(font("T1","fut\textfamilyextension","m","n"));
+
+File: asy-faq.info, Node: Question 4.6, Next: Question 4.7, Previous: Question 4.5, Up: Section 4
+
+Question 4.6. Is there any way to change the default appearance of the decimal separator, using a comma instead of a dot?
+
+Just set your locale appropriately:
+
+locale("it_IT");
+usepackage("icomma");
+label(format(0.5));
+
+File: asy-faq.info, Node: Question 4.7, Next: Question 4.8, Previous: Question 4.6, Up: Section 4
+
+Question 4.7. How can I get a rotated label with the filled box rotated as well so that it fits the text?
+
+frame f;
+label(f,"This is some text",white,Fill(blue));
+add(rotate(65)*f);
+
+File: asy-faq.info, Node: Question 4.8, Next: Question 4.9, Previous: Question 4.7, Up: Section 4
+
+Question 4.8. How can I rotate labels in a 3D figure?
+
+You need to first project the triple to a pair like this:
+
+import three;
+size(100,100);
+
+draw(rotate(90,project(Z))*"A",O--X);
+
+File: asy-faq.info, Node: Question 4.9, Next: Question 4.10, Previous: Question 4.8, Up: Section 4
+
+Question 4.9. How can I draw some squares and circles of a fixed size and put a label in the middle of them?
+
+Fixed-size objects should be drawn on a separate picture and then added to
+currentpicture. Here is one way (see also
+http://asymptote.sourceforge.net/gallery/subpictures.asy and
+http://asymptote.sourceforge.net/gallery/mosquito.asy):
+
+real u=2cm;
+
+picture square;
+draw(square,scale(u)*shift(-0.5,-0.5)*unitsquare);
+
+picture circle;
+draw(circle,scale(0.5u)*unitcircle);
+
+void add(picture pic=currentpicture, Label L, picture object, pair z) {
+add(pic,object,z);
+label(pic,L,z);
+}
+
+add("square",square,(0,0));
+add("circle",circle,(5cm,0));
+
+File: asy-faq.info, Node: Question 4.10, Next: Question 4.11, Previous: Question 4.9, Up: Section 4
+
+Question 4.10. The binary operator * can be used to scale the color of a pen by a real number. Does this scaling factor have to be less than 1?
+
+The scaling factor can be greater than 1. But keep in mind that the rgb
+color components saturate at 1.
+
+Try
+write(cyan); write(0.8*cyan); write(1.5*cyan);
+and you will quickly see what is going on.
+
+To get a lighter cyan you can say white+cyan, which yields rgb(0.5,1,1).
+If you want something even lighter specify the rgb colors directly, for
+example, rgb(0.9,1,1).
+
+Alternatively, work in cmyk colour space, which is nicer in that it
+handles saturation separately from hue:
+
+0.1*Cyan is light and 0.9*Cyan is dark. You can also say 0.1*cmyk(red).
+
+
+File: asy-faq.info, Node: Question 4.11, Next: Question 4.12, Previous: Question 4.10, Up: Section 4
+
+Question 4.11. Why is the space after the comma decimal separator in my locale so large?
+
+LaTeX is treating the comma as punctuation and not as a decimal separator.
+The solution is to load the icomma package near the beginning of your
+file:
+usepackage("icomma");
+
+File: asy-faq.info, Node: Question 4.12, Next: Question 5.1, Previous: Question 4.11, Up: Section 4
+
+Question 4.12. How can I prevent texpreamble("\usepackage[pdftex]{hyperref}") from changing the page size?
+
+texpreamble("\usepackage[pdftex,setpagesize=false]{hyperref}");
+
+File: asy-faq.info, Node: Section 5, Next: Section 6, Previous: Section 4, Up: Top
+
+Questions about arrows
+
+* Menu:
+* Question 5.1:: How do I draw two arrows at arbitrary positions along
+ a path?
+* Question 5.2:: How do I reverse the direction of an arrowhead?
+* Question 5.3:: How do I change the size of all arrows?
+* Question 5.4:: Can I create other arrowhead styles?
+
+
+
+File: asy-faq.info, Node: Question 5.1, Next: Question 5.2, Previous: Question 4.12, Up: Section 5
+
+Question 5.1. How do I draw two arrows at arbitrary positions along a path?
+
+Assuming that at least one of the arrowheads is to be filled, you can do
+this:
+
+size(200);
+path g = (0,0)..(1,3)..(3,0);
+draw(g,Arrow(Relative(0.9)));
+add(arrow(g,invisible,FillDraw(black),Relative(0.5)));
+add(arrow(reverse(g),invisible,FillDraw(white,black),Relative(0.9)));
+If both of the arrowheads are to be drawn with filltype NoFill, one will
+need to create a specialized version of the arrow routine in
+plain_arrows.asy:
+
+void arrow(frame f, arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=arrowhead.defaultfilltype,
+ position position=EndPoint, bool forwards=true,
+ margin margin=NoMargin, bool center=false);
+
+File: asy-faq.info, Node: Question 5.2, Next: Question 5.3, Previous: Question 5.1, Up: Section 5
+
+Question 5.2. How do I reverse the direction of an arrowhead?
+
+Simply reverse the direction of the path.
+
+path g=((0,0)--(5cm,0));
+draw(reverse(g),Arrow(Relative(0.55)));
+
+File: asy-faq.info, Node: Question 5.3, Next: Question 5.4, Previous: Question 5.2, Up: Section 5
+
+Question 5.3. How do I change the size of all arrows?
+
+To override the arrowsize you can give every Arrow drawing attribute a
+real size argument. If you want to do this globally, you can override the
+pen-dependent arrowsize function like this:
+
+DefaultHead.size=new real(pen p=currentpen) {return 2mm;};
+
+File: asy-faq.info, Node: Question 5.4, Next: Question 6.1, Previous: Question 5.3, Up: Section 5
+
+Question 5.4. Can I create other arrowhead styles?
+
+Yes, you can build custom arrowheads like this (see the predefined
+arrowhead styles in plain_arrows.asy for further examples):
+
+arrowhead DotHead;
+DotHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ if(size == 0) size=DotHead.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ return circle(0.5(x+y),0.5size);
+};
+
+size(100);
+draw((0,0)..(1,1)..(2,0),Arrow(DotHead));
+dot((2,0),red);
+If you submit your alternate arrowheads to the Forum or the Patch
+Tracking System, we'll consider including them in a future release.
+
+
+File: asy-faq.info, Node: Section 6, Next: Section 7, Previous: Section 5, Up: Top
+
+Questions about 2D graphs
+
+* Menu:
+* Question 6.1:: How can I draw x axis ticks on the right side, with
+ the tick labels on the left side (relative to the axis
+ path)?
+* Question 6.2:: How can I reposition the x axis label to
+ three-quarters along the axis length?
+* Question 6.3:: How can I move the x axis label down 10bp?
+* Question 6.4:: Can I use different pens for the axis, the axis label,
+ and the tick labels?
+* Question 6.5:: How can I change the font type of the axes label?
+* Question 6.6:: How can I change the font type of the tick labels on
+ an axis?
+* Question 6.7:: How can I prevent axes tick labels from rendering on
+ top of each other?
+* Question 6.8:: How do I make the plot region of a graph, ignoring
+ labels and legends, have a fixed size?
+* Question 6.9:: How can I plot a function f(x) within [0,1]x[0,2]
+ without explicitly calculating the x values for which
+ f(x) hits the boundary?
+* Question 6.10:: Is it possible to define customized palettes?
+* Question 6.11:: Is there an easy way to graph factorial functions
+ nicely?
+* Question 6.12:: How do I indicate that a certain length should be
+ exactly the size I prescribe with no rescaling, within
+ a picture which has its own size?
+* Question 6.13:: How can I make the y axis display base-2 logarithmic
+ values?
+* Question 6.14:: How can I align the x axes of two graphs on the same
+ figure?
+* Question 6.15:: How can I change the direction of the y-axis, such
+ that negatives values are on the upper y-axis?
+* Question 6.16:: How can I fill a path with a function that defines the
+ color of each location?
+* Question 6.17:: Is there a way to draw a function that is not
+ explicitly given, such as (y - 2)^2 = x - 1 ?
+* Question 6.18:: Is it possible to reverse or stretch an axis?
+* Question 6.19:: Why can't I use the UnFill option to draw graphs with
+ empty markers?
+* Question 6.20:: How can I force several images to use the same palette
+ range (e.g. the entire 0-255 grayscale range)?
+
+
+
+File: asy-faq.info, Node: Question 6.1, Next: Question 6.2, Previous: Question 5.4, Up: Section 6
+
+Question 6.1. How can I draw x axis ticks on the right side, with the tick labels on the left side (relative to the axis path)?
+
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis("$x$",RightTicks(Label(align=left)));
+yaxis("$y$",RightTicks);
+
+File: asy-faq.info, Node: Question 6.2, Next: Question 6.3, Previous: Question 6.1, Up: Section 6
+
+Question 6.2. How can I reposition the x axis label to three-quarters along the axis length?
+
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis(Label("$x$",0.75),LeftTicks);
+yaxis("$y$",RightTicks);
+
+File: asy-faq.info, Node: Question 6.3, Next: Question 6.4, Previous: Question 6.2, Up: Section 6
+
+Question 6.3. How can I move the x axis label down 10bp?
+
+import graph;
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis(shift(0,-10)*"$x$",LeftTicks);
+yaxis("$y$",RightTicks);
+
+File: asy-faq.info, Node: Question 6.4, Next: Question 6.5, Previous: Question 6.3, Up: Section 6
+
+Question 6.4. Can I use different pens for the axis, the axis label, and the tick labels?
+
+Yes:
+
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis(Label("$x$",MidPoint,red),Bottom,blue,LeftTicks(green));
+yaxis("$y$",Left,RightTicks);
+
+File: asy-faq.info, Node: Question 6.5, Next: Question 6.6, Previous: Question 6.4, Up: Section 6
+
+Question 6.5. How can I change the font type of the axes label?
+
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis("x",Bottom,Courier("m","n"),LeftTicks);
+yaxis("$y$",Left,RightTicks);
+
+File: asy-faq.info, Node: Question 6.6, Next: Question 6.7, Previous: Question 6.5, Up: Section 6
+
+Question 6.6. How can I change the font type of the tick labels on an axis?
+
+Tick labels are by default typeset in (TeX) math mode, so to use other
+fonts you need to override the default tick format:
+
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis("$x$",Bottom,LeftTicks("%.4g",Courier("m","n")+fontsize(12)));
+yaxis("$y$",Left,RightTicks);
+
+File: asy-faq.info, Node: Question 6.7, Next: Question 6.8, Previous: Question 6.6, Up: Section 6
+
+Question 6.7. How can I prevent axes tick labels from rendering on top of each other?
+
+Either:
+
+(i) give LeftTicks/RightTicks/Ticks the arguments beginlabel=false and/or
+endlabel=false;
+
+(ii) explicitly remove specific ticks and their labels (drawing them
+manually; see
+http://www.github.com/vectorgraphics/asymptote/base/graph.asy for the
+definition of NoZero):
+
+import graph;
+
+size(10cm);
+
+real f(real x) {return x^2;}
+
+draw(graph(f,-2,2));
+
+xaxis(Ticks(NoZero));
+yaxis(Ticks(NoZero));
+
+label("$0$",(0,0),SW);
+(iii) explicitly remove specific tick labels and draw them manually (see
+http://www.github.com/vectorgraphics/asymptote/base/graph.asy for the
+definition of NoZeroFormat):
+
+import graph;
+
+size(10cm);
+
+real f(real x) {return x^2;}
+
+draw(graph(f,-2,2));
+
+xaxis(Ticks(NoZeroFormat));
+yaxis(Ticks(NoZeroFormat));
+
+label("$0$",(0,0),SW);
+(iv) use the xasy GUI to move overlapping labels;
+
+(v) change the Label argument of LeftTicks, RightTicks, or Ticks to:
+
+Label(currentpen+overwrite(Move))
+Solution (v) will move labels that might otherwise overwrite a previous
+label. Other possible overwrite arguments are Allow (allows overlapping
+labels; the default), Suppress (an overlapping label will not be written
+at all), SuppressQuiet, and MoveQuiet. The last two achieve the same
+result as the non-quiet types, but will not notify you which labels are
+overlapping. See: http://asymptote.sourceforge.net/doc/Pens.html.
+
+In the case of a user-specified tick array, you can change which labels
+get suppressed/moved by changing the order of array entries.
+
+
+File: asy-faq.info, Node: Question 6.8, Next: Question 6.9, Previous: Question 6.7, Up: Section 6
+
+Question 6.8. How do I make the plot region of a graph, ignoring labels and legends, have a fixed size?
+
+Either:
+
+i) Specify an explicit unitsize, which overrides any call to size:
+unitsize(x=1cm,y=2cm);
+ii) Explicitly tell Asymptote to map the plot region to a specific size:
+import graph;
+real[] x={0,1,2,3};
+real[] y=x^2;
+draw(graph(x,y),red);
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+size(5cm,5cm,point(SW),point(NE));
+
+label("$f_\mathrm{T}$",point(N),2N);
+iii) Specify the points in user coordinates that should correspond to a
+given picture size:
+
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+fixedscaling((-1.5,-0.5),(1.5,3.5));
+In this example, the user coordinate (-1.5,-0.5) will end up being the
+lower left corner of the figure and (1.5,3.5) will be the upper right
+corner. You can use this option to ensure multiple figures have the same
+scaling and same resulting figure size (just ensure the two coordinates
+given to fixedscaling() leaves room for any labels).
+
+See also http://asymptote.sourceforge.net/doc/Frames-and-pictures.html.
+
+
+File: asy-faq.info, Node: Question 6.9, Next: Question 6.10, Previous: Question 6.8, Up: Section 6
+
+Question 6.9. How can I plot a function f(x) within [0,1]x[0,2] without explicitly calculating the x values for which f(x) hits the boundary?
+
+Call limits with the Crop option before drawing the graph:
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+limits((0,0),(1,2),Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+See also http://asymptote.sourceforge.net/doc/graph.html.
+
+
+File: asy-faq.info, Node: Question 6.10, Next: Question 6.11, Previous: Question 6.9, Up: Section 6
+
+Question 6.10. Is it possible to define customized palettes?
+
+Yes, you may generate your own pen[] array. For example:
+
+int NColors=32768;
+pen[] MyPalette=new pen[NColors];
+real step=1/(NColors-1.0);
+// Start at black: rgb(0,0,0)
+// End at yellow: rgb(1,1,0)
+for(int i=0; i < NColors; ++i) {
+ real rgval=i*step;
+ MyPalette[i]=rgb(rgval,rgval,0.0);
+}
+
+File: asy-faq.info, Node: Question 6.11, Next: Question 6.12, Previous: Question 6.10, Up: Section 6
+
+Question 6.11. Is there an easy way to graph factorial functions nicely?
+
+The example below shows a continuous function and two methods for placing
+markers at integer values of x:
+
+import graph;
+
+size(200,200,IgnoreAspect);
+
+real factorial(real t) {return gamma(t+1);}
+
+scale(Linear,Log);
+
+// Graph the factorial function.
+draw(graph(factorial,0,10));
+
+// Method 1: Draw nodes, but hide line
+pair F(int t) {return (t,factorial(t));}
+// Graph of factorial function from 0 to 10
+pair[] z=sequence(F,11);
+draw(graph(z),invisible,marker(scale(0.8mm)*unitcircle,blue,Fill));
+
+// Method 2: Nongraphing routines require explicit scaling:
+pair dotloc(int t) {return Scale(F(t));}
+pair[] dotlocs=sequence(dotloc,11);
+dot(dotlocs);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+File: asy-faq.info, Node: Question 6.12, Next: Question 6.13, Previous: Question 6.11, Up: Section 6
+
+Question 6.12. How do I indicate that a certain length should be exactly the size I prescribe with no rescaling, within a picture which has its own size?
+
+Here's an easy way to do this.
+
+size(12cm,0);
+
+void distance(picture pic=currentpicture, pair A, pair B, Label L="", real n=0,
+ pen p=currentpen)
+{
+ real d=3mm;
+ path g=A--B;
+ transform T=shift(-n*d*unit(B-A)*I);
+ pic.add(new void(frame f, transform t) {
+ picture opic;
+ path G=T*t*g;
+ draw(opic,Label(L,Center,UnFill(1)),G,p,Arrows(NoFill),Bars,PenMargins);
+ add(f,opic.fit());
+ });
+ pic.addBox(min(g),max(g),T*min(p),T*max(p));
+}
+
+pair A=(0,0), B=(3,3);
+
+dot(A);
+dot(B);
+
+distance(A,B,"$\ell$",1);
+
+File: asy-faq.info, Node: Question 6.13, Next: Question 6.14, Previous: Question 6.12, Up: Section 6
+
+Question 6.13. How can I make the y axis display base-2 logarithmic values?
+
+See the example http://asymptote.sourceforge.net/gallery/2D
+graphs/log2graph.asy.
+
+
+File: asy-faq.info, Node: Question 6.14, Next: Question 6.15, Previous: Question 6.13, Up: Section 6
+
+Question 6.14. How can I align the x axes of two graphs on the same figure?
+
+An easy way to do this, if the axes to be aligned have the same scaling
+and size, is illustrated in the example
+http://asymptote.sourceforge.net/gallery/2D graphs/alignedaxis.asy.
+
+Here is a more general solution to the problem of aligning two arbitrary
+axes. One fits the second picture to a frame based on the horizontal
+scaling for the first picture:
+
+import graph;
+
+real width=15cm;
+real aspect=0.3;
+
+picture pic1,pic2;
+
+size(pic1,width,aspect*width,IgnoreAspect);
+size(pic2,width,aspect*width,IgnoreAspect);
+
+scale(pic1,false);
+scale(pic2,false);
+
+real xmin1=6;
+real xmax1=9;
+real xmin2=8;
+real xmax2=16;
+
+real a1=1;
+real a2=0.001;
+
+real f1(real x) {return a1*sin(x/2*pi);}
+real f2(real x) {return a2*sin(x/4*pi);}
+
+draw(pic1,graph(pic1,f1,xmin1,xmax1));
+draw(pic2,graph(pic2,f2,xmin2,xmax2));
+
+xaxis(pic1,Bottom,LeftTicks());
+yaxis(pic1,"$f_1(x)$",Left,RightTicks);
+
+xaxis(pic2,"$x$",Bottom,LeftTicks(Step=4));
+yaxis(pic2,"$f_2(x)$",Left,RightTicks);
+
+yequals(pic1,0,Dotted);
+yequals(pic2,0,Dotted);
+
+pair min1=point(pic1,SW);
+pair max1=point(pic1,NE);
+
+pair min2=point(pic2,SW);
+pair max2=point(pic2,NE);
+
+real scale=(max1.x-min1.x)/(max2.x-min2.x);
+real shift=min1.x/scale-min2.x;
+
+transform t1=pic1.calculateTransform();
+transform t2=pic2.calculateTransform();
+transform T=xscale(scale*t1.xx)*yscale(t2.yy);
+
+add(pic1.fit());
+real height=truepoint(N,user=false).y-truepoint(S,user=false).y;
+add(shift(0,-height)*(shift(shift)*pic2).fit(T));
+
+File: asy-faq.info, Node: Question 6.15, Next: Question 6.16, Previous: Question 6.14, Up: Section 6
+
+Question 6.15. How can I change the direction of the y-axis, such that negatives values are on the upper y-axis?
+
+Here is a simple example (see also the example
+http://asymptote.sourceforge.net/gallery/2D graphs/diatom.asy or the
+discussion of Linear(-1) in the documentation):
+
+import graph;
+size(250,200,IgnoreAspect);
+
+scale(Linear,Linear(-1));
+
+draw(graph(log,0.1,10),red);
+
+xaxis("$x$",LeftTicks);
+yaxis("$y$",RightTicks);
+
+File: asy-faq.info, Node: Question 6.16, Next: Question 6.17, Previous: Question 6.15, Up: Section 6
+
+Question 6.16. How can I fill a path with a function that defines the color of each location?
+
+Use functionshade with a PDF tex engine, as illustrated by the example
+{functionshading.asy}.
+
+If you want to produce PostScript output, an approximate solution for now
+would be to superimpose a fine grid and specify colors to latticeshade
+that depend on position as a single pen[][] lattice. Alternatively, it may
+be more efficient to use tensorshade}.
+
+
+File: asy-faq.info, Node: Question 6.17, Next: Question 6.18, Previous: Question 6.16, Up: Section 6
+
+Question 6.17. Is there a way to draw a function that is not explicitly given, such as (y - 2)^2 = x - 1 ?
+
+Yes, use the parametric form
+
+y=t
+x=(t-2)^2+1
+See the example http://asymptote.sourceforge.net/gallery/2D
+graphs/parametricgraph.asy.
+
+
+File: asy-faq.info, Node: Question 6.18, Next: Question 6.19, Previous: Question 6.17, Up: Section 6
+
+Question 6.18. Is it possible to reverse or stretch an axis?
+
+The real scaling argument to Linear is used to stretch (or reverse) the
+axis. To see the effect of axis stretching, be sure not to specify
+IgnoreAspect in the picture size command.
+
+A secondary axis has the same length as the primary axis, so stretching
+cannot have any effect. But one can still reverse the axis, with
+Linear(-1).
+
+
+File: asy-faq.info, Node: Question 6.19, Next: Question 6.20, Previous: Question 6.18, Up: Section 6
+
+Question 6.19. Why can't I use the UnFill option to draw graphs with empty markers?
+
+UnFill won't work here because it only affects the local frame the markers
+are initially drawn on, before being added to currentpicture. Here is a
+way of achieving the desired effect (assuming a white background):
+
+import graph;
+size(10cm,0);
+pair[] z={(0,0),(0.5,0.5),(1,1)};
+path g=graph(z);
+
+draw(shift(0,.5)*g,marker(scale(5)*unitcircle,FillDraw(white)));
+
+xaxis(BottomTop,LeftTicks);
+yaxis(LeftRight,RightTicks);
+
+File: asy-faq.info, Node: Question 6.20, Next: Question 7.1, Previous: Question 6.19, Up: Section 6
+
+Question 6.20. How can I force several images to use the same palette range (e.g. the entire 0-255 grayscale range)?
+
+The palette color space corresponds to a range of values specified by the
+argument range, which can be Full, Automatic or an explicit range
+Range(pair min, pair max). Here Full} specifies a range varying from the
+minimum to maximum values of the function over the sampling interval,
+while Automatic selects "nice" limits.
+
+
+File: asy-faq.info, Node: Section 7, Next: Section 8, Previous: Section 6, Up: Top
+
+Questions about programming
+
+* Menu:
+* Question 7.1:: Is Asymptote an interpreter or a compiler?
+* Question 7.2:: What is the difference between a frame and a picture?
+* Question 7.3:: What is the difference between a path and a guide?
+* Question 7.4:: What is a convenient way to declare and initialize an
+ array of pictures?
+* Question 7.5:: Is there a way to define functions that act on arrays
+ in general (i.e. work for arrays of any type)?
+* Question 7.6:: Is there any way to declare structures ahead of their
+ definition, e.g. where struct A performs some
+ operation on struct B, but B contains an A member?
+* Question 7.7:: Where are static variables in for loops allocated?
+* Question 7.8:: Is there a debugger for asy?
+* Question 7.9:: Do you accept patches for Asymptote?
+
+
+
+File: asy-faq.info, Node: Question 7.1, Next: Question 7.2, Previous: Question 6.20, Up: Section 7
+
+Question 7.1. Is Asymptote an interpreter or a compiler?
+
+Asymptote compiles Asymptote commands into its own virtual machine code.
+It then runs this pseudocode on a virtual machine to produce PostScript
+code.
+
+
+File: asy-faq.info, Node: Question 7.2, Next: Question 7.3, Previous: Question 7.1, Up: Section 7
+
+Question 7.2. What is the difference between a frame and a picture?
+
+Frames are canvases for drawing in PostScript coordinates. While working
+with frames directly is occasionally necessary for constructing deferred
+drawing routines, pictures are usually more convenient to work with. See
+*Note Question 8.8:: `In MetaPost, it is possible to have a drawing remain
+the same size in different pictures by defining a unit u and explicitly
+multiply all the coordinates by u. Is there a better way to do this in
+Asymptote?'.
+
+
+File: asy-faq.info, Node: Question 7.3, Next: Question 7.4, Previous: Question 7.2, Up: Section 7
+
+Question 7.3. What is the difference between a path and a guide?
+
+A path is a cubic spline with fixed endpoint conditions.
+
+A guide is an unresolved cubic spline (list of cubic-spline nodes and
+control points). A guide is like a path except that the computation of the
+cubic spline is deferred until drawing time (when it is resolved into a
+path); this allows two guides with free endpoint conditions to be joined
+together smoothly.
+
+
+File: asy-faq.info, Node: Question 7.4, Next: Question 7.5, Previous: Question 7.3, Up: Section 7
+
+Question 7.4. What is a convenient way to declare and initialize an array of pictures?
+
+You could write yourself a routine such as:
+picture[] picture(int n) {
+ picture[] pic;
+ for(int i=0; i < n; ++i) {
+ pic[i]=new picture;
+ size(pic[i],19cm,0);
+ }
+ return pic;
+}
+
+picture[] pic=picture(6);
+
+File: asy-faq.info, Node: Question 7.5, Next: Question 7.6, Previous: Question 7.4, Up: Section 7
+
+Question 7.5. Is there a way to define functions that act on arrays in general (i.e. work for arrays of any type)?
+
+Generic types aren't yet implemented.
+
+But for now you can at least say
+typedef string T;
+include F;
+
+typedef real T;
+include F;
+where F.asy contains some type-dependent code like
+T[] operator $(T A, T B) {return new T[] {A,B};}
+
+File: asy-faq.info, Node: Question 7.6, Next: Question 7.7, Previous: Question 7.5, Up: Section 7
+
+Question 7.6. Is there any way to declare structures ahead of their definition, e.g. where struct A performs some operation on struct B, but B contains an A member?
+
+Asymptote does not support forward declaration of types. You can, however,
+nest structures, so that both types are visible for parts of the bodies of
+both structure definitions. For example:
+
+struct B {
+ typedef void someroutine(B b);
+
+ static struct A {
+ someroutine routine;
+ void operator init(someroutine routine) {
+ this.routine=routine;
+ }
+ }
+
+ string test="Testing";
+}
+
+typedef B.A A;
+
+A a=B.A(new void(B b){write(b.test);});
+
+B b;
+a.routine(b);
+
+File: asy-faq.info, Node: Question 7.7, Next: Question 7.8, Previous: Question 7.6, Up: Section 7
+
+Question 7.7. Where are static variables in for loops allocated?
+
+In the example
+
+void f() {
+ for(int i=0; i < 3; ++i) {
+ static int n;
+ ++n;
+ write(n);
+ }
+}
+
+f(); // Writes 1, 2, 3
+the static qualifier means that n is allocated not just outside of the for
+loop, but also outside the function. This is clear if you call f multiple
+times; there is still only one instance of n.
+
+The "level" of a variable (where it is allocated) has nothing to do with
+the "scope" of a variable (how long it can be referred to by name). The
+curly braces enclosing a block affect only a variable's scope, not its
+level.
+
+Static modifiers are meaningless at the top level; they generate a warning
+and are simply ignored:
+
+for(int i=0; i < 3; ++i) {
+ static int n;
+ ++n;
+ write(n);
+}
+// Writes warning about top-level static modifier and then 1, 1, 1
+Since version 1.22, non-static variables allocated in a loop body are
+allocated anew every iteration. This is only noticable in obscure cases
+where a variable in a loop is accessed in the closure of a function
+defined in the loop:
+
+int f();
+
+for(int i=0; i < 10; ++i) {
+ int j=10*i;
+ if(i == 5)
+ f=new int() {return j;};
+}
+
+write(f()); // Writes 50
+Variables in the body of a loop last as long as that iteration of the
+loop, unless they are kept alive by a function closure as in the example
+above. In a function body, variables will last at least as long as the
+function call, though because of closures and garbage collection, they may
+last longer than that. If defined at the top level of a file or at the
+interactive prompt, they will last at least until the end of the file or
+prompt's run.
+
+
+File: asy-faq.info, Node: Question 7.8, Next: Question 7.9, Previous: Question 7.7, Up: Section 7
+
+Question 7.8. Is there a debugger for asy?
+
+Yes, Asymptote includes a line-based debugger:
+
+http://asymptote.sourceforge.net/doc/Debugger.html
+
+
+File: asy-faq.info, Node: Question 7.9, Next: Question 8.1, Previous: Question 7.8, Up: Section 7
+
+Question 7.9. Do you accept patches for Asymptote?
+
+Yes, in fact we would prefer that users submit patches for customized
+features (to http://sourceforge.net/tracker/?atid=685685&group_id=120000)
+instead of relying on us to do all of the coding. Development will proceed
+faster that way.
+
+
+File: asy-faq.info, Node: Section 8, Next: Section 9, Previous: Section 7, Up: Top
+
+Questions about differences between Asymptote and MetaPost
+
+* Menu:
+* Question 8.1:: What is the equivalent of the MetaPost c[a,b]
+ interpolation operator?
+* Question 8.2:: How does picture scaling differ in Asymptote and
+ MetaPost?
+* Question 8.3:: How can I avoid automatic scaling of a picture?
+* Question 8.4:: What is the equivalent of MetaPost ... command?
+* Question 8.5:: What is the equivalent of the MetaPost pickup command?
+* Question 8.6:: What is the equivalent of the MetaPost whatever
+ command?
+* Question 8.7:: What is the equivalent for the MetaPost command for
+ lray - horiz*v - verti*u = whatever*(LightSource - R),
+ a system of three linear equations for three unknowns:
+ horiz, verti, whatever?
+* Question 8.8:: In MetaPost, it is possible to have a drawing remain
+ the same size in different pictures by defining a unit
+ u and explicitly multiply all the coordinates by u. Is
+ there a better way to do this in Asymptote?
+* Question 8.9:: In MetaPost, one could produce tiling pictures by
+ generating a picture, and then clipping the picture to
+ a rectangle of fixed dimensions around the center of
+ the picture. How is that done in Asymptote?
+
+
+
+File: asy-faq.info, Node: Question 8.1, Next: Question 8.2, Previous: Question 7.9, Up: Section 8
+
+Question 8.1. What is the equivalent of the MetaPost c[a,b] interpolation operator?
+
+interp(a,b,c);
+
+File: asy-faq.info, Node: Question 8.2, Next: Question 8.3, Previous: Question 8.1, Up: Section 8
+
+Question 8.2. How does picture scaling differ in Asymptote and MetaPost?
+
+Asymptote includes an optional facility to do automatic scaling of
+pictures to achieve a given overall picture size, whereas Metapost only
+supports manual scaling. Asymptote defers drawing of objects drawn to
+pictures and distinguishes between true-size objects and objects that
+should scale with the picture size. The resulting linear programming
+problem is solved via the Simplex method.
+
+See the http://asymptote.sourceforge.net/gallery/dimension.asy example for
+an example of how deferred drawing is used to accomodate both user and
+true-size (PostScript) coordinates.
+
+
+File: asy-faq.info, Node: Question 8.3, Next: Question 8.4, Previous: Question 8.2, Up: Section 8
+
+Question 8.3. How can I avoid automatic scaling of a picture?
+
+If you really like Metapost-style manual (hard-wired) scaling either:
+
+(i) use the default size(0,0) for the entire picture and do all of the
+scaling by hand, just like in MetaPost;
+
+(ii) draw to a separate picture pic and add(pic.fit());
+
+(iii) use frames.
+
+
+File: asy-faq.info, Node: Question 8.4, Next: Question 8.5, Previous: Question 8.3, Up: Section 8
+
+Question 8.4. What is the equivalent of MetaPost ... command?
+
+The connector :: is a macro for tension atleast 1:
+
+size(100);
+pair z0=(0,0);
+pair z1=(1,0.25);
+pair z2=(2,0);
+draw(z0{up}::z1{right}::z2{down});
+
+File: asy-faq.info, Node: Question 8.5, Next: Question 8.6, Previous: Question 8.4, Up: Section 8
+
+Question 8.5. What is the equivalent of the MetaPost pickup command?
+
+Just say, for example:
+
+currentpen=red;
+
+File: asy-faq.info, Node: Question 8.6, Next: Question 8.7, Previous: Question 8.5, Up: Section 8
+
+Question 8.6. What is the equivalent of the MetaPost whatever command?
+
+Asymptote does not implicitly solve linear equations and therefore does
+not have the notion of a whatever unknown. Such a facility could certainly
+be added (perhaps using the notation ?= since = means assignment).
+However, the most common uses of whatever in MetaPost are covered by
+functions like extension in math.asy:
+pair extension(pair P, pair Q, pair p, pair q);
+this returns the intersection point of the extensions of the line segments
+PQ and pq. We find using routines like extension more explicit and less
+confusing to new users. But we could be persuaded to add something similar
+if someone can justify the need. In the meantime, one can always use the
+explicit built-in linear solver solve (see
+http://asymptote.sourceforge.net/doc/solve.html), which uses LU
+decomposition.
+
+
+File: asy-faq.info, Node: Question 8.7, Next: Question 8.8, Previous: Question 8.6, Up: Section 8
+
+Question 8.7. What is the equivalent for the MetaPost command for lray - horiz*v - verti*u = whatever*(LightSource - R), a system of three linear equations for three unknowns: horiz, verti, whatever?
+
+Since horiz*v+verti*u spans a plane, you could use
+real intersect(vector P, vector Q, vector n, vector Z);
+to find the intersection time for the line lray-whatever*(LightSource -
+R) and then extract the three desired values from there. (You'll still
+need to use the built-in explicit linear solver to solve a 2x2 system to
+get horiz and verti.)
+
+
+File: asy-faq.info, Node: Question 8.8, Next: Question 8.9, Previous: Question 8.7, Up: Section 8
+
+Question 8.8. In MetaPost, it is possible to have a drawing remain the same size in different pictures by defining a unit u and explicitly multiply all the coordinates by u. Is there a better way to do this in Asymptote?
+
+Yes, Asymptote has a better way: you definitely don't want to manually
+scale all of your coordinates. To make the user coordinates represent
+multiples of exactly 1cm:
+
+unitsize(1cm);
+draw(unitsquare);
+One can also specify different x and y unit sizes:
+
+unitsize(x=1cm,y=2cm);
+draw(unitsquare);
+Another way is to draw your fixed size object to a frame and add it to
+currentpicture like this:
+
+path p=(0,0)--(1,0);
+frame object;
+draw(object,scale(100)*p);
+
+add(object);
+add(object,(0,-10));
+To understand the difference between frames and pictures, try this:
+
+size(300,300);
+
+path p=(0,0)--(1,0);
+picture object;
+draw(object,scale(100)*p);
+
+add(object);
+add(object,(0,-10)); // Adds truesize object to currentpicture
+
+File: asy-faq.info, Node: Question 8.9, Next: Question 9.1, Previous: Question 8.8, Up: Section 8
+
+Question 8.9. In MetaPost, one could produce tiling pictures by generating a picture, and then clipping the picture to a rectangle of fixed dimensions around the center of the picture. How is that done in Asymptote?
+
+If you are using currentpicture the way one would in MetaPost (drawing in
+raw PostScript coordinates), you can simply do something like:
+
+fill((0,0)--(100,100)--(200,0)--cycle);
+
+pair center(picture pic=currentpicture) {return 0.5*(pic.min()+pic.max());}
+
+real height=100;
+real width=100;
+pair delta=0.5(width,height);
+pair c=center();
+clip(box(c-delta,c+delta));
+However, drawing in PostScript coordinates is often inconvenient. Here's
+the Asymptote way of doing the same thing, using deferred drawing:
+
+size(200,100);
+fill((0,0)--(1,1)--(2,0)--cycle);
+
+void clip(picture pic=currentpicture, real width, real height)
+{
+ pic.clip(new void (frame f, transform) {
+ pair center=0.5(min(f)+max(f));
+ pair delta=0.5(width,height);
+ clip(f,box(center-delta,center+delta));
+ });
+}
+
+clip(100,100);
+See also the discussion of tilings in the documentation:
+http://asymptote.sourceforge.net/doc/Pens.html.
+
+
+File: asy-faq.info, Node: Section 9, Previous: Section 8, Up: Top
+
+Questions about output
+
+* Menu:
+* Question 9.1:: How can I disable automatic invocation of the PS
+ viewer after an asy file is done processing?
+* Question 9.2:: How do I output jpeg images?
+* Question 9.3:: Can I embed bitmaps (photos) into my drawings and
+ position and scale them?
+* Question 9.4:: Does Asymptote support direct PDF output?
+* Question 9.5:: How to I produce large pictures of high quality in
+ raster format (e.g. png, giff etc).
+* Question 9.6:: Is it possible to produce multi-page documents with
+ asymptote?
+
+
+
+File: asy-faq.info, Node: Question 9.1, Next: Question 9.2, Previous: Question 8.9, Up: Section 9
+
+Question 9.1. How can I disable automatic invocation of the PS viewer after an asy file is done processing?
+
+It's actually not on by default, unless you happen to be using Microsoft
+Windows (because that is what most Microsoft Windows users expect).
+Microsoft Windows users can turn this feature off with the command-line
+option -noV or by putting
+
+import settings;
+interactiveView=false;
+batchView=false;
+in their config.asy file. See
+http://asymptote.sourceforge.net/doc/Options.html.
+
+
+File: asy-faq.info, Node: Question 9.2, Next: Question 9.3, Previous: Question 9.1, Up: Section 9
+
+Question 9.2. How do I output jpeg images?
+
+If you have the ImageMagick convert program installed, simply type
+
+asy -f jpg test.asy
+
+File: asy-faq.info, Node: Question 9.3, Next: Question 9.4, Previous: Question 9.2, Up: Section 9
+
+Question 9.3. Can I embed bitmaps (photos) into my drawings and position and scale them?
+
+Convert them to eps format and use the graphic(string) function just like
+a Label:
+
+label(graphic("file"),(0,0));
+See the example http://asymptote.sourceforge.net/gallery/orthocenter.asy
+and http://asymptote.sourceforge.net/doc/label.html.
+
+
+File: asy-faq.info, Node: Question 9.4, Next: Question 9.5, Previous: Question 9.3, Up: Section 9
+
+Question 9.4. Does Asymptote support direct PDF output?
+
+Yes, PDF output can be produced by the -f pdf option or -tex pdflatex
+option. This supports transparency, annotations, embedded movies, and
+U3D/PRC content.
+
+
+File: asy-faq.info, Node: Question 9.5, Next: Question 9.6, Previous: Question 9.4, Up: Section 9
+
+Question 9.5. How to I produce large pictures of high quality in raster format (e.g. png, giff etc).
+
+Try using some of the options to convert, mainly -geometry and -density.
+For example:
+convert -geometry 1000x3000 example.eps example.png
+You can also change the default resolution of the image with:
+convert -geometry 1000x3000 -density 300 -units PixelsPerInch example.eps example.png
+This does not change the number of pixels in the image, but just gives a
+hint as to how large each pixel should be displayed.
+
+If you include the -density option without the -geometry option, convert
+will keep the image size constant (so a 4cm x 3cm eps figure will
+generate a 4cm x 3cm png image).
+
+
+File: asy-faq.info, Node: Question 9.6, Previous: Question 9.5, Up: Section 9
+
+Question 9.6. Is it possible to produce multi-page documents with asymptote?
+
+Yes, simply call the newpage() function. This is used by the slide.asy
+package to produce high-quality slide presentations (easier to use than
+Prosper).
+
diff --git a/graphics/asymptote/doc/FAQ/bfnnconv.pl b/graphics/asymptote/doc/FAQ/bfnnconv.pl
new file mode 100755
index 0000000000..0a705e2c68
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/bfnnconv.pl
@@ -0,0 +1,298 @@
+#!/usr/bin/perl --
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+@outputs=('ascii','info','html');
+
+while ($ARGV[0] =~ m/^\-/) {
+ $_= shift(@ARGV);
+ if (m/^-only/) {
+ @outputs= (shift(@ARGV));
+ } else {
+ warn "unknown option `$_' ignored";
+ }
+}
+
+$prefix= $ARGV[0];
+$prefix= 'stdin' unless length($prefix);
+$prefix =~ s/\.bfnn$//;
+
+if (open(O,"$prefix.xrefdb")) {
+ @xrefdb= <O>;
+ close(O);
+} else {
+ warn "no $prefix.xrefdb ($!)";
+}
+
+$section= -1;
+for $thisxr (@xrefdb) {
+ $_= $thisxr;
+ chop;
+ if (m/^Q (\w+) ((\d+)\.(\d+)) (.*)$/) {
+ $qrefn{$1}= $2;
+ $qreft{$1}= $5;
+ $qn2ref{$3,$4}= $1;
+ $maxsection= $3;
+ $maxquestion[$3]= $4;
+ } elsif (m/^S (\d+) /) {
+ $maxsection= $1;
+ $sn2title{$1}=$';
+ }
+}
+
+open(U,">$prefix.xrefdb-new");
+
+for $x (@outputs) { require("./m-$x.pl"); }
+
+&call('init');
+
+while (<>) {
+ chop;
+ next if m/^\\comment\b/;
+ if (!m/\S/) {
+ &call('endpara');
+ next;
+ }
+ if (s/^\\section +//) {
+ $line= $_;
+ $section++; $question=0;
+ print U "S $section $line\n";
+ $|=1; print "S$section",' 'x10,"\r"; $|=0;
+ &call('endpara');
+ &call('startmajorheading',"$section",
+ "Section $section",
+ $section<$maxsection ? "Section ".($section+1) : '',
+ $section>1 ? 'Section '.($section-1) : 'Top');
+ &text($line);
+ &call('endmajorheading');
+ if ($section) {
+ &call('endpara');
+ &call('startindex');
+ for $thisxr (@xrefdb) {
+ $_= $thisxr;
+ chop;
+ if (m/^Q (\w+) (\d+)\.(\d+) (.*)$/) {
+ $ref= $1; $num1= $2; $num2= $3; $text= $4;
+ next unless $num1 == $section;
+ &call('startindexitem',$ref,"Q$num1.$num2","Question $num1.$num2");
+ &text($text);
+ &call('endindexitem');
+ }
+ }
+ &call('endindex');
+ }
+ } elsif (s/^\\question \d{2}[a-z]{3}((:\w+)?) +//) {
+ $line= $_;
+ $question++;
+ $qrefstring= $1;
+ $qrefstring= "q_${section}_$question" unless $qrefstring =~ s/^://;
+ print U "Q $qrefstring $section.$question $line\n";
+ $|=1; print "Q$section.$question",' 'x10,"\r"; $|=0;
+ &call('endpara');
+ &call('startminorheading',$qrefstring,
+ "Question $section.$question",
+ $question < $maxquestion[$section] ? "Question $section.".($question+1) :
+ $section < $maxsection ? "Question ".($section+1).".1" : '',
+ $question > 1 ? "Question $section.".($question-1) :
+ $section > 1 ? "Question ".($section-1).'.'.($maxquestion[$section-1]) :
+ 'Top',
+ "Section $section");
+ &text("Question $section.$question. $line");
+ &call('endminorheading');
+ } elsif (s/^\\only +//) {
+ @saveoutputs= @outputs;
+ @outputs=();
+ for $x (split(/\s+/,$_)) {
+ push(@outputs,$x) if grep($x eq $_, @saveoutputs);
+ }
+ } elsif (s/^\\endonly$//) {
+ @outputs= @saveoutputs;
+ } elsif (s/^\\copyto +//) {
+ $fh= $';
+ while(<>) {
+ last if m/^\\endcopy$/;
+ while (s/^([^\`]*)\`//) {
+ print $fh $1;
+ m/([^\\])\`/ || warn "`$_'";
+ $_= $';
+ $cmd= $`.$1;
+ $it= `$cmd`; chop $it;
+ print $fh $it;
+ }
+ print $fh $_;
+ }
+ } elsif (m/\\index$/) {
+ &call('startindex');
+ for $thisxr (@xrefdb) {
+ $_= $thisxr;
+ chop;
+ if (m/^Q (\w+) (\d+\.\d+) (.*)$/) {
+ $ref= $1; $num= $2; $text= $3;
+ &call('startindexitem',$ref,"Q$num","Question $num");
+ &text($text);
+ &call('endindexitem');
+ } elsif (m/^S (\d+) (.*)$/) {
+ $num= $1; $text= $2;
+ next unless $num;
+ &call('startindexmainitem',"s_$num",
+ "Section $num.","Section $num");
+ &text($text);
+ &call('endindexitem');
+ } else {
+ warn $_;
+ }
+ }
+ &call('endindex');
+ } elsif (m/^\\call-(\w+) +(\w+)\s*(.*)$/) {
+ $fn= $1.'_'.$2;
+ eval { &$fn($3); };
+ warn $@ if length($@);
+ } elsif (m/^\\call +(\w+)\s*(.*)$/) {
+ eval { &call($1,$2); };
+ warn $@ if length($@);
+ } elsif (s/^\\set +(\w+)\s*//) {
+ $svalue= $'; $svari= $1;
+ eval("\$user_$svari=\$svalue"); $@ && warn "setting $svalue failed: $@\n";
+ } elsif (m/^\\verbatim$/) {
+ &call('startverbatim');
+ while (<>) {
+ chop;
+ last if m/^\\endverbatim$/;
+ &call('verbatim',$_);
+ }
+ &call('endverbatim');
+ } else {
+ s/\.$/\. /;
+ &text($_." ");
+ }
+}
+
+print ' 'x25,"\r";
+&call('finish');
+rename("$prefix.xrefdb-new","$prefix.xrefdb") || warn "rename xrefdb: $!";
+exit 0;
+
+
+sub text {
+ local($in,$rhs,$word,$refn,$reft,$fn,$style);
+ $in= "$holdover$_[0]";
+ $holdover= '';
+ while ($in =~ m/\\/) {
+#print STDERR ">$`##$'\n";
+ $rhs=$';
+ &call('text',$`);
+ $_= $rhs;
+ if (m/^\w+ $/) {
+ $holdover= "\\$&";
+ $in= '';
+ } elsif (s/^fn\s+([^\s\\]*\w)//) {
+ $in= $_;
+ $word= $1;
+ &call('courier');
+ &call('text',$word);
+ &call('endcourier');
+ } elsif (s/^tab\s+(\d+)\s+//) {
+ $in= $_; &call('tab',$1);
+ } elsif (s/^nl\s+//) {
+ $in= $_; &call('newline');
+ } elsif (s/^qref\s+(\w+)//) {
+ $refn= $qrefn{$1};
+ $reft= $qreft{$1};
+ if (!length($refn)) {
+ warn "unknown question `$1'";
+ }
+ $in= "$`\\pageref:$1:$refn:$reft\\endpageref.$_";
+ } elsif (s/^pageref:(\w+):([^:\n]+)://) {
+ $in= $_;
+ &call('pageref',$1,$2);
+ } elsif (s/^endpageref\.//) {
+ $in= $_; &call('endpageref');
+ } elsif (s/^(\w+)\{//) {
+ $in= $_; $fn= $1;
+ eval { &call("$fn"); };
+ if (length($@)) { warn $@; $fn= 'x'; }
+ push(@styles,$fn);
+ } elsif (s/^\}//) {
+ $in= $_;
+ $fn= pop(@styles);
+ if ($fn ne 'x') { &call("end$fn"); }
+ } elsif (s/^\\//) {
+ $in= $_;
+ &call('text',"\\");
+ } elsif (s,^(\w+)\s+([-A-Za-z0-9.\@:/]*\w),,) {
+#print STDERR "**$&**$_\n";
+ $in= $_;
+ $style=$1; $word= $2;
+ &call($style);
+ &call('text',$word);
+ &call("end$style");
+ } else {
+ warn "unknown control `\\$_'";
+ $in= $_;
+ }
+ }
+ &call('text',$in);
+}
+
+
+sub call {
+ local ($fnbase, @callargs) = @_;
+ local ($coutput);
+ for $coutput (@outputs) {
+ if ($fnbase eq 'text' && eval("\@${coutput}_cmds")) {
+#print STDERR "special handling text (@callargs) for $coutput\n";
+ $evstrg= "\$${coutput}_args[\$#${coutput}_args].=\"\@callargs\"";
+ eval($evstrg);
+ length($@) && warn "call adding for $coutput (($evstrg)): $@";
+ } else {
+ $fntc= $coutput.'_'.$fnbase;
+ &$fntc(@callargs);
+ }
+ }
+}
+
+
+sub recurse {
+ local (@outputs) = $coutput;
+ local ($holdover);
+ &text($_[0]);
+}
+
+
+sub arg {
+#print STDERR "arg($_[0]) from $coutput\n";
+ $cmd= $_[0];
+ eval("push(\@${coutput}_cmds,\$cmd); push(\@${coutput}_args,'')");
+ length($@) && warn "arg setting up for $coutput: $@";
+}
+
+sub endarg {
+#print STDERR "endarg($_[0]) from $coutput\n";
+ $evstrg= "\$${coutput}_cmd= \$cmd= pop(\@${coutput}_cmds); ".
+ "\$${coutput}_arg= \$arg= pop(\@${coutput}_args); ";
+ eval($evstrg);
+ length($@) && warn "endarg extracting for $coutput (($evstrg)): $@";
+#print STDERR ">call $coutput $cmd $arg< (($evstrg))\n";
+ $evstrg= "&${coutput}_do_${cmd}(\$arg)";
+ eval($evstrg);
+ length($@) && warn "endarg running ${coutput}_do_${cmd} (($evstrg)): $@";
+}
diff --git a/graphics/asymptote/doc/FAQ/install-sh b/graphics/asymptote/doc/FAQ/install-sh
new file mode 100755
index 0000000000..6781b987bd
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/graphics/asymptote/doc/FAQ/m-ascii.pl b/graphics/asymptote/doc/FAQ/m-ascii.pl
new file mode 100644
index 0000000000..d05f8ed80d
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/m-ascii.pl
@@ -0,0 +1,189 @@
+## ASCII output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub ascii_init {
+ open(ASCII,">$prefix.ascii");
+}
+
+sub ascii_startmajorheading {
+ print ASCII '='x79,"\n\n";
+ $ascii_status= 'h';
+ &ascii_text($_[0] ? "Section $_[0]. " : '');
+}
+
+sub ascii_startminorheading {
+ print ASCII '-'x79,"\n\n";
+ $ascii_status= 'h';
+}
+
+sub ascii_italic { &ascii_text('*'); }
+sub ascii_enditalic { $ascii_para .= '*'; }
+
+sub ascii_email { &ascii_text('<'); } sub ascii_endemail { &ascii_text('>'); }
+
+sub ascii_ftpon { } sub ascii_endftpon { }
+sub ascii_ftpin { } sub ascii_endftpin { }
+sub ascii_docref { } sub ascii_enddocref { }
+sub ascii_courier { } sub ascii_endcourier { }
+sub ascii_newsgroup { } sub ascii_endnewsgroup { }
+sub ascii_ftpsilent { $ascii_ignore++; }
+sub ascii_endftpsilent { $ascii_ignore--; }
+
+sub ascii_text {
+ return if $ascii_ignore;
+ if ($ascii_status eq '') {
+ $ascii_status= 'p';
+ }
+ $ascii_para .= $_[0];
+}
+
+sub ascii_tab {
+ local ($n) = $_[0]-length($ascii_para);
+ $ascii_para .= ' 'x$n if $n>0;
+}
+
+sub ascii_newline {
+ return unless $ascii_status eq 'p';
+ &ascii_writepara;
+}
+
+sub ascii_writepara {
+ local ($thisline, $thisword, $rest);
+ for (;;) {
+ last unless $ascii_para =~ m/\S/;
+ $thisline= $ascii_indentstring;
+ for (;;) {
+ last unless $ascii_para =~ m/^(\s*\S+)/;
+ unless (length($1) + length($thisline) < 75 ||
+ length($thisline) == length($ascii_indentstring)) {
+ last;
+ }
+ $thisline .= $1;
+ $ascii_para= $';
+ }
+ $ascii_para =~ s/^\s*//;
+ print ASCII $thisline,"\n";
+ $ascii_indentstring= $ascii_nextindent;
+ last unless length($ascii_para);
+ }
+ $ascii_status= ''; $ascii_para= '';
+}
+
+sub ascii_endpara {
+ return unless $ascii_status eq 'p';
+ &ascii_writepara;
+ print ASCII "\n";
+}
+
+sub ascii_endheading {
+ $ascii_para =~ s/\s*$//;
+ print ASCII "$ascii_para\n\n";
+ $ascii_status= '';
+ $ascii_para= '';
+}
+
+sub ascii_endmajorheading { &ascii_endheading(@_); }
+sub ascii_endminorheading { &ascii_endheading(@_); }
+
+sub ascii_startverbatim {
+ $ascii_vstatus= $ascii_status;
+ &ascii_writepara;
+}
+
+sub ascii_verbatim {
+ print ASCII $_[0],"\n";
+}
+
+sub ascii_endverbatim {
+ $ascii_status= $ascii_vstatus;
+}
+
+sub ascii_finish {
+ close(ASCII);
+}
+
+sub ascii_startindex { $ascii_status= ''; }
+sub ascii_endindex { $ascii_status= 'p'; }
+
+sub ascii_endindexitem {
+ printf ASCII " %-11s %-.66s\n",$ascii_left,$ascii_para;
+ $ascii_status= 'p';
+ $ascii_para= '';
+}
+
+sub ascii_startindexitem {
+ $ascii_left= $_[1];
+}
+
+sub ascii_startindexmainitem {
+ $ascii_left= $_[1];
+ print ASCII "\n" if $ascii_status eq 'p';
+}
+
+sub ascii_startindent {
+ $ascii_istatus= $ascii_status;
+ &ascii_writepara;
+ $ascii_indentstring= " $ascii_indentstring";
+ $ascii_nextindent= " $ascii_nextindent";
+}
+
+sub ascii_endindent {
+ $ascii_indentstring =~ s/^ //;
+ $ascii_nextindent =~ s/^ //;
+ $ascii_status= $ascii_istatus;
+}
+
+sub ascii_startpackedlist { $ascii_plc=0; }
+sub ascii_endpackedlist { &ascii_newline if !$ascii_plc; }
+sub ascii_packeditem {
+ &ascii_newline if !$ascii_plc;
+ &ascii_tab($ascii_plc*40+5);
+ $ascii_plc= !$ascii_plc;
+}
+
+sub ascii_startlist {
+ &ascii_endpara;
+ $ascii_indentstring= " $ascii_indentstring";
+ $ascii_nextindent= " $ascii_nextindent";
+}
+
+sub ascii_endlist {
+ &ascii_endpara;
+ $ascii_indentstring =~ s/^ //;
+ $ascii_nextindent =~ s/^ //;
+}
+
+sub ascii_item {
+ &ascii_newline;
+ $ascii_indentstring =~ s/ $/* /;
+}
+
+sub ascii_pageref {
+ &ascii_text("Q$_[1] \`");
+}
+
+sub ascii_endpageref {
+ &ascii_text("'");
+}
+
+1;
diff --git a/graphics/asymptote/doc/FAQ/m-html.pl b/graphics/asymptote/doc/FAQ/m-html.pl
new file mode 100644
index 0000000000..75b8ccc38f
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/m-html.pl
@@ -0,0 +1,341 @@
+## HTML output
+# Copyright (C) 1993-1995 Ian Jackson.
+# Modified by John Bowman 02Sep06: simply docref usage
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+%saniarray= ('<','lt', '>','gt', '&','amp', '"','quot');
+
+sub html_init {
+ $html_prefix = './'.$prefix;
+ $html_prefix =~ s:^\.//:/:;
+ system('rm','-r',"$html_prefix.html");
+ system('mkdir',"$html_prefix.html");
+ open(HTML,">$html_prefix.html/index.html");
+ print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
+ print HTML "<html>\n";
+ $html_needpara= -1;
+ $html_end='';
+ chop($html_date=`date '+%d %B %Y'`);
+ chop($html_year=`date '+%Y'`);
+}
+
+sub html_startup {
+ print HTML <<END;
+<head><title>
+$user_title
+</title>
+<link rev="made" href="mailto:$user_authormail">
+<link rel="Contents" href="index.html">
+<link rel="Start" href="index.html">
+<META name="description"
+ content="Frequently asked questions and answers (FAQ) for Asymptote.">
+<link rel="Bookmark" title="Asymptote FAQ" href="index.html">
+<LINK rel="Bookmark" title="Asymptote Home Page"
+ href="http://asymptote.sourceforge.net">
+<LINK rel="Bookmark" title="Asymptote Manual"
+ href="http://asymptote.sourceforge.net/doc/">
+</head><body text="#000000" bgcolor="#FFFFFF"><h1>
+$user_title
+</h1>
+END
+ &html_readrefs($_[0]);
+ if (length($user_copyrightref)) {
+ local ($refn) = $qrefn{$user_copyrightref};
+ if (!length($refn)) {
+ warn "unknown question (copyright) `$user_copyrightref'";
+ }
+ $refn =~ m/(\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ $html_copyrighthref= ($s == $html_sectionn)?'':"section$s.html";
+ $html_copyrighthref.= "#$qn2ref{$s,$n}";
+ }
+}
+
+sub html_close {
+ print HTML $html_end,"<address>\n$user_author\n";
+ print HTML "- $html_date\n</address><br>\n";
+ print HTML "Extracted from $user_title,\n";
+ print HTML "<A href=\"$html_copyrighthref\">" if length($html_copyrighthref);
+ print HTML "Copyright &copy; $html_year $user_copyholder.";
+ print HTML "</A>" if length($html_copyrighthref);
+ print HTML "\n</body></html>\n";
+ close(HTML);
+}
+
+sub html_startmajorheading {
+ local ($ref, $this,$next,$back) = @_;
+ local ($nextt,$backt);
+ $this =~ s/^Section /section/; $html_sectionn= $ref;
+ $next =~ s/^Section /section/ && ($nextt= $sn2title{$'});
+ $back =~ s/^Section /section/ ? ($backt= $sn2title{$'}) : ($back='');
+ if ($html_sectionn) {
+ &html_close;
+ open(HTML,">$html_prefix.html/$this.html");
+ print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
+ print HTML "<html>\n";
+ $html_end= "<hr>\n";
+ $html_end.= "Next: <a href=\"$next.html\" rel=precedes>$nextt</a>.<br>\n"
+ if $next;
+ $html_end.= "Back: <a href=\"$back.html\" rev=precedes>$backt</a>.<br>\n"
+ if $back;
+ $html_end.= "<a href=\"index.html\" rev=subdocument>";
+ $html_end.= "Return to contents</a>.<p>\n";
+ print HTML <<END;
+<head><title>
+$user_brieftitle - Section $html_sectionn
+</title>
+<link rev="made" href="mailto:$user_authormail">
+<link rel="Contents" href="index.html">
+<link rel="Start" href="index.html">
+END
+ print HTML "<link rel=\"Next\" href=\"$next.html\">" if $next;
+ print HTML "<link rel=\"Previous\" href=\"$back.html\">" if $back;
+ print HTML <<END;
+<link rel="Bookmark" title="Asymptote FAQ" href="index.html">
+</head><body text="#000000" bgcolor="#FFFFFF"><h1>
+$user_brieftitle - Section $html_sectionn <br>
+END
+ $html_needpara= -1;
+ }
+ else {
+ print HTML "\n<h1>\n";
+ $html_needpara=-1;
+ }
+}
+
+sub html_endmajorheading {
+ print HTML "\n</h1>\n\n";
+ $html_needpara=-1;
+}
+
+sub html_startminorheading {
+ local ($ref, $this) = @_;
+ $html_needpara=0;
+ $this =~ m/^Question (\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ print HTML "\n<h2><A name=\"$qn2ref{$s,$n}\">\n";
+}
+
+sub html_endminorheading {
+ print HTML "\n</A></h2>\n\n";
+ $html_needpara=-1;
+}
+
+sub html_newsgroup { &arg('newsgroup'); }
+sub html_endnewsgroup { &endarg('newsgroup'); }
+sub html_do_newsgroup {
+ print HTML "<A href=\"news:$_[0]\"><code>$_[0]</code></A>";
+}
+
+sub html_email { &arg('email'); }
+sub html_endemail { &endarg('email'); }
+sub html_do_email {
+ print HTML "<A href=\"mailto:$_[0]\"><code>$_[0]</code></A>";
+}
+
+sub html_courier { print HTML "<code>" ; }
+sub html_endcourier { print HTML "</code>"; }
+sub html_italic { print HTML "<i>" ; }
+sub html_enditalic { print HTML "</i>" ; }
+
+sub html_docref { &arg('docref'); }
+sub html_enddocref { &endarg('docref'); }
+sub html_do_docref {
+ if (!defined($html_refval{$_[0]})) {
+# Modified by John Bowman 02Sep06: interpret the argument as an html reference
+# warn "undefined HTML reference $_[0]";
+# $html_refval{$n}='UNDEFINED';
+ print HTML "<A href=\"$_[0]\">";
+ } else {
+ print HTML "<A href=\"$html_refval{$_[0]}\">";
+ }
+ &recurse($_[0]);
+ print HTML "</A>";
+}
+
+sub html_readrefs {
+ local ($p);
+ open(HTMLREFS,"<$_[0]") || (warn("failed to open HTML refs $_[0]: $!"),return);
+ while(<HTMLREFS>) {
+ next if m/^\\\s/;
+ s/\s*\n$//;
+ if (s/^\\prefix\s*//) {
+ $p= $'; next;
+ } elsif (s/^\s*(\S.*\S)\s*\\\s*//) {
+ $_=$1; $v=$';
+ s/\\\\/\\/g;
+ $html_refval{$_}= $p.$v;
+ } else {
+ warn("cannot understand line in HTML refs >$_<");
+ }
+ }
+ close(HTMLREFS);
+}
+
+sub html_ftpsilent { &arg('ftpsilent'); }
+sub html_endftpsilent { &endarg('ftpsilent'); }
+sub html_do_ftpsilent {
+ if ($_[0] =~ m/:/) {
+ $html_ftpsite= $`;
+ $html_ftpdir= $'.'/';
+ } else {
+ $html_ftpsite= $_[0];
+ $html_ftpdir= '';
+ }
+}
+
+sub html_ftpon { &arg('ftpon'); }
+sub html_endftpon { &endarg('ftpon'); }
+sub html_do_ftpon {
+#print STDERR "ftpon($_[0])\n";
+ $html_ftpsite= $_[0]; $html_ftpdir= '';
+ print HTML "<code>";
+ &recurse($_[0]);
+ print HTML "</code>";
+}
+
+sub html_ftpin { &arg('ftpin'); }
+sub html_endftpin { &endarg('ftpin'); }
+sub html_do_ftpin {
+#print STDERR "ftpin($_[0])\n";
+ print HTML "<A href=\"ftp://$html_ftpsite$html_ftpdir$_[0]\"><code>";
+ &recurse($_[0]);
+ print HTML "</code></A>";
+}
+
+sub html_text {
+ print HTML "\n<p>\n" if $html_needpara > 0;
+ $html_needpara=0;
+ $html_stuff= &html_sanitise($_[0]);
+ while ($html_stuff =~ s/^(.{40,70}) //) {
+ print HTML "$1\n";
+ }
+ print HTML $html_stuff;
+}
+
+sub html_tab {
+ $htmltabignore++ || warn "html tab ignored";
+}
+
+sub html_newline { print HTML "<br>\n" ; }
+sub html_startverbatim { print HTML "<pre>\n" ; }
+sub html_verbatim { print HTML &html_sanitise($_[0]),"\n"; }
+sub html_endverbatim { print HTML "</pre>\n" ; $html_needpara= -1; }
+
+sub html_endpara {
+ $html_needpara || $html_needpara++;
+}
+
+sub html_finish {
+ &html_close;
+}
+
+sub html_startindex {
+ print HTML "<ul>\n";
+}
+
+sub html_endindex {
+ print HTML "</ul><hr>\n";
+}
+
+sub html_startindexitem {
+ local ($ref,$qval) = @_;
+ $qval =~ m/Q(\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ print HTML "<li><a href=\"";
+ print HTML ($s == $html_sectionn)?'':"section$s.html";
+ print HTML "#$qn2ref{$s,$n}\" rel=subdocument>Q$s.$n. ";
+ $html_indexunhead='';
+}
+
+sub html_startindexmainitem {
+ local ($ref,$s) = @_;
+ $s =~ m/\d+/; $s= $&;
+ print HTML "<br><br>" if ($s > 1);
+ print HTML "<li><b><font size=\"+2\"><a href=\"section$s.html\" rel=subdocument>Section $s. ";
+ $html_indexunhead='</font></b>';
+}
+
+sub html_endindexitem {
+ print HTML "</a>$html_indexunhead\n";
+}
+
+sub html_startlist {
+ print HTML "\n";
+ $html_itemend="<ul>";
+}
+
+sub html_endlist {
+ print HTML "$html_itemend\n</ul>\n";
+ $html_needpara=-1
+}
+
+sub html_item {
+ print HTML "$html_itemend\n<li>";
+ $html_itemend="";
+ $html_needpara=-1;
+}
+
+sub html_startpackedlist {
+ print HTML "\n";
+ $html_itemend="<dir>";
+}
+
+sub html_endpackedlist {
+ print HTML "$html_itemend\n</dir>\n";
+ $html_needpara=-1;
+}
+
+sub html_packeditem {
+ print HTML "$html_itemend\n<li>";
+ $html_itemend="";
+ $html_needpara=-1;
+}
+
+sub html_startindent { print HTML "<blockquote>\n"; }
+sub html_endindent { print HTML "</blockquote>\n"; }
+
+sub html_pageref {
+ local ($ref,$sq) = @_;
+ $sq =~ m/(\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ print HTML "<A href=\"";
+ print HTML ($s == $html_sectionn)?'':"section$s.html";
+ print HTML "#$qn2ref{$s,$n}\">Q$sq \`";
+}
+
+sub html_endpageref {
+ print HTML "'</A>";
+}
+
+sub html_sanitise {
+ local ($in) = @_;
+ local ($out);
+ while ($in =~ m/[<>&"]/) {
+ $out.= $`. '&'. $saniarray{$&}. ';';
+ $in=$';
+ }
+ $out.= $in;
+ $out;
+}
+
+1;
diff --git a/graphics/asymptote/doc/FAQ/m-info.pl b/graphics/asymptote/doc/FAQ/m-info.pl
new file mode 100644
index 0000000000..cfa2515ae1
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/m-info.pl
@@ -0,0 +1,226 @@
+## Info output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub info_init {
+ open(INFO,">$prefix.info");
+ print INFO <<END;
+Info file: $prefix.info, -*-Text-*-
+produced by bfnnconv.pl from the Bizarre Format With No Name.
+
+END
+}
+
+sub info_heading {
+ # refstring Node Next Previous Up
+ print INFO "\nFile: $prefix.info, Node: $_[1]";
+ print INFO ", Next: $_[2]" if length($_[2]);
+ print INFO ", Previous: $_[3]" if length($_[3]);
+ print INFO ", Up: $_[4]" if length($_[4]);
+ print INFO "\n\n";
+ $info_status= '';
+}
+
+sub info_startmajorheading {
+ return if $_[0] eq '0';
+ &info_heading('s_'.$_[0],@_[1..$#_],'Top');
+}
+
+sub info_startminorheading {
+ &info_heading(@_);
+}
+
+sub info_italic { &info_text('*'); }
+sub info_enditalic { $info_para .= '*'; }
+
+sub info_email { &info_text('<'); } sub info_endemail { &info_text('>'); }
+
+sub info_ftpon { } sub info_endftpon { }
+sub info_ftpin { } sub info_endftpin { }
+sub info_docref { } sub info_enddocref { }
+sub info_courier { } sub info_endcourier { }
+sub info_newsgroup { } sub info_endnewsgroup { }
+sub info_ftpsilent { $info_ignore++; }
+sub info_endftpsilent { $info_ignore--; }
+
+sub info_text {
+ return if $info_ignore;
+ if ($info_status eq '') {
+ $info_status= 'p';
+ }
+ $info_para .= $_[0];
+}
+
+sub info_tab {
+ local ($n) = $_[0]-length($info_para);
+ $info_para .= ' 'x$n if $n>0;
+}
+
+sub info_newline {
+ return unless $info_status eq 'p';
+ print INFO &info_writepara;
+}
+
+sub info_writepara {
+ local ($thisline, $thisword, $rest, $output);
+ for (;;) {
+ last unless $info_para =~ m/\S/;
+ $thisline= $info_indentstring;
+ for (;;) {
+ last unless $info_para =~ m/^(\s*\S+)/;
+ unless (length($1) + length($thisline) < 75 ||
+ length($thisline) == length($info_indentstring)) {
+ last;
+ }
+ $thisline .= $1;
+ $info_para= $';
+ }
+ $info_para =~ s/^\s*//;
+ $output.= $thisline."\n";
+ $info_indentstring= $info_nextindent;
+ last unless length($info_para);
+ }
+ $info_status= ''; $info_para= '';
+ return $output;
+}
+
+sub info_endpara {
+ return unless $info_status eq 'p';
+ print INFO &info_writepara;
+ print INFO "\n";
+}
+
+sub info_endheading {
+ $info_para =~ s/\s*$//;
+ print INFO "$info_para\n\n";
+ $info_status= '';
+ $info_para= '';
+}
+
+sub info_endmajorheading { &info_endheading(@_); }
+sub info_endminorheading { &info_endheading(@_); }
+
+sub info_startverbatim {
+ print INFO &info_writepara;
+}
+
+sub info_verbatim {
+ print INFO $_[0],"\n";
+}
+
+sub info_endverbatim {
+ $info_status= $info_vstatus;
+}
+
+sub info_finish {
+ close(INFO);
+}
+
+sub info_startindex {
+ &info_endpara;
+ $info_moredetail= '';
+ $info_status= '';
+}
+
+sub info_endindex {
+ print INFO "$info_moredetail\n" if length($info_moredetail);
+}
+
+sub info_endindexitem {
+ $info_indentstring= sprintf("* %-17s ",$info_label.'::');
+ $info_nextindent= ' 'x20;
+ local ($txt);
+ $txt= &info_writepara;
+ if ($info_main) {
+ print INFO $label.$txt;
+ $txt =~ s/^.{20}//;
+ $info_moredetail.= $txt;
+ } else {
+ $info_moredetail.= $label.$txt;
+ }
+ $info_indentstring= $info_nextindent= '';
+ $info_status='p';
+}
+
+sub info_startindexitem {
+ print INFO "* Menu:\n" if $info_status eq '';
+ $info_status= '';
+ $info_label= $_[2];
+ $info_main= 0;
+}
+
+sub info_startindexmainitem {
+ print INFO "* Menu:\n" if $info_status eq '';
+ $info_label= $_[2];
+ $info_main= 1;
+ $info_moredetail .= "\n$_[2], ";
+ $info_status= '';
+}
+
+sub info_startindent {
+ $info_istatus= $info_status;
+ print INFO &info_writepara;
+ $info_indentstring= " $info_indentstring";
+ $info_nextindent= " $info_nextindent";
+}
+
+sub info_endindent {
+ $info_indentstring =~ s/^ //;
+ $info_nextindent =~ s/^ //;
+ $info_status= $info_istatus;
+}
+
+sub info_startpackedlist { $info_plc=0; }
+sub info_endpackedlist { &info_newline if !$info_plc; }
+sub info_packeditem {
+ &info_newline if !$info_plc;
+ &info_tab($info_plc*40+5);
+ $info_plc= !$info_plc;
+}
+
+sub info_startlist {
+ $info_istatus= $info_status;
+ print INFO &info_writepara;
+ $info_indentstring= " $info_indentstring";
+ $info_nextindent= " $info_nextindent";
+}
+
+sub info_endlist {
+ $info_indentstring =~ s/^ //;
+ $info_nextindent =~ s/^ //;
+ $info_status= $info_lstatus;
+}
+
+sub info_item {
+ &info_newline;
+ $info_indentstring =~ s/ $/* /;
+}
+
+sub info_pageref {
+ &info_text("*Note Question $_[1]:: \`");
+}
+
+sub info_endpageref {
+ &info_text("'");
+}
+
+1;
diff --git a/graphics/asymptote/doc/FAQ/m-lout.pl b/graphics/asymptote/doc/FAQ/m-lout.pl
new file mode 100644
index 0000000000..5c44852c75
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/m-lout.pl
@@ -0,0 +1,242 @@
+## Lout output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub lout_init {
+ open(LOUT,">$prefix.lout");
+ chop($dprint= `date '+%d %B %Y'`);
+ $dprint =~ s/^0//;
+}
+
+sub lout_startup {
+ local ($lbs) = &lout_sanitise($user_brieftitle);
+ print LOUT <<END;
+\@SysInclude{ fontdefs }
+\@SysInclude{ langdefs }
+\@SysInclude{ dl }
+\@SysInclude{ docf }
+\@Use { \@DocumentLayout
+ \@OddTop { \@Null }
+ \@EvenTop { \@Null }
+ \@StartOddTop { \@Null }
+ \@StartEvenTop { \@Null }
+ \@OddFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@EvenFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@StartOddFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@StartEvenFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@ParaGap { 1.70vx }
+ \@InitialBreak { 1.0fx ragged hyphen }
+}
+\@Use { \@OrdinaryLayout }
+END
+ $lout_textstatus= 'p';
+}
+
+sub lout_pageref {
+ print LOUT "Q$_[1] (page {\@PageOf{$_[0]}}) ";
+ &lout_text("\`");
+}
+
+sub lout_endpageref {
+ &lout_text("'");
+}
+
+sub lout_finish {
+ print LOUT "\@End \@Text\n";
+ close(L);
+}
+
+sub lout_startmajorheading {
+ $lout_styles .= 'h';
+ print LOUT <<END
+\@CNP
+{
+ newpath 0 ysize 0.3 ft sub moveto
+ xsize 0 rlineto
+ 0 0.2 ft rlineto
+ xsize neg 0 rlineto
+ closepath fill
+} \@Graphic { //1.6f \@HAdjust \@Heading{
+END
+ ;
+ $endh= "}\n{\@PageMark s_$_[0]}\n/1.0fo\n";
+ &lout_text($_[0] ? "Section $_[0]. " : '');
+}
+
+sub lout_startminorheading {
+ $lout_styles .= 'h';
+ print LOUT "//0.2f \@CNP {\@PageMark $_[0]} \@Heading{\n";
+ $endh= '';
+}
+
+sub lout_endheading {
+ $lout_styles =~ s/.$//; print LOUT "}\n$endh";
+ $lout_status= 'p';
+}
+
+sub lout_endmajorheading { &lout_endheading(@_); }
+sub lout_endminorheading { &lout_endheading(@_); }
+
+sub lout_courier {
+ $lout_styles .= 'f';
+ print LOUT "{{0.7 1.0} \@Scale {Courier Bold} \@Font {";
+}
+
+sub lout_endcourier {
+ $lout_styles =~ s/.$//; print LOUT "}}";
+}
+
+sub lout_italic { $lout_styles .= 'f'; print LOUT "{Slope \@Font {"; }
+sub lout_enditalic { $lout_styles =~ s/.$//; print LOUT "}}"; }
+
+sub lout_startindent { $lout_styles .= 'i'; print LOUT "\@IndentedDisplay {\n"; }
+
+sub lout_endindent {
+ &lout_endpara;
+ $lout_styles =~ s/.$//; print LOUT "}\n\@LP\n";
+}
+
+sub lout_startpackedlist { $lout_plc=-1; }
+sub lout_endpackedlist { &lout_newline if !$lout_plc; }
+sub lout_packeditem {
+ &lout_newline if !$lout_plc;
+ &lout_tab(($lout_plc>0)*40+5);
+ $lout_plc= !$lout_plc;
+}
+
+sub lout_startlist {
+ &lout_endpara;
+ print LOUT "\@RawIndentedList style {\@Bullet} indent {0.5i} gap {1.1vx}\n";
+ $lout_styles .= 'l';
+ $lout_status= '';
+}
+
+sub lout_endlist {
+ &lout_endpara;
+ print LOUT "\@EndList\n\n";
+ $lout_styles =~ s/.$//;
+}
+
+sub lout_item {
+ &lout_endpara;
+ print LOUT "\@ListItem{";
+ $lout_styles.= 'I';
+}
+
+sub lout_startindex {
+ print LOUT "//0.0fe\n";
+}
+
+sub lout_endindex {
+ $lout_status='p';
+}
+
+sub lout_startindexmainitem {
+ $lout_marker= $_[0];
+ $lout_status= '';
+ print LOUT "//0.3vx Bold \@Font \@HAdjust { \@HContract { { $_[1] } |3cx {";
+ $lout_iiendheight= '1.00';
+ $lout_styles .= 'X';
+}
+
+sub lout_startindexitem {
+ $lout_marker= $_[0];
+ print LOUT "\@HAdjust { \@HContract { { $_[1] } |3cx {";
+ $lout_iiendheight= '0.95';
+ $lout_styles .= 'X';
+}
+
+sub lout_endindexitem {
+ print LOUT "} } |0c \@PageOf { $lout_marker } } //${lout_iiendheight}vx\n";
+ $lout_styles =~ s/.$//;
+}
+
+sub lout_email { &lout_courier; &lout_text('<'); }
+sub lout_endemail { &lout_text('>'); &lout_endcourier; }
+
+sub lout_ftpon { &lout_courier; } sub lout_endftpon { &lout_endcourier; }
+sub lout_ftpin { &lout_courier; } sub lout_endftpin { &lout_endcourier; }
+sub lout_docref { } sub lout_enddocref { }
+sub lout_ftpsilent { $lout_ignore++; }
+sub lout_endftpsilent { $lout_ignore--; }
+
+sub lout_newsgroup { &lout_courier; }
+sub lout_endnewsgroup { &lout_endcourier; }
+
+sub lout_text {
+ return if $lout_ignore;
+ $lout_status= 'p';
+ $_= &lout_sanitise($_[0]);
+ s/ $/\n/ unless $lout_styles =~ m/[fhX]/;
+ print LOUT $_;
+}
+
+sub lout_tab {
+ local ($size) = $_[0]*0.5;
+ print LOUT " |${size}ft ";
+}
+
+sub lout_newline {
+ print LOUT " //1.0vx\n";
+}
+
+sub lout_sanitise {
+ local ($in) = @_;
+ local ($out);
+ $in= ' '.$in.' ';
+ $out='';
+ while ($in =~ m/(\s)(\S*[\@\/|\\\"\^\&\{\}\#]\S*)(\s)/) {
+ $out .= $`.$1;
+ $in = $3.$';
+ $_= $2;
+ s/[\\\"]/\\$&/g;
+ $out .= '"'.$_.'"';
+ }
+ $out .= $in;
+ $out =~ s/^ //; $out =~ s/ $//;
+ $out;
+}
+
+sub lout_endpara {
+ return if $lout_status eq '';
+ if ($lout_styles eq '') {
+ print LOUT "\@LP\n\n";
+ } elsif ($lout_styles =~ s/I$//) {
+ print LOUT "}\n";
+ }
+ $lout_status= '';
+}
+
+sub lout_startverbatim {
+ print LOUT "//0.4f\n\@RawIndentedDisplay lines \@Break".
+ " { {0.7 1.0} \@Scale {Courier Bold} \@Font {\n";
+}
+
+sub lout_verbatim {
+ $_= $_[0];
+ s/^\s*//;
+ print LOUT &lout_sanitise($_),"\n";
+}
+
+sub lout_endverbatim { print LOUT "}\n}\n//0.4f\n"; }
+
+1;
diff --git a/graphics/asymptote/doc/FAQ/m-post.pl b/graphics/asymptote/doc/FAQ/m-post.pl
new file mode 100644
index 0000000000..e41c8d84fe
--- /dev/null
+++ b/graphics/asymptote/doc/FAQ/m-post.pl
@@ -0,0 +1,189 @@
+## POST output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub post_init {
+ open(POST,">$prefix.post");
+}
+
+sub post_startmajorheading {
+ print POST '='x79,"\n\n";
+ $post_status= 'h';
+ &post_text($_[0] ? "Section $_[0]. " : '');
+}
+
+sub post_startminorheading {
+ print POST '-'x77,"\n\n";
+ $post_status= 'h';
+}
+
+sub post_italic { &post_text('*'); }
+sub post_enditalic { $post_para .= '*'; }
+
+sub post_email { &post_text('<'); } sub post_endemail { &post_text('>'); }
+
+sub post_ftpon { } sub post_endftpon { }
+sub post_ftpin { } sub post_endftpin { }
+sub post_docref { } sub post_enddocref { }
+sub post_courier { } sub post_endcourier { }
+sub post_newsgroup { } sub post_endnewsgroup { }
+sub post_ftpsilent { $post_ignore++; }
+sub post_endftpsilent { $post_ignore--; }
+
+sub post_text {
+ return if $post_ignore;
+ if ($post_status eq '') {
+ $post_status= 'p';
+ }
+ $post_para .= $_[0];
+}
+
+sub post_tab {
+ local ($n) = $_[0]-length($post_para);
+ $post_para .= ' 'x$n if $n>0;
+}
+
+sub post_newline {
+ return unless $post_status eq 'p';
+ &post_writepara;
+}
+
+sub post_writepara {
+ local ($thisline, $thisword, $rest);
+ for (;;) {
+ last unless $post_para =~ m/\S/;
+ $thisline= $post_indentstring;
+ for (;;) {
+ last unless $post_para =~ m/^(\s*\S+)/;
+ unless (length($1) + length($thisline) < 75 ||
+ length($thisline) == length($post_indentstring)) {
+ last;
+ }
+ $thisline .= $1;
+ $post_para= $';
+ }
+ $post_para =~ s/^\s*//;
+ print POST $thisline,"\n";
+ $post_indentstring= $post_nextindent;
+ last unless length($post_para);
+ }
+ $post_status= ''; $post_para= '';
+}
+
+sub post_endpara {
+ return unless $post_status eq 'p';
+ &post_writepara;
+ print POST "\n";
+}
+
+sub post_endheading {
+ $post_para =~ s/\s*$//;
+ print POST "$post_para\n\n";
+ $post_status= '';
+ $post_para= '';
+}
+
+sub post_endmajorheading { &post_endheading(@_); }
+sub post_endminorheading { &post_endheading(@_); }
+
+sub post_startverbatim {
+ $post_vstatus= $post_status;
+ &post_writepara;
+}
+
+sub post_verbatim {
+ print POST $_[0],"\n";
+}
+
+sub post_endverbatim {
+ $post_status= $post_vstatus;
+}
+
+sub post_finish {
+ close(POST);
+}
+
+sub post_startindex { $post_status= ''; }
+sub post_endindex { $post_status= 'p'; }
+
+sub post_endindexitem {
+ printf POST " %-11s %-.66s\n",$post_left,$post_para;
+ $post_status= 'p';
+ $post_para= '';
+}
+
+sub post_startindexitem {
+ $post_left= $_[1];
+}
+
+sub post_startindexmainitem {
+ $post_left= $_[1];
+ print POST "\n" if $post_status eq 'p';
+}
+
+sub post_startindent {
+ $post_istatus= $post_status;
+ &post_writepara;
+ $post_indentstring= " $post_indentstring";
+ $post_nextindent= " $post_nextindent";
+}
+
+sub post_endindent {
+ $post_indentstring =~ s/^ //;
+ $post_nextindent =~ s/^ //;
+ $post_status= $post_istatus;
+}
+
+sub post_startpackedlist { $post_plc=0; }
+sub post_endpackedlist { &post_newline if !$post_plc; }
+sub post_packeditem {
+ &post_newline if !$post_plc;
+ &post_tab($post_plc*40+5);
+ $post_plc= !$post_plc;
+}
+
+sub post_startlist {
+ &post_endpara;
+ $post_indentstring= " $post_indentstring";
+ $post_nextindent= " $post_nextindent";
+}
+
+sub post_endlist {
+ &post_endpara;
+ $post_indentstring =~ s/^ //;
+ $post_nextindent =~ s/^ //;
+}
+
+sub post_item {
+ &post_newline;
+ $post_indentstring =~ s/ $/* /;
+}
+
+sub post_pageref {
+ &post_text("Q$_[1] \`");
+}
+
+sub post_endpageref {
+ &post_text("'");
+}
+
+1;
diff --git a/graphics/asymptote/doc/GaussianSurface.asy b/graphics/asymptote/doc/GaussianSurface.asy
new file mode 100644
index 0000000000..bf198a6a24
--- /dev/null
+++ b/graphics/asymptote/doc/GaussianSurface.asy
@@ -0,0 +1,21 @@
+import graph3;
+
+size(200,0);
+
+currentprojection=perspective(10,8,4);
+
+real f(pair z) {return 0.5+exp(-abs(z)^2);}
+
+draw((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle);
+
+draw(arc(0.12Z,0.2,90,60,90,25),ArcArrow3);
+
+surface s=surface(f,(-1,-1),(1,1),nx=5,Spline);
+
+xaxis3(Label("$x$"),red,Arrow3);
+yaxis3(Label("$y$"),red,Arrow3);
+zaxis3(XYZero(extend=true),red,Arrow3);
+
+draw(s,lightgray,meshpen=black+thick(),nolight,render(merge=true));
+
+label("$O$",O,-Z+Y,red);
diff --git a/graphics/asymptote/doc/HermiteSpline.asy b/graphics/asymptote/doc/HermiteSpline.asy
new file mode 100644
index 0000000000..7f4cbbebb2
--- /dev/null
+++ b/graphics/asymptote/doc/HermiteSpline.asy
@@ -0,0 +1,14 @@
+import graph;
+
+size(140mm,70mm,IgnoreAspect);
+scale(false);
+real[] x={1,3,4,5,6};
+real[] y={1,5,2,0,4};
+
+marker mark=marker(scale(1mm)*cross(6,false,r=0.35),red,Fill);
+
+draw(graph(x,y,Hermite),"Hermite Spline",mark);
+xaxis("$x$",Bottom,LeftTicks(x));
+yaxis("$y$",Left,LeftTicks);
+attach(legend(),point(NW),40S+30E,UnFill);
+
diff --git a/graphics/asymptote/doc/Hobbycontrol.asy b/graphics/asymptote/doc/Hobbycontrol.asy
new file mode 100644
index 0000000000..50662988e0
--- /dev/null
+++ b/graphics/asymptote/doc/Hobbycontrol.asy
@@ -0,0 +1,20 @@
+size(200);
+pair z0=(0,0);
+pair z1=(0.5,3);
+pair z2=(2,1);
+
+path g=z0..z1..z2;
+
+pair d0=dir(g,0);
+pair d1=dir(g,1);
+draw(Label("$\omega_0$",1),z0-d0..z0+d0,blue+dashed,Arrow);
+draw(Label("$\omega_1$",1),z1-d1..z1+1.5d1,blue+dashed,Arrow);
+draw(z0--interp(z0,z1,1.5),dashed);
+draw(subpath(g,0,1),blue);
+draw("$\theta$",arc(z0,0.4,degrees(z1-z0),degrees(d0)),red,Arrow,
+ EndPenMargin);
+draw("$\phi$",arc(z1,1.05,degrees(z1-z0),degrees(d1)),red,Arrow,
+ EndPenMargin);
+
+dot("$z_0$",z0,SW,red);
+dot("$z_1$",z1,SE,red);
diff --git a/graphics/asymptote/doc/Hobbydir.asy b/graphics/asymptote/doc/Hobbydir.asy
new file mode 100644
index 0000000000..01d8a2e0ed
--- /dev/null
+++ b/graphics/asymptote/doc/Hobbydir.asy
@@ -0,0 +1,21 @@
+size(200);
+pair z0=(0,0);
+pair z1=(1,2);
+pair z2=(2,1);
+
+path g=z0..z1..z2;
+
+label("$\ell_k$",z0--z1);
+draw("$\ell_{k+1}$",z1--z2,dashed);
+draw(z0--interp(z0,z1,1.5),dashed);
+pair d1=dir(g,1);
+draw(z1-d1..z1+d1,blue+dashed);
+draw(g,blue);
+draw(Label("$\theta_k$",0.4),arc(z1,0.4,degrees(z2-z1),degrees(d1)),blue,Arrow,
+ EndPenMargin);
+draw("$\phi_k$",arc(z1,0.4,degrees(d1),degrees(z1-z0),CCW),Arrow,
+ EndPenMargin);
+
+dot("$z_{k-1}$",z0,red);
+dot("$z_k$",z1,NW,red);
+dot("$z_{k+1}$",z2,red);
diff --git a/graphics/asymptote/doc/Makefile.in b/graphics/asymptote/doc/Makefile.in
new file mode 100644
index 0000000000..58dfc179df
--- /dev/null
+++ b/graphics/asymptote/doc/Makefile.in
@@ -0,0 +1,135 @@
+MANFILES = asy.1 xasy.1x
+ASYFILES = $(filter-out $(wildcard latexusage-*.asy),$(wildcard *.asy))
+SOURCE = asymptote.texi version.texi options
+ASY = ../asy -dir ../base -config "" -render=0
+DOCFILES = asymptote.pdf asy-latex.pdf CAD.pdf TeXShopAndAsymptote.pdf \
+ asyRefCard.pdf
+
+docdir = $(DESTDIR)@docdir@
+infodir = $(DESTDIR)@infodir@
+datarootdir = @datarootdir@
+INSTALL = @INSTALL@
+TEXI2DVI = @TEXI2DVI@
+PERL5LIB = ./
+
+export docdir infodir INSTALL PERL5LIB
+
+all: doc
+
+asy-latex.pdf:
+ pdflatex asy-latex.dtx
+
+asymptote.sty:
+ pdflatex asy-latex.dtx
+
+dvi: doc asymptote.dvi
+
+doc: $(DOCFILES) asy.1 faq latexusage.eps
+ cd png && $(MAKE) all
+
+manpage: $(MANFILES)
+
+man: $(DOCFILES) manpage
+ cd png && $(MAKE) asymptote.info
+
+faq:
+ cd FAQ && $(MAKE) faq
+
+%.eps: %.asy
+ $(ASY) -f eps $<
+
+%.pdf: %.asy
+ $(ASY) -f pdf -noprc $<
+
+latexusage.dvi: latexusage.tex asymptote.sty
+ rm -f latexusage-*
+ rm -f latexusage.pre
+ rm -f latexusage.aux
+ latex latexusage
+ $(ASY) -noprc latexusage-*.asy
+ latex latexusage
+
+latexusage.eps: latexusage.dvi
+ dvips -o latexusage.eps latexusage
+
+latexusage.pdf: latexusage.dvi
+ dvipdf -P latexusage
+
+options: ../settings.cc
+ $(ASY) -h 2>&1 | grep -iv Asymptote > options
+
+asy.1: options asy.1.begin asy.1.end
+ cat options | grep \^- | \
+ sed -e "s/-\(.*\) \([a-zA-Z0-9].*\)/.TP\n.B -\1\n\2\./" | \
+ sed -e "/^.B/ s/-/\\\\-/g" | cat asy.1.begin - asy.1.end > asy.1
+
+asymptote.dvi: $(SOURCE) $(ASYFILES:.asy=.eps) latexusage.pdf
+ ln -sf asymptote.texi asymptote_.texi
+ -$(TEXI2DVI) asymptote_.texi
+ mv asymptote_.dvi asymptote.dvi
+
+asymptote.pdf: $(SOURCE) $(ASYFILES:.asy=.pdf) latexusage.pdf
+ -$(TEXI2DVI) --pdf asymptote.texi
+
+CAD.pdf: CAD.tex CAD1.eps
+ latex CAD
+ latex CAD
+ latex CAD
+ dvipdf -P CAD
+
+TeXShopAndAsymptote.pdf: TeXShopAndAsymptote.tex
+ latex TeXShopAndAsymptote
+ latex TeXShopAndAsymptote
+ dvipdf -P TeXShopAndAsymptote
+
+asyRefCard.pdf: asyRefCard.tex
+ tex asyRefCard
+ dvipdf -P asyRefCard
+
+clean: FORCE
+ -rm -f asy-latex.{aux,idx,ins,log,toc}
+ -rm -f $(ASYFILES:.asy=.pdf)
+ -rm -f *.eps latexusage.{dvi,eps,pdf,log,aux,*.eps} latexusage-* \
+ latexusage.pre
+ -rm -f \
+ {asymptote,asymptote_}.{aux,cp,cps,dvi,fn,info,ky,log,pg,toc,tp,vr}
+ -rm -f asymptote_.texi
+ -rm -f {CAD,TeXShopAndAsymptote,asyRefCard}.{aux,dvi,log,toc}
+ -rm -f options asy.1
+ cd png && $(MAKE) clean
+
+install-man:
+ ${INSTALL} -d -m 755 $(docdir) $(mandir)/man1
+ ${INSTALL} -p -m 644 $(DOCFILES) $(docdir)
+ ${INSTALL} -p -m 644 $(MANFILES) $(mandir)/man1
+
+install: man faq install-man
+ cd png && $(MAKE) install
+ cd FAQ && $(MAKE) install
+
+install-prebuilt: install-man options
+ touch png/asymptote.info
+ cd png && $(MAKE) install
+ cd FAQ && $(MAKE) install-prebuilt
+
+install-all: $(DOCFILES) $(MANFILES) faq latexusage.eps install-man
+ cd png && $(MAKE) install-all
+ cd FAQ && $(MAKE) install-info
+
+uninstall: uninstall-all
+
+uninstall-all:
+ cd png && $(MAKE) uninstall
+ cd FAQ && $(MAKE) uninstall
+ -cd $(mandir)/man1 && rm -f $(MANFILES)
+ -rm -f $(addprefix $(docdir)/,$(DOCFILES))
+
+distclean: FORCE clean
+ -rm -f version.texi Makefile
+ -rm -f $(DOCFILES)
+ cd png && $(MAKE) distclean
+ cd FAQ && $(MAKE) distclean
+FORCE:
+
+Makefile: Makefile.in
+ cd ..; config.status
diff --git a/graphics/asymptote/doc/TeXShopAndAsymptote.pdf b/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
new file mode 100644
index 0000000000..75708beb4e
--- /dev/null
+++ b/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/TeXShopAndAsymptote.tex b/graphics/asymptote/doc/TeXShopAndAsymptote.tex
new file mode 100644
index 0000000000..06ca734152
--- /dev/null
+++ b/graphics/asymptote/doc/TeXShopAndAsymptote.tex
@@ -0,0 +1,94 @@
+\documentclass[11pt]{article}
+\usepackage{geometry}
+\geometry{letterpaper}
+
+\usepackage[parfill]{parskip}
+\usepackage{graphicx}
+\usepackage{amssymb}
+
+\title{Integrating Asymptote and TeXShop for Mac OS X}
+\author{Vishaal Rajani \& Cole Zmurchok \\ University of Alberta}
+\date{\today}
+
+
+\begin{document}
+\maketitle
+\begin{enumerate}
+\item Download Asymptote and place the \emph{asymptote-x.xx.src.tgz} file
+on the desktop.
+\item Open Terminal and type the following. Note that you will
+have to enter the root password for the final command.
+\begin{verbatim}
+cd Desktop
+gunzip asymptote-x.xx.src.tgz
+tar -xf asymptote-x.xx.src.tar
+cd asymptote-x.xx
+./configure
+make all
+sudo make install
+\end{verbatim}
+If you get an error at the \verb+./configure+ step, stating that you there
+is \verb+no acceptable C+ \verb+compiler found in $PATH+, a solution
+is to download and install Xcode here: \\
+\verb+http://developer.apple.com/TOOLS/Xcode/+.
+
+\item We now create the engine that will typeset Asymptote in TeXShop. The
+easiest way to create this engine, which we will
+call \emph{asyEngine.engine}, is to navigate
+to \verb+~/Library/TeXShop/Engines+ and duplicate one of the
+existing \emph{.engine} files. Open the duplicate file and delete the code
+there. Type the following:
+\begin{verbatim}
+#!/bin/sh
+location=$(dirname "$1")
+basename="${1%.tex}"
+#process
+cd $location
+pdflatex "$1"
+asy "${basename}"-*.asy
+pdflatex "$1"
+\end{verbatim}
+Save this file as \emph{asyEngine.engine}.
+
+\item Now we set our engine to be executable. In the terminal, navigate to
+the Engines directory and type:
+
+\begin{verbatim}
+chmod +x asyEngine.engine
+\end{verbatim}
+
+\item Finally, in the terminal, type:
+
+\begin{verbatim}
+defaults write TeXShop OtherTeXExtensions -array-add "asy"
+\end{verbatim}
+
+This last command allows you choose the \emph{asyEngine} option from the
+drop-down menu when you wish to typeset a document that includes asymptote.
+\end{enumerate}
+
+Now, if you wish to typeset something simple, like the following red line,
+create a new document in TeXShop and type:
+
+\begin{verbatim}
+\documentclass[letterpaper,12pt]{article}
+\usepackage{amsmath}
+\usepackage{amssymb}
+\usepackage{asymptote}
+
+\begin{document}
+\begin{asy}
+ size(300);
+ draw((0,0)--(1,1),red);
+\end{asy}
+\end{document}
+\end{verbatim}
+
+Choose the \emph{asyEngine} option from the drop-down menu and
+press \emph{Typeset}. Your red line will be created in a PDF Document.
+
+On a final note, it is best to avoid using filenames with spaces in them.
+For example, avoid filenames such as \verb+asy test.tex+ and instead use
+filenames without spaces, such as \verb+asyTest.tex+.
+
+\end{document}
diff --git a/graphics/asymptote/doc/asy-latex.dtx b/graphics/asymptote/doc/asy-latex.dtx
new file mode 100644
index 0000000000..bcf8498c83
--- /dev/null
+++ b/graphics/asymptote/doc/asy-latex.dtx
@@ -0,0 +1,715 @@
+% \iffalse
+%
+%<*internal>
+\begingroup
+%</internal>
+%<*batchfile>
+\input docstrip.tex
+\keepsilent
+\preamble
+____________________________
+The ASYMPTOTE package
+
+(C) 2003 Tom Prince
+(C) 2003-2016 John Bowman
+(C) 2010 Will Robertson
+
+Adapted from comment.sty
+
+Licence: GPL2+
+
+\endpreamble
+\nopostamble
+\askforoverwritefalse
+\generate{\file{asymptote.sty}{\from{\jobname.dtx}{pkg}}}
+%</batchfile>
+%<batchfile>\endbatchfile
+%<*internal>
+\generate{\file{\jobname.ins}{\from{\jobname.dtx}{batchfile}}}
+\edef\tmpa{plain}
+\ifx\tmpa\fmtname\endgroup\expandafter\bye\fi
+\endgroup
+\immediate\write18{makeindex -s gind.ist -o \jobname.ind \jobname.idx}
+\immediate\write18{makeindex -s gglo.ist -o \jobname.gls \jobname.glo}
+%</internal>
+%
+%<*driver>
+\ProvidesFile{asy-latex.dtx}
+%</driver>
+%<pkg>\ProvidesPackage{asymptote}
+%<*pkg>
+ [2016/11/26 v1.33 Asymptote style file for LaTeX]
+%</pkg>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \GetFileInfo{asy-latex.dtx}
+% \title{The \textsf{asymptote} package}
+% \author{%
+% John Bowman, Tom Prince, and Will Robertson
+% }
+% \date{\filedate\qquad\fileversion}
+% \maketitle
+% \begin{abstract}
+% This package provides integration of inline and external Asymptote
+% graphics within a \LaTeX\ document.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% This is the documentation for the \LaTeX\ package \texttt{asymptote}
+% which accompanies the Asymptote drawing package. For further details on
+% Asymptote, please see its documentation in \texttt{asymptote.pdf}.
+%
+% \section{User syntax}
+%
+% \subsection{Package loading and options}
+%
+% The package may take two options at load time: \texttt{inline} or
+% \texttt{attach}.
+% These options can also be set at any time with the
+% \cmd\asysetup\marg{options} command, or specified individually in the
+% optional argument to each \texttt{asy} environment or \texttt{asyinclude}
+% command.
+%
+% The \texttt{inline} option uses Asymptote's `inline' mode whereby
+% included graphics have their labels typeset in the environment of the
+% document they are contained within. Otherwise the Asymptote graphics are
+% self-contained and their formatting is independent of the document.
+%
+% The \texttt{attach} option allows generated graphics to be embedded
+% within the PDF using the \texttt{attachfile2} package; please load that
+% package separately if you wish to use it. The \texttt{attach} option
+% takes precedence over the \texttt{inline} option.
+%
+% This package produces quite a number of output files, which by default
+% are created in the same directory as the \LaTeX\ document that is being
+% compiled. To keep things more tidy, you can specify an output directory
+% for these files by defining the \cmd\asydir\ command. For example, if you
+% wish to store the figure files in the subdirectory \texttt{asytmp/}, the
+% you would write \verb|\renewcommand\asydir{asytmp}|.
+%
+% Alternatively (and tentatively), you may write \verb|dir=asytmp| in
+% either the \texttt{asy} environment options or the options to
+% \cmd\asysetup.
+%
+% \subsection{Commands for inserting Asymptote graphics}
+%
+% The main environment defined by the package is the \texttt{asy}
+% environment, in which verbatim Asymptote code is placed that will be
+% compiled for generating a graphic in the document. For example,
+% \begin{verbatim}
+% \begin{figure}
+% \begin{asy}[ <options> ]
+% <ASYMPTOTE CODE>
+% \end{asy}
+% \caption{...}\label{...}
+% \end{verbatim}
+%
+% If you have Asymptote code in a separate file, you can include it with
+% the \cmd\asyinclude\oarg{options}\marg{filename}\ command.
+%
+% For Asymptote code that should be included in \emph{every} graphic,
+% define it using the \texttt{asydef} environment.
+%
+% \subsection{Graphics options}
+%
+% Both the \texttt{asy} environment and the \cmd\asyinclude\ command take
+% optional parameters for controlling aspects of the graphics creation. In
+% addition to locally setting \texttt{inline} and \texttt{attach}, the
+% following options may also be used:
+% \begin{description}
+% \item[width] Width of the figure
+% \item[height] Height of the figure
+% \item[keepAspect] Maintain aspect ratio [default true]
+% \item[viewportwidth] Viewport width for 3D figures
+% \item[viewportheight] Viewport height for 3D figures
+% \end{description}
+% These may also be set globally using the \cmd\asysetup\ command.
+%
+% \section{Processing the document}
+%
+% After running \LaTeX\ on the document, it is necessary to process the
+% Asymptote graphics so they can be included in the next compilation. The
+% simplest procedure is a recipe such as
+% \begin{verbatim}
+% pdflatex mydoc
+% asy mydoc-*.asy
+% pdflatex mydoc
+% \end{verbatim}
+% This technique will recompile each graphic every time, however. To only
+% recompile graphics that have changed, use the \texttt{latexmk}
+% tool. Asymptote is distributed with a \texttt{latexmkrc} configuration
+% file; place this file in a place where \texttt{latexmk} will find it and
+% your document may be compiled, including the \texttt{asy} compilations,
+% with \texttt{latexmk mydoc} or \texttt{latexmk --pdf mydoc}.
+%
+% \section{Implementation}
+%
+% \iffalse
+%<*pkg>
+% \fi
+%
+% \begin{macrocode}
+\def\Asymptote{{\tt Asymptote}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\InputIfFileExists{\jobname.pre}{}{}
+% \end{macrocode}
+%
+% \subsection{Allocations}
+%
+% \paragraph{Allocations}
+%
+% \begin{macrocode}
+\newbox\ASYbox
+\newdimen\ASYdimen
+\newcounter{asy}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newwrite\AsyStream
+\newwrite\AsyPreStream
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newif\ifASYinline
+\newif\ifASYattach
+\newif\ifASYkeepAspect
+\ASYkeepAspecttrue
+% \end{macrocode}
+%
+% \subsection{Packages}
+%
+% \begin{macrocode}
+\RequirePackage{keyval}
+\RequirePackage{ifthen}
+\RequirePackage{color,graphicx}
+% \end{macrocode}
+%
+% \paragraph{Emulating packages}
+% We cannot assume that Asymptote users have recent
+% \TeX\ distributions. (E.g., Fedora until recently still shipped teTeX.)
+% So load \textsf{ifpdf} and \textsf{ifxetex} if they exist; otherwise,
+% emulate them.
+%
+% In due course, delete this code and just load the packages.
+% \begin{macrocode}
+\IfFileExists{ifpdf.sty}{
+ \RequirePackage{ifpdf}
+}{
+ \expandafter\newif\csname ifpdf\endcsname
+ \ifx\pdfoutput\@undefined\else
+ \ifcase\pdfoutput\else
+ \pdftrue
+ \fi
+ \fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\IfFileExists{ifxetex.sty}{
+ \RequirePackage{ifxetex}
+}{
+ \expandafter\newif\csname ifxetex\endcsname
+ \ifx\XeTeXversion\@undefined\else
+ \xetextrue
+ \fi
+}
+% \end{macrocode}
+%
+% \begin{macro}{\CatchFileDef}
+% Used for \cmd\asyinclude.
+% Note that the fallback definition is not as robust as the one provided by catchfile.
+% \begin{macrocode}
+\IfFileExists{catchfile.sty}{
+ \RequirePackage{catchfile}
+}{
+ \newcommand\CatchFileDef[3]{%
+ \begingroup
+ \everyeof{%
+ \ENDCATCHFILEMARKER
+ \noexpand
+ }%
+ \long\def\@tempa####1\ENDCATCHFILEMARKER{%
+ \endgroup
+ \def##1{####1}%
+ }%
+ ##3%
+ \expandafter\@tempa\@@input ##2\relax
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{Ensuring attachfile2 is loaded if [attach] is requested}
+% \begin{macrocode}
+\newif\if@asy@attachfile@loaded
+% \end{macrocode}
+%
+% \begin{macrocode}
+\AtBeginDocument{%
+ \@ifpackageloaded{attachfile2}{\@asy@attachfile@loadedtrue}{}%
+ \let\asy@check@attachfile\asy@check@attachfile@loaded
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcommand\asy@check@attachfile@loaded{%
+ \if@asy@attachfile@loaded\else
+ \PackageError{asymptote}{You must load the attachfile2 package}{^^J%
+ You have requested the [attach] option for some or all of your^^J%
+ Asymptote graphics, which requires the attachfile2 package.^^J%
+ Please load it in the document preamble.^^J%
+ }%
+ \fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcommand\asy@check@attachfile{%
+ \AtBeginDocument{\asy@check@attachfile@loaded}%
+ \let\asy@check@attachfile\@empty
+}
+% \end{macrocode}
+%
+% \paragraph{Macros}
+% \begin{macrocode}
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+% \end{macrocode}
+%
+% \subsection{Package options}
+%
+% \begin{macrocode}
+\DeclareOption{inline}{%
+ \ASYinlinetrue
+}
+\DeclareOption{attach}{%
+ \asy@check@attachfile
+ \ASYattachtrue
+}
+\ProcessOptions*
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\asylatexdir{}
+\def\asydir{}
+\def\ASYasydir{}
+\def\ASYprefix{}
+% \end{macrocode}
+%
+%
+% \subsection{Testing for PDF output}
+% Note this is not quite the same as \cs{ifpdf}, since we still want PDF
+% output when using XeTeX.
+% \begin{macrocode}
+\newif\ifASYPDF
+\ifxetex
+ \ASYPDFtrue
+ \usepackage{everypage}
+\else
+ \ifpdf
+ \ASYPDFtrue
+ \fi
+\fi
+\ifASYPDF
+ \def\AsyExtension{pdf}
+\else
+ \def\AsyExtension{eps}
+\fi
+% \end{macrocode}
+%
+% \subsection{Bug squashing}
+%
+% \begin{macrocode}
+\def\unquoteJobname#1"#2"#3\relax{%
+ \def\rawJobname{#1}%
+ \ifx\rawJobname\empty
+ \def\rawJobname{#2}%
+ \fi
+}
+\expandafter\unquoteJobname\jobname""\relax
+% \end{macrocode}
+% Work around jobname bug in MiKTeX 2.5 and 2.6:
+% Turn stars in file names (resulting from spaces, etc.) into minus signs
+% \begin{macrocode}
+\def\fixstar#1*#2\relax{%
+ \def\argtwo{#2}%
+ \ifx\argtwo\empty
+ \gdef\Jobname{#1}%
+ \else
+ \fixstar#1-#2\relax
+ \fi
+}
+\expandafter\fixstar\rawJobname*\relax
+% \end{macrocode}
+%
+% Work around bug in dvips.def: allow spaces in file names.
+% \begin{macrocode}
+\def\Ginclude@eps#1{%
+ \message{<#1>}%
+ \bgroup
+ \def\@tempa{!}%
+ \dimen@\Gin@req@width
+ \dimen@ii.1bp\relax
+ \divide\dimen@\dimen@ii
+ \@tempdima\Gin@req@height
+ \divide\@tempdima\dimen@ii
+ \special{PSfile=#1\space
+ llx=\Gin@llx\space
+ lly=\Gin@lly\space
+ urx=\Gin@urx\space
+ ury=\Gin@ury\space
+ \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\space\fi
+ \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\space\fi
+ \ifGin@clip clip\fi}%
+ \egroup
+}
+% \end{macrocode}
+%
+% \subsection{Input/Output}
+%
+% \begin{macrocode}
+\immediate\openout\AsyPreStream=\jobname.pre\relax
+\AtEndDocument{\immediate\closeout\AsyPreStream}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\WriteAsyLine#1{%
+ \immediate\write\AsyStream{\detokenize{#1}}%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\globalASYdefs{}
+\def\WriteGlobalAsyLine#1{%
+ \expandafter\g@addto@macro
+ \expandafter\globalASYdefs
+ \expandafter{\detokenize{#1^^J}}%
+}
+% \end{macrocode}
+%
+% \subsection{Commands for verbatim processing environments}
+%
+% \begin{macrocode}
+\def\ProcessAsymptote#1{%
+ \begingroup
+ \def\CurrentAsymptote{#1}%
+ \let\do\@makeother \dospecials
+ \@makeother\^^L% and whatever other special cases
+ \catcode`\ =10
+ \endlinechar`\^^M \catcode`\^^M=12 \xAsymptote
+}
+% \end{macrocode}
+% Need lots of comment chars here because \meta{line end} is no longer a
+% space character.
+% \begin{macrocode}
+\begingroup
+ \catcode`\^^M=12 \endlinechar=-1\relax%
+ \gdef\xAsymptote{%
+ \expandafter\ProcessAsymptoteLine%
+ }
+ \gdef\ProcessAsymptoteLine#1^^M{%
+ \def\@tempa{#1}%
+ {%
+ \escapechar=-1\relax%
+ \xdef\@tempb{\string\\end\string\{\CurrentAsymptote\string\}}%
+ }%
+ \ifx\@tempa\@tempb%
+ \edef\next{\endgroup\noexpand\end{\CurrentAsymptote}}%
+ \else%
+ \ThisAsymptote{#1}%
+ \let\next\ProcessAsymptoteLine%
+ \fi%
+ \next%
+ }
+\endgroup
+\def\asy@init{%
+ \def\ASYlatexdir{}%
+ \ifx\asylatexdir\empty\else
+ \def\ASYlatexdir{\asylatexdir/}%
+ \fi
+ \ifx\asydir\empty\else
+ \def\ASYasydir{\asydir/}%
+ \fi
+ \def\ASYprefix{\ASYlatexdir\ASYasydir}%
+}
+% \end{macrocode}
+%
+% \subsection{User interface}
+%
+% \begin{macrocode}
+\newcommand\asy[1][]{%
+ \stepcounter{asy}%
+ \setkeys{ASYkeys}{#1}%
+% \end{macrocode}
+% Disable the "inline" option if "attach" is enabled:
+% \begin{macrocode}
+ \ifASYattach
+ \ASYinlinefalse
+ \fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \asy@init
+ \immediate\write\AsyPreStream{%
+ \noexpand\InputIfFileExists{%
+ \ASYprefix\noexpand\jobname-\the\c@asy.pre}{}{}%
+ }%
+ \asy@write@graphic@header
+ \let\ThisAsymptote\WriteAsyLine
+ \ProcessAsymptote{asy}%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\endasy{%
+ \asy@finalise@stream
+ \asy@input@graphic
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\asy@write@graphic@header{%
+ \immediate\openout\AsyStream=\ASYasydir\jobname-\the\c@asy.asy\relax
+ \gdef\AsyFile{\ASYprefix\Jobname-\the\c@asy}%
+ \immediate\write\AsyStream{%
+ if(!settings.multipleView) settings.batchView=false;^^J%
+ \ifxetex
+ settings.tex="xelatex";^^J%
+ \else\ifASYPDF
+ settings.tex="pdflatex";^^J%
+ \fi\fi
+ \ifASYinline
+ settings.inlinetex=true;^^J%
+ deletepreamble();^^J%
+ \fi
+ defaultfilename="\Jobname-\the\c@asy";^^J%
+ if(settings.render < 0) settings.render=4;^^J%
+ settings.outformat="";^^J%
+ \ifASYattach
+ settings.inlineimage=false;^^J%
+ settings.embed=false;^^J%
+ settings.toolbar=true;^^J%
+ \else
+ settings.inlineimage=true;^^J%
+ settings.embed=true;^^J%
+ settings.toolbar=false;^^J%
+ viewportmargin=(2,2);^^J%
+ \fi
+ \globalASYdefs
+ }%
+}
+\def\asy@expand@keepAspect{%
+ \ifASYkeepAspect keepAspect=true%
+ \else keepAspect=false%
+ \fi%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\asy@finalise@stream{%
+% \end{macrocode}
+% Setting \verb|size()|. Only inserted if one of the dimensions is
+% set explicitly (i.e., if both height and width are not empty).
+% \begin{macrocode}
+ \ifx\ASYwidth\@empty
+ \ifx\ASYheight\@empty
+ % write nothing!
+ \else
+ \immediate\write\AsyStream{size(0,\ASYheight,\asy@expand@keepAspect);}%
+ \fi
+ \else
+ \ifx\ASYheight\@empty
+ \immediate\write\AsyStream{size(\ASYwidth,0,\asy@expand@keepAspect);}%
+ \else
+ \immediate\write\AsyStream{size(\ASYwidth,\ASYheight,\asy@expand@keepAspect);}%
+ \fi
+ \fi
+% \end{macrocode}
+% Setting \verb|viewportsize=()|. Same logic as for \verb|size()|.
+% \begin{macrocode}
+ \ifx\ASYviewportwidth\@empty
+ \ifx\ASYviewportheight\@empty
+ % write nothing!
+ \else
+ \immediate\write\AsyStream{viewportsize=(0,\ASYviewportheight);}%
+ \fi
+ \else
+ \ifx\ASYviewportheight\@empty
+ \immediate\write\AsyStream{viewportsize=(\ASYviewportwidth,0);}%
+ \else
+ \immediate\write\AsyStream{%
+ viewportsize=(\ASYviewportwidth,\ASYviewportheight);}%
+ \fi
+ \fi
+ \immediate\closeout\AsyStream
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\asy@input@graphic{%
+ \ifASYinline
+ \IfFileExists{"\AsyFile.tex"}{%
+ \catcode`:=12\relax
+ \@@input"\AsyFile.tex"\relax
+ }{%
+ \PackageWarning{asymptote}{file `\AsyFile.tex' not found}%
+ }%
+ \else
+ \IfFileExists{"\AsyFile.\AsyExtension"}{%
+ \ifASYattach
+ \ifASYPDF
+ \IfFileExists{"\AsyFile+0.pdf"}{%
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile+0".pdf}}%
+ }{%
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile".pdf}}%
+ }%
+ \else
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile.eps"}}%
+ \fi
+ \textattachfile{\AsyFile.\AsyExtension}{\phantom{\copy\ASYbox}}%
+ \vskip-\ht\ASYbox
+ \indent
+ \box\ASYbox
+ \else
+ \ifASYPDF
+ \includegraphics[hiresbb]{"\AsyFile".pdf}%
+ \else
+ \includegraphics[hiresbb]{"\AsyFile.eps"}%
+ \fi
+ \fi
+ }{%
+% \end{macrocode}
+% 3D PRC figures require inline mode.
+% \begin{macrocode}
+ \IfFileExists{"\AsyFile.tex"}{%
+ \catcode`:=12
+ \@@input"\AsyFile.tex"\relax
+ }{%
+ \PackageWarning{asymptote}{%
+ file `\AsyFile.\AsyExtension' not found%
+ }%
+ }%
+ }%
+ \fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\asydef{%
+ \let\ThisAsymptote\WriteGlobalAsyLine
+ \ProcessAsymptote{asydef}%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcommand\asyinclude[2][]{%
+ \begingroup
+ \stepcounter{asy}%
+ \setkeys{ASYkeys}{#1}%
+ \ifASYattach
+ \ASYinlinefalse
+ \fi
+ \asy@init
+ \immediate\write\AsyPreStream{%
+ \noexpand\InputIfFileExists{%
+ \ASYprefix\noexpand\jobname-\the\c@asy.pre}{}{}%
+ }%
+ \asy@write@graphic@header
+ \IfFileExists{#2.asy}{%
+ \CatchFileDef\@tempa{#2.asy}{%
+ \let\do\@makeother
+ \dospecials
+ \endlinechar=10\relax
+ }%
+ }{%
+ \IfFileExists{#2}{%
+ \CatchFileDef\@tempa{#2}{%
+ \let\do\@makeother
+ \dospecials
+ \endlinechar=10\relax
+ }%
+ }{%
+ \PackageWarning{asymptote}{file #2 not found}%
+ \def\@tempa{}%
+ }%
+ }%
+ \immediate\write\AsyStream{\unexpanded\expandafter{\@tempa}}%
+ \asy@finalise@stream
+ \asy@input@graphic
+ \endgroup
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcommand{\ASYanimategraphics}[5][]{%
+ \IfFileExists{_#3.pdf}{%
+ \animategraphics[{#1}]{#2}{_#3}{#4}{#5}%
+ }{}%
+}
+% \end{macrocode}
+%
+% \subsection{Keys for graphics processing}
+%
+% \begin{macrocode}
+\newcommand\asysetup[1]{\setkeys{ASYkeys}{#1}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\define@key{ASYkeys}{dir}{%
+ \def\asydir{#1}%
+}
+\def\ASYwidth{}
+\define@key{ASYkeys}{width}{%
+ \edef\ASYwidth{\the\dimexpr#1\relax}%
+}
+\def\ASYheight{}
+\define@key{ASYkeys}{height}{%
+ \edef\ASYheight{\the\dimexpr#1\relax}%
+}
+\define@key{ASYkeys}{keepAspect}[true]{%
+ \ifthenelse{\equal{#1}{true}}
+ {\ASYkeepAspecttrue}
+ {\ASYkeepAspectfalse}%
+}
+\def\ASYviewportwidth{}
+\define@key{ASYkeys}{viewportwidth}{%
+ \edef\ASYviewportwidth{\the\dimexpr#1\relax}%
+}
+\def\ASYviewportheight{}
+\define@key{ASYkeys}{viewportheight}{%
+ \edef\ASYviewportheight{\the\dimexpr#1\relax}%
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\define@key{ASYkeys}{inline}[true]{%
+ \ifthenelse{\equal{#1}{true}}
+ {\ASYinlinetrue}
+ {\ASYinlinefalse}%
+}
+\define@key{ASYkeys}{attach}[true]{%
+ \ifthenelse{\equal{#1}{true}}
+ {\ASYattachtrue}
+ {\ASYattachfalse}%
+}
+% \end{macrocode}
+%
+% \iffalse
+%</pkg>
+% \fi
+%
+% \Finale
+%
diff --git a/graphics/asymptote/doc/asy-latex.pdf b/graphics/asymptote/doc/asy-latex.pdf
new file mode 100644
index 0000000000..4d861a4e54
--- /dev/null
+++ b/graphics/asymptote/doc/asy-latex.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asy.1 b/graphics/asymptote/doc/asy.1
new file mode 100644
index 0000000000..d9380da919
--- /dev/null
+++ b/graphics/asymptote/doc/asy.1
@@ -0,0 +1,309 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH ASY 1 "1 Dec 2004"
+.SH NAME
+asy \- Asymptote: a script-based vector graphics language
+.SH SYNOPSIS
+.B asy
+.RI [ options ]
+.RI [ file \ ...]
+.SH DESCRIPTION
+\fBAsymptote\fP is a powerful descriptive vector graphics language for
+technical drawings, inspired by MetaPost but with an improved C++-like syntax.
+Asymptote provides for figures the same high-quality level of typesetting that
+LaTeX does for scientific text.
+.SH OPTIONS
+If no arguments are given, Asymptote runs in interactive mode.
+.PP
+If "\-" is given as the file argument, Asymptote reads from standard input.
+.PP
+A summary of options is included below. The effect of most options
+can be negated by prepending
+.B no
+to the option name.
+Default values for most options may also be entered in the
+file
+.B .asy/config.asy
+in the user's home directory using the long form:
+.PP
+ import settings;
+ batchView=true;
+.PP
+For a complete
+description, see the Info files.
+.TP
+.B \-V,\-View
+View output; command-line only.
+.TP
+.B \-a,\-align C|B|T|Z
+Center, Bottom, Top, or Zero page alignment [C].
+.TP
+.B \-aligndir pair
+Directional page alignment (overrides align) [(0,0)].
+.TP
+.B \-antialias n
+Antialiasing width for rasterized output [2].
+.TP
+.B \-arcballradius pixels
+Arcball radius [750].
+.TP
+.B \-auto3D
+Automatically activate 3D scene [true].
+.TP
+.B \-autobillboard
+3D labels always face viewer by default [true].
+.TP
+.B \-autoimport string
+Module to automatically import.
+.TP
+.B \-autoplain
+Enable automatic importing of plain [true].
+.TP
+.B \-autoplay
+Autoplay 3D animations [false].
+.TP
+.B \-autorotate
+Enable automatic PDF page rotation [false].
+.TP
+.B \-axes3
+Show 3D axes in PDF output [true].
+.TP
+.B \-batchMask
+Mask fpu exceptions in batch mode [false].
+.TP
+.B \-batchView
+View output in batch mode [false].
+.TP
+.B \-bw
+Convert all colors to black and white [false].
+.TP
+.B \-cd directory
+Set current directory; command-line only.
+.TP
+.B \-cmyk
+Convert rgb colors to cmyk [false].
+.TP
+.B \-c,\-command string
+Command to autoexecute.
+.TP
+.B \-compact
+Conserve memory at the expense of speed [false].
+.TP
+.B \-d,\-debug
+Enable debugging messages [false].
+.TP
+.B \-divisor n
+Garbage collect using purge(divisor=n) [2].
+.TP
+.B \-doubleclick ms
+Emulated double-click timeout [200].
+.TP
+.B \-embed
+Embed rendered preview image [true].
+.TP
+.B \-envmap
+Enable environment map image-based lighting (Experimental) [false].
+.TP
+.B \-exitonEOF
+Exit interactive mode on EOF [true].
+.TP
+.B \-fitscreen
+Fit rendered image to screen [true].
+.TP
+.B \-framedelay ms
+Additional frame delay [0].
+.TP
+.B \-framerate frames/s
+Animation speed [30].
+.TP
+.B \-globalwrite
+Allow write to other directory [false].
+.TP
+.B \-gray
+Convert all colors to grayscale [false].
+.TP
+.B \-h,\-help
+Show summary of options; command-line only.
+.TP
+.B \-historylines n
+Retain n lines of history [1000].
+.TP
+.B \-iconify
+Iconify rendering window [false].
+.TP
+.B \-inlineimage
+Generate inline embedded image [false].
+.TP
+.B \-inlinetex
+Generate inline TeX code [false].
+.TP
+.B \-interactiveMask
+Mask fpu exceptions in interactive mode [true].
+.TP
+.B \-interactiveView
+View output in interactive mode [true].
+.TP
+.B \-interactiveWrite
+Write expressions entered at the prompt to stdout [true].
+.TP
+.B \-k,\-keep
+Keep intermediate files [false].
+.TP
+.B \-keepaux
+Keep intermediate LaTeX .aux files [false].
+.TP
+.B \-level n
+Postscript level [3].
+.TP
+.B \-l,\-listvariables
+List available global functions and variables [false].
+.TP
+.B \-localhistory
+Use a local interactive history file [false].
+.TP
+.B \-loop
+Loop 3D animations [false].
+.TP
+.B \-m,\-mask
+Mask fpu exceptions; command-line only.
+.TP
+.B \-maxtile pair
+Maximum rendering tile size [(1024,768)].
+.TP
+.B \-maxvertices n
+Maximum number of vertices to queue [0].
+.TP
+.B \-maxviewport pair
+Maximum viewport size [(2048,2048)].
+.TP
+.B \-multiline
+Input code over multiple lines at the prompt [false].
+.TP
+.B \-multipleView
+View output from multiple batch-mode files [false].
+.TP
+.B \-multisample n
+Multisampling width for screen images [4].
+.TP
+.B \-offscreen
+Use offscreen rendering [false].
+.TP
+.B \-O,\-offset pair
+PostScript offset [(0,0)].
+.TP
+.B \-f,\-outformat format
+Convert each output file to specified format.
+.TP
+.B \-o,\-outname name
+Alternative output directory/filename.
+.TP
+.B \-p,\-parseonly
+Parse file [false].
+.TP
+.B \-pdfreload
+Automatically reload document in pdfviewer [false].
+.TP
+.B \-pdfreloaddelay usec
+Delay before attempting initial pdf reload [750000].
+.TP
+.B \-position pair
+Initial 3D rendering screen position [(0,0)].
+.TP
+.B \-prc
+Embed 3D PRC graphics in PDF output [true].
+.TP
+.B \-prompt string
+Prompt [> ].
+.TP
+.B \-prompt2 string
+Continuation prompt for multiline input [..].
+.TP
+.B \-q,\-quiet
+Suppress welcome text and noninteractive stdout [false].
+.TP
+.B \-render n
+Render 3D graphics using n pixels per bp (-1=auto) [-1].
+.TP
+.B \-resizestep step
+Resize step [1.2].
+.TP
+.B \-reverse
+reverse 3D animations [false].
+.TP
+.B \-rgb
+Convert cmyk colors to rgb [false].
+.TP
+.B \-safe
+Disable system call [true].
+.TP
+.B \-scroll n
+Scroll standard output n lines at a time [0].
+.TP
+.B \-spinstep deg/s
+Spin speed [60].
+.TP
+.B \-svgemulation
+Emulate unimplemented SVG shading [false].
+.TP
+.B \-tabcompletion
+Interactive prompt auto-completion [true].
+.TP
+.B \-tex engine
+latex|pdflatex|xelatex|lualatex|tex|pdftex|luatex|context|none [latex].
+.TP
+.B \-thick
+Render thick 3D lines [true].
+.TP
+.B \-thin
+Render thin 3D lines [true].
+.TP
+.B \-threads
+Use POSIX threads for 3D rendering [true].
+.TP
+.B \-toolbar
+Show 3D toolbar in PDF output [true].
+.TP
+.B \-s,\-translate
+Show translated virtual machine code [false].
+.TP
+.B \-twice
+Run LaTeX twice (to resolve references) [false].
+.TP
+.B \-twosided
+Use two-sided 3D lighting model for rendering [true].
+.TP
+.B \-u,\-user string
+General purpose user string.
+.TP
+.B \-v,\-verbose
+Increase verbosity level (can specify multiple times) [0].
+.TP
+.B \-version
+Show version; command-line only.
+.TP
+.B \-wait
+Wait for child processes to finish before exiting [false].
+.TP
+.B \-warn string
+Enable warning; command-line only.
+.TP
+.B \-where
+Show where listed variables are declared [false].
+.TP
+.B \-xasy
+Special interactive mode for xasy [false].
+.TP
+.B \-zoomfactor factor
+Zoom step factor [1.05].
+.TP
+.B \-zoomstep step
+Mouse motion zoom step [0.1].
+
+.SH SEE ALSO
+Asymptote is documented fully in the asymptote Info page.
+The manual can also be accessed in interactive mode with the "help" command.
+
+.SH AUTHOR
+Asymptote was written by Andy Hammerlindl, John Bowman, and Tom Prince.
+.PP
+This manual page was written by Hubert Chan for the Debian project (but may
+be used by others).
diff --git a/graphics/asymptote/doc/asy.1.begin b/graphics/asymptote/doc/asy.1.begin
new file mode 100644
index 0000000000..1a2232968e
--- /dev/null
+++ b/graphics/asymptote/doc/asy.1.begin
@@ -0,0 +1,32 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH ASY 1 "1 Dec 2004"
+.SH NAME
+asy \- Asymptote: a script-based vector graphics language
+.SH SYNOPSIS
+.B asy
+.RI [ options ]
+.RI [ file \ ...]
+.SH DESCRIPTION
+\fBAsymptote\fP is a powerful descriptive vector graphics language for
+technical drawings, inspired by MetaPost but with an improved C++-like syntax.
+Asymptote provides for figures the same high-quality level of typesetting that
+LaTeX does for scientific text.
+.SH OPTIONS
+If no arguments are given, Asymptote runs in interactive mode.
+.PP
+If "\-" is given as the file argument, Asymptote reads from standard input.
+.PP
+A summary of options is included below. The effect of most options
+can be negated by prepending
+.B no
+to the option name.
+Default values for most options may also be entered in the
+file
+.B .asy/config.asy
+in the user's home directory using the long form:
+.PP
+ import settings;
+ batchView=true;
+.PP
+For a complete
+description, see the Info files.
diff --git a/graphics/asymptote/doc/asy.1.end b/graphics/asymptote/doc/asy.1.end
new file mode 100644
index 0000000000..24586d9d40
--- /dev/null
+++ b/graphics/asymptote/doc/asy.1.end
@@ -0,0 +1,10 @@
+
+.SH SEE ALSO
+Asymptote is documented fully in the asymptote Info page.
+The manual can also be accessed in interactive mode with the "help" command.
+
+.SH AUTHOR
+Asymptote was written by Andy Hammerlindl, John Bowman, and Tom Prince.
+.PP
+This manual page was written by Hubert Chan for the Debian project (but may
+be used by others).
diff --git a/graphics/asymptote/doc/asyRefCard.pdf b/graphics/asymptote/doc/asyRefCard.pdf
new file mode 100644
index 0000000000..b439ce9f9a
--- /dev/null
+++ b/graphics/asymptote/doc/asyRefCard.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asyRefCard.tex b/graphics/asymptote/doc/asyRefCard.tex
new file mode 100644
index 0000000000..134acc4b88
--- /dev/null
+++ b/graphics/asymptote/doc/asyRefCard.tex
@@ -0,0 +1,558 @@
+% Reference Card for Asymptote
+
+% Copyright (c) 2011 John C. Bowman. May be freely distributed.
+% Thanks to Stephen Gildea for the multicolumn macro package
+% and Joseph H. Silverman for the C Reference card.
+
+%**start of header
+\newcount\columnsperpage
+
+\overfullrule=0pt
+
+% This file can be printed with 1, 2, or 3 columns per page (see below).
+% [For 2 or 3 columns, you'll need 6 and 8 point fonts.]
+% Specify how many you want here. Nothing else needs to be changed.
+
+\columnsperpage=2
+
+% This reference card is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+% This file is intended to be processed by plain TeX (TeX82).
+%
+% The final reference card has six columns, three on each side.
+% This file can be used to produce it in any of three ways:
+% 1 column per page
+% produces six separate pages, each of which needs to be reduced to 80%.
+% This gives the best resolution.
+% 2 columns per page
+% produces three already-reduced pages.
+% You will still need to cut and paste.
+% 3 columns per page
+% produces two pages which must be printed sideways to make a
+% ready-to-use 8.5 x 11 inch reference card.
+% For this you need a dvi device driver that can print sideways.
+% Which mode to use is controlled by setting \columnsperpage above.
+%
+% (reference card macros due to Stephen Gildea)
+%
+
+\def\versionnumber{1.1} % Version of this reference card
+\def\year{2014}
+\def\month{May}
+\def\version{\month\ \year\ v\versionnumber}
+
+\def\shortcopyrightnotice{\vskip .5ex plus 2 fill
+ \centerline{\small \copyright\ \year\ John C. Bowman
+ Permissions on back. v\versionnumber}}
+
+\def\copyrightnotice{
+\vskip 1ex plus 100 fill\begingroup\small
+\centerline{\version. Copyright \copyright\ \year\ John C. Bowman}
+
+Permission is granted to make and distribute copies of this card, with
+or without modifications, provided the copyright notice and this
+permission notice are preserved on all copies.
+\endgroup}
+
+% make \bye not \outer so that the \def\bye in the \else clause below
+% can be scanned without complaint.
+\def\bye{\par\vfill\supereject\end}
+
+\newdimen\intercolumnskip
+\newbox\columna
+\newbox\columnb
+
+\def\ncolumns{\the\columnsperpage}
+
+\message{[\ncolumns\space
+ column\if 1\ncolumns\else s\fi\space per page]}
+
+\def\scaledmag#1{ scaled \magstep #1}
+
+% This multi-way format was designed by Stephen Gildea
+% October 1986.
+\if 1\ncolumns
+ \hsize 4in
+ \vsize 10in
+ \voffset -.7in
+ \font\titlefont=\fontname\tenbf \scaledmag3
+ \font\headingfont=\fontname\tenbf \scaledmag2
+ \font\headingfonttt=\fontname\tentt \scaledmag2
+ \font\smallfont=\fontname\sevenrm
+ \font\smallsy=\fontname\sevensy
+
+ \footline{\hss\folio}
+ \def\makefootline{\baselineskip10pt\hsize6.5in\line{\the\footline}}
+\else
+ \hsize 3.2in
+ \vsize 7.95in
+ \hoffset -.75in
+ \voffset -.745in
+ \font\titlefont=cmbx10 \scaledmag2
+ \font\headingfont=cmbx10 \scaledmag1
+ \font\headingfonttt=cmtt10 \scaledmag1
+ \font\smallfont=cmr6
+ \font\smallsy=cmsy6
+ \font\eightrm=cmr8
+ \font\eightbf=cmbx8
+ \font\eightit=cmti8
+ \font\eighttt=cmtt8
+ \font\eightsy=cmsy8
+ \font\eightsl=cmsl8
+ \font\eighti=cmmi8
+ \font\eightex=cmex10 at 8pt
+ \textfont0=\eightrm
+ \textfont1=\eighti
+ \textfont2=\eightsy
+ \textfont3=\eightex
+ \def\rm{\fam0 \eightrm}
+ \def\bf{\eightbf}
+ \def\it{\eightit}
+ \def\tt{\eighttt}
+ \def\sl{\eightsl}
+ \normalbaselineskip=.8\normalbaselineskip
+ \normallineskip=.8\normallineskip
+ \normallineskiplimit=.8\normallineskiplimit
+ \normalbaselines\rm %make definitions take effect
+
+ \if 2\ncolumns
+ \let\maxcolumn=b
+ \footline{\hss\rm\folio\hss}
+ \def\makefootline{\vskip 2in \hsize=6.86in\line{\the\footline}}
+ \else \if 3\ncolumns
+ \let\maxcolumn=c
+ \nopagenumbers
+ \else
+ \errhelp{You must set \columnsperpage equal to 1, 2, or 3.}
+ \errmessage{Illegal number of columns per page}
+ \fi\fi
+
+ \intercolumnskip=.46in
+ \def\abc{a}
+ \output={%
+ % This next line is useful when designing the layout.
+ %\immediate\write16{Column \folio\abc\space starts with \firstmark}
+ \if \maxcolumn\abc \multicolumnformat \global\def\abc{a}
+ \else\if a\abc
+ \global\setbox\columna\columnbox \global\def\abc{b}
+ %% in case we never use \columnb (two-column mode)
+ \global\setbox\columnb\hbox to -\intercolumnskip{}
+ \else
+ \global\setbox\columnb\columnbox \global\def\abc{c}\fi\fi}
+ \def\multicolumnformat{\shipout\vbox{\makeheadline
+ \hbox{\box\columna\hskip\intercolumnskip
+ \box\columnb\hskip\intercolumnskip\columnbox}
+ \makefootline}\advancepageno}
+ \def\columnbox{\leftline{\pagebody}}
+
+ \def\bye{\par\vfill\supereject
+ \if a\abc \else\null\vfill\eject\fi
+ \if a\abc \else\null\vfill\eject\fi
+ \end}
+\fi
+
+% we won't be using math mode much, so redefine some of the characters
+% we might want to talk about
+\catcode`\^=12
+%\catcode`\_=12
+\catcode`\~=12
+
+\chardef\\=`\\
+\chardef\{=`\{
+\chardef\}=`\}
+\chardef\underscore=`\_
+
+\hyphenation{}
+
+\parindent 0pt
+\parskip .85ex plus .35ex minus .5ex
+
+\def\small{\smallfont\textfont2=\smallsy\baselineskip=.8\baselineskip}
+
+\outer\def\newcolumn{\vfill\eject}
+
+\outer\def\title#1{{\titlefont\centerline{#1}}\vskip 1ex plus .5ex}
+
+\outer\def\section#1{\par\filbreak
+ \vskip .5ex minus .1ex {\headingfont #1}\mark{#1}%
+ \vskip .3ex minus .1ex}
+
+\outer\def\librarysection#1#2{\par\filbreak
+ \vskip .5ex minus .1ex {\headingfont #1}\quad{\headingfonttt<#2>}\mark{#1}%
+ \vskip .3ex minus .1ex}
+
+
+\newdimen\keyindent
+
+\def\beginindentedkeys{\keyindent=1em}
+\def\endindentedkeys{\keyindent=0em}
+\def\begindoubleindentedkeys{\keyindent=2em}
+\def\enddoubleindentedkeys{\keyindent=1em}
+\endindentedkeys
+
+\def\paralign{\vskip\parskip\halign}
+
+\def\<#1>{$\langle${\rm #1}$\rangle$}
+
+\def\kbd#1{{\tt#1}\null} %\null so not an abbrev even if period follows
+
+\def\beginexample{\par\vskip1\jot
+\hrule width.5\hsize
+\vskip1\jot
+\begingroup\parindent=2em
+ \obeylines\obeyspaces\parskip0pt\tt}
+{\obeyspaces\global\let =\ }
+\def\endexample{\endgroup}
+
+\def\Example{\qquad{\sl Example\/}.\enspace\ignorespaces}
+
+\def\key#1#2{\leavevmode\hbox to \hsize{\vtop
+ {\hsize=.75\hsize\rightskip=1em
+ \hskip\keyindent\relax#1}\kbd{#2}\hfil}}
+
+\newbox\metaxbox
+\setbox\metaxbox\hbox{\kbd{M-x }}
+\newdimen\metaxwidth
+\metaxwidth=\wd\metaxbox
+
+\def\metax#1#2{\leavevmode\hbox to \hsize{\hbox to .75\hsize
+ {\hskip\keyindent\relax#1\hfil}%
+ \hskip -\metaxwidth minus 1fil
+ \kbd{#2}\hfil}}
+
+\def\threecol#1#2#3{\hskip\keyindent\relax#1\hfil&\kbd{#2}\quad
+ &\kbd{#3}\quad\cr}
+
+% Define Italic Names
+\def\makedef#1 {%
+\expandafter\edef\csname#1\endcsname{\hbox{\it#1\/}}}
+\makedef array
+\makedef arg
+\makedef const
+\makedef dim
+\makedef expr
+\makedef filename
+\makedef f
+\makedef format
+\makedef member
+\makedef name
+\makedef statement
+\makedef statements
+\makedef string
+\makedef type
+\makedef value
+\makedef var
+
+%**end of header
+
+
+\title{Asymptote Reference Card}
+
+\section{Program structure/functions}
+\halign{\tt#\hfil&\qquad#\hfil\cr
+import "\filename"&import module\cr
+import "\filename" as name&import filename as module name\cr
+include "\filename"&include verbatim text from file\cr
+\type\ \f(\type,\dots);&optional function declaration\cr
+\type\ \name;&variable declaration\cr
+\type\ \f(\type\ \arg,\dots) \{&function definition\cr
+\quad\statements\cr
+\quad return \value;\cr
+\}\cr
+}
+
+\section{Data types/declarations}
+\key{boolean (true or false)}{bool}
+\key{tri-state boolean (true, default, or false)}{bool3}
+\key{integer}{int}
+\key{float (double precision)}{real}
+\key{ordered pair (complex number)}{pair}
+\key{character string}{string}
+\key{fixed piecewise cubic Bezier spline}{path}
+\key{unresolved piecewise cubic Bezier spline}{guide}
+\key{color, line type/width/cap, font, fill rule}{pen}
+\key{label with position, alignment, pen attributes}{Label}
+\key{drawing canvas}{picture}
+\key{affine transform}{transform}
+\key{constant (unchanging) value}{const}
+\key{allocate in higher scope}{static}
+\key{no value}{void}
+\key{inhibit implicit argument casting}{explicit}
+\key{structure}{struct}
+\key{create name by data type}{typedef \type\ \name}
+
+\section{3D data types (import three;)}
+\key{ordered triple}{triple}
+\key{3D path}{path3}
+\key{3D guide}{guide3}
+\key{3D affine transform}{transform3}
+
+\section{Constants}
+\key{exponential form}{6.02e23}
+\key{\TeX\ string constant}{"abc\dots de"}
+\key{\TeX\ strings: special characters}{\\\\, \\"}
+\key{C strings: constant}{'abc\dots de'}
+\key{C strings: special characters}{\\\\, \\" \\' \\?}
+\key{C strings: newline, cr, tab, backspace}{\\n \\r \\t \\b}
+\key{C strings: octal, hexadecimal bytes}{\\0-\\377 \\x0-\\xFF}
+
+\section{Operators}
+\key{arithmetic operations}{+ - * /}
+\key{modulus (remainder)}{\%}
+\key{comparisons}{== != > >= < <=}
+\key{not}{!}
+\key{and or (conditional evaluation of RHS)}{\&\& ||}
+\key{and or xor}{\& | ^}
+\key{cast expression to type}{(\type) \expr}
+\key{increment decrement prefix operators}{++ --}
+\key{assignment operators}{+= -= *= /= \%=}
+\key{conditional expression}{\expr$_1$\ {?}\ \expr$_2$\ {:}\ \expr$_3$}
+\key{structure member operator}{\name.\member}
+\key{expression evaluation separator}{,}
+
+\section{Flow control}
+\key{statement terminator}{;}
+\key{block delimeters}{\{\quad\}}
+\key{comment delimeters}{/*\quad*/}
+\key{comment to end of line delimiter}{//}
+\key{exit from \kbd{while}/\kbd{do}/\kbd{for}}{break;}
+\key{next iteration of \kbd{while}/\kbd{do}/\kbd{for}}{continue;}
+\key{return value from function}{return \expr;}
+\key{terminate execution}{exit();}
+\key{abort execution with error message}{abort(string);}
+\metax{{\bf Flow constructions} ({\tt if/while/for/do})\hidewidth}{}
+\beginexample
+if(\expr)\ \statement
+else if(\expr)\ \statement
+else \statement
+\endexample
+\beginexample
+while(\expr)
+\quad\statement
+\endexample
+\beginexample
+for(\expr$_1$; \expr$_2$; \expr$_3$)
+\quad\statement
+\endexample
+\beginexample
+for(\type var : \array)
+\quad\statement
+\endexample
+\beginexample
+do \statement
+\quad while(\expr);
+\endexample
+
+\section{Arrays}
+\key{array}{\type[]\ \name;}
+\key{array element i}{\name[i]}
+\key{array indexed by elements of int array {\tt A}}{\name[A]}
+\key{anonymous array}{new \type[\dim]}
+\key{array containing {\tt n} deep copies of {\tt x}}{array(n,x)}
+\key{length}{\name.length}
+\key{cyclic flag}{\name.cyclic}
+\key{pop element {\tt x}}{\name.pop()}
+\key{push element {\tt x}}{\name.push(x)}
+\key{append array {\tt a}}{\name.append(a)}
+\key{insert rest arguments at index {\tt i}}{\name.insert(i,\dots)}
+\key{delete element at index {\tt i}}{\name.delete(i)}
+\key{delete elements with indices in [{\tt i},{\tt j}]}{\name.delete(i,j)}
+\key{delete all elements}{\name.delete()}
+\key{test whether element n is initialized}{\name.initialized(n)}
+\key{array of indices of initialized elements}{\name.keys}
+\key{complement of int array in {\tt \{0,\dots,n-1\}}}{complement(a,n)}
+\key{deep copy of array {\tt a}}{copy(a)}
+\key{array {\tt \{0,1,\dots,n-1\}}}{sequence(n)}
+\key{array {\tt \{n,n+1,\dots,m\}}}{sequence(n,m)}
+\key{array {\tt \{n-1,n-2,\dots,0\}}}{reverse(n)}
+\key{array {\tt \{f(0),f(1),\dots,f(n-1)\}}}{sequence(f,n)}
+\key{array obtained by applying {\tt f} to array {\tt a}}{map(f,a)}
+\key{uniform partition of [{\tt a},{\tt b}] into n intervals}{uniform(a,b,n)}
+\key{concat specified 1D arrays}{concat(a,b,\dots)}
+\key{return sorted array}{sort(a)}
+\key{return array sorted using ordering {\tt less}}{sort(a,{\tt less})}
+\key{search sorted array {\tt a} for key}{search(a,key)}
+\key{index of first true value of bool array {\tt a}}{find(a)}
+\key{index of nth true value of bool array {\tt a}}{find(a,n)}
+
+\section{Initialization}
+\key{initialize variable}{\type\ \name=\value;}
+\key{initialize array}{\type[]\ \name=\{\dots\};}
+
+\section{path connectors}
+\key{straight segment}{--}
+\key{Bezi\'er segment with implicit control points}{..}
+\key{Bezi\'er segment with explicit control points}{..controls c0 and c1..}
+\key{concatenate}{\&}
+\key{lift pen}{^^}
+\key{..tension atleast 1..}{::}
+\key{..tension atleast infinity..}{---}
+
+\section{Labels}
+\key{implicit cast of string {\tt s} to Label}{s}
+\key{Label {\tt s} with relative position and alignment}{Label(s,real,pair)}
+\key{Label {\tt s} with absolute position and alignment}{Label(s,pair,pair)}
+\key{Label {\tt s} with specified pen}{Label(s,pen)}
+
+\section{draw commands}
+\key{draw path with current pen}{draw(path)}
+\key{draw path with pen}{draw(path,pen)}
+\key{draw labeled path}{draw(Label,path)}
+\key{draw arrow with pen}{draw(path,pen,Arrow)}
+\key{draw path on picture}{draw(picture,path)}
+\key{draw visible portion of line through two pairs}{drawline(pair,pair)}
+
+\section{fill commands}
+\key{fill path with current pen}{fill(path)}
+\key{fill path with pen}{fill(path,pen)}
+\key{fill path on picture}{fill(picture,path)}
+
+\section{label commands}
+\key{label a pair with optional alignment z}{label(Label,pair,{\tt z})}
+\key{label a path with optional alignment z}{label(Label,path,{\tt z})}
+\key{add label to picture}{label(picture,Label)}
+
+\section{clip commands}
+\key{clip to path}{clip(path)}
+\key{clip to path with fill rule}{clip(path,pen)}
+\key{clip picture to path}{clip(picture,path)}
+
+\section{pens}
+\key{Grayscale pen from value in [0,1]}{gray(g)}
+\key{RGB pen from values in [0,1]}{rgb(r,g,b)}
+\key{CMYK pen from values in [0,1]}{cmyk(r,g,b)}
+\key{RGB pen from heximdecimal string]}{rgb(string)}
+\key{heximdecimal string from rgb pen]}{hex(pen)}
+\key{hsv pen from values in [0,1]}{hsv(h,s,v)}
+\key{invisible pen}{invisible}
+\key{default pen}{defaultpen}
+\key{current pen}{currentpen}
+\key{solid pen}{solid}
+\key{dotted pen}{dotted}
+\key{wide dotted current pen}{Dotted}
+\key{wide dotted pen}{Dotted(pen)}
+\key{dashed pen}{dashed}
+\key{long dashed pen}{longdashed}
+\key{dash dotted pen}{dashdotted}
+\key{long dash dotted pen}{longdashdotted}
+\key{PostScript butt line cap}{squarecap}
+\key{PostScript round line cap}{roundcap}
+\key{PostScript projecting square line cap}{extendcap}
+\key{miter join}{miterjoin}
+\key{round join}{roundjoin}
+\key{bevel join}{beveljoin}
+\key{pen with miter limit}{miterlimit(real)}
+\key{zero-winding fill rule}{zerowinding}
+\key{even-odd fill rule}{evenodd}
+\key{align to character bounding box (default)}{nobasealign}
+\key{align to \TeX\ baseline}{basealign}
+\key{pen with font size (pt)}{fontsize(real)}
+\key{LaTeX pen from encoding,family,series,shape}{font(strings)}
+\key{\TeX\ pen}{font(string)}
+\key{scaled \TeX\ pen}{font(string,real)}
+\key{PostScript font from strings}{Courier(series,shape)}
+\key{pen with opacity in [0,1]}{opacity(real)}
+\key{construct pen nib from polygonal path}{makepen(path)}
+\key{pen mixing operator}{+}
+
+\section{path operations}
+\key{number of segments in path {\tt p}}{length(p)}
+\key{number of nodes in path {\tt p}}{size(p)}
+\key{is path {\tt p} cyclic?}{cyclic(p)}
+\key{is segment {\tt i} of path {\tt p} straight?}{straight(p,i)}
+\key{is path {\tt p} straight?}{piecewisestraight(p)}
+\key{coordinates of path {\tt p} at time {\tt t}}{point(p,t)}
+\key{direction of path {\tt p} at time {\tt t}}{dir(p,t)}
+\key{direction of path {\tt p} at {\tt length(p)}}{dir(p)}
+\key{unit(dir(p)+dir(q))}{dir(p,q)}
+\key{acceleration of path {\tt p} at time {\tt t}}{accel(p,t)}
+\key{radius of curvature of path {\tt p} at time {\tt t}}{radius(p,t)}
+\key{precontrol point of path {\tt p} at time {\tt t}}{precontrol(p,t)}
+\key{postcontrol point of path {\tt p} at time {\tt t}}{postcontrol(p,t)}
+\key{arclength of path {\tt p}}{arclength(p)}
+\key{time at which {\tt arclength(p)=L}}{arctime(p,L)}
+\key{point on path {\tt p} at arclength {\tt L}}{arcpoint(p,L)}
+\key{first value {\tt t} at which {\tt dir(p,t)=z}}{dirtime(p,z)}
+\key{time {\tt t} at relative fraction {\tt l} of {\tt arclength(p)}}{reltime(p,l)}
+\key{point at relative fraction {\tt l} of {\tt arclength(p)}}{relpoint(p,l)}
+\key{point midway along arclength of {\tt p}}{midpoint(p)}
+\key{path running backwards along {\tt p}}{reverse(p)}
+\key{subpath of {\tt p} between times {\tt a} and {\tt b}}{subpath(p,a,b)}
+\key{times for one intersection of paths {\tt p} and {\tt q}}{intersect(p,q)}
+\key{times at which {\tt p} reaches minimal extents}{mintimes(p)}
+\key{times at which {\tt p} reaches maximal extents}{maxtimes(p)}
+\key{intersection times of paths {\tt p} and {\tt q}}{intersections(p,q)}
+\key{intersection times of path {\tt p} with `{\tt --a--b--}'}{intersections(p,a,b)}
+\key{intersection times of path {\tt p} crossing $x=${\tt x}}{times(p,x)}
+\key{intersection times of path {\tt p} crossing $y=${\tt z.y}}{times(p,z)}
+\key{intersection point of paths {\tt p} and {\tt q}}{intersectionpoint(p,q)}
+\key{intersection points of {\tt p} and {\tt q}}{intersectionpoints(p,q)}
+\key{intersection of extension of {\tt P--Q} and {\tt p--q}}{extension(P,Q,p,q)}
+\key{lower left point of bounding box of path {\tt p}}{min(p)}
+\key{upper right point of bounding box of path {\tt p}}{max(p)}
+\key{subpaths of {\tt p} split by {\tt n}th cut of {\tt knife}}{cut(p,knife,n)}
+\key{winding number of path {\tt p} about pair {\tt z}}{windingnumber(p,z)}
+\key{pair {\tt z} lies within path {\tt p}?}{interior(p,z)}
+\key{pair {\tt z} lies within or on path {\tt p}?}{inside(p,z)}
+\key{path surrounding region bounded by paths}{buildcycle(\dots)}
+\key{path filled by \tt{draw(g,p)}}{strokepath(g,p)}
+\key{unit square with lower-left vertex at origin}{unitsquare}
+\key{unit circle centered at origin}{unitcircle}
+\key{circle of radius {\tt r} about {\tt c}}{circle(c,r)}
+\key{arc of radius {\tt r} about {\tt c} from angle {\tt a} to {\tt b}}{arc(c,r,a,b)}
+\key{unit {\tt n}-sided polygon}{polygon(n)}
+\key{unit {\tt n}-point cyclic cross}{cross(n)}
+
+\section{pictures}
+\key{add picture {\tt pic} to currentpicture}{add(pic)}
+\key{add picture {\tt pic} about pair {\tt z}}{add(pic,z)}
+
+\section{affine transforms}
+\key{identity transform}{identity()}
+\key{shift by values}{shift(real,real)}
+\key{shift by pair}{shift(pair)}
+\key{scale by {\tt x} in the $x$ direction}{xscale(x)}
+\key{scale by {\tt y} in the $y$ direction}{yscale(y)}
+\key{scale by {\tt x} in both directions}{scale(x)}
+\key{scale by real values {\tt x} and {\tt y}}{scale(x,y)}
+\key{map $(x,y) \rightarrow (x+${\tt s}$y,y)$}{slant(s)}
+\key{rotate by real {\tt angle} in degrees about pair {\tt z}}{rotate(angle,z=(0,0))}
+\key{reflect about line from {\tt P--Q}}{reflect(P,Q)}
+
+\section{string operations}
+\key{concatenate operator}{+}
+\key{string length}{length(string)}
+\key{position $\ge$ {\tt pos} of first occurence of {\tt t} in {\tt s}}{find({\tt s},{\tt t},pos=0)}
+\key{position $\le$ {\tt pos} of last occurence of {\tt t} in {\tt s}}{rfind({\tt s},{\tt t},pos=-1)}
+\key{string with {\tt t} inserted in {\tt s} at {\tt pos}}{insert({\tt s},{\tt pos},{\tt t})}
+\key{string {\tt s} with {\tt n} characters at {\tt pos} erased}{erase({\tt s},{\tt pos},{\tt n})}
+\key{substring of string {\tt s} of length {\tt n} at {\tt pos}}{substr({\tt s},{\tt pos},{\tt n})}
+\key{string {\tt s} reversed}{reverse({\tt s})}
+\key{string {\tt s} with {\tt before} changed to {\tt after}}{replace({\tt s},{\tt before},{\tt after})}
+\key{string {\tt s} translated via {\tt \{\{before,after\},\dots\}}}{replace({\tt
+s},string [][] table)}
+\key{format {\tt x} using C-style format string {\tt s} }{format({\tt s},x)}
+\key{casts hexadecimal string to an integer}{hex(s)}
+\key{casts {\tt x} to string using precision {\tt digits}}{string(x,digits=realDigits)}
+\key{current time formatted by {\tt format}}{time(format="\%a \%b \%d \%T \%Z \%Y")}
+\key{time in seconds of string {\tt t} using {\tt format}}{seconds(t,format)}
+\key{string corresponding to {\tt seconds} using {\tt format}}{time(seconds,format)}
+\key{split {\tt s} into strings separated by {\tt delimiter}}{split(s,delimiter="")}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%% END LIBRARIES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% This goes at the bottom of the last page (column 6)
+\copyrightnotice
+%
+
+\bye
+
+% Local variables:
+% compile-command: "tex AsyRefCard"
+% End:
+
+
+
+
diff --git a/graphics/asymptote/doc/asycolors.sty b/graphics/asymptote/doc/asycolors.sty
new file mode 100644
index 0000000000..31031c730f
--- /dev/null
+++ b/graphics/asymptote/doc/asycolors.sty
@@ -0,0 +1,72 @@
+\usepackage{color}
+\definecolor{cyan}{cmyk}{1,0,0,0}
+\definecolor{magenta}{cmyk}{0,1,0,0}
+\definecolor{yellow}{cmyk}{0,0,1,0}
+\definecolor{black}{cmyk}{0,0,0,1}
+
+\definecolor{white}{cmyk}{0,0,0,0}
+\definecolor{gray}{cmyk}{0,0,0,0.5}
+
+\definecolor{red}{cmyk}{0,1,1,0}
+\definecolor{green}{cmyk}{1,0,1,0}
+\definecolor{blue}{cmyk}{1,1,0,0}
+
+\definecolor{palered}{cmyk}{0,0.25,0.25,0}
+\definecolor{palegreen}{cmyk}{0.25,0,0.25,0}
+\definecolor{paleblue}{cmyk}{0.25,0.25,0,0}
+\definecolor{palecyan}{cmyk}{0.25,0,0,0}
+\definecolor{palemagenta}{cmyk}{0,0.25,0,0}
+\definecolor{paleyellow}{cmyk}{0,0,0.25,0}
+\definecolor{palegray}{cmyk}{0,0,0,0.05}
+\definecolor{lightred}{cmyk}{0,0.5,0.5,0}
+\definecolor{lightgreen}{cmyk}{0.5,0,0.5,0}
+\definecolor{lightblue}{cmyk}{0.5,0.5,0,0}
+\definecolor{lightcyan}{cmyk}{0.5,0,0,0}
+\definecolor{lightmagenta}{cmyk}{0,0.5,0,0}
+\definecolor{lightyellow}{cmyk}{0,0,0.5,0}
+\definecolor{lightgray}{cmyk}{0,0,0,0.1}
+\definecolor{mediumred}{cmyk}{0,0.75,0.75,0}
+\definecolor{mediumgreen}{cmyk}{0.75,0,0.75,0}
+\definecolor{mediumblue}{cmyk}{0.75,0.75,0,0}
+\definecolor{mediumcyan}{cmyk}{0.75,0,0,0}
+\definecolor{mediummagenta}{cmyk}{0,0.75,0,0}
+\definecolor{mediumyellow}{cmyk}{0,0,0.75,0}
+\definecolor{mediumgray}{cmyk}{0,0,0,0.25}
+\definecolor{heavyred}{cmyk}{0,1,1,0.25}
+\definecolor{heavygreen}{cmyk}{1,0,1,0.25}
+\definecolor{heavyblue}{cmyk}{1,1,0,0.25}
+\definecolor{heavycyan}{cmyk}{1,0,0,0.25}
+\definecolor{heavymagenta}{cmyk}{0,1,0,0.25}
+\definecolor{lightolive}{cmyk}{0,0,1,0.25}
+\definecolor{heavygray}{cmyk}{0,0,0,0.75}
+\definecolor{deepred}{cmyk}{0,1,1,0.5}
+\definecolor{deepgreen}{cmyk}{1,0,1,0.5}
+\definecolor{deepblue}{cmyk}{1,1,0,0.5}
+\definecolor{deepcyan}{cmyk}{1,0,0,0.5}
+\definecolor{deepmagenta}{cmyk}{0,1,0,0.5}
+\definecolor{olive}{cmyk}{0,0,1,0.5}
+\definecolor{deepgray}{cmyk}{0,0,0,0.9}
+\definecolor{darkred}{cmyk}{0,1,1,0.75}
+\definecolor{darkgreen}{cmyk}{1,0,1,0.75}
+\definecolor{darkblue}{cmyk}{1,1,0,0.75}
+\definecolor{darkcyan}{cmyk}{1,0,0,0.75}
+\definecolor{darkmagenta}{cmyk}{0,1,0,0.75}
+\definecolor{darkolive}{cmyk}{0,0,1,0.75}
+\definecolor{darkgray}{cmyk}{0,0,0,0.95}
+\definecolor{orange}{cmyk}{0,0.5,1,0}
+\definecolor{fuchsia}{cmyk}{0,1,0.5,0}
+\definecolor{chartreuse}{cmyk}{0.5,0,1,0}
+\definecolor{springgreen}{cmyk}{1,0,0.5,0}
+\definecolor{purple}{cmyk}{0.5,1,0,0}
+\definecolor{royalblue}{cmyk}{1,0.5,0,0}
+\definecolor{salmon}{cmyk}{0,0.5,0.5,0}
+\definecolor{brown}{cmyk}{0,1,1,0.5}
+\definecolor{darkbrown}{cmyk}{0,1,1,0.75}
+\definecolor{pink}{cmyk}{0,0.25,0,0}
+\definecolor{palegrey}{cmyk}{0,0,0,0.05}
+\definecolor{lightgrey}{cmyk}{0,0,0,0.1}
+\definecolor{mediumgrey}{cmyk}{0,0,0,0.25}
+\definecolor{grey}{cmyk}{0,0,0,0.5}
+\definecolor{heavygrey}{cmyk}{0,0,0,0.5}
+\definecolor{deepgrey}{cmyk}{0,0,0,0.9}
+\definecolor{darkgrey}{cmyk}{0,0,0,0.95}
diff --git a/graphics/asymptote/doc/asymptote.pdf b/graphics/asymptote/doc/asymptote.pdf
new file mode 100644
index 0000000000..06c2a69fc4
--- /dev/null
+++ b/graphics/asymptote/doc/asymptote.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asymptote.sty b/graphics/asymptote/doc/asymptote.sty
new file mode 100644
index 0000000000..302e6aebe3
--- /dev/null
+++ b/graphics/asymptote/doc/asymptote.sty
@@ -0,0 +1,405 @@
+%%
+%% This is file `asymptote.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% asy-latex.dtx (with options: `pkg')
+%% ____________________________
+%% The ASYMPTOTE package
+%%
+%% (C) 2003 Tom Prince
+%% (C) 2003-2016 John Bowman
+%% (C) 2010 Will Robertson
+%%
+%% Adapted from comment.sty
+%%
+%% Licence: GPL2+
+%%
+\ProvidesPackage{asymptote}
+ [2016/11/26 v1.33 Asymptote style file for LaTeX]
+\def\Asymptote{{\tt Asymptote}}
+\InputIfFileExists{\jobname.pre}{}{}
+\newbox\ASYbox
+\newdimen\ASYdimen
+\newcounter{asy}
+\newwrite\AsyStream
+\newwrite\AsyPreStream
+\newif\ifASYinline
+\newif\ifASYattach
+\newif\ifASYkeepAspect
+\ASYkeepAspecttrue
+\RequirePackage{keyval}
+\RequirePackage{ifthen}
+\RequirePackage{color,graphicx}
+\IfFileExists{ifpdf.sty}{
+ \RequirePackage{ifpdf}
+}{
+ \expandafter\newif\csname ifpdf\endcsname
+ \ifx\pdfoutput\@undefined\else
+ \ifcase\pdfoutput\else
+ \pdftrue
+ \fi
+ \fi
+}
+\IfFileExists{ifxetex.sty}{
+ \RequirePackage{ifxetex}
+}{
+ \expandafter\newif\csname ifxetex\endcsname
+ \ifx\XeTeXversion\@undefined\else
+ \xetextrue
+ \fi
+}
+\IfFileExists{catchfile.sty}{
+ \RequirePackage{catchfile}
+}{
+ \newcommand\CatchFileDef[3]{%
+ \begingroup
+ \everyeof{%
+ \ENDCATCHFILEMARKER
+ \noexpand
+ }%
+ \long\def\@tempa####1\ENDCATCHFILEMARKER{%
+ \endgroup
+ \def##1{####1}%
+ }%
+ ##3%
+ \expandafter\@tempa\@@input ##2\relax
+ }
+}
+\newif\if@asy@attachfile@loaded
+\AtBeginDocument{%
+ \@ifpackageloaded{attachfile2}{\@asy@attachfile@loadedtrue}{}%
+ \let\asy@check@attachfile\asy@check@attachfile@loaded
+}
+\newcommand\asy@check@attachfile@loaded{%
+ \if@asy@attachfile@loaded\else
+ \PackageError{asymptote}{You must load the attachfile2 package}{^^J%
+ You have requested the [attach] option for some or all of your^^J%
+ Asymptote graphics, which requires the attachfile2 package.^^J%
+ Please load it in the document preamble.^^J%
+ }%
+ \fi
+}
+\newcommand\asy@check@attachfile{%
+ \AtBeginDocument{\asy@check@attachfile@loaded}%
+ \let\asy@check@attachfile\@empty
+}
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+\DeclareOption{inline}{%
+ \ASYinlinetrue
+}
+\DeclareOption{attach}{%
+ \asy@check@attachfile
+ \ASYattachtrue
+}
+\ProcessOptions*
+\def\asylatexdir{}
+\def\asydir{}
+\def\ASYasydir{}
+\def\ASYprefix{}
+\newif\ifASYPDF
+\ifxetex
+ \ASYPDFtrue
+ \usepackage{everypage}
+\else
+ \ifpdf
+ \ASYPDFtrue
+ \fi
+\fi
+\ifASYPDF
+ \def\AsyExtension{pdf}
+\else
+ \def\AsyExtension{eps}
+\fi
+\def\unquoteJobname#1"#2"#3\relax{%
+ \def\rawJobname{#1}%
+ \ifx\rawJobname\empty
+ \def\rawJobname{#2}%
+ \fi
+}
+\expandafter\unquoteJobname\jobname""\relax
+\def\fixstar#1*#2\relax{%
+ \def\argtwo{#2}%
+ \ifx\argtwo\empty
+ \gdef\Jobname{#1}%
+ \else
+ \fixstar#1-#2\relax
+ \fi
+}
+\expandafter\fixstar\rawJobname*\relax
+\def\Ginclude@eps#1{%
+ \message{<#1>}%
+ \bgroup
+ \def\@tempa{!}%
+ \dimen@\Gin@req@width
+ \dimen@ii.1bp\relax
+ \divide\dimen@\dimen@ii
+ \@tempdima\Gin@req@height
+ \divide\@tempdima\dimen@ii
+ \special{PSfile=#1\space
+ llx=\Gin@llx\space
+ lly=\Gin@lly\space
+ urx=\Gin@urx\space
+ ury=\Gin@ury\space
+ \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\space\fi
+ \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\space\fi
+ \ifGin@clip clip\fi}%
+ \egroup
+}
+\immediate\openout\AsyPreStream=\jobname.pre\relax
+\AtEndDocument{\immediate\closeout\AsyPreStream}
+\def\WriteAsyLine#1{%
+ \immediate\write\AsyStream{\detokenize{#1}}%
+}
+\def\globalASYdefs{}
+\def\WriteGlobalAsyLine#1{%
+ \expandafter\g@addto@macro
+ \expandafter\globalASYdefs
+ \expandafter{\detokenize{#1^^J}}%
+}
+\def\ProcessAsymptote#1{%
+ \begingroup
+ \def\CurrentAsymptote{#1}%
+ \let\do\@makeother \dospecials
+ \@makeother\^^L% and whatever other special cases
+ \catcode`\ =10
+ \endlinechar`\^^M \catcode`\^^M=12 \xAsymptote
+}
+\begingroup
+ \catcode`\^^M=12 \endlinechar=-1\relax%
+ \gdef\xAsymptote{%
+ \expandafter\ProcessAsymptoteLine%
+ }
+ \gdef\ProcessAsymptoteLine#1^^M{%
+ \def\@tempa{#1}%
+ {%
+ \escapechar=-1\relax%
+ \xdef\@tempb{\string\\end\string\{\CurrentAsymptote\string\}}%
+ }%
+ \ifx\@tempa\@tempb%
+ \edef\next{\endgroup\noexpand\end{\CurrentAsymptote}}%
+ \else%
+ \ThisAsymptote{#1}%
+ \let\next\ProcessAsymptoteLine%
+ \fi%
+ \next%
+ }
+\endgroup
+\def\asy@init{%
+ \def\ASYlatexdir{}%
+ \ifx\asylatexdir\empty\else
+ \def\ASYlatexdir{\asylatexdir/}%
+ \fi
+ \ifx\asydir\empty\else
+ \def\ASYasydir{\asydir/}%
+ \fi
+ \def\ASYprefix{\ASYlatexdir\ASYasydir}%
+}
+\newcommand\asy[1][]{%
+ \stepcounter{asy}%
+ \setkeys{ASYkeys}{#1}%
+ \ifASYattach
+ \ASYinlinefalse
+ \fi
+ \asy@init
+ \immediate\write\AsyPreStream{%
+ \noexpand\InputIfFileExists{%
+ \ASYprefix\noexpand\jobname-\the\c@asy.pre}{}{}%
+ }%
+ \asy@write@graphic@header
+ \let\ThisAsymptote\WriteAsyLine
+ \ProcessAsymptote{asy}%
+}
+\def\endasy{%
+ \asy@finalise@stream
+ \asy@input@graphic
+}
+\def\asy@write@graphic@header{%
+ \immediate\openout\AsyStream=\ASYasydir\jobname-\the\c@asy.asy\relax
+ \gdef\AsyFile{\ASYprefix\Jobname-\the\c@asy}%
+ \immediate\write\AsyStream{%
+ if(!settings.multipleView) settings.batchView=false;^^J%
+ \ifxetex
+ settings.tex="xelatex";^^J%
+ \else\ifASYPDF
+ settings.tex="pdflatex";^^J%
+ \fi\fi
+ \ifASYinline
+ settings.inlinetex=true;^^J%
+ deletepreamble();^^J%
+ \fi
+ defaultfilename="\Jobname-\the\c@asy";^^J%
+ if(settings.render < 0) settings.render=4;^^J%
+ settings.outformat="";^^J%
+ \ifASYattach
+ settings.inlineimage=false;^^J%
+ settings.embed=false;^^J%
+ settings.toolbar=true;^^J%
+ \else
+ settings.inlineimage=true;^^J%
+ settings.embed=true;^^J%
+ settings.toolbar=false;^^J%
+ viewportmargin=(2,2);^^J%
+ \fi
+ \globalASYdefs
+ }%
+}
+\def\asy@expand@keepAspect{%
+ \ifASYkeepAspect keepAspect=true%
+ \else keepAspect=false%
+ \fi%
+}
+\def\asy@finalise@stream{%
+ \ifx\ASYwidth\@empty
+ \ifx\ASYheight\@empty
+ % write nothing!
+ \else
+ \immediate\write\AsyStream{size(0,\ASYheight,\asy@expand@keepAspect);}%
+ \fi
+ \else
+ \ifx\ASYheight\@empty
+ \immediate\write\AsyStream{size(\ASYwidth,0,\asy@expand@keepAspect);}%
+ \else
+ \immediate\write\AsyStream{size(\ASYwidth,\ASYheight,\asy@expand@keepAspect);}%
+ \fi
+ \fi
+ \ifx\ASYviewportwidth\@empty
+ \ifx\ASYviewportheight\@empty
+ % write nothing!
+ \else
+ \immediate\write\AsyStream{viewportsize=(0,\ASYviewportheight);}%
+ \fi
+ \else
+ \ifx\ASYviewportheight\@empty
+ \immediate\write\AsyStream{viewportsize=(\ASYviewportwidth,0);}%
+ \else
+ \immediate\write\AsyStream{%
+ viewportsize=(\ASYviewportwidth,\ASYviewportheight);}%
+ \fi
+ \fi
+ \immediate\closeout\AsyStream
+}
+\def\asy@input@graphic{%
+ \ifASYinline
+ \IfFileExists{"\AsyFile.tex"}{%
+ \catcode`:=12\relax
+ \@@input"\AsyFile.tex"\relax
+ }{%
+ \PackageWarning{asymptote}{file `\AsyFile.tex' not found}%
+ }%
+ \else
+ \IfFileExists{"\AsyFile.\AsyExtension"}{%
+ \ifASYattach
+ \ifASYPDF
+ \IfFileExists{"\AsyFile+0.pdf"}{%
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile+0".pdf}}%
+ }{%
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile".pdf}}%
+ }%
+ \else
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile.eps"}}%
+ \fi
+ \textattachfile{\AsyFile.\AsyExtension}{\phantom{\copy\ASYbox}}%
+ \vskip-\ht\ASYbox
+ \indent
+ \box\ASYbox
+ \else
+ \ifASYPDF
+ \includegraphics[hiresbb]{"\AsyFile".pdf}%
+ \else
+ \includegraphics[hiresbb]{"\AsyFile.eps"}%
+ \fi
+ \fi
+ }{%
+ \IfFileExists{"\AsyFile.tex"}{%
+ \catcode`:=12
+ \@@input"\AsyFile.tex"\relax
+ }{%
+ \PackageWarning{asymptote}{%
+ file `\AsyFile.\AsyExtension' not found%
+ }%
+ }%
+ }%
+ \fi
+}
+\def\asydef{%
+ \let\ThisAsymptote\WriteGlobalAsyLine
+ \ProcessAsymptote{asydef}%
+}
+\newcommand\asyinclude[2][]{%
+ \begingroup
+ \stepcounter{asy}%
+ \setkeys{ASYkeys}{#1}%
+ \ifASYattach
+ \ASYinlinefalse
+ \fi
+ \asy@init
+ \immediate\write\AsyPreStream{%
+ \noexpand\InputIfFileExists{%
+ \ASYprefix\noexpand\jobname-\the\c@asy.pre}{}{}%
+ }%
+ \asy@write@graphic@header
+ \IfFileExists{#2.asy}{%
+ \CatchFileDef\@tempa{#2.asy}{%
+ \let\do\@makeother
+ \dospecials
+ \endlinechar=10\relax
+ }%
+ }{%
+ \IfFileExists{#2}{%
+ \CatchFileDef\@tempa{#2}{%
+ \let\do\@makeother
+ \dospecials
+ \endlinechar=10\relax
+ }%
+ }{%
+ \PackageWarning{asymptote}{file #2 not found}%
+ \def\@tempa{}%
+ }%
+ }%
+ \immediate\write\AsyStream{\unexpanded\expandafter{\@tempa}}%
+ \asy@finalise@stream
+ \asy@input@graphic
+ \endgroup
+}
+\newcommand{\ASYanimategraphics}[5][]{%
+ \IfFileExists{_#3.pdf}{%
+ \animategraphics[{#1}]{#2}{_#3}{#4}{#5}%
+ }{}%
+}
+\newcommand\asysetup[1]{\setkeys{ASYkeys}{#1}}
+\define@key{ASYkeys}{dir}{%
+ \def\asydir{#1}%
+}
+\def\ASYwidth{}
+\define@key{ASYkeys}{width}{%
+ \edef\ASYwidth{\the\dimexpr#1\relax}%
+}
+\def\ASYheight{}
+\define@key{ASYkeys}{height}{%
+ \edef\ASYheight{\the\dimexpr#1\relax}%
+}
+\define@key{ASYkeys}{keepAspect}[true]{%
+ \ifthenelse{\equal{#1}{true}}
+ {\ASYkeepAspecttrue}
+ {\ASYkeepAspectfalse}%
+}
+\def\ASYviewportwidth{}
+\define@key{ASYkeys}{viewportwidth}{%
+ \edef\ASYviewportwidth{\the\dimexpr#1\relax}%
+}
+\def\ASYviewportheight{}
+\define@key{ASYkeys}{viewportheight}{%
+ \edef\ASYviewportheight{\the\dimexpr#1\relax}%
+}
+\define@key{ASYkeys}{inline}[true]{%
+ \ifthenelse{\equal{#1}{true}}
+ {\ASYinlinetrue}
+ {\ASYinlinefalse}%
+}
+\define@key{ASYkeys}{attach}[true]{%
+ \ifthenelse{\equal{#1}{true}}
+ {\ASYattachtrue}
+ {\ASYattachfalse}%
+}
diff --git a/graphics/asymptote/doc/asymptote.texi b/graphics/asymptote/doc/asymptote.texi
new file mode 100644
index 0000000000..d231d55cd0
--- /dev/null
+++ b/graphics/asymptote/doc/asymptote.texi
@@ -0,0 +1,9954 @@
+\input texinfo @c -*-texinfo-*-
+@setfilename asymptote.info
+@settitle Asymptote: the Vector Graphics Language
+@include version.texi
+@finalout
+
+@codequoteundirected on
+
+@copying
+This file documents @code{Asymptote}, version @value{VERSION}.
+
+@url{http://asymptote.sourceforge.net}
+
+Copyright @copyright{} 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the @acronym{GNU} Lesser General Public License (see the
+file LICENSE in the top-level source directory).
+
+@end quotation
+@end copying
+
+@dircategory Languages
+@direntry
+* asymptote: (asymptote/asymptote). Vector graphics language.
+@end direntry
+
+@titlepage
+@title Asymptote: the Vector Graphics Language
+@subtitle For version @value{VERSION}
+@sp 1
+@center @image{logo}
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+
+@end titlepage
+
+@c So the toc is printed at the start.
+@contents
+
+@ifnottex
+@node Top, Description, (dir), (dir)
+@top Asymptote
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Description:: What is @code{Asymptote}?
+* Installation:: Downloading and installing
+* Tutorial:: Getting started
+* Drawing commands:: Four primitive graphics commands
+* Bezier curves:: Path connectors and direction specifiers
+* Programming:: The @code{Asymptote} vector graphics language
+* LaTeX usage:: Embedding @code{Asymptote} commands within @code{LaTeX}
+* Base modules:: Base modules shipped with @code{Asymptote}
+* Options:: Command-line options
+* Interactive mode:: Typing @code{Asymptote} commands interactively
+* GUI:: Graphical user interface
+* PostScript to Asymptote:: @code{Asymptote} backend to @code{pstoedit}
+* Help:: Where to get help and submit bug reports
+* Debugger:: Squish those bugs!
+* Credits:: Contributions and acknowledgments
+* Index:: General index
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Installation
+
+* UNIX binary distributions:: Prebuilt @code{UNIX} binaries
+* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
+* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary
+* Configuring:: Configuring @code{Asymptote} for your system
+* Search paths:: Where @code{Asymptote} looks for your files
+* Compiling from UNIX source:: Building @code{Asymptote} from scratch
+* Editing modes:: Convenient @code{emacs} and @code{vim} modes
+* Git:: Getting the latest development source
+* Uninstall:: Goodbye, @code{Asymptote}!
+
+Tutorial
+
+* Drawing in batch mode:: Run @code{Asymptote} on a text file
+* Drawing in interactive mode:: Running @code{Asymptote} interactively
+* Figure size:: Specifying the figure size
+* Labels:: Adding @code{LaTeX} labels
+* Paths:: Drawing lines and curves
+
+Drawing commands
+
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+
+Programming
+
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides:: Bezier curves
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external @code{Asymptote} modules
+* Static:: Where to allocate your variable?
+
+Operators
+
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+
+Functions
+
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+
+Arrays
+
+* Slices:: Python-style array slices
+
+Base modules
+
+* plain:: Default @code{Asymptote} base file
+* simplex:: Linear programming: simplex method
+* math:: Extend @code{Asymptote}'s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded @acronym{PDF} and @acronym{MPEG} movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with @code{Asymptote}
+* MetaPost:: @code{MetaPost} compatibility routines
+* unicode:: Accept @code{unicode} (UTF-8) characters
+* latin1:: Accept @code{ISO 8859-1} characters
+* babel:: Interface to @code{LaTeX} @code{babel} package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your @acronym{PDF} files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* smoothcontour3:: Smooth implicit surfaces
+* slopefield:: Slope fields
+* ode:: Ordinary differential equations
+
+Graphical User Interface
+
+* GUI installation:: Installing @code{xasy}
+* GUI usage:: Using @code{xasy} to edit objects
+
+@end detailmenu
+@end menu
+
+@node Description, Installation, Top, Top
+@chapter Description
+@cindex description
+
+@code{Asymptote} is a powerful descriptive vector graphics language that
+provides a mathematical coordinate-based framework for technical drawing.
+Labels and equations are typeset with @code{LaTeX}, for overall document
+consistency, yielding the same high-quality level of typesetting that
+@code{LaTeX} provides for scientific text. By default it produces
+@code{PostScript} output, but it can also generate any format that the
+@code{ImageMagick} package can produce.
+
+A major advantage of @code{Asymptote} over other graphics packages is
+that it is a high-level programming language, as opposed to just a graphics
+program: it can therefore exploit the best features of the script
+(command-driven) and graphical-user-interface (@acronym{GUI}) methods for
+producing figures. The rudimentary @acronym{GUI} @code{xasy} included with the
+package allows one to move script-generated objects
+around. To make @code{Asymptote} accessible to the average user, this
+@acronym{GUI} is currently being developed into a full-fledged interface
+that can generate objects directly. However, the script portion of the language
+is now ready for general use by users who are willing to learn a few
+simple @code{Asymptote} graphics commands (@pxref{Drawing commands}).
+
+@code{Asymptote} is mathematically oriented (e.g.@ one can
+use complex multiplication to rotate a vector) and uses
+@code{LaTeX} to do the
+typesetting of labels. This is an important feature for scientific
+applications. It was inspired by an earlier drawing program (with a weaker
+syntax and capabilities) called @code{MetaPost}.
+
+The @code{Asymptote} vector graphics language provides:
+
+@itemize @bullet
+@item a standard for typesetting mathematical figures, just
+as @TeX{}/@code{LaTeX} is the de-facto standard for typesetting equations.
+
+@item @code{LaTeX} typesetting of labels, for overall document consistency;
+
+@item the ability to generate and embed 3D vector @acronym{PRC}
+graphics within @acronym{PDF} files;
+
+@item a natural coordinate-based framework for technical drawing,
+inspired by @code{MetaPost}, with a much cleaner, powerful C++-like programming
+syntax;
+
+@item compilation of figures into virtual machine code for speed, without
+sacrificing portability;
+
+@item the power of a script-based language coupled to the convenience of
+a @acronym{GUI};
+
+@item customization using its own C++-like graphics programming language;
+
+@item sensible defaults for graphical features, with the ability to override;
+
+@item a high-level mathematically oriented interface to the
+@code{PostScript} language for vector graphics, including affine transforms
+and complex variables;
+
+@item functions that can create new (anonymous) functions;
+
+@item deferred drawing that uses the simplex method to solve overall size
+constraint issues between fixed-sized objects (labels and arrowheads) and
+objects that should scale with figure size;
+
+@end itemize
+
+Many of the features of @code{Asymptote} are written in the
+@code{Asymptote} language itself. While the stock version of
+@code{Asymptote} is designed for mathematics typesetting needs, one can
+write @code{Asymptote} modules that tailor it to specific
+applications. A scientific graphing module has already been written
+(@pxref{graph}). Examples of @code{Asymptote} code and output,
+including animations, are available at
+@quotation
+@url{http://asymptote.sourceforge.net/gallery/}
+@end quotation
+@noindent
+Clicking on an example file name in this manual, like
+@code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.pdf,,Pythagoras}}, will display the @acronym{PDF} output, whereas clicking on its
+@code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.asy,,.asy}}
+extension will show the corresponding @code{Asymptote} code in a separate window.
+
+Links to many external resources, including an excellent user-written
+@code{Asymptote} tutorial can be found at
+@quotation
+@url{http://asymptote.sourceforge.net/links.html}
+@end quotation
+@cindex reference
+@cindex quick reference
+A quick reference card for @code{Asymptote} is available at
+@quotation
+@url{http://asymptote.sourceforge.net/asyRefCard.pdf}
+@end quotation
+
+@node Installation, Tutorial, Description, Top
+@chapter Installation
+@cindex installation
+
+@menu
+* UNIX binary distributions:: Prebuilt @code{UNIX} binaries
+* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
+* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary
+* Configuring:: Configuring @code{Asymptote} for your system
+* Search paths:: Where @code{Asymptote} looks for your files
+* Compiling from UNIX source:: Building @code{Asymptote} from scratch
+* Editing modes:: Convenient @code{emacs} and @code{vim} modes
+* Git:: Getting the latest development source
+* Uninstall:: Goodbye, @code{Asymptote}!
+@end menu
+
+After following the instructions for your specific distribution,
+please see also @ref{Configuring}.
+
+@noindent
+We recommend subscribing to new release announcements at
+@quotation
+@url{http://sourceforge.net/projects/asymptote}
+@end quotation
+@noindent
+Users may also wish to monitor the @code{Asymptote} forum:
+@quotation
+@url{http://sourceforge.net/p/asymptote/discussion/409349}
+@end quotation
+@noindent
+
+@node UNIX binary distributions, MacOS X binary distributions, Installation, Installation
+@section UNIX binary distributions
+@cindex UNIX binary distributions
+
+@cindex @acronym{RPM}
+@cindex @code{tgz}
+We release both @code{tgz} and @acronym{RPM} binary distributions of
+@code{Asymptote}. The root user can install the @code{Linux x86_64} @code{tgz}
+distribution of version @code{x.xx} of @code{Asymptote} with the commands:
+@verbatim
+tar -C / -zxf asymptote-x.xx.x86_64.tgz
+texhash
+@end verbatim
+@noindent
+The @code{texhash} command, which installs LaTeX style files, is optional.
+The executable file will be @code{/usr/local/bin/asy}) and example code
+will be installed by default in @code{@value{Datadir}/doc/asymptote/examples}.
+
+@noindent
+@cindex Fedora
+Fedora users can easily install the most recent version of @code{Asymptote}
+with the command
+@verbatim
+dnf --enablerepo=rawhide install asymptote
+@end verbatim
+
+@cindex Debian
+@noindent
+To install the latest version of @code{Asymptote} on a Debian-based distribution
+(e.g.@ Ubuntu, Mepis, Linspire) follow the instructions for compiling
+from @code{UNIX} source (@pxref{Compiling from UNIX source}).
+Alternatively, Debian users can install one of Hubert Chan's
+prebuilt @code{Asymptote} binaries from
+@quotation
+@url{http://ftp.debian.org/debian/pool/main/a/asymptote}
+@end quotation
+
+@node MacOS X binary distributions, Microsoft Windows, UNIX binary distributions, Installation
+@section MacOS X binary distributions
+@cindex @code{MacOS X} binary distributions
+@code{MacOS X} users can either compile the @code{UNIX} source code
+(@pxref{Compiling from UNIX source})
+or install the @code{Asymptote} binary available at
+
+@url{http://www.macports.org/}
+
+@noindent
+Note that many @code{MacOS X} (and FreeBSD) systems lack the
+@acronym{GNU} @code{readline} library. For full interactive
+functionality, @acronym{GNU} @code{readline} version 4.3 or later must
+be installed.
+
+@node Microsoft Windows, Configuring, MacOS X binary distributions, Installation
+@section Microsoft Windows
+@cindex Microsoft Windows
+Users of the @code{Microsoft Windows} operating system can install the
+self-extracting @code{Asymptote} executable @code{asymptote-x.xx-setup.exe},
+where @code{x.xx} denotes the latest version.
+
+A working @TeX{} implementation (we recommend
+@url{https://www.tug.org/texlive} or
+@url{http://www.miktex.org}) will be required to typeset labels.
+You will also need to install @code{GPL Ghostscript} version 9.14 or
+later from @url{http://downloads.ghostscript.com/public}.
+
+To view @code{PostScript} output, you can install the
+program @code{gsview} available from
+@url{http://www.cs.wisc.edu/~ghost/gsview/}.
+
+The @code{ImageMagick} package from
+@url{http://www.imagemagick.org/script/binary-releases.php}
+
+@noindent
+is required to support output formats other than @acronym{EPS},
+@acronym{PDF}, @acronym{SVG}, and @acronym{PNG} (@pxref{convert}).
+The @code{Python 3} interpreter from @url{http://www.python.org} is only required
+if you wish to try out the graphical user interface (@pxref{GUI}).
+
+@noindent
+Example code will be installed by default in the @code{examples}
+subdirectory of the installation directory (by default,
+@code{C:\Program Files\Asymptote}).
+
+@node Configuring, Search paths, Microsoft Windows, Installation
+@section Configuring
+@cindex configuring
+@cindex @code{-V}
+@cindex @code{psviewer}
+@cindex @code{pdfviewer}
+@cindex @code{gs}
+In interactive mode, or when given the @code{-V} option (the default
+when running @code{Asymptote} on a single file under @code{MSDOS}),
+@code{Asymptote} will automatically invoke the @code{PostScript}
+viewer @code{gv} (under @code{UNIX}) or @code{gsview} (under
+@code{MSDOS} to display graphical output. These defaults may be
+overridden with the configuration variable @code{psviewer}.
+The @code{PostScript} viewer should be capable of automatically
+redrawing whenever the output file is updated. The default @code{UNIX}
+@code{PostScript} viewer @code{gv} supports this (via a @code{SIGHUP}
+signal). Version @code{gv-3.6.3} or later (from
+@url{http://ftp.gnu.org/gnu/gv/}) is required for interactive mode to
+work properly.
+Users of @code{ggv} will need to enable @code{Watch file} under
+@code{Edit/Postscript Viewer Preferences}.
+Users of @code{gsview} will need to enable @code{Options/Auto Redisplay}
+(however, under @code{MSDOS} it is still necessary to click on the
+@code{gsview} window; under @code{UNIX} one must manually redisplay by
+pressing the @code{r} key).
+
+@cindex @code{settings}
+@cindex configuration file
+Configuration variables are most easily set as @code{Asymptote}
+variables in an optional configuration file @code{config.asy}
+@pxref{configuration file}).
+Here are the default values of several important configuration
+variables under @code{UNIX}:
+
+@noindent
+@verbatim
+import settings;
+psviewer="gv";
+pdfviewer="acroread";
+gs="gs";
+@end verbatim
+
+@noindent
+@cindex @code{cmd}
+Under @code{MSDOS}, the (installation-dependent) default values of
+these configuration variables are determined automatically from the
+@code{Microsoft Windows} registry. Viewer settings (such as
+@code{psviewer} and @code{pdfviewer}) can be set to the string
+@code{cmd} to request the application normally associated with the
+corresponding file type.
+
+For @acronym{PDF} format output, the @code{gs} setting specifies the
+location of the @code{PostScript}-to-@acronym{PDF} processor @code{Ghostscript},
+available from @url{http://downloads.ghostscript.com/public}.
+
+The setting @code{pdfviewer} specifies the location of the @acronym{PDF}
+viewer. On @code{UNIX} systems, to support automatic document
+reloading in @code{Adobe Reader}, we recommend copying the file
+@code{reload.js} from the @code{Asymptote} system directory (by default,
+@code{@value{Datadir}/asymptote} under @code{UNIX} to
+@code{~/.adobe/Acrobat/x.x/JavaScripts/},
+where @code{x.x} represents the appropriate @code{Adobe Reader}
+version number. The automatic document reload feature must then be
+explicitly enabled by putting
+@verbatim
+import settings;
+pdfreload=true;
+pdfreloadOptions="-tempFile";
+@end verbatim
+@noindent
+in the @code{Asymptote} configuration file. This reload feature is not
+useful under @code{MSDOS} since the document cannot be updated anyway on
+that operating system until it is first closed by @code{Adobe Reader}.
+
+The configuration variable @code{dir} can be used to adjust the
+search path (@pxref{Search paths}).
+
+@cindex @code{papertype}
+@cindex @code{paperwidth}
+@cindex @code{paperheight}
+@cindex @code{letter}
+@cindex @code{a4}
+By default, @code{Asymptote} attempts to center the figure on the
+page, assuming that the paper type is @code{letter}. The default paper
+type may be changed to @code{a4} with the configuration variable
+@code{papertype}. Alignment to other paper sizes can be obtained by setting the
+configuration variables @code{paperwidth} and @code{paperheight}.
+
+@cindex @code{config}
+@cindex @code{texpath}
+@cindex @code{texcommand}
+@cindex @code{dvips}
+@cindex @code{dvisvgm}
+@cindex @code{libgs}
+@cindex @code{convert}
+@cindex @code{display}
+@cindex @code{animate}
+@cindex @code{ImageMagick}
+The following configuration variables normally do not require adjustment:
+@verbatim
+config
+texpath
+texcommand
+dvips
+dvisvgm
+libgs
+convert
+display
+animate
+@end verbatim
+@noindent
+
+Warnings (such as "unbounded" and "offaxis") may be enabled or disabled with
+the functions
+@verbatim
+warn(string s);
+nowarn(string s);
+@end verbatim
+@noindent
+or by directly modifying the string array @code{settings.suppress}, which lists
+all disabled warnings.
+
+@cindex command-line options
+Configuration variables may also be set or overwritten with a
+command-line option:
+@verbatim
+asy -psviewer=gsview -V venn
+@end verbatim
+
+@cindex environment variables
+Alternatively, system environment versions of the above configuration
+variables may be set in the conventional way. The corresponding
+environment variable name is obtained by converting the configuration
+variable name to upper case and prepending @code{ASYMPTOTE_}:
+for example, to set the environment variable
+@verbatim
+ASYMPTOTE_PSVIEWER="C:\Program Files\Ghostgum\gsview\gsview32.exe";
+@end verbatim
+@noindent
+under @code{Microsoft Windows XP}:
+@enumerate
+@item Click on the @code{Start} button;
+@item Right-click on @code{My Computer};
+@item Choose @code{View system information};
+@item Click the @code{Advanced} tab;
+@item Click the @code{Environment Variables} button.
+@end enumerate
+
+@node Search paths, Compiling from UNIX source, Configuring, Installation
+@section Search paths
+@cindex search paths
+
+In looking for @code{Asymptote} system
+files, @code{asy} will search the following paths, in the order listed:
+@enumerate
+@item
+The current directory;
+@item
+@cindex @code{dir}
+A list of one or more directories specified by the configuration
+variable @code{dir} or environment variable @code{ASYMPTOTE_DIR}
+(separated by @code{:} under UNIX and
+@code{;} under @code{MSDOS});
+@item
+@cindex @code{.asy}
+The directory specified by the environment variable
+@code{ASYMPTOTE_HOME}; if this variable is not set,
+the directory @code{.asy} in the user's home directory
+(@code{%USERPROFILE%\.asy} under @code{MSDOS}) is used;
+@item
+The @code{Asymptote} system directory (by default,
+@code{@value{Datadir}/asymptote} under @code{UNIX} and
+@code{C:\Program Files\Asymptote} under @code{MSDOS}).
+@end enumerate
+
+@node Compiling from UNIX source, Editing modes, Search paths, Installation
+@section Compiling from UNIX source
+@cindex Compiling from UNIX source
+
+To compile and install a @code{UNIX} executable from
+the source release @code{asymptote-x.xx.src.tgz} in the subdirectory
+@code{x.xx} under
+
+@url{http://sourceforge.net/projects/asymptote/files/}
+
+execute the commands:
+@verbatim
+gunzip asymptote-x.xx.src.tgz
+tar -xf asymptote-x.xx.src.tar
+cd asymptote-x.xx
+@end verbatim
+By default the system version of the Boehm garbage collector will be
+used; if it is old we recommend first putting
+@url{https://github.com/ivmai/bdwgc/releases/download/v8.0.4/gc-8.0.4.tar.gz}
+@url{https://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-7.6.10.tar.gz}
+in the @code{Asymptote} source directory.
+
+On @code{UNIX} platforms (other than @code{MacOS X}), we recommend
+using version @code{3.0.0} of the @code{freeglut} library. To compile
+@code{freeglut}, download
+@quotation
+@url{http://prdownloads.sourceforge.net/freeglut/freeglut-3.0.0.tar.gz}
+@end quotation
+@noindent
+and type (as the root user):
+@verbatim
+gunzip freeglut-3.0.0.tar.gz
+tar -xf freeglut-3.0.0.tar
+cd freeglut-3.0.0
+./configure --prefix=/usr
+cmake .
+make
+make install
+cd ..
+@end verbatim
+@noindent
+
+Then compile @code{Asymptote} with the commands
+@verbatim
+./configure
+make all
+make install
+@end verbatim
+@noindent
+Be sure to use @acronym{GNU} @code{make} (on non-@acronym{GNU} systems
+this command may be called @code{gmake}).
+To build the documentation, you may need to install the
+@code{texinfo-tex} package. If you get errors from a broken @code{texinfo}
+or @code{pdftex} installation, simply put
+@quotation
+@url{http://asymptote.sourceforge.net/asymptote.pdf}
+@end quotation
+@noindent
+in the directory @code{doc} and repeat the command @code{make all}.
+
+@noindent
+For a (default) system-wide installation, the last command should be
+done as the root user. To install without root privileges, change the
+@code{./configure} command to
+@verbatim
+./configure --prefix=$HOME/asymptote
+@end verbatim
+One can disable use of the Boehm garbage collector by configuring
+with @code{./configure --disable-gc}. For a list of other configuration
+options, say @code{./configure --help}. For example, one can tell
+configure to look for header files and libraries in nonstandard locations:
+@verbatim
+./configure CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
+@end verbatim
+
+If you are compiling @code{Asymptote} with @code{gcc}, you will need a
+relatively recent version (e.g.@ 3.4.4 or later). For full interactive
+functionality, you will need version 4.3 or later of the @acronym{GNU}
+@code{readline} library.
+The file @code{gcc3.3.2curses.patch} in the @code{patches} directory can
+be used to patch the broken curses.h header file (or a local copy thereof
+in the current directory) on some @code{AIX} and @code{IRIX} systems.
+
+@cindex @code{FFTW}
+@cindex @code{GSL}
+The @code{FFTW} library is only required if you want @code{Asymptote}
+to be able to take Fourier transforms of data (say, to compute an
+audio power spectrum). The @code{GSL} library is only required if you
+require the special functions that it supports.
+
+If you don't want to install @code{Asymptote} system wide, just make
+sure the compiled binary @code{asy} and @acronym{GUI} script @code{xasy} are in
+your path and set the configuration variable @code{dir} to point
+to the directory @code{base} (in the top level directory of the
+@code{Asymptote} source code).
+
+@node Editing modes, Git, Compiling from UNIX source, Installation
+@section Editing modes
+@cindex Editing modes
+@cindex @code{emacs}
+@cindex @code{asy-mode}
+@cindex @code{lasy-mode}
+Users of @code{emacs} can edit @code{Asymptote} code with the mode
+@code{asy-mode}, after enabling it by putting the following lines in their
+@code{.emacs} initialization file, replacing @code{ASYDIR} with the
+location of the @code{Asymptote} system directory (by default,
+@code{@value{Datadir}/asymptote} or @code{C:\Program Files\Asymptote}
+under @code{MSDOS}):
+@verbatim
+(add-to-list 'load-path "ASYDIR")
+(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+@end verbatim
+@noindent
+Particularly useful key bindings in this mode are @code{C-c C-c}, which compiles
+and displays the current buffer, and the key binding @code{C-c ?}, which
+shows the available function prototypes for the command at the cursor.
+For full functionality you should also install the Apache Software Foundation
+package @code{two-mode-mode}:
+@quotation
+@url{http://www.dedasys.com/freesoftware/files/two-mode-mode.el}
+@end quotation
+@noindent
+Once installed, you can use the hybrid mode @code{lasy-mode} to edit a
+LaTeX file containing embedded @code{Asymptote} code (@pxref{LaTeX usage}).
+This mode can be enabled within @code{latex-mode}
+with the key sequence @code{M-x lasy-mode <RET>}.
+On @code{UNIX} systems, additional keywords will be generated from
+all @code{asy} files in the space-separated list of directories
+specified by the environment variable @code{ASYMPTOTE_SITEDIR}.
+Further documentation of @code{asy-mode} is available within
+@code{emacs} by pressing the sequence keys @code{C-h f asy-mode <RET>}.
+
+@cindex @code{vim}
+@cindex @code{asy.vim}
+Fans of @code{vim} can customize @code{vim} for @code{Asymptote} with
+
+@noindent
+@code{cp @value{Datadir}/asymptote/asy.vim ~/.vim/syntax/asy.vim}
+
+@noindent
+and add the following to their @code{~/.vimrc} file:
+@verbatim
+augroup filetypedetect
+au BufNewFile,BufRead *.asy setf asy
+augroup END
+filetype plugin on
+@end verbatim
+
+If any of these directories or files don't exist, just create them.
+To set @code{vim} up to run the current asymptote script using @code{:make}
+just add to @code{~/.vim/ftplugin/asy.vim}:
+@verbatim
+setlocal makeprg=asy\ %
+setlocal errorformat=%f:\ %l.%c:\ %m
+@end verbatim
+
+@cindex @code{KDE editor}
+@cindex @code{Kate}
+@cindex @code{asymptote.xml}
+Syntax highlighting support for the @acronym{KDE} editor @code{Kate}
+can be enabled by running @code{asy-kate.sh} in the
+@code{@value{Datadir}/asymptote} directory and putting the generated
+@code{asymptote.xml} file in @code{~/.kde/share/apps/katepart/syntax/}.
+
+@node Git, Uninstall, Editing modes, Installation
+@section Git
+@cindex git
+
+The following commands are needed to install the latest development version of
+@code{Asymptote} using @code{git}:
+@verbatim
+git clone https://github.com/vectorgraphics/asymptote
+
+cd asymptote
+./autogen.sh
+./configure
+make all
+make install
+@end verbatim
+
+@noindent
+To compile without optimization, use the command @code{make CFLAGS=-g}.
+
+@node Uninstall, , Git, Installation
+@section Uninstall
+@cindex uninstall
+
+To uninstall a @code{Linux x86_64} binary distribution, use the commands
+@verbatim
+tar -zxvf asymptote-x.xx.x86_64.tgz | xargs --replace=% rm /%
+texhash
+@end verbatim
+
+@noindent
+To uninstall all @code{Asymptote} files installed from a source
+distribution, use the command
+@verbatim
+make uninstall
+@end verbatim
+
+@node Tutorial, Drawing commands, Installation, Top
+@chapter Tutorial
+@cindex tutorial
+
+@menu
+* Drawing in batch mode:: Run @code{Asymptote} on a text file
+* Drawing in interactive mode:: Running @code{Asymptote} interactively
+* Figure size:: Specifying the figure size
+* Labels:: Adding @code{LaTeX} labels
+* Paths:: Drawing lines and curves
+@end menu
+
+A concise introduction to @code{Asymptote} is given here.
+For a more thorough introduction, see the excellent @code{Asymptote}
+tutorial written by Charles Staats:
+
+@url{http://math.uchicago.edu/~cstaats/Charles_Staats_III/Notes_and_papers_files/asymptote_tutorial.pdf}
+
+Another @code{Asymptote} tutorial is available as a wiki,
+with images rendered by an online Asymptote engine:
+
+@url{http://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)}
+
+@node Drawing in batch mode, Drawing in interactive mode, Tutorial, Tutorial
+@section Drawing in batch mode
+@cindex batch mode
+To draw a line from coordinate (0,0) to coordinate (100,100),
+create a text file @code{test.asy} containing
+@verbatiminclude diagonal.asy
+
+@noindent
+Then execute the command
+@verbatim
+asy -V test
+@end verbatim
+@noindent
+Alternatively, @code{MSDOS} users can drag and drop @code{test.asy} onto the
+Desktop @code{asy} icon (or make @code{Asymptote} the default
+application for the extension @code{asy}).
+
+@noindent
+@cindex @code{-V}
+This method, known as @emph{batch mode}, outputs a @code{PostScript}
+file @code{test.eps}. If you prefer @acronym{PDF} output, use
+the command line
+@verbatim
+asy -V -f pdf test
+@end verbatim
+In either case, the @code{-V} option opens up a viewer window so you
+can immediately view the result:
+@sp 1
+@center @image{diagonal}
+@cindex @code{bp}
+@noindent
+Here, the @code{--} connector joins the two points @code{(0,0)} and
+@code{(100,100)} with a line segment.
+
+@node Drawing in interactive mode, Figure size, Drawing in batch mode, Tutorial
+@section Drawing in interactive mode
+@cindex interactive mode
+Another method is @emph{interactive mode}, where @code{Asymptote} reads
+individual commands as they are entered by the user. To try this out, enter
+@code{Asymptote}'s interactive mode by clicking on the
+@code{Asymptote} icon or typing the command @code{asy}.
+Then type
+@verbatim
+draw((0,0)--(100,100));
+@end verbatim
+@noindent
+followed by @code{Enter}, to obtain the above image.
+@cindex tab completion
+@cindex arrow keys
+@cindex erase
+@cindex quit
+@noindent
+At this point you can type further @code{draw} commands, which will be added
+to the displayed figure, @code{erase} to clear the canvas,
+@verbatim
+input test;
+@end verbatim
+@noindent
+to execute all of the commands contained in the file @code{test.asy},
+or @code{quit} to exit interactive mode.
+You can use the arrow keys in interactive mode to edit previous lines.
+The tab key will automatically complete unambiguous words;
+otherwise, hitting tab again will show the possible choices. Further
+commands specific to interactive mode are described in @ref{Interactive mode}.
+
+@node Figure size, Labels, Drawing in interactive mode, Tutorial
+@section Figure size
+@cindex @code{size}
+@cindex @code{pair}
+In @code{Asymptote}, coordinates like @code{(0,0)} and @code{(100,100)},
+called @emph{pairs},
+are expressed in @code{PostScript} "big points" (1 @code{bp} = 1/72
+@code{inch}) and the default line width is @code{0.5bp}.
+However, it is often inconvenient to work directly in
+@code{PostScript} coordinates.
+The next example produces identical output to the previous example, by
+scaling the line @code{(0,0)--(1,1)} to fit a rectangle of width
+@code{100.5 bp} and height @code{100.5 bp} (the extra @code{0.5bp}
+accounts for the line width):
+@verbatim
+size(100.5,100.5);
+draw((0,0)--(1,1));
+@end verbatim
+@sp 1
+@center @image{diagonal}
+
+@cindex @code{inches}
+@cindex @code{cm}
+@cindex @code{mm}
+@cindex @code{pt}
+One can also specify the size in @code{pt} (1 @code{pt} = 1/72.27 @code{inch}),
+@code{cm}, @code{mm}, or @code{inches}.
+Two nonzero size arguments (or a single size argument) restrict the
+size in both directions, preserving the aspect ratio.
+If 0 is given as a size argument, no restriction is made in that direction;
+the overall scaling will be determined by the other direction (@pxref{size}):
+@verbatiminclude bigdiagonal.asy
+@sp 1
+@center @image{bigdiagonal}
+
+@cindex @code{cycle}
+To connect several points and create a cyclic path, use the
+@code{cycle} keyword:
+@verbatiminclude square.asy
+@sp 1
+@center @image{square}
+@noindent
+For convenience, the path @code{(0,0)--(1,0)--(1,1)--(0,1)--cycle}
+may be replaced with the predefined variable
+@code{unitsquare}, or equivalently, @code{box((0,0),(1,1))}.
+
+@cindex user coordinates
+@cindex @code{unitsize}
+To make the user coordinates represent multiples of exactly @code{1cm}:
+@verbatim
+unitsize(1cm);
+draw(unitsquare);
+@end verbatim
+@noindent
+
+@node Labels, Paths, Figure size, Tutorial
+@section Labels
+@cindex @code{label}
+Adding labels is easy in @code{Asymptote}; one specifies the
+label as a double-quoted @code{LaTeX} string, a
+coordinate, and an optional alignment direction:
+@verbatiminclude labelsquare.asy
+@sp 1
+@center @image{labelsquare}
+
+@cindex compass directions
+@cindex @code{N}
+@cindex @code{E}
+@cindex @code{W}
+@cindex @code{S}
+@code{Asymptote} uses the standard compass directions @code{E=(1,0)},
+@code{N=(0,1)}, @code{NE=unit(N+E)}, and @code{ENE=unit(E+NE)}, etc.,
+which along with the directions @code{up}, @code{down}, @code{right},
+and @code{left} are defined as pairs in the @code{Asymptote} base
+module @code{plain} (a user who has a local variable named @code{E}
+may access the compass direction @code{E} by prefixing it with the name
+of the module where it is defined: @code{plain.E}).
+
+@node Paths, , Labels, Tutorial
+@section Paths
+@cindex @code{path}
+This example draws a path that approximates a quarter circle,
+terminated with an arrowhead:
+@verbatiminclude quartercircle.asy
+@sp 1
+@center @image{quartercircle}
+@noindent
+Here the directions @code{up} and @code{left} in braces specify the
+outgoing and incoming directions at the points @code{(1,0)} and
+@code{(0,1)}, respectively.
+
+In general, a path is specified as a list of points (or other paths)
+interconnected with
+@cindex @code{cycle}
+@cindex @code{--}
+@cindex @code{..}
+@code{--}, which denotes a straight line segment, or @code{..}, which
+denotes a cubic spline (@pxref{Bezier curves}).
+@cindex @code{unitcircle}
+@anchor{unitcircle}
+@cindex @code{unitcircle}
+Specifying a final @code{..cycle} creates a cyclic path that
+connects smoothly back to the initial node, as in this approximation
+(accurate to within 0.06%) of a unit circle:
+@verbatim
+path unitcircle=E..N..W..S..cycle;
+@end verbatim
+
+@cindex @code{PostScript} subpath
+@cindex @code{^^}
+@cindex @code{path[]}
+@cindex superpath
+@noindent
+An @code{Asymptote} path, being connected, is equivalent to a
+@code{Postscript subpath}. The @code{^^} binary operator, which
+requests that the pen be moved (without drawing or affecting
+endpoint curvatures) from the final point of the left-hand path to the
+initial point of the right-hand path, may be used to group several
+@code{Asymptote} paths into a @code{path[]} array (equivalent to a
+@code{PostScript} path):
+@verbatiminclude superpath.asy
+@sp 1
+@center @image{superpath}
+
+@cindex evenodd
+@noindent
+The @code{PostScript} even-odd fill rule here specifies that only the
+region bounded between the two unit circles is filled (@pxref{fillrule}).
+In this example, the same effect can be achieved by using the default
+zero winding number fill rule, if one is careful to alternate the
+orientation of the paths:
+@verbatim
+filldraw(unitcircle^^reverse(g),yellow,black);
+@end verbatim
+
+@cindex @code{unitbox}
+The @code{^^} operator is used by the @code{box(triple, triple)} function in
+the module @code{three.asy} to construct the edges of a
+cube @code{unitbox} without retracing steps (@pxref{three}):
+@verbatiminclude cube.asy
+@sp 1
+@center @image{cube}
+
+See section @ref{graph} (or the online
+@code{Asymptote} @uref{http://asymptote.sourceforge.net/gallery,,gallery} and
+external links posted at @url{http://asymptote.sourceforge.net}) for
+further examples, including two-dimensional and interactive
+three-dimensional scientific graphs. Additional examples have been
+posted by Philippe Ivaldi at @url{http://www.piprime.fr/asymptote}.
+
+@node Drawing commands, Bezier curves, Tutorial, Top
+@chapter Drawing commands
+@cindex drawing commands
+
+All of @code{Asymptote}'s graphical capabilities are based on four primitive
+commands. The three @code{PostScript} drawing commands @code{draw},
+@code{fill}, and @code{clip} add objects to a picture in the order in
+which they are executed, with the most recently drawn object appearing on top.
+The labeling command @code{label} can be used to add text
+labels and external @acronym{EPS} images, which will appear on top of the
+@code{PostScript} objects (since this is normally what one wants), but
+again in the relative order in which they were executed. After drawing
+objects on a picture, the picture can be output with the
+@code{shipout} function (@pxref{shipout}).
+
+@cindex @code{layer}
+If you wish to draw @code{PostScript} objects on top of labels (or verbatim
+@code{tex} commands; @pxref{tex}), the @code{layer} command may be
+used to start a
+new @code{PostScript/LaTeX} layer:
+@verbatim
+void layer(picture pic=currentpicture);
+@end verbatim
+
+The @code{layer} function gives one full control over the order in which
+objects are drawn. Layers are drawn sequentially, with the most recent
+layer appearing on top. Within each layer, labels, images, and
+verbatim @code{tex} commands are always drawn after the
+@code{PostScript} objects in that layer.
+
+While some of these drawing commands take many options, they all have sensible
+default values (for example, the picture argument defaults to
+currentpicture).
+
+@cindex legend
+@cindex @code{draw}
+@cindex @code{arrow}
+
+@menu
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+@end menu
+
+@node draw, fill, Drawing commands, Drawing commands
+@section draw
+@cindex @code{draw}
+@verbatim
+void draw(picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
+ Label legend="", marker marker=nomarker);
+@end verbatim
+
+Draw the path @code{g} on the picture @code{pic} using pen @code{p}
+for drawing, with optional drawing attributes (Label @code{L},
+explicit label alignment @code{align},
+arrows and bars @code{arrow} and @code{bar}, margins @code{margin},
+legend, and markers @code{marker}). Only one parameter, the path, is
+required. For convenience, the arguments @code{arrow} and @code{bar} may be
+specified in either order. The argument @code{legend} is a Label to
+use in constructing an optional legend entry.
+
+@cindex @code{None}
+@cindex @code{BeginBar}
+@cindex @code{EndBar}
+@cindex @code{Bar}
+@cindex @code{Bars}
+@cindex @code{barsize}
+Bars are useful for indicating dimensions. The possible values of
+@code{bar} are @code{None}, @code{BeginBar}, @code{EndBar} (or
+equivalently @code{Bar}), and @code{Bars} (which draws a bar at both
+ends of the path). Each of these bar specifiers (except for
+@code{None}) will accept an optional real argument that denotes the
+length of the bar in @code{PostScript} coordinates. The default
+bar length is @code{barsize(pen)}.
+
+@cindex arrows
+@anchor{arrows}
+@cindex @code{None}
+@cindex @code{Blank}
+@cindex @code{BeginArrow}
+@cindex @code{MidArrow}
+@cindex @code{EndArrow}
+@cindex @code{Arrow}
+@cindex @code{Arrows}
+@cindex @code{FillDraw}
+@cindex @code{Fill}
+@cindex @code{Draw}
+@cindex @code{NoFill}
+@cindex @code{UnFill}
+@cindex @code{BeginArcArrow}
+@cindex @code{MidArcArrow}
+@cindex @code{EndArcArrow}
+@cindex @code{ArcArrow}
+@cindex @code{ArcArrows}
+
+@cindex @code{DefaultHead}
+@cindex @code{SimpleHead}
+@cindex @code{HookHead}
+@cindex @code{TeXHead}
+The possible values of @code{arrow} are @code{None}, @code{Blank}
+(which draws no arrows or path), @code{BeginArrow}, @code{MidArrow},
+@code{EndArrow} (or equivalently @code{Arrow}),
+and @code{Arrows} (which draws an arrow at both ends of the path).
+All of the arrow specifiers except for @code{None} and @code{Blank}
+may be given the optional arguments arrowhead @code{arrowhead} (one of
+the predefined arrowhead styles @code{DefaultHead}, @code{SimpleHead},
+@code{HookHead}, @code{TeXHead}),
+real @code{size} (arrowhead size in @code{PostScript} coordinates),
+real @code{angle} (arrowhead angle
+in degrees), filltype @code{filltype} (one of @code{FillDraw}, @code{Fill},
+@code{NoFill}, @code{UnFill}, @code{Draw}) and (except for
+@code{MidArrow} and @code{Arrows}) a real @code{position} (in the
+sense of @code{point(path p, real t)}) along the path where the tip of
+the arrow should be placed. The default arrowhead size when drawn
+with a pen @code{p} is @code{arrowsize(p)}. There are also arrow versions with
+slightly modified default values of @code{size} and @code{angle} suitable for
+curved arrows: @code{BeginArcArrow}, @code{EndArcArrow} (or equivalently
+@code{ArcArrow}), @code{MidArcArrow}, and @code{ArcArrows}.
+
+@cindex @code{NoMargin}
+@cindex @code{BeginMargin}
+@cindex @code{EndMargin}
+@cindex @code{Margin}
+@cindex @code{Margins}
+@cindex @code{BeginPenMargin}
+@cindex @code{EndPenMargin}
+@cindex @code{PenMargin}
+@cindex @code{PenMargins}
+@cindex @code{BeginDotMargin}
+@cindex @code{EndDotMargin}
+@cindex @code{DotMargin}
+@cindex @code{DotMargins}
+@cindex @code{Margin}
+@cindex @code{TrueMargin}
+Margins can be used to shrink the visible portion of a path by
+@code{labelmargin(p)} to avoid overlap with other drawn objects.
+Typical values of @code{margin}
+are @code{NoMargin}, @code{BeginMargin}, @code{EndMargin} (or
+equivalently @code{Margin}), and @code{Margins} (which leaves a margin
+at both ends of the path). One may use @code{Margin(real begin, real end)}
+to specify the size of the beginning and ending margin, respectively,
+in multiples of the units @code{labelmargin(p)} used for aligning labels.
+Alternatively, @code{BeginPenMargin}, @code{EndPenMargin}
+(or equivalently @code{PenMargin}), @code{PenMargins},
+@code{PenMargin(real begin, real end)} specify a margin in units of
+the pen line width, taking account of the pen line width when drawing
+the path or arrow. For example, use @code{DotMargin}, an
+abbreviation for @code{PenMargin(-0.5*dotfactor,0.5*dotfactor)},
+to draw from the usual beginning point just up to the boundary of an
+end dot of width @code{dotfactor*linewidth(p)}. The qualifiers
+@code{BeginDotMargin}, @code{EndDotMargin}, and @code{DotMargins} work
+similarly. The qualifier @code{TrueMargin(real begin, real end)} allows one to
+specify a margin directly in @code{PostScript} units, independent of
+the pen line width.
+
+The use of arrows, bars, and margins is illustrated by the examples
+@code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.pdf,,Pythagoras}@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.asy,,.asy}},
+@code{@uref{http://asymptote.sourceforge.net/gallery/sqrtx01.pdf,,sqrtx01}@uref{http://asymptote.sourceforge.net/gallery/sqrtx01.asy,,.asy}}, and @code{@uref{http://asymptote.sourceforge.net/gallery/triads.pdf,,triads}@uref{http://asymptote.sourceforge.net/gallery/triads.asy,,.asy}}.
+
+The legend for a picture @code{pic} can be fit and aligned to a frame
+with the routine:
+@cindex @code{legend}
+@verbatim
+frame legend(picture pic=currentpicture, int perline=1,
+ real xmargin=legendmargin, real ymargin=xmargin,
+ real linelength=legendlinelength,
+ real hskip=legendhskip, real vskip=legendvskip,
+ real maxwidth=0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false, pen p=currentpen);
+@end verbatim
+@noindent
+Here @code{xmargin} and @code{ymargin} specify the surrounding @math{x}
+and @math{y} margins, @code{perline} specifies the number of entries
+per line (default 1; 0 means choose this number automatically),
+@code{linelength} specifies the length of the path lines, @code{hskip}
+and @code{vskip} specify the line skip (as a multiple of the legend entry
+size), @code{maxwidth} and @code{maxheight} specify optional upper limits
+on the width and height of the resulting legend (0 means unlimited),
+@code{hstretch} and @code{vstretch} allow the legend to stretch
+horizontally or vertically, and @code{p} specifies the pen used to draw
+the bounding box. The legend frame can then be added and aligned about a
+point on a picture @code{dest} using @code{add} or @code{attach}
+(@pxref{add about}).
+
+@cindex @code{dot}
+To draw a dot, simply draw a path containing a single point.
+The @code{dot} command defined in the module @code{plain} draws a
+dot having a diameter equal to an explicit pen line width or the
+default line width magnified by @code{dotfactor} (6 by default),
+using the specified filltype (@pxref{filltype}) or @code{dotfilltype}
+(@code{Fill} by default):
+@verbatim
+void dot(frame f, pair z, pen p=currentpen, filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, pair z, pen p=currentpen,
+ filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, Label L, pair z, align align=NoAlign,
+ string format=defaultformat, pen p=currentpen, filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, Label[] L=new Label[], pair[] z,
+ align align=NoAlign, string format=defaultformat, pen p=currentpen,
+ filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, path[] g, pen p=currentpen,
+ filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, Label L, pen p=currentpen,
+ filltype filltype=dotfilltype);
+@end verbatim
+
+@cindex @code{Label}
+If the variable @code{Label} is given as the @code{Label}
+argument to the third routine, the @code{format} argument will be
+used to format a string based on the dot location (here @code{defaultformat}
+is @code{"$%.4g$"}).
+The fourth routine draws a dot at every point of a pair array @code{z}.
+One can also draw a dot at every node of a path:
+@verbatim
+void dot(picture pic=currentpicture, Label[] L=new Label[],
+ explicit path g, align align=RightSide, string format=defaultformat,
+ pen p=currentpen, filltype filltype=dotfilltype);
+@end verbatim
+See @ref{pathmarkers} and @ref{markers} for more general
+methods for marking path nodes.
+
+To draw a fixed-sized object (in @code{PostScript} coordinates) about
+the user coordinate @code{origin}, use the routine
+@cindex @code{draw}
+@verbatim
+void draw(pair origin, picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen, arrowbar arrow=None,
+ arrowbar bar=None, margin margin=NoMargin, Label legend="",
+ marker marker=nomarker);
+@end verbatim
+
+@cindex @code{fill}
+@node fill, clip, draw, Drawing commands
+@section fill
+@cindex @code{fill}
+@verbatim
+void fill(picture pic=currentpicture, path g, pen p=currentpen);
+@end verbatim
+
+Fill the interior region bounded by the cyclic path @code{g} on the picture
+@code{pic}, using the pen @code{p}.
+
+@cindex @code{filldraw}
+There is also a convenient @code{filldraw} command, which fills the path
+and then draws in the boundary. One can specify separate pens for each
+operation:
+@verbatim
+void filldraw(picture pic=currentpicture, path g, pen fillpen=currentpen,
+ pen drawpen=currentpen);
+@end verbatim
+
+@cindex @code{fill}
+This fixed-size version of @code{fill} allows one to fill an object
+described in @code{PostScript} coordinates about the user coordinate
+@code{origin}:
+@verbatim
+void fill(pair origin, picture pic=currentpicture, path g, pen p=currentpen);
+@end verbatim
+
+@noindent
+This is just a convenient abbreviation for the commands:
+@verbatim
+picture opic;
+fill(opic,g,p);
+add(pic,opic,origin);
+@end verbatim
+
+The routine
+@cindex @code{filloutside}
+@verbatim
+void filloutside(picture pic=currentpicture, path g, pen p=currentpen);
+@end verbatim
+@noindent
+fills the region exterior to the path @code{g}, out to the current
+boundary of picture @code{pic}.
+
+@anchor{gradient shading}
+@cindex gradient shading
+
+@cindex shading
+@cindex @code{latticeshade}
+Lattice gradient shading varying smoothly over a two-dimensional
+array of pens @code{p}, using fill rule @code{fillrule}, can be produced with
+@verbatim
+void latticeshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p)
+@end verbatim
+@cindex @code{stroke}
+If @code{stroke=true}, the region filled is the same as the region that
+would be drawn by @code{draw(pic,g,zerowinding)}; in this case the path
+@code{g} need not be cyclic.
+The pens in @code{p} must belong to the same color space. One can use the
+functions @code{rgb(pen)} or @code{cmyk(pen)} to promote pens to a
+higher color space, as illustrated in the example file
+@code{@uref{http://asymptote.sourceforge.net/gallery/latticeshading.pdf,,latticeshading}@uref{http://asymptote.sourceforge.net/gallery/latticeshading.asy,,.asy}}.
+
+@cindex @code{axialshade}
+Axial gradient shading varying smoothly from @code{pena} to @code{penb} in the
+direction of the line segment @code{a--b} can be achieved with
+@verbatim
+void axialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a, bool extenda=true,
+ pen penb, pair b, bool extendb=true);
+@end verbatim
+@noindent
+The boolean parameters @code{extenda} and @code{extendb} indicate
+whether the shading should extend beyond the axis endpoints @code{a}
+and @code{b}.
+
+@cindex @code{radialshade}
+Radial gradient shading varying smoothly from
+@code{pena} on the circle with center @code{a} and radius @code{ra} to
+@code{penb} on the circle with center @code{b} and radius @code{rb}
+is similar:
+@verbatim
+void radialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a, real ra, bool extenda=true,
+ pen penb, pair b, real rb, bool extendb=true);
+@end verbatim
+@noindent
+The boolean parameters @code{extenda} and @code{extendb} indicate
+whether the shading should extend beyond the radii @code{a} and @code{b}.
+Illustrations of radial shading are provided in the example files
+@code{@uref{http://asymptote.sourceforge.net/gallery/shade.pdf,,shade}@uref{http://asymptote.sourceforge.net/gallery/shade.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/ring.pdf,,ring}@uref{http://asymptote.sourceforge.net/gallery/ring.asy,,.asy}}, and @code{@uref{http://asymptote.sourceforge.net/gallery/shadestroke.pdf,,shadestroke}@uref{http://asymptote.sourceforge.net/gallery/shadestroke.asy,,.asy}}.
+
+@cindex @code{gouraudshade}
+Gouraud shading using fill rule @code{fillrule} and the vertex colors in the
+pen array @code{p} on a triangular lattice defined by the vertices
+@code{z} and edge flags @code{edges} is implemented with
+@verbatim
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, pair[] z,
+ int[] edges);
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, int[] edges);
+@end verbatim
+@noindent
+In the second form, the elements of @code{z} are taken to be successive
+nodes of path @code{g}. The pens in @code{p} must belong to the same
+color space. Illustrations of Gouraud shading are provided in the example file
+@code{@uref{http://asymptote.sourceforge.net/gallery/Gouraud.pdf,,Gouraud}@uref{http://asymptote.sourceforge.net/gallery/Gouraud.asy,,.asy}}.
+The edge flags used in Gouraud shading are documented here:
+@quotation
+@url{http://partners.adobe.com/public/developer/en/ps/sdk/TN5600.SmoothShading.pdf}.
+@end quotation
+
+@cindex Coons shading
+@cindex tensor product shading
+@cindex @code{tensorshade}
+Tensor product shading using fill rule @code{fillrule} on patches
+bounded by the @math{n} cyclic paths of length 4 in path array @code{b},
+using the vertex colors specified in the @math{n \times 4} pen array
+@code{p} and internal control points in the @math{n \times 4}
+array @code{z}, is implemented with
+@verbatim
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, path[] b=g,
+ pair[][] z=new pair[][]);
+@end verbatim
+@noindent
+If the array @code{z} is empty, Coons shading, in which the color
+control points are calculated automatically, is used.
+The pens in @code{p} must belong to the same color space.
+A simpler interface for the case of a single patch (@math{n=1}) is also
+available:
+@verbatim
+void tensorshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, path b=g,
+ pair[] z=new pair[]);
+@end verbatim
+One can also smoothly shade the regions between consecutive paths of a
+sequence using a given array of pens:
+@verbatim
+void draw(picture pic=currentpicture, pen fillrule=currentpen, path[] g,
+ pen[] p);
+@end verbatim
+@noindent
+Illustrations of tensor product and Coons shading are provided in the
+example files @code{@uref{http://asymptote.sourceforge.net/gallery/tensor.pdf,,tensor}@uref{http://asymptote.sourceforge.net/gallery/tensor.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/Coons.pdf,,Coons}@uref{http://asymptote.sourceforge.net/gallery/Coons.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/BezierSurface.pdf,,BezierSurface}@uref{http://asymptote.sourceforge.net/gallery/BezierSurface.asy,,.asy}},
+and @code{@uref{http://asymptote.sourceforge.net/gallery/rainbow.pdf,,rainbow}@uref{http://asymptote.sourceforge.net/gallery/rainbow.asy,,.asy}}.
+
+@cindex Function shading
+@cindex function shading
+@cindex @code{functionshade}
+More general shading possibilities are available using @TeX{} engines
+that produce PDF output (@pxref{texengines}): the routine
+@verbatim
+void functionshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, string shader);
+@end verbatim
+@noindent
+shades on picture @code{pic} the interior of path @code{g} according
+to fill rule @code{fillrule} using the @code{PostScript} calculator routine
+specified by the string @code{shader}; this routine takes 2 arguments,
+each in [0,1], and returns @code{colors(fillrule).length} color components.
+Function shading is illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/functionshading.pdf,,functionshading}@uref{http://asymptote.sourceforge.net/gallery/functionshading.asy,,.asy}}.
+
+@cindex unfill
+The following routine uses @code{evenodd} clipping together with the
+@code{^^} operator to unfill a region:
+
+@verbatim
+void unfill(picture pic=currentpicture, path g);
+@end verbatim
+
+@node clip, label, fill, Drawing commands
+@section clip
+@cindex @code{clip}
+@cindex @code{stroke}
+@verbatim
+void clip(picture pic=currentpicture, path g, stroke=false,
+ pen fillrule=currentpen);
+@end verbatim
+
+Clip the current contents of picture @code{pic} to the region bounded
+by the path @code{g}, using fill rule @code{fillrule} (@pxref{fillrule}).
+If @code{stroke=true}, the clipped portion is the same as the region
+that would be drawn with @code{draw(pic,g,zerowinding)}; in
+this case the path @code{g} need not be cyclic. For an illustration of
+picture clipping, see the first example in @ref{LaTeX usage}.
+
+@node label, , clip, Drawing commands
+@section label
+@cindex @code{label}
+@verbatim
+void label(picture pic=currentpicture, Label L, pair position,
+ align align=NoAlign, pen p=currentpen, filltype filltype=NoFill)
+@end verbatim
+
+Draw Label @code{L} on picture @code{pic} using pen @code{p}. If
+@code{align} is @code{NoAlign}, the label will be centered at user
+coordinate @code{position}; otherwise it will be aligned in the
+direction of @code{align} and displaced from @code{position} by
+the @code{PostScript} offset @code{align*labelmargin(p)}.
+@cindex @code{Align}
+The constant @code{Align} can be used to align the
+bottom-left corner of the label at @code{position}.
+@cindex @code{nullpen}
+@cindex @code{Label}
+@anchor{Label}
+The Label @code{L} can either be a string or the structure obtained by calling
+one of the functions
+@verbatim
+Label Label(string s="", pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(string s="", align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(Label L, pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+Label Label(Label L, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+@end verbatim
+The text of a Label can be scaled, slanted, rotated, or shifted by
+multiplying it on the left by an affine transform (@pxref{Transforms}).
+For example, @code{rotate(45)*xscale(2)*L} first scales @code{L} in the
+@math{x} direction and then rotates it counterclockwise by 45
+degrees. The final position of a Label can also be shifted by a
+@code{PostScript} coordinate translation: @code{shift(10,0)*L}.
+An explicit pen specified within the Label overrides other pen arguments.
+The @code{embed} argument determines how the Label should transform with the
+embedding picture:
+@table @code
+@item Shift
+@cindex @code{Shift}
+only shift with embedding picture;
+
+@item Rotate
+@cindex @code{Rotate}
+only shift and rotate with embedding picture (default);
+
+@item Rotate(pair z)
+@cindex @code{Rotate(pair z)}
+rotate with (picture-transformed) vector @code{z}.
+
+@item Slant
+@cindex @code{Slant}
+only shift, rotate, slant, and reflect with embedding picture;
+
+@item Scale
+@cindex @code{Scale}
+shift, rotate, slant, reflect, and scale with embedding picture.
+
+@end table
+
+To add a label to a path, use
+@verbatim
+void label(picture pic=currentpicture, Label L, path g, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill);
+@end verbatim
+@cindex @code{Relative}
+By default the label will be positioned at the midpoint of the path.
+An alternative label position (in the sense of @code{point(path p, real t)})
+may be specified as a real value for @code{position} in constructing
+the Label. The position @code{Relative(real)} specifies a location
+relative to the total arclength of the path. These convenient
+abbreviations are predefined:
+@cindex @code{BeginPoint}
+@cindex @code{MidPoint}
+@cindex @code{EndPoint}
+@verbatim
+position BeginPoint=Relative(0);
+position MidPoint=Relative(0.5);
+position EndPoint=Relative(1);
+@end verbatim
+
+@cindex @code{Relative}
+@cindex @code{LeftSide}
+@cindex @code{Center}
+@cindex @code{RightSide}
+Path labels are aligned in the direction @code{align}, which may
+be specified as an absolute compass direction (pair) or a direction
+@code{Relative(pair)} measured relative to a north axis
+in the local direction of the path. For convenience @code{LeftSide},
+@code{Center}, and @code{RightSide} are defined as @code{Relative(W)},
+@code{Relative((0,0))}, and @code{Relative(E)}, respectively.
+Multiplying @code{LeftSide} and @code{RightSide} on the
+left by a real scaling factor will move the label further away from or
+closer to the path.
+
+A label with a fixed-size arrow of length @code{arrowlength} pointing
+to @code{b} from direction @code{dir} can be produced with the routine
+@cindex @code{arrow}
+@verbatim
+void arrow(picture pic=currentpicture, Label L="", pair b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar arrow=Arrow, margin margin=EndMargin);
+@end verbatim
+If no alignment is specified (either in the Label or as an explicit
+argument), the optional Label will be aligned in the direction @code{dir},
+using margin @code{margin}.
+
+@cindex including images
+@cindex @code{graphic}
+@cindex @acronym{EPS}
+The function @code{string graphic(string name, string options="")}
+returns a string that can be used to include an encapsulated
+@code{PostScript} (@acronym{EPS}) file. Here, @code{name} is the name
+of the file to include and @code{options} is a string containing a
+comma-separated list of optional bounding box (@code{bb=llx lly urx
+ury}), width (@code{width=value}), height (@code{height=value}),
+rotation (@code{angle=value}), scaling (@code{scale=factor}), clipping
+(@code{clip=bool}), and draft mode (@code{draft=bool}) parameters. The
+@code{layer()} function can be used to force future objects to be
+drawn on top of the included image:
+@verbatim
+label(graphic("file.eps","width=1cm"),(0,0),NE);
+layer();
+@end verbatim
+
+@cindex @code{baseline}
+The @code{string baseline(string s, string template="\strut")}
+function can be used to enlarge the bounding box of labels to match a
+given template, so that their baselines will be typeset on a
+horizontal line. See @code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.pdf,,Pythagoras}@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.asy,,.asy}} for an example.
+
+One can prevent labels from overwriting one another with the
+@code{overwrite} pen attribute (@pxref{overwrite}).
+
+The structure @code{object} defined in @code{plain_Label.asy}
+allows Labels and frames to be treated in a uniform manner.
+A group of objects may be packed together into single frame with the routine
+@cindex @code{pack}
+@verbatim
+frame pack(pair align=2S ... object inset[]);
+@end verbatim
+@noindent
+To draw or fill a box (or ellipse or other path) around a Label and
+return the bounding object, use one of the routines
+@verbatim
+object draw(picture pic=currentpicture, Label L, envelope e,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+object draw(picture pic=currentpicture, Label L, envelope e, pair position,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+@noindent
+Here @code{envelope} is a boundary-drawing routine such as @code{box},
+@code{roundbox}, or @code{ellipse} defined in @code{plain_boxes.asy}
+(@pxref{envelope}).
+
+@cindex @code{texpath}
+The function @code{path[] texpath(Label L)} returns the path array that
+@TeX{} would fill to draw the Label @code{L}.
+
+@cindex @code{minipage}
+The @code{string minipage(string s, width=100pt)} function can be used
+to format string @code{s} into a paragraph of width @code{width}.
+This example uses @code{minipage}, @code{clip}, and @code{graphic} to
+produce a CD label:
+@sp 1
+@center @image{CDlabel}
+@verbatiminclude CDlabel.asy
+
+@node Bezier curves, Programming, Drawing commands, Top
+@chapter Bezier curves
+@cindex Bezier curves
+@cindex direction specifier
+Each interior node of a cubic spline may be given a
+direction prefix or suffix @code{@{dir@}}: the direction of the pair
+@code{dir} specifies the direction of the incoming or outgoing tangent,
+respectively, to the curve at that node. Exterior nodes may be
+given direction specifiers only on their interior side.
+
+A cubic spline between the node @math{z_0}, with postcontrol point
+@math{c_0}, and the node @math{z_1}, with precontrol point @math{c_1},
+is computed as the Bezier curve
+@sp 1
+@center @image{bezier,,,(1-t)^3*z_0+3t(1-t)^2*c_0+3t^2(1-t)*c_1+t^3*z_1 for 0 <=t <= 1.}
+
+As illustrated in the diagram below, the third-order midpoint (@math{m_5})
+constructed from two endpoints @math{z_0} and @math{z_1} and two control points
+@math{c_0} and @math{c_1}, is the point corresponding to @math{t=1/2} on
+the Bezier curve formed by the quadruple (@math{z_0}, @math{c_0},
+@math{c_1}, @math{z_1}). This allows one to recursively construct the
+desired curve, by using the newly extracted third-order midpoint as an
+endpoint and the respective second- and first-order midpoints as control
+points:
+@sp 1
+@center @image{bezier2}
+
+Here @math{m_0}, @math{m_1} and @math{m_2} are the first-order
+midpoints, @math{m_3} and @math{m_4} are the second-order midpoints, and
+@math{m_5} is the third-order midpoint.
+The curve is then constructed by recursively applying the algorithm to
+(@math{z_0}, @math{m_0}, @math{m_3}, @math{m_5}) and
+(@math{m_5}, @math{m_4}, @math{m_2}, @math{z_1}).
+
+In fact, an analogous property holds for points located at any
+fraction @math{t} in @math{[0,1]} of each segment, not just for
+midpoints (@math{t=1/2}).
+
+The Bezier curve constructed in this manner has the following properties:
+@itemize @bullet
+
+@item It is entirely contained in the convex hull of the given four points.
+
+@item It starts heading from the first endpoint to the first control point
+and finishes heading from the second control point to the second endpoint.
+
+@end itemize
+
+@cindex @code{controls}
+The user can specify explicit control points between two nodes like this:
+@verbatim
+draw((0,0)..controls (0,100) and (100,100)..(100,0));
+@end verbatim
+
+However, it is usually more convenient to just use the
+@code{..} operator, which tells @code{Asymptote} to choose its own
+control points using the algorithms described in Donald Knuth's
+monograph, The MetaFontbook, Chapter 14.
+The user can still customize the guide (or path) by specifying
+direction, tension, and curl values.
+
+The higher the tension, the straighter the curve is, and the more
+it approximates a straight line.
+@cindex @code{tension}
+@cindex @code{and}
+@cindex @code{atleast}
+One can change the spline tension from its default value of 1 to any
+real value greater than or equal to 0.75 (cf. John D. Hobby, Discrete and
+Computational Geometry 1, 1986):
+@verbatim
+draw((100,0)..tension 2 ..(100,100)..(0,100));
+draw((100,0)..tension 3 and 2 ..(100,100)..(0,100));
+draw((100,0)..tension atleast 2 ..(100,100)..(0,100));
+@end verbatim
+
+In these examples there is a space between @code{2} and @code{..}.
+This is needed as @code{2.} is interpreted as a numerical constant.
+
+@cindex @code{curl}
+The curl parameter specifies the curvature at the endpoints of a path
+(0 means straight; the default value of 1 means approximately circular):
+@verbatim
+draw((100,0){curl 0}..(100,100)..{curl 0}(0,100));
+@end verbatim
+
+@cindex @code{MetaPost ...@ }
+@cindex @code{::}
+The @code{MetaPost ...} path connector, which requests, when possible, an
+inflection-free curve confined to a triangle defined by the
+endpoints and directions, is implemented in @code{Asymptote} as the
+convenient abbreviation @code{::} for @code{..tension atleast 1 ..}
+(the ellipsis @code{...} is used in @code{Asymptote} to indicate a
+variable number of arguments; @pxref{Rest arguments}). For example,
+compare
+@verbatiminclude dots.asy
+@sp 1
+@center @image{dots}
+@noindent
+with
+@verbatiminclude colons.asy
+@sp 1
+@center @image{colons}
+
+@cindex @code{---}
+@cindex @code{&}
+The @code{---} connector is an abbreviation for @code{..tension atleast
+infinity..} and the @code{&} connector concatenates two paths, after
+first stripping off the last node of the first path (which normally
+should coincide with the first node of the second path).
+
+@node Programming, LaTeX usage, Bezier curves, Top
+@chapter Programming
+@cindex programming
+
+@menu
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides:: Bezier curves
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external @code{Asymptote} modules
+* Static:: Where to allocate your variable?
+@end menu
+
+Here is a short introductory example to the @code{Asymptote} programming
+language that highlights the similarity of its control structures
+with those of C, C++, and Java:
+@cindex declaration
+@cindex assignment
+@cindex conditional
+@cindex loop
+@cindex @code{if}
+@cindex @code{else}
+@cindex @code{for}
+@verbatim
+// This is a comment.
+
+// Declaration: Declare x to be a real variable;
+real x;
+
+// Assignment: Assign the real variable x the value 1.
+x=1.0;
+
+// Conditional: Test if x equals 1 or not.
+if(x == 1.0) {
+ write("x equals 1.0");
+} else {
+ write("x is not equal to 1.0");
+}
+
+// Loop: iterate 10 times
+for(int i=0; i < 10; ++i) {
+ write(i);
+}
+
+@end verbatim
+
+@cindex @code{while}
+@cindex @code{do}
+@cindex @code{break}
+@cindex @code{continue}
+@code{Asymptote} supports @code{while}, @code{do}, @code{break}, and
+@code{continue} statements just as in C/C++. It also supports the Java-style
+shorthand for iterating over all elements of an array:
+
+@cindex array iteration
+@anchor{array iteration}
+@verbatim
+// Iterate over an array
+int[] array={1,1,2,3,5};
+for(int k : array) {
+ write(k);
+}
+@end verbatim
+@noindent
+In addition, it supports many features beyond the ones found in those
+languages.
+
+@node Data types, Paths and guides, Programming, Programming
+@section Data types
+@cindex data types
+@code{Asymptote} supports the following data types (in addition to
+user-defined types):
+
+@table @code
+
+@item void
+@cindex @code{void}
+The void type is used only by functions that take or return no arguments.
+
+@item bool
+@cindex @code{bool}
+a boolean type that can only take on the values @code{true} or
+@code{false}. For example:
+@verbatim
+bool b=true;
+@end verbatim
+
+@noindent
+defines a boolean variable @code{b} and initializes it to the value
+@code{true}. If no initializer is given:
+@verbatim
+bool b;
+@end verbatim
+
+@noindent
+the value @code{false} is assumed.
+
+@item bool3
+@cindex @code{bool3}
+an extended boolean type that can take on the values
+@code{true}, @code{default}, or @code{false}. A bool3 type can be cast
+to or from a bool. The default initializer for bool3 is @code{default}.
+
+@item int
+@cindex @code{int}
+@cindex @code{intMin}
+@cindex @code{intMax}
+an integer type; if no initializer is given, the implicit value @code{0}
+is assumed. The minimum allowed value of an integer is @code{intMin} and the
+maximum value is @code{intMax}.
+
+@item real
+@cindex @code{real}
+@cindex @code{realMin}
+@cindex @code{realMax}
+@cindex @code{realEpsilon}
+@cindex @code{realDigits}
+@cindex @code{mask}
+@cindex @code{inf}
+@cindex @code{nan}
+@cindex @code{isnan}
+a real number; this should be set to the highest-precision native
+floating-point type on the architecture. The implicit initializer for
+reals is @code{0.0}. Real numbers have precision
+@code{realEpsilon}, with @code{realDigits} significant digits.
+The smallest positive real number is @code{realMin} and the largest
+positive real number is @code{realMax}.
+The variables @code{inf} and @code{nan}, along with the function
+@code{bool isnan(real x)} are useful when floating-point exceptions
+are masked with the @code{-mask} command-line option (the default in
+interactive mode).
+
+@item pair
+@cindex @code{pair}
+complex number, that is, an ordered pair of real components @code{(x,y)}.
+The real and imaginary parts of a pair @code{z} can read as @code{z.x}
+and @code{z.y}. We say that @code{x} and @code{y} are virtual members of
+the data element pair; they cannot be directly modified, however.
+The implicit initializer for pairs is @code{(0.0,0.0)}.
+
+There are a number of ways to take the complex conjugate of a pair:
+@example
+pair z=(3,4);
+z=(z.x,-z.y);
+z=z.x-I*z.y;
+z=conj(z);
+@end example
+
+Here @code{I} is the pair @code{(0,1)}.
+A number of built-in functions are defined for pairs:
+
+@table @code
+@item pair conj(pair z)
+@cindex @code{conj}
+returns the conjugate of @code{z};
+
+@item real length(pair z)
+@cindex @code{length}
+@cindex @code{abs}
+returns the complex modulus @code{|z|} of its argument @code{z}.
+For example,
+@example
+pair z=(3,4);
+length(z);
+@end example
+returns the result 5. A synonym for @code{length(pair)} is @code{abs(pair)};
+
+@item real angle(pair z, bool warn=true)
+@cindex @code{angle}
+returns the angle of @code{z} in radians in the interval
+[-@code{pi},@code{pi}] or @code{0} if @code{warn} is @code{false} and
+@code{z=(0,0)} (rather than producing an error);
+
+@item real degrees(pair z, bool warn=true)
+@cindex @code{degrees}
+returns the angle of @code{z} in degrees in the interval [0,360)
+or @code{0} if @code{warn} is @code{false} and @code{z=(0,0)} (rather than
+producing an error);
+
+@item pair unit(pair z)
+@cindex @code{unit}
+returns a unit vector in the direction of the pair @code{z};
+
+@item pair expi(real angle)
+@cindex @code{expi}
+returns a unit vector in the direction @code{angle} measured in radians;
+
+@item pair dir(real degrees)
+@cindex @code{dir}
+returns a unit vector in the direction @code{degrees} measured in degrees;
+
+@item real xpart(pair z)
+@cindex @code{xpart}
+returns @code{z.x};
+
+@item real ypart(pair z)
+@cindex @code{ypart}
+returns @code{z.y};
+
+@item pair realmult(pair z, pair w)
+@cindex @code{realmult}
+returns the element-by-element product @code{(z.x*w.x,z.y*w.y)};
+
+@item real dot(explicit pair z, explicit pair w)
+@cindex @code{dot}
+returns the dot product @code{z.x*w.x+z.y*w.y};
+
+@item real cross(explicit pair z, explicit pair w)
+@cindex @code{cross}
+returns the 2D scalar product @code{z.x*w.y-z.y*w.x};
+
+@cindex @code{orient}
+@item real orient(pair a, pair b, pair c);
+returns a positive (negative) value if @code{a--b--c--cycle} is oriented
+counterclockwise (clockwise) or zero if all three points are colinear.
+Equivalently, a positive (negative) value is returned if
+@code{c} lies to the left (right) of the line through @code{a} and @code{b}
+or zero if @code{c} lies on this line.
+The value returned can be expressed in terms of the 2D scalar cross product
+as @code{cross(a-c,b-c)}, which is the determinant
+@verbatim
+|a.x a.y 1|
+|b.x b.y 1|
+|c.x c.y 1|
+@end verbatim
+
+@cindex @code{incircle}
+@item real incircle(pair a, pair b, pair c, pair d);
+returns a positive (negative) value if @code{d} lies inside (outside)
+the circle passing through the counterclockwise-oriented points @code{a,b,c}
+or zero if @code{d} lies on the this circle.
+The value returned is the determinant
+@verbatim
+|a.x a.y a.x^2+a.y^2 1|
+|b.x b.y b.x^2+b.y^2 1|
+|c.x c.y c.x^2+c.y^2 1|
+|d.x d.y d.x^2+d.y^2 1|
+@end verbatim
+
+@item pair minbound(pair z, pair w)
+@cindex @code{minbound}
+returns @code{(min(z.x,w.x),min(z.y,w.y))};
+
+@item pair maxbound(pair z, pair w)
+@cindex @code{maxbound}
+returns @code{(max(z.x,w.x),max(z.y,w.y))}.
+
+@end table
+
+@item triple
+@cindex @code{triple}
+an ordered triple of real components @code{(x,y,z)} used for
+three-dimensional drawings. The respective components of a triple
+@code{v} can read as @code{v.x}, @code{v.y}, and @code{v.z}.
+The implicit initializer for triples is @code{(0.0,0.0,0.0)}.
+
+Here are the built-in functions for triples:
+@table @code
+@item real length(triple v)
+@cindex @code{length}
+returns the length @code{|v|} of the vector @code{v}.
+A synonym for @code{length(triple)} is @code{abs(triple)};
+
+@item real polar(triple v, bool warn=true)
+@cindex @code{polar}
+returns the colatitude of @code{v} measured from the @math{z} axis in radians
+or @code{0} if @code{warn} is @code{false} and @code{v=O} (rather than
+producing an error);
+
+@item real azimuth(triple v, bool warn=true)
+@cindex @code{azimuth}
+returns the longitude of @code{v} measured from the @math{x} axis in radians
+or @code{0} if @code{warn} is @code{false} and @code{v.x=v.y=0} (rather than
+producing an error);
+
+@item real colatitude(triple v, bool warn=true)
+@cindex @code{colatitude}
+returns the colatitude of @code{v} measured from the @math{z} axis in degrees
+or @code{0} if @code{warn} is @code{false} and @code{v=O} (rather than
+producing an error);
+
+@item real latitude(triple v, bool warn=true)
+@cindex @code{latitude}
+returns the latitude of @code{v} measured from the @math{xy} plane in degrees
+or @code{0} if @code{warn} is @code{false} and @code{v=O} (rather than
+producing an error);
+
+@item real longitude(triple v, bool warn=true)
+@cindex @code{longitude}
+returns the longitude of @code{v} measured from the @math{x} axis in degrees
+or @code{0} if @code{warn} is @code{false} and @code{v.x=v.y=0} (rather than
+producing an error);
+
+@item triple unit(triple v)
+@cindex @code{unit}
+returns a unit triple in the direction of the triple @code{v};
+
+@item triple expi(real polar, real azimuth)
+@cindex @code{expi}
+returns a unit triple in the direction @code{(polar,azimuth)}
+measured in radians;
+
+@item triple dir(real colatitude, real longitude)
+@cindex @code{dir}
+returns a unit triple in the direction @code{(colatitude,longitude)}
+measured in degrees;
+
+@item real xpart(triple v)
+@cindex @code{xpart}
+returns @code{v.x};
+
+@item real ypart(triple v)
+@cindex @code{ypart}
+returns @code{v.y};
+
+@item real zpart(triple v)
+@cindex @code{zpart}
+returns @code{v.z};
+
+@item real dot(triple u, triple v)
+@cindex @code{dot}
+returns the dot product @code{u.x*v.x+u.y*v.y+u.z*v.z};
+
+@item triple cross(triple u, triple v)
+@cindex @code{cross}
+returns the cross product
+
+@code{(u.y*v.z-u.z*v.y,u.z*v.x-u.x*v.z,u.x*v.y-v.x*u.y)};
+
+@item triple minbound(triple u, triple v)
+@cindex @code{minbound}
+returns @code{(min(u.x,v.x),min(u.y,v.y),min(u.z,v.z))};
+
+@item triple maxbound(triple u, triple v)
+@cindex @code{maxbound}
+returns @code{(max(u.x,v.x),max(u.y,v.y),max(u.z,v.z)}).
+
+@end table
+
+@item string
+@cindex @code{string}
+@cindex @TeX{} string
+a character string, implemented using the STL @code{string} class.
+
+Strings delimited by double quotes (@code{"}) are subject to the
+following mappings to allow the use of double quotes in @TeX{} (e.g.@ for
+using the @code{babel} package, @pxref{babel}):
+
+@itemize @bullet
+@item \" maps to "
+@item \\ maps to \\
+@end itemize
+
+@cindex @code{C} string
+Strings delimited by single quotes (@code{'}) have the same mappings as
+character strings in ANSI @code{C}:
+
+@itemize @bullet
+@item \' maps to '
+@item \" maps to "
+@item \? maps to ?
+@item \\ maps to backslash
+@item \a maps to alert
+@item \b maps to backspace
+@item \f maps to form feed
+@item \n maps to newline
+@item \r maps to carriage return
+@item \t maps to tab
+@item \v maps to vertical tab
+@item \0-\377 map to corresponding octal byte
+@item \x0-\xFF map to corresponding hexadecimal byte
+@end itemize
+
+The implicit initializer for strings is the empty string @code{""}.
+Strings may be concatenated with the @code{+} operator. In the following
+string functions, position @code{0} denotes the start of the string:
+@table @code
+
+@cindex @code{length}
+@item int length(string s)
+returns the length of the string @code{s};
+
+@cindex @code{find}
+@item int find(string s, string t, int pos=0)
+returns the position of the first occurrence of string @code{t} in string
+@code{s} at or after position @code{pos}, or -1 if @code{t} is not a
+substring of @code{s};
+
+@cindex @code{rfind}
+@item int rfind(string s, string t, int pos=-1)
+returns the position of the last occurrence of string @code{t} in string
+@code{s} at or before position @code{pos} (if @code{pos}=-1, at the end
+of the string @code{s}), or -1 if @code{t} is not a substring of @code{s};
+
+@cindex @code{insert}
+@item string insert(string s, int pos, string t)
+returns the string formed by inserting string @code{t} at position
+@code{pos} in @code{s};
+
+@cindex @code{erase}
+@item string erase(string s, int pos, int n)
+returns the string formed by erasing the string of length @code{n}
+(if @code{n}=-1, to the end of the string @code{s}) at
+position @code{pos} in @code{s};
+
+@cindex @code{substr}
+@item string substr(string s, int pos, int n=-1)
+returns the substring of @code{s} starting at position @code{pos}
+and of length @code{n} (if @code{n}=-1, until the end of the
+string @code{s});
+
+@cindex @code{reverse}
+@item string reverse(string s)
+returns the string formed by reversing string @code{s};
+
+@item string replace(string s, string before, string after)
+@cindex @code{replace}
+returns a string with all occurrences of the string @code{before} in the
+string @code{s} changed to the string @code{after};
+
+@item string replace(string s, string[][] table)
+returns a string constructed by translating in string @code{s} all
+occurrences of the string @code{before} in an array @code{table} of
+string pairs @{@code{before},@code{after}@} to the corresponding
+string @code{after};
+
+@cindex @code{split}
+@item string[] split(string s, string delimiter="")
+returns an array of strings obtained by splitting @code{s} into substrings
+delimited by @code{delimiter} (an empty delimiter signifies a space,
+but with duplicate delimiters discarded);
+
+@cindex @code{array}
+@cindex @code{operator +(...string[] a)}.
+@item string[] array(string s)
+returns an array of strings obtained by splitting @code{s} into
+individual characters. The inverse operation is provided by
+@code{operator +(...string[] a)}.
+
+@anchor{format}
+@item string format(string s, int n, string locale="")
+@cindex @code{format}
+returns a string containing @code{n} formatted according to the C-style format
+string @code{s} using locale @code{locale} (or the current locale if an
+empty string is specified), following the behaviour of the C function
+@code{fprintf}), except that only one data field is allowed.
+
+@item string format(string s=defaultformat, bool forcemath=false, string s=defaultseparator, real x, string locale="")
+returns a string containing @code{x} formatted according to the C-style format
+string @code{s} using locale @code{locale} (or the current locale if an
+empty string is specified), following the behaviour of the C function
+@code{fprintf}), except that only one data field is allowed, trailing
+zeros are removed by default (unless @code{#} is specified), and
+if @code{s} specifies math mode or @code{forcemath=true}, @TeX{} is
+used to typeset scientific notation using the
+@code{defaultseparator="\!\times\!";};
+
+@cindex @code{hex}
+@cindex @code{hexadecimal}
+@item int hex(string s);
+casts a hexadecimal string @code{s} to an integer;
+
+@cindex @code{ascii}
+@cindex @code{ascii}
+@item int ascii(string s);
+returns the ASCII code for the first character of string @code{s};
+
+@cindex @code{string}
+@item string string(real x, int digits=realDigits)
+casts @code{x} to a string using precision @code{digits} and the C locale;
+
+@cindex @code{locale}
+@item string locale(string s="")
+sets the locale to the given string, if nonempty, and returns the
+current locale;
+
+@item string time(string format="%a %b %d %T %Z %Y")
+@cindex @code{time}
+@cindex @code{date}
+@cindex @code{strftime}
+returns the current time formatted by the ANSI C routine
+@code{strftime} according to the string @code{format} using the current
+locale. Thus
+@verbatim
+time();
+time("%a %b %d %H:%M:%S %Z %Y");
+@end verbatim
+
+@noindent
+are equivalent ways of returning the current time in the default
+format used by the @code{UNIX} @code{date} command;
+
+@cindex @code{seconds}
+@cindex @code{strptime}
+@item int seconds(string t="", string format="")
+returns the time measured in seconds after the Epoch (Thu Jan 01
+00:00:00 UTC 1970) as determined by the ANSI C routine @code{strptime}
+according to the string @code{format} using the current locale, or the
+current time if @code{t} is the empty string.
+Note that the @code{"%Z"} extension to the POSIX @code{strptime}
+specification is ignored by the current GNU C Library. If an error occurs, the
+value -1 is returned. Here are some examples:
+@verbatim
+seconds("Mar 02 11:12:36 AM PST 2007","%b %d %r PST %Y");
+seconds(time("%b %d %r %z %Y"),"%b %d %r %z %Y");
+seconds(time("%b %d %r %Z %Y"),"%b %d %r "+time("%Z")+" %Y");
+1+(seconds()-seconds("Jan 1","%b %d"))/(24*60*60);
+@end verbatim
+The last example returns today's ordinal date, measured from the
+beginning of the year.
+
+@cindex @code{time}
+@cindex @code{strftime}
+@item string time(int seconds, string format="%a %b %d %T %Z %Y")
+returns the time corresponding to @code{seconds} seconds after the Epoch
+(Thu Jan 01 00:00:00 UTC 1970) formatted by the ANSI C routine
+@code{strftime} according to the string @code{format} using the current
+locale. For example, to return the date corresponding to 24 hours ago:
+@verbatim
+time(seconds()-24*60*60);
+@end verbatim
+
+@cindex @code{system}
+@item int system(string s)
+@item int system(string[] s)
+if the setting @code{safe} is false, call the arbitrary system command @code{s};
+
+@cindex @code{asy}
+@item void asy(string format, bool overwrite=false ... string[] s)
+conditionally process each file name in array @code{s} in a new environment,
+using format @code{format}, overwriting the output file only if
+@code{overwrite} is true;
+
+@cindex @code{abort}
+@item void abort(string s="")
+aborts execution (with a non-zero return code in batch mode); if string
+@code{s} is nonempty, a diagnostic message constructed from the source
+file, line number, and @code{s} is printed;
+
+@cindex @code{assert}
+@item void assert(bool b, string s="")
+aborts execution with an error message constructed from @code{s} if
+@code{b=false};
+
+@cindex @code{exit}
+@item void exit()
+exits (with a zero error return code in batch mode);
+
+@cindex @code{sleep}
+@item void sleep(int seconds)
+pauses for the given number of seconds;
+
+@cindex @code{usleep}
+@item void usleep(int microseconds)
+pauses for the given number of microseconds;
+
+@cindex @code{beep}
+@item void beep()
+produces a beep on the console;
+
+@end table
+
+@cindex @code{typedef}
+
+@end table
+
+As in C/C++, complicated types may be abbreviated with @code{typedef}
+(see the example in @ref{Functions}).
+
+@node Paths and guides, Pens, Data types, Programming
+@section Paths and guides
+
+@table @code
+
+@item path
+@cindex @code{path}
+a cubic spline resolved into a fixed path.
+The implicit initializer for paths is @code{nullpath}.
+
+@cindex @code{circle}
+@anchor{circle}
+For example, the routine @code{circle(pair c, real r)}, which returns a
+Bezier curve approximating a circle of radius @code{r} centered on @code{c},
+is based on @code{unitcircle} (@pxref{unitcircle}):
+@verbatim
+path circle(pair c, real r)
+{
+ return shift(c)*scale(r)*unitcircle;
+}
+@end verbatim
+If high accuracy is needed, a true circle may be produced with the
+routine @code{Circle} defined in the module @code{@uref{http://asymptote.sourceforge.net/gallery/graph.pdf,,graph}@uref{http://asymptote.sourceforge.net/gallery/graph.asy,,.asy}}:
+@cindex @code{Circle}
+@verbatim
+import graph;
+path Circle(pair c, real r, int n=nCircle);
+@end verbatim
+
+A circular arc consistent with @code{circle} centered on
+@code{c} with radius @code{r} from @code{angle1} to @code{angle2}
+degrees, drawing counterclockwise if @code{angle2 >= angle1}, can be
+constructed with
+@cindex @code{arc}
+@verbatim
+path arc(pair c, real r, real angle1, real angle2);
+@end verbatim
+One may also specify the direction explicitly:
+@verbatim
+path arc(pair c, real r, real angle1, real angle2, bool direction);
+@end verbatim
+Here the direction can be specified as CCW (counter-clockwise) or CW
+(clockwise). For convenience, an arc centered at @code{c} from pair
+@code{z1} to @code{z2} (assuming @code{|z2-c|=|z1-c|}) in the may also
+be constructed with
+@verbatim
+path arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW)
+@end verbatim
+
+If high accuracy is needed, true arcs may be produced with routines
+in the module @code{@uref{http://asymptote.sourceforge.net/gallery/graph.pdf,,graph}@uref{http://asymptote.sourceforge.net/gallery/graph.asy,,.asy}} that produce Bezier curves with @code{n}
+control points:
+@cindex @code{Arc}
+@verbatim
+import graph;
+path Arc(pair c, real r, real angle1, real angle2, bool direction,
+ int n=nCircle);
+path Arc(pair c, real r, real angle1, real angle2, int n=nCircle);
+path Arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW, int n=nCircle);
+@end verbatim
+
+An ellipse can be drawn with the routine
+@cindex @code{ellipse}
+@verbatim
+path ellipse(pair c, real a, real b)
+{
+ return shift(c)*scale(a,b)*unitcircle;
+}
+@end verbatim
+
+A brace can be constructed between pairs @code{a} and @code{b} with
+@cindex @code{brace}
+@verbatim
+path brace(pair a, pair b, real amplitude=bracedefaultratio*length(b-a));
+@end verbatim
+
+This example illustrates the use of all five guide connectors discussed
+in @ref{Tutorial} and @ref{Bezier curves}:
+@verbatiminclude join.asy
+@sp 1
+@center @image{join}
+
+Here are some useful functions for paths:
+
+@table @code
+
+@cindex @code{length}
+@item int length(path p);
+This is the number of (linear or cubic) segments in path @code{p}.
+If @code{p} is cyclic, this is the same as the number of nodes in @code{p}.
+
+@cindex @code{size}
+@item int size(path p);
+This is the number of nodes in the path @code{p}.
+If @code{p} is cyclic, this is the same as @code{length(p)}.
+
+@cindex @code{cyclic}
+@item bool cyclic(path p);
+returns @code{true} iff path @code{p} is cyclic.
+
+@cindex @code{straight}
+@item bool straight(path p, int i);
+returns @code{true} iff the segment of path @code{p} between node
+@code{i} and node @code{i+1} is straight.
+
+@cindex @code{piecewisestraight}
+@item bool piecewisestraight(path p)
+returns @code{true} iff the path @code{p} is piecewise straight.
+
+@cindex @code{point}
+@item pair point(path p, int t);
+If @code{p} is cyclic, return the coordinates of node @code{t} mod
+@code{length(p)}. Otherwise, return the coordinates of node @code{t},
+unless @code{t} < 0 (in which case @code{point(0)} is returned) or
+@code{t} > @code{length(p)} (in which case @code{point(length(p))}
+is returned).
+
+@item pair point(path p, real t);
+This returns the coordinates of the point between node @code{floor(t)}
+and @code{floor(t)+1} corresponding to the cubic spline parameter
+@code{t-floor(t)} (@pxref{Bezier curves}). If @code{t} lies outside the range
+[0,@code{length(p)}], it is first reduced modulo @code{length(p)}
+in the case where @code{p} is cyclic or else converted to the corresponding
+endpoint of @code{p}.
+
+@cindex @code{dir}
+@item pair dir(path p, int t, int sign=0, bool normalize=true);
+If @code{sign < 0}, return the direction (as a pair) of the incoming tangent
+to path @code{p} at node @code{t}; if @code{sign > 0}, return the
+direction of the outgoing tangent. If @code{sign=0}, the mean of these
+two directions is returned.
+
+@item pair dir(path p, real t, bool normalize=true);
+returns the direction of the tangent to path @code{p} at the point
+between node @code{floor(t)} and @code{floor(t)+1} corresponding to the
+cubic spline parameter @code{t-floor(t)} (@pxref{Bezier curves}).
+
+@item pair dir(path p)
+returns dir(p,length(p)).
+
+@item pair dir(path p, path q)
+returns unit(dir(p)+dir(q)).
+
+@cindex @code{accel}
+@item pair accel(path p, int t, int sign=0);
+If @code{sign < 0}, return the acceleration of the incoming path
+@code{p} at node @code{t}; if @code{sign > 0}, return the
+acceleration of the outgoing path. If @code{sign=0}, the mean of these
+two accelerations is returned.
+
+@cindex @code{accel}
+@item pair accel(path p, real t);
+returns the acceleration of the path @code{p} at the point @code{t}.
+
+@cindex @code{radius}
+@item real radius(path p, real t);
+returns the radius of curvature of the path @code{p} at the point @code{t}.
+
+@cindex @code{precontrol}
+@item pair precontrol(path p, int t);
+returns the precontrol point of @code{p} at node @code{t}.
+
+@item pair precontrol(path p, real t);
+returns the effective precontrol point of @code{p} at parameter @code{t}.
+
+@cindex @code{postcontrol}
+@item pair postcontrol(path p, int t);
+returns the postcontrol point of @code{p} at node @code{t}.
+
+@item pair postcontrol(path p, real t);
+returns the effective postcontrol point of @code{p} at parameter @code{t}.
+
+@cindex @code{arclength}
+@item real arclength(path p);
+returns the length (in user coordinates) of the piecewise linear
+or cubic curve that path @code{p} represents.
+
+@cindex @code{arctime}
+@item real arctime(path p, real L);
+returns the path "time", a real number between 0 and the length of
+the path in the sense of @code{point(path p, real t)}, at which the
+cumulative arclength (measured from the beginning of the path) equals @code{L}.
+
+@cindex @code{arcpoint}
+@item real arcpoint(path p, real L);
+returns @code{point(p,arctime(p,L))}.
+
+@cindex @code{dirtime}
+@item real dirtime(path p, pair z);
+returns the first "time", a real number between 0 and the length of
+the path in the sense of @code{point(path, real)}, at which the tangent
+to the path has the direction of pair @code{z}, or -1 if this never happens.
+
+@cindex @code{reltime}
+@item real reltime(path p, real l);
+returns the time on path @code{p} at the relative fraction @code{l} of
+its arclength.
+
+@cindex @code{relpoint}
+@item pair relpoint(path p, real l);
+returns the point on path @code{p} at the relative fraction @code{l} of its
+arclength.
+
+@cindex @code{midpoint}
+@item pair midpoint(path p);
+returns the point on path @code{p} at half of its arclength.
+
+@cindex @code{reverse}
+@item path reverse(path p);
+returns a path running backwards along @code{p}.
+
+@cindex @code{subpath}
+@item path subpath(path p, int a, int b);
+returns the subpath of @code{p} running from node @code{a} to node @code{b}.
+If @code{a} < @code{b}, the direction of the subpath is reversed.
+
+@item path subpath(path p, real a, real b);
+returns the subpath of @code{p} running from path time @code{a} to path
+time @code{b}, in the sense of @code{point(path, real)}. If @code{a} <
+@code{b}, the direction of the subpath is reversed.
+
+@cindex @code{intersect}
+@item real[] intersect(path p, path q, real fuzz=-1);
+If @code{p} and @code{q} have at least one intersection point, return a
+real array of length 2 containing the times representing the respective
+path times along @code{p} and @code{q}, in the sense of
+@code{point(path, real)}, for one such intersection point (as chosen by
+the algorithm described on page 137 of @code{The MetaFontbook}).
+The computations are performed to the absolute error specified by @code{fuzz},
+or if @code{fuzz < 0}, to machine precision. If the paths do not
+intersect, return a real array of length 0.
+
+@cindex @code{intersections}
+@item real[][] intersections(path p, path q, real fuzz=-1);
+Return all (unless there are infinitely many) intersection times of
+paths @code{p} and @code{q} as a sorted array of real arrays of length 2
+(@pxref{sort}). The computations are performed to the absolute error
+specified by @code{fuzz}, or if @code{fuzz < 0}, to machine precision.
+
+@cindex @code{intersections}
+@item real[] intersections(path p, explicit pair a, explicit pair b, real fuzz=-1);
+Return all (unless there are infinitely many) intersection times of path
+@code{p} with the (infinite) line through points @code{a} and @code{b}
+as a sorted array. The intersections returned are guaranteed to be
+correct to within the absolute error specified by @code{fuzz}, or if
+@code{fuzz < 0}, to machine precision.
+
+@cindex @code{times}
+@item real[] times(path p, real x)
+returns all intersection times of path @code{p} with the vertical line
+through @code{(x,0)}.
+
+@cindex @code{times}
+@item real[] times(path p, explicit pair z)
+returns all intersection times of path @code{p} with the horizontal line
+through @code{(0,z.y)}.
+
+@cindex @code{mintimes}
+@item real[] mintimes(path p)
+returns an array of length 2 containing times at which path @code{p}
+reaches its minimal horizontal and vertical extents, respectively.
+
+@cindex @code{maxtimes}
+@item real[] maxtimes(path p)
+returns an array of length 2 containing times at which path @code{p}
+reaches its maximal horizontal and vertical extents, respectively.
+
+@cindex @code{intersectionpoint}
+@item pair intersectionpoint(path p, path q, real fuzz=-1);
+returns the intersection point @code{point(p,intersect(p,q,fuzz)[0])}.
+
+@cindex @code{intersectionpoints}
+@item pair[] intersectionpoints(path p, path q, real fuzz=-1);
+returns an array containing all intersection points of the paths
+@code{p} and @code{q}.
+
+@anchor{extension}
+@cindex @code{whatever}
+@cindex @code{extension}
+@item pair extension(pair P, pair Q, pair p, pair q);
+returns the intersection point of the extensions of the line segments
+@code{P--Q} and @code{p--q}, or if the lines are parallel,
+@code{(infinity,infinity)}.
+
+@cindex @code{cut}
+@cindex @code{slice}
+@item slice cut(path p, path knife, int n);
+returns the portions of path @code{p} before and after the @code{n}th
+intersection of @code{p} with path @code{knife} as a structure
+@code{slice} (if no intersection exist is found, the entire path is
+considered to be `before' the intersection):
+@verbatim
+struct slice {
+ path before,after;
+}
+@end verbatim
+The argument @code{n} is treated as modulo the number of intersections.
+
+@cindex @code{firstcut}
+@cindex @code{slice}
+@item slice firstcut(path p, path knife);
+equivalent to @code{cut(p,knife,0);}
+@cindex @code{MetaPost cutbefore}
+Note that @code{firstcut.after} plays the role of the @code{MetaPost
+cutbefore} command.
+
+@cindex @code{lastcut}
+@item slice lastcut(path p, path knife);
+equivalent to @code{cut(p,knife,-1);}
+@cindex @code{MetaPost cutafter}
+Note that @code{lastcut.before} plays the role of the
+@code{MetaPost cutafter} command.
+
+@cindex @code{buildcycle}
+@item path buildcycle(... path[] p);
+This returns the path surrounding a region bounded by a list of two or more
+consecutively intersecting paths, following the behaviour of the
+@code{MetaPost buildcycle} command.
+
+@cindex @code{min}
+@item pair min(path p);
+returns the pair (left,bottom) for the path bounding box of path @code{p}.
+
+@cindex @code{max}
+@item pair max(path p);
+returns the pair (right,top) for the path bounding box of path @code{p}.
+
+@cindex @code{windingnumber}
+@cindex @code{undefined}
+@item int windingnumber(path p, pair z);
+returns the winding number of the cyclic path @code{p} relative to the point
+@code{z}. The winding number is positive if the path encircles @code{z} in the
+counterclockwise direction. If @code{z} lies on @code{p} the constant
+@code{undefined} (defined to be the largest odd integer) is returned.
+
+@cindex @code{interior}
+@item bool interior(int windingnumber, pen fillrule)
+returns true if @code{windingnumber} corresponds to an interior point
+according to @code{fillrule}.
+
+@cindex @code{inside}
+@item bool inside(path p, pair z, pen fillrule=currentpen);
+returns @code{true} iff the point @code{z} lies inside or on the edge of
+the region bounded by the cyclic path @code{p} according to the fill
+rule @code{fillrule} (@pxref{fillrule}).
+
+@cindex @code{inside}
+@item int inside(path p, path q, pen fillrule=currentpen);
+returns @code{1} if the cyclic path @code{p} strictly contains @code{q}
+according to the fill rule @code{fillrule} (@pxref{fillrule}), @code{-1}
+if the cyclic path @code{q} strictly contains @code{p}, and @code{0}
+otherwise.
+
+@cindex @code{inside}
+@item pair inside(path p, pen fillrule=currentpen);
+returns an arbitrary point strictly inside a cyclic path @code{p}
+according to the fill rule @code{fillrule} (@pxref{fillrule}).
+
+@cindex @code{strokepath}
+@item path[] strokepath(path g, pen p=currentpen);
+returns the path array that @code{PostScript} would fill in drawing path
+@code{g} with pen @code{p}.
+
+@end table
+
+@item guide
+@cindex @code{guide}
+an unresolved cubic spline (list of cubic-spline nodes and control points).
+The implicit initializer for a guide is @code{nullpath}; this is useful
+for building up a guide within a loop.
+
+A guide is similar to a path except that the computation of the cubic spline is
+deferred until drawing time (when it is resolved into a path); this allows
+two guides with free endpoint conditions to be joined together smoothly.
+The solid curve in the following example is built up incrementally as
+a guide, but only resolved at drawing time; the dashed curve is
+incrementally resolved at each iteration, before the entire set of nodes
+(shown in red) is known:
+
+@verbatiminclude mexicanhat.asy
+@sp 1
+@center @image{mexicanhat}
+
+We point out an efficiency distinction in the use of guides and paths:
+@verbatim
+guide g;
+for(int i=0; i < 10; ++i)
+ g=g--(i,i);
+path p=g;
+@end verbatim
+
+@noindent
+runs in linear time, whereas
+@verbatim
+path p;
+for(int i=0; i < 10; ++i)
+ p=p--(i,i);
+@end verbatim
+
+@noindent
+runs in quadratic time, as the entire path up to that point is copied at each
+step of the iteration.
+
+The following routines can be used to examine the individual elements of
+a guide without actually resolving the guide to a fixed path (except for
+internal cycles, which are resolved):
+
+@table @code
+
+@cindex @code{size}
+@item int size(guide g);
+Analogous to @code{size(path p)}.
+
+@cindex @code{length}
+@item int length(guide g);
+Analogous to @code{length(path p)}.
+
+@cindex @code{cyclic}
+@item bool cyclic(path p);
+Analogous to @code{cyclic(path p)}.
+
+@cindex @code{point}
+@item pair point(guide g, int t);
+Analogous to @code{point(path p, int t)}.
+
+@cindex @code{reverse}
+@item guide reverse(guide g);
+Analogous to @code{reverse(path p)}. If @code{g} is cyclic and
+also contains a secondary cycle, it is first solved to a
+path, then reversed. If @code{g} is not cyclic but contains an internal
+cycle, only the internal cycle is solved before reversal. If there are
+no internal cycles, the guide is reversed but not solved to a path.
+
+@cindex @code{dirSpecifier}
+@item pair[] dirSpecifier(guide g, int i);
+This returns a pair array of length 2 containing the outgoing (in
+element 0) and incoming (in element 1) direction specifiers (or
+@code{(0,0)} if none specified) for the segment of guide @code{g}
+between nodes @code{i} and @code{i+1}.
+
+@cindex @code{controlSpecifier}
+@item pair[] controlSpecifier(guide g, int i);
+If the segment of guide @code{g} between nodes @code{i} and @code{i+1}
+has explicit outgoing and incoming control points, they are returned as
+elements 0 and 1, respectively, of a two-element array. Otherwise, an
+empty array is returned.
+
+@cindex @code{tensionSpecifier}
+@item tensionSpecifier tensionSpecifier(guide g, int i);
+This returns the tension specifier for the segment of guide @code{g} between
+nodes @code{i} and @code{i+1}. The individual components of the
+@code{tensionSpecifier} type can be accessed as the virtual members
+@code{in}, @code{out}, and @code{atLeast}.
+
+@cindex @code{curlSpecifier}
+@item real[] curlSpecifier(guide g);
+This returns an array containing the initial curl specifier (in element 0)
+and final curl specifier (in element 1) for guide @code{g}.
+
+@end table
+
+As a technical detail we note that a direction specifier given to
+@code{nullpath} modifies the node on the other side: the guides
+@verbatim
+a..{up}nullpath..b;
+c..nullpath{up}..d;
+e..{up}nullpath{down}..f;
+@end verbatim
+are respectively equivalent to
+@verbatim
+a..nullpath..{up}b;
+c{up}..nullpath..d;
+e{down}..nullpath..{up}f;
+@end verbatim
+
+@end table
+
+@node Pens, Transforms, Paths and guides, Programming
+@section Pens
+
+@cindex @code{pen}
+@cindex @code{currentpen}
+@cindex @code{MetaPost pickup}
+In @code{Asymptote}, pens provide a context for the four basic drawing
+commands (@pxref{Drawing commands}). They are used to specify the
+following drawing attributes: color, line type, line width, line cap,
+line join, fill rule, text alignment, font, font size, pattern,
+overwrite mode, and calligraphic transforms on the pen nib. The
+default pen used by the drawing routines is called
+@code{currentpen}. This provides the same functionality as the
+@code{MetaPost} command @code{pickup}.
+The implicit initializer for pens is @code{defaultpen}.
+
+@cindex @code{+}
+@cindex @code{*}
+Pens may be added together with the nonassociative binary
+operator @code{+}. This will add the colors of the two pens.
+All other non-default attributes of the rightmost pen will
+override those of the leftmost pen. Thus, one can obtain a yellow
+dashed pen by saying @code{dashed+red+green} or @code{red+green+dashed}
+or @code{red+dashed+green}. The binary operator @code{*}
+can be used to scale the color of a pen by a real number, until it
+saturates with one or more color components equal to 1.
+
+@itemize @bullet
+
+@item Colors are specified using one of the following colorspaces:
+@cindex color
+@table @code
+@item pen gray(real g);
+@cindex @code{gray}
+@cindex grayscale
+This produces a grayscale color, where the intensity @code{g} lies in the
+interval [0,1], with 0.0 denoting black and 1.0 denoting white.
+
+@item pen rgb(real r, real g, real b);
+@cindex @code{rgb}
+This produces an @acronym{RGB} color, where each of the red, green,
+and blue intensities @code{r}, @code{g}, @code{b}, lies in the interval [0,1].
+
+@item pen RGB(int r, int g, int b);
+@cindex @code{rgb}
+This produces an @acronym{RGB} color, where each of the red, green,
+and blue intensities @code{r}, @code{g}, @code{b}, lies in the
+interval [0,255].
+
+@item pen cmyk(real c, real m, real y, real k);
+@cindex @code{cmyk}
+This produces a @acronym{CMYK} color, where each of the cyan, magenta,
+yellow, and black intensities @code{c}, @code{m}, @code{y}, @code{k},
+lies in the interval [0,1].
+
+@item pen invisible;
+@cindex @code{invisible}
+This special pen writes in invisible ink, but adjusts the bounding
+box as if something had been drawn (like the @code{\phantom}
+command in @TeX{}). The function @code{bool invisible(pen)} can be used
+to test whether a pen is invisible.
+
+@end table
+
+@cindex @code{defaultpen}
+The default color is @code{black}; this may be changed with the routine
+@code{defaultpen(pen)}. The function @code{colorspace(pen p)} returns
+the colorspace of pen @code{p} as a string (@code{"gray"}, @code{"rgb"},
+@code{"cmyk"}, or @code{""}).
+
+@cindex @code{colors}
+The function @code{real[] colors(pen)} returns the color components of a pen.
+The functions @code{pen gray(pen)}, @code{pen rgb(pen)}, and
+@code{pen cmyk(pen)} return new pens obtained by converting their
+arguments to the respective color spaces.
+@cindex @code{colorless}
+The function @code{colorless(pen=currentpen)} returns a copy of its argument
+with the color attributes stripped (to avoid color mixing).
+
+A 6-character RGB hexadecimal string can be converted to a pen with
+the routine
+@cindex @code{rgb}
+@cindex @code{hexadecimal}
+@verbatim
+pen rgb(string s);
+@end verbatim
+@noindent
+A pen can be converted to a hexadecimal string with
+@cindex @code{hex}
+@item string hex(pen p);
+
+Various shades and mixtures of the grayscale primary colors
+@code{black} and @code{white}, @acronym{RGB} primary colors
+@code{red}, @code{green}, and @code{blue}, and
+@acronym{RGB} secondary colors @code{cyan}, @code{magenta}, and @code{yellow}
+are defined as named colors, along with the @acronym{CMYK} primary
+colors @code{Cyan}, @code{Magenta}, @code{Yellow}, and @code{Black}, in
+the module @code{plain}:
+@sp 1
+@center @image{colors}
+
+The standard 140 @acronym{RGB} @code{X11} colors can be imported with
+the command
+@verbatim
+import x11colors;
+@end verbatim
+and the standard 68 @acronym{CMYK} @TeX{} colors can be imported with
+the command
+@verbatim
+import texcolors;
+@end verbatim
+Note that there is some overlap between these two standards
+and the definitions of some colors (e.g.@ @code{Green}) actually disagree.
+
+@code{Asymptote} also comes with a @code{asycolors.sty} @code{LaTeX} package
+that defines to @code{LaTeX} @acronym{CMYK} versions of
+@code{Asymptote}'s predefined colors, so that they can be used
+directly within @code{LaTeX} strings. Normally, such colors are
+passed to @code{LaTeX} via a pen argument; however, to change the
+color of only a portion of a string, say for a slide presentation,
+(@pxref{slide}) it may be desirable to specify the color directly to
+@code{LaTeX}. This file can be passed to @code{LaTeX} with the
+@code{Asymptote} command
+@verbatim
+usepackage("asycolors");
+@end verbatim
+
+The structure @code{hsv} defined in @code{plain_pens.asy} may be used
+to convert between @acronym{HSV} and @acronym{RGB} spaces, where
+the hue @code{h} is an angle in @math{[0,360)} and the saturation
+@code{s} and value @code{v} lie in @code{[0,1]}:
+@verbatim
+pen p=hsv(180,0.5,0.75);
+write(p); // ([default], red=0.375, green=0.75, blue=0.75)
+hsv q=p;
+write(q.h,q.s,q.v); // 180 0.5 0.75
+@end verbatim
+
+@item Line types are specified with the function
+@code{pen linetype(real[] a, real offset=0, bool scale=true, bool adjust=true)},
+@cindex @code{solid}
+@cindex @code{dashed}
+@cindex @code{dotted}
+@cindex @code{longdashed}
+@cindex @code{dashdotted}
+@cindex @code{longdashdotted}
+where @code{a} is an array of real array numbers.
+The optional parameter @code{offset} specifies where in the pattern
+to begin. The first number specifies how far (if @code{scale} is
+@code{true}, in units of the pen line width; otherwise in
+@code{PostScript} units) to draw with the pen on, the second number
+specifies how far to draw with the pen off, and so on. If
+@code{adjust} is @code{true}, these spacings are automatically
+adjusted by @code{Asymptote} to fit the arclength of the path. Here
+are the predefined line types:
+@verbatim
+pen solid=linetype(new real[]);
+pen dotted=linetype(new real[] {0,4});
+pen dashed=linetype(new real[] {8,8});
+pen longdashed=linetype(new real[] {24,8});
+pen dashdotted=linetype(new real[] {8,8,0,8});
+pen longdashdotted=linetype(new real[] {24,8,0,8});
+pen Dotted(pen p=currentpen) {return linetype(new real[] {0,3})+2*linewidth(p);}
+pen Dotted=Dotted();
+@end verbatim
+@sp 1
+@center @image{linetype}
+
+@cindex @code{defaultpen}
+The default line type is @code{solid}; this may be changed with
+@code{defaultpen(pen)}.
+@cindex @code{linetype}
+@cindex @code{offset}
+@cindex @code{scale}
+@cindex @code{adjust}
+The line type of a pen can be determined with the functions
+@code{real[] linetype(pen p=currentpen)},
+@code{real offset(pen p)}, @code{bool scale(pen p)}, and
+@code{bool adjust(pen p)}.
+
+@cindex @code{linewidth}
+@cindex @code{defaultpen}
+@item The pen line width is specified in @code{PostScript} units with
+@code{pen linewidth(real)}. The default line width is 0.5 bp; this value
+may be changed with @code{defaultpen(pen)}. The line width of a pen
+is returned by @code{real linewidth(pen p=currentpen)}.
+For convenience, in the module @code{plain_pens} we define
+@verbatim
+void defaultpen(real w) {defaultpen(linewidth(w));}
+pen operator +(pen p, real w) {return p+linewidth(w);}
+pen operator +(real w, pen p) {return linewidth(w)+p;}
+@end verbatim
+so that one may set the line width like this:
+@verbatim
+defaultpen(2);
+pen p=red+0.5;
+@end verbatim
+
+@cindex @code{linecap}
+@cindex @code{squarecap}
+@cindex @code{roundcap}
+@cindex @code{extendcap}
+@cindex @code{defaultpen}
+@item A pen with a specific @code{PostScript} line cap is returned on
+calling @code{linecap} with an integer argument:
+@verbatim
+pen squarecap=linecap(0);
+pen roundcap=linecap(1);
+pen extendcap=linecap(2);
+@end verbatim
+
+@noindent
+The default line cap, @code{roundcap}, may be changed with
+@code{defaultpen(pen)}. The line cap of a pen is returned by
+@code{int linecap(pen p=currentpen)}.
+
+@cindex @code{linejoin}
+@cindex @code{miterjoin}
+@cindex @code{roundjoin}
+@cindex @code{beveljoin}
+@item A pen with a specific @code{PostScript} join style is returned on
+calling @code{linejoin} with an integer argument:
+@verbatim
+pen miterjoin=linejoin(0);
+pen roundjoin=linejoin(1);
+pen beveljoin=linejoin(2);
+@end verbatim
+
+@noindent
+The default join style, @code{roundjoin}, may be changed with
+@code{defaultpen(pen)}.The join style of a pen is returned by
+@code{int linejoin(pen p=currentpen)}.
+
+@cindex @code{miterlimit}
+@item A pen with a specific @code{PostScript} miter limit is returned by
+calling @code{miterlimit(real)}.
+The default miterlimit, @code{10.0}, may be changed with
+@code{defaultpen(pen)}. The miter limit of a pen is returned by
+@code{real miterlimit(pen p=currentpen)}.
+
+@cindex @code{fillrule}
+@cindex @code{zerowinding}
+@cindex @code{evenodd}
+@anchor{fillrule}
+@item A pen with a specific @code{PostScript} fill rule is returned on
+calling @code{fillrule} with an integer argument:
+@verbatim
+pen zerowinding=fillrule(0);
+pen evenodd=fillrule(1);
+@end verbatim
+
+@noindent
+The fill rule, which identifies the algorithm used to determine the
+insideness of a path or array of paths, only affects the @code{clip},
+@code{fill}, and @code{inside} functions. For the @code{zerowinding}
+fill rule, a point @code{z} is outside the region bounded by a path if
+the number of upward intersections of the path with the horizontal
+line @code{z--z+infinity} minus the number of downward intersections
+is zero. For the @code{evenodd} fill rule, @code{z} is considered to
+be outside the region if the total number of such intersections is even.
+The default fill rule, @code{zerowinding}, may be changed with
+@code{defaultpen(pen)}. The fill rule of a pen is returned by
+@code{int fillrule(pen p=currentpen)}.
+
+@cindex @code{nobasealign}
+@cindex @code{basealign}
+@anchor{basealign}
+@item A pen with a specific text alignment setting is returned on
+calling @code{basealign} with an integer argument:
+@verbatim
+pen nobasealign=basealign(0);
+pen basealign=basealign(1);
+@end verbatim
+
+@noindent
+The default setting, @code{nobasealign},which may be changed with
+@code{defaultpen(pen)}, causes the label alignment routines to use the
+full label bounding box for alignment. In contrast, @code{basealign}
+requests that the @TeX{} baseline be respected.
+The base align setting of a pen is returned by
+@code{int basealigin(pen p=currentpen)}.
+
+@cindex @code{fontsize}
+@cindex @code{lineskip}
+@cindex @code{defaultpen}
+@cindex @code{type1cm}
+@item The font size is specified in @TeX{} points (1 pt = 1/72.27 inches) with
+the function @code{pen fontsize(real size, real lineskip=1.2*size)}.
+The default font size, 12pt, may be changed with @code{defaultpen(pen)}.
+Nonstandard font sizes may require inserting
+@verbatim
+import fontsize;
+@end verbatim
+at the beginning of the file (this requires the @code{type1cm} package
+available from
+@quotation
+@url{http://mirror.ctan.org/macros/latex/contrib/type1cm/}
+@end quotation
+and included in recent @code{LaTeX} distributions). The font size and line
+skip of a pen can be examined with the routines
+@code{real fontsize(pen p=currentpen)} and
+@code{real lineskip(pen p=currentpen)}, respectively.
+
+@cindex @code{font}
+@cindex @code{LaTeX fonts}
+@cindex @code{NFSS}
+@cindex @code{font command}
+@item A pen using a specific @code{LaTeX} @code{NFSS} font is returned
+by calling the function @code{pen font(string encoding, string family,
+string series, string shape)}. The default setting,
+@code{font("OT1","cmr","m","n")}, corresponds to 12pt Computer Modern Roman;
+this may be changed with @code{defaultpen(pen)}.
+The font setting of a pen is returned by
+@code{string font(pen p=currentpen)}.
+Support for standardized international characters is provided by the
+@code{unicode} package (@pxref{unicode}).
+
+@cindex @code{TeX fonts}
+Alternatively, one may select a fixed-size @TeX{} font (on which
+@code{fontsize} has no effect) like @code{"cmr12"} (12pt Computer Modern
+Roman) or @code{"pcrr"} (Courier) using the function @code{pen font(string
+name)}. An optional size argument can also be given to scale the font
+to the requested size: @code{pen font(string name, real size)}.
+
+@cindex @code{fontcommand}
+A nonstandard font command can be generated with
+@code{pen fontcommand(string)}.
+
+@cindex @code{PostScript fonts}
+A convenient interface to the following standard @code{PostScript}
+fonts is also provided:
+@verbatim
+pen AvantGarde(string series="m", string shape="n");
+pen Bookman(string series="m", string shape="n");
+pen Courier(string series="m", string shape="n");
+pen Helvetica(string series="m", string shape="n");
+pen NewCenturySchoolBook(string series="m", string shape="n");
+pen Palatino(string series="m", string shape="n");
+pen TimesRoman(string series="m", string shape="n");
+pen ZapfChancery(string series="m", string shape="n");
+pen Symbol(string series="m", string shape="n");
+pen ZapfDingbats(string series="m", string shape="n");
+@end verbatim
+
+@anchor{transparency}
+@cindex transparency
+@cindex @code{opacity}
+@item The transparency of a pen can be changed with the command:
+@verbatim
+pen opacity(real opacity=1, string blend="Compatible");
+@end verbatim
+The opacity can be varied from @code{0} (fully transparent) to the default
+value of @code{1} (opaque), and @code{blend} specifies one of the
+following foreground--background blending operations:
+@verbatim
+"Compatible","Normal","Multiply","Screen","Overlay","SoftLight",
+"HardLight","ColorDodge","ColorBurn","Darken","Lighten","Difference",
+"Exclusion","Hue","Saturation","Color","Luminosity",
+@end verbatim
+as described in
+
+@url{http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf}.
+Since @code{PostScript} does not support transparency, this feature is
+only effective with the @code{-f pdf} output format option; other
+formats can be produced from the resulting @acronym{PDF} file with the
+@code{ImageMagick} @code{convert} program.
+Labels are always drawn with an @code{opacity} of 1.
+A simple example of transparent filling is provided in the example file
+@code{@uref{http://asymptote.sourceforge.net/gallery/transparency.pdf,,transparency}@uref{http://asymptote.sourceforge.net/gallery/transparency.asy,,.asy}}.
+
+@cindex patterns
+@cindex tilings
+@item @code{PostScript} commands within a @code{picture} may be used
+to create a tiling pattern, identified by the string @code{name}, for
+@code{fill} and @code{draw} operations by adding it to the
+global @code{PostScript} frame @code{currentpatterns},
+with optional left-bottom margin @code{lb} and right-top margin @code{rt}.
+@verbatim
+import patterns;
+void add(string name, picture pic, pair lb=0, pair rt=0);
+@end verbatim
+
+To @code{fill} or @code{draw} using pattern @code{name}, use
+the pen @code{pattern("name")}. For example, rectangular tilings
+can be constructed using the routines
+@code{picture tile(real Hx=5mm, real Hy=0, pen p=currentpen,
+filltype filltype=NoFill)},
+@code{picture checker(real Hx=5mm, real Hy=0, pen p=currentpen)}, and
+@code{picture brick(real Hx=5mm, real Hy=0, pen p=currentpen)} defined in
+@code{@uref{http://asymptote.sourceforge.net/gallery/patterns.pdf,,patterns}@uref{http://asymptote.sourceforge.net/gallery/patterns.asy,,.asy}}:
+@cindex grid
+@cindex tile
+@cindex checker
+@cindex brick
+@verbatiminclude tile.asy
+@sp 1
+@center @image{tile}
+
+@cindex hatch
+@cindex crosshatch
+Hatch patterns can be generated with the routines
+@code{picture hatch(real H=5mm, pair dir=NE, pen p=currentpen)},
+@code{picture crosshatch(real H=5mm, pen p=currentpen)}:
+@verbatiminclude hatch.asy
+@sp 1
+@center @image{hatch}
+
+You may need to turn off aliasing in your @code{PostScript} viewer for
+patterns to appear correctly. Custom patterns can easily be constructed,
+following the examples in @code{@uref{http://asymptote.sourceforge.net/gallery/patterns.pdf,,patterns}@uref{http://asymptote.sourceforge.net/gallery/patterns.asy,,.asy}}. The tiled pattern can
+even incorporate shading (@pxref{gradient shading}), as illustrated
+in this example (not included in the manual because not all printers support
+@code{PostScript} 3):
+@verbatiminclude shadedtiling.asy
+
+@anchor{makepen}
+@cindex @code{makepen}
+@item One can specify a custom pen nib as an arbitrary polygonal path
+with @code{pen makepen(path)}; this path represents the mark to be
+drawn for paths containing a single point. This pen nib path can be
+recovered from a pen with @code{path nib(pen)}. Unlike in
+@code{MetaPost}, the path need not be convex:
+
+@verbatiminclude makepen.asy
+@sp 1
+@center @image{makepen}
+
+The value @code{nullpath} represents a circular pen nib (the default);
+an elliptical pen can be achieved simply by multiplying the pen by a
+transform: @code{yscale(2)*currentpen}.
+
+@anchor{overwrite}
+@cindex @code{overwrite}
+@item One can prevent labels from overwriting one another by using
+the pen attribute @code{overwrite}, which takes a single argument:
+
+@table @code
+@cindex @code{Allow}
+@cindex @code{defaultpen}
+@item Allow
+Allow labels to overwrite one another. This is the default behaviour (unless
+overridden with @code{defaultpen(pen)}.
+
+@cindex @code{Suppress}
+@item Suppress
+Suppress, with a warning, each label that would overwrite another label.
+
+@cindex @code{SuppressQuiet}
+@item SuppressQuiet
+Suppress, without warning, each label that would overwrite another label.
+
+@cindex @code{Move}
+@item Move
+Move a label that would overwrite another out of the way and issue a warning.
+As this adjustment is during the final output phase (in @code{PostScript}
+coordinates) it could result in a larger figure than requested.
+
+@cindex @code{MoveQuiet}
+@item MoveQuiet
+Move a label that would overwrite another out of the way, without warning.
+As this adjustment is during the final output phase (in @code{PostScript}
+coordinates) it could result in a larger figure than requested.
+
+@end table
+
+@end itemize
+
+@cindex @code{defaultpen}
+@cindex @code{resetdefaultpen}
+The routine @code{defaultpen()} returns the current default pen attributes.
+Calling the routine @code{resetdefaultpen()} resets all pen default
+attributes to their initial values.
+
+@node Transforms, Frames and pictures, Pens, Programming
+@section Transforms
+
+@cindex @code{transform}
+@code{Asymptote} makes extensive use of affine transforms. A pair
+@code{(x,y)} is transformed by the transform
+@code{t=(t.x,t.y,t.xx,t.xy,t.yx,t.yy)} to @code{(x',y')}, where
+@verbatim
+x' = t.x + t.xx * x + t.xy * y
+y' = t.y + t.yx * x + t.yy * y
+@end verbatim
+@noindent
+This is equivalent to the @code{PostScript} transformation
+@code{[t.xx t.yx t.xy t.yy t.x t.y]}.
+
+Transforms can be applied to pairs, guides, paths, pens, strings,
+transforms, frames, and pictures by multiplication (via the binary operator
+@code{*}) on the left (@pxref{circle} for an example).
+@cindex @code{inverse}
+Transforms can be composed with one another and inverted with the
+function @code{transform inverse(transform t)}; they can also be raised to any
+integer power with the @code{^} operator.
+
+The built-in transforms are:
+
+@table @code
+@item transform identity;
+@cindex @code{identity}
+the identity transform;
+@item transform shift(pair z);
+@cindex @code{shift}
+translates by the pair @code{z};
+@item transform shift(real x, real y);
+@cindex @code{shift}
+translates by the pair @code{(x,y)};
+@item transform xscale(real x);
+@cindex @code{xscale}
+scales by @code{x} in the @math{x} direction;
+@item transform yscale(real y);
+@cindex @code{yscale}
+scales by @code{y} in the @math{y} direction;
+@item transform scale(real s);
+@cindex @code{scale}
+scale by @code{s} in both @math{x} and @math{y} directions;
+@item transform scale(real x, real y);
+@cindex @code{scale}
+scale by @code{x} in the @math{x} direction and by @code{y} in the
+@math{y} direction;
+@item transform slant(real s);
+@cindex @code{slant}
+maps @code{(x,y)} --> @code{(x+s*y,y)};
+@item transform rotate(real angle, pair z=(0,0));
+rotates by @code{angle} in degrees about @code{z};
+@item transform reflect(pair a, pair b);
+@cindex @code{reflect}
+reflects about the line @code{a--b}.
+@item transform zeroTransform;
+@cindex @code{zeroTransform}
+the zero transform;
+@end table
+
+@cindex @code{shift}
+@cindex @code{shiftless}
+The implicit initializer for transforms is @code{identity()}.
+The routines @code{shift(transform t)} and @code{shiftless(transform t)}
+return the transforms @code{(t.x,t.y,0,0,0,0)} and
+@code{(0,0,t.xx,t.xy,t.yx,t.yy)} respectively.
+
+
+@node Frames and pictures, Files, Transforms, Programming
+@section Frames and pictures
+
+@table @code
+
+@item frame
+@cindex @code{frame}
+@cindex @code{newframe}
+@cindex @code{empty}
+@cindex @code{erase}
+@cindex @code{min}
+@cindex @code{max}
+Frames are canvases for drawing in @code{PostScript} coordinates. While working
+with frames directly is occasionally necessary for constructing deferred
+drawing routines, pictures are usually more convenient to work with.
+The implicit initializer for frames is @code{newframe}. The function
+@code{bool empty(frame f)} returns @code{true} only if the frame @code{f}
+is empty. A frame may be erased with the @code{erase(frame)} routine.
+The functions @code{pair min(frame)} and @code{pair max(frame)}
+return the (left,bottom) and (right,top) coordinates of the frame
+bounding box, respectively. The contents of frame @code{src} may be
+appended to frame @code{dest} with the command
+@verbatim
+void add(frame dest, frame src);
+@end verbatim
+or prepended with
+@verbatim
+void prepend(frame dest, frame src);
+@end verbatim
+A frame obtained by aligning frame @code{f} in the direction
+@code{align}, in a manner analogous to the @code{align} argument of
+@code{label} (@pxref{label}), is returned by
+@verbatim
+frame align(frame f, pair align);
+@end verbatim
+
+@cindex @code{box}
+@cindex @code{ellipse}
+@anchor{envelope}
+@cindex @code{envelope}
+To draw or fill a box or ellipse around a label or frame and return the
+boundary as a path, use one of the predefined @code{envelope} routines
+@verbatim
+path box(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+path roundbox(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+path ellipse(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+
+@item picture
+@cindex @code{picture}
+Pictures are high-level structures (@pxref{Structures}) defined in
+the module @code{plain} that provide canvases for drawing in user coordinates.
+The default picture is called @code{currentpicture}. A new picture
+can be created like this:
+@verbatim
+picture pic;
+@end verbatim
+@noindent
+Anonymous pictures can be made by the expression @code{new picture}.
+
+The @code{size} routine specifies the dimensions of the desired picture:
+
+@anchor{size}
+@cindex @code{size}
+@verbatim
+void size(picture pic=currentpicture, real x, real y=x,
+ bool keepAspect=Aspect);
+@end verbatim
+
+If the @code{x} and @code{y} sizes are both 0, user coordinates will be
+interpreted as @code{PostScript} coordinates. In this case, the transform
+mapping @code{pic} to the final output frame is @code{identity()}.
+
+If exactly one of @code{x} or @code{y} is 0, no size restriction
+is imposed in that direction; it will be scaled the same as the other
+direction.
+
+@cindex @code{keepAspect}
+@cindex @code{Aspect}
+If @code{keepAspect} is set to @code{Aspect} or @code{true},
+the picture will be scaled with its aspect ratio preserved such that
+the final width is no more than @code{x} and the final height is
+no more than @code{y}.
+
+@cindex @code{keepAspect}
+@cindex @code{IgnoreAspect}
+If @code{keepAspect} is set to @code{IgnoreAspect} or @code{false},
+the picture will be scaled in both directions so that the final width
+is @code{x} and the height is @code{y}.
+
+To make the user coordinates of picture @code{pic}
+represent multiples of @code{x} units in the @math{x} direction and
+@code{y} units in the @math{y} direction, use
+@anchor{unitsize}
+@cindex @code{unitsize}
+@verbatim
+void unitsize(picture pic=currentpicture, real x, real y=x);
+@end verbatim
+When nonzero, these @code{x} and @code{y} values override the
+corresponding size parameters of picture @code{pic}.
+
+The routine
+@cindex @code{size}
+@verbatim
+void size(picture pic=currentpicture, real xsize, real ysize,
+ pair min, pair max);
+@end verbatim
+forces the final picture scaling to map the user coordinates
+@code{box(min,max)} to a region of width @code{xsize} and height @code{ysize}
+(when these parameters are nonzero).
+
+Alternatively, calling the routine
+@cindex @code{fixedscaling}
+@verbatim
+transform fixedscaling(picture pic=currentpicture, pair min,
+ pair max, pen p=nullpen, bool warn=false);
+@end verbatim
+will cause picture @code{pic} to use a fixed scaling to map user
+coordinates in @code{box(min,max)} to the (already specified) picture size,
+taking account of the width of pen @code{p}. A warning will be issued if
+the final picture exceeds the specified size.
+
+A picture @code{pic} can be fit to a frame and output to a file
+@code{prefix}.@code{format} using image format @code{format}
+by calling the @code{shipout} function:
+@anchor{shipout}
+@cindex @code{shipout}
+@cindex @code{outprefix}
+@verbatim
+void shipout(string prefix=defaultfilename, picture pic=currentpicture,
+ orientation orientation=orientation,
+ string format="", bool wait=false, bool view=true,
+ string options="", string script="",
+ light light=currentlight, projection P=currentprojection)
+@end verbatim
+@noindent
+The default output format, @code{PostScript}, may be changed
+with the @code{-f} or @code{-tex} command-line options.
+The @code{options}, @code{script}, and @code{projection} parameters
+are only relevant for 3D pictures. If @code{defaultfilename} is an
+empty string, the prefix @code{outprefix()} will be used.
+
+A @code{shipout()} command is added implicitly at file exit if no
+previous @code{shipout} commands have been executed.
+@cindex @code{orientation}
+@cindex @code{Portrait}
+@cindex @code{Landscape}
+@cindex @code{UpsideDown}
+The default page orientation is @code{Portrait}; this may be modified
+by changing the variable @code{orientation}. To output in landscape
+mode, simply set the variable @code{orientation=Landscape} or issue
+the command
+@verbatim
+shipout(Landscape);
+@end verbatim
+
+@cindex @code{Seascape}
+To rotate the page by @math{-90} degrees, use the orientation @code{Seascape}.
+@cindex @code{UpsideDown}
+The orientation @code{UpsideDown} rotates the page by 180 degrees.
+
+@cindex subpictures
+@cindex @code{fit}
+A picture @code{pic} can be explicitly fit to a frame by calling
+@verbatim
+frame pic.fit(real xsize=pic.xsize, real ysize=pic.ysize,
+ bool keepAspect=pic.keepAspect);
+@end verbatim
+The default size and aspect ratio settings are those given to the
+@code{size} command (which default to @code{0}, @code{0}, and
+@code{true}, respectively).
+@cindex @code{calculateTransform}
+The transformation that would currently be used to fit a picture
+@code{pic} to a frame is returned by the member function
+@code{pic.calculateTransform()}.
+
+In certain cases (e.g.@ 2D graphs) where only an approximate size
+estimate for @code{pic} is available, the picture fitting routine
+@verbatim
+frame pic.scale(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect);
+@end verbatim
+(which scales the resulting frame, including labels and fixed-size
+objects) will enforce perfect compliance with the requested size
+specification, but should not normally be required.
+
+@cindex @code{box}
+To draw a bounding box with margins around a picture, fit the
+picture to a frame using the function
+@verbatim
+frame bbox(picture pic=currentpicture, real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill);
+@end verbatim
+@anchor{filltype}
+Here @code{filltype} specifies one of the following fill types:
+@table @code
+@cindex @code{FillDraw}
+@item FillDraw
+Fill the interior and draw the boundary.
+
+@item FillDraw(real xmargin=0, real ymargin=xmargin, pen fillpen=nullpen,
+ @code{pen drawpen=nullpen)}
+@cindex @code{nullpen}
+If @code{fillpen} is @code{nullpen}, fill with the drawing pen;
+otherwise fill with pen @code{fillpen}.
+If @code{drawpen} is @code{nullpen}, draw the boundary with @code{fillpen};
+otherwise with @code{drawpen}. An optional margin of
+@code{xmargin} and @code{ymargin} can be specified.
+
+@cindex @code{Fill}
+@item Fill
+Fill the interior.
+
+@cindex @code{nullpen}
+@item Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+If @code{p} is @code{nullpen}, fill with the drawing pen;
+otherwise fill with pen @code{p}. An optional margin of
+@code{xmargin} and @code{ymargin} can be specified.
+
+@cindex @code{NoFill}
+@item NoFill
+Do not fill.
+
+@item Draw
+Draw only the boundary.
+
+@cindex @code{Draw}
+@item Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+If @code{p} is @code{nullpen}, draw the boundary with the drawing pen;
+otherwise draw with pen @code{p}. An optional margin of
+@code{xmargin} and @code{ymargin} can be specified.
+
+@cindex @code{UnFill}
+@item UnFill
+Clip the region.
+
+@cindex @code{UnFill}
+@item UnFill(real xmargin=0, real ymargin=xmargin)
+Clip the region and surrounding margins @code{xmargin} and @code{ymargin}.
+
+@cindex @code{RadialShade}
+@item RadialShade(pen penc, pen penr)
+Fill varying radially from @code{penc} at the center of the bounding
+box to @code{penr} at the edge.
+
+@cindex @code{RadialShadeDraw}
+@item RadialShadeDraw(real xmargin=0, real ymargin=xmargin, pen penc,
+ @code{pen penr, pen drawpen=nullpen)}
+Fill with RadialShade and draw the boundary.
+
+@end table
+
+@cindex bounding box
+@cindex background color
+For example, to draw a bounding box around a picture with a 0.25 cm
+margin and output the resulting frame, use the command:
+@verbatim
+shipout(bbox(0.25cm));
+@end verbatim
+A @code{picture} may be fit to a frame with the background color
+pen @code{p}, using the function @code{bbox(p,Fill)}.
+
+The functions
+@verbatim
+pair min(picture pic, user=false);
+pair max(picture pic, user=false);
+pair size(picture pic, user=false);
+@end verbatim
+calculate the bounds that picture @code{pic} would
+have if it were currently fit to a frame using its default size specification.
+If @code{user} is @code{false} the returned value is in
+@code{PostScript} coordinates, otherwise it is in user coordinates.
+
+The function
+@verbatim
+pair point(picture pic=currentpicture, pair dir, bool user=true);
+@end verbatim
+is a convenient way of determining the point on the bounding box of
+@code{pic} in the direction @code{dir} relative to its center, ignoring
+the contributions from fixed-size objects (such as labels and arrowheads).
+If @code{user} is @code{true} the returned value is in user coordinates,
+otherwise it is in @code{PostScript} coordinates.
+
+The function
+@verbatim
+pair truepoint(picture pic=currentpicture, pair dir, bool user=true);
+@end verbatim
+is identical to @code{point}, except that it also accounts for
+fixed-size objects, using the scaling transform that picture @code{pic}
+would have if currently fit to a frame using its default size
+specification. If @code{user} is @code{true} the returned value is in
+user coordinates, otherwise it is in @code{PostScript} coordinates.
+
+@anchor{add}
+Sometimes it is useful to draw objects on separate pictures and add one
+picture to another using the @code{add} function:
+@cindex @code{add}
+@verbatim
+void add(picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+void add(picture dest, picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+@noindent
+The first example adds @code{src} to @code{currentpicture}; the second
+one adds @code{src} to @code{dest}.
+The @code{group} option specifies whether or not the graphical user
+interface @code{@uref{http://asymptote.sourceforge.net/gallery/.pdf,,}@uref{http://asymptote.sourceforge.net/gallery/.asy,,.asy}} should treat all of the elements of @code{src}
+as a single entity (@pxref{GUI}), @code{filltype} requests optional
+background filling or clipping, and @code{above} specifies
+whether to add @code{src} above or below existing objects.
+
+There are also routines to add a picture or frame @code{src} specified
+in postscript coordinates to another picture @code{dest} (or
+@code{currentpicture}) about the user coordinate
+@code{position}:
+@anchor{add about}
+@cindex @code{add}
+@cindex picture alignment
+@verbatim
+void add(picture src, pair position, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+void add(picture dest, picture src, pair position,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+void add(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+void add(picture dest=currentpicture, frame src, pair position,
+ pair align, bool group=true, filltype filltype=NoFill,
+ bool above=true);
+@end verbatim
+
+The optional @code{align} argument in the last form specifies a
+direction to use for aligning the frame, in a manner analogous to the
+@code{align} argument of @code{label} (@pxref{label}). However, one key
+difference is that when @code{align} is not specified, labels are
+centered, whereas frames and pictures are aligned so that their origin is
+at @code{position}. Illustrations of frame alignment can be found in
+the examples @ref{errorbars} and @ref{image}. If you want to align three
+or more subpictures, group them two at a time:
+
+@verbatiminclude subpictures.asy
+@sp 1
+@center @image{subpictures}
+
+Alternatively, one can use @code{attach} to automatically increase the
+size of picture @code{dest} to accommodate adding a frame @code{src}
+about the user coordinate @code{position}:
+@cindex @code{attach}
+@verbatim
+void attach(picture dest=currentpicture, frame src,
+ pair position=0, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+void attach(picture dest=currentpicture, frame src,
+ pair position, pair align, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+
+@cindex @code{erase}
+To erase the contents of a picture (but not the size specification), use
+the function
+@verbatim
+void erase(picture pic=currentpicture);
+@end verbatim
+
+@cindex @code{save}
+To save a snapshot of @code{currentpicture}, @code{currentpen}, and
+@code{currentprojection}, use the function @code{save()}.
+
+@cindex @code{restore}
+To restore a snapshot of @code{currentpicture}, @code{currentpen}, and
+@code{currentprojection}, use the function @code{restore()}.
+
+Many further examples of picture and frame operations are provided in
+the base module @code{plain}.
+
+@cindex verbatim
+@cindex @code{postscript}
+It is possible to insert verbatim @code{PostScript} commands in a picture with
+one of the routines
+@verbatim
+void postscript(picture pic=currentpicture, string s);
+void postscript(picture pic=currentpicture, string s, pair min,
+ pair max)
+@end verbatim
+Here @code{min} and @code{max} can be used to specify explicit bounds
+associated with the resulting @code{PostScript} code.
+
+@anchor{tex}
+@cindex @code{tex}
+Verbatim @TeX{} commands can be inserted in the intermediate
+@code{LaTeX} output file with one of the functions
+@verbatim
+void tex(picture pic=currentpicture, string s);
+void tex(picture pic=currentpicture, string s, pair min, pair max)
+@end verbatim
+Here @code{min} and @code{max} can be used to specify explicit bounds
+associated with the resulting @TeX{} code.
+
+To issue a global @TeX{} command (such as a @TeX{} macro definition) in the
+@TeX{} preamble (valid for the remainder of the top-level module) use:
+@cindex @code{texpreamble}
+@verbatim
+void texpreamble(string s);
+@end verbatim
+
+The @TeX{} environment can be reset to its initial state, clearing all
+macro definitions, with the function
+@cindex @code{texreset}
+@verbatim
+void texreset();
+@end verbatim
+
+@cindex @code{usepackage}
+The routine
+@verbatim
+void usepackage(string s, string options="");
+@end verbatim
+provides a convenient abbreviation for
+@verbatim
+texpreamble("\usepackage["+options+"]{"+s+"}");
+@end verbatim
+@noindent
+that can be used for importing @code{LaTeX} packages.
+
+@end table
+
+@node Files, Variable initializers, Frames and pictures, Programming
+@section Files
+
+@cindex @code{file}
+@code{Asymptote} can read and write text files (including comma-separated
+value) files and portable @acronym{XDR} (External Data Representation)
+binary files.
+
+@cindex @code{input}
+An input file must first be opened with
+@verbatim
+input(string name="", bool check=true, string comment="#", string mode="");
+@end verbatim
+reading is then done by assignment:
+@cindex open
+@cindex @code{input}
+@cindex reading
+@verbatim
+file fin=input("test.txt");
+real a=fin;
+@end verbatim
+
+@cindex comment character
+@cindex @code{error}
+If the optional boolean argument @code{check} is @code{false}, no check will
+be made that the file exists. If the file does not exist or is not
+readable, the function @code{bool error(file)} will return @code{true}.
+The first character of the string @code{comment} specifies a
+comment character. If this character is encountered in a data file,
+the remainder of the line is ignored. When reading strings, a comment
+character followed immediately by another comment character is treated
+as a single literal comment character.
+
+@anchor{cd}
+@cindex @code{cd}
+@cindex directory
+One can change the current working directory for read operations to
+the contents of the string @code{s} with the function @code{string
+cd(string s)}, which returns the new working directory. If
+@code{string s} is empty, the path is reset to the value it had at
+program startup.
+
+@cindex @code{getc}
+When reading pairs, the enclosing parenthesis are optional.
+Strings are also read by assignment, by reading characters up to but not
+including a newline. In addition, @code{Asymptote} provides the function
+@code{string getc(file)} to read the next character (treating the
+comment character as an ordinary character) and return it as a string.
+
+@cindex @code{output}
+@cindex @code{update}
+@cindex append
+A file named @code{name} can be open for output with
+@verbatim
+file output(string name="", bool update=false, string comment="#", string mode="");
+@end verbatim
+@noindent
+If @code{update=false}, any existing data in the file will be erased
+and only write operations can be used on the file.
+If @code{update=true}, any existing data will be preserved, the position
+will be set to the end-of-file, and both reading and writing operations
+will be enabled. For security reasons, writing to files in directories
+other than the current directory is allowed only if the @code{-globalwrite}
+(or @code{-nosafe}) command-line option is specified.
+@cindex @code{mktemp}
+The function @code{string mktemp(string s)} may be used to create and
+return the name of a unique temporary file in the current directory
+based on the string @code{s}.
+
+@cindex @code{stdin}
+@cindex @code{stdout}
+There are two special files: @code{stdin}, which reads from the keyboard,
+and @code{stdout}, which writes to the terminal. The implicit
+initializer for files is @code{null}.
+
+Data of a built-in type @code{T} can be written to an output file by
+calling one of the functions
+@cindex @code{write}
+@verbatim
+write(string s="", T x, suffix suffix=endl ... T[]);
+write(file file, string s="", T x, suffix suffix=none ... T[]);
+write(file file=stdout, string s="", explicit T[] x ... T[][]);
+write(file file=stdout, T[][]);
+write(file file=stdout, T[][][]);
+write(suffix suffix=endl);
+write(file file, suffix suffix=none);
+@end verbatim
+@cindex @code{none}
+@cindex @code{flush}
+@cindex @code{endl}
+@cindex @code{newl}
+@cindex @code{DOSendl}
+@cindex @code{DOSnewl}
+@cindex @code{tab}
+@cindex @code{comma}
+If @code{file} is not specified, @code{stdout} is used and
+terminated by default with a newline. If specified, the optional
+identifying string @code{s} is written before the data @code{x}.
+An arbitrary number of data values may be listed when writing scalars
+or one-dimensional arrays. The @code{suffix} may be one of the following:
+@code{none} (do nothing), @code{flush} (output buffered data),
+@code{endl} (terminate with a newline and flush),
+@code{newl} (terminate with a newline),
+@code{DOSendl} (terminate with a DOS newline and flush),
+@code{DOSnewl} (terminate with a DOS newline),
+@code{tab} (terminate with a tab), or @code{comma} (terminate with a
+comma). Here are some simple examples of data output:
+@verbatim
+file fout=output("test.txt");
+write(fout,1); // Writes "1"
+write(fout); // Writes a new line
+write(fout,"List: ",1,2,3); // Writes "List: 1 2 3"
+@end verbatim
+@noindent
+
+@cindex binary format
+@cindex single precision
+@cindex double precision
+@cindex @code{singlereal}
+@cindex @code{singleint}
+@cindex @code{signedint}
+@cindex @code{mode}
+@cindex @code{binary}
+@cindex @code{xdr}
+A file may be opened with @code{mode="xdr"}, to read or write
+double precision (64-bit) reals and single precision (32-bit)
+integers in Sun Microsystem's @acronym{XDR} (External
+Data Representation) portable binary format (available on all
+@code{UNIX} platforms).
+Alternatively, a file may also be opened with @code{mode="binary"}
+to read or write double precision reals and single
+precision integers in the native (nonportable) machine binary format.
+The virtual member functions
+@code{file singlereal(bool b=true)} and @code{file singleint(bool b=true)}
+be used to change the precision of real and integer I/O
+operations, respectively, for an @acronym{XDR} or binary file @code{f}.
+Similarly, the function @code{file signedint(bool b=true)}
+can be used to modify the signedness of integer reads and writes for
+an @acronym{XDR} or binary file @code{f}.
+
+@cindex @code{name}
+@cindex @code{mode}
+@cindex @code{singlereal}
+@cindex @code{singleint}
+@cindex @code{signedint}
+The virtual members @code{name}, @code{mode}, @code{singlereal},
+@code{singleint}, and @code{signedint} may be used to query the
+respective parameters for a given file.
+
+@cindex @code{eof}
+@cindex @code{eol}
+@cindex @code{error}
+@cindex @code{flush}
+@cindex @code{clear}
+@cindex @code{precision}
+@cindex @code{seek}
+@cindex @code{tell}
+@cindex rewind
+@cindex @code{seekeof}
+One can test a file for end-of-file with the boolean function @code{eof(file)},
+end-of-line with @code{eol(file)}, and for I/O errors with @code{error(file)}.
+One can flush the output buffers with @code{flush(file)}, clear a
+previous I/O error with @code{clear(file)}, and close the file with
+@code{close(file)}. The function
+@code{int precision(file file=stdout, int digits=0)}
+sets the number of digits of output precision for @code{file} to @code{digits},
+provided @code{digits} is nonzero, and returns the previous
+precision setting. The function @code{int tell(file)} returns
+the current position in a file relative to the beginning.
+The routine @code{seek(file file, int pos)} can be used to
+change this position, where a negative value for the position @code{pos}
+is interpreted as relative to the end-of-file. For example, one can
+rewind a file @code{file} with the command @code{seek(file,0)}
+and position to the final character in the file with @code{seek(file,-1)}.
+The command @code{seekeof(file)} sets the position to the end of the file.
+
+@cindex @code{scroll}
+@anchor{scroll}
+Assigning @code{settings.scroll=n} for a positive integer @code{n}
+requests a pause after every @code{n} output lines to @code{stdout}.
+One may then press @code{Enter} to continue to the next @code{n} output lines,
+@code{s} followed by @code{Enter} to scroll without further interruption,
+or @code{q} followed by @code{Enter} to quit the current output
+operation. If @code{n} is negative, the output scrolls a page at a time
+(i.e. by one less than the current number of display lines). The default
+value, @code{settings.scroll=0}, specifies continuous scrolling.
+
+The routines
+@cindex @code{getstring}
+@cindex @code{getreal}
+@cindex @code{getpair}
+@cindex @code{gettriple}
+@verbatim
+string getstring(string name="", string default="", string prompt="",
+ bool store=true);
+int getint(string name="", int default=0, string prompt="",
+ bool store=true);
+real getreal(string name="", real default=0, string prompt="",
+ bool store=true);
+pair getpair(string name="", pair default=0, string prompt="",
+ bool store=true);
+triple gettriple(string name="", triple default=(0,0,0), string prompt="",
+ bool store=true);
+@end verbatim
+@noindent
+defined in the module @code{plain} may be used to prompt for a value from
+@code{stdin} using the @acronym{GNU} @code{readline} library.
+If @code{store=true}, the history of values for @code{name} is
+stored in the file @code{".asy_history_"+name} (@pxref{history}). The most
+recent value in the history will be used to provide a default value
+for subsequent runs. The default value (initially @code{default}) is
+displayed after @code{prompt}. These functions are based on the internal
+routines
+@cindex @code{readline}
+@cindex @code{saveline}
+@verbatim
+string readline(string prompt="", string name="", bool tabcompletion=false);
+void saveline(string name, string value, bool store=true);
+@end verbatim
+Here, @code{readline} prompts the user with the default value
+formatted according to @code{prompt}, while @code{saveline}
+is used to save the string @code{value} in a local history named
+@code{name}, optionally storing the local history in a file
+@code{".asy_history_"+name}.
+
+@cindex @code{history}
+The routine @code{history(string name, int n=1)} can be used to look up
+the @code{n} most recent values (or all values up to @code{historylines}
+if @code{n=0}) entered for string @code{name}.
+The routine @code{history(int n=0)} returns the interactive history.
+For example,
+@verbatim
+write(output("transcript.asy"),history());
+@end verbatim
+@noindent
+outputs the interactive history to the file @code{@uref{http://asymptote.sourceforge.net/gallery/transcript.pdf,,transcript}@uref{http://asymptote.sourceforge.net/gallery/transcript.asy,,.asy}}.
+
+@cindex @code{delete}
+The function @code{int delete(string s)} deletes the file named by the
+string @code{s}. Unless the @code{-globalwrite} (or @code{-nosafe})
+option is enabled, the file must reside in the current directory.
+@cindex @code{rename}
+The function @code{int rename(string from, string to)} may be used to
+rename file @code{from} to file @code{to}.
+Unless the @code{-globalwrite} (or @code{-nosafe}) option is enabled,
+this operation is restricted to the current directory.
+@cindex @code{convert}
+@cindex @code{animate}
+The functions
+@verbatim
+int convert(string args="", string file="", string format="");
+int animate(string args="", string file="", string format="");
+@end verbatim
+@noindent
+call the @code{ImageMagick} commands @code{convert} and @code{animate},
+respectively, with the arguments @code{args} and the file name constructed
+from the strings @code{file} and @code{format}.
+
+@node Variable initializers, Structures, Files, Programming
+@section Variable initializers
+@cindex variable initializers
+@cindex @code{operator init}
+@cindex initializers
+
+A variable can be assigned a value when it is declared, as in
+@code{int x=3;} where the variable @code{x} is assigned the value @code{3}.
+As well as literal constants such as @code{3}, arbitary expressions can be used
+as initializers, as in @code{real x=2*sin(pi/2);}.
+
+A variable is not added to the namespace until after the initializer is
+evaluated, so for example, in
+@verbatim
+int x=2;
+int x=5*x;
+@end verbatim
+@noindent
+the @code{x} in the initializer on the second line refers to the variable
+@code{x} declared on the first line. The second line, then, declares a variable
+@code{x} shadowing the original @code{x} and initializes it to the value
+@code{10}.
+
+Variables of most types can be declared without an explicit initializer and they
+will be initialized by the default initializer of that type:
+
+@itemize
+@item Variables of the numeric types @code{int}, @code{real}, and @code{pair}
+are all initialized to zero; variables of type @code{triple} are
+initialized to @code{O=(0,0,0)}.
+@item @code{boolean} variables are initialized to @code{false}.
+@item @code{string} variables are initialized to the empty string.
+@item @code{transform} variables are initialized to the identity transformation.
+@item @code{path} and @code{guide} variables are initialized to
+@code{nullpath}.
+@item @code{pen} variables are initialized to the default pen.
+@item @code{frame} and @code{picture} variables are initialized to empty
+frames and pictures, respectively.
+@item @code{file} variables are initialized to @code{null}.
+@end itemize
+
+The default initializers for user-defined array, structure, and function types
+are explained in their respective sections. Some types, such as
+@code{code}, do not have default initializers. When a variable of such
+a type is introduced, the user must initialize it by explicitly giving
+it a value.
+
+The default initializer for any type @code{T} can be redeclared by defining the
+function @code{T operator init()}. For instance, @code{int} variables are
+usually initialized to zero, but in
+@verbatim
+int operator init() {
+ return 3;
+}
+int y;
+@end verbatim
+
+@noindent
+the variable @code{y} is initialized to @code{3}. This example was given for
+illustrative purposes; redeclaring the initializers of built-in types is not
+recommended. Typically, @code{operator init} is used to define sensible
+defaults for user-defined types.
+
+@cindex @code{var}
+The special type @code{var} may be used to infer the type of a variable from
+its initializer. If the initializer is an expression of a unique type, then
+the variable will be defined with that type. For instance,
+@verbatim
+var x=5;
+var y=4.3;
+var reddash=red+dashed;
+@end verbatim
+@noindent
+is equivalent to
+@verbatim
+int x=5;
+real y=4.3;
+pen reddash=red+dashed;
+@end verbatim
+
+@code{var} may also be used with the extended @code{for} loop syntax.
+
+@verbatim
+int[] a = {1,2,3};
+for (var x : a)
+ write(x);
+@end verbatim
+
+@node Structures, Operators, Variable initializers, Programming
+@section Structures
+@cindex @code{struct}
+@cindex structures
+@cindex @code{public}
+@cindex @code{restricted}
+@cindex @code{private}
+@cindex @code{this}
+@cindex @code{new}
+@cindex @code{null}
+
+Users may also define their own data types as structures, along with
+user-defined operators, much as in C++. By default, structure members
+are @code{public} (may be read and modified anywhere in the code), but may be
+optionally declared @code{restricted} (readable anywhere but writeable
+only inside the structure where they are defined) or @code{private}
+(readable and writable only inside the structure). In a structure definition,
+the keyword @code{this} can be used as an expression to refer to the enclosing
+structure. Any code at the
+top-level scope within the structure is executed on initialization.
+
+Variables hold references to structures. That is, in the example:
+@verbatim
+struct T {
+ int x;
+}
+
+T foo;
+T bar=foo;
+bar.x=5;
+@end verbatim
+
+The variable @code{foo} holds a reference to an instance of the structure
+@code{T}. When @code{bar} is assigned the value of @code{foo}, it too
+now holds a reference to the same instance as @code{foo} does. The assignment
+@code{bar.x=5} changes the value of the field @code{x} in that instance, so
+that @code{foo.x} will also be equal to @code{5}.
+
+The expression @code{new T} creates a new instance of the structure @code{T} and
+returns a reference to that instance. In creating the new instance, any code in
+the body of the record definition is executed. For example:
+@verbatim
+int Tcount=0;
+struct T {
+ int x;
+ ++Tcount;
+}
+
+T foo=new T;
+T foo;
+@end verbatim
+@noindent
+Here, @code{new T} produces a new instance of the class, which
+causes @code{Tcount} to be incremented, tracking the
+number of instances produced. The declarations @code{T foo=new T} and
+@code{T foo} are equivalent: the second form implicitly creates a new
+instance of @code{T}.
+That is, after the definition of a structure @code{T}, a variable of
+type @code{T} is initialized to a new instance (@code{new T}) by
+default. During the definition of the structure, however, variables
+of type @code{T} are initialized to @code{null} by default. This
+special behaviour is to avoid infinite recursion of creating new
+instances in code such as
+@verbatim
+struct tree {
+ int value;
+ tree left;
+ tree right;
+}
+@end verbatim
+
+The expression @code{null} can be cast to any structure type to yield a null
+reference, a reference that does not actually refer to any instance of the
+structure. Trying to use a field of a null reference will cause an error.
+
+@cindex alias
+@cindex @code{==}
+@cindex @code{!=}
+The function @code{bool alias(T,T)} checks to see if two structure references
+refer to the same instance of the structure (or both to @code{null}).
+In example at the beginning of this section, @code{alias(foo,bar)}
+would return true, but @code{alias(foo,new T)} would return false, as @code{new
+T} creates a new instance of the structure @code{T}. The boolean operators
+@code{==} and @code{!=} are by default equivalent to @code{alias} and
+@code{!alias} respectively, but may be overwritten for a particular type
+(for example, to do a deep comparison).
+
+Here is a simple example that illustrates the use of structures:
+@verbatim
+struct S {
+ real a=1;
+ real f(real a) {return a+this.a;}
+}
+
+S s; // Initializes s with new S;
+
+write(s.f(2)); // Outputs 3
+
+S operator + (S s1, S s2)
+{
+ S result;
+ result.a=s1.a+s2.a;
+ return result;
+}
+
+write((s+s).f(0)); // Outputs 2
+
+@end verbatim
+
+@cindex constructors
+It is often convenient to have functions that construct new instances of a
+structure. Say we have a @code{Person} structure:
+@verbatim
+struct Person {
+ string firstname;
+ string lastname;
+}
+
+Person joe;
+joe.firstname="Joe";
+joe.lastname="Jones";
+@end verbatim
+@noindent
+Creating a new Person is a chore; it takes three lines to create a new instance
+and to initialize its fields (that's still considerably less effort than
+creating a new person in real life, though).
+
+We can reduce the work by defining a constructor function
+@code{Person(string,string)}:
+@verbatim
+struct Person {
+ string firstname;
+ string lastname;
+
+ static Person Person(string firstname, string lastname) {
+ Person p=new Person;
+ p.firstname=firstname;
+ p.lastname=lastname;
+ return p;
+ }
+}
+
+Person joe=Person.Person("Joe", "Jones");
+@end verbatim
+
+While it is now easier than before to create a new instance, we still
+have to refer to the constructor by the qualified name
+@code{Person.Person}. If we add the line
+@verbatim
+from Person unravel Person;
+@end verbatim
+@noindent
+immediately after the structure definition, then the constructor can be used
+without qualification: @code{Person joe=Person("Joe", "Jones");}.
+
+The constructor is now easy to use, but it is quite a hassle to define. If you
+write a lot of constructors, you will find that you are repeating a lot of code
+in each of them. Fortunately, your friendly neighbourhood Asymptote
+developers have devised a way to automate much of the process.
+
+@cindex @code{operator init}
+If, in the body of a structure, Asymptote encounters the definition of
+a function of the form @code{void operator init(@var{args})}, it implicitly
+defines a constructor function of the arguments @code{@var{args}} that
+uses the @code{void operator init} function to initialize a
+new instance of the structure.
+That is, it essentially defines the following constructor (assuming the
+structure is called @code{Foo}):
+
+@example
+static Foo Foo(@var{args}) @{
+ Foo instance=new Foo;
+ instance.operator init(@var{args});
+ return instance;
+@}
+@end example
+
+This constructor is also implicitly copied to the enclosing scope after the end
+of the structure definition, so that it can used subsequently without qualifying
+it by the structure name. Our @code{Person} example can thus be implemented as:
+@verbatim
+struct Person {
+ string firstname;
+ string lastname;
+
+ void operator init(string firstname, string lastname) {
+ this.firstname=firstname;
+ this.lastname=lastname;
+ }
+}
+
+Person joe=Person("Joe", "Jones");
+@end verbatim
+
+The use of @code{operator init} to implicitly define constructors should not be
+confused with its use to define default values for variables
+(@pxref{Variable initializers}). Indeed, in the
+first case, the return type of the @code{operator init} must be @code{void}
+while in the second, it must be the (non-@code{void}) type of the variable.
+
+@cindex @code{cputime}
+The function @code{cputime()}
+returns a structure @code{cputime} with cumulative @acronym{CPU} times
+broken down into the fields @code{parent.user}, @code{parent.system},
+@code{child.user}, and @code{child.system}. For convenience, the
+incremental fields @code{change.user} and @code{change.system} indicate
+the change in the corresponding total parent and child @acronym{CPU}
+times since the last call to @code{cputime()}. The function
+@verbatim
+void write(file file=stdout, string s="", cputime c,
+ string format=cputimeformat, suffix suffix=none);
+@end verbatim
+@noindent
+displays the incremental user cputime followed by ``u'',
+the incremental system cputime followed by ``s'',
+the total user cputime followed by ``U'', and
+the total system cputime followed by ``S''.
+
+@cindex inheritance
+@cindex virtual functions
+Much like in C++, casting (@pxref{Casts}) provides for an elegant
+implementation of structure inheritance, including virtual functions:
+@verbatim
+struct parent {
+ real x;
+ void operator init(int x) {this.x=x;}
+ void virtual(int) {write(0);}
+ void f() {virtual(1);}
+}
+
+void write(parent p) {write(p.x);}
+
+struct child {
+ parent parent;
+ real y=3;
+ void operator init(int x) {parent.operator init(x);}
+ void virtual(int x) {write(x);}
+ parent.virtual=virtual;
+ void f()=parent.f;
+}
+
+parent operator cast(child child) {return child.parent;}
+
+parent p=parent(1);
+child c=child(2);
+
+write(c); // Outputs 2;
+
+p.f(); // Outputs 0;
+c.f(); // Outputs 1;
+
+write(c.parent.x); // Outputs 2;
+write(c.y); // Outputs 3;
+@end verbatim
+
+For further examples of structures, see @code{Legend} and @code{picture} in
+the @code{Asymptote} base module @code{plain}.
+
+@node Operators, Implicit scaling, Structures, Programming
+@section Operators
+@cindex operators
+
+@menu
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+@end menu
+
+@node Arithmetic & logical, Self & prefix operators, Operators, Operators
+@subsection Arithmetic & logical operators
+@cindex arithmetic operators
+@cindex binary operators
+@cindex boolean operators
+@cindex logical operators
+@cindex @code{quotient}
+
+@code{Asymptote} uses the standard binary arithmetic operators.
+However, when one integer is divided by another, both arguments are
+converted to real values before dividing and a real quotient is
+returned (since this is typically what is intended; otherwise
+one can use the function @code{int quotient(int x, int y)}, which returns
+greatest integer less than or equal to @code{x/y}). In all other cases both
+operands are promoted to the same type, which will also be the
+type of the result:
+@table @code
+@cindex @code{+}
+@item +
+addition
+@cindex @code{-}
+@item -
+subtractiona
+@cindex @code{*}
+@item *
+multiplication
+@cindex @code{/}
+@item /
+division
+@cindex integer division
+@cindex @code{#}
+@item #
+integer division; equivalent to @code{quotient(x,y)}. Noting that the
+@code{Python3} community adopted our comment symbol (@code{//}) for
+integer division, we decided to reciprocate and use their comment
+symbol for integer division in @code{Asymptote}!
+@cindex @code{%}
+@item %
+modulo; the result always has the same sign as the divisor.
+In particular, this makes @code{q*(p # q)+p % q == p} for all
+integers @code{p} and nonzero integers @code{q}.
+@cindex @code{^}
+@item ^
+@cindex @code{**}
+power; if the exponent (second argument) is an int, recursive
+multiplication is used; otherwise, logarithms and exponentials are used
+(@code{**} is a synonym for @code{^}).
+
+@end table
+
+The usual boolean operators are also defined:
+@table @code
+@cindex @code{==}
+@item ==
+equals
+@cindex @code{!=}
+@item !=
+not equals
+@cindex @code{<}
+@item <
+less than
+@cindex @code{<=}
+@item <=
+less than or equals
+@cindex @code{>=}
+@item >=
+greater than or equals
+@cindex @code{>}
+@item >
+greater than
+@cindex @code{&&}
+@item &&
+and (with conditional evaluation of right-hand argument)
+@cindex @code{&}
+@item &
+and
+@cindex @code{||}
+@item ||
+or (with conditional evaluation of right-hand argument)
+@cindex @code{|}
+@item |
+or
+@cindex @code{^}
+@item ^
+xor
+@cindex @code{!}
+@item !
+not
+@end table
+
+@code{Asymptote} also supports the C-like conditional syntax:
+@cindex @code{:}
+@cindex @code{?}
+@cindex conditional
+@verbatim
+bool positive=(pi > 0) ? true : false;
+@end verbatim
+
+@cindex @code{interp}
+The function @code{T interp(T a, T b, real t)} returns @code{(1-t)*a+t*b}
+for nonintegral built-in arithmetic types @code{T}. If @code{a} and
+@code{b} are pens, they are first promoted to the same color space.
+
+@cindex @code{AND}
+@cindex @code{OR}
+@cindex @code{XOR}
+@cindex @code{NOT}
+@cindex @code{CLZ}
+@cindex @code{CTZ}
+@code{Asymptote} also defines bitwise functions @code{int AND(int,int)},
+@code{int OR(int,int)}, @code{int XOR(int,int)}, @code{int NOT(int)},
+@code{int CLZ(int)} (count leading zeros),
+@code{int CTZ(int)} (count trailing zeros),
+@code{int popcount(int)} (count bits populated by ones), and
+@code{int bitreverse(int a, int bits)} (reverse bits within a word of
+length bits).
+
+@node Self & prefix operators, User-defined operators, Arithmetic & logical, Operators
+@subsection Self & prefix operators
+@cindex self operators
+@cindex prefix operators
+@cindex @code{+=}
+@cindex @code{-=}
+@cindex @code{*=}
+@cindex @code{/=}
+@cindex @code{%=}
+@cindex @code{^=}
+@cindex @code{++}
+@cindex @code{--}
+
+As in C, each of the arithmetic operators @code{+}, @code{-}, @code{*},
+@code{/}, @code{#}, @code{%}, and @code{^} can be used as a self operator.
+The prefix operators @code{++} (increment by one) and @code{--} (decrement
+by one) are also defined.
+For example,
+@verbatim
+int i=1;
+i += 2;
+int j=++i;
+@end verbatim
+
+@noindent
+is equivalent to the code
+@verbatim
+int i=1;
+i=i+2;
+int j=i=i+1;
+@end verbatim
+
+@cindex postfix operators
+However, postfix operators like @code{i++} and @code{i--} are not defined
+(because of the inherent ambiguities that would arise with the @code{--}
+path-joining operator). In the rare instances where @code{i++}
+and @code{i--} are really needed, one can substitute the expressions
+@code{(++i-1)} and @code{(--i+1)}, respectively.
+
+@node User-defined operators, , Self & prefix operators, Operators
+@subsection User-defined operators
+@cindex user-defined operators
+@cindex @code{operator}
+The following symbols may be used with @code{operator} to define or redefine
+operators on structures and built-in types:
+@verbatim
+- + * / % ^ ! < > == != <= >= & | ^^ .. :: -- --- ++
+<< >> $ $$ @ @@ <>
+@end verbatim
+@noindent
+The operators on the second line have precedence one higher than the
+boolean operators @code{<}, @code{>}, @code{<=}, and @code{>=}.
+
+Guide operators like @code{..} may be overloaded, say, to write
+a user function that produces a new guide from a given guide:
+@verbatim
+guide dots(... guide[] g)=operator ..;
+
+guide operator ..(... guide[] g) {
+ guide G;
+ if(g.length > 0) {
+ write(g[0]);
+ G=g[0];
+ }
+ for(int i=1; i < g.length; ++i) {
+ write(g[i]);
+ write();
+ G=dots(G,g[i]);
+ }
+ return G;
+}
+
+guide g=(0,0){up}..{SW}(100,100){NE}..{curl 3}(50,50)..(10,10);
+write("g=",g);
+@end verbatim
+
+@node Implicit scaling, Functions, Operators, Programming
+@section Implicit scaling
+@cindex implicit scaling
+
+If a numeric literal is in front of certain types of expressions, then the two
+are multiplied:
+@verbatim
+int x=2;
+real y=2.0;
+real cm=72/2.540005;
+
+write(3x);
+write(2.5x);
+write(3y);
+write(-1.602e-19 y);
+write(0.5(x,y));
+write(2x^2);
+write(3x+2y);
+write(3(x+2y));
+write(3sin(x));
+write(3(sin(x))^2);
+write(10cm);
+@end verbatim
+
+This produces the output
+@verbatim
+6
+5
+6
+-3.204e-19
+(1,1)
+8
+10
+18
+2.72789228047704
+2.48046543129542
+283.464008929116
+@end verbatim
+
+@node Functions, Arrays, Implicit scaling, Programming
+@section Functions
+@cindex functions
+
+@menu
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+@end menu
+
+@code{Asymptote} functions are treated as variables with a signature
+(non-function variables have null signatures). Variables with the
+same name are allowed, so long as they have distinct signatures.
+
+Functions arguments are passed by value. To pass an argument by
+reference, simply enclose it in a structure (@pxref{Structures}).
+
+Here are some significant features of @code{Asymptote} functions:
+
+@enumerate
+@item Variables with signatures (functions) and without signatures
+(nonfunction variables) are distinct:
+@verbatim
+int x, x();
+x=5;
+x=new int() {return 17;};
+x=x(); // calls x() and puts the result, 17, in the scalar x
+@end verbatim
+
+@item Traditional function definitions are allowed:
+@verbatim
+int sqr(int x)
+{
+ return x*x;
+}
+sqr=null; // but the function is still just a variable.
+@end verbatim
+
+@item Casting can be used to resolve ambiguities:
+@verbatim
+int a, a(), b, b(); // Valid: creates four variables.
+a=b; // Invalid: assignment is ambiguous.
+a=(int) b; // Valid: resolves ambiguity.
+(int) (a=b); // Valid: resolves ambiguity.
+(int) a=b; // Invalid: cast expressions cannot be L-values.
+
+int c();
+c=a; // Valid: only one possible assignment.
+@end verbatim
+
+@item Anonymous (so-called "high-order") functions are also allowed:
+@cindex @code{typedef}
+@verbatim
+typedef int intop(int);
+intop adder(int m)
+{
+ return new int(int n) {return m+n;};
+}
+intop addby7=adder(7);
+write(addby7(1)); // Writes 8.
+@end verbatim
+
+@item
+@cindex overloading functions
+One may redefine a function @code{f}, even for calls to @code{f} in previously
+declared functions, by assigning another (anonymous or named)
+function to it. However, if @code{f} is overloaded by a
+new function definition, previous calls will still access the original
+version of @code{f}, as illustrated in this example:
+@verbatim
+void f() {
+ write("hi");
+}
+
+void g() {
+ f();
+}
+
+g(); // writes "hi"
+
+f=new void() {write("bye");};
+
+g(); // writes "bye"
+
+void f() {write("overloaded");};
+
+f(); // writes "overloaded"
+g(); // writes "bye"
+@end verbatim
+
+@cindex function declarations
+@item Anonymous functions can be used to redefine a function variable
+that has been declared (and implicitly initialized to the null function)
+but not yet explicitly defined:
+@verbatim
+void f(bool b);
+
+void g(bool b) {
+ if(b) f(b);
+ else write(b);
+}
+
+f=new void(bool b) {
+ write(b);
+ g(false);
+};
+
+g(true); // Writes true, then writes false.
+@end verbatim
+
+@end enumerate
+
+@code{Asymptote} is the only language we know of that treats functions
+as variables, but allows overloading by distinguishing variables
+based on their signatures.
+
+@cindex @code{libsigsegv}
+@cindex stack overflow
+@anchor{stack overflow}
+@cindex recursion
+@cindex stack overflow
+Functions are allowed to call themselves recursively. As in C++, infinite
+nested recursion will generate a stack overflow (reported as a
+segmentation fault, unless a fully working version of the @acronym{GNU}
+library @code{libsigsegv} (e.g.@ 2.4 or later) is installed at
+configuration time).
+
+@node Default arguments, Named arguments, Functions, Functions
+@subsection Default arguments
+@cindex default arguments
+@cindex arguments
+
+@code{Asymptote} supports a more flexible mechanism for default function
+arguments than C++: they may appear anywhere in the function prototype.
+Because certain data types are implicitly cast to more sophisticated
+types (@pxref{Casts}) one can often avoid ambiguities by ordering
+function arguments from the simplest to the most complicated.
+For example, given
+@verbatim
+real f(int a=1, real b=0) {return a+b;}
+@end verbatim
+@noindent
+then @code{f(1)} returns 1.0, but @code{f(1.0)} returns 2.0.
+
+The value of a default argument is determined by evaluating the
+given @code{Asymptote} expression in the scope where the called
+function is defined.
+
+@node Named arguments, Rest arguments, Default arguments, Functions
+@subsection Named arguments
+@cindex keywords
+@cindex named arguments
+
+It is sometimes difficult to remember the order in which arguments
+appear in a function declaration. Named (keyword) arguments make calling
+functions with multiple arguments easier. Unlike in the C and C++
+languages, an assignment in a function argument is interpreted as an
+assignment to a parameter of the same name in the function signature,
+@emph{not within the local scope}. The command-line option @code{-d}
+may be used to check @code{Asymptote} code for cases where a
+named argument may be mistaken for a local assignment.
+
+When matching arguments to signatures, first all of the keywords are
+matched, then the arguments without names are matched against the
+unmatched formals as usual. For example,
+@verbatim
+int f(int x, int y) {
+ return 10x+y;
+}
+write(f(4,x=3));
+@end verbatim
+@noindent
+outputs 34, as @code{x} is already matched when we try to match the
+unnamed argument @code{4}, so it gets matched to the next item, @code{y}.
+
+For the rare occasions where it is desirable to assign a value to
+local variable within a function argument (generally @emph{not} a good
+programming practice), simply enclose the assignment in
+parentheses. For example, given the definition of @code{f} in the
+previous example,
+@verbatim
+int x;
+write(f(4,(x=3)));
+@end verbatim
+@noindent
+is equivalent to the statements
+@verbatim
+int x;
+x=3;
+write(f(4,3));
+@end verbatim
+@noindent
+and outputs 43.
+
+@cindex @code{keyword}
+@cindex keyword-only
+Parameters can be specified as ``keyword-only'' by putting @code{keyword}
+immediately before the parameter name, as in @code{int f(int keyword x)} or
+@code{int f(int keyword x=77)}. This forces the caller of the function to use
+a named argument to give a value for this parameter. That is, @code{f(x=42)}
+is legal, but @code{f(25)} is not. Keyword-only parameters must be listed
+after normal parameters in a function definition.
+
+
+As a technical detail, we point out that, since variables of the same
+name but different signatures are allowed in the same scope, the code
+@verbatim
+int f(int x, int x()) {
+ return x+x();
+}
+int seven() {return 7;}
+@end verbatim
+@noindent
+is legal in @code{Asymptote}, with @code{f(2,seven)} returning 9.
+A named argument matches the first unmatched formal of the same name, so
+@code{f(x=2,x=seven)} is an equivalent call, but @code{f(x=seven,2)}
+is not, as the first argument is matched to the first formal, and
+@code{int ()} cannot be implicitly cast to @code{int}. Default
+arguments do not affect which formal a named argument is matched to,
+so if @code{f} were defined as
+@verbatim
+int f(int x=3, int x()) {
+ return x+x();
+}
+@end verbatim
+@noindent
+then @code{f(x=seven)} would be illegal, even though @code{f(seven)}
+obviously would be allowed.
+
+@node Rest arguments, Mathematical functions, Named arguments, Functions
+@subsection Rest arguments
+@cindex rest arguments
+
+Rest arguments allow one to write functions that take a variable
+number of arguments:
+@verbatim
+// This function sums its arguments.
+int sum(... int[] nums) {
+ int total=0;
+ for(int i=0; i < nums.length; ++i)
+ total += nums[i];
+ return total;
+}
+
+sum(1,2,3,4); // returns 10
+sum(); // returns 0
+
+// This function subtracts subsequent arguments from the first.
+int subtract(int start ... int[] subs) {
+ for(int i=0; i < subs.length; ++i)
+ start -= subs[i];
+ return start;
+}
+
+subtract(10,1,2); // returns 7
+subtract(10); // returns 10
+subtract(); // illegal
+@end verbatim
+
+@cindex packing
+Putting an argument into a rest array is called @emph{packing}.
+One can give an explicit list of arguments for the rest
+argument, so @code{subtract} could alternatively be implemented as
+@verbatim
+int subtract(int start ... int[] subs) {
+ return start - sum(... subs);
+}
+@end verbatim
+
+One can even combine normal arguments with rest arguments:
+@verbatim
+sum(1,2,3 ... new int[] {4,5,6}); // returns 21
+@end verbatim
+@noindent
+@cindex unpacking
+This builds a new six-element array that is passed to @code{sum} as
+@code{nums}. The opposite operation, @emph{unpacking}, is not allowed:
+@verbatim
+subtract(... new int[] {10, 1, 2});
+@end verbatim
+@noindent
+is illegal, as the start formal is not matched.
+
+If no arguments are packed, then a zero-length array (as opposed to
+@code{null}) is bound to the rest parameter. Note that default
+arguments are ignored for rest formals and the rest argument is not
+bound to a keyword.
+
+In some cases, keyword-only parameters are helpful to avoid arguments intended
+for the rest parameter to be assigned to other parameters. For example, here
+the use of @code{keyword} is to avoid @code{pnorm(1.0,2.0,0.3)} matching
+@code{1.0} to @code{p}.
+@verbatim
+real pnorm(real keyword p=2.0 ... real[] v)
+{
+ return sum(v^p)^(1/p);
+}
+@end verbatim
+
+The overloading resolution in @code{Asymptote} is similar to the
+function matching rules used in C++. Every argument match is given a
+score. Exact matches score better than matches with casting, and
+matches with formals (regardless of casting) score better than packing
+an argument into the rest array. A candidate is maximal if all of the
+arguments score as well in it as with any other candidate. If there
+is one unique maximal candidate, it is chosen; otherwise, there is an
+ambiguity error.
+
+@verbatim
+int f(path g);
+int f(guide g);
+f((0,0)--(100,100)); // matches the second; the argument is a guide
+
+int g(int x, real y);
+int g(real x, int x);
+
+g(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second argument
+
+int h(... int[] rest);
+int h(real x ... int[] rest);
+
+h(1,2); // the second definition matches, even though there is a cast,
+ // because casting is preferred over packing
+
+int i(int x ... int[] rest);
+int i(real x, real y ... int[] rest);
+
+i(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second one
+@end verbatim
+
+@node Mathematical functions, , Rest arguments, Functions
+@subsection Mathematical functions
+@cindex mathematical functions
+@cindex functions
+@cindex @code{libm} routines
+
+@cindex @code{sin}
+@cindex @code{cos}
+@cindex @code{tan}
+@cindex @code{asin}
+@cindex @code{acos}
+@cindex @code{atan}
+@cindex @code{exp}
+@cindex @code{log}
+@cindex @code{pow10}
+@cindex @code{log10}
+@cindex @code{sinh}
+@cindex @code{cosh}
+@cindex @code{tanh}
+@cindex @code{asinh}
+@cindex @code{acosh}
+@cindex @code{atanh}
+@cindex @code{sqrt}
+@cindex @code{cbrt}
+@cindex @code{fabs}
+@cindex @code{expm1}
+@cindex @code{log1p}
+@cindex @code{identity}
+@cindex @code{J}
+@cindex @code{Y}
+@cindex @code{gamma}
+@cindex @code{erf}
+@cindex @code{erfc}
+@cindex @code{atan2}
+@cindex @code{hypot}
+@cindex @code{fmod}
+@cindex @code{remainder}
+@code{Asymptote} has built-in versions of the standard @code{libm} mathematical
+real(real) functions @code{sin}, @code{cos}, @code{tan}, @code{asin},
+@code{acos}, @code{atan}, @code{exp}, @code{log}, @code{pow10},
+@code{log10}, @code{sinh}, @code{cosh}, @code{tanh}, @code{asinh},
+@code{acosh}, @code{atanh}, @code{sqrt}, @code{cbrt}, @code{fabs}, @code{expm1},
+@code{log1p}, as well as the identity function @code{identity}.
+@code{Asymptote} also defines the order @code{n} Bessel functions of
+the first kind @code{Jn(int n, real)} and second kind
+@code{Yn(int n, real)}, as well as the gamma function @code{gamma},
+the error function @code{erf}, and the complementary error function
+@code{erfc}. The standard real(real, real) functions @code{atan2},
+@code{hypot}, @code{fmod}, @code{remainder} are also included.
+
+@cindex @code{degrees}
+@cindex @code{radians}
+@cindex @code{Degrees}
+The functions @code{degrees(real radians)} and @code{radians(real degrees)}
+can be used to convert between radians and degrees. The function
+@code{Degrees(real radians)} returns the angle in degrees in the
+interval [0,360).
+@cindex @code{Sin}
+@cindex @code{Cos}
+@cindex @code{Tan}
+@cindex @code{aSin}
+@cindex @code{aCos}
+@cindex @code{aTan}
+For convenience, @code{Asymptote} defines variants @code{Sin},
+@code{Cos}, @code{Tan}, @code{aSin}, @code{aCos}, and @code{aTan} of
+the standard trigonometric functions that use degrees rather than radians.
+We also define complex versions of the @code{sqrt}, @code{sin}, @code{cos},
+@code{exp}, @code{log}, and @code{gamma} functions.
+
+@cindex @code{floor}
+@cindex @code{ceil}
+@cindex @code{round}
+@cindex @code{sgn}
+The functions @code{floor}, @code{ceil}, and @code{round} differ from
+their usual definitions in that they all return an int value rather than
+a real (since that is normally what one wants).
+The functions @code{Floor}, @code{Ceil}, and @code{Round} are
+respectively similar, except that if the result cannot be converted
+to a valid int, they return @code{intMax}
+for positive arguments and @code{intMin} for negative arguments,
+rather than generating an integer overflow.
+We also define a function @code{sgn}, which returns the sign of its
+real argument as an integer (-1, 0, or 1).
+
+@cindex @code{abs}
+There is an @code{abs(int)} function, as well as an @code{abs(real)}
+function (equivalent to @code{fabs(real)}), an @code{abs(pair)} function
+(equivalent to @code{length(pair)}).
+
+@cindex @code{srand}
+@cindex @code{rand}
+@cindex @code{randMax}
+@cindex @code{unitrand}
+@cindex @code{Gaussrand}
+@cindex @code{histogram}
+@cindex @code{factorial}
+@cindex @code{choose}
+Random numbers can be seeded with @code{srand(int)} and generated with
+the @code{int rand()} function, which returns a random integer between 0
+and the integer @code{randMax}. The @code{unitrand()} function returns
+a random number uniformly distributed in the interval [0,1].
+A Gaussian random number generator
+@code{Gaussrand} and a collection of statistics routines, including
+@code{histogram}, are provided in the base file @code{@uref{http://asymptote.sourceforge.net/gallery/stats.pdf,,stats}@uref{http://asymptote.sourceforge.net/gallery/stats.asy,,.asy}}.
+The functions @code{factorial(int n)}, which returns @math{n!}, and
+@code{choose(int n, int k)}, which returns @math{n!/(k!(n-k)!)}, are
+also defined.
+
+@cindex @acronym{GNU} Scientific Library
+@cindex @code{gsl}
+@cindex Airy
+@cindex Bessel
+@cindex Legendre
+@cindex elliptic functions
+@cindex exponential integral
+@cindex trigonometric integrals
+@cindex Riemann zeta function
+@cindex @code{Ai}
+@cindex @code{Bi}
+@cindex @code{Ai_deriv}
+@cindex @code{Bi_deriv}
+@cindex @code{zero_Ai}
+@cindex @code{zero_Bi}
+@cindex @code{zero_Ai_deriv}
+@cindex @code{zero_Bi_deriv}
+@cindex @code{J}
+@cindex @code{Y}
+@cindex @code{I}
+@cindex @code{K}
+@cindex @code{i_scaled}
+@cindex @code{k_scaled}
+@cindex @code{zero_J}
+@cindex @code{F}
+@cindex @code{E}
+@cindex @code{P}
+@cindex @code{sncndn}
+@cindex @code{Ei}
+@cindex @code{Si}
+@cindex @code{Ci}
+@cindex @code{Pl}
+@cindex @code{zeta}
+When configured with the @acronym{GNU} Scientific Library (GSL), available from
+@url{http://www.gnu.org/software/gsl/},
+@code{Asymptote} contains an internal module @code{gsl} that
+defines the airy functions @code{Ai(real)},
+@code{Bi(real)}, @code{Ai_deriv(real)}, @code{Bi_deriv(real)},
+@code{zero_Ai(int)}, @code{zero_Bi(int)},
+@code{zero_Ai_deriv(int)}, @code{zero_Bi_deriv(int)}, the Bessel functions
+@code{I(int, real)}, @code{K(int, real)}, @code{j(int, real)},
+@code{y(int, real)}, @code{i_scaled(int, real)}, @code{k_scaled(int, real)},
+@code{J(real, real)}, @code{Y(real, real)}, @code{I(real, real)},
+@code{K(real, real)}, @code{zero_J(real, int)}, the elliptic functions
+@code{F(real, real)}, @code{E(real, real)}, and @code{P(real, real)},
+the Jacobi elliptic functions @code{real[] sncndn(real,real)},
+the exponential/trigonometric integrals @code{Ei}, @code{Si}, and @code{Ci},
+the Legendre polynomials @code{Pl(int, real)}, and the Riemann zeta
+function @code{zeta(real)}. For example, to compute the sine integral
+@code{Si} of 1.0:
+@verbatim
+import gsl;
+write(Si(1.0));
+@end verbatim
+
+@code{Asymptote} also provides a few general purpose numerical routines:
+
+@table @code
+
+@cindex @code{newton}
+@item @code{real newton(int iterations=100, real f(real), real fprime(real), real x, bool verbose=false);}
+Use Newton-Raphson iteration to solve for a root of a real-valued
+differentiable function @code{f}, given its derivative @code{fprime} and
+an initial guess @code{x}. Diagnostics for
+each iteration are printed if @code{verbose=true}.
+If the iteration fails after the maximum allowed number of loops
+(@code{iterations}), @code{realMax} is returned.
+
+@cindex @code{newton}
+@item @code{real newton(int iterations=100, real f(real), real fprime(real), real x1, real x2, bool verbose=false);}
+Use bracketed Newton-Raphson bisection to solve for a root of a real-valued
+differentiable function @code{f} within an interval
+[@code{x1},@code{x2}] (on which the endpoint values of @code{f} have
+opposite signs), given its derivative @code{fprime}. Diagnostics for
+each iteration are printed if @code{verbose=true}.
+If the iteration fails after the maximum allowed number of loops
+(@code{iterations}), @code{realMax} is returned.
+
+@cindex integral
+@cindex integrate
+@cindex @code{simpson}
+@item @code{real simpson(real f(real), real a, real b, real acc=realEpsilon, real dxmax=b-a)}
+returns the integral of @code{f} from @code{a} to @code{b} using adaptive Simpson integration.
+
+@end table
+
+@node Arrays, Casts, Functions, Programming
+@section Arrays
+@cindex arrays
+
+@menu
+* Slices:: Python-style array slices
+@end menu
+
+Appending @code{[]} to a built-in or user-defined type yields an array.
+The array element @code{i} of an array @code{A} can be accessed as @code{A[i]}.
+By default, attempts to access or assign to an array element using a negative
+index generates an error. Reading an array element with an index
+beyond the length of the array also generates an error; however,
+assignment to an element beyond the length of the array causes the
+array to be resized to accommodate the new element.
+One can also index an array @code{A} with an integer array @code{B}:
+the array @code{A[B]} is formed by indexing array @code{A} with
+successive elements of array @code{B}.
+A convenient Java-style shorthand exists for iterating over all elements of an
+array; see @ref{array iteration}.
+
+The declaration
+@verbatim
+real[] A;
+@end verbatim
+
+@noindent
+initializes @code{A} to be an empty (zero-length) array. Empty arrays should be
+distinguished from null arrays. If we say
+@verbatim
+real[] A=null;
+@end verbatim
+
+@noindent
+then @code{A} cannot be dereferenced at all (null arrays have no length
+and cannot be read from or assigned to).
+
+Arrays can be explicitly initialized like this:
+@verbatim
+real[] A={0,1,2};
+@end verbatim
+
+Array assignment in @code{Asymptote} does a shallow copy: only
+the pointer is copied (if one copy if modified, the other will be too).
+The @code{copy} function listed below provides a deep copy of an array.
+
+@cindex @code{length}
+@cindex @code{cyclic}
+@cindex @code{keys}
+@cindex @code{push}
+@cindex @code{append}
+@cindex @code{pop}
+@cindex @code{insert}
+@cindex @code{delete}
+@cindex @code{initialized}
+Every array @code{A} of type @code{T[]} has the virtual members
+@itemize
+@item @code{int length},
+@item @code{int cyclic},
+@item @code{int[] keys},
+@item @code{T push(T x)},
+@item @code{void append(T[] a)},
+@item @code{T pop()},
+@item @code{void insert(int i ... T[] x)},
+@item @code{void delete(int i, int j=i)},
+@item @code{void delete()}, and
+@item @code{bool initialized(int n)}.
+@end itemize
+
+The member @code{A.length} evaluates to the length of the array.
+Setting @code{A.cyclic=true} signifies that array indices should be reduced
+modulo the current array length. Reading from or writing to a nonempty
+cyclic array never leads to out-of-bounds errors or array resizing.
+
+The member @code{A.keys} evaluates to an array of integers containing the
+indices of initialized entries in the array in ascending order. Hence, for an
+array of length @code{n} with all entries initialized, @code{A.keys} evaluates
+to @code{@{0,1,...,n-1@}}. A new keys array is produced each time
+@code{A.keys} is evaluated.
+
+The functions @code{A.push} and @code{A.append} append their
+arguments onto the end of the array, while @code{A.insert(int i ... T[] x)}
+inserts @code{x} into the array at index @code{i}.
+For convenience @code{A.push} returns the pushed item.
+The function @code{A.pop()} pops and returns the last element,
+while @code{A.delete(int i, int j=i)} deletes elements with indices in
+the range [@code{i},@code{j}], shifting the position of all higher-indexed
+elements down. If no arguments are given, @code{A.delete()} provides a
+convenient way of deleting all elements of @code{A}. The routine
+@code{A.initialized(int n)} can be used to examine whether the element
+at index @code{n} is initialized. Like all @code{Asymptote} functions,
+@code{push}, @code{append}, @code{pop}, @code{insert},
+@code{delete}, and @code{initialized} can be "pulled off" of the array
+and used on their own. For example,
+@verbatim
+int[] A={1};
+A.push(2); // A now contains {1,2}.
+A.append(A); // A now contains {1,2,1,2}.
+int f(int)=A.push;
+f(3); // A now contains {1,2,1,2,3}.
+int g()=A.pop;
+write(g()); // Outputs 3.
+A.delete(0); // A now contains {2,1,2}.
+A.delete(0,1); // A now contains {2}.
+A.insert(1,3); // A now contains {2,3}.
+A.insert(1 ... A); // A now contains {2,2,3,3}
+A.insert(2,4,5); // A now contains {2,2,4,5,3,3}.
+@end verbatim
+
+The @code{[]} suffix can also appear after the variable name; this
+is sometimes convenient for declaring a list of variables and arrays
+of the same type:
+@verbatim
+real a,A[];
+@end verbatim
+@noindent
+This declares @code{a} to be @code{real} and implicitly declares @code{A} to
+be of type @code{real[]}.
+
+In the following list of built-in array functions, @code{T} represents a
+generic type. Note that the internal functions @code{alias}, @code{array},
+@code{copy}, @code{concat}, @code{sequence}, @code{map}, and
+@code{transpose}, which depend on type @code{T[]}, are defined only after the
+first declaration of a variable of type @code{T[]}.
+
+@table @code
+
+@cindex @code{new}
+@item new T[]
+returns a new empty array of type @code{T[]};
+
+@cindex @code{new}
+@item new T[] @{list@}
+returns a new array of type @code{T[]} initialized with @code{list} (a comma
+delimited list of elements).
+
+@item new T[n]
+returns a new array of @code{n} elements of type @code{T[]}.
+These @code{n} array elements are not initialized unless they are arrays
+themselves (in which case they are each initialized to empty arrays).
+
+@cindex @code{array}
+@item T[] array(int n, T value, int depth=intMax)
+returns an array consisting of @code{n} copies of @code{value}.
+If @code{value} is itself an array, a deep copy of @code{value} is made
+for each entry. If @code{depth} is specified, this deep copying only
+recurses to the specified number of levels.
+
+@cindex @code{sequence}
+@item int[] sequence(int n)
+if @code{n >= 1} returns the array @code{@{0,1,...,n-1@}} (otherwise returns
+a null array);
+
+@item int[] sequence(int n, int m)
+if @code{m >= n} returns an array @code{@{n,n+1,...,m@}} (otherwise
+returns a null array);
+
+@item T[] sequence(T f(int), int n)
+if @code{n >= 1} returns the sequence @code{@{f_i :i=0,1,...n-1@}} given a
+function @code{T f(int)} and integer @code{int n} (otherwise returns a
+null array);
+
+@cindex @code{map}
+@item T[] map(T f(T), T[] a)
+returns the array obtained by applying the function @code{f} to each
+element of the array @code{a}. This is equivalent to
+@code{sequence(new T(int i) @{return f(a[i]);@},a.length)}.
+
+@cindex @code{reverse}
+@item int[] reverse(int n)
+if @code{n >= 1} returns the array @code{@{n-1,n-2,...,0@}} (otherwise
+returns a null array);
+
+@cindex @code{complement}
+@item int[] complement(int[] a, int n)
+returns the complement of the integer array @code{a} in
+@code{@{0,1,2,...,n-1@}}, so that @code{b[complement(a,b.length)]} yields the
+complement of @code{b[a]}.
+
+@cindex @code{uniform}
+@item real[] uniform(real a, real b, int n)
+if @code{n >= 1} returns a uniform partition of @code{[a,b]} into
+@code{n} subintervals (otherwise returns a null array);
+
+@cindex @code{find}
+@item int find(bool[] a, int n=1)
+returns the index of the @code{n}th @code{true} value in the boolean array
+@code{a} or -1 if not found. If @code{n} is negative, search backwards
+from the end of the array for the @code{-n}th value;
+
+@cindex @code{findall}
+@item int[] findall(bool[] a)
+returns the indices of all @code{true} values in the boolean array @code{a}.
+
+@cindex @code{search}
+@item int search(T[] a, T key)
+For built-in ordered types @code{T}, searches a sorted array
+@code{a} of @code{n} elements for k, returning the index @code{i}
+if @code{a[i] <= key < a[i+1]}, @code{-1} if @code{key} is
+less than all elements of @code{a}, or @code{n-1} if @code{key} is
+greater than or equal to the last element of @code{a}.
+
+@cindex @code{search}
+@item int search(T[] a, T key, bool less(T i, T j))
+searches an array @code{a} sorted in ascending order such that element
+@code{i} precedes element @code{j} if @code{less(i,j)} is true;
+
+@cindex @code{copy}
+@item T[] copy(T[] a)
+returns a deep copy of the array @code{a};
+
+@cindex @code{concat}
+@item T[] concat(... T[][] a)
+returns a new array formed by concatenating the given one-dimensional
+arrays given as arguments;
+
+@cindex @code{alias}
+@item bool alias(T[] a, T[] b)
+returns @code{true} if the arrays @code{a} and @code{b} are identical;
+
+@cindex @code{sort}
+@item T[] sort(T[] a)
+For built-in ordered types @code{T}, returns a copy of @code{a} sorted in
+ascending order;
+
+@cindex @code{sort}
+@anchor{sort}
+@item T[][] sort(T[][] a)
+For built-in ordered types @code{T}, returns a copy of @code{a} with the rows
+sorted by the first column, breaking ties with successively higher
+columns. For example:
+@verbatim
+string[][] a={{"bob","9"},{"alice","5"},{"pete","7"},
+ {"alice","4"}};
+// Row sort (by column 0, using column 1 to break ties):
+write(sort(a));
+@end verbatim
+
+produces
+@verbatim
+alice 4
+alice 5
+bob 9
+pete 7
+@end verbatim
+
+@cindex @code{sort}
+@item T[] sort(T[] a, bool less(T i, T j), bool stable=true)
+returns a copy of @code{a} sorted in ascending order such that
+element @code{i} precedes element @code{j} if @code{less(i,j)} is
+true, subject to (if @code{stable} is @code{true}) the stability constraint
+that the original order of elements @code{i} and @code{j} is preserved if
+@code{less(i,j)} and @code{less(j,i)} are both @code{false}.
+
+@cindex @code{transpose}
+@item T[][] transpose(T[][] a)
+returns the transpose of @code{a}.
+
+@cindex @code{transpose}
+@item T[][][] transpose(T[][][] a, int[] perm)
+returns the 3D transpose of @code{a} obtained by applying the permutation
+@code{perm} of @code{new int[]@{0,1,2@}} to the indices of each entry.
+
+@cindex @code{sum}
+@item T sum(T[] a)
+For arithmetic types @code{T}, returns the sum of @code{a}.
+In the case where @code{T} is @code{bool}, the number of true elements in
+@code{a} is returned.
+
+@cindex @code{min}
+@item T min(T[] a)
+@item T min(T[][] a)
+@item T min(T[][][] a)
+For built-in ordered types @code{T}, returns the minimum element of @code{a}.
+
+@cindex @code{max}
+@item T max(T[] a)
+@item T max(T[][] a)
+@item T max(T[][][] a)
+For built-in ordered types @code{T}, returns the maximum element of @code{a}.
+
+@cindex @code{min}
+@item T[] min(T[] a, T[] b)
+For built-in ordered types @code{T}, and arrays @code{a} and @code{b}
+of the same length, returns an array composed of the minimum of the
+corresponding elements of @code{a} and @code{b}.
+
+@cindex @code{max}
+@item T[] max(T[] a, T[] b)
+For built-in ordered types @code{T}, and arrays @code{a} and @code{b}
+of the same length, returns an array composed of the maximum of the
+corresponding elements of @code{a} and @code{b}.
+
+@cindex @code{pairs}
+@item pair[] pairs(real[] x, real[] y);
+For arrays @code{x} and @code{y} of the same length, returns the pair array
+@code{sequence(new pair(int i) @{return (x[i],y[i]);@},x.length)}.
+
+@cindex @code{fft}
+@item pair[] fft(pair[] a, int sign=1)
+returns the unnormalized Fast Fourier Transform of @code{a} (if the optional
+@code{FFTW} package is installed), using the given @code{sign}. Here
+is a simple example:
+@verbatim
+int n=4;
+pair[] f=sequence(n);
+write(f);
+pair[] g=fft(f,-1);
+write();
+write(g);
+f=fft(g,1);
+write();
+write(f/n);
+@end verbatim
+
+@cindex @code{dot}
+@item real dot(real[] a, real[] b)
+returns the dot product of the vectors @code{a} and @code{b}.
+
+@cindex @code{dot}
+@item pair dot(pair[] a, pair[] b)
+returns the complex dot product @code{sum(a*conj(b))} of the vectors
+@code{a} and @code{b}.
+
+@anchor{tridiagonal}
+@cindex @code{tridiagonal}
+@item real[] tridiagonal(real[] a, real[] b, real[] c, real[] f);
+Solve the periodic tridiagonal problem @math{L@code{x}=@code{f}} and return the
+solution @code{x}, where @code{f}
+is an @math{n} vector and @math{L} is the @math{n \times n} matrix
+@verbatim
+[ b[0] c[0] a[0] ]
+[ a[1] b[1] c[1] ]
+[ a[2] b[2] c[2] ]
+[ ... ]
+[ c[n-1] a[n-1] b[n-1] ]
+@end verbatim
+For Dirichlet boundary conditions (denoted here by @code{u[-1]} and
+@code{u[n]}), replace @code{f[0]} by @code{f[0]-a[0]u[-1]} and
+@code{f[n-1]-c[n-1]u[n]}; then set @code{a[0]=c[n-1]=0}.
+
+@cindex @code{solve}
+@item real[] solve(real[][] a, real[] b, bool warn=true)
+Solve the linear equation @math{@code{a}x=@code{b}} by LU decomposition
+and return the solution @math{x}, where @code{a} is an
+@math{n \times n} matrix and @code{b} is an array of length @math{n}.
+For example:
+@verbatim
+import math;
+real[][] a={{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},{1,50,1,-2}};
+real[] b={7,19,33,3};
+real[] x=solve(a,b);
+write(a); write();
+write(b); write();
+write(x); write();
+write(a*x);
+@end verbatim
+If @code{a} is a singular matrix and @code{warn} is @code{false}, return an
+empty array.
+If the matrix @code{a} is tridiagonal, the routine @code{tridiagonal} provides
+a more efficient algorithm (@pxref{tridiagonal}).
+
+@anchor{solve}
+@cindex @code{solve}
+@item real[][] solve(real[][] a, real[][] b, bool warn=true)
+Solve the linear equation @math{@code{a}x=@code{b}} and return the
+solution @math{x}, where @code{a} is an @math{n \times n} matrix and
+@code{b} is an @math{n \times m} matrix. If @code{a} is a singular
+matrix and @code{warn} is @code{false}, return an empty matrix.
+
+@cindex @code{identity}
+@item real[][] identity(int n);
+returns the @math{n \times n} identity matrix.
+
+@cindex @code{diagonal}
+@item real[][] diagonal(... real[] a)
+returns the diagonal matrix with diagonal entries given by a.
+
+@cindex @code{inverse}
+@item real[][] inverse(real[][] a)
+returns the inverse of a square matrix @code{a}.
+
+@cindex @code{quadraticroots}
+@item @code{real[] quadraticroots(real a, real b, real c);}
+This numerically robust solver returns the real roots of the
+quadratic equation @math{ax^2+bx+c=0}, in ascending order. Multiple
+roots are listed separately.
+
+@cindex @code{quadraticroots}
+@item @code{pair[] quadraticroots(explicit pair a, explicit pair b, explicit pair c);}
+This numerically robust solver returns the complex roots of the
+quadratic equation @math{ax^2+bx+c=0}.
+
+@cindex @code{cubicroots}
+@item @code{real[] cubicroots(real a, real b, real c, real d);}
+This numerically robust solver returns the real roots of the
+cubic equation @math{ax^3+bx^2+cx+d=0}. Multiple roots are listed separately.
+
+@end table
+
+@cindex vectorization
+@code{Asymptote} includes a full set of vectorized array instructions for
+arithmetic (including self) and logical operations. These
+element-by-element instructions are implemented in C++ code for speed. Given
+@verbatim
+real[] a={1,2};
+real[] b={3,2};
+@end verbatim
+@noindent
+then @code{a == b} and @code{a >= 2} both evaluate to the vector
+@code{@{false, true@}}.
+@cindex @code{all}
+To test whether all components of @code{a} and @code{b} agree,
+use the boolean function @code{all(a == b)}. One can also use conditionals like
+@code{(a >= 2) ? a : b}, which returns the array @code{@{3,2@}}, or
+@code{write((a >= 2) ? a : null}, which returns the array @code{@{2@}}.
+
+All of the standard built-in @code{libm} functions of signature
+@code{real(real)} also take a real array as an argument, effectively like an
+implicit call to @code{map}.
+
+As with other built-in types, arrays of the basic data types can be read
+in by assignment. In this example, the code
+@verbatim
+file fin=input("test.txt");
+real[] A=fin;
+@end verbatim
+
+@cindex @code{eof}
+@cindex @code{eol}
+@cindex @code{line}
+@cindex line mode
+@noindent
+reads real values into @code{A} until the end-of-file is reached (or an
+I/O error occurs).
+
+The virtual members @code{dimension}, @code{line}, @code{csv},
+@code{word}, and @code{read} of a file are useful for reading arrays.
+@cindex @code{line}
+For example, if line mode is set with @code{file line(bool b=true)}, then
+reading will stop once the end of the line is reached instead:
+@verbatim
+file fin=input("test.txt");
+real[] A=fin.line();
+@end verbatim
+
+@cindex reading string arrays
+@cindex @code{word}
+@cindex white-space string delimiter mode
+Since string reads by default read up to the end of line anyway, line mode
+normally has no effect on string array reads.
+However, there is a white-space delimiter mode for reading strings,
+@code{file word(bool b=true)}, which causes string reads to respect
+white-space delimiters, instead of the default end-of-line delimiter:
+@verbatim
+file fin=input("test.txt").line().word();
+real[] A=fin;
+@end verbatim
+
+@cindex @code{csv}
+@cindex comma-separated-value mode
+Another useful mode is comma-separated-value mode,
+@code{file csv(bool b=true)}, which causes reads to respect comma delimiters:
+@verbatim
+file fin=csv(input("test.txt"));
+real[] A=fin;
+@end verbatim
+
+@cindex @code{dimension}
+To restrict the number of values read, use the @code{file dimension(int)}
+function:
+@verbatim
+file fin=input("test.txt");
+real[] A=dimension(fin,10);
+@end verbatim
+
+This reads 10 values into A, unless end-of-file (or end-of-line in line mode)
+occurs first. Attempting to read beyond the end of the file will produce a
+runtime error message. Specifying a value of 0 for the integer limit is
+equivalent to the previous example of reading until end-of-file (or
+end-of-line in line mode) is encountered.
+
+Two- and three-dimensional arrays of the basic data types can be read
+in like this:
+@verbatim
+file fin=input("test.txt");
+real[][] A=fin.dimension(2,3);
+real[][][] B=fin.dimension(2,3,4);
+@end verbatim
+@noindent
+
+@cindex @code{read}
+Sometimes the array dimensions are stored with the data as integer
+fields at the beginning of an array. Such 1, 2, or 3 dimensional
+arrays can be read in with the virtual member functions
+@code{read(1)}, @code{read(2)}, or @code{read(3)}, respectively:
+@verbatim
+file fin=input("test.txt");
+real[] A=fin.read(1);
+real[][] B=fin.read(2);
+real[][][] C=fin.read(3);
+@end verbatim
+
+@cindex @code{write}
+One, two, and three-dimensional arrays of the basic data types can be
+output with the functions @code{write(file,T[])},
+@code{write(file,T[][])}, @code{write(file,T[][][])}, respectively.
+
+@node Slices, , Arrays, Arrays
+@subsection Slices
+@cindex slices
+
+Asymptote allows a section of an array to be addressed as a slice
+using a Python-like syntax. If @code{A} is an array, the expression
+@code{A[m:n]} returns a new array consisting of the elements of @code{A} with
+indices from @code{m} up to but not including @code{n}. For example,
+@verbatim
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[2:6]; // y={2,3,4,5};
+int[] z=x[5:10]; // z={5,6,7,8,9};
+@end verbatim
+
+If the left index is omitted, it is taken be @code{0}. If the right index is
+omitted it is taken to be the length of the array. If both are omitted, the
+slice then goes from the start of the array to the end, producing a non-cyclic
+deep copy of the array. For example:
+@verbatim
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[:4]; // y={0,1,2,3}
+int[] z=x[5:]; // z={5,6,7,8,9}
+int[] w=x[:]; // w={0,1,2,3,4,5,6,7,8,9}, distinct from array x.
+@end verbatim
+
+If A is a non-cyclic array, it is illegal to use negative values for either of
+the indices. If the indices exceed the length of the array, however, they are
+politely truncated to that length.
+
+For cyclic arrays, the slice @code{A[m:n]} still consists of the cells with
+indices in the set [@code{m},@code{n}), but now negative
+values and values beyond the length of the array are allowed. The indices
+simply wrap around. For example:
+
+@verbatim
+int[] x={0,1,2,3,4,5,6,7,8,9};
+x.cyclic=true;
+int[] y=x[8:15]; // y={8,9,0,1,2,3,4}.
+int[] z=x[-5:5]; // z={5,6,7,8,9,0,1,2,3,4}
+int[] w=x[-3:17]; // w={7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}
+@end verbatim
+
+Notice that with cyclic arrays, it is possible to include the same element of
+the original array multiple times within a slice. Regardless of the original
+array, arrays produced by slices are always non-cyclic.
+
+If the left and right indices of a slice are the same, the result is an empty
+array. If the array being sliced is empty, the result is an empty array. Any
+slice with a left index greater than its right index will yield an error.
+
+Slices can also be assigned to, changing the value of the original array. If
+the array being assigned to the slice has a different length than the
+slice itself, elements will be inserted or removed from the array to
+accommodate it. For instance:
+@verbatim
+string[] toppings={"mayo", "salt", "ham", "lettuce"};
+toppings[0:2]=new string[] {"mustard", "pepper"};
+ // Now toppings={"mustard", "pepper", "ham", "lettuce"}
+toppings[2:3]=new string[] {"turkey", "bacon" };
+ // Now toppings={"mustard", "pepper", "turkey", "bacon", "lettuce"}
+toppings[0:3]=new string[] {"tomato"};
+ // Now toppings={"tomato", "bacon", "lettuce"}
+@end verbatim
+
+If an array is assigned to a slice of itself, a copy of the original array
+is assigned to the slice. That is, code such as @code{x[m:n]=x} is equivalent
+to @code{x[m:n]=copy(x)}. One can use the shorthand @code{x[m:m]=y} to insert
+the contents of the array @code{y} into the array @code{x} starting at the
+location just before @code{x[m]}.
+
+For a cyclic array, a slice is bridging if it addresses cells up to the end of
+the array and then continues on to address cells at the start of the array.
+For instance, if @code{A} is a cyclic array of length 10, @code{A[8:12]},
+@code{A[-3:1]}, and @code{A[5:25]} are bridging slices whereas @code{A[3:7]},
+@code{A[7:10]}, @code{A[-3:0]} and @code{A[103:107]} are not. Bridging slices
+can only be assigned to if the number of elements in the slice is exactly equal
+to the number of elements we are assigning to it. Otherwise, there is no clear
+way to decide which of the new entries should be @code{A[0]} and an error is
+reported. Non-bridging slices may be assigned an array of any length.
+
+For a cyclic array @code{A} an expression of the form
+@code{A[A.length:A.length]} is equivalent to the expression @code{A[0:0]} and
+so assigning to this slice will insert values at the start of the array.
+@code{A.append()} can be used to insert values at the end of the array.
+
+It is illegal to assign to a slice of a cyclic array that repeats any of the
+cells.
+
+@node Casts, Import, Arrays, Programming
+@section Casts
+@cindex casts
+@cindex implicit casts
+@cindex @code{explicit}
+
+@code{Asymptote} implicitly casts @code{int} to @code{real}, @code{int} to
+@code{pair}, @code{real} to @code{pair}, @code{pair} to @code{path},
+@code{pair} to @code{guide}, @code{path} to @code{guide}, @code{guide}
+to @code{path}, @code{real} to @code{pen},
+@code{pair[]} to @code{guide[]}, @code{pair[]} to @code{path[]},
+@code{path} to @code{path[]}, and @code{guide} to @code{path[]},
+along with various three-dimensional casts defined in @code{@uref{http://asymptote.sourceforge.net/gallery/three.pdf,,three}@uref{http://asymptote.sourceforge.net/gallery/three.asy,,.asy}}.
+Implicit casts are automatically attempted on assignment and when
+trying to match function calls with possible function
+signatures. Implicit casting can be inhibited by declaring individual
+arguments @code{explicit} in the function signature, say to avoid an
+ambiguous function call in the following example, which outputs 0:
+@verbatim
+int f(pair a) {return 0;}
+int f(explicit real x) {return 1;}
+
+write(f(0));
+@end verbatim
+
+@cindex explicit casts
+Other conversions, say @code{real} to @code{int} or
+@code{real} to @code{string}, require an explicit cast:
+@verbatim
+int i=(int) 2.5;
+string s=(string) 2.5;
+
+real[] a={2.5,-3.5};
+int[] b=(int []) a;
+write(stdout,b); // Outputs 2,-3
+@end verbatim
+In situations where casting from a string to a type @code{T} fails,
+an uninitialized variable is returned; this condition can be detected
+with the function @code{bool initialized(T);}
+@verbatim
+int i=(int) "2.5";
+assert(initialized(i),"Invalid cast.");
+
+real x=(real) "2.5a";
+assert(initialized(x),"Invalid cast.");
+@end verbatim
+
+@cindex @code{operator cast}
+Casting to user-defined types is also possible using @code{operator cast}:
+@verbatim
+struct rpair {
+ real radius;
+ real angle;
+}
+
+pair operator cast(rpair x) {
+ return (x.radius*cos(x.angle),x.radius*sin(x.angle));
+}
+
+rpair x;
+x.radius=1;
+x.angle=pi/6;
+
+write(x); // Outputs (0.866025403784439,0.5)
+@end verbatim
+
+One must use care when defining new cast operators. Suppose that in some
+code one wants all integers to represent multiples of 100. To convert them
+to reals, one would first want to multiply them by 100. However, the
+straightforward implementation
+@verbatim
+real operator cast(int x) {return x*100;}
+@end verbatim
+@noindent
+is equivalent to an infinite recursion, since the result @code{x*100}
+needs itself to be cast from an integer to a real. Instead, we want to
+use the standard conversion of int to real:
+@verbatim
+real convert(int x) {return x*100;}
+real operator cast(int x)=convert;
+@end verbatim
+
+@cindex @code{operator ecast}
+Explicit casts are implemented similarly, with @code{operator ecast}.
+
+@node Import, Static, Casts, Programming
+@section Import
+@cindex @code{access}
+While @code{Asymptote} provides many features by default,
+some applications require specialized features contained in
+external @code{Asymptote} modules. For instance, the lines
+@verbatim
+access graph;
+graph.axes();
+@end verbatim
+@noindent
+draw @math{x} and @math{y} axes on a two-dimensional graph. Here, the
+command looks up the module under the name @code{graph} in a global dictionary
+of modules and puts it in a new variable named @code{graph}.
+The module is a structure, and we can refer to its fields as we usually
+would with a structure.
+
+@cindex @code{from}
+Often, one wants to use module functions without having to specify
+the module name. The code
+@verbatim
+from graph access axes;
+@end verbatim
+@noindent
+adds the @code{axes} field of @code{graph} into the local name space,
+so that subsequently, one can just write @code{axes()}. If the given name
+is overloaded, all types and variables of that name are added. To add
+more than one name, just use a comma-separated list:
+@verbatim
+from graph access axes, xaxis, yaxis;
+@end verbatim
+@noindent
+Wild card notation can be used to add all non-private fields and types of a
+module to the local name space:
+
+@verbatim
+from graph access *;
+@end verbatim
+
+@cindex @code{unravel}
+Similarly, one can add the non-private fields and types of a structure
+to the local environment with the @code{unravel} keyword:
+@verbatim
+struct matrix {
+ real a,b,c,d;
+}
+
+real det(matrix m) {
+ unravel m;
+ return a*d-b*c;
+}
+@end verbatim
+Alternatively, one can unravel selective fields:
+@verbatim
+real det(matrix m) {
+ from m unravel a,b,c as C,d;
+ return a*d-b*C;
+}
+@end verbatim
+
+@cindex @code{import}
+The command
+@verbatim
+import graph;
+@end verbatim
+is a convenient abbreviation for the commands
+@verbatim
+access graph;
+unravel graph;
+@end verbatim
+That is, @code{import graph} first loads a module into a structure called
+@code{graph} and then adds its non-private fields and types to the
+local environment. This way, if a member variable (or function) is
+overwritten with a local variable (or function of the same signature),
+the original one can still be accessed by qualifying it with the
+module name.
+
+Wild card importing will work fine in most cases, but one does not usually know
+all of the internal types and variables of a module, which can also
+change as the module writer adds or changes features of the module.
+As such, it is prudent to add @code{import} commands at the start of an
+@code{Asymptote} file, so that imported names won't shadow locally
+defined functions. Still, imported names may shadow other imported
+names, depending on the order in which they were imported, and
+imported functions may cause overloading resolution problems if they
+have the same name as local functions defined later.
+
+@cindex @code{as}
+To rename modules or fields when adding them to the local environment, use
+@code{as}:
+@verbatim
+access graph as graph2d;
+from graph access xaxis as xline, yaxis as yline;
+@end verbatim
+
+The command
+@verbatim
+import graph as graph2d;
+@end verbatim
+is a convenient abbreviation for the commands
+@verbatim
+access graph as graph2d;
+unravel graph2d;
+@end verbatim
+
+Except for a few built-in modules, such as @code{settings}, all modules
+are implemented as @code{Asymptote} files. When looking up a module
+that has not yet been loaded, @code{Asymptote} searches the standard
+search paths (@pxref{Search paths}) for the matching file. The file
+corresponding to that name is read and the code within it is interpreted
+as the body of a structure defining the module.
+
+If the file name contains
+nonalphanumeric characters, enclose it with quotation marks:
+
+@noindent
+@code{access "@value{Datadir}/asymptote/graph.asy" as graph;}
+
+@noindent
+@code{from "@value{Datadir}/asymptote/graph.asy" access axes;}
+
+@noindent
+@code{import "@value{Datadir}/asymptote/graph.asy" as graph;}
+
+It is an error if modules import themselves (or each other in a cycle).
+The module name to be imported must be known at compile time.
+
+@cindex runtime imports
+@cindex @code{eval}
+However, you can import an @code{Asymptote} module determined by the
+string @code{s} at runtime like this:
+@verbatim
+eval("import "+s,true);
+@end verbatim
+
+@cindex @code{asy}
+To conditionally execute an array of asy files, use
+@verbatim
+void asy(string format, bool overwrite ... string[] s);
+@end verbatim
+The file will only be processed, using output format @code{format}, if
+overwrite is @code{true} or the output file is missing.
+
+One can evaluate an @code{Asymptote} expression (without any return
+value, however) contained in the string @code{s} with:
+@cindex @code{eval}
+@verbatim
+void eval(string s, bool embedded=false);
+@end verbatim
+It is not necessary to terminate the string @code{s} with a semicolon.
+If @code{embedded} is @code{true}, the string will be evaluated
+at the top level of the current environment.
+If @code{embedded} is @code{false} (the default), the string
+will be evaluated in an independent environment, sharing the same
+@code{settings} module (@pxref{settings}).
+
+@cindex @code{quote}
+One can evaluate arbitrary @code{Asymptote} code (which may
+contain unescaped quotation marks) with the command
+@verbatim
+void eval(code s, bool embedded=false);
+@end verbatim
+Here @code{code} is a special type used with @code{quote @{@}}
+to enclose @code{Asymptote code} like this:
+@verbatim
+real a=1;
+code s=quote {
+ write(a);
+};
+eval(s,true); // Outputs 1
+@end verbatim
+
+@cindex @code{include}
+To include the contents of an existing file @code{graph} verbatim (as if the
+contents of the file were inserted at that point), use one of the forms:
+@verbatim
+include graph;
+@end verbatim
+
+@noindent
+@code{include "@value{Datadir}/asymptote/graph.asy";}
+
+To list all global functions and variables defined in a module named
+by the contents of the string @code{s}, use the function
+@verbatim
+void list(string s, bool imports=false);
+@end verbatim
+@noindent
+Imported global functions and variables are also listed if
+@code{imports} is @code{true}.
+
+@node Static, , Import, Programming
+@section Static
+@cindex @code{static}
+
+Static qualifiers allocate the memory address of a variable in a higher
+enclosing level.
+
+For a function body, the variable is allocated in the block where the
+function is defined; so in the code
+@verbatim
+struct s {
+ int count() {
+ static int c=0;
+ ++c;
+ return c;
+ }
+}
+@end verbatim
+
+@noindent
+there is one instance of the variable @code{c} for each
+object @code{s} (as opposed to each call of @code{count}).
+
+Similarly, in
+@verbatim
+int factorial(int n) {
+ int helper(int k) {
+ static int x=1;
+ x *= k;
+ return k == 1 ? x : helper(k-1);
+ }
+ return helper(n);
+}
+@end verbatim
+
+@noindent
+there is one instance of @code{x} for every call to
+@code{factorial} (and not for every call to @code{helper}), so this is
+a correct, but ugly, implementation of factorial.
+
+Similarly, a static variable declared within a structure is allocated in
+the block where the structure is defined. Thus,
+@verbatim
+struct A {
+ struct B {
+ static pair z;
+ }
+}
+@end verbatim
+
+@noindent
+creates one object @code{z} for each object of type @code{A} created.
+
+In this example,
+@verbatim
+int pow(int n, int k) {
+ struct A {
+ static int x=1;
+ void helper() {
+ x *= n;
+ }
+ }
+ for(int i=0; i < k; ++i) {
+ A a;
+ a.helper();
+ }
+ return A.x;
+}
+@end verbatim
+
+@noindent
+there is one instance of @code{x} for each call to @code{pow}, so this
+is an ugly implementation of exponentiation.
+
+Loop constructs allocate a new frame in every iteration. This is so that
+higher-order functions can refer to variables of a specific iteration of a
+loop:
+@verbatim
+void f();
+for(int i=0; i < 10; ++i) {
+ int x=i;
+ if(x==5) {
+ f=new void () { write(x); }
+ }
+}
+f();
+@end verbatim
+
+Here, every iteration of the loop has its own variable @code{x}, so @code{f()}
+will write @code{5}. If a variable in a loop is declared static, it will be
+allocated where the enclosing function or structure was defined (just as if it
+were declared static outside of the loop). For instance, in:
+@verbatim
+void f() {
+ static int x;
+ for(int i=0; i < 10; ++i) {
+ static int y;
+ }
+}
+@end verbatim
+@noindent
+both @code{x} and @code{y} will be allocated in the same place, which is
+also where @code{f} is also allocated.
+
+Statements may also be declared static, in which case they are run at the place
+where the enclosing function or structure is defined.
+Declarations or statements not enclosed in a function or structure definition
+are already at the top level, so static modifiers are meaningless. A warning is
+given in such a case.
+
+Since structures can have static fields, it is not always clear for a qualified
+name whether the qualifier is a variable or a type. For instance, in:
+
+@verbatim
+struct A {
+ static int x;
+}
+pair A;
+
+int y=A.x;
+@end verbatim
+@noindent
+does the @code{A} in @code{A.x} refer to the structure or to the pair variable.
+It is the convention in Asymptote that, if there is a non-function variable with
+the same name as the qualifier, the qualifier refers to that variable, and not
+to the type. This is regardless of what fields the variable actually possesses.
+
+@node LaTeX usage, Base modules, Programming, Top
+@chapter @code{LaTeX} usage
+@cindex @code{LaTeX} usage
+@cindex @code{asymptote.sty}
+
+@code{Asymptote} comes with a convenient @code{LaTeX} style file
+@code{asymptote.sty} (v1.33 or later required) that makes @code{LaTeX}
+@code{Asymptote}-aware. Entering @code{Asymptote} code
+directly into the @code{LaTeX} source file, at the point where it is
+needed, keeps figures organized and avoids the need to invent new file
+names for each figure. Simply add the line
+@code{\usepackage@{asymptote@}} at the beginning of your file
+and enclose your @code{Asymptote} code within a
+@code{\begin@{asy@}...\end@{asy@}} environment. As with the
+@code{LaTeX} @code{comment} environment, the @code{\end@{asy@}} command
+must appear on a line by itself, with no trailing commands/comments.
+A blank line is not allowed after @code{\begin@{asy@}}.
+
+The sample @code{LaTeX} file below, named @code{latexusage.tex}, can
+be run as follows:
+@verbatim
+latex latexusage
+asy latexusage-*.asy
+latex latexusage
+@end verbatim
+
+@noindent
+or
+@verbatim
+pdflatex latexusage
+asy latexusage-*.asy
+pdflatex latexusage
+@end verbatim
+@noindent
+To switch between using inline Asymptote code with @code{latex} and
+@code{pdflatex} you may first need to remove the files @code{latexusage-*.tex}.
+
+@cindex @code{latexmk}
+@cindex @code{perl}
+An even better method for processing a @code{LaTeX} file with embedded
+@code{Asymptote} code is to use the @code{latexmk} utility from
+@quotation
+@url{http://mirror.ctan.org/support/latexmk/}
+@end quotation
+@noindent
+after putting the contents of
+@url{https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/latexmkrc}
+@noindent
+in a file @code{latexmkrc} in the same directory. The command
+@verbatim
+latexmk -pdf latexusage
+@end verbatim
+@noindent
+will then call @code{Asymptote} automatically, recompiling only the figures
+that have changed. Since each figure is compiled in a separate
+system process, this method also tends to use less memory.
+To store the figures in a separate directory named @code{asy}, one can define
+@verbatim
+\def\asydir{asy}
+@end verbatim
+in @code{latexusage.tex} and put the contents of
+@url{http://sourceforge.net/p/asymptote/code/HEAD/tree/trunk/asymptote/doc/latexmkrc_asydir}
+in a file @code{latexmkrc} in the same directory.
+@noindent
+External @code{Asymptote} code in @code{@uref{http://asymptote.sourceforge.net/gallery/filename.pdf,,filename}@uref{http://asymptote.sourceforge.net/gallery/filename.asy,,.asy}} should be included with
+@cindex @code{asyinclude}
+@verbatim
+\asyinclude[<options>]{<filename.asy>}
+@end verbatim
+@noindent
+so that @code{latexmk} will recognize when the code is changed. Note that
+@code{latemk} requires @code{perl}, available from @url{http://www.perl.org/}.
+
+@cindex @code{width}
+@cindex @code{height}
+@cindex @code{keepAspect}
+@cindex @code{viewportwidth}
+@cindex @code{viewportheight}
+@cindex @code{attach}
+@cindex @code{inline}
+One can specify @code{width}, @code{height}, @code{keepAspect},
+@code{viewportwidth}, @code{viewportheight}, @code{attach}, and @code{inline}.
+@code{keyval}-style options to the @code{asy} and @code{asyinclude}
+environments.
+Three-dimensional @acronym{PRC} files may either be embedded within
+the page (the default) or attached as annotated (but printable)
+attachments, using the @code{attach} option and the @code{attachfile2}
+(or older @code{attachfile}) @code{LaTeX} package.
+The @code{inline} option generates
+inline @code{LaTeX} code instead of @acronym{EPS} or @acronym{PDF}
+files. This makes 2D LaTeX symbols visible to the
+@code{\begin@{asy@}...\end@{asy@}} environment. In this mode,
+Asymptote correctly aligns 2D LaTeX symbols defined outside of
+@code{\begin@{asy@}...\end@{asy@}}, but treats their size as zero; an
+optional second string can be given to @code{Label} to provide an
+estimate of the unknown label size.
+
+Note that if the @code{latex} @TeX{} engine is used with the
+@code{inline} option, labels might not show up in @acronym{DVI}
+viewers that cannot handle raw @code{PostScript} code. One can use
+@code{dvips}/@code{dvipdf} to produce @code{PostScript}/@acronym{PDF}
+output (we recommend using the modified version of @code{dvipdf} in
+the @code{Asymptote} patches directory, which accepts the @code{dvips -z}
+hyperdvi option).
+
+Here now is @code{latexusage.tex}:
+@verbatiminclude latexusage.tex
+@page
+@image{latexusage,,25cm}
+
+@node Base modules, Options, LaTeX usage, Top
+@chapter Base modules
+@cindex base modules
+
+@code{Asymptote} currently ships with the following base modules:
+
+@menu
+* plain:: Default @code{Asymptote} base file
+* simplex:: Linear programming: simplex method
+* math:: Extend @code{Asymptote}'s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded @acronym{PDF} and @acronym{MPEG} movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with @code{Asymptote}
+* MetaPost:: @code{MetaPost} compatibility routines
+* unicode:: Accept @code{unicode} (UTF-8) characters
+* latin1:: Accept @code{ISO 8859-1} characters
+* babel:: Interface to @code{LaTeX} @code{babel} package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your @acronym{PDF} files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* smoothcontour3:: Smooth implicit surfaces
+* slopefield:: Slope fields
+* ode:: Ordinary differential equations
+@end menu
+
+@node plain, simplex, Base modules, Base modules
+@section @code{plain}
+@cindex @code{plain}
+
+This is the default @code{Asymptote} base file, which defines key parts of the
+drawing language (such as the @code{picture} structure).
+
+By default, an implicit @code{private import plain;} occurs before
+translating a file and before the first command given in interactive
+mode. This also applies when translating files for module definitions
+(except when translating @code{plain}, of course). This means that
+the types and functions defined in @code{plain} are accessible in
+almost all @code{Asymptote} code. Use the @code{-noautoplain} command-line
+option to disable this feature.
+
+@node simplex, math, plain, Base modules
+@section @code{simplex}
+@cindex @code{simplex}
+@cindex @code{deferred drawing}
+This package solves the two-variable linear programming problem using the
+simplex method. It is used by the module @code{plain} for automatic
+sizing of pictures.
+
+@node math, interpolate, simplex, Base modules
+@section @code{math}
+@cindex @code{math}
+This package extends @code{Asymptote}'s mathematical capabilities with
+useful functions such as
+
+@table @code
+
+@cindex @code{drawline}
+@item void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen);
+draw the visible portion of the (infinite) line going through
+@code{P} and @code{Q}, without altering the size of picture @code{pic},
+using pen @code{p}.
+
+@cindex @code{intersect}
+@item real intersect(triple P, triple Q, triple n, triple Z);
+returns the intersection time of the extension of the line segment @code{PQ}
+with the plane perpendicular to @code{n} and passing through @code{Z}.
+
+@cindex @code{intersectionpoint}
+@item triple intersectionpoint(triple n0, triple P0, triple n1, triple P1);
+Return any point on the intersection of the two planes with normals
+@code{n0} and @code{n1} passing through points @code{P0} and @code{P1},
+respectively. If the planes are parallel, return
+@code{(infinity,infinity,infinity)}.
+
+@cindex @code{quarticroots}
+@item pair[] quarticroots(real a, real b, real c, real d, real e);
+returns the four complex roots of the quartic equation
+@math{ax^4+bx^3+cx^2+dx+e=0}.
+
+@cindex @code{fft}
+@item pair[][] fft(pair[][] a, int sign=1)
+returns the two-dimensional Fourier transform of a using the given
+@code{sign}.
+
+@cindex @code{time}
+@item real time(path g, real x, int n=0)
+returns the @code{n}th intersection time of path @code{g} with the vertical
+line through x.
+
+@cindex @code{time}
+@item real time(path g, explicit pair z, int n=0)
+returns the @code{n}th intersection time of path @code{g} with the horizontal
+line through @code{(0,z.y)}.
+
+@cindex @code{value}
+@item real value(path g, real x, int n=0)
+returns the @code{n}th @code{y} value of @code{g} at @code{x}.
+
+@cindex @code{value}
+@item real value(path g, explicit pair z, int n=0)
+returns the @code{n}th @code{x} value of @code{g} at @code{y=z.y}.
+
+@cindex @code{slope}
+@item real slope(path g, real x, int n=0)
+returns the @code{n}th slope of @code{g} at @code{x}.
+
+@cindex @code{slope}
+@item real slope(path g, explicit pair z, int n=0)
+returns the @code{n}th slope of @code{g} at @code{y=z.y}.
+
+@cindex @code{segment}
+int[][] segment(bool[] b)
+returns the indices of consecutive true-element segments of bool[] @code{b}.
+
+@cindex @code{partialsum}
+@item real[] partialsum(real[] a)
+returns the partial sums of a real array @code{a}.
+
+@cindex @code{partialsum}
+@item real[] partialsum(real[] a, real[] dx)
+returns the partial @code{dx}-weighted sums of a real array @code{a}.
+
+@cindex @code{increasing}
+@item bool increasing(real[] a, bool strict=false)
+returns, if @code{strict=false}, whether @code{i > j} implies
+@code{a[i] >= a[j]}, or if @code{strict=true}, whether @code{i > j} implies
+implies @code{a[i] > a[j]}.
+
+@cindex @code{unique}
+@item int unique(real[] a, real x)
+if the sorted array @code{a} does not contain @code{x}, insert it
+sequentially, returning the index of @code{x} in the resulting array.
+
+@cindex @code{lexorder}
+@item bool lexorder(pair a, pair b)
+returns the strict lexicographical partial order of @code{a} and @code{b}.
+
+@cindex @code{lexorder}
+@item bool lexorder(triple a, triple b)
+returns the strict lexicographical partial order of @code{a} and @code{b}.
+@end table
+
+@node interpolate, geometry, math, Base modules
+@section @code{interpolate}
+@cindex @code{interpolate}
+This module implements Lagrange, Hermite, and standard cubic spline
+interpolation in @code{Asymptote}, as illustrated in the example
+@code{@uref{http://asymptote.sourceforge.net/gallery/interpolate1.pdf,,interpolate1}@uref{http://asymptote.sourceforge.net/gallery/interpolate1.asy,,.asy}}.
+
+@node geometry, trembling, interpolate, Base modules
+@section @code{geometry}
+@cindex @code{geometry}
+@cindex @code{triangle}
+@cindex @code{perpendicular}
+This module, written by Philippe Ivaldi, provides an extensive set of
+geometry routines, including @code{perpendicular} symbols and a @code{triangle}
+structure. Link to the documentation for the @code{geometry} module
+are posted here:
+@url{http://asymptote.sourceforge.net/links.html},
+including an extensive set of examples,
+@url{http://www.piprime.fr/files/asymptote/geometry/}, and an index:
+@quotation
+@url{http://www.piprime.fr/files/asymptote/geometry/modules/geometry.asy.index.type.html}
+@end quotation
+
+@node trembling, stats, geometry, Base modules
+@section @code{trembling}
+@cindex @code{trembling}
+This module, written by Philippe Ivaldi and illustrated in the example
+@code{@uref{http://asymptote.sourceforge.net/gallery/floatingdisk.pdf,,floatingdisk}@uref{http://asymptote.sourceforge.net/gallery/floatingdisk.asy,,.asy}}, allows one to draw wavy lines, as if drawn by
+hand.
+
+@node stats, patterns, trembling, Base modules
+@section @code{stats}
+@cindex @code{stats}
+@cindex @code{leastsquares}
+This package implements a Gaussian random number generator
+and a collection of statistics routines, including @code{histogram}
+and @code{leastsquares}.
+
+@node patterns, markers, stats, Base modules
+@section @code{patterns}
+@cindex @code{patterns}
+This package implements @code{Postscript} tiling patterns and includes
+several convenient pattern generation routines.
+
+@node markers, tree, patterns, Base modules
+@section @code{markers}
+@cindex @code{markers}
+This package implements specialized routines for marking paths and angles.
+The principal mark routine provided by this package is
+@verbatim
+markroutine markinterval(int n=1, frame f, bool rotated=false);
+@end verbatim
+@noindent
+which centers @code{n} copies of frame @code{f} within uniformly space
+intervals in arclength along the path, optionally rotated by the angle of the
+local tangent.
+
+The @code{marker} (@pxref{marker}) routine can be used to construct new
+markers from these predefined frames:
+
+@cindex @code{stickframe}
+@verbatim
+frame stickframe(int n=1, real size=0, pair space=0, real angle=0,
+ pair offset=0, pen p=currentpen);
+@end verbatim
+@cindex @code{circlebarframe}
+@verbatim
+frame circlebarframe(int n=1, real barsize=0,
+ real radius=0,real angle=0,
+ pair offset=0, pen p=currentpen,
+ filltype filltype=NoFill, bool above=false);
+@end verbatim
+@cindex @code{crossframe}
+@verbatim
+frame crossframe(int n=3, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+@end verbatim
+@cindex @code{tildeframe}
+@verbatim
+frame tildeframe(int n=1, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+@end verbatim
+
+For convenience, this module also constructs the markers
+@code{StickIntervalMarker}, @code{CrossIntervalMarker},
+@code{CircleBarIntervalMarker}, and @code{TildeIntervalMarker}
+from the above frames. The example @code{@uref{http://asymptote.sourceforge.net/gallery/markers1.pdf,,markers1}@uref{http://asymptote.sourceforge.net/gallery/markers1.asy,,.asy}} illustrates the
+use of these markers:
+
+@sp 1
+@center @image{markers1}
+
+This package also provides a routine for marking an angle @math{AOB}:
+@cindex @code{markangle}
+@verbatim
+void markangle(picture pic=currentpicture, Label L="",
+ int n=1, real radius=0, real space=0,
+ pair A, pair O, pair B, arrowbar arrow=None,
+ pen p=currentpen, margin margin=NoMargin,
+ marker marker=nomarker);
+@end verbatim
+@noindent
+as illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/markers2.pdf,,markers2}@uref{http://asymptote.sourceforge.net/gallery/markers2.asy,,.asy}}.
+
+@sp 1
+@center @image{markers2}
+
+@node tree, binarytree, markers, Base modules
+@section @code{tree}
+@cindex @code{tree}
+This package implements an example of a dynamic binary search tree.
+
+@node binarytree, drawtree, tree, Base modules
+@section @code{binarytree}
+@cindex @code{binarytree}
+This module can be used to draw an arbitrary binary tree and includes an
+input routine for the special case of a binary search tree, as
+illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/binarytreetest.pdf,,binarytreetest}@uref{http://asymptote.sourceforge.net/gallery/binarytreetest.asy,,.asy}}:
+@verbatiminclude binarytreetest.asy
+@sp 1
+@center @image{binarytreetest}
+
+@node drawtree, syzygy, binarytree, Base modules
+@section @code{drawtree}
+@cindex @code{drawtree}
+This is a simple tree drawing module used by the example @code{@uref{http://asymptote.sourceforge.net/gallery/treetest.pdf,,treetest}@uref{http://asymptote.sourceforge.net/gallery/treetest.asy,,.asy}}.
+
+@node syzygy, feynman, drawtree, Base modules
+@section @code{syzygy}
+@cindex @code{syzygy}
+This module automates the drawing of braids, relations, and syzygies,
+along with the corresponding equations, as illustrated in the example
+@code{@uref{http://asymptote.sourceforge.net/gallery/knots.pdf,,knots}@uref{http://asymptote.sourceforge.net/gallery/knots.asy,,.asy}}.
+
+@node feynman, roundedpath, syzygy, Base modules
+@section @code{feynman}
+@cindex @code{feynman}
+This package, contributed by Martin Wiebusch, is useful for drawing
+Feynman diagrams, as illustrated by the examples @code{@uref{http://asymptote.sourceforge.net/gallery/eetomumu.pdf,,eetomumu}@uref{http://asymptote.sourceforge.net/gallery/eetomumu.asy,,.asy}}
+and @code{@uref{http://asymptote.sourceforge.net/gallery/fermi.pdf,,fermi}@uref{http://asymptote.sourceforge.net/gallery/fermi.asy,,.asy}}.
+
+@node roundedpath, animation, feynman, Base modules
+@section @code{roundedpath}
+@cindex @code{roundedpath}
+This package, contributed by Stefan Knorr, is useful for rounding the
+sharp corners of paths, as illustrated in the example file @code{@uref{http://asymptote.sourceforge.net/gallery/roundpath.pdf,,roundpath}@uref{http://asymptote.sourceforge.net/gallery/roundpath.asy,,.asy}}.
+
+@node animation, embed, roundedpath, Base modules
+@section @code{animation}
+@cindex @code{animation}
+@cindex @code{convert}
+@cindex animation
+@cindex @code{ImageMagick}
+This module allows one to generate animations, as illustrated by the
+files @code{@uref{http://asymptote.sourceforge.net/gallery/animations/wheel.pdf,,wheel}@uref{http://asymptote.sourceforge.net/gallery/animations/wheel.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/animations/wavepacket.pdf,,wavepacket}@uref{http://asymptote.sourceforge.net/gallery/animations/wavepacket.asy,,.asy}}, and @code{@uref{http://asymptote.sourceforge.net/gallery/animations/cube.pdf,,cube}@uref{http://asymptote.sourceforge.net/gallery/animations/cube.asy,,.asy}} in
+the @code{animations} subdirectory of the examples directory. These
+animations use the @code{ImageMagick} @code{convert} program to
+merge multiple images into a @acronym{GIF} or @acronym{MPEG}
+movie.
+
+@cindex @code{animate}
+@anchor{animate}
+The related @code{animate} module, derived from the @code{animation}
+module, generates higher-quality portable clickable @acronym{PDF} movies, with
+optional controls. This requires installing the package
+@quotation
+@url{http://mirror.ctan.org/macros/latex/contrib/animate/animate.sty}
+@noindent
+@end quotation
+@noindent
+(version 2007/11/30 or later) in a new directory @code{animate} in the
+local @code{LaTeX} directory (for example, in
+@code{/usr/local/share/texmf/tex/latex/animate}). On @code{UNIX} systems,
+one must then execute the command @code{texhash}.
+
+The example @code{@uref{http://asymptote.sourceforge.net/gallery/animations/pdfmovie.pdf,,pdfmovie}@uref{http://asymptote.sourceforge.net/gallery/animations/pdfmovie.asy,,.asy}} in the @code{animations}
+directory, along with the slide presentations @code{@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.pdf,,slidemovies}@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.asy,,.asy}}
+and @code{@uref{http://asymptote.sourceforge.net/gallery/intro.pdf,,intro}@uref{http://asymptote.sourceforge.net/gallery/intro.asy,,.asy}}, illustrate the use of embedded @acronym{PDF} movies.
+The examples @code{inlinemovie.tex} and @code{inlinemovie3.tex}
+show how to generate and embed @acronym{PDF} movies directly within a
+@code{LaTeX} file (@pxref{LaTeX usage}).
+The member function
+@verbatim
+string pdf(fit fit=NoBox, real delay=animationdelay, string options="",
+ bool keep=settings.keep, bool multipage=true);
+@end verbatim
+@noindent
+of the @code{animate} structure accepts any of the @code{animate.sty} options,
+as described here:
+@quotation
+@url{http://mirror.ctan.org/macros/latex/contrib/animate/doc/animate.pdf}
+@end quotation
+
+@node embed, slide, animation, Base modules
+@section @code{embed}
+@cindex @code{embed}
+This module provides an interface to the @code{LaTeX} package
+(included with @code{MikTeX})
+@quotation
+@url{http://mirror.ctan.org/macros/latex/contrib/media9}
+@end quotation
+@noindent
+for embedding movies, sounds, and 3D objects into a @acronym{PDF} document.
+
+@cindex @code{external}
+A more portable method for embedding movie files, which should work on any
+platform and does not require the @code{media9} package, is provided
+by using the @code{external} module instead of @code{embed}.
+
+Examples of the above two interfaces is provided in the file
+@code{@uref{http://asymptote.sourceforge.net/gallery/animations/embeddedmovie.pdf,,embeddedmovie}@uref{http://asymptote.sourceforge.net/gallery/animations/embeddedmovie.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/animations/externalmovie.pdf,,externalmovie}@uref{http://asymptote.sourceforge.net/gallery/animations/externalmovie.asy,,.asy}} in the
+@code{animations} subdirectory of the examples directory. For a higher
+quality embedded movie generated directly by @code{Asymptote}, use the
+@code{animate} module along with the @code{animate.sty} package to
+embed a portable @acronym{PDF} animation (@pxref{animate}).
+
+@cindex @code{U3D}
+An example of embedding @code{U3D} code is provided in the file
+@code{@uref{http://asymptote.sourceforge.net/gallery/animations/embeddedu3d.pdf,,embeddedu3d}@uref{http://asymptote.sourceforge.net/gallery/animations/embeddedu3d.asy,,.asy}}.
+
+@node slide, MetaPost, embed, Base modules
+@section @code{slide}
+@cindex @code{slide}
+This package provides a simple yet high-quality facility for making
+presentation slides, including portable embedded @acronym{PDF} animations (see
+the file @code{@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.pdf,,slidemovies}@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.asy,,.asy}}). A simple example is provided in the file
+@code{@uref{http://asymptote.sourceforge.net/gallery/animations/slidedemo.pdf,,slidedemo}@uref{http://asymptote.sourceforge.net/gallery/animations/slidedemo.asy,,.asy}}.
+
+@node MetaPost, unicode, slide, Base modules
+@section @code{MetaPost}
+@cindex @code{MetaPost}
+This package provides some useful routines to help @code{MetaPost} users
+migrate old @code{MetaPost} code to @code{Asymptote}. Further
+contributions here are welcome.
+
+@cindex @code{implicit linear solver}
+@cindex @code{MetaPost whatever}
+@cindex @code{extension}
+Unlike @code{MetaPost}, @code{Asymptote} does not implicitly solve
+linear equations and therefore does not have the notion of a
+@code{whatever} unknown. The routine @code{extension} (@pxref{extension})
+provides a useful replacement for a common use of @code{whatever}: finding the
+intersection point of the lines through @code{P}, @code{Q} and
+@code{p}, @code{q}. For less common occurrences of @code{whatever}, one
+can use the built-in explicit linear equation solver @code{solve} instead.
+
+@node unicode, latin1, MetaPost, Base modules
+@section @code{unicode}
+@cindex @code{unicode}
+@cindex international characters
+Import this package at the beginning of the file to instruct
+@code{LaTeX} to accept @code{unicode} (UTF-8) standardized international
+characters.
+@noindent
+@cindex Cyrillic
+@cindex Russian
+To use Cyrillic fonts, you will need to change the font encoding:
+@verbatim
+import unicode;
+texpreamble("\usepackage{mathtext}\usepackage[russian]{babel}");
+defaultpen(font("T2A","cmr","m","n"));
+@end verbatim
+@noindent
+@cindex Chinese
+@cindex Japanese
+@cindex Korean
+@cindex CJK
+Support for Chinese, Japanese, and Korean fonts is provided by the
+CJK package:
+@quotation
+@url{http://mirror.ctan.org/languages/chinese/CJK/}
+@end quotation
+@noindent
+The following commands enable the CJK song family (within a label, you
+can also temporarily switch to another family, say kai, by prepending
+@code{"\CJKfamily@{kai@}"} to the label string):
+@verbatim
+texpreamble("\usepackage{CJK}
+\AtBeginDocument{\begin{CJK*}{GBK}{song}}
+\AtEndDocument{\clearpage\end{CJK*}}");
+@end verbatim
+
+@node latin1, babel, unicode, Base modules
+@section @code{latin1}
+@cindex @code{latin1}
+If you don't have @code{LaTeX} support for @code{unicode} installed,
+you can enable support for Western European languages (ISO 8859-1) by
+importing the module @code{latin1}. This module can be used as a
+template for providing support for other ISO 8859 alphabets.
+
+@node babel, labelpath, latin1, Base modules
+@section @code{babel}
+@cindex @code{babel}
+This module implements the @code{LaTeX} @code{babel} package in
+@code{Asymptote}. For example:
+@verbatim
+import babel;
+babel("german");
+@end verbatim
+
+@node labelpath, labelpath3, babel, Base modules
+@section @code{labelpath}
+@cindex @code{labelpath}
+This module uses the @code{PSTricks} @code{pstextpath} macro to fit labels
+along a path (properly kerned, as illustrated in the example file
+@code{@uref{http://asymptote.sourceforge.net/gallery/curvedlabel.pdf,,curvedlabel}@uref{http://asymptote.sourceforge.net/gallery/curvedlabel.asy,,.asy}}), using the command
+@verbatim
+void labelpath(picture pic=currentpicture, Label L, path g,
+ string justify=Centered, pen p=currentpen);
+@end verbatim
+@noindent
+Here @code{justify} is one of @code{LeftJustified}, @code{Centered}, or
+@code{RightJustified}. The @math{x} component of a shift transform
+applied to the Label is interpreted as a shift along the curve, whereas
+the @math{y} component is interpreted as a shift away from the curve.
+All other Label transforms are ignored. This package requires the
+@code{latex} tex engine and inherits the limitations of the
+@code{PSTricks} @code{\pstextpath} macro.
+
+@node labelpath3, annotate, labelpath, Base modules
+@section @code{labelpath3}
+@cindex @code{labelpath3}
+This module, contributed by Jens Schwaiger, implements a 3D version of
+@code{labelpath} that does not require the @code{PSTricks} package.
+An example is provided in @code{@uref{http://asymptote.sourceforge.net/gallery/curvedlabel3.pdf,,curvedlabel3}@uref{http://asymptote.sourceforge.net/gallery/curvedlabel3.asy,,.asy}}.
+
+@node annotate, CAD, labelpath3, Base modules
+@section @code{annotate}
+@cindex @code{annotate}
+This module supports @acronym{PDF} annotations for viewing with
+@code{Adobe Reader}, via the function
+@verbatim
+void annotate(picture pic=currentpicture, string title, string text,
+ pair position);
+@end verbatim
+@noindent
+Annotations are illustrated in the example file @code{@uref{http://asymptote.sourceforge.net/gallery/annotation.pdf,,annotation}@uref{http://asymptote.sourceforge.net/gallery/annotation.asy,,.asy}}.
+Currently, annotations are only implemented for the @code{latex}
+(default) and @code{tex} @TeX{} engines.
+
+@node CAD, graph, annotate, Base modules
+@section @code{CAD}
+@cindex @code{CAD}
+This package, contributed by Mark Henning, provides basic pen
+definitions and measurement functions for simple 2D CAD drawings
+according to DIN 15. It is documented separately, in the file
+@code{CAD.pdf}.
+
+@node graph, palette, CAD, Base modules
+@section @code{graph}
+@cindex @code{graph}
+@cindex 2D graphs
+This package implements two-dimensional linear and logarithmic graphs,
+including automatic scale and tick selection (with the ability to
+override manually). A graph is a @code{guide} (that can be drawn with
+the draw command, with an optional legend) constructed with one of
+the following routines:
+
+@itemize
+@item
+@verbatim
+guide graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+(@pxref{automatic scaling}) of the function @code{f} on the interval
+[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points
+evenly spaced in [@code{a},@code{b}], optionally restricted by the
+bool3 function @code{cond} on [@code{a},@code{b}]. If @code{cond} is:
+@itemize @bullet
+@item @code{true}, the point is added to the existing guide;
+@item @code{default}, the point is added to a new guide;
+@item @code{false}, the point is omitted and a new guide is begun.
+@end itemize
+The points are connected using the interpolation specified by @code{join}:
+@itemize @bullet
+
+@cindex @code{operator --}
+@cindex @code{Straight}
+@item @code{operator --} (linear interpolation; the abbreviation
+@code{Straight} is also accepted);
+
+@cindex @code{operator ..}
+@cindex @code{Spline}
+@item @code{operator ..} (piecewise Bezier cubic spline interpolation;
+the abbreviation @code{Spline} is also accepted);
+
+@cindex @code{Hermite}
+@cindex @code{notaknot}
+@cindex @code{natural}
+@cindex @code{periodic}
+@cindex @code{clamped}
+@cindex @code{monotonic}
+@cindex @code{Hermite(splinetype splinetype}
+@item @code{Hermite} (standard cubic spline interpolation using boundary
+condition @code{notaknot}, @code{natural}, @code{periodic},
+@code{clamped(real slopea, real slopeb)}), or @code{monotonic}.
+The abbreviation @code{Hermite} is equivalent to
+@code{Hermite(notaknot)} for nonperiodic data and
+@code{Hermite(periodic)} for periodic data).
+
+@end itemize
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ bool3 cond(real), interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the parametrized function
+(@code{x}(@math{t}),@code{y}(@math{t})) for @math{t} in the interval
+[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points
+evenly spaced in [@code{a},@code{b}], optionally restricted by the
+bool3 function @code{cond} on [@code{a},@code{b}], using the given
+interpolation type.
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the parametrized function
+@code{z}(@math{t}) for @math{t} in the interval
+[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points
+evenly spaced in [@code{a},@code{b}], optionally restricted by the
+bool3 function @code{cond} on [@code{a},@code{b}], using the given
+interpolation type.
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, pair[] z,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond,
+ interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the elements of the array @code{z}, optionally restricted to
+those indices for which the elements of the boolean array @code{cond} are
+@code{true}, using the given interpolation type.
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, real[] x, real[] y,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, real[] x, real[] y,
+ bool3[] cond, interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the elements of the arrays (@code{x},@code{y}), optionally
+restricted to those indices for which the elements of the boolean
+array @code{cond} are @code{true}, using the given interpolation type.
+
+@item
+@cindex @code{polargraph}
+@verbatim
+guide polargraph(picture pic=currentpicture, real f(real), real a,
+ real b, int n=ngraph, interpolate join=operator --);
+@end verbatim
+
+Returns a polar-coordinate graph using the scaling information for
+picture @code{pic} of the function @code{f} on the interval
+[@code{a},@code{b}], sampling at @code{n} evenly spaced points, with
+the given interpolation type.
+
+@item
+@verbatim
+guide polargraph(picture pic=currentpicture, real[] r, real[] theta,
+ interpolate join=operator--);
+@end verbatim
+Returns a polar-coordinate graph using the scaling information for
+picture @code{pic} of the elements of the arrays (@code{r},@code{theta}),
+using the given interpolation type.
+
+@end itemize
+
+@verbatim
+
+
+@end verbatim
+
+An axis can be drawn on a picture with one of the following commands:
+
+@itemize
+
+@item
+@verbatim
+void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
+@end verbatim
+
+Draw an @math{x} axis on picture @code{pic} from @math{x}=@code{xmin} to
+@math{x}=@code{xmax} using pen @code{p}, optionally labelling it with
+Label @code{L}. The relative label location along the axis (a real number from
+[0,1]) defaults to 1 (@pxref{Label}), so that the label is drawn at the
+end of the axis. An infinite value of @code{xmin}
+or @code{xmax} specifies that the corresponding axis limit will be
+automatically determined from the picture limits.
+The optional @code{arrow} argument takes the same values as in the
+@code{draw} command (@pxref{arrows}). The axis is drawn before any
+existing objects in @code{pic} unless @code{above=true}.
+The axis placement is determined by one of the following @code{axis} types:
+
+@table @code
+
+@cindex @code{YZero}
+@item YZero(bool extend=true)
+Request an @math{x} axis at @math{y}=0 (or @math{y}=1 on a logarithmic axis)
+extending to the full dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{YEquals}
+@item YEquals(real Y, bool extend=true)
+Request an @math{x} axis at @math{y}=@code{Y} extending to the full
+dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{Bottom}
+@item Bottom(bool extend=false)
+Request a bottom axis.
+
+@cindex @code{Top}
+@item Top(bool extend=false)
+Request a top axis.
+
+@cindex @code{BottomTop}
+@item BottomTop(bool extend=false)
+Request a bottom and top axis.
+
+@end table
+
+@cindex custom axis types
+Custom axis types can be created by following the examples in the
+module @code{graph.asy}.
+One can easily override the default values for the standard axis types:
+@verbatim
+import graph;
+
+YZero=new axis(bool extend=true) {
+ return new void(picture pic, axisT axis) {
+ real y=pic.scale.x.scale.logarithmic ? 1 : 0;
+ axis.value=I*pic.scale.y.T(y);
+ axis.position=1;
+ axis.side=right;
+ axis.align=2.5E;
+ axis.value2=Infinity;
+ axis.extend=extend;
+ };
+};
+YZero=YZero();
+
+@end verbatim
+
+@anchor{ticks}
+@cindex @code{ticks}
+@cindex @code{NoTicks}
+@cindex @code{LeftTicks}
+@cindex @code{RightTicks}
+@cindex @code{Ticks}
+The default tick option is @code{NoTicks}.
+The options @code{LeftTicks}, @code{RightTicks}, or @code{Ticks} can be
+used to draw ticks on the left, right, or both sides of the path,
+relative to the direction in which the path is drawn.
+These tick routines accept a number of optional arguments:
+@verbatim
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen);
+@end verbatim
+
+If any of these parameters are omitted, reasonable defaults will
+be chosen:
+@table @code
+@item Label format
+@cindex @code{defaultformat}
+@cindex @code{trailingzero}
+override the default tick label format (@code{defaultformat}, initially
+"$%.4g$"), rotation, pen, and alignment (for example, @code{LeftSide},
+@code{Center}, or @code{RightSide}) relative to the axis. To enable
+@code{LaTeX} math mode fonts, the format string should begin and
+end with @code{$} @pxref{format}. If the format string is @code{trailingzero},
+trailing zeros will be added to the tick labels; if the format string is
+@code{"%"}, the tick label will be suppressed;
+@item ticklabel
+is a function @code{string(real x)} returning the label (by default,
+format(format.s,x)) for each major tick value @code{x};
+@item bool beginlabel
+include the first label;
+@item bool endlabel
+include the last label;
+@item int N
+when automatic scaling is enabled (the default; @pxref{automatic scaling}),
+divide a linear axis evenly into this many intervals, separated by major ticks;
+for a logarithmic axis, this is the number of decades between labelled ticks;
+@item int n
+divide each interval into this many subintervals, separated by minor ticks;
+@item real Step
+the tick value spacing between major ticks
+(if @code{N}=@code{0});
+@item real step
+the tick value spacing between minor ticks (if @code{n}=@code{0});
+@item bool begin
+include the first major tick;
+@item bool end
+include the last major tick;
+@item tickmodifier modify;
+an optional function that takes and returns a @code{tickvalue} structure having
+real[] members @code{major} and @code{minor} consisting of the tick values
+(to allow modification of the automatically generated tick values);
+@item real Size
+the size of the major ticks (in @code{PostScript} coordinates);
+@item real size
+the size of the minor ticks (in @code{PostScript} coordinates);
+@item bool extend;
+extend the ticks between two axes (useful for drawing a grid on the graph);
+@item pen pTick
+an optional pen used to draw the major ticks;
+@item pen ptick
+an optional pen used to draw the minor ticks.
+
+@end table
+
+@cindex @code{OmitTick}
+@cindex @code{OmitTickInterval}
+@cindex @code{OmitTickIntervals}
+For convenience, the predefined tickmodifiers @code{OmitTick(... real[] x)},
+@code{OmitTickInterval(real a, real b)}, and
+@code{OmitTickIntervals(real[] a, real[] b)}
+can be used to remove specific auto-generated ticks and
+their labels. The @code{OmitFormat(string s=defaultformat ... real[] x)}
+ticklabel can be used to remove specific tick labels but not the
+corresponding ticks. The tickmodifier @code{NoZero} is an abbreviation for
+@code{OmitTick(0)} and the ticklabel @code{NoZeroFormat} is an
+abbrevation for @code{OmitFormat(0)}.
+
+@cindex custom tick locations
+@cindex @code{LeftTicks}
+@cindex @code{RightTicks}
+@cindex @code{Ticks}
+It is also possible to specify custom tick locations with
+@code{LeftTicks}, @code{RightTicks}, and @code{Ticks} by passing explicit real
+arrays @code{Ticks} and (optionally) @code{ticks} containing the
+locations of the major and minor ticks, respectively:
+@verbatim
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+@end verbatim
+
+@item
+@verbatim
+void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false,
+ bool autorotate=true);
+@end verbatim
+
+Draw a @math{y} axis on picture @code{pic} from @math{y}=@code{ymin} to
+@math{y}=@code{ymax} using pen @code{p}, optionally labelling it with
+a Label @code{L} that is autorotated unless @code{autorotate=false}.
+The relative location of the label (a real number from
+[0,1]) defaults to 1 (@pxref{Label}). An infinite value of @code{ymin}
+or @code{ymax} specifies that the corresponding axis limit will be
+automatically determined from the picture limits.
+The optional @code{arrow} argument takes the same values as in the
+@code{draw} command (@pxref{arrows}). The axis is drawn before any
+existing objects in @code{pic} unless @code{above=true}.
+The tick type is specified by @code{ticks} and the axis placement is
+determined by one of the following @code{axis} types:
+
+@table @code
+
+@cindex @code{XZero}
+@item XZero(bool extend=true)
+Request a @math{y} axis at @math{x}=0 (or @math{x}=1 on a logarithmic axis)
+extending to the full dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{XEquals}
+@item XEquals(real X, bool extend=true)
+Request a @math{y} axis at @math{x}=@code{X} extending to the full
+dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{Left}
+@item Left(bool extend=false)
+Request a left axis.
+
+@cindex @code{Right}
+@item Right(bool extend=false)
+Request a right axis.
+
+@cindex @code{LeftRight}
+@item LeftRight(bool extend=false)
+Request a left and right axis.
+
+@end table
+
+@item
+@cindex @code{xequals}
+@cindex @code{yequals}
+For convenience, the functions
+@verbatim
+void xequals(picture pic=currentpicture, Label L="", real x,
+ bool extend=false, real ymin=-infinity, real ymax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+@end verbatim
+and
+@verbatim
+void yequals(picture pic=currentpicture, Label L="", real y,
+ bool extend=false, real xmin=-infinity, real xmax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+@end verbatim
+can be respectively used to call @code{yaxis} and
+@code{xaxis} with the appropriate axis types @code{XEquals(x,extend)} and
+@code{YEquals(y,extend)}. This is the recommended way of drawing vertical
+or horizontal lines and axes at arbitrary locations.
+
+@item
+@verbatim
+void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
+ bool extend=true,
+ pair min=(-infinity,-infinity), pair max=(infinity,infinity),
+ pen p=currentpen, arrowbar arrow=None, bool above=false);
+@end verbatim
+This convenience routine draws both @math{x} and @math{y} axes
+on picture @code{pic} from @code{min} to @code{max},
+with optional labels @code{xlabel} and @code{ylabel}
+and any arrows specified by @code{arrow}. The axes are drawn on top of
+existing objects in @code{pic} only if @code{above=true}.
+
+@item
+@verbatim
+void axis(picture pic=currentpicture, Label L="", path g,
+ pen p=currentpen, ticks ticks, ticklocate locate,
+ arrowbar arrow=None, int[] divisor=new int[],
+ bool above=false, bool opposite=false);
+@end verbatim
+
+This routine can be used to draw on picture @code{pic} a general axis
+based on an arbitrary path @code{g}, using pen @code{p}.
+One can optionally label the axis with Label @code{L} and add an arrow
+@code{arrow}. The tick type is given by @code{ticks}.
+The optional integer array @code{divisor} specifies what tick divisors
+to try in the attempt to produce uncrowded tick labels. A @code{true}
+value for the flag @code{opposite} identifies an unlabelled secondary
+axis (typically drawn opposite a primary axis). The axis is drawn before
+any existing objects in @code{pic} unless @code{above=true}.
+The tick locator @code{ticklocate} is constructed by the routine
+@verbatim
+ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, pair dir(real)=zero);
+@end verbatim
+@noindent
+where @code{a} and @code{b} specify the respective tick values at
+@code{point(g,0)} and @code{point(g,length(g))}, @code{S} specifies
+the autoscaling transformation, the function @code{real time(real v)}
+returns the time corresponding to the value @code{v}, and
+@code{pair dir(real t)} returns the absolute tick direction as a
+function of @code{t} (zero means draw the tick perpendicular to the axis).
+
+@item These routines are useful for manually putting ticks and labels on axes
+(if the variable @code{Label} is given as the @code{Label}
+argument, the @code{format} argument will be used to format a string based on
+the tick location):
+@cindex xtick
+@cindex ytick
+@cindex labelx
+@cindex labely
+@cindex tick
+@cindex Label
+@verbatim
+void xtick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+void xtick(picture pic=currentpicture, Label L="", real x,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+void ytick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+void ytick(picture pic=currentpicture, Label L="", real y,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+void tick(picture pic=currentpicture, pair z,
+ pair dir, real size=Ticksize, pen p=currentpen);
+void labelx(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=S, string format="", pen p=currentpen);
+void labelx(picture pic=currentpicture, Label L="", real x,
+ align align=S, string format="", pen p=currentpen);
+void labelx(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen);
+void labely(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=W, string format="", pen p=currentpen);
+void labely(picture pic=currentpicture, Label L="", real y,
+ align align=W, string format="", pen p=currentpen);
+void labely(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen);
+@end verbatim
+@end itemize
+
+Here are some simple examples of two-dimensional graphs:
+
+@enumerate
+
+@cindex textbook graph
+@item This example draws a textbook-style graph of
+@math{y=} exp@math{(x)}, with the @math{y} axis starting at @math{y=0}:
+@verbatiminclude exp.asy
+@sp 1
+@center @image{exp}
+
+
+@item The next example draws a scientific-style graph with a legend.
+The position of the legend can be adjusted either explicitly or by using the
+graphical user interface @code{@uref{http://asymptote.sourceforge.net/gallery/.pdf,,}@uref{http://asymptote.sourceforge.net/gallery/.asy,,.asy}} (@pxref{GUI}). If an
+@code{UnFill(real xmargin=0, real ymargin=xmargin)} or
+@code{Fill(pen)} option is specified to @code{add}, the legend will obscure
+any underlying objects. Here we illustrate how to clip the portion of
+the picture covered by a label:
+
+@cindex scientific graph
+@verbatiminclude lineargraph0.asy
+@sp 1
+@center @image{lineargraph0}
+
+@cindex @code{attach}
+To specify a fixed size for the graph proper, use @code{attach}:
+@verbatiminclude lineargraph.asy
+
+@cindex @code{legend}
+A legend can have multiple entries per line:
+@verbatiminclude legend.asy
+@sp 1
+@center @image{legend}
+
+@item This example draws a graph of one array versus another (both of
+the same size) using custom tick locations and a smaller font size for
+the tick labels on the @math{y} axis.
+@verbatiminclude datagraph.asy
+@sp 1
+@center @image{datagraph}
+
+@item This example shows how to graph columns of data read from a file.
+@verbatiminclude filegraph.asy
+@sp 1
+@center @image{filegraph}
+
+@cindex @code{polygon}
+@cindex @code{cross}
+@cindex @code{errorbars}
+@cindex @code{marker}
+@cindex @code{marknodes}
+@cindex @code{markuniform}
+@cindex @code{mark}
+@cindex path markers
+@anchor{pathmarkers}
+@item The next example draws two graphs of an array of coordinate pairs,
+using frame alignment and data markers. In the left-hand graph, the
+markers, constructed with
+@verbatim
+marker marker(path g, markroutine markroutine=marknodes,
+ pen p=currentpen, filltype filltype=NoFill,
+ bool above=true);
+@end verbatim
+using the path @code{unitcircle} (@pxref{filltype}), are drawn
+below each node. Any frame can be converted to a marker, using
+@anchor{marker}
+@verbatim
+marker marker(frame f, markroutine markroutine=marknodes,
+ bool above=true);
+@end verbatim
+In the right-hand graph, the unit @math{n}-sided regular polygon
+@code{polygon(int n)} and the unit @math{n}-point cyclic cross
+@code{cross(int n, bool round=true, real r=0)} (where @code{r} is an
+optional ``inner'' radius) are used to build a custom marker frame.
+@anchor{markuniform}
+Here @code{markuniform(bool centered=false, int n, bool rotated=false)}
+adds this frame at @code{n} uniformly spaced points along the arclength
+of the path, optionally rotated by the angle of the local tangent to the path
+(if centered is true, the frames will be centered within @code{n} evenly
+spaced arclength intervals). Alternatively, one can use
+markroutine @code{marknodes} to request that the marks be placed at each
+Bezier node of the path, or
+markroutine @code{markuniform(pair z(real t), real a, real b, int n)}
+to place marks at points @code{z(t)} for n evenly spaced values of
+@code{t} in @code{[a,b]}.
+
+These markers are predefined:
+@verbatim
+marker[] Mark={
+ marker(scale(circlescale)*unitcircle),
+ marker(polygon(3)),marker(polygon(4)),
+ marker(polygon(5)),marker(invert*polygon(3)),
+ marker(cross(4)),marker(cross(6))
+};
+
+marker[] MarkFill={
+ marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
+ marker(polygon(4),Fill),marker(polygon(5),Fill),
+ marker(invert*polygon(3),Fill)
+};
+@end verbatim
+
+The example also illustrates the @code{errorbar} routines:
+
+@verbatim
+void errorbars(picture pic=currentpicture, pair[] z, pair[] dp,
+ pair[] dm={}, bool[] cond={}, pen p=currentpen,
+ real size=0);
+
+void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpx, real[] dpy, real[] dmx={}, real[] dmy={},
+ bool[] cond={}, pen p=currentpen, real size=0);
+@end verbatim
+
+@noindent
+Here, the positive and negative extents of the error are given by the
+absolute values of the elements of the pair array @code{dp} and the
+optional pair array @code{dm}. If @code{dm} is not specified, the
+positive and negative extents of the error are assumed to be equal.
+@anchor{errorbars}
+@cindex error bars
+@verbatiminclude errorbars.asy
+@sp 1
+@center @image{errorbars}
+
+@cindex custom mark routine
+@item A custom mark routine can be also be specified:
+@verbatiminclude graphmarkers.asy
+@sp 1
+@center @image{graphmarkers}
+
+@item This example shows how to label an axis with arbitrary strings.
+@verbatiminclude monthaxis.asy
+@sp 1
+@center @image{monthaxis}
+
+@item The next example draws a graph of a parametrized curve.
+@cindex parametrized curve
+@cindex cropping graphs
+@cindex @code{xlimits}
+@cindex @code{ylimits}
+@cindex @code{limits}
+@cindex @code{crop}
+The calls to
+@verbatim
+xlimits(picture pic=currentpicture, real min=-infinity,
+ real max=infinity, bool crop=NoCrop);
+@end verbatim
+@noindent
+and the analogous function @code{ylimits} can be uncommented
+to set the respective axes limits for picture @code{pic} to the
+specified @code{min} and @code{max} values. Alternatively, the function
+@verbatim
+void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop);
+@end verbatim
+can be used to limit the axes to the box having opposite vertices at
+the given pairs). Existing objects in picture @code{pic} will be cropped to lie
+within the given limits if @code{crop}=@code{Crop}. The function
+@code{crop(picture pic)} can be used to crop a graph to the current
+graph limits.
+@verbatiminclude parametricgraph.asy
+@sp 1
+@center @image{parametricgraph}
+
+@cindex scaled graph
+The next example illustrates how one can extract a common axis scaling
+factor.
+@verbatiminclude scaledgraph.asy
+@sp 1
+@center @image{scaledgraph}
+
+@anchor{automatic scaling}
+@cindex automatic scaling
+@cindex @code{scale}
+@cindex @code{Linear}
+@cindex @code{Log}
+@cindex automatic scaling
+Axis scaling can be requested and/or automatic selection of the
+axis limits can be inhibited with one of these @code{scale} routines:
+@verbatim
+void scale(picture pic=currentpicture, scaleT x, scaleT y);
+
+void scale(picture pic=currentpicture, bool xautoscale=true,
+ bool yautoscale=xautoscale, bool zautoscale=yautoscale);
+@end verbatim
+
+This sets the scalings for picture @code{pic}. The @code{graph} routines
+accept an optional @code{picture} argument for determining the appropriate
+scalings to use; if none is given, it uses those set for
+@code{currentpicture}.
+
+Two frequently used scaling routines
+@code{Linear} and @code{Log} are predefined in @code{graph}.
+
+All picture coordinates (including those in paths and those given
+to the @code{label} and @code{limits} functions) are always treated as linear
+(post-scaled) coordinates. Use
+@cindex @code{Scale}
+@verbatim
+pair Scale(picture pic=currentpicture, pair z);
+@end verbatim
+to convert a graph coordinate into a scaled picture coordinate.
+
+The @math{x} and @math{y} components can be individually scaled using
+the analogous routines
+@verbatim
+real ScaleX(picture pic=currentpicture, real x);
+real ScaleY(picture pic=currentpicture, real y);
+@end verbatim
+
+The predefined scaling routines can be given two optional boolean arguments:
+@code{automin=false} and @code{automax=automin}. These default to
+@code{false} but can be respectively set to @code{true} to enable
+automatic selection of "nice" axis minimum and maximum values. The
+@code{Linear} scaling can also take as optional final arguments a
+multiplicative scaling factor and intercept (e.g.@ for a depth axis,
+@code{Linear(-1)} requests axis reversal).
+
+@cindex logarithmic graph
+@cindex log-log graph
+For example, to draw a log/log graph of a function, use @code{scale(Log,Log)}:
+@verbatiminclude loggraph.asy
+@sp 1
+@center @image{loggraph}
+
+@cindex grid
+By extending the ticks, one can easily produce a logarithmic grid:
+@verbatiminclude loggrid.asy
+
+@sp 1
+@center @image{loggrid}
+
+One can also specify custom tick locations and formats for logarithmic axes:
+@verbatiminclude logticks.asy
+@sp 1
+@center @image{logticks}
+
+@cindex @code{log2} graph
+It is easy to draw logarithmic graphs with respect to other bases:
+@verbatiminclude log2graph.asy
+@sp 1
+@center @image{log2graph}
+
+@cindex broken axis
+Here is an example of "broken" linear @math{x} and logarithmic
+@math{y} axes that omit the segments [3,8] and [100,1000], respectively.
+In the case of a logarithmic axis, the break endpoints are automatically
+rounded to the nearest integral power of the base.
+@verbatiminclude brokenaxis.asy
+@sp 1
+@center @image{brokenaxis}
+
+@cindex secondary axis
+@cindex @code{secondaryX}
+@cindex @code{secondaryY}
+@item @code{Asymptote} can draw secondary axes with the routines
+@verbatim
+picture secondaryX(picture primary=currentpicture, void f(picture));
+picture secondaryY(picture primary=currentpicture, void f(picture));
+@end verbatim
+
+In this example, @code{secondaryY} is used to draw a secondary linear
+@math{y} axis against a primary logarithmic @math{y} axis:
+@verbatiminclude Bode.asy
+@sp 1
+@center @image{Bode}
+
+A secondary logarithmic @math{y} axis can be drawn like this:
+@verbatiminclude secondaryaxis.asy
+@sp 1
+@center @image{secondaryaxis}
+
+@item Here is a histogram example, which uses the @code{stats} module.
+@cindex @code{axis}
+@verbatiminclude histogram.asy
+@sp 1
+@center @image{histogram}
+
+@item Here is an example of reading column data in from a file and a
+least-squares fit, using the @code{stats} module.
+@cindex @code{leastsquares}
+@verbatiminclude leastsquares.asy
+@sp 1
+@center @image{leastsquares}
+
+@item Here is an example that illustrates the general @code{axis} routine.
+@cindex @code{axis}
+@verbatiminclude generalaxis.asy
+@sp 1
+@center @image{generalaxis}
+
+@item To draw a vector field of @code{n} arrows evenly spaced along
+the arclength of a path, use the routine
+@cindex @code{vectorfield}
+@verbatim
+picture vectorfield(path vector(real), path g, int n, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow);
+@end verbatim
+as illustrated in this simple example of a flow field:
+@verbatiminclude flow.asy
+@sp 1
+@center @image{flow}
+
+@item To draw a vector field of @code{nx}@math{\times}@code{ny} arrows
+in @code{box(a,b)}, use the routine
+@cindex @code{vectorfield}
+@verbatim
+picture vectorfield(path vector(pair), pair a, pair b,
+ int nx=nmesh, int ny=nx, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(a,b,nx,ny),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar arrow=Arrow, margin margin=PenMargin)
+@end verbatim
+as illustrated in this example:
+@verbatiminclude vectorfield.asy
+@sp 1
+@center @image{vectorfield}
+
+@item The following scientific graphs, which illustrate many features of
+@code{Asymptote}'s graphics routines, were generated from the examples
+@code{@uref{http://asymptote.sourceforge.net/gallery/2D graphs/diatom.pdf,,diatom}@uref{http://asymptote.sourceforge.net/gallery/2D graphs/diatom.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/2D graphs/westnile.pdf,,westnile}@uref{http://asymptote.sourceforge.net/gallery/2D graphs/westnile.asy,,.asy}}, using the comma-separated
+data in @code{@uref{http://asymptote.sourceforge.net/gallery/2D graphs/diatom.csv,,diatom.csv}} and @code{@uref{http://asymptote.sourceforge.net/gallery/2D graphs/westnile.csv,,westnile.csv}}.
+@page
+
+@sp 1
+@center @image{diatom}
+@sp 1
+@center @image{westnile,,7.5cm}
+@end enumerate
+
+@page
+@node palette, three, graph, Base modules
+@section @code{palette}
+@anchor{images}
+@cindex images
+@code{Asymptote} can also generate color density images
+and palettes. The following palettes are predefined in
+@code{palette.asy}:
+
+@table @code
+
+@cindex @code{Grayscale}
+@item pen[] Grayscale(int NColors=256)
+a grayscale palette;
+
+@cindex @code{Rainbow}
+@item pen[] Rainbow(int NColors=32766)
+a rainbow spectrum;
+
+@cindex @code{BWRainbow}
+@item pen[] BWRainbow(int NColors=32761)
+a rainbow spectrum tapering off to black/white at the ends;
+
+@cindex @code{BWRainbow2}
+@item pen[] BWRainbow2(int NColors=32761)
+a double rainbow palette tapering off to black/white at the ends, with
+a linearly scaled intensity.
+
+@cindex @code{Wheel}
+@item pen[] Wheel(int NColors=32766)
+a full color wheel palette;
+
+@cindex @code{Gradient}
+@item pen[] Gradient(int NColors=256 ... pen[] p)
+a palette varying linearly over the specified array of pens, using
+NColors in each interpolation interval;
+
+@end table
+
+The function @code{cmyk(pen[] Palette)} may be used to convert any
+of these palettes to the @acronym{CMYK} colorspace.
+
+A color density plot using palette @code{palette} can be generated from
+a function @code{f}(@math{x},@math{y}) and added to a picture @code{pic}:
+@cindex @code{image}
+@verbatim
+bounds image(picture pic=currentpicture, real f(real, real),
+ range range=Full, pair initial, pair final,
+ int nx=ngraph, int ny=nx, pen[] palette, bool antialias=false)
+@end verbatim
+The function @code{f} will be sampled at @code{nx} and @code{ny}
+evenly spaced points over a rectangle defined by the points
+@code{initial} and @code{final}, respecting the current graphical
+scaling of @code{pic}. The color space is scaled according to the
+@math{z} axis scaling (@pxref{automatic scaling}). A bounds structure
+for the function values is returned:
+@verbatim
+struct bounds {
+ real min;
+ real max;
+ // Possible tick intervals:
+ int[] divisor;
+}
+@end verbatim
+@noindent
+This information can be used for generating an optional palette bar.
+The palette color space corresponds to a range of values specified by
+the argument @code{range}, which can be @code{Full}, @code{Automatic},
+or an explicit range @code{Range(real min, real max)}.
+Here @code{Full} specifies a range varying from the
+minimum to maximum values of the function over the sampling interval,
+while @code{Automatic} selects "nice" limits.
+The example @code{@uref{http://asymptote.sourceforge.net/gallery/2D graphs/imagecontour.pdf,,imagecontour}@uref{http://asymptote.sourceforge.net/gallery/2D graphs/imagecontour.asy,,.asy}} illustrates how level sets
+(contour lines) can be drawn on a color density plot (@pxref{contour}).
+
+A color density plot can also be generated from an explicit real[][]
+array @code{data}:
+@cindex @code{image}
+@verbatim
+bounds image(picture pic=currentpicture, real[][] f, range range=Full,
+ pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+@end verbatim
+@noindent
+If the initial point is to the left and below the final point,
+by default the array indices are interpreted according to the
+Cartesian convention (first index: @math{x}, second index: @math{y})
+rather than the usual matrix convention (first index: @math{-y},
+second index: @math{x}).
+
+To construct an image from an array of irregularly spaced points
+and an array of values @code{f} at these points, use one of the routines
+@verbatim
+bounds image(picture pic=currentpicture, pair[] z, real[] f,
+ range range=Full, pen[] palette)
+bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f,
+ range range=Full, pen[] palette)
+@end verbatim
+
+An optionally labelled palette bar may be generated with the routine
+@verbatim
+void palette(picture pic=currentpicture, Label L="", bounds bounds,
+ pair initial, pair final, axis axis=Right, pen[] palette,
+ pen p=currentpen, paletteticks ticks=PaletteTicks,
+ bool copy=true, bool antialias=false);
+@end verbatim
+The color space of @code{palette} is taken to be over bounds @code{bounds} with
+scaling given by the @math{z} scaling of @code{pic}.
+The palette orientation is specified by @code{axis}, which may be one of
+@code{Right}, @code{Left}, @code{Top}, or @code{Bottom}.
+The bar is drawn over the rectangle from @code{initial} to @code{final}.
+The argument @code{paletteticks} is a special tick type (@pxref{ticks})
+that takes the following arguments:
+@verbatim
+paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ pen pTick=nullpen, pen ptick=nullpen);
+@end verbatim
+
+The image and palette bar can be fit to a frame and added and
+optionally aligned to a picture at the desired location:
+
+@anchor{image}
+@verbatiminclude image.asy
+@sp 1
+@center @image{image}
+
+Here is an example that uses logarithmic scaling of the function values:
+
+@anchor{logimage}
+@verbatiminclude logimage.asy
+@sp 1
+@center @image{logimage}
+
+One can also draw an image directly from a two-dimensional pen array
+or a function @code{pen f(int, int)}:
+@verbatim
+void image(picture pic=currentpicture, pen[][] data,
+ pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+void image(picture pic=currentpicture, pen f(int, int), int width, int height,
+ pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool antialias=false);
+@end verbatim
+@noindent
+as illustrated in the following examples:
+
+@anchor{penimage}
+@verbatiminclude penimage.asy
+@sp 1
+@center @image{penimage}
+
+@anchor{penfunctionimage}
+@verbatiminclude penfunctionimage.asy
+@sp 1
+@center @image{penfunctionimage}
+
+For convenience, the module @code{palette} also defines functions
+that may be used to construct a pen array from a given function and palette:
+@verbatim
+pen[] palette(real[] f, pen[] palette);
+pen[][] palette(real[][] f, pen[] palette);
+@end verbatim
+
+@node three, obj, palette, Base modules
+@section @code{three}
+@cindex @code{three}
+@cindex @code{guide3}
+@cindex @code{path3}
+@cindex @code{cycle}
+@cindex @code{curl}
+@cindex @code{tension}
+@cindex @code{controls}
+This module fully extends the notion of guides and paths in @code{Asymptote}
+to three dimensions. It introduces the new types guide3, path3, and surface.
+Guides in three dimensions are specified with the same syntax as in two
+dimensions except that triples @code{(x,y,z)} are used in place of pairs
+@code{(x,y)} for the nodes and direction specifiers. This
+generalization of John Hobby's spline algorithm is shape-invariant under
+three-dimensional rotation, scaling, and shifting, and reduces in the
+planar case to the two-dimensional algorithm used in @code{Asymptote},
+@code{MetaPost}, and @code{MetaFont} [cf.@ J. C. Bowman, Proceedings in
+Applied Mathematics and Mechanics, 7:1, 2010021-2010022 (2007)].
+
+For example, a unit circle in the @math{XY} plane may be filled and
+drawn like this:
+@verbatiminclude unitcircle3.asy
+@sp 1
+@center @image{unitcircle3}
+@noindent
+and then distorted into a saddle:
+@verbatiminclude saddle.asy
+@sp 1
+@center @image{saddle}
+@noindent
+
+Module @code{three} provides constructors for converting two-dimensional
+paths to three-dimensional ones, and vice-versa:
+@cindex @code{path3}
+@cindex @code{path}
+@verbatim
+path3 path3(path p, triple plane(pair)=XYplane);
+path path(path3 p, pair P(triple)=xypart);
+@end verbatim
+
+@cindex @code{surface}
+@cindex @code{render}
+@cindex @code{defaultrender}
+A Bezier surface, the natural two-dimensional generalization of Bezier
+curves, is defined in @code{three_surface.asy} as a structure
+containing an array of Bezier patches. Surfaces may drawn with one of
+the routines
+@verbatim
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen meshpen,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender);
+
+@end verbatim
+The parameters @code{nu} and @code{nv} specify the number of subdivisions
+for drawing optional mesh lines for each Bezier patch. The optional
+@code{name} parameter is used as a prefix for naming the surface
+patches in the @acronym{PRC} model tree.
+Here material is a structure defined in @code{three_light.asy}:
+@verbatim
+struct material {
+ pen[] p; // diffusepen,emissivepen,specularpen
+ real opacity;
+ real shininess;
+...
+}
+@end verbatim
+@noindent
+These material properties are used to implement @code{OpenGL}-style lighting,
+based on the Phong-Blinn specular model. Sample Bezier surfaces are
+contained in the example files @code{@uref{http://asymptote.sourceforge.net/gallery/BezierSurface.pdf,,BezierSurface}@uref{http://asymptote.sourceforge.net/gallery/BezierSurface.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/teapot.pdf,,teapot}@uref{http://asymptote.sourceforge.net/gallery/teapot.asy,,.asy}},
+and @code{@uref{http://asymptote.sourceforge.net/gallery/parametricsurface.pdf,,parametricsurface}@uref{http://asymptote.sourceforge.net/gallery/parametricsurface.asy,,.asy}}. The structure @code{render} contains
+specialized rendering options documented at the beginning of module
+@code{@uref{http://asymptote.sourceforge.net/gallery/three.pdf,,three}@uref{http://asymptote.sourceforge.net/gallery/three.asy,,.asy}}.
+
+@cindex patch-dependent colors
+@cindex vertex-dependent colors
+The examples
+@code{@uref{http://asymptote.sourceforge.net/gallery/3D graphs/elevation.pdf,,elevation}@uref{http://asymptote.sourceforge.net/gallery/3D graphs/elevation.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/sphericalharmonic.pdf,,sphericalharmonic}@uref{http://asymptote.sourceforge.net/gallery/sphericalharmonic.asy,,.asy}}
+illustrate how to draw a surface with patch-dependent colors.
+The examples @code{@uref{http://asymptote.sourceforge.net/gallery/vertexshading.pdf,,vertexshading}@uref{http://asymptote.sourceforge.net/gallery/vertexshading.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/3D graphs/smoothelevation.pdf,,smoothelevation}@uref{http://asymptote.sourceforge.net/gallery/3D graphs/smoothelevation.asy,,.asy}} illustrate
+vertex-dependent colors, which is supported for both
+@code{Asymptote}'s native @code{OpenGL} renderer and two-dimensional
+projections. Since the @acronym{PRC} output format does not currently support
+vertex shading of Bezier surfaces, @acronym{PRC} patches are shaded
+with the mean of the four vertex colors.
+
+@cindex @code{surface}
+@cindex @code{planar}
+@cindex @code{Bezier patch}
+@cindex @code{Bezier triangle}
+A surface can be constructed from a cyclic @code{path3} with the constructor
+@verbatim
+surface surface(path3 external, triple[] internal=new triple[],
+ pen[] colors=new pen[], bool3 planar=default);
+@end verbatim
+@noindent
+and then filled:
+@verbatim
+draw(surface(unitsquare3,new triple[] {X,Y,Z,O}),red);
+draw(surface(O--X{Y}..Y{-X}--cycle,new triple[] {Z}),red);
+draw(surface(path3(polygon(5))),red,nolight);
+draw(surface(unitcircle3),red,nolight);
+draw(surface(unitcircle3,new pen[] {red,green,blue,black}),nolight);
+@end verbatim
+@noindent
+The first example draws a Bezier patch and the second example draws
+a Bezier triangle. The third and fourth examples are planar surfaces.
+The last example constructs a patch with vertex-specific colors.
+A three-dimensional planar surface in the plane @code{plane} can be
+constructed from a two-dimensional cyclic path @code{g} with the constructor
+@cindex @code{surface}
+@verbatim
+surface surface(path p, triple plane(pair)=XYplane);
+@end verbatim
+@noindent
+and then filled:
+@verbatim
+draw(surface((0,0)--E+2N--2E--E+N..0.2E..cycle),red);
+@end verbatim
+@noindent
+@cindex @code{bezulate}
+Planar Bezier surfaces patches are constructed using Orest Shardt's
+@code{bezulate} routine, which decomposes (possibly nonsimply
+connected) regions bounded (according to the @code{zerowinding} fill rule)
+by simple cyclic paths (intersecting only at the endpoints)
+into subregions bounded by cyclic paths of length @code{4} or less.
+
+A more efficient routine also exists for drawing tessellations
+composed of many 3D triangles, with specified vertices, and optional
+normals or vertex colors:
+@cindex @code{draw}
+@cindex @code{triangles}
+@cindex @code{tessellation}
+@verbatim
+void draw(picture pic=currentpicture, triple[] v, int[][] vi,
+ triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
+ int[][] pi={}, light light=currentlight);
+@end verbatim
+Here, the triple array @code{v} lists the distinct vertices, while
+the array @code{vi} lists integer arrays of length 3 containing
+the indices of @code{v} corresponding to the vertices of each
+triangle. Similarly, the arguments @code{n} and @code{ni} contain
+optional normal data and @code{p} and @code{pi} contain optional pen vertex data.
+An example of this tessellation facility is given in @code{@uref{http://asymptote.sourceforge.net/gallery/triangles.pdf,,triangles}@uref{http://asymptote.sourceforge.net/gallery/triangles.asy,,.asy}}.
+
+@cindex @code{thin}
+@cindex @code{thick}
+@cindex @code{tube}
+Arbitrary thick three-dimensional curves and line caps (which the
+@code{OpenGL} standard does not require implementations to provide) are
+constructed with
+@verbatim
+tube tube(path3 p, real width, render render=defaultrender);
+@end verbatim
+@noindent
+this returns a tube structure representing a tube of diameter @code{width}
+centered approximately on @code{g}. The tube structure consists of a
+surface @code{s} and the actual tube center, path3 @code{center}.
+Drawing thick lines as tubes can be slow to render,
+especially with the @code{Adobe Reader} renderer. The setting
+@code{thick=false} can be used to disable this feature and force all
+lines to be drawn with @code{linewidth(0)} (one pixel wide, regardless
+of the resolution). By default, mesh and contour lines in three-dimensions
+are always drawn thin, unless an explicit line width is given in the pen
+parameter or the setting @code{thin} is set to @code{false}. The pens
+@code{thin()} and @code{thick()} defined in @code{plain_pens.asy} can
+also be used to override these defaults for specific draw commands.
+
+@noindent
+There are four choices for viewing 3D @code{Asymptote} output:
+@enumerate
+@cindex @code{OpenGL}
+@cindex @code{render}
+@cindex @code{outformat}
+@cindex @code{multisample}
+@item Use the native @code{Asymptote} adaptive @code{OpenGL}-based
+renderer (with the command-line option @code{-V} and the default settings
+@code{outformat=""} and @code{render=-1}). If you encounter warnings
+from your graphics card driver, try specifying @code{-glOptions=-indirect}
+on the command line. On @code{UNIX} systems with graphics support for
+multisampling, the sample width can be
+controlled with the setting @code{multisample}. An initial screen
+position can be specified with the pair setting @code{position}, where
+negative values are interpreted as relative to the corresponding
+maximum screen dimension. The default settings
+@cindex mouse bindings
+@verbatim
+import settings;
+leftbutton=new string[] {"rotate","zoom","shift","pan"};
+middlebutton=new string[] {""};
+rightbutton=new string[] {"zoom","rotateX","rotateY","rotateZ"};
+wheelup=new string[] {"zoomin"};
+wheeldown=new string[] {"zoomout"};
+@end verbatim
+bind the mouse buttons as follows:
+@itemize
+@item Left: rotate
+@item Shift Left: zoom
+@item Ctrl Left: shift viewport
+@item Alt Left: pan
+@item Wheel Up: zoom in
+@item Wheel Down: zoom out
+@item Right: zoom
+@item Shift Right: rotate about the X axis
+@item Ctrl Right: rotate about the Y axis
+@item Alt Right: rotate about the Z axis
+@end itemize
+
+The keyboard shortcuts are:
+@cindex keyboard bindings:
+@itemize
+@item h: home
+@item f: toggle fitscreen
+@item x: spin about the X axis
+@item y: spin about the Y axis
+@item z: spin about the Z axis
+@item s: stop spinning
+@item m: rendering mode (solid/patch/mesh)
+@item e: export
+@item c: show camera parameters
+@item p: play animation
+@item r: reverse animation
+@item : step animation
+@item +: expand
+@item =: expand
+@item >: expand
+@item -: shrink
+@item _: shrink
+@item <: shrink
+@item q: exit
+@item Ctrl-q: exit
+@end itemize
+
+@cindex @code{antialias}
+@cindex @code{maxviewport}
+@cindex @code{maxtile}
+@cindex @code{glOptions}
+@cindex @code{iconify}
+@cindex @code{black stripes}
+@item Render the scene to a specified rasterized format @code{outformat}
+at the resolution of @code{n} pixels per @code{bp}, as specified by the
+setting @code{render=n}. A negative value of @code{n} is interpreted
+as @code{|2n|} for @acronym{EPS} and @acronym{PDF} formats and
+@code{|n|} for other formats. The default value of @code{render} is -1.
+By default, the scene is internally rendered at twice the specified
+resolution; this can be disabled by setting @code{antialias=1}.
+High resolution rendering is done by tiling the image. If your
+graphics card allows it, the rendering can be made more efficient by
+increasing the maximum tile size @code{maxtile} to your screen
+dimensions (indicated by @code{maxtile=(0,0)}. If your video card
+generates unwanted black stripes in the output, try setting the
+horizontal and vertical components of @code{maxtiles} to something
+less than your screen dimensions. The tile size is also limited by the
+setting @code{maxviewport}, which restricts the maximum width and
+height of the viewport. On @code{UNIX} systems some graphics
+drivers support batch mode (@code{-noV}) rendering in an
+iconified window; this can be enabled with the setting @code{iconify=true}.
+Some (broken) @code{UNIX} graphics drivers may require the command line setting
+@code{-glOptions=-indirect}, which requests (slower) indirect rendering.
+
+@cindex @code{prc}
+@cindex @code{views}
+@item Embed the 3D @acronym{PRC} format in a @acronym{PDF} file
+and view the resulting @acronym{PDF} file with
+version @code{9.0} or later of @code{Adobe Reader}.
+In addition to the default @code{settings.prc=true}, this requires
+@code{settings.outformat="pdf"}, which can be specified by the command
+line option @code{-f pdf}, put in the @code{Asymptote} configuration
+file (@pxref{configuration file}), or specified in the script before
+@code{@uref{http://asymptote.sourceforge.net/gallery/three.pdf,,three}@uref{http://asymptote.sourceforge.net/gallery/three.asy,,.asy}} (or @code{@uref{http://asymptote.sourceforge.net/gallery/graph3.pdf,,graph3}@uref{http://asymptote.sourceforge.net/gallery/graph3.asy,,.asy}}) is imported.
+The @code{media9} LaTeX package is also required (@pxref{embed}).
+The example @code{@uref{http://asymptote.sourceforge.net/gallery/pdb.pdf,,pdb}@uref{http://asymptote.sourceforge.net/gallery/pdb.asy,,.asy}} illustrates
+how one can generate a list of predefined views (see @code{100d.views}).
+A stationary preview image with a resolution of @code{n} pixels per
+@code{bp} can be embedded with the setting @code{render=n}; this allows
+the file to be viewed with other @code{PDF} viewers. Alternatively, the
+file @code{externalprc.tex} illustrates how the resulting @acronym{PRC} and
+rendered image files can be extracted and processed in a separate
+@code{LaTeX} file. However, see @ref{LaTeX usage} for an easier way
+to embed three-dimensional @code{Asymptote} pictures within @code{LaTeX}.
+For specialized applications where only the raw @acronym{PRC} file is
+required, specify @code{settings.outformat="prc"}.
+The open-source @acronym{PRC} specification is available from
+@url{http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/}.
+
+@item Project the scene to a two-dimensional vector (@acronym{EPS} or
+@acronym{PDF}) format with @code{render=0}. Only limited hidden surface
+removal facilities are currently available with this approach
+(@pxref{PostScript3D}).
+
+@end enumerate
+
+@cindex @code{double deferred drawing}
+Automatic picture sizing in three dimensions is accomplished with double
+deferred drawing. The maximal desired dimensions of the scene in each of
+the three dimensions can optionally be specified with the routine
+@cindex @code{size3}
+@verbatim
+void size3(picture pic=currentpicture, real x, real y=x, real z=y,
+ bool keepAspect=pic.keepAspect);
+@end verbatim
+@noindent
+@cindex margins
+@cindex @code{viewportmargin}
+@cindex @code{viewportsize}
+The resulting simplex linear programming problem is then solved to
+produce a 3D version of a frame (actually implemented as a 3D picture).
+The result is then fit with another application of deferred drawing
+to the viewport dimensions corresponding to the usual two-dimensional
+picture @code{size} parameters. The global pair @code{viewportmargin}
+may be used to add horizontal and vertical margins to the viewport
+dimensions. Alternatively, a minimum @code{viewportsize} may be specified.
+A 3D picture @code{pic} can be explicitly fit to a 3D frame by calling
+@cindex @code{fit3}
+@verbatim
+frame pic.fit3(projection P=currentprojection);
+@end verbatim
+@noindent
+and then added to picture @code{dest} about @code{position} with
+@cindex @code{add}
+@verbatim
+void add(picture dest=currentpicture, frame src, triple position=(0,0,0));
+@end verbatim
+
+@cindex @code{O}
+@cindex @code{X}
+@cindex @code{Y}
+@cindex @code{Z}
+@cindex @code{unitcircle}
+For convenience, the @code{three} module defines @code{O=(0,0,0)},
+@code{X=(1,0,0)}, @code{Y=(0,1,0)}, and @code{Z=(0,0,1)}, along with a
+unitcircle in the XY plane:
+@verbatim
+path3 unitcircle3=X..Y..-X..-Y..cycle;
+@end verbatim
+
+@cindex @code{circle}
+A general (approximate) circle can be drawn perpendicular to the direction
+@code{normal} with the routine
+@verbatim
+path3 circle(triple c, real r, triple normal=Z);
+@end verbatim
+
+@cindex @code{arc}
+A circular arc centered at @code{c} with radius @code{r} from
+@code{c+r*dir(theta1,phi1)} to @code{c+r*dir(theta2,phi2)},
+drawing counterclockwise relative to the normal vector
+@code{cross(dir(theta1,phi1),dir(theta2,phi2))} if @code{theta2 > theta1}
+or if @code{theta2 == theta1} and @code{phi2 >= phi1}, can be constructed with
+@verbatim
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O);
+@end verbatim
+The normal must be explicitly specified if @code{c} and the endpoints
+are colinear. If @code{r} < 0, the complementary arc of radius
+@code{|r|} is constructed.
+For convenience, an arc centered at @code{c} from triple @code{v1} to
+@code{v2} (assuming @code{|v2-c|=|v1-c|}) in the direction CCW
+(counter-clockwise) or CW (clockwise) may also be constructed with
+@verbatim
+path3 arc(triple c, triple v1, triple v2, triple normal=O,
+ bool direction=CCW);
+@end verbatim
+@noindent
+When high accuracy is needed, the routines @code{Circle} and
+@code{Arc} defined in @code{graph3} may be used instead.
+See @ref{GaussianSurface} for an example of a three-dimensional circular arc.
+
+@cindex @code{plane}
+The representation @code{O--O+u--O+u+v--O+v--cycle}
+of the plane passing through point @code{O} with normal
+@code{cross(u,v)} is returned by
+@verbatim
+path3 plane(triple u, triple v, triple O=O);
+@end verbatim
+A three-dimensional box with opposite vertices at triples @code{v1}
+and @code{v2} may be drawn with the function
+@cindex @code{box}
+@verbatim
+path3[] box(triple v1, triple v2);
+@end verbatim
+@noindent
+For example, a unit box is predefined as
+@cindex @code{box}
+@cindex @code{unitbox}
+@verbatim
+path3[] unitbox=box(O,(1,1,1));
+@end verbatim
+@code{Asymptote} also provides optimized definitions for the
+three-dimensional paths @code{unitsquare3} and @code{unitcircle3},
+along with the surfaces @code{unitdisk}, @code{unitplane}, @code{unitcube},
+@code{unitcylinder}, @code{unitcone}, @code{unitsolidcone},
+@code{unitfrustum(real t1, real t2)}, @code{unitsphere}, and
+@code{unithemisphere}.
+
+@noindent
+These projections to two dimensions are predefined:
+@table @code
+@item oblique
+@item oblique(real angle)
+@cindex @code{oblique}
+@cindex @code{obliqueZ}
+The point @code{(x,y,z)} is projected to @code{(x-0.5z,y-0.5z)}.
+If an optional real argument is given, the
+negative @math{z} axis is drawn at this angle in degrees.
+The projection @code{obliqueZ} is a synonym for @code{oblique}.
+
+@item obliqueX
+@item obliqueX(real angle)
+@cindex @code{obliqueX}
+The point @code{(x,y,z)} is projected to @code{(y-0.5x,z-0.5x)}.
+If an optional real argument is given, the
+negative @math{x} axis is drawn at this angle in degrees.
+
+@item obliqueY
+@item obliqueY(real angle)
+@cindex @code{obliqueY}
+The point @code{(x,y,z)} is projected to @code{(x+0.5y,z+0.5y)}.
+If an optional real argument is given, the
+positive @math{y} axis is drawn at this angle in degrees.
+
+@cindex @code{orthographic}
+@cindex @code{up}
+@cindex @code{target}
+@cindex @code{showtarget}
+@cindex @code{center}
+@item orthographic(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, pair viewportshift=0, bool showtarget=true, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool center=false)
+This projects from three to two dimensions using the view as seen at a point
+infinitely far away in the direction @code{unit(camera)}, orienting the camera
+so that, if possible, the vector @code{up} points upwards. Parallel
+lines are projected to parallel lines. The bounding volume is expanded
+to include @code{target} if @code{showtarget=true}.
+If @code{center=true}, the target will be adjusted to the center of the
+bounding volume.
+
+@item orthographic(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, pair viewportshift=0, bool showtarget=true, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool center=false)
+This is equivalent to
+@verbatim
+orthographic((x,y,z),up,target,zoom,viewportshift,showtarget,center)
+@end verbatim
+
+The routine
+@cindex @code{camera}
+@verbatim
+triple camera(real alpha, real beta);
+@end verbatim
+can be used to compute the camera position with the @math{x} axis below
+the horizontal at angle @code{alpha}, the @math{y} axis below the horizontal
+at angle @code{beta}, and the @math{z} axis up.
+
+@cindex @code{autoadjust}
+@item perspective(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, real angle=0, pair viewportshift=0, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, @*@ @ @ @ @ @ @ @ @ @ @ @ bool center=autoadjust)
+@cindex @code{perspective}
+@cindex @code{NURBS}
+This projects from three to two dimensions, taking account of
+perspective, as seen from the location @code{camera} looking at @code{target},
+orienting the camera so that, if possible, the vector @code{up} points upwards.
+If @code{render=0}, projection of three-dimensional cubic Bezier splines
+is implemented by approximating a two-dimensional nonuniform rational B-spline
+(@acronym{NURBS}) with a two-dimensional Bezier curve containing
+additional nodes and control points. If @code{autoadjust=true},
+the camera will automatically be adjusted to lie outside the bounding volume
+for all possible interactive rotations about @code{target}.
+If @code{center=true}, the target will be adjusted to the center of the
+bounding volume.
+
+@item perspective(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, real angle=0, pair viewportshift=0, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, @*@ @ @ @ @ @ @ @ @ @ @ @ bool center=autoadjust)
+This is equivalent to
+@verbatim
+perspective((x,y,z),up,target,zoom,angle,viewportshift,showtarget,
+ autoadjust,center)
+@end verbatim
+@end table
+
+@cindex @code{currentprojection}
+@noindent
+The default projection, @code{currentprojection}, is initially set to
+@code{perspective(5,4,2)}.
+
+@cindex @code{LeftView}
+@cindex @code{RightView}
+@cindex @code{FrontView}
+@cindex @code{BackView}
+@cindex @code{BottomView}
+@cindex @code{TopView}
+We also define standard orthographic views used in technical drawing:
+@verbatim
+projection LeftView=orthographic(-X,showtarget=true);
+projection RightView=orthographic(X,showtarget=true);
+projection FrontView=orthographic(-Y,showtarget=true);
+projection BackView=orthographic(Y,showtarget=true);
+projection BottomView=orthographic(-Z,showtarget=true);
+projection TopView=orthographic(Z,showtarget=true);
+@end verbatim
+@noindent
+The function
+@cindex @code{addViews}
+@verbatim
+void addViews(picture dest=currentpicture, picture src,
+ projection[][] views=SixViewsUS,
+ bool group=true, filltype filltype=NoFill);
+@end verbatim
+@noindent
+adds to picture @code{dest} an array of views of picture @code{src}
+using the layout projection[][] @code{views}. The default layout
+@code{SixViewsUS} aligns the projection @code{FrontView} below
+@code{TopView} and above @code{BottomView}, to the right of
+@code{LeftView} and left of @code{RightView} and @code{BackView}.
+The predefined layouts are:
+@cindex @code{ThreeViewsUS}
+@cindex @code{SixViewsUS}
+@cindex @code{ThreeViewsFR}
+@cindex @code{SixViewsFR}
+@cindex @code{ThreeViews}
+@cindex @code{SixViews}
+@verbatim
+projection[][] ThreeViewsUS={{TopView},
+ {FrontView,RightView}};
+
+projection[][] SixViewsUS={{null,TopView},
+ {LeftView,FrontView,RightView,BackView},
+ {null,BottomView}};
+
+projection[][] ThreeViewsFR={{RightView,FrontView},
+ {null,TopView}};
+
+projection[][] SixViewsFR={{null,BottomView},
+ {RightView,FrontView,LeftView,BackView},
+ {null,TopView}};
+
+projection[][] ThreeViews={{FrontView,TopView,RightView}};
+
+projection[][] SixViews={{FrontView,TopView,RightView},
+ {BackView,BottomView,LeftView}};
+
+@end verbatim
+
+A triple or path3 can be projected to a pair or path,
+with @code{project(triple, projection P=currentprojection)} or
+@code{project(path3, projection P=currentprojection)}.
+
+It is occasionally useful to be able to invert a projection, sending
+a pair @code{z} onto the plane perpendicular to @code{normal} and passing
+through @code{point}:
+@cindex @code{invert}
+@verbatim
+triple invert(pair z, triple normal, triple point,
+ projection P=currentprojection);
+@end verbatim
+@noindent
+A pair @code{z} on the projection plane can be inverted to a triple
+with the routine
+@verbatim
+triple invert(pair z, projection P=currentprojection);
+@end verbatim
+@noindent
+A pair direction @code{dir} on the projection plane can be inverted to
+a triple direction relative to a point @code{v} with the routine
+@verbatim
+triple invert(pair dir, triple v, projection P=currentprojection).
+@end verbatim
+
+@cindex @code{transform3}
+@cindex @code{identity4}
+Three-dimensional objects may be transformed with one of the following
+built-in transform3 types (the identity transformation is @code{identity4}):
+
+@table @code
+@item shift(triple v)
+@cindex @code{shift}
+translates by the triple @code{v};
+@item xscale3(real x)
+@cindex @code{xscale3}
+scales by @code{x} in the @math{x} direction;
+@item yscale3(real y)
+@cindex @code{yscale3}
+scales by @code{y} in the @math{y} direction;
+@item zscale3(real z)
+@cindex @code{zscale3}
+scales by @code{z} in the @math{z} direction;
+@item scale3(real s)
+@cindex @code{scale3}
+scales by @code{s} in the @math{x}, @math{y}, and @math{z} directions;
+@item scale(real x, real y, real z)
+@cindex @code{scale}
+scales by @code{x} in the @math{x} direction,
+by @code{y} in the @math{y} direction, and by @code{z} in the @math{z}
+direction;
+@cindex @code{rotate}
+@item rotate(real angle, triple v)
+rotates by @code{angle} in degrees about an axis @code{v} through the origin;
+@item rotate(real angle, triple u, triple v)
+rotates by @code{angle} in degrees about the axis @code{u--v};
+@item reflect(triple u, triple v, triple w)
+reflects about the plane through @code{u}, @code{v}, and @code{w}.
+@cindex @code{XY}
+@end table
+
+When not multiplied on the left by a transform3, three-dimensional
+@TeX{} Labels are drawn as Bezier surfaces directly on the projection plane:
+@cindex @code{label}
+@verbatim
+void label(picture pic=currentpicture, Label L, triple position,
+ align align=NoAlign, pen p=currentpen,
+ light light=nolight, string name="",
+ render render=defaultrender, interaction interaction=
+ settings.autobillboard ? Billboard : Embedded)
+@end verbatim
+@noindent
+@cindex @code{Billboard}
+@cindex @code{Embedded}
+The optional @code{name} parameter is used as a prefix for naming the label
+patches in the @acronym{PRC} model tree.
+The default interaction is @code{Billboard}, which means that labels
+are rotated interactively so that they always face the camera.
+The interaction @code{Embedded} means that the label interacts as a
+normal @code{3D} surface, as illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/billboard.pdf,,billboard}@uref{http://asymptote.sourceforge.net/gallery/billboard.asy,,.asy}}.
+@cindex @code{transform}
+@cindex @code{XY}
+@cindex @code{YZ}
+@cindex @code{ZX}
+@cindex @code{YX}
+@cindex @code{ZY}
+@cindex @code{ZX}
+Alternatively, a label can be transformed from the @code{XY} plane by an
+explicit transform3 or mapped to a specified two-dimensional plane with
+the predefined transform3 types @code{XY}, @code{YZ}, @code{ZX}, @code{YX},
+@code{ZY}, @code{ZX}. There are also modified versions of these
+transforms that take an optional argument @code{projection
+P=currentprojection} that rotate and/or flip the label so that it is
+more readable from the initial viewpoint.
+
+@cindex @code{planeproject}
+A transform3 that projects in the direction @code{dir} onto the plane
+with normal @code{n} through point @code{O} is returned by
+@verbatim
+transform3 planeproject(triple n, triple O=O, triple dir=n);
+@end verbatim
+@noindent
+One can use
+@cindex @code{normal}
+@verbatim
+triple normal(path3 p);
+@end verbatim
+@noindent
+to find the unit normal vector to a planar three-dimensional path @code{p}.
+As illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/planeproject.pdf,,planeproject}@uref{http://asymptote.sourceforge.net/gallery/planeproject.asy,,.asy}}, a transform3
+that projects in the direction @code{dir} onto the plane defined by a
+planar path @code{p} is returned by
+@verbatim
+transform3 planeproject(path3 p, triple dir=normal(p));
+@end verbatim
+
+The functions
+@cindex @code{extrude}
+@verbatim
+surface extrude(path p, triple axis=Z);
+surface extrude(Label L, triple axis=Z);
+@end verbatim
+@noindent
+return the surface obtained by extruding path @code{p} or
+Label @code{L} along @code{axis}.
+
+@cindex @code{length}
+@cindex @code{size}
+@cindex @code{point}
+@cindex @code{dir}
+@cindex @code{accel}
+@cindex @code{radius}
+@cindex @code{precontrol}
+@cindex @code{postcontrol}
+@cindex @code{arclength}
+@cindex @code{arctime}
+@cindex @code{reverse}
+@cindex @code{subpath}
+@cindex @code{intersect}
+@cindex @code{intersections}
+@cindex @code{intersectionpoint}
+@cindex @code{intersectionpoints}
+@cindex @code{min}
+@cindex @code{max}
+@cindex @code{cyclic}
+@cindex @code{straight}
+Three-dimensional versions of the path functions @code{length},
+@code{size}, @code{point}, @code{dir}, @code{accel}, @code{radius},
+@code{precontrol}, @code{postcontrol},
+@code{arclength}, @code{arctime}, @code{reverse}, @code{subpath},
+@code{intersect}, @code{intersections}, @code{intersectionpoint},
+@code{intersectionpoints}, @code{min}, @code{max}, @code{cyclic}, and
+@code{straight} are also defined.
+
+The routine
+@cindex @code{intersections}
+@verbatim
+real[] intersect(path3 p, surface s, real fuzz=-1);
+@end verbatim
+@noindent
+returns a real array of length 3 containing the intersection times, if any,
+of a path @code{p} with a surface @code{s}.
+The routine
+@verbatim
+real[][] intersections(path3 p, surface s, real fuzz=-1);
+@end verbatim
+@noindent
+returns all (unless there are infinitely many) intersection times of a
+path @code{p} with a surface @code{s} as a sorted array of real arrays
+of length 3, and
+@cindex @code{intersectionpoints}
+@verbatim
+triple[] intersectionpoints(path3 p, surface s, real fuzz=-1);
+@end verbatim
+@noindent
+returns the corresponding intersection points.
+Here, the computations are performed to the absolute error specified by
+@code{fuzz}, or if @code{fuzz < 0}, to machine precision.
+The routine
+@cindex @code{orient}
+@verbatim
+real orient(triple a, triple b, triple c, triple d);
+@end verbatim
+@noindent
+is a numerically robust computation of @code{dot(cross(a-d,b-d),c-d)},
+which is the determinant
+@verbatim
+|a.x a.y a.z 1|
+|b.x b.y b.z 1|
+|c.x c.y c.z 1|
+|d.x d.y d.z 1|
+@end verbatim
+The result is negative (positive) if @code{a}, @code{b}, @code{c} appear in
+counterclockwise (clockwise) order when viewed from @code{d} or zero
+if all four points are coplanar.
+
+The routine
+@cindex @code{insphere}
+@verbatim
+real insphere(triple a, triple b, triple c, triple d, triple e);
+@end verbatim
+@noindent
+returns a positive (negative) value if @code{e} lies inside (outside)
+the sphere passing through points @code{a,b,c,d} oriented so that
+@code{dot(cross(a-d,b-d),c-d)} is positive,
+or zero if all five points are cospherical.
+The value returned is the determinant
+@verbatim
+|a.x a.y a.z a.x^2+a.y^2+a.z^2 1|
+|b.x b.y b.z b.x^2+b.y^2+b.z^2 1|
+|c.x c.y c.z c.x^2+c.y^2+c.z^2 1|
+|d.x d.y d.z d.x^2+d.y^2+d.z^2 1|
+|e.x e.y e.z e.x^2+e.y^2+e.z^2 1|
+@end verbatim
+
+Here is an example showing all five guide3 connectors:
+@verbatiminclude join3.asy
+@sp 1
+@center @image{join3}
+
+@cindex @code{BeginBar3}
+@cindex @code{EndBar3}
+@cindex @code{Bar3}
+@cindex @code{Bars3}
+@cindex @code{BeginArrow3}
+@cindex @code{MidArrow3}
+@cindex @code{EndArrow3}
+@cindex @code{Arrow3}
+@cindex @code{Arrows3}
+@cindex @code{BeginArcArrow3}
+@cindex @code{MidArcArrow3}
+@cindex @code{EndArcArrow3}
+@cindex @code{ArcArrow3}
+@cindex @code{ArcArrows3}
+@cindex @code{DefaultHead3}
+@cindex @code{HookHead3}
+@cindex @code{TeXHead3}
+Three-dimensional versions of bars or arrows can be drawn with one of
+the specifiers @code{None}, @code{Blank},
+@code{BeginBar3}, @code{EndBar3} (or equivalently @code{Bar3}), @code{Bars3},
+@code{BeginArrow3}, @code{MidArrow3},
+@code{EndArrow3} (or equivalently @code{Arrow3}), @code{Arrows3},
+@code{BeginArcArrow3}, @code{EndArcArrow3} (or equivalently
+@code{ArcArrow3}), @code{MidArcArrow3}, and @code{ArcArrows3}.
+Three-dimensional bars accept the optional arguments @code{(real size=0,
+triple dir=O)}. If @code{size=O}, the default bar length is used; if
+@code{dir=O}, the bar is drawn perpendicular to the path
+and the initial viewing direction. The predefined three-dimensional
+arrowhead styles are @code{DefaultHead3}, @code{HookHead3}, @code{TeXHead3}.
+Versions of the two-dimensional arrowheads lifted to three-dimensional
+space and aligned according to the initial viewpoint (or an optionally
+specified @code{normal} vector) are also defined:
+@code{DefaultHead2(triple normal=O)}, @code{HookHead2(triple normal=O)},
+@code{TeXHead2(triple normal=O)}. These are illustrated in the example
+@code{@uref{http://asymptote.sourceforge.net/gallery/arrows3.pdf,,arrows3}@uref{http://asymptote.sourceforge.net/gallery/arrows3.asy,,.asy}}.
+
+@cindex @code{NoMargin3}
+@cindex @code{BeginMargin3}
+@cindex @code{EndMargin3}
+@cindex @code{Margin3}
+@cindex @code{Margins3}
+@cindex @code{BeginPenMargin2}
+@cindex @code{EndPenMargin2}
+@cindex @code{PenMargin2}
+@cindex @code{PenMargins2}
+@cindex @code{BeginPenMargin3}
+@cindex @code{EndPenMargin3}
+@cindex @code{PenMargin3}
+@cindex @code{PenMargins3}
+@cindex @code{BeginDotMargin3}
+@cindex @code{EndDotMargin3}
+@cindex @code{DotMargin3}
+@cindex @code{DotMargins3}
+@cindex @code{Margin3}
+@cindex @code{TrueMargin3}
+Module @code{three} also defines the three-dimensional margins
+@code{NoMargin3}, @code{BeginMargin3}, @code{EndMargin3},
+@code{Margin3}, @code{Margins3},
+@code{BeginPenMargin2}, @code{EndPenMargin2}, @code{PenMargin2},
+@code{PenMargins2},
+@code{BeginPenMargin3}, @code{EndPenMargin3}, @code{PenMargin3},
+@code{PenMargins3},
+@code{BeginDotMargin3}, @code{EndDotMargin3}, @code{DotMargin3},
+@code{DotMargins3}, @code{Margin3}, and @code{TrueMargin3}.
+
+@cindex @code{pixel}
+The routine
+@verbatim
+void pixel(picture pic=currentpicture, triple v, pen p=currentpen,
+ real width=1);
+@end verbatim
+@noindent
+can be used to draw on picture @code{pic} a pixel of width @code{width} at
+position @code{v} using pen @code{p}.
+
+Further three-dimensional examples are provided in the files
+@code{@uref{http://asymptote.sourceforge.net/gallery/near_earth.pdf,,near_earth}@uref{http://asymptote.sourceforge.net/gallery/near_earth.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/conicurv.pdf,,conicurv}@uref{http://asymptote.sourceforge.net/gallery/conicurv.asy,,.asy}}, and (in the @code{animations}
+subdirectory) @code{@uref{http://asymptote.sourceforge.net/gallery/cube.pdf,,cube}@uref{http://asymptote.sourceforge.net/gallery/cube.asy,,.asy}}.
+
+@anchor{PostScript3D}
+@cindex 3D @code{PostScript}
+Limited support for projected vector graphics (effectively three-dimensional
+nonrendered @code{PostScript}) is available with the setting
+@code{render=0}. This currently only works for piecewise planar
+surfaces, such as those produced by the parametric @code{surface}
+routines in the @code{graph3} module. Surfaces produced by the
+@code{solids} package will also be properly rendered if the parameter
+@code{nslices} is sufficiently large.
+
+@cindex hidden surface removal
+@cindex @code{face}
+In the module @code{bsp}, hidden surface removal of planar pictures is
+implemented using a binary space partition and picture clipping.
+A planar path is first converted to a structure @code{face} derived from
+@code{picture}. A @code{face} may be given to a two-dimensional drawing
+routine in place of any @code{picture} argument. An array of such faces
+may then be drawn, removing hidden surfaces:
+@verbatim
+void add(picture pic=currentpicture, face[] faces,
+ projection P=currentprojection);
+@end verbatim
+Labels may be projected to two dimensions, using projection @code{P},
+onto the plane passing through point @code{O} with normal
+@code{cross(u,v)} by multiplying it on the left by the transform
+@verbatim
+transform transform(triple u, triple v, triple O=O,
+ projection P=currentprojection);
+@end verbatim
+
+Here is an example that shows how a binary space partition may be used to draw a
+two-dimensional vector graphics projection of three orthogonal
+intersecting planes:
+@verbatiminclude planes.asy
+@sp 1
+@center @image{planes}
+
+@node obj, graph3, three, Base modules
+@section @code{obj}
+@cindex @code{obj}
+This module allows one to construct surfaces from simple obj files,
+as illustrated in the example files @code{@uref{http://asymptote.sourceforge.net/gallery/galleon.pdf,,galleon}@uref{http://asymptote.sourceforge.net/gallery/galleon.asy,,.asy}} and
+@code{@uref{http://asymptote.sourceforge.net/gallery/triceratops.pdf,,triceratops}@uref{http://asymptote.sourceforge.net/gallery/triceratops.asy,,.asy}}.
+
+@node graph3, grid3, obj, Base modules
+@section @code{graph3}
+@cindex @code{graph3}
+@cindex 3D graphs
+This module implements three-dimensional versions of the
+functions in @code{graph.asy}.
+@cindex @code{xaxis3}
+@cindex @code{yaxis3}
+@cindex @code{zaxis3}
+@noindent
+To draw an @math{x} axis in three dimensions, use the routine
+@verbatim
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3, arrowbar3 arrow=None, bool above=false);
+@end verbatim
+@noindent
+Analogous routines @code{yaxis} and @code{zaxis} can be used to draw
+@math{y} and @math{z} axes in three dimensions.
+There is also a routine for drawing all three axis:
+@verbatim
+void axes3(picture pic=currentpicture,
+ Label xlabel="", Label ylabel="", Label zlabel="",
+ bool extend=false,
+ triple min=(-infinity,-infinity,-infinity),
+ triple max=(infinity,infinity,infinity),
+ pen p=currentpen, arrowbar3 arrow=None);
+@end verbatim
+
+@cindex @code{YZEquals}
+@cindex @code{XZEquals}
+@cindex @code{XYEquals}
+@cindex @code{YZZero}
+@cindex @code{XZZero}
+@cindex @code{XYZero}
+@cindex @code{Bounds}
+@noindent
+The predefined three-dimensional axis types are
+@verbatim
+axis YZEquals(real y, real z, triple align=O, bool extend=false);
+axis XZEquals(real x, real z, triple align=O, bool extend=false);
+axis XYEquals(real x, real y, triple align=O, bool extend=false);
+axis YZZero(triple align=O, bool extend=false);
+axis XZZero(triple align=O, bool extend=false);
+axis XYZero(triple align=O, bool extend=false);
+axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false);
+@end verbatim
+@noindent
+The optional @code{align} parameter to these routines can be used to
+specify the default axis and tick label alignments. The @code{Bounds}
+axis accepts two type parameters, each of which must be one of
+@code{Min}, @code{Max}, or @code{Both}. These parameters specify which
+of the four possible three-dimensional bounding box edges should be drawn.
+
+@cindex @code{NoTicks3}
+@cindex @code{InTicks}
+@cindex @code{OutTicks}
+@cindex @code{InOutTicks}
+The three-dimensional tick options are @code{NoTicks3}, @code{InTicks},
+@code{OutTicks}, and @code{InOutTicks}. These specify the tick
+directions for the @code{Bounds} axis type; other axis types inherit
+the direction that would be used for the @code{Bounds(Min,Min)} axis.
+
+Here is an example of a helix and bounding box axes with ticks
+and axis labels, using orthographic projection:
+@verbatiminclude helix.asy
+@sp 1
+@center @image{helix}
+
+The next example illustrates three-dimensional @math{x}, @math{y}, and
+@math{z} axes, without autoscaling of the axis limits:
+@cindex @code{axis}
+@verbatiminclude axis3.asy
+@sp 1
+@center @image{axis3}
+
+One can also place ticks along a general three-dimensional axis:
+@cindex @code{axis}
+@verbatiminclude generalaxis3.asy
+@sp 1
+@center @image{generalaxis3}
+
+@cindex @code{surface}
+@cindex @code{Spline}
+@cindex parametric surface
+Surface plots of matrices and functions over the region
+@code{box(a,b)} in the @math{XY} plane are also implemented:
+@verbatim
+surface surface(real[][] f, pair a, pair b, bool[][] cond={});
+surface surface(real[][] f, pair a, pair b, splinetype xsplinetype,
+ splinetype ysplinetype=xsplinetype, bool[][] cond={});
+surface surface(real[][] f, real[] x, real[] y,
+ splinetype xsplinetype=null, splinetype ysplinetype=xsplinetype,
+ bool[][] cond={})
+surface surface(triple[][] f, bool[][] cond={});
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ bool cond(pair z)=null);
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ splinetype xsplinetype, splinetype ysplinetype=xsplinetype,
+ bool cond(pair z)=null);
+surface surface(triple f(pair z), real[] u, real[] v,
+ splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
+ bool cond(pair z)=null);
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ bool cond(pair z)=null);
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
+ bool cond(pair z)=null);
+@end verbatim
+@noindent
+The final two versions draw parametric surfaces for a function
+@math{f(u,v)} over the parameter space @code{box(a,b)},
+as illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/parametricsurface.pdf,,parametricsurface}@uref{http://asymptote.sourceforge.net/gallery/parametricsurface.asy,,.asy}}.
+An optional splinetype @code{Spline} may be specified.
+The boolean array or function @code{cond} can be used to control which
+surface mesh cells are actually drawn (by default all mesh cells over
+@code{box(a,b)} are drawn).
+Surface lighting is illustrated in the example files
+@code{@uref{http://asymptote.sourceforge.net/gallery/parametricsurface.pdf,,parametricsurface}@uref{http://asymptote.sourceforge.net/gallery/parametricsurface.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/3D graphs/sinc.pdf,,sinc}@uref{http://asymptote.sourceforge.net/gallery/3D graphs/sinc.asy,,.asy}}.
+Lighting can be disabled by setting @code{light=nolight}, as in this example
+of a Gaussian surface:
+@anchor{GaussianSurface}
+@verbatiminclude GaussianSurface.asy
+@sp 1
+@center @image{GaussianSurface}
+@noindent
+A mesh can be drawn without surface filling by specifying @code{nullpen}
+for the surfacepen.
+
+A vector field of @code{nu}@math{\times}@code{nv} arrows on a
+parametric surface @code{f} over @code{box(a,b)} can be drawn with the routine
+@cindex @code{vectorfield3}
+@verbatim
+picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b,
+ int nu=nmesh, int nv=nu, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(f,a,b,nu,nv),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3)
+@end verbatim
+as illustrated in the examples @code{@uref{http://asymptote.sourceforge.net/gallery/3D graphs/vectorfield3.pdf,,vectorfield3}@uref{http://asymptote.sourceforge.net/gallery/3D graphs/vectorfield3.asy,,.asy}} and
+@code{@uref{http://asymptote.sourceforge.net/gallery/vectorfieldsphere.pdf,,vectorfieldsphere}@uref{http://asymptote.sourceforge.net/gallery/vectorfieldsphere.asy,,.asy}}.
+
+@node grid3, solids, graph3, Base modules
+@section @code{grid3}
+@cindex @code{grid3}
+@cindex 3D grids
+
+This module, contributed by Philippe Ivaldi, can be used for drawing
+3D grids. Here is an example (further examples can be found in
+@code{grid3.asy} and at @url{http://www.piprime.fr/files/asymptote/grid3/}):
+@verbatiminclude grid3xyz.asy
+@sp 1
+@center @image{grid3xyz}
+
+@node solids, tube, grid3, Base modules
+@section @code{solids}
+@cindex @code{solids}
+This solid geometry package defines a structure @code{revolution} that
+can be used to fill and draw surfaces of revolution. The following example
+uses it to display the outline of a circular cylinder of radius 1
+with axis @code{O--1.5unit(Y+Z)} with perspective projection:
+@verbatiminclude cylinderskeleton.asy
+@sp 1
+@center @image{cylinderskeleton}
+
+Further illustrations are provided in the example files @code{@uref{http://asymptote.sourceforge.net/gallery/cylinder.pdf,,cylinder}@uref{http://asymptote.sourceforge.net/gallery/cylinder.asy,,.asy}},
+@code{@uref{http://asymptote.sourceforge.net/gallery/cones.pdf,,cones}@uref{http://asymptote.sourceforge.net/gallery/cones.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/hyperboloid.pdf,,hyperboloid}@uref{http://asymptote.sourceforge.net/gallery/hyperboloid.asy,,.asy}}, and @code{@uref{http://asymptote.sourceforge.net/gallery/torus.pdf,,torus}@uref{http://asymptote.sourceforge.net/gallery/torus.asy,,.asy}}.
+
+The structure @code{skeleton} contains the three-dimensional wireframe
+used to visualize a volume of revolution:
+@verbatim
+struct skeleton {
+ struct curve {
+ path3[] front;
+ path3[] back;
+ }
+ // transverse skeleton (perpendicular to axis of revolution)
+ curve transverse;
+ // longitudinal skeleton (parallel to axis of revolution)
+ curve longitudinal;
+}
+@end verbatim
+
+@node tube, flowchart, solids, Base modules
+@section @code{tube}
+@cindex @code{tube}
+This package extends the @code{tube} surfaces constructed in
+@code{@uref{http://asymptote.sourceforge.net/gallery/three_arrows.pdf,,three_arrows}@uref{http://asymptote.sourceforge.net/gallery/three_arrows.asy,,.asy}} to arbitrary cross sections, colors, and spine
+transformations. The routine
+@verbatim
+surface tube(path3 g, coloredpath section,
+ transform T(real)=new transform(real t) {return identity();},
+ real corner=1, real relstep=0);
+@end verbatim
+@noindent
+draws a tube along @code{g} with cross section @code{section}, after
+applying the transformation @code{T(t)} at @code{relpoint(g,t)}.
+The parameter @code{corner} controls the number of elementary tubes at
+the angular points of @code{g}. A nonzero value of @code{relstep}
+specifies a fixed relative time step (in the sense of
+@code{relpoint(g,t)}) to use in constructing elementary tubes along @code{g}.
+The type @code{coloredpath} is a generalization of @code{path} to
+which a @code{path} can be cast:
+@cindex @code{coloredpath}
+@verbatim
+struct coloredpath
+{
+ path p;
+ pen[] pens(real);
+ int colortype=coloredSegments;
+}
+@end verbatim
+@noindent
+@cindex @code{coloredSegments}
+@cindex @code{coloredNodes}
+Here @code{p} defines the cross section and
+the method @code{pens(real t)} returns an array of pens (interpreted
+as a cyclic array) used for shading the tube patches at
+@code{relpoint(g,t)}. If @code{colortype=coloredSegments}, the tube patches
+are filled as if each segment of the section was colored with the pen
+returned by @code{pens(t)}, whereas if @code{colortype=coloredNodes}, the
+tube components are vertex shaded as if the nodes of the section were colored.
+
+A @code{coloredpath} can be constructed with one of the routines:
+@verbatim
+coloredpath coloredpath(path p, pen[] pens(real),
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen[] pens=new pen[] {currentpen},
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen pen(real));
+@end verbatim
+@noindent
+In the second case, the pens are independent of the relative time.
+In the third case, the array of pens contains only one pen, which
+depends of the relative time.
+
+The casting of @code{path} to @code{coloredpath} allows the
+use of a @code{path} instead of a @code{coloredpath}; in this case the
+shading behaviour is the default shading behavior for a surface.
+
+An example of @code{tube} is provided in the file
+@code{@uref{http://asymptote.sourceforge.net/gallery/trefoilknot.pdf,,trefoilknot}@uref{http://asymptote.sourceforge.net/gallery/trefoilknot.asy,,.asy}}. Further examples can be found at
+@url{http://www.piprime.fr/files/asymptote/tube/}.
+
+@node flowchart, contour, tube, Base modules
+@section @code{flowchart}
+@cindex @code{flowchart}
+This package provides routines for drawing flowcharts. The primary
+structure is a @code{block}, which represents a single block on the
+flowchart. The following eight functions return a position on the appropriate
+edge of the block, given picture transform @code{t}:
+
+@verbatim
+pair block.top(transform t=identity());
+pair block.left(transform t=identity());
+pair block.right(transform t=identity());
+pair block.bottom(transform t=identity());
+pair block.topleft(transform t=identity());
+pair block.topright(transform t=identity());
+pair block.bottomleft(transform t=identity());
+pair block.bottomright(transform t=identity());
+@end verbatim
+@cindex @code{block.top}
+@cindex @code{block.left}
+@cindex @code{block.right}
+@cindex @code{block.bottom}
+@cindex @code{block.topleft}
+@cindex @code{block.topright}
+@cindex @code{block.bottomleft}
+@cindex @code{block.bottomright}
+
+@noindent
+To obtain an arbitrary position along the boundary of the block in user
+coordinates, use:
+@verbatim
+pair block.position(real x, transform t=identity());
+@end verbatim
+@cindex @code{block.position}
+
+@noindent
+@cindex @code{block.center}
+The center of the block in user coordinates is stored in
+@code{block.center} and the block size in @code{PostScript} coordinates
+is given by @code{block.size}.
+
+@noindent
+A frame containing the block is returned by
+@verbatim
+frame block.draw(pen p=currentpen);
+@end verbatim
+@cindex @code{block.draw}
+
+The following block generation routines accept a Label, string, or
+frame for their object argument:
+
+@table @dfn
+@item rectangular block with an optional header (and padding @code{dx} around header and body):
+@cindex @code{rectangle}
+@verbatim
+block rectangle(object header, object body, pair center=(0,0),
+ pen headerpen=mediumgray, pen bodypen=invisible,
+ pen drawpen=currentpen,
+ real dx=3, real minheaderwidth=minblockwidth,
+ real minheaderheight=minblockwidth,
+ real minbodywidth=minblockheight,
+ real minbodyheight=minblockheight);
+block rectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+@end verbatim
+
+@item parallelogram block:
+@cindex @code{parallelogram}
+@verbatim
+block parallelogram(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real slope=2,
+ real minwidth=minblockwidth,
+ real minheight=minblockheight);
+@end verbatim
+
+@item diamond-shaped block:
+@cindex @code{diamond}
+@verbatim
+block diamond(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=1,
+ real height=20, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+@end verbatim
+
+@item circular block:
+@cindex @code{circle}
+@verbatim
+block circle(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dr=3,
+ real mindiameter=mincirclediameter);
+@end verbatim
+
+@item rectangular block with rounded corners:
+@cindex @code{roundrectangle}
+@verbatim
+block roundrectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=0, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+@end verbatim
+
+@item rectangular block with beveled edges:
+@cindex @code{bevel}
+@verbatim
+block bevel(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dh=5, real dw=5,
+ real minwidth=minblockwidth, real minheight=minblockheight);
+@end verbatim
+
+@end table
+
+To draw paths joining the pairs in @code{point} with right-angled lines,
+use the routine:
+@cindex @code{path}
+@cindex @code{Horizontal}
+@cindex @code{Vertical}
+@verbatim
+path path(pair point[] ... flowdir dir[]);
+@end verbatim
+@noindent
+The entries in @code{dir} identify whether successive
+segments between the pairs specified by @code{point} should be drawn
+in the @code{Horizontal} or @code{Vertical} direction.
+
+Here is a simple flowchart example (see also the example
+@code{@uref{http://asymptote.sourceforge.net/gallery/controlsystem.pdf,,controlsystem}@uref{http://asymptote.sourceforge.net/gallery/controlsystem.asy,,.asy}}):
+
+@verbatiminclude flowchartdemo.asy
+@sp 1
+@center @image{flowchartdemo}
+
+@node contour, contour3, flowchart, Base modules
+@section @code{contour}
+@cindex @code{contour}
+This package draws contour lines.
+To construct contours corresponding to the values in a real array @code{c}
+for a function @code{f} on @code{box(a,b)}, use the routine
+@verbatim
+guide[][] contour(real f(real, real), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --, int subsample=1);
+@end verbatim
+@noindent
+The integers @code{nx} and @code{ny} define the resolution.
+The default resolution, @code{ngraph x ngraph} (here @code{ngraph}
+defaults to @code{100}) can be increased for greater accuracy.
+The default interpolation operator is @code{operator --} (linear). Spline
+interpolation (@code{operator ..}) may produce smoother
+contours but it can also lead to overshooting.
+The @code{subsample} parameter indicates the number of interior points
+that should be used to sample contours within each @code{1 x 1} box;
+the default value of @code{1} is usually sufficient.
+
+To construct contours for an array of data values on a uniform
+two-dimensional lattice on @code{box(a,b)}, use
+@verbatim
+guide[][] contour(real[][] f, pair a, pair b, real[] c,
+ interpolate join=operator --, int subsample=1);
+@end verbatim
+
+To construct contours for an array of data values on a nonoverlapping
+regular mesh specified by the two-dimensional array @code{z},
+@verbatim
+guide[][] contour(pair[][] z, real[][] f, real[] c,
+ interpolate join=operator --, int subsample=1);
+
+@end verbatim
+@noindent
+To construct contours for an array of values @code{f} specified at
+irregularly positioned points @code{z}, use the routine
+@verbatim
+guide[][] contour(pair[] z, real[] f, real[] c, interpolate join=operator --);
+@end verbatim
+@noindent
+The contours themselves can be drawn with one of the routines
+@verbatim
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen p=currentpen);
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen[] p);
+@end verbatim
+
+The following simple example draws the contour at value @code{1}
+for the function @math{z=x^2+y^2}, which is a unit circle:
+@verbatiminclude onecontour.asy
+@sp 1
+@center @image{onecontour}
+
+The next example draws and labels multiple contours for the function
+@math{z=x^2-y^2} with the resolution @code{100 x 100}, using a dashed
+pen for negative contours and a solid pen for positive (and zero) contours:
+@verbatiminclude multicontour.asy
+@sp 1
+@center @image{multicontour}
+
+The next example illustrates how contour lines can be drawn on color
+density images:
+@verbatiminclude imagecontour.asy
+@sp 1
+@center @image{imagecontour}
+
+Finally, here is an example that illustrates the construction of contours
+from irregularly spaced data:
+@verbatiminclude irregularcontour.asy
+@sp 1
+@center @image{irregularcontour}
+
+In the above example, the contours of irregularly spaced data are constructed by
+first creating a triangular mesh from an array @code{z} of pairs:
+
+@cindex @code{triangulate}
+@verbatim
+int[][] triangulate(pair[] z);
+@end verbatim
+
+@verbatiminclude triangulate.asy
+@sp 1
+@center @image{triangulate}
+
+The example @code{@uref{http://asymptote.sourceforge.net/gallery/2D
+graphs/Gouraudcontour.pdf,,Gouraudcontour}@uref{http://asymptote.sourceforge.net/gallery/2D graphs/Gouraudcontour.asy,,.asy}} illustrates how to produce color
+density images over such irregular triangular meshes.
+@code{Asymptote} uses a robust version of Paul Bourke's Delaunay triangulation
+algorithm based on the public-domain exact arithmetic predicates written by
+Jonathan Shewchuk.
+
+@node contour3, smoothcontour3, contour, Base modules
+@section @code{contour3}
+@cindex @code{contour3}
+This package draws surfaces described as the null space of real-valued
+functions of @math{(x,y,z)} or @code{real[][][]} matrices.
+Its usage is illustrated in the example file @code{@uref{http://asymptote.sourceforge.net/gallery/3D graphs/magnetic.pdf,,magnetic}@uref{http://asymptote.sourceforge.net/gallery/3D graphs/magnetic.asy,,.asy}}.
+
+@node smoothcontour3, slopefield, contour3, Base modules
+@section @code{smoothcontour3}
+@cindex @code{smoothcontour3}
+This module, written by Charles Staats, draws implicitly defined surfaces
+with smooth appearance.
+The purpose of this module is similar to that of @code{contour3}: given
+a real-valued function @math{f(x,y,z)}, construct the surface described by
+the equation @math{f(x,y,z) = 0}. The @code{smoothcontour3} module generally produces
+nicer results than @code{contour3}, but takes longer to compile. Additionally, the
+algorithm assumes that the function and the surface are both smooth; if they are not,
+then @code{contour3} may be a better choice.
+
+To construct the null surface of a function @code{f(triple)} or @code{ff(real,real,real)}
+over @code{box(a,b)}, use the routine
+@cindex @code{implicitsurface}
+@verbatim
+surface implicitsurface(real f(triple)=null,
+ real ff(real,real,real)=null,
+ triple a,
+ triple b,
+ int n=nmesh,
+ bool keyword overlapedges=false,
+ int keyword nx=n,
+ int keyword ny=n,
+ int keyword nz=n,
+ int keyword maxdepth=8,
+ bool usetriangles=true);
+@end verbatim
+@noindent
+The optional parameter @code{overlapedges} attempts to compensate for
+an artifact that can cause the renderer to ``see through'' the
+boundary between patches. Although
+it defaults to @code{false}, it should usually be set to @code{true}.
+The example @code{@uref{http://asymptote.sourceforge.net/gallery/genustwo.pdf,,genustwo}@uref{http://asymptote.sourceforge.net/gallery/genustwo.asy,,.asy}} illustrates the use of this function.
+Additional examples, together with a more in-depth explanation of
+the module's usage and pitfalls, are available at
+@url{https://github.com/charlesstaats/smoothcontour3}.
+
+@node slopefield, ode, smoothcontour3, Base modules
+@section @code{slopefield}
+@cindex @code{slopefield}
+To draw a slope field for the differential equation @math{dy/dx=f(x,y)} (or
+@math{dy/dx=f(x)}), use:
+@verbatim
+picture slopefield(real f(real,real), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ real tickfactor=0.5, pen p=currentpen,
+ arrowbar arrow=None);
+@end verbatim
+@noindent
+Here, the points @code{a} and @code{b} are the lower left and upper
+right corners of the rectangle in which the slope field is to be drawn,
+@code{nx} and @code{ny} are the respective number of ticks in the
+@math{x} and @math{y} directions, @code{tickfactor} is the fraction of
+the minimum cell dimension to use for drawing ticks, and @code{p} is
+the pen to use for drawing the slope fields.
+The return value is a picture that can be added to
+@code{currentpicture} via the @code{add(picture)} command.
+
+The function
+@cindex @code{curve}
+@verbatim
+path curve(pair c, real f(real,real), pair a, pair b);
+@end verbatim
+@noindent
+takes a point (@code{c}) and a slope field-defining function @code{f}
+and returns, as a path, the curve passing through that point. The points
+@code{a} and @code{b} represent the rectangular boundaries over which
+the curve is interpolated.
+
+Both @code{slopefield} and @code{curve} alternatively accept a function
+@code{real f(real)} that depends on @math{x} only, as seen in this example:
+
+@verbatiminclude slopefield1.asy
+@sp 1
+@center @image{slopefield1}
+
+@node ode, , slopefield, Base modules
+@section @code{ode}
+@cindex @code{ode}
+The @code{ode} module, illustrated in the example @code{@uref{https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/examples/odetest.asy,,odetest.asy}},
+implements a number of explicit numerical integration schemes for
+ordinary differential equations.
+
+@node Options, Interactive mode, Base modules, Top
+@chapter Command-line options
+@cindex options
+@cindex command-line options
+Type @code{asy -h} to see the full list of command-line options
+supported by @code{Asymptote}:
+@verbatiminclude options
+
+All boolean options can be negated by prepending @code{no} to the option name.
+
+If no arguments are given, @code{Asymptote} runs in interactive mode
+(@pxref{Interactive mode}). In this case, the default output file
+is @code{out.eps}.
+
+If @code{-} is given as the file argument, @code{Asymptote} reads from
+standard input.
+
+If multiple files are specified, they are treated as separate
+@code{Asymptote} runs.
+
+@cindex @code{autoimport}
+If the string @code{autoimport} is nonempty, a module with this name is
+automatically imported for each run as the final step in loading module
+@code{plain}.
+
+@anchor{configuration file}
+@cindex configuration file
+@cindex @code{ASYMPTOTE_CONFIG}
+@cindex @code{config}
+@cindex @code{settings}
+@anchor{settings}
+Default option values may be entered as @code{Asymptote} code in a
+configuration file named @code{config.asy} (or the file specified by
+the environment variable @code{ASYMPTOTE_CONFIG} or @code{-config} option).
+@code{Asymptote} will look for this file in its usual search path
+(@pxref{Search paths}). Typically the configuration file is placed in the
+@code{.asy} directory in the user's home directory
+(@code{%USERPROFILE%\.asy} under @code{MSDOS}).
+Configuration variables are accessed using the long form of the option names:
+@verbatim
+import settings;
+outformat="pdf";
+batchView=false;
+interactiveView=true;
+batchMask=false;
+interactiveMask=true;
+@end verbatim
+Command-line options override these defaults. Most configuration
+variables may also be changed at runtime.
+@cindex @code{dvipsOptions}
+@cindex @code{hyperrefOptions}
+@cindex @code{convertOptions}
+@cindex @code{gsOptions}
+@cindex @code{psviewerOptions}
+@cindex @code{pdfviewerOptions}
+@cindex @code{pdfreloadOptions}
+@cindex @code{glOptions}
+@cindex @code{dvisvgmOptions}
+The advanced configuration variables @code{dvipsOptions},
+@code{hyperrefOptions}, @code{convertOptions}, @code{gsOptions},
+@code{psviewerOptions}, @code{pdfviewerOptions}, @code{pdfreloadOptions},
+@code{glOptions}, and @code{dvisvgmOptions} allow specialized options
+to be passed as a string to the respective applications or
+libraries. The default value of @code{hyperrefOptions} is
+@code{setpagesize=false,unicode,pdfborder=0 0 0}.
+
+If you insert
+@verbatim
+import plain;
+settings.autoplain=true;
+@end verbatim
+@noindent
+at the beginning of the configuration file, it can contain arbitrary
+@code{Asymptote} code.
+
+@cindex @code{convert}
+@cindex @code{output}
+@cindex @code{format}
+@cindex @code{ImageMagick}
+@cindex @code{render}
+@cindex @code{antialias}
+@cindex @code{size}
+@cindex @code{latex}
+@cindex @code{tex}
+@cindex @code{pdflatex}
+@cindex @code{xelatex}
+@cindex @code{context}
+@cindex @code{luatex}
+@cindex @code{lualatex}
+@cindex @code{EPS}
+@cindex @code{PDF}
+@anchor{texengines}
+@anchor{convert}
+The default output format is @acronym{EPS} for the (default)
+@code{latex} and @code{tex} tex engine and @acronym{PDF} for the
+@code{pdflatex}, @code{xelatex}, @code{context}, @code{luatex}, and
+@code{lualatex} tex engines. Alternative output formats may be
+produced using the @code{-f} option (or @code{outformat} setting).
+
+@cindex @code{SVG}
+@cindex @code{dvisvgm}
+@cindex @code{libgs}
+To produce @acronym{SVG} output, you will need @code{dvisvgm} (version
+1.5.3 or later) from @url{http://dvisvgm.sourceforge.net} and must use
+the @code{latex} or @code{tex} tex engine. You might need to adjust
+the configuration variable @code{libgs} to point to the location of
+your @code{Ghostscript} library @code{libgs.so} (or to an empty
+string, depending on how @code{dvisvgm} was configured).
+
+@code{Asymptote} can also produce any output format supported
+by the @code{ImageMagick} @code{convert} program (version 6.3.5 or
+later recommended; an @code{Invalid Parameter} error message indicates
+that the @code{MSDOS} utility @code{convert} is being used instead of
+the one that comes with @code{ImageMagick}).
+The optional setting @code{-render n} requests
+an output resolution of @code{n} pixels per @code{bp}. Antialiasing is
+controlled by the parameter @code{antialias}, which by default
+specifies a sampling width of 2 pixels.
+To give other options to @code{convert}, use the
+@code{convertOptions} setting or call convert manually. This example
+emulates how @code{Asymptote} produces antialiased @code{tiff} output at
+one pixel per @code{bp}:
+@verbatim
+asy -o - venn | convert -alpha Off -density 144x144 -geometry 50%x eps:- venn.tiff
+@end verbatim
+
+@cindex @code{nosafe}
+@cindex @code{safe}
+@cindex @code{system}
+If the option @code{-nosafe} is given, @code{Asymptote} runs
+in unsafe mode. This enables the @code{int system(string s)} and
+@code{int system(string[] s)} calls, allowing one
+to execute arbitrary shell commands. The default mode, @code{-safe},
+disables this call.
+
+@cindex offset
+@cindex @code{aligndir}
+A @code{PostScript} offset may be specified as a pair (in @code{bp}
+units) with the @code{-O} option:
+@verbatim
+asy -O 0,0 file
+@end verbatim
+@noindent
+The default offset is zero. The pair @code{aligndir} specifies
+an optional direction on the boundary of the page (mapped to the
+rectangle [-1,1]@math{\times}[-1,1]) to which the picture should be aligned; the
+default value @code{(0,0)} species center alignment.
+
+@cindex @code{-c}
+The @code{-c} (@code{command}) option may be used to execute arbitrary
+@code{Asymptote} code on the command line as a string. It is not
+necessary to terminate the string with a semicolon. Multiple @code{-c}
+options are executed in the order they are given. For example
+@verbatim
+asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
+@end verbatim
+@noindent
+produces the output
+@verbatim
+4
+0.841470984807897
+@end verbatim
+@noindent
+and draws a unitsquare of size @code{100}.
+
+@cindex @code{-u}
+The @code{-u} (@code{user}) option may be used to specify arbitrary
+@code{Asymptote} settings on the command line as a string. It is not
+necessary to terminate the string with a semicolon. Multiple @code{-u}
+options are executed in the order they are given. Command-line code like
+@code{-u x=sqrt(2)} can be executed within a module like this:
+@verbatim
+real x;
+usersetting();
+write(x);
+@end verbatim
+
+@cindex @code{-l}
+When the @code{-l} (@code{listvariables}) option is used with file
+arguments, only global functions and variables defined in the specified
+file(s) are listed.
+
+Additional debugging output is produced with each additional @code{-v} option:
+@table @code
+@item -v
+Display top-level module and final output file names.
+@item -vv
+Also display imported and included module names and final @code{LaTeX} and
+@code{dvips} processing information.
+@item -vvv
+Also output @code{LaTeX} bidirectional pipe diagnostics.
+@item -vvvv
+Also output knot guide solver diagnostics.
+@item -vvvvv
+Also output @code{Asymptote} traceback diagnostics.
+@end table
+
+@node Interactive mode, GUI, Options, Top
+@chapter Interactive mode
+@cindex interactive mode
+Interactive mode is entered by executing the command @code{asy} with
+no file arguments. When the @code{-multiline} option is disabled (the default),
+each line must be a complete @code{Asymptote} statement (unless
+explicitly continued by a final backslash character @code{\});
+it is not necessary to terminate input lines with a semicolon.
+If one assigns @code{settings.multiline=true}, interactive code can be
+entered over multiple lines; in this mode, the automatic termination of
+interactive input lines by a semicolon is inhibited. Multiline mode is useful
+for cutting and pasting @code{Asymptote} code directly into the
+interactive input buffer.
+
+@cindex @code{%}
+Interactive mode can be conveniently used as a calculator: expressions
+entered at the interactive prompt (for which a corresponding @code{write}
+function exists) are automatically evaluated and written to @code{stdout}.
+If the expression is non-writable, its type signature will be printed out
+instead. In either case, the expression can be referred to using the symbol
+@code{%} in the next line input at the prompt. For example:
+@verbatim
+> 2+3
+5
+> %*4
+20
+> 1/%
+0.05
+> sin(%)
+0.0499791692706783
+> currentpicture
+<picture currentpicture>
+> %.size(200,0)
+>
+@end verbatim
+
+@cindex @code{operator answer}
+The @code{%} symbol, when used as a variable, is shorthand for the identifier
+@code{operator answer}, which is set by the prompt after each written
+expression evaluation.
+
+
+The following special commands are supported only in interactive mode
+and must be entered immediately after the prompt:
+
+@table @code
+@cindex @code{help}
+@item help
+view the manual;
+@item erase
+erase @code{currentpicture};
+@cindex @code{input}
+@item reset
+reset the @code{Asymptote} environment to its initial state, except for
+changes to the settings module (@pxref{settings}), the current directory
+(@pxref{cd}), and breakpoints (@pxref{Debugger});
+@cindex @code{input}
+@item input FILE
+does an interactive reset, followed by the command
+@code{include FILE}. If the file name @code{FILE} contains
+nonalphanumeric characters, enclose it with quotation marks.
+A trailing semi-colon followed by optional @code{Asymptote} commands may
+be entered on the same line.
+@cindex @code{quit}
+@cindex @code{exit}
+@cindex @code{history}
+@anchor{history}
+@item quit
+exit interactive mode (@code{exit} is a synonym; the abbreviation
+@code{q} is also accepted unless there exists a top-level variable named
+@code{q}).
+@cindex @code{historylines}
+A history of the most recent 1000 (this number can be changed with the
+@code{historylines} configuration variable) previous commands will be retained
+in the file @code{.asy/history} in the user's home directory (unless
+the command-line option @code{-localhistory} was specified, in which case
+the history will be stored in the file @code{.asy_history} in the
+current directory).
+
+@end table
+
+Typing @code{ctrl-C} interrupts the execution of @code{Asymptote} code
+and returns control to the interactive prompt.
+
+Interactive mode is implemented with the @acronym{GNU} @code{readline} library,
+with command history and auto-completion. To customize the key bindings, see:
+@url{http://cnswww.cns.cwru.edu/php/chet/readline/readline.html}
+
+@cindex @code{Python} usage
+The file @code{asymptote.py} in the @code{Asymptote} system directory
+provides an alternative way of entering @code{Asymptote} commands
+interactively, coupled with the full power of @code{Python}. Copy this
+file to your @code{Python path} and then execute from within
+@code{Python 3} the commands
+@verbatim
+from asymptote import *
+g=asy()
+g.size(200)
+g.draw("unitcircle")
+g.send("draw(unitsquare)")
+g.fill("unitsquare, blue")
+g.clip("unitcircle")
+g.label("\"$O$\", (0,0), SW")
+@end verbatim
+
+@node GUI, PostScript to Asymptote, Interactive mode, Top
+@chapter Graphical User Interface
+@cindex graphical user interface
+@cindex @acronym{GUI}
+@cindex mouse
+@cindex wheel mouse
+@cindex @code{Button-1}
+@cindex @code{Button-2}
+@cindex @code{xasy}
+
+@menu
+* GUI installation:: Installing @code{xasy}
+* GUI usage:: Using @code{xasy} to edit objects
+@end menu
+
+In the event that adjustments to the final figure are required, the
+preliminary Graphical User Interface (@acronym{GUI}) @code{xasy} included with
+@code{Asymptote} allows you to move graphical objects and draw new ones.
+The modified figure can then be saved as a normal @code{Asymptote} file.
+
+@node GUI installation, GUI usage, GUI, GUI
+@section GUI installation
+@cindex GUI installation
+
+As @code{xasy} is written in the interactive scripting language
+@code{Python/Qt}, it requires @code{Python} (@url{http://www.python.org}),
+along with the @code{Python} packages @code{pyqt5}, @code{cson}, and
+@code{numpy}:
+
+@verbatim
+pip3 install cson numpy pyqt5 PyQt5.sip
+@end verbatim
+
+Pictures are deconstructed into the @acronym{SVG} image format.
+Since @code{Qt5} does not suport @code{SVG} clipping, you will need
+the @code{rsvg-convert} utility, which is part of the
+@code{librsvg2-tools} package on @code{UNIX} systems
+and the @code{librsvg} package on @code{MacOS}; under
+@code{Microsoft Windows}, it is available as
+
+@url{https://sourceforge.net/projects/tumagcc/files/rsvg-convert-2.40.20.7z}
+
+@node GUI usage, , GUI installation, GUI
+@section GUI usage
+@cindex GUI usage
+@cindex arrow keys
+@cindex mouse wheel
+@cindex @code{deconstruct}
+The arrow keys (or mouse wheel) are convenient for temporarily
+raising and lowering objects within @code{xasy}, allowing an object to
+be selected. Pressing the arrow keys will pan while the shift key is held
+and zoom while the control key is held. The mouse wheel will pan while
+the alt or shift keys is held and zoom while the control key is held.
+
+Deconstruction of compound objects (such as arrows) can be prevented
+by enclosing them within the commands
+@verbatim
+void begingroup(picture pic=currentpicture);
+void endgroup(picture pic=currentpicture);
+@end verbatim
+By default, the elements of a picture or frame will be grouped
+together on adding them to a picture. However, the elements of a frame
+added to another frame are not grouped together by default: their
+elements will be individually deconstructed (@pxref{add}).
+
+@node PostScript to Asymptote, Help, GUI, Top
+@chapter @code{PostScript} to @code{Asymptote}
+@cindex @code{pstoedit}
+The excellent @code{PostScript} editor @code{pstoedit} (version 3.50 or later;
+available from @url{http://sourceforge.net/projects/pstoedit/}) includes an
+@code{Asymptote} backend. Unlike virtually all other @code{pstoedit}
+backends, this driver includes native clipping, even-odd fill rule,
+@code{PostScript} subpath, and full image support. Here is an example:
+@noindent
+@code{asy -V @value{Datadir}/doc/asymptote/examples/venn.asy}
+@noindent
+@verbatim
+pstoedit -f asy venn.eps test.asy
+asy -V test
+@end verbatim
+
+@noindent
+If the line widths aren't quite correct, try giving @code{pstoedit} the
+@code{-dis} option.
+If the fonts aren't typeset correctly, try giving @code{pstoedit} the
+@code{-dt} option.
+
+@node Help, Debugger, PostScript to Asymptote, Top
+@chapter Help
+@cindex help
+@cindex forum
+
+A list of frequently asked questions (@acronym{FAQ}) is maintained at
+@quotation
+@url{http://asymptote.sourceforge.net/FAQ}
+@end quotation
+@noindent
+Questions on installing and using @code{Asymptote} that are not
+addressed in the @acronym{FAQ} should be sent to the
+@code{Asymptote} forum:
+@quotation
+@url{http://sourceforge.net/p/asymptote/discussion/409349}
+@end quotation
+@noindent
+Including an example that illustrates what you are trying to do will help
+you get useful feedback.
+@code{LaTeX} problems can often be diagnosed with the @code{-vv} or
+@code{-vvv} command-line options.
+Contributions in the form of patches or @code{Asymptote} modules can be
+posted here:
+@quotation
+@url{http://sourceforge.net/p/asymptote/patches}
+@end quotation
+@noindent
+To receive announcements of upcoming releases, please subscribe to
+@code{Asymptote} at
+@quotation
+@url{http://freecode.com/projects/asy}
+@end quotation
+@cindex bug reports
+@noindent
+If you find a bug in @code{Asymptote}, please check (if possible)
+whether the bug is still present in the latest @code{git}
+developmental code (@pxref{Git}) before submitting a bug
+report. New bugs can be reported at
+@quotation
+@url{https://github.com/vectorgraphics/asymptote/issues}
+@end quotation
+@noindent
+To see if the bug has already been fixed,
+check bugs with Status @code{Closed} and recent lines in
+@quotation
+@url{http://asymptote.sourceforge.net/ChangeLog}
+@end quotation
+@noindent
+
+@cindex stack overflow
+@cindex segmentation fault
+@cindex @code{libsigsegv}
+@code{Asymptote} can be configured with the optional @acronym{GNU} library
+@code{libsigsegv}, available from
+@url{http://libsigsegv.sourceforge.net}, which allows one to distinguish
+user-generated @code{Asymptote} stack overflows (@pxref{stack overflow})
+from true segmentation faults (due to internal C++ programming errors;
+please submit the @code{Asymptote} code that generates such segmentation
+faults along with your bug report).
+
+@node Debugger, Credits, Help, Top
+@chapter Debugger
+@cindex debugger
+Asymptote now includes a line-based (as opposed to code-based)
+debugger that can assist the user in following flow control. To set a
+break point in file @code{file} at line @code{line}, use the command
+
+@cindex @code{stop}
+@verbatim
+void stop(string file, int line, code s=quote{});
+@end verbatim
+@noindent
+The optional argument @code{s} may be used to conditionally set the variable
+@code{ignore} in @code{plain_debugger.asy} to @code{true}. For example, the
+first 10 instances of this breakpoint will be ignored (the
+variable @code{int count=0} is defined in @code{plain_debugger.asy}):
+@verbatim
+stop("test",2,quote{ignore=(++count <= 10);});
+@end verbatim
+
+To set a break point in file @code{file} at the first line containing
+the string @code{text}, use
+
+@verbatim
+void stop(string file, string text, code s=quote{});
+@end verbatim
+@noindent
+To list all breakpoints, use:
+@cindex @code{breakpoints}
+@verbatim
+void breakpoints();
+@end verbatim
+@noindent
+To clear a breakpoint, use:
+@cindex @code{clear}
+@verbatim
+void clear(string file, int line);
+@end verbatim
+@noindent
+To clear all breakpoints, use:
+@verbatim
+void clear();
+@end verbatim
+
+The following commands may be entered at the debugging prompt:
+
+@table @code
+@cindex @code{help}
+@item @code{h}
+help;
+@cindex @code{continue}
+@item @code{c}
+continue execution;
+
+@cindex @code{inst}
+@item @code{i}
+step to the next instruction;
+
+@cindex @code{step}
+@item @code{s}
+step to the next executable line;
+
+@cindex @code{next}
+@item @code{n}
+step to the next executable line in the current file;
+
+@cindex @code{file}
+@item @code{f}
+step to the next file;
+
+@cindex @code{return}
+@item @code{r}
+return to the file associated with the most recent breakpoint;
+
+@cindex @code{trace}
+@item @code{t}
+toggle tracing (@code{-vvvvv}) mode;
+
+@cindex @code{quit}
+@item @code{q}
+quit debugging and end execution;
+
+@cindex @code{exit}
+@item @code{x}
+exit the debugger and run to completion.
+
+@end table
+@noindent
+Arbitrary @code{Asymptote} code may also be entered at the debugging prompt;
+however, since the debugger is implemented with @code{eval}, currently
+only top-level (global) variables can be displayed or modified.
+
+The debugging prompt may be entered manually with the call
+@verbatim
+void breakpoint(code s=quote{});
+@end verbatim
+
+@node Credits, Index, Debugger, Top
+@chapter Acknowledgments
+@cindex acknowledgments
+
+Financial support for the development of @code{Asymptote} was generously
+provided by the Natural Sciences and Engineering Research Council of
+Canada, the Pacific Institute for Mathematical Sciences, and the
+University of Alberta Faculty of Science.
+
+We also would like to acknowledge the previous work of John D. Hobby,
+author of the program @code{MetaPost} that inspired the development of
+@code{Asymptote}, and Donald E. Knuth, author of @TeX{} and
+@code{MetaFont} (on which @code{MetaPost} is based).
+
+The authors of @code{Asymptote} are Andy Hammerlindl, John Bowman, and
+Tom Prince. Sean Healy designed the @code{Asymptote} logo. Other
+contributors include Orest Shardt, Jesse Frohlich, Michail Vidiassov,
+Charles Staats, Philippe Ivaldi, Olivier Guib@'e, Radoslav Marinov,
+Jeff Samuelson, Chris Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk,
+Martin Wiebusch, Stefan Knorr, and Supakorn ``Jamie'' Rassameemasmuang.
+
+@node Index, , Credits, Top
+@unnumbered Index
+
+@printindex cp
+
+@bye
+
+@c LocalWords: randMax Gaussrand asy cindex indices resized LaTeX TK latin au
+@c LocalWords: latexusage tex bbox PostScript subdirectory gcc emacs ASYDIR
+@c LocalWords: documentclass usepackage subpath shipout sqrt xN Mx bw AcroRd
+@c LocalWords: xscale xaxis yaxis BeginBar GIF postprocessing fpu de rpair xy
+@c LocalWords: ImageMagick cd asymptote Hy 0pt 1filll 's 3D 2D 'asy
+@c LocalWords: startup natively xasy tkinter VxN yingyang currentpicture toc
+@c LocalWords: MetaPost MetaFont Hammerlindl Healy texinfo autoload setq setf
+@c LocalWords: printindex setfilename settitle dircategory direntry titlepage
+@c LocalWords: vskip filll insertcopying ifnottex detailmenu alist augroup PQ
+@c LocalWords: bool behaviour facto zxf login Debian dev filetypedetect
+@c LocalWords: FFTW bp readline gv eps args Boehm gc evenoddoverlap png joe
+@c LocalWords: boolean initializer expi dir xpart ypart STL substring rfind
+@c LocalWords: pos substr strftime typedef pxref unitcircle yscale Bezier iff
+@c LocalWords: postcontrol precontrol atleast nullpath arclength arctime rgb
+@c LocalWords: dirtime currentpen colorspaces grayscale cmyk defaultpen x cx
+@c LocalWords: linetype longdashed dashdotted longdashdotted linewidth y XP
+@c LocalWords: fontsize defaultfilename keepAspect IgnoreAspect ise flushleft
+@c LocalWords: src dest XDR txt getc fout stdin stdout endl eof js prc ni
+@c LocalWords: Microsystem's eol exponentials postfix sayhi th Ubuntu
+@c LocalWords: sqr intop addby libm asin acos atan sinh tanh asinh acosh cbrt
+@c LocalWords: atanh fabs hypot fmod ceil srand dereferenced alice pete sqrtx
+@c LocalWords: eval fft csv runtime nonalphanumeric labely LeftTicks NoTicks
+@c LocalWords: RightTicks BottomTop LeftRight Ticksize UTF BufNewFile BufRead
+@c LocalWords: ticksize subintervals xlimits filetype plugin setlocal makeprg
+@c LocalWords: ylimits uncommented automin automax cp uninstall reals ecast
+@c LocalWords: scaleT unicode RightSide yx yy NoAlign legendmargin opic CCW
+@c LocalWords: arrowbar LeftSide EndBar BeginArrow lly feynman isi showtarget
+@c LocalWords: EndArrow BeginArcArrow EndArcArrow ArcArrow ArcArrows NoFill
+@c LocalWords: filldraw fillpen drawpen errorformat bigsquare bezier darkblue
+@c LocalWords: quartercircle darkgreen lightblue urx ury texpreamble sgn texi
+@c LocalWords: lineargraph datagraph vertices parametricgraph uncomment ggv
+@c LocalWords: loggraph generalaxis texhash arrowsize arrowangle arrowlength
+@c LocalWords: SuppressQuiet MoveQuiet LIBREADLINE config MacOS prebuilt
+@c LocalWords: ghostview gsview SIGHUP PDF acroread xpdf cutbefore strptime
+@c LocalWords: libsigsegv intersectionpoint dotfactor vv firstcut pq logticks
+@c LocalWords: Unisys dvips vvv vvvv vvvvv traceback lastcut cutafter infodir
+@c LocalWords: zxvf xargs cond polargraph xmin xmax plabel YZero labelling ln
+@c LocalWords: ymin ymax XZero xequals tickmin tickmax unlabelled se pq pena
+@c LocalWords: yequals Nobre Barbarosie Schwaiger nearearth conicurv Wiebusch
+@c LocalWords: unfill posterSize ngraph interpolatetype ctrl dt pic getint Ai
+@c LocalWords: NNE jxf linecap linejoin unitsquare shadedtiling ei nomarker
+@c LocalWords: westnile minipage ra penb paletteticks drawline nV FillDraw uv
+@c LocalWords: susceptibleM flushright secondaryX secondaryY secondaryaxis tt
+@c LocalWords: titlelabel columnlabel rb xtick ytick labelx XEquals YEquals
+@c LocalWords: treetest eetomumu fermi backend pstoedit drawtree xFF MSDOS gz
+@c LocalWords: vimrc CFLAGS verbatiminclude online noindent bezier superpath
+@c LocalWords: evenodd squarecap roundcap extendcap miterjoin roundjoin NFSS
+@c LocalWords: beveljoin fillrule zerowinding insideness lineskip cmr pcrr Hx
+@c LocalWords: AvantGarde Bookman Helvetica NewCenturySchoolBook minbound pdf
+@c LocalWords: Palatino TimesRoman ZapfChancery ZapfDingbats german basealign
+@c LocalWords: nondeconstructed backends usr venn labelsquare nobasealign dp
+@c LocalWords: NoMargin BeginMargin EndMargin BeginPenMargin EndPenMargin dm
+@c LocalWords: PenMargin PenMargins TrueMargin labelmargin errorbars errorbar
+@c LocalWords: dpx dpy dmx dmy barsize arrowsize BeginDotMargin DotMargin acc
+@c LocalWords: EndDotMargin DotMargins NColors BWRainbow colorspace labelled
+@c LocalWords: PaletteTicks defaultformat leastsquares bjam fprintf endgroup
+@c LocalWords: begingroup xmargin ymargin pbox box ellipse wget exe Gouraud
+@c LocalWords: multithreaded newframe init emph nums concat xline yline zpart
+@c LocalWords: colatitude zscale cosh nullpen MetaFontbook cyclicflag FreeBSD
+@c LocalWords: nodeps Ghostgum beginlabel endlabel pTick ptick loggrid SAS dy
+@c LocalWords: currentprojection latticeshading subpictures colinear unitcube
+@c LocalWords: Autoscaling solveQuadratic MidArrow MidArcArrow Prebuilt url
+@c LocalWords: pdftex comment getstring getstringprefix getreal defaultS hsv
+@c LocalWords: ticklocate autoscaleT autoscaling vectorfield autolimits dvi
+@c LocalWords: zlimits inline dvipdf hyperdvi autoconf gui zerowindingoverlap
+@c LocalWords: prepended intMax quadraticroots cubicroots filltype prepend dx
+@c LocalWords: ticklabel popup UnFill markroutine marknodes markuniform erf
+@c LocalWords: intersectpoint cyrillic mathtext russian brokenaxis Datadir ds
+@c LocalWords: resetdefaultpen latticeshade axialshade radialshade erfc det
+@c LocalWords: gouraudshade unescaped nmesh surfacepen getpair MikTeX dw YZ
+@c LocalWords: meshpen localhistory axisT roundedpath unitsize aSin accel pre
+@c LocalWords: fontcommand makepen aCos aTan Knorr roundpath BeginPoint nView
+@c LocalWords: MidPoint EndPoint nmask antialiasing autoplain batchMask libgc
+@c LocalWords: batchView clearGUI ignoreGUI interactiveMask interactiveView
+@c LocalWords: listvariables outformat parseonly prepending psviewer nCircle
+@c LocalWords: pdfviewer papertype tabcompletion noautoplain plugins Teixeira
+@c LocalWords: embeddedmovie historylines RadialShade penc penr CJK tgz GPL
+@c LocalWords: legendlinelength legendskip USERPROFILE LDFLAGS currentlight
+@c LocalWords: subsampled sinc kai AtBeginDocument GBK clearpage lasy texpath
+@c LocalWords: AtEndDocument zaxis maxbound truepoint paperwidth paperheight
+@c LocalWords: GSL deriv texcolors fixedscaling UpsideDown texreset slidedemo
+@c LocalWords: subitem newslide realMin realMax realEpsilon realDigits gsl dh
+@c LocalWords: obliqueX asycolors monthaxis xautoscale yautoscale zautoscale
+@c LocalWords: obliqueZ obliqueY cylinderskeleton block llcorner dr py nx CPU
+@c LocalWords: loc topleft topright bottomleft bottomright flowrectangle UTC
+@c LocalWords: chartblock flowdiamond flowcircle xlabel BezierSurface el xyz
+@c LocalWords: flowroundrectangle flowbevel flowpath drawflow blocks ny cpu
+@c LocalWords: multipleView usersetting mediumgray flowchartdemo ylabel nv xf
+@c LocalWords: zlabel slopefields cputime roundrectangle slopefield libgccpp
+@c LocalWords: tickfactor USERNAME writeable imagecontour logimage Dumoulin's
+@c LocalWords: NoCrop parametricsurface realmult SoftLight HardLight interp
+@c LocalWords: ColorDodge ColorBurn Ivaldi buildcycle autorotate mexicanhat
+@c LocalWords: Gouraudcontour pdflatex preconfigured perline linelength hskip
+@c LocalWords: penimage filloutside legendhskip legendvskip maxwidth CDlabel
+@c LocalWords: tensorshade MPEG framepoint nonfunction Radoslav Marinov Mepis
+@c LocalWords: Pienaar Melenchuk finalout Linspire Dpkg sudo dpkg dtx Tcount
+@c LocalWords: windingnumber clickable pdfmovie dfn du animationdelay fprime
+@c LocalWords: slidemovies ifdraft embeddedu externalmovie headerpen bodypen
+@c LocalWords: GaussianSurface multiline binarytree tridiagonal portably AIX
+@c LocalWords: binarytreetest Henning subsample breakpoint locator wireframe
+@c LocalWords: labelpath intersectionpoints PSTricks pstextpath curvedlabel
+@c LocalWords: LeftJustified RightJustified tickmodifier gunzip gmake IRIX dv
+@c LocalWords: texcommand RET SITEDIR filegraph pathmarkers POSIX binput AOB
+@c LocalWords: nonportable markinterval stickframe circlebarframe tix
+@c LocalWords: crossframe tildeframe markangle StickIntervalMarker gswin expm
+@c LocalWords: CrossIntervalMarker CircleBarIntervalMarker Ghostscript syzygy
+@c LocalWords: TildeIntervalMarker autoimport calculateTransform bitwise tk
+@c LocalWords: headersize bodysize minheaderwidth minheaderheight minwidth ZX
+@c LocalWords: minbodywidth minbodyheight minheight mindiameter reltime PNG
+@c LocalWords: relpoint Syzygy syzygies seekeof splinetype notaknot slopea ZY
+@c LocalWords: slopeb nonperiodic circlescale MarkFill ScaleX ScaleY xformat
+@c LocalWords: onecontour multicontour irregularcontour dvipsOptions saveline
+@c LocalWords: dirSpecifier controlSpecifier tensionSpecifier atleastflag bsp
+@c LocalWords: curlSpecifier cputimeformat initializers arbitary redeclaring
+@c LocalWords: firstname lastname multdiagonal Raphson OmitTick OmitFormat sp
+@c LocalWords: NoZero NoZeroFormat abbrevation gsOptions namespace redeclared
+@c LocalWords: atLeast intMin globalwrite quarticroots deconsruct substrings
+@c LocalWords: usleep currentpatterns trailingzero Orest Shardt DefaultHead
+@c LocalWords: SimpleHead HookHead TeXHead multipage NURBS inlinemovie dxmax
+@c LocalWords: simpson NoBox truesize autoscale shadestroke recurses mintimes
+@c LocalWords: nonoverlapping texengine maxtimes maxheight pdb TEXMFCONFIG Jn
+@c LocalWords: piecewisestraight unitrand graphmarkers antialias nolight newl
+@c LocalWords: Delaunay Shewchuk convertOptions APPDATA pdfreload tempFile Yn
+@c LocalWords: pdfreloadOptions deferred OpenGL Phong Blinn renderer unitbox
+@c LocalWords: bezulate Shardt's rasterized viewport unitdisk unitplane devel
+@c LocalWords: unitcylinder unitcone solidcone unitfrustum unitsphere nslices
+@c LocalWords: DPostScript YZZero externalprc nonrendered nosafe KDE
+@c LocalWords: unithemisphere versa XYplane xypart unitsolidcone YZEquals xml
+@c LocalWords: XZEquals XYEquals XZZero XYZero InTicks OutTicks InOutTicks
+@c LocalWords: fitscreen planeproject strokepath meshlight nullpens arrowdir
+@c LocalWords: diffusepen emissivepen specularpen arrowbarb keyval
+@c LocalWords: hstretch vstretch roundbox nonconvex miterlimit basealigin cmd
+@c LocalWords: maxviewport maxtile antialiased sphericalharmonic attachfile
+@c LocalWords: vertexshading smoothelevation glOptions iconified iconify kate
+@c LocalWords: psviewerOptions pdfviewerOptions viewportmargin asyattach SVG
+@c LocalWords: multisampling autogen multisample coloredpath relstep flowdir
+@c LocalWords: colortype coloredSegments coloredNodes trefoilknot scaledgraph
+@c LocalWords: minblockwidth minblockheight mincirclediameter nonassociative
+@c LocalWords: nonintegral gettriple enablerepo hexadecimal XeLaTeX xelatex
+@c LocalWords: dvipdfmx autoadjust viewportsize viewportwidth viewportheight
+@c LocalWords: subregions nonsimply functionshade shader floatingdisk TopView
+@c LocalWords: functionshading maxlength LeftView odetest RadialShadeDraw CLZ
+@c LocalWords: vectorfieldsphere RightView FrontView BackView BottomView CTZ
+@c LocalWords: addViews outprefix addAllViews xsplinetype ysplinetype rotateX
+@c LocalWords: usplinetype vsplinetype leftbutton middlebutton rightbutton
+@c LocalWords: rotateY rotateZ wheelup zoomin wheeldown zoomout TeXLive pnorm
+@c LocalWords: viewportshift signedint signedness psview multiplatform nowarn
+@c LocalWords: singlereal singleint writeoverloaded dvisvg reddash lexorder
+@c LocalWords: bigdiagonal autobillboard dvisvgm maxtiles hyperrefOptions xdr
+@c LocalWords: setpagesize pdfborder controlsystem OmitTickInterval SixViews
+@c LocalWords: OmitTickIntervals tickmodifiers autorotated SixViewsUS latexmk
+@c LocalWords: ThreeViewsUS ThreeViewsFR SixViewsFR ThreeViews partialsum
+@c LocalWords: defaultrender Vidiassov latexmkrc mktemp DOSendl DOSnewl perl
+@c LocalWords: filename asyinclude latemk penfunctionimage Affine decrement
+@c LocalWords: affine Redisplay redisplay isnan radians defaultseparator Jens
+@c LocalWords: ascii piecewise arcpoint spacings tilings sncndn resizing
+@c LocalWords: differentiable vectorization vectorized asydir normals quartic
+@c LocalWords: wavepacket kerned parametrized specular hyperboloid Bourke's
+@c LocalWords: Michail 0pt 1filll 's 3D latin1 labelpath3 2D graph3
+@c LocalWords: grid3 contour3 x86_64 psv a4 gsview32 freeglut 'load '
+@c LocalWords: 'asy 'lasy 'auto 5bp 1cm sqrtx01 4g extenda extendb
+@c LocalWords: bb llx 2S 100pt 3t bezier2 bool3 x0 angle1 angle2 z1
+@c LocalWords: z2 before' struct X11 x11colors type1cm 12pt OT1 5mm
+@c LocalWords: cmr12 x' y' xsize ysize 25cm s1 s2 neighbourhood u''
+@c LocalWords: s'' 3x 5x 3y 602e 2x 2y 3sin 10cm 204e addby7 10x Ai
+@c LocalWords: only'' pow10 log10 expm1 log1p atan2 0pt 1filll 's '
+@c LocalWords: x1 x2 graph2d attachfile2 n0 P0 n1 P1 markers1 3D 2D
+@c LocalWords: interpolate1 markers2 inlinemovie3 media9 U3D T2A 5E
+@c LocalWords: embeddedu3d curvedlabel3 value2 tickvalue inner'' 2N
+@c LocalWords: lineargraph0 scalings log2 log2graph 5cm BWRainbow2
+@c LocalWords: guide3 path3 unitcircle3 2E 2n noV 100d PostScript3D
+@c LocalWords: size3 fit3 theta1 phi1 theta2 phi2 v1 v2 unitsquare3
+@c LocalWords: t1 t2 5z 5y transform3 identity4 xscale3 yscale3 0pt
+@c LocalWords: zscale3 scale3 join3 BeginBar3 EndBar3 Bar3 Bars3 's
+@c LocalWords: BeginArrow3 MidArrow3 EndArrow3 Arrow3 Arrows3 axes3
+@c LocalWords: BeginArcArrow3 MidArcArrow3 EndArcArrow3 ArcArrow3 '
+@c LocalWords: ArcArrows3 DefaultHead3 HookHead3 TeXHead3 HookHead2
+@c LocalWords: DefaultHead2 TeXHead2 arrows3 NoMargin3 BeginMargin3
+@c LocalWords: EndMargin3 Margin3 Margins3 BeginPenMargin2 xaxis3 '
+@c LocalWords: EndPenMargin2 PenMargin2 PenMargins2 BeginPenMargin3
+@c LocalWords: EndPenMargin3 PenMargin3 PenMargins3 BeginDotMargin3
+@c LocalWords: EndDotMargin3 DotMargin3 DotMargins3 TrueMargin3 3D
+@c LocalWords: yaxis3 zaxis3 ticks3 NoTicks3 arrowbar3 type2 axis3
+@c LocalWords: generalaxis3 vectorfield3 margin3 grid3xyz 5unit 2D
+@c LocalWords: slopefield1 144x144 1filll 'load 'asy 'lasy 'auto 4g
+@c LocalWords: libgs 'load 'asy 'lasy 'auto 5bp 1cm 2S 100pt 3t 5mm
+@c LocalWords: bracedefaultratio incircle 12pt 25cm 3x 5x 3y 602e '
+@c LocalWords: 2x 2y 3sin 10cm 204e 10x Ai 5E offaxis 'load 'lasy '
+@c LocalWords: 5cm 2N 2E 2n 100d 5z 5y 5unit dvisvgmOptions 144x144
+@c LocalWords: 4g texengines coplanar 0pt 1filll 's 3D 2D 'load 5bp
+@c LocalWords: insphere cospherical 5unit luatex lualatex 'asy 1cm
+@c LocalWords: 'lasy 'auto 4g 2S 100pt 3t 12pt 5mm 25cm 3x 5x 3y 2x
+@c LocalWords: 602e 2y 3sin 10cm 204e 10x Ai Ai Ai Ai Ai Ai Ai Ai '
+@c LocalWords: unnormalized 5E 5cm 2N 2E 2n 100d 5z 5y 0pt 1filll '
+@c LocalWords: 5unit 144x144 aligndir smoothcontour3 's 3D 2D cmake
+@c LocalWords: 'load 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t nan 3x
+@c LocalWords: 12pt 5mm 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x Ai
+@c LocalWords: Ai Ai Ai Ai Ai Ai Ai 5E 5cm 2N 2E 2n 100d 5z 5y nz
+@c LocalWords: 5unit Staats implicitsurface overlapedges maxdepth
+@c LocalWords: through'' genustwo 144x144 0pt 1filll 's 3D 2D 'load
+@c LocalWords: 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t 12pt 5mm 3x
+@c LocalWords: 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x Ai Ai Ai Ai
+@c LocalWords: Ai Ai Ai Ai 5E 5cm 2N 2E 2n 100d 5z 5y 5unit 144x144
+@c LocalWords: Frohlich
diff --git a/graphics/asymptote/doc/axis3.asy b/graphics/asymptote/doc/axis3.asy
new file mode 100644
index 0000000000..90cbdc6ad0
--- /dev/null
+++ b/graphics/asymptote/doc/axis3.asy
@@ -0,0 +1,12 @@
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=perspective(5,2,2);
+
+scale(Linear,Linear,Log);
+
+xaxis3("$x$",0,1,red,OutTicks(2,2));
+yaxis3("$y$",0,1,red,OutTicks(2,2));
+zaxis3("$z$",1,30,red,OutTicks(beginlabel=false));
diff --git a/graphics/asymptote/doc/bezier.asy b/graphics/asymptote/doc/bezier.asy
new file mode 100644
index 0000000000..1c168042c0
--- /dev/null
+++ b/graphics/asymptote/doc/bezier.asy
@@ -0,0 +1 @@
+label("$(1-t)^3z_0+3t(1-t)^2c_0+3t^2(1-t)c_1+t^3z_1\qquad 0\le t\le 1$.",(0,0));
diff --git a/graphics/asymptote/doc/bezier2.asy b/graphics/asymptote/doc/bezier2.asy
new file mode 100644
index 0000000000..745fb649dd
--- /dev/null
+++ b/graphics/asymptote/doc/bezier2.asy
@@ -0,0 +1,21 @@
+import beziercurve;
+
+pair midpoint(pair a, pair b) {return interp(a,b,0.5);}
+
+pair m0=midpoint(z0,c0);
+pair m1=midpoint(c0,c1);
+pair m2=midpoint(c1,z1);
+
+draw(m0--m1--m2,dashed);
+dot("$m_0$",m0,NW,red);
+dot("$m_1$",m1,N,red);
+dot("$m_2$",m2,red);
+
+pair m3=midpoint(m0,m1);
+pair m4=midpoint(m1,m2);
+pair m5=midpoint(m3,m4);
+
+draw(m3--m4,dashed);
+dot("$m_3$",m3,NW,red);
+dot("$m_4$",m4,NE,red);
+dot("$m_5$",m5,N,red);
diff --git a/graphics/asymptote/doc/beziercurve.asy b/graphics/asymptote/doc/beziercurve.asy
new file mode 100644
index 0000000000..338109bbd6
--- /dev/null
+++ b/graphics/asymptote/doc/beziercurve.asy
@@ -0,0 +1,12 @@
+size(400);
+pair z0=(0,0);
+pair c0=(1,1);
+pair c1=(2,1);
+pair z1=(3,0);
+draw(z0..controls c0 and c1 .. z1,blue);
+
+draw(z0--c0--c1--z1,dashed);
+dot("$z_0$",z0,W,red);
+dot("$c_0$",c0,NW,red);
+dot("$c_1$",c1,NE,red);
+dot("$z_1$",z1,red);
diff --git a/graphics/asymptote/doc/bigdiagonal.asy b/graphics/asymptote/doc/bigdiagonal.asy
new file mode 100644
index 0000000000..7242b7ae84
--- /dev/null
+++ b/graphics/asymptote/doc/bigdiagonal.asy
@@ -0,0 +1,2 @@
+size(0,100.5);
+draw((0,0)--(2,1),Arrow);
diff --git a/graphics/asymptote/doc/binarytreetest.asy b/graphics/asymptote/doc/binarytreetest.asy
new file mode 100644
index 0000000000..af55292e4a
--- /dev/null
+++ b/graphics/asymptote/doc/binarytreetest.asy
@@ -0,0 +1,13 @@
+import binarytree;
+
+picture pic,pic2;
+
+binarytree bt=binarytree(1,2,4,nil,5,nil,nil,0,nil,nil,3,6,nil,nil,7);
+draw(pic,bt,condensed=false);
+
+binarytree st=searchtree(10,5,2,1,3,4,7,6,8,9,15,13,12,11,14,17,16,18,19);
+draw(pic2,st,blue,condensed=true);
+
+add(pic.fit(),(0,0),10N);
+add(pic2.fit(),(0,0),10S);
+
diff --git a/graphics/asymptote/doc/brokenaxis.asy b/graphics/asymptote/doc/brokenaxis.asy
new file mode 100644
index 0000000000..9de9fa414d
--- /dev/null
+++ b/graphics/asymptote/doc/brokenaxis.asy
@@ -0,0 +1,25 @@
+import graph;
+
+size(200,150,IgnoreAspect);
+
+// Break the x axis at 3; restart at 8:
+real a=3, b=8;
+
+// Break the y axis at 100; restart at 1000:
+real c=100, d=1000;
+
+scale(Broken(a,b),BrokenLog(c,d));
+
+real[] x={1,2,4,6,10};
+real[] y=x^4;
+
+draw(graph(x,y),red,MarkFill[0]);
+
+xaxis("$x$",BottomTop,LeftTicks(Break(a,b)));
+yaxis("$y$",LeftRight,RightTicks(Break(c,d)));
+
+label(rotate(90)*Break,(a,point(S).y));
+label(rotate(90)*Break,(a,point(N).y));
+label(Break,(point(W).x,ScaleY(c)));
+label(Break,(point(E).x,ScaleY(c)));
+
diff --git a/graphics/asymptote/doc/colo-asy.tex b/graphics/asymptote/doc/colo-asy.tex
new file mode 100644
index 0000000000..a9f2a9b636
--- /dev/null
+++ b/graphics/asymptote/doc/colo-asy.tex
@@ -0,0 +1,84 @@
+%D \module
+%D [ file=colo-asy,
+%D version=2009.05.20,
+%D title=\CONTEXT\ Color Macros,
+%D subtitle=\asymptote\ Colors,
+%D author=\asymptote\ developers,
+%D date=\currentdate,
+%D copyright={put something here}]
+%C
+%C any copyright notice may go here
+
+% call with \setupcolor[asy]
+
+\definecolor [cyan] [c=1.00,m=0.00,y=0.00,k=0.00]
+\definecolor [magenta] [c=0.00,m=1.00,y=0.00,k=0.00]
+\definecolor [yellow] [c=0.00,m=0.00,y=1.00,k=0.00]
+\definecolor [black] [c=0.00,m=0.00,y=0.00,k=1.00]
+
+\definecolor [white] [c=0.00,m=0.00,y=0.00,k=0.00]
+\definecolor [gray] [c=0.00,m=0.00,y=0.00,k=0.50]
+
+\definecolor [red] [c=0.00,m=1.00,y=1.00,k=0.00]
+\definecolor [green] [c=1.00,m=0.00,y=1.00,k=0.00]
+\definecolor [blue] [c=1.00,m=1.00,y=0.00,k=0.00]
+
+\definecolor [palered] [c=0.00,m=0.25,y=0.25,k=0.00]
+\definecolor [palegreen] [c=0.25,m=0.00,y=0.25,k=0.00]
+\definecolor [paleblue] [c=0.25,m=0.25,y=0.00,k=0.00]
+\definecolor [palecyan] [c=0.25,m=0.00,y=0.00,k=0.00]
+\definecolor [palemagenta] [c=0.00,m=0.25,y=0.00,k=0.00]
+\definecolor [paleyellow] [c=0.00,m=0.00,y=0.25,k=0.00]
+\definecolor [palegray] [c=0.00,m=0.00,y=0.00,k=0.05]
+\definecolor [lightred] [c=0.00,m=0.50,y=0.50,k=0.00]
+\definecolor [lightgreen] [c=0.50,m=0.00,y=0.50,k=0.00]
+\definecolor [lightblue] [c=0.50,m=0.50,y=0.00,k=0.00]
+\definecolor [lightcyan] [c=0.50,m=0.00,y=0.00,k=0.00]
+\definecolor [lightmagenta] [c=0.00,m=0.50,y=0.00,k=0.00]
+\definecolor [lightyellow] [c=0.00,m=0.00,y=0.50,k=0.00]
+\definecolor [lightgray] [c=0.00,m=0.00,y=0.00,k=0.10]
+\definecolor [mediumred] [c=0.00,m=0.75,y=0.75,k=0.00]
+\definecolor [mediumgreen] [c=0.75,m=0.00,y=0.75,k=0.00]
+\definecolor [mediumblue] [c=0.75,m=0.75,y=0.00,k=0.00]
+\definecolor [mediumcyan] [c=0.75,m=0.00,y=0.00,k=0.00]
+\definecolor [mediummagenta] [c=0.00,m=0.75,y=0.00,k=0.00]
+\definecolor [mediumyellow] [c=0.00,m=0.00,y=0.75,k=0.00]
+\definecolor [mediumgray] [c=0.00,m=0.00,y=0.00,k=0.25]
+\definecolor [heavyred] [c=0.00,m=1.00,y=1.00,k=0.25]
+\definecolor [heavygreen] [c=1.00,m=0.00,y=1.00,k=0.25]
+\definecolor [heavyblue] [c=1.00,m=1.00,y=0.00,k=0.25]
+\definecolor [heavycyan] [c=1.00,m=0.00,y=0.00,k=0.25]
+\definecolor [heavymagenta] [c=0.00,m=1.00,y=0.00,k=0.25]
+\definecolor [lightolive] [c=0.00,m=0.00,y=1.00,k=0.25]
+\definecolor [heavygray] [c=0.00,m=0.00,y=0.00,k=0.75]
+\definecolor [deepred] [c=0.00,m=1.00,y=1.00,k=0.50]
+\definecolor [deepgreen] [c=1.00,m=0.00,y=1.00,k=0.50]
+\definecolor [deepblue] [c=1.00,m=1.00,y=0.00,k=0.50]
+\definecolor [deepcyan] [c=1.00,m=0.00,y=0.00,k=0.50]
+\definecolor [deepmagenta] [c=0.00,m=1.00,y=0.00,k=0.50]
+\definecolor [olive] [c=0.00,m=0.00,y=1.00,k=0.50]
+\definecolor [deepgray] [c=0.00,m=0.00,y=0.00,k=0.90]
+\definecolor [darkred] [c=0.00,m=1.00,y=1.00,k=0.75]
+\definecolor [darkgreen] [c=1.00,m=0.00,y=1.00,k=0.75]
+\definecolor [darkblue] [c=1.00,m=1.00,y=0.00,k=0.75]
+\definecolor [darkcyan] [c=1.00,m=0.00,y=0.00,k=0.75]
+\definecolor [darkmagenta] [c=0.00,m=1.00,y=0.00,k=0.75]
+\definecolor [darkolive] [c=0.00,m=0.00,y=1.00,k=0.75]
+\definecolor [darkgray] [c=0.00,m=0.00,y=0.00,k=0.95]
+\definecolor [orange] [c=0.00,m=0.50,y=1.00,k=0.00]
+\definecolor [fuchsia] [c=0.00,m=1.00,y=0.50,k=0.00]
+\definecolor [chartreuse] [c=0.50,m=0.00,y=1.00,k=0.00]
+\definecolor [springgreen] [c=1.00,m=0.00,y=0.50,k=0.00]
+\definecolor [purple] [c=0.50,m=1.00,y=0.00,k=0.00]
+\definecolor [royalblue] [c=1.00,m=0.50,y=0.00,k=0.00]
+\definecolor [salmon] [c=0.00,m=0.50,y=0.50,k=0.00]
+\definecolor [brown] [c=0.00,m=1.00,y=1.00,k=0.50]
+\definecolor [darkbrown] [c=0.00,m=1.00,y=1.00,k=0.75]
+\definecolor [pink] [c=0.00,m=0.25,y=0.00,k=0.00]
+\definecolor [palegrey] [c=0.00,m=0.00,y=0.00,k=0.05]
+\definecolor [lightgrey] [c=0.00,m=0.00,y=0.00,k=0.10]
+\definecolor [mediumgrey] [c=0.00,m=0.00,y=0.00,k=0.25]
+\definecolor [grey] [c=0.00,m=0.00,y=0.00,k=0.50]
+\definecolor [heavygrey] [c=0.00,m=0.00,y=0.00,k=0.50]
+\definecolor [deepgrey] [c=0.00,m=0.00,y=0.00,k=0.90]
+\definecolor [darkgrey] [c=0.00,m=0.00,y=0.00,k=0.95]
diff --git a/graphics/asymptote/doc/colons.asy b/graphics/asymptote/doc/colons.asy
new file mode 100644
index 0000000000..3cdb6b4296
--- /dev/null
+++ b/graphics/asymptote/doc/colons.asy
@@ -0,0 +1 @@
+draw((0,0){up}::(100,25){right}::(200,0){down});
diff --git a/graphics/asymptote/doc/colors.asy b/graphics/asymptote/doc/colors.asy
new file mode 100644
index 0000000000..2f2bf988d0
--- /dev/null
+++ b/graphics/asymptote/doc/colors.asy
@@ -0,0 +1,115 @@
+int i=0;
+int j=0;
+
+bool components=false;
+
+pen p;
+
+void col(... string[] s) {
+ for(int n=0; n < s.length; ++n) {
+ j -= 10;
+ string s=s[n];
+ eval("p="+s+";",true);
+ if(components) {
+ real[] a=colors(p);
+ for(int i=0; i < a.length; ++i)
+ s += " "+(string) a[i];
+ }
+ label(s,(i+10,j),E);
+ filldraw(box((i,j-5),(i+10,j+5)),p);
+ }
+}
+
+col("palered");
+col("lightred");
+col("mediumred");
+col("red");
+col("heavyred");
+col("brown");
+col("darkbrown");
+j -= 10;
+
+col("palegreen");
+col("lightgreen");
+col("mediumgreen");
+col("green");
+col("heavygreen");
+col("deepgreen");
+col("darkgreen");
+j -= 10;
+
+col("paleblue");
+col("lightblue");
+col("mediumblue");
+col("blue");
+col("heavyblue");
+col("deepblue");
+col("darkblue");
+j -= 10;
+
+i += 150;
+j=0;
+
+col("palecyan");
+col("lightcyan");
+col("mediumcyan");
+col("cyan");
+col("heavycyan");
+col("deepcyan");
+col("darkcyan");
+j -= 10;
+
+col("pink");
+col("lightmagenta");
+col("mediummagenta");
+col("magenta");
+col("heavymagenta");
+col("deepmagenta");
+col("darkmagenta");
+j -= 10;
+
+col("paleyellow");
+col("lightyellow");
+col("mediumyellow");
+col("yellow");
+col("lightolive");
+col("olive");
+col("darkolive");
+j -= 10;
+
+col("palegray");
+col("lightgray");
+col("mediumgray");
+col("gray");
+col("heavygray");
+col("deepgray");
+col("darkgray");
+j -= 10;
+
+i += 150;
+j=0;
+
+col("black");
+col("white");
+j -= 10;
+
+col("orange");
+col("fuchsia");
+j -= 10;
+col("chartreuse");
+col("springgreen");
+j -= 10;
+col("purple");
+col("royalblue");
+j -= 10;
+
+col("Cyan");
+col("Magenta");
+col("Yellow");
+col("Black");
+
+j -= 10;
+
+col("cmyk(red)");
+col("cmyk(blue)");
+col("cmyk(green)");
diff --git a/graphics/asymptote/doc/cube.asy b/graphics/asymptote/doc/cube.asy
new file mode 100644
index 0000000000..acfecfdd7d
--- /dev/null
+++ b/graphics/asymptote/doc/cube.asy
@@ -0,0 +1,15 @@
+import three;
+
+currentprojection=orthographic(5,4,2,center=true);
+
+size(5cm);
+size3(3cm,5cm,8cm);
+
+draw(unitbox);
+
+dot(unitbox,red);
+
+label("$O$",(0,0,0),NW);
+label("(1,0,0)",(1,0,0),S);
+label("(0,1,0)",(0,1,0),E);
+label("(0,0,1)",(0,0,1),Z);
diff --git a/graphics/asymptote/doc/cylinderskeleton.asy b/graphics/asymptote/doc/cylinderskeleton.asy
new file mode 100644
index 0000000000..7dcd1c8119
--- /dev/null
+++ b/graphics/asymptote/doc/cylinderskeleton.asy
@@ -0,0 +1,6 @@
+import solids;
+
+size(0,100);
+
+revolution r=cylinder(O,1,1.5,Y+Z);
+draw(r,heavygreen);
diff --git a/graphics/asymptote/doc/datagraph.asy b/graphics/asymptote/doc/datagraph.asy
new file mode 100644
index 0000000000..62cca8ea89
--- /dev/null
+++ b/graphics/asymptote/doc/datagraph.asy
@@ -0,0 +1,12 @@
+import graph;
+
+size(200,150,IgnoreAspect);
+
+real[] x={0,1,2,3};
+real[] y=x^2;
+
+draw(graph(x,y),red);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,
+ RightTicks(Label(fontsize(8pt)),new real[]{0,4,9}));
diff --git a/graphics/asymptote/doc/diagonal.asy b/graphics/asymptote/doc/diagonal.asy
new file mode 100644
index 0000000000..32f3fc04be
--- /dev/null
+++ b/graphics/asymptote/doc/diagonal.asy
@@ -0,0 +1 @@
+draw((0,0)--(100,100));
diff --git a/graphics/asymptote/doc/diatom.asy b/graphics/asymptote/doc/diatom.asy
new file mode 100644
index 0000000000..23673dcadf
--- /dev/null
+++ b/graphics/asymptote/doc/diatom.asy
@@ -0,0 +1,129 @@
+import graph;
+
+size(15cm,12cm,IgnoreAspect);
+
+real minpercent=20;
+real ignorebelow=0;
+string data="diatom.csv";
+string[] group;
+int[] begin,end;
+
+defaultpen(fontsize(8pt)+overwrite(MoveQuiet));
+
+file in=input(data).line().csv();
+
+string depthlabel=in;
+string yearlabel=in;
+string[] taxa=in;
+group=in;
+begin=in;
+real[] depth;
+int[] year;
+real[][] percentage;
+
+while(true) {
+ real d=in;
+ if(eof(in)) break;
+ depth.push(d);
+ year.push(in);
+ percentage.push(in);
+}
+
+percentage=transpose(percentage);
+real depthmin=-min(depth);
+real depthmax=-max(depth);
+
+int n=percentage.length;
+
+int final;
+for(int taxon=0; taxon < n; ++taxon) {
+ real[] P=percentage[taxon];
+ if(max(P) < ignorebelow) continue;
+ final=taxon;
+}
+
+real angle=45;
+real L=3cm;
+pair Ldir=L*dir(angle);
+real ymax=-infinity;
+real margin=labelmargin();
+
+real location=0;
+
+for(int i=0; i < begin.length-1; ++i) end[i]=begin[i+1]-1;
+end[begin.length-1]=n-1;
+
+typedef void drawfcn(frame f);
+drawfcn[] draw=new drawfcn[begin.length];
+
+pair z0;
+
+for(int taxon=0; taxon < n; ++taxon) {
+ real[] P=percentage[taxon];
+ real maxP=max(P);
+ if(maxP < ignorebelow) continue;
+ picture pic;
+ real x=1;
+ if(maxP < minpercent) x=minpercent/maxP;
+ if(maxP > 100) x=50/maxP;
+ scale(pic,Linear(true,x),Linear(-1));
+ filldraw(pic,(0,depthmin)--graph(pic,P,depth)--(0,depthmax)--cycle,
+ gray(0.9));
+ xaxis(pic,Bottom,LeftTicks("$%.3g$",beginlabel=false,0,2),above=true);
+ xaxis(pic,Top,above=true);
+
+ frame label;
+ label(label,rotate(angle)*TeXify(taxa[taxon]),(0,0),N);
+
+ pair z=point(pic,N);
+ pair v=max(label);
+ int taxon=taxon;
+ pic.add(new void(frame f, transform t) {
+ pair z1=t*z+v;
+ ymax=max(ymax,z1.y+margin);
+ });
+
+ for(int i=0; i < begin.length; ++i) {
+ pair z=point(pic,N);
+ pair v=max(label);
+ if(taxon == begin[i]) {
+ pic.add(new void(frame f, transform t) {
+ pair Z=t*z+v;
+ z0=Z;
+ pair w0=Z+Ldir;
+ });
+ } else if(taxon == end[i]) {
+ int i=i;
+ pair align=2N;
+ pic.add(new void(frame, transform t) {
+ pair z0=z0;
+ pair z1=t*z+v;
+ pair w1=z1+Ldir;
+ draw[i]=new void(frame f) {
+ path g=z0--(z0.x+(ymax-z0.y)/Tan(angle),ymax)--
+ (z1.x+(ymax-z1.y)/Tan(angle),ymax)--z1;
+ draw(f,g);
+ label(f,group[i],point(g,1.5),align);
+ };
+ });
+ }
+ }
+
+ add(pic,label,point(pic,N));
+
+ if(taxon == 0) yaxis(pic,depthlabel,Left,RightTicks(0,10),above=true);
+ if(taxon == final) yaxis(pic,Right,LeftTicks("%",0,10),above=true);
+
+ add(shift(location,0)*pic);
+ location += pic.userMax().x;
+}
+
+add(new void(frame f, transform) {
+ for(int i=0; i < draw.length; ++i)
+ draw[i](f);
+ });
+
+for(int i=0; i < year.length; ++i)
+ if(year[i] != 0) label((string) year[i],(location,-depth[i]),E);
+
+label("\%",(0.5*location,point(S).y),5*S);
diff --git a/graphics/asymptote/doc/diatom.csv b/graphics/asymptote/doc/diatom.csv
new file mode 100644
index 0000000000..d05c3f4bc9
--- /dev/null
+++ b/graphics/asymptote/doc/diatom.csv
@@ -0,0 +1,28 @@
+"sediment depth (cm)","year","Achnanthes minutissima Kuetzing","Anomoeoneis vitrea (Grunow) Ross","Asterionella formosa Hassall","Tabellaria flocculosa (Roth) Kuetzing","Fragilaria cf. tenera","Chaetoceros muelleri/elmorei cysts","Aulacoseira spp. ","Fragilaria capucina var. vaucheriae (Kuetzing)","Fragilaria crotonensis Kitton"
+"A","B","C"
+0,4,6
+0,2000,11.6959064327485,9.55165692007797,49.6101364522417,1.364522417154,0,0.974658869395711,0,2.14424951267057,4.09356725146199
+10,1998,20.2676864244742,11.2810707456979,34.7992351816444,2.39005736137667,0,0.191204588910134,0.573613766730402,0.382409177820268,7.55258126195029
+20,1996,21.1282051282051,33.6410256410256,24,2.35897435897436,0.615384615384615,0,0.205128205128205,0.615384615384615,2.56410256410256
+30,1994,25.7620452310718,21.0422812192724,31.3667649950836,2.16322517207473,0.393313667649951,0.393313667649951,0.196656833824975,1.76991150442478,3.73647984267453
+40,1992,21.0422812192724,16.5191740412979,42.9695181907571,0.589970501474926,0,0.983284169124877,0.589970501474926,0.393313667649951,1.96656833824975
+50,1990,23.1067961165049,24.0776699029126,29.126213592233,1.35922330097087,0,0.970873786407767,0.388349514563107,0.58252427184466,3.30097087378641
+60,1988,35.0738916256158,33.3004926108374,4.33497536945813,1.37931034482759,0.591133004926108,1.97044334975369,1.18226600985222,0.985221674876847,2.75862068965517
+70,1986,42.2090729783037,33.7278106508876,2.26824457593688,1.38067061143984,0.788954635108481,1.18343195266272,0.591715976331361,1.38067061143984,3.25443786982249
+90,1984,34.5098039215686,41.9607843137255,0.196078431372549,2.15686274509804,0.588235294117647,2.74509803921569,0.588235294117647,2.15686274509804,0
+95,1982,38.0487804878049,45.4634146341463,0.487804878048781,0.975609756097561,0.975609756097561,0,0.390243902439024,0.390243902439024,0
+110,1980,40.1860465116279,41.4883720930233,1.30232558139535,0.837209302325581,0,0.930232558139535,0.372093023255814,0.372093023255814,1.3953488372093
+130,1978,39.6501457725948,42.1768707482993,0.291545189504373,0.194363459669582,2.72108843537415,1.55490767735666,0,1.36054421768707,0.777453838678329
+150,1972,32.6298701298701,31.4935064935065,1.86688311688312,1.78571428571429,0.162337662337662,13.961038961039,0.162337662337662,1.94805194805195,1.86688311688312
+170,1970,30.7692307692308,47.534516765286,0.986193293885602,3.35305719921105,0.19723865877712,1.38067061143984,0,1.18343195266272,0.591715976331361
+190,1965,40.5268490374873,37.8926038500507,1.82370820668693,2.63424518743668,0,1.21580547112462,0.405268490374873,1.21580547112462,1.01317122593718
+260,1961,40.4494382022472,26.0299625468165,0.468164794007491,1.31086142322097,0.561797752808989,8.05243445692884,0,3.74531835205992,0.374531835205993
+280,1950,44.946025515211,11.9725220804711,0.294406280667321,0.785083415112856,16.48675171737,1.96270853778214,0.392541707556428,2.35525024533857,0
+290,1942,41.2818096135721,8.29406220546654,0.188501413760603,0.282752120640905,28.6522148916117,0.942507068803016,0.377002827521206,4.33553251649387,0
+300,1940,18.0995475113122,12.3076923076923,0,0.180995475113122,40.3619909502262,5.61085972850679,0,2.35294117647059,0
+310,1920,28.6844708209693,11.2759643916914,0.593471810089021,3.26409495548961,13.0563798219585,13.2542037586548,0.19782393669634,9.89119683481701,0.989119683481701
+320,1915,6.17977528089888,1.31086142322097,4.30711610486891,6.74157303370787,32.7715355805243,34.4569288389513,1.31086142322097,2.62172284644195,0
+330,1910,4.03846153846154,0.769230769230769,14.5192307692308,36.4423076923077,5,0.769230769230769,11.1538461538462,0,2.11538461538462
+340,1888,7.37148399612027,1.1639185257032,9.40834141610087,31.8137730358875,1.1639185257032,0.969932104752667,14.3549951503395,0.193986420950533,0.969932104752667
+400,1763,2.69749518304432,0.192678227360308,24.8554913294798,26.7822736030829,0.385356454720617,2.69749518304432,20.0385356454721,0,1.54142581888247
+450,1726,2.37859266600595,0.396432111000991,9.71258671952428,28.5431119920714,0.198216055500496,0.594648166501487,30.5252725470763,0,0.792864222001982
diff --git a/graphics/asymptote/doc/dots.asy b/graphics/asymptote/doc/dots.asy
new file mode 100644
index 0000000000..49acfce341
--- /dev/null
+++ b/graphics/asymptote/doc/dots.asy
@@ -0,0 +1 @@
+draw((0,0){up}..(100,25){right}..(200,0){down});
diff --git a/graphics/asymptote/doc/eetomumu.asy b/graphics/asymptote/doc/eetomumu.asy
new file mode 100644
index 0000000000..309547d145
--- /dev/null
+++ b/graphics/asymptote/doc/eetomumu.asy
@@ -0,0 +1,60 @@
+import feynman;
+
+
+// set default line width to 0.8bp
+currentpen = linewidth(0.8);
+
+// scale all other defaults of the feynman module appropriately
+fmdefaults();
+
+// define vertex and external points
+
+real L = 50;
+
+pair zl = (-0.75*L,0);
+pair zr = (+0.75*L,0);
+
+pair xu = zl + L*dir(+120);
+pair xl = zl + L*dir(-120);
+
+pair yu = zr + L*dir(+60);
+pair yl = zr + L*dir(-60);
+
+
+// draw propagators and vertices
+
+drawFermion(xu--zl);
+drawFermion(zl--xl);
+
+drawPhoton(zl--zr);
+
+drawFermion(yu--zr);
+drawFermion(zr--yl);
+
+drawVertex(zl);
+drawVertex(zr);
+
+
+// draw momentum arrows and momentum labels
+
+drawMomArrow(xl--zl, Relative(left));
+label(Label("$k'$",2RightSide), xl--zl);
+
+label(Label("$k$",2LeftSide), xu--zl);
+
+drawMomArrow(zl--zr, Relative(left));
+label(Label("$q$",2RightSide), zl--zr);
+
+drawMomArrow(zr--yu, Relative(right));
+label(Label("$p'$",2LeftSide), zr--yu);
+
+label(Label("$p$",2RightSide), zr--yl);
+
+
+// draw particle labels
+
+label("$e^-$", xu, left);
+label("$e^+$", xl, left);
+
+label("$\mu^+$", yu, right);
+label("$\mu^-$", yl, right);
diff --git a/graphics/asymptote/doc/elliptic.asy b/graphics/asymptote/doc/elliptic.asy
new file mode 100644
index 0000000000..728508f011
--- /dev/null
+++ b/graphics/asymptote/doc/elliptic.asy
@@ -0,0 +1,115 @@
+struct curve {
+ real a=0;
+ real b=8;
+
+ real y2(real x) {
+ return x^3+a*x+b;
+ }
+
+ real disc() {
+ return -16*(4*a*a*a+27*b*b);
+ }
+
+ real lowx () {
+ return sqrt(-a/3);
+ }
+
+ int comps() {
+ if (a < 0) {
+ real x=sqrt(-a/3);
+ return y2(x) < 0 ? 2 : 1;
+ }
+ return 1;
+ }
+
+ void locus(picture pic=currentpicture, real m, real M, int n=100,
+ pen p=currentpen) {
+ path flip(path p, bool close) {
+ path pp=reverse(yscale(-1)*p)..p;
+ return close ? pp..cycle : pp;
+ }
+ path section(real m, real M, int n) {
+ guide g;
+ real width=(M-m)/n;
+ for(int i=0; i <= n; ++i) {
+ real x=m+width*i;
+ real yy=y2(x);
+ if (yy > 0)
+ g=g..(x,sqrt(yy));
+ }
+ return g;
+ }
+
+ if (comps() == 1) {
+ draw(pic,flip(section(m,M,n),false),p);
+ }
+ else {
+ real x=lowx(); // The minimum on x^3+ax+b
+ if (m < x)
+ draw(pic,flip(section(m,min(x,M),n),true),p);
+ if (x < M)
+ draw(pic,flip(section(max(x,m),M,n),false),p);
+ }
+ }
+
+ pair neg(pair P) {
+ return finite(P.y) ? yscale(-1)*P : P;
+ }
+
+ pair add(pair P, pair Q) {
+ if (P.x == Q.x && P.x != Q.x)
+ return (0,infinity);
+ else {
+ real lambda=P == Q ? (3*P.x^2+a)/(2*P.y) : (Q.y-P.y)/(Q.x-P.x);
+ real Rx=lambda^2-P.x-Q.x;
+ return (Rx,(P.x-Rx)*lambda-P.y);
+ }
+ }
+}
+
+import graph;
+import math;
+
+size(0,200);
+
+curve c; c.a=-1; c.b=4;
+
+pair oncurve(real x)
+{
+ return (x,sqrt(c.y2(x)));
+}
+
+picture output;
+
+axes();
+c.locus(-4,3,.3red+.7blue);
+
+pair P=oncurve(-1),Q=oncurve(1.2);
+pair PP=c.add(P,P),sum=c.add(P,Q);
+
+save();
+
+drawline(P,Q,dashed);
+drawline(c.neg(sum),sum,dashed);
+dot("$P$", P, NW);
+dot("$Q$", Q, SSE);
+dot(c.neg(sum));
+dot("$P+Q$", sum, 2SW);
+
+add(output,currentpicture.fit(),(-0.5cm,0),W);
+
+restore();
+
+save();
+
+drawline(P,c.neg(PP),dashed);
+drawline(c.neg(PP),PP,dashed);
+dot("$P$", P, NW);
+dot(c.neg(PP));
+dot("$2P$", PP, SW);
+
+add(output,currentpicture.fit(),(0.5cm,0),E);
+
+shipout(output);
+
+restore();
diff --git a/graphics/asymptote/doc/errorbars.asy b/graphics/asymptote/doc/errorbars.asy
new file mode 100644
index 0000000000..a8707b2497
--- /dev/null
+++ b/graphics/asymptote/doc/errorbars.asy
@@ -0,0 +1,42 @@
+import graph;
+
+picture pic;
+real xsize=200, ysize=140;
+size(pic,xsize,ysize,IgnoreAspect);
+
+pair[] f={(5,5),(50,20),(90,90)};
+pair[] df={(0,0),(5,7),(0,5)};
+
+errorbars(pic,f,df,red);
+draw(pic,graph(pic,f),"legend",
+ marker(scale(0.8mm)*unitcircle,red,FillDraw(blue),above=false));
+
+scale(pic,true);
+
+xaxis(pic,"$x$",BottomTop,LeftTicks);
+yaxis(pic,"$y$",LeftRight,RightTicks);
+add(pic,legend(pic),point(pic,NW),20SE,UnFill);
+
+picture pic2;
+size(pic2,xsize,ysize,IgnoreAspect);
+
+frame mark;
+filldraw(mark,scale(0.8mm)*polygon(6),green,green);
+draw(mark,scale(0.8mm)*cross(6),blue);
+
+draw(pic2,graph(pic2,f),marker(mark,markuniform(5)));
+
+scale(pic2,true);
+
+xaxis(pic2,"$x$",BottomTop,LeftTicks);
+yaxis(pic2,"$y$",LeftRight,RightTicks);
+
+yequals(pic2,55.0,red+Dotted);
+xequals(pic2,70.0,red+Dotted);
+
+// Fit pic to W of origin:
+add(pic.fit(),(0,0),W);
+
+// Fit pic2 to E of (5mm,0):
+add(pic2.fit(),(5mm,0),E);
+
diff --git a/graphics/asymptote/doc/exp.asy b/graphics/asymptote/doc/exp.asy
new file mode 100644
index 0000000000..2c4eed90d4
--- /dev/null
+++ b/graphics/asymptote/doc/exp.asy
@@ -0,0 +1,14 @@
+import graph;
+size(150,0);
+
+real f(real x) {return exp(x);}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$");
+yaxis("$y$",0);
+
+draw(graph(f,-4,2,operator ..),red);
+
+labely(1,E);
+label("$e^x$",F(1),SE);
+
diff --git a/graphics/asymptote/doc/external-proposal.html b/graphics/asymptote/doc/external-proposal.html
new file mode 100644
index 0000000000..3dcc97d95b
--- /dev/null
+++ b/graphics/asymptote/doc/external-proposal.html
@@ -0,0 +1,415 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1-strict.dtd">
+<html>
+ <head>
+ <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
+ <title>Asymptote Proposal - External Modules</title>
+ <style><!--
+ --></style>
+ </head>
+ <body>
+ <h1>Asymptote Proposal &mdash External Modules</h1>
+ <h2>Overview</h2>
+ <p>External modules allow users to extend Asymptote by calling functions
+ written in another programming language.</p>
+ <p>Users do this by writing a .asyc file, which contains a mix of
+ Asymptote code and code from another language, say C++. Then, a program
+ is run which produces a .asy file and a C++ source file. The C++ file is
+ compiled to produce a shared library file. Then, the .asy file can be
+ imported in Asymptote to use the externally defined features.</p>
+ <p>This spec is describes a proposed feature that has not yet been
+ implemented. It is incomplete, and does not address all of the issues
+ involved in implementing the feature.</p>
+ <h2>Example</h2>
+ <p>Let&#8217;s look at a simple example that shows off the main features.
+ Asymptote currently doesn&#8217;t offer a way to read the contents of a
+ directory. This would be useful if, say, we wanted to make a series of
+ graphs for every .csv file in a directory.</p>
+ <pre>
+/*****
+ * dir.asyc
+ * Andy Hammerlindl 2007/09/11
+ *
+ * An example for the proposed external module support in Asymptote. This reads
+ * the contents of a directory via the POSIX commands.
+ *
+ * Example usage in asymptote:
+ * access dir;
+ * dir.entry[] entries= dir.open('.');
+ * for (dir.entry e : entries)
+ * write(e.name);
+ *****/
+
+// Verbatim code will appear in the c++ or asy file (as specified) interleaved
+// in the same order as it appears here.
+verbatim c++ {
+ #include &lt;sys/types.h&gt;
+ #include &lt;dirent.h&gt;
+ #include &lt;errno.h&gt;
+
+ // asy.h is included by default (needed for hidden code, anyway).
+ // Asymptote-specific types, such as array below, are in the asy namespace.
+ using namespace asy;
+}
+
+// Define a new opaque type in asy which is internally represented by struct
+// dirent *. This is too messy to expose to users of the module, so define
+// everything as private.
+private asytype const struct dirent *entry_t;
+
+private int entry_d_ino(entry_t e) {
+ return (Int)e-&gt;d_ino;
+}
+
+private int entry_d_off(entry_t e) {
+ return (Int)e-&gt;d_off;
+}
+
+private int entry_d_reclen(entry_t e) {
+ return (Int)e-&gt;reclen;
+}
+
+private string entry_d_type(entry_t e) {
+ return string( /*length*/ 1, e-&gt;d_type);
+}
+
+private string entry_d_name(entry_t e) {
+ return string(e-&gt;d_name);
+}
+
+// Define an asy structure to expose the information. These steps are annoying,
+// but straightforward, and not too hard to plow through.
+verbatim asy {
+ struct entry {
+ restricted int ino;
+ restricted int off;
+ restricted int reclen;
+ restricted int type;
+ restricted string name;
+
+ void operator init(entry_t e) {
+ ino=entry_d_ino(e);
+ off=entry_d_off(e);
+ reclen=entry_d_reclen(e);
+ type=entry_d_type(e);
+ name=entry_d_name(e);
+ }
+ }
+}
+
+
+// Given the name of a directory, return an array of entries. Return 0
+// (a null array) on error.
+private entry_t[] base_read(string name)
+{
+ DIR *dir=opendir(name.c_str());
+
+ // TODO: Add standard style of error reporting.
+ if (dir == NULL)
+ return 0;
+
+ // Create the array structure.
+ // array is derived from gc, so will be automatically memory-managed.
+ array *a=new array();
+
+ struct dirent *entry;
+ while (entry=readdir(dir))
+ a-&gt;push&lt;struct dirent *&gt;(entry);
+
+ // The loop has exited, either by error, or after reading the entire
+ // directory. Check before closedir(), in case that call resets errno.
+ if (errno != 0) {
+ closedir(dir);
+ return 0;
+ }
+
+ closedir(dir);
+ return a;
+}
+
+verbatim asy {
+ private entry[] cleanEntries(entry_t[] raw_entries) {
+ if (raw_entries) {
+ entry[] entries;
+ for (entry_t e : raw_entries)
+ entries.push(entry(e));
+ return entries;
+ }
+ return null;
+ }
+
+ entry[] read(string name) {
+ return cleanEntries(base_read(name));
+ }
+}
+
+</pre>
+ <h2>Type Mappings</h2>
+ <p>Types in Asymptote do not directly relate to types in C++, but there
+ is a partial mapping between them. The header file
+ <code>asymptote.h</code> provides typedefs for the primitive asymptote
+ types. For instance <code>string</code> in Asymptote maps to the C++
+ class <code>asy::string</code> which is a variant of
+ <code>std::string</code> and <code>real</code> to <code>asy::real</code>
+ which is a basic floating point type (probably <code>double</code>).
+ Because <code>int</code> is a reserved word in C++, the Asymptote type
+ <code>int</code> is mapped to <code>asy::Int</code> which is one of the
+ basic signed numeric types in C++ (currently 64 bit).
+ <code>asy::pair</code> is a class that implements complex numbers. In
+ the first version of the external module implementation, these will be
+ the only primitive types with mappings, but eventually all of them will
+ be added.</p>
+
+ <p>All Asymptote arrays, regardless of the cell type, are mapped to
+ <code>asy::array *</code> where <code>asy::array</code> is a C++ class.
+ The cells of the array are of the type <code>asy::item</code> which can
+ hold any Asymptote data type. Items can be constructed from any C++
+ type. Once constructed, the value of an item can be retrieved by the
+ function <code>template&lt;typename T&gt; T get(const item&amp;)</code>.
+ Calling <code>get</code> on an item using the wrong type generates a
+ runtime error. </p>
+<pre>
+// Examples of using item.
+item x((asy::Int)2);
+item y(3.4);
+item z=new array;
+item w=(asy::real)3.4;
+
+cout &lt;&lt; get&lt;asy::Int&gt;(x);
+cout &lt;&lt; get&lt;double&gt;(y);
+
+x=y; // x now stores a double.
+cout &lt;&lt; get&lt;double&gt;(x);
+
+cout &lt;&lt; get&lt;asy::real&gt;(w);
+</pre>
+
+ <p>The <code>asy::array</code> class implements, at a minimum, the
+ methods:</p>
+ <ul>
+ <li><code>size_t size()</code>
+ which returns the number of elements,</li>
+ <li><code>template &lt;typename T&gt; T read(size_t i) const</code>
+ which returns the i-th element, interpreted as being of type t.</li>
+ <li><code>template &lt;typename T&gt; void push(item i)</code>
+ adds the item to the end of the array.</li>
+ </ul>
+ <p>It allows access to elements of the array as items by
+ <code>operator[]</code>. We may specify that <code>asy::array</code>
+ be a model of the Random Access Container in the C++ Standard Template
+ Library. It is currently implemented as a subclass of an STL
+ vector.</p>
+<pre>
+// Example of a C++ function that doubles the entries in an array of integers.
+using namespace asy;
+
+void doubler(array *a) {
+ assert(a);
+ size_t length=a-&gt;size();
+ for (size_t i=0; i&lt;length; ++i) {
+ Int x=a-&gt;read&lt;Int&gt;(i); // This is shorthand for get&lt;Int&gt;((*a)[i]).
+ a[i]=2*x; // The type of 2*x is also Int, so this will enter
+ // the item as the proper type.
+ }
+}
+</pre>
+ <p>Users can map new Asymptote types to their own custom C++ types using
+ Opaque Type Declarations, explained below.</p>
+
+ <h2>Syntactic Features</h2>
+ <p>A .asyc file is neither an asy file with some C++ in it, nor a C++
+ with some asy code in it. It can only contain a small number of
+ specific constructs:</p>
+ <ul>
+ <li>Comments</li>
+ <li>Function Definitions</li>
+ <li>Verbatim Code Block</li>
+ <li>Opaque Type Declaration</li>
+ </ul>
+ <!-- Move to after constructs -->
+ <p>Each component may produce code for either the .asy file, the .cc
+ file, or both. The pieces of code produced by each construct appears in
+ the output file in the same order as the constructs in the .asyc. For
+ example, if a function definition occurs before a verbatim Asymptote
+ code block, we can be sure that the function is defined and can be used
+ in that block. Similarly, if a verbatim C++ block occurs before a
+ function definition, then the body of the function can use features
+ declared in the verbatim section.</p>
+
+ <h3>Comments</h3>
+ <p>C++/Asymptote style comments using <code>/* */</code> or
+ <code>//</code> are allowed at the top level. These do not affect the
+ definition of the module, but the implementation may copy them into the
+ .asy and .cc to help explain the resulting code.</p>
+
+ <h3>Verbatim Code Blocks</h3>
+ <p>Verbatim code, ie. code to be copied directly into the either
+ the output .asy or .cc file can be specified in the .asyc file by
+ enclosing it in a verbatim code block. This starts with the special
+ identifier <code>verbatim</code> followed by either <code>c++</code>
+ or <code>asy</code> to specify into which file the code will be copied,
+ and then a block of code in braces. When the .asyc file is parsed,
+ the parser keeps track of matching open and close braces inside the
+ verbatim code block, so that the brace at the start of the block can
+ be matched with the one at the end. This matching process will ignore
+ braces occuring in comments and string and character literals.</p>
+ <h4>Open issue</h4>
+ <p>It may prove to be impractical to walk through the code, matching
+ braces. Also, this plan precludes having a verbatim block with an
+ unbalanced number of braces which might be useful, say to start a
+ namespace at the beginning of the C++ file, and end it at the end of the
+ file. As such, it may be useful to have another technique. A really
+ simple idea (with obvious drawbacks) would be to use the first closing
+ braces that occur at the same indentation level as the verbatim keyword
+ (assuming that the code block itself will be indented). Other
+ alternatives are to use more complicated tokens such as <code>%{</code>
+ and <code>%}</code>, or the shell style <code>&lt;&lt;EOF</code>.</p>
+
+ <h3>Function Definitions</h3>
+ <p>A function definition given at the top level of the file (and not
+ inside a verbatim block) looks much like a function definition in
+ Asymptote or C++, but is actually a mix of both. The header of the
+ function is given in Asymptote code, and defines how the function will
+ look in the resulting Asymptote module. The body, on the other hand, is
+ given in C++, and defines how the function is implemented in C++. As a
+ simple example, consider:
+ <pre>real sum(real x, real y=0.0) {
+ return x+y;
+}</pre>
+ <h4>Header</h4>
+ <p> The header of the definition gives
+ the name, permission, return type, and parameters of the function.
+ Because the function is defined for use in Asymptote, all of the types
+ are given as Asymptote types.</p>
+ <h5>Permissions</h5>
+ <p>As in pure Asymptote, the function can optionally be given a
+ <code>private</code>, <code>restricted</code> or <code>public</code>
+ permission. If not specified, the permission is <code>public</code> by
+ default. This is the permission that the function will have when it is
+ part of the Asymptote module. The example of <code>sum</code> above
+ specifies no permission, so it is public.</p>
+ <p>Just as public methods such as <code>plain.draw</code> can be
+ re-assigned by scripts that import the <code>plain</code> module, the
+ current plan is to allow Asymptote code to modify public members of any
+ module, including ones defined using native code. This is in contrast
+ to builtin functions bindings, which cannot be modified.</p>
+ <h5>Return Type</h5>
+ <p>This gives the Asymptote return type of the function. This cannot be
+ an arbitrary Asymptote type, but must one which maps to a C++ type as
+ explained in the type mapping section above. Our example of <code>sum</code> gives
+ <code>real</code> as a return type, which maps to the C++ type
+ <code>asy::real</code>.</p>
+ <h5>Function Name</h5>
+ <p>This gives the name of the function as it will appear in the
+ Asymptote module. In our example, the Asymptote name is
+ <code>sum</code>. The name can be any Asymptote identifier, including
+ operator names, such as <code>operator +</code>.</p>
+ <p>It is important to note that the Asymptote name has no relation to
+ the C++ name of the function, which may be something strange, such as
+ <code>_asy_func_modulename162</code>. Also, the actual signature and
+ return type of the C++ function may bear no relation to the Asymptote
+ signature. That said, the C++ name of the function may be defined by
+ giving the function name as <code>asyname:cname</code>. Then it can be
+ referred to by other C++ code. The function will be defined with C
+ calling convention, so that its name is not mangled.</p>
+ <h5>Formal Parameters</h5>
+ <p>The function header takes a list of formal parameters. Just as in
+ pure Asymptote code, these can include <code>explicit</code>
+ keywords, type declarations with array and functional types, and rest
+ parameters. Just as with the return type of the function, the type of
+ each of the parameters must map to a C++ type.</p>
+ <p>Parameters may be given an optional Asymptote name and an optional
+ C++ name. These may be declared in one of six ways as in the following
+ examples:</p>
+ <pre>void f(int)
+void f(int name)
+void f(int :)
+void f(int asyname:)
+void f(int :cname)
+void f(int asyname:cname)
+</pre>
+ <p>If the parameter just contains a type, with no identifier,
+ then it has no Asymptote name and no C++ name. If it contains a single
+ name (with no colon), then that name is both the Asymptote and the C++
+ name. If it contains a colon in the place of an identifier, with an
+ optional name in front of the colon and an optional name behind the
+ colon, than the name in front (if given) is the Asymptote name, and the
+ name behind (if given) is the C++ name.</p>
+ <p>The Asymptote name can be any Asymptote identifier, including
+ operator names, but the C++ name must be a valid C++ identifier. For
+ instance <code>void f(int operator +)</code> is not allowed, as the
+ parameter would not have a valid C++ name. The examples
+ <code>void f(int operator +:)</code> and
+ <code>void f(int operator +:addop)</code> are allowed.</p>
+ <p>When called by Asymptote code, named arguments are only matched to
+ the Asymptote names, so for example a function defined by
+ <code>void f(int :x, string x:y)</code> could be called by
+ <code>f(x="hi mom", 4)</code>, but one defined by
+ <code>void f(int x, string x:y)</code> could not.</p>
+ <p>Each formal parameter may take a piece of code as a default value.
+ Because the function is implemented in C++, this code must be given as
+ C++ code. More akin to Asymptote than C++, default arguments may occur
+ for any non-rest parameters, not just those at the end of the list, and
+ may refer to earlier parameters in the list. Earlier parameters are
+ refered to by their C++ names. Example:
+<pre>void drawbox(pair center, real width, real height=2*width, pen p)</pre>
+ Default arguments are parsed by finding the next comma that is not part
+ of a comment, string literal, or character constant, and is not nested
+ inside parentheses. The C++ code between the equals-sign and the comma
+ is taken as the expression for the default argument.</p>
+ <h4>Body</h4>
+ <p>The body of the function is written as C++ code. When the .asyc
+ file is processed, this C++ code is copied verbatim into an actual C++
+ function providing the implementation. However, the actual body of the
+ resultant C++ function may contain code other than the body provided by
+ the user. This auxillary code could include instruction to retrieve the
+ arguments of the function from their representation in the Asymptote
+ virtual machine and bind them to local variables with their C++ names.
+ It could also include initialization and finalization code for the
+ function.</p>
+ <p>In writing code for the function body, one can be assured that all
+ function arguments with C++ names have been bound and are therefore
+ usable in the code. Since all parameters must have Asymptote types that
+ map to C++ types, the types of the paramaters in the body have the type
+ resulting from that mapping.</p>
+ <p>The <code>return</code> keyword can be used to return the result of
+ the function (or without an expression, if the return type was declared
+ as void). The Asymptote return type must map to a C++ type, and the
+ expression given in the return statement will be implicitly cast to that
+ type.</p>
+ <p>Since the implementation will likely not use an actual return
+ statement to return the value of the function back to the Asymptote
+ virtual machine, the interpreter of the .asyc file may walk through the
+ code converting return expressions into a special format in the actual
+ implementation of the function.<p>
+
+ <h3>Opaque Type Declarations</h3>
+ <p>There are a number of mappings between Asymptote and C++ types
+ builtin to the facility. For instance <code>int</code> maps to
+ <code>asy::Int</code> and <code>real</code> to <code>asy::real</code>.
+ Users, however, may want to reference other C++ objects in Asymptote
+ code. This done though opaque type declarations.</p>
+
+ <p>An opaque type declaration is given by an optional permission
+ modifier, the keyword <code>asytype</code>, a C++ type, and an Asymptote
+ identifier; in that order.</p>
+<pre>
+// Examples
+asytype char char;
+public asytype const std::list&lt;asy::Int&gt; *intList;
+private asytype const struct dirert *entry_t;
+</pre>
+ <p>This declaration mapping the Asymptote identifier to the C++ type
+ within the module. The permission of the Asymptote type is given by the
+ permission modifier (or public if the modifier is omitted). The type is
+ opaque, in that none of its internal structure is revealed in the
+ Asymptote code. Like any other type, however, objects of this new type
+ can be returned from functions, given as an arguments to functions, and
+ stored in variables, structures and arrays.</p>
+ <p>In many cases, such as the directory listing example at the start, it
+ will be practical to declare the type as private, and use an Asymptote
+ structure as a wrapper hiding the C++ implementation.</p>
+ </body>
+</html>
+
+
diff --git a/graphics/asymptote/doc/externalprc.tex b/graphics/asymptote/doc/externalprc.tex
new file mode 100644
index 0000000000..04718b86a1
--- /dev/null
+++ b/graphics/asymptote/doc/externalprc.tex
@@ -0,0 +1,13 @@
+% Generate inline PRC images for latex with
+% asy -inlineimage cube -render=4
+%
+% Generate inline PRC images for pdflatex with
+% asy -inlineimage cube -render=4 -tex pdflatex
+%
+\documentclass[12pt]{article}
+\input cube.pre
+\usepackage[bigfiles]{media9}
+\RequirePackage{asymptote,color,graphicx}
+\begin{document}
+\input cube.tex
+\end{document}
diff --git a/graphics/asymptote/doc/extra/intro.asy b/graphics/asymptote/doc/extra/intro.asy
new file mode 100644
index 0000000000..68aa7e0347
--- /dev/null
+++ b/graphics/asymptote/doc/extra/intro.asy
@@ -0,0 +1,959 @@
+orientation=Landscape;
+
+settings.tex="pdflatex";
+
+import slide;
+import three;
+import animate;
+
+bool long=true;
+
+usepackage("mflogo");
+
+usersetting();
+
+viewportsize=pagewidth-2pagemargin;
+
+// To generate bibliographic references:
+// asy -k intro
+// bibtex intro_
+// asy -k intro
+bibliographystyle("alpha");
+
+itempen=fontsize(22pt);
+defaultpen(itempen);
+viewportmargin=(2,2);
+
+titlepage(long ? "Asymptote: The Vector Graphics Language" :
+ "Interactive TeX-Aware 3D Vector Graphics",
+ "John Bowman and Andy Hammerlindl",
+"Department of Mathematical and Statistical Sciences\\
+ University of Alberta\\
+%and Instituto Nacional de Matem\'atica Pura e Aplicada (IMPA)
+\medskip\Green{Collaborators: Orest Shardt, Michail Vidiassov}",
+"June 30, 2010",
+"http://asymptote.sf.net/intro.pdf");
+
+title("History");
+item("1979: \TeX\ and \MF\ (Knuth)");
+item("1986: 2D B\'ezier control point selection (Hobby)");
+item("1989: MetaPost (Hobby)");
+item("2004: Asymptote");
+subitem("2004: initial public release (Hammerlindl, Bowman, \& Prince)");
+subitem("2005: 3D B\'ezier control point selection (Bowman)");
+subitem("2008: 3D interactive \TeX\ within PDF files (Shardt \& Bowman)");
+subitem("2009: 3D billboard labels that always face camera (Bowman)");
+subitem("2010: 3D PDF enhancements (Vidiassov \& Bowman)");
+
+title("Statistics (as of June, 2010)");
+item("Runs under Linux/UNIX, Mac OS X, Microsoft Windows.");
+item("4000 downloads/month from primary\hfill\\
+ {\tt asymptote.sourceforge.net} site alone.");
+item("80\ 000 lines of low-level C++ code.");
+item("36\ 000 lines of high-level Asymptote code.");
+
+if(long) {
+title("Vector Graphics");
+item("Raster graphics assign colors to a grid of pixels.");
+figure("pixel.pdf");
+item("Vector graphics are graphics which still maintain their look when
+ inspected at arbitrarily small scales.");
+asyfigure(asywrite("
+picture pic;
+
+path zoombox(real h) {
+ return box((-h,-h/2),(min(10,h),min(10,h)/2));
+}
+
+frame zoom(real h, real next=0) {
+ frame f;
+ draw(f, (0,-100){W}..{E}(0,0), Arrow);
+ clip(f, zoombox(h));
+ if(next > 0)
+ draw(f, zoombox(next));
+
+ return scale(100/h)*f;
+}
+
+add(zoom(100), (0,0));
+add(zoom(10), (200,0));
+add(zoom(1), (400,0));
+"));
+}
+
+title("Cartesian Coordinates");
+
+item("Asymptote's graphical capabilities are based on four primitive
+ commands: {\tt draw}, {\tt label}, {\tt fill}, {\tt clip} \cite{Bowman08}");
+
+asyfilecode("diagonal");
+item("units are {\tt PostScript} {\it big points\/} (1 {\tt bp} =
+1/72 {\tt inch})");
+item("{\tt --} means join the points with a linear segment to create
+a {\it path}");
+
+item("{\it cyclic\/} path:");
+
+asycode("
+draw((0,0)--(100,0)--(100,100)--(0,100)--cycle);
+");
+
+title("Scaling to a Given Size");
+
+item("{\tt PostScript} units are often inconvenient.");
+
+item("Instead, scale user coordinates to a specified final size:");
+
+asyfilecode("square");
+
+item("One can also specify the size in {\tt cm}:");
+
+asycode("
+size(3cm,3cm);
+draw(unitsquare);
+");
+
+title("Labels");
+
+item("Adding and aligning \LaTeX\ labels is easy:");
+
+asycode(preamble="defaultpen(fontsize("+string(fontsize(itempen))+"));",
+"size(6cm);
+draw(unitsquare);
+label(\"$A$\",(0,0),SW);
+label(\"$B$\",(1,0),SE);
+label(\"$C$\",(1,1),NE);
+label(\"$D$\",(0,1),NW);
+");
+
+title("2D B\'ezier Splines");
+
+item("Using {\tt ..} instead of {\tt --} specifies a {\it B\'ezier cubic
+spline}:");
+
+code("
+draw(z0 .. controls c0 and c1 .. z1,blue);
+");
+asyfigure(asywrite("defaultpen(fontsize("+string(fontsize(itempen))+"));
+size(0,7cm);
+pair z0=(0,0);
+pair c0=(1,1);
+pair c1=(2,1);
+pair z1=(3,0);
+draw(z0..controls c0 and c1 .. z1,blue);
+draw(z0--c0--c1--z1,dashed);
+dot(\"$z_0$\",z0,W,red);
+dot(\"$c_0$\",c0,NW,red);
+dot(\"$c_1$\",c1,NE,red);
+dot(\"$z_1$\",z1,red);
+"));
+
+equation("(1-t)^3 z_0+3t(1-t)^2 c_0+3t^2(1-t) c_1+t^3 z_1, \qquad t\in [0,1].");
+
+title("Smooth Paths");
+
+item("Asymptote can choose control points for you, using the algorithms of
+Hobby and Knuth \cite{Hobby86,Knuth86b}:");
+
+string bean="
+pair[] z={(0,0), (0,1), (2,1), (2,0), (1,0)};
+";
+
+asycode(preamble="size(130,0);",bean+"
+draw(z[0]..z[1]..z[2]..z[3]..z[4]..cycle,
+ grey+linewidth(5));
+dot(z,linewidth(7));
+");
+
+item("First, linear equations involving the curvature are solved to find the
+ direction through each knot. Then, control points along those directions
+ are chosen:");
+
+asyfigure(asywrite(preamble="size(130,0);",bean+"
+path p=z[0]..z[1]..z[2]..z[3]..z[4]..cycle;
+
+dot(z);
+draw(p,lightgrey+linewidth(5));
+dot(z);
+
+picture output;
+save();
+for(int i=0; i<length(p); ++i) {
+ pair z=point(p,i), dir=dir(p,i);
+ draw((z-0.3dir)--(z+0.3dir), Arrow);
+}
+add(output, currentpicture.fit(), (-0.5inch, 0), W);
+restore();
+
+save();
+guide g;
+for(int i=0; i<length(p); ++i) {
+ dot(precontrol(p,i));
+ dot(postcontrol(p,i));
+ g=g--precontrol(p,i)--point(p,i)--postcontrol(p,i);
+}
+draw(g--cycle,dashed);
+add(output, currentpicture.fit(), (+0.5inch, 0), E);
+restore();
+
+shipout(output);
+"));
+
+title("Filling");
+item("The {\tt fill} primitive to fill the inside of a path:");
+asycode(preamble="size(0,200);","
+path star;
+for(int i=0; i < 5; ++i)
+ star=star--dir(90+144i);
+star=star--cycle;
+
+fill(star,orange+zerowinding);
+draw(star,linewidth(3));
+
+fill(shift(2,0)*star,blue+evenodd);
+draw(shift(2,0)*star,linewidth(3));
+");
+
+title("Filling");
+item("Use a list of paths to fill a region with holes:");
+asycode(preamble="size(0,300);","
+path[] p={scale(2)*unitcircle, reverse(unitcircle)};
+fill(p,green+zerowinding);
+");
+
+title("Clipping");
+item("Pictures can be clipped to a path:");
+asycode(preamble="
+size(0,200);
+guide star;
+for(int i=0; i<5; ++i)
+ star=star--dir(90+144i);
+star=star--cycle;","
+fill(star,orange+zerowinding);
+clip(scale(0.7)*unitcircle);
+draw(scale(0.7)*unitcircle);
+");
+
+title("Affine Transforms");
+
+item("Affine transformations: shifts, rotations, reflections, and scalings
+ can be applied to pairs, paths, pens, strings, and even whole pictures:");
+
+code("
+fill(P,blue);
+fill(shift(2,0)*reflect((0,0),(0,1))*P, red);
+fill(shift(4,0)*rotate(30)*P, yellow);
+fill(shift(6,0)*yscale(0.7)*xscale(2)*P, green);
+");
+asyfigure(asywrite("
+size(500,0);
+real bw=0.15;
+real sw=0.2;
+real r=0.15;
+
+path outside=(0,0)--(0,1)--
+ (bw+sw,1)..(bw+sw+r+bw,1-(r+bw))..(bw+sw,1-2(r+bw))--
+ (bw,1-2(r+bw))--(bw,0)--cycle;
+path inside=(bw,1-bw-2r)--(bw,1-bw)--
+ (bw+sw,1-bw)..(bw+sw+r,1-bw-r)..(bw+sw,1-bw-2r)--cycle;
+//fill(new path[] {outside, reverse(inside)},yellow);
+
+path[] P={outside, reverse(inside)};
+
+fill(P,blue);
+fill(shift(2,0)*reflect((0,0),(0,1))*P, red);
+fill(shift(4,0)*rotate(30)*P, yellow);
+fill(shift(6,0)*yscale(0.7)*xscale(2)*P, green);
+"));
+
+if(long) {
+title("C++/Java-like Programming Syntax");
+
+code("// Declaration: Declare x to be real:
+real x;
+
+// Assignment: Assign x the value 1.
+x=1.0;
+
+// Conditional: Test if x equals 1 or not.
+if(x == 1.0) {
+ write(\"x equals 1.0\");
+} else {
+ write(\"x is not equal to 1.0\");
+}
+
+// Loop: iterate 10 times
+for(int i=0; i < 10; ++i) {
+ write(i);
+}");
+}
+
+title("Modules");
+
+item("There are modules for Feynman diagrams,");
+asyfigure("eetomumu","height=6cm");
+remark("data structures,");
+asyfigure(asywrite("
+import binarytree;
+
+binarytree bt=binarytree(1,2,4,nil,5,nil,nil,0,nil,nil,3,6,nil,nil,7);
+draw(bt);
+"),"height=6cm");
+newslide();
+remark("algebraic knot theory:");
+asyfigure("knots");
+equations("\Phi\Phi(x_1,x_2,x_3,x_4,x_5)
+ = &\rho_{4b}(x_1+x_4,x_2,x_3,x_5) + \rho_{4b}(x_1,x_2,x_3,x_4) \\
+ + &\rho_{4a}(x_1,x_2+x_3,x_4,x_5) - \rho_{4b}(x_1,x_2,x_3,x_4+x_5) \\
+ - &\rho_{4a}(x_1+x_2,x_3,x_4,x_5) - \rho_{4a}(x_1,x_2,x_4,x_5).");
+
+if(long) {
+title("Textbook Graph");
+asy(nativeformat(),"exp");
+filecode("exp.asy");
+label(graphic("exp."+nativeformat(),"height=10cm"),(0.5,0),
+ Fill(figureborder,figuremattpen));
+
+title("Scientific Graph");
+asyfilecode("lineargraph","height=13cm",newslide=true);
+
+title("Data Graph");
+asyfilecode("datagraph","height=13cm",newslide=true);
+
+title("Imported Data Graph");
+asyfilecode("filegraph","height=15cm",newslide=true);
+
+title("Logarithmic Graph");
+asyfilecode("loggraph","height=15cm",newslide=true);
+title("Secondary Axis");
+} else
+title("Scientific Graph");
+
+asyfigure("secondaryaxis","height=15cm");
+
+title("Images and Contours");
+asyfigure("imagecontour","height=17cm");
+
+title("Multiple Graphs");
+asyfigure("diatom","height=17cm");
+
+title("Hobby's 2D Direction Algorithm");
+item("A tridiagonal system of linear equations is solved to determine any unspecified directions $\phi_k$ and $\theta_k$ through each knot $z_k$:");
+
+equation("\frac{\theta_{k-1}-2\phi_k}{\ell_k}=
+\frac{\phi_{k+1}-2\theta_k}{\ell_{k+1}}.");
+
+asyfigure("Hobbydir","height=9cm");
+
+item("The resulting shape may be adjusted by modifying optional {\it tension\/} parameters and {\it curl\/} boundary conditions.");
+
+title("Hobby's 2D Control Point Algorithm");
+item("Having prescribed outgoing and incoming path directions $e^{i\theta}$
+at node~$z_0$ and $e^{i\phi}$ at node $z_1$ relative to the
+vector $z_1-z_0$, the control points are determined as:");
+
+equations("u&=&z_0+e^{i\theta}(z_1-z_0)f(\theta,-\phi),\nonumber\\
+v&=&z_1-e^{i\phi}(z_1-z_0)f(-\phi,\theta),");
+
+remark("where the relative distance function $f(\theta,\phi)$ is given by Hobby [1986].");
+
+asyfigure("Hobbycontrol","height=9cm");
+
+if(long) {
+title("B\'ezier Curves in 3D");
+
+item("Apply an affine transformation");
+
+equation("x'_i=A_{ij} x_j+C_i");
+
+remark("to a B\'ezier curve:");
+
+equation("\displaystyle x(t)=\sum_{k=0}^3 B_k(t) P_k, \qquad t\in [0,1].");
+
+item("The resulting curve is also a B\'ezier curve:");
+
+skip(-2);
+
+equations("x'_i(t)&=&\sum_{k=0}^3 B_k(t) A_{ij}(P_k)_j+C_i\nonumber\\
+&=&\sum_{k=0}^3 B_k(t) P'_k,");
+
+skip(-2);
+
+remark("where $P'_k$ is the transformed $k^{\rm th}$ control point, noting
+$\displaystyle\sum_{k=0}^3 B_k(t)=1.$");
+}
+
+title("3D Generalization of Direction Algorithm");
+
+item("Must reduce to 2D algorithm in planar case.");
+
+item("Determine directions by applying Hobby's algorithm in the plane containing $z_{k-1}$, $z_k$, $z_{k+1}$.");
+
+// Reformulate Hobby's equations in terms of the angle $\psi_k=$
+item("The only ambiguity that can arise is the overall sign of the angles, which relates to viewing each 2D plane from opposing normal directions.");
+
+item("A reference vector based on the mean unit normal of successive segments can be used to resolve such ambiguities \cite{Bowman07,Bowman09}");
+
+title("3D Control Point Algorithm");
+
+item("Express Hobby's algorithm in terms of the absolute directions $\omega_0$ and~$\omega_1$:");
+skip(-1);
+equation("u=z_0+\omega_0\left|z_1-z_0\right|f(\theta,-\phi),");
+equation("v=z_1-\omega_1\left|z_1-z_0\right|f(-\phi,\theta),");
+
+asyfigure("Hobbycontrol");
+
+remark("interpreting $\theta$ and $\phi$ as the angle between the corresponding path direction vector and $z_1-z_0$.");
+
+item("Here there is an unambiguous reference vector for determining the relative sign of the angles $\phi$ and $\theta$.");
+
+viewportmargin=(2,0.5cm);
+//defaultpen(1.0);
+title("Interactive 3D Saddle");
+item("A unit circle in the $X$--$Y$ plane may be constructed with:
+{\tt (1,0,0)..(0,1,0)..(-1,0,0)..(0,-1,0)..cycle}:");
+asyinclude("unitcircle3",8cm);
+remark("and then distorted into the saddle\\
+{\tt (1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle}:");
+asyinclude("saddle",8cm);
+//defaultpen(0.5);
+
+title("Lifting TeX to 3D");
+item("Glyphs are first split into simply connected regions and then decomposed into planar B\'ezier surface patches \cite{Bowman09,Shardt12}:");
+asyfigure("../examples/partitionExample");
+
+viewportmargin=(2,1cm);
+title("Label Manipulation");
+item("They can then be extruded and/or arbitrarily transformed:");
+asyinclude("../examples/label3solid");
+
+title("Billboard Labels");
+defaultpen(fontsize(36pt));
+asyinclude("../examples/billboard",15cm);
+defaultpen(itempen);
+
+title("Smooth 3D surfaces");
+asyinclude("../examples/sinc",25cm);
+
+title("Curved 3D Arrows");
+asyinclude("../examples/arrows3",20cm);
+
+title("Slide Presentations");
+item("Asymptote has a module for preparing slides.");
+item("It even supports embedded high-resolution PDF movies.");
+
+code('
+title("Slide Presentations");
+item("Asymptote has a module for preparing slides.");
+item("It even supports embedded high-resolution PDF movies.");
+');
+remark("\quad\ldots");
+
+import graph;
+
+pen p=linewidth(1);
+pen dotpen=linewidth(5);
+
+pair wheelpoint(real t) {return (t+cos(t),-sin(t));}
+
+guide wheel(guide g=nullpath, real a, real b, int n)
+{
+ real width=(b-a)/n;
+ for(int i=0; i <= n; ++i) {
+ real t=a+width*i;
+ g=g--wheelpoint(t);
+ }
+ return g;
+}
+
+real t1=0;
+real t2=t1+2*pi;
+
+picture base;
+draw(base,circle((0,0),1),p);
+draw(base,wheel(t1,t2,100),p+linetype("0 2"));
+yequals(base,Label("$y=-1$",1.0),-1,extend=true,p+linetype("4 4"));
+xaxis(base,Label("$x$",align=3SW),0,p);
+yaxis(base,"$y$",0,1.3,p);
+pair z1=wheelpoint(t1);
+pair z2=wheelpoint(t2);
+dot(base,z1,dotpen);
+dot(base,z2,dotpen);
+
+animation a;
+
+int n=25;
+real dt=(t2-t1)/n;
+for(int i=0; i <= n; ++i) {
+ picture pic;
+ size(pic,24cm);
+ real t=t1+dt*i;
+ add(pic,base);
+ draw(pic,circle((t,0),1),p+red);
+ dot(pic,wheelpoint(t),dotpen);
+ a.add(pic);
+}
+
+display(a.pdf(delay=150,"controls"));
+
+title("Automatic Sizing");
+item("Figures can be specified in user coordinates, then
+ automatically scaled to the desired final size.");
+asyfigure(asywrite("
+import graph;
+
+size(0,100);
+
+frame cardsize(real w=0, real h=0, bool keepAspect=Aspect) {
+ picture pic;
+ pic.size(w,h,keepAspect);
+
+ real f(real t) {return 1+cos(t);}
+
+ guide g=polargraph(f,0,2pi,operator ..)--cycle;
+ filldraw(pic,g,pink);
+
+ xaxis(pic,\"$x$\",above=true);
+ yaxis(pic,\"$y$\",above=true);
+
+ dot(pic,\"$(a,0)$\",(1,0),N);
+ dot(pic,\"$(2a,0)$\",(2,0),N+E);
+
+ frame f=pic.fit();
+ label(f,\"{\tt size(\"+string(w)+\",\"+string(h)+\");}\",point(f,S),align=S);
+ return f;
+}
+
+add(cardsize(0,50), (0,0));
+add(cardsize(0,100), (230,0));
+add(cardsize(0,200), (540,0));
+"));
+
+title("Deferred Drawing");
+item("We can't draw a graphical object until we know the scaling
+ factors for the user coordinates.");
+item("Instead, store a function that, given the scaling information, draws
+ the scaled object.");
+code("
+void draw(picture pic=currentpicture, path g, pen p=currentpen) {
+ pic.add(new void(frame f, transform t) {
+ draw(f,t*g,p);
+ });
+ pic.addPoint(min(g),min(p));
+ pic.addPoint(max(g),max(p));
+}
+");
+
+title("Coordinates");
+item("Store bounding box information as the sum of user and true-size
+ coordinates:");
+asyfigure(asywrite("
+size(0,150);
+
+path q=(0,0){dir(70)}..{dir(70)}(100,50);
+pen p=rotate(30)*yscale(0.7)*(lightblue+linewidth(20));
+draw(q,p);
+draw((90,10),p);
+
+currentpicture.add(new void(frame f, transform t) {
+ draw(f,box(min(t*q)+min(p),max(t*q)+max(p)), dashed);
+ });
+
+draw(box(min(q),max(q)));
+
+frame f;
+draw(f,box(min(p),max(p)));
+
+add(f,min(q));
+add(f,max(q));
+
+draw(q);
+"));
+
+code("pic.addPoint(min(g),min(p));
+pic.addPoint(max(g),max(p));");
+item("Filling ignores the pen width:");
+code("pic.addPoint(min(g),(0,0));
+pic.addPoint(max(g),(0,0));");
+item("Communicate with \LaTeX\ {\it via\/} a pipe to determine label sizes:");
+
+asyfigure(asywrite("
+size(0,100);
+
+pen p=fontsize(30pt);
+frame f;
+label(f, \"$E=mc^2$\", p);
+draw(f, box(min(f),max(f)));
+shipout(f);
+"));
+
+title("Sizing");
+
+item("When scaling the final figure to a given size $S$, we first need to
+ determine a scaling factor $a>0$ and a shift $b$ so that all of the
+ coordinates when transformed will lie in the interval $[0,S]$.");
+
+item("That is, if $u$ and $t$ are the user and truesize components:");
+equation("0\le au+t+b \le S.");
+
+item("Maximize the variable $a$ subject to a number of inequalities.");
+
+item("Use the simplex method to solve the resulting linear programming problem.");
+
+if(long) {
+title("Sizing");
+item("Every addition of a coordinate $(t,u)$ adds two restrictions");
+equation("au+t+b\ge 0,");
+equation("au+t+b\le S,");
+remark("and each drawing component adds two coordinates.");
+item("A figure could easily produce thousands of restrictions, making the
+ simplex method impractical.");
+
+item("Most of these restrictions are redundant, however. For instance, with
+ concentric circles, only the largest circle needs to be accounted for.");
+asyfigure(asywrite("
+import palette;
+size(160,0);
+pen[] p=Rainbow(NColors=11);
+for(int i=1; i<10; ++i) {
+ draw(scale(i)*unitcircle, p[i]+linewidth(2));
+}
+"));
+
+title("Redundant Restrictions");
+item("In general, if $u\le u'$ and $t\le t'$ then");
+equation("au+t+b\le au'+t'+b");
+remark("for all choices of $a>0$ and $b$, so");
+equation("0\le au+t+b\le au'+t'+b\le S.");
+item("This defines a partial ordering on coordinates. When sizing a picture,
+ the program first computes which coordinates are maximal (or minimal) and
+ only sends effective constraints to the simplex algorithm.");
+item("In practice, the linear programming problem will have less than a dozen
+ restraints.");
+item("All picture sizing is implemented in Asymptote code.");
+}
+
+title("Infinite Lines");
+item("Deferred drawing allows us to draw infinite lines.");
+code("drawline(P, Q);");
+
+asyfigure("elliptic","height=12cm");
+
+title("Helpful Math Notation");
+
+item("Integer division returns a {\tt real}. Use {\tt quotient} for an integer
+ result:");
+code("3/4 == 0.75 quotient(3,4) == 0");
+
+item("Caret for real and integer exponentiation:");
+code("2^3 2.7^3 2.7^3.2");
+
+item("Many expressions can be implicitly scaled by a numeric constant:");
+code("2pi 10cm 2x^2 3sin(x) 2(a+b)");
+
+item("Pairs are complex numbers:");
+code("(0,1)*(0,1) == (-1,0)");
+
+title("Function Calls");
+
+item("Functions can take default arguments in any position. Arguments are
+ matched to the first possible location:");
+string unitsize="unitsize(0.65cm);";
+string preamble="void drawEllipse(real xsize=1, real ysize=xsize, pen p=blue) {
+ draw(xscale(xsize)*yscale(ysize)*unitcircle, p);
+}
+";
+
+asycode(preamble=unitsize,preamble+"
+drawEllipse(2);
+drawEllipse(red);
+");
+
+item("Arguments can be given by name:");
+asycode(preamble=unitsize+preamble,"
+drawEllipse(xsize=2, ysize=1);
+drawEllipse(ysize=2, xsize=3, green);
+");
+
+if(long) {
+title("Rest Arguments");
+item("Rest arguments allow one to write a function that takes an arbitrary
+ number of arguments:");
+code("
+int sum(... int[] nums) {
+ int total=0;
+ for(int i=0; i < nums.length; ++i)
+ total += nums[i];
+ return total;
+}
+
+sum(1,2,3,4); // returns 10
+sum(); // returns 0
+sum(1,2,3 ... new int[] {4,5,6}); // returns 21
+
+int subtract(int start ... int[] subs) {
+ return start - sum(... subs);
+}
+");
+}
+
+title("High-Order Functions");
+
+item("Functions are first-class values. They can be passed to other
+ functions:");
+code("import graph;
+real f(real x) {
+ return x*sin(10x);
+}
+draw(graph(f,-3,3,300),red);");
+asyfigure(asywrite("
+import graph;
+size(300,0);
+real f(real x) {
+ return x*sin(10x);
+}
+draw(graph(f,-3,3,300),red);
+"));
+
+if(long) {
+title("Higher-Order Functions");
+item("Functions can return functions:");
+equation("f_n(x)=n\sin\left(\frac{x}{n}\right).");
+skip();
+string preamble="
+import graph;
+size(300,0);
+";
+string graphfunc2="
+typedef real func(real);
+func f(int n) {
+ real fn(real x) {
+ return n*sin(x/n);
+ }
+ return fn;
+}
+
+func f1=f(1);
+real y=f1(pi);
+
+for(int i=1; i<=5; ++i)
+ draw(graph(f(i),-10,10),red);
+";
+code(graphfunc2);
+string name=asywrite(graphfunc2,preamble=preamble);
+asy(nativeformat(),name+".asy");
+label(graphic(name+"."+nativeformat()),(0.5,0),
+ Fill(figureborder,figuremattpen));
+
+title("Anonymous Functions");
+
+item("Create new functions with {\tt new}:");
+code("
+path p=graph(new real (real x) { return x*sin(10x); },-3,3,red);
+
+func f(int n) {
+ return new real (real x) { return n*sin(x/n); };
+}");
+
+item("Function definitions are just syntactic sugar for assigning function
+objects to variables.");
+code("
+real square(real x) {
+ return x^2;
+}
+");
+
+remark("is equivalent to");
+code("
+real square(real x);
+square=new real (real x) {
+ return x^2;
+};
+");
+
+title("Structures");
+
+item("As in other languages, structures group together data.");
+code("
+struct Person {
+ string firstname, lastname;
+ int age;
+}
+Person bob=new Person;
+bob.firstname=\"Bob\";
+bob.lastname=\"Chesterton\";
+bob.age=24;
+");
+
+item("Any code in the structure body will be executed every time a new structure
+ is allocated...");
+code("
+struct Person {
+ write(\"Making a person.\");
+ string firstname, lastname;
+ int age=18;
+}
+Person eve=new Person; // Writes \"Making a person.\"
+write(eve.age); // Writes 18.
+");
+
+title("Modules");
+
+item("Function and structure definitions can be grouped into modules:");
+code("
+// powers.asy
+real square(real x) { return x^2; }
+real cube(real x) { return x^3; }
+");
+remark("and imported:");
+code("
+import powers;
+real eight=cube(2.0);
+draw(graph(powers.square, -1, 1));
+");
+}
+
+title("Object-Oriented Programming");
+item("Functions are defined for each instance of a structure.");
+code("
+struct Quadratic {
+ real a,b,c;
+ real discriminant() {
+ return b^2-4*a*c;
+ }
+ real eval(real x) {
+ return a*x^2 + b*x + c;
+ }
+}
+");
+
+item("This allows us to construct ``methods'' which are just normal functions
+ declared in the environment of a particular object:");
+code("
+Quadratic poly=new Quadratic;
+poly.a=-1; poly.b=1; poly.c=2;
+
+real f(real x)=poly.eval;
+real y=f(2);
+draw(graph(poly.eval, -5, 5));
+");
+
+title("Specialization");
+
+item("Can create specialized objects just by redefining methods:");
+code("
+struct Shape {
+ void draw();
+ real area();
+}
+
+Shape rectangle(real w, real h) {
+ Shape s=new Shape;
+ s.draw = new void () {
+ fill((0,0)--(w,0)--(w,h)--(0,h)--cycle); };
+ s.area = new real () { return w*h; };
+ return s;
+}
+
+Shape circle(real radius) {
+ Shape s=new Shape;
+ s.draw = new void () { fill(scale(radius)*unitcircle); };
+ s.area = new real () { return pi*radius^2; }
+ return s;
+}
+");
+
+title("Overloading");
+item("Consider the code:");
+code("
+int x1=2;
+int x2() {
+ return 7;
+}
+int x3(int y) {
+ return 2y;
+}
+
+write(x1+x2()); // Writes 9.
+write(x3(x1)+x2()); // Writes 11.
+");
+
+title("Overloading");
+item("{\tt x1}, {\tt x2}, and {\tt x3} are never used in the same context, so
+ they can all be renamed {\tt x} without ambiguity:");
+code("
+int x=2;
+int x() {
+ return 7;
+}
+int x(int y) {
+ return 2y;
+}
+
+write(x+x()); // Writes 9.
+write(x(x)+x()); // Writes 11.
+");
+
+item("Function definitions are just variable definitions, but variables are
+ distinguished by their signatures to allow overloading.");
+
+title("Operators");
+item("Operators are just syntactic sugar for functions, and can be addressed or
+ defined as functions with the {\tt operator} keyword.");
+code("
+int add(int x, int y)=operator +;
+write(add(2,3)); // Writes 5.
+
+// Don't try this at home.
+int operator +(int x, int y) {
+ return add(2x,y);
+}
+write(2+3); // Writes 7.
+");
+item("This allows operators to be defined for new types.");
+
+title("Operators");
+item("Operators for constructing paths are also functions:");
+code("a.. controls b and c .. d--e");
+remark("is equivalent to");
+code(
+ "operator --(operator ..(a, operator controls(b,c), d), e)");
+item("This allowed us to redefine all of the path operators for 3D paths.");
+
+title("Summary");
+
+item("Asymptote:");
+subitem("uses IEEE floating point numerics;");
+subitem("uses C++/Java-like syntax;");
+subitem("supports deferred drawing for automatic picture sizing;");
+subitem("supports Grayscale, RGB, CMYK, and HSV colour spaces;");
+subitem("supports PostScript shading, pattern fills, and function shading;");
+subitem("can fill nonsimply connected regions;");
+subitem("generalizes MetaPost path construction algorithms to 3D;");
+subitem("lifts \TeX\ to 3D;");
+subitem("supports 3D billboard labels and PDF grouping.");
+
+bibliography("../examples/refs");
+
+viewportmargin=(2,2);
+viewportsize=0;
+defaultpen(0.5);
+title("\mbox{Asymptote: 2D \& 3D Vector Graphics Language}");
+asyinclude("../examples/logo3");
+skip();
+center("\tt http://asymptote.sf.net");
+center("(freely available under the LGPL license)");
+
+// LocalWords: pdflatex mflogo viewportsize pagewidth pagemargin goysr bibtex
+// LocalWords: itempen defaultrender medskip Orest Shardt Vidiassov MF ezier
+// LocalWords: Hammerlindl MetaPost PDF hfill LGPL pdf asywrite zoombox LaTeX
+// LocalWords: asyfilecode PostScript asycode unitsquare beziercurve grey bw
+// LocalWords: lightgrey zerowinding evenodd sw unitsize drawEllipse nums fn
+// LocalWords: frac graphfunc func nativeformat figureborder figuremattpen bt
+// LocalWords: firstname lastname eval eetomumu binarytree filecode datagraph
+// LocalWords: lineargraph filegraph loggraph secondaryaxis imagecontour ij
+// LocalWords: tridiagonal Hobbydir nonumber Hobbycontrol th viewportmargin
+// LocalWords: asyinclude dotpen wheelpoint yequals xaxis yaxis cardsize mc
+// LocalWords: polargraph filldraw addPoint lightblue truesize le au NColors
+// LocalWords: drawline unityroot mult oct intang IEEE numerics HSV colour
+// LocalWords: nonsimply
diff --git a/graphics/asymptote/doc/filegraph.asy b/graphics/asymptote/doc/filegraph.asy
new file mode 100644
index 0000000000..0add531a3e
--- /dev/null
+++ b/graphics/asymptote/doc/filegraph.asy
@@ -0,0 +1,15 @@
+import graph;
+
+size(200,150,IgnoreAspect);
+
+file in=input("filegraph.dat").line();
+real[][] a=in;
+a=transpose(a);
+
+real[] x=a[0];
+real[] y=a[1];
+
+draw(graph(x,y),red);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
diff --git a/graphics/asymptote/doc/filegraph.dat b/graphics/asymptote/doc/filegraph.dat
new file mode 100644
index 0000000000..f69ffe330d
--- /dev/null
+++ b/graphics/asymptote/doc/filegraph.dat
@@ -0,0 +1,4 @@
+# x y
+ 50 0
+100 0.5
+125 2
diff --git a/graphics/asymptote/doc/flow.asy b/graphics/asymptote/doc/flow.asy
new file mode 100644
index 0000000000..aba6c5aa05
--- /dev/null
+++ b/graphics/asymptote/doc/flow.asy
@@ -0,0 +1,31 @@
+import graph;
+defaultpen(1.0);
+
+size(0,150,IgnoreAspect);
+
+real arrowsize=4mm;
+real arrowlength=2arrowsize;
+
+typedef path vector(real);
+
+// Return a vector interpolated linearly between a and b.
+vector vector(pair a, pair b) {
+ return new path(real x) {
+ return (0,0)--arrowlength*interp(a,b,x);
+ };
+}
+
+real f(real x) {return 1/x;}
+
+real epsilon=0.5;
+path g=graph(f,epsilon,1/epsilon);
+
+int n=3;
+draw(g);
+xaxis("$x$");
+yaxis("$y$");
+
+add(vectorfield(vector(W,W),g,n,true));
+add(vectorfield(vector(NE,NW),(0,0)--(point(E).x,0),n,true));
+add(vectorfield(vector(NE,NE),(0,0)--(0,point(N).y),n,true));
+
diff --git a/graphics/asymptote/doc/flowchartdemo.asy b/graphics/asymptote/doc/flowchartdemo.asy
new file mode 100644
index 0000000000..796e357a5f
--- /dev/null
+++ b/graphics/asymptote/doc/flowchartdemo.asy
@@ -0,0 +1,27 @@
+size(0,300);
+
+import flowchart;
+
+block block1=rectangle(Label("Example",magenta),
+ pack(Label("Start:",heavygreen),"",Label("$A:=0$",blue),
+ "$B:=1$"),(-0.5,3),palegreen,paleblue,red);
+block block2=diamond(Label("Choice?",blue),(0,2),palegreen,red);
+block block3=roundrectangle("Do something",(-1,1));
+block block4=bevel("Don't do something",(1,1));
+block block5=circle("End",(0,0));
+
+draw(block1);
+draw(block2);
+draw(block3);
+draw(block4);
+draw(block5);
+
+add(new void(picture pic, transform t) {
+ blockconnector operator --=blockconnector(pic,t);
+ // draw(pic,block1.right(t)--block2.top(t));
+ block1--Right--Down--Arrow--block2;
+ block2--Label("Yes",0.5,NW)--Left--Down--Arrow--block3;
+ block2--Right--Label("No",0.5,NE)--Down--Arrow--block4;
+ block4--Down--Left--Arrow--block5;
+ block3--Down--Right--Arrow--block5;
+ });
diff --git a/graphics/asymptote/doc/generalaxis.asy b/graphics/asymptote/doc/generalaxis.asy
new file mode 100644
index 0000000000..dfe1000838
--- /dev/null
+++ b/graphics/asymptote/doc/generalaxis.asy
@@ -0,0 +1,11 @@
+import graph;
+size(0,100);
+
+path g=ellipse((0,0),1,2);
+
+scale(true);
+
+axis(Label("C",align=10W),g,LeftTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path h=(0,0)--max(abs(max(g)),abs(min(g)))*dir(v);
+ return intersect(g,h)[0];}));
diff --git a/graphics/asymptote/doc/generalaxis3.asy b/graphics/asymptote/doc/generalaxis3.asy
new file mode 100644
index 0000000000..68a01c8ce2
--- /dev/null
+++ b/graphics/asymptote/doc/generalaxis3.asy
@@ -0,0 +1,13 @@
+import graph3;
+
+size(0,100);
+
+path3 g=yscale3(2)*unitcircle3;
+currentprojection=perspective(10,10,10);
+
+axis(Label("C",position=0,align=15X),g,InTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path3 h=O--max(abs(max(g)),abs(min(g)))*dir(90,v);
+ return intersect(g,h)[0];},
+ new triple(real t) {return cross(dir(g,t),Z);}));
+
diff --git a/graphics/asymptote/doc/graphmarkers.asy b/graphics/asymptote/doc/graphmarkers.asy
new file mode 100644
index 0000000000..f40f00d9ff
--- /dev/null
+++ b/graphics/asymptote/doc/graphmarkers.asy
@@ -0,0 +1,37 @@
+import graph;
+
+size(200,100,IgnoreAspect);
+
+markroutine marks() {
+ return new void(picture pic=currentpicture, frame f, path g) {
+ path p=scale(1mm)*unitcircle;
+ for(int i=0; i <= length(g); ++i) {
+ pair z=point(g,i);
+ frame f;
+ if(i % 4 == 0) {
+ fill(f,p);
+ add(pic,f,z);
+ } else {
+ if(z.y > 50) {
+ pic.add(new void(frame F, transform t) {
+ path q=shift(t*z)*p;
+ unfill(F,q);
+ draw(F,q);
+ });
+ } else {
+ draw(f,p);
+ add(pic,f,z);
+ }
+ }
+ }
+ };
+}
+
+pair[] f={(5,5),(40,20),(55,51),(90,30)};
+
+draw(graph(f),marker(marks()));
+
+scale(true);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
diff --git a/graphics/asymptote/doc/grid3xyz.asy b/graphics/asymptote/doc/grid3xyz.asy
new file mode 100644
index 0000000000..888b9202ee
--- /dev/null
+++ b/graphics/asymptote/doc/grid3xyz.asy
@@ -0,0 +1,17 @@
+import grid3;
+
+size(8cm,0,IgnoreAspect);
+currentprojection=orthographic(0.5,1,0.5);
+
+scale(Linear, Linear, Log);
+
+limits((-2,-2,1),(0,2,100));
+
+grid3(XYZgrid);
+
+xaxis3(Label("$x$",position=EndPoint,align=S),Bounds(Min,Min),
+ OutTicks());
+yaxis3(Label("$y$",position=EndPoint,align=S),Bounds(Min,Min),OutTicks());
+zaxis3(Label("$z$",position=EndPoint,align=(-1,0.5)),Bounds(Min,Min),
+ OutTicks(beginlabel=false));
+
diff --git a/graphics/asymptote/doc/hatch.asy b/graphics/asymptote/doc/hatch.asy
new file mode 100644
index 0000000000..126b5bec13
--- /dev/null
+++ b/graphics/asymptote/doc/hatch.asy
@@ -0,0 +1,11 @@
+size(0,100);
+import patterns;
+
+add("hatch",hatch());
+add("hatchback",hatch(NW));
+add("crosshatch",crosshatch(3mm));
+
+real s=1.25;
+filldraw(unitsquare,pattern("hatch"));
+filldraw(shift(s,0)*unitsquare,pattern("hatchback"));
+filldraw(shift(2s,0)*unitsquare,pattern("crosshatch"));
diff --git a/graphics/asymptote/doc/helix.asy b/graphics/asymptote/doc/helix.asy
new file mode 100644
index 0000000000..0925e0821b
--- /dev/null
+++ b/graphics/asymptote/doc/helix.asy
@@ -0,0 +1,20 @@
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=orthographic(4,6,3);
+
+real x(real t) {return cos(2pi*t);}
+real y(real t) {return sin(2pi*t);}
+real z(real t) {return t;}
+
+path3 p=graph(x,y,z,0,2.7,operator ..);
+
+draw(p,Arrow3);
+
+scale(true);
+
+xaxis3(XZ()*"$x$",Bounds,red,InTicks(Label,2,2));
+yaxis3(YZ()*"$y$",Bounds,red,InTicks(beginlabel=false,Label,2,2));
+zaxis3(XZ()*"$z$",Bounds,red,InTicks);
diff --git a/graphics/asymptote/doc/histogram.asy b/graphics/asymptote/doc/histogram.asy
new file mode 100644
index 0000000000..ec00d6638d
--- /dev/null
+++ b/graphics/asymptote/doc/histogram.asy
@@ -0,0 +1,19 @@
+import graph;
+import stats;
+
+size(400,200,IgnoreAspect);
+
+int n=10000;
+real[] a=new real[n];
+for(int i=0; i < n; ++i) a[i]=Gaussrand();
+
+draw(graph(Gaussian,min(a),max(a)),blue);
+
+// Optionally calculate "optimal" number of bins a la Shimazaki and Shinomoto.
+int N=bins(a);
+
+histogram(a,min(a),max(a),N,normalize=true,low=0,lightred,black,bars=false);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$dP/dx$",LeftRight,RightTicks(trailingzero));
+
diff --git a/graphics/asymptote/doc/icon.asy b/graphics/asymptote/doc/icon.asy
new file mode 100644
index 0000000000..1701fe0f32
--- /dev/null
+++ b/graphics/asymptote/doc/icon.asy
@@ -0,0 +1,22 @@
+import graph;
+
+size(30,30,IgnoreAspect);
+
+real f(real t) {return t < 0 ? -1/t : -0.5/t;}
+
+picture logo(pair s=0, pen q)
+{
+ picture pic;
+ pen p=linewidth(3)+q;
+ real a=-0.5;
+ real b=1;
+ real eps=0.1;
+ draw(pic,shift((eps,-f(a)))*graph(f,a,-eps),p);
+ real c=0.5*a;
+ pair z=(0,f(c)-f(a));
+ draw(pic,z+c+eps--z,p);
+ yaxis(pic,p);
+ return shift(s)*pic;
+}
+
+add(logo(red));
diff --git a/graphics/asymptote/doc/image.asy b/graphics/asymptote/doc/image.asy
new file mode 100644
index 0000000000..37a2cf6017
--- /dev/null
+++ b/graphics/asymptote/doc/image.asy
@@ -0,0 +1,21 @@
+size(12cm,12cm);
+
+import graph;
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+real[][] v=new real[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=sin(i*ninv)*cos(j*ninv);
+
+pen[] Palette=BWRainbow();
+
+picture bar;
+
+bounds range=image(v,(0,0),(1,1),Palette);
+palette(bar,"$A$",range,(0,0),(0.5cm,8cm),Right,Palette,
+ PaletteTicks("$%+#.1f$"));
+add(bar.fit(),point(E),30E);
diff --git a/graphics/asymptote/doc/imagecontour.asy b/graphics/asymptote/doc/imagecontour.asy
new file mode 100644
index 0000000000..6b5eb455ca
--- /dev/null
+++ b/graphics/asymptote/doc/imagecontour.asy
@@ -0,0 +1,38 @@
+import graph;
+import palette;
+import contour;
+
+size(10cm,10cm,IgnoreAspect);
+
+pair a=(0,0);
+pair b=(2pi,2pi);
+
+real f(real x, real y) {return cos(x)*sin(y);}
+
+int N=200;
+int Divs=10;
+int divs=2;
+
+defaultpen(1bp);
+pen Tickpen=black;
+pen tickpen=gray+0.5*linewidth(currentpen);
+pen[] Palette=BWRainbow();
+
+bounds range=image(f,Automatic,a,b,N,Palette);
+
+// Major contours
+
+real[] Cvals=uniform(range.min,range.max,Divs);
+draw(contour(f,a,b,Cvals,N,operator --),Tickpen);
+
+// Minor contours
+real[] cvals;
+for(int i=0; i < Cvals.length-1; ++i)
+ cvals.append(uniform(Cvals[i],Cvals[i+1],divs)[1:divs]);
+draw(contour(f,a,b,cvals,N,operator --),tickpen);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,point(NW)+(0,0.5),point(NE)+(0,1),Top,Palette,
+ PaletteTicks(N=Divs,n=divs,Tickpen,tickpen));
diff --git a/graphics/asymptote/doc/install-sh b/graphics/asymptote/doc/install-sh
new file mode 100755
index 0000000000..6781b987bd
--- /dev/null
+++ b/graphics/asymptote/doc/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/graphics/asymptote/doc/irregularcontour.asy b/graphics/asymptote/doc/irregularcontour.asy
new file mode 100644
index 0000000000..70b38ae15e
--- /dev/null
+++ b/graphics/asymptote/doc/irregularcontour.asy
@@ -0,0 +1,21 @@
+import contour;
+
+size(200);
+
+int n=100;
+
+real f(real a, real b) {return a^2+b^2;}
+
+srand(1);
+
+real r() {return 1.1*(rand()/randMax*2-1);}
+
+pair[] points=new pair[n];
+real[] values=new real[n];
+
+for(int i=0; i < n; ++i) {
+ points[i]=(r(),r());
+ values[i]=f(points[i].x,points[i].y);
+}
+
+draw(contour(points,values,new real[]{0.25,0.5,1},operator ..),blue);
diff --git a/graphics/asymptote/doc/join.asy b/graphics/asymptote/doc/join.asy
new file mode 100644
index 0000000000..75fa14f36c
--- /dev/null
+++ b/graphics/asymptote/doc/join.asy
@@ -0,0 +1,15 @@
+size(300,0);
+pair[] z=new pair[10];
+
+z[0]=(0,100); z[1]=(50,0); z[2]=(180,0);
+
+for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0);
+
+path p=z[0]..z[1]---z[2]::{up}z[3]
+&z[3]..z[4]--z[5]::{up}z[6]
+&z[6]::z[7]---z[8]..{up}z[9];
+
+draw(p,grey+linewidth(4mm));
+
+dot(z);
diff --git a/graphics/asymptote/doc/join3.asy b/graphics/asymptote/doc/join3.asy
new file mode 100644
index 0000000000..9513d522b4
--- /dev/null
+++ b/graphics/asymptote/doc/join3.asy
@@ -0,0 +1,21 @@
+import graph3;
+
+size(200);
+
+currentprojection=orthographic(500,-500,500);
+
+triple[] z=new triple[10];
+
+z[0]=(0,100,0); z[1]=(50,0,0); z[2]=(180,0,0);
+
+for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0,0);
+
+path3 p=z[0]..z[1]---z[2]::{Y}z[3]
+&z[3]..z[4]--z[5]::{Y}z[6]
+&z[6]::z[7]---z[8]..{Y}z[9];
+
+draw(p,grey+linewidth(4mm),currentlight);
+
+xaxis3(Label(XY()*"$x$",align=-3Y),red,above=true);
+yaxis3(Label(XY()*"$y$",align=-3X),red,above=true);
diff --git a/graphics/asymptote/doc/knots.asy b/graphics/asymptote/doc/knots.asy
new file mode 100644
index 0000000000..48881459d0
--- /dev/null
+++ b/graphics/asymptote/doc/knots.asy
@@ -0,0 +1,27 @@
+import syzygy;
+
+Braid initial;
+initial.n = 4;
+initial.add(bp,1);
+initial.add(bp,0);
+initial.add(bp,2);
+initial.add(bp,1);
+initial.add(phi,2);
+initial.add(phi,0);
+
+Syzygy pp;
+pp.lsym="\Phi\Phi"; pp.codename="PhiAroundPhi";
+
+pp.number=true;
+pp.initial=initial;
+pp.apply(r4b,2,1);
+pp.apply(r4b,0,0);
+pp.apply(r4a,1,0);
+pp.swap(0,1);
+pp.apply(-r4b,1,0);
+pp.apply(-r4a,0,1);
+pp.apply(-r4a,2,0);
+pp.swap(4,5);
+
+pp.draw();
+
diff --git a/graphics/asymptote/doc/labelsquare.asy b/graphics/asymptote/doc/labelsquare.asy
new file mode 100644
index 0000000000..9531792b6a
--- /dev/null
+++ b/graphics/asymptote/doc/labelsquare.asy
@@ -0,0 +1,6 @@
+size(3cm);
+draw(unitsquare);
+label("$A$",(0,0),SW);
+label("$B$",(1,0),SE);
+label("$C$",(1,1),NE);
+label("$D$",(0,1),NW);
diff --git a/graphics/asymptote/doc/latexmkrc b/graphics/asymptote/doc/latexmkrc
new file mode 100644
index 0000000000..fbc52a98d2
--- /dev/null
+++ b/graphics/asymptote/doc/latexmkrc
@@ -0,0 +1,4 @@
+sub asy {return system("asy \"$_[0]\"");}
+add_cus_dep("asy","eps",0,"asy");
+add_cus_dep("asy","pdf",0,"asy");
+add_cus_dep("asy","tex",0,"asy");
diff --git a/graphics/asymptote/doc/latexmkrc_asydir b/graphics/asymptote/doc/latexmkrc_asydir
new file mode 100644
index 0000000000..043084e8e6
--- /dev/null
+++ b/graphics/asymptote/doc/latexmkrc_asydir
@@ -0,0 +1,4 @@
+sub asy {return system("asy -o asy/ '$_[0]'");}
+add_cus_dep("asy","eps",0,"asy");
+add_cus_dep("asy","pdf",0,"asy");
+add_cus_dep("asy","tex",0,"asy");
diff --git a/graphics/asymptote/doc/latexusage.tex b/graphics/asymptote/doc/latexusage.tex
new file mode 100644
index 0000000000..07b0e56a35
--- /dev/null
+++ b/graphics/asymptote/doc/latexusage.tex
@@ -0,0 +1,119 @@
+\documentclass[12pt]{article}
+
+% Use this form to include EPS (latex) or PDF (pdflatex) files:
+%\usepackage{asymptote}
+
+% Use this form with latex or pdflatex to include inline LaTeX code by default:
+\usepackage[inline]{asymptote}
+
+% Use this form with latex or pdflatex to create PDF attachments by default:
+%\usepackage[attach]{asymptote}
+
+% Enable this line to support the attach option:
+%\usepackage[dvips]{attachfile2}
+
+\begin{document}
+
+% Optional subdirectory for latex files (no spaces):
+\def\asylatexdir{}
+% Optional subdirectory for asy files (no spaces):
+\def\asydir{}
+
+\begin{asydef}
+// Global Asymptote definitions can be put here.
+import three;
+usepackage("bm");
+texpreamble("\def\V#1{\bm{#1}}");
+// One can globally override the default toolbar settings here:
+// settings.toolbar=true;
+\end{asydef}
+
+Here is a venn diagram produced with Asymptote, drawn to width 4cm:
+
+\def\A{A}
+\def\B{\V{B}}
+
+%\begin{figure}
+\begin{center}
+\begin{asy}
+size(4cm,0);
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+fill(c1,colour1);
+fill(c2,colour2);
+
+picture intersection=new picture;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+//draw("$\A$",box,z1); // Requires [inline] package option.
+//draw(Label("$\B$","$B$"),box,z2); // Requires [inline] package option.
+draw("$A$",box,z1);
+draw("$\V{B}$",box,z2);
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
+
+shipout(bbox(0.25cm));
+\end{asy}
+%\caption{Venn diagram}\label{venn}
+\end{center}
+%\end{figure}
+
+Each graph is drawn in its own environment. One can specify the width
+and height to \LaTeX\ explicitly. This 3D example can be viewed
+interactively either with Adobe Reader or Asymptote's fast OpenGL-based
+renderer. To support {\tt latexmk}, 3D figures should specify
+\verb+inline=true+. It is sometimes desirable to embed 3D files as annotated
+attachments; this requires the \verb+attach=true+ option as well as the
+\verb+attachfile2+ \LaTeX\ package.
+\begin{center}
+\begin{asy}[height=4cm,inline=true,attach=false,viewportwidth=\linewidth]
+currentprojection=orthographic(5,4,2);
+draw(unitcube,blue);
+label("$V-E+F=2$",(0,1,0.5),3Y,blue+fontsize(17pt));
+\end{asy}
+\end{center}
+
+One can also scale the figure to the full line width:
+\begin{center}
+\begin{asy}[width=\the\linewidth,inline=true]
+pair z0=(0,0);
+pair z1=(2,0);
+pair z2=(5,0);
+pair zf=z1+0.75*(z2-z1);
+
+draw(z1--z2);
+dot(z1,red+0.15cm);
+dot(z2,darkgreen+0.3cm);
+label("$m$",z1,1.2N,red);
+label("$M$",z2,1.5N,darkgreen);
+label("$\hat{\ }$",zf,0.2*S,fontsize(24pt)+blue);
+
+pair s=-0.2*I;
+draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
+s=-0.5*I;
+draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
+s=-0.95*I;
+draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
+\end{asy}
+\end{center}
+\end{document}
diff --git a/graphics/asymptote/doc/leastsquares.asy b/graphics/asymptote/doc/leastsquares.asy
new file mode 100644
index 0000000000..37477d5885
--- /dev/null
+++ b/graphics/asymptote/doc/leastsquares.asy
@@ -0,0 +1,55 @@
+size(400,200,IgnoreAspect);
+
+import graph;
+import stats;
+
+file fin=input("leastsquares.dat").line();
+
+real[][] a=fin;
+a=transpose(a);
+
+real[] t=a[0], rho=a[1];
+
+// Read in parameters from the keyboard:
+//real first=getreal("first");
+//real step=getreal("step");
+//real last=getreal("last");
+
+real first=100;
+real step=50;
+real last=700;
+
+// Remove negative or zero values of rho:
+t=rho > 0 ? t : null;
+rho=rho > 0 ? rho : null;
+
+scale(Log(true),Linear(true));
+
+int n=step > 0 ? ceil((last-first)/step) : 0;
+
+real[] T,xi,dxi;
+
+for(int i=0; i <= n; ++i) {
+ real first=first+i*step;
+ real[] logrho=(t >= first & t <= last) ? log(rho) : null;
+ real[] logt=(t >= first & t <= last) ? -log(t) : null;
+
+ if(logt.length < 2) break;
+
+ // Fit to the line logt=L.m*logrho+L.b:
+ linefit L=leastsquares(logt,logrho);
+
+ T.push(first);
+ xi.push(L.m);
+ dxi.push(L.dm);
+}
+
+draw(graph(T,xi),blue);
+errorbars(T,xi,dxi,red);
+
+crop();
+
+ylimits(0);
+
+xaxis("$T$",BottomTop,LeftTicks);
+yaxis("$\xi$",LeftRight,RightTicks);
diff --git a/graphics/asymptote/doc/leastsquares.dat b/graphics/asymptote/doc/leastsquares.dat
new file mode 100644
index 0000000000..a4d63d6e10
--- /dev/null
+++ b/graphics/asymptote/doc/leastsquares.dat
@@ -0,0 +1,882 @@
+1 3825
+2 4057
+3 4217
+4 4278
+5 4353
+6 4483
+7 4410
+8 4462
+9 4626
+10 4511
+11 4531
+12 4450
+13 4354
+14 4402
+15 4489
+16 4441
+17 4366
+18 4443
+19 4442
+20 4335
+21 4292
+22 4458
+23 4444
+24 4426
+25 4310
+26 4264
+27 4263
+28 4252
+29 4330
+30 4304
+31 4242
+32 4272
+33 4284
+34 4198
+35 4242
+36 4096
+37 4142
+38 4248
+39 4186
+40 4210
+41 4125
+42 4134
+43 4098
+44 4129
+45 3960
+46 4012
+47 4079
+48 4038
+49 4024
+50 3949
+51 3996
+52 3970
+53 4031
+54 3895
+55 3806
+56 3825
+57 3850
+58 3742
+59 3678
+60 3589
+61 3648
+62 3476
+63 3490
+64 3353
+65 3270
+66 3134
+67 3018
+68 2922
+69 2801
+70 2691
+71 2528
+72 2460
+73 2254
+74 2105
+75 2009
+76 1854
+77 1677
+78 1562
+79 1501
+80 1399
+81 1244
+82 1160
+83 1080
+84 963
+85 879
+86 797
+87 745
+88 701
+89 634
+90 554
+91 532
+92 549
+93 521
+94 466
+95 460
+96 435
+97 412
+98 376
+99 367
+100 350
+101 360
+102 321
+103 302
+104 291
+105 273
+106 261
+107 255
+108 231
+109 245
+110 252
+111 236
+112 227
+113 207
+114 196
+115 199
+116 211
+117 232
+118 220
+119 214
+120 229
+121 213
+122 208
+123 196
+124 218
+125 196
+126 192
+127 178
+128 177
+129 178
+130 179
+131 170
+132 173
+133 170
+134 150
+135 144
+136 149
+137 145
+138 145
+139 139
+140 147
+141 140
+142 128
+143 133
+144 156
+145 136
+146 164
+147 152
+148 140
+149 141
+150 112
+151 108
+152 110
+153 133
+154 118
+155 113
+156 113
+157 108
+158 88
+159 109
+160 97
+161 99
+162 94
+163 97
+164 104
+165 105
+166 118
+167 108
+168 130
+169 126
+170 114
+171 112
+172 107
+173 96
+174 96
+175 102
+176 85
+177 89
+178 93
+179 96
+180 101
+181 82
+182 97
+183 96
+184 94
+185 97
+186 85
+187 79
+188 72
+189 75
+190 63
+191 65
+192 62
+193 54
+194 53
+195 49
+196 55
+197 48
+198 53
+199 46
+200 50
+201 48
+202 50
+203 51
+204 50
+205 49
+206 46
+207 47
+208 44
+209 42
+210 47
+211 45
+212 44
+213 46
+214 43
+215 40
+216 42
+217 41
+218 40
+219 43
+220 41
+221 42
+222 43
+223 40
+224 42
+225 39
+226 41
+227 42
+228 44
+229 40
+230 40
+231 35
+232 38
+233 37
+234 36
+235 34
+236 34
+237 34
+238 36
+239 36
+240 36
+241 37
+242 37
+243 37
+244 36
+245 36
+246 45
+247 43
+248 43
+249 43
+250 49
+251 58
+252 48
+253 50
+254 56
+255 51
+256 50
+257 55
+258 64
+259 55
+260 49
+261 36
+262 36
+263 40
+264 49
+265 37
+266 35
+267 35
+268 33
+269 33
+270 39
+271 35
+272 34
+273 36
+274 32
+275 37
+276 31
+277 31
+278 32
+279 30
+280 32
+281 29
+282 31
+283 30
+284 30
+285 28
+286 27
+287 26
+288 24
+289 25
+290 28
+291 30
+292 29
+293 27
+294 27
+295 27
+296 26
+297 26
+298 28
+299 27
+300 24
+301 22
+302 27
+303 26
+304 25
+305 25
+306 25
+307 26
+308 28
+309 26
+310 25
+311 24
+312 26
+313 25
+314 23
+315 25
+316 24
+317 23
+318 23
+319 24
+320 23
+321 24
+322 22
+323 24
+324 24
+325 24
+326 23
+327 25
+328 24
+329 22
+330 22
+331 23
+332 23
+333 23
+334 21
+335 19
+336 20
+337 22
+338 26
+339 25
+340 24
+341 22
+342 22
+343 23
+344 23
+345 23
+346 20
+347 21
+348 20
+349 21
+350 25
+351 22
+352 22
+353 21
+354 24
+355 24
+356 22
+357 23
+358 26
+359 24
+360 23
+361 22
+362 26
+363 30
+364 27
+365 25
+366 26
+367 26
+368 25
+369 24
+370 24
+371 22
+372 21
+373 20
+374 20
+375 19
+376 20
+377 21
+378 20
+379 20
+380 19
+381 19
+382 19
+383 19
+384 20
+385 20
+386 19
+387 20
+388 20
+389 20
+390 17
+391 18
+392 16
+393 18
+394 32
+395 31
+396 47
+397 57
+398 64
+399 34
+400 42
+401 40
+402 41
+403 35
+404 26
+405 25
+406 25
+407 36
+408 42
+409 55
+410 75
+411 94
+412 87
+413 97
+414 95
+415 101
+416 70
+417 66
+418 66
+419 73
+420 77
+421 89
+422 79
+423 63
+424 66
+425 71
+426 70
+427 49
+428 46
+429 46
+430 43
+431 49
+432 48
+433 44
+434 36
+435 33
+436 28
+437 29
+438 32
+439 31
+440 29
+441 28
+442 29
+443 31
+444 31
+445 33
+446 33
+447 39
+448 44
+449 37
+450 58
+451 64
+452 38
+453 31
+454 36
+455 33
+456 29
+457 34
+458 28
+459 27
+460 23
+461 31
+462 26
+463 21
+464 23
+465 26
+466 21
+467 21
+468 24
+469 24
+470 24
+471 24
+472 26
+473 23
+474 26
+475 20
+476 21
+477 25
+478 21
+479 22
+480 22
+481 23
+482 22
+483 23
+484 22
+485 20
+486 22
+487 20
+488 22
+489 20
+490 24
+491 20
+492 22
+493 19
+494 19
+495 20
+496 19
+497 18
+498 18
+499 17
+500 16
+501 16
+502 17
+503 17
+504 16
+505 17
+506 16
+507 16
+508 16
+509 17
+510 18
+511 17
+512 16
+513 17
+514 16
+515 16
+516 16
+517 17
+518 16
+519 16
+520 16
+521 16
+522 16
+523 16
+524 16
+525 16
+526 16
+527 17
+528 17
+529 18
+530 17
+531 16
+532 15
+533 15
+534 15
+535 15
+536 16
+537 17
+538 16
+539 18
+540 17
+541 17
+542 15
+543 15
+544 15
+545 16
+546 15
+547 15
+548 15
+549 15
+550 15
+551 14
+552 14
+553 14
+554 14
+555 14
+556 14
+557 14
+558 15
+559 14
+560 16
+561 15
+562 16
+563 17
+564 15
+565 14
+566 17
+567 18
+568 17
+569 16
+570 17
+571 14
+572 15
+573 15
+574 15
+575 14
+576 15
+577 14
+578 14
+579 13
+580 13
+581 13
+582 13
+583 13
+584 12
+585 12
+586 13
+587 12
+588 12
+589 12
+590 13
+591 15
+592 16
+593 14
+594 13
+595 14
+596 13
+597 13
+598 13
+599 13
+600 14
+601 13
+602 13
+603 13
+604 14
+605 15
+606 15
+607 15
+608 15
+609 15
+610 15
+611 15
+612 15
+613 15
+614 15
+615 15
+616 14
+617 14
+618 14
+619 14
+620 14
+621 14
+622 14
+623 15
+624 15
+625 15
+626 14
+627 15
+628 14
+629 14
+630 14
+631 14
+632 14
+633 14
+634 13
+635 13
+636 13
+637 13
+638 13
+639 13
+640 13
+641 13
+642 13
+643 13
+644 13
+645 13
+646 13
+647 13
+648 13
+649 13
+650 13
+651 13
+652 13
+653 13
+654 13
+655 13
+656 13
+657 13
+658 13
+659 13
+660 13
+661 13
+662 13
+663 13
+664 13
+665 13
+666 13
+667 13
+668 13
+669 13
+670 13
+671 13
+672 13
+673 13
+674 13
+675 13
+676 13
+677 13
+678 13
+679 12
+680 12
+681 13
+682 13
+683 13
+684 13
+685 12
+686 12
+687 13
+688 13
+689 13
+690 13
+691 13
+692 13
+693 13
+694 13
+695 13
+696 13
+697 13
+698 13
+699 13
+700 13
+701 13
+702 13
+703 13
+704 13
+705 13
+706 13
+707 13
+708 13
+709 13
+710 13
+711 13
+712 13
+713 13
+714 13
+715 13
+716 13
+717 13
+718 13
+719 13
+720 13
+721 13
+722 13
+723 13
+724 13
+725 13
+726 13
+727 13
+728 13
+729 13
+730 13
+731 13
+732 13
+733 13
+734 13
+735 13
+736 13
+737 13
+738 13
+739 13
+740 13
+741 13
+742 13
+743 13
+744 13
+745 13
+746 13
+747 13
+748 13
+749 13
+750 13
+751 13
+752 13
+753 13
+754 13
+755 12
+756 12
+757 12
+758 12
+759 11
+760 12
+761 11
+762 12
+763 11
+764 12
+765 12
+766 12
+767 12
+768 14
+769 14
+770 14
+771 14
+772 12
+773 12
+774 12
+775 13
+776 13
+777 13
+778 12
+779 13
+780 13
+781 13
+782 13
+783 13
+784 13
+785 12
+786 11
+787 11
+788 11
+789 12
+790 13
+791 13
+792 13
+793 12
+794 13
+795 13
+796 13
+797 13
+798 13
+799 12
+800 12
+801 12
+802 12
+803 12
+804 12
+805 11
+806 11
+807 11
+808 12
+809 13
+810 13
+811 12
+812 12
+813 12
+814 12
+815 12
+816 12
+817 12
+818 12
+819 12
+820 13
+821 13
+822 13
+823 13
+824 12
+825 13
+826 12
+827 13
+828 13
+829 13
+830 13
+831 12
+832 12
+833 12
+834 13
+835 13
+836 12
+837 9
+838 9
+839 10
+840 10
+841 11
+842 11
+843 11
+844 12
+845 12
+846 11
+847 12
+848 12
+849 12
+850 12
+851 12
+852 12
+853 12
+854 12
+855 12
+856 11
+857 10
+858 11
+859 12
+860 11
+861 11
+862 11
+863 10
+864 10
+865 10
+866 11
+867 10
+868 10
+869 10
+870 11
+871 11
+872 12
+873 12
+874 12
+875 12
+876 12
+877 12
+878 12
+879 12
+880 12
+881 0
+882 0
diff --git a/graphics/asymptote/doc/legend.asy b/graphics/asymptote/doc/legend.asy
new file mode 100644
index 0000000000..09a31868ae
--- /dev/null
+++ b/graphics/asymptote/doc/legend.asy
@@ -0,0 +1,15 @@
+import graph;
+size(8cm,6cm,IgnoreAspect);
+
+typedef real realfcn(real);
+realfcn F(real p) {
+ return new real(real x) {return sin(p*x);};
+};
+
+for(int i=1; i < 5; ++i)
+ draw(graph(F(i*pi),0,1),Pen(i),
+ "$\sin("+(i == 1 ? "" : (string) i)+"\pi x)$");
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+attach(legend(2),(point(S).x,truepoint(S).y),10S,UnFill);
diff --git a/graphics/asymptote/doc/lineargraph.asy b/graphics/asymptote/doc/lineargraph.asy
new file mode 100644
index 0000000000..c352311ee7
--- /dev/null
+++ b/graphics/asymptote/doc/lineargraph.asy
@@ -0,0 +1,16 @@
+import graph;
+
+size(250,200,IgnoreAspect);
+
+real Sin(real t) {return sin(2pi*t);}
+real Cos(real t) {return cos(2pi*t);}
+
+draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+label("LABEL",point(0),UnFill(1mm));
+
+attach(legend(),truepoint(E),20E,UnFill);
diff --git a/graphics/asymptote/doc/lineargraph0.asy b/graphics/asymptote/doc/lineargraph0.asy
new file mode 100644
index 0000000000..fc344181d5
--- /dev/null
+++ b/graphics/asymptote/doc/lineargraph0.asy
@@ -0,0 +1,16 @@
+import graph;
+
+size(400,200,IgnoreAspect);
+
+real Sin(real t) {return sin(2pi*t);}
+real Cos(real t) {return cos(2pi*t);}
+
+draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+label("LABEL",point(0),UnFill(1mm));
+
+add(legend(),point(E),20E,UnFill);
diff --git a/graphics/asymptote/doc/linetype.asy b/graphics/asymptote/doc/linetype.asy
new file mode 100644
index 0000000000..dc4762c247
--- /dev/null
+++ b/graphics/asymptote/doc/linetype.asy
@@ -0,0 +1,13 @@
+void testline(real y) {
+ draw((0,y)--(100,y),currentpen+solid);
+ draw((0,y-10)--(100,y-10),currentpen+dotted);
+ draw((0,y-20)--(100,y-20),currentpen+dashed);
+ draw((0,y-30)--(100,y-30),currentpen+longdashed);
+ draw((0,y-40)--(100,y-40),currentpen+dashdotted);
+ draw((0,y-50)--(100,y-50),currentpen+longdashdotted);
+ draw((0,y-60)--(100,y-60),currentpen+Dotted);
+}
+
+currentpen=linewidth(0.5);
+testline(100);
+
diff --git a/graphics/asymptote/doc/log2graph.asy b/graphics/asymptote/doc/log2graph.asy
new file mode 100644
index 0000000000..238f412627
--- /dev/null
+++ b/graphics/asymptote/doc/log2graph.asy
@@ -0,0 +1,17 @@
+import graph;
+size(200,IgnoreAspect);
+
+// Base-2 logarithmic scale on y-axis:
+
+real log2(real x) {static real log2=log(2); return log(x)/log2;}
+real pow2(real x) {return 2^x;}
+
+scaleT yscale=scaleT(log2,pow2,logarithmic=true);
+scale(Linear,yscale);
+
+real f(real x) {return 1+x^2;}
+
+draw(graph(f,-4,4));
+
+yaxis("$y$",ymin=1,ymax=f(5),RightTicks(Label(Fill(white))),EndArrow);
+xaxis("$x$",xmin=-5,xmax=5,LeftTicks,EndArrow);
diff --git a/graphics/asymptote/doc/loggraph.asy b/graphics/asymptote/doc/loggraph.asy
new file mode 100644
index 0000000000..d496fba162
--- /dev/null
+++ b/graphics/asymptote/doc/loggraph.asy
@@ -0,0 +1,17 @@
+import graph;
+
+size(200,200,IgnoreAspect);
+
+real f(real t) {return 1/t;}
+
+scale(Log,Log);
+
+draw(graph(f,0.1,10));
+
+//limits((1,0.1),(10,0.5),Crop);
+
+dot(Label("(3,5)",align=S),Scale((3,5)));
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
diff --git a/graphics/asymptote/doc/loggrid.asy b/graphics/asymptote/doc/loggrid.asy
new file mode 100644
index 0000000000..bb48a1e4ca
--- /dev/null
+++ b/graphics/asymptote/doc/loggrid.asy
@@ -0,0 +1,13 @@
+import graph;
+size(200,200,IgnoreAspect);
+
+real f(real t) {return 1/t;}
+
+scale(Log,Log);
+draw(graph(f,0.1,10),red);
+pen thin=linewidth(0.5*linewidth());
+xaxis("$x$",BottomTop,LeftTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+yaxis("$y$",LeftRight,RightTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+
diff --git a/graphics/asymptote/doc/logimage.asy b/graphics/asymptote/doc/logimage.asy
new file mode 100644
index 0000000000..65d6bb5311
--- /dev/null
+++ b/graphics/asymptote/doc/logimage.asy
@@ -0,0 +1,22 @@
+import graph;
+import palette;
+
+size(10cm,10cm,IgnoreAspect);
+
+real f(real x, real y) {
+ return 0.9*pow10(2*sin(x/5+2*y^0.25)) + 0.1*(1+cos(10*log(y)));
+}
+
+scale(Linear,Log,Log);
+
+pen[] Palette=BWRainbow();
+
+bounds range=image(f,Automatic,(0,1),(100,100),nx=200,Palette);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,(0,200),(100,250),Top,Palette,
+ PaletteTicks(ptick=linewidth(0.5*linewidth())));
+
+
diff --git a/graphics/asymptote/doc/logo.asy b/graphics/asymptote/doc/logo.asy
new file mode 100644
index 0000000000..d180558ad3
--- /dev/null
+++ b/graphics/asymptote/doc/logo.asy
@@ -0,0 +1,28 @@
+size(140,80,IgnoreAspect);
+
+picture logo(pair s=0, pen q)
+{
+ picture pic;
+ pen p=linewidth(2)+fontsize(24pt)+q;
+ real a=-0.4;
+ real b=0.95;
+ real y1=-5;
+ real y2=-3y1/2;
+ path A=(a,0){dir(10)}::{dir(89.5)}(0,y2);
+ draw(pic,A,p);
+ draw(pic,(0,y1){dir(88.3)}::{dir(20)}(b,0),p);
+ real c=0.5*a;
+ pair z=(0,2.5);
+ label(pic,"{\it symptote}",z,0.25*E+0.169S,p);
+ pair w=(0,1.7);
+ draw(pic,intersectionpoint(A,w-1--w)--w,p);
+ draw(pic,(0,y1)--(0,y2),p);
+ draw(pic,(a,0)--(b,0),p);
+ return shift(s)*pic;
+}
+
+pair z=(-0.015,0.08);
+for(int x=0; x < 10; ++x)
+ add(logo(0.1*x*z,gray(0.04*x)));
+
+add(logo(red));
diff --git a/graphics/asymptote/doc/logticks.asy b/graphics/asymptote/doc/logticks.asy
new file mode 100644
index 0000000000..bdd1441169
--- /dev/null
+++ b/graphics/asymptote/doc/logticks.asy
@@ -0,0 +1,11 @@
+import graph;
+
+size(300,175,IgnoreAspect);
+scale(Log,Log);
+draw(graph(identity,5,20));
+xlimits(5,20);
+ylimits(1,100);
+xaxis("$M/M_\odot$",BottomTop,LeftTicks(DefaultFormat,
+ new real[] {6,10,12,14,16,18}));
+yaxis("$\nu_{\rm upp}$ [Hz]",LeftRight,RightTicks(DefaultFormat));
+
diff --git a/graphics/asymptote/doc/makepen.asy b/graphics/asymptote/doc/makepen.asy
new file mode 100644
index 0000000000..7c7868a090
--- /dev/null
+++ b/graphics/asymptote/doc/makepen.asy
@@ -0,0 +1,9 @@
+size(200);
+pen convex=makepen(scale(10)*polygon(8))+grey;
+draw((1,0.4),convex);
+draw((0,0)---(1,1)..(2,0)--cycle,convex);
+
+pen nonconvex=scale(10)*
+ makepen((0,0)--(0.25,-1)--(0.5,0.25)--(1,0)--(0.5,1.25)--cycle)+red;
+draw((0.5,-1.5),nonconvex);
+draw((0,-1.5)..(1,-0.5)..(2,-1.5),nonconvex);
diff --git a/graphics/asymptote/doc/markers1.asy b/graphics/asymptote/doc/markers1.asy
new file mode 100644
index 0000000000..a3af424616
--- /dev/null
+++ b/graphics/asymptote/doc/markers1.asy
@@ -0,0 +1,102 @@
+size(12cm,0);
+import markers;
+
+pair A=(0,0), B=(1,0), C=(2,0), D=(3,0);
+path p=A--B--C--D;
+transform T=shift(-4,-1);
+transform t=shift(4,0);
+
+//line 1 **********
+draw(p,marker(markinterval(3,dotframe,true)));
+label("$1$",point(p,0),3W);
+
+//line 2 **********
+p=t*p;
+draw(p,marker(stickframe,markuniform(4)));
+label("$2$",point(p,0),3W);
+
+//line 3 **********
+p=T*p;
+draw(p,marker(stickframe(red),markinterval(3,dotframe(blue),true)));
+label("$3$",point(p,0),3W);
+
+//line 4 **********
+p=t*p;
+draw(p,StickIntervalMarker(3,2,blue,dotframe(red)));
+label("$4$",point(p,0),3W);
+
+//line 5 **********
+p=T*p;
+pen pn=linewidth(4bp);
+draw(p,pn,StickIntervalMarker(3,3,angle=25,pn,dotframe(red+pn)));
+label("$5$",point(p,0),3W);
+
+//line 6 **********
+p=t*p;
+draw(p,StickIntervalMarker(3,5,angle=25,size=4mm,space=2mm,offset=I*2mm,
+ scale(2)*dotframe(red)));
+label("$6$",point(p,0),3W);
+
+//line 7 **********
+p=T*p;
+draw(p,StickIntervalMarker(n=3,angle=45,size=10mm,space=3mm,dotframe));
+label("$7$",point(p,0),3W);
+
+//line 8 **********
+p=t*p;
+draw(p,CircleBarIntervalMarker(n=2,dotframe));
+label("$8$",point(p,0),3W);
+
+//line 9 **********
+p=T*p;
+draw(p,CircleBarIntervalMarker(n=3,angle=30,barsize=8mm,radius=2mm,
+ FillDraw(.8red),
+ dotframe));
+label("$9$",point(p,0),3W);
+
+//line 10 **********
+p=t*p;
+draw(p,CircleBarIntervalMarker(n=3,angle=30,barsize=8mm,radius=2mm,
+ FillDraw(.8red),circleabove=true,dotframe));
+label("$10$",point(p,0),3W);
+
+//line 11 **********
+p=T*p;
+draw(p,CircleBarIntervalMarker(n=3,angle=30,barsize=8mm,radius=2mm,
+ FillDraw(.8red),circleabove=true,dotframe,
+ above=false));
+label("$11$",point(p,0),3W);
+
+//line 12 **********
+p=t*p;
+draw(p,TildeIntervalMarker(i=3,dotframe));
+label("$12$",point(p,0),3W);
+
+//line 13 **********
+p=T*p;
+draw(p,TildeIntervalMarker(i=3,n=2,angle=-20,dotframe));
+label("$13$",point(p,0),3W);
+
+//line 14 **********
+p=t*p;
+draw(p,CrossIntervalMarker(3,3,dotframe));
+label("$14$",point(p,0),3W);
+
+//line 15 **********
+p=shift(.25S)*T*p;
+path cle=shift(relpoint(p,.5))*scale(abs(A-D)/4)*unitcircle;
+draw(cle,StickIntervalMarker(5,3,dotframe(6bp+red)));
+label("$15$",point(p,0),3W);
+
+//line 16 **********
+cle=t*cle;
+p=t*p;
+frame a;
+label(a,"$a$",(0,-2labelmargin()));
+draw(cle,marker(dotframe(6bp+red),markinterval(5,a,true)));
+label("$16$",point(p,0),3W);
+
+// line 17 **********
+p=T*shift(relpoint(p,.5)+.65S)*scale(.5)*shift(-relpoint(p,.5))*rotate(45,relpoint(p,.5))*p;
+draw(p,TildeIntervalMarker(size=5mm,rotated=false,dotframe));
+label("$17$",point(p,0),3W);
diff --git a/graphics/asymptote/doc/markers2.asy b/graphics/asymptote/doc/markers2.asy
new file mode 100644
index 0000000000..b9c8ac2189
--- /dev/null
+++ b/graphics/asymptote/doc/markers2.asy
@@ -0,0 +1,34 @@
+size(10cm,0);
+import markers;
+import geometry;
+import math;
+
+pair A=0, B=(1,0), C=(0.7,1), D=(-0.5,0), F=rotate(-90)*(C-B)/2+B;
+
+draw(A--B);
+draw(A--C);
+pen p=linewidth(1mm);
+draw(B--C,p);
+draw(A--D);
+draw(B--F,p);
+label("$A$",A,SW);
+label("$B$",B,S);
+label("$C$",C,N);
+dot(Label("$D$",D,S));
+dot(Label("$F$",F,N+NW));
+
+markangle(A,C,B);
+
+markangle(scale(1.5)*"$\theta$",radius=40,C,B,A,ArcArrow(2mm),1mm+red);
+markangle(scale(1.5)*"$-\theta$",radius=-70,A,B,C,ArcArrow,green);
+
+markangle(Label("$\gamma$",Relative(0.25)),n=2,radius=-30,A,C,B,p=0.7blue+2);
+
+markangle(n=3,B,A,C,marker(markinterval(stickframe(n=2),true)));
+
+pen RedPen=0.7red+1bp;
+markangle(C,A,D,RedPen,marker(markinterval(2,stickframe(3,4mm,RedPen),true)));
+drawline(A,A+dir(A--D,A--C),dotted);
+
+perpendicular(B,NE,F-B,size=10mm,1mm+red,
+ TrueMargin(linewidth(p)/2,linewidth(p)/2),Fill(yellow));
diff --git a/graphics/asymptote/doc/mexicanhat.asy b/graphics/asymptote/doc/mexicanhat.asy
new file mode 100644
index 0000000000..d55b127ae5
--- /dev/null
+++ b/graphics/asymptote/doc/mexicanhat.asy
@@ -0,0 +1,22 @@
+size(200);
+
+real mexican(real x) {return (1-8x^2)*exp(-(4x^2));}
+
+int n=30;
+real a=1.5;
+real width=2a/n;
+
+guide hat;
+path solved;
+
+for(int i=0; i < n; ++i) {
+ real t=-a+i*width;
+ pair z=(t,mexican(t));
+ hat=hat..z;
+ solved=solved..z;
+}
+
+draw(hat);
+dot(hat,red);
+draw(solved,dashed);
+
diff --git a/graphics/asymptote/doc/monthaxis.asy b/graphics/asymptote/doc/monthaxis.asy
new file mode 100644
index 0000000000..d2c8bf3298
--- /dev/null
+++ b/graphics/asymptote/doc/monthaxis.asy
@@ -0,0 +1,17 @@
+import graph;
+
+size(400,150,IgnoreAspect);
+
+real[] x=sequence(12);
+real[] y=sin(2pi*x/12);
+
+scale(false);
+
+string[] month={"Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"};
+
+draw(graph(x,y),red,MarkFill[0]);
+
+xaxis(BottomTop,LeftTicks(new string(real x) {
+ return month[round(x % 12)];}));
+yaxis("$y$",LeftRight,RightTicks(4));
diff --git a/graphics/asymptote/doc/multicontour.asy b/graphics/asymptote/doc/multicontour.asy
new file mode 100644
index 0000000000..0e8476de92
--- /dev/null
+++ b/graphics/asymptote/doc/multicontour.asy
@@ -0,0 +1,19 @@
+import contour;
+
+size(200);
+
+real f(real x, real y) {return x^2-y^2;}
+int n=10;
+real[] c=new real[n];
+for(int i=0; i < n; ++i) c[i]=(i-n/2)/n;
+
+pen[] p=sequence(new pen(int i) {
+ return (c[i] >= 0 ? solid : dashed)+fontsize(6pt);
+ },c.length);
+
+Label[] Labels=sequence(new Label(int i) {
+ return Label(c[i] != 0 ? (string) c[i] : "",Relative(unitrand()),(0,0),
+ UnFill(1bp));
+ },c.length);
+
+draw(Labels,contour(f,(-1,-1),(1,1),c),p);
diff --git a/graphics/asymptote/doc/ocg.sty b/graphics/asymptote/doc/ocg.sty
new file mode 100644
index 0000000000..87da828a8d
--- /dev/null
+++ b/graphics/asymptote/doc/ocg.sty
@@ -0,0 +1,130 @@
+%% Copyright (C) 2007 by Michael Ritzert <michael.ritz...@gmail.com>
+%% Spurious spaces removed by John Bowman [2009/06/01].
+%% Global macros to find the number of a PDF OCG object from its LaTeX
+%% reference contributed by Paul Gaborit [2012/09/13].
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{ocg}[2012/09/13]
+
+\RequirePackage{ifpdf}
+\ifpdf
+\else
+ \PackageWarningNoLine{ocg}{%
+ Loading aborted, because pdfTeX is not running in PDF mode%
+ }%
+ \expandafter\endinput
+\fi
+
+\DeclareOption*{}\ProcessOptions*\relax %allow anything as option for the moment
+
+%testing for correct pdfTeX version
+%TODO: find out minimum required version!
+\ifnum\pdftexversion<120
+ \PackageError{ocg}{%
+ pdfeTeX, version >= 1.20, required%
+ }{%
+ Install a newer version!%
+ }%
+\fi
+
+% Next OCG id -- TODO: autogenerate. but keep possibility to reopen an OCG.
+\newcount\@ocg@num\@ocg@num=0
+
+\gdef\@ocg@layersnames{}
+
+% called from the aux file
+\def\@ocg@makeknown#1#2#3{% #1: OCG name, #2: OC id, #3: on/off
+ \@ifundefined{OCG#2}{%
+ \message{OCG#2}
+ \expandafter\gdef\csname OCG#2\endcsname{#1}%
+ \immediate\pdfobj{<< /Type /OCG /Name (#1) >>}% new ocg
+ \xdef\@ocg@curocg{\the\pdflastobj\space 0 R}% reference to id
+ \expandafter\xdef\csname OCGpdfobj#2\endcsname{\@ocg@curocg}
+ \xdef\@ocg@ocgs{\@ocg@ocgs\space\@ocg@curocg}% list of all OCGs in "first defined" order
+ \ifnum#3=1 %on
+ \xdef\@ocg@ocgson{\@ocg@ocgson\space\@ocg@curocg}% list of all default-on OCGs
+ \else%
+ \xdef\@ocg@ocgsoff{\@ocg@ocgsoff\space\@ocg@curocg}% list of all default-off OCGs
+ \fi%
+ \xdef\@ocg@layersnames{%
+ \@ocg@layersnames\space/OC#2\space\@ocg@curocg% name-to-id mapping
+ }%
+ }{%
+ \message{OCG#2 reopened}
+ % layer reopened
+ }
+}
+
+\AtBeginDocument{%
+ % the auxfile has been read if available. register the OCGs in the page resources.
+ \@ocg@addresource
+ \let\@ocg@makeknown\@gobble
+}
+
+% set page resources to include the layers defined in the aux file
+\def\@ocg@addresource{%
+ \immediate\pdfobj{<<\@ocg@layersnames\space>>}%
+ \xdef\@ocg@namesobj{\the\pdflastobj\space 0 R}%
+ % append to pageresources
+ \begingroup
+ \edef\x{\endgroup
+ \pdfpageresources{%
+ \the\pdfpageresources
+ /Properties \@ocg@namesobj%
+ }%
+ }%
+ \x
+}
+
+\newcount\@ocg@@ocgs
+\pdfobj reserveobjnum
+\@ocg@@ocgs=\pdflastobj
+
+\newcount\@ocg@@layersconfig
+\pdfobj reserveobjnum
+\@ocg@@layersconfig=\pdflastobj
+
+\pdfcatalog{%
+ /OCProperties <<
+ /OCGs \the\@ocg@@ocgs\space0 R\space
+ /D \the\@ocg@@layersconfig\space0 R\space
+ >>%
+}
+\def\@ocg@ocgs{}
+\def\@ocg@ocgson{}
+\def\@ocg@ocgsoff{}
+\AtEndDocument{%
+ \immediate\pdfobj useobjnum \@ocg@@ocgs {%
+ [\@ocg@ocgs\space]%
+ }%
+ \immediate\pdfobj useobjnum \@ocg@@layersconfig {%
+ <<
+ /Order [\@ocg@ocgs\space]
+ /ON [\@ocg@ocgson\space]
+ /OFF [\@ocg@ocgsoff\space]
+ >>%
+ }%
+}%
+
+% schedule a OCG for creation on the next pdflatex run (via the auxfile)
+\def\@ocg@newocg#1#2#3{% #1:name, #2:num, #3:on
+ \if@filesw%
+ \immediate\write\@auxout{%
+ \string\@ocg@makeknown{#1}{#2}{#3}%
+ }%
+ \fi%
+}
+
+% TODO: Are nested OCGs allowed?
+\newenvironment{ocg}[3]{%
+ \@ocg@newocg{#1}{#2}{#3}%
+ \gdef\@ocg@curnum{#2}%
+ \pdfliteral{/OC /OC\@ocg@curnum\space BDC}%
+ \message{/OC\@ocg@curnum}%
+ \ignorespaces
+}{%
+ \pdfliteral{EMC}%
+ %\unskip%
+ %\endgroup%
+ \ignorespacesafterend
+}
diff --git a/graphics/asymptote/doc/onecontour.asy b/graphics/asymptote/doc/onecontour.asy
new file mode 100644
index 0000000000..0d7f247fd3
--- /dev/null
+++ b/graphics/asymptote/doc/onecontour.asy
@@ -0,0 +1,5 @@
+import contour;
+size(75);
+
+real f(real a, real b) {return a^2+b^2;}
+draw(contour(f,(-1,-1),(1,1),new real[] {1}));
diff --git a/graphics/asymptote/doc/parametricgraph.asy b/graphics/asymptote/doc/parametricgraph.asy
new file mode 100644
index 0000000000..61c219d810
--- /dev/null
+++ b/graphics/asymptote/doc/parametricgraph.asy
@@ -0,0 +1,15 @@
+import graph;
+
+size(0,200);
+
+real x(real t) {return cos(2pi*t);}
+real y(real t) {return sin(2pi*t);}
+
+draw(graph(x,y,0,1));
+
+//limits((0,-1),(1,0),Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+
diff --git a/graphics/asymptote/doc/penfunctionimage.asy b/graphics/asymptote/doc/penfunctionimage.asy
new file mode 100644
index 0000000000..38951e550d
--- /dev/null
+++ b/graphics/asymptote/doc/penfunctionimage.asy
@@ -0,0 +1,27 @@
+import palette;
+
+size(200);
+
+real fracpart(real x) {return (x-floor(x));}
+
+pair pws(pair z) {
+ pair w=(z+exp(pi*I/5)/0.9)/(1+z/0.9*exp(-pi*I/5));
+ return exp(w)*(w^3-0.5*I);
+}
+
+int N=512;
+
+pair a=(-1,-1);
+pair b=(0.5,0.5);
+real dx=(b-a).x/N;
+real dy=(b-a).y/N;
+
+pen f(int u, int v) {
+ pair z=a+(u*dx,v*dy);
+ pair w=pws(z);
+ real phase=degrees(w,warn=false);
+ real modulus=w == 0 ? 0: fracpart(log(abs(w)));
+ return hsv(phase,1,sqrt(modulus));
+}
+
+image(f,N,N,(0,0),(300,300),antialias=true);
diff --git a/graphics/asymptote/doc/penimage.asy b/graphics/asymptote/doc/penimage.asy
new file mode 100644
index 0000000000..2aef9f9ebe
--- /dev/null
+++ b/graphics/asymptote/doc/penimage.asy
@@ -0,0 +1,14 @@
+size(200);
+
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+pen[][] v=new pen[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=rgb(0.5*(1+sin(i*ninv)),0.5*(1+cos(j*ninv)),0);
+
+image(v,(0,0),(1,1));
+
diff --git a/graphics/asymptote/doc/pixel.pdf b/graphics/asymptote/doc/pixel.pdf
new file mode 100644
index 0000000000..de3d0820da
--- /dev/null
+++ b/graphics/asymptote/doc/pixel.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/planes.asy b/graphics/asymptote/doc/planes.asy
new file mode 100644
index 0000000000..a3aeb252e2
--- /dev/null
+++ b/graphics/asymptote/doc/planes.asy
@@ -0,0 +1,18 @@
+size(6cm,0);
+import bsp;
+
+real u=2.5;
+real v=1;
+
+currentprojection=oblique;
+
+path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
+path3 l=rotate(90,Z)*rotate(90,Y)*y;
+path3 g=rotate(90,X)*rotate(90,Y)*y;
+
+face[] faces;
+filldraw(faces.push(y),project(y),yellow);
+filldraw(faces.push(l),project(l),lightgrey);
+filldraw(faces.push(g),project(g),green);
+
+add(faces);
diff --git a/graphics/asymptote/doc/png/Makefile.in b/graphics/asymptote/doc/png/Makefile.in
new file mode 100644
index 0000000000..44e3fbdf4a
--- /dev/null
+++ b/graphics/asymptote/doc/png/Makefile.in
@@ -0,0 +1,57 @@
+ASYFILES = $(notdir $(filter-out $(wildcard ../latexusage-*.asy),$(wildcard ../*.asy)))
+
+SOURCE = ../asymptote.texi ../version.texi ../options
+ASY = ../asy -dir ../base -config "" -render=0
+
+docdir = $(DESTDIR)@docdir@
+infodir = $(DESTDIR)@infodir@
+datarootdir = @datarootdir@
+INSTALL = @INSTALL@
+
+all: html info
+
+%.png: ../%.asy
+ cd .. && $(ASY) -f png -o png/ $(notdir $<)
+
+latexusage.png: ../latexusage.eps
+ gs -q -dNOPAUSE -dBATCH -sDEVICE=pngalpha -dEPSCrop -dSAFER -r72x72 \
+ -sOutputFile=latexusage.png ../latexusage.eps
+
+index.html: $(SOURCE) $(ASYFILES:.asy=.png) latexusage.png
+ makeinfo --html ../asymptote -o .
+
+asymptote.info: $(SOURCE)
+ makeinfo --no-warn --no-split ../asymptote
+
+info: $(SOURCE) $(ASYFILES:.asy=.png) latexusage.png
+ makeinfo --no-split ../asymptote
+
+../options:
+ cd .. && $(MAKE) options
+
+html: index.html
+
+clean: FORCE
+ -rm -f *.png *.html asymptote.info* texput.aux texput.log
+
+distclean: FORCE clean
+ -rm -f Makefile
+
+install: asymptote.info
+ ${INSTALL} -d -m 755 $(infodir)/asymptote
+ ${INSTALL} -p -m 644 asymptote.info $(infodir)/asymptote
+ -if test -z "$(DESTDIR)"; then \
+ install-info --infodir=$(infodir) asymptote.info; \
+ fi
+
+install-all: all install
+ ${INSTALL} -p -m 644 *.png $(infodir)/asymptote
+
+uninstall:
+ -install-info --remove --infodir=$(infodir) asymptote.info
+ -cd $(infodir)/asymptote && rm -f asymptote.info *.png
+ -rmdir $(infodir)/asymptote
+FORCE:
+
+Makefile: Makefile.in
+ cd ../..; config.status
diff --git a/graphics/asymptote/doc/png/asymptote.info b/graphics/asymptote/doc/png/asymptote.info
new file mode 100644
index 0000000000..eefb40a447
--- /dev/null
+++ b/graphics/asymptote/doc/png/asymptote.info
@@ -0,0 +1,10265 @@
+This is asymptote.info, produced by makeinfo version 6.5 from
+asymptote.texi.
+
+This file documents 'Asymptote', version 2.53.
+
+ <http://asymptote.sourceforge.net>
+
+ Copyright (C) 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Lesser General Public License
+ (see the file LICENSE in the top-level source directory).
+
+INFO-DIR-SECTION Languages
+START-INFO-DIR-ENTRY
+* asymptote: (asymptote/asymptote). Vector graphics language.
+END-INFO-DIR-ENTRY
+
+
+File: asymptote.info, Node: Top, Next: Description, Prev: (dir), Up: (dir)
+
+Asymptote
+*********
+
+This file documents 'Asymptote', version 2.53.
+
+ <http://asymptote.sourceforge.net>
+
+ Copyright (C) 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Lesser General Public License
+ (see the file LICENSE in the top-level source directory).
+
+* Menu:
+
+* Description:: What is 'Asymptote'?
+* Installation:: Downloading and installing
+* Tutorial:: Getting started
+* Drawing commands:: Four primitive graphics commands
+* Bezier curves:: Path connectors and direction specifiers
+* Programming:: The 'Asymptote' vector graphics language
+* LaTeX usage:: Embedding 'Asymptote' commands within 'LaTeX'
+* Base modules:: Base modules shipped with 'Asymptote'
+* Options:: Command-line options
+* Interactive mode:: Typing 'Asymptote' commands interactively
+* GUI:: Graphical user interface
+* PostScript to Asymptote:: 'Asymptote' backend to 'pstoedit'
+* Help:: Where to get help and submit bug reports
+* Debugger:: Squish those bugs!
+* Credits:: Contributions and acknowledgments
+* Index:: General index
+
+ -- The Detailed Node Listing --
+
+Installation
+
+* UNIX binary distributions:: Prebuilt 'UNIX' binaries
+* MacOS X binary distributions:: Prebuilt 'MacOS X' binaries
+* Microsoft Windows:: Prebuilt 'Microsoft Windows' binary
+* Configuring:: Configuring 'Asymptote' for your system
+* Search paths:: Where 'Asymptote' looks for your files
+* Compiling from UNIX source:: Building 'Asymptote' from scratch
+* Editing modes:: Convenient 'emacs' and 'vim' modes
+* Git:: Getting the latest development source
+* Uninstall:: Goodbye, 'Asymptote'!
+
+Tutorial
+
+* Drawing in batch mode:: Run 'Asymptote' on a text file
+* Drawing in interactive mode:: Running 'Asymptote' interactively
+* Figure size:: Specifying the figure size
+* Labels:: Adding 'LaTeX' labels
+* Paths:: Drawing lines and curves
+
+Drawing commands
+
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+
+Programming
+
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides:: Bezier curves
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external 'Asymptote' modules
+* Static:: Where to allocate your variable?
+
+Operators
+
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+
+Functions
+
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+
+Arrays
+
+* Slices:: Python-style array slices
+
+Base modules
+
+* plain:: Default 'Asymptote' base file
+* simplex:: Linear programming: simplex method
+* math:: Extend 'Asymptote''s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded PDF and MPEG movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with 'Asymptote'
+* MetaPost:: 'MetaPost' compatibility routines
+* unicode:: Accept 'unicode' (UTF-8) characters
+* latin1:: Accept 'ISO 8859-1' characters
+* babel:: Interface to 'LaTeX' 'babel' package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your PDF files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* smoothcontour3:: Smooth implicit surfaces
+* slopefield:: Slope fields
+* ode:: Ordinary differential equations
+
+Graphical User Interface
+
+* GUI installation:: Installing 'xasy'
+* GUI usage:: Using 'xasy' to edit objects
+
+
+
+File: asymptote.info, Node: Description, Next: Installation, Prev: Top, Up: Top
+
+1 Description
+*************
+
+'Asymptote' is a powerful descriptive vector graphics language that
+provides a mathematical coordinate-based framework for technical
+drawing. Labels and equations are typeset with 'LaTeX', for overall
+document consistency, yielding the same high-quality level of
+typesetting that 'LaTeX' provides for scientific text. By default it
+produces 'PostScript' output, but it can also generate any format that
+the 'ImageMagick' package can produce.
+
+ A major advantage of 'Asymptote' over other graphics packages is that
+it is a high-level programming language, as opposed to just a graphics
+program: it can therefore exploit the best features of the script
+(command-driven) and graphical-user-interface (GUI) methods for
+producing figures. The rudimentary GUI 'xasy' included with the package
+allows one to move script-generated objects around. To make 'Asymptote'
+accessible to the average user, this GUI is currently being developed
+into a full-fledged interface that can generate objects directly.
+However, the script portion of the language is now ready for general use
+by users who are willing to learn a few simple 'Asymptote' graphics
+commands (*note Drawing commands::).
+
+ 'Asymptote' is mathematically oriented (e.g. one can use complex
+multiplication to rotate a vector) and uses 'LaTeX' to do the
+typesetting of labels. This is an important feature for scientific
+applications. It was inspired by an earlier drawing program (with a
+weaker syntax and capabilities) called 'MetaPost'.
+
+ The 'Asymptote' vector graphics language provides:
+
+ * a standard for typesetting mathematical figures, just as
+ TeX/'LaTeX' is the de-facto standard for typesetting equations.
+
+ * 'LaTeX' typesetting of labels, for overall document consistency;
+
+ * the ability to generate and embed 3D vector PRC graphics within PDF
+ files;
+
+ * a natural coordinate-based framework for technical drawing,
+ inspired by 'MetaPost', with a much cleaner, powerful C++-like
+ programming syntax;
+
+ * compilation of figures into virtual machine code for speed, without
+ sacrificing portability;
+
+ * the power of a script-based language coupled to the convenience of
+ a GUI;
+
+ * customization using its own C++-like graphics programming language;
+
+ * sensible defaults for graphical features, with the ability to
+ override;
+
+ * a high-level mathematically oriented interface to the 'PostScript'
+ language for vector graphics, including affine transforms and
+ complex variables;
+
+ * functions that can create new (anonymous) functions;
+
+ * deferred drawing that uses the simplex method to solve overall size
+ constraint issues between fixed-sized objects (labels and
+ arrowheads) and objects that should scale with figure size;
+
+ Many of the features of 'Asymptote' are written in the 'Asymptote'
+language itself. While the stock version of 'Asymptote' is designed for
+mathematics typesetting needs, one can write 'Asymptote' modules that
+tailor it to specific applications. A scientific graphing module has
+already been written (*note graph::). Examples of 'Asymptote' code and
+output, including animations, are available at
+ <http://asymptote.sourceforge.net/gallery/>
+Clicking on an example file name in this manual, like 'Pythagoras', will
+display the PDF output, whereas clicking on its '.asy' extension will
+show the corresponding 'Asymptote' code in a separate window.
+
+ Links to many external resources, including an excellent user-written
+'Asymptote' tutorial can be found at
+ <http://asymptote.sourceforge.net/links.html>
+ A quick reference card for 'Asymptote' is available at
+ <http://asymptote.sourceforge.net/asyRefCard.pdf>
+
+
+File: asymptote.info, Node: Installation, Next: Tutorial, Prev: Description, Up: Top
+
+2 Installation
+**************
+
+* Menu:
+
+* UNIX binary distributions:: Prebuilt 'UNIX' binaries
+* MacOS X binary distributions:: Prebuilt 'MacOS X' binaries
+* Microsoft Windows:: Prebuilt 'Microsoft Windows' binary
+* Configuring:: Configuring 'Asymptote' for your system
+* Search paths:: Where 'Asymptote' looks for your files
+* Compiling from UNIX source:: Building 'Asymptote' from scratch
+* Editing modes:: Convenient 'emacs' and 'vim' modes
+* Git:: Getting the latest development source
+* Uninstall:: Goodbye, 'Asymptote'!
+
+After following the instructions for your specific distribution, please
+see also *note Configuring::.
+
+We recommend subscribing to new release announcements at
+ <http://sourceforge.net/projects/asymptote>
+Users may also wish to monitor the 'Asymptote' forum:
+ <http://sourceforge.net/p/asymptote/discussion/409349>
+
+
+File: asymptote.info, Node: UNIX binary distributions, Next: MacOS X binary distributions, Prev: Installation, Up: Installation
+
+2.1 UNIX binary distributions
+=============================
+
+We release both 'tgz' and RPM binary distributions of 'Asymptote'. The
+root user can install the 'Linux x86_64' 'tgz' distribution of version
+'x.xx' of 'Asymptote' with the commands:
+tar -C / -zxf asymptote-x.xx.x86_64.tgz
+texhash
+The 'texhash' command, which installs LaTeX style files, is optional.
+The executable file will be '/usr/local/bin/asy') and example code will
+be installed by default in '/usr/local/share/doc/asymptote/examples'.
+
+Fedora users can easily install the most recent version of 'Asymptote'
+with the command
+dnf --enablerepo=rawhide install asymptote
+
+To install the latest version of 'Asymptote' on a Debian-based
+distribution (e.g. Ubuntu, Mepis, Linspire) follow the instructions for
+compiling from 'UNIX' source (*note Compiling from UNIX source::).
+Alternatively, Debian users can install one of Hubert Chan's prebuilt
+'Asymptote' binaries from
+ <http://ftp.debian.org/debian/pool/main/a/asymptote>
+
+
+File: asymptote.info, Node: MacOS X binary distributions, Next: Microsoft Windows, Prev: UNIX binary distributions, Up: Installation
+
+2.2 MacOS X binary distributions
+================================
+
+'MacOS X' users can either compile the 'UNIX' source code (*note
+Compiling from UNIX source::) or install the 'Asymptote' binary
+available at
+
+ <http://www.macports.org/>
+
+Note that many 'MacOS X' (and FreeBSD) systems lack the GNU 'readline'
+library. For full interactive functionality, GNU 'readline' version 4.3
+or later must be installed.
+
+
+File: asymptote.info, Node: Microsoft Windows, Next: Configuring, Prev: MacOS X binary distributions, Up: Installation
+
+2.3 Microsoft Windows
+=====================
+
+Users of the 'Microsoft Windows' operating system can install the
+self-extracting 'Asymptote' executable 'asymptote-x.xx-setup.exe', where
+'x.xx' denotes the latest version.
+
+ A working TeX implementation (we recommend
+<https://www.tug.org/texlive> or <http://www.miktex.org>) will be
+required to typeset labels. You will also need to install 'GPL
+Ghostscript' version 9.14 or later from
+<http://downloads.ghostscript.com/public>.
+
+ To view 'PostScript' output, you can install the program 'gsview'
+available from <http://www.cs.wisc.edu/~ghost/gsview/>.
+
+ The 'ImageMagick' package from
+<http://www.imagemagick.org/script/binary-releases.php>
+
+is required to support output formats other than EPS, PDF, SVG, and PNG
+(*note convert::). The 'Python 3' interpreter from
+<http://www.python.org> is only required if you wish to try out the
+graphical user interface (*note GUI::).
+
+Example code will be installed by default in the 'examples' subdirectory
+of the installation directory (by default, 'C:\Program
+Files\Asymptote').
+
+
+File: asymptote.info, Node: Configuring, Next: Search paths, Prev: Microsoft Windows, Up: Installation
+
+2.4 Configuring
+===============
+
+In interactive mode, or when given the '-V' option (the default when
+running 'Asymptote' on a single file under 'MSDOS'), 'Asymptote' will
+automatically invoke the 'PostScript' viewer 'gv' (under 'UNIX') or
+'gsview' (under 'MSDOS' to display graphical output. These defaults may
+be overridden with the configuration variable 'psviewer'. The
+'PostScript' viewer should be capable of automatically redrawing
+whenever the output file is updated. The default 'UNIX' 'PostScript'
+viewer 'gv' supports this (via a 'SIGHUP' signal). Version 'gv-3.6.3'
+or later (from <http://ftp.gnu.org/gnu/gv/>) is required for interactive
+mode to work properly. Users of 'ggv' will need to enable 'Watch file'
+under 'Edit/Postscript Viewer Preferences'. Users of 'gsview' will need
+to enable 'Options/Auto Redisplay' (however, under 'MSDOS' it is still
+necessary to click on the 'gsview' window; under 'UNIX' one must
+manually redisplay by pressing the 'r' key).
+
+ Configuration variables are most easily set as 'Asymptote' variables
+in an optional configuration file 'config.asy' *note configuration
+file::). Here are the default values of several important configuration
+variables under 'UNIX':
+
+import settings;
+psviewer="gv";
+pdfviewer="acroread";
+gs="gs";
+
+Under 'MSDOS', the (installation-dependent) default values of these
+configuration variables are determined automatically from the 'Microsoft
+Windows' registry. Viewer settings (such as 'psviewer' and 'pdfviewer')
+can be set to the string 'cmd' to request the application normally
+associated with the corresponding file type.
+
+ For PDF format output, the 'gs' setting specifies the location of the
+'PostScript'-to-PDF processor 'Ghostscript', available from
+<http://downloads.ghostscript.com/public>.
+
+ The setting 'pdfviewer' specifies the location of the PDF viewer. On
+'UNIX' systems, to support automatic document reloading in 'Adobe
+Reader', we recommend copying the file 'reload.js' from the 'Asymptote'
+system directory (by default, '/usr/local/share/asymptote' under 'UNIX'
+to '~/.adobe/Acrobat/x.x/JavaScripts/', where 'x.x' represents the
+appropriate 'Adobe Reader' version number. The automatic document
+reload feature must then be explicitly enabled by putting
+import settings;
+pdfreload=true;
+pdfreloadOptions="-tempFile";
+in the 'Asymptote' configuration file. This reload feature is not
+useful under 'MSDOS' since the document cannot be updated anyway on that
+operating system until it is first closed by 'Adobe Reader'.
+
+ The configuration variable 'dir' can be used to adjust the search
+path (*note Search paths::).
+
+ By default, 'Asymptote' attempts to center the figure on the page,
+assuming that the paper type is 'letter'. The default paper type may be
+changed to 'a4' with the configuration variable 'papertype'. Alignment
+to other paper sizes can be obtained by setting the configuration
+variables 'paperwidth' and 'paperheight'.
+
+ The following configuration variables normally do not require
+adjustment:
+config
+texpath
+texcommand
+dvips
+dvisvgm
+libgs
+convert
+display
+animate
+
+ Warnings (such as "unbounded" and "offaxis") may be enabled or
+disabled with the functions
+warn(string s);
+nowarn(string s);
+or by directly modifying the string array 'settings.suppress', which
+lists all disabled warnings.
+
+ Configuration variables may also be set or overwritten with a
+command-line option:
+asy -psviewer=gsview -V venn
+
+ Alternatively, system environment versions of the above configuration
+variables may be set in the conventional way. The corresponding
+environment variable name is obtained by converting the configuration
+variable name to upper case and prepending 'ASYMPTOTE_': for example, to
+set the environment variable
+ASYMPTOTE_PSVIEWER="C:\Program Files\Ghostgum\gsview\gsview32.exe";
+under 'Microsoft Windows XP':
+ 1. Click on the 'Start' button;
+ 2. Right-click on 'My Computer';
+ 3. Choose 'View system information';
+ 4. Click the 'Advanced' tab;
+ 5. Click the 'Environment Variables' button.
+
+
+File: asymptote.info, Node: Search paths, Next: Compiling from UNIX source, Prev: Configuring, Up: Installation
+
+2.5 Search paths
+================
+
+In looking for 'Asymptote' system files, 'asy' will search the following
+paths, in the order listed:
+ 1. The current directory;
+ 2. A list of one or more directories specified by the configuration
+ variable 'dir' or environment variable 'ASYMPTOTE_DIR' (separated
+ by ':' under UNIX and ';' under 'MSDOS');
+ 3. The directory specified by the environment variable
+ 'ASYMPTOTE_HOME'; if this variable is not set, the directory '.asy'
+ in the user's home directory ('%USERPROFILE%\.asy' under 'MSDOS')
+ is used;
+ 4. The 'Asymptote' system directory (by default,
+ '/usr/local/share/asymptote' under 'UNIX' and 'C:\Program
+ Files\Asymptote' under 'MSDOS').
+
+
+File: asymptote.info, Node: Compiling from UNIX source, Next: Editing modes, Prev: Search paths, Up: Installation
+
+2.6 Compiling from UNIX source
+==============================
+
+To compile and install a 'UNIX' executable from the source release
+'asymptote-x.xx.src.tgz' in the subdirectory 'x.xx' under
+
+ <http://sourceforge.net/projects/asymptote/files/>
+
+ execute the commands:
+gunzip asymptote-x.xx.src.tgz
+tar -xf asymptote-x.xx.src.tar
+cd asymptote-x.xx
+ By default the system version of the Boehm garbage collector will be
+used; if it is old we recommend first putting
+<https://github.com/ivmai/bdwgc/releases/download/v8.0.4/gc-8.0.4.tar.gz>
+<https://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-7.6.10.tar.gz>
+in the 'Asymptote' source directory.
+
+ On 'UNIX' platforms (other than 'MacOS X'), we recommend using
+version '3.0.0' of the 'freeglut' library. To compile 'freeglut',
+download
+ <http://prdownloads.sourceforge.net/freeglut/freeglut-3.0.0.tar.gz>
+and type (as the root user):
+gunzip freeglut-3.0.0.tar.gz
+tar -xf freeglut-3.0.0.tar
+cd freeglut-3.0.0
+./configure --prefix=/usr
+cmake .
+make
+make install
+cd ..
+
+ Then compile 'Asymptote' with the commands
+./configure
+make all
+make install
+Be sure to use GNU 'make' (on non-GNU systems this command may be called
+'gmake'). To build the documentation, you may need to install the
+'texinfo-tex' package. If you get errors from a broken 'texinfo' or
+'pdftex' installation, simply put
+ <http://asymptote.sourceforge.net/asymptote.pdf>
+in the directory 'doc' and repeat the command 'make all'.
+
+For a (default) system-wide installation, the last command should be
+done as the root user. To install without root privileges, change the
+'./configure' command to
+./configure --prefix=$HOME/asymptote
+ One can disable use of the Boehm garbage collector by configuring
+with './configure --disable-gc'. For a list of other configuration
+options, say './configure --help'. For example, one can tell configure
+to look for header files and libraries in nonstandard locations:
+./configure CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
+
+ If you are compiling 'Asymptote' with 'gcc', you will need a
+relatively recent version (e.g. 3.4.4 or later). For full interactive
+functionality, you will need version 4.3 or later of the GNU 'readline'
+library. The file 'gcc3.3.2curses.patch' in the 'patches' directory can
+be used to patch the broken curses.h header file (or a local copy
+thereof in the current directory) on some 'AIX' and 'IRIX' systems.
+
+ The 'FFTW' library is only required if you want 'Asymptote' to be
+able to take Fourier transforms of data (say, to compute an audio power
+spectrum). The 'GSL' library is only required if you require the
+special functions that it supports.
+
+ If you don't want to install 'Asymptote' system wide, just make sure
+the compiled binary 'asy' and GUI script 'xasy' are in your path and set
+the configuration variable 'dir' to point to the directory 'base' (in
+the top level directory of the 'Asymptote' source code).
+
+
+File: asymptote.info, Node: Editing modes, Next: Git, Prev: Compiling from UNIX source, Up: Installation
+
+2.7 Editing modes
+=================
+
+Users of 'emacs' can edit 'Asymptote' code with the mode 'asy-mode',
+after enabling it by putting the following lines in their '.emacs'
+initialization file, replacing 'ASYDIR' with the location of the
+'Asymptote' system directory (by default, '/usr/local/share/asymptote'
+or 'C:\Program Files\Asymptote' under 'MSDOS'):
+(add-to-list 'load-path "ASYDIR")
+(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+Particularly useful key bindings in this mode are 'C-c C-c', which
+compiles and displays the current buffer, and the key binding 'C-c ?',
+which shows the available function prototypes for the command at the
+cursor. For full functionality you should also install the Apache
+Software Foundation package 'two-mode-mode':
+ <http://www.dedasys.com/freesoftware/files/two-mode-mode.el>
+Once installed, you can use the hybrid mode 'lasy-mode' to edit a LaTeX
+file containing embedded 'Asymptote' code (*note LaTeX usage::). This
+mode can be enabled within 'latex-mode' with the key sequence 'M-x
+lasy-mode <RET>'. On 'UNIX' systems, additional keywords will be
+generated from all 'asy' files in the space-separated list of
+directories specified by the environment variable 'ASYMPTOTE_SITEDIR'.
+Further documentation of 'asy-mode' is available within 'emacs' by
+pressing the sequence keys 'C-h f asy-mode <RET>'.
+
+ Fans of 'vim' can customize 'vim' for 'Asymptote' with
+
+'cp /usr/local/share/asymptote/asy.vim ~/.vim/syntax/asy.vim'
+
+and add the following to their '~/.vimrc' file:
+augroup filetypedetect
+au BufNewFile,BufRead *.asy setf asy
+augroup END
+filetype plugin on
+
+ If any of these directories or files don't exist, just create them.
+To set 'vim' up to run the current asymptote script using ':make' just
+add to '~/.vim/ftplugin/asy.vim':
+setlocal makeprg=asy\ %
+setlocal errorformat=%f:\ %l.%c:\ %m
+
+ Syntax highlighting support for the KDE editor 'Kate' can be enabled
+by running 'asy-kate.sh' in the '/usr/local/share/asymptote' directory
+and putting the generated 'asymptote.xml' file in
+'~/.kde/share/apps/katepart/syntax/'.
+
+
+File: asymptote.info, Node: Git, Next: Uninstall, Prev: Editing modes, Up: Installation
+
+2.8 Git
+=======
+
+The following commands are needed to install the latest development
+version of 'Asymptote' using 'git':
+git clone https://github.com/vectorgraphics/asymptote
+
+cd asymptote
+./autogen.sh
+./configure
+make all
+make install
+
+To compile without optimization, use the command 'make CFLAGS=-g'.
+
+
+File: asymptote.info, Node: Uninstall, Prev: Git, Up: Installation
+
+2.9 Uninstall
+=============
+
+To uninstall a 'Linux x86_64' binary distribution, use the commands
+tar -zxvf asymptote-x.xx.x86_64.tgz | xargs --replace=% rm /%
+texhash
+
+To uninstall all 'Asymptote' files installed from a source distribution,
+use the command
+make uninstall
+
+
+File: asymptote.info, Node: Tutorial, Next: Drawing commands, Prev: Installation, Up: Top
+
+3 Tutorial
+**********
+
+* Menu:
+
+* Drawing in batch mode:: Run 'Asymptote' on a text file
+* Drawing in interactive mode:: Running 'Asymptote' interactively
+* Figure size:: Specifying the figure size
+* Labels:: Adding 'LaTeX' labels
+* Paths:: Drawing lines and curves
+
+A concise introduction to 'Asymptote' is given here. For a more
+thorough introduction, see the excellent 'Asymptote' tutorial written by
+Charles Staats:
+
+ <http://math.uchicago.edu/~cstaats/Charles_Staats_III/Notes_and_papers_files/asymptote_tutorial.pdf>
+
+ Another 'Asymptote' tutorial is available as a wiki, with images
+rendered by an online Asymptote engine:
+
+ <http://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)>
+
+
+File: asymptote.info, Node: Drawing in batch mode, Next: Drawing in interactive mode, Prev: Tutorial, Up: Tutorial
+
+3.1 Drawing in batch mode
+=========================
+
+To draw a line from coordinate (0,0) to coordinate (100,100), create a
+text file 'test.asy' containing
+draw((0,0)--(100,100));
+
+Then execute the command
+asy -V test
+Alternatively, 'MSDOS' users can drag and drop 'test.asy' onto the
+Desktop 'asy' icon (or make 'Asymptote' the default application for the
+extension 'asy').
+
+This method, known as _batch mode_, outputs a 'PostScript' file
+'test.eps'. If you prefer PDF output, use the command line
+asy -V -f pdf test
+ In either case, the '-V' option opens up a viewer window so you can
+immediately view the result:
+
+ [diagonal]
+Here, the '--' connector joins the two points '(0,0)' and '(100,100)'
+with a line segment.
+
+
+File: asymptote.info, Node: Drawing in interactive mode, Next: Figure size, Prev: Drawing in batch mode, Up: Tutorial
+
+3.2 Drawing in interactive mode
+===============================
+
+Another method is _interactive mode_, where 'Asymptote' reads individual
+commands as they are entered by the user. To try this out, enter
+'Asymptote''s interactive mode by clicking on the 'Asymptote' icon or
+typing the command 'asy'. Then type
+draw((0,0)--(100,100));
+followed by 'Enter', to obtain the above image. At this point you can
+type further 'draw' commands, which will be added to the displayed
+figure, 'erase' to clear the canvas,
+input test;
+to execute all of the commands contained in the file 'test.asy', or
+'quit' to exit interactive mode. You can use the arrow keys in
+interactive mode to edit previous lines. The tab key will automatically
+complete unambiguous words; otherwise, hitting tab again will show the
+possible choices. Further commands specific to interactive mode are
+described in *note Interactive mode::.
+
+
+File: asymptote.info, Node: Figure size, Next: Labels, Prev: Drawing in interactive mode, Up: Tutorial
+
+3.3 Figure size
+===============
+
+In 'Asymptote', coordinates like '(0,0)' and '(100,100)', called
+_pairs_, are expressed in 'PostScript' "big points" (1 'bp' = 1/72
+'inch') and the default line width is '0.5bp'. However, it is often
+inconvenient to work directly in 'PostScript' coordinates. The next
+example produces identical output to the previous example, by scaling
+the line '(0,0)--(1,1)' to fit a rectangle of width '100.5 bp' and
+height '100.5 bp' (the extra '0.5bp' accounts for the line width):
+size(100.5,100.5);
+draw((0,0)--(1,1));
+
+ [diagonal]
+
+ One can also specify the size in 'pt' (1 'pt' = 1/72.27 'inch'),
+'cm', 'mm', or 'inches'. Two nonzero size arguments (or a single size
+argument) restrict the size in both directions, preserving the aspect
+ratio. If 0 is given as a size argument, no restriction is made in that
+direction; the overall scaling will be determined by the other direction
+(*note size::):
+size(0,100.5);
+draw((0,0)--(2,1),Arrow);
+
+ [bigdiagonal]
+
+ To connect several points and create a cyclic path, use the 'cycle'
+keyword:
+size(3cm);
+draw((0,0)--(1,0)--(1,1)--(0,1)--cycle);
+
+ [square]
+For convenience, the path '(0,0)--(1,0)--(1,1)--(0,1)--cycle' may be
+replaced with the predefined variable 'unitsquare', or equivalently,
+'box((0,0),(1,1))'.
+
+ To make the user coordinates represent multiples of exactly '1cm':
+unitsize(1cm);
+draw(unitsquare);
+
+
+File: asymptote.info, Node: Labels, Next: Paths, Prev: Figure size, Up: Tutorial
+
+3.4 Labels
+==========
+
+Adding labels is easy in 'Asymptote'; one specifies the label as a
+double-quoted 'LaTeX' string, a coordinate, and an optional alignment
+direction:
+size(3cm);
+draw(unitsquare);
+label("$A$",(0,0),SW);
+label("$B$",(1,0),SE);
+label("$C$",(1,1),NE);
+label("$D$",(0,1),NW);
+
+ [labelsquare]
+
+ 'Asymptote' uses the standard compass directions 'E=(1,0)',
+'N=(0,1)', 'NE=unit(N+E)', and 'ENE=unit(E+NE)', etc., which along with
+the directions 'up', 'down', 'right', and 'left' are defined as pairs in
+the 'Asymptote' base module 'plain' (a user who has a local variable
+named 'E' may access the compass direction 'E' by prefixing it with the
+name of the module where it is defined: 'plain.E').
+
+
+File: asymptote.info, Node: Paths, Prev: Labels, Up: Tutorial
+
+3.5 Paths
+=========
+
+This example draws a path that approximates a quarter circle, terminated
+with an arrowhead:
+size(100,0);
+draw((1,0){up}..{left}(0,1),Arrow);
+
+ [quartercircle]
+Here the directions 'up' and 'left' in braces specify the outgoing and
+incoming directions at the points '(1,0)' and '(0,1)', respectively.
+
+ In general, a path is specified as a list of points (or other paths)
+interconnected with '--', which denotes a straight line segment, or
+'..', which denotes a cubic spline (*note Bezier curves::). Specifying
+a final '..cycle' creates a cyclic path that connects smoothly back to
+the initial node, as in this approximation (accurate to within 0.06%) of
+a unit circle:
+path unitcircle=E..N..W..S..cycle;
+
+An 'Asymptote' path, being connected, is equivalent to a 'Postscript
+subpath'. The '^^' binary operator, which requests that the pen be
+moved (without drawing or affecting endpoint curvatures) from the final
+point of the left-hand path to the initial point of the right-hand path,
+may be used to group several 'Asymptote' paths into a 'path[]' array
+(equivalent to a 'PostScript' path):
+size(0,100);
+path unitcircle=E..N..W..S..cycle;
+path g=scale(2)*unitcircle;
+filldraw(unitcircle^^g,evenodd+yellow,black);
+
+
+ [superpath]
+
+The 'PostScript' even-odd fill rule here specifies that only the region
+bounded between the two unit circles is filled (*note fillrule::). In
+this example, the same effect can be achieved by using the default zero
+winding number fill rule, if one is careful to alternate the orientation
+of the paths:
+filldraw(unitcircle^^reverse(g),yellow,black);
+
+ The '^^' operator is used by the 'box(triple, triple)' function in
+the module 'three.asy' to construct the edges of a cube 'unitbox'
+without retracing steps (*note three::):
+import three;
+
+currentprojection=orthographic(5,4,2,center=true);
+
+size(5cm);
+size3(3cm,5cm,8cm);
+
+draw(unitbox);
+
+dot(unitbox,red);
+
+label("$O$",(0,0,0),NW);
+label("(1,0,0)",(1,0,0),S);
+label("(0,1,0)",(0,1,0),E);
+label("(0,0,1)",(0,0,1),Z);
+
+ [cube]
+
+ See section *note graph:: (or the online 'Asymptote' gallery and
+external links posted at <http://asymptote.sourceforge.net>) for further
+examples, including two-dimensional and interactive three-dimensional
+scientific graphs. Additional examples have been posted by Philippe
+Ivaldi at <http://www.piprime.fr/asymptote>.
+
+
+File: asymptote.info, Node: Drawing commands, Next: Bezier curves, Prev: Tutorial, Up: Top
+
+4 Drawing commands
+******************
+
+All of 'Asymptote''s graphical capabilities are based on four primitive
+commands. The three 'PostScript' drawing commands 'draw', 'fill', and
+'clip' add objects to a picture in the order in which they are executed,
+with the most recently drawn object appearing on top. The labeling
+command 'label' can be used to add text labels and external EPS images,
+which will appear on top of the 'PostScript' objects (since this is
+normally what one wants), but again in the relative order in which they
+were executed. After drawing objects on a picture, the picture can be
+output with the 'shipout' function (*note shipout::).
+
+ If you wish to draw 'PostScript' objects on top of labels (or
+verbatim 'tex' commands; *note tex::), the 'layer' command may be used
+to start a new 'PostScript/LaTeX' layer:
+void layer(picture pic=currentpicture);
+
+ The 'layer' function gives one full control over the order in which
+objects are drawn. Layers are drawn sequentially, with the most recent
+layer appearing on top. Within each layer, labels, images, and verbatim
+'tex' commands are always drawn after the 'PostScript' objects in that
+layer.
+
+ While some of these drawing commands take many options, they all have
+sensible default values (for example, the picture argument defaults to
+currentpicture).
+
+* Menu:
+
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+
+
+File: asymptote.info, Node: draw, Next: fill, Prev: Drawing commands, Up: Drawing commands
+
+4.1 draw
+========
+
+void draw(picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
+ Label legend="", marker marker=nomarker);
+
+ Draw the path 'g' on the picture 'pic' using pen 'p' for drawing,
+with optional drawing attributes (Label 'L', explicit label alignment
+'align', arrows and bars 'arrow' and 'bar', margins 'margin', legend,
+and markers 'marker'). Only one parameter, the path, is required. For
+convenience, the arguments 'arrow' and 'bar' may be specified in either
+order. The argument 'legend' is a Label to use in constructing an
+optional legend entry.
+
+ Bars are useful for indicating dimensions. The possible values of
+'bar' are 'None', 'BeginBar', 'EndBar' (or equivalently 'Bar'), and
+'Bars' (which draws a bar at both ends of the path). Each of these bar
+specifiers (except for 'None') will accept an optional real argument
+that denotes the length of the bar in 'PostScript' coordinates. The
+default bar length is 'barsize(pen)'.
+
+ The possible values of 'arrow' are 'None', 'Blank' (which draws no
+arrows or path), 'BeginArrow', 'MidArrow', 'EndArrow' (or equivalently
+'Arrow'), and 'Arrows' (which draws an arrow at both ends of the path).
+All of the arrow specifiers except for 'None' and 'Blank' may be given
+the optional arguments arrowhead 'arrowhead' (one of the predefined
+arrowhead styles 'DefaultHead', 'SimpleHead', 'HookHead', 'TeXHead'),
+real 'size' (arrowhead size in 'PostScript' coordinates), real 'angle'
+(arrowhead angle in degrees), filltype 'filltype' (one of 'FillDraw',
+'Fill', 'NoFill', 'UnFill', 'Draw') and (except for 'MidArrow' and
+'Arrows') a real 'position' (in the sense of 'point(path p, real t)')
+along the path where the tip of the arrow should be placed. The default
+arrowhead size when drawn with a pen 'p' is 'arrowsize(p)'. There are
+also arrow versions with slightly modified default values of 'size' and
+'angle' suitable for curved arrows: 'BeginArcArrow', 'EndArcArrow' (or
+equivalently 'ArcArrow'), 'MidArcArrow', and 'ArcArrows'.
+
+ Margins can be used to shrink the visible portion of a path by
+'labelmargin(p)' to avoid overlap with other drawn objects. Typical
+values of 'margin' are 'NoMargin', 'BeginMargin', 'EndMargin' (or
+equivalently 'Margin'), and 'Margins' (which leaves a margin at both
+ends of the path). One may use 'Margin(real begin, real end)' to
+specify the size of the beginning and ending margin, respectively, in
+multiples of the units 'labelmargin(p)' used for aligning labels.
+Alternatively, 'BeginPenMargin', 'EndPenMargin' (or equivalently
+'PenMargin'), 'PenMargins', 'PenMargin(real begin, real end)' specify a
+margin in units of the pen line width, taking account of the pen line
+width when drawing the path or arrow. For example, use 'DotMargin', an
+abbreviation for 'PenMargin(-0.5*dotfactor,0.5*dotfactor)', to draw from
+the usual beginning point just up to the boundary of an end dot of width
+'dotfactor*linewidth(p)'. The qualifiers 'BeginDotMargin',
+'EndDotMargin', and 'DotMargins' work similarly. The qualifier
+'TrueMargin(real begin, real end)' allows one to specify a margin
+directly in 'PostScript' units, independent of the pen line width.
+
+ The use of arrows, bars, and margins is illustrated by the examples
+'Pythagoras.asy', 'sqrtx01.asy', and 'triads.asy'.
+
+ The legend for a picture 'pic' can be fit and aligned to a frame with
+the routine:
+frame legend(picture pic=currentpicture, int perline=1,
+ real xmargin=legendmargin, real ymargin=xmargin,
+ real linelength=legendlinelength,
+ real hskip=legendhskip, real vskip=legendvskip,
+ real maxwidth=0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false, pen p=currentpen);
+Here 'xmargin' and 'ymargin' specify the surrounding x and y margins,
+'perline' specifies the number of entries per line (default 1; 0 means
+choose this number automatically), 'linelength' specifies the length of
+the path lines, 'hskip' and 'vskip' specify the line skip (as a multiple
+of the legend entry size), 'maxwidth' and 'maxheight' specify optional
+upper limits on the width and height of the resulting legend (0 means
+unlimited), 'hstretch' and 'vstretch' allow the legend to stretch
+horizontally or vertically, and 'p' specifies the pen used to draw the
+bounding box. The legend frame can then be added and aligned about a
+point on a picture 'dest' using 'add' or 'attach' (*note add about::).
+
+ To draw a dot, simply draw a path containing a single point. The
+'dot' command defined in the module 'plain' draws a dot having a
+diameter equal to an explicit pen line width or the default line width
+magnified by 'dotfactor' (6 by default), using the specified filltype
+(*note filltype::) or 'dotfilltype' ('Fill' by default):
+void dot(frame f, pair z, pen p=currentpen, filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, pair z, pen p=currentpen,
+ filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, Label L, pair z, align align=NoAlign,
+ string format=defaultformat, pen p=currentpen, filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, Label[] L=new Label[], pair[] z,
+ align align=NoAlign, string format=defaultformat, pen p=currentpen,
+ filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, path[] g, pen p=currentpen,
+ filltype filltype=dotfilltype);
+void dot(picture pic=currentpicture, Label L, pen p=currentpen,
+ filltype filltype=dotfilltype);
+
+ If the variable 'Label' is given as the 'Label' argument to the third
+routine, the 'format' argument will be used to format a string based on
+the dot location (here 'defaultformat' is '"$%.4g$"'). The fourth
+routine draws a dot at every point of a pair array 'z'. One can also
+draw a dot at every node of a path:
+void dot(picture pic=currentpicture, Label[] L=new Label[],
+ explicit path g, align align=RightSide, string format=defaultformat,
+ pen p=currentpen, filltype filltype=dotfilltype);
+ See *note pathmarkers:: and *note markers:: for more general methods
+for marking path nodes.
+
+ To draw a fixed-sized object (in 'PostScript' coordinates) about the
+user coordinate 'origin', use the routine
+void draw(pair origin, picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen, arrowbar arrow=None,
+ arrowbar bar=None, margin margin=NoMargin, Label legend="",
+ marker marker=nomarker);
+
+
+File: asymptote.info, Node: fill, Next: clip, Prev: draw, Up: Drawing commands
+
+4.2 fill
+========
+
+void fill(picture pic=currentpicture, path g, pen p=currentpen);
+
+ Fill the interior region bounded by the cyclic path 'g' on the
+picture 'pic', using the pen 'p'.
+
+ There is also a convenient 'filldraw' command, which fills the path
+and then draws in the boundary. One can specify separate pens for each
+operation:
+void filldraw(picture pic=currentpicture, path g, pen fillpen=currentpen,
+ pen drawpen=currentpen);
+
+ This fixed-size version of 'fill' allows one to fill an object
+described in 'PostScript' coordinates about the user coordinate
+'origin':
+void fill(pair origin, picture pic=currentpicture, path g, pen p=currentpen);
+
+This is just a convenient abbreviation for the commands:
+picture opic;
+fill(opic,g,p);
+add(pic,opic,origin);
+
+ The routine
+void filloutside(picture pic=currentpicture, path g, pen p=currentpen);
+fills the region exterior to the path 'g', out to the current boundary
+of picture 'pic'.
+
+ Lattice gradient shading varying smoothly over a two-dimensional
+array of pens 'p', using fill rule 'fillrule', can be produced with
+void latticeshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p)
+ If 'stroke=true', the region filled is the same as the region that
+would be drawn by 'draw(pic,g,zerowinding)'; in this case the path 'g'
+need not be cyclic. The pens in 'p' must belong to the same color
+space. One can use the functions 'rgb(pen)' or 'cmyk(pen)' to promote
+pens to a higher color space, as illustrated in the example file
+'latticeshading.asy'.
+
+ Axial gradient shading varying smoothly from 'pena' to 'penb' in the
+direction of the line segment 'a--b' can be achieved with
+void axialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a, bool extenda=true,
+ pen penb, pair b, bool extendb=true);
+The boolean parameters 'extenda' and 'extendb' indicate whether the
+shading should extend beyond the axis endpoints 'a' and 'b'.
+
+ Radial gradient shading varying smoothly from 'pena' on the circle
+with center 'a' and radius 'ra' to 'penb' on the circle with center 'b'
+and radius 'rb' is similar:
+void radialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a, real ra, bool extenda=true,
+ pen penb, pair b, real rb, bool extendb=true);
+The boolean parameters 'extenda' and 'extendb' indicate whether the
+shading should extend beyond the radii 'a' and 'b'. Illustrations of
+radial shading are provided in the example files 'shade.asy',
+'ring.asy', and 'shadestroke.asy'.
+
+ Gouraud shading using fill rule 'fillrule' and the vertex colors in
+the pen array 'p' on a triangular lattice defined by the vertices 'z'
+and edge flags 'edges' is implemented with
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, pair[] z,
+ int[] edges);
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, int[] edges);
+In the second form, the elements of 'z' are taken to be successive nodes
+of path 'g'. The pens in 'p' must belong to the same color space.
+Illustrations of Gouraud shading are provided in the example file
+'Gouraud.asy'. The edge flags used in Gouraud shading are documented
+here:
+ <http://partners.adobe.com/public/developer/en/ps/sdk/TN5600.SmoothShading.pdf>.
+
+ Tensor product shading using fill rule 'fillrule' on patches bounded
+by the n cyclic paths of length 4 in path array 'b', using the vertex
+colors specified in the n \times 4 pen array 'p' and internal control
+points in the n \times 4 array 'z', is implemented with
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, path[] b=g,
+ pair[][] z=new pair[][]);
+If the array 'z' is empty, Coons shading, in which the color control
+points are calculated automatically, is used. The pens in 'p' must
+belong to the same color space. A simpler interface for the case of a
+single patch (n=1) is also available:
+void tensorshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, path b=g,
+ pair[] z=new pair[]);
+ One can also smoothly shade the regions between consecutive paths of
+a sequence using a given array of pens:
+void draw(picture pic=currentpicture, pen fillrule=currentpen, path[] g,
+ pen[] p);
+Illustrations of tensor product and Coons shading are provided in the
+example files 'tensor.asy', 'Coons.asy', 'BezierSurface.asy', and
+'rainbow.asy'.
+
+ More general shading possibilities are available using TeX engines
+that produce PDF output (*note texengines::): the routine
+void functionshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, string shader);
+shades on picture 'pic' the interior of path 'g' according to fill rule
+'fillrule' using the 'PostScript' calculator routine specified by the
+string 'shader'; this routine takes 2 arguments, each in [0,1], and
+returns 'colors(fillrule).length' color components. Function shading is
+illustrated in the example 'functionshading.asy'.
+
+ The following routine uses 'evenodd' clipping together with the '^^'
+operator to unfill a region:
+
+void unfill(picture pic=currentpicture, path g);
+
+
+File: asymptote.info, Node: clip, Next: label, Prev: fill, Up: Drawing commands
+
+4.3 clip
+========
+
+void clip(picture pic=currentpicture, path g, stroke=false,
+ pen fillrule=currentpen);
+
+ Clip the current contents of picture 'pic' to the region bounded by
+the path 'g', using fill rule 'fillrule' (*note fillrule::). If
+'stroke=true', the clipped portion is the same as the region that would
+be drawn with 'draw(pic,g,zerowinding)'; in this case the path 'g' need
+not be cyclic. For an illustration of picture clipping, see the first
+example in *note LaTeX usage::.
+
+
+File: asymptote.info, Node: label, Prev: clip, Up: Drawing commands
+
+4.4 label
+=========
+
+void label(picture pic=currentpicture, Label L, pair position,
+ align align=NoAlign, pen p=currentpen, filltype filltype=NoFill)
+
+ Draw Label 'L' on picture 'pic' using pen 'p'. If 'align' is
+'NoAlign', the label will be centered at user coordinate 'position';
+otherwise it will be aligned in the direction of 'align' and displaced
+from 'position' by the 'PostScript' offset 'align*labelmargin(p)'. The
+constant 'Align' can be used to align the bottom-left corner of the
+label at 'position'. The Label 'L' can either be a string or the
+structure obtained by calling one of the functions
+Label Label(string s="", pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(string s="", align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(Label L, pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+Label Label(Label L, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+ The text of a Label can be scaled, slanted, rotated, or shifted by
+multiplying it on the left by an affine transform (*note Transforms::).
+For example, 'rotate(45)*xscale(2)*L' first scales 'L' in the x
+direction and then rotates it counterclockwise by 45 degrees. The final
+position of a Label can also be shifted by a 'PostScript' coordinate
+translation: 'shift(10,0)*L'. An explicit pen specified within the
+Label overrides other pen arguments. The 'embed' argument determines
+how the Label should transform with the embedding picture:
+'Shift'
+ only shift with embedding picture;
+
+'Rotate'
+ only shift and rotate with embedding picture (default);
+
+'Rotate(pair z)'
+ rotate with (picture-transformed) vector 'z'.
+
+'Slant'
+ only shift, rotate, slant, and reflect with embedding picture;
+
+'Scale'
+ shift, rotate, slant, reflect, and scale with embedding picture.
+
+ To add a label to a path, use
+void label(picture pic=currentpicture, Label L, path g, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill);
+ By default the label will be positioned at the midpoint of the path.
+An alternative label position (in the sense of 'point(path p, real t)')
+may be specified as a real value for 'position' in constructing the
+Label. The position 'Relative(real)' specifies a location relative to
+the total arclength of the path. These convenient abbreviations are
+predefined:
+position BeginPoint=Relative(0);
+position MidPoint=Relative(0.5);
+position EndPoint=Relative(1);
+
+ Path labels are aligned in the direction 'align', which may be
+specified as an absolute compass direction (pair) or a direction
+'Relative(pair)' measured relative to a north axis in the local
+direction of the path. For convenience 'LeftSide', 'Center', and
+'RightSide' are defined as 'Relative(W)', 'Relative((0,0))', and
+'Relative(E)', respectively. Multiplying 'LeftSide' and 'RightSide' on
+the left by a real scaling factor will move the label further away from
+or closer to the path.
+
+ A label with a fixed-size arrow of length 'arrowlength' pointing to
+'b' from direction 'dir' can be produced with the routine
+void arrow(picture pic=currentpicture, Label L="", pair b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar arrow=Arrow, margin margin=EndMargin);
+ If no alignment is specified (either in the Label or as an explicit
+argument), the optional Label will be aligned in the direction 'dir',
+using margin 'margin'.
+
+ The function 'string graphic(string name, string options="")' returns
+a string that can be used to include an encapsulated 'PostScript' (EPS)
+file. Here, 'name' is the name of the file to include and 'options' is
+a string containing a comma-separated list of optional bounding box
+('bb=llx lly urx ury'), width ('width=value'), height ('height=value'),
+rotation ('angle=value'), scaling ('scale=factor'), clipping
+('clip=bool'), and draft mode ('draft=bool') parameters. The 'layer()'
+function can be used to force future objects to be drawn on top of the
+included image:
+label(graphic("file.eps","width=1cm"),(0,0),NE);
+layer();
+
+ The 'string baseline(string s, string template="\strut")' function
+can be used to enlarge the bounding box of labels to match a given
+template, so that their baselines will be typeset on a horizontal line.
+See 'Pythagoras.asy' for an example.
+
+ One can prevent labels from overwriting one another with the
+'overwrite' pen attribute (*note overwrite::).
+
+ The structure 'object' defined in 'plain_Label.asy' allows Labels and
+frames to be treated in a uniform manner. A group of objects may be
+packed together into single frame with the routine
+frame pack(pair align=2S ... object inset[]);
+To draw or fill a box (or ellipse or other path) around a Label and
+return the bounding object, use one of the routines
+object draw(picture pic=currentpicture, Label L, envelope e,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+object draw(picture pic=currentpicture, Label L, envelope e, pair position,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+Here 'envelope' is a boundary-drawing routine such as 'box', 'roundbox',
+or 'ellipse' defined in 'plain_boxes.asy' (*note envelope::).
+
+ The function 'path[] texpath(Label L)' returns the path array that
+TeX would fill to draw the Label 'L'.
+
+ The 'string minipage(string s, width=100pt)' function can be used to
+format string 's' into a paragraph of width 'width'. This example uses
+'minipage', 'clip', and 'graphic' to produce a CD label:
+
+ [CDlabel]
+size(11.7cm,11.7cm);
+asy(nativeformat(),"logo");
+fill(unitcircle^^(scale(2/11.7)*unitcircle),
+ evenodd+rgb(124/255,205/255,124/255));
+label(scale(1.1)*minipage(
+"\centering\scriptsize \textbf{\LARGE {\tt Asymptote}\\
+\smallskip
+\small The Vector Graphics Language}\\
+\smallskip
+\textsc{Andy Hammerlindl, John Bowman, and Tom Prince}
+http://asymptote.sourceforge.net\\
+",8cm),(0,0.6));
+label(graphic("logo."+nativeformat(),"height=7cm"),(0,-0.22));
+clip(unitcircle^^(scale(2/11.7)*unitcircle),evenodd);
+
+
+File: asymptote.info, Node: Bezier curves, Next: Programming, Prev: Drawing commands, Up: Top
+
+5 Bezier curves
+***************
+
+Each interior node of a cubic spline may be given a direction prefix or
+suffix '{dir}': the direction of the pair 'dir' specifies the direction
+of the incoming or outgoing tangent, respectively, to the curve at that
+node. Exterior nodes may be given direction specifiers only on their
+interior side.
+
+ A cubic spline between the node z_0, with postcontrol point c_0, and
+the node z_1, with precontrol point c_1, is computed as the Bezier curve
+
+ [(1-t)^3*z_0+3t(1-t)^2*c_0+3t^2(1-t)*c_1+t^3*z_1 for 0 <=t <= 1.]
+
+ As illustrated in the diagram below, the third-order midpoint (m_5)
+constructed from two endpoints z_0 and z_1 and two control points c_0
+and c_1, is the point corresponding to t=1/2 on the Bezier curve formed
+by the quadruple (z_0, c_0, c_1, z_1). This allows one to recursively
+construct the desired curve, by using the newly extracted third-order
+midpoint as an endpoint and the respective second- and first-order
+midpoints as control points:
+
+ [bezier2]
+
+ Here m_0, m_1 and m_2 are the first-order midpoints, m_3 and m_4 are
+the second-order midpoints, and m_5 is the third-order midpoint. The
+curve is then constructed by recursively applying the algorithm to (z_0,
+m_0, m_3, m_5) and (m_5, m_4, m_2, z_1).
+
+ In fact, an analogous property holds for points located at any
+fraction t in [0,1] of each segment, not just for midpoints (t=1/2).
+
+ The Bezier curve constructed in this manner has the following
+properties:
+
+ * It is entirely contained in the convex hull of the given four
+ points.
+
+ * It starts heading from the first endpoint to the first control
+ point and finishes heading from the second control point to the
+ second endpoint.
+
+ The user can specify explicit control points between two nodes like
+this:
+draw((0,0)..controls (0,100) and (100,100)..(100,0));
+
+ However, it is usually more convenient to just use the '..' operator,
+which tells 'Asymptote' to choose its own control points using the
+algorithms described in Donald Knuth's monograph, The MetaFontbook,
+Chapter 14. The user can still customize the guide (or path) by
+specifying direction, tension, and curl values.
+
+ The higher the tension, the straighter the curve is, and the more it
+approximates a straight line. One can change the spline tension from
+its default value of 1 to any real value greater than or equal to 0.75
+(cf. John D. Hobby, Discrete and Computational Geometry 1, 1986):
+draw((100,0)..tension 2 ..(100,100)..(0,100));
+draw((100,0)..tension 3 and 2 ..(100,100)..(0,100));
+draw((100,0)..tension atleast 2 ..(100,100)..(0,100));
+
+ In these examples there is a space between '2' and '..'. This is
+needed as '2.' is interpreted as a numerical constant.
+
+ The curl parameter specifies the curvature at the endpoints of a path
+(0 means straight; the default value of 1 means approximately circular):
+draw((100,0){curl 0}..(100,100)..{curl 0}(0,100));
+
+ The 'MetaPost ...' path connector, which requests, when possible, an
+inflection-free curve confined to a triangle defined by the endpoints
+and directions, is implemented in 'Asymptote' as the convenient
+abbreviation '::' for '..tension atleast 1 ..' (the ellipsis '...' is
+used in 'Asymptote' to indicate a variable number of arguments; *note
+Rest arguments::). For example, compare
+draw((0,0){up}..(100,25){right}..(200,0){down});
+
+ [dots]
+with
+draw((0,0){up}::(100,25){right}::(200,0){down});
+
+ [colons]
+
+ The '---' connector is an abbreviation for '..tension atleast
+infinity..' and the '&' connector concatenates two paths, after first
+stripping off the last node of the first path (which normally should
+coincide with the first node of the second path).
+
+
+File: asymptote.info, Node: Programming, Next: LaTeX usage, Prev: Bezier curves, Up: Top
+
+6 Programming
+*************
+
+* Menu:
+
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides:: Bezier curves
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external 'Asymptote' modules
+* Static:: Where to allocate your variable?
+
+Here is a short introductory example to the 'Asymptote' programming
+language that highlights the similarity of its control structures with
+those of C, C++, and Java:
+// This is a comment.
+
+// Declaration: Declare x to be a real variable;
+real x;
+
+// Assignment: Assign the real variable x the value 1.
+x=1.0;
+
+// Conditional: Test if x equals 1 or not.
+if(x == 1.0) {
+ write("x equals 1.0");
+} else {
+ write("x is not equal to 1.0");
+}
+
+// Loop: iterate 10 times
+for(int i=0; i < 10; ++i) {
+ write(i);
+}
+
+
+ 'Asymptote' supports 'while', 'do', 'break', and 'continue'
+statements just as in C/C++. It also supports the Java-style shorthand
+for iterating over all elements of an array:
+
+// Iterate over an array
+int[] array={1,1,2,3,5};
+for(int k : array) {
+ write(k);
+}
+In addition, it supports many features beyond the ones found in those
+languages.
+
+
+File: asymptote.info, Node: Data types, Next: Paths and guides, Prev: Programming, Up: Programming
+
+6.1 Data types
+==============
+
+'Asymptote' supports the following data types (in addition to
+user-defined types):
+
+'void'
+ The void type is used only by functions that take or return no
+ arguments.
+
+'bool'
+ a boolean type that can only take on the values 'true' or 'false'.
+ For example:
+ bool b=true;
+
+ defines a boolean variable 'b' and initializes it to the value
+ 'true'. If no initializer is given:
+ bool b;
+
+ the value 'false' is assumed.
+
+'bool3'
+ an extended boolean type that can take on the values 'true',
+ 'default', or 'false'. A bool3 type can be cast to or from a bool.
+ The default initializer for bool3 is 'default'.
+
+'int'
+ an integer type; if no initializer is given, the implicit value '0'
+ is assumed. The minimum allowed value of an integer is 'intMin'
+ and the maximum value is 'intMax'.
+
+'real'
+ a real number; this should be set to the highest-precision native
+ floating-point type on the architecture. The implicit initializer
+ for reals is '0.0'. Real numbers have precision 'realEpsilon',
+ with 'realDigits' significant digits. The smallest positive real
+ number is 'realMin' and the largest positive real number is
+ 'realMax'. The variables 'inf' and 'nan', along with the function
+ 'bool isnan(real x)' are useful when floating-point exceptions are
+ masked with the '-mask' command-line option (the default in
+ interactive mode).
+
+'pair'
+ complex number, that is, an ordered pair of real components
+ '(x,y)'. The real and imaginary parts of a pair 'z' can read as
+ 'z.x' and 'z.y'. We say that 'x' and 'y' are virtual members of
+ the data element pair; they cannot be directly modified, however.
+ The implicit initializer for pairs is '(0.0,0.0)'.
+
+ There are a number of ways to take the complex conjugate of a pair:
+ pair z=(3,4);
+ z=(z.x,-z.y);
+ z=z.x-I*z.y;
+ z=conj(z);
+
+ Here 'I' is the pair '(0,1)'. A number of built-in functions are
+ defined for pairs:
+
+ 'pair conj(pair z)'
+ returns the conjugate of 'z';
+
+ 'real length(pair z)'
+ returns the complex modulus '|z|' of its argument 'z'. For
+ example,
+ pair z=(3,4);
+ length(z);
+ returns the result 5. A synonym for 'length(pair)' is
+ 'abs(pair)';
+
+ 'real angle(pair z, bool warn=true)'
+ returns the angle of 'z' in radians in the interval
+ [-'pi','pi'] or '0' if 'warn' is 'false' and 'z=(0,0)' (rather
+ than producing an error);
+
+ 'real degrees(pair z, bool warn=true)'
+ returns the angle of 'z' in degrees in the interval [0,360) or
+ '0' if 'warn' is 'false' and 'z=(0,0)' (rather than producing
+ an error);
+
+ 'pair unit(pair z)'
+ returns a unit vector in the direction of the pair 'z';
+
+ 'pair expi(real angle)'
+ returns a unit vector in the direction 'angle' measured in
+ radians;
+
+ 'pair dir(real degrees)'
+ returns a unit vector in the direction 'degrees' measured in
+ degrees;
+
+ 'real xpart(pair z)'
+ returns 'z.x';
+
+ 'real ypart(pair z)'
+ returns 'z.y';
+
+ 'pair realmult(pair z, pair w)'
+ returns the element-by-element product '(z.x*w.x,z.y*w.y)';
+
+ 'real dot(explicit pair z, explicit pair w)'
+ returns the dot product 'z.x*w.x+z.y*w.y';
+
+ 'real cross(explicit pair z, explicit pair w)'
+ returns the 2D scalar product 'z.x*w.y-z.y*w.x';
+
+ 'real orient(pair a, pair b, pair c);'
+ returns a positive (negative) value if 'a--b--c--cycle' is
+ oriented counterclockwise (clockwise) or zero if all three
+ points are colinear. Equivalently, a positive (negative)
+ value is returned if 'c' lies to the left (right) of the line
+ through 'a' and 'b' or zero if 'c' lies on this line. The
+ value returned can be expressed in terms of the 2D scalar
+ cross product as 'cross(a-c,b-c)', which is the determinant
+ |a.x a.y 1|
+ |b.x b.y 1|
+ |c.x c.y 1|
+
+ 'real incircle(pair a, pair b, pair c, pair d);'
+ returns a positive (negative) value if 'd' lies inside
+ (outside) the circle passing through the
+ counterclockwise-oriented points 'a,b,c' or zero if 'd' lies
+ on the this circle. The value returned is the determinant
+ |a.x a.y a.x^2+a.y^2 1|
+ |b.x b.y b.x^2+b.y^2 1|
+ |c.x c.y c.x^2+c.y^2 1|
+ |d.x d.y d.x^2+d.y^2 1|
+
+ 'pair minbound(pair z, pair w)'
+ returns '(min(z.x,w.x),min(z.y,w.y))';
+
+ 'pair maxbound(pair z, pair w)'
+ returns '(max(z.x,w.x),max(z.y,w.y))'.
+
+'triple'
+ an ordered triple of real components '(x,y,z)' used for
+ three-dimensional drawings. The respective components of a triple
+ 'v' can read as 'v.x', 'v.y', and 'v.z'. The implicit initializer
+ for triples is '(0.0,0.0,0.0)'.
+
+ Here are the built-in functions for triples:
+ 'real length(triple v)'
+ returns the length '|v|' of the vector 'v'. A synonym for
+ 'length(triple)' is 'abs(triple)';
+
+ 'real polar(triple v, bool warn=true)'
+ returns the colatitude of 'v' measured from the z axis in
+ radians or '0' if 'warn' is 'false' and 'v=O' (rather than
+ producing an error);
+
+ 'real azimuth(triple v, bool warn=true)'
+ returns the longitude of 'v' measured from the x axis in
+ radians or '0' if 'warn' is 'false' and 'v.x=v.y=0' (rather
+ than producing an error);
+
+ 'real colatitude(triple v, bool warn=true)'
+ returns the colatitude of 'v' measured from the z axis in
+ degrees or '0' if 'warn' is 'false' and 'v=O' (rather than
+ producing an error);
+
+ 'real latitude(triple v, bool warn=true)'
+ returns the latitude of 'v' measured from the xy plane in
+ degrees or '0' if 'warn' is 'false' and 'v=O' (rather than
+ producing an error);
+
+ 'real longitude(triple v, bool warn=true)'
+ returns the longitude of 'v' measured from the x axis in
+ degrees or '0' if 'warn' is 'false' and 'v.x=v.y=0' (rather
+ than producing an error);
+
+ 'triple unit(triple v)'
+ returns a unit triple in the direction of the triple 'v';
+
+ 'triple expi(real polar, real azimuth)'
+ returns a unit triple in the direction '(polar,azimuth)'
+ measured in radians;
+
+ 'triple dir(real colatitude, real longitude)'
+ returns a unit triple in the direction
+ '(colatitude,longitude)' measured in degrees;
+
+ 'real xpart(triple v)'
+ returns 'v.x';
+
+ 'real ypart(triple v)'
+ returns 'v.y';
+
+ 'real zpart(triple v)'
+ returns 'v.z';
+
+ 'real dot(triple u, triple v)'
+ returns the dot product 'u.x*v.x+u.y*v.y+u.z*v.z';
+
+ 'triple cross(triple u, triple v)'
+ returns the cross product
+
+ '(u.y*v.z-u.z*v.y,u.z*v.x-u.x*v.z,u.x*v.y-v.x*u.y)';
+
+ 'triple minbound(triple u, triple v)'
+ returns '(min(u.x,v.x),min(u.y,v.y),min(u.z,v.z))';
+
+ 'triple maxbound(triple u, triple v)'
+ returns '(max(u.x,v.x),max(u.y,v.y),max(u.z,v.z)').
+
+'string'
+ a character string, implemented using the STL 'string' class.
+
+ Strings delimited by double quotes ('"') are subject to the
+ following mappings to allow the use of double quotes in TeX
+ (e.g. for using the 'babel' package, *note babel::):
+
+ * \" maps to "
+ * \\ maps to \\
+
+ Strings delimited by single quotes (''') have the same mappings as
+ character strings in ANSI 'C':
+
+ * \' maps to '
+ * \" maps to "
+ * \? maps to ?
+ * \\ maps to backslash
+ * \a maps to alert
+ * \b maps to backspace
+ * \f maps to form feed
+ * \n maps to newline
+ * \r maps to carriage return
+ * \t maps to tab
+ * \v maps to vertical tab
+ * \0-\377 map to corresponding octal byte
+ * \x0-\xFF map to corresponding hexadecimal byte
+
+ The implicit initializer for strings is the empty string '""'.
+ Strings may be concatenated with the '+' operator. In the
+ following string functions, position '0' denotes the start of the
+ string:
+
+ 'int length(string s)'
+ returns the length of the string 's';
+
+ 'int find(string s, string t, int pos=0)'
+ returns the position of the first occurrence of string 't' in
+ string 's' at or after position 'pos', or -1 if 't' is not a
+ substring of 's';
+
+ 'int rfind(string s, string t, int pos=-1)'
+ returns the position of the last occurrence of string 't' in
+ string 's' at or before position 'pos' (if 'pos'=-1, at the
+ end of the string 's'), or -1 if 't' is not a substring of
+ 's';
+
+ 'string insert(string s, int pos, string t)'
+ returns the string formed by inserting string 't' at position
+ 'pos' in 's';
+
+ 'string erase(string s, int pos, int n)'
+ returns the string formed by erasing the string of length 'n'
+ (if 'n'=-1, to the end of the string 's') at position 'pos' in
+ 's';
+
+ 'string substr(string s, int pos, int n=-1)'
+ returns the substring of 's' starting at position 'pos' and of
+ length 'n' (if 'n'=-1, until the end of the string 's');
+
+ 'string reverse(string s)'
+ returns the string formed by reversing string 's';
+
+ 'string replace(string s, string before, string after)'
+ returns a string with all occurrences of the string 'before'
+ in the string 's' changed to the string 'after';
+
+ 'string replace(string s, string[][] table)'
+ returns a string constructed by translating in string 's' all
+ occurrences of the string 'before' in an array 'table' of
+ string pairs {'before','after'} to the corresponding string
+ 'after';
+
+ 'string[] split(string s, string delimiter="")'
+ returns an array of strings obtained by splitting 's' into
+ substrings delimited by 'delimiter' (an empty delimiter
+ signifies a space, but with duplicate delimiters discarded);
+
+ 'string[] array(string s)'
+ returns an array of strings obtained by splitting 's' into
+ individual characters. The inverse operation is provided by
+ 'operator +(...string[] a)'.
+
+ 'string format(string s, int n, string locale="")'
+ returns a string containing 'n' formatted according to the
+ C-style format string 's' using locale 'locale' (or the
+ current locale if an empty string is specified), following the
+ behaviour of the C function 'fprintf'), except that only one
+ data field is allowed.
+
+ 'string format(string s=defaultformat, bool forcemath=false, string s=defaultseparator, real x, string locale="")'
+ returns a string containing 'x' formatted according to the
+ C-style format string 's' using locale 'locale' (or the
+ current locale if an empty string is specified), following the
+ behaviour of the C function 'fprintf'), except that only one
+ data field is allowed, trailing zeros are removed by default
+ (unless '#' is specified), and if 's' specifies math mode or
+ 'forcemath=true', TeX is used to typeset scientific notation
+ using the 'defaultseparator="\!\times\!";';
+
+ 'int hex(string s);'
+ casts a hexadecimal string 's' to an integer;
+
+ 'int ascii(string s);'
+ returns the ASCII code for the first character of string 's';
+
+ 'string string(real x, int digits=realDigits)'
+ casts 'x' to a string using precision 'digits' and the C
+ locale;
+
+ 'string locale(string s="")'
+ sets the locale to the given string, if nonempty, and returns
+ the current locale;
+
+ 'string time(string format="%a %b %d %T %Z %Y")'
+ returns the current time formatted by the ANSI C routine
+ 'strftime' according to the string 'format' using the current
+ locale. Thus
+ time();
+ time("%a %b %d %H:%M:%S %Z %Y");
+
+ are equivalent ways of returning the current time in the
+ default format used by the 'UNIX' 'date' command;
+
+ 'int seconds(string t="", string format="")'
+ returns the time measured in seconds after the Epoch (Thu Jan
+ 01 00:00:00 UTC 1970) as determined by the ANSI C routine
+ 'strptime' according to the string 'format' using the current
+ locale, or the current time if 't' is the empty string. Note
+ that the '"%Z"' extension to the POSIX 'strptime'
+ specification is ignored by the current GNU C Library. If an
+ error occurs, the value -1 is returned. Here are some
+ examples:
+ seconds("Mar 02 11:12:36 AM PST 2007","%b %d %r PST %Y");
+ seconds(time("%b %d %r %z %Y"),"%b %d %r %z %Y");
+ seconds(time("%b %d %r %Z %Y"),"%b %d %r "+time("%Z")+" %Y");
+ 1+(seconds()-seconds("Jan 1","%b %d"))/(24*60*60);
+ The last example returns today's ordinal date, measured from
+ the beginning of the year.
+
+ 'string time(int seconds, string format="%a %b %d %T %Z %Y")'
+ returns the time corresponding to 'seconds' seconds after the
+ Epoch (Thu Jan 01 00:00:00 UTC 1970) formatted by the ANSI C
+ routine 'strftime' according to the string 'format' using the
+ current locale. For example, to return the date corresponding
+ to 24 hours ago:
+ time(seconds()-24*60*60);
+
+ 'int system(string s)'
+ 'int system(string[] s)'
+ if the setting 'safe' is false, call the arbitrary system
+ command 's';
+
+ 'void asy(string format, bool overwrite=false ... string[] s)'
+ conditionally process each file name in array 's' in a new
+ environment, using format 'format', overwriting the output
+ file only if 'overwrite' is true;
+
+ 'void abort(string s="")'
+ aborts execution (with a non-zero return code in batch mode);
+ if string 's' is nonempty, a diagnostic message constructed
+ from the source file, line number, and 's' is printed;
+
+ 'void assert(bool b, string s="")'
+ aborts execution with an error message constructed from 's' if
+ 'b=false';
+
+ 'void exit()'
+ exits (with a zero error return code in batch mode);
+
+ 'void sleep(int seconds)'
+ pauses for the given number of seconds;
+
+ 'void usleep(int microseconds)'
+ pauses for the given number of microseconds;
+
+ 'void beep()'
+ produces a beep on the console;
+
+ As in C/C++, complicated types may be abbreviated with 'typedef' (see
+the example in *note Functions::).
+
+
+File: asymptote.info, Node: Paths and guides, Next: Pens, Prev: Data types, Up: Programming
+
+6.2 Paths and guides
+====================
+
+'path'
+ a cubic spline resolved into a fixed path. The implicit
+ initializer for paths is 'nullpath'.
+
+ For example, the routine 'circle(pair c, real r)', which returns a
+ Bezier curve approximating a circle of radius 'r' centered on 'c',
+ is based on 'unitcircle' (*note unitcircle::):
+ path circle(pair c, real r)
+ {
+ return shift(c)*scale(r)*unitcircle;
+ }
+ If high accuracy is needed, a true circle may be produced with the
+ routine 'Circle' defined in the module 'graph.asy':
+ import graph;
+ path Circle(pair c, real r, int n=nCircle);
+
+ A circular arc consistent with 'circle' centered on 'c' with radius
+ 'r' from 'angle1' to 'angle2' degrees, drawing counterclockwise if
+ 'angle2 >= angle1', can be constructed with
+ path arc(pair c, real r, real angle1, real angle2);
+ One may also specify the direction explicitly:
+ path arc(pair c, real r, real angle1, real angle2, bool direction);
+ Here the direction can be specified as CCW (counter-clockwise) or
+ CW (clockwise). For convenience, an arc centered at 'c' from pair
+ 'z1' to 'z2' (assuming '|z2-c|=|z1-c|') in the may also be
+ constructed with
+ path arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW)
+
+ If high accuracy is needed, true arcs may be produced with routines
+ in the module 'graph.asy' that produce Bezier curves with 'n'
+ control points:
+ import graph;
+ path Arc(pair c, real r, real angle1, real angle2, bool direction,
+ int n=nCircle);
+ path Arc(pair c, real r, real angle1, real angle2, int n=nCircle);
+ path Arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW, int n=nCircle);
+
+ An ellipse can be drawn with the routine
+ path ellipse(pair c, real a, real b)
+ {
+ return shift(c)*scale(a,b)*unitcircle;
+ }
+
+ A brace can be constructed between pairs 'a' and 'b' with
+ path brace(pair a, pair b, real amplitude=bracedefaultratio*length(b-a));
+
+ This example illustrates the use of all five guide connectors
+ discussed in *note Tutorial:: and *note Bezier curves:::
+ size(300,0);
+ pair[] z=new pair[10];
+
+ z[0]=(0,100); z[1]=(50,0); z[2]=(180,0);
+
+ for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0);
+
+ path p=z[0]..z[1]---z[2]::{up}z[3]
+ &z[3]..z[4]--z[5]::{up}z[6]
+ &z[6]::z[7]---z[8]..{up}z[9];
+
+ draw(p,grey+linewidth(4mm));
+
+ dot(z);
+
+ [join]
+
+ Here are some useful functions for paths:
+
+ 'int length(path p);'
+ This is the number of (linear or cubic) segments in path 'p'.
+ If 'p' is cyclic, this is the same as the number of nodes in
+ 'p'.
+
+ 'int size(path p);'
+ This is the number of nodes in the path 'p'. If 'p' is
+ cyclic, this is the same as 'length(p)'.
+
+ 'bool cyclic(path p);'
+ returns 'true' iff path 'p' is cyclic.
+
+ 'bool straight(path p, int i);'
+ returns 'true' iff the segment of path 'p' between node 'i'
+ and node 'i+1' is straight.
+
+ 'bool piecewisestraight(path p)'
+ returns 'true' iff the path 'p' is piecewise straight.
+
+ 'pair point(path p, int t);'
+ If 'p' is cyclic, return the coordinates of node 't' mod
+ 'length(p)'. Otherwise, return the coordinates of node 't',
+ unless 't' < 0 (in which case 'point(0)' is returned) or 't' >
+ 'length(p)' (in which case 'point(length(p))' is returned).
+
+ 'pair point(path p, real t);'
+ This returns the coordinates of the point between node
+ 'floor(t)' and 'floor(t)+1' corresponding to the cubic spline
+ parameter 't-floor(t)' (*note Bezier curves::). If 't' lies
+ outside the range [0,'length(p)'], it is first reduced modulo
+ 'length(p)' in the case where 'p' is cyclic or else converted
+ to the corresponding endpoint of 'p'.
+
+ 'pair dir(path p, int t, int sign=0, bool normalize=true);'
+ If 'sign < 0', return the direction (as a pair) of the
+ incoming tangent to path 'p' at node 't'; if 'sign > 0',
+ return the direction of the outgoing tangent. If 'sign=0',
+ the mean of these two directions is returned.
+
+ 'pair dir(path p, real t, bool normalize=true);'
+ returns the direction of the tangent to path 'p' at the point
+ between node 'floor(t)' and 'floor(t)+1' corresponding to the
+ cubic spline parameter 't-floor(t)' (*note Bezier curves::).
+
+ 'pair dir(path p)'
+ returns dir(p,length(p)).
+
+ 'pair dir(path p, path q)'
+ returns unit(dir(p)+dir(q)).
+
+ 'pair accel(path p, int t, int sign=0);'
+ If 'sign < 0', return the acceleration of the incoming path
+ 'p' at node 't'; if 'sign > 0', return the acceleration of the
+ outgoing path. If 'sign=0', the mean of these two
+ accelerations is returned.
+
+ 'pair accel(path p, real t);'
+ returns the acceleration of the path 'p' at the point 't'.
+
+ 'real radius(path p, real t);'
+ returns the radius of curvature of the path 'p' at the point
+ 't'.
+
+ 'pair precontrol(path p, int t);'
+ returns the precontrol point of 'p' at node 't'.
+
+ 'pair precontrol(path p, real t);'
+ returns the effective precontrol point of 'p' at parameter
+ 't'.
+
+ 'pair postcontrol(path p, int t);'
+ returns the postcontrol point of 'p' at node 't'.
+
+ 'pair postcontrol(path p, real t);'
+ returns the effective postcontrol point of 'p' at parameter
+ 't'.
+
+ 'real arclength(path p);'
+ returns the length (in user coordinates) of the piecewise
+ linear or cubic curve that path 'p' represents.
+
+ 'real arctime(path p, real L);'
+ returns the path "time", a real number between 0 and the
+ length of the path in the sense of 'point(path p, real t)', at
+ which the cumulative arclength (measured from the beginning of
+ the path) equals 'L'.
+
+ 'real arcpoint(path p, real L);'
+ returns 'point(p,arctime(p,L))'.
+
+ 'real dirtime(path p, pair z);'
+ returns the first "time", a real number between 0 and the
+ length of the path in the sense of 'point(path, real)', at
+ which the tangent to the path has the direction of pair 'z',
+ or -1 if this never happens.
+
+ 'real reltime(path p, real l);'
+ returns the time on path 'p' at the relative fraction 'l' of
+ its arclength.
+
+ 'pair relpoint(path p, real l);'
+ returns the point on path 'p' at the relative fraction 'l' of
+ its arclength.
+
+ 'pair midpoint(path p);'
+ returns the point on path 'p' at half of its arclength.
+
+ 'path reverse(path p);'
+ returns a path running backwards along 'p'.
+
+ 'path subpath(path p, int a, int b);'
+ returns the subpath of 'p' running from node 'a' to node 'b'.
+ If 'a' < 'b', the direction of the subpath is reversed.
+
+ 'path subpath(path p, real a, real b);'
+ returns the subpath of 'p' running from path time 'a' to path
+ time 'b', in the sense of 'point(path, real)'. If 'a' < 'b',
+ the direction of the subpath is reversed.
+
+ 'real[] intersect(path p, path q, real fuzz=-1);'
+ If 'p' and 'q' have at least one intersection point, return a
+ real array of length 2 containing the times representing the
+ respective path times along 'p' and 'q', in the sense of
+ 'point(path, real)', for one such intersection point (as
+ chosen by the algorithm described on page 137 of 'The
+ MetaFontbook'). The computations are performed to the
+ absolute error specified by 'fuzz', or if 'fuzz < 0', to
+ machine precision. If the paths do not intersect, return a
+ real array of length 0.
+
+ 'real[][] intersections(path p, path q, real fuzz=-1);'
+ Return all (unless there are infinitely many) intersection
+ times of paths 'p' and 'q' as a sorted array of real arrays of
+ length 2 (*note sort::). The computations are performed to
+ the absolute error specified by 'fuzz', or if 'fuzz < 0', to
+ machine precision.
+
+ 'real[] intersections(path p, explicit pair a, explicit pair b, real fuzz=-1);'
+ Return all (unless there are infinitely many) intersection
+ times of path 'p' with the (infinite) line through points 'a'
+ and 'b' as a sorted array. The intersections returned are
+ guaranteed to be correct to within the absolute error
+ specified by 'fuzz', or if 'fuzz < 0', to machine precision.
+
+ 'real[] times(path p, real x)'
+ returns all intersection times of path 'p' with the vertical
+ line through '(x,0)'.
+
+ 'real[] times(path p, explicit pair z)'
+ returns all intersection times of path 'p' with the horizontal
+ line through '(0,z.y)'.
+
+ 'real[] mintimes(path p)'
+ returns an array of length 2 containing times at which path
+ 'p' reaches its minimal horizontal and vertical extents,
+ respectively.
+
+ 'real[] maxtimes(path p)'
+ returns an array of length 2 containing times at which path
+ 'p' reaches its maximal horizontal and vertical extents,
+ respectively.
+
+ 'pair intersectionpoint(path p, path q, real fuzz=-1);'
+ returns the intersection point
+ 'point(p,intersect(p,q,fuzz)[0])'.
+
+ 'pair[] intersectionpoints(path p, path q, real fuzz=-1);'
+ returns an array containing all intersection points of the
+ paths 'p' and 'q'.
+
+ 'pair extension(pair P, pair Q, pair p, pair q);'
+ returns the intersection point of the extensions of the line
+ segments 'P--Q' and 'p--q', or if the lines are parallel,
+ '(infinity,infinity)'.
+
+ 'slice cut(path p, path knife, int n);'
+ returns the portions of path 'p' before and after the 'n'th
+ intersection of 'p' with path 'knife' as a structure 'slice'
+ (if no intersection exist is found, the entire path is
+ considered to be 'before' the intersection):
+ struct slice {
+ path before,after;
+ }
+ The argument 'n' is treated as modulo the number of
+ intersections.
+
+ 'slice firstcut(path p, path knife);'
+ equivalent to 'cut(p,knife,0);' Note that 'firstcut.after'
+ plays the role of the 'MetaPost cutbefore' command.
+
+ 'slice lastcut(path p, path knife);'
+ equivalent to 'cut(p,knife,-1);' Note that 'lastcut.before'
+ plays the role of the 'MetaPost cutafter' command.
+
+ 'path buildcycle(... path[] p);'
+ This returns the path surrounding a region bounded by a list
+ of two or more consecutively intersecting paths, following the
+ behaviour of the 'MetaPost buildcycle' command.
+
+ 'pair min(path p);'
+ returns the pair (left,bottom) for the path bounding box of
+ path 'p'.
+
+ 'pair max(path p);'
+ returns the pair (right,top) for the path bounding box of path
+ 'p'.
+
+ 'int windingnumber(path p, pair z);'
+ returns the winding number of the cyclic path 'p' relative to
+ the point 'z'. The winding number is positive if the path
+ encircles 'z' in the counterclockwise direction. If 'z' lies
+ on 'p' the constant 'undefined' (defined to be the largest odd
+ integer) is returned.
+
+ 'bool interior(int windingnumber, pen fillrule)'
+ returns true if 'windingnumber' corresponds to an interior
+ point according to 'fillrule'.
+
+ 'bool inside(path p, pair z, pen fillrule=currentpen);'
+ returns 'true' iff the point 'z' lies inside or on the edge of
+ the region bounded by the cyclic path 'p' according to the
+ fill rule 'fillrule' (*note fillrule::).
+
+ 'int inside(path p, path q, pen fillrule=currentpen);'
+ returns '1' if the cyclic path 'p' strictly contains 'q'
+ according to the fill rule 'fillrule' (*note fillrule::), '-1'
+ if the cyclic path 'q' strictly contains 'p', and '0'
+ otherwise.
+
+ 'pair inside(path p, pen fillrule=currentpen);'
+ returns an arbitrary point strictly inside a cyclic path 'p'
+ according to the fill rule 'fillrule' (*note fillrule::).
+
+ 'path[] strokepath(path g, pen p=currentpen);'
+ returns the path array that 'PostScript' would fill in drawing
+ path 'g' with pen 'p'.
+
+'guide'
+ an unresolved cubic spline (list of cubic-spline nodes and control
+ points). The implicit initializer for a guide is 'nullpath'; this
+ is useful for building up a guide within a loop.
+
+ A guide is similar to a path except that the computation of the
+ cubic spline is deferred until drawing time (when it is resolved
+ into a path); this allows two guides with free endpoint conditions
+ to be joined together smoothly. The solid curve in the following
+ example is built up incrementally as a guide, but only resolved at
+ drawing time; the dashed curve is incrementally resolved at each
+ iteration, before the entire set of nodes (shown in red) is known:
+
+ size(200);
+
+ real mexican(real x) {return (1-8x^2)*exp(-(4x^2));}
+
+ int n=30;
+ real a=1.5;
+ real width=2a/n;
+
+ guide hat;
+ path solved;
+
+ for(int i=0; i < n; ++i) {
+ real t=-a+i*width;
+ pair z=(t,mexican(t));
+ hat=hat..z;
+ solved=solved..z;
+ }
+
+ draw(hat);
+ dot(hat,red);
+ draw(solved,dashed);
+
+
+ [mexicanhat]
+
+ We point out an efficiency distinction in the use of guides and
+ paths:
+ guide g;
+ for(int i=0; i < 10; ++i)
+ g=g--(i,i);
+ path p=g;
+
+ runs in linear time, whereas
+ path p;
+ for(int i=0; i < 10; ++i)
+ p=p--(i,i);
+
+ runs in quadratic time, as the entire path up to that point is
+ copied at each step of the iteration.
+
+ The following routines can be used to examine the individual
+ elements of a guide without actually resolving the guide to a fixed
+ path (except for internal cycles, which are resolved):
+
+ 'int size(guide g);'
+ Analogous to 'size(path p)'.
+
+ 'int length(guide g);'
+ Analogous to 'length(path p)'.
+
+ 'bool cyclic(path p);'
+ Analogous to 'cyclic(path p)'.
+
+ 'pair point(guide g, int t);'
+ Analogous to 'point(path p, int t)'.
+
+ 'guide reverse(guide g);'
+ Analogous to 'reverse(path p)'. If 'g' is cyclic and also
+ contains a secondary cycle, it is first solved to a path, then
+ reversed. If 'g' is not cyclic but contains an internal
+ cycle, only the internal cycle is solved before reversal. If
+ there are no internal cycles, the guide is reversed but not
+ solved to a path.
+
+ 'pair[] dirSpecifier(guide g, int i);'
+ This returns a pair array of length 2 containing the outgoing
+ (in element 0) and incoming (in element 1) direction
+ specifiers (or '(0,0)' if none specified) for the segment of
+ guide 'g' between nodes 'i' and 'i+1'.
+
+ 'pair[] controlSpecifier(guide g, int i);'
+ If the segment of guide 'g' between nodes 'i' and 'i+1' has
+ explicit outgoing and incoming control points, they are
+ returned as elements 0 and 1, respectively, of a two-element
+ array. Otherwise, an empty array is returned.
+
+ 'tensionSpecifier tensionSpecifier(guide g, int i);'
+ This returns the tension specifier for the segment of guide
+ 'g' between nodes 'i' and 'i+1'. The individual components of
+ the 'tensionSpecifier' type can be accessed as the virtual
+ members 'in', 'out', and 'atLeast'.
+
+ 'real[] curlSpecifier(guide g);'
+ This returns an array containing the initial curl specifier
+ (in element 0) and final curl specifier (in element 1) for
+ guide 'g'.
+
+ As a technical detail we note that a direction specifier given to
+ 'nullpath' modifies the node on the other side: the guides
+ a..{up}nullpath..b;
+ c..nullpath{up}..d;
+ e..{up}nullpath{down}..f;
+ are respectively equivalent to
+ a..nullpath..{up}b;
+ c{up}..nullpath..d;
+ e{down}..nullpath..{up}f;
+
+
+File: asymptote.info, Node: Pens, Next: Transforms, Prev: Paths and guides, Up: Programming
+
+6.3 Pens
+========
+
+In 'Asymptote', pens provide a context for the four basic drawing
+commands (*note Drawing commands::). They are used to specify the
+following drawing attributes: color, line type, line width, line cap,
+line join, fill rule, text alignment, font, font size, pattern,
+overwrite mode, and calligraphic transforms on the pen nib. The default
+pen used by the drawing routines is called 'currentpen'. This provides
+the same functionality as the 'MetaPost' command 'pickup'. The implicit
+initializer for pens is 'defaultpen'.
+
+ Pens may be added together with the nonassociative binary operator
+'+'. This will add the colors of the two pens. All other non-default
+attributes of the rightmost pen will override those of the leftmost pen.
+Thus, one can obtain a yellow dashed pen by saying 'dashed+red+green' or
+'red+green+dashed' or 'red+dashed+green'. The binary operator '*' can
+be used to scale the color of a pen by a real number, until it saturates
+with one or more color components equal to 1.
+
+ * Colors are specified using one of the following colorspaces:
+ 'pen gray(real g);'
+ This produces a grayscale color, where the intensity 'g' lies
+ in the interval [0,1], with 0.0 denoting black and 1.0
+ denoting white.
+
+ 'pen rgb(real r, real g, real b);'
+ This produces an RGB color, where each of the red, green, and
+ blue intensities 'r', 'g', 'b', lies in the interval [0,1].
+
+ 'pen RGB(int r, int g, int b);'
+ This produces an RGB color, where each of the red, green, and
+ blue intensities 'r', 'g', 'b', lies in the interval [0,255].
+
+ 'pen cmyk(real c, real m, real y, real k);'
+ This produces a CMYK color, where each of the cyan, magenta,
+ yellow, and black intensities 'c', 'm', 'y', 'k', lies in the
+ interval [0,1].
+
+ 'pen invisible;'
+ This special pen writes in invisible ink, but adjusts the
+ bounding box as if something had been drawn (like the
+ '\phantom' command in TeX). The function 'bool
+ invisible(pen)' can be used to test whether a pen is
+ invisible.
+
+ The default color is 'black'; this may be changed with the routine
+ 'defaultpen(pen)'. The function 'colorspace(pen p)' returns the
+ colorspace of pen 'p' as a string ('"gray"', '"rgb"', '"cmyk"', or
+ '""').
+
+ The function 'real[] colors(pen)' returns the color components of a
+ pen. The functions 'pen gray(pen)', 'pen rgb(pen)', and 'pen
+ cmyk(pen)' return new pens obtained by converting their arguments
+ to the respective color spaces. The function
+ 'colorless(pen=currentpen)' returns a copy of its argument with the
+ color attributes stripped (to avoid color mixing).
+
+ A 6-character RGB hexadecimal string can be converted to a pen with
+ the routine
+ pen rgb(string s);
+ A pen can be converted to a hexadecimal string with
+ * string hex(pen p);
+
+ Various shades and mixtures of the grayscale primary colors 'black'
+ and 'white', RGB primary colors 'red', 'green', and 'blue', and RGB
+ secondary colors 'cyan', 'magenta', and 'yellow' are defined as
+ named colors, along with the CMYK primary colors 'Cyan', 'Magenta',
+ 'Yellow', and 'Black', in the module 'plain':
+
+ [colors]
+
+ The standard 140 RGB 'X11' colors can be imported with the command
+ import x11colors;
+ and the standard 68 CMYK TeX colors can be imported with the
+ command
+ import texcolors;
+ Note that there is some overlap between these two standards and the
+ definitions of some colors (e.g. 'Green') actually disagree.
+
+ 'Asymptote' also comes with a 'asycolors.sty' 'LaTeX' package that
+ defines to 'LaTeX' CMYK versions of 'Asymptote''s predefined
+ colors, so that they can be used directly within 'LaTeX' strings.
+ Normally, such colors are passed to 'LaTeX' via a pen argument;
+ however, to change the color of only a portion of a string, say for
+ a slide presentation, (*note slide::) it may be desirable to
+ specify the color directly to 'LaTeX'. This file can be passed to
+ 'LaTeX' with the 'Asymptote' command
+ usepackage("asycolors");
+
+ The structure 'hsv' defined in 'plain_pens.asy' may be used to
+ convert between HSV and RGB spaces, where the hue 'h' is an angle
+ in [0,360) and the saturation 's' and value 'v' lie in '[0,1]':
+ pen p=hsv(180,0.5,0.75);
+ write(p); // ([default], red=0.375, green=0.75, blue=0.75)
+ hsv q=p;
+ write(q.h,q.s,q.v); // 180 0.5 0.75
+
+ * Line types are specified with the function 'pen linetype(real[] a,
+ real offset=0, bool scale=true, bool adjust=true)', where 'a' is an
+ array of real array numbers. The optional parameter 'offset'
+ specifies where in the pattern to begin. The first number
+ specifies how far (if 'scale' is 'true', in units of the pen line
+ width; otherwise in 'PostScript' units) to draw with the pen on,
+ the second number specifies how far to draw with the pen off, and
+ so on. If 'adjust' is 'true', these spacings are automatically
+ adjusted by 'Asymptote' to fit the arclength of the path. Here are
+ the predefined line types:
+ pen solid=linetype(new real[]);
+ pen dotted=linetype(new real[] {0,4});
+ pen dashed=linetype(new real[] {8,8});
+ pen longdashed=linetype(new real[] {24,8});
+ pen dashdotted=linetype(new real[] {8,8,0,8});
+ pen longdashdotted=linetype(new real[] {24,8,0,8});
+ pen Dotted(pen p=currentpen) {return linetype(new real[] {0,3})+2*linewidth(p);}
+ pen Dotted=Dotted();
+
+ [linetype]
+
+ The default line type is 'solid'; this may be changed with
+ 'defaultpen(pen)'. The line type of a pen can be determined with
+ the functions 'real[] linetype(pen p=currentpen)', 'real offset(pen
+ p)', 'bool scale(pen p)', and 'bool adjust(pen p)'.
+
+ * The pen line width is specified in 'PostScript' units with 'pen
+ linewidth(real)'. The default line width is 0.5 bp; this value may
+ be changed with 'defaultpen(pen)'. The line width of a pen is
+ returned by 'real linewidth(pen p=currentpen)'. For convenience,
+ in the module 'plain_pens' we define
+ void defaultpen(real w) {defaultpen(linewidth(w));}
+ pen operator +(pen p, real w) {return p+linewidth(w);}
+ pen operator +(real w, pen p) {return linewidth(w)+p;}
+ so that one may set the line width like this:
+ defaultpen(2);
+ pen p=red+0.5;
+
+ * A pen with a specific 'PostScript' line cap is returned on calling
+ 'linecap' with an integer argument:
+ pen squarecap=linecap(0);
+ pen roundcap=linecap(1);
+ pen extendcap=linecap(2);
+
+ The default line cap, 'roundcap', may be changed with
+ 'defaultpen(pen)'. The line cap of a pen is returned by 'int
+ linecap(pen p=currentpen)'.
+
+ * A pen with a specific 'PostScript' join style is returned on
+ calling 'linejoin' with an integer argument:
+ pen miterjoin=linejoin(0);
+ pen roundjoin=linejoin(1);
+ pen beveljoin=linejoin(2);
+
+ The default join style, 'roundjoin', may be changed with
+ 'defaultpen(pen)'.The join style of a pen is returned by 'int
+ linejoin(pen p=currentpen)'.
+
+ * A pen with a specific 'PostScript' miter limit is returned by
+ calling 'miterlimit(real)'. The default miterlimit, '10.0', may be
+ changed with 'defaultpen(pen)'. The miter limit of a pen is
+ returned by 'real miterlimit(pen p=currentpen)'.
+
+ * A pen with a specific 'PostScript' fill rule is returned on calling
+ 'fillrule' with an integer argument:
+ pen zerowinding=fillrule(0);
+ pen evenodd=fillrule(1);
+
+ The fill rule, which identifies the algorithm used to determine the
+ insideness of a path or array of paths, only affects the 'clip',
+ 'fill', and 'inside' functions. For the 'zerowinding' fill rule, a
+ point 'z' is outside the region bounded by a path if the number of
+ upward intersections of the path with the horizontal line
+ 'z--z+infinity' minus the number of downward intersections is zero.
+ For the 'evenodd' fill rule, 'z' is considered to be outside the
+ region if the total number of such intersections is even. The
+ default fill rule, 'zerowinding', may be changed with
+ 'defaultpen(pen)'. The fill rule of a pen is returned by 'int
+ fillrule(pen p=currentpen)'.
+
+ * A pen with a specific text alignment setting is returned on calling
+ 'basealign' with an integer argument:
+ pen nobasealign=basealign(0);
+ pen basealign=basealign(1);
+
+ The default setting, 'nobasealign',which may be changed with
+ 'defaultpen(pen)', causes the label alignment routines to use the
+ full label bounding box for alignment. In contrast, 'basealign'
+ requests that the TeX baseline be respected. The base align
+ setting of a pen is returned by 'int basealigin(pen p=currentpen)'.
+
+ * The font size is specified in TeX points (1 pt = 1/72.27 inches)
+ with the function 'pen fontsize(real size, real
+ lineskip=1.2*size)'. The default font size, 12pt, may be changed
+ with 'defaultpen(pen)'. Nonstandard font sizes may require
+ inserting
+ import fontsize;
+ at the beginning of the file (this requires the 'type1cm' package
+ available from
+ <http://mirror.ctan.org/macros/latex/contrib/type1cm/>
+ and included in recent 'LaTeX' distributions). The font size and
+ line skip of a pen can be examined with the routines 'real
+ fontsize(pen p=currentpen)' and 'real lineskip(pen p=currentpen)',
+ respectively.
+
+ * A pen using a specific 'LaTeX' 'NFSS' font is returned by calling
+ the function 'pen font(string encoding, string family, string
+ series, string shape)'. The default setting,
+ 'font("OT1","cmr","m","n")', corresponds to 12pt Computer Modern
+ Roman; this may be changed with 'defaultpen(pen)'. The font
+ setting of a pen is returned by 'string font(pen p=currentpen)'.
+ Support for standardized international characters is provided by
+ the 'unicode' package (*note unicode::).
+
+ Alternatively, one may select a fixed-size TeX font (on which
+ 'fontsize' has no effect) like '"cmr12"' (12pt Computer Modern
+ Roman) or '"pcrr"' (Courier) using the function 'pen font(string
+ name)'. An optional size argument can also be given to scale the
+ font to the requested size: 'pen font(string name, real size)'.
+
+ A nonstandard font command can be generated with 'pen
+ fontcommand(string)'.
+
+ A convenient interface to the following standard 'PostScript' fonts
+ is also provided:
+ pen AvantGarde(string series="m", string shape="n");
+ pen Bookman(string series="m", string shape="n");
+ pen Courier(string series="m", string shape="n");
+ pen Helvetica(string series="m", string shape="n");
+ pen NewCenturySchoolBook(string series="m", string shape="n");
+ pen Palatino(string series="m", string shape="n");
+ pen TimesRoman(string series="m", string shape="n");
+ pen ZapfChancery(string series="m", string shape="n");
+ pen Symbol(string series="m", string shape="n");
+ pen ZapfDingbats(string series="m", string shape="n");
+
+ * The transparency of a pen can be changed with the command:
+ pen opacity(real opacity=1, string blend="Compatible");
+ The opacity can be varied from '0' (fully transparent) to the
+ default value of '1' (opaque), and 'blend' specifies one of the
+ following foreground-background blending operations:
+ "Compatible","Normal","Multiply","Screen","Overlay","SoftLight",
+ "HardLight","ColorDodge","ColorBurn","Darken","Lighten","Difference",
+ "Exclusion","Hue","Saturation","Color","Luminosity",
+ as described in
+
+ <http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf>.
+ Since 'PostScript' does not support transparency, this feature is
+ only effective with the '-f pdf' output format option; other
+ formats can be produced from the resulting PDF file with the
+ 'ImageMagick' 'convert' program. Labels are always drawn with an
+ 'opacity' of 1. A simple example of transparent filling is
+ provided in the example file 'transparency.asy'.
+
+ * 'PostScript' commands within a 'picture' may be used to create a
+ tiling pattern, identified by the string 'name', for 'fill' and
+ 'draw' operations by adding it to the global 'PostScript' frame
+ 'currentpatterns', with optional left-bottom margin 'lb' and
+ right-top margin 'rt'.
+ import patterns;
+ void add(string name, picture pic, pair lb=0, pair rt=0);
+
+ To 'fill' or 'draw' using pattern 'name', use the pen
+ 'pattern("name")'. For example, rectangular tilings can be
+ constructed using the routines 'picture tile(real Hx=5mm, real
+ Hy=0, pen p=currentpen, filltype filltype=NoFill)', 'picture
+ checker(real Hx=5mm, real Hy=0, pen p=currentpen)', and 'picture
+ brick(real Hx=5mm, real Hy=0, pen p=currentpen)' defined in
+ 'patterns.asy':
+ size(0,90);
+ import patterns;
+
+ add("tile",tile());
+ add("filledtilewithmargin",tile(6mm,4mm,red,Fill),(1mm,1mm),(1mm,1mm));
+ add("checker",checker());
+ add("brick",brick());
+
+ real s=2.5;
+ filldraw(unitcircle,pattern("tile"));
+ filldraw(shift(s,0)*unitcircle,pattern("filledtilewithmargin"));
+ filldraw(shift(2s,0)*unitcircle,pattern("checker"));
+ filldraw(shift(3s,0)*unitcircle,pattern("brick"));
+
+ [tile]
+
+ Hatch patterns can be generated with the routines 'picture
+ hatch(real H=5mm, pair dir=NE, pen p=currentpen)', 'picture
+ crosshatch(real H=5mm, pen p=currentpen)':
+ size(0,100);
+ import patterns;
+
+ add("hatch",hatch());
+ add("hatchback",hatch(NW));
+ add("crosshatch",crosshatch(3mm));
+
+ real s=1.25;
+ filldraw(unitsquare,pattern("hatch"));
+ filldraw(shift(s,0)*unitsquare,pattern("hatchback"));
+ filldraw(shift(2s,0)*unitsquare,pattern("crosshatch"));
+
+ [hatch]
+
+ You may need to turn off aliasing in your 'PostScript' viewer for
+ patterns to appear correctly. Custom patterns can easily be
+ constructed, following the examples in 'patterns.asy'. The tiled
+ pattern can even incorporate shading (*note gradient shading::), as
+ illustrated in this example (not included in the manual because not
+ all printers support 'PostScript' 3):
+ size(0,100);
+ import patterns;
+
+ real d=4mm;
+ picture tiling;
+ path square=scale(d)*unitsquare;
+ axialshade(tiling,square,white,(0,0),black,(d,d));
+ fill(tiling,shift(d,d)*square,blue);
+ add("shadedtiling",tiling);
+
+ filldraw(unitcircle,pattern("shadedtiling"));
+
+
+ * One can specify a custom pen nib as an arbitrary polygonal path
+ with 'pen makepen(path)'; this path represents the mark to be drawn
+ for paths containing a single point. This pen nib path can be
+ recovered from a pen with 'path nib(pen)'. Unlike in 'MetaPost',
+ the path need not be convex:
+
+ size(200);
+ pen convex=makepen(scale(10)*polygon(8))+grey;
+ draw((1,0.4),convex);
+ draw((0,0)---(1,1)..(2,0)--cycle,convex);
+
+ pen nonconvex=scale(10)*
+ makepen((0,0)--(0.25,-1)--(0.5,0.25)--(1,0)--(0.5,1.25)--cycle)+red;
+ draw((0.5,-1.5),nonconvex);
+ draw((0,-1.5)..(1,-0.5)..(2,-1.5),nonconvex);
+
+ [makepen]
+
+ The value 'nullpath' represents a circular pen nib (the default);
+ an elliptical pen can be achieved simply by multiplying the pen by
+ a transform: 'yscale(2)*currentpen'.
+
+ * One can prevent labels from overwriting one another by using the
+ pen attribute 'overwrite', which takes a single argument:
+
+ 'Allow'
+ Allow labels to overwrite one another. This is the default
+ behaviour (unless overridden with 'defaultpen(pen)'.
+
+ 'Suppress'
+ Suppress, with a warning, each label that would overwrite
+ another label.
+
+ 'SuppressQuiet'
+ Suppress, without warning, each label that would overwrite
+ another label.
+
+ 'Move'
+ Move a label that would overwrite another out of the way and
+ issue a warning. As this adjustment is during the final
+ output phase (in 'PostScript' coordinates) it could result in
+ a larger figure than requested.
+
+ 'MoveQuiet'
+ Move a label that would overwrite another out of the way,
+ without warning. As this adjustment is during the final
+ output phase (in 'PostScript' coordinates) it could result in
+ a larger figure than requested.
+
+ The routine 'defaultpen()' returns the current default pen
+attributes. Calling the routine 'resetdefaultpen()' resets all pen
+default attributes to their initial values.
+
+
+File: asymptote.info, Node: Transforms, Next: Frames and pictures, Prev: Pens, Up: Programming
+
+6.4 Transforms
+==============
+
+'Asymptote' makes extensive use of affine transforms. A pair '(x,y)' is
+transformed by the transform 't=(t.x,t.y,t.xx,t.xy,t.yx,t.yy)' to
+'(x',y')', where
+x' = t.x + t.xx * x + t.xy * y
+y' = t.y + t.yx * x + t.yy * y
+This is equivalent to the 'PostScript' transformation '[t.xx t.yx t.xy
+t.yy t.x t.y]'.
+
+ Transforms can be applied to pairs, guides, paths, pens, strings,
+transforms, frames, and pictures by multiplication (via the binary
+operator '*') on the left (*note circle:: for an example). Transforms
+can be composed with one another and inverted with the function
+'transform inverse(transform t)'; they can also be raised to any integer
+power with the '^' operator.
+
+ The built-in transforms are:
+
+'transform identity;'
+ the identity transform;
+'transform shift(pair z);'
+ translates by the pair 'z';
+'transform shift(real x, real y);'
+ translates by the pair '(x,y)';
+'transform xscale(real x);'
+ scales by 'x' in the x direction;
+'transform yscale(real y);'
+ scales by 'y' in the y direction;
+'transform scale(real s);'
+ scale by 's' in both x and y directions;
+'transform scale(real x, real y);'
+ scale by 'x' in the x direction and by 'y' in the y direction;
+'transform slant(real s);'
+ maps '(x,y)' -> '(x+s*y,y)';
+'transform rotate(real angle, pair z=(0,0));'
+ rotates by 'angle' in degrees about 'z';
+'transform reflect(pair a, pair b);'
+ reflects about the line 'a--b'.
+'transform zeroTransform;'
+ the zero transform;
+
+ The implicit initializer for transforms is 'identity()'. The
+routines 'shift(transform t)' and 'shiftless(transform t)' return the
+transforms '(t.x,t.y,0,0,0,0)' and '(0,0,t.xx,t.xy,t.yx,t.yy)'
+respectively.
+
+
+File: asymptote.info, Node: Frames and pictures, Next: Files, Prev: Transforms, Up: Programming
+
+6.5 Frames and pictures
+=======================
+
+'frame'
+ Frames are canvases for drawing in 'PostScript' coordinates. While
+ working with frames directly is occasionally necessary for
+ constructing deferred drawing routines, pictures are usually more
+ convenient to work with. The implicit initializer for frames is
+ 'newframe'. The function 'bool empty(frame f)' returns 'true' only
+ if the frame 'f' is empty. A frame may be erased with the
+ 'erase(frame)' routine. The functions 'pair min(frame)' and 'pair
+ max(frame)' return the (left,bottom) and (right,top) coordinates of
+ the frame bounding box, respectively. The contents of frame 'src'
+ may be appended to frame 'dest' with the command
+ void add(frame dest, frame src);
+ or prepended with
+ void prepend(frame dest, frame src);
+ A frame obtained by aligning frame 'f' in the direction 'align', in
+ a manner analogous to the 'align' argument of 'label' (*note
+ label::), is returned by
+ frame align(frame f, pair align);
+
+ To draw or fill a box or ellipse around a label or frame and return
+ the boundary as a path, use one of the predefined 'envelope'
+ routines
+ path box(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+ path roundbox(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+ path ellipse(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+
+'picture'
+ Pictures are high-level structures (*note Structures::) defined in
+ the module 'plain' that provide canvases for drawing in user
+ coordinates. The default picture is called 'currentpicture'. A
+ new picture can be created like this:
+ picture pic;
+ Anonymous pictures can be made by the expression 'new picture'.
+
+ The 'size' routine specifies the dimensions of the desired picture:
+
+ void size(picture pic=currentpicture, real x, real y=x,
+ bool keepAspect=Aspect);
+
+ If the 'x' and 'y' sizes are both 0, user coordinates will be
+ interpreted as 'PostScript' coordinates. In this case, the
+ transform mapping 'pic' to the final output frame is 'identity()'.
+
+ If exactly one of 'x' or 'y' is 0, no size restriction is imposed
+ in that direction; it will be scaled the same as the other
+ direction.
+
+ If 'keepAspect' is set to 'Aspect' or 'true', the picture will be
+ scaled with its aspect ratio preserved such that the final width is
+ no more than 'x' and the final height is no more than 'y'.
+
+ If 'keepAspect' is set to 'IgnoreAspect' or 'false', the picture
+ will be scaled in both directions so that the final width is 'x'
+ and the height is 'y'.
+
+ To make the user coordinates of picture 'pic' represent multiples
+ of 'x' units in the x direction and 'y' units in the y direction,
+ use
+ void unitsize(picture pic=currentpicture, real x, real y=x);
+ When nonzero, these 'x' and 'y' values override the corresponding
+ size parameters of picture 'pic'.
+
+ The routine
+ void size(picture pic=currentpicture, real xsize, real ysize,
+ pair min, pair max);
+ forces the final picture scaling to map the user coordinates
+ 'box(min,max)' to a region of width 'xsize' and height 'ysize'
+ (when these parameters are nonzero).
+
+ Alternatively, calling the routine
+ transform fixedscaling(picture pic=currentpicture, pair min,
+ pair max, pen p=nullpen, bool warn=false);
+ will cause picture 'pic' to use a fixed scaling to map user
+ coordinates in 'box(min,max)' to the (already specified) picture
+ size, taking account of the width of pen 'p'. A warning will be
+ issued if the final picture exceeds the specified size.
+
+ A picture 'pic' can be fit to a frame and output to a file
+ 'prefix'.'format' using image format 'format' by calling the
+ 'shipout' function:
+ void shipout(string prefix=defaultfilename, picture pic=currentpicture,
+ orientation orientation=orientation,
+ string format="", bool wait=false, bool view=true,
+ string options="", string script="",
+ light light=currentlight, projection P=currentprojection)
+ The default output format, 'PostScript', may be changed with the
+ '-f' or '-tex' command-line options. The 'options', 'script', and
+ 'projection' parameters are only relevant for 3D pictures. If
+ 'defaultfilename' is an empty string, the prefix 'outprefix()' will
+ be used.
+
+ A 'shipout()' command is added implicitly at file exit if no
+ previous 'shipout' commands have been executed. The default page
+ orientation is 'Portrait'; this may be modified by changing the
+ variable 'orientation'. To output in landscape mode, simply set
+ the variable 'orientation=Landscape' or issue the command
+ shipout(Landscape);
+
+ To rotate the page by -90 degrees, use the orientation 'Seascape'.
+ The orientation 'UpsideDown' rotates the page by 180 degrees.
+
+ A picture 'pic' can be explicitly fit to a frame by calling
+ frame pic.fit(real xsize=pic.xsize, real ysize=pic.ysize,
+ bool keepAspect=pic.keepAspect);
+ The default size and aspect ratio settings are those given to the
+ 'size' command (which default to '0', '0', and 'true',
+ respectively). The transformation that would currently be used to
+ fit a picture 'pic' to a frame is returned by the member function
+ 'pic.calculateTransform()'.
+
+ In certain cases (e.g. 2D graphs) where only an approximate size
+ estimate for 'pic' is available, the picture fitting routine
+ frame pic.scale(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect);
+ (which scales the resulting frame, including labels and fixed-size
+ objects) will enforce perfect compliance with the requested size
+ specification, but should not normally be required.
+
+ To draw a bounding box with margins around a picture, fit the
+ picture to a frame using the function
+ frame bbox(picture pic=currentpicture, real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill);
+ Here 'filltype' specifies one of the following fill types:
+ 'FillDraw'
+ Fill the interior and draw the boundary.
+
+ 'FillDraw(real xmargin=0, real ymargin=xmargin, pen fillpen=nullpen,'
+ 'pen drawpen=nullpen)' If 'fillpen' is 'nullpen', fill with
+ the drawing pen; otherwise fill with pen 'fillpen'. If
+ 'drawpen' is 'nullpen', draw the boundary with 'fillpen';
+ otherwise with 'drawpen'. An optional margin of 'xmargin' and
+ 'ymargin' can be specified.
+
+ 'Fill'
+ Fill the interior.
+
+ 'Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)'
+ If 'p' is 'nullpen', fill with the drawing pen; otherwise fill
+ with pen 'p'. An optional margin of 'xmargin' and 'ymargin'
+ can be specified.
+
+ 'NoFill'
+ Do not fill.
+
+ 'Draw'
+ Draw only the boundary.
+
+ 'Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)'
+ If 'p' is 'nullpen', draw the boundary with the drawing pen;
+ otherwise draw with pen 'p'. An optional margin of 'xmargin'
+ and 'ymargin' can be specified.
+
+ 'UnFill'
+ Clip the region.
+
+ 'UnFill(real xmargin=0, real ymargin=xmargin)'
+ Clip the region and surrounding margins 'xmargin' and
+ 'ymargin'.
+
+ 'RadialShade(pen penc, pen penr)'
+ Fill varying radially from 'penc' at the center of the
+ bounding box to 'penr' at the edge.
+
+ 'RadialShadeDraw(real xmargin=0, real ymargin=xmargin, pen penc,'
+ 'pen penr, pen drawpen=nullpen)' Fill with RadialShade and
+ draw the boundary.
+
+ For example, to draw a bounding box around a picture with a 0.25 cm
+ margin and output the resulting frame, use the command:
+ shipout(bbox(0.25cm));
+ A 'picture' may be fit to a frame with the background color pen
+ 'p', using the function 'bbox(p,Fill)'.
+
+ The functions
+ pair min(picture pic, user=false);
+ pair max(picture pic, user=false);
+ pair size(picture pic, user=false);
+ calculate the bounds that picture 'pic' would have if it were
+ currently fit to a frame using its default size specification. If
+ 'user' is 'false' the returned value is in 'PostScript'
+ coordinates, otherwise it is in user coordinates.
+
+ The function
+ pair point(picture pic=currentpicture, pair dir, bool user=true);
+ is a convenient way of determining the point on the bounding box of
+ 'pic' in the direction 'dir' relative to its center, ignoring the
+ contributions from fixed-size objects (such as labels and
+ arrowheads). If 'user' is 'true' the returned value is in user
+ coordinates, otherwise it is in 'PostScript' coordinates.
+
+ The function
+ pair truepoint(picture pic=currentpicture, pair dir, bool user=true);
+ is identical to 'point', except that it also accounts for
+ fixed-size objects, using the scaling transform that picture 'pic'
+ would have if currently fit to a frame using its default size
+ specification. If 'user' is 'true' the returned value is in user
+ coordinates, otherwise it is in 'PostScript' coordinates.
+
+ Sometimes it is useful to draw objects on separate pictures and add
+ one picture to another using the 'add' function:
+ void add(picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ void add(picture dest, picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ The first example adds 'src' to 'currentpicture'; the second one
+ adds 'src' to 'dest'. The 'group' option specifies whether or not
+ the graphical user interface
+ '<http://asymptote.sourceforge.net/gallery/.pdf>.asy' should treat
+ all of the elements of 'src' as a single entity (*note GUI::),
+ 'filltype' requests optional background filling or clipping, and
+ 'above' specifies whether to add 'src' above or below existing
+ objects.
+
+ There are also routines to add a picture or frame 'src' specified
+ in postscript coordinates to another picture 'dest' (or
+ 'currentpicture') about the user coordinate 'position':
+ void add(picture src, pair position, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ void add(picture dest, picture src, pair position,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+ void add(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+ void add(picture dest=currentpicture, frame src, pair position,
+ pair align, bool group=true, filltype filltype=NoFill,
+ bool above=true);
+
+ The optional 'align' argument in the last form specifies a
+ direction to use for aligning the frame, in a manner analogous to
+ the 'align' argument of 'label' (*note label::). However, one key
+ difference is that when 'align' is not specified, labels are
+ centered, whereas frames and pictures are aligned so that their
+ origin is at 'position'. Illustrations of frame alignment can be
+ found in the examples *note errorbars:: and *note image::. If you
+ want to align three or more subpictures, group them two at a time:
+
+ picture pic1;
+ real size=50;
+ size(pic1,size);
+ fill(pic1,(0,0)--(50,100)--(100,0)--cycle,red);
+
+ picture pic2;
+ size(pic2,size);
+ fill(pic2,unitcircle,green);
+
+ picture pic3;
+ size(pic3,size);
+ fill(pic3,unitsquare,blue);
+
+ picture pic;
+ add(pic,pic1.fit(),(0,0),N);
+ add(pic,pic2.fit(),(0,0),10S);
+
+ add(pic.fit(),(0,0),N);
+ add(pic3.fit(),(0,0),10S);
+
+
+ [subpictures]
+
+ Alternatively, one can use 'attach' to automatically increase the
+ size of picture 'dest' to accommodate adding a frame 'src' about
+ the user coordinate 'position':
+ void attach(picture dest=currentpicture, frame src,
+ pair position=0, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ void attach(picture dest=currentpicture, frame src,
+ pair position, pair align, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+
+ To erase the contents of a picture (but not the size
+ specification), use the function
+ void erase(picture pic=currentpicture);
+
+ To save a snapshot of 'currentpicture', 'currentpen', and
+ 'currentprojection', use the function 'save()'.
+
+ To restore a snapshot of 'currentpicture', 'currentpen', and
+ 'currentprojection', use the function 'restore()'.
+
+ Many further examples of picture and frame operations are provided
+ in the base module 'plain'.
+
+ It is possible to insert verbatim 'PostScript' commands in a
+ picture with one of the routines
+ void postscript(picture pic=currentpicture, string s);
+ void postscript(picture pic=currentpicture, string s, pair min,
+ pair max)
+ Here 'min' and 'max' can be used to specify explicit bounds
+ associated with the resulting 'PostScript' code.
+
+ Verbatim TeX commands can be inserted in the intermediate 'LaTeX'
+ output file with one of the functions
+ void tex(picture pic=currentpicture, string s);
+ void tex(picture pic=currentpicture, string s, pair min, pair max)
+ Here 'min' and 'max' can be used to specify explicit bounds
+ associated with the resulting TeX code.
+
+ To issue a global TeX command (such as a TeX macro definition) in
+ the TeX preamble (valid for the remainder of the top-level module)
+ use:
+ void texpreamble(string s);
+
+ The TeX environment can be reset to its initial state, clearing all
+ macro definitions, with the function
+ void texreset();
+
+ The routine
+ void usepackage(string s, string options="");
+ provides a convenient abbreviation for
+ texpreamble("\usepackage["+options+"]{"+s+"}");
+ that can be used for importing 'LaTeX' packages.
+
+
+File: asymptote.info, Node: Files, Next: Variable initializers, Prev: Frames and pictures, Up: Programming
+
+6.6 Files
+=========
+
+'Asymptote' can read and write text files (including comma-separated
+value) files and portable XDR (External Data Representation) binary
+files.
+
+ An input file must first be opened with
+input(string name="", bool check=true, string comment="#", string mode="");
+ reading is then done by assignment:
+file fin=input("test.txt");
+real a=fin;
+
+ If the optional boolean argument 'check' is 'false', no check will be
+made that the file exists. If the file does not exist or is not
+readable, the function 'bool error(file)' will return 'true'. The first
+character of the string 'comment' specifies a comment character. If
+this character is encountered in a data file, the remainder of the line
+is ignored. When reading strings, a comment character followed
+immediately by another comment character is treated as a single literal
+comment character.
+
+ One can change the current working directory for read operations to
+the contents of the string 's' with the function 'string cd(string s)',
+which returns the new working directory. If 'string s' is empty, the
+path is reset to the value it had at program startup.
+
+ When reading pairs, the enclosing parenthesis are optional. Strings
+are also read by assignment, by reading characters up to but not
+including a newline. In addition, 'Asymptote' provides the function
+'string getc(file)' to read the next character (treating the comment
+character as an ordinary character) and return it as a string.
+
+ A file named 'name' can be open for output with
+file output(string name="", bool update=false, string comment="#", string mode="");
+If 'update=false', any existing data in the file will be erased and only
+write operations can be used on the file. If 'update=true', any
+existing data will be preserved, the position will be set to the
+end-of-file, and both reading and writing operations will be enabled.
+For security reasons, writing to files in directories other than the
+current directory is allowed only if the '-globalwrite' (or '-nosafe')
+command-line option is specified. The function 'string mktemp(string
+s)' may be used to create and return the name of a unique temporary file
+in the current directory based on the string 's'.
+
+ There are two special files: 'stdin', which reads from the keyboard,
+and 'stdout', which writes to the terminal. The implicit initializer
+for files is 'null'.
+
+ Data of a built-in type 'T' can be written to an output file by
+calling one of the functions
+write(string s="", T x, suffix suffix=endl ... T[]);
+write(file file, string s="", T x, suffix suffix=none ... T[]);
+write(file file=stdout, string s="", explicit T[] x ... T[][]);
+write(file file=stdout, T[][]);
+write(file file=stdout, T[][][]);
+write(suffix suffix=endl);
+write(file file, suffix suffix=none);
+ If 'file' is not specified, 'stdout' is used and terminated by
+default with a newline. If specified, the optional identifying string
+'s' is written before the data 'x'. An arbitrary number of data values
+may be listed when writing scalars or one-dimensional arrays. The
+'suffix' may be one of the following: 'none' (do nothing), 'flush'
+(output buffered data), 'endl' (terminate with a newline and flush),
+'newl' (terminate with a newline), 'DOSendl' (terminate with a DOS
+newline and flush), 'DOSnewl' (terminate with a DOS newline), 'tab'
+(terminate with a tab), or 'comma' (terminate with a comma). Here are
+some simple examples of data output:
+file fout=output("test.txt");
+write(fout,1); // Writes "1"
+write(fout); // Writes a new line
+write(fout,"List: ",1,2,3); // Writes "List: 1 2 3"
+
+ A file may be opened with 'mode="xdr"', to read or write double
+precision (64-bit) reals and single precision (32-bit) integers in Sun
+Microsystem's XDR (External Data Representation) portable binary format
+(available on all 'UNIX' platforms). Alternatively, a file may also be
+opened with 'mode="binary"' to read or write double precision reals and
+single precision integers in the native (nonportable) machine binary
+format. The virtual member functions 'file singlereal(bool b=true)' and
+'file singleint(bool b=true)' be used to change the precision of real
+and integer I/O operations, respectively, for an XDR or binary file 'f'.
+Similarly, the function 'file signedint(bool b=true)' can be used to
+modify the signedness of integer reads and writes for an XDR or binary
+file 'f'.
+
+ The virtual members 'name', 'mode', 'singlereal', 'singleint', and
+'signedint' may be used to query the respective parameters for a given
+file.
+
+ One can test a file for end-of-file with the boolean function
+'eof(file)', end-of-line with 'eol(file)', and for I/O errors with
+'error(file)'. One can flush the output buffers with 'flush(file)',
+clear a previous I/O error with 'clear(file)', and close the file with
+'close(file)'. The function 'int precision(file file=stdout, int
+digits=0)' sets the number of digits of output precision for 'file' to
+'digits', provided 'digits' is nonzero, and returns the previous
+precision setting. The function 'int tell(file)' returns the current
+position in a file relative to the beginning. The routine 'seek(file
+file, int pos)' can be used to change this position, where a negative
+value for the position 'pos' is interpreted as relative to the
+end-of-file. For example, one can rewind a file 'file' with the command
+'seek(file,0)' and position to the final character in the file with
+'seek(file,-1)'. The command 'seekeof(file)' sets the position to the
+end of the file.
+
+ Assigning 'settings.scroll=n' for a positive integer 'n' requests a
+pause after every 'n' output lines to 'stdout'. One may then press
+'Enter' to continue to the next 'n' output lines, 's' followed by
+'Enter' to scroll without further interruption, or 'q' followed by
+'Enter' to quit the current output operation. If 'n' is negative, the
+output scrolls a page at a time (i.e. by one less than the current
+number of display lines). The default value, 'settings.scroll=0',
+specifies continuous scrolling.
+
+ The routines
+string getstring(string name="", string default="", string prompt="",
+ bool store=true);
+int getint(string name="", int default=0, string prompt="",
+ bool store=true);
+real getreal(string name="", real default=0, string prompt="",
+ bool store=true);
+pair getpair(string name="", pair default=0, string prompt="",
+ bool store=true);
+triple gettriple(string name="", triple default=(0,0,0), string prompt="",
+ bool store=true);
+defined in the module 'plain' may be used to prompt for a value from
+'stdin' using the GNU 'readline' library. If 'store=true', the history
+of values for 'name' is stored in the file '".asy_history_"+name' (*note
+history::). The most recent value in the history will be used to
+provide a default value for subsequent runs. The default value
+(initially 'default') is displayed after 'prompt'. These functions are
+based on the internal routines
+string readline(string prompt="", string name="", bool tabcompletion=false);
+void saveline(string name, string value, bool store=true);
+ Here, 'readline' prompts the user with the default value formatted
+according to 'prompt', while 'saveline' is used to save the string
+'value' in a local history named 'name', optionally storing the local
+history in a file '".asy_history_"+name'.
+
+ The routine 'history(string name, int n=1)' can be used to look up
+the 'n' most recent values (or all values up to 'historylines' if 'n=0')
+entered for string 'name'. The routine 'history(int n=0)' returns the
+interactive history. For example,
+write(output("transcript.asy"),history());
+outputs the interactive history to the file 'transcript.asy'.
+
+ The function 'int delete(string s)' deletes the file named by the
+string 's'. Unless the '-globalwrite' (or '-nosafe') option is enabled,
+the file must reside in the current directory. The function 'int
+rename(string from, string to)' may be used to rename file 'from' to
+file 'to'. Unless the '-globalwrite' (or '-nosafe') option is enabled,
+this operation is restricted to the current directory. The functions
+int convert(string args="", string file="", string format="");
+int animate(string args="", string file="", string format="");
+call the 'ImageMagick' commands 'convert' and 'animate', respectively,
+with the arguments 'args' and the file name constructed from the strings
+'file' and 'format'.
+
+
+File: asymptote.info, Node: Variable initializers, Next: Structures, Prev: Files, Up: Programming
+
+6.7 Variable initializers
+=========================
+
+A variable can be assigned a value when it is declared, as in 'int x=3;'
+where the variable 'x' is assigned the value '3'. As well as literal
+constants such as '3', arbitary expressions can be used as initializers,
+as in 'real x=2*sin(pi/2);'.
+
+ A variable is not added to the namespace until after the initializer
+is evaluated, so for example, in
+int x=2;
+int x=5*x;
+the 'x' in the initializer on the second line refers to the variable 'x'
+declared on the first line. The second line, then, declares a variable
+'x' shadowing the original 'x' and initializes it to the value '10'.
+
+ Variables of most types can be declared without an explicit
+initializer and they will be initialized by the default initializer of
+that type:
+
+ * Variables of the numeric types 'int', 'real', and 'pair' are all
+ initialized to zero; variables of type 'triple' are initialized to
+ 'O=(0,0,0)'.
+ * 'boolean' variables are initialized to 'false'.
+ * 'string' variables are initialized to the empty string.
+ * 'transform' variables are initialized to the identity
+ transformation.
+ * 'path' and 'guide' variables are initialized to 'nullpath'.
+ * 'pen' variables are initialized to the default pen.
+ * 'frame' and 'picture' variables are initialized to empty frames and
+ pictures, respectively.
+ * 'file' variables are initialized to 'null'.
+
+ The default initializers for user-defined array, structure, and
+function types are explained in their respective sections. Some types,
+such as 'code', do not have default initializers. When a variable of
+such a type is introduced, the user must initialize it by explicitly
+giving it a value.
+
+ The default initializer for any type 'T' can be redeclared by
+defining the function 'T operator init()'. For instance, 'int'
+variables are usually initialized to zero, but in
+int operator init() {
+ return 3;
+}
+int y;
+
+the variable 'y' is initialized to '3'. This example was given for
+illustrative purposes; redeclaring the initializers of built-in types is
+not recommended. Typically, 'operator init' is used to define sensible
+defaults for user-defined types.
+
+ The special type 'var' may be used to infer the type of a variable
+from its initializer. If the initializer is an expression of a unique
+type, then the variable will be defined with that type. For instance,
+var x=5;
+var y=4.3;
+var reddash=red+dashed;
+is equivalent to
+int x=5;
+real y=4.3;
+pen reddash=red+dashed;
+
+ 'var' may also be used with the extended 'for' loop syntax.
+
+int[] a = {1,2,3};
+for (var x : a)
+ write(x);
+
+
+File: asymptote.info, Node: Structures, Next: Operators, Prev: Variable initializers, Up: Programming
+
+6.8 Structures
+==============
+
+Users may also define their own data types as structures, along with
+user-defined operators, much as in C++. By default, structure members
+are 'public' (may be read and modified anywhere in the code), but may be
+optionally declared 'restricted' (readable anywhere but writeable only
+inside the structure where they are defined) or 'private' (readable and
+writable only inside the structure). In a structure definition, the
+keyword 'this' can be used as an expression to refer to the enclosing
+structure. Any code at the top-level scope within the structure is
+executed on initialization.
+
+ Variables hold references to structures. That is, in the example:
+struct T {
+ int x;
+}
+
+T foo;
+T bar=foo;
+bar.x=5;
+
+ The variable 'foo' holds a reference to an instance of the structure
+'T'. When 'bar' is assigned the value of 'foo', it too now holds a
+reference to the same instance as 'foo' does. The assignment 'bar.x=5'
+changes the value of the field 'x' in that instance, so that 'foo.x'
+will also be equal to '5'.
+
+ The expression 'new T' creates a new instance of the structure 'T'
+and returns a reference to that instance. In creating the new instance,
+any code in the body of the record definition is executed. For example:
+int Tcount=0;
+struct T {
+ int x;
+ ++Tcount;
+}
+
+T foo=new T;
+T foo;
+Here, 'new T' produces a new instance of the class, which causes
+'Tcount' to be incremented, tracking the number of instances produced.
+The declarations 'T foo=new T' and 'T foo' are equivalent: the second
+form implicitly creates a new instance of 'T'. That is, after the
+definition of a structure 'T', a variable of type 'T' is initialized to
+a new instance ('new T') by default. During the definition of the
+structure, however, variables of type 'T' are initialized to 'null' by
+default. This special behaviour is to avoid infinite recursion of
+creating new instances in code such as
+struct tree {
+ int value;
+ tree left;
+ tree right;
+}
+
+ The expression 'null' can be cast to any structure type to yield a
+null reference, a reference that does not actually refer to any instance
+of the structure. Trying to use a field of a null reference will cause
+an error.
+
+ The function 'bool alias(T,T)' checks to see if two structure
+references refer to the same instance of the structure (or both to
+'null'). In example at the beginning of this section, 'alias(foo,bar)'
+would return true, but 'alias(foo,new T)' would return false, as 'new T'
+creates a new instance of the structure 'T'. The boolean operators '=='
+and '!=' are by default equivalent to 'alias' and '!alias' respectively,
+but may be overwritten for a particular type (for example, to do a deep
+comparison).
+
+ Here is a simple example that illustrates the use of structures:
+struct S {
+ real a=1;
+ real f(real a) {return a+this.a;}
+}
+
+S s; // Initializes s with new S;
+
+write(s.f(2)); // Outputs 3
+
+S operator + (S s1, S s2)
+{
+ S result;
+ result.a=s1.a+s2.a;
+ return result;
+}
+
+write((s+s).f(0)); // Outputs 2
+
+
+ It is often convenient to have functions that construct new instances
+of a structure. Say we have a 'Person' structure:
+struct Person {
+ string firstname;
+ string lastname;
+}
+
+Person joe;
+joe.firstname="Joe";
+joe.lastname="Jones";
+Creating a new Person is a chore; it takes three lines to create a new
+instance and to initialize its fields (that's still considerably less
+effort than creating a new person in real life, though).
+
+ We can reduce the work by defining a constructor function
+'Person(string,string)':
+struct Person {
+ string firstname;
+ string lastname;
+
+ static Person Person(string firstname, string lastname) {
+ Person p=new Person;
+ p.firstname=firstname;
+ p.lastname=lastname;
+ return p;
+ }
+}
+
+Person joe=Person.Person("Joe", "Jones");
+
+ While it is now easier than before to create a new instance, we still
+have to refer to the constructor by the qualified name 'Person.Person'.
+If we add the line
+from Person unravel Person;
+immediately after the structure definition, then the constructor can be
+used without qualification: 'Person joe=Person("Joe", "Jones");'.
+
+ The constructor is now easy to use, but it is quite a hassle to
+define. If you write a lot of constructors, you will find that you are
+repeating a lot of code in each of them. Fortunately, your friendly
+neighbourhood Asymptote developers have devised a way to automate much
+of the process.
+
+ If, in the body of a structure, Asymptote encounters the definition
+of a function of the form 'void operator init(ARGS)', it implicitly
+defines a constructor function of the arguments 'ARGS' that uses the
+'void operator init' function to initialize a new instance of the
+structure. That is, it essentially defines the following constructor
+(assuming the structure is called 'Foo'):
+
+ static Foo Foo(ARGS) {
+ Foo instance=new Foo;
+ instance.operator init(ARGS);
+ return instance;
+ }
+
+ This constructor is also implicitly copied to the enclosing scope
+after the end of the structure definition, so that it can used
+subsequently without qualifying it by the structure name. Our 'Person'
+example can thus be implemented as:
+struct Person {
+ string firstname;
+ string lastname;
+
+ void operator init(string firstname, string lastname) {
+ this.firstname=firstname;
+ this.lastname=lastname;
+ }
+}
+
+Person joe=Person("Joe", "Jones");
+
+ The use of 'operator init' to implicitly define constructors should
+not be confused with its use to define default values for variables
+(*note Variable initializers::). Indeed, in the first case, the return
+type of the 'operator init' must be 'void' while in the second, it must
+be the (non-'void') type of the variable.
+
+ The function 'cputime()' returns a structure 'cputime' with
+cumulative CPU times broken down into the fields 'parent.user',
+'parent.system', 'child.user', and 'child.system'. For convenience, the
+incremental fields 'change.user' and 'change.system' indicate the change
+in the corresponding total parent and child CPU times since the last
+call to 'cputime()'. The function
+void write(file file=stdout, string s="", cputime c,
+ string format=cputimeformat, suffix suffix=none);
+displays the incremental user cputime followed by "u", the incremental
+system cputime followed by "s", the total user cputime followed by "U",
+and the total system cputime followed by "S".
+
+ Much like in C++, casting (*note Casts::) provides for an elegant
+implementation of structure inheritance, including virtual functions:
+struct parent {
+ real x;
+ void operator init(int x) {this.x=x;}
+ void virtual(int) {write(0);}
+ void f() {virtual(1);}
+}
+
+void write(parent p) {write(p.x);}
+
+struct child {
+ parent parent;
+ real y=3;
+ void operator init(int x) {parent.operator init(x);}
+ void virtual(int x) {write(x);}
+ parent.virtual=virtual;
+ void f()=parent.f;
+}
+
+parent operator cast(child child) {return child.parent;}
+
+parent p=parent(1);
+child c=child(2);
+
+write(c); // Outputs 2;
+
+p.f(); // Outputs 0;
+c.f(); // Outputs 1;
+
+write(c.parent.x); // Outputs 2;
+write(c.y); // Outputs 3;
+
+ For further examples of structures, see 'Legend' and 'picture' in the
+'Asymptote' base module 'plain'.
+
+
+File: asymptote.info, Node: Operators, Next: Implicit scaling, Prev: Structures, Up: Programming
+
+6.9 Operators
+=============
+
+* Menu:
+
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+
+
+File: asymptote.info, Node: Arithmetic & logical, Next: Self & prefix operators, Prev: Operators, Up: Operators
+
+6.9.1 Arithmetic & logical operators
+------------------------------------
+
+'Asymptote' uses the standard binary arithmetic operators. However,
+when one integer is divided by another, both arguments are converted to
+real values before dividing and a real quotient is returned (since this
+is typically what is intended; otherwise one can use the function 'int
+quotient(int x, int y)', which returns greatest integer less than or
+equal to 'x/y'). In all other cases both operands are promoted to the
+same type, which will also be the type of the result:
+'+'
+ addition
+'-'
+ subtractiona
+'*'
+ multiplication
+'/'
+ division
+'#'
+ integer division; equivalent to 'quotient(x,y)'. Noting that the
+ 'Python3' community adopted our comment symbol ('//') for integer
+ division, we decided to reciprocate and use their comment symbol
+ for integer division in 'Asymptote'!
+'%'
+ modulo; the result always has the same sign as the divisor. In
+ particular, this makes 'q*(p # q)+p % q == p' for all integers 'p'
+ and nonzero integers 'q'.
+'^'
+ power; if the exponent (second argument) is an int, recursive
+ multiplication is used; otherwise, logarithms and exponentials are
+ used ('**' is a synonym for '^').
+
+ The usual boolean operators are also defined:
+'=='
+ equals
+'!='
+ not equals
+'<'
+ less than
+'<='
+ less than or equals
+'>='
+ greater than or equals
+'>'
+ greater than
+'&&'
+ and (with conditional evaluation of right-hand argument)
+'&'
+ and
+'||'
+ or (with conditional evaluation of right-hand argument)
+'|'
+ or
+'^'
+ xor
+'!'
+ not
+
+ 'Asymptote' also supports the C-like conditional syntax:
+bool positive=(pi > 0) ? true : false;
+
+ The function 'T interp(T a, T b, real t)' returns '(1-t)*a+t*b' for
+nonintegral built-in arithmetic types 'T'. If 'a' and 'b' are pens,
+they are first promoted to the same color space.
+
+ 'Asymptote' also defines bitwise functions 'int AND(int,int)', 'int
+OR(int,int)', 'int XOR(int,int)', 'int NOT(int)', 'int CLZ(int)' (count
+leading zeros), 'int CTZ(int)' (count trailing zeros), 'int
+popcount(int)' (count bits populated by ones), and 'int bitreverse(int
+a, int bits)' (reverse bits within a word of length bits).
+
+
+File: asymptote.info, Node: Self & prefix operators, Next: User-defined operators, Prev: Arithmetic & logical, Up: Operators
+
+6.9.2 Self & prefix operators
+-----------------------------
+
+As in C, each of the arithmetic operators '+', '-', '*', '/', '#', '%',
+and '^' can be used as a self operator. The prefix operators '++'
+(increment by one) and '--' (decrement by one) are also defined. For
+example,
+int i=1;
+i += 2;
+int j=++i;
+
+is equivalent to the code
+int i=1;
+i=i+2;
+int j=i=i+1;
+
+ However, postfix operators like 'i++' and 'i--' are not defined
+(because of the inherent ambiguities that would arise with the '--'
+path-joining operator). In the rare instances where 'i++' and 'i--' are
+really needed, one can substitute the expressions '(++i-1)' and
+'(--i+1)', respectively.
+
+
+File: asymptote.info, Node: User-defined operators, Prev: Self & prefix operators, Up: Operators
+
+6.9.3 User-defined operators
+----------------------------
+
+The following symbols may be used with 'operator' to define or redefine
+operators on structures and built-in types:
+- + * / % ^ ! < > == != <= >= & | ^^ .. :: -- --- ++
+<< >> $ $$ @ @@ <>
+The operators on the second line have precedence one higher than the
+boolean operators '<', '>', '<=', and '>='.
+
+ Guide operators like '..' may be overloaded, say, to write a user
+function that produces a new guide from a given guide:
+guide dots(... guide[] g)=operator ..;
+
+guide operator ..(... guide[] g) {
+ guide G;
+ if(g.length > 0) {
+ write(g[0]);
+ G=g[0];
+ }
+ for(int i=1; i < g.length; ++i) {
+ write(g[i]);
+ write();
+ G=dots(G,g[i]);
+ }
+ return G;
+}
+
+guide g=(0,0){up}..{SW}(100,100){NE}..{curl 3}(50,50)..(10,10);
+write("g=",g);
+
+
+File: asymptote.info, Node: Implicit scaling, Next: Functions, Prev: Operators, Up: Programming
+
+6.10 Implicit scaling
+=====================
+
+If a numeric literal is in front of certain types of expressions, then
+the two are multiplied:
+int x=2;
+real y=2.0;
+real cm=72/2.540005;
+
+write(3x);
+write(2.5x);
+write(3y);
+write(-1.602e-19 y);
+write(0.5(x,y));
+write(2x^2);
+write(3x+2y);
+write(3(x+2y));
+write(3sin(x));
+write(3(sin(x))^2);
+write(10cm);
+
+ This produces the output
+6
+5
+6
+-3.204e-19
+(1,1)
+8
+10
+18
+2.72789228047704
+2.48046543129542
+283.464008929116
+
+
+File: asymptote.info, Node: Functions, Next: Arrays, Prev: Implicit scaling, Up: Programming
+
+6.11 Functions
+==============
+
+* Menu:
+
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+
+'Asymptote' functions are treated as variables with a signature
+(non-function variables have null signatures). Variables with the same
+name are allowed, so long as they have distinct signatures.
+
+ Functions arguments are passed by value. To pass an argument by
+reference, simply enclose it in a structure (*note Structures::).
+
+ Here are some significant features of 'Asymptote' functions:
+
+ 1. Variables with signatures (functions) and without signatures
+ (nonfunction variables) are distinct:
+ int x, x();
+ x=5;
+ x=new int() {return 17;};
+ x=x(); // calls x() and puts the result, 17, in the scalar x
+
+ 2. Traditional function definitions are allowed:
+ int sqr(int x)
+ {
+ return x*x;
+ }
+ sqr=null; // but the function is still just a variable.
+
+ 3. Casting can be used to resolve ambiguities:
+ int a, a(), b, b(); // Valid: creates four variables.
+ a=b; // Invalid: assignment is ambiguous.
+ a=(int) b; // Valid: resolves ambiguity.
+ (int) (a=b); // Valid: resolves ambiguity.
+ (int) a=b; // Invalid: cast expressions cannot be L-values.
+
+ int c();
+ c=a; // Valid: only one possible assignment.
+
+ 4. Anonymous (so-called "high-order") functions are also allowed:
+ typedef int intop(int);
+ intop adder(int m)
+ {
+ return new int(int n) {return m+n;};
+ }
+ intop addby7=adder(7);
+ write(addby7(1)); // Writes 8.
+
+ 5. One may redefine a function 'f', even for calls to 'f' in
+ previously declared functions, by assigning another (anonymous or
+ named) function to it. However, if 'f' is overloaded by a new
+ function definition, previous calls will still access the original
+ version of 'f', as illustrated in this example:
+ void f() {
+ write("hi");
+ }
+
+ void g() {
+ f();
+ }
+
+ g(); // writes "hi"
+
+ f=new void() {write("bye");};
+
+ g(); // writes "bye"
+
+ void f() {write("overloaded");};
+
+ f(); // writes "overloaded"
+ g(); // writes "bye"
+
+ 6. Anonymous functions can be used to redefine a function variable
+ that has been declared (and implicitly initialized to the null
+ function) but not yet explicitly defined:
+ void f(bool b);
+
+ void g(bool b) {
+ if(b) f(b);
+ else write(b);
+ }
+
+ f=new void(bool b) {
+ write(b);
+ g(false);
+ };
+
+ g(true); // Writes true, then writes false.
+
+ 'Asymptote' is the only language we know of that treats functions as
+variables, but allows overloading by distinguishing variables based on
+their signatures.
+
+ Functions are allowed to call themselves recursively. As in C++,
+infinite nested recursion will generate a stack overflow (reported as a
+segmentation fault, unless a fully working version of the GNU library
+'libsigsegv' (e.g. 2.4 or later) is installed at configuration time).
+
+
+File: asymptote.info, Node: Default arguments, Next: Named arguments, Prev: Functions, Up: Functions
+
+6.11.1 Default arguments
+------------------------
+
+'Asymptote' supports a more flexible mechanism for default function
+arguments than C++: they may appear anywhere in the function prototype.
+Because certain data types are implicitly cast to more sophisticated
+types (*note Casts::) one can often avoid ambiguities by ordering
+function arguments from the simplest to the most complicated. For
+example, given
+real f(int a=1, real b=0) {return a+b;}
+then 'f(1)' returns 1.0, but 'f(1.0)' returns 2.0.
+
+ The value of a default argument is determined by evaluating the given
+'Asymptote' expression in the scope where the called function is
+defined.
+
+
+File: asymptote.info, Node: Named arguments, Next: Rest arguments, Prev: Default arguments, Up: Functions
+
+6.11.2 Named arguments
+----------------------
+
+It is sometimes difficult to remember the order in which arguments
+appear in a function declaration. Named (keyword) arguments make
+calling functions with multiple arguments easier. Unlike in the C and
+C++ languages, an assignment in a function argument is interpreted as an
+assignment to a parameter of the same name in the function signature,
+_not within the local scope_. The command-line option '-d' may be used
+to check 'Asymptote' code for cases where a named argument may be
+mistaken for a local assignment.
+
+ When matching arguments to signatures, first all of the keywords are
+matched, then the arguments without names are matched against the
+unmatched formals as usual. For example,
+int f(int x, int y) {
+ return 10x+y;
+}
+write(f(4,x=3));
+outputs 34, as 'x' is already matched when we try to match the unnamed
+argument '4', so it gets matched to the next item, 'y'.
+
+ For the rare occasions where it is desirable to assign a value to
+local variable within a function argument (generally _not_ a good
+programming practice), simply enclose the assignment in parentheses.
+For example, given the definition of 'f' in the previous example,
+int x;
+write(f(4,(x=3)));
+is equivalent to the statements
+int x;
+x=3;
+write(f(4,3));
+and outputs 43.
+
+ Parameters can be specified as "keyword-only" by putting 'keyword'
+immediately before the parameter name, as in 'int f(int keyword x)' or
+'int f(int keyword x=77)'. This forces the caller of the function to
+use a named argument to give a value for this parameter. That is,
+'f(x=42)' is legal, but 'f(25)' is not. Keyword-only parameters must be
+listed after normal parameters in a function definition.
+
+ As a technical detail, we point out that, since variables of the same
+name but different signatures are allowed in the same scope, the code
+int f(int x, int x()) {
+ return x+x();
+}
+int seven() {return 7;}
+is legal in 'Asymptote', with 'f(2,seven)' returning 9. A named
+argument matches the first unmatched formal of the same name, so
+'f(x=2,x=seven)' is an equivalent call, but 'f(x=seven,2)' is not, as
+the first argument is matched to the first formal, and 'int ()' cannot
+be implicitly cast to 'int'. Default arguments do not affect which
+formal a named argument is matched to, so if 'f' were defined as
+int f(int x=3, int x()) {
+ return x+x();
+}
+then 'f(x=seven)' would be illegal, even though 'f(seven)' obviously
+would be allowed.
+
+
+File: asymptote.info, Node: Rest arguments, Next: Mathematical functions, Prev: Named arguments, Up: Functions
+
+6.11.3 Rest arguments
+---------------------
+
+Rest arguments allow one to write functions that take a variable number
+of arguments:
+// This function sums its arguments.
+int sum(... int[] nums) {
+ int total=0;
+ for(int i=0; i < nums.length; ++i)
+ total += nums[i];
+ return total;
+}
+
+sum(1,2,3,4); // returns 10
+sum(); // returns 0
+
+// This function subtracts subsequent arguments from the first.
+int subtract(int start ... int[] subs) {
+ for(int i=0; i < subs.length; ++i)
+ start -= subs[i];
+ return start;
+}
+
+subtract(10,1,2); // returns 7
+subtract(10); // returns 10
+subtract(); // illegal
+
+ Putting an argument into a rest array is called _packing_. One can
+give an explicit list of arguments for the rest argument, so 'subtract'
+could alternatively be implemented as
+int subtract(int start ... int[] subs) {
+ return start - sum(... subs);
+}
+
+ One can even combine normal arguments with rest arguments:
+sum(1,2,3 ... new int[] {4,5,6}); // returns 21
+This builds a new six-element array that is passed to 'sum' as 'nums'.
+The opposite operation, _unpacking_, is not allowed:
+subtract(... new int[] {10, 1, 2});
+is illegal, as the start formal is not matched.
+
+ If no arguments are packed, then a zero-length array (as opposed to
+'null') is bound to the rest parameter. Note that default arguments are
+ignored for rest formals and the rest argument is not bound to a
+keyword.
+
+ In some cases, keyword-only parameters are helpful to avoid arguments
+intended for the rest parameter to be assigned to other parameters. For
+example, here the use of 'keyword' is to avoid 'pnorm(1.0,2.0,0.3)'
+matching '1.0' to 'p'.
+real pnorm(real keyword p=2.0 ... real[] v)
+{
+ return sum(v^p)^(1/p);
+}
+
+ The overloading resolution in 'Asymptote' is similar to the function
+matching rules used in C++. Every argument match is given a score.
+Exact matches score better than matches with casting, and matches with
+formals (regardless of casting) score better than packing an argument
+into the rest array. A candidate is maximal if all of the arguments
+score as well in it as with any other candidate. If there is one unique
+maximal candidate, it is chosen; otherwise, there is an ambiguity error.
+
+int f(path g);
+int f(guide g);
+f((0,0)--(100,100)); // matches the second; the argument is a guide
+
+int g(int x, real y);
+int g(real x, int x);
+
+g(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second argument
+
+int h(... int[] rest);
+int h(real x ... int[] rest);
+
+h(1,2); // the second definition matches, even though there is a cast,
+ // because casting is preferred over packing
+
+int i(int x ... int[] rest);
+int i(real x, real y ... int[] rest);
+
+i(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second one
+
+
+File: asymptote.info, Node: Mathematical functions, Prev: Rest arguments, Up: Functions
+
+6.11.4 Mathematical functions
+-----------------------------
+
+'Asymptote' has built-in versions of the standard 'libm' mathematical
+real(real) functions 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'exp',
+'log', 'pow10', 'log10', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh',
+'atanh', 'sqrt', 'cbrt', 'fabs', 'expm1', 'log1p', as well as the
+identity function 'identity'. 'Asymptote' also defines the order 'n'
+Bessel functions of the first kind 'Jn(int n, real)' and second kind
+'Yn(int n, real)', as well as the gamma function 'gamma', the error
+function 'erf', and the complementary error function 'erfc'. The
+standard real(real, real) functions 'atan2', 'hypot', 'fmod',
+'remainder' are also included.
+
+ The functions 'degrees(real radians)' and 'radians(real degrees)' can
+be used to convert between radians and degrees. The function
+'Degrees(real radians)' returns the angle in degrees in the interval
+[0,360). For convenience, 'Asymptote' defines variants 'Sin', 'Cos',
+'Tan', 'aSin', 'aCos', and 'aTan' of the standard trigonometric
+functions that use degrees rather than radians. We also define complex
+versions of the 'sqrt', 'sin', 'cos', 'exp', 'log', and 'gamma'
+functions.
+
+ The functions 'floor', 'ceil', and 'round' differ from their usual
+definitions in that they all return an int value rather than a real
+(since that is normally what one wants). The functions 'Floor', 'Ceil',
+and 'Round' are respectively similar, except that if the result cannot
+be converted to a valid int, they return 'intMax' for positive arguments
+and 'intMin' for negative arguments, rather than generating an integer
+overflow. We also define a function 'sgn', which returns the sign of
+its real argument as an integer (-1, 0, or 1).
+
+ There is an 'abs(int)' function, as well as an 'abs(real)' function
+(equivalent to 'fabs(real)'), an 'abs(pair)' function (equivalent to
+'length(pair)').
+
+ Random numbers can be seeded with 'srand(int)' and generated with the
+'int rand()' function, which returns a random integer between 0 and the
+integer 'randMax'. The 'unitrand()' function returns a random number
+uniformly distributed in the interval [0,1]. A Gaussian random number
+generator 'Gaussrand' and a collection of statistics routines, including
+'histogram', are provided in the base file 'stats.asy'. The functions
+'factorial(int n)', which returns n!, and 'choose(int n, int k)', which
+returns n!/(k!(n-k)!), are also defined.
+
+ When configured with the GNU Scientific Library (GSL), available from
+<http://www.gnu.org/software/gsl/>, 'Asymptote' contains an internal
+module 'gsl' that defines the airy functions 'Ai(real)', 'Bi(real)',
+'Ai_deriv(real)', 'Bi_deriv(real)', 'zero_Ai(int)', 'zero_Bi(int)',
+'zero_Ai_deriv(int)', 'zero_Bi_deriv(int)', the Bessel functions 'I(int,
+real)', 'K(int, real)', 'j(int, real)', 'y(int, real)', 'i_scaled(int,
+real)', 'k_scaled(int, real)', 'J(real, real)', 'Y(real, real)',
+'I(real, real)', 'K(real, real)', 'zero_J(real, int)', the elliptic
+functions 'F(real, real)', 'E(real, real)', and 'P(real, real)', the
+Jacobi elliptic functions 'real[] sncndn(real,real)', the
+exponential/trigonometric integrals 'Ei', 'Si', and 'Ci', the Legendre
+polynomials 'Pl(int, real)', and the Riemann zeta function 'zeta(real)'.
+For example, to compute the sine integral 'Si' of 1.0:
+import gsl;
+write(Si(1.0));
+
+ 'Asymptote' also provides a few general purpose numerical routines:
+
+'real newton(int iterations=100, real f(real), real fprime(real), real x, bool verbose=false);'
+ Use Newton-Raphson iteration to solve for a root of a real-valued
+ differentiable function 'f', given its derivative 'fprime' and an
+ initial guess 'x'. Diagnostics for each iteration are printed if
+ 'verbose=true'. If the iteration fails after the maximum allowed
+ number of loops ('iterations'), 'realMax' is returned.
+
+'real newton(int iterations=100, real f(real), real fprime(real), real x1, real x2, bool verbose=false);'
+ Use bracketed Newton-Raphson bisection to solve for a root of a
+ real-valued differentiable function 'f' within an interval
+ ['x1','x2'] (on which the endpoint values of 'f' have opposite
+ signs), given its derivative 'fprime'. Diagnostics for each
+ iteration are printed if 'verbose=true'. If the iteration fails
+ after the maximum allowed number of loops ('iterations'), 'realMax'
+ is returned.
+
+'real simpson(real f(real), real a, real b, real acc=realEpsilon, real dxmax=b-a)'
+ returns the integral of 'f' from 'a' to 'b' using adaptive Simpson
+ integration.
+
+
+File: asymptote.info, Node: Arrays, Next: Casts, Prev: Functions, Up: Programming
+
+6.12 Arrays
+===========
+
+* Menu:
+
+* Slices:: Python-style array slices
+
+Appending '[]' to a built-in or user-defined type yields an array. The
+array element 'i' of an array 'A' can be accessed as 'A[i]'. By
+default, attempts to access or assign to an array element using a
+negative index generates an error. Reading an array element with an
+index beyond the length of the array also generates an error; however,
+assignment to an element beyond the length of the array causes the array
+to be resized to accommodate the new element. One can also index an
+array 'A' with an integer array 'B': the array 'A[B]' is formed by
+indexing array 'A' with successive elements of array 'B'. A convenient
+Java-style shorthand exists for iterating over all elements of an array;
+see *note array iteration::.
+
+ The declaration
+real[] A;
+
+initializes 'A' to be an empty (zero-length) array. Empty arrays should
+be distinguished from null arrays. If we say
+real[] A=null;
+
+then 'A' cannot be dereferenced at all (null arrays have no length and
+cannot be read from or assigned to).
+
+ Arrays can be explicitly initialized like this:
+real[] A={0,1,2};
+
+ Array assignment in 'Asymptote' does a shallow copy: only the pointer
+is copied (if one copy if modified, the other will be too). The 'copy'
+function listed below provides a deep copy of an array.
+
+ Every array 'A' of type 'T[]' has the virtual members
+ * 'int length',
+ * 'int cyclic',
+ * 'int[] keys',
+ * 'T push(T x)',
+ * 'void append(T[] a)',
+ * 'T pop()',
+ * 'void insert(int i ... T[] x)',
+ * 'void delete(int i, int j=i)',
+ * 'void delete()', and
+ * 'bool initialized(int n)'.
+
+ The member 'A.length' evaluates to the length of the array. Setting
+'A.cyclic=true' signifies that array indices should be reduced modulo
+the current array length. Reading from or writing to a nonempty cyclic
+array never leads to out-of-bounds errors or array resizing.
+
+ The member 'A.keys' evaluates to an array of integers containing the
+indices of initialized entries in the array in ascending order. Hence,
+for an array of length 'n' with all entries initialized, 'A.keys'
+evaluates to '{0,1,...,n-1}'. A new keys array is produced each time
+'A.keys' is evaluated.
+
+ The functions 'A.push' and 'A.append' append their arguments onto the
+end of the array, while 'A.insert(int i ... T[] x)' inserts 'x' into the
+array at index 'i'. For convenience 'A.push' returns the pushed item.
+The function 'A.pop()' pops and returns the last element, while
+'A.delete(int i, int j=i)' deletes elements with indices in the range
+['i','j'], shifting the position of all higher-indexed elements down.
+If no arguments are given, 'A.delete()' provides a convenient way of
+deleting all elements of 'A'. The routine 'A.initialized(int n)' can be
+used to examine whether the element at index 'n' is initialized. Like
+all 'Asymptote' functions, 'push', 'append', 'pop', 'insert', 'delete',
+and 'initialized' can be "pulled off" of the array and used on their
+own. For example,
+int[] A={1};
+A.push(2); // A now contains {1,2}.
+A.append(A); // A now contains {1,2,1,2}.
+int f(int)=A.push;
+f(3); // A now contains {1,2,1,2,3}.
+int g()=A.pop;
+write(g()); // Outputs 3.
+A.delete(0); // A now contains {2,1,2}.
+A.delete(0,1); // A now contains {2}.
+A.insert(1,3); // A now contains {2,3}.
+A.insert(1 ... A); // A now contains {2,2,3,3}
+A.insert(2,4,5); // A now contains {2,2,4,5,3,3}.
+
+ The '[]' suffix can also appear after the variable name; this is
+sometimes convenient for declaring a list of variables and arrays of the
+same type:
+real a,A[];
+This declares 'a' to be 'real' and implicitly declares 'A' to be of type
+'real[]'.
+
+ In the following list of built-in array functions, 'T' represents a
+generic type. Note that the internal functions 'alias', 'array',
+'copy', 'concat', 'sequence', 'map', and 'transpose', which depend on
+type 'T[]', are defined only after the first declaration of a variable
+of type 'T[]'.
+
+'new T[]'
+ returns a new empty array of type 'T[]';
+
+'new T[] {list}'
+ returns a new array of type 'T[]' initialized with 'list' (a comma
+ delimited list of elements).
+
+'new T[n]'
+ returns a new array of 'n' elements of type 'T[]'. These 'n' array
+ elements are not initialized unless they are arrays themselves (in
+ which case they are each initialized to empty arrays).
+
+'T[] array(int n, T value, int depth=intMax)'
+ returns an array consisting of 'n' copies of 'value'. If 'value'
+ is itself an array, a deep copy of 'value' is made for each entry.
+ If 'depth' is specified, this deep copying only recurses to the
+ specified number of levels.
+
+'int[] sequence(int n)'
+ if 'n >= 1' returns the array '{0,1,...,n-1}' (otherwise returns a
+ null array);
+
+'int[] sequence(int n, int m)'
+ if 'm >= n' returns an array '{n,n+1,...,m}' (otherwise returns a
+ null array);
+
+'T[] sequence(T f(int), int n)'
+ if 'n >= 1' returns the sequence '{f_i :i=0,1,...n-1}' given a
+ function 'T f(int)' and integer 'int n' (otherwise returns a null
+ array);
+
+'T[] map(T f(T), T[] a)'
+ returns the array obtained by applying the function 'f' to each
+ element of the array 'a'. This is equivalent to 'sequence(new
+ T(int i) {return f(a[i]);},a.length)'.
+
+'int[] reverse(int n)'
+ if 'n >= 1' returns the array '{n-1,n-2,...,0}' (otherwise returns
+ a null array);
+
+'int[] complement(int[] a, int n)'
+ returns the complement of the integer array 'a' in
+ '{0,1,2,...,n-1}', so that 'b[complement(a,b.length)]' yields the
+ complement of 'b[a]'.
+
+'real[] uniform(real a, real b, int n)'
+ if 'n >= 1' returns a uniform partition of '[a,b]' into 'n'
+ subintervals (otherwise returns a null array);
+
+'int find(bool[] a, int n=1)'
+ returns the index of the 'n'th 'true' value in the boolean array
+ 'a' or -1 if not found. If 'n' is negative, search backwards from
+ the end of the array for the '-n'th value;
+
+'int[] findall(bool[] a)'
+ returns the indices of all 'true' values in the boolean array 'a'.
+
+'int search(T[] a, T key)'
+ For built-in ordered types 'T', searches a sorted array 'a' of 'n'
+ elements for k, returning the index 'i' if 'a[i] <= key < a[i+1]',
+ '-1' if 'key' is less than all elements of 'a', or 'n-1' if 'key'
+ is greater than or equal to the last element of 'a'.
+
+'int search(T[] a, T key, bool less(T i, T j))'
+ searches an array 'a' sorted in ascending order such that element
+ 'i' precedes element 'j' if 'less(i,j)' is true;
+
+'T[] copy(T[] a)'
+ returns a deep copy of the array 'a';
+
+'T[] concat(... T[][] a)'
+ returns a new array formed by concatenating the given
+ one-dimensional arrays given as arguments;
+
+'bool alias(T[] a, T[] b)'
+ returns 'true' if the arrays 'a' and 'b' are identical;
+
+'T[] sort(T[] a)'
+ For built-in ordered types 'T', returns a copy of 'a' sorted in
+ ascending order;
+
+'T[][] sort(T[][] a)'
+ For built-in ordered types 'T', returns a copy of 'a' with the rows
+ sorted by the first column, breaking ties with successively higher
+ columns. For example:
+ string[][] a={{"bob","9"},{"alice","5"},{"pete","7"},
+ {"alice","4"}};
+ // Row sort (by column 0, using column 1 to break ties):
+ write(sort(a));
+
+ produces
+ alice 4
+ alice 5
+ bob 9
+ pete 7
+
+'T[] sort(T[] a, bool less(T i, T j), bool stable=true)'
+ returns a copy of 'a' sorted in ascending order such that element
+ 'i' precedes element 'j' if 'less(i,j)' is true, subject to (if
+ 'stable' is 'true') the stability constraint that the original
+ order of elements 'i' and 'j' is preserved if 'less(i,j)' and
+ 'less(j,i)' are both 'false'.
+
+'T[][] transpose(T[][] a)'
+ returns the transpose of 'a'.
+
+'T[][][] transpose(T[][][] a, int[] perm)'
+ returns the 3D transpose of 'a' obtained by applying the
+ permutation 'perm' of 'new int[]{0,1,2}' to the indices of each
+ entry.
+
+'T sum(T[] a)'
+ For arithmetic types 'T', returns the sum of 'a'. In the case
+ where 'T' is 'bool', the number of true elements in 'a' is
+ returned.
+
+'T min(T[] a)'
+'T min(T[][] a)'
+'T min(T[][][] a)'
+ For built-in ordered types 'T', returns the minimum element of 'a'.
+
+'T max(T[] a)'
+'T max(T[][] a)'
+'T max(T[][][] a)'
+ For built-in ordered types 'T', returns the maximum element of 'a'.
+
+'T[] min(T[] a, T[] b)'
+ For built-in ordered types 'T', and arrays 'a' and 'b' of the same
+ length, returns an array composed of the minimum of the
+ corresponding elements of 'a' and 'b'.
+
+'T[] max(T[] a, T[] b)'
+ For built-in ordered types 'T', and arrays 'a' and 'b' of the same
+ length, returns an array composed of the maximum of the
+ corresponding elements of 'a' and 'b'.
+
+'pair[] pairs(real[] x, real[] y);'
+ For arrays 'x' and 'y' of the same length, returns the pair array
+ 'sequence(new pair(int i) {return (x[i],y[i]);},x.length)'.
+
+'pair[] fft(pair[] a, int sign=1)'
+ returns the unnormalized Fast Fourier Transform of 'a' (if the
+ optional 'FFTW' package is installed), using the given 'sign'.
+ Here is a simple example:
+ int n=4;
+ pair[] f=sequence(n);
+ write(f);
+ pair[] g=fft(f,-1);
+ write();
+ write(g);
+ f=fft(g,1);
+ write();
+ write(f/n);
+
+'real dot(real[] a, real[] b)'
+ returns the dot product of the vectors 'a' and 'b'.
+
+'pair dot(pair[] a, pair[] b)'
+ returns the complex dot product 'sum(a*conj(b))' of the vectors 'a'
+ and 'b'.
+
+'real[] tridiagonal(real[] a, real[] b, real[] c, real[] f);'
+ Solve the periodic tridiagonal problem L'x'='f' and return the
+ solution 'x', where 'f' is an n vector and L is the n \times n
+ matrix
+ [ b[0] c[0] a[0] ]
+ [ a[1] b[1] c[1] ]
+ [ a[2] b[2] c[2] ]
+ [ ... ]
+ [ c[n-1] a[n-1] b[n-1] ]
+ For Dirichlet boundary conditions (denoted here by 'u[-1]' and
+ 'u[n]'), replace 'f[0]' by 'f[0]-a[0]u[-1]' and
+ 'f[n-1]-c[n-1]u[n]'; then set 'a[0]=c[n-1]=0'.
+
+'real[] solve(real[][] a, real[] b, bool warn=true)'
+ Solve the linear equation 'a'x='b' by LU decomposition and return
+ the solution x, where 'a' is an n \times n matrix and 'b' is an
+ array of length n. For example:
+ import math;
+ real[][] a={{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},{1,50,1,-2}};
+ real[] b={7,19,33,3};
+ real[] x=solve(a,b);
+ write(a); write();
+ write(b); write();
+ write(x); write();
+ write(a*x);
+ If 'a' is a singular matrix and 'warn' is 'false', return an empty
+ array. If the matrix 'a' is tridiagonal, the routine 'tridiagonal'
+ provides a more efficient algorithm (*note tridiagonal::).
+
+'real[][] solve(real[][] a, real[][] b, bool warn=true)'
+ Solve the linear equation 'a'x='b' and return the solution x, where
+ 'a' is an n \times n matrix and 'b' is an n \times m matrix. If
+ 'a' is a singular matrix and 'warn' is 'false', return an empty
+ matrix.
+
+'real[][] identity(int n);'
+ returns the n \times n identity matrix.
+
+'real[][] diagonal(... real[] a)'
+ returns the diagonal matrix with diagonal entries given by a.
+
+'real[][] inverse(real[][] a)'
+ returns the inverse of a square matrix 'a'.
+
+'real[] quadraticroots(real a, real b, real c);'
+ This numerically robust solver returns the real roots of the
+ quadratic equation ax^2+bx+c=0, in ascending order. Multiple roots
+ are listed separately.
+
+'pair[] quadraticroots(explicit pair a, explicit pair b, explicit pair c);'
+ This numerically robust solver returns the complex roots of the
+ quadratic equation ax^2+bx+c=0.
+
+'real[] cubicroots(real a, real b, real c, real d);'
+ This numerically robust solver returns the real roots of the cubic
+ equation ax^3+bx^2+cx+d=0. Multiple roots are listed separately.
+
+ 'Asymptote' includes a full set of vectorized array instructions for
+arithmetic (including self) and logical operations. These
+element-by-element instructions are implemented in C++ code for speed.
+Given
+real[] a={1,2};
+real[] b={3,2};
+then 'a == b' and 'a >= 2' both evaluate to the vector '{false, true}'.
+To test whether all components of 'a' and 'b' agree, use the boolean
+function 'all(a == b)'. One can also use conditionals like '(a >= 2) ?
+a : b', which returns the array '{3,2}', or 'write((a >= 2) ? a : null',
+which returns the array '{2}'.
+
+ All of the standard built-in 'libm' functions of signature
+'real(real)' also take a real array as an argument, effectively like an
+implicit call to 'map'.
+
+ As with other built-in types, arrays of the basic data types can be
+read in by assignment. In this example, the code
+file fin=input("test.txt");
+real[] A=fin;
+
+reads real values into 'A' until the end-of-file is reached (or an I/O
+error occurs).
+
+ The virtual members 'dimension', 'line', 'csv', 'word', and 'read' of
+a file are useful for reading arrays. For example, if line mode is set
+with 'file line(bool b=true)', then reading will stop once the end of
+the line is reached instead:
+file fin=input("test.txt");
+real[] A=fin.line();
+
+ Since string reads by default read up to the end of line anyway, line
+mode normally has no effect on string array reads. However, there is a
+white-space delimiter mode for reading strings, 'file word(bool
+b=true)', which causes string reads to respect white-space delimiters,
+instead of the default end-of-line delimiter:
+file fin=input("test.txt").line().word();
+real[] A=fin;
+
+ Another useful mode is comma-separated-value mode, 'file csv(bool
+b=true)', which causes reads to respect comma delimiters:
+file fin=csv(input("test.txt"));
+real[] A=fin;
+
+ To restrict the number of values read, use the 'file dimension(int)'
+function:
+file fin=input("test.txt");
+real[] A=dimension(fin,10);
+
+ This reads 10 values into A, unless end-of-file (or end-of-line in
+line mode) occurs first. Attempting to read beyond the end of the file
+will produce a runtime error message. Specifying a value of 0 for the
+integer limit is equivalent to the previous example of reading until
+end-of-file (or end-of-line in line mode) is encountered.
+
+ Two- and three-dimensional arrays of the basic data types can be read
+in like this:
+file fin=input("test.txt");
+real[][] A=fin.dimension(2,3);
+real[][][] B=fin.dimension(2,3,4);
+
+ Sometimes the array dimensions are stored with the data as integer
+fields at the beginning of an array. Such 1, 2, or 3 dimensional arrays
+can be read in with the virtual member functions 'read(1)', 'read(2)',
+or 'read(3)', respectively:
+file fin=input("test.txt");
+real[] A=fin.read(1);
+real[][] B=fin.read(2);
+real[][][] C=fin.read(3);
+
+ One, two, and three-dimensional arrays of the basic data types can be
+output with the functions 'write(file,T[])', 'write(file,T[][])',
+'write(file,T[][][])', respectively.
+
+
+File: asymptote.info, Node: Slices, Prev: Arrays, Up: Arrays
+
+6.12.1 Slices
+-------------
+
+Asymptote allows a section of an array to be addressed as a slice using
+a Python-like syntax. If 'A' is an array, the expression 'A[m:n]'
+returns a new array consisting of the elements of 'A' with indices from
+'m' up to but not including 'n'. For example,
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[2:6]; // y={2,3,4,5};
+int[] z=x[5:10]; // z={5,6,7,8,9};
+
+ If the left index is omitted, it is taken be '0'. If the right index
+is omitted it is taken to be the length of the array. If both are
+omitted, the slice then goes from the start of the array to the end,
+producing a non-cyclic deep copy of the array. For example:
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[:4]; // y={0,1,2,3}
+int[] z=x[5:]; // z={5,6,7,8,9}
+int[] w=x[:]; // w={0,1,2,3,4,5,6,7,8,9}, distinct from array x.
+
+ If A is a non-cyclic array, it is illegal to use negative values for
+either of the indices. If the indices exceed the length of the array,
+however, they are politely truncated to that length.
+
+ For cyclic arrays, the slice 'A[m:n]' still consists of the cells
+with indices in the set ['m','n'), but now negative values and values
+beyond the length of the array are allowed. The indices simply wrap
+around. For example:
+
+int[] x={0,1,2,3,4,5,6,7,8,9};
+x.cyclic=true;
+int[] y=x[8:15]; // y={8,9,0,1,2,3,4}.
+int[] z=x[-5:5]; // z={5,6,7,8,9,0,1,2,3,4}
+int[] w=x[-3:17]; // w={7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}
+
+ Notice that with cyclic arrays, it is possible to include the same
+element of the original array multiple times within a slice. Regardless
+of the original array, arrays produced by slices are always non-cyclic.
+
+ If the left and right indices of a slice are the same, the result is
+an empty array. If the array being sliced is empty, the result is an
+empty array. Any slice with a left index greater than its right index
+will yield an error.
+
+ Slices can also be assigned to, changing the value of the original
+array. If the array being assigned to the slice has a different length
+than the slice itself, elements will be inserted or removed from the
+array to accommodate it. For instance:
+string[] toppings={"mayo", "salt", "ham", "lettuce"};
+toppings[0:2]=new string[] {"mustard", "pepper"};
+ // Now toppings={"mustard", "pepper", "ham", "lettuce"}
+toppings[2:3]=new string[] {"turkey", "bacon" };
+ // Now toppings={"mustard", "pepper", "turkey", "bacon", "lettuce"}
+toppings[0:3]=new string[] {"tomato"};
+ // Now toppings={"tomato", "bacon", "lettuce"}
+
+ If an array is assigned to a slice of itself, a copy of the original
+array is assigned to the slice. That is, code such as 'x[m:n]=x' is
+equivalent to 'x[m:n]=copy(x)'. One can use the shorthand 'x[m:m]=y' to
+insert the contents of the array 'y' into the array 'x' starting at the
+location just before 'x[m]'.
+
+ For a cyclic array, a slice is bridging if it addresses cells up to
+the end of the array and then continues on to address cells at the start
+of the array. For instance, if 'A' is a cyclic array of length 10,
+'A[8:12]', 'A[-3:1]', and 'A[5:25]' are bridging slices whereas
+'A[3:7]', 'A[7:10]', 'A[-3:0]' and 'A[103:107]' are not. Bridging
+slices can only be assigned to if the number of elements in the slice is
+exactly equal to the number of elements we are assigning to it.
+Otherwise, there is no clear way to decide which of the new entries
+should be 'A[0]' and an error is reported. Non-bridging slices may be
+assigned an array of any length.
+
+ For a cyclic array 'A' an expression of the form
+'A[A.length:A.length]' is equivalent to the expression 'A[0:0]' and so
+assigning to this slice will insert values at the start of the array.
+'A.append()' can be used to insert values at the end of the array.
+
+ It is illegal to assign to a slice of a cyclic array that repeats any
+of the cells.
+
+
+File: asymptote.info, Node: Casts, Next: Import, Prev: Arrays, Up: Programming
+
+6.13 Casts
+==========
+
+'Asymptote' implicitly casts 'int' to 'real', 'int' to 'pair', 'real' to
+'pair', 'pair' to 'path', 'pair' to 'guide', 'path' to 'guide', 'guide'
+to 'path', 'real' to 'pen', 'pair[]' to 'guide[]', 'pair[]' to 'path[]',
+'path' to 'path[]', and 'guide' to 'path[]', along with various
+three-dimensional casts defined in 'three.asy'. Implicit casts are
+automatically attempted on assignment and when trying to match function
+calls with possible function signatures. Implicit casting can be
+inhibited by declaring individual arguments 'explicit' in the function
+signature, say to avoid an ambiguous function call in the following
+example, which outputs 0:
+int f(pair a) {return 0;}
+int f(explicit real x) {return 1;}
+
+write(f(0));
+
+ Other conversions, say 'real' to 'int' or 'real' to 'string', require
+an explicit cast:
+int i=(int) 2.5;
+string s=(string) 2.5;
+
+real[] a={2.5,-3.5};
+int[] b=(int []) a;
+write(stdout,b); // Outputs 2,-3
+ In situations where casting from a string to a type 'T' fails, an
+uninitialized variable is returned; this condition can be detected with
+the function 'bool initialized(T);'
+int i=(int) "2.5";
+assert(initialized(i),"Invalid cast.");
+
+real x=(real) "2.5a";
+assert(initialized(x),"Invalid cast.");
+
+ Casting to user-defined types is also possible using 'operator cast':
+struct rpair {
+ real radius;
+ real angle;
+}
+
+pair operator cast(rpair x) {
+ return (x.radius*cos(x.angle),x.radius*sin(x.angle));
+}
+
+rpair x;
+x.radius=1;
+x.angle=pi/6;
+
+write(x); // Outputs (0.866025403784439,0.5)
+
+ One must use care when defining new cast operators. Suppose that in
+some code one wants all integers to represent multiples of 100. To
+convert them to reals, one would first want to multiply them by 100.
+However, the straightforward implementation
+real operator cast(int x) {return x*100;}
+is equivalent to an infinite recursion, since the result 'x*100' needs
+itself to be cast from an integer to a real. Instead, we want to use
+the standard conversion of int to real:
+real convert(int x) {return x*100;}
+real operator cast(int x)=convert;
+
+ Explicit casts are implemented similarly, with 'operator ecast'.
+
+
+File: asymptote.info, Node: Import, Next: Static, Prev: Casts, Up: Programming
+
+6.14 Import
+===========
+
+While 'Asymptote' provides many features by default, some applications
+require specialized features contained in external 'Asymptote' modules.
+For instance, the lines
+access graph;
+graph.axes();
+draw x and y axes on a two-dimensional graph. Here, the command looks
+up the module under the name 'graph' in a global dictionary of modules
+and puts it in a new variable named 'graph'. The module is a structure,
+and we can refer to its fields as we usually would with a structure.
+
+ Often, one wants to use module functions without having to specify
+the module name. The code
+from graph access axes;
+adds the 'axes' field of 'graph' into the local name space, so that
+subsequently, one can just write 'axes()'. If the given name is
+overloaded, all types and variables of that name are added. To add more
+than one name, just use a comma-separated list:
+from graph access axes, xaxis, yaxis;
+Wild card notation can be used to add all non-private fields and types
+of a module to the local name space:
+
+from graph access *;
+
+ Similarly, one can add the non-private fields and types of a
+structure to the local environment with the 'unravel' keyword:
+struct matrix {
+ real a,b,c,d;
+}
+
+real det(matrix m) {
+ unravel m;
+ return a*d-b*c;
+}
+ Alternatively, one can unravel selective fields:
+real det(matrix m) {
+ from m unravel a,b,c as C,d;
+ return a*d-b*C;
+}
+
+ The command
+import graph;
+ is a convenient abbreviation for the commands
+access graph;
+unravel graph;
+ That is, 'import graph' first loads a module into a structure called
+'graph' and then adds its non-private fields and types to the local
+environment. This way, if a member variable (or function) is
+overwritten with a local variable (or function of the same signature),
+the original one can still be accessed by qualifying it with the module
+name.
+
+ Wild card importing will work fine in most cases, but one does not
+usually know all of the internal types and variables of a module, which
+can also change as the module writer adds or changes features of the
+module. As such, it is prudent to add 'import' commands at the start of
+an 'Asymptote' file, so that imported names won't shadow locally defined
+functions. Still, imported names may shadow other imported names,
+depending on the order in which they were imported, and imported
+functions may cause overloading resolution problems if they have the
+same name as local functions defined later.
+
+ To rename modules or fields when adding them to the local
+environment, use 'as':
+access graph as graph2d;
+from graph access xaxis as xline, yaxis as yline;
+
+ The command
+import graph as graph2d;
+ is a convenient abbreviation for the commands
+access graph as graph2d;
+unravel graph2d;
+
+ Except for a few built-in modules, such as 'settings', all modules
+are implemented as 'Asymptote' files. When looking up a module that has
+not yet been loaded, 'Asymptote' searches the standard search paths
+(*note Search paths::) for the matching file. The file corresponding to
+that name is read and the code within it is interpreted as the body of a
+structure defining the module.
+
+ If the file name contains nonalphanumeric characters, enclose it with
+quotation marks:
+
+'access "/usr/local/share/asymptote/graph.asy" as graph;'
+
+'from "/usr/local/share/asymptote/graph.asy" access axes;'
+
+'import "/usr/local/share/asymptote/graph.asy" as graph;'
+
+ It is an error if modules import themselves (or each other in a
+cycle). The module name to be imported must be known at compile time.
+
+ However, you can import an 'Asymptote' module determined by the
+string 's' at runtime like this:
+eval("import "+s,true);
+
+ To conditionally execute an array of asy files, use
+void asy(string format, bool overwrite ... string[] s);
+ The file will only be processed, using output format 'format', if
+overwrite is 'true' or the output file is missing.
+
+ One can evaluate an 'Asymptote' expression (without any return value,
+however) contained in the string 's' with:
+void eval(string s, bool embedded=false);
+ It is not necessary to terminate the string 's' with a semicolon. If
+'embedded' is 'true', the string will be evaluated at the top level of
+the current environment. If 'embedded' is 'false' (the default), the
+string will be evaluated in an independent environment, sharing the same
+'settings' module (*note settings::).
+
+ One can evaluate arbitrary 'Asymptote' code (which may contain
+unescaped quotation marks) with the command
+void eval(code s, bool embedded=false);
+ Here 'code' is a special type used with 'quote {}' to enclose
+'Asymptote code' like this:
+real a=1;
+code s=quote {
+ write(a);
+};
+eval(s,true); // Outputs 1
+
+ To include the contents of an existing file 'graph' verbatim (as if
+the contents of the file were inserted at that point), use one of the
+forms:
+include graph;
+
+'include "/usr/local/share/asymptote/graph.asy";'
+
+ To list all global functions and variables defined in a module named
+by the contents of the string 's', use the function
+void list(string s, bool imports=false);
+Imported global functions and variables are also listed if 'imports' is
+'true'.
+
+
+File: asymptote.info, Node: Static, Prev: Import, Up: Programming
+
+6.15 Static
+===========
+
+Static qualifiers allocate the memory address of a variable in a higher
+enclosing level.
+
+ For a function body, the variable is allocated in the block where the
+function is defined; so in the code
+struct s {
+ int count() {
+ static int c=0;
+ ++c;
+ return c;
+ }
+}
+
+there is one instance of the variable 'c' for each object 's' (as
+opposed to each call of 'count').
+
+ Similarly, in
+int factorial(int n) {
+ int helper(int k) {
+ static int x=1;
+ x *= k;
+ return k == 1 ? x : helper(k-1);
+ }
+ return helper(n);
+}
+
+there is one instance of 'x' for every call to 'factorial' (and not for
+every call to 'helper'), so this is a correct, but ugly, implementation
+of factorial.
+
+ Similarly, a static variable declared within a structure is allocated
+in the block where the structure is defined. Thus,
+struct A {
+ struct B {
+ static pair z;
+ }
+}
+
+creates one object 'z' for each object of type 'A' created.
+
+ In this example,
+int pow(int n, int k) {
+ struct A {
+ static int x=1;
+ void helper() {
+ x *= n;
+ }
+ }
+ for(int i=0; i < k; ++i) {
+ A a;
+ a.helper();
+ }
+ return A.x;
+}
+
+there is one instance of 'x' for each call to 'pow', so this is an ugly
+implementation of exponentiation.
+
+ Loop constructs allocate a new frame in every iteration. This is so
+that higher-order functions can refer to variables of a specific
+iteration of a loop:
+void f();
+for(int i=0; i < 10; ++i) {
+ int x=i;
+ if(x==5) {
+ f=new void () { write(x); }
+ }
+}
+f();
+
+ Here, every iteration of the loop has its own variable 'x', so 'f()'
+will write '5'. If a variable in a loop is declared static, it will be
+allocated where the enclosing function or structure was defined (just as
+if it were declared static outside of the loop). For instance, in:
+void f() {
+ static int x;
+ for(int i=0; i < 10; ++i) {
+ static int y;
+ }
+}
+both 'x' and 'y' will be allocated in the same place, which is also
+where 'f' is also allocated.
+
+ Statements may also be declared static, in which case they are run at
+the place where the enclosing function or structure is defined.
+Declarations or statements not enclosed in a function or structure
+definition are already at the top level, so static modifiers are
+meaningless. A warning is given in such a case.
+
+ Since structures can have static fields, it is not always clear for a
+qualified name whether the qualifier is a variable or a type. For
+instance, in:
+
+struct A {
+ static int x;
+}
+pair A;
+
+int y=A.x;
+does the 'A' in 'A.x' refer to the structure or to the pair variable.
+It is the convention in Asymptote that, if there is a non-function
+variable with the same name as the qualifier, the qualifier refers to
+that variable, and not to the type. This is regardless of what fields
+the variable actually possesses.
+
+
+File: asymptote.info, Node: LaTeX usage, Next: Base modules, Prev: Programming, Up: Top
+
+7 'LaTeX' usage
+***************
+
+'Asymptote' comes with a convenient 'LaTeX' style file 'asymptote.sty'
+(v1.33 or later required) that makes 'LaTeX' 'Asymptote'-aware.
+Entering 'Asymptote' code directly into the 'LaTeX' source file, at the
+point where it is needed, keeps figures organized and avoids the need to
+invent new file names for each figure. Simply add the line
+'\usepackage{asymptote}' at the beginning of your file and enclose your
+'Asymptote' code within a '\begin{asy}...\end{asy}' environment. As
+with the 'LaTeX' 'comment' environment, the '\end{asy}' command must
+appear on a line by itself, with no trailing commands/comments. A blank
+line is not allowed after '\begin{asy}'.
+
+ The sample 'LaTeX' file below, named 'latexusage.tex', can be run as
+follows:
+latex latexusage
+asy latexusage-*.asy
+latex latexusage
+
+or
+pdflatex latexusage
+asy latexusage-*.asy
+pdflatex latexusage
+To switch between using inline Asymptote code with 'latex' and
+'pdflatex' you may first need to remove the files 'latexusage-*.tex'.
+
+ An even better method for processing a 'LaTeX' file with embedded
+'Asymptote' code is to use the 'latexmk' utility from
+ <http://mirror.ctan.org/support/latexmk/>
+after putting the contents of
+<https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/latexmkrc>
+in a file 'latexmkrc' in the same directory. The command
+latexmk -pdf latexusage
+will then call 'Asymptote' automatically, recompiling only the figures
+that have changed. Since each figure is compiled in a separate system
+process, this method also tends to use less memory. To store the
+figures in a separate directory named 'asy', one can define
+\def\asydir{asy}
+ in 'latexusage.tex' and put the contents of
+<http://sourceforge.net/p/asymptote/code/HEAD/tree/trunk/asymptote/doc/latexmkrc_asydir>
+in a file 'latexmkrc' in the same directory. External 'Asymptote' code
+in 'filename.asy' should be included with
+\asyinclude[<options>]{<filename.asy>}
+so that 'latexmk' will recognize when the code is changed. Note that
+'latemk' requires 'perl', available from <http://www.perl.org/>.
+
+ One can specify 'width', 'height', 'keepAspect', 'viewportwidth',
+'viewportheight', 'attach', and 'inline'. 'keyval'-style options to the
+'asy' and 'asyinclude' environments. Three-dimensional PRC files may
+either be embedded within the page (the default) or attached as
+annotated (but printable) attachments, using the 'attach' option and the
+'attachfile2' (or older 'attachfile') 'LaTeX' package. The 'inline'
+option generates inline 'LaTeX' code instead of EPS or PDF files. This
+makes 2D LaTeX symbols visible to the '\begin{asy}...\end{asy}'
+environment. In this mode, Asymptote correctly aligns 2D LaTeX symbols
+defined outside of '\begin{asy}...\end{asy}', but treats their size as
+zero; an optional second string can be given to 'Label' to provide an
+estimate of the unknown label size.
+
+ Note that if the 'latex' TeX engine is used with the 'inline' option,
+labels might not show up in DVI viewers that cannot handle raw
+'PostScript' code. One can use 'dvips'/'dvipdf' to produce
+'PostScript'/PDF output (we recommend using the modified version of
+'dvipdf' in the 'Asymptote' patches directory, which accepts the 'dvips
+-z' hyperdvi option).
+
+ Here now is 'latexusage.tex':
+\documentclass[12pt]{article}
+
+% Use this form to include EPS (latex) or PDF (pdflatex) files:
+%\usepackage{asymptote}
+
+% Use this form with latex or pdflatex to include inline LaTeX code by default:
+\usepackage[inline]{asymptote}
+
+% Use this form with latex or pdflatex to create PDF attachments by default:
+%\usepackage[attach]{asymptote}
+
+% Enable this line to support the attach option:
+%\usepackage[dvips]{attachfile2}
+
+\begin{document}
+
+% Optional subdirectory for latex files (no spaces):
+\def\asylatexdir{}
+% Optional subdirectory for asy files (no spaces):
+\def\asydir{}
+
+\begin{asydef}
+// Global Asymptote definitions can be put here.
+import three;
+usepackage("bm");
+texpreamble("\def\V#1{\bm{#1}}");
+// One can globally override the default toolbar settings here:
+// settings.toolbar=true;
+\end{asydef}
+
+Here is a venn diagram produced with Asymptote, drawn to width 4cm:
+
+\def\A{A}
+\def\B{\V{B}}
+
+%\begin{figure}
+\begin{center}
+\begin{asy}
+size(4cm,0);
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+fill(c1,colour1);
+fill(c2,colour2);
+
+picture intersection=new picture;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+//draw("$\A$",box,z1); // Requires [inline] package option.
+//draw(Label("$\B$","$B$"),box,z2); // Requires [inline] package option.
+draw("$A$",box,z1);
+draw("$\V{B}$",box,z2);
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
+
+shipout(bbox(0.25cm));
+\end{asy}
+%\caption{Venn diagram}\label{venn}
+\end{center}
+%\end{figure}
+
+Each graph is drawn in its own environment. One can specify the width
+and height to \LaTeX\ explicitly. This 3D example can be viewed
+interactively either with Adobe Reader or Asymptote's fast OpenGL-based
+renderer. To support {\tt latexmk}, 3D figures should specify
+\verb+inline=true+. It is sometimes desirable to embed 3D files as annotated
+attachments; this requires the \verb+attach=true+ option as well as the
+\verb+attachfile2+ \LaTeX\ package.
+\begin{center}
+\begin{asy}[height=4cm,inline=true,attach=false,viewportwidth=\linewidth]
+currentprojection=orthographic(5,4,2);
+draw(unitcube,blue);
+label("$V-E+F=2$",(0,1,0.5),3Y,blue+fontsize(17pt));
+\end{asy}
+\end{center}
+
+One can also scale the figure to the full line width:
+\begin{center}
+\begin{asy}[width=\the\linewidth,inline=true]
+pair z0=(0,0);
+pair z1=(2,0);
+pair z2=(5,0);
+pair zf=z1+0.75*(z2-z1);
+
+draw(z1--z2);
+dot(z1,red+0.15cm);
+dot(z2,darkgreen+0.3cm);
+label("$m$",z1,1.2N,red);
+label("$M$",z2,1.5N,darkgreen);
+label("$\hat{\ }$",zf,0.2*S,fontsize(24pt)+blue);
+
+pair s=-0.2*I;
+draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
+s=-0.5*I;
+draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
+s=-0.95*I;
+draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
+\end{asy}
+\end{center}
+\end{document}
+[latexusage]
+
+File: asymptote.info, Node: Base modules, Next: Options, Prev: LaTeX usage, Up: Top
+
+8 Base modules
+**************
+
+'Asymptote' currently ships with the following base modules:
+
+* Menu:
+
+* plain:: Default 'Asymptote' base file
+* simplex:: Linear programming: simplex method
+* math:: Extend 'Asymptote''s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded PDF and MPEG movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with 'Asymptote'
+* MetaPost:: 'MetaPost' compatibility routines
+* unicode:: Accept 'unicode' (UTF-8) characters
+* latin1:: Accept 'ISO 8859-1' characters
+* babel:: Interface to 'LaTeX' 'babel' package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your PDF files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* smoothcontour3:: Smooth implicit surfaces
+* slopefield:: Slope fields
+* ode:: Ordinary differential equations
+
+
+File: asymptote.info, Node: plain, Next: simplex, Prev: Base modules, Up: Base modules
+
+8.1 'plain'
+===========
+
+This is the default 'Asymptote' base file, which defines key parts of
+the drawing language (such as the 'picture' structure).
+
+ By default, an implicit 'private import plain;' occurs before
+translating a file and before the first command given in interactive
+mode. This also applies when translating files for module definitions
+(except when translating 'plain', of course). This means that the types
+and functions defined in 'plain' are accessible in almost all
+'Asymptote' code. Use the '-noautoplain' command-line option to disable
+this feature.
+
+
+File: asymptote.info, Node: simplex, Next: math, Prev: plain, Up: Base modules
+
+8.2 'simplex'
+=============
+
+This package solves the two-variable linear programming problem using
+the simplex method. It is used by the module 'plain' for automatic
+sizing of pictures.
+
+
+File: asymptote.info, Node: math, Next: interpolate, Prev: simplex, Up: Base modules
+
+8.3 'math'
+==========
+
+This package extends 'Asymptote''s mathematical capabilities with useful
+functions such as
+
+'void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen);'
+ draw the visible portion of the (infinite) line going through 'P'
+ and 'Q', without altering the size of picture 'pic', using pen 'p'.
+
+'real intersect(triple P, triple Q, triple n, triple Z);'
+ returns the intersection time of the extension of the line segment
+ 'PQ' with the plane perpendicular to 'n' and passing through 'Z'.
+
+'triple intersectionpoint(triple n0, triple P0, triple n1, triple P1);'
+ Return any point on the intersection of the two planes with normals
+ 'n0' and 'n1' passing through points 'P0' and 'P1', respectively.
+ If the planes are parallel, return '(infinity,infinity,infinity)'.
+
+'pair[] quarticroots(real a, real b, real c, real d, real e);'
+ returns the four complex roots of the quartic equation
+ ax^4+bx^3+cx^2+dx+e=0.
+
+'pair[][] fft(pair[][] a, int sign=1)'
+ returns the two-dimensional Fourier transform of a using the given
+ 'sign'.
+
+'real time(path g, real x, int n=0)'
+ returns the 'n'th intersection time of path 'g' with the vertical
+ line through x.
+
+'real time(path g, explicit pair z, int n=0)'
+ returns the 'n'th intersection time of path 'g' with the horizontal
+ line through '(0,z.y)'.
+
+'real value(path g, real x, int n=0)'
+ returns the 'n'th 'y' value of 'g' at 'x'.
+
+'real value(path g, explicit pair z, int n=0)'
+ returns the 'n'th 'x' value of 'g' at 'y=z.y'.
+
+'real slope(path g, real x, int n=0)'
+ returns the 'n'th slope of 'g' at 'x'.
+
+'real slope(path g, explicit pair z, int n=0)'
+ returns the 'n'th slope of 'g' at 'y=z.y'.
+
+ int[][] segment(bool[] b) returns the indices of consecutive
+ true-element segments of bool[] 'b'.
+
+'real[] partialsum(real[] a)'
+ returns the partial sums of a real array 'a'.
+
+'real[] partialsum(real[] a, real[] dx)'
+ returns the partial 'dx'-weighted sums of a real array 'a'.
+
+'bool increasing(real[] a, bool strict=false)'
+ returns, if 'strict=false', whether 'i > j' implies 'a[i] >= a[j]',
+ or if 'strict=true', whether 'i > j' implies implies 'a[i] > a[j]'.
+
+'int unique(real[] a, real x)'
+ if the sorted array 'a' does not contain 'x', insert it
+ sequentially, returning the index of 'x' in the resulting array.
+
+'bool lexorder(pair a, pair b)'
+ returns the strict lexicographical partial order of 'a' and 'b'.
+
+'bool lexorder(triple a, triple b)'
+ returns the strict lexicographical partial order of 'a' and 'b'.
+
+
+File: asymptote.info, Node: interpolate, Next: geometry, Prev: math, Up: Base modules
+
+8.4 'interpolate'
+=================
+
+This module implements Lagrange, Hermite, and standard cubic spline
+interpolation in 'Asymptote', as illustrated in the example
+'interpolate1.asy'.
+
+
+File: asymptote.info, Node: geometry, Next: trembling, Prev: interpolate, Up: Base modules
+
+8.5 'geometry'
+==============
+
+This module, written by Philippe Ivaldi, provides an extensive set of
+geometry routines, including 'perpendicular' symbols and a 'triangle'
+structure. Link to the documentation for the 'geometry' module are
+posted here: <http://asymptote.sourceforge.net/links.html>, including an
+extensive set of examples,
+<http://www.piprime.fr/files/asymptote/geometry/>, and an index:
+ <http://www.piprime.fr/files/asymptote/geometry/modules/geometry.asy.index.type.html>
+
+
+File: asymptote.info, Node: trembling, Next: stats, Prev: geometry, Up: Base modules
+
+8.6 'trembling'
+===============
+
+This module, written by Philippe Ivaldi and illustrated in the example
+'floatingdisk.asy', allows one to draw wavy lines, as if drawn by hand.
+
+
+File: asymptote.info, Node: stats, Next: patterns, Prev: trembling, Up: Base modules
+
+8.7 'stats'
+===========
+
+This package implements a Gaussian random number generator and a
+collection of statistics routines, including 'histogram' and
+'leastsquares'.
+
+
+File: asymptote.info, Node: patterns, Next: markers, Prev: stats, Up: Base modules
+
+8.8 'patterns'
+==============
+
+This package implements 'Postscript' tiling patterns and includes
+several convenient pattern generation routines.
+
+
+File: asymptote.info, Node: markers, Next: tree, Prev: patterns, Up: Base modules
+
+8.9 'markers'
+=============
+
+This package implements specialized routines for marking paths and
+angles. The principal mark routine provided by this package is
+markroutine markinterval(int n=1, frame f, bool rotated=false);
+which centers 'n' copies of frame 'f' within uniformly space intervals
+in arclength along the path, optionally rotated by the angle of the
+local tangent.
+
+ The 'marker' (*note marker::) routine can be used to construct new
+markers from these predefined frames:
+
+frame stickframe(int n=1, real size=0, pair space=0, real angle=0,
+ pair offset=0, pen p=currentpen);
+frame circlebarframe(int n=1, real barsize=0,
+ real radius=0,real angle=0,
+ pair offset=0, pen p=currentpen,
+ filltype filltype=NoFill, bool above=false);
+frame crossframe(int n=3, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+frame tildeframe(int n=1, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+
+ For convenience, this module also constructs the markers
+'StickIntervalMarker', 'CrossIntervalMarker', 'CircleBarIntervalMarker',
+and 'TildeIntervalMarker' from the above frames. The example
+'markers1.asy' illustrates the use of these markers:
+
+
+ [markers1]
+
+ This package also provides a routine for marking an angle AOB:
+void markangle(picture pic=currentpicture, Label L="",
+ int n=1, real radius=0, real space=0,
+ pair A, pair O, pair B, arrowbar arrow=None,
+ pen p=currentpen, margin margin=NoMargin,
+ marker marker=nomarker);
+as illustrated in the example 'markers2.asy'.
+
+
+ [markers2]
+
+
+File: asymptote.info, Node: tree, Next: binarytree, Prev: markers, Up: Base modules
+
+8.10 'tree'
+===========
+
+This package implements an example of a dynamic binary search tree.
+
+
+File: asymptote.info, Node: binarytree, Next: drawtree, Prev: tree, Up: Base modules
+
+8.11 'binarytree'
+=================
+
+This module can be used to draw an arbitrary binary tree and includes an
+input routine for the special case of a binary search tree, as
+illustrated in the example 'binarytreetest.asy':
+import binarytree;
+
+picture pic,pic2;
+
+binarytree bt=binarytree(1,2,4,nil,5,nil,nil,0,nil,nil,3,6,nil,nil,7);
+draw(pic,bt,condensed=false);
+
+binarytree st=searchtree(10,5,2,1,3,4,7,6,8,9,15,13,12,11,14,17,16,18,19);
+draw(pic2,st,blue,condensed=true);
+
+add(pic.fit(),(0,0),10N);
+add(pic2.fit(),(0,0),10S);
+
+
+ [binarytreetest]
+
+
+File: asymptote.info, Node: drawtree, Next: syzygy, Prev: binarytree, Up: Base modules
+
+8.12 'drawtree'
+===============
+
+This is a simple tree drawing module used by the example 'treetest.asy'.
+
+
+File: asymptote.info, Node: syzygy, Next: feynman, Prev: drawtree, Up: Base modules
+
+8.13 'syzygy'
+=============
+
+This module automates the drawing of braids, relations, and syzygies,
+along with the corresponding equations, as illustrated in the example
+'knots.asy'.
+
+
+File: asymptote.info, Node: feynman, Next: roundedpath, Prev: syzygy, Up: Base modules
+
+8.14 'feynman'
+==============
+
+This package, contributed by Martin Wiebusch, is useful for drawing
+Feynman diagrams, as illustrated by the examples 'eetomumu.asy' and
+'fermi.asy'.
+
+
+File: asymptote.info, Node: roundedpath, Next: animation, Prev: feynman, Up: Base modules
+
+8.15 'roundedpath'
+==================
+
+This package, contributed by Stefan Knorr, is useful for rounding the
+sharp corners of paths, as illustrated in the example file
+'roundpath.asy'.
+
+
+File: asymptote.info, Node: animation, Next: embed, Prev: roundedpath, Up: Base modules
+
+8.16 'animation'
+================
+
+This module allows one to generate animations, as illustrated by the
+files 'wheel.asy', 'wavepacket.asy', and 'cube.asy' in the 'animations'
+subdirectory of the examples directory. These animations use the
+'ImageMagick' 'convert' program to merge multiple images into a GIF or
+MPEG movie.
+
+ The related 'animate' module, derived from the 'animation' module,
+generates higher-quality portable clickable PDF movies, with optional
+controls. This requires installing the package
+ <http://mirror.ctan.org/macros/latex/contrib/animate/animate.sty>
+(version 2007/11/30 or later) in a new directory 'animate' in the local
+'LaTeX' directory (for example, in
+'/usr/local/share/texmf/tex/latex/animate'). On 'UNIX' systems, one
+must then execute the command 'texhash'.
+
+ The example 'pdfmovie.asy' in the 'animations' directory, along with
+the slide presentations 'slidemovies.asy' and 'intro.asy', illustrate
+the use of embedded PDF movies. The examples 'inlinemovie.tex' and
+'inlinemovie3.tex' show how to generate and embed PDF movies directly
+within a 'LaTeX' file (*note LaTeX usage::). The member function
+string pdf(fit fit=NoBox, real delay=animationdelay, string options="",
+ bool keep=settings.keep, bool multipage=true);
+of the 'animate' structure accepts any of the 'animate.sty' options, as
+described here:
+ <http://mirror.ctan.org/macros/latex/contrib/animate/doc/animate.pdf>
+
+
+File: asymptote.info, Node: embed, Next: slide, Prev: animation, Up: Base modules
+
+8.17 'embed'
+============
+
+This module provides an interface to the 'LaTeX' package (included with
+'MikTeX')
+ <http://mirror.ctan.org/macros/latex/contrib/media9>
+for embedding movies, sounds, and 3D objects into a PDF document.
+
+ A more portable method for embedding movie files, which should work
+on any platform and does not require the 'media9' package, is provided
+by using the 'external' module instead of 'embed'.
+
+ Examples of the above two interfaces is provided in the file
+'embeddedmovie.asy' and 'externalmovie.asy' in the 'animations'
+subdirectory of the examples directory. For a higher quality embedded
+movie generated directly by 'Asymptote', use the 'animate' module along
+with the 'animate.sty' package to embed a portable PDF animation (*note
+animate::).
+
+ An example of embedding 'U3D' code is provided in the file
+'embeddedu3d.asy'.
+
+
+File: asymptote.info, Node: slide, Next: MetaPost, Prev: embed, Up: Base modules
+
+8.18 'slide'
+============
+
+This package provides a simple yet high-quality facility for making
+presentation slides, including portable embedded PDF animations (see the
+file 'slidemovies.asy'). A simple example is provided in the file
+'slidedemo.asy'.
+
+
+File: asymptote.info, Node: MetaPost, Next: unicode, Prev: slide, Up: Base modules
+
+8.19 'MetaPost'
+===============
+
+This package provides some useful routines to help 'MetaPost' users
+migrate old 'MetaPost' code to 'Asymptote'. Further contributions here
+are welcome.
+
+ Unlike 'MetaPost', 'Asymptote' does not implicitly solve linear
+equations and therefore does not have the notion of a 'whatever'
+unknown. The routine 'extension' (*note extension::) provides a useful
+replacement for a common use of 'whatever': finding the intersection
+point of the lines through 'P', 'Q' and 'p', 'q'. For less common
+occurrences of 'whatever', one can use the built-in explicit linear
+equation solver 'solve' instead.
+
+
+File: asymptote.info, Node: unicode, Next: latin1, Prev: MetaPost, Up: Base modules
+
+8.20 'unicode'
+==============
+
+Import this package at the beginning of the file to instruct 'LaTeX' to
+accept 'unicode' (UTF-8) standardized international characters. To use
+Cyrillic fonts, you will need to change the font encoding:
+import unicode;
+texpreamble("\usepackage{mathtext}\usepackage[russian]{babel}");
+defaultpen(font("T2A","cmr","m","n"));
+Support for Chinese, Japanese, and Korean fonts is provided by the CJK
+package:
+ <http://mirror.ctan.org/languages/chinese/CJK/>
+The following commands enable the CJK song family (within a label, you
+can also temporarily switch to another family, say kai, by prepending
+'"\CJKfamily{kai}"' to the label string):
+texpreamble("\usepackage{CJK}
+\AtBeginDocument{\begin{CJK*}{GBK}{song}}
+\AtEndDocument{\clearpage\end{CJK*}}");
+
+
+File: asymptote.info, Node: latin1, Next: babel, Prev: unicode, Up: Base modules
+
+8.21 'latin1'
+=============
+
+If you don't have 'LaTeX' support for 'unicode' installed, you can
+enable support for Western European languages (ISO 8859-1) by importing
+the module 'latin1'. This module can be used as a template for
+providing support for other ISO 8859 alphabets.
+
+
+File: asymptote.info, Node: babel, Next: labelpath, Prev: latin1, Up: Base modules
+
+8.22 'babel'
+============
+
+This module implements the 'LaTeX' 'babel' package in 'Asymptote'. For
+example:
+import babel;
+babel("german");
+
+
+File: asymptote.info, Node: labelpath, Next: labelpath3, Prev: babel, Up: Base modules
+
+8.23 'labelpath'
+================
+
+This module uses the 'PSTricks' 'pstextpath' macro to fit labels along a
+path (properly kerned, as illustrated in the example file
+'curvedlabel.asy'), using the command
+void labelpath(picture pic=currentpicture, Label L, path g,
+ string justify=Centered, pen p=currentpen);
+Here 'justify' is one of 'LeftJustified', 'Centered', or
+'RightJustified'. The x component of a shift transform applied to the
+Label is interpreted as a shift along the curve, whereas the y component
+is interpreted as a shift away from the curve. All other Label
+transforms are ignored. This package requires the 'latex' tex engine
+and inherits the limitations of the 'PSTricks' '\pstextpath' macro.
+
+
+File: asymptote.info, Node: labelpath3, Next: annotate, Prev: labelpath, Up: Base modules
+
+8.24 'labelpath3'
+=================
+
+This module, contributed by Jens Schwaiger, implements a 3D version of
+'labelpath' that does not require the 'PSTricks' package. An example is
+provided in 'curvedlabel3.asy'.
+
+
+File: asymptote.info, Node: annotate, Next: CAD, Prev: labelpath3, Up: Base modules
+
+8.25 'annotate'
+===============
+
+This module supports PDF annotations for viewing with 'Adobe Reader',
+via the function
+void annotate(picture pic=currentpicture, string title, string text,
+ pair position);
+Annotations are illustrated in the example file 'annotation.asy'.
+Currently, annotations are only implemented for the 'latex' (default)
+and 'tex' TeX engines.
+
+
+File: asymptote.info, Node: CAD, Next: graph, Prev: annotate, Up: Base modules
+
+8.26 'CAD'
+==========
+
+This package, contributed by Mark Henning, provides basic pen
+definitions and measurement functions for simple 2D CAD drawings
+according to DIN 15. It is documented separately, in the file
+'CAD.pdf'.
+
+
+File: asymptote.info, Node: graph, Next: palette, Prev: CAD, Up: Base modules
+
+8.27 'graph'
+============
+
+This package implements two-dimensional linear and logarithmic graphs,
+including automatic scale and tick selection (with the ability to
+override manually). A graph is a 'guide' (that can be drawn with the
+draw command, with an optional legend) constructed with one of the
+following routines:
+
+ * guide graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture 'pic'
+ (*note automatic scaling::) of the function 'f' on the interval
+ ['T'('a'),'T'('b')], sampling at 'n' points evenly spaced in
+ ['a','b'], optionally restricted by the bool3 function 'cond' on
+ ['a','b']. If 'cond' is:
+ * 'true', the point is added to the existing guide;
+ * 'default', the point is added to a new guide;
+ * 'false', the point is omitted and a new guide is begun.
+ The points are connected using the interpolation specified by
+ 'join':
+
+ * 'operator --' (linear interpolation; the abbreviation
+ 'Straight' is also accepted);
+
+ * 'operator ..' (piecewise Bezier cubic spline interpolation;
+ the abbreviation 'Spline' is also accepted);
+
+ * 'Hermite' (standard cubic spline interpolation using boundary
+ condition 'notaknot', 'natural', 'periodic', 'clamped(real
+ slopea, real slopeb)'), or 'monotonic'. The abbreviation
+ 'Hermite' is equivalent to 'Hermite(notaknot)' for nonperiodic
+ data and 'Hermite(periodic)' for periodic data).
+
+ * guide graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ bool3 cond(real), interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture 'pic' of
+ the parametrized function ('x'(t),'y'(t)) for t in the interval
+ ['T'('a'),'T'('b')], sampling at 'n' points evenly spaced in
+ ['a','b'], optionally restricted by the bool3 function 'cond' on
+ ['a','b'], using the given interpolation type.
+
+ * guide graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture 'pic' of
+ the parametrized function 'z'(t) for t in the interval
+ ['T'('a'),'T'('b')], sampling at 'n' points evenly spaced in
+ ['a','b'], optionally restricted by the bool3 function 'cond' on
+ ['a','b'], using the given interpolation type.
+
+ * guide graph(picture pic=currentpicture, pair[] z,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond,
+ interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture 'pic' of
+ the elements of the array 'z', optionally restricted to those
+ indices for which the elements of the boolean array 'cond' are
+ 'true', using the given interpolation type.
+
+ * guide graph(picture pic=currentpicture, real[] x, real[] y,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, real[] x, real[] y,
+ bool3[] cond, interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture 'pic' of
+ the elements of the arrays ('x','y'), optionally restricted to
+ those indices for which the elements of the boolean array 'cond'
+ are 'true', using the given interpolation type.
+
+ * guide polargraph(picture pic=currentpicture, real f(real), real a,
+ real b, int n=ngraph, interpolate join=operator --);
+
+ Returns a polar-coordinate graph using the scaling information for
+ picture 'pic' of the function 'f' on the interval ['a','b'],
+ sampling at 'n' evenly spaced points, with the given interpolation
+ type.
+
+ * guide polargraph(picture pic=currentpicture, real[] r, real[] theta,
+ interpolate join=operator--);
+ Returns a polar-coordinate graph using the scaling information for
+ picture 'pic' of the elements of the arrays ('r','theta'), using
+ the given interpolation type.
+
+
+
+
+ An axis can be drawn on a picture with one of the following commands:
+
+ * void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
+
+ Draw an x axis on picture 'pic' from x='xmin' to x='xmax' using pen
+ 'p', optionally labelling it with Label 'L'. The relative label
+ location along the axis (a real number from [0,1]) defaults to 1
+ (*note Label::), so that the label is drawn at the end of the axis.
+ An infinite value of 'xmin' or 'xmax' specifies that the
+ corresponding axis limit will be automatically determined from the
+ picture limits. The optional 'arrow' argument takes the same
+ values as in the 'draw' command (*note arrows::). The axis is
+ drawn before any existing objects in 'pic' unless 'above=true'.
+ The axis placement is determined by one of the following 'axis'
+ types:
+
+ 'YZero(bool extend=true)'
+ Request an x axis at y=0 (or y=1 on a logarithmic axis)
+ extending to the full dimensions of the picture, unless
+ 'extend'=false.
+
+ 'YEquals(real Y, bool extend=true)'
+ Request an x axis at y='Y' extending to the full dimensions of
+ the picture, unless 'extend'=false.
+
+ 'Bottom(bool extend=false)'
+ Request a bottom axis.
+
+ 'Top(bool extend=false)'
+ Request a top axis.
+
+ 'BottomTop(bool extend=false)'
+ Request a bottom and top axis.
+
+ Custom axis types can be created by following the examples in the
+ module 'graph.asy'. One can easily override the default values for
+ the standard axis types:
+ import graph;
+
+ YZero=new axis(bool extend=true) {
+ return new void(picture pic, axisT axis) {
+ real y=pic.scale.x.scale.logarithmic ? 1 : 0;
+ axis.value=I*pic.scale.y.T(y);
+ axis.position=1;
+ axis.side=right;
+ axis.align=2.5E;
+ axis.value2=Infinity;
+ axis.extend=extend;
+ };
+ };
+ YZero=YZero();
+
+
+ The default tick option is 'NoTicks'. The options 'LeftTicks',
+ 'RightTicks', or 'Ticks' can be used to draw ticks on the left,
+ right, or both sides of the path, relative to the direction in
+ which the path is drawn. These tick routines accept a number of
+ optional arguments:
+ ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen);
+
+ If any of these parameters are omitted, reasonable defaults will be
+ chosen:
+ 'Label format'
+ override the default tick label format ('defaultformat',
+ initially "$%.4g$"), rotation, pen, and alignment (for
+ example, 'LeftSide', 'Center', or 'RightSide') relative to the
+ axis. To enable 'LaTeX' math mode fonts, the format string
+ should begin and end with '$' *note format::. If the format
+ string is 'trailingzero', trailing zeros will be added to the
+ tick labels; if the format string is '"%"', the tick label
+ will be suppressed;
+ 'ticklabel'
+ is a function 'string(real x)' returning the label (by
+ default, format(format.s,x)) for each major tick value 'x';
+ 'bool beginlabel'
+ include the first label;
+ 'bool endlabel'
+ include the last label;
+ 'int N'
+ when automatic scaling is enabled (the default; *note
+ automatic scaling::), divide a linear axis evenly into this
+ many intervals, separated by major ticks; for a logarithmic
+ axis, this is the number of decades between labelled ticks;
+ 'int n'
+ divide each interval into this many subintervals, separated by
+ minor ticks;
+ 'real Step'
+ the tick value spacing between major ticks (if 'N'='0');
+ 'real step'
+ the tick value spacing between minor ticks (if 'n'='0');
+ 'bool begin'
+ include the first major tick;
+ 'bool end'
+ include the last major tick;
+ 'tickmodifier modify;'
+ an optional function that takes and returns a 'tickvalue'
+ structure having real[] members 'major' and 'minor' consisting
+ of the tick values (to allow modification of the automatically
+ generated tick values);
+ 'real Size'
+ the size of the major ticks (in 'PostScript' coordinates);
+ 'real size'
+ the size of the minor ticks (in 'PostScript' coordinates);
+ 'bool extend;'
+ extend the ticks between two axes (useful for drawing a grid
+ on the graph);
+ 'pen pTick'
+ an optional pen used to draw the major ticks;
+ 'pen ptick'
+ an optional pen used to draw the minor ticks.
+
+ For convenience, the predefined tickmodifiers 'OmitTick(... real[]
+ x)', 'OmitTickInterval(real a, real b)', and
+ 'OmitTickIntervals(real[] a, real[] b)' can be used to remove
+ specific auto-generated ticks and their labels. The
+ 'OmitFormat(string s=defaultformat ... real[] x)' ticklabel can be
+ used to remove specific tick labels but not the corresponding
+ ticks. The tickmodifier 'NoZero' is an abbreviation for
+ 'OmitTick(0)' and the ticklabel 'NoZeroFormat' is an abbrevation
+ for 'OmitFormat(0)'.
+
+ It is also possible to specify custom tick locations with
+ 'LeftTicks', 'RightTicks', and 'Ticks' by passing explicit real
+ arrays 'Ticks' and (optionally) 'ticks' containing the locations of
+ the major and minor ticks, respectively:
+ ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+
+ * void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false,
+ bool autorotate=true);
+
+ Draw a y axis on picture 'pic' from y='ymin' to y='ymax' using pen
+ 'p', optionally labelling it with a Label 'L' that is autorotated
+ unless 'autorotate=false'. The relative location of the label (a
+ real number from [0,1]) defaults to 1 (*note Label::). An infinite
+ value of 'ymin' or 'ymax' specifies that the corresponding axis
+ limit will be automatically determined from the picture limits.
+ The optional 'arrow' argument takes the same values as in the
+ 'draw' command (*note arrows::). The axis is drawn before any
+ existing objects in 'pic' unless 'above=true'. The tick type is
+ specified by 'ticks' and the axis placement is determined by one of
+ the following 'axis' types:
+
+ 'XZero(bool extend=true)'
+ Request a y axis at x=0 (or x=1 on a logarithmic axis)
+ extending to the full dimensions of the picture, unless
+ 'extend'=false.
+
+ 'XEquals(real X, bool extend=true)'
+ Request a y axis at x='X' extending to the full dimensions of
+ the picture, unless 'extend'=false.
+
+ 'Left(bool extend=false)'
+ Request a left axis.
+
+ 'Right(bool extend=false)'
+ Request a right axis.
+
+ 'LeftRight(bool extend=false)'
+ Request a left and right axis.
+
+ * For convenience, the functions
+ void xequals(picture pic=currentpicture, Label L="", real x,
+ bool extend=false, real ymin=-infinity, real ymax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+ and
+ void yequals(picture pic=currentpicture, Label L="", real y,
+ bool extend=false, real xmin=-infinity, real xmax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+ can be respectively used to call 'yaxis' and 'xaxis' with the
+ appropriate axis types 'XEquals(x,extend)' and 'YEquals(y,extend)'.
+ This is the recommended way of drawing vertical or horizontal lines
+ and axes at arbitrary locations.
+
+ * void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
+ bool extend=true,
+ pair min=(-infinity,-infinity), pair max=(infinity,infinity),
+ pen p=currentpen, arrowbar arrow=None, bool above=false);
+ This convenience routine draws both x and y axes on picture 'pic'
+ from 'min' to 'max', with optional labels 'xlabel' and 'ylabel' and
+ any arrows specified by 'arrow'. The axes are drawn on top of
+ existing objects in 'pic' only if 'above=true'.
+
+ * void axis(picture pic=currentpicture, Label L="", path g,
+ pen p=currentpen, ticks ticks, ticklocate locate,
+ arrowbar arrow=None, int[] divisor=new int[],
+ bool above=false, bool opposite=false);
+
+ This routine can be used to draw on picture 'pic' a general axis
+ based on an arbitrary path 'g', using pen 'p'. One can optionally
+ label the axis with Label 'L' and add an arrow 'arrow'. The tick
+ type is given by 'ticks'. The optional integer array 'divisor'
+ specifies what tick divisors to try in the attempt to produce
+ uncrowded tick labels. A 'true' value for the flag 'opposite'
+ identifies an unlabelled secondary axis (typically drawn opposite a
+ primary axis). The axis is drawn before any existing objects in
+ 'pic' unless 'above=true'. The tick locator 'ticklocate' is
+ constructed by the routine
+ ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, pair dir(real)=zero);
+ where 'a' and 'b' specify the respective tick values at
+ 'point(g,0)' and 'point(g,length(g))', 'S' specifies the
+ autoscaling transformation, the function 'real time(real v)'
+ returns the time corresponding to the value 'v', and 'pair dir(real
+ t)' returns the absolute tick direction as a function of 't' (zero
+ means draw the tick perpendicular to the axis).
+
+ * These routines are useful for manually putting ticks and labels on
+ axes (if the variable 'Label' is given as the 'Label' argument, the
+ 'format' argument will be used to format a string based on the tick
+ location):
+ void xtick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void xtick(picture pic=currentpicture, Label L="", real x,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void ytick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void ytick(picture pic=currentpicture, Label L="", real y,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void tick(picture pic=currentpicture, pair z,
+ pair dir, real size=Ticksize, pen p=currentpen);
+ void labelx(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=S, string format="", pen p=currentpen);
+ void labelx(picture pic=currentpicture, Label L="", real x,
+ align align=S, string format="", pen p=currentpen);
+ void labelx(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen);
+ void labely(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=W, string format="", pen p=currentpen);
+ void labely(picture pic=currentpicture, Label L="", real y,
+ align align=W, string format="", pen p=currentpen);
+ void labely(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen);
+
+ Here are some simple examples of two-dimensional graphs:
+
+ 1. This example draws a textbook-style graph of y= exp(x), with the y
+ axis starting at y=0:
+ import graph;
+ size(150,0);
+
+ real f(real x) {return exp(x);}
+ pair F(real x) {return (x,f(x));}
+
+ xaxis("$x$");
+ yaxis("$y$",0);
+
+ draw(graph(f,-4,2,operator ..),red);
+
+ labely(1,E);
+ label("$e^x$",F(1),SE);
+
+
+ [exp]
+
+ 2. The next example draws a scientific-style graph with a legend. The
+ position of the legend can be adjusted either explicitly or by
+ using the graphical user interface
+ '<http://asymptote.sourceforge.net/gallery/.pdf>.asy' (*note
+ GUI::). If an 'UnFill(real xmargin=0, real ymargin=xmargin)' or
+ 'Fill(pen)' option is specified to 'add', the legend will obscure
+ any underlying objects. Here we illustrate how to clip the portion
+ of the picture covered by a label:
+
+ import graph;
+
+ size(400,200,IgnoreAspect);
+
+ real Sin(real t) {return sin(2pi*t);}
+ real Cos(real t) {return cos(2pi*t);}
+
+ draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+ draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+ label("LABEL",point(0),UnFill(1mm));
+
+ add(legend(),point(E),20E,UnFill);
+
+ [lineargraph0]
+
+ To specify a fixed size for the graph proper, use 'attach':
+ import graph;
+
+ size(250,200,IgnoreAspect);
+
+ real Sin(real t) {return sin(2pi*t);}
+ real Cos(real t) {return cos(2pi*t);}
+
+ draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+ draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+ label("LABEL",point(0),UnFill(1mm));
+
+ attach(legend(),truepoint(E),20E,UnFill);
+
+ A legend can have multiple entries per line:
+ import graph;
+ size(8cm,6cm,IgnoreAspect);
+
+ typedef real realfcn(real);
+ realfcn F(real p) {
+ return new real(real x) {return sin(p*x);};
+ };
+
+ for(int i=1; i < 5; ++i)
+ draw(graph(F(i*pi),0,1),Pen(i),
+ "$\sin("+(i == 1 ? "" : (string) i)+"\pi x)$");
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+ attach(legend(2),(point(S).x,truepoint(S).y),10S,UnFill);
+
+ [legend]
+
+ 3. This example draws a graph of one array versus another (both of the
+ same size) using custom tick locations and a smaller font size for
+ the tick labels on the y axis.
+ import graph;
+
+ size(200,150,IgnoreAspect);
+
+ real[] x={0,1,2,3};
+ real[] y=x^2;
+
+ draw(graph(x,y),red);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,
+ RightTicks(Label(fontsize(8pt)),new real[]{0,4,9}));
+
+ [datagraph]
+
+ 4. This example shows how to graph columns of data read from a file.
+ import graph;
+
+ size(200,150,IgnoreAspect);
+
+ file in=input("filegraph.dat").line();
+ real[][] a=in;
+ a=transpose(a);
+
+ real[] x=a[0];
+ real[] y=a[1];
+
+ draw(graph(x,y),red);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks);
+
+ [filegraph]
+
+ 5. The next example draws two graphs of an array of coordinate pairs,
+ using frame alignment and data markers. In the left-hand graph,
+ the markers, constructed with
+ marker marker(path g, markroutine markroutine=marknodes,
+ pen p=currentpen, filltype filltype=NoFill,
+ bool above=true);
+ using the path 'unitcircle' (*note filltype::), are drawn below
+ each node. Any frame can be converted to a marker, using
+ marker marker(frame f, markroutine markroutine=marknodes,
+ bool above=true);
+ In the right-hand graph, the unit n-sided regular polygon
+ 'polygon(int n)' and the unit n-point cyclic cross 'cross(int n,
+ bool round=true, real r=0)' (where 'r' is an optional "inner"
+ radius) are used to build a custom marker frame. Here
+ 'markuniform(bool centered=false, int n, bool rotated=false)' adds
+ this frame at 'n' uniformly spaced points along the arclength of
+ the path, optionally rotated by the angle of the local tangent to
+ the path (if centered is true, the frames will be centered within
+ 'n' evenly spaced arclength intervals). Alternatively, one can use
+ markroutine 'marknodes' to request that the marks be placed at each
+ Bezier node of the path, or markroutine 'markuniform(pair z(real
+ t), real a, real b, int n)' to place marks at points 'z(t)' for n
+ evenly spaced values of 't' in '[a,b]'.
+
+ These markers are predefined:
+ marker[] Mark={
+ marker(scale(circlescale)*unitcircle),
+ marker(polygon(3)),marker(polygon(4)),
+ marker(polygon(5)),marker(invert*polygon(3)),
+ marker(cross(4)),marker(cross(6))
+ };
+
+ marker[] MarkFill={
+ marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
+ marker(polygon(4),Fill),marker(polygon(5),Fill),
+ marker(invert*polygon(3),Fill)
+ };
+
+ The example also illustrates the 'errorbar' routines:
+
+ void errorbars(picture pic=currentpicture, pair[] z, pair[] dp,
+ pair[] dm={}, bool[] cond={}, pen p=currentpen,
+ real size=0);
+
+ void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpx, real[] dpy, real[] dmx={}, real[] dmy={},
+ bool[] cond={}, pen p=currentpen, real size=0);
+
+ Here, the positive and negative extents of the error are given by
+ the absolute values of the elements of the pair array 'dp' and the
+ optional pair array 'dm'. If 'dm' is not specified, the positive
+ and negative extents of the error are assumed to be equal.
+ import graph;
+
+ picture pic;
+ real xsize=200, ysize=140;
+ size(pic,xsize,ysize,IgnoreAspect);
+
+ pair[] f={(5,5),(50,20),(90,90)};
+ pair[] df={(0,0),(5,7),(0,5)};
+
+ errorbars(pic,f,df,red);
+ draw(pic,graph(pic,f),"legend",
+ marker(scale(0.8mm)*unitcircle,red,FillDraw(blue),above=false));
+
+ scale(pic,true);
+
+ xaxis(pic,"$x$",BottomTop,LeftTicks);
+ yaxis(pic,"$y$",LeftRight,RightTicks);
+ add(pic,legend(pic),point(pic,NW),20SE,UnFill);
+
+ picture pic2;
+ size(pic2,xsize,ysize,IgnoreAspect);
+
+ frame mark;
+ filldraw(mark,scale(0.8mm)*polygon(6),green,green);
+ draw(mark,scale(0.8mm)*cross(6),blue);
+
+ draw(pic2,graph(pic2,f),marker(mark,markuniform(5)));
+
+ scale(pic2,true);
+
+ xaxis(pic2,"$x$",BottomTop,LeftTicks);
+ yaxis(pic2,"$y$",LeftRight,RightTicks);
+
+ yequals(pic2,55.0,red+Dotted);
+ xequals(pic2,70.0,red+Dotted);
+
+ // Fit pic to W of origin:
+ add(pic.fit(),(0,0),W);
+
+ // Fit pic2 to E of (5mm,0):
+ add(pic2.fit(),(5mm,0),E);
+
+
+ [errorbars]
+
+ 6. A custom mark routine can be also be specified:
+ import graph;
+
+ size(200,100,IgnoreAspect);
+
+ markroutine marks() {
+ return new void(picture pic=currentpicture, frame f, path g) {
+ path p=scale(1mm)*unitcircle;
+ for(int i=0; i <= length(g); ++i) {
+ pair z=point(g,i);
+ frame f;
+ if(i % 4 == 0) {
+ fill(f,p);
+ add(pic,f,z);
+ } else {
+ if(z.y > 50) {
+ pic.add(new void(frame F, transform t) {
+ path q=shift(t*z)*p;
+ unfill(F,q);
+ draw(F,q);
+ });
+ } else {
+ draw(f,p);
+ add(pic,f,z);
+ }
+ }
+ }
+ };
+ }
+
+ pair[] f={(5,5),(40,20),(55,51),(90,30)};
+
+ draw(graph(f),marker(marks()));
+
+ scale(true);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks);
+
+ [graphmarkers]
+
+ 7. This example shows how to label an axis with arbitrary strings.
+ import graph;
+
+ size(400,150,IgnoreAspect);
+
+ real[] x=sequence(12);
+ real[] y=sin(2pi*x/12);
+
+ scale(false);
+
+ string[] month={"Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"};
+
+ draw(graph(x,y),red,MarkFill[0]);
+
+ xaxis(BottomTop,LeftTicks(new string(real x) {
+ return month[round(x % 12)];}));
+ yaxis("$y$",LeftRight,RightTicks(4));
+
+ [monthaxis]
+
+ 8. The next example draws a graph of a parametrized curve. The calls
+ to
+ xlimits(picture pic=currentpicture, real min=-infinity,
+ real max=infinity, bool crop=NoCrop);
+ and the analogous function 'ylimits' can be uncommented to set the
+ respective axes limits for picture 'pic' to the specified 'min' and
+ 'max' values. Alternatively, the function
+ void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop);
+ can be used to limit the axes to the box having opposite vertices
+ at the given pairs). Existing objects in picture 'pic' will be
+ cropped to lie within the given limits if 'crop'='Crop'. The
+ function 'crop(picture pic)' can be used to crop a graph to the
+ current graph limits.
+ import graph;
+
+ size(0,200);
+
+ real x(real t) {return cos(2pi*t);}
+ real y(real t) {return sin(2pi*t);}
+
+ draw(graph(x,y,0,1));
+
+ //limits((0,-1),(1,0),Crop);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+
+
+ [parametricgraph]
+
+ The next example illustrates how one can extract a common axis
+ scaling factor.
+ import graph;
+
+ axiscoverage=0.9;
+ size(200,IgnoreAspect);
+
+ real[] x={-1e-11,1e-11};
+ real[] y={0,1e6};
+
+ real xscale=round(log10(max(x)));
+ real yscale=round(log10(max(y)))-1;
+
+ draw(graph(x*10^(-xscale),y*10^(-yscale)),red);
+
+ xaxis("$x/10^{"+(string) xscale+"}$",BottomTop,LeftTicks);
+ yaxis("$y/10^{"+(string) yscale+"}$",LeftRight,RightTicks(trailingzero));
+
+ [scaledgraph]
+
+ Axis scaling can be requested and/or automatic selection of the
+ axis limits can be inhibited with one of these 'scale' routines:
+ void scale(picture pic=currentpicture, scaleT x, scaleT y);
+
+ void scale(picture pic=currentpicture, bool xautoscale=true,
+ bool yautoscale=xautoscale, bool zautoscale=yautoscale);
+
+ This sets the scalings for picture 'pic'. The 'graph' routines
+ accept an optional 'picture' argument for determining the
+ appropriate scalings to use; if none is given, it uses those set
+ for 'currentpicture'.
+
+ Two frequently used scaling routines 'Linear' and 'Log' are
+ predefined in 'graph'.
+
+ All picture coordinates (including those in paths and those given
+ to the 'label' and 'limits' functions) are always treated as linear
+ (post-scaled) coordinates. Use
+ pair Scale(picture pic=currentpicture, pair z);
+ to convert a graph coordinate into a scaled picture coordinate.
+
+ The x and y components can be individually scaled using the
+ analogous routines
+ real ScaleX(picture pic=currentpicture, real x);
+ real ScaleY(picture pic=currentpicture, real y);
+
+ The predefined scaling routines can be given two optional boolean
+ arguments: 'automin=false' and 'automax=automin'. These default to
+ 'false' but can be respectively set to 'true' to enable automatic
+ selection of "nice" axis minimum and maximum values. The 'Linear'
+ scaling can also take as optional final arguments a multiplicative
+ scaling factor and intercept (e.g. for a depth axis, 'Linear(-1)'
+ requests axis reversal).
+
+ For example, to draw a log/log graph of a function, use
+ 'scale(Log,Log)':
+ import graph;
+
+ size(200,200,IgnoreAspect);
+
+ real f(real t) {return 1/t;}
+
+ scale(Log,Log);
+
+ draw(graph(f,0.1,10));
+
+ //limits((1,0.1),(10,0.5),Crop);
+
+ dot(Label("(3,5)",align=S),Scale((3,5)));
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks);
+
+
+ [loggraph]
+
+ By extending the ticks, one can easily produce a logarithmic grid:
+ import graph;
+ size(200,200,IgnoreAspect);
+
+ real f(real t) {return 1/t;}
+
+ scale(Log,Log);
+ draw(graph(f,0.1,10),red);
+ pen thin=linewidth(0.5*linewidth());
+ xaxis("$x$",BottomTop,LeftTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+ yaxis("$y$",LeftRight,RightTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+
+
+
+ [loggrid]
+
+ One can also specify custom tick locations and formats for
+ logarithmic axes:
+ import graph;
+
+ size(300,175,IgnoreAspect);
+ scale(Log,Log);
+ draw(graph(identity,5,20));
+ xlimits(5,20);
+ ylimits(1,100);
+ xaxis("$M/M_\odot$",BottomTop,LeftTicks(DefaultFormat,
+ new real[] {6,10,12,14,16,18}));
+ yaxis("$\nu_{\rm upp}$ [Hz]",LeftRight,RightTicks(DefaultFormat));
+
+
+ [logticks]
+
+ It is easy to draw logarithmic graphs with respect to other bases:
+ import graph;
+ size(200,IgnoreAspect);
+
+ // Base-2 logarithmic scale on y-axis:
+
+ real log2(real x) {static real log2=log(2); return log(x)/log2;}
+ real pow2(real x) {return 2^x;}
+
+ scaleT yscale=scaleT(log2,pow2,logarithmic=true);
+ scale(Linear,yscale);
+
+ real f(real x) {return 1+x^2;}
+
+ draw(graph(f,-4,4));
+
+ yaxis("$y$",ymin=1,ymax=f(5),RightTicks(Label(Fill(white))),EndArrow);
+ xaxis("$x$",xmin=-5,xmax=5,LeftTicks,EndArrow);
+
+ [log2graph]
+
+ Here is an example of "broken" linear x and logarithmic y axes that
+ omit the segments [3,8] and [100,1000], respectively. In the case
+ of a logarithmic axis, the break endpoints are automatically
+ rounded to the nearest integral power of the base.
+ import graph;
+
+ size(200,150,IgnoreAspect);
+
+ // Break the x axis at 3; restart at 8:
+ real a=3, b=8;
+
+ // Break the y axis at 100; restart at 1000:
+ real c=100, d=1000;
+
+ scale(Broken(a,b),BrokenLog(c,d));
+
+ real[] x={1,2,4,6,10};
+ real[] y=x^4;
+
+ draw(graph(x,y),red,MarkFill[0]);
+
+ xaxis("$x$",BottomTop,LeftTicks(Break(a,b)));
+ yaxis("$y$",LeftRight,RightTicks(Break(c,d)));
+
+ label(rotate(90)*Break,(a,point(S).y));
+ label(rotate(90)*Break,(a,point(N).y));
+ label(Break,(point(W).x,ScaleY(c)));
+ label(Break,(point(E).x,ScaleY(c)));
+
+
+ [brokenaxis]
+
+ 9. 'Asymptote' can draw secondary axes with the routines
+ picture secondaryX(picture primary=currentpicture, void f(picture));
+ picture secondaryY(picture primary=currentpicture, void f(picture));
+
+ In this example, 'secondaryY' is used to draw a secondary linear y
+ axis against a primary logarithmic y axis:
+ import graph;
+ texpreamble("\def\Arg{\mathop {\rm Arg}\nolimits}");
+
+ size(10cm,5cm,IgnoreAspect);
+
+ real ampl(real x) {return 2.5/sqrt(1+x^2);}
+ real phas(real x) {return -atan(x)/pi;}
+
+ scale(Log,Log);
+ draw(graph(ampl,0.01,10));
+ ylimits(0.001,100);
+
+ xaxis("$\omega\tau_0$",BottomTop,LeftTicks);
+ yaxis("$|G(\omega\tau_0)|$",Left,RightTicks);
+
+ picture q=secondaryY(new void(picture pic) {
+ scale(pic,Log,Linear);
+ draw(pic,graph(pic,phas,0.01,10),red);
+ ylimits(pic,-1.0,1.5);
+ yaxis(pic,"$\Arg G/\pi$",Right,red,
+ LeftTicks("$% #.1f$",
+ begin=false,end=false));
+ yequals(pic,1,Dotted);
+ });
+ label(q,"(1,0)",Scale(q,(1,0)),red);
+ add(q);
+
+
+ [Bode]
+
+ A secondary logarithmic y axis can be drawn like this:
+ import graph;
+
+ size(9cm,6cm,IgnoreAspect);
+ string data="secondaryaxis.csv";
+
+ file in=input(data).line().csv();
+
+ string[] titlelabel=in;
+ string[] columnlabel=in;
+
+ real[][] a=in;
+ a=transpose(a);
+ real[] t=a[0], susceptible=a[1], infectious=a[2], dead=a[3], larvae=a[4];
+ real[] susceptibleM=a[5], exposed=a[6],infectiousM=a[7];
+
+ scale(true);
+
+ draw(graph(t,susceptible,t >= 10 & t <= 15));
+ draw(graph(t,dead,t >= 10 & t <= 15),dashed);
+
+ xaxis("Time ($\tau$)",BottomTop,LeftTicks);
+ yaxis(Left,RightTicks);
+
+ picture secondary=secondaryY(new void(picture pic) {
+ scale(pic,Linear(true),Log(true));
+ draw(pic,graph(pic,t,infectious,t >= 10 & t <= 15),red);
+ yaxis(pic,Right,red,LeftTicks(begin=false,end=false));
+ });
+
+ add(secondary);
+ label(shift(5mm*N)*"Proportion of crows",point(NW),E);
+
+
+ [secondaryaxis]
+
+ 10. Here is a histogram example, which uses the 'stats' module.
+ import graph;
+ import stats;
+
+ size(400,200,IgnoreAspect);
+
+ int n=10000;
+ real[] a=new real[n];
+ for(int i=0; i < n; ++i) a[i]=Gaussrand();
+
+ draw(graph(Gaussian,min(a),max(a)),blue);
+
+ // Optionally calculate "optimal" number of bins a la Shimazaki and Shinomoto.
+ int N=bins(a);
+
+ histogram(a,min(a),max(a),N,normalize=true,low=0,lightred,black,bars=false);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$dP/dx$",LeftRight,RightTicks(trailingzero));
+
+
+ [histogram]
+
+ 11. Here is an example of reading column data in from a file and a
+ least-squares fit, using the 'stats' module.
+ size(400,200,IgnoreAspect);
+
+ import graph;
+ import stats;
+
+ file fin=input("leastsquares.dat").line();
+
+ real[][] a=fin;
+ a=transpose(a);
+
+ real[] t=a[0], rho=a[1];
+
+ // Read in parameters from the keyboard:
+ //real first=getreal("first");
+ //real step=getreal("step");
+ //real last=getreal("last");
+
+ real first=100;
+ real step=50;
+ real last=700;
+
+ // Remove negative or zero values of rho:
+ t=rho > 0 ? t : null;
+ rho=rho > 0 ? rho : null;
+
+ scale(Log(true),Linear(true));
+
+ int n=step > 0 ? ceil((last-first)/step) : 0;
+
+ real[] T,xi,dxi;
+
+ for(int i=0; i <= n; ++i) {
+ real first=first+i*step;
+ real[] logrho=(t >= first & t <= last) ? log(rho) : null;
+ real[] logt=(t >= first & t <= last) ? -log(t) : null;
+
+ if(logt.length < 2) break;
+
+ // Fit to the line logt=L.m*logrho+L.b:
+ linefit L=leastsquares(logt,logrho);
+
+ T.push(first);
+ xi.push(L.m);
+ dxi.push(L.dm);
+ }
+
+ draw(graph(T,xi),blue);
+ errorbars(T,xi,dxi,red);
+
+ crop();
+
+ ylimits(0);
+
+ xaxis("$T$",BottomTop,LeftTicks);
+ yaxis("$\xi$",LeftRight,RightTicks);
+
+ [leastsquares]
+
+ 12. Here is an example that illustrates the general 'axis' routine.
+ import graph;
+ size(0,100);
+
+ path g=ellipse((0,0),1,2);
+
+ scale(true);
+
+ axis(Label("C",align=10W),g,LeftTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path h=(0,0)--max(abs(max(g)),abs(min(g)))*dir(v);
+ return intersect(g,h)[0];}));
+
+ [generalaxis]
+
+ 13. To draw a vector field of 'n' arrows evenly spaced along the
+ arclength of a path, use the routine
+ picture vectorfield(path vector(real), path g, int n, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow);
+ as illustrated in this simple example of a flow field:
+ import graph;
+ defaultpen(1.0);
+
+ size(0,150,IgnoreAspect);
+
+ real arrowsize=4mm;
+ real arrowlength=2arrowsize;
+
+ typedef path vector(real);
+
+ // Return a vector interpolated linearly between a and b.
+ vector vector(pair a, pair b) {
+ return new path(real x) {
+ return (0,0)--arrowlength*interp(a,b,x);
+ };
+ }
+
+ real f(real x) {return 1/x;}
+
+ real epsilon=0.5;
+ path g=graph(f,epsilon,1/epsilon);
+
+ int n=3;
+ draw(g);
+ xaxis("$x$");
+ yaxis("$y$");
+
+ add(vectorfield(vector(W,W),g,n,true));
+ add(vectorfield(vector(NE,NW),(0,0)--(point(E).x,0),n,true));
+ add(vectorfield(vector(NE,NE),(0,0)--(0,point(N).y),n,true));
+
+
+ [flow]
+
+ 14. To draw a vector field of 'nx'\times'ny' arrows in 'box(a,b)', use
+ the routine
+ picture vectorfield(path vector(pair), pair a, pair b,
+ int nx=nmesh, int ny=nx, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(a,b,nx,ny),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar arrow=Arrow, margin margin=PenMargin)
+ as illustrated in this example:
+ import graph;
+ size(100);
+
+ pair a=(0,0);
+ pair b=(2pi,2pi);
+
+ path vector(pair z) {return (0,0)--(sin(z.x),cos(z.y));}
+
+ add(vectorfield(vector,a,b));
+
+ [vectorfield]
+
+ 15. The following scientific graphs, which illustrate many features of
+ 'Asymptote''s graphics routines, were generated from the examples
+ 'diatom.asy' and 'westnile.asy', using the comma-separated data in
+ 'diatom.csv' and 'westnile.csv'.
+
+
+ [diatom]
+
+ [westnile]
+
+
+File: asymptote.info, Node: palette, Next: three, Prev: graph, Up: Base modules
+
+8.28 'palette'
+==============
+
+'Asymptote' can also generate color density images and palettes. The
+following palettes are predefined in 'palette.asy':
+
+'pen[] Grayscale(int NColors=256)'
+ a grayscale palette;
+
+'pen[] Rainbow(int NColors=32766)'
+ a rainbow spectrum;
+
+'pen[] BWRainbow(int NColors=32761)'
+ a rainbow spectrum tapering off to black/white at the ends;
+
+'pen[] BWRainbow2(int NColors=32761)'
+ a double rainbow palette tapering off to black/white at the ends,
+ with a linearly scaled intensity.
+
+'pen[] Wheel(int NColors=32766)'
+ a full color wheel palette;
+
+'pen[] Gradient(int NColors=256 ... pen[] p)'
+ a palette varying linearly over the specified array of pens, using
+ NColors in each interpolation interval;
+
+ The function 'cmyk(pen[] Palette)' may be used to convert any of
+these palettes to the CMYK colorspace.
+
+ A color density plot using palette 'palette' can be generated from a
+function 'f'(x,y) and added to a picture 'pic':
+bounds image(picture pic=currentpicture, real f(real, real),
+ range range=Full, pair initial, pair final,
+ int nx=ngraph, int ny=nx, pen[] palette, bool antialias=false)
+ The function 'f' will be sampled at 'nx' and 'ny' evenly spaced
+points over a rectangle defined by the points 'initial' and 'final',
+respecting the current graphical scaling of 'pic'. The color space is
+scaled according to the z axis scaling (*note automatic scaling::). A
+bounds structure for the function values is returned:
+struct bounds {
+ real min;
+ real max;
+ // Possible tick intervals:
+ int[] divisor;
+}
+This information can be used for generating an optional palette bar.
+The palette color space corresponds to a range of values specified by
+the argument 'range', which can be 'Full', 'Automatic', or an explicit
+range 'Range(real min, real max)'. Here 'Full' specifies a range
+varying from the minimum to maximum values of the function over the
+sampling interval, while 'Automatic' selects "nice" limits. The example
+'imagecontour.asy' illustrates how level sets (contour lines) can be
+drawn on a color density plot (*note contour::).
+
+ A color density plot can also be generated from an explicit real[][]
+array 'data':
+bounds image(picture pic=currentpicture, real[][] f, range range=Full,
+ pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+If the initial point is to the left and below the final point, by
+default the array indices are interpreted according to the Cartesian
+convention (first index: x, second index: y) rather than the usual
+matrix convention (first index: -y, second index: x).
+
+ To construct an image from an array of irregularly spaced points and
+an array of values 'f' at these points, use one of the routines
+bounds image(picture pic=currentpicture, pair[] z, real[] f,
+ range range=Full, pen[] palette)
+bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f,
+ range range=Full, pen[] palette)
+
+ An optionally labelled palette bar may be generated with the routine
+void palette(picture pic=currentpicture, Label L="", bounds bounds,
+ pair initial, pair final, axis axis=Right, pen[] palette,
+ pen p=currentpen, paletteticks ticks=PaletteTicks,
+ bool copy=true, bool antialias=false);
+ The color space of 'palette' is taken to be over bounds 'bounds' with
+scaling given by the z scaling of 'pic'. The palette orientation is
+specified by 'axis', which may be one of 'Right', 'Left', 'Top', or
+'Bottom'. The bar is drawn over the rectangle from 'initial' to
+'final'. The argument 'paletteticks' is a special tick type (*note
+ticks::) that takes the following arguments:
+paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ pen pTick=nullpen, pen ptick=nullpen);
+
+ The image and palette bar can be fit to a frame and added and
+optionally aligned to a picture at the desired location:
+
+size(12cm,12cm);
+
+import graph;
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+real[][] v=new real[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=sin(i*ninv)*cos(j*ninv);
+
+pen[] Palette=BWRainbow();
+
+picture bar;
+
+bounds range=image(v,(0,0),(1,1),Palette);
+palette(bar,"$A$",range,(0,0),(0.5cm,8cm),Right,Palette,
+ PaletteTicks("$%+#.1f$"));
+add(bar.fit(),point(E),30E);
+
+ [image]
+
+ Here is an example that uses logarithmic scaling of the function
+values:
+
+import graph;
+import palette;
+
+size(10cm,10cm,IgnoreAspect);
+
+real f(real x, real y) {
+ return 0.9*pow10(2*sin(x/5+2*y^0.25)) + 0.1*(1+cos(10*log(y)));
+}
+
+scale(Linear,Log,Log);
+
+pen[] Palette=BWRainbow();
+
+bounds range=image(f,Automatic,(0,1),(100,100),nx=200,Palette);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,(0,200),(100,250),Top,Palette,
+ PaletteTicks(ptick=linewidth(0.5*linewidth())));
+
+
+
+ [logimage]
+
+ One can also draw an image directly from a two-dimensional pen array
+or a function 'pen f(int, int)':
+void image(picture pic=currentpicture, pen[][] data,
+ pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+void image(picture pic=currentpicture, pen f(int, int), int width, int height,
+ pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool antialias=false);
+as illustrated in the following examples:
+
+size(200);
+
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+pen[][] v=new pen[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=rgb(0.5*(1+sin(i*ninv)),0.5*(1+cos(j*ninv)),0);
+
+image(v,(0,0),(1,1));
+
+
+ [penimage]
+
+import palette;
+
+size(200);
+
+real fracpart(real x) {return (x-floor(x));}
+
+pair pws(pair z) {
+ pair w=(z+exp(pi*I/5)/0.9)/(1+z/0.9*exp(-pi*I/5));
+ return exp(w)*(w^3-0.5*I);
+}
+
+int N=512;
+
+pair a=(-1,-1);
+pair b=(0.5,0.5);
+real dx=(b-a).x/N;
+real dy=(b-a).y/N;
+
+pen f(int u, int v) {
+ pair z=a+(u*dx,v*dy);
+ pair w=pws(z);
+ real phase=degrees(w,warn=false);
+ real modulus=w == 0 ? 0: fracpart(log(abs(w)));
+ return hsv(phase,1,sqrt(modulus));
+}
+
+image(f,N,N,(0,0),(300,300),antialias=true);
+
+ [penfunctionimage]
+
+ For convenience, the module 'palette' also defines functions that may
+be used to construct a pen array from a given function and palette:
+pen[] palette(real[] f, pen[] palette);
+pen[][] palette(real[][] f, pen[] palette);
+
+
+File: asymptote.info, Node: three, Next: obj, Prev: palette, Up: Base modules
+
+8.29 'three'
+============
+
+This module fully extends the notion of guides and paths in 'Asymptote'
+to three dimensions. It introduces the new types guide3, path3, and
+surface. Guides in three dimensions are specified with the same syntax
+as in two dimensions except that triples '(x,y,z)' are used in place of
+pairs '(x,y)' for the nodes and direction specifiers. This
+generalization of John Hobby's spline algorithm is shape-invariant under
+three-dimensional rotation, scaling, and shifting, and reduces in the
+planar case to the two-dimensional algorithm used in 'Asymptote',
+'MetaPost', and 'MetaFont' [cf. J. C. Bowman, Proceedings in Applied
+Mathematics and Mechanics, 7:1, 2010021-2010022 (2007)].
+
+ For example, a unit circle in the XY plane may be filled and drawn
+like this:
+import three;
+
+size(100);
+
+path3 g=(1,0,0)..(0,1,0)..(-1,0,0)..(0,-1,0)..cycle;
+draw(g);
+draw(O--Z,red+dashed,Arrow3);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
+
+ [unitcircle3]
+and then distorted into a saddle:
+import three;
+
+size(100,0);
+path3 g=(1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle;
+draw(g);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
+
+ [saddle]
+
+ Module 'three' provides constructors for converting two-dimensional
+paths to three-dimensional ones, and vice-versa:
+path3 path3(path p, triple plane(pair)=XYplane);
+path path(path3 p, pair P(triple)=xypart);
+
+ A Bezier surface, the natural two-dimensional generalization of
+Bezier curves, is defined in 'three_surface.asy' as a structure
+containing an array of Bezier patches. Surfaces may drawn with one of
+the routines
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen meshpen,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=nolight, string name="",
+ render render=defaultrender);
+
+ The parameters 'nu' and 'nv' specify the number of subdivisions for
+drawing optional mesh lines for each Bezier patch. The optional 'name'
+parameter is used as a prefix for naming the surface patches in the PRC
+model tree. Here material is a structure defined in 'three_light.asy':
+struct material {
+ pen[] p; // diffusepen,emissivepen,specularpen
+ real opacity;
+ real shininess;
+...
+}
+These material properties are used to implement 'OpenGL'-style lighting,
+based on the Phong-Blinn specular model. Sample Bezier surfaces are
+contained in the example files 'BezierSurface.asy', 'teapot.asy', and
+'parametricsurface.asy'. The structure 'render' contains specialized
+rendering options documented at the beginning of module 'three.asy'.
+
+ The examples 'elevation.asy' and 'sphericalharmonic.asy' illustrate
+how to draw a surface with patch-dependent colors. The examples
+'vertexshading.asy' and 'smoothelevation.asy' illustrate
+vertex-dependent colors, which is supported for both 'Asymptote''s
+native 'OpenGL' renderer and two-dimensional projections. Since the PRC
+output format does not currently support vertex shading of Bezier
+surfaces, PRC patches are shaded with the mean of the four vertex
+colors.
+
+ A surface can be constructed from a cyclic 'path3' with the
+constructor
+surface surface(path3 external, triple[] internal=new triple[],
+ pen[] colors=new pen[], bool3 planar=default);
+and then filled:
+draw(surface(unitsquare3,new triple[] {X,Y,Z,O}),red);
+draw(surface(O--X{Y}..Y{-X}--cycle,new triple[] {Z}),red);
+draw(surface(path3(polygon(5))),red,nolight);
+draw(surface(unitcircle3),red,nolight);
+draw(surface(unitcircle3,new pen[] {red,green,blue,black}),nolight);
+The first example draws a Bezier patch and the second example draws a
+Bezier triangle. The third and fourth examples are planar surfaces.
+The last example constructs a patch with vertex-specific colors. A
+three-dimensional planar surface in the plane 'plane' can be constructed
+from a two-dimensional cyclic path 'g' with the constructor
+surface surface(path p, triple plane(pair)=XYplane);
+and then filled:
+draw(surface((0,0)--E+2N--2E--E+N..0.2E..cycle),red);
+Planar Bezier surfaces patches are constructed using Orest Shardt's
+'bezulate' routine, which decomposes (possibly nonsimply connected)
+regions bounded (according to the 'zerowinding' fill rule) by simple
+cyclic paths (intersecting only at the endpoints) into subregions
+bounded by cyclic paths of length '4' or less.
+
+ A more efficient routine also exists for drawing tessellations
+composed of many 3D triangles, with specified vertices, and optional
+normals or vertex colors:
+void draw(picture pic=currentpicture, triple[] v, int[][] vi,
+ triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
+ int[][] pi={}, light light=currentlight);
+ Here, the triple array 'v' lists the distinct vertices, while the
+array 'vi' lists integer arrays of length 3 containing the indices of
+'v' corresponding to the vertices of each triangle. Similarly, the
+arguments 'n' and 'ni' contain optional normal data and 'p' and 'pi'
+contain optional pen vertex data. An example of this tessellation
+facility is given in 'triangles.asy'.
+
+ Arbitrary thick three-dimensional curves and line caps (which the
+'OpenGL' standard does not require implementations to provide) are
+constructed with
+tube tube(path3 p, real width, render render=defaultrender);
+this returns a tube structure representing a tube of diameter 'width'
+centered approximately on 'g'. The tube structure consists of a surface
+'s' and the actual tube center, path3 'center'. Drawing thick lines as
+tubes can be slow to render, especially with the 'Adobe Reader'
+renderer. The setting 'thick=false' can be used to disable this feature
+and force all lines to be drawn with 'linewidth(0)' (one pixel wide,
+regardless of the resolution). By default, mesh and contour lines in
+three-dimensions are always drawn thin, unless an explicit line width is
+given in the pen parameter or the setting 'thin' is set to 'false'. The
+pens 'thin()' and 'thick()' defined in 'plain_pens.asy' can also be used
+to override these defaults for specific draw commands.
+
+There are four choices for viewing 3D 'Asymptote' output:
+ 1. Use the native 'Asymptote' adaptive 'OpenGL'-based renderer (with
+ the command-line option '-V' and the default settings
+ 'outformat=""' and 'render=-1'). If you encounter warnings from
+ your graphics card driver, try specifying '-glOptions=-indirect' on
+ the command line. On 'UNIX' systems with graphics support for
+ multisampling, the sample width can be controlled with the setting
+ 'multisample'. An initial screen position can be specified with
+ the pair setting 'position', where negative values are interpreted
+ as relative to the corresponding maximum screen dimension. The
+ default settings
+ import settings;
+ leftbutton=new string[] {"rotate","zoom","shift","pan"};
+ middlebutton=new string[] {""};
+ rightbutton=new string[] {"zoom","rotateX","rotateY","rotateZ"};
+ wheelup=new string[] {"zoomin"};
+ wheeldown=new string[] {"zoomout"};
+ bind the mouse buttons as follows:
+ * Left: rotate
+ * Shift Left: zoom
+ * Ctrl Left: shift viewport
+ * Alt Left: pan
+ * Wheel Up: zoom in
+ * Wheel Down: zoom out
+ * Right: zoom
+ * Shift Right: rotate about the X axis
+ * Ctrl Right: rotate about the Y axis
+ * Alt Right: rotate about the Z axis
+
+ The keyboard shortcuts are:
+ * h: home
+ * f: toggle fitscreen
+ * x: spin about the X axis
+ * y: spin about the Y axis
+ * z: spin about the Z axis
+ * s: stop spinning
+ * m: rendering mode (solid/patch/mesh)
+ * e: export
+ * c: show camera parameters
+ * p: play animation
+ * r: reverse animation
+ * : step animation
+ * +: expand
+ * =: expand
+ * >: expand
+ * -: shrink
+ * _: shrink
+ * <: shrink
+ * q: exit
+ * Ctrl-q: exit
+
+ 2. Render the scene to a specified rasterized format 'outformat' at
+ the resolution of 'n' pixels per 'bp', as specified by the setting
+ 'render=n'. A negative value of 'n' is interpreted as '|2n|' for
+ EPS and PDF formats and '|n|' for other formats. The default value
+ of 'render' is -1. By default, the scene is internally rendered at
+ twice the specified resolution; this can be disabled by setting
+ 'antialias=1'. High resolution rendering is done by tiling the
+ image. If your graphics card allows it, the rendering can be made
+ more efficient by increasing the maximum tile size 'maxtile' to
+ your screen dimensions (indicated by 'maxtile=(0,0)'. If your
+ video card generates unwanted black stripes in the output, try
+ setting the horizontal and vertical components of 'maxtiles' to
+ something less than your screen dimensions. The tile size is also
+ limited by the setting 'maxviewport', which restricts the maximum
+ width and height of the viewport. On 'UNIX' systems some graphics
+ drivers support batch mode ('-noV') rendering in an iconified
+ window; this can be enabled with the setting 'iconify=true'. Some
+ (broken) 'UNIX' graphics drivers may require the command line
+ setting '-glOptions=-indirect', which requests (slower) indirect
+ rendering.
+
+ 3. Embed the 3D PRC format in a PDF file and view the resulting PDF
+ file with version '9.0' or later of 'Adobe Reader'. In addition to
+ the default 'settings.prc=true', this requires
+ 'settings.outformat="pdf"', which can be specified by the command
+ line option '-f pdf', put in the 'Asymptote' configuration file
+ (*note configuration file::), or specified in the script before
+ 'three.asy' (or 'graph3.asy') is imported. The 'media9' LaTeX
+ package is also required (*note embed::). The example 'pdb.asy'
+ illustrates how one can generate a list of predefined views (see
+ '100d.views'). A stationary preview image with a resolution of 'n'
+ pixels per 'bp' can be embedded with the setting 'render=n'; this
+ allows the file to be viewed with other 'PDF' viewers.
+ Alternatively, the file 'externalprc.tex' illustrates how the
+ resulting PRC and rendered image files can be extracted and
+ processed in a separate 'LaTeX' file. However, see *note LaTeX
+ usage:: for an easier way to embed three-dimensional 'Asymptote'
+ pictures within 'LaTeX'. For specialized applications where only
+ the raw PRC file is required, specify 'settings.outformat="prc"'.
+ The open-source PRC specification is available from
+ <http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/>.
+
+ 4. Project the scene to a two-dimensional vector (EPS or PDF) format
+ with 'render=0'. Only limited hidden surface removal facilities
+ are currently available with this approach (*note PostScript3D::).
+
+ Automatic picture sizing in three dimensions is accomplished with
+double deferred drawing. The maximal desired dimensions of the scene in
+each of the three dimensions can optionally be specified with the
+routine
+void size3(picture pic=currentpicture, real x, real y=x, real z=y,
+ bool keepAspect=pic.keepAspect);
+The resulting simplex linear programming problem is then solved to
+produce a 3D version of a frame (actually implemented as a 3D picture).
+The result is then fit with another application of deferred drawing to
+the viewport dimensions corresponding to the usual two-dimensional
+picture 'size' parameters. The global pair 'viewportmargin' may be used
+to add horizontal and vertical margins to the viewport dimensions.
+Alternatively, a minimum 'viewportsize' may be specified. A 3D picture
+'pic' can be explicitly fit to a 3D frame by calling
+frame pic.fit3(projection P=currentprojection);
+and then added to picture 'dest' about 'position' with
+void add(picture dest=currentpicture, frame src, triple position=(0,0,0));
+
+ For convenience, the 'three' module defines 'O=(0,0,0)', 'X=(1,0,0)',
+'Y=(0,1,0)', and 'Z=(0,0,1)', along with a unitcircle in the XY plane:
+path3 unitcircle3=X..Y..-X..-Y..cycle;
+
+ A general (approximate) circle can be drawn perpendicular to the
+direction 'normal' with the routine
+path3 circle(triple c, real r, triple normal=Z);
+
+ A circular arc centered at 'c' with radius 'r' from
+'c+r*dir(theta1,phi1)' to 'c+r*dir(theta2,phi2)', drawing
+counterclockwise relative to the normal vector
+'cross(dir(theta1,phi1),dir(theta2,phi2))' if 'theta2 > theta1' or if
+'theta2 == theta1' and 'phi2 >= phi1', can be constructed with
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O);
+ The normal must be explicitly specified if 'c' and the endpoints are
+colinear. If 'r' < 0, the complementary arc of radius '|r|' is
+constructed. For convenience, an arc centered at 'c' from triple 'v1'
+to 'v2' (assuming '|v2-c|=|v1-c|') in the direction CCW
+(counter-clockwise) or CW (clockwise) may also be constructed with
+path3 arc(triple c, triple v1, triple v2, triple normal=O,
+ bool direction=CCW);
+When high accuracy is needed, the routines 'Circle' and 'Arc' defined in
+'graph3' may be used instead. See *note GaussianSurface:: for an
+example of a three-dimensional circular arc.
+
+ The representation 'O--O+u--O+u+v--O+v--cycle' of the plane passing
+through point 'O' with normal 'cross(u,v)' is returned by
+path3 plane(triple u, triple v, triple O=O);
+ A three-dimensional box with opposite vertices at triples 'v1' and
+'v2' may be drawn with the function
+path3[] box(triple v1, triple v2);
+For example, a unit box is predefined as
+path3[] unitbox=box(O,(1,1,1));
+ 'Asymptote' also provides optimized definitions for the
+three-dimensional paths 'unitsquare3' and 'unitcircle3', along with the
+surfaces 'unitdisk', 'unitplane', 'unitcube', 'unitcylinder',
+'unitcone', 'unitsolidcone', 'unitfrustum(real t1, real t2)',
+'unitsphere', and 'unithemisphere'.
+
+These projections to two dimensions are predefined:
+'oblique'
+'oblique(real angle)'
+ The point '(x,y,z)' is projected to '(x-0.5z,y-0.5z)'. If an
+ optional real argument is given, the negative z axis is drawn at
+ this angle in degrees. The projection 'obliqueZ' is a synonym for
+ 'oblique'.
+
+'obliqueX'
+'obliqueX(real angle)'
+ The point '(x,y,z)' is projected to '(y-0.5x,z-0.5x)'. If an
+ optional real argument is given, the negative x axis is drawn at
+ this angle in degrees.
+
+'obliqueY'
+'obliqueY(real angle)'
+ The point '(x,y,z)' is projected to '(x+0.5y,z+0.5y)'. If an
+ optional real argument is given, the positive y axis is drawn at
+ this angle in degrees.
+
+'orthographic(triple camera, triple up=Z, triple target=O,
+ real zoom=1, pair viewportshift=0, bool showtarget=true,
+ bool center=false)'
+ This projects from three to two dimensions using the view as seen
+ at a point infinitely far away in the direction 'unit(camera)',
+ orienting the camera so that, if possible, the vector 'up' points
+ upwards. Parallel lines are projected to parallel lines. The
+ bounding volume is expanded to include 'target' if
+ 'showtarget=true'. If 'center=true', the target will be adjusted
+ to the center of the bounding volume.
+
+'orthographic(real x, real y, real z, triple up=Z, triple target=O,
+ real zoom=1, pair viewportshift=0, bool showtarget=true,
+ bool center=false)'
+ This is equivalent to
+ orthographic((x,y,z),up,target,zoom,viewportshift,showtarget,center)
+
+ The routine
+ triple camera(real alpha, real beta);
+ can be used to compute the camera position with the x axis below
+ the horizontal at angle 'alpha', the y axis below the horizontal at
+ angle 'beta', and the z axis up.
+
+'perspective(triple camera, triple up=Z, triple target=O,
+ real zoom=1, real angle=0, pair viewportshift=0,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=autoadjust)'
+ This projects from three to two dimensions, taking account of
+ perspective, as seen from the location 'camera' looking at
+ 'target', orienting the camera so that, if possible, the vector
+ 'up' points upwards. If 'render=0', projection of
+ three-dimensional cubic Bezier splines is implemented by
+ approximating a two-dimensional nonuniform rational B-spline
+ (NURBS) with a two-dimensional Bezier curve containing additional
+ nodes and control points. If 'autoadjust=true', the camera will
+ automatically be adjusted to lie outside the bounding volume for
+ all possible interactive rotations about 'target'. If
+ 'center=true', the target will be adjusted to the center of the
+ bounding volume.
+
+'perspective(real x, real y, real z, triple up=Z, triple target=O,
+ real zoom=1, real angle=0, pair viewportshift=0,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=autoadjust)'
+ This is equivalent to
+ perspective((x,y,z),up,target,zoom,angle,viewportshift,showtarget,
+ autoadjust,center)
+
+The default projection, 'currentprojection', is initially set to
+'perspective(5,4,2)'.
+
+ We also define standard orthographic views used in technical drawing:
+projection LeftView=orthographic(-X,showtarget=true);
+projection RightView=orthographic(X,showtarget=true);
+projection FrontView=orthographic(-Y,showtarget=true);
+projection BackView=orthographic(Y,showtarget=true);
+projection BottomView=orthographic(-Z,showtarget=true);
+projection TopView=orthographic(Z,showtarget=true);
+The function
+void addViews(picture dest=currentpicture, picture src,
+ projection[][] views=SixViewsUS,
+ bool group=true, filltype filltype=NoFill);
+adds to picture 'dest' an array of views of picture 'src' using the
+layout projection[][] 'views'. The default layout 'SixViewsUS' aligns
+the projection 'FrontView' below 'TopView' and above 'BottomView', to
+the right of 'LeftView' and left of 'RightView' and 'BackView'. The
+predefined layouts are:
+projection[][] ThreeViewsUS={{TopView},
+ {FrontView,RightView}};
+
+projection[][] SixViewsUS={{null,TopView},
+ {LeftView,FrontView,RightView,BackView},
+ {null,BottomView}};
+
+projection[][] ThreeViewsFR={{RightView,FrontView},
+ {null,TopView}};
+
+projection[][] SixViewsFR={{null,BottomView},
+ {RightView,FrontView,LeftView,BackView},
+ {null,TopView}};
+
+projection[][] ThreeViews={{FrontView,TopView,RightView}};
+
+projection[][] SixViews={{FrontView,TopView,RightView},
+ {BackView,BottomView,LeftView}};
+
+
+ A triple or path3 can be projected to a pair or path, with
+'project(triple, projection P=currentprojection)' or 'project(path3,
+projection P=currentprojection)'.
+
+ It is occasionally useful to be able to invert a projection, sending
+a pair 'z' onto the plane perpendicular to 'normal' and passing through
+'point':
+triple invert(pair z, triple normal, triple point,
+ projection P=currentprojection);
+A pair 'z' on the projection plane can be inverted to a triple with the
+routine
+triple invert(pair z, projection P=currentprojection);
+A pair direction 'dir' on the projection plane can be inverted to a
+triple direction relative to a point 'v' with the routine
+triple invert(pair dir, triple v, projection P=currentprojection).
+
+ Three-dimensional objects may be transformed with one of the
+following built-in transform3 types (the identity transformation is
+'identity4'):
+
+'shift(triple v)'
+ translates by the triple 'v';
+'xscale3(real x)'
+ scales by 'x' in the x direction;
+'yscale3(real y)'
+ scales by 'y' in the y direction;
+'zscale3(real z)'
+ scales by 'z' in the z direction;
+'scale3(real s)'
+ scales by 's' in the x, y, and z directions;
+'scale(real x, real y, real z)'
+ scales by 'x' in the x direction, by 'y' in the y direction, and by
+ 'z' in the z direction;
+'rotate(real angle, triple v)'
+ rotates by 'angle' in degrees about an axis 'v' through the origin;
+'rotate(real angle, triple u, triple v)'
+ rotates by 'angle' in degrees about the axis 'u--v';
+'reflect(triple u, triple v, triple w)'
+ reflects about the plane through 'u', 'v', and 'w'.
+
+ When not multiplied on the left by a transform3, three-dimensional
+TeX Labels are drawn as Bezier surfaces directly on the projection
+plane:
+void label(picture pic=currentpicture, Label L, triple position,
+ align align=NoAlign, pen p=currentpen,
+ light light=nolight, string name="",
+ render render=defaultrender, interaction interaction=
+ settings.autobillboard ? Billboard : Embedded)
+The optional 'name' parameter is used as a prefix for naming the label
+patches in the PRC model tree. The default interaction is 'Billboard',
+which means that labels are rotated interactively so that they always
+face the camera. The interaction 'Embedded' means that the label
+interacts as a normal '3D' surface, as illustrated in the example
+'billboard.asy'. Alternatively, a label can be transformed from the
+'XY' plane by an explicit transform3 or mapped to a specified
+two-dimensional plane with the predefined transform3 types 'XY', 'YZ',
+'ZX', 'YX', 'ZY', 'ZX'. There are also modified versions of these
+transforms that take an optional argument 'projection
+P=currentprojection' that rotate and/or flip the label so that it is
+more readable from the initial viewpoint.
+
+ A transform3 that projects in the direction 'dir' onto the plane with
+normal 'n' through point 'O' is returned by
+transform3 planeproject(triple n, triple O=O, triple dir=n);
+One can use
+triple normal(path3 p);
+to find the unit normal vector to a planar three-dimensional path 'p'.
+As illustrated in the example 'planeproject.asy', a transform3 that
+projects in the direction 'dir' onto the plane defined by a planar path
+'p' is returned by
+transform3 planeproject(path3 p, triple dir=normal(p));
+
+ The functions
+surface extrude(path p, triple axis=Z);
+surface extrude(Label L, triple axis=Z);
+return the surface obtained by extruding path 'p' or Label 'L' along
+'axis'.
+
+ Three-dimensional versions of the path functions 'length', 'size',
+'point', 'dir', 'accel', 'radius', 'precontrol', 'postcontrol',
+'arclength', 'arctime', 'reverse', 'subpath', 'intersect',
+'intersections', 'intersectionpoint', 'intersectionpoints', 'min',
+'max', 'cyclic', and 'straight' are also defined.
+
+ The routine
+real[] intersect(path3 p, surface s, real fuzz=-1);
+returns a real array of length 3 containing the intersection times, if
+any, of a path 'p' with a surface 's'. The routine
+real[][] intersections(path3 p, surface s, real fuzz=-1);
+returns all (unless there are infinitely many) intersection times of a
+path 'p' with a surface 's' as a sorted array of real arrays of length
+3, and
+triple[] intersectionpoints(path3 p, surface s, real fuzz=-1);
+returns the corresponding intersection points. Here, the computations
+are performed to the absolute error specified by 'fuzz', or if 'fuzz <
+0', to machine precision. The routine
+real orient(triple a, triple b, triple c, triple d);
+is a numerically robust computation of 'dot(cross(a-d,b-d),c-d)', which
+is the determinant
+|a.x a.y a.z 1|
+|b.x b.y b.z 1|
+|c.x c.y c.z 1|
+|d.x d.y d.z 1|
+ The result is negative (positive) if 'a', 'b', 'c' appear in
+counterclockwise (clockwise) order when viewed from 'd' or zero if all
+four points are coplanar.
+
+ The routine
+real insphere(triple a, triple b, triple c, triple d, triple e);
+returns a positive (negative) value if 'e' lies inside (outside) the
+sphere passing through points 'a,b,c,d' oriented so that
+'dot(cross(a-d,b-d),c-d)' is positive, or zero if all five points are
+cospherical. The value returned is the determinant
+|a.x a.y a.z a.x^2+a.y^2+a.z^2 1|
+|b.x b.y b.z b.x^2+b.y^2+b.z^2 1|
+|c.x c.y c.z c.x^2+c.y^2+c.z^2 1|
+|d.x d.y d.z d.x^2+d.y^2+d.z^2 1|
+|e.x e.y e.z e.x^2+e.y^2+e.z^2 1|
+
+ Here is an example showing all five guide3 connectors:
+import graph3;
+
+size(200);
+
+currentprojection=orthographic(500,-500,500);
+
+triple[] z=new triple[10];
+
+z[0]=(0,100,0); z[1]=(50,0,0); z[2]=(180,0,0);
+
+for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0,0);
+
+path3 p=z[0]..z[1]---z[2]::{Y}z[3]
+&z[3]..z[4]--z[5]::{Y}z[6]
+&z[6]::z[7]---z[8]..{Y}z[9];
+
+draw(p,grey+linewidth(4mm),currentlight);
+
+xaxis3(Label(XY()*"$x$",align=-3Y),red,above=true);
+yaxis3(Label(XY()*"$y$",align=-3X),red,above=true);
+
+ [join3]
+
+ Three-dimensional versions of bars or arrows can be drawn with one of
+the specifiers 'None', 'Blank', 'BeginBar3', 'EndBar3' (or equivalently
+'Bar3'), 'Bars3', 'BeginArrow3', 'MidArrow3', 'EndArrow3' (or
+equivalently 'Arrow3'), 'Arrows3', 'BeginArcArrow3', 'EndArcArrow3' (or
+equivalently 'ArcArrow3'), 'MidArcArrow3', and 'ArcArrows3'.
+Three-dimensional bars accept the optional arguments '(real size=0,
+triple dir=O)'. If 'size=O', the default bar length is used; if
+'dir=O', the bar is drawn perpendicular to the path and the initial
+viewing direction. The predefined three-dimensional arrowhead styles
+are 'DefaultHead3', 'HookHead3', 'TeXHead3'. Versions of the
+two-dimensional arrowheads lifted to three-dimensional space and aligned
+according to the initial viewpoint (or an optionally specified 'normal'
+vector) are also defined: 'DefaultHead2(triple normal=O)',
+'HookHead2(triple normal=O)', 'TeXHead2(triple normal=O)'. These are
+illustrated in the example 'arrows3.asy'.
+
+ Module 'three' also defines the three-dimensional margins
+'NoMargin3', 'BeginMargin3', 'EndMargin3', 'Margin3', 'Margins3',
+'BeginPenMargin2', 'EndPenMargin2', 'PenMargin2', 'PenMargins2',
+'BeginPenMargin3', 'EndPenMargin3', 'PenMargin3', 'PenMargins3',
+'BeginDotMargin3', 'EndDotMargin3', 'DotMargin3', 'DotMargins3',
+'Margin3', and 'TrueMargin3'.
+
+ The routine
+void pixel(picture pic=currentpicture, triple v, pen p=currentpen,
+ real width=1);
+can be used to draw on picture 'pic' a pixel of width 'width' at
+position 'v' using pen 'p'.
+
+ Further three-dimensional examples are provided in the files
+'near_earth.asy', 'conicurv.asy', and (in the 'animations' subdirectory)
+'cube.asy'.
+
+ Limited support for projected vector graphics (effectively
+three-dimensional nonrendered 'PostScript') is available with the
+setting 'render=0'. This currently only works for piecewise planar
+surfaces, such as those produced by the parametric 'surface' routines in
+the 'graph3' module. Surfaces produced by the 'solids' package will
+also be properly rendered if the parameter 'nslices' is sufficiently
+large.
+
+ In the module 'bsp', hidden surface removal of planar pictures is
+implemented using a binary space partition and picture clipping. A
+planar path is first converted to a structure 'face' derived from
+'picture'. A 'face' may be given to a two-dimensional drawing routine
+in place of any 'picture' argument. An array of such faces may then be
+drawn, removing hidden surfaces:
+void add(picture pic=currentpicture, face[] faces,
+ projection P=currentprojection);
+ Labels may be projected to two dimensions, using projection 'P', onto
+the plane passing through point 'O' with normal 'cross(u,v)' by
+multiplying it on the left by the transform
+transform transform(triple u, triple v, triple O=O,
+ projection P=currentprojection);
+
+ Here is an example that shows how a binary space partition may be
+used to draw a two-dimensional vector graphics projection of three
+orthogonal intersecting planes:
+size(6cm,0);
+import bsp;
+
+real u=2.5;
+real v=1;
+
+currentprojection=oblique;
+
+path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
+path3 l=rotate(90,Z)*rotate(90,Y)*y;
+path3 g=rotate(90,X)*rotate(90,Y)*y;
+
+face[] faces;
+filldraw(faces.push(y),project(y),yellow);
+filldraw(faces.push(l),project(l),lightgrey);
+filldraw(faces.push(g),project(g),green);
+
+add(faces);
+
+ [planes]
+
+
+File: asymptote.info, Node: obj, Next: graph3, Prev: three, Up: Base modules
+
+8.30 'obj'
+==========
+
+This module allows one to construct surfaces from simple obj files, as
+illustrated in the example files 'galleon.asy' and 'triceratops.asy'.
+
+
+File: asymptote.info, Node: graph3, Next: grid3, Prev: obj, Up: Base modules
+
+8.31 'graph3'
+=============
+
+This module implements three-dimensional versions of the functions in
+'graph.asy'. To draw an x axis in three dimensions, use the routine
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3, arrowbar3 arrow=None, bool above=false);
+Analogous routines 'yaxis' and 'zaxis' can be used to draw y and z axes
+in three dimensions. There is also a routine for drawing all three
+axis:
+void axes3(picture pic=currentpicture,
+ Label xlabel="", Label ylabel="", Label zlabel="",
+ bool extend=false,
+ triple min=(-infinity,-infinity,-infinity),
+ triple max=(infinity,infinity,infinity),
+ pen p=currentpen, arrowbar3 arrow=None);
+
+The predefined three-dimensional axis types are
+axis YZEquals(real y, real z, triple align=O, bool extend=false);
+axis XZEquals(real x, real z, triple align=O, bool extend=false);
+axis XYEquals(real x, real y, triple align=O, bool extend=false);
+axis YZZero(triple align=O, bool extend=false);
+axis XZZero(triple align=O, bool extend=false);
+axis XYZero(triple align=O, bool extend=false);
+axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false);
+The optional 'align' parameter to these routines can be used to specify
+the default axis and tick label alignments. The 'Bounds' axis accepts
+two type parameters, each of which must be one of 'Min', 'Max', or
+'Both'. These parameters specify which of the four possible
+three-dimensional bounding box edges should be drawn.
+
+ The three-dimensional tick options are 'NoTicks3', 'InTicks',
+'OutTicks', and 'InOutTicks'. These specify the tick directions for the
+'Bounds' axis type; other axis types inherit the direction that would be
+used for the 'Bounds(Min,Min)' axis.
+
+ Here is an example of a helix and bounding box axes with ticks and
+axis labels, using orthographic projection:
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=orthographic(4,6,3);
+
+real x(real t) {return cos(2pi*t);}
+real y(real t) {return sin(2pi*t);}
+real z(real t) {return t;}
+
+path3 p=graph(x,y,z,0,2.7,operator ..);
+
+draw(p,Arrow3);
+
+scale(true);
+
+xaxis3(XZ()*"$x$",Bounds,red,InTicks(Label,2,2));
+yaxis3(YZ()*"$y$",Bounds,red,InTicks(beginlabel=false,Label,2,2));
+zaxis3(XZ()*"$z$",Bounds,red,InTicks);
+
+ [helix]
+
+ The next example illustrates three-dimensional x, y, and z axes,
+without autoscaling of the axis limits:
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=perspective(5,2,2);
+
+scale(Linear,Linear,Log);
+
+xaxis3("$x$",0,1,red,OutTicks(2,2));
+yaxis3("$y$",0,1,red,OutTicks(2,2));
+zaxis3("$z$",1,30,red,OutTicks(beginlabel=false));
+
+ [axis3]
+
+ One can also place ticks along a general three-dimensional axis:
+import graph3;
+
+size(0,100);
+
+path3 g=yscale3(2)*unitcircle3;
+currentprojection=perspective(10,10,10);
+
+axis(Label("C",position=0,align=15X),g,InTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path3 h=O--max(abs(max(g)),abs(min(g)))*dir(90,v);
+ return intersect(g,h)[0];},
+ new triple(real t) {return cross(dir(g,t),Z);}));
+
+
+ [generalaxis3]
+
+ Surface plots of matrices and functions over the region 'box(a,b)' in
+the XY plane are also implemented:
+surface surface(real[][] f, pair a, pair b, bool[][] cond={});
+surface surface(real[][] f, pair a, pair b, splinetype xsplinetype,
+ splinetype ysplinetype=xsplinetype, bool[][] cond={});
+surface surface(real[][] f, real[] x, real[] y,
+ splinetype xsplinetype=null, splinetype ysplinetype=xsplinetype,
+ bool[][] cond={})
+surface surface(triple[][] f, bool[][] cond={});
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ bool cond(pair z)=null);
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ splinetype xsplinetype, splinetype ysplinetype=xsplinetype,
+ bool cond(pair z)=null);
+surface surface(triple f(pair z), real[] u, real[] v,
+ splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
+ bool cond(pair z)=null);
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ bool cond(pair z)=null);
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
+ bool cond(pair z)=null);
+The final two versions draw parametric surfaces for a function f(u,v)
+over the parameter space 'box(a,b)', as illustrated in the example
+'parametricsurface.asy'. An optional splinetype 'Spline' may be
+specified. The boolean array or function 'cond' can be used to control
+which surface mesh cells are actually drawn (by default all mesh cells
+over 'box(a,b)' are drawn). Surface lighting is illustrated in the
+example files 'parametricsurface.asy' and 'sinc.asy'. Lighting can be
+disabled by setting 'light=nolight', as in this example of a Gaussian
+surface:
+import graph3;
+
+size(200,0);
+
+currentprojection=perspective(10,8,4);
+
+real f(pair z) {return 0.5+exp(-abs(z)^2);}
+
+draw((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle);
+
+draw(arc(0.12Z,0.2,90,60,90,25),ArcArrow3);
+
+surface s=surface(f,(-1,-1),(1,1),nx=5,Spline);
+
+xaxis3(Label("$x$"),red,Arrow3);
+yaxis3(Label("$y$"),red,Arrow3);
+zaxis3(XYZero(extend=true),red,Arrow3);
+
+draw(s,lightgray,meshpen=black+thick(),nolight,render(merge=true));
+
+label("$O$",O,-Z+Y,red);
+
+ [GaussianSurface]
+A mesh can be drawn without surface filling by specifying 'nullpen' for
+the surfacepen.
+
+ A vector field of 'nu'\times'nv' arrows on a parametric surface 'f'
+over 'box(a,b)' can be drawn with the routine
+picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b,
+ int nu=nmesh, int nv=nu, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(f,a,b,nu,nv),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3)
+ as illustrated in the examples 'vectorfield3.asy' and
+'vectorfieldsphere.asy'.
+
+
+File: asymptote.info, Node: grid3, Next: solids, Prev: graph3, Up: Base modules
+
+8.32 'grid3'
+============
+
+This module, contributed by Philippe Ivaldi, can be used for drawing 3D
+grids. Here is an example (further examples can be found in 'grid3.asy'
+and at <http://www.piprime.fr/files/asymptote/grid3/>):
+import grid3;
+
+size(8cm,0,IgnoreAspect);
+currentprojection=orthographic(0.5,1,0.5);
+
+scale(Linear, Linear, Log);
+
+limits((-2,-2,1),(0,2,100));
+
+grid3(XYZgrid);
+
+xaxis3(Label("$x$",position=EndPoint,align=S),Bounds(Min,Min),
+ OutTicks());
+yaxis3(Label("$y$",position=EndPoint,align=S),Bounds(Min,Min),OutTicks());
+zaxis3(Label("$z$",position=EndPoint,align=(-1,0.5)),Bounds(Min,Min),
+ OutTicks(beginlabel=false));
+
+
+ [grid3xyz]
+
+
+File: asymptote.info, Node: solids, Next: tube, Prev: grid3, Up: Base modules
+
+8.33 'solids'
+=============
+
+This solid geometry package defines a structure 'revolution' that can be
+used to fill and draw surfaces of revolution. The following example
+uses it to display the outline of a circular cylinder of radius 1 with
+axis 'O--1.5unit(Y+Z)' with perspective projection:
+import solids;
+
+size(0,100);
+
+revolution r=cylinder(O,1,1.5,Y+Z);
+draw(r,heavygreen);
+
+ [cylinderskeleton]
+
+ Further illustrations are provided in the example files
+'cylinder.asy', 'cones.asy', 'hyperboloid.asy', and 'torus.asy'.
+
+ The structure 'skeleton' contains the three-dimensional wireframe
+used to visualize a volume of revolution:
+struct skeleton {
+ struct curve {
+ path3[] front;
+ path3[] back;
+ }
+ // transverse skeleton (perpendicular to axis of revolution)
+ curve transverse;
+ // longitudinal skeleton (parallel to axis of revolution)
+ curve longitudinal;
+}
+
+
+File: asymptote.info, Node: tube, Next: flowchart, Prev: solids, Up: Base modules
+
+8.34 'tube'
+===========
+
+This package extends the 'tube' surfaces constructed in
+'three_arrows.asy' to arbitrary cross sections, colors, and spine
+transformations. The routine
+surface tube(path3 g, coloredpath section,
+ transform T(real)=new transform(real t) {return identity();},
+ real corner=1, real relstep=0);
+draws a tube along 'g' with cross section 'section', after applying the
+transformation 'T(t)' at 'relpoint(g,t)'. The parameter 'corner'
+controls the number of elementary tubes at the angular points of 'g'. A
+nonzero value of 'relstep' specifies a fixed relative time step (in the
+sense of 'relpoint(g,t)') to use in constructing elementary tubes along
+'g'. The type 'coloredpath' is a generalization of 'path' to which a
+'path' can be cast:
+struct coloredpath
+{
+ path p;
+ pen[] pens(real);
+ int colortype=coloredSegments;
+}
+Here 'p' defines the cross section and the method 'pens(real t)' returns
+an array of pens (interpreted as a cyclic array) used for shading the
+tube patches at 'relpoint(g,t)'. If 'colortype=coloredSegments', the
+tube patches are filled as if each segment of the section was colored
+with the pen returned by 'pens(t)', whereas if 'colortype=coloredNodes',
+the tube components are vertex shaded as if the nodes of the section
+were colored.
+
+ A 'coloredpath' can be constructed with one of the routines:
+coloredpath coloredpath(path p, pen[] pens(real),
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen[] pens=new pen[] {currentpen},
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen pen(real));
+In the second case, the pens are independent of the relative time. In
+the third case, the array of pens contains only one pen, which depends
+of the relative time.
+
+ The casting of 'path' to 'coloredpath' allows the use of a 'path'
+instead of a 'coloredpath'; in this case the shading behaviour is the
+default shading behavior for a surface.
+
+ An example of 'tube' is provided in the file 'trefoilknot.asy'.
+Further examples can be found at
+<http://www.piprime.fr/files/asymptote/tube/>.
+
+
+File: asymptote.info, Node: flowchart, Next: contour, Prev: tube, Up: Base modules
+
+8.35 'flowchart'
+================
+
+This package provides routines for drawing flowcharts. The primary
+structure is a 'block', which represents a single block on the
+flowchart. The following eight functions return a position on the
+appropriate edge of the block, given picture transform 't':
+
+pair block.top(transform t=identity());
+pair block.left(transform t=identity());
+pair block.right(transform t=identity());
+pair block.bottom(transform t=identity());
+pair block.topleft(transform t=identity());
+pair block.topright(transform t=identity());
+pair block.bottomleft(transform t=identity());
+pair block.bottomright(transform t=identity());
+
+To obtain an arbitrary position along the boundary of the block in user
+coordinates, use:
+pair block.position(real x, transform t=identity());
+
+The center of the block in user coordinates is stored in 'block.center'
+and the block size in 'PostScript' coordinates is given by 'block.size'.
+
+A frame containing the block is returned by
+frame block.draw(pen p=currentpen);
+
+ The following block generation routines accept a Label, string, or
+frame for their object argument:
+
+"rectangular block with an optional header (and padding 'dx' around header and body):"
+ block rectangle(object header, object body, pair center=(0,0),
+ pen headerpen=mediumgray, pen bodypen=invisible,
+ pen drawpen=currentpen,
+ real dx=3, real minheaderwidth=minblockwidth,
+ real minheaderheight=minblockwidth,
+ real minbodywidth=minblockheight,
+ real minbodyheight=minblockheight);
+ block rectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+
+"parallelogram block:"
+ block parallelogram(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real slope=2,
+ real minwidth=minblockwidth,
+ real minheight=minblockheight);
+
+"diamond-shaped block:"
+ block diamond(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=1,
+ real height=20, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+
+"circular block:"
+ block circle(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dr=3,
+ real mindiameter=mincirclediameter);
+
+"rectangular block with rounded corners:"
+ block roundrectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=0, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+
+"rectangular block with beveled edges:"
+ block bevel(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dh=5, real dw=5,
+ real minwidth=minblockwidth, real minheight=minblockheight);
+
+ To draw paths joining the pairs in 'point' with right-angled lines,
+use the routine:
+path path(pair point[] ... flowdir dir[]);
+The entries in 'dir' identify whether successive segments between the
+pairs specified by 'point' should be drawn in the 'Horizontal' or
+'Vertical' direction.
+
+ Here is a simple flowchart example (see also the example
+'controlsystem.asy'):
+
+size(0,300);
+
+import flowchart;
+
+block block1=rectangle(Label("Example",magenta),
+ pack(Label("Start:",heavygreen),"",Label("$A:=0$",blue),
+ "$B:=1$"),(-0.5,3),palegreen,paleblue,red);
+block block2=diamond(Label("Choice?",blue),(0,2),palegreen,red);
+block block3=roundrectangle("Do something",(-1,1));
+block block4=bevel("Don't do something",(1,1));
+block block5=circle("End",(0,0));
+
+draw(block1);
+draw(block2);
+draw(block3);
+draw(block4);
+draw(block5);
+
+add(new void(picture pic, transform t) {
+ blockconnector operator --=blockconnector(pic,t);
+ // draw(pic,block1.right(t)--block2.top(t));
+ block1--Right--Down--Arrow--block2;
+ block2--Label("Yes",0.5,NW)--Left--Down--Arrow--block3;
+ block2--Right--Label("No",0.5,NE)--Down--Arrow--block4;
+ block4--Down--Left--Arrow--block5;
+ block3--Down--Right--Arrow--block5;
+ });
+
+ [flowchartdemo]
+
+
+File: asymptote.info, Node: contour, Next: contour3, Prev: flowchart, Up: Base modules
+
+8.36 'contour'
+==============
+
+This package draws contour lines. To construct contours corresponding
+to the values in a real array 'c' for a function 'f' on 'box(a,b)', use
+the routine
+guide[][] contour(real f(real, real), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --, int subsample=1);
+The integers 'nx' and 'ny' define the resolution. The default
+resolution, 'ngraph x ngraph' (here 'ngraph' defaults to '100') can be
+increased for greater accuracy. The default interpolation operator is
+'operator --' (linear). Spline interpolation ('operator ..') may
+produce smoother contours but it can also lead to overshooting. The
+'subsample' parameter indicates the number of interior points that
+should be used to sample contours within each '1 x 1' box; the default
+value of '1' is usually sufficient.
+
+ To construct contours for an array of data values on a uniform
+two-dimensional lattice on 'box(a,b)', use
+guide[][] contour(real[][] f, pair a, pair b, real[] c,
+ interpolate join=operator --, int subsample=1);
+
+ To construct contours for an array of data values on a nonoverlapping
+regular mesh specified by the two-dimensional array 'z',
+guide[][] contour(pair[][] z, real[][] f, real[] c,
+ interpolate join=operator --, int subsample=1);
+
+To construct contours for an array of values 'f' specified at
+irregularly positioned points 'z', use the routine
+guide[][] contour(pair[] z, real[] f, real[] c, interpolate join=operator --);
+The contours themselves can be drawn with one of the routines
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen p=currentpen);
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen[] p);
+
+ The following simple example draws the contour at value '1' for the
+function z=x^2+y^2, which is a unit circle:
+import contour;
+size(75);
+
+real f(real a, real b) {return a^2+b^2;}
+draw(contour(f,(-1,-1),(1,1),new real[] {1}));
+
+ [onecontour]
+
+ The next example draws and labels multiple contours for the function
+z=x^2-y^2 with the resolution '100 x 100', using a dashed pen for
+negative contours and a solid pen for positive (and zero) contours:
+import contour;
+
+size(200);
+
+real f(real x, real y) {return x^2-y^2;}
+int n=10;
+real[] c=new real[n];
+for(int i=0; i < n; ++i) c[i]=(i-n/2)/n;
+
+pen[] p=sequence(new pen(int i) {
+ return (c[i] >= 0 ? solid : dashed)+fontsize(6pt);
+ },c.length);
+
+Label[] Labels=sequence(new Label(int i) {
+ return Label(c[i] != 0 ? (string) c[i] : "",Relative(unitrand()),(0,0),
+ UnFill(1bp));
+ },c.length);
+
+draw(Labels,contour(f,(-1,-1),(1,1),c),p);
+
+ [multicontour]
+
+ The next example illustrates how contour lines can be drawn on color
+density images:
+import graph;
+import palette;
+import contour;
+
+size(10cm,10cm,IgnoreAspect);
+
+pair a=(0,0);
+pair b=(2pi,2pi);
+
+real f(real x, real y) {return cos(x)*sin(y);}
+
+int N=200;
+int Divs=10;
+int divs=2;
+
+defaultpen(1bp);
+pen Tickpen=black;
+pen tickpen=gray+0.5*linewidth(currentpen);
+pen[] Palette=BWRainbow();
+
+bounds range=image(f,Automatic,a,b,N,Palette);
+
+// Major contours
+
+real[] Cvals=uniform(range.min,range.max,Divs);
+draw(contour(f,a,b,Cvals,N,operator --),Tickpen);
+
+// Minor contours
+real[] cvals;
+for(int i=0; i < Cvals.length-1; ++i)
+ cvals.append(uniform(Cvals[i],Cvals[i+1],divs)[1:divs]);
+draw(contour(f,a,b,cvals,N,operator --),tickpen);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,point(NW)+(0,0.5),point(NE)+(0,1),Top,Palette,
+ PaletteTicks(N=Divs,n=divs,Tickpen,tickpen));
+
+ [imagecontour]
+
+ Finally, here is an example that illustrates the construction of
+contours from irregularly spaced data:
+import contour;
+
+size(200);
+
+int n=100;
+
+real f(real a, real b) {return a^2+b^2;}
+
+srand(1);
+
+real r() {return 1.1*(rand()/randMax*2-1);}
+
+pair[] points=new pair[n];
+real[] values=new real[n];
+
+for(int i=0; i < n; ++i) {
+ points[i]=(r(),r());
+ values[i]=f(points[i].x,points[i].y);
+}
+
+draw(contour(points,values,new real[]{0.25,0.5,1},operator ..),blue);
+
+ [irregularcontour]
+
+ In the above example, the contours of irregularly spaced data are
+constructed by first creating a triangular mesh from an array 'z' of
+pairs:
+
+int[][] triangulate(pair[] z);
+
+size(200);
+int np=100;
+pair[] points;
+
+real r() {return 1.2*(rand()/randMax*2-1);}
+
+for(int i=0; i < np; ++i)
+ points.push((r(),r()));
+
+int[][] trn=triangulate(points);
+
+for(int i=0; i < trn.length; ++i) {
+ draw(points[trn[i][0]]--points[trn[i][1]]);
+ draw(points[trn[i][1]]--points[trn[i][2]]);
+ draw(points[trn[i][2]]--points[trn[i][0]]);
+}
+
+for(int i=0; i < np; ++i)
+ dot(points[i],red);
+
+ [triangulate]
+
+ The example 'Gouraudcontour.asy' illustrates how to produce color
+density images over such irregular triangular meshes. 'Asymptote' uses
+a robust version of Paul Bourke's Delaunay triangulation algorithm based
+on the public-domain exact arithmetic predicates written by Jonathan
+Shewchuk.
+
+
+File: asymptote.info, Node: contour3, Next: smoothcontour3, Prev: contour, Up: Base modules
+
+8.37 'contour3'
+===============
+
+This package draws surfaces described as the null space of real-valued
+functions of (x,y,z) or 'real[][][]' matrices. Its usage is illustrated
+in the example file 'magnetic.asy'.
+
+
+File: asymptote.info, Node: smoothcontour3, Next: slopefield, Prev: contour3, Up: Base modules
+
+8.38 'smoothcontour3'
+=====================
+
+This module, written by Charles Staats, draws implicitly defined
+surfaces with smooth appearance. The purpose of this module is similar
+to that of 'contour3': given a real-valued function f(x,y,z), construct
+the surface described by the equation f(x,y,z) = 0. The
+'smoothcontour3' module generally produces nicer results than
+'contour3', but takes longer to compile. Additionally, the algorithm
+assumes that the function and the surface are both smooth; if they are
+not, then 'contour3' may be a better choice.
+
+ To construct the null surface of a function 'f(triple)' or
+'ff(real,real,real)' over 'box(a,b)', use the routine
+surface implicitsurface(real f(triple)=null,
+ real ff(real,real,real)=null,
+ triple a,
+ triple b,
+ int n=nmesh,
+ bool keyword overlapedges=false,
+ int keyword nx=n,
+ int keyword ny=n,
+ int keyword nz=n,
+ int keyword maxdepth=8,
+ bool usetriangles=true);
+The optional parameter 'overlapedges' attempts to compensate for an
+artifact that can cause the renderer to "see through" the boundary
+between patches. Although it defaults to 'false', it should usually be
+set to 'true'. The example 'genustwo.asy' illustrates the use of this
+function. Additional examples, together with a more in-depth
+explanation of the module's usage and pitfalls, are available at
+<https://github.com/charlesstaats/smoothcontour3>.
+
+
+File: asymptote.info, Node: slopefield, Next: ode, Prev: smoothcontour3, Up: Base modules
+
+8.39 'slopefield'
+=================
+
+To draw a slope field for the differential equation dy/dx=f(x,y) (or
+dy/dx=f(x)), use:
+picture slopefield(real f(real,real), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ real tickfactor=0.5, pen p=currentpen,
+ arrowbar arrow=None);
+Here, the points 'a' and 'b' are the lower left and upper right corners
+of the rectangle in which the slope field is to be drawn, 'nx' and 'ny'
+are the respective number of ticks in the x and y directions,
+'tickfactor' is the fraction of the minimum cell dimension to use for
+drawing ticks, and 'p' is the pen to use for drawing the slope fields.
+The return value is a picture that can be added to 'currentpicture' via
+the 'add(picture)' command.
+
+ The function
+path curve(pair c, real f(real,real), pair a, pair b);
+takes a point ('c') and a slope field-defining function 'f' and returns,
+as a path, the curve passing through that point. The points 'a' and 'b'
+represent the rectangular boundaries over which the curve is
+interpolated.
+
+ Both 'slopefield' and 'curve' alternatively accept a function 'real
+f(real)' that depends on x only, as seen in this example:
+
+import slopefield;
+
+size(200);
+
+real func(real x) {return 2x;}
+add(slopefield(func,(-3,-3),(3,3),20,Arrow));
+draw(curve((0,0),func,(-3,-3),(3,3)),red);
+
+
+
+ [slopefield1]
+
+
+File: asymptote.info, Node: ode, Prev: slopefield, Up: Base modules
+
+8.40 'ode'
+==========
+
+The 'ode' module, illustrated in the example 'odetest.asy', implements a
+number of explicit numerical integration schemes for ordinary
+differential equations.
+
+
+File: asymptote.info, Node: Options, Next: Interactive mode, Prev: Base modules, Up: Top
+
+9 Command-line options
+**********************
+
+Type 'asy -h' to see the full list of command-line options supported by
+'Asymptote':
+Usage: ../asy [options] [file ...]
+
+Options (negate by replacing - with -no):
+
+-V,-View View output; command-line only
+-a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [C]
+-aligndir pair Directional page alignment (overrides align) [(0,0)]
+-antialias n Antialiasing width for rasterized output [2]
+-arcballradius pixels Arcball radius [750]
+-auto3D Automatically activate 3D scene [true]
+-autobillboard 3D labels always face viewer by default [true]
+-autoimport string Module to automatically import
+-autoplain Enable automatic importing of plain [true]
+-autoplay Autoplay 3D animations [false]
+-autorotate Enable automatic PDF page rotation [false]
+-axes3 Show 3D axes in PDF output [true]
+-batchMask Mask fpu exceptions in batch mode [false]
+-batchView View output in batch mode [false]
+-bw Convert all colors to black and white [false]
+-cd directory Set current directory; command-line only
+-cmyk Convert rgb colors to cmyk [false]
+-c,-command string Command to autoexecute
+-compact Conserve memory at the expense of speed [false]
+-d,-debug Enable debugging messages [false]
+-divisor n Garbage collect using purge(divisor=n) [2]
+-doubleclick ms Emulated double-click timeout [200]
+-embed Embed rendered preview image [true]
+-envmap Enable environment map image-based lighting (Experimental) [false]
+-exitonEOF Exit interactive mode on EOF [true]
+-fitscreen Fit rendered image to screen [true]
+-framedelay ms Additional frame delay [0]
+-framerate frames/s Animation speed [30]
+-globalwrite Allow write to other directory [false]
+-gray Convert all colors to grayscale [false]
+-h,-help Show summary of options; command-line only
+-historylines n Retain n lines of history [1000]
+-iconify Iconify rendering window [false]
+-inlineimage Generate inline embedded image [false]
+-inlinetex Generate inline TeX code [false]
+-interactiveMask Mask fpu exceptions in interactive mode [true]
+-interactiveView View output in interactive mode [true]
+-interactiveWrite Write expressions entered at the prompt to stdout [true]
+-k,-keep Keep intermediate files [false]
+-keepaux Keep intermediate LaTeX .aux files [false]
+-level n Postscript level [3]
+-l,-listvariables List available global functions and variables [false]
+-localhistory Use a local interactive history file [false]
+-loop Loop 3D animations [false]
+-m,-mask Mask fpu exceptions; command-line only
+-maxtile pair Maximum rendering tile size [(1024,768)]
+-maxvertices n Maximum number of vertices to queue [0]
+-maxviewport pair Maximum viewport size [(2048,2048)]
+-multiline Input code over multiple lines at the prompt [false]
+-multipleView View output from multiple batch-mode files [false]
+-multisample n Multisampling width for screen images [4]
+-offscreen Use offscreen rendering [false]
+-O,-offset pair PostScript offset [(0,0)]
+-f,-outformat format Convert each output file to specified format
+-o,-outname name Alternative output directory/filename
+-p,-parseonly Parse file [false]
+-pdfreload Automatically reload document in pdfviewer [false]
+-pdfreloaddelay usec Delay before attempting initial pdf reload [750000]
+-position pair Initial 3D rendering screen position [(0,0)]
+-prc Embed 3D PRC graphics in PDF output [true]
+-prompt string Prompt [> ]
+-prompt2 string Continuation prompt for multiline input [..]
+-q,-quiet Suppress welcome text and noninteractive stdout [false]
+-render n Render 3D graphics using n pixels per bp (-1=auto) [-1]
+-resizestep step Resize step [1.2]
+-reverse reverse 3D animations [false]
+-rgb Convert cmyk colors to rgb [false]
+-safe Disable system call [true]
+-scroll n Scroll standard output n lines at a time [0]
+-spinstep deg/s Spin speed [60]
+-svgemulation Emulate unimplemented SVG shading [false]
+-tabcompletion Interactive prompt auto-completion [true]
+-tex engine latex|pdflatex|xelatex|lualatex|tex|pdftex|luatex|context|none [latex]
+-thick Render thick 3D lines [true]
+-thin Render thin 3D lines [true]
+-threads Use POSIX threads for 3D rendering [true]
+-toolbar Show 3D toolbar in PDF output [true]
+-s,-translate Show translated virtual machine code [false]
+-twice Run LaTeX twice (to resolve references) [false]
+-twosided Use two-sided 3D lighting model for rendering [true]
+-u,-user string General purpose user string
+-v,-verbose Increase verbosity level (can specify multiple times) [0]
+-version Show version; command-line only
+-wait Wait for child processes to finish before exiting [false]
+-warn string Enable warning; command-line only
+-where Show where listed variables are declared [false]
+-xasy Special interactive mode for xasy [false]
+-zoomfactor factor Zoom step factor [1.05]
+-zoomstep step Mouse motion zoom step [0.1]
+
+
+ All boolean options can be negated by prepending 'no' to the option
+name.
+
+ If no arguments are given, 'Asymptote' runs in interactive mode
+(*note Interactive mode::). In this case, the default output file is
+'out.eps'.
+
+ If '-' is given as the file argument, 'Asymptote' reads from standard
+input.
+
+ If multiple files are specified, they are treated as separate
+'Asymptote' runs.
+
+ If the string 'autoimport' is nonempty, a module with this name is
+automatically imported for each run as the final step in loading module
+'plain'.
+
+ Default option values may be entered as 'Asymptote' code in a
+configuration file named 'config.asy' (or the file specified by the
+environment variable 'ASYMPTOTE_CONFIG' or '-config' option).
+'Asymptote' will look for this file in its usual search path (*note
+Search paths::). Typically the configuration file is placed in the
+'.asy' directory in the user's home directory ('%USERPROFILE%\.asy'
+under 'MSDOS'). Configuration variables are accessed using the long
+form of the option names:
+import settings;
+outformat="pdf";
+batchView=false;
+interactiveView=true;
+batchMask=false;
+interactiveMask=true;
+ Command-line options override these defaults. Most configuration
+variables may also be changed at runtime. The advanced configuration
+variables 'dvipsOptions', 'hyperrefOptions', 'convertOptions',
+'gsOptions', 'psviewerOptions', 'pdfviewerOptions', 'pdfreloadOptions',
+'glOptions', and 'dvisvgmOptions' allow specialized options to be passed
+as a string to the respective applications or libraries. The default
+value of 'hyperrefOptions' is 'setpagesize=false,unicode,pdfborder=0 0
+0'.
+
+ If you insert
+import plain;
+settings.autoplain=true;
+at the beginning of the configuration file, it can contain arbitrary
+'Asymptote' code.
+
+ The default output format is EPS for the (default) 'latex' and 'tex'
+tex engine and PDF for the 'pdflatex', 'xelatex', 'context', 'luatex',
+and 'lualatex' tex engines. Alternative output formats may be produced
+using the '-f' option (or 'outformat' setting).
+
+ To produce SVG output, you will need 'dvisvgm' (version 1.5.3 or
+later) from <http://dvisvgm.sourceforge.net> and must use the 'latex' or
+'tex' tex engine. You might need to adjust the configuration variable
+'libgs' to point to the location of your 'Ghostscript' library
+'libgs.so' (or to an empty string, depending on how 'dvisvgm' was
+configured).
+
+ 'Asymptote' can also produce any output format supported by the
+'ImageMagick' 'convert' program (version 6.3.5 or later recommended; an
+'Invalid Parameter' error message indicates that the 'MSDOS' utility
+'convert' is being used instead of the one that comes with
+'ImageMagick'). The optional setting '-render n' requests an output
+resolution of 'n' pixels per 'bp'. Antialiasing is controlled by the
+parameter 'antialias', which by default specifies a sampling width of 2
+pixels. To give other options to 'convert', use the 'convertOptions'
+setting or call convert manually. This example emulates how 'Asymptote'
+produces antialiased 'tiff' output at one pixel per 'bp':
+asy -o - venn | convert -alpha Off -density 144x144 -geometry 50%x eps:- venn.tiff
+
+ If the option '-nosafe' is given, 'Asymptote' runs in unsafe mode.
+This enables the 'int system(string s)' and 'int system(string[] s)'
+calls, allowing one to execute arbitrary shell commands. The default
+mode, '-safe', disables this call.
+
+ A 'PostScript' offset may be specified as a pair (in 'bp' units) with
+the '-O' option:
+asy -O 0,0 file
+The default offset is zero. The pair 'aligndir' specifies an optional
+direction on the boundary of the page (mapped to the rectangle
+[-1,1]\times[-1,1]) to which the picture should be aligned; the default
+value '(0,0)' species center alignment.
+
+ The '-c' ('command') option may be used to execute arbitrary
+'Asymptote' code on the command line as a string. It is not necessary
+to terminate the string with a semicolon. Multiple '-c' options are
+executed in the order they are given. For example
+asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
+produces the output
+4
+0.841470984807897
+and draws a unitsquare of size '100'.
+
+ The '-u' ('user') option may be used to specify arbitrary 'Asymptote'
+settings on the command line as a string. It is not necessary to
+terminate the string with a semicolon. Multiple '-u' options are
+executed in the order they are given. Command-line code like '-u
+x=sqrt(2)' can be executed within a module like this:
+real x;
+usersetting();
+write(x);
+
+ When the '-l' ('listvariables') option is used with file arguments,
+only global functions and variables defined in the specified file(s) are
+listed.
+
+ Additional debugging output is produced with each additional '-v'
+option:
+'-v'
+ Display top-level module and final output file names.
+'-vv'
+ Also display imported and included module names and final 'LaTeX'
+ and 'dvips' processing information.
+'-vvv'
+ Also output 'LaTeX' bidirectional pipe diagnostics.
+'-vvvv'
+ Also output knot guide solver diagnostics.
+'-vvvvv'
+ Also output 'Asymptote' traceback diagnostics.
+
+
+File: asymptote.info, Node: Interactive mode, Next: GUI, Prev: Options, Up: Top
+
+10 Interactive mode
+*******************
+
+Interactive mode is entered by executing the command 'asy' with no file
+arguments. When the '-multiline' option is disabled (the default), each
+line must be a complete 'Asymptote' statement (unless explicitly
+continued by a final backslash character '\'); it is not necessary to
+terminate input lines with a semicolon. If one assigns
+'settings.multiline=true', interactive code can be entered over multiple
+lines; in this mode, the automatic termination of interactive input
+lines by a semicolon is inhibited. Multiline mode is useful for cutting
+and pasting 'Asymptote' code directly into the interactive input buffer.
+
+ Interactive mode can be conveniently used as a calculator:
+expressions entered at the interactive prompt (for which a corresponding
+'write' function exists) are automatically evaluated and written to
+'stdout'. If the expression is non-writable, its type signature will be
+printed out instead. In either case, the expression can be referred to
+using the symbol '%' in the next line input at the prompt. For example:
+> 2+3
+5
+> %*4
+20
+> 1/%
+0.05
+> sin(%)
+0.0499791692706783
+> currentpicture
+<picture currentpicture>
+> %.size(200,0)
+>
+
+ The '%' symbol, when used as a variable, is shorthand for the
+identifier 'operator answer', which is set by the prompt after each
+written expression evaluation.
+
+ The following special commands are supported only in interactive mode
+and must be entered immediately after the prompt:
+
+'help'
+ view the manual;
+'erase'
+ erase 'currentpicture';
+'reset'
+ reset the 'Asymptote' environment to its initial state, except for
+ changes to the settings module (*note settings::), the current
+ directory (*note cd::), and breakpoints (*note Debugger::);
+'input FILE'
+ does an interactive reset, followed by the command 'include FILE'.
+ If the file name 'FILE' contains nonalphanumeric characters,
+ enclose it with quotation marks. A trailing semi-colon followed by
+ optional 'Asymptote' commands may be entered on the same line.
+'quit'
+ exit interactive mode ('exit' is a synonym; the abbreviation 'q' is
+ also accepted unless there exists a top-level variable named 'q').
+ A history of the most recent 1000 (this number can be changed with
+ the 'historylines' configuration variable) previous commands will
+ be retained in the file '.asy/history' in the user's home directory
+ (unless the command-line option '-localhistory' was specified, in
+ which case the history will be stored in the file '.asy_history' in
+ the current directory).
+
+ Typing 'ctrl-C' interrupts the execution of 'Asymptote' code and
+returns control to the interactive prompt.
+
+ Interactive mode is implemented with the GNU 'readline' library, with
+command history and auto-completion. To customize the key bindings,
+see: <http://cnswww.cns.cwru.edu/php/chet/readline/readline.html>
+
+ The file 'asymptote.py' in the 'Asymptote' system directory provides
+an alternative way of entering 'Asymptote' commands interactively,
+coupled with the full power of 'Python'. Copy this file to your 'Python
+path' and then execute from within 'Python 3' the commands
+from asymptote import *
+g=asy()
+g.size(200)
+g.draw("unitcircle")
+g.send("draw(unitsquare)")
+g.fill("unitsquare, blue")
+g.clip("unitcircle")
+g.label("\"$O$\", (0,0), SW")
+
+
+File: asymptote.info, Node: GUI, Next: PostScript to Asymptote, Prev: Interactive mode, Up: Top
+
+11 Graphical User Interface
+***************************
+
+* Menu:
+
+* GUI installation:: Installing 'xasy'
+* GUI usage:: Using 'xasy' to edit objects
+
+In the event that adjustments to the final figure are required, the
+preliminary Graphical User Interface (GUI) 'xasy' included with
+'Asymptote' allows you to move graphical objects and draw new ones. The
+modified figure can then be saved as a normal 'Asymptote' file.
+
+
+File: asymptote.info, Node: GUI installation, Next: GUI usage, Prev: GUI, Up: GUI
+
+11.1 GUI installation
+=====================
+
+As 'xasy' is written in the interactive scripting language 'Python/Qt',
+it requires 'Python' (<http://www.python.org>), along with the 'Python'
+packages 'pyqt5', 'cson', and 'numpy':
+
+pip3 install cson numpy pyqt5 PyQt5.sip
+
+ Pictures are deconstructed into the SVG image format. Since 'Qt5'
+does not suport 'SVG' clipping, you will need the 'rsvg-convert'
+utility, which is part of the 'librsvg2-tools' package on 'UNIX' systems
+and the 'librsvg' package on 'MacOS'; under 'Microsoft Windows', it is
+available as
+
+ <https://sourceforge.net/projects/tumagcc/files/rsvg-convert-2.40.20.7z>
+
+
+File: asymptote.info, Node: GUI usage, Prev: GUI installation, Up: GUI
+
+11.2 GUI usage
+==============
+
+The arrow keys (or mouse wheel) are convenient for temporarily raising
+and lowering objects within 'xasy', allowing an object to be selected.
+Pressing the arrow keys will pan while the shift key is held and zoom
+while the control key is held. The mouse wheel will pan while the alt
+or shift keys is held and zoom while the control key is held.
+
+ Deconstruction of compound objects (such as arrows) can be prevented
+by enclosing them within the commands
+void begingroup(picture pic=currentpicture);
+void endgroup(picture pic=currentpicture);
+ By default, the elements of a picture or frame will be grouped
+together on adding them to a picture. However, the elements of a frame
+added to another frame are not grouped together by default: their
+elements will be individually deconstructed (*note add::).
+
+
+File: asymptote.info, Node: PostScript to Asymptote, Next: Help, Prev: GUI, Up: Top
+
+12 'PostScript' to 'Asymptote'
+******************************
+
+The excellent 'PostScript' editor 'pstoedit' (version 3.50 or later;
+available from <http://sourceforge.net/projects/pstoedit/>) includes an
+'Asymptote' backend. Unlike virtually all other 'pstoedit' backends,
+this driver includes native clipping, even-odd fill rule, 'PostScript'
+subpath, and full image support. Here is an example: 'asy -V
+/usr/local/share/doc/asymptote/examples/venn.asy'
+pstoedit -f asy venn.eps test.asy
+asy -V test
+
+If the line widths aren't quite correct, try giving 'pstoedit' the
+'-dis' option. If the fonts aren't typeset correctly, try giving
+'pstoedit' the '-dt' option.
+
+
+File: asymptote.info, Node: Help, Next: Debugger, Prev: PostScript to Asymptote, Up: Top
+
+13 Help
+*******
+
+A list of frequently asked questions (FAQ) is maintained at
+ <http://asymptote.sourceforge.net/FAQ>
+Questions on installing and using 'Asymptote' that are not addressed in
+the FAQ should be sent to the 'Asymptote' forum:
+ <http://sourceforge.net/p/asymptote/discussion/409349>
+Including an example that illustrates what you are trying to do will
+help you get useful feedback. 'LaTeX' problems can often be diagnosed
+with the '-vv' or '-vvv' command-line options. Contributions in the
+form of patches or 'Asymptote' modules can be posted here:
+ <http://sourceforge.net/p/asymptote/patches>
+To receive announcements of upcoming releases, please subscribe to
+'Asymptote' at
+ <http://freecode.com/projects/asy>
+If you find a bug in 'Asymptote', please check (if possible) whether the
+bug is still present in the latest 'git' developmental code (*note
+Git::) before submitting a bug report. New bugs can be reported at
+ <https://github.com/vectorgraphics/asymptote/issues>
+To see if the bug has already been fixed, check bugs with Status
+'Closed' and recent lines in
+ <http://asymptote.sourceforge.net/ChangeLog>
+
+ 'Asymptote' can be configured with the optional GNU library
+'libsigsegv', available from <http://libsigsegv.sourceforge.net>, which
+allows one to distinguish user-generated 'Asymptote' stack overflows
+(*note stack overflow::) from true segmentation faults (due to internal
+C++ programming errors; please submit the 'Asymptote' code that
+generates such segmentation faults along with your bug report).
+
+
+File: asymptote.info, Node: Debugger, Next: Credits, Prev: Help, Up: Top
+
+14 Debugger
+***********
+
+Asymptote now includes a line-based (as opposed to code-based) debugger
+that can assist the user in following flow control. To set a break
+point in file 'file' at line 'line', use the command
+
+void stop(string file, int line, code s=quote{});
+The optional argument 's' may be used to conditionally set the variable
+'ignore' in 'plain_debugger.asy' to 'true'. For example, the first 10
+instances of this breakpoint will be ignored (the variable 'int count=0'
+is defined in 'plain_debugger.asy'):
+stop("test",2,quote{ignore=(++count <= 10);});
+
+ To set a break point in file 'file' at the first line containing the
+string 'text', use
+
+void stop(string file, string text, code s=quote{});
+To list all breakpoints, use:
+void breakpoints();
+To clear a breakpoint, use:
+void clear(string file, int line);
+To clear all breakpoints, use:
+void clear();
+
+ The following commands may be entered at the debugging prompt:
+
+'h'
+ help;
+'c'
+ continue execution;
+
+'i'
+ step to the next instruction;
+
+'s'
+ step to the next executable line;
+
+'n'
+ step to the next executable line in the current file;
+
+'f'
+ step to the next file;
+
+'r'
+ return to the file associated with the most recent breakpoint;
+
+'t'
+ toggle tracing ('-vvvvv') mode;
+
+'q'
+ quit debugging and end execution;
+
+'x'
+ exit the debugger and run to completion.
+
+Arbitrary 'Asymptote' code may also be entered at the debugging prompt;
+however, since the debugger is implemented with 'eval', currently only
+top-level (global) variables can be displayed or modified.
+
+ The debugging prompt may be entered manually with the call
+void breakpoint(code s=quote{});
+
+
+File: asymptote.info, Node: Credits, Next: Index, Prev: Debugger, Up: Top
+
+15 Acknowledgments
+******************
+
+Financial support for the development of 'Asymptote' was generously
+provided by the Natural Sciences and Engineering Research Council of
+Canada, the Pacific Institute for Mathematical Sciences, and the
+University of Alberta Faculty of Science.
+
+ We also would like to acknowledge the previous work of John D. Hobby,
+author of the program 'MetaPost' that inspired the development of
+'Asymptote', and Donald E. Knuth, author of TeX and 'MetaFont' (on which
+'MetaPost' is based).
+
+ The authors of 'Asymptote' are Andy Hammerlindl, John Bowman, and Tom
+Prince. Sean Healy designed the 'Asymptote' logo. Other contributors
+include Orest Shardt, Jesse Frohlich, Michail Vidiassov, Charles Staats,
+Philippe Ivaldi, Olivier Guibe', Radoslav Marinov, Jeff Samuelson, Chris
+Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk, Martin Wiebusch,
+Stefan Knorr, and Supakorn "Jamie" Rassameemasmuang.
+
+
+File: asymptote.info, Node: Index, Prev: Credits, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* !: Arithmetic & logical.
+ (line 57)
+* !=: Structures. (line 62)
+* != <1>: Arithmetic & logical.
+ (line 37)
+* #: Arithmetic & logical.
+ (line 20)
+* %: Arithmetic & logical.
+ (line 25)
+* % <1>: Interactive mode. (line 16)
+* %=: Self & prefix operators.
+ (line 6)
+* &: Bezier curves. (line 84)
+* & <1>: Arithmetic & logical.
+ (line 49)
+* &&: Arithmetic & logical.
+ (line 47)
+* *: Pens. (line 15)
+* * <1>: Arithmetic & logical.
+ (line 16)
+* **: Arithmetic & logical.
+ (line 31)
+* *=: Self & prefix operators.
+ (line 6)
+* +: Pens. (line 15)
+* + <1>: Arithmetic & logical.
+ (line 13)
+* ++: Self & prefix operators.
+ (line 6)
+* +=: Self & prefix operators.
+ (line 6)
+* -: Arithmetic & logical.
+ (line 14)
+* --: Paths. (line 16)
+* -- <1>: Self & prefix operators.
+ (line 6)
+* ---: Bezier curves. (line 84)
+* -=: Self & prefix operators.
+ (line 6)
+* -c: Options. (line 186)
+* -l: Options. (line 205)
+* -u: Options. (line 196)
+* -V: Configuring. (line 6)
+* -V <1>: Drawing in batch mode.
+ (line 16)
+* ..: Paths. (line 16)
+* .asy: Search paths. (line 12)
+* /: Arithmetic & logical.
+ (line 18)
+* /=: Self & prefix operators.
+ (line 6)
+* 2D graphs: graph. (line 6)
+* 3D graphs: graph3. (line 6)
+* 3D grids: grid3. (line 6)
+* 3D PostScript: three. (line 580)
+* :: Arithmetic & logical.
+ (line 61)
+* ::: Bezier curves. (line 70)
+* <: Arithmetic & logical.
+ (line 39)
+* <=: Arithmetic & logical.
+ (line 41)
+* ==: Structures. (line 62)
+* == <1>: Arithmetic & logical.
+ (line 36)
+* >: Arithmetic & logical.
+ (line 45)
+* >=: Arithmetic & logical.
+ (line 43)
+* ?: Arithmetic & logical.
+ (line 61)
+* ^: Arithmetic & logical.
+ (line 29)
+* ^ <1>: Arithmetic & logical.
+ (line 55)
+* ^=: Self & prefix operators.
+ (line 6)
+* ^^: Paths. (line 23)
+* |: Arithmetic & logical.
+ (line 53)
+* ||: Arithmetic & logical.
+ (line 51)
+* a4: Configuring. (line 58)
+* abort: Data types. (line 363)
+* abs: Data types. (line 65)
+* abs <1>: Mathematical functions.
+ (line 35)
+* accel: Paths and guides. (line 126)
+* accel <1>: Paths and guides. (line 132)
+* accel <2>: three. (line 481)
+* access: Import. (line 6)
+* acknowledgments: Credits. (line 6)
+* acos: Mathematical functions.
+ (line 6)
+* aCos: Mathematical functions.
+ (line 20)
+* acosh: Mathematical functions.
+ (line 6)
+* add: Frames and pictures.
+ (line 212)
+* add <1>: Frames and pictures.
+ (line 228)
+* add <2>: three. (line 253)
+* addViews: three. (line 374)
+* adjust: Pens. (line 123)
+* Ai: Mathematical functions.
+ (line 48)
+* Airy: Mathematical functions.
+ (line 48)
+* Ai_deriv: Mathematical functions.
+ (line 48)
+* alias: Structures. (line 62)
+* alias <1>: Arrays. (line 174)
+* Align: label. (line 12)
+* aligndir: Options. (line 178)
+* all: Arrays. (line 325)
+* Allow: Pens. (line 347)
+* and: Bezier curves. (line 56)
+* AND: Arithmetic & logical.
+ (line 68)
+* angle: Data types. (line 73)
+* animate: Configuring. (line 64)
+* animate <1>: Files. (line 155)
+* animate <2>: animation. (line 12)
+* animation: animation. (line 6)
+* animation <1>: animation. (line 6)
+* annotate: annotate. (line 6)
+* antialias: three. (line 192)
+* antialias <1>: Options. (line 149)
+* append: Files. (line 36)
+* append <1>: Arrays. (line 39)
+* arc: Paths and guides. (line 24)
+* Arc: Paths and guides. (line 37)
+* arc <1>: three. (line 264)
+* ArcArrow: draw. (line 26)
+* ArcArrow3: three. (line 547)
+* ArcArrows: draw. (line 26)
+* ArcArrows3: three. (line 547)
+* arclength: Paths and guides. (line 153)
+* arclength <1>: three. (line 481)
+* arcpoint: Paths and guides. (line 163)
+* arctime: Paths and guides. (line 157)
+* arctime <1>: three. (line 481)
+* arguments: Default arguments. (line 6)
+* arithmetic operators: Arithmetic & logical.
+ (line 6)
+* array: Data types. (line 283)
+* array <1>: Arrays. (line 112)
+* array iteration: Programming. (line 52)
+* arrays: Arrays. (line 6)
+* arrow: Drawing commands. (line 31)
+* Arrow: draw. (line 26)
+* arrow <1>: label. (line 70)
+* arrow keys: Drawing in interactive mode.
+ (line 11)
+* arrow keys <1>: GUI usage. (line 6)
+* Arrow3: three. (line 547)
+* arrows: draw. (line 26)
+* Arrows: draw. (line 26)
+* Arrows3: three. (line 547)
+* as: Import. (line 67)
+* ascii: Data types. (line 308)
+* ascii <1>: Data types. (line 308)
+* asin: Mathematical functions.
+ (line 6)
+* aSin: Mathematical functions.
+ (line 20)
+* asinh: Mathematical functions.
+ (line 6)
+* Aspect: Frames and pictures.
+ (line 59)
+* assert: Data types. (line 368)
+* assignment: Programming. (line 26)
+* asy: Data types. (line 358)
+* asy <1>: Import. (line 101)
+* asy-mode: Editing modes. (line 6)
+* asy.vim: Editing modes. (line 32)
+* asyinclude: LaTeX usage. (line 45)
+* asymptote.sty: LaTeX usage. (line 6)
+* asymptote.xml: Editing modes. (line 48)
+* ASYMPTOTE_CONFIG: Options. (line 120)
+* atan: Mathematical functions.
+ (line 6)
+* aTan: Mathematical functions.
+ (line 20)
+* atan2: Mathematical functions.
+ (line 6)
+* atanh: Mathematical functions.
+ (line 6)
+* atleast: Bezier curves. (line 56)
+* attach: Frames and pictures.
+ (line 273)
+* attach <1>: LaTeX usage. (line 50)
+* attach <2>: graph. (line 407)
+* autoadjust: three. (line 339)
+* autoimport: Options. (line 116)
+* automatic scaling: graph. (line 691)
+* automatic scaling <1>: graph. (line 691)
+* axialshade: fill. (line 43)
+* axis: graph. (line 906)
+* axis <1>: graph. (line 989)
+* axis <2>: graph3. (line 66)
+* axis <3>: graph3. (line 82)
+* azimuth: Data types. (line 153)
+* babel: babel. (line 6)
+* background color: Frames and pictures.
+ (line 180)
+* BackView: three. (line 367)
+* Bar: draw. (line 19)
+* Bar3: three. (line 547)
+* Bars: draw. (line 19)
+* Bars3: three. (line 547)
+* barsize: draw. (line 19)
+* base modules: Base modules. (line 6)
+* basealign: Pens. (line 181)
+* baseline: label. (line 90)
+* batch mode: Drawing in batch mode.
+ (line 6)
+* beep: Data types. (line 381)
+* BeginArcArrow: draw. (line 26)
+* BeginArcArrow3: three. (line 547)
+* BeginArrow: draw. (line 26)
+* BeginArrow3: three. (line 547)
+* BeginBar: draw. (line 19)
+* BeginBar3: three. (line 547)
+* BeginDotMargin: draw. (line 42)
+* BeginDotMargin3: three. (line 563)
+* BeginMargin: draw. (line 42)
+* BeginMargin3: three. (line 563)
+* BeginPenMargin: draw. (line 42)
+* BeginPenMargin2: three. (line 563)
+* BeginPenMargin3: three. (line 563)
+* BeginPoint: label. (line 55)
+* Bessel: Mathematical functions.
+ (line 48)
+* bevel: flowchart. (line 72)
+* beveljoin: Pens. (line 149)
+* Bezier curves: Bezier curves. (line 6)
+* Bezier patch: three. (line 88)
+* Bezier triangle: three. (line 88)
+* bezulate: three. (line 106)
+* Bi: Mathematical functions.
+ (line 48)
+* Billboard: three. (line 451)
+* binary: Files. (line 76)
+* binary format: Files. (line 76)
+* binary operators: Arithmetic & logical.
+ (line 6)
+* binarytree: binarytree. (line 6)
+* Bi_deriv: Mathematical functions.
+ (line 48)
+* black stripes: three. (line 192)
+* Blank: draw. (line 26)
+* block.bottom: flowchart. (line 19)
+* block.bottomleft: flowchart. (line 19)
+* block.bottomright: flowchart. (line 19)
+* block.center: flowchart. (line 24)
+* block.draw: flowchart. (line 29)
+* block.left: flowchart. (line 19)
+* block.position: flowchart. (line 23)
+* block.right: flowchart. (line 19)
+* block.top: flowchart. (line 19)
+* block.topleft: flowchart. (line 19)
+* block.topright: flowchart. (line 19)
+* bool: Data types. (line 14)
+* bool3: Data types. (line 25)
+* boolean operators: Arithmetic & logical.
+ (line 6)
+* Bottom: graph. (line 132)
+* BottomTop: graph. (line 138)
+* BottomView: three. (line 367)
+* bounding box: Frames and pictures.
+ (line 180)
+* Bounds: graph3. (line 21)
+* box: Frames and pictures.
+ (line 25)
+* box <1>: Frames and pictures.
+ (line 130)
+* box <2>: three. (line 286)
+* box <3>: three. (line 288)
+* bp: Drawing in batch mode.
+ (line 23)
+* brace: Paths and guides. (line 51)
+* break: Programming. (line 48)
+* breakpoints: Debugger. (line 21)
+* brick: Pens. (line 269)
+* broken axis: graph. (line 802)
+* bug reports: Help. (line 19)
+* buildcycle: Paths and guides. (line 270)
+* Button-1: GUI. (line 6)
+* Button-2: GUI. (line 6)
+* BWRainbow: palette. (line 15)
+* BWRainbow2: palette. (line 18)
+* C string: Data types. (line 216)
+* CAD: CAD. (line 6)
+* calculateTransform: Frames and pictures.
+ (line 118)
+* camera: three. (line 333)
+* casts: Casts. (line 6)
+* cbrt: Mathematical functions.
+ (line 6)
+* cd: Files. (line 25)
+* ceil: Mathematical functions.
+ (line 26)
+* Center: label. (line 60)
+* center: three. (line 316)
+* checker: Pens. (line 269)
+* Chinese: unicode. (line 12)
+* choose: Mathematical functions.
+ (line 39)
+* Ci: Mathematical functions.
+ (line 48)
+* circle: Paths and guides. (line 10)
+* Circle: Paths and guides. (line 18)
+* circle <1>: three. (line 260)
+* circle <2>: flowchart. (line 61)
+* circlebarframe: markers. (line 18)
+* CJK: unicode. (line 12)
+* clamped: graph. (line 36)
+* clear: Files. (line 93)
+* clear <1>: Debugger. (line 23)
+* clip: clip. (line 6)
+* CLZ: Arithmetic & logical.
+ (line 68)
+* cm: Figure size. (line 18)
+* cmd: Configuring. (line 31)
+* cmyk: Pens. (line 38)
+* colatitude: Data types. (line 158)
+* color: Pens. (line 23)
+* coloredNodes: tube. (line 25)
+* coloredpath: tube. (line 18)
+* coloredSegments: tube. (line 25)
+* colorless: Pens. (line 57)
+* colors: Pens. (line 54)
+* comma: Files. (line 61)
+* comma-separated-value mode: Arrays. (line 357)
+* command-line options: Configuring. (line 83)
+* command-line options <1>: Options. (line 6)
+* comment character: Files. (line 16)
+* compass directions: Labels. (line 18)
+* Compiling from UNIX source: Compiling from UNIX source.
+ (line 6)
+* complement: Arrays. (line 140)
+* concat: Arrays. (line 170)
+* conditional: Programming. (line 26)
+* conditional <1>: Arithmetic & logical.
+ (line 61)
+* config: Configuring. (line 64)
+* config <1>: Options. (line 120)
+* configuration file: Configuring. (line 21)
+* configuration file <1>: Options. (line 120)
+* configuring: Configuring. (line 6)
+* conj: Data types. (line 62)
+* constructors: Structures. (line 91)
+* context: Options. (line 149)
+* continue: Programming. (line 48)
+* continue <1>: Debugger. (line 31)
+* contour: contour. (line 6)
+* contour3: contour3. (line 6)
+* controls: Bezier curves. (line 45)
+* controls <1>: three. (line 6)
+* controlSpecifier: Paths and guides. (line 396)
+* convert: Configuring. (line 64)
+* convert <1>: Files. (line 155)
+* convert <2>: animation. (line 6)
+* convert <3>: Options. (line 149)
+* convertOptions: Options. (line 135)
+* Coons shading: fill. (line 77)
+* copy: Arrays. (line 167)
+* cos: Mathematical functions.
+ (line 6)
+* Cos: Mathematical functions.
+ (line 20)
+* cosh: Mathematical functions.
+ (line 6)
+* cputime: Structures. (line 169)
+* crop: graph. (line 640)
+* cropping graphs: graph. (line 640)
+* cross: Data types. (line 106)
+* cross <1>: Data types. (line 196)
+* cross <2>: graph. (line 481)
+* crossframe: markers. (line 22)
+* crosshatch: Pens. (line 286)
+* csv: Arrays. (line 357)
+* CTZ: Arithmetic & logical.
+ (line 68)
+* cubicroots: Arrays. (line 314)
+* curl: Bezier curves. (line 66)
+* curl <1>: three. (line 6)
+* curlSpecifier: Paths and guides. (line 408)
+* currentpen: Pens. (line 6)
+* currentprojection: three. (line 364)
+* curve: slopefield. (line 20)
+* custom axis types: graph. (line 141)
+* custom mark routine: graph. (line 578)
+* custom tick locations: graph. (line 233)
+* cut: Paths and guides. (line 251)
+* cycle: Figure size. (line 29)
+* cycle <1>: Paths. (line 16)
+* cycle <2>: three. (line 6)
+* cyclic: Paths and guides. (line 85)
+* cyclic <1>: Paths and guides. (line 376)
+* cyclic <2>: Arrays. (line 39)
+* cyclic <3>: three. (line 481)
+* Cyrillic: unicode. (line 7)
+* dashdotted: Pens. (line 102)
+* dashed: Pens. (line 102)
+* data types: Data types. (line 6)
+* date: Data types. (line 320)
+* Debian: UNIX binary distributions.
+ (line 19)
+* debugger: Debugger. (line 6)
+* declaration: Programming. (line 26)
+* deconstruct: GUI usage. (line 6)
+* default arguments: Default arguments. (line 6)
+* defaultformat: graph. (line 175)
+* DefaultHead: draw. (line 26)
+* DefaultHead3: three. (line 547)
+* defaultpen: Pens. (line 49)
+* defaultpen <1>: Pens. (line 122)
+* defaultpen <2>: Pens. (line 127)
+* defaultpen <3>: Pens. (line 139)
+* defaultpen <4>: Pens. (line 192)
+* defaultpen <5>: Pens. (line 347)
+* defaultpen <6>: Pens. (line 371)
+* defaultrender: three. (line 46)
+* deferred drawing: simplex. (line 6)
+* degrees: Data types. (line 78)
+* degrees <1>: Mathematical functions.
+ (line 17)
+* Degrees: Mathematical functions.
+ (line 17)
+* delete: Files. (line 150)
+* delete <1>: Arrays. (line 39)
+* description: Description. (line 6)
+* diagonal: Arrays. (line 299)
+* diamond: flowchart. (line 54)
+* dimension: Arrays. (line 362)
+* dir: Search paths. (line 9)
+* dir <1>: Data types. (line 90)
+* dir <2>: Data types. (line 180)
+* dir <3>: Paths and guides. (line 109)
+* dir <4>: three. (line 481)
+* direction specifier: Bezier curves. (line 6)
+* directory: Files. (line 25)
+* dirSpecifier: Paths and guides. (line 390)
+* dirtime: Paths and guides. (line 166)
+* display: Configuring. (line 64)
+* do: Programming. (line 48)
+* DOSendl: Files. (line 61)
+* DOSnewl: Files. (line 61)
+* dot: draw. (line 82)
+* dot <1>: Data types. (line 103)
+* dot <2>: Data types. (line 193)
+* dot <3>: Arrays. (line 254)
+* dot <4>: Arrays. (line 257)
+* DotMargin: draw. (line 42)
+* DotMargin3: three. (line 563)
+* DotMargins: draw. (line 42)
+* DotMargins3: three. (line 563)
+* dotted: Pens. (line 102)
+* double deferred drawing: three. (line 238)
+* double precision: Files. (line 76)
+* draw: Drawing commands. (line 31)
+* draw <1>: draw. (line 6)
+* Draw: draw. (line 26)
+* draw <2>: draw. (line 112)
+* Draw <1>: Frames and pictures.
+ (line 160)
+* draw <3>: three. (line 114)
+* drawing commands: Drawing commands. (line 6)
+* drawline: math. (line 9)
+* drawtree: drawtree. (line 6)
+* dvips: Configuring. (line 64)
+* dvipsOptions: Options. (line 135)
+* dvisvgm: Configuring. (line 64)
+* dvisvgm <1>: Options. (line 154)
+* dvisvgmOptions: Options. (line 135)
+* E: Labels. (line 18)
+* E <1>: Mathematical functions.
+ (line 48)
+* Editing modes: Editing modes. (line 6)
+* Ei: Mathematical functions.
+ (line 48)
+* ellipse: Paths and guides. (line 45)
+* ellipse <1>: Frames and pictures.
+ (line 25)
+* elliptic functions: Mathematical functions.
+ (line 48)
+* else: Programming. (line 26)
+* emacs: Editing modes. (line 6)
+* embed: embed. (line 6)
+* Embedded: three. (line 451)
+* empty: Frames and pictures.
+ (line 7)
+* EndArcArrow: draw. (line 26)
+* EndArcArrow3: three. (line 547)
+* EndArrow: draw. (line 26)
+* EndArrow3: three. (line 547)
+* EndBar: draw. (line 19)
+* EndBar3: three. (line 547)
+* EndDotMargin: draw. (line 42)
+* EndDotMargin3: three. (line 563)
+* endl: Files. (line 61)
+* EndMargin: draw. (line 42)
+* EndMargin3: three. (line 563)
+* EndPenMargin: draw. (line 42)
+* EndPenMargin2: three. (line 563)
+* EndPenMargin3: three. (line 563)
+* EndPoint: label. (line 55)
+* envelope: Frames and pictures.
+ (line 25)
+* environment variables: Configuring. (line 87)
+* eof: Files. (line 93)
+* eof <1>: Arrays. (line 339)
+* eol: Files. (line 93)
+* eol <1>: Arrays. (line 339)
+* EPS: label. (line 78)
+* EPS <1>: Options. (line 149)
+* erase: Drawing in interactive mode.
+ (line 11)
+* erase <1>: Data types. (line 256)
+* erase <2>: Frames and pictures.
+ (line 7)
+* erase <3>: Frames and pictures.
+ (line 281)
+* erf: Mathematical functions.
+ (line 6)
+* erfc: Mathematical functions.
+ (line 6)
+* error: Files. (line 16)
+* error <1>: Files. (line 93)
+* error bars: graph. (line 532)
+* errorbars: graph. (line 481)
+* eval: Import. (line 97)
+* eval <1>: Import. (line 107)
+* evenodd: Paths. (line 37)
+* evenodd <1>: Pens. (line 164)
+* exit: Data types. (line 372)
+* exit <1>: Interactive mode. (line 54)
+* exit <2>: Debugger. (line 56)
+* exp: Mathematical functions.
+ (line 6)
+* expi: Data types. (line 86)
+* expi <1>: Data types. (line 176)
+* explicit: Casts. (line 6)
+* explicit casts: Casts. (line 21)
+* expm1: Mathematical functions.
+ (line 6)
+* exponential integral: Mathematical functions.
+ (line 48)
+* extendcap: Pens. (line 139)
+* extension: Paths and guides. (line 246)
+* extension <1>: MetaPost. (line 10)
+* external: embed. (line 11)
+* extrude: three. (line 475)
+* F: Mathematical functions.
+ (line 48)
+* fabs: Mathematical functions.
+ (line 6)
+* face: three. (line 588)
+* factorial: Mathematical functions.
+ (line 39)
+* Fedora: UNIX binary distributions.
+ (line 15)
+* feynman: feynman. (line 6)
+* fft: Arrays. (line 240)
+* fft <1>: math. (line 26)
+* FFTW: Compiling from UNIX source.
+ (line 63)
+* file: Files. (line 6)
+* file <1>: Debugger. (line 44)
+* Fill: draw. (line 26)
+* fill: draw. (line 117)
+* fill <1>: fill. (line 6)
+* fill <2>: fill. (line 17)
+* Fill <1>: Frames and pictures.
+ (line 146)
+* FillDraw: draw. (line 26)
+* filldraw: fill. (line 11)
+* FillDraw <1>: Frames and pictures.
+ (line 136)
+* filloutside: fill. (line 27)
+* fillrule: Pens. (line 164)
+* find: Data types. (line 241)
+* find <1>: Arrays. (line 149)
+* findall: Arrays. (line 154)
+* firstcut: Paths and guides. (line 262)
+* fit: Frames and pictures.
+ (line 113)
+* fit3: three. (line 251)
+* fixedscaling: Frames and pictures.
+ (line 81)
+* floor: Mathematical functions.
+ (line 26)
+* flowchart: flowchart. (line 6)
+* flush: Files. (line 61)
+* flush <1>: Files. (line 93)
+* fmod: Mathematical functions.
+ (line 6)
+* font: Pens. (line 206)
+* font command: Pens. (line 206)
+* fontcommand: Pens. (line 221)
+* fontsize: Pens. (line 192)
+* for: Programming. (line 26)
+* format: Data types. (line 289)
+* format <1>: Options. (line 149)
+* forum: Help. (line 6)
+* frame: Frames and pictures.
+ (line 7)
+* from: Import. (line 16)
+* FrontView: three. (line 367)
+* function declarations: Functions. (line 79)
+* Function shading: fill. (line 99)
+* function shading: fill. (line 99)
+* functions: Functions. (line 6)
+* functions <1>: Mathematical functions.
+ (line 6)
+* functionshade: fill. (line 99)
+* gamma: Mathematical functions.
+ (line 6)
+* Gaussrand: Mathematical functions.
+ (line 39)
+* geometry: geometry. (line 6)
+* getc: Files. (line 30)
+* getpair: Files. (line 118)
+* getreal: Files. (line 118)
+* getstring: Files. (line 118)
+* gettriple: Files. (line 118)
+* git: Git. (line 6)
+* glOptions: three. (line 192)
+* glOptions <1>: Options. (line 135)
+* GNU Scientific Library: Mathematical functions.
+ (line 48)
+* gouraudshade: fill. (line 62)
+* Gradient: palette. (line 25)
+* gradient shading: fill. (line 32)
+* graph: graph. (line 6)
+* graph3: graph3. (line 6)
+* graphic: label. (line 78)
+* graphical user interface: GUI. (line 6)
+* gray: Pens. (line 25)
+* grayscale: Pens. (line 25)
+* Grayscale: palette. (line 9)
+* grid: Pens. (line 269)
+* grid <1>: graph. (line 747)
+* grid3: grid3. (line 6)
+* gs: Configuring. (line 6)
+* GSL: Compiling from UNIX source.
+ (line 63)
+* gsl: Mathematical functions.
+ (line 48)
+* gsOptions: Options. (line 135)
+* GUI: GUI. (line 6)
+* GUI installation: GUI installation. (line 6)
+* GUI usage: GUI usage. (line 6)
+* guide: Paths and guides. (line 314)
+* guide3: three. (line 6)
+* hatch: Pens. (line 286)
+* height: LaTeX usage. (line 50)
+* help: Interactive mode. (line 42)
+* help <1>: Help. (line 6)
+* help <2>: Debugger. (line 30)
+* Hermite: graph. (line 36)
+* Hermite(splinetype splinetype: graph. (line 36)
+* hex: Data types. (line 305)
+* hex <1>: Pens. (line 64)
+* hexadecimal: Data types. (line 305)
+* hexadecimal <1>: Pens. (line 62)
+* hidden surface removal: three. (line 588)
+* histogram: Mathematical functions.
+ (line 39)
+* history: Files. (line 143)
+* history <1>: Interactive mode. (line 54)
+* historylines: Interactive mode. (line 57)
+* HookHead: draw. (line 26)
+* HookHead3: three. (line 547)
+* Horizontal: flowchart. (line 77)
+* hyperrefOptions: Options. (line 135)
+* hypot: Mathematical functions.
+ (line 6)
+* I: Mathematical functions.
+ (line 48)
+* iconify: three. (line 192)
+* identity: Transforms. (line 24)
+* identity <1>: Mathematical functions.
+ (line 6)
+* identity <2>: Arrays. (line 296)
+* identity4: three. (line 419)
+* if: Programming. (line 26)
+* IgnoreAspect: Frames and pictures.
+ (line 63)
+* image: palette. (line 33)
+* image <1>: palette. (line 58)
+* ImageMagick: Configuring. (line 64)
+* ImageMagick <1>: animation. (line 6)
+* ImageMagick <2>: Options. (line 149)
+* images: palette. (line 6)
+* implicit casts: Casts. (line 6)
+* implicit linear solver: MetaPost. (line 10)
+* implicit scaling: Implicit scaling. (line 6)
+* implicitsurface: smoothcontour3. (line 16)
+* import: Import. (line 45)
+* inches: Figure size. (line 18)
+* incircle: Data types. (line 120)
+* include: Import. (line 126)
+* including images: label. (line 78)
+* increasing: math. (line 59)
+* inf: Data types. (line 35)
+* inheritance: Structures. (line 181)
+* initialized: Arrays. (line 39)
+* initializers: Variable initializers.
+ (line 6)
+* inline: LaTeX usage. (line 50)
+* InOutTicks: graph3. (line 35)
+* input: Files. (line 10)
+* input <1>: Files. (line 12)
+* input <2>: Interactive mode. (line 45)
+* input <3>: Interactive mode. (line 49)
+* insert: Data types. (line 252)
+* insert <1>: Arrays. (line 39)
+* inside: Paths and guides. (line 294)
+* inside <1>: Paths and guides. (line 299)
+* inside <2>: Paths and guides. (line 305)
+* insphere: three. (line 510)
+* inst: Debugger. (line 35)
+* installation: Installation. (line 6)
+* int: Data types. (line 30)
+* integer division: Arithmetic & logical.
+ (line 20)
+* integral: Mathematical functions.
+ (line 82)
+* integrate: Mathematical functions.
+ (line 82)
+* interactive mode: Drawing in interactive mode.
+ (line 6)
+* interactive mode <1>: Interactive mode. (line 6)
+* interior: Paths and guides. (line 290)
+* international characters: unicode. (line 6)
+* interp: Arithmetic & logical.
+ (line 64)
+* interpolate: interpolate. (line 6)
+* intersect: Paths and guides. (line 195)
+* intersect <1>: math. (line 13)
+* intersect <2>: three. (line 481)
+* intersectionpoint: Paths and guides. (line 238)
+* intersectionpoint <1>: math. (line 17)
+* intersectionpoint <2>: three. (line 481)
+* intersectionpoints: Paths and guides. (line 242)
+* intersectionpoints <1>: three. (line 481)
+* intersectionpoints <2>: three. (line 494)
+* intersections: Paths and guides. (line 206)
+* intersections <1>: Paths and guides. (line 213)
+* intersections <2>: three. (line 481)
+* intersections <3>: three. (line 487)
+* InTicks: graph3. (line 35)
+* intMax: Data types. (line 30)
+* intMin: Data types. (line 30)
+* inverse: Transforms. (line 16)
+* inverse <1>: Arrays. (line 302)
+* invert: three. (line 409)
+* invisible: Pens. (line 43)
+* isnan: Data types. (line 35)
+* i_scaled: Mathematical functions.
+ (line 48)
+* J: Mathematical functions.
+ (line 6)
+* J <1>: Mathematical functions.
+ (line 48)
+* Japanese: unicode. (line 12)
+* K: Mathematical functions.
+ (line 48)
+* Kate: Editing modes. (line 48)
+* KDE editor: Editing modes. (line 48)
+* keepAspect: Frames and pictures.
+ (line 59)
+* keepAspect <1>: Frames and pictures.
+ (line 63)
+* keepAspect <2>: LaTeX usage. (line 50)
+* keyboard bindings:: three. (line 170)
+* keys: Arrays. (line 39)
+* keyword: Named arguments. (line 37)
+* keyword-only: Named arguments. (line 37)
+* keywords: Named arguments. (line 6)
+* Korean: unicode. (line 12)
+* k_scaled: Mathematical functions.
+ (line 48)
+* label: Labels. (line 6)
+* Label: draw. (line 100)
+* label <1>: label. (line 6)
+* Label <1>: label. (line 14)
+* Label <2>: graph. (line 330)
+* label <2>: three. (line 445)
+* labelpath: labelpath. (line 6)
+* labelpath3: labelpath3. (line 6)
+* labelx: graph. (line 330)
+* labely: graph. (line 330)
+* Landscape: Frames and pictures.
+ (line 104)
+* lastcut: Paths and guides. (line 266)
+* lasy-mode: Editing modes. (line 6)
+* latex: Options. (line 149)
+* LaTeX fonts: Pens. (line 206)
+* LaTeX usage: LaTeX usage. (line 6)
+* latexmk: LaTeX usage. (line 30)
+* latin1: latin1. (line 6)
+* latitude: Data types. (line 163)
+* latticeshade: fill. (line 32)
+* layer: Drawing commands. (line 16)
+* leastsquares: stats. (line 6)
+* leastsquares <1>: graph. (line 930)
+* Left: graph. (line 269)
+* LeftRight: graph. (line 275)
+* LeftSide: label. (line 60)
+* LeftTicks: graph. (line 160)
+* LeftTicks <1>: graph. (line 233)
+* LeftView: three. (line 367)
+* legend: Drawing commands. (line 31)
+* legend <1>: draw. (line 64)
+* legend <2>: graph. (line 425)
+* Legendre: Mathematical functions.
+ (line 48)
+* length: Data types. (line 65)
+* length <1>: Data types. (line 144)
+* length <2>: Data types. (line 238)
+* length <3>: Paths and guides. (line 76)
+* length <4>: Paths and guides. (line 373)
+* length <5>: Arrays. (line 39)
+* length <6>: three. (line 481)
+* letter: Configuring. (line 58)
+* lexorder: math. (line 67)
+* lexorder <1>: math. (line 70)
+* libgs: Configuring. (line 64)
+* libgs <1>: Options. (line 154)
+* libm routines: Mathematical functions.
+ (line 6)
+* libsigsegv: Functions. (line 100)
+* libsigsegv <1>: Help. (line 27)
+* limits: graph. (line 640)
+* line: Arrays. (line 339)
+* line <1>: Arrays. (line 343)
+* line mode: Arrays. (line 339)
+* Linear: graph. (line 691)
+* linecap: Pens. (line 139)
+* linejoin: Pens. (line 149)
+* lineskip: Pens. (line 192)
+* linetype: Pens. (line 123)
+* linewidth: Pens. (line 127)
+* locale: Data types. (line 315)
+* log: Mathematical functions.
+ (line 6)
+* Log: graph. (line 691)
+* log-log graph: graph. (line 725)
+* log10: Mathematical functions.
+ (line 6)
+* log1p: Mathematical functions.
+ (line 6)
+* log2 graph: graph. (line 781)
+* logarithmic graph: graph. (line 725)
+* logical operators: Arithmetic & logical.
+ (line 6)
+* longdashdotted: Pens. (line 102)
+* longdashed: Pens. (line 102)
+* longitude: Data types. (line 168)
+* loop: Programming. (line 26)
+* lualatex: Options. (line 149)
+* luatex: Options. (line 149)
+* MacOS X binary distributions: MacOS X binary distributions.
+ (line 6)
+* makepen: Pens. (line 322)
+* map: Arrays. (line 131)
+* Margin: draw. (line 42)
+* Margin <1>: draw. (line 42)
+* Margin3: three. (line 563)
+* Margin3 <1>: three. (line 563)
+* Margins: draw. (line 42)
+* margins: three. (line 244)
+* Margins3: three. (line 563)
+* mark: graph. (line 481)
+* markangle: markers. (line 35)
+* marker: graph. (line 481)
+* markers: markers. (line 6)
+* marknodes: graph. (line 481)
+* markuniform: graph. (line 481)
+* mask: Data types. (line 35)
+* math: math. (line 6)
+* mathematical functions: Mathematical functions.
+ (line 6)
+* max: Paths and guides. (line 279)
+* max <1>: Frames and pictures.
+ (line 7)
+* max <2>: Arrays. (line 221)
+* max <3>: Arrays. (line 231)
+* max <4>: three. (line 481)
+* maxbound: Data types. (line 134)
+* maxbound <1>: Data types. (line 204)
+* maxtile: three. (line 192)
+* maxtimes: Paths and guides. (line 233)
+* maxviewport: three. (line 192)
+* MetaPost: MetaPost. (line 6)
+* MetaPost ... : Bezier curves. (line 70)
+* MetaPost cutafter: Paths and guides. (line 267)
+* MetaPost cutbefore: Paths and guides. (line 263)
+* MetaPost pickup: Pens. (line 6)
+* MetaPost whatever: MetaPost. (line 10)
+* Microsoft Windows: Microsoft Windows. (line 6)
+* MidArcArrow: draw. (line 26)
+* MidArcArrow3: three. (line 547)
+* MidArrow: draw. (line 26)
+* MidArrow3: three. (line 547)
+* MidPoint: label. (line 55)
+* midpoint: Paths and guides. (line 180)
+* min: Paths and guides. (line 275)
+* min <1>: Frames and pictures.
+ (line 7)
+* min <2>: Arrays. (line 216)
+* min <3>: Arrays. (line 226)
+* min <4>: three. (line 481)
+* minbound: Data types. (line 131)
+* minbound <1>: Data types. (line 201)
+* minipage: label. (line 116)
+* mintimes: Paths and guides. (line 228)
+* miterjoin: Pens. (line 149)
+* miterlimit: Pens. (line 159)
+* mktemp: Files. (line 44)
+* mm: Figure size. (line 18)
+* mode: Files. (line 76)
+* mode <1>: Files. (line 89)
+* monotonic: graph. (line 36)
+* mouse: GUI. (line 6)
+* mouse bindings: three. (line 151)
+* mouse wheel: GUI usage. (line 6)
+* Move: Pens. (line 359)
+* MoveQuiet: Pens. (line 365)
+* multisample: three. (line 142)
+* N: Labels. (line 18)
+* name: Files. (line 89)
+* named arguments: Named arguments. (line 6)
+* nan: Data types. (line 35)
+* natural: graph. (line 36)
+* new: Structures. (line 6)
+* new <1>: Arrays. (line 100)
+* new <2>: Arrays. (line 103)
+* newframe: Frames and pictures.
+ (line 7)
+* newl: Files. (line 61)
+* newton: Mathematical functions.
+ (line 66)
+* newton <1>: Mathematical functions.
+ (line 73)
+* next: Debugger. (line 41)
+* NFSS: Pens. (line 206)
+* nobasealign: Pens. (line 181)
+* NoFill: draw. (line 26)
+* NoFill <1>: Frames and pictures.
+ (line 154)
+* NoMargin: draw. (line 42)
+* NoMargin3: three. (line 563)
+* None: draw. (line 19)
+* None <1>: draw. (line 26)
+* none: Files. (line 61)
+* normal: three. (line 467)
+* nosafe: Options. (line 173)
+* NOT: Arithmetic & logical.
+ (line 68)
+* notaknot: graph. (line 36)
+* NoTicks: graph. (line 160)
+* NoTicks3: graph3. (line 35)
+* null: Structures. (line 6)
+* nullpen: label. (line 14)
+* nullpen <1>: Frames and pictures.
+ (line 140)
+* nullpen <2>: Frames and pictures.
+ (line 149)
+* NURBS: three. (line 343)
+* O: three. (line 256)
+* obj: obj. (line 6)
+* oblique: three. (line 299)
+* obliqueX: three. (line 306)
+* obliqueY: three. (line 312)
+* obliqueZ: three. (line 299)
+* ode: ode. (line 6)
+* offset: Pens. (line 123)
+* offset <1>: Options. (line 178)
+* OmitTick: graph. (line 223)
+* OmitTickInterval: graph. (line 223)
+* OmitTickIntervals: graph. (line 223)
+* opacity: Pens. (line 237)
+* open: Files. (line 12)
+* OpenGL: three. (line 142)
+* operator: User-defined operators.
+ (line 6)
+* operator +(...string[] a).: Data types. (line 283)
+* operator --: graph. (line 30)
+* operator ..: graph. (line 33)
+* operator answer: Interactive mode. (line 35)
+* operator cast: Casts. (line 38)
+* operator ecast: Casts. (line 65)
+* operator init: Variable initializers.
+ (line 6)
+* operator init <1>: Structures. (line 134)
+* operators: Operators. (line 6)
+* options: Options. (line 6)
+* OR: Arithmetic & logical.
+ (line 68)
+* orient: Data types. (line 108)
+* orient <1>: three. (line 498)
+* orientation: Frames and pictures.
+ (line 104)
+* orthographic: three. (line 316)
+* outformat: three. (line 142)
+* outprefix: Frames and pictures.
+ (line 91)
+* output: Files. (line 36)
+* output <1>: Options. (line 149)
+* OutTicks: graph3. (line 35)
+* overloading functions: Functions. (line 55)
+* overwrite: Pens. (line 344)
+* P: Mathematical functions.
+ (line 48)
+* pack: label. (line 100)
+* packing: Rest arguments. (line 30)
+* pair: Figure size. (line 6)
+* pair <1>: Data types. (line 46)
+* pairs: Arrays. (line 236)
+* paperheight: Configuring. (line 58)
+* papertype: Configuring. (line 58)
+* paperwidth: Configuring. (line 58)
+* parallelogram: flowchart. (line 47)
+* parametric surface: graph3. (line 99)
+* parametrized curve: graph. (line 640)
+* partialsum: math. (line 53)
+* partialsum <1>: math. (line 56)
+* patch-dependent colors: three. (line 79)
+* path: Paths. (line 6)
+* path <1>: Paths and guides. (line 7)
+* path <2>: three. (line 42)
+* path <3>: flowchart. (line 77)
+* path markers: graph. (line 481)
+* path3: three. (line 6)
+* path3 <1>: three. (line 42)
+* path[]: Paths. (line 23)
+* patterns: Pens. (line 255)
+* patterns <1>: patterns. (line 6)
+* PDF: Options. (line 149)
+* pdflatex: Options. (line 149)
+* pdfreloadOptions: Options. (line 135)
+* pdfviewer: Configuring. (line 6)
+* pdfviewerOptions: Options. (line 135)
+* pen: Pens. (line 6)
+* PenMargin: draw. (line 42)
+* PenMargin2: three. (line 563)
+* PenMargin3: three. (line 563)
+* PenMargins: draw. (line 42)
+* PenMargins2: three. (line 563)
+* PenMargins3: three. (line 563)
+* periodic: graph. (line 36)
+* perl: LaTeX usage. (line 30)
+* perpendicular: geometry. (line 6)
+* perspective: three. (line 343)
+* picture: Frames and pictures.
+ (line 39)
+* picture alignment: Frames and pictures.
+ (line 228)
+* piecewisestraight: Paths and guides. (line 92)
+* pixel: three. (line 570)
+* Pl: Mathematical functions.
+ (line 48)
+* plain: plain. (line 6)
+* planar: three. (line 88)
+* plane: three. (line 282)
+* planeproject: three. (line 464)
+* point: Paths and guides. (line 95)
+* point <1>: Paths and guides. (line 379)
+* point <2>: three. (line 481)
+* polar: Data types. (line 148)
+* polargraph: graph. (line 88)
+* polygon: graph. (line 481)
+* pop: Arrays. (line 39)
+* Portrait: Frames and pictures.
+ (line 104)
+* postcontrol: Paths and guides. (line 146)
+* postcontrol <1>: three. (line 481)
+* postfix operators: Self & prefix operators.
+ (line 19)
+* postscript: Frames and pictures.
+ (line 294)
+* PostScript fonts: Pens. (line 224)
+* PostScript subpath: Paths. (line 23)
+* pow10: Mathematical functions.
+ (line 6)
+* prc: three. (line 213)
+* precision: Files. (line 93)
+* precontrol: Paths and guides. (line 139)
+* precontrol <1>: three. (line 481)
+* prefix operators: Self & prefix operators.
+ (line 6)
+* private: Structures. (line 6)
+* programming: Programming. (line 6)
+* pstoedit: PostScript to Asymptote.
+ (line 6)
+* psviewer: Configuring. (line 6)
+* psviewerOptions: Options. (line 135)
+* pt: Figure size. (line 18)
+* public: Structures. (line 6)
+* push: Arrays. (line 39)
+* Python usage: Interactive mode. (line 72)
+* quadraticroots: Arrays. (line 305)
+* quadraticroots <1>: Arrays. (line 310)
+* quarticroots: math. (line 22)
+* quick reference: Description. (line 81)
+* quit: Drawing in interactive mode.
+ (line 11)
+* quit <1>: Interactive mode. (line 54)
+* quit <2>: Debugger. (line 53)
+* quote: Import. (line 115)
+* quotient: Arithmetic & logical.
+ (line 6)
+* radialshade: fill. (line 51)
+* RadialShade: Frames and pictures.
+ (line 172)
+* RadialShadeDraw: Frames and pictures.
+ (line 176)
+* radians: Mathematical functions.
+ (line 17)
+* radius: Paths and guides. (line 135)
+* radius <1>: three. (line 481)
+* Rainbow: palette. (line 12)
+* rand: Mathematical functions.
+ (line 39)
+* randMax: Mathematical functions.
+ (line 39)
+* read: Arrays. (line 379)
+* reading: Files. (line 12)
+* reading string arrays: Arrays. (line 349)
+* readline: Files. (line 135)
+* real: Data types. (line 35)
+* realDigits: Data types. (line 35)
+* realEpsilon: Data types. (line 35)
+* realMax: Data types. (line 35)
+* realMin: Data types. (line 35)
+* realmult: Data types. (line 100)
+* rectangle: flowchart. (line 34)
+* recursion: Functions. (line 100)
+* reference: Description. (line 81)
+* reflect: Transforms. (line 42)
+* Relative: label. (line 50)
+* Relative <1>: label. (line 60)
+* relpoint: Paths and guides. (line 176)
+* reltime: Paths and guides. (line 172)
+* remainder: Mathematical functions.
+ (line 6)
+* rename: Files. (line 152)
+* render: three. (line 46)
+* render <1>: three. (line 142)
+* render <2>: Options. (line 149)
+* replace: Data types. (line 269)
+* resetdefaultpen: Pens. (line 371)
+* rest arguments: Rest arguments. (line 6)
+* restore: Frames and pictures.
+ (line 288)
+* restricted: Structures. (line 6)
+* return: Debugger. (line 47)
+* reverse: Data types. (line 265)
+* reverse <1>: Paths and guides. (line 183)
+* reverse <2>: Paths and guides. (line 382)
+* reverse <3>: Arrays. (line 136)
+* reverse <4>: three. (line 481)
+* rewind: Files. (line 93)
+* rfind: Data types. (line 246)
+* rgb: Pens. (line 30)
+* rgb <1>: Pens. (line 34)
+* rgb <2>: Pens. (line 62)
+* Riemann zeta function: Mathematical functions.
+ (line 48)
+* Right: graph. (line 272)
+* RightSide: label. (line 60)
+* RightTicks: graph. (line 160)
+* RightTicks <1>: graph. (line 233)
+* RightView: three. (line 367)
+* Rotate: label. (line 36)
+* rotate: three. (line 435)
+* Rotate(pair z): label. (line 39)
+* round: Mathematical functions.
+ (line 26)
+* roundcap: Pens. (line 139)
+* roundedpath: roundedpath. (line 6)
+* roundjoin: Pens. (line 149)
+* roundrectangle: flowchart. (line 66)
+* RPM: UNIX binary distributions.
+ (line 6)
+* runtime imports: Import. (line 97)
+* Russian: unicode. (line 7)
+* S: Labels. (line 18)
+* safe: Options. (line 173)
+* save: Frames and pictures.
+ (line 285)
+* saveline: Files. (line 135)
+* Scale: label. (line 45)
+* scale: Pens. (line 123)
+* scale <1>: Transforms. (line 34)
+* scale <2>: Transforms. (line 36)
+* scale <3>: graph. (line 691)
+* Scale <1>: graph. (line 708)
+* scale <4>: three. (line 434)
+* scale3: three. (line 432)
+* scaled graph: graph. (line 671)
+* scientific graph: graph. (line 388)
+* scroll: Files. (line 109)
+* search: Arrays. (line 157)
+* search <1>: Arrays. (line 163)
+* search paths: Search paths. (line 6)
+* Seascape: Frames and pictures.
+ (line 110)
+* secondary axis: graph. (line 834)
+* secondaryX: graph. (line 834)
+* secondaryY: graph. (line 834)
+* seconds: Data types. (line 329)
+* seek: Files. (line 93)
+* seekeof: Files. (line 93)
+* segment: math. (line 50)
+* segmentation fault: Help. (line 27)
+* self operators: Self & prefix operators.
+ (line 6)
+* sequence: Arrays. (line 118)
+* settings: Configuring. (line 21)
+* settings <1>: Options. (line 120)
+* sgn: Mathematical functions.
+ (line 26)
+* shading: fill. (line 32)
+* Shift: label. (line 33)
+* shift: Transforms. (line 26)
+* shift <1>: Transforms. (line 28)
+* shift <2>: Transforms. (line 46)
+* shift <3>: three. (line 424)
+* shiftless: Transforms. (line 46)
+* shipout: Frames and pictures.
+ (line 91)
+* showtarget: three. (line 316)
+* Si: Mathematical functions.
+ (line 48)
+* signedint: Files. (line 76)
+* signedint <1>: Files. (line 89)
+* SimpleHead: draw. (line 26)
+* simplex: simplex. (line 6)
+* simpson: Mathematical functions.
+ (line 82)
+* sin: Mathematical functions.
+ (line 6)
+* Sin: Mathematical functions.
+ (line 20)
+* single precision: Files. (line 76)
+* singleint: Files. (line 76)
+* singleint <1>: Files. (line 89)
+* singlereal: Files. (line 76)
+* singlereal <1>: Files. (line 89)
+* sinh: Mathematical functions.
+ (line 6)
+* SixViews: three. (line 382)
+* SixViewsFR: three. (line 382)
+* SixViewsUS: three. (line 382)
+* size: Figure size. (line 6)
+* size <1>: Paths and guides. (line 81)
+* size <2>: Paths and guides. (line 370)
+* size <3>: Frames and pictures.
+ (line 48)
+* size <4>: Frames and pictures.
+ (line 74)
+* size <5>: three. (line 481)
+* size <6>: Options. (line 149)
+* size3: three. (line 241)
+* Slant: label. (line 42)
+* slant: Transforms. (line 38)
+* sleep: Data types. (line 375)
+* slice: Paths and guides. (line 251)
+* slice <1>: Paths and guides. (line 262)
+* slices: Slices. (line 6)
+* slide: slide. (line 6)
+* slope: math. (line 44)
+* slope <1>: math. (line 47)
+* slopefield: slopefield. (line 6)
+* smoothcontour3: smoothcontour3. (line 6)
+* sncndn: Mathematical functions.
+ (line 48)
+* solid: Pens. (line 102)
+* solids: solids. (line 6)
+* solve: Arrays. (line 274)
+* solve <1>: Arrays. (line 290)
+* sort: Arrays. (line 177)
+* sort <1>: Arrays. (line 181)
+* sort <2>: Arrays. (line 196)
+* Spline: graph. (line 33)
+* Spline <1>: graph3. (line 99)
+* split: Data types. (line 278)
+* sqrt: Mathematical functions.
+ (line 6)
+* squarecap: Pens. (line 139)
+* srand: Mathematical functions.
+ (line 39)
+* stack overflow: Functions. (line 100)
+* stack overflow <1>: Functions. (line 100)
+* stack overflow <2>: Help. (line 27)
+* static: Static. (line 6)
+* stats: stats. (line 6)
+* stdin: Files. (line 48)
+* stdout: Files. (line 48)
+* step: Debugger. (line 38)
+* stickframe: markers. (line 16)
+* stop: Debugger. (line 10)
+* straight: Paths and guides. (line 88)
+* Straight: graph. (line 30)
+* straight <1>: three. (line 481)
+* strftime: Data types. (line 320)
+* strftime <1>: Data types. (line 345)
+* string: Data types. (line 207)
+* string <1>: Data types. (line 311)
+* stroke: fill. (line 36)
+* stroke <1>: clip. (line 6)
+* strokepath: Paths and guides. (line 309)
+* strptime: Data types. (line 329)
+* struct: Structures. (line 6)
+* structures: Structures. (line 6)
+* subpath: Paths and guides. (line 186)
+* subpath <1>: three. (line 481)
+* subpictures: Frames and pictures.
+ (line 113)
+* substr: Data types. (line 261)
+* sum: Arrays. (line 211)
+* superpath: Paths. (line 23)
+* Suppress: Pens. (line 351)
+* SuppressQuiet: Pens. (line 355)
+* surface: three. (line 46)
+* surface <1>: three. (line 88)
+* surface <2>: three. (line 102)
+* surface <3>: graph3. (line 99)
+* SVG: Options. (line 154)
+* system: Data types. (line 353)
+* system <1>: Options. (line 173)
+* syzygy: syzygy. (line 6)
+* tab: Files. (line 61)
+* tab completion: Drawing in interactive mode.
+ (line 11)
+* tan: Mathematical functions.
+ (line 6)
+* Tan: Mathematical functions.
+ (line 20)
+* tanh: Mathematical functions.
+ (line 6)
+* target: three. (line 316)
+* tell: Files. (line 93)
+* tension: Bezier curves. (line 56)
+* tension <1>: three. (line 6)
+* tensionSpecifier: Paths and guides. (line 402)
+* tensor product shading: fill. (line 77)
+* tensorshade: fill. (line 77)
+* tessellation: three. (line 114)
+* tex: Frames and pictures.
+ (line 302)
+* tex <1>: Options. (line 149)
+* TeX fonts: Pens. (line 215)
+* TeX string: Data types. (line 207)
+* texcommand: Configuring. (line 64)
+* TeXHead: draw. (line 26)
+* TeXHead3: three. (line 547)
+* texpath: Configuring. (line 64)
+* texpath <1>: label. (line 113)
+* texpreamble: Frames and pictures.
+ (line 311)
+* texreset: Frames and pictures.
+ (line 315)
+* textbook graph: graph. (line 360)
+* tgz: UNIX binary distributions.
+ (line 6)
+* thick: three. (line 125)
+* thin: three. (line 125)
+* this: Structures. (line 6)
+* three: three. (line 6)
+* ThreeViews: three. (line 382)
+* ThreeViewsFR: three. (line 382)
+* ThreeViewsUS: three. (line 382)
+* tick: graph. (line 330)
+* ticks: graph. (line 160)
+* Ticks: graph. (line 160)
+* Ticks <1>: graph. (line 233)
+* tildeframe: markers. (line 24)
+* tile: Pens. (line 269)
+* tilings: Pens. (line 255)
+* time: Data types. (line 320)
+* time <1>: Data types. (line 345)
+* time <2>: math. (line 30)
+* time <3>: math. (line 34)
+* times: Paths and guides. (line 220)
+* times <1>: Paths and guides. (line 224)
+* Top: graph. (line 135)
+* TopView: three. (line 367)
+* trace: Debugger. (line 50)
+* trailingzero: graph. (line 175)
+* transform: Transforms. (line 6)
+* transform <1>: three. (line 456)
+* transform3: three. (line 419)
+* transparency: Pens. (line 237)
+* transpose: Arrays. (line 203)
+* transpose <1>: Arrays. (line 206)
+* tree: tree. (line 6)
+* trembling: trembling. (line 6)
+* triangle: geometry. (line 6)
+* triangles: three. (line 114)
+* triangulate: contour. (line 149)
+* tridiagonal: Arrays. (line 261)
+* trigonometric integrals: Mathematical functions.
+ (line 48)
+* triple: Data types. (line 137)
+* TrueMargin: draw. (line 42)
+* TrueMargin3: three. (line 563)
+* tube: three. (line 125)
+* tube <1>: tube. (line 6)
+* tutorial: Tutorial. (line 6)
+* type1cm: Pens. (line 192)
+* typedef: Data types. (line 384)
+* typedef <1>: Functions. (line 46)
+* U3D: embed. (line 22)
+* undefined: Paths and guides. (line 283)
+* UnFill: draw. (line 26)
+* unfill: fill. (line 109)
+* UnFill <1>: Frames and pictures.
+ (line 165)
+* UnFill <2>: Frames and pictures.
+ (line 168)
+* unicode: unicode. (line 6)
+* uniform: Arrays. (line 145)
+* uninstall: Uninstall. (line 6)
+* unique: math. (line 63)
+* unit: Data types. (line 83)
+* unit <1>: Data types. (line 173)
+* unitbox: Paths. (line 44)
+* unitbox <1>: three. (line 288)
+* unitcircle: Paths. (line 17)
+* unitcircle <1>: Paths. (line 17)
+* unitcircle <2>: three. (line 256)
+* unitrand: Mathematical functions.
+ (line 39)
+* unitsize: Figure size. (line 39)
+* unitsize <1>: Frames and pictures.
+ (line 69)
+* UNIX binary distributions: UNIX binary distributions.
+ (line 6)
+* unpacking: Rest arguments. (line 39)
+* unravel: Import. (line 29)
+* up: three. (line 316)
+* update: Files. (line 36)
+* UpsideDown: Frames and pictures.
+ (line 104)
+* UpsideDown <1>: Frames and pictures.
+ (line 110)
+* usepackage: Frames and pictures.
+ (line 318)
+* user coordinates: Figure size. (line 39)
+* user-defined operators: User-defined operators.
+ (line 6)
+* usleep: Data types. (line 378)
+* value: math. (line 38)
+* value <1>: math. (line 41)
+* var: Variable initializers.
+ (line 55)
+* variable initializers: Variable initializers.
+ (line 6)
+* vectorfield: graph. (line 1005)
+* vectorfield <1>: graph. (line 1044)
+* vectorfield3: graph3. (line 157)
+* vectorization: Arrays. (line 318)
+* verbatim: Frames and pictures.
+ (line 294)
+* vertex-dependent colors: three. (line 79)
+* Vertical: flowchart. (line 77)
+* viewportheight: LaTeX usage. (line 50)
+* viewportmargin: three. (line 244)
+* viewportsize: three. (line 244)
+* viewportwidth: LaTeX usage. (line 50)
+* views: three. (line 213)
+* vim: Editing modes. (line 32)
+* virtual functions: Structures. (line 181)
+* void: Data types. (line 10)
+* W: Labels. (line 18)
+* whatever: Paths and guides. (line 246)
+* Wheel: palette. (line 22)
+* wheel mouse: GUI. (line 6)
+* while: Programming. (line 48)
+* white-space string delimiter mode: Arrays. (line 349)
+* width: LaTeX usage. (line 50)
+* windingnumber: Paths and guides. (line 283)
+* word: Arrays. (line 349)
+* write: Files. (line 53)
+* write <1>: Arrays. (line 388)
+* X: three. (line 256)
+* xasy: GUI. (line 6)
+* xaxis3: graph3. (line 7)
+* xdr: Files. (line 76)
+* xelatex: Options. (line 149)
+* XEquals: graph. (line 265)
+* xequals: graph. (line 278)
+* xlimits: graph. (line 640)
+* XOR: Arithmetic & logical.
+ (line 68)
+* xpart: Data types. (line 94)
+* xpart <1>: Data types. (line 184)
+* xscale: Transforms. (line 30)
+* xscale3: three. (line 426)
+* xtick: graph. (line 330)
+* XY: three. (line 441)
+* XY <1>: three. (line 456)
+* XYEquals: graph3. (line 21)
+* XYZero: graph3. (line 21)
+* XZEquals: graph3. (line 21)
+* XZero: graph. (line 260)
+* XZZero: graph3. (line 21)
+* Y: Mathematical functions.
+ (line 6)
+* Y <1>: Mathematical functions.
+ (line 48)
+* Y <2>: three. (line 256)
+* yaxis3: graph3. (line 7)
+* YEquals: graph. (line 128)
+* yequals: graph. (line 278)
+* ylimits: graph. (line 640)
+* ypart: Data types. (line 97)
+* ypart <1>: Data types. (line 187)
+* yscale: Transforms. (line 32)
+* yscale3: three. (line 428)
+* ytick: graph. (line 330)
+* YX: three. (line 456)
+* YZ: three. (line 456)
+* YZEquals: graph3. (line 21)
+* YZero: graph. (line 123)
+* YZZero: graph3. (line 21)
+* Z: three. (line 256)
+* zaxis3: graph3. (line 7)
+* zeroTransform: Transforms. (line 44)
+* zerowinding: Pens. (line 164)
+* zero_Ai: Mathematical functions.
+ (line 48)
+* zero_Ai_deriv: Mathematical functions.
+ (line 48)
+* zero_Bi: Mathematical functions.
+ (line 48)
+* zero_Bi_deriv: Mathematical functions.
+ (line 48)
+* zero_J: Mathematical functions.
+ (line 48)
+* zeta: Mathematical functions.
+ (line 48)
+* zpart: Data types. (line 190)
+* zscale3: three. (line 430)
+* ZX: three. (line 456)
+* ZX <1>: three. (line 456)
+* ZY: three. (line 456)
+
+
+
+Tag Table:
+Node: Top570
+Node: Description7279
+Node: Installation11100
+Node: UNIX binary distributions12144
+Node: MacOS X binary distributions13274
+Node: Microsoft Windows13828
+Node: Configuring15032
+Node: Search paths19178
+Node: Compiling from UNIX source20017
+Node: Editing modes23077
+Node: Git25498
+Node: Uninstall25898
+Node: Tutorial26244
+Node: Drawing in batch mode27132
+Node: Drawing in interactive mode28007
+Node: Figure size29039
+Node: Labels30631
+Node: Paths31458
+Ref: unitcircle32073
+Node: Drawing commands33973
+Node: draw35688
+Ref: arrows36870
+Node: fill42383
+Ref: gradient shading43429
+Node: clip47936
+Node: label48523
+Ref: Label49123
+Node: Bezier curves54968
+Node: Programming58865
+Ref: array iteration60618
+Node: Data types60785
+Ref: format71447
+Node: Paths and guides75893
+Ref: circle76147
+Ref: extension85854
+Node: Pens92663
+Ref: fillrule100352
+Ref: basealign101256
+Ref: transparency104090
+Ref: makepen107670
+Ref: overwrite108553
+Node: Transforms109767
+Node: Frames and pictures111599
+Ref: envelope112757
+Ref: size113850
+Ref: unitsize114837
+Ref: shipout115910
+Ref: filltype118261
+Ref: add121433
+Ref: add about122439
+Ref: tex125468
+Node: Files126364
+Ref: cd127351
+Ref: scroll132036
+Node: Variable initializers134954
+Node: Structures137671
+Node: Operators145173
+Node: Arithmetic & logical145487
+Node: Self & prefix operators147858
+Node: User-defined operators148652
+Node: Implicit scaling149565
+Node: Functions150128
+Ref: stack overflow153271
+Node: Default arguments153553
+Node: Named arguments154309
+Node: Rest arguments156879
+Node: Mathematical functions160001
+Node: Arrays164664
+Ref: sort171772
+Ref: tridiagonal174397
+Ref: solve175628
+Node: Slices179767
+Node: Casts183675
+Node: Import185942
+Node: Static191200
+Node: LaTeX usage194093
+Node: Base modules200608
+Node: plain203165
+Node: simplex203839
+Node: math204113
+Node: interpolate206822
+Node: geometry207101
+Node: trembling207695
+Node: stats207964
+Node: patterns208224
+Node: markers208460
+Node: tree210320
+Node: binarytree210505
+Node: drawtree211171
+Node: syzygy211372
+Node: feynman211646
+Node: roundedpath211921
+Node: animation212204
+Ref: animate212625
+Node: embed213742
+Node: slide214697
+Node: MetaPost215038
+Node: unicode215757
+Node: latin1216631
+Node: babel217000
+Node: labelpath217230
+Node: labelpath3218051
+Node: annotate218362
+Node: CAD218832
+Node: graph219143
+Ref: ticks226304
+Ref: pathmarkers240096
+Ref: marker240567
+Ref: markuniform240921
+Ref: errorbars242729
+Ref: automatic scaling247203
+Node: palette258950
+Ref: images259068
+Ref: image263242
+Ref: logimage263762
+Ref: penimage264867
+Ref: penfunctionimage265129
+Node: three265900
+Ref: PostScript3D292907
+Node: obj294645
+Node: graph3294894
+Ref: GaussianSurface300174
+Node: grid3301323
+Node: solids302107
+Node: tube303099
+Node: flowchart305333
+Node: contour309941
+Node: contour3315256
+Node: smoothcontour3315569
+Node: slopefield317290
+Node: ode318779
+Node: Options319036
+Ref: configuration file325418
+Ref: settings325418
+Ref: texengines326661
+Ref: convert326661
+Node: Interactive mode329985
+Ref: history332135
+Node: GUI333441
+Node: GUI installation333992
+Node: GUI usage334721
+Node: PostScript to Asymptote335637
+Node: Help336395
+Node: Debugger338049
+Node: Credits339805
+Node: Index340822
+
+End Tag Table
diff --git a/graphics/asymptote/doc/quartercircle.asy b/graphics/asymptote/doc/quartercircle.asy
new file mode 100644
index 0000000000..6565daa046
--- /dev/null
+++ b/graphics/asymptote/doc/quartercircle.asy
@@ -0,0 +1,2 @@
+size(100,0);
+draw((1,0){up}..{left}(0,1),Arrow);
diff --git a/graphics/asymptote/doc/reloadpdf.tex b/graphics/asymptote/doc/reloadpdf.tex
new file mode 100644
index 0000000000..f203af1699
--- /dev/null
+++ b/graphics/asymptote/doc/reloadpdf.tex
@@ -0,0 +1,11 @@
+% Tex file for generating the reloadpdf.pdf utility to force Adobe Reader
+% to reload all currently loaded documents. Usage:
+%
+% pdflatex reloadpdf
+% acroread reloadpdf.pdf
+%
+\documentclass{article}
+\begin{document}
+\ \pdfannot width 0pt height 0pt { /AA << /PO << /S /JavaScript /JS
+ (try{reload();} catch(e) {} closeDoc(this);) >> >> }
+\end{document}
diff --git a/graphics/asymptote/doc/saddle.asy b/graphics/asymptote/doc/saddle.asy
new file mode 100644
index 0000000000..0180bf125a
--- /dev/null
+++ b/graphics/asymptote/doc/saddle.asy
@@ -0,0 +1,7 @@
+import three;
+
+size(100,0);
+path3 g=(1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle;
+draw(g);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
diff --git a/graphics/asymptote/doc/scaledgraph.asy b/graphics/asymptote/doc/scaledgraph.asy
new file mode 100644
index 0000000000..408c10cc58
--- /dev/null
+++ b/graphics/asymptote/doc/scaledgraph.asy
@@ -0,0 +1,15 @@
+import graph;
+
+axiscoverage=0.9;
+size(200,IgnoreAspect);
+
+real[] x={-1e-11,1e-11};
+real[] y={0,1e6};
+
+real xscale=round(log10(max(x)));
+real yscale=round(log10(max(y)))-1;
+
+draw(graph(x*10^(-xscale),y*10^(-yscale)),red);
+
+xaxis("$x/10^{"+(string) xscale+"}$",BottomTop,LeftTicks);
+yaxis("$y/10^{"+(string) yscale+"}$",LeftRight,RightTicks(trailingzero));
diff --git a/graphics/asymptote/doc/secondaryaxis.asy b/graphics/asymptote/doc/secondaryaxis.asy
new file mode 100644
index 0000000000..27b89b9c38
--- /dev/null
+++ b/graphics/asymptote/doc/secondaryaxis.asy
@@ -0,0 +1,32 @@
+import graph;
+
+size(9cm,6cm,IgnoreAspect);
+string data="secondaryaxis.csv";
+
+file in=input(data).line().csv();
+
+string[] titlelabel=in;
+string[] columnlabel=in;
+
+real[][] a=in;
+a=transpose(a);
+real[] t=a[0], susceptible=a[1], infectious=a[2], dead=a[3], larvae=a[4];
+real[] susceptibleM=a[5], exposed=a[6],infectiousM=a[7];
+
+scale(true);
+
+draw(graph(t,susceptible,t >= 10 & t <= 15));
+draw(graph(t,dead,t >= 10 & t <= 15),dashed);
+
+xaxis("Time ($\tau$)",BottomTop,LeftTicks);
+yaxis(Left,RightTicks);
+
+picture secondary=secondaryY(new void(picture pic) {
+ scale(pic,Linear(true),Log(true));
+ draw(pic,graph(pic,t,infectious,t >= 10 & t <= 15),red);
+ yaxis(pic,Right,red,LeftTicks(begin=false,end=false));
+ });
+
+add(secondary);
+label(shift(5mm*N)*"Proportion of crows",point(NW),E);
+
diff --git a/graphics/asymptote/doc/secondaryaxis.csv b/graphics/asymptote/doc/secondaryaxis.csv
new file mode 100644
index 0000000000..082d45a0e7
--- /dev/null
+++ b/graphics/asymptote/doc/secondaryaxis.csv
@@ -0,0 +1,1003 @@
+,"Proportion of crows",,,"Mosquitoes per crow",,,
+Time,Susceptible,Infectious,Dead,Larvae,Susceptible,Exposed,Infectious
+0,1,0,0,,30,0.000,0.001
+0.1,1.000,0.000,0.000,12.794,30.000,0.000,0.001
+0.2,1.000,0.000,0.000,12.794,30.000,0.000,0.001
+0.3,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.4,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.5,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.6,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.7,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.8,0.999,0.000,0.000,12.795,30.000,0.000,0.001
+0.9,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.1,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.2,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.3,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.4,0.999,0.000,0.001,12.795,29.999,0.001,0.001
+1.5,0.999,0.001,0.001,12.795,29.999,0.001,0.001
+1.6,0.999,0.001,0.001,12.795,29.999,0.001,0.001
+1.7,0.999,0.001,0.001,12.795,29.998,0.001,0.001
+1.8,0.999,0.001,0.001,12.795,29.998,0.001,0.001
+1.9,0.998,0.001,0.001,12.795,29.998,0.001,0.002
+2,0.998,0.001,0.001,12.795,29.998,0.001,0.002
+2.1,0.998,0.001,0.001,12.795,29.998,0.002,0.002
+2.2,0.998,0.001,0.001,12.795,29.998,0.002,0.002
+2.3,0.998,0.001,0.001,12.795,29.997,0.002,0.002
+2.4,0.998,0.001,0.001,12.795,29.997,0.002,0.002
+2.5,0.998,0.001,0.002,12.795,29.997,0.002,0.002
+2.6,0.997,0.001,0.002,12.795,29.997,0.002,0.002
+2.7,0.997,0.001,0.002,12.795,29.996,0.002,0.003
+2.8,0.997,0.001,0.002,12.795,29.996,0.002,0.003
+2.9,0.997,0.001,0.002,12.795,29.996,0.002,0.003
+3,0.997,0.001,0.002,12.795,29.995,0.003,0.003
+3.1,0.996,0.001,0.002,12.795,29.995,0.003,0.003
+3.2,0.996,0.001,0.003,12.795,29.995,0.003,0.003
+3.3,0.996,0.001,0.003,12.795,29.994,0.003,0.004
+3.4,0.996,0.001,0.003,12.795,29.994,0.003,0.004
+3.5,0.995,0.002,0.003,12.795,29.994,0.003,0.004
+3.6,0.995,0.002,0.003,12.795,29.993,0.004,0.004
+3.7,0.995,0.002,0.004,12.795,29.993,0.004,0.004
+3.8,0.994,0.002,0.004,12.795,29.992,0.004,0.005
+3.9,0.994,0.002,0.004,12.795,29.992,0.004,0.005
+4,0.994,0.002,0.004,12.795,29.991,0.005,0.005
+4.1,0.993,0.002,0.005,12.795,29.991,0.005,0.006
+4.2,0.993,0.002,0.005,12.795,29.990,0.005,0.006
+4.3,0.992,0.002,0.005,12.795,29.989,0.005,0.006
+4.4,0.992,0.003,0.006,12.795,29.989,0.006,0.007
+4.5,0.991,0.003,0.006,12.795,29.988,0.006,0.007
+4.6,0.991,0.003,0.006,12.795,29.987,0.006,0.008
+4.7,0.990,0.003,0.007,12.795,29.986,0.007,0.008
+4.8,0.990,0.003,0.007,12.795,29.985,0.007,0.008
+4.9,0.989,0.003,0.008,12.795,29.984,0.008,0.009
+5,0.988,0.004,0.008,12.795,29.984,0.008,0.009
+5.1,0.988,0.004,0.009,12.795,29.982,0.008,0.010
+5.2,0.987,0.004,0.009,12.795,29.981,0.009,0.011
+5.3,0.986,0.004,0.010,12.795,29.980,0.010,0.011
+5.4,0.985,0.005,0.010,12.795,29.979,0.010,0.012
+5.5,0.984,0.005,0.011,12.795,29.978,0.011,0.013
+5.6,0.983,0.005,0.012,12.795,29.976,0.011,0.013
+5.7,0.982,0.005,0.012,12.795,29.975,0.012,0.014
+5.8,0.981,0.006,0.013,12.795,29.973,0.013,0.015
+5.9,0.980,0.006,0.014,12.795,29.972,0.013,0.016
+6,0.979,0.006,0.015,12.795,29.970,0.014,0.017
+6.1,0.978,0.007,0.016,12.795,29.968,0.015,0.018
+6.2,0.976,0.007,0.016,12.795,29.966,0.016,0.019
+6.3,0.975,0.008,0.017,12.795,29.964,0.017,0.020
+6.4,0.973,0.008,0.019,12.795,29.962,0.018,0.021
+6.5,0.972,0.008,0.020,12.795,29.960,0.019,0.022
+6.6,0.970,0.009,0.021,12.795,29.957,0.020,0.024
+6.7,0.968,0.009,0.022,12.795,29.955,0.021,0.025
+6.8,0.967,0.010,0.023,12.795,29.952,0.022,0.026
+6.9,0.965,0.011,0.025,12.795,29.949,0.024,0.028
+7,0.963,0.011,0.026,12.795,29.946,0.025,0.030
+7.1,0.960,0.012,0.028,12.795,29.943,0.026,0.031
+7.2,0.958,0.013,0.029,12.795,29.940,0.028,0.033
+7.3,0.956,0.013,0.031,12.795,29.936,0.029,0.035
+7.4,0.953,0.014,0.033,12.795,29.933,0.031,0.037
+7.5,0.950,0.015,0.035,12.795,29.929,0.033,0.039
+7.6,0.947,0.016,0.037,12.795,29.925,0.035,0.042
+7.7,0.944,0.016,0.039,12.795,29.920,0.037,0.044
+7.8,0.941,0.017,0.041,12.795,29.916,0.039,0.046
+7.9,0.938,0.018,0.044,12.795,29.911,0.041,0.049
+8,0.934,0.019,0.046,12.795,29.906,0.043,0.052
+8.1,0.931,0.020,0.049,12.795,29.900,0.046,0.055
+8.2,0.927,0.021,0.052,12.795,29.895,0.048,0.058
+8.3,0.923,0.023,0.055,12.795,29.889,0.051,0.061
+8.4,0.918,0.024,0.058,12.795,29.883,0.054,0.065
+8.5,0.914,0.025,0.061,12.795,29.876,0.056,0.069
+8.6,0.909,0.026,0.065,12.795,29.869,0.059,0.072
+8.7,0.904,0.028,0.068,12.795,29.862,0.063,0.076
+8.8,0.899,0.029,0.072,12.795,29.854,0.066,0.081
+8.9,0.893,0.031,0.076,12.795,29.846,0.070,0.085
+9,0.887,0.032,0.080,12.795,29.838,0.073,0.090
+9.1,0.881,0.034,0.085,12.795,29.829,0.077,0.095
+9.2,0.875,0.036,0.090,12.795,29.820,0.081,0.100
+9.3,0.868,0.037,0.095,12.795,29.810,0.085,0.106
+9.4,0.861,0.039,0.100,12.795,29.800,0.090,0.112
+9.5,0.854,0.041,0.105,12.795,29.789,0.094,0.118
+9.6,0.846,0.043,0.111,12.795,29.778,0.099,0.124
+9.7,0.838,0.045,0.117,12.795,29.766,0.104,0.131
+9.8,0.830,0.047,0.123,12.795,29.754,0.109,0.138
+9.9,0.821,0.049,0.130,12.795,29.742,0.114,0.145
+10,0.812,0.052,0.136,12.795,29.729,0.120,0.153
+10.1,0.802,0.054,0.144,12.795,29.715,0.126,0.161
+10.2,0.793,0.056,0.151,12.795,29.701,0.132,0.169
+10.3,0.782,0.059,0.159,12.795,29.686,0.138,0.178
+10.4,0.772,0.061,0.167,12.795,29.670,0.144,0.187
+10.5,0.761,0.064,0.175,12.795,29.654,0.150,0.196
+10.6,0.750,0.066,0.184,12.795,29.638,0.157,0.206
+10.7,0.738,0.069,0.193,12.795,29.621,0.164,0.216
+10.8,0.726,0.072,0.203,12.795,29.603,0.171,0.227
+10.9,0.713,0.074,0.212,12.795,29.585,0.178,0.238
+11,0.700,0.077,0.223,12.795,29.566,0.185,0.250
+11.1,0.687,0.080,0.233,12.795,29.547,0.193,0.261
+11.2,0.674,0.082,0.244,12.795,29.527,0.200,0.274
+11.3,0.660,0.085,0.255,12.795,29.507,0.208,0.286
+11.4,0.645,0.088,0.267,12.795,29.486,0.215,0.300
+11.5,0.631,0.090,0.279,12.795,29.465,0.223,0.313
+11.6,0.616,0.093,0.291,12.795,29.443,0.231,0.327
+11.7,0.601,0.095,0.304,12.795,29.421,0.238,0.341
+11.8,0.585,0.098,0.317,12.795,29.399,0.246,0.356
+11.9,0.570,0.100,0.330,12.795,29.376,0.254,0.371
+12,0.554,0.102,0.344,12.795,29.353,0.261,0.386
+12.1,0.538,0.104,0.358,12.795,29.330,0.269,0.402
+12.2,0.521,0.106,0.372,12.795,29.307,0.276,0.418
+12.3,0.505,0.108,0.387,12.795,29.283,0.283,0.434
+12.4,0.489,0.110,0.401,12.795,29.260,0.290,0.451
+12.5,0.472,0.112,0.416,12.795,29.236,0.297,0.468
+12.6,0.456,0.113,0.432,12.795,29.213,0.303,0.485
+12.7,0.439,0.114,0.447,12.795,29.190,0.309,0.502
+12.8,0.423,0.115,0.462,12.795,29.167,0.315,0.519
+12.9,0.406,0.116,0.478,12.795,29.144,0.320,0.536
+13,0.390,0.116,0.494,12.795,29.122,0.325,0.554
+13.1,0.374,0.117,0.509,12.795,29.100,0.329,0.571
+13.2,0.358,0.117,0.525,12.795,29.079,0.333,0.588
+13.3,0.343,0.117,0.541,12.795,29.059,0.337,0.606
+13.4,0.327,0.116,0.557,12.795,29.039,0.340,0.623
+13.5,0.312,0.116,0.572,12.795,29.020,0.342,0.639
+13.6,0.297,0.115,0.588,12.795,29.001,0.344,0.656
+13.7,0.283,0.114,0.603,12.795,28.984,0.345,0.672
+13.8,0.269,0.113,0.618,12.795,28.967,0.346,0.688
+13.9,0.255,0.111,0.634,12.795,28.952,0.346,0.704
+14,0.242,0.109,0.648,12.795,28.937,0.345,0.719
+14.1,0.229,0.108,0.663,12.795,28.924,0.344,0.733
+14.2,0.217,0.106,0.677,12.795,28.912,0.342,0.747
+14.3,0.205,0.103,0.692,12.795,28.900,0.340,0.761
+14.4,0.194,0.101,0.705,12.795,28.891,0.337,0.774
+14.5,0.183,0.099,0.719,12.795,28.882,0.333,0.786
+14.6,0.172,0.096,0.732,12.795,28.874,0.329,0.797
+14.7,0.162,0.093,0.745,12.795,28.868,0.325,0.808
+14.8,0.153,0.090,0.757,12.795,28.863,0.320,0.818
+14.9,0.143,0.087,0.769,12.795,28.860,0.314,0.827
+15,0.135,0.084,0.781,12.795,28.857,0.308,0.836
+15.1,0.127,0.081,0.792,12.795,28.856,0.302,0.843
+15.2,0.119,0.078,0.803,12.795,28.856,0.295,0.850
+15.3,0.112,0.075,0.813,12.795,28.857,0.288,0.856
+15.4,0.105,0.072,0.823,12.795,28.859,0.281,0.861
+15.5,0.098,0.069,0.833,12.795,28.863,0.273,0.865
+15.6,0.092,0.066,0.842,12.795,28.867,0.266,0.868
+15.7,0.086,0.063,0.850,12.795,28.873,0.258,0.870
+15.8,0.081,0.060,0.859,12.795,28.879,0.250,0.872
+15.9,0.076,0.058,0.867,12.795,28.887,0.242,0.873
+16,0.071,0.055,0.874,12.795,28.895,0.233,0.873
+16.1,0.066,0.052,0.882,12.795,28.904,0.225,0.872
+16.2,0.062,0.049,0.888,12.795,28.914,0.217,0.870
+16.3,0.058,0.047,0.895,12.795,28.925,0.209,0.867
+16.4,0.055,0.044,0.901,12.795,28.936,0.201,0.864
+16.5,0.051,0.042,0.907,12.795,28.948,0.192,0.860
+16.6,0.048,0.040,0.912,12.795,28.961,0.185,0.856
+16.7,0.045,0.037,0.918,12.795,28.974,0.177,0.850
+16.8,0.042,0.035,0.922,12.795,28.988,0.169,0.844
+16.9,0.040,0.033,0.927,12.795,29.002,0.161,0.838
+17,0.037,0.031,0.931,12.795,29.016,0.154,0.831
+17.1,0.035,0.029,0.936,12.795,29.031,0.147,0.823
+17.2,0.033,0.028,0.939,12.795,29.046,0.140,0.815
+17.3,0.031,0.026,0.943,12.795,29.061,0.133,0.807
+17.4,0.029,0.024,0.946,12.795,29.077,0.126,0.798
+17.5,0.028,0.023,0.950,12.795,29.093,0.120,0.788
+17.6,0.026,0.021,0.953,12.795,29.108,0.114,0.779
+17.7,0.025,0.020,0.955,12.795,29.124,0.108,0.769
+17.8,0.023,0.019,0.958,12.795,29.141,0.102,0.758
+17.9,0.022,0.018,0.960,12.795,29.157,0.097,0.748
+18,0.021,0.017,0.963,12.795,29.173,0.092,0.737
+18.1,0.020,0.015,0.965,12.795,29.189,0.087,0.726
+18.2,0.019,0.014,0.967,12.795,29.205,0.082,0.714
+18.3,0.018,0.014,0.969,12.795,29.221,0.077,0.703
+18.4,0.017,0.013,0.971,12.795,29.237,0.073,0.691
+18.5,0.016,0.012,0.972,12.795,29.253,0.069,0.680
+18.6,0.015,0.011,0.974,12.795,29.268,0.065,0.668
+18.7,0.014,0.010,0.975,12.795,29.284,0.061,0.656
+18.8,0.014,0.010,0.977,12.795,29.299,0.057,0.644
+18.9,0.013,0.009,0.978,12.795,29.315,0.054,0.632
+19,0.012,0.008,0.979,12.795,29.330,0.051,0.620
+19.1,0.012,0.008,0.980,12.795,29.345,0.048,0.609
+19.2,0.011,0.007,0.981,12.795,29.359,0.045,0.597
+19.3,0.011,0.007,0.982,12.795,29.374,0.042,0.585
+19.4,0.010,0.007,0.983,12.795,29.388,0.040,0.573
+19.5,0.010,0.006,0.984,12.795,29.402,0.037,0.562
+19.6,0.010,0.006,0.985,12.795,29.416,0.035,0.550
+19.7,0.009,0.005,0.985,12.795,29.430,0.033,0.538
+19.8,0.009,0.005,0.986,12.795,29.443,0.031,0.527
+19.9,0.009,0.005,0.987,12.795,29.456,0.029,0.516
+20,0.008,0.004,0.987,12.795,29.469,0.027,0.505
+20.1,0.008,0.004,0.988,12.795,29.482,0.026,0.494
+20.2,0.008,0.004,0.989,12.795,29.494,0.024,0.483
+20.3,0.007,0.004,0.989,12.795,29.506,0.023,0.472
+20.4,0.007,0.003,0.990,12.795,29.518,0.021,0.461
+20.5,0.007,0.003,0.990,12.795,29.530,0.020,0.451
+20.6,0.007,0.003,0.990,12.795,29.541,0.019,0.441
+20.7,0.006,0.003,0.991,12.795,29.553,0.018,0.431
+20.8,0.006,0.003,0.991,12.795,29.564,0.017,0.421
+20.9,0.006,0.002,0.991,12.795,29.575,0.016,0.411
+21,0.006,0.002,0.992,12.795,29.585,0.015,0.401
+21.1,0.006,0.002,0.992,12.795,29.595,0.014,0.392
+21.2,0.006,0.002,0.992,12.795,29.605,0.013,0.383
+21.3,0.005,0.002,0.993,12.795,29.615,0.012,0.374
+21.4,0.005,0.002,0.993,12.795,29.625,0.011,0.365
+21.5,0.005,0.002,0.993,12.795,29.634,0.011,0.356
+21.6,0.005,0.002,0.993,12.795,29.644,0.010,0.347
+21.7,0.005,0.002,0.994,12.795,29.653,0.009,0.339
+21.8,0.005,0.001,0.994,12.795,29.661,0.009,0.331
+21.9,0.005,0.001,0.994,12.795,29.670,0.008,0.323
+22,0.004,0.001,0.994,12.795,29.678,0.008,0.315
+22.1,0.004,0.001,0.994,12.795,29.687,0.007,0.307
+22.2,0.004,0.001,0.995,12.795,29.695,0.007,0.299
+22.3,0.004,0.001,0.995,12.795,29.702,0.007,0.292
+22.4,0.004,0.001,0.995,12.795,29.710,0.006,0.285
+22.5,0.004,0.001,0.995,12.795,29.718,0.006,0.278
+22.6,0.004,0.001,0.995,12.795,29.725,0.006,0.271
+22.7,0.004,0.001,0.995,12.795,29.732,0.005,0.264
+22.8,0.004,0.001,0.995,12.795,29.739,0.005,0.257
+22.9,0.004,0.001,0.995,12.795,29.746,0.005,0.251
+23,0.004,0.001,0.996,12.795,29.752,0.004,0.244
+23.1,0.004,0.001,0.996,12.795,29.758,0.004,0.238
+23.2,0.004,0.001,0.996,12.795,29.765,0.004,0.232
+23.3,0.003,0.001,0.996,12.795,29.771,0.004,0.226
+23.4,0.003,0.001,0.996,12.795,29.777,0.004,0.221
+23.5,0.003,0.001,0.996,12.795,29.783,0.003,0.215
+23.6,0.003,0.001,0.996,12.795,29.788,0.003,0.210
+23.7,0.003,0.001,0.996,12.795,29.794,0.003,0.204
+23.8,0.003,0.001,0.996,12.795,29.799,0.003,0.199
+23.9,0.003,0.001,0.996,12.795,29.804,0.003,0.194
+24,0.003,0.000,0.996,12.795,29.809,0.003,0.189
+24.1,0.003,0.000,0.996,12.795,29.814,0.002,0.184
+24.2,0.003,0.000,0.997,12.795,29.819,0.002,0.179
+24.3,0.003,0.000,0.997,12.795,29.824,0.002,0.175
+24.4,0.003,0.000,0.997,12.795,29.829,0.002,0.170
+24.5,0.003,0.000,0.997,12.795,29.833,0.002,0.166
+24.6,0.003,0.000,0.997,12.795,29.838,0.002,0.162
+24.7,0.003,0.000,0.997,12.795,29.842,0.002,0.157
+24.8,0.003,0.000,0.997,12.795,29.846,0.002,0.153
+24.9,0.003,0.000,0.997,12.795,29.850,0.002,0.149
+25,0.003,0.000,0.997,12.795,29.854,0.002,0.145
+25.1,0.003,0.000,0.997,12.795,29.858,0.002,0.142
+25.2,0.003,0.000,0.997,12.795,29.862,0.001,0.138
+25.3,0.003,0.000,0.997,12.795,29.865,0.001,0.134
+25.4,0.003,0.000,0.997,12.795,29.869,0.001,0.131
+25.5,0.003,0.000,0.997,12.795,29.872,0.001,0.128
+25.6,0.003,0.000,0.997,12.795,29.876,0.001,0.124
+25.7,0.003,0.000,0.997,12.795,29.879,0.001,0.121
+25.8,0.003,0.000,0.997,12.795,29.882,0.001,0.118
+25.9,0.003,0.000,0.997,12.795,29.885,0.001,0.115
+26,0.002,0.000,0.997,12.795,29.888,0.001,0.112
+26.1,0.002,0.000,0.997,12.795,29.891,0.001,0.109
+26.2,0.002,0.000,0.997,12.795,29.894,0.001,0.106
+26.3,0.002,0.000,0.997,12.795,29.897,0.001,0.103
+26.4,0.002,0.000,0.997,12.795,29.900,0.001,0.101
+26.5,0.002,0.000,0.997,12.795,29.902,0.001,0.098
+26.6,0.002,0.000,0.997,12.795,29.905,0.001,0.095
+26.7,0.002,0.000,0.997,12.795,29.907,0.001,0.093
+26.8,0.002,0.000,0.997,12.795,29.910,0.001,0.090
+26.9,0.002,0.000,0.998,12.795,29.912,0.001,0.088
+27,0.002,0.000,0.998,12.795,29.915,0.001,0.086
+27.1,0.002,0.000,0.998,12.795,29.917,0.001,0.083
+27.2,0.002,0.000,0.998,12.795,29.919,0.001,0.081
+27.3,0.002,0.000,0.998,12.795,29.921,0.001,0.079
+27.4,0.002,0.000,0.998,12.795,29.923,0.001,0.077
+27.5,0.002,0.000,0.998,12.795,29.925,0.001,0.075
+27.6,0.002,0.000,0.998,12.795,29.927,0.001,0.073
+27.7,0.002,0.000,0.998,12.795,29.929,0.001,0.071
+27.8,0.002,0.000,0.998,12.795,29.931,0.001,0.069
+27.9,0.002,0.000,0.998,12.795,29.933,0.000,0.067
+28,0.002,0.000,0.998,12.795,29.935,0.000,0.066
+28.1,0.002,0.000,0.998,12.795,29.937,0.000,0.064
+28.2,0.002,0.000,0.998,12.795,29.938,0.000,0.062
+28.3,0.002,0.000,0.998,12.795,29.940,0.000,0.061
+28.4,0.002,0.000,0.998,12.795,29.942,0.000,0.059
+28.5,0.002,0.000,0.998,12.795,29.943,0.000,0.057
+28.6,0.002,0.000,0.998,12.795,29.945,0.000,0.056
+28.7,0.002,0.000,0.998,12.795,29.946,0.000,0.054
+28.8,0.002,0.000,0.998,12.795,29.948,0.000,0.053
+28.9,0.002,0.000,0.998,12.795,29.949,0.000,0.052
+29,0.002,0.000,0.998,12.795,29.950,0.000,0.050
+29.1,0.002,0.000,0.998,12.795,29.952,0.000,0.049
+29.2,0.002,0.000,0.998,12.795,29.953,0.000,0.048
+29.3,0.002,0.000,0.998,12.795,29.954,0.000,0.046
+29.4,0.002,0.000,0.998,12.795,29.955,0.000,0.045
+29.5,0.002,0.000,0.998,12.795,29.957,0.000,0.044
+29.6,0.002,0.000,0.998,12.795,29.958,0.000,0.043
+29.7,0.002,0.000,0.998,12.795,29.959,0.000,0.042
+29.8,0.002,0.000,0.998,12.795,29.960,0.000,0.041
+29.9,0.002,0.000,0.998,12.795,29.961,0.000,0.040
+30,0.002,0.000,0.998,12.795,29.962,0.000,0.039
+30.1,0.002,0.000,0.998,12.795,29.963,0.000,0.037
+30.2,0.002,0.000,0.998,12.795,29.964,0.000,0.037
+30.3,0.002,0.000,0.998,12.795,29.965,0.000,0.036
+30.4,0.002,0.000,0.998,12.795,29.966,0.000,0.035
+30.5,0.002,0.000,0.998,12.795,29.967,0.000,0.034
+30.6,0.002,0.000,0.998,12.795,29.968,0.000,0.033
+30.7,0.002,0.000,0.998,12.795,29.969,0.000,0.032
+30.8,0.002,0.000,0.998,12.795,29.970,0.000,0.031
+30.9,0.002,0.000,0.998,12.795,29.971,0.000,0.030
+31,0.002,0.000,0.998,12.795,29.971,0.000,0.029
+31.1,0.002,0.000,0.998,12.795,29.972,0.000,0.029
+31.2,0.002,0.000,0.998,12.795,29.973,0.000,0.028
+31.3,0.002,0.000,0.998,12.795,29.974,0.000,0.027
+31.4,0.002,0.000,0.998,12.795,29.974,0.000,0.026
+31.5,0.002,0.000,0.998,12.795,29.975,0.000,0.026
+31.6,0.002,0.000,0.998,12.795,29.976,0.000,0.025
+31.7,0.002,0.000,0.998,12.795,29.976,0.000,0.024
+31.8,0.002,0.000,0.998,12.795,29.977,0.000,0.024
+31.9,0.002,0.000,0.998,12.795,29.978,0.000,0.023
+32,0.002,0.000,0.998,12.795,29.978,0.000,0.023
+32.1,0.002,0.000,0.998,12.795,29.979,0.000,0.022
+32.2,0.002,0.000,0.998,12.795,29.979,0.000,0.021
+32.3,0.002,0.000,0.998,12.795,29.980,0.000,0.021
+32.4,0.002,0.000,0.998,12.795,29.981,0.000,0.020
+32.5,0.002,0.000,0.998,12.795,29.981,0.000,0.020
+32.6,0.002,0.000,0.998,12.795,29.982,0.000,0.019
+32.7,0.002,0.000,0.998,12.795,29.982,0.000,0.019
+32.8,0.002,0.000,0.998,12.795,29.983,0.000,0.018
+32.9,0.002,0.000,0.998,12.795,29.983,0.000,0.018
+33,0.002,0.000,0.998,12.795,29.984,0.000,0.017
+33.1,0.002,0.000,0.998,12.795,29.984,0.000,0.017
+33.2,0.002,0.000,0.998,12.795,29.985,0.000,0.016
+33.3,0.002,0.000,0.998,12.795,29.985,0.000,0.016
+33.4,0.002,0.000,0.998,12.795,29.985,0.000,0.015
+33.5,0.002,0.000,0.998,12.795,29.986,0.000,0.015
+33.6,0.002,0.000,0.998,12.795,29.986,0.000,0.015
+33.7,0.002,0.000,0.998,12.795,29.987,0.000,0.014
+33.8,0.002,0.000,0.998,12.795,29.987,0.000,0.014
+33.9,0.002,0.000,0.998,12.795,29.987,0.000,0.014
+34,0.002,0.000,0.998,12.795,29.988,0.000,0.013
+34.1,0.002,0.000,0.998,12.795,29.988,0.000,0.013
+34.2,0.002,0.000,0.998,12.795,29.988,0.000,0.012
+34.3,0.002,0.000,0.998,12.795,29.989,0.000,0.012
+34.4,0.002,0.000,0.998,12.795,29.989,0.000,0.012
+34.5,0.002,0.000,0.998,12.795,29.989,0.000,0.012
+34.6,0.002,0.000,0.998,12.795,29.990,0.000,0.011
+34.7,0.002,0.000,0.998,12.795,29.990,0.000,0.011
+34.8,0.002,0.000,0.998,12.795,29.990,0.000,0.011
+34.9,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35.1,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35.2,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35.3,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.4,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.5,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.6,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.7,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+35.8,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+35.9,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+36,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+36.1,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+36.2,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.3,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.4,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.5,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.6,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.7,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+36.8,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+36.9,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37.1,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37.2,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37.3,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.4,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.5,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.6,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.7,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.8,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.9,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+38,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+38.1,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.2,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.3,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.4,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.5,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.6,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.7,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.8,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.9,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+39,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.1,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.2,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.3,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.4,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.5,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.6,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.7,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.8,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.9,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+40,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+40.1,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+40.2,0.002,0.000,0.998,12.795,29.998,0.000,0.002
+40.3,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.4,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.5,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.6,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.7,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.8,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.9,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.1,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.2,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.3,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.4,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.5,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.6,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.7,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.8,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.9,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+42,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+42.1,0.002,0.000,0.998,12.795,29.999,0.000,0.001
+42.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+46,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+46.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+46.2,0.002,0.000,0.998,12.795,30.000,0.000,0.000
+46.3,0.002,0.000,0.998,12.795,30.000,0.000,0.000
+46.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+100,0.002,0.000,0.998,12.795,30.001,0.000,0.000
diff --git a/graphics/asymptote/doc/shadedtiling.asy b/graphics/asymptote/doc/shadedtiling.asy
new file mode 100644
index 0000000000..4d3b8ae894
--- /dev/null
+++ b/graphics/asymptote/doc/shadedtiling.asy
@@ -0,0 +1,12 @@
+size(0,100);
+import patterns;
+
+real d=4mm;
+picture tiling;
+path square=scale(d)*unitsquare;
+axialshade(tiling,square,white,(0,0),black,(d,d));
+fill(tiling,shift(d,d)*square,blue);
+add("shadedtiling",tiling);
+
+filldraw(unitcircle,pattern("shadedtiling"));
+
diff --git a/graphics/asymptote/doc/slopefield1.asy b/graphics/asymptote/doc/slopefield1.asy
new file mode 100644
index 0000000000..fd60de4f63
--- /dev/null
+++ b/graphics/asymptote/doc/slopefield1.asy
@@ -0,0 +1,9 @@
+import slopefield;
+
+size(200);
+
+real func(real x) {return 2x;}
+add(slopefield(func,(-3,-3),(3,3),20,Arrow));
+draw(curve((0,0),func,(-3,-3),(3,3)),red);
+
+
diff --git a/graphics/asymptote/doc/square.asy b/graphics/asymptote/doc/square.asy
new file mode 100644
index 0000000000..6fd9d2314d
--- /dev/null
+++ b/graphics/asymptote/doc/square.asy
@@ -0,0 +1,2 @@
+size(3cm);
+draw((0,0)--(1,0)--(1,1)--(0,1)--cycle);
diff --git a/graphics/asymptote/doc/subpictures.asy b/graphics/asymptote/doc/subpictures.asy
new file mode 100644
index 0000000000..1ace23f567
--- /dev/null
+++ b/graphics/asymptote/doc/subpictures.asy
@@ -0,0 +1,20 @@
+picture pic1;
+real size=50;
+size(pic1,size);
+fill(pic1,(0,0)--(50,100)--(100,0)--cycle,red);
+
+picture pic2;
+size(pic2,size);
+fill(pic2,unitcircle,green);
+
+picture pic3;
+size(pic3,size);
+fill(pic3,unitsquare,blue);
+
+picture pic;
+add(pic,pic1.fit(),(0,0),N);
+add(pic,pic2.fit(),(0,0),10S);
+
+add(pic.fit(),(0,0),N);
+add(pic3.fit(),(0,0),10S);
+
diff --git a/graphics/asymptote/doc/superpath.asy b/graphics/asymptote/doc/superpath.asy
new file mode 100644
index 0000000000..ec2787a9ce
--- /dev/null
+++ b/graphics/asymptote/doc/superpath.asy
@@ -0,0 +1,5 @@
+size(0,100);
+path unitcircle=E..N..W..S..cycle;
+path g=scale(2)*unitcircle;
+filldraw(unitcircle^^g,evenodd+yellow,black);
+
diff --git a/graphics/asymptote/doc/tile.asy b/graphics/asymptote/doc/tile.asy
new file mode 100644
index 0000000000..fe9cbc523c
--- /dev/null
+++ b/graphics/asymptote/doc/tile.asy
@@ -0,0 +1,13 @@
+size(0,90);
+import patterns;
+
+add("tile",tile());
+add("filledtilewithmargin",tile(6mm,4mm,red,Fill),(1mm,1mm),(1mm,1mm));
+add("checker",checker());
+add("brick",brick());
+
+real s=2.5;
+filldraw(unitcircle,pattern("tile"));
+filldraw(shift(s,0)*unitcircle,pattern("filledtilewithmargin"));
+filldraw(shift(2s,0)*unitcircle,pattern("checker"));
+filldraw(shift(3s,0)*unitcircle,pattern("brick"));
diff --git a/graphics/asymptote/doc/triangulate.asy b/graphics/asymptote/doc/triangulate.asy
new file mode 100644
index 0000000000..56ad347b53
--- /dev/null
+++ b/graphics/asymptote/doc/triangulate.asy
@@ -0,0 +1,19 @@
+size(200);
+int np=100;
+pair[] points;
+
+real r() {return 1.2*(rand()/randMax*2-1);}
+
+for(int i=0; i < np; ++i)
+ points.push((r(),r()));
+
+int[][] trn=triangulate(points);
+
+for(int i=0; i < trn.length; ++i) {
+ draw(points[trn[i][0]]--points[trn[i][1]]);
+ draw(points[trn[i][1]]--points[trn[i][2]]);
+ draw(points[trn[i][2]]--points[trn[i][0]]);
+}
+
+for(int i=0; i < np; ++i)
+ dot(points[i],red);
diff --git a/graphics/asymptote/doc/unitcircle3.asy b/graphics/asymptote/doc/unitcircle3.asy
new file mode 100644
index 0000000000..be282011dc
--- /dev/null
+++ b/graphics/asymptote/doc/unitcircle3.asy
@@ -0,0 +1,9 @@
+import three;
+
+size(100);
+
+path3 g=(1,0,0)..(0,1,0)..(-1,0,0)..(0,-1,0)..cycle;
+draw(g);
+draw(O--Z,red+dashed,Arrow3);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
diff --git a/graphics/asymptote/doc/vectorfield.asy b/graphics/asymptote/doc/vectorfield.asy
new file mode 100644
index 0000000000..12de66e49c
--- /dev/null
+++ b/graphics/asymptote/doc/vectorfield.asy
@@ -0,0 +1,9 @@
+import graph;
+size(100);
+
+pair a=(0,0);
+pair b=(2pi,2pi);
+
+path vector(pair z) {return (0,0)--(sin(z.x),cos(z.y));}
+
+add(vectorfield(vector,a,b));
diff --git a/graphics/asymptote/doc/westnile.asy b/graphics/asymptote/doc/westnile.asy
new file mode 100644
index 0000000000..222bb38e05
--- /dev/null
+++ b/graphics/asymptote/doc/westnile.asy
@@ -0,0 +1,64 @@
+import graph;
+
+size(9cm,8cm,IgnoreAspect);
+string data="westnile.csv";
+
+file in=input(data).line().csv();
+
+string[] columnlabel=in;
+
+real[][] A=in;
+A=transpose(A);
+real[] number=A[0], survival=A[1];
+
+path g=graph(number,survival);
+draw(g);
+
+scale(true);
+
+xaxis("Initial no.\ of mosquitoes per bird ($S_{M_0}/N_{B_0}$)",
+ Bottom,LeftTicks);
+xaxis(Top);
+yaxis("Susceptible bird survival",Left,RightTicks(trailingzero));
+yaxis(Right);
+
+real a=number[0];
+real b=number[number.length-1];
+
+real S1=0.475;
+path h1=(a,S1)--(b,S1);
+real M1=interp(a,b,intersect(h1,g)[0]);
+
+real S2=0.9;
+path h2=(a,S2)--(b,S2);
+real M2=interp(a,b,intersect(h2,g)[0]);
+
+labelx("$M_1$",M1);
+labelx("$M_2$",M2);
+
+draw((a,S2)--(M2,S2)--(M2,0),Dotted);
+draw((a,S1)--(M1,S1)--(M1,0),dashed);
+
+pen p=fontsize(10pt);
+
+real y3=0.043;
+path reduction=(M1,y3)--(M2,y3);
+draw(reduction,Arrow,TrueMargin(0,0.5*(linewidth(Dotted)+linewidth())));
+
+arrow(shift(-20,5)*Label(minipage("\flushleft{\begin{itemize}\item[1.]
+Estimate proportion of birds surviving at end of season\end{itemize}}",100),
+ align=NNE),
+ (M1,S1),NNE,1cm,p,Arrow(NoFill));
+
+arrow(shift(-24,5)*Label(minipage("\flushleft{\begin{itemize}\item[2.]
+Read off initial mosquito abundance\end{itemize}}",80),align=NNE),
+ (M1,0),NE,2cm,p,Arrow(NoFill));
+
+arrow(shift(20,0)*Label(minipage("\flushleft{\begin{itemize}\item[3.]
+Determine desired bird survival for next season\end{itemize}}",90),align=SW),
+ (M2,S2),SW,arrowlength,p,Arrow(NoFill));
+
+arrow(shift(8,-15)*Label(minipage("\flushleft{\begin{itemize}\item[4.]
+Calculate required proportional reduction in mosquitoes\end{itemize}}",90),
+ align=NW),
+ point(reduction,0.5),NW,1.5cm,p,Arrow(NoFill));
diff --git a/graphics/asymptote/doc/westnile.csv b/graphics/asymptote/doc/westnile.csv
new file mode 100644
index 0000000000..cfc8493ed2
--- /dev/null
+++ b/graphics/asymptote/doc/westnile.csv
@@ -0,0 +1,402 @@
+sm0,0.001(T14)
+0.0,0.9973
+0.1,0.9973
+0.2,0.9972
+0.3,0.9972
+0.4,0.9971
+0.5,0.9971
+0.6,0.9970
+0.7,0.9970
+0.8,0.9969
+0.9,0.9968
+1.0,0.9968
+1.1,0.9967
+1.2,0.9966
+1.3,0.9966
+1.4,0.9965
+1.5,0.9964
+1.6,0.9963
+1.7,0.9963
+1.8,0.9962
+1.9,0.9961
+2.0,0.9960
+2.1,0.9959
+2.2,0.9958
+2.3,0.9957
+2.4,0.9957
+2.5,0.9956
+2.6,0.9955
+2.7,0.9954
+2.8,0.9952
+2.9,0.9951
+3.0,0.9950
+3.1,0.9949
+3.2,0.9948
+3.3,0.9947
+3.4,0.9945
+3.5,0.9944
+3.6,0.9943
+3.7,0.9941
+3.8,0.9940
+3.9,0.9939
+4.0,0.9937
+4.1,0.9936
+4.2,0.9934
+4.3,0.9932
+4.4,0.9931
+4.5,0.9929
+4.6,0.9927
+4.7,0.9926
+4.8,0.9924
+4.9,0.9922
+5.0,0.9920
+5.1,0.9918
+5.2,0.9916
+5.3,0.9914
+5.4,0.9912
+5.5,0.9909
+5.6,0.9907
+5.7,0.9905
+5.8,0.9902
+5.9,0.9900
+6.0,0.9897
+6.1,0.9895
+6.2,0.9892
+6.3,0.9889
+6.4,0.9887
+6.5,0.9884
+6.6,0.9881
+6.7,0.9878
+6.8,0.9875
+6.9,0.9872
+7.0,0.9868
+7.1,0.9865
+7.2,0.9861
+7.3,0.9858
+7.4,0.9854
+7.5,0.9851
+7.6,0.9847
+7.7,0.9843
+7.8,0.9839
+7.9,0.9835
+8.0,0.9831
+8.1,0.9826
+8.2,0.9822
+8.3,0.9818
+8.4,0.9813
+8.5,0.9808
+8.6,0.9803
+8.7,0.9798
+8.8,0.9793
+8.9,0.9788
+9.0,0.9783
+9.1,0.9777
+9.2,0.9772
+9.3,0.9766
+9.4,0.9760
+9.5,0.9754
+9.6,0.9748
+9.7,0.9742
+9.8,0.9735
+9.9,0.9729
+10.0,0.9722
+10.1,0.9715
+10.2,0.9708
+10.3,0.9701
+10.4,0.9694
+10.5,0.9686
+10.6,0.9679
+10.7,0.9671
+10.8,0.9663
+10.9,0.9654
+11.0,0.9646
+11.1,0.9637
+11.2,0.9629
+11.3,0.9620
+11.4,0.9611
+11.5,0.9601
+11.6,0.9592
+11.7,0.9582
+11.8,0.9572
+11.9,0.9562
+12.0,0.9551
+12.1,0.9541
+12.2,0.9530
+12.3,0.9519
+12.4,0.9507
+12.5,0.9496
+12.6,0.9484
+12.7,0.9472
+12.8,0.9460
+12.9,0.9447
+13.0,0.9434
+13.1,0.9421
+13.2,0.9408
+13.3,0.9394
+13.4,0.9380
+13.5,0.9366
+13.6,0.9352
+13.7,0.9337
+13.8,0.9322
+13.9,0.9307
+14.0,0.9291
+14.1,0.9275
+14.2,0.9259
+14.3,0.9243
+14.4,0.9226
+14.5,0.9209
+14.6,0.9191
+14.7,0.9174
+14.8,0.9156
+14.9,0.9137
+15.0,0.9118
+15.1,0.9099
+15.2,0.9080
+15.3,0.9060
+15.4,0.9041
+15.5,0.9020
+15.6,0.8999
+15.7,0.8978
+15.8,0.8956
+15.9,0.8934
+16.0,0.8912
+16.1,0.8889
+16.2,0.8866
+16.3,0.8843
+16.4,0.8819
+16.5,0.8795
+16.6,0.8770
+16.7,0.8745
+16.8,0.8720
+16.9,0.8694
+17.0,0.8668
+17.1,0.8641
+17.2,0.8614
+17.3,0.8587
+17.4,0.8559
+17.5,0.8531
+17.6,0.8502
+17.7,0.8473
+17.8,0.8444
+17.9,0.8414
+18.0,0.8383
+18.1,0.8353
+18.2,0.8323
+18.3,0.8291
+18.4,0.8259
+18.5,0.8227
+18.6,0.8194
+18.7,0.8160
+18.8,0.8127
+18.9,0.8092
+19.0,0.8058
+19.1,0.8022
+19.2,0.7987
+19.3,0.7951
+19.4,0.7914
+19.5,0.7878
+19.6,0.7840
+19.7,0.7803
+19.8,0.7764
+19.9,0.7726
+20.0,0.7687
+20.1,0.7647
+20.2,0.7607
+20.3,0.7567
+20.4,0.7526
+20.5,0.7485
+20.6,0.7443
+20.7,0.7401
+20.8,0.7359
+20.9,0.7316
+21.0,0.7272
+21.1,0.7229
+21.2,0.7185
+21.3,0.7140
+21.4,0.7096
+21.5,0.7050
+21.6,0.7005
+21.7,0.6959
+21.8,0.6912
+21.9,0.6866
+22.0,0.6819
+22.1,0.6771
+22.2,0.6723
+22.3,0.6675
+22.4,0.6627
+22.5,0.6578
+22.6,0.6530
+22.7,0.6480
+22.8,0.6430
+22.9,0.6380
+23.0,0.6330
+23.1,0.6280
+23.2,0.6229
+23.3,0.6178
+23.4,0.6126
+23.5,0.6075
+23.6,0.6023
+23.7,0.5971
+23.8,0.5918
+23.9,0.5866
+24.0,0.5813
+24.1,0.5760
+24.2,0.5706
+24.3,0.5653
+24.4,0.5600
+24.5,0.5547
+24.6,0.5493
+24.7,0.5440
+24.8,0.5385
+24.9,0.5332
+25.0,0.5278
+25.1,0.5224
+25.2,0.5170
+25.3,0.5115
+25.4,0.5061
+25.5,0.5007
+25.6,0.4952
+25.7,0.4898
+25.8,0.4844
+25.9,0.4789
+26.0,0.4735
+26.1,0.4681
+26.2,0.4627
+26.3,0.4572
+26.4,0.4518
+26.5,0.4464
+26.6,0.4410
+26.7,0.4356
+26.8,0.4303
+26.9,0.4249
+27.0,0.4194
+27.1,0.4143
+27.2,0.4089
+27.3,0.4036
+27.4,0.3983
+27.5,0.3931
+27.6,0.3878
+27.7,0.3826
+27.8,0.3774
+27.9,0.3724
+28.0,0.3672
+28.1,0.3621
+28.2,0.3571
+28.3,0.3520
+28.4,0.3470
+28.5,0.3420
+28.6,0.3370
+28.7,0.3320
+28.8,0.3271
+28.9,0.3223
+29.0,0.3174
+29.1,0.3126
+29.2,0.3078
+29.3,0.3031
+29.4,0.2983
+29.5,0.2936
+29.6,0.2890
+29.7,0.2845
+29.8,0.2801
+29.9,0.2756
+30.0,0.2711
+30.1,0.2667
+30.2,0.2623
+30.3,0.2580
+30.4,0.2537
+30.5,0.2495
+30.6,0.2453
+30.7,0.2411
+30.8,0.2370
+30.9,0.2329
+31.0,0.2289
+31.1,0.2250
+31.2,0.2210
+31.3,0.2171
+31.4,0.2133
+31.5,0.2095
+31.6,0.2057
+31.7,0.2019
+31.8,0.1983
+31.9,0.1947
+32.0,0.1912
+32.1,0.1876
+32.2,0.1842
+32.3,0.1807
+32.4,0.1773
+32.5,0.1740
+32.6,0.1707
+32.7,0.1674
+32.8,0.1642
+32.9,0.1611
+33.0,0.1580
+33.1,0.1549
+33.2,0.1520
+33.3,0.1490
+33.4,0.1461
+33.5,0.1432
+33.6,0.1404
+33.7,0.1376
+33.8,0.1348
+33.9,0.1321
+34.0,0.1294
+34.1,0.1268
+34.2,0.1242
+34.3,0.1217
+34.4,0.1193
+34.5,0.1168
+34.6,0.1144
+34.7,0.1120
+34.8,0.1097
+34.9,0.1074
+35.0,0.1052
+35.1,0.1029
+35.2,0.1008
+35.3,0.0987
+35.4,0.0966
+35.5,0.0946
+35.6,0.0925
+35.7,0.0905
+35.8,0.0886
+35.9,0.0867
+36.0,0.0848
+36.1,0.0830
+36.2,0.0812
+36.3,0.0794
+36.4,0.0777
+36.5,0.0760
+36.6,0.0743
+36.7,0.0727
+36.8,0.0711
+36.9,0.0696
+37.0,0.0680
+37.1,0.0665
+37.2,0.0651
+37.3,0.0636
+37.4,0.0622
+37.5,0.0608
+37.6,0.0595
+37.7,0.0581
+37.8,0.0568
+37.9,0.0555
+38.0,0.0543
+38.1,0.0531
+38.2,0.0519
+38.3,0.0507
+38.4,0.0495
+38.5,0.0484
+38.6,0.0473
+38.7,0.0462
+38.8,0.0452
+38.9,0.0441
+39.0,0.0431
+39.1,0.0421
+39.2,0.0412
+39.3,0.0402
+39.4,0.0393
+39.5,0.0384
+39.6,0.0375
+39.7,0.0366
+39.8,0.0358
+39.9,0.0350
+40.0,0.0342
diff --git a/graphics/asymptote/doc/xasy.1x b/graphics/asymptote/doc/xasy.1x
new file mode 100644
index 0000000000..e882db2521
--- /dev/null
+++ b/graphics/asymptote/doc/xasy.1x
@@ -0,0 +1,27 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH XASY 1x "27 Nov 2007"
+.SH NAME
+asy \- script-based vector graphics language
+.SH SYNOPSIS
+.B xasy
+.RI " [-x magnification] [filename]"
+.SH DESCRIPTION
+\fBAsymptote\fP is a powerful descriptive vector graphics language for
+technical drawing, inspired by MetaPost but with an improved C++\-like syntax.
+Asymptote provides for figures the same high\-quality level of typesetting that
+LaTeX does for scientific text.
+.PP
+\fBxasy\fP is a GUI for Asymptote that allows for final figure adjustments.
+
+.SH OPTIONS
+.TP
+.B \-x magnification
+Initial zoom.
+
+.SH SEE ALSO
+Asymptote and xasy are documented fully in the Asymptote Info page.
+.SH AUTHOR
+Asymptote was written by Andy Hammerlindl, John Bowman, and Tom Prince.
+.PP
+This manual page was written by Hubert Chan for the Debian project (but may
+be used by others).
diff --git a/graphics/asymptote/drawclipbegin.h b/graphics/asymptote/drawclipbegin.h
new file mode 100644
index 0000000000..58b4ac5794
--- /dev/null
+++ b/graphics/asymptote/drawclipbegin.h
@@ -0,0 +1,92 @@
+/*****
+ * drawclipbegin.h
+ * John Bowman
+ *
+ * Begin clip of picture to specified path.
+ *****/
+
+#ifndef DRAWCLIPBEGIN_H
+#define DRAWCLIPBEGIN_H
+
+#include "drawelement.h"
+#include "path.h"
+#include "drawpath.h"
+
+namespace camp {
+
+class drawClipBegin : public drawSuperPathPenBase {
+ bool gsave;
+ bool stroke;
+public:
+ void noncyclic() {
+ reportError("cannot clip to non-cyclic path");
+ }
+
+ drawClipBegin(const vm::array& src, bool stroke, pen pentype,
+ bool gsave=true, const string& key="") :
+ drawElement(key), drawSuperPathPenBase(src,pentype), gsave(gsave),
+ stroke(stroke) {
+ if(!stroke && !cyclic()) noncyclic();
+ }
+
+ virtual ~drawClipBegin() {}
+
+ bool beginclip() {return true;}
+
+ void bounds(bbox& b, iopipestream& iopipe, boxvector& vbox,
+ bboxlist& bboxstack) {
+ bboxstack.push_back(b);
+ bbox bpath;
+ if(stroke) strokebounds(bpath);
+ else drawSuperPathPenBase::bounds(bpath,iopipe,vbox,bboxstack);
+ bboxstack.push_back(bpath);
+ }
+
+ bool begingroup() {return true;}
+
+ bool svg() {return true;}
+
+ void save(bool b) {
+ gsave=b;
+ }
+
+ bool draw(psfile *out) {
+ if(gsave) out->gsave();
+ if(empty()) return true;
+ out->beginclip();
+ writepath(out,false);
+ if(stroke) strokepath(out);
+ out->endclip(pentype);
+ return true;
+ }
+
+ bool write(texfile *out, const bbox& bpath) {
+ if(gsave) out->gsave();
+ if(empty()) return true;
+
+ if(out->toplevel())
+ out->beginpicture(bpath);
+
+ out->begingroup();
+
+ out->beginspecial();
+ out->beginraw();
+ writeshiftedpath(out);
+ if(stroke) strokepath(out);
+ out->endclip(pentype);
+ out->endraw();
+ out->endspecial();
+
+ return true;
+ }
+
+ drawElement *transformed(const transform& t)
+ {
+ return new drawClipBegin(transpath(t),stroke,transpen(t),gsave,KEY);
+ }
+
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/drawclipend.h b/graphics/asymptote/drawclipend.h
new file mode 100644
index 0000000000..e86842d3d1
--- /dev/null
+++ b/graphics/asymptote/drawclipend.h
@@ -0,0 +1,66 @@
+/*****
+ * drawclipend.h
+ * John Bowman
+ *
+ * End clip of picture to specified path.
+ *****/
+
+#ifndef DRAWCLIPEND_H
+#define DRAWCLIPEND_H
+
+#include "drawclipbegin.h"
+#include "path.h"
+
+namespace camp {
+
+class drawClipEnd : public drawElement {
+ bool grestore;
+ drawClipBegin *partner;
+public:
+ drawClipEnd(bool grestore=true, drawClipBegin *partner=NULL) :
+ grestore(grestore), partner(partner) {}
+
+ virtual ~drawClipEnd() {}
+
+ bool endclip() {return true;}
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist& bboxstack) {
+ if(bboxstack.size() < 2)
+ reportError("endclip without matching beginclip");
+ b.clip(bboxstack.back());
+ bboxstack.pop_back();
+ b += bboxstack.back();
+ bboxstack.pop_back();
+ }
+
+ bool endgroup() {return true;}
+
+ bool svg() {return true;}
+
+ void save(bool b) {
+ grestore=b;
+ if(partner) partner->save(b);
+ }
+
+ bool draw(psfile *out) {
+ if(grestore) out->grestore();
+ return true;
+ }
+
+ bool write(texfile *out, const bbox& bpath) {
+ out->endgroup();
+
+ if(out->toplevel())
+ out->endpicture(bpath);
+
+ if(grestore) out->grestore();
+ return true;
+ }
+
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawClipEnd);
+
+#endif
diff --git a/graphics/asymptote/drawelement.h b/graphics/asymptote/drawelement.h
new file mode 100644
index 0000000000..cea6baf3c9
--- /dev/null
+++ b/graphics/asymptote/drawelement.h
@@ -0,0 +1,436 @@
+/*****
+ * drawelement.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Abstract base class of any drawable item in camp.
+ *****/
+
+#ifndef DRAWELEMENT_H
+#define DRAWELEMENT_H
+
+#include <vector>
+
+#include "common.h"
+#include "bbox.h"
+#include "bbox3.h"
+#include "pen.h"
+#include "psfile.h"
+#include "texfile.h"
+#include "prcfile.h"
+#include "glrender.h"
+#include "arrayop.h"
+#include "material.h"
+
+namespace camp {
+
+//extern double Tx[3]; // x-component of current transform
+//extern double Ty[3]; // y-component of current transform
+extern double* Tz; // z-component of current transform
+
+static const double pixel=1.0; // Adaptive rendering constant.
+
+// Return one-sixth of the second derivative of the Bezier curve defined
+// by a,b,c,d at 0.
+inline triple bezierPP(triple a, triple b, triple c) {
+ return a+c-2.0*b;
+}
+
+// Return one-third of the third derivative of the Bezier curve defined by
+// a,b,c,d.
+inline triple bezierPPP(triple a, triple b, triple c, triple d) {
+ return d-a+3.0*(b-c);
+}
+
+enum Interaction {EMBEDDED=0,BILLBOARD};
+
+void copyArray4x4C(double*& dest, const vm::array *a);
+
+class box {
+ pair p[4];
+public:
+
+ box() {}
+ box(const pair& a, const pair& b, const pair& c, const pair& d) {
+ p[0]=a; p[1]=b; p[2]=c; p[3]=d;
+ }
+
+// Returns true if the line a--b intersects box b.
+ bool intersect(const pair& a, const pair& b) const
+ {
+ for(Int i=0; i < 4; ++i) {
+ pair A=p[i];
+ pair B=p[i < 3 ? i+1 : 0];
+ double de=(b.x-a.x)*(A.y-B.y)-(A.x-B.x)*(b.y-a.y);
+ if(de != 0.0) {
+ de=1.0/de;
+ double t=((A.x-a.x)*(A.y-B.y)-(A.x-B.x)*(A.y-a.y))*de;
+ double T=((b.x-a.x)*(A.y-a.y)-(A.x-a.x)*(b.y-a.y))*de;
+ if(0 <= t && t <= 1 && 0 <= T && T <= 1) return true;
+ }
+ }
+ return false;
+ }
+
+ pair operator [] (Int i) const {return p[i];}
+
+ bool intersect(const box& b) const {
+ for(Int i=0; i < 4; ++i) {
+ pair A=b[i];
+ pair B=b[i < 3 ? i+1 : 0];
+ if(intersect(A,B)) return true;
+ }
+ return false;
+ }
+
+// Returns true iff the point z lies in the region bounded by b.
+ bool inside(const pair& z) const {
+ bool c=false;
+ for(Int i=0; i < 3; ++i) {
+ pair pi=p[i];
+ pair pj=p[i < 3 ? i+1 : 0];
+ if(((pi.y <= z.y && z.y < pj.y) || (pj.y <= z.y && z.y < pi.y)) &&
+ z.x < pi.x+(pj.x-pi.x)*(z.y-pi.y)/(pj.y-pi.y)) c=!c;
+ }
+ return c;
+ }
+
+ double xmax() {
+ return max(max(max(p[0].x,p[1].x),p[2].x),p[3].x);
+ }
+
+ double ymax() {
+ return max(max(max(p[0].y,p[1].y),p[2].y),p[3].y);
+ }
+
+ double xmin() {
+ return min(min(min(p[0].x,p[1].x),p[2].x),p[3].x);
+ }
+
+ double ymin() {
+ return min(min(min(p[0].y,p[1].y),p[2].y),p[3].y);
+ }
+
+};
+
+typedef mem::vector<box> boxvector;
+
+typedef mem::list<bbox> bboxlist;
+
+typedef mem::map<CONST string,unsigned> groupmap;
+typedef mem::vector<groupmap> groupsmap;
+
+#ifdef HAVE_GL
+typedef mem::map<CONST Material,size_t> MaterialMap;
+#endif
+
+class drawElement : public gc
+{
+public:
+ string KEY;
+
+ drawElement(const string& key="") : KEY(key == "" ? processData().KEY : key)
+ {}
+
+ virtual ~drawElement() {}
+
+
+#ifdef HAVE_GL
+ static mem::vector<Material> material;
+ static MaterialMap materialMap;
+ static size_t materialIndex;
+#endif
+
+ static pen lastpen;
+ static const triple zero;
+
+ // Adjust the bbox of the picture based on the addition of this
+ // element. The iopipestream is needed for determining label sizes.
+ virtual void bounds(bbox&, iopipestream&, boxvector&, bboxlist&) {}
+ virtual void bounds(const double*, bbox3&) {}
+ virtual void bounds(bbox3& b) { bounds(NULL, b); }
+
+ // Compute bounds on ratio (x,y)/z for 3d picture (not cached).
+ virtual void ratio(const double *t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first) {}
+
+ virtual void minratio(const double *t, pair &b, double fuzz, bool &first) {
+ ratio(t, b, camp::min, fuzz, first);
+ }
+
+ virtual void maxratio(const double *t,pair &b, double fuzz, bool &first) {
+ ratio(t, b, camp::max, fuzz, first);
+ }
+
+ virtual void ratio(pair &b, double (*m)(double, double), double fuzz,
+ bool &first) {
+ ratio(NULL, b, m, fuzz, first);
+ }
+
+ virtual void minratio(pair &b, double fuzz, bool &first) {
+ minratio(NULL, b, fuzz, first);
+ }
+
+ virtual void maxratio(pair &b, double fuzz, bool &first) {
+ maxratio(NULL, b, fuzz, first);
+ }
+
+ virtual bool islabel() {return false;}
+
+ virtual bool isnewpage() {return false;}
+
+ virtual bool islayer() {return false;}
+
+ virtual bool is3D() {return false;}
+
+// Implement element as raw SVG code?
+ virtual bool svg() {return false;}
+
+// Implement SVG element as png image?
+ virtual bool svgpng() {return false;}
+
+ virtual bool beginclip() {return false;}
+ virtual bool endclip() {return false;}
+
+ virtual bool begingroup() {return false;}
+ virtual bool begingroup3() {return false;}
+
+ virtual bool endgroup() {return false;}
+ virtual bool endgroup3() {return false;}
+
+ virtual const double* transf3() {return NULL;}
+
+ virtual void save(bool b) {}
+
+ // Output to a PostScript file
+ virtual bool draw(psfile *) {
+ return false;
+ }
+
+ // Output to a TeX file
+ virtual bool write(texfile *, const bbox&) {
+ return false;
+ }
+
+ // Output to a PRC file
+ virtual bool write(prcfile *out, unsigned int *count, double compressionlimit,
+ groupsmap& groups) {
+ return false;
+ }
+
+ // Used to compute deviation of a surface from a quadrilateral.
+ virtual void displacement() {}
+
+ // Render with OpenGL
+ virtual void render(double size2, const triple& Min, const triple& Max,
+ double perspective, bool transparent) {}
+
+ // Transform as part of a picture.
+ virtual drawElement *transformed(const transform&) {
+ return this;
+ }
+
+ virtual drawElement *transformed(const double* t) {
+ return this;
+ }
+
+};
+
+// Hold transform of an object.
+class drawElementLC : public virtual drawElement {
+public:
+ double *T; // Keep track of accumulative picture transform
+
+ drawElementLC() : T(NULL) {}
+
+ drawElementLC(const double *t) : T(NULL) {
+ copyTransform3(T,t);
+ }
+
+ drawElementLC(const vm::array& t) : T(NULL) {
+ copyArray4x4C(T,&t);
+ }
+
+ drawElementLC(const double* t, const drawElementLC *s) :
+ drawElement(s->KEY), T(NULL) {
+ multiplyTransform3(T,t,s->T);
+ }
+
+ virtual ~drawElementLC() {}
+
+ virtual bool is3D() {return true;}
+
+ virtual const double* transf3() {return T;}
+
+ virtual drawElement* transformed(const double* t) {
+ return new drawElementLC(t,this);
+ }
+};
+
+// Base class for drawElements that involve paths.
+class drawPathBase : public virtual drawElement {
+protected:
+ path p;
+
+ path transpath(const transform& t) const {
+ return p.transformed(t);
+ }
+
+public:
+ drawPathBase() {}
+ drawPathBase(path p) : p(p) {}
+
+ virtual ~drawPathBase() {}
+
+ virtual void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ b += p.bounds();
+ }
+
+ virtual void writepath(psfile *out,bool) {
+ out->write(p);
+ }
+
+ virtual void writeclippath(psfile *out, bool newpath=true) {
+ out->writeclip(p,newpath);
+ }
+
+ virtual void writeshiftedpath(texfile *out) {
+ out->writeshifted(p);
+ }
+};
+
+// Base class for drawElements that involve paths and pens.
+class drawPathPenBase : public drawPathBase {
+protected:
+ pen pentype;
+
+ pen transpen(const transform& t) const {
+ return camp::transformed(shiftless(t),pentype);
+ }
+
+public:
+ drawPathPenBase(path p, pen pentype) :
+ drawPathBase(p), pentype(pentype) {}
+
+ drawPathPenBase(pen pentype) :
+ pentype(pentype) {}
+
+ virtual bool empty() {
+ return p.empty();
+ }
+
+ virtual bool cyclic() {
+ return p.cyclic();
+ }
+
+ void strokebounds(bbox& b, const path& p);
+
+ virtual void penSave(psfile *out)
+ {
+ if (!pentype.getTransform().isIdentity())
+ out->gsave();
+ }
+
+ virtual void penTranslate(psfile *out)
+ {
+ out->translate(shiftpair(pentype.getTransform()));
+ }
+
+ virtual void penConcat(psfile *out)
+ {
+ out->concat(shiftless(pentype.getTransform()));
+ }
+
+ virtual void penRestore(psfile *out)
+ {
+ if (!pentype.getTransform().isIdentity())
+ out->grestore();
+ }
+};
+
+// Base class for drawElements that involve superpaths and pens.
+class drawSuperPathPenBase : public drawPathPenBase {
+protected:
+ vm::array P;
+ size_t size;
+ bbox bpath;
+
+ vm::array transpath(const transform& t) const {
+ vm::array *Pt=new vm::array(size);
+ for(size_t i=0; i < size; i++)
+ (*Pt)[i]=vm::read<path>(P,i).transformed(t);
+ return *Pt;
+ }
+
+public:
+ drawSuperPathPenBase(const vm::array& P, pen pentype) :
+ drawPathPenBase(pentype), P(P), size(P.size()) {}
+
+ bool empty() {
+ for(size_t i=0; i < size; i++)
+ if(vm::read<path>(P,i).size() != 0) return false;
+ return true;
+ }
+
+ bool cyclic() {
+ for(size_t i=0; i < size; i++)
+ if(!vm::read<path>(P,i).cyclic()) return false;
+ return true;
+ }
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ for(size_t i=0; i < size; i++)
+ bpath += vm::read<path>(P,i).bounds();
+ b += bpath;
+ }
+
+ void strokepath(psfile *out) {
+ out->strokepath();
+ }
+
+ void strokebounds(bbox& b) {
+ for(size_t i=0; i < size; i++)
+ drawPathPenBase::strokebounds(bpath,vm::read<path>(P,i));
+ b += bpath;
+ }
+
+ void writepath(psfile *out, bool newpath=true) {
+ if(size > 0) out->write(vm::read<path>(P,0),newpath);
+ for(size_t i=1; i < size; i++)
+ out->write(vm::read<path>(P,i),false);
+ }
+
+ void writeclippath(psfile *out, bool newpath=true) {
+ if(size > 0) out->writeclip(vm::read<path>(P,0),newpath);
+ for(size_t i=1; i < size; i++)
+ out->writeclip(vm::read<path>(P,i),false);
+ }
+
+ void writeshiftedpath(texfile *out) {
+ for(size_t i=0; i < size; i++)
+ out->writeshifted(vm::read<path>(P,i),i == 0);
+ }
+};
+
+#ifdef HAVE_GL
+template<class T>
+void registerBuffer(std::vector<T>& buffervector, GLuint bufferIndex) {
+ if (!buffervector.empty()) {
+ glBindBuffer(GL_ARRAY_BUFFER,bufferIndex);
+ glBufferData(GL_ARRAY_BUFFER,sizeof(T)*buffervector.size(),
+ buffervector.data(),GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER,0);
+ }
+}
+
+void setcolors(bool colors,
+ const prc::RGBAColour& diffuse,
+ const prc::RGBAColour& emissive,
+ const prc::RGBAColour& specular, double shininess,
+ double metallic, double fresnel0);
+#endif
+}
+
+GC_DECLARE_PTRFREE(camp::box);
+GC_DECLARE_PTRFREE(camp::drawElement);
+
+#endif
diff --git a/graphics/asymptote/drawfill.cc b/graphics/asymptote/drawfill.cc
new file mode 100644
index 0000000000..443a7775d4
--- /dev/null
+++ b/graphics/asymptote/drawfill.cc
@@ -0,0 +1,176 @@
+/*****
+ * drawfill.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a cyclic path that will outline a filled shape in a picture.
+ *****/
+
+#include "drawfill.h"
+
+namespace camp {
+
+using settings::ps2tex;
+using settings::tex2ps;
+
+void drawAxialShade::palette(psfile *out)
+{
+ pentype.convert();
+ penb.convert();
+
+ colorspace=(ColorSpace) max(pentype.colorspace(),penb.colorspace());
+
+ switch(colorspace) {
+ case RGB:
+ {
+ if (pentype.grayscale()) pentype.greytorgb();
+ else if (penb.grayscale()) penb.greytorgb();
+ break;
+ }
+
+ case CMYK:
+ {
+ if (pentype.grayscale()) pentype.greytocmyk();
+ else if (penb.grayscale()) penb.greytocmyk();
+
+ if (pentype.rgb()) pentype.rgbtocmyk();
+ else if (penb.rgb()) penb.rgbtocmyk();
+ break;
+ }
+ default:
+ break;
+ }
+
+ out->gsave();
+}
+
+bool drawFill::draw(psfile *out)
+{
+ if(pentype.invisible() || empty()) return true;
+
+ palette(out);
+ writepath(out);
+ fill(out);
+ return true;
+}
+
+drawElement *drawFill::transformed(const transform& t)
+{
+ return new drawFill(transpath(t),stroke,transpen(t),KEY);
+}
+
+drawElement *drawLatticeShade::transformed(const transform& t)
+{
+ return new drawLatticeShade(transpath(t),stroke,pentype,pens,t*T,KEY);
+}
+
+drawElement *drawAxialShade::transformed(const transform& t)
+{
+ pair A=t*a, B=t*b;
+ return new drawAxialShade(transpath(t),stroke,pentype,A,extenda,penb,B,
+ extendb,KEY);
+}
+
+drawElement *drawRadialShade::transformed(const transform& t)
+{
+ pair A=t*a, B=t*b;
+ double RA=length(t*(a+ra)-A);
+ double RB=length(t*(b+rb)-B);
+ return new drawRadialShade(transpath(t),stroke,pentype,A,RA,extenda,penb,B,
+ RB,extendb,KEY);
+}
+
+drawElement *drawGouraudShade::transformed(const transform& t)
+{
+ size_t size=vertices.size();
+ vm::array *Vertices=new vm::array(size);
+ for(size_t i=0; i < size; i++)
+ (*Vertices)[i]=t*vm::read<pair>(vertices,i);
+
+ return new drawGouraudShade(transpath(t),stroke,pentype,pens,*Vertices,
+ edges,KEY);
+}
+
+drawElement *drawTensorShade::transformed(const transform& t)
+{
+ size_t size=boundaries.size();
+ size_t zsize=z.size();
+ vm::array *Boundaries=new vm::array(size);
+ vm::array *Z=new vm::array(zsize);
+
+ for(size_t i=0; i < size; i++)
+ (*Boundaries)[i]=vm::read<path>(boundaries,i).transformed(t);
+
+ for(size_t i=0; i < zsize; i++) {
+ vm::array *zi=vm::read<vm::array *>(z,i);
+ size_t zisize=checkArray(zi);
+ vm::array *Zi=new vm::array(zisize);
+ (*Z)[i]=Zi;
+ for(size_t j=0; j < zisize; j++)
+ (*Zi)[j]=t*vm::read<pair>(zi,j);
+ }
+
+ return new drawTensorShade(transpath(t),stroke,pentype,pens,*Boundaries,*Z,
+ KEY);
+}
+
+bool drawFunctionShade::write(texfile *out, const bbox& box)
+{
+ if(empty()) return true;
+
+ ColorSpace colorspace=pentype.colorspace();
+ size_t ncomponents=ColorComponents[colorspace];
+
+ out->verbatim("\\pdfobj stream attr {/FunctionType 4");
+ out->verbatim("/Domain [0 1 0 1]");
+ out->verbatim("/Range [");
+ for(size_t i=0; i < ncomponents; ++i)
+ out->verbatim("0 1 ");
+ out->verbatim("]}{{");
+ out->verbatimline(shader);
+ out->verbatimline("}}%");
+ out->verbatimline("\\edef\\lastobj{\\the\\pdflastobj}\\pdfrefobj\\lastobj");
+
+ out->verbatim("\\setbox\\ASYbox=\\hbox to ");
+ double Hoffset=out->hoffset();
+ double hoffset=(bpath.Max().getx()-Hoffset)*ps2tex;
+ out->write(hoffset);
+ out->verbatim("pt {");
+ out->verbatim("\\vbox to ");
+ out->write((box.top-box.bottom)*ps2tex);
+ out->verbatimline("pt {\\vfil%");
+ out->gsave();
+ out->beginspecial();
+ out->beginraw();
+ writeshiftedpath(out);
+ if(stroke) strokepath(out);
+ out->endclip(pentype);
+ out->verbatimline("/Sh sh");
+ out->endraw();
+ out->endspecial();
+ out->grestore();
+ out->verbatimline("}\\hfil}%");
+
+ out->verbatimline("\\pdfxform resources {");
+ out->verbatimline("/Shading << /Sh << /ShadingType 1");
+ out->verbatim("/Matrix [");
+
+ out->write(shift(pair(-Hoffset,-box.bottom))*matrix(bpath.Min(),bpath.Max()));
+ out->verbatimline("]");
+ out->verbatim("/Domain [0 1 0 1]");
+ out->verbatim("/ColorSpace /Device");
+ out->verbatimline(ColorDeviceSuffix[colorspace]);
+ out->verbatimline("/Function \\lastobj\\space 0 R >> >>}\\ASYbox");
+
+ out->verbatimline("\\pdfrefxform\\the\\pdflastxform");
+ out->verbatim("\\kern");
+ out->write(-hoffset);
+ out->verbatimline("pt%");
+ return true;
+}
+
+drawElement *drawFunctionShade::transformed(const transform& t)
+{
+ return new drawFunctionShade(transpath(t),stroke,pentype,shader,KEY);
+}
+
+} // namespace camp
diff --git a/graphics/asymptote/drawfill.h b/graphics/asymptote/drawfill.h
new file mode 100644
index 0000000000..4f7df49f96
--- /dev/null
+++ b/graphics/asymptote/drawfill.h
@@ -0,0 +1,256 @@
+/*****
+ * drawfill.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a cyclic path that will outline a filled shape in a picture.
+ *****/
+
+#ifndef DRAWFILL_H
+#define DRAWFILL_H
+
+#include "drawelement.h"
+#include "path.h"
+
+namespace camp {
+
+class drawFill : public drawSuperPathPenBase {
+protected:
+ bool stroke;
+public:
+ void noncyclic() {
+ reportError("non-cyclic path cannot be filled");
+ }
+
+ drawFill(const vm::array& src, bool stroke, pen pentype,
+ const string& key="") :
+ drawElement(key), drawSuperPathPenBase(src,pentype), stroke(stroke) {
+ if(!stroke && !cyclic()) noncyclic();
+ }
+
+ bool svg() {return true;}
+
+ // dvisvgm doesn't yet support SVG patterns.
+ bool svgpng() {return pentype.fillpattern() != "";}
+
+ virtual ~drawFill() {}
+
+ virtual bool draw(psfile *out);
+
+ virtual void palette(psfile *out) {
+ penSave(out);
+ penTranslate(out);
+ }
+ virtual void fill(psfile *out) {
+ out->setpen(pentype);
+ if(stroke) out->strokepath();
+ out->fill(pentype);
+ penRestore(out);
+ };
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawShade : public drawFill {
+public:
+ drawShade(const vm::array& src, bool stroke, pen pentype,
+ const string& key="")
+ : drawFill(src,stroke,pentype,key) {}
+
+ void bounds(bbox& b, iopipestream& iopipe, boxvector& vbox,
+ bboxlist& bboxstack) {
+ if(stroke) strokebounds(b);
+ else drawSuperPathPenBase::bounds(b,iopipe,vbox,bboxstack);
+ }
+
+ // Shading in SVG is incomplete and not supported at all by dvisvgm.
+ bool svgpng() {return true;}
+
+ virtual void beginshade(psfile *out)=0;
+ virtual void shade(psfile *out)=0;
+
+ bool draw(psfile *out) {
+ if(pentype.invisible() || empty()) return true;
+
+ palette(out);
+ beginshade(out);
+ writeclippath(out);
+ if(stroke) strokepath(out);
+ out->endpsclip(pentype.Fillrule());
+ shade(out);
+ out->grestore();
+ return true;
+ }
+};
+
+class drawLatticeShade : public drawShade {
+protected:
+ vm::array pens;
+ const transform T;
+public:
+ drawLatticeShade(const vm::array& src, bool stroke,
+ pen pentype, const vm::array& pens,
+ const camp::transform& T=identity, const string& key="")
+ : drawShade(src,stroke,pentype,key), pens(pens), T(T) {}
+
+ void palette(psfile *out) {
+ out->gsave();
+ }
+
+ void beginshade(psfile *out) {
+ out->beginlatticeshade(pens,bpath);
+ }
+
+ void shade(psfile *out) {
+ bbox b;
+ for(size_t i=0; i < size; i++) {
+ path p=vm::read<path>(P,i).transformed(inverse(T));
+ if(stroke)
+ drawPathPenBase::strokebounds(b,p);
+ else
+ b += p.bounds();
+ }
+ out->latticeshade(pens,T*matrix(b.Min(),b.Max()));
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawAxialShade : public drawShade {
+protected:
+ pair a;
+ bool extenda;
+ pen penb;
+ pair b;
+ bool extendb;
+ ColorSpace colorspace;
+public:
+ drawAxialShade(const vm::array& src, bool stroke,
+ pen pentype, pair a, bool extenda, pen penb, pair b,
+ bool extendb, const string& key="")
+ : drawShade(src,stroke,pentype,key), a(a), extenda(extenda),
+ penb(penb), b(b), extendb(extendb) {}
+
+ bool svgpng() {return false;}
+
+ void palette(psfile *out);
+
+ void beginshade(psfile *out) {
+ out->begingradientshade(true,colorspace,pentype,a,0,penb,b,0);
+ }
+
+ void shade(psfile *out) {
+ out->gradientshade(true,colorspace,pentype,a,0,extenda,penb,b,0,extendb);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawRadialShade : public drawAxialShade {
+protected:
+ double ra;
+ double rb;
+public:
+ drawRadialShade(const vm::array& src, bool stroke,
+ pen pentype, pair a, double ra, bool extenda, pen penb,
+ pair b, double rb, bool extendb, const string& key="")
+ : drawAxialShade(src,stroke,pentype,a,extenda,penb,b,
+ extendb,key), ra(ra), rb(rb) {}
+
+ bool svgpng() {return ra > 0.0;}
+
+ void beginshade(psfile *out) {
+ out->begingradientshade(false,colorspace,pentype,a,ra,penb,b,rb);
+ }
+
+ void shade(psfile *out) {
+ out->gradientshade(false,colorspace,pentype,a,ra,extenda,penb,b,rb,extendb);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawGouraudShade : public drawShade {
+protected:
+ vm::array pens,vertices,edges;
+public:
+ drawGouraudShade(const vm::array& src, bool stroke,
+ pen pentype, const vm::array& pens,
+ const vm::array& vertices, const vm::array& edges,
+ const string& key="")
+ : drawElement(key), drawShade(src,stroke,pentype,key), pens(pens),
+ vertices(vertices), edges(edges) {}
+
+ bool svgpng() {return !settings::getSetting<bool>("svgemulation");}
+
+ void palette(psfile *out) {
+ out->gsave();
+ }
+
+ void beginshade(psfile *out) {
+ out->begingouraudshade(pens,vertices,edges);
+ }
+
+ void shade(psfile *out) {
+ out->gouraudshade(pentype,pens,vertices,edges);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawTensorShade : public drawShade {
+protected:
+ vm::array pens,boundaries,z;
+public:
+ drawTensorShade(const vm::array& src, bool stroke,
+ pen pentype, const vm::array& pens,
+ const vm::array& boundaries, const vm::array& z,
+ const string& key="") :
+ drawShade(src,stroke,pentype,key), pens(pens), boundaries(boundaries),
+ z(z) {}
+
+ bool svgpng() {
+ return pens.size() > 1 || !settings::getSetting<bool>("svgemulation");
+ }
+
+ void palette(psfile *out) {
+ out->gsave();
+ }
+
+ void beginshade(psfile *out) {
+ out->begintensorshade(pens,boundaries,z);
+ }
+
+ void shade(psfile *out) {
+ out->tensorshade(pentype,pens,boundaries,z);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawFunctionShade : public drawFill {
+protected:
+ string shader;
+public:
+ drawFunctionShade(const vm::array& src, bool stroke,
+ pen pentype, const string& shader, const string& key="")
+ : drawFill(src,stroke,pentype,key), shader(shader) {
+ string texengine=settings::getSetting<string>("tex");
+ if(!settings::pdf(texengine))
+ reportError("functionshade is not implemented for the '"+texengine+
+ "' tex engine");
+ }
+
+ virtual ~drawFunctionShade() {}
+
+ bool draw(psfile *out) {return false;}
+
+ bool write(texfile *, const bbox&);
+
+ bool islabel() {return true;}
+
+ drawElement *transformed(const transform& t);
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/drawgrestore.h b/graphics/asymptote/drawgrestore.h
new file mode 100644
index 0000000000..7f1b62fe63
--- /dev/null
+++ b/graphics/asymptote/drawgrestore.h
@@ -0,0 +1,35 @@
+/*****
+ * drawgrestore.h
+ * John Bowman
+ *
+ * Output PostScript grestore to picture.
+ *****/
+
+#ifndef DRAWGRESTORE_H
+#define DRAWGRESTORE_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawGrestore : public drawElement {
+public:
+ drawGrestore() {}
+ virtual ~drawGrestore() {}
+
+ bool draw(psfile *out) {
+ out->grestore();
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&) {
+ out->grestore();
+ return true;
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawGrestore);
+
+#endif
diff --git a/graphics/asymptote/drawgroup.h b/graphics/asymptote/drawgroup.h
new file mode 100644
index 0000000000..e8149f118b
--- /dev/null
+++ b/graphics/asymptote/drawgroup.h
@@ -0,0 +1,116 @@
+/*****
+ * drawgroup.h
+ * John Bowman
+ *
+ * Group elements in a picture to be deconstructed as a single object.
+ *****/
+
+#ifndef DRAWGROUP_H
+#define DRAWGROUP_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawBegin : public drawElement {
+public:
+ drawBegin() {}
+
+ virtual ~drawBegin() {}
+
+ bool begingroup() {return true;}
+};
+
+class drawEnd : public drawElement {
+public:
+ drawEnd() {}
+
+ virtual ~drawEnd() {}
+
+ bool endgroup() {return true;}
+};
+
+class drawBegin3 : public drawElementLC {
+ string name;
+ double compression;
+ double granularity;
+ bool closed; // render the surface as one-sided; may yield faster rendering
+ bool tessellate; // use tessellated mesh to store straight patches
+ bool dobreak; // force breaking
+ bool nobreak; // force grouping for transparent patches
+
+ triple center;
+ int interaction;
+public:
+ drawBegin3(string name, double compression, double granularity,
+ bool closed, bool tessellate, bool dobreak, bool nobreak,
+ triple center, int interaction) :
+ name(name), compression(compression), granularity(granularity),
+ closed(closed), tessellate(tessellate), dobreak(dobreak), nobreak(nobreak),
+ center(center), interaction(interaction) {}
+
+ virtual ~drawBegin3() {}
+
+ bool begingroup() {return true;}
+ bool begingroup3() {return true;}
+
+ bool write(prcfile *out, unsigned int *count, double compressionlimit,
+ groupsmap& groups) {
+ groupmap& group=groups.back();
+ if(name.empty()) name="group";
+ groupmap::const_iterator p=group.find(name);
+
+ unsigned c=(p != group.end()) ? p->second+1 : 0;
+ group[name]=c;
+
+ ostringstream buf;
+ buf << name;
+ if(c > 0) buf << "-" << (c+1);
+
+ if(interaction == BILLBOARD)
+ buf << "-" << (*count)++ << "\001";
+
+ prc::PRCoptions options(compression > 0.0 ?
+ max(compression,compressionlimit) : 0.0,
+ granularity,closed,tessellate,dobreak,nobreak);
+
+ groups.push_back(groupmap());
+ const string& s=buf.str();
+ out->begingroup(s.c_str(),&options,T);
+ return true;
+ }
+
+ drawBegin3(const double* t, const drawBegin3 *s) :
+ drawElementLC(t, s), name(s->name), compression(s->compression),
+ granularity(s->granularity), closed(s->closed), tessellate(s->tessellate),
+ dobreak(s->dobreak), nobreak(s->nobreak), interaction(s->interaction) {
+ center=t*s->center;
+ }
+
+ drawElement *transformed(const double* t) {
+ return new drawBegin3(t,this);
+ }
+};
+
+class drawEnd3 : public drawElement {
+public:
+ drawEnd3() {}
+
+ virtual ~drawEnd3() {}
+
+ bool endgroup() {return true;}
+ bool endgroup3() {return true;}
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap& groups) {
+ groups.pop_back();
+ out->endgroup();
+ return true;
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawBegin);
+GC_DECLARE_PTRFREE(camp::drawEnd);
+
+#endif
diff --git a/graphics/asymptote/drawgsave.h b/graphics/asymptote/drawgsave.h
new file mode 100644
index 0000000000..bddc3a1dba
--- /dev/null
+++ b/graphics/asymptote/drawgsave.h
@@ -0,0 +1,35 @@
+/*****
+ * drawgsave.h
+ * John Bowman
+ *
+ * Output PostScript gsave to picture.
+ *****/
+
+#ifndef DRAWGSAVE_H
+#define DRAWGSAVE_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawGsave : public drawElement {
+public:
+ drawGsave() {}
+ virtual ~drawGsave() {}
+
+ bool draw(psfile *out) {
+ out->gsave();
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&) {
+ out->gsave();
+ return true;
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawGsave);
+
+#endif
diff --git a/graphics/asymptote/drawimage.h b/graphics/asymptote/drawimage.h
new file mode 100644
index 0000000000..a3c5971dc4
--- /dev/null
+++ b/graphics/asymptote/drawimage.h
@@ -0,0 +1,128 @@
+/*****
+ * drawimage.h
+ * John Bowman
+ *
+ * Stores a image that has been added to a picture.
+ *****/
+
+#ifndef DRAWIMAGE_H
+#define DRAWIMAGE_H
+
+#include "drawelement.h"
+#include "array.h"
+
+namespace camp {
+
+class drawImage : public drawElement {
+protected:
+ transform t;
+ bool antialias;
+public:
+ drawImage(const transform& t, bool antialias, const string& key="")
+ : drawElement(key), t(t), antialias(antialias) {}
+
+ virtual ~drawImage() {}
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ b += t*pair(0,0);
+ b += t*pair(1,1);
+ }
+
+ bool svg() {return true;}
+ bool svgpng() {return true;}
+};
+
+class drawPaletteImage : public drawImage {
+ vm::array image;
+ vm::array palette;
+public:
+ drawPaletteImage(const vm::array& image, const vm::array& palette,
+ const transform& t, bool antialias, const string& key="")
+ : drawImage(t,antialias,key), image(image), palette(palette) {}
+
+ virtual ~drawPaletteImage() {}
+
+ bool draw(psfile *out) {
+ out->gsave();
+ out->concat(t);
+ out->image(image,palette,antialias);
+
+ out->grestore();
+
+ return true;
+ }
+
+ drawElement *transformed(const transform& T) {
+ return new drawPaletteImage(image,palette,T*t,antialias,KEY);
+ }
+};
+
+class drawNoPaletteImage : public drawImage {
+ vm::array image;
+public:
+ drawNoPaletteImage(const vm::array& image, const transform& t,
+ bool antialias, const string& key="")
+ : drawImage(t,antialias,key), image(image) {}
+
+ virtual ~drawNoPaletteImage() {}
+
+ bool draw(psfile *out) {
+ out->gsave();
+ out->concat(t);
+ out->image(image,antialias);
+ out->grestore();
+ return true;
+ }
+
+ drawElement *transformed(const transform& T) {
+ return new drawNoPaletteImage(image,T*t,antialias,KEY);
+ }
+};
+
+class drawFunctionImage : public drawImage {
+ vm::stack *Stack;
+ vm::callable *f;
+ Int width, height;
+public:
+ drawFunctionImage(vm::stack *Stack, vm::callable *f, Int width, Int height,
+ const transform& t, bool antialias, const string& key="")
+ : drawImage(t,antialias,key), Stack(Stack), f(f),
+ width(width), height(height) {}
+
+ virtual ~drawFunctionImage() {}
+
+ bool draw(psfile *out) {
+ out->gsave();
+ out->concat(t);
+ out->image(Stack,f,width,height,antialias);
+ out->grestore();
+ return true;
+ }
+
+ drawElement *transformed(const transform& T) {
+ return new drawFunctionImage(Stack,f,width,height,T*t,antialias,KEY);
+ }
+};
+
+class drawRawImage : public drawImage {
+ unsigned char *raw; // For internal use; not buffered, may be overwritten.
+ size_t width,height;
+public:
+ drawRawImage(unsigned char *raw, size_t width, size_t height,
+ const transform& t, bool antialias, const string& key="")
+ : drawImage(t,antialias,key), raw(raw), width(width), height(height) {}
+
+ virtual ~drawRawImage() {}
+
+ bool draw(psfile *out) {
+ out->gsave();
+ out->concat(t);
+ out->rawimage(raw,width,height,antialias);
+ out->grestore();
+ return true;
+ }
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/drawlabel.cc b/graphics/asymptote/drawlabel.cc
new file mode 100644
index 0000000000..7f749989c4
--- /dev/null
+++ b/graphics/asymptote/drawlabel.cc
@@ -0,0 +1,271 @@
+/*****
+ * drawlabel.cc
+ * John Bowman 2003/04/07
+ *
+ * Add a label to a picture.
+ *****/
+
+#include <sstream>
+
+#include "drawlabel.h"
+#include "settings.h"
+#include "util.h"
+#include "lexical.h"
+
+using namespace settings;
+
+namespace camp {
+
+string texready=string("(Please type a command or say `\\end')\n*");
+
+void drawLabel::labelwarning(const char *action)
+{
+ cerr << "warning: label \"" << label
+ << "\" " << action << " to avoid overwriting" << endl;
+}
+
+// Reads one of the dimensions from the pipe.
+void texdim(iopipestream& tex, double& dest, const string command,
+ const string name)
+{
+ string start(">dim(");
+ string stop(")dim");
+ string expect("pt"+stop+"\n\n*");
+
+ // ask the tex engine for dimension
+ tex << "\\immediate\\write16{" << start << "\\the\\" << command << "\\ASYbox"
+ << stop << "}\n";
+ // keep reading output until ')dim\n\n*' is read
+ tex.wait(expect.c_str());
+ string buffer = tex.getbuffer();
+
+ size_t dim1=buffer.find(start);
+ size_t dim2=buffer.find("pt" + stop);
+ string cannotread="Cannot read label "+name;
+ if (dim1 != string::npos && dim2 != string::npos) {
+ string n=buffer.substr(dim1+start.size(),dim2-dim1-start.size());
+ try {
+ dest=lexical::cast<double>(n,true)*tex2ps;
+ } catch(lexical::bad_cast&) {
+ camp::reportError(cannotread);
+ }
+ } else {
+ camp::reportError(cannotread);
+ }
+}
+
+void texbounds(double& width, double& height, double& depth,
+ iopipestream& tex, string& s)
+{
+ tex << "\\setbox\\ASYbox=\\hbox{" << stripblanklines(s) << "}\n\n";
+ tex.wait(texready.c_str());
+ texdim(tex,width,"wd","width");
+ texdim(tex,height,"ht","height");
+ texdim(tex,depth,"dp","depth");
+}
+
+inline double urand()
+{
+ static const double factor=2.0/RANDOM_MAX;
+ return random()*factor-1.0;
+}
+
+void setpen(iopipestream& tex, const string& texengine, const pen& pentype)
+{
+ bool Latex=latex(texengine);
+
+ if(Latex && setlatexfont(tex,pentype,drawElement::lastpen)) {
+ tex << "\n";
+ tex.wait(texready.c_str());
+ }
+ if(settexfont(tex,pentype,drawElement::lastpen,Latex)) {
+ tex << "\n";
+ tex.wait(texready.c_str());
+ }
+
+ drawElement::lastpen=pentype;
+}
+
+void drawLabel::getbounds(iopipestream& tex, const string& texengine)
+{
+ if(havebounds) return;
+ havebounds=true;
+
+ setpen(tex,texengine,pentype);
+ texbounds(width,height,depth,tex,label);
+
+ if(width == 0.0 && height == 0.0 && depth == 0.0 && !size.empty())
+ texbounds(width,height,depth,tex,size);
+
+ enabled=true;
+
+ Align=inverse(T)*align;
+ double scale0=max(fabs(Align.getx()),fabs(Align.gety()));
+ if(scale0) Align *= 0.5/scale0;
+ Align -= pair(0.5,0.5);
+ double Depth=(pentype.Baseline() == NOBASEALIGN) ? depth :
+ -depth*Align.gety();
+ texAlign=Align;
+ const double vertical=height+depth;
+ if(Depth > 0) texAlign += pair(0.0,Depth/vertical);
+ Align.scale(width,vertical);
+ Align += pair(0.0,Depth-depth);
+ Align=T*Align;
+}
+
+void drawLabel::bounds(bbox& b, iopipestream& tex, boxvector& labelbounds,
+ bboxlist&)
+{
+ string texengine=getSetting<string>("tex");
+ if(texengine == "none") {b += position; return;}
+
+ getbounds(tex,texengine);
+
+ // alignment point
+ pair p=position+Align;
+ const double vertical=height+depth;
+ const double fuzz=pentype.size()*0.1+0.3;
+ pair A=p+T*pair(-fuzz,-fuzz);
+ pair B=p+T*pair(-fuzz,vertical+fuzz);
+ pair C=p+T*pair(width+fuzz,vertical+fuzz);
+ pair D=p+T*pair(width+fuzz,-fuzz);
+
+ if(pentype.Overwrite() != ALLOW && label != "") {
+ size_t n=labelbounds.size();
+ box Box=box(A,B,C,D);
+ for(size_t i=0; i < n; i++) {
+ if(labelbounds[i].intersect(Box)) {
+ switch(pentype.Overwrite()) {
+ case SUPPRESS:
+ labelwarning("suppressed");
+ case SUPPRESSQUIET:
+ suppress=true;
+ return;
+ case MOVE:
+ labelwarning("moved");
+ default:
+ break;
+ }
+
+ pair Align=(align == pair(0,0)) ? unit(pair(urand(),urand())) :
+ unit(align);
+ double s=0.1*pentype.size();
+ double dx=0, dy=0;
+ if(Align.getx() > 0.1) dx=labelbounds[i].xmax()-Box.xmin()+s;
+ if(Align.getx() < -0.1) dx=labelbounds[i].xmin()-Box.xmax()-s;
+ if(Align.gety() > 0.1) dy=labelbounds[i].ymax()-Box.ymin()+s;
+ if(Align.gety() < -0.1) dy=labelbounds[i].ymin()-Box.ymax()-s;
+ pair offset=pair(dx,dy);
+ position += offset;
+ A += offset;
+ B += offset;
+ C += offset;
+ D += offset;
+ Box=box(A,B,C,D);
+ i=0;
+ }
+ }
+ labelbounds.resize(n+1);
+ labelbounds[n]=Box;
+ }
+
+ Box=bbox();
+ Box += A;
+ Box += B;
+ Box += C;
+ Box += D;
+
+ b += Box;
+}
+
+void drawLabel::checkbounds()
+{
+ if(!havebounds)
+ reportError("drawLabel::write called before bounds");
+}
+
+bool drawLabel::write(texfile *out, const bbox&)
+{
+ checkbounds();
+ if(suppress || pentype.invisible() || !enabled) return true;
+ out->setpen(pentype);
+ out->put(label,T,position,texAlign);
+ return true;
+}
+
+drawElement *drawLabel::transformed(const transform& t)
+{
+ return new drawLabel(label,size,t*T,t*position,
+ length(align)*unit(shiftless(t)*align),pentype,KEY);
+}
+
+void drawLabelPath::bounds(bbox& b, iopipestream& tex, boxvector&, bboxlist&)
+{
+ string texengine=getSetting<string>("tex");
+ if(texengine == "none") {b += position; return;}
+
+ getbounds(tex,texengine);
+ double L=p.arclength();
+
+ double s1,s2;
+ if(justify == "l") {
+ s1=0.0;
+ s2=width;
+ } else if(justify == "r") {
+ s1=L-width;
+ s2=L;
+ } else {
+ double s=0.5*L;
+ double h=0.5*width;
+ s1=s-h;
+ s2=s+h;
+ }
+
+ double Sx=shift.getx();
+ double Sy=shift.gety();
+ s1 += Sx;
+ s2 += Sx;
+
+ if(width > L || (!p.cyclic() && (s1 < 0 || s2 > L))) {
+ ostringstream buf;
+ buf << "Cannot fit label \"" << label << "\" to path";
+ reportError(buf);
+ }
+
+ path q=p.subpath(p.arctime(s1),p.arctime(s2));
+
+ b += q.bounds(Sy,Sy+height);
+ Box=b;
+}
+
+bool drawLabelPath::write(texfile *out, const bbox&)
+{
+ bbox b=Box;
+ double Hoffset=getSetting<bool>("inlinetex") ? b.right : b.left;
+ b.shift(pair(-Hoffset,-b.bottom));
+
+ checkbounds();
+ if(drawLabel::pentype.invisible()) return true;
+ out->setpen(drawLabel::pentype);
+ out->verbatimline("\\psset{unit=1pt}%");
+ out->verbatim("\\pstextpath[");
+ out->verbatim(justify);
+ out->verbatim("]");
+ out->writepair(shift);
+ out->verbatim("{\\pstVerb{");
+ out->beginraw();
+ writeshiftedpath(out);
+ out->endraw();
+ out->verbatim("}}{");
+ out->verbatim(label);
+ out->verbatimline("}");
+ return true;
+}
+
+drawElement *drawLabelPath::transformed(const transform& t)
+{
+ return new drawLabelPath(label,size,transpath(t),justify,shift,
+ transpen(t),KEY);
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/drawlabel.h b/graphics/asymptote/drawlabel.h
new file mode 100644
index 0000000000..c16209bc51
--- /dev/null
+++ b/graphics/asymptote/drawlabel.h
@@ -0,0 +1,90 @@
+/*****
+ * drawlabel.h
+ * John Bowman 2003/03/14
+ *
+ * Add a label to a picture.
+ *****/
+
+#ifndef DRAWLABEL_H
+#define DRAWLABEL_H
+
+#include "drawelement.h"
+#include "path.h"
+#include "angle.h"
+#include "transform.h"
+
+namespace camp {
+
+class drawLabel : public virtual drawElement {
+protected:
+ string label,size;
+ transform T; // A linear (shiftless) transformation.
+ pair position;
+ pair align;
+ pair scale;
+ pen pentype;
+ double width,height,depth;
+ bool havebounds;
+ bool suppress;
+ pair Align;
+ pair texAlign;
+ bbox Box;
+ bool enabled;
+
+public:
+ drawLabel(string label, string size, transform T, pair position,
+ pair align, pen pentype, const string& key="")
+ : drawElement(key), label(label), size(size), T(shiftless(T)),
+ position(position), align(align), pentype(pentype), width(0.0),
+ height(0.0), depth(0.0), havebounds(false), suppress(false),
+ enabled(false) {}
+
+ virtual ~drawLabel() {}
+
+ void getbounds(iopipestream& tex, const string& texengine);
+
+ void checkbounds();
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&);
+
+ bool islabel() {
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&);
+
+ drawElement *transformed(const transform& t);
+
+ void labelwarning(const char *action);
+};
+
+class drawLabelPath : public drawLabel, public drawPathPenBase {
+private:
+ string justify;
+ pair shift;
+public:
+ drawLabelPath(string label, string size, path src,
+ string justify, pair shift, pen pentype,
+ const string& key="") :
+ drawLabel(label,size,identity,pair(0.0,0.0),pair(0.0,0.0),pentype,key),
+ drawPathPenBase(src,pentype), justify(justify), shift(shift) {}
+
+ virtual ~drawLabelPath() {}
+
+ bool svg() {return true;}
+ bool svgpng() {return true;}
+
+ void bounds(bbox& b, iopipestream& tex, boxvector&, bboxlist&);
+
+ bool write(texfile *out, const bbox&);
+
+ drawElement *transformed(const transform& t);
+};
+
+void setpen(iopipestream& tex, const string& texengine, const pen& pentype);
+void texbounds(double& width, double& height, double& depth,
+ iopipestream& tex, string& s);
+
+}
+
+#endif
diff --git a/graphics/asymptote/drawlayer.h b/graphics/asymptote/drawlayer.h
new file mode 100644
index 0000000000..1f4500dac2
--- /dev/null
+++ b/graphics/asymptote/drawlayer.h
@@ -0,0 +1,45 @@
+/*****
+ * drawlayer.h
+ * John Bowman
+ *
+ * Start a new postscript/TeX layer in picture.
+ *****/
+
+#ifndef DRAWLAYER_H
+#define DRAWLAYER_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawLayer : public drawElement {
+public:
+ drawLayer() {}
+
+ virtual ~drawLayer() {}
+
+ bool islayer() {return true;}
+};
+
+class drawNewPage : public drawLayer {
+public:
+ drawNewPage() {}
+
+ virtual ~drawNewPage() {}
+
+ bool islabel() {return true;}
+ bool isnewpage() {return true;}
+
+ bool write(texfile *out, const bbox&) {
+ out->verbatimline(settings::latex(out->texengine) ? "\\newpage" :
+ settings::context(out->texengine) ? "}\\page\\hbox{%" :
+ "\\eject");
+ return true;
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawLayer);
+
+#endif
diff --git a/graphics/asymptote/drawpath.cc b/graphics/asymptote/drawpath.cc
new file mode 100644
index 0000000000..bb6dc393bd
--- /dev/null
+++ b/graphics/asymptote/drawpath.cc
@@ -0,0 +1,165 @@
+/*****
+ * drawpath.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a path that has been added to a picture.
+ *****/
+
+#include <sstream>
+#include <vector>
+#include <cfloat>
+
+#include "drawpath.h"
+#include "psfile.h"
+#include "util.h"
+
+using vm::array;
+using vm::read;
+
+namespace camp {
+
+double PatternLength(double arclength, const array& pat,
+ bool cyclic, double penwidth)
+{
+ double sum=0.0;
+
+ size_t n=pat.size();
+ for(unsigned i=0; i < n; i ++)
+ sum += read<double>(pat,i)*penwidth;
+
+ if(sum == 0.0) return 0.0;
+
+ if(n % 2 == 1) sum *= 2.0; // On/off pattern repeats after 2 cycles.
+
+ double pat0=read<double>(pat,0);
+ // Fix bounding box resolution problem. Example:
+ // asy -f pdf testlinetype; gv -scale -2 testlinetype.pdf
+ if(!cyclic && pat0 == 0) sum += 1.0e-3*penwidth;
+
+ double terminator=(cyclic && arclength >= 0.5*sum) ? 0.0 : pat0*penwidth;
+ int ncycle=(int)((arclength-terminator)/sum+0.5);
+
+ return (ncycle >= 1 || terminator >= 0.75*arclength) ?
+ ncycle*sum+terminator : 0.0;
+}
+
+bool isdashed(pen& p) {
+ const LineType *linetype=p.linetype();
+ size_t n=linetype->pattern.size();
+ return n > 0;
+}
+
+pen adjustdash(pen& p, double arclength, bool cyclic)
+{
+ pen q=p;
+ // Adjust dash sizes to fit arclength; also compensate for linewidth.
+ const LineType *linetype=q.linetype();
+ size_t n=linetype->pattern.size();
+
+ if(n > 0) {
+ double penwidth=linetype->scale ? q.width() : 1.0;
+ double factor=penwidth;
+
+ if(linetype->adjust && arclength) {
+ double denom=PatternLength(arclength,linetype->pattern,cyclic,penwidth);
+ if(denom != 0.0) factor *= arclength/denom;
+ }
+
+ if(factor != 1.0)
+ q.adjust(max(factor,0.1));
+ }
+ return q;
+}
+
+// Account for square or extended pen cap contributions to bounding box.
+void cap(bbox& b, double t, path p, pen pentype) {
+ transform T=pentype.getTransform();
+
+ double h=0.5*pentype.width();
+ pair v=p.dir(t);
+ transform S=rotate(conj(v))*shiftless(T);
+ double xx=S.getxx(), xy=S.getxy();
+ double yx=S.getyx(), yy=S.getyy();
+ double y=hypot(yx,yy);
+ if(y == 0) return;
+ double numer=xx*yx+xy*yy;
+ double x=numer/y;
+ pair z=shift(T)*p.point(t);
+
+ switch(pentype.cap()) {
+ case 0:
+ {
+ pair d=rotate(v)*pair(x,y)*h;
+ b += z+d;
+ b += z-d;
+ break;
+ }
+ case 2:
+ {
+ transform R=rotate(v);
+ double w=(xx*yy-xy*yx)/y;
+ pair dp=R*pair(x+w,y)*h;
+ pair dm=R*pair(x-w,y)*h;
+ b += z+dp;
+ b += z+dm;
+ b += z-dp;
+ b += z-dm;
+ break;
+ }
+ }
+}
+
+void drawPathPenBase::strokebounds(bbox& b, const path& p)
+{
+ Int l=p.length();
+ if(l < 0) return;
+
+ bbox penbounds=pentype.bounds();
+
+ if(cyclic() || pentype.cap() == 1) {
+ b += pad(p.bounds(),penbounds);
+ return;
+ }
+
+ b += p.internalbounds(penbounds);
+
+ cap(b,0,p,pentype);
+ cap(b,l,p,pentype);
+}
+
+bool drawPath::draw(psfile *out)
+{
+ Int n = p.size();
+ if (n == 0 || pentype.invisible())
+ return true;
+
+ pen q=isdashed(pentype) ?
+ adjustdash(pentype,
+ p.transformed(inverse(pentype.getTransform())).arclength(),
+ p.cyclic()) : pentype;
+
+ penSave(out);
+ penTranslate(out);
+
+ if(n > 1)
+ out->write(p);
+ else
+ out->dot(p,q);
+
+ penConcat(out);
+
+ out->setpen(q);
+
+ out->stroke(q,n == 1);
+
+ penRestore(out);
+
+ return true;
+}
+
+drawElement *drawPath::transformed(const transform& t)
+{
+ return new drawPath(transpath(t),transpen(t),KEY);
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/drawpath.h b/graphics/asymptote/drawpath.h
new file mode 100644
index 0000000000..93ec38eb69
--- /dev/null
+++ b/graphics/asymptote/drawpath.h
@@ -0,0 +1,37 @@
+/*****
+ * drawpath.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a path that has been added to a picture.
+ *****/
+
+#ifndef DRAWPATH_H
+#define DRAWPATH_H
+
+#include "drawelement.h"
+#include "path.h"
+
+namespace camp {
+
+class drawPath : public drawPathPenBase {
+public:
+ drawPath(path src, pen pentype, const string& key="") :
+ drawElement(key), drawPathPenBase(src,pentype) {}
+
+ virtual ~drawPath() {}
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ strokebounds(b,p);
+ }
+
+ bool svg() {return true;}
+
+ bool draw(psfile *out);
+
+ drawElement *transformed(const transform& t);
+};
+
+pen adjustdash(pen& p, double arclength, bool cyclic);
+}
+
+#endif
diff --git a/graphics/asymptote/drawpath3.cc b/graphics/asymptote/drawpath3.cc
new file mode 100644
index 0000000000..55752509ff
--- /dev/null
+++ b/graphics/asymptote/drawpath3.cc
@@ -0,0 +1,289 @@
+/*****
+ * drawpath3.cc
+ *
+ * Stores a path3 that has been added to a picture.
+ *****/
+
+#include "drawpath3.h"
+#include "drawsurface.h"
+#include "material.h"
+
+#ifdef HAVE_GL
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#endif
+
+namespace camp {
+
+using vm::array;
+using namespace prc;
+
+#ifdef HAVE_GL
+using gl::modelView;
+
+BezierCurve drawPath3::R;
+Pixel drawPixel::R;
+#endif
+
+bool drawPath3::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ Int n=g.length();
+ if(n == 0 || invisible)
+ return true;
+
+ if(straight) {
+ triple *controls=new(UseGC) triple[n+1];
+ for(Int i=0; i <= n; ++i)
+ controls[i]=g.point(i);
+
+ out->addLine(n+1,controls,color);
+ } else {
+ int m=3*n+1;
+ triple *controls=new(UseGC) triple[m];
+ controls[0]=g.point((Int) 0);
+ controls[1]=g.postcontrol((Int) 0);
+ size_t k=1;
+ for(Int i=1; i < n; ++i) {
+ controls[++k]=g.precontrol(i);
+ controls[++k]=g.point(i);
+ controls[++k]=g.postcontrol(i);
+ }
+ controls[++k]=g.precontrol(n);
+ controls[++k]=g.point(n);
+ out->addBezierCurve(m,controls,color);
+ }
+
+ return true;
+}
+
+void drawPath3::render(double size2, const triple& b, const triple& B,
+ double perspective, bool transparent)
+{
+#ifdef HAVE_GL
+ Int n=g.length();
+ if(n == 0 || invisible || ((color.A < 1.0) ^ transparent))
+ return;
+
+ const bool billboard=interaction == BILLBOARD &&
+ !settings::getSetting<bool>("offscreen");
+ triple m,M;
+
+ double f,F,s;
+ if(perspective) {
+ f=Min.getz()*perspective;
+ F=Max.getz()*perspective;
+ m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
+ M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
+ s=max(f,F);
+ } else {
+ m=b;
+ M=B;
+ s=1.0;
+ }
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+
+ bbox3 box(m,M);
+ box.transform(modelView.Tinv);
+ m=box.Min();
+ M=box.Max();
+
+ if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() ||
+ Max.gety() < m.gety() || Min.gety() > M.gety() ||
+ Max.getz() < m.getz() || Min.getz() > M.getz()))
+ return;
+
+ RGBAColour Black(0.0,0.0,0.0,color.A);
+ setcolors(false,Black,color,Black,1.0,0.0,0.04);
+
+ if(billboard) {
+ for(Int i=0; i < n; ++i) {
+ triple controls[]={BB.transform(g.point(i)),BB.transform(g.postcontrol(i)),
+ BB.transform(g.precontrol(i+1)),
+ BB.transform(g.point(i+1))};
+ R.queue(controls,straight,size3.length()/size2,m,M);
+ }
+ } else {
+ BB.init(center);
+ for(Int i=0; i < n; ++i) {
+ triple controls[]={g.point(i),g.postcontrol(i),g.precontrol(i+1),
+ g.point(i+1)};
+ R.queue(controls,straight,size3.length()/size2,m,M);
+ }
+ }
+ if(BezierCurve::vertexbuffer.size() >= (unsigned) gl::maxvertices) {
+ R.draw();
+ BezierCurve::clear();
+ gl::forceRemesh=true;
+ }
+#endif
+}
+
+drawElement *drawPath3::transformed(const double* t)
+{
+ return new drawPath3(t,this);
+}
+
+bool drawNurbsPath3::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ out->addCurve(degree,n,controls,knots,color,weights);
+
+ return true;
+}
+
+// Approximate bounds by bounding box of control polyhedron.
+void drawNurbsPath3::bounds(const double* t, bbox3& b)
+{
+ double x,y,z;
+ double X,Y,Z;
+
+ triple* Controls;
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=new triple[n];
+ for(size_t i=0; i < n; i++)
+ Controls[i]=t*controls[i];
+ }
+
+ boundstriples(x,y,z,X,Y,Z,n,Controls);
+
+ b.add(x,y,z);
+ b.add(X,Y,Z);
+
+ if(t == NULL) {
+ Min=triple(x,y,z);
+ Max=triple(X,Y,Z);
+ } else delete[] Controls;
+}
+
+drawElement *drawNurbsPath3::transformed(const double* t)
+{
+ return new drawNurbsPath3(t,this);
+}
+
+void drawNurbsPath3::ratio(const double* t, pair &b, double (*m)(double, double),
+ double, bool &first)
+{
+ triple* Controls;
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=new triple[n];
+ for(size_t i=0; i < n; i++)
+ Controls[i]=t*controls[i];
+ }
+
+ if(first) {
+ first=false;
+ triple v=Controls[0];
+ b=pair(xratio(v),yratio(v));
+ }
+
+ double x=b.getx();
+ double y=b.gety();
+ for(size_t i=0; i < n; ++i) {
+ triple v=Controls[i];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ }
+ b=pair(x,y);
+
+ if(t != NULL)
+ delete[] Controls;
+}
+
+void drawNurbsPath3::displacement()
+{
+#ifdef HAVE_GL
+ size_t nknots=degree+n+1;
+ if(Controls == NULL) {
+ Controls=new(UseGC) GLfloat[(weights ? 4 : 3)*n];
+ Knots=new(UseGC) GLfloat[nknots];
+ }
+ if(weights)
+ for(size_t i=0; i < n; ++i)
+ store(Controls+4*i,controls[i],weights[i]);
+ else
+ for(size_t i=0; i < n; ++i)
+ store(Controls+3*i,controls[i]);
+
+ for(size_t i=0; i < nknots; ++i)
+ Knots[i]=knots[i];
+#endif
+}
+
+void drawNurbsPath3::render(double, const triple&, const triple&,
+ double, bool transparent)
+{
+#ifdef HAVE_GL
+ if(invisible || ((color.A < 1.0) ^ transparent))
+ return;
+
+// TODO: implement NURBS renderer
+#endif
+}
+
+bool drawPixel::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ out->addPoint(v,color,width);
+
+ return true;
+}
+
+void drawPixel::render(double size2, const triple& b, const triple& B,
+ double perspective, bool transparent)
+{
+#ifdef HAVE_GL
+ if(invisible || ((color.A < 1.0) ^ transparent)) return;
+ triple m,M;
+
+ double f,F,s;
+ if(perspective) {
+ f=Min.getz()*perspective;
+ F=Max.getz()*perspective;
+ m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
+ M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
+ s=max(f,F);
+ } else {
+ m=b;
+ M=B;
+ s=1.0;
+ }
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+
+ bbox3 box(m,M);
+ box.transform(modelView.Tinv);
+ m=box.Min();
+ M=box.Max();
+
+ if((Max.getx() < m.getx() || Min.getx() > M.getx() ||
+ Max.gety() < m.gety() || Min.gety() > M.gety() ||
+ Max.getz() < m.getz() || Min.getz() > M.getz()))
+ return;
+
+ RGBAColour Black(0.0,0.0,0.0,color.A);
+ setcolors(false,color,color,Black,1.0,0.0,0.04);
+
+ R.queue(v,width);
+
+ if(Pixel::vertexbuffer.size() >= (unsigned) gl::maxvertices) {
+ R.draw();
+ Pixel::clear();
+ gl::forceRemesh=true;
+ }
+#endif
+}
+
+drawElement *drawPixel::transformed(const double* t)
+{
+ return new drawPixel(t*v,p,width,KEY);
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/drawpath3.h b/graphics/asymptote/drawpath3.h
new file mode 100644
index 0000000000..c6515057c9
--- /dev/null
+++ b/graphics/asymptote/drawpath3.h
@@ -0,0 +1,206 @@
+/*****
+ * drawpath3.h
+ *
+ * Stores a path3 that has been added to a picture.
+ *****/
+
+#ifndef DRAWPATH3_H
+#define DRAWPATH3_H
+
+#include "drawelement.h"
+#include "path3.h"
+#include "beziercurve.h"
+
+namespace camp {
+
+class drawPath3 : public drawElement {
+protected:
+ const path3 g;
+ triple center;
+ bool straight;
+ prc::RGBAColour color;
+ bool invisible;
+ Interaction interaction;
+ triple Min,Max;
+public:
+#ifdef HAVE_GL
+ static BezierCurve R;
+#endif
+ drawPath3(path3 g, triple center, const pen& p, Interaction interaction,
+ const string& key="") :
+ drawElement(key), g(g), center(center), straight(g.piecewisestraight()),
+ color(rgba(p)), invisible(p.invisible()), interaction(interaction),
+ Min(g.min()), Max(g.max()) {}
+
+ drawPath3(const double* t, const drawPath3 *s) :
+ drawElement(s->KEY), g(camp::transformed(t,s->g)), straight(s->straight),
+ color(s->color), invisible(s->invisible), interaction(s->interaction),
+ Min(g.min()), Max(g.max()) {
+ center=t*s->center;
+ }
+
+ virtual ~drawPath3() {}
+
+ bool is3D() {return true;}
+
+ void bounds(const double* t, bbox3& B) {
+ if(t != NULL) {
+ const path3 tg(camp::transformed(t,g));
+ B.add(tg.min());
+ B.add(tg.max());
+ } else {
+ B.add(Min);
+ B.add(Max);
+ }
+ }
+
+ void ratio(const double* t, pair &b, double (*m)(double, double), double,
+ bool &first) {
+ pair z;
+ if(t != NULL) {
+ const path3 tg(camp::transformed(t,g));
+ z=tg.ratio(m);
+ } else z=g.ratio(m);
+
+ if(first) {
+ b=z;
+ first=false;
+ } else b=pair(m(b.getx(),z.getx()),m(b.gety(),z.gety()));
+ }
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ void render(double, const triple&, const triple&, double,
+ bool transparent);
+
+ drawElement *transformed(const double* t);
+};
+
+class drawNurbsPath3 : public drawElement {
+protected:
+ size_t degree;
+ size_t n;
+ triple *controls;
+ double *weights;
+ double *knots;
+ prc::RGBAColour color;
+ bool invisible;
+ triple Min,Max;
+
+#ifdef HAVE_GL
+ GLfloat *Controls;
+ GLfloat *Knots;
+#endif
+
+public:
+ drawNurbsPath3(const vm::array& g, const vm::array* knot,
+ const vm::array* weight, const pen& p, const string& key="") :
+ drawElement(key), color(rgba(p)), invisible(p.invisible()) {
+ size_t weightsize=checkArray(weight);
+
+ string wrongsize="Inconsistent NURBS data";
+ n=checkArray(&g);
+
+ if(n == 0 || (weightsize != 0 && weightsize != n))
+ reportError(wrongsize);
+
+ controls=new(UseGC) triple[n];
+
+ size_t k=0;
+ for(size_t i=0; i < n; ++i)
+ controls[k++]=vm::read<triple>(g,i);
+
+ if(weightsize > 0) {
+ size_t k=0;
+ weights=new(UseGC) double[n];
+ for(size_t i=0; i < n; ++i)
+ weights[k++]=vm::read<double>(weight,i);
+ } else weights=NULL;
+
+ size_t nknots=checkArray(knot);
+
+ if(nknots <= n+1 || nknots > 2*n)
+ reportError(wrongsize);
+
+ degree=nknots-n-1;
+
+ run::copyArrayC(knots,knot,0,NoGC);
+
+#ifdef HAVE_GL
+ Controls=NULL;
+#endif
+ }
+
+ drawNurbsPath3(const double* t, const drawNurbsPath3 *s) :
+ drawElement(s->KEY), degree(s->degree), n(s->n), weights(s->weights),
+ knots(s->knots), color(s->color), invisible(s->invisible) {
+ controls=new(UseGC) triple[n];
+ for(unsigned int i=0; i < n; ++i)
+ controls[i]=t*s->controls[i];
+
+#ifdef HAVE_GL
+ Controls=NULL;
+#endif
+ }
+
+ bool is3D() {return true;}
+
+ void bounds(const double* t, bbox3& b);
+
+ virtual ~drawNurbsPath3() {}
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ void displacement();
+ void ratio(const double* t, pair &b, double (*m)(double, double), double fuzz,
+ bool &first);
+
+ void render(double size2, const triple& Min, const triple& Max,
+ double perspective, bool transparent);
+
+ drawElement *transformed(const double* t);
+};
+
+// Draw a pixel.
+class drawPixel : public drawElement {
+ triple v;
+ pen p;
+ prc::RGBAColour color;
+ double width;
+ bool invisible;
+ triple Min,Max;
+public:
+#ifdef HAVE_GL
+ static Pixel R;
+#endif
+ drawPixel(const triple& v, const pen& p, double width, const string& key="")
+ : drawElement(key), v(v), p(p), color(rgba(p)), width(width),
+ invisible(p.invisible()) {}
+
+ void bounds(const double* t, bbox3& B) {
+ Min=Max=(t != NULL) ? t*v : v;
+ B.add(Min);
+ }
+
+ void ratio(const double* t, pair &b, double (*m)(double, double), double,
+ bool &first) {
+ triple V=(t != NULL) ? t*v : v;
+ pair z=pair(xratio(V),yratio(V));
+
+ if(first) {
+ b=z;
+ first=false;
+ } else b=pair(m(b.getx(),z.getx()),m(b.gety(),z.gety()));
+ }
+
+ void render(double size2, const triple& b, const triple& B,
+ double perspective, bool transparent);
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ drawElement *transformed(const double* t);
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/drawsurface.cc b/graphics/asymptote/drawsurface.cc
new file mode 100644
index 0000000000..80f7581ee3
--- /dev/null
+++ b/graphics/asymptote/drawsurface.cc
@@ -0,0 +1,953 @@
+/*****
+ * drawsurface.cc
+ *
+ * Stores a surface that has been added to a picture.
+ *****/
+
+#include "drawsurface.h"
+#include "drawpath3.h"
+#include "arrayop.h"
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+#ifdef HAVE_GL
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#endif
+
+using namespace prc;
+#include "material.h"
+namespace camp {
+
+#ifdef HAVE_GL
+mem::vector<Material> drawElement::material;
+MaterialMap drawElement::materialMap;
+size_t drawElement::materialIndex;
+
+using gl::modelView;
+//double* Tx=modelView.T; // x-component of current transform
+//double* Ty=modelView.T+4; // y-component of current transform
+double* Tz=modelView.T+8; // z-component of current transform
+
+#endif
+
+const triple drawElement::zero;
+
+using vm::array;
+
+#ifdef HAVE_GL
+BezierCurve drawSurface::C;
+BezierPatch drawBezierPatch::S;
+BezierTriangle drawBezierTriangle::S;
+
+void storecolor(GLfloat *colors, int i, const vm::array &pens, int j)
+{
+ pen p=vm::read<camp::pen>(pens,j);
+ p.torgb();
+ colors[i]=p.red();
+ colors[i+1]=p.green();
+ colors[i+2]=p.blue();
+ colors[i+3]=p.opacity();
+}
+
+void storecolor(GLfloat *colors, int i, const RGBAColour& p)
+{
+ colors[i]=p.R;
+ colors[i+1]=p.G;
+ colors[i+2]=p.B;
+ colors[i+3]=p.A;
+}
+
+void clearMaterialBuffer(bool draw)
+{
+ if(draw) {
+ drawBezierPatch::S.draw();
+ drawPath3::R.draw();
+ drawPixel::R.draw();
+ }
+ drawElement::material.clear();
+ drawElement::material.reserve(nmaterials);
+ drawElement::materialMap.clear();
+ drawElement::materialIndex=0;
+}
+
+void setcolors(bool colors,
+ const RGBAColour& diffuse,
+ const RGBAColour& emissive,
+ const RGBAColour& specular, double shininess,
+ double metallic, double fresnel0)
+{
+ Material m;
+ if(colors) {
+ static glm::vec4 Black(0.0,0.0,0.0,diffuse.A);
+ m=Material(Black,Black,
+ glm::vec4(specular.R,specular.G,specular.B,specular.A),
+ shininess, metallic, fresnel0);
+ } else
+ m=Material(glm::vec4(diffuse.R,diffuse.G,diffuse.B,diffuse.A),
+ glm::vec4(emissive.R,emissive.G,emissive.B,emissive.A),
+ glm::vec4(specular.R,specular.G,specular.B,specular.A),
+ shininess, metallic, fresnel0);
+
+ MaterialMap::iterator p=drawElement::materialMap.find(m);
+ if(p != drawElement::materialMap.end())
+ drawElement::materialIndex=p->second;
+ else {
+ drawElement::materialIndex=drawElement::material.size();
+ if(drawElement::materialIndex >= nmaterials)
+ nmaterials=min(Maxmaterials,2*nmaterials);
+ if(drawElement::materialIndex >= Maxmaterials)
+ clearMaterialBuffer(true);
+ drawElement::material.push_back(m);
+ drawElement::materialMap[m]=drawElement::materialIndex;
+ }
+}
+
+#endif
+
+void drawBezierPatch::bounds(const double* t, bbox3& b)
+{
+ double x,y,z;
+ double X,Y,Z;
+
+ if(straight) {
+ triple Vertices[4];
+ if(t == NULL) {
+ Vertices[0]=controls[0];
+ Vertices[1]=controls[3];
+ Vertices[2]=controls[12];
+ Vertices[3]=controls[15];
+ } else {
+ Vertices[0]=t*controls[0];
+ Vertices[1]=t*controls[3];
+ Vertices[2]=t*controls[12];
+ Vertices[3]=t*controls[15];
+ }
+
+ boundstriples(x,y,z,X,Y,Z,4,Vertices);
+ } else {
+ double cx[16];
+ double cy[16];
+ double cz[16];
+
+ if(t == NULL) {
+ for(int i=0; i < 16; ++i) {
+ triple v=controls[i];
+ cx[i]=v.getx();
+ cy[i]=v.gety();
+ cz[i]=v.getz();
+ }
+ } else {
+ for(int i=0; i < 16; ++i) {
+ triple v=t*controls[i];
+ cx[i]=v.getx();
+ cy[i]=v.gety();
+ cz[i]=v.getz();
+ }
+ }
+
+ double c0=cx[0];
+ double fuzz=Fuzz*run::norm(cx,16);
+ x=bound(cx,min,b.empty ? c0 : min(c0,b.left),fuzz,maxdepth);
+ X=bound(cx,max,b.empty ? c0 : max(c0,b.right),fuzz,maxdepth);
+
+ c0=cy[0];
+ fuzz=Fuzz*run::norm(cy,16);
+ y=bound(cy,min,b.empty ? c0 : min(c0,b.bottom),fuzz,maxdepth);
+ Y=boundtri(cy,max,b.empty ? c0 : max(c0,b.top),fuzz,maxdepth);
+
+ c0=cz[0];
+ fuzz=Fuzz*run::norm(cz,16);
+ z=bound(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth);
+ Z=bound(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth);
+ }
+
+ b.add(x,y,z);
+ b.add(X,Y,Z);
+
+ if(t == NULL) {
+ Min=triple(x,y,z);
+ Max=triple(X,Y,Z);
+ }
+}
+
+void drawBezierPatch::ratio(const double* t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first)
+{
+ triple buf[16];
+ triple* Controls;
+ if(straight) {
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=buf;
+ Controls[0]=t*controls[0];
+ Controls[3]=t*controls[3];
+ Controls[12]=t*controls[12];
+ Controls[15]=t*controls[15];
+ }
+
+ triple v=Controls[0];
+ double x=xratio(v);
+ double y=yratio(v);
+ if(first) {
+ first=false;
+ b=pair(x,y);
+ } else {
+ x=m(b.getx(),x);
+ y=m(b.gety(),y);
+ }
+ v=Controls[3];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ v=Controls[12];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ v=Controls[15];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ b=pair(x,y);
+ } else {
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=buf;
+ for(unsigned int i=0; i < 16; ++i)
+ Controls[i]=t*controls[i];
+ }
+
+ if(first) {
+ triple v=Controls[0];
+ b=pair(xratio(v),yratio(v));
+ first=false;
+ }
+
+ b=pair(bound(Controls,m,xratio,b.getx(),fuzz,maxdepth),
+ bound(Controls,m,yratio,b.gety(),fuzz,maxdepth));
+ }
+}
+
+bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible || !prc)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+
+ if(straight) {
+ triple vertices[]={controls[0],controls[12],controls[3],controls[15]};
+ if(colors)
+ out->addQuad(vertices,colors);
+ else
+ out->addRectangle(vertices,m);
+ } else
+ out->addPatch(controls,m);
+
+ return true;
+}
+
+void drawBezierPatch::render(double size2, const triple& b, const triple& B,
+ double perspective, bool transparent)
+{
+#ifdef HAVE_GL
+ if(invisible ||
+ ((colors ? colors[0].A+colors[1].A+colors[2].A+colors[3].A < 4.0 :
+ diffuse.A < 1.0) ^ transparent)) return;
+
+ const bool billboard=interaction == BILLBOARD &&
+ !settings::getSetting<bool>("offscreen");
+ triple m,M;
+
+ double f,F,s;
+ if(perspective) {
+ f=Min.getz()*perspective;
+ F=Max.getz()*perspective;
+ m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
+ M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
+ s=max(f,F);
+ } else {
+ m=b;
+ M=B;
+ s=1.0;
+ }
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+
+ bbox3 box(m,M);
+ box.transform(modelView.Tinv);
+ m=box.Min();
+ M=box.Max();
+
+ if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() ||
+ Max.gety() < m.gety() || Min.gety() > M.gety() ||
+ Max.getz() < m.getz() || Min.getz() > M.getz()))
+ return;
+
+ setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
+
+ if(billboard) BB.init(center);
+
+ GLfloat c[16];
+ if(colors)
+ for(size_t i=0; i < 4; ++i)
+ storecolor(c,4*i,colors[i]);
+
+ triple *Controls;
+ triple Controls0[16];
+ if(billboard) {
+ Controls=Controls0;
+ for(size_t i=0; i < 16; i++)
+ Controls[i]=BB.transform(controls[i]);
+ } else
+ Controls=controls;
+
+ if(gl::outlinemode) {
+ triple edge0[]={Controls[0],Controls[4],Controls[8],Controls[12]};
+ C.queue(edge0,straight,size3.length()/size2,m,M);
+ triple edge1[]={Controls[12],Controls[13],Controls[14],Controls[15]};
+ C.queue(edge1,straight,size3.length()/size2,m,M);
+ triple edge2[]={Controls[15],Controls[11],Controls[7],Controls[3]};
+ C.queue(edge2,straight,size3.length()/size2,m,M);
+ triple edge3[]={Controls[3],Controls[2],Controls[1],Controls[0]};
+ C.queue(edge3,straight,size3.length()/size2,m,M);
+ C.draw();
+ } else {
+ S.queue(Controls,straight,size3.length()/size2,m,M,transparent,
+ colors ? c : NULL);
+ if(BezierPatch::nvertices >= gl::maxvertices) {
+ S.drawMaterials();
+ BezierPatch::clear();
+ gl::forceRemesh=true;
+ }
+ if(BezierPatch::Nvertices >= gl::maxvertices) {
+ S.drawColors();
+ BezierPatch::Clear();
+ gl::forceRemesh=true;
+ }
+ }
+#endif
+}
+
+drawElement *drawBezierPatch::transformed(const double* t)
+{
+ return new drawBezierPatch(t,this);
+}
+
+void drawBezierTriangle::bounds(const double* t, bbox3& b)
+{
+ double x,y,z;
+ double X,Y,Z;
+
+ if(straight) {
+ triple Vertices[3];
+ if(t == NULL) {
+ Vertices[0]=controls[0];
+ Vertices[1]=controls[6];
+ Vertices[2]=controls[9];
+ } else {
+ Vertices[0]=t*controls[0];
+ Vertices[1]=t*controls[6];
+ Vertices[2]=t*controls[9];
+ }
+
+ boundstriples(x,y,z,X,Y,Z,3,Vertices);
+ } else {
+ double cx[10];
+ double cy[10];
+ double cz[10];
+
+ if(t == NULL) {
+ for(unsigned int i=0; i < 10; ++i) {
+ triple v=controls[i];
+ cx[i]=v.getx();
+ cy[i]=v.gety();
+ cz[i]=v.getz();
+ }
+ } else {
+ for(unsigned int i=0; i < 10; ++i) {
+ triple v=t*controls[i];
+ cx[i]=v.getx();
+ cy[i]=v.gety();
+ cz[i]=v.getz();
+ }
+ }
+
+ double c0=cx[0];
+ double fuzz=Fuzz*run::norm(cx,10);
+ x=boundtri(cx,min,b.empty ? c0 : min(c0,b.left),fuzz,maxdepth);
+ X=boundtri(cx,max,b.empty ? c0 : max(c0,b.right),fuzz,maxdepth);
+
+ c0=cy[0];
+ fuzz=Fuzz*run::norm(cy,10);
+ y=boundtri(cy,min,b.empty ? c0 : min(c0,b.bottom),fuzz,maxdepth);
+ Y=boundtri(cy,max,b.empty ? c0 : max(c0,b.top),fuzz,maxdepth);
+
+ c0=cz[0];
+ fuzz=Fuzz*run::norm(cz,10);
+ z=boundtri(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth);
+ Z=boundtri(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth);
+ }
+
+ b.add(x,y,z);
+ b.add(X,Y,Z);
+
+ if(t == NULL) {
+ Min=triple(x,y,z);
+ Max=triple(X,Y,Z);
+ }
+}
+
+void drawBezierTriangle::ratio(const double* t, pair &b,
+ double (*m)(double, double), double fuzz,
+ bool &first)
+{
+ triple buf[10];
+ triple* Controls;
+ if(straight) {
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=buf;
+ Controls[0]=t*controls[0];
+ Controls[6]=t*controls[6];
+ Controls[9]=t*controls[9];
+ }
+
+ triple v=Controls[0];
+ double x=xratio(v);
+ double y=yratio(v);
+ if(first) {
+ first=false;
+ b=pair(x,y);
+ } else {
+ x=m(b.getx(),x);
+ y=m(b.gety(),y);
+ }
+ v=Controls[6];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ v=Controls[9];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ b=pair(x,y);
+ } else {
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=buf;
+ for(unsigned int i=0; i < 10; ++i)
+ Controls[i]=t*controls[i];
+ }
+
+ if(first) {
+ triple v=Controls[0];
+ b=pair(xratio(v),yratio(v));
+ first=false;
+ }
+
+ b=pair(boundtri(Controls,m,xratio,b.getx(),fuzz,maxdepth),
+ boundtri(Controls,m,yratio,b.gety(),fuzz,maxdepth));
+ }
+}
+
+bool drawBezierTriangle::write(prcfile *out, unsigned int *, double,
+ groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+
+ static const double third=1.0/3.0;
+ static const double third2=2.0/3.0;
+ triple Controls[]={controls[0],controls[0],controls[0],controls[0],
+ controls[1],third2*controls[1]+third*controls[2],
+ third*controls[1]+third2*controls[2],
+ controls[2],controls[3],
+ third*controls[3]+third2*controls[4],
+ third2*controls[4]+third*controls[5],
+ controls[5],controls[6],controls[7],
+ controls[8],controls[9]};
+ out->addPatch(Controls,m);
+
+ return true;
+}
+
+void drawBezierTriangle::render(double size2, const triple& b, const triple& B,
+ double perspective, bool transparent)
+{
+#ifdef HAVE_GL
+ if(invisible ||
+ ((colors ? colors[0].A+colors[1].A+colors[2].A < 3.0 :
+ diffuse.A < 1.0) ^ transparent)) return;
+
+ const bool billboard=interaction == BILLBOARD &&
+ !settings::getSetting<bool>("offscreen");
+ triple m,M;
+
+ double f,F,s;
+ if(perspective) {
+ f=Min.getz()*perspective;
+ F=Max.getz()*perspective;
+ m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz());
+ M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz());
+ s=max(f,F);
+ } else {
+ m=b;
+ M=B;
+ s=1.0;
+ }
+
+ const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+
+ bbox3 box(m,M);
+ box.transform(modelView.Tinv);
+ m=box.Min();
+ M=box.Max();
+
+ if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() ||
+ Max.gety() < m.gety() || Min.gety() > M.gety() ||
+ Max.getz() < m.getz() || Min.getz() > M.getz()))
+ return;
+
+ setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
+
+ if(billboard) BB.init(center);
+
+ GLfloat v[12];
+ if(colors)
+ for(size_t i=0; i < 3; ++i)
+ storecolor(v,4*i,colors[i]);
+
+ triple *Controls;
+ triple Controls0[10];
+ if(billboard) {
+ Controls=Controls0;
+ for(size_t i=0; i < 10; i++)
+ Controls[i]=BB.transform(controls[i]);
+ } else
+ Controls=controls;
+
+ if(gl::outlinemode) {
+ triple edge0[]={Controls[0],Controls[1],Controls[3],Controls[6]};
+ C.queue(edge0,straight,size3.length()/size2,m,M);
+ triple edge1[]={Controls[6],Controls[7],Controls[8],Controls[9]};
+ C.queue(edge1,straight,size3.length()/size2,m,M);
+ triple edge2[]={Controls[9],Controls[5],Controls[2],Controls[0]};
+ C.queue(edge2,straight,size3.length()/size2,m,M);
+ C.draw();
+ } else
+ S.queue(Controls,straight,size3.length()/size2,m,M,transparent,
+ colors ? v : NULL);
+#endif
+}
+
+drawElement *drawBezierTriangle::transformed(const double* t)
+{
+ return new drawBezierTriangle(t,this);
+}
+
+bool drawNurbs::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+ out->addSurface(udegree,vdegree,nu,nv,controls,uknots,vknots,m,weights);
+
+ return true;
+}
+
+// Approximate bounds by bounding box of control polyhedron.
+void drawNurbs::bounds(const double* t, bbox3& b)
+{
+ double x,y,z;
+ double X,Y,Z;
+
+ const size_t n=nu*nv;
+ triple* Controls;
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=new triple[n];
+ for(size_t i=0; i < n; i++)
+ Controls[i]=t*controls[i];
+ }
+
+ boundstriples(x,y,z,X,Y,Z,n,Controls);
+
+ b.add(x,y,z);
+ b.add(X,Y,Z);
+
+ if(t == NULL) {
+ Min=triple(x,y,z);
+ Max=triple(X,Y,Z);
+ } else delete[] Controls;
+}
+
+drawElement *drawNurbs::transformed(const double* t)
+{
+ return new drawNurbs(t,this);
+}
+
+void drawNurbs::ratio(const double *t, pair &b, double (*m)(double, double),
+ double, bool &first)
+{
+ const size_t n=nu*nv;
+
+ triple* Controls;
+ if(t == NULL) Controls=controls;
+ else {
+ Controls=new triple[n];
+ for(unsigned int i=0; i < n; ++i)
+ Controls[i]=t*controls[i];
+ }
+
+ if(first) {
+ first=false;
+ triple v=Controls[0];
+ b=pair(xratio(v),yratio(v));
+ }
+
+ double x=b.getx();
+ double y=b.gety();
+ for(size_t i=0; i < n; ++i) {
+ triple v=Controls[i];
+ x=m(x,xratio(v));
+ y=m(y,yratio(v));
+ }
+ b=pair(x,y);
+
+ if(t != NULL)
+ delete[] Controls;
+}
+
+
+void drawNurbs::displacement()
+{
+#ifdef HAVE_GL
+ size_t n=nu*nv;
+ size_t nuknots=udegree+nu+1;
+ size_t nvknots=vdegree+nv+1;
+
+ if(Controls == NULL) {
+ Controls=new(UseGC) GLfloat[(weights ? 4 : 3)*n];
+ uKnots=new(UseGC) GLfloat[nuknots];
+ vKnots=new(UseGC) GLfloat[nvknots];
+ }
+
+ if(weights)
+ for(size_t i=0; i < n; ++i)
+ store(Controls+4*i,controls[i],weights[i]);
+ else
+ for(size_t i=0; i < n; ++i)
+ store(Controls+3*i,controls[i]);
+
+ for(size_t i=0; i < nuknots; ++i)
+ uKnots[i]=uknots[i];
+ for(size_t i=0; i < nvknots; ++i)
+ vKnots[i]=vknots[i];
+#endif
+}
+
+void drawNurbs::render(double size2, const triple& Min, const triple& Max,
+ double perspective, bool transparent)
+{
+#ifdef HAVE_GL
+ if(invisible || ((colors ? colors[3]+colors[7]+colors[11]+colors[15] < 4.0
+ : diffuse.A < 1.0) ^ transparent)) return;
+
+ bbox3 B(this->Min,this->Max);
+ B.transform(modelView.T);
+
+ triple m=B.Min();
+ triple M=B.Max();
+
+ if(perspective) {
+ double f=m.getz()*perspective;
+ double F=M.getz()*perspective;
+ if(M.getx() < min(f*Min.getx(),F*Min.getx()) ||
+ m.getx() > max(f*Max.getx(),F*Max.getx()) ||
+ M.gety() < min(f*Min.gety(),F*Min.gety()) ||
+ m.gety() > max(f*Max.gety(),F*Max.gety()) ||
+ M.getz() < Min.getz() ||
+ m.getz() > Max.getz()) return;
+ } else {
+ if(M.getx() < Min.getx() || m.getx() > Max.getx() ||
+ M.gety() < Min.gety() || m.gety() > Max.gety() ||
+ M.getz() < Min.getz() || m.getz() > Max.getz()) return;
+ }
+
+ setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
+// TODO: implement NURBS renderer
+#endif
+}
+
+void drawSphere::P(triple& t, double x, double y, double z)
+{
+ if(half) {
+ double temp=z; z=x; x=-temp;
+ }
+
+ if(T == NULL) {
+ t=triple(x,y,z);
+ return;
+ }
+
+ double f=T[12]*x+T[13]*y+T[14]*z+T[15];
+ if(f == 0.0) run::dividebyzero();
+ f=1.0/f;
+
+ t=triple((T[0]*x+T[1]*y+T[2]*z+T[3])*f,(T[4]*x+T[5]*y+T[6]*z+T[7])*f,
+ (T[8]*x+T[9]*y+T[10]*z+T[11])*f);
+}
+
+bool drawSphere::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
+
+ switch(type) {
+ case 0: // PRCsphere
+ {
+ if(half)
+ out->addHemisphere(1.0,m,NULL,NULL,NULL,1.0,T);
+ else
+ out->addSphere(1.0,m,NULL,NULL,NULL,1.0,T);
+ break;
+ }
+ case 1: // NURBSsphere
+ {
+ static double uknot[]={0.0,0.0,1.0/3.0,0.5,1.0,1.0};
+ static double vknot[]={0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0};
+ static double Weights[12]={2.0/3.0,2.0/9.0,2.0/9.0,2.0/3.0,
+ 1.0/3.0,1.0/9.0,1.0/9.0,1.0/3.0,
+ 1.0,1.0/3.0,1.0/3.0,1.0};
+
+// NURBS representation of a sphere using 10 distinct control points
+// K. Qin, J. Comp. Sci. and Tech. 12, 210-216 (1997).
+
+ triple N,S,P1,P2,P3,P4,P5,P6,P7,P8;
+
+ P(N,0.0,0.0,1.0);
+ P(P1,-2.0,-2.0,1.0);
+ P(P2,-2.0,-2.0,-1.0);
+ P(S,0.0,0.0,-1.0);
+ P(P3,2.0,-2.0,1.0);
+ P(P4,2.0,-2.0,-1.0);
+ P(P5,2.0,2.0,1.0);
+ P(P6,2.0,2.0,-1.0);
+ P(P7,-2.0,2.0,1.0);
+ P(P8,-2.0,2.0,-1.0);
+
+ triple p0[]={N,P1,P2,S,
+ N,P3,P4,S,
+ N,P5,P6,S,
+ N,P7,P8,S,
+ N,P1,P2,S,
+ N,P3,P4,S};
+
+ out->addSurface(2,3,3,4,p0,uknot,vknot,m,Weights);
+ out->addSurface(2,3,3,4,p0+4,uknot,vknot,m,Weights);
+ if(!half) {
+ out->addSurface(2,3,3,4,p0+8,uknot,vknot,m,Weights);
+ out->addSurface(2,3,3,4,p0+12,uknot,vknot,m,Weights);
+ }
+
+ break;
+ }
+ default:
+ reportError("Invalid sphere type");
+ }
+
+ return true;
+}
+
+bool drawCylinder::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
+
+ out->addCylinder(1.0,1.0,m,NULL,NULL,NULL,1.0,T);
+
+ return true;
+}
+
+bool drawDisk::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
+
+ out->addDisk(1.0,m,NULL,NULL,NULL,1.0,T);
+
+ return true;
+}
+
+bool drawTube::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
+
+ Int n=center.length();
+
+ if(center.piecewisestraight()) {
+ triple *centerControls=new(UseGC) triple[n+1];
+ for(Int i=0; i <= n; ++i)
+ centerControls[i]=center.point(i);
+ size_t N=n+1;
+ triple *controls=new(UseGC) triple[N];
+ for(Int i=0; i <= n; ++i)
+ controls[i]=g.point(i);
+ out->addTube(N,centerControls,controls,true,m);
+ } else {
+ size_t N=3*n+1;
+ triple *centerControls=new(UseGC) triple[N];
+ centerControls[0]=center.point((Int) 0);
+ centerControls[1]=center.postcontrol((Int) 0);
+ size_t k=1;
+ for(Int i=1; i < n; ++i) {
+ centerControls[++k]=center.precontrol(i);
+ centerControls[++k]=center.point(i);
+ centerControls[++k]=center.postcontrol(i);
+ }
+ centerControls[++k]=center.precontrol(n);
+ centerControls[++k]=center.point(n);
+
+ triple *controls=new(UseGC) triple[N];
+ controls[0]=g.point((Int) 0);
+ controls[1]=g.postcontrol((Int) 0);
+ k=1;
+ for(Int i=1; i < n; ++i) {
+ controls[++k]=g.precontrol(i);
+ controls[++k]=g.point(i);
+ controls[++k]=g.postcontrol(i);
+ }
+ controls[++k]=g.precontrol(n);
+ controls[++k]=g.point(n);
+
+ out->addTube(N,centerControls,controls,false,m);
+ }
+
+ return true;
+}
+
+const string drawBaseTriangles::wrongsize=
+ "triangle indices require 3 components";
+const string drawBaseTriangles::outofrange="index out of range";
+
+void drawBaseTriangles::bounds(const double* t, bbox3& b)
+{
+ double x,y,z;
+ double X,Y,Z;
+ triple* tP;
+
+ if(t == NULL) tP=P;
+ else {
+ tP=new triple[nP];
+ for(size_t i=0; i < nP; i++)
+ tP[i]=t*P[i];
+ }
+
+ boundstriples(x,y,z,X,Y,Z,nP,tP);
+
+ b.add(x,y,z);
+ b.add(X,Y,Z);
+
+ if(t == NULL) {
+ Min=triple(x,y,z);
+ Max=triple(X,Y,Z);
+ } else delete[] tP;
+}
+
+void drawBaseTriangles::ratio(const double* t, pair &b,
+ double (*m)(double, double), double fuzz,
+ bool &first)
+{
+ triple* tP;
+
+ if(t == NULL) tP=P;
+ else {
+ tP=new triple[nP];
+ for(size_t i=0; i < nP; i++)
+ tP[i]=t*P[i];
+ }
+
+ ratiotriples(b,m,first,nP,tP);
+
+ if(t != NULL)
+ delete[] tP;
+}
+
+bool drawTriangles::write(prcfile *out, unsigned int *, double, groupsmap&)
+{
+ if(invisible)
+ return true;
+
+ if(nC) {
+ const RGBAColour white(1,1,1,opacity);
+ const RGBAColour black(0,0,0,opacity);
+ const PRCmaterial m(black,white,black,specular,opacity,PRCshininess);
+ out->addTriangles(nP,P,nI,PI,m,nN,N,NI,0,NULL,NULL,nC,C,CI,0,NULL,NULL,30);
+ } else {
+ RGBAColour Black(0.0,0.0,0.0,diffuse.A);
+ const PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+ out->addTriangles(nP,P,nI,PI,m,nN,N,NI,0,NULL,NULL,0,NULL,NULL,0,NULL,NULL,30);
+ }
+
+ return true;
+}
+
+void drawTriangles::render(double size2, const triple& Min,
+ const triple& Max, double perspective,
+ bool transparent)
+{
+#ifdef HAVE_GL
+ if(invisible)
+ return;
+
+ if(invisible || ((diffuse.A < 1.0) ^ transparent)) return;
+
+ triple m,M;
+
+ bbox3 B(this->Min,this->Max);
+ B.transform(modelView.T);
+
+ m=B.Min();
+ M=B.Max();
+
+ if(perspective) {
+ const double f=m.getz()*perspective;
+ const double F=M.getz()*perspective;
+ if((M.getx() < min(f*Min.getx(),F*Min.getx()) ||
+ m.getx() > max(f*Max.getx(),F*Max.getx()) ||
+ M.gety() < min(f*Min.gety(),F*Min.gety()) ||
+ m.gety() > max(f*Max.gety(),F*Max.gety()) ||
+ M.getz() < Min.getz() ||
+ m.getz() > Max.getz()))
+ return;
+ } else {
+ if((M.getx() < Min.getx() || m.getx() > Max.getx() ||
+ M.gety() < Min.gety() || m.gety() > Max.gety() ||
+ M.getz() < Min.getz() || m.getz() > Max.getz()))
+ return;
+ }
+
+ setcolors(nC,diffuse,emissive,specular,shininess,metallic,fresnel0);
+ R.queue(nP,P,nN,N,nC,C,nI,PI,NI,CI,transparent);
+#endif
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/drawsurface.h b/graphics/asymptote/drawsurface.h
new file mode 100644
index 0000000000..226de59db7
--- /dev/null
+++ b/graphics/asymptote/drawsurface.h
@@ -0,0 +1,655 @@
+/*****
+ * drawsurface.h
+ *
+ * Stores a surface that has been added to a picture.
+ *****/
+
+#ifndef DRAWSURFACE_H
+#define DRAWSURFACE_H
+
+#include "drawelement.h"
+#include "arrayop.h"
+#include "path3.h"
+#include "beziercurve.h"
+#include "bezierpatch.h"
+
+namespace camp {
+
+#ifdef HAVE_GL
+void storecolor(GLfloat *colors, int i, const vm::array &pens, int j);
+#endif
+
+class drawSurface : public drawElement {
+protected:
+ triple *controls;
+ size_t ncontrols;
+ triple center;
+ bool straight; // True iff Bezier patch is planar and has straight edges.
+ prc::RGBAColour diffuse;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
+ prc::RGBAColour *colors;
+ double opacity;
+ double shininess;
+ double metallic;
+ double fresnel0;
+ double PRCshininess;
+ bool invisible;
+ Interaction interaction;
+
+ triple Min,Max;
+ bool prc;
+
+public:
+#ifdef HAVE_GL
+ static BezierCurve C;
+#endif
+
+ string wrongsize() {
+ return (ncontrols == 16 ? "4x4" : "triangular")+
+ string(" array of triples and array of 4 pens required");
+ }
+
+ drawSurface(const vm::array& g, size_t ncontrols, triple center,
+ bool straight, const vm::array&p, double opacity,
+ double shininess, double metallic, double fresnel0, double PRCshininess, const vm::array &pens,
+ Interaction interaction, bool prc, const string& key="") :
+ drawElement(key), ncontrols(ncontrols), center(center), straight(straight),
+ opacity(opacity), shininess(shininess), metallic(metallic), fresnel0(fresnel0), PRCshininess(PRCshininess),
+ interaction(interaction), prc(prc) {
+ if(checkArray(&g) != 4 || checkArray(&p) != 3)
+ reportError(wrongsize());
+
+ size_t k=0;
+ controls=new(UseGC) triple[ncontrols];
+ for(unsigned int i=0; i < 4; ++i) {
+ vm::array *gi=vm::read<vm::array*>(g,i);
+ size_t n=(ncontrols == 16 ? 4 : i+1);
+ if(checkArray(gi) != n)
+ reportError(wrongsize());
+ for(unsigned int j=0; j < n; ++j)
+ controls[k++]=vm::read<triple>(gi,j);
+ }
+
+ pen surfacepen=vm::read<camp::pen>(p,0);
+ invisible=surfacepen.invisible();
+
+ diffuse=rgba(surfacepen);
+ emissive=rgba(vm::read<camp::pen>(p,1));
+ specular=rgba(vm::read<camp::pen>(p,2));
+
+ size_t nodes=(ncontrols == 16 ? 4 : 3);
+ size_t size=checkArray(&pens);
+ if(size > 0) {
+ if(size != nodes) reportError("4 vertex pens required");
+ colors=new(UseGC) prc::RGBAColour[nodes];
+ for(size_t i=0; i < nodes; ++i)
+ colors[i]=rgba(vm::read<camp::pen>(pens,i));
+ } else colors=NULL;
+ }
+
+ drawSurface(const double* t, const drawSurface *s) :
+ drawElement(s->KEY), ncontrols(s->ncontrols), straight(s->straight),
+ diffuse(s->diffuse), emissive(s->emissive),
+ specular(s->specular), colors(s->colors), opacity(s->opacity),
+ shininess(s->shininess), metallic(s->metallic), fresnel0(s->fresnel0),
+ PRCshininess(s->PRCshininess), invisible(s->invisible),
+ interaction(s->interaction), prc(s->prc) {
+
+ if(s->controls) {
+ controls=new(UseGC) triple[ncontrols];
+ for(unsigned int i=0; i < ncontrols; ++i)
+ controls[i]=t*s->controls[i];
+ } else controls=NULL;
+
+#ifdef HAVE_GL
+ center=t*s->center;
+#endif
+ }
+
+ virtual ~drawSurface() {}
+
+ bool is3D() {return true;}
+};
+
+class drawBezierPatch : public drawSurface {
+public:
+#ifdef HAVE_GL
+ static BezierPatch S;
+#endif
+
+ drawBezierPatch(const vm::array& g, triple center, bool straight,
+ const vm::array&p, double opacity, double shininess,
+ double metallic, double fresnel0,
+ double PRCshininess, const vm::array &pens,
+ Interaction interaction, bool prc) :
+ drawSurface(g,16,center,straight,p,opacity,
+ shininess,metallic,fresnel0,PRCshininess,pens,interaction,prc) {}
+
+ drawBezierPatch(const double* t, const drawBezierPatch *s) :
+ drawSurface(t,s) {
+ }
+
+ void bounds(const double* t, bbox3& b);
+
+ void ratio(const double* t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first);
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ void render(double, const triple& Min, const triple& Max,
+ double perspective, bool transparent);
+ drawElement *transformed(const double* t);
+};
+
+class drawBezierTriangle : public drawSurface {
+public:
+#ifdef HAVE_GL
+ static BezierTriangle S;
+#endif
+
+ drawBezierTriangle(const vm::array& g, triple center, bool straight,
+ const vm::array&p, double opacity, double shininess,
+ double metallic, double fresnel0,
+ double PRCshininess, const vm::array &pens,
+ Interaction interaction, bool prc) :
+ drawSurface(g,10,center,straight,p,opacity,shininess,metallic,fresnel0,
+ PRCshininess,pens,interaction,prc) {}
+
+ drawBezierTriangle(const double* t, const drawBezierTriangle *s) :
+ drawSurface(t,s) {
+ }
+
+ void bounds(const double* t, bbox3& b);
+
+ void ratio(const double* t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first);
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ void render(double, const triple& Min, const triple& Max,
+ double perspective, bool transparent);
+ drawElement *transformed(const double* t);
+};
+
+class drawNurbs : public drawElement {
+protected:
+ size_t udegree,vdegree;
+ size_t nu,nv;
+ triple *controls;
+ double *weights;
+ double *uknots, *vknots;
+ prc::RGBAColour diffuse;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
+ double opacity;
+ double shininess;
+ double metallic;
+ double fresnel0;
+ double PRCshininess;
+ triple normal;
+ bool invisible;
+
+ triple Min,Max;
+
+#ifdef HAVE_GL
+ GLfloat *colors;
+ GLfloat *Controls;
+ GLfloat *uKnots;
+ GLfloat *vKnots;
+#endif
+
+public:
+ drawNurbs(const vm::array& g, const vm::array* uknot, const vm::array* vknot,
+ const vm::array* weight, const vm::array&p, double opacity,
+ double shininess, double metallic, double fresnel0, double PRCshininess, const vm::array &pens,
+ const string& key="")
+ : drawElement(key), opacity(opacity), shininess(shininess),
+ metallic(metallic), fresnel0(fresnel0), PRCshininess(PRCshininess) {
+ size_t weightsize=checkArray(weight);
+
+ const string wrongsize="Inconsistent NURBS data";
+ nu=checkArray(&g);
+
+ if(nu == 0 || (weightsize != 0 && weightsize != nu) || checkArray(&p) != 3)
+ reportError(wrongsize);
+
+ vm::array *g0=vm::read<vm::array*>(g,0);
+ nv=checkArray(g0);
+
+ size_t n=nu*nv;
+ controls=new(UseGC) triple[n];
+
+ size_t k=0;
+ for(size_t i=0; i < nu; ++i) {
+ vm::array *gi=vm::read<vm::array*>(g,i);
+ if(checkArray(gi) != nv)
+ reportError(wrongsize);
+ for(size_t j=0; j < nv; ++j)
+ controls[k++]=vm::read<triple>(gi,j);
+ }
+
+ if(weightsize > 0) {
+ size_t k=0;
+ weights=new(UseGC) double[n];
+ for(size_t i=0; i < nu; ++i) {
+ vm::array *weighti=vm::read<vm::array*>(weight,i);
+ if(checkArray(weighti) != nv)
+ reportError(wrongsize);
+ for(size_t j=0; j < nv; ++j)
+ weights[k++]=vm::read<double>(weighti,j);
+ }
+ } else weights=NULL;
+
+ size_t nuknots=checkArray(uknot);
+ size_t nvknots=checkArray(vknot);
+
+ if(nuknots <= nu+1 || nuknots > 2*nu || nvknots <= nv+1 || nvknots > 2*nv)
+ reportError(wrongsize);
+
+ udegree=nuknots-nu-1;
+ vdegree=nvknots-nv-1;
+
+ run::copyArrayC(uknots,uknot,0,UseGC);
+ run::copyArrayC(vknots,vknot,0,UseGC);
+
+ pen surfacepen=vm::read<camp::pen>(p,0);
+ invisible=surfacepen.invisible();
+
+ diffuse=rgba(surfacepen);
+ emissive=rgba(vm::read<camp::pen>(p,1));
+ specular=rgba(vm::read<camp::pen>(p,2));
+
+#ifdef HAVE_GL
+ Controls=NULL;
+ int size=checkArray(&pens);
+ if(size > 0) {
+ colors=new(UseGC) GLfloat[16];
+ if(size != 4) reportError(wrongsize);
+ storecolor(colors,0,pens,0);
+ storecolor(colors,8,pens,1);
+ storecolor(colors,12,pens,2);
+ storecolor(colors,4,pens,3);
+ } else colors=NULL;
+#endif
+ }
+
+ drawNurbs(const double* t, const drawNurbs *s) :
+ drawElement(s->KEY), udegree(s->udegree), vdegree(s->vdegree), nu(s->nu),
+ nv(s->nv), weights(s->weights), uknots(s->uknots), vknots(s->vknots),
+ diffuse(s->diffuse),
+ emissive(s->emissive), specular(s->specular), opacity(s->opacity),
+ shininess(s->shininess), PRCshininess(s->PRCshininess),
+ invisible(s->invisible) {
+
+ const size_t n=nu*nv;
+ controls=new(UseGC) triple[n];
+ for(unsigned int i=0; i < n; ++i)
+ controls[i]=t*s->controls[i];
+
+#ifdef HAVE_GL
+ Controls=NULL;
+ colors=s->colors;
+#endif
+ }
+
+ bool is3D() {return true;}
+
+ void bounds(const double* t, bbox3& b);
+
+ virtual ~drawNurbs() {}
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ void displacement();
+ void ratio(const double* t, pair &b, double (*m)(double, double), double,
+ bool &first);
+
+ void render(double size2, const triple& Min, const triple& Max,
+ double perspective, bool transparent);
+
+ drawElement *transformed(const double* t);
+};
+
+// Draw a transformed PRC object.
+class drawPRC : public drawElementLC {
+protected:
+ prc::RGBAColour diffuse;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
+ double opacity;
+ double shininess;
+ bool invisible;
+public:
+ drawPRC(const vm::array& t, const vm::array&p, double opacity,
+ double shininess) :
+ drawElementLC(t), opacity(opacity), shininess(shininess) {
+
+ string needthreepens="array of 3 pens required";
+ if(checkArray(&p) != 3)
+ reportError(needthreepens);
+
+ pen surfacepen=vm::read<camp::pen>(p,0);
+ invisible=surfacepen.invisible();
+
+ diffuse=rgba(surfacepen);
+ emissive=rgba(vm::read<camp::pen>(p,1));
+ specular=rgba(vm::read<camp::pen>(p,2));
+ }
+
+ drawPRC(const double* t, const drawPRC *s) :
+ drawElementLC(t,s), diffuse(s->diffuse),
+ emissive(s->emissive), specular(s->specular), opacity(s->opacity),
+ shininess(s->shininess), invisible(s->invisible) {
+ }
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&) {
+ return true;
+ }
+ virtual void transformedbounds(const double*, bbox3&) {}
+ virtual void transformedratio(const double*, pair&,
+ double (*)(double, double), double, bool&) {}
+
+};
+
+// Draw a PRC unit sphere.
+class drawSphere : public drawPRC {
+ bool half;
+ int type;
+public:
+ drawSphere(const vm::array& t, bool half, const vm::array&p, double opacity,
+ double shininess, int type) :
+ drawPRC(t,p,opacity,shininess), half(half), type(type) {}
+
+ drawSphere(const double* t, const drawSphere *s) :
+ drawElement(s->KEY), drawPRC(t,s), half(s->half), type(s->type) {}
+
+ void P(triple& t, double x, double y, double z);
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ drawElement *transformed(const double* t) {
+ return new drawSphere(t,this);
+ }
+};
+
+// Draw a PRC unit cylinder.
+class drawCylinder : public drawPRC {
+public:
+ drawCylinder(const vm::array& t, const vm::array&p, double opacity,
+ double shininess) :
+ drawPRC(t,p,opacity,shininess) {}
+
+ drawCylinder(const double* t, const drawCylinder *s) :
+ drawPRC(t,s) {}
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ drawElement *transformed(const double* t) {
+ return new drawCylinder(t,this);
+ }
+};
+
+// Draw a PRC unit disk.
+class drawDisk : public drawPRC {
+public:
+ drawDisk(const vm::array& t, const vm::array&p, double opacity,
+ double shininess) :
+ drawPRC(t,p,opacity,shininess) {}
+
+ drawDisk(const double* t, const drawDisk *s) :
+ drawPRC(t,s) {}
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ drawElement *transformed(const double* t) {
+ return new drawDisk(t,this);
+ }
+};
+
+// Draw a PRC tube.
+class drawTube : public drawElement {
+protected:
+ path3 center;
+ path3 g;
+ prc::RGBAColour diffuse;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
+ double opacity;
+ double shininess;
+ bool invisible;
+public:
+ drawTube(path3 center, path3 g, const vm::array&p, double opacity,
+ double shininess) :
+ center(center), g(g), opacity(opacity), shininess(shininess) {
+ string needthreepens="array of 3 pens required";
+ if(checkArray(&p) != 3)
+ reportError(needthreepens);
+
+ pen surfacepen=vm::read<camp::pen>(p,0);
+ invisible=surfacepen.invisible();
+
+ diffuse=rgba(surfacepen);
+ emissive=rgba(vm::read<camp::pen>(p,1));
+ specular=rgba(vm::read<camp::pen>(p,2));
+ }
+
+ drawTube(const double* t, const drawTube *s) :
+ drawElement(s->KEY), center(camp::transformed(t,s->center)),
+ g(camp::transformed(t,s->g)),
+ diffuse(s->diffuse), emissive(s->emissive),
+ specular(s->specular), opacity(s->opacity),
+ shininess(s->shininess), invisible(s->invisible) {
+ }
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ drawElement *transformed(const double* t) {
+ return new drawTube(t,this);
+ }
+};
+
+
+class drawBaseTriangles : public drawElement {
+protected:
+#ifdef HAVE_GL
+ Triangles R;
+#endif
+
+ size_t nP;
+ triple* P;
+ size_t nN;
+ triple* N;
+ size_t nI;
+ uint32_t (*PI)[3];
+ uint32_t (*NI)[3];
+
+ triple Min,Max;
+
+ static const string wrongsize;
+ static const string outofrange;
+
+public:
+ drawBaseTriangles(const vm::array& v, const vm::array& vi,
+ const vm::array& n, const vm::array& ni) {
+ nP=checkArray(&v);
+ P=new(UseGC) triple[nP];
+ for(size_t i=0; i < nP; ++i)
+ P[i]=vm::read<triple>(v,i);
+
+ nI=checkArray(&vi);
+ PI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ vm::array *vii=vm::read<vm::array*>(vi,i);
+ if(checkArray(vii) != 3) reportError(wrongsize);
+ uint32_t *PIi=PI[i];
+ for(size_t j=0; j < 3; ++j) {
+ size_t index=unsignedcast(vm::read<Int>(vii,j));
+ if(index >= nP) reportError(outofrange);
+ PIi[j]=index;
+ }
+ }
+
+ nN=checkArray(&n);
+ if(nN) {
+ N=new(UseGC) triple[nN];
+ for(size_t i=0; i < nN; ++i)
+ N[i]=vm::read<triple>(n,i);
+
+ if(checkArray(&ni) != nI)
+ reportError("Index arrays have different lengths");
+ NI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ vm::array *nii=vm::read<vm::array*>(ni,i);
+ if(checkArray(nii) != 3) reportError(wrongsize);
+ uint32_t *NIi=NI[i];
+ for(size_t j=0; j < 3; ++j) {
+ size_t index=unsignedcast(vm::read<Int>(nii,j));
+ if(index >= nN) reportError(outofrange);
+ NIi[j]=index;
+ }
+ }
+ }
+ }
+
+ drawBaseTriangles(const double* t, const drawBaseTriangles *s) :
+ drawElement(s->KEY), nP(s->nP), nN(s->nN), nI(s->nI) {
+ P=new(UseGC) triple[nP];
+ for(size_t i=0; i < nP; i++)
+ P[i]=t*s->P[i];
+
+ PI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ uint32_t *PIi=PI[i];
+ uint32_t *sPIi=s->PI[i];
+ for(size_t j=0; j < 3; ++j)
+ PIi[j]=sPIi[j];
+ }
+
+ if(nN) {
+ N=new(UseGC) triple[nN];
+ for(size_t i=0; i < nN; i++)
+ N[i]=transformNormal(t,s->N[i]);
+
+ NI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ uint32_t *NIi=NI[i];
+ uint32_t *sNIi=s->NI[i];
+ for(size_t j=0; j < 3; ++j)
+ NIi[j]=sNIi[j];
+ }
+ }
+ }
+
+ bool is3D() {return true;}
+
+ void bounds(const double* t, bbox3& b);
+
+ void ratio(const double* t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first);
+
+ virtual ~drawBaseTriangles() {}
+
+ drawElement *transformed(const double* t) {
+ return new drawBaseTriangles(t,this);
+ }
+};
+
+class drawTriangles : public drawBaseTriangles {
+ size_t nC;
+ prc::RGBAColour*C;
+ uint32_t (*CI)[3];
+
+ // Asymptote material data
+ prc::RGBAColour diffuse;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
+ double opacity;
+ double shininess;
+ double metallic;
+ double fresnel0;
+ double PRCshininess;
+ bool invisible;
+
+public:
+ drawTriangles(const vm::array& v, const vm::array& vi,
+ const vm::array& n, const vm::array& ni,
+ const vm::array&p, double opacity, double shininess,
+ double metallic, double fresnel0,
+ double PRCshininess, const vm::array& c, const vm::array& ci) :
+ drawBaseTriangles(v,vi,n,ni),
+ opacity(opacity),shininess(shininess),metallic(metallic),
+ fresnel0(fresnel0),PRCshininess(PRCshininess) {
+
+ const string needthreepens="array of 3 pens required";
+ if(checkArray(&p) != 3)
+ reportError(needthreepens);
+
+ const pen surfacepen=vm::read<camp::pen>(p,0);
+ invisible=surfacepen.invisible();
+ diffuse=rgba(surfacepen);
+
+ nC=checkArray(&c);
+ if(nC) {
+ C=new(UseGC) prc::RGBAColour[nC];
+ for(size_t i=0; i < nC; ++i)
+ C[i]=rgba(vm::read<camp::pen>(c,i));
+
+ size_t nI=checkArray(&vi);
+
+ if(checkArray(&ci) != nI)
+ reportError("Index arrays have different lengths");
+ CI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ vm::array *cii=vm::read<vm::array*>(ci,i);
+ if(checkArray(cii) != 3) reportError(wrongsize);
+ uint32_t *CIi=CI[i];
+ for(size_t j=0; j < 3; ++j) {
+ size_t index=unsignedcast(vm::read<Int>(cii,j));
+ if(index >= nC) reportError(outofrange);
+ CIi[j]=index;
+ }
+ }
+ } else {
+ emissive=rgba(vm::read<camp::pen>(p,1));
+ }
+ specular=rgba(vm::read<camp::pen>(p,2));
+ }
+
+ drawTriangles(const double* t, const drawTriangles *s) :
+ drawBaseTriangles(t,s), nC(s->nC),
+ diffuse(s->diffuse), emissive(s->emissive),
+ specular(s->specular), opacity(s->opacity), shininess(s->shininess),
+ metallic(s->metallic), fresnel0(s->fresnel0), PRCshininess(s->PRCshininess),
+ invisible(s->invisible) {
+
+ if(nC) {
+ C=new(UseGC) prc::RGBAColour[nC];
+ for(size_t i=0; i < nC; ++i)
+ C[i]=s->C[i];
+
+ CI=new(UseGC) uint32_t[nI][3];
+ for(size_t i=0; i < nI; ++i) {
+ uint32_t *CIi=CI[i];
+ uint32_t *sCIi=s->CI[i];
+ for(size_t j=0; j < 3; ++j)
+ CIi[j]=sCIi[j];
+ }
+ }
+ }
+
+ virtual ~drawTriangles() {}
+
+ void render(double size2, const triple& Min, const triple& Max,
+ double perspective, bool transparent);
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+ drawElement *transformed(const double* t) {
+ return new drawTriangles(t,this);
+ }
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/drawverbatim.h b/graphics/asymptote/drawverbatim.h
new file mode 100644
index 0000000000..186dc54442
--- /dev/null
+++ b/graphics/asymptote/drawverbatim.h
@@ -0,0 +1,63 @@
+/*****
+ * drawverbatim.h
+ * John Bowman 2003/03/18
+ *
+ * Add verbatim postscript to picture.
+ *****/
+
+#ifndef DRAWVERBATIM_H
+#define DRAWVERBATIM_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+enum Language {PostScript,TeX};
+
+class drawVerbatim : public drawElement {
+private:
+ Language language;
+ string text;
+ bool userbounds;
+ pair min,max;
+ bool havebounds;
+public:
+ drawVerbatim(Language language, const string& text) :
+ language(language), text(text), userbounds(false), havebounds(false) {}
+
+ drawVerbatim(Language language, const string& text, pair min,
+ pair max) :
+ language(language), text(text), userbounds(true), min(min), max(max),
+ havebounds(false) {}
+
+ virtual ~drawVerbatim() {}
+
+ void bounds(bbox& b, iopipestream& tex, boxvector&, bboxlist&) {
+ if(havebounds) return;
+ havebounds=true;
+ if(language == TeX)
+ tex << text << "%" << newl;
+ if(userbounds) {
+ b += min;
+ b += max;
+ }
+ }
+
+ bool islabel() {
+ return language == TeX;
+ }
+
+ bool draw(psfile *out) {
+ if(language == PostScript) out->verbatimline(text);
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&) {
+ if(language == TeX) out->verbatimline(stripblanklines(text));
+ return true;
+ }
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/entry.cc b/graphics/asymptote/entry.cc
new file mode 100644
index 0000000000..e2c27681c3
--- /dev/null
+++ b/graphics/asymptote/entry.cc
@@ -0,0 +1,873 @@
+/*****
+ * entry.cc
+ * Andy Hammerlindl 2002/08/29
+ *
+ * All variables, built-in functions and user-defined functions reside
+ * within the same namespace. To keep track of all these, table of
+ * "entries" is used.
+ *****/
+
+#include <iostream>
+
+#include <cmath>
+#include <cstring>
+#include <utility>
+#include "entry.h"
+#include "coder.h"
+
+using std::memset;
+using types::ty;
+using types::signature;
+using types::overloaded;
+using types::ty_vector;
+using types::ty_iterator;
+
+namespace trans {
+
+bool entry::pr::check(action act, coder &c) {
+ // We assume PUBLIC permissions and one's without an associated record are not
+ // stored.
+ assert(perm!=PUBLIC && r!=0);
+ return c.inTranslation(r->getLevel()) ||
+ (perm == RESTRICTED && act != WRITE);
+}
+
+void entry::pr::report(action act, position pos, coder &c) {
+ if (!c.inTranslation(r->getLevel())) {
+ if (perm == PRIVATE) {
+ em.error(pos);
+ em << "accessing private field outside of structure";
+ }
+ else if (perm == RESTRICTED && act == WRITE) {
+ em.error(pos);
+ em << "modifying non-public field outside of structure";
+ }
+ }
+}
+
+entry::entry(entry &e1, entry &e2) : where(e2.where), pos(e2.pos) {
+ perms.insert(perms.end(), e1.perms.begin(), e1.perms.end());
+ perms.insert(perms.end(), e2.perms.begin(), e2.perms.end());
+}
+
+entry::entry(entry &base, permission perm, record *r)
+ : where(base.where), pos(base.pos) {
+ perms.insert(perms.end(), base.perms.begin(), base.perms.end());
+ addPerm(perm, r);
+}
+
+bool entry::checkPerm(action act, coder &c) {
+ for (mem::list<pr>::iterator p=perms.begin(); p != perms.end(); ++p)
+ if (!p->check(act, c))
+ return false;
+ return true;
+}
+
+void entry::reportPerm(action act, position pos, coder &c) {
+ for (mem::list<pr>::iterator p=perms.begin(); p != perms.end(); ++p)
+ p->report(act, pos, c);
+}
+
+
+varEntry::varEntry(varEntry &qv, varEntry &v)
+ : entry(qv,v), t(v.t),
+ location(new qualifiedAccess(qv.location, qv.getLevel(), v.location)) {}
+
+frame *varEntry::getLevel() {
+ record *r=dynamic_cast<record *>(t);
+ assert(r);
+ return r->getLevel();
+}
+
+void varEntry::encode(action act, position pos, coder &c) {
+ reportPerm(act, pos, c);
+ getLocation()->encode(act, pos, c);
+}
+
+void varEntry::encode(action act, position pos, coder &c, frame *top) {
+ reportPerm(act, pos, c);
+ getLocation()->encode(act, pos, c, top);
+}
+
+varEntry *qualifyVarEntry(varEntry *qv, varEntry *v)
+{
+ return qv ? (v ? new varEntry(*qv,*v) : qv) : v;
+}
+
+
+bool tenv::add(symbol dest,
+ names_t::value_type &x, varEntry *qualifier, coder &c)
+{
+ if (!x.second.empty()) {
+ tyEntry *ent=x.second.front();
+ if (ent->checkPerm(READ, c)) {
+ enter(dest, qualifyTyEntry(qualifier, ent));
+ return true;
+ }
+ }
+ return false;
+}
+
+void tenv::add(tenv& source, varEntry *qualifier, coder &c) {
+ // Enter each distinct (unshadowed) name,type pair.
+ for(names_t::iterator p = source.names.begin(); p != source.names.end(); ++p)
+ add(p->first, *p, qualifier, c);
+}
+
+bool tenv::add(symbol src, symbol dest,
+ tenv& source, varEntry *qualifier, coder &c) {
+ names_t::iterator p = source.names.find(src);
+ if (p != source.names.end())
+ return add(dest, *p, qualifier, c);
+ else
+ return false;
+}
+
+#if 0 //{{{
+/*NOHASH*/ void venv::add(venv& source, varEntry *qualifier, coder &c)
+/*NOHASH*/ {
+/*NOHASH*/ // Enter each distinct (unshadowed) name,type pair.
+/*NOHASH*/ for(names_t::iterator p = source.names.begin();
+/*NOHASH*/ p != source.names.end();
+/*NOHASH*/ ++p)
+/*NOHASH*/ add(p->first, p->first, source, qualifier, c);
+/*NOHASH*/ }
+/*NOHASH*/
+/*NOHASH*/ bool venv::add(symbol src, symbol dest,
+/*NOHASH*/ venv& source, varEntry *qualifier, coder &c)
+/*NOHASH*/ {
+/*NOHASH*/ bool added=false;
+/*NOHASH*/ name_t &list=source.names[src];
+/*NOHASH*/ types::overloaded set; // To keep track of what is shadowed.
+/*NOHASH*/ bool special = src.special();
+/*NOHASH*/
+/*NOHASH*/ for(name_iterator p = list.begin();
+/*NOHASH*/ p != list.end();
+/*NOHASH*/ ++p) {
+/*NOHASH*/ varEntry *v=*p;
+/*NOHASH*/ if (!equivalent(v->getType(), &set)) {
+/*NOHASH*/ set.addDistinct(v->getType(), special);
+/*NOHASH*/ if (v->checkPerm(READ, c)) {
+/*NOHASH*/ enter(dest, qualifyVarEntry(qualifier, v));
+/*NOHASH*/ added=true;
+/*NOHASH*/ }
+/*NOHASH*/ }
+/*NOHASH*/ }
+/*NOHASH*/
+/*NOHASH*/ return added;
+/*NOHASH*/ }
+/*NOHASH*/
+/*NOHASH*/ varEntry *venv::lookByType(symbol name, ty *t)
+/*NOHASH*/ {
+/*NOHASH*/ // Find first applicable function.
+/*NOHASH*/ name_t &list = names[name];
+/*NOHASH*/ for(name_iterator p = list.begin();
+/*NOHASH*/ p != list.end();
+/*NOHASH*/ ++p) {
+/*NOHASH*/ if (equivalent((*p)->getType(), t))
+/*NOHASH*/ return *p;
+/*NOHASH*/ }
+/*NOHASH*/ return 0;
+/*NOHASH*/ }
+/*NOHASH*/
+/*NOHASH*/ void venv::list(record *module)
+/*NOHASH*/ {
+/*NOHASH*/ bool where=settings::getSetting<bool>("where");
+/*NOHASH*/ // List all functions and variables.
+/*NOHASH*/ for(names_t::iterator N = names.begin(); N != names.end(); ++N) {
+/*NOHASH*/ symbol s=N->first;
+/*NOHASH*/ name_t &list=names[s];
+/*NOHASH*/ for(name_iterator p = list.begin(); p != list.end(); ++p) {
+/*NOHASH*/ if(!module || (*p)->whereDefined() == module) {
+/*NOHASH*/ if(where) cout << (*p)->getPos();
+/*NOHASH*/ (*p)->getType()->printVar(cout, s);
+/*NOHASH*/ cout << ";\n";
+/*NOHASH*/ }
+/*NOHASH*/ }
+/*NOHASH*/ }
+/*NOHASH*/ flush(cout);
+/*NOHASH*/ }
+/*NOHASH*/
+/*NOHASH*/ ty *venv::getType(symbol name)
+/*NOHASH*/ {
+/*NOHASH*/ types::overloaded set;
+/*NOHASH*/
+/*NOHASH*/ // Find all applicable functions in scope.
+/*NOHASH*/ name_t &list = names[name];
+/*NOHASH*/ bool special = name.special();
+/*NOHASH*/
+/*NOHASH*/ for(name_iterator p = list.begin();
+/*NOHASH*/ p != list.end();
+/*NOHASH*/ ++p) {
+/*NOHASH*/ set.addDistinct((*p)->getType(), special);
+/*NOHASH*/ }
+/*NOHASH*/
+/*NOHASH*/ return set.simplify();
+/*NOHASH*/ }
+// }}}
+#else
+
+// To avoid writing qualifiers everywhere.
+typedef core_venv::cell cell;
+
+void core_venv::initTable(size_t capacity) {
+ // Assert that capacity is a power of two.
+ assert((capacity & (capacity-1)) == 0);
+
+ this->capacity = capacity;
+ size = 0;
+ mask = capacity - 1;
+ table = new (UseGC) cell[capacity];
+ memset(table, 0, sizeof(cell) * capacity);
+}
+
+void core_venv::clear() {
+ if (size != 0) {
+ memset(table, 0, sizeof(cell) * capacity);
+ size = 0;
+ }
+}
+
+void core_venv::resize() {
+ size_t oldCapacity = capacity;
+ size_t oldSize = size;
+ cell *oldTable = table;
+
+ initTable(capacity * 4);
+
+ for (size_t i = 0; i < oldCapacity; ++i) {
+ cell& b = oldTable[i];
+ if (!b.empty() && !b.isATomb()) {
+ varEntry *old = store(b.name, b.ent);
+
+ // We should not be shadowing anything when reconstructing the table.
+ DEBUG_CACHE_ASSERT(old == 0);
+ }
+ }
+
+ assert(size == oldSize);
+
+#if DEBUG_CACHE
+ confirm_size();
+
+ for (size_t i = 0; i < oldCapacity; ++i) {
+ cell& b = oldTable[i];
+ if (!b.empty() && !b.isATomb()) {
+ assert(lookup(b.name, b.ent->getType()) == b.ent);
+ }
+ }
+#endif
+
+ //cout << "resized from " << oldCapacity << " to " << capacity << endl;
+}
+
+cell& core_venv::cellByIndex(size_t i) {
+ return table[i & mask];
+}
+
+const cell& core_venv::cellByIndex(size_t i) const {
+ return table[i & mask];
+}
+
+void core_venv::confirm_size() {
+ size_t sum = 0;
+ for (size_t i = 0; i < capacity; ++i) {
+ cell& b = table[i];
+ if (!b.empty() && !b.isATomb())
+ ++sum;
+ }
+ assert(sum == size);
+}
+
+varEntry *core_venv::storeNew(cell& cell, symbol name, varEntry *ent) {
+ // Store the value into the cell.
+ cell.storeNew(name, ent);
+
+ // We now have a new entry. Update the size.
+ ++size;
+
+ // Check if the hash table has grown too big and needs to be expanded.
+ if (2*size > capacity)
+ resize();
+
+ // Nothing is shadowed.
+ return 0;
+}
+
+
+varEntry *core_venv::storeNonSpecialAfterTomb(size_t tombIndex,
+ symbol name, varEntry *ent) {
+ DEBUG_CACHE_ASSERT(name.notSpecial());
+ DEBUG_CACHE_ASSERT(ent);
+ DEBUG_CACHE_ASSERT(ent->getType());
+
+ signature *sig = ent->getSignature();
+
+ for (size_t i = tombIndex+1; ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.empty())
+ return storeNew(cellByIndex(tombIndex), name, ent);
+
+ if (b.matches(name, sig))
+ return b.replaceWith(name, ent);
+ }
+}
+
+varEntry *core_venv::storeSpecialAfterTomb(size_t tombIndex,
+ symbol name, varEntry *ent) {
+ DEBUG_CACHE_ASSERT(name.special());
+ DEBUG_CACHE_ASSERT(ent);
+ DEBUG_CACHE_ASSERT(ent->getType());
+
+ ty *t = ent->getType();
+
+ for (size_t i = tombIndex+1; ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.empty())
+ return storeNew(cellByIndex(tombIndex), name, ent);
+
+ if (b.matches(name, t))
+ return b.replaceWith(name, ent);
+ }
+}
+
+size_t hashSig(const signature *sig) {
+ return sig ? sig->hash() : 0;
+}
+size_t nonSpecialHash(symbol name, const signature *sig) {
+ return name.hash() * 107 + hashSig(sig);
+}
+size_t nonSpecialHash(symbol name, const ty *t) {
+ DEBUG_CACHE_ASSERT(t);
+ return nonSpecialHash(name, t->getSignature());
+}
+size_t specialHash(symbol name, const ty *t) {
+ DEBUG_CACHE_ASSERT(t);
+ return name.hash() * 107 + t->hash();
+}
+
+varEntry *core_venv::storeNonSpecial(symbol name, varEntry *ent) {
+ DEBUG_CACHE_ASSERT(name.notSpecial());
+ DEBUG_CACHE_ASSERT(ent);
+ DEBUG_CACHE_ASSERT(ent->getType());
+
+ signature *sig = ent->getSignature();
+
+ for (size_t i = nonSpecialHash(name, sig); ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.empty())
+ return storeNew(b, name, ent);
+
+ if (b.matches(name, sig))
+ return b.replaceWith(name, ent);
+
+ if (b.isATomb())
+ return storeNonSpecialAfterTomb(i, name, ent);
+ }
+}
+
+varEntry *core_venv::storeSpecial(symbol name, varEntry *ent) {
+ DEBUG_CACHE_ASSERT(name.special());
+ DEBUG_CACHE_ASSERT(ent);
+ DEBUG_CACHE_ASSERT(ent->getType());
+
+ ty *t = ent->getType();
+
+ for (size_t i = specialHash(name, t); ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.empty())
+ return storeNew(b, name, ent);
+
+ if (b.matches(name, t))
+ return b.replaceWith(name, ent);
+
+ if (b.isATomb())
+ return storeSpecialAfterTomb(i, name, ent);
+ }
+}
+
+varEntry *core_venv::store(symbol name, varEntry *ent) {
+ DEBUG_CACHE_ASSERT(ent);
+ DEBUG_CACHE_ASSERT(ent->getType());
+
+ return name.special() ? storeSpecial(name, ent) :
+ storeNonSpecial(name, ent);
+}
+
+varEntry *core_venv::lookupSpecial(symbol name, const ty *t) {
+ DEBUG_CACHE_ASSERT(name.special());
+ DEBUG_CACHE_ASSERT(t);
+
+ for (size_t i = specialHash(name, t); ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.matches(name, t))
+ return b.ent;
+
+ if (b.empty())
+ return 0;
+ }
+}
+
+varEntry *core_venv::lookupNonSpecial(symbol name, const signature *sig) {
+ DEBUG_CACHE_ASSERT(name.notSpecial());
+
+ for (size_t i = nonSpecialHash(name, sig); ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.matches(name, sig))
+ return b.ent;
+
+ if (b.empty())
+ return 0;
+ }
+}
+
+varEntry *core_venv::lookup(symbol name, const ty *t) {
+ DEBUG_CACHE_ASSERT(t);
+
+ return name.special() ? lookupSpecial(name, t) :
+ lookupNonSpecial(name, t->getSignature());
+}
+
+void core_venv::removeNonSpecial(symbol name, const signature *sig) {
+ DEBUG_CACHE_ASSERT(name.notSpecial());
+
+ for (size_t i = nonSpecialHash(name, sig); ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.matches(name, sig)) {
+ b.remove();
+ --size;
+ return;
+ }
+
+ DEBUG_CACHE_ASSERT(!b.empty());
+ }
+}
+
+void core_venv::removeSpecial(symbol name, const ty *t) {
+ DEBUG_CACHE_ASSERT(name.special());
+ DEBUG_CACHE_ASSERT(t);
+
+ for (size_t i = specialHash(name, t); ; ++i)
+ {
+ cell& b = cellByIndex(i);
+
+ if (b.matches(name, t)) {
+ b.remove();
+ --size;
+ return;
+ }
+
+ DEBUG_CACHE_ASSERT(!b.empty());
+ }
+}
+
+void core_venv::remove(symbol name, const ty *t) {
+ DEBUG_CACHE_ASSERT(t);
+
+ if (name.special())
+ removeSpecial(name, t);
+ else
+ removeNonSpecial(name, t->getSignature());
+}
+
+
+size_t numFormals(ty *t) {
+ signature *sig = t->getSignature();
+ return sig ? sig->getNumFormals() : 0;
+}
+
+void venv::checkName(symbol name)
+{
+#if 0
+ // This size test is too slow, even for DEBUG_CACHE.
+ core.confirm_size();
+#endif
+
+ // Get the type, and make it overloaded if it is not (for uniformity).
+ overloaded o;
+ ty *t = getType(name);
+ if (!t)
+ t = &o;
+ if (!t->isOverloaded()) {
+ o.add(t);
+ t = &o;
+ }
+ assert(t->isOverloaded());
+
+ size_t maxFormals = names[name].maxFormals;
+
+ size_t size = 0;
+ for (ty_iterator i = t->begin(); i != t->end(); ++i) {
+ assert(numFormals(*i) <= maxFormals);
+ varEntry *v = lookByType(name, *i);
+ assert(v);
+ assert(equivalent(v->getType(), *i));
+ ++size;
+ }
+
+ size_t matches = 0;
+ core_venv::const_iterator end = core.end();
+ for (core_venv::const_iterator p = core.begin(); p != end; ++p) {
+ if (p->name == name) {
+ ++matches;
+
+ varEntry *v=p->ent;
+ assert(v);
+ assert(equivalent(t, v->getType()));
+ }
+ }
+ assert(matches == size);
+}
+
+void rightKind(ty *t) {
+ if (t && t->isOverloaded()) {
+ ty_vector& set=((overloaded *)t)->sub;
+ assert(set.size() > 1);
+ }
+}
+
+#ifdef DEBUG_CACHE
+#define RIGHTKIND(t) (rightKind(t))
+#define CHECKNAME(name) (checkName(name))
+#else
+#define RIGHTKIND(t) (void)(t)
+#define CHECKNAME(name) (void)(name)
+#endif
+
+void venv::namevalue::addType(ty *s) {
+ RIGHTKIND(t);
+
+#ifdef DEBUG_CACHE
+ assert(!s->isOverloaded());
+#endif
+
+ if (t == 0) {
+ maxFormals = numFormals(s);
+ t = s;
+ } else {
+ if (!t->isOverloaded())
+ t = new overloaded(t);
+
+#ifdef DEBUG_CACHE
+ assert(t->isOverloaded());
+ assert(!equivalent(t, s));
+#endif
+
+ ((overloaded *)t)->add(s);
+
+ size_t n = numFormals(s);
+ if (n > maxFormals)
+ maxFormals = n;
+ }
+
+ RIGHTKIND(t);
+}
+
+void venv::namevalue::replaceType(ty *new_t, ty *old_t) {
+#ifdef DEBUG_CACHE
+ assert(t != 0);
+ RIGHTKIND(t);
+#endif
+
+ // TODO: Test for equivalence.
+
+ if (t->isOverloaded()) {
+ for (ty_iterator i = t->begin(); i != t->end(); ++i) {
+ if (equivalent(old_t, *i)) {
+ *i = new_t;
+ return;
+ }
+ }
+
+ // An error, the type was not found.
+ assert("unreachable code" == 0);
+
+ } else {
+#ifdef DEBUG_CACHE
+ assert(equivalent(old_t, t));
+#endif
+ t = new_t;
+ }
+
+#ifdef DEBUG_CACHE
+ assert(t != 0);
+ RIGHTKIND(t);
+#endif
+}
+
+#ifdef DEBUG_CACHE
+void venv::namevalue::popType(ty *s)
+#else
+void venv::namevalue::popType()
+#endif
+{
+#ifdef DEBUG_CACHE
+ assert(t);
+ RIGHTKIND(t);
+ assert(!s->isOverloaded());
+#endif
+
+ if (t->isOverloaded()) {
+ ty_vector& set=((overloaded *)t)->sub;
+
+#ifdef DEBUG_CACHE
+ assert(set.size() > 0);
+ assert(equivalent(set.back(), s));
+#endif
+
+ // We are relying on the fact that this was the last type added to t, and
+ // that type are added by pushing them on the end of the vector.
+ set.pop_back();
+
+ if (set.size() == 1)
+ t = set.front();
+ } else {
+#ifdef DEBUG_CACHE
+ assert(equivalent(t, s));
+#endif
+ t = 0;
+ }
+
+ RIGHTKIND(t);
+
+ // Don't try to reduce numFormals as I doubt it is worth the cost of
+ // recalculating.
+}
+
+void venv::remove(const addition& a) {
+ CHECKNAME(a.name);
+
+ if (a.shadowed) {
+ varEntry *popEnt = core.store(a.name, a.shadowed);
+
+ DEBUG_CACHE_ASSERT(popEnt);
+
+ // Unshadow the previously shadowed varEntry.
+ names[a.name].replaceType(a.shadowed->getType(), popEnt->getType());
+ }
+ else {
+ // Remove the (name,sig) key completely.
+#if DEBUG_CACHE
+ varEntry *popEnt = core.lookup(a.name, a.t);
+ assert(popEnt);
+ names[a.name].popType(popEnt->getType());
+#else
+ names[a.name].popType();
+#endif
+
+ core.remove(a.name, a.t);
+ }
+
+ CHECKNAME(a.name);
+}
+
+void venv::beginScope() {
+ if (core.empty()) {
+ assert(scopesizes.empty());
+ ++empty_scopes;
+ } else {
+ scopesizes.push(additions.size());
+ }
+}
+
+void venv::endScope() {
+ if (scopesizes.empty()) {
+ // The corresponding beginScope happened when the venv was empty, so
+ // clear the hash tables to return to that state.
+ core.clear();
+ names.clear();
+
+ assert(empty_scopes > 0);
+ --empty_scopes;
+ } else {
+ size_t scopesize = scopesizes.top();
+ assert(additions.size() >= scopesize);
+ while (additions.size() > scopesize) {
+ remove(additions.top());
+ additions.pop();
+ }
+ scopesizes.pop();
+ }
+}
+
+// Adds the definitions of the top-level scope to the level underneath,
+// and then removes the top scope.
+void venv::collapseScope() {
+ if (scopesizes.empty()) {
+ // Collapsing an empty scope.
+ assert(empty_scopes > 0);
+ --empty_scopes;
+ } else {
+ // As scopes are stored solely by the number of entries at the beginning
+ // of the scope, popping the top size will put all of the entries into the
+ // next scope down.
+ scopesizes.pop();
+ }
+}
+
+
+void venv::enter(symbol name, varEntry *v)
+{
+ CHECKNAME(name);
+
+ // Store the new variable. If it shadows an older variable, that varEntry
+ // will be returned.
+ varEntry *shadowed = core.store(name, v);
+
+ ty *t = v->getType();
+
+ // Record the addition, so it can be undone during endScope.
+ if (!scopesizes.empty())
+ additions.push(addition(name, t, shadowed));
+
+ if (shadowed)
+ // The new value shadows an old value. They have the same signature, but
+ // possibly different return types. If necessary, update the type stored
+ // by name.
+ names[name].replaceType(t, shadowed->getType());
+ else
+ // Add to the names hash table.
+ names[name].addType(t);
+
+ CHECKNAME(name);
+}
+
+
+varEntry *venv::lookBySignature(symbol name, signature *sig) {
+ // Rest arguments are complicated and rare. Don't handle them here.
+ if (sig->hasRest())
+ return 0;
+
+ // Likewise with the special operators.
+ if (name.special())
+ return 0;
+
+ namevalue& nv = names[name];
+
+ // Avoid ambiguities with default parameters.
+ if (nv.maxFormals != sig->getNumFormals())
+ return 0;
+
+ // See if this exactly matches a function in the table.
+ varEntry *ve = core.lookupNonSpecial(name, sig);
+
+ if (!ve)
+ return 0;
+
+ // Keyword-only arguments may cause matching to fail.
+ if (ve->getSignature()->numKeywordOnly > 0)
+ return 0;
+
+ // At this point, any function with an equivalent signature will be equal
+ // to the result of the normal overloaded function resolution. We may
+ // safely return it.
+ return ve;
+}
+
+void venv::add(venv& source, varEntry *qualifier, coder &c)
+{
+ core_venv::const_iterator end = source.core.end();
+ for (core_venv::const_iterator p = source.core.begin(); p != end; ++p)
+ {
+ DEBUG_CACHE_ASSERT(p->filled());
+
+ varEntry *v=p->ent;
+ if (v->checkPerm(READ, c)) {
+ enter(p->name, qualifyVarEntry(qualifier, v));
+ }
+ }
+}
+
+bool venv::add(symbol src, symbol dest,
+ venv& source, varEntry *qualifier, coder &c)
+{
+ ty *t=source.getType(src);
+
+ if (!t)
+ return false;
+
+ if (t->isOverloaded()) {
+ bool added=false;
+ for (ty_iterator i = t->begin(); i != t->end(); ++i)
+ {
+ varEntry *v=source.lookByType(src, *i);
+ if (v->checkPerm(READ, c)) {
+ enter(dest, qualifyVarEntry(qualifier, v));
+ added=true;
+ }
+ }
+ return added;
+ }
+ else {
+ varEntry *v=source.lookByType(src, t);
+ if (v->checkPerm(READ, c)) {
+ enter(dest, qualifyVarEntry(qualifier, v));
+ return true;
+ }
+ return false;
+ }
+}
+
+
+ty *venv::getType(symbol name)
+{
+ return names[name].t;
+}
+
+void listValue(symbol name, varEntry *v, record *module)
+{
+ if (!module || v->whereDefined() == module)
+ {
+ if (settings::getSetting<bool>("where"))
+ cout << v->getPos();
+
+ v->getType()->printVar(cout, name);
+
+ cout << ";\n";
+ }
+}
+
+void venv::listValues(symbol name, record *module)
+{
+ ty *t=getType(name);
+
+ if (t->isOverloaded())
+ for (ty_iterator i = t->begin(); i != t->end(); ++i)
+ listValue(name, lookByType(name, *i), module);
+ else
+ listValue(name, lookByType(name, t), module);
+
+ flush(cout);
+}
+
+void venv::list(record *module)
+{
+ // List all functions and variables.
+ for (namemap::iterator N = names.begin(); N != names.end(); ++N)
+ listValues(N->first, module);
+}
+
+void venv::completions(mem::list<symbol >& l, string start)
+{
+ for(namemap::iterator N = names.begin(); N != names.end(); ++N)
+ if (prefix(start, N->first) && N->second.t)
+ l.push_back(N->first);
+}
+
+#endif /* not NOHASH */
+
+} // namespace trans
diff --git a/graphics/asymptote/entry.h b/graphics/asymptote/entry.h
new file mode 100644
index 0000000000..0c1441c6a0
--- /dev/null
+++ b/graphics/asymptote/entry.h
@@ -0,0 +1,535 @@
+/*****
+ * entry.h
+ * Andy Hammerlindl 2002/08/29
+ *
+ * All variables, built-in functions and user-defined functions reside
+ * within the same namespace. To keep track of all these, a table of
+ * "entries" is used.
+ *****/
+
+#ifndef ENTRY_H
+#define ENTRY_H
+
+#include <iostream>
+
+#include "common.h"
+#include "frame.h"
+#include "table.h"
+#include "types.h"
+#include "modifier.h"
+
+using sym::symbol;
+using types::ty;
+using types::signature;
+
+// Forward declaration.
+namespace types {
+class record;
+}
+using types::record;
+
+namespace trans {
+
+// An entry is associated to a name in the (variable or type) environment, and
+// has permission based on the enclosing records where it was defined or
+// imported.
+class entry : public gc {
+ struct pr {
+ permission perm;
+ record *r;
+
+ pr(permission perm, record *r)
+ : perm(perm), r(r) {}
+
+ // Returns true if the permission allows access in this context.
+ bool check(action act, coder &c);
+
+ // Reports an error if permission is not allowed.
+ void report(action act, position pos, coder &c);
+ };
+
+ mem::list<pr> perms;
+
+ void addPerm(permission perm, record *r) {
+ // Only store restrictive permissions.
+ if (perm != PUBLIC && r)
+ perms.push_back(pr(perm,r));
+ }
+
+ // The record where the variable or type is defined, or 0 if the entry is
+ // not a field.
+ record *where;
+
+ // The location (file and line number) where the entry was defined.
+ position pos;
+
+public:
+ entry(record *where, position pos) : where(where), pos(pos) {}
+ entry(permission perm, record *r, record *where, position pos)
+ : where(where), pos(pos) {
+ addPerm(perm, r);
+ }
+
+ // (Non-destructively) merges two entries, appending permission lists.
+ // The 'where' member is taken from the second entry.
+ entry(entry &e1, entry &e2);
+
+ // Create an entry with one more permission in the list.
+ entry(entry &base, permission perm, record *r);
+
+ bool checkPerm(action act, coder &c);
+ void reportPerm(action act, position pos, coder &c);
+
+ record *whereDefined() {
+ return where;
+ }
+
+ position getPos() {
+ return pos;
+ }
+};
+
+class varEntry : public entry {
+ ty *t;
+ access *location;
+
+public:
+ varEntry(ty *t, access *location, record *where, position pos)
+ : entry(where, pos), t(t), location(location) {}
+
+ varEntry(ty *t, access *location, permission perm, record *r,
+ record *where, position pos)
+ : entry(perm, r, where, pos), t(t), location(location) {}
+
+ // (Non-destructively) merges two varEntries, creating a qualified varEntry.
+ varEntry(varEntry &qv, varEntry &v);
+
+ ty *getType()
+ { return t; }
+
+ signature *getSignature()
+ {
+ return t->getSignature();
+ }
+
+ access *getLocation()
+ { return location; }
+
+ frame *getLevel();
+
+ // Encodes the access, but also checks permissions.
+ void encode(action act, position pos, coder &c);
+ void encode(action act, position pos, coder &c, frame *top);
+};
+
+varEntry *qualifyVarEntry(varEntry *qv, varEntry *v);
+
+// As looked-up types can be allocated in a new expression, we need to know
+// what frame they should be allocated on. Type entries store this extra
+// information along with the type.
+class tyEntry : public entry {
+public:
+ ty *t;
+ varEntry *v; // NOTE: Name isn't very descriptive.
+
+ tyEntry(ty *t, varEntry *v, record *where, position pos)
+ : entry(where, pos), t(t), v(v) {}
+
+ tyEntry(tyEntry *base, permission perm, record *r)
+ : entry(*base, perm, r), t(base->t), v(base->v) {}
+
+ // Records need a varEntry that refers back to the qualifier qv; i.e. in
+ // the last new of the code
+ // struct A {
+ // struct B {}
+ // }
+ // A a=new A;
+ // unravel a;
+ // new B;
+ // we need to put a's frame on the stack before allocating an instance of B.
+ // NOTE: A possible optimization could be to only qualify the varEntry if
+ // the type is a record, as other types don't use the varEntry.
+private:
+ tyEntry(tyEntry *base, varEntry *qv)
+ : entry(*base, *qv), t(base->t), v(qualifyVarEntry(qv, base->v)) {}
+
+public:
+ // Since the constructor can only be used when qv is non-null it is private
+ // for safety reasons, and we provide this method instead.
+ friend tyEntry *qualifyTyEntry(varEntry *qv, tyEntry *ent);
+};
+
+inline tyEntry *qualifyTyEntry(varEntry *qv, tyEntry *ent) {
+ return qv ? new tyEntry(ent, qv) : ent;
+}
+
+// The type environment.
+class tenv : public sym::table<tyEntry *> {
+ bool add(symbol dest, names_t::value_type &x, varEntry *qualifier,
+ coder &c);
+public:
+ // Add the entries in one environment to another, if qualifier is
+ // non-null, it is a record and the source environment is its types. The
+ // coder is used to see which entries are accessible and should be added.
+ void add(tenv& source, varEntry *qualifier, coder &c);
+
+ // Adds entries of the name src in source as the name dest, returning true if
+ // any were added.
+ bool add(symbol src, symbol dest,
+ tenv& source, varEntry *qualifier, coder &c);
+};
+
+#if 0 //{{{
+ /* This version of venv is provided for compiling on systems which do not
+ * have some form of STL hash table. It will eventually be removed.
+ * See the hash version below for documentation on the functions.
+ */
+/*NOHASH*/ class venv : public sym::table<varEntry*> {
+/*NOHASH*/ public:
+/*NOHASH*/ venv() {}
+/*NOHASH*/
+/*NOHASH*/ struct file_env_tag {};
+/*NOHASH*/ venv(file_env_tag) {}
+/*NOHASH*/
+/*NOHASH*/ void add(venv& source, varEntry *qualifier, coder &c);
+/*NOHASH*/
+/*NOHASH*/ bool add(symbol src, symbol dest,
+/*NOHASH*/ venv& source, varEntry *qualifier, coder &c);
+/*NOHASH*/
+/*NOHASH*/ varEntry *lookByType(symbol name, ty *t);
+/*NOHASH*/
+/*NOHASH*/ varEntry *lookBySignature(symbol name, signature *sig) {
+/*NOHASH*/ // This optimization is not implemented for the NOHASH version.
+/*NOHASH*/ return 0;
+/*NOHASH*/ }
+/*NOHASH*/
+/*NOHASH*/ ty *getType(symbol name);
+/*NOHASH*/
+/*NOHASH*/ friend std::ostream& operator<< (std::ostream& out,
+/*NOHASH*/ const venv& ve);
+/*NOHASH*/
+/*NOHASH*/ void list(record *module=0);
+/*NOHASH*/ };
+
+//}}}
+#else
+
+// For speed reasons, many asserts are only tested when DEBUG_CACHE is set.
+#ifdef DEBUG_CACHE
+#define DEBUG_CACHE_ASSERT(x) assert(x)
+#else
+#define DEBUG_CACHE_ASSERT(x) (void)(x)
+#endif
+
+// The hash table which is at the core of the variable environment venv.
+class core_venv : public gc {
+
+public:
+ // The cells of the table
+ struct cell {
+ symbol name;
+ varEntry *ent;
+
+ bool empty() const {
+ return name == 0;
+ }
+
+ bool isATomb() const {
+ DEBUG_CACHE_ASSERT(!empty());
+ return ent == 0;
+ }
+
+ bool filled() const {
+ return !empty() and !isATomb();
+ }
+
+ bool matches(symbol name, const ty *t) {
+ DEBUG_CACHE_ASSERT(name.special());
+ DEBUG_CACHE_ASSERT(t);
+
+ if (this->name != name)
+ return false;
+ if (!this->ent)
+ return false;
+ return equivalent(this->ent->getType(), t);
+ }
+
+ bool matches(symbol name, const signature *sig) {
+ DEBUG_CACHE_ASSERT(!name.special());
+
+ if (this->name != name)
+ return false;
+ if (!this->ent)
+ return false;
+ return equivalent(this->ent->getSignature(), sig);
+ }
+
+ void storeNew(symbol name, varEntry *ent) {
+ DEBUG_CACHE_ASSERT(empty() || isATomb());
+
+ this->name = name;
+ this->ent = ent;
+ }
+
+ varEntry *replaceWith(symbol name, varEntry *ent) {
+ this->name = name;
+
+ varEntry *old = this->ent;
+ this->ent = ent;
+ return old;
+ }
+
+ void remove() {
+ this->ent = 0;
+ }
+ };
+
+private:
+ size_t capacity;
+ size_t size;
+ size_t mask;
+ cell *table;
+
+ void initTable(size_t capacity);
+
+ void resize();
+
+ cell& cellByIndex(size_t i);
+
+ const cell& cellByIndex(size_t i) const;
+
+ varEntry *storeNew(cell& cell, symbol name, varEntry *ent);
+
+ varEntry *storeNonSpecialAfterTomb(size_t tombIndex,
+ symbol name, varEntry *ent);
+ varEntry *storeSpecialAfterTomb(size_t tombIndex,
+ symbol name, varEntry *ent);
+
+public:
+ core_venv(size_t capacity) {
+ initTable(capacity);
+ }
+
+ bool empty() const { return size == 0; }
+ void clear();
+
+ void confirm_size();
+
+ // Store an entry into the table. If this shadows a previous entry, the old
+ // entry is returned, otherwise 0 is returned.
+ varEntry *storeNonSpecial(symbol name, varEntry *ent);
+ varEntry *storeSpecial(symbol name, varEntry *ent);
+ varEntry *store(symbol name, varEntry *ent);
+
+ // Lookup an entry in the table.
+ varEntry *lookupNonSpecial(symbol name, const signature *sig);
+ varEntry *lookupSpecial(symbol name, const ty *t);
+ varEntry *lookup(symbol name, const ty *t);
+
+ // Remove an entry from the table.
+ void removeNonSpecial(symbol name, const signature *sig);
+ void removeSpecial(symbol name, const ty *t);
+ void remove(symbol name, const ty *t);
+
+ // Features for iterating over the entire table.
+ class const_iterator {
+ const core_venv& core;
+ size_t index;
+
+ public:
+ const_iterator(const core_venv& core, size_t index)
+ : core(core), index(index) {}
+
+ const cell& operator * () const {
+ return core.cellByIndex(index);
+ }
+ const cell* operator -> () const {
+ return &core.cellByIndex(index);
+ }
+
+ const_iterator& operator ++ () {
+ // Advance to the next filled cell, or stop at the end of the array.
+ do {
+ ++index;
+ } while (!(*this)->filled() && index < core.capacity);
+
+ DEBUG_CACHE_ASSERT((*this)->filled() || (*this) == core.end());
+
+ return *this;
+ }
+
+ friend bool operator == (const const_iterator& a, const const_iterator& b)
+ {
+ // For speed, we don't compare the hashtables.
+ return a.index == b.index;
+ }
+ friend bool operator != (const const_iterator& a, const const_iterator& b)
+ {
+ // For speed, we don't compare the hashtables.
+ return a.index != b.index;
+ }
+ };
+
+ const_iterator begin() const {
+ size_t index = 0;
+ while (index < capacity && !cellByIndex(index).filled())
+ ++index;
+ return const_iterator(*this, index);
+ }
+
+ const_iterator end() const {
+ return const_iterator(*this, capacity);
+ }
+};
+
+
+// venv implemented with a hash table.
+class venv {
+ // A hash table used to quickly look up a variable once its name and type are
+ // known. Includes all scopes.
+ core_venv core;
+
+ // Record of added variables in the order they were added.
+ struct addition {
+ symbol name;
+ ty *t;
+ varEntry *shadowed;
+
+ addition(symbol name, ty *t, varEntry *shadowed)
+ : name(name), t(t), shadowed(shadowed) {}
+ };
+ typedef mem::stack<addition> addstack;
+ addstack additions;
+
+ // A scope can be recorded by the size of the addition stack at the time the
+ // scope began.
+ typedef mem::stack<size_t> scopestack;
+ scopestack scopesizes;
+
+
+ struct namehash {
+ size_t operator()(const symbol name) const {
+ return name.hash();
+ }
+ };
+ struct nameeq {
+ bool operator()(const symbol s, const symbol t) const {
+ return s==t;
+ }
+ };
+
+ struct namevalue {
+ size_t maxFormals;
+ ty *t;
+
+ namevalue() : maxFormals(0), t(0) {}
+
+ void addType(ty *s);
+
+ void replaceType(ty *new_t, ty *old_t);
+
+#if DEBUG_CACHE
+ void popType(ty *tnew);
+#else
+ void popType();
+#endif
+ };
+
+ // A dictionary indexed solely on the name, storing for each name the
+ // current (possibly overloaded) type of the name.
+ // The hash table implementation is slightly faster than the std::map binary
+ // tree implementation, so we use it if we can.
+#ifdef NOHASH
+ typedef mem::map<symbol CONST, namevalue> namemap;
+#else
+ typedef mem::unordered_map<symbol, namevalue, namehash, nameeq> namemap;
+#endif
+ namemap names;
+
+
+ // A sanity check. For a given name, it checks that the type stored in the
+ // names hash table exactly matches with all of the entries of that name
+ // stored in the full hash table.
+ void checkName(symbol name);
+
+ void listValues(symbol name, record *module);
+
+
+ // Helper function for endScope.
+ void remove(const addition& a);
+
+ // These are roughly the size the hashtables will be after loading the
+ // builtin functions and plain module.
+ static const size_t fileCoreSize=1 << 13;
+ static const size_t fileNamesSize=1000;
+
+ // The number of scopes begun (but not yet ended) when the venv was empty.
+ size_t empty_scopes;
+public:
+ venv() :
+ core(1 << 2), empty_scopes(0) {}
+
+ // Most file level modules automatically import plain, so allocate hashtables
+ // big enough to hold it in advance.
+ struct file_env_tag {};
+ venv(file_env_tag)
+ : core(fileCoreSize),
+#ifndef NOHASH
+ names(fileNamesSize),
+#endif
+ empty_scopes(0) {}
+
+ // Add a new variable definition.
+ void enter(symbol name, varEntry *v);
+
+ // Add the entries in one environment to another, if qualifier is
+ // non-null, it is a record and entries of the source environment are its
+ // fields. The coder is necessary to check which variables are accessible and
+ // should be added.
+ void add(venv& source, varEntry *qualifier, coder &c);
+
+ // Add all unshadowed variables from source of the name src as variables
+ // named dest. Returns true if at least one was added.
+ bool add(symbol src, symbol dest,
+ venv& source, varEntry *qualifier, coder &c);
+
+ // Look for a function that exactly matches the type given.
+ varEntry *lookByType(symbol name, ty *t) {
+ return core.lookup(name, t);
+ }
+
+ // An optimization heuristic. Try to guess the signature of a variable and
+ // look it up. This is allowed to return 0 even if the appropriate variable
+ // exists. If it returns a varEntry from an overloaded number of choices,
+ // the returned function must be the one which would be called with
+ // arguments given by sig, and its signature must be equivalent to sig.
+ // For instance, in
+ // int f(int a, int b);
+ // int f(int a, int b, int c = 1);
+ // f(a,b);
+ // looking up the signature of 'f' with arguments (int, int) must return 0
+ // as there is an ambiguity. The maxFormals field is used to ensure we
+ // avoid such ambiguities.
+ varEntry *lookBySignature(symbol name, signature *sig);
+
+ // Get the (possibly overloaded) type of all variables associated to a
+ // particular name.
+ ty *getType(symbol name);
+
+ void beginScope();
+ void endScope();
+
+ // Merges the top-level scope with the level immediately underneath it.
+ void collapseScope();
+
+ // Prints a list of the variables to the standard output.
+ void list(record *module=0);
+
+ // Adds to l, all names prefixed by start.
+ void completions(mem::list<symbol>& l, string start);
+};
+#endif
+
+} // namespace trans
+
+#endif //ENTRY_H
diff --git a/graphics/asymptote/env.cc b/graphics/asymptote/env.cc
new file mode 100644
index 0000000000..09d16f21a0
--- /dev/null
+++ b/graphics/asymptote/env.cc
@@ -0,0 +1,217 @@
+/*****
+ * env.cc
+ * Andy Hammerlindl 2002/6/20
+ *
+ * Keeps track of the namespaces of variables and types when traversing
+ * the abstract syntax.
+ *****/
+
+#include "env.h"
+#include "record.h"
+#include "genv.h"
+#include "builtin.h"
+
+using namespace types;
+
+namespace trans {
+
+// Instances of this class are passed to types::ty objects so that they can call
+// back to env when checking casting of subtypes.
+class envCaster : public caster {
+ protoenv &e;
+ symbol name;
+public:
+ envCaster(protoenv &e, symbol name)
+ : e(e), name(name) {}
+
+ access *operator() (ty *target, ty *source) {
+ return e.lookupCast(target, source, name);
+ }
+
+ bool castable(ty *target, ty *source) {
+ return e.castable(target, source, name);
+ }
+};
+
+access *protoenv::baseLookupCast(ty *target, ty *source, symbol name) {
+ static identAccess id;
+
+ assert(target->kind != ty_overloaded &&
+ source->kind != ty_overloaded);
+
+ // If errors already exist, don't report more. This may, however, cause
+ // problems with resoving the signature of an overloaded function. The
+ // abstract syntax should check if any of the parameters had an error before
+ // finding the signature.
+ if (target->kind == ty_error || source->kind == ty_error)
+ return &id;
+ else if (equivalent(target,source))
+ return &id;
+ else {
+ varEntry *v=lookupVarByType(name,new function(target,source));
+ return v ? v->getLocation() : 0;
+ }
+}
+
+access *protoenv::lookupCast(ty *target, ty *source, symbol name) {
+ access *a=baseLookupCast(target, source, name);
+ if (a)
+ return a;
+
+ envCaster ec(*this, name);
+ return source->castTo(target, ec);
+}
+
+bool protoenv::castable(ty *target, ty *source, symbol name) {
+ struct castTester : public tester {
+ protoenv &e;
+ symbol name;
+
+ castTester(protoenv &e, symbol name)
+ : e(e), name(name) {}
+
+ bool base(ty *t, ty *s) {
+ access *a=e.baseLookupCast(t, s, name);
+ if (a)
+ return true;
+
+ envCaster ec(e, name);
+ return s->castable(t, ec);
+ }
+ };
+
+ castTester ct(*this, name);
+ return ct.test(target,source);
+}
+
+bool protoenv::fastCastable(ty *target, ty *source) {
+ assert(target->kind != types::ty_overloaded);
+ assert(target->kind != types::ty_error);
+ assert(source->kind != types::ty_error);
+
+ // To avoid memory allocation, fill one static variable with new parameters
+ // in each call.
+ // Warning: This is not re-entrant if asy ever goes multi-threaded.
+ static types::function castFunc(primVoid(), primVoid());
+ castFunc.result = target;
+
+ if (source->kind == types::ty_overloaded) {
+ bool result = false;
+ types::ty_vector& v = ((overloaded *)source)->sub;
+ for (size_t i = 0; i < v.size(); ++i) {
+ castFunc.sig.formals[0].t = v[i];
+ if (lookupVarByType(symbol::castsym, &castFunc)) {
+ result = true;
+ break;
+ }
+ }
+ //assert(result == castable(target, source, symbol::castsym));
+ //cout << "fc OVERLOADED " << (result ? "CAST" : "FAIL") << endl;
+ return result;
+ }
+ //else cout << "fc SIMPLE" << endl;
+
+ // Don't test for equivalent, as that is already done by the castScore
+ // code. Assert disabled for speed.
+#if 0
+ assert(!equivalent(target, source));
+#endif
+
+ castFunc.sig.formals[0].t = source;
+
+ if (lookupVarByType(symbol::castsym, &castFunc))
+ return true;
+
+ // Test for generic casts of null. This should be moved to a types.h
+ // routine.
+ return source->kind == ty_null && target->isReference();
+}
+
+access *protoenv::fastLookupCast(ty *target, ty *source) {
+ assert(target->kind != types::ty_overloaded);
+ assert(target->kind != types::ty_error);
+ assert(source->kind != types::ty_overloaded);
+ assert(source->kind != types::ty_error);
+
+ // Warning: This is not re-entrant.
+ static types::function castFunc(primVoid(), primVoid());
+ castFunc.result = target;
+ castFunc.sig.formals[0].t = source;
+
+ varEntry *ve = lookupVarByType(symbol::castsym, &castFunc);
+ if (ve)
+ return ve->getLocation();
+
+ // Fall back on slow routine.
+ return lookupCast(target, source, symbol::castsym);
+}
+
+
+ty *protoenv::castTarget(ty *target, ty *source, symbol name) {
+ struct resolver : public collector {
+ protoenv &e;
+ symbol name;
+
+ resolver(protoenv &e, symbol name)
+ : e(e), name(name) {}
+
+ types::ty *base(types::ty *target, types::ty *source) {
+ return e.castable(target, source, name) ? target : 0;
+ }
+ };
+
+ resolver r(*this, name);
+ return r.collect(target, source);
+}
+
+ty *protoenv::castSource(ty *target, ty *source, symbol name) {
+ struct resolver : public collector {
+ protoenv &e;
+ symbol name;
+
+ resolver(protoenv &e, symbol name)
+ : e(e), name(name) {}
+
+ types::ty *base(types::ty *target, types::ty *source) {
+ return e.castable(target, source, name) ? source : 0;
+ }
+ };
+
+ resolver r(*this, name);
+ return r.collect(target, source);
+}
+
+void protoenv::addArrayOps(array *a)
+{
+ trans::addArrayOps(ve, a);
+}
+
+void protoenv::addRecordOps(record *r)
+{
+ trans::addRecordOps(ve, r);
+}
+
+void protoenv::addFunctionOps(function *f)
+{
+ trans::addFunctionOps(ve, f);
+}
+
+env::env(genv &ge)
+ : protoenv(venv::file_env_tag()), ge(ge)
+{
+ // NOTE: May want to make this initial environment into a "builtin" module,
+ // and then import the builtin module.
+ base_tenv(te);
+ base_venv(ve);
+}
+
+env::~env()
+{
+}
+
+record *env::getModule(symbol id, string filename)
+{
+ return ge.getModule(id, filename);
+}
+
+}
diff --git a/graphics/asymptote/env.h b/graphics/asymptote/env.h
new file mode 100644
index 0000000000..7fd7a003e5
--- /dev/null
+++ b/graphics/asymptote/env.h
@@ -0,0 +1,187 @@
+/*****
+ * env.h
+ * Andy Hammerlindl 2002/6/20
+ *
+ * Keeps track of the namespaces of variables and types when traversing
+ * the abstract syntax.
+ *****/
+
+#ifndef ENV_H
+#define ENV_H
+
+#include "errormsg.h"
+#include "entry.h"
+#include "types.h"
+#include "util.h"
+
+namespace types {
+class record;
+}
+
+namespace trans {
+
+using sym::symbol;
+using types::ty;
+using types::function;
+using types::record;
+
+class genv;
+
+// Keeps track of the name bindings of variables and types. This is used for
+// the fields of a record, whereas the derived class env is used for unqualified
+// names in translation.
+class protoenv {
+//protected:
+public:
+ // These tables keep track of type and variable definitions.
+ tenv te;
+ venv ve;
+
+ access *baseLookupCast(ty *target, ty *source, symbol name);
+
+public:
+ // Start an environment for a file-level module.
+ protoenv() {}
+
+ protoenv(venv::file_env_tag tag)
+ : ve(tag) {}
+
+ protoenv(const protoenv&);
+
+ void beginScope()
+ {
+ te.beginScope(); ve.beginScope();
+ }
+ void endScope()
+ {
+ te.endScope(); ve.endScope();
+ }
+ void collapseScope()
+ {
+ te.collapseScope(); ve.collapseScope();
+ }
+
+ tyEntry *lookupTyEntry(symbol s)
+ {
+ return te.look(s);
+ }
+
+ ty *lookupType(symbol s)
+ {
+ tyEntry *ent=lookupTyEntry(s);
+ return ent ? ent->t : 0;
+ }
+
+ varEntry *lookupVarByType(symbol name, ty *t)
+ {
+ // Search in local vars.
+ return ve.lookByType(name, t);
+ }
+
+ varEntry *lookupVarBySignature(symbol name, types::signature *sig)
+ {
+ return ve.lookBySignature(name, sig);
+ }
+
+ access *lookupInitializer(ty *t)
+ {
+ // The initializer's type is a function returning the desired type.
+ function *it=new function(t);
+ varEntry *v=lookupVarByType(symbol::initsym,it);
+
+ // If not in the environment, try the type itself.
+ return v ? v->getLocation() : t->initializer();
+ }
+
+ // Find the function that handles casting between the types.
+ // The name is "operator cast" for implicit casting and "operator ecast" for
+ // explicit.
+ access *lookupCast(ty *target, ty *source, symbol name);
+ bool castable(ty *target, ty *source, symbol name);
+
+ // A cast lookup designed to work quickly with the application matching
+ // code. The target type must not be overloaded.
+ bool fastCastable(ty *target, ty *source);
+
+ // For the lookup, neither target nor source may be overloaded.
+ access *fastLookupCast(ty *target, ty *source);
+
+ // Given overloaded types, this resolves which types should be the target and
+ // the source of the cast.
+ ty *castTarget(ty *target, ty *source, symbol name);
+ ty *castSource(ty *target, ty *source, symbol name);
+
+ ty *varGetType(symbol name)
+ {
+ return ve.getType(name);
+ }
+
+ void addType(symbol name, tyEntry *desc)
+ {
+ te.enter(name, desc);
+ }
+
+ void addVar(symbol name, varEntry *desc)
+ {
+ // Don't check for multiple variables, as this makes adding casts
+ // and initializers harder.
+ ve.enter(name, desc);
+ }
+
+ // Add another environment, say from a record.
+ void add(protoenv &source, varEntry *qualifier, coder &c)
+ {
+ te.add(source.te, qualifier, c);
+ ve.add(source.ve, qualifier, c);
+ }
+
+ // Add variables and types of name src from another environment under the
+ // name dest in this environment.
+ bool add(symbol src, symbol dest,
+ protoenv &source, varEntry *qualifier, coder &c)
+ {
+ return te.add(src, dest, source.te, qualifier, c) |
+ ve.add(src, dest, source.ve, qualifier, c);
+ }
+
+ // Add the standard functions for a new type.
+ void addArrayOps(types::array *t);
+ void addRecordOps(types::record *r);
+ void addFunctionOps(types::function *f);
+
+ void list(record *r=0)
+ {
+ ve.list(r);
+ }
+
+ // Adds to a list the keywords in the environment that start with the given
+ // prefix. Used for automatic completion at the interactive prompt.
+ typedef mem::list<symbol> symbol_list;
+ void completions(symbol_list &l, string start)
+ {
+ te.completions(l, start);
+ ve.completions(l, start);
+ }
+
+private: // Non-copyable
+ void operator=(const protoenv&);
+};
+
+// Environment used in translating statements and expressions at all scopes. As
+// opposed to protoenv which is suitable for keeping track of the fields of
+// records, this also keeps track of the global env, for loading modules.
+class env : public protoenv {
+ // The global environment - keeps track of modules.
+ genv &ge;
+public:
+ // Start an environment for a file-level module.
+ env(genv &ge);
+
+ ~env();
+
+ record *getModule(symbol id, string filename);
+};
+
+} // namespace trans
+
+#endif
diff --git a/graphics/asymptote/envcompleter.cc b/graphics/asymptote/envcompleter.cc
new file mode 100644
index 0000000000..9477a77f3c
--- /dev/null
+++ b/graphics/asymptote/envcompleter.cc
@@ -0,0 +1,58 @@
+/*****
+ * envcompleter.cc
+ * Andy Hammerlindl 2006/07/31
+ *
+ * Implements a text completion function for readline based on symbols in the
+ * environment.
+ *****/
+
+#include <fstream>
+
+#include "table.h"
+#include "envcompleter.h"
+
+namespace trans {
+
+bool basicListLoaded=false;
+envCompleter::symbol_list basicList;
+
+static void loadBasicList() {
+ assert(basicListLoaded==false);
+
+#define ADD(word) basicList.push_back(symbol::literalTrans(#word))
+#include "keywords.cc"
+#undef ADD
+
+ basicListLoaded=true;
+}
+
+void envCompleter::basicCompletions(symbol_list &l, string start) {
+ if (!basicListLoaded)
+ loadBasicList();
+
+ for (symbol_list::iterator p = basicList.begin(); p != basicList.end(); ++p)
+ if (prefix(start, *p))
+ l.push_back(*p);
+}
+
+void envCompleter::makeList(const char *text) {
+ l.clear();
+ basicCompletions(l, text);
+ e.completions(l, text);
+ index=l.begin();
+}
+
+char *envCompleter::operator () (const char *text, int state) {
+ if (state==0)
+ makeList(text);
+
+ if (index==l.end())
+ return 0;
+ else {
+ symbol name=*index;
+ ++index;
+ return StrdupMalloc((string)name);
+ }
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/envcompleter.h b/graphics/asymptote/envcompleter.h
new file mode 100644
index 0000000000..8af7f5bff3
--- /dev/null
+++ b/graphics/asymptote/envcompleter.h
@@ -0,0 +1,41 @@
+/*****
+ * envcompleter.h
+ * Andy Hammerlindl 2006/07/31
+ *
+ * Implements a text completion function for readline based on symbols in the
+ * environment.
+ *****/
+
+#ifndef ENVCOMPLETER_H
+#define ENVCOMPLETER_H
+
+#include "env.h"
+#include "interact.h"
+
+namespace trans {
+
+class envCompleter : public interact::completer {
+public:
+ typedef protoenv::symbol_list symbol_list;
+
+private:
+ protoenv &e;
+ symbol_list l;
+ symbol_list::iterator index;
+
+ // These are completions that don't come from the environment, such as
+ // keywords. They are read from the keywords file.
+ static void basicCompletions(symbol_list &l, string start);
+
+ void makeList(const char *text);
+
+public:
+ envCompleter(protoenv &e)
+ : e(e), l(), index(l.end()) {}
+
+ char *operator () (const char *text, int state);
+};
+
+} // namespace trans
+
+#endif // ENVCOMPLETER_H
diff --git a/graphics/asymptote/errormsg.cc b/graphics/asymptote/errormsg.cc
new file mode 100644
index 0000000000..a2b62c7fad
--- /dev/null
+++ b/graphics/asymptote/errormsg.cc
@@ -0,0 +1,110 @@
+/*****
+ * errormsg.cc
+ * Andy Hammerlindl 2002/06/17
+ *
+ * Used in all phases of the compiler to give error messages.
+ *****/
+
+#include <cstdio>
+#include <cstdlib>
+
+#include "errormsg.h"
+
+errorstream em;
+
+position nullPos;
+static nullPosInitializer nullPosInit;
+
+bool errorstream::interrupt=false;
+
+ostream& operator<< (ostream& out, const position& pos)
+{
+ if (!pos)
+ return out;
+
+ out << pos.file->name() << ": ";
+ out << pos.line << "." << pos.column << ": ";
+ return out;
+}
+
+void errorstream::clear()
+{
+ sync();
+ anyErrors = anyWarnings = false;
+}
+
+void errorstream::message(position pos, const string& s)
+{
+ if (floating) out << endl;
+ out << pos << s;
+ floating = true;
+}
+
+void errorstream::compiler(position pos)
+{
+ message(pos,"compiler: ");
+ anyErrors = true;
+}
+
+void errorstream::compiler()
+{
+ message(nullPos,"compiler: ");
+ anyErrors = true;
+}
+
+void errorstream::runtime(position pos)
+{
+ message(pos,"runtime: ");
+ anyErrors = true;
+}
+
+void errorstream::error(position pos)
+{
+ message(pos,"");
+ anyErrors = true;
+}
+
+void errorstream::warning(position pos, string s)
+{
+ message(pos,"warning ["+s+"]: ");
+ anyWarnings = true;
+}
+
+void errorstream::warning(position pos)
+{
+ message(pos,"warning: ");
+ anyWarnings = true;
+}
+
+void errorstream::fatal(position pos)
+{
+ message(pos,"abort: ");
+ anyErrors = true;
+}
+
+void errorstream::trace(position pos)
+{
+ static position lastpos;
+ if(!pos || (pos.match(lastpos.filename()) && pos.match(lastpos.Line())))
+ return;
+ lastpos=pos;
+ message(pos,"");
+ sync();
+}
+
+void errorstream::cont()
+{
+ floating = false;
+}
+
+void errorstream::sync()
+{
+ if (floating) out << endl;
+ floating = false;
+}
+
+void outOfMemory()
+{
+ cerr << "error: out of memory" << endl;
+ exit(1);
+}
diff --git a/graphics/asymptote/errormsg.h b/graphics/asymptote/errormsg.h
new file mode 100644
index 0000000000..22e7f79f1f
--- /dev/null
+++ b/graphics/asymptote/errormsg.h
@@ -0,0 +1,233 @@
+/*****
+ * errormsg.h
+ * Andy Hammerlindl 2002/06/17
+ *
+ * Used in all phases of the compiler to give error messages.
+ *****/
+
+#ifndef ERRORMSG_H
+#define ERRORMSG_H
+
+#include <iostream>
+#include "common.h"
+#include "settings.h"
+
+using std::ostream;
+
+struct handled_error {}; // Exception to process next file.
+struct interrupted {}; // Exception to interrupt execution.
+struct quit {}; // Exception to quit current operation.
+struct eof {}; // Exception to exit interactive mode.
+
+class fileinfo : public gc {
+ string filename;
+ size_t lineNum;
+
+public:
+ fileinfo(string filename, size_t lineNum=1)
+ : filename(filename), lineNum(lineNum) {}
+
+ size_t line() const
+ {
+ return lineNum;
+ }
+
+ string name() const {
+ return filename;
+ }
+
+ // The filename without the directory and without the '.asy' suffix.
+ // Note that this assumes name are separated by a forward slash.
+ string moduleName() const {
+ size_t start = filename.rfind('/');
+ if (start == filename.npos)
+ start = 0;
+ else
+ // Step over slash.
+ ++start;
+
+ size_t end = filename.rfind(".asy");
+ if (end != filename.size() - 4)
+ end = filename.size();
+
+ return filename.substr(start, end-start);
+ }
+
+ // Specifies a newline symbol at the character position given.
+ void newline() {
+ ++lineNum;
+ }
+
+};
+
+inline bool operator == (const fileinfo& a, const fileinfo& b)
+{
+ return a.line() == b.line() && a.name() == b.name();
+}
+
+class position : public gc {
+ fileinfo *file;
+ size_t line;
+ size_t column;
+
+public:
+ void init(fileinfo *f, Int p) {
+ file = f;
+ if (file) {
+ line = file->line();
+ column = p;
+ } else {
+ line = column = 0;
+ }
+ }
+
+ string filename() const
+ {
+ return file ? file->name() : "";
+ }
+
+ size_t Line() const
+ {
+ return line;
+ }
+
+ size_t Column() const
+ {
+ return column;
+ }
+
+ std::pair<size_t,size_t>LineColumn() const {
+ return std::pair<size_t,size_t>(line,column);
+ }
+
+ bool match(const string& s) {
+ return file && file->name() == s;
+ }
+
+ bool match(size_t l) {
+ return line == l;
+ }
+
+ bool matchColumn(size_t c) {
+ return column == c;
+ }
+
+ bool operator! () const
+ {
+ return (file == 0);
+ }
+
+ friend ostream& operator << (ostream& out, const position& pos);
+
+ // Write out just the module name and line number.
+ void printTerse(ostream& out) const
+ {
+ if (file) {
+ out << file->moduleName() << ":" << line;
+ }
+ }
+};
+
+extern position nullPos;
+
+struct nullPosInitializer {
+ nullPosInitializer() {nullPos.init(NULL,0);}
+};
+
+inline bool operator == (const position& a, const position& b)
+{
+ return a.Line() == b.Line() && a.Column() == b.Column() &&
+ a.filename() == b.filename();
+}
+
+string warning(string s);
+
+class errorstream {
+ ostream& out;
+ bool anyErrors;
+ bool anyWarnings;
+ bool floating; // Was a message output without a terminating newline?
+
+ // Is there an error that warrants the asy process to return 1 instead of 0?
+ bool anyStatusErrors;
+
+public:
+ static bool interrupt; // Is there a pending interrupt?
+
+ errorstream(ostream& out = cerr)
+ : out(out), anyErrors(false), anyWarnings(false), floating(false),
+ anyStatusErrors(false) {}
+
+
+ void clear();
+
+ void message(position pos, const string& s);
+
+ void Interrupt(bool b) {
+ interrupt=b;
+ }
+
+ // An error is encountered, not in the user's code, but in the way the
+ // compiler works! This may be augmented in the future with a message
+ // to contact the compiler writers.
+ void compiler();
+ void compiler(position pos);
+
+ // An error encountered when running compiled code. This method does
+ // not stop the executable, but the executable should be stopped
+ // shortly after calling this method.
+ void runtime(position pos);
+
+ // Errors encountered when compiling making it impossible to run the code.
+ void error(position pos);
+
+ // Indicate potential problems in the code, but the code is still usable.
+ void warning(position pos);
+ void warning(position pos, string s);
+
+ // Single a fatal error and execute the main process.
+ void fatal(position pos);
+
+ // Print out position in code to aid debugging.
+ void trace(position pos);
+
+ // Sends stuff to out to print.
+ // NOTE: May later make it do automatic line breaking for long messages.
+ template<class T>
+ errorstream& operator << (const T& x) {
+ flush(out);
+ out << x;
+ return *this;
+ }
+
+ // Reporting errors to the stream may be incomplete. This draws the
+ // appropriate newlines or file excerpts that may be needed at the end.
+ void sync();
+
+ void cont();
+
+ bool errors() const {
+ return anyErrors;
+ }
+
+ bool warnings() const {
+ return anyWarnings || errors();
+ }
+
+ void statusError() {
+ anyStatusErrors=true;
+ }
+
+ // Returns true if no errors have occured that should be reported by the
+ // return value of the process.
+ bool processStatus() const {
+ return !anyStatusErrors;
+ }
+};
+
+extern errorstream em;
+void outOfMemory();
+
+GC_DECLARE_PTRFREE(nullPosInitializer);
+
+#endif
diff --git a/graphics/asymptote/errors b/graphics/asymptote/errors
new file mode 100644
index 0000000000..d9b46b6ed9
--- /dev/null
+++ b/graphics/asymptote/errors
@@ -0,0 +1,157 @@
+errortest.asy: 476.34: unnamed argument after rest argument
+errortest.asy: 477.37: additional rest argument
+errortest.asy: 478.28: unnamed argument after rest argument
+errortest.asy: 479.31: additional rest argument
+errortest.asy: 482.22: normal parameter after rest parameter
+errortest.asy: 483.22: normal parameter after rest parameter
+errortest.asy: 484.31: normal parameter after rest parameter
+errortest.asy: 485.31: normal parameter after rest parameter
+errortest.asy: 486.24: normal parameter after keyword-only parameter
+errortest.asy: 487.24: normal parameter after keyword-only parameter
+errortest.asy: 488.24: normal parameter after keyword-only parameter
+errortest.asy: 488.31: normal parameter after keyword-only parameter
+errortest.asy: 489.24: normal parameter after keyword-only parameter
+errortest.asy: 489.31: normal parameter after keyword-only parameter
+errortest.asy: 490.32: normal parameter after keyword-only parameter
+errortest.asy: 491.32: normal parameter after keyword-only parameter
+errortest.asy: 492.32: normal parameter after keyword-only parameter
+errortest.asy: 492.39: normal parameter after keyword-only parameter
+errortest.asy: 493.32: normal parameter after keyword-only parameter
+errortest.asy: 493.39: normal parameter after keyword-only parameter
+errortest.asy: 496.13: expected 'keyword' here
+errortest.asy: 497.13: expected 'keyword' here
+errortest.asy: 498.21: expected 'keyword' here
+errortest.asy: 499.21: expected 'keyword' here
+errortest.asy: 500.36: expected 'keyword' here
+errortest.asy: 500.32: normal parameter after keyword-only parameter
+errortest.asy: 501.36: expected 'keyword' here
+errortest.asy: 501.32: normal parameter after keyword-only parameter
+errortest.asy: 502.21: expected 'keyword' here
+errortest.asy: 503.21: expected 'keyword' here
+errortest.asy: 504.13: expected 'keyword' here
+errortest.asy: 505.13: expected 'keyword' here
+errortest.asy: 506.13: expected 'keyword' here
+errortest.asy: 507.13: expected 'keyword' here
+errortest.asy: 508.13: expected 'keyword' here
+errortest.asy: 509.13: expected 'keyword' here
+errortest.asy: 510.21: expected 'keyword' here
+errortest.asy: 511.21: expected 'keyword' here
+errortest.asy: 512.21: expected 'keyword' here
+errortest.asy: 513.21: expected 'keyword' here
+errortest.asy: 12.4: no matching variable 'x.y'
+errortest.asy: 16.11: no matching variable of name 'z'
+errortest.asy: 20.3: no matching variable 'x'
+errortest.asy: 27.3: no type of name 'x'
+errortest.asy: 28.3: no type of name 'x'
+errortest.asy: 29.3: no type of name 'x'
+errortest.asy: 30.10: no type of name 'x'
+errortest.asy: 32.5: no type of name 'x'
+errortest.asy: 33.5: no type of name 'x'
+errortest.asy: 34.5: no type of name 'x'
+errortest.asy: 35.12: no type of name 'x'
+errortest.asy: 41.4: no matching variable 'x.y'
+errortest.asy: 48.6: no matching variable 'm.u.v'
+errortest.asy: 55.12: no matching field of name 'z' in 'm'
+errortest.asy: 62.4: no matching variable 'm.z'
+errortest.asy: 75.4: no matching field or type of name 'u' in 'm'
+errortest.asy: 77.5: no matching field or type of name 'u' in 'm'
+errortest.asy: 84.3: expression cannot be used as an address
+errortest.asy: 89.3: use of variable 'f' is ambiguous
+errortest.asy: 91.4: use of variable 'm.f' is ambiguous
+errortest.asy: 97.11: array initializer used for non-array
+errortest.asy: 98.12: array initializer used for non-array
+errortest.asy: 103.4: no matching variable 'f.m'
+errortest.asy: 108.4: no matching variable 'x.m'
+errortest.asy: 116.12: no matching field of name 'z' in 'point'
+errortest.asy: 124.4: no matching variable 'p.z'
+errortest.asy: 132.4: use of variable 'p.f' is ambiguous
+errortest.asy: 140.4: no matching variable 'p.z'
+errortest.asy: 151.4: no matching function 'f()'
+errortest.asy: 152.4: no matching function 'f(string)'
+errortest.asy: 160.4: cannot call 'void f(int)' without parameters
+errortest.asy: 168.7: no matching function 'operator +(point)'
+errortest.asy: 173.10: types in conditional expression do not match
+errortest.asy: 178.10: type of conditional expression is ambiguous
+errortest.asy: 183.5: cannot convert 'int()' to 'int' in assignment
+errortest.asy: 188.5: assignment is ambiguous
+errortest.asy: 194.24: function must return a value
+errortest.asy: 200.11: type 'int' is not a structure
+errortest.asy: 209.3: allocation of struct 'b' is not in a valid scope
+errortest.asy: 219.3: break statement outside of a loop
+errortest.asy: 223.3: continue statement outside of a loop
+errortest.asy: 228.5: function cannot return a value
+errortest.asy: 234.5: function must return a value
+errortest.asy: 241.11: function must return a value
+errortest.asy: 244.11: function must return a value
+errortest.asy: 290.3: built-in functions cannot be modified
+errortest.asy: 298.11: cannot cast 'string' to 'int'
+errortest.asy: 312.4: accessing private field outside of structure
+errortest.asy: 313.4: accessing private field outside of structure
+errortest.asy: 314.4: accessing private field outside of structure
+errortest.asy: 314.4: accessing private field outside of structure
+errortest.asy: 315.4: modifying non-public field outside of structure
+errortest.asy: 316.4: modifying non-public field outside of structure
+errortest.asy: 318.4: accessing private field outside of structure
+errortest.asy: 319.4: accessing private field outside of structure
+errortest.asy: 320.4: accessing private field outside of structure
+errortest.asy: 321.4: modifying non-public field outside of structure
+errortest.asy: 330.18: no matching types or fields of name 'x'
+errortest.asy: 331.18: no matching types or fields of name 'f'
+errortest.asy: 341.3: modifying non-public field outside of structure
+errortest.asy: 342.3: modifying non-public field outside of structure
+errortest.asy: 344.3: modifying non-public field outside of structure
+errortest.asy: 350.4: accessing private field outside of structure
+errortest.asy: 351.4: accessing private field outside of structure
+errortest.asy: 353.4: accessing private field outside of structure
+errortest.asy: 354.4: accessing private field outside of structure
+errortest.asy: 360.18: no matching types or fields of name 'T'
+errortest.asy: 367.4: accessing private field outside of structure
+errortest.asy: 368.4: accessing private field outside of structure
+errortest.asy: 370.4: accessing private field outside of structure
+errortest.asy: 371.4: accessing private field outside of structure
+errortest.asy: 378.18: no matching types or fields of name 'T'
+errortest.asy: 386.11: modifying non-public field outside of structure
+errortest.asy: 387.11: modifying non-public field outside of structure
+errortest.asy: 388.11: modifying non-public field outside of structure
+errortest.asy: 389.11: modifying non-public field outside of structure
+errortest.asy: 393.3: modifying non-public field outside of structure
+errortest.asy: 394.3: modifying non-public field outside of structure
+errortest.asy: 395.3: modifying non-public field outside of structure
+errortest.asy: 396.3: modifying non-public field outside of structure
+errortest.asy: 400.3: modifying non-public field outside of structure
+errortest.asy: 401.3: modifying non-public field outside of structure
+errortest.asy: 402.3: modifying non-public field outside of structure
+errortest.asy: 403.3: modifying non-public field outside of structure
+errortest.asy: 407.11: modifying non-public field outside of structure
+errortest.asy: 408.11: modifying non-public field outside of structure
+errortest.asy: 409.11: modifying non-public field outside of structure
+errortest.asy: 410.11: modifying non-public field outside of structure
+errortest.asy: 411.3: modifying non-public field outside of structure
+errortest.asy: 412.3: modifying non-public field outside of structure
+errortest.asy: 413.3: modifying non-public field outside of structure
+errortest.asy: 414.3: modifying non-public field outside of structure
+errortest.asy: 419.7: inferred variable declaration without initializer
+errortest.asy: 422.20: cannot cast 'int' to 'var'
+errortest.asy: 425.4: cannot cast 'int' to 'var'
+errortest.asy: 426.12: cannot cast 'int' to 'var'
+errortest.asy: 427.12: cannot cast 'var' to 'int'
+errortest.asy: 430.25: cannot cast 'int' to 'var'
+errortest.asy: 430.28: cannot cast 'int' to 'var'
+errortest.asy: 430.31: cannot cast 'int' to 'var'
+errortest.asy: 431.13: cannot cast 'int[]' to 'var[]'
+errortest.asy: 432.14: cannot cast 'int' to 'var'
+errortest.asy: 432.17: cannot cast 'int' to 'var'
+errortest.asy: 432.20: cannot cast 'int' to 'var'
+errortest.asy: 433.15: cannot cast 'int' to 'var'
+errortest.asy: 433.18: cannot cast 'int' to 'var'
+errortest.asy: 433.21: cannot cast 'int' to 'var'
+errortest.asy: 434.13: cannot cast 'var[]' to 'int[]'
+errortest.asy: 435.3: type 'var' is not a structure
+errortest.asy: 438.17: cannot cast 'int' to 'var'
+errortest.asy: 442.7: could not infer type of initializer
+errortest.asy: 446.7: could not infer type of initializer
+errortest.asy: 448.7: could not infer type of initializer
+errortest.asy: 452.16: expression is not an array of inferable type
+errortest.asy: 457.16: expression is not an array of inferable type
+errortest.asy: 463.16: expression is not an array of inferable type
+errortest.asy: 470.7: array expression cannot be used as an address
diff --git a/graphics/asymptote/errortest.asy b/graphics/asymptote/errortest.asy
new file mode 100644
index 0000000000..1e313702f4
--- /dev/null
+++ b/graphics/asymptote/errortest.asy
@@ -0,0 +1,514 @@
+/*****
+ * errortest.asy
+ * Andy Hammerlindl 2003/08/08
+ *
+ * This struct attempts to trigger every error message reportable by the
+ * compiler to ensure that errors are being reported properly.
+ *****/
+
+// name.cc
+{
+ // line 33
+ x.y = 5;
+}
+{
+ // line 50
+ int x = z;
+}
+{
+ // line 67
+ x = 5;
+}
+{
+ // line 84 - unreachable
+}
+{
+ // line 95
+ x y1;
+ x y2();
+ x y3(int);
+ int y4(x);
+ struct m {
+ x y1;
+ x y2();
+ x y3(int);
+ int y4(x);
+ }
+}
+{
+ // line 130
+ int x;
+ x.y = 4;
+}
+{
+ // line 156
+ struct m {
+ int x,y;
+ }
+ m.u.v = 5;
+}
+{
+ // line 186
+ struct m {
+ int x,y;
+ }
+ int x = m.z;
+}
+{
+ // line 217
+ struct m {
+ int x,y;
+ }
+ m.z = 5;
+}
+{
+ // line 249 - unreachable
+}
+{
+ // line 272 - not testable without typedef
+}
+{
+ // line 283
+ struct m {
+ int x,y;
+ }
+ m.u v;
+ struct mm {
+ m.u v;
+ }
+}
+
+// exp.h
+{
+ // line 109
+ 5 = 4;
+}
+{
+ // line 136
+ int f, f();
+ f;
+ struct m { int f, f(); }
+ m.f;
+}
+
+// exp.cc
+{
+ // line 40
+ int x = {};
+ int y = {4, 5, 6};
+}
+{
+ // line 110
+ int f(), f(int);
+ f.m = 5;
+}
+{
+ // line 122
+ int x;
+ x.m = 5;
+}
+{
+ // line 147
+ struct point {
+ int x,y;
+ }
+ point p;
+ int x = p.z;
+}
+{
+ // line 157
+ struct point {
+ int x, y;
+ }
+ point p;
+ p.z;
+}
+{
+ // line 163
+ struct point {
+ int f(), f(int);
+ }
+ point p;
+ p.f;
+}
+{
+ // line 204
+ struct point {
+ int x, y;
+ }
+ point p;
+ p.z = 5;
+}
+{
+ // line 229 - unreachable
+}
+{
+ // lines 261 and 275 - wait for subscript to be fully implemented.
+}
+{
+ // line 515
+ void f(int), f(int, int);
+ f();
+ f("Hello?");
+}
+{
+ // line 520 - not yet testable (need int->float casting or the like)
+}
+{
+ // line 525
+ void f(int);
+ f();
+}
+{
+ // line 649
+ struct point {
+ int x,y;
+ }
+ point p;
+ p = +p;
+}
+{
+ // line 1359
+ int x, f();
+ (true) ? x : f;
+}
+{
+ // line 1359
+ int a, a(), b, b();
+ (true) ? a : b;
+}
+{
+ // line 1581
+ int x, f();
+ x = f;
+}
+{
+ // line 1586
+ int a, a(), b, b();
+ a = b;
+}
+
+// newexp.cc
+{
+ // line 34
+ int f() = new int () {
+ int x = 5;
+ };
+}
+{
+ // line 64
+ int x = new int;
+}
+{
+ // line 72
+ struct a {
+ struct b {
+ }
+ }
+
+ new a.b;
+}
+
+// stm.cc
+{
+ // line 86
+ 5;
+}
+{
+ // line 246
+ break;
+}
+{
+ // line 261
+ continue;
+}
+{
+ // line 282
+ void f() {
+ return 17;
+ }
+}
+{
+ // line 288
+ int f() {
+ return;
+ }
+}
+
+// dec.cc
+{
+ // line 378
+ int f() {
+ int x = 5;
+ }
+ int g() {
+ if (true)
+ return 7;
+ }
+}
+
+// env.h
+{
+ // line 99
+ struct m {}
+ struct m {}
+}
+{
+ // line 109
+ int f() {
+ return 1;
+ }
+ int f() {
+ return 2;
+ }
+
+ int x = 1;
+ int x = 2;
+
+ struct m {
+ int f() {
+ return 1;
+ }
+ int f() {
+ return 2;
+ }
+
+ int x = 1;
+ int x = 2;
+ }
+}
+
+// env.cc
+{
+ // line 107 - currently unreachable as no built-ins are currently used
+ // in records.
+}
+{
+ // line 140
+ // Assuming there is a built-in function void abort(string):
+ void f(string);
+ abort = f;
+}
+{
+ // line 168 - currently unreachable as no built-in functions are
+ // currently used in records.
+}
+{
+ // line 222
+ int x = "Hello";
+}
+
+// Test permissions.
+{
+ struct A {
+ private int x=4;
+ restricted int y=5;
+
+ private void f() {}
+ restricted void g() {}
+ }
+
+ A a;
+ a.x;
+ a.x = 4;
+ a.x += 5;
+ a.y = 6;
+ a.y += 7;
+
+ a.f;
+ a.f();
+ a.f = new void() {};
+ a.g = new void() {};
+}
+{
+ struct A {
+ private int x=4;
+ private void f() {}
+ }
+
+ A a;
+ from a unravel x;
+ from a unravel f;
+}
+{
+ struct A {
+ restricted int y=5;
+ restricted void g() {}
+ }
+
+ A a;
+ from a unravel y,g;
+ y = 6;
+ y += 7;
+
+ g = new void() {};
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ A.T x;
+ A.T x=4;
+ int y=2;
+ A.T x=y;
+ A.T x=17+3*y;
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ from A unravel T;
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ A a;
+ a.T x;
+ a.T x=4;
+ int y=2;
+ a.T x=y;
+ a.T x=17+3*y;
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ A a;
+ from a unravel T;
+}
+
+// Read-only settings
+// Ensure that the safe and globalwrite options can't be modified inside the
+// code.
+{
+ access settings;
+ settings.safe=false;
+ settings.safe=true;
+ settings.globalwrite=false;
+ settings.globalwrite=true;
+}
+{
+ from settings access safe, globalwrite;
+ safe=false;
+ safe=true;
+ globalwrite=false;
+ globalwrite=true;
+}
+{
+ from settings access safe as x, globalwrite as y;
+ x=false;
+ x=true;
+ y=false;
+ y=true;
+}
+{
+ import settings;
+ settings.safe=false;
+ settings.safe=true;
+ settings.globalwrite=false;
+ settings.globalwrite=true;
+ safe=false;
+ safe=true;
+ globalwrite=false;
+ globalwrite=true;
+}
+
+// Test cases where var is used outside of type inference.
+{
+ var x;
+}
+{
+ var f() { return 4; }
+}
+{
+ (var)3;
+ var x = (var)3;
+ int y = (var)3;
+}
+{
+ var[] b = new var[] { 1, 2, 3};
+ var[] b = new int[] { 1, 2, 3};
+ var[] c = {1, 2, 3};
+ new var[] { 4, 5, 6};
+ int[] d = new var[] { 4, 5, 6};
+ new var;
+}
+{
+ int f(var x = 3) { return 0; }
+}
+{
+ int f, f();
+ var g = f;
+}
+{
+ struct A { int f, f(); }
+ var g = A.f;
+ A a;
+ var h = a.f;
+}
+{
+ int x;
+ for (var i : x)
+ ;
+}
+{
+ int x, x();
+ for (var i : x)
+ ;
+}
+{
+ int x, x();
+ int[] x = {2,3,4};
+ for (var i : x)
+ ;
+}
+{
+ int[] temp={0};
+ int[] v={0};
+
+ temp[v]= v;
+}
+
+// Keyword and rest errors.
+{
+ int f(string s="" ... int[] a);
+ f(1,2,3 ... new int[] {4,5,6}, "hi");
+ f(1,2,3 ... new int[] {4,5,6} ... new int[] {7,8,9});
+ f(... new int[] {4,5,6}, "hi");
+ f(... new int[] {4,5,6} ... new int[] {7,8,9});
+}
+{
+ int f(... int[] x, int y);
+ int g(... int[] x, int y) { return 7; }
+ int f(string s ... int[] x, int y);
+ int g(string s ... int[] x, int y) { return 7; }
+ int f(int keyword x, int y);
+ int g(int keyword x, int y) { return 7; }
+ int f(int keyword x, int y, string z);
+ int g(int keyword x, int y, string z) { return 7; }
+ int f(real t, int keyword x, int y);
+ int g(real t, int keyword x, int y) { return 7; }
+ int f(real t, int keyword x, int y, string z);
+ int g(real t, int keyword x, int y, string z) { return 7; }
+}
+{
+ int f(int notkeyword x);
+ int g(int notkeyword x) { return 7; }
+ int f(real w, int notkeyword x);
+ int g(real w, int notkeyword x) { return 7; }
+ int f(real w, int keyword y, int notkeyword x);
+ int g(real w, int keyword y, int notkeyword x) { return 7; }
+ int f(real w, int notkeyword y, int keyword x);
+ int g(real w, int notkeyword y, int keyword x) { return 7; }
+ int f(int notkeyword x, int y, string z);
+ int g(int notkeyword x, int y, string z) { return 7; }
+ int f(int notkeyword x, int y);
+ int g(int notkeyword x, int y) { return 7; }
+ int f(int notkeyword x, int y, string z);
+ int g(int notkeyword x, int y, string z) { return 7; }
+ int f(real t, int notkeyword x, int y);
+ int g(real t, int notkeyword x, int y) { return 7; }
+ int f(real t, int notkeyword x, int y, string z);
+ int g(real t, int notkeyword x, int y, string z) { return 7; }
+}
diff --git a/graphics/asymptote/examples/100d.views b/graphics/asymptote/examples/100d.views
new file mode 100644
index 0000000000..82dbb73479
--- /dev/null
+++ b/graphics/asymptote/examples/100d.views
@@ -0,0 +1,21 @@
+VIEW={View A}
+ COO=95.703857421875 -26.603919982910156 122.73419952392578
+ C2C=-0.4144790768623352 0.7603927254676819 0.5000100135803223
+ ROO=141.69743417830577
+ ROLL=13.566625455930614
+ AAC=34.903342413559436
+END
+VIEW={View B}
+ COO=15.9437837600708 -12.494922637939453 67.1521987915039
+ C2C=0.9024380445480347 0.3321097493171692 0.27442431449890137
+ ROO=303.7409567061654
+ ROLL=66.40207458248847
+ AAC=34.903342413559436
+END
+VIEW={View C}
+ COO=-42.11725616455078 -13.32657241821289 18.372915267944336
+ C2C=0.6989848017692566 -0.009704185649752617 0.7150706648826599
+ ROO=444.70718853041143
+ ROLL=78.84753985408712
+ AAC=34.903342413559436
+END
diff --git a/graphics/asymptote/examples/1overx.asy b/graphics/asymptote/examples/1overx.asy
new file mode 100644
index 0000000000..5d9775d44d
--- /dev/null
+++ b/graphics/asymptote/examples/1overx.asy
@@ -0,0 +1,17 @@
+import graph;
+size(200,IgnoreAspect);
+
+real f(real x) {return 1/x;};
+
+bool3 branch(real x)
+{
+ static int lastsign=0;
+ if(x == 0) return false;
+ int sign=sgn(x);
+ bool b=lastsign == 0 || sign == lastsign;
+ lastsign=sign;
+ return b ? true : default;
+}
+
+draw(graph(f,-1,1,branch));
+axes("$x$","$y$",red);
diff --git a/graphics/asymptote/examples/BezierPatch.asy b/graphics/asymptote/examples/BezierPatch.asy
new file mode 100644
index 0000000000..4e3e55cb40
--- /dev/null
+++ b/graphics/asymptote/examples/BezierPatch.asy
@@ -0,0 +1,14 @@
+import three;
+
+size(10cm);
+currentlight=Headlamp;
+
+surface s=surface(patch(new triple[][] {
+ {(0,0,0),(1,0,0),(1,0,0),(2,0,0)},
+ {(0,1,0),(1,0,1),(1,0,1),(2,1,0)},
+ {(0,1,0),(1,0,-1),(1,0,-1),(2,1,0)},
+ {(0,2,0),(1,2,0),(1,2,0),(2,2,0)}}));
+
+draw(s,yellow);
+draw(s.s[0].vequals(0.5),squarecap+2bp+blue,currentlight);
+draw(s.s[0].uequals(0.5),squarecap+2bp+red,currentlight);
diff --git a/graphics/asymptote/examples/BezierSaddle.asy b/graphics/asymptote/examples/BezierSaddle.asy
new file mode 100644
index 0000000000..f6c1d1895f
--- /dev/null
+++ b/graphics/asymptote/examples/BezierSaddle.asy
@@ -0,0 +1,29 @@
+import three;
+
+size(300);
+
+patch p=patch(unstraighten(unitplane.s[0].external()));
+
+p.P[3][0]+=(0,0,1);
+
+p.P[1][0]+=(0,0,1/3);
+p.P[2][0]+=(0,0,2/3);
+p.P[3][1]+=(0,0,2/3);
+p.P[3][2]+=(0,0,1/3);
+
+p.P[2][1]=interp(p.P[2][0],p.P[2][3],1/3);
+p.P[2][2]=interp(p.P[2][0],p.P[2][3],2/3);
+
+p.P[1][1]=interp(p.P[1][0],p.P[1][3],1/3);
+p.P[1][2]=interp(p.P[1][0],p.P[1][3],2/3);
+
+draw(surface(p),red+opacity(0.75));
+
+void dot(triple[][] P) {
+ for(int i=0; i < 4; ++i)
+ for(int j=0; j < 4; ++j) {
+ draw(string(i)+","+string(j),P[i][j],linewidth(1mm));
+ }
+}
+
+dot(surface(p).s[0].P);
diff --git a/graphics/asymptote/examples/BezierSurface.asy b/graphics/asymptote/examples/BezierSurface.asy
new file mode 100644
index 0000000000..62c01a5571
--- /dev/null
+++ b/graphics/asymptote/examples/BezierSurface.asy
@@ -0,0 +1,42 @@
+import three;
+
+string viewpoint="
+COO=-684.0787963867188 206.90650939941406 218.13809204101562
+C2C=0.8244762420654297 -0.563306450843811 0.0540805421769619
+ROO=1009.7407942621448
+ROLL=17.39344555165265
+";
+
+// viewpoint=getstring("viewpoint",viewpoint);
+currentprojection=perspective(viewpoint);
+
+triple[][][] P={
+ {
+ {(-1.6,0,1.875),(-2.3,0,1.875),(-2.7,0,1.875),(-2.7,0,1.65),},
+ {(-1.6,-0.3,1.875),(-2.3,-0.3,1.875),(-2.7,-0.3,1.875),(-2.7,-0.3,1.65),},
+ {(-1.5,-0.3,2.1),(-2.5,-0.3,2.1),(-3,-0.3,2.1),(-3,-0.3,1.65),},
+ {(-1.5,0,2.1),(-2.5,0,2.1),(-3,0,2.1),(-3,0,1.65),}
+ },{
+ {(-2.7,0,1.65),(-2.7,0,1.425),(-2.5,0,0.975),(-2,0,0.75),},
+ {(-2.7,-0.3,1.65),(-2.7,-0.3,1.425),(-2.5,-0.3,0.975),(-2,-0.3,0.75),},
+ {(-3,-0.3,1.65),(-3,-0.3,1.2),(-2.65,-0.3,0.7275),(-1.9,-0.3,0.45),},
+ {(-3,0,1.65),(-3,0,1.2),(-2.65,0,0.7275),(-1.9,0,0.45),}
+ },{
+ {(-2.7,0,1.65),(-2.7,0,1.875),(-2.3,0,1.875),(-1.6,0,1.875),},
+ {(-2.7,0.3,1.65),(-2.7,0.3,1.875),(-2.3,0.3,1.875),(-1.6,0.3,1.875),},
+ {(-3,0.3,1.65),(-3,0.3,2.1),(-2.5,0.3,2.1),(-1.5,0.3,2.1),},
+ {(-3,0,1.65),(-3,0,2.1),(-2.5,0,2.1),(-1.5,0,2.1),}
+ },{
+ {(-2,0,0.75),(-2.5,0,0.975),(-2.7,0,1.425),(-2.7,0,1.65),},
+ {(-2,0.3,0.75),(-2.5,0.3,0.975),(-2.7,0.3,1.425),(-2.7,0.3,1.65),},
+ {(-1.9,0.3,0.45),(-2.65,0.3,0.7275),(-3,0.3,1.2),(-3,0.3,1.65),},
+ {(-1.9,0,0.45),(-2.65,0,0.7275),(-3,0,1.2),(-3,0,1.65),}
+ }
+};
+
+picture pic;
+size(pic,15cm);
+size3(pic,10cm);
+draw(pic,surface(P),blue);
+
+add(embed("label",pic),(0,0),N);
diff --git a/graphics/asymptote/examples/BezierTriangle.asy b/graphics/asymptote/examples/BezierTriangle.asy
new file mode 100644
index 0000000000..2942dbf042
--- /dev/null
+++ b/graphics/asymptote/examples/BezierTriangle.asy
@@ -0,0 +1,10 @@
+import three;
+currentprojection=perspective(-2,5,1);
+
+size(10cm);
+
+surface s=surface((0,0,0)--(3,0,0)--(1.5,3*sqrt(3)/2,0)--cycle,
+ new triple[] {(1.5,sqrt(3)/2,2)});
+
+draw(s,red);
+
diff --git a/graphics/asymptote/examples/Coons.asy b/graphics/asymptote/examples/Coons.asy
new file mode 100644
index 0000000000..9f59d15257
--- /dev/null
+++ b/graphics/asymptote/examples/Coons.asy
@@ -0,0 +1,6 @@
+size(200);
+
+pen[] p={red,green,blue,magenta};
+path g=(0,0){dir(45)}..(1,0)..(1,1)..(0,1)..cycle;
+tensorshade(g,p);
+dot(g);
diff --git a/graphics/asymptote/examples/Gouraud.asy b/graphics/asymptote/examples/Gouraud.asy
new file mode 100644
index 0000000000..d49813e5e6
--- /dev/null
+++ b/graphics/asymptote/examples/Gouraud.asy
@@ -0,0 +1,18 @@
+size(200);
+
+pen[] p={red,green,blue,magenta};
+pair[] z={(-1,0),(0,0),(0,1),(1,0)};
+int[] edges={0,0,0,1};
+gouraudshade(z[0]--z[2]--z[3]--cycle,p,z,edges);
+
+draw(z[0]--z[1]--z[2]--cycle);
+draw(z[1]--z[3]--z[2],dashed);
+
+dot(Label,z[0],W);
+dot(Label,z[1],S);
+dot(Label,z[2],N);
+dot(Label,z[3],E);
+
+label("0",z[0]--z[1],S,red);
+label("1",z[1]--z[2],E,red);
+label("2",z[2]--z[0],NW,red);
diff --git a/graphics/asymptote/examples/Gouraudcontour.asy b/graphics/asymptote/examples/Gouraudcontour.asy
new file mode 100644
index 0000000000..1cf788869a
--- /dev/null
+++ b/graphics/asymptote/examples/Gouraudcontour.asy
@@ -0,0 +1,31 @@
+import graph;
+import palette;
+import contour;
+
+size(200);
+
+int n=100;
+
+real[] x=new real[n];
+real[] y=new real[n];
+real[] f=new real[n];
+
+real F(real a, real b) {return a^2+b^2;}
+
+real r() {return 1.1*(rand()/randMax*2-1);}
+
+for(int i=0; i < n; ++i) {
+ x[i]=r();
+ y[i]=r();
+ f[i]=F(x[i],y[i]);
+}
+
+pen Tickpen=black;
+pen tickpen=gray+0.5*linewidth(currentpen);
+pen[] Palette=BWRainbow();
+
+bounds range=image(x,y,f,Range(0,2),Palette);
+draw(contour(pairs(x,y),f,new real[]{0.25,0.5,1},operator ..));
+
+palette("$f(x,y)$",range,point(NW)+(0,0.5),point(NE)+(0,0.8),Top,Palette,
+ PaletteTicks(Tickpen,tickpen));
diff --git a/graphics/asymptote/examples/Klein.asy b/graphics/asymptote/examples/Klein.asy
new file mode 100644
index 0000000000..99914d9043
--- /dev/null
+++ b/graphics/asymptote/examples/Klein.asy
@@ -0,0 +1,51 @@
+import graph3;
+
+size(469pt);
+
+viewportmargin=0;
+
+currentprojection=perspective(
+camera=(25.0851928432063,-30.3337528952473,19.3728775115443),
+up=Z,
+target=(-0.590622314050054,0.692357205025578,-0.627122488455679),
+zoom=1,
+autoadjust=false);
+
+triple f(pair t) {
+ real u=t.x;
+ real v=t.y;
+ real r=2-cos(u);
+ real x=3*cos(u)*(1+sin(u))+r*cos(v)*(u < pi ? cos(u) : -1);
+ real y=8*sin(u)+(u < pi ? r*sin(u)*cos(v) : 0);
+ real z=r*sin(v);
+ return (x,y,z);
+}
+
+surface s=surface(f,(0,0),(2pi,2pi),8,8,Spline);
+draw(s,lightolive+white,"bottle",render(merge=true));
+
+string lo="$\displaystyle u\in[0,\pi]: \cases{x=3\cos u(1+\sin u)+(2-\cos u)\cos u\cos v,\cr
+y=8\sin u+(2-\cos u)\sin u\cos v,\cr
+z=(2-\cos u)\sin v.\cr}$";
+
+string hi="$\displaystyle u\in[\pi,2\pi]:\\\cases{x=3\cos u(1+\sin u)-(2-\cos u)\cos v,\cr
+y=8\sin u,\cr
+z=(2-\cos u)\sin v.\cr}$";
+
+real h=0.0125;
+
+begingroup3("parametrization");
+draw(surface(xscale(-0.38)*yscale(-0.18)*lo,s,0,1.7,h,bottom=false),
+ "[0,pi]");
+draw(surface(xscale(0.26)*yscale(0.1)*rotate(90)*hi,s,4.9,1.4,h,bottom=false),
+ "[pi,2pi]");
+endgroup3();
+
+begingroup3("boundary");
+draw(s.uequals(0),blue+dashed);
+draw(s.uequals(pi),blue+dashed);
+endgroup3();
+
+add(new void(frame f, transform3 t, picture pic, projection P) {
+ draw(f,invert(box(min(f,P),max(f,P)),P),"frame");
+ });
diff --git a/graphics/asymptote/examples/NURBScurve.asy b/graphics/asymptote/examples/NURBScurve.asy
new file mode 100644
index 0000000000..c4da5c2ff5
--- /dev/null
+++ b/graphics/asymptote/examples/NURBScurve.asy
@@ -0,0 +1,33 @@
+import three;
+
+size(10cm);
+
+currentprojection=perspective(50,80,50);
+
+// Nonrational curve:
+// udegree=3, nu=6;
+real[] knot={0,0,0,0,0.4,0.6,1,1,1,1};
+
+triple[] P={
+ (-31.2061,12.001,6.45082),
+ (-31.3952,14.7353,6.53707),
+ (-31.5909,21.277,6.70051),
+ (-31.4284,25.4933,6.76745),
+ (-31.5413,30.3485,6.68777),
+ (-31.4896,32.2839,6.58385)
+ };
+
+draw(P,knot,green);
+
+// Rational Bezier curve:
+// udegree=3, nu=4;
+real[] knot={0,0,0,0,1,1,1,1};
+path3 g=scale3(20)*(X{Y}..{-X}Y);
+triple[] P={point(g,0),postcontrol(g,0),precontrol(g,1),point(g,1)};
+
+// Optional weights:
+real[] weights=array(P.length,1.0);
+weights[2]=5;
+
+draw(P,knot,weights,red);
+
diff --git a/graphics/asymptote/examples/NURBSsphere.asy b/graphics/asymptote/examples/NURBSsphere.asy
new file mode 100644
index 0000000000..5258c9986d
--- /dev/null
+++ b/graphics/asymptote/examples/NURBSsphere.asy
@@ -0,0 +1,46 @@
+import three;
+
+/* Reference:
+@article{Qin97,
+ title={{Representing quadric surfaces using NURBS surfaces}},
+ author={Qin, K.},
+ journal={Journal of Computer Science and Technology},
+ volume={12},
+ number={3},
+ pages={210--216},
+ year={1997},
+ publisher={Springer}
+}
+*/
+
+size(10cm);
+currentprojection=perspective(5,4,2,autoadjust=false);
+
+// udegree=2, vdegree=3, nu=3, nv=4;
+
+real[] W={2/3,1/3,1};
+real[] w={1,1/3,1/3,1};
+
+// 10 distinct control points
+triple[][] P={{(0,0,1),(-2,-2,1),(-2,-2,-1),(0,0,-1)},
+ {(0,0,1),(2,-2,1),(2,-2,-1),(0,0,-1)},
+ {(0,0,1),(2,2,1),(2,2,-1),(0,0,-1)},
+ {(0,0,1),(-2,2,1),(-2,2,-1),(0,0,-1)}};
+
+P.cyclic=true;
+
+real[][] weights=new real[3][4];
+for(int i=0; i < 3; ++i)
+for(int j=0; j < 4; ++j)
+ weights[i][j]=W[i]*w[j];
+
+real[] uknot={0,0,1/3,1/2,1,1};
+real[] vknot={0,0,0,0,1,1,1,1};
+
+int N=1;
+
+for(int k=0; k < N; ++k)
+for(int i=0; i < 4; ++i)
+ draw(shift(k*Z)*P[i:i+3],uknot,vknot,weights,blue);
+
+// draw(unitsphere,red+opacity(0.1));
diff --git a/graphics/asymptote/examples/NURBSsurface.asy b/graphics/asymptote/examples/NURBSsurface.asy
new file mode 100644
index 0000000000..32df6ff98e
--- /dev/null
+++ b/graphics/asymptote/examples/NURBSsurface.asy
@@ -0,0 +1,62 @@
+import three;
+
+size(10cm);
+
+currentprojection=perspective(50,80,50);
+
+// Nonrational surface:
+// udegree=3, vdegree=3, nu=5, nv=6;
+real[] uknot={0,0,0,0,0.5,1,1,1,1};
+real[] vknot={0,0,0,0,0.4,0.6,1,1,1,1};
+
+triple[][] P={{
+ (-31.2061,12.001,6.45082),
+ (-31.3952,14.7353,6.53707),
+ (-31.5909,21.277,6.70051),
+ (-31.4284,25.4933,6.76745),
+ (-31.5413,30.3485,6.68777),
+ (-31.4896,32.2839,6.58385)
+ },{
+ (-28.279,12.001,7.89625),
+ (-28.4187,14.7353,8.00954),
+ (-28.5633,21.277,8.22422),
+ (-28.4433,25.4933,8.31214),
+ (-28.5266,30.3485,8.20749),
+ (-28.4885,32.2839,8.07099)
+ },{
+ (-20,12.001,10.0379),
+ (-20,14.7353,10.2001),
+ (-20,21.277,10.5076),
+ (-20,25.4933,10.6335),
+ (-20,30.3485,10.4836),
+ (-20,32.2839,10.2881)
+ },{
+ (-11.721,12.001,7.84024),
+ (-11.5813,14.7353,7.95269),
+ (-11.4367,21.277,8.16575),
+ (-11.5567,25.4933,8.25302),
+ (-11.4734,30.3485,8.14915),
+ (-11.5115,32.2839,8.01367)
+ },{
+ (-8.79391,12.001,6.39481),
+ (-8.60483,14.7353,6.48022),
+ (-8.40905,21.277,6.64204),
+ (-8.57158,25.4933,6.70832),
+ (-8.45874,30.3485,6.62943),
+ (-8.51041,32.2839,6.52653)
+ }
+};
+
+draw(P,uknot,vknot,new pen[] {red,green,blue,magenta});
+
+// Rational Bezier patch:
+// udegree=3, vdegree=3, nu=4, nv=4;
+real[] uknot={0,0,0,0,1,1,1,1};
+real[] vknot={0,0,0,0,1,1,1,1};
+triple[][] P=scale3(20)*octant1.P;
+
+// Optional weights:
+real[][] weights=array(P.length,array(P[0].length,1.0));
+weights[0][2]=5.0;
+
+draw(P,uknot,vknot,weights,blue);
diff --git a/graphics/asymptote/examples/Pythagoras.asy b/graphics/asymptote/examples/Pythagoras.asy
new file mode 100644
index 0000000000..f4ea68fe43
--- /dev/null
+++ b/graphics/asymptote/examples/Pythagoras.asy
@@ -0,0 +1,22 @@
+size(0,150);
+import geometry;
+
+real a=3;
+real b=4;
+real c=hypot(a,b);
+
+pair z1=(0,b);
+pair z2=(a,0);
+pair z3=(a+b,0);
+perpendicular(z1,NE,z1--z2,blue);
+perpendicular(z3,NW,blue);
+draw(square((0,0),z3));
+draw(square(z1,z2));
+
+real d=0.3;
+pair v=unit(z2-z1);
+draw(baseline("$a$"),-d*I--z2-d*I,red,Bars,Arrows,PenMargins);
+draw(baseline("$b$"),z2-d*I--z3-d*I,red,Arrows,Bars,PenMargins);
+draw("$c$",z3+z2*I-d*v--z2-d*v,red,Arrows,PenMargins);
+draw("$a$",z3+d--z3+z2*I+d,red,Arrows,Bars,PenMargins);
+draw("$b$",z3+z2*I+d--z3+z3*I+d,red,Arrows,Bars,PenMargins);
diff --git a/graphics/asymptote/examples/PythagoreanTree.asy b/graphics/asymptote/examples/PythagoreanTree.asy
new file mode 100644
index 0000000000..8ea66650bf
--- /dev/null
+++ b/graphics/asymptote/examples/PythagoreanTree.asy
@@ -0,0 +1,20 @@
+size(250);
+
+real a=3;
+real b=4;
+real c=hypot(a,b);
+
+transform ta=shift(c,c)*rotate(-aCos(a/c))*scale(a/c)*shift(-c);
+transform tb=shift(0,c)*rotate(aCos(b/c))*scale(b/c);
+
+picture Pythagorean(int n) {
+ picture pic;
+ fill(pic,scale(c)*unitsquare,1/(n+1)*green+n/(n+1)*brown);
+ if(n == 0) return pic;
+ picture branch=Pythagorean(--n);
+ add(pic,ta*branch);
+ add(pic,tb*branch);
+ return pic;
+}
+
+add(Pythagorean(12));
diff --git a/graphics/asymptote/examples/RiemannSphere.asy b/graphics/asymptote/examples/RiemannSphere.asy
new file mode 100644
index 0000000000..ec1ab7586a
--- /dev/null
+++ b/graphics/asymptote/examples/RiemannSphere.asy
@@ -0,0 +1,47 @@
+import graph3;
+import solids;
+
+currentlight=White;
+defaultrender.merge=true;
+
+size(10cm,0);
+
+pair k=(1,0.2);
+real r=abs(k);
+real theta=angle(k);
+
+real x(real t) { return r^t*cos(t*theta); }
+real y(real t) { return r^t*sin(t*theta); }
+real z(real t) { return 0; }
+
+real u(real t) { return x(t)/(x(t)^2+y(t)^2+1); }
+real v(real t) { return y(t)/(x(t)^2+y(t)^2+1); }
+real w(real t) { return (x(t)^2+y(t)^2)/(x(t)^2+y(t)^2+1); }
+
+real nb=3;
+for (int i=0; i<12; ++i) draw((0,0,0)--nb*(Cos(i*30),Sin(i*30),0),yellow);
+for (int i=0; i<=nb; ++i) draw(circle((0,0,0),i),lightgreen+white);
+
+
+path3 p=graph(x,y,z,-200,40,operator ..);
+path3 q=graph(u,v,w,-200,40,operator ..);
+
+revolution sph=sphere((0,0,0.5),0.5);
+draw(surface(sph),green+white+opacity(0.5));
+
+draw(p,1bp+heavyred);
+draw(q,1bp+heavyblue);
+
+triple
+ A=(0,0,1),
+ B=(u(40),v(40),w(40)),
+ C=(x(40),y(40),z(40));
+
+path3 L=A--C;
+draw(L,1bp+black);
+
+pen p=fontsize(8pt);
+
+dot("$(0,0,1)$",A,N,p);
+dot("$(u,v,w)$",B,E,p);
+dot("$(x,y,0)$",C,E,p);
diff --git a/graphics/asymptote/examples/RiemannSurface.asy b/graphics/asymptote/examples/RiemannSurface.asy
new file mode 100644
index 0000000000..a1f1b66508
--- /dev/null
+++ b/graphics/asymptote/examples/RiemannSurface.asy
@@ -0,0 +1,13 @@
+import graph3;
+import palette;
+
+size(200,300,keepAspect=false);
+//settings.nothin=true;
+
+currentprojection=orthographic(10,10,30);
+currentlight=(10,10,5);
+triple f(pair t) {return (exp(t.x)*cos(t.y),exp(t.x)*sin(t.y),t.y);}
+
+surface s=surface(f,(-4,-2pi),(0,4pi),8,16,Spline);
+s.colors(palette(s.map(zpart),Rainbow()));
+draw(s,render(merge=true));
diff --git a/graphics/asymptote/examples/RiemannSurfaceRoot.asy b/graphics/asymptote/examples/RiemannSurfaceRoot.asy
new file mode 100644
index 0000000000..8cb3af2cfa
--- /dev/null
+++ b/graphics/asymptote/examples/RiemannSurfaceRoot.asy
@@ -0,0 +1,16 @@
+// Riemann surface of z^{1/n}
+import graph3;
+import palette;
+
+int n=3;
+
+size(200,300,keepAspect=false);
+
+currentprojection=orthographic(10,10,30);
+currentlight=(10,10,5);
+triple f(pair t) {return (t.x*cos(t.y),t.x*sin(t.y),t.x^(1/n)*sin(t.y/n));}
+
+surface s=surface(f,(0,0),(1,2pi*n),8,16,Spline);
+s.colors(palette(s.map(zpart),Rainbow()));
+
+draw(s,meshpen=black,render(merge=true));
diff --git a/graphics/asymptote/examples/Sierpinski.asy b/graphics/asymptote/examples/Sierpinski.asy
new file mode 100644
index 0000000000..c0ff04971d
--- /dev/null
+++ b/graphics/asymptote/examples/Sierpinski.asy
@@ -0,0 +1,17 @@
+size(10cm);
+
+// Draw Sierpinski triangle with top vertex A, side s, and depth q.
+void Sierpinski(pair A, real s, int q, bool top=true)
+{
+ pair B=A-(1,sqrt(2))*s/2;
+ pair C=B+s;
+ if(top) fill(A--B--C--cycle);
+ unfill((A+B)/2--(B+C)/2--(A+C)/2--cycle);
+ if(q > 0) {
+ Sierpinski(A,s/2,q-1,false);
+ Sierpinski((A+B)/2,s/2,q-1,false);
+ Sierpinski((A+C)/2,s/2,q-1,false);
+ }
+}
+
+Sierpinski((0,1),1,9);
diff --git a/graphics/asymptote/examples/SierpinskiGasket.asy b/graphics/asymptote/examples/SierpinskiGasket.asy
new file mode 100644
index 0000000000..2e0d4facd6
--- /dev/null
+++ b/graphics/asymptote/examples/SierpinskiGasket.asy
@@ -0,0 +1,31 @@
+size(200);
+import palette;
+import three;
+currentprojection=perspective(8,2,1);
+
+triple[] M={(0,0,1),1/3*(sqrt(8),0,-1),
+ 1/3*((sqrt(8))*Cos(120),(sqrt(8))*Sin(120),-1),
+ 1/3*((sqrt(8))*Cos(240),(sqrt(8))*Sin(240),-1)};
+
+int level=5;
+
+surface s;
+
+void recur(triple p, real u, int l) {
+ if(l < level)
+ for(triple V : M)
+ recur(p+u*V,u/2,l+1);
+ else
+ for(triple V : M) {
+ s.append(surface((p+u*(V+M[0]))--(p+u*(V+M[1]))--(p+u*(V+M[2]))--cycle));
+ s.append(surface((p+u*(V+M[0]))--(p+u*(V+M[2]))--(p+u*(V+M[3]))--cycle));
+ s.append(surface((p+u*(V+M[0]))--(p+u*(V+M[3]))--(p+u*(V+M[1]))--cycle));
+ s.append(surface((p+u*(V+M[3]))--(p+u*(V+M[2]))--(p+u*(V+M[1]))--cycle));
+ }
+}
+
+recur(O,0.5,1);
+
+s.colors(palette(s.map(zpart),Rainbow()));
+
+draw(s,render(merge=true));
diff --git a/graphics/asymptote/examples/SierpinskiSponge.asy b/graphics/asymptote/examples/SierpinskiSponge.asy
new file mode 100644
index 0000000000..c398aa511c
--- /dev/null
+++ b/graphics/asymptote/examples/SierpinskiSponge.asy
@@ -0,0 +1,99 @@
+size(200);
+import palette;
+import three;
+
+currentprojection=orthographic(1,1,1);
+
+triple[] M={
+ (-1,-1,-1),(0,-1,-1),(1,-1,-1),(1,0,-1),
+ (1,1,-1),(0,1,-1),(-1,1,-1),(-1,0,-1),
+ (-1,-1,0),(1,-1,0),(1,1,0),(-1,1,0),
+ (-1,-1,1),(0,-1,1),(1,-1,1),(1,0,1),(1,1,1),(0,1,1),(-1,1,1),(-1,0,1)
+};
+
+surface[] Squares={
+ surface((1,-1,-1)--(1,1,-1)--(1,1,1)--(1,-1,1)--cycle),
+ surface((-1,-1,-1)--(-1,1,-1)--(-1,1,1)--(-1,-1,1)--cycle),
+ surface((1,1,-1)--(-1,1,-1)--(-1,1,1)--(1,1,1)--cycle),
+ surface((1,-1,-1)--(-1,-1,-1)--(-1,-1,1)--(1,-1,1)--cycle),
+ surface((1,-1,1)--(1,1,1)--(-1,1,1)--(-1,-1,1)--cycle),
+ surface((1,-1,-1)--(1,1,-1)--(-1,1,-1)--(-1,-1,-1)--cycle),
+};
+
+int[][] SquaresPoints={
+ {2,3,4,10,16,15,14,9},
+ {0,7,6,11,18,19,12,8},
+ {4,5,6,11,18,17,16,10},
+ {2,1,0,8,12,13,14,9},
+ {12,13,14,15,16,17,18,19},
+ {0,1,2,3,4,5,6,7}
+};
+
+int[][] index={
+ {0,2,4},{0,1},{1,2,4},{2,3},{1,3,4},{0,1},{0,3,4},{2,3},
+ {4,5},{4,5},{4,5},{4,5},
+ {0,2,5},{0,1},{1,2,5},{2,3},{1,3,5},{0,1},{0,3,5},{2,3}
+};
+
+int[] Sponge0=array(n=6,value=1);
+
+int[] eraseFaces(int n, int[] Sponge0) {
+ int[] temp=copy(Sponge0);
+ for(int k : index[n]) {
+ temp[k]=0;
+ }
+ return temp;
+}
+
+int[][] Sponge1=new int[20][];
+for(int n=0; n < 20; ++n) {
+ Sponge1[n]=eraseFaces(n,Sponge0);
+}
+
+int[][] eraseFaces(int n, int[][] Sponge1) {
+ int[][] temp=copy(Sponge1);
+ for(int k : index[n])
+ for(int n1 : SquaresPoints[k])
+ temp[n1][k]=0;
+ return temp;
+}
+
+int[][][] Sponge2=new int[20][][];
+for(int n=0; n < 20; ++n)
+ Sponge2[n]=eraseFaces(n,Sponge1);
+
+int[][][] eraseFaces(int n, int[][][] Sponge2) {
+ int[][][] temp=copy(Sponge2);
+ for(int k : index[n])
+ for(int n2: SquaresPoints[k])
+ for(int n1: SquaresPoints[k])
+ temp[n2][n1][k]=0;
+ return temp;
+}
+
+int[][][][] Sponge3=new int[20][][][];
+for(int n=0; n < 20; ++n)
+ Sponge3[n]=eraseFaces(n,Sponge2);
+
+surface s3;
+real u=2/3;
+for(int n3=0; n3 < 20; ++n3) {
+ surface s2;
+ for(int n2=0; n2 < 20; ++n2) {
+ surface s1;
+ for(int n1=0; n1 < 20; ++n1) {
+ for(int k=0; k < 6; ++k){
+ transform3 T=scale3(u)*shift(M[n1])*scale3(0.5);
+ if(Sponge3[n3][n2][n1][k] > 0) {
+ s1.append(T*Squares[k]);
+ }
+ }
+ }
+ transform3 T=scale3(u)*shift(M[n2])*scale3(0.5);
+ s2.append(T*s1);
+ }
+ transform3 T=scale3(u)*shift(M[n3])*scale3(0.5);
+ s3.append(T*s2);
+}
+s3.colors(palette(s3.map(abs),Rainbow()));
+draw(s3);
diff --git a/graphics/asymptote/examples/advection.asy b/graphics/asymptote/examples/advection.asy
new file mode 100644
index 0000000000..ea993ff0fc
--- /dev/null
+++ b/graphics/asymptote/examples/advection.asy
@@ -0,0 +1,87 @@
+size(0,22cm);
+
+texpreamble("
+\usepackage{bm}
+\def\v{\bm}
+\def\grad{\v\nabla}
+\def\cross{{\v\times}}
+\def\curl{\grad\cross}
+\def\del{\nabla}
+");
+
+defaultpen(fontsize(10pt));
+
+real margin=1.5mm;
+
+object IC=draw("initial condition $\v U_0$",box,(0,1),
+ margin,black,FillDraw(palegray));
+object Adv0=draw("Lagrangian state $\v U(t)$",ellipse,(1,1),
+ margin,red,FillDraw(palered));
+object Adv=draw("Lagrangian prediction $\v U(t+\tau)$",ellipse,(1,0),
+ margin,red,FillDraw(palered));
+object AdvD=draw("diffused parcels",ellipse,(1.8,1),
+ margin,red,FillDraw(palered));
+object Ur=draw("rearranged $\v \widetilde U$",box,(0,0),
+ margin,orange+gray,FillDraw(paleyellow));
+object Ui=draw("interpolated $\v \widetilde U$",box,(1,-1),
+ margin,blue,FillDraw(paleblue));
+object Crank=draw("${\cal L}^{-1}(-\tau){\cal L}(\tau)\v \widetilde U$",
+ box,(0.5,-1),margin,blue,FillDraw(paleblue));
+object CrankR=draw("${\cal L}^{-1}(-\tau){\cal L}(\tau)\v \widetilde U$",
+ box,(0,-1),margin,orange+gray,FillDraw(paleyellow));
+object Urout=draw(minipage("\center{Lagrangian rearranged solution~$\v U_R$}",
+ 100pt),box,(0,-2),margin,orange+gray,
+ FillDraw(paleyellow));
+object Diff=draw("$\v D\del^2 \v \widetilde U$",box,(0.75,-1.5),
+ margin,blue,FillDraw(paleblue));
+object UIout=draw(minipage("\center{semi-Lagrangian solution~$\v U_I$}",80pt),
+ box,(0.5,-2),margin,FillDraw(palered+paleyellow));
+object psi=draw("$\psi=\del^{-2}\omega$",box,(1.6,-1),
+ margin,darkgreen,FillDraw(palegreen));
+object vel=draw("$\v v=\v{\hat z} \cross\grad\psi$",box,(1.6,-0.5),
+ margin,darkgreen,FillDraw(palegreen));
+
+add(new void(frame f, transform t) {
+ pair padv=0.5*(point(Adv0,S,t)+point(Adv,N,t));
+ picture pic;
+ draw(pic,"initialize",point(IC,E,t)--point(Adv0,W,t),RightSide,Arrow,
+ PenMargin);
+ draw(pic,minipage("\flushright{advect: Runge-Kutta}",80pt),
+ point(Adv0,S,t)--point(Adv,N,t),RightSide,red,Arrow,PenMargin);
+ draw(pic,Label("Lagrange $\rightarrow$ Euler",0.45),
+ point(Adv,W,t)--point(Ur,E,t),5LeftSide,orange+gray,
+ Arrow,PenMargin);
+ draw(pic,"Lagrange $\rightarrow$ Euler",point(Adv,S,t)--point(Ui,N,t),
+ RightSide,blue,Arrow,PenMargin);
+ draw(pic,point(Adv,E,t)--(point(AdvD,S,t).x,point(Adv,E,t).y),red,
+ Arrow(Relative(0.7)),PenMargin);
+ draw(pic,minipage("\flushleft{diffuse: multigrid Crank--Nicholson}",80pt),
+ point(Ui,W,t)--point(Crank,E,t),5N,blue,MidArrow,PenMargin);
+ draw(pic,minipage("\flushleft{diffuse: multigrid Crank--Nicholson}",80pt),
+ point(Ur,S,t)--point(CrankR,N,t),LeftSide,orange+gray,Arrow,PenMargin);
+ draw(pic,"output",point(CrankR,S,t)--point(Urout,N,t),RightSide,
+ orange+gray,Arrow,PenMargin);
+ draw(pic,point(Ui,S,t)--point(Diff,N,t),blue,MidArrow,PenMargin);
+ draw(pic,point(Crank,S,t)--point(Diff,N,t),blue,MidArrow,PenMargin);
+ label(pic,"subtract",point(Diff,N,t),12N,blue);
+ draw(pic,Label("Euler $\rightarrow$ Lagrange",0.5),
+ point(Diff,E,t)--(point(AdvD,S,t).x,point(Diff,E,t).y)--
+ (point(AdvD,S,t).x,point(Adv,E,t).y),RightSide,blue,
+ Arrow(position=1.5),PenMargin);
+ dot(pic,(point(AdvD,S,t).x,point(Adv,E,t).y),red);
+ draw(pic,(point(AdvD,S,t).x,point(Adv,E,t).y)--point(AdvD,S,t),red,Arrow,
+ PenMargin);
+ draw(pic,"output",point(Crank,S,t)--point(UIout,N,t),RightSide,brown,Arrow,
+ PenMargin);
+ draw(pic,Label("$t+\tau\rightarrow t$",0.45),
+ point(AdvD,W,t)--point(Adv0,E,t),2.5LeftSide,red,Arrow,PenMargin);
+ draw(pic,point(psi,N,t)--point(vel,S,t),darkgreen,Arrow,PenMargin);
+ draw(pic,Label("self-advection",4.5),point(vel,N,t)--
+ arc((point(vel,N,t).x,point(Adv,E,t).y),5,270,90)--
+ (point(vel,N,t).x,padv.y)--
+ padv,LeftSide,darkgreen,Arrow,PenMargin);
+ draw(pic,Label("multigrid",0.5,S),point(Ui,E,t)--point(psi,W,t),darkgreen,
+ Arrow,PenMargin);
+
+ add(f,pic.fit());
+ });
diff --git a/graphics/asymptote/examples/alignbox.asy b/graphics/asymptote/examples/alignbox.asy
new file mode 100644
index 0000000000..67083b1e2e
--- /dev/null
+++ b/graphics/asymptote/examples/alignbox.asy
@@ -0,0 +1,9 @@
+real margin=1.5mm;
+
+object left=align(object("$x^2$",ellipse,margin),W);
+add(left);
+object right=align(object("$\sin x$",ellipse,margin),4E);
+add(right);
+add(new void(frame f, transform t) {
+ draw(f,point(left,NE,t)--point(right,W,t));
+ });
diff --git a/graphics/asymptote/examples/alignedaxis.asy b/graphics/asymptote/examples/alignedaxis.asy
new file mode 100644
index 0000000000..542dcb9bc6
--- /dev/null
+++ b/graphics/asymptote/examples/alignedaxis.asy
@@ -0,0 +1,107 @@
+import graph;
+
+real Freq=60.0;
+real margin=5mm;
+
+pair exp(pair x) {
+ return exp(x.x)*(cos(x.y)+I*sin(x.y));
+}
+
+real Merr(real x, real w) {
+ real tau=x/(2*Freq);
+ return 20*log(abs((tau*w+tau/(exp(I*2*pi*Freq*tau)-1))*(I*2*pi*Freq)));
+}
+
+real Aerr(real x, real w) {
+ real tau=x/(2*Freq);
+ return degrees((tau*w+tau/(exp(I*2*pi*Freq*tau)-1))*(I*2*pi*Freq));
+}
+
+picture pic1;
+scale(pic1,Log,Linear);
+real Merr1(real x){return Merr(x,1);}
+draw(pic1,graph(pic1,Merr1,1e-4,1),black+1.2);
+
+ylimits(pic1,-60,20);
+yaxis(pic1,"magnitude (dB)",LeftRight,RightTicks(new
+ real[] {-60,-40,-20,0,20}));
+xaxis(pic1,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic1,0,Dotted);
+yequals(pic1,-20,Dotted);
+yequals(pic1,-40,Dotted);
+xequals(pic1,1e-3,Dotted);
+xequals(pic1,1e-2,Dotted);
+xequals(pic1,1e-1,Dotted);
+
+size(pic1,100,100,point(pic1,SW),point(pic1,NE));
+
+label(pic1,"$\theta=1$",point(pic1,N),2N);
+
+frame f1=pic1.fit();
+add(f1);
+
+picture pic1p;
+scale(pic1p,Log,Linear);
+real Aerr1(real x){return Aerr(x,1);}
+draw(pic1p,graph(pic1p,Aerr1,1e-4,1),black+1.2);
+
+ylimits(pic1p,-5,95);
+yaxis(pic1p,"phase (deg)",LeftRight,RightTicks(new real[] {0,45,90}));
+xaxis(pic1p,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic1p,0,Dotted);
+yequals(pic1p,45,Dotted);
+yequals(pic1p,90,Dotted);
+xequals(pic1p,1e-3,Dotted);
+xequals(pic1p,1e-2,Dotted);
+xequals(pic1p,1e-1,Dotted);
+
+size(pic1p,100,100,point(pic1p,SW),point(pic1p,NE));
+
+frame f1p=pic1p.fit();
+f1p=shift(0,min(f1).y-max(f1p).y-margin)*f1p;
+add(f1p);
+
+picture pic2;
+scale(pic2,Log,Linear);
+real Merr2(real x){return Merr(x,0.75);}
+draw(pic2,graph(pic2,Merr2,1e-4,1),black+1.2);
+
+ylimits(pic2,-60,20);
+yaxis(pic2,"magnitude (dB)",LeftRight,RightTicks(new
+ real[] {-60,-40,-20,0,20}));
+xaxis(pic2,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic2,0,Dotted);
+yequals(pic2,-20,Dotted);
+yequals(pic2,-40,Dotted);
+xequals(pic2,1e-3,Dotted);
+xequals(pic2,1e-2,Dotted);
+xequals(pic2,1e-1,Dotted);
+
+size(pic2,100,100,point(pic2,SW),point(pic2,NE));
+
+label(pic2,"$\theta=0.75$",point(pic2,N),2N);
+
+frame f2=pic2.fit();
+f2=shift(max(f1).x-min(f2).x+margin)*f2;
+add(f2);
+
+picture pic2p;
+scale(pic2p,Log,Linear);
+real Aerr2(real x){return Aerr(x,0.75);}
+draw(pic2p,graph(pic2p,Aerr2,1e-4,1),black+1.2);
+
+ylimits(pic2p,-5,95);
+yaxis(pic2p,"phase (deg)",LeftRight,RightTicks(new real[] {0,45.1,90}));
+xaxis(pic2p,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic2p,0,Dotted);
+yequals(pic2p,45,Dotted);
+yequals(pic2p,90,Dotted);
+xequals(pic2p,1e-3,Dotted);
+xequals(pic2p,1e-2,Dotted);
+xequals(pic2p,1e-1,Dotted);
+
+size(pic2p,100,100,point(pic2p,SW),point(pic2p,NE));
+
+frame f2p=pic2p.fit();
+f2p=shift(max(f1p).x-min(f2p).x+margin,min(f2).y-max(f2p).y-margin)*f2p;
+add(f2p);
diff --git a/graphics/asymptote/examples/animations/cube.asy b/graphics/asymptote/examples/animations/cube.asy
new file mode 100644
index 0000000000..001e54466d
--- /dev/null
+++ b/graphics/asymptote/examples/animations/cube.asy
@@ -0,0 +1,46 @@
+import math;
+import bsp;
+import animation;
+
+size(100,100);
+
+animation a;
+
+void face(face[] faces, path3 p, int j, int k) {
+ picture pic=faces.push(p);
+ filldraw(pic,project(p),Pen(j));
+ int sign=(k % 2 == 0) ? 1 : -1;
+ transform t=scale(4)*transform(dir(p,0,sign),dir(p,0,-sign));
+ label(pic,t*(string) j,project(0.5*(min(p)+max(p))));
+}
+
+void snapshot(transform3 t)
+{
+ static transform3 s=shift(-0.5*(X+Y+Z));
+ save();
+
+ face[] faces;
+ int j=-1;
+ transform3 T=t*s;
+ for(int k=0; k < 2; ++k) {
+ face(faces,T*plane((1,0,0),(0,1,0),(0,0,k)),++j,k);
+ face(faces,T*plane((0,1,0),(0,0,1),(k,0,0)),++j,k);
+ face(faces,T*plane((0,0,1),(1,0,0),(0,k,0)),++j,k);
+ }
+ add(faces);
+
+ a.add();
+ restore();
+}
+
+int n=50;
+
+real step=360/n;
+for(int i=0; i < n; ++i)
+ snapshot(rotate(i*step,X));
+for(int i=0; i < n; ++i)
+ snapshot(rotate(i*step,Y));
+for(int i=0; i < n; ++i)
+ snapshot(rotate(i*step,Z));
+
+a.movie(loops=10,delay=50);
diff --git a/graphics/asymptote/examples/animations/dice.u3d b/graphics/asymptote/examples/animations/dice.u3d
new file mode 100644
index 0000000000..ae14b756a1
--- /dev/null
+++ b/graphics/asymptote/examples/animations/dice.u3d
Binary files differ
diff --git a/graphics/asymptote/examples/animations/earthmoon.asy b/graphics/asymptote/examples/animations/earthmoon.asy
new file mode 100644
index 0000000000..4590eaeec4
--- /dev/null
+++ b/graphics/asymptote/examples/animations/earthmoon.asy
@@ -0,0 +1,78 @@
+import graph3;
+import solids;
+import three;
+import animate;
+
+settings.render=2;
+settings.tex="pdflatex";
+settings.prc=false;
+settings.thick=false;
+settings.outformat="mpg";
+currentprojection=orthographic(5,4,2);
+currentlight=light(specular=black,(0.1,-0.1,1));
+
+size(15cm,0);
+
+animation A;
+
+real Rst=20, Rl=0.7, Rtl=5;
+real ast=20, est=0.3, bst=ast*sqrt(1-est^2), cst=ast*est;
+real atl=5, etl=0.8, btl=atl*sqrt(1-etl^2), ctl=atl*etl;
+
+real xST(real t) {return ast*cos(t)+cst;}
+real yST(real t) {return bst*sin(t);}
+real zST(real t) {return 0;}
+
+real xTL(real t) {return atl*cos(27t);}
+real yTL(real t) {return btl*sin(27t);}
+real zTL(real t) {return 0;}
+
+
+real xLl(real t) {return Rl*cos(27t);}
+real yLl(real t) {return Rl*sin(27t);}
+real zLl(real t) {return 0;}
+
+real xTt(real t) {return Rtl*cos(100t)/5;}
+real yTt(real t) {return Rtl*sin(100t)/5;}
+real zTt(real t) {return 0;}
+
+real xl(real t) {return xST(t)+xTL(t)+xLl(t);}
+real yl(real t) {return yST(t)+yTL(t)+yLl(t);}
+real zl(real t) {return 0;}
+
+real xt(real t) {return xST(t)+xTt(t);}
+real yt(real t) {return yST(t)+yTt(t);}
+real zt(real t) {return 0;}
+
+real xL(real t) {return xST(t)+xTL(t);}
+real yL(real t) {return yST(t)+yTL(t);}
+real zL(real t) {return 0;}
+
+path3 Pl=graph(xl,yl,zl,0,2pi,1000),Pt=graph(xt,yt,zt,0,2pi,3000),
+Pts=graph(xST,yST,zST,0,2pi,500);
+
+picture pic;
+
+draw(pic,Pl,lightgray);
+draw(pic,Pt,lightblue);
+draw(pic,Pts,blue+dashed);
+
+draw(pic,shift(cst,0,0)*scale3(Rtl/2)*unitsphere,yellow);
+
+surface terre=scale3(Rtl/5)*unitsphere;
+surface lune=scale3(Rl)*unitsphere;
+
+int n=50;
+
+real step=2pi/n;
+for(int i=0; i < n; ++i) {
+ real k=i*step;
+ add(pic);
+ draw(shift(xL(k),yL(k),0)*lune,lightgray);
+ draw(shift(xST(k),yST(k),0)*terre,lightblue+lightgreen);
+ A.add();
+ erase();
+}
+
+A.movie(BBox(1mm,Fill(Black)),delay=500,
+ options="-density 288x288 -geometry 50%x");
diff --git a/graphics/asymptote/examples/animations/embeddedmovie.asy b/graphics/asymptote/examples/animations/embeddedmovie.asy
new file mode 100644
index 0000000000..7557266bb0
--- /dev/null
+++ b/graphics/asymptote/examples/animations/embeddedmovie.asy
@@ -0,0 +1,19 @@
+// An embedded movie;
+//
+// See http://mirror.ctan.org/macros/latex/contrib/media9/doc/media9.pdf
+// for documentation of the options.
+
+import embed; // Add embedded movie
+//import external; // Add external movie (use this form under Linux).
+
+// Generated needed mp4 file if it doesn't already exist.
+asy("mp4","wheel");
+
+// Produce a pdf file.
+settings.outformat="pdf";
+
+settings.twice=true;
+
+// An embedded movie:
+label(embed("wheel.mp4",20cm,5.6cm),(0,0),N);
+label(link("wheel.mp4"),(0,0),S);
diff --git a/graphics/asymptote/examples/animations/embeddedu3d.asy b/graphics/asymptote/examples/animations/embeddedu3d.asy
new file mode 100644
index 0000000000..b30ada927c
--- /dev/null
+++ b/graphics/asymptote/examples/animations/embeddedu3d.asy
@@ -0,0 +1,8 @@
+// An embedded U3D object;
+//
+import embed;
+settings.tex="pdflatex";
+
+label(embedplayer("dice.u3d","dice","activate=pagevisible,3Droo=27",
+ settings.paperwidth,settings.paperheight));
+
diff --git a/graphics/asymptote/examples/animations/externalmovie.asy b/graphics/asymptote/examples/animations/externalmovie.asy
new file mode 100644
index 0000000000..8dc8af74bb
--- /dev/null
+++ b/graphics/asymptote/examples/animations/externalmovie.asy
@@ -0,0 +1,16 @@
+// Embed a movie to be run in an external window.
+
+import external;
+
+// External movies require the pdflatex engine.
+settings.tex="pdflatex";
+
+// Generated needed mpeg file if it doesn't already exist.
+asy("mp4","wheel");
+
+// Produce a pdf file.
+settings.outformat="pdf";
+
+// External movie: viewable even with the Linux version of acroread.
+label(embed("wheel.mp4"),(0,0),N);
+label(link("wheel.mp4"),(0,0),S);
diff --git a/graphics/asymptote/examples/animations/glmovie.asy b/graphics/asymptote/examples/animations/glmovie.asy
new file mode 100644
index 0000000000..c3d86481b1
--- /dev/null
+++ b/graphics/asymptote/examples/animations/glmovie.asy
@@ -0,0 +1,21 @@
+settings.autoplay=true;
+settings.loop=true;
+
+import graph3;
+import animate;
+currentprojection=orthographic(1,-2,0.5);
+
+animation A;
+int n=25;
+
+for(int i=0; i < n; ++i) {
+ picture pic;
+ size3(pic,6cm);
+ real k=i/n*pi;
+ real f(pair z) {return 4cos(abs(z)-k)*exp(-abs(z)/6);}
+ draw(pic,surface(f,(-4pi,-4pi),(4pi,4pi),Spline),paleblue);
+ draw(pic,shift(i*6Z/n)*unitsphere,yellow);
+ A.add(pic);
+}
+
+A.glmovie();
diff --git a/graphics/asymptote/examples/animations/heatequation.asy b/graphics/asymptote/examples/animations/heatequation.asy
new file mode 100644
index 0000000000..3c5708e583
--- /dev/null
+++ b/graphics/asymptote/examples/animations/heatequation.asy
@@ -0,0 +1,76 @@
+import graph3;
+import palette;
+import animate;
+
+settings.tex="pdflatex";
+settings.render=0;
+settings.prc=false;
+unitsize(1cm);
+
+animation a;
+
+currentprojection=perspective(-20,-18,18);
+currentlight=light(1,1,10);
+
+int n=26;
+real L=2.5;
+real dx=2*L/n;
+real CFL=0.125;
+real dt=CFL*dx^2;
+
+real[][] Z=new real[n][n];
+real[][] W=new real[n][n];
+
+guide initcond1=shift((-1,-1))*scale(0.5)*unitcircle;
+guide initcond2=shift((0.5,0))*yscale(1.2)*unitcircle;
+
+real f(pair p) {return (inside(initcond1,p)||inside(initcond2,p)) ? 2 : 0;}
+
+//Initialize
+for(int i=0; i < n; ++i)
+ for (int j=0; j < n; ++j)
+ Z[i][j]=f((-L,-L)+(2*L/n)*(i,j));
+
+real f(pair t) {
+ int i=round((n/2)*(t.x/L+1));
+ int j=round((n/2)*(t.y/L+1));
+ if(i > n-1) i=n-1;
+ if(j > n-1) j=n-1;
+ return Z[i][j];
+}
+
+surface sf;
+
+void advanceZ(int iter=20) {
+ for(int k=0; k < iter; ++k) {
+ for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j) W[i][j]=0;
+ for(int i=1; i < n-1; ++i)
+ for(int j=1; j< n-1; ++j)
+ W[i][j]=Z[i][j]+(dt/dx^2)*(Z[i+1][j]+Z[i-1][j]+Z[i][j-1]+Z[i][j+1]
+ -4*Z[i][j]);
+ for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ Z[i][j]=W[i][j];
+ };
+}
+
+pen[] Pal=Rainbow(96);
+
+int endframe=40;
+
+for(int fr=0; fr < endframe; ++fr) {
+ if(fr == 0) {// smoothing of initial state; no Spline, but full grid
+ advanceZ(3);
+ sf=surface(f,(-L,-L),(L,L),nx=n);
+ } else // use Spline and fewer grid points to save memory
+ sf=surface(f,(-L,-L),(L,L),nx=round(n/2),Spline);
+ sf.colors(palette(sf.map(zpart),Pal[0:round(48*max(sf).z)]));
+ draw(sf);
+ a.add();
+ erase();
+ advanceZ(30);
+};
+
+label(a.pdf(delay=400,"controls,loop"));
+shipout(bbox(3mm,darkblue+3bp+miterjoin,FillDraw(fillpen=paleblue)),"pdf");
diff --git a/graphics/asymptote/examples/animations/inlinemovie.tex b/graphics/asymptote/examples/animations/inlinemovie.tex
new file mode 100644
index 0000000000..5f1eff9d4b
--- /dev/null
+++ b/graphics/asymptote/examples/animations/inlinemovie.tex
@@ -0,0 +1,55 @@
+\documentclass{article}
+\usepackage[inline]{asymptote}
+%\usepackage{asymptote}
+\usepackage{animate}
+\begin{document}
+
+Here is an inline PDF movie, generated with the commands
+\begin{verbatim}
+pdflatex inlinemovie
+asy inlinemovie-*.asy
+pdflatex inlinemovie
+\end{verbatim}
+or equivalently,
+\begin{verbatim}
+latexmk -pdf inlinemovie
+\end{verbatim}
+
+\begin{center}
+\begin{asy}
+import animate;
+animation A=animation("movie1");
+real h=2pi/10;
+
+picture pic;
+unitsize(pic,2cm);
+for(int i=0; i < 10; ++i) {
+ draw(pic,expi(i*h)--expi((i+1)*h));
+ A.add(pic);
+}
+label(A.pdf("controls",delay=50,keep=!settings.inlinetex));
+\end{asy}
+%Uncomment the following line when not using the [inline] package option:
+%\ASYanimategraphics[controls]{50}{movie1}{}{}
+\end{center}
+
+And here is another one, clickable but without the control panel:
+\begin{center}
+\begin{asy}
+import animate;
+animation A=animation("movie2");
+real h=2pi/10;
+
+picture pic;
+unitsize(pic,2cm);
+for(int i=0; i < 10; ++i) {
+ draw(pic,expi(-i*h)--expi(-(i+1)*h),red);
+ A.add(pic);
+}
+label(A.pdf(keep=!settings.inlinetex));
+\end{asy}
+%Uncomment the following line when not using the [inline] package option:
+%\ASYanimategraphics[controls]{10}{movie2}{}{}
+\end{center}
+
+\end{document}
diff --git a/graphics/asymptote/examples/animations/inlinemovie3.tex b/graphics/asymptote/examples/animations/inlinemovie3.tex
new file mode 100644
index 0000000000..5131c652a1
--- /dev/null
+++ b/graphics/asymptote/examples/animations/inlinemovie3.tex
@@ -0,0 +1,44 @@
+\documentclass{article}
+\usepackage[inline]{asymptote}
+%\usepackage{asymptote}
+\usepackage{animate}
+\begin{document}
+
+Here is an inline 3D PDF movie, generated with the commands
+\begin{verbatim}
+pdflatex inlinemovie3
+asy inlinemovie3-*.asy
+pdflatex inlinemovie3
+\end{verbatim}
+or equivalently,
+\begin{verbatim}
+latexmk -pdf inlinemovie3
+\end{verbatim}
+
+\begin{center}
+\begin{asy}
+settings.render=4;
+settings.prc=false;
+
+import graph3;
+import animate;
+currentprojection=orthographic(1,-2,0.5);
+
+animation A=animation("movie3");
+int n=20;
+for(int i=0; i < n; ++i) {
+ picture pic;
+ size3(pic,12cm,12cm,8cm);
+ real k=i/n*pi;
+ real f(pair z) {return 4cos(abs(z)-k)*exp(-abs(z)/6);}
+ draw(pic,surface(f,(-4pi,-4pi),(4pi,4pi),Spline),paleblue);
+ draw(pic,shift(i*6Z/n)*unitsphere,yellow);
+ A.add(pic);
+}
+label(A.pdf("autoplay,loop",delay=20,keep=!settings.inlinetex));
+\end{asy}
+%Uncomment the following line when not using the [inline] package option:
+%\ASYanimategraphics[autoplay,loop]{50}{movie3}{}{}
+\end{center}
+\end{document}
+
diff --git a/graphics/asymptote/examples/animations/pdfmovie.asy b/graphics/asymptote/examples/animations/pdfmovie.asy
new file mode 100644
index 0000000000..0f9cbc9644
--- /dev/null
+++ b/graphics/asymptote/examples/animations/pdfmovie.asy
@@ -0,0 +1,20 @@
+import animate;
+import patterns;
+
+settings.tex="pdflatex";
+
+animation a;
+
+add("brick",brick(black));
+
+int n=20;
+for(int i=0; i < 3.5n; ++i) {
+ picture pic;
+ size(pic,100);
+ path g=circle((0,sin(pi/n*i)),1);
+ fill(pic,g,mediumred);
+ fill(pic,g,pattern("brick"));
+ a.add(pic);
+}
+
+label(a.pdf("controls",multipage=false));
diff --git a/graphics/asymptote/examples/animations/slidemovies.asy b/graphics/asymptote/examples/animations/slidemovies.asy
new file mode 100644
index 0000000000..bbfdd21eab
--- /dev/null
+++ b/graphics/asymptote/examples/animations/slidemovies.asy
@@ -0,0 +1,44 @@
+// Slide demo.
+// Command-line options to enable stepping and/or reverse video:
+// asy [-u stepping=true] [-u reverse=true] slidedemo
+
+orientation=Landscape;
+
+settings.tex="pdflatex";
+
+import slide;
+
+// Optional movie modules:
+import animate; // For portable embedded PDF movies
+access external; // For portable external movies
+access embed; // For non-portable embedded movies
+
+usersetting();
+
+titlepage("Slides with {\tt Asymptote}: Animations","John C. Bowman",
+ "University of Alberta","\today","http://asymptote.sf.net");
+
+title("Embedded PDF movies (portable)");
+animation a=animation("A");
+animation b=animation("B");
+int n=20;
+for(int i=0; i < 2n; ++i) {
+ picture pic;
+ size(pic,100);
+ draw(pic,shift(0,sin(pi/n*i))*unitsquare);
+ a.add(pic);
+ if(i < 1.5n) b.add(rotate(45)*pic);
+}
+display(a.pdf("autoplay,loop,controls",multipage=false));
+display(b.pdf("controls",multipage=false));
+
+// Generated needed files if they don't already exist.
+asy("mp4","wheel");
+
+title("External Movie (portable)");
+display(external.embed("wheel.mp4",20cm,5.6cm));
+display(external.link("wheel.mp4"));
+
+title("Embedded Movie (not portable)");
+display(embed.embed("wheel.mp4",20cm,5.6cm));
+display(embed.link("wheel.mp4"));
diff --git a/graphics/asymptote/examples/animations/sphere.asy b/graphics/asymptote/examples/animations/sphere.asy
new file mode 100644
index 0000000000..125cecc556
--- /dev/null
+++ b/graphics/asymptote/examples/animations/sphere.asy
@@ -0,0 +1,42 @@
+import solids;
+import animation;
+
+currentprojection=orthographic((0,5,2));
+currentlight=(0,5,5);
+
+settings.thick=false;
+settings.render=0;
+
+int nbpts=200;
+real step=2*pi/nbpts;
+int angle=10;
+
+unitsize(1cm);
+
+triple[] P=new triple[nbpts];
+for(int i=0; i < nbpts; ++i) {
+ real t=-pi+i*step;
+ P[i]=(3sin(t)*cos(2t),3sin(t)*sin(2t),3cos(t));
+}
+
+transform3 t=rotate(angle,(0,0,0),(1,0.25,0.25));
+revolution r=sphere(O,3);
+draw(surface(r),lightgrey);
+draw(r,backpen=linetype("8 8",8));
+
+animation A;
+
+for(int phi=0; phi < 360; phi += angle) {
+ bool[] front=new bool[nbpts];
+ save();
+ for(int i=0; i < nbpts; ++i) {
+ P[i]=t*P[i];
+ front[i]=dot(P[i],currentprojection.camera) > 0;
+ }
+ draw(segment(P,front,operator ..),1mm+blue+extendcap);
+ draw(segment(P,!front,operator ..),grey);
+ A.add();
+ restore();
+}
+
+A.movie(0,200);
diff --git a/graphics/asymptote/examples/animations/torusanimation.asy b/graphics/asymptote/examples/animations/torusanimation.asy
new file mode 100644
index 0000000000..74a5df4327
--- /dev/null
+++ b/graphics/asymptote/examples/animations/torusanimation.asy
@@ -0,0 +1,43 @@
+import graph3;
+import animation;
+import solids;
+
+currentprojection=perspective(50,40,20);
+
+currentlight=(0,5,5);
+
+real R=3;
+real a=1;
+int n=8;
+
+path3[] p=new path3[n];
+animation A;
+
+for(int i=0; i < n; ++i) {
+ triple g(real s) {
+ real twopi=2*pi;
+ real u=twopi*s;
+ real v=twopi/(1+i+s);
+ real cosu=cos(u);
+ return((R-a*cosu)*cos(v),(R-a*cosu)*sin(v),-a*sin(u));
+ }
+ p[i]=graph(g,0,1,operator ..);
+}
+
+triple f(pair t) {
+ real costy=cos(t.y);
+ return((R+a*costy)*cos(t.x),(R+a*costy)*sin(t.x),a*sin(t.y));
+}
+
+surface s=surface(f,(0,0),(2pi,2pi),8,8,Spline);
+
+for(int i=0; i < n; ++i){
+ picture fig;
+ size(fig,20cm);
+ draw(fig,s,yellow);
+ for(int j=0; j <= i; ++j)
+ draw(fig,p[j],blue+linewidth(4));
+ A.add(fig);
+}
+
+A.movie(BBox(10,Fill(rgb(0.98,0.98,0.9))),delay=100);
diff --git a/graphics/asymptote/examples/animations/wavepacket.asy b/graphics/asymptote/examples/animations/wavepacket.asy
new file mode 100644
index 0000000000..006fbce154
--- /dev/null
+++ b/graphics/asymptote/examples/animations/wavepacket.asy
@@ -0,0 +1,86 @@
+// Author : Philippe Ivaldi
+// http://www.piprime.fr/
+// 2006/11/10
+
+import animation;
+import graph;
+
+unitsize(x=2cm,y=1.5cm);
+
+typedef real realfcn(real);
+
+real lambda=4;
+real T=2;
+real [] k=new real[3];
+real [] w=new real[3];
+k[0]=2pi/lambda;
+w[0]=2pi/T;
+real dk=-.5;
+k[1]=k[0]-dk;
+k[2]=k[0]+dk;
+real dw=1;
+w[1]=w[0]-dw;
+w[2]=w[0]+dw;
+
+real vp=w[1]/k[1];
+real vg=dw/dk;
+
+realfcn F(real x) {
+ return new real(real t) {
+ return cos(k[1]*x-w[1]*t)+cos(k[2]*x-w[2]*t);
+ };
+};
+
+realfcn G(real x) {
+ return new real(real t) {
+ return 2*cos(0.5*(k[2]-k[1])*x+0.5*(w[1]-w[2])*t);
+ };
+};
+
+realfcn operator -(realfcn f) {return new real(real t) {return -f(t);};};
+
+animation A;
+
+real tmax=abs(2pi/dk);
+real xmax=abs(2pi/dw);
+
+pen envelope=0.8*blue;
+pen fillpen=lightgrey;
+
+int n=50;
+real step=tmax/(n-1);
+for(int i=0; i < n; ++i) {
+ save();
+ real t=i*step;
+ real a=xmax*t/tmax-xmax/pi;
+ real b=xmax*t/tmax;
+ path f=graph(F(t),a,b);
+ path g=graph(G(t),a,b);
+ path h=graph(-G(t),a,b);
+ fill(buildcycle(reverse(f),g),fillpen);
+ draw(f);
+ draw(g,envelope);
+ draw(h,envelope);
+ A.add();
+ restore();
+}
+
+for(int i=0; i < n; ++i) {
+ save();
+ real t=i*step;
+ real a=-xmax/pi;
+ real b=xmax;
+ path f=graph(F(t),a,b);
+ path g=graph(G(t),a,b);
+ path h=graph(-G(t),a,b);
+ path B=box((-xmax/pi,-2),(xmax,2));
+ fill(buildcycle(reverse(f),g,B),fillpen);
+ fill(buildcycle(f,g,reverse(B)),fillpen);
+ draw(f);
+ draw(g,envelope);
+ draw(h,envelope);
+ A.add();
+ restore();
+}
+
+A.movie(0,10);
diff --git a/graphics/asymptote/examples/animations/wheel.asy b/graphics/asymptote/examples/animations/wheel.asy
new file mode 100644
index 0000000000..6620d59085
--- /dev/null
+++ b/graphics/asymptote/examples/animations/wheel.asy
@@ -0,0 +1,63 @@
+import graph;
+
+// Uncomment the following 2 lines to support pdf animations:
+// usepackage("animate");
+// settings.tex="pdflatex";
+
+import animation;
+
+size(0,200);
+
+defaultpen(3);
+dotfactor=4;
+
+pair wheelpoint(real t)
+{
+ return (t+cos(t),-sin(t));
+}
+
+guide wheel(guide g=nullpath, real a, real b, int n)
+{
+ real width=(b-a)/n;
+ for(int i=0; i <= n; ++i) {
+ real t=a+width*i;
+ g=g--wheelpoint(t);
+ }
+ return g;
+}
+
+real t1=0;
+real t2=t1+2*pi;
+
+animation a;
+
+draw(circle((0,0),1));
+draw(wheel(t1,t2,100),linetype("0 2"));
+yequals(Label("$y=-1$",1.0),-1,extend=true,linetype("4 4"));
+xaxis(Label("$x$",align=3SW),0);
+yaxis("$y$",0,1.2);
+pair z1=wheelpoint(t1);
+pair z2=wheelpoint(t2);
+dot(z1);
+dot(z2);
+
+int n=10;
+real dt=(t2-t1)/n;
+for(int i=0; i <= n; ++i) {
+ save();
+
+ real t=t1+dt*i;
+ draw(circle((t,0),1),red);
+ dot(wheelpoint(t));
+
+ a.add(); // Add currentpicture to animation.
+ restore();
+}
+
+erase();
+
+// Merge the images into a gif animation.
+a.movie(BBox(0.25cm),loops=10,delay=250);
+
+// Merge the images into a pdf animation.
+// label(a.pdf(BBox(0.25cm),delay=250,"controls",multipage=false));
diff --git a/graphics/asymptote/examples/annotation.asy b/graphics/asymptote/examples/annotation.asy
new file mode 100644
index 0000000000..d52e15b4f7
--- /dev/null
+++ b/graphics/asymptote/examples/annotation.asy
@@ -0,0 +1,13 @@
+import annotate;
+settings.outformat="pdf";
+
+size(200);
+
+draw(unitcircle);
+dot((0,0));
+annotate("O","(0,0)",(0,0));
+annotate("A","(1,0)",(1,0));
+annotate("B","(0,1)",(0,1));
+annotate("C","(-1,0)",(-1,0));
+annotate("D","(0,-1)",(0,-1));
+
diff --git a/graphics/asymptote/examples/arrows3.asy b/graphics/asymptote/examples/arrows3.asy
new file mode 100644
index 0000000000..06b986ef5f
--- /dev/null
+++ b/graphics/asymptote/examples/arrows3.asy
@@ -0,0 +1,22 @@
+import three;
+
+size(15cm);
+
+defaultrender.merge=true;
+
+currentprojection=perspective(24,14,13);
+currentlight=light(gray(0.5),specularfactor=3,
+ (0.5,-0.5,-0.25),(0.5,0.5,0.25),(0.5,0.5,1),(-0.5,-0.5,-1));
+
+defaultpen(0.75mm);
+
+path3 g=arc(O,1,90,-60,90,60);
+transform3 t=shift(invert(3S,O));
+
+draw(g,blue,Arrows3(TeXHead3),currentlight);
+draw(scale3(3)*g,green,ArcArrows3(HookHead3),currentlight);
+draw(scale3(6)*g,red,Arrows3(DefaultHead3),currentlight);
+
+draw(t*g,blue,Arrows3(TeXHead2),currentlight);
+draw(t*scale3(3)*g,green,ArcArrows3(HookHead2,NoFill),currentlight);
+draw(t*scale3(6)*g,red,Arrows3(DefaultHead2(normal=Z)),currentlight);
diff --git a/graphics/asymptote/examples/bars3.asy b/graphics/asymptote/examples/bars3.asy
new file mode 100644
index 0000000000..4205d46f37
--- /dev/null
+++ b/graphics/asymptote/examples/bars3.asy
@@ -0,0 +1,22 @@
+import three;
+import palette;
+import graph3;
+
+size(300);
+
+currentprojection=perspective(-30,-30,30,up=Z);
+
+surface s;
+
+for(int i = 0; i < 10; ++i) {
+ for(int j = 0; j < 10; ++j) {
+ s.append(shift(i,j,0)*scale(1,1,i+j)*unitcube);
+ }
+}
+
+s.colors(palette(s.map(zpart),Rainbow()));
+draw(s,meshpen=black+thick(),nolight,render(merge=true));
+
+xaxis3("$x$",Bounds,InTicks(endlabel=false,Label,2,2));
+yaxis3(YZ()*"$y$",Bounds,InTicks(beginlabel=false,Label,2,2));
+zaxis3(XZ()*"$z$",Bounds,InTicks);
diff --git a/graphics/asymptote/examples/basealign.asy b/graphics/asymptote/examples/basealign.asy
new file mode 100644
index 0000000000..d653ec3c04
--- /dev/null
+++ b/graphics/asymptote/examples/basealign.asy
@@ -0,0 +1,44 @@
+import fontsize;
+import three;
+
+settings.autobillboard=false;
+settings.embed=false;
+currentprojection=orthographic(Z);
+
+defaultpen(fontsize(100pt));
+
+dot(O);
+
+label("acg",O,align=N,basealign);
+label("ace",O,align=N,red);
+label("acg",O,align=S,basealign);
+label("ace",O,align=S,red);
+label("acg",O,align=E,basealign);
+label("ace",O,align=E,red);
+label("acg",O,align=W,basealign);
+label("ace",O,align=W,red);
+
+picture pic;
+dot(pic,(labelmargin(),0,0),blue);
+dot(pic,(-labelmargin(),0,0),blue);
+dot(pic,(0,labelmargin(),0),blue);
+dot(pic,(0,-labelmargin(),0),blue);
+add(pic,O);
+
+dot((0,0));
+
+label("acg",(0,0),align=N,basealign);
+label("ace",(0,0),align=N,red);
+label("acg",(0,0),align=S,basealign);
+label("ace",(0,0),align=S,red);
+label("acg",(0,0),align=E,basealign);
+label("ace",(0,0),align=E,red);
+label("acg",(0,0),align=W,basealign);
+label("ace",(0,0),align=W,red);
+
+picture pic;
+dot(pic,(labelmargin(),0),blue);
+dot(pic,(-labelmargin(),0),blue);
+dot(pic,(0,labelmargin()),blue);
+dot(pic,(0,-labelmargin()),blue);
+add(pic,(0,0));
diff --git a/graphics/asymptote/examples/billboard.asy b/graphics/asymptote/examples/billboard.asy
new file mode 100644
index 0000000000..6e5df87100
--- /dev/null
+++ b/graphics/asymptote/examples/billboard.asy
@@ -0,0 +1,10 @@
+import three;
+
+size(100);
+
+currentprojection=perspective(1,-2,1);
+
+draw(unitbox);
+
+label("Billboard",X,red,Billboard);
+label("Embedded",Y,blue,Embedded);
diff --git a/graphics/asymptote/examples/buildcycle.asy b/graphics/asymptote/examples/buildcycle.asy
new file mode 100644
index 0000000000..e4e7f8c7c9
--- /dev/null
+++ b/graphics/asymptote/examples/buildcycle.asy
@@ -0,0 +1,22 @@
+size(200);
+
+real w=1.35;
+
+path[] p;
+for(int k=0; k < 2; ++k) {
+ int i=2+2*k;
+ int ii=i^2;
+ p[k]=(w/ii,1){1,-ii}::(w/i,1/i)::(w,1/ii){ii,-1};
+}
+
+path q0=(0,0)--(w,0.5);
+path q1=(0,0)--(w,1.5);
+draw(q0); draw(p[0]); draw(q1); draw(p[1]);
+path s=buildcycle(q0,p[0],q1,p[1]);
+fill(s,mediumgrey);
+
+label("$P$",intersectionpoint(p[0],q0),N);
+label("$Q$",intersectionpoint(p[0],q1),E);
+label("$R$",intersectionpoint(p[1],q1),W);
+label("$S$",intersectionpoint(p[1],q0),S);
+label("$f > 0$",0.5*(min(s)+max(s)),UnFill);
diff --git a/graphics/asymptote/examples/cardioid.asy b/graphics/asymptote/examples/cardioid.asy
new file mode 100644
index 0000000000..49a3c55207
--- /dev/null
+++ b/graphics/asymptote/examples/cardioid.asy
@@ -0,0 +1,15 @@
+import graph;
+
+size(0,100);
+
+real f(real t) {return 1+cos(t);}
+
+path g=polargraph(f,0,2pi,operator ..)--cycle;
+filldraw(g,pink);
+
+xaxis("$x$",above=true);
+yaxis("$y$",above=true);
+
+dot("$(a,0)$",(1,0),N);
+dot("$(2a,0)$",(2,0),N+E);
+
diff --git a/graphics/asymptote/examples/cards.asy b/graphics/asymptote/examples/cards.asy
new file mode 100644
index 0000000000..337a886ec8
--- /dev/null
+++ b/graphics/asymptote/examples/cards.asy
@@ -0,0 +1,26 @@
+picture rect;
+
+size(rect,0,2.5cm);
+
+real x=1;
+real y=1.25;
+
+filldraw(rect,box((-x,-y)/2,(x,y)/2),lightolive);
+
+label(rect,"1",(-x,y)*0.45,SE);
+label(rect,"2",(x,y)*0.45,SW);
+label(rect,"3",(-x,-y)*0.45,NE);
+label(rect,"4",(x,-y)*0.45,NW);
+
+frame rectf=rect.fit();
+frame toplef=rectf;
+frame toprig=xscale(-1)*rectf;
+frame botlef=yscale(-1)*rectf;
+frame botrig=xscale(-1)*yscale(-1)*rectf;
+
+size(0,7.5cm);
+
+add(toplef,(-x,y));
+add(toprig,(x,y));
+add(botlef,(-x,-y));
+add(botrig,(x,-y));
diff --git a/graphics/asymptote/examples/centroidfg.asy b/graphics/asymptote/examples/centroidfg.asy
new file mode 100644
index 0000000000..2e26454cdb
--- /dev/null
+++ b/graphics/asymptote/examples/centroidfg.asy
@@ -0,0 +1,38 @@
+import graph;
+size(0,150);
+
+int a=-1, b=1;
+
+real f(real x) {return x^3-x+2;}
+real g(real x) {return x^2;}
+
+draw(graph(f,a,b,operator ..),red);
+draw(graph(g,a,b,operator ..),blue);
+
+xaxis();
+
+int n=5;
+
+real width=(b-a)/(real) n;
+for(int i=0; i <= n; ++i) {
+ real x=a+width*i;
+ draw((x,g(x))--(x,f(x)));
+}
+
+labelx("$a$",a);
+labelx("$b$",b);
+draw((a,0)--(a,g(a)),dotted);
+draw((b,0)--(b,g(b)),dotted);
+
+real m=a+0.73*(b-a);
+arrow("$f(x)$",(m,f(m)),N,red);
+arrow("$g(x)$",(m,g(m)),E,0.8cm,blue);
+
+int j=2;
+real xi=b-j*width;
+real xp=xi+width;
+real xm=0.5*(xi+xp);
+pair dot=(xm,0.5*(f(xm)+g(xm)));
+dot(dot,darkgreen+4.0);
+arrow("$\left(x,\frac{f(x)+g(x)}{2}\right)$",dot,NE,2cm,darkgreen);
+
diff --git a/graphics/asymptote/examples/cheese.asy b/graphics/asymptote/examples/cheese.asy
new file mode 100644
index 0000000000..05b9181fdf
--- /dev/null
+++ b/graphics/asymptote/examples/cheese.asy
@@ -0,0 +1,15 @@
+import graph3;
+import palette;
+import contour3;
+size(400);
+
+real f(real x, real y, real z) {
+ return cos(x)*sin(y)+cos(y)*sin(z)+cos(z)*sin(x);
+}
+
+surface sf=surface(contour3(f,(-2pi,-2pi,-2pi),(2pi,2pi,2pi),12));
+sf.colors(palette(sf.map(abs),Gradient(red,yellow)));
+
+currentlight=nolight;
+
+draw(sf,render(merge=true));
diff --git a/graphics/asymptote/examples/circles.asy b/graphics/asymptote/examples/circles.asy
new file mode 100644
index 0000000000..69f5cf244a
--- /dev/null
+++ b/graphics/asymptote/examples/circles.asy
@@ -0,0 +1,33 @@
+size(6cm,0);
+import math;
+
+currentpen=magenta;
+
+real r1=1;
+real r2=sqrt(7);
+real r3=4;
+pair O=0;
+
+path c1=circle(O,r1);
+draw(c1,green);
+draw(circle(O,r2),green);
+draw(circle(O,r3),green);
+
+real x=-0.6;
+real y=-0.8;
+real yD=0.3;
+pair A=(sqrt(r1^2-y^2),y);
+pair B=(-sqrt(r2^2-y^2),y);
+pair C=(x,sqrt(r3^2-x^2));
+
+pair d=A+r2*dir(B--C);
+pair D=intersectionpoint(c1,A--d);
+
+draw(A--B--C--cycle);
+draw(interp(A,D,-0.5)--interp(A,D,1.5),blue);
+
+dot("$O$",O,S,red);
+dot("$A$",A,dir(C--A,B--A),red);
+dot("$B$",B,dir(C--B,A--B),red);
+dot("$C$",C,dir(A--C,B--C),red);
+dot("$D$",D,red);
diff --git a/graphics/asymptote/examples/circumcircle.asy b/graphics/asymptote/examples/circumcircle.asy
new file mode 100644
index 0000000000..96b3bdd82a
--- /dev/null
+++ b/graphics/asymptote/examples/circumcircle.asy
@@ -0,0 +1,9 @@
+unitsize(1inch);
+
+path tri=(0,0)--(1,0)--(2,1)--cycle;
+pair p1=point(tri,0.5);
+pair p2=point(tri,1.5);
+pair z0=extension(p1,p1+I*dir(tri,0.5),p2,p2+I*dir(tri,1.5));
+dot(z0);
+draw(circle(z0,abs(z0-point(tri,0))));
+draw(tri,red);
diff --git a/graphics/asymptote/examples/clockarray.asy b/graphics/asymptote/examples/clockarray.asy
new file mode 100644
index 0000000000..be7fd899a0
--- /dev/null
+++ b/graphics/asymptote/examples/clockarray.asy
@@ -0,0 +1,39 @@
+int nx=3;
+int ny=4;
+real xmargin=1cm;
+real ymargin=xmargin;
+
+size(settings.paperwidth,settings.paperheight);
+
+picture pic;
+real width=settings.paperwidth/nx-xmargin;
+real height=settings.paperheight/ny-ymargin;
+if(width <= 0 || height <= 0) abort("margin too big");
+size(pic,width,height);
+
+pen p=linewidth(0.5mm);
+draw(pic,unitcircle,p);
+
+real h=0.08;
+real m=0.05;
+
+for(int hour=1; hour <= 12; ++hour) {
+ pair z=dir((12-hour+3)*30);
+ label(pic,string(hour),z,z);
+ draw(pic,z--(1-h)*z,p);
+}
+
+for(int minutes=0; minutes < 60; ++minutes) {
+ pair z=dir(6*minutes);
+ draw(pic,z--(1-m)*z);
+}
+
+dot(pic,(0,0));
+
+frame f=pic.fit();
+pair size=size(f)+(xmargin,ymargin);
+
+for(int i=0; i < nx; ++i)
+ for(int j=0; j < ny; ++j)
+ add(shift(realmult(size,(i,j)))*f);
+
diff --git a/graphics/asymptote/examples/coag.asy b/graphics/asymptote/examples/coag.asy
new file mode 100644
index 0000000000..de976cb145
--- /dev/null
+++ b/graphics/asymptote/examples/coag.asy
@@ -0,0 +1,16 @@
+size(0,200);
+import graph;
+
+pair z0=(0,0);
+pair m0=(0,1);
+pair tg=(1.5,0);
+pair mt=m0+tg;
+pair tf=(3,0);
+
+draw(m0--mt{dir(-70)}..{dir(0)}2tg+m0/4);
+xtick("$T_g$",tg,N);
+label("$M(t)$",mt,2NE);
+labely("$M_0$",m0);
+
+xaxis(Label("$t$",align=2S),Arrow);
+yaxis(Arrow);
diff --git a/graphics/asymptote/examples/colorpatch.asy b/graphics/asymptote/examples/colorpatch.asy
new file mode 100644
index 0000000000..e0f6b5b427
--- /dev/null
+++ b/graphics/asymptote/examples/colorpatch.asy
@@ -0,0 +1,18 @@
+import three;
+currentlight=Viewport;
+
+size(10cm);
+
+surface s=surface(patch(new triple[][] {
+ {(0,0,0),(1,0,0),(1,0,0),(2,0,0)},
+ {(0,1,0),(1,0,1),(1,0,1),(2,1,0)},
+ {(0,1,0),(1,0,-1),(1,0,-1),(2,1,0)},
+ {(0,2,0),(1,2,0),(1,2,0),(2,2,0)}}));
+
+s.s[0].colors=new pen[] {red,green,blue,black};
+draw(s,nolight);
+
+surface t=shift(Z)*unitplane;
+t.s[0].colors=new pen[] {red,green,blue,black};
+
+draw(t,nolight);
diff --git a/graphics/asymptote/examples/colorplanes.asy b/graphics/asymptote/examples/colorplanes.asy
new file mode 100644
index 0000000000..16bef25b54
--- /dev/null
+++ b/graphics/asymptote/examples/colorplanes.asy
@@ -0,0 +1,22 @@
+size(6cm,0);
+import bsp;
+
+real u=2.5;
+real v=1;
+
+currentprojection=oblique;
+
+path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
+path3 l=rotate(90,Z)*rotate(90,Y)*y;
+path3 g=rotate(90,X)*rotate(90,Y)*y;
+
+face[] faces;
+pen[] p={red,green,blue,black};
+int[] edges={0,0,0,2};
+gouraudshade(faces.push(y),project(y),p,edges);
+gouraudshade(faces.push(l),project(l),p,edges);
+gouraudshade(faces.push(g),project(g),new pen[]{cyan,magenta,yellow,black},
+ edges);
+
+add(faces);
+
diff --git a/graphics/asymptote/examples/condor.asy b/graphics/asymptote/examples/condor.asy
new file mode 100644
index 0000000000..5ce5caa241
--- /dev/null
+++ b/graphics/asymptote/examples/condor.asy
@@ -0,0 +1,32 @@
+// Peter Luschny's Condor function
+// http://www.luschny.de/math/asy/ElCondorYElGamma.html
+
+import palette;
+import graph3;
+
+size(300,300,IgnoreAspect);
+currentprojection=orthographic(0,-1,0,center=true);
+currentlight=White;
+real K=7;
+
+triple condor(pair t)
+{
+ real y=t.y;
+ real x=t.x*y;
+ real e=gamma(y+1);
+ real ymx=y-x;
+ real ypx=y+x;
+ real a=gamma((ymx+1)/2);
+ real b=gamma((ymx+2)/2);
+ real c=gamma((ypx+1)/2);
+ real d=gamma((ypx+2)/2);
+ real A=cos(pi*ymx);
+ real B=cos(pi*ypx);
+ return (x,y,log(e)+log(a)*((A-1)/2)+log(b)*((-A-1)/2)+log(c)*((B-1)/2)+
+ log(d)*((-B-1)/2));
+}
+
+surface s=surface(condor,(-1,0),(1,K),16,Spline);
+s.colors(palette(s.map(zpart),Rainbow()));
+
+draw(s,render(compression=Low,merge=true));
diff --git a/graphics/asymptote/examples/cones.asy b/graphics/asymptote/examples/cones.asy
new file mode 100644
index 0000000000..e63a428125
--- /dev/null
+++ b/graphics/asymptote/examples/cones.asy
@@ -0,0 +1,18 @@
+import solids;
+
+size(200);
+currentprojection=orthographic(5,4,2);
+
+render render=render(compression=Low,merge=true);
+
+revolution upcone=cone(-Z,1,1);
+revolution downcone=cone(Z,1,-1);
+draw(surface(upcone),green,render);
+draw(surface(downcone),green,render);
+draw(upcone,5,blue,longitudinalpen=nullpen);
+draw(downcone,5,blue,longitudinalpen=nullpen);
+
+revolution cone=shift(2Y-2X)*cone(1,1);
+
+draw(surface(cone),green,render);
+draw(cone,5,blue);
diff --git a/graphics/asymptote/examples/conicurv.asy b/graphics/asymptote/examples/conicurv.asy
new file mode 100644
index 0000000000..cb678710c1
--- /dev/null
+++ b/graphics/asymptote/examples/conicurv.asy
@@ -0,0 +1,49 @@
+// Original name : conicurv.mp
+// Author : L. Nobre G.
+// Translators : J. Pienaar (2004) and John Bowman (2005)
+
+import three;
+texpreamble("\usepackage{bm}");
+
+size(300,0);
+
+currentprojection=perspective(10,-5,5.44);
+
+real theta=30, width=3, shortradius=2, bord=2, refsize=1, vecsize=2;
+real height=0.3, anglar=1.75, totup=3;
+real longradius=shortradius+width*Cos(theta), updiff=width*Sin(theta);
+
+triple iplow=(0,shortradius,0), iphig=(0,longradius,updiff);
+triple oplow=(-shortradius,0,0), ophig=(-longradius,0,updiff);
+triple aplow=-iplow, aphig=(0,-longradius,updiff);
+triple eplow=-oplow, ephig=(longradius,0,updiff);
+triple anglebase=(0,longradius,0), centre=interp(iplow,iphig,0.5)+(0,0,height);
+triple central=(0,0,centre.z), refo=(0,0.5*centre.y,centre.z);
+triple refx=refsize*(0,Cos(theta),Sin(theta));
+triple refy=refsize*(0,-Sin(theta),Cos(theta));
+
+draw("$\theta$",arc(iplow,iplow+0.58*(iphig-iplow),anglebase),E);
+
+draw(central,linewidth(2bp));
+draw(iplow--iphig);
+draw(oplow--ophig);
+draw(aplow--aphig);
+draw(eplow--ephig);
+draw(iphig--anglebase--aplow,dashed);
+draw(oplow--eplow,dashed);
+draw(central--centre,dashed);
+
+draw((0,0,-bord)--(0,longradius+bord,-bord)--(0,longradius+bord,totup)
+ --(0,0,totup)--cycle);
+draw(Label("$y$",1),refo--refo+refy,SW,Arrow3);
+draw(Label("$x$",1),refo--refo+refx,SE,Arrow3);
+
+draw(Label("$\vec{R}_N$",1),centre--centre+vecsize*refy,E,Arrow3);
+draw(Label("$\vec{F}_a$",1),centre--centre+vecsize*refx,N,Arrow3);
+draw(Label("$\vec{F}_c$",1),centre--centre+vecsize*Y,NE,Arrow3);
+draw(Label("$\vec{P}$",1),centre--centre-vecsize*Z,E,Arrow3);
+draw(Label("$\vec{v}$",1),centre--centre+vecsize*X,E,Arrow3);
+draw(centre,10pt+blue);
+
+draw(circle((0,0,updiff),longradius),linewidth(2bp));
+draw(circle(O,shortradius),linewidth(2bp));
diff --git a/graphics/asymptote/examples/contextfonts.asy b/graphics/asymptote/examples/contextfonts.asy
new file mode 100644
index 0000000000..39177abdba
--- /dev/null
+++ b/graphics/asymptote/examples/contextfonts.asy
@@ -0,0 +1,10 @@
+settings.tex="context";
+// Work around ConTeXT bug for font sizes less than 12pt:
+texpreamble("\setupbodyfont[8pt]");
+
+usetypescript("iwona");
+usetypescript("antykwa-torunska");
+
+label("$A$",0,N,font("iwona"));
+label("$A$",0,S,font("antykwa",8pt)+red);
+
diff --git a/graphics/asymptote/examples/controlsystem.asy b/graphics/asymptote/examples/controlsystem.asy
new file mode 100644
index 0000000000..bfd8336f1f
--- /dev/null
+++ b/graphics/asymptote/examples/controlsystem.asy
@@ -0,0 +1,25 @@
+size(0,4cm);
+import flowchart;
+
+block delay=roundrectangle("$e^{-sT_t}$",(0.33,0));
+block system=roundrectangle("$\frac{s+3}{s^2+0.3s+1}$",(0.6,0));
+block controller=roundrectangle("$0.06\left( 1 + \frac{1}{s}\right)$",
+ (0.45,-0.25));
+block sum1=circle("",(0.15,0),mindiameter=0.3cm);
+block junction1=circle("",(0.75,0),fillpen=currentpen);
+
+draw(delay);
+draw(system);
+draw(controller);
+draw(sum1);
+draw(junction1);
+
+add(new void(picture pic, transform t) {
+ blockconnector operator --=blockconnector(pic,t);
+
+ block(0,0)--Label("$u$",align=N)--Arrow--sum1--Arrow--delay--Arrow--
+ system--junction1--Label("$y$",align=N)--Arrow--block(1,0);
+
+ junction1--Down--Left--Arrow--controller--Left--Up--
+ Label("$-$",position=3,align=ESE)--Arrow--sum1;
+ });
diff --git a/graphics/asymptote/examples/cos2theta.asy b/graphics/asymptote/examples/cos2theta.asy
new file mode 100644
index 0000000000..1be0c519fb
--- /dev/null
+++ b/graphics/asymptote/examples/cos2theta.asy
@@ -0,0 +1,15 @@
+import graph;
+size(0,100);
+
+real f(real t) {return cos(2*t);}
+
+path g=polargraph(f,0,2pi,operator ..)--cycle;
+fill(g,green+white);
+xaxis("$x$",above=true);
+yaxis("$y$",above=true);
+draw(g);
+
+dot(Label,(1,0),NE);
+dot(Label,(0,1),NE);
+
+
diff --git a/graphics/asymptote/examples/cos3.asy b/graphics/asymptote/examples/cos3.asy
new file mode 100644
index 0000000000..ef8054d662
--- /dev/null
+++ b/graphics/asymptote/examples/cos3.asy
@@ -0,0 +1,25 @@
+import graph3;
+import palette;
+
+size(12cm,IgnoreAspect);
+currentprojection=orthographic(1,-2,1);
+
+real f(pair z) {return abs(cos(z));}
+
+real Arg(triple v) {return degrees(cos((v.x,v.y)),warn=false);}
+
+surface s=surface(f,(-pi,-2),(pi,2),20,Spline);
+
+s.colors(palette(s.map(Arg),Wheel()));
+draw(s,render(compression=Low,merge=true));
+
+real xmin=point((-1,-1,-1)).x;
+real xmax=point((1,1,1)).x;
+draw((xmin,0,0)--(xmax,0,0),dashed);
+
+xaxis3("$\mathop{\rm Re} z$",Bounds,InTicks);
+yaxis3("$\mathop{\rm Im} z$",Bounds,InTicks(beginlabel=false));
+zaxis3("$|\cos(z)|$",Bounds,InTicks);
+
+
+
diff --git a/graphics/asymptote/examples/cosaddition.asy b/graphics/asymptote/examples/cosaddition.asy
new file mode 100644
index 0000000000..f6ce8de62a
--- /dev/null
+++ b/graphics/asymptote/examples/cosaddition.asy
@@ -0,0 +1,26 @@
+size(0,200);
+import geometry;
+
+real A=130;
+real B=40;
+
+pair O=(0,0);
+pair R=(1,0);
+pair P=dir(A);
+pair Q=dir(B);
+
+draw(circle(O,1.0));
+draw(Q--O--P);
+draw(P--Q,red);
+draw(O--Q--R--cycle);
+
+draw("$A$",arc(R,O,P,0.3),blue,Arrow,PenMargin);
+draw("$B$",arc(R,O,Q,0.6),blue,Arrow,PenMargin);
+pair S=(Cos(B),0);
+draw(Q--S,blue);
+perpendicular(S,NE,blue);
+
+dot(O);
+dot("$R=(1,0)$",R);
+dot("$P=(\cos A,\sin A)$",P,dir(O--P)+W);
+dot("$Q=(\cos B,\sin B)$",Q,dir(O--Q));
diff --git a/graphics/asymptote/examples/cpkcolors.asy b/graphics/asymptote/examples/cpkcolors.asy
new file mode 100644
index 0000000000..ddc7e286d5
--- /dev/null
+++ b/graphics/asymptote/examples/cpkcolors.asy
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: miguel@jmol.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+string[] Element={
+ "Xx", // 0
+ "H", // 1
+ "He", // 2
+ "Li", // 3
+ "Be", // 4
+ "B", // 5
+ "C", // 6
+ "N", // 7
+ "O", // 8
+ "F", // 9
+ "Ne", // 10
+ "Na", // 11
+ "Mg", // 12
+ "Al", // 13
+ "Si", // 14
+ "P", // 15
+ "S", // 16
+ "Cl", // 17
+ "Ar", // 18
+ "K", // 19
+ "Ca", // 20
+ "Sc", // 21
+ "Ti", // 22
+ "V", // 23
+ "Cr", // 24
+ "Mn", // 25
+ "Fe", // 26
+ "Co", // 27
+ "Ni", // 28
+ "Cu", // 29
+ "Zn", // 30
+ "Ga", // 31
+ "Ge", // 32
+ "As", // 33
+ "Se", // 34
+ "Br", // 35
+ "Kr", // 36
+ "Rb", // 37
+ "Sr", // 38
+ "Y", // 39
+ "Zr", // 40
+ "Nb", // 41
+ "Mo", // 42
+ "Tc", // 43
+ "Ru", // 44
+ "Rh", // 45
+ "Pd", // 46
+ "Ag", // 47
+ "Cd", // 48
+ "In", // 49
+ "Sn", // 50
+ "Sb", // 51
+ "Te", // 52
+ "I", // 53
+ "Xe", // 54
+ "Cs", // 55
+ "Ba", // 56
+ "La", // 57
+ "Ce", // 58
+ "Pr", // 59
+ "Nd", // 60
+ "Pm", // 61
+ "Sm", // 62
+ "Eu", // 63
+ "Gd", // 64
+ "Tb", // 65
+ "Dy", // 66
+ "Ho", // 67
+ "Er", // 68
+ "Tm", // 69
+ "Yb", // 70
+ "Lu", // 71
+ "Hf", // 72
+ "Ta", // 73
+ "W", // 74
+ "Re", // 75
+ "Os", // 76
+ "Ir", // 77
+ "Pt", // 78
+ "Au", // 79
+ "Hg", // 80
+ "Tl", // 81
+ "Pb", // 82
+ "Bi", // 83
+ "Po", // 84
+ "At", // 85
+ "Rn", // 86
+ "Fr", // 87
+ "Ra", // 88
+ "Ac", // 89
+ "Th", // 90
+ "Pa", // 91
+ "U", // 92
+ "Np", // 93
+ "Pu", // 94
+ "Am", // 95
+ "Cm", // 96
+ "Bk", // 97
+ "Cf", // 98
+ "Es", // 99
+ "Fm", // 100
+ "Md", // 101
+ "No", // 102
+ "Lr", // 103
+ "Rf", // 104
+ "Db", // 105
+ "Sg", // 106
+ "Bh", // 107
+ "Hs", // 108
+ "Mt", // 109
+ /*
+ "Ds", // 110
+ "Uuu",// 111
+ "Uub",// 112
+ "Uut",// 113
+ "Uuq",// 114
+ "Uup",// 115
+ "Uuh",// 116
+ "Uus",// 117
+ "Uuo",// 118
+ */
+};
+
+// Default table of CPK atom colors
+// (ghemical colors with a few proposed modifications).
+string[] Hexcolor={
+ "FF1493", // Xx 0
+ "FFFFFF", // H 1
+ "D9FFFF", // He 2
+ "CC80FF", // Li 3
+ "C2FF00", // Be 4
+ "FFB5B5", // B 5
+ "909090", // C 6 - changed from ghemical
+ "3050F8", // N 7 - changed from ghemical
+ "FF0D0D", // O 8
+ "90E050", // F 9 - changed from ghemical
+ "B3E3F5", // Ne 10
+ "AB5CF2", // Na 11
+ "8AFF00", // Mg 12
+ "BFA6A6", // Al 13
+ "F0C8A0", // Si 14 - changed from ghemical
+ "FF8000", // P 15
+ "FFFF30", // S 16
+ "1FF01F", // Cl 17
+ "80D1E3", // Ar 18
+ "8F40D4", // K 19
+ "3DFF00", // Ca 20
+ "E6E6E6", // Sc 21
+ "BFC2C7", // Ti 22
+ "A6A6AB", // V 23
+ "8A99C7", // Cr 24
+ "9C7AC7", // Mn 25
+ "E06633", // Fe 26 - changed from ghemical
+ "F090A0", // Co 27 - changed from ghemical
+ "50D050", // Ni 28 - changed from ghemical
+ "C88033", // Cu 29 - changed from ghemical
+ "7D80B0", // Zn 30
+ "C28F8F", // Ga 31
+ "668F8F", // Ge 32
+ "BD80E3", // As 33
+ "FFA100", // Se 34
+ "A62929", // Br 35
+ "5CB8D1", // Kr 36
+ "702EB0", // Rb 37
+ "00FF00", // Sr 38
+ "94FFFF", // Y 39
+ "94E0E0", // Zr 40
+ "73C2C9", // Nb 41
+ "54B5B5", // Mo 42
+ "3B9E9E", // Tc 43
+ "248F8F", // Ru 44
+ "0A7D8C", // Rh 45
+ "006985", // Pd 46
+ "C0C0C0", // Ag 47 - changed from ghemical
+ "FFD98F", // Cd 48
+ "A67573", // In 49
+ "668080", // Sn 50
+ "9E63B5", // Sb 51
+ "D47A00", // Te 52
+ "940094", // I 53
+ "429EB0", // Xe 54
+ "57178F", // Cs 55
+ "00C900", // Ba 56
+ "70D4FF", // La 57
+ "FFFFC7", // Ce 58
+ "D9FFC7", // Pr 59
+ "C7FFC7", // Nd 60
+ "A3FFC7", // Pm 61
+ "8FFFC7", // Sm 62
+ "61FFC7", // Eu 63
+ "45FFC7", // Gd 64
+ "30FFC7", // Tb 65
+ "1FFFC7", // Dy 66
+ "00FF9C", // Ho 67
+ "00E675", // Er 68
+ "00D452", // Tm 69
+ "00BF38", // Yb 70
+ "00AB24", // Lu 71
+ "4DC2FF", // Hf 72
+ "4DA6FF", // Ta 73
+ "2194D6", // W 74
+ "267DAB", // Re 75
+ "266696", // Os 76
+ "175487", // Ir 77
+ "D0D0E0", // Pt 78 - changed from ghemical
+ "FFD123", // Au 79 - changed from ghemical
+ "B8B8D0", // Hg 80 - changed from ghemical
+ "A6544D", // Tl 81
+ "575961", // Pb 82
+ "9E4FB5", // Bi 83
+ "AB5C00", // Po 84
+ "754F45", // At 85
+ "428296", // Rn 86
+ "420066", // Fr 87
+ "007D00", // Ra 88
+ "70ABFA", // Ac 89
+ "00BAFF", // Th 90
+ "00A1FF", // Pa 91
+ "008FFF", // U 92
+ "0080FF", // Np 93
+ "006BFF", // Pu 94
+ "545CF2", // Am 95
+ "785CE3", // Cm 96
+ "8A4FE3", // Bk 97
+ "A136D4", // Cf 98
+ "B31FD4", // Es 99
+ "B31FBA", // Fm 100
+ "B30DA6", // Md 101
+ "BD0D87", // No 102
+ "C70066", // Lr 103
+ "CC0059", // Rf 104
+ "D1004F", // Db 105
+ "D90045", // Sg 106
+ "E00038", // Bh 107
+ "E6002E", // Hs 108
+ "EB0026" // Mt 109
+};
+
+
diff --git a/graphics/asymptote/examples/curvedlabel.asy b/graphics/asymptote/examples/curvedlabel.asy
new file mode 100644
index 0000000000..2ff4c6c34e
--- /dev/null
+++ b/graphics/asymptote/examples/curvedlabel.asy
@@ -0,0 +1,4 @@
+size(200);
+import labelpath;
+labelpath("This is a test of curved labels in Asymptote (implemented with the {\tt PSTricks pstextpath} macro).",reverse(rotate(-90)*unitcircle));
+
diff --git a/graphics/asymptote/examples/curvedlabel3.asy b/graphics/asymptote/examples/curvedlabel3.asy
new file mode 100644
index 0000000000..5bee2342d8
--- /dev/null
+++ b/graphics/asymptote/examples/curvedlabel3.asy
@@ -0,0 +1,17 @@
+size(200);
+import labelpath3;
+
+path3 g=(1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle;
+path3 g2=shift(-Z)*reverse(unitcircle3);
+
+string txt1="\hbox{This is a test of \emph{curved} 3D labels in
+\textbf{Asymptote} (implemented with {\tt texpath}).}";
+
+string txt2="This is a test of curved labels in Asymptote\\(implemented
+without the {\tt PSTricks pstextpath} macro).";
+
+draw(surface(g),paleblue+opacity(0.5));
+draw(labelpath(txt1,subpath(g,0,reltime(g,0.95)),angle=-90),orange);
+
+draw(g2,1bp+red);
+draw(labelpath(txt2,subpath(g2,0,3.9),angle=180,optional=rotate(-70,X)*Z));
diff --git a/graphics/asymptote/examples/cyclohexane.asy b/graphics/asymptote/examples/cyclohexane.asy
new file mode 100644
index 0000000000..11b01551c8
--- /dev/null
+++ b/graphics/asymptote/examples/cyclohexane.asy
@@ -0,0 +1,80 @@
+import three;
+
+currentprojection=perspective(300,-650,500);
+currentlight.background=palecyan;
+
+surface carbon=scale3(70)*unitsphere; // 70 pm
+surface hydrogen=scale3(25)*unitsphere; // 25 pm
+
+real alpha=90+aSin(1/3);
+
+real CCbond=156; // 156 pm
+real CHbond=110; // 110 pm
+
+triple c1=(0,0,0);
+triple h1=c1+CHbond*Z;
+triple c2=rotate(alpha,c1,c1+Y)*(CCbond*Z);
+triple h2=rotate(120,c1,c2)*h1;
+triple h3=c2-CHbond*Z;
+triple h4=rotate(120,c2,c1)*h3;
+
+triple c3=rotate(120,c2,h3)*c1;
+triple h5=c3+CHbond*Z;
+triple h6=rotate(-120,c3,c2)*h5;
+
+triple c4=rotate(-120,c3,h5)*c2;
+triple h7=c4-CHbond*Z;
+triple h8=rotate(120,c4,c3)*h7;
+
+triple c5=rotate(120,c4,h7)*c3;
+triple h9=c5+CHbond*Z;
+triple h10=rotate(-120,c5,c4)*h9;
+
+triple c6=rotate(-120,c5,h9)*c4;
+triple h11=c6-CHbond*Z;
+triple h12=rotate(120,c6,c5)*h11;
+
+pen Black=gray(0.4);
+
+defaultrender=render(compression=Zero,merge=true);
+
+draw(shift(c1)*carbon,Black);
+draw(shift(c2)*carbon,Black);
+draw(shift(c3)*carbon,Black);
+draw(shift(c4)*carbon,Black);
+draw(shift(c5)*carbon,Black);
+draw(shift(c6)*carbon,Black);
+
+
+material White=material(diffusepen=gray(0.4),emissivepen=gray(0.6));
+
+draw(shift(h1)*hydrogen,White);
+draw(shift(h2)*hydrogen,White);
+draw(shift(h3)*hydrogen,White);
+draw(shift(h4)*hydrogen,White);
+draw(shift(h5)*hydrogen,White);
+draw(shift(h6)*hydrogen,White);
+draw(shift(h7)*hydrogen,White);
+draw(shift(h8)*hydrogen,White);
+draw(shift(h9)*hydrogen,White);
+draw(shift(h10)*hydrogen,White);
+draw(shift(h11)*hydrogen,White);
+draw(shift(h12)*hydrogen,White);
+
+
+pen thick=linewidth(10);
+
+draw(c1--c2--c3--c4--c5--c6--cycle,thick);
+
+draw(c1--h1,thick);
+draw(c1--h2,thick);
+draw(c2--h3,thick);
+draw(c2--h4,thick);
+draw(c3--h5,thick);
+draw(c3--h6,thick);
+draw(c4--h7,thick);
+draw(c4--h8,thick);
+draw(c5--h9,thick);
+draw(c5--h10,thick);
+draw(c6--h11,thick);
+draw(c6--h12,thick);
diff --git a/graphics/asymptote/examples/cylinder.asy b/graphics/asymptote/examples/cylinder.asy
new file mode 100644
index 0000000000..88ff1394ba
--- /dev/null
+++ b/graphics/asymptote/examples/cylinder.asy
@@ -0,0 +1,8 @@
+import solids;
+
+size(0,100);
+currentlight=Viewport;
+
+revolution r=cylinder(O,1,1.5,Y+Z);
+draw(surface(r),green,render(merge=true));
+draw(r,blue);
diff --git a/graphics/asymptote/examples/delu.asy b/graphics/asymptote/examples/delu.asy
new file mode 100644
index 0000000000..7f9853eb51
--- /dev/null
+++ b/graphics/asymptote/examples/delu.asy
@@ -0,0 +1,29 @@
+size(7cm,0);
+
+pair z1=(1,-0.25);
+pair v1=dir(45);
+pair z2=-z1;
+pair v2=0.75*dir(260);
+pair z3=(z1.x,-3);
+
+// A centered random number
+real crand() {return unitrand()-0.5;}
+
+guide g;
+pair lastz;
+for(int i=0; i < 60; ++i) {
+ pair z=0.75*lastz+(crand(),crand());
+ g=g..2.5*z;
+ lastz=z;
+}
+g=shift(0,-.5)*g..cycle;
+
+draw(g,gray(0.7));
+
+draw("$r$",z1--z2,RightSide,red,Arrows,DotMargins);
+draw(z1--z1+v1,Arrow);
+draw(z2--z2+v2,Arrow);
+draw(z3--z3+v1-v2,green,Arrow);
+
+dot("1",z1,S,blue);
+dot("2",z2,NW,blue);
diff --git a/graphics/asymptote/examples/dimension.asy b/graphics/asymptote/examples/dimension.asy
new file mode 100644
index 0000000000..1244ba84e6
--- /dev/null
+++ b/graphics/asymptote/examples/dimension.asy
@@ -0,0 +1,23 @@
+size(12cm,0);
+
+void distance(picture pic=currentpicture, pair A, pair B, Label L="", real n=0,
+ pen p=currentpen)
+{
+ real d=3mm;
+ path g=A--B;
+ transform T=shift(-n*d*unit(B-A)*I);
+ pic.add(new void(frame f, transform t) {
+ picture opic;
+ path G=T*t*g;
+ draw(opic,Label(L,Center,UnFill(1)),G,p,Arrows(NoFill),Bars,PenMargins);
+ add(f,opic.fit());
+ });
+ pic.addBox(min(g),max(g),T*min(p),T*max(p));
+}
+
+pair A=(0,0), B=(3,3);
+
+dot(A);
+dot(B);
+
+distance(A,B,"$\ell$",1);
diff --git a/graphics/asymptote/examples/dragon.asy b/graphics/asymptote/examples/dragon.asy
new file mode 100644
index 0000000000..08fcb61f5c
--- /dev/null
+++ b/graphics/asymptote/examples/dragon.asy
@@ -0,0 +1,66 @@
+pair crease(pair z1, pair z2, bool left)
+{
+ pair dz = z2 - z1;
+
+ if (left)
+ return z1 + dz * (0.5, 0.5);
+ else
+ return z1 + dz * (0.5, -0.5);
+}
+
+pair[] fold(pair[] oldz)
+{
+ int n = oldz.length;
+ pair[] newz = new pair[2n-1];
+
+ for (int i = 0; i < n-1; ++i)
+ {
+ newz[2i] = oldz[i];
+ newz[2i+1] = crease(oldz[i], oldz[i+1], i%2==0);
+ }
+
+ newz[2(n-1)] = oldz[n-1];
+
+ return newz;
+}
+
+pair[] dragon(int n, pair[] base={})
+{
+ if (base.length == 0)
+ if (n%2 == 0)
+ base = new pair[] {(0,0), (1,1) };
+ else
+ base = new pair[] {(0,0), (1,0) };
+
+ pair[] z = base;
+
+ for (int i = 1; i < n; ++i)
+ z = fold(z);
+
+ return z;
+}
+
+void drawtris(pair[] z, pen p = currentpen)
+{
+ int n = z.length;
+
+ for (int i = 0; i < n-2; i+=2)
+ fill(z[i]--z[i+1]--z[i+2]--cycle, p);
+}
+
+void drawtris(pair[] z, pen p1, pen p2)
+{
+ int n = z.length;
+
+ for (int i = 0; i < n-2; i+=2)
+ fill(z[i]--z[i+1]--z[i+2]--cycle, 2i < n-1 ? p1 : p2);
+}
+
+size(500,0);
+
+int n = 10;
+
+drawtris(dragon(n, new pair[] {(0,0), (1,0)}), black);
+drawtris(dragon(n, new pair[] {(0,0), (0,-1)}), blue);
+drawtris(dragon(n, new pair[] {(0,0), (-1,0)}), red);
+drawtris(dragon(n, new pair[] {(0,0), (0,1)}), green);
diff --git a/graphics/asymptote/examples/electromagnetic.asy b/graphics/asymptote/examples/electromagnetic.asy
new file mode 100644
index 0000000000..d229f76b74
--- /dev/null
+++ b/graphics/asymptote/examples/electromagnetic.asy
@@ -0,0 +1,47 @@
+import graph;
+import palette;
+texpreamble("\usepackage[amssymb,thinqspace,thinspace]{SIunits}");
+
+size(800,200);
+
+real c=3e8;
+real nm=1e-9;
+real freq(real lambda) {return c/(lambda*nm);}
+real lambda(real f) {return c/(f*nm);}
+
+real fmin=10;
+real fmax=1e23;
+
+scale(Log(true),Linear(true));
+xlimits(fmin,fmax);
+ylimits(0,1);
+
+real uv=freq(400);
+real ir=freq(700);
+
+bounds visible=bounds(Scale(uv).x,Scale(ir).x);
+palette(visible,uv,ir+(0,2),Bottom,Rainbow(),invisible);
+
+xaxis(Label("\hertz",1),Bottom,RightTicks,above=true);
+
+real log10Left(real x) {return -log10(x);}
+real pow10Left(real x) {return pow10(-x);}
+
+scaleT LogLeft=scaleT(log10Left,pow10Left,logarithmic=true);
+
+picture q=secondaryX(new void(picture p) {
+ scale(p,LogLeft,Linear);
+ xlimits(p,lambda(fmax),lambda(fmin));
+ ylimits(p,0,1);
+ xaxis(p,Label("\nano\metre",1,0.01N),Top,LeftTicks(DefaultLogFormat,n=10));
+ });
+
+add(q,above=true);
+
+margin margin=PenMargin(0,0);
+draw("radio",Scale((10,1))--Scale((5e12,1)),S,Arrow);
+draw("infrared",Scale((1e12,1.75))--Scale(shift(0,1.75)*ir),LeftSide,Arrows,margin);
+draw("UV",Scale(shift(0,1.75)*uv)--Scale((1e17,1.76)),LeftSide,Arrows,margin);
+draw("x-rays",Scale((1e16,1))--Scale((1e21,1)),RightSide,Arrows);
+draw("$\gamma$-rays",Scale((fmax,1.75))--Scale((2e18,1.75)),Arrow);
+
diff --git a/graphics/asymptote/examples/elevation.asy b/graphics/asymptote/examples/elevation.asy
new file mode 100644
index 0000000000..1ff4ee38f2
--- /dev/null
+++ b/graphics/asymptote/examples/elevation.asy
@@ -0,0 +1,17 @@
+import graph3;
+import grid3;
+import palette;
+
+currentprojection=orthographic(0.8,1,1);
+
+size(400,300,IgnoreAspect);
+
+defaultrender.merge=true;
+
+real f(pair z) {return cos(2*pi*z.x)*sin(2*pi*z.y);}
+
+surface s=surface(f,(-1/2,-1/2),(1/2,1/2),50,Spline);
+
+draw(s,mean(palette(s.map(zpart),Rainbow())),black);
+
+grid3(XYZgrid);
diff --git a/graphics/asymptote/examples/epix.asy b/graphics/asymptote/examples/epix.asy
new file mode 100644
index 0000000000..b833289bd8
--- /dev/null
+++ b/graphics/asymptote/examples/epix.asy
@@ -0,0 +1,14 @@
+import graph3;
+
+size(200,200,IgnoreAspect);
+
+currentprojection=perspective(4,2,3);
+
+real f(pair z) {return z.y^3/2-3z.x^2*z.y;}
+
+draw(surface(f,(-1,-1),(1,1),nx=10,Spline),green,render(merge=true));
+draw(Label("$y$",1),(0,0,0)--(0,2,0),red,Arrow3);
+
+draw(Label("$x$",1),(0,0,0)--(2,0,0),red,Arrow3);
+draw(Label("$z$",1),(0,0,0)--(0,0,2.5),red,Arrow3);
+label("$z=\frac{1}{2}y^3-3x^2y$",(1,1,1),NE);
diff --git a/graphics/asymptote/examples/equilateral.asy b/graphics/asymptote/examples/equilateral.asy
new file mode 100644
index 0000000000..d68e0d0222
--- /dev/null
+++ b/graphics/asymptote/examples/equilateral.asy
@@ -0,0 +1,12 @@
+size(10cm,0);
+import math;
+
+pair b=(0,0), c=(1,0);
+pair a=extension(b,b+dir(60),c,c+dir(120));
+pair d=extension(b,b+dir(30),a,a+dir(270));
+
+draw(a--b--c--a--d--b^^d--c);
+label("$A$",a,N);
+label("$B$",b,W);
+label("$C$",c,E);
+label("$D$",d,S);
diff --git a/graphics/asymptote/examples/equilchord.asy b/graphics/asymptote/examples/equilchord.asy
new file mode 100644
index 0000000000..b93da942d0
--- /dev/null
+++ b/graphics/asymptote/examples/equilchord.asy
@@ -0,0 +1,21 @@
+import graph3;
+
+size(0,150);
+currentprojection=perspective(5,-4,6);
+currentlight=(-1,-1,2);
+real t=0.5;
+
+real F(pair z) {
+ return (z.x^2+z.y^2 <= 1) ? sqrt(3)*(sqrt(1-z.x^2)-abs(z.y)) : 0;
+}
+
+real a=1.5;
+draw((-a,-a,0)--(-a,a,0)--(a,a,0)--(a,-a,0)--cycle,lightgray);
+
+xaxis3(Label("$x$",1),red,Arrow3);
+yaxis3(Label("$y$",1),red,Arrow3);
+draw(circle((0,0,0),1),dashed);
+draw(surface(F,(-1,-1),(t,1),20,monotonic),green,black,render(merge=true));
+real y=sqrt(1-t^2);
+draw((t,y,0)--(t,-y,0)--(t,0,sqrt(3)*y)--cycle,blue);
+label("$1$",(1,0,0),-Y+X);
diff --git a/graphics/asymptote/examples/exp3.asy b/graphics/asymptote/examples/exp3.asy
new file mode 100644
index 0000000000..39baba993f
--- /dev/null
+++ b/graphics/asymptote/examples/exp3.asy
@@ -0,0 +1,22 @@
+import graph3;
+import palette;
+
+size(12cm,IgnoreAspect);
+currentprojection=orthographic(1,-2,1);
+
+real f(pair z) {return abs(exp(z));}
+
+real Arg(triple v) {return degrees(exp((v.x,v.y)),warn=false);}
+
+surface s=surface(f,(-2,-pi),(2,pi),20,Spline);
+
+s.colors(palette(s.map(Arg),Wheel()));
+draw(s,render(compression=Low,merge=true));
+
+real xmin=point((-1,-1,-1)).x;
+real xmax=point((1,1,1)).x;
+draw((xmin,0,0)--(xmax,0,0),dashed);
+
+xaxis3("$\mathop{\rm Re} z$",Bounds,InTicks);
+yaxis3("$\mathop{\rm Im} z$",Bounds,InTicks(beginlabel=false));
+zaxis3("$|\exp(z)|$",Bounds,InTicks);
diff --git a/graphics/asymptote/examples/extrudedcontour.asy b/graphics/asymptote/examples/extrudedcontour.asy
new file mode 100644
index 0000000000..dabd56b929
--- /dev/null
+++ b/graphics/asymptote/examples/extrudedcontour.asy
@@ -0,0 +1,26 @@
+import contour;
+import palette;
+import graph3;
+
+defaultrender.merge=true;
+
+currentprojection=orthographic(25,10,10);
+size(0,12cm);
+real a=3;
+real b=4;
+real f(pair z) {return (z.x+z.y)/(2+cos(z.x)*sin(z.y));}
+guide[][] g=contour(f,(-10,-10),(10,10),new real[]{8},150);
+
+render render=render(merge=true);
+for(guide p:g[0]){
+ draw(extrude(p,8Z),palered,render);
+ draw(path3(p),red+2pt,render);
+}
+
+draw(lift(f,g),red+2pt,render);
+
+surface s=surface(f,(0,0),(10,10),20,Spline);
+s.colors(palette(s.map(zpart),Rainbow()+opacity(0.5)));
+draw(s,render);
+axes3("$x$","$y$","$z$",Arrow3);
+
diff --git a/graphics/asymptote/examples/fano.asy b/graphics/asymptote/examples/fano.asy
new file mode 100644
index 0000000000..12286d7006
--- /dev/null
+++ b/graphics/asymptote/examples/fano.asy
@@ -0,0 +1,28 @@
+import math;
+
+size(100,0);
+
+pair z4=(0,0);
+pair z7=(2,0);
+pair z1=point(rotate(60)*(z4--z7),1);
+
+pair z5=interp(z4,z7,0.5);
+pair z3=interp(z7,z1,0.5);
+pair z2=interp(z1,z4,0.5);
+pair z6=extension(z4,z3,z7,z2);
+
+draw(z4--z7--z1--cycle);
+draw(z4--z3);
+draw(z7--z2);
+draw(z1--z5);
+draw(circle(z6,abs(z3-z6)));
+
+label("1",z1,dir(z5--z1));
+label("2",z2,dir(z7--z2));
+label("3",z3,dir(z4--z3));
+label("4",z4,dir(z3--z4));
+label("5",z5,dir(z1--z5));
+label("6",z6,2.5E+0.1*N);
+label("7",z7,dir(z2--z7));
+
+
diff --git a/graphics/asymptote/examples/fequlogo.asy b/graphics/asymptote/examples/fequlogo.asy
new file mode 100644
index 0000000000..b928e42197
--- /dev/null
+++ b/graphics/asymptote/examples/fequlogo.asy
@@ -0,0 +1,40 @@
+// A compressed version of the required data file may be obtained from:
+// http://www-roc.inria.fr/gamma/download/counter.php?dir=ARCHITEC/&get_obj=uhrturm.obj.gz
+
+import graph3;
+import obj;
+
+size(200,0);
+size3(200);
+
+if(settings.render < 0) settings.render=8;
+
+texpreamble("\usepackage[T1]{fontenc}");
+texpreamble("\usepackage{ccfonts,eulervm}");
+
+currentprojection=perspective(4,1,2);
+currentlight=(4,0,2);
+currentlight.background=blue;
+
+real R=4;
+
+triple f1(pair t) {return (R*cos(t.x),R*sin(t.x),t.y);}
+
+draw(shift(-0.6Z)*scale3(0.66)*rotate(55,Z)*rotate(90,X)*
+ obj("uhrturm.obj",orange));
+
+surface s=surface(f1,(0,0),(2pi,2),8,8,Spline);
+
+string lo="$\displaystyle f(x+y)=f(x)+f(y)$";
+string hi="$\displaystyle F_{t+s}=F_t\circ F_s$";
+
+real h=0.0125;
+
+draw(surface(rotate(2)*xscale(0.32)*yscale(0.6)*lo,s,-pi/4-1.5*pi/20,0.5,h));
+draw(surface(rotate(0)*xscale(-0.45)*yscale(0.3)*hi,s,0.8*pi,0.25,h),blue);
+
+add(new void(frame f, transform3 t, picture pic, projection P) {
+ draw(f,surface(invert(box(min(f,P),max(f,P)),min3(f),P),
+ new pen[] {orange,red,yellow,brown}));
+ }
+);
diff --git a/graphics/asymptote/examples/fermi.asy b/graphics/asymptote/examples/fermi.asy
new file mode 100644
index 0000000000..c74da952ab
--- /dev/null
+++ b/graphics/asymptote/examples/fermi.asy
@@ -0,0 +1,40 @@
+import feynman;
+
+// set default line width to 0.8bp
+currentpen = linewidth(0.8);
+
+// scale all other defaults of the feynman module appropriately
+fmdefaults();
+
+// disable middle arrows
+currentarrow = None;
+
+// define vertex and external points
+
+pair xu = (-40,+45);
+pair xl = (-40,-45);
+pair yu = (+40,+45);
+pair yl = (+40,-45);
+
+pair zu = ( 0,+ 5);
+pair zl = ( 0,- 5);
+
+// define mid points
+
+pair mxu = (xu+zu)/2;
+pair mxl = (xl+zl)/2;
+pair myu = (yu+zu)/2;
+pair myl = (yl+zl)/2;
+
+// draw fermion lines
+drawFermion(xu--zu--yu);
+drawFermion(xl--zl--yl);
+
+// draw vertices
+drawVertexOX(zu);
+drawVertexOX(zl);
+
+// draw gluon. Note that the underlying fermion line is blotted out.
+drawGluon(arc((0,0),mxu,myl,CW));
+
+// shipout
diff --git a/graphics/asymptote/examples/filesurface.asy b/graphics/asymptote/examples/filesurface.asy
new file mode 100644
index 0000000000..b4817a0586
--- /dev/null
+++ b/graphics/asymptote/examples/filesurface.asy
@@ -0,0 +1,45 @@
+import graph3;
+import palette;
+
+size3(200,IgnoreAspect);
+
+file in=input("filesurface.dat").line();
+real[] x=in;
+real[] y=in;
+
+real[][] f=in;
+
+triple f(pair t) {
+ int i=round(t.x);
+ int j=round(t.y);
+ return (x[i],y[j],f[i][j]);
+}
+
+surface s=surface(f,(0,0),(x.length-1,y.length-1),x.length-1,y.length-1);
+real[] level=uniform(min(f)*(1-sqrtEpsilon),max(f)*(1+sqrtEpsilon),4);
+
+s.colors(palette(s.map(new real(triple v) {return find(level >= v.z);}),
+ Rainbow()));
+
+draw(s,meshpen=thick(),render(merge=true));
+
+triple m=currentpicture.userMin();
+triple M=currentpicture.userMax();
+triple target=0.5*(m+M);
+
+xaxis3("$x$",Bounds,InTicks);
+yaxis3("$y$",Bounds,InTicks(Step=1,step=0.1));
+zaxis3("$z$",Bounds,InTicks);
+
+/*
+picture palette;
+size3(palette,1cm);
+draw(palette,unitcube,red);
+frame F=palette.fit3();
+add(F,(M.x,m.y,m.z));
+*/
+
+currentprojection=perspective(camera=target+realmult(dir(68,225),M-m),
+ target=target);
+
+
diff --git a/graphics/asymptote/examples/filesurface.dat b/graphics/asymptote/examples/filesurface.dat
new file mode 100644
index 0000000000..16d5966f6b
--- /dev/null
+++ b/graphics/asymptote/examples/filesurface.dat
@@ -0,0 +1,12 @@
+1 12 24 36 60 84 120 180 240 360
+2005 2005.083333 2005.166667 2005.25 2005.333333 2005.416667 2005.5 2005.583333 2005.666667 2005.75 2005.833333 2005.916667 2006 2006.083333 2006.166667 2006.25 2006.333333 2006.416667 2006.5 2006.583333 2006.666667 2006.75 2006.833333 2006.916667 2007 2007.083333 2007.166667 2007.25 2007.333333 2007.416667 2007.5 2007.583333 2007.666667 2007.75 2007.833333 2007.916667 2008 2008.083333 2008.166667 2008.25 2008.333333 2008.416667 2008.5 2008.583333 2008.666667 2008.75 2008.833333 2008.916667
+2.111 2.1039 2.103 2.1047 2.1041 2.1039 2.1064 2.1126 2.1152 2.1209 2.2225 2.4112 2.3885 2.4586 2.6333 2.6489 2.6926 2.8691 2.9389 3.0941 3.1572 3.3501 3.4214 3.64 3.6159 3.6511 3.8439 3.859 3.9194 4.0982 4.105 4.3081 4.4339 4.2355 4.216 4.7114 4.1973 4.1821 4.3046 4.3691 4.3874 4.4724 4.4716 4.4875 4.6599 4.8313 3.8433 2.9929
+2.223809524 2.228 2.246190476 2.165238095 2.092727273 1.997272727 2.07185 2.14 2.128636364 2.327619048 2.577272727 2.67 2.717727273 2.793 2.978695652 3.094210526 3.175 3.271363636 3.415238095 3.489565217 3.573333333 3.664090909 3.723636364 3.773157895 3.914090909 3.9605 3.982727273 4.132105263 4.254545455 4.398095238 4.44 4.228695652 4.088 4.09 4.044090909 4.0855 3.870909091 3.631904762 3.711052632 3.955909091 4.141428571 4.562380952 4.575217391 4.36952381 4.210909091 2.93173913 2.3795 2.007727273
+2.431904762 2.4595 2.517142857 2.367619048 2.237272727 2.077727273 2.18235 2.253913043 2.222727273 2.484761905 2.743636364 2.804285714 2.862272727 2.968 3.192173913 3.343157895 3.381818182 3.462727273 3.574285714 3.575652174 3.602380952 3.657272727 3.677727273 3.744210526 3.926818182 3.954 3.922272727 4.105263158 4.255454545 4.464285714 4.475 4.183478261 4.0595 4.090434783 3.898636364 3.9975 3.68 3.334761905 3.402105263 3.781818182 4.07047619 4.624761905 4.542608696 4.178095238 4.008636364 3.151304348 2.641 2.375
+2.638095238 2.6685 2.735714286 2.562380952 2.416818182 2.241363636 2.33035 2.400869565 2.340454545 2.60952381 2.865454545 2.895238095 2.949545455 3.0775 3.297826087 3.477368421 3.521363636 3.589545455 3.685714286 3.640434783 3.614761905 3.674545455 3.668636364 3.742631579 3.938636364 3.9625 3.91 4.106842105 4.258636364 4.496666667 4.496818182 4.210869565 4.0975 4.138695652 3.933181818 4.027 3.719090909 3.413809524 3.434210526 3.818636364 4.071428571 4.622380952 4.56826087 4.157619048 3.993181818 3.358695652 2.8285 2.594090909
+2.996190476 3.015 3.124761905 2.920952381 2.753181818 2.581818182 2.6606 2.710869565 2.595 2.829047619 3.082272727 3.056190476 3.080909091 3.2445 3.45173913 3.664736842 3.703181818 3.74 3.82047619 3.726956522 3.655714286 3.712727273 3.669090909 3.753157895 3.970454545 4.0055 3.914090909 4.126315789 4.273181818 4.538095238 4.537727273 4.25826087 4.1655 4.210869565 3.982727273 4.1085 3.829545455 3.600952381 3.591578947 3.941363636 4.137619048 4.65952381 4.622173913 4.201428571 4.126363636 3.774782609 3.2075 2.983181818
+3.265714286 3.2665 3.405238095 3.21 3.04 2.87 2.9277 2.959565217 2.819545455 3.021428571 3.238636364 3.144761905 3.143636364 3.3225 3.536086957 3.798421053 3.85 3.867727273 3.91047619 3.803043478 3.706666667 3.757727273 3.700454545 3.775263158 4.003181818 4.037368421 3.938181818 4.156315789 4.288636364 4.566190476 4.546363636 4.31173913 4.23 4.27 4.076818182 4.185 3.949545455 3.793333333 3.730526316 4.043636364 4.219047619 4.636190476 4.62173913 4.258095238 4.190454545 3.967826087 3.53 3.192272727
+3.593809524 3.5845 3.745238095 3.543333333 3.381363636 3.209545455 3.249 3.282173913 3.122272727 3.285714286 3.488181818 3.380952381 3.344545455 3.497 3.674347826 3.935789474 4.004090909 4.004545455 4.029047619 3.906956522 3.778095238 3.817272727 3.75 3.811052632 4.055909091 4.091 3.99 4.203157895 4.330454545 4.614285714 4.590454545 4.393913043 4.344 4.397391304 4.234545455 4.346 4.165 4.105238095 4.044210526 4.252727273 4.398571429 4.718571429 4.705217391 4.407142857 4.379090909 4.255652174 3.998 3.514545455
+3.78952381 3.7435 3.9255 3.75 3.582272727 3.451363636 3.50775 3.513913043 3.359545455 3.494761905 3.665909091 3.551428571 3.504545455 3.6535 3.812608696 4.098421053 4.167272727 4.175909091 4.186666667 4.056086957 3.908571429 3.916363636 3.824545455 3.882105263 4.12 4.162 4.089090909 4.306315789 4.423181818 4.699047619 4.661818182 4.504782609 4.4985 4.519565217 4.402272727 4.5115 4.382727273 4.366666667 4.336842105 4.509545455 4.613809524 4.861428571 4.877391304 4.636666667 4.659545455 4.482173913 4.2535 3.744545455
+3.99 3.9085 4.098571429 3.944285714 3.771363636 3.609090909 3.6536 3.640869565 3.488181818 3.604761905 3.755454545 3.634285714 3.565909091 3.7165 3.866521739 4.151052632 4.235454545 4.235909091 4.249047619 4.116086957 3.961904762 3.953333333 3.855714286 3.92 4.153636364 4.1985 4.139090909 4.365789474 4.471818182 4.747142857 4.695454545 4.55 4.572 4.590434783 4.500909091 4.602 4.504090909 4.513809524 4.521052632 4.656818182 4.733809524 4.899047619 4.935652174 4.746190476 4.776818182 4.598695652 4.4835 3.900454545
+4.137142857 4.0305 4.213333333 4.08 3.902727273 3.739090909 3.774285714 3.757391304 3.598181818 3.706190476 3.842272727 3.712 3.629545455 3.771 3.919565217 4.231111111 4.295909091 4.306818182 4.31 4.170434783 4.000952381 3.99 3.881818182 3.943684211 4.176818182 4.2195 4.163636364 4.387368421 4.480454545 4.758095238 4.710454545 4.559565217 4.595 4.612173913 4.544090909 4.64 4.57 4.58 4.614736842 4.702727273 4.768571429 4.884761905 4.905652174 4.741904762 4.775454545 4.496521739 4.3585 3.738636364
diff --git a/graphics/asymptote/examples/fillcontour.asy b/graphics/asymptote/examples/fillcontour.asy
new file mode 100644
index 0000000000..311192fb7f
--- /dev/null
+++ b/graphics/asymptote/examples/fillcontour.asy
@@ -0,0 +1,29 @@
+import graph;
+import palette;
+import contour;
+
+size(12cm,IgnoreAspect);
+
+pair a=(pi/2,0);
+pair b=(3pi/2,2pi);
+
+real f(real x, real y) {return cos(x)*sin(y);}
+
+int N=100;
+int Divs=10;
+
+defaultpen(1bp);
+
+bounds range=bounds(-1,1);
+
+real[] Cvals=uniform(range.min,range.max,Divs);
+guide[][] g=contour(f,a,b,Cvals,N,operator --);
+
+pen[] Palette=quantize(Rainbow(),Divs);
+
+pen[][] interior=interior(g,extend(Palette,grey,black));
+fill(g,interior);
+draw(g);
+
+palette("$f(x,y)$",range,point(SE)+(0.5,0),point(NE)+(1,0),Right,Palette,
+ PaletteTicks("$%+#0.1f$",N=Divs));
diff --git a/graphics/asymptote/examples/fin.asy b/graphics/asymptote/examples/fin.asy
new file mode 100644
index 0000000000..8fe88f3dc0
--- /dev/null
+++ b/graphics/asymptote/examples/fin.asy
@@ -0,0 +1,152 @@
+import three;
+import palette;
+
+int N = 26;
+real[] C = array(N,0);
+real[][] A = new real[N][N];
+for(int i = 0; i < N; ++i)
+ for(int j = 0; j < N; ++j)
+ A[i][j] = 0;
+
+real Tb = 100; // deg C
+real h = 240; // 240 W/m^2 K
+real k = 240; // W/m K
+real Tinf = 20; // deg C
+real L = 12; // cm
+real t = 2; // cm
+
+real delta = 0.01; // 1 cm = 0.01 m
+
+// (1,2)-(2,2)-(3,2)-...-(13,2)
+// | | | |
+// (1,1)-(2,1)-(3,1)-...-(13,1)
+//
+// |
+// \ /
+// V
+//
+// 13-14-15-...-24-25
+// | | | ... | |
+// 0- 1- 2-...-11-12
+
+// but, note zero-based array indexing, so counting starts at 0
+int indexof(int m, int n)
+{
+ return 13(n-1)+m-1;
+}
+
+int i = 0;
+
+// fixed temperature bottom left
+A[i][indexof(1,1)] = 1; C[i] = Tb;
+++i;
+// fixed temperature middle left
+A[i][indexof(1,2)] = 1; C[i] = Tb;
+++i;
+
+// interior nodes
+for(int m = 2; m<13; ++m)
+{
+ A[i][indexof(m,2)] = -4;
+ A[i][indexof(m-1,2)] = A[i][indexof(m+1,2)] = 1;
+ A[i][indexof(m,1)] = 2;
+ C[i] = 0;
+ ++i;
+}
+
+// convective bottom side nodes
+for(int m = 2; m<13; ++m)
+{
+ A[i][indexof(m,1)] = -(2+h*delta/k);
+ A[i][indexof(m-1,1)] = A[i][indexof(m+1,1)] = 0.5;
+ A[i][indexof(m,2)] = 1;
+ C[i] = -h*delta*Tinf/k;
+ ++i;
+}
+
+// convective bottom right corner node
+A[i][indexof(13,2)] = A[i][indexof(12,1)] = 0.5;
+A[i][indexof(13,1)] = -(1+h*delta/k);
+C[i] = -h*delta*Tinf/k;
+++i;
+
+// convective middle right side node
+A[i][indexof(13,2)] = -(2+h*delta/k);
+A[i][indexof(13,1)] = 1;
+A[i][indexof(12,2)] = 1;
+C[i] = -h*delta*Tinf/k;
+++i;
+
+real[] T = solve(A,C);
+
+pen[] Palette = Gradient(256,blue,cyan,yellow,orange,red);
+
+real[][] T = {T[0:13],T[13:26],T[0:13]};
+T = transpose(T);
+
+size3(15cm);
+real w = 10;
+real h = 5;
+currentprojection = orthographic(2*(L,h,w),Y);
+draw((L,t,0)--(L,0,0)--(L,0,w)--(0,0,w)--(0,-h,w));
+draw((0,t,w)--(0,t+h,w)--(0,t+h,0)--(0,t,0));
+draw((L,0,w)--(L,t,w)--(0,t,w)--(0,t,0)--(L,t,0)--(L,t,w));
+
+real wo2 = 0.5*w;
+draw((0,0,wo2)--(0,t,wo2)--(L,t,wo2)--(L,0,wo2)--cycle);
+
+// centre points
+surface square = surface(shift(-0.5,-0.5,wo2)*unitsquare3);
+surface bottomsquare = surface(shift(-0.5,-0.5,wo2)*scale(1,0.5,1)*unitsquare3);
+surface topsquare = surface(shift(-0.5,0,wo2)*scale(1,0.5,1)*unitsquare3);
+surface leftsquare = surface(shift(-0.5,-0.5,wo2)*scale(0.5,1,1)*unitsquare3);
+surface rightsquare = surface(shift(0,-0.5,wo2)*scale(0.5,1,1)*unitsquare3);
+surface NEcorner = surface(shift(0,0,wo2)*scale(0.5,0.5,1)*unitsquare3);
+surface SEcorner = surface(shift(0,-0.5,wo2)*scale(0.5,0.5,1)*unitsquare3);
+surface SWcorner = surface(shift(-0.5,-0.5,wo2)*scale(0.5,0.5,1)*unitsquare3);
+surface NWcorner = surface(shift(-0.5,0,wo2)*scale(0.5,0.5,1)*unitsquare3);
+
+material lookupColour(int m,int n)
+{
+ int index = round(Palette.length*(T[m-1][n-1]-60)/(100-60));
+ if(index >= Palette.length) index = Palette.length-1;
+ return emissive(Palette[index]);
+}
+
+draw(shift(0,1,0)*rightsquare,lookupColour(1,2));
+for(int i = 2; i < 13; ++i)
+{
+ draw(shift(i-1,1,0)*square,lookupColour(i,2));
+}
+draw(shift(12,1,0)*leftsquare,lookupColour(13,2));
+
+draw(shift(0,2,0)*SEcorner,lookupColour(1,3));
+draw(shift(0,0,0)*NEcorner,lookupColour(1,1));
+for(int i = 2; i < 13; ++i)
+{
+ draw(shift(i-1,0,0)*topsquare,lookupColour(i,1));
+ draw(shift(i-1,2,0)*bottomsquare,lookupColour(i,3));
+}
+draw(shift(12,2,0)*SWcorner,lookupColour(13,3));
+draw(shift(12,0,0)*NWcorner,lookupColour(13,1));
+
+// annotations
+draw("$x$",(0,-h/2,w)--(L/4,-h/2,w),Y,Arrow3(HookHead2(normal=Z)),BeginBar3(Y));
+draw("$y$",(0,0,1.05*w)--(0,2t,1.05*w),Z,Arrow3(HookHead2(normal=X)),
+ BeginBar3(Z));
+draw("$z$",(L,-h/2,0)--(L,-h/2,w/4),Y,Arrow3(HookHead2(normal=X)),BeginBar3(Y));
+
+draw("$L$",(0,-h/4,w)--(L,-h/4,w),-Y,Arrows3(HookHead2(normal=Z)),
+ Bars3(Y),PenMargins2);
+draw("$w$",(L,-h/4,0)--(L,-h/4,w),-Y,Arrows3(HookHead2(normal=X)),
+ Bars3(Y),PenMargins2);
+draw("$t$",(1.05*L,0,0)--(1.05*L,t,0),-2Z,Arrows3(HookHead2(normal=Z)),
+ Bars3(X),PenMargins2);
+
+label(ZY()*"$T_b$",(0,t+h/2,wo2));
+
+label("$h$,$T_\infty$",(L/2,t+h/2,0),Y);
+path3 air = (L/2,t+h/3,w/3.5)--(1.5*L/2,t+2*h/3,w/8);
+draw(air,EndArrow3(TeXHead2));
+draw(shift(0.5,0,0)*air,EndArrow3(TeXHead2));
+draw(shift(1.0,0,0)*air,EndArrow3(TeXHead2));
diff --git a/graphics/asymptote/examples/fjortoft.asy b/graphics/asymptote/examples/fjortoft.asy
new file mode 100644
index 0000000000..0ef81ca2c0
--- /dev/null
+++ b/graphics/asymptote/examples/fjortoft.asy
@@ -0,0 +1,27 @@
+size(15cm,0);
+
+pair d=(1.5,1);
+real s=d.x+1;
+
+picture box(string s) {
+ picture pic;
+ draw(pic,box(0,d));
+ label(pic,s,d/2);
+ return pic;
+}
+
+add(box("$k_1$"));
+add(shift(s)*box("$k_2$"));
+add(shift(s)^2*box("$k_3$"));
+
+path g=(d.x,d.y/2)--(s,d.y/2);
+path G=(d.x/2,-(s-d.x))--(d.x/2,0);
+
+draw(Label(baseline("$\ldots$")),shift(-s)*g,BeginArrow,BeginPenMargin);
+draw(Label("$Z_1$"),g,BeginArrow,BeginPenMargin);
+draw(Label("$E_1$",LeftSide),g,Blank);
+draw(Label("$Z_3$"),shift(s)*g,Arrow,PenMargin);
+draw(Label("$E_3$",LeftSide),shift(s)*g,Blank);
+draw(Label("$Z_2$"),shift(s)*G,Arrow,PenMargin);
+draw(Label("$E_2$",LeftSide),shift(s)*G,Blank);
+draw(Label(baseline("$\ldots$")),shift(s)^2*g,Arrow,PenMargin);
diff --git a/graphics/asymptote/examples/floatingdisk.asy b/graphics/asymptote/examples/floatingdisk.asy
new file mode 100644
index 0000000000..be8b339767
--- /dev/null
+++ b/graphics/asymptote/examples/floatingdisk.asy
@@ -0,0 +1,26 @@
+import trembling;
+settings.outformat="pdf";
+size(6cm,0);
+
+real R=1/5;
+real h=0.5;
+real d=1/12;
+real l=.7;
+
+pair pA=(-l,0);
+pair pB=(l,0);
+
+tremble tr=tremble(angle=10,frequency=0.1,random=50,fuzz=1);
+path waterline=tr.deform(pA..pB);
+
+path disk=shift(0,-d)*scale(R)*unitcircle;
+path water=waterline--(l,-h)--(-l,-h)--(-l,0)--cycle;
+path container=(l,1/7)--(l,-h)--(-l,-h)--(-l,1/7);
+
+filldraw(disk,red,linewidth(.3));
+fill(water,mediumgrey+opacity(0.5));
+draw(waterline);
+
+draw(container,linewidth(1.5));
+
+shipout(bbox(2mm));
diff --git a/graphics/asymptote/examples/floor.asy b/graphics/asymptote/examples/floor.asy
new file mode 100644
index 0000000000..02c2446abe
--- /dev/null
+++ b/graphics/asymptote/examples/floor.asy
@@ -0,0 +1,28 @@
+import graph;
+unitsize(1cm);
+
+real Floor(real x) {return floor(x);}
+
+pair[] Close;
+pair[] Open;
+
+bool3 branch(real x) {
+ static real lasty;
+ static bool first=true;
+ real y=floor(x);
+ bool samebranch=first || lasty == y;
+ first=false;
+ if(samebranch) lasty=x;
+ else {
+ Close.push((x,lasty));
+ Open.push((x,y));
+ }
+ lasty=y;
+ return samebranch ? true : default;
+};
+
+draw(graph(Floor,-5.5,5.5,500,branch));
+axes("$x$",rotate(0)*"$\lfloor x\rfloor$",red);
+
+dot(Close);
+dot(Open,UnFill);
diff --git a/graphics/asymptote/examples/fractaltree.asy b/graphics/asymptote/examples/fractaltree.asy
new file mode 100644
index 0000000000..c9775ec69d
--- /dev/null
+++ b/graphics/asymptote/examples/fractaltree.asy
@@ -0,0 +1,27 @@
+size(200);
+
+path ltrans(path p,int d)
+{
+ path a=rotate(65)*scale(0.4)*p;
+ return shift(point(p,(1/d)*length(p))-point(a,0))*a;
+}
+path rtrans(path p, int d)
+{
+ path a=reflect(point(p,0),point(p,length(p)))*rotate(65)*scale(0.35)*p;
+ return shift(point(p,(1/d)*length(p))-point(a,0))*a;
+}
+
+void drawtree(int depth, path branch)
+{
+ if(depth == 0) return;
+ real breakp=(1/depth)*length(branch);
+ draw(subpath(branch,0,breakp),deepgreen);
+ drawtree(depth-1,subpath(branch,breakp,length(branch)));
+ drawtree(depth-1,ltrans(branch,depth));
+ drawtree(depth-1,rtrans(branch,depth));
+ return;
+}
+
+path start=(0,0)..controls (-1/10,1/3) and (-1/20,2/3)..(1/20,1);
+drawtree(6,start);
+
diff --git a/graphics/asymptote/examples/functionshading.asy b/graphics/asymptote/examples/functionshading.asy
new file mode 100644
index 0000000000..7cdeb6f4bf
--- /dev/null
+++ b/graphics/asymptote/examples/functionshading.asy
@@ -0,0 +1,31 @@
+size(200);
+
+settings.tex="pdflatex";
+
+// PostScript Calculator routine to convert from [0,1]x[0,1] to RG:
+string redgreen="0";
+
+// PostScript Calculator routine to convert from [0,1]x[0,1] to HS to RGB:
+// (http://www.texample.net/tikz/examples/hsv-shading):
+string hsv="0.5 sub exch 0.5 sub exch
+2 copy 2 copy 0 eq exch 0 eq and { pop pop 0.0 } {atan 360.0 div}
+ifelse dup 360 eq { pop 0.0 }{} ifelse 3 1 roll dup mul exch dup mul add
+sqrt 2.5 mul 0.25 sub 1 1 index 1.0
+eq { 3 1 roll pop pop dup dup } { 3 -1 roll 6.0 mul dup 4 1 roll floor dup
+5 1 roll 3 index sub neg 1.0 3 index sub 2 index mul 6 1 roll dup 3 index
+mul neg 1.0 add 2 index mul 7 1 roll neg 1.0 add 2 index mul neg 1.0 add 1
+index mul 7 2 roll pop pop dup 0 eq { pop exch pop } { dup 1 eq { pop exch
+4 1 roll exch pop } { dup 2 eq { pop 4 1 roll pop } { dup 3 eq { pop exch 4
+2 roll pop } { dup 4 eq { pop exch pop 3 -1 roll } { pop 3 1 roll exch pop
+} ifelse } ifelse } ifelse } ifelse } ifelse } ifelse cvr 3 1 roll cvr 3 1
+roll cvr 3 1 roll";
+
+path p=unitcircle;
+functionshade(p,rgb(zerowinding),redgreen);
+layer();
+draw(p);
+
+path g=shift(2*dir(-45))*p;
+functionshade(g,rgb(zerowinding),hsv);
+layer();
+draw(g);
diff --git a/graphics/asymptote/examples/galleon.asy b/graphics/asymptote/examples/galleon.asy
new file mode 100644
index 0000000000..1221fd5c86
--- /dev/null
+++ b/graphics/asymptote/examples/galleon.asy
@@ -0,0 +1,14 @@
+import obj;
+
+size(15cm);
+currentprojection=orthographic(0,2,5,up=Y);
+
+// A compressed version of the required data file may be obtained from:
+// http://www.cs.technion.ac.il/~irit/data/Viewpoint/galleon.obj.gz
+
+pen[] surfacepen={darkred,brown,darkred+orange,heavyred,heavyred,darkred+orange,
+ palegreen+blue+lightgrey,darkred,darkred,yellow,darkred,white,
+ white,white,white,white,white};
+surfacepen.cyclic=true;
+
+draw(obj("galleon.obj",verbose=false,surfacepen));
diff --git a/graphics/asymptote/examples/gamma.asy b/graphics/asymptote/examples/gamma.asy
new file mode 100644
index 0000000000..f92dd775ab
--- /dev/null
+++ b/graphics/asymptote/examples/gamma.asy
@@ -0,0 +1,24 @@
+import graph;
+size(300,IgnoreAspect);
+
+bool3 branch(real x)
+{
+ static int lastsign=0;
+ if(x <= 0 && x == floor(x)) return false;
+ int sign=sgn(gamma(x));
+ bool b=lastsign == 0 || sign == lastsign;
+ lastsign=sign;
+ return b ? true : default;
+}
+
+draw(graph(gamma,-4,4,n=2000,branch),red);
+
+scale(false);
+xlimits(-4,4);
+ylimits(-6,6);
+crop();
+
+xaxis("$x$",RightTicks(NoZero));
+yaxis(LeftTicks(NoZero));
+
+label("$\Gamma(x)$",(1,2),red);
diff --git a/graphics/asymptote/examples/gamma3.asy b/graphics/asymptote/examples/gamma3.asy
new file mode 100644
index 0000000000..e522dad4e7
--- /dev/null
+++ b/graphics/asymptote/examples/gamma3.asy
@@ -0,0 +1,33 @@
+import graph3;
+import palette;
+
+size(12cm,IgnoreAspect);
+currentprojection=orthographic(1,-2,1);
+
+real X=4.5;
+real M=abs(gamma((X,0)));
+
+pair Gamma(pair z)
+{
+ return (z.x > 0 || z != floor(z.x)) ? gamma(z) : M;
+}
+
+real f(pair z) {return min(abs(Gamma(z)),M);}
+
+surface s=surface(f,(-2.1,-2),(X,2),70,Spline);
+
+real Arg(triple v)
+{
+ return degrees(Gamma((v.x,v.y)),warn=false);
+}
+
+s.colors(palette(s.map(Arg),Wheel()));
+draw(s,render(compression=Low,merge=true));
+
+real xmin=point((-1,-1,-1)).x;
+real xmax=point((1,1,1)).x;
+draw((xmin,0,0)--(xmax,0,0),dashed);
+
+xaxis3("$\mathop{\rm Re} z$",Bounds,InTicks);
+yaxis3("$\mathop{\rm Im} z$",Bounds,InTicks(beginlabel=false));
+zaxis3("$|\Gamma(z)|$",Bounds,InTicks);
diff --git a/graphics/asymptote/examples/genusthree.asy b/graphics/asymptote/examples/genusthree.asy
new file mode 100644
index 0000000000..b3b7eb7f2b
--- /dev/null
+++ b/graphics/asymptote/examples/genusthree.asy
@@ -0,0 +1,23 @@
+size(8cm);
+
+import smoothcontour3;
+
+// Erdos lemniscate of order n:
+real erdos(pair z, int n) { return abs(z^n-1)^2 - 1; }
+
+real h = 0.12;
+
+// Erdos lemniscate of order 3:
+real lemn3(real x, real y) { return erdos((x,y), 3); }
+
+// "Inflate" the order 3 (planar) lemniscate into a
+// smooth surface:
+real f(real x, real y, real z) {
+ return lemn3(x,y)^2 + (16*abs((x,y))^4 + 1) * (z^2 - h^2);
+}
+
+// Draw the implicit surface on a box with diagonally opposite
+// corners at (-3,-3,-3), (3,3,3).
+draw(implicitsurface(f,a=(-3,-3,-3),b=(3,3,3),overlapedges=true),
+ surfacepen=material(diffusepen=gray(0.5),emissivepen=gray(0.4),
+ specularpen=gray(0.1)));
diff --git a/graphics/asymptote/examples/genustwo.asy b/graphics/asymptote/examples/genustwo.asy
new file mode 100644
index 0000000000..0d346481d0
--- /dev/null
+++ b/graphics/asymptote/examples/genustwo.asy
@@ -0,0 +1,36 @@
+size(10cm,0);
+import smoothcontour3;
+currentprojection=perspective((18,20,10));
+if(settings.render < 0) settings.render=8;
+
+real tuberadius = 0.69;
+
+// Convert to cylindrical coordinates to draw
+// a circle revolved about the z axis.
+real toruscontour(real x, real y, real z) {
+ real r = sqrt(x^2 + y^2);
+ return (r-2)^2 + z^2 - tuberadius^2;
+}
+
+// Take the union of the two tangent tori (by taking
+// the product of the functions defining them). Then
+// add (or subtract) a bit of noise to smooth things
+// out.
+real f(real x, real y, real z) {
+ real f1 = toruscontour(x - 2 - tuberadius, y, z);
+ real f2 = toruscontour(x + 2 + tuberadius, y, z);
+ return f1 * f2 - 0.1;
+}
+
+// The noisy function extends a bit farther than the union of
+// the two tori, so include a bit of extra space in the box.
+triple max = (2*(2+tuberadius), 2+tuberadius, tuberadius)
+ + (0.1, 0.1, 0.1);
+triple min = -max;
+
+// Draw the implicit surface.
+draw(implicitsurface(f, min, max, overlapedges=true,
+ nx=20, nz=5),
+ surfacepen=material(diffusepen=gray(0.6),
+ emissivepen=gray(0.3),
+ specularpen=gray(0.1)));
diff --git a/graphics/asymptote/examples/grid.asy b/graphics/asymptote/examples/grid.asy
new file mode 100644
index 0000000000..a607ac78e2
--- /dev/null
+++ b/graphics/asymptote/examples/grid.asy
@@ -0,0 +1,7 @@
+import math;
+size(100,0);
+
+add(shift(-5,-5)*grid(10,10));
+
+dot((0,0),red);
+
diff --git a/graphics/asymptote/examples/hierarchy.asy b/graphics/asymptote/examples/hierarchy.asy
new file mode 100644
index 0000000000..fdb833e652
--- /dev/null
+++ b/graphics/asymptote/examples/hierarchy.asy
@@ -0,0 +1,9 @@
+texpreamble("\def\Ham{\mathop {\rm Ham}\nolimits}");
+pair align=2N;
+frame f;
+ellipse(f,Label("$\Ham(r,2)$",(0,0)),lightblue,Fill,above=false);
+ellipse(f,Label("BCH Codes",point(f,N),align),green,Fill,above=false);
+ellipse(f,Label("Cyclic Codes",point(f,N),align),lightmagenta,Fill,above=false);
+ellipse(f,Label("Linear Codes",point(f,N),align),-4mm,orange,Fill,above=false);
+box(f,Label("General Codes",point(f,N),align),2mm,yellow,Fill,above=false);
+add(f);
diff --git a/graphics/asymptote/examples/hyperboloid.asy b/graphics/asymptote/examples/hyperboloid.asy
new file mode 100644
index 0000000000..22f3b3d80b
--- /dev/null
+++ b/graphics/asymptote/examples/hyperboloid.asy
@@ -0,0 +1,8 @@
+size(200);
+import solids;
+
+currentprojection=perspective(4,4,3);
+revolution hyperboloid=revolution(graph(new triple(real z) {
+ return (sqrt(1+z*z),0,z);},-2,2,20,operator ..),axis=Z);
+draw(surface(hyperboloid),green,render(compression=Low,merge=true));
+draw(hyperboloid,6,blue,longitudinalpen=nullpen);
diff --git a/graphics/asymptote/examples/hyperboloidsilhouette.asy b/graphics/asymptote/examples/hyperboloidsilhouette.asy
new file mode 100644
index 0000000000..1bb265de62
--- /dev/null
+++ b/graphics/asymptote/examples/hyperboloidsilhouette.asy
@@ -0,0 +1,9 @@
+size(200);
+import solids;
+settings.render=0;
+settings.prc=false;
+
+currentprojection=perspective(4,4,3);
+revolution hyperboloid=revolution(graph(new triple(real z) {
+ return (sqrt(1+z*z),0,z);},-2,2,20,operator ..),axis=Z);
+draw(hyperboloid.silhouette(64),blue);
diff --git a/graphics/asymptote/examples/imagehistogram.asy b/graphics/asymptote/examples/imagehistogram.asy
new file mode 100644
index 0000000000..d3bdc78375
--- /dev/null
+++ b/graphics/asymptote/examples/imagehistogram.asy
@@ -0,0 +1,47 @@
+import stats;
+import graph;
+import palette;
+import contour;
+
+size(20cm);
+
+scale(false);
+
+pair[] data=new pair[50000];
+for(int i=0; i < data.length; ++i)
+ data[i]=Gaussrandpair();
+
+// Histogram limits and number of bins
+pair datamin=(-0.15,-0.15);
+pair datamax=(0.15,0.15);
+int Nx=30;
+int Ny=30;
+
+int[][] bins=frequency(data,datamin,datamax,Nx,Ny);
+
+real[] values=new real[Nx*Ny];
+pair[] points=new pair[Nx*Ny];
+int k=0;
+real dx=(datamax.x-datamin.x)/Nx;
+real dy=(datamax.y-datamin.y)/Ny;
+for(int i=0; i < Nx; ++i) {
+ for(int j=0; j < Ny; ++j) {
+ values[k]=bins[i][j];
+ points[k]=(datamin.x+(i+0.5)*dx,datamin.y+(j+0.5)*dy);
+ ++k;
+ }
+}
+
+// Create a color palette
+pen[] InvGrayscale(int NColors=256) {
+ real ninv=1.0/(NColors-1.0);
+ return sequence(new pen(int i) {return gray(1-17*i*ninv);},NColors);
+}
+
+// Draw the histogram, with axes
+bounds range=image(points,values,Range(0,40),InvGrayscale());
+draw(contour(points,values,new real[] {1,2,3,4,8,12,16,20,24,28,32,36,40},
+ operator--),blue);
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
diff --git a/graphics/asymptote/examples/impact.asy b/graphics/asymptote/examples/impact.asy
new file mode 100644
index 0000000000..d903969777
--- /dev/null
+++ b/graphics/asymptote/examples/impact.asy
@@ -0,0 +1,29 @@
+// Contributed by Philippe Ivaldi.
+// http://www.piprime.fr/
+
+import graph3 ;
+import contour;
+size (6cm,0);
+currentprojection=orthographic(1,1,1) ;
+
+real rc=1, hc=2, c=rc/hc;
+draw(shift(hc*Z)*scale(rc,rc,-hc)*unitcone,blue);
+
+triple Os=(0.5,0.5,1);
+real r=0.5;
+draw(shift(Os)*scale3(r)*unitsphere,red);
+
+real a=1+1/c^2;
+real b=abs(Os)^2-r^2;
+
+real f(pair z)
+{
+ real x=z.x, y=z.y;
+ return a*x^2-2*Os.x*x+a*y^2-2*Os.y*y-2*Os.z*sqrt(x^2+y^2)/c+b;
+}
+
+real g(pair z){return (sqrt(z.x^2+z.y^2))/c;}
+
+draw(lift(g,contour(f,(-rc,-rc),(rc,rc),new real[]{0})),linewidth(2bp)+yellow);
+
+axes3("$x$","$y$","$z$",Arrow3);
diff --git a/graphics/asymptote/examples/integraltest.asy b/graphics/asymptote/examples/integraltest.asy
new file mode 100644
index 0000000000..c45b1eb8f1
--- /dev/null
+++ b/graphics/asymptote/examples/integraltest.asy
@@ -0,0 +1,38 @@
+import graph;
+size(300,150,IgnoreAspect);
+
+real f(real x) {return 1/x^(1.1);}
+pair F(real x) {return (x,f(x));}
+
+dotfactor=7;
+
+void subinterval(real a, real b)
+{
+ path g=box((a,0),(b,f(b)));
+ filldraw(g,lightgray);
+ draw(box((a,f(a)),(b,0)));
+}
+
+int a=1, b=9;
+
+xaxis("$x$",0,b);
+yaxis("$y$",0);
+
+draw(graph(f,a,b,operator ..),red);
+
+int n=2;
+
+for(int i=a; i <= b; ++i) {
+ if(i < b) subinterval(i,i+1);
+ if(i <= n) labelx(i);
+ dot(F(i));
+}
+
+int i=n;
+labelx("$\ldots$",++i);
+labelx("$k$",++i);
+labelx("$k+1$",++i);
+labelx("$\ldots$",++i);
+
+arrow("$f(x)$",F(i-1.5),NE,1.5cm,red,Margin(0,0.5));
+
diff --git a/graphics/asymptote/examples/interpolate1.asy b/graphics/asymptote/examples/interpolate1.asy
new file mode 100644
index 0000000000..8845c8dd2f
--- /dev/null
+++ b/graphics/asymptote/examples/interpolate1.asy
@@ -0,0 +1,226 @@
+// Lagrange and Hermite interpolation in Asymptote
+// Author: Olivier Guibé
+
+import interpolate;
+import graph;
+
+// Test 1: The Runge effect in the Lagrange interpolation of 1/(x^2+1).
+
+unitsize(2cm);
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=15;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+xlimits(-5,5);
+ylimits(-1,1,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+attach(legend(),point(10S),30S);
+
+shipout("runge1");
+
+erase();
+
+// Test 2: The Runge effect in the Hermite interpolation of 1/(x^2+1).
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=16;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=hdiffdiv(x,y,dy);
+fhorner ph=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}H_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+unitsize(2cm);
+
+xlimits(-5,5);
+ylimits(-1,5,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+attach(legend(),point(10S),30S);
+
+shipout("runge2");
+
+erase();
+
+// Test 3: The Runge effect does not occur for all functions:
+// Lagrange interpolation of a function whose successive derivatives
+// are bounded by a constant M (here M=1) is shown here to converge.
+
+real f(real x) {return(sin(x));}
+real df(real x) {return(cos(x));}
+
+real a=-5, b=5;
+int n=16;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+
+draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+attach(legend(),point(10S),30S);
+
+shipout("runge3");
+
+erase();
+
+// Test 4: However, one notes here that numerical artifacts may arise
+// from limit precision (typically 1e-16).
+
+real f(real x) {return(sin(x));}
+real df(real x) {return(cos(x));}
+
+real a=-5, b=5;
+int n=72;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+
+draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$");
+
+ylimits(-1,5,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+attach(legend(),point(10S),30S);
+
+shipout("runge4");
+
+erase();
+
+// Test 5: The situation is much better using Tchebychev points.
+
+unitsize(2cm);
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=16;
+real[] x,y,dy;
+fhorner p,ph,ph1;
+for(int i=0; i <= n; ++i)
+ x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+
+draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+xlimits(-5,5);
+ylimits(-1,2,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+shipout("runge5");
+
+erase();
+
+// Test 6: Adding a few more Tchebychev points yields a very good result.
+
+unitsize(2cm);
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=26;
+real[] x,y,dy;
+for(int i=0; i <= n; ++i)
+ x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+xlimits(-5,5);
+ylimits(-1,2,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+
+shipout("runge6");
+
+erase();
+
+// Test 7: Another Tchebychev example.
+
+unitsize(2cm);
+
+real f(real x) {return(sqrt(abs(x-1)));}
+
+real a=-2, b=2;
+int n=30;
+real[] x,y,dy;
+for(int i=0; i <= n; ++i)
+ x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\sqrt{|x-1|}$");
+
+xlimits(-2,2);
+ylimits(-0.5,2,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+shipout("runge7");
diff --git a/graphics/asymptote/examples/jump.asy b/graphics/asymptote/examples/jump.asy
new file mode 100644
index 0000000000..7ae19be388
--- /dev/null
+++ b/graphics/asymptote/examples/jump.asy
@@ -0,0 +1,14 @@
+import graph;
+size(4inches,0);
+
+real f1(real x) {return (1+x^2);}
+real f2(real x) {return (4-x);}
+
+xaxis("$x$",LeftTicks,Arrow);
+yaxis("$y$",RightTicks,Arrow);
+
+draw("$y=1+x^2$",graph(f1,-2,1));
+dot((1,f1(1)),UnFill);
+
+draw("$y=4-x$",graph(f2,1,5),LeftSide,red,Arrow);
+dot((1,f2(1)),red);
diff --git a/graphics/asymptote/examples/label3.asy b/graphics/asymptote/examples/label3.asy
new file mode 100644
index 0000000000..f8d5e07049
--- /dev/null
+++ b/graphics/asymptote/examples/label3.asy
@@ -0,0 +1,7 @@
+import three;
+
+currentprojection=perspective(0,0,1,up=Y);
+
+label(scale(4)*"$\displaystyle\int_{-\infty}^{+\infty} e^{-\alpha x^2}\,dx=
+\sqrt{\frac{\pi}{\alpha}}$",O,blue,Embedded);
+
diff --git a/graphics/asymptote/examples/label3ribbon.asy b/graphics/asymptote/examples/label3ribbon.asy
new file mode 100644
index 0000000000..59ccbc9237
--- /dev/null
+++ b/graphics/asymptote/examples/label3ribbon.asy
@@ -0,0 +1,6 @@
+import three;
+
+currentprojection=perspective(100,100,200,up=Y);
+
+draw(scale3(4)*extrude(texpath("$\displaystyle\int_{-\infty}^{+\infty}
+e^{-\alpha x^2}\,dx=\sqrt{\frac{\pi}{\alpha}}$"),2Z),blue);
diff --git a/graphics/asymptote/examples/label3solid.asy b/graphics/asymptote/examples/label3solid.asy
new file mode 100644
index 0000000000..476d41fdbc
--- /dev/null
+++ b/graphics/asymptote/examples/label3solid.asy
@@ -0,0 +1,6 @@
+import three;
+
+currentprojection=perspective(100,100,200,up=Y);
+
+draw(scale3(4)*extrude("$\displaystyle\int_{-\infty}^{+\infty}
+e^{-\alpha x^2}\,dx=\sqrt{\frac{\pi}{\alpha}}$",2Z),blue);
diff --git a/graphics/asymptote/examples/label3zoom.asy b/graphics/asymptote/examples/label3zoom.asy
new file mode 100644
index 0000000000..cba4f98cb5
--- /dev/null
+++ b/graphics/asymptote/examples/label3zoom.asy
@@ -0,0 +1,16 @@
+import three;
+
+currentlight=Headlamp;
+size(469.75499pt,0);
+
+currentprojection=perspective(
+camera=(160.119024441391,136.348802919248,253.822628496226),
+up=(-0.188035408976828,0.910392236102215,-0.368549401594584),
+target=(25.5462739598034,1.77605243766079,-9.93996244768584),
+zoom=5.59734733413271,
+angle=5.14449021168139,
+viewportshift=(0.813449720559684,-0.604674743165144),
+autoadjust=false);
+
+draw(scale3(4)*extrude("$\displaystyle\int\limits_{-\infty}^{+\infty}\!\! e^{-\alpha x^2}\!\!=\sqrt{\frac{\pi}{\alpha}}$",2Z),
+ material(blue));
diff --git a/graphics/asymptote/examples/labelbox.asy b/graphics/asymptote/examples/labelbox.asy
new file mode 100644
index 0000000000..38153b856e
--- /dev/null
+++ b/graphics/asymptote/examples/labelbox.asy
@@ -0,0 +1,11 @@
+size(0,100);
+real margin=2mm;
+pair z1=(0,1);
+pair z0=(0,0);
+
+object Box=draw("small box",box,z1,margin);
+object Ellipse=draw("LARGE ELLIPSE",ellipse,z0,margin);
+
+add(new void(frame f, transform t) {
+ draw(f,point(Box,SW,t){SW}..{SW}point(Ellipse,NNE,t));
+ });
diff --git a/graphics/asymptote/examples/laserlattice.asy b/graphics/asymptote/examples/laserlattice.asy
new file mode 100644
index 0000000000..da4d9a49b7
--- /dev/null
+++ b/graphics/asymptote/examples/laserlattice.asy
@@ -0,0 +1,44 @@
+import graph;
+import palette;
+
+int n=256;
+pen[] Palette=BWRainbow();
+
+real w(real w0, real z0, real z) {return w0*sqrt(1+(z/z0)^2);}
+
+real pot(real lambda, real w0, real r, real z)
+{
+ real z0=pi*w0^2/lambda, kappa=2pi/lambda;
+ return exp(-2*(r/w(w0,z0,z))^2)*cos(kappa*z)^2;
+}
+
+picture make_field(real lambda, real w0)
+{
+ real[][] v=new real[n][n];
+ for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=pot(lambda,w0,i-n/2,abs(j-n/2));
+
+ picture p=new picture;
+ size(p,250,250,IgnoreAspect);
+ real xm=-n/lambda, ym=-n/(2*w0), xx=n/lambda, yx=n/(2*w0);
+ image(p,v,(xm,ym),(xx,yx),Palette);
+ xlimits(p,xm,xx);
+ ylimits(p,ym,yx);
+ xaxis(p,"{\Large $z/\frac{\lambda}{2}$}",BottomTop,LeftTicks);
+ yaxis(p,"{\Large $r/w_0$}",LeftRight,RightTicks);
+ label(p,format("{\LARGE $w_0/\lambda=%.2f$}",w0/lambda),point(p,NW),5N);
+
+ return p;
+}
+
+picture p=make_field(160,80);
+picture q=make_field(80,80);
+picture r=make_field(16,80);
+picture s=make_field(2,80);
+
+real margin=1cm;
+add(p.fit(),(0,0),margin*NW);
+add(q.fit(),(0,0),margin*NE);
+add(r.fit(),(0,0),margin*SW);
+add(s.fit(),(0,0),margin*SE);
diff --git a/graphics/asymptote/examples/latticeshading.asy b/graphics/asymptote/examples/latticeshading.asy
new file mode 100644
index 0000000000..c6689fa72d
--- /dev/null
+++ b/graphics/asymptote/examples/latticeshading.asy
@@ -0,0 +1,7 @@
+size(200);
+
+pen[][] p={{white,grey,black},
+ {red,green,blue},
+ {cyan,magenta,yellow}};
+
+latticeshade(unitsquare,p);
diff --git a/graphics/asymptote/examples/layers.asy b/graphics/asymptote/examples/layers.asy
new file mode 100644
index 0000000000..4fe745f6a3
--- /dev/null
+++ b/graphics/asymptote/examples/layers.asy
@@ -0,0 +1,44 @@
+usepackage("ocg");
+settings.tex="pdflatex";
+
+size(0,150);
+
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+
+begin("A");
+fill(c1,colour1);
+end();
+
+fill(c2,colour2);
+
+picture intersection;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+label("$A$",z1);
+
+begin("B");
+label("$B$",z2);
+end();
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
diff --git a/graphics/asymptote/examples/lever.asy b/graphics/asymptote/examples/lever.asy
new file mode 100644
index 0000000000..a0c81f5a47
--- /dev/null
+++ b/graphics/asymptote/examples/lever.asy
@@ -0,0 +1,23 @@
+size(200,0);
+
+pair z0=(0,0);
+pair z1=(2,0);
+pair z2=(5,0);
+pair zf=z1+0.75*(z2-z1);
+
+draw(z1--z2);
+dot(z1,red+0.15cm);
+dot(z2,darkgreen+0.3cm);
+label("$m$",z1,1.2N,red);
+label("$M$",z2,1.5N,darkgreen);
+label("$\hat{\ }$",zf,0.2*S,fontsize(24pt)+blue);
+
+pair s=-0.2*I;
+draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
+
+s=-0.5*I;
+draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
+
+s=-0.95*I;
+draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
+
diff --git a/graphics/asymptote/examples/limit.asy b/graphics/asymptote/examples/limit.asy
new file mode 100644
index 0000000000..ef71928941
--- /dev/null
+++ b/graphics/asymptote/examples/limit.asy
@@ -0,0 +1,28 @@
+size(200,200,IgnoreAspect);
+import graph;
+
+real L=1;
+real epsilon=0.25;
+
+real a(int n) {return L+1/n;}
+
+for(int i=1; i < 20; ++i)
+ dot((i,a(i)));
+
+real N=1/epsilon;
+
+xaxis(Label("$n$",align=2S));
+yaxis(Label("$a_n$",0.85));
+
+xtick("$2$",2);
+ytick("$\frac{3}{2}$",3/2);
+ytick("$2$",2);
+
+yequals(Label("$L$",0,up),L,extend=true,blue);
+yequals(Label("$L+\epsilon$",1,NW),L+epsilon,extend=true,red+dashed);
+yequals(Label("$L-\epsilon$",1,SW),L-epsilon,extend=true,red+dashed);
+
+xequals(N,extend=true,darkgreen+dashed);
+labelx(shift(0,-10)*"$N=\frac{1}{\epsilon}$",N,E,darkgreen);
+
+label("$a_n=1+\frac{1}{n},\quad \epsilon=\frac{1}{4}$",point((0,1)),10S+E);
diff --git a/graphics/asymptote/examples/linearregression.asy b/graphics/asymptote/examples/linearregression.asy
new file mode 100644
index 0000000000..a1cc6ff6bc
--- /dev/null
+++ b/graphics/asymptote/examples/linearregression.asy
@@ -0,0 +1,64 @@
+import graph3;
+import math; // for the leastsquares routine
+
+Billboard.targetsize = true; // Perspective should not affect the labels.
+currentprojection = perspective(60 * (5, 2, 3));
+
+file duncan = input("linearregression.dat");
+
+string headers = duncan;
+
+real[][] independentvars;
+real[] dependentvars;
+
+while (!eof(duncan)) {
+ string line = duncan;
+ string[] entries = split(line);
+ if (entries.length < 5) continue;
+ string type = entries[1];
+ real income = (real)(entries[2]);
+ real education = (real)(entries[3]);
+ real prestige = (real)(entries[4]);
+
+ // include 1.0 for the residue
+ independentvars.push(new real[] {income, education, 1.0});
+ dependentvars.push(prestige);
+}
+
+real[] coeffs = leastsquares(independentvars, dependentvars, warn=false);
+if (coeffs.length == 0) {
+ abort("Unable to find regression: independent variables are "
+ + "linearly dependent.");
+}
+
+real f(pair xy) {
+ return coeffs[0] * xy.x // income
+ + coeffs[1] * xy.y // education
+ + coeffs[2]; // residue
+}
+
+real xmin = infinity, xmax = -infinity, ymin = infinity, ymax = -infinity;
+for (real[] row : independentvars) {
+ if (row[0] < xmin) xmin = row[0];
+ if (row[0] > xmax) xmax = row[0];
+ if (row[1] < ymin) ymin = row[1];
+ if (row[1] > ymax) ymax = row[1];
+}
+
+// Draw the plane
+draw(surface(f, (xmin, ymin), (xmax, ymax)),
+ surfacepen=emissive(blue + opacity(0.6)),
+ meshpen = blue);
+
+for (int ii = 0; ii < independentvars.length; ++ii) {
+ triple pt = (independentvars[ii][0], independentvars[ii][1],
+ dependentvars[ii]);
+ draw(shift(pt) * unitsphere, material(yellow, emissivepen=0.2*yellow));
+ real z = f((pt.x, pt.y));
+ if (pt.z > z) draw (pt -- (pt.x, pt.y, z), green);
+ else draw(pt -- (pt.x, pt.y, z), red);
+}
+
+xaxis3("income", Bounds(Min, Min), InTicks);
+yaxis3("education", Bounds(Min, Min), InTicks);
+zaxis3("prestige", Bounds(Min, Min), InTicks);
diff --git a/graphics/asymptote/examples/lines.asy b/graphics/asymptote/examples/lines.asy
new file mode 100644
index 0000000000..9749f73a35
--- /dev/null
+++ b/graphics/asymptote/examples/lines.asy
@@ -0,0 +1,10 @@
+import math;
+
+int n=7;
+
+size(200,0);
+
+draw(unitcircle,red);
+for (int i=0; i < n-1; ++i)
+ for (int j=i+1; j < n; ++j)
+ drawline(unityroot(n,i),unityroot(n,j),blue);
diff --git a/graphics/asymptote/examples/lmfit1.asy b/graphics/asymptote/examples/lmfit1.asy
new file mode 100644
index 0000000000..c25a7c4b4b
--- /dev/null
+++ b/graphics/asymptote/examples/lmfit1.asy
@@ -0,0 +1,37 @@
+import lmfit;
+import graph;
+
+size(10cm, 7cm, IgnoreAspect);
+
+real[] date = { 1790, 1800, 1810, 1820, 1830, 1840, 1850, 1860, 1870, 1880,
+1890, 1900, 1910, 1920, 1930, 1940, 1950, 1960, 1970, 1980, 1990 };
+real[] population = { 3.929, 5.308, 7.240, 9.638, 12.866, 17.069, 23.192, 31.443,
+38.558, 50.156, 62.948, 75.996, 91.972, 105.711, 122.775, 131.669, 150.697,
+179.323, 203.185, 226.546, 248.710 };
+
+real t0 = 1776;
+
+real P(real[] params, real t) {
+ real P0 = params[0];
+ real K = params[1];
+ real r = params[2];
+ return (K * P0) / (P0 + (K - P0) * exp(-r * (t - t0)));
+}
+
+real[] params = { 10, 500, 0.1 };
+
+real res = lmfit.fit(date, population, P, params).norm;
+
+write("P_0 = ", params[0]);
+write("K = ", params[1]);
+write("r = ", params[2]);
+write("error = ", res);
+
+real P(real t) {
+ return P(params, t);
+}
+
+draw(graph(date, population), blue);
+draw(graph(P, t0, 2000), red);
+xaxis("Year", BottomTop, LeftTicks);
+yaxis("Population in millions", LeftRight, RightTicks);
diff --git a/graphics/asymptote/examples/log.asy b/graphics/asymptote/examples/log.asy
new file mode 100644
index 0000000000..532b7b782b
--- /dev/null
+++ b/graphics/asymptote/examples/log.asy
@@ -0,0 +1,14 @@
+import graph;
+
+size(150,0);
+
+real f(real x) {return log(x);}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$",0);
+yaxis("$y$");
+
+draw(graph(f,0.01,10,operator ..));
+
+labelx(1,SSE);
+label("$\log x$",F(7),SE);
diff --git a/graphics/asymptote/examples/logdown.asy b/graphics/asymptote/examples/logdown.asy
new file mode 100644
index 0000000000..25d10ed978
--- /dev/null
+++ b/graphics/asymptote/examples/logdown.asy
@@ -0,0 +1,13 @@
+import graph;
+size(200,IgnoreAspect);
+
+real log10Down(real x) {return -log10(x);}
+real pow10Down(real x) {return pow10(-x);}
+
+scaleT LogDown=scaleT(log10Down,pow10Down,logarithmic=true);
+scale(Linear,LogDown);
+
+draw(graph(exp,-5,5));
+
+yaxis("$y$",RightTicks(Label(Fill(white)),DefaultLogFormat),BeginArrow);
+xaxis("$x$",LeftTicks(NoZero),EndArrow);
diff --git a/graphics/asymptote/examples/logo3.asy b/graphics/asymptote/examples/logo3.asy
new file mode 100644
index 0000000000..93b5a331e9
--- /dev/null
+++ b/graphics/asymptote/examples/logo3.asy
@@ -0,0 +1,41 @@
+import three;
+
+size(560,320,IgnoreAspect);
+size3(140,80,15);
+currentprojection=perspective(-2,20,10,up=Y);
+currentlight=White;
+
+real a=-0.4;
+real b=0.95;
+real y1=-5;
+real y2=-3y1/2;
+path A=(a,0){dir(10)}::{dir(89.5)}(0,y2);
+path B=(0,y1){dir(88.3)}::{dir(20)}(b,0);
+real c=0.5*a;
+pair z=(0,2.5);
+transform t=scale(1,15);
+transform T=inverse(scale(t.yy,t.xx));
+path[] g=shift(0,1.979)*scale(0.01)*t*
+ texpath(Label("{\it symptote}",z,0.25*E+0.169S,fontsize(24pt)));
+pair w=(0,1.7);
+pair u=intersectionpoint(A,w-1--w);
+
+real h=0.25*linewidth();
+real hy=(T*(h,h)).x;
+g.push(t*((a,hy)--(b,hy)..(b+hy,0)..(b,-hy)--(a,-hy)..(a-hy,0)..cycle));
+g.push(T*((h,y1)--(h,y2)..(0,y2+h)..(-h,y2)--(-h,y1)..(0,y1-h)..cycle));
+g.push(shift(0,w.y)*t*((u.x,hy)--(w.x,hy)..(w.x+hy,0)..(w.x,-hy)--(u.x,-hy)..(u.x-hy,0)..cycle));
+real f=0.75;
+g.push(point(A,0)--shift(-f*hy,f*h)*A--point(A,1)--shift(f*hy,-f*h)*reverse(A)--cycle);
+g.push(point(B,0)--shift(f*hy,-f*h)*B--point(B,1)--shift(-f*hy,f*h)*reverse(B)--cycle);
+
+triple H=-0.1Z;
+material m=material(lightgray,shininess=1.0);
+
+for(path p : g)
+ draw(extrude(p,H),m);
+
+surface s=surface(g);
+draw(s,red,nolight);
+draw(shift(H)*s,m);
+
diff --git a/graphics/asymptote/examples/lowint.asy b/graphics/asymptote/examples/lowint.asy
new file mode 100644
index 0000000000..e4bf1c5560
--- /dev/null
+++ b/graphics/asymptote/examples/lowint.asy
@@ -0,0 +1,11 @@
+size(100,0);
+import graph;
+import lowupint;
+
+real a=-0.8, b=1.2;
+real c=1.0/sqrt(3.0);
+
+partition(a,b,c,min);
+
+arrow("$f(x)$",F(0.5*(a+b)),NNE,red);
+label("$\cal{L}$",(0.5*(a+b),f(0.5*(a+b))/2));
diff --git a/graphics/asymptote/examples/lowupint.asy b/graphics/asymptote/examples/lowupint.asy
new file mode 100644
index 0000000000..3a14cd9110
--- /dev/null
+++ b/graphics/asymptote/examples/lowupint.asy
@@ -0,0 +1,31 @@
+import graph;
+
+real f(real x) {return x^3-x+2;}
+pair F(real x) {return (x,f(x));}
+
+void rectangle(real a, real b, real c, real h(real,real))
+{
+ real height=(a < c && c < b) ? f(c) : h(f(a),f(b));
+ pair p=(a,0), q=(b,height);
+ path g=box(p,q);
+ fill(g,lightgray);
+ draw(g);
+}
+
+void partition(real a, real b, real c, real h(real,real))
+{
+ rectangle(a,a+.4,c,h);
+ rectangle(a+.4,a+.6,c,h);
+ rectangle(a+.6,a+1.2,c,h);
+ rectangle(a+1.2,a+1.6,c,h);
+ rectangle(a+1.6,a+1.8,c,h);
+ rectangle(a+1.8,b,c,h);
+
+ draw((a,0)--(F(a)));
+ draw((b,0)--(F(b)));
+
+ draw(graph(f,a,b,operator ..),red);
+ draw((a,0)--(b,0));
+ labelx("$a$",a);
+ labelx("$b$",b);
+}
diff --git a/graphics/asymptote/examples/magnetic.asy b/graphics/asymptote/examples/magnetic.asy
new file mode 100644
index 0000000000..3ae40466d4
--- /dev/null
+++ b/graphics/asymptote/examples/magnetic.asy
@@ -0,0 +1,18 @@
+import graph3;
+import contour3;
+
+size(200,0);
+currentprojection=orthographic((6,8,2),up=Y);
+
+real a(real z) {return (z < 6) ? 1 : exp((abs(z)-6)/4);}
+real b(real z) {return 1/a(z);}
+real B(real z) {return 1-0.5cos(pi*z/10);}
+
+real f(real x, real y, real z) {return 0.5B(z)*(a(z)*x^2+b(z)*y^2)-1;}
+
+draw(surface(contour3(f,(-2,-2,-10),(2,2,10),10)),blue+opacity(0.75),
+ render(merge=true));
+
+xaxis3(Label("$x$",1),red);
+yaxis3(Label("$y$",1),red);
+zaxis3(Label("$z$",1),red);
diff --git a/graphics/asymptote/examples/markregular.asy b/graphics/asymptote/examples/markregular.asy
new file mode 100644
index 0000000000..716599fbcf
--- /dev/null
+++ b/graphics/asymptote/examples/markregular.asy
@@ -0,0 +1,26 @@
+import graph;
+
+size(10cm,0);
+
+real xmin=-4,xmax=4;
+real ymin=-2,ymax=10;
+
+real f(real x) {return x^2;}
+
+marker cross=marker(scale(4)*rotate(45)*cross(4),
+ markuniform(new pair(real t) {return Scale((t,f(t)));},
+ xmin,xmax,round(2*(xmax-xmin))),1bp+red);
+
+draw(graph(f,xmin,xmax,n=400),linewidth(1bp),cross);
+
+ylimits(-2.5,10,Crop);
+
+xaxis(Label("$x$",position=EndPoint, align=NE),xmin=xmin,xmax=xmax,
+ Ticks(scale(.7)*Label(align=E),NoZero,begin=false,beginlabel=false,
+ end=false,endlabel=false,Step=1,step=.25,
+ Size=1mm, size=.5mm,pTick=black,ptick=gray),Arrow);
+
+yaxis(Label("$y$",position=EndPoint, align=NE),ymin=ymin,ymax=ymax,
+ Ticks(scale(.7)*Label(),NoZero,begin=false,beginlabel=false,
+ end=false,endlabel=false,Step=1,step=.25,Size=1mm,size=.5mm,
+ pTick=black,ptick=gray),Arrow);
diff --git a/graphics/asymptote/examples/mergeExample.asy b/graphics/asymptote/examples/mergeExample.asy
new file mode 100644
index 0000000000..e0fdcd0f6c
--- /dev/null
+++ b/graphics/asymptote/examples/mergeExample.asy
@@ -0,0 +1,77 @@
+size(16cm);
+import bezulate;
+
+pen edgepen=linewidth(1)+blue;
+pen dotpen=deepgreen;
+pen labelpen=fontsize(8pt);
+
+path outer = (0.5,5){E}..(5,-1){S}..{W}(4,-4)..{W}(2.5,-1.5){W}..(-0.3,-2.5){W}..(-3,0)..cycle;
+outer = subdivide(outer);
+path[] p = {outer,shift(-0.5,1.0)*rotate(-22)*scale(1.5,2.4)*subdivide(unitcircle),shift(2.3,0.3)*scale(0.7)*unitcircle};
+
+// a
+filldraw(p,lightgrey+evenodd);
+
+real w = 1.1*(max(p).x-min(p).x);
+
+// b
+p = shift(w)*p;
+draw(p);
+path l = point(p[1],2)--point(p[0],4);
+draw(l,red);
+for(int i = 0; i < p.length; ++i)
+{
+ real[][] ts = intersections(l,p[i]);
+ for(real[] t:ts)
+ dot(point(l,t[0]));
+}
+path l2 = point(l,intersections(l,p[0])[0][0])--point(l,intersections(l,p[2])[1][0]);
+real to = intersections(l,p[0])[0][1];
+real ti = intersections(l,p[2])[1][1];
+draw(l2,edgepen);
+label("$A$",point(l2,1),2E,labelpen);
+label("$B$",point(l2,0),1.5E,labelpen);
+
+// c
+p = shift(w)*p;
+l2 = shift(w)*l2;
+draw(p);
+real timeoffset=2;
+path t1=subpath(p[0],to,to+timeoffset);
+t1=t1--point(p[2],ti)--cycle;
+fill(t1,lightgrey);
+draw(point(p[2],ti)--point(p[0],to+4),red);
+dot(Label("$A$",labelpen),point(p[2],ti),2E,dotpen);
+dot(Label("$B$",labelpen),point(p[0],to),1.5E,dotpen);
+dot(Label("$C$",labelpen),point(p[0],to+timeoffset),1.5S,dotpen);
+draw(t1,edgepen);
+dot(point(p[0],to+4));
+draw(shift(-0.5,-0.5)*subpath(p[0],to+4,to+timeoffset+0.5),Arrow(4));
+
+// d
+p = shift(w)*p;
+p[0] = subpath(p[0],to+timeoffset,to+length(p[0]))--uncycle(p[2],ti)--cycle;
+p.delete(2);
+draw(p);
+
+// e
+p = shift(w)*p;
+path q=point(p[1],0)--subpath(p[0],15.4,16)--cycle;
+p[0] = subpath(p[0],16,15.4+length(p[0]))--uncycle(p[1],0)--cycle;
+p.delete(1);
+filldraw(p,lightgrey);
+
+// f
+p = shift(w)*p;
+filldraw(bezulate(p),lightgrey);
+filldraw(shift(3w)*t1,lightgrey);
+filldraw(shift(w)*q,lightgrey);
+
+
+real x = min(p).x - 4.5w;
+string l = "abcdef";
+for(int i = 0; i < 6; ++i)
+{
+ label("("+substr(l,i,1)+")",(x,min(p).y),3S,fontsize(10pt));
+ x += w;
+}
diff --git a/graphics/asymptote/examples/mosaic.asy b/graphics/asymptote/examples/mosaic.asy
new file mode 100644
index 0000000000..0f19117c4b
--- /dev/null
+++ b/graphics/asymptote/examples/mosaic.asy
@@ -0,0 +1,165 @@
+// Calendar example contributed by Jens Schwaiger
+
+// transformations
+path similarpath(pair a, pair b, path p) {
+ // transform p into a path starting at a and ending at b
+ pair first;
+ pair last;
+ path p_;
+ first=point(p,0);
+ last=point(p,length(p));
+ p_=shift(-first)*p;
+ p_=rotate(degrees(b-a))*p_;
+ p_=scale(abs(b-a)/abs(last-first))*p_;
+ p_=shift(a)*p_;
+ return p_;
+}
+
+path c_line(path p) {
+ // returns the path obtained by adding to p a copy rotated
+ // around the endpoint of p by 180 degrees
+ // works only if the initial point and the endpoint of p are different
+ // a c_line is symetric with respect to the center of
+ // the straight line between its endpoints
+ //
+ return p..rotate(180,point(p,length(p)))*reverse(p);
+}
+
+path tounitcircle(path p, int n=300) {
+ // the transformation pair x --> x/sqrt(1+abs(x)^2)
+ // is a bijection from the plane to the open unitdisk
+ real l=arclength(p);
+ path ghlp;
+ for(int i=0; i <= n; ++i) {
+ real at=arctime(p,l/n*i);
+ pair phlp=point(p,at);
+ real trhlp=1/(1+abs(phlp)^2)^(1/2);
+ ghlp=ghlp--trhlp*phlp;
+ }
+ if(cyclic(p)) {ghlp=ghlp--cycle;}
+ return ghlp;
+}
+
+void centershade(picture pic=currentpicture, path p, pen in, pen out,
+ pen drawpen=currentpen) {
+ pair center=0.5(max(p)+min(p));
+ real radius=0.5abs(max(p)-min(p));
+ radialshade(pic,p,in,center,0,out,center,radius);
+ draw(pic,p,drawpen);
+}
+
+pair zentrum(path p) {return 0.5(min(p)+max(p));}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+real scalefactor=19/13; // For output: height=scalefactor*width
+real outputwidth=13cm;
+picture kalender;// at first we produce a calendar for february 2006
+texpreamble("\usepackage[latin1]{inputenc}");
+size(outputwidth,0);
+real yc=0.5;
+pair diff=(-3.5,5*yc);
+pen farbe(int j) {
+ pen hlp=0.8white;
+ if(j % 7 == 6) {hlp=red+white;}
+ return hlp;}
+
+// farbe=German word for color
+path kasten=yscale(yc)*unitsquare;
+// Kasten is a German word meaning something like box
+path Gkasten=shift((0,2*yc)+diff)*xscale(7)*yscale(2)*kasten;
+path tage[]= new path[7]; // Tag=day
+string wochentag[]={"MO","DI","MI","DO","FR","SA","SO"};
+path[][] bx= new path[6][7];
+string[][] entry= new string[6][7];
+bool[][] holiday=new bool[6][7];
+
+// Now the necessary information for February 2006
+int start=2;
+int days=28;
+for(int i=0; i < entry.length; ++i) {
+ for(int j=0; j < entry[0].length; ++j) {
+ int day=i*7+j-start+1;
+ entry[i][j]=(day > 0 && day <= days ? (string) day : "");
+ holiday[i][j]=false;
+ }
+}
+
+for(int j=0; j < 7; ++j) {
+ tage[j]=shift((j,yc)+diff)*kasten;
+ filldraw(tage[j],farbe(j),black+2bp);
+ label(wochentag[j],zentrum(tage[j]),Palatino());
+ for(int i=0; i < 6; ++i) {bx[i][j]=shift((j,-yc*i)+diff)*kasten;
+ filldraw(bx[i][j],farbe(j),black+2bp);
+ if(holiday[i][j]) {filldraw(bx[i][j],farbe(6),black+2bp);};
+ };
+};
+filldraw(Gkasten,0.3white,black+2bp);
+for(int j=0; j < 7; ++j)
+ for(int i=0; i < 6 ; ++i) {label(entry[i][j],zentrum(bx[i][j]),Palatino());}
+label("\Huge Februar 2006",zentrum(Gkasten),Palatino()+white);
+// Zentrum=center; Februar=february
+add(kalender,currentpicture);
+erase();
+
+// Now the mosaic is constructed
+pair a[]=new pair[4];
+path p[]=new path[4];
+path q[]=new path[4];
+path kontur[]=new path[5];
+picture temppic;
+
+a[1]=(0,0);
+a[2]=(1,0);
+a[3]=(0,1); // a triangle with abs(a[2]-a[1])=abs(a[3]-a[1]
+ // and a right angle at a[1];
+q[1]=(0,0){dir(-20)}::{dir(20)}(0.2,0){dir(-140)}..{dir(0)}(0.3,-0.2){dir(0)}..
+{dir(140)}(0.4,0){dir(20)}..{dir(-20)}(1,0);
+q[2]=(0,0){dir(20)}..{dir(-20)}(0.8,0){dir(-140)}..{dir(0)}(0.9,-0.3){dir(0)}..
+{dir(140)}(1,0);
+q[2]=c_line(q[2]);
+p[1]=similarpath(a[1],a[2],q[1]);// arbitrary path from a[1] to a[2]
+p[2]=similarpath(a[2],a[3],q[2]);// arbitrary c_line from a[2] to a[3]
+p[3]=rotate(90,a[1])*reverse(p[1]);//
+kontur[1]=p[1]..p[2]..p[3]..cycle;// first tile
+kontur[2]=rotate(90,a[1])*kontur[1];// second
+kontur[3]=rotate(180,a[1])*kontur[1];// third
+kontur[4]=rotate(270,a[1])*kontur[1];// fourth
+pair tri=2*(interp(a[2],a[3],0.5)-a[1]);
+pair trii=rotate(90)*tri;
+// translations of kontur[i], i=1,2,3,4, with respect to
+// j*tri+k*trii
+// fill the plane
+
+for(int j=-4; j < 4; ++j)
+ for(int k=-4; k < 4; ++k) {
+ transform tr=shift(j*tri+k*trii);
+ for(int i=1; i < 5; ++i) {
+ centershade(temppic,tr*kontur[i],(1-i/10)*white,
+ (1-i/10)*chartreuse,black+2bp);
+ }
+ }
+
+// Now we produce the bijective images inside
+// a suitably scaled unitcircle
+for(int k=-1; k < 2; ++k)
+ for(int l=-1; l < 2; ++l) {
+ transform tr=shift(k*tri+l*trii);
+ for(int i=1; i < 5; ++i) {
+ centershade(temppic,scale(2.5)*tounitcircle(tr*kontur[i],380),
+ (1-i/10)*white,(1-i/10)*orange,black+2bp);
+ }
+ }
+
+add(temppic);
+
+// We clip the picture to a suitable box
+pair piccenter=0.5*(temppic.min()+temppic.max());
+pair picbox=temppic.max()-temppic.min();
+real picwidth=picbox.x;
+transform trialtrans=shift(0,-1.5)*shift(piccenter)*yscale(scalefactor)*
+ scale(0.25picwidth)*shift((-0.5,-0.5))*identity();
+clip(trialtrans*unitsquare);
+
+// add the calendar at a suitable position
+add(kalender.fit(0.75*outputwidth),interp(point(S),point(N),1/13));
diff --git a/graphics/asymptote/examples/mosquito.asy b/graphics/asymptote/examples/mosquito.asy
new file mode 100644
index 0000000000..7e299d264d
--- /dev/null
+++ b/graphics/asymptote/examples/mosquito.asy
@@ -0,0 +1,82 @@
+size(9cm,10cm,IgnoreAspect);
+
+pair d=(1,0.25);
+real s=1.6d.x;
+real y=0.6;
+defaultpen(fontsize(8pt));
+
+picture box(string s, pair z=(0,0)) {
+ picture pic;
+ draw(pic,box(-d/2,d/2));
+ label(pic,s,(0,0));
+ return shift(z)*pic;
+}
+
+label("Birds",(0,y));
+picture removed=box("Removed ($R_B$)");
+picture infectious=box("Infectious ($I_B$)",(0,-1.5));
+picture susceptible=box("Susceptible ($S_B$)",(0,-3));
+
+add(removed);
+add(infectious);
+add(susceptible);
+
+label("Mosquitoes",(s,y));
+picture larval=box("Larval ($L_M$)",(s,0));
+picture susceptibleM=box("Susceptible ($S_M$)",(s,-1));
+picture exposed=box("Exposed ($E_M$)",(s,-2));
+picture infectiousM=box("Infectious ($I_M$)",(s,-3));
+
+add(larval);
+add(susceptibleM);
+add(exposed);
+add(infectiousM);
+
+path ls=point(larval,S)--point(susceptibleM,N);
+path se=point(susceptibleM,S)--point(exposed,N);
+path ei=point(exposed,S)--point(infectiousM,N);
+path si=point(susceptible,N)--point(infectious,S);
+
+draw(minipage("\flushright{recovery rate ($g$) \& death rate from virus
+($\mu_V$)}",40pt),point(infectious,N)--point(removed,S),LeftSide,Arrow,
+ PenMargin);
+
+draw(si,LeftSide,Arrow,PenMargin);
+
+draw(minipage("\flushright{maturation rate ($m$)}",50pt),ls,RightSide,
+ Arrow,PenMargin);
+draw(minipage("\flushright{viral incubation rate ($k$)}",40pt),ei,
+ RightSide,Arrow,PenMargin);
+
+path ise=point(infectious,E)--point(se,0.5);
+
+draw("$(ac)$",ise,LeftSide,dashed,Arrow,PenMargin);
+label(minipage("\flushleft{biting rate $\times$ transmission
+probability}",50pt),point(infectious,SE),dir(-60)+S);
+
+path isi=point(infectiousM,W)--point(si,2.0/3);
+
+draw("$(ab)$",isi,LeftSide,dashed,Arrow,PenMargin);
+draw(se,LeftSide,Arrow,PenMargin);
+
+real t=2.0;
+draw("$\beta_M$",
+ point(susceptibleM,E){right}..tension t..{left}point(larval,E),
+ 2*(S+SE),red,Arrow(Fill,0.5));
+draw(minipage("\flushleft{birth rate ($\beta_M$)}",20pt),
+ point(exposed,E){right}..tension t..{left}point(larval,E),2SW,red,
+ Arrow(Fill,0.5));
+draw("$\beta_M$",
+ point(infectiousM,E){right}..tension t..{left}point(larval,E),2SW,
+ red,Arrow(Fill,0.5));
+
+path arrow=(0,0)--0.75cm*dir(35);
+draw(point(larval,NNE),
+ Label(minipage("\flushleft{larval death rate ($\mu_L$)}",45pt),1),
+ arrow,blue,Arrow);
+draw(point(susceptibleM,NNE),
+ Label(minipage("\flushleft{adult death rate ($\mu_A$)}",20pt),1),
+ arrow,N,blue,Arrow);
+draw(point(exposed,NNE),Label("$\mu_A$",1),arrow,blue,Arrow);
+draw(point(infectiousM,NNE),Label("$\mu_A$",1),arrow,blue,Arrow);
+
diff --git a/graphics/asymptote/examples/near_earth.asy b/graphics/asymptote/examples/near_earth.asy
new file mode 100644
index 0000000000..afdf64c6b5
--- /dev/null
+++ b/graphics/asymptote/examples/near_earth.asy
@@ -0,0 +1,56 @@
+import three;
+import math;
+texpreamble("\usepackage{bm}");
+
+size(300,0);
+
+pen thickp=linewidth(0.5mm);
+real radius=0.8, lambda=37, aux=60;
+
+currentprojection=perspective(4,1,2);
+
+// Planes
+pen bg=gray(0.9)+opacity(0.5);
+draw(surface((1.2,0,0)--(1.2,0,1.2)--(0,0,1.2)--(0,0,0)--cycle),bg);
+draw(surface((0,1.2,0)--(0,1.2,1.2)--(0,0,1.2)--(0,0,0)--cycle),bg);
+draw(surface((1.2,0,0)--(1.2,1.2,0)--(0,1.2,0)--(0,0,0)--cycle),bg);
+
+real r=1.5;
+pen p=rgb(0,0.7,0);
+draw(Label("$x$",1),O--r*X,p,Arrow3);
+draw(Label("$y$",1),O--r*Y,p,Arrow3);
+draw(Label("$z$",1),O--r*Z,p,Arrow3);
+label("$\rm O$",(0,0,0),W);
+
+// Point Q
+triple pQ=radius*dir(lambda,aux);
+draw(O--radius*dir(90,aux),dashed);
+label("$\rm Q$",pQ,N+3*W);
+draw("$\lambda$",arc(O,0.15pQ,0.15*Z),N+0.3E);
+
+// Particle
+triple m=pQ-(0.26,-0.4,0.28);
+real width=5;
+dot("$m$",m,SE,linewidth(width));
+draw("$\bm{\rho}$",(0,0,0)--m,Arrow3,PenMargin3(0,width));
+draw("$\bm{r}$",pQ--m,Arrow3,PenMargin3(0,width));
+
+// Spherical octant
+real r=sqrt(pQ.x^2+pQ.y^2);
+draw(arc((0,0,pQ.z),(r,0,pQ.z),(0,r,pQ.z)),dashed);
+draw(arc(O,radius*Z,radius*dir(90,aux)),dashed);
+draw(arc(O,radius*Z,radius*X),thickp);
+draw(arc(O,radius*Z,radius*Y),thickp);
+draw(arc(O,radius*X,radius*Y),thickp);
+
+// Moving axes
+triple i=dir(90+lambda,aux);
+triple k=unit(pQ);
+triple j=cross(k,i);
+
+draw(Label("$x$",1),pQ--pQ+0.2*i,2W,red,Arrow3);
+draw(Label("$y$",1),pQ--pQ+0.32*j,red,Arrow3);
+draw(Label("$z$",1),pQ--pQ+0.26*k,red,Arrow3);
+
+draw("$\bm{R}$",O--pQ,Arrow3,PenMargin3);
+draw("$\omega\bm{K}$",arc(0.9Z,0.2,90,-120,90,160,CW),1.2N,Arrow3);
diff --git a/graphics/asymptote/examples/odetest.asy b/graphics/asymptote/examples/odetest.asy
new file mode 100644
index 0000000000..69f8ea3fd0
--- /dev/null
+++ b/graphics/asymptote/examples/odetest.asy
@@ -0,0 +1,43 @@
+import ode;
+
+write("integration test");
+real f(real t, real x) {return cos(x);}
+write(integrate(1,f,0,10,0.1,dynamic=true,0.0002,0.0004,RK3BS,verbose=true));
+write();
+
+write("system integration test");
+real[] f(real t, real[] x) {return new real[] {x[1],1.5*x[0]^2};}
+write(integrate(new real[] {4,-8},f,0,1,n=100,dynamic=true,tolmin=0.0002,
+ tolmax=0.0004,RK3BS,verbose=false));
+write();
+
+write("simultaneous newton test");
+real[] function(real[] x) {
+ return new real[] {x[0]^2+x[1]^2-25,(x[0]-6)^2+x[1]^2-25};
+}
+real[][] fJac(real[] x) {
+ return new real[][] {{2*x[0],2*x[1]},{2*(x[0]-6),2*x[1]}};
+}
+write(newton(function,fJac,new real[] {0,-1}));
+write();
+
+
+write("BVP solver test");
+write("Finding initial conditions that solve w''(t)=1.5*w(t), w(0)=4, w(1)=1");
+real[] initial(real[] x) {
+ return new real[] {4,x[0]};
+}
+
+real[] discrepancy(real[] x) {
+ real error=x[0]-1;
+ write("Error: ",error);
+ return new real[] {error};
+}
+
+real[] w0=solveBVP(f,0,1,n=10,dynamic=true,tolmin=0.0002,tolmax=0.0004,RK3BS,
+ initial,discrepancy,guess=new real[] {-30},iterations=10);
+write(w0);
+write();
+write(integrate(w0,f,0,1,n=10,dynamic=true,tolmin=0.0002,tolmax=0.0004,RK3BS,
+ verbose=false));
+write();
diff --git a/graphics/asymptote/examples/oneoverx.asy b/graphics/asymptote/examples/oneoverx.asy
new file mode 100644
index 0000000000..5d9775d44d
--- /dev/null
+++ b/graphics/asymptote/examples/oneoverx.asy
@@ -0,0 +1,17 @@
+import graph;
+size(200,IgnoreAspect);
+
+real f(real x) {return 1/x;};
+
+bool3 branch(real x)
+{
+ static int lastsign=0;
+ if(x == 0) return false;
+ int sign=sgn(x);
+ bool b=lastsign == 0 || sign == lastsign;
+ lastsign=sign;
+ return b ? true : default;
+}
+
+draw(graph(f,-1,1,branch));
+axes("$x$","$y$",red);
diff --git a/graphics/asymptote/examples/orthocenter.asy b/graphics/asymptote/examples/orthocenter.asy
new file mode 100644
index 0000000000..5c6807b4f2
--- /dev/null
+++ b/graphics/asymptote/examples/orthocenter.asy
@@ -0,0 +1,40 @@
+import geometry;
+import math;
+
+size(7cm,0);
+
+real theta=degrees(asin(0.5/sqrt(7)));
+
+pair B=(0,sqrt(7));
+pair A=B+2sqrt(3)*dir(270-theta);
+pair C=A+sqrt(21);
+pair O=0;
+
+pair Ap=extension(A,O,B,C);
+pair Bp=extension(B,O,C,A);
+pair Cp=extension(C,O,A,B);
+
+perpendicular(Ap,NE,Ap--O,blue);
+perpendicular(Bp,NE,Bp--C,blue);
+perpendicular(Cp,NE,Cp--O,blue);
+
+draw(A--B--C--cycle);
+
+currentpen=black;
+
+draw("1",A--O,-0.25*I*dir(A--O));
+draw(O--Ap);
+draw("$\sqrt{7}$",B--O,LeftSide);
+draw(O--Bp);
+draw("4",C--O);
+draw(O--Cp);
+
+dot("$O$",O,dir(B--Bp,Cp--C),red);
+dot("$A$",A,dir(C--A,B--A),red);
+dot("$B$",B,NW,red);
+dot("$C$",C,dir(A--C,B--C),red);
+dot("$A'$",Ap,dir(A--Ap),red);
+dot("$B'$",Bp,dir(B--Bp),red);
+dot("$C'$",Cp,dir(C--Cp),red);
+
+label(graphic("piicon","width=2.5cm"),Ap,5ENE,red);
diff --git a/graphics/asymptote/examples/p-orbital.asy b/graphics/asymptote/examples/p-orbital.asy
new file mode 100644
index 0000000000..4638aa21a2
--- /dev/null
+++ b/graphics/asymptote/examples/p-orbital.asy
@@ -0,0 +1,31 @@
+import graph3;
+import palette;
+size(200);
+currentprojection=orthographic(6,8,2);
+viewportmargin=(1cm,0);
+
+real c0=0.1;
+
+real f(real r) {return r*(1-r/6)*exp(-r/3);}
+
+triple f(pair t) {
+ real r=t.x;
+ real phi=t.y;
+ real f=f(r);
+ real s=max(min(f != 0 ? c0/f : 1,1),-1);
+ real R=r*sqrt(1-s^2);
+ return (R*cos(phi),R*sin(phi),r*s);
+}
+
+bool cond(pair t) {return f(t.x) != 0;}
+
+real R=abs((20,20,20));
+surface s=surface(f,(0,0),(R,2pi),100,8,Spline,cond);
+
+s.colors(palette(s.map(abs),Gradient(palegreen,heavyblue)));
+
+render render=render(compression=Low,merge=true);
+draw(s,render);
+draw(zscale3(-1)*s);
+
+axes3("$x$","$y$","$z$",Arrow3);
diff --git a/graphics/asymptote/examples/parametricelevation.asy b/graphics/asymptote/examples/parametricelevation.asy
new file mode 100644
index 0000000000..ac0f0b09ad
--- /dev/null
+++ b/graphics/asymptote/examples/parametricelevation.asy
@@ -0,0 +1,10 @@
+import graph3;
+import palette;
+size(200);
+
+currentprojection=orthographic(4,2,4);
+
+triple f(pair z) {return expi(z.x,z.y);}
+
+surface s=surface(f,(0,0),(pi,2pi),10,Spline);
+draw(s,mean(palette(s.map(zpart),BWRainbow())),black,nolight,render(merge=true));
diff --git a/graphics/asymptote/examples/parametricsurface.asy b/graphics/asymptote/examples/parametricsurface.asy
new file mode 100644
index 0000000000..299ea72eef
--- /dev/null
+++ b/graphics/asymptote/examples/parametricsurface.asy
@@ -0,0 +1,23 @@
+import graph3;
+
+size(200,0);
+currentprojection=orthographic(4,0,2);
+
+real R=2;
+real a=1.9;
+
+triple f(pair t) {
+ return ((R+a*cos(t.y))*cos(t.x),(R+a*cos(t.y))*sin(t.x),a*sin(t.y));
+}
+
+pen p=rgb(0.2,0.5,0.7);
+surface s=surface(f,(0,0),(2pi,2pi),8,8,Spline);
+
+// surface only
+//draw(s,lightgray);
+
+// mesh only
+// draw(s,nullpen,meshpen=p);
+
+// surface & mesh
+draw(s,lightgray,meshpen=p,render(merge=true));
diff --git a/graphics/asymptote/examples/partialsurface.asy b/graphics/asymptote/examples/partialsurface.asy
new file mode 100644
index 0000000000..2e8ad34d83
--- /dev/null
+++ b/graphics/asymptote/examples/partialsurface.asy
@@ -0,0 +1,29 @@
+import graph3;
+import palette;
+
+size(0,300);
+currentprojection=perspective(3,-2,2);
+
+real V(real r) {return r^4-r^2;}
+real V(pair pos) {return V(abs(pos));}
+
+real R=1/sqrt(2);
+real z=-0.2;
+
+bool active(pair pos) {return abs(pos) < R;}
+bool above(pair pos) {return V(pos) >= z;}
+
+pair a=(-1.5,-1);
+pair b=(0.5,1);
+real f=1.2;
+
+draw(plane(f*(b.x-a.x,0,z),(0,f*(b.y-a.y),z),(a.x,a.y,z)),
+ lightgrey+opacity(0.5));
+
+surface s=surface(V,a,b,40,Spline,active);
+draw(s,mean(palette(s.map(new real(triple v) {
+ return above((v.x,v.y)) ? 1 : 0;}),
+ new pen[] {lightblue,lightgreen})),black);
+
+xaxis3(Label("$\phi^\dagger\phi$",1),red,Arrow3);
+zaxis3(Label("$V(\phi^\dagger\phi)$",1),0,0.3,red,Arrow3);
diff --git a/graphics/asymptote/examples/partitionExample.asy b/graphics/asymptote/examples/partitionExample.asy
new file mode 100644
index 0000000000..4974d99d9c
--- /dev/null
+++ b/graphics/asymptote/examples/partitionExample.asy
@@ -0,0 +1,27 @@
+size(15cm);
+import bezulate;
+
+path[] p = texpath("$\sigma \Theta$");
+pair m = min(p);
+pair M = max(p);
+real midy = 0.5(M.y+m.y);
+
+path[] alpha = p[0:2];
+path[] theta = p[2:5];
+filldraw(p,lightgrey,black);
+
+draw("{\tt partition}",(M.x+1mm,midy)--(M.x+5mm,midy),Arrow);
+draw((M.x+1mm,midy+1mm)--(M.x+5mm,midy+2mm),Arrow);
+draw((M.x+1mm,midy-1mm)--(M.x+5mm,midy-2mm),Arrow);
+
+filldraw(shift((M.x+8.5mm,midy+3.5mm))*alpha,lightgrey,black);
+filldraw(shift((M.x+5.5mm,0))*theta[0:2],lightgrey,black);
+filldraw(shift(M.x+5.5mm,midy-2.5mm)*theta[2:3],lightgrey,black);
+
+draw("{\tt merge}, {\tt bezulate}",(M.x+9mm,midy+3mm)--(M.x+15mm,midy+3mm),Arrow);
+draw("{\tt merge}, {\tt bezulate}",(M.x+9mm,midy)--(M.x+15mm,midy),Arrow);
+draw("{\tt bezulate}",(M.x+9mm,midy-2.5mm)--(M.x+15mm,midy-2.5mm),Arrow);
+
+filldraw(shift(M.x+16mm-min(alpha).x,midy+3.5mm)*bezulate(alpha),lightgrey,black);
+filldraw(shift(M.x+16mm-min(theta[0:2]).x,0)*bezulate(theta[0:2]),lightgrey,black);
+filldraw(shift(M.x+16mm-min(theta[0:2]).x,midy-2.5mm)*bezulate(theta[2:3]),lightgrey,black);
diff --git a/graphics/asymptote/examples/pathintersectsurface.asy b/graphics/asymptote/examples/pathintersectsurface.asy
new file mode 100644
index 0000000000..b69b0b859a
--- /dev/null
+++ b/graphics/asymptote/examples/pathintersectsurface.asy
@@ -0,0 +1,20 @@
+size(500);
+import graph3;
+
+currentprojection=perspective(-5,-4,2);
+
+path3 g=randompath3(10);
+
+draw(g,red+thin());
+
+triple[][] P={
+ {(0,0,0),(1,0,0),(1,0,0),(2,0,0)},
+ {(0,4/3,0),(2/3,4/3,2),(4/3,4/3,2),(2,4/3,0)},
+ {(0,2/3,0),(2/3,2/3,0),(4/3,2/3,0),(2,2/3,0)},
+ {(0,2,0),(2/3,2,0),(4/3,2,0),(2,2,0)}};
+
+surface s=surface(patch(P));
+s.append(unitplane);
+
+draw(s,lightgray+opacity(0.9));
+dot(intersectionpoints(g,s),blue);
diff --git a/graphics/asymptote/examples/pdb.asy b/graphics/asymptote/examples/pdb.asy
new file mode 100644
index 0000000000..41cd29faaf
--- /dev/null
+++ b/graphics/asymptote/examples/pdb.asy
@@ -0,0 +1,164 @@
+import three;
+import cpkcolors;
+
+// A sample Protein Data Bank file for this example is available from
+// http://ndbserver.rutgers.edu/files/ftp/NDB/coordinates/na-biol/100d.pdb1
+
+currentlight=White;
+//currentlight=nolight;
+
+defaultrender.merge=true; // Fast low-quality rendering
+//defaultrender.merge=false; // Slow high-quality rendering
+bool pixel=false; // Set to true to draw dots as pixels.
+real width=10;
+
+size(200);
+currentprojection=perspective(30,30,15);
+
+pen chainpen=green;
+pen hetpen=purple;
+
+string filename="100d.pdb1";
+//string filename=getstring("filename");
+
+string prefix=stripextension(filename);
+file data=input(filename);
+
+pen color(string e)
+{
+ e=replace(e," ","");
+ int n=length(e);
+ if(n < 1) return currentpen;
+ if(n > 1) e=substr(e,0,1)+downcase(substr(e,1,n-1));
+ int index=find(Element == e);
+ if(index < 0) return currentpen;
+ return rgb(Hexcolor[index]);
+}
+
+// ATOM
+string[] name,altLoc,resName,chainID,iCode,element,charge;
+int[] serial,resSeq;
+real[][] occupancy,tempFactor;
+
+bool newchain=true;
+
+struct bond
+{
+ int i,j;
+ void operator init(int i, int j) {
+ this.i=i;
+ this.j=j;
+ }
+}
+
+bond[] bonds;
+
+struct atom
+{
+ string name;
+ triple v;
+ void operator init(string name, triple v) {
+ this.name=name;
+ this.v=v;
+ }
+}
+
+struct chain
+{
+ int[] serial;
+ atom[] a;
+}
+
+int[] serials;
+chain[] chains;
+atom[] atoms;
+
+while(true) {
+ string line=data;
+ if(eof(data)) break;
+ string record=replace(substr(line,0,6)," ","");
+ if(record == "TER") {newchain=true; continue;}
+ bool ATOM=record == "ATOM";
+ bool HETATOM=record == "HETATM";
+ int serial;
+
+ atom a;
+ if(ATOM || HETATOM) {
+ serial=(int) substr(line,6,5);
+ a.name=substr(line,76,2);
+ a.v=((real) substr(line,30,8),
+ (real) substr(line,38,8),
+ (real) substr(line,46,8));
+ }
+ if(ATOM) {
+ if(newchain) {
+ chains.push(new chain);
+ newchain=false;
+ }
+ chain c=chains[chains.length-1];
+ c.serial.push(serial);
+ c.a.push(a);
+ continue;
+ }
+ if(HETATOM) {
+ serials.push(serial);
+ atoms.push(a);
+ }
+ if(record == "CONECT") {
+ int k=0;
+ int i=(int) substr(line,6,5);
+ while(true) {
+ string s=replace(substr(line,11+k,5)," ","");
+ if(s == "") break;
+ k += 5;
+ int j=(int) s;
+ if(j <= i) continue;
+ bonds.push(bond(i,j));
+ }
+ }
+}
+
+write("Number of atomic chains: ",chains.length);
+
+int natoms;
+begingroup3("chained");
+for(chain c : chains) {
+ for(int i=0; i < c.a.length-1; ++i)
+ draw(c.a[i].v--c.a[i+1].v,chainpen,currentlight);
+ for(atom a : c.a)
+ if(pixel)
+ pixel(a.v,color(a.name),width);
+ else
+ dot(a.v,color(a.name),currentlight);
+ natoms += c.a.length;
+}
+endgroup3();
+
+write("Number of chained atoms: ",natoms);
+write("Number of hetero atoms: ",atoms.length);
+
+begingroup3("hetero");
+for(atom h : atoms)
+ if(pixel)
+ pixel(h.v,color(h.name),width);
+ else
+ dot(h.v,color(h.name),currentlight);
+endgroup3();
+
+write("Number of hetero bonds: ",bonds.length);
+
+begingroup3("bonds");
+for(bond b : bonds) {
+ triple v(int i) {return atoms[find(serials == i)].v;}
+ draw(v(b.i)--v(b.j),hetpen,currentlight);
+}
+endgroup3();
+
+string options;
+string viewfilename=prefix+".views";
+
+if(!error(input(viewfilename,check=false)))
+ options="3Dviews="+viewfilename;
+
+shipout(prefix,options=options);
+
diff --git a/graphics/asymptote/examples/phase.asy b/graphics/asymptote/examples/phase.asy
new file mode 100644
index 0000000000..7256ffc515
--- /dev/null
+++ b/graphics/asymptote/examples/phase.asy
@@ -0,0 +1,18 @@
+import graph;
+size(8cm,6cm,IgnoreAspect);
+
+pair S0=(4,0.2);
+pair S1=(2,3);
+pair S8=(0.5,0);
+
+xaxis("$S$");
+yaxis(Label("$I$",0.5));
+
+draw(S0{curl 0}..tension 1.5..S1{W}..tension 1.5..{curl 0}S8,Arrow(Fill,0.4));
+draw((S1.x,0)..S1,dashed);
+draw((0,S1.y)..S1,dotted);
+
+labelx("$\frac{\gamma}{\beta}$",S1.x);
+labelx("$S_\infty$",S8.x);
+labely("$I_{\max}$",S1.y);
+
diff --git a/graphics/asymptote/examples/piicon.eps b/graphics/asymptote/examples/piicon.eps
new file mode 100644
index 0000000000..56bf59bde9
--- /dev/null
+++ b/graphics/asymptote/examples/piicon.eps
@@ -0,0 +1,1135 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 147 144
+%%HiResBoundingBox: 0.000000 0.000000 147.000000 144.000000
+%.........................................
+%%Creator: AFPL Ghostscript 814 (epswrite)
+%%CreationDate: 2005/05/07 23:32:22
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%EndComments
+%%BeginProlog
+% This copyright applies to everything between here and the %%EndProlog:
+% Copyright (C) 2004 artofcode LLC, Benicia, CA. All rights reserved.
+%%BeginResource: procset GS_epswrite_2_0_1001
+/GS_epswrite_2_0_1001 80 dict dup begin
+/PageSize 2 array def/setpagesize{ PageSize aload pop 3 index eq exch
+4 index eq and{ pop pop pop}{ PageSize dup 1
+5 -1 roll put 0 4 -1 roll put dup null eq {false} {dup where} ifelse{ exch get exec}
+{ pop/setpagedevice where
+{ pop 1 dict dup /PageSize PageSize put setpagedevice}
+{ /setpage where{ pop PageSize aload pop pageparams 3 {exch pop} repeat
+setpage}if}ifelse}ifelse}ifelse} bind def
+/!{bind def}bind def/#{load def}!/N/counttomark #
+/rG{3{3 -1 roll 255 div}repeat setrgbcolor}!/G{255 div setgray}!/K{0 G}!
+/r6{dup 3 -1 roll rG}!/r5{dup 3 1 roll rG}!/r3{dup rG}!
+/w/setlinewidth #/J/setlinecap #
+/j/setlinejoin #/M/setmiterlimit #/d/setdash #/i/setflat #
+/m/moveto #/l/lineto #/c/rcurveto #
+/p{N 2 idiv{N -2 roll rlineto}repeat}!
+/P{N 0 gt{N -2 roll moveto p}if}!
+/h{p closepath}!/H{P closepath}!
+/lx{0 rlineto}!/ly{0 exch rlineto}!/v{0 0 6 2 roll c}!/y{2 copy c}!
+/re{4 -2 roll m exch dup lx exch ly neg lx h}!
+/^{3 index neg 3 index neg}!
+/f{P fill}!/f*{P eofill}!/s{H stroke}!/S{P stroke}!
+/q/gsave #/Q/grestore #/rf{re fill}!
+/Y{P clip newpath}!/Y*{P eoclip newpath}!/rY{re Y}!
+/|={pop exch 4 1 roll 1 array astore cvx 3 array astore cvx exch 1 index def exec}!
+/|{exch string readstring |=}!
+/+{dup type/nametype eq{2 index 7 add -3 bitshift 2 index mul}if}!
+/@/currentfile #/${+ @ |}!
+/B{{2 copy string{readstring pop}aload pop 4 array astore cvx
+3 1 roll}repeat pop pop true}!
+/Ix{[1 0 0 1 11 -2 roll exch neg exch neg]exch}!
+/,{true exch Ix imagemask}!/If{false exch Ix imagemask}!/I{exch Ix image}!
+/Ic{exch Ix false 3 colorimage}!
+/F{/Columns counttomark 3 add -2 roll/Rows exch/K -1/BlackIs1 true>>
+/CCITTFaxDecode filter}!/FX{<</EndOfBlock false F}!
+/X{/ASCII85Decode filter}!/@X{@ X}!/&2{2 index 2 index}!
+/@F{@ &2<<F}!/@C{@X &2 FX}!
+/$X{+ @X |}!/&4{4 index 4 index}!/$F{+ @ &4<<F |}!/$C{+ @X &4 FX |}!
+/IC{3 1 roll 10 dict begin 1{/ImageType/Interpolate/Decode/DataSource
+/ImageMatrix/BitsPerComponent/Height/Width}{exch def}forall
+currentdict end image}!
+/~{@ read {pop} if}!
+end readonly def
+%%EndResource
+/pagesave null def
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+GS_epswrite_2_0_1001 begin
+/pagesave save store 197 dict begin
+0.1 0.1 scale
+%%EndPageSetup
+gsave mark
+Q q
+0 0 250000 250000 re
+Y
+q[1470 0 0 1440 0 0]concat
+147 144 8[147 0 0 -144 0 144]@X false 3
+colorimage
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts7Z*U`K_\Jms=`eDnV)BF^#aQnF?PYs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts6f@F>Y#U0HO],N3WK,=
+aI!gMUk8XHs8;cjs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8Vfco#@%As6tC0iGZDf&oh%mnF5uJs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8VNUn6AL!Wd>3;]fH,mNQ@M*[&/KUs8W#oqZ$Tqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,mo^^"g,QI7\
+pYfu%M\9r3)=[.cs8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,en*jRQ'rlTik.NeTs,G-g)7QPss8W,sr;-Hns8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#up@\!rR3_h&IJ;Z3]S[5<=;p\unc/Xhrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#umdKXM8/8.O%Hb>a
+s8S)$RMiW6KE(uOr;?Eks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr)lss7,UF`0_bKnUC5hB"Ea,CfVJCnF?PYs8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts6f@F>Y#U0HO],N3WK,=c(,`_W.Y-Ms8;fks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;6?js8T$jM6ML5
+s7h<Ag1@gL%Vo&_n*olIs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VNUn6AL!Wd>3;]fH,mNm4+4\Z1;^s8W#pqZ$Tq
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8;cjs8W+uSV"1u"981Qp"EibL(8$")Xm1cs8W,urr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,en*jRQ'rlWj
+k.<YRs,kQt)S)l#s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#oqZ$TqXeLKXJcu,LM"95+\:kE.<>t>qnc/Xh
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#un*faK8/8+O%Hb;`s8S5+Sf5/>KE(uOr;?Eks8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,sqtg?ms0/;O
+\:Y"cq2+[p?FGLsAPsH7n+$GXs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts6oFG=\9F.HO],L3WK,Ac(5iaWe:?Os8;fk
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!r;6?js8T@"K=HXAs8.]Fe6]J7%:`6Rn*ffHs8W)trr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VQVn5r3r
+WI,0;]K-#lOj0I9\>k2]s8W#pqZ$Tqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;cjs8W,+Vh;O:#ljd[o$gmNK+2?f)Xm.b
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,emdO4H'rlWjk.<YRs,kTu)S<#%s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#oqZ$Tq
+[&8YhL^O1ZN:PJ$["Aiu:E&]jnc/Xhrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#umdBRE7hr%O%Hb8_s8S5,Sf5;BKE(uO
+r;?Eks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,sr;-Hns0en]\qpdor/C3r=gWek@87[-n*pAWs8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts6f=E
+<C[e(Hk#5M3WK,AcCPreWe:?Os8;fks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Eks8TU.L:`?Ns8@oIdoj&2%U_sH
+mdBQDs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+rr2opr;-BiqYg?grVcZnrr2orrr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8VNTn5VsnWdG9<]K-#lOj9O:]W6\bs8W#pqZ$Tqs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;fk
+s8W,/X+n6H$NL'ao$^[IK+;9_([g_[s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W,urr2rts8N#s
+rr2orrr2rts8W)ts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2oss8W&qqu-Kks8W,urr2rts8N#ss8W,urqu`mqYgBjs8N#srr;usrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,emdO4H'rlWjk.<YRs,kTu)SE,'
+s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W#pqZ$Tq];p\$NXPmdORpn"[=Jco8f-m_n,NFfrr2oss8W-!s8W-!
+s8W-!s8W,urr2ors8W,trVQQlr;ZfsrVZNjrVZZorr2ors8W,urr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts8N#sr;?Hls8Vcao#.kmf=m!]Z$Y9R\G>pq
+q"OL^s8W)ts8N#qrVZNkrr2rts8W-!s8W)us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+mdBRE7hr%O%Hb5^s8S5,Sf58BKE(uOr;?Eks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,sr;-Hns1PLg^lAj'rfH^!;71rb
+>"KOtmdL2Us8N#ss8W-!s8W-!s8W-!s8N#srr2rts8Doos8W,pq"XIOnc&Oes8W,urr2lpr;Q]p
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,urr2inqu?]r
+e^;=:O@[*C#j/r`gUJuhW@c,U+j$NXcF8GTb-h9Ls8N#srr2oqrVQTnrVuots8W-!s8N&us8W-!
+s8W-!s8W-!s8W-!s8W,urr2rts6f=E<C[e(Hk#5N3WK,AcCPreX+UHPs8;fks8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+r;?Eks8Ta6L;T#[s8A#Icr%&u%Tu@>mI'HCs8W)trr2orrVc`prr2orrr2orrr2opr;-Hns5;SM
+W/jN?H6LM?I,NShp\=X`r;?QnrVlfprr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2or
+rr2orrr2orrr)fpr;?Hks8UBc[W>CRY'^QLb=)C-KDtn7rr%fUomcYi?/2nBaI!gkX&RWbP4J,-
+s8W,urr2loqYpKmrr2orrr2orrr2orrr2orrr2orrr2orrVc]ps8VKSmo2alWI#*9]/fokOj0I9
+]W6\bs8Vunq>UBmrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2or
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+rr2orrr2inrV?9dqYL-dqY^3dr:p$\s8W,1WeA<O%0-9ema"b6J.>aR)!L5Os8N&oq>:*frVuot
+rr2oss8W)trr)fns8W,Ncb"mA$aYEkeY+,8TbP\<)Ph]tfZpl(s8W)trVlfqs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rtrr2rtLO3$79*'r`'<[$.e"nGHX=E,2/a^D>
+q:]3Unp:<7PQ1T?p#0?8ZR<h`-e,h`o^_GMs8W,urr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+s8W,emdO7J's2oolG#@Zs-(m))SW>+s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,urr2cjr;6Birr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,urr2flrVHBgrr2oss8W)trr<#us8W-!s8W#pqZ$Tq]W?k*NXYscORCCk
+YCI*d7i:X]nGiOgs8W,oq"O=Kn+-&>o()>@nF-)FqqTW1F&`O)B+)>2*o<b=s5@8`q1\@a9>Q]#
+]:W6to_%S<p@@bCnaZ5@nal>AoC;ABnaZ2?nac5?oC;ABnaZ5@nal;@oC;ABnF,oBq>SUV[:)N-
+E`Wm0AdOT:%\n=^UNmEJHk3Z@'ul@Sd@MH?ZS;$t;#^!3s8S>]np'3-0ufP*`3P'Zl1=B4p[RbB
+nF,u<nFQ/<oC25?nF,r;n+,r9nauJIi8EZl5o-)7%G@pDq!s?[PT$g#IJWmAmd9H3n+,u:o'l,=
+nF,u<nFQ/=oC28@nF6&=nFQ/=oC28@nF6)?nal;@oC;AAo()DOrr2rts8;fnrVc`qs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqlTkr;?Nns8W#pr;6Bf['[qoE2%]+Y'G;r
+H$QT=GcQ(9]Qn6tcC,CGqMjmd:U5T`903c%D52E'YC_A85X:#'!)a+0?3^^A#7"N>#[dc<9`P/i
+82VZWE!3_/);D2CpYTEZs-!?MHJ>GCT6M/$,>naPEs`7b#RP/M$"jPNBF5)]$41MT$#U%VE!Zki
+#mtVY$?-=ZE!cqk$Oh%[#@R`=@fusG1FPUr6kW`o&5"nk<'Lt1:C2GR!0qL-Xah(uN#0m5*p^L#
+r9//#s-NQGDq:a!LLVnJ&pY'(KbG/G&JKL('71?*HP.!?&efa-'7LQ.Ih<<B#mkV]$uumjF:o74
+%h<Ui%sS^$J.`NE&efa-'7UW.IM*<@&JKL&'719&HOpa7&.j.!&:+itH4:@.$Oq.b%<2XZD%R@r
+BkaEN[E\aOrqlTkrr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr<#uqtp<hr;HWorr<#u
+[C+4lBqlI^I0p@7$k&18)PJ8rX!8mn-Rl;A,f*DI@+Cn_s7hT@b>5Bo"'A6.,q?__0!QoXZ8FPT
+5=!CS4ioiOaZr275XELY7*J"ec::CNA5uNZ@L&o^&BBqNkIWSLoRQu<Ms.Z'Nb8PV2O@-5i(Qhj
+92*f/9[up6ePAul:J]P;:tAH?ek]/o:f?(L<8LYThGmP2=BOQb=lNLbiDEY=>[?&i?J/OffN__@
+=&uD3>)6Tc;dr?&Kk(@ZGSIQ>(!rBfm__3foR[#APk)s^TlguM;P@/qpKq:g?XN#)?ftg(k[7c^
+?si/+?g1s*l!n2h@:AM1@-h9.l=")e@:8A.?g(m)l!Rl_?si/+?g1s*kZqKW?!c`$?fta%jBc-Q
+>@$>q?0,6oi)a%=<E7mP:tSB5eLN2Z#7#oS8s&oGqYgBlrr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+s8W,urr2cjr;HTns8W)2][Ai&N!'<7,:0Nr=Q!k+n8E:=B4pO;@-1HkhcEt;;HWF)>BA5a&-)Hc
+m`JD/IfNnVGuI`/='!jO<S:2HfM#&j8l!i-:=Dj2dS!<_92*c,9[-1&cU1(K3Ac@g57<Ec&$gg$
+hPqt%nU:H1K\WI?M/5XK7aFLmb="eB6UT$a6cVP^_a$Q+5XN@R6Gl#S_`^9'4[?tL5fGlO`B?K)
+4?pbH4Mj9E^,nBl4$(2?42Ep<^,J'i2`f/;1r(1TFs\7t9f`]/?3m*F'tK/8go)FniFW&hQM]E6
+_iY[28s(GN^b[jU0Jg0m1Uf%o[kKVI0Jg0l1Uf%o[P0MG0Jg-l1U\tn[P0MH0f-9m1Uf%o[kT\J
+0Jg0k1:Akm[PTkM1c;]u27GJ%[l?CZ3BFc53kmg@_EC0&5=37R7*&V=hfEl5(Drl87ZRNKrr2os
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W-!s8DoqqYL-is8TmMdlKOH"9sK=42c#SojhY!5=!(,+J&rNL^=B=
+"pf__#C6U\FoVMo6SUs]V&01,N:"\]Z%WWP1+N>)Gm4It"9`rM"*aeIGQ7eh!!%'?!H8#?E<#uW
+!!$s<!,quBFTVhu!X3]q+XhSA$F5="i3=g4r/LO2E6=FM4"NAl!-ePIDu]o[!!.-@!HS5AEW?,\
+!!.*?!HS5@E<#uV!!$a6!,DQ7BE/$I!!$d7!,qo<D?'ZP!!$g8!,DQ7B`J-G!<Hs>"aC(OJcl3V
+*uZ5(6j\lj(9`B-c^GgHdo$/FQi,]C]8-h:(et&2C]OQF!!$L/!+Q!/@fQL=!!$L/!+#X*?N:(;
+!!$U2!+Gp.?iU1:!!$L/!+Z'0@fQLB!!$j9!,MW8C]FHO!!$g8!,MW8CB+?M!!$m:!,qo<EW?,\
+!!$m<"*uj`[rHKc'c)n;ZHW@Ks8;fns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2ors8W,rqu$Kos7GpVI=/(##^@jO[W$6\
+>@->9-`I7RIK0@a!!$L/!*K:%9E5&V!!#1a!B^>^4?tPDfqoeipPA4X9X'0_82q"X!&O]V3<0%=
+!!"tY!&srY2ZNhN!!#Oi!'pSb8cSic!!#Uk!&srY2#mV<!!"qZ!"<O7$,;H8mDqcss.Ao+9<3IT
+*#1F5!&=QU0E;),!!"\Q!&+BQ0E;),!!"\Q!&"<P0`V2?!<>=m$qL@!63%!O!!"YP!%n6O/cYl(
+!!"VO!&"<P/H>c#!!"DI!%%[G0`V2(!!!*B&ccfF#H!"had!_:bt7s7PPsBC]8I7J*BFZB<t5[/
+%Lu&?%S7-?8.Q5'*$&8u(Kq7U5Re,d&e[tS(0(eQ7h-##%Lu,B%o3E849,@0!!"ML!%S$L.f]Q"
+!!"VO!&"<P0E;)+!!"YP!&4HR2ZNhQ!!$F-!-h%+bYCse6q!:>s8W)ts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqu]m
+rVc]fp%LmEOT>N<@V"b>C[`c&XT8NN!!$j:!au'/57%WU"pQeO7UM"/SUGpLJ:E`3Jsq7/:=#@E
+s7qH<a\/dg&5GG&F*34hJs(V5O+2Y?J:N`1J<Nhn+*V<OJq@0H=sm-/(+ggOG^5$pJW5//MLU,4
+JqTY$=A+-K"43JVq;Q&eq30^=,Bd6-GBo-uJW##-M1:#1It*6'ItrN'LOXf.JV&c(GC<@N'7OXI
+kN7D@?Q_s#'RG(TJUrQ*ItN6#KR\K)It*-$ItN6#K7AB'It**#It<-#Jp_s$L51Xs>=Da]!2b5a
+a,q/2b";X5QMB08["Ah-^T@>2s6oCCnaZ/@oCV;3lCaJn`N+"5[QaEQHIT6#cH!Njq"jLKn*f`6
+qYL&u\@Qj,H@^X$It**#ItN6#K7AB(It*-$ItrN'LOXf/JUrc+HA<"A2uiqQ!!$dP)OG/PnLH,\
+jlPe-s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#urVc`lqY^Bns08iO"U/fr0=5tKr('E(#RQ4c!,;Q:@K6Bm!!"3,5$#M9`:s#u
+p@e.Ys8W)trqu]js8W,5Y(afT%KH?]m`A,)J.GXK([UPXs8W,urr2oqr;Zfskhj>,T,7P%HN3V^
+jKB\[?N?adJH,ZLr;6Bjrr2orrr<#up\F`3C.FJ%"Q6L7s88&Oem,J3&Du0[s8W,trVZ]qs8W-!
+s8W-!s8W&qqZ$Tq`jh8JL]mbHEW>ZZhk_-FC)ld6o)Jairr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#uq"aeq>YA-]!2k>daHRP9cqOK>QhAd'X*bE-d(o\]s8;fls8W,dmdX4=%B+CL
+l+f=Zs,kEi&@A3Ys8W,sqtg?ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqcKf
+s8W+EH$fSl-3OH]!WmaU?f<Uk\UK"2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrqlTks8W,'Yg!1LGY1TUF*%%%.B3@JEWQ;U
+!<Gsr!%C)q;o$2as8W&rrVliss8;fnq>'m`qYU'^pAb0m\u^P&Nt)-eL[N8WY^d6b72G(Mm/R+c
+q"XX`s8VWYm\kRKnBao0qiTmA0Vit)@8.^)l0SHMs7uKdqYL'bqYKs\p](9n]=b^g:CY.#')(@"
+s7VAhOq<Y!7J6EQqtp6cq>0saqYL'bq>'jcrr;6Jl\K6lgSu_&r/U3h9:Tl#Wh>+Hs8VlgpA4X^
+qYL'bqYL'bqYL'bqYL'bqYL'bqYL'bqYL'bqYL$`q>UBlq"jkt>YA9c!3(MgcBfFDd8L#ERHqjU
+a.Pp"r;QZnqu?]rmdKUO9GsmY&EUSds8S)"R2`N2L&_2Qqtp3frVlfqrqu]lq>'m`qYL'bqYL'b
+qYL'bqYL'bqYL'bqYL'bqYKs\q#CBo\@B$K!%%^H=9&>@7S(Z_43`/$\,ZL.s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#urVc]nrVl`mqaa86
+"9a9`@-D68lkUJ-!!$d;"ChH54:)<BZ*C\9s8W)trqu]lqtp<jrr2orrr<#urr2opr;-Hns1GIf
+_iG9,r.j^_8[*aV<CI_imI1)Ts8Mupp\F^!Sl=[Y/H>a8p!$4PP8\L?!0rXrs8W,rqtg<krr2or
+rr2oss8VunqZ$TqW1Sd0B)q><70!:TjgR(-CDZI/n,NFfrr2orrr2orrqu]ks8W,#TnT@e!;kY`
+s7_6"V&tA$(?t)Js8W,urr)lss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrVlfp
+q"jl#?V4iu!N^klc^>[GfNA1RRd7jLcDX_<qu$Kos6f@D>tPm4HO],N3WK,=aI*pPVM"pKs8;cj
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts7#OH%1Off!)3FnD)OAd
+:/9V78<j/Sr;Zfss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8W&rrVc]orVZU]6])6ZMf<S-<E@c\$\n]^C'=cD!!!p193V#]o`"jhr;?KiqtpBlrr<#u
+rr2oss8W-!s8W-!r;?Eks8Ta5L;&ZVs87Q<btP?m%p2:;m-X<Bs8N&us1kgl_MnZtqM>(1CsSLg
+P&(Lo2&#6>mJm4drr2lqrr2rts8W-!rr2orrr2rts6T+;N,'6\U`]X5NUkIsW-Jfub.RcSs8Doo
+rr2orrr2rts6Aq;L1_O^W?_H@MY,G"XaC;%E(Kp*s8W,urr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W&rrVc]nqtp:r<C:Cl!j@4pd$l$Nfj"LVRcM+9aei#:s8VQVmTiBu
+Wd>3;]fH,mNQIS+[]"iYs8W#pqZ$Tqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+rVc]ps8VHPl3n(H!!#[m!,aeY^JRqd%M3:BnF-DWs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#urVc]nrVl`mr'Ec3&JLRYHMp?*c3"5t!!$[4!)<n007SJ.
+oCMMPs8Vunqu6Tos8W,urr2rts8W-!s8W-!s8W-!s8;fks8W,1X+n6E%0-6Xm`eG/J.GgS([LGT
+s8W,Jc+L?8')LQps7hK1W[=Zo'j='8[^NOBs8W&qr;Q]prr2oss8W-!s8N#srr2oss8VNUno7hS
+`0(c2m!A^"I'S5%Xe'k=s8W&qqYpKnr;?Hls8T*kKr&hjr8(c[pkIS*-@oJ._n`e^s8W#pr;Q]p
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8Vunqu?]r]"5Hs(]ekb%BP1!
+d[M3PhIHTcS`774c`:46m-\1O(92]ik.NeTs,P9l)7ZYus8W,sr;-Hns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2rts8Dops8W,gnF$hs0E;)O!!%1B<SB8f_g-O6s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrVc]or;?I[6^&K0Uj77b
+4$CC\!d=\IB)hp$!s9RN[(-/9s8)TgrVc]ps8W-!s8N#ss8W,urr2rts8N#srr2orrr2flq>^Kp
+\>b1oM@BO^J*tTSZ@NNi8J^[[mem(aZB.H3ZRPqSRIA!Z^Ps+;5lch"J,fQKqYL'gs8W)trr<#u
+s8W-!s8W-!s8N#sr;?Eks8T3pJ"^f]o\!IKqN0:(+FIZ@mdTfIs8W&rrVuotlg*qmBcZ!.,QI\"
+o[['HIKkXP9)JSes8Murrr2orrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8Vunqu?]r['[1f)Zk7f%BP0ueY+&]iFr8kSEIXB]9u/m8K+XW%Hb5]s8S5+Sf52>KE(uO
+qtp3grr2orrr2orrr2orrr2orrr2orrr2orrr2orrr)fpqYL*bq>:$bqu?]rZEgh;!'1)[A.9'/
+DJo"\(RobuV>pSqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+rVc]nrVl`mqa3c9+<dh2H2]NR[K$;J!s3!7!^?tt,dXhas8W,oq"Xjfrr<#us8W,urr2orrqu]l
+q>'paqY^3dr;Q]ps8W,sqtg?ms0nq^\:k4gpNH,Q9=9?^>Y#S&qZ"L?L;o;Zs87ZNk%iJ;)hqf*
+Cgfj1qu-Qps82]kqtp<ks8W)trr2orr;?Nhq>:$br:]jYs8W+dP_Xos!:%?^s8SJL]fVd0([UMR
+rVccjp\4^fs/DZGTPso+g0agQM:ngTHs$Zj^:4.Bs7lBbqYL*cqYU-cqtg0dqYL*cqYU-cr;HTn
+s8W-!s8W-!s8DoqqYL*cqYU-cqtg0dqYL*cqY^'\p](9nYHP2T)$"h_$a,1!eY+&\i+E#hRcqUL
+Tlpp:FV3lN2#mT7e"RhqXb6ZRs8;fks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+rVc`qs8TF3]*&6j!!$4'!I%./cXg\T!<R/J\&\OKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W&rrVc]or;?FZ7$]&DZ#t9g.P._&!,r)FAcMf`91rXbp%84]rVZTk
+s8W,urr2lprqcKgr;?Nns8W)trr2ors8W,urr2N[oCDJDn*f`Ds8T3nJ$st7s7'mrbtGBq%r#&d
+^q-VRL)oX1>kIE=etXXcGSa(7#.(\Cs8W,dmI'cEq#CBorr2oqrVl`mrVuotrr2oss8W)trr<#u
+o()=,Bc#3g)?9Ggr7u%^Er`D@N;rqXs8W,Vf<hl<&G=7,s8S;]i(pn:!1SdDs8W-!rr2orrr<#u
+s8W-!s8W-!s8W-!rr2oss8W)trqu]ms8W,sr;HWorr<#urr2oss8W-!s8W-!s8W-!s8W#pr;Zfs
+`lGta3"1:F$a#+!etO5_i+2lfQhAa!Wd5,pTIp3DPKK@5\#4QMrr;KVmIKi=o()ABo(2GCoCDJD
+o()DCo(2GCo^VJDoCM\AlgKIYRtcWq7RhP$!(?kfB+,3*923fQEqKtTP<hKcs8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#urVc]nrVl`mr'No<-7H0BGk`U7WW3$:
+"U/B9!%^`7>5S3ns8W,rqtpEns82]kr;?Nns8W-!s7Z0\qYL)u\&`T1S:5phF*"8h%UfMF@gWNR
+!<[3m,<*T+'*%0%o#aD2L^um0.f]QS#R+E>$>9_M@0H[;!!$:,"'uHICBk)U!<HCc3d\`\cN!qE
+qtp?ls8972b\qHrH@)];H)c7>X))^Q;*HGFN=PX@C]F!]aHI'dE`m^:[!-\f75Ql37kf=2@s`K=
+D,NGY.4.ndF+].PH$Q65H_l(9V0mWdI!_];I&24<VL!QaJqC#glgb#Ts8DoqrVc]]m-TIZUO.?a
+I!hf=I&24<VgEchH[D]<H`2+2UQ(8G2E,1l(]\tl$*/Xoe=I`Xh-L'\Qh&U*_3#M&O')Yl<!<@r
+#RFK:#?V6;=pPC;#7"Q?#[[fBAI&QR#7+rJ#\jVND$^Mi#mtYP!+,^+A,u^R&e^?f3kT0@n7?1s
+)B,"D!*m+Hc2[hDr;?Nns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trr<#u
+r;?I[7$Af>X`\mb-7>_l!,i#EA,lT[8kN4_qtg9irqu]lqtp?ir;HZqs8)TgkND5iMmGQ1L&_9h
+#mteT!-\VPM\d8)0JU'r35.F9_Dsd"7Rau!MBr5R8b0k_Z%O,m:<?%!g.=rf7nD'"9$p.$cpgUP
+7n:ff5fPrN`%s9b#ml(l%nQ*Tmf!+`9MC$<!-o(fRL^$q%M4j8&<I8/U,FT&V0N(+a%?=2RHM"3
+G?5F\#)i`kM[pGj#nEI-"criiNW]ZQ#nN=-$&JW^IK0A!!!%KK!.4bHHN4%n!!%?G!."VFHN=.o
+$4:gXYfZqFs0fDS#RF</!G)62H2mqj!!%<F!.+\GIfKJ!!!.TM!J:@PKFeZX)&no)1HB\_!NLYe
+d@2-NeQ2_MMY>OmV03;(/92j[[4!K*-n2;L/@$iZYV.Z:0f$9p1V#G(^,\9k4?peP7*.qicV73d
+>[?Au@d%B6l"Ol"AS1?i42D%'HiX7K[C"0Xs8W#prVuots8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2oqrVl`mqEdN.)&]&jGlB*@XT/?="U/B9!%1B2<r;dkrVc]jq>:*frVlfq
+s8W,6^="r!Jcl6u"p]i--`p-=eR;qOCM`KZEV='[mo39=:/BA4:!lR,e4E6LY(@_e`&I(t0s6*O
+5XNFW7En1gb!eeC7nLlo8]jRqb=bLR92<r.9@%BjnjuL$!!$&WMPHE#YQ+Z.='=F$EV=*[nS;q3
+C2<<VDuNL+Vh\dhh5i"(r0$Zu=K[,^C1ObeC]%m[l=O\rB5$^JC@#VJl"4SlB4gIEC$o\MmqHP-
+Bkm-JB^fVJnRu\-Bkd!KB^BMOnL#`g%Luk=p%1jKCB+?=1c;dVBC'/>l!\/h@qG%>B'a)?l==Mk
+AnUIBB'j)=l=+8j?=)h_3C%[f!3(Dbb*<k2^c;5?:$Af*Vgogt@G,.#l<dr]?=)Yr>i8[dhH3k8
+;cMLK;UnQ>eOiQ`7nLom7`mq]`B$)p2)Vfs19_fDTEPLL!!$70#Z7t9`rH)=qYL*hs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7uKfs8W+FHDUlNKm7nC2)`#G!-&/G@fQKY
+8kN.^r;-?hrVHBfrr2oss8KaHe2]RF!!%'c-)t-PiG`c.@V+k!:!kaT\/l``',?T;%>P,lI0'Ot
+!!.$=!,VlBB:sJejKC,lX=LE*'I"Dq!!%*A!Gqf:E<#uT!!$d7!,DQ7C]FHN!<[aT?fj+"ZiC).
+<)e!38Uq'QM/-qt+<dE`#_Wd%NXuk`&/1*9'9d$(*6=BYqWN#"mt&fQ%8&ZN#S*C@(Q]CLQPUR,
+(E8\X)j_?[QPpj5*$(Lg*h+,iS/`T?*?^jk*h!rdSf8]C)&\fE=klG9cO:5#jQ,>8'Lr-'DbX$W
+;,Z![(RZ<fSfJoD*?L^h*LdlbQl$d/()`GS(mc!TOqeh!&/(9V*[u26$DVna]o3`RRiT\?+Ld1<
+75dsD#*B<'KaJ0>$4;Ci#_E6dI0Bh$"U02R!d4PDC]FHO!!$d7!,)?4@fQL>!!$"#!_WLn92/-#
+p%A%WrVcZlrVuotrr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,sr;HZqs0oJ`
+$4MJuB^J;]c2[ig!s2s4!%gf8=oA3pqtp<gqu$Kork?+p3]`#r!-BP9Y@hS<Bl!3(6,a]\Qj*hH
+!!.*?!+Gp.>lXk"!!#1_!&srY0*__J%hDVJ$V>VH&&XSR_iu@EIh,OD)Z]q)&.Co/"#^Pr8Ic5)
+%Ll,D%o<6+<#m!KCi/eZ(7,"$7!!F"*?ArB-EC`km03fF!!$%"!'pSb4ok[M!!#P=*?qY;%HbAf
+s641OW?m+%'*&#1!!$1&!([(i7fWNZ!!#Oi!([(i8,rW\!!#Oi!(R"h8,rW^!!#pt!+,^+>Q=bE
+?<uVK27sY=EilIL!<Gam!dS-[juPQ:!!$1'!D<Cm8,rW\!!#Oi!([(i7fWN[!!#Ff!(6ee6N@*V
+!!#Rs!t/-m!ge!FWe)(lKGg(n#ppQ5!!#Cf!BpJ`4obRA!!"qX!&afW2?3_2#6mL*%TNuJ9b%Y-
+%Lu)B&4Qg,1dsiJOH?C(kiqs?q#CBor;?Kms8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2orrVc`nr;8cDNB]\LA7Y!1#_W3ZB)hon8kNLhr;-<fr;?Kjp%A#M8WEcNDCI'=
+BPR!ND"'AD\d8au!!$j9!+>j-9)nrK&.h>8"YN;8@Yor2It*B"G'pg0])):"nF?1*E^u4'!j74s
+P&D(04:H+,%VJ<4@9cLsoCVPAnFcJHhr!Ds"_'AK]O"t+!!%3U&m@Re?iU17:J]G6:X]:DD?pJ0
+H$P3tJsUt:PCS4TJUN3(A.cqK)W%PCbF9W?EY18]&N_TqI!_'.JXV+=Q[jUTJ:O/?J=M.?S:H-[
+J:O/=I[Z+MVFX3h!!"/B!)a::MIpMf)]YIi*+a24GlRh2&.st7BC$`aUBh-+I!h93JY%CARt-$Z
+J:O,>J=(k;R"0^SJ:O&<J=1q<Q[XCMKnc:":IccK!*))]>X8?o8fE&'Lk1,?It*N/Iuf)/Mgp58
+It*?,JVnVoHapSsqYL*Xn*ff:naZ/>naZ,<nEp#GpAb0ms8W)rr;HTmrVuots8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8Vojqu?]rG^-5%'UO&gr#?`K!!$a6!)+"<.dcWj
+r;?Qos8TC1bl\)c)]bV`B'a>NnMN8:#mu@d!,V]9=onag"9^YP7:)"8QKdYunaZ)Bp\+Xes8N#s
+s8W-!s8W#pr;Zfs^V76J3"8A6!\PMo(C^@@3rs,.;"jY[s8W,pq>:3ls+cB*!!$D2?/n:@a8c3N
+,U?'&E0^J(Eb&eJ1H)]B!*MlbDZBb8rr2rsrr2rtrr<#uIr7c?C'D/+)m4f.M/!bj/-)oKJcGcM
+r;6Bjrr2rts8W-!s8W-!s8W-!s8W-!rr2ooqu$Kos*fE]!!#S:-`Cj!o)JcB=BLQ5J<g089-kp\
+DK,:L!.T6<W;lntqYL-hrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#unF5t&KnPD@I$^%O
+lg3s;s8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,sr;HKgqu-Km
+rr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#ur;?Nns8TR;cO1/3
+CMN?)6H&p)EWH2E!!"=MZ*OE0s8W-!ZEhdV!-Ue#c#e%&5=!0p$\\Q\CB+?<!!#"k&O1erOR)5u
+q>'dbs8W)trr<#ur;?Nhq>0saqYBs`r;?Klrr2lprVc]nkj%MlM1pY:ItWAr]=YQNrr;ooqu-Kl
+qYL-is8R4aUAt:BD/Sqi,c1PA=?SfP&eS7\(78rUnJN75!!#97J;XC,s7Q'YqYL*`p\=dgs2Dme
+:cel1>RZ<u&m.C!2(B=-mHsoPs7uKeqYL*cqYU-cqtg0dqYL*cqYU-cqt^'bq>'pfs8>M\FoVMJ
+5XE@q?KD.eATMpQ.4J!l!*qE=[q0.;!!$PYI[gB;s7Q'ZqYL*cqYU-cqtg0dqYL*cqYU-cqtg0d
+qYL*cqYU*aqY^9hs8W,urr2rts8N#sqYL*cqYL'bqYL'bqYL'bqYL'bqYL'bq>'mbr;?Qnrr)fp
+rr2orrr2orrr)fprr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrr)fpr;?FU5E%]ga(8iI"p]\[!Fu014%i4Ms8W,ko^mQZV[Eod<`\*kC@<#YRfEG,
+!<HU/!'q2/5(A'CmHs9?s8W-!s8;fmqYL'erVlfqrr2ors8W,urr2rts8W-!rr2oss8W&rr;Q]p
+s8W,urr2orrr<#ur;?Klrr)iqrr<#uoCMSa%V$k6WG6/8%1S-o!(M6ZM]3UX/2"8;@HI[qIK0@9
+[^N^Gs8W#pr;Q]ps8W,sr;?Tps1Q"N1arhl.17jZ%CimQs8W,sr;?Qnrr2ors8W-!s8W-!s8W-!
+s8W,urr2orrr<#ul07=<$VCC!G[Fh;4?gR]!+N%2\f)Jb!!$_*9[QL-e,TJV\@BQYs8W#pr;Q]p
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqcKfqYL'cqtg<krVuots8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,pq>:3ls*/dh',-[UGPiI'TE"t,!!#\(&1Hl1li7"b
+7Rht0!,l7QkZqNT#RZ=e!,;W><WE+K9hf*ho^i%[rVlfqqYL*frVc`prr<#urr2oss8W-!s8W-!
+s8W-!s8W-!s8N#ss8W-!s8W)trVHBeqYL'bqYC'er;Q]ps8W,sr;?Tps1,\]!!$A":=;p7eGoSa
++X(-2EK:)"@9H^g7nCi(!+lr\8b;QDs8W,urr2rts8N#ss8W,trVZ]qs5;kq^:h5Sq"ajcr;Q]p
+rr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+cAu!!#J.*Lpn^nduP"():,VXK2C%8HAm<
+?=2eS3kkt,B(PWes8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts8;fns8W,.\'GEkK558l
+5siNj!-/)@>6"XM['[4?s8PDPK`hR1C2<9@=l'AgK)bmb!Wl.""!OtU\,ZL.rVc]kqYU6irVuot
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL-is8R:eQiI,'B5-fe0s^i[?R[EuCi#=9!-W$iln:&r!!#c>H'\L1s82]krr2oss8W)trr2or
+s8W,sr;?Qnrr<#urr2opr;?Tps8N#srr2oss8W-!s8W-!s8W-!s8W-!s8N#srr2rts85>UC]FH>
+3BOo`A*EsnD-:"rIt)tK!'Lf%NFZVe+X<oj#>XdXmf3=erVc`qs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr2lprqu]l5<k2o5fdGFl3.EC!Wcg3!'3_E>6"X$77E"<#_d28oM/33!sO2V!GVT78HT&8
+['[7@s8VrlqYgBks8W-!s8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#uoCMMa&R67qSn`*4',?Z1!(:sPJg2LZ()`QVD=S>TOoPJM
+L5)#os8Vrlqu?]rs8W-!s8W)trr<#us8W,trVcZlr;Q]prr2oss8W)trr<#us8W-!s8W-!s8W-!
+s8W-!s8W)trr<#unaZ#W%7L6sFB;W#84h,-!)B#QYEkKQ!!#A-+.[7co*,MX6:,qss8Drrs8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#uq>'pfs8R=gWtQ59G'<d&*M!01B`J-+$k+K_s7q(kW;lpE
+E,bJA9$dS?HNF4^!Wkar#plpa[/^1+q>'mdrr2rts8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6Ak9"pSd(5/g]/hZ*Y!
+#R=(EEe+;p@lZTb>?p.f!-ASV;![H5s8W,trVlfqrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;?Tps0oJO!!#b#$]/J.lm!dQ"U/6#mHR>;CB+?6
+/M=/CD=RZ,EIWJ:s8W,qqYU<ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W#prVuot\$sZj%>8S7nNK1V
+!!%!>!F#O(+iVF:]tN&#"aXZgl;:I0!<RTL!bVK51eUJOp%@tUrVcZlr;Zfsrr2orrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rb*VuQg3@q=gc42([p?n*X0F*!6>!+9,>j?c8T!!$OE'h@lenGiOgrr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL'gs8RV"NrT/L
+-7>X*D=Io>MA6k-jQ,).&NKgkB0&/h?!ZCh!*al"PlLd`qYL*grr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+rr2oqrVl`mr'*E*5![1t@d4+$J-#d_!!"oe@r&lqeGoSc:/KMN@d"%&K`V<g!!#;W8n%Voq>^Kp
+qtp9js8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*c6@B:PNc8n.)B>4H!).`dOB,D>!!%RcC@3GuW;lok
+H?teTs8Vrlqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2oss8W$h8T4Y0=ueXT@:JI$!+pV+U&Y/l$O]Q,!,YS1e4E<\!!$<8\\nIIs8;fm
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2rts7uKgs8W+DGcDDkQ[!`O*$1[O!,2E58KAg)X/j)=!c:Csb\V1g
+&/1-*!,MW88J)O]mHs<@s8W#pr;Zfss8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An8"pS<j2nWL*j95a;
+!!#B4H%R(VAfVqdBl!5L&rlql4be]Qs8W,qqYL6ls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,XH%LkW&!,k\2e4i`i!!#l[P,caMb5_N.
+!sEpY@H9@+]EegRoCMVSs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,rqu$Kos1#Sb$4MH!C@OSW`rH*[
+!!$.)"=pOQXVVds4$:;uEV1.dQiI,'!Wl7$![>"Y[f?C-qtp9js8W)trr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rh-V>pU+?!lYW6,N[&AJl=SUSFpk!,"J]aAuC"!!$sH$V]mPlMpnarVc`prr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srVc`qs8VENljXA(
+!!.LXAEbd'[/pG<s8W+NJqa7*3t;g^A7b!K,,>GK:%7Z>s8W,trVliss8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2or
+rVc`nr;8`CO$5hLAS(-2#D)sWA,lTj:/4ti;Oo0aZ#OgZ*?C^O!,_i><s&OQ['[@Cs8W#pr;Zfs
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*c6@B+GMJ[;(+!@0U!)?d(FFo+6!!$J:@d-*@_#OIG
+(DfF/o'cVYs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8)Ths8W+RL6_f>6PgW,BPQuN(RYC/9)nqkL5)6!!(IqLSSN*5"pp,Q6?rP1rVlfr
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2lprr<#t6puhO*MR\!q]-`K!!$a6!(SUm3coJ:$4Mi6FS[I;WrN-:
+!s;^0"=pjd\c;^0qYL'gs8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An7"U8-c1V."(k6D9E
+!!#6@MNV(DP6(i<CMWD_,GG/<7XBB;s8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]rH?thV!)5("Y\S%F!!%:57<ee3r's7k
+!!$"N/Zil-o`+u4It+Ess8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Nns8TI5bmOr2DK,;/3PGInE<#uA
+%1P"7G)-P9IplaI8kR>.!-/)@?iU0UZEgq=s8VrlqZ$Tqrr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rh-UAt:'>[HJX7)o9-BFthChVQrp$sb5-WbH28#mu=c!)0r6_#OH7r;?Kms8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VWZmM$@(
+!!$Xu7)i;1huEa[K7fcqs83001&q;c3B=i]?fqCh?%%*ds8W,qqYU9krr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+r;?CW6'=l6do]f2!!@ZO!Fu01/Pf/G8P5-s0",P2mg9DV!<Hj6!'3eI>Q=a'r;?Klrr2orrr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*c6@/nBMJ[8'+!R?X!)ZZnE4rs,!!$Iu8^(%1f)Peh
+%Ltqtna?GWs8N#srr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,hnaR%t:&k9:?!cJS5K3['>J%MgrVcU&%8$U#C.q@K9MNt9!+*4H`W,u<
+r;?Kms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,qqYU<ms*fEo&e^@KFScjlQN.#$!!#/i?tY+EXpYYqG'<a0-DphDC]FH2
+&eZ\\m-F]Os8N#srr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An7"pS6d1V."(k6D9E
+!!#-LR\Gb!VuQg-AnLBj3kPFm=\22(s8W#rrr;usrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inr;Zfs\$s*P!)*k5N+ltm*Zq'\#?(<jp$_A=
+$49Z2!-VXTiB06>#RG,8oC`.`s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL-is8R+\YX(V#;,YmD!-/&><sAjY
+G'/i](lVg0k=J7k!!%'@!+5d,-F0q_s8W,rqu$Kos8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rh-V>pU+?=2bZ6cT0,BFk_Ahr!-'(0V4\O_\b'*$1UM!(DEgNrT.ZqYL'gs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#W_
+!!#P=.]dN*o`,&E5X9Yqs8Rh.OT5AE$4DSuAEbKlYQb;1nF5lGs8W&rrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o^q_m)Kf4fj#/m+!!$O0!)E_#3=#q/92*]AAEX4&K`V<h!!#)S9O%Pss8N#srr2orrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*d6@K7KMf!D(+!@3V!)cKaC@L]["U/?d0!f,#l3%<B
+!!#[$\%Mb@s8;fmrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2rts85DYDu]lF4[6nk?fV1e@![-ds8W+EH&Ve(6PL?$BkcrD&!9.EIfKHI
+rr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8Vrlr;ZfsEcS3@3Q,3/i!^*Q!!79C!.$t!aDPnf'Gco5!,DQ78J)O]
+m-O*=s8W)trr2orrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An8"pS?m34rX-jou'@
+!!#*LR\6+<Z2al*;cMCC:=9+BCCUh;naZ#Hs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#unaZ#V%7L6sG$%r+5t&fp!+<.>_Z0Z9
+IX[[b!(eIaVf$JK!!%=nI&R)Fs8)Ths8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,rqu-Qps0]8[$4DGn?fu0>nQK2Y
+@V"_;B^Zr^T)\k1!WlC)"!b1[[K$:,r;?Kms8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL-is8Re+W;lp4?t&+Z5/R@#BF>21qu#u3H`$iDD.RDK1,ZN@!*;``CB+>2rr2rsrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;?Tps0oJO
+!!#b#$]/J.lm!dS"p\6#nac_[s$fIm!!$.W1:(\/mJm6$I!_Ufs8Vrlqu6Tos8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr2rts%?"D!!$[S+eh(]^,J*e&/($)!ce8@<!*4P['[FEs8W#pr;Zfsrr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2orrr2oss8W*c6@o[XP&G=3)B5.G!)Q9[@/'Ee%hDkY(7K#ToGAI5
+!!#97J;XC,s8)Tgs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!qYL'gs8RV"O8o8M,q#U-Dt3r3KL/"Ss8W,gnEg\p3rf7n4?gMa>MfD\?A4*,
+s8W,qqYU<ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oss8V]^omM7b$k-GB!)3Fn:&k8`!<G+c#r&]l\,ZL.
+qYL'gs8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,sr;?Tps1,\W!!$%f7*8e>huEe%
+!!#R']u9[>q#^_,1GlUL@H@UpHiO.7[^N^Gs8W#pr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W!g8T=_1?9:?c?t&*r!+^P-V#UJp
+mHs<Q&5N9+D,!jW7Rt`-#&<Mkn,NFfrVc`qs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#urr2opr;HZqs6T+?
+L5).HJ"(n9QA($Rm-O$;s8W#pr;Zfsrr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qtp<ks8R:eQiI,(Bkcul27W\eA.fMEs8W%RLo::R?<ULg7nCi(!+lr\8b;QDs8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,XI
+%1P`+!,tt@g.=r_!!#lKK:;i?s6&S0$O]i4!-VURjuY]@#7"`/o(;t^s8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#urr2onqY^?lrr<#urr2orrr2rts8N#sr;?Kms8W)trr2ors8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2orrr<#unaZ/]&7He-UMF];&JL6+!(D$QLB%;REcR`O!-;jhm4U/s
+!!#c>H'\L1s82]krr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#sr;?Kms8TX?^&S.,$42AuB'^imX9Ac4kND+0s8Rb*NrT/C$4DW!AEbNmXp,,7
+o()AOs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#us8W,trVlZiqtg0dqYL*cqYL0hrVuot
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;HZqs1#S]!!$P-;:eWAeGoSi
+!!#9r]YFLHrsT<?)BGDbD=S>TOoPJML5)#os8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Tgs8W+LJ;XC-6QmYICM`PN%ZV&2<:B;D
+s8W+JIZOO05nk&uBP6ZJ)4:sE;tT_Ps8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2or
+rr2rts8PGRF9;YtDf,+o-`-kD?4ml4rr2c*]#F^M=$Agc>?g%d!-ASV;![H5s8W,trVlfqrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjr;Zfs
+I!hC`!)ba7\7]I?!!$e\HD1B=s8W-!J:O'g!(S1VT5SZA!!%OlFe\p9s8)Tirr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W&rrr<#um-F!C#[B,?\79+9#muFf!(2*[NW9%YH[D%Y!*ru>j?c8T
+!!$OE'h@lenGiOgrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8VWZmh6@*!!$_'9$U@7g&M+PJ:Npbs8W-!s*B!Y!!#bF/Zs#1oDel2
+I=8!ms8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2ooqu$Kos*fEk!!$_A@H9[>`W-!Q
+%LteilKJ9Js$T8&!<[siC@3GtW;lokH?teTs8Vrlqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,hnaR%t:]LK=?XMnX5/R@#=1GcU
+s8W,gnEgo(5QCdm1,HCLAa9<rAq5E,s8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2or
+s8W,joCEJ'=r&!ED/Jh^)O^X+;+=#[s8W,hnaQhh<$<KbBkm&H&WHbj5DFoTs8W,qqYL6ls8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inr;Zfs
+\$s$N!)*e1MJ$Sg+<dKb#[-]fo)JainF5iU%R:!oANW/l>$Bha!*4T!OoPI]qYL*hs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2inr;Zfs\@BT[!+/;hcW+$&!!%0B!(jT+^An65[C*pQ!+J5]b#MKu
+!!%!I$UsCIkPtS^rVc]orr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,qqYL6ls+#W[!!#G5-DYHpo*c%d&.hV+nF$>Vs7#OH%Lu&1!,>,!cV@6b
+!!$E;\\nIIs8;fms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2onqYU<ms*&[X!!%(WD=T52Y5eQ/
+'bs(%m-F]Os*]<c!!$M?A*H0@_>jR@8P+%(s8N#ss8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2rts8>M\D#aQ>2E/-WAa9<rB6\Zl
+s8W,urr;NYnI5q(!!$q;<S9Z*b6A/ao()GQs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Doq
+s8W,dmI1PpBe1j?BPHlC%Z(/c8Ul5Qs8W-!s858RJHlI:CM`Ma,,,&;7Y$#Ns8W,qqYU9krr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+naYuV%Qj^kDGX-Y:f5aC!*4i/UAt8ns8W,blg+ue;?-]??XVtV4N%C-AFT*Zs8W,trVliss8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2flr;ZfsIXe$k!,?.YlU=:a!!$sI%n5dJkPtS^lK[[>#[K,>[qTXG
+#RcCf!Dp88^An65r;?Klrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,trVliss6T+>$kQYH#(UB%lSLK0#7G22m-juSrr<#uL51ij!'U`!M.^Me
+1,QNH$Y8i!oDejjrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oss8V]_ndc=:*ZgqpFSHjuSH&Xl
+7n@CnrVHQos+Q9)!!$>.=PZqTfDknj%1ktuna?GWs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqYL*hs8Rb,PQ1\R+!@+mDtOteSI#[%
+o'u2Jrr<#us+#WZ!!#=s&s$dAm3sKd#74T)o()h\s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]m
+s8W,/\]OmPBhM1I?<uIn$%N!U4GAQOs8W-!s8R:fUAt::DJei&3Of%h?:de.s8Vuqrr;usrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Th
+s8W+LJ=QZ?;)'l5EHCdQ"+ip2HN4$Dq>'sgs8RV$PlLeS(DrBPC[iJgU(.f=o^q_Ss8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2cjr;ZfsGB]VY!-rR)oeSD2!!$[I),0;[kPtS^oCMPa'4)UuS8`NC
+*?L^N!(MKhMuWhWqYL'gs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2ors8W,t7nR_#!+J5\`+3B@!!$Y\J#32Fs7Q'[s8W+LJsZN<8KAkA
+DK,@U$B0+OVuQesqYL-hrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oss8VENmLKqE/haPIDY+MSO8o8O
+H?tGJs8W)trp&b8"UJm%3PK'9lN@KH!!#Nt\%2P=s8;fmrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VWYljXIi!!%%=<7b)Kg&M+W
+K8-'!s8Vcbq#CBoJ:a6j!)+U_TlY;M!<e1)IB<JKs8)Tis8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqcKh
+s8W+PL8FqNAn,?4923e6!-J8A3k2]0s8W-!s8Re.VuQg/?XVqe:"'(BC_R^_oCMMPs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+s8W,io(!;(;ucuFA7aph6,a!6C@(<Us8W,pq>1-ks+#]k!!#e@.&V62q#CGIH[Vmns8Vrlr;Q]p
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2ors8W-!6:?G9&!D-ZqB[Ja!!$+k88eJ-rr2oss8Vs`7!Sb6Jo5Gq
+0f--9!)e)gRK*<eqtp<jrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W&rrr<#ulg3sF%Trr@KP>2i/M=:5$Y/buo`+skq>'mes8RV$S,`Oc
+.kIfFG5M=?I!gCBs8W,qqY^Bns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Kms8TX?_Z0[=6q#.,AEF.*K)bm@
+L51ums8W)ts75^L#mscY,c5U&o+i41!!#KCLmA#?s8)Ths8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYL6ls+Z>j!!#A&)4"rOoGo$J
+#RXf+nac_[s7uKes8W+LJtE#C;(aQ*FERBZ!.0*BWW3"uqYL-is8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqlTj
+s8W+CGb"g7F)>g`4?^=W!,2rU6KmXos8W-!s8TR<`W-!J6Uf+(?fM+eGmb'\lg!g9s8W&rrr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8RS!PlLeV,:0+'EVC%YPRnL/oCVVRs8VojqZ$TqJ:aHp!)tU*Y]Y*b!!%@nI]<AIs8)Ti
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2rts7,XN&JSq(-`V0*oG8=0!!#qf86c,os7uKfs8W+JJ"?W?AS,N=
+7n:Z$!,*)a8FuHBs8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8)Ths8W+LJt2lA;)'l5F`mEY!./m6V#UJpqYL-dqYU<ms+#]o
+!!#nM0X5\@q>^MBI"&'ps8Vrlr;Zfss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sr;?Nns8TU>bQ%WY<EIsV<SIKTFoVM6
+\@K?Rs8W#prVuor77_q7$&NS>oI;Dl!!#oCHBnO1s8)Thrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjr;ZfsH@24_!*;9H^hINN
+!!$e`JZ&PJs8)ThqYL*hs8RV$T)\jf/hjGMFnl";H[L:As8W,qqY^Bns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr2os
+s8W*d7!o:IMK<k6-nDA!!+Q]Z6LjU6s8W-!s8VWZnH]J,-nDE;DtO\UOoPJML5:uls8Vrlqu?]r
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8V]^mM$L)!!$e&8'>(?irB'eIt+0ls8Vrlqtg0ds8W+LJt)f@:b40#Fa!Z_!.90CWW3"u
+qYL-is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oqrVliss6K";#n(<+4ht`EljOAZ!!#T?JWTp3s7lBcs8W,0]#t'RCJ7IN
+='4;Z!-\h]8*fI's8W,trVc`prr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,hna?nt8H8a1<*.^L;V1sL<ecF%s8W,qqYU-cqu?]r
+J:a9k!)OsjWHNI]!!%OrIB!8Hs8)Tis8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqYL-is8RP!VZ6^=CMW?&6,`g(D[m=I
+lg![5s8Vojqu?]rGBfSW!,cRfm63hR!!$Cu9R-U;rr2osrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W&srr<#un*f]R&5iK0H"1CH
+5XEBn#\iYln,NFfrVc`lqYU<ms+#]k!!#e@-_tp-pAb5JH[Vsps8Vrlr;Zfss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr<#u
+lg4!J%qHq3Wc<(S(E&S?!*)N\?2ss)rVc`qs8V]^ne)[B'Gm*TE:bA#UAt9bJ:Na]s8Vrlqu6To
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts7,[N$P-AC#(gQ&lS13(#7G/7o(;t^s8N#sqYL*hs8RV$R/d4[+siq'Eqoe@L3e3I
+s8W,qqY^?lrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2onqY^Bns+H-'!!$J7?K"mafDkts!!#<p\\.tBs82]js8W,blg=r_A2,mL
+C2<5C$AJN]:q*sKs8W,sr;?Qnrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Kms8TX@]`8%-&e^=CD"8bpV$[]?o()DPs8W)trqcKg
+s8W+LJscT=9->@KE,t^V#)R_UXT/>#qYL-is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2orrVc`qs8GARKaS?NF`mO..B<FK>XqA)
+s8W&rrVlZiqu?]rKnlE'!*rc3hbmA(!!$sI&4Q-Zmf3=err2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Tgs8W+LJ;=1*66IGC
+D/T%`)4Cm?;"F/Fs8W,urr2cjqu?]rJ:a-g!(\1RS8E0<&.t'l7="q5rVlfrrr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inr;Zfs
+\@K]]!*r)bb[FuC#Rc:c!(2HpPQ1[_qYL*cqY^Bns)rU^!!%4[D=BPF\,ZM88P="%s82fps8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2cjqu?]rJqTTn!)4mmW,m(T"UKoN7XP18rr2osrr2onqYU<ms+#]d!!#J,*1(JXnf/[C
+#ms2nna6AVs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2orrr<#us$]D$"9jBrEV)1L[K$;?',=((lfnHLs8Dops8W,jo^`V-?l^>^
+EH:gn*1Hp.7Y$#Is8W,qqYL6ls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#]m!!#nS2R[XHoDel7I=J9ss8Vrlqu?]r
+qYL*hs8RV$PQ1\R)&e`UC[iMiUC%K6o(2DOs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr)fps8W,blg4rb@l?6WCi/YQ&WQhk9Rq_\
+s8W,qqYU3gr;Zfs\$s0R!*qfS`FWQA!sa;U!(XK,\c;^0r;?Klrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqYL-is8RCmS,`Ol
+4[-brBBoNtC4(N.s8W,qqY^?lrqcKgs8W+NKTZ<87M?N!C2<8`-)UtU=n;.Ss8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2cjr;Zfs
+IY"L!!-N$km6a:\!!%!K&4c$NkPtS^rVc`lqYU<ms*oNf!!$M<A*$9Tbl@`Z'c9U8oC;k\s8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#uoCMDb(d\3&CIUk=>$Kqc!+15+U&Y/mqYL*hs8VrlqZ$TqJ:N7P!'Li)NbE.p
+.4_P+$XN>ooDejjrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rVc`qs8VNTn-on?-Rc!8EV(%aQ2gnb7nHtcs8W)ts8N#srr2rts85;VJ-Q@5
+DfG>$0!50S;L*SSs8W,rqu$Hmrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,UI%1c)3!-2(@g/:l&!!$&SLn=YHs8)Th
+s8W,sr;?Tps1#YR!!#[s$AN8/l8:K0"q"r4o(;t^s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqlTjs8W+JJ>3)EC1(K3:/B7;!d4PE6+FG8
+s8W,sr;?Qnrr<#unaZ)S$<nl,XE/@Q'GZc2!(M^!Q2gmaqYL*hs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VW[ndQ14
+!!7LYB';HF`<6H\m-O3@s8W&rrr<#urr2oss8VWZndH(4!!7LYA`l3A`<HW^nF6&Ls8W&srr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts7,[N
+&.r:j*M7Frq&prV!!$"h87qo%rr)fprr2opr;HZqs1,_a!!$_)9@$gHhZ*Y#$Oo_olKJ9Js8Doq
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8Doqs8W,bm-P,h=p51cBkm)f/Zo<dA+K3_s8W,urr2rts8Drrs8W,fn*^Yr;ucoB
+>[?8W8'V>HDY!Aks8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#sr;?Nns8TU=bQ%WY:f>qL>MfD`I/j7@\@B?Ss8W#pr;Q]pqYL-is8R=gRfEG)
+Bkcs"6Grj(?qF%9s8W)trr;usrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vrlqu?]rL5;&o!(IqJRVcm5)]YFU$X</ko)Jai
+rr2oss8W)trr<#unaZ)Y&kr?+DGO-Z:f>sH!+`UNa8c2>r;?Kms8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr)fps8W*d7=PRMMK<n7.kI_$!+lr^6h0^7
+s8W,urr2orrr<#uoCMPc'j_UlQZ@-@,:'#a!(_WjOT5@\qYL*grr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#Wc
+!!#Y?.B.?.pC@gs&/8%6o^Vt]s8N#ss8W,urr2rts7,XJ%M2#.!,P%jaC&E<!!$AUJ!p?:s8)Th
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;?Tps1#VZ
+!!$=n7`]+OkQq]R!!#K<J<0a1s82]krr2orrr2rts6Ak9"pep#27R@9lj!lO!!,p*\A&"Cs8;fm
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!qYL*hs8RV$SH&Xe1GlI[FS5\7H$=P0s8W,qqY^?lrr<#urr2oss8V]^mM$L%
+!!$Uj34Nd?mJm6*I=S0os8Vrlr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2orrr2rts8PMWF92SoE,kG.3P,7kB+u1[m-X-=s8W&rrr<#uqYL*hs8Re.VuQg-
+>[?8_:XT4CD@R4EnaYuGs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Ths8W+LJtW/E<&m"PD/AV?!-*I<WW3"u
+qYL*hs8W-!s8N#sqYL*hs8RCmR/d4c0JTbRG52+<H@11@s8W,qqY^Bns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2lprr<#ulg*mC$=bkK\8H3S&JL<-!)%WaM?!VU
+qYL*grr2orrr2oss8W$b7!o"<Jo>Su0f$!6!*Vl`B`J,1rr2rsrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vrlqu?]r
+J:aEo!*2<L_.@6E!!$e`J>`GIs8)Thrr2oss8W-!s8)Ths8W+NKU`#B:*M!XEH:d\%$!YCI/j6G
+rr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2onqY^Bns*oTt
+!!$qNBBr#VaT)<`!!,3l\@;M<s8;fmrr2orrr2rts7,XL#Raf^.&q<,obA:-!!#KCLmA#?s8)Th
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,qqYU<ms+#]o!!$(e6cNVHkPtTnIY"?qs8Vrlqu?]rs8W,urr2cjqZ$Tq
+It*:T!(.P?Q"t4)+<[Eb$<$Ean,NFfrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2ors8W,bm-P5mA0N7qEc_!o*16d,<_#\hs8W,urr;usrr2orr;?Nns8TX@b5_NW
+8kdN8>MfD\G7+mRl07@1s8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL*hs8RV$U&Y0q6q#+)@d!dl@t0')
+s8W,qqYU<ms8W-!s8W,sr;?Tps1#YU!!#e$$\iA/lRt!##n:G:oCW(_s8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]rKSH<'!+B&8hc<e5!!@BE!(s`1^]4?6
+r;?Klrr2orrqlTjs8W+CGFSX5DJO(W4[?mb!+8AlGQ7^Brr2rsrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Th
+s8W+LJtrAH=@>Tu?sr*s!+UM0V#UJpqYL*hs8W-!s8W-!rr2oss8VW[ndQ14!!%:TA*--H`rlZ_
+m-O3@s8W&rrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oqrVlisr^0).
+$P&8@Fnm=2VZ6^,'c0.*naHMXs8N#srr2orrr2rts7>jR&J\[m*1:bdq&giR!!#Q?J<0a1s8)Th
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2cjqu?]rJ:aQs!*Vc\a^AK;!!$JXJY`>Gs8)Ths8W-!s8W-!s8Doq
+s8W,fn*UVq8cSj0;Gu%F=53cU>(qa's8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trqu]ls8W,/\]=aN?V*i8@:A4&$A&6X7"9`Gs8W,rqtpBlrr2orr;?Kms8TR;_Z0[C
+4[-eqAa'@)K)bmD[^WmKs8W#pr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#]t!!$7r9$LXIirB'g
+It=Eqs8Vrlqu?]rs8W-!s8W)trr<#uoCMGc(e"E)BKeYrA7as)!,-h2V>pSqqYL*hs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2ors8W-!77MP*#(gl8oeSJ7!!$XE'M.WYlMpna
+rVc`qs8W)trqcKgs8W+KJ"6Q>AR]3484h#*!,NDh:\42Js8W,urr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL-is8R@lT)\js9MNi=>MoJ]@"3a%s8W,qqYU<ms8W-!s8W,urr2cjr;ZfsH@2.]!)t[/[<$H_
+!!%=hH)1K?s8)Tirr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srVc`qs8VENm0F&0
+2`SEdD=7uHM?!WMJ:a*es8Vrlqu6Torr2orrr2ors8W,u77`1>$&ieBoI;Do!!#i@HB%t)s82]j
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#uoCMA`(IA*%D+m[O='+5Y!*t)*U&Y/mqYL*hs8W-!s8W-!
+s8W,qqYU<ms+#Wd!!#Y9,,&mlp(\F4%h`"7o'l\Zs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrqcKhs8W+JJZ8\MF_Y^Z6:8]l!-&M\8*]C&s8W,trVlfqrr2orrr2oss8V?JlN[]&
+0ep"MD=IuCM#[NT\[oZXs8W#pr;Zfss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,XH%1kc)!-(k5ePoT(
+!!$,NJtN)Cs8)Ths8W-!s8W-!s8N#sqYL*hs8Re.O8o8J%han:C@3Z*Xp58@o()DPs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,trVliss6f=E$k?ns-`M-,pD4^6!!$(j8R;Ars8N#t
+rr2orrr2orrqcKgs8W+RLo(.P?WgRg;H)3J!-&J[7e-!8s8W,urr2orrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8VWZmg]su!!%"><SLGNec5\MJ:a<ks8Vrlqu?]rs8W-!s8W-!s8Doqs8W,cm-G/n<r`5G
+@q+Rl8B_&6?FdYds8W,sr;?Qnrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqtp<ks8ROuUAt:.
+?t&(j:t5OIG5qY2\@B3Os8W#pr;Q]ps8W,urr2ors8W-!6q)M(!J,-+nhW/3!!$4m88A2)r;Q]q
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,hna?o!7K<F.=BXBV;:Y^I<If[js8W,qqYU<ms8W-!
+s8W-!s8W)trr<#unaYuU&3g-pDbEaJ>[6:h!*t)(RfEEfqYL*hs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrr<#unac5^&muXuS98uM,:'&b!*2T\BE/#2rVc`prr2orrr2orrVc`qs8VENklqGs
+,q,^3EV't^Q2gnWL5;5ss8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#unaZ)X&P)m%E*?K%
+;c;3I!*"K#R/d3dqYL*hs8W-!s8W-!s8W,urr2ors8W,s8PF"%!+.TAZuL*X!!%1fH_pcBs8)Ti
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;HZqs1#Sa!!$e3;:\uWhuEn.!!#d(\AJ:Gs8;fm
+rr2oss8W-!s8)Ths8W+RLn+MG>Yn8G>?p(d!-ek]9Bk^'s8W,urr2orrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts75aL%hhG5!,u+Gh,@5&!!#uKJt)f?s8)Ths8W-!s8W-!s8W-!s8W,qqYL6ls+#W\
+!!#S6,GK-rp(nO4%hi:@o^r1`s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2orrVc`qs8PGTJHuXA
+FER@//?8aNB,)4MnaZ&Is8W)trr2ors8W,urr2flr;ZfsGB]h_!-2jkmQEeL!!$@t9QpI9rr2os
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VWZljXId!!%(B=kZePec5\NJ:a?ls8Vrlqu?]r
+s8W-!s8W-!s8N#sr;?Kms8TR<]`8(0#n)T(C@*i8[g!(Jlg+!=s8W&rrr2ors8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2inrVuot\@BZ]!+JMkc"(AJ$4MUg!(MHgNrT.Zqtp9irr2rts8N#srr2oss8V]^oFM[H
+*$(VjEVU[uT)\j^J:N[[s8VrlqYpKns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2rts8>DYF8u;T
+='"'S<7h0N<e#^ms8W,qqYU<ms8W-!s8W-!s8W-!s8N#ss8W,hna6hs7fWO3=BO<W<SIKR>_\'1
+s8W,qqYU<ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oqrVliss$T;)"pfs'EqV1C[K$;?&emq)mHX`Os8Doq
+s8W-!s8W-!s8;fms8W,0\]=aN?9git@q4[(#CujT8%,n;s8W,sr;?Qnrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8)Ths8W+KJYrJJ>u4DK<`e)W!*t#&U&Y/mqYL*grr2rts8W-!s8W-!s8W)trr2os
+s8W!g961(5@66WdCi/P>!-*4,UAt8nqtp<jrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]ms8W,/\B+^N?pmH+
+B4pK;%Yt)b8Ul;Ts8W,qqYU9krr2ors8W,urr2flr;ZfsG^,VV!,6(XlpX@b!!$[J)G0PlnGiOg
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]rIXn*l!*Vobb[+W8!!$MYJYrJIs8)Th
+s8W-!s8W-!s8W-!s8W-!s8VrlqZ$TqJ:N[\!(eI_VfQnR(`/MM'OUJ'oDejjrr2orrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr2lprr<#u6q2V0#_mA?p,"Y8!!$[F'hn#^li7"brVc`prr2rts8W-!rr2oss8V]^o+DdF
+'Gm'TEV1P&VZ6]kH$YGLs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+5ot
+!!#t\5/:`AlMpp-77_S$s8Drrs8N#ss8W-!s8W-!s8W-!rr2opr;?Tps0fDK!!#[t$\i;.lT./C
+!!$<8]#XjNs8;fms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sr;?Nns8TU=a8c3I6:Jt.BBfj7LB%<GIt<g`s8Vrlqu6To
+rr2oss8W)trqu]ls8W,.\&/1G?9(*[BkZi=$AJN\9t7aKs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!qYL'gs8RV"NW9&O1GuRZEUsDCM$jb_naZ#Hs8W)trr<#us8W-!s8W-!s8W-!
+rr2oss8V]^nJ3!@!!$t6:XWKRiW&seG^5\Vs8Vunr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr2oss8W*f7XYCCKQ2#'
+2E8/G!+uoY9C;-4s8W,trVlfqrr<#us8W,urr2cjqu?]rIt*sg!+TJIj\/@p!!$jO)H-.snGiOg
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;fms8W,0]"n@H;^*H]F)q'i'Trk9?h3dZ
+s8W,urr2rts8W-!s8W-!s8W-!s8N#sqtp<ks8R@jOT5A[/hjVOEV'\NM\?n7naZ/Ls8W)trr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2opr;?Tps1#VX!!$4d5Jh2OmLKkd!!#ZBJsHB9s8)Thrr2orrr2rts8W-!rr2orrr<#ur^BA6
+#RZK/EqCn7X8i5sH$YSPs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+o()A]&75hWNG<;$+<dKb$=N5emf3=erVc`qs8W-!s8W-!s8W-!s8W-!s8;fms8W,/\\S7G;%+"q
+D/Jc!27<Jb?+IPfs8W,sr;?Qnrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2orqYL-is8R=gScAb4DK##.5JdC#D%7+GlK[R4s8W&rrr2or
+s8W-!s8W)trr2ors8W,`l0AQ[?na=CCMiPK%Z(/c;7O0Rs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,trVliss6oFC$OoZ/"bC9!l9.AH!!#iKL7J;Ds8)Thrr2oss8W-!s8W-!
+s8W,urr2orrr<#uoCMJd(/Fo1E_]K\?XVjn!,G%oDu]k;rr2rsrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W&rrr<#umI'EQ&o0!LZZ'jR
+&epK/!*)N\>6"X&rr2rsrr2orrr<#us8W,urr2cjqu?]rKnu].!+oG>hbm>&!!$pQ)HQG"nc/Xh
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr<#urC0D'!!$nB?/\RWe,TJN
+J:OBos8Vrlqu?]rs8W-!s8W-!s8W-!s8W,urr2flr;ZfsJ:a6j!*1KuXE/LX'Gd#B$ruQVkl:\_
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2ooqu$Kos*fHm!!$bDA*HQXci=)i!!,6m\@MY>s8;fmrr2oss8W-!s8W-!rr2orrr<#us$K5*
+"pTa"E:bk?Z2al$H$YYRs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+qYL*hs8RV"T`>'p7S([/@,q:fDad3Cs8W#rrr;usrr<#us8W-!s8W-!s8W-!s8W,trVliss6K"9
+$4Kl9#D6Z&l:+4a!!$,VM51+Ns8)Thrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2ors8W,ho(!>(@3-J`Ec_$t+J/W6<_#\ks8W)srVlfqrr2or
+s8W-!s8W)trr2ors8W,`l0AQ\>q@S3D/SqS%ugPh<Oo]Zs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trqcKgs8W+PL6hl?:GO`5E,b@T%>bH%:\!uDs8W,urr2rts8W-!
+s8W-!s8W-!s8N#srr2orrr<#us$oV'!!$Ot7`]:Xkl:^*77M_*s8N#ss8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inrVuot\@Kf`!,>D1fNVS9
+!!@NI!)0o4_#OH7r;?Klrr2rts8W-!s8W,urr2cjr;ZfsKnlT,!+K&5gf%/)!!%'O&kDH\mJm4d
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W&rrr<#ulg*pD$==ScQZ-m9
+*[%*U!*-M<_>jQ8r;?Klrr2rts8W-!s8W-!s8W-!s8N#sqYL*hs8Rh0S,`Ob+<dD!EqUOrTa(m.
+m-F!;s8W&rrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr<#us$K2%#RQ<-F8.7:XT/?5'Gj4.naHMXs8N#srr2oss8W-!s8N#srr2orrr<#us$T;,
+!sO9rE:bh=ZN'u.7n@(gs8Drrs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts7>jQ&f+OM"Fk)uks.SQ!!#fFJ<^*6s8)Thrr2oss8W-!s8W-!s8W-!s8W)trr2or
+s8W,`l0&Ka:B1HF@:A1i9[<\=>)%j,s8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8Doqs8W,blg5#eB0JQ!BP?]?%Yk#a8:Q2Rs8W,rqu$Hmrr<#u
+s8W-!s8W)trqu]ls8W,0\\8%D;)0o6Ci/_Q&<6_j;7O0Ss8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2onqY^Bns*8m^!!$D,=4pVTg&M+c8PF@.s8N#ss8N#s
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W'g8p(+6@m3/rBPHl7!,R+5W;lntqYL*hs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjr;ZfsJqU-(!-E'omliqP
+!!$aB%S5pOlMpnarVc`qs8W-!s8W-!rr2orrr2cjqu?]rH$YbV!+K2;iDNV+!!$pQ)HZFunGiOg
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL*hs8Rk2T)\jj
+3'+]fD!hH4KF/,[l07=0s8W)trr2ors8W-!s8W-!s8W-!s8W,urr2cjqu?]rJ:a?m!)Y-oWH37[
+!!@muGcC`Cs8)Tirr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,qqY^Bns*B!n&J::NG52pkQ2gnj*?d]@p%&._s8N#srr2oss8W-!s8N#srVc`qs8VKRlk'q=
+%M4_>E:Y\8Z2al&H?tbSs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr)fps8W,blg"f`=;MmCEH1Up,bb8=98A=hs8W,qqYU9krr<#us8W-!s8W-!s8W-!
+rr2onqYU<ms*oTb!!#P+)3\iOn00'P$kQV6oCDq]s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2rts8G>RM_Hru@q4U($%N!U9gD'HrVcTms8W)trr2or
+s8W,urr2rts7uKfs8W+LJsQH;<'<F^Bl!/F%>Xua9";FGs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*f7XtI=G\_$Z6UScl!+/5eDZBb8
+rr2rsrr2orrr<#us8W-!s8W)trr2orrVc`qs8>G[?2st&%1e>2C$I6%Z3q1FoCVSQs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#uo'u)P$!9hoeko>q
+!!%-A!Dj7;,4P*hs8W,trVccrs8N#srr2onqYU<ms6f=@&/.tB"+FlokXS.d!!$M"8TXq3s8N#s
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]r
+L5;],!+/>kcX1)@!!7HS%8#mOl2Ue`rVc`prr2rts8N#ss8W-!s8VrlqZ$Tq\@K!I!#tt?@1Np-
+D/JbY(nYkkW;lntqYL-hrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2ors8W,u77WD+7*SV.ec5\m!!HF)"!FnUZ2ak(qYL'aq>0saqu6Tos8W,rqtNfZC]FH?
+/1muDEVC:gR/d4b\@BKWs8W#prVlfqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2rts68e5#n(&^+es+"pDtHK!!#iHK:)]=s7uKfs8W,urr2orrr2or
+qtp9irr;ooqaEtG!!#"Z!c9)*TQPDR#766=KWb@Ts8)Tis8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqY^Bns*/gi.4hi7A*F%!IfKUZ!!>"Z"p_H?ZiC(*
+rVc]lqu$9cp;+Va4[30O!(R8"Jm`!H;,YsF!,4qpGQ7^BrVc`prr2orrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr<#us$]G&!!%:WB'MiUaoDEX
+&en%,md0uRs7lBbqYL'bqYL3jrr)fpp%@rM9i(fi+9MjX!!.148',1KkReGPl07R7s8W&rrr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sr;?Nns8T:-bTeF0
+D/]%[(6ee"B`SE9!sC:X!!u.f:Pt*jGBn]R));@#1B7DO!!.=(3Os3Qq&(-@!!#g)\]+UKs8;fn
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+r;?Kms8TU>a8c3H3]t2jB^?3@NW9&W9200uqtU3ks8N#sqtp9hrVNn,ZO%'U!<OMK#?Lm+C_IMF
+FEI.(/$D0&JH,ZLrr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,ioCWe4J6u^I6Uo/t!dObJAcW*<!X)$o!%IsK,6.]t!!#mt"(qZ=Hn[:]
+H@,QO4i%*u>YS%>s8W&srr2orrr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2orrVc`qs8PMWIfot-Ci&W"34f.kF8u;)7S$jAMMlt8JpD]j
+'Gr(u"s3gF3<KLj!!6m:#(fcPfP,'d#Rc-l]$:9Ts8;fnrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]ms8W,"XNMY,TlkSX3]t+Y#(ZaSDZBiL
+!<ls8#AO8BD?'`X%M=^l9$Vd2r]WN^!!$:t:4rH@qYgBlrr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]ms8W,/\]OmP><bEl
+Ci/_W(6ALuD#jZ-!!")@!#P\9*<6(%!X)I'"_7T7D[$K$8P76THiF6QKR/$Fs8W,qqY^Bns8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2os
+s8W*n:6ZhEVfHkU?<uJ7-`@LdM[0ZE$kA.<,G.=ka)c=pCMWDT(RkR5C4Lo8o^qeUs8W&rrVuot
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrr2ors8W$j:4WBFE+3AB?!lS"%>k,fD$1,W":/?:#\!c:B)hsM!<dZd*1^JHjDf26
+"p^)V8<!KEqYgBlrr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2orrqlTks8W,&YgO*uP!;4WBkd-QD";=Wm;$P.D/JuR?fiRYX8i6D
+4$JG:_pn_ds8)TirVc`qs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr)fpqu$=]8rEfUJo,>oAS13N,GYPOJH?"%
+!X*oX$AKZIU/+V7F`dIO8_+OhNdQ;Xo^qhVs8W)trr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqcKhs8W,-\'8`,XXl,r
+-7>T/*i'\nSf]/C(`Rp<CSeMMd/X.GrVc`lqYU9krr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrr)fp
+r;?I`98roOG>1faE,bSgC@#)*gg"+@CMN6UDtd..h]<o85<tOJ^XiGbs8)TirVc`qs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8W)trqu]mrr2opr;?<`q6I?JCi>qsJu[trmITrBrVc`qs8W#prVQKis8W,urr2orrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W&rrVuoto_%p(IAmnsHl!Zf,q$&U1r(t-_'gh<+<d(:6']$neGfLH
+rVc`lqY^?lrr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2rsrr2rts8;fnqYL-hrr2rts8N#srr2oss8W)trqcKh
+qu$Elrr2rts8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrqu]mr;?NjqtdY+c#7U%
+I"&MIGd)UGXl\[2q"adds8W#prVQKjs8W,urr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts8N#s
+rr2opr;HHfqtg0erVc`prr2orrr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8W)trqcKhrr2oss8W)trr<#us8W,urr2rts8;fnqtp?krr2rts8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trr2orqu$Egq>C*cr;$3eqYL-grVlfqrr<#u
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!~>
+Q
+cleartomark end end pagesave restore showpage
+%%PageTrailer
+%%Trailer
+%%Pages: 1
diff --git a/graphics/asymptote/examples/pipeintersection.asy b/graphics/asymptote/examples/pipeintersection.asy
new file mode 100644
index 0000000000..6b0388f137
--- /dev/null
+++ b/graphics/asymptote/examples/pipeintersection.asy
@@ -0,0 +1,13 @@
+import graph3;
+
+currentprojection=orthographic(5,4,2);
+
+size(12cm,0);
+
+real f(pair z) {return min(sqrt(1-z.x^2),sqrt(1-z.y^2));}
+
+surface s=surface(f,(0,0),(1,1),40,Spline);
+
+transform3 t=rotate(90,O,Z), t2=t*t, t3=t2*t, i=xscale3(-1)*zscale3(-1);
+draw(surface(s,t*s,t2*s,t3*s,i*s,i*t*s,i*t2*s,i*t3*s),blue,
+ render(compression=Low,closed=true,merge=true));
diff --git a/graphics/asymptote/examples/pipes.asy b/graphics/asymptote/examples/pipes.asy
new file mode 100644
index 0000000000..6b2025f6b3
--- /dev/null
+++ b/graphics/asymptote/examples/pipes.asy
@@ -0,0 +1,140 @@
+import solids;
+import tube;
+import graph3;
+import palette;
+size(8cm);
+
+currentprojection=perspective(
+camera=(13.3596389245356,8.01038090435314,14.4864483364785),
+up=(-0.0207054323419367,-0.00472438375047319,0.0236460907598947),
+target=(-1.06042550499095,2.68154529985845,0.795007562120261));
+
+defaultpen(fontsize(6pt));
+
+// draw coordinates and frames
+// axis1 is defined by z axis of TBase
+// axis2 is defined by z axis of TEnd
+void DrawFrame(transform3 TBase, transform3 TEnd, string s)
+{
+ triple p1,v1,p2,v2;
+ p1=TBase*O;
+ v1=TBase*Z-p1;
+ p2=TEnd*O;
+ v2=TEnd*Z-p2;
+ triple n=cross(v1,v2);
+
+ real[][] A=
+ {
+ {v1.x,-v2.x,-n.x},
+ {v1.y,-v2.y,-n.y},
+ {v1.z,-v2.z,-n.z}
+ };
+
+ triple vb=p2-p1;
+
+ real[] b={vb.x,vb.y,vb.z};
+
+ // Get the extention along vector v1 and v2,
+ // so, we can get the common normal between two axis
+ real[] x=solve(A,b);
+
+ real s1=x[0];
+ real s2=x[1];
+
+ // get foot of a perpendicular on both axies
+ triple foot1=p1+s1*v1;
+ triple foot2=p2+s2*v2;
+
+ // draw two axis
+ triple axis_a,axis_b;
+ axis_a=p1+s1*v1*1.5;
+ axis_b=p1-s1*v1*1.5;
+ draw(axis_a--axis_b);
+
+ axis_a=p2+s2*v2*1.5;
+ axis_b=p2-s2*v2*1.5;
+ draw(axis_a--axis_b);
+
+ // draw "a"(common normal)
+ draw(Label("$a_{"+s+"}$"),foot1--foot2,linewidth(1pt));
+
+ // draw the coordinates frame
+ triple dx,dy,dz,org;
+ real length=0.8;
+
+ org=foot1;
+ dx =length*unit(foot2-foot1); // define the x axis of the frame on "a"
+ dz =length*unit(v1); // define the z axis which is along axis1
+ dy =length*unit(cross(dz,dx));
+
+ draw(Label("$X_{"+s+"}$",1,align=-dy-dz),org--(org+dx),red+linewidth(1.5pt),
+ Arrow3(8));
+ draw(Label("$Y_{"+s+"}$",1,align=2dy-dz-dx),org--(org+dy),
+ green+linewidth(1.5pt), Arrow3(8));
+ draw(Label("$Z_{"+s+"}$",1,align=-2dx-dy),org--(org+dz),
+ blue+linewidth(1.5pt), Arrow3(8));
+
+ dot(Label("$O_{"+s+"}$",align =-dx-dz,black),org,black); // origin
+
+}
+
+void DrawLink(transform3 TBase, transform3 TEnd, pen objStyle,string s)
+{
+ real h=1;
+ real r=0.5;
+ path3 generator=(0.5*r,0,h)--(r,0,h)--(r,0,0)--(0.5*r,0,0);
+ revolution vase=revolution(O,generator,0,360);
+ surface objSurface=surface(vase);
+
+ render render=render(merge=true);
+
+ // draw two cylinders
+ draw(TBase*objSurface,objStyle,render);
+ draw(TEnd*shift((0,0,-h))*objSurface,objStyle,render);
+
+ // draw the link between two cylinders
+ triple pStart=TBase*(0.5*h*Z);
+ triple pEnd =TEnd*(-0.5*h*Z);
+ triple pControl1=0.25*(pEnd-pStart)+TBase*(0,0,h);
+ triple pControl2=-0.25*(pEnd-pStart)+TEnd*(0,0,-h);
+ path3 p=pStart..controls pControl1 and pControl2..pEnd;
+ draw(tube(p,scale(0.2)*unitsquare),objStyle,render);
+}
+
+// t1 and t2 define the starting frame and ending frame of the first link(i-1)
+transform3 t1=shift((0,0,1));
+transform3 t2=shift((0,0,-1))*rotate(-20,Y)*shift((0,3,2));
+// as, the two links were connected, so t2 is also the starting frame of link(i)
+// t3 defines the ending frame of link(i)
+transform3 t3=t2*rotate(40,Z)*shift((0,3,1.5))*rotate(-15,Y)*shift(-1.5*Z);
+
+// draw link(i-1)
+DrawLink(t1,t2,palegreen,"i-1");
+DrawFrame(t1,t2,"i-1");
+// draw link(i)
+DrawLink(t2,t3,lightmagenta,"i");
+DrawFrame(t2,t3,"i");
+
+
+// draw angle alpha, which is the angle between axis(i-1) and axis(i)
+triple p0=(0,0,-1);
+triple p1=(0,0,2.3);
+triple p2=shift((0,0,-1))*rotate(-20,Y)*(0,0,4);
+draw(p0--p2,cyan);
+draw("$\alpha_{i-1}$",arc(p0,p1,p2,Y,CW),ArcArrow3(3));
+
+
+// draw angle theta, which is the angle between a_i and a_{i-1}
+transform3 tx=shift((0,0,-1))*rotate(-20,Y)*shift((0,3,0));
+p0=tx*O;
+p1=tx*(0,3,0);
+p2=tx*rotate(40,Z)*(0,3,0);
+draw(p0--p1,cyan);
+draw(p0--p2,cyan);
+
+triple p1a=tx*(0,1.5,0);
+draw("$\theta_{i}$",arc(p0,p1a,p2),ArcArrow3(3));
+
+// draw d_{i-1}
+triple org_i =t2*shift((0,0,1.5))*O;
+draw(Label("$d_{i}$",0.13),p0--org_i,linewidth(1pt));
diff --git a/graphics/asymptote/examples/planeproject.asy b/graphics/asymptote/examples/planeproject.asy
new file mode 100644
index 0000000000..ab8980b613
--- /dev/null
+++ b/graphics/asymptote/examples/planeproject.asy
@@ -0,0 +1,18 @@
+import graph3;
+
+size3(200,IgnoreAspect);
+
+currentprojection=orthographic(4,6,3);
+
+real x(real t) {return 1+cos(2pi*t);}
+real y(real t) {return 1+sin(2pi*t);}
+real z(real t) {return t;}
+
+path3 p=graph(x,y,z,0,1,operator ..);
+
+draw(p,Arrow3);
+draw(planeproject(XY*unitsquare3)*p,red,Arrow3);
+draw(planeproject(YZ*unitsquare3)*p,green,Arrow3);
+draw(planeproject(ZX*unitsquare3)*p,blue,Arrow3);
+
+axes3("$x$","$y$","$z$");
diff --git a/graphics/asymptote/examples/polararea.asy b/graphics/asymptote/examples/polararea.asy
new file mode 100644
index 0000000000..15d42ffd00
--- /dev/null
+++ b/graphics/asymptote/examples/polararea.asy
@@ -0,0 +1,38 @@
+import math;
+import graph;
+
+size(0,150);
+
+real f(real t) {return 5+cos(10*t);}
+
+xaxis("$x$");
+yaxis("$y$");
+
+real theta1=pi/8;
+real theta2=pi/3;
+path k=graph(f,theta1,theta2,operator ..);
+real rmin=min(k).y;
+real rmax=max(k).y;
+draw((0,0)--rmax*expi(theta1),dotted);
+draw((0,0)--rmax*expi(theta2),dotted);
+
+path g=polargraph(f,theta1,theta2,operator ..);
+path h=(0,0)--g--cycle;
+fill(h,lightgray);
+draw(h);
+
+real thetamin=3*pi/10;
+real thetamax=2*pi/10;
+pair zmin=polar(f(thetamin),thetamin);
+pair zmax=polar(f(thetamax),thetamax);
+draw((0,0)--zmin,dotted+red);
+draw((0,0)--zmax,dotted+blue);
+
+draw("$\theta_*$",arc((0,0),0.5*rmin,0,degrees(thetamin)),red+fontsize(10pt),
+ PenMargins);
+draw("$\theta^*$",arc((0,0),0.5*rmax,0,degrees(thetamax)),blue+fontsize(10pt),
+ PenMargins);
+
+draw(arc((0,0),rmin,degrees(theta1),degrees(theta2)),red,PenMargins);
+draw(arc((0,0),rmax,degrees(theta1),degrees(theta2)),blue,PenMargins);
+
diff --git a/graphics/asymptote/examples/polarcircle.asy b/graphics/asymptote/examples/polarcircle.asy
new file mode 100644
index 0000000000..ce7ed94819
--- /dev/null
+++ b/graphics/asymptote/examples/polarcircle.asy
@@ -0,0 +1,30 @@
+import math;
+import graph;
+size(0,100);
+
+real f(real t) {return 2*cos(t);}
+pair F(real x) {return (x,f(x));}
+
+draw(polargraph(f,0,pi,operator ..));
+
+defaultpen(fontsize(10pt));
+
+xaxis("$x$");
+yaxis("$y$");
+
+real theta=radians(50);
+real r=f(theta);
+draw("$\theta$",arc((0,0),0.5,0,degrees(theta)),red,Arrow,PenMargins);
+
+pair z=polar(r,theta);
+draw(z--(z.x,0),dotted+red);
+draw((0,0)--(z.x,0),dotted+red);
+label("$r\cos\theta$",(0.5*z.x,0),0.5*S,red);
+label("$r\sin\theta$",(z.x,0.5*z.y),0.5*E,red);
+dot("$(x,y)$",z,N);
+draw("r",(0,0)--z,0.5*unit(z)*I,blue,Arrow,DotMargin);
+
+dot("$(a,0)$",(1,0),NE);
+dot("$(2a,0)$",(2,0),NE);
+
+
diff --git a/graphics/asymptote/examples/polardatagraph.asy b/graphics/asymptote/examples/polardatagraph.asy
new file mode 100644
index 0000000000..6bd646e8aa
--- /dev/null
+++ b/graphics/asymptote/examples/polardatagraph.asy
@@ -0,0 +1,17 @@
+import graph;
+
+size(100);
+
+int n=30;
+real minRadius=0.2;
+real angles[]=uniform(0,2pi,n);
+angles.delete(angles.length-1);
+
+real[] r=new real[n];
+for(int i=0; i < n; ++i)
+ r[i]=unitrand()*(1-minRadius)+minRadius;
+
+interpolate join=operator ..(operator tension(10,true));
+draw(join(polargraph(r,angles,join),cycle),dot(red));
+
+
diff --git a/graphics/asymptote/examples/poster.asy b/graphics/asymptote/examples/poster.asy
new file mode 100644
index 0000000000..cbcefc4bf6
--- /dev/null
+++ b/graphics/asymptote/examples/poster.asy
@@ -0,0 +1,33 @@
+orientation=Landscape;
+import slide;
+import graph;
+
+defaultpen(deepblue);
+pagenumberpen=invisible;
+
+real f(real x) {return (x != 0) ? x*sin(1/x) : 0;}
+pair F(real x) {return (x,f(x));}
+
+xaxis(background,grey);
+yaxis(background,-0.25,0.25,grey);
+real a=1.2/pi;
+draw(background,graph(background,f,-a,a,10000),grey);
+label(background,"$x\sin\frac{1}{x}$",F(0.92/pi),3SE,grey+fontsize(14pt));
+frame f=background.fit();
+box(f,RadialShade(yellow,0.6*yellow+red),above=false);
+background.erase();
+add(background,f);
+
+title("Young Researchers' Conference",align=3S,fontsize(48pt));
+center("University of Alberta, Edmonton, April 1--2, 2006");
+
+skip(4);
+
+center("A general conference for\\
+the mathematical and statistical sciences\\
+for graduate students, by graduate students.",fontsize(32pt));
+
+label("Registration and abstract submission online.",(0,-0.5));
+
+label("\tt http://www.pims.math.ca/science/2006/06yrc/",point(SW),2NE,
+ black+fontsize(18pt));
diff --git a/graphics/asymptote/examples/progrid.asy b/graphics/asymptote/examples/progrid.asy
new file mode 100644
index 0000000000..20400b7148
--- /dev/null
+++ b/graphics/asymptote/examples/progrid.asy
@@ -0,0 +1 @@
+label("$\displaystyle X_i = \sum_{j=1}^{N} a_{ij} f_j$");
diff --git a/graphics/asymptote/examples/projectelevation.asy b/graphics/asymptote/examples/projectelevation.asy
new file mode 100644
index 0000000000..6ffe512663
--- /dev/null
+++ b/graphics/asymptote/examples/projectelevation.asy
@@ -0,0 +1,17 @@
+import graph3;
+import grid3;
+import palette;
+
+currentprojection=orthographic(0.8,1,2);
+size(400,300,IgnoreAspect);
+
+real f(pair z) {return cos(2*pi*z.x)*sin(2*pi*z.y);}
+
+surface s=surface(f,(-1/2,-1/2),(1/2,1/2),50,Spline);
+
+surface S=planeproject(unitsquare3)*s;
+S.colors(palette(s.map(zpart),Rainbow()));
+draw(S,nolight);
+draw(s,lightgray+opacity(0.7));
+
+grid3(XYZgrid);
diff --git a/graphics/asymptote/examples/projectrevolution.asy b/graphics/asymptote/examples/projectrevolution.asy
new file mode 100644
index 0000000000..8bbe7f38c3
--- /dev/null
+++ b/graphics/asymptote/examples/projectrevolution.asy
@@ -0,0 +1,17 @@
+import solids;
+import palette;
+
+currentprojection=orthographic(20,0,3);
+
+size(400,300,IgnoreAspect);
+
+revolution r=revolution(graph(new triple(real x) {
+ return (x,0,sin(x)*exp(-x/2));},0,2pi,operator ..),axis=Z);
+surface s=surface(r);
+
+surface S=planeproject(shift(-Z)*unitsquare3)*s;
+S.colors(palette(s.map(zpart),Rainbow()));
+
+render render=render(compression=Low,merge=true);
+draw(S,render);
+draw(s,lightgray,render);
diff --git a/graphics/asymptote/examples/pseudosphere.asy b/graphics/asymptote/examples/pseudosphere.asy
new file mode 100644
index 0000000000..a740381ef0
--- /dev/null
+++ b/graphics/asymptote/examples/pseudosphere.asy
@@ -0,0 +1,33 @@
+// Pseudosphere:
+// x = a sin(u) cos(v);
+// y = a sin(u) sin(v);
+// z = a (ln(tg(u/2))+cos(u));
+
+import three;
+import solids;
+import graph3;
+import palette;
+
+triple pseudosphere(real x) {
+ return (sin(x),0,cos(x)+log(tan(x/2)));
+}
+
+size(20cm,IgnoreAspect);
+currentprojection=orthographic(160,40,100);
+currentlight=(50,50,50);
+
+path3 G=graph(pseudosphere,0.5pi,0.965pi,10,Spline);
+
+revolution r=revolution(O,G,Z);
+
+draw(r,1,longitudinalpen=nullpen);
+surface s=surface(r);
+s.colors(palette(s.map(zpart),Gradient(cyan+white+opacity(0.9),
+ magenta+white+opacity(0.9))));
+draw(s);
+
+draw(r,6,backpen=linetype("10 10",10),longitudinalpen=nullpen);
+
+int n=10;
+for(int i=0; i < n; ++i)
+ draw(rotate(i*360/n,O,Z)*G);
diff --git a/graphics/asymptote/examples/quilt.asy b/graphics/asymptote/examples/quilt.asy
new file mode 100644
index 0000000000..7a84017762
--- /dev/null
+++ b/graphics/asymptote/examples/quilt.asy
@@ -0,0 +1,44 @@
+import math;
+
+int n=8, skip=3;
+
+pair r(int k) { return unityroot(n,k); }
+
+pen col=blue, col2=purple;
+
+guide square=box((1,1),(-1,-1));
+
+guide step(int mult)
+{
+ guide g;
+ for(int k=0; k<n; ++k)
+ g=g--r(mult*k);
+ g=g--cycle;
+ return g;
+}
+
+guide oct=step(1), star=step(skip);
+
+guide wedge(pair z, pair v, real r, real a)
+{
+ pair w=expi(a/2.0);
+ v=unit(v)*r;
+ return shift(z)*((0,0)--v*w--v*conj(w)--cycle);
+}
+
+filldraw(square, col);
+filldraw(oct, yellow);
+
+// The interior angle of the points of the star.
+real intang=pi*(1-((real)2skip)/((real)n));
+
+for(int k=0; k<n; ++k) {
+ pair z=midpoint(r(k)--r(k+1));
+ guide g=wedge(z,-z,1,intang);
+ filldraw(g,col2);
+}
+
+fill(star,yellow);
+filldraw(star,evenodd+col);
+
+size(5inch,0);
diff --git a/graphics/asymptote/examples/rainbow.asy b/graphics/asymptote/examples/rainbow.asy
new file mode 100644
index 0000000000..c85282a87b
--- /dev/null
+++ b/graphics/asymptote/examples/rainbow.asy
@@ -0,0 +1,12 @@
+size(200);
+
+pen indigo=rgb(102/255,0,238/255);
+
+void rainbow(path g) {
+ draw(new path[] {scale(1.3)*g,scale(1.2)*g,scale(1.1)*g,g,
+ scale(0.9)*g,scale(0.8)*g,scale(0.7)*g},
+ new pen[] {red,orange,yellow,green,blue,indigo,purple});
+}
+
+rainbow((1,0){N}..(0,1){W}..{S}(-1,0));
+rainbow(scale(4)*shift(-0.5,-0.5)*unitsquare);
diff --git a/graphics/asymptote/examples/randompath3.asy b/graphics/asymptote/examples/randompath3.asy
new file mode 100644
index 0000000000..b6666570b3
--- /dev/null
+++ b/graphics/asymptote/examples/randompath3.asy
@@ -0,0 +1,4 @@
+import three;
+
+size(300);
+draw(randompath3(100),red);
diff --git a/graphics/asymptote/examples/refs.bib b/graphics/asymptote/examples/refs.bib
new file mode 100644
index 0000000000..1c15d4e29b
--- /dev/null
+++ b/graphics/asymptote/examples/refs.bib
@@ -0,0 +1,55 @@
+@ARTICLE{Hobby86,
+ AUTHOR = "John D. Hobby",
+ TITLE = "Smooth, Easy to Compute Interpolating Splines",
+ JOURNAL = "Discrete Comput. Geom.",
+ YEAR = 1986,
+ VOLUME = 1,
+ PAGES = "123-140"}
+
+@BOOK{Knuth86b,
+ AUTHOR = "Donald E. Knuth",
+ TITLE = "The \MF{}book",
+ PUBLISHER = "Addison-Wesley",
+ YEAR = 1986,
+ ADDRESS = "Reading, Massachusetts"}
+
+@article{Bowman07,
+ title={{The 3D {A}symptote generalization of MetaPost B\'ezier interpolation}},
+ author={John C. Bowman},
+ journal={Proceedings in Applied Mathematics and Mechanics},
+ volume={7},
+ number={1},
+ pages={2010021-2010022},
+ year={2007}
+}
+
+@article{Bowman08,
+ title={Asymptote: A vector graphics language},
+ author={John C. Bowman and Andy Hammerlindl},
+ journal={TUGboat: The Communications of the \TeX\ Users Group},
+ volume={29},
+ number={2},
+ pages={288-294},
+ year={2008}
+}
+
+@article{Bowman09,
+ title={Asymptote: Lifting {\TeX} to three dimensions},
+ author={John C. Bowman and Orest Shardt},
+ journal={TUGboat: The Communications of the \TeX\ Users Group},
+ volume={30},
+ number={1},
+ pages={58-63},
+ year={2009}
+}
+
+@article{Shardt12,
+ title={Surface Parametrization of Nonsimply Connected Planar {B\'ezier} Regions},
+ author={Orest Shardt and John C. Bowman},
+ journal = {Computer-Aided Design},
+ volume={44},
+ number={5},
+ pages={484.e1-10},
+ year={2012},
+}
+
diff --git a/graphics/asymptote/examples/ring.asy b/graphics/asymptote/examples/ring.asy
new file mode 100644
index 0000000000..5fec60d4c0
--- /dev/null
+++ b/graphics/asymptote/examples/ring.asy
@@ -0,0 +1,4 @@
+size(0,100);
+path g=scale(2)*unitcircle;
+label("$a \le r \le b$");
+radialshade(unitcircle^^g,yellow+evenodd,(0,0),1.0,yellow+brown,(0,0),2);
diff --git a/graphics/asymptote/examples/roll.asy b/graphics/asymptote/examples/roll.asy
new file mode 100644
index 0000000000..4d15ac0feb
--- /dev/null
+++ b/graphics/asymptote/examples/roll.asy
@@ -0,0 +1,10 @@
+import graph3;
+
+size(200,0);
+
+triple f(pair t) {
+return(t.x+t.y/4+sin(t.y),cos(t.y),sin(t.y));
+}
+
+surface s=surface(f,(0,0),(2pi,2pi),7,20,Spline);
+draw(s,olive,render(merge=true));
diff --git a/graphics/asymptote/examples/roundpath.asy b/graphics/asymptote/examples/roundpath.asy
new file mode 100644
index 0000000000..e6d31c6bc9
--- /dev/null
+++ b/graphics/asymptote/examples/roundpath.asy
@@ -0,0 +1,32 @@
+// example file for 'roundedpath.asy'
+// written by stefan knorr
+
+// import needed packages
+import roundedpath;
+
+// define open and closed path
+path A = (0,0)--(10,10)--(30,10)--(20,0)--(30,-10)--(10,-10);
+path B = A--cycle;
+
+draw(shift(-60,0)*A, green);
+draw(shift(-30,0)*roundedpath(A,1), red);
+
+// draw open path and some modifications
+for (int i = 1; i < 20; ++i)
+ draw(roundedpath(A,i/4), rgb(1 - i*0.049, 0, i*0.049) + linewidth(0.5));
+
+draw(shift(-60,-30)*B, green);
+draw(shift(-30,-30)*roundedpath(B,1), red);
+
+//draw closed path and some modifications
+for (int i = 1; i < 20; ++i) // only round edges
+ draw(shift(0,-30)*roundedpath(B,i/4), rgb(0.5, i*0.049,0) + linewidth(0.5));
+
+for (int i = 1; i < 20; ++i) // round edged and scale
+ draw(shift(0,-60)*roundedpath(B,i/4,1-i/50), rgb(1, 1 - i*0.049,i*0.049) + linewidth(0.5));
+
+for (int i = 1; i < 50; ++i) // shift (round edged und scaled shifted version)
+ draw(shift(-30,-60)*shift(10,0)*roundedpath(shift(-10,0)*B,i/10,1-i/80), rgb( i*0.024, 1 - i*0.024,0) + linewidth(0.5));
+
+for (int i = 1; i < 20; ++i) // shift (round edged und scaled shifted version)
+ draw(shift(-60,-60)*shift(10,0)*roundedpath(shift(-10,0)*B,i/4,1-i/50), gray(i/40));
diff --git a/graphics/asymptote/examples/sacone.asy b/graphics/asymptote/examples/sacone.asy
new file mode 100644
index 0000000000..9cdd0e138a
--- /dev/null
+++ b/graphics/asymptote/examples/sacone.asy
@@ -0,0 +1,23 @@
+size(0,150);
+
+pair z0=(0,0);
+real r=1;
+real h=1;
+real l=sqrt(r^2+h^2);
+real a=(1-r/l)*360;
+real a1=a/2;
+real a2=360-a/2;
+path g=arc(z0,r,a1,a2);
+fill((0,0)--g--cycle,lightgreen);
+draw(g);
+pair z1=point(g,0);
+pair z2=point(g,length(g));
+
+real r2=1.1*r;
+path c=arc(0,r2,a1,a2);
+draw("$2\pi r$",c,red,Arrows,Bars,PenMargins);
+pen edge=blue+0.5mm;
+draw("$\ell$",z0--z1,0.5*SE,edge);
+draw(z0--z2,edge);
+draw(arc(z0,r,a2-360,a1),grey+dashed);
+dot(0);
diff --git a/graphics/asymptote/examples/sacone3D.asy b/graphics/asymptote/examples/sacone3D.asy
new file mode 100644
index 0000000000..d8f3aa373d
--- /dev/null
+++ b/graphics/asymptote/examples/sacone3D.asy
@@ -0,0 +1,14 @@
+import solids;
+
+size(0,75);
+real r=1;
+real h=1;
+
+revolution R=cone(r,h);
+
+draw(surface(R),lightgreen+opacity(0.5),render(compression=Low));
+pen edge=blue+0.25mm;
+draw("$\ell$",(0,r,0)--(0,0,h),W,edge);
+draw("$r$",(0,0,0)--(r,0,0),red+dashed);
+draw((0,0,0)--(0,0,h),red+dashed);
+dot(h*Z);
diff --git a/graphics/asymptote/examples/sacylinder.asy b/graphics/asymptote/examples/sacylinder.asy
new file mode 100644
index 0000000000..06f7909d52
--- /dev/null
+++ b/graphics/asymptote/examples/sacylinder.asy
@@ -0,0 +1,26 @@
+import graph;
+size(0,100);
+
+real r=1;
+real h=3;
+
+yaxis(dashed);
+
+real m=0.475*h;
+
+draw((r,0)--(r,h));
+label("$L$",(r,0.5*h),E);
+
+real s=4;
+
+pair z1=(s,0);
+pair z2=z1+(2*pi*r,h);
+filldraw(box(z1,z2),lightgreen);
+pair zm=0.5*(z1+z2);
+label("$L$",(z1.x,zm.y),W);
+label("$2\pi r$",(zm.x,z2.y),N);
+draw("$r$",(0,m)--(r,m),N,red,Arrows);
+
+draw((0,1.015h),yscale(0.5)*arc(0,0.25cm,-250,70),red,ArcArrow);
+
+
diff --git a/graphics/asymptote/examples/sacylinder3D.asy b/graphics/asymptote/examples/sacylinder3D.asy
new file mode 100644
index 0000000000..fcc1a487bb
--- /dev/null
+++ b/graphics/asymptote/examples/sacylinder3D.asy
@@ -0,0 +1,14 @@
+import solids;
+size(0,100);
+
+real r=1;
+real h=3;
+
+revolution R=cylinder(-h/2*Z,r,h);
+draw(surface(R),lightgreen+opacity(0.5),render(compression=Low));
+draw((0,0,-h/2)--(0,0,h/2),dashed);
+dot((0,0,-h/2));
+dot((0,0,h/2));
+draw("$L$",(0,r,-h/2)--(0,r,h/2),W,black);
+draw("$r$",(0,0,-h/2)--(0,r,-h/2),red);
+draw(arc(O,1,90,90,90,0),red,Arrow3);
diff --git a/graphics/asymptote/examples/shade.asy b/graphics/asymptote/examples/shade.asy
new file mode 100644
index 0000000000..889834585c
--- /dev/null
+++ b/graphics/asymptote/examples/shade.asy
@@ -0,0 +1,3 @@
+size(100,0);
+radialshade(unitsquare,yellow,(0,0),0,red,(0,0),1);
+
diff --git a/graphics/asymptote/examples/shadestroke.asy b/graphics/asymptote/examples/shadestroke.asy
new file mode 100644
index 0000000000..44f0b6e8a3
--- /dev/null
+++ b/graphics/asymptote/examples/shadestroke.asy
@@ -0,0 +1,5 @@
+size(100);
+
+radialshade(W..N..E--(0,0),stroke=true,
+ red+linewidth(30),(0,0),0.25,yellow,(0,0),1);
+
diff --git a/graphics/asymptote/examples/shellmethod.asy b/graphics/asymptote/examples/shellmethod.asy
new file mode 100644
index 0000000000..c8e541f2a6
--- /dev/null
+++ b/graphics/asymptote/examples/shellmethod.asy
@@ -0,0 +1,41 @@
+import graph3;
+import solids;
+
+size(400);
+currentprojection=perspective(0,-1,30,up=Y);
+currentlight=light(gray(0.75),(0.25,-0.25,1),(0,1,0));
+
+pen color=green;
+real alpha=240;
+
+real f(real x) {return 2x^2-x^3;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+int n=10;
+path3[] blocks=new path3[n];
+for(int i=1; i <= n; ++i) {
+ real height=f((i-0.5)*2/n);
+ real left=(i-1)*2/n;
+ real right=i*2/n;
+ blocks[i-1]=
+ (left,0,0)--(left,height,0)--(right,height,0)--(right,0,0)--cycle;
+}
+
+path p=graph(F,0,2,n,operator ..)--cycle;
+surface s=surface(p);
+path3 p3=path3(p);
+
+render render=render(compression=0,merge=true);
+
+revolution a=revolution(p3,Y,0,alpha);
+draw(surface(a),color,render);
+draw(rotate(alpha,Y)*s,color,render);
+for(int i=0; i < n; ++i)
+ draw(surface(blocks[i]),color+opacity(0.5),black,render);
+draw(p3);
+
+xaxis3(Label("$x$",1,align=2X),Arrow3);
+yaxis3(Label("$y$",1,align=2Y),ymax=1.4,dashed,Arrow3);
+arrow("$y=2x^2-x^3$",XYplane(F(1.8)),X+Z,1.5cm,red,Arrow3(DefaultHead2));
+draw(arc(1.17Y,0.3,90,0,7.5,180),ArcArrow3);
diff --git a/graphics/asymptote/examples/shellsqrtx01.asy b/graphics/asymptote/examples/shellsqrtx01.asy
new file mode 100644
index 0000000000..553200df14
--- /dev/null
+++ b/graphics/asymptote/examples/shellsqrtx01.asy
@@ -0,0 +1,36 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=orthographic(1,0,10,up=Y);
+pen color=green;
+real alpha=-240;
+
+real f(real x) {return sqrt(x);}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=30,operator ..)--(1,0)--cycle;
+path3 p3=path3(p);
+
+revolution a=revolution(p3,X,alpha,0);
+
+render render=render(compression=0,merge=true);
+draw(surface(a),color,render);
+draw(p3,blue);
+
+surface s=surface(p);
+draw(s,color,render);
+draw(rotate(alpha,X)*s,color,render);
+
+xaxis3(Label("$x$",1),xmax=1.25,dashed,Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+
+dot("$(1,1)$",(1,1,0));
+arrow("$y=\sqrt{x}$",F3(0.8),Y,0.75cm,red);
+
+real r=0.4;
+draw(F3(r)--(1,f(r),0),red);
+real x=(1+r)/2;
+
+draw("$r$",(x,0,0)--(x,f(r),0),X+0.2Z,red,Arrow3,PenMargin3);
+draw(arc(1.1X,0.4,90,90,3,-90),Arrow3);
diff --git a/graphics/asymptote/examples/sin1x.asy b/graphics/asymptote/examples/sin1x.asy
new file mode 100644
index 0000000000..637943691f
--- /dev/null
+++ b/graphics/asymptote/examples/sin1x.asy
@@ -0,0 +1,16 @@
+import graph;
+size(200,0);
+
+real f(real x) {return (x != 0) ? sin(1/x) : 0;}
+real T(real x) {return 2/(x*pi);}
+
+real a=-4/pi, b=4/pi;
+int n=150,m=5;
+
+xaxis("$x$",red);
+yaxis(red);
+
+draw(graph(f,a,-T(m),n)--graph(f,-m,-(m+n),n,T)--(0,f(0))--graph(f,m+n,m,n,T)--
+ graph(f,T(m),b,n));
+
+label("$\sin\frac{1}{x}$",(b,f(b)),SW);
diff --git a/graphics/asymptote/examples/sin3.asy b/graphics/asymptote/examples/sin3.asy
new file mode 100644
index 0000000000..76551dacb9
--- /dev/null
+++ b/graphics/asymptote/examples/sin3.asy
@@ -0,0 +1,22 @@
+import graph3;
+import palette;
+
+size(12cm,IgnoreAspect);
+currentprojection=orthographic(1,-2,1);
+
+real f(pair z) {return abs(sin(z));}
+
+real Arg(triple v) {return degrees(cos((v.x,v.y)),warn=false);}
+
+surface s=surface(f,(-pi,-2),(pi,2),20,Spline);
+
+s.colors(palette(s.map(Arg),Wheel()));
+draw(s,render(compression=Low,merge=true));
+
+real xmin=point((-1,-1,-1)).x;
+real xmax=point((1,1,1)).x;
+draw((xmin,0,0)--(xmax,0,0),dashed);
+
+xaxis3("$\mathop{\rm Re} z$",Bounds,InTicks);
+yaxis3("$\mathop{\rm Im} z$",Bounds,InTicks(beginlabel=false));
+zaxis3("$|\sin(z)|$",Bounds,InTicks);
diff --git a/graphics/asymptote/examples/sinc.asy b/graphics/asymptote/examples/sinc.asy
new file mode 100644
index 0000000000..352585bdbe
--- /dev/null
+++ b/graphics/asymptote/examples/sinc.asy
@@ -0,0 +1,24 @@
+import graph3;
+import contour;
+
+currentprojection=orthographic(1,-2,1);
+currentlight=White;
+
+size(12cm,0);
+
+real sinc(pair z) {
+ real r=2pi*abs(z);
+ return r != 0 ? sin(r)/r : 1;
+}
+
+render render=render(compression=Low,merge=true);
+
+draw(lift(sinc,contour(sinc,(-2,-2),(2,2),new real[] {0})),red);
+draw(surface(sinc,(-2,-2),(2,2),Spline),lightgray,render);
+
+draw(scale3(2*sqrt(2))*unitdisk,paleyellow+opacity(0.25),nolight,render);
+draw(scale3(2*sqrt(2))*unitcircle3,red,render);
+
+xaxis3("$x$",Bounds,InTicks);
+yaxis3("$y$",Bounds,InTicks(beginlabel=false));
+zaxis3("$z$",Bounds,InTicks);
diff --git a/graphics/asymptote/examples/sinxlex.asy b/graphics/asymptote/examples/sinxlex.asy
new file mode 100644
index 0000000000..912fa3c889
--- /dev/null
+++ b/graphics/asymptote/examples/sinxlex.asy
@@ -0,0 +1,24 @@
+import geometry;
+
+size(0,100);
+real theta=30;
+
+pair A=(0,0);
+pair B=dir(theta);
+pair C=(1,0);
+pair D=(1,Tan(theta));
+pair E=(Cos(theta),0);
+
+filldraw(A--C{N}..B--cycle,lightgrey);
+draw(B--C--D--cycle);
+draw(B--E);
+
+draw("$x$",arc(C,A,B,0.7),RightSide,Arrow,PenMargin);
+
+dot("$A$",A,W);
+dot("$B$",B,NW);
+dot("$C$",C);
+dot("$D$",D);
+dot(("$E$"),E,S);
+label("$1$",A--B,LeftSide);
+
diff --git a/graphics/asymptote/examples/slidedemo.asy b/graphics/asymptote/examples/slidedemo.asy
new file mode 100644
index 0000000000..0cbd15af74
--- /dev/null
+++ b/graphics/asymptote/examples/slidedemo.asy
@@ -0,0 +1,118 @@
+// Slide demo.
+// Command-line options to enable stepping and/or reverse video:
+// asy [-u stepping=true] [-u reverse=true] [-u itemstep=true] slidedemo
+
+orientation=Landscape;
+
+import slide;
+import three;
+
+viewportsize=pagewidth-2pagemargin;
+
+usersetting();
+
+// Commands to generate optional bibtex citations:
+// asy slidedemo
+// bibtex slidedemo_
+// asy slidedemo
+//
+bibliographystyle("alpha");
+
+// Generated needed files if they don't already exist.
+asy(nativeformat(),"Pythagoras","log","PythagoreanTree");
+usepackage("mflogo");
+
+// Optional background color or header:
+// import x11colors;
+// fill(background,box((-1,-1),(1,1)),Azure);
+// label(background,"Header",(0,startposition.y));
+
+titlepage(title="Slides with {\tt Asymptote}: A Demo",
+ author="John C. Bowman",
+ institution="University of Alberta",
+ date="\today",
+ url="http://asymptote.sf.net");
+
+outline("Basic Commands");
+item("item");
+subitem("subitem");
+remark("remark");
+item("draw \cite{Hobby86,Knuth86b}");
+item("figure");
+item("embedded and external animations: see {\tt slidemovie.asy}");
+
+title("Items");
+item("First item.");
+subitem("First subitem.");
+subitem("Second subitem.");
+item("Second item.");
+equation("a^2+b^2=c^2.");
+equations("\frac{\sin^2\theta+\cos^2\theta}{\cos^2\theta}
+&=&\frac{1}{\cos^2\theta}\nonumber\\
+&=&\sec^2\theta.");
+remark("A remark.");
+item("To enable pausing between bullets:");
+remark("{\tt asy -u stepping=true}");
+item("To enable reverse video:");
+remark("{\tt asy -u reverse=true}");
+
+title("Can draw on a slide, preserving the aspect ratio:");
+picture pic,pic2;
+draw(pic,unitcircle);
+add(pic.fit(15cm));
+step();
+fill(pic2,unitcircle,paleblue);
+label(pic2,"$\pi$",(0,0),fontsize(500pt));
+add(pic2.fit(15cm));
+
+newslide();
+item("The slide \Red{title} \Green{can} \Blue{be} omitted.");
+figure("Pythagoras","height=12cm",
+ "A simple proof of Pythagoras' Theorem.");
+
+newslide();
+item("Single skip:");
+skip();
+item("Double skip:");
+skip(2);
+figure(new string[] {"log."+nativeformat(),"PythagoreanTree."+nativeformat()},
+ "width=10cm",new string[] {"{\tt log.asy}","{\tt PythagoreanTree.asy}"},
+ "Examples of {\tt Asymptote} output.");
+
+title("Embedded Interactive 3D Graphics");
+picture pic;
+import graph3;
+import solids;
+viewportmargin=(0,1cm);
+currentprojection=orthographic(1,0,10,up=Y);
+pen color=green;
+real alpha=-240;
+real f(real x) {return sqrt(x);}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+path p=graph(pic,F,0,1,n=30,operator ..)--(1,0)--cycle;
+path3 p3=path3(p);
+revolution a=revolution(p3,X,alpha,0);
+render render=render(compression=0,merge=true);
+draw(pic,surface(a),color,render);
+draw(pic,p3,blue);
+surface s=surface(p);
+draw(pic,s,color,render);
+draw(pic,rotate(alpha,X)*s,color,render);
+xaxis3(pic,Label("$x$",1),xmax=1.25,dashed,Arrow3);
+yaxis3(pic,Label("$y$",1),Arrow3);
+dot(pic,"$(1,1)$",(1,1,0));
+arrow(pic,"$y=\sqrt{x}$",F3(0.8),Y,0.75cm,red);
+real r=0.4;
+draw(pic,F3(r)--(1,f(r),0),red);
+real x=(1+r)/2;
+draw(pic,"$r$",(x,0,0)--(x,f(r),0),X+0.2Z,red,Arrow3);
+draw(pic,arc(1.1X,0.4,90,90,3,-90),Arrow3);
+add(pic.fit(0,14cm));
+
+title("\mbox{Asymptote: 2D \& 3D Vector Graphics Language}");
+asyinclude("logo3");
+center("\tt http://asymptote.sf.net");
+center("(freely available under the LGPL license)");
+
+bibliography("refs");
diff --git a/graphics/asymptote/examples/slidedemo_.bbl b/graphics/asymptote/examples/slidedemo_.bbl
new file mode 100644
index 0000000000..73f4fc0bc7
--- /dev/null
+++ b/graphics/asymptote/examples/slidedemo_.bbl
@@ -0,0 +1,13 @@
+\begin{thebibliography}{Knu86}
+
+\bibitem[Hob86]{Hobby86}
+John~D. Hobby.
+\newblock Smooth, easy to compute interpolating splines.
+\newblock {\em Discrete Comput. Geom.}, 1:123--140, 1986.
+
+\bibitem[Knu86]{Knuth86b}
+Donald~E. Knuth.
+\newblock {\em The \MF{}book}.
+\newblock Addison-Wesley, Reading, Massachusetts, 1986.
+
+\end{thebibliography}
diff --git a/graphics/asymptote/examples/slope.asy b/graphics/asymptote/examples/slope.asy
new file mode 100644
index 0000000000..ae7fb45daf
--- /dev/null
+++ b/graphics/asymptote/examples/slope.asy
@@ -0,0 +1,83 @@
+import ode;
+import graph;
+import math;
+size(200,200,IgnoreAspect);
+
+real f(real t, real y) {return cos(y);}
+//real f(real t, real y) {return 1/(1+y);}
+typedef real function(real,real);
+
+real a=0;
+real b=1;
+real y0=0;
+
+real L[]={1,2};
+
+int M=L.length; // Number of modes.
+
+//real Y0[]=array(M,y0);
+real Y0[]=new real[] {-1,2};
+
+real[] F(real t, real[] y) {
+ return sequence(new real(int m) {return f(t,y[M-m-1]);},M);
+ // return new real[] {exp((L[1]-1)*t)*y[1],
+ // -exp(-(L[1]-1)*t)*y[0]};
+ // return new real[]{-y[0]^2};
+}
+
+real[] G(real t, real[] y) {
+ return F(t,y)-sequence(new real(int m) {return L[m]*y[m];},M);
+}
+
+real lambda=sqrt(0.5);
+real[] tau,error,error2;
+int n=25;
+
+real order=3;
+
+for(int i=0; i < n-1; ++i) {
+ real dt=(b-a)*lambda^(n-i);
+ Solution S=integrate(Y0,L,F,a,b,dt,dynamic=false,0.0002,0.0004,ERK3BS,verbose=false);
+ real maxnorm=0;
+
+ Solution E=integrate(Y0,G,a,b,1e-2*dt,dynamic=false,0.0002,0.0004,RK5);
+ real[] exact=E.y[E.y.length-1];
+
+ // real[] exact=new real[] {exp(-b)*sin(b),exp(-L[1]*b)*cos(b)};
+ for(int m=0; m < M; ++m)
+ maxnorm=max(maxnorm,abs(S.y[S.y.length-1][m]-exact[m]));
+ if(maxnorm != 0) {
+ tau.push(dt);
+ // error.push(dt^-(order+1)*maxnorm);
+ error.push(maxnorm);
+ }
+}
+
+/*
+for(int i=0; i < n-1; ++i) {
+ real dt=(b-a)*lambda^(n-i);
+ real maxnorm=0;
+ for(int m=0; m < M; ++m) {
+ solution S=integrate(Y0[m],L[m],f,a,b,dt,dynamic=false,0.000,1000,RK4_375,verbose=false);
+ maxnorm=max(maxnorm,abs(S.y[S.y.length-1]-exact[m]));
+ }
+ error2.push(dt^-order*maxnorm);
+}
+*/
+
+//scale(Log,Log);
+scale(Log,Linear);
+
+//draw(graph(tau,error),marker(scale(0.8mm)*unitcircle,red));
+//draw(graph(tau,error2),marker(scale(0.8mm)*unitcircle,blue));
+
+int[] index=sequence(error.length-1);
+real[] slope=log(error[index+1]/error[index])/log(tau[index+1]/tau[index]);
+real[] t=sqrt(tau[index]*tau[index+1]);
+//write(t,slope);
+draw(graph(t,slope),red);
+
+
+
+xaxis("$\tau$",BottomTop,LeftTicks);
+yaxis("$e/\tau^"+string(order)+"$",LeftRight,RightTicks);
diff --git a/graphics/asymptote/examples/smoothelevation.asy b/graphics/asymptote/examples/smoothelevation.asy
new file mode 100644
index 0000000000..a7995b7079
--- /dev/null
+++ b/graphics/asymptote/examples/smoothelevation.asy
@@ -0,0 +1,26 @@
+import graph3;
+import grid3;
+import palette;
+
+currentlight=Viewport;
+
+if(settings.render <= 0) settings.prc=false;
+
+currentprojection=orthographic(1,2,13);
+
+size(400,300,IgnoreAspect);
+
+real f(pair z) {return cos(2*pi*z.x)*sin(2*pi*z.y);}
+
+surface s=surface(f,(-1/2,-1/2),(1/2,1/2),20,Spline);
+s.colors(palette(s.map(zpart),Rainbow()));
+
+draw(s);
+
+scale(true);
+
+xaxis3(Label("$x$",0.5),Bounds,InTicks);
+yaxis3(Label("$y$",0.5),Bounds,InTicks);
+zaxis3(Label("$z$",0.5),Bounds,InTicks(beginlabel=false));
+
+grid3(XYZgrid);
diff --git a/graphics/asymptote/examples/soccerball.asy b/graphics/asymptote/examples/soccerball.asy
new file mode 100644
index 0000000000..5cf0f01505
--- /dev/null
+++ b/graphics/asymptote/examples/soccerball.asy
@@ -0,0 +1,90 @@
+import graph3;
+size(400);
+currentlight.background=palegreen;
+
+defaultrender=render(compression=Zero,merge=true);
+
+real c=(1+sqrt(5))/2;
+
+triple[] z={(c,1,0),(-c,1,0),(-c,-1,0),(c,-1,0)};
+triple[] x={(0,c,1),(0,-c,1),(0,-c,-1),(0,c,-1)};
+triple[] y={(1,0,c),(1,0,-c),(-1,0,-c),(-1,0,c)};
+
+triple[][] Q={
+ {z[0],y[1],x[3],x[0],y[0],z[3]},
+ {z[1],x[0],x[3],y[2],z[2],y[3]},
+ {z[2],z[1],y[2],x[2],x[1],y[3]},
+ {z[3],z[0],y[0],x[1],x[2],y[1]},
+ {x[0],x[3],z[1],y[3],y[0],z[0]},
+ {x[1],x[2],z[2],y[3],y[0],z[3]},
+ {x[2],x[1],z[3],y[1],y[2],z[2]},
+ {x[3],x[0],z[0],y[1],y[2],z[1]},
+ {y[0],y[3],x[1],z[3],z[0],x[0]},
+ {y[1],y[2],x[2],z[3],z[0],x[3]},
+ {y[2],y[1],x[3],z[1],z[2],x[2]},
+ {y[3],y[0],x[0],z[1],z[2],x[1]}
+};
+
+int nArc=4;
+
+path3 p=Arc(O,Q[0][0],Q[0][1],nArc);
+real R=abs(point(p,reltime(p,1/3)));
+
+triple[][] P;
+for(int i=0;i < Q.length;++i){
+ P[i]=new triple[] ;
+ for(int j=0;j < Q[i].length;++j){
+ P[i][j]=Q[i][j]/R;
+ }
+}
+
+// FIXME: Use a baryicentric coordinate mesh
+surface sphericaltriangle(triple center, triple A, triple B, triple C,
+ int nu=3, int nv=nu) {
+ path3 tri1=Arc(center,A,B,nArc);
+ path3 tri2=Arc(center,A,C,nArc);
+ path3 tri3=Arc(center,B,C,nArc);
+ triple tri(pair p) {
+ path3 cr=Arc(O,relpoint(tri2,p.x),relpoint(tri3,p.x),nArc);
+ return relpoint(cr,p.y);
+ };
+
+ return surface(tri,(0,0),(1-sqrtEpsilon,1),nu,nv,Spline);
+}
+
+for(int i=0;i < P.length;++i){
+ triple[] pentagon=sequence(new triple(int k) {
+ path3 p=Arc(O,P[i][0],P[i][k+1],nArc);
+ return point(p,reltime(p,1/3));
+ },5);
+ pentagon.cyclic=true;
+ draw(sequence(new path3(int k) {
+ return Arc(O,pentagon[k],pentagon[k+1],nArc);},5),linewidth(2pt));
+ triple M=unit(sum(pentagon)/5);
+ for(int i=0;i < 5;++i){
+ surface sf=sphericaltriangle(O,pentagon[i],M,pentagon[i+1]);
+ draw(sf,black);
+ }
+}
+
+for(int i=0;i < P.length;++i) {
+ for(int j=1;j <= 5;++j) {
+ triple K=P[i][0];
+ triple A=P[i][j];
+ triple B=P[i][(j % 5)+1];
+ path3[] p={Arc(O,K,A,nArc),Arc(O,A,B,nArc),Arc(O,B,K,nArc)};
+ draw(subpath(p[0],reltime(p[0],1/3),reltime(p[0],2/3)),linewidth(4pt));
+ triple[] hexagon={point(p[0],reltime(p[0],1/3)),
+ point(p[0],reltime(p[0],2/3)),
+ point(p[1],reltime(p[1],1/3)),
+ point(p[1],reltime(p[1],2/3)),
+ point(p[2],reltime(p[2],1/3)),
+ point(p[2],reltime(p[2],2/3))};
+ hexagon.cyclic=true;
+ triple M=unit(sum(hexagon)/6);
+ for(int i=0;i < 6;++i) {
+ surface sf=sphericaltriangle(O,hexagon[i],M,hexagon[i+1]);
+ draw(sf,white);
+ }
+ }
+}
diff --git a/graphics/asymptote/examples/spectrum.asy b/graphics/asymptote/examples/spectrum.asy
new file mode 100644
index 0000000000..a5d576921c
--- /dev/null
+++ b/graphics/asymptote/examples/spectrum.asy
@@ -0,0 +1,79 @@
+import graph;
+usepackage("ocg");
+settings.tex="pdflatex";
+
+// Dan Bruton algorithm
+pen nm2rgb(real wl, real gamma=0.8, bool intensity=true) {
+ triple rgb;
+ if(wl >= 380 && wl <= 440) {rgb=((440-wl)/60,0,1);}
+ if(wl > 440 && wl <= 490) {rgb=(0,(wl-440)/50,1);}
+ if(wl > 490 && wl <= 510) {rgb=(0,1,(510-wl)/20);}
+ if(wl > 510 && wl <= 580) {rgb=((wl-510)/70,1,0);}
+ if(wl > 580 && wl <= 645) {rgb=(1,(645-wl)/65,0);}
+ if(wl > 645 && wl <= 780) {rgb=(1,0,0);}
+
+ real Intensity=1;
+ if(intensity) {
+ if(wl >= 700) {Intensity=0.3+0.7*(780-wl)/80;}
+ else if(wl <= 420) {Intensity=0.3+0.7*(wl-380)/40;}
+ }
+
+ return rgb((Intensity*rgb.x)**gamma,(Intensity*rgb.y)**gamma,
+ (Intensity*rgb.z)**gamma);
+}
+
+real width=1;
+real height=50;
+
+begin("spectrum");
+for(real i=380 ; i <= 780 ; i += width) {
+ draw((i,0)--(i,height),width+nm2rgb(wl=i,false)+squarecap);
+}
+begin("Extinction",false); // nested
+for(real i=380 ; i <= 780 ; i += width) {
+ draw((i,0)--(i,height),width+nm2rgb(wl=i,true)+squarecap);
+}
+end();
+end();
+
+begin("Wavelength");
+xaxis(scale(0.5)*"$\lambda$(nm)",BottomTop,380,780,
+ RightTicks(scale(0.5)*rotate(90)*Label(),step=2,Step=10),above=true);
+end();
+
+// From Astronomical Data Center(NASA)
+// Neutral only
+real[] Na={423.899, 424.208, 427.364, 427.679, 428.784, 429.101,
+ 432.14, 432.462, 434.149, 434.474, 439.003, 439.334, 441.989, 442.325,
+ 449.418, 449.766, 454.163, 454.519, 568.2633, 568.8204, 588.995,
+ 589.5924};
+begin("Na absorption");
+for(int i=0; i < Na.length; ++i) {
+ draw((Na[i],0)--(Na[i],height),0.1*width+squarecap);
+}
+end();
+
+begin("Na emission");
+for(int i=0; i < Na.length; ++i) {
+ draw((Na[i],0)--(Na[i],-height),0.1*width+nm2rgb(Na[i],false)+squarecap);
+}
+end();
+
+// Neutral only
+real[] Zn={388.334, 396.543, 411.321, 429.288, 429.833, 462.981,
+ 468.014, 472.215, 481.053 , 506.866, 506.958, 518.198, 530.865,
+ 531.024, 531.102, 577.21, 577.55, 577.711, 623.79, 623.917, 636.234,
+ 647.918, 692.832, 693.847, 694.32, 779.936};
+begin("Zn absorption",false);
+for(int i=0; i < Zn.length; ++i) {
+ draw((Zn[i],0)--(Zn[i],height),width+squarecap);
+}
+end();
+
+begin("Zn emission",false);
+for(int i=0; i < Zn.length; ++i) {
+ draw((Zn[i],0)--(Zn[i],-height),width+nm2rgb(Zn[i],false)+squarecap);
+}
+end();
+
+shipout(bbox(2mm,Fill(white)));
diff --git a/graphics/asymptote/examples/sphere.asy b/graphics/asymptote/examples/sphere.asy
new file mode 100644
index 0000000000..8d1b5fe50c
--- /dev/null
+++ b/graphics/asymptote/examples/sphere.asy
@@ -0,0 +1,6 @@
+import three;
+
+size(200);
+currentprojection=orthographic(5,4,3);
+
+draw(unitsphere,green,render(compression=Zero,merge=true));
diff --git a/graphics/asymptote/examples/spheresilhouette.asy b/graphics/asymptote/examples/spheresilhouette.asy
new file mode 100644
index 0000000000..795efb0066
--- /dev/null
+++ b/graphics/asymptote/examples/spheresilhouette.asy
@@ -0,0 +1,9 @@
+import solids;
+settings.render=0;
+settings.prc=false;
+
+size(200);
+
+revolution r=sphere(O,1);
+draw(r,1,longitudinalpen=nullpen);
+draw(r.silhouette());
diff --git a/graphics/asymptote/examples/sphereskeleton.asy b/graphics/asymptote/examples/sphereskeleton.asy
new file mode 100644
index 0000000000..ca8b8c3d58
--- /dev/null
+++ b/graphics/asymptote/examples/sphereskeleton.asy
@@ -0,0 +1,9 @@
+size(100);
+import solids;
+
+currentprojection=orthographic(5,4,2);
+
+revolution sphere=sphere(1);
+draw(surface(sphere),green+opacity(0.2));
+draw(sphere,m=7,blue);
+
diff --git a/graphics/asymptote/examples/sphericalharmonic.asy b/graphics/asymptote/examples/sphericalharmonic.asy
new file mode 100644
index 0000000000..9fbb16f624
--- /dev/null
+++ b/graphics/asymptote/examples/sphericalharmonic.asy
@@ -0,0 +1,14 @@
+import graph3;
+import palette;
+size(200);
+
+currentprojection=orthographic(4,2,4);
+currentlight=Viewport;
+
+real r(real theta, real phi) {return 1+0.5*(sin(2*theta)*sin(2*phi))^2;}
+
+triple f(pair z) {return r(z.x,z.y)*expi(z.x,z.y);}
+
+surface s=surface(f,(0,0),(pi,2pi),50,Spline);
+s.colors(palette(s.map(abs),Gradient(yellow,red)));
+draw(s,render(compression=Low,merge=true));
diff --git a/graphics/asymptote/examples/spiral.asy b/graphics/asymptote/examples/spiral.asy
new file mode 100644
index 0000000000..a417ea06a7
--- /dev/null
+++ b/graphics/asymptote/examples/spiral.asy
@@ -0,0 +1,12 @@
+size(0,150);
+import graph;
+
+real f(real t) {return exp(-t/(2pi));}
+
+draw(polargraph(f,0,20*pi,operator ..));
+
+xaxis("$x$",-infinity,1.3);
+yaxis("$y$",-infinity,1);
+
+labelx(1);
+labelx("$e^{-1}$",1.0/exp(1),SE);
diff --git a/graphics/asymptote/examples/spiral3.asy b/graphics/asymptote/examples/spiral3.asy
new file mode 100644
index 0000000000..727ca3f6d3
--- /dev/null
+++ b/graphics/asymptote/examples/spiral3.asy
@@ -0,0 +1,20 @@
+import graph3;
+import palette;
+
+size3(10cm);
+
+currentprojection=orthographic(5,4,2);
+viewportmargin=(2cm,0);
+
+real r(real t) {return 3exp(-0.1*t);}
+real x(real t) {return r(t)*cos(t);}
+real y(real t) {return r(t)*sin(t);}
+real z(real t) {return t;}
+
+path3 p=graph(x,y,z,0,6*pi,50,operator ..);
+
+tube T=tube(p,2);
+surface s=T.s;
+s.colors(palette(s.map(zpart),BWRainbow()));
+draw(s,render(merge=true));
+draw(T.center,thin());
diff --git a/graphics/asymptote/examples/spline.asy b/graphics/asymptote/examples/spline.asy
new file mode 100644
index 0000000000..9d79ef3a96
--- /dev/null
+++ b/graphics/asymptote/examples/spline.asy
@@ -0,0 +1,25 @@
+import graph;
+import interpolate;
+
+size(15cm,15cm,IgnoreAspect);
+
+real a=1997, b=2002;
+int n=5;
+real[] xpt=a+sequence(n+1)*(b-a)/n;
+real[] ypt={31,36,26,22,21,24};
+horner h=diffdiv(xpt,ypt);
+fhorner L=fhorner(h);
+
+scale(false,true);
+
+pen p=linewidth(1);
+
+draw(graph(L,a,b),dashed+black+p,"Lagrange interpolation");
+draw(graph(xpt,ypt,Hermite(natural)),red+p,"natural spline");
+draw(graph(xpt,ypt,Hermite(monotonic)),blue+p,"monotone spline");
+xaxis("$x$",BottomTop,LeftTicks(Step=1,step=0.25));
+yaxis("$y$",LeftRight,RightTicks(Step=5));
+
+dot(pairs(xpt,ypt),4bp+gray(0.3));
+
+attach(legend(),point(10S),30S);
diff --git a/graphics/asymptote/examples/splitpatch.asy b/graphics/asymptote/examples/splitpatch.asy
new file mode 100644
index 0000000000..f8578bbbcc
--- /dev/null
+++ b/graphics/asymptote/examples/splitpatch.asy
@@ -0,0 +1,87 @@
+import three;
+
+size(300);
+
+// A structure to subdivide two intersecting patches about their intersection.
+struct split
+{
+ surface[] S={new surface};
+ surface[] T={new surface};
+
+ struct tree {
+ tree[] tree=new tree[2];
+ }
+ // Default subdivision depth.
+ int n=20;
+
+ // Subdivide p and q to depth n if they overlap.
+ void write(tree pt, tree qt, triple[][] p, triple[][] q, int depth=n) {
+ --depth;
+ triple[][][] Split(triple[][] P, real u=0)=depth % 2 == 0 ? hsplit : vsplit;
+ triple[][][] P=Split(p);
+ triple[][][] Q=Split(q);
+
+ for(int i=0; i < 2; ++i) {
+ triple[][] Pi=P[i];
+ for(int j=0; j < 2; ++j) {
+ triple[][] Qj=Q[j];
+ if(overlap(Pi,Qj)) {
+ if(!pt.tree.initialized(i))
+ pt.tree[i]=new tree;
+ if(!qt.tree.initialized(j))
+ qt.tree[j]=new tree;
+ if(depth > 0)
+ write(pt.tree[i],qt.tree[j],Pi,Qj,depth);
+ }
+ }
+ }
+ }
+
+ // Output the subpatches of p from subdivision.
+ void read(surface[] S, tree t, triple[][] p, int depth=n) {
+ --depth;
+ triple[][][] Split(triple[][] P, real u=0)=depth % 2 == 0 ? hsplit : vsplit;
+ triple[][][] P=Split(p);
+
+ for(int i=0; i < 2; ++i) {
+ if(t.tree.initialized(i))
+ read(S,t.tree[i],P[i],depth);
+ else {
+ S[0].push(patch(P[i]));
+ }
+ }
+ }
+
+ void operator init(triple[][] p, triple[][] q, int depth=n) {
+ tree ptrunk,qtrunk;
+ write(ptrunk,qtrunk,p,q,depth);
+ read(T,ptrunk,p,depth);
+ read(S,qtrunk,q,depth);
+ }
+}
+
+currentprojection=orthographic(0,0,1);
+
+triple[][] A={
+ {(0,0,0),(1,0,0),(1,0,0),(2,0,0)},
+ {(0,4/3,0),(2/3,4/3,2),(4/3,4/3,2),(2,4/3,0)},
+ {(0,2/3,0),(2/3,2/3,0),(4/3,2/3,0),(2,2/3,0)},
+ {(0,2,0),(2/3,2,0),(4/3,2,0),(2,2,0)}
+};
+
+triple[][] B={
+ {(0.5,0,-1),(0.5,1,-1),(0.5,2,-1),(0.5,3,-1)},
+ {(0.5,0,0),(0.5,1,0),(0.5,2,0),(0.5,3,0)},
+ {(0.5,0,1),(0.5,1,1),(0.5,2,1),(0.5,3,1)},
+ {(0.5,0,2),(0.5,1,2),(0.5,2,2),(0.5,3,2)}
+};
+
+split S=split(B,A);
+
+defaultrender.merge=true;
+
+for(int i=0; i < S.S[0].s.length; ++i)
+ draw(surface(S.S[0].s[i]),Pen(i));
+
+for(int i=0; i < S.T[0].s.length; ++i)
+ draw(surface(S.T[0].s[i]),Pen(i));
diff --git a/graphics/asymptote/examples/spring.asy b/graphics/asymptote/examples/spring.asy
new file mode 100644
index 0000000000..cbfb256eee
--- /dev/null
+++ b/graphics/asymptote/examples/spring.asy
@@ -0,0 +1,33 @@
+pair coilpoint(real lambda, real r, real t)
+{
+ return (2.0*lambda*t+r*cos(t),r*sin(t));
+}
+
+guide coil(guide g=nullpath, real lambda, real r, real a, real b, int n)
+{
+ real width=(b-a)/n;
+ for(int i=0; i <= n; ++i) {
+ real t=a+width*i;
+ g=g..coilpoint(lambda,r,t);
+ }
+ return g;
+}
+
+void drawspring(real x, string label) {
+ real r=8;
+ real t1=-pi;
+ real t2=10*pi;
+ real lambda=(t2-t1+x)/(t2-t1);
+ pair b=coilpoint(lambda,r,t1);
+ pair c=coilpoint(lambda,r,t2);
+ pair a=b-20;
+ pair d=c+20;
+
+ draw(a--b,BeginBar(2*barsize()));
+ draw(c--d);
+ draw(coil(lambda,r,t1,t2,100));
+ dot(d);
+
+ pair h=20*I;
+ draw(label,a-h--d-h,red,Arrow,Bars,PenMargin);
+}
diff --git a/graphics/asymptote/examples/spring0.asy b/graphics/asymptote/examples/spring0.asy
new file mode 100644
index 0000000000..fd6cdf8293
--- /dev/null
+++ b/graphics/asymptote/examples/spring0.asy
@@ -0,0 +1,4 @@
+import spring;
+
+drawspring(0,"$L$");
+
diff --git a/graphics/asymptote/examples/spring2.asy b/graphics/asymptote/examples/spring2.asy
new file mode 100644
index 0000000000..e3eec5f39f
--- /dev/null
+++ b/graphics/asymptote/examples/spring2.asy
@@ -0,0 +1,4 @@
+import spring;
+
+drawspring(40.0,"$L+x$");
+
diff --git a/graphics/asymptote/examples/sqrtx01.asy b/graphics/asymptote/examples/sqrtx01.asy
new file mode 100644
index 0000000000..4d2b0a45dc
--- /dev/null
+++ b/graphics/asymptote/examples/sqrtx01.asy
@@ -0,0 +1,25 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(1.5,0,10,Y);
+pen color=green+opacity(0.75);
+
+real f(real x){return sqrt(x);}
+pair F(real x){return (x,f(x));}
+triple F3(real x){return (x,f(x),0);}
+
+path p=graph(F,0,1,n=20,operator ..);
+path3 p3=path3(p);
+
+revolution a=revolution(p3,X,0,360);
+draw(surface(a),color,render(compression=Low,merge=true));
+draw(p3,blue);
+
+real x=relpoint(p,0.5).x;
+
+xaxis3(Label("$x$",1),xmax=1.5,dashed,Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+dot(Label("$(1,1)$"),(1,1,0));
+arrow(Label("$y=\sqrt{x}$"),F3(0.7),Y,0.75cm,red);
+draw(arc(1.2X,0.4,90,90,175,-40,CW),Arrow3);
+draw("$r$",(x,0,0)--F3(x),red,Arrow3,PenMargin3);
diff --git a/graphics/asymptote/examples/sqrtx01y1.asy b/graphics/asymptote/examples/sqrtx01y1.asy
new file mode 100644
index 0000000000..0bb7dd5216
--- /dev/null
+++ b/graphics/asymptote/examples/sqrtx01y1.asy
@@ -0,0 +1,22 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(0,1,10,up=Y);
+currentlight=White;
+
+real f(real x) {return sqrt(x);}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=25,operator ..);
+path3 p3=path3(p);
+
+revolution a=revolution(p3,Y,0,360);
+draw(surface(a),green,render(compression=Low,merge=true));
+draw(p3,blue);
+
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),ymax=1.5,dashed,Arrow3);
+dot(Label("$(1,1)$"),(1,1,0));
+arrow("$y=\sqrt{x}$",F3(0.5),X,0.75cm,red);
+draw(arc(1.2Y,0.3,90,0,7.5,140),Arrow3);
diff --git a/graphics/asymptote/examples/star.asy b/graphics/asymptote/examples/star.asy
new file mode 100644
index 0000000000..3a7afb2529
--- /dev/null
+++ b/graphics/asymptote/examples/star.asy
@@ -0,0 +1,13 @@
+size(100);
+import math;
+
+int n=5;
+path p;
+
+int i=0;
+do {
+ p=p--unityroot(n,i);
+ i=(i+2) % n;
+} while(i != 0);
+
+filldraw(p--cycle,red+evenodd);
diff --git a/graphics/asymptote/examples/stereoscopic.asy b/graphics/asymptote/examples/stereoscopic.asy
new file mode 100644
index 0000000000..639333ec47
--- /dev/null
+++ b/graphics/asymptote/examples/stereoscopic.asy
@@ -0,0 +1,11 @@
+import three;
+
+currentprojection=perspective(50*dir(70,15));
+
+picture pic;
+unitsize(pic,1cm);
+
+draw(pic,xscale3(10)*unitcube,yellow,blue);
+
+addStereoViews(pic);
+
diff --git a/graphics/asymptote/examples/stroke3.asy b/graphics/asymptote/examples/stroke3.asy
new file mode 100644
index 0000000000..75824d41dd
--- /dev/null
+++ b/graphics/asymptote/examples/stroke3.asy
@@ -0,0 +1,4 @@
+import three;
+size(5cm);
+
+draw(O--X,red+1cm,currentlight);
diff --git a/graphics/asymptote/examples/strokepath.asy b/graphics/asymptote/examples/strokepath.asy
new file mode 100644
index 0000000000..c857150ec5
--- /dev/null
+++ b/graphics/asymptote/examples/strokepath.asy
@@ -0,0 +1,17 @@
+path g=scale(100)*unitcircle;
+pen p=linewidth(1cm);
+
+frame f;
+// Equivalent to draw(f,g,p):
+fill(f,strokepath(g,p),red);
+shipout("strokepathframe",f);
+shipped=false;
+
+size(400);
+
+// Equivalent to draw(g,p):
+add(new void(frame f, transform t) {
+ fill(f,strokepath(t*g,p),red);
+ });
+currentpicture.addPath(g,p);
+
diff --git a/graphics/asymptote/examples/strokeshade.asy b/graphics/asymptote/examples/strokeshade.asy
new file mode 100644
index 0000000000..f9413091d1
--- /dev/null
+++ b/graphics/asymptote/examples/strokeshade.asy
@@ -0,0 +1,4 @@
+size(100);
+guide g=(0,0)..controls(70,30) and (-40,30)..(30,0);
+latticeshade(g,stroke=true,linewidth(10),
+ new pen[][] {{red,orange,yellow},{green,blue,purple}});
diff --git a/graphics/asymptote/examples/tanh.asy b/graphics/asymptote/examples/tanh.asy
new file mode 100644
index 0000000000..21d4decb1a
--- /dev/null
+++ b/graphics/asymptote/examples/tanh.asy
@@ -0,0 +1,13 @@
+import graph;
+size(100,0);
+
+real f(real x) {return tanh(x);}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$");
+yaxis("$y$");
+
+draw(graph(f,-2.5,2.5,operator ..));
+
+label("$\tanh x$",F(1.5),1.25*N);
+
diff --git a/graphics/asymptote/examples/teapot.asy b/graphics/asymptote/examples/teapot.asy
new file mode 100644
index 0000000000..bff93ace19
--- /dev/null
+++ b/graphics/asymptote/examples/teapot.asy
@@ -0,0 +1,172 @@
+import three;
+import settings;
+size(20cm);
+
+currentprojection=perspective(250,-250,250);
+currentlight=Viewport;
+
+triple[][][] Q={
+ {
+ {(39.68504,0,68.0315),(37.91339,0,71.75197),(40.74803,0,71.75197),(42.51969,0,68.0315)},
+ {(39.68504,-22.22362,68.0315),(37.91339,-21.2315,71.75197),(40.74803,-22.8189,71.75197),(42.51969,-23.81102,68.0315)},
+ {(22.22362,-39.68504,68.0315),(21.2315,-37.91339,71.75197),(22.8189,-40.74803,71.75197),(23.81102,-42.51969,68.0315)},
+ {(0,-39.68504,68.0315),(0,-37.91339,71.75197),(0,-40.74803,71.75197),(0,-42.51969,68.0315)}
+ },{
+ {(0,-39.68504,68.0315),(0,-37.91339,71.75197),(0,-40.74803,71.75197),(0,-42.51969,68.0315)},
+ {(-22.22362,-39.68504,68.0315),(-21.2315,-37.91339,71.75197),(-22.8189,-40.74803,71.75197),(-23.81102,-42.51969,68.0315)},
+ {(-39.68504,-22.22362,68.0315),(-37.91339,-21.2315,71.75197),(-40.74803,-22.8189,71.75197),(-42.51969,-23.81102,68.0315)},
+ {(-39.68504,0,68.0315),(-37.91339,0,71.75197),(-40.74803,0,71.75197),(-42.51969,0,68.0315)}
+ },{
+ {(-39.68504,0,68.0315),(-37.91339,0,71.75197),(-40.74803,0,71.75197),(-42.51969,0,68.0315)},
+ {(-39.68504,22.22362,68.0315),(-37.91339,21.2315,71.75197),(-40.74803,22.8189,71.75197),(-42.51969,23.81102,68.0315)},
+ {(-22.22362,39.68504,68.0315),(-21.2315,37.91339,71.75197),(-22.8189,40.74803,71.75197),(-23.81102,42.51969,68.0315)},
+ {(0,39.68504,68.0315),(0,37.91339,71.75197),(0,40.74803,71.75197),(0,42.51969,68.0315)}
+ },{
+ {(0,39.68504,68.0315),(0,37.91339,71.75197),(0,40.74803,71.75197),(0,42.51969,68.0315)},
+ {(22.22362,39.68504,68.0315),(21.2315,37.91339,71.75197),(22.8189,40.74803,71.75197),(23.81102,42.51969,68.0315)},
+ {(39.68504,22.22362,68.0315),(37.91339,21.2315,71.75197),(40.74803,22.8189,71.75197),(42.51969,23.81102,68.0315)},
+ {(39.68504,0,68.0315),(37.91339,0,71.75197),(40.74803,0,71.75197),(42.51969,0,68.0315)}
+ },{
+ {(42.51969,0,68.0315),(49.60629,0,53.1496),(56.69291,0,38.26771),(56.69291,0,25.51181)},
+ {(42.51969,-23.81102,68.0315),(49.60629,-27.77952,53.1496),(56.69291,-31.74803,38.26771),(56.69291,-31.74803,25.51181)},
+ {(23.81102,-42.51969,68.0315),(27.77952,-49.60629,53.1496),(31.74803,-56.69291,38.26771),(31.74803,-56.69291,25.51181)},
+ {(0,-42.51969,68.0315),(0,-49.60629,53.1496),(0,-56.69291,38.26771),(0,-56.69291,25.51181)}
+ },{
+ {(0,-42.51969,68.0315),(0,-49.60629,53.1496),(0,-56.69291,38.26771),(0,-56.69291,25.51181)},
+ {(-23.81102,-42.51969,68.0315),(-27.77952,-49.60629,53.1496),(-31.74803,-56.69291,38.26771),(-31.74803,-56.69291,25.51181)},
+ {(-42.51969,-23.81102,68.0315),(-49.60629,-27.77952,53.1496),(-56.69291,-31.74803,38.26771),(-56.69291,-31.74803,25.51181)},
+ {(-42.51969,0,68.0315),(-49.60629,0,53.1496),(-56.69291,0,38.26771),(-56.69291,0,25.51181)}
+ },{
+ {(-42.51969,0,68.0315),(-49.60629,0,53.1496),(-56.69291,0,38.26771),(-56.69291,0,25.51181)},
+ {(-42.51969,23.81102,68.0315),(-49.60629,27.77952,53.1496),(-56.69291,31.74803,38.26771),(-56.69291,31.74803,25.51181)},
+ {(-23.81102,42.51969,68.0315),(-27.77952,49.60629,53.1496),(-31.74803,56.69291,38.26771),(-31.74803,56.69291,25.51181)},
+ {(0,42.51969,68.0315),(0,49.60629,53.1496),(0,56.69291,38.26771),(0,56.69291,25.51181)}
+ },{
+ {(0,42.51969,68.0315),(0,49.60629,53.1496),(0,56.69291,38.26771),(0,56.69291,25.51181)},
+ {(23.81102,42.51969,68.0315),(27.77952,49.60629,53.1496),(31.74803,56.69291,38.26771),(31.74803,56.69291,25.51181)},
+ {(42.51969,23.81102,68.0315),(49.60629,27.77952,53.1496),(56.69291,31.74803,38.26771),(56.69291,31.74803,25.51181)},
+ {(42.51969,0,68.0315),(49.60629,0,53.1496),(56.69291,0,38.26771),(56.69291,0,25.51181)}
+ },{
+ {(56.69291,0,25.51181),(56.69291,0,12.7559),(42.51969,0,6.377957),(42.51969,0,4.251961)},
+ {(56.69291,-31.74803,25.51181),(56.69291,-31.74803,12.7559),(42.51969,-23.81102,6.377957),(42.51969,-23.81102,4.251961)},
+ {(31.74803,-56.69291,25.51181),(31.74803,-56.69291,12.7559),(23.81102,-42.51969,6.377957),(23.81102,-42.51969,4.251961)},
+ {(0,-56.69291,25.51181),(0,-56.69291,12.7559),(0,-42.51969,6.377957),(0,-42.51969,4.251961)}
+ },{
+ {(0,-56.69291,25.51181),(0,-56.69291,12.7559),(0,-42.51969,6.377957),(0,-42.51969,4.251961)},
+ {(-31.74803,-56.69291,25.51181),(-31.74803,-56.69291,12.7559),(-23.81102,-42.51969,6.377957),(-23.81102,-42.51969,4.251961)},
+ {(-56.69291,-31.74803,25.51181),(-56.69291,-31.74803,12.7559),(-42.51969,-23.81102,6.377957),(-42.51969,-23.81102,4.251961)},
+ {(-56.69291,0,25.51181),(-56.69291,0,12.7559),(-42.51969,0,6.377957),(-42.51969,0,4.251961)}
+ },{
+ {(-56.69291,0,25.51181),(-56.69291,0,12.7559),(-42.51969,0,6.377957),(-42.51969,0,4.251961)},
+ {(-56.69291,31.74803,25.51181),(-56.69291,31.74803,12.7559),(-42.51969,23.81102,6.377957),(-42.51969,23.81102,4.251961)},
+ {(-31.74803,56.69291,25.51181),(-31.74803,56.69291,12.7559),(-23.81102,42.51969,6.377957),(-23.81102,42.51969,4.251961)},
+ {(0,56.69291,25.51181),(0,56.69291,12.7559),(0,42.51969,6.377957),(0,42.51969,4.251961)}
+ },{
+ {(0,56.69291,25.51181),(0,56.69291,12.7559),(0,42.51969,6.377957),(0,42.51969,4.251961)},
+ {(31.74803,56.69291,25.51181),(31.74803,56.69291,12.7559),(23.81102,42.51969,6.377957),(23.81102,42.51969,4.251961)},
+ {(56.69291,31.74803,25.51181),(56.69291,31.74803,12.7559),(42.51969,23.81102,6.377957),(42.51969,23.81102,4.251961)},
+ {(56.69291,0,25.51181),(56.69291,0,12.7559),(42.51969,0,6.377957),(42.51969,0,4.251961)}
+ },{
+ {(-45.35433,0,57.40157),(-65.19685,0,57.40157),(-76.53543,0,57.40157),(-76.53543,0,51.02362)},
+ {(-45.35433,-8.503932,57.40157),(-65.19685,-8.503932,57.40157),(-76.53543,-8.503932,57.40157),(-76.53543,-8.503932,51.02362)},
+ {(-42.51969,-8.503932,63.77952),(-70.86614,-8.503932,63.77952),(-85.03937,-8.503932,63.77952),(-85.03937,-8.503932,51.02362)},
+ {(-42.51969,0,63.77952),(-70.86614,0,63.77952),(-85.03937,0,63.77952),(-85.03937,0,51.02362)}
+ },{
+ {(-42.51969,0,63.77952),(-70.86614,0,63.77952),(-85.03937,0,63.77952),(-85.03937,0,51.02362)},
+ {(-42.51969,8.503932,63.77952),(-70.86614,8.503932,63.77952),(-85.03937,8.503932,63.77952),(-85.03937,8.503932,51.02362)},
+ {(-45.35433,8.503932,57.40157),(-65.19685,8.503932,57.40157),(-76.53543,8.503932,57.40157),(-76.53543,8.503932,51.02362)},
+ {(-45.35433,0,57.40157),(-65.19685,0,57.40157),(-76.53543,0,57.40157),(-76.53543,0,51.02362)}
+ },{
+ {(-76.53543,0,51.02362),(-76.53543,0,44.64566),(-70.86614,0,31.88976),(-56.69291,0,25.51181)},
+ {(-76.53543,-8.503932,51.02362),(-76.53543,-8.503932,44.64566),(-70.86614,-8.503932,31.88976),(-56.69291,-8.503932,25.51181)},
+ {(-85.03937,-8.503932,51.02362),(-85.03937,-8.503932,38.26771),(-75.11811,-8.503932,26.5748),(-53.85826,-8.503932,17.00787)},
+ {(-85.03937,0,51.02362),(-85.03937,0,38.26771),(-75.11811,0,26.5748),(-53.85826,0,17.00787)}
+ },{
+ {(-85.03937,0,51.02362),(-85.03937,0,38.26771),(-75.11811,0,26.5748),(-53.85826,0,17.00787)},
+ {(-85.03937,8.503932,51.02362),(-85.03937,8.503932,38.26771),(-75.11811,8.503932,26.5748),(-53.85826,8.503932,17.00787)},
+ {(-76.53543,8.503932,51.02362),(-76.53543,8.503932,44.64566),(-70.86614,8.503932,31.88976),(-56.69291,8.503932,25.51181)},
+ {(-76.53543,0,51.02362),(-76.53543,0,44.64566),(-70.86614,0,31.88976),(-56.69291,0,25.51181)}
+ },{
+ {(48.18897,0,40.3937),(73.70078,0,40.3937),(65.19685,0,59.52755),(76.53543,0,68.0315)},
+ {(48.18897,-18.70866,40.3937),(73.70078,-18.70866,40.3937),(65.19685,-7.086619,59.52755),(76.53543,-7.086619,68.0315)},
+ {(48.18897,-18.70866,17.00787),(87.87401,-18.70866,23.38582),(68.0315,-7.086619,57.40157),(93.5433,-7.086619,68.0315)},
+ {(48.18897,0,17.00787),(87.87401,0,23.38582),(68.0315,0,57.40157),(93.5433,0,68.0315)}
+ },{
+ {(48.18897,0,17.00787),(87.87401,0,23.38582),(68.0315,0,57.40157),(93.5433,0,68.0315)},
+ {(48.18897,18.70866,17.00787),(87.87401,18.70866,23.38582),(68.0315,7.086619,57.40157),(93.5433,7.086619,68.0315)},
+ {(48.18897,18.70866,40.3937),(73.70078,18.70866,40.3937),(65.19685,7.086619,59.52755),(76.53543,7.086619,68.0315)},
+ {(48.18897,0,40.3937),(73.70078,0,40.3937),(65.19685,0,59.52755),(76.53543,0,68.0315)}
+ },{
+ {(76.53543,0,68.0315),(79.37007,0,70.15748),(82.20472,0,70.15748),(79.37007,0,68.0315)},
+ {(76.53543,-7.086619,68.0315),(79.37007,-7.086619,70.15748),(82.20472,-4.251961,70.15748),(79.37007,-4.251961,68.0315)},
+ {(93.5433,-7.086619,68.0315),(99.92125,-7.086619,70.68897),(97.79527,-4.251961,71.22047),(90.70866,-4.251961,68.0315)},
+ {(93.5433,0,68.0315),(99.92125,0,70.68897),(97.79527,0,71.22047),(90.70866,0,68.0315)}
+ },{
+ {(93.5433,0,68.0315),(99.92125,0,70.68897),(97.79527,0,71.22047),(90.70866,0,68.0315)},
+ {(93.5433,7.086619,68.0315),(99.92125,7.086619,70.68897),(97.79527,4.251961,71.22047),(90.70866,4.251961,68.0315)},
+ {(76.53543,7.086619,68.0315),(79.37007,7.086619,70.15748),(82.20472,4.251961,70.15748),(79.37007,4.251961,68.0315)},
+ {(76.53543,0,68.0315),(79.37007,0,70.15748),(82.20472,0,70.15748),(79.37007,0,68.0315)}
+ },{
+ {(0,0,89.29133),(22.67716,0,89.29133),(0,0,80.7874),(5.669294,0,76.53543)},
+ {(0,0,89.29133),(22.67716,-12.7559,89.29133),(0,0,80.7874),(5.669294,-3.174809,76.53543)},
+ {(0,0,89.29133),(12.7559,-22.67716,89.29133),(0,0,80.7874),(3.174809,-5.669294,76.53543)},
+ {(0,0,89.29133),(0,-22.67716,89.29133),(0,0,80.7874),(0,-5.669294,76.53543)}
+ },{
+ {(0,0,89.29133),(0,-22.67716,89.29133),(0,0,80.7874),(0,-5.669294,76.53543)},
+ {(0,0,89.29133),(-12.7559,-22.67716,89.29133),(0,0,80.7874),(-3.174809,-5.669294,76.53543)},
+ {(0,0,89.29133),(-22.67716,-12.7559,89.29133),(0,0,80.7874),(-5.669294,-3.174809,76.53543)},
+ {(0,0,89.29133),(-22.67716,0,89.29133),(0,0,80.7874),(-5.669294,0,76.53543)}
+ },{
+ {(0,0,89.29133),(-22.67716,0,89.29133),(0,0,80.7874),(-5.669294,0,76.53543)},
+ {(0,0,89.29133),(-22.67716,12.7559,89.29133),(0,0,80.7874),(-5.669294,3.174809,76.53543)},
+ {(0,0,89.29133),(-12.7559,22.67716,89.29133),(0,0,80.7874),(-3.174809,5.669294,76.53543)},
+ {(0,0,89.29133),(0,22.67716,89.29133),(0,0,80.7874),(0,5.669294,76.53543)}
+ },{
+ {(0,0,89.29133),(0,22.67716,89.29133),(0,0,80.7874),(0,5.669294,76.53543)},
+ {(0,0,89.29133),(12.7559,22.67716,89.29133),(0,0,80.7874),(3.174809,5.669294,76.53543)},
+ {(0,0,89.29133),(22.67716,12.7559,89.29133),(0,0,80.7874),(5.669294,3.174809,76.53543)},
+ {(0,0,89.29133),(22.67716,0,89.29133),(0,0,80.7874),(5.669294,0,76.53543)}
+ },{
+ {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)},
+ {(5.669294,-3.174809,76.53543),(11.33858,-6.349609,72.28346),(36.85039,-20.63622,72.28346),(36.85039,-20.63622,68.0315)},
+ {(3.174809,-5.669294,76.53543),(6.349609,-11.33858,72.28346),(20.63622,-36.85039,72.28346),(20.63622,-36.85039,68.0315)},
+ {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)}
+ },{
+ {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)},
+ {(-3.174809,-5.669294,76.53543),(-6.349609,-11.33858,72.28346),(-20.63622,-36.85039,72.28346),(-20.63622,-36.85039,68.0315)},
+ {(-5.669294,-3.174809,76.53543),(-11.33858,-6.349609,72.28346),(-36.85039,-20.63622,72.28346),(-36.85039,-20.63622,68.0315)},
+ {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
+ },{
+ {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
+ {(-5.669294,3.174809,76.53543),(-11.33858,6.349609,72.28346),(-36.85039,20.63622,72.28346),(-36.85039,20.63622,68.0315)},
+ {(-3.174809,5.669294,76.53543),(-6.349609,11.33858,72.28346),(-20.63622,36.85039,72.28346),(-20.63622,36.85039,68.0315)},
+ {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)}
+ },{
+ {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)},
+ {(3.174809,5.669294,76.53543),(6.349609,11.33858,72.28346),(20.63622,36.85039,72.28346),(20.63622,36.85039,68.0315)},
+ {(5.669294,3.174809,76.53543),(11.33858,6.349609,72.28346),(36.85039,20.63622,72.28346),(36.85039,20.63622,68.0315)},
+ {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)},
+ },{
+ {(0,0,0),(40.3937,0,0),(42.51969,0,2.12598),(42.51969,0,4.251961)},
+ {(0,0,0),(40.3937,22.62047,0),(42.51969,23.81102,2.12598),(42.51969,23.81102,4.251961)},
+ {(0,0,0),(22.62047,40.3937,0),(23.81102,42.51969,2.12598),(23.81102,42.51969,4.251961)},
+ {(0,0,0),(0,40.3937,0),(0,42.51969,2.12598),(0,42.51969,4.251961)}
+ },{
+ {(0,0,0),(0,40.3937,0),(0,42.51969,2.12598),(0,42.51969,4.251961)},
+ {(0,0,0),(-22.62047,40.3937,0),(-23.81102,42.51969,2.12598),(-23.81102,42.51969,4.251961)},
+ {(0,0,0),(-40.3937,22.62047,0),(-42.51969,23.81102,2.12598),(-42.51969,23.81102,4.251961)},
+ {(0,0,0),(-40.3937,0,0),(-42.51969,0,2.12598),(-42.51969,0,4.251961)}
+ },{
+ {(0,0,0),(-40.3937,0,0),(-42.51969,0,2.12598),(-42.51969,0,4.251961)},
+ {(0,0,0),(-40.3937,-22.62047,0),(-42.51969,-23.81102,2.12598),(-42.51969,-23.81102,4.251961)},
+ {(0,0,0),(-22.62047,-40.3937,0),(-23.81102,-42.51969,2.12598),(-23.81102,-42.51969,4.251961)},
+ {(0,0,0),(0,-40.3937,0),(0,-42.51969,2.12598),(0,-42.51969,4.251961)}
+ },{
+ {(0,0,0),(0,-40.3937,0),(0,-42.51969,2.12598),(0,-42.51969,4.251961)},
+ {(0,0,0),(22.62047,-40.3937,0),(23.81102,-42.51969,2.12598),(23.81102,-42.51969,4.251961)},
+ {(0,0,0),(40.3937,-22.62047,0),(42.51969,-23.81102,2.12598),(42.51969,-23.81102,4.251961)},
+ {(0,0,0),(40.3937,0,0),(42.51969,0,2.12598),(42.51969,0,4.251961)}
+ }
+};
+
+draw(surface(Q),material(blue, shininess=0.85, metallic=0),render(compression=Low));
diff --git a/graphics/asymptote/examples/tensor.asy b/graphics/asymptote/examples/tensor.asy
new file mode 100644
index 0000000000..19b1e08765
--- /dev/null
+++ b/graphics/asymptote/examples/tensor.asy
@@ -0,0 +1,9 @@
+size(200);
+
+pen[][] p={{red,green,blue,cyan},{blue,green,magenta,rgb(black)}};
+path G=(0,0){dir(-120)}..(1,0)..(1,1)..(0,1)..cycle;
+path[] g={G,subpath(G,2,1)..(2,0)..(2,1)..cycle};
+pair[][] z={{(0.5,0.5),(0.5,0.5),(0.5,0.5),(0.5,0.5)},{(2,0.5),(2,0.5),(1.5,0.5),(2,0.5)}};
+tensorshade(g,p,z);
+
+dot(g);
diff --git a/graphics/asymptote/examples/tetra.asy b/graphics/asymptote/examples/tetra.asy
new file mode 100644
index 0000000000..a20d27b8db
--- /dev/null
+++ b/graphics/asymptote/examples/tetra.asy
@@ -0,0 +1,12 @@
+import graph3;
+unitsize(1cm);
+currentprojection=orthographic(10,5,5);
+triple O=(0,0,0),N=(0,0,10),A=(8.66,0,-5), B=(-4.33,7.5,-5),C=(-4.33,-7.5,-5);
+path3[] D=N--A--B--C--N--B^^A--C;
+draw(surface(A--B--C--cycle),.5*blue+.5*white+opacity(.5));
+draw(surface(N--B--C--cycle),.5*green+.5*white+opacity(.5));
+draw(surface(N--C--A--cycle),.5*yellow+.5*white+opacity(.5));
+draw(surface(N--A--B--cycle),.5*red+.5*white+opacity(.5));
+draw(D,blue+1bp);
+dot(D);dot(O);
+label("$O$",O,E);label("$N$",N,N);label("$A$",A,SE);label("$B$",B,E);label("$C$",C,W+S);
diff --git a/graphics/asymptote/examples/textpath.asy b/graphics/asymptote/examples/textpath.asy
new file mode 100644
index 0000000000..1fc105364b
--- /dev/null
+++ b/graphics/asymptote/examples/textpath.asy
@@ -0,0 +1,10 @@
+size(300);
+
+fill(texpath(Label("test",TimesRoman())),pink);
+fill(texpath(Label("test",fontcommand('.fam T\n.ps 12')),tex=false),red);
+
+pair z=10S;
+
+fill(texpath(Label("$ \sqrt{x^2} $",z,TimesRoman())),pink);
+fill(texpath(Label("$ sqrt {x sup 2} $",z,fontcommand('.fam T\n.ps 12')),
+ tex=false),red);
diff --git a/graphics/asymptote/examples/thermodynamics.asy b/graphics/asymptote/examples/thermodynamics.asy
new file mode 100644
index 0000000000..cfcc3d0e98
--- /dev/null
+++ b/graphics/asymptote/examples/thermodynamics.asy
@@ -0,0 +1,131 @@
+// example file for roundedpath() in roundedpath.asy
+// written by stefan knorr
+
+
+// import needed packages
+import roundedpath;
+
+// function definition
+picture CreateKOOS(real Scale, string legend) // draw labeled coordinate system as picture
+{
+ picture ReturnPic;
+ real S = 1.2*Scale;
+ draw(ReturnPic, ((-S,0)--(S,0)), bar = EndArrow); // x axis
+ draw(ReturnPic, ((0,-S)--(0,S)), bar = EndArrow); // y axis
+ label(ReturnPic, "$\varepsilon$", (S,0), SW); // x axis label
+ label(ReturnPic, "$\sigma$", (0,S), SW); // y axis label
+ label(ReturnPic, legend, (0.7S, -S), NW); // add label 'legend'
+ return ReturnPic; // return picture
+}
+
+
+// some global definitions
+real S = 13mm; // universal scale factor for the whole file
+real grad = 0.25; // gradient for lines
+real radius = 0.04; // radius for the rounded path'
+real lw = 2; // linewidth
+pair A = (-1, -1); // start point for graphs
+pair E = ( 1, 1); // end point for graphs
+path graph; // local graph
+pen ActPen; // actual pen for each drawing
+picture T[]; // vector of all four diagrams
+real inc = 2.8; // increment-offset for combining pictures
+
+//////////////////////////////////////// 1st diagram
+T[1] = CreateKOOS(S, "$T_1$"); // initialise T[1] as empty diagram with label $T_1$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*1.6, A.y + 1.6); // #
+graph = graph -- (E.x - grad*0.4, E.y - 0.4); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0,0,0.6) + linewidth(lw); // define pen for drawing in 1st diagram
+draw(T[1], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[1]' (1st hysteresis branch)
+draw(T[1], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (2nd hysteresis branch)
+
+graph = (0,0) -- (grad*0.6, 0.6) -- ( (grad*0.6, 0.6) + (0.1, 0) ); // define branch from origin to hysteresis
+graph = roundedpath(graph, radius, S); // round this path
+draw(T[1], graph, ActPen); // draw this path into 'T[1]'
+
+
+//////////////////////////////////////// 2nd diagram
+T[2] = CreateKOOS(S, "$T_2$"); // initialise T[2] as empty diagram with label $T_2$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*1.3, A.y + 1.3); // #
+graph = graph -- (E.x - grad*0.7 , E.y - 0.7); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0.2,0,0.4) + linewidth(lw); // define pen for drawing in 2nd diagram
+draw(T[2], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[2]' (1st hysteresis branch)
+draw(T[2], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (2nd hysteresis branch)
+
+graph = (0,0) -- (grad*0.3, 0.3) -- ( (grad*0.3, 0.3) + (0.1, 0) ); // define branch from origin to hysteresis
+graph = roundedpath(graph, radius, S); // round this path
+draw(T[2], graph, ActPen); // draw this path into 'T[2]'
+
+
+//////////////////////////////////////// 3rd diagram
+T[3] = CreateKOOS(S, "$T_3$"); // initialise T[3] as empty diagram with label $T_3$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*0.7, A.y + 0.7); // #
+graph = graph -- ( - grad*0.3 , - 0.3); // #
+graph = graph -- (0,0); // #
+graph = graph -- (grad*0.6, 0.6); // #
+graph = graph -- (E.x - grad*0.4, E.y - 0.4); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0.6,0,0.2) + linewidth(lw); // define pen for drawing in 3rd diagram
+draw(T[3], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[3]' (1st hysteresis branch)
+draw(T[3], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (2nd hysteresis branch)
+
+
+//////////////////////////////////////// 4th diagram
+T[4] = CreateKOOS(S, "$T_4$"); // initialise T[4] as empty diagram with label $T_4$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*0.4, A.y + 0.4); // #
+graph = graph -- ( - grad*0.6 , - 0.6); // #
+graph = graph -- (0,0); // #
+graph = graph -- (grad*0.9, 0.9); // #
+graph = graph -- (E.x - grad*0.1, E.y - 0.1); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0.6,0,0) + linewidth(lw); // define pen for drawing in 4th diagram
+draw(T[4], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[4]' (1st hysteresis branch)
+draw(T[4], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (3nd hysteresis branch)
+
+
+// add some labels and black dots to the first two pictures
+pair SWW = (-0.8, -0.6);
+label(T[1], "$\sigma_f$", (0, 0.6S), NE); // sigma_f
+draw(T[1], (0, 0.6S), linewidth(3) + black);
+label(T[2], "$\sigma_f$", (0, 0.3S), NE); // sigma_f
+draw(T[2], (0, 0.3S), linewidth(3) + black);
+label(T[1], "$\varepsilon_p$", (0.7S, 0), SWW); // epsilon_p
+draw(T[1], (0.75S, 0), linewidth(3) + black);
+label(T[2], "$\varepsilon_p$", (0.7S, 0), SWW); // epsilon_p
+draw(T[2], (0.75S, 0), linewidth(3) + black);
+
+
+// add all pictures T[1...4] to the current one
+add(T[1],(0,0));
+add(T[2],(1*inc*S,0));
+add(T[3],(2*inc*S,0));
+add(T[4],(3*inc*S,0));
+
+
+// draw line of constant \sigma and all intersection points with the graphs in T[1...4]
+ActPen = linewidth(1) + dashed + gray(0.5); // pen definition
+draw((-S, 0.45*S)--((3*inc+1)*S, 0.45*S), ActPen); // draw backgoundline
+label("$\sigma_s$", (-S, 0.45S), W); // label 'sigma_s'
+
+path mark = scale(2)*unitcircle; // define mark-symbol to be used for intersections
+ActPen = linewidth(1) + gray(0.5); // define pen for intersection mark
+draw(shift(( 1 - grad*0.55 + 0*inc)*S, 0.45*S)*mark, ActPen); // # draw all intersections
+draw(shift((-1 + grad*1.45 + 0*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( 1 - grad*0.55 + 1*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( 1 - grad*0.55 + 2*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( grad*0.45 + 2*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( grad*0.45 + 3*inc)*S, 0.45*S)*mark, ActPen); // #
diff --git a/graphics/asymptote/examples/threeviews.asy b/graphics/asymptote/examples/threeviews.asy
new file mode 100644
index 0000000000..239a24cc28
--- /dev/null
+++ b/graphics/asymptote/examples/threeviews.asy
@@ -0,0 +1,26 @@
+import three;
+
+picture pic;
+unitsize(pic,5cm);
+
+if(settings.render < 0) settings.render=4;
+settings.toolbar=false;
+viewportmargin=(1cm,1cm);
+
+draw(pic,scale3(0.5)*unitsphere,green,render(compression=Low,merge=true));
+
+draw(pic,Label("$x$",1),O--X);
+draw(pic,Label("$y$",1),O--Y);
+draw(pic,Label("$z$",1),O--Z);
+
+// Europe and Asia:
+//addViews(pic,ThreeViewsFR);
+//addViews(pic,SixViewsFR);
+
+// United Kingdom, United States, Canada, and Australia:
+addViews(pic,ThreeViewsUS);
+//addViews(pic,SixViewsUS);
+
+// Front, Top, Right,
+// Back, Bottom, Left:
+//addViews(pic,SixViews);
diff --git a/graphics/asymptote/examples/torus.asy b/graphics/asymptote/examples/torus.asy
new file mode 100644
index 0000000000..d0b8673d73
--- /dev/null
+++ b/graphics/asymptote/examples/torus.asy
@@ -0,0 +1,20 @@
+size(200);
+import graph3;
+
+currentprojection=perspective(5,4,4);
+
+real R=3;
+real a=1;
+
+/*
+import solids;
+revolution torus=revolution(reverse(Circle(R*X,a,Y,32)),Z,90,345);
+surface s=surface(torus);
+*/
+
+triple f(pair t) {
+ return ((R+a*cos(t.y))*cos(t.x),(R+a*cos(t.y))*sin(t.x),a*sin(t.y));
+}
+
+surface s=surface(f,(radians(90),0),(radians(345),2pi),8,8,Spline);
+draw(s,green,render(compression=Low,merge=true));
diff --git a/graphics/asymptote/examples/transparency.asy b/graphics/asymptote/examples/transparency.asy
new file mode 100644
index 0000000000..36e741d294
--- /dev/null
+++ b/graphics/asymptote/examples/transparency.asy
@@ -0,0 +1,10 @@
+size(0,150);
+
+if(settings.outformat == "")
+ settings.outformat="pdf";
+
+begingroup();
+fill(shift(1.5dir(120))*unitcircle,green+opacity(0.75));
+fill(shift(1.5dir(60))*unitcircle,red+opacity(0.75));
+fill(unitcircle,blue+opacity(0.75));
+endgroup();
diff --git a/graphics/asymptote/examples/treetest.asy b/graphics/asymptote/examples/treetest.asy
new file mode 100644
index 0000000000..dbdf973c50
--- /dev/null
+++ b/graphics/asymptote/examples/treetest.asy
@@ -0,0 +1,22 @@
+import drawtree;
+
+treeLevelStep = 2cm;
+
+TreeNode root = makeNode( "Root" );
+TreeNode child1 = makeNode( root, "Child\_1" );
+TreeNode child2 = makeNode( root, "Child\_2" );
+
+TreeNode gchild1 = makeNode( child1, "Grandchild\_1" );
+TreeNode gchild2 = makeNode( child1, "Grandchild\_2" );
+
+TreeNode gchild3 = makeNode( child1, "Grandchild\_3" );
+TreeNode gchild4 = makeNode( child1, "Grandchild\_4" );
+
+
+TreeNode gchild11 = makeNode( child2, "Grandchild\_1" );
+TreeNode gchild22 = makeNode( child2, "Grandchild\_2" );
+
+TreeNode ggchild1 = makeNode( gchild1, "Great Grandchild\_1" );
+
+draw( root, (0,0) );
+
diff --git a/graphics/asymptote/examples/trefoilknot.asy b/graphics/asymptote/examples/trefoilknot.asy
new file mode 100644
index 0000000000..8ea5b264b4
--- /dev/null
+++ b/graphics/asymptote/examples/trefoilknot.asy
@@ -0,0 +1,23 @@
+import tube;
+import graph3;
+import palette;
+currentlight=White;
+
+size(0,8cm);
+currentprojection=perspective(1,1,1,up=-Y);
+
+int e=1;
+real x(real t) {return cos(t)+2*cos(2t);}
+real y(real t) {return sin(t)-2*sin(2t);}
+real z(real t) {return 2*e*sin(3t);}
+
+path3 p=scale3(2)*graph(x,y,z,0,2pi,50,operator ..)&cycle;
+
+pen[] pens=Gradient(6,red,blue,purple);
+pens.push(yellow);
+for (int i=pens.length-2; i >= 0 ; --i)
+ pens.push(pens[i]);
+
+path sec=scale(0.25)*texpath("$\pi$")[0];
+coloredpath colorsec=coloredpath(sec, pens,colortype=coloredNodes);
+draw(tube(p,colorsec),render(merge=true));
diff --git a/graphics/asymptote/examples/triads.asy b/graphics/asymptote/examples/triads.asy
new file mode 100644
index 0000000000..73088197e2
--- /dev/null
+++ b/graphics/asymptote/examples/triads.asy
@@ -0,0 +1,52 @@
+import graph;
+
+path p=(10,75)..(15,85)..(20,90)..(35,85)..(40,79)--(78,30)..(85,15)..(87,5);
+
+pair l=point(p,3.5);
+pair m=point(p,4.5);
+pair s=point(p,4.9);
+
+pen c=linewidth(1.5);
+pair o=(m.x,0.5(m.x+l.y));
+
+pen d=c+darkgreen;
+
+void drawarrow(string s="", pair p, pair q, side side=RightSide,
+ bool upscale=false, pen c)
+{
+ path g=p{dir(-5)}..{dir(-85)}q;
+ if(upscale) g=reverse(g);
+ draw(s,g,side,c,Arrow(Fill,0.65));
+}
+
+void spectrum(pair l,pair m, pair s) {
+ draw(p,c);
+
+ d += 4.0;
+ dot("$p$",l,SW,d);
+ dot("$q$",m,SW,d);
+ dot("$k$",s,SW,d);
+
+ xaxis("$k$",0);
+ yaxis("$E(k)$",0);
+}
+
+drawarrow("$T_p$",l,m,true,blue);
+drawarrow("$T_k$",m,s,LeftSide,red);
+spectrum(l,m,s);
+shipout("triadpqk");
+
+erase();
+
+drawarrow("$-T_p$",l,m,LeftSide,red);
+drawarrow("$-T_q$",m,s,true,blue);
+spectrum(l,s,m);
+shipout("triadpkq");
+
+erase();
+
+drawarrow("$T_k$",l,m,true,blue);
+drawarrow("$T_q$",m,s,LeftSide,red);
+spectrum(m,s,l);
+
+shipout("triadkpq");
diff --git a/graphics/asymptote/examples/triangle.asy b/graphics/asymptote/examples/triangle.asy
new file mode 100644
index 0000000000..60388a7851
--- /dev/null
+++ b/graphics/asymptote/examples/triangle.asy
@@ -0,0 +1,12 @@
+size(0,100);
+import geometry;
+
+triangle t=triangle(b=3,alpha=90,c=4);
+
+dot((0,0));
+
+draw(t);
+draw(rotate(90)*t,red);
+draw(shift((-4,0))*t,blue);
+draw(reflect((0,0),(1,0))*t,green);
+draw(slant(2)*t,magenta);
diff --git a/graphics/asymptote/examples/triangles.asy b/graphics/asymptote/examples/triangles.asy
new file mode 100644
index 0000000000..fc62c58c12
--- /dev/null
+++ b/graphics/asymptote/examples/triangles.asy
@@ -0,0 +1,20 @@
+import three;
+size(10cm);
+
+triple[] v={O,X,X+Y,Y};
+
+triple[] n={Z,X};
+
+int[][] vi={{0,1,2},{2,3,0}};
+int[][] ni={{0,0,0},{1,1,1}};
+
+// Adobe Reader exhibits a PRC rendering bug for opacities:
+pen[] p={red+opacity(0.5),green+opacity(0.5),blue+opacity(0.5),
+ black+opacity(0.5)};
+
+int[][] pi={{0,1,2},{2,3,0}};
+draw(v,vi,n,ni,red);
+draw(v+Z,vi,n,ni,p,pi);
+//draw(v+Z,vi,p,pi);
+//draw(v,vi,red);
+//draw(v+Z,vi);
diff --git a/graphics/asymptote/examples/triceratops.asy b/graphics/asymptote/examples/triceratops.asy
new file mode 100644
index 0000000000..a9e6e93cd5
--- /dev/null
+++ b/graphics/asymptote/examples/triceratops.asy
@@ -0,0 +1,9 @@
+import obj;
+
+size(15cm);
+currentprojection=orthographic(0,2,5,up=Y);
+
+// A compressed version of the required data file may be obtained from:
+// http://www.cs.technion.ac.il/~irit/data/Viewpoint/triceratops.obj.gz
+
+draw(obj("triceratops.obj",brown));
diff --git a/graphics/asymptote/examples/trumpet.asy b/graphics/asymptote/examples/trumpet.asy
new file mode 100644
index 0000000000..842af2b23c
--- /dev/null
+++ b/graphics/asymptote/examples/trumpet.asy
@@ -0,0 +1,12 @@
+import graph3;
+size(200,0);
+
+currentlight=Viewport;
+
+triple f(pair t) {
+ real u=log(abs(tan(t.y/2)));
+ return (10*sin(t.y),cos(t.x)*(cos(t.y)+u),sin(t.x)*(cos(t.y)+u));
+}
+
+surface s=surface(f,(0,pi/2),(2pi,pi-0.1),7,15,Spline);
+draw(s,olive+0.25*white,render(compression=Low,merge=true));
diff --git a/graphics/asymptote/examples/truncatedIcosahedron.asy b/graphics/asymptote/examples/truncatedIcosahedron.asy
new file mode 100644
index 0000000000..e4d07a49e5
--- /dev/null
+++ b/graphics/asymptote/examples/truncatedIcosahedron.asy
@@ -0,0 +1,68 @@
+import graph3;
+
+size(200);
+
+defaultrender.merge=true;
+
+real c=(1+sqrt(5))/2;
+
+triple[] z={(c,1,0),(-c,1,0),(-c,-1,0),(c,-1,0)};
+triple[] x={(0,c,1),(0,-c,1),(0,-c,-1),(0,c,-1)};
+triple[] y={(1,0,c),(1,0,-c),(-1,0,-c),(-1,0,c)};
+
+triple[][] Q={
+ {(c,1,0),(1,0,-c),(0,c,-1),(0,c,1),(1,0,c),(c,-1,0)},
+ {(-c,1,0),(0,c,1),(0,c,-1),(-1,0,-c),(-c,-1,0),(-1,0,c)},
+ {(-c,-1,0),(-c,1,0),(-1,0,-c),(0,-c,-1),(0,-c,1),(-1,0,c)},
+ {(c,-1,0),(c,1,0),(1,0,c),(0,-c,1),(0,-c,-1),(1,0,-c)},
+ {(0,c,1),(0,c,-1),(-c,1,0),(-1,0,c),(1,0,c),(c,1,0)},
+ {(0,-c,1),(0,-c,-1),(-c,-1,0),(-1,0,c),(1,0,c),(c,-1,0)},
+ {(0,-c,-1),(0,-c,1),(c,-1,0),(1,0,-c),(-1,0,-c),(-c,-1,0)},
+ {(0,c,-1),(0,c,1),(c,1,0),(1,0,-c),(-1,0,-c),(-c,1,0)},
+ {(1,0,c),(-1,0,c),(0,-c,1),(c,-1,0),(c,1,0),(0,c,1)},
+ {(1,0,-c),(-1,0,-c),(0,-c,-1),(c,-1,0),(c,1,0),(0,c,-1)},
+ {(-1,0,-c),(1,0,-c),(0,c,-1),(-c,1,0),(-c,-1,0),(0,-c,-1)},
+ {(-1,0,c),(1,0,c),(0,c,1),(-c,1,0),(-c,-1,0),(0,-c,1)}
+};
+
+real R=abs(interp(Q[0][0],Q[0][1],1/3));
+
+triple[][] P;
+for(int i=0; i < Q.length; ++i) {
+ P[i]=new triple[] ;
+ for(int j=0; j < Q[i].length; ++j) {
+ P[i][j]=Q[i][j]/R;
+ }
+}
+
+for(int i=0; i < P.length; ++i) {
+ for(int j=1; j < P[i].length; ++j) {
+ triple C=P[i][0];
+ triple A=P[i][j];
+ triple B=P[i][j % 5+1];
+ triple[] sixout=new
+ triple[] {interp(C,A,1/3),interp(C,A,2/3),interp(A,B,1/3),interp(A,B,2/3),
+ interp(B,C,1/3),interp(B,C,2/3)};
+ triple M=(sum(sixout))/6;
+ triple[] sixin=sequence(new triple(int k) {
+ return interp(sixout[k],M,0.1);
+ },6);
+ draw(surface(reverse(operator--(...sixout)--cycle)^^
+ operator--(...sixin)--cycle,planar=true),magenta);
+ }
+}
+
+for(int i=0; i < P.length; ++i) {
+ triple[] fiveout=sequence(new triple(int k) {
+ return interp(P[i][0],P[i][k+1],1/3);
+ },5);
+ triple M=(sum(fiveout))/5;
+ triple[] fivein=sequence(new triple(int k) {
+ return interp(fiveout[k],M,0.1);
+ },5);
+ draw(surface(reverse(operator--(...fiveout)--cycle)^^
+ operator--(...fivein)--cycle,planar=true),cyan);
+}
+
+
+
diff --git a/graphics/asymptote/examples/tvgen.asy b/graphics/asymptote/examples/tvgen.asy
new file mode 100644
index 0000000000..c7898fe712
--- /dev/null
+++ b/graphics/asymptote/examples/tvgen.asy
@@ -0,0 +1,1480 @@
+/* tvgen - draw pm5544-like television test cards.
+ * Copyright (C) 2007, 2009, 2012, Servaas Vandenberghe.
+ *
+ * The tvgen code below is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with tvgen: see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * tvgen-1.2/tvgen.asy http://picaros.org/ftp/soft/tvgen-1.2.tgz
+ * This asy script generates pm5544-like television test cards. The image
+ * parameters were derived from a 1990 recording. The basic parameters
+ * conform to itu-r bt.470, bt.601, and bt.709. There is no unique image
+ * since local variants exist and parameters have varied over time.
+ */
+//papertype="a4";
+import plain;
+int verbose=settings.verbose/*+2*/; /* uncomment for debug info */
+
+/* tv dot coordinates --> PS points */
+pair tvps(real col, real row, real xd, real yd, int Nv) {
+ real psx, psy;
+ psx=col*xd; psy=(Nv-row)*yd;
+ return (psx,psy);
+}
+path tvrect(int lc, int tr, int rc, int br, real xd, real yd, int Nv) {
+ real lx, ty, rx, by;
+ pair[] z;
+
+ lx=lc*xd; ty=(Nv-tr)*yd;
+ rx=rc*xd; by=(Nv-br)*yd;
+ /* bl br tr tl */
+ z[0]=(lx, by);
+ z[1]=(rx, by);
+ z[2]=(rx, ty);
+ z[3]=(lx, ty);
+
+ return z[0]--z[1]--z[2]--z[3]--cycle;
+}
+
+/********************* horizontal castellations ********************/
+/* Draw a horizontal red line in the top left and the bottom right
+ * castellation. These testlines disappear if the monitor is not set
+ * in a dot-exact mode. An example is image crop due to overscan.
+ *
+ * For 625 line systems any analog-compatible processing removes
+ * these red testlines since the first halfline of the odd field and
+ * the last halfline of the even field are ignored. A full 576
+ * visible line frame often results via a final copy paste operation.
+ */
+void castelhor(int colortv, int[] rccoll, int[] rccolr, int cmaxi, int Nh,
+ int topdist, int botdist,
+ pen pdef, real xd, real yd, int Nv) {
+ pen pblack, pwhite, pred;
+ int i;
+
+ pblack = pdef+gray(0.0);
+ pwhite = pdef+gray(1.0);
+ pred = pdef+rgb(0.75, 0, 0);
+
+ /** top and bottom: white corners. **/
+ for (i=-1; i<=cmaxi; ++i) {
+ pen pcast;
+ int inext, lc, rc, tr, br;
+ path zzc;
+
+ inext = i+1;
+ if (inext%2 == 0) {
+ pcast = pwhite;
+ } else {
+ pcast = pblack;
+ }
+
+ if (i >= 0) {
+ lc = rccolr[i];
+ } else {
+ lc = 0;
+ }
+ if (inext <= cmaxi) {
+ rc = rccoll[inext];
+ } else {
+ rc = Nh;
+ }
+
+ if (i == 0 && colortv > 0 && topdist > 1) {
+ path zzr;
+ zzr = tvrect(lc,0, rc,1, xd,yd,Nv);
+ fill(zzr, p=pred);
+ tr = 1;
+ } else {
+ tr = 0;
+ }
+ zzc = tvrect(lc,tr, rc,topdist, xd,yd,Nv);
+ fill(zzc, p=pcast);
+
+ if (inext == cmaxi && colortv > 0 && botdist+1 < Nv) {
+ path zzr;
+ zzr = tvrect(lc,Nv-1, rc,Nv, xd,yd,Nv);
+ fill(zzr, p=pred);
+ br = Nv-1;
+ } else {
+ br = Nv;
+ }
+ zzc = tvrect(lc,botdist, rc,br, xd,yd,Nv);
+ fill(zzc, p=pcast);
+ }
+
+ return;
+}
+
+/********************* vertical castellations ********************/
+/* The bottom right red rectangle tests for a non causal color FIR
+ * filter in the receiver. The last 2..4 dots then typically appear
+ * colorless, green, or cyan.
+ *
+ * This stems from the fact that the chroma subcarrier is of lower
+ * bandwidth than luma and thus continues after the last active sample.
+ * These trailing (y,u,v) samples result from an abrupt signal to zero
+ * transition and depend on the transmit and receive filters. Samples
+ * from VHS, system B/G/D/K, system I, or a DVD player output are
+ * different. Nevertheless, a sharpening filter uses this data and so
+ * adds false color to the last dots.
+ */
+void castelver(int colortv, int leftdist, int rightdist, int Nh,
+ int[] rcrowb, int[] rcrowt, int rmaxi,
+ pen pdef, real xd, real yd, int Nv) {
+ pen pblack, pwhite;
+ int i;
+
+ pblack = pdef+gray(0.0);
+ pwhite = pdef+gray(1.0);
+
+ for (i=0; i<rmaxi; ++i) {
+ int inext = i+1;
+ pen pcastl, pcastr;
+ int tr, br;
+ path zzc;
+
+ if (inext%2 == 0) {
+ pcastl = pwhite;
+ } else {
+ pcastl = pblack;
+ }
+ if (inext == rmaxi && colortv>0) {
+ pcastr = pdef+rgb(0.75,0.0,0);
+ } else {
+ pcastr = pcastl;
+ }
+
+ tr=rcrowb[i];
+ br=rcrowt[i+1];
+ zzc=tvrect( 0,tr, leftdist,br, xd,yd,Nv);
+ fill(zzc, p=pcastl);
+ zzc=tvrect(rightdist,tr, Nh,br, xd,yd,Nv);
+ fill(zzc, p=pcastr);
+ }
+ return;
+}
+/********************* image aspect ratio markers ********************/
+void rimarkers(real rimage, int Nh, int Nhc, int os, int Nvc, int Nsy,
+ pen pdef, real xd, real yd, int Nv) {
+ int[] ridefN={ 4, 16 };
+ int[] ridefD={ 3, 9 };
+ int i;
+
+ for (i=0; i<2; ++i) {
+ real rid=ridefN[i]/ridefD[i];
+
+ if (rimage>rid) {
+ int off, offa, offb;
+
+ /* Nhdef=Nh*rid/rimage */
+ off=round(Nh*rid/rimage/2);
+ offa=off+os;
+ offb=off-os;
+ // write(offa,offb);
+
+ if (2*offa<Nh) {
+ int hy, tr, br;
+ path zz;
+
+ hy=floor(Nsy/3);
+ tr=Nvc-hy;
+ br=Nvc+hy;
+
+ zz=tvrect(Nhc+offb, tr, Nhc+offa, br, xd,yd,Nv);
+ //dot(zz);
+ fill(zz, p=pdef);
+ zz=tvrect(Nhc-offa, tr, Nhc-offb, br, xd,yd,Nv);
+ fill(zz, p=pdef);
+ }
+ }
+ } /* for i */
+ return;
+}
+
+/************* crosshatch: line pairing, center interlace test *************/
+/* There are 2 coordinate systems in use:
+ * 1. integer number based for the gridlines
+ *
+ * coff, Nhc, rccoll[], rccolc[], rccolr[] : vertical gridlines,
+ * rcrowc, Nvc : horizontal gridlines,
+ *
+ * 2. real number based for the center circle
+ *
+ * ccenter={ cx=Nh/2, cy=Nv/2} : the true image center,
+ * rcoff rcright rcleft : offset to ccenter and points on the circle.
+ *
+ * Both centers coincide if Nh and Nv are even.
+ */
+void centerline(int colortv,
+ int[] rccoll, int[] rccolc, int[] rccolr, int divsx,
+ int Nhc, int os,
+ int[] rcrowt, int[] rcrowc, int[] rcrowb, int divsy,
+ int Nvc,
+ pair ccenter, real[] rcoff, pair[] rcright, pair[] rcleft,
+ pen pdef, real xd, real yd, int Nv) {
+ pen pblack, pwhite;
+ int cmaxi, maxoff, mincol, maxcol;
+ int rows, tr, br;
+ path zz;
+
+ cmaxi=2*divsx+1;
+
+ pblack=pdef+gray(0.0);
+ pwhite=pdef+gray(1.0);
+
+ /* black background for center cross */
+ if (colortv > 0) {
+ /* black, vertical gridlines redrawn below */
+ pair[] z;
+ int col;
+
+ z[0]=rcright[divsy];
+
+ col = rccolc[divsx+1];
+ z[1]=tvps(col,rcrowc[divsy], xd,yd,Nv);
+ z[2]=tvps(col,rcrowc[divsy-1], xd,yd,Nv);
+ col = rccolc[divsx];
+ z[3]=tvps(col,rcrowc[divsy-1], xd,yd,Nv);
+ z[4]=tvps(col,rcrowc[divsy], xd,yd,Nv);
+
+ z[5]=rcleft[divsy];
+ z[6]=rcleft[divsy+1];
+
+ z[7]=tvps(col,rcrowc[divsy+1], xd,yd,Nv);
+ z[8]=tvps(col,rcrowc[divsy+2], xd,yd,Nv);
+ col = rccolc[divsx+1];
+ z[9]=tvps(col,rcrowc[divsy+2], xd,yd,Nv);
+ z[10]=tvps(col,rcrowc[divsy+1], xd,yd,Nv);
+
+ z[11]=rcright[divsy+1];
+ fill(z[1]--z[2]--z[3]--z[4] //--z[5]--z[6]
+ --arc(ccenter, z[5], z[6])
+ --z[7]--z[8]--z[9]--z[10] //--z[11]--z[0]
+ --arc(ccenter,z[11], z[0])
+ --cycle, p=pblack);
+ } else {
+ /* 3 rows of black squares inside the gratings */
+ int i, imax = divsy+1;
+
+ for (i=divsy-1; i<=imax; ++i) { /* all 3 rows */
+ int lmaxoff, lmincol, lmaxcol;
+ int inext = i+1;
+ int tr, br, j;
+
+ /* XXX rcoff is relative to ccenter */
+ lmaxoff = min(floor(rcoff[i]), floor(rcoff[inext]));
+ lmincol = Nhc-lmaxoff;
+ lmaxcol = Nhc+lmaxoff;
+
+ /* square top and bottom */
+ tr = rcrowb[i];
+ br = rcrowt[inext];
+
+ for (j=0; j<cmaxi; ++j) { /* column j */
+ int jnext = j+1;
+
+ if (lmincol<=rccolc[j] && rccolc[jnext]<=lmaxcol) {
+ /* square is inside circle */
+ int lc, rc;
+ path zzsq;
+
+ lc = rccolr[j];
+ rc = rccoll[jnext];
+ zzsq = tvrect(lc, tr, rc, br, xd,yd,Nv);
+ fill(zzsq, p=pblack); /* draw black squares */
+ }
+ } /* for col j */
+ } /* for row i */
+ }
+
+ /* center cross: vertical and horizontal centerline */
+ maxoff = floor(rcoff[divsy]); /* XXX rcoff is relative to ccenter */
+ mincol = Nhc-maxoff;
+ maxcol = Nhc+maxoff;
+
+ rows=min(Nvc-rcrowc[divsy-1], rcrowc[divsy+2]-Nvc);
+ tr=Nvc-rows;
+ br=Nvc+rows;
+ if (verbose > 1) {
+ write("centerline long : rows tr br ", rows, tr, br);
+ }
+ zz=tvrect(Nhc-os, tr, Nhc+os, br, xd,yd,Nv);
+ fill(zz, p=pwhite);
+ zz=tvrect(Nhc-maxoff,Nvc-1, Nhc+maxoff,Nvc+1, xd,yd,Nv);
+ fill(zz, p=pwhite);
+
+ /* vertical short lines */
+ rows=min(Nvc-rcrowc[divsy], rcrowc[divsy+1]-Nvc);
+ tr=Nvc-rows;
+ br=Nvc+rows;
+ if (verbose > 1) {
+ write("centerline short: rows tr br ", rows, tr, br);
+ }
+
+ if (colortv > 0) {
+ int i;
+ for (i=0; i<=cmaxi; ++i) {
+ int coll, colr;
+
+ coll=rccoll[i];
+ colr=rccolr[i];
+
+ if (mincol<=coll && colr<=maxcol) {
+ path zzv;
+ zzv=tvrect(coll, tr, colr, br, xd,yd,Nv);
+ fill(zzv, p=pwhite);
+ }
+ }
+ }
+ return;
+}
+
+/************************ topbw **************************************/
+void topbw(int[] coff, int Nhc, int os, int urow, int trow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ pen pblack=pdef+gray(0.0), pwhite=pdef+gray(1.0);
+ pair[] ze;
+ path zext, zref, zint;
+ int off, col, cr;
+
+ off=ceil((coff[2]+coff[3])/2);
+ ze[0]=tvps(Nhc+off,trow, xd,yd,Nv);
+ ze[1]=rcrt;
+ ze[2]=rclt;
+ ze[3]=tvps(Nhc-off,trow, xd,yd,Nv);
+ ze[4]=tvps(Nhc-off,brow, xd,yd,Nv);
+ col=Nhc-coff[2]-os;
+ ze[5]=tvps(col,brow, xd,yd,Nv);
+ ze[6]=tvps(col,trow, xd,yd,Nv);
+ cr=col+3*os; /* reflection test black pulse */
+ zref=tvrect(col,trow, cr,brow, xd,yd,Nv);
+ ze[7]=tvps(cr,trow, xd,yd,Nv);
+ ze[8]=tvps(cr,brow, xd,yd,Nv);
+ ze[9]=tvps(Nhc+off,brow, xd,yd,Nv);
+ //dot(ze);
+
+ zext=ze[0] // --ze[1]--ze[2]
+ --arc(ccenter, ze[1], ze[2])
+ --ze[3]--ze[4]--ze[5]--ze[6]--ze[7]--ze[8]--ze[9]--cycle;
+
+ off=ceil((coff[1]+coff[2])/2);
+ zint=tvrect(Nhc-off,urow, Nhc+off,trow, xd,yd,Nv);
+
+ /* paths are completely resolved; no free endpoint conditions */
+ fill(zext^^reverse(zint), p=pwhite);
+ fill(zint, p=pblack);
+ fill(zref, p=pblack);
+
+ fill(arc(ccenter,rclt,rclb)--ze[4]--ze[3]--cycle, p=pblack);
+ fill(arc(ccenter,rcrb,rcrt)--ze[0]--ze[9]--cycle, p=pblack);
+ return;
+}
+
+/************************ testtone **************************************/
+/* x on circle -> return y>=0
+ * in:
+ * x x-coordinate relative to origin
+ * crad circle radius in y units, true size=crad*yd
+ */
+real testcircx(real x, real crad, real xd, real yd) {
+ real relx, ph, y;
+
+ relx=x*xd/yd/crad;
+ if (relx>1) {
+ ph=0;
+ } else {
+ ph=acos(relx);
+ }
+ y=crad*sin(ph); // or (x*xd)^2+(y*yd)^2=(crad*yd)^2
+
+ return y;
+}
+/* y on circle -> return x>=0 */
+real testcircy(real y, real crad, real xd, real yd) {
+ real rely, ph, x;
+
+ rely=y/crad;
+ if (rely>1) {
+ ph=pi/2;
+ } else {
+ ph=asin(rely);
+ }
+ x=crad*cos(ph)*yd/xd; // or (x*xd)^2+(y*yd)^2=(crad*yd)^2
+
+ return x;
+}
+
+/* brow>trow && xb>xt */
+void testtone(real Tt, int trow, int brow,
+ real ccol, real crow, real crad,
+ pen pdef, real xd, real yd, int Nv) {
+ int blocks, i;
+ real yt, xt, yb, xb, Ttt=Tt/2;
+ pair ccenter;
+
+ yt=crow-trow;
+ xt=testcircy(yt, crad, xd, yd);
+ yb=crow-brow;
+ xb=testcircy(yb, crad, xd, yd);
+ //write('#xt yt\t',xt,yt); write('#xb yb\t',xb,yb);
+
+ ccenter=tvps(ccol,crow, xd,yd,Nv);
+
+ blocks=floor(2*xb/Tt);
+
+ for (i=-blocks-1; i<=blocks; ++i) {
+ real tl, tr;
+ path zz;
+
+ tl=max(-xb,min(i*Ttt,xb)); /* limit [-xb..xb] */
+ tr=max(-xb,min((i+1)*Ttt,xb));
+
+ if (tl<-xt && tr<=-xt || tr>xt && tl>=xt) { /* top full circle */
+ pair[] z;
+ real yl, yr;
+
+ yl=testcircx(tl, crad, xd, yd);
+ yr=testcircx(tr, crad, xd, yd);
+
+ z[0]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[1]=tvps(ccol+tr,brow, xd,yd,Nv);
+ z[2]=tvps(ccol+tr,crow-yr, xd,yd,Nv);
+ z[3]=tvps(ccol+tl,crow-yl, xd,yd,Nv);
+
+ zz=z[0]--z[1]--arc(ccenter,z[2],z[3])--cycle;
+ } else if(tl<-xt) { /* tl in circel, tr not, partial */
+ pair[] z;
+ real yl;
+
+ yl=testcircx(tl, crad, xd, yd);
+
+ z[0]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[1]=tvps(ccol+tr,brow, xd,yd,Nv);
+ z[2]=tvps(ccol+tr,trow, xd,yd,Nv);
+ z[3]=tvps(ccol-xt,trow, xd,yd,Nv);
+ z[4]=tvps(ccol+tl,crow-yl, xd,yd,Nv);
+
+ zz=z[0]--z[1]--z[2]--arc(ccenter,z[3],z[4])--cycle;
+ } else if(tr>xt) { /* tr in circle, tl not, partial */
+ pair[] z;
+ real yr;
+
+ yr=testcircx(tr, crad, xd, yd);
+
+ z[0]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[1]=tvps(ccol+tr,brow, xd,yd,Nv);
+ z[2]=tvps(ccol+tr,crow-yr, xd,yd,Nv);
+ z[3]=tvps(ccol+xt,trow, xd,yd,Nv);
+ z[4]=tvps(ccol+tl,trow, xd,yd,Nv);
+ zz=z[0]--z[1]--arc(ccenter,z[2],z[3])--z[4]--cycle;
+ } else { /* full block */
+ pair[] z;
+
+ z[0]=tvps(ccol+tr,trow, xd,yd,Nv);
+ z[1]=tvps(ccol+tl,trow, xd,yd,Nv);
+ z[2]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[3]=tvps(ccol+tr,brow, xd,yd,Nv);
+ zz=z[0]--z[1]--z[2]--z[3]--cycle;
+ }
+
+ if (tl<tr) {
+ if (i%2 == 0) {
+ fill(zz, p=pdef+gray(0.0));
+ } else {
+ fill(zz, p=pdef+gray(0.75));
+ }
+ }
+ }
+ return;
+}
+
+/************************ color bars *************************************/
+void colorbars(int[] coff, int Nhc, int trow, int crow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ real cI=0.75;
+ real[] cR={ cI, 0, 0, cI, cI, 0 };
+ real[] cG={ cI, cI, cI, 0, 0, 0 };
+ real[] cB={ 0, cI, 0, cI, 0, cI };
+ int cmax=2, poff, rows, i;
+
+ rows=brow-trow;
+ poff=0;
+ for (i=0; i<=cmax; ++i) {
+ int off;
+ int ii=2*i, il=cmax-i, ir=i+cmax+1;
+ path zzl, zzr;
+
+ off=ceil((coff[1+ii]+coff[2+ii])/2);
+ if (i!=0 && i<cmax) {
+ zzr=tvrect(Nhc+poff,trow, Nhc+off,brow, xd,yd,Nv);
+ zzl=tvrect(Nhc-off,trow, Nhc-poff,brow, xd,yd,Nv);
+ } else {
+ if(i==0) {
+ int col, pcol;
+ pair[] zl, zr;
+
+ col=Nhc+off;
+ pcol=Nhc+poff;
+ zr[0]=tvps(col,trow, xd,yd,Nv);
+ zr[1]=tvps(pcol,trow, xd,yd,Nv);
+ zr[2]=tvps(pcol,crow, xd,yd,Nv);
+ zr[3]=tvps(Nhc+coff[0],crow, xd,yd,Nv);
+ zr[4]=tvps(Nhc+coff[0],brow, xd,yd,Nv);
+ zr[5]=tvps(col,brow, xd,yd,Nv);
+ zzr=zr[0]--zr[1]--zr[2]--zr[3]--zr[4]--zr[5]--cycle;
+
+ col=Nhc-off;
+ pcol=Nhc-poff;
+ zl[0]=tvps(pcol,trow, xd,yd,Nv);
+ zl[1]=tvps(col,trow, xd,yd,Nv);
+ zl[2]=tvps(col,brow, xd,yd,Nv);
+ zl[3]=tvps(Nhc-coff[0],brow, xd,yd,Nv);
+ zl[4]=tvps(Nhc-coff[0],crow, xd,yd,Nv);
+ zl[5]=tvps(pcol,crow, xd,yd,Nv);
+ zzl=zl[0]--zl[1]--zl[2]--zl[3]--zl[4]--zl[5]--cycle;
+ } else {
+ int pcol;
+ pair[] zl, zr;
+
+ pcol=Nhc+poff;
+ zr[0]=tvps(pcol,brow, xd,yd,Nv);
+ zr[1]=rcrb;
+ zr[2]=rcrt;
+ zr[3]=tvps(pcol,trow, xd,yd,Nv);
+ zzr=zr[0]--arc(ccenter,zr[1],zr[2])--zr[3]--cycle;
+
+ pcol=Nhc-poff;
+ zl[0]=tvps(pcol,trow, xd,yd,Nv);
+ zl[1]=rclt;
+ zl[2]=rclb;
+ zl[3]=tvps(pcol,brow, xd,yd,Nv);
+ zzl=zl[0]--arc(ccenter,zl[1],zl[2])--zl[3]--cycle;
+ }
+ }
+ fill(zzr, p=pdef+rgb(cR[ir], cG[ir], cB[ir]));
+ fill(zzl, p=pdef+rgb(cR[il], cG[il], cB[il]));
+
+ poff=off;
+ }
+ return;
+}
+
+/************************ test frequencies ****************************/
+/* in
+ * theta rad
+ * freq 1/hdot
+ * step hdot
+ * out
+ * new phase theta
+ */
+real addphase(real theta, real freq, real step) {
+ real cycles, thetaret;
+ int coverflow;
+
+ cycles=freq*step;
+ coverflow=floor(abs(cycles));
+ if (coverflow>1) {
+ thetaret=0;
+ } else {
+ real dpi=2*pi;
+
+ cycles-=coverflow*sgn(cycles);
+ thetaret=theta+cycles*dpi; /* cycles=(-1 .. 1) */
+
+ if (thetaret>pi) {
+ thetaret-=dpi;
+ } else if (thetaret<-pi) {
+ thetaret-=dpi;
+ }
+ }
+
+ //write("addphase: ", step, theta, thetaret);
+ return thetaret;
+}
+
+void testfreqs(real[] ftones, int[] coff, int Nhc, int trow,int crow,int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ int[] divc;
+ real[] divfl, divfr;
+ int i, divs, coffmax, off, divnext;
+ real fl, fr, thr, thl;
+
+ /* Segment info for PAL continental test card
+ * segment i extends from (divc[i] .. divc[i+1]) with frequency divf[i]
+ */
+ divs=2; // the number of segments to the right, total=2*divs+1
+ divc[0]=0;
+ for (i=0; i<=divs; ++i) {
+ int ii=i*2, il=divs-i, ir=divs+i;
+
+ divc[i+1]=ceil((coff[ii]+coff[ii+1])/2); /* xdot distance to center */
+
+ divfl[i]=ftones[divs-i];
+ divfr[i]=ftones[divs+i];
+ }
+ coffmax=divc[divs+1];
+
+ int trowlim=coff[0];
+ int tr;
+
+ tr=crow;
+
+ divnext=0;
+ fl=0;
+ fr=0;
+ thl=0; /* ={ 0, -pi/2 } : initial angle at center vertical line Nhc */
+ thr=thl;
+ /* draw a vertical line at off..off+1, use theta for off+1/2 */
+ for (off=0; off<coffmax; ++off) {
+ real ampl, ampr;
+ int col;
+ path zz;
+
+ if (off==trowlim) {
+ tr=trow;
+ }
+
+ if (off == divc[divnext]) {
+ /* switch frequency: cycles=0.5*fcur+0.5*fnext */
+ thl=addphase(thl, fl, -0.5);
+ thr=addphase(thr, fr, 0.5);
+ fl=divfl[divnext];
+ fr=divfr[divnext];
+ thl=addphase(thl, fl, -0.5);
+ thr=addphase(thr, fr, 0.5);
+
+ ++divnext;
+ // thl=pi; thr=pi;
+ //write(off, fl, fr);
+ } else {
+ thl=addphase(thl, fl, -1);
+ thr=addphase(thr, fr, 1);
+ // thl=0; thr=0;
+ }
+
+ ampl=(1+sin(thl))/2;
+ ampr=(1+sin(thr))/2;
+ //write(off, thr, ampr);
+
+ col=Nhc-off-1;
+ zz=tvrect(col,tr, col+1,brow, xd,yd,Nv);
+ fill(zz, p=pdef+gray(ampl));
+ col=Nhc+off;
+ zz=tvrect(col,tr, col+1,brow, xd,yd,Nv);
+ fill(zz, p=pdef+gray(ampr));
+ }
+
+ pair[] z;
+ z[0]=tvps(Nhc-coffmax,trow, xd,yd,Nv);
+ z[1]=tvps(Nhc-coffmax,brow, xd,yd,Nv);
+ fill(z[0]--arc(ccenter,rclt,rclb)--z[1]--cycle, p=pdef+gray(0.0));
+ z[0]=tvps(Nhc+coffmax,brow, xd,yd,Nv);
+ z[1]=tvps(Nhc+coffmax,trow, xd,yd,Nv);
+ fill(z[0]--arc(ccenter,rcrb,rcrt)--z[1]--cycle, p=pdef+gray(0.0));
+ return;
+}
+
+/************************ gray bars **************************************/
+void graybars(int[] coff, int Nhc, int trow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ int[] gs={0, 20, 40, 60, 80, 100};
+ int cmax=2, poff, i;
+
+ poff=0;
+ for (i=0; i<=cmax; ++i) {
+ int off;
+ int ii=2*i, il=cmax-i, ir=i+cmax+1;
+ path zzl, zzr;
+
+ off=ceil((coff[1+ii]+coff[2+ii])/2);
+ if (i<cmax) {
+ zzl=tvrect(Nhc-off,trow, Nhc-poff,brow, xd,yd,Nv);
+ zzr=tvrect(Nhc+poff,trow, Nhc+off,brow, xd,yd,Nv);
+ } else {
+ int pcol;
+ pair zlt, zlb, zrt, zrb;
+
+ pcol=Nhc-poff;
+ zlt=tvps(pcol,trow, xd,yd,Nv);
+ zlb=tvps(pcol,brow, xd,yd,Nv);
+ zzl=zlt--arc(ccenter,rclt,rclb)--zlb--cycle;
+
+ pcol=Nhc+poff;
+ zrb=tvps(pcol,brow, xd,yd,Nv);
+ zrt=tvps(pcol,trow, xd,yd,Nv);
+ zzr=zrb--arc(ccenter,rcrb,rcrt)--zrt--cycle;
+ }
+ fill(zzl, p=pdef+gray(gs[il]/100));
+ fill(zzr, p=pdef+gray(gs[ir]/100));
+
+ poff=off;
+ }
+ return;
+}
+
+/************************ bottom bw **************************************/
+void bottombw(int off, int Nhc, int trow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ int rows;
+ pair zt, zb;
+ path zz;
+
+ rows=brow-trow;
+ zz=tvrect(Nhc-off,trow, Nhc+off,brow, xd,yd,Nv);
+ fill(zz, p=pdef+gray(0.0));
+
+ zt=tvps(Nhc-off,trow, xd,yd,Nv);
+ zb=tvps(Nhc-off,brow, xd,yd,Nv);
+ fill(zt--arc(ccenter,rclt,rclb)--zb--cycle, p=pdef+gray(1.0));
+
+ zb=tvps(Nhc+off,brow, xd,yd,Nv);
+ zt=tvps(Nhc+off,trow, xd,yd,Nv);
+ fill(zb--arc(ccenter,rcrb,rcrt)--zt--cycle, p=pdef+gray(1.0));
+ return;
+}
+
+/************************ bottom circle **************************************/
+void bottomcirc(int off, int Nhc, int trow, real cx, real cy, real crad,
+ pair ccenter, pair rclt, pair rcrt,
+ pen pdef, real xd, real yd, int Nv) {
+ real cI=0.75;
+ real xl, yl, xr, yr, phil, phir;
+ pair ccleft, ccright;
+ pair[] z;
+
+ xl=Nhc-off-cx;
+ phil=acos(xl*xd/yd/crad);
+ yl=crad*sin(phil); // or (x*xd)^2+(y*yd)^2=(crad*yd)^2
+ ccleft=tvps(cx+xl,cy+yl, xd,yd,Nv);
+ //write(xl,yl);
+
+ xr=Nhc+off-cx;
+ phir=acos(xr*xd/yd/crad);
+ yr=crad*sin(phir);
+ ccright=tvps(cx+xr,cy+yr, xd,yd,Nv);
+
+ //dot(ccright); dot(ccleft);
+ // red center
+ z[0]=tvps(Nhc-off,trow, xd,yd,Nv);
+ z[1]=ccleft;
+ z[2]=ccright;
+ z[3]=tvps(Nhc+off,trow, xd,yd,Nv);
+ fill(z[0]--arc(ccenter,z[1],z[2])--z[3]--cycle, p=pdef+rgb(cI,0,0));
+
+ // yellow
+ z[0]=tvps(Nhc-off,trow, xd,yd,Nv);
+ z[1]=rclt;
+ z[2]=ccleft;
+ fill(z[0]--arc(ccenter,z[1],z[2])--cycle, p=pdef+rgb(cI,cI,0));
+ z[0]=tvps(Nhc+off,trow, xd,yd,Nv);
+ z[1]=ccright;
+ z[2]=rcrt;
+ fill(z[0]--arc(ccenter,z[1],z[2])--cycle, p=pdef+rgb(cI,cI,0));
+
+ return;
+}
+
+/****************************** PAL ears ***********************************/
+/* values pro mille
+ * left y R G B
+ * 550 306 674 550
+ * 500 363 500 859
+ * 500 637 500 141
+ * 450 694 326 450
+ * right
+ * 600 600 684 166
+ * 400 400 316 834
+ *
+ * in: dright= -1 left ear, +1 right ear
+ */
+void palears(int[] coff, int[] coffa, int[] coffb, int Nhc,
+ int[] rcrowt, int[] rcrowb, int Nvc, int divsy, int dright,
+ pen pdef, real xd, real yd, int Nv) {
+ /* the amplitude of (u,v) as seen on a vectorscope,
+ * max 0.296 Vn for 100% saturation in W and V ears.
+ * cvbs: 0.7*( y +/- |u+jv| ) = -0.24 .. 0.93 V
+ * maxima: ebu 75/0 bars 0.70, bbc 100/25 0.88, 100/0 bars 0.93
+ * burst: 0.150 Vcvbs, 21.4 IRE or 0.214 V normalized.
+ * luma: modulated for monochrome compatibility, 1990 version.
+ * choice: set amplitude of subcarrier equal to amplitude of colorburst.
+ */
+ real cI=0.214;
+
+ /* itu-r */
+ real wr=0.299, wb=0.114, wg=1-wr-wb; /* wg=0.587, y=wr*R+wg*G+wb*B */
+ real wu=0.493, wv=0.877; /* u=wu*(B-y) v=wv*(R-y) */
+ /* (u,v) for zero G-y, phase of -34.5 degrees */
+ real colu=wu*wg/wb, colv=-wv*wg/wr; /* for w=(G-y)/0.696 == 0 */
+
+ /* ears: U==0 W==0 W==0 U==0 */
+ real[] cyl={ 0.55, 0.5, 0.5, 0.45 };
+ real[] cul={ 0, colu, -colu, 0 };
+ real[] cvl={ -1, colv, -colv, 1 };
+
+ /* ears: V==0 W==0 W==0 V==0 */
+ real[] cyr={ 0.60, 0.5, 0.5, 0.40 };
+ real[] cur={ -1, colu, -colu, 1 };
+ real[] cvr={ 0, colv, -colv, 0 };
+
+ real[] cy, cu, cv;
+ pair[] z;
+ path[] zz;
+ int lcol, ccol, cicol, rcol, i;
+
+ if (dright>0) {
+ if (verbose > 1)
+ write("right ears");
+ cy=cyr; cu=cur; cv=cvr;
+ } else {
+ if (verbose > 1)
+ write("left ears");
+ cy=cyl; cu=cul; cv=cvl;
+ }
+
+ lcol=Nhc+dright*coffa[5];
+ ccol=Nhc+dright*coff[6];
+ cicol=Nhc+dright*coffa[6];
+ rcol=Nhc+dright*coffb[7];
+
+ int urow, trow, crow, brow, arow;
+ urow=rcrowb[divsy-5];
+ trow=rcrowt[divsy-3];
+ crow=Nvc;
+ brow=rcrowb[divsy+4];
+ arow=rcrowt[divsy+6];
+
+ z[0]=tvps(ccol,urow, xd,yd,Nv);
+ z[1]=tvps(ccol,trow, xd,yd,Nv);
+ z[2]=tvps(cicol,trow, xd,yd,Nv);
+ z[3]=tvps(cicol,crow, xd,yd,Nv);
+ z[4]=tvps(rcol,crow, xd,yd,Nv);
+ z[5]=tvps(rcol,urow, xd,yd,Nv);
+ zz[0]=z[0]--z[1]--z[2]--z[3]--z[4]--z[5]--cycle;
+
+ zz[1]=tvrect(lcol,urow, ccol,trow, xd,yd,Nv);
+ zz[2]=tvrect(lcol,brow, ccol,arow, xd,yd,Nv);
+
+ z[0]=tvps(ccol,arow, xd,yd,Nv);
+ z[1]=tvps(ccol,brow, xd,yd,Nv);
+ z[2]=tvps(cicol,brow, xd,yd,Nv);
+ z[3]=tvps(cicol,crow, xd,yd,Nv);
+ z[4]=tvps(rcol,crow, xd,yd,Nv);
+ z[5]=tvps(rcol,arow, xd,yd,Nv);
+ zz[3]=z[0]--z[1]--z[2]--z[3]--z[4]--z[5]--cycle;
+
+ for (i=0; i<4; ++i) {
+ real y, u, v, A, ph, By, Ry, Gy, R, G, B;
+
+ y=cy[i];
+ u=cu[i];
+ v=cv[i];
+
+ A=hypot(u,v);
+ ph= (u!=0 || v!=0) ? atan2(v,u) : 0.0;
+ if (v>=0) {
+ if (ph<0)
+ ph=ph+pi;
+ } else {
+ if (ph>0)
+ ph=ph-pi;
+ }
+ if (A>0) {
+ u=u/A*cI;
+ v=v/A*cI;
+ }
+
+ By=u/wu;
+ Ry=v/wv;
+ Gy=(-wr*Ry-wb*By)/wg;
+ //write(y,Gy,A,ph*180/pi);
+
+ R=Ry+y;
+ G=Gy+y;
+ B=By+y;
+ if (verbose > 1)
+ write(y*1000, round(R*1000), round(G*1000), round(B*1000));
+
+ fill(zz[i], p=pdef+rgb(R,G,B));
+ }
+ return;
+}
+
+/****************************** NTSC bars ***********************************/
+/* amplitude equals color burst smpte (pm: -V +U)
+ * y campl sat R G B
+ * left 0.5 0.21 70% -I?
+ * right 0.5 0.17 60% +Q?
+ */
+void ntscbars(int[] rccoll, int[] rccolr, int divsx,
+ int[] rcrowt, int[] rcrowb, int divsy, int dright,
+ pen pdef, real xd, real yd, int Nv) {
+ /* The amplitude of (i,q) as seen on a vectorscope,
+ * max 0.292 Vn for 100% saturation in I==0 ears.
+ * burst: 0.143 Vcvbs, 20 IRE or 0.200 V normalized.
+ * pedestal: (yp,up,vp)=(p,0,0)+(1-p)*(y,u,v), p=0.075.
+ * choice: equal amplitude for colorburst and subcarrier.
+ */
+ real campl=0.200/0.925;
+
+ /* wg=0.587, y=wr*R+wg*G+wb*B */
+ real wr=0.299, wb=0.114, wg=1-wr-wb;
+ /* iT : iq -> RyBy : rotation+scaling */
+ real iT11=0.95, iT12=0.62, iT21=-1.11, iT22=1.71;
+
+ /* bars -2 -1 0 1 2 */
+ real[] cyl={ 0.50, 0.50, 1, 0.50, 0.50 };
+ real[] cil={ 0, 0, 0, -1, 1 };
+ real[] cql={ -1, 1, 0, 0, 0 };
+ int[] indl={ -7, -8, 0, 8, 7 };
+
+ real cy, ci, cq;
+ int rmaxi, dri, ind, ibase, lcol, rcol, i;
+
+ rmaxi=2*divsy+1;
+ if (dright<-2 || dright>2) {
+ dri=2;
+ } else {
+ dri=2+dright;
+ }
+
+ cy=cyl[dri];
+ ci=cil[dri];
+ cq=cql[dri];
+ ind=indl[dri];
+ ibase=divsx+ind;
+ lcol=rccolr[ibase];
+ rcol=rccoll[ibase+1];
+
+ real A, By, Ry, Gy, R, G, B;
+
+ A=hypot(ci,cq);
+ if (A>0) {
+ ci=ci/A*campl;
+ cq=cq/A*campl;
+ }
+ Ry=iT11*ci+iT12*cq;
+ By=iT21*ci+iT22*cq;
+ Gy=(-wr*Ry-wb*By)/wg;
+ //write(cy,Ry,Gy,By);
+
+ R=Ry+cy;
+ G=Gy+cy;
+ B=By+cy;
+ if (verbose > 1)
+ write(ind, cy*1000, round(ci*1000), round(cq*1000),
+ round(R*1000), round(G*1000), round(B*1000));
+
+ for (i=0; i<rmaxi; ++i) {
+ path zz;
+ int brow, trow, inext=i+1;
+
+ if (i>0) {
+ trow=rcrowb[i];
+ } else {
+ trow=floor((rcrowb[i]+rcrowt[inext])/2);
+ }
+
+ if (inext<rmaxi) {
+ brow=rcrowt[inext];
+ } else {
+ brow=floor((rcrowb[i]+rcrowt[inext])/2);
+ }
+
+ zz=tvrect(lcol,trow, rcol,brow, xd,yd,Nv);
+ fill(zz, p=pdef+rgb(R,G,B));
+ }
+
+ return;
+}
+
+/****************************** main ***********************************/
+/* Conversion to bitmap:
+ * EPSPNG='gs -dQUIET -dNOPAUSE -dBATCH -sDEVICE=png16m'
+ * asy -u bsys=2 -u colortv=1 -u os=1 -a Z tvgen
+ * $EPSPNG -r132x144 -g720x576 -sOutputFile=tvgen.png tvgen.eps
+ *
+ * asy -u bsys=2 -u colortv=1 -u os=1 tvgen
+ */
+int bsys=2, colortv=1, os=1;
+
+/* bsys: broadcast system
+ * bsys im aspect Nh
+ * 0 4/3 704 guaranteed analog broadcast itu-r bt.470
+ * 1 4/3 720 new broadcast, most TV station logos and animations
+ * 2 15/11 720 total aperture analog 4/3, 1.37 film DVDs
+ * 3 20/11 720 total aperture analog 16/9, 1.85 film DVDs
+ * 4 4/3 768 bsys=0, square dot analog broadcast
+ * 5 4/3 768 bsys=1, square dot cable TV info channel
+ * 6 131/96 786 bsys=2, total square dot broadcast camera
+ * 7 16/9 720 new broadcast 16/9, SD from HD-1440 or itu-r bt.709
+ * 8 4/3 704 525 analog broadcast itu-r bt.470 711x485
+ * 9 4/3 720 525 new broadcast
+ * 10 15/11 720 525 total aperture analog broadcast
+ * 11 16/9 1920 1250, 1080 square dot at 12.5 frames/second
+ * 12 4/3 1600 1250, 1200 square dot at 12.5 frames/second
+ *
+ * colortv:
+ * 0 monochrome crosshatch,
+ * 1 pal ears,
+ * 2 ntsc bars,
+ * 3 neither ears nor bars.
+ *
+ * os: horizontal oversampling, typical values for 13.5MHz:
+ * 2 4/3 704*576, 15/11 720*576
+ * 4 4/3 720*480
+ * 5 4/3 704*480, 15/11 720*480, 4/3 768*576 14.4MHz
+ * 8 4/3 720*576, 20/11 720*576
+ * 12 704->768 rerastering
+ * 16 720->768 rerastering
+ */
+access settings;
+usersetting();
+
+if (bsys<0 || bsys>12 || colortv<0 || colortv>3 || os<=0 || os>16) {
+ write("Error: bad user input: bsys, colortv, os=\t", bsys, colortv, os);
+ abort("Bad option -u bsys=N ?");
+}
+
+int[] bNdot=
+ { 12, 16, 12, 16, 1, 1, 1, 64, 10, 8, 10, 1, 1 };
+int[] bDdot=
+ { 11, 15, 11, 11, 1, 1, 1, 45, 11, 9, 11, 1, 1 };
+int[] bNh=
+ { 704, 720, 720, 720, 768, 768, 786, 720, 704, 720, 720, 1920, 1600 };
+int[] bNv=
+ { 576, 576, 576, 576, 576, 576, 576, 576, 480, 480, 480, 1080, 1200 };
+real[] bfs=
+ { 13.5,13.5,13.5,13.5, 14.75,14.4,14.75,13.5, 13.5,13.5,13.5, 36, 30 };
+int[] bNsy=
+ { 42, 42, 42, 42, 42, 42, 42, 42, 34, 34, 34, 78, 90 };
+int[] bNsh=
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+/* active lines for a 625 line frame
+ * The number of active video lines decreased around 1997.
+ * old: 3 run in + 575 visible + 3 run out = 581 lines
+ * new: 6 teletext and WSS + 575 visible
+ * Hence the image center shifted down by 3 lines. Thus
+ * old TV + new testcard = bottom is cut off,
+ * new TV + old testcard = top is cut off.
+ *
+ * To generate the old testcard either use Nv=582 Nsh=0 or Nv=576 Nsh=3.
+ *
+ * aspect ratio
+ * rimage=xsize/ysize rimage=rdot*Nh/Nv
+ * Nh=704 dots
+ * Nv=576 lines
+ * rd=ri*Nv/Nh=4/3*9/11=12/11
+ *
+ * Nv: 480=2^5*3*5 576=2^6*3^2
+ * Nh: 704=2^6*11 720=2^4*3^2*5
+ *
+ * horizontal line distance for pre 1997 test pattern
+ * top 8 lines, 13 squares of Ny=43 lines, bottom 9 lines
+ * top 12 lines, 13 squares of Ny=42 lines, bottom 18 lines
+ * pairs are from odd even field
+ * Interlace test: Ny must be odd for a cross-hatch without centerline.
+ *
+ * squares: ly=Nsy, lx=rd*Nsx, lx=ly ==> Nsx=Nsy/rd={ 39.4, 38.5 }
+ * x line width 230 ns -> 3 dots
+ * bottom 2.9us red -> 39.15 dots
+ *
+ * resolution DPI from image aspect ratio
+ * Rv=Nv/ly, ly=4in
+ * ri=Ni/Di, Ni={ 4, 15, 16} Di={ 3, 11, 9}
+ * lx=ri*ly
+ *
+ * Rh=Nh/lx=Di*(Nh/(Ni*ly))
+ * integer Rh:
+ * Ni=4 ri=4/Di => Nh=k*16
+ * Ni=15 ri=15/Di => Nh=k*60
+ * Ni=16 ri=16/Di => Nh=k*64
+ *
+ * resolution DPI from dot aspect ratio, general algorithm,
+ *
+ * rd=Nd/Dd=ldx/ldy
+ *
+ * assume 1 dot = Nd x Dd square subdots at a resolution of k, in dpi, then
+ *
+ * ldx=Nd/k, ldy=Dd/k ==> Rh=k/Nd, Rv=k/Dd
+ *
+ * choosing k=m*Nd*Dd for integer Rh and Rv gives
+ *
+ * ldx=1/(m*Dd), ldy=1/(m*Nd), Rh=m*Dd, Rv=m*Nd
+ *
+ * and
+ *
+ * lx=Nh*ldx=Nh/(m*Dd), ly=Nv*ldy=Nv/(m*Nd)
+ *
+ * so choose m for the intended height Ly, in inch, as
+ *
+ * m=round(Nv/(Ly*Nd))
+ *
+ * which limits Ly<=Nv/Nd since Rv>=Nd.
+ */
+//cm=72/2.540005;
+real Ly, ly, lx, ysize, xsize, rimage, xd, yd, pwidth;
+int Nd, Dd, m, Nh, Nv, Nshift, Na, Nsy;
+real fs, Ttone;
+
+Nd=bNdot[bsys];
+Dd=bDdot[bsys]*os;
+Nh=bNh[bsys]*os;
+Nv=bNv[bsys];
+
+Ly=4; // 4 inch vertical size
+m=floor(0.5+Nv/(Ly*Nd));
+if (m < 1) m=1;
+ly=Nv/(m*Nd);
+lx=Nh/(m*Dd);
+
+ysize=ly*1inch;
+xsize=lx*1inch;
+rimage=xsize/ysize;
+if (verbose > 1) {
+ write("#Nd Dd m ri:\t", Nd, Dd, m, rimage);
+}
+//size(xsize, ysize, Aspect); // should not have any effect
+
+Nsy=bNsy[bsys]; // grating size in lines 42,43 or 34,35
+Nshift=bNsh[bsys]; // shift image up: pre 1997 =3, 2007 =0
+fs=1e6*bfs[bsys]*os;
+Na=0; // add 1,0,-1 to height of hor center squares for even Na+Nsy
+
+Ttone=fs/250e3; // period of ft=250 kHz, fs/ft=54
+real[] ftones={0.8e6/fs, 1.8e6/fs, 2.8e6/fs, 3.8e6/fs, 4.8e6/fs};
+
+xd=xsize/Nh;
+yd=ysize/Nv;
+pwidth=min(abs(xd),abs(yd));
+
+pen pdefault = squarecap+linewidth(pwidth);
+pen pblack = pdefault+gray(0.0);
+pen pwhite = pdefault+gray(1.0);
+
+/**** calculate grating repeats and size in tv dots ****/
+/* horizontal lines */
+int divsy, rdisty, Nvc, Nt, Nb, rmaxi;
+
+Nvc=floor(Nv/2)-Nshift;
+/* top half picture (Nv-2)/2-(Nsy+Na)/2 dots for divisions of Nsy dots */
+divsy=floor(((Nv-2-Na)/Nsy-1)/2);
+rdisty=Na+Nsy*(1+2*divsy);
+/* first guess free lines top and bottom */
+Nt=Nvc-ceil(rdisty/2);
+Nb=Nv-Nt-rdisty;
+if (verbose > 1) {
+ write('#divsy t b: \t', divsy, Nt, Nb);
+}
+rmaxi=2*divsy+1;
+
+/* Nsyc: center square height
+ * line pairing test: verify distance of center to top and bot
+ * distance is odd ==> top=even/odd, cent=odd/even, bot=even/odd
+ *
+ * Nsyc odd: not possible
+ *
+ * Nsyc even:
+ * Nsyc/2 odd --> OK
+ * Nsyc/2 even --> stagger the raster one line upwards
+ *
+ * rcrowt top dist of hor line
+ * rcrowc true center for color info, distance to top of image.
+ * rcrowb bot dist of hor line
+ *
+ * offd = offu-Nsyc
+ * Nt = Nvc-(offu+divsy*Nsy);
+ * Nb = Nv-( Nvc-(offd-divsy*Nsy) );
+ * ==> Nt+Nb = Nv-Nsyc-2*divsy*Nsy
+ */
+int Nsyc, offu, offd, Nyst=0, i;
+int[] rcrowt, rcrowc, rcrowb;
+
+Nsyc=Nsy+Na;
+offu=floor(Nsyc/2);
+offd=offu-Nsyc;
+if (Nsyc%2 != 0) {
+ Nyst=1;
+} else if (Nsyc%4 == 0) {
+ Nyst=1; /* stagger */
+}
+for (i=0; i<=divsy; ++i) {
+ int iu, id, ou, od, ru, rd;
+
+ iu=divsy-i;
+ id=divsy+i+1;
+
+ ou=offu+Nsy*i;
+ od=offd-Nsy*i;
+ if (verbose > 1) {
+ write(ou,od);
+ }
+ rcrowc[iu]=Nvc-ou;
+ rcrowc[id]=Nvc-od;
+
+ ru=Nvc-(ou+Nyst);
+ rd=Nvc-(od+Nyst);
+
+ rcrowt[iu]=ru-1;
+ rcrowb[iu]=ru+1;
+
+ rcrowt[id]=rd-1;
+ rcrowb[id]=rd+1;
+}
+Nt=floor((rcrowt[0]+rcrowb[0])/2);
+Nb=Nv-Nt-Nsyc-2*Nsy*divsy;
+if (verbose > 1) {
+ write('#st t b: \t', Nyst, Nt, Nb);
+}
+
+/* vertical lines
+ * (Nh-2*os)/2-Nsx/2 dots available for divisions of Nsx dots.
+ * At least 5 dots margin left and right ==> use -10*os
+ */
+real lsq, Nsx, rdistx;
+int divsx, Nhc, Nl, Nr, cmaxi;
+
+lsq=Nsy*yd;
+Nsx=lsq/xd; /* floating point */
+divsx=floor(((Nh-10*os)/Nsx-1)/2);
+Nhc=round(Nh/2);
+rdistx=(1+2*divsx)*Nsx;
+Nl=Nhc-round(rdistx/2);
+if (verbose > 1) {
+ write('#divsx Nsx l:\t', divsx, Nsx, Nl);
+}
+cmaxi=2*divsx+1;
+
+int[] coff, coffl, coffr;
+int[] rccoll, rccolc, rccolr;
+for (i=0; i<=divsx; ++i) {
+ int off, offl, offr, il, ir;
+ real cdist;
+
+ cdist=Nsx*(1+2*i); /* horizontal distance 2 symmetrical vert lines */
+ off=round(cdist/2);
+ // write(cdist, off);
+ offl=off-os;
+ offr=off+os;
+
+ coff[i]=off;
+ coffl[i]=offl;
+ coffr[i]=offr;
+
+ if (verbose > 1) {
+ write(cdist, off);
+ }
+ il=divsx-i;
+ ir=divsx+i+1;
+
+ rccoll[il]=Nhc-offr;
+ rccolc[il]=Nhc-off;
+ rccolr[il]=Nhc-offl;
+
+ rccoll[ir]=Nhc+offl;
+ rccolc[ir]=Nhc+off;
+ rccolr[ir]=Nhc+offr;
+}
+Nl=rccolc[0];
+Nr=Nh-rccolc[cmaxi];
+if (verbose > 1) {
+ write('#divsx Nsx l r:\t', divsx, Nsx, Nl, Nr);
+}
+
+/**** draw gray background ****/
+{
+ path zz;
+
+ //zz=tvrect(0,0, Nh,Nv, xd,yd,Nv);
+ /* keep white canvas for castellations */
+ zz=tvrect(rccoll[0],rcrowt[0], rccolr[cmaxi],rcrowb[rmaxi], xd,yd,Nv);
+ fill(zz, p=pdefault+gray(0.5));
+ //dot(zz);
+}
+/**** draw center circle ****/
+real cx, cy, crad;
+pair ccenter;
+path ccirc;
+cx=Nh/2;
+cy=Nv/2-Nshift;
+crad=6*Nsy;
+if (Nv%2 != 0) {
+ crad+=0.5;
+}
+ccenter=tvps(cx,cy, xd,yd,Nv);
+ccirc=circle(ccenter, crad*yd);
+if (colortv<=0) {
+ draw(ccirc, p=pwhite+linewidth(2*yd));
+}
+
+/**** draw 2*divsy+2 horizontal gridlines ****/
+real[] rcang, rcoff;
+pair[] rcright, rcleft;
+int i;
+for (i=0; i<=rmaxi; ++i) {
+ real y, ph, x;
+ path zzh;
+ pair zd;
+
+ zzh=tvrect(0,rcrowt[i], Nh,rcrowb[i], xd,yd,Nv);
+ fill(zzh, p=pwhite);
+
+ y=cy-rcrowc[i];
+ if (abs(y)<crad) {
+ ph=asin(y/crad);
+ } else {
+ ph=pi/2;
+ }
+ rcang[i]=ph;
+ x=(crad*cos(ph))*yd/xd;
+ rcoff[i]=x;
+ zd=tvps(cx+x,cy-y, xd,yd,Nv);
+ rcright[i]=zd;
+ //dot(zd);
+ zd=tvps(cx-x,cy-y, xd,yd,Nv);
+ rcleft[i]=zd;
+}
+
+/**** draw 2*divsx+2 vertical gridlines ****/
+for (i=0; i<=cmaxi; ++i) {
+ path zzv;
+ zzv=tvrect(rccoll[i],0, rccolr[i],Nv, xd,yd,Nv);
+ fill(zzv, p=pwhite);
+}
+
+/**** castellations ****/
+castelhor(colortv, rccoll, rccolr, cmaxi, Nh, rcrowt[0], rcrowb[rmaxi],
+ pdefault, xd, yd, Nv);
+
+castelver(colortv, rccoll[0], rccolr[cmaxi], Nh, rcrowb, rcrowt, rmaxi,
+ pdefault, xd, yd, Nv);
+
+/****** markers for 4/3 aspect ratio ******/
+if (rimage>4/3) {
+ rimarkers(rimage, Nh, Nhc, os, Nvc, Nsy, pwhite, xd, yd, Nv);
+}
+
+/****** line pairing center ******/
+centerline(colortv, rccoll, rccolc, rccolr, divsx, Nhc, os,
+ rcrowt, rcrowc, rcrowb, divsy, Nvc,
+ ccenter, rcoff, rcright, rcleft, pdefault, xd, yd, Nv);
+
+if (colortv>0) {
+ /* topbw structure */
+ topbw(coff, Nhc, os, rcrowc[divsy-5], rcrowc[divsy-4], rcrowc[divsy-3],
+ ccenter, rcleft[divsy-4], rcleft[divsy-3], rcright[divsy-4],
+ rcright[divsy-3], pdefault, xd, yd, Nv);
+
+ /* 250 kHz */
+ testtone(Ttone, rcrowc[divsy-3], rcrowc[divsy-2],
+ cx, cy, crad, pdefault, xd, yd, Nv);
+
+ /* color bars */
+ colorbars(coff, Nhc, rcrowc[divsy-2], rcrowc[divsy-1], rcrowc[divsy],
+ ccenter, rcleft[divsy-2], rcleft[divsy], rcright[divsy-2],
+ rcright[divsy], pdefault, xd, yd, Nv);
+
+ /* test frequencies */
+ testfreqs(ftones, coff, Nhc, rcrowc[divsy+1], rcrowc[divsy+2],
+ rcrowc[divsy+3], ccenter, rcleft[divsy+1], rcleft[divsy+3],
+ rcright[divsy+1],rcright[divsy+3], pdefault, xd, yd, Nv);
+
+ /* gray bars */
+ graybars(coff, Nhc, rcrowc[divsy+3], rcrowc[divsy+4], ccenter,
+ rcleft[divsy+3], rcleft[divsy+4],
+ rcright[divsy+3], rcright[divsy+4], pdefault, xd,yd,Nv);
+
+ /* PAL ears */
+ if (colortv == 1) {
+ palears(coff,coffr,coffl, Nhc, rcrowt, rcrowb, Nvc, divsy, -1,
+ pdefault, xd, yd, Nv);
+ palears(coff,coffr,coffl, Nhc, rcrowt, rcrowb, Nvc, divsy, 1,
+ pdefault, xd, yd, Nv);
+ } else if (colortv == 2) {
+ ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, -1,
+ pdefault, xd, yd, Nv);
+ ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, 1,
+ pdefault, xd, yd, Nv);
+ ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, -2,
+ pdefault, xd, yd, Nv);
+ ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, 2,
+ pdefault, xd, yd, Nv);
+ }
+
+ /* bottom wh - black - wh */
+ bottombw(round((coff[2]+coff[3])/2), Nhc, rcrowc[divsy+4], rcrowc[divsy+5],
+ ccenter, rcleft[divsy+4], rcleft[divsy+5],
+ rcright[divsy+4], rcright[divsy+5], pdefault, xd, yd, Nv);
+
+ /* bottom yellow red circle */
+ bottomcirc(coff[0], Nhc, rcrowc[divsy+5], cx, cy, crad,
+ ccenter, rcleft[divsy+5], rcright[divsy+5], pdefault, xd, yd, Nv);
+}
+
+/********************** set id *********************/
+{ /* dpi */
+ pair rpos=tvps(Nhc,round((rcrowc[divsy-4]+rcrowc[divsy-5])/2), xd,yd,Nv);
+ string iRhor, iRver, ires;
+ real Rh, Rv;
+
+ Rh=Nh/xsize*inch;
+ Rv=Nv/ysize*inch;
+ iRhor=format("%.4gx", Rh);
+ iRver=format("%.4gdpi", Rv);
+ ires=insert(iRver,0, iRhor);
+
+ /* size info */
+ int rowbot=round((rcrowc[divsy+4]+rcrowc[divsy+5])/2);
+ pair tpos=tvps(Nhc,rowbot, xd,yd,Nv);
+ string ihor, iver, itot, iasp, ifm;
+ real asp, fm;
+
+ ihor=format("%ix",Nh);
+ iver=format("%i ",Nv);
+ itot=insert(iver,0, ihor);
+ asp=xsize/ysize;
+ iasp=format("%.3g ",asp);
+ fm=fs/1e6;
+ ifm=format("%.4gMHz",fm);
+ itot=insert(iasp,0, itot);
+ itot=insert(ifm,0, itot);
+
+ /* size of square */
+ int rowNsy, colNsy;
+ pair Npos;
+ string iNsy;
+ pen pbw;
+
+ rowNsy = round((rcrowc[divsy+5]+rcrowc[divsy+6])/2);
+ colNsy = round((rccolc[divsx+5]+rccolc[divsx+6])/2);
+ Npos = tvps(colNsy,rowNsy, xd,yd,Nv);
+ iNsy = format("%i", Nsy);
+
+ if (colortv>0) {
+ pbw=pdefault+gray(1.0);
+ } else {
+ pbw=pdefault+gray(0.0);
+ }
+ label(ires, rpos, p=pbw);
+ label(itot, tpos, p=pbw);
+ label(iNsy, Npos, p=pbw);
+ if (verbose > 1)
+ write('#res:\t', ires, itot, iNsy);
+}
diff --git a/graphics/asymptote/examples/twistedtubes.asy b/graphics/asymptote/examples/twistedtubes.asy
new file mode 100644
index 0000000000..9121ad6444
--- /dev/null
+++ b/graphics/asymptote/examples/twistedtubes.asy
@@ -0,0 +1,30 @@
+import graph3;
+import palette;
+
+size(300,300,keepAspect=true);
+
+real w=0.4;
+
+real f(triple t) {return sin(t.x);}
+triple f1(pair t) {return (cos(t.x)-2cos(w*t.y),sin(t.x)-2sin(w*t.y),t.y);}
+triple f2(pair t) {return (cos(t.x)+2cos(w*t.y),sin(t.x)+2sin(w*t.y),t.y);}
+triple f3(pair t) {return (cos(t.x)+2sin(w*t.y),sin(t.x)-2cos(w*t.y),t.y);}
+triple f4(pair t) {return (cos(t.x)-2sin(w*t.y),sin(t.x)+2cos(w*t.y),t.y);}
+
+surface s1=surface(f1,(0,0),(2pi,10),8,8,Spline);
+surface s2=surface(f2,(0,0),(2pi,10),8,8,Spline);
+surface s3=surface(f3,(0,0),(2pi,10),8,8,Spline);
+surface s4=surface(f4,(0,0),(2pi,10),8,8,Spline);
+
+pen[] Rainbow=Rainbow();
+s1.colors(palette(s1.map(f),Rainbow));
+s2.colors(palette(s2.map(f),Rainbow));
+s3.colors(palette(s3.map(f),Rainbow));
+s4.colors(palette(s4.map(f),Rainbow));
+
+defaultrender.merge=true;
+
+draw(s1);
+draw(s2);
+draw(s3);
+draw(s4);
diff --git a/graphics/asymptote/examples/unitcircle.asy b/graphics/asymptote/examples/unitcircle.asy
new file mode 100644
index 0000000000..582f5f3c1f
--- /dev/null
+++ b/graphics/asymptote/examples/unitcircle.asy
@@ -0,0 +1,14 @@
+size(0,150);
+
+pair z0=0;
+pair z1=1;
+real theta=30;
+pair z=dir(theta);
+
+draw(circle(z0,1));
+filldraw(z0--arc(z0,1,0,theta)--cycle,lightgrey);
+dot(z0);
+dot(Label,z1);
+dot("$(x,y)=(\cos\theta,\sin\theta)$",z);
+arrow("area $\frac{\theta}{2}$",dir(0.5*theta),2E);
+draw("$\theta$",arc(z0,0.7,0,theta),LeftSide,Arrow,PenMargin);
diff --git a/graphics/asymptote/examples/unitoctant.asy b/graphics/asymptote/examples/unitoctant.asy
new file mode 100644
index 0000000000..89f851f6a2
--- /dev/null
+++ b/graphics/asymptote/examples/unitoctant.asy
@@ -0,0 +1,35 @@
+import graph3;
+
+currentprojection=orthographic(5,4,2);
+
+size(0,150);
+patch s=octant1;
+draw(surface(s),green+opacity(0.5));
+draw(s.external(),blue);
+
+triple[][] P=s.P;
+
+for(int i=0; i < 4; ++i)
+ dot(P[i],red);
+
+axes3("$x$","$y$",Label("$z$",align=Z));
+triple P00=P[0][0];
+triple P10=P[1][0];
+triple P01=P[0][1];
+triple P02=P[0][2];
+triple P11=P[1][1];
+triple P12=P[1][2];
+triple Q11=XYplane(xypart(P11));
+triple Q12=XYplane(xypart(P12));
+
+draw(P11--Q11,dashed);
+draw(P12--Q12,dashed);
+draw(O--Q12--Q11--(Q11.x,0,0));
+draw(Q12--(Q12.x,0,0));
+
+label("$(1,0,0)$",P00,-2Y);
+label("$(1,a,0)$",P10,-Z);
+label("$(1,0,a)$",P01,-2Y);
+label("$(a,0,1)$",P02,Z+X-Y);
+label("$(1,a,a)$",P11,3X);
+label("$(a,a^2,1)$",P12,7X+Y);
diff --git a/graphics/asymptote/examples/upint.asy b/graphics/asymptote/examples/upint.asy
new file mode 100644
index 0000000000..b488358ec6
--- /dev/null
+++ b/graphics/asymptote/examples/upint.asy
@@ -0,0 +1,13 @@
+import graph;
+import lowupint;
+
+size(100,0);
+
+real a=-0.8, b=1.2;
+real c=-1.0/sqrt(3.0);
+
+partition(a,b,c,max);
+
+arrow("$f(x)$",F(0.5*(a+b)),NNE,red);
+label("$\cal{U}$",(0.5*(a+b),f(0.5*(a+b))/2));
+
diff --git a/graphics/asymptote/examples/vectorfield3.asy b/graphics/asymptote/examples/vectorfield3.asy
new file mode 100644
index 0000000000..a7bdbdb36c
--- /dev/null
+++ b/graphics/asymptote/examples/vectorfield3.asy
@@ -0,0 +1,26 @@
+import graph3;
+
+size(12cm,0);
+
+currentprojection=orthographic(1,-2,1);
+currentlight=(1,-1,0.5);
+
+real f(pair z) {return abs(z)^2;}
+
+path3 gradient(pair z) {
+ static real dx=sqrtEpsilon, dy=dx;
+ return O--((f(z+dx)-f(z-dx))/2dx,(f(z+I*dy)-f(z-I*dy))/2dy,0);
+}
+
+pair a=(-1,-1);
+pair b=(1,1);
+
+triple F(pair z) {return (z.x,z.y,0);}
+
+add(vectorfield(gradient,F,a,b,red));
+
+draw(surface(f,a,b,Spline),gray+opacity(0.5));
+
+xaxis3(XY()*"$x$",OutTicks(XY()*Label));
+yaxis3(XY()*"$y$",InTicks(YX()*Label));
+zaxis3("$z$",OutTicks);
diff --git a/graphics/asymptote/examples/vectorfieldsphere.asy b/graphics/asymptote/examples/vectorfieldsphere.asy
new file mode 100644
index 0000000000..7f1e49057a
--- /dev/null
+++ b/graphics/asymptote/examples/vectorfieldsphere.asy
@@ -0,0 +1,17 @@
+import graph3;
+
+size(12cm);
+
+currentprojection=orthographic(1,-2,1);
+currentlight=(1,-1,0.5);
+
+triple f(pair z) {return expi(z.x,z.y);}
+
+path3 vector(pair z) {
+ triple v=f(z);
+ return O--(v.y,v.z,v.x);
+}
+
+add(vectorfield(vector,f,(0,0),(pi,2pi),10,0.25,red,render(merge=true)));
+
+draw(unitsphere,gray+opacity(0.5),render(compression=0,merge=true));
diff --git a/graphics/asymptote/examples/venn.asy b/graphics/asymptote/examples/venn.asy
new file mode 100644
index 0000000000..33100a72e8
--- /dev/null
+++ b/graphics/asymptote/examples/venn.asy
@@ -0,0 +1,36 @@
+size(0,150);
+
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+fill(c1,colour1);
+fill(c2,colour2);
+
+picture intersection;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+label("$A$",z1);
+label("$B$",z2);
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
+
+shipout(bbox(0.25cm));
diff --git a/graphics/asymptote/examples/venn3.asy b/graphics/asymptote/examples/venn3.asy
new file mode 100644
index 0000000000..6118fab6e9
--- /dev/null
+++ b/graphics/asymptote/examples/venn3.asy
@@ -0,0 +1,50 @@
+size(0,150);
+
+pen colour1=red;
+pen colour2=green;
+pen colour3=blue;
+
+real r=sqrt(3);
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+pair z3=(0,r);
+
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+path c3=circle(z3,r);
+
+fill(c1,colour1);
+fill(c2,colour2);
+fill(c3,colour3);
+
+picture intersection12;
+fill(intersection12,c1,colour1+colour2);
+clip(intersection12,c2);
+
+picture intersection13;
+fill(intersection13,c1,colour1+colour3);
+clip(intersection13,c3);
+
+picture intersection23;
+fill(intersection23,c2,colour2+colour3);
+clip(intersection23,c3);
+
+picture intersection123;
+fill(intersection123,c1,colour1+colour2+colour3);
+clip(intersection123,c2);
+clip(intersection123,c3);
+
+add(intersection12);
+add(intersection13);
+add(intersection23);
+add(intersection123);
+
+draw(c1);
+draw(c2);
+draw(c3);
+
+label("$A$",z1);
+label("$B$",z2);
+label("$C$",z3);
diff --git a/graphics/asymptote/examples/vertexshading.asy b/graphics/asymptote/examples/vertexshading.asy
new file mode 100644
index 0000000000..a5555d66f7
--- /dev/null
+++ b/graphics/asymptote/examples/vertexshading.asy
@@ -0,0 +1,14 @@
+import three;
+
+size(200);
+
+currentprojection=perspective(4,5,5);
+
+draw(surface(unitcircle3,new pen[] {red,green,blue,black}));
+draw(surface(shift(Z)*unitsquare3,
+ new pen[] {red,green+opacity(0.5),blue,black}));
+draw(surface(shift(X)*((0,0,0)..controls (1,0,0) and (2,0,0)..(3,0,0)..
+ controls (2.5,sqrt(3)/2,0) and (2,sqrt(3),0)..
+ (1.5,3*sqrt(3)/2,0)..
+ controls (1,sqrt(3),0) and (0.5,sqrt(3)/2,0)..cycle),
+ new triple[] {(1.5,sqrt(3)/2,2)},new pen[] {red,green,blue}));
diff --git a/graphics/asymptote/examples/washer.asy b/graphics/asymptote/examples/washer.asy
new file mode 100644
index 0000000000..457ae69fb8
--- /dev/null
+++ b/graphics/asymptote/examples/washer.asy
@@ -0,0 +1,14 @@
+import three;
+size(10cm);
+
+path3[] p=reverse(unitcircle3)^^scale3(0.5)*unitcircle3;
+path[] g=reverse(unitcircle)^^scale(0.5)*unitcircle;
+triple H=-0.4Z;
+
+render render=render(merge=true);
+draw(surface(p,planar=true),render);
+draw(surface(shift(H)*p,planar=true),render);
+material m=material(lightgray,shininess=1.0);
+for(path pp : g)
+ draw(extrude(pp,H),m);
+
diff --git a/graphics/asymptote/examples/washermethod.asy b/graphics/asymptote/examples/washermethod.asy
new file mode 100644
index 0000000000..c3177aa111
--- /dev/null
+++ b/graphics/asymptote/examples/washermethod.asy
@@ -0,0 +1,43 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(0,0,11,up=Y);
+
+pen color1=green+opacity(0.25);
+pen color2=red;
+real alpha=240;
+
+real f(real x) {return 2x^2-x^3;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+ngraph=12;
+
+real x1=0.7476;
+real x2=1.7787;
+real x3=1.8043;
+
+path[] p={graph(F,x1,x2,Spline),
+ graph(F,0.7,x1,Spline)--graph(F,x2,x3,Spline),
+ graph(F,0,0.7,Spline)--graph(F,x3,2,Spline)};
+
+pen[] pn=new pen[] {color1,color2,color1};
+
+render render=render(compression=0);
+
+for(int i=0; i < p.length; ++i) {
+ revolution a=revolution(path3(p[i]),Y,0,alpha);
+ draw(surface(a),pn[i],render);
+
+ surface s=surface(p[i]--cycle);
+ draw(s,pn[i],render);
+ draw(rotate(alpha,Y)*s,pn[i],render);
+}
+
+draw((4/3,0,0)--F3(4/3),dashed);
+xtick("$\frac{4}{3}$",(4/3,0,0));
+
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),ymax=1.25,dashed,Arrow3);
+arrow("$y=2x^2-x^3$",F3(1.6),X+Y,0.75cm,red);
+draw(arc(1.1Y,0.3,90,0,7.5,180),Arrow3);
diff --git a/graphics/asymptote/examples/wedge.asy b/graphics/asymptote/examples/wedge.asy
new file mode 100644
index 0000000000..41b4326cf4
--- /dev/null
+++ b/graphics/asymptote/examples/wedge.asy
@@ -0,0 +1,23 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(8,10,2);
+currentlight=White;
+
+draw(circle(O,4,Z));
+draw(shift(-4Z)*scale(4,4,8)*unitcylinder,green+opacity(0.2));
+
+triple F(real x){return (x,sqrt(16-x^2),sqrt((16-x^2)/3));}
+path3 p=graph(F,0,4,operator ..);
+path3 q=reverse(p)--rotate(180,(0,4,4/sqrt(3)))*p--cycle;
+
+render render=render(merge=true);
+draw(surface(q--cycle),red,render);
+
+real t=2;
+path3 triangle=(t,0,0)--(t,sqrt(16-t^2),0)--F(t)--cycle;
+draw(surface(triangle),blue,render);
+
+xaxis3("$x$",Arrow3,PenMargin3(0,0.25));
+yaxis3("$y$",Arrow3,PenMargin3(0,0.25));
+zaxis3("$z$",dashed,Arrow3);
diff --git a/graphics/asymptote/examples/workcone.asy b/graphics/asymptote/examples/workcone.asy
new file mode 100644
index 0000000000..5d102d8621
--- /dev/null
+++ b/graphics/asymptote/examples/workcone.asy
@@ -0,0 +1,42 @@
+import solids;
+size(0,150);
+currentprojection=orthographic(0,-30,5);
+
+real r=4;
+real h=10;
+real s=8;
+real x=r*s/h;
+
+real sr=5;
+real xr=r*sr/h;
+
+real s1=sr-0.1;
+real x1=r*s1/h;
+
+real s2=sr+0.2;
+real x2=r*s2/h;
+
+render render=render(compression=0,merge=true);
+
+path3 p=(0,0,0)--(x,0,s);
+revolution a=revolution(p,Z);
+draw(surface(a,4),lightblue+opacity(0.5),render);
+
+path3 q=(x,0,s)--(r,0,h);
+revolution b=revolution(q,Z);
+draw(surface(b),white+opacity(0.5),render);
+
+draw((-r-1,0,0)--(r+1,0,0));
+draw((0,0,0)--(0,0,h+1),dashed);
+
+path3 w=(x1,0,s1)--(x2,0,s2)--(0,0,s2);
+revolution b=revolution(w,Z);
+draw(surface(b),blue+opacity(0.5),render);
+draw(circle((0,0,s2),x2));
+draw(circle((0,0,s1),x1));
+
+draw("$x$",(xr,0,0)--(xr,0,sr),red,Arrow3,PenMargin3);
+draw("$r$",(0,0,sr)--(xr,0,sr),N,red);
+draw((string) r,(0,0,h)--(r,0,h),N,red);
+draw((string) h,(r,0,0)--(r,0,h),red,Arrow3,PenMargin3);
+draw((string) s,(-x,0,0)--(-x,0,s),W,red,Arrow3,Bar3,PenMargin3);
diff --git a/graphics/asymptote/examples/worksheet.asy b/graphics/asymptote/examples/worksheet.asy
new file mode 100644
index 0000000000..9894e5802b
--- /dev/null
+++ b/graphics/asymptote/examples/worksheet.asy
@@ -0,0 +1,49 @@
+import fontsize;
+
+defaultpen(Helvetica());
+
+picture pic;
+unitsize(pic,mm);
+
+pair z=(0,0);
+real length=88;
+real height=8;
+pair step=height*S;
+
+label(pic,"Word Wall Spelling",z,Align);
+z += step;
+frame f;
+label(f,"Name:");
+pair z0=(max(f).x,min(f).y);
+draw(f,z0--z0+50mm);
+add(pic,f,z,Align);
+z += step;
+
+for(int i=1; i <= 15; ++i) {
+ draw(pic,z--z+length);
+ z += step;
+ draw(pic,z--z+length,dashed+gray);
+ z += step;
+ void label(int i) {
+ label(pic,string(i)+".",z,0.2NE,fontsize(0.8*1.5*2*height*mm)+gray);
+ }
+ if(i <= 10) label(i);
+ else if(i == 11) {
+ pair z0=z+length/2;
+ pen p=fontsize(20pt);
+ label(pic,"Challenge Word",z0+N*height,I*Align.y,p+basealign);
+ label(pic,"(optional)",z0,I*Align.y,p);
+ }
+ else if(i == 12) label(1);
+ else if(i == 13) label(2);
+ else if(i == 14) label(3);
+}
+draw(pic,z--z+length);
+
+add(pic.fit(),(0,0),W);
+add(pic.fit(),(0,0),E);
+newpage();
+add(pic.fit(),(0,0),W);
+add(pic.fit(),(0,0),E);
+
+
diff --git a/graphics/asymptote/examples/worldmap.asy b/graphics/asymptote/examples/worldmap.asy
new file mode 100644
index 0000000000..c52ff23ded
--- /dev/null
+++ b/graphics/asymptote/examples/worldmap.asy
@@ -0,0 +1,87 @@
+settings.outformat="pdf";
+size(20cm);
+
+// The required data file is available here:
+// http://www.uni-graz.at/~schwaige/asymptote/worldmap.dat
+// This data was originally obtained from
+// http://www.ngdc.noaa.gov/mgg_coastline/mapit.jsp
+
+real findtheta(real phi, real epsilon=realEpsilon) {
+ // Determine for given phi the unique solution -pi/2 <= theta <= pi/2 off
+ // 2*theta+sin(2*theta)=pi*sin(phi)
+ // in the non-trivial cases by Newton iteration;
+ // theoretically the initial guess pi*sin(phi)/4 always works.
+ real nwtn(real x, real y) {return x-(2x+sin(2x)-y)/(2+2*cos(2x));};
+ real y=pi*sin(phi);
+ if(y == 0) return 0.0;
+ if(abs(y) == 1) return pi/2;
+ real startv=y/4;
+ real endv=nwtn(startv,y);
+ if(epsilon < 500*realEpsilon) epsilon=500*realEpsilon;
+ while(abs(endv-startv) > epsilon) {startv=endv; endv=nwtn(startv,y);};
+ return endv;
+}
+
+pair mollweide(real lambda, real phi, real lambda0=0){
+ // calculate the Mollweide projection centered at lambda0 for the point
+ // with coordinates(phi,lambda)
+ static real c1=2*sqrt(2)/pi;
+ static real c2=sqrt(2);
+ real theta=findtheta(phi);
+ return(c1*(lambda-lambda0)*cos(theta), c2*sin(theta));
+}
+
+guide gfrompairs(pair[] data){
+ guide gtmp;
+ for(int i=0; i < data.length; ++i) {
+ pair tmp=mollweide(radians(data[i].y),radians(data[i].x));
+ gtmp=gtmp--tmp;
+ }
+ return gtmp;
+}
+
+string datafile="worldmap.dat";
+
+file in=input(datafile,comment="/").line();
+// new commentchar since "#" is contained in the file
+pair[][] arrarrpair=new pair[][] ;
+int cnt=-1;
+bool newseg=false;
+while(true) {
+ if(eof(in)) break;
+ string str=in;
+ string[] spstr=split(str,"");
+
+ if(spstr[0] == "#") {++cnt; arrarrpair[cnt]=new pair[] ; newseg=true;}
+ if(spstr[0] != "#" && newseg) {
+ string[] spstr1=split(str,'\t'); // separator is TAB not SPACE
+ pair tmp=((real) spstr1[1],(real) spstr1[0]);
+ arrarrpair[cnt].push(tmp);
+ }
+}
+
+for(int i=0; i < arrarrpair.length; ++i)
+ draw(gfrompairs(arrarrpair[i]),1bp+black);
+
+// lines of longitude and latitude
+pair[] constlong(real lambda, int np=100) {
+ pair[] tmp;
+ for(int i=0; i <= np; ++i) tmp.push((-90+i*180/np,lambda));
+ return tmp;
+}
+
+pair[] constlat(real phi, int np=100) {
+ pair[] tmp;
+ for(int i=0; i <= 2*np; ++i) tmp.push((phi,-180+i*180/np));
+ return tmp;
+}
+
+for(int j=1; j <= 5; ++j) draw(gfrompairs(constlong(-180+j/6*360)),white);
+draw(gfrompairs(constlong(-180)),1.5bp+white);
+draw(gfrompairs(constlong(180)),1.5bp+white);
+for(int j=0; j <= 12; ++j) draw(gfrompairs(constlat(-90+j/6*180)),white);
+//draw(gfrompairs(constlong(10)),dotted);
+
+close(in);
+shipout(bbox(1mm,darkblue,Fill(lightblue)), view=true);
+
diff --git a/graphics/asymptote/examples/xsin1x.asy b/graphics/asymptote/examples/xsin1x.asy
new file mode 100644
index 0000000000..cf394efb1a
--- /dev/null
+++ b/graphics/asymptote/examples/xsin1x.asy
@@ -0,0 +1,24 @@
+import graph;
+size(300,0);
+
+real f(real x) {return (x != 0.0) ? x * sin(1.0 / x) : 0.0;}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$",red);
+yaxis(red);
+draw(graph(f,-1.2/pi,1.2/pi,1000));
+label("$x\sin\frac{1}{x}$",F(1.1/pi),NW);
+
+picture pic;
+size(pic,50,IgnoreAspect);
+xaxis(pic,red);
+yaxis(pic,red);
+draw(pic,graph(pic,f,-0.1/pi,0.1/pi,1000));
+
+add(new void(frame f, transform t) {
+ frame G=shift(point(f,N+0.85W))*align(bbox(pic,blue),10SE);
+ add(f,G);
+ draw(f,t*box(min(pic,user=true),max(pic,user=true)),blue);
+ draw(f,point(G,E)--t*point(pic,W),blue);
+ });
+
diff --git a/graphics/asymptote/examples/xstitch.asy b/graphics/asymptote/examples/xstitch.asy
new file mode 100644
index 0000000000..5f33288173
--- /dev/null
+++ b/graphics/asymptote/examples/xstitch.asy
@@ -0,0 +1,170 @@
+pair c=(0,0.8);
+
+int iters(pair z, int max=160) {
+ int n=0;
+ while(abs(z) < 2 && n < max) {
+ z=z*z+c;
+ ++n;
+ }
+ return n;
+}
+
+int[] cutoffs={12,15,20,30,40,60,200};
+int key(pair z) {
+ int i=iters(z);
+ int j=0;
+ while(cutoffs[j] < i)
+ ++j;
+ return j;
+}
+
+
+int width=210;
+int height=190;
+
+real zoom=2.5/200;
+
+int[][] values=new int[width][height];
+int[] histogram; for(int v=0; v < 10; ++v) histogram.push(0);
+for(int i=0; i < width; ++i) {
+ real x=zoom*(i-width/2);
+ for(int j=0; j < height; ++j) {
+ real y=zoom*(j-height/2);
+ int v=key((x,y));
+ values[i][j]=v;
+ ++histogram[v];
+ }
+}
+
+// Print out a histogram.
+write("histogram: ");
+write(histogram);
+
+
+pen linepen(int i, int max) {
+ real w=i == -1 || i == max+1 ? 2.0 :
+ i % 10 == 0 || i == max ? 1.0 :
+ i % 5 == 0 ? 0.8 :
+ 0.25;
+ return linewidth(w);
+}
+
+pen xpen(int i) {
+ return linepen(i,width)+(i == width/2 ? red :
+ i == 75 || i == width-75 ? dashed :
+ black);
+}
+
+pen ypen(int i) {
+ return linepen(i,height)+(i == height/2 ? red :
+ i == 75 || i == height-75 ? dashed :
+ black);
+}
+
+// The length of the side of a cross stitch cell.
+real cell=2.3mm;
+transform t=scale(cell);
+
+
+picture tick;
+draw(tick,(0,0)--(1,1));
+
+picture ell;
+draw(ell,(0,1)--(0,0)--(0.7,0));
+
+picture cross;
+draw(cross,(0,0)--(1,1));
+draw(cross,(1,0)--(0,1));
+
+picture star;
+draw(star,(0.15,0.15)--(0.85,0.85));
+draw(star,(0.85,0.15)--(0.15,0.85));
+draw(star,(.5,0)--(.5,1));
+draw(star,(0,.5)--(1,.5));
+
+picture triangle;
+draw(triangle,(0,0)--(2,0)--(1,1.5)--cycle);
+
+picture circle;
+fill(circle,shift(1,1)*unitcircle);
+
+picture ocircle;
+draw(ocircle,shift(1,1)*unitcircle);
+
+picture spare;
+fill(spare,(0,0)--(1,1)--(0,1)--cycle);
+
+picture[] pics={tick,ell,cross,star,triangle,circle};
+pen[] colors={black,0.2purple,0.4purple,0.6purple,0.8purple,purple,
+ 0.8purple+0.2white};
+
+frame[] icons;
+icons.push(newframe);
+for(picture pic : pics) {
+ // Scaling factor, so that we don't need weird line widths.
+ real X=1.0;
+ frame f=pic.fit(.8X*cell,.8X*cell,Aspect);
+ f=scale(1/X)*f;
+
+ // Center the icon in the cell.
+ f=shift((cell/2,cell/2)-0.5(max(f)-min(f)))*f;
+
+ icons.push(f);
+}
+
+void drawSection(int xmin, int xmax, int ymin, int ymax) {
+ static int shipoutNumber=0;
+
+ // Draw directly to a frame for speed reasons.
+ frame pic;
+
+ for(int i=xmin; i <= xmax; ++i) {
+ draw(pic,t*((i,ymin)--(i,ymax)),xpen(i));
+ if(i%10 == 0) {
+ label(pic,string(i),t*(i,ymin),align=S);
+ label(pic,string(i),t*(i,ymax),align=N);
+ }
+ }
+ for(int j=ymin; j <= ymax; ++j) {
+ draw(pic,t*((xmin,j)--(xmax,j)),ypen(j));
+ if(j%10 == 0) {
+ label(pic,string(j),t*(xmin,j),align=W);
+ label(pic,string(j),t*(xmax,j),align=E);
+ }
+ }
+
+ if(xmin < 0)
+ xmin=0;
+ if(xmax >= width)
+ xmax=width-1;
+ if(ymin < 0)
+ ymin=0;
+ if(ymax >= height)
+ ymax=height-1;
+
+ int stitchCount=0;
+ path box=scale(cell) *((0,0)--(1,0)--(1,1)--(0,1)--cycle);
+ for(int i=xmin; i < xmax; ++i)
+ for(int j=ymin; j < ymax; ++j) {
+ int v=values[i][j];
+ add(pic,icons[v],(i*cell,j*cell));
+ //fill(pic,shift(i*cell,j*cell)*box,colors[v]);
+ if(v != 0)
+ ++stitchCount;
+ }
+
+ write("stitch count: ",stitchCount);
+
+ // shipout("xstitch"+string(shipoutNumber),pic);
+ shipout(pic);
+ ++shipoutNumber;
+}
+
+//drawSection(-1,width+1,-1,height+1);
+
+
+//drawSection(-1,80,height-80,height+1);
+//drawSection(70,150,height-80,height+1);
+drawSection(quotient(width,2)-40,quotient(width,2)+40,quotient(height,2)-40,quotient(height,2)+40);
+//drawSection(width-150,width-70,-1,80);
+//drawSection(width-80,width+1,-1,80);
diff --git a/graphics/asymptote/examples/xxsq01.asy b/graphics/asymptote/examples/xxsq01.asy
new file mode 100644
index 0000000000..23a38393a9
--- /dev/null
+++ b/graphics/asymptote/examples/xxsq01.asy
@@ -0,0 +1,30 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(0,0,10,up=Y);
+
+pen color=green;
+real alpha=250;
+
+real f(real x) {return x^2;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=10,operator ..)--cycle;
+path3 p3=path3(p);
+
+revolution a=revolution(p3,X,-alpha,0);
+render render=render(compression=0,merge=true);
+draw(surface(a),color,render);
+surface s=surface(p);
+draw(s,color,render);
+draw(rotate(-alpha,X)*s,color,render);
+
+draw(p3,blue);
+
+xaxis3(Label("$x$",1),xmax=1.25,dashed,Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+dot(Label("$(1,1)$"),(1,1,0),X+Y);
+arrow("$y=x$",(0.7,0.7,0),Y,0.75cm,red);
+arrow("$y=x^2$",F3(0.7),X,0.75cm,red);
+draw(arc(1.1X,0.3,90,90,3,-90),Arrow3);
diff --git a/graphics/asymptote/examples/xxsq01x-1.asy b/graphics/asymptote/examples/xxsq01x-1.asy
new file mode 100644
index 0000000000..6d645a4966
--- /dev/null
+++ b/graphics/asymptote/examples/xxsq01x-1.asy
@@ -0,0 +1,35 @@
+import graph3;
+import solids;
+size(300);
+currentprojection=perspective(0,2,10,up=Y);
+currentlight=Viewport;
+
+pen color=green;
+
+real f(real x) {return x^2;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=10,operator ..)--cycle;
+path3 p3=path3(p);
+
+revolution a=revolution(-X,p3,Y,0,180);
+render render=render(merge=true);
+draw(surface(a),color);
+surface s=surface(p);
+draw(s,color);
+transform3 t=shift(-2X)*rotate(180,Y);
+draw(t*s,color);
+draw(p3);
+draw(t*p3);
+
+draw((-1,0,0)--(-1,1,0),dashed);
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+dot(Label("$(1,1)$"),(1,1,0));
+dot(Label("$(-1,1)$"),(-1,1,0),W);
+arrow("$y=x^{2}$",F3(0.7),X,1cm,red);
+arrow("$y=x$",(0.3,0.3,0),X,1.5cm,red);
+draw(circle((-1,1,0),2,Y),dashed);
+draw((-1,1,0)--(1,1,0),dashed);
+draw(shift(-X)*arc(0.02Y,0.3,90,0,0,0,CW),Arrow3);
diff --git a/graphics/asymptote/examples/xxsq01y.asy b/graphics/asymptote/examples/xxsq01y.asy
new file mode 100644
index 0000000000..770f4fc22c
--- /dev/null
+++ b/graphics/asymptote/examples/xxsq01y.asy
@@ -0,0 +1,34 @@
+import solids;
+size(0,150);
+currentprojection=perspective(0,0,10,up=Y);
+pen color=green;
+real alpha=240;
+
+real f(real x) {return x^2;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=10,operator ..)--cycle;
+path3 p3=path3(p);
+
+render render=render(compression=0,merge=true);
+
+draw(surface(revolution(p3,Y,0,alpha)),color,render);
+
+surface s=surface(p);
+draw(s,color,render);
+draw(rotate(alpha,Y)*s,color,render);
+
+draw(p3,blue);
+
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),ymax=1.25,dashed,Arrow3);
+
+dot("$(1,1)$",(1,1,0),X);
+arrow("$y=x^{2}$",F3(0.7),X,0.75cm,red);
+arrow("$y=x$",(0.8,0.8,0),Y,1cm,red);
+
+real r=0.4;
+draw((r,f(r),0)--(r,r,0),red);
+draw("$r$",(0,(f(r)+r)*0.5,0)--(r,(f(r)+r)*0.5,0),N,red,Arrows3,PenMargins3);
+draw(arc(1.1Y,0.3,90,0,7.5,180),Arrow3);
diff --git a/graphics/asymptote/examples/yingyang.asy b/graphics/asymptote/examples/yingyang.asy
new file mode 100644
index 0000000000..68b0d0eea7
--- /dev/null
+++ b/graphics/asymptote/examples/yingyang.asy
@@ -0,0 +1,7 @@
+size(0,25cm);
+guide center=(0,1){W}..tension 0.8..(0,0){(1,-.5)}..tension 0.8..{W}(0,-1);
+
+draw((0,1)..(-1,0)..(0,-1));
+filldraw(center{E}..{N}(1,0)..{W}cycle);
+unfill(circle((0,0.5),0.125));
+fill(circle((0,-0.5),0.125));
diff --git a/graphics/asymptote/exp.cc b/graphics/asymptote/exp.cc
new file mode 100644
index 0000000000..4dacff72ec
--- /dev/null
+++ b/graphics/asymptote/exp.cc
@@ -0,0 +1,1496 @@
+/*****
+ * exp.cc
+ * andy hammerlindl 2002/8/19
+ *
+ * represents the abstract syntax tree for the expressions in the
+ * language. this is translated into virtual machine code using trans()
+ * and with the aid of the environment class.
+ *****/
+
+#include "exp.h"
+#include "errormsg.h"
+#include "runtime.h"
+#include "runmath.h"
+#include "runpicture.h"
+#include "runarray.h"
+#include "runpair.h"
+#include "runtriple.h"
+#include "runpath.h"
+#include "coenv.h"
+#include "application.h"
+#include "dec.h"
+#include "stm.h"
+#include "inst.h"
+#include "opsymbols.h"
+#include "process.h"
+
+//void runCode(absyntax::block *code);
+
+namespace absyntax {
+
+using namespace types;
+using namespace trans;
+using vm::inst;
+using mem::vector;
+
+
+#if 0
+void exp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "exp",indent);
+}
+#endif
+
+void exp::transAsType(coenv &e, types::ty *target) {
+ trans(e);
+// types::ty *t=trans(e);
+// assert(t->kind==ty_error || equivalent(t,target));
+}
+
+void exp::transToType(coenv &e, types::ty *target)
+{
+ types::ty *ct=cgetType(e);
+
+ if (equivalent(target, ct)) {
+ transAsType(e, target);
+ return;
+ }
+
+ // See if the cast can be handled by the fastLookupCast method, which does
+ // less memory allocation.
+ if (ct->kind != ty_overloaded &&
+ ct->kind != ty_error &&
+ target->kind != ty_error) {
+ access *a = e.e.fastLookupCast(target, ct);
+ if (a) {
+ transAsType(e, ct);
+ a->encode(trans::CALL, getPos(), e.c);
+ return;
+ }
+ }
+
+ types::ty *source = e.e.castSource(target, ct, symbol::castsym);
+ if (source==0) {
+ if (target->kind != ty_error) {
+ types::ty *sources=cgetType(e);
+ em.error(getPos());
+
+ em << "cannot cast ";
+ if (sources->kind==ty_overloaded)
+ em << "expression";
+ else
+ em << "'" << *sources << "'";
+ em << " to '" << *target << "'";
+ }
+ }
+ else if (source->kind==ty_overloaded) {
+ if (target->kind != ty_error) {
+ em.error(getPos());
+ em << "expression is ambiguous in cast to '" << *target << "'";
+ }
+ }
+ else {
+ transAsType(e, source);
+ e.implicitCast(getPos(), target, source);
+ }
+}
+
+void exp::testCachedType(coenv &e) {
+ if (ct != 0) {
+ types::ty *t = getType(e);
+ if (!equivalent(t, ct)) {
+ em.compiler(getPos());
+ em << "cached type '" << *ct
+ << "' doesn't match actual type '" << *t << "'";
+ em.sync();
+ }
+ }
+}
+
+void exp::transCall(coenv &e, types::ty *target)
+{
+ transAsType(e, target);
+ e.c.encode(inst::popcall);
+}
+
+void exp::transConditionalJump(coenv &e, bool cond, label dest) {
+ transToType(e, primBoolean());
+ e.c.useLabel(cond ? inst::cjmp : inst::njmp, dest);
+}
+
+exp *exp::evaluate(coenv &e, types::ty *target) {
+ return new tempExp(e, this, target);
+}
+
+
+tempExp::tempExp(coenv &e, varinit *v, types::ty *t)
+ : exp(v->getPos()), a(e.c.allocLocal()), t(t)
+{
+ v->transToType(e, t);
+ a->encode(WRITE, getPos(), e.c);
+ e.c.encodePop();
+}
+
+void tempExp::prettyprint(ostream &out, Int indent) {
+ prettyname(out, "tempExp", indent);
+}
+
+types::ty *tempExp::trans(coenv &e) {
+ a->encode(READ, getPos(), e.c);
+ return t;
+}
+
+
+varEntryExp::varEntryExp(position pos, types::ty *t, access *a)
+ : exp(pos), v(new trans::varEntry(t, a, 0, position())) {}
+varEntryExp::varEntryExp(position pos, types::ty *t, vm::bltin f)
+ : exp(pos), v(new trans::varEntry(t, new bltinAccess(f), 0, position())) {}
+
+void varEntryExp::prettyprint(ostream &out, Int indent) {
+ prettyname(out, "varEntryExp", indent);
+}
+
+types::ty *varEntryExp::getType(coenv &) {
+ return v->getType();
+}
+
+types::ty *varEntryExp::trans(coenv &e) {
+ v->encode(READ, getPos(), e.c);
+ return getType(e);
+}
+
+trans::varEntry *varEntryExp::getCallee(coenv &e, types::signature *sig) {
+ return equivalent(sig, v->getType()->getSignature()) ? v : 0;
+}
+
+void varEntryExp::transAct(action act, coenv &e, types::ty *target) {
+ assert(equivalent(getType(e),target));
+ v->encode(act, getPos(), e.c);
+}
+void varEntryExp::transAsType(coenv &e, types::ty *target) {
+ transAct(READ, e, target);
+}
+void varEntryExp::transWrite(coenv &e, types::ty *target, exp *value) {
+ value->transToType(e, target);
+ transAct(WRITE, e, target);
+}
+void varEntryExp::transCall(coenv &e, types::ty *target) {
+ transAct(trans::CALL, e, target);
+}
+
+
+void nameExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nameExp",indent);
+
+ value->prettyprint(out, indent+1);
+}
+
+
+void fieldExp::pseudoName::prettyprint(ostream &out, Int indent)
+{
+ // This should never be called.
+ prettyindent(out, indent);
+ out << "pseudoName" << "\n";
+
+ object->prettyprint(out, indent+1);
+}
+
+void fieldExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fieldExp '" << field << "'\n";
+
+ object->prettyprint(out, indent+1);
+}
+
+types::ty *fieldExp::getObject(coenv& e)
+{
+ types::ty *t = object->cgetType(e);
+ if (t->kind == ty_overloaded) {
+ t=((overloaded *)t)->signatureless();
+ if(!t) return primError();
+ }
+ return t;
+}
+
+
+array *arrayExp::getArrayType(coenv &e)
+{
+ types::ty *a = set->cgetType(e);
+ if (a->kind == ty_overloaded) {
+ a = ((overloaded *)a)->signatureless();
+ if (!a)
+ return 0;
+ }
+
+ switch (a->kind) {
+ case ty_array:
+ return (array *)a;
+ case ty_error:
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+array *arrayExp::transArray(coenv &e)
+{
+ types::ty *a = set->cgetType(e);
+ if (a->kind == ty_overloaded) {
+ a = ((overloaded *)a)->signatureless();
+ if (!a) {
+ em.error(set->getPos());
+ em << "expression is not an array";
+ return 0;
+ }
+ }
+
+ set->transAsType(e, a);
+
+ switch (a->kind) {
+ case ty_array:
+ return (array *)a;
+ case ty_error:
+ return 0;
+ default:
+ em.error(set->getPos());
+ em << "expression is not an array";
+ return 0;
+ }
+}
+
+// Checks if the expression can be translated as an array.
+bool isAnArray(coenv &e, exp *x)
+{
+ types::ty *t=x->cgetType(e);
+ if (t->kind == ty_overloaded)
+ t=dynamic_cast<overloaded *>(t)->signatureless();
+ return t && t->kind==ty_array;
+}
+
+
+void subscriptExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "subscriptExp\n";
+
+ set->prettyprint(out, indent+1);
+ index->prettyprint(out, indent+1);
+}
+
+types::ty *subscriptExp::trans(coenv &e)
+{
+ array *a = transArray(e);
+ if (!a)
+ return primError();
+
+ if (isAnArray(e, index)) {
+ index->transToType(e, types::IntArray());
+ e.c.encode(inst::builtin, run::arrayIntArray);
+ return getArrayType(e);
+ }
+ else {
+ index->transToType(e, types::primInt());
+ e.c.encode(inst::builtin,
+ a->celltype->kind==ty_array ? run::arrayArrayRead :
+ run::arrayRead);
+ return a->celltype;
+ }
+}
+
+types::ty *subscriptExp::getType(coenv &e)
+{
+ array *a = getArrayType(e);
+ return a ? (isAnArray(e, index) ? a : a->celltype) :
+ primError();
+}
+
+void subscriptExp::transWrite(coenv &e, types::ty *t, exp *value)
+{
+ // Put array, index, and value on the stack in that order, then call
+ // arrayWrite.
+ array *a = transArray(e);
+ if (!a)
+ return;
+
+ if (!equivalent(a->celltype, t))
+ {
+ em.error(getPos());
+ em << "array expression cannot be used as an address";
+
+ // Translate the value for errors.
+ value->transToType(e, t);
+ return;
+ }
+
+ index->transToType(e, types::primInt());
+
+ value->transToType(e, t);
+
+ e.c.encode(inst::builtin, run::arrayWrite);
+}
+
+
+void slice::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "slice", indent);
+ if (left)
+ left->prettyprint(out, indent+1);
+ else
+ prettyname(out, "left omitted", indent+1);
+ if (right)
+ right->prettyprint(out, indent+1);
+ else
+ prettyname(out, "right omitted", indent+1);
+}
+
+void slice::trans(coenv &e)
+{
+ if (left)
+ left->transToType(e, types::primInt());
+ else
+ // If the left index is omitted it can be assumed to be zero.
+ e.c.encode(inst::intpush, (Int)0);
+
+ if (right)
+ right->transToType(e, types::primInt());
+}
+
+
+void sliceExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "sliceExp", indent);
+ set->prettyprint(out, indent+1);
+ index->prettyprint(out, indent+1);
+}
+
+types::ty *sliceExp::trans(coenv &e)
+{
+ array *a = transArray(e);
+ if (!a)
+ return primError();
+
+ index->trans(e);
+
+ e.c.encode(inst::builtin, index->getRight() ? run::arraySliceRead :
+ run::arraySliceReadToEnd);
+
+ return a;
+}
+
+types::ty *sliceExp::getType(coenv &e)
+{
+ array *a = getArrayType(e);
+ return a ? a : primError();
+}
+
+void sliceExp::transWrite(coenv &e, types::ty *t, exp *value)
+{
+ array *a = transArray(e);
+ if (!a)
+ return;
+ assert(equivalent(a, t));
+
+ index->trans(e);
+
+ value->transToType(e, t);
+
+ e.c.encode(inst::builtin, index->getRight() ? run::arraySliceWrite :
+ run::arraySliceWriteToEnd);
+}
+
+void thisExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "thisExp", indent);
+}
+
+types::ty *thisExp::trans(coenv &e)
+{
+ if (!e.c.encodeThis()) {
+ em.error(getPos());
+ em << "static use of 'this' expression";
+ }
+ return cgetType(e);
+}
+
+types::ty *thisExp::getType(coenv &e)
+{
+ return e.c.thisType();
+}
+
+void equalityExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "equalityExp", indent);
+ callExp::prettyprint(out, indent+1);
+}
+
+types::ty *equalityExp::getType(coenv &e) {
+ // Try to the resolve the expression as a function call first.
+ types::ty *t = callExp::getType(e);
+ assert(t);
+ if (t->kind != ty_error)
+ return t;
+ else
+ // Either an error or handled by the function equality methods. In the
+ // first case, we may return whatever we like, and the second case always
+ // returns bool. In either case, it is safe to return bool.
+ return primBoolean();
+}
+
+// From a possibly overloaded type, if there is a unique function type, return
+// it, otherwise 0.
+types::ty *uniqueFunction(types::ty *t) {
+ if (t->kind == types::ty_function)
+ return t;
+
+ if (t->isOverloaded()) {
+ types::ty *ft = 0;
+ for (ty_iterator i = t->begin(); i != t->end(); ++i)
+ {
+ if ((*i)->kind != types::ty_function)
+ continue;
+
+ if (ft) {
+ // Multiple function types.
+ return 0;
+ }
+
+ ft = *i;
+ }
+
+ return ft;
+ }
+
+ // Not a function.
+ return 0;
+}
+
+// From two possibly overloaded types, if there is a unique function type
+// common to both, return it, otherwise 0.
+types::ty *uniqueFunction(types::ty *t1, types::ty *t2) {
+ if (t1->kind == types::ty_function)
+ return equivalent(t1, t2) ? t1 : 0;
+
+ if (t1->isOverloaded()) {
+ types::ty *ft = 0;
+ for (ty_iterator i = t1->begin(); i != t1->end(); ++i)
+ {
+ if ((*i)->kind != types::ty_function)
+ continue;
+
+ if (!equivalent(*i, t2))
+ continue;
+
+ if (ft) {
+ // Multiple function types.
+ return 0;
+ }
+
+ ft = *i;
+ }
+
+ return ft;
+ }
+
+ // Not a function.
+ return 0;
+}
+
+bltin bltinFromName(symbol name) {
+ if (name == SYM_EQ)
+ return run::boolFuncEq;
+ assert(name == SYM_NEQ);
+ return run::boolFuncNeq;
+}
+
+types::ty *equalityExp::trans(coenv &e) {
+ // First, try to handle by normal function resolution.
+ types::ty *t = callExp::getType(e);
+ assert(t);
+ if (t->kind != ty_error)
+ return callExp::trans(e);
+
+ // Then, check for the function equality case.
+ exp *left = (*this->args)[0].val;
+ exp *right = (*this->args)[1].val;
+
+ types::ty *lt = left->getType(e);
+ types::ty *rt = right->getType(e);
+
+ // TODO: decide what null == null should do.
+
+ // Check for function == null and null == function
+ types::ty *ft = 0;
+ if (rt->kind == types::ty_null)
+ ft = uniqueFunction(lt);
+ else if (lt->kind == types::ty_null)
+ ft = uniqueFunction(rt);
+ else
+ ft = uniqueFunction(lt, rt);
+
+
+ if (ft) {
+ assert(ft->kind == ty_function);
+
+ left->transToType(e, ft);
+ right->transToType(e, ft);
+ e.c.encode(inst::builtin, bltinFromName(callee->getName()));
+
+ return primBoolean();
+ } else {
+ // Let callExp report a "no such function" error.
+ types::ty *t = callExp::trans(e);
+ assert(t->kind == ty_error);
+ return t;
+ }
+}
+
+void scaleExp::prettyprint(ostream &out, Int indent)
+{
+ exp *left=getLeft(); exp *right=getRight();
+
+ prettyname(out, "scaleExp",indent);
+ left->prettyprint(out, indent+1);
+ right->prettyprint(out, indent+1);
+}
+
+types::ty *scaleExp::trans(coenv &e)
+{
+ exp *left=getLeft(); exp *right=getRight();
+
+ types::ty *lt = left->cgetType(e);
+ if (lt->kind != types::ty_Int && lt->kind != types::ty_real) {
+ if (lt->kind != types::ty_error) {
+ em.error(left->getPos());
+ em << "only numeric constants can do implicit scaling";
+ }
+ right->trans(e);
+ return types::primError();
+ }
+
+ if (!right->scalable()) {
+ em.warning(right->getPos());
+ em << "implicit scaling may be unintentional";
+ }
+
+ // Defer to the binaryExp for multiplication.
+ return binaryExp::trans(e);
+}
+
+
+void intExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "intExp: " << value << "\n";
+}
+
+types::ty *intExp::trans(coenv &e)
+{
+ e.c.encode(inst::intpush,value);
+
+ return types::primInt();
+}
+
+
+void realExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "realExp: " << value << "\n";
+}
+
+types::ty *realExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item)value);
+
+ return types::primReal();
+}
+
+void stringExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "stringExp '" << str << "'\n";
+}
+
+types::ty *stringExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item) string(str));
+
+ return types::primString();
+}
+
+
+void booleanExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "booleanExp: " << value << "\n";
+}
+
+types::ty *booleanExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item)value);
+
+ return types::primBoolean();
+}
+
+void newPictureExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "newPictureExp",indent);
+}
+
+types::ty *newPictureExp::trans(coenv &e)
+{
+ e.c.encode(inst::builtin, run::newPicture);
+
+ return types::primPicture();
+}
+
+void cycleExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "cycleExp",indent);
+}
+
+types::ty *cycleExp::trans(coenv &e)
+{
+ e.c.encode(inst::builtin, run::newCycleToken);
+
+ return types::primCycleToken();
+}
+
+void nullPathExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nullPathExp",indent);
+}
+
+types::ty *nullPathExp::trans(coenv &e)
+{
+ e.c.encode(inst::builtin, run::nullPath);
+
+ return types::primPath();
+}
+
+void nullExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nullExp",indent);
+}
+
+types::ty *nullExp::trans(coenv &)
+{
+ // Things get put on the stack when ty_null
+ // is cast to an appropriate type
+ return types::primNull();
+}
+
+
+void quoteExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "quoteExp", indent);
+ value->prettyprint(out, indent+1);
+}
+
+types::ty *quoteExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item)value);
+
+ return types::primCode();
+}
+
+void explist::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "explist",indent);
+ for (expvector::iterator p = exps.begin();
+ p != exps.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+
+void argument::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "explist";
+ if (name)
+ out << " '" << name << "'";
+ out << '\n';
+
+ val->prettyprint(out, indent+1);
+}
+
+void arglist::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "arglist",indent);
+ for (argvector::iterator p = args.begin();
+ p != args.end(); ++p)
+ p->prettyprint(out, indent+1);
+}
+
+void callExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "callExp",indent);
+
+ callee->prettyprint(out, indent+1);
+ args->prettyprint(out, indent+1);
+}
+
+signature *callExp::argTypes(coenv &e, bool *searchable)
+{
+ signature *source=new signature;
+
+ // The signature is searchable unless one of the arguments is overloaded or
+ // named.
+ *searchable = true;
+
+ size_t n = args->size();
+
+ for (size_t i = 0; i < n; i++) {
+ if(string(args->args[i].name) == "KEY") {
+ stringExp *s=dynamic_cast<stringExp*>(args->args[i].val);
+ if(s) {
+ if(getPos().filename() == processData().fileName)
+ processData().xkey[getPos().LineColumn()]=Strdup(s->getString());
+ args->args.erase(args->args.begin()+i);
+ --n;
+ if(i == n) break;
+ }
+ }
+
+ argument a=(*args)[i];
+ types::ty *t = a.val->cgetType(e);
+ if (t->kind == types::ty_error)
+ return 0;
+ if (t->kind == types::ty_overloaded || a.name)
+ *searchable = false;
+ source->add(types::formal(t,a.name));
+ }
+
+ if (args->rest.val) {
+ argument a=args->rest;
+ types::ty *t = a.val->cgetType(e);
+ if (t->kind == types::ty_error)
+ return 0;
+ if (t->kind == types::ty_overloaded || a.name)
+ *searchable = false;
+ source->addRest(types::formal(t,a.name));
+ }
+
+ return source;
+}
+
+application *callExp::resolve(coenv &e, overloaded *o, signature *source,
+ bool tacit) {
+ app_list l=multimatch(e.e, o, source, *args);
+
+ if (l.empty()) {
+ //cerr << "l is empty\n";
+ if (!tacit) {
+ em.error(getPos());
+
+ symbol s = callee->getName();
+ if (s)
+ em << "no matching function \'" << s;
+ else
+ em << "no matching function for signature \'";
+ em << *source << "\'";
+ }
+
+ return 0;
+ }
+ else if (l.size() > 1) { // This may take O(n) time.
+ //cerr << "l is full\n";
+ if (!tacit) {
+ em.error(getPos());
+
+ symbol s = callee->getName();
+ if(s)
+ em << "call of function \'" << s;
+ else
+ em << "call with signature \'";
+ em << *source << "\' is ambiguous";
+ }
+
+ return 0;
+ }
+ else {
+ //cerr << "l is singleton\n";
+ return l.front();
+ }
+}
+
+bool hasNamedParameters(signature *sig) {
+ for (size_t i=0; i < sig->getNumFormals(); ++i)
+ if (sig->getFormal(i).name)
+ return true;
+ return false;
+}
+
+void callExp::reportMismatch(function *ft, signature *source)
+{
+ symbol s = callee->getName();
+ const char *separator=ft->getSignature()->getNumFormals() > 1 ? "\n" : " ";
+
+ em.error(getPos());
+ em << "cannot call" << separator << "'" << *ft->getResult() << " ";
+ if(s)
+ em << s;
+ em << *ft->getSignature() << "'" << separator;
+
+ if (ft->getSignature()->isOpen && hasNamedParameters(source))
+ em << "with named parameters";
+ else
+ switch(source->getNumFormals()) {
+ case 0:
+ em << "without parameters";
+ break;
+ case 1:
+ em << "with parameter '" << *source << "'";
+ break;
+ default:
+ em << "with parameters\n'" << *source << "'";
+ }
+}
+
+void callExp::reportArgErrors(coenv &e)
+{
+ // Cycle through the parameters to report all errors.
+ // NOTE: This may report inappropriate ambiguity errors.
+ for (size_t i = 0; i < args->size(); i++) {
+ (*args)[i].val->trans(e);
+ }
+ if (args->rest.val)
+ args->rest.val->trans(e);
+}
+
+void callExp::reportNonFunction() {
+ em.error(getPos());
+ symbol s = callee->getName();
+ if (s)
+ em << "\'" << s << "\' is not a function";
+ else
+ em << "called expression is not a function";
+}
+
+types::ty *callExp::cacheAppOrVarEntry(coenv &e, bool tacit)
+{
+ assert(cachedVarEntry == 0 && cachedApp == 0);
+
+ // First figure out the signature of what we want to call.
+ bool searchable;
+ signature *source=argTypes(e, &searchable);
+
+#ifdef DEBUG_GETAPP /* {{{ */
+ cout << "getApp for ";
+ if (callee->getName())
+ cout << *callee->getName();
+ else
+ cout << "unnamed";
+ cout << " at " << getPos() << endl;
+ cout << "searchable: " << searchable << endl;
+#endif /* }}} */
+
+ if (!source) {
+ return primError();
+ }
+
+ // An attempt at speeding up compilation: See if the source arguments match
+ // the (possibly overloaded) function exactly.
+ if (searchable) {
+ varEntry *ve = callee->getCallee(e, source);
+
+#ifdef DEBUG_GETAPP
+ cout << "guessed: " << (ve!=0) << endl;
+#endif
+
+ if (ve) {
+ cachedVarEntry = ve;
+#ifndef DEBUG_CACHE
+ // Normally DEBUG_CACHE is not defined and we return here for efficiency
+ // reasons. If DEBUG_CACHE is defined, we instead proceed to resolve
+ // the function by the normal techniques and make sure we get the same
+ // result.
+ return ((function *)ve->getType())->getResult();
+#endif
+ }
+ }
+
+ // Figure out what function types we can call.
+ types::ty *ft = callee->cgetType(e);
+
+#ifdef DEBUG_GETAPP
+ string name = callee->getName() ? string(*callee->getName()) :
+ string("unnamed");
+ if (!callee->getName())
+ cout << getPos() << endl;
+#endif
+
+ switch (ft->kind) {
+ case ty_error:
+ if (!tacit)
+ // Report callee errors.
+ callee->trans(e);
+ break;
+
+ case ty_function:
+ //cout << "name " << name << endl;
+ cachedApp = application::match(e.e, (function *)ft, source, *args);
+ if (!cachedApp && !tacit)
+ reportMismatch((function *)ft, source);
+ break;
+
+ case ty_overloaded: {
+#ifdef DEBUG_GETAPP
+ int size = ((overloaded *)ft)->sub.size();
+ for (int i = 0; i < size; ++i) cout << "name " << name << endl;
+#endif
+ cachedApp = resolve(e, (overloaded *)ft, source, tacit);
+ break;
+ }
+
+ default:
+ if (!tacit)
+ reportNonFunction();
+ break;
+ }
+
+#ifdef DEBUG_GETAPP
+ cout << name << " " << *source << " --> "
+ << *cachedApp->getType()->getSignature() << endl;
+#endif
+
+#if DEBUG_CACHE
+ // Make sure cachedVarEntry is giving us the right function.
+ if (cachedVarEntry)
+ assert(equivalent(cachedVarEntry->getType(), cachedApp->getType()));
+#endif
+
+ // getType relies on this method for the type.
+ return cachedApp ? cachedApp->getType()->getResult() : primError();
+}
+
+types::ty *callExp::transPerfectMatch(coenv &e) {
+ // The varEntry of the callee. (No longer needed after translation.)
+ varEntry *ve = cachedVarEntry;
+ cachedVarEntry = 0;
+ assert(ve);
+
+ // Translate the arguments in turn.
+ for (size_t i = 0; i < args->size(); ++i)
+ (*args)[i].val->trans(e);
+ if (args->rest.val)
+ args->rest.val->trans(e);
+
+ // Call the function.
+ ve->encode(trans::CALL, getPos(), e.c);
+
+ // That's it. Return the return type of the function.
+ return ct ? ct : dynamic_cast<function *>(ve->getType())->getResult();
+}
+
+types::ty *callExp::trans(coenv &e)
+{
+ if (cachedVarEntry == 0 && cachedApp == 0)
+ cacheAppOrVarEntry(e, false);
+
+ if (cachedVarEntry)
+ return transPerfectMatch(e);
+
+ // The cached data is no longer needed after translation, so let it be
+ // garbage collected.
+ application *a = cachedApp;
+ cachedApp=0;
+
+ if (!a) {
+ reportArgErrors(e);
+ return primError();
+ }
+
+ // To simulate left-to-right order of evaluation, produce the
+ // side-effects for the callee.
+ assert(a);
+ function *t=a->getType();
+ assert(t);
+ exp *temp=callee->evaluate(e, t);
+
+ // Let the application handle the argument translation.
+ a->transArgs(e);
+
+ // Translate the call.
+ temp->transCall(e, t);
+
+ return t->result;
+}
+
+types::ty *callExp::getType(coenv &e)
+{
+ if (cachedApp)
+ return cachedApp->getType()->getResult();
+ if (cachedVarEntry) {
+ function *ft = dynamic_cast<function *>(cachedVarEntry->getType());
+ assert(ft);
+ return ft->getResult();
+ }
+ return cacheAppOrVarEntry(e, true);
+}
+
+bool callExp::resolved(coenv &e) {
+ if (cachedApp == 0 && cachedVarEntry == 0)
+ cacheAppOrVarEntry(e, true);
+ return cachedApp || cachedVarEntry;
+}
+
+
+void pairExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "pairExp",indent);
+
+ x->prettyprint(out, indent+1);
+ y->prettyprint(out, indent+1);
+}
+
+types::ty *pairExp::trans(coenv &e)
+{
+ x->transToType(e, types::primReal());
+ y->transToType(e, types::primReal());
+
+ e.c.encode(inst::builtin, run::realRealToPair);
+
+ return types::primPair();
+}
+
+void tripleExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "tripleExp",indent);
+
+ x->prettyprint(out, indent+1);
+ y->prettyprint(out, indent+1);
+ z->prettyprint(out, indent+1);
+}
+
+types::ty *tripleExp::trans(coenv &e)
+{
+ x->transToType(e, types::primReal());
+ y->transToType(e, types::primReal());
+ z->transToType(e, types::primReal());
+
+ e.c.encode(inst::builtin, run::realRealRealToTriple);
+
+ return types::primTriple();
+}
+
+void transformExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "transformExp",indent);
+
+ x->prettyprint(out, indent+1);
+ y->prettyprint(out, indent+1);
+ xx->prettyprint(out, indent+1);
+ xy->prettyprint(out, indent+1);
+ yx->prettyprint(out, indent+1);
+ yy->prettyprint(out, indent+1);
+}
+
+types::ty *transformExp::trans(coenv &e)
+{
+ x->transToType(e, types::primReal());
+ y->transToType(e, types::primReal());
+ xx->transToType(e, types::primReal());
+ xy->transToType(e, types::primReal());
+ yx->transToType(e, types::primReal());
+ yy->transToType(e, types::primReal());
+
+ e.c.encode(inst::builtin, run::real6ToTransform);
+
+ return types::primTransform();
+}
+
+void castExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "castExp",indent);
+
+ target->prettyprint(out, indent+1);
+ castee->prettyprint(out, indent+1);
+}
+
+types::ty *castExp::tryCast(coenv &e, types::ty *t, types::ty *s,
+ symbol csym)
+{
+ types::ty *ss=e.e.castSource(t, s, csym);
+ if (ss == 0) {
+ return 0;
+ }
+ if (ss->kind == ty_overloaded) {
+ em.error(getPos());
+ em << "cast is ambiguous";
+ return primError();
+ }
+ else {
+ castee->transAsType(e, ss);
+
+ access *a=e.e.lookupCast(t, ss, csym);
+ assert(a);
+ a->encode(trans::CALL, getPos(), e.c);
+ return ss;
+ }
+}
+
+types::ty *castExp::trans(coenv &e)
+{
+ target->addOps(e, (record *)0);
+ types::ty *t=target->trans(e);
+
+ types::ty *s=castee->cgetType(e);
+
+ if (!tryCast(e, t, s, symbol::ecastsym))
+ if (!tryCast(e, t, s, symbol::castsym)) {
+ em.error(getPos());
+ em << "cannot cast '" << *s << "' to '" << *t << "'";
+ }
+
+ return t;
+}
+
+types::ty *castExp::getType(coenv &e)
+{
+ return target->trans(e, true);
+}
+
+
+void conditionalExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "conditionalExp",indent);
+
+ test->prettyprint(out, indent+1);
+ onTrue->prettyprint(out, indent+1);
+ onFalse->prettyprint(out, indent+1);
+}
+
+void conditionalExp::baseTransToType(coenv &e, types::ty *target) {
+ test->transToType(e, types::primBoolean());
+
+ label tlabel = e.c.fwdLabel();
+ e.c.useLabel(inst::cjmp,tlabel);
+
+ onFalse->transToType(e, target);
+
+ label end = e.c.fwdLabel();
+ e.c.useLabel(inst::jmp,end);
+
+ e.c.defLabel(tlabel);
+ onTrue->transToType(e, target);
+
+ e.c.defLabel(end);
+}
+
+void conditionalExp::transToType(coenv &e, types::ty *target)
+{
+ if (isAnArray(e, test)) {
+ if (target->kind != ty_array) {
+ em.error(getPos());
+ em << "cannot cast vectorized conditional to '" << *target << "'";
+ }
+ test->transToType(e, types::booleanArray());
+ onTrue->transToType(e, target);
+ onFalse->transToType(e, target);
+ e.c.encode(inst::builtin, run::arrayConditional);
+ }
+ else {
+ baseTransToType(e, target);
+ }
+}
+
+types::ty *promote(coenv &e, types::ty *x, types::ty *y)
+{
+ struct promoter : public collector {
+ env &e;
+
+ promoter(env &e)
+ : e(e) {}
+
+ types::ty *both (types::ty *x, types::ty *y) {
+ overloaded *o=new overloaded;
+ o->add(x); o->add(y);
+ return o;
+ }
+
+ types::ty *base (types::ty *x, types::ty *y) {
+ if (equivalent(x,y))
+ return x;
+ else {
+ bool castToFirst=e.castable(x, y, symbol::castsym);
+ bool castToSecond=e.castable(y, x, symbol::castsym);
+
+ return (castToFirst && castToSecond) ? both(x,y) :
+ castToFirst ? x :
+ castToSecond ? y :
+ 0;
+ }
+ }
+ };
+
+ promoter p(e.e);
+ return p.collect(x,y);
+}
+
+types::ty *conditionalExp::trans(coenv &e)
+{
+ types::ty *tt=onTrue->cgetType(e);
+ types::ty *ft=onFalse->cgetType(e);
+
+ if (tt->kind==ty_error)
+ return onTrue->trans(e);
+ if (ft->kind==ty_error)
+ return onFalse->trans(e);
+
+ types::ty *t=promote(e, tt, ft);
+ if (!t) {
+ em.error(getPos());
+ em << "types in conditional expression do not match";
+ return primError();
+ }
+ else if (t->kind == ty_overloaded) {
+ em.error(getPos());
+ em << "type of conditional expression is ambiguous";
+ return primError();
+ }
+
+ transToType(e,t);
+ return t;
+}
+
+types::ty *conditionalExp::getType(coenv &e)
+{
+ types::ty *tt=onTrue->cgetType(e);
+ types::ty *ft=onFalse->cgetType(e);
+ if (tt->kind==ty_error || ft->kind==ty_error)
+ return primError();
+
+ types::ty *t = promote(e, tt, ft);
+ return t ? t : primError();
+}
+
+
+void orExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "orExp", indent);
+
+ left->prettyprint(out, indent+1);
+ right->prettyprint(out, indent+1);
+}
+
+types::ty *orExp::trans(coenv &e)
+{
+ // a || b
+ // translates into
+ // a ? true : b
+ booleanExp be(pos, true);
+ conditionalExp ce(pos, left, &be, right);
+ ce.baseTransToType(e, primBoolean());
+
+ return getType(e);
+}
+
+void orExp::transConditionalJump(coenv &e, bool cond, label dest)
+{
+ if (cond == true) {
+ left->transConditionalJump(e, true, dest);
+ right->transConditionalJump(e, true, dest);
+ } else { /* cond == false */
+ label end = e.c.fwdLabel();
+
+ left->transConditionalJump(e, true, end);
+ right->transConditionalJump(e, false, dest);
+
+ e.c.defLabel(end);
+ }
+}
+
+
+void andExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "andExp", indent);
+
+ left->prettyprint(out, indent+1);
+ right->prettyprint(out, indent+1);
+}
+
+types::ty *andExp::trans(coenv &e)
+{
+ // a && b
+ // translates into
+ // a ? b : false
+ booleanExp be(pos, false);
+ conditionalExp ce(pos, left, right, &be);
+ ce.baseTransToType(e, primBoolean());
+
+ return getType(e);
+}
+
+void andExp::transConditionalJump(coenv &e, bool cond, label dest)
+{
+ if (cond == true) {
+ label end = e.c.fwdLabel();
+
+ left->transConditionalJump(e, false, end);
+ right->transConditionalJump(e, true, dest);
+
+ e.c.defLabel(end);
+ } else { /* cond == false */
+ left->transConditionalJump(e, false, dest);
+ right->transConditionalJump(e, false, dest);
+ }
+}
+
+void joinExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "joinExp",indent);
+
+ callee->prettyprint(out, indent+1);
+ args->prettyprint(out, indent+1);
+}
+
+
+void specExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "specExp '" << op << "' "
+ << (s==camp::OUT ? "out" :
+ s==camp::IN ? "in" :
+ "invalid side") << '\n';
+
+ arg->prettyprint(out, indent+1);
+}
+
+types::ty *specExp::trans(coenv &e)
+{
+ intExp ie(getPos(), (Int)s);
+ binaryExp be(getPos(), arg, op, &ie);
+ return be.trans(e);
+}
+
+types::ty *specExp::getType(coenv &e)
+{
+ intExp ie(getPos(), (Int)s);
+ binaryExp be(getPos(), arg, op, &ie);
+ return be.cgetType(e);
+}
+
+void assignExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "assignExp",indent);
+
+ dest->prettyprint(out, indent+1);
+ value->prettyprint(out, indent+1);
+}
+
+void assignExp::transAsType(coenv &e, types::ty *target)
+{
+#if 0
+ // For left-to-right order, we have to evaluate the side-effects of the
+ // destination first.
+ exp *temp=dest->evaluate(e, target);
+ ultimateValue(temp)->transToType(e, target);
+ temp->transWrite(e, target);
+#endif
+
+ // All of the heavy work is handled by transWrite.
+ dest->transWrite(e, target, value);
+}
+
+types::ty *assignExp::trans(coenv &e)
+{
+ exp *uvalue=ultimateValue(dest);
+ types::ty *lt = dest->cgetType(e), *rt = uvalue->cgetType(e);
+
+ if (lt->kind == ty_error)
+ return dest->trans(e);
+ if (rt->kind == ty_error)
+ return uvalue->trans(e);
+
+ types::ty *t = e.e.castTarget(lt, rt, symbol::castsym);
+ if (!t) {
+ em.error(getPos());
+ em << "cannot convert '" << *rt << "' to '" << *lt << "' in assignment";
+ return primError();
+ }
+ else if (t->kind == ty_overloaded) {
+ em.error(getPos());
+ em << "assignment is ambiguous";
+ return primError();
+ }
+ else {
+ transAsType(e, t);
+ return t;
+ }
+}
+
+types::ty *assignExp::getType(coenv &e)
+{
+ types::ty *lt = dest->cgetType(e), *rt = ultimateValue(dest)->cgetType(e);
+ if (lt->kind==ty_error || rt->kind==ty_error)
+ return primError();
+ types::ty *t = e.e.castTarget(lt, rt, symbol::castsym);
+
+ return t ? t : primError();
+}
+
+
+void selfExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "selfExp '" << op << "'\n";
+
+ dest->prettyprint(out, indent+1);
+ value->prettyprint(out, indent+1);
+}
+
+void selfExp::transAsType(coenv &e, types::ty *target)
+{
+ // Create a temp expression for the destination, so it is not evaluated
+ // twice.
+ exp *temp=dest->evaluate(e, target);
+ temp->transWrite(e, target, ultimateValue(temp));
+}
+
+void prefixExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "prefixExp '" << op << "'\n";
+
+ dest->prettyprint(out, indent+1);
+}
+
+types::ty *prefixExp::trans(coenv &e)
+{
+ // Convert into the operation and the assign.
+ // NOTE: This can cause multiple evaluations.
+ intExp ie(getPos(), 1);
+ selfExp se(getPos(), dest, op, &ie);
+
+ return se.trans(e);
+}
+
+types::ty *prefixExp::getType(coenv &e)
+{
+ // Convert into the operation and the assign.
+ intExp ie(getPos(), 1);
+ selfExp se(getPos(), dest, op, &ie);
+
+ return se.getType(e);
+}
+
+void postfixExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "postfixExp <illegal> '" << op << "'\n";
+
+ dest->prettyprint(out, indent+1);
+}
+
+types::ty *postfixExp::trans(coenv &)
+{
+ em.error(getPos());
+ em << "postfix expressions are not allowed";
+ return primError();
+}
+
+
+} // namespace absyntax
+
diff --git a/graphics/asymptote/exp.h b/graphics/asymptote/exp.h
new file mode 100644
index 0000000000..af24523b6d
--- /dev/null
+++ b/graphics/asymptote/exp.h
@@ -0,0 +1,1101 @@
+/*****
+ * exp.h
+ * Andy Hammerlindl 2002/8/19
+ *
+ * Represents the abstract syntax tree for the expressions in the
+ * language. this is translated into virtual machine code using trans()
+ * and with the aid of the environment class.
+ *****/
+
+#ifndef EXP_H
+#define EXP_H
+
+#include "types.h"
+#include "symbol.h"
+#include "absyn.h"
+#include "varinit.h"
+#include "name.h"
+#include "guideflags.h"
+
+namespace trans {
+class coenv;
+class coder;
+
+struct label_t;
+typedef label_t *label;
+
+class application;
+}
+
+namespace absyntax {
+
+using trans::coenv;
+using trans::label;
+using trans::application;
+using trans::access;
+using sym::symbol;
+using types::record;
+using types::array;
+
+class exp : public varinit {
+protected:
+ // The cached type (from a call to cgetType).
+ types::ty *ct;
+public:
+ exp(position pos)
+ : varinit(pos), ct(0) {}
+
+ void prettyprint(ostream &out, Int indent) = 0;
+
+ // When reporting errors with function calls, it is nice to say "no
+ // function f(int)" instead of "no function matching signature
+ // (int)." Hence, this method returns the name of the expression if
+ // there is one.
+ virtual symbol getName()
+ {
+ return symbol::nullsym;
+ }
+
+ // Checks if the expression can be used as the right side of a scale
+ // expression. ie. 3sin(x)
+ // If a "non-scalable" expression is scaled a warning is issued.
+ virtual bool scalable() { return true; }
+
+ // Specifies if the value of the expression should be written to interactive
+ // prompt if typed as a stand-alone expression. For example:
+ // > 2+3;
+ // should write 5, but
+ // > x=2+3;
+ // shouldn't. (These choices are largely aesthetic)
+ virtual bool writtenToPrompt() { return true; }
+
+ // Translates the expression to the given target type. This should only be
+ // called with a type returned by getType(). It does not perform implicit
+ // casting.
+ virtual void transAsType(coenv &e, types::ty *target);
+
+ // Translates the expression to the given target type, possibly using an
+ // implicit cast.
+ void transToType(coenv &e, types::ty *target);
+
+ // Translates the expression and returns the resultant type.
+ // For some expressions, this will be ambiguous and return an error.
+ // Trans may only return ty_error, if it (or one of its recursively
+ // called children in the syntax tree) reported an error to em.
+ virtual types::ty *trans(coenv &) = 0;
+
+ // getType() figures out the type of the expression without translating
+ // the code into the virtual machine language or reporting errors to em.
+ // This must follow a few rules to ensure proper translation:
+ // 1. If this returns a valid type, t, trans(e) must return t or
+ // report an error, and transToType(e, t) must run either reporting
+ // an error or reporting no error and yielding the same result as
+ // trans(e).
+ // 2. If this returns a superposition of types (ie. for overloaded
+ // functions), trans must not return a singular type, and every
+ // type in the superposition must run without error properly
+ // if fed to transAsType(e, t).
+ // 3. If this returns ty_error, then so must a call to trans(e) and any
+ // call to trans, transAsType, or transToType must report an error
+ // to em.
+ // 4. Any call to transAsType(e, t) with a type that is not returned by
+ // getType() (or one of the subtypes in case of a superposition)
+ // must report an error.
+ // Any call to transToType(e, t) with a type that is not returned by
+ // getType() (or one of the subtypes in case of a superposition)
+ // or any type not implicitly castable from the above must report an
+ // error.
+ virtual types::ty *getType(coenv &) = 0;
+
+ // This is an optimization which works in some cases to by-pass the slow
+ // overloaded function resolution provided by the application class.
+ //
+ // If an expression is called with arguments given by sig, getCallee must
+ // either return 0 (the default), or if it returns a varEntry, the varEntry
+ // must correspond to the function which would be called after normal
+ // function resolution.
+ //
+ // The callee must produce no side effects as there are no guarantees when
+ // the varEntry will be translated.
+ virtual trans::varEntry *getCallee(coenv &e, types::signature *sig) {
+//#define DEBUG_GETAPP
+#if DEBUG_GETAPP
+ cout << "exp fail" << endl;
+ cout << "exp fail at " << getPos() << endl;
+ prettyprint(cout, 2);
+#endif
+ return 0;
+ }
+
+ // Same result as getType, but caches the result so that subsequent
+ // calls are faster. For this to work correctly, the expression should
+ // only be used in one place, so the environment doesn't change between
+ // calls.
+ virtual types::ty *cgetType(coenv &e) {
+#ifdef DEBUG_CACHE
+ testCachedType(e);
+#endif
+ return ct ? ct : ct = getType(e);
+ }
+
+ void testCachedType(coenv &e);
+
+ // The expression is being written. Translate code such that the value
+ // (represented by the exp value) is stored into the address represented by
+ // this expression.
+ // In terms of side-effects, this expression must be evaluated (once) before
+ // value is evaluated (once).
+ virtual void transWrite(coenv &e, types::ty *t, exp *value) {
+ em.error(getPos());
+ em << "expression cannot be used as an address";
+
+ // Translate the value for errors.
+ value->transToType(e, t);
+ }
+
+ // Translates code for calling a function. The arguments, in the order they
+ // appear in the function's signature, must all be on the stack.
+ virtual void transCall(coenv &e, types::ty *target);
+
+ // transConditionalJump must produce code equivalent to the following:
+ // Evaluate the expression as a boolean. If the result equals cond, jump to
+ // the label dest, otherwise do not jump. In either case, no value is left
+ // on the stack.
+ virtual void transConditionalJump(coenv &e, bool cond, label dest);
+
+ // This is used to ensure the proper order and number of evaluations. When
+ // called, it immediately translates code to perform the side-effects
+ // consistent with a corresponding call to transAsType(e, target).
+ //
+ // The return value, called an evaluation for lack of a better name, is
+ // another expression that responds to the trans methods exactly as would the
+ // original expression, but without producing side-effects. It is also no
+ // longer overloaded, due to the resolution effected by giving a target type
+ // to evaluate().
+ //
+ // The methods transAsType, transWrite, and transCall of the evaluation must
+ // be called with the same target type as the original call to evaluate.
+ // When evaluate() is called during the translation of a function, that
+ // function must still be in translation when the evaluation is translated.
+ //
+ // The base implementation uses a tempExp (see below). This is
+ // sufficient for most expressions.
+ virtual exp *evaluate(coenv &e, types::ty *target);
+
+ // NOTE: could add a "side-effects" method which says if the expression has
+ // side-effects. This might allow some small optimizations in translating.
+};
+
+class tempExp : public exp {
+ access *a;
+ types::ty *t;
+
+public:
+ tempExp(coenv &e, varinit *v, types::ty *t);
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+
+ types::ty *getType(coenv &) {
+ return t;
+ }
+};
+
+// Wrap a varEntry so that it can be used as an expression.
+// Translating the varEntry must cause no side-effects.
+class varEntryExp : public exp {
+ trans::varEntry *v;
+public:
+ varEntryExp(position pos, trans::varEntry *v)
+ : exp(pos), v(v) {}
+ varEntryExp(position pos, types::ty *t, access *a);
+ varEntryExp(position pos, types::ty *t, vm::bltin f);
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *getType(coenv &);
+ types::ty *trans(coenv &e);
+ trans::varEntry *getCallee(coenv &e, types::signature *sig);
+
+ void transAct(action act, coenv &e, types::ty *target);
+ void transAsType(coenv &e, types::ty *target);
+ void transWrite(coenv &e, types::ty *t, exp *value);
+ void transCall(coenv &e, types::ty *target);
+};
+
+class nameExp : public exp {
+ name *value;
+
+public:
+ nameExp(position pos, name *value)
+ : exp(pos), value(value) {}
+
+ nameExp(position pos, symbol id)
+ : exp(pos), value(new simpleName(pos, id)) {}
+
+ nameExp(position pos, string s)
+ : exp(pos), value(new simpleName(pos, symbol::trans(s))) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ symbol getName()
+ {
+ return value->getName();
+ }
+
+ void transAsType(coenv &e, types::ty *target) {
+ value->varTrans(trans::READ, e, target);
+
+ // After translation, the cached type is no longer needed and should be
+ // garbage collected. This could presumably be done in every class derived
+ // from exp, but here it is most important as nameExp can have heavily
+ // overloaded types cached.
+ ct=0;
+ }
+
+ types::ty *trans(coenv &e) {
+ types::ty *t=cgetType(e);
+ if (t->kind == types::ty_error) {
+ em.error(getPos());
+ em << "no matching variable \'" << *value << "\'";
+ return types::primError();
+ }
+ if (t->kind == types::ty_overloaded) {
+ em.error(getPos());
+ em << "use of variable \'" << *value << "\' is ambiguous";
+ return types::primError();
+ }
+ else {
+ transAsType(e, t);
+ return t;
+ }
+ }
+
+ types::ty *getType(coenv &e) {
+ types::ty *t=value->varGetType(e);
+ return t ? t : types::primError();
+ }
+
+ trans::varEntry *getCallee(coenv &e, types::signature *sig) {
+#ifdef DEBUG_GETAPP
+ cout << "nameExp" << endl;
+#endif
+ return value->getCallee(e, sig);
+ }
+
+ void transWrite(coenv &e, types::ty *target, exp *newValue) {
+ newValue->transToType(e, target);
+ this->value->varTrans(trans::WRITE, e, target);
+
+ ct=0; // See note in transAsType.
+ }
+
+ void transCall(coenv &e, types::ty *target) {
+ value->varTrans(trans::CALL, e, target);
+
+ ct=0; // See note in transAsType.
+ }
+
+ exp *evaluate(coenv &, types::ty *) {
+ // Names have no side-effects.
+ return this;
+ }
+};
+
+// Most fields accessed are handled as parts of qualified names, but in cases
+// like f().x or (new t).x, a separate expression is needed.
+class fieldExp : public nameExp {
+ exp *object;
+ symbol field;
+
+ // fieldExp has a lot of common functionality with qualifiedName, so we
+ // essentially hack qualifiedName, by making our object expression look
+ // like a name.
+ class pseudoName : public name {
+ exp *object;
+
+ public:
+ pseudoName(exp *object)
+ : name(object->getPos()), object(object) {}
+
+ // As a variable:
+ void varTrans(trans::action act, coenv &e, types::ty *target) {
+ assert(act == trans::READ);
+ object->transToType(e, target);
+ }
+ types::ty *varGetType(coenv &e) {
+ return object->getType(e);
+ }
+ trans::varEntry *getCallee(coenv &, types::signature *) {
+#ifdef DEBUG_GETAPP
+ cout << "pseudoName" << endl;
+#endif
+ return 0;
+ }
+
+ // As a type:
+ types::ty *typeTrans(coenv &, bool tacit = false) {
+ if (!tacit) {
+ em.error(getPos());
+ em << "expression is not a type";
+ }
+ return types::primError();
+ }
+
+ trans::varEntry *getVarEntry(coenv &) {
+ em.compiler(getPos());
+ em << "expression cannot be used as part of a type";
+ return 0;
+ }
+
+ trans::tyEntry *tyEntryTrans(coenv &) {
+ em.compiler(getPos());
+ em << "expression cannot be used as part of a type";
+ return 0;
+ }
+
+ trans::frame *tyFrameTrans(coenv &) {
+ return 0;
+ }
+
+ void prettyprint(ostream &out, Int indent);
+ void print(ostream& out) const {
+ out << "<exp>";
+ }
+ symbol getName() {
+ return object->getName();
+ }
+ };
+
+ // Try to get this into qualifiedName somehow.
+ types::ty *getObject(coenv &e);
+
+public:
+ fieldExp(position pos, exp *object, symbol field)
+ : nameExp(pos, new qualifiedName(pos,
+ new pseudoName(object),
+ field)),
+ object(object), field(field) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ symbol getName()
+ {
+ return field;
+ }
+
+ exp *evaluate(coenv &e, types::ty *) {
+ // Evaluate the object.
+ return new fieldExp(getPos(),
+ new tempExp(e, object, getObject(e)),
+ field);
+ }
+};
+
+class arrayExp : public exp {
+protected:
+ exp *set;
+
+ array *getArrayType(coenv &e);
+ array *transArray(coenv &e);
+
+public:
+ arrayExp(position pos, exp *set)
+ : exp(pos), set(set) {}
+};
+
+
+class subscriptExp : public arrayExp {
+ exp *index;
+
+public:
+ subscriptExp(position pos, exp *set, exp *index)
+ : arrayExp(pos, set), index(index) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+ void transWrite(coenv &e, types::ty *t, exp *value);
+
+ exp *evaluate(coenv &e, types::ty *) {
+ return new subscriptExp(getPos(),
+ new tempExp(e, set, getArrayType(e)),
+ new tempExp(e, index, types::primInt()));
+ }
+};
+
+class slice : public absyn {
+ exp *left;
+ exp *right;
+
+public:
+ slice(position pos, exp *left, exp *right)
+ : absyn(pos), left(left), right(right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ exp *getLeft() { return left; }
+ exp *getRight() { return right; }
+
+ // Translates code to put the left and right expressions on the stack (in that
+ // order). If left is omitted, zero is pushed on the stack in it's place. If
+ // right is omitted, nothing is pushed in its place.
+ void trans(coenv &e);
+
+ slice *evaluate(coenv &e) {
+ return new slice(getPos(),
+ left ? new tempExp(e, left, types::primInt()) : 0,
+ right ? new tempExp(e, right, types::primInt()) : 0);
+ }
+};
+
+class sliceExp : public arrayExp {
+ slice *index;
+
+public:
+ sliceExp(position pos, exp *set, slice *index)
+ : arrayExp(pos, set), index(index) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+ void transWrite(coenv &e, types::ty *t, exp *value);
+
+ exp *evaluate(coenv &e, types::ty *) {
+ return new sliceExp(getPos(),
+ new tempExp(e, set, getArrayType(e)),
+ index->evaluate(e));
+ }
+};
+
+
+// The expression "this," that evaluates to the lexically enclosing record.
+class thisExp : public exp {
+public:
+ thisExp(position pos)
+ : exp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+
+ exp *evaluate(coenv &, types::ty *) {
+ // this has no side-effects
+ return this;
+ }
+};
+
+class literalExp : public exp {
+public:
+ literalExp(position pos)
+ : exp(pos) {}
+
+ bool scalable() { return false; }
+
+ exp *evaluate(coenv &, types::ty *) {
+ // Literals are constant, they have no side-effects.
+ return this;
+ }
+};
+
+class intExp : public literalExp {
+ Int value;
+
+public:
+ intExp(position pos, Int value)
+ : literalExp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primInt(); }
+};
+
+class realExp : public literalExp {
+protected:
+ double value;
+
+public:
+ realExp(position pos, double value)
+ : literalExp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primReal(); }
+};
+
+
+class stringExp : public literalExp {
+ string str;
+
+public:
+ stringExp(position pos, string str)
+ : literalExp(pos), str(str) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primString(); }
+
+ const string& getString() { return str; }
+};
+
+class booleanExp : public literalExp {
+ bool value;
+
+public:
+ booleanExp(position pos, bool value)
+ : literalExp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primBoolean(); }
+};
+
+class cycleExp : public literalExp {
+
+public:
+ cycleExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primCycleToken(); }
+};
+
+class newPictureExp : public literalExp {
+
+public:
+ newPictureExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primPicture(); }
+};
+
+class nullPathExp : public literalExp {
+
+public:
+ nullPathExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primPath(); }
+};
+
+class nullExp : public literalExp {
+
+public:
+ nullExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primNull(); }
+};
+
+class quoteExp : public exp {
+ runnable *value;
+
+public:
+ quoteExp(position pos, runnable *value)
+ : exp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primCode(); }
+};
+
+// A list of expressions used in a function call.
+class explist : public absyn {
+ typedef mem::vector<exp *> expvector;
+ expvector exps;
+
+public:
+ explist(position pos)
+ : absyn(pos) {}
+
+ virtual ~explist() {}
+
+ virtual void add(exp *e) {
+ exps.push_back(e);
+ }
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual size_t size() {
+ return exps.size();
+ }
+
+ virtual exp * operator[] (size_t index) {
+ return exps[index];
+ }
+};
+
+struct argument {
+ exp *val;
+ symbol name;
+
+ // No constructor due to the union in camp.y
+#if 0
+ argument(exp *val=0, symbol name=0)
+ : val(val), name(name) {}
+#endif
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+class arglist : public gc {
+public:
+ typedef mem::vector<argument> argvector;
+
+ argvector args;
+ argument rest;
+
+ // As the language allows named arguments after rest arguments, store the
+ // index of the rest argument in order to ensure proper left-to-right
+ // execution.
+ static const size_t DUMMY_REST_POSITION = 9999;
+ size_t restPosition;
+
+ arglist()
+ : args(), rest(), restPosition(DUMMY_REST_POSITION) {}
+
+ virtual ~arglist() {}
+
+ virtual void addFront(argument a) {
+ args.insert(args.begin(), a);
+ }
+
+ virtual void addFront(exp *val, symbol name=symbol::nullsym) {
+ argument a; a.val=val; a.name=name;
+ addFront(a);
+ }
+
+ virtual void add(argument a) {
+ if (rest.val && !a.name) {
+ em.error(a.val->getPos());
+ em << "unnamed argument after rest argument";
+ return;
+ }
+ args.push_back(a);
+ }
+
+ virtual void add(exp *val, symbol name=symbol::nullsym) {
+ argument a; a.val=val; a.name=name;
+ add(a);
+ }
+
+ virtual void addRest(argument a) {
+ if (rest.val) {
+ em.error(a.val->getPos());
+ em << "additional rest argument";
+ return;
+ }
+
+ rest = a;
+
+ assert(restPosition == DUMMY_REST_POSITION);
+ restPosition = size();
+ }
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual size_t size() {
+ return args.size();
+ }
+
+ virtual argument& operator[] (size_t index) {
+ return args[index];
+ }
+
+ virtual argument& getRest() {
+ return rest;
+ }
+};
+
+// callExp has a global cache of resolved overloaded functions. This clears
+// this cache so the associated data can be garbage collected.
+void clearCachedCalls();
+
+class callExp : public exp {
+protected:
+ exp *callee;
+ arglist *args;
+
+private:
+ // Per object caching - Cache the application when it's determined.
+ application *cachedApp;
+
+ // In special cases, no application object is needed and we can store the
+ // varEntry used in advance.
+ trans::varEntry *cachedVarEntry;
+
+ types::signature *argTypes(coenv& e, bool *searchable);
+ void reportArgErrors(coenv &e);
+ application *resolve(coenv &e,
+ types::overloaded *o,
+ types::signature *source,
+ bool tacit);
+ application *resolveWithCache(coenv &e,
+ types::overloaded *o,
+ types::signature *source,
+ bool tacit);
+ void reportMismatch(types::function *ft,
+ types::signature *source);
+
+ void reportNonFunction();
+
+ // Caches either the application object used to apply the function to the
+ // arguments, or in cases where the arguments match the function perfectly,
+ // the varEntry of the callee (or neither in case of an error). Returns
+ // what getType should return.
+ types::ty *cacheAppOrVarEntry(coenv &e, bool tacit);
+
+ types::ty *transPerfectMatch(coenv &e);
+public:
+ callExp(position pos, exp *callee, arglist *args)
+ : exp(pos), callee(callee), args(args),
+ cachedApp(0), cachedVarEntry(0) { assert(args); }
+
+ callExp(position pos, exp *callee)
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {}
+
+ callExp(position pos, exp *callee, exp *arg1)
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {
+ args->add(arg1);
+ }
+
+ callExp(position pos, exp *callee, exp *arg1, exp *arg2)
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {
+ args->add(arg1);
+ args->add(arg2);
+ }
+
+ callExp(position pos, exp *callee, exp *arg1, exp *arg2, exp *arg3)
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {
+ args->add(arg1);
+ args->add(arg2);
+ args->add(arg3);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+
+ // Returns true if the function call resolves uniquely without error. Used
+ // in implementing the special == and != operators for functions.
+ virtual bool resolved(coenv &e);
+};
+
+
+class pairExp : public exp {
+ exp *x;
+ exp *y;
+
+public:
+ pairExp(position pos, exp *x, exp *y)
+ : exp(pos), x(x), y(y) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primPair(); }
+};
+
+class tripleExp : public exp {
+ exp *x;
+ exp *y;
+ exp *z;
+
+public:
+ tripleExp(position pos, exp *x, exp *y, exp *z)
+ : exp(pos), x(x), y(y), z(z) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primTriple(); }
+};
+
+class transformExp : public exp {
+ exp *x;
+ exp *y;
+ exp *xx,*xy,*yx,*yy;
+
+public:
+ transformExp(position pos, exp *x, exp *y, exp *xx, exp *xy, exp *yx,
+ exp *yy)
+ : exp(pos), x(x), y(y), xx(xx), xy(xy), yx(yx), yy(yy) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primTransform(); }
+};
+
+class castExp : public exp {
+ ty *target;
+ exp *castee;
+
+ types::ty *tryCast(coenv &e, types::ty *t, types::ty *s,
+ symbol csym);
+public:
+ castExp(position pos, ty *target, exp *castee)
+ : exp(pos), target(target), castee(castee) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class nullaryExp : public callExp {
+public:
+ nullaryExp(position pos, symbol op)
+ : callExp(pos, new nameExp(pos, op)) {}
+};
+
+class unaryExp : public callExp {
+public:
+ unaryExp(position pos, exp *base, symbol op)
+ : callExp(pos, new nameExp(pos, op), base) {}
+};
+
+class binaryExp : public callExp {
+public:
+ binaryExp(position pos, exp *left, symbol op, exp *right)
+ : callExp(pos, new nameExp(pos, op), left, right) {}
+};
+
+class equalityExp : public callExp {
+public:
+ equalityExp(position pos, exp *left, symbol op, exp *right)
+ : callExp(pos, new nameExp(pos, op), left, right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+
+// Scaling expressions such as 3sin(x).
+class scaleExp : public binaryExp {
+ exp *getLeft() {
+ return (*this->args)[0].val;
+ }
+ exp *getRight() {
+ return (*this->args)[1].val;
+ }
+public:
+ scaleExp(position pos, exp *left, exp *right)
+ : binaryExp(pos, left, symbol::trans("*"), right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ //types::ty *getType(coenv &e);
+
+ bool scalable() { return false; }
+};
+
+// Used for tension, which takes two real values, and a boolean to denote if it
+// is a tension atleast case.
+class ternaryExp : public callExp {
+public:
+ ternaryExp(position pos, exp *left, symbol op, exp *right, exp *last)
+ : callExp(pos, new nameExp(pos, op), left, right, last) {}
+};
+
+// The a ? b : c ternary operator.
+class conditionalExp : public exp {
+ exp *test;
+ exp *onTrue;
+ exp *onFalse;
+
+public:
+ conditionalExp(position pos, exp *test, exp *onTrue, exp *onFalse)
+ : exp(pos), test(test), onTrue(onTrue), onFalse(onFalse) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void baseTransToType(coenv &e, types::ty *target);
+
+ void transToType(coenv &e, types::ty *target);
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+
+};
+
+class andOrExp : public exp {
+protected:
+ exp *left;
+ symbol op;
+ exp *right;
+
+public:
+ andOrExp(position pos, exp *left, symbol op, exp *right)
+ : exp(pos), left(left), op(op), right(right) {}
+
+ virtual types::ty *trans(coenv &e) = 0;
+ virtual types::ty *getType(coenv &) {
+ return types::primBoolean();
+ }
+};
+
+class orExp : public andOrExp {
+public:
+ orExp(position pos, exp *left, symbol op, exp *right)
+ : andOrExp(pos, left, op, right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ void transConditionalJump(coenv &e, bool cond, label dest);
+};
+
+class andExp : public andOrExp {
+public:
+ andExp(position pos, exp *left, symbol op, exp *right)
+ : andOrExp(pos, left, op, right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ void transConditionalJump(coenv &e, bool cond, label dest);
+};
+
+class joinExp : public callExp {
+public:
+ joinExp(position pos, symbol op)
+ : callExp(pos, new nameExp(pos, op)) {}
+
+ void pushFront(exp *e) {
+ args->addFront(e);
+ }
+ void pushBack(exp *e) {
+ args->add(e);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+class specExp : public exp {
+ symbol op;
+ exp *arg;
+ camp::side s;
+
+public:
+ specExp(position pos, symbol op, exp *arg, camp::side s=camp::OUT)
+ : exp(pos), op(op), arg(arg), s(s) {}
+
+ void setSide(camp::side ss) {
+ s=ss;
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class assignExp : public exp {
+protected:
+ exp *dest;
+ exp *value;
+
+ // This is basically a hook to facilitate selfExp. dest is given as an
+ // argument since it will be a temporary in translation in order to avoid
+ // multiple evaluation.
+ virtual exp *ultimateValue(exp *) {
+ return value;
+ }
+
+public:
+ assignExp(position pos, exp *dest, exp *value)
+ : exp(pos), dest(dest), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Don't write the result of an assignment to the prompt.
+ bool writtenToPrompt() { return false; }
+
+ void transAsType(coenv &e, types::ty *target);
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class selfExp : public assignExp {
+ symbol op;
+
+ exp *ultimateValue(exp *dest) {
+ return new binaryExp(getPos(), dest, op, value);
+ }
+
+public:
+ selfExp(position pos, exp *dest, symbol op, exp *value)
+ : assignExp(pos, dest, value), op(op) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsType(coenv &e, types::ty *target);
+};
+
+class prefixExp : public exp {
+ exp *dest;
+ symbol op;
+
+public:
+ prefixExp(position pos, exp *dest, symbol op)
+ : exp(pos), dest(dest), op(op) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ bool scalable() { return false; }
+
+ // Don't write the result to the prompt.
+ bool writtenToPrompt() { return false; }
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+// Postfix expresions are illegal. This is caught here as we can give a
+// more meaningful error message to the user, rather than a "parse
+// error."
+class postfixExp : public exp {
+ exp *dest;
+ symbol op;
+
+public:
+ postfixExp(position pos, exp *dest, symbol op)
+ : exp(pos), dest(dest), op(op) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primError(); }
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/graphics/asymptote/fftw++.cc b/graphics/asymptote/fftw++.cc
new file mode 100644
index 0000000000..7c1095f930
--- /dev/null
+++ b/graphics/asymptote/fftw++.cc
@@ -0,0 +1,75 @@
+#include <cstring>
+#include <sstream>
+#include "fftw++.h"
+
+using namespace std;
+
+namespace fftwpp {
+
+const double fftw::twopi=2.0*acos(-1.0);
+
+// User settings:
+unsigned int fftw::effort=FFTW_MEASURE;
+const char *fftw::WisdomName=".wisdom";
+unsigned int fftw::maxthreads=1;
+double fftw::testseconds=0.2; // Time limit for threading efficiency tests
+
+fftw_plan (*fftw::planner)(fftw *f, Complex *in, Complex *out)=Planner;
+
+const char *fftw::oddshift="Shift is not implemented for odd nx";
+const char *inout=
+ "constructor and call must be both in place or both out of place";
+
+fft1d::Table fft1d::threadtable;
+mfft1d::Table mfft1d::threadtable;
+rcfft1d::Table rcfft1d::threadtable;
+crfft1d::Table crfft1d::threadtable;
+mrcfft1d::Table mrcfft1d::threadtable;
+mcrfft1d::Table mcrfft1d::threadtable;
+fft2d::Table fft2d::threadtable;
+
+void LoadWisdom()
+{
+ static bool Wise=false;
+ if(!Wise) {
+ ifstream ifWisdom;
+ ifWisdom.open(fftw::WisdomName);
+ ostringstream wisdom;
+ wisdom << ifWisdom.rdbuf();
+ ifWisdom.close();
+ const string& s=wisdom.str();
+ fftw_import_wisdom_from_string(s.c_str());
+ Wise=true;
+ }
+}
+
+void SaveWisdom()
+{
+ ofstream ofWisdom;
+ ofWisdom.open(fftw::WisdomName);
+ char *wisdom=fftw_export_wisdom_to_string();
+ ofWisdom << wisdom;
+ fftw_free(wisdom);
+ ofWisdom.close();
+}
+
+fftw_plan Planner(fftw *F, Complex *in, Complex *out)
+{
+ LoadWisdom();
+ fftw::effort |= FFTW_WISDOM_ONLY;
+ fftw_plan plan=F->Plan(in,out);
+ fftw::effort &= !FFTW_WISDOM_ONLY;
+ if(!plan) {
+ plan=F->Plan(in,out);
+ SaveWisdom();
+ }
+ return plan;
+}
+
+ThreadBase::ThreadBase() {threads=fftw::maxthreads;}
+
+}
+
+namespace utils {
+unsigned int defaultmpithreads=1;
+}
diff --git a/graphics/asymptote/fftw++.h b/graphics/asymptote/fftw++.h
new file mode 100644
index 0000000000..14ea4300f1
--- /dev/null
+++ b/graphics/asymptote/fftw++.h
@@ -0,0 +1,1551 @@
+/* Fast Fourier transform C++ header class for the FFTW3 Library
+ Copyright (C) 2004-16
+ John C. Bowman, University of Alberta
+ Malcolm Roberts, University of Strasbourg
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __fftwpp_h__
+#define __fftwpp_h__ 1
+
+#define __FFTWPP_H_VERSION__ 2.07
+
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <fftw3.h>
+#include <cerrno>
+#include <map>
+
+#ifndef _OPENMP
+#ifndef FFTWPP_SINGLE_THREAD
+#define FFTWPP_SINGLE_THREAD
+#endif
+#endif
+
+#ifndef FFTWPP_SINGLE_THREAD
+#include <omp.h>
+#endif
+
+inline int get_thread_num()
+{
+#ifdef FFTWPP_SINGLE_THREAD
+ return 0;
+#else
+ return omp_get_thread_num();
+#endif
+}
+
+inline int get_max_threads()
+{
+#ifdef FFTWPP_SINGLE_THREAD
+ return 1;
+#else
+ return omp_get_max_threads();
+#endif
+}
+
+#ifndef FFTWPP_SINGLE_THREAD
+#define PARALLEL(code) \
+ if(threads > 1) { \
+ _Pragma("omp parallel for num_threads(threads)") \
+ code \
+ } else { \
+ code \
+ }
+#else
+#define PARALLEL(code) \
+ { \
+ code \
+ }
+#endif
+
+#ifndef __Complex_h__
+#include <complex>
+typedef std::complex<double> Complex;
+#endif
+
+#include "seconds.h"
+#include "statistics.h"
+#include "align.h"
+
+namespace fftwpp {
+
+// Obsolete names:
+#define FFTWComplex ComplexAlign
+#define FFTWdouble doubleAlign
+#define FFTWdelete deleteAlign
+
+class fftw;
+
+extern "C" fftw_plan Planner(fftw *F, Complex *in, Complex *out);
+void LoadWisdom();
+void SaveWisdom();
+
+extern const char *inout;
+
+struct threaddata {
+ unsigned int threads;
+ double mean;
+ double stdev;
+ threaddata() : threads(0), mean(0.0), stdev(0.0) {}
+ threaddata(unsigned int threads, double mean, double stdev) :
+ threads(threads), mean(mean), stdev(stdev) {}
+};
+
+class fftw;
+
+class ThreadBase
+{
+protected:
+ unsigned int threads;
+ unsigned int innerthreads;
+public:
+ ThreadBase();
+ ThreadBase(unsigned int threads) : threads(threads) {}
+ void Threads(unsigned int nthreads) {threads=nthreads;}
+ unsigned int Threads() {return threads;}
+
+ void multithread(unsigned int nx) {
+ if(nx >= threads) {
+ innerthreads=1;
+ } else {
+ innerthreads=threads;
+ threads=1;
+ }
+ }
+};
+
+inline unsigned int realsize(unsigned int n, Complex *in, Complex *out=NULL)
+{
+ return (!out || in == out) ? 2*(n/2+1) : n;
+}
+
+inline unsigned int realsize(unsigned int n, Complex *in, double *out)
+{
+ return realsize(n,in,(Complex *) out);
+}
+
+inline unsigned int realsize(unsigned int n, double *in, Complex *out)
+{
+ return realsize(n,(Complex *) in,out);
+}
+
+// Base clase for fft routines
+//
+class fftw : public ThreadBase {
+protected:
+ unsigned int doubles; // number of double precision values in dataset
+ int sign;
+ unsigned int threads;
+ double norm;
+
+ fftw_plan plan;
+ bool inplace;
+
+ unsigned int Dist(unsigned int n, size_t stride, size_t dist) {
+ return dist ? dist : ((stride == 1) ? n : 1);
+ }
+
+ static const double twopi;
+
+public:
+ static unsigned int effort;
+ static unsigned int maxthreads;
+ static double testseconds;
+ static const char *WisdomName;
+ static fftw_plan (*planner)(fftw *f, Complex *in, Complex *out);
+
+ virtual unsigned int Threads() {return threads;}
+
+ static const char *oddshift;
+
+ // Inplace shift of Fourier origin to (nx/2,0) for even nx.
+ static void Shift(Complex *data, unsigned int nx, unsigned int ny,
+ unsigned int threads) {
+ unsigned int nyp=ny/2+1;
+ unsigned int stop=nx*nyp;
+ if(nx % 2 == 0) {
+ unsigned int inc=2*nyp;
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=nyp; i < stop; i += inc) {
+ Complex *p=data+i;
+ for(unsigned int j=0; j < nyp; j++) p[j]=-p[j];
+ }
+ } else {
+ std::cerr << oddshift << std::endl;
+ exit(1);
+ }
+ }
+
+ // Out-of-place shift of Fourier origin to (nx/2,0) for even nx.
+ static void Shift(double *data, unsigned int nx, unsigned int ny,
+ unsigned int threads) {
+ if(nx % 2 == 0) {
+ unsigned int stop=nx*ny;
+ unsigned int inc=2*ny;
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=ny; i < stop; i += inc) {
+ double *p=data+i;
+ for(unsigned int j=0; j < ny; j++) p[j]=-p[j];
+ }
+ } else {
+ std::cerr << oddshift << std::endl;
+ exit(1);
+ }
+ }
+
+ // Inplace shift of Fourier origin to (nx/2,ny/2,0) for even nx and ny.
+ static void Shift(Complex *data, unsigned int nx, unsigned int ny,
+ unsigned int nz, unsigned int threads) {
+ unsigned int nzp=nz/2+1;
+ unsigned int nyzp=ny*nzp;
+ if(nx % 2 == 0 && ny % 2 == 0) {
+ unsigned int pinc=2*nzp;
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; i++) {
+ Complex *pstart=data+i*nyzp;
+ Complex *pstop=pstart+nyzp;
+ for(Complex *p=pstart+(1-(i % 2))*nzp; p < pstop; p += pinc) {
+ for(unsigned int k=0; k < nzp; k++) p[k]=-p[k];
+ }
+ }
+ } else {
+ std::cerr << oddshift << " or odd ny" << std::endl;
+ exit(1);
+ }
+ }
+
+ // Out-of-place shift of Fourier origin to (nx/2,ny/2,0) for even nx and ny.
+ static void Shift(double *data, unsigned int nx, unsigned int ny,
+ unsigned int nz, unsigned int threads) {
+ unsigned int nyz=ny*nz;
+ if(nx % 2 == 0 && ny % 2 == 0) {
+ unsigned int pinc=2*nz;
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; i++) {
+ double *pstart=data+i*nyz;
+ double *pstop=pstart+nyz;
+ for(double *p=pstart+(1-(i % 2))*nz; p < pstop; p += pinc) {
+ for(unsigned int k=0; k < nz; k++) p[k]=-p[k];
+ }
+ }
+ } else {
+ std::cerr << oddshift << " or odd ny" << std::endl;
+ exit(1);
+ }
+ }
+
+ fftw() : plan(NULL) {}
+ fftw(unsigned int doubles, int sign, unsigned int threads,
+ unsigned int n=0) :
+ doubles(doubles), sign(sign), threads(threads),
+ norm(1.0/(n ? n : doubles/2)), plan(NULL) {
+#ifndef FFTWPP_SINGLE_THREAD
+ fftw_init_threads();
+#endif
+ }
+
+ virtual ~fftw() {
+ if(plan) fftw_destroy_plan(plan);
+ }
+
+ virtual fftw_plan Plan(Complex *in, Complex *out) {return NULL;};
+
+ inline void CheckAlign(Complex *p, const char *s) {
+ if((size_t) p % sizeof(Complex) == 0) return;
+ std::cerr << "WARNING: " << s << " array is not " << sizeof(Complex)
+ << "-byte aligned: address " << p << std::endl;
+ }
+
+ void noplan() {
+ std::cerr << "Unable to construct FFTW plan" << std::endl;
+ exit(1);
+ }
+
+ static void planThreads(unsigned int threads) {
+#ifndef FFTWPP_SINGLE_THREAD
+ omp_set_num_threads(threads);
+ fftw_plan_with_nthreads(threads);
+#endif
+ }
+
+ threaddata time(fftw_plan plan1, fftw_plan planT, Complex *in, Complex *out,
+ unsigned int Threads) {
+ utils::statistics S,ST;
+ double stop=utils::totalseconds()+testseconds;
+ threads=1;
+ plan=plan1;
+ fft(in,out);
+ threads=Threads;
+ plan=planT;
+ fft(in,out);
+ unsigned int N=1;
+ for(;;) {
+ double t0=utils::totalseconds();
+ threads=1;
+ plan=plan1;
+ for(unsigned int i=0; i < N; ++i)
+ fft(in,out);
+ double t1=utils::totalseconds();
+ threads=Threads;
+ plan=planT;
+ for(unsigned int i=0; i < N; ++i)
+ fft(in,out);
+ double t=utils::totalseconds();
+ S.add(t1-t0);
+ ST.add(t-t1);
+ if(S.mean() < 100.0/CLOCKS_PER_SEC) N *= 2;
+ if(S.count() >= 10) {
+ double error=S.stdev();
+ double diff=ST.mean()-S.mean();
+ if(diff >= 0.0 || t > stop) {
+ threads=1;
+ plan=plan1;
+ fftw_destroy_plan(planT);
+ break;
+ }
+ if(diff < -error) {
+ threads=Threads;
+ fftw_destroy_plan(plan1);
+ break;
+ }
+ }
+ }
+ return threaddata(threads,S.mean(),S.stdev());
+ }
+
+ virtual threaddata lookup(bool inplace, unsigned int threads) {
+ return threaddata();
+ }
+ virtual void store(bool inplace, const threaddata& data) {}
+
+ inline Complex *CheckAlign(Complex *in, Complex *out, bool constructor=true)
+ {
+#ifndef NO_CHECK_ALIGN
+ CheckAlign(in,constructor ? "constructor input" : "input");
+ if(out) CheckAlign(out,constructor ? "constructor output" : "output");
+ else out=in;
+#else
+ if(!out) out=in;
+#endif
+ return out;
+ }
+
+ threaddata Setup(Complex *in, Complex *out=NULL) {
+ bool alloc=!in;
+ if(alloc) in=utils::ComplexAlign((doubles+1)/2);
+ out=CheckAlign(in,out);
+ inplace=(out==in);
+
+ threaddata data;
+ unsigned int Threads=threads;
+ if(threads > 1) data=lookup(inplace,threads);
+ threads=data.threads > 0 ? data.threads : 1;
+ planThreads(threads);
+ plan=(*planner)(this,in,out);
+ if(!plan) noplan();
+
+ fftw_plan planT;
+ if(fftw::maxthreads > 1) {
+ threads=Threads;
+ planThreads(threads);
+ planT=(*planner)(this,in,out);
+
+ if(data.threads == 0) {
+ if(planT)
+ data=time(plan,planT,in,out,threads);
+ else noplan();
+ store(inplace,threaddata(threads,data.mean,data.stdev));
+ }
+ }
+
+ if(alloc) Array::deleteAlign(in,(doubles+1)/2);
+ return data;
+ }
+
+ threaddata Setup(Complex *in, double *out) {
+ return Setup(in,(Complex *) out);
+ }
+
+ threaddata Setup(double *in, Complex *out=NULL) {
+ return Setup((Complex *) in,out);
+ }
+
+ virtual void Execute(Complex *in, Complex *out, bool=false) {
+ fftw_execute_dft(plan,(fftw_complex *) in,(fftw_complex *) out);
+ }
+
+ Complex *Setout(Complex *in, Complex *out) {
+ out=CheckAlign(in,out,false);
+ if(inplace ^ (out == in)) {
+ std::cerr << "ERROR: fft " << inout << std::endl;
+ exit(1);
+ }
+ return out;
+ }
+
+ void fft(Complex *in, Complex *out=NULL) {
+ out=Setout(in,out);
+ Execute(in,out);
+ }
+
+ void fft(double *in, Complex *out=NULL) {
+ fft((Complex *) in,out);
+ }
+
+ void fft(Complex *in, double *out) {
+ fft(in,(Complex *) out);
+ }
+
+ void fft0(Complex *in, Complex *out=NULL) {
+ out=Setout(in,out);
+ Execute(in,out,true);
+ }
+
+ void fft0(double *in, Complex *out=NULL) {
+ fft0((Complex *) in,out);
+ }
+
+ void fft0(Complex *in, double *out) {
+ fft0(in,(Complex *) out);
+ }
+
+ void Normalize(Complex *out) {
+ unsigned int stop=doubles/2;
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < stop; i++) out[i] *= norm;
+ }
+
+ void Normalize(double *out) {
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < doubles; i++) out[i] *= norm;
+ }
+
+ virtual void fftNormalized(Complex *in, Complex *out=NULL, bool shift=false)
+ {
+ out=Setout(in,out);
+ Execute(in,out,shift);
+ Normalize(out);
+ }
+
+ virtual void fftNormalized(Complex *in, double *out, bool shift=false) {
+ out=(double *) Setout(in,(Complex *) out);
+ Execute(in,(Complex *) out,shift);
+ Normalize(out);
+ }
+
+ virtual void fftNormalized(double *in, Complex *out, bool shift=false) {
+ fftNormalized((Complex *) in,out,shift);
+ }
+
+ template<class I, class O>
+ void fft0Normalized(I in, O out) {
+ fftNormalized(in,out,true);
+ }
+
+ template<class O>
+ void Normalize(unsigned int nx, unsigned int M, size_t ostride,
+ size_t odist, O *out) {
+ unsigned int stop=nx*ostride;
+ O *outMdist=out+M*odist;
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < stop; i += ostride) {
+ O *pstop=outMdist+i;
+ for(O *p=out+i; p < pstop; p += odist) {
+ *p *= norm;
+ }
+ }
+ }
+
+ template<class I, class O>
+ void fftNormalized(unsigned int nx, unsigned int M, size_t ostride,
+ size_t odist, I *in, O *out=NULL, bool shift=false) {
+ out=(O *) Setout((Complex *) in,(Complex *) out);
+ Execute((Complex *) in,(Complex *) out,shift);
+ Normalize(nx,M,ostride,odist,out);
+ }
+
+}; // class fftw
+
+class Transpose {
+ fftw_plan plan;
+ fftw_plan plan2;
+ unsigned int a,b;
+ unsigned int nlength,mlength;
+ unsigned int ilast,jlast;
+ unsigned int rows,cols;
+ unsigned int threads;
+ bool inplace;
+ unsigned int size;
+public:
+ template<class T>
+ Transpose(unsigned int rows, unsigned int cols, unsigned int length,
+ T *in, T *out=NULL, unsigned int threads=fftw::maxthreads) :
+ rows(rows), cols(cols), threads(threads) {
+ size=sizeof(T);
+ if(size % sizeof(double) != 0) {
+ std::cerr << "ERROR: Transpose is not implemented for type of size "
+ << size;
+ exit(1);
+ }
+ plan=plan2=NULL;
+ if(rows == 0 || cols == 0) return;
+ size /= sizeof(double);
+ length *= size;
+
+ if(!out) out=in;
+ inplace=(out==in);
+ if(inplace) {
+ fftw::planThreads(threads);
+ threads=1;
+ } else fftw::planThreads(1);
+
+ fftw_iodim dims[3];
+
+ a=std::min(rows,threads);
+ b=std::min(cols,threads/a);
+
+ unsigned int n=utils::ceilquotient(rows,a);
+ unsigned int m=utils::ceilquotient(cols,b);
+
+ // If rows <= threads then a=rows and n=1.
+ // If rows >= threads then b=1 and m=cols.
+
+ nlength=n*length;
+ mlength=m*length;
+
+ dims[0].n=n;
+ dims[0].is=cols*length;
+ dims[0].os=length;
+
+ dims[1].n=m;
+ dims[1].is=length;
+ dims[1].os=rows*length;
+
+ dims[2].n=length;
+ dims[2].is=1;
+ dims[2].os=1;
+
+ // A plan with rank=0 is a transpose.
+ plan=fftw_plan_guru_r2r(0,NULL,3,dims,(double *) in,(double *) out,
+ NULL,fftw::effort);
+ ilast=a;
+ jlast=b;
+
+ if(n*a > rows) { // Only happens when rows > threads.
+ a=utils::ceilquotient(rows,n);
+ ilast=a-1;
+ dims[0].n=rows-n*ilast;
+ plan2=fftw_plan_guru_r2r(0,NULL,3,dims,(double *) in,(double *) out,
+ NULL,fftw::effort);
+ } else { // Only happens when rows < threads.
+ if(m*b > cols) {
+ b=utils::ceilquotient(cols,m);
+ jlast=b-1;
+ dims[1].n=cols-m*jlast;
+ plan2=fftw_plan_guru_r2r(0,NULL,3,dims,(double *) in,(double *) out,
+ NULL,fftw::effort);
+ }
+ }
+ }
+
+ ~Transpose() {
+ if(plan) fftw_destroy_plan(plan);
+ if(plan2) fftw_destroy_plan(plan2);
+ }
+
+ template<class T>
+ void transpose(T *in, T *out=NULL) {
+ if(rows == 0 || cols == 0) return;
+ if(!out) out=in;
+ if(inplace ^ (out == in)) {
+ std::cerr << "ERROR: Transpose " << inout << std::endl;
+ exit(1);
+ }
+#ifndef FFTWPP_SINGLE_THREAD
+ if(a > 1) {
+ if(b > 1) {
+ int A=a, B=b;
+#pragma omp parallel for num_threads(A)
+ for(unsigned int i=0; i < a; ++i) {
+ unsigned int I=i*nlength;
+#pragma omp parallel for num_threads(B)
+ for(unsigned int j=0; j < b; ++j) {
+ unsigned int J=j*mlength;
+ fftw_execute_r2r((i < ilast && j < jlast) ? plan : plan2,
+ (double *) in+cols*I+J,
+ (double *) out+rows*J+I);
+ }
+ }
+ } else {
+ int A=a;
+#pragma omp parallel for num_threads(A)
+ for(unsigned int i=0; i < a; ++i) {
+ unsigned int I=i*nlength;
+ fftw_execute_r2r(i < ilast ? plan : plan2,
+ (double *) in+cols*I,(double *) out+I);
+ }
+ }
+ } else if(b > 1) {
+ int B=b;
+#pragma omp parallel for num_threads(B)
+ for(unsigned int j=0; j < b; ++j) {
+ unsigned int J=j*mlength;
+ fftw_execute_r2r(j < jlast ? plan : plan2,
+ (double *) in+J,(double *) out+rows*J);
+ }
+ } else
+#endif
+ fftw_execute_r2r(plan,(double *) in,(double*) out);
+ }
+};
+
+template<class T, class L>
+class Threadtable {
+public:
+ typedef std::map<T,threaddata,L> Table;
+
+ threaddata Lookup(Table& table, T key) {
+ typename Table::iterator p=table.find(key);
+ return p == table.end() ? threaddata() : p->second;
+ }
+
+ void Store(Table& threadtable, T key, const threaddata& data) {
+ threadtable[key]=data;
+ }
+};
+
+struct keytype1 {
+ unsigned int nx;
+ unsigned int threads;
+ bool inplace;
+ keytype1(unsigned int nx, unsigned int threads, bool inplace) :
+ nx(nx), threads(threads), inplace(inplace) {}
+};
+
+struct keyless1 {
+ bool operator()(const keytype1& a, const keytype1& b) const {
+ return a.nx < b.nx || (a.nx == b.nx &&
+ (a.threads < b.threads || (a.threads == b.threads &&
+ a.inplace < b.inplace)));
+ }
+};
+
+struct keytype2 {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int threads;
+ bool inplace;
+ keytype2(unsigned int nx, unsigned int ny, unsigned int threads,
+ bool inplace) :
+ nx(nx), ny(ny), threads(threads), inplace(inplace) {}
+};
+
+struct keyless2 {
+ bool operator()(const keytype2& a, const keytype2& b) const {
+ return a.nx < b.nx || (a.nx == b.nx &&
+ (a.ny < b.ny || (a.ny == b.ny &&
+ (a.threads < b.threads ||
+ (a.threads == b.threads &&
+ a.inplace < b.inplace)))));
+ }
+};
+
+struct keytype3 {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int nz;
+ unsigned int threads;
+ bool inplace;
+ keytype3(unsigned int nx, unsigned int ny, unsigned int nz,
+ unsigned int threads, bool inplace) :
+ nx(nx), ny(ny), nz(nz), threads(threads), inplace(inplace) {}
+};
+
+struct keyless3 {
+ bool operator()(const keytype3& a, const keytype3& b) const {
+ return a.nx < b.nx || (a.nx == b.nx &&
+ (a.ny < b.ny || (a.ny == b.ny &&
+ (a.nz < b.nz ||
+ (a.nz == b.nz &&
+ (a.threads < b.threads ||
+ (a.threads == b.threads &&
+ a.inplace < b.inplace)))))));
+ }
+};
+
+// Compute the complex Fourier transform of n complex values.
+// Before calling fft(), the arrays in and out (which may coincide) must be
+// allocated as Complex[n].
+//
+// Out-of-place usage:
+//
+// fft1d Forward(n,-1,in,out);
+// Forward.fft(in,out);
+//
+// fft1d Backward(n,1,in,out);
+// Backward.fft(in,out);
+//
+// fft1d Backward(n,1,in,out);
+// Backward.fftNormalized(in,out); // True inverse of Forward.fft(out,in);
+//
+// In-place usage:
+//
+// fft1d Forward(n,-1);
+// Forward.fft(in);
+//
+// fft1d Backward(n,1);
+// Backward.fft(in);
+//
+class fft1d : public fftw, public Threadtable<keytype1,keyless1> {
+ unsigned int nx;
+ static Table threadtable;
+public:
+ fft1d(unsigned int nx, int sign, Complex *in=NULL, Complex *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(2*nx,sign,threads), nx(nx) {Setup(in,out);}
+
+#ifdef __Array_h__
+ fft1d(int sign, const Array::array1<Complex>& in,
+ const Array::array1<Complex>& out=Array::NULL1,
+ unsigned int threads=maxthreads)
+ : fftw(2*in.Nx(),sign,threads), nx(in.Nx()) {Setup(in,out);}
+#endif
+
+ threaddata lookup(bool inplace, unsigned int threads) {
+ return this->Lookup(threadtable,keytype1(nx,threads,inplace));
+ }
+ void store(bool inplace, const threaddata& data) {
+ this->Store(threadtable,keytype1(nx,data.threads,inplace),data);
+ }
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_1d(nx,(fftw_complex *) in,(fftw_complex *) out,
+ sign,effort);
+ }
+};
+
+template<class I, class O>
+class fftwblock : public virtual fftw {
+public:
+ int nx;
+ unsigned int M;
+ size_t istride,ostride;
+ size_t idist,odist;
+ fftw_plan plan1,plan2;
+ unsigned int T,Q,R;
+ fftwblock(unsigned int nx, unsigned int M,
+ size_t istride, size_t ostride, size_t idist, size_t odist,
+ Complex *in, Complex *out, unsigned int Threads)
+ : fftw(), nx(nx), M(M), istride(istride), ostride(ostride),
+ idist(Dist(nx,istride,idist)), odist(Dist(nx,ostride,odist)),
+ plan1(NULL), plan2(NULL) {
+ T=1;
+ Q=M;
+ R=0;
+
+ threaddata S1=Setup(in,out);
+ fftw_plan planT1=plan;
+
+ if(fftw::maxthreads > 1) {
+ if(Threads > 1) {
+ T=std::min(M,Threads);
+ Q=T > 0 ? M/T : 0;
+ R=M-Q*T;
+
+ threads=Threads;
+ threaddata ST=Setup(in,out);
+
+ if(R > 0 && threads == 1 && plan1 != plan2) {
+ fftw_destroy_plan(plan2);
+ plan2=plan1;
+ }
+
+ if(ST.mean > S1.mean-S1.stdev) { // Use FFTW's multi-threading
+ fftw_destroy_plan(plan);
+ if(R > 0) {
+ fftw_destroy_plan(plan2);
+ plan2=NULL;
+ }
+ T=1;
+ Q=M;
+ R=0;
+ plan=planT1;
+ threads=S1.threads;
+ } else { // Do the multi-threading ourselves
+ fftw_destroy_plan(planT1);
+ threads=ST.threads;
+ }
+ } else
+ Setup(in,out); // Synchronize wisdom
+ }
+ }
+
+ fftw_plan Plan(int Q, fftw_complex *in, fftw_complex *out) {
+ return fftw_plan_many_dft(1,&nx,Q,in,NULL,istride,idist,
+ out,NULL,ostride,odist,sign,effort);
+ }
+
+ fftw_plan Plan(int Q, double *in, fftw_complex *out) {
+ return fftw_plan_many_dft_r2c(1,&nx,Q,in,NULL,istride,idist,
+ out,NULL,ostride,odist,effort);
+ }
+
+ fftw_plan Plan(int Q, fftw_complex *in, double *out) {
+ return fftw_plan_many_dft_c2r(1,&nx,Q,in,NULL,istride,idist,
+ out,NULL,ostride,odist,effort);
+ }
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ if(R > 0) {
+ plan2=Plan(Q+1,(I *) in,(O *) out);
+ if(!plan2) return NULL;
+ if(threads == 1) plan1=plan2;
+ }
+ return Plan(Q,(I *) in,(O *) out);
+ }
+
+ void Execute(fftw_plan plan, fftw_complex *in, fftw_complex *out) {
+ fftw_execute_dft(plan,in,out);
+ }
+
+ void Execute(fftw_plan plan, double *in, fftw_complex *out) {
+ fftw_execute_dft_r2c(plan,in,out);
+ }
+
+ void Execute(fftw_plan plan, fftw_complex *in, double *out) {
+ fftw_execute_dft_c2r(plan,in,out);
+ }
+
+ void Execute(Complex *in, Complex *out, bool=false) {
+ if(T == 1)
+ Execute(plan,(I *) in,(O *) out);
+ else {
+ unsigned int extra=T-R;
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(T)
+#endif
+ for(unsigned int i=0; i < T; ++i) {
+ unsigned int iQ=i*Q;
+ if(i < extra)
+ Execute(plan,(I *) in+iQ*idist,(O *) out+iQ*odist);
+ else {
+ unsigned int offset=iQ+i-extra;
+ Execute(plan2,(I *) in+offset*idist,(O *) out+offset*odist);
+ }
+ }
+ }
+ }
+
+ unsigned int Threads() {return std::max(T,threads);}
+
+ ~fftwblock() {
+ if(plan2) fftw_destroy_plan(plan2);
+ }
+};
+
+// Compute the complex Fourier transform of M complex vectors, each of
+// length n.
+// Before calling fft(), the arrays in and out (which may coincide) must be
+// allocated as Complex[M*n].
+//
+// Out-of-place usage:
+//
+// mfft1d Forward(n,-1,M,stride,dist,in,out);
+// Forward.fft(in,out);
+//
+// In-place usage:
+//
+// mfft1d Forward(n,-1,M,stride,dist);
+// Forward.fft(in);
+//
+// Notes:
+// stride is the spacing between the elements of each Complex vector;
+// dist is the spacing between the first elements of the vectors.
+//
+//
+class mfft1d : public fftwblock<fftw_complex,fftw_complex>,
+ public Threadtable<keytype3,keyless3> {
+ static Table threadtable;
+public:
+ mfft1d(unsigned int nx, int sign, unsigned int M=1, size_t stride=1,
+ size_t dist=0, Complex *in=NULL, Complex *out=NULL,
+ unsigned int threads=maxthreads) :
+ fftw(2*((nx-1)*stride+(M-1)*Dist(nx,stride,dist)+1),sign,threads,nx),
+ fftwblock<fftw_complex,fftw_complex>
+ (nx,M,stride,stride,dist,dist,in,out,threads) {}
+
+ mfft1d(unsigned int nx, int sign, unsigned int M,
+ size_t istride, size_t ostride, size_t idist, size_t odist,
+ Complex *in=NULL, Complex *out=NULL, unsigned int threads=maxthreads):
+ fftw(std::max(2*((nx-1)*istride+(M-1)*Dist(nx,istride,idist)+1),
+ 2*((nx-1)*ostride+(M-1)*Dist(nx,ostride,odist)+1)),sign,
+ threads, nx),
+ fftwblock<fftw_complex,fftw_complex>(nx,M,istride,ostride,idist,odist,in,
+ out,threads) {}
+
+ threaddata lookup(bool inplace, unsigned int threads) {
+ return Lookup(threadtable,keytype3(nx,Q,R,threads,inplace));
+ }
+ void store(bool inplace, const threaddata& data) {
+ Store(threadtable,keytype3(nx,Q,R,data.threads,inplace),data);
+ }
+};
+
+// Compute the complex Fourier transform of n real values, using phase sign -1.
+// Before calling fft(), the array in must be allocated as double[n] and
+// the array out must be allocated as Complex[n/2+1]. The arrays in and out
+// may coincide, allocated as Complex[n/2+1].
+//
+// Out-of-place usage:
+//
+// rcfft1d Forward(n,in,out);
+// Forward.fft(in,out);
+//
+// In-place usage:
+//
+// rcfft1d Forward(n);
+// Forward.fft(out);
+//
+// Notes:
+// in contains the n real values stored as a Complex array;
+// out contains the first n/2+1 Complex Fourier values.
+//
+class rcfft1d : public fftw, public Threadtable<keytype1,keyless1> {
+ unsigned int nx;
+ static Table threadtable;
+public:
+ rcfft1d(unsigned int nx, Complex *out=NULL, unsigned int threads=maxthreads)
+ : fftw(2*(nx/2+1),-1,threads,nx), nx(nx) {Setup(out,(double*) NULL);}
+
+ rcfft1d(unsigned int nx, double *in, Complex *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(2*(nx/2+1),-1,threads,nx), nx(nx) {Setup(in,out);}
+
+ threaddata lookup(bool inplace, unsigned int threads) {
+ return Lookup(threadtable,keytype1(nx,threads,inplace));
+ }
+ void store(bool inplace, const threaddata& data) {
+ Store(threadtable,keytype1(nx,data.threads,inplace),data);
+ }
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_r2c_1d(nx,(double *) in,(fftw_complex *) out, effort);
+ }
+
+ void Execute(Complex *in, Complex *out, bool=false) {
+ fftw_execute_dft_r2c(plan,(double *) in,(fftw_complex *) out);
+ }
+};
+
+// Compute the real inverse Fourier transform of the n/2+1 Complex values
+// corresponding to the non-negative part of the frequency spectrum, using
+// phase sign +1.
+// Before calling fft(), the array in must be allocated as Complex[n/2+1]
+// and the array out must be allocated as double[n]. The arrays in and out
+// may coincide, allocated as Complex[n/2+1].
+//
+// Out-of-place usage (input destroyed):
+//
+// crfft1d Backward(n,in,out);
+// Backward.fft(in,out);
+//
+// In-place usage:
+//
+// crfft1d Backward(n);
+// Backward.fft(in);
+//
+// Notes:
+// in contains the first n/2+1 Complex Fourier values.
+// out contains the n real values stored as a Complex array;
+//
+class crfft1d : public fftw, public Threadtable<keytype1,keyless1> {
+ unsigned int nx;
+ static Table threadtable;
+public:
+ crfft1d(unsigned int nx, double *out=NULL, unsigned int threads=maxthreads)
+ : fftw(2*(nx/2+1),1,threads,nx), nx(nx) {Setup(out);}
+
+ crfft1d(unsigned int nx, Complex *in, double *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(realsize(nx,in,out),1,threads,nx), nx(nx) {Setup(in,out);}
+
+ threaddata lookup(bool inplace, unsigned int threads) {
+ return Lookup(threadtable,keytype1(nx,threads,inplace));
+ }
+ void store(bool inplace, const threaddata& data) {
+ Store(threadtable,keytype1(nx,data.threads,inplace),data);
+ }
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_c2r_1d(nx,(fftw_complex *) in,(double *) out,effort);
+ }
+
+ void Execute(Complex *in, Complex *out, bool=false) {
+ fftw_execute_dft_c2r(plan,(fftw_complex *) in,(double *) out);
+ }
+};
+
+// Compute the real Fourier transform of M real vectors, each of length n,
+// using phase sign -1. Before calling fft(), the array in must be
+// allocated as double[M*n] and the array out must be allocated as
+// Complex[M*(n/2+1)]. The arrays in and out may coincide,
+// allocated as Complex[M*(n/2+1)].
+//
+// Out-of-place usage:
+//
+// mrcfft1d Forward(n,M,istride,ostride,idist,odist,in,out);
+// Forward.fft(in,out);
+//
+// In-place usage:
+//
+// mrcfft1d Forward(n,M,istride,ostride,idist,odist);
+// Forward.fft(out);
+//
+// Notes:
+// istride is the spacing between the elements of each real vector;
+// ostride is the spacing between the elements of each Complex vector;
+// idist is the spacing between the first elements of the real vectors;
+// odist is the spacing between the first elements of the Complex vectors;
+// in contains the n real values stored as a Complex array;
+// out contains the first n/2+1 Complex Fourier values.
+//
+class mrcfft1d : public fftwblock<double,fftw_complex>,
+ public Threadtable<keytype3,keyless3> {
+ static Table threadtable;
+public:
+ mrcfft1d(unsigned int nx, unsigned int M,
+ size_t istride, size_t ostride,
+ size_t idist, size_t odist,
+ double *in=NULL, Complex *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(std::max((realsize(nx,in,out)-2)*istride+(M-1)*idist+2,
+ 2*(nx/2*ostride+(M-1)*odist+1)),-1,threads,nx),
+ fftwblock<double,fftw_complex>
+ (nx,M,istride,ostride,idist,odist,(Complex *) in,out,threads) {}
+
+ threaddata lookup(bool inplace, unsigned int threads) {
+ return Lookup(threadtable,keytype3(nx,Q,R,threads,inplace));
+ }
+
+ void store(bool inplace, const threaddata& data) {
+ Store(threadtable,keytype3(nx,Q,R,data.threads,inplace),data);
+ }
+
+ void Normalize(Complex *out) {
+ fftw::Normalize<Complex>(nx/2+1,M,ostride,odist,out);
+ }
+
+ void fftNormalized(double *in, Complex *out=NULL, bool shift=false) {
+ fftw::fftNormalized<double,Complex>(nx/2+1,M,ostride,odist,in,out,false);
+ }
+
+ void fft0Normalized(double *in, Complex *out=NULL) {
+ fftw::fftNormalized<double,Complex>(nx/2+1,M,ostride,odist,in,out,true);
+ }
+};
+
+// Compute the real inverse Fourier transform of M complex vectors, each of
+// length n/2+1, corresponding to the non-negative parts of the frequency
+// spectra, using phase sign +1. Before calling fft(), the array in must be
+// allocated as Complex[M*(n/2+1)] and the array out must be allocated as
+// double[M*n]. The arrays in and out may coincide,
+// allocated as Complex[M*(n/2+1)].
+//
+// Out-of-place usage (input destroyed):
+//
+// mcrfft1d Backward(n,M,istride,ostride,idist,odist,in,out);
+// Backward.fft(in,out);
+//
+// In-place usage:
+//
+// mcrfft1d Backward(n,M,istride,ostride,idist,odist);
+// Backward.fft(out);
+//
+// Notes:
+// stride is the spacing between the elements of each Complex vector;
+// dist is the spacing between the first elements of the vectors;
+// in contains the first n/2+1 Complex Fourier values;
+// out contains the n real values stored as a Complex array.
+//
+class mcrfft1d : public fftwblock<fftw_complex,double>,
+ public Threadtable<keytype3,keyless3> {
+ static Table threadtable;
+public:
+ mcrfft1d(unsigned int nx, unsigned int M, size_t istride, size_t ostride,
+ size_t idist, size_t odist, Complex *in=NULL, double *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(std::max(2*(nx/2*istride+(M-1)*idist+1),
+ (realsize(nx,in,out)-2)*ostride+(M-1)*odist+2),1,threads,nx),
+ fftwblock<fftw_complex,double>
+ (nx,M,istride,ostride,idist,odist,in,(Complex *) out,threads) {}
+
+ threaddata lookup(bool inplace, unsigned int threads) {
+ return Lookup(threadtable,keytype3(nx,Q,R,threads,inplace));
+ }
+
+ void store(bool inplace, const threaddata& data) {
+ Store(threadtable,keytype3(nx,Q,R,data.threads,inplace),data);
+ }
+
+ void Normalize(double *out) {
+ fftw::Normalize<double>(nx,M,ostride,odist,out);
+ }
+
+ void fftNormalized(Complex *in, double *out=NULL, bool shift=false) {
+ fftw::fftNormalized<Complex,double>(nx,M,ostride,odist,in,out,false);
+ }
+
+ void fft0Normalized(Complex *in, double *out=NULL) {
+ fftw::fftNormalized<Complex,double>(nx,M,ostride,odist,in,out,true);
+ }
+};
+
+// Compute the complex two-dimensional Fourier transform of nx times ny
+// complex values. Before calling fft(), the arrays in and out (which may
+// coincide) must be allocated as Complex[nx*ny].
+//
+// Out-of-place usage:
+//
+// fft2d Forward(nx,ny,-1,in,out);
+// Forward.fft(in,out);
+//
+// fft2d Backward(nx,ny,1,in,out);
+// Backward.fft(in,out);
+//
+// fft2d Backward(nx,ny,1,in,out);
+// Backward.fftNormalized(in,out); // True inverse of Forward.fft(out,in);
+//
+// In-place usage:
+//
+// fft2d Forward(nx,ny,-1);
+// Forward.fft(in);
+//
+// fft2d Backward(nx,ny,1);
+// Backward.fft(in);
+//
+// Note:
+// in[ny*i+j] contains the ny Complex values for each i=0,...,nx-1.
+//
+class fft2d : public fftw, public Threadtable<keytype2,keyless2> {
+ unsigned int nx;
+ unsigned int ny;
+ static Table threadtable;
+public:
+ fft2d(unsigned int nx, unsigned int ny, int sign, Complex *in=NULL,
+ Complex *out=NULL, unsigned int threads=maxthreads)
+ : fftw(2*nx*ny,sign,threads), nx(nx), ny(ny) {Setup(in,out);}
+
+#ifdef __Array_h__
+ fft2d(int sign, const Array::array2<Complex>& in,
+ const Array::array2<Complex>& out=Array::NULL2,
+ unsigned int threads=maxthreads)
+ : fftw(2*in.Size(),sign,threads), nx(in.Nx()), ny(in.Ny()) {
+ Setup(in,out);
+ }
+#endif
+
+ threaddata lookup(bool inplace, unsigned int threads) {
+ return this->Lookup(threadtable,keytype2(nx,ny,threads,inplace));
+ }
+ void store(bool inplace, const threaddata& data) {
+ this->Store(threadtable,keytype2(nx,ny,data.threads,inplace),data);
+ }
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_2d(nx,ny,(fftw_complex *) in,(fftw_complex *) out,
+ sign,effort);
+ }
+
+ void Execute(Complex *in, Complex *out, bool=false) {
+ fftw_execute_dft(plan,(fftw_complex *) in,(fftw_complex *) out);
+ }
+};
+
+// Compute the complex two-dimensional Fourier transform of nx times ny real
+// values, using phase sign -1.
+// Before calling fft(), the array in must be allocated as double[nx*ny] and
+// the array out must be allocated as Complex[nx*(ny/2+1)]. The arrays in
+// and out may coincide, allocated as Complex[nx*(ny/2+1)].
+//
+// Out-of-place usage:
+//
+// rcfft2d Forward(nx,ny,in,out);
+// Forward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in,out); // Origin of Fourier domain at (nx/2,0);
+// input destroyed.
+//
+// In-place usage:
+//
+// rcfft2d Forward(nx,ny);
+// Forward.fft(in); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in); // Origin of Fourier domain at (nx/2,0)
+//
+// Notes:
+// in contains the nx*ny real values stored as a Complex array;
+// out contains the upper-half portion (ky >= 0) of the Complex transform.
+//
+class rcfft2d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+public:
+ rcfft2d(unsigned int nx, unsigned int ny, Complex *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(2*nx*(ny/2+1),-1,threads,nx*ny), nx(nx), ny(ny) {Setup(out);}
+
+ rcfft2d(unsigned int nx, unsigned int ny, double *in, Complex *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(2*nx*(ny/2+1),-1,threads,nx*ny), nx(nx), ny(ny) {
+ Setup(in,out);
+ }
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_r2c_2d(nx,ny,(double *) in,(fftw_complex *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out, bool shift=false) {
+ if(shift) {
+ if(inplace) Shift(in,nx,ny,threads);
+ else Shift((double *) in,nx,ny,threads);
+ }
+ fftw_execute_dft_r2c(plan,(double *) in,(fftw_complex *) out);
+ }
+
+ // Set Nyquist modes of even shifted transforms to zero.
+ void deNyquist(Complex *f) {
+ unsigned int nyp=ny/2+1;
+ if(nx % 2 == 0)
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int j=0; j < nyp; ++j)
+ f[j]=0.0;
+ if(ny % 2 == 0)
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; ++i)
+ f[(i+1)*nyp-1]=0.0;
+ }
+};
+
+// Compute the real two-dimensional inverse Fourier transform of the
+// nx*(ny/2+1) Complex values corresponding to the spectral values in the
+// half-plane ky >= 0, using phase sign +1.
+// Before calling fft(), the array in must be allocated as
+// Complex[nx*(ny/2+1)] and the array out must be allocated as
+// double[nx*ny]. The arrays in and out may coincide,
+// allocated as Complex[nx*(ny/2+1)].
+//
+// Out-of-place usage (input destroyed):
+//
+// crfft2d Backward(nx,ny,in,out);
+// Backward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in,out); // Origin of Fourier domain at (nx/2,0)
+//
+// In-place usage:
+//
+// crfft2d Backward(nx,ny);
+// Backward.fft(in); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in); // Origin of Fourier domain at (nx/2,0)
+//
+// Notes:
+// in contains the upper-half portion (ky >= 0) of the Complex transform;
+// out contains the nx*ny real values stored as a Complex array.
+//
+class crfft2d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+public:
+ crfft2d(unsigned int nx, unsigned int ny, double *out=NULL,
+ unsigned int threads=maxthreads) :
+ fftw(2*nx*(ny/2+1),1,threads,nx*ny), nx(nx), ny(ny) {Setup(out);}
+
+ crfft2d(unsigned int nx, unsigned int ny, Complex *in, double *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(nx*realsize(ny,in,out),1,threads,nx*ny), nx(nx), ny(ny) {
+ Setup(in,out);
+ }
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_c2r_2d(nx,ny,(fftw_complex *) in,(double *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out, bool shift=false) {
+ fftw_execute_dft_c2r(plan,(fftw_complex *) in,(double *) out);
+ if(shift) {
+ if(inplace) Shift(out,nx,ny,threads);
+ else Shift((double *) out,nx,ny,threads);
+ }
+ }
+
+ // Set Nyquist modes of even shifted transforms to zero.
+ void deNyquist(Complex *f) {
+ unsigned int nyp=ny/2+1;
+ if(nx % 2 == 0)
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int j=0; j < nyp; ++j)
+ f[j]=0.0;
+ if(ny % 2 == 0)
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; ++i)
+ f[(i+1)*nyp-1]=0.0;
+ }
+};
+
+// Compute the complex three-dimensional Fourier transform of
+// nx times ny times nz complex values. Before calling fft(), the arrays in
+// and out (which may coincide) must be allocated as Complex[nx*ny*nz].
+//
+// Out-of-place usage:
+//
+// fft3d Forward(nx,ny,nz,-1,in,out);
+// Forward.fft(in,out);
+//
+// fft3d Backward(nx,ny,nz,1,in,out);
+// Backward.fft(in,out);
+//
+// fft3d Backward(nx,ny,nz,1,in,out);
+// Backward.fftNormalized(in,out); // True inverse of Forward.fft(out,in);
+//
+// In-place usage:
+//
+// fft3d Forward(nx,ny,nz,-1);
+// Forward.fft(in);
+//
+// fft3d Backward(nx,ny,nz,1);
+// Backward.fft(in);
+//
+// Note:
+// in[nz*(ny*i+j)+k] contains the (i,j,k)th Complex value,
+// indexed by i=0,...,nx-1, j=0,...,ny-1, and k=0,...,nz-1.
+//
+class fft3d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int nz;
+public:
+ fft3d(unsigned int nx, unsigned int ny, unsigned int nz,
+ int sign, Complex *in=NULL, Complex *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(2*nx*ny*nz,sign,threads), nx(nx), ny(ny), nz(nz) {Setup(in,out);}
+
+#ifdef __Array_h__
+ fft3d(int sign, const Array::array3<Complex>& in,
+ const Array::array3<Complex>& out=Array::NULL3,
+ unsigned int threads=maxthreads)
+ : fftw(2*in.Size(),sign,threads), nx(in.Nx()), ny(in.Ny()), nz(in.Nz())
+ {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_3d(nx,ny,nz,(fftw_complex *) in,
+ (fftw_complex *) out, sign, effort);
+ }
+};
+
+// Compute the complex two-dimensional Fourier transform of
+// nx times ny times nz real values, using phase sign -1.
+// Before calling fft(), the array in must be allocated as double[nx*ny*nz]
+// and the array out must be allocated as Complex[nx*ny*(nz/2+1)]. The
+// arrays in and out may coincide, allocated as Complex[nx*ny*(nz/2+1)].
+//
+// Out-of-place usage:
+//
+// rcfft3d Forward(nx,ny,nz,in,out);
+// Forward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in,out); // Origin of Fourier domain at (nx/2,ny/2,0);
+// input destroyed
+// In-place usage:
+//
+// rcfft3d Forward(nx,ny,nz);
+// Forward.fft(in); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in); // Origin of Fourier domain at (nx/2,ny/2,0)
+//
+// Notes:
+// in contains the nx*ny*nz real values stored as a Complex array;
+// out contains the upper-half portion (kz >= 0) of the Complex transform.
+//
+class rcfft3d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int nz;
+public:
+ rcfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(2*nx*ny*(nz/2+1),-1,threads,nx*ny*nz), nx(nx), ny(ny), nz(nz) {
+ Setup(out);
+ }
+
+ rcfft3d(unsigned int nx, unsigned int ny, unsigned int nz, double *in,
+ Complex *out=NULL, unsigned int threads=maxthreads)
+ : fftw(2*nx*ny*(nz/2+1),-1,threads,nx*ny*nz),
+ nx(nx), ny(ny), nz(nz) {Setup(in,out);}
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_r2c_3d(nx,ny,nz,(double *) in,(fftw_complex *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out, bool shift=false) {
+ if(shift) {
+ if(inplace) Shift(in,nx,ny,nz,threads);
+ else Shift((double *) in,nx,ny,nz,threads);
+ }
+ fftw_execute_dft_r2c(plan,(double *) in,(fftw_complex *) out);
+ }
+
+ // Set Nyquist modes of even shifted transforms to zero.
+ void deNyquist(Complex *f) {
+ unsigned int nzp=nz/2+1;
+ unsigned int yz=ny*nzp;
+ if(nx % 2 == 0) {
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int k=0; k < yz; ++k)
+ f[k]=0.0;
+ }
+
+ if(ny % 2 == 0) {
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; ++i) {
+ unsigned int iyz=i*yz;
+ for(unsigned int k=0; k < nzp; ++k)
+ f[iyz+k]=0.0;
+ }
+ }
+
+ if(nz % 2 == 0)
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; ++i)
+ for(unsigned int j=0; j < ny; ++j)
+ f[i*yz+(j+1)*nzp-1]=0.0;
+ }
+};
+
+// Compute the real two-dimensional inverse Fourier transform of the
+// nx*ny*(nz/2+1) Complex values corresponding to the spectral values in the
+// half-plane kz >= 0, using phase sign +1.
+// Before calling fft(), the array in must be allocated as
+// Complex[nx*ny*(nz+1)/2] and the array out must be allocated as
+// double[nx*ny*nz]. The arrays in and out may coincide,
+// allocated as Complex[nx*ny*(nz/2+1)].
+//
+// Out-of-place usage (input destroyed):
+//
+// crfft3d Backward(nx,ny,nz,in,out);
+// Backward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in,out); // Origin of Fourier domain at (nx/2,ny/2,0)
+//
+// In-place usage:
+//
+// crfft3d Backward(nx,ny,nz);
+// Backward.fft(in); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in); // Origin of Fourier domain at (nx/2,ny/2,0)
+//
+// Notes:
+// in contains the upper-half portion (kz >= 0) of the Complex transform;
+// out contains the nx*ny*nz real values stored as a Complex array.
+//
+class crfft3d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int nz;
+public:
+ crfft3d(unsigned int nx, unsigned int ny, unsigned int nz, double *out=NULL,
+ unsigned int threads=maxthreads)
+ : fftw(2*nx*ny*(nz/2+1),1,threads,nx*ny*nz), nx(nx), ny(ny), nz(nz)
+ {Setup(out);}
+
+ crfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *in,
+ double *out=NULL, unsigned int threads=maxthreads)
+ : fftw(nx*ny*(realsize(nz,in,out)),1,threads,nx*ny*nz), nx(nx), ny(ny),
+ nz(nz) {Setup(in,out);}
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_c2r_3d(nx,ny,nz,(fftw_complex *) in,(double *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out, bool shift=false) {
+ fftw_execute_dft_c2r(plan,(fftw_complex *) in,(double *) out);
+ if(shift) {
+ if(inplace) Shift(out,nx,ny,nz,threads);
+ else Shift((double *) out,nx,ny,nz,threads);
+ }
+ }
+
+ // Set Nyquist modes of even shifted transforms to zero.
+ void deNyquist(Complex *f) {
+ unsigned int nzp=nz/2+1;
+ unsigned int yz=ny*nzp;
+ if(nx % 2 == 0) {
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int k=0; k < yz; ++k)
+ f[k]=0.0;
+ }
+
+ if(ny % 2 == 0) {
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; ++i) {
+ unsigned int iyz=i*yz;
+ for(unsigned int k=0; k < nzp; ++k)
+ f[iyz+k]=0.0;
+ }
+ }
+
+ if(nz % 2 == 0)
+#ifndef FFTWPP_SINGLE_THREAD
+#pragma omp parallel for num_threads(threads)
+#endif
+ for(unsigned int i=0; i < nx; ++i)
+ for(unsigned int j=0; j < ny; ++j)
+ f[i*yz+(j+1)*nzp-1]=0.0;
+ }
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/fftw++asy.cc b/graphics/asymptote/fftw++asy.cc
new file mode 100644
index 0000000000..7d52933e50
--- /dev/null
+++ b/graphics/asymptote/fftw++asy.cc
@@ -0,0 +1,9 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_LIBFFTW3
+#include "fftw++.h"
+#include "fftw++.cc"
+
+#endif
diff --git a/graphics/asymptote/fileio.cc b/graphics/asymptote/fileio.cc
new file mode 100644
index 0000000000..d738438820
--- /dev/null
+++ b/graphics/asymptote/fileio.cc
@@ -0,0 +1,180 @@
+/******
+ * fileio.cc
+ * Tom Prince and John Bowman 2004/08/10
+ *
+ * Handle input/output
+ ******/
+
+#include "fileio.h"
+#include "settings.h"
+
+namespace camp {
+
+FILE *pipeout=NULL;
+
+string tab="\t";
+string newline="\n";
+
+ofile Stdout("");
+file nullfile("",false,NOMODE,false,true);
+
+void ifile::ignoreComment()
+{
+ if(comment == 0) return;
+ int c;
+ bool eol=(stream->peek() == '\n');
+ if(eol && csvmode && nullfield) return;
+ for(;;) {
+ while(isspace(c=stream->peek())) {
+ stream->ignore();
+ whitespace += (char) c;
+ }
+ if(c == comment) {
+ whitespace="";
+ while((c=stream->peek()) != '\n' && c != EOF)
+ stream->ignore();
+ if(c == '\n')
+ stream->ignore();
+ } else {if(c != EOF && eol) stream->unget(); return;}
+ }
+}
+
+bool ifile::eol()
+{
+ int c;
+ while(isspace(c=stream->peek())) {
+ if(c == '\n') return true;
+ else {
+ stream->ignore();
+ whitespace += (char) c;
+ }
+ }
+ return false;
+}
+
+bool ifile::nexteol()
+{
+ int c;
+ if(nullfield) {
+ nullfield=false;
+ return true;
+ }
+
+ while(isspace(c=stream->peek())) {
+ if(c == '\n' && comma) {
+ nullfield=true;
+ return false;
+ }
+ stream->ignore();
+ if(c == '\n') {
+ while(isspace(c=stream->peek())) {
+ if(c == '\n') {nullfield=true; return true;}
+ else {
+ stream->ignore();
+ whitespace += (char) c;
+ }
+ }
+ return true;
+ }
+ else whitespace += (char) c;
+ }
+ return false;
+}
+
+void ifile::csv()
+{
+ comma=false;
+ nullfield=false;
+ if(!csvmode || stream->eof()) return;
+ std::ios::iostate rdstate=stream->rdstate();
+ if(stream->fail()) stream->clear();
+ int c=stream->peek();
+ if(c == ',') stream->ignore();
+ else if(c == '\n') {
+ stream->ignore();
+ if(linemode && stream->peek() != EOF) stream->unget();
+ } else stream->clear(rdstate);
+ if(c == ',') comma=true;
+}
+
+void ifile::Read(string& val)
+{
+ string s;
+ if(wordmode) {
+ whitespace="";
+ while(isspace(stream->peek())) stream->ignore();
+ }
+ if(csvmode || wordmode) {
+ bool quote=false;
+ while(stream->good()) {
+ int c=stream->peek();
+ if(c == '"') {quote=!quote; stream->ignore(); continue;}
+ if(!quote) {
+ if(comment && c == comment) {
+ while((c=stream->peek()) != '\n' && c != EOF)
+ stream->ignore();
+ if(wordmode && !linemode)
+ while(isspace(stream->peek())) stream->ignore();
+ if(stream->peek() == '"') {quote=!quote; stream->ignore(); continue;}
+ if(s.empty() && c == '\n') {
+ stream->ignore();
+ continue;
+ }
+ }
+ if(csvmode && (c == ',' || c == '\n'))
+ break;
+ if(wordmode && isspace(c)) {
+ if(!linemode) while(isspace(stream->peek())) stream->ignore();
+ break;
+ }
+ }
+ s += (char) stream->get();
+ }
+ } else
+ getline(*stream,s);
+
+ if(comment) {
+ size_t p=0;
+ while((p=s.find(comment,p)) < string::npos) {
+ if(p+1 < s.length() && s[p+1] == comment) {
+ s.erase(p,1);
+ ++p;
+ } else {
+ s.erase(p);
+ break;
+ }
+ }
+ }
+ size_t n=s.length();
+ if(n > 0) {
+ size_t pos=n-1;
+ if(s[pos] == '\r') s.erase(pos,1);
+ }
+ val=whitespace+s;
+}
+
+void ofile::writeline()
+{
+ if(standard && interact::query && !vm::indebugger) {
+ Int scroll=settings::getScroll();
+ if(scroll && interact::lines > 0 && interact::lines % scroll == 0) {
+ for(;;) {
+ if(!cin.good()) {
+ *stream << newline;
+ cin.clear();
+ break;
+ }
+ int c=cin.get();
+ if(c == '\n') break;
+ // Discard any additional characters
+ while(cin.good() && cin.get() != '\n');
+ if(c == 's') {interact::query=false; break;}
+ if(c == 'q') {interact::query=false; interact::lines=0; throw quit();}
+ }
+ } else *stream << newline;
+ ++interact::lines;
+ } else *stream << newline;
+ if(errorstream::interrupt) {interact::lines=0; throw interrupted();}
+}
+
+} // namespace camp
diff --git a/graphics/asymptote/fileio.h b/graphics/asymptote/fileio.h
new file mode 100644
index 0000000000..d5e78cec29
--- /dev/null
+++ b/graphics/asymptote/fileio.h
@@ -0,0 +1,814 @@
+/******
+ * fileio.h
+ * Tom Prince and John Bowman 2004/05/10
+ *
+ * Handle input/output
+ ******/
+
+#ifndef FILEIO_H
+#define FILEIO_H
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include "common.h"
+
+#ifdef HAVE_RPC_RPC_H
+#include "xstream.h"
+#endif
+
+#include "pair.h"
+#include "triple.h"
+#include "guide.h"
+#include "pen.h"
+
+#include "camperror.h"
+#include "interact.h"
+#include "errormsg.h"
+#include "util.h"
+#include "process.h"
+
+namespace vm {
+extern bool indebugger;
+}
+
+namespace camp {
+
+extern string tab;
+extern string newline;
+
+enum Mode {NOMODE,INPUT,OUTPUT,UPDATE,BINPUT,BOUTPUT,BUPDATE,XINPUT,XOUTPUT,
+ XUPDATE,OPIPE};
+
+static const string FileModes[]=
+{"none","input","output","output(update)",
+ "input(binary)","output(binary)","output(binary,update)",
+ "input(xdr)","output(xdr)","output(xdr,update)","output(pipe)"};
+
+extern FILE *pipeout;
+
+inline void openpipeout()
+{
+ int fd=intcast(settings::getSetting<Int>("outpipe"));
+ if(!pipeout && fd >= 0) pipeout=fdopen(fd,"w");
+ if(!pipeout) {
+ ostringstream buf;
+ buf << "Cannot open outpipe " << fd;
+ reportError(buf);
+ }
+}
+
+class file : public gc {
+protected:
+ string name;
+ bool check; // Check whether input file exists.
+ Mode type;
+
+ Int nx,ny,nz; // Array dimensions
+ bool linemode; // Array reads will stop at eol instead of eof.
+ bool csvmode; // Read comma-separated values.
+ bool wordmode; // Delimit strings by white space instead of eol.
+ bool singlereal; // Read/write single-precision XDR/binary reals.
+ bool singleint; // Read/write single-precision XDR/binary ints.
+ bool signedint; // Read/write signed XDR/binary ints.
+
+ bool closed; // File has been closed.
+ bool standard; // Standard input/output
+ bool binary; // Read in binary mode.
+
+ bool nullfield; // Used to detect a final null field in csv+line mode.
+ string whitespace;
+ size_t index; // Terminator index.
+
+public:
+
+ bool Standard() {return standard;}
+
+ void standardEOF() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ cout << endl;
+#endif
+ }
+
+ template<class T>
+ void purgeStandard(T&) {
+ if(standard) {
+ int c;
+ if(cin.eof())
+ standardEOF();
+ else {
+ cin.clear();
+ while((c=cin.peek()) != EOF) {
+ cin.ignore();
+ if(c == '\n') break;
+ }
+ }
+ }
+ }
+
+ void purgeStandard(string&) {
+ if(cin.eof())
+ standardEOF();
+ }
+
+ void dimension(Int Nx=-1, Int Ny=-1, Int Nz=-1) {nx=Nx; ny=Ny; nz=Nz;}
+
+ file(const string& name, bool check=true, Mode type=NOMODE, bool binary=false,
+ bool closed=false) :
+ name(name), check(check), type(type), linemode(false), csvmode(false),
+ singlereal(false), singleint(true), signedint(true),
+ closed(closed), standard(name.empty()),
+ binary(binary), nullfield(false), whitespace("") {dimension();}
+
+ virtual void open() {}
+
+ void Check() {
+ if(error()) {
+ ostringstream buf;
+ buf << "Cannot open file \"" << name << "\"";
+ reportError(buf);
+ }
+ }
+
+ virtual ~file() {}
+
+ bool isOpen() {
+ if(closed) {
+ ostringstream buf;
+ buf << "I/O operation attempted on ";
+ if(name != "") buf << "closed file \'" << name << "\'";
+ else buf << "null file";
+ reportError(buf);
+ }
+ return true;
+ }
+
+ string filename() {return name;}
+ virtual bool eol() {return false;}
+ virtual bool nexteol() {return false;}
+ virtual bool text() {return false;}
+ virtual bool eof() {return true;}
+ virtual bool error() {return true;}
+ virtual void close() {}
+ virtual void clear() {}
+ virtual Int precision(Int) {return 0;}
+ virtual void flush() {}
+ virtual size_t tell() {return 0;}
+ virtual void seek(Int, bool=true) {}
+
+ string FileMode() {return FileModes[type];}
+
+ void unsupported(const char *rw, const char *type) {
+ ostringstream buf;
+ buf << rw << " of type " << type << " not supported in " << FileMode()
+ << " mode";
+ reportError(buf);
+ }
+
+ void noread(const char *type) {unsupported("Read",type);}
+ void nowrite(const char *type) {unsupported("Write",type);}
+
+ virtual void Read(bool&) {noread("bool");}
+ virtual void Read(Int&) {noread("int");}
+ virtual void Read(double&) {noread("real");}
+ virtual void Read(float&) {noread("real");}
+ virtual void Read(pair&) {noread("pair");}
+ virtual void Read(triple&) {noread("triple");}
+ virtual void Read(char&) {noread("char");}
+ virtual void Read(string&) {noread("string");}
+ virtual void readwhite(string&) {noread("string");}
+
+ virtual void write(bool) {nowrite("bool");}
+ virtual void write(Int) {nowrite("int");}
+ virtual void write(double) {nowrite("real");}
+ virtual void write(const pair&) {nowrite("pair");}
+ virtual void write(const triple&) {nowrite("triple");}
+ virtual void write(const string&) {nowrite("string");}
+ virtual void write(const pen&) {nowrite("pen");}
+ virtual void write(guide *) {nowrite("guide");}
+ virtual void write(const transform&) {nowrite("transform");}
+ virtual void writeline() {nowrite("string");}
+
+ virtual void ignoreComment() {};
+ virtual void csv() {};
+
+ template<class T>
+ void ignoreComment(T&) {
+ ignoreComment();
+ }
+
+ void ignoreComment(string&) {}
+ void ignoreComment(char&) {}
+
+ template<class T>
+ void read(T& val) {
+ if(binary) Read(val);
+ else {
+ if(standard) clear();
+ if(errorstream::interrupt) throw interrupted();
+ else {
+ ignoreComment(val);
+ val=T();
+ if(!nullfield)
+ Read(val);
+ csv();
+ whitespace="";
+ }
+ }
+ }
+
+ Int Nx() {return nx;}
+ Int Ny() {return ny;}
+ Int Nz() {return nz;}
+
+ void Nx(Int n) {nx=n;}
+ void Ny(Int n) {ny=n;}
+ void Nz(Int n) {nz=n;}
+
+ void LineMode(bool b) {linemode=b;}
+ bool LineMode() {return linemode;}
+
+ void CSVMode(bool b) {csvmode=b; if(b) wordmode=false;}
+ bool CSVMode() {return csvmode;}
+
+ void WordMode(bool b) {wordmode=b; if(b) csvmode=false;}
+ bool WordMode() {return wordmode;}
+
+ void SingleReal(bool b) {singlereal=b;}
+ bool SingleReal() {return singlereal;}
+
+ void SingleInt(bool b) {singleint=b;}
+ bool SingleInt() {return singleint;}
+
+ void SignedInt(bool b) {signedint=b;}
+ bool SignedInt() {return signedint;}
+};
+
+class opipe : public file {
+public:
+ opipe(const string& name) : file(name,false,OPIPE) {standard=false;}
+
+ void open() {
+ openpipeout();
+ }
+
+ bool text() {return true;}
+ bool eof() {return pipeout ? feof(pipeout) : true;}
+ bool error() {return pipeout ? ferror(pipeout) : true;}
+ void clear() {if(pipeout) clearerr(pipeout);}
+ void flush() {if(pipeout) fflush(pipeout);}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && pipeout) {
+ clear();
+ fseek(pipeout,pos,begin ? SEEK_SET : SEEK_END);
+ }
+ }
+
+ size_t tell() {
+ return pipeout ? ftell(pipeout) : 0;
+ }
+
+ void write(const string& val) {
+ fprintf(pipeout,"%s",val.c_str());
+ }
+
+ void write(bool val) {
+ ostringstream s;
+ s << val;
+ write(s.str());
+ }
+
+ void write(Int val) {
+ ostringstream s;
+ s << val;
+ write(s.str());
+ }
+ void write(double val) {
+ ostringstream s;
+ s << val;
+ write(s.str());
+ }
+ void write(const pair& val) {
+ ostringstream s;
+ s << val;
+ write(s.str());
+ }
+ void write(const triple& val) {
+ ostringstream s;
+ s << val;
+ write(s.str());
+ }
+
+ void write(const pen &val) {
+ ostringstream s;
+ s << val;
+ write(s.str());
+ }
+
+ void write(guide *val) {
+ ostringstream s;
+ s << *val;
+ write(s.str());
+ }
+
+ void write(const transform& val) {
+ ostringstream s;
+ s << val;
+ write(s.str());
+ }
+
+ void writeline() {
+ fprintf(pipeout,"\n");
+ if(errorstream::interrupt) throw interrupted();
+ }
+};
+
+class ifile : public file {
+protected:
+ istream *stream;
+ std::fstream *fstream;
+ char comment;
+ std::ios::openmode mode;
+ bool comma;
+
+public:
+ ifile(const string& name, char comment, bool check=true, Mode type=INPUT,
+ std::ios::openmode mode=std::ios::in) :
+ file(name,check,type), stream(&cin), fstream(NULL), comment(comment),
+ mode(mode), comma(false) {}
+
+ // Binary file
+ ifile(const string& name, bool check=true, Mode type=BINPUT,
+ std::ios::openmode mode=std::ios::in) :
+ file(name,check,type,true), mode(mode) {}
+
+ ~ifile() {close();}
+
+ void open() {
+ if(standard) {
+ if(mode & std::ios::binary)
+ reportError("Cannot open standard input in binary mode");
+ stream=&cin;
+ } else {
+ if(mode & std::ios::out)
+ name=outpath(name);
+ stream=fstream=new std::fstream(name.c_str(),mode);
+ if(mode & std::ios::out) {
+ if(error()) {
+ delete fstream;
+ std::ofstream f(name.c_str());
+ f.close();
+ stream=fstream=new std::fstream(name.c_str(),mode);
+ }
+ }
+ index=processData().ifile.add(fstream);
+ if(check) Check();
+ }
+ }
+
+ bool eol();
+ bool nexteol();
+
+ bool text() {return true;}
+ bool eof() {return stream->eof();}
+ bool error() {return stream->fail();}
+
+ void close() {
+ if(!standard && fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().ifile.remove(index);
+ }
+ }
+
+ void clear() {stream->clear();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seekg(pos,begin ? std::ios::beg : std::ios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tellg();
+ else
+ return 0;
+ }
+
+ void csv();
+
+ virtual void ignoreComment();
+
+ // Skip over white space
+ void readwhite(string& val) {val=string(); *stream >> val;}
+
+ void Read(bool &val) {string t; readwhite(t); val=(t == "true");}
+ void Read(Int& val) {*stream >> val;}
+ void Read(double& val) {*stream >> val;}
+ void Read(pair& val) {*stream >> val;}
+ void Read(triple& val) {*stream >> val;}
+ void Read(char& val) {stream->get(val);}
+ void Read(string& val);
+};
+
+class iofile : public ifile {
+public:
+ iofile(const string& name, char comment=0) :
+ ifile(name,comment,true,UPDATE,std::ios::in | std::ios::out) {}
+
+ Int precision(Int p) {
+ return p == 0 ? stream->precision() : stream->precision(p);
+ }
+ void flush() {if(fstream) fstream->flush();}
+
+ void write(bool val) {*fstream << (val ? "true " : "false ");}
+ void write(Int val) {*fstream << val;}
+ void write(double val) {*fstream << val;}
+ void write(const pair& val) {*fstream << val;}
+ void write(const triple& val) {*fstream << val;}
+ void write(const string& val) {*fstream << val;}
+ void write(const pen& val) {*fstream << val;}
+ void write(guide *val) {*fstream << *val;}
+ void write(const transform& val) {*fstream << val;}
+
+ void writeline() {
+ *fstream << newline;
+ if(errorstream::interrupt) throw interrupted();
+ }
+};
+
+class ofile : public file {
+protected:
+ ostream *stream;
+ std::ofstream *fstream;
+ std::ios::openmode mode;
+public:
+ ofile(const string& name, Mode type=OUTPUT,
+ std::ios::openmode mode=std::ios::trunc) :
+ file(name,true,type), stream(&cout), fstream(NULL), mode(mode) {}
+
+ ~ofile() {close();}
+
+ void open() {
+ if(standard) {
+ if(mode & std::ios::binary)
+ reportError("Cannot open standard output in binary mode");
+ stream=&cout;
+ } else {
+ name=outpath(name);
+ stream=fstream=new std::ofstream(name.c_str(),mode | std::ios::trunc);
+ index=processData().ofile.add(fstream);
+ Check();
+ }
+ }
+
+ bool text() {return true;}
+ bool eof() {return stream->eof();}
+ bool error() {return stream->fail();}
+
+ void close() {
+ if(!standard && fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().ofile.remove(index);
+ }
+ }
+ void clear() {stream->clear();}
+ Int precision(Int p) {
+ return p == 0 ? stream->precision() : stream->precision(p);
+ }
+ void flush() {stream->flush();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seekp(pos,begin ? std::ios::beg : std::ios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tellp();
+ else
+ return 0;
+ }
+
+ bool enabled() {return !standard || settings::verbose > 1 ||
+ interact::interactive || !settings::getSetting<bool>("quiet");}
+
+ void write(bool val) {*stream << (val ? "true " : "false ");}
+ void write(Int val) {*stream << val;}
+ void write(double val) {*stream << val;}
+ void write(const pair& val) {*stream << val;}
+ void write(const triple& val) {*stream << val;}
+ void write(const string& val) {*stream << val;}
+ void write(const pen& val) {*stream << val;}
+ void write(guide *val) {*stream << *val;}
+ void write(const transform& val) {*stream << val;}
+
+ void writeline();
+};
+
+class ibfile : public ifile {
+public:
+ ibfile(const string& name, bool check=true, Mode type=BINPUT,
+ std::ios::openmode mode=std::ios::in) :
+ ifile(name,check,type,mode | std::ios::binary) {}
+ template<class T>
+ void iread(T& val) {
+ val=T();
+ if(fstream) fstream->read((char *) &val,sizeof(T));
+ }
+
+ void Read(bool& val) {iread(val);}
+ void Read(Int& val) {
+ if(signedint) {
+ if(singleint) {int ival; iread(ival); val=ival;}
+ else iread(val);
+ } else {
+ if(singleint) {unsigned ival; iread(ival); val=Intcast(ival);}
+ else {unsignedInt ival; iread(ival); val=Intcast(ival);}
+ }
+ }
+ void Read(char& val) {iread(val);}
+ void Read(string& val) {char c; iread(c); val=c;}
+
+ void Read(double& val) {
+ if(singlereal) {float fval; iread(fval); val=fval;}
+ else iread(val);
+ }
+};
+
+class iobfile : public ibfile {
+public:
+ iobfile(const string& name) :
+ ibfile(name,true,BUPDATE,std::ios::in | std::ios::out) {}
+
+ void flush() {if(fstream) fstream->flush();}
+
+ template<class T>
+ void iwrite(T val) {
+ if(fstream) fstream->write((char *) &val,sizeof(T));
+ }
+
+ void write(bool val) {iwrite(val);}
+ void write(Int val) {
+ if(signedint) {
+ if(singleint) iwrite(intcast(val));
+ else iwrite(val);
+ } else {
+ if(singleint) iwrite(unsignedcast(val));
+ else iwrite(unsignedIntcast(val));
+ }
+ }
+ void write(const string& val) {iwrite(val);}
+ void write(const pen& val) {iwrite(val);}
+ void write(guide *val) {iwrite(val);}
+ void write(const transform& val) {iwrite(val);}
+ void write(double val) {
+ if(singlereal) iwrite((float) val);
+ else iwrite(val);
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+ void writeline() {}
+};
+
+class obfile : public ofile {
+public:
+ obfile(const string& name) : ofile(name,BOUTPUT,std::ios::binary) {}
+
+ template<class T>
+ void iwrite(T val) {
+ if(fstream) fstream->write((char *) &val,sizeof(T));
+ }
+
+ void write(bool val) {iwrite(val);}
+ void write(Int val) {
+ if(signedint) {
+ if(singleint) iwrite(intcast(val));
+ else iwrite(val);
+ } else {
+ if(singleint) iwrite(unsignedcast(val));
+ else iwrite(unsignedIntcast(val));
+ }
+ }
+ void write(const string& val) {iwrite(val);}
+ void write(const pen& val) {iwrite(val);}
+ void write(guide *val) {iwrite(val);}
+ void write(const transform& val) {iwrite(val);}
+ void write(double val) {
+ if(singlereal) iwrite((float) val);
+ else iwrite(val);
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+
+ void writeline() {}
+};
+
+#ifdef HAVE_RPC_RPC_H
+
+class ixfile : public file {
+protected:
+ xdr::ioxstream *fstream;
+ xdr::xios::open_mode mode;
+public:
+ ixfile(const string& name, bool check=true, Mode type=XINPUT,
+ xdr::xios::open_mode mode=xdr::xios::in) :
+ file(name,check,type,true), fstream(NULL), mode(mode) {}
+
+ void open() {
+ fstream=new xdr::ioxstream(name.c_str(),mode);
+ index=processData().ixfile.add(fstream);
+ if(check) Check();
+ }
+
+ void close() {
+ if(fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().ixfile.remove(index);
+ }
+ }
+
+ ~ixfile() {close();}
+
+ bool eof() {return fstream ? fstream->eof() : true;}
+ bool error() {return fstream ? fstream->fail() : true;}
+
+ void clear() {if(fstream) fstream->clear();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tell();
+ else
+ return 0;
+ }
+
+ void Read(Int& val) {
+ if(signedint) {
+ if(singleint) {int ival=0; *fstream >> ival; val=ival;}
+ else {val=0; *fstream >> val;}
+ } else {
+ if(singleint) {unsigned ival=0; *fstream >> ival; val=Intcast(ival);}
+ else {unsignedInt ival=0; *fstream >> ival; val=Intcast(ival);}
+ }
+ }
+ void Read(double& val) {
+ if(singlereal) {float fval=0.0; *fstream >> fval; val=fval;}
+ else {
+ val=0.0;
+ *fstream >> val;
+ }
+ }
+ void Read(pair& val) {
+ double x,y;
+ Read(x);
+ Read(y);
+ val=pair(x,y);
+ }
+ void Read(triple& val) {
+ double x,y,z;
+ Read(x);
+ Read(y);
+ Read(z);
+ val=triple(x,y,z);
+ }
+};
+
+class ioxfile : public ixfile {
+public:
+ ioxfile(const string& name) : ixfile(name,true,XUPDATE,xdr::xios::out) {}
+
+ void flush() {if(fstream) fstream->flush();}
+
+ void write(Int val) {
+ if(signedint) {
+ if(singleint) *fstream << intcast(val);
+ else *fstream << val;
+ } else {
+ if(singleint) *fstream << unsignedcast(val);
+ else *fstream << unsignedIntcast(val);
+ }
+ }
+ void write(double val) {
+ if(singlereal) *fstream << (float) val;
+ else *fstream << val;
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+};
+
+class oxfile : public file {
+ xdr::oxstream *fstream;
+public:
+ oxfile(const string& name) : file(name,true,XOUTPUT), fstream(NULL) {}
+
+ void open() {
+ fstream=new xdr::oxstream(outpath(name).c_str(),xdr::xios::trunc);
+ index=processData().oxfile.add(fstream);
+ Check();
+ }
+
+ void close() {
+ if(fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().oxfile.remove(index);
+ }
+ }
+
+ ~oxfile() {close();}
+
+ bool eof() {return fstream ? fstream->eof() : true;}
+ bool error() {return fstream ? fstream->fail() : true;}
+ void clear() {if(fstream) fstream->clear();}
+ void flush() {if(fstream) fstream->flush();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tell();
+ else
+ return 0;
+ }
+
+ void write(Int val) {
+ if(signedint) {
+ if(singleint) *fstream << intcast(val);
+ else *fstream << val;
+ } else {
+ if(singleint) *fstream << unsignedcast(val);
+ else *fstream << unsignedIntcast(val);
+ }
+ }
+ void write(double val) {
+ if(singlereal) *fstream << (float) val;
+ else *fstream << val;
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+};
+
+#endif
+
+extern ofile Stdout;
+extern file nullfile;
+
+} // namespace camp
+
+#endif // FILEIO_H
diff --git a/graphics/asymptote/findsym.pl b/graphics/asymptote/findsym.pl
new file mode 100755
index 0000000000..9cfe6c131b
--- /dev/null
+++ b/graphics/asymptote/findsym.pl
@@ -0,0 +1,53 @@
+#!/usr/bin/env perl
+#####
+# findsym.pl
+# Andy Hammerlindl 2010/06/01
+#
+# Extract static symbols used in builtin.cc and write code so that they are
+# translated only once when creating the symbol table.
+#####
+
+$outname = shift(@ARGV);
+if (not $outname) {
+ print STDERR "usage ./findsym.pl out_symbols.h file1.cc file2.cc ...\n";
+ exit(1);
+}
+
+open(header, ">$outname") ||
+ die("Couldn't open $outname for writing");
+
+print header <<END;
+/*****
+ * This file is automatically generated by findsym.pl
+ * Changes will be overwritten.
+ *****/
+
+// If the ADDSYMBOL macro is not already defined, define it with the default
+// purpose of referring to an external pre-translated symbol, such that
+// SYM(name) also refers to that symbol.
+#ifndef ADDSYMBOL
+ #define ADDSYMBOL(name) extern sym::symbol PRETRANSLATED_SYMBOL_##name
+ #define SYM(name) PRETRANSLATED_SYMBOL_##name
+#endif
+
+END
+
+sub add {
+ print header "ADDSYMBOL(".$_[0].");\n";
+}
+
+my %symbols = ();
+
+foreach my $inname (@ARGV) {
+ open(infile, $inname) ||
+ die("Couldn't open $inname");
+ while (<infile>) {
+ while (m/SYM\(([_A-Za-z][_A-Za-z0-9]*)\)/gx) {
+ $symbols{ $1 } = 1;
+ }
+ }
+}
+
+foreach my $s (sort keys %symbols) {
+ add($s);
+}
diff --git a/graphics/asymptote/flatguide.cc b/graphics/asymptote/flatguide.cc
new file mode 100644
index 0000000000..1bbf375593
--- /dev/null
+++ b/graphics/asymptote/flatguide.cc
@@ -0,0 +1,53 @@
+/*****
+ * flatguide.cc
+ * Andy Hammerlindl 2005/02/23
+ *
+ * The data structure that builds up a knotlist. This is done by calling in
+ * order the methods to set knots, specifiers, and tensions.
+ * Used by the guide solving routines.
+ *****/
+
+#include "flatguide.h"
+
+namespace camp {
+
+void flatguide::addPre(path& p, Int j)
+{
+ setSpec(new controlSpec(p.precontrol(j),p.straight(j-1)),IN);
+}
+void flatguide::addPoint(path& p, Int j)
+{
+ add(p.point(j));
+}
+void flatguide::addPost(path& p, Int j)
+{
+ setSpec(new controlSpec(p.postcontrol(j),p.straight(j)),OUT);
+}
+
+void flatguide::uncheckedAdd(path p, bool allowsolve)
+{
+ Int n=p.length();
+ if(n < 0) return;
+ if(n == 0) {
+ addPoint(p,0);
+ return;
+ }
+ int nminus1=n-1;
+ if(!allowsolve && p.cyclic()) addPre(p,0);
+ for(Int i=0; i < nminus1;) {
+ addPoint(p,i);
+ addPost(p,i);
+ ++i;
+ addPre(p,i);
+ }
+ addPoint(p,nminus1);
+ addPost(p,nminus1);
+ if(allowsolve || !p.cyclic()) {
+ addPre(p,n);
+ addPoint(p,n);
+ }
+}
+
+spec flatguide::open;
+
+}
diff --git a/graphics/asymptote/flatguide.h b/graphics/asymptote/flatguide.h
new file mode 100644
index 0000000000..c4d5c9bce6
--- /dev/null
+++ b/graphics/asymptote/flatguide.h
@@ -0,0 +1,190 @@
+/*****
+ * flatguide.h
+ * Andy Hammerlindl 2005/02/23
+ *
+ * The data structure that builds up a knotlist. This is done by calling in
+ * order the methods to set knots, specifiers, and tensions.
+ * Used by the guide solving routines.
+ *
+ * NOTE: figure out how nullpath{}..a should be handled.
+ *****/
+
+#ifndef FLATGUIDE_H
+#define FLATGUIDE_H
+
+#include "knot.h"
+#include "guideflags.h"
+
+namespace camp {
+
+class flatguide
+{
+ // A cached solution of the path. When traversing through a tree of guides,
+ // if a cycle tag is encountered, then the path is solved up to that point.
+ // If the guide continues from there (which rarely occurs in practice), all of
+ // the control points solved are added as control specifiers, and then solved
+ // into a path again. In the (usual) case that a cycle ends a path, the
+ // cached path avoids this second pass.
+ bool solved;
+
+ // Used by reverse(guide) to indicate the presence of an unresolved
+ // interior cycle.
+ bool precycle;
+
+ path p;
+
+ cvector<knot> nodes;
+
+ // Information before the first knot. For a non-cyclic guide, this is
+ // ignored. For a cyclic guide, it may be useful, but I can't determine a
+ // sensible way to use it yet.
+ tension tout;
+ spec *out;
+
+ // Information for the next knot to come.
+ tension tin;
+ spec *in;
+
+ static spec open;
+
+ tension& tref(side s)
+ {
+ switch (s) {
+ case OUT:
+ return nodes.empty() ? tout : nodes.back().tout;
+ case IN:
+ default:
+ return tin;
+ }
+ }
+
+ // Returns a reference to a spec* so that it may be assigned.
+ spec*& sref(side s)
+ {
+ switch (s) {
+ case OUT:
+ return nodes.empty() ? out : nodes.back().out;
+ case IN:
+ default:
+ return in;
+ }
+ }
+
+ void addPre(path& p, Int j);
+ void addPoint(path& p, Int j);
+ void addPost(path& p, Int j);
+
+ void clearNodes() {
+ nodes.clear();
+ in=&open;
+ tin=tension();
+ }
+ void clearPath() {
+ p=path();
+ solved=false;
+ }
+
+ void uncheckedAdd(path p, bool allowsolve=true);
+
+ // Sets solved to false, indicating that the path has been updated since last
+ // being solved. Also, copies a solved path back in as knots and control
+ // specifiers, as it will have to be solved again.
+ void update() {
+ if (solved) {
+ solved=false;
+ clearNodes();
+ add(p);
+ clearPath();
+ }
+ }
+
+public:
+ flatguide()
+ : solved(true), precycle(false), p(), out(&open), in(&open) {}
+
+ Int size() const {
+ return (Int) nodes.size();
+ }
+
+ knot Nodes(Int i) const {
+ return nodes[i];
+ }
+
+ void setTension(tension t, side s) {
+ update();
+ tref(s)=t;
+ }
+ void setSpec(spec *p, side s) {
+ assert(p);
+ update();
+ spec *&ref=sref(s);
+ // Control specifiers trump normal direction specifiers.
+ if (!ref || !ref->controlled() || p->controlled())
+ ref=p;
+ }
+
+ void add(pair z) {
+ update();
+ // Push the pair onto the vector as a knot, using the current in-specifier
+ // and in-tension for the in side for the knot. Use default values for the
+ // out side, as those will be set after the point is added.
+ nodes.push_back(knot(z,in,&open,tin,tension()));
+
+ // Reset the in-spec and in-tension to defaults;
+ tin=tension();
+ in=&open;
+ }
+
+ // Reverts to an empty state.
+ void add(path p, bool allowsolve=true) {
+ update();
+ uncheckedAdd(p,allowsolve);
+ }
+
+ void clear() {
+ clearNodes();
+ clearPath();
+ }
+
+ void close() {
+ if(!nodes.empty()) {
+ nodes.front().in=in;
+ nodes.front().tin=tin;
+ }
+ }
+
+ void resolvecycle() {
+ if(!nodes.empty())
+ nodes.push_back(nodes.front());
+ }
+
+ void precyclic(bool b) {
+ precycle=b;
+ }
+
+ bool precyclic() {
+ return precycle;
+ }
+
+ // Once all information has been added, release the flat result.
+ simpleknotlist list(bool cycles=false) {
+ if(cycles && !nodes.empty()) close();
+ return simpleknotlist(nodes,cycles);
+ }
+
+ // Yield a path from the guide as represented here.
+ path solve(bool cycles=false) {
+ if (solved)
+ return p;
+ else {
+ simpleknotlist l=list(cycles);
+ p=camp::solve(l);
+ solved=true;
+ return p;
+ }
+ }
+};
+
+} // namespace camp
+
+#endif // FLATGUIDE_H
diff --git a/graphics/asymptote/fpu.h b/graphics/asymptote/fpu.h
new file mode 100644
index 0000000000..bf60a21dac
--- /dev/null
+++ b/graphics/asymptote/fpu.h
@@ -0,0 +1,41 @@
+#ifndef FPU_H
+#define FPU_H
+
+#ifdef __GNU_VISIBLE
+#undef __GNU_VISIBLE
+#define __GNU_VISIBLE 1
+#endif
+
+#include "common.h"
+
+#ifdef HAVE_FEENABLEEXCEPT
+#include <fenv.h>
+
+inline int fpu_exceptions() {
+ int excepts=0;
+#ifdef FE_INVALID
+ excepts |= FE_INVALID;
+#endif
+#ifdef FE_DIVBYZERO
+ excepts |= FE_DIVBYZERO;
+#endif
+#ifdef FE_OVERFLOW
+ excepts |= FE_OVERFLOW;
+#endif
+ return excepts;
+}
+
+inline void fpu_trap(bool trap=true)
+{
+ // Conditionally trap FPU exceptions on NaN, zero divide and overflow.
+ if(trap) feenableexcept(fpu_exceptions());
+ else fedisableexcept(fpu_exceptions());
+}
+
+#else
+
+inline void fpu_trap(bool=true) {}
+
+#endif
+
+#endif
diff --git a/graphics/asymptote/frame.h b/graphics/asymptote/frame.h
new file mode 100644
index 0000000000..804e89baea
--- /dev/null
+++ b/graphics/asymptote/frame.h
@@ -0,0 +1,98 @@
+/*****
+ * frame.h
+ * Andy Hammerlindl 2002/07/22
+ *
+ * Describes the frame levels for the functions of the language.
+ * Also creates accesses for the variable for automated loading
+ * and saving of variables.
+ *****/
+
+#ifndef FRAME_H
+#define FRAME_H
+
+#include <cassert>
+
+#include "access.h"
+
+namespace trans {
+
+class frame : public gc {
+ frame *parent;
+ size_t numFormals;
+ Int numLocals;
+
+ // With the SIMPLE_FRAME flag, the size of frames cannot be changed at
+ // runtime. This is an issue for runnable-at-a-time mode, where global
+ // variables can be continually added. To handle this, the frame for
+ // global variables is an "indirect" frame. It holds one variable, which is
+ // a link to another frame. When the subframe is too small, a larger
+ // runtime array is allocated, and the link is changed.
+ enum {DIRECT_FRAME, INDIRECT_FRAME} style;
+
+#ifdef DEBUG_FRAME
+ string name;
+#endif
+
+ frame(string name)
+ : parent(new frame("<subframe of " + name + ">", 0, 0)),
+ numFormals(0), numLocals(1), style(INDIRECT_FRAME)
+#ifdef DEBUG_FRAME
+ , name(name)
+#endif
+ {}
+
+public:
+ frame(string name, frame *parent, size_t numFormals)
+ : parent(parent), numFormals(numFormals), numLocals(0),
+ style(DIRECT_FRAME)
+#ifdef DEBUG_FRAME
+ , name(name)
+#endif
+ {}
+
+ static frame *indirect_frame(string name) {
+ return new frame(name);
+ }
+
+ frame *getParent() {
+ return parent;
+ }
+
+ // Which variable stores the link to the parent frame.
+ Int parentIndex() {
+ return numFormals;
+ }
+
+ Int size() {
+ if (style == DIRECT_FRAME)
+ return (Int) (1+numFormals+numLocals);
+ else
+ return parent->size();
+ }
+
+ access *accessFormal(size_t index) {
+ assert(index < numFormals);
+ assert(style == DIRECT_FRAME);
+ return new localAccess((Int) (index), this);
+ }
+
+ access *allocLocal() {
+ if (style == DIRECT_FRAME)
+ return new localAccess((Int) (1 + numFormals + numLocals++), this);
+ else
+ return parent->allocLocal();
+ }
+};
+
+inline void print(ostream& out, frame *f) {
+ out << f;
+ if (f != 0) {
+ out << " -> ";
+ print(out, f->getParent());
+ }
+}
+
+} // namespace trans
+
+#endif
+
diff --git a/graphics/asymptote/fundec.cc b/graphics/asymptote/fundec.cc
new file mode 100644
index 0000000000..c83dd4b234
--- /dev/null
+++ b/graphics/asymptote/fundec.cc
@@ -0,0 +1,318 @@
+/*****
+ * fundec.h
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Defines the semantics for defining functions. Both the newexp syntax, and
+ * the abbreviated C-style function definition.
+ *****/
+
+#include "fundec.h"
+#include "errormsg.h"
+#include "coenv.h"
+#include "stm.h"
+#include "runtime.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+using mem::list;
+
+varinit *Default=new definit(nullPos);
+
+void formal::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, keywordOnly ? "formal (keyword only)" : "formal", indent);
+
+ base->prettyprint(out, indent+1);
+ if (start) start->prettyprint(out, indent+1);
+ if (defval) defval->prettyprint(out, indent+1);
+}
+
+types::formal formal::trans(coenv &e, bool encodeDefVal, bool tacit) {
+ return types::formal(getType(e,tacit),
+ getName(),
+ encodeDefVal ? (bool) getDefaultValue() : 0,
+ getExplicit());
+}
+
+types::ty *formal::getType(coenv &e, bool tacit) {
+ types::ty *bt = base->trans(e, tacit);
+ types::ty *t = start ? start->getType(bt, e, tacit) : bt;
+ if (t->kind == ty_void && !tacit) {
+ em.error(getPos());
+ em << "cannot declare parameters of type void";
+ return primError();
+ }
+
+ return t;
+}
+
+void formal::addOps(coenv &e, record *r) {
+ base->addOps(e, r);
+ if (start)
+ start->addOps(base->trans(e, true), e, r);
+}
+
+void formals::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "formals",indent);
+
+ for (list<formal *>::iterator p = fields.begin(); p != fields.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+void formals::addToSignature(signature& sig,
+ coenv &e, bool encodeDefVal, bool tacit)
+{
+ for (list<formal *>::iterator p = fields.begin(); p != fields.end(); ++p) {
+ formal& f=**p;
+ types::formal tf = f.trans(e, encodeDefVal, tacit);
+
+ if (f.isKeywordOnly())
+ sig.addKeywordOnly(tf);
+ else
+ sig.add(tf);
+ }
+
+ if (rest) {
+ if (!tacit && rest->getDefaultValue()) {
+ em.error(rest->getPos());
+ em << "rest parameters cannot have default values";
+ }
+ sig.addRest(rest->trans(e, encodeDefVal, tacit));
+ }
+}
+
+// Returns the types of each parameter as a signature.
+// encodeDefVal means that it will also encode information regarding
+// the default values into the signature
+signature *formals::getSignature(coenv &e, bool encodeDefVal, bool tacit)
+{
+ signature *sig = new signature;
+ addToSignature(*sig,e,encodeDefVal,tacit);
+ return sig;
+}
+
+
+// Returns the corresponding function type, assuming it has a return
+// value of types::ty *result.
+function *formals::getType(types::ty *result, coenv &e,
+ bool encodeDefVal,
+ bool tacit)
+{
+ function *ft = new function(result);
+ addToSignature(ft->sig,e,encodeDefVal,tacit);
+ return ft;
+}
+
+void formals::addOps(coenv &e, record *r)
+{
+ for(list<formal *>::iterator p = fields.begin(); p != fields.end(); ++p)
+ (*p)->addOps(e, r);
+
+ if (rest)
+ rest->addOps(e, r);
+}
+
+// Another helper class. Does an assignment, but relying only on the
+// destination for the type.
+class basicAssignExp : public exp {
+ varEntry *dest;
+ varinit *value;
+public:
+ basicAssignExp(position pos, varEntry *dest, varinit *value)
+ : exp(pos), dest(dest), value(value) {}
+
+ void prettyprint(ostream &out, Int indent) {
+ prettyname(out, "basicAssignExp", indent);
+ }
+
+ types::ty *getType(coenv &) {
+ return dest->getType();
+ }
+
+ types::ty *trans(coenv &e) {
+ // This doesn't handle overloaded types for the destination.
+ value->transToType(e, getType(e));
+ dest->encode(WRITE, pos, e.c);
+ return getType(e);
+ }
+};
+
+void transDefault(coenv &e, position pos, varEntry *v, varinit *init) {
+ // This roughly translates into the statement
+ // if (isDefault(x))
+ // x=init;
+ // where x is the variable in v and isDefault is a function that tests
+ // whether x is the default argument token.
+
+ v->encode(READ, pos, e.c);
+
+ label end = e.c.fwdLabel();
+ e.c.useLabel(inst::jump_if_not_default, end);
+
+ init->transToType(e, v->getType());
+ v->encode(WRITE, pos, e.c);
+ e.c.encodePop();
+
+ e.c.defLabel(end);
+}
+
+void formal::transAsVar(coenv &e, Int index) {
+ symbol name = getName();
+ if (name) {
+ trans::access *a = e.c.accessFormal(index);
+ assert(a);
+
+ // Suppress error messages because they will already be reported
+ // when the formals are translated to yield the type earlier.
+ types::ty *t = getType(e, true);
+ varEntry *v = new varEntry(t, a, 0, getPos());
+
+ // Translate the default argument before adding the formal to the
+ // environment, consistent with the initializers of variables.
+ if (defval)
+ transDefault(e, getPos(), v, defval);
+
+ e.e.addVar(name, v);
+ }
+}
+
+void formals::trans(coenv &e)
+{
+ Int index = 0;
+
+ for (list<formal *>::iterator p=fields.begin(); p!=fields.end(); ++p) {
+ (*p)->transAsVar(e, index);
+ ++index;
+ }
+
+ if (rest) {
+ rest->transAsVar(e, index);
+ ++index;
+ }
+}
+
+void fundef::prettyprint(ostream &out, Int indent)
+{
+ result->prettyprint(out, indent+1);
+ params->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+function *fundef::transType(coenv &e, bool tacit) {
+ bool encodeDefVal=true;
+ return params->getType(result->trans(e, tacit), e, encodeDefVal, tacit);
+}
+
+function *fundef::transTypeAndAddOps(coenv &e, record *r, bool tacit) {
+ result->addOps(e,r);
+ params->addOps(e,r);
+
+ function *ft=transType(e, tacit);
+ e.e.addFunctionOps(ft);
+ if (r)
+ r->e.addFunctionOps(ft);
+
+ return ft;
+}
+
+varinit *fundef::makeVarInit(function *ft) {
+ struct initializer : public varinit {
+ fundef *f;
+ function *ft;
+
+ initializer(fundef *f, function *ft)
+ : varinit(f->getPos()), f(f), ft(ft) {}
+
+ void prettyprint(ostream &out, Int indent) {
+ prettyname(out, "initializer", indent);
+ }
+
+ void transToType(coenv &e, types::ty *target) {
+ assert(ft==target);
+ f->baseTrans(e, ft);
+ }
+ };
+
+ return new initializer(this, ft);
+}
+
+void fundef::baseTrans(coenv &e, types::function *ft)
+{
+ string name = id ? string(id) : string("<anonymous function>");
+
+ // Create a new function environment.
+ coder fc = e.c.newFunction(getPos(), name, ft);
+ coenv fe(fc,e.e);
+
+ // Translate the function.
+ fe.e.beginScope();
+ params->trans(fe);
+
+ body->trans(fe);
+
+ types::ty *rt = ft->result;
+ if (rt->kind != ty_void &&
+ rt->kind != ty_error &&
+ !body->returns()) {
+ em.error(body->getPos());
+ em << "function must return a value";
+ }
+
+ fe.e.endScope();
+
+ // Put an instance of the new function on the stack.
+ vm::lambda *l = fe.c.close();
+ e.c.encode(inst::pushclosure);
+ e.c.encode(inst::makefunc, l);
+}
+
+types::ty *fundef::trans(coenv &e) {
+ // I don't see how addFunctionOps can be useful here.
+ // For instance, in
+ //
+ // new void() {} == null
+ //
+ // callExp has to search for == before translating either argument, and the
+ // operator cannot be added before translation. (getType() is not allowed to
+ // manipulate the environment.)
+ // A new function expression is assigned to a variable, given as a return
+ // value, or used as an argument to a function. In any of these
+ //
+ // We must still addOps though, for the return type and formals. ex:
+ //
+ // new guide[] (guide f(int)) {
+ // return sequence(f, 10);
+ // };
+ function *ft=transTypeAndAddOps(e, (record *)0, false);
+ assert(ft);
+
+ baseTrans(e, ft);
+
+ return ft;
+}
+
+void fundec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fundec '" << id << "'\n";
+
+ fun.prettyprint(out, indent);
+}
+
+void fundec::trans(coenv &e)
+{
+ transAsField(e,0);
+}
+
+void fundec::transAsField(coenv &e, record *r)
+{
+ function *ft = fun.transTypeAndAddOps(e, r, false);
+ assert(ft);
+
+ createVar(getPos(), e, r, id, ft, fun.makeVarInit(ft));
+}
+
+} // namespace absyntax
diff --git a/graphics/asymptote/fundec.h b/graphics/asymptote/fundec.h
new file mode 100644
index 0000000000..5dd0dab85b
--- /dev/null
+++ b/graphics/asymptote/fundec.h
@@ -0,0 +1,173 @@
+/*****
+ * fundec.h
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Defines the semantics for defining functions. Both the newexp syntax, and
+ * the abbreviated C-style function definition.
+ *****/
+
+#ifndef FUNDEC_H
+#define FUNDEC_H
+
+#include "dec.h"
+#include "exp.h"
+
+namespace absyntax {
+
+class formal : public absyn {
+ ty *base;
+ decidstart *start;
+ bool Explicit;
+ varinit *defval;
+ bool keywordOnly;
+
+public:
+ formal(position pos, ty *base, decidstart *start=0, varinit *defval=0,
+ bool Explicit= false, bool keywordOnly=false)
+ : absyn(pos), base(base), start(start), Explicit(Explicit),
+ defval(defval), keywordOnly(keywordOnly) {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ // Build the corresponding types::formal to put into a signature.
+ types::formal trans(coenv &e, bool encodeDefVal, bool tacit=false);
+
+ // Add the formal parameter to the environment to prepare for the
+ // function body's translation.
+ virtual void transAsVar(coenv &e, Int index);
+
+ types::ty *getType(coenv &e, bool tacit=false);
+
+ virtual void addOps(coenv &e, record *r);
+
+ varinit *getDefaultValue() {
+ return defval;
+ }
+
+ symbol getName() {
+ return start ? start->getName() : symbol::nullsym;
+ }
+
+ bool getExplicit() {
+ return Explicit;
+ }
+
+ bool isKeywordOnly() {
+ return keywordOnly;
+ }
+};
+
+class formals : public absyn {
+ //friend class funheader;
+
+ mem::list<formal *> fields;
+ formal *rest;
+
+ // If the list of formals contains at least one keyword-only formal.
+ bool keywordOnly;
+
+ void addToSignature(types::signature& sig,
+ coenv &e, bool encodeDefVal, bool tacit);
+public:
+ formals(position pos)
+ : absyn(pos), rest(0), keywordOnly(false) {}
+
+ virtual ~formals() {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual void add(formal *f) {
+ if (f->isKeywordOnly()) {
+ keywordOnly = true;
+ }
+ else if (rest) {
+ em.error(f->getPos());
+ em << "normal parameter after rest parameter";
+ }
+ else if (keywordOnly) {
+ em.error(f->getPos());
+ em << "normal parameter after keyword-only parameter";
+ }
+
+ fields.push_back(f);
+ }
+
+ virtual void addRest(formal *f) {
+ if (rest) {
+ em.error(f->getPos());
+ em << "additional rest parameter";
+ }
+ else if (f->isKeywordOnly()) {
+ em.error(f->getPos());
+ em << "rest parameter declared as keyword-only";
+ }
+ rest = f;
+ }
+
+ // Returns the types of each parameter as a signature.
+ // encodeDefVal means that it will also encode information regarding
+ // the default values into the signature
+ types::signature *getSignature(coenv &e,
+ bool encodeDefVal = false,
+ bool tacit = false);
+
+ // Returns the corresponding function type, assuming it has a return
+ // value of "result."
+ types::function *getType(types::ty *result, coenv &e,
+ bool encodeDefVal = false,
+ bool tacit = false);
+
+ virtual void addOps(coenv &e, record *r);
+
+ // Add the formal parameters to the environment to prepare for the
+ // function body's translation.
+ virtual void trans(coenv &e);
+};
+
+class fundef : public exp {
+ ty *result;
+ formals *params;
+ stm *body;
+
+ // If the fundef is part of a fundec, the name of the function is stored
+ // here for debugging purposes.
+ symbol id;
+
+ friend class fundec;
+
+public:
+ fundef(position pos, ty *result, formals *params, stm *body)
+ : exp(pos), result(result), params(params), body(body), id() {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ varinit *makeVarInit(types::function *ft);
+ virtual void baseTrans(coenv &e, types::function *ft);
+ virtual types::ty *trans(coenv &e);
+
+ virtual types::function *transType(coenv &e, bool tacit);
+ virtual types::function *transTypeAndAddOps(coenv &e, record *r, bool tacit);
+ virtual types::ty *getType(coenv &e) {
+ return transType(e, true);
+ }
+};
+
+class fundec : public dec {
+ symbol id;
+ fundef fun;
+
+public:
+ fundec(position pos, ty *result, symbol id, formals *params, stm *body)
+ : dec(pos), id(id), fun(pos, result, params, body)
+ { fun.id = id; }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ void transAsField(coenv &e, record *r);
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/graphics/asymptote/genv.cc b/graphics/asymptote/genv.cc
new file mode 100644
index 0000000000..2f3a030822
--- /dev/null
+++ b/graphics/asymptote/genv.cc
@@ -0,0 +1,134 @@
+/*****
+ * genv.cc
+ * Andy Hammerlindl 2002/08/29
+ *
+ * This is the global environment for the translation of programs. In
+ * actuality, it is basically a module manager. When a module is
+ * requested, it looks for the corresponding filename, and if found,
+ * parses and translates the file, returning the resultant module.
+ *
+ * genv sets up the basic type bindings and function bindings for
+ * builtin functions, casts and operators, and imports plain (if set),
+ * but all other initialization is done by the local environment defined
+ * in env.h.
+ *****/
+
+#include <sstream>
+#include <unistd.h>
+#include <algorithm>
+
+#include "genv.h"
+#include "env.h"
+#include "dec.h"
+#include "stm.h"
+#include "types.h"
+#include "settings.h"
+#include "runtime.h"
+#include "parser.h"
+#include "locate.h"
+#include "interact.h"
+#include "builtin.h"
+
+using namespace types;
+using settings::getSetting;
+using settings::Setting;
+
+// Dynamic loading of external libraries.
+types::record *transExternalModule(trans::genv& ge, string filename, symbol id);
+
+namespace trans {
+
+genv::genv()
+ : imap()
+{
+ // Add settings as a module. This is so that the init file ~/.asy/config.asy
+ // can set settings.
+ imap["settings"]=settings::getSettingsModule();
+
+ // Translate plain in advance, if we're using autoplain.
+ if(getSetting<bool>("autoplain")) {
+ Setting("autoplain")=false;
+
+ // Translate plain without autoplain.
+ getModule(symbol::trans("plain"), "plain");
+
+ Setting("autoplain")=true;
+ }
+#ifdef HAVE_LIBGSL
+ imap["gsl"]=trans::getGSLModule();
+#endif
+}
+
+bool endswith(string suffix, string str)
+{
+ return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
+}
+
+record *genv::loadModule(symbol id, string filename) {
+ // Hackish way to load an external library.
+#if 0
+ if (endswith(".so", filename)) {
+ return transExternalModule(*this, filename, id);
+ }
+#endif
+
+ // Get the abstract syntax tree.
+ absyntax::file *ast = parser::parseFile(filename,"Loading");
+
+ inTranslation.push_front(filename);
+
+ em.sync();
+
+ record *r=ast->transAsFile(*this, id);
+
+ inTranslation.remove(filename);
+
+ return r;
+}
+
+void genv::checkRecursion(string filename) {
+ if (find(inTranslation.begin(), inTranslation.end(), filename) !=
+ inTranslation.end()) {
+ em.sync();
+ em << "error: recursive loading of module '" << filename << "'\n";
+ em.sync();
+ throw handled_error();
+ }
+}
+
+record *genv::getModule(symbol id, string filename) {
+ checkRecursion(filename);
+
+ record *r=imap[filename];
+ if (r)
+ return r;
+ else {
+ record *r=loadModule(id, filename);
+ // Don't add an erroneous module to the dictionary in interactive mode, as
+ // the user may try to load it again.
+ if (!interact::interactive || !em.errors())
+ imap[filename]=r;
+
+ return r;
+ }
+
+}
+
+typedef vm::stack::importInitMap importInitMap;
+
+importInitMap *genv::getInitMap()
+{
+ struct initMap : public importInitMap, public gc {
+ genv &ge;
+ initMap(genv &ge)
+ : ge(ge) {}
+ lambda *operator[](string s) {
+ record *r=ge.imap[s];
+ return r ? r->getInit() : 0;
+ }
+ };
+
+ return new initMap(*this);
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/genv.h b/graphics/asymptote/genv.h
new file mode 100644
index 0000000000..014896e3e2
--- /dev/null
+++ b/graphics/asymptote/genv.h
@@ -0,0 +1,61 @@
+/*****
+ * genv.h
+ * Andy Hammerlindl 2002/08/29
+ *
+ * This is the global environment for the translation of programs. In
+ * actuality, it is basically a module manager. When a module is
+ * requested, it looks for the corresponding filename, and if found,
+ * parses and translates the file, returning the resultant module.
+ *
+ * genv sets up the basic type bindings and function bindings for
+ * builtin functions, casts and operators, and imports plain (if set),
+ * but all other initialization, is done by the local environmet defined
+ * in env.h.
+ *****/
+
+#ifndef GENV_H
+#define GENV_H
+
+#include "common.h"
+#include "table.h"
+#include "record.h"
+#include "absyn.h"
+#include "access.h"
+#include "coenv.h"
+#include "stack.h"
+
+using types::record;
+using vm::lambda;
+
+namespace trans {
+
+class genv : public gc {
+ // The initializer functions for imports, indexed by filename.
+ typedef mem::map<CONST string,record *> importMap;
+ importMap imap;
+
+ // List of modules in translation. Used to detect and prevent infinite
+ // recursion in loading modules.
+ mem::list<string> inTranslation;
+
+ // Checks for recursion in loading, reporting an error and throwing an
+ // exception if it occurs.
+ void checkRecursion(string filename);
+
+ // Translate a module to build the record type.
+ record *loadModule(symbol name, string s);
+
+public:
+ genv();
+
+ // Get an imported module, translating if necessary.
+ record *getModule(symbol name, string s);
+
+ // Uses the filename->record map to build a filename->initializer map to be
+ // used at runtime.
+ vm::stack::importInitMap *getInitMap();
+};
+
+} // namespace trans
+
+#endif
diff --git a/graphics/asymptote/getopt.c b/graphics/asymptote/getopt.c
new file mode 100644
index 0000000000..9bafa453c6
--- /dev/null
+++ b/graphics/asymptote/getopt.c
@@ -0,0 +1,1055 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages. */
+# if defined HAVE_LIBINTL_H || defined _LIBC
+# include <libintl.h>
+# ifndef _
+# define _(msgid) gettext (msgid)
+# endif
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (posixly_correct == NULL
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ int print_errors = opterr;
+ if (optstring[0] == ':')
+ print_errors = 0;
+
+ if (argc < 1)
+ return -1;
+
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (print_errors)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/graphics/asymptote/getopt.h b/graphics/asymptote/getopt.h
new file mode 100644
index 0000000000..0648548081
--- /dev/null
+++ b/graphics/asymptote/getopt.h
@@ -0,0 +1,180 @@
+/* Declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include <features.h>, but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include <ctype.h>, which will pull in <features.h> for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+ extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+ extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+ extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+ extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+ struct option
+ {
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+ };
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+ extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+/* extern int getopt (); */
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+ extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+ extern int getopt_long_only (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+ extern int _getopt_internal (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+ extern int getopt ();
+# ifndef __need_getopt
+ extern int getopt_long ();
+ extern int getopt_long_only ();
+
+ extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/graphics/asymptote/getopt1.c b/graphics/asymptote/getopt1.c
new file mode 100644
index 0000000000..22a7efbdd1
--- /dev/null
+++ b/graphics/asymptote/getopt1.c
@@ -0,0 +1,188 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/graphics/asymptote/glew.c b/graphics/asymptote/glew.c
new file mode 100644
index 0000000000..bea419ea8a
--- /dev/null
+++ b/graphics/asymptote/glew.c
@@ -0,0 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_LIBGL
+#include "GL/glew.c"
+#endif /* HAVE_LIBGL */
diff --git a/graphics/asymptote/glrender.cc b/graphics/asymptote/glrender.cc
new file mode 100644
index 0000000000..d864ed34de
--- /dev/null
+++ b/graphics/asymptote/glrender.cc
@@ -0,0 +1,1789 @@
+/*****
+ * glrender.cc
+ * John Bowman and Orest Shardt
+ * Render 3D Bezier paths and surfaces.
+ *****/
+
+#ifdef __CYGWIN__
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <stdlib.h>
+#include <fstream>
+#include <cstring>
+#include <sys/time.h>
+
+
+#include "common.h"
+#include "locate.h"
+#include "seconds.h"
+#include "statistics.h"
+#include "bezierpatch.h"
+#include "beziercurve.h"
+
+#ifdef HAVE_GL
+
+#ifdef HAVE_LIBGLUT
+#ifdef __MSDOS__
+#ifndef FGAPI
+#define FGAPI GLUTAPI
+#endif
+#ifndef FGAPIENTRY
+#define FGAPIENTRY APIENTRY
+#endif
+#endif
+
+#define GLUT_BUILDING_LIB
+#endif // HAVE_LIBGLUT
+
+#include "picture.h"
+#include "arcball.h"
+#include "bbox3.h"
+#include "drawimage.h"
+#include "interact.h"
+#include "tr.h"
+
+#ifdef HAVE_LIBGLUT
+#ifdef FREEGLUT
+#include <GL/freeglut_ext.h>
+#endif
+#endif
+
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+#include "shaders.h"
+#include "material.h"
+
+#ifdef HAVE_LIBOPENIMAGEIO
+#include <OpenImageIO/imageio.h>
+#endif
+
+using settings::locateFile;
+using camp::Material;
+using camp::Maxmaterials;
+using camp::Nmaterials;
+using camp::nmaterials;
+using utils::seconds;
+
+namespace camp {
+billboard BB;
+GLint materialShader;
+GLint colorShader;
+GLint noNormalShader;
+GLint pixelShader;
+
+size_t Maxmaterials;
+size_t Nmaterials=1;
+size_t nmaterials=48;
+}
+namespace gl {
+
+bool outlinemode=false;
+bool glthread=false;
+bool initialize=true;
+
+GLint Maxvertices;
+Int maxvertices;
+
+using camp::picture;
+using camp::drawRawImage;
+using camp::transform;
+using camp::pair;
+using camp::triple;
+using vm::array;
+using vm::read;
+using camp::bbox3;
+using settings::getSetting;
+using settings::Setting;
+
+bool Iconify=false;
+bool ignorezoom;
+int Fitscreen;
+
+bool queueExport=false;
+bool readyAfterExport=false;
+
+#ifdef HAVE_LIBGLUT
+timeval lasttime;
+timeval lastframetime;
+int oldWidth,oldHeight;
+
+bool Xspin,Yspin,Zspin;
+bool Animate;
+bool Step;
+bool remesh;
+bool forceRemesh=false;
+
+bool queueScreen=false;
+
+int x0,y0;
+string Action;
+
+double lastangle;
+Arcball arcball;
+int window;
+#endif
+
+double Aspect;
+bool View;
+int Oldpid;
+string Prefix;
+const picture* Picture;
+string Format;
+int Width,Height;
+int fullWidth,fullHeight;
+double oWidth,oHeight;
+int screenWidth,screenHeight;
+int maxWidth;
+int maxHeight;
+int maxTileWidth;
+int maxTileHeight;
+
+double T[16];
+
+int Mode;
+
+double Angle;
+bool orthographic;
+double H;
+double xmin,xmax;
+double ymin,ymax;
+double zmin,zmax;
+
+double Xmin,Xmax;
+double Ymin,Ymax;
+
+pair Shift;
+double X,Y;
+double cx,cy;
+double Xfactor,Yfactor;
+
+static const double pi=acos(-1.0);
+static const double degrees=180.0/pi;
+static const double radians=1.0/degrees;
+
+double Background[4];
+size_t Nlights=1; // Maximum number of lights compiled in shader
+size_t nlights; // Actual number of lights
+size_t nlights0;
+triple *Lights;
+double *Diffuse;
+double *Specular;
+bool antialias;
+
+double Zoom;
+double Zoom0;
+double lastzoom;
+
+using glm::dvec3;
+using glm::mat4;
+using glm::dmat4;
+using glm::value_ptr;
+using glm::translate;
+
+mat4 projViewMat;
+mat4 viewMat;
+mat4 normMat;
+
+dmat4 dprojMat;
+dmat4 dviewMat;
+dmat4 drotateMat;
+
+using utils::statistics;
+statistics S;
+
+ModelView modelView;
+GLuint ubo;
+
+#ifdef HAVE_LIBOPENIMAGEIO
+GLuint envMapBuf;
+
+GLuint initHDR() {
+ GLuint tex;
+ glGenTextures(1, &tex);
+
+ auto imagein = OIIO::ImageInput::open(locateFile("res/studio006.hdr").c_str());
+ OIIO::ImageSpec const& imspec = imagein->spec();
+
+ // uses GL_TEXTURE1 for now.
+ glActiveTexture(GL_TEXTURE1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+ std::vector<float> pixels(imspec.width*imspec.height*3);
+ imagein->read_image(pixels.data());
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imspec.width, imspec.height, 0,
+ GL_RGB, GL_FLOAT, pixels.data());
+
+ glGenerateMipmap(GL_TEXTURE_2D);
+ imagein->close();
+
+ glActiveTexture(GL_TEXTURE0);
+ return tex;
+}
+
+#endif
+void updateModelViewData()
+{
+ // Like Fortran, OpenGL uses transposed (column-major) format!
+ dmat4 MV=glm::transpose(dviewMat);
+ dmat4 MVinv=glm::inverse(MV);
+
+ normMat=mat4(MVinv);
+
+ double* T=value_ptr(MV);
+ double* Tinv=value_ptr(MVinv);
+
+ for(int j=0; j < 16; ++j) {
+ modelView.T[j]=T[j];
+ modelView.Tinv[j]=Tinv[j];
+ }
+}
+
+
+GLint shaderProg,shaderProgColor;
+
+double *Rotate;
+void *glrenderWrapper(void *a);
+
+#ifdef HAVE_LIBOSMESA
+OSMesaContext ctx;
+unsigned char *osmesa_buffer;
+#endif
+
+#ifdef HAVE_PTHREAD
+pthread_t mainthread;
+
+pthread_cond_t initSignal=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t initLock=PTHREAD_MUTEX_INITIALIZER;
+
+pthread_cond_t readySignal=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t readyLock=PTHREAD_MUTEX_INITIALIZER;
+
+void endwait(pthread_cond_t& signal, pthread_mutex_t& lock)
+{
+ pthread_mutex_lock(&lock);
+ pthread_cond_signal(&signal);
+ pthread_mutex_unlock(&lock);
+}
+void wait(pthread_cond_t& signal, pthread_mutex_t& lock)
+{
+ pthread_mutex_lock(&lock);
+ pthread_cond_signal(&signal);
+ pthread_cond_wait(&signal,&lock);
+ pthread_mutex_unlock(&lock);
+}
+#endif
+
+template<class T>
+inline T min(T a, T b)
+{
+ return (a < b) ? a : b;
+}
+
+template<class T>
+inline T max(T a, T b)
+{
+ return (a > b) ? a : b;
+}
+
+glm::vec4 vec4(triple v)
+{
+ return glm::vec4(v.getx(),v.gety(),v.getz(),0);
+}
+
+glm::vec4 vec4(double *v)
+{
+ return glm::vec4(v[0],v[1],v[2],v[3]);
+}
+
+void setDimensions(int Width, int Height, double X, double Y)
+{
+ double Aspect=((double) Width)/Height;
+ double xshift=X/Width*lastzoom+Shift.getx()*Xfactor;
+ double yshift=Y/Height*lastzoom+Shift.gety()*Yfactor;
+ double Zoominv=1.0/lastzoom;
+ if(orthographic) {
+ double xsize=Xmax-Xmin;
+ double ysize=Ymax-Ymin;
+ if(xsize < ysize*Aspect) {
+ double r=0.5*ysize*Aspect*Zoominv;
+ double X0=2.0*r*xshift;
+ double Y0=(Ymax-Ymin)*Zoominv*yshift;
+ xmin=-r-X0;
+ xmax=r-X0;
+ ymin=Ymin*Zoominv-Y0;
+ ymax=Ymax*Zoominv-Y0;
+ } else {
+ double r=0.5*xsize/(Aspect*Zoom);
+ double X0=(Xmax-Xmin)*Zoominv*xshift;
+ double Y0=2.0*r*yshift;
+ xmin=Xmin*Zoominv-X0;
+ xmax=Xmax*Zoominv-X0;
+ ymin=-r-Y0;
+ ymax=r-Y0;
+ }
+ } else {
+ double r=H*Zoominv;
+ double rAspect=r*Aspect;
+ double X0=2.0*rAspect*xshift;
+ double Y0=2.0*r*yshift;
+ xmin=-rAspect-X0;
+ xmax=rAspect-X0;
+ ymin=-r-Y0;
+ ymax=r-Y0;
+ }
+}
+
+void frustum(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble nearVal, GLdouble farVal)
+{
+ dprojMat=glm::frustum(left,right,bottom,top,nearVal,farVal);
+ projViewMat=mat4(dprojMat*dviewMat);
+}
+
+void ortho(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble nearVal, GLdouble farVal)
+{
+ dprojMat=glm::ortho(left,right,bottom,top,nearVal,farVal);
+ projViewMat=mat4(dprojMat*dviewMat);
+}
+
+void setProjection()
+{
+ setDimensions(Width,Height,X,Y);
+ if(orthographic) ortho(xmin,xmax,ymin,ymax,-zmax,-zmin);
+ else frustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
+
+#ifdef HAVE_LIBGLUT
+ double arcballRadius=getSetting<double>("arcballradius");
+ arcball.set_params(vec2(0.5*Width,0.5*Height),arcballRadius*Zoom);
+#endif
+}
+
+void drawscene(int Width, int Height)
+{
+#ifdef HAVE_PTHREAD
+ static bool first=true;
+ if(glthread && first && !getSetting<bool>("offscreen")) {
+ wait(initSignal,initLock);
+ endwait(initSignal,initLock);
+ first=false;
+ }
+#endif
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ triple m(xmin,ymin,zmin);
+ triple M(xmax,ymax,zmax);
+ double perspective=orthographic ? 0.0 : 1.0/zmax;
+
+ double size2=hypot(Width,Height);
+
+ if(remesh) {
+ camp::BezierPatch::clear();
+ camp::BezierPatch::Clear();
+ camp::BezierPatch::tClear();
+ camp::BezierCurve::clear();
+ camp::Pixel::clear();
+ }
+
+ // Render opaque objects
+ Picture->render(size2,m,M,perspective,false,remesh);
+
+ // Enable transparency
+ glDepthMask(GL_FALSE);
+
+ // Render transparent objects
+ Picture->render(size2,m,M,perspective,true,remesh);
+ glDepthMask(GL_TRUE);
+}
+
+// Return x divided by y rounded up to the nearest integer.
+int Quotient(int x, int y)
+{
+ return (x+y-1)/y;
+}
+
+void Export()
+{
+ glReadBuffer(GL_BACK_LEFT);
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ glFinish();
+ try {
+ size_t ndata=3*fullWidth*fullHeight;
+ unsigned border=1;
+ unsigned char *data=new unsigned char[ndata];
+ if(data) {
+ TRcontext *tr=trNew();
+ int width=Quotient(fullWidth,Quotient(fullWidth,min(maxTileWidth,Width)));
+ int height=Quotient(fullHeight,Quotient(fullHeight,
+ min(maxTileHeight,Height)));
+ if(settings::verbose > 1)
+ cout << "Exporting " << Prefix << " as " << fullWidth << "x"
+ << fullHeight << " image" << " using tiles of size "
+ << width << "x" << height << endl;
+
+ trTileSize(tr,width,height,border);
+ trImageSize(tr,fullWidth,fullHeight);
+ trImageBuffer(tr,GL_RGB,GL_UNSIGNED_BYTE,data);
+
+ setDimensions(fullWidth,fullHeight,X/Width*fullWidth,Y/Width*fullWidth);
+ (orthographic ? trOrtho : trFrustum)(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
+
+ size_t count=0;
+ do {
+ trBeginTile(tr);
+ drawscene(fullWidth,fullHeight);
+ ++count;
+ } while (trEndTile(tr));
+ if(settings::verbose > 1)
+ cout << count << " tile" << (count != 1 ? "s" : "") << " drawn" << endl;
+ trDelete(tr);
+
+ picture pic;
+ double w=oWidth;
+ double h=oHeight;
+ double Aspect=((double) fullWidth)/fullHeight;
+ if(w > h*Aspect) w=(int) (h*Aspect+0.5);
+ else h=(int) (w/Aspect+0.5);
+ // Render an antialiased image.
+ drawRawImage *Image=new drawRawImage(data,fullWidth,fullHeight,
+ transform(0.0,0.0,w,0.0,0.0,h),
+ antialias);
+ pic.append(Image);
+ pic.shipout(NULL,Prefix,Format,false,View);
+ delete Image;
+ delete[] data;
+ }
+ } catch(handled_error) {
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ }
+ setProjection();
+ bool offscreen=getSetting<bool>("offscreen");
+#ifdef HAVE_LIBGLUT
+ if(!offscreen)
+ glutPostRedisplay();
+#endif
+
+#ifdef HAVE_PTHREAD
+ if(glthread && readyAfterExport && !offscreen) {
+ readyAfterExport=false;
+ endwait(readySignal,readyLock);
+ }
+#endif
+}
+
+#ifdef HAVE_LIBGLUT
+void idle()
+{
+ glutIdleFunc(NULL);
+ Xspin=Yspin=Zspin=Animate=Step=false;
+}
+#endif
+
+void home()
+{
+ X=Y=cx=cy=0.0;
+#ifdef HAVE_LIBGLUT
+ if(!getSetting<bool>("offscreen")) {
+ idle();
+ arcball.init();
+ }
+#endif
+ viewMat=mat4(1.0f);
+ normMat=mat4(1.0f);
+
+ dviewMat=dmat4(1.0);
+ drotateMat=dmat4(1.0);
+
+ Rotate=value_ptr(drotateMat);
+ updateModelViewData();
+
+ remesh=true;
+ lastzoom=Zoom=Zoom0;
+ setDimensions(Width,Height,0,0);
+ glClearColor(Background[0],Background[1],Background[2],Background[3]);
+}
+
+void nodisplay()
+{
+}
+
+void destroywindow()
+{
+ glutDestroyWindow(glutGetWindow());
+}
+
+// Return the greatest power of 2 less than or equal to n.
+inline unsigned int floorpow2(unsigned int n)
+{
+ n |= n >> 1;
+ n |= n >> 2;
+ n |= n >> 4;
+ n |= n >> 8;
+ n |= n >> 16;
+ return n-(n >> 1);
+}
+
+void quit()
+{
+#ifdef HAVE_LIBOSMESA
+ if(getSetting<bool>("offscreen")) {
+ if(osmesa_buffer) delete[] osmesa_buffer;
+ if(ctx) OSMesaDestroyContext(ctx);
+ exit(0);
+ }
+#endif
+#ifdef HAVE_LIBGLUT
+ if(glthread) {
+ bool animating=getSetting<bool>("animating");
+ if(animating)
+ Setting("interrupt")=true;
+ home();
+ Animate=getSetting<bool>("autoplay");
+#ifdef HAVE_PTHREAD
+ if(!interact::interactive || animating) {
+ idle();
+ glutDisplayFunc(nodisplay);
+ endwait(readySignal,readyLock);
+ }
+#endif
+ if(interact::interactive)
+ glutHideWindow();
+ } else {
+ glutDestroyWindow(window);
+ exit(0);
+ }
+#endif
+}
+
+void mode()
+{
+ remesh=true;
+ switch(Mode) {
+ case 0: // wireframe -> regular
+ outlinemode=false;
+ nlights=nlights0;
+ glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
+ ++Mode;
+ break;
+ case 1: // regular -> outline
+ outlinemode=true;
+ nlights=0;
+ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
+ ++Mode;
+ break;
+ case 2: // outline -> wireframe
+ outlinemode=false;
+ Mode=0;
+ break;
+ }
+#ifdef HAVE_LIBGLUT
+ if(!getSetting<bool>("offscreen"))
+ glutPostRedisplay();
+#endif
+}
+
+// GUI-related functions
+#ifdef HAVE_LIBGLUT
+bool capsize(int& width, int& height)
+{
+ bool resize=false;
+ if(width > maxWidth) {
+ width=maxWidth;
+ resize=true;
+ }
+ if(height > maxHeight) {
+ height=maxHeight;
+ resize=true;
+ }
+ return resize;
+}
+
+void reshape0(int width, int height)
+{
+ X=(X/Width)*width;
+ Y=(Y/Height)*height;
+
+ Width=width;
+ Height=height;
+
+ setProjection();
+ glViewport(0,0,Width,Height);
+}
+
+void windowposition(int& x, int& y, int width=Width, int height=Height)
+{
+ pair z=getSetting<pair>("position");
+ x=(int) z.getx();
+ y=(int) z.gety();
+ if(x < 0) {
+ x += screenWidth-width;
+ if(x < 0) x=0;
+ }
+ if(y < 0) {
+ y += screenHeight-height;
+ if(y < 0) y=0;
+ }
+}
+
+void setsize(int w, int h, bool reposition=true)
+{
+ int x,y;
+
+ capsize(w,h);
+ if(reposition) {
+ windowposition(x,y,w,h);
+ glutPositionWindow(x,y);
+ }
+ glutReshapeWindow(w,h);
+ reshape0(w,h);
+ glutPostRedisplay();
+}
+
+void fullscreen(bool reposition=true)
+{
+ Width=screenWidth;
+ Height=screenHeight;
+ reshape0(Width,Height);
+ if(reposition)
+ glutPositionWindow(0,0);
+ glutReshapeWindow(Width,Height);
+ glutPostRedisplay();
+}
+
+void fitscreen(bool reposition=true)
+{
+ if(Animate && Fitscreen == 2) Fitscreen=0;
+ switch(Fitscreen) {
+ case 0: // Original size
+ {
+ Xfactor=Yfactor=1.0;
+ setsize(oldWidth,oldHeight,reposition);
+ break;
+ }
+ case 1: // Fit to screen in one dimension
+ {
+ oldWidth=Width;
+ oldHeight=Height;
+ int w=screenWidth;
+ int h=screenHeight;
+ if(w >= h*Aspect) w=(int) (h*Aspect+0.5);
+ else h=(int) (w/Aspect+0.5);
+ setsize(w,h,reposition);
+ break;
+ }
+ case 2: // Full screen
+ {
+ Xfactor=((double) screenHeight)/Height;
+ Yfactor=((double) screenWidth)/Width;
+ fullscreen(reposition);
+ break;
+ }
+ }
+}
+
+void togglefitscreen()
+{
+ ++Fitscreen;
+ if(Fitscreen > 2) Fitscreen=0;
+ fitscreen();
+}
+
+void initTimer()
+{
+ gettimeofday(&lasttime,NULL);
+ gettimeofday(&lastframetime,NULL);
+}
+
+void idleFunc(void (*f)())
+{
+ initTimer();
+ glutIdleFunc(f);
+}
+
+void screen()
+{
+ if(glthread && !interact::interactive)
+ fitscreen(false);
+}
+
+void nextframe(int)
+{
+#ifdef HAVE_PTHREAD
+ endwait(readySignal,readyLock);
+#endif
+ double framedelay=getSetting<double>("framedelay");
+ if(framedelay > 0)
+ usleep((unsigned int) (1000.0*framedelay+0.5));
+ if(Step) Animate=false;
+}
+
+void display()
+{
+ if(queueScreen) {
+ if(!Animate) screen();
+ queueScreen=false;
+ }
+
+ maxvertices=getSetting<Int>("maxvertices");
+ if(maxvertices == 0) maxvertices=Maxvertices;
+
+ bool fps=settings::verbose > 2;
+ if(fps) seconds();
+ drawscene(Width,Height);
+ if(fps) {
+ glFinish();
+ double s=seconds();
+ if(s > 0.0) {
+ double rate=1.0/s;
+ S.add(rate);
+ cout << "FPS=" << rate << "\t" << S.mean() << " +/- " << S.stdev() << endl;
+ }
+ }
+ glutSwapBuffers();
+
+#ifdef HAVE_PTHREAD
+ if(glthread && Animate) {
+ queueExport=false;
+ double delay=1.0/getSetting<double>("framerate");
+ timeval tv;
+ gettimeofday(&tv,NULL);
+ double seconds=tv.tv_sec-lastframetime.tv_sec+
+ ((double) tv.tv_usec-lastframetime.tv_usec)/1000000.0;
+ lastframetime=tv;
+ double milliseconds=1000.0*(delay-seconds);
+ double framedelay=getSetting<double>("framedelay");
+ if(framedelay > 0) milliseconds -= framedelay;
+ if(milliseconds > 0)
+ glutTimerFunc((int) (milliseconds+0.5),nextframe,0);
+ else nextframe(0);
+ }
+#endif
+ if(queueExport) {
+ Export();
+ queueExport=false;
+ }
+ if(!glthread) {
+ if(Oldpid != 0 && waitpid(Oldpid,NULL,WNOHANG) != Oldpid) {
+ kill(Oldpid,SIGHUP);
+ Oldpid=0;
+ }
+ }
+}
+
+void update()
+{
+ glutDisplayFunc(display);
+ Animate=getSetting<bool>("autoplay");
+ glutShowWindow();
+ if(Zoom != lastzoom) remesh=true;
+ lastzoom=Zoom;
+ double cz=0.5*(zmin+zmax);
+
+ dviewMat=translate(translate(dmat4(1.0),dvec3(cx,cy,cz))*drotateMat,
+ dvec3(0,0,-cz));
+ viewMat=mat4(dviewMat);
+ setProjection();
+ updateModelViewData();
+
+ glutPostRedisplay();
+}
+
+void updateHandler(int)
+{
+ queueScreen=true;
+ update();
+ if(interact::interactive || !Animate) {
+ glutShowWindow();
+ }
+}
+
+void animate()
+{
+ Animate=!Animate;
+ if(Animate) {
+ if(Fitscreen == 2) {
+ togglefitscreen();
+ togglefitscreen();
+ }
+ update();
+ }
+}
+
+void reshape(int width, int height)
+{
+ if(glthread) {
+ static bool initialize=true;
+ if(initialize) {
+ initialize=false;
+ Signal(SIGUSR1,updateHandler);
+ }
+ }
+
+ if(capsize(width,height))
+ glutReshapeWindow(width,height);
+
+ reshape0(width,height);
+ remesh=true;
+}
+
+void shift(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ double Zoominv=1.0/Zoom;
+ X += (x-x0)*Zoominv;
+ Y += (y0-y)*Zoominv;
+ x0=x; y0=y;
+ update();
+ }
+}
+
+void pan(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ if(orthographic) {
+ double Zoominv=1.0/Zoom;
+ X += (x-x0)*Zoominv;
+ Y += (y0-y)*Zoominv;
+ } else {
+ cx += (x-x0)*(xmax-xmin)/Width;
+ cy += (y0-y)*(ymax-ymin)/Height;
+ }
+ x0=x; y0=y;
+ update();
+ }
+}
+
+void capzoom()
+{
+ static double maxzoom=sqrt(DBL_MAX);
+ static double minzoom=1/maxzoom;
+ if(Zoom <= minzoom) Zoom=minzoom;
+ if(Zoom >= maxzoom) Zoom=maxzoom;
+
+ if(Zoom != lastzoom) remesh=true;
+ lastzoom=Zoom;
+}
+
+void zoom(int x, int y)
+{
+ if(ignorezoom) {ignorezoom=false; y0=y; return;}
+ if(x > 0 && y > 0) {
+ double zoomFactor=getSetting<double>("zoomfactor");
+ if(zoomFactor > 0.0) {
+ double zoomStep=getSetting<double>("zoomstep");
+ const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
+ double s=zoomStep*(y0-y);
+ if(fabs(s) < limit) {
+ Zoom *= pow(zoomFactor,s);
+ capzoom();
+ y0=y;
+ setProjection();
+ glutPostRedisplay();
+ }
+ }
+ }
+}
+
+void mousewheel(int wheel, int direction, int x, int y)
+{
+ double zoomFactor=getSetting<double>("zoomfactor");
+ if(zoomFactor > 0.0) {
+ if(direction > 0)
+ Zoom *= zoomFactor;
+ else
+ Zoom /= zoomFactor;
+ capzoom();
+ setProjection();
+ glutPostRedisplay();
+ }
+}
+
+void rotate(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ arcball.mouse_motion(x,Height-y,0,
+ Action == "rotateX", // X rotation only
+ Action == "rotateY"); // Y rotation only
+
+ for(int i=0; i < 4; ++i) {
+ const ::vec4& roti=arcball.rot[i];
+ int i4=4*i;
+ for(int j=0; j < 4; ++j)
+ value_ptr(drotateMat)[i4+j]=roti[j];
+ }
+
+ update();
+ }
+}
+
+double Degrees(int x, int y)
+{
+ return atan2(0.5*Height-y-Y,x-0.5*Width-X)*degrees;
+}
+
+void updateArcball()
+{
+ Rotate=value_ptr(drotateMat);
+ for(int i=0; i < 4; ++i) {
+ int i4=4*i;
+ ::vec4& roti=arcball.rot[i];
+ for(int j=0; j < 4; ++j)
+ roti[j]=Rotate[i4+j];
+ }
+ update();
+}
+
+void rotateX(double step)
+{
+ dmat4 tmpRot(1.0);
+ tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(1,0,0));
+ drotateMat=tmpRot*drotateMat;
+ updateArcball();
+}
+
+void rotateY(double step)
+{
+ dmat4 tmpRot(1.0);
+ tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,1,0));
+ drotateMat=tmpRot*drotateMat;
+ updateArcball();
+}
+
+void rotateZ(double step)
+{
+ dmat4 tmpRot(1.0);
+ tmpRot=glm::rotate(tmpRot,glm::radians(step),dvec3(0,0,1));
+ drotateMat=tmpRot*drotateMat;
+ updateArcball();
+}
+
+void rotateZ(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ double angle=Degrees(x,y);
+ rotateZ(angle-lastangle);
+ lastangle=angle;
+ }
+}
+
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP 3
+#endif
+
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN 4
+#endif
+
+string action(int button, int mod)
+{
+ size_t Button;
+ size_t nButtons=5;
+ switch(button) {
+ case GLUT_LEFT_BUTTON:
+ Button=0;
+ break;
+ case GLUT_MIDDLE_BUTTON:
+ Button=1;
+ break;
+ case GLUT_RIGHT_BUTTON:
+ Button=2;
+ break;
+ case GLUT_WHEEL_UP:
+ Button=3;
+ break;
+ case GLUT_WHEEL_DOWN:
+ Button=4;
+ break;
+ default:
+ Button=nButtons;
+ }
+
+ size_t Mod;
+ size_t nMods=4;
+ switch(mod) {
+ case 0:
+ Mod=0;
+ break;
+ case GLUT_ACTIVE_SHIFT:
+ Mod=1;
+ break;
+ case GLUT_ACTIVE_CTRL:
+ Mod=2;
+ break;
+ case GLUT_ACTIVE_ALT:
+ Mod=3;
+ break;
+ default:
+ Mod=nMods;
+ }
+
+ if(Button < nButtons) {
+ array *left=getSetting<array *>("leftbutton");
+ array *middle=getSetting<array *>("middlebutton");
+ array *right=getSetting<array *>("rightbutton");
+ array *wheelup=getSetting<array *>("wheelup");
+ array *wheeldown=getSetting<array *>("wheeldown");
+ array *Buttons[]={left,middle,right,wheelup,wheeldown};
+ array *a=Buttons[button];
+ size_t size=checkArray(a);
+ if(Mod < size)
+ return read<string>(a,Mod);
+ }
+ return "";
+}
+
+void timeout(int)
+{
+}
+
+void mouse(int button, int state, int x, int y)
+{
+ int mod=glutGetModifiers();
+ string Action=action(button,mod);
+
+ if(Action == "zoomin") {
+ glutMotionFunc(NULL);
+ mousewheel(0,1,x,y);
+ return;
+ }
+ if(Action == "zoomout") {
+ glutMotionFunc(NULL);
+ mousewheel(0,-1,x,y);
+ return;
+ }
+
+ if(state == GLUT_DOWN) {
+ if(Action == "rotate" || Action == "rotateX" || Action == "rotateY") {
+ arcball.mouse_down(x,Height-y);
+ glutMotionFunc(rotate);
+ } else if(Action == "shift") {
+ x0=x; y0=y;
+ glutMotionFunc(shift);
+ } else if(Action == "pan") {
+ x0=x; y0=y;
+ glutMotionFunc(pan);
+ } else if(Action == "zoom" || Action == "zoom/menu") {
+ y0=y;
+ glutMotionFunc(zoom);
+ } else if(Action == "rotateZ") {
+ lastangle=Degrees(x,y);
+ glutMotionFunc(rotateZ);
+ }
+ } else {
+ arcball.mouse_up();
+ glutMotionFunc(NULL);
+ }
+}
+
+double spinstep()
+{
+ timeval tv;
+ gettimeofday(&tv,NULL);
+ double step=getSetting<double>("spinstep")*
+ (tv.tv_sec-lasttime.tv_sec+
+ ((double) tv.tv_usec-lasttime.tv_usec)/1000000.0);
+ lasttime=tv;
+ return step;
+}
+
+void xspin()
+{
+ rotateX(spinstep());
+}
+
+void yspin()
+{
+ rotateY(spinstep());
+}
+
+void zspin()
+{
+ rotateZ(spinstep());
+}
+
+void expand()
+{
+ double resizeStep=getSetting<double>("resizestep");
+ if(resizeStep > 0.0)
+ setsize((int) (Width*resizeStep+0.5),(int) (Height*resizeStep+0.5));
+}
+
+void shrink()
+{
+ double resizeStep=getSetting<double>("resizestep");
+ if(resizeStep > 0.0)
+ setsize(max((int) (Width/resizeStep+0.5),1),
+ max((int) (Height/resizeStep+0.5),1));
+}
+
+void spinx()
+{
+ if(Xspin)
+ idle();
+ else {
+ idleFunc(xspin);
+ Xspin=true;
+ Yspin=Zspin=false;
+ }
+}
+
+void spiny()
+{
+ if(Yspin)
+ idle();
+ else {
+ idleFunc(yspin);
+ Yspin=true;
+ Xspin=Zspin=false;
+ }
+}
+
+void spinz()
+{
+ if(Zspin)
+ idle();
+ else {
+ idleFunc(zspin);
+ Zspin=true;
+ Xspin=Yspin=false;
+ }
+}
+
+void write(const char *text, const double *v)
+{
+ cout << text << "=(" << v[0] << "," << v[1] << "," << v[2] << ")";
+}
+
+void showCamera()
+{
+ projection P=camera();
+ cout << endl
+ << "currentprojection="
+ << (P.orthographic ? "orthographic(" : "perspective(") << endl
+ << "camera=" << P.camera << "," << endl
+ << "up=" << P.up << "," << endl
+ << "target=" << P.target << "," << endl
+ << "zoom=" << P.zoom;
+ if(!orthographic)
+ cout << "," << endl << "angle=" << P.angle;
+ if(P.viewportshift != pair(0.0,0.0))
+ cout << "," << endl << "viewportshift=" << P.viewportshift;
+ if(!orthographic)
+ cout << "," << endl << "autoadjust=false";
+ cout << ");" << endl;
+}
+
+void keyboard(unsigned char key, int x, int y)
+{
+ switch(key) {
+ case 'h':
+ home();
+ update();
+ break;
+ case 'f':
+ togglefitscreen();
+ break;
+ case 'x':
+ spinx();
+ break;
+ case 'y':
+ spiny();
+ break;
+ case 'z':
+ spinz();
+ break;
+ case 's':
+ idle();
+ break;
+ case 'm':
+ mode();
+ break;
+ case 'e':
+ Export();
+ break;
+ case 'c':
+ showCamera();
+ break;
+ case '+':
+ case '=':
+ case '>':
+ expand();
+ break;
+ case '-':
+ case '_':
+ case '<':
+ shrink();
+ break;
+ case 'p':
+ if(getSetting<bool>("reverse")) Animate=false;
+ Setting("reverse")=Step=false;
+ animate();
+ break;
+ case 'r':
+ if(!getSetting<bool>("reverse")) Animate=false;
+ Setting("reverse")=true;
+ Step=false;
+ animate();
+ break;
+ case ' ':
+ Step=true;
+ animate();
+ break;
+ case 17: // Ctrl-q
+ case 'q':
+ if(!Format.empty()) Export();
+ quit();
+ break;
+ }
+}
+
+void setosize()
+{
+ oldWidth=(int) ceil(oWidth);
+ oldHeight=(int) ceil(oHeight);
+}
+#endif
+// end of GUI-related functions
+
+void exportHandler(int=0)
+{
+#ifdef HAVE_LIBGLUT
+ bool offscreen=getSetting<bool>("offscreen");
+ if(!Iconify && !offscreen)
+ glutShowWindow();
+#endif
+ readyAfterExport=true;
+ Export();
+#ifdef HAVE_LIBGLUT
+ if(!Iconify && !offscreen)
+ glutHideWindow();
+#endif
+ glutDisplayFunc(nodisplay);
+}
+
+static bool glinitialize=true;
+
+projection camera(bool user)
+{
+ if(glinitialize) return projection();
+
+ camp::Triple vCamera,vUp,vTarget;
+
+ double cz=0.5*(zmin+zmax);
+
+ if(user) {
+ for(int i=0; i < 3; ++i) {
+ double sumCamera=0.0, sumTarget=0.0, sumUp=0.0;
+ int i4=4*i;
+ for(int j=0; j < 4; ++j) {
+ int j4=4*j;
+ double R0=Rotate[j4];
+ double R1=Rotate[j4+1];
+ double R2=Rotate[j4+2];
+ double R3=Rotate[j4+3];
+ double T4ij=T[i4+j];
+ sumCamera += T4ij*(R3-cx*R0-cy*R1-cz*R2);
+ sumUp += T4ij*R1;
+ sumTarget += T4ij*(R3-cx*R0-cy*R1);
+ }
+ vCamera[i]=sumCamera;
+ vUp[i]=sumUp;
+ vTarget[i]=sumTarget;
+ }
+ } else {
+ for(int i=0; i < 3; ++i) {
+ int i4=4*i;
+ double R0=Rotate[i4];
+ double R1=Rotate[i4+1];
+ double R2=Rotate[i4+2];
+ double R3=Rotate[i4+3];
+ vCamera[i]=R3-cx*R0-cy*R1-cz*R2;
+ vUp[i]=R1;
+ vTarget[i]=R3-cx*R0-cy*R1;
+ }
+ }
+
+ return projection(orthographic,vCamera,vUp,vTarget,Zoom,
+ 2.0*atan(tan(0.5*Angle)/Zoom)/radians,
+ pair(X/Width*lastzoom+Shift.getx(),
+ Y/Height*lastzoom+Shift.gety()));
+}
+
+void init()
+{
+#ifdef HAVE_LIBGLUT
+ mem::vector<string> cmd;
+ cmd.push_back(settings::argv0);
+ if(!interact::interactive && Iconify)
+ cmd.push_back("-iconic");
+ push_split(cmd,getSetting<string>("glOptions"));
+ char **argv=args(cmd,true);
+ int argc=cmd.size();
+
+#ifndef __APPLE__
+ glutInitContextProfile(GLUT_CORE_PROFILE);
+#endif
+
+ glutInit(&argc,argv);
+ screenWidth=glutGet(GLUT_SCREEN_WIDTH);
+ screenHeight=glutGet(GLUT_SCREEN_HEIGHT);
+
+#endif
+}
+
+void init_osmesa()
+{
+#ifdef HAVE_LIBOSMESA
+ // create context and buffer
+ if(settings::verbose > 1)
+ cout << "Allocating osmesa_buffer of size " << screenWidth << "x"
+ << screenHeight << "x4x" << sizeof(GLubyte) << endl;
+ osmesa_buffer=new unsigned char[screenWidth*screenHeight*4*sizeof(GLubyte)];
+ if(!osmesa_buffer) {
+ cerr << "Cannot allocate image buffer." << endl;
+ exit(-1);
+ }
+
+ ctx = OSMesaCreateContextExt(OSMESA_RGBA,16,0,0,NULL);
+ if(!ctx) {
+ cerr << "OSMesaCreateContext failed." << endl;
+ exit(-1);
+ }
+
+ if(!OSMesaMakeCurrent(ctx,osmesa_buffer,GL_UNSIGNED_BYTE,
+ screenWidth,screenHeight )) {
+ cerr << "OSMesaMakeCurrent failed." << endl;
+ exit(-1);
+ }
+
+ int z=0, s=0, a=0;
+ glGetIntegerv(GL_DEPTH_BITS,&z);
+ glGetIntegerv(GL_STENCIL_BITS,&s);
+ glGetIntegerv(GL_ACCUM_RED_BITS,&a);
+ if(settings::verbose > 1)
+ cout << "Offscreen context settings: Depth=" << z << " Stencil=" << s
+ << " Accum=" << a << endl;
+
+ if(z <= 0) {
+ cerr << "Error initializing offscreen context: Depth=" << z << endl;
+ exit(-1);
+ }
+#endif // HAVE_LIBOSMESA
+}
+
+GLuint vertShader,fragShader;
+GLuint vertShaderCol,fragShaderCol;
+
+void initshader()
+{
+ Nlights=max(Nlights,nlights);
+ Nmaterials=max(Nmaterials,nmaterials);
+ shaderProg=glCreateProgram();
+ string vs=locateFile("shaders/vertex.glsl");
+ string fs=locateFile("shaders/fragment.glsl");
+ if(vs.empty() || fs.empty()) {
+ cerr << "GLSL shaders not found." << endl;
+ exit(-1);
+ }
+
+ std::vector<std::string> shaderParams;
+
+#if HAVE_LIBOPENIMAGEIO
+ if (getSetting<bool>("envmap")) {
+ shaderParams.push_back("ENABLE_TEXTURE");
+ envMapBuf=initHDR();
+ }
+#endif
+
+ std::vector<ShaderfileModePair> shaders;
+ shaders.push_back(ShaderfileModePair(vs.c_str(),GL_VERTEX_SHADER));
+ shaders.push_back(ShaderfileModePair(fs.c_str(),GL_FRAGMENT_SHADER));
+
+ camp::noNormalShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
+ shaderParams);
+
+ shaderParams.push_back("WIDTH");
+ camp::pixelShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
+ shaderParams);
+ shaderParams.pop_back();
+
+ shaderParams.push_back("NORMAL");
+ camp::materialShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
+ shaderParams);
+
+ shaderParams.push_back("EXPLICIT_COLOR");
+ camp::colorShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
+ shaderParams);
+}
+
+void deleteshader()
+{
+ glDeleteProgram(camp::materialShader);
+ glDeleteProgram(camp::colorShader);
+ glDeleteProgram(camp::noNormalShader);
+}
+
+// angle=0 means orthographic.
+void glrender(const string& prefix, const picture *pic, const string& format,
+ double width, double height, double angle, double zoom,
+ const triple& m, const triple& M, const pair& shift, double *t,
+ double *background, size_t nlightsin, triple *lights,
+ double *diffuse, double *specular, bool view, int oldpid)
+{
+ remesh=true;
+ bool offscreen=getSetting<bool>("offscreen");
+ Iconify=getSetting<bool>("iconify");
+
+#ifdef HAVE_PTHREAD
+ static bool initializedView=false;
+#endif
+ width=max(width,1.0);
+ height=max(height,1.0);
+
+ if(zoom == 0.0) zoom=1.0;
+
+ Prefix=prefix;
+ Picture=pic;
+ Format=format;
+ for(int i=0; i < 16; ++i)
+ T[i]=t[i];
+ for(int i=0; i < 4; ++i)
+ Background[i]=background[i];
+
+ nlights0=nlights=nlightsin;
+
+ Lights=lights;
+ Diffuse=diffuse;
+ Specular=specular;
+ View=view;
+ Angle=angle*radians;
+ Zoom0=zoom;
+ Oldpid=oldpid;
+ Shift=shift;
+
+ Xmin=m.getx();
+ Xmax=M.getx();
+ Ymin=m.gety();
+ Ymax=M.gety();
+ zmin=m.getz();
+ zmax=M.getz();
+
+ orthographic=Angle == 0.0;
+ H=orthographic ? 0.0 : -tan(0.5*Angle)*zmax;
+
+ ignorezoom=false;
+ Mode=0;
+ Xfactor=Yfactor=1.0;
+
+ pair maxtile=getSetting<pair>("maxtile");
+ maxTileWidth=(int) maxtile.getx();
+ maxTileHeight=(int) maxtile.gety();
+ if(maxTileWidth <= 0) maxTileWidth=1024;
+ if(maxTileHeight <= 0) maxTileHeight=768;
+
+ if(offscreen) {
+ screenWidth=maxTileWidth;
+ screenHeight=maxTileHeight;
+
+ static bool osmesa_initialized=false;
+ if(!osmesa_initialized) {
+ osmesa_initialized=true;
+ init_osmesa();
+ }
+ }
+
+ if(glinitialize) {
+ init();
+ Fitscreen=1;
+ }
+
+ static bool initialized=false;
+ if(!initialized || !interact::interactive) {
+ antialias=getSetting<Int>("antialias") > 1;
+ double expand=getSetting<double>("render");
+ if(expand < 0)
+ expand *= (Format.empty() || Format == "eps" || Format == "pdf")
+ ? -2.0 : -1.0;
+ if(antialias) expand *= 2.0;
+
+ // Force a hard viewport limit to work around direct rendering bugs.
+ // Alternatively, one can use -glOptions=-indirect (with a performance
+ // penalty).
+ pair maxViewport=getSetting<pair>("maxviewport");
+ maxWidth=(int) ceil(maxViewport.getx());
+ maxHeight=(int) ceil(maxViewport.gety());
+ if(maxWidth <= 0) maxWidth=max(maxHeight,2);
+ if(maxHeight <= 0) maxHeight=max(maxWidth,2);
+ if(screenWidth <= 0) screenWidth=maxWidth;
+ else screenWidth=min(screenWidth,maxWidth);
+ if(screenHeight <= 0) screenHeight=maxHeight;
+ else screenHeight=min(screenHeight,maxHeight);
+
+ oWidth=width;
+ oHeight=height;
+ Aspect=width/height;
+
+ fullWidth=(int) ceil(expand*width);
+ fullHeight=(int) ceil(expand*height);
+
+ Width=min(fullWidth,screenWidth);
+ Height=min(fullHeight,screenHeight);
+
+ if(Width > Height*Aspect)
+ Width=min((int) (ceil(Height*Aspect)),screenWidth);
+ else
+ Height=min((int) (ceil(Width/Aspect)),screenHeight);
+
+ Aspect=((double) Width)/Height;
+
+ if(maxTileWidth <= 0) maxTileWidth=screenWidth;
+ if(maxTileHeight <= 0) maxTileHeight=screenHeight;
+#ifdef HAVE_LIBGLUT
+ setosize();
+#endif
+
+ if(View && settings::verbose > 1)
+ cout << "Rendering " << stripDir(prefix) << " as "
+ << Width << "x" << Height << " image" << endl;
+ }
+
+ bool havewindow=initialized && glthread && !offscreen;
+
+#ifdef HAVE_LIBGLUT
+ unsigned int displaymode=GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
+#endif
+
+#ifdef __APPLE__
+ displaymode |= GLUT_3_2_CORE_PROFILE;
+#endif
+
+ camp::clearMaterialBuffer();
+
+#ifdef HAVE_PTHREAD
+ if(glthread && initializedView && !offscreen) {
+ if(!View)
+ readyAfterExport=queueExport=true;
+ pthread_kill(mainthread,SIGUSR1);
+ return;
+ }
+#endif
+
+#ifdef HAVE_LIBGLUT
+ if(!offscreen) {
+ if(View) {
+ int x,y;
+ if(havewindow)
+ glutDestroyWindow(window);
+
+ windowposition(x,y);
+ glutInitWindowPosition(x,y);
+ glutInitWindowSize(1,1);
+ Int multisample=getSetting<Int>("multisample");
+ if(multisample <= 1) multisample=0;
+ if(multisample)
+ displaymode |= GLUT_MULTISAMPLE;
+ glutInitDisplayMode(displaymode);
+
+ int samples;
+
+#ifdef FREEGLUT
+#ifdef GLUT_INIT_MAJOR_VERSION
+ while(true) {
+ if(multisample > 0)
+ glutSetOption(GLUT_MULTISAMPLE,multisample);
+#endif
+#endif
+ string title=string(settings::PROGRAM)+": "+prefix;
+ window=glutCreateWindow(title.c_str());
+
+ GLint samplebuf[1];
+ glGetIntegerv(GL_SAMPLES,samplebuf);
+ samples=samplebuf[0];
+#ifdef FREEGLUT
+#ifdef GLUT_INIT_MAJOR_VERSION
+ if(samples < multisample) {
+ multisample=floorpow2(multisample-1);
+ if(multisample > 1) {
+ glutReshapeWindow(1,1);
+ glutDisplayFunc(destroywindow);
+ glutShowWindow();
+ glutMainLoopEvent();
+ continue;
+ }
+ }
+ break;
+ }
+#endif
+#endif
+ if(settings::verbose > 1 && samples > 1)
+ cout << "Multisampling enabled with sample width " << samples
+ << endl;
+ glutDisplayFunc(display);
+ glutShowWindow();
+ } else if(!havewindow) {
+ glutInitWindowSize(maxTileWidth,maxTileHeight);
+ glutInitDisplayMode(displaymode);
+ window=glutCreateWindow("");
+ glutHideWindow();
+ }
+ }
+#endif // HAVE_LIBGLUT
+ initialized=true;
+
+ GLint val;
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE,&val);
+ Maxmaterials=val/sizeof(Material);
+ if(nmaterials > Maxmaterials) nmaterials=Maxmaterials;
+
+ glGetIntegerv(GL_MAX_ELEMENTS_VERTICES,&Maxvertices);
+
+ if(glinitialize) {
+ glinitialize=false;
+ int result = glewInit();
+
+ if (result != GLEW_OK) {
+ cerr << "GLEW initialization error." << endl;
+ exit(-1);
+ }
+
+ initshader();
+ }
+
+ home();
+
+#ifdef HAVE_LIBGLUT
+ if(!offscreen) {
+ Animate=getSetting<bool>("autoplay") && glthread;
+
+ if(View) {
+ if(!getSetting<bool>("fitscreen"))
+ Fitscreen=0;
+ fitscreen();
+ setosize();
+ }
+ }
+#endif
+
+ glEnable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ mode();
+
+ if(View && !offscreen) {
+#ifdef HAVE_LIBGLUT
+#ifdef HAVE_PTHREAD
+ initializedView=true;
+#endif
+ glutReshapeFunc(reshape);
+ glutKeyboardFunc(keyboard);
+ glutMouseFunc(mouse);
+ glutDisplayFunc(display);
+
+ glutMainLoop();
+#endif // HAVE_LIBGLUT
+ } else {
+ if(glthread && !offscreen) {
+ if(havewindow) {
+ readyAfterExport=true;
+#ifdef HAVE_PTHREAD
+ pthread_kill(mainthread,SIGUSR1);
+#endif
+ } else {
+ initialized=true;
+ readyAfterExport=true;
+ Signal(SIGUSR1,exportHandler);
+ exportHandler();
+ }
+ } else {
+ exportHandler();
+ quit();
+ }
+ }
+}
+
+} // namespace gl
+
+namespace camp {
+
+string getLightIndex(size_t const& index, string const& fieldName) {
+ ostringstream buf;
+ buf << "lights[" << index << "]." << fieldName;
+ return Strdup(buf.str());
+}
+
+void setUniforms(GLint shader)
+{
+ if(gl::nlights > gl::Nlights || nmaterials > Nmaterials) {
+ gl::deleteshader();
+ gl::initshader();
+ }
+
+ glUseProgram(shader);
+
+ glUniformMatrix4fv(glGetUniformLocation(shader,"projViewMat"),1,GL_FALSE, value_ptr(gl::projViewMat));
+ glUniformMatrix4fv(glGetUniformLocation(shader,"viewMat"),1,GL_FALSE, value_ptr(gl::viewMat));
+ glUniformMatrix4fv(glGetUniformLocation(shader,"normMat"),1,GL_FALSE, value_ptr(gl::normMat));
+
+ GLuint binding=0;
+ GLint blockindex=glGetUniformBlockIndex(shader,"MaterialBuffer");
+ glUniformBlockBinding(shader,blockindex,binding);
+
+ glGenBuffers(1,&gl::ubo);
+ glBindBuffer(GL_UNIFORM_BUFFER,gl::ubo);
+
+ glBufferData(GL_UNIFORM_BUFFER,drawElement::material.size()*sizeof(Material),
+ drawElement::material.data(),GL_STATIC_DRAW);
+ glBindBufferBase(GL_UNIFORM_BUFFER,binding,gl::ubo);
+
+ glUniform1i(glGetUniformLocation(shader,"nlights"),gl::nlights);
+
+ for(size_t i=0; i < gl::nlights; ++i) {
+ triple Lighti=gl::Lights[i];
+ size_t i4=4*i;
+ glUniform4f(glGetUniformLocation(shader,
+ getLightIndex(i,"direction").c_str()),
+ (GLfloat) Lighti.getx(),(GLfloat) Lighti.gety(),
+ (GLfloat) Lighti.getz(),0.0);
+
+ glUniform4f(glGetUniformLocation(shader,
+ getLightIndex(i,"diffuse").c_str()),
+ (GLfloat) gl::Diffuse[i4],(GLfloat) gl::Diffuse[i4+1],
+ (GLfloat) gl::Diffuse[i4+2],(GLfloat) gl::Diffuse[i4+3]);
+
+ glUniform4f(glGetUniformLocation(shader,
+ getLightIndex(i,"specular").c_str()),
+ (GLfloat) gl::Specular[i4],(GLfloat) gl::Specular[i4+1],
+ (GLfloat) gl::Specular[i4+2],(GLfloat) gl::Specular[i4+3]);
+ }
+
+#if HAVE_LIBOPENIMAGEIO
+ // textures
+ if (settings::getSetting<bool>("envmap")) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindBuffer(GL_TEXTURE_2D, gl::envMapBuf);
+ glUniform1i(glGetUniformLocation(shader, "environmentMap"), 1);
+ glActiveTexture(GL_TEXTURE0);
+ }
+#endif
+}
+
+void deleteUniforms()
+{
+ glBindBuffer(GL_UNIFORM_BUFFER,0);
+ glDeleteBuffers(1,&gl::ubo);
+ glUseProgram(0);
+}
+
+}
+
+#endif
diff --git a/graphics/asymptote/glrender.h b/graphics/asymptote/glrender.h
new file mode 100644
index 0000000000..5354fa59e7
--- /dev/null
+++ b/graphics/asymptote/glrender.h
@@ -0,0 +1,180 @@
+/*****
+ * glrender.h
+ * Render 3D Bezier paths and surfaces.
+ *****/
+
+#ifndef GLRENDER_H
+#define GLRENDER_H
+
+#include "common.h"
+#include "triple.h"
+
+#ifdef HAVE_GL
+
+#include <csignal>
+
+#define GLEW_NO_GLU
+//#define GLEW_OSMESA
+
+#ifdef __MSDOS__
+#define GLEW_STATIC
+#define _WIN32
+#endif
+
+#include "GL/glew.h"
+
+#ifdef __APPLE__
+#define GL_SILENCE_DEPRECATION
+#include <OpenGL/gl.h>
+#ifdef HAVE_LIBGLUT
+#include <GLUT/glut.h>
+#endif
+#ifdef HAVE_LIBOSMESA
+#include <GL/osmesa.h>
+#endif
+#else
+#ifdef __MSDOS__
+#undef _WIN32
+#include <GL/gl.h>
+#include <GL/wglew.h>
+#include <GL/wglext.h>
+#endif
+#ifdef HAVE_LIBGLUT
+#include <GL/glut.h>
+#endif
+#ifdef HAVE_LIBOSMESA
+#include <GL/osmesa.h>
+#endif
+#endif
+
+namespace camp {
+class picture;
+
+inline void store(GLfloat *f, double *C)
+{
+ f[0]=C[0];
+ f[1]=C[1];
+ f[2]=C[2];
+}
+
+inline void store(GLfloat *control, const camp::triple& v)
+{
+ control[0]=v.getx();
+ control[1]=v.gety();
+ control[2]=v.getz();
+}
+
+inline void store(GLfloat *control, const triple& v, double weight)
+{
+ control[0]=v.getx()*weight;
+ control[1]=v.gety()*weight;
+ control[2]=v.getz()*weight;
+ control[3]=weight;
+}
+
+}
+
+namespace gl {
+
+extern bool outlinemode;
+extern bool wireframeMode;
+extern Int maxvertices;
+extern bool forceRemesh;
+extern GLuint ubo;
+
+struct projection
+{
+public:
+ bool orthographic;
+ camp::triple camera;
+ camp::triple up;
+ camp::triple target;
+ double zoom;
+ double angle;
+ camp::pair viewportshift;
+
+ projection(bool orthographic=false, camp::triple camera=0.0,
+ camp::triple up=0.0, camp::triple target=0.0,
+ double zoom=0.0, double angle=0.0,
+ camp::pair viewportshift=0.0) :
+ orthographic(orthographic), camera(camera), up(up), target(target),
+ zoom(zoom), angle(angle), viewportshift(viewportshift) {}
+};
+
+GLuint initHDR();
+
+projection camera(bool user=true);
+
+void glrender(const string& prefix, const camp::picture* pic,
+ const string& format, double width, double height, double angle,
+ double zoom, const camp::triple& m, const camp::triple& M,
+ const camp::pair& shift, double *t, double *background,
+ size_t nlights, camp::triple *lights, double *diffuse,
+ double *specular, bool view, int oldpid=0);
+
+struct ModelView {
+ double T[16];
+ double Tinv[16];
+};
+
+extern ModelView modelView;
+
+void initshader();
+void deleteshader();
+
+}
+
+namespace camp {
+
+struct billboard
+{
+ double cx,cy,cz;
+ triple u,v,w;
+
+ void init(const triple& center) {
+ cx=center.getx();
+ cy=center.gety();
+ cz=center.getz();
+ gl::projection P=gl::camera(false);
+ w=unit(P.camera-P.target);
+ v=unit(perp(P.up,w));
+ u=cross(v,w);
+ }
+
+ triple transform(const triple& V) {
+ double x=V.getx()-cx;
+ double y=V.gety()-cy;
+ double z=V.getz()-cz;
+
+ return triple(cx+u.getx()*x+v.getx()*y+w.getx()*z,
+ cy+u.gety()*x+v.gety()*y+w.gety()*z,
+ cz+u.getz()*x+v.getz()*y+w.getz()*z);
+ }
+
+ void store(GLfloat* C, const triple& V) {
+ double x=V.getx()-cx;
+ double y=V.gety()-cy;
+ double z=V.getz()-cz;
+ C[0]=cx+u.getx()*x+v.getx()*y+w.getx()*z;
+ C[1]=cy+u.gety()*x+v.gety()*y+w.gety()*z;
+ C[2]=cz+u.getz()*x+v.getz()*y+w.getz()*z;
+ }
+};
+
+extern billboard BB;
+
+extern GLint materialShader;
+extern GLint colorShader;
+extern GLint noNormalShader;
+extern GLint pixelShader;
+
+void setUniforms(GLint shader);
+void deleteUniforms();
+
+}
+
+#else
+typedef float GLfloat;
+#endif
+
+#endif
diff --git a/graphics/asymptote/gsl.cc b/graphics/asymptote/gsl.cc
new file mode 100644
index 0000000000..0f81dc6034
--- /dev/null
+++ b/graphics/asymptote/gsl.cc
@@ -0,0 +1,1489 @@
+/*****
+ * gsl.cc
+ * 2010/05/19
+ *
+ * Initialize gsl builtins.
+ *****/
+
+#include "config.h"
+
+#ifdef HAVE_LIBGSL
+
+#include "vm.h"
+#include "types.h"
+#include "entry.h"
+#include "builtin.h"
+
+#include "record.h"
+#include "stack.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+
+#include <gsl/gsl_math.h>
+#include <gsl/gsl_sf.h>
+#include <gsl/gsl_errno.h>
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+#include <gsl/gsl_cdf.h>
+#include <gsl/gsl_version.h>
+
+#include "opsymbols.h"
+
+#ifndef NOSYM
+#include "gsl.symbols.h"
+#endif
+
+namespace trans {
+
+using types::formal;
+using types::primVoid;
+using types::primInt;
+using types::primReal;
+using types::primPair;
+using types::primTriple;
+using types::primString;
+using types::IntArray;
+using types::realArray;
+using types::stringArray;
+
+using vm::stack;
+using vm::array;
+using vm::pop;
+using vm::error;
+using run::copyArrayC;
+using run::copyCArray;
+
+using camp::pair;
+using camp::triple;
+
+const char* GSLrngnull = "GSL random number generator not initialized";
+const char* GSLinvalid = "invalid argument";
+
+bool GSLerror=false;
+types::dummyRecord *GSLModule;
+
+types::record *getGSLModule()
+{
+ return GSLModule;
+}
+
+inline void checkGSLerror()
+{
+ if(GSLerror) {
+ GSLerror=false;
+ throw handled_error();
+ }
+}
+
+template <double (*func)(double)>
+void realRealGSL(stack *s)
+{
+ double x=pop<double>(s);
+ s->push(func(x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, gsl_mode_t)>
+void realRealDOUBLE(stack *s)
+{
+ double x=pop<double>(s);
+ s->push(func(x,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template <double (*func)(double, double, gsl_mode_t)>
+void realRealRealDOUBLE(stack *s)
+{
+ double y=pop<double>(s);
+ double x=pop<double>(s);
+ s->push(func(x,y,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template <double (*func)(unsigned)>
+void realIntGSL(stack *s)
+{
+ s->push(func(unsignedcast(pop<Int>(s))));
+ checkGSLerror();
+}
+
+template <double (*func)(int, double)>
+void realIntRealGSL(stack *s)
+{
+ double x=pop<double>(s);
+ s->push(func(intcast(pop<Int>(s)),x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, double)>
+void realRealRealGSL(stack *s)
+{
+ double x=pop<double>(s);
+ double n=pop<double>(s);
+ s->push(func(n,x));
+ checkGSLerror();
+}
+
+template <int (*func)(double, double, double)>
+void intRealRealRealGSL(stack *s)
+{
+ double x=pop<double>(s);
+ double n=pop<double>(s);
+ double a=pop<double>(s);
+ s->push(func(a,n,x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, double, double)>
+void realRealRealRealGSL(stack *s)
+{
+ double x=pop<double>(s);
+ double n=pop<double>(s);
+ double a=pop<double>(s);
+ s->push(func(a,n,x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, unsigned)>
+void realRealIntGSL(stack *s)
+{
+ Int n=pop<Int>(s);
+ double x=pop<double>(s);
+ s->push(func(x,unsignedcast(n)));
+ checkGSLerror();
+}
+
+// Add a GSL special function from the GNU GSL library
+template<double (*fcn)(double)>
+void addGSLRealFunc(symbol name, symbol arg1=SYM(x))
+{
+ addFunc(GSLModule->e.ve, realRealGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1));
+}
+
+// Add a GSL_PREC_DOUBLE GSL special function.
+template<double (*fcn)(double, gsl_mode_t)>
+void addGSLDOUBLEFunc(symbol name, symbol arg1=SYM(x))
+{
+ addFunc(GSLModule->e.ve, realRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1));
+}
+
+template<double (*fcn)(double, double, gsl_mode_t)>
+void addGSLDOUBLE2Func(symbol name, symbol arg1=SYM(phi),
+ symbol arg2=SYM(k))
+{
+ addFunc(GSLModule->e.ve, realRealRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2));
+}
+
+template <double (*func)(double, double, double, gsl_mode_t)>
+void realRealRealRealDOUBLE(stack *s)
+{
+ double z=pop<double>(s);
+ double y=pop<double>(s);
+ double x=pop<double>(s);
+ s->push(func(x,y,z,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double, double, gsl_mode_t)>
+void addGSLDOUBLE3Func(symbol name, symbol arg1, symbol arg2,
+ symbol arg3)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3));
+}
+
+template <double (*func)(double, double, double, double, gsl_mode_t)>
+void realRealRealRealRealDOUBLE(stack *s)
+{
+ double z=pop<double>(s);
+ double y=pop<double>(s);
+ double x=pop<double>(s);
+ double w=pop<double>(s);
+ s->push(func(w,x,y,z,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double, double, double, gsl_mode_t)>
+void addGSLDOUBLE4Func(symbol name, symbol arg1, symbol arg2,
+ symbol arg3, symbol arg4)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3), formal(primReal(), arg4));
+}
+
+template<double (*fcn)(unsigned)>
+void addGSLIntFunc(symbol name)
+{
+ addFunc(GSLModule->e.ve, realIntGSL<fcn>, primReal(), name,
+ formal(primInt(),SYM(s)));
+}
+
+template <double (*func)(int)>
+void realSignedGSL(stack *s)
+{
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int)>
+void addGSLSignedFunc(symbol name, symbol arg1)
+{
+ addFunc(GSLModule->e.ve, realSignedGSL<fcn>, primReal(), name,
+ formal(primInt(),arg1));
+}
+
+template<double (*fcn)(int, double)>
+void addGSLIntRealFunc(symbol name, symbol arg1=SYM(n),
+ symbol arg2=SYM(x))
+{
+ addFunc(GSLModule->e.ve, realIntRealGSL<fcn>, primReal(), name,
+ formal(primInt(),arg1), formal(primReal(),arg2));
+}
+
+template<double (*fcn)(double, double)>
+void addGSLRealRealFunc(symbol name, symbol arg1=SYM(nu),
+ symbol arg2=SYM(x))
+{
+ addFunc(GSLModule->e.ve, realRealRealGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2));
+}
+
+template<double (*fcn)(double, double, double)>
+void addGSLRealRealRealFunc(symbol name, symbol arg1,
+ symbol arg2, symbol arg3)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3));
+}
+
+template<int (*fcn)(double, double, double)>
+void addGSLRealRealRealFuncInt(symbol name, symbol arg1,
+ symbol arg2, symbol arg3)
+{
+ addFunc(GSLModule->e.ve, intRealRealRealGSL<fcn>, primInt(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3));
+}
+
+template<double (*fcn)(double, unsigned)>
+void addGSLRealIntFunc(symbol name, symbol arg1=SYM(nu),
+ symbol arg2=SYM(s))
+{
+ addFunc(GSLModule->e.ve, realRealIntGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primInt(),arg2));
+}
+
+template<double (*func)(double, int)>
+void realRealSignedGSL(stack *s)
+{
+ Int b = pop<Int>(s);
+ double a = pop<double>(s);
+ s->push(func(a, intcast(b)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, int)>
+void addGSLRealSignedFunc(symbol name, symbol arg1, symbol arg2)
+{
+ addFunc(GSLModule->e.ve, realRealSignedGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primInt(),arg2));
+}
+
+template<double (*func)(unsigned int, unsigned int)>
+void realUnsignedUnsignedGSL(stack *s)
+{
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(unsignedcast(a), unsignedcast(b)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(unsigned int, unsigned int)>
+void addGSLUnsignedUnsignedFunc(symbol name, symbol arg1,
+ symbol arg2)
+{
+ addFunc(GSLModule->e.ve, realUnsignedUnsignedGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2));
+}
+
+template<double (*func)(int, double, double)>
+void realIntRealRealGSL(stack *s)
+{
+ double c = pop<double>(s);
+ double b = pop<double>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), b, c));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, double, double)>
+void addGSLIntRealRealFunc(symbol name, symbol arg1,
+ symbol arg2, symbol arg3)
+{
+ addFunc(GSLModule->e.ve, realIntRealRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primReal(), arg2),
+ formal(primReal(), arg3));
+}
+
+template<double (*func)(int, int, double)>
+void realIntIntRealGSL(stack *s)
+{
+ double c = pop<double>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), c));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, double)>
+void addGSLIntIntRealFunc(symbol name, symbol arg1, symbol arg2,
+ symbol arg3)
+{
+ addFunc(GSLModule->e.ve, realIntIntRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primReal(), arg3));
+}
+
+template<double (*func)(int, int, double, double)>
+void realIntIntRealRealGSL(stack *s)
+{
+ double d = pop<double>(s);
+ double c = pop<double>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), c, d));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, double, double)>
+void addGSLIntIntRealRealFunc(symbol name, symbol arg1,
+ symbol arg2, symbol arg3,
+ symbol arg4)
+{
+ addFunc(GSLModule->e.ve, realIntIntRealRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primReal(), arg3), formal(primReal(), arg4));
+}
+
+template<double (*func)(double, double, double, double)>
+void realRealRealRealRealGSL(stack *s)
+{
+ double d = pop<double>(s);
+ double c = pop<double>(s);
+ double b = pop<double>(s);
+ double a = pop<double>(s);
+ s->push(func(a, b, c, d));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double, double, double)>
+void addGSLRealRealRealRealFunc(symbol name, symbol arg1,
+ symbol arg2, symbol arg3,
+ symbol arg4)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealRealGSL<fcn>, primReal(), name,
+ formal(primReal(), arg1), formal(primReal(), arg2),
+ formal(primReal(), arg3), formal(primReal(), arg4));
+}
+
+template<double (*func)(int, int, int, int, int, int)>
+void realIntIntIntIntIntIntGSL(stack *s)
+{
+ Int f = pop<Int>(s);
+ Int e = pop<Int>(s);
+ Int d = pop<Int>(s);
+ Int c = pop<Int>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e),
+ intcast(f)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, int, int, int, int)>
+void addGSLIntIntIntIntIntIntFunc(symbol name, symbol arg1,
+ symbol arg2, symbol arg3,
+ symbol arg4, symbol arg5,
+ symbol arg6)
+{
+ addFunc(GSLModule->e.ve, realIntIntIntIntIntIntGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primInt(), arg3), formal(primInt(), arg4),
+ formal(primInt(), arg5), formal(primInt(), arg6));
+}
+
+template<double (*func)(int, int, int, int, int, int, int, int, int)>
+void realIntIntIntIntIntIntIntIntIntGSL(stack *s)
+{
+ Int i = pop<Int>(s);
+ Int h = pop<Int>(s);
+ Int g = pop<Int>(s);
+ Int f = pop<Int>(s);
+ Int e = pop<Int>(s);
+ Int d = pop<Int>(s);
+ Int c = pop<Int>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e),
+ intcast(f), intcast(g), intcast(h), intcast(i)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, int, int, int, int, int, int, int)>
+void addGSLIntIntIntIntIntIntIntIntIntFunc(symbol name, symbol arg1,
+ symbol arg2, symbol arg3,
+ symbol arg4, symbol arg5,
+ symbol arg6, symbol arg7,
+ symbol arg8, symbol arg9)
+{
+ addFunc(GSLModule->e.ve, realIntIntIntIntIntIntIntIntIntGSL<fcn>, primReal(),
+ name, formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primInt(), arg3), formal(primInt(), arg4),
+ formal(primInt(), arg5), formal(primInt(), arg6),
+ formal(primInt(), arg7), formal(primInt(), arg8),
+ formal(primInt(), arg9));
+}
+
+template<double (*func)(unsigned int, double)>
+void realUIntRealGSL(stack *s)
+{
+ double a = pop<double>(s);
+ unsigned int k = unsignedcast(pop<Int>(s));
+ s->push(func(k,a));
+ checkGSLerror();
+}
+
+template<double (*fcn)(unsigned int, double)>
+void addGSLUIntRealFunc(symbol name, symbol arg1, symbol arg2)
+{
+ addFunc(GSLModule->e.ve, realUIntRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primReal(), arg2));
+}
+
+template<double (*func)(unsigned int, double, unsigned int)>
+void realUIntRealUIntGSL(stack *s)
+{
+ unsigned int n = unsignedcast(pop<Int>(s));
+ double a = pop<double>(s);
+ unsigned int k = unsignedcast(pop<Int>(s));
+ s->push(func(k,a,n));
+ checkGSLerror();
+}
+
+template<double (*fcn)(unsigned int, double, unsigned int)>
+void addGSLUIntRealUIntFunc(symbol name, symbol arg1, symbol arg2, symbol arg3)
+{
+ addFunc(GSLModule->e.ve, realUIntRealUIntGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primReal(), arg2),
+ formal(primInt(), arg3));
+}
+
+template<double (*func)(unsigned int, double, double)>
+void realUIntRealRealGSL(stack *s)
+{
+ double b = pop<double>(s);
+ double a = pop<double>(s);
+ unsigned int k = unsignedcast(pop<Int>(s));
+ s->push(func(k,a,b));
+ checkGSLerror();
+}
+
+template<double (*fcn)(unsigned int, double, double)>
+void addGSLUIntRealRealFunc(symbol name, symbol arg1, symbol arg2, symbol arg3)
+{
+ addFunc(GSLModule->e.ve, realUIntRealRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primReal(), arg2),
+ formal(primReal(), arg3));
+}
+
+template<double (*func)(unsigned int, unsigned int, unsigned int, unsigned int)>
+void realUIntUIntUIntUIntGSL(stack *s)
+{
+ unsigned int t = unsignedcast(pop<Int>(s));
+ unsigned int n2 = unsignedcast(pop<Int>(s));
+ unsigned int n1 = unsignedcast(pop<Int>(s));
+ unsigned int k = unsignedcast(pop<Int>(s));
+ s->push(func(k,n1,n2,t));
+ checkGSLerror();
+}
+
+template<double (*fcn)(unsigned int, unsigned int, unsigned int, unsigned int)>
+void addGSLUIntUIntUIntUIntFunc(symbol name, symbol arg1, symbol arg2,
+ symbol arg3, symbol arg4)
+{
+ addFunc(GSLModule->e.ve, realUIntUIntUIntUIntGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primInt(), arg3), formal(primInt(), arg4));
+}
+
+// GSL random number generators
+gsl_rng *GSLrng=0;
+const gsl_rng_type **GSLrngFirstType=gsl_rng_types_setup();
+
+inline void checkGSLrng()
+{
+ if(GSLrng == 0) error(GSLrngnull);
+}
+
+void GSLrngFree()
+{
+ if(GSLrng != 0) gsl_rng_free(GSLrng);
+ GSLrng=0;
+}
+
+void GSLrngInit(stack *s)
+{
+ string n = pop<string>(s,string());
+ const gsl_rng_type **t;
+ if(n.empty()) t = &gsl_rng_default;
+ else {
+ for(t=GSLrngFirstType; *t!=0; ++t)
+ if(n == string((*t)->name)) break;
+ if(*t == 0) error(GSLinvalid);
+ }
+ GSLrngFree();
+ GSLrng = gsl_rng_alloc(*t);
+ if(GSLrng == 0) {
+ GSLerror=false;
+ error("insufficient memory for allocation of GSL random number generator");
+ }
+}
+
+void GSLrngList(stack *s)
+{
+ array* a = new array(0);
+ const gsl_rng_type **t;
+ for(t=GSLrngFirstType; *t!=0; ++t) {
+ a->push(string((*t)->name));
+ }
+ s->push<array*>(a);
+ checkGSLerror();
+}
+
+void GSLrngSet(stack *s)
+{
+ Int i=pop<Int>(s,-1);
+ checkGSLrng();
+ if(i < 0) gsl_rng_set(GSLrng,gsl_rng_default_seed);
+ else gsl_rng_set(GSLrng,unsignedcast(i));
+ checkGSLerror();
+}
+
+template<unsigned long int (*func)(const gsl_rng*)>
+void intVoidGSLrng(stack *s)
+{
+ s->push<Int>(func(GSLrng));
+ checkGSLrng();
+ checkGSLerror();
+}
+
+template<unsigned long int (*fcn)(const gsl_rng*)>
+void addGSLrngVoidFuncInt(symbol name)
+{
+ addFunc(GSLModule->e.ve, intVoidGSLrng<fcn>, primInt(), name);
+}
+
+template<unsigned long int (*func)(const gsl_rng*, unsigned long int)>
+void intULongGSLrng(stack *s)
+{
+ unsigned long int i = unsignedcast(pop<Int>(s));
+ checkGSLrng();
+ s->push<Int>(func(GSLrng,i));
+ checkGSLerror();
+}
+
+template<unsigned long int (*fcn)(const gsl_rng*, unsigned long int)>
+void addGSLrngULongFuncInt(symbol name, symbol arg1)
+{
+ addFunc(GSLModule->e.ve, intULongGSLrng<fcn>, primInt(), name,
+ formal(primInt(), arg1));
+}
+
+template<unsigned int (*func)(const gsl_rng*, double)>
+void intRealGSLrng(stack *s)
+{
+ double x = pop<double>(s);
+ checkGSLrng();
+ s->push<Int>(func(GSLrng,x));
+ checkGSLerror();
+}
+
+template<unsigned int (*fcn)(const gsl_rng*, double)>
+void addGSLrngRealFuncInt(symbol name, symbol arg1)
+{
+ addFunc(GSLModule->e.ve, intRealGSLrng<fcn>, primInt(), name,
+ formal(primReal(), arg1));
+}
+
+template<unsigned int (*func)(const gsl_rng*, double, double)>
+void intRealRealGSLrng(stack *s)
+{
+ double y = pop<double>(s);
+ double x = pop<double>(s);
+ checkGSLrng();
+ s->push<Int>(func(GSLrng,x,y));
+ checkGSLerror();
+}
+
+template<unsigned int (*fcn)(const gsl_rng*, double, double)>
+void addGSLrngRealRealFuncInt(symbol name, symbol arg1, symbol arg2)
+{
+ addFunc(GSLModule->e.ve, intRealRealGSLrng<fcn>, primInt(), name,
+ formal(primReal(), arg1), formal(primReal(), arg2));
+}
+
+template<double (*func)(const gsl_rng*)>
+void realVoidGSLrng(stack *s)
+{
+ checkGSLrng();
+ s->push(func(GSLrng));
+ checkGSLerror();
+}
+
+template<double (*fcn)(const gsl_rng*)>
+void addGSLrngVoidFunc(symbol name)
+{
+ addFunc(GSLModule->e.ve, realVoidGSLrng<fcn>, primReal(), name);
+}
+
+template<double (*func)(const gsl_rng*, double)>
+void realRealGSLrng(stack *s)
+{
+ double x = pop<double>(s);
+ checkGSLrng();
+ s->push(func(GSLrng,x));
+ checkGSLerror();
+}
+
+template<double (*fcn)(const gsl_rng*, double)>
+void addGSLrngRealFunc(symbol name, symbol arg1)
+{
+ addFunc(GSLModule->e.ve, realRealGSLrng<fcn>, primReal(), name,
+ formal(primReal(), arg1));
+}
+
+template<double (*func)(const gsl_rng*, double, double)>
+void realRealRealGSLrng(stack *s)
+{
+ double b = pop<double>(s);
+ double a = pop<double>(s);
+ checkGSLrng();
+ s->push(func(GSLrng,a,b));
+ checkGSLerror();
+}
+
+template<double (*fcn)(const gsl_rng*, double, double)>
+void addGSLrngRealRealFunc(symbol name, symbol arg1, symbol arg2)
+{
+ addFunc(GSLModule->e.ve, realRealRealGSLrng<fcn>, primReal(), name,
+ formal(primReal(), arg1), formal(primReal(), arg2));
+}
+
+template<unsigned int (*func)(const gsl_rng*, double, unsigned int)>
+void intRealUIntGSLrng(stack *s)
+{
+ unsigned int n = unsignedcast(pop<Int>(s));
+ double a = pop<double>(s);
+ checkGSLrng();
+ s->push<Int>(func(GSLrng,a,n));
+ checkGSLerror();
+}
+
+template<unsigned int (*fcn)(const gsl_rng*, double, unsigned int)>
+void addGSLrngRealUIntFuncInt(symbol name, symbol arg1, symbol arg2)
+{
+ addFunc(GSLModule->e.ve, intRealUIntGSLrng<fcn>, primInt(), name,
+ formal(primReal(), arg1), formal(primInt(), arg2));
+}
+
+template<unsigned int (*func)(const gsl_rng*, unsigned int, unsigned int,
+ unsigned int)>
+void intUIntUIntUIntGSLrng(stack *s)
+ {
+ unsigned int t = unsignedcast(pop<Int>(s));
+ unsigned int n2 = unsignedcast(pop<Int>(s));
+ unsigned int n1 = unsignedcast(pop<Int>(s));
+ checkGSLrng();
+ s->push<Int>(func(GSLrng,n1,n2,t));
+ checkGSLerror();
+ }
+
+template<unsigned int (*fcn)(const gsl_rng*, unsigned int, unsigned int,
+ unsigned int)>
+void addGSLrngUIntUIntUIntFuncInt(symbol name, symbol arg1, symbol arg2,
+ symbol arg3)
+{
+ addFunc(GSLModule->e.ve, intUIntUIntUIntGSLrng<fcn>, primInt(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primInt(), arg3));
+}
+
+template<const char* (*func)(const gsl_rng*)>
+void stringVoidGSLrng(stack *s)
+{
+ checkGSLrng();
+ s->push<string>(func(GSLrng));
+ checkGSLerror();
+}
+
+template<const char* (*fcn)(const gsl_rng*)>
+void addGSLrngVoidFuncString(symbol name)
+{
+ addFunc(GSLModule->e.ve, stringVoidGSLrng<fcn>, primString(), name);
+}
+
+void GSLrng_gaussian(stack *s)
+{
+ string method = pop<string>(s,string("polar"));
+ double sigma = pop<double>(s,1.0);
+ double mu = pop<double>(s,0.0);
+ checkGSLrng();
+ double x=mu;
+ if(method == "polar") x += gsl_ran_gaussian(GSLrng,sigma);
+ else if(method == "ziggurat") x += gsl_ran_gaussian_ziggurat(GSLrng,sigma);
+ else if(method == "ratio") x += gsl_ran_gaussian_ratio_method(GSLrng,sigma);
+ else error(GSLinvalid);
+ s->push(x);
+ checkGSLerror();
+}
+
+template<double (*func)(double, double)>
+void realRealRealRealGSLgaussian(stack *s)
+{
+ double sigma = pop<double>(s,1.0);
+ double mu = pop<double>(s,0.0);
+ double x = pop<double>(s);
+ s->push(func(x-mu,sigma));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double)>
+void addGSLgaussianrealRealRealRealFunc(symbol name, symbol arg1)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealGSLgaussian<fcn>, primReal(), name,
+ formal(primReal(), arg1),
+ formal(primReal(), SYM(mu), true, false),
+ formal(primReal(), SYM(sigma), true, false));
+}
+
+template<double (*func)(double, double)>
+void realRealRealRealGSLinvgaussian(stack *s)
+{
+ double sigma = pop<double>(s,1.0);
+ double mu = pop<double>(s,0.0);
+ double x = pop<double>(s);
+ s->push(func(x,sigma)+mu);
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double)>
+void addGSLinvgaussianrealRealRealRealFunc(symbol name, symbol arg1)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealGSLinvgaussian<fcn>, primReal(),
+ name,
+ formal(primReal(), arg1),
+ formal(primReal(), SYM(mu), true, false),
+ formal(primReal(), SYM(sigma), true, false));
+}
+
+void GSLrng_bivariate_gaussian(stack *s)
+{
+ double rho = pop<double>(s,0.0);
+ pair sigma = pop<pair>(s,pair(1.0,1.0));
+ pair mu = pop<pair>(s,pair(0.0,0.0));
+ checkGSLrng();
+ double x,y;
+ gsl_ran_bivariate_gaussian(GSLrng,sigma.getx(),sigma.gety(),rho,&x,&y);
+ s->push(pair(x,y)+mu);
+ checkGSLerror();
+}
+
+void GSLpdf_bivariate_gaussian(stack *s)
+{
+ double rho = pop<double>(s,0.0);
+ pair sigma = pop<pair>(s,pair(1.0,1.0));
+ pair mu = pop<pair>(s,pair(0.0,0.0));
+ pair z = pop<pair>(s);
+ s->push(gsl_ran_bivariate_gaussian_pdf(z.getx()+mu.getx(),z.gety()+mu.gety(),
+ sigma.getx(),sigma.gety(),rho));
+ checkGSLerror();
+}
+
+void GSLrng_levy(stack *s)
+{
+ double beta = pop<double>(s,0.0);
+ double alpha = pop<double>(s);
+ double c = pop<double>(s);
+ if((alpha<=0) || (alpha>2)) error(GSLinvalid);
+ if((beta<-1) || (beta>1)) error(GSLinvalid);
+ checkGSLrng();
+ double x;
+ if(beta==0) x=gsl_ran_levy(GSLrng,c,alpha);
+ else x=gsl_ran_levy_skew(GSLrng,c,alpha,beta);
+ s->push(x);
+ checkGSLerror();
+}
+
+void GSLrng_gamma(stack *s)
+{
+ string method = pop<string>(s,string("mt"));
+ double b = pop<double>(s);
+ double a = pop<double>(s);
+ checkGSLrng();
+ double x=0.0;
+ if(method == "mt") x = gsl_ran_gamma(GSLrng,a,b);
+ else if(method == "knuth") x = gsl_ran_gamma_knuth(GSLrng,a,b);
+ else error(GSLinvalid);
+ s->push(x);
+ checkGSLerror();
+}
+
+void GSLrng_dir2d(stack *s)
+{
+ string method = pop<string>(s,string("neumann"));
+ checkGSLrng();
+ double x=0, y=0;
+ if(method == "neumann") gsl_ran_dir_2d(GSLrng,&x,&y);
+ else if(method == "trig") gsl_ran_dir_2d_trig_method(GSLrng,&x,&y);
+ else error(GSLinvalid);
+ s->push(pair(x,y));
+ checkGSLerror();
+}
+
+void GSLrng_dir3d(stack *s)
+{
+ checkGSLrng();
+ double x,y,z;
+ gsl_ran_dir_3d(GSLrng,&x,&y,&z);
+ s->push(triple(x,y,z));
+ checkGSLerror();
+}
+
+void GSLrng_dir(stack *s)
+{
+ size_t n = (size_t) unsignedcast(pop<Int>(s));
+ if(n==0) error(GSLinvalid);
+ checkGSLrng();
+ double* p = new double[n];
+ gsl_ran_dir_nd(GSLrng,n,p);
+ s->push<array*>(copyCArray(n,p));
+ delete[] p;
+ checkGSLerror();
+}
+
+void GSLrng_dirichlet(stack *s)
+{
+ array* alpha = pop<array*>(s);
+ size_t K = checkArray(alpha);
+ checkGSLrng();
+ double* calpha;
+ copyArrayC(calpha,alpha);
+ double* ctheta = new double[K];
+ gsl_ran_dirichlet(GSLrng,K,calpha,ctheta);
+ s->push<array*>(copyCArray(K,ctheta));
+ delete[] ctheta;
+ delete[] calpha;
+ checkGSLerror();
+}
+
+void GSLpdf_dirichlet(stack *s)
+{
+ array* theta = pop<array*>(s);
+ array* alpha = pop<array*>(s);
+ size_t K = checkArray(alpha);
+ if(checkArray(theta) != K)
+ error(GSLinvalid);
+ double* calpha;
+ copyArrayC(calpha,alpha);
+ double* ctheta;
+ copyArrayC(ctheta,theta);
+ s->push(gsl_ran_dirichlet_pdf(K,calpha,ctheta));
+ delete[] ctheta;
+ delete[] calpha;
+ checkGSLerror();
+}
+
+void GSLrng_multinomial(stack *s)
+{
+ array* p = pop<array*>(s);
+ unsigned int N = unsignedcast(pop<Int>(s));
+ size_t K = checkArray(p);
+ checkGSLrng();
+ double* cp;
+ copyArrayC(cp,p);
+ unsigned int* cn = new unsigned int[K];
+ gsl_ran_multinomial(GSLrng,K,N,cp,cn);
+ s->push<array*>(copyCArray(K,cn));
+ delete[] cn;
+ delete[] cp;
+ checkGSLerror();
+}
+
+void GSLpdf_multinomial(stack *s)
+{
+ array* n = pop<array*>(s);
+ array* p = pop<array*>(s);
+ size_t K = checkArray(p);
+ if(K != checkArray(n)) error(GSLinvalid);
+ double* cp;
+ copyArrayC(cp,p);
+ unsigned int* cn;
+ copyArrayC<unsigned int,Int>(cn,n,unsignedcast);
+ s->push(gsl_ran_multinomial_pdf(K,cp,cn));
+ delete[] cn;
+ delete[] cp;
+ checkGSLerror();
+}
+
+void GSLsf_elljac_e(stack *s)
+{
+ double m = pop<double>(s);
+ double u = pop<double>(s);
+ double sn,cn,dn;
+ gsl_sf_elljac_e(u,m,&sn,&cn,&dn);
+ array *result=new array(3);
+ (*result)[0]=sn;
+ (*result)[1]=cn;
+ (*result)[2]=dn;
+ s->push(result);
+}
+
+// Handle GSL errors gracefully.
+void GSLerrorhandler(const char *reason, const char *, int, int)
+{
+ if(!GSLerror) {
+ vm::errornothrow(reason);
+ GSLerror=true;
+ }
+}
+
+void gen_rungsl_venv(venv &ve)
+{
+ GSLModule=new types::dummyRecord(SYM(gsl));
+ gsl_set_error_handler(GSLerrorhandler);
+
+ // Common functions
+ addGSLRealRealFunc<gsl_hypot>(SYM(hypot),SYM(x),SYM(y));
+// addGSLRealRealRealFunc<gsl_hypot3>(SYM(hypot),SYM(x),SYM(y),SYM(z));
+ addGSLRealRealRealFuncInt<gsl_fcmp>(SYM(fcmp),SYM(x),SYM(y),SYM(epsilon));
+
+ // Airy functions
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai>(SYM(Ai));
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi>(SYM(Bi));
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai_scaled>(SYM(Ai_scaled));
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi_scaled>(SYM(Bi_scaled));
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai_deriv>(SYM(Ai_deriv));
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi_deriv>(SYM(Bi_deriv));
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai_deriv_scaled>(SYM(Ai_deriv_scaled));
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi_deriv_scaled>(SYM(Bi_deriv_scaled));
+ addGSLIntFunc<gsl_sf_airy_zero_Ai>(SYM(zero_Ai));
+ addGSLIntFunc<gsl_sf_airy_zero_Bi>(SYM(zero_Bi));
+ addGSLIntFunc<gsl_sf_airy_zero_Ai_deriv>(SYM(zero_Ai_deriv));
+ addGSLIntFunc<gsl_sf_airy_zero_Bi_deriv>(SYM(zero_Bi_deriv));
+
+ // Bessel functions
+ addGSLRealFunc<gsl_sf_bessel_J0>(SYM(J0));
+ addGSLRealFunc<gsl_sf_bessel_J1>(SYM(J1));
+ addGSLIntRealFunc<gsl_sf_bessel_Jn>(SYM(Jn));
+ addGSLRealFunc<gsl_sf_bessel_Y0>(SYM(Y0));
+ addGSLRealFunc<gsl_sf_bessel_Y1>(SYM(Y1));
+ addGSLIntRealFunc<gsl_sf_bessel_Yn>(SYM(Yn));
+ addGSLRealFunc<gsl_sf_bessel_I0>(SYM(I0));
+ addGSLRealFunc<gsl_sf_bessel_I1>(SYM(I1));
+ addGSLIntRealFunc<gsl_sf_bessel_In>(SYM(I));
+ addGSLRealFunc<gsl_sf_bessel_I0_scaled>(SYM(I0_scaled));
+ addGSLRealFunc<gsl_sf_bessel_I1_scaled>(SYM(I1_scaled));
+ addGSLIntRealFunc<gsl_sf_bessel_In_scaled>(SYM(I_scaled));
+ addGSLRealFunc<gsl_sf_bessel_K0>(SYM(K0));
+ addGSLRealFunc<gsl_sf_bessel_K1>(SYM(K1));
+ addGSLIntRealFunc<gsl_sf_bessel_Kn>(SYM(K));
+ addGSLRealFunc<gsl_sf_bessel_K0_scaled>(SYM(K0_scaled));
+ addGSLRealFunc<gsl_sf_bessel_K1_scaled>(SYM(K1_scaled));
+ addGSLIntRealFunc<gsl_sf_bessel_Kn_scaled>(SYM(K_scaled));
+ addGSLRealFunc<gsl_sf_bessel_j0>(SYM(j0));
+ addGSLRealFunc<gsl_sf_bessel_j1>(SYM(j1));
+ addGSLRealFunc<gsl_sf_bessel_j2>(SYM(j2));
+ addGSLIntRealFunc<gsl_sf_bessel_jl>(SYM(j),SYM(l));
+ addGSLRealFunc<gsl_sf_bessel_y0>(SYM(y0));
+ addGSLRealFunc<gsl_sf_bessel_y1>(SYM(y1));
+ addGSLRealFunc<gsl_sf_bessel_y2>(SYM(y2));
+ addGSLIntRealFunc<gsl_sf_bessel_yl>(SYM(y),SYM(l));
+ addGSLRealFunc<gsl_sf_bessel_i0_scaled>(SYM(i0_scaled));
+ addGSLRealFunc<gsl_sf_bessel_i1_scaled>(SYM(i1_scaled));
+ addGSLRealFunc<gsl_sf_bessel_i2_scaled>(SYM(i2_scaled));
+ addGSLIntRealFunc<gsl_sf_bessel_il_scaled>(SYM(i_scaled),SYM(l));
+ addGSLRealFunc<gsl_sf_bessel_k0_scaled>(SYM(k0_scaled));
+ addGSLRealFunc<gsl_sf_bessel_k1_scaled>(SYM(k1_scaled));
+ addGSLRealFunc<gsl_sf_bessel_k2_scaled>(SYM(k2_scaled));
+ addGSLIntRealFunc<gsl_sf_bessel_kl_scaled>(SYM(k_scaled),SYM(l));
+ addGSLRealRealFunc<gsl_sf_bessel_Jnu>(SYM(J));
+ addGSLRealRealFunc<gsl_sf_bessel_Ynu>(SYM(Y));
+ addGSLRealRealFunc<gsl_sf_bessel_Inu>(SYM(I));
+ addGSLRealRealFunc<gsl_sf_bessel_Inu_scaled>(SYM(I_scaled));
+ addGSLRealRealFunc<gsl_sf_bessel_Knu>(SYM(K));
+ addGSLRealRealFunc<gsl_sf_bessel_lnKnu>(SYM(lnK));
+ addGSLRealRealFunc<gsl_sf_bessel_Knu_scaled>(SYM(K_scaled));
+ addGSLIntFunc<gsl_sf_bessel_zero_J0>(SYM(zero_J0));
+ addGSLIntFunc<gsl_sf_bessel_zero_J1>(SYM(zero_J1));
+ addGSLRealIntFunc<gsl_sf_bessel_zero_Jnu>(SYM(zero_J));
+
+ // Clausen functions
+ addGSLRealFunc<gsl_sf_clausen>(SYM(clausen));
+
+ // Coulomb functions
+ addGSLRealRealFunc<gsl_sf_hydrogenicR_1>(SYM(hydrogenicR_1),SYM(Z),SYM(r));
+ addGSLIntIntRealRealFunc<gsl_sf_hydrogenicR>(SYM(hydrogenicR),SYM(n),SYM(l),
+ SYM(Z),SYM(r));
+ // Missing: F_L(eta,x), G_L(eta,x), C_L(eta)
+
+ // Coupling coefficients
+ addGSLIntIntIntIntIntIntFunc<gsl_sf_coupling_3j>(SYM(coupling_3j),SYM(two_ja),
+ SYM(two_jb),SYM(two_jc),
+ SYM(two_ma),
+ SYM(two_mb),SYM(two_mc));
+ addGSLIntIntIntIntIntIntFunc<gsl_sf_coupling_6j>(SYM(coupling_6j),SYM(two_ja),
+ SYM(two_jb),SYM(two_jc),
+ SYM(two_jd),
+ SYM(two_je),SYM(two_jf));
+ addGSLIntIntIntIntIntIntIntIntIntFunc<gsl_sf_coupling_9j>(SYM(coupling_9j),
+ SYM(two_ja),
+ SYM(two_jb),
+ SYM(two_jc),
+ SYM(two_jd),
+ SYM(two_je),
+ SYM(two_jf),
+ SYM(two_jg),
+ SYM(two_jh),
+ SYM(two_ji));
+ // Dawson function
+ addGSLRealFunc<gsl_sf_dawson>(SYM(dawson));
+
+ // Debye functions
+ addGSLRealFunc<gsl_sf_debye_1>(SYM(debye_1));
+ addGSLRealFunc<gsl_sf_debye_2>(SYM(debye_2));
+ addGSLRealFunc<gsl_sf_debye_3>(SYM(debye_3));
+ addGSLRealFunc<gsl_sf_debye_4>(SYM(debye_4));
+ addGSLRealFunc<gsl_sf_debye_5>(SYM(debye_5));
+ addGSLRealFunc<gsl_sf_debye_6>(SYM(debye_6));
+
+ // Dilogarithm
+ addGSLRealFunc<gsl_sf_dilog>(SYM(dilog));
+ // Missing: complex dilogarithm
+
+ // Elementary operations
+ // we don't support errors at the moment
+
+ // Elliptic integrals
+ addGSLDOUBLEFunc<gsl_sf_ellint_Kcomp>(SYM(K),SYM(k));
+ addGSLDOUBLEFunc<gsl_sf_ellint_Ecomp>(SYM(E),SYM(k));
+ addGSLDOUBLE2Func<gsl_sf_ellint_Pcomp>(SYM(P),SYM(k),SYM(n));
+ addGSLDOUBLE2Func<gsl_sf_ellint_F>(SYM(F));
+ addGSLDOUBLE2Func<gsl_sf_ellint_E>(SYM(E));
+ addGSLDOUBLE3Func<gsl_sf_ellint_P>(SYM(P),SYM(phi),SYM(k),SYM(n));
+#if GSL_MAJOR_VERSION >= 2
+ addGSLDOUBLE2Func<gsl_sf_ellint_D>(SYM(D),SYM(phi),SYM(k));
+#else
+ addGSLDOUBLE3Func<gsl_sf_ellint_D>(SYM(D),SYM(phi),SYM(k),SYM(n));
+#endif
+ addGSLDOUBLE2Func<gsl_sf_ellint_RC>(SYM(RC),SYM(x),SYM(y));
+ addGSLDOUBLE3Func<gsl_sf_ellint_RD>(SYM(RD),SYM(x),SYM(y),SYM(z));
+ addGSLDOUBLE3Func<gsl_sf_ellint_RF>(SYM(RF),SYM(x),SYM(y),SYM(z));
+ addGSLDOUBLE4Func<gsl_sf_ellint_RJ>(SYM(RJ),SYM(x),SYM(y),SYM(z),SYM(p));
+
+ // Error functions
+ addGSLRealFunc<gsl_sf_erf>(SYM(erf));
+ addGSLRealFunc<gsl_sf_erfc>(SYM(erfc));
+ addGSLRealFunc<gsl_sf_log_erfc>(SYM(log_erfc));
+ addGSLRealFunc<gsl_sf_erf_Z>(SYM(erf_Z));
+ addGSLRealFunc<gsl_sf_erf_Q>(SYM(erf_Q));
+ addGSLRealFunc<gsl_sf_hazard>(SYM(hazard));
+
+ // Exponential functions
+ addGSLRealRealFunc<gsl_sf_exp_mult>(SYM(exp_mult),SYM(x),SYM(y));
+// addGSLRealFunc<gsl_sf_expm1>(SYM(expm1));
+ addGSLRealFunc<gsl_sf_exprel>(SYM(exprel));
+ addGSLRealFunc<gsl_sf_exprel_2>(SYM(exprel_2));
+ addGSLIntRealFunc<gsl_sf_exprel_n>(SYM(exprel),SYM(n),SYM(x));
+
+ // Exponential integrals
+ addGSLRealFunc<gsl_sf_expint_E1>(SYM(E1));
+ addGSLRealFunc<gsl_sf_expint_E2>(SYM(E2));
+// addGSLIntRealFunc<gsl_sf_expint_En>(SYM(En),SYM(n),SYM(x));
+ addGSLRealFunc<gsl_sf_expint_Ei>(SYM(Ei));
+ addGSLRealFunc<gsl_sf_Shi>(SYM(Shi));
+ addGSLRealFunc<gsl_sf_Chi>(SYM(Chi));
+ addGSLRealFunc<gsl_sf_expint_3>(SYM(Ei3));
+ addGSLRealFunc<gsl_sf_Si>(SYM(Si));
+ addGSLRealFunc<gsl_sf_Ci>(SYM(Ci));
+ addGSLRealFunc<gsl_sf_atanint>(SYM(atanint));
+
+ // Fermi--Dirac function
+ addGSLRealFunc<gsl_sf_fermi_dirac_m1>(SYM(FermiDiracM1));
+ addGSLRealFunc<gsl_sf_fermi_dirac_0>(SYM(FermiDirac0));
+ addGSLRealFunc<gsl_sf_fermi_dirac_1>(SYM(FermiDirac1));
+ addGSLRealFunc<gsl_sf_fermi_dirac_2>(SYM(FermiDirac2));
+ addGSLIntRealFunc<gsl_sf_fermi_dirac_int>(SYM(FermiDirac),SYM(j),SYM(x));
+ addGSLRealFunc<gsl_sf_fermi_dirac_mhalf>(SYM(FermiDiracMHalf));
+ addGSLRealFunc<gsl_sf_fermi_dirac_half>(SYM(FermiDiracHalf));
+ addGSLRealFunc<gsl_sf_fermi_dirac_3half>(SYM(FermiDirac3Half));
+ addGSLRealRealFunc<gsl_sf_fermi_dirac_inc_0>(SYM(FermiDiracInc0),SYM(x),
+ SYM(b));
+
+ // Gamma and beta functions
+ addGSLRealFunc<gsl_sf_gamma>(SYM(gamma));
+ addGSLRealFunc<gsl_sf_lngamma>(SYM(lngamma));
+ addGSLRealFunc<gsl_sf_gammastar>(SYM(gammastar));
+ addGSLRealFunc<gsl_sf_gammainv>(SYM(gammainv));
+ addGSLIntFunc<gsl_sf_fact>(SYM(fact));
+ addGSLIntFunc<gsl_sf_doublefact>(SYM(doublefact));
+ addGSLIntFunc<gsl_sf_lnfact>(SYM(lnfact));
+ addGSLIntFunc<gsl_sf_lndoublefact>(SYM(lndoublefact));
+ addGSLUnsignedUnsignedFunc<gsl_sf_choose>(SYM(choose),SYM(n),SYM(m));
+ addGSLUnsignedUnsignedFunc<gsl_sf_lnchoose>(SYM(lnchoose),SYM(n),SYM(m));
+ addGSLIntRealFunc<gsl_sf_taylorcoeff>(SYM(taylorcoeff),SYM(n),SYM(x));
+ addGSLRealRealFunc<gsl_sf_poch>(SYM(poch),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_lnpoch>(SYM(lnpoch),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_pochrel>(SYM(pochrel),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_gamma_inc>(SYM(gamma),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_gamma_inc_Q>(SYM(gamma_Q),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_gamma_inc_P>(SYM(gamma_P),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_beta>(SYM(beta),SYM(a),SYM(b));
+ addGSLRealRealFunc<gsl_sf_lnbeta>(SYM(lnbeta),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_sf_beta_inc>(SYM(beta),SYM(a),SYM(b),SYM(x));
+
+ // Gegenbauer functions
+ addGSLRealRealFunc<gsl_sf_gegenpoly_1>(SYM(gegenpoly_1),SYM(lambda),SYM(x));
+ addGSLRealRealFunc<gsl_sf_gegenpoly_2>(SYM(gegenpoly_2),SYM(lambda),SYM(x));
+ addGSLRealRealFunc<gsl_sf_gegenpoly_3>(SYM(gegenpoly_3),SYM(lambda),SYM(x));
+ addGSLIntRealRealFunc<gsl_sf_gegenpoly_n>(SYM(gegenpoly),SYM(n),SYM(lambda),
+ SYM(x));
+
+ // Hypergeometric functions
+ addGSLRealRealFunc<gsl_sf_hyperg_0F1>(SYM(hy0F1),SYM(c),SYM(x));
+ addGSLIntIntRealFunc<gsl_sf_hyperg_1F1_int>(SYM(hy1F1),SYM(m),SYM(n),SYM(x));
+ addGSLRealRealRealFunc<gsl_sf_hyperg_1F1>(SYM(hy1F1),SYM(a),SYM(b),SYM(x));
+ addGSLIntIntRealFunc<gsl_sf_hyperg_U_int>(SYM(U),SYM(m),SYM(n),SYM(x));
+ addGSLRealRealRealFunc<gsl_sf_hyperg_U>(SYM(U),SYM(a),SYM(b),SYM(x));
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1>(SYM(hy2F1),SYM(a),SYM(b),SYM(c),
+ SYM(x));
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1_conj>(SYM(hy2F1_conj),SYM(aR),
+ SYM(aI),SYM(c),SYM(x));
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1_renorm>(SYM(hy2F1_renorm),SYM(a),
+ SYM(b),SYM(c),SYM(x));
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1_conj_renorm>
+ (SYM(hy2F1_conj_renorm),SYM(aR),SYM(aI),SYM(c),SYM(x));
+ addGSLRealRealRealFunc<gsl_sf_hyperg_2F0>(SYM(hy2F0),SYM(a),SYM(b),SYM(x));
+
+ // Laguerre functions
+ addGSLRealRealFunc<gsl_sf_laguerre_1>(SYM(L1),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_laguerre_2>(SYM(L2),SYM(a),SYM(x));
+ addGSLRealRealFunc<gsl_sf_laguerre_3>(SYM(L3),SYM(a),SYM(x));
+ addGSLIntRealRealFunc<gsl_sf_laguerre_n>(SYM(L),SYM(n),SYM(a),SYM(x));
+
+ // Lambert W functions
+ addGSLRealFunc<gsl_sf_lambert_W0>(SYM(W0));
+ addGSLRealFunc<gsl_sf_lambert_Wm1>(SYM(Wm1));
+
+ // Legendre functions and spherical harmonics
+ addGSLRealFunc<gsl_sf_legendre_P1>(SYM(P1));
+ addGSLRealFunc<gsl_sf_legendre_P2>(SYM(P2));
+ addGSLRealFunc<gsl_sf_legendre_P3>(SYM(P3));
+ addGSLIntRealFunc<gsl_sf_legendre_Pl>(SYM(Pl),SYM(l));
+ addGSLRealFunc<gsl_sf_legendre_Q0>(SYM(Q0));
+ addGSLRealFunc<gsl_sf_legendre_Q1>(SYM(Q1));
+ addGSLIntRealFunc<gsl_sf_legendre_Ql>(SYM(Ql),SYM(l));
+ addGSLIntIntRealFunc<gsl_sf_legendre_Plm>(SYM(Plm),SYM(l),SYM(m),SYM(x));
+ addGSLIntIntRealFunc<gsl_sf_legendre_sphPlm>(SYM(sphPlm),SYM(l),SYM(m),
+ SYM(x));
+ addGSLRealRealFunc<gsl_sf_conicalP_half>(SYM(conicalP_half),SYM(lambda),
+ SYM(x));
+ addGSLRealRealFunc<gsl_sf_conicalP_mhalf>(SYM(conicalP_mhalf),SYM(lambda),
+ SYM(x));
+ addGSLRealRealFunc<gsl_sf_conicalP_0>(SYM(conicalP_0),SYM(lambda),SYM(x));
+ addGSLRealRealFunc<gsl_sf_conicalP_1>(SYM(conicalP_1),SYM(lambda),SYM(x));
+ addGSLIntRealRealFunc<gsl_sf_conicalP_sph_reg>(SYM(conicalP_sph_reg),SYM(l),
+ SYM(lambda),SYM(x));
+ addGSLIntRealRealFunc<gsl_sf_conicalP_cyl_reg>(SYM(conicalP_cyl_reg),SYM(m),
+ SYM(lambda),SYM(x));
+ addGSLRealRealFunc<gsl_sf_legendre_H3d_0>(SYM(H3d0),SYM(lambda),SYM(eta));
+ addGSLRealRealFunc<gsl_sf_legendre_H3d_1>(SYM(H3d1),SYM(lambda),SYM(eta));
+ addGSLIntRealRealFunc<gsl_sf_legendre_H3d>(SYM(H3d),SYM(l),SYM(lambda),
+ SYM(eta));
+
+ // Logarithm and related functions
+ addGSLRealFunc<gsl_sf_log_abs>(SYM(logabs));
+// addGSLRealFunc<gsl_sf_log_1plusx>(SYM(log1p));
+ addGSLRealFunc<gsl_sf_log_1plusx_mx>(SYM(log1pm));
+
+ // Matthieu functions
+ // to be implemented
+
+ // Power function
+ addGSLRealSignedFunc<gsl_sf_pow_int>(SYM(pow),SYM(x),SYM(n));
+
+ // Psi (digamma) function
+ addGSLSignedFunc<gsl_sf_psi_int>(SYM(psi),SYM(n));
+ addGSLRealFunc<gsl_sf_psi>(SYM(psi));
+ addGSLRealFunc<gsl_sf_psi_1piy>(SYM(psi_1piy),SYM(y));
+ addGSLSignedFunc<gsl_sf_psi_1_int>(SYM(psi1),SYM(n));
+ addGSLRealFunc<gsl_sf_psi_1>(SYM(psi1),SYM(x));
+ addGSLIntRealFunc<gsl_sf_psi_n>(SYM(psi),SYM(n),SYM(x));
+
+ // Synchrotron functions
+ addGSLRealFunc<gsl_sf_synchrotron_1>(SYM(synchrotron_1));
+ addGSLRealFunc<gsl_sf_synchrotron_2>(SYM(synchrotron_2));
+
+ // Transport functions
+ addGSLRealFunc<gsl_sf_transport_2>(SYM(transport_2));
+ addGSLRealFunc<gsl_sf_transport_3>(SYM(transport_3));
+ addGSLRealFunc<gsl_sf_transport_4>(SYM(transport_4));
+ addGSLRealFunc<gsl_sf_transport_5>(SYM(transport_5));
+
+ // Trigonometric functions
+ addGSLRealFunc<gsl_sf_sinc>(SYM(sinc));
+ addGSLRealFunc<gsl_sf_lnsinh>(SYM(lnsinh));
+ addGSLRealFunc<gsl_sf_lncosh>(SYM(lncosh));
+
+ // Zeta functions
+ addGSLSignedFunc<gsl_sf_zeta_int>(SYM(zeta),SYM(n));
+ addGSLRealFunc<gsl_sf_zeta>(SYM(zeta),SYM(s));
+ addGSLSignedFunc<gsl_sf_zetam1_int>(SYM(zetam1),SYM(n));
+ addGSLRealFunc<gsl_sf_zetam1>(SYM(zetam1),SYM(s));
+ addGSLRealRealFunc<gsl_sf_hzeta>(SYM(hzeta),SYM(s),SYM(q));
+ addGSLSignedFunc<gsl_sf_eta_int>(SYM(eta),SYM(n));
+ addGSLRealFunc<gsl_sf_eta>(SYM(eta),SYM(s));
+
+ // Random number generation
+ gsl_rng_env_setup();
+ addFunc(GSLModule->e.ve,GSLrngInit,primVoid(),SYM(rng_init),
+ formal(primString(),SYM(name),true,false));
+ addFunc(GSLModule->e.ve,GSLrngList,stringArray(),SYM(rng_list));
+ addFunc(GSLModule->e.ve,GSLrngSet,primVoid(),SYM(rng_set),
+ formal(primInt(),SYM(seed),true,false));
+ addGSLrngVoidFuncString<gsl_rng_name>(SYM(rng_name));
+ addGSLrngVoidFuncInt<gsl_rng_min>(SYM(rng_min));
+ addGSLrngVoidFuncInt<gsl_rng_max>(SYM(rng_max));
+ addGSLrngVoidFuncInt<gsl_rng_get>(SYM(rng_get));
+ addGSLrngULongFuncInt<gsl_rng_uniform_int>(SYM(rng_uniform_int),SYM(n));
+ addGSLrngVoidFunc<gsl_rng_uniform>(SYM(rng_uniform));
+ addGSLrngVoidFunc<gsl_rng_uniform_pos>(SYM(rng_uniform_pos));
+
+ // Gaussian distribution
+ addFunc(GSLModule->e.ve,GSLrng_gaussian,primReal(),SYM(rng_gaussian),
+ formal(primReal(),SYM(mu),true,false),
+ formal(primReal(),SYM(sigma),true,false),
+ formal(primString(),SYM(method),true,false));
+ addGSLgaussianrealRealRealRealFunc<gsl_ran_gaussian_pdf>(SYM(pdf_gaussian),
+ SYM(x));
+ addGSLgaussianrealRealRealRealFunc<gsl_cdf_gaussian_P>(SYM(cdf_gaussian_P),
+ SYM(x));
+ addGSLgaussianrealRealRealRealFunc<gsl_cdf_gaussian_Q>(SYM(cdf_gaussian_Q),
+ SYM(x));
+ addGSLinvgaussianrealRealRealRealFunc<gsl_cdf_gaussian_Pinv>
+ (SYM(cdf_gaussian_Pinv),SYM(x));
+ addGSLinvgaussianrealRealRealRealFunc<gsl_cdf_gaussian_Qinv>
+ (SYM(cdf_gaussian_Qinv),SYM(x));
+
+ // Gaussian tail distribution
+ addGSLrngRealRealFunc<gsl_ran_gaussian_tail>(SYM(rng_gaussian_tail),SYM(a),
+ SYM(sigma));
+ addGSLRealRealRealFunc<gsl_ran_gaussian_tail_pdf>(SYM(pdf_gaussian_tail),
+ SYM(x),SYM(a),SYM(sigma));
+
+ // Bivariate Gaussian distribution
+ addFunc(GSLModule->e.ve,GSLrng_bivariate_gaussian,primPair(),
+ SYM(rng_bivariate_gaussian),
+ formal(primPair(),SYM(mu),true,true),
+ formal(primPair(),SYM(sigma),true,true),
+ formal(primReal(),SYM(rho),true,false));
+ addFunc(GSLModule->e.ve,GSLpdf_bivariate_gaussian,primReal(),
+ SYM(pdf_bivariate_gaussian),
+ formal(primPair(),SYM(z),false,true),
+ formal(primPair(),SYM(mu),true,true),
+ formal(primPair(),SYM(sigma),true,true),
+ formal(primReal(),SYM(rho),true,false));
+
+#define addGSLrealdist1param(NAME,ARG) \
+ addGSLrngRealFunc<gsl_ran_##NAME> \
+ (SYM(rng_##NAME),SYM(ARG)); \
+ addGSLRealRealFunc<gsl_ran_##NAME##_pdf> \
+ (SYM(pdf_##NAME),SYM(x),SYM(ARG)); \
+ addGSLRealRealFunc<gsl_cdf_##NAME##_P> \
+ (SYM(cdf_##NAME##_P),SYM(x),SYM(ARG)); \
+ addGSLRealRealFunc<gsl_cdf_##NAME##_Q> \
+ (SYM(cdf_##NAME##_Q),SYM(x),SYM(ARG)); \
+ addGSLRealRealFunc<gsl_cdf_##NAME##_Pinv> \
+ (SYM(cdf_##NAME##_Pinv),SYM(P),SYM(ARG)); \
+ addGSLRealRealFunc<gsl_cdf_##NAME##_Qinv> \
+ (SYM(cdf_##NAME##_Qinv),SYM(Q),SYM(ARG))
+
+ // Exponential, Laplace, Cauchy, Rayleigh, Chi-squared, t,
+ // and Logistic distribution
+ addGSLrealdist1param(exponential,mu);
+ addGSLrealdist1param(laplace,a);
+ addGSLrealdist1param(cauchy,a);
+ addGSLrealdist1param(rayleigh,mu);
+ addGSLrealdist1param(chisq,mu);
+ addGSLrealdist1param(tdist,mu);
+ addGSLrealdist1param(logistic,mu);
+#undef addGSLrealdist1param
+
+#define addGSLrealdist2param(NAME,ARG1,ARG2) \
+ addGSLrngRealRealFunc<gsl_ran_##NAME> \
+ (SYM(rng_##NAME),SYM(ARG1),SYM(ARG2)); \
+ addGSLRealRealRealFunc<gsl_ran_##NAME##_pdf> \
+ (SYM(pdf_##NAME),SYM(x),SYM(ARG1),SYM(ARG2)); \
+ addGSLRealRealRealFunc<gsl_cdf_##NAME##_P> \
+ (SYM(cdf_##NAME##_P),SYM(x),SYM(ARG1),SYM(ARG2)); \
+ addGSLRealRealRealFunc<gsl_cdf_##NAME##_Q> \
+ (SYM(cdf_##NAME##_Q),SYM(x),SYM(ARG1),SYM(ARG2)); \
+ addGSLRealRealRealFunc<gsl_cdf_##NAME##_Pinv> \
+ (SYM(cdf_##NAME##_Pinv),SYM(P),SYM(ARG1),SYM(ARG2)); \
+ addGSLRealRealRealFunc<gsl_cdf_##NAME##_Qinv> \
+ (SYM(cdf_##NAME##_Qinv),SYM(Q),SYM(ARG1),SYM(ARG2))
+
+ // Uniform, log-normal, F, Beta, Pareto, Weibull, Type-1 Gumbel,
+ // and Type-2 Gumbel distribution
+ addGSLrealdist2param(flat,a,b);
+ addGSLrealdist2param(lognormal,zeta,sigma);
+ addGSLrealdist2param(fdist,nu1,nu2);
+ addGSLrealdist2param(beta,a,b);
+ addGSLrealdist2param(pareto,a,b);
+ addGSLrealdist2param(weibull,a,b);
+ addGSLrealdist2param(gumbel1,a,b);
+ addGSLrealdist2param(gumbel2,a,b);
+#undef addGSLrealdist2param
+
+ // Exponential power distribution
+ addGSLrngRealRealFunc<gsl_ran_exppow>
+ (SYM(rng_exppow),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_ran_exppow_pdf>
+ (SYM(pdf_exppow),SYM(x),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_cdf_exppow_P>
+ (SYM(cdf_exppow_P),SYM(x),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_cdf_exppow_Q>
+ (SYM(cdf_exppow_Q),SYM(x),SYM(a),SYM(b));
+
+ // Exponential power distribution
+ addGSLrngRealRealFunc<gsl_ran_rayleigh_tail>
+ (SYM(rng_rayleigh_tail),SYM(a),SYM(sigma));
+ addGSLRealRealRealFunc<gsl_ran_rayleigh_tail_pdf>
+ (SYM(pdf_rayleigh_tail),SYM(x),SYM(a),SYM(sigma));
+
+ // Landau distribution
+ addGSLrngVoidFunc<gsl_ran_landau>(SYM(rng_landau));
+ addGSLRealFunc<gsl_ran_landau_pdf>(SYM(pdf_landau),SYM(x));
+
+ // Levy skwew alpha-stable distribution
+ addFunc(GSLModule->e.ve,GSLrng_levy,primReal(),SYM(rng_levy),
+ formal(primReal(),SYM(c)),
+ formal(primReal(),SYM(alpha)),
+ formal(primReal(),SYM(beta),true,false));
+
+ // Gamma distribution
+ addFunc(GSLModule->e.ve,GSLrng_gamma,primReal(),SYM(rng_gamma),
+ formal(primReal(),SYM(a)),
+ formal(primReal(),SYM(b)),
+ formal(primString(),SYM(method),true,false));
+ addGSLRealRealRealFunc<gsl_ran_gamma_pdf>
+ (SYM(pdf_gamma),SYM(x),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_cdf_gamma_P>
+ (SYM(cdf_gamma_P),SYM(x),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_cdf_gamma_Q>
+ (SYM(cdf_gamma_Q),SYM(x),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_cdf_gamma_Pinv>
+ (SYM(cdf_gamma_Pinv),SYM(P),SYM(a),SYM(b));
+ addGSLRealRealRealFunc<gsl_cdf_gamma_Qinv>
+ (SYM(cdf_gamma_Qinv),SYM(Q),SYM(a),SYM(b));
+
+ // Sperical distributions
+ addFunc(GSLModule->e.ve,GSLrng_dir2d,primPair(),SYM(rng_dir2d),
+ formal(primString(),SYM(method),true,false));
+ addFunc(GSLModule->e.ve,GSLrng_dir3d,primTriple(),SYM(rng_dir3d));
+ addFunc(GSLModule->e.ve,GSLrng_dir,realArray(),SYM(rng_dir),
+ formal(primInt(),SYM(n)));
+
+ // Elliptic functions (Jacobi)
+ addFunc(GSLModule->e.ve,GSLsf_elljac_e,realArray(),SYM(sncndn),
+ formal(primReal(),SYM(u)),formal(primReal(),SYM(m)));
+
+ // Dirirchlet distribution
+ addFunc(GSLModule->e.ve,GSLrng_dirichlet,realArray(),SYM(rng_dirichlet),
+ formal(realArray(),SYM(alpha)));
+ addFunc(GSLModule->e.ve,GSLpdf_dirichlet,primReal(),SYM(pdf_dirichlet),
+ formal(realArray(),SYM(alpha)),
+ formal(realArray(),SYM(theta)));
+
+ // General discrete distributions
+ // to be implemented
+
+#define addGSLdiscdist1param(NAME,ARG,TYPE) \
+ addGSLrng##TYPE##FuncInt<gsl_ran_##NAME> \
+ (SYM(rng_##NAME),SYM(ARG)); \
+ addGSLUInt##TYPE##Func<gsl_ran_##NAME##_pdf> \
+ (SYM(pdf_##NAME),SYM(k),SYM(ARG)); \
+ addGSLUInt##TYPE##Func<gsl_cdf_##NAME##_P> \
+ (SYM(cdf_##NAME##_P),SYM(k),SYM(ARG)); \
+ addGSLUInt##TYPE##Func<gsl_cdf_##NAME##_Q> \
+ (SYM(cdf_##NAME##_Q),SYM(k),SYM(ARG))
+
+ // Poisson, geometric distributions
+ addGSLdiscdist1param(poisson,mu,Real);
+ addGSLdiscdist1param(geometric,p,Real);
+#undef addGSLdiscdist1param
+
+#define addGSLdiscdist2param(NAME,ARG1,TYPE1,ARG2,TYPE2) \
+ addGSLrng##TYPE1##TYPE2##FuncInt<gsl_ran_##NAME> \
+ (SYM(rng_##NAME),SYM(ARG1),SYM(ARG2)); \
+ addGSLUInt##TYPE1##TYPE2##Func<gsl_ran_##NAME##_pdf> \
+ (SYM(pdf_##NAME),SYM(k),SYM(ARG1),SYM(ARG2)); \
+ addGSLUInt##TYPE1##TYPE2##Func<gsl_cdf_##NAME##_P> \
+ (SYM(cdf_##NAME##_P),SYM(k),SYM(ARG1),SYM(ARG2)); \
+ addGSLUInt##TYPE1##TYPE2##Func<gsl_cdf_##NAME##_Q> \
+ (SYM(cdf_##NAME##_Q),SYM(k),SYM(ARG1),SYM(ARG2))
+
+ // Binomial, negative binomial distributions
+ addGSLdiscdist2param(binomial,p,Real,n,UInt);
+ addGSLdiscdist2param(negative_binomial,p,Real,n,Real);
+#undef addGSLdiscdist2param
+
+ // Logarithmic distribution
+ addGSLrngRealFuncInt<gsl_ran_logarithmic>(SYM(rng_logarithmic),SYM(p));
+ addGSLUIntRealFunc<gsl_ran_logarithmic_pdf>(SYM(pdf_logarithmic),SYM(k),
+ SYM(p));
+
+ // Bernoulli distribution
+ addGSLrngRealFuncInt<gsl_ran_bernoulli>(SYM(rng_bernoulli),SYM(p));
+ addGSLUIntRealFunc<gsl_ran_bernoulli_pdf>(SYM(pdf_bernoulli),SYM(k),SYM(p));
+
+ // Multinomial distribution
+ addFunc(GSLModule->e.ve,GSLrng_multinomial,IntArray(),SYM(rng_multinomial),
+ formal(primInt(),SYM(n)),
+ formal(realArray(),SYM(p)));
+ addFunc(GSLModule->e.ve,GSLpdf_multinomial,primReal(),SYM(pdf_multinomial),
+ formal(realArray(),SYM(p)),
+ formal(IntArray(),SYM(n)));
+
+ // Hypergeometric distribution
+ addGSLrngUIntUIntUIntFuncInt<gsl_ran_hypergeometric>
+ (SYM(rng_hypergeometric),SYM(n1),SYM(n2),SYM(t));
+ addGSLUIntUIntUIntUIntFunc<gsl_ran_hypergeometric_pdf>
+ (SYM(pdf_hypergeometric),SYM(k),SYM(n1),SYM(n2),SYM(t));
+ addGSLUIntUIntUIntUIntFunc<gsl_cdf_hypergeometric_P>
+ (SYM(cdf_hypergeometric_P),SYM(k),SYM(n1),SYM(n2),SYM(t));
+ addGSLUIntUIntUIntUIntFunc<gsl_cdf_hypergeometric_Q>
+ (SYM(cdf_hypergeometric_Q),SYM(k),SYM(n1),SYM(n2),SYM(t));
+}
+
+} // namespace trans
+
+#endif
diff --git a/graphics/asymptote/guide.cc b/graphics/asymptote/guide.cc
new file mode 100644
index 0000000000..6479a00ba5
--- /dev/null
+++ b/graphics/asymptote/guide.cc
@@ -0,0 +1,53 @@
+/*****
+ * guide.cc
+ * Andy Hammerlindl 2005/02/23
+ *
+ *****/
+
+#include "guide.h"
+
+namespace camp {
+
+multiguide::multiguide(guidevector& v)
+{
+ // This constructor tests if the first subguide is also a multiguide and,
+ // if possible, uses the same base, extending it beyond what is used.
+ multiguide *rg = v.empty() ? 0 : dynamic_cast<multiguide *>(v[0]);
+ if (rg && rg->base->size() == rg->length) {
+ base = rg->base;
+ base->insert(base->end(), v.begin()+1, v.end());
+ }
+ else
+ base = new guidevector(v);
+
+ length = base->size();
+}
+
+void multiguide::flatten(flatguide& g, bool allowsolve)
+{
+ size_t n=length;
+ if(n > 0) {
+ for(size_t i=0; i+1 < n; ++i) {
+ subguide(i)->flatten(g,allowsolve);
+ if(!allowsolve && subguide(i)->cyclic()) {
+ g.precyclic(true);
+ g.resolvecycle();
+ }
+ }
+ subguide(n-1)->flatten(g,allowsolve);
+ }
+}
+
+void multiguide::print(ostream& out) const
+{
+ side lastLoc=JOIN;
+ for(size_t i=0; i < length; ++i) {
+ guide *g = subguide(i);
+ side loc = g->printLocation();
+ adjustLocation(out,lastLoc,loc);
+ g->print(out);
+ lastLoc=loc;
+ }
+}
+
+} // namespace camp
diff --git a/graphics/asymptote/guide.h b/graphics/asymptote/guide.h
new file mode 100644
index 0000000000..a25e7ffa9e
--- /dev/null
+++ b/graphics/asymptote/guide.h
@@ -0,0 +1,319 @@
+/*****
+ * guide.h
+ * Andy Hammerlindl 2005/02/23
+ *
+ *****/
+
+#ifndef GUIDE_H
+#define GUIDE_H
+
+#include <iostream>
+#include "knot.h"
+#include "flatguide.h"
+#include "settings.h"
+
+namespace camp {
+
+// Abstract base class for guides.
+class guide : public gc {
+protected:
+public:
+ virtual ~guide() {}
+
+ // Returns the path that the guide represents.
+ virtual path solve() {
+ return path();
+ }
+
+ // Add the information in the guide to the flatguide, so that it can be
+ // solved via the knotlist solving routines.
+ // Returns true if guide has an interior cycle token.
+ virtual void flatten(flatguide&, bool allowsolve=true)=0;
+
+ virtual bool cyclic() {return false;}
+
+ virtual void print(ostream& out) const {
+ out << "nullpath";
+ }
+
+ // Needed so that multiguide can know where to put in ".." symbols.
+ virtual side printLocation() const {
+ return END;
+ }
+
+};
+
+inline ostream& operator<< (ostream& out, const guide& g)
+{
+ g.print(out);
+ return out;
+}
+
+// Draws dots between two printings of guides, if their locations are such that
+// the dots are necessary.
+inline void adjustLocation(ostream& out, side l1, side l2)
+{
+ if (l1 == END)
+ out << endl;
+ if ((l1 == END || l1 == OUT) && (l2 == IN || l2 == END))
+ out << "..";
+}
+
+// A guide representing a pair.
+class pairguide : public guide {
+ pair z;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.add(z);
+ }
+
+ pairguide(pair z)
+ : z(z) {}
+
+ path solve() {
+ return path(z);
+ }
+
+ void print(ostream& out) const {
+ out << z;
+ }
+
+ side printLocation() const {
+ return END;
+ }
+};
+
+
+// A guide representing a path.
+class pathguide : public guide {
+ path p;
+
+public:
+ void flatten(flatguide& g, bool allowsolve=true) {
+ g.add(p,allowsolve);
+ }
+
+ pathguide(path p)
+ : p(p) {}
+
+ path solve() {
+ return p;
+ }
+
+ bool cyclic() {return p.cyclic();}
+
+ void print(ostream& out) const {
+ out << p;
+ }
+
+ side printLocation() const {
+ return END;
+ }
+};
+
+// Tension expressions are evaluated to this class before being cast to a guide,
+// so that they can be cast to other types (such as guide3) instead.
+class tensionSpecifier : public gc {
+ double out,in;
+ bool atleast;
+
+public:
+ tensionSpecifier(double val, bool atleast=false)
+ : out(val), in(val), atleast(atleast) {}
+ tensionSpecifier(double out, double in, bool atleast=false)
+ : out(out), in(in), atleast(atleast) {}
+
+ double getOut() const { return out; }
+ double getIn() const { return in; }
+ bool getAtleast() const { return atleast; }
+};
+
+
+// A guide giving tension information (as part of a join).
+class tensionguide : public guide {
+ tension tout,tin;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.setTension(tin,IN);
+ g.setTension(tout,OUT);
+ }
+
+ tensionguide(tensionSpecifier spec)
+ : tout(spec.getOut(), spec.getAtleast()),
+ tin(spec.getIn(), spec.getAtleast()) {}
+
+ void print(ostream& out) const {
+ out << (tout.atleast ? ".. tension atleast " : ".. tension ")
+ << tout.val << " and " << tin.val << " ..";
+ }
+
+ side printLocation() const {
+ return JOIN;
+ }
+};
+
+// Similar to tensionSpecifier, curl expression are evaluated to this type
+// before being cast to guides.
+class curlSpecifier : public gc {
+ double value;
+ side s;
+
+public:
+ curlSpecifier(double value, side s)
+ : value(value), s(s) {}
+
+ double getValue() const { return value; }
+ side getSide() const { return s; }
+};
+
+// A guide giving a specifier.
+class specguide : public guide {
+ spec *p;
+ side s;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.setSpec(p,s);
+ }
+
+ specguide(spec *p, side s)
+ : p(p), s(s) {}
+
+ specguide(curlSpecifier spec)
+ : p(new curlSpec(spec.getValue())), s(spec.getSide()) {}
+
+ void print(ostream& out) const {
+ out << *p;
+ }
+
+ side printLocation() const {
+ return s;
+ }
+};
+
+// A guide for explicit control points between two knots. This could be done
+// with two specguides, instead, but this prints nicer, and is easier to encode.
+class controlguide : public guide {
+ pair zout, zin;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.setSpec(new controlSpec(zout), OUT);
+ g.setSpec(new controlSpec(zin), IN);
+ }
+
+ controlguide(pair zout,pair zin)
+ : zout(zout),zin(zin) {}
+ controlguide(pair z)
+ : zout(z),zin(z) {}
+
+ void print(ostream& out) const {
+ out << ".. controls "
+ << zout << " and " << zin << " ..";
+ }
+
+ side printLocation() const {
+ return JOIN;
+ }
+};
+
+// A guide that is a sequence of other guides. This is used, for instance is
+// joins, where we have the left and right guide, and possibly specifiers and
+// tensions in between.
+typedef mem::vector<guide *> guidevector;
+
+// A multiguide represents a guide given by the first "length" items of
+// the vector pointed to by "base".
+// The constructor, if given another multiguide as a first argument,
+// will try to avoid allocating a new "base" array.
+class multiguide : public guide {
+ guidevector *base;
+ size_t length;
+
+ guide *subguide(size_t i) const
+ {
+ assert(i < length);
+ assert(length <= base->size());
+ return (*base)[i];
+ }
+
+public:
+
+ multiguide(guidevector& v);
+
+ void flatten(flatguide&, bool=true);
+
+ bool cyclic() {
+ size_t n=length;
+ if(n < 1) return false;
+ return subguide(n-1)->cyclic();
+ }
+
+ path solve() {
+ if (settings::verbose>3) {
+ cerr << "solving guide:\n";
+ print(cerr); cerr << "\n\n";
+ }
+
+ flatguide g;
+ this->flatten(g);
+ path p=g.solve(false);
+
+ if (settings::verbose>3)
+ cerr << "solved as:\n" << p << "\n\n";
+
+ return p;
+ }
+
+ void print(ostream& out) const;
+
+ side printLocation() const {
+ int n = length;
+ return subguide(n-1)->printLocation();
+ }
+};
+
+struct cycleToken : public gc {};
+
+// A guide representing the cycle token.
+class cycletokguide : public guide {
+public:
+ void flatten(flatguide& g, bool allowsolve=true) {
+ // If cycles occur in the midst of a guide, the guide up to that point
+ // should be solved as a path. Any subsequent guide will work with that
+ // path locked in place.
+ if(allowsolve)
+ g.solve(true);
+ else
+ g.close();
+ }
+
+ bool cyclic() {return true;}
+
+ path solve() {
+ // Just a cycle on it's own makes an empty guide.
+ return path();
+ }
+
+ void print(ostream& out) const {
+ out << "cycle";
+ }
+
+ side printLocation() const {
+ return END;
+ }
+};
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::pairguide);
+GC_DECLARE_PTRFREE(camp::tensionSpecifier);
+GC_DECLARE_PTRFREE(camp::tensionguide);
+GC_DECLARE_PTRFREE(camp::curlSpecifier);
+GC_DECLARE_PTRFREE(camp::controlguide);
+GC_DECLARE_PTRFREE(camp::cycleToken);
+GC_DECLARE_PTRFREE(camp::cycletokguide);
+
+#endif // GUIDE_H
diff --git a/graphics/asymptote/guideflags.h b/graphics/asymptote/guideflags.h
new file mode 100644
index 0000000000..dae2b7cc47
--- /dev/null
+++ b/graphics/asymptote/guideflags.h
@@ -0,0 +1,20 @@
+/*****
+ * guideflags.h
+ * Tom Prince 2004/5/12
+ *
+ * These flags are used to indicate what specifications of the join are
+ * put on the stack.
+ *****/
+#ifndef GUIDEFLAGS_H
+#define GUIDEFLAGS_H
+
+namespace camp {
+
+#undef OUT
+#undef IN
+
+enum side { OUT, IN, END, JOIN };
+
+}
+
+#endif //GUIDEFLAGS_H
diff --git a/graphics/asymptote/impdatum.cc b/graphics/asymptote/impdatum.cc
new file mode 100644
index 0000000000..9d0be54f15
--- /dev/null
+++ b/graphics/asymptote/impdatum.cc
@@ -0,0 +1,615 @@
+#include <cstring>
+
+#include "stack.h"
+#include "env.h"
+#include "exp.h"
+#include "stm.h"
+#include "refaccess.h"
+
+using std::strlen;
+
+using namespace absyntax;
+using namespace trans;
+
+using vm::item;
+using vm::get;
+
+
+#include "policy.h"
+
+coenv &coenvInOngoingProcess();
+void runInOngoingProcess(absyntax::runnable *r);
+
+void runExp(absyntax::exp *e)
+{
+ absyntax::expStm s(nullPos, e);
+ runInOngoingProcess(&s);
+}
+
+class ImpDatum;
+class ImpArguments;
+
+ImpDatum *datumError(const char *msg);
+
+// Expression used for non-item datums.
+class errorExp : public absyntax::exp {
+public:
+ errorExp() : exp(nullPos) {}
+
+ void prettyprint(ostream &out, Int indent)
+ {
+ absyntax::prettyname(out, "errorExp", indent);
+ }
+
+ void complain() {
+ em.error(nullPos); em << "cannot use datum as expression";
+ }
+
+ types::ty *getType(coenv &) { return types::primError(); }
+ types::ty *trans(coenv &e) { complain(); return getType(e); }
+
+ void transAsType(coenv &e, types::ty *target) { complain(); }
+};
+
+// Abstract base class for Datum types.
+class ImpDatum {
+public:
+ virtual operator handle_typ() { return (handle_typ)(this); }
+
+ virtual int_typ toInt() {
+ datumError("cannot convert to integer");
+
+ // Return a weird value that will hopefully be noticed.
+ return -777777;
+ }
+
+ virtual bool toBool() {
+ datumError("cannot convert to bool");
+ return false;
+ }
+
+ virtual double toDouble() {
+ datumError("cannot convert to double");
+ return -777e77;
+ }
+
+ virtual string_typ toString() {
+ datumError("cannot convert to string");
+
+ string_typ s = { "XXXXX", 5 };
+ return s;
+ }
+
+ virtual absyntax::exp *getExp() {
+ datumError("invalid use of datum");
+ return new errorExp;
+ }
+
+ // How to access a field of the datum.
+ virtual absyntax::exp *getFieldExp(symbol id) {
+ assert(id);
+ return new fieldExp(nullPos, this->getExp(), id);
+ }
+
+ virtual ImpDatum *getField(const char *name);
+
+ virtual ImpDatum *getCell(ImpDatum *index) {
+ return datumError("cannot index datatype");
+ }
+
+ virtual void addField(const char *name, ImpDatum *init)
+ {
+ datumError("cannot set field of datatype");
+ }
+
+};
+
+// An ever-growing list of handles, used to avoid garbage collecting the data.
+// TODO: Implement effective releaseHandle.
+mem::vector<handle_typ> handles;
+
+handle_typ wrap(ImpDatum *d)
+{
+ handle_typ h = (handle_typ)(d);
+ handles.push_back(h);
+ return h;
+}
+
+ImpDatum *unwrap(handle_typ handle)
+{
+ assert(handle != 0);
+ return (ImpDatum *)(handle);
+}
+
+class ErrorDatum : public ImpDatum {
+};
+
+error_callback_typ errorCallback = 0;
+
+ImpDatum *datumError(const char *msg)
+{
+ static ErrorDatum ed;
+
+ if (errorCallback) {
+ string_typ s = { msg, strlen(msg) };
+ errorCallback(s);
+ }
+ else {
+ cerr << msg << '\n';
+ }
+
+ return &ed;
+}
+
+handle_typ imp_copyHandle(handle_typ handle)
+{
+ //cout << "+";
+ // For now, don't do anything.
+ return handle;
+}
+
+void imp_releaseHandle()
+{
+ //cout << "-";
+ // Do nothing, for now.
+}
+
+// A datum representing a value in Asymptote. Both the runtime representation
+// of the value and its type are stored.
+class ItemDatum : public ImpDatum {
+ item i;
+ types::ty *t;
+
+public:
+ // Every itemDatum has a fixed (non-overloaded) type, t
+ ItemDatum(types::ty *t) : t(t) {
+ assert(t);
+ assert(t->isNotOverloaded());
+ assert(t->isNotError());
+ }
+
+ // An expression that can be used to get and set the datum.
+ // The value should only be set once, when the datum is created, and not
+ // changed.
+ absyntax::exp *getExp() {
+ // It may be faster to create this once on start, but then the datum will
+ // require more space. For now, we create the access and expression on
+ // demand.
+ return new varEntryExp(nullPos, t, new itemRefAccess(&i));
+ }
+
+ int_typ toInt() {
+ // TODO: Decide if we want to use casting.
+ if (t->kind == types::ty_Int)
+ return static_cast<int_typ>(get<Int>(i));
+ else
+ return ImpDatum::toInt();
+ }
+
+ bool toBool() {
+ if (t->kind == types::ty_boolean)
+ return get<bool>(i);
+ else
+ return ImpDatum::toBool();
+ }
+
+ double toDouble() {
+ if (t->kind == types::ty_real)
+ return get<double>(i);
+ else
+ return ImpDatum::toDouble();
+ }
+
+ string_typ toString() {
+ if (t->kind == types::ty_string) {
+ // TODO: Fix for strings containing NUL.
+ string *s = get<string *>(i);
+ string_typ st = { s->c_str(), s->length() };
+ return st;
+ }
+ else
+ return ImpDatum::toString();
+ }
+};
+
+ItemDatum *ItemDatumFromExp(types::ty *t, absyntax::exp *e)
+{
+ ItemDatum *d = new ItemDatum(t);
+ assignExp ae(nullPos, d->getExp(), e);
+ runExp(&ae);
+
+ return d;
+}
+
+ItemDatum *ItemDatumFromInt(int_typ x)
+{
+ intExp ie(nullPos, static_cast<Int>(x));
+ return ItemDatumFromExp(types::primInt(), &ie);
+}
+
+ItemDatum *ItemDatumFromBool(bool x)
+{
+ booleanExp be(nullPos, x);
+ return ItemDatumFromExp(types::primBoolean(), &be);
+}
+
+ItemDatum *ItemDatumFromDouble(double x)
+{
+ realExp re(nullPos, x);
+ return ItemDatumFromExp(types::primReal(), &re);
+}
+
+ItemDatum *ItemDatumFromString(string_typ x)
+{
+ mem::string s(x.buf, (size_t)x.length);
+ stringExp se(nullPos, s);
+ return ItemDatumFromExp(types::primString(), &se);
+}
+
+
+// If the interface is asked to return a field which is overloaded, a handle
+// to and OverloadedDatum is returned. No evaluation actually occurs. The
+// datum simply consists of the containing datum and the name of the field
+// requested. Subsequent use of the datum will resolve the overloading (or
+// report an error).
+class OverloadedDatum : public ImpDatum {
+ ImpDatum *parent;
+ symbol id;
+
+public:
+ OverloadedDatum(ImpDatum *parent, symbol id) : parent(parent), id(id)
+ {
+ assert(parent);
+ assert(id);
+ }
+
+ absyntax::exp *getExp() {
+ return parent->getFieldExp(id);
+ return new fieldExp(nullPos, parent->getExp(), id);
+ }
+};
+
+ImpDatum *ImpDatum::getField(const char *name)
+{
+ coenv &e = coenvInOngoingProcess();
+ symbol id = symbol::trans(name);
+
+ absyntax::exp *ex = getFieldExp(id);
+
+ types::ty *t = ex->getType(e);
+ if (t->isError())
+ return datumError("no field of that name");
+
+ if (t->isOverloaded())
+ return new OverloadedDatum(this, id);
+
+ // Create a new datum and assign the variable to it.
+ ItemDatum *d = new ItemDatum(t);
+ assignExp ae(nullPos, d->getExp(), ex);
+ runExp(&ae);
+
+ return d;
+}
+
+handle_typ imp_handleFromInt(int_typ x)
+{
+ return wrap(ItemDatumFromInt(x));
+}
+
+handle_typ imp_handleFromBool(int_typ x)
+{
+ if (x != 0 && x != 1)
+ return wrap(datumError("invalid boolean value"));
+
+ return wrap(ItemDatumFromBool(x == 1));
+}
+
+handle_typ imp_handleFromDouble(double x)
+{
+ return wrap(ItemDatumFromDouble(x));
+}
+
+int_typ imp_IntFromHandle(handle_typ handle)
+{
+ return unwrap(handle)->toInt();
+}
+
+int_typ imp_boolFromHandle(handle_typ handle)
+{
+ return unwrap(handle)->toBool() ? 1 : 0;
+}
+
+double imp_doubleFromHandle(handle_typ handle)
+{
+ return unwrap(handle)->toDouble();
+}
+
+
+handle_typ imp_handleFromString(string_typ x)
+{
+ return wrap(ItemDatumFromString(x));
+}
+
+string_typ imp_stringFromHandle(handle_typ handle)
+{
+ return unwrap(handle)->toString();
+}
+
+handle_typ imp_getField(handle_typ handle, const char *name)
+{
+ return wrap(unwrap(handle)->getField(name));
+}
+
+handle_typ imp_getCell(handle_typ handle, handle_typ index)
+{
+ return wrap(unwrap(handle)->getCell(unwrap(index)));
+}
+
+void imp_addField(handle_typ handle, const char *name, handle_typ init)
+{
+ unwrap(handle)->addField(name, unwrap(init));
+}
+
+class ImpArguments /* TODO: gc visible but not collected */ {
+ arglist args;
+public:
+
+ ImpArguments() {}
+
+ void add(const char *name, ImpDatum *arg, arg_rest_option isRest)
+ {
+ assert(isRest == NORMAL_ARG); // TODO: Implement rest.
+ symbol id = (name && name[0]) ? symbol::trans(name) : symbol::nullsym;
+
+ args.add(arg->getExp(), id);
+ }
+
+ arglist *getArgs() { return &args; }
+};
+
+arguments_typ wrapArgs(ImpArguments *args)
+{
+ return (arguments_typ)(args);
+}
+ImpArguments *unwrapArgs(arguments_typ args)
+{
+ return (ImpArguments *)(args);
+}
+
+arguments_typ imp_newArguments()
+{
+ return wrapArgs(new ImpArguments);
+}
+
+void imp_releaseArguments(arguments_typ args)
+{
+ // For now, do nothing.
+}
+
+void imp_addArgument(arguments_typ args, const char *name, handle_typ handle,
+ arg_rest_option isRest)
+{
+ unwrapArgs(args)->add(name, unwrap(handle), isRest);
+}
+
+ImpDatum *callDatum(ImpDatum *callee, ImpArguments *args)
+{
+ coenv &e = coenvInOngoingProcess();
+
+ callExp callex(nullPos, callee->getExp(), args->getArgs());
+
+ types::ty *t = callex.getType(e);
+ if (t->isError()) {
+ // Run for errors.
+ runExp(&callex); em.sync();
+ return datumError("invalid call");
+ }
+
+ assert(t->isNotOverloaded()); // Calls are never overloaded.
+
+ if (t->kind == types::ty_void) {
+ // Execute the call and return 0 to indicate void.
+ runExp(&callex);
+ return 0;
+ }
+ else
+ return ItemDatumFromExp(t, &callex);
+}
+
+handle_typ imp_call(handle_typ callee, arguments_typ args)
+{
+ return wrap(callDatum(unwrap(callee), unwrapArgs(args)));
+}
+
+class GlobalsDatum : public ImpDatum {
+ typedef std::map<const char*, ImpDatum *> gmap;
+ gmap base;
+
+ virtual absyntax::exp *getFieldExp(symbol id)
+ {
+ // Fields of the globals datum are global variables. Use the unqualified
+ // name.
+ return new nameExp(nullPos, id);
+ }
+
+ virtual void addField(const char *name, ImpDatum *init) {
+ datumError("addField not yet re-implemented");
+ }
+};
+
+class ImpState {
+ //ImpArguments *params;
+
+ ImpDatum *retval;
+public:
+ ImpState() : retval(0) {}
+
+ ImpDatum *globals() {
+ return new GlobalsDatum();
+ }
+
+ int_typ numParams() {
+ /*if (params)
+ return params->val.size();
+ else */ {
+ datumError("parameters accessed outside of function");
+ return 0;
+ }
+ }
+
+ ImpDatum *getParam(int_typ index) {
+ /*if (params) {
+ if (index >= 0 && index < static_cast<int_typ>(params->val.size()))
+ return params->val[index];
+ else
+ return datumError("invalid index for parameter");
+ }
+ else */ {
+ return datumError("parameters accessed outside of function");
+ }
+ }
+
+ void setReturnValue(ImpDatum *retval)
+ {
+ /*if (params) {
+ if (this->retval)
+ datumError("return value set more than once");
+ else
+ this->retval = retval;
+ }
+ else */ {
+ datumError("return value set outside of function");
+ }
+ }
+
+ ImpDatum *getReturnValue()
+ {
+ return retval;
+ }
+};
+
+state_typ wrapState(ImpState *s)
+{
+ return (state_typ)(s);
+}
+ImpState *unwrapState(state_typ s)
+{
+ return (ImpState *)(s);
+}
+
+
+handle_typ imp_globals(state_typ state)
+{
+ return wrap(unwrapState(state)->globals());
+}
+
+int_typ imp_numParams(state_typ state)
+{
+ return unwrapState(state)->numParams();
+}
+
+handle_typ imp_getParam(state_typ state, int_typ index)
+{
+ return wrap(unwrapState(state)->getParam(index));
+}
+
+void imp_setReturnValue(state_typ state, handle_typ handle)
+{
+ unwrapState(state)->setReturnValue(unwrap(handle));
+}
+
+state_typ cheatState()
+{
+ return wrapState(new ImpState());
+}
+
+#if 0
+class FunctionDatum : public ImpDatum {
+ function_typ f;
+ void *data;
+
+public:
+ FunctionDatum(function_typ f, void *data) : f(f), data(data) {}
+
+ ImpDatum *call(ImpArguments *args) {
+ ImpState state(args);
+
+ // Call the function.
+ f(wrapState(&state),data);
+
+ if (state.getReturnValue())
+ return state.getReturnValue();
+ else
+ // TODO: Decide on datum for void return.
+ return 0;
+ }
+};
+#endif
+
+handle_typ imp_handleFromFunction(const char *signature,
+ function_typ f, void *data)
+{
+ // TODO: Re-implement.
+ return 0; //wrap(new FunctionDatum(f, data));
+}
+
+void imp_setErrorCallback(error_callback_typ callback)
+{
+ errorCallback = callback;
+}
+
+extern policy_typ imp_policy;
+policy_typ imp_policy =
+{
+ /* version = */ 101,
+ imp_copyHandle,
+ imp_releaseHandle,
+ imp_handleFromInt,
+ imp_handleFromBool,
+ imp_handleFromDouble,
+ imp_handleFromString,
+ imp_handleFromFunction,
+ imp_IntFromHandle,
+ imp_boolFromHandle,
+ imp_doubleFromHandle,
+ imp_stringFromHandle,
+ imp_getField,
+ imp_getCell,
+ imp_addField,
+ imp_newArguments,
+ imp_releaseArguments,
+ imp_addArgument,
+ imp_call,
+ imp_globals,
+ imp_numParams,
+ imp_getParam,
+ imp_setReturnValue,
+ imp_setErrorCallback,
+};
+
+// Defined in process.cc
+void init(bool resetpath=true);
+
+extern "C" {
+
+policy_typ *_asy_getPolicy()
+{
+ return &imp_policy;
+}
+
+state_typ _asy_getState()
+{
+ static state_typ state = cheatState();
+
+ // TODO: Make sure this runs once.
+ char buf[] = "asymptote.so";
+ char *argv [] = { buf };
+ settings::setOptions(1,argv);
+
+ // Ensures uptodate is not used.
+ init();
+
+ return state;
+}
+
+}
diff --git a/graphics/asymptote/inst.h b/graphics/asymptote/inst.h
new file mode 100644
index 0000000000..fbbe6d873d
--- /dev/null
+++ b/graphics/asymptote/inst.h
@@ -0,0 +1,78 @@
+/*****
+ * inst.h
+ * Andy Hammerlindl 2002/06/27
+ *
+ * Descibes the items and instructions that are used by the virtual machine.
+ *****/
+
+#ifndef INST_H
+#define INST_H
+
+#include <iterator>
+#include <iostream>
+
+#include "errormsg.h"
+#include "item.h"
+#include "vm.h"
+
+namespace vm {
+
+// Forward declarations
+struct inst; class stack; class program;
+
+// A function "lambda," that is, the code that runs a function.
+// It also needs the closure of the enclosing module or function to run.
+struct lambda : public gc {
+ // The instructions to follow.
+ program *code;
+
+ // The index of the link to the parent closure in the frame corresponding to
+ // this function.
+ size_t parentIndex;
+
+ // The total number of items that will be stored in the closure of this
+ // function. Includes a link to the higher closure, the parameters, and the
+ // local variables.
+ // NOTE: In order to help garbage collection, this could be modified to
+ // have one array store escaping items, and another to store non-
+ // escaping items.
+ size_t framesize;
+
+ // States whether any of the variables escape the function, in which case a
+ // closure needs to be allocated when the function is called. It is
+ // initially set to "maybe" and it is computed the first time the function
+ // is called.
+ enum { NEEDS_CLOSURE, DOESNT_NEED_CLOSURE, MAYBE_NEEDS_CLOSURE} closureReq;
+
+#ifdef DEBUG_FRAME
+ string name;
+
+ lambda()
+ : closureReq(MAYBE_NEEDS_CLOSURE), name("<unnamed>") {}
+ virtual ~lambda() {}
+#else
+ lambda()
+ : closureReq(MAYBE_NEEDS_CLOSURE) {}
+#endif
+};
+
+// The code run is just a string of instructions. The ops are actual commands
+// to be run, but constants, labels, and other objects can be in the code.
+struct inst : public gc {
+ enum opcode {
+#define OPCODE(name,type) name,
+#include "opcodes.h"
+#undef OPCODE
+ };
+ opcode op;
+ position pos;
+ item ref;
+};
+template<typename T>
+inline T get(const inst& it)
+{ return get<T>(it.ref); }
+
+} // namespace vm
+
+#endif
+
diff --git a/graphics/asymptote/install-sh b/graphics/asymptote/install-sh
new file mode 100755
index 0000000000..6781b987bd
--- /dev/null
+++ b/graphics/asymptote/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/graphics/asymptote/interact.cc b/graphics/asymptote/interact.cc
new file mode 100644
index 0000000000..c49f50d2b9
--- /dev/null
+++ b/graphics/asymptote/interact.cc
@@ -0,0 +1,231 @@
+/*****
+ * interact.cc
+ *
+ * The glue between the lexical analyzer and the readline library.
+ *****/
+
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <csignal>
+#include <cstdio>
+#include <cstring>
+
+#include "interact.h"
+#include "runhistory.h"
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+#include "util.h"
+#include "errormsg.h"
+
+using namespace settings;
+
+namespace run {
+void init_readline(bool);
+}
+
+namespace interact {
+
+bool interactive=false;
+bool uptodate=true;
+int lines=0;
+bool query=false;
+
+bool tty=isatty(STDIN_FILENO);
+completer *currentCompleter=0;
+
+void setCompleter(completer *c) {
+ currentCompleter=c;
+}
+
+char *call_completer(const char *text, int state) {
+ return currentCompleter ? (*currentCompleter)(text, state) : 0;
+}
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+void init_completion() {
+ rl_completion_entry_function=call_completer;
+
+ rl_completion_append_character='\0'; // Don't add a space after a match.
+
+ /*
+ // Build a string containing all characters that separate words to be
+ // completed. All characters that can't form part of an identifier are
+ // treated as break characters.
+ static char break_characters[128];
+ Int j=0;
+ for (unsigned char c=9; c < 128; ++c)
+ if (!isalnum(c) && c != '_') {
+ break_characters[j]=c;
+ ++j;
+ }
+ break_characters[j]='\0';
+ rl_completer_word_break_characters=break_characters;
+ */
+}
+#endif
+
+char *(*Readline)(const char *prompt);
+
+char *readverbatimline(const char *prompt)
+{
+ if(!cin.good()) {cin.clear(); return NULL;}
+ cout << prompt;
+ string s;
+ getline(cin,s);
+ return StrdupMalloc(s);
+}
+
+FILE *fin=NULL;
+
+char *readpipeline(const char *prompt)
+{
+#if _POSIX_VERSION >= 200809L
+ char *line=NULL;
+ size_t n=0;
+ return getline(&line,&n,fin) >= 0 ? line : NULL;
+#else
+ const int max_size=256;
+ static char buf[max_size];
+ ostringstream s;
+ do {
+ if(fgets(buf,max_size-1,fin) == NULL) break;
+ s << buf;
+ } while(buf[std::strlen(buf)-1] != '\n');
+ return StrdupMalloc(s.str());
+#endif
+}
+
+void pre_readline()
+{
+ int fd=intcast(settings::getSetting<Int>("inpipe"));
+ if(fd >= 0) {
+ if(!fin) fin=fdopen(fd,"r");
+ Readline=readpipeline;
+ } else {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ Readline=readline;
+ } else
+#endif
+ Readline=readverbatimline;
+ }
+}
+
+void init_interactive()
+{
+ if(getSetting<bool>("xasy")) tty=false;
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ init_completion();
+ run::init_readline(getSetting<bool>("tabcompletion"));
+ read_history(historyname.c_str());
+ }
+#endif
+}
+
+string simpleline(string prompt) {
+ // Rebind tab key, as the setting tabcompletion may be changed at runtime.
+ pre_readline();
+
+ Signal(SIGINT,SIG_IGN);
+ // Get a line from the user.
+ char *line=Readline(prompt.c_str());
+ Signal(SIGINT,interruptHandler);
+
+ // Reset scroll count.
+ interact::lines=0;
+ interact::query=tty;
+
+ // Ignore keyboard interrupts while taking input.
+ errorstream::interrupt=false;
+
+ if(line) {
+ string s=line;
+ free(line);
+ return s;
+ } else {
+ cout << endl;
+ if(!tty || getSetting<bool>("exitonEOF"))
+ throw eof();
+ return "\n";
+ }
+}
+
+void addToHistory(string line) {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ // Only add it if it has something other than newlines.
+ if(tty && line.find_first_not_of('\n') != string::npos) {
+ add_history(line.c_str());
+ }
+#endif
+}
+
+string getLastHistoryLine() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty && history_length > 0) {
+ HIST_ENTRY *entry=history_list()[history_length-1];
+ if(!entry) {
+ em.compiler();
+ em << "cannot access last history line";
+ return "";
+ } else
+ return entry->line;
+ } else
+#endif
+ return "";
+}
+
+void setLastHistoryLine(string line) {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ if (history_length > 0) {
+ HIST_ENTRY *entry=remove_history(history_length-1);
+
+ if(!entry) {
+ em.compiler();
+ em << "cannot modify last history line";
+ } else {
+ free(entry->line);
+ free(entry);
+ }
+ }
+ addToHistory(line);
+ }
+#endif
+}
+
+void deleteLastLine() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ HIST_ENTRY *entry=remove_history(history_length-1);
+ if(!entry) {
+ em.compiler();
+ em << "cannot delete last history line";
+ } else {
+ free(entry->line);
+ free(entry);
+ }
+ }
+#endif
+}
+
+void cleanup_interactive() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ // Write the history file.
+ if(tty) {
+ stifle_history(intcast(getSetting<Int>("historylines")));
+ write_history(historyname.c_str());
+ }
+#endif
+}
+
+} // namespace interact
diff --git a/graphics/asymptote/interact.h b/graphics/asymptote/interact.h
new file mode 100644
index 0000000000..e1827e3701
--- /dev/null
+++ b/graphics/asymptote/interact.h
@@ -0,0 +1,54 @@
+/*****
+ * interact.h
+ *
+ * The glue between the lexical analyzer and the readline library.
+ *****/
+
+#ifndef INTERACT_H
+#define INTERACT_H
+
+#include "common.h"
+
+void interruptHandler(int);
+
+namespace interact {
+
+extern bool interactive;
+extern bool uptodate;
+extern int lines; // Interactive scroll count
+extern bool query; // Enable interactive scrolling;
+
+void init_interactive();
+
+// Read a line from the input, without any processing.
+string simpleline(string prompt);
+
+// Add a line of input to the readline history.
+void addToHistory(string line);
+
+// Functions to work with the most recently entered line in the history.
+string getLastHistoryLine();
+void setLastHistoryLine(string line);
+
+// Remove the line last added to the history.
+void deleteLastLine();
+
+// Write out the history of input lines to the history file.
+void cleanup_interactive();
+
+// This class is used to set a text completion function for readline. A class
+// is used instead the usual function pointer so that information such as the
+// current environment can be coded into the function (mimicking a closure).
+class completer {
+public:
+ virtual ~completer() {};
+ virtual char *operator () (const char *text, int state) = 0;
+};
+
+void setCompleter(completer *c);
+
+#define YY_READ_BUF_SIZE YY_BUF_SIZE
+
+}
+
+#endif // INTERACT_H
diff --git a/graphics/asymptote/item.h b/graphics/asymptote/item.h
new file mode 100644
index 0000000000..60fb89fe6e
--- /dev/null
+++ b/graphics/asymptote/item.h
@@ -0,0 +1,315 @@
+/*****
+ * item.h
+ * Tom Prince and John Bowman 2005/04/12
+ *
+ * Descibes the items that are used by the virtual machine.
+ *****/
+
+#ifndef ITEM_H
+#define ITEM_H
+
+#include "common.h"
+#include <cfloat>
+#include <cmath>
+
+#if COMPACT
+#include <cassert>
+#else
+#include <typeinfo>
+#endif
+
+namespace vm {
+
+class item;
+class bad_item_value {};
+
+template<typename T>
+T get(const item&);
+
+#if COMPACT
+// Identify a default argument.
+extern const Int DefaultValue;
+
+// Identify an undefined item.
+extern const Int Undefined;
+
+// Values for true and false unlikely to match other values.
+extern const Int BoolTruthValue;
+extern const Int BoolFalseValue;
+
+inline Int valueFromBool(bool b) {
+ return b ? BoolTruthValue : BoolFalseValue;
+}
+#endif
+
+extern const item Default;
+
+class item : public gc {
+private:
+
+#if !COMPACT
+ const std::type_info *kind;
+#endif
+
+ union {
+ Int i;
+ double x;
+#if !COMPACT
+ bool b;
+#endif
+ void *p;
+ };
+
+public:
+#if COMPACT
+ bool empty() const
+ {return i >= Undefined;}
+
+ item() : i(Undefined) {}
+
+ item(Int i)
+ : i(i) {}
+ item(int i)
+ : i(i) {}
+ item(double x)
+ : x(x) {}
+ item(bool b)
+ : i(valueFromBool(b)) {}
+
+ item& operator= (int a)
+ { i=a; return *this; }
+ item& operator= (unsigned int a)
+ { i=a; return *this; }
+ item& operator= (Int a)
+ { i=a; return *this; }
+ item& operator= (double a)
+ { x=a; return *this; }
+ item& operator= (bool b)
+ { i=valueFromBool(b); return *this; }
+
+ template<class T>
+ item(T *p)
+ : p((void *) p) {
+ assert(!empty());
+ }
+
+ template<class T>
+ item(const T &p)
+ : p(new(UseGC) T(p)) {
+ assert(!empty());
+ }
+
+ template<class T>
+ item& operator= (T *a)
+ { p=(void *) a; return *this; }
+
+ template<class T>
+ item& operator= (const T &it)
+ { p=new(UseGC) T(it); return *this; }
+#else
+ bool empty() const
+ {return *kind == typeid(void);}
+
+ item()
+ : kind(&typeid(void)) {}
+
+ item(Int i)
+ : kind(&typeid(Int)), i(i) {}
+ item(int i)
+ : kind(&typeid(Int)), i(i) {}
+ item(double x)
+ : kind(&typeid(double)), x(x) {}
+ item(bool b)
+ : kind(&typeid(bool)), b(b) {}
+
+ item& operator= (int a)
+ { kind=&typeid(Int); i=a; return *this; }
+ item& operator= (unsigned int a)
+ { kind=&typeid(Int); i=a; return *this; }
+ item& operator= (Int a)
+ { kind=&typeid(Int); i=a; return *this; }
+ item& operator= (double a)
+ { kind=&typeid(double); x=a; return *this; }
+ item& operator= (bool a)
+ { kind=&typeid(bool); b=a; return *this; }
+
+ template<class T>
+ item(T *p)
+ : kind(&typeid(T)), p((void *) p) {}
+
+ template<class T>
+ item(const T &p)
+ : kind(&typeid(T)), p(new(UseGC) T(p)) {}
+
+ template<class T>
+ item& operator= (T *a)
+ { kind=&typeid(T); p=(void *) a; return *this; }
+
+ template<class T>
+ item& operator= (const T &it)
+ { kind=&typeid(T); p=new(UseGC) T(it); return *this; }
+
+ const std::type_info &type() const
+ { return *kind; }
+#endif
+
+ template<typename T>
+ friend inline T get(const item&);
+
+ friend inline bool isdefault(const item&);
+
+ friend ostream& operator<< (ostream& out, const item& i);
+
+private:
+ template <typename T>
+ struct help;
+
+ template <typename T>
+ struct help<T*> {
+ static T* unwrap(const item& it)
+ {
+#if COMPACT
+ if(!it.empty())
+ return (T*) it.p;
+#else
+ if(*it.kind == typeid(T))
+ return (T*) it.p;
+#endif
+ throw vm::bad_item_value();
+ }
+ };
+
+ template <typename T>
+ struct help {
+ static T& unwrap(const item& it)
+ {
+#if COMPACT
+ if(!it.empty())
+ return *(T*) it.p;
+#else
+ if(*it.kind == typeid(T))
+ return *(T*) it.p;
+#endif
+ throw vm::bad_item_value();
+ }
+ };
+};
+
+#ifdef SIMPLE_FRAME
+// In the simple implementation, a frame is just an array of items.
+typedef item frame;
+#else
+class frame : public gc {
+#ifdef DEBUG_FRAME
+ string name;
+ Int parentIndex;
+#endif
+ typedef mem::vector<item> internal_vars_t;
+ internal_vars_t vars;
+
+ // Allow the stack direct access to vars.
+ friend class stack;
+public:
+#ifdef DEBUG_FRAME
+ frame(string name, Int parentIndex, size_t size)
+ : name(name), parentIndex(parentIndex), vars(size)
+ {}
+
+ string getName() { return name; }
+
+ Int getParentIndex() { return parentIndex; }
+#else
+ frame(size_t size)
+ : vars(size)
+ {}
+#endif
+
+ item& operator[] (size_t n)
+ { return vars[n]; }
+ item operator[] (size_t n) const
+ { return vars[n]; }
+
+ size_t size()
+ { return vars.size(); }
+
+ // Extends vars to ensure it has a place for any variable indexed up to n.
+ void extend(size_t n) {
+ if(vars.size() < n)
+ vars.resize(n);
+ }
+};
+#endif
+
+
+template<typename T>
+inline T get(const item& it)
+{
+ return item::help<T>::unwrap(it);
+}
+
+template <>
+inline int get<int>(const item&)
+{
+ throw vm::bad_item_value();
+}
+
+template <>
+inline Int get<Int>(const item& it)
+{
+#if COMPACT
+ if(!it.empty())
+ return it.i;
+#else
+ if(*it.kind == typeid(Int))
+ return it.i;
+#endif
+ throw vm::bad_item_value();
+}
+
+template <>
+inline double get<double>(const item& it)
+{
+#if COMPACT
+ if(!it.empty())
+ return it.x;
+#else
+ if(*it.kind == typeid(double))
+ return it.x;
+#endif
+ throw vm::bad_item_value();
+}
+
+template <>
+inline bool get<bool>(const item& it)
+{
+#if COMPACT
+ if(it.i == BoolTruthValue)
+ return true;
+ if(it.i == BoolFalseValue)
+ return false;
+#else
+ if(*it.kind == typeid(bool))
+ return it.b;
+#endif
+ throw vm::bad_item_value();
+}
+
+#if !COMPACT
+// This serves as the object for representing a default argument.
+struct default_t : public gc {};
+#endif
+
+inline bool isdefault(const item& it)
+{
+#if COMPACT
+ return it.i == DefaultValue;
+#else
+ return *it.kind == typeid(default_t);
+#endif
+}
+
+ostream& operator<< (ostream& out, const item& i);
+
+} // namespace vm
+
+#endif // ITEM_H
diff --git a/graphics/asymptote/keywords.cc b/graphics/asymptote/keywords.cc
new file mode 100644
index 0000000000..19c9bbe4df
--- /dev/null
+++ b/graphics/asymptote/keywords.cc
@@ -0,0 +1,46 @@
+/*****
+ * This file is automatically generated by keywords.pl.
+ * Changes will be overwritten.
+ *****/
+
+ADD(and);
+ADD(controls);
+ADD(tension);
+ADD(atleast);
+ADD(curl);
+ADD(if);
+ADD(else);
+ADD(while);
+ADD(for);
+ADD(do);
+ADD(return);
+ADD(break);
+ADD(continue);
+ADD(struct);
+ADD(typedef);
+ADD(new);
+ADD(access);
+ADD(import);
+ADD(unravel);
+ADD(from);
+ADD(include);
+ADD(quote);
+ADD(static);
+ADD(public);
+ADD(private);
+ADD(restricted);
+ADD(this);
+ADD(explicit);
+ADD(true);
+ADD(false);
+ADD(null);
+ADD(cycle);
+ADD(newframe);
+ADD(operator);
+ADD(quit);
+ADD(q);
+ADD(exit);
+ADD(reset);
+ADD(erase);
+ADD(help);
+ADD(input);
diff --git a/graphics/asymptote/keywords.pl b/graphics/asymptote/keywords.pl
new file mode 100755
index 0000000000..d3b48c5220
--- /dev/null
+++ b/graphics/asymptote/keywords.pl
@@ -0,0 +1,60 @@
+#!/usr/bin/env perl
+#####
+# keywords.pl
+# Andy Hammerlindl 2006/07/31
+#
+# Extract keywords from camp.l and list them in a keywords file. These
+# keywords are used in autocompletion at the interactive prompt.
+#####
+
+# Extra keywords to add that aren't automatically extracted, currently none.
+@extrawords = ();
+
+
+open(keywords, ">keywords.cc") ||
+ die("Couldn't open keywords.out for writing.");
+
+print keywords <<END;
+/*****
+ * This file is automatically generated by keywords.pl.
+ * Changes will be overwritten.
+ *****/
+
+END
+
+sub add {
+ print keywords "ADD(".$_[0].");\n";
+}
+
+foreach $word (@extrawords) {
+ add($word);
+}
+
+open(camp, "camp.l") || die("Couldn't open camp.l");
+
+# Search for the %% separator, after which the definitions start.
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # Break out of the loop.
+ }
+}
+
+# Grab simple keyword definitions from camp.l
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # A second %% indicates the end of definitions.
+ }
+ if (/^([A-Za-z_][A-Za-z0-9_]*)\s*\{/) {
+ add($1);
+ }
+}
+
+# Grab the special commands from the interactive prompt.
+open(process, "process.cc") || dir("Couldn't open process.cc");
+
+while (<process>) {
+ if (/^\s*ADDCOMMAND\(\s*([A-Za-z_][A-Za-z0-9_]*),/) {
+ add($1);
+ }
+}
+
diff --git a/graphics/asymptote/knot.cc b/graphics/asymptote/knot.cc
new file mode 100644
index 0000000000..199be8249b
--- /dev/null
+++ b/graphics/asymptote/knot.cc
@@ -0,0 +1,840 @@
+/*****
+ * knot.cc
+ * Andy Hammerlindl 2005/02/10
+ *
+ * Describes a knot, a point and its neighbouring specifiers, used as an
+ * intermediate structure in solving paths.
+ *****/
+
+#include "knot.h"
+#include "util.h"
+
+#include "angle.h"
+#include "settings.h"
+
+namespace camp {
+
+/***** Debugging *****/
+//bool tracing_solving=false;
+
+template <typename T>
+ostream& info(ostream& o, const char *name, cvector<T>& v)
+{
+ if (settings::verbose > 3) {
+ o << name << ":\n\n";
+
+ for(Int i=0; i < (Int) v.size(); ++i)
+ o << v[i] << endl;
+
+ o << endl;
+ }
+ return o;
+}
+
+ostream& info(ostream& o, string name, knotlist& l)
+{
+ if (settings::verbose > 3) {
+ o << name << ":\n\n";
+
+ for(Int i=0; i < (Int) l.size(); ++i)
+ o << l[i] << endl;
+
+ if (l.cyclic())
+ o << "cyclic" << endl;
+
+ o << endl;
+ }
+ return o;
+}
+
+#define INFO(x) info(cerr,#x,x)
+
+/***** Auxillary computation functions *****/
+
+// Computes the relative distance of a control point given the angles.
+// The name is somewhat misleading as the velocity (with respect to the
+// variable that parameterizes the path) is relative to the distance
+// between the knots and even then, is actually three times this.
+// The routine is based on the velocity function in Section 131 of the MetaPost
+// code, but differs in that it automatically accounts for the tension and
+// bounding with tension atleast.
+double velocity(double theta, double phi, tension t)
+{
+ static const double VELOCITY_BOUND = 4.0;
+ static const double a = sqrt(2.0);
+ static const double b = 1.0/16.0;
+ static const double c = 1.5*(sqrt(5.0)-1.0);
+ static const double d = 1.5*(3.0-sqrt(5.0));
+
+ double st = sin(theta), ct = cos(theta),
+ sf = sin(phi), cf = cos(phi);
+
+ double denom = t.val * (3.0 + c*ct + d*cf);
+
+ double r = denom != 0.0 ? (2.0 + a*(st - b*sf)*(sf - b*st)*(ct-cf)) / denom
+ : VELOCITY_BOUND;
+
+ //cerr << " velocity(" << theta << "," << phi <<")= " << r << endl;
+ if (r > VELOCITY_BOUND)
+ r = VELOCITY_BOUND;
+
+ // Apply boundedness condition for tension atleast cases.
+ if (t.atleast)
+ {
+ double sine = sin(theta + phi);
+ if ((st >= 0.0 && sf >= 0.0 && sine > 0.0) ||
+ (st <= 0.0 && sf <= 0.0 && sine < 0.0))
+ {
+ double rmax = sf / sine;
+ if (r > rmax)
+ r = rmax;
+ }
+ }
+
+ return r;
+}
+
+double niceAngle(pair z)
+{
+ return z.gety() == 0 ? z.getx() >= 0 ? 0 : PI
+ : angle(z);
+}
+
+// Ensures an angle is in the range between -PI and PI.
+double reduceAngle(double angle)
+{
+ return angle > PI ? angle - 2.0*PI :
+ angle < -PI ? angle + 2.0*PI :
+ angle;
+}
+
+
+bool interesting(tension t)
+{
+ return t.val!=1.0 || t.atleast==true;
+}
+
+bool interesting(spec *s)
+{
+ return !s->open();
+}
+
+ostream& operator<<(ostream& out, const knot& k)
+{
+ if (interesting(k.tin))
+ out << k.tin << " ";
+ if (interesting(k.in))
+ out << *k.in << " ";
+ out << k.z;
+ if (interesting(k.out))
+ out << " " << *k.out;
+ if (interesting(k.tout))
+ out << " " << k.tout;
+ return out;
+}
+
+
+eqn dirSpec::eqnOut(Int j, knotlist& l, cvector<double>&, cvector<double>&)
+{
+ // When choosing the control points, the path will come out the first knot
+ // going straight to the next knot rotated by the angle theta.
+ // Therefore, the angle theta we want is the difference between the
+ // specified heading given and the heading to the next knot.
+ double theta=reduceAngle(given-niceAngle(l[j+1].z-l[j].z));
+
+ // Give a simple linear equation to ensure this theta is picked.
+ return eqn(0.0,1.0,0.0,theta);
+}
+
+eqn dirSpec::eqnIn(Int j, knotlist& l, cvector<double>&, cvector<double>&)
+{
+ double theta=reduceAngle(given-niceAngle(l[j].z-l[j-1].z));
+ return eqn(0.0,1.0,0.0,theta);
+}
+
+eqn curlSpec::eqnOut(Int j, knotlist& l, cvector<double>&,
+ cvector<double>& psi)
+{
+ double alpha=l[j].alpha();
+ double beta=l[j+1].beta();
+
+ double chi=alpha*alpha*gamma/(beta*beta);
+
+ double C=alpha*chi+3-beta;
+ double D=(3.0-alpha)*chi+beta;
+
+ return eqn(0.0,C,D,-D*psi[j+1]);
+}
+
+eqn curlSpec::eqnIn(Int j, knotlist& l, cvector<double>&, cvector<double>&)
+{
+ double alpha=l[j-1].alpha();
+ double beta=l[j].beta();
+
+ double chi=beta*beta*gamma/(alpha*alpha);
+
+ double A=(3-beta)*chi+alpha;
+ double B=beta*chi+3-alpha;
+
+ return eqn(A,B,0.0,0.0);
+}
+
+spec *controlSpec::outPartner(pair z)
+{
+ static curlSpec curl;
+ return cz==z ? (spec *)&curl : (spec *)new dirSpec(z-cz);
+}
+
+spec *controlSpec::inPartner(pair z)
+{
+ static curlSpec curl;
+ return cz==z ? (spec *)&curl : (spec *)new dirSpec(cz-z);
+}
+
+// Compute the displacement between points. The j-th result is the distance
+// between knot j and knot j+1.
+struct dzprop : public knotprop<pair> {
+ dzprop(knotlist& l)
+ : knotprop<pair>(l) {}
+
+ pair solo(Int) { return pair(0,0); }
+ pair start(Int j) { return l[j+1].z - l[j].z; }
+ pair mid(Int j) { return l[j+1].z - l[j].z; }
+ pair end(Int) { return pair(0,0); }
+};
+
+// Compute the distance between points, using the already computed dz. This
+// doesn't use the infomation in the knots, but the knotprop class is useful as
+// it takes care of the iteration for us.
+struct dprop : public knotprop<double> {
+ cvector<pair>& dz;
+
+ dprop(knotlist &l, cvector<pair>& dz)
+ : knotprop<double>(l), dz(dz) {}
+
+ double solo(Int j) { return length(dz[j]); }
+ double start(Int j) { return length(dz[j]); }
+ double mid(Int j) { return length(dz[j]); }
+ double end(Int j) { return length(dz[j]); }
+};
+
+// Compute the turning angles (psi) between points, using the already computed
+// dz.
+struct psiprop : public knotprop<double> {
+ cvector<pair>& dz;
+
+ psiprop(knotlist &l, cvector<pair>& dz)
+ : knotprop<double>(l), dz(dz) {}
+
+ double solo(Int) { return 0; }
+
+ // We set the starting and ending psi to zero.
+ double start(Int) { return 0; }
+ double end(Int) { return 0; }
+
+ double mid(Int j) { return niceAngle(dz[j]/dz[j-1]); }
+};
+
+struct eqnprop : public knotprop<eqn> {
+ cvector<double>& d;
+ cvector<double>& psi;
+
+ eqnprop(knotlist &l, cvector<double>& d, cvector<double>& psi)
+ : knotprop<eqn>(l), d(d), psi(psi) {}
+
+ eqn solo(Int) {
+ assert(False);
+ return eqn(0.0,1.0,0.0,0.0);
+ }
+
+ eqn start(Int j) {
+ // Defer to the specifier, as it knows the specifics.
+ return dynamic_cast<endSpec *>(l[j].out)->eqnOut(j,l,d,psi);
+ }
+
+ eqn end(Int j) {
+ return dynamic_cast<endSpec *>(l[j].in)->eqnIn(j,l,d,psi);
+ }
+
+ eqn mid(Int j) {
+ double lastAlpha = l[j-1].alpha();
+ double thisAlpha = l[j].alpha();
+ double thisBeta = l[j].beta();
+ double nextBeta = l[j+1].beta();
+
+ // Values based on the linear approximation of the curvature coming
+ // into the knot with respect to theta[j-1] and theta[j].
+ double inFactor = 1.0/(thisBeta*thisBeta*d[j-1]);
+ double A = lastAlpha*inFactor;
+ double B = (3.0 - lastAlpha)*inFactor;
+
+ // Values based on the linear approximation of the curvature going out of
+ // the knot with respect to theta[j] and theta[j+1].
+ double outFactor = 1.0/(thisAlpha*thisAlpha*d[j]);
+ double C = (3.0 - nextBeta)*outFactor;
+ double D = nextBeta*outFactor;
+
+ return eqn(A,B+C,D,-B*psi[j]-D*psi[j+1]);
+ }
+};
+
+// If the system of equations is homogeneous (ie. we are solving for x in
+// Ax=0), there is no need to solve for theta; we can just use zeros for the
+// thetas. In fact, our general solving method may not work in this case.
+// A common example of this is
+//
+// a{curl 1}..{curl 1}b
+//
+// which arises when solving a one-length path a..b or in a larger path a
+// section a--b.
+bool homogeneous(cvector<eqn>& e)
+{
+ for(cvector<eqn>::iterator p=e.begin(); p!=e.end(); ++p)
+ if (p->aug != 0)
+ return false;
+ return true;
+}
+
+// Checks whether the equation being solved will be solved as a straight
+// path from the first point to the second.
+bool straightSection(cvector<eqn>& e)
+{
+ return e.size()==2 && e.front().aug==0 && e.back().aug==0;
+}
+
+struct weqn : public eqn {
+ double w;
+ weqn(double pre, double piv, double post, double aug, double w=0)
+ : eqn(pre,piv,post,aug), w(w) {}
+
+ friend ostream& operator<< (ostream& out, const weqn we)
+ {
+ return out << (eqn &)we << " + " << we.w << " * theta[0]";
+ }
+};
+
+weqn scale(weqn q) {
+ assert(q.pre == 0 && q.piv != 0);
+ return weqn(0,1,q.post/q.piv,q.aug/q.piv,q.w/q.piv);
+}
+
+/* Recalculate the equations in the form:
+ * theta[j] + post * theta[j+1] = aug + w * theta[0]
+ *
+ * Used as the first step in solve cyclic equations.
+ */
+cvector<weqn> recalc(cvector<eqn>& e)
+{
+ Int n=(Int) e.size();
+ cvector<weqn> we;
+ weqn lasteqn(0,1,0,0,1);
+ we.push_back(lasteqn); // As a placeholder.
+ for (Int j=1; j < n; j++) {
+ // Subtract a factor of the last equation so that the first entry is
+ // zero, then procede to scale it.
+ eqn& q=e[j];
+ lasteqn=scale(weqn(0,q.piv-q.pre*lasteqn.post,q.post,
+ q.aug-q.pre*lasteqn.aug,-q.pre*lasteqn.w));
+ we.push_back(lasteqn);
+ }
+ // To keep all of the infomation enocoded in the linear equations, we need
+ // to augment the computation to replace our trivial start weqn with a
+ // real one. To do this, we take one more step in the iteration and
+ // compute the weqn for j=n, since n=0 (mod n).
+ {
+ eqn& q=e[0];
+ we.front()=scale(weqn(0,q.piv-q.pre*lasteqn.post,q.post,
+ q.aug-q.pre*lasteqn.aug,-q.pre*lasteqn.w));
+ }
+ return we;
+}
+
+double solveForTheta0(cvector<weqn>& we)
+{
+ // Solve for theta[0]=theta[n].
+ // How we do this is essentially to write out the first equation as:
+ //
+ // theta[n] = aug[0] + w[0]*theta[0] - post[0]*theta[1]
+ //
+ // and then use the next equation to substitute in for theta[1]:
+ //
+ // theta[1] = aug[1] + w[1]*theta[0] - post[1]*theta[2]
+ //
+ // and so on until we have an equation just in terms of theta[0] and
+ // theta[n] (which are the same theta).
+ //
+ // The loop invariant maintained is that after j iterations, we have
+ // theta[n]= a + b*theta[0] + c*theta[j]
+ Int n=(Int) we.size();
+ double a=0,b=0,c=1;
+ for (Int j=0;j<n;++j) {
+ weqn& q=we[j];
+ a+=c*q.aug;
+ b+=c*q.w;
+ c=-c*q.post;
+ }
+
+ // After the iteration we have
+ //
+ // theta[n] = a + b*theta[0] + c*theta[n]
+ //
+ // where theta[n]=theta[0], so
+ return a/(1.0-(b+c));
+}
+
+cvector<double> backsubCyclic(cvector<weqn>& we, double theta0)
+{
+ Int n=(Int) we.size();
+ cvector<double> thetas;
+ double lastTheta=theta0;
+ for (Int j=1;j<=n;++j)
+ {
+ weqn& q=we[n-j];
+ assert(q.pre == 0 && q.piv == 1);
+ double theta=-q.post*lastTheta+q.aug+q.w*theta0;
+ thetas.push_back(theta);
+ lastTheta=theta;
+ }
+ reverse(thetas.begin(),thetas.end());
+ return thetas;
+}
+
+// For the non-cyclic equations, do row operation to put the matrix into
+// reduced echelon form, ie. calculates equivalent equations but with pre=0 and
+// piv=1 for each eqn.
+struct ref : public knotprop<eqn> {
+ cvector<eqn>& e;
+ eqn lasteqn;
+
+ ref(knotlist& l, cvector<eqn>& e)
+ : knotprop<eqn>(l), e(e), lasteqn(0,1,0,0) {}
+
+ // Scale the equation so that the pivot (diagonal) entry is one, and save
+ // the new equation as lasteqn.
+ eqn scale(eqn q) {
+ assert(q.pre == 0 && q.piv != 0);
+ return lasteqn = eqn(0,1,q.post/q.piv,q.aug/q.piv);
+ }
+
+ eqn start(Int j) {
+ return scale(e[j]);
+ }
+ eqn mid(Int j) {
+ // Subtract a factor of the last equation so that the first entry is
+ // zero, then procede to scale it.
+ eqn& q=e[j];
+ return scale(eqn(0,q.piv-q.pre*lasteqn.post,q.post,
+ q.aug-q.pre*lasteqn.aug));
+ }
+ // The end case is the same as the middle case.
+};
+
+// Once the matrix is in reduced echelon form, we can solve for the values by
+// back-substitution. This algorithm works from the bottom-up, so backCompute
+// must be used to get the answer.
+struct backsub : public knotprop<double> {
+ cvector<eqn>& e;
+ double lastTheta;
+
+ backsub(knotlist& l, cvector<eqn>& e)
+ : knotprop<double>(l), e(e) {}
+
+ double end(Int j) {
+ eqn& q=e[j];
+ assert(q.pre == 0 && q.piv == 1 && q.post == 0);
+ double theta=q.aug;
+ lastTheta=theta;
+ return theta;
+ }
+
+ double mid(Int j) {
+ eqn& q=e[j];
+ assert(q.pre == 0 && q.piv == 1);
+ double theta=-q.post*lastTheta+q.aug;
+ lastTheta=theta;
+ return theta;
+ }
+
+ // start is the same as mid.
+};
+
+// Once the equations have been determined, solve for the thetas.
+cvector<double> solveThetas(knotlist& l, cvector<eqn>& e)
+{
+ if (homogeneous(e))
+ // We are solving Ax=0, so a solution is zero for every theta.
+ return cvector<double>(e.size(),0);
+ else if (l.cyclic()) {
+ // The knotprop template is unusually unhelpful in this case, so I
+ // won't use it here. The algorithm breaks into three passes on the
+ // object. The old Asymptote code used a two-pass method, but I
+ // implemented this to stay closer to the MetaPost source code.
+ // This might be something to look at for optimization.
+ cvector<weqn> we=recalc(e);
+ INFO(we);
+ double theta0=solveForTheta0(we);
+ return backsubCyclic(we, theta0);
+ }
+ else { /* Non-cyclic case. */
+ /* First do row operations to get it into reduced echelon form. */
+ cvector<eqn> el=ref(l,e).compute();
+
+ /* Then, do back substitution. */
+ return backsub(l,el).backCompute();
+ }
+}
+
+// Once thetas have been solved, determine the first control point of every
+// join.
+struct postcontrolprop : public knotprop<pair> {
+ cvector<pair>& dz;
+ cvector<double>& psi;
+ cvector<double>& theta;
+
+ postcontrolprop(knotlist& l, cvector<pair>& dz,
+ cvector<double>& psi, cvector<double>& theta)
+ : knotprop<pair>(l), dz(dz), psi(psi), theta(theta) {}
+
+ double phi(Int j) {
+ /* The third angle: psi + theta + phi = 0 */
+ return -psi[j] - theta[j];
+ }
+
+ double vel(Int j) {
+ /* Use the standard velocity function. */
+ return velocity(theta[j],phi(j+1),l[j].tout);
+ }
+
+ // start is the same as mid.
+
+ pair mid(Int j) {
+ // Put a control point at the relative distance determined by the velocity,
+ // and at an angle determined by theta.
+ return l[j].z + vel(j)*expi(theta[j])*dz[j];
+ }
+
+ // The end postcontrol is the same as the last knot.
+ pair end(Int j) {
+ return l[j].z;
+ }
+};
+
+// Determine the first control point of every join.
+struct precontrolprop : public knotprop<pair> {
+ cvector<pair>& dz;
+ cvector<double>& psi;
+ cvector<double>& theta;
+
+ precontrolprop(knotlist& l, cvector<pair>& dz,
+ cvector<double>& psi, cvector<double>& theta)
+ : knotprop<pair>(l), dz(dz), psi(psi), theta(theta) {}
+
+ double phi(Int j) {
+ return -psi[j] - theta[j];
+ }
+
+ double vel(Int j) {
+ return velocity(phi(j),theta[j-1],l[j].tin);
+ }
+
+ // The start precontrol is the same as the first knot.
+ pair start(Int j) {
+ return l[j].z;
+ }
+ pair mid(Int j) {
+ return l[j].z - vel(j)*expi(-phi(j))*dz[j-1];
+ }
+
+ // end is the same as mid.
+};
+
+// Puts solved controls into a protopath starting at the given index.
+// By convention, the first knot is not coded, as it is assumed to be coded by
+// the previous section (or it is the first breakpoint and encoded as a special
+// case).
+struct encodeControls : public knoteffect {
+ protopath& p;
+ Int k;
+ cvector<pair>& pre;
+ cvector<pair>& post;
+
+ encodeControls(protopath& p, Int k,
+ cvector<pair>& pre, knotlist& l, cvector<pair>& post)
+ : knoteffect(l), p(p), k(k), pre(pre), post(post) {}
+
+ void encodePre(Int j) {
+ p.pre(k+j)=pre[j];
+ }
+ void encodePoint(Int j) {
+ p.point(k+j)=l[j].z;
+ }
+ void encodePost(Int j) {
+ p.post(k+j)=post[j];
+ }
+
+ void solo(Int) {
+#if 0
+ encodePoint(j);
+#endif
+ }
+ void start(Int j) {
+#if 0
+ encodePoint(j);
+#endif
+ encodePost(j);
+ }
+ void mid(Int j) {
+ encodePre(j);
+ encodePoint(j);
+ encodePost(j);
+ }
+ void end(Int j) {
+ encodePre(j);
+ encodePoint(j);
+ }
+};
+
+void encodeStraight(protopath& p, Int k, knotlist& l)
+{
+ pair a=l.front().z;
+ double at=l.front().tout.val;
+ pair b=l.back().z;
+ double bt=l.back().tin.val;
+ pair step=(b-a)/3.0;
+
+ if (at==1.0 && bt==1.0) {
+ p.straight(k)=true;
+ p.post(k)=a+step;
+ p.pre(k+1)=b-step;
+ p.point(k+1)=b;
+ }
+ else {
+ p.post(k)=a+step/at;
+ p.pre(k+1)=b-step/bt;
+ p.point(k+1)=b;
+ }
+}
+
+void solveSection(protopath& p, Int k, knotlist& l)
+{
+ if (l.length()>0) {
+ info(cerr, "solving section", l);
+
+ // Calculate useful properties.
+ cvector<pair> dz = dzprop(l) .compute();
+ cvector<double> d = dprop(l,dz).compute();
+ cvector<double> psi = psiprop(l,dz).compute();
+
+ INFO(dz); INFO(d); INFO(psi);
+
+ // Build and solve the linear equations for theta.
+ cvector<eqn> e = eqnprop(l,d,psi).compute();
+ INFO(e);
+
+ if (straightSection(e))
+ // Handle straight section as special case.
+ encodeStraight(p,k,l);
+ else {
+ cvector<double> theta = solveThetas(l,e);
+ INFO(theta);
+
+ // Calculate the control points.
+ cvector<pair> post = postcontrolprop(l,dz,psi,theta).compute();
+ cvector<pair> pre = precontrolprop(l,dz,psi,theta).compute();
+
+ // Encode the results into the protopath.
+ encodeControls(p,k,pre,l,post).exec();
+ }
+ }
+}
+
+// Find the first breakpoint in the knotlist, ie. where we can start solving a
+// non-cyclic section. If the knotlist is fully cyclic, then this returns
+// NOBREAK.
+// This must be called with a knot that has all of its implicit specifiers in
+// place.
+const Int NOBREAK=-1;
+Int firstBreakpoint(knotlist& l)
+{
+ for (Int j=0;j<l.size();++j)
+ if (!l[j].out->open())
+ return j;
+ return NOBREAK;
+}
+
+// Once a breakpoint, a, is found, find where the next breakpoint after it is.
+// This must be called with a knot that has all of its implicit specifiers in
+// place, so that breakpoint can be identified by either an in or out specifier
+// that is not open.
+Int nextBreakpoint(knotlist& l, Int a)
+{
+ // This is guaranteed to terminate if a is the index of a breakpoint. If the
+ // path is non-cyclic it will stop at or before the last knot which must be a
+ // breakpoint. If the path is cyclic, it will stop at or before looping back
+ // around to a which is a breakpoint.
+ Int j=a+1;
+ while (l[j].in->open())
+ ++j;
+ return j;
+}
+
+// Write out the controls for section of the form
+// a.. control b and c ..d
+void writeControls(protopath& p, Int a, knotlist& l)
+{
+ // By convention, the first point will already be encoded.
+ p.straight(a)=dynamic_cast<controlSpec *>(l[a].out)->straight;
+ p.post(a)=dynamic_cast<controlSpec *>(l[a].out)->cz;
+ p.pre(a+1)=dynamic_cast<controlSpec *>(l[a+1].in)->cz;
+ p.point(a+1)=l[a+1].z;
+}
+
+// Solves a path that has all of its specifiers laid out explicitly.
+path solveSpecified(knotlist& l)
+{
+ protopath p(l.size(),l.cyclic());
+
+ Int first=firstBreakpoint(l);
+ if (first==NOBREAK)
+ /* We are solving a fully cyclic path, so do it in one swoop. */
+ solveSection(p,0,l);
+ else {
+ // Encode the first point.
+ p.point(first)=l[first].z;
+
+ // If the path is cyclic, we should stop where we started (modulo the
+ // length of the path); otherwise, just stop at the end.
+ Int last=l.cyclic() ? first+l.length()
+ : l.length();
+ Int a=first;
+ while (a!=last) {
+ if (l[a].out->controlled()) {
+ assert(l[a+1].in->controlled());
+
+ // Controls are already picked, just write them out.
+ writeControls(p,a,l);
+ ++a;
+ }
+ else {
+ // Find the section a to b and solve it, putting the result (starting
+ // from index a into our protopath.
+ Int b=nextBreakpoint(l,a);
+ subknotlist section(l,a,b);
+ solveSection(p,a,section);
+ a=b;
+ }
+ }
+
+ // For a non-cyclic path, the end control points need to be set.
+ p.controlEnds();
+ }
+
+ return p.fix();
+}
+
+/* If a knot is open on one side and restricted on the other, this replaces the
+ * open side with a restriction determined by the restriction on the other
+ * side. After this, any knot will either have two open specs or two
+ * restrictions.
+ */
+struct partnerUp : public knoteffect {
+ partnerUp(knotlist& l)
+ : knoteffect(l) {}
+
+ void mid(Int j) {
+ knot& k=l[j];
+ if (k.in->open() && !k.out->open())
+ k.in=k.out->inPartner(k.z);
+ else if (!k.in->open() && k.out->open())
+ k.out=k.in->outPartner(k.z);
+ }
+};
+
+/* Ensures a non-cyclic path has direction specifiers at the ends, adding curls
+ * if there are none.
+ */
+void curlEnds(knotlist& l)
+{
+ static curlSpec endSpec;
+
+ if (!l.cyclic()) {
+ if (l.front().in->open())
+ l.front().in=&endSpec;
+ if (l.back().out->open())
+ l.back().out=&endSpec;
+ }
+}
+
+/* If a point occurs twice in a row in a knotlist, write in controls
+ * between the two knots at that point (unless it already has controls).
+ */
+struct controlDuplicates : public knoteffect {
+ controlDuplicates(knotlist& l)
+ : knoteffect(l) {}
+
+ void solo(Int) { /* One point ==> no duplicates */ }
+ // start is the same as mid.
+ void mid(Int j) {
+ knot &k1=l[j];
+ knot &k2=l[j+1];
+ if (!k1.out->controlled() && k1.z==k2.z) {
+ k1.out=k2.in=new controlSpec(k1.z,true);
+ }
+ }
+ void end(Int) { /* No next point to compare with. */ }
+};
+
+path solve(knotlist& l)
+{
+ if (l.empty())
+ return path();
+ else {
+ info(cerr, "input knotlist", l);
+ curlEnds(l);
+ controlDuplicates(l).exec();
+ partnerUp(l).exec();
+ info(cerr, "specified knotlist", l);
+ return solveSpecified(l);
+ }
+}
+
+// Code for Testing
+#if 0
+path solveSimple(cvector<pair>& z)
+{
+ // The two specifiers used: an open spec and a curl spec for the ends.
+ spec open;
+
+// curlSpec curl;
+// curlSpec curly(2.0);
+// dirSpec E(0);
+// dirSpec N(PI/2.0);
+
+ controlSpec here(pair(150,150));
+
+ // Encode the knots as open in the knotlist.
+ cvector<knot> nodes;
+ for (cvector<pair>::iterator p=z.begin(); p!=z.end(); ++p) {
+ knot k;
+ k.z=*p;
+ k.in=k.out=&open;
+
+ nodes.push_back(k);
+ }
+
+ // Substitute in a curl spec for the ends.
+ //nodes.front().out=nodes.back().in=&curl;
+
+ // Test direction specifiers.
+ //nodes.front().tout=2;
+ //nodes.front().out=nodes.back().in=&curly;
+
+ //nodes[0].out=nodes[0].in=&E;
+ nodes[1].out=nodes[2].in=&here;
+
+ simpleknotlist l(nodes,false);
+ return solve(l);
+}
+#endif
+
+} // namespace camp
diff --git a/graphics/asymptote/knot.h b/graphics/asymptote/knot.h
new file mode 100644
index 0000000000..aaf49a4c03
--- /dev/null
+++ b/graphics/asymptote/knot.h
@@ -0,0 +1,533 @@
+/*****
+ * knot.h
+ * Andy Hammerlindl 200/02/10
+ *
+ * Describes a knot, a point and its neighbouring specifiers, used as an
+ * intermediate structure in solving paths.
+ *****/
+
+#ifndef KNOT_H
+#define KNOT_H
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#include "mod.h"
+#include "pair.h"
+#include "path.h"
+
+namespace camp {
+
+using mem::vector;
+
+// The choice of branch cuts of atan2 disguishes between y=+0.0 and y=-0.0 in
+// the case where x<0. This can lead to strange looking paths being
+// calculated from guides of the form a..b..cycle. To avoid these degenerate
+// cases, the niceAngle routine moves the branch cut so that the sign of a
+// zero won't matter.
+double niceAngle(pair z);
+
+// A cyclic vector: ie. a vector where the index is taken mod the size of the
+// vector.
+template <typename T>
+class cvector : public vector<T> {
+public:
+ cvector() {}
+ cvector(size_t n) : vector<T>(n) {}
+ cvector(size_t n, const T& t) : vector<T>(n,t) {}
+ cvector(const vector<T>& v) : vector<T>(v) {}
+
+ T& operator[](Int j) {
+ return vector<T>::operator[](imod(j,(Int) this->size()));
+ }
+ const T& operator[](Int j) const {
+ return vector<T>::operator[](imod(j,(Int) this->size()));
+ }
+};
+
+// Forward declaration.
+class knotlist;
+
+/* A linear equation (one of a set of equations to solve for direction through
+ knots in a path). The i-th equation is:
+
+ pre*theta[i-1] + piv*theta[i] + post*theta[i+1] = aug
+
+ where indices are taken mod n.
+*/
+struct eqn {
+ double pre,piv,post,aug;
+ eqn(double pre, double piv, double post, double aug)
+ : pre(pre), piv(piv), post(post), aug(aug) {}
+
+ friend ostream& operator<< (ostream& out, const eqn& e)
+ {
+ return out << e.pre << " * pre + "
+ << e.piv << " * piv + "
+ << e.post << " * post = "
+ << e.aug;
+ }
+};
+
+
+// A direction specifier, telling how the path behaves coming in or out of a
+// point. The base class represents the "open" specifier.
+class spec : public gc {
+public:
+ virtual ~spec() {}
+
+ // If the knot is open, it gives no restriction on the behavior of the
+ // path.
+ virtual bool open() { return true; }
+ virtual bool controlled() { return false; }
+ virtual pair control() {return pair(0.0,0.0);}
+ virtual double curl() { return -1.0; }
+ virtual pair dir() { return pair(0.0,0.0); }
+
+ // When a knot has a restriction on one side but is open on the other, the
+ // restriction implies a restriction on the other side. This is the partner
+ // restriction defined here, where the pair argument is for the location of
+ // the knot.
+ virtual spec *outPartner(pair) { return this; }
+ virtual spec *inPartner(pair) { return this; }
+
+ virtual void print(ostream&) const {}
+};
+
+inline ostream& operator<< (ostream& out, spec& s)
+{
+ s.print(out);
+ return out;
+}
+
+
+// Specifier used at an endpoint.
+class endSpec : public spec {
+public:
+ bool open() { return false; }
+
+ // Returns an equation used to solve for the thetas along the knot. These are
+ // called by eqnprop in the non-cyclic case for the first and last equations.
+ virtual eqn eqnOut(Int j, knotlist& l,
+ cvector<double>& d, cvector<double>& psi) = 0;
+ virtual eqn eqnIn (Int j, knotlist& l,
+ cvector<double>& d, cvector<double>& psi) = 0;
+};
+
+// A specifier with a given direction (in radians).
+class dirSpec : public endSpec {
+ double given;
+public:
+ // Direction should be given in the range [-PI,PI]
+ dirSpec(double given)
+ : given(given) {}
+ dirSpec(pair z)
+ : given(niceAngle(z)) {}
+
+ pair dir() { return expi(given); }
+
+ eqn eqnOut(Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+ eqn eqnIn (Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+
+ void print(ostream& out) const {
+ out << "{dir(" << degrees(given) << ")}";
+ }
+};
+
+// A curl specifier. The curvature at the end knot should be gamma times the
+// curvature at the neighbouring knot.
+class curlSpec : public endSpec {
+ double gamma;
+public:
+ // Gamma should be non-negative.
+ curlSpec(double gamma=1.0)
+ : gamma(gamma) {
+ if(gamma < 0)
+ reportError("curl cannot be less than 0");
+ }
+
+ double curl() { return gamma; }
+
+ eqn eqnOut(Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+ eqn eqnIn (Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+
+ void print(ostream& out) const {
+ out << "{curl " << gamma << "}";
+ }
+};
+
+
+// A specifier with a control point. All information for this portion of the
+// curve has been determined.
+class controlSpec : public spec {
+public:
+ pair cz;
+ bool straight;
+
+ controlSpec(pair cz, bool straight=false)
+ : cz(cz), straight(straight) {}
+
+ bool open() { return false; }
+ bool controlled() { return true; }
+ pair control() { return cz; }
+
+ // The partner spec will be a dirSpec in the same direction the specifier
+ // takes the path, unless the velocity is zero, then it uses a curl
+ // specifier.
+ spec *outPartner(pair);
+ spec *inPartner(pair);
+
+ void print(ostream& out) const {
+ // NOTE: This format cannot be read back in.
+ out << "{control " << cz << "}";
+ }
+};
+
+
+// The tension information for one side of a knot.
+struct tension {
+ double val;
+ bool atleast;
+
+ tension(double val=1.0, bool atleast=false)
+ : val(val), atleast(atleast) {
+ if(val < 0.75)
+ reportError("tension cannot be less than 3/4");
+ }
+};
+
+inline
+ostream& operator<<(ostream& out, tension t)
+{
+ return out << "tension" << (t.atleast ? " atleast " : " ") << t.val;
+}
+
+// A knot, a point with specifiers to double the path coming in and going out
+// of the knot.
+struct knot {
+ pair z;
+ spec *in;
+ spec *out;
+ tension tin, tout;
+
+ knot() {}
+ knot(pair z, spec *in, spec *out,
+ tension tin=tension(), tension tout=tension())
+ : z(z), in(in), out(out), tin(tin), tout(tout) {}
+
+ double alpha() { return 1.0/tout.val; }
+ double beta() { return 1.0/tin.val; }
+};
+
+ostream& operator<<(ostream& out, const knot& k);
+
+// Abstract base class for a section of a guide.
+class knotlist {
+public:
+ virtual ~knotlist() {}
+
+ virtual Int length() = 0;
+ virtual bool cyclic() = 0;
+
+ // Returns the number of knots.
+ Int size() {
+ return cyclic() ? length() : length() + 1;
+ }
+ bool empty() {
+ return size()==0;
+ }
+
+ virtual knot& cell(Int) = 0;
+ virtual knot& operator[] (Int i) {
+#if 0
+ assert(cyclic() || (0 <= i && i <= length())); // Bounds check.
+#endif
+ return cell(i);
+ }
+ knot& front() {
+ return (*this)[0];
+ }
+ knot& back() {
+ return (*this)[length()];
+ }
+};
+
+
+// Defines a knotlist as a piece of another knotlist.
+class subknotlist : public knotlist {
+ knotlist& l;
+ Int a,b;
+public:
+ subknotlist(knotlist& l, Int a, Int b)
+ : l(l), a(a), b(b) {}
+
+ Int length() { return b-a; }
+ bool cyclic() { return false; }
+ knot& cell(Int i) { return l[a+i]; }
+};
+
+struct simpleknotlist : public knotlist {
+ cvector<knot> nodes;
+ bool cycles;
+
+ simpleknotlist(cvector<knot> nodes, bool cycles=false)
+ : nodes(nodes), cycles(cycles) {}
+
+ Int length() { return cycles ? (Int) nodes.size() : (Int) nodes.size() - 1; }
+ bool cyclic() { return cycles; }
+ knot& cell(Int j) { return nodes[j]; }
+};
+
+// A protopath is a path being made.
+struct protopath {
+ bool cycles;
+ Int n;
+ mem::vector<solvedKnot> nodes;
+
+ protopath(Int n, bool cycles)
+ : cycles(cycles), n(n), nodes(n) {}
+
+ solvedKnot& operator[](Int j) {
+ return nodes[imod(j,n)];
+ }
+
+ bool& straight(Int j) {
+ return (*this)[j].straight;
+ }
+ pair& pre(Int j) {
+ return (*this)[j].pre;
+ }
+ pair& point(Int j) {
+ return (*this)[j].point;
+ }
+ pair& post(Int j) {
+ return (*this)[j].post;
+ }
+
+ void controlEnds() {
+ if (!cycles) {
+ solvedKnot& start=(*this)[0];
+ solvedKnot& end=(*this)[n-1];
+
+ start.pre=start.point;
+ end.post=end.point;
+ }
+ }
+ // Once all the controls are set, return the final (constant) path.
+ path fix() {
+ return path(nodes,n,cycles);
+ }
+};
+
+
+// Represents properties that can be computed along a knotlist.
+// Examples include distances (d), turning angles (psi), and the linear
+// equations used to solve for the thetas.
+template <typename T>
+class knotprop {
+protected:
+ knotlist& l;
+
+ // Calculate the property for the usual case in the iteration (and for a
+ // cyclic knot, the only case), at the index given.
+ virtual T mid(Int) = 0;
+
+ // The special cases, these default to the usual case: mid.
+ virtual T solo(Int j) // Calculates the property for a list of length 0.
+ {
+ return mid(j);
+ }
+ virtual T start(Int j) // Calculates it at the start of the list.
+ {
+ return mid(j);
+ }
+ virtual T end(Int j) // Calculate it at the end.
+ {
+ return mid(j);
+ }
+
+ virtual cvector<T> linearCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ if (n==0)
+ v.push_back(solo(0));
+ else {
+ v.push_back(start(0));
+ for (Int j=1; j<n; ++j)
+ v.push_back(mid(j));
+ v.push_back(end(n));
+ }
+ return v;
+ }
+
+ virtual cvector<T> cyclicCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ for (Int j=0; j<n; ++j)
+ v.push_back(mid(j));
+ return v;
+ }
+
+ virtual cvector<T> linearBackCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ if (n==0)
+ v.push_back(solo(0));
+ else {
+ v.push_back(end(n));
+ for (Int j=1; j<n; ++j)
+ v.push_back(mid(n-j));
+ v.push_back(start(0));
+ }
+ return v;
+ }
+
+ virtual cvector<T> cyclicBackCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ for (Int j=1; j<=n; ++j)
+ v.push_back(mid(n-j));
+ return v;
+ }
+
+public:
+ virtual ~knotprop() {}
+
+ virtual cvector<T> compute() {
+ return l.cyclic() ? cyclicCompute() : linearCompute();
+ }
+
+ // Compute the values in the opposite order. This is needed for instance if
+ // the i-th calculation needed a result computed in the i+1-th, such as in the
+ // back substitution for solving thetas.
+ virtual cvector<T> backCompute() {
+ cvector<T> v=l.cyclic() ? cyclicBackCompute() : linearBackCompute();
+
+ // Even though they are computed in the backwards order, return them in the
+ // standard order.
+ reverse(v.begin(),v.end());
+ return v;
+ }
+
+ knotprop(knotlist& l)
+ : l(l) {}
+};
+
+// A knot transforms, it takes in one knotlist and transforms it knot for knot
+// into a new one.
+class knottrans : public knotprop<knot> {
+protected:
+ virtual knot mid(Int j) {
+ /* By default, just copy the knot. */
+ return l[j];
+ }
+
+public:
+ virtual ~knottrans() {}
+
+ knottrans(knotlist& l)
+ : knotprop<knot>(l) {}
+
+ virtual simpleknotlist trans() {
+ return simpleknotlist(compute(),l.cyclic());
+ }
+};
+
+// Like a knotprop, but it doesn't compute a vector of values for the knot. It
+// iterates over the knotlist calling method for side-effect. For instance,
+// this is used to plug control points into protopaths.
+class knoteffect {
+protected:
+ knotlist& l;
+
+ virtual void mid(Int) = 0;
+
+ // The special cases, these default to the usual case: mid.
+ virtual void solo(Int j) {
+ mid(j);
+ }
+ virtual void start(Int j) {
+ mid(j);
+ }
+ virtual void end(Int j) {
+ mid(j);
+ }
+
+ virtual void linearExec()
+ {
+ Int n=l.length();
+ if (n==0)
+ solo(0);
+ else {
+ start(0);
+ for (Int j=1; j<n; ++j)
+ mid(j);
+ end(n);
+ }
+ }
+
+ virtual void cyclicExec()
+ {
+ Int n=l.length();
+ for (Int j=0; j<n; ++j)
+ mid(j);
+ }
+
+ virtual void linearBackExec()
+ {
+ Int n=l.length();
+ if (n==0)
+ solo(0);
+ else {
+ end(n);
+ for (Int j=1; j<n; ++j)
+ mid(n-j);
+ start(0);
+ }
+ }
+
+ virtual void cyclicBackExec()
+ {
+ Int n=l.length();
+ for (Int j=1; j<=n; ++j)
+ mid(n-j);
+ }
+
+public:
+ virtual ~knoteffect() {}
+
+ virtual void exec() {
+ if (l.cyclic())
+ cyclicExec();
+ else
+ linearExec();
+ }
+
+ virtual void backCompute() {
+ if (l.cyclic())
+ cyclicBackExec();
+ else
+ linearBackExec();
+ }
+
+ knoteffect(knotlist& l)
+ : l(l) {}
+};
+
+path solve(knotlist& l);
+
+path solveSimple(cvector<pair>& z);
+
+double velocity(double theta, double phi, tension t);
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::eqn);
+GC_DECLARE_PTRFREE(camp::tension);
+
+#endif // KNOT_H
diff --git a/graphics/asymptote/lex.yy.cc b/graphics/asymptote/lex.yy.cc
new file mode 100644
index 0000000000..218ccfb8b4
--- /dev/null
+++ b/graphics/asymptote/lex.yy.cc
@@ -0,0 +1,3265 @@
+#line 2 "lex.yy.cc"
+
+#line 4 "lex.yy.cc"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+
+/* %endif */
+/* %endif */
+/* %ok-for-header */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 1
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* %if-c++-only */
+/* %endif */
+
+/* %if-c-only */
+
+/* %endif */
+
+/* %if-c-only */
+
+/* %endif */
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+/* %if-c-only */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+/* %endif */
+
+/* %if-tables-serialization */
+/* %endif */
+/* end standard C headers. */
+
+/* %if-c-or-c++ */
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* %not-for-header */
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+/* %if-not-reentrant */
+extern int yyleng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+extern FILE *yyin, *yyout;
+/* %endif */
+/* %endif */
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yy_size_t yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+/* %if-c-only */
+ FILE *yy_input_file;
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+/* %if-not-reentrant */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* %if-c-only Standard (non-C++) definition */
+
+/* %if-not-reentrant */
+/* %not-for-header */
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = NULL;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+/* %ok-for-header */
+
+/* %endif */
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+/* %endif */
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
+
+#define FLEX_DEBUG
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = NULL, *yyout = NULL;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
+#define yytext_ptr yytext
+
+/* %% [1.5] DFA */
+
+/* %if-c-only Standard (non-C++) definition */
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yynoreturn yy_fatal_error (yyconst char* msg );
+
+/* %endif */
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
+ yyleng = (int) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
+ (yy_c_buf_p) = yy_cp;
+
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
+#define YY_NUM_RULES 124
+#define YY_END_OF_BUFFER 125
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[337] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 125, 123, 28, 29, 29, 60, 121, 46,
+ 69, 47, 67, 122, 34, 35, 44, 42, 31, 43,
+ 40, 45, 105, 32, 33, 54, 51, 56, 50, 69,
+ 119, 36, 123, 37, 48, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 38, 68, 39, 69, 4, 3, 3, 4, 4,
+ 10, 7, 7, 6, 10, 27, 13, 13, 12, 27,
+ 124, 118, 113, 114, 113, 116, 116, 116, 116, 116,
+ 116, 118, 118, 116, 118, 116, 116, 117, 118, 116,
+
+ 116, 29, 53, 74, 69, 75, 58, 49, 72, 63,
+ 70, 65, 71, 64, 106, 120, 30, 73, 106, 105,
+ 0, 62, 55, 52, 57, 119, 29, 76, 61, 119,
+ 119, 119, 119, 119, 119, 119, 86, 119, 119, 119,
+ 119, 119, 82, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 59,
+ 3, 2, 1, 7, 0, 0, 5, 0, 7, 9,
+ 8, 13, 0, 0, 11, 0, 13, 14, 22, 22,
+ 15, 16, 17, 18, 19, 20, 21, 0, 114, 116,
+ 116, 115, 116, 117, 114, 66, 41, 0, 30, 0,
+
+ 106, 0, 0, 106, 119, 77, 119, 119, 119, 119,
+ 119, 119, 119, 119, 85, 119, 119, 119, 92, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 0, 0, 23, 23, 25, 0,
+ 0, 106, 119, 119, 119, 119, 81, 119, 83, 119,
+ 119, 96, 119, 119, 119, 109, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 103, 107, 119, 119, 119,
+ 24, 26, 0, 106, 119, 119, 88, 119, 119, 110,
+ 119, 108, 119, 119, 119, 119, 119, 119, 98, 119,
+ 119, 119, 119, 119, 119, 119, 84, 93, 119, 119,
+
+ 119, 119, 94, 119, 119, 119, 119, 100, 119, 87,
+ 99, 90, 119, 119, 119, 80, 119, 119, 119, 97,
+ 119, 119, 101, 119, 79, 91, 95, 89, 78, 104,
+ 111, 112, 119, 119, 102, 0
+ } ;
+
+static yyconst YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 20, 20,
+ 20, 21, 21, 21, 21, 22, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 30, 30, 30, 30, 30,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 33, 34, 35, 31, 1, 36, 37, 38, 39,
+
+ 40, 41, 31, 42, 43, 31, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 31, 59, 60, 61, 62, 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, 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, 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, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst YY_CHAR yy_meta[63] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 3, 3, 1, 1, 1, 1, 1, 1, 1, 3,
+ 3, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 1, 1,
+ 1, 1
+ } ;
+
+static yyconst flex_uint16_t yy_base[344] =
+ { 0,
+ 0, 0, 60, 62, 64, 69, 74, 79, 0, 0,
+ 112, 0, 541, 542, 542, 542, 537, 513, 542, 512,
+ 529, 510, 525, 542, 542, 542, 66, 69, 542, 70,
+ 83, 72, 157, 511, 542, 83, 507, 62, 542, 503,
+ 0, 542, 90, 542, 150, 142, 480, 133, 482, 54,
+ 148, 147, 146, 480, 147, 474, 487, 473, 162, 478,
+ 482, 542, 463, 542, 542, 542, 542, 519, 502, 506,
+ 542, 542, 516, 203, 212, 542, 542, 515, 219, 250,
+ 542, 542, 542, 542, 514, 490, 542, 507, 500, 498,
+ 495, 493, 487, 185, 483, 156, 479, 0, 223, 472,
+
+ 542, 542, 542, 542, 542, 542, 542, 542, 542, 542,
+ 542, 489, 542, 211, 217, 542, 0, 542, 222, 228,
+ 243, 542, 542, 542, 542, 0, 502, 542, 542, 466,
+ 464, 457, 461, 453, 448, 460, 0, 445, 447, 450,
+ 443, 445, 0, 443, 453, 434, 444, 448, 444, 449,
+ 437, 182, 215, 437, 440, 428, 432, 429, 436, 542,
+ 542, 542, 542, 542, 271, 306, 542, 276, 475, 542,
+ 542, 542, 312, 318, 542, 281, 474, 542, 268, 272,
+ 542, 542, 542, 542, 542, 542, 542, 310, 542, 542,
+ 542, 542, 459, 0, 472, 542, 278, 313, 0, 326,
+
+ 316, 337, 345, 321, 434, 0, 433, 436, 418, 425,
+ 424, 428, 422, 414, 0, 419, 416, 418, 421, 416,
+ 409, 404, 413, 404, 403, 401, 401, 399, 400, 399,
+ 410, 409, 412, 402, 366, 372, 274, 542, 364, 375,
+ 386, 367, 394, 409, 400, 204, 0, 403, 0, 399,
+ 401, 0, 389, 385, 387, 0, 401, 400, 392, 393,
+ 362, 361, 367, 366, 359, 0, 0, 361, 343, 353,
+ 542, 542, 394, 397, 339, 330, 0, 334, 331, 0,
+ 335, 0, 318, 325, 327, 308, 302, 312, 0, 306,
+ 281, 289, 272, 271, 273, 271, 0, 0, 253, 248,
+
+ 245, 238, 0, 236, 226, 221, 227, 0, 221, 0,
+ 0, 0, 194, 187, 179, 0, 179, 165, 155, 0,
+ 163, 141, 0, 137, 0, 0, 0, 0, 0, 0,
+ 0, 0, 66, 61, 0, 542, 419, 422, 425, 428,
+ 68, 66, 431
+ } ;
+
+static yyconst flex_int16_t yy_def[344] =
+ { 0,
+ 336, 1, 337, 337, 338, 338, 339, 339, 340, 340,
+ 336, 11, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 341, 336, 336, 336, 336, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 342, 336, 336,
+
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 343, 336, 336, 336,
+ 336, 336, 336, 336, 336, 341, 336, 336, 336, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 342, 336, 336, 336, 336, 343, 336,
+
+ 336, 336, 336, 336, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 336, 336, 336, 336, 336, 336,
+ 336, 336, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 336, 336, 336, 336, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
+ 341, 341, 341, 341, 341, 0, 336, 336, 336, 336,
+ 336, 336, 336
+ } ;
+
+static yyconst flex_uint16_t yy_nxt[605] =
+ { 0,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 33, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 41, 52, 41, 41, 41, 53, 54, 55, 56,
+ 57, 58, 59, 60, 41, 61, 41, 41, 62, 63,
+ 64, 65, 67, 68, 67, 68, 72, 73, 194, 74,
+ 126, 72, 73, 69, 74, 69, 77, 78, 70, 108,
+ 70, 77, 78, 110, 79, 116, 112, 125, 105, 79,
+ 117, 109, 102, 127, 111, 113, 75, 118, 138, 335,
+
+ 114, 75, 115, 115, 115, 334, 80, 105, 123, 105,
+ 139, 80, 82, 83, 84, 85, 86, 82, 87, 88,
+ 87, 87, 82, 82, 82, 89, 90, 82, 91, 92,
+ 87, 82, 82, 82, 93, 82, 94, 95, 96, 82,
+ 97, 98, 98, 82, 99, 82, 100, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 82, 87, 82, 101, 119, 128, 120, 120, 120, 130,
+ 134, 190, 191, 140, 129, 146, 135, 143, 131, 333,
+ 136, 332, 144, 145, 132, 141, 121, 149, 142, 147,
+
+ 150, 154, 331, 155, 165, 165, 166, 330, 167, 191,
+ 190, 191, 156, 167, 164, 169, 329, 170, 328, 157,
+ 173, 173, 174, 327, 175, 189, 195, 326, 197, 175,
+ 198, 198, 198, 225, 226, 168, 115, 115, 115, 200,
+ 325, 201, 201, 201, 171, 119, 278, 120, 120, 120,
+ 227, 176, 172, 177, 279, 178, 121, 203, 324, 203,
+ 178, 202, 204, 204, 204, 228, 323, 121, 322, 179,
+ 180, 321, 165, 165, 166, 320, 167, 178, 165, 166,
+ 319, 167, 178, 173, 174, 181, 182, 237, 237, 318,
+ 183, 238, 238, 271, 271, 200, 184, 198, 198, 198,
+
+ 185, 317, 186, 168, 187, 316, 188, 165, 235, 166,
+ 315, 167, 314, 173, 173, 174, 167, 175, 313, 173,
+ 236, 174, 175, 175, 312, 239, 311, 310, 175, 239,
+ 239, 239, 198, 198, 198, 201, 201, 201, 168, 239,
+ 204, 204, 204, 200, 176, 198, 198, 198, 309, 308,
+ 176, 241, 121, 241, 307, 240, 242, 242, 242, 203,
+ 306, 203, 305, 304, 204, 204, 204, 165, 165, 166,
+ 303, 167, 302, 173, 173, 174, 167, 175, 301, 272,
+ 300, 299, 175, 272, 272, 272, 242, 242, 242, 273,
+ 298, 273, 297, 272, 274, 274, 274, 296, 168, 295,
+
+ 241, 294, 241, 293, 176, 242, 242, 242, 273, 292,
+ 273, 291, 290, 274, 274, 274, 274, 274, 274, 66,
+ 66, 66, 71, 71, 71, 76, 76, 76, 81, 81,
+ 81, 199, 289, 199, 288, 287, 286, 285, 284, 283,
+ 282, 281, 280, 277, 276, 275, 270, 269, 268, 267,
+ 266, 265, 264, 263, 262, 261, 260, 259, 258, 257,
+ 256, 255, 254, 253, 252, 251, 250, 249, 248, 247,
+ 246, 245, 244, 243, 189, 190, 172, 164, 234, 233,
+ 232, 231, 230, 229, 224, 223, 222, 221, 220, 219,
+ 218, 217, 216, 215, 214, 213, 212, 211, 210, 209,
+
+ 208, 207, 206, 205, 102, 196, 190, 191, 190, 190,
+ 190, 193, 190, 192, 191, 190, 189, 172, 164, 163,
+ 162, 161, 160, 159, 158, 153, 152, 151, 148, 137,
+ 133, 105, 124, 122, 107, 106, 105, 104, 103, 102,
+ 336, 13, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+
+ 336, 336, 336, 336
+ } ;
+
+static yyconst flex_int16_t yy_chk[605] =
+ { 0,
+ 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, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 3, 4, 4, 5, 5, 342, 5,
+ 341, 6, 6, 3, 6, 4, 7, 7, 3, 27,
+ 4, 8, 8, 28, 7, 32, 30, 38, 38, 8,
+ 32, 27, 43, 43, 28, 30, 5, 32, 50, 334,
+
+ 31, 6, 31, 31, 31, 333, 7, 36, 36, 36,
+ 50, 8, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 33, 45, 33, 33, 33, 46,
+ 48, 96, 96, 51, 45, 53, 48, 52, 46, 324,
+ 48, 322, 52, 52, 46, 51, 33, 55, 51, 53,
+
+ 55, 59, 321, 59, 74, 74, 74, 319, 74, 94,
+ 94, 94, 59, 74, 75, 75, 318, 75, 317, 59,
+ 79, 79, 79, 315, 79, 99, 99, 314, 114, 79,
+ 114, 114, 114, 152, 152, 74, 115, 115, 115, 119,
+ 313, 119, 119, 119, 75, 120, 246, 120, 120, 120,
+ 153, 79, 80, 80, 246, 80, 115, 121, 309, 121,
+ 80, 119, 121, 121, 121, 153, 307, 120, 306, 80,
+ 80, 305, 165, 165, 165, 304, 165, 80, 168, 168,
+ 302, 165, 80, 176, 176, 80, 80, 179, 179, 301,
+ 80, 180, 180, 237, 237, 197, 80, 197, 197, 197,
+
+ 80, 300, 80, 165, 80, 299, 80, 166, 166, 166,
+ 296, 166, 295, 173, 173, 173, 166, 173, 294, 174,
+ 174, 174, 173, 174, 293, 188, 292, 291, 174, 188,
+ 188, 188, 198, 198, 198, 201, 201, 201, 166, 188,
+ 204, 204, 204, 200, 173, 200, 200, 200, 290, 288,
+ 174, 202, 198, 202, 287, 201, 202, 202, 202, 203,
+ 286, 203, 285, 284, 203, 203, 203, 235, 235, 235,
+ 283, 235, 281, 236, 236, 236, 235, 236, 279, 239,
+ 278, 276, 236, 239, 239, 239, 242, 242, 242, 240,
+ 275, 240, 270, 239, 240, 240, 240, 269, 235, 268,
+
+ 241, 265, 241, 264, 236, 241, 241, 241, 273, 263,
+ 273, 262, 261, 273, 273, 273, 274, 274, 274, 337,
+ 337, 337, 338, 338, 338, 339, 339, 339, 340, 340,
+ 340, 343, 260, 343, 259, 258, 257, 255, 254, 253,
+ 251, 250, 248, 245, 244, 243, 234, 233, 232, 231,
+ 230, 229, 228, 227, 226, 225, 224, 223, 222, 221,
+ 220, 219, 218, 217, 216, 214, 213, 212, 211, 210,
+ 209, 208, 207, 205, 195, 193, 177, 169, 159, 158,
+ 157, 156, 155, 154, 151, 150, 149, 148, 147, 146,
+ 145, 144, 142, 141, 140, 139, 138, 136, 135, 134,
+
+ 133, 132, 131, 130, 127, 112, 100, 97, 95, 93,
+ 92, 91, 90, 89, 88, 86, 85, 78, 73, 70,
+ 69, 68, 63, 61, 60, 58, 57, 56, 54, 49,
+ 47, 40, 37, 34, 23, 22, 21, 20, 18, 17,
+ 13, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,
+
+ 336, 336, 336, 336
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 1;
+
+static yyconst flex_int16_t yy_rule_linenum[124] =
+ { 0,
+ 212, 213, 215, 221, 225, 226, 236, 237, 238, 239,
+ 243, 244, 254, 255, 256, 257, 258, 259, 260, 261,
+ 262, 263, 268, 273, 279, 285, 293, 296, 297, 298,
+ 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
+ 309, 311, 312, 313, 314, 315, 316, 317, 318, 319,
+ 320, 321, 322, 323, 324, 325, 326, 327, 328, 329,
+ 330, 331, 332, 333, 334, 335, 336, 337, 338, 340,
+ 341, 342, 343, 344, 345, 346, 348, 349, 350, 351,
+ 352, 354, 355, 356, 357, 358, 359, 360, 361, 362,
+ 363, 364, 365, 366, 367, 368, 369, 370, 371, 373,
+
+ 374, 375, 376, 377, 380, 387, 394, 396, 398, 400,
+ 402, 405, 407, 408, 414, 418, 422, 426, 429, 433,
+ 434, 435, 439
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "camp.l"
+#line 2 "camp.l"
+/*****
+ * camp.l
+ * Andy Hammerlindl 2002/06/14
+ *
+ * The lexical analyzer of the Asymptote language.
+ *****/
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cstring>
+
+#include "util.h"
+#include "modifier.h"
+#include "exp.h"
+#include "stm.h"
+#include "fundec.h"
+#include "errormsg.h"
+#include "interact.h"
+#include "lexical.h"
+
+using namespace absyntax;
+using mem::string;
+
+#include "camp.tab.h"
+
+#include "opsymbols.h"
+
+#define YY_NO_INPUT
+
+static void yyunput(int, char *);
+void (*unused)(int,char *) = yyunput;
+
+fileinfo* fi;
+Int tokPos;
+Int charPos;
+//int commentDepth = 0;
+
+bool eof;
+string eofMessage;
+
+extern errorstream em;
+
+extern "C" int yywrap(void)
+{
+ charPos=1;
+ return 1;
+}
+
+typedef size_t (*input_f) (char* bif, size_t max_size);
+
+input_f yy_input = NULL;
+
+void setlexer(input_f input, string filename)
+{
+ YY_FLUSH_BUFFER;
+ yywrap();
+ fi = new fileinfo(filename);
+ yy_input = input;
+ tokPos = charPos = 1;
+
+ eof=false;
+ eofMessage="<no eof>";
+}
+
+#define YY_INPUT(buf,result,max_size) {result=yy_input(buf,max_size);}
+
+position lexerPos()
+{
+ position p;
+ p.init(fi, tokPos);
+ return p;
+}
+
+namespace {
+position here()
+
+{
+ return lexerPos();
+}
+
+void adjust()
+{
+ tokPos = charPos;
+ charPos += yyleng;
+ yylval.pos = here();
+}
+
+void savesymbol(symbol name)
+{
+ adjust();
+ yylval.ps.pos=yylval.pos; // avoid invoking here() twice
+ yylval.ps.sym=name;
+}
+
+/* For optimization reasons, the operator names are translated into symbols
+ * just once, and can be accessed throughout the code as SYM_PLUS, SYM_DASHES,
+ * etc. Following the Don't Repeat Yourself principle, the mapping from
+ * strings to names is defined only here in camp.l (because we can't produce
+ * lex rules from a C style macro).
+ * The script opsymbols.pl reads this file scanning for rules using DEFSYMBOL
+ * and creates opsymbols.h which defines the names for use in C++ code.
+ */
+#define DEFSYMBOL(name) \
+ savesymbol(name)
+
+ /* Extra symbols can be added by EXTRASYMBOL */
+#define EXTRASYMBOL(chars, codename) /* blank */
+
+EXTRASYMBOL(tuple, SYM_TUPLE);
+
+void makesymbol()
+{
+ assert(strlen(yytext) == (size_t)yyleng);
+ savesymbol(symbol::rawTrans(yytext, yyleng+1));
+}
+
+void makeopsymbol()
+{
+ savesymbol(symbol::opTrans(yytext));
+}
+
+void makemod(trans::modifier mod) {
+ yylval.mod.pos=here();
+ yylval.mod.val=mod;
+}
+
+void makeperm(trans::permission perm) {
+ yylval.perm.pos=here();
+ yylval.perm.val=perm;
+}
+
+void newline()
+{
+ fi->newline();
+ charPos = tokPos = 1;
+}
+
+void error(void)
+{
+ em.error(here());
+}
+
+}
+
+
+// Used by the lexer rules to flag an unexpected end of input. The message is
+// the error message that should be reported, and may differ if, say the input
+// ends in the middle of a string or comment.
+void setEOF(string message) {
+ eof=true;
+ eofMessage=message;
+}
+
+// Called by code outside of the lexer to see if a parse error was caused by
+// running out of input.
+bool lexerEOF()
+{
+ return eof;
+}
+
+// Called by code outside of the lexer when it wants to report the unexpected
+// eof as an error (instead of looking for more input).
+void reportEOF() {
+ assert(eof);
+ error();
+ em << eofMessage;
+ em.sync();
+}
+
+position stringpos; // The position of the start of the string.
+string stringbuild; // Stores the string literal as it is read.
+
+namespace {
+void startstring()
+{
+ adjust();
+ stringpos = here();
+}
+
+void append(char c)
+{
+ stringbuild.push_back(c);
+ yylval.pos = here();
+}
+
+void getstring(void)
+{
+ // NOTE: Replace here() with a position at the start of the string.
+ yylval.stre = new stringExp(stringpos, stringbuild);
+ string().swap(stringbuild);
+}
+}
+
+
+
+
+
+
+#line 1001 "lex.yy.cc"
+
+#define INITIAL 0
+#define lexcomment 1
+#define texstring 2
+#define cstring 3
+#define lexformat 4
+#define opname 5
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+/* %if-c-only */
+#include <unistd.h>
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+
+static int yy_init_globals (void );
+
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif End reentrant structures and macros. */
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * _in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * _out_str );
+
+ int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int _line_number );
+
+/* %if-bison-bridge */
+/* %endif */
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+/* %not-for-header */
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput (int c,char *buf_ptr );
+
+#endif
+/* %ok-for-header */
+
+/* %endif */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+/* %ok-for-header */
+
+/* %endif */
+#endif
+
+/* %if-c-only */
+
+/* %endif */
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* %if-c-only Standard (non-C++) definition */
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+/* %if-c++-only C++ definition \ */\
+/* %endif */
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+/* %if-c-only */
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+#endif
+
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
+/* end tables serialization structures and prototypes */
+
+/* %ok-for-header */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+/* %if-c-only Standard (non-C++) definition */
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+/* %% [6.0] YY_RULE_SETUP definition goes here */
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/* %not-for-header */
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+/* %if-c-only */
+ yyin = stdin;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! yyout )
+/* %if-c-only */
+ yyout = stdout;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ {
+/* %% [7.0] user's declarations go here */
+#line 209 "camp.l"
+
+
+#line 1294 "lex.yy.cc"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+/* %% [8.0] yymore()-related code goes here */
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+/* %% [9.0] code to set up and find next match goes here */
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 337 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 542 );
+
+yy_find_action:
+/* %% [10.0] code to find the action number goes here */
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+/* %% [11.0] code for yylineno update goes here */
+
+do_action: /* This label is used only to access EOF actions. */
+
+/* %% [12.0] debug code goes here */
+ if ( yy_flex_debug )
+ {
+ if ( yy_act == 0 )
+ fprintf( stderr, "--scanner backing up\n" );
+ else if ( yy_act < 124 )
+ fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
+ (long)yy_rule_linenum[yy_act], yytext );
+ else if ( yy_act == 124 )
+ fprintf( stderr, "--accepting default rule (\"%s\")\n",
+ yytext );
+ else if ( yy_act == 125 )
+ fprintf( stderr, "--(end of buffer or a NUL)\n" );
+ else
+ fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
+ }
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+/* %% [13.0] actions go here */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 212 "camp.l"
+{adjust(); /*commentDepth++;*/}
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 213 "camp.l"
+{adjust(); /*commentDepth--;*/
+ /*if (commentDepth == 0)*/ BEGIN INITIAL; }
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 215 "camp.l"
+{adjust(); newline(); continue; }
+ YY_BREAK
+case YY_STATE_EOF(lexcomment):
+#line 216 "camp.l"
+{adjust();
+ setEOF("comment not terminated");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 221 "camp.l"
+{adjust(); continue; }
+ YY_BREAK
+
+
+case 5:
+/* rule 5 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+YY_LINENO_REWIND_TO(yy_bp + 1);
+(yy_c_buf_p) = yy_cp = yy_bp + 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 225 "camp.l"
+{adjust(); BEGIN INITIAL;}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 226 "camp.l"
+{adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+ YY_BREAK
+case YY_STATE_EOF(texstring):
+#line 230 "camp.l"
+{adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+ YY_BREAK
+case 7:
+/* rule 7 can match eol */
+YY_RULE_SETUP
+#line 236 "camp.l"
+{adjust(); newline(); append('\n'); continue; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 237 "camp.l"
+{adjust(); append('\\'); append('\\'); continue; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 238 "camp.l"
+{adjust(); append('\"'); continue; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 239 "camp.l"
+{adjust(); append(*yytext); }
+ YY_BREAK
+
+
+case 11:
+/* rule 11 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+YY_LINENO_REWIND_TO(yy_bp + 1);
+(yy_c_buf_p) = yy_cp = yy_bp + 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 243 "camp.l"
+{adjust(); BEGIN INITIAL;}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 244 "camp.l"
+{adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+ YY_BREAK
+case YY_STATE_EOF(cstring):
+#line 248 "camp.l"
+{adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+ YY_BREAK
+case 13:
+/* rule 13 can match eol */
+YY_RULE_SETUP
+#line 254 "camp.l"
+{adjust(); newline(); append('\n'); continue; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 255 "camp.l"
+{adjust(); append(yytext[1]); continue; }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 256 "camp.l"
+{adjust(); append('\a'); continue; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 257 "camp.l"
+{adjust(); append('\b'); continue; }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 258 "camp.l"
+{adjust(); append('\f'); continue; }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 259 "camp.l"
+{adjust(); append('\n'); continue; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 260 "camp.l"
+{adjust(); append('\r'); continue; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 261 "camp.l"
+{adjust(); append('\t'); continue; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 262 "camp.l"
+{adjust(); append('\v'); continue; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 263 "camp.l"
+{adjust();
+ char x=(char)(yytext[1]-'0');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 268 "camp.l"
+{adjust();
+ char x=(char)((yytext[1]-'0')*8+yytext[2]-'0');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 273 "camp.l"
+{adjust();
+ char x=(char)((yytext[1]-'0')*64+(yytext[2]-'0')*8
+ +yytext[3]-'0');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 279 "camp.l"
+{adjust();
+ char x=(char) (yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 285 "camp.l"
+{adjust();
+ char x=(char) ((yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A')*16
+ +(yytext[3] <= '9' ? yytext[3]-'0' :
+ 10+yytext[3]-'A'));
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 293 "camp.l"
+{adjust(); append(*yytext); }
+ YY_BREAK
+
+case 28:
+YY_RULE_SETUP
+#line 296 "camp.l"
+{adjust(); continue;}
+ YY_BREAK
+case 29:
+/* rule 29 can match eol */
+YY_RULE_SETUP
+#line 297 "camp.l"
+{adjust(); newline(); continue;}
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 298 "camp.l"
+{adjust(); continue;}
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 299 "camp.l"
+{adjust(); return ','; }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 300 "camp.l"
+{adjust(); return ':'; }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 301 "camp.l"
+{adjust(); return ';'; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 302 "camp.l"
+{adjust(); return '('; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 303 "camp.l"
+{adjust(); return ')'; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 304 "camp.l"
+{adjust(); return '['; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 305 "camp.l"
+{adjust(); return ']'; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 306 "camp.l"
+{adjust(); return '{'; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 307 "camp.l"
+{adjust(); return '}'; }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 308 "camp.l"
+{adjust(); return '.'; }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 309 "camp.l"
+{adjust(); return ELLIPSIS; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 311 "camp.l"
+{DEFSYMBOL(SYM_PLUS); return '+'; }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 312 "camp.l"
+{DEFSYMBOL(SYM_MINUS); return '-'; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 313 "camp.l"
+{DEFSYMBOL(SYM_TIMES); return '*'; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 314 "camp.l"
+{DEFSYMBOL(SYM_DIVIDE); return '/'; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 315 "camp.l"
+{DEFSYMBOL(SYM_QUOTIENT); return '#'; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 316 "camp.l"
+{DEFSYMBOL(SYM_MOD); return '%'; }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 317 "camp.l"
+{DEFSYMBOL(SYM_CARET); return '^'; }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 318 "camp.l"
+{savesymbol(SYM_CARET); return '^'; }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 319 "camp.l"
+{adjust(); return '?'; }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 320 "camp.l"
+{adjust(); return ASSIGN; }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 321 "camp.l"
+{DEFSYMBOL(SYM_EQ); return EQ; }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 322 "camp.l"
+{DEFSYMBOL(SYM_NEQ); return NEQ; }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 323 "camp.l"
+{DEFSYMBOL(SYM_LT); return LT; }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 324 "camp.l"
+{DEFSYMBOL(SYM_LE); return LE; }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 325 "camp.l"
+{DEFSYMBOL(SYM_GT); return GT; }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 326 "camp.l"
+{DEFSYMBOL(SYM_GE); return GE; }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 327 "camp.l"
+{DEFSYMBOL(SYM_CAND); return CAND; }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 328 "camp.l"
+{DEFSYMBOL(SYM_COR); return COR; }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 329 "camp.l"
+{DEFSYMBOL(SYM_LOGNOT); return OPERATOR; }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 330 "camp.l"
+{DEFSYMBOL(SYM_CARETS); return CARETS; }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 331 "camp.l"
+{DEFSYMBOL(SYM_COLONS); return COLONS; }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 332 "camp.l"
+{DEFSYMBOL(SYM_INCR); return INCR; }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 333 "camp.l"
+{DEFSYMBOL(SYM_DOTS); return DOTS; }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 334 "camp.l"
+{DEFSYMBOL(SYM_DASHES); return DASHES; }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 335 "camp.l"
+{DEFSYMBOL(SYM_LONGDASH); return LONGDASH; }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 336 "camp.l"
+{DEFSYMBOL(SYM_AMPERSAND); return AMPERSAND; }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 337 "camp.l"
+{DEFSYMBOL(SYM_BAR); return BAR; }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 338 "camp.l"
+{makeopsymbol(); return OPERATOR; }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 340 "camp.l"
+{savesymbol(SYM_PLUS); return SELFOP; }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 341 "camp.l"
+{savesymbol(SYM_MINUS); return SELFOP; }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 342 "camp.l"
+{savesymbol(SYM_TIMES); return SELFOP; }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 343 "camp.l"
+{savesymbol(SYM_DIVIDE); return SELFOP; }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 344 "camp.l"
+{savesymbol(SYM_QUOTIENT); return SELFOP; }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 345 "camp.l"
+{savesymbol(SYM_MOD); return SELFOP; }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 346 "camp.l"
+{savesymbol(SYM_CARET); return SELFOP; }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 348 "camp.l"
+{adjust(); return AND; }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 349 "camp.l"
+{DEFSYMBOL(SYM_CONTROLS); return CONTROLS; }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 350 "camp.l"
+{DEFSYMBOL(SYM_TENSION); return TENSION; }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 351 "camp.l"
+{DEFSYMBOL(SYM_ATLEAST); return ATLEAST; }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 352 "camp.l"
+{DEFSYMBOL(SYM_CURL); return CURL; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 354 "camp.l"
+{adjust(); return IF; }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 355 "camp.l"
+{adjust(); return ELSE; }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 356 "camp.l"
+{adjust(); return WHILE; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 357 "camp.l"
+{adjust(); return FOR; }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 358 "camp.l"
+{adjust(); return DO; }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 359 "camp.l"
+{adjust(); return RETURN_; }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 360 "camp.l"
+{adjust(); return BREAK; }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 361 "camp.l"
+{adjust(); return CONTINUE; }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 362 "camp.l"
+{adjust(); return STRUCT; }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 363 "camp.l"
+{adjust(); return TYPEDEF; }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 364 "camp.l"
+{adjust(); return NEW; }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 365 "camp.l"
+{adjust(); return ACCESS; }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 366 "camp.l"
+{adjust(); return IMPORT; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 367 "camp.l"
+{adjust(); return UNRAVEL; }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 368 "camp.l"
+{adjust(); return FROM; }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 369 "camp.l"
+{adjust(); return INCLUDE; }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 370 "camp.l"
+{adjust(); return QUOTE; }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 371 "camp.l"
+{adjust(); makemod(trans::EXPLICIT_STATIC);
+ return MODIFIER; }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 373 "camp.l"
+{adjust(); makeperm(trans::PUBLIC); return PERM; }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 374 "camp.l"
+{adjust(); makeperm(trans::PRIVATE); return PERM; }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 375 "camp.l"
+{adjust(); makeperm(trans::RESTRICTED); return PERM; }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 376 "camp.l"
+{adjust(); return THIS; }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 377 "camp.l"
+{adjust(); return EXPLICIT; }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 380 "camp.l"
+try {
+ adjust(); yylval.e= new intExp(here(), lexical::cast<Int>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid integer";
+ yylval.e= new intExp(here(), 0);
+ } return LIT;
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 387 "camp.l"
+try {
+ adjust(); yylval.e= new realExp(here(), lexical::cast<double>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid real";
+ yylval.e= new realExp(here(), 0);
+ } return LIT;
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 394 "camp.l"
+{
+ adjust(); yylval.e= new booleanExp(here(), true); return LIT; }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 396 "camp.l"
+{
+ adjust(); yylval.e= new booleanExp(here(), false); return LIT; }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 398 "camp.l"
+{
+ adjust(); yylval.e= new nullExp(here()); return LIT; }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 400 "camp.l"
+{
+ adjust(); yylval.e= new cycleExp(here()); return LIT; }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 402 "camp.l"
+{
+ adjust(); yylval.e= new newPictureExp(here()); return LIT; }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 405 "camp.l"
+{adjust(); BEGIN opname; }
+ YY_BREAK
+
+case 113:
+YY_RULE_SETUP
+#line 407 "camp.l"
+{adjust(); continue;}
+ YY_BREAK
+case 114:
+/* rule 114 can match eol */
+YY_RULE_SETUP
+#line 408 "camp.l"
+{adjust(); newline(); continue;}
+ YY_BREAK
+case YY_STATE_EOF(opname):
+#line 409 "camp.l"
+{adjust();
+ setEOF("missing operator name");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 414 "camp.l"
+{ savesymbol(SYM_CARET);
+ BEGIN INITIAL;
+ return ID;
+ }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 418 "camp.l"
+{
+ makeopsymbol();
+ BEGIN INITIAL;
+ return ID;}
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 422 "camp.l"
+{
+ makeopsymbol();
+ BEGIN INITIAL;
+ return ID; }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 426 "camp.l"
+{}
+ YY_BREAK
+
+case 119:
+YY_RULE_SETUP
+#line 429 "camp.l"
+{
+ makesymbol();
+ return ID; }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 433 "camp.l"
+{adjust(); /*commentDepth = 1;*/ BEGIN lexcomment; }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 434 "camp.l"
+{startstring(); BEGIN texstring; }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 435 "camp.l"
+{startstring(); BEGIN cstring; }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(lexformat):
+#line 437 "camp.l"
+{ setEOF("unexpected end of input"); yyterminate(); }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 439 "camp.l"
+{adjust();
+ error();
+ em << "invalid token";
+ if (isgraph(yytext[0]))
+ em << " '" << yytext[0] << "'";
+ }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 445 "camp.l"
+ECHO;
+ YY_BREAK
+#line 2121 "lex.yy.cc"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+/* %if-c-only */
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+/* %ok-for-header */
+
+/* %if-c++-only */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %endif */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+/* %if-c-only */
+static int yy_get_next_buffer (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ yy_size_t number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,(yy_size_t) (b->yy_buf_size + 2) );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,(yy_size_t) new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+/* %if-c-only */
+/* %not-for-header */
+
+ static yy_state_type yy_get_previous_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+/* %% [15.0] code to get the start state into yy_current_state goes here */
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+/* %% [16.0] code to find the next state goes here */
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 337 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+/* %if-c-only */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int yy_is_jam;
+ /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 337 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ yy_is_jam = (yy_current_state == 336);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+/* %if-c-only */
+
+ static void yyunput (int c, char * yy_bp )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ int number_to_move = (yy_n_chars) + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+/* %% [18.0] update yylineno here */
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+/* %if-c-only */
+
+/* %endif */
+#endif
+
+/* %if-c-only */
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return 0;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+/* %% [19.0] update BOL and yylineno */
+
+ return c;
+}
+/* %if-c-only */
+#endif /* ifndef YY_NO_INPUT */
+/* %endif */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+/* %if-c-only */
+ void yyrestart (FILE * input_file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/* %if-c++-only */
+/* %endif */
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+/* %if-c-only */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/* %if-c-only */
+static void yy_load_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+/* %if-c-only */
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+/* %if-c-only */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc((yy_size_t) (b->yy_buf_size + 2) );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/* %if-c++-only */
+/* %endif */
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+/* %if-c-only */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+/* %if-c-only */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+/* %if-c-only */
+ b->yy_input_file = file;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+/* %if-c-only */
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+/* %if-c-only */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/* %if-c-or-c++ */
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+/* %if-c-only */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+/* %if-c-only */
+void yypop_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+/* %if-c-only */
+static void yyensure_buffer_stack (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,(int) strlen(yystr) );
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+/* %endif */
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+/* %if-c-only */
+static void yynoreturn yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yy_size_t yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/* %if-reentrant */
+/* %endif */
+
+/** Set the current line number.
+ * @param _line_number line number
+ *
+ */
+void yyset_lineno (int _line_number )
+{
+
+ yylineno = _line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * _in_str )
+{
+ yyin = _in_str ;
+}
+
+void yyset_out (FILE * _out_str )
+{
+ yyout = _out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int _bdebug )
+{
+ yy_flex_debug = _bdebug ;
+}
+
+/* %endif */
+
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif if-c-only */
+
+/* %if-c-only */
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = NULL;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = NULL;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+/* %endif */
+
+/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+/* %if-reentrant */
+/* %endif */
+ return 0;
+}
+/* %endif */
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return malloc(size);
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+/* %if-tables-serialization definitions */
+/* %define-yytables The name for this specific scanner's tables. */
+#define YYTABLES_NAME "yytables"
+/* %endif */
+
+/* %ok-for-header */
+
+#line 445 "camp.l"
diff --git a/graphics/asymptote/lexical.h b/graphics/asymptote/lexical.h
new file mode 100644
index 0000000000..fc3879961d
--- /dev/null
+++ b/graphics/asymptote/lexical.h
@@ -0,0 +1,23 @@
+#ifndef __lexical_h__
+#define __lexical_h__ 1
+
+#include <sstream>
+
+#include "common.h"
+
+namespace lexical {
+
+class bad_cast {};
+
+template <typename T>
+T cast(const string& s, bool tolerant=false)
+{
+ istringstream is(s);
+ T value;
+ if(is && is >> value && ((is >> std::ws).eof() || tolerant)) return value;
+ throw bad_cast();
+}
+
+}
+
+#endif
diff --git a/graphics/asymptote/lnkX64IconFix.nsh b/graphics/asymptote/lnkX64IconFix.nsh
new file mode 100644
index 0000000000..d1a4c9f311
--- /dev/null
+++ b/graphics/asymptote/lnkX64IconFix.nsh
@@ -0,0 +1,74 @@
+/******************************************************************************
+ WORKAROUND - lnkX64IconFix
+ This snippet was developed to address an issue with Windows
+ x64 incorrectly redirecting the shortcuts icon from $PROGRAMFILES32
+ to $PROGRAMFILES64.
+
+ See Forum post: http://forums.winamp.com/newreply.php?do=postreply&t=327806
+
+ Example:
+ CreateShortcut "$SMPROGRAMS\My App\My App.lnk" "$INSTDIR\My App.exe" "" "$INSTDIR\My App.exe"
+ ${lnkX64IconFix} "$SMPROGRAMS\My App\My App.lnk"
+
+ Original Code by Anders [http://forums.winamp.com/member.php?u=70852]
+ ******************************************************************************/
+!ifndef ___lnkX64IconFix___
+ !verbose push
+ !verbose 0
+
+ !include "LogicLib.nsh"
+ !include "x64.nsh"
+
+ !define ___lnkX64IconFix___
+ !define lnkX64IconFix `!insertmacro _lnkX64IconFix`
+ !macro _lnkX64IconFix _lnkPath
+ !verbose push
+ !verbose 0
+ ${If} ${RunningX64}
+ DetailPrint "WORKAROUND: 64bit OS Detected, Attempting to apply lnkX64IconFix"
+ Push "${_lnkPath}"
+ Call lnkX64IconFix
+ ${EndIf}
+ !verbose pop
+ !macroend
+
+ Function lnkX64IconFix ; _lnkPath
+ Exch $5
+ Push $0
+ Push $1
+ Push $2
+ Push $3
+ Push $4
+ System::Call 'OLE32::CoCreateInstance(g "{00021401-0000-0000-c000-000000000046}",i 0,i 1,g "{000214ee-0000-0000-c000-000000000046}",*i.r1)i'
+ ${If} $1 <> 0
+ System::Call '$1->0(g "{0000010b-0000-0000-C000-000000000046}",*i.r2)'
+ ${If} $2 <> 0
+ System::Call '$2->5(w r5,i 2)i.r0'
+ ${If} $0 = 0
+ System::Call '$1->0(g "{45e2b4ae-b1c3-11d0-b92f-00a0c90312e1}",*i.r3)i.r0'
+ ${If} $3 <> 0
+ System::Call '$3->5(i 0xA0000007)i.r0'
+ System::Call '$3->6(*i.r4)i.r0'
+ ${If} $0 = 0
+ IntOp $4 $4 & 0xffffBFFF
+ System::Call '$3->7(ir4)i.r0'
+ ${If} $0 = 0
+ System::Call '$2->6(i0,i0)'
+ DetailPrint "WORKAROUND: lnkX64IconFix Applied successfully"
+ ${EndIf}
+ ${EndIf}
+ System::Call $3->2()
+ ${EndIf}
+ ${EndIf}
+ System::Call $2->2()
+ ${EndIf}
+ System::Call $1->2()
+ ${EndIf}
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+ FunctionEnd
+ !verbose pop
+!endif
diff --git a/graphics/asymptote/locate.cc b/graphics/asymptote/locate.cc
new file mode 100644
index 0000000000..7c6381e6b3
--- /dev/null
+++ b/graphics/asymptote/locate.cc
@@ -0,0 +1,102 @@
+/*****
+ * locate.cc
+ * Tom Prince 2005/03/24
+ *
+ * Locate files in search path.
+ *****/
+
+#include <unistd.h>
+
+#include "settings.h"
+#include "util.h"
+#include "locate.h"
+
+
+
+namespace settings {
+
+namespace fs {
+
+string extension(string name)
+{
+ size_t n = name.rfind(".");
+ if (n != string::npos)
+ return name.substr(n);
+ else
+ return string();
+}
+
+bool exists(string filename)
+{
+ return ::access(filename.c_str(), R_OK) == 0;
+}
+
+} // namespace fs
+
+
+file_list_t searchPath;
+
+// Returns list of possible filenames, accounting for extensions.
+file_list_t mungeFileName(string id)
+{
+ string ext = fs::extension(id);
+ file_list_t files;
+ if (ext == "."+settings::suffix) {
+ files.push_back(id);
+ files.push_back(id+"."+settings::suffix);
+ } else {
+ files.push_back(id+"."+settings::suffix);
+ files.push_back(id);
+ }
+ return files;
+}
+
+// Join a directory with the given filename, to give the path to the file. This
+// also avoids unsightly joins such as './file.asy' in favour of 'file.asy' and
+// 'dir//file.asy' in favour of 'dir/file.asy'
+string join(string dir, string file)
+{
+ return dir == "." ? file :
+ *dir.rbegin() == '/' ? dir + file :
+ dir + "/" + file;
+}
+
+// Find the appropriate file, first looking in the local directory, then the
+// directory given in settings, and finally the global system directory.
+string locateFile(string id)
+{
+ if(id.empty()) return "";
+ file_list_t filenames = mungeFileName(id);
+ for (file_list_t::iterator leaf = filenames.begin();
+ leaf != filenames.end();
+ ++leaf) {
+#ifdef __MSDOS__
+ size_t p;
+ while ((p=leaf->find('\\')) < string::npos)
+ (*leaf)[p]='/';
+ if ((p=leaf->find(':')) < string::npos && p > 0) {
+ (*leaf)[p]='/';
+ leaf->insert(0,"/cygdrive/");
+ }
+#endif
+
+ if ((*leaf)[0] == '/') {
+ string file = *leaf;
+ if (fs::exists(file))
+ return file;
+ } else {
+ for (file_list_t::iterator dir = searchPath.begin();
+ dir != searchPath.end();
+ ++dir) {
+ string file = join(*dir,*leaf);
+ if (fs::exists(file))
+ return file;
+ }
+ }
+ }
+ return string();
+}
+
+} // namespace settings
+
+
diff --git a/graphics/asymptote/locate.h b/graphics/asymptote/locate.h
new file mode 100644
index 0000000000..915a5e9d59
--- /dev/null
+++ b/graphics/asymptote/locate.h
@@ -0,0 +1,31 @@
+/*****
+ * locate.h
+ * Tom Prince 2005/03/24
+ *
+ * Locate files in search path.
+ *****/
+
+#ifndef LOCATE_H
+#define LOCATE_H
+
+#include "common.h"
+
+namespace settings {
+
+typedef mem::list<string> file_list_t;
+extern file_list_t searchPath;
+
+// Find the appropriate file, first looking in the local directory, then the
+// directory given in settings, and finally the global system directory.
+string locateFile(string id);
+
+namespace fs {
+
+// Check to see if a file of given name exists.
+bool exists(string filename);
+
+}
+
+} // namespace settings
+
+#endif // LOCATE_H
diff --git a/graphics/asymptote/main.cc b/graphics/asymptote/main.cc
new file mode 100644
index 0000000000..486e84ef78
--- /dev/null
+++ b/graphics/asymptote/main.cc
@@ -0,0 +1,250 @@
+/************
+*
+* This file is part of the vector graphics language Asymptote
+* Copyright (C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince
+* http://asymptote.sourceforge.net
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifdef __CYGWIN__
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <iostream>
+#include <cstdlib>
+#include <cerrno>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+#define GC_PTHREAD_SIGMASK_NEEDED
+
+#include "common.h"
+
+#ifdef HAVE_LIBSIGSEGV
+#include <sigsegv.h>
+#endif
+
+#include "errormsg.h"
+#include "fpu.h"
+#include "settings.h"
+#include "locate.h"
+#include "interact.h"
+#include "fileio.h"
+
+#include "stack.h"
+
+using namespace settings;
+
+using interact::interactive;
+
+namespace run {
+void purge();
+}
+
+#ifdef PROFILE
+namespace vm {
+extern void dumpProfile();
+};
+#endif
+
+#ifdef HAVE_LIBSIGSEGV
+void stackoverflow_handler (int, stackoverflow_context_t)
+{
+ em.runtime(vm::getPos());
+ cerr << "Stack overflow" << endl;
+ abort();
+}
+
+int sigsegv_handler (void *, int emergency)
+{
+ if(!emergency) return 0; // Really a stack overflow
+ em.runtime(vm::getPos());
+#ifdef HAVE_GL
+ if(gl::glthread)
+ cerr << "Stack overflow or segmentation fault: rerun with -nothreads"
+ << endl;
+ else
+#endif
+ cerr << "Segmentation fault" << endl;
+ abort();
+}
+#endif
+
+void setsignal(RETSIGTYPE (*handler)(int))
+{
+#ifdef HAVE_LIBSIGSEGV
+ char mystack[16384];
+ stackoverflow_install_handler(&stackoverflow_handler,
+ mystack,sizeof (mystack));
+ sigsegv_install_handler(&sigsegv_handler);
+#endif
+ Signal(SIGBUS,handler);
+ Signal(SIGFPE,handler);
+}
+
+void signalHandler(int)
+{
+ // Print the position and trust the shell to print an error message.
+ em.runtime(vm::getPos());
+
+ Signal(SIGBUS,SIG_DFL);
+ Signal(SIGFPE,SIG_DFL);
+}
+
+void interruptHandler(int)
+{
+ em.Interrupt(true);
+}
+
+bool hangup=false;
+void hangup_handler(int sig)
+{
+ hangup=true;
+}
+
+struct Args
+{
+ int argc;
+ char **argv;
+ Args(int argc, char **argv) : argc(argc), argv(argv) {}
+};
+
+void *asymain(void *A)
+{
+ setsignal(signalHandler);
+ Args *args=(Args *) A;
+ fpu_trap(trap());
+
+ if(interactive) {
+ Signal(SIGINT,interruptHandler);
+ processPrompt();
+ } else if (getSetting<bool>("listvariables") && numArgs()==0) {
+ try {
+ doUnrestrictedList();
+ } catch(handled_error) {
+ em.statusError();
+ }
+ } else {
+ int n=numArgs();
+ if(n == 0) {
+ int inpipe=intcast(settings::getSetting<Int>("inpipe"));
+ if(inpipe >= 0) {
+ Signal(SIGHUP,hangup_handler);
+ camp::openpipeout();
+ fprintf(camp::pipeout,"\n");
+ fflush(camp::pipeout);
+ }
+ while(true) {
+ processFile("-",true);
+ try {
+ setOptions(args->argc,args->argv);
+ } catch(handled_error) {
+ em.statusError();
+ }
+ if(inpipe < 0) break;
+ }
+ } else {
+ for(int ind=0; ind < n; ind++) {
+ processFile(string(getArg(ind)),n > 1);
+ try {
+ if(ind < n-1)
+ setOptions(args->argc,args->argv);
+ } catch(handled_error) {
+ em.statusError();
+ }
+ }
+ }
+ }
+
+#ifdef PROFILE
+ vm::dumpProfile();
+#endif
+
+ if(getSetting<bool>("wait")) {
+ int status;
+ while(wait(&status) > 0);
+ }
+#ifdef HAVE_GL
+#ifdef HAVE_PTHREAD
+ if(gl::glthread && !getSetting<bool>("offscreen")) {
+ pthread_kill(gl::mainthread,SIGURG);
+ pthread_join(gl::mainthread,NULL);
+ }
+#endif
+#endif
+ exit(em.processStatus() || interact::interactive ? 0 : 1);
+}
+
+void exitHandler(int)
+{
+ exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+#ifdef HAVE_LIBGSL
+ unsetenv("GSL_RNG_SEED");
+ unsetenv("GSL_RNG_TYPE");
+#endif
+ setsignal(signalHandler);
+
+ try {
+ setOptions(argc,argv);
+ } catch(handled_error) {
+ em.statusError();
+ }
+
+ Args args(argc,argv);
+#ifdef HAVE_GL
+#ifdef __APPLE__
+ bool usethreads=true;
+#else
+ bool usethreads=view();
+#endif
+ gl::glthread=usethreads ? getSetting<bool>("threads") : false;
+#if HAVE_PTHREAD
+
+ if(gl::glthread) {
+ pthread_t thread;
+ try {
+ if(pthread_create(&thread,NULL,asymain,&args) == 0) {
+ gl::mainthread=pthread_self();
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGCHLD);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+ while(true) {
+ Signal(SIGURG,exitHandler);
+ camp::glrenderWrapper();
+ gl::initialize=true;
+ }
+ } else gl::glthread=false;
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ }
+ }
+#endif
+ gl::glthread=false;
+#endif
+ asymain(&args);
+}
+
+#ifdef USEGC
+GC_API void GC_CALL GC_throw_bad_alloc() {
+ std::bad_alloc();
+}
+#endif
+
diff --git a/graphics/asymptote/material.h b/graphics/asymptote/material.h
new file mode 100644
index 0000000000..4a07229046
--- /dev/null
+++ b/graphics/asymptote/material.h
@@ -0,0 +1,66 @@
+#ifndef MATERIAL_STRUCT
+#define MATERIAL_STRUCT
+#ifdef HAVE_GL
+
+#include <glm/glm.hpp>
+
+namespace camp {
+
+inline bool operator < (const glm::vec4& m1, const glm::vec4& m2) {
+ return m1[0] < m2[0] ||
+ (m1[0] == m2[0] &&
+ (m1[1] < m2[1] ||
+ (m1[1] == m2[1] &&
+ (m1[2] < m2[2] ||
+ (m1[2] == m2[2] &&
+ (m1[3] < m2[3]))))));
+}
+
+inline glm::vec4 GLparameters(GLfloat shininess, GLfloat metallic,
+ GLfloat fresnel0) {
+ return glm::vec4(shininess,metallic,fresnel0,0.0);
+}
+
+struct Material {
+public:
+ glm::vec4 diffuse,emissive,specular;
+ glm::vec4 parameters;
+ Material() {}
+
+ Material(const glm::vec4& diffuse, const glm::vec4& emissive,
+ const glm::vec4& specular, double shininess, double metallic, double fresnel0) :
+ diffuse(diffuse), emissive(emissive), specular(specular),
+ parameters(GLparameters(shininess,metallic,fresnel0)) {}
+
+ Material(Material const& m):
+ diffuse(m.diffuse), emissive(m.emissive),
+ specular(m.specular), parameters(m.parameters) {}
+ ~Material() {}
+
+ Material& operator=(Material const& m)
+ {
+ diffuse=m.diffuse;
+ emissive=m.emissive;
+ specular=m.specular;
+ parameters=m.parameters;
+ return *this;
+ }
+ friend bool operator < (const Material& m1, const Material& m2) {
+ return m1.diffuse < m2.diffuse ||
+ (m1.diffuse == m2.diffuse &&
+ (m1.emissive < m2.emissive ||
+ (m1.emissive == m2.emissive &&
+ (m1.specular < m2.specular ||
+ (m1.specular == m2.specular &&
+ (m1.parameters < m2.parameters))))));
+ }
+};
+
+extern size_t Nmaterials; // Number of materials compiled in shader
+extern size_t nmaterials; // Current size of materials buffer
+extern size_t Maxmaterials; // Maxinum size of materials buffer
+void clearMaterialBuffer(bool draw=false);
+
+}
+#endif
+#endif
diff --git a/graphics/asymptote/mathop.h b/graphics/asymptote/mathop.h
new file mode 100644
index 0000000000..aba85d39a4
--- /dev/null
+++ b/graphics/asymptote/mathop.h
@@ -0,0 +1,328 @@
+/*****
+ * mathop.h
+ * Tom Prince 2005/3/18
+ *
+ * Defines some runtime functions used by the stack machine.
+ *
+ *****/
+
+#ifndef MATHOP_H
+#define MATHOP_H
+
+#include <sstream>
+
+#include "stack.h"
+#include "mod.h"
+#include "triple.h"
+
+namespace run {
+
+template <typename T>
+struct less {
+ bool operator() (T x, T y, size_t=0) {return x < y;}
+};
+
+template <typename T>
+struct lessequals {
+ bool operator() (T x, T y, size_t=0) {return x <= y;}
+};
+
+template <typename T>
+struct equals {
+ bool operator() (T x, T y, size_t=0) {return x == y;}
+};
+
+template <typename T>
+struct greaterequals {
+ bool operator() (T x, T y, size_t=0) {return x >= y;}
+};
+
+template <typename T>
+struct greater {
+ bool operator() (T x, T y, size_t=0) {return x > y;}
+};
+
+template <typename T>
+struct notequals {
+ bool operator() (T x, T y, size_t=0) {return x != y;}
+};
+
+template <typename T>
+struct And {
+ bool operator() (T x, T y, size_t=0) {return x && y;}
+};
+
+template <typename T>
+struct Or {
+ bool operator() (T x, T y, size_t=0) {return x || y;}
+};
+
+template <typename T>
+struct Xor {
+ bool operator() (T x, T y, size_t=0) {return x ^ y;}
+};
+
+template <typename T>
+struct plus {
+ T operator() (T x, T y, size_t=0) {return x+y;}
+};
+
+template <typename T>
+struct minus {
+ T operator() (T x, T y, size_t=0) {return x-y;}
+};
+
+template <typename T>
+struct times {
+ T operator() (T x, T y, size_t=0) {return x*y;}
+};
+
+template <>
+struct times<camp::triple> {
+ camp::triple operator() (double x, camp::triple y, size_t=0) {return x*y;}
+};
+
+template <typename T>
+struct timesR {
+ T operator () (T y, double x, size_t=0) {return x*y;}
+};
+
+extern void dividebyzero(size_t i=0);
+extern void integeroverflow(size_t i=0);
+
+template <typename T>
+struct divide {
+ T operator() (T x, T y, size_t i=0) {
+ if(y == 0) dividebyzero(i);
+ return x/y;
+ }
+};
+
+template <>
+struct divide<camp::triple> {
+ camp::triple operator() (camp::triple x, double y, size_t=0) {return x/y;}
+};
+
+inline bool validInt(double x) {
+ return x > Int_MIN-0.5 && x < Int_MAX+0.5;
+}
+
+inline void checkInt(double x, size_t i)
+{
+ if(validInt(x)) return;
+ integeroverflow(i);
+}
+
+inline Int Intcast(double x)
+{
+ if(validInt(x)) return (Int) x;
+ integeroverflow(0);
+ return 0;
+}
+
+template<>
+struct plus<Int> {
+ Int operator() (Int x, Int y, size_t i=0) {
+ if((y > 0 && x > Int_MAX-y) || (y < 0 && x < Int_MIN-y))
+ integeroverflow(i);
+ return x+y;
+ }
+};
+
+template<>
+struct minus<Int> {
+ Int operator() (Int x, Int y, size_t i=0) {
+ if((y < 0 && x > Int_MAX+y) || (y > 0 && x < Int_MIN+y))
+ integeroverflow(i);
+ return x-y;
+ }
+};
+
+template<>
+struct times<Int> {
+ Int operator() (Int x, Int y, size_t i=0) {
+ if(y == 0) return 0;
+ if(y < 0) {y=-y; x=-x;}
+ if((y > int_MAX || x > int_MAX/(int) y || x < int_MIN/(int) y) &&
+ (x > Int_MAX/y || x < Int_MIN/y))
+ integeroverflow(i);
+ return x*y;
+ }
+};
+
+template<>
+struct divide<Int> {
+ double operator() (Int x, Int y, size_t i=0) {
+ if(y == 0) dividebyzero(i);
+ return ((double) x)/(double) y;
+ }
+};
+
+template <class T>
+void Negate(vm::stack *s)
+{
+ T a=vm::pop<T>(s);
+ s->push(-a);
+}
+
+inline Int Negate(Int x, size_t i=0) {
+ if(x < -Int_MAX) integeroverflow(i);
+ return -x;
+}
+
+template<>
+inline void Negate<Int>(vm::stack *s)
+{
+ s->push(Negate(vm::pop<Int>(s)));
+}
+
+inline double pow(double x, double y)
+{
+ return ::pow(x,y);
+}
+
+template<class T>
+T pow(T x, Int y)
+{
+ if(y == 0) return 1.0;
+ if(x == 0.0 && y > 0) return 0.0;
+ if(y < 0) {y=-y; x=1/x;}
+
+ T r=1.0;
+ for(;;) {
+ if(y & 1) r *= x;
+ if((y >>= 1) == 0) return r;
+ x *= x;
+ }
+}
+
+template <typename T>
+struct power {
+ T operator() (T x, T y, size_t=0) {return pow(x,y);}
+};
+
+template <>
+struct power<Int> {
+ Int operator() (Int x, Int p, size_t i=0) {
+ if(p == 0) return 1;
+ Int sign=1;
+ if(x < 0) {
+ if(p % 2) sign=-1;
+ x=-x;
+ }
+ if(p > 0) {
+ if(x == 0) return 0;
+ Int r = 1;
+ for(;;) {
+ if(p & 1) {
+ if(r > Int_MAX/x) integeroverflow(i);
+ r *= x;
+ }
+ if((p >>= 1) == 0)
+ return sign*r;
+ if(x > Int_MAX/x) integeroverflow(i);
+ x *= x;
+ }
+ } else {
+ if(x == 1) return sign;
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Only 1 and -1 can be raised to negative exponents as integers.";
+ vm::error(buf);
+ return 0;
+ }
+ }
+};
+
+template <typename T>
+struct mod {
+ T operator() (T x, T y, size_t i=0) {
+ if(y == 0) dividebyzero(i);
+ return portableMod(x,y);
+ }
+};
+
+template <typename>
+struct quotient {
+ Int operator() (Int x, Int y, size_t i=0) {
+ if(y == 0) dividebyzero(i);
+ if(y == -1) return Negate(x);
+// Implementation-independent definition of integer division: round down
+ Int q=x/y;
+ if(q >= 0 || y*q == x) return q;
+ return q-1;
+ }
+};
+
+template <typename T>
+struct min {
+ T operator() (T x, T y, size_t=0) {return x < y ? x : y;}
+};
+
+template <typename T>
+struct max {
+ T operator() (T x, T y, size_t=0) {return x > y ? x : y;}
+};
+
+template<class T>
+inline T Min(T a, T b)
+{
+ return (a < b) ? a : b;
+}
+
+template<class T>
+inline T Max(T a, T b)
+{
+ return (a > b) ? a : b;
+}
+
+template <typename T>
+struct minbound {
+ camp::pair operator() (camp::pair z, camp::pair w) {
+ return camp::pair(Min(z.getx(),w.getx()),Min(z.gety(),w.gety()));
+ }
+ camp::triple operator() (camp::triple u, camp::triple v) {
+ return camp::triple(Min(u.getx(),v.getx()),Min(u.gety(),v.gety()),
+ Min(u.getz(),v.getz()));
+ }
+};
+
+template <typename T>
+struct maxbound {
+ camp::pair operator() (camp::pair z, camp::pair w) {
+ return camp::pair(Max(z.getx(),w.getx()),Max(z.gety(),w.gety()));
+ }
+ camp::triple operator() (camp::triple u, camp::triple v) {
+ return camp::triple(Max(u.getx(),v.getx()),Max(u.gety(),v.gety()),
+ Max(u.getz(),v.getz()));
+ }
+};
+
+template <double (*func)(double)>
+void realReal(vm::stack *s)
+{
+ double x=vm::pop<double>(s);
+ s->push(func(x));
+}
+
+template <class T, template <class S> class op>
+void binaryOp(vm::stack *s)
+{
+ T b=vm::pop<T>(s);
+ T a=vm::pop<T>(s);
+ s->push(op<T>()(a,b));
+}
+
+template <class T>
+void interp(vm::stack *s)
+{
+ double t=vm::pop<double>(s);
+ T b=vm::pop<T>(s);
+ T a=vm::pop<T>(s);
+ s->push((1-t)*a+t*b);
+}
+
+} // namespace run
+
+#endif //MATHOP_H
+
diff --git a/graphics/asymptote/memory.h b/graphics/asymptote/memory.h
new file mode 100644
index 0000000000..cf6f8f2084
--- /dev/null
+++ b/graphics/asymptote/memory.h
@@ -0,0 +1,201 @@
+/****
+ * memory.h
+ *
+ * Interface to the Boehm Garbage Collector.
+ *****/
+
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#include <list>
+#include <vector>
+#include <stack>
+#include <map>
+#include <deque>
+#include <string>
+#include <sstream>
+
+#ifndef NOHASH
+
+#ifdef HAVE_TR1_UNORDERED_MAP
+
+#include <memory>
+#include <tr1/unordered_map>
+#define EXT std::tr1
+
+#else
+
+#ifdef HAVE_UNORDERED_MAP
+#include <unordered_map>
+#define EXT std
+#else
+#define EXT __gnu_cxx
+#include <ext/hash_map>
+#define unordered_map hash_map
+#define unordered_multimap hash_multimap
+#endif
+
+#endif
+
+#endif
+
+#ifdef __DECCXX_LIBCXX_RH70
+#define CONST
+#else
+#define CONST const
+#endif
+
+#ifdef USEGC
+
+#define GC_THREADS
+#ifdef __clang__
+#define GC_ATTR_EXPLICIT
+#endif
+#include <gc.h>
+
+#ifdef GC_DEBUG
+extern "C" {
+#include <gc_backptr.h>
+}
+#endif
+
+inline void *asy_malloc(size_t n)
+{
+#ifdef GC_DEBUG
+ if(void *mem=GC_debug_malloc_ignore_off_page(n, GC_EXTRAS))
+#else
+ if(void *mem=GC_malloc_ignore_off_page(n))
+#endif
+ return mem;
+ throw std::bad_alloc();
+}
+
+inline void *asy_malloc_atomic(size_t n)
+{
+#ifdef GC_DEBUG
+ if(void *mem=GC_debug_malloc_atomic_ignore_off_page(n, GC_EXTRAS))
+#else
+ if(void *mem=GC_malloc_atomic_ignore_off_page(n))
+#endif
+ return mem;
+ throw std::bad_alloc();
+}
+
+#undef GC_MALLOC
+#undef GC_MALLOC_ATOMIC
+
+#define GC_MALLOC(sz) asy_malloc(sz)
+#define GC_MALLOC_ATOMIC(sz) asy_malloc_atomic(sz)
+
+#include <gc_allocator.h>
+#include <gc_cpp.h>
+
+#define gc_allocator gc_allocator_ignore_off_page
+
+#else // USEGC
+
+using std::allocator;
+#define gc_allocator allocator
+
+class gc {};
+class gc_cleanup {};
+
+enum GCPlacement {UseGC, NoGC, PointerFreeGC};
+
+inline void* operator new(size_t size, GCPlacement) {
+ return operator new(size);
+}
+
+inline void* operator new[](size_t size, GCPlacement) {
+ return operator new(size);
+}
+
+template<class T>
+struct GC_type_traits {};
+
+#define GC_DECLARE_PTRFREE(T) \
+ template<> struct GC_type_traits<T> {}
+
+#endif // USEGC
+
+namespace mem {
+
+#define GC_CONTAINER(KIND) \
+ template <typename T> \
+ struct KIND : public std::KIND<T, gc_allocator<T> >, public gc { \
+ KIND() : std::KIND<T, gc_allocator<T> >() {} \
+ KIND(size_t n) : std::KIND<T, gc_allocator<T> >(n) {} \
+ KIND(size_t n, const T& t) : std::KIND<T, gc_allocator<T> >(n,t) {} \
+ }
+
+GC_CONTAINER(list);
+GC_CONTAINER(vector);
+GC_CONTAINER(deque);
+
+template <typename T, typename Container = vector<T> >
+struct stack : public std::stack<T, Container>, public gc {
+};
+
+#define PAIR_ALLOC gc_allocator<std::pair<CONST Key,T> > /* space */
+
+#undef GC_CONTAINER
+
+#define GC_CONTAINER(KIND) \
+ template <typename Key, \
+ typename T, \
+ typename Compare = std::less<Key> > \
+ struct KIND : public std::KIND<Key,T,Compare,PAIR_ALLOC>, public gc \
+ { \
+ KIND() : std::KIND<Key,T,Compare,PAIR_ALLOC> () {} \
+ }
+
+GC_CONTAINER(map);
+GC_CONTAINER(multimap);
+
+#undef GC_CONTAINER
+
+#ifndef NOHASH
+#define GC_CONTAINER(KIND) \
+ template <typename Key, typename T, \
+ typename Hash = EXT::hash<Key>, \
+ typename Eq = std::equal_to<Key> > \
+ struct KIND : public \
+ EXT::KIND<Key,T,Hash,Eq,PAIR_ALLOC>, public gc { \
+ KIND() : EXT::KIND<Key,T,Hash,Eq,PAIR_ALLOC> () {} \
+ KIND(size_t n) \
+ : EXT::KIND<Key,T,Hash,Eq,PAIR_ALLOC> (n) {} \
+ }
+
+GC_CONTAINER(unordered_map);
+GC_CONTAINER(unordered_multimap);
+
+#undef GC_CONTAINER
+#undef EXT
+#endif
+
+#undef PAIR_ALLOC
+
+#ifdef USEGC
+typedef std::basic_string<char,std::char_traits<char>,
+ gc_allocator<char> > string;
+typedef std::basic_stringstream<char,std::char_traits<char>,
+ gc_allocator<char> > stringstream;
+typedef std::basic_istringstream<char,std::char_traits<char>,
+ gc_allocator<char> > istringstream;
+typedef std::basic_ostringstream<char,std::char_traits<char>,
+ gc_allocator<char> > ostringstream;
+typedef std::basic_stringbuf<char,std::char_traits<char>,
+ gc_allocator<char> > stringbuf;
+inline void compact(int x) {GC_set_dont_expand(x);}
+#else
+inline void compact(int x) {}
+typedef std::string string;
+typedef std::stringstream stringstream;
+typedef std::istringstream istringstream;
+typedef std::ostringstream ostringstream;
+typedef std::stringbuf stringbuf;
+#endif // USEGC
+
+} // namespace mem
+
+#endif
diff --git a/graphics/asymptote/mod.h b/graphics/asymptote/mod.h
new file mode 100644
index 0000000000..89d017c6ce
--- /dev/null
+++ b/graphics/asymptote/mod.h
@@ -0,0 +1,41 @@
+/*****
+ * mod.h
+ * Andy Hammerlindl 2005/03/16
+ *
+ * Definition of implementation-independent mod function.
+ *****/
+
+#ifndef MOD_H
+#define MOD_H
+
+#include <cmath>
+
+#include "common.h"
+
+using std::fmod;
+
+inline Int Mod(Int x, Int y) {return x % y;}
+inline double Mod(double x, double y) {return fmod(x,y);}
+
+template<typename T>
+inline T portableMod(T x,T y)
+{
+// Implementation-independent definition of mod; ensure that result has
+// same sign as divisor
+ T val=Mod(x,y);
+ if((y > 0 && val < 0) || (y < 0 && val > 0)) val += y;
+ return val;
+}
+
+inline Int imod(Int x, Int y)
+{
+ return portableMod<Int>(x,y);
+}
+
+inline Int imod(Int i, size_t n) {
+ i %= (Int) n;
+ if(i < 0) i += (Int) n;
+ return i;
+}
+
+#endif
diff --git a/graphics/asymptote/modifier.h b/graphics/asymptote/modifier.h
new file mode 100644
index 0000000000..856da9d5c0
--- /dev/null
+++ b/graphics/asymptote/modifier.h
@@ -0,0 +1,41 @@
+/*****
+ * modifier.h
+ * Andy Hammerlindl 2002/08/29
+ *
+ * Permissions for variables.
+ * PUBLIC means the variable can be read or written anywhere.
+ * RESTRICTED means it can be read anywhere, but written only in the record.
+ * PRIVATE means it can only be accessed in the record.
+ *
+ * The modifiers static declares that variable to be allocated, are allocated in
+ * the parent's frame, and code is translated into the parent's frame.
+ *****/
+
+#ifndef MODIFIER_H
+#define MODIFIER_H
+
+namespace trans {
+
+// Permission tokens defined in camp.y for accessing a variable outside of
+// its lexically enclosing record.
+enum permission {
+ RESTRICTED,
+ PUBLIC,
+ PRIVATE
+};
+
+const permission DEFAULT_PERM=PUBLIC;
+
+enum modifier {
+ DEFAULT_STATIC,
+ DEFAULT_DYNAMIC,
+ EXPLICIT_STATIC,
+ EXPLICIT_DYNAMIC
+};
+
+} // namespace trans
+
+GC_DECLARE_PTRFREE(trans::permission);
+GC_DECLARE_PTRFREE(trans::modifier);
+
+#endif
diff --git a/graphics/asymptote/name.cc b/graphics/asymptote/name.cc
new file mode 100644
index 0000000000..b3853b5a91
--- /dev/null
+++ b/graphics/asymptote/name.cc
@@ -0,0 +1,326 @@
+/*****
+ * name.cc
+ * Andy Hammerlindl2002/07/14
+ *
+ * Qualified names (such as x, f, builtin.sin, a.b.c.d, etc.) can be used
+ * either as variables or a type names. This class stores qualified
+ * names used in nameExp and nameTy in the abstract syntax, and
+ * implements the exp and type functions.
+ *****/
+
+#include "name.h"
+#include "frame.h"
+#include "record.h"
+#include "coenv.h"
+#include "inst.h"
+
+namespace absyntax {
+using namespace types;
+using trans::access;
+using trans::qualifiedAccess;
+using trans::action;
+using trans::READ;
+using trans::WRITE;
+using trans::CALL;
+using vm::inst;
+
+
+types::ty *signatureless(types::ty *t) {
+ if (overloaded *o=dynamic_cast<overloaded *>(t))
+ return o->signatureless();
+ else
+ return (t && !t->getSignature()) ? t : 0;
+}
+
+
+void name::forceEquivalency(action act, coenv &e,
+ types::ty *target, types::ty *source)
+{
+ if (act == READ)
+ e.implicitCast(getPos(), target, source);
+ else if (!equivalent(target, source)) {
+ em.compiler(getPos());
+ em << "type mismatch in variable: "
+ << *target
+ << " vs " << *source;
+ }
+}
+
+frame *name::frameTrans(coenv &e)
+{
+ if (types::ty *t=signatureless(varGetType(e))) {
+ if (t->kind == types::ty_record) {
+ varTrans(READ, e, t);
+ return ((record *)t)->getLevel();
+ }
+ else
+ return 0;
+ }
+ else
+ return tyFrameTrans(e);
+}
+
+
+types::ty *name::getType(coenv &e, bool tacit)
+{
+ types::ty *t=signatureless(varGetType(e));
+ if (!tacit && t && t->kind == ty_error)
+ // Report errors associated with regarding the name as a variable.
+ varTrans(trans::READ, e, t);
+ return t ? t : typeTrans(e, tacit);
+}
+
+
+varEntry *simpleName::getVarEntry(coenv &e)
+{
+ types::ty *t=signatureless(varGetType(e));
+ return t ? e.e.lookupVarByType(id, t) : 0;
+}
+
+void simpleName::varTrans(action act, coenv &e, types::ty *target)
+{
+ varEntry *v = e.e.lookupVarByType(id, target);
+
+ if (v) {
+ v->encode(act, getPos(), e.c);
+ forceEquivalency(act, e, target, v->getType());
+ }
+ else {
+ em.error(getPos());
+ em << "no matching variable of name \'" << id << "\'";
+ }
+}
+
+types::ty *simpleName::varGetType(coenv &e)
+{
+ return e.e.varGetType(id);
+}
+
+trans::varEntry *simpleName::getCallee(coenv &e, signature *sig)
+{
+ varEntry *ve = e.e.lookupVarBySignature(id, sig);
+ return ve;
+}
+
+types::ty *simpleName::typeTrans(coenv &e, bool tacit)
+{
+ types::ty *t = e.e.lookupType(id);
+ if (t) {
+ return t;
+ }
+ else {
+ if (!tacit) {
+ em.error(getPos());
+ em << "no type of name \'" << id << "\'";
+ }
+ return primError();
+ }
+}
+
+tyEntry *simpleName::tyEntryTrans(coenv &e)
+{
+ tyEntry *ent = e.e.lookupTyEntry(id);
+ if (!ent) {
+ em.error(getPos());
+ em << "no type of name \'" << id << "\'";
+ return new tyEntry(primError(), 0, 0, position());
+ }
+ return ent;
+}
+
+frame *simpleName::tyFrameTrans(coenv &e)
+{
+ tyEntry *ent = e.e.lookupTyEntry(id);
+ if (ent && ent->t->kind==types::ty_record && ent->v) {
+ ent->v->encode(READ, getPos(), e.c);
+ return ent->v->getLevel();
+ }
+ else
+ return 0;
+}
+
+void simpleName::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "simpleName '" << id << "'\n";
+}
+
+
+record *qualifiedName::castToRecord(types::ty *t, bool tacit)
+{
+ switch (t->kind) {
+ case ty_overloaded:
+ if (!tacit) {
+ em.compiler(qualifier->getPos());
+ em << "name::getType returned overloaded";
+ }
+ return 0;
+ case ty_record:
+ return (record *)t;
+ case ty_error:
+ return 0;
+ default:
+ if (!tacit) {
+ em.error(qualifier->getPos());
+ em << "type \'" << *t << "\' is not a structure";
+ }
+ return 0;
+ }
+}
+
+bool qualifiedName::varTransVirtual(action act, coenv &e,
+ types::ty *target, types::ty *qt)
+{
+ varEntry *v = qt->virtualField(id, target->getSignature());
+ if (v) {
+ // Push qualifier onto stack.
+ qualifier->varTrans(READ, e, qt);
+
+ v->encode(act, getPos(), e.c);
+
+ // A virtual field was used.
+ return true;
+ }
+
+ // No virtual field.
+ return false;
+}
+
+void qualifiedName::varTransField(action act, coenv &e,
+ types::ty *target, record *r)
+{
+ varEntry *v = r->e.lookupVarByType(id, target);
+
+ if (v) {
+ frame *f = qualifier->frameTrans(e);
+ if (f)
+ v->encode(act, getPos(), e.c, f);
+ else
+ v->encode(act, getPos(), e.c);
+
+ forceEquivalency(act, e, target, v->getType());
+ }
+ else {
+ em.error(getPos());
+ em << "no matching field of name \'" << id << "\' in \'" << *r << "\'";
+ }
+}
+
+void qualifiedName::varTrans(action act, coenv &e, types::ty *target)
+{
+ types::ty *qt = qualifier->getType(e);
+
+ // Use virtual fields if applicable.
+ if (varTransVirtual(act, e, target, qt))
+ return;
+
+ record *r = castToRecord(qt);
+ if (r)
+ varTransField(act, e, target, r);
+}
+
+types::ty *qualifiedName::varGetType(coenv &e)
+{
+ types::ty *qt = qualifier->getType(e, true);
+
+ // Look for virtual fields.
+ types::ty *t = qt->virtualFieldGetType(id);
+ if (t)
+ return t;
+
+ record *r = castToRecord(qt, true);
+ return r ? r->e.varGetType(id) : 0;
+}
+
+trans::varEntry *qualifiedName::getCallee(coenv &e, signature *sig)
+{
+ // getTypeAsCallee is an optimization attempt. We don't try optimizing the
+ // rarer qualifiedName call case.
+ // TODO: See if this is worth implementing.
+ //cout << "FAIL BY QUALIFIED NAME" << endl;
+ return 0;
+}
+
+trans::varEntry *qualifiedName::getVarEntry(coenv &e)
+{
+ varEntry *qv = qualifier->getVarEntry(e);
+
+ types::ty *qt = qualifier->getType(e, true);
+ record *r = castToRecord(qt, true);
+ if (r) {
+ types::ty *t = signatureless(r->e.varGetType(id));
+ varEntry *v = t ? r->e.lookupVarByType(id, t) : 0;
+ return trans::qualifyVarEntry(qv,v);
+ }
+ else
+ return qv;
+}
+
+types::ty *qualifiedName::typeTrans(coenv &e, bool tacit)
+{
+ types::ty *rt = qualifier->getType(e, tacit);
+
+ record *r = castToRecord(rt, tacit);
+ if (!r)
+ return primError();
+
+ tyEntry *ent = r->e.lookupTyEntry(id);
+ if (ent) {
+ if (!tacit)
+ ent->reportPerm(READ, getPos(), e.c);
+ return ent->t;
+ }
+ else {
+ if (!tacit) {
+ em.error(getPos());
+ em << "no matching field or type of name \'" << id << "\' in \'"
+ << *r << "\'";
+ }
+ return primError();
+ }
+}
+
+tyEntry *qualifiedName::tyEntryTrans(coenv &e)
+{
+ types::ty *rt = qualifier->getType(e, false);
+
+ record *r = castToRecord(rt, false);
+ if (!r)
+ return new tyEntry(primError(), 0, 0, position());
+
+ tyEntry *ent = r->e.lookupTyEntry(id);
+ if (!ent) {
+ em.error(getPos());
+ em << "no matching type of name \'" << id << "\' in \'"
+ << *r << "\'";
+ return new tyEntry(primError(), 0, 0, position());
+ }
+ ent->reportPerm(READ, getPos(), e.c);
+
+ return trans::qualifyTyEntry(qualifier->getVarEntry(e), ent);
+}
+
+frame *qualifiedName::tyFrameTrans(coenv &e)
+{
+ frame *f=qualifier->frameTrans(e);
+ tyEntry *ent = e.e.lookupTyEntry(id);
+ if (ent && ent->t->kind==types::ty_record && ent->v) {
+ if (f)
+ ent->v->encode(READ, getPos(), e.c, f);
+ else
+ ent->v->encode(READ, getPos(), e.c);
+ return ent->v->getLevel();
+ }
+ else
+ return f;
+}
+
+void qualifiedName::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "qualifiedName '" << id << "'\n";
+
+ qualifier->prettyprint(out, indent+1);
+}
+
+} // namespace absyntax
diff --git a/graphics/asymptote/name.h b/graphics/asymptote/name.h
new file mode 100644
index 0000000000..a10168d9f4
--- /dev/null
+++ b/graphics/asymptote/name.h
@@ -0,0 +1,170 @@
+/*****
+ * name.h
+ * Andy Hammerlindl 2002/07/14
+ *
+ * Qualified names (such as x, f, builtin.sin, a.b.c.d, etc.) can be used
+ * either as variables or a type names. This class stores qualified
+ * names used in nameExp and nameTy in the abstract syntax, and
+ * implements the exp and type functions.
+ *****/
+
+#ifndef NAME_H
+#define NAME_H
+
+#include "absyn.h"
+#include "types.h"
+#include "frame.h"
+#include "access.h"
+
+namespace trans {
+class coenv;
+class varEntry;
+class tyEntry;
+}
+namespace types {
+class record;
+}
+
+namespace absyntax {
+
+using trans::coenv;
+using trans::action;
+using types::record;
+using std::ostream;
+
+class name : public absyn {
+public:
+ name(position pos)
+ : absyn(pos) {}
+
+ // Helper function - ensures target and source match up, using casting in the
+ // case of a read. Issues errors on failure.
+ void forceEquivalency(action act, coenv &e,
+ types::ty *target, types::ty *source);
+
+ // Used for determining the type when the context does not establish
+ // the name as a variable or a type. First, the function looks for a
+ // non-function variable fitting the description. If one fits, the
+ // type of the variable is returned. Failing that, the function looks
+ // for a fitting type and returns that. If nothing is found, an
+ // appropriate error is reported and ty_error is returned.
+ // Because this is used only on qualifiers (ie. names to the left of a
+ // dot), it does not look at function variables.
+ // Tacit means that no error messages will be reported to the user.
+ virtual types::ty *getType(coenv &e, bool tacit = false);
+
+ // Pushes the highest level frame possible onto the stack. Returning
+ // the frame pushed. If no frame can be pushed, returns 0.
+ // NOTE: This duplicates some functionality with getVarEntry.
+ virtual trans::frame *frameTrans(coenv &e);
+ // Helper function for the case where the name is known to be a type.
+ virtual trans::frame *tyFrameTrans(coenv &e) = 0;
+
+ // Constructs the varEntry part of the tyEntry for the name. Like
+ // getType, this is called on the qualifier, instead of the full name.
+ // This reports no errors, and returns 0 if there is no varEntry to
+ // use.
+ virtual trans::varEntry *getVarEntry(coenv &e) = 0;
+
+ // As a variable:
+ // Translates the name (much like an expression).
+ virtual void varTrans(action act, coenv &e, types::ty *target) = 0;
+ // Returns the possible variable types. Unlike exp, returns 0 if none
+ // match.
+ virtual types::ty *varGetType(coenv &e) = 0;
+ virtual trans::varEntry *getCallee(coenv &e, types::signature *sig) = 0;
+
+ // As a type:
+ // Determines the type, as used in a variable declaration.
+ virtual types::ty *typeTrans(coenv &e, bool tacit = false) = 0;
+ // Constructs the tyEntry of the name, needed so that we know the
+ // parent frame for allocating new objects of that type. Reports
+ // errors as typeTrans() does with tacit=false.
+ virtual trans::tyEntry *tyEntryTrans(coenv &e) = 0;
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+ virtual void print(ostream& out) const {
+ out << "<base name>";
+ }
+
+ virtual symbol getName() = 0;
+};
+
+inline ostream& operator<< (ostream& out, const name& n) {
+ n.print(out);
+ return out;
+}
+
+class simpleName : public name {
+ symbol id;
+
+public:
+ simpleName(position pos, symbol id)
+ : name(pos), id(id) {}
+
+ trans::varEntry *getVarEntry(coenv &e);
+
+ // As a variable:
+ void varTrans(action act, coenv &e, types::ty *target);
+ types::ty *varGetType(coenv &);
+ trans::varEntry *getCallee(coenv &e, types::signature *sig);
+
+ // As a type:
+ types::ty *typeTrans(coenv &e, bool tacit = false);
+ virtual trans::tyEntry *tyEntryTrans(coenv &e);
+ trans::frame *tyFrameTrans(coenv &e);
+
+ void prettyprint(ostream &out, Int indent);
+ void print(ostream& out) const {
+ out << id;
+ }
+ symbol getName() {
+ return id;
+ }
+};
+
+
+class qualifiedName : public name {
+ name *qualifier;
+ symbol id;
+
+ // Gets the record type associated with the qualifier. Reports an
+ // error and returns null if the type is not a record.
+ record *castToRecord(types::ty *t, bool tacit = false);
+
+ // Translates as a virtual field, if possible. qt is the type of the
+ // qualifier. Return true if there was a matching virtual field.
+ bool varTransVirtual(action act, coenv &e,
+ types::ty *target, types::ty *qt);
+
+ // Translates as an ordinary (non-virtual) field of a record, r.
+ void varTransField(action act, coenv &e,
+ types::ty *target, record *r);
+public:
+ qualifiedName(position pos, name *qualifier, symbol id)
+ : name(pos), qualifier(qualifier), id(id) {}
+
+ trans::varEntry *getVarEntry(coenv &e);
+
+ // As a variable:
+ void varTrans(action act, coenv &, types::ty *target);
+ types::ty *varGetType(coenv &);
+ trans::varEntry *getCallee(coenv &e, types::signature *sig);
+
+ // As a type:
+ types::ty *typeTrans(coenv &e, bool tacit = false);
+ trans::tyEntry *tyEntryTrans(coenv &e);
+ trans::frame *tyFrameTrans(coenv &e);
+
+ void prettyprint(ostream &out, Int indent);
+ void print(ostream& out) const {
+ out << *qualifier << "." << id;
+ }
+ symbol getName() {
+ return id;
+ }
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/graphics/asymptote/newexp.cc b/graphics/asymptote/newexp.cc
new file mode 100644
index 0000000000..8105a9d929
--- /dev/null
+++ b/graphics/asymptote/newexp.cc
@@ -0,0 +1,185 @@
+/*****
+ * newexp.cc
+ * Andy Hammerlindl 2003/07/28
+ *
+ * Handles the abstract syntax for expressions the create new objects,
+ * such as record, array, and function constructors.
+ *****/
+
+#include "newexp.h"
+#include "stm.h"
+#include "runtime.h"
+#include "runarray.h"
+#include "coenv.h"
+#include "inst.h"
+
+using namespace types;
+using trans::coder;
+using trans::coenv;
+using vm::inst;
+
+namespace absyntax {
+
+void printFrame(frame *f) {
+ if (f == 0) {
+ cerr << '0';
+ }
+ else {
+ cerr << f << " of ";
+ printFrame(f->getParent());
+ }
+}
+
+void newRecordExp::prettyprint(ostream &out, Int indent) {
+ prettyname(out, "newRecordExp", indent);
+}
+
+bool newRecordExp::encodeLevel(position pos, coenv &e, trans::tyEntry *ent)
+{
+ record *r = dynamic_cast<record *>(ent->t);
+ assert(r);
+
+ // The level needed on which to allocate the record.
+ frame *level = r->getLevel()->getParent();
+
+ if (ent->v) {
+ // Put the record on the stack. For instance, in code like
+ // import imp;
+ // new imp.t;
+ // we are putting the instance of imp on the stack, so we can use it to
+ // allocate an instance of imp.t.
+ ent->v->getLocation()->encode(trans::READ, pos, e.c);
+
+ // Adjust to the right frame. For instance, in the last new in
+ // struct A {
+ // struct B {
+ // static struct C {}
+ // }
+ // B b=new B;
+ // }
+ // A a=new A;
+ // new a.b.C;
+ // we push a.b onto the stack, but need a as the enclosing frame for
+ // allocating an instance of C.
+ record *q = dynamic_cast<record *>(ent->v->getType());
+ return e.c.encode(level, q->getLevel());
+ }
+ else
+ return e.c.encode(level);
+}
+
+types::ty *newRecordExp::transFromTyEntry(position pos, coenv &e,
+ trans::tyEntry *ent)
+{
+ types::ty *t = ent->t;
+ if (t->kind == ty_error)
+ return t;
+ else if (t->kind != ty_record) {
+ em.error(pos);
+ em << "type '" << *t << "' is not a structure";
+ return primError();
+ }
+
+ // Put the enclosing frame on the stack.
+ if (!encodeLevel(pos, e, ent)) {
+ em.error(pos);
+ em << "allocation of struct '" << *t << "' is not in a valid scope";
+ return primError();
+ }
+
+ record *r = dynamic_cast<record *>(t);
+ assert(r);
+
+ // Encode the allocation.
+ e.c.encode(inst::makefunc,r->getInit());
+ e.c.encode(inst::popcall);
+
+ return t;
+}
+
+types::ty *newRecordExp::trans(coenv &e)
+{
+ return transFromTyEntry(getPos(), e, result->transAsTyEntry(e, 0));
+}
+
+types::ty *newRecordExp::getType(coenv &e)
+{
+ types::ty *t = result->trans(e, true);
+ if (t->kind != ty_error && t->kind != ty_record)
+ return primError();
+ else
+ return t;
+}
+
+void newArrayExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"newArrayExp",indent);
+
+ celltype->prettyprint(out, indent+1);
+ if (dimexps) dimexps->prettyprint(out, indent+1);
+ if (dims) dims->prettyprint(out, indent+1);
+ if (ai) ai->prettyprint(out, indent+1);
+}
+
+types::ty *newArrayExp::trans(coenv &e)
+{
+ types::ty *c = celltype->trans(e);
+ if (c->kind == ty_void) {
+ em.error(getPos());
+ em << "cannot declare array of type void";
+ return primError();
+ }
+
+ if (dims)
+ c = dims->truetype(c);
+
+ if (ai) {
+ ai->transToType(e, c);
+ return c;
+ } else if (dimexps || dims) {
+ if (dimexps) {
+ for (size_t i = 0; i < dimexps->size(); ++i) {
+ (*dimexps)[i]->transToType(e, types::primInt());
+ c = new types::array(c);
+ }
+ }
+ if (dims) {
+ for (size_t i = 0; i < dims->size(); ++i) {
+ e.c.encode(inst::intpush,0);
+ }
+ }
+ e.c.encode(inst::intpush,
+ (Int) ((dimexps ? dimexps->size():0)
+ + (dims ? dims->size():0)));
+ e.c.encode(inst::builtin, run::newDeepArray);
+
+ return c;
+ } else {
+ em.compiler(getPos());
+ em << "new array expression must have either dims or dimexps";
+ return primError();
+ }
+}
+
+types::ty *newArrayExp::getType(coenv &e)
+{
+ types::ty *c = celltype->trans(e);
+ if (c->kind == ty_void) {
+ return primError();
+ }
+ if (dims)
+ c = dims->truetype(c);
+
+ if (dimexps) {
+ Int depth = (Int)dimexps->size();
+ while (depth > 0) {
+ c = new types::array(c);
+ depth--;
+ }
+ }
+
+ return c;
+}
+
+
+} // namespace absyntax
diff --git a/graphics/asymptote/newexp.h b/graphics/asymptote/newexp.h
new file mode 100644
index 0000000000..dd64584a6a
--- /dev/null
+++ b/graphics/asymptote/newexp.h
@@ -0,0 +1,60 @@
+/*****
+ * newexp.h
+ * Andy Hammerlindl 2003/07/28
+ *
+ * Handles the abstract syntax for expressions the create new objects,
+ * such as record, array, and function constructors.
+ *****/
+
+#ifndef NEWEXP_H
+#define NEWEXP_H
+
+#include "exp.h"
+#include "dec.h"
+#include "fundec.h"
+#include "entry.h"
+
+namespace absyntax {
+
+typedef fundef newFunctionExp;
+
+class newRecordExp : public exp {
+ ty *result;
+
+ static bool encodeLevel(position pos, coenv &e, trans::tyEntry *ent);
+public:
+ newRecordExp(position pos, ty *result)
+ : exp(pos), result(result) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ static types::ty *transFromTyEntry(position pos, coenv &e,
+ trans::tyEntry *ent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class newArrayExp : public exp {
+ ty *celltype;
+ explist *dimexps;
+ dimensions *dims;
+ arrayinit *ai;
+
+public:
+ newArrayExp(position pos,
+ ty *celltype,
+ explist *dimexps,
+ dimensions *dims,
+ arrayinit *ai)
+ : exp(pos), celltype(celltype), dimexps(dimexps), dims(dims), ai(ai) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/graphics/asymptote/opcodes.h b/graphics/asymptote/opcodes.h
new file mode 100644
index 0000000000..71c0de41aa
--- /dev/null
+++ b/graphics/asymptote/opcodes.h
@@ -0,0 +1,46 @@
+/*****
+ * opcodes.h
+ * Andy Hammerlindl 2010/10/24
+ *
+ * A list of the virtual machine opcodes, defined by the macro OPCODE.
+ *****/
+
+/* The first parameter is the name of the opcode. The second parameter is a
+ * character indicating what additional information (if any) is encoded with
+ * the opcode:
+ * x - nothing
+ * n - integer
+ * t - item
+ * b - builtin
+ * l - lambda pointer
+ * o - instruction offset
+ */
+
+OPCODE(nop, 'x')
+OPCODE(pop,'x')
+OPCODE(intpush,'n')
+OPCODE(constpush,'t')
+OPCODE(varpush,'n')
+OPCODE(varsave,'n')
+OPCODE(fieldpush,'n')
+OPCODE(fieldsave,'n')
+OPCODE(builtin,'b')
+OPCODE(jmp,'o')
+OPCODE(cjmp,'o')
+OPCODE(njmp,'o')
+OPCODE(popcall,'x')
+OPCODE(pushclosure,'x')
+OPCODE(makefunc,'l')
+OPCODE(ret,'x')
+OPCODE(pushframe,'n')
+OPCODE(popframe,'x')
+
+OPCODE(push_default,'x')
+OPCODE(jump_if_not_default,'o')
+
+#ifdef COMBO
+OPCODE(varpop,'n')
+OPCODE(fieldpop,'n')
+
+OPCODE(gejmp,'o')
+#endif
diff --git a/graphics/asymptote/opsymbols.pl b/graphics/asymptote/opsymbols.pl
new file mode 100755
index 0000000000..06491ad1c6
--- /dev/null
+++ b/graphics/asymptote/opsymbols.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+#####
+# opsymbols.pl
+# Andy Hammerlindl 2010/06/01
+#
+# Extract mapping such as '+' --> SYM_PLUS from camp.l
+#####
+
+open(header, ">opsymbols.h") ||
+ die("Couldn't open opsymbols.h for writing");
+
+print header <<END;
+/*****
+ * This file is automatically generated by opsymbols.pl
+ * Changes will be overwritten.
+ *****/
+
+// If the OPSYMBOL macro is not defined for a specific purpose, define it with
+// the default purpose of using SYM_PLUS etc. as external pre-translated
+// symbols.
+
+#ifndef OPSYMBOL
+#define OPSYMBOL(str, name) extern sym::symbol name
+#endif
+
+END
+
+sub add {
+ print header "OPSYMBOL(\"".$_[0]."\", " . $_[1] . ");\n";
+}
+
+open(lexer, "camp.l") ||
+ die("Couldn't open camp.l");
+
+while (<lexer>) {
+ if (m/^"(\S+)"\s*{\s*DEFSYMBOL\((\w+)\);/) {
+ add($1, $2);
+ }
+ if (m/^(\w+)\s*{\s*DEFSYMBOL\((\w+)\);/) {
+ add($1, $2);
+ }
+ if (m/^\s*EXTRASYMBOL\(\s*(\w+)\s*,\s*(\w+)\s*\)/) {
+ add($1, $2);
+ }
+}
+
+print header <<END
+
+/* This file is automatically generated. */
+END
diff --git a/graphics/asymptote/pair.h b/graphics/asymptote/pair.h
new file mode 100644
index 0000000000..4a2ca09d68
--- /dev/null
+++ b/graphics/asymptote/pair.h
@@ -0,0 +1,235 @@
+/*****
+ * pair.h
+ * Andy Hammerlindl 2002/05/16
+ *
+ * Stores a two-dimensional point similar to the pair type in MetaPost.
+ * In some cases, pairs behave as complex numbers.
+ *
+ * A pair is a guide as a pair alone can be used to describe a path.
+ * The solve and subsolve methods are fairly straight forward as solve
+ * returns a path with just the pair and subsolve just adds the pair to
+ * the structure.
+ *****/
+
+#ifndef PAIR_H
+#define PAIR_H
+
+#include <cassert>
+#include <cmath>
+
+#include "common.h"
+#include "angle.h"
+
+namespace camp {
+
+class pair : public gc {
+ double x;
+ double y;
+
+public:
+ pair() : x(0.0), y(0.0) {}
+ pair(double x, double y=0.0) : x(x), y(y) {}
+
+ double getx() const { return x; }
+ double gety() const { return y; }
+
+ bool isreal() {return y == 0;}
+
+ friend pair operator+ (const pair& z, const pair& w)
+ {
+ return pair(z.x+w.x,z.y+w.y);
+ }
+
+ friend pair operator- (const pair& z, const pair& w)
+ {
+ return pair(z.x-w.x,z.y-w.y);
+ }
+
+ friend pair operator- (const pair& z)
+ {
+ return pair(-z.x,-z.y);
+ }
+
+ // Complex multiplication
+ friend pair operator* (const pair& z, const pair& w)
+ {
+ return pair(z.x*w.x-z.y*w.y,z.x*w.y+w.x*z.y);
+ }
+
+ const pair& operator+= (const pair& w)
+ {
+ x += w.x;
+ y += w.y;
+ return *this;
+ }
+
+ const pair& operator-= (const pair& w)
+ {
+ x -= w.x;
+ y -= w.y;
+ return *this;
+ }
+
+ const pair& operator*= (const pair& w)
+ {
+ (*this) = (*this) * w;
+ return (*this);
+ }
+
+ const pair& operator/= (const pair& w)
+ {
+ (*this) = (*this) / w;
+ return (*this);
+ }
+
+ const pair& scale (double xscale, double yscale)
+ {
+ x *= xscale;
+ y *= yscale;
+ return *this;
+ }
+
+ friend pair operator/ (const pair &z, double t)
+ {
+ if (t == 0.0)
+ reportError("division by 0");
+ t=1.0/t;
+ return pair(z.x*t, z.y*t);
+ }
+
+ friend pair operator/ (const pair& z, const pair& w)
+ {
+ if (!w.nonZero())
+ reportError("division by pair (0,0)");
+
+ double t = 1.0 / (w.x*w.x + w.y*w.y);
+ return pair(t*(z.x*w.x + z.y*w.y),
+ t*(-z.x*w.y + w.x*z.y));
+ }
+
+ friend bool operator== (const pair& z, const pair& w)
+ {
+ return z.x == w.x && z.y == w.y;
+ }
+
+ friend bool operator!= (const pair& z, const pair& w)
+ {
+ return z.x != w.x || z.y != w.y;
+ }
+
+ double abs2() const
+ {
+ return x*x + y*y;
+ }
+
+ double length() const
+ {
+ return sqrt(abs2());
+ }
+
+ friend double length(const pair& z)
+ {
+ return z.length();
+ }
+
+ double angle() const
+ {
+ return camp::angle(x,y);
+ }
+
+ friend double angle(const pair& z)
+ {
+ return z.angle();
+ }
+
+ friend pair unit(const pair& z)
+ {
+ double scale=z.length();
+ if(scale == 0.0) return z;
+ scale=1.0/scale;
+ return pair(z.x*scale,z.y*scale);
+ }
+
+ friend pair conj(const pair& z)
+ {
+ return pair(z.x,-z.y);
+ }
+
+ friend double dot(const pair& z, const pair& w)
+ {
+ return z.x*w.x+z.y*w.y;
+ }
+
+ friend double cross(const pair& z, const pair& w)
+ {
+ return z.x*w.y-z.y*w.x;
+ }
+
+// Return the principal branch of the square root (non-negative real part).
+ friend pair Sqrt(const pair& z) {
+ double mag=z.length();
+ if(mag == 0.0) return pair(0.0,0.0);
+ else if(z.x > 0) {
+ double re=sqrt(0.5*(mag+z.x));
+ return pair(re,0.5*z.y/re);
+ } else {
+ double im=sqrt(0.5*(mag-z.x));
+ if(z.y < 0) im=-im;
+ return pair(0.5*z.y/im,im);
+ }
+ }
+
+ bool nonZero() const
+ {
+ return x != 0.0 || y != 0.0;
+ }
+
+ friend istream& operator >> (istream& s, pair& z)
+ {
+ char c;
+ s >> std::ws;
+ bool paren=s.peek() == '('; // parenthesis are optional
+ if(paren) s >> c;
+ s >> z.x >> std::ws;
+ if(!s.eof() && s.peek() == ',') s >> c >> z.y;
+ else z.y=0.0;
+ if(paren) {
+ s >> std::ws;
+ if(s.peek() == ')') s >> c;
+ }
+
+ return s;
+ }
+
+ friend ostream& operator << (ostream& out, const pair& z)
+ {
+ out << "(" << z.x << "," << z.y << ")";
+ return out;
+ }
+
+ friend class box;
+};
+
+// Calculates exp(i * theta), useful for unit vectors.
+inline pair expi(double theta)
+{
+ if(theta == 0.0) return pair(1.0,0.0); // Frequently occurring case
+ return pair(cos(theta),sin(theta));
+}
+
+// Complex exponentiation
+inline pair pow(const pair& z, const pair& w)
+{
+ double u=w.getx();
+ double v=w.gety();
+ if(z == 0.0) return w == 0.0 ? 1.0 : 0.0;
+ double logr=0.5*log(z.abs2());
+ double th=z.angle();
+ return exp(logr*u-th*v)*expi(logr*v+th*u);
+}
+
+} //namespace camp
+
+GC_DECLARE_PTRFREE(camp::pair);
+
+#endif
diff --git a/graphics/asymptote/parser.cc b/graphics/asymptote/parser.cc
new file mode 100644
index 0000000000..c12a47c50e
--- /dev/null
+++ b/graphics/asymptote/parser.cc
@@ -0,0 +1,180 @@
+/*****
+ * parser.cc
+ * Tom Prince 2004/01/10
+ *
+ *****/
+
+#include <fstream>
+#include <sstream>
+#include <cstring>
+#include <fcntl.h>
+
+#include "common.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "interact.h"
+#include "locate.h"
+#include "errormsg.h"
+#include "parser.h"
+#include "util.h"
+
+// The lexical analysis and parsing functions used by parseFile.
+void setlexer(size_t (*input) (char* bif, size_t max_size), string filename);
+extern bool yyparse(void);
+extern int yydebug;
+extern int yy_flex_debug;
+extern bool lexerEOF();
+extern void reportEOF();
+extern bool hangup;
+
+static int fd;
+
+namespace parser {
+
+static FILE *fin=NULL;
+
+namespace yy { // Lexers
+
+std::streambuf *sbuf = NULL;
+
+size_t stream_input(char *buf, size_t max_size)
+{
+ return sbuf ? sbuf->sgetn(buf,max_size) : 0;
+}
+
+int fpeek(int fd)
+{
+ int flags=fcntl(fd,F_GETFL,0);
+ fcntl(fd,F_SETFL,flags | O_NONBLOCK);
+ char c=fgetc(fin);
+ ungetc(c,fin);
+ fcntl(fd,F_SETFL,flags & ~O_NONBLOCK);
+ return c;
+}
+
+size_t pipe_input(char *buf, size_t max_size)
+{
+ if(hangup && fpeek(fd) == EOF) {hangup=false; return 0;}
+ fgets(buf,max_size-1,fin);
+ return strlen(buf);
+}
+
+} // namespace yy
+
+void debug(bool state)
+{
+ // For debugging the machine-generated lexer and parser.
+ yy_flex_debug = yydebug = state;
+}
+
+namespace {
+void error(const string& filename)
+{
+ em.sync();
+ em << "error: could not load module '" << filename << "'\n";
+ em.sync();
+ throw handled_error();
+}
+}
+
+absyntax::file *doParse(size_t (*input) (char* bif, size_t max_size),
+ const string& filename, bool extendable=false)
+{
+ setlexer(input,filename);
+ absyntax::file *root = yyparse() == 0 ? absyntax::root : 0;
+ absyntax::root = 0;
+ yy::sbuf = 0;
+
+ if (!root) {
+ if (lexerEOF()) {
+ if (extendable) {
+ return 0;
+ } else {
+ // Have the lexer report the error.
+ reportEOF();
+ }
+ }
+
+ em.error(nullPos);
+ if(!interact::interactive)
+ error(filename);
+ else
+ throw handled_error();
+ }
+
+ return root;
+}
+
+absyntax::file *parseStdin()
+{
+ debug(false);
+
+ if(!fin) {
+ fd=intcast(settings::getSetting<Int>("inpipe"));
+ if(fd >= 0)
+ fin=fdopen(fd,"r");
+ }
+
+ if(fin)
+ return doParse(yy::pipe_input,"-");
+ else {
+ yy::sbuf = cin.rdbuf();
+ return doParse(yy::stream_input,"-");
+ }
+}
+
+absyntax::file *parseFile(const string& filename,
+ const char *nameOfAction)
+{
+ if(filename == "-")
+ return parseStdin();
+
+ string file = settings::locateFile(filename);
+
+ if(file.empty())
+ error(filename);
+
+ if(nameOfAction && settings::verbose > 1)
+ cerr << nameOfAction << " " << filename << " from " << file << endl;
+
+ debug(false);
+
+ std::filebuf filebuf;
+ if(!filebuf.open(file.c_str(),std::ios::in))
+ error(filename);
+
+#ifdef HAVE_SYS_STAT_H
+ // Check that the file is not a directory.
+ static struct stat buf;
+ if(stat(file.c_str(),&buf) == 0) {
+ if(S_ISDIR(buf.st_mode))
+ error(filename);
+ }
+#endif
+
+ // Check that the file can actually be read.
+ try {
+ filebuf.sgetc();
+ } catch (...) {
+ error(filename);
+ }
+
+ yy::sbuf = &filebuf;
+ return doParse(yy::stream_input,file);
+}
+
+absyntax::file *parseString(const string& code,
+ const string& filename,
+ bool extendable)
+{
+ debug(false);
+ stringbuf buf(code);
+ yy::sbuf = &buf;
+ return doParse(yy::stream_input,filename,extendable);
+}
+
+} // namespace parser
+
diff --git a/graphics/asymptote/parser.h b/graphics/asymptote/parser.h
new file mode 100644
index 0000000000..b297d5e86c
--- /dev/null
+++ b/graphics/asymptote/parser.h
@@ -0,0 +1,29 @@
+/*****
+ * parser.h
+ * Tom Prince 2004/01/10
+ *
+ *****/
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include "common.h"
+#include "absyn.h"
+
+namespace parser {
+
+// Opens and parses the file returning the abstract syntax tree. If
+// there is an unrecoverable parse error, returns null.
+absyntax::file *parseFile(const string& filename,
+ const char *nameOfAction);
+
+// Parses string and returns the abstract syntax tree. Any error in lexing or
+// parsing will be reported and a handled_error thrown. If the string is
+// "extendable", then a parse error simply due to running out of input will not
+// throw an exception, but will return null.
+absyntax::file *parseString(const string& code,
+ const string& filename,
+ bool extendable=false);
+} // namespace parser
+
+#endif // PARSER_H
diff --git a/graphics/asymptote/patches/README b/graphics/asymptote/patches/README
new file mode 100644
index 0000000000..f7e67aad98
--- /dev/null
+++ b/graphics/asymptote/patches/README
@@ -0,0 +1,23 @@
+The optional patches to flex-2.5.31 and bison-2.0a in this directory fix a
+number of problems with warning and/or error messages generated by strict
+compilers.
+
+A modified version of dvipdf that accepts common dvips options is included.
+
+The file gcc3.3.2curses.patch can be used to patch the broken curses.h header
+files (or a local copy thereof in the current directory) on some AIX and
+IRIX systems.
+
+The file gc6.8_AIX.patch fixes an incorrect Boehm garbage collector
+prototype in the file gc6.8/include/gc.h (version 6.8).
+
+The file gc-7.0nomem.patch avoids segmentation faults with gc-7.0 on
+out-of-memory errors.
+
+The file cygwin_freeglut-3.0.0.patch fixes undefined symbols when compiling the
+freeglut library statically under cygwin.
+
+The file fixmem.reg patches the Microsoft Windows registry so that the
+cygwin1.dll library can allocate more than 384MB. It is applied
+automatically by the Asymptote setup.exe file but may also be applied manually:
+regedit /s fixmem.reg
diff --git a/graphics/asymptote/patches/bison.patch b/graphics/asymptote/patches/bison.patch
new file mode 100644
index 0000000000..5f7e4fe1dc
--- /dev/null
+++ b/graphics/asymptote/patches/bison.patch
@@ -0,0 +1,206 @@
+diff -ru bison-2.0a/data/yacc.c bison-2.0aJ/data/yacc.c
+--- bison-2.0a/data/yacc.c 2005-05-21 11:12:32.000000000 -0600
++++ bison-2.0aJ/data/yacc.c 2005-06-30 18:14:16.509158136 -0600
+@@ -237,7 +237,7 @@
+
+ # ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
++# define YYSTACK_FREE(Ptr) { /* empty */; }
+ # ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+@@ -291,19 +291,20 @@
+ /* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+ # ifndef YYCOPY
+-# if defined (__GNUC__) && 1 < __GNUC__
++# if defined (__GNUC__)
++# if 1 < __GNUC__
+ # define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+-# else
++# endif
++# endif
++# endif
++# ifndef YYCOPY
+ # define YYCOPY(To, From, Count) \
+- do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+- } \
+- while (0)
+-# endif
++ }
+ # endif
+
+ /* Relocate STACK from its old location to the new one. The
+@@ -312,15 +313,13 @@
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+ # define YYSTACK_RELOCATE(Stack) \
+- do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+- } \
+- while (0)
++ }
+
+ #endif
+
+@@ -487,6 +486,7 @@
+ #define YYACCEPT goto yyacceptlab
+ #define YYABORT goto yyabortlab
+ #define YYERROR goto yyerrorlab
++int yy_false=false; /* Used to suppress compiler warning about unused label */
+
+
+ /* Like YYERROR except do call yyerror. This remains here temporarily
+@@ -498,7 +498,7 @@
+ #define YYRECOVERING() (!!yyerrstatus)
+
+ #define YYBACKUP(Token, Value) \
+-do \
++{ \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+@@ -512,7 +512,7 @@
+ yyerror (]b4_yyerror_args[_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+-while (0)
++}
+
+
+ #define YYTERROR 1
+@@ -526,7 +526,7 @@
+ #define YYRHSLOC(Rhs, K) ((Rhs)[K])
+ #ifndef YYLLOC_DEFAULT
+ # define YYLLOC_DEFAULT(Current, Rhs, N) \
+- do \
++ { \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+@@ -541,7 +541,7 @@
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+- while (0)
++ }
+ #endif
+
+
+@@ -550,7 +550,7 @@
+ we won't break user code: when these are the locations we know. */
+
+ #ifndef YY_LOCATION_PRINT
+-# if YYLTYPE_IS_TRIVIAL
++# ifdef YYLTYPE_IS_TRIVIAL
+ # define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+@@ -578,13 +578,13 @@
+ # endif
+
+ # define YYDPRINTF(Args) \
+-do { \
++{ \
+ if (yydebug) \
+ YYFPRINTF Args; \
+-} while (0)
++}
+
+ # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+-do { \
++{ \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+@@ -592,7 +592,7 @@
+ Type, Value]b4_location_if([, Location])[); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+-} while (0)
++}
+
+ /*------------------------------------------------------------------.
+ | yy_stack_print -- Print the state stack from its BOTTOM up to its |
+@@ -610,10 +610,10 @@
+ }
+
+ # define YY_STACK_PRINT(Bottom, Top) \
+-do { \
++{ \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+-} while (0)
++}
+
+
+ /*------------------------------------------------.
+@@ -634,10 +634,10 @@
+ }
+
+ # define YY_REDUCE_PRINT(Rule) \
+-do { \
++{ \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+-} while (0)
++}
+
+ /* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+@@ -826,7 +826,7 @@
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+- int yylen;
++ int yylen=0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+@@ -874,7 +874,7 @@
+ yyssp++;
+
+ yysetstate:
+- *yyssp = yystate;
++ *yyssp = (short int) yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+@@ -1222,12 +1222,6 @@
+ `---------------------------------------------------*/
+ yyerrorlab:
+
+- /* Pacify compilers like GCC when the user code never invokes
+- YYERROR and the label yyerrorlab therefore never appears in user
+- code. */
+- if (0)
+- goto yyerrorlab;
+-
+ ]b4_location_if([[ yyerror_range[0] = yylsp[1-yylen];
+ yylsp -= yylen;
+ ]])[yyvsp -= yylen;
+@@ -1297,6 +1291,13 @@
+ `-----------------------------------*/
+ yyabortlab:
+ yyresult = 1;
++
++ /* Pacify compilers like GCC when the user code never invokes
++ YYERROR and the label yyerrorlab therefore never appears in user
++ code. */
++ if (yy_false)
++ goto yyerrorlab;
++
+ goto yyreturn;
+
+ #ifndef yyoverflow
diff --git a/graphics/asymptote/patches/cygwin_freeglut-3.0.0.patch b/graphics/asymptote/patches/cygwin_freeglut-3.0.0.patch
new file mode 100644
index 0000000000..bd27dfe356
--- /dev/null
+++ b/graphics/asymptote/patches/cygwin_freeglut-3.0.0.patch
@@ -0,0 +1,48 @@
+diff -ru freeglut-3.0.0/CMakeLists.txt freeglut-3.0.0J/CMakeLists.txt
+--- freeglut-3.0.0/CMakeLists.txt 2015-02-17 23:59:57.000000000 -0500
++++ freeglut-3.0.0J/CMakeLists.txt 2019-01-20 22:15:55.410415400 -0500
+@@ -20,7 +20,7 @@
+ set(VERSION_MAJOR 3)
+ set(VERSION_MINOR 0)
+ set(VERSION_PATCH 0)
+-
++set(WIN32 1)
+ # Update fg_version.h to match the versions number here in cmake
+ CONFIGURE_FILE(src/fg_version.h.in src/fg_version.h)
+
+@@ -32,7 +32,7 @@
+ # FREEGLUT_BUILD_SHARED_LIBS is already a standard CMake variable, but we need to
+ # re-declare it here so it will show up in the GUI.
+ # by default, we want to build both
+-OPTION(FREEGLUT_BUILD_SHARED_LIBS "Build FreeGLUT shared library." ON)
++OPTION(FREEGLUT_BUILD_SHARED_LIBS "Build FreeGLUT shared library." OFF)
+ OPTION(FREEGLUT_BUILD_STATIC_LIBS "Build FreeGLUT static library." ON)
+
+ # option for whether warnings and errors should be printed
+@@ -439,7 +439,7 @@
+
+
+ # Optionally build demos, on by default.
+-option( FREEGLUT_BUILD_DEMOS "Build FreeGLUT demos." ON )
++option( FREEGLUT_BUILD_DEMOS "Build FreeGLUT demos." OFF )
+
+ SET(DEMO_LIBS ${OPENGL_glu_LIBRARY} ${LIBS})
+ # lib m for math, not needed on windows
+Only in freeglut-3.0.0J: CMakeLists.txt~
+diff -ru freeglut-3.0.0/src/fg_internal.h freeglut-3.0.0J/src/fg_internal.h
+--- freeglut-3.0.0/src/fg_internal.h 2014-12-22 11:27:02.000000000 -0500
++++ freeglut-3.0.0J/src/fg_internal.h 2019-01-20 22:13:40.317578700 -0500
+@@ -24,6 +24,13 @@
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
++#define FREEGLUT_EXPORTS 1
++
++#define TARGET_HOST_MS_WINDOWS 1
++
++#define GCL_HCURSOR (-12)
++#define _snprintf snprintf
++
+
+ #ifndef FREEGLUT_INTERNAL_H
+ #define FREEGLUT_INTERNAL_H
diff --git a/graphics/asymptote/patches/dvipdf b/graphics/asymptote/patches/dvipdf
new file mode 100755
index 0000000000..36dbe4206b
--- /dev/null
+++ b/graphics/asymptote/patches/dvipdf
@@ -0,0 +1,54 @@
+#!/bin/sh
+# $Id$
+# Convert DVI to PDF.
+#
+# Please contact Andrew Ford <A.Ford@ford-mason.co.uk> with any questions
+# about this file.
+#
+# Based on ps2pdf
+
+# This definition is changed on install to match the
+# executable name set in the makefile
+GS_EXECUTABLE=gs
+
+
+OPTIONS="-DSAFER -P"
+DVIPSOPTIONS=""
+while true
+do
+ case "$1" in
+ -R*) DVIPSOPTIONS="$DVIPSOPTIONS $1";;
+ -z) DVIPSOPTIONS="$DVIPSOPTIONS -z" ;;
+ -pp) shift; DVIPSOPTIONS="$DVIPSOPTIONS -pp $1" ;;
+ -p) shift; DVIPSOPTIONS="$DVIPSOPTIONS -p $1" ;;
+ -t) shift; DVIPSOPTIONS="$DVIPSOPTIONS -t $1" ;;
+ -T) shift; DVIPSOPTIONS="$DVIPSOPTIONS -T $1" ;;
+ -l) shift; DVIPSOPTIONS="$DVIPSOPTIONS -l $1" ;;
+ -?*) OPTIONS="$OPTIONS $1" ;;
+ *) break ;;
+ esac
+ shift
+done
+
+if [ $# -lt 1 -o $# -gt 2 ]; then
+ echo "Usage: `basename $0` [options...] input.dvi [output.pdf]" 1>&2
+ exit 1
+fi
+
+infile=$1;
+
+if [ $# -eq 1 ]
+then
+ case "${infile}" in
+ *.dvi) base=`basename "${infile}" .dvi` ;;
+ *) base=`basename "${infile}"` ;;
+ esac
+ outfile="${base}".pdf
+else
+ outfile=$2
+fi
+
+# We have to include the options twice because -I only takes effect if it
+# appears before other options.
+exec dvips $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite -
+
diff --git a/graphics/asymptote/patches/fixmem.reg b/graphics/asymptote/patches/fixmem.reg
new file mode 100644
index 0000000000..bdf09d9ad1
--- /dev/null
+++ b/graphics/asymptote/patches/fixmem.reg
@@ -0,0 +1,4 @@
+Windows Registry Editor Version 5.00
+
+[HKEY_LOCAL_MACHINE\Software\Cygwin]
+"heap_chunk_in_mb"=dword:ffffff00
diff --git a/graphics/asymptote/patches/flex.patch b/graphics/asymptote/patches/flex.patch
new file mode 100644
index 0000000000..56a2d4d5c4
--- /dev/null
+++ b/graphics/asymptote/patches/flex.patch
@@ -0,0 +1,50 @@
+diff -u flex-2.5.39/gen.c flex-2.5.39J/gen.c
+--- flex-2.5.39/gen.c 2014-03-26 06:46:44.000000000 -0600
++++ flex-2.5.39J/gen.c 2014-04-26 10:52:30.962073096 -0600
+@@ -55,6 +55,14 @@
+ * 0 elements of its arrays, too.)
+ */
+
++static const char *get_yy_char_decl (void)
++{
++ return (gentables)
++ ? "static yyconst YY_CHAR %s[%d] =\n { 0,\n"
++ : "static yyconst YY_CHAR * %s = 0;\n";
++}
++
++
+ static const char *get_int16_decl (void)
+ {
+ return (gentables)
+@@ -465,7 +473,7 @@
+ register int i, j;
+ int numrows;
+
+- out_str_dec (get_int32_decl (), "yy_ec", csize);
++ out_str_dec (get_yy_char_decl (), "yy_ec", csize);
+
+ for (i = 1; i < csize; ++i) {
+ ecgroup[i] = ABS (ecgroup[i]);
+@@ -1271,7 +1279,7 @@
+ fputs (_("\n\nMeta-Equivalence Classes:\n"),
+ stderr);
+
+- out_str_dec (get_int32_decl (), "yy_meta", numecs + 1);
++ out_str_dec (get_yy_char_decl (), "yy_meta", numecs + 1);
+ buf_prints (&yydmap_buf,
+ "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n",
+ "flex_int32_t");
+@@ -1516,11 +1524,11 @@
+ if (yymore_used && !yytext_is_array) {
+ indent_puts ("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\");
+ indent_puts
+- ("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\");
++ ("yyleng = (int) (yy_cp - YY_G(yytext_ptr)); \\");
+ }
+
+ else
+- indent_puts ("yyleng = (size_t) (yy_cp - yy_bp); \\");
++ indent_puts ("yyleng = (int) (yy_cp - yy_bp); \\");
+
+ /* Now also deal with copying yytext_ptr to yytext if needed. */
+ skelout (); /* %% [3.0] - break point in skel */
diff --git a/graphics/asymptote/patches/gc-7.0nomem.patch b/graphics/asymptote/patches/gc-7.0nomem.patch
new file mode 100644
index 0000000000..4cc2058f4c
--- /dev/null
+++ b/graphics/asymptote/patches/gc-7.0nomem.patch
@@ -0,0 +1,21 @@
+*** gc_hdrs.h.orig Tue Jun 5 14:01:25 2007
+--- gc_hdrs.h Thu Oct 18 14:32:03 2007
+***************
+*** 112,119 ****
+ hhdr = hce -> hce_hdr; \
+ } else { \
+ hhdr = HEADER_CACHE_MISS(p, hce, source); \
+- if (0 == hhdr) goto exit_label; \
+ } \
+ }
+
+ typedef struct bi {
+--- 112,119 ----
+ hhdr = hce -> hce_hdr; \
+ } else { \
+ hhdr = HEADER_CACHE_MISS(p, hce, source); \
+ } \
++ if (0 == hhdr) goto exit_label; \
+ }
+
+ typedef struct bi {
diff --git a/graphics/asymptote/patches/gc6.8_AIX.patch b/graphics/asymptote/patches/gc6.8_AIX.patch
new file mode 100644
index 0000000000..4fdddd81c7
--- /dev/null
+++ b/graphics/asymptote/patches/gc6.8_AIX.patch
@@ -0,0 +1,7 @@
+*** gc.h.orig Fri Jul 7 18:10:16 2006
+--- gc.h Mon Feb 12 12:30:48 2007
+***************
+*** 981 ****
+! # define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); }
+--- 981 ----
+! # define GC_INIT() { GC_add_roots((char *) GC_DATASTART, (char *) GC_DATAEND); }
diff --git a/graphics/asymptote/patches/gcc3.3.2curses.patch b/graphics/asymptote/patches/gcc3.3.2curses.patch
new file mode 100644
index 0000000000..34d75aaa48
--- /dev/null
+++ b/graphics/asymptote/patches/gcc3.3.2curses.patch
@@ -0,0 +1,7 @@
+*** curses.h.orig Sun Feb 11 21:43:36 2007
+--- curses.h Sun Feb 11 21:43:21 2007
+***************
+*** 1302 ****
+! #if defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus) || defined (__STRICT_ANSI__)
+--- 1302 ----
+! #if 0 && (defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus) || defined (__STRICT_ANSI__))
diff --git a/graphics/asymptote/path.cc b/graphics/asymptote/path.cc
new file mode 100644
index 0000000000..75b084fa36
--- /dev/null
+++ b/graphics/asymptote/path.cc
@@ -0,0 +1,1355 @@
+/*****
+ * path.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores and returns information on a predefined path.
+ *
+ * When changing the path algorithms, also update the corresponding
+ * three-dimensional algorithms in path3.cc.
+ *****/
+
+#include "path.h"
+#include "util.h"
+#include "angle.h"
+#include "camperror.h"
+#include "mathop.h"
+#include "predicates.h"
+#include "rounding.h"
+
+namespace camp {
+
+const double Fuzz2=1000.0*DBL_EPSILON;
+const double Fuzz=sqrt(Fuzz2);
+const double Fuzz4=Fuzz2*Fuzz2;
+const double BigFuzz=10.0*Fuzz2;
+const double fuzzFactor=100.0;
+
+const double third=1.0/3.0;
+
+path nullpath;
+
+const char *nopoints="nullpath has no points";
+
+void checkEmpty(Int n) {
+ if(n == 0)
+ reportError(nopoints);
+}
+
+// Accurate computation of sqrt(1+x)-1.
+inline double sqrt1pxm1(double x)
+{
+ return x/(sqrt(1.0+x)+1.0);
+}
+inline pair sqrt1pxm1(pair x)
+{
+ return x/(Sqrt(1.0+x)+1.0);
+}
+
+// Solve for the real roots of the quadratic equation ax^2+bx+c=0.
+quadraticroots::quadraticroots(double a, double b, double c)
+{
+ // Remove roots at numerical infinity.
+ if(fabs(a) <= Fuzz2*fabs(b)+Fuzz4*fabs(c)) {
+ if(fabs(b) > Fuzz2*fabs(c)) {
+ distinct=quadraticroots::ONE;
+ roots=1;
+ t1=-c/b;
+ } else if(c == 0.0) {
+ distinct=quadraticroots::MANY;
+ roots=1;
+ t1=0.0;
+ } else {
+ distinct=quadraticroots::NONE;
+ roots=0;
+ }
+ } else {
+ double factor=0.5*b/a;
+ double denom=b*factor;
+ if(fabs(denom) <= Fuzz2*fabs(c)) {
+ double x=-c/a;
+ if(x >= 0.0) {
+ distinct=quadraticroots::TWO;
+ roots=2;
+ t2=sqrt(x);
+ t1=-t2;
+ } else {
+ distinct=quadraticroots::NONE;
+ roots=0;
+ }
+ } else {
+ double x=-2.0*c/denom;
+ if(x > -1.0) {
+ distinct=quadraticroots::TWO;
+ roots=2;
+ double r2=factor*sqrt1pxm1(x);
+ double r1=-r2-2.0*factor;
+ if(r1 <= r2) {
+ t1=r1;
+ t2=r2;
+ } else {
+ t1=r2;
+ t2=r1;
+ }
+ } else if(x == -1.0) {
+ distinct=quadraticroots::ONE;
+ roots=2;
+ t1=t2=-factor;
+ } else {
+ distinct=quadraticroots::NONE;
+ roots=0;
+ }
+ }
+ }
+}
+
+// Solve for the complex roots of the quadratic equation ax^2+bx+c=0.
+Quadraticroots::Quadraticroots(pair a, pair b, pair c)
+{
+ if(a == 0.0) {
+ if(b != 0.0) {
+ roots=1;
+ z1=-c/b;
+ } else if(c == 0.0) {
+ roots=1;
+ z1=0.0;
+ } else
+ roots=0;
+ } else {
+ roots=2;
+ pair factor=0.5*b/a;
+ pair denom=b*factor;
+ if(denom == 0.0) {
+ z1=Sqrt(-c/a);
+ z2=-z1;
+ } else {
+ z1=factor*sqrt1pxm1(-2.0*c/denom);
+ z2=-z1-2.0*factor;
+ }
+ }
+}
+
+inline bool goodroot(double a, double b, double c, double t)
+{
+ return goodroot(t) && quadratic(a,b,c,t) >= 0.0;
+}
+
+// Accurate computation of cbrt(sqrt(1+x)+1)-cbrt(sqrt(1+x)-1).
+inline double cbrtsqrt1pxm(double x)
+{
+ double s=sqrt1pxm1(x);
+ return 2.0/(cbrt(x+2.0*(sqrt(1.0+x)+1.0))+cbrt(x)+cbrt(s*s));
+}
+
+// Taylor series of cos((atan(1.0/w)+pi)/3.0).
+static inline double costhetapi3(double w)
+{
+ static const double c1=1.0/3.0;
+ static const double c3=-19.0/162.0;
+ static const double c5=425.0/5832.0;
+ static const double c7=-16829.0/314928.0;
+ double w2=w*w;
+ double w3=w2*w;
+ double w5=w3*w2;
+ return c1*w+c3*w3+c5*w5+c7*w5*w2;
+}
+
+// Solve for the real roots of the cubic equation ax^3+bx^2+cx+d=0.
+cubicroots::cubicroots(double a, double b, double c, double d)
+{
+ static const double ninth=1.0/9.0;
+ static const double fiftyfourth=1.0/54.0;
+
+ // Remove roots at numerical infinity.
+ if(fabs(a) <= Fuzz2*(fabs(b)+fabs(c)*Fuzz2+fabs(d)*Fuzz4)) {
+ quadraticroots q(b,c,d);
+ roots=q.roots;
+ if(q.roots >= 1) t1=q.t1;
+ if(q.roots == 2) t2=q.t2;
+ return;
+ }
+
+ // Detect roots at numerical zero.
+ if(fabs(d) <= Fuzz2*(fabs(c)+fabs(b)*Fuzz2+fabs(a)*Fuzz4)) {
+ quadraticroots q(a,b,c);
+ roots=q.roots+1;
+ t1=0;
+ if(q.roots >= 1) t2=q.t1;
+ if(q.roots == 2) t3=q.t2;
+ return;
+ }
+
+ b /= a;
+ c /= a;
+ d /= a;
+
+ double b2=b*b;
+ double Q=3.0*c-b2;
+ if(fabs(Q) < Fuzz2*(3.0*fabs(c)+fabs(b2)))
+ Q=0.0;
+
+ double R=(3.0*Q+b2)*b-27.0*d;
+ if(fabs(R) < Fuzz2*((3.0*fabs(Q)+fabs(b2))*fabs(b)+27.0*fabs(d)))
+ R=0.0;
+
+ Q *= ninth;
+ R *= fiftyfourth;
+
+ double Q3=Q*Q*Q;
+ double R2=R*R;
+ double D=Q3+R2;
+ double mthirdb=-b*third;
+
+ if(D > 0.0) {
+ roots=1;
+ t1=mthirdb;
+ if(R2 != 0.0) t1 += cbrt(R)*cbrtsqrt1pxm(Q3/R2);
+ } else {
+ roots=3;
+ double v=0.0,theta;
+ if(R2 > 0.0) {
+ v=sqrt(-D/R2);
+ theta=atan(v);
+ } else theta=0.5*PI;
+ double factor=2.0*sqrt(-Q)*(R >= 0 ? 1 : -1);
+
+ t1=mthirdb+factor*cos(third*theta);
+ t2=mthirdb-factor*cos(third*(theta-PI));
+ t3=mthirdb;
+ if(R2 > 0.0)
+ t3 -= factor*((v < 100.0) ? cos(third*(theta+PI)) : costhetapi3(1.0/v));
+ }
+}
+
+pair path::point(double t) const
+{
+ checkEmpty(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].point;
+ else if (i >= n-1)
+ return nodes[n-1].point;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ pair a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ abc = one_t*ab + t*bc,
+ bcd = one_t*bc + t*cd,
+ abcd = one_t*abc + t*bcd;
+
+ return abcd;
+}
+
+pair path::precontrol(double t) const
+{
+ checkEmpty(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].pre;
+ else if (i >= n-1)
+ return nodes[n-1].pre;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ pair a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ abc = one_t*ab + t*bc;
+
+ return (abc == a) ? nodes[i].pre : abc;
+}
+
+
+pair path::postcontrol(double t) const
+{
+ checkEmpty(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].post;
+ else if (i >= n-1)
+ return nodes[n-1].post;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ pair b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ bcd = one_t*bc + t*cd;
+
+ return (bcd == d) ? nodes[iplus].post : bcd;
+}
+
+path path::reverse() const
+{
+ mem::vector<solvedKnot> nodes(n);
+ Int len=length();
+ for (Int i = 0, j = len; i < n; i++, j--) {
+ nodes[i].pre = postcontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = precontrol(j);
+ nodes[i].straight = straight(j-1);
+ }
+ return path(nodes, n, cycles);
+}
+
+path path::subpath(Int a, Int b) const
+{
+ if(empty()) return path();
+
+ if (a > b) {
+ const path &rp = reverse();
+ Int len=length();
+ path result = rp.subpath(len-a, len-b);
+ return result;
+ }
+
+ if (!cycles) {
+ if (a < 0) {
+ a = 0;
+ if(b < 0)
+ b = 0;
+ }
+ if (b > n-1) {
+ b = n-1;
+ if(a > b)
+ a = b;
+ }
+ }
+
+ Int sn = b-a+1;
+ mem::vector<solvedKnot> nodes(sn);
+
+ for (Int i = 0, j = a; j <= b; i++, j++) {
+ nodes[i].pre = precontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = postcontrol(j);
+ nodes[i].straight = straight(j);
+ }
+ nodes[0].pre = nodes[0].point;
+ nodes[sn-1].post = nodes[sn-1].point;
+
+ return path(nodes, sn);
+}
+
+inline pair split(double t, const pair& x, const pair& y) { return x+(y-x)*t; }
+
+inline void splitCubic(solvedKnot sn[], double t, const solvedKnot& left_,
+ const solvedKnot& right_)
+{
+ solvedKnot &left=(sn[0]=left_), &mid=sn[1], &right=(sn[2]=right_);
+ if(left.straight) {
+ mid.point=split(t,left.point,right.point);
+ pair deltaL=third*(mid.point-left.point);
+ left.post=left.point+deltaL;
+ mid.pre=mid.point-deltaL;
+ pair deltaR=third*(right.point-mid.point);
+ mid.post=mid.point+deltaR;
+ right.pre=right.point-deltaR;
+ mid.straight=true;
+ } else {
+ pair x=split(t,left.post,right.pre); // m1
+ left.post=split(t,left.point,left.post); // m0
+ right.pre=split(t,right.pre,right.point); // m2
+ mid.pre=split(t,left.post,x); // m3
+ mid.post=split(t,x,right.pre); // m4
+ mid.point=split(t,mid.pre,mid.post); // m5
+ }
+}
+
+path path::subpath(double a, double b) const
+{
+ if(empty()) return path();
+
+ if (a > b) {
+ const path &rp = reverse();
+ Int len=length();
+ return rp.subpath(len-a, len-b);
+ }
+
+ solvedKnot aL, aR, bL, bR;
+ if (!cycles) {
+ if (a < 0) {
+ a = 0;
+ if (b < 0)
+ b = 0;
+ }
+ if (b > n-1) {
+ b = n-1;
+ if (a > b)
+ a = b;
+ }
+ aL = nodes[(Int)floor(a)];
+ aR = nodes[(Int)ceil(a)];
+ bL = nodes[(Int)floor(b)];
+ bR = nodes[(Int)ceil(b)];
+ } else {
+ if(run::validInt(a) && run::validInt(b)) {
+ aL = nodes[imod((Int) floor(a),n)];
+ aR = nodes[imod((Int) ceil(a),n)];
+ bL = nodes[imod((Int) floor(b),n)];
+ bR = nodes[imod((Int) ceil(b),n)];
+ } else reportError("invalid path index");
+ }
+
+ if (a == b) return path(point(a));
+
+ solvedKnot sn[3];
+ path p = subpath(Ceil(a), Floor(b));
+ if (a > floor(a)) {
+ if (b < ceil(a)) {
+ splitCubic(sn,a-floor(a),aL,aR);
+ splitCubic(sn,(b-a)/(ceil(b)-a),sn[1],sn[2]);
+ return path(sn[0],sn[1]);
+ }
+ splitCubic(sn,a-floor(a),aL,aR);
+ p=concat(path(sn[1],sn[2]),p);
+ }
+ if (ceil(b) > b) {
+ splitCubic(sn,b-floor(b),bL,bR);
+ p=concat(p,path(sn[0],sn[1]));
+ }
+ return p;
+}
+
+// Special case of subpath for paths of length 1 used by intersect.
+void path::halve(path &first, path &second) const
+{
+ solvedKnot sn[3];
+ splitCubic(sn,0.5,nodes[0],nodes[1]);
+ first=path(sn[0],sn[1]);
+ second=path(sn[1],sn[2]);
+}
+
+// Calculate the coefficients of a Bezier derivative divided by 3.
+static inline void derivative(pair& a, pair& b, pair& c,
+ const pair& z0, const pair& c0,
+ const pair& c1, const pair& z1)
+{
+ a=z1-z0+3.0*(c0-c1);
+ b=2.0*(z0+c1)-4.0*c0;
+ c=c0-z0;
+}
+
+bbox path::bounds() const
+{
+ if(!box.empty) return box;
+
+ if (empty()) {
+ // No bounds
+ return bbox();
+ }
+
+ Int len=length();
+ box.add(point(len));
+ times=bbox(len,len,len,len);
+
+ for (Int i = 0; i < len; i++) {
+ addpoint(box,i);
+ if(straight(i)) continue;
+
+ pair a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ addpoint(box,i+x.t1);
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ addpoint(box,i+x.t2);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ addpoint(box,i+y.t1);
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ addpoint(box,i+y.t2);
+ }
+ return box;
+}
+
+bbox path::bounds(double min, double max) const
+{
+ bbox box;
+
+ Int len=length();
+ for (Int i = 0; i < len; i++) {
+ addpoint(box,i,min,max);
+ if(straight(i)) continue;
+
+ pair a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ addpoint(box,i+x.t1,min,max);
+
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ addpoint(box,i+x.t2,min,max);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ addpoint(box,i+y.t1,min,max);
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ addpoint(box,i+y.t2,min,max);
+ }
+ addpoint(box,len,min,max);
+ return box;
+}
+
+inline void add(bbox& box, const pair& z, const pair& min, const pair& max)
+{
+ box += z+min;
+ box += z+max;
+}
+
+bbox path::internalbounds(const bbox& padding) const
+{
+ bbox box;
+
+ // Check interior nodes.
+ Int len=length();
+ for (Int i = 1; i < len; i++) {
+ pair pre=point(i)-precontrol(i);
+ pair post=postcontrol(i)-point(i);
+
+ // Check node x coordinate
+ if((pre.getx() >= 0.0) ^ (post.getx() >= 0))
+ add(box,point(i),padding.left,padding.right);
+
+ // Check node y coordinate
+ if((pre.gety() >= 0.0) ^ (post.gety() >= 0))
+ add(box,point(i),pair(0,padding.bottom),pair(0,padding.top));
+ }
+
+ // Check interior segments.
+ for (Int i = 0; i < len; i++) {
+ if(straight(i)) continue;
+
+ pair a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ add(box,point(i+x.t1),padding.left,padding.right);
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ add(box,point(i+x.t2),padding.left,padding.right);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ add(box,point(i+y.t1),pair(0,padding.bottom),pair(0,padding.top));
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ add(box,point(i+y.t2),pair(0,padding.bottom),pair(0,padding.top));
+ }
+ return box;
+}
+
+// {{{ Arclength Calculations
+
+static pair a,b,c;
+
+static double ds(double t)
+{
+ double dx=quadratic(a.getx(),b.getx(),c.getx(),t);
+ double dy=quadratic(a.gety(),b.gety(),c.gety(),t);
+ return sqrt(dx*dx+dy*dy);
+}
+
+// Calculates arclength of a cubic using adaptive simpson integration.
+double path::cubiclength(Int i, double goal) const
+{
+ const pair& z0=point(i);
+ const pair& z1=point(i+1);
+ double L;
+ if(straight(i)) {
+ L=(z1-z0).length();
+ return (goal < 0 || goal >= L) ? L : -goal/L;
+ }
+
+ const pair& c0=postcontrol(i);
+ const pair& c1=precontrol(i+1);
+
+ double integral;
+ derivative(a,b,c,z0,c0,c1,z1);
+
+ if(!simpson(integral,ds,0.0,1.0,DBL_EPSILON,1.0))
+ reportError("nesting capacity exceeded in computing arclength");
+ L=3.0*integral;
+ if(goal < 0 || goal >= L) return L;
+
+ double t=goal/L;
+ goal *= third;
+ static double dxmin=sqrt(DBL_EPSILON);
+ if(!unsimpson(goal,ds,0.0,t,100.0*DBL_EPSILON,integral,1.0,dxmin))
+ reportError("nesting capacity exceeded in computing arctime");
+ return -t;
+}
+
+double path::arclength() const
+{
+ if (cached_length != -1) return cached_length;
+
+ double L=0.0;
+ for (Int i = 0; i < n-1; i++) {
+ L += cubiclength(i);
+ }
+ if(cycles) L += cubiclength(n-1);
+ cached_length = L;
+ return cached_length;
+}
+
+double path::arctime(double goal) const
+{
+ if (cycles) {
+ if (goal == 0 || cached_length == 0) return 0;
+ if (goal < 0) {
+ const path &rp = this->reverse();
+ double result = -rp.arctime(-goal);
+ return result;
+ }
+ if (cached_length > 0 && goal >= cached_length) {
+ Int loops = (Int)(goal / cached_length);
+ goal -= loops*cached_length;
+ return loops*n+arctime(goal);
+ }
+ } else {
+ if (goal <= 0)
+ return 0;
+ if (cached_length > 0 && goal >= cached_length)
+ return n-1;
+ }
+
+ double l,L=0;
+ for (Int i = 0; i < n-1; i++) {
+ l = cubiclength(i,goal);
+ if (l < 0)
+ return (-l+i);
+ else {
+ L += l;
+ goal -= l;
+ if (goal <= 0)
+ return i+1;
+ }
+ }
+ if (cycles) {
+ l = cubiclength(n-1,goal);
+ if (l < 0)
+ return -l+n-1;
+ if (cached_length > 0 && cached_length != L+l) {
+ reportError("arclength != length.\n"
+ "path::arclength(double) must have broken semantics.\n"
+ "Please report this error.");
+ }
+ cached_length = L += l;
+ goal -= l;
+ return arctime(goal)+n;
+ }
+ else {
+ cached_length = L;
+ return length();
+ }
+}
+
+// }}}
+
+// {{{ Direction Time Calulation
+// Algorithm Stolen from Knuth's MetaFont
+inline double cubicDir(const solvedKnot& left, const solvedKnot& right,
+ const pair& rot)
+{
+ pair a,b,c;
+ derivative(a,b,c,left.point,left.post,right.pre,right.point);
+ a *= rot; b *= rot; c *= rot;
+
+ quadraticroots ret(a.gety(),b.gety(),c.gety());
+ switch(ret.distinct) {
+ case quadraticroots::MANY:
+ case quadraticroots::ONE:
+ {
+ if(goodroot(a.getx(),b.getx(),c.getx(),ret.t1)) return ret.t1;
+ } break;
+
+ case quadraticroots::TWO:
+ {
+ if(goodroot(a.getx(),b.getx(),c.getx(),ret.t1)) return ret.t1;
+ if(goodroot(a.getx(),b.getx(),c.getx(),ret.t2)) return ret.t2;
+ } break;
+
+ case quadraticroots::NONE:
+ break;
+ }
+
+ return -1;
+}
+
+// TODO: Check that we handle corner cases.
+// Velocity(t) == (0,0)
+double path::directiontime(const pair& dir) const {
+ if (dir == pair(0,0)) return 0;
+ pair rot = pair(1,0)/unit(dir);
+
+ double t; double pre,post;
+ for (Int i = 0; i < n-1+cycles; ) {
+ t = cubicDir(this->nodes[i],(cycles && i==n-1) ? nodes[0]:nodes[i+1],rot);
+ if (t >= 0) return i+t;
+ i++;
+ if (cycles || i != n-1) {
+ pair Pre = (point(i)-precontrol(i))*rot;
+ pair Post = (postcontrol(i)-point(i))*rot;
+ static pair zero(0.0,0.0);
+ if(Pre != zero && Post != zero) {
+ pre = angle(Pre);
+ post = angle(Post);
+ if ((pre <= 0 && post >= 0 && pre >= post - PI) ||
+ (pre >= 0 && post <= 0 && pre <= post + PI))
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+// }}}
+
+// {{{ Path Intersection Calculations
+
+const unsigned maxdepth=DBL_MANT_DIG;
+const unsigned mindepth=maxdepth-16;
+
+void roots(std::vector<double> &roots, double a, double b, double c, double d)
+{
+ cubicroots r(a,b,c,d);
+ if(r.roots >= 1) roots.push_back(r.t1);
+ if(r.roots >= 2) roots.push_back(r.t2);
+ if(r.roots == 3) roots.push_back(r.t3);
+}
+
+void roots(std::vector<double> &r, double x0, double c0, double c1, double x1,
+ double x)
+{
+ double a=x1-x0+3.0*(c0-c1);
+ double b=3.0*(x0+c1)-6.0*c0;
+ double c=3.0*(c0-x0);
+ double d=x0-x;
+ roots(r,a,b,c,d);
+}
+
+// Return all intersection times of path g with the pair z.
+void intersections(std::vector<double>& T, const path& g, const pair& z,
+ double fuzz)
+{
+ double fuzz2=fuzz*fuzz;
+ Int n=g.length();
+ bool cycles=g.cyclic();
+ for(Int i=0; i < n; ++i) {
+ // Check both directions to circumvent degeneracy.
+ std::vector<double> r;
+ roots(r,g.point(i).getx(),g.postcontrol(i).getx(),
+ g.precontrol(i+1).getx(),g.point(i+1).getx(),z.getx());
+ roots(r,g.point(i).gety(),g.postcontrol(i).gety(),
+ g.precontrol(i+1).gety(),g.point(i+1).gety(),z.gety());
+
+ size_t m=r.size();
+ for(size_t j=0 ; j < m; ++j) {
+ double t=r[j];
+ if(t >= -Fuzz2 && t <= 1.0+Fuzz2) {
+ double s=i+t;
+ if((g.point(s)-z).abs2() <= fuzz2) {
+ if(cycles && s >= n-Fuzz2) s=0;
+ T.push_back(s);
+ }
+ }
+ }
+ }
+}
+
+inline bool online(const pair&p, const pair& q, const pair& z, double fuzz)
+{
+ if(p == q) return (z-p).abs2() <= fuzz*fuzz;
+ return (z.getx()-p.getx())*(q.gety()-p.gety()) ==
+ (q.getx()-p.getx())*(z.gety()-p.gety());
+}
+
+// Return all intersection times of path g with the (infinite)
+// line through p and q; if there are an infinite number of intersection points,
+// the returned list is guaranteed to include the endpoint times of
+// the intersection if endpoints=true.
+void lineintersections(std::vector<double>& T, const path& g,
+ const pair& p, const pair& q, double fuzz,
+ bool endpoints=false)
+{
+ Int n=g.length();
+ if(n == 0) {
+ if(online(p,q,g.point((Int) 0),fuzz)) T.push_back(0.0);
+ return;
+ }
+ bool cycles=g.cyclic();
+ double dx=q.getx()-p.getx();
+ double dy=q.gety()-p.gety();
+ double det=p.gety()*q.getx()-p.getx()*q.gety();
+ for(Int i=0; i < n; ++i) {
+ pair z0=g.point(i);
+ pair c0=g.postcontrol(i);
+ pair c1=g.precontrol(i+1);
+ pair z1=g.point(i+1);
+ pair t3=z1-z0+3.0*(c0-c1);
+ pair t2=3.0*(z0+c1)-6.0*c0;
+ pair t1=3.0*(c0-z0);
+ double a=dy*t3.getx()-dx*t3.gety();
+ double b=dy*t2.getx()-dx*t2.gety();
+ double c=dy*t1.getx()-dx*t1.gety();
+ double d=dy*z0.getx()-dx*z0.gety()+det;
+ std::vector<double> r;
+ if(max(max(max(a*a,b*b),c*c),d*d) >
+ Fuzz4*max(max(max(z0.abs2(),z1.abs2()),c0.abs2()),c1.abs2()))
+ roots(r,a,b,c,d);
+ else r.push_back(0.0);
+ if(endpoints) {
+ path h=g.subpath(i,i+1);
+ intersections(r,h,p,fuzz);
+ intersections(r,h,q,fuzz);
+ if(online(p,q,z0,fuzz)) r.push_back(0.0);
+ if(online(p,q,z1,fuzz)) r.push_back(1.0);
+ }
+ size_t m=r.size();
+ for(size_t j=0 ; j < m; ++j) {
+ double t=r[j];
+ if(t >= -Fuzz2 && t <= 1.0+Fuzz2) {
+ double s=i+t;
+ if(cycles && s >= n-Fuzz2) s=0;
+ T.push_back(s);
+ }
+ }
+ }
+}
+
+// An optimized implementation of intersections(g,p--q);
+// if there are an infinite number of intersection points, the returned list is
+// only guaranteed to include the endpoint times of the intersection.
+void intersections(std::vector<double>& S, std::vector<double>& T,
+ const path& g, const pair& p, const pair& q, double fuzz)
+{
+ double length2=(q-p).abs2();
+ if(length2 == 0.0) {
+ std::vector<double> S1;
+ intersections(S1,g,p,fuzz);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i) {
+ S.push_back(S1[i]);
+ T.push_back(0.0);
+ }
+ } else {
+ pair factor=(q-p)/length2;
+ std::vector<double> S1;
+ lineintersections(S1,g,p,q,fuzz,true);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i) {
+ double s=S1[i];
+ double t=dot(g.point(s)-p,factor);
+ if(t >= -Fuzz2 && t <= 1.0+Fuzz2) {
+ S.push_back(s);
+ T.push_back(t);
+ }
+ }
+ }
+}
+
+void add(std::vector<double>& S, double s, const path& p, double fuzz2)
+{
+ pair z=p.point(s);
+ size_t n=S.size();
+ for(size_t i=0; i < n; ++i)
+ if((p.point(S[i])-z).abs2() <= fuzz2) return;
+ S.push_back(s);
+}
+
+void add(std::vector<double>& S, std::vector<double>& T, double s, double t,
+ const path& p, double fuzz2)
+{
+ pair z=p.point(s);
+ size_t n=S.size();
+ for(size_t i=0; i < n; ++i)
+ if((p.point(S[i])-z).abs2() <= fuzz2) return;
+ S.push_back(s);
+ T.push_back(t);
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ double pscale, double qscale, double poffset, double qoffset,
+ const path& p, double fuzz2, bool single)
+{
+ if(single) {
+ s=s*pscale+poffset;
+ t=t*qscale+qoffset;
+ } else {
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i)
+ add(S,T,pscale*S1[i]+poffset,qscale*T1[i]+qoffset,p,fuzz2);
+ }
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ const path& p, double fuzz2, bool single)
+{
+ size_t n=S1.size();
+ if(single) {
+ if(n > 0) {
+ s=S1[0];
+ t=T1[0];
+ }
+ } else {
+ for(size_t i=0; i < n; ++i)
+ add(S,T,S1[i],T1[i],p,fuzz2);
+ }
+}
+
+void intersections(std::vector<double>& S, path& g,
+ const pair& p, const pair& q, double fuzz)
+{
+ double fuzz2=max(fuzzFactor*fuzz*fuzz,Fuzz2);
+ std::vector<double> S1;
+ lineintersections(S1,g,p,q,fuzz);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i)
+ add(S,S1[i],g,fuzz2);
+}
+
+bool intersections(double &s, double &t, std::vector<double>& S,
+ std::vector<double>& T, path& p, path& q,
+ double fuzz, bool single, bool exact, unsigned depth)
+{
+ if(errorstream::interrupt) throw interrupted();
+
+ double fuzz2=max(fuzzFactor*fuzz*fuzz,Fuzz2);
+
+ Int lp=p.length();
+ if(((lp == 1 && p.straight(0)) || lp == 0) && exact) {
+ std::vector<double> T1,S1;
+ intersections(T1,S1,q,p.point((Int) 0),p.point(lp),fuzz);
+ add(s,t,S,T,S1,T1,p,fuzz2,single);
+ return S1.size() > 0;
+ }
+
+ Int lq=q.length();
+ if(((lq == 1 && q.straight(0)) || lq == 0) && exact) {
+ std::vector<double> S1,T1;
+ intersections(S1,T1,p,q.point((Int) 0),q.point(lq),fuzz);
+ add(s,t,S,T,S1,T1,p,fuzz2,single);
+ return S1.size() > 0;
+ }
+
+ pair maxp=p.max();
+ pair minp=p.min();
+ pair maxq=q.max();
+ pair minq=q.min();
+
+ if(maxp.getx()+fuzz >= minq.getx() &&
+ maxp.gety()+fuzz >= minq.gety() &&
+ maxq.getx()+fuzz >= minp.getx() &&
+ maxq.gety()+fuzz >= minp.gety()) {
+ // Overlapping bounding boxes
+
+ --depth;
+ fuzz *= 2.0;
+ fuzz2=max(fuzzFactor*fuzz*fuzz,Fuzz2);
+
+ if((maxp-minp).length()+(maxq-minq).length() <= fuzz || depth == 0) {
+ if(single) {
+ s=0.5;
+ t=0.5;
+ } else {
+ S.push_back(0.5);
+ T.push_back(0.5);
+ }
+ return true;
+ }
+
+ path p1,p2;
+ double pscale,poffset;
+ std::vector<double> S1,T1;
+
+ if(lp <= 1) {
+ if(lp == 1) p.halve(p1,p2);
+ if(lp == 0 || p1 == p || p2 == p) {
+ intersections(T1,S1,q,p.point((Int) 0),p.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,fuzz2,single);
+ return S1.size() > 0;
+ }
+ pscale=poffset=0.5;
+ } else {
+ Int tp=lp/2;
+ p1=p.subpath(0,tp);
+ p2=p.subpath(tp,lp);
+ poffset=tp;
+ pscale=1.0;
+ }
+
+ path q1,q2;
+ double qscale,qoffset;
+
+ if(lq <= 1) {
+ if(lq == 1) q.halve(q1,q2);
+ if(lq == 0 || q1 == q || q2 == q) {
+ intersections(S1,T1,p,q.point((Int) 0),q.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,fuzz2,single);
+ return S1.size() > 0;
+ }
+ qscale=qoffset=0.5;
+ } else {
+ Int tq=lq/2;
+ q1=q.subpath(0,tq);
+ q2=q.subpath(tq,lq);
+ qoffset=tq;
+ qscale=1.0;
+ }
+
+ bool Short=lp == 1 && lq == 1;
+
+ static size_t maxcount=9;
+ size_t count=0;
+
+ if(intersections(s,t,S1,T1,p1,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,0.0,p,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p1,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,qoffset,p,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,0.0,p,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,qoffset,p,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ return S.size() > 0;
+ }
+ return false;
+}
+
+// }}}
+
+ostream& operator<< (ostream& out, const path& p)
+{
+ Int n = p.length();
+ if(n < 0)
+ out << "<nullpath>";
+ else {
+ for(Int i = 0; i < n; i++) {
+ out << p.point(i);
+ if(p.straight(i)) out << "--";
+ else
+ out << ".. controls " << p.postcontrol(i) << " and "
+ << p.precontrol(i+1) << newl << " ..";
+ }
+ if(p.cycles)
+ out << "cycle";
+ else
+ out << p.point(n);
+ }
+ return out;
+}
+
+path concat(const path& p1, const path& p2)
+{
+ Int n1 = p1.length(), n2 = p2.length();
+
+ if (n1 == -1) return p2;
+ if (n2 == -1) return p1;
+
+ mem::vector<solvedKnot> nodes(n1+n2+1);
+
+ Int i = 0;
+ nodes[0].pre = p1.point((Int) 0);
+ for (Int j = 0; j < n1; j++) {
+ nodes[i].point = p1.point(j);
+ nodes[i].straight = p1.straight(j);
+ nodes[i].post = p1.postcontrol(j);
+ nodes[i+1].pre = p1.precontrol(j+1);
+ i++;
+ }
+ for (Int j = 0; j < n2; j++) {
+ nodes[i].point = p2.point(j);
+ nodes[i].straight = p2.straight(j);
+ nodes[i].post = p2.postcontrol(j);
+ nodes[i+1].pre = p2.precontrol(j+1);
+ i++;
+ }
+ nodes[i].point = nodes[i].post = p2.point(n2);
+
+ return path(nodes, i+1);
+}
+
+// Interface to orient2d predicate optimized for pairs.
+double orient2d(const pair& a, const pair& b, const pair& c)
+{
+ double detleft, detright, det;
+ double detsum, errbound;
+ double orient;
+
+ FPU_ROUND_DOUBLE;
+
+ detleft = (a.getx() - c.getx()) * (b.gety() - c.gety());
+ detright = (a.gety() - c.gety()) * (b.getx() - c.getx());
+ det = detleft - detright;
+
+ if (detleft > 0.0) {
+ if (detright <= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = detleft + detright;
+ }
+ } else if (detleft < 0.0) {
+ if (detright >= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = -detleft - detright;
+ }
+ } else {
+ FPU_RESTORE;
+ return det;
+ }
+
+ errbound = ccwerrboundA * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ double pa[]={a.getx(),a.gety()};
+ double pb[]={b.getx(),b.gety()};
+ double pc[]={c.getx(),c.gety()};
+
+ orient = orient2dadapt(pa, pb, pc, detsum);
+ FPU_RESTORE;
+ return orient;
+}
+
+// Returns true iff the point z lies in or on the bounding box
+// of a,b,c, and d.
+bool insidebbox(const pair& a, const pair& b, const pair& c, const pair& d,
+ const pair& z)
+{
+ bbox B(a);
+ B.addnonempty(b);
+ B.addnonempty(c);
+ B.addnonempty(d);
+ return B.left <= z.getx() && z.getx() <= B.right && B.bottom <= z.gety()
+ && z.gety() <= B.top;
+}
+
+inline bool inrange(double x0, double x1, double x)
+{
+ return (x0 <= x && x <= x1) || (x1 <= x && x <= x0);
+}
+
+// Return true if point z is on z0--z1; otherwise compute contribution to
+// winding number.
+bool checkstraight(const pair& z0, const pair& z1, const pair& z, Int& count)
+{
+ if(z0.gety() <= z.gety() && z.gety() <= z1.gety()) {
+ double side=orient2d(z0,z1,z);
+ if(side == 0.0 && inrange(z0.getx(),z1.getx(),z.getx()))
+ return true;
+ if(z.gety() < z1.gety() && side > 0) ++count;
+ } else if(z1.gety() <= z.gety() && z.gety() <= z0.gety()) {
+ double side=orient2d(z0,z1,z);
+ if(side == 0.0 && inrange(z0.getx(),z1.getx(),z.getx()))
+ return true;
+ if(z.gety() < z0.gety() && side < 0) --count;
+ }
+ return false;
+}
+
+// returns true if point is on curve; otherwise compute contribution to
+// winding number.
+bool checkcurve(const pair& z0, const pair& c0, const pair& c1,
+ const pair& z1, const pair& z, Int& count, unsigned depth)
+{
+ if(depth == 0) return true;
+ --depth;
+
+ if(insidebbox(z0,c0,c1,z1,z)) {
+ const pair m0=0.5*(z0+c0);
+ const pair m1=0.5*(c0+c1);
+ const pair m2=0.5*(c1+z1);
+ const pair m3=0.5*(m0+m1);
+ const pair m4=0.5*(m1+m2);
+ const pair m5=0.5*(m3+m4);
+ if(checkcurve(z0,m0,m3,m5,z,count,depth) ||
+ checkcurve(m5,m4,m2,z1,z,count,depth)) return true;
+ } else
+ if(checkstraight(z0,z1,z,count)) return true;
+ return false;
+}
+
+// Return the winding number of the region bounded by the (cyclic) path
+// relative to the point z, or the largest odd integer if the point lies on
+// the path.
+Int path::windingnumber(const pair& z) const
+{
+ static const Int undefined=Int_MAX % 2 ? Int_MAX : Int_MAX-1;
+
+ if(!cycles)
+ reportError("path is not cyclic");
+
+ bbox b=bounds();
+
+ if(z.getx() < b.left || z.getx() > b.right ||
+ z.gety() < b.bottom || z.gety() > b.top) return 0;
+
+ Int count=0;
+ for(Int i=0; i < n; ++i)
+ if(straight(i)) {
+ if(checkstraight(point(i),point(i+1),z,count))
+ return undefined;
+ } else
+ if(checkcurve(point(i),postcontrol(i),precontrol(i+1),point(i+1),z,count,
+ maxdepth)) return undefined;
+ return count;
+}
+
+path path::transformed(const transform& t) const
+{
+ mem::vector<solvedKnot> nodes(n);
+
+ for (Int i = 0; i < n; ++i) {
+ nodes[i].pre = t * this->nodes[i].pre;
+ nodes[i].point = t * this->nodes[i].point;
+ nodes[i].post = t * this->nodes[i].post;
+ nodes[i].straight = this->nodes[i].straight;
+ }
+
+ path p(nodes, n, cyclic());
+ return p;
+}
+
+path transformed(const transform& t, const path& p)
+{
+ Int n = p.size();
+ mem::vector<solvedKnot> nodes(n);
+
+ for (Int i = 0; i < n; ++i) {
+ nodes[i].pre = t * p.precontrol(i);
+ nodes[i].point = t * p.point(i);
+ nodes[i].post = t * p.postcontrol(i);
+ nodes[i].straight = p.straight(i);
+ }
+
+ return path(nodes, n, p.cyclic());
+}
+
+path nurb(pair z0, pair z1, pair z2, pair z3,
+ double w0, double w1, double w2, double w3, Int m)
+{
+ mem::vector<solvedKnot> nodes(m+1);
+
+ if(m < 1) reportError("invalid sampling interval");
+
+ double step=1.0/m;
+ for(Int i=0; i <= m; ++i) {
+ double t=i*step;
+ double t2=t*t;
+ double onemt=1.0-t;
+ double onemt2=onemt*onemt;
+ double W0=w0*onemt2*onemt;
+ double W1=w1*3.0*t*onemt2;
+ double W2=w2*3.0*t2*onemt;
+ double W3=w3*t2*t;
+ nodes[i].point=(W0*z0+W1*z1+W2*z2+W3*z3)/(W0+W1+W2+W3);
+ }
+
+ static const double twothirds=2.0/3.0;
+ pair z=nodes[0].point;
+ nodes[0].pre=z;
+ nodes[0].post=twothirds*z+third*nodes[1].point;
+ for(int i=1; i < m; ++i) {
+ pair z0=nodes[i].point;
+ pair zm=nodes[i-1].point;
+ pair zp=nodes[i+1].point;
+ pair pre=twothirds*z0+third*zm;
+ pair pos=twothirds*z0+third*zp;
+ pair dir=unit(pos-pre);
+ nodes[i].pre=z0-length(z0-pre)*dir;
+ nodes[i].post=z0+length(pos-z0)*dir;
+ }
+ z=nodes[m].point;
+ nodes[m].pre=twothirds*z+third*nodes[m-1].point;
+ nodes[m].post=z;
+ return path(nodes,m+1);
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/path.h b/graphics/asymptote/path.h
new file mode 100644
index 0000000000..9d2890b150
--- /dev/null
+++ b/graphics/asymptote/path.h
@@ -0,0 +1,460 @@
+/*****
+ * path.h
+ * Andy Hammerlindl 2002/05/16
+ *
+ * Stores a piecewise cubic spline with known control points.
+ *
+ * When changing the path algorithms, also update the corresponding
+ * three-dimensional algorithms in path3.cc and three.asy.
+ *****/
+
+#ifndef PATH_H
+#define PATH_H
+
+#include <cfloat>
+
+#include "mod.h"
+#include "pair.h"
+#include "transform.h"
+#include "bbox.h"
+
+inline double Intcap(double t) {
+ if(t <= Int_MIN) return Int_MIN;
+ if(t >= Int_MAX) return Int_MAX;
+ return t;
+}
+
+// The are like floor and ceil, except they return an integer;
+// if the argument cannot be converted to a valid integer, they return
+// Int_MAX (for positive arguments) or Int_MIN (for negative arguments).
+
+inline Int Floor(double t) {return (Int) floor(Intcap(t));}
+inline Int Ceil(double t) {return (Int) ceil(Intcap(t));}
+
+bool simpson(double& integral, double (*)(double), double a, double b,
+ double acc, double dxmax);
+
+bool unsimpson(double integral, double (*)(double), double a, double& b,
+ double acc, double& area, double dxmax, double dxmin=0);
+
+namespace camp {
+
+void checkEmpty(Int n);
+
+inline Int adjustedIndex(Int i, Int n, bool cycles)
+{
+ checkEmpty(n);
+ if(cycles)
+ return imod(i,n);
+ else if(i < 0)
+ return 0;
+ else if(i >= n)
+ return n-1;
+ else
+ return i;
+}
+
+// Used in the storage of solved path knots.
+struct solvedKnot : public gc {
+ pair pre;
+ pair point;
+ pair post;
+ bool straight;
+ solvedKnot() : straight(false) {}
+
+ friend bool operator== (const solvedKnot& p, const solvedKnot& q)
+ {
+ return p.pre == q.pre && p.point == q.point && p.post == q.post;
+ }
+};
+
+extern const double Fuzz;
+extern const double Fuzz2;
+extern const double Fuzz4;
+extern const double sqrtFuzz;
+extern const double BigFuzz;
+extern const double fuzzFactor;
+
+class path : public gc {
+ bool cycles; // If the path is closed in a loop
+
+ Int n; // The number of knots
+
+ mem::vector<solvedKnot> nodes;
+ mutable double cached_length; // Cache length since path is immutable.
+
+ mutable bbox box;
+ mutable bbox times; // Times where minimum and maximum extents are attained.
+
+public:
+ path()
+ : cycles(false), n(0), nodes(), cached_length(-1) {}
+
+ // Create a path of a single point
+ path(pair z, bool = false)
+ : cycles(false), n(1), nodes(1), cached_length(-1)
+ {
+ nodes[0].pre = nodes[0].point = nodes[0].post = z;
+ nodes[0].straight = false;
+ }
+
+ // Creates path from a list of knots. This will be used by camp
+ // methods such as the guide solver, but should probably not be used by a
+ // user of the system unless he knows what he is doing.
+ path(mem::vector<solvedKnot>& nodes, Int n, bool cycles = false)
+ : cycles(cycles), n(n), nodes(nodes), cached_length(-1)
+ {
+ }
+
+ friend bool operator== (const path& p, const path& q)
+ {
+ return p.cycles == q.cycles && p.nodes == q.nodes;
+ }
+
+public:
+ path(solvedKnot n1, solvedKnot n2)
+ : cycles(false), n(2), nodes(2), cached_length(-1)
+ {
+ nodes[0] = n1;
+ nodes[1] = n2;
+ nodes[0].pre = nodes[0].point;
+ nodes[1].post = nodes[1].point;
+ }
+
+ // Copy constructor
+ path(const path& p)
+ : cycles(p.cycles), n(p.n), nodes(p.nodes), cached_length(p.cached_length),
+ box(p.box)
+ {}
+
+ path unstraighten() const
+ {
+ path P=path(*this);
+ for(int i=0; i < n; ++i)
+ P.nodes[i].straight=false;
+ return P;
+ }
+
+ virtual ~path()
+ {
+ }
+
+ // Getting control points
+ Int size() const
+ {
+ return n;
+ }
+
+ bool empty() const
+ {
+ return n == 0;
+ }
+
+ Int length() const
+ {
+ return cycles ? n : n-1;
+ }
+
+ bool cyclic() const
+ {
+ return cycles;
+ }
+
+ mem::vector<solvedKnot>& Nodes() {
+ return nodes;
+ }
+
+ bool straight(Int t) const
+ {
+ if (cycles) return nodes[imod(t,n)].straight;
+ return (t >= 0 && t < n) ? nodes[t].straight : false;
+ }
+
+ bool piecewisestraight() const
+ {
+ Int L=length();
+ for(Int i=0; i < L; ++i)
+ if(!straight(i)) return false;
+ return true;
+ }
+
+ pair point(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].point;
+ }
+
+ pair point(double t) const;
+
+ pair precontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].pre;
+ }
+
+ pair precontrol(double t) const;
+
+ pair postcontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].post;
+ }
+
+ pair postcontrol(double t) const;
+
+ inline double norm(const pair& z0, const pair& c0, const pair& c1,
+ const pair& z1) const {
+ return Fuzz2*camp::max((c0-z0).abs2(),
+ camp::max((c1-z0).abs2(),(z1-z0).abs2()));
+ }
+
+ pair predir(Int t, bool normalize=true) const {
+ if(!cycles && t <= 0) return pair(0,0);
+ pair z1=point(t);
+ pair c1=precontrol(t);
+ pair dir=3.0*(z1-c1);
+ if(!normalize) return dir;
+ pair z0=point(t-1);
+ pair c0=postcontrol(t-1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*c1-c0-z1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ pair postdir(Int t, bool normalize=true) const {
+ if(!cycles && t >= n-1) return pair(0,0);
+ pair c0=postcontrol(t);
+ pair z0=point(t);
+ pair dir=3.0*(c0-z0);
+ if(!normalize) return dir;
+ pair z1=point(t+1);
+ pair c1=precontrol(t+1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=z0-2.0*c0+c1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ pair dir(Int t, Int sign, bool normalize=true) const {
+ if(sign == 0) {
+ pair v=predir(t,normalize)+postdir(t,normalize);
+ return normalize ? unit(v) : 0.5*v;
+ }
+ if(sign > 0) return postdir(t,normalize);
+ return predir(t,normalize);
+ }
+
+ pair dir(double t, bool normalize=true) const {
+ if(!cycles) {
+ if(t <= 0) return postdir((Int) 0,normalize);
+ if(t >= n-1) return predir(n-1,normalize);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return dir(i,0,normalize);
+ pair z0=point(i);
+ pair c0=postcontrol(i);
+ pair c1=precontrol(i+1);
+ pair z1=point(i+1);
+ pair a=3.0*(z1-z0)+9.0*(c0-c1);
+ pair b=6.0*(z0+c1)-12.0*c0;
+ pair c=3.0*(c0-z0);
+ pair dir=a*t*t+b*t+c;
+ if(!normalize) return dir;
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*a*t+b;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(a);
+ }
+
+ pair postaccel(Int t) const {
+ if(!cycles && t >= n-1) return pair(0,0);
+ pair z0=point(t);
+ pair c0=postcontrol(t);
+ pair c1=precontrol(t+1);
+ return 6.0*(z0+c1)-12.0*c0;
+ }
+
+ pair preaccel(Int t) const {
+ if(!cycles && t <= 0) return pair(0,0);
+ pair c0=postcontrol(t-1);
+ pair c1=precontrol(t);
+ pair z1=point(t);
+ return 6.0*(z1+c0)-12.0*c1;
+ }
+
+ pair accel(Int t, Int sign) const {
+ if(sign == 0) return 0.5*(preaccel(t)+postaccel(t));
+ if(sign > 0) return postaccel(t);
+ return preaccel(t);
+ }
+
+ pair accel(double t) const {
+ if(!cycles) {
+ if(t <= 0) return postaccel((Int) 0);
+ if(t >= n-1) return preaccel(n-1);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return 0.5*(postaccel(i)+preaccel(i));
+ pair z0=point(i);
+ pair c0=postcontrol(i);
+ pair c1=precontrol(i+1);
+ pair z1=point(i+1);
+ return 6.0*t*(z1-z0+3.0*(c0-c1))+6.0*(z0+c1)-12.0*c0;
+ }
+
+ // Returns the path traced out in reverse.
+ path reverse() const;
+
+ // Generates a path that is a section of the old path, using the time
+ // interval given.
+ path subpath(Int start, Int end) const;
+ path subpath(double start, double end) const;
+
+ // Special case of subpath used by intersect.
+ void halve(path &first, path &second) const;
+
+ // Used by picture to determine bounding box.
+ bbox bounds() const;
+
+ pair mintimes() const {
+ checkEmpty(n);
+ bounds();
+ return camp::pair(times.left,times.bottom);
+ }
+
+ pair maxtimes() const {
+ checkEmpty(n);
+ bounds();
+ return camp::pair(times.right,times.top);
+ }
+
+ template<class T>
+ void addpoint(bbox& box, T i) const {
+ box.addnonempty(point(i),times,(double) i);
+ }
+
+ template<class T>
+ void addpoint(bbox& box, T i, double min, double max) const {
+ static const pair I(0,1);
+ pair v=I*dir(i);
+ pair z=point(i);
+ box.add(z+min*v);
+ box.addnonempty(z+max*v);
+ }
+
+ // Return bounding box accounting for padding perpendicular to path.
+ bbox bounds(double min, double max) const;
+
+ // Return bounding box accounting for internal pen padding (but not pencap).
+ bbox internalbounds(const bbox &padding) const;
+
+ double cubiclength(Int i, double goal=-1) const;
+ double arclength () const;
+ double arctime (double l) const;
+ double directiontime(const pair& z) const;
+
+ pair max() const {
+ checkEmpty(n);
+ return bounds().Max();
+ }
+
+ pair min() const {
+ checkEmpty(n);
+ return bounds().Min();
+ }
+
+ // Debugging output
+ friend std::ostream& operator<< (std::ostream& out, const path& p);
+
+// Increment count if the path has a vertical component at t.
+ bool Count(Int& count, double t) const;
+
+// Count if t is in (begin,end] and z lies to the left of point(i+t).
+ void countleft(Int& count, double x, Int i, double t,
+ double begin, double end, double& mint, double& maxt) const;
+
+// Return the winding number of the region bounded by the (cyclic) path
+// relative to the point z.
+ Int windingnumber(const pair& z) const;
+
+ // Transformation
+ path transformed(const transform& t) const;
+
+};
+
+extern path nullpath;
+extern const unsigned maxdepth;
+extern const unsigned mindepth;
+extern const char *nopoints;
+
+bool intersect(double& S, double& T, path& p, path& q, double fuzz,
+ unsigned depth=maxdepth);
+bool intersections(double& s, double& t, std::vector<double>& S,
+ std::vector<double>& T, path& p, path& q,
+ double fuzz, bool single, bool exact,
+ unsigned depth=maxdepth);
+void intersections(std::vector<double>& S, path& g,
+ const pair& p, const pair& q, double fuzz);
+
+
+// Concatenates two paths into a new one.
+path concat(const path& p1, const path& p2);
+
+// Applies a transformation to the path
+path transformed(const transform& t, const path& p);
+
+inline double quadratic(double a, double b, double c, double x)
+{
+ return a*x*x+b*x+c;
+}
+
+class quadraticroots {
+public:
+ enum {NONE=0, ONE=1, TWO=2, MANY} distinct; // Number of distinct real roots.
+ unsigned roots; // Total number of real roots.
+ double t1,t2; // Real roots
+
+ quadraticroots(double a, double b, double c);
+};
+
+class Quadraticroots {
+public:
+ unsigned roots; // Total number of roots.
+ pair z1,z2; // Complex roots
+ Quadraticroots(pair a, pair b, pair c);
+};
+
+class cubicroots {
+public:
+ unsigned roots; // Total number of real roots.
+ double t1,t2,t3;
+ cubicroots(double a, double b, double c, double d);
+};
+
+path nurb(pair z0, pair z1, pair z2, pair z3,
+ double w0, double w1, double w2, double w3, Int m);
+
+double orient2d(const pair& a, const pair& b, const pair& c);
+
+void roots(std::vector<double> &roots, double a, double b, double c, double d);
+void roots(std::vector<double> &r, double x0, double c0, double c1, double x1,
+ double x);
+
+inline bool goodroot(double t)
+{
+ return 0.0 <= t && t <= 1.0;
+}
+
+extern const double third;
+
+}
+
+#ifndef BROKEN_COMPILER
+// Delete the following line to work around problems with old broken compilers.
+GC_DECLARE_PTRFREE(camp::solvedKnot);
+#endif
+
+#endif
diff --git a/graphics/asymptote/path3.cc b/graphics/asymptote/path3.cc
new file mode 100644
index 0000000000..32a5604a29
--- /dev/null
+++ b/graphics/asymptote/path3.cc
@@ -0,0 +1,1447 @@
+/*****
+ * path3.cc
+ * John Bowman
+ *
+ * Compute information for a three-dimensional path.
+ *****/
+
+#include <cfloat>
+
+#include "path3.h"
+#include "util.h"
+#include "camperror.h"
+#include "mathop.h"
+
+namespace camp {
+
+using run::operator *;
+using vm::array;
+
+path3 nullpath3;
+
+void checkEmpty3(Int n) {
+ if(n == 0)
+ reportError("nullpath3 has no points");
+}
+
+triple path3::point(double t) const
+{
+ checkEmpty3(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].point;
+ else if (i >= n-1)
+ return nodes[n-1].point;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ triple a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ abc = one_t*ab + t*bc,
+ bcd = one_t*bc + t*cd,
+ abcd = one_t*abc + t*bcd;
+
+ return abcd;
+}
+
+triple path3::precontrol(double t) const
+{
+ checkEmpty3(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].pre;
+ else if (i >= n-1)
+ return nodes[n-1].pre;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ triple a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ abc = one_t*ab + t*bc;
+
+ return (abc == a) ? nodes[i].pre : abc;
+}
+
+
+triple path3::postcontrol(double t) const
+{
+ checkEmpty3(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].post;
+ else if (i >= n-1)
+ return nodes[n-1].post;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ triple b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ bcd = one_t*bc + t*cd;
+
+ return (bcd == d) ? nodes[iplus].post : bcd;
+}
+
+path3 path3::reverse() const
+{
+ mem::vector<solvedKnot3> nodes(n);
+ Int len=length();
+ for (Int i = 0, j = len; i < n; i++, j--) {
+ nodes[i].pre = postcontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = precontrol(j);
+ nodes[i].straight = straight(j-1);
+ }
+ return path3(nodes, n, cycles);
+}
+
+path3 path3::subpath(Int a, Int b) const
+{
+ if(empty()) return path3();
+
+ if (a > b) {
+ const path3 &rp = reverse();
+ Int len=length();
+ path3 result = rp.subpath(len-a, len-b);
+ return result;
+ }
+
+ if (!cycles) {
+ if (a < 0)
+ a = 0;
+ if (b > n-1)
+ b = n-1;
+ }
+
+ Int sn = b-a+1;
+ mem::vector<solvedKnot3> nodes(sn);
+
+ for (Int i = 0, j = a; j <= b; i++, j++) {
+ nodes[i].pre = precontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = postcontrol(j);
+ nodes[i].straight = straight(j);
+ }
+ nodes[0].pre = nodes[0].point;
+ nodes[sn-1].post = nodes[sn-1].point;
+
+ return path3(nodes, sn);
+}
+
+inline triple split(double t, const triple& x, const triple& y) {
+ return x+(y-x)*t;
+}
+
+inline void splitCubic(solvedKnot3 sn[], double t, const solvedKnot3& left_,
+ const solvedKnot3& right_)
+{
+ solvedKnot3 &left=(sn[0]=left_), &mid=sn[1], &right=(sn[2]=right_);
+ if(left.straight) {
+ mid.point=split(t,left.point,right.point);
+ triple deltaL=third*(mid.point-left.point);
+ left.post=left.point+deltaL;
+ mid.pre=mid.point-deltaL;
+ triple deltaR=third*(right.point-mid.point);
+ mid.post=mid.point+deltaR;
+ right.pre=right.point-deltaR;
+ mid.straight=true;
+ } else {
+ triple x=split(t,left.post,right.pre); // m1
+ left.post=split(t,left.point,left.post); // m0
+ right.pre=split(t,right.pre,right.point); // m2
+ mid.pre=split(t,left.post,x); // m3
+ mid.post=split(t,x,right.pre); // m4
+ mid.point=split(t,mid.pre,mid.post); // m5
+ }
+}
+
+path3 path3::subpath(double a, double b) const
+{
+ if(empty()) return path3();
+
+ if (a > b) {
+ const path3 &rp = reverse();
+ Int len=length();
+ return rp.subpath(len-a, len-b);
+ }
+
+ solvedKnot3 aL, aR, bL, bR;
+ if (!cycles) {
+ if (a < 0) {
+ a = 0;
+ if (b < 0)
+ b = 0;
+ }
+ if (b > n-1) {
+ b = n-1;
+ if (a > n-1)
+ a = n-1;
+ }
+ aL = nodes[(Int)floor(a)];
+ aR = nodes[(Int)ceil(a)];
+ bL = nodes[(Int)floor(b)];
+ bR = nodes[(Int)ceil(b)];
+ } else {
+ if(run::validInt(a) && run::validInt(b)) {
+ aL = nodes[imod((Int) floor(a),n)];
+ aR = nodes[imod((Int) ceil(a),n)];
+ bL = nodes[imod((Int) floor(b),n)];
+ bR = nodes[imod((Int) ceil(b),n)];
+ } else reportError("invalid path3 index");
+ }
+
+ if (a == b) return path3(point(a));
+
+ solvedKnot3 sn[3];
+ path3 p = subpath(Ceil(a), Floor(b));
+ if (a > floor(a)) {
+ if (b < ceil(a)) {
+ splitCubic(sn,a-floor(a),aL,aR);
+ splitCubic(sn,(b-a)/(ceil(b)-a),sn[1],sn[2]);
+ return path3(sn[0],sn[1]);
+ }
+ splitCubic(sn,a-floor(a),aL,aR);
+ p=concat(path3(sn[1],sn[2]),p);
+ }
+ if (ceil(b) > b) {
+ splitCubic(sn,b-floor(b),bL,bR);
+ p=concat(p,path3(sn[0],sn[1]));
+ }
+ return p;
+}
+
+// Special case of subpath for paths of length 1 used by intersect.
+void path3::halve(path3 &first, path3 &second) const
+{
+ solvedKnot3 sn[3];
+ splitCubic(sn,0.5,nodes[0],nodes[1]);
+ first=path3(sn[0],sn[1]);
+ second=path3(sn[1],sn[2]);
+}
+
+// Calculate the coefficients of a Bezier derivative divided by 3.
+static inline void derivative(triple& a, triple& b, triple& c,
+ const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1)
+{
+ a=z1-z0+3.0*(c0-c1);
+ b=2.0*(z0+c1)-4.0*c0;
+ c=c0-z0;
+}
+
+bbox3 path3::bounds() const
+{
+ if(!box.empty) return box;
+
+ if (empty()) {
+ // No bounds
+ return bbox3();
+ }
+
+ Int len=length();
+ box.add(point(len));
+ times=bbox3(len,len,len,len,len,len);
+
+ for (Int i = 0; i < len; i++) {
+ addpoint(box,i);
+ if(straight(i)) continue;
+
+ triple a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ addpoint(box,i+x.t1);
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ addpoint(box,i+x.t2);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ addpoint(box,i+y.t1);
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ addpoint(box,i+y.t2);
+
+ // Check z coordinate
+ quadraticroots z(a.getz(),b.getz(),c.getz());
+ if(z.distinct != quadraticroots::NONE && goodroot(z.t1))
+ addpoint(box,i+z.t1);
+ if(z.distinct == quadraticroots::TWO && goodroot(z.t2))
+ addpoint(box,i+z.t2);
+ }
+ return box;
+}
+
+// Return f evaluated at controlling vertex of bounding box of convex hull for
+// similiar-triangle transform x'=x/z, y'=y/z, where z < 0.
+double ratiobound(triple z0, triple c0, triple c1, triple z1,
+ double (*m)(double, double),
+ double (*f)(const triple&))
+{
+ double MX=m(m(m(-z0.getx(),-c0.getx()),-c1.getx()),-z1.getx());
+ double MY=m(m(m(-z0.gety(),-c0.gety()),-c1.gety()),-z1.gety());
+ double Z=m(m(m(z0.getz(),c0.getz()),c1.getz()),z1.getz());
+ double MZ=m(m(m(-z0.getz(),-c0.getz()),-c1.getz()),-z1.getz());
+ return m(f(triple(-MX,-MY,Z)),f(triple(-MX,-MY,-MZ)));
+}
+
+double bound(triple z0, triple c0, triple c1, triple z1,
+ double (*m)(double, double),
+ double (*f)(const triple&), double b, double fuzz, int depth)
+{
+ b=m(b,m(f(z0),f(z1)));
+ if(m(-1.0,1.0)*(b-ratiobound(z0,c0,c1,z1,m,f)) >= -fuzz || depth == 0)
+ return b;
+
+ --depth;
+ fuzz *= 2;
+
+ triple m0=0.5*(z0+c0);
+ triple m1=0.5*(c0+c1);
+ triple m2=0.5*(c1+z1);
+ triple m3=0.5*(m0+m1);
+ triple m4=0.5*(m1+m2);
+ triple m5=0.5*(m3+m4);
+
+ // Check both Bezier subpaths.
+ b=bound(z0,m0,m3,m5,m,f,b,fuzz,depth);
+ return bound(m5,m4,m2,z1,m,f,b,fuzz,depth);
+}
+
+pair path3::ratio(double (*m)(double, double)) const
+{
+ double fuzz=Fuzz*(max()-min()).length();
+ checkEmpty3(n);
+
+ triple v=point((Int) 0);
+ pair B=pair(xratio(v),yratio(v));
+
+ Int n=length();
+ for(Int i=0; i <= n; ++i) {
+ if(straight(i)) {
+ triple v=point(i);
+ B=pair(m(B.getx(),xratio(v)),m(B.gety(),yratio(v)));
+ } else {
+ triple z0=point(i);
+ triple c0=postcontrol(i);
+ triple c1=precontrol(i+1);
+ triple z1=point(i+1);
+ B=pair(bound(z0,c0,c1,z1,m,xratio,B.getx(),fuzz),
+ bound(z0,c0,c1,z1,m,yratio,B.gety(),fuzz));
+ }
+ }
+ return B;
+}
+
+// {{{ Arclength Calculations
+
+static triple a,b,c;
+
+static double ds(double t)
+{
+ double dx=quadratic(a.getx(),b.getx(),c.getx(),t);
+ double dy=quadratic(a.gety(),b.gety(),c.gety(),t);
+ double dz=quadratic(a.getz(),b.getz(),c.getz(),t);
+ return sqrt(dx*dx+dy*dy+dz*dz);
+}
+
+// Calculates arclength of a cubic using adaptive simpson integration.
+double path3::cubiclength(Int i, double goal) const
+{
+ const triple& z0=point(i);
+ const triple& z1=point(i+1);
+ double L;
+ if(straight(i)) {
+ L=(z1-z0).length();
+ return (goal < 0 || goal >= L) ? L : -goal/L;
+ }
+ const triple& c0=postcontrol(i);
+ const triple& c1=precontrol(i+1);
+
+ double integral;
+ derivative(a,b,c,z0,c0,c1,z1);
+
+ if(!simpson(integral,ds,0.0,1.0,DBL_EPSILON,1.0))
+ reportError("nesting capacity exceeded in computing arclength");
+ L=3.0*integral;
+ if(goal < 0 || goal >= L) return L;
+
+ double t=goal/L;
+ goal *= third;
+ static double dxmin=sqrt(DBL_EPSILON);
+ if(!unsimpson(goal,ds,0.0,t,100.0*DBL_EPSILON,integral,1.0,dxmin))
+ reportError("nesting capacity exceeded in computing arctime");
+ return -t;
+}
+
+double path3::arclength() const
+{
+ if (cached_length != -1) return cached_length;
+
+ double L=0.0;
+ for (Int i = 0; i < n-1; i++) {
+ L += cubiclength(i);
+ }
+ if(cycles) L += cubiclength(n-1);
+ cached_length = L;
+ return cached_length;
+}
+
+double path3::arctime(double goal) const
+{
+ if (cycles) {
+ if (goal == 0 || cached_length == 0) return 0;
+ if (goal < 0) {
+ const path3 &rp = this->reverse();
+ double result = -rp.arctime(-goal);
+ return result;
+ }
+ if (cached_length > 0 && goal >= cached_length) {
+ Int loops = (Int)(goal / cached_length);
+ goal -= loops*cached_length;
+ return loops*n+arctime(goal);
+ }
+ } else {
+ if (goal <= 0)
+ return 0;
+ if (cached_length > 0 && goal >= cached_length)
+ return n-1;
+ }
+
+ double l,L=0;
+ for (Int i = 0; i < n-1; i++) {
+ l = cubiclength(i,goal);
+ if (l < 0)
+ return (-l+i);
+ else {
+ L += l;
+ goal -= l;
+ if (goal <= 0)
+ return i+1;
+ }
+ }
+ if (cycles) {
+ l = cubiclength(n-1,goal);
+ if (l < 0)
+ return -l+n-1;
+ if (cached_length > 0 && cached_length != L+l) {
+ reportError("arclength != length.\n"
+ "path3::arclength(double) must have broken semantics.\n"
+ "Please report this error.");
+ }
+ cached_length = L += l;
+ goal -= l;
+ return arctime(goal)+n;
+ }
+ else {
+ cached_length = L;
+ return length();
+ }
+}
+
+// }}}
+
+// {{{ Path3 Intersection Calculations
+
+// Return all intersection times of path3 g with the triple v.
+void intersections(std::vector<double>& T, const path3& g, const triple& v,
+ double fuzz)
+{
+ double fuzz2=fuzz*fuzz;
+ Int n=g.length();
+ bool cycles=g.cyclic();
+ for(Int i=0; i < n; ++i) {
+ // Check all directions to circumvent degeneracy.
+ std::vector<double> r;
+ roots(r,g.point(i).getx(),g.postcontrol(i).getx(),
+ g.precontrol(i+1).getx(),g.point(i+1).getx(),v.getx());
+ roots(r,g.point(i).gety(),g.postcontrol(i).gety(),
+ g.precontrol(i+1).gety(),g.point(i+1).gety(),v.gety());
+ roots(r,g.point(i).getz(),g.postcontrol(i).getz(),
+ g.precontrol(i+1).getz(),g.point(i+1).getz(),v.getz());
+
+ size_t m=r.size();
+ for(size_t j=0 ; j < m; ++j) {
+ double t=r[j];
+ if(t >= -Fuzz2 && t <= 1.0+Fuzz2) {
+ double s=i+t;
+ if((g.point(s)-v).abs2() <= fuzz2) {
+ if(cycles && s >= n-Fuzz2) s=0;
+ T.push_back(s);
+ }
+ }
+ }
+ }
+}
+
+// An optimized implementation of intersections(g,p--q);
+// if there are an infinite number of intersection points, the returned list is
+// only guaranteed to include the endpoint times of the intersection.
+void intersections(std::vector<double>& S, std::vector<double>& T,
+ const path3& g, const triple& p, double fuzz)
+{
+ std::vector<double> S1;
+ intersections(S1,g,p,fuzz);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i) {
+ S.push_back(S1[i]);
+ T.push_back(0.0);
+ }
+}
+
+void add(std::vector<double>& S, std::vector<double>& T, double s, double t,
+ const path3& p, const path3& q, double fuzz2)
+{
+ triple P=p.point(s);
+ for(size_t i=0; i < S.size(); ++i)
+ if((p.point(S[i])-P).abs2() <= fuzz2) return;
+ S.push_back(s);
+ T.push_back(t);
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ double pscale, double qscale, double poffset, double qoffset,
+ const path3& p, const path3& q, double fuzz2, bool single)
+{
+ if(single) {
+ s=s*pscale+poffset;
+ t=t*qscale+qoffset;
+ } else {
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i)
+ add(S,T,pscale*S1[i]+poffset,qscale*T1[i]+qoffset,p,q,fuzz2);
+ }
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ const path3& p, const path3& q, double fuzz2, bool single)
+{
+ size_t n=S1.size();
+ if(single) {
+ if(n > 0) {
+ s=S1[0];
+ t=T1[0];
+ }
+ } else {
+ for(size_t i=0; i < n; ++i)
+ add(S,T,S1[i],T1[i],p,q,fuzz2);
+ }
+}
+
+bool intersections(double &s, double &t, std::vector<double>& S,
+ std::vector<double>& T, path3& p, path3& q,
+ double fuzz, bool single, bool exact, unsigned depth)
+{
+ if(errorstream::interrupt) throw interrupted();
+
+ double fuzz2=max(fuzzFactor*fuzz*fuzz,Fuzz2);
+
+ Int lp=p.length();
+ if(lp == 0 && exact) {
+ std::vector<double> T1,S1;
+ intersections(T1,S1,q,p.point(lp),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz2,single);
+ return S1.size() > 0;
+ }
+
+ Int lq=q.length();
+ if(lq == 0 && exact) {
+ std::vector<double> S1,T1;
+ intersections(S1,T1,p,q.point(lq),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz2,single);
+ return S1.size() > 0;
+ }
+
+ triple maxp=p.max();
+ triple minp=p.min();
+ triple maxq=q.max();
+ triple minq=q.min();
+
+ if(maxp.getx()+fuzz >= minq.getx() &&
+ maxp.gety()+fuzz >= minq.gety() &&
+ maxp.getz()+fuzz >= minq.getz() &&
+ maxq.getx()+fuzz >= minp.getx() &&
+ maxq.gety()+fuzz >= minp.gety() &&
+ maxq.getz()+fuzz >= minp.getz()) {
+ // Overlapping bounding boxes
+
+ --depth;
+ fuzz *= 2;
+
+ if((maxp-minp).length()+(maxq-minq).length() <= fuzz || depth == 0) {
+ if(single) {
+ s=0.5;
+ t=0.5;
+ } else {
+ S.push_back(0.5);
+ T.push_back(0.5);
+ }
+ return true;
+ }
+
+ path3 p1,p2;
+ double pscale,poffset;
+
+ std::vector<double> S1,T1;
+
+ fuzz2=max(fuzzFactor*fuzz*fuzz,Fuzz2);
+
+ if(lp <= 1) {
+ if(lp == 1) p.halve(p1,p2);
+ if(lp == 0 || p1 == p || p2 == p) {
+ intersections(T1,S1,q,p.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz2,single);
+ return S1.size() > 0;
+ }
+ pscale=poffset=0.5;
+ } else {
+ Int tp=lp/2;
+ p1=p.subpath(0,tp);
+ p2=p.subpath(tp,lp);
+ poffset=tp;
+ pscale=1.0;
+ }
+
+ path3 q1,q2;
+ double qscale,qoffset;
+
+ if(lq <= 1) {
+ if(lq == 1) q.halve(q1,q2);
+ if(lq == 0 || q1 == q || q2 == q) {
+ intersections(S1,T1,p,q.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz2,single);
+ return S1.size() > 0;
+ }
+ qscale=qoffset=0.5;
+ } else {
+ Int tq=lq/2;
+ q1=q.subpath(0,tq);
+ q2=q.subpath(tq,lq);
+ qoffset=tq;
+ qscale=1.0;
+ }
+
+ bool Short=lp == 1 && lq == 1;
+
+ static size_t maxcount=9;
+ size_t count=0;
+
+ if(intersections(s,t,S1,T1,p1,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,0.0,p,q,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p1,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,qoffset,p,q,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,0.0,p,q,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,qoffset,p,q,fuzz2,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ return S.size() > 0;
+ }
+ return false;
+}
+
+// }}}
+
+path3 concat(const path3& p1, const path3& p2)
+{
+ Int n1 = p1.length(), n2 = p2.length();
+
+ if (n1 == -1) return p2;
+ if (n2 == -1) return p1;
+ triple a=p1.point(n1);
+ triple b=p2.point((Int) 0);
+
+ mem::vector<solvedKnot3> nodes(n1+n2+1);
+
+ Int i = 0;
+ nodes[0].pre = p1.point((Int) 0);
+ for (Int j = 0; j < n1; j++) {
+ nodes[i].point = p1.point(j);
+ nodes[i].straight = p1.straight(j);
+ nodes[i].post = p1.postcontrol(j);
+ nodes[i+1].pre = p1.precontrol(j+1);
+ i++;
+ }
+ for (Int j = 0; j < n2; j++) {
+ nodes[i].point = p2.point(j);
+ nodes[i].straight = p2.straight(j);
+ nodes[i].post = p2.postcontrol(j);
+ nodes[i+1].pre = p2.precontrol(j+1);
+ i++;
+ }
+ nodes[i].point = nodes[i].post = p2.point(n2);
+
+ return path3(nodes, i+1);
+}
+
+path3 transformed(const array& t, const path3& p)
+{
+ Int n = p.size();
+ mem::vector<solvedKnot3> nodes(n);
+
+ for (Int i = 0; i < n; ++i) {
+ nodes[i].pre = t * p.precontrol(i);
+ nodes[i].point = t * p.point(i);
+ nodes[i].post = t * p.postcontrol(i);
+ nodes[i].straight = p.straight(i);
+ }
+
+ return path3(nodes, n, p.cyclic());
+}
+
+path3 transformed(const double* t, const path3& p)
+{
+ Int n = p.size();
+ mem::vector<solvedKnot3> nodes(n);
+
+ for(Int i=0; i < n; ++i) {
+ nodes[i].pre=t*p.precontrol(i);
+ nodes[i].point=t*p.point(i);
+ nodes[i].post=t*p.postcontrol(i);
+ nodes[i].straight=p.straight(i);
+ }
+
+ return path3(nodes, n, p.cyclic());
+}
+
+template<class T>
+struct Split {
+ T m0,m1,m2,m3,m4,m5;
+ Split(T z0, T c0, T c1, T z1) {
+ m0=0.5*(z0+c0);
+ m1=0.5*(c0+c1);
+ m2=0.5*(c1+z1);
+ m3=0.5*(m0+m1);
+ m4=0.5*(m1+m2);
+ m5=0.5*(m3+m4);
+ }
+};
+
+double cornerbound(double *P, double (*m)(double, double))
+{
+ double b=m(P[0],P[3]);
+ b=m(b,P[12]);
+ return m(b,P[15]);
+}
+
+double controlbound(double *P, double (*m)(double, double))
+{
+ double b=m(P[1],P[2]);
+ b=m(b,P[4]);
+ b=m(b,P[5]);
+ b=m(b,P[6]);
+ b=m(b,P[7]);
+ b=m(b,P[8]);
+ b=m(b,P[9]);
+ b=m(b,P[10]);
+ b=m(b,P[11]);
+ b=m(b,P[13]);
+ return m(b,P[14]);
+}
+
+double bound(double *P, double (*m)(double, double), double b,
+ double fuzz, int depth)
+{
+ b=m(b,cornerbound(P,m));
+ if(m(-1.0,1.0)*(b-controlbound(P,m)) >= -fuzz || depth == 0)
+ return b;
+
+ --depth;
+ fuzz *= 2;
+
+ Split<double> c0(P[0],P[1],P[2],P[3]);
+ Split<double> c1(P[4],P[5],P[6],P[7]);
+ Split<double> c2(P[8],P[9],P[10],P[11]);
+ Split<double> c3(P[12],P[13],P[14],P[15]);
+
+ Split<double> c4(P[12],P[8],P[4],P[0]);
+ Split<double> c5(c3.m0,c2.m0,c1.m0,c0.m0);
+ Split<double> c6(c3.m3,c2.m3,c1.m3,c0.m3);
+ Split<double> c7(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split<double> c8(c3.m4,c2.m4,c1.m4,c0.m4);
+ Split<double> c9(c3.m2,c2.m2,c1.m2,c0.m2);
+ Split<double> c10(P[15],P[11],P[7],P[3]);
+
+ // Check all 4 Bezier subpatches.
+ double s0[]={c4.m5,c5.m5,c6.m5,c7.m5,c4.m3,c5.m3,c6.m3,c7.m3,
+ c4.m0,c5.m0,c6.m0,c7.m0,P[12],c3.m0,c3.m3,c3.m5};
+ b=bound(s0,m,b,fuzz,depth);
+ double s1[]={P[0],c0.m0,c0.m3,c0.m5,c4.m2,c5.m2,c6.m2,c7.m2,
+ c4.m4,c5.m4,c6.m4,c7.m4,c4.m5,c5.m5,c6.m5,c7.m5};
+ b=bound(s1,m,b,fuzz,depth);
+ double s2[]={c0.m5,c0.m4,c0.m2,P[3],c7.m2,c8.m2,c9.m2,c10.m2,
+ c7.m4,c8.m4,c9.m4,c10.m4,c7.m5,c8.m5,c9.m5,c10.m5};
+ b=bound(s2,m,b,fuzz,depth);
+ double s3[]={c7.m5,c8.m5,c9.m5,c10.m5,c7.m3,c8.m3,c9.m3,c10.m3,
+ c7.m0,c8.m0,c9.m0,c10.m0,c3.m5,c3.m4,c3.m2,P[15]};
+ return bound(s3,m,b,fuzz,depth);
+}
+
+double cornerbound(triple *P, double (*m)(double, double),
+ double (*f)(const triple&))
+{
+ double b=m(f(P[0]),f(P[3]));
+ b=m(b,f(P[12]));
+ return m(b,f(P[15]));
+}
+
+// Return f evaluated at controlling vertex of bounding box of n control
+// net points for similiar-triangle transform x'=x/z, y'=y/z, where z < 0.
+double ratiobound(triple *P, double (*m)(double, double),
+ double (*f)(const triple&), int n)
+{
+ double MX=-P[0].getx();
+ double MY=-P[0].gety();
+ double Z=P[0].getz();
+ double MZ=-Z;
+ for(int i=1; i < n; ++i) {
+ triple v=P[i];
+ MX=m(MX,-v.getx());
+ MY=m(MY,-v.gety());
+ Z=m(Z,v.getz());
+ MZ=m(MZ,-v.getz());
+ }
+ return m(f(triple(-MX,-MY,Z)),f(triple(-MX,-MY,-MZ)));
+}
+
+double controlbound(triple *P, double (*m)(double, double),
+ double (*f)(const triple&))
+{
+ double b=m(f(P[1]),f(P[2]));
+ b=m(b,f(P[4]));
+ b=m(b,f(P[5]));
+ b=m(b,f(P[6]));
+ b=m(b,f(P[7]));
+ b=m(b,f(P[8]));
+ b=m(b,f(P[9]));
+ b=m(b,f(P[10]));
+ b=m(b,f(P[11]));
+ b=m(b,f(P[13]));
+ return m(b,f(P[14]));
+}
+
+double bound(triple *P, double (*m)(double, double),
+ double (*f)(const triple&), double b, double fuzz, int depth)
+{
+ b=m(b,cornerbound(P,m,f));
+ if(m(-1.0,1.0)*(b-ratiobound(P,m,f,16)) >= -fuzz || depth == 0)
+ return b;
+
+ --depth;
+ fuzz *= 2;
+
+ Split<triple> c0(P[0],P[1],P[2],P[3]);
+ Split<triple> c1(P[4],P[5],P[6],P[7]);
+ Split<triple> c2(P[8],P[9],P[10],P[11]);
+ Split<triple> c3(P[12],P[13],P[14],P[15]);
+
+ Split<triple> c4(P[12],P[8],P[4],P[0]);
+ Split<triple> c5(c3.m0,c2.m0,c1.m0,c0.m0);
+ Split<triple> c6(c3.m3,c2.m3,c1.m3,c0.m3);
+ Split<triple> c7(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split<triple> c8(c3.m4,c2.m4,c1.m4,c0.m4);
+ Split<triple> c9(c3.m2,c2.m2,c1.m2,c0.m2);
+ Split<triple> c10(P[15],P[11],P[7],P[3]);
+
+ // Check all 4 Bezier subpatches.
+ triple s0[]={c4.m5,c5.m5,c6.m5,c7.m5,c4.m3,c5.m3,c6.m3,c7.m3,
+ c4.m0,c5.m0,c6.m0,c7.m0,P[12],c3.m0,c3.m3,c3.m5};
+ b=bound(s0,m,f,b,fuzz,depth);
+ triple s1[]={P[0],c0.m0,c0.m3,c0.m5,c4.m2,c5.m2,c6.m2,c7.m2,
+ c4.m4,c5.m4,c6.m4,c7.m4,c4.m5,c5.m5,c6.m5,c7.m5};
+ b=bound(s1,m,f,b,fuzz,depth);
+ triple s2[]={c0.m5,c0.m4,c0.m2,P[3],c7.m2,c8.m2,c9.m2,c10.m2,
+ c7.m4,c8.m4,c9.m4,c10.m4,c7.m5,c8.m5,c9.m5,c10.m5};
+ b=bound(s2,m,f,b,fuzz,depth);
+ triple s3[]={c7.m5,c8.m5,c9.m5,c10.m5,c7.m3,c8.m3,c9.m3,c10.m3,
+ c7.m0,c8.m0,c9.m0,c10.m0,c3.m5,c3.m4,c3.m2,P[15]};
+ return bound(s3,m,f,b,fuzz,depth);
+}
+
+template<class T>
+struct Splittri {
+ T l003,p102,p012,p201,p111,p021,r300,p210,p120,u030;
+ T u021,u120;
+ T p033,p231,p330;
+ T p123;
+ T l012,p312,r210,l102,p303,r201;
+ T u012,u210,l021,p4xx,r120,px4x,pxx4,l201,r102;
+ T l210,r012,l300;
+ T r021,u201,r030;
+ T u102,l120,l030;
+ T l111,r111,u111,c111;
+
+ Splittri(const T *p) {
+ l003=p[0];
+ p102=p[1];
+ p012=p[2];
+ p201=p[3];
+ p111=p[4];
+ p021=p[5];
+ r300=p[6];
+ p210=p[7];
+ p120=p[8];
+ u030=p[9];
+
+ u021=0.5*(u030+p021);
+ u120=0.5*(u030+p120);
+
+ p033=0.5*(p021+p012);
+ p231=0.5*(p120+p111);
+ p330=0.5*(p120+p210);
+
+ p123=0.5*(p012+p111);
+
+ l012=0.5*(p012+l003);
+ p312=0.5*(p111+p201);
+ r210=0.5*(p210+r300);
+
+ l102=0.5*(l003+p102);
+ p303=0.5*(p102+p201);
+ r201=0.5*(p201+r300);
+
+ u012=0.5*(u021+p033);
+ u210=0.5*(u120+p330);
+ l021=0.5*(p033+l012);
+ p4xx=0.5*p231+0.25*(p111+p102);
+ r120=0.5*(p330+r210);
+ px4x=0.5*p123+0.25*(p111+p210);
+ pxx4=0.25*(p021+p111)+0.5*p312;
+ l201=0.5*(l102+p303);
+ r102=0.5*(p303+r201);
+
+ l210=0.5*(px4x+l201); // = m120
+ r012=0.5*(px4x+r102); // = m021
+ l300=0.5*(l201+r102); // = r003 = m030
+
+ r021=0.5*(pxx4+r120); // = m012
+ u201=0.5*(u210+pxx4); // = m102
+ r030=0.5*(u210+r120); // = u300 = m003
+
+ u102=0.5*(u012+p4xx); // = m201
+ l120=0.5*(l021+p4xx); // = m210
+ l030=0.5*(u012+l021); // = u003 = m300
+
+ l111=0.5*(p123+l102);
+ r111=0.5*(p312+r210);
+ u111=0.5*(u021+p231);
+ c111=0.25*(p033+p330+p303+p111);
+ }
+};
+
+// Return the extremum of the vertices of a Bezier triangle.
+double cornerboundtri(double *P, double (*m)(double, double))
+{
+ double b=m(P[0],P[6]);
+ return m(b,P[9]);
+}
+
+double cornerboundtri(triple *P, double (*m)(double, double),
+ double (*f)(const triple&))
+{
+ double b=m(f(P[0]),f(P[6]));
+ return m(b,f(P[9]));
+}
+
+// Return the extremum of the non-vertex control points of a Bezier triangle.
+double controlboundtri(double *P, double (*m)(double, double))
+{
+ double b=m(P[1],P[2]);
+ b=m(b,P[3]);
+ b=m(b,P[4]);
+ b=m(b,P[5]);
+ b=m(b,P[7]);
+ return m(b,P[8]);
+}
+
+double controlboundtri(triple *P, double (*m)(double, double),
+ double (*f)(const triple&))
+{
+ double b=m(f(P[1]),f(P[2]));
+ b=m(b,f(P[3]));
+ b=m(b,f(P[4]));
+ b=m(b,f(P[5]));
+ b=m(b,f(P[7]));
+ return m(b,f(P[8]));
+}
+
+// Return the global bound of a Bezier triangle.
+double boundtri(double *P, double (*m)(double, double), double b,
+ double fuzz, int depth)
+{
+ b=m(b,cornerboundtri(P,m));
+ if(m(-1.0,1.0)*(b-controlboundtri(P,m)) >= -fuzz || depth == 0)
+ return b;
+
+ --depth;
+ fuzz *= 2;
+
+ Splittri<double> s(P);
+
+ double l[]={s.l003,s.l102,s.l012,s.l201,s.l111,
+ s.l021,s.l300,s.l210,s.l120,s.l030}; // left
+ b=boundtri(l,m,b,fuzz,depth);
+
+ double r[]={s.l300,s.r102,s.r012,s.r201,s.r111,
+ s.r021,s.r300,s.r210,s.r120,s.r030}; // right
+ b=boundtri(r,m,b,fuzz,depth);
+
+ double u[]={s.l030,s.u102,s.u012,s.u201,s.u111,
+ s.u021,s.r030,s.u210,s.u120,s.u030}; // up
+ b=boundtri(u,m,b,fuzz,depth);
+
+ double c[]={s.r030,s.u201,s.r021,s.u102,s.c111,
+ s.r012,s.l030,s.l120,s.l210,s.l300}; // center
+ return boundtri(c,m,b,fuzz,depth);
+}
+
+double boundtri(triple *P, double (*m)(double, double),
+ double (*f)(const triple&), double b, double fuzz, int depth)
+{
+ b=m(b,cornerboundtri(P,m,f));
+ if(m(-1.0,1.0)*(b-ratiobound(P,m,f,10)) >= -fuzz || depth == 0)
+ return b;
+
+ --depth;
+ fuzz *= 2;
+
+ Splittri<triple> s(P);
+
+ triple l[]={s.l003,s.l102,s.l012,s.l201,s.l111,
+ s.l021,s.l300,s.l210,s.l120,s.l030}; // left
+ b=boundtri(l,m,f,b,fuzz,depth);
+
+ triple r[]={s.l300,s.r102,s.r012,s.r201,s.r111,
+ s.r021,s.r300,s.r210,s.r120,s.r030}; // right
+ b=boundtri(r,m,f,b,fuzz,depth);
+
+ triple u[]={s.l030,s.u102,s.u012,s.u201,s.u111,
+ s.u021,s.r030,s.u210,s.u120,s.u030}; // up
+ b=boundtri(u,m,f,b,fuzz,depth);
+
+ triple c[]={s.r030,s.u201,s.r021,s.u102,s.c111,
+ s.r012,s.l030,s.l120,s.l210,s.l300}; // center
+ return boundtri(c,m,f,b,fuzz,depth);
+}
+
+inline void add(std::vector<double>& T, std::vector<double>& U,
+ std::vector<double>& V, double t, double u, double v,
+ const path3& p, double fuzz2)
+{
+ triple z=p.point(t);
+ size_t n=T.size();
+ for(size_t i=0; i < n; ++i)
+ if((p.point(T[i])-z).abs2() <= fuzz2) return;
+ T.push_back(t);
+ U.push_back(u);
+ V.push_back(v);
+}
+
+void add(std::vector<double>& T, std::vector<double>& U,
+ std::vector<double>& V, std::vector<double>& T1,
+ std::vector<double>& U1, std::vector<double>& V1,
+ const path3& p, double tscale, double toffset,
+ double uoffset, double voffset, double fuzz2)
+{
+ size_t n=T1.size();
+ for(size_t i=0; i < n; ++i)
+ add(T,U,V,tscale*T1[i]+toffset,0.5*U1[i]+uoffset,0.5*V1[i]+voffset,p,
+ fuzz2);
+}
+
+void bounds(triple& Pmin, triple& Pmax, triple *P, double fuzz)
+{
+ double Px[]={P[0].getx(),P[1].getx(),P[2].getx(),P[3].getx(),
+ P[4].getx(),P[5].getx(),P[6].getx(),P[7].getx(),
+ P[8].getx(),P[9].getx(),P[10].getx(),P[11].getx(),
+ P[12].getx(),P[13].getx(),P[14].getx(),P[15].getx()};
+ double bx=Px[0];
+ double xmin=bound(Px,min,bx,fuzz,maxdepth);
+ double xmax=bound(Px,max,bx,fuzz,maxdepth);
+
+ double Py[]={P[0].gety(),P[1].gety(),P[2].gety(),P[3].gety(),
+ P[4].gety(),P[5].gety(),P[6].gety(),P[7].gety(),
+ P[8].gety(),P[9].gety(),P[10].gety(),P[11].gety(),
+ P[12].gety(),P[13].gety(),P[14].gety(),P[15].gety()};
+ double by=Py[0];
+ double ymin=bound(Py,min,by,fuzz,maxdepth);
+ double ymax=bound(Py,max,by,fuzz,maxdepth);
+
+ double Pz[]={P[0].getz(),P[1].getz(),P[2].getz(),P[3].getz(),
+ P[4].getz(),P[5].getz(),P[6].getz(),P[7].getz(),
+ P[8].getz(),P[9].getz(),P[10].getz(),P[11].getz(),
+ P[12].getz(),P[13].getz(),P[14].getz(),P[15].getz()};
+ double bz=Pz[0];
+ double zmin=bound(Pz,min,bz,fuzz,maxdepth);
+ double zmax=bound(Pz,max,bz,fuzz,maxdepth);
+ Pmin=triple(xmin,ymin,zmin);
+ Pmax=triple(xmax,ymax,zmax);
+}
+
+inline double abs2(double x, double y, double z)
+{
+ return x*x+y*y+z*z;
+}
+
+bool intersections(double& U, double& V, const triple& v, triple *P,
+ double fuzz, unsigned depth)
+{
+ if(errorstream::interrupt) throw interrupted();
+
+ triple Pmin,Pmax;
+ bounds(Pmin,Pmax,P,fuzz);
+
+ double x=P[0].getx();
+ double y=P[0].gety();
+ double z=P[0].getz();
+ double X=x, Y=y, Z=z;
+ for(int i=1; i < 16; ++i) {
+ triple v=P[i];
+ double vx=v.getx();
+ x=min(x,vx);
+ X=max(X,vx);
+ double vy=v.gety();
+ y=min(y,vy);
+ Y=max(Y,vy);
+ double vz=v.getz();
+ z=min(z,vz);
+ Z=max(Z,vz);
+ }
+
+ if(X+fuzz >= v.getx() &&
+ Y+fuzz >= v.gety() &&
+ Z+fuzz >= v.getz() &&
+ v.getx()+fuzz >= x &&
+ v.gety()+fuzz >= y &&
+ v.getz()+fuzz >= z) { // Overlapping bounding boxes
+
+ --depth;
+ fuzz *= 2;
+
+ if(abs2(X-x,Y-y,Z-z) <= fuzz*fuzz || depth == 0) {
+ U=0.5;
+ V=0.5;
+ return true;
+ }
+
+// Compute the control points of the four subpatches obtained by splitting
+// the patch with control points P at u=v=1/2.
+ Split<triple> c0(P[0],P[1],P[2],P[3]);
+ Split<triple> c1(P[4],P[5],P[6],P[7]);
+ Split<triple> c2(P[8],P[9],P[10],P[11]);
+ Split<triple> c3(P[12],P[13],P[14],P[15]);
+
+ Split<triple> c4(P[12],P[8],P[4],P[0]);
+ Split<triple> c5(c3.m0,c2.m0,c1.m0,c0.m0);
+ Split<triple> c6(c3.m3,c2.m3,c1.m3,c0.m3);
+ Split<triple> c7(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split<triple> c8(c3.m4,c2.m4,c1.m4,c0.m4);
+ Split<triple> c9(c3.m2,c2.m2,c1.m2,c0.m2);
+ Split<triple> c10(P[15],P[11],P[7],P[3]);
+
+ // Check all 4 Bezier subpatches.
+
+ double U1,V1;
+ triple Q0[]={P[0],c0.m0,c0.m3,c0.m5,c4.m2,c5.m2,c6.m2,c7.m2,
+ c4.m4,c5.m4,c6.m4,c7.m4,c4.m5,c5.m5,c6.m5,c7.m5};
+ if(intersections(U1,V1,v,Q0,fuzz,depth)) {
+ U=0.5*U1;
+ V=0.5*V1;
+ return true;
+ }
+
+ triple Q1[]={c0.m5,c0.m4,c0.m2,P[3],c7.m2,c8.m2,c9.m2,c10.m2,
+ c7.m4,c8.m4,c9.m4,c10.m4,c7.m5,c8.m5,c9.m5,c10.m5};
+ if(intersections(U1,V1,v,Q1,fuzz,depth)) {
+ U=0.5*U1;
+ V=0.5*V1+0.5;
+ return true;
+ }
+
+ triple Q2[]={c7.m5,c8.m5,c9.m5,c10.m5,c7.m3,c8.m3,c9.m3,c10.m3,
+ c7.m0,c8.m0,c9.m0,c10.m0,c3.m5,c3.m4,c3.m2,P[15]};
+ if(intersections(U1,V1,v,Q2,fuzz,depth)) {
+ U=0.5*U1+0.5;
+ V=0.5*V1+0.5;
+ return true;
+ }
+
+ triple Q3[]={c4.m5,c5.m5,c6.m5,c7.m5,c4.m3,c5.m3,c6.m3,c7.m3,
+ c4.m0,c5.m0,c6.m0,c7.m0,P[12],c3.m0,c3.m3,c3.m5};
+ if(intersections(U1,V1,v,Q3,fuzz,depth)) {
+ U=0.5*U1+0.5;
+ V=0.5*V1;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool intersections(std::vector<double>& T, std::vector<double>& U,
+ std::vector<double>& V, path3& p, triple *P,
+ double fuzz, bool single, unsigned depth)
+{
+ if(errorstream::interrupt) throw interrupted();
+
+ triple pmin=p.min();
+ triple pmax=p.max();
+
+ double x=P[0].getx();
+ double y=P[0].gety();
+ double z=P[0].getz();
+ double X=x, Y=y, Z=z;
+ for(int i=1; i < 16; ++i) {
+ triple v=P[i];
+ double vx=v.getx();
+ x=min(x,vx);
+ X=max(X,vx);
+ double vy=v.gety();
+ y=min(y,vy);
+ Y=max(Y,vy);
+ double vz=v.getz();
+ z=min(z,vz);
+ Z=max(Z,vz);
+ }
+
+ if(X+fuzz >= pmin.getx() &&
+ Y+fuzz >= pmin.gety() &&
+ Z+fuzz >= pmin.getz() &&
+ pmax.getx()+fuzz >= x &&
+ pmax.gety()+fuzz >= y &&
+ pmax.getz()+fuzz >= z) { // Overlapping bounding boxes
+
+ --depth;
+ fuzz *= 2;
+
+ if(((pmax-pmin).length()+sqrt(abs2(X-x,Y-y,Z-z)) <= fuzz) || depth == 0) {
+ T.push_back(0.5);
+ U.push_back(0.5);
+ V.push_back(0.5);
+ return true;
+ }
+
+ Int lp=p.length();
+
+ path3 p0,p1;
+ p.halve(p0,p1);
+
+ std::vector<double> T1,U1,V1;
+ double tscale,toffset;
+
+ double fuzz2=max(fuzzFactor*fuzz*fuzz,Fuzz2);
+
+ if(lp <= 1) {
+ if(lp == 1) p.halve(p0,p1);
+ if(lp == 0 || p0 == p || p1 == p) {
+ double u,v;
+ if(intersections(u,v,p.point((Int) 0),P,fuzz,depth)) {
+ T1.push_back(0.0);
+ U1.push_back(u);
+ V1.push_back(v);
+ add(T,U,V,T1,U1,V1,p,1.0,0.0,0.0,0.0,fuzz2);
+ }
+ return T1.size() > 0;
+ }
+ tscale=toffset=0.5;
+ } else {
+ Int tp=lp/2;
+ p0=p.subpath(0,tp);
+ p1=p.subpath(tp,lp);
+ toffset=tp;
+ tscale=1.0;
+ }
+
+ Split<triple> c0(P[0],P[1],P[2],P[3]);
+ Split<triple> c1(P[4],P[5],P[6],P[7]);
+ Split<triple> c2(P[8],P[9],P[10],P[11]);
+ Split<triple> c3(P[12],P[13],P[14],P[15]);
+
+ Split<triple> c4(P[12],P[8],P[4],P[0]);
+ Split<triple> c5(c3.m0,c2.m0,c1.m0,c0.m0);
+ Split<triple> c6(c3.m3,c2.m3,c1.m3,c0.m3);
+ Split<triple> c7(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split<triple> c8(c3.m4,c2.m4,c1.m4,c0.m4);
+ Split<triple> c9(c3.m2,c2.m2,c1.m2,c0.m2);
+ Split<triple> c10(P[15],P[11],P[7],P[3]);
+
+ static size_t maxcount=9;
+ size_t count=0;
+
+ bool Short=lp == 1;
+
+ // Check all 4 Bezier subpatches against p0.
+ triple Q0[]={P[0],c0.m0,c0.m3,c0.m5,c4.m2,c5.m2,c6.m2,c7.m2,
+ c4.m4,c5.m4,c6.m4,c7.m4,c4.m5,c5.m5,c6.m5,c7.m5};
+ if(intersections(T1,U1,V1,p0,Q0,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,0.0,0.0,0.0,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ T1.clear();
+ U1.clear();
+ V1.clear();
+ triple Q1[]={c0.m5,c0.m4,c0.m2,P[3],c7.m2,c8.m2,c9.m2,c10.m2,
+ c7.m4,c8.m4,c9.m4,c10.m4,c7.m5,c8.m5,c9.m5,c10.m5};
+ if(intersections(T1,U1,V1,p0,Q1,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,0.0,0.0,0.5,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ T1.clear();
+ U1.clear();
+ V1.clear();
+ triple Q2[]={c7.m5,c8.m5,c9.m5,c10.m5,c7.m3,c8.m3,c9.m3,c10.m3,
+ c7.m0,c8.m0,c9.m0,c10.m0,c3.m5,c3.m4,c3.m2,P[15]};
+ if(intersections(T1,U1,V1,p0,Q2,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,0.0,0.5,0.5,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ T1.clear();
+ U1.clear();
+ V1.clear();
+ triple Q3[]={c4.m5,c5.m5,c6.m5,c7.m5,c4.m3,c5.m3,c6.m3,c7.m3,
+ c4.m0,c5.m0,c6.m0,c7.m0,P[12],c3.m0,c3.m3,c3.m5};
+ if(intersections(T1,U1,V1,p0,Q3,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,0.0,0.5,0.0,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ // Check all 4 Bezier subpatches against p1.
+ T1.clear();
+ U1.clear();
+ V1.clear();
+ if(intersections(T1,U1,V1,p1,Q0,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,toffset,0.0,0.0,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ T1.clear();
+ U1.clear();
+ V1.clear();
+ if(intersections(T1,U1,V1,p1,Q1,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,toffset,0.0,0.5,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ T1.clear();
+ U1.clear();
+ V1.clear();
+ if(intersections(T1,U1,V1,p1,Q2,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,toffset,0.5,0.5,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ T1.clear();
+ U1.clear();
+ V1.clear();
+ if(intersections(T1,U1,V1,p1,Q3,fuzz,single,depth)) {
+ add(T,U,V,T1,U1,V1,p,tscale,toffset,0.5,0.0,fuzz2);
+ if(single || depth <= mindepth)
+ return true;
+ count += T1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ return T.size() > 0;
+ }
+ return false;
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/path3.h b/graphics/asymptote/path3.h
new file mode 100644
index 0000000000..14ed3dd1ca
--- /dev/null
+++ b/graphics/asymptote/path3.h
@@ -0,0 +1,392 @@
+/*****
+ * path.h
+ * John Bowman
+ *
+ * Stores a 3D piecewise cubic spline with known control points.
+ *
+ *****/
+
+#ifndef PATH3_H
+#define PATH3_H
+
+#include <cfloat>
+
+#include "mod.h"
+#include "triple.h"
+#include "bbox3.h"
+#include "path.h"
+#include "arrayop.h"
+
+namespace camp {
+
+void checkEmpty3(Int n);
+
+// Used in the storage of solved path3 knots.
+struct solvedKnot3 : public gc {
+ triple pre;
+ triple point;
+ triple post;
+ bool straight;
+ solvedKnot3() : straight(false) {}
+
+ friend bool operator== (const solvedKnot3& p, const solvedKnot3& q)
+ {
+ return p.pre == q.pre && p.point == q.point && p.post == q.post;
+ }
+};
+
+class path3 : public gc {
+ bool cycles; // If the path3 is closed in a loop
+
+ Int n; // The number of knots
+
+ mem::vector<solvedKnot3> nodes;
+ mutable double cached_length; // Cache length since path3 is immutable.
+
+ mutable bbox3 box;
+ mutable bbox3 times; // Times where minimum and maximum extents are attained.
+
+public:
+ path3()
+ : cycles(false), n(0), nodes(), cached_length(-1) {}
+
+ // Create a path3 of a single point
+ path3(triple z, bool = false)
+ : cycles(false), n(1), nodes(1), cached_length(-1)
+ {
+ nodes[0].pre = nodes[0].point = nodes[0].post = z;
+ nodes[0].straight = false;
+ }
+
+ // Creates path3 from a list of knots. This will be used by camp
+ // methods such as the guide solver, but should probably not be used by a
+ // user of the system unless he knows what he is doing.
+ path3(mem::vector<solvedKnot3>& nodes, Int n, bool cycles = false)
+ : cycles(cycles), n(n), nodes(nodes), cached_length(-1)
+ {
+ }
+
+ friend bool operator== (const path3& p, const path3& q)
+ {
+ return p.cycles == q.cycles && p.nodes == q.nodes;
+ }
+
+public:
+ path3(solvedKnot3 n1, solvedKnot3 n2)
+ : cycles(false), n(2), nodes(2), cached_length(-1)
+ {
+ nodes[0] = n1;
+ nodes[1] = n2;
+ nodes[0].pre = nodes[0].point;
+ nodes[1].post = nodes[1].point;
+ }
+
+ // Copy constructor
+ path3(const path3& p)
+ : cycles(p.cycles), n(p.n), nodes(p.nodes), cached_length(p.cached_length),
+ box(p.box)
+ {}
+
+ path3 unstraighten() const
+ {
+ path3 P=path3(*this);
+ for(int i=0; i < n; ++i)
+ P.nodes[i].straight=false;
+ return P;
+ }
+
+ virtual ~path3()
+ {
+ }
+
+ // Getting control points
+ Int size() const
+ {
+ return n;
+ }
+
+ bool empty() const
+ {
+ return n == 0;
+ }
+
+ Int length() const
+ {
+ return cycles ? n : n-1;
+ }
+
+ bool cyclic() const
+ {
+ return cycles;
+ }
+
+ mem::vector<solvedKnot3>& Nodes() {
+ return nodes;
+ }
+
+ bool straight(Int t) const
+ {
+ if (cycles) return nodes[imod(t,n)].straight;
+ return (t >= 0 && t < n) ? nodes[t].straight : false;
+ }
+
+ bool piecewisestraight() const
+ {
+ Int L=length();
+ for(Int i=0; i < L; ++i)
+ if(!straight(i)) return false;
+ return true;
+ }
+
+ triple point(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].point;
+ }
+
+ triple point(double t) const;
+
+ triple precontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].pre;
+ }
+
+ triple precontrol(double t) const;
+
+ triple postcontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].post;
+ }
+
+ triple postcontrol(double t) const;
+
+ inline double norm(const triple& z0, const triple& c0, const triple& c1,
+ const triple& z1) const {
+ return Fuzz2*camp::max((c0-z0).abs2(),
+ camp::max((c1-z0).abs2(),(z1-z0).abs2()));
+ }
+
+ triple predir(Int t, bool normalize=true) const {
+ if(!cycles && t <= 0) return triple(0,0,0);
+ triple z1=point(t);
+ triple c1=precontrol(t);
+ triple dir=3.0*(z1-c1);
+ if(!normalize) return dir;
+ triple z0=point(t-1);
+ triple c0=postcontrol(t-1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*c1-c0-z1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ triple postdir(Int t, bool normalize=true) const {
+ if(!cycles && t >= n-1) return triple(0,0,0);
+ triple c0=postcontrol(t);
+ triple z0=point(t);
+ triple dir=3.0*(c0-z0);
+ triple z1=point(t+1);
+ triple c1=precontrol(t+1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(!normalize) return dir;
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=z0-2.0*c0+c1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ triple dir(Int t, Int sign, bool normalize=true) const {
+ if(sign == 0) {
+ triple v=predir(t,normalize)+postdir(t,normalize);
+ return normalize ? unit(v) : 0.5*v;
+ }
+ if(sign > 0) return postdir(t,normalize);
+ return predir(t,normalize);
+ }
+
+ triple dir(double t, bool normalize=true) const {
+ if(!cycles) {
+ if(t <= 0) return postdir((Int) 0,normalize);
+ if(t >= n-1) return predir(n-1,normalize);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return dir(i,0,normalize);
+ triple z0=point(i);
+ triple c0=postcontrol(i);
+ triple c1=precontrol(i+1);
+ triple z1=point(i+1);
+ triple a=3.0*(z1-z0)+9.0*(c0-c1);
+ triple b=6.0*(z0+c1)-12.0*c0;
+ triple c=3.0*(c0-z0);
+ triple dir=a*t*t+b*t+c;
+ if(!normalize) return dir;
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*a*t+b;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(a);
+ }
+
+ triple postaccel(Int t) const {
+ if(!cycles && t >= n-1) return triple(0,0,0);
+ triple z0=point(t);
+ triple c0=postcontrol(t);
+ triple c1=precontrol(t+1);
+ return 6.0*(z0+c1)-12.0*c0;
+ }
+
+ triple preaccel(Int t) const {
+ if(!cycles && t <= 0) return triple(0,0,0);
+ triple z0=point(t-1);
+ triple c0=postcontrol(t-1);
+ triple c1=precontrol(t);
+ triple z1=point(t);
+ return 6.0*(z1+c0)-12.0*c1;
+ }
+
+ triple accel(Int t, Int sign) const {
+ if(sign == 0) return 0.5*(preaccel(t)+postaccel(t));
+ if(sign > 0) return postaccel(t);
+ return preaccel(t);
+ }
+
+ triple accel(double t) const {
+ if(!cycles) {
+ if(t <= 0) return postaccel((Int) 0);
+ if(t >= n-1) return preaccel(n-1);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return 0.5*(postaccel(i)+preaccel(i));
+ triple z0=point(i);
+ triple c0=postcontrol(i);
+ triple c1=precontrol(i+1);
+ triple z1=point(i+1);
+ return 6.0*t*(z1-z0+3.0*(c0-c1))+6.0*(z0+c1)-12.0*c0;
+ }
+
+ // Returns the path3 traced out in reverse.
+ path3 reverse() const;
+
+ // Generates a path3 that is a section of the old path3, using the time
+ // interval given.
+ path3 subpath(Int start, Int end) const;
+ path3 subpath(double start, double end) const;
+
+ // Special case of subpath used by intersect.
+ void halve(path3 &first, path3 &second) const;
+
+ // Used by picture to determine bounding box.
+ bbox3 bounds() const;
+
+ triple mintimes() const {
+ checkEmpty3(n);
+ bounds();
+ return camp::triple(times.left,times.bottom,times.lower);
+ }
+
+ triple maxtimes() const {
+ checkEmpty3(n);
+ bounds();
+ return camp::triple(times.right,times.top,times.upper);
+ }
+
+ template<class T>
+ void addpoint(bbox3& box, T i) const {
+ box.addnonempty(point(i),times,(double) i);
+ }
+
+ double cubiclength(Int i, double goal=-1) const;
+ double arclength () const;
+ double arctime (double l) const;
+
+ triple max() const {
+ checkEmpty3(n);
+ return bounds().Max();
+ }
+
+ triple min() const {
+ checkEmpty3(n);
+ return bounds().Min();
+ }
+
+ pair ratio(double (*m)(double, double)) const;
+
+// Increment count if the path3 has a vertical component at t.
+ bool Count(Int& count, double t) const;
+
+// Count if t is in (begin,end] and z lies to the left of point(i+t).
+ void countleft(Int& count, double x, Int i, double t,
+ double begin, double end, double& mint, double& maxt) const;
+
+// Return the winding number of the region bounded by the (cyclic) path3
+// relative to the point z.
+ Int windingnumber(const triple& z) const;
+};
+
+path3 transformed(const vm::array& t, const path3& p);
+path3 transformed(const double* t, const path3& p);
+
+extern path3 nullpath3;
+extern const unsigned maxdepth;
+
+bool intersect(double& S, double& T, path3& p, path3& q, double fuzz,
+ unsigned depth=maxdepth);
+bool intersections(double& s, double& t, std::vector<double>& S,
+ std::vector<double>& T, path3& p, path3& q,
+ double fuzz, bool single, bool exact,
+ unsigned depth=maxdepth);
+void intersections(std::vector<double>& S, path3& g,
+ const triple& p, const triple& q, double fuzz);
+
+bool intersections(std::vector<double>& T, std::vector<double>& U,
+ std::vector<double>& V, path3& p, triple *P,
+ double fuzz, bool single, unsigned depth=maxdepth);
+bool intersections(double& U, double& V, const triple& v, triple *P,
+ double fuzz, unsigned depth=maxdepth);
+
+// Concatenates two path3s into a new one.
+path3 concat(const path3& p1, const path3& p2);
+
+// return the perpendicular displacement of a point z from the line through
+// points p and q.
+inline triple displacement(const triple& z, const triple& p, const triple& q)
+{
+ triple Z=z-p;
+ triple Q=unit(q-p);
+ return Z-dot(Z,Q)*Q;
+}
+
+typedef double bound_double(double *P, double (*m)(double, double), double b,
+ double fuzz, int depth);
+
+typedef double bound_triple(triple *P, double (*m)(double, double),
+ double (*f)(const triple&), double b, double fuzz,
+ int depth);
+
+bound_double bound,boundtri;
+
+double bound(triple z0, triple c0, triple c1, triple z1,
+ double (*m)(double, double),
+ double (*f)(const triple&),
+ double b, double fuzz, int depth=maxdepth);
+double bound(double *p, double (*m)(double, double),
+ double b, double fuzz, int depth);
+double bound(triple *P, double (*m)(double, double),
+ double (*f)(const triple&), double b, double fuzz,
+ int depth);
+
+double boundtri(double *P, double (*m)(double, double), double b,
+ double fuzz, int depth);
+double boundtri(triple *P, double (*m)(double, double),
+ double (*f)(const triple&), double b, double fuzz,
+ int depth);
+}
+
+#ifndef BROKEN_COMPILER
+// Delete the following line to work around problems with old broken compilers.
+GC_DECLARE_PTRFREE(camp::solvedKnot3);
+#endif
+
+#endif
diff --git a/graphics/asymptote/pen.cc b/graphics/asymptote/pen.cc
new file mode 100644
index 0000000000..5e526e5dcc
--- /dev/null
+++ b/graphics/asymptote/pen.cc
@@ -0,0 +1,46 @@
+/*****
+ * pen.cc
+ * John Bowman
+ *
+ *****/
+
+#include "pen.h"
+#include "drawelement.h"
+
+namespace camp {
+
+const char* DEFPAT="<default>";
+const char* DEFLATEXFONT="\\usefont{\\ASYencoding}{\\ASYfamily}{\\ASYseries}{\\ASYshape}";
+const char* DEFCONTEXTFONT="modern";
+const char* DEFTEXFONT="cmr12";
+const double DEFWIDTH=-1;
+const Int DEFCAP=-1;
+const Int DEFJOIN=-1;
+const double DEFMITER=0;
+const transform nullTransform=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+
+const char* PSCap[]={"butt","round","square"};
+const char* Cap[]={"square","round","extended"};
+const Int nCap=sizeof(Cap)/sizeof(char*);
+const char* Join[]={"miter","round","bevel"};
+const Int nJoin=sizeof(Join)/sizeof(char*);
+const char* OverwriteTag[]={"Allow","Suppress","SupressQuiet",
+ "Move","MoveQuiet"};
+const Int nOverwrite=sizeof(OverwriteTag)/sizeof(char*);
+const char* FillRuleTag[]={"ZeroWinding","EvenOdd"};
+const Int nFill=sizeof(FillRuleTag)/sizeof(char*);
+const char* BaseLineTag[]={"NoAlign","Align"};
+const Int nBaseLine=sizeof(BaseLineTag)/sizeof(char*);
+
+const char* ColorDeviceSuffix[]={"","","Gray","RGB","CMYK",""};
+const unsigned nColorSpace=sizeof(ColorDeviceSuffix)/sizeof(char*);
+const char* BlendMode[]={"Compatible","Normal","Multiply","Screen",
+ "Overlay","SoftLight","HardLight",
+ "ColorDodge","ColorBurn","Darken",
+ "Lighten","Difference","Exclusion",
+ "Hue","Saturation","Color","Luminosity"};
+const Int nBlendMode=sizeof(BlendMode)/sizeof(char*);
+
+pen drawElement::lastpen;
+
+}
diff --git a/graphics/asymptote/pen.h b/graphics/asymptote/pen.h
new file mode 100644
index 0000000000..1208f4a60c
--- /dev/null
+++ b/graphics/asymptote/pen.h
@@ -0,0 +1,970 @@
+/*****
+ * pen.h
+ * John Bowman 2003/03/23
+ *
+ *****/
+
+#ifndef PEN_H
+#define PEN_H
+
+#include <iomanip>
+
+#include "transform.h"
+#include "settings.h"
+#include "bbox.h"
+#include "common.h"
+#include "path.h"
+#include "array.h"
+
+namespace camp {
+
+class LineType
+{
+public:
+ vm::array pattern; // Array of PostScript style line pattern entries.
+ double offset; // The offset in the pattern at which to start drawing.
+ bool scale; // Scale the line type values by the pen width?
+ bool adjust; // Adjust the line type values to fit the arclength?
+ bool isdefault;
+
+ LineType() : offset(0.0), scale(true), adjust(true), isdefault(true) {}
+
+ LineType(vm::array pattern, double offset, bool scale, bool adjust) :
+ pattern(pattern), offset(offset), scale(scale), adjust(adjust),
+ isdefault(false) {}
+
+ void Scale(double factor) {
+ size_t n=pattern.size();
+ for(size_t i=0; i < n; i++)
+ pattern[i]=vm::read<double>(pattern,i)*factor;
+ offset *= factor;
+ }
+};
+
+extern const char* DEFPAT;
+extern const char* DEFLATEXFONT;
+extern const char* DEFCONTEXTFONT;
+extern const char* DEFTEXFONT;
+extern const double DEFWIDTH;
+extern const Int DEFCAP;
+extern const Int DEFJOIN;
+extern const double DEFMITER;
+extern const transform nullTransform;
+
+static const struct invisiblepen_t {} invisiblepen={};
+static const struct setlinewidth_t {} setlinewidth={};
+static const struct setfont_t {} setfont={};
+static const struct setfontsize_t {} setfontsize={};
+static const struct setpattern_t {} setpattern={};
+static const struct setlinecap_t {} setlinecap={};
+static const struct setlinejoin_t {} setlinejoin={};
+static const struct setmiterlimit_t {} setmiterlimit={};
+static const struct setoverwrite_t {} setoverwrite={};
+static const struct initialpen_t {} initialpen={};
+static const struct resolvepen_t {} resolvepen={};
+
+extern const char* PSCap[];
+extern const char* Cap[];
+extern const Int nCap;
+extern const char* Join[];
+extern const Int nJoin;
+
+enum overwrite_t {DEFWRITE=-1,ALLOW,SUPPRESS,SUPPRESSQUIET,MOVE,MOVEQUIET};
+extern const char* OverwriteTag[];
+extern const Int nOverwrite;
+
+enum FillRule {DEFFILL=-1,ZEROWINDING,EVENODD};
+extern const char* FillRuleTag[];
+extern const Int nFill;
+
+enum BaseLine {DEFBASE=-1,NOBASEALIGN,BASEALIGN};
+extern const char* BaseLineTag[];
+extern const Int nBaseLine;
+
+enum ColorSpace {DEFCOLOR=0,INVISIBLE,GRAYSCALE,RGB,CMYK,PATTERN};
+extern const size_t ColorComponents[];
+extern const char* ColorDeviceSuffix[];
+extern const unsigned nColorSpace;
+
+inline bool operator == (const vm::array& a, const vm::array& b)
+{
+ size_t asize=a.size();
+ size_t bsize=b.size();
+ if(asize != bsize) return false;
+ for(size_t i=0; i < asize; ++i)
+ if(vm::read<double>(a,i) != vm::read<double>(b,i)) return false;
+ return true;
+}
+
+inline bool operator == (const LineType& a, const LineType& b)
+{
+ return a.pattern == b.pattern && a.offset == b.offset && a.scale == b.scale
+ && a.adjust == b.adjust;
+}
+
+inline ostream& operator << (ostream& out, const vm::array& a)
+{
+ out << "[";
+ size_t n=a.size();
+ if(n > 0) {
+ out << vm::read<double>(a,0);
+ for(size_t i=1; i < n; ++i)
+ out << " " << vm::read<double>(a,i);
+ }
+ out << "]";
+ return out;
+}
+
+class Transparency
+{
+public:
+ string blend;
+ double opacity;
+ bool isdefault;
+
+ Transparency() :
+ blend("Compatible"), opacity(1.0), isdefault(true) {}
+
+ Transparency(const string& blend, double opacity) :
+ blend(blend), opacity(opacity), isdefault(false) {}
+};
+
+inline bool operator == (const Transparency& a, const Transparency& b) {
+ return a.blend == b.blend && a.opacity == b.opacity;
+}
+
+extern const char* BlendMode[];
+extern const Int nBlendMode;
+
+// Map [0,1] to [0,255]
+inline unsigned int byte(double r)
+{
+ if(r < 0.0) r=0.0;
+ else if(r > 1.0) r=1.0;
+ int a=(int)(256.0*r);
+ if(a == 256) a=255;
+ return a;
+}
+
+class pen;
+pen& defaultpen();
+
+class pen : public gc {
+ LineType line;
+
+ // Width of line, in PS units.
+ double linewidth;
+ path P; // A polygonal path defining a custom pen nib;
+ // nullpath means the default (typically circular) nib.
+ string font;
+ double fontsize;
+ double lineskip;
+
+ ColorSpace color;
+ double r,g,b; // RGB or CMY value
+ double grey; // grayscale or K value
+
+ string pattern; // The name of the user-defined fill/draw pattern
+ FillRule fillrule; // Zero winding-number (default) or even-odd rule
+ BaseLine baseline; // Align to TeX baseline?
+ Transparency transparency;
+ Int linecap;
+ Int linejoin;
+ double miterlimit;
+ overwrite_t overwrite;
+
+ // The transformation applied to the pen nib for calligraphic effects.
+ // nullTransform means the default (typically identity) transformation.
+ transform t;
+
+public:
+ static double pos0(double x) {return x >= 0 ? x : 0;}
+
+ void greyrange() {if(grey > 1.0) grey=1.0;}
+
+ void rgbrange() {
+ double sat=rgbsaturation();
+ if(sat > 1.0) {
+ double scale=1.0/sat;
+ r *= scale;
+ g *= scale;
+ b *= scale;
+ }
+ }
+
+ void cmykrange() {
+ double sat=cmyksaturation();
+ if(sat > 1.0) {
+ double scale=1.0/sat;
+ r *= scale;
+ g *= scale;
+ b *= scale;
+ grey *= scale;
+ }
+ }
+
+ void colorless() {
+ r=g=b=grey=0.0;
+ color=DEFCOLOR;
+ }
+
+ pen() :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(const LineType& line, double linewidth, const path& P,
+ const string& font, double fontsize, double lineskip,
+ ColorSpace color, double r, double g, double b, double grey,
+ const string& pattern, FillRule fillrule, BaseLine baseline,
+ const Transparency& transparency,
+ Int linecap, Int linejoin, double miterlimit,
+ overwrite_t overwrite, const transform& t) :
+ line(line), linewidth(linewidth), P(P),
+ font(font), fontsize(fontsize), lineskip(lineskip), color(color),
+ r(r), g(g), b(b), grey(grey),
+ pattern(pattern), fillrule(fillrule), baseline(baseline),
+ transparency(transparency),
+ linecap(linecap), linejoin(linejoin), miterlimit(miterlimit),
+ overwrite(overwrite), t(t) {}
+
+ pen(invisiblepen_t) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(INVISIBLE),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setlinewidth_t, double linewidth) :
+ line(), linewidth(linewidth), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(path P) :
+ line(), linewidth(DEFWIDTH), P(P),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(const LineType& line) :
+ line(line), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setfont_t, string font) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(font), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setfontsize_t, double fontsize, double lineskip) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(fontsize), lineskip(lineskip), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setpattern_t, const string& pattern) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(PATTERN),
+ r(0), g(0), b(0), grey(0),
+ pattern(pattern), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(FillRule fillrule) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(fillrule), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(BaseLine baseline) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(baseline),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(const Transparency& transparency) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(transparency),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setlinecap_t, Int linecap) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(linecap), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setlinejoin_t, Int linejoin) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(linejoin), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setmiterlimit_t, double miterlimit) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(miterlimit),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setoverwrite_t, overwrite_t overwrite) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(overwrite), t(nullTransform) {}
+
+ explicit pen(double grey) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(GRAYSCALE),
+ r(0.0), g(0.0), b(0.0), grey(pos0(grey)),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform)
+ {greyrange();}
+
+ pen(double r, double g, double b) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(RGB),
+ r(pos0(r)), g(pos0(g)), b(pos0(b)), grey(0.0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform)
+ {rgbrange();}
+
+ pen(double c, double m, double y, double k) :
+ line(), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(CMYK),
+ r(pos0(c)), g(pos0(m)), b(pos0(y)), grey(pos0(k)),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform)
+ {cmykrange();}
+
+ // Construct one pen from another, resolving defaults
+ pen(resolvepen_t, const pen& p) :
+ line(LineType(p.line.pattern,p.line.offset,p.line.scale,p.line.adjust)),
+ linewidth(p.width()), P(p.Path()),
+ font(p.Font()), fontsize(p.size()), lineskip(p.Lineskip()),
+ color(p.colorspace()),
+ r(p.red()), g(p.green()), b(p.blue()), grey(p.gray()),
+ pattern(""), fillrule(p.Fillrule()), baseline(p.Baseline()),
+ transparency(Transparency(p.blend(), p.opacity())),
+ linecap(p.cap()), linejoin(p.join()), miterlimit(p.miter()),
+ overwrite(p.Overwrite()), t(p.getTransform()) {}
+
+ static pen initialpen() {
+ return pen(LineType(vm::array(0),0.0,true,true),0.5,nullpath,"",
+ 12.0*settings::tex2ps,12.0*1.2*settings::tex2ps,GRAYSCALE,
+ 0.0,0.0,0.0,0.0,"",ZEROWINDING,NOBASEALIGN,
+ Transparency(),1,1,10.0,ALLOW,identity);
+ }
+
+ pen(initialpen_t) :
+ line(), linewidth(-2.0), P(nullpath),
+ font("<invalid>"), fontsize(-1.0), lineskip(-1.0), color(INVISIBLE),
+ r(0.0), g(0.0), b(0.0), grey(0.0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(NOBASEALIGN),
+ transparency(),linecap(-2), linejoin(-2), miterlimit(-1.0),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ double width() const {
+ return linewidth == DEFWIDTH ? defaultpen().linewidth : linewidth;
+ }
+
+ path Path() const {
+ return P.empty() ? defaultpen().P : P;
+ }
+
+ double size() const {
+ return fontsize == 0.0 ? defaultpen().fontsize : fontsize;
+ }
+
+ string Font() const {
+ if(font.empty()) {
+ if(defaultpen().font.empty()) {
+ string texengine=settings::getSetting<string>("tex");
+ if(settings::latex(texengine))
+ return DEFLATEXFONT;
+ else if(texengine == "none")
+ return settings::getSetting<string>("textinitialfont");
+ else {
+ ostringstream buf;
+ // Work around misalignment in ConTeXt switchtobodyfont if font is not found.
+ if(texengine == "context")
+ buf << "\\switchtobodyfont["
+ << DEFCONTEXTFONT << "," << size()*settings::ps2tex
+ << "pt]\\removeunwantedspaces%" << newl;
+ else
+ buf << "\\font\\ASYfont=" << DEFTEXFONT
+ << " at " << size()*settings::ps2tex << "pt\\ASYfont";
+ return buf.str();
+ }
+ }
+ else return defaultpen().font;
+ }
+ return font;
+ }
+
+ double Lineskip() const {
+ return lineskip == 0.0 ? defaultpen().lineskip : lineskip;
+ }
+
+ const LineType *linetype() const {
+ return line.isdefault ? &defaultpen().line : &line;
+ }
+
+ void adjust(double factor) {
+ if(line.isdefault)
+ line=defaultpen().line;
+ line.Scale(factor);
+ }
+
+ void setstroke(const vm::array& s) {line.pattern=s;}
+ void setoffset(const double& offset) {line.offset=offset;}
+
+ string fillpattern() const {
+ return pattern == DEFPAT ? (string)"" : pattern;
+ }
+
+ FillRule Fillrule() const {
+ return fillrule == DEFFILL ? defaultpen().fillrule : fillrule;
+ }
+
+ bool evenodd() const {
+ return Fillrule() == EVENODD;
+ }
+
+ bool inside(Int count) const {
+ return evenodd() ? count % 2 : count != 0;
+ }
+
+ BaseLine Baseline() const {
+ return baseline == DEFBASE ? defaultpen().baseline : baseline;
+ }
+
+ Transparency transp() const {
+ return transparency.isdefault ? defaultpen().transparency : transparency;
+ }
+
+ string blend() const {
+ return transparency.isdefault ? defaultpen().transparency.blend :
+ transparency.blend;
+ }
+
+ double opacity() const {
+ return transparency.isdefault ? defaultpen().transparency.opacity :
+ transparency.opacity;
+ }
+
+ Int cap() const {
+ return linecap == DEFCAP ? defaultpen().linecap : linecap;
+ }
+
+ Int join() const {
+ return linejoin == DEFJOIN ? defaultpen().linejoin : linejoin;
+ }
+
+ double miter() const {
+ return miterlimit == DEFMITER ? defaultpen().miterlimit : miterlimit;
+ }
+
+ overwrite_t Overwrite() const {
+ return overwrite == DEFWRITE ? defaultpen().overwrite : overwrite;
+ }
+
+ ColorSpace colorspace() const {
+ return color == DEFCOLOR ? defaultpen().color : color;
+ }
+
+ string hex() const {
+ int n=ColorComponents[colorspace()];
+ ostringstream buf;
+ buf.setf(std::ios::hex,std::ios::basefield);
+ buf.fill('0');
+
+ switch(n) {
+ case 0:
+ break;
+ case 1:
+ buf << std::setw(2) << byte(gray());
+ break;
+ case 3:
+ buf << std::setw(2) << byte(red())
+ << std::setw(2) << byte(green())
+ << std::setw(2) << byte(blue());
+ break;
+ case 4:
+ buf << std::setw(2) << byte(cyan())
+ << std::setw(2) << byte(magenta())
+ << std::setw(2) << byte(yellow())
+ << std::setw(2) << byte(black());
+ break;
+ default:
+ break;
+ }
+ return buf.str();
+ }
+
+ bool invisible() const {return colorspace() == INVISIBLE;}
+
+ bool grayscale() const {return colorspace() == GRAYSCALE;}
+
+ bool rgb() const {return colorspace() == RGB;}
+
+ bool cmyk() const {return colorspace() == CMYK;}
+
+ double gray() const {return color == DEFCOLOR ? defaultpen().grey : grey;}
+
+ double red() const {return color == DEFCOLOR ? defaultpen().r : r;}
+
+ double green() const {return color == DEFCOLOR ? defaultpen().g : g;}
+
+ double blue() const {return color == DEFCOLOR ? defaultpen().b : b;}
+
+ double cyan() const {return red();}
+
+ double magenta() const {return green();}
+
+ double yellow() const {return blue();}
+
+ double black() const {return gray();}
+
+ double rgbsaturation() const {return max(max(r,g),b);}
+
+ double cmyksaturation() const {return max(rgbsaturation(),black());}
+
+ void greytorgb() {
+ r=g=b=grey; grey=0.0;
+ color=RGB;
+ }
+
+ void rgbtogrey() {
+ grey=0.299*r+0.587*g+0.114*b; // Standard YUV luminosity coefficients
+ r=g=b=0.0;
+ color=GRAYSCALE;
+ }
+
+ void greytocmyk() {
+ grey=1.0-grey;
+ r=g=b=0.0;
+ color=CMYK;
+ }
+
+ void rgbtocmyk() {
+ double sat=rgbsaturation();
+ grey=1.0-sat;
+ if(sat) {
+ double scale=1.0/sat;
+ r=1.0-r*scale;
+ g=1.0-g*scale;
+ b=1.0-b*scale;
+ }
+ color=CMYK;
+ }
+
+ void cmyktorgb() {
+ double sat=1.0-grey;
+ r=(1.0-r)*sat;
+ g=(1.0-g)*sat;
+ b=(1.0-b)*sat;
+ grey=0.0;
+ color=RGB;
+ }
+
+ void cmyktogrey() {
+ cmyktorgb();
+ rgbtogrey();
+ }
+
+ void togrey() {
+ if(rgb()) rgbtogrey();
+ else if(cmyk()) cmyktogrey();
+ }
+
+ void torgb() {
+ if(cmyk()) cmyktorgb();
+ else if(grayscale()) greytorgb();
+ }
+
+ void tocmyk() {
+ if(rgb()) rgbtocmyk();
+ else if(grayscale()) greytocmyk();
+ }
+
+ void settransparency(const pen& p) {
+ transparency=p.transparency;
+ }
+
+ void setfont(const pen& p) {
+ font=p.font;
+ }
+
+ void setfillrule(const pen& p) {
+ fillrule=p.fillrule;
+ }
+
+ void convert() {
+ if(settings::gray || settings::bw) {
+ if(rgb()) rgbtogrey();
+ else if(cmyk()) cmyktogrey();
+ if(settings::bw) {grey=(grey == 1.0) ? 1.0 : 0.0;}
+ }
+ else if(settings::rgb && cmyk()) cmyktorgb();
+ else if(settings::cmyk && rgb()) rgbtocmyk();
+ }
+
+ // Try to upgrade to the specified colorspace.
+ bool promote(ColorSpace c) {
+ if(color == c) return true;
+
+ switch(color) {
+ case PATTERN:
+ case INVISIBLE:
+ break;
+ case DEFCOLOR:
+ {
+ return true;
+ break;
+ }
+ break;
+ case GRAYSCALE:
+ {
+ if(c == RGB) {greytorgb(); return true;}
+ else if(c == CMYK) {greytocmyk(); return true;}
+ break;
+ }
+ case RGB:
+ {
+ if(c == CMYK) {rgbtocmyk(); return true;}
+ break;
+ }
+ case CMYK:
+ {
+ break;
+ }
+ }
+ return false;
+ }
+
+ friend pen operator * (double x, const pen& q) {
+ pen p=q;
+ if(x < 0.0) x = 0.0;
+ switch(p.color) {
+ case PATTERN:
+ case INVISIBLE:
+ case DEFCOLOR:
+ break;
+ case GRAYSCALE:
+ {
+ p.grey *= x;
+ p.greyrange();
+ break;
+ }
+ case RGB:
+ {
+ p.r *= x;
+ p.g *= x;
+ p.b *= x;
+ p.rgbrange();
+ break;
+ }
+ case CMYK:
+ {
+ p.r *= x;
+ p.g *= x;
+ p.b *= x;
+ p.grey *= x;
+ p.cmykrange();
+ break;
+ }
+ }
+ return p;
+ }
+
+ friend pen operator + (const pen& p, const pen& q) {
+ pen P=p;
+ pen Q=q;
+
+ if(P.color == PATTERN && P.pattern.empty()) P.color=DEFCOLOR;
+ ColorSpace colorspace=(ColorSpace) max((Int) P.color,(Int) Q.color);
+
+ if(!(p.transparency.isdefault && q.transparency.isdefault))
+ P.transparency.opacity=max(p.opacity(),q.opacity());
+
+ switch(colorspace) {
+ case PATTERN:
+ case INVISIBLE:
+ case DEFCOLOR:
+ break;
+ case GRAYSCALE:
+ {
+ P.grey += Q.grey;
+ P.greyrange();
+ break;
+ }
+
+ case RGB:
+ {
+ if(P.color == GRAYSCALE) P.greytorgb();
+ else if(Q.color == GRAYSCALE) Q.greytorgb();
+
+ P.r += Q.r;
+ P.g += Q.g;
+ P.b += Q.b;
+ P.rgbrange();
+ break;
+ }
+
+ case CMYK:
+ {
+ if(P.color == GRAYSCALE) P.greytocmyk();
+ else if(Q.color == GRAYSCALE) Q.greytocmyk();
+
+ if(P.color == RGB) P.rgbtocmyk();
+ else if(Q.color == RGB) Q.rgbtocmyk();
+
+ P.r += Q.r;
+ P.g += Q.g;
+ P.b += Q.b;
+ P.grey += Q.grey;
+ P.cmykrange();
+ break;
+ }
+ }
+
+ return pen(q.line.isdefault ? p.line : q.line,
+ q.linewidth == DEFWIDTH ? p.linewidth : q.linewidth,
+ q.P.empty() ? p.P : q.P,
+ q.font.empty() ? p.font : q.font,
+ q.fontsize == 0.0 ? p.fontsize : q.fontsize,
+ q.lineskip == 0.0 ? p.lineskip : q.lineskip,
+ colorspace,P.r,P.g,P.b,P.grey,
+ q.pattern == DEFPAT ? p.pattern : q.pattern,
+ q.fillrule == DEFFILL ? p.fillrule : q.fillrule,
+ q.baseline == DEFBASE ? p.baseline : q.baseline,
+ q.transparency.isdefault ? p.transparency : q.transparency,
+ q.linecap == DEFCAP ? p.linecap : q.linecap,
+ q.linejoin == DEFJOIN ? p.linejoin : q.linejoin,
+ q.miterlimit == DEFMITER ? p.miterlimit : q.miterlimit,
+ q.overwrite == DEFWRITE ? p.overwrite : q.overwrite,
+ q.t.isNull() ? p.t : q.t);
+ }
+
+ friend pen interpolate(const pen& p, const pen& q, double t) {
+ pen P=p;
+ pen Q=q;
+
+ if(P.color == PATTERN && P.pattern.empty()) P.color=DEFCOLOR;
+ ColorSpace colorspace=(ColorSpace) max((Int) P.color,(Int) Q.color);
+
+ switch(colorspace) {
+ case PATTERN:
+ case INVISIBLE:
+ case DEFCOLOR:
+ case GRAYSCALE:
+ break;
+ case RGB:
+ {
+ if(P.color == GRAYSCALE) P.greytorgb();
+ else if(Q.color == GRAYSCALE) Q.greytorgb();
+ break;
+ }
+
+ case CMYK:
+ {
+ if(P.color == GRAYSCALE) P.greytocmyk();
+ else if(Q.color == GRAYSCALE) Q.greytocmyk();
+
+ if(P.color == RGB) P.rgbtocmyk();
+ else if(Q.color == RGB) Q.rgbtocmyk();
+ break;
+ }
+ }
+
+ return (1-t)*P+t*Q;
+ }
+
+ friend bool operator == (const pen& p, const pen& q) {
+ return *(p.linetype()) == *(q.linetype())
+ && p.width() == q.width()
+ && p.Path() == q.Path()
+ && p.Font() == q.Font()
+ && p.Lineskip() == q.Lineskip()
+ && p.size() == q.size()
+ && p.colorspace() == q.colorspace()
+ && (!(p.grayscale() || p.cmyk()) || p.gray() == q.gray())
+ && (!(p.rgb() || p.cmyk()) || (p.red() == q.red() &&
+ p.green() == q.green() &&
+ p.blue() == q.blue()))
+ && p.pattern == q.pattern
+ && p.Fillrule() == q.Fillrule()
+ && p.Baseline() == q.Baseline()
+ && p.transp() == q.transp()
+ && p.cap() == q.cap()
+ && p.join() == q.join()
+ && p.miter() == q.miter()
+ && p.Overwrite() == q.Overwrite()
+ && p.t == q.t;
+ }
+
+ friend bool operator != (const pen& p, const pen& q) {
+ return !(p == q);
+ }
+
+ friend ostream& operator << (ostream& out, const pen& p) {
+ out << "(";
+ if(p.line.isdefault)
+ out << "default";
+ else
+ out << p.line.pattern;
+ if(p.line.offset)
+ out << p.line.offset;
+ if(!p.line.scale)
+ out << " bp";
+ if(!p.line.adjust)
+ out << " fixed";
+ if(p.linewidth != DEFWIDTH)
+ out << ", linewidth=" << p.linewidth;
+ if(!p.P.empty())
+ out << ", path=" << p.P;
+ if(p.linecap != DEFCAP)
+ out << ", linecap=" << Cap[p.linecap];
+ if(p.linejoin != DEFJOIN)
+ out << ", linejoin=" << Join[p.linejoin];
+ if(p.miterlimit != DEFMITER)
+ out << ", miterlimit=" << p.miterlimit;
+ if(!p.font.empty())
+ out << ", font=\"" << p.font << "\"";
+ if(p.fontsize)
+ out << ", fontsize=" << p.fontsize;
+ if(p.lineskip)
+ out << ", lineskip=" << p.lineskip;
+ if(p.color == INVISIBLE)
+ out << ", invisible";
+ else if(p.color == GRAYSCALE)
+ out << ", gray=" << p.grey;
+ else if(p.color == RGB)
+ out << ", red=" << p.red() << ", green=" << p.green()
+ << ", blue=" << p.blue();
+ else if(p.color == CMYK)
+ out << ", cyan=" << p.cyan() << ", magenta=" << p.magenta()
+ << ", yellow=" << p.yellow() << ", black=" << p.black();
+ if(p.pattern != DEFPAT)
+ out << ", pattern=" << "\"" << p.pattern << "\"";
+ if(p.fillrule != DEFFILL)
+ out << ", fillrule=" << FillRuleTag[p.fillrule];
+ if(p.baseline != DEFBASE)
+ out << ", baseline=" << BaseLineTag[p.baseline];
+ if(!p.transparency.isdefault) {
+ out << ", opacity=" << p.transparency.opacity;
+ out << ", blend=" << p.transparency.blend;
+ }
+ if(p.overwrite != DEFWRITE)
+ out << ", overwrite=" << OverwriteTag[p.overwrite];
+ if(!p.t.isNull())
+ out << ", transform=" << p.t;
+ out << ")";
+
+ return out;
+ }
+
+ const transform getTransform() const {
+ return t.isNull() ? defaultpen().t : t;
+ }
+
+ // The bounds of the circle or ellipse the pen describes.
+ bbox bounds() const
+ {
+ double maxx, maxy;
+ pair shift;
+
+ if(!P.empty()) return P.bounds();
+
+ transform t=getTransform();
+
+ if(t.isIdentity()) {
+ maxx = 1;
+ maxy = 1;
+ shift = pair(0,0);
+ } else {
+ double xx = t.getxx(), xy = t.getxy(),
+ yx = t.getyx(), yy = t.getyy();
+
+ // These are the maximum x and y values that a linear transform can map
+ // a point in the unit circle. This can be proven by the Lagrange
+ // Multiplier theorem or by properties of the dot product.
+ maxx = length(pair(xx,xy));
+ maxy = length(pair(yx,yy));
+
+ shift = t*pair(0,0);
+ }
+
+ bbox b;
+ pair z=0.5*width()*pair(maxx,maxy);
+ b += z + shift;
+ b += -z + shift;
+
+ return b;
+ }
+
+ friend pen transformed(const transform& t, const pen& p) {
+ pen ret = p;
+ if(!p.P.empty()) ret.P = p.P.transformed(t);
+ ret.t = p.t.isNull() ? t : t*p.t;
+ return ret;
+ }
+
+};
+
+pen transformed(const transform& t, const pen &p);
+}
+
+#endif
diff --git a/graphics/asymptote/picture.cc b/graphics/asymptote/picture.cc
new file mode 100644
index 0000000000..c59c28e91b
--- /dev/null
+++ b/graphics/asymptote/picture.cc
@@ -0,0 +1,1425 @@
+/*****
+ * picture.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a picture as a list of drawElements and handles its output to
+ * PostScript.
+ *****/
+
+#include "errormsg.h"
+#include "picture.h"
+#include "util.h"
+#include "settings.h"
+#include "interact.h"
+#include "drawverbatim.h"
+#include "drawlabel.h"
+#include "drawlayer.h"
+#include "drawsurface.h"
+#include "drawpath3.h"
+
+using std::ifstream;
+using std::ofstream;
+using vm::array;
+
+using namespace settings;
+using namespace gl;
+
+texstream::~texstream() {
+ string texengine=getSetting<string>("tex");
+ bool context=settings::context(texengine);
+ string name;
+ if(!context)
+ name=stripFile(outname());
+ name += "texput.";
+ unlink((name+"aux").c_str());
+ unlink((name+"log").c_str());
+ unlink((name+"out").c_str());
+ if(settings::pdf(texengine)) {
+ unlink((name+"pdf").c_str());
+ unlink((name+"m9").c_str());
+ } else
+ unlink((name+"pbsdat").c_str());
+ if(context) {
+ unlink("cont-new.log");
+ unlink((name+"tex").c_str());
+ unlink((name+"top").c_str());
+ unlink((name+"tua").c_str());
+ unlink((name+"tui").c_str());
+ }
+}
+
+namespace camp {
+
+extern void draw();
+
+bool isIdTransform3(const double* t)
+{
+ return (t == NULL || (t[0]==1 && t[1]==0 && t[2]==0 && t[3]==0 &&
+ t[4]==0 && t[5]==1 && t[6]==0 && t[7]==0 &&
+ t[8]==0 && t[9]==0 && t[10]==1 && t[11]==0 &&
+ t[12]==0 && t[13]==0 && t[14]==0 && t[15]==1));
+}
+
+// copy array to 4x4 transform matrix with range checks
+void copyArray4x4C(double*& dest, const vm::array *a)
+{
+ double tt[16];
+ const size_t n=checkArray(a);
+ const string fourbyfour="4x4 array of doubles expected";
+ if(n != 4) reportError(fourbyfour);
+
+ for(size_t i=0; i < 4; i++) {
+ const vm::array *ai=vm::read<vm::array*>(a,i);
+ const size_t aisize=checkArray(ai);
+ double *tti=tt+4*i;
+ if(aisize == 4) {
+ for(size_t j=0; j < 4; j++)
+ tti[j]=vm::read<double>(ai,j);
+ } else reportError(fourbyfour);
+ }
+
+ copyTransform3(dest,tt);
+}
+
+void copyTransform3(double*& d, const double* s, GCPlacement placement)
+
+{
+ if(s != NULL) {
+ if(d == NULL)
+ d=placement == NoGC ? new double[16] : new(placement) double[16];
+ memcpy(d,s,sizeof(double)*16);
+ }
+}
+
+// t = s*r
+void multiplyTransform3(double*& t, const double* s, const double* r)
+{
+ if(isIdTransform3(s)) {
+ copyTransform3(t,r);
+ } else if(isIdTransform3(r)) {
+ copyTransform3(t,s);
+ } else {
+ t=new(UseGC) double[16];
+ for(size_t i=0; i < 4; i++) {
+ size_t i4=4*i;
+ const double *si=s+i4;
+ const double& s0=si[0];
+ const double& s1=si[1];
+ const double& s2=si[2];
+ const double& s3=si[3];
+ double *ti=t+i4;
+ ti[0]=s0*r[0]+s1*r[4]+s2*r[8]+s3*r[12];
+ ti[1]=s0*r[1]+s1*r[5]+s2*r[9]+s3*r[13];
+ ti[2]=s0*r[2]+s1*r[6]+s2*r[10]+s3*r[14];
+ ti[3]=s0*r[3]+s1*r[7]+s2*r[11]+s3*r[15];
+ }
+ }
+}
+
+double xratio(const triple& v) {return v.getx()/v.getz();}
+double yratio(const triple& v) {return v.gety()/v.getz();}
+
+class matrixstack {
+ mem::stack<const double*> mstack;
+
+public:
+ // return current transform
+ const double* T() const
+ {
+ if(mstack.empty())
+ return NULL;
+ else
+ return mstack.top();
+ }
+ // we store the accumulated transform of all pushed transforms
+ void push(const double *r)
+ {
+ double* T3 = NULL;
+ multiplyTransform3(T3,T(),r);
+ mstack.push(T3);
+ }
+ void pop()
+ {
+ if(!mstack.empty())
+ mstack.pop();
+ }
+
+};
+
+const char *texpathmessage() {
+ ostringstream buf;
+ buf << "the directory containing your " << getSetting<string>("tex")
+ << " engine (" << texcommand() << ")";
+ return Strdup(buf.str());
+}
+
+picture::~picture()
+{
+}
+
+void picture::enclose(drawElement *begin, drawElement *end)
+{
+ assert(begin);
+ assert(end);
+ nodes.push_front(begin);
+ lastnumber=0;
+ lastnumber3=0;
+
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->islayer()) {
+ nodes.insert(p,end);
+ ++p;
+ while(p != nodes.end() && (*p)->islayer()) ++p;
+ if(p == nodes.end()) return;
+ nodes.insert(p,begin);
+ }
+ }
+ nodes.push_back(end);
+}
+
+// Insert at beginning of picture.
+void picture::prepend(drawElement *p)
+{
+ assert(p);
+ nodes.push_front(p);
+ lastnumber=0;
+ lastnumber3=0;
+}
+
+void picture::append(drawElement *p)
+{
+ assert(p);
+ nodes.push_back(p);
+}
+
+void picture::add(picture &pic)
+{
+ if (&pic == this) return;
+
+ // STL's funny way of copying one list into another.
+ copy(pic.nodes.begin(), pic.nodes.end(), back_inserter(nodes));
+}
+
+// Insert picture pic at beginning of picture.
+void picture::prepend(picture &pic)
+{
+ if (&pic == this) return;
+
+ copy(pic.nodes.begin(), pic.nodes.end(), inserter(nodes, nodes.begin()));
+ lastnumber=0;
+ lastnumber3=0;
+}
+
+bool picture::havelabels()
+{
+ size_t n=nodes.size();
+ if(n > lastnumber && !labels && getSetting<string>("tex") != "none") {
+ // Check to see if there are any labels yet
+ nodelist::iterator p=nodes.begin();
+ for(size_t i=0; i < lastnumber; ++i) ++p;
+ for(; p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->islabel()) {
+ labels=true;
+ break;
+ }
+ }
+ }
+ return labels;
+}
+
+bool picture::have3D()
+{
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->is3D())
+ return true;
+ }
+ return false;
+}
+
+bool picture::havepng()
+{
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->svgpng())
+ return true;
+ }
+ return false;
+}
+
+bool picture::havenewpage()
+{
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->isnewpage())
+ return true;
+ }
+ return false;
+}
+
+bbox picture::bounds()
+{
+ size_t n=nodes.size();
+ if(n == lastnumber) return b_cached;
+
+ if(lastnumber == 0) { // Maybe these should be put into a structure.
+ b_cached=bbox();
+ labelbounds.clear();
+ bboxstack.clear();
+ }
+
+ if(havelabels()) texinit();
+
+ nodelist::iterator p=nodes.begin();
+ for(size_t i=0; i < lastnumber; ++i) ++p;
+ for(; p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->bounds(b_cached,processData().tex,labelbounds,bboxstack);
+
+ // Optimization for interpreters with fixed stack limits.
+ if((*p)->endclip()) {
+ nodelist::iterator q=p;
+ if(q != nodes.begin()) {
+ --q;
+ assert(*q);
+ if((*q)->endclip())
+ (*q)->save(false);
+ }
+ }
+ }
+
+ lastnumber=n;
+ return b_cached;
+}
+
+bbox3 picture::bounds3()
+{
+ size_t n=nodes.size();
+ if(n == lastnumber3) return b3;
+
+ if(lastnumber3 == 0)
+ b3=bbox3();
+
+ matrixstack ms;
+ size_t i=0;
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->begingroup3())
+ ms.push((*p)->transf3());
+ else if((*p)->endgroup3())
+ ms.pop();
+ else
+ (*p)->bounds(ms.T(),b3);
+ i++;
+ }
+
+ lastnumber3=n;
+ return b3;
+}
+
+pair picture::ratio(double (*m)(double, double))
+{
+ bool first=true;
+ pair b;
+ bounds3();
+ double fuzz=Fuzz*(b3.Max()-b3.Min()).length();
+ matrixstack ms;
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->begingroup3())
+ ms.push((*p)->transf3());
+ else if((*p)->endgroup3())
+ ms.pop();
+ else
+ (*p)->ratio(ms.T(),b,m,fuzz,first);
+ }
+ return b;
+}
+
+void texinit()
+{
+ drawElement::lastpen=pen(initialpen);
+ processDataStruct &pd=processData();
+ // Output any new texpreamble commands
+ if(pd.tex.isopen()) {
+ if(pd.TeXpipepreamble.empty()) return;
+ texpreamble(pd.tex,pd.TeXpipepreamble,false);
+ pd.TeXpipepreamble.clear();
+ return;
+ }
+
+ bool context=settings::context(getSetting<string>("tex"));
+ string dir=stripFile(outname());
+ string logname;
+ if(!context) logname=dir;
+ logname += "texput.log";
+ const char *cname=logname.c_str();
+ ofstream writeable(cname);
+ if(!writeable)
+ reportError("Cannot write to "+logname);
+ else
+ writeable.close();
+ unlink(cname);
+
+ mem::vector<string> cmd;
+ cmd.push_back(texprogram());
+ if(context) {
+ cmd.push_back("--pipe");
+ } else {
+ if(!dir.empty())
+ cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1));
+ if(getSetting<bool>("inlineimage") || getSetting<bool>("inlinetex")) {
+ string name=stripDir(stripExt((outname())));
+ size_t pos=name.rfind("-");
+ if(pos < string::npos) {
+ name=stripExt(name).substr(0,pos);
+ unlink((name+".aux").c_str());
+ cmd.push_back("-jobname="+name.substr(0,pos));
+#ifdef __MSDOS__
+ cmd.push_back("NUL"); // For MikTeX
+#endif
+ }
+ }
+ cmd.push_back("\\scrollmode");
+ }
+
+ pd.tex.open(cmd,"texpath",texpathmessage());
+ pd.tex.wait("\n*");
+ pd.tex << "\n";
+ texdocumentclass(pd.tex,true);
+
+ texdefines(pd.tex,pd.TeXpreamble,true);
+ pd.TeXpipepreamble.clear();
+}
+
+int opentex(const string& texname, const string& prefix, bool dvi)
+{
+ string aux=auxname(prefix,"aux");
+ unlink(aux.c_str());
+ bool context=settings::context(getSetting<string>("tex"));
+ mem::vector<string> cmd;
+ cmd.push_back(texprogram());
+ if(dvi)
+ cmd.push_back("-output-format=dvi");
+ if(context) {
+ cmd.push_back("--nonstopmode");
+ cmd.push_back(texname);
+ } else {
+ string dir=stripFile(texname);
+ if(!dir.empty())
+ cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1));
+ cmd.push_back("\\nonstopmode\\input");
+ cmd.push_back(stripDir(texname));
+ }
+
+ bool quiet=verbose <= 1;
+ int status=System(cmd,quiet ? 1 : 0,true,"texpath",texpathmessage());
+ if(!status && getSetting<bool>("twice"))
+ status=System(cmd,quiet ? 1 : 0,true,"texpath",texpathmessage());
+ if(status) {
+ if(quiet) {
+ cmd[1]=context ? "--scrollmode" : "\\scrollmode\\input";
+ System(cmd,0);
+ }
+ }
+ return status;
+}
+
+
+bool picture::texprocess(const string& texname, const string& outname,
+ const string& prefix, const pair& bboxshift,
+ bool svg)
+{
+ int status=1;
+ ifstream outfile;
+
+ outfile.open(texname.c_str());
+ bool keep=getSetting<bool>("keep");
+
+ if(outfile) {
+ outfile.close();
+
+ status=opentex(texname,prefix);
+ string texengine=getSetting<string>("tex");
+
+ if(status == 0) {
+ string dviname=auxname(prefix,"dvi");
+ mem::vector<string> cmd;
+
+ if(svg) {
+ cmd.push_back(getSetting<string>("dvisvgm"));
+ cmd.push_back("-n");
+ cmd.push_back("-v0");
+ string libgs=getSetting<string>("libgs");
+ if(!libgs.empty())
+ cmd.push_back("--libgs="+libgs);
+ push_split(cmd,getSetting<string>("dvisvgmOptions"));
+ cmd.push_back("-o"+outname);
+ ostringstream buf;
+ bbox B=svgbbox(b,bboxshift);
+ /*
+ double height=b.top-b.bottom;
+ double threshold=12.0*tex2ps;
+ if(height < threshold) {
+ double offset=threshold-height;
+ b.top += offset;
+ b.bottom += offset;
+ }
+ bbox B=b;
+ B.shift(bboxshift+pair(1.99*cm,1.9*cm));
+ */
+ buf << "--bbox="
+ << B.left << "bp "
+ << B.bottom << "bp "
+ << B.right << "bp "
+ << B.top << "bp";
+ cmd.push_back(buf.str());
+ cmd.push_back(dviname);
+ status=System(cmd,0,true,"dvisvgm");
+ if(!keep)
+ unlink(dviname.c_str());
+ } else {
+ if(!settings::pdf(texengine)) {
+ string psname=auxname(prefix,"ps");
+ double height=b.top-b.bottom+1.0;
+
+ // Magic dvips offsets:
+ double hoffset=-128.4;
+ double vertical=height;
+ if(!latex(texengine)) vertical += 2.0;
+ double voffset=(vertical < 13.0) ? -137.8+vertical : -124.8;
+ double paperHeight=getSetting<double>("paperheight");
+
+ hoffset += b.left+bboxshift.getx();
+ voffset += paperHeight-height-b.bottom-bboxshift.gety();
+
+ string dvipsrc=getSetting<string>("dir");
+ if(dvipsrc.empty()) dvipsrc=systemDir;
+ dvipsrc += dirsep+"nopapersize.ps";
+ setenv("DVIPSRC",dvipsrc.c_str(),1);
+ string papertype=getSetting<string>("papertype") == "letter" ?
+ "letterSize" : "a4size";
+ cmd.push_back(getSetting<string>("dvips"));
+ cmd.push_back("-R");
+ cmd.push_back("-Pdownload35");
+ cmd.push_back("-D600");
+ cmd.push_back("-O"+String(hoffset)+"bp,"+String(voffset)+"bp");
+ bool ps=havenewpage();
+ if(ps)
+ cmd.push_back("-T"+String(getSetting<double>("paperwidth"))+"bp,"+
+ String(paperHeight)+"bp");
+ else
+ cmd.push_back("-E");
+ push_split(cmd,getSetting<string>("dvipsOptions"));
+ if(ps && getSetting<string>("papertype") != "")
+ cmd.push_back("-t"+papertype);
+ if(verbose <= 1) cmd.push_back("-q");
+ cmd.push_back("-o"+psname);
+ cmd.push_back(dviname);
+ status=System(cmd,0,true,"dvips");
+ if(status == 0) {
+ ifstream fin(psname.c_str());
+ psfile fout(outname,false);
+
+ string s;
+ bool first=true;
+ transform t=shift(bboxshift)*T;
+ bool shift=!t.isIdentity();
+
+ const string beginspecial="TeXDict begin @defspecial";
+ const size_t beginlength=beginspecial.size();
+ const string endspecial="@fedspecial end";
+ const size_t endlength=endspecial.size();
+
+ while(getline(fin,s)) {
+ if (s[0] == '%') {
+ if (s.find("%%DocumentPaperSizes:") == 0)
+ continue;
+
+ if(s.find("%!PS-Adobe-") == 0) {
+ fout.header(!ps);
+ continue;
+ }
+
+ if (first && s.find("%%BoundingBox:") == 0) {
+ bbox box=b;
+ box.shift(bboxshift);
+ if(verbose > 2) BoundingBox(cout,box);
+ fout.BoundingBox(box);
+ first=false;
+ continue;
+ }
+ }
+
+ if (shift) {
+ if (s.compare(0, beginlength, beginspecial) == 0) {
+ fout.verbatimline(s);
+ fout.gsave();
+ fout.concat(t);
+ continue;
+ }
+ if (s.compare(0, endlength, endspecial) == 0) {
+ fout.grestore();
+ fout.verbatimline(s);
+ continue;
+ }
+ }
+
+ // For the default line, output it unchanged.
+ fout.verbatimline(s);
+ }
+ }
+ if(!keep) {
+ unlink(dviname.c_str());
+ unlink(psname.c_str());
+ }
+ }
+ }
+ }
+
+ if(!keep) {
+ unlink(texname.c_str());
+ if(!getSetting<bool>("keepaux"))
+ unlink(auxname(prefix,"aux").c_str());
+ unlink(auxname(prefix,"log").c_str());
+ unlink(auxname(prefix,"out").c_str());
+ if(settings::context(texengine)) {
+ unlink(auxname(prefix,"top").c_str());
+ unlink(auxname(prefix,"tua").c_str());
+ unlink(auxname(prefix,"tuc").c_str());
+ unlink(auxname(prefix,"tui").c_str());
+ unlink(auxname(prefix,"tuo").c_str());
+ }
+ }
+ if(status == 0) return true;
+ }
+ return false;
+}
+
+int picture::epstopdf(const string& epsname, const string& pdfname)
+{
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dNOPAUSE");
+ cmd.push_back("-dBATCH");
+ cmd.push_back("-P");
+ if(safe) {
+ cmd.push_back("-dSAFER");
+ cmd.push_back("-dDELAYSAFER"); // Support transparency extensions.
+ }
+ cmd.push_back("-sDEVICE=pdfwrite");
+ cmd.push_back("-dEPSCrop");
+ cmd.push_back("-dSubsetFonts=true");
+ cmd.push_back("-dEmbedAllFonts=true");
+ cmd.push_back("-dMaxSubsetPct=100");
+ cmd.push_back("-dPDFSETTINGS=/prepress");
+ cmd.push_back("-dCompatibilityLevel=1.4");
+ if(!getSetting<bool>("autorotate"))
+ cmd.push_back("-dAutoRotatePages=/None");
+ cmd.push_back("-g"+String(max(ceil(getSetting<double>("paperwidth")),1.0))
+ +"x"+String(max(ceil(getSetting<double>("paperheight")),1.0)));
+ cmd.push_back("-dDEVICEWIDTHPOINTS="+String(max(b.right-b.left,3.0)));
+ cmd.push_back("-dDEVICEHEIGHTPOINTS="+String(max(b.top-b.bottom,3.0)));
+ push_split(cmd,getSetting<string>("gsOptions"));
+ cmd.push_back("-sOutputFile="+stripDir(pdfname));
+ if(safe) {
+ cmd.push_back("-c");
+ cmd.push_back(".setsafe");
+ cmd.push_back("-f");
+ }
+ cmd.push_back(stripDir(epsname));
+
+ char *oldPath=NULL;
+ string dir=stripFile(pdfname);
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
+ int status=System(cmd,0,true,"gs","Ghostscript");
+ if(oldPath != NULL)
+ setPath(oldPath);
+ return status;
+}
+
+int picture::pdftoeps(const string& pdfname, const string& epsname)
+{
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dNOCACHE");
+ cmd.push_back("-dNOPAUSE");
+ cmd.push_back("-dBATCH");
+ cmd.push_back("-P");
+ if(safe)
+ cmd.push_back("-dSAFER");
+ string texengine=getSetting<string>("tex");
+ cmd.push_back("-sDEVICE="+getSetting<string>("epsdriver"));
+
+ cmd.push_back("-sOutputFile="+stripDir(epsname));
+ cmd.push_back(stripDir(pdfname));
+
+ char *oldPath=NULL;
+ string dir=stripFile(epsname);
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
+ int status=System(cmd,0,true,"gs","Ghostscript");
+ if(oldPath != NULL)
+ setPath(oldPath);
+ return status;
+}
+
+bool picture::reloadPDF(const string& Viewer, const string& outname) const
+{
+ static bool needReload=true;
+ static bool haveReload=false;
+
+ // Send javascript code to redraw picture.
+ picture f;
+ string name=getPath()+string("/")+outname;
+ f.append(new drawVerbatim(TeX,"\\ \\pdfannot width 0pt height 0pt { /AA << /PO << /S /JavaScript /JS (try{reload('"+
+ name+"');} catch(e) {} closeDoc(this);) >> >> }"));
+ string reloadprefix="reload";
+ if(needReload) {
+ needReload=false;
+ string texengine=getSetting<string>("tex");
+ Setting("tex")=string("pdflatex");
+ haveReload=f.shipout(NULL,reloadprefix,"pdf",false,false);
+ Setting("tex")=texengine;
+ }
+ if(haveReload) {
+ mem::vector<string> cmd;
+ push_command(cmd,Viewer);
+ string pdfreloadOptions=getSetting<string>("pdfreloadOptions");
+ if(!pdfreloadOptions.empty())
+ cmd.push_back(pdfreloadOptions);
+ cmd.push_back(reloadprefix+".pdf");
+ System(cmd,0,false);
+ }
+ return true;
+}
+
+int picture::epstosvg(const string& epsname, const string& outname)
+{
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("dvisvgm"));
+ cmd.push_back("-n");
+ cmd.push_back("-E");
+ cmd.push_back("--verbosity=3");
+ string libgs=getSetting<string>("libgs");
+ if(!libgs.empty())
+ cmd.push_back("--libgs="+libgs);
+ push_split(cmd,getSetting<string>("dvisvgmOptions"));
+ cmd.push_back("-o"+outname);
+ cmd.push_back(epsname);
+ int status=System(cmd,2,true,"dvisvgm");
+ if(!getSetting<bool>("keep"))
+ unlink(epsname.c_str());
+ return status;
+}
+
+int picture::pdftosvg(const string& pdfname, const string& outname)
+{
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("dvisvgm"));
+ cmd.push_back("-n");
+ cmd.push_back("--pdf");
+ cmd.push_back("--verbosity=3");
+ string libgs=getSetting<string>("libgs");
+ if(!libgs.empty())
+ cmd.push_back("--libgs="+libgs);
+ push_split(cmd,getSetting<string>("dvisvgmOptions"));
+ cmd.push_back("-o"+outname);
+ cmd.push_back(pdfname);
+ int status=System(cmd,2,true,"dvisvgm");
+ if(status == 0 && !getSetting<bool>("keep"))
+ unlink(pdfname.c_str());
+ return status;
+}
+
+bool picture::postprocess(const string& prename, const string& outname,
+ const string& outputformat,
+ bool wait, bool view, bool pdftex,
+ bool epsformat, bool svg)
+{
+ static mem::map<CONST string,int> pids;
+ int status=0;
+ bool pdfformat=(settings::pdf(getSetting<string>("tex"))
+ && outputformat == "") || outputformat == "pdf";
+
+ mem::vector<string> cmd;
+ if(pdftex || !epsformat) {
+ if(pdfformat) {
+ if(pdftex) {
+ status=rename(prename.c_str(),outname.c_str());
+ if(status != 0)
+ reportError("Cannot rename "+prename+" to "+outname);
+ } else status=epstopdf(prename,outname);
+ } else if(epsformat) {
+ if(svg) {
+ status=pdftosvg(prename,outname);
+ if(status != 0) { // Dvisvgm version < 2.4 doesn't support --pdf
+ string epsname=stripExt(prename)+".eps";
+ status=pdftoeps(prename,epsname);
+ if(status != 0) return false;
+ status=epstosvg(epsname,outname);
+ }
+ epsformat=false;
+ } else
+ status=pdftoeps(prename,outname);
+ } else {
+ double render=fabs(getSetting<double>("render"));
+ if(render == 0) render=1.0;
+ double res=render*72.0;
+ Int antialias=getSetting<Int>("antialias");
+ if(outputformat == "png" && antialias == 2) {
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dNOPAUSE");
+ cmd.push_back("-dBATCH");
+ cmd.push_back("-P");
+ cmd.push_back("-sDEVICE=pngalpha");
+ cmd.push_back("-dEPSCrop");
+ if(safe)
+ cmd.push_back("-dSAFER");
+ cmd.push_back("-r"+String(res)+"x"+String(res));
+ push_split(cmd,getSetting<string>("gsOptions"));
+ cmd.push_back("-sOutputFile="+outname);
+ cmd.push_back(prename);
+ status=System(cmd,0,true,"gs","Ghostscript");
+ } else if(!svg && !getSetting<bool>("xasy")) {
+ double expand=antialias;
+ if(expand < 2.0) expand=1.0;
+ res *= expand;
+ cmd.push_back(getSetting<string>("convert"));
+ cmd.push_back("-density");
+ cmd.push_back(String(res)+"x"+String(res));
+ if(expand == 1.0)
+ cmd.push_back("+antialias");
+ push_split(cmd,getSetting<string>("convertOptions"));
+ cmd.push_back("-resize");
+ cmd.push_back(String(100.0/expand)+"%x");
+ if(outputformat == "jpg") cmd.push_back("-flatten");
+ cmd.push_back(prename);
+ cmd.push_back(outputformat+":"+outname);
+ status=System(cmd,0,true,"convert");
+ }
+ }
+ if(!getSetting<bool>("keep"))
+ unlink(prename.c_str());
+ }
+ if(status != 0) return false;
+
+ if(verbose > 0)
+ cout << "Wrote " << outname << endl;
+ bool View=settings::view() && view;
+ if(View) {
+ if(epsformat || pdfformat) {
+ // Check to see if there is an existing viewer for this outname.
+ mem::map<CONST string,int>::iterator p=pids.find(outname);
+ bool running=(p != pids.end());
+ string Viewer=pdfformat ? getSetting<string>("pdfviewer") :
+ getSetting<string>("psviewer");
+ int pid;
+ if(running) {
+ pid=p->second;
+ if(pid)
+ running=(waitpid(pid, &status, WNOHANG) != pid);
+ }
+
+ bool pdfreload=pdfformat && getSetting<bool>("pdfreload");
+ if(running) {
+ // Tell gv/acroread to reread file.
+ if(Viewer == "gv") kill(pid,SIGHUP);
+ else if(pdfreload) reloadPDF(Viewer,outname);
+ } else {
+ mem::vector<string> cmd;
+ push_command(cmd,Viewer);
+ string viewerOptions=getSetting<string>(pdfformat ?
+ "pdfviewerOptions" :
+ "psviewerOptions");
+ if(!viewerOptions.empty())
+ push_split(cmd,viewerOptions);
+ cmd.push_back(outname);
+ status=System(cmd,0,wait,
+ pdfformat ? "pdfviewer" : "psviewer",
+ pdfformat ? "your PDF viewer" : "your PostScript viewer",
+ &pid);
+ if(status != 0) return false;
+
+ if(!wait) pids[outname]=pid;
+
+ if(pdfreload) {
+ // Work around race conditions in acroread initialization script
+ usleep(getSetting<Int>("pdfreloaddelay"));
+ // Only reload if pdf viewer process is already running.
+ if(waitpid(pid, &status, WNOHANG) == pid)
+ reloadPDF(Viewer,outname);
+ }
+ }
+ } else {
+ mem::vector<string> cmd;
+ push_command(cmd,getSetting<string>("display"));
+ cmd.push_back(outname);
+ string application="your "+outputformat+" viewer";
+ status=System(cmd,0,wait,"display",application.c_str());
+ if(status != 0) return false;
+ }
+ }
+
+ return true;
+}
+
+string Outname(const string& prefix, const string& outputformat,
+ bool standardout)
+{
+ return standardout ? "-" : buildname(prefix,outputformat,"");
+}
+
+bool picture::shipout(picture *preamble, const string& Prefix,
+ const string& format, bool wait, bool view)
+{
+ b=bounds();
+
+ string texengine=getSetting<string>("tex");
+ bool usetex=texengine != "none";
+ bool TeXmode=getSetting<bool>("inlinetex") && usetex;
+ bool pdf=settings::pdf(texengine);
+
+ bool standardout=Prefix == "-";
+ string prefix=standardout ? standardprefix : stripExt(Prefix);
+
+ string preformat=nativeformat();
+ string outputformat=format.empty() ? defaultformat() : format;
+ bool epsformat=outputformat == "eps";
+ bool pdfformat=pdf || outputformat == "pdf";
+ bool svgformat=outputformat == "svg";
+ bool dvi=false;
+ bool svg=svgformat && usetex && !(pdf && havepng()) &&
+ (!have3D() || getSetting<double>("render") == 0.0);
+ if(svg) {
+ if(pdf) epsformat=true;
+ else dvi=true;
+ }
+
+ string outname=Outname(prefix,outputformat,standardout);
+ string epsname=epsformat ? (standardout ? "" : outname) :
+ auxname(prefix,"eps");
+
+ bool Labels=labels || TeXmode;
+
+ bool empty=b.empty;
+ if(outputformat == "png" && (b.right-b.left < 1.0 || b.top-b.bottom < 1.0))
+ empty=true;
+
+ if(empty && !Labels) { // Output a null file
+ bbox b;
+ b.left=b.bottom=0;
+ b.right=b.top=1;
+ psfile out(epsname,false);
+ out.prologue(b);
+ out.epilogue();
+ out.close();
+ return postprocess(epsname,outname,outputformat,wait,view,false,
+ epsformat,false);
+ }
+
+ Labels |= svg;
+
+ if(Labels)
+ prefix=cleanpath(prefix);
+
+ string prename=((epsformat && !pdf) || !Labels) ? epsname :
+ auxname(prefix,preformat);
+
+ SetPageDimensions();
+
+ pair aligndir=getSetting<pair>("aligndir");
+ string origin=getSetting<string>("align");
+
+ pair bboxshift=(origin == "Z" && epsformat) ?
+ pair(0.0,0.0) : pair(-b.left,-b.bottom);
+
+ if(epsformat) {
+ bboxshift += getSetting<pair>("offset");
+ double yexcess=max(getSetting<double>("paperheight")-
+ (b.top-b.bottom+1.0),0.0);
+ double xexcess=max(getSetting<double>("paperwidth")-
+ (b.right-b.left+1.0),0.0);
+ if(aligndir == pair(0,0)) {
+ if(origin != "Z" && origin != "B") {
+ if(origin == "T") bboxshift += pair(0.0,yexcess);
+ else bboxshift += pair(0.5*xexcess,0.5*yexcess);
+ }
+ } else {
+ double scale=max(fabs(aligndir.getx()),fabs(aligndir.gety()));
+ if(scale != 0) aligndir *= 0.5/scale;
+ bboxshift +=
+ pair((aligndir.getx()+0.5)*xexcess,(aligndir.gety()+0.5)*yexcess);
+ }
+ }
+
+ bool status=true;
+
+ string texname;
+ texfile *tex=NULL;
+
+ if(Labels) {
+ texname=TeXmode ? buildname(prefix,"tex") : auxname(prefix,"tex");
+ tex=dvi ? new svgtexfile(texname,b) : new texfile(texname,b);
+ tex->prologue();
+ }
+
+ nodelist::iterator layerp=nodes.begin();
+ nodelist::iterator p=layerp;
+ unsigned layer=0;
+ mem::list<string> files;
+
+ bbox bshift=b;
+
+// transparency=false;
+ int svgcount=0;
+
+ typedef mem::list<drawElement *> clipstack;
+ clipstack begin;
+
+ while(p != nodes.end()) {
+ string psname,pdfname;
+ if(Labels) {
+ ostringstream buf;
+ buf << prefix << "_" << layer;
+ psname=buildname(buf.str(),"eps");
+ if(pdf) pdfname=buildname(buf.str(),"pdf");
+ } else {
+ psname=epsname;
+ bshift.shift(bboxshift);
+ }
+ files.push_back(psname);
+ if(pdf) files.push_back(pdfname);
+ psfile out(psname,pdfformat);
+ out.prologue(bshift);
+
+ if(!Labels) {
+ out.gsave();
+ out.translate(bboxshift);
+ }
+
+ if(preamble) {
+ // Postscript preamble.
+ nodelist Nodes=preamble->nodes;
+ nodelist::iterator P=Nodes.begin();
+ if(P != Nodes.end()) {
+ out.resetpen();
+ for(; P != Nodes.end(); ++P) {
+ assert(*P);
+ (*P)->draw(&out);
+ }
+ }
+ }
+ out.resetpen();
+
+ bool postscript=false;
+ drawLabel *L=NULL;
+
+ if(dvi)
+ for(nodelist::const_iterator r=begin.begin(); r != begin.end(); ++r)
+ (*r)->draw(&out);
+
+ for(; p != nodes.end(); ++p) {
+ assert(*p);
+ if(Labels && (*p)->islayer()) break;
+
+ if(dvi && (*p)->svg()) {
+ picture *f=(*p)->svgpng() ? new picture : NULL;
+ nodelist::const_iterator q=layerp;
+ for(;;) {
+ if((*q)->beginclip())
+ begin.push_back(*q);
+ else if((*q)->endclip()) {
+ if(begin.size() < 1)
+ reportError("endclip without matching beginclip");
+ begin.pop_back();
+ }
+ if(q == p) break;
+ ++q;
+ }
+
+ if(f) {
+ for(nodelist::const_iterator r=begin.begin(); r != begin.end(); ++r)
+ f->append(*r);
+
+ f->append(*(q++));
+ }
+
+ while(q != nodes.end() && !(*q)->islayer()) ++q;
+
+ clipstack end;
+
+ for(nodelist::const_iterator r=--q;; --r) {
+ if((*r)->beginclip() && end.size() >= 1)
+ end.pop_back();
+ else if((*r)->endclip())
+ end.push_back(*r);
+ if(r == p) break;
+ }
+
+ for(nodelist::reverse_iterator r=end.rbegin(); r != end.rend();
+ ++r) {
+ (*r)->draw(&out);
+ if(f)
+ f->append(*r);
+ }
+
+ if(f) {
+ ostringstream buf;
+ buf << prefix << "_" << svgcount;
+ ++svgcount;
+ string pngname=buildname(buf.str(),"png");
+ f->shipout(preamble,buf.str(),"png",false,false);
+ pair m=f->bounds().Min();
+ pair M=f->bounds().Max();
+ delete f;
+
+ pair size=M-m;
+ ostringstream cmd;
+ cmd << "\\special{dvisvgm:img " << size.getx()*ps2tex << " "
+ << size.gety()*ps2tex << " " << pngname << "}";
+ static pen P;
+ static pair zero;
+ L=new drawLabel(cmd.str(),"",identity,pair(m.getx(),M.gety()),zero,P);
+ texinit();
+ L->bounds(b_cached,processData().tex,labelbounds,bboxstack);
+ postscript=true;
+ }
+ break;
+ } else postscript |= (*p)->draw(&out);
+ }
+
+ if(Labels) {
+ tex->beginlayer(pdf ? pdfname : psname,postscript);
+ } else out.grestore();
+
+ out.epilogue();
+ out.close();
+
+// if(out.Transparency())
+// transparency=true;
+
+ if(Labels) {
+ tex->resetpen();
+ if(pdf && !b.empty) {
+ status=(epstopdf(psname,pdfname) == 0);
+ if(!getSetting<bool>("keep")) unlink(psname.c_str());
+ }
+
+ if(status) {
+ for (p=layerp; p != nodes.end(); ++p) {
+ assert(*p);
+ bool islayer=(*p)->islayer();
+ if(dvi && (*p)->svg()) {
+ islayer=true;
+ if((*p)->svgpng())
+ L->write(tex,b);
+ else
+ (*p)->draw(tex);
+ } else
+ (*p)->write(tex,b);
+ if(islayer) {
+ tex->endlayer();
+ layerp=++p;
+ layer++;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ bool context=settings::context(texengine);
+ if(status) {
+ if(TeXmode) {
+ if(Labels && verbose > 0) cout << "Wrote " << texname << endl;
+ delete tex;
+ } else {
+ if(Labels) {
+ tex->epilogue();
+ if(context) prefix=stripDir(prefix);
+ status=texprocess(texname,dvi ? outname : prename,prefix,
+ bboxshift,dvi);
+ delete tex;
+ if(!getSetting<bool>("keep")) {
+ for(mem::list<string>::iterator p=files.begin(); p != files.end();
+ ++p)
+ unlink(p->c_str());
+ }
+ }
+ if(status) {
+ if(context) prename=stripDir(prename);
+ status=postprocess(prename,outname,outputformat,wait,
+ view,pdf && Labels,epsformat,svg);
+ if(pdfformat && !getSetting<bool>("keep")) {
+ unlink(auxname(prefix,"m9").c_str());
+ unlink(auxname(prefix,"pbsdat").c_str());
+ }
+ }
+ }
+ }
+
+ if(!status) reportError("shipout failed");
+
+ return true;
+}
+
+// render viewport with width x height pixels.
+void picture::render(double size2, const triple& Min, const triple& Max,
+ double perspective, bool transparent, bool remesh) const
+{
+ if(remesh) {
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->render(size2,Min,Max,perspective,transparent);
+ }
+ }
+
+#ifdef HAVE_GL
+ if(transparent)
+ drawBezierPatch::S.drawTransparent();
+ else {
+ drawBezierPatch::S.drawOpaque();
+ drawPath3::R.draw();
+ drawPixel::R.draw();
+ }
+#endif
+}
+
+struct Communicate : public gc {
+ string prefix;
+ picture* pic;
+ string format;
+ double width;
+ double height;
+ double angle;
+ double zoom;
+ triple m;
+ triple M;
+ pair shift;
+ double *t;
+ double *background;
+ size_t nlights;
+ triple *lights;
+ double *diffuse;
+ double *specular;
+ bool view;
+};
+
+Communicate com;
+
+void glrenderWrapper()
+{
+#ifdef HAVE_GL
+#ifdef HAVE_PTHREAD
+ wait(initSignal,initLock);
+ endwait(initSignal,initLock);
+#endif
+ glrender(com.prefix,com.pic,com.format,com.width,com.height,com.angle,
+ com.zoom,com.m,com.M,com.shift,com.t,com.background,com.nlights,
+ com.lights,com.diffuse,com.specular,com.view);
+#endif
+}
+
+bool picture::shipout3(const string& prefix, const string& format,
+ double width, double height, double angle, double zoom,
+ const triple& m, const triple& M, const pair& shift,
+ double *t, double *background, size_t nlights,
+ triple *lights, double *diffuse, double *specular, bool view)
+{
+ if(getSetting<bool>("interrupt"))
+ return true;
+
+#ifndef HAVE_LIBGLUT
+ if(!getSetting<bool>("offscreen"))
+ camp::reportError("to support onscreen rendering, please install glut library, run ./configure, and recompile");
+#endif
+
+#ifndef HAVE_LIBOSMESA
+ if(getSetting<bool>("offscreen"))
+ camp::reportError("to support offscreen rendering; please install OSMesa library, run ./configure --enable-offscreen, and recompile");
+#endif
+
+ picture *pic = new picture;
+
+ matrixstack ms;
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->begingroup3())
+ ms.push((*p)->transf3());
+ else if((*p)->endgroup3())
+ ms.pop();
+ else
+ pic->append((*p)->transformed(ms.T()));
+ }
+
+ pic->b3=bbox3();
+ for(nodelist::iterator p=pic->nodes.begin(); p != pic->nodes.end(); ++p) {
+ assert(*p);
+ (*p)->bounds(pic->b3);
+ }
+ pic->lastnumber3=pic->nodes.size();
+
+ for(nodelist::iterator p=pic->nodes.begin(); p != pic->nodes.end(); ++p) {
+ assert(*p);
+ (*p)->displacement();
+ }
+
+ const string outputformat=format.empty() ?
+ getSetting<string>("outformat") : format;
+
+#ifdef HAVE_GL
+ bool View=settings::view() && view;
+ static int oldpid=0;
+ bool offscreen=getSetting<bool>("offscreen");
+#ifdef HAVE_PTHREAD
+ bool animating=getSetting<bool>("animating");
+ bool Wait=!interact::interactive || !View || animating;
+#endif
+#endif
+
+#if defined(HAVE_LIBGLUT) && defined(HAVE_GL)
+ if(glthread && !offscreen) {
+#ifdef HAVE_PTHREAD
+ if(gl::initialize) {
+ gl::initialize=false;
+ com.prefix=prefix;
+ com.pic=pic;
+ com.format=outputformat;
+ com.width=width;
+ com.height=height;
+ com.angle=angle;
+ com.zoom=zoom;
+ com.m=m;
+ com.M=M;
+ com.shift=shift;
+ com.t=t;
+ com.background=background;
+ com.nlights=nlights;
+ com.lights=lights;
+ com.diffuse=diffuse;
+ com.specular=specular;
+ com.view=View;
+ if(Wait)
+ pthread_mutex_lock(&readyLock);
+ wait(initSignal,initLock);
+ endwait(initSignal,initLock);
+ static bool initialize=true;
+ if(initialize) {
+ wait(initSignal,initLock);
+ endwait(initSignal,initLock);
+ initialize=false;
+ }
+ if(Wait) {
+ pthread_cond_wait(&readySignal,&readyLock);
+ pthread_mutex_unlock(&readyLock);
+ }
+ return true;
+ }
+ if(Wait)
+ pthread_mutex_lock(&readyLock);
+#endif
+ } else {
+ int pid=fork();
+ if(pid == -1)
+ camp::reportError("Cannot fork process");
+ if(pid != 0) {
+ oldpid=pid;
+ waitpid(pid,NULL,interact::interactive && View ? WNOHANG : 0);
+ return true;
+ }
+ }
+#endif
+#ifdef HAVE_GL
+ glrender(prefix,pic,outputformat,width,height,angle,zoom,m,M,shift,t,
+ background,nlights,lights,diffuse,specular,View,oldpid);
+#ifdef HAVE_PTHREAD
+ if(glthread && !offscreen && Wait) {
+ pthread_cond_wait(&readySignal,&readyLock);
+ pthread_mutex_unlock(&readyLock);
+ }
+ return true;
+#endif
+#endif
+
+ return false;
+}
+
+bool picture::shipout3(const string& prefix)
+{
+ bounds3();
+ bool status = true;
+
+ string prcname=buildname(prefix,"prc");
+ prcfile prc(prcname);
+
+ static const double limit=2.5*10.0/INT_MAX;
+ double compressionlimit=max(length(b3.Max()),length(b3.Min()))*limit;
+
+ groups.push_back(groupmap());
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->write(&prc,&billboard,compressionlimit,groups);
+ }
+ groups.pop_back();
+ if(status)
+ status=prc.finish();
+
+ if(!status) reportError("shipout3 failed");
+
+ if(verbose > 0) cout << "Wrote " << prcname << endl;
+
+ return true;
+}
+
+picture *picture::transformed(const transform& t)
+{
+ picture *pic = new picture;
+
+ nodelist::iterator p;
+ for (p = nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ pic->append((*p)->transformed(t));
+ }
+ pic->T=transform(t*T);
+
+ return pic;
+}
+
+picture *picture::transformed(const array& t)
+{
+ picture *pic = new picture;
+ double* T=NULL;
+ copyArray4x4C(T,&t);
+ size_t level = 0;
+ for (nodelist::iterator p = nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if(level==0)
+ pic->append((*p)->transformed(T));
+ else
+ pic->append(*p);
+ if((*p)->begingroup3())
+ level++;
+ if((*p)->endgroup3()) {
+ if(level==0)
+ reportError("endgroup3 without matching begingroup3");
+ else
+ level--;
+ }
+ }
+
+ return pic;
+}
+
+
+} // namespace camp
diff --git a/graphics/asymptote/picture.h b/graphics/asymptote/picture.h
new file mode 100644
index 0000000000..0d571d0a3b
--- /dev/null
+++ b/graphics/asymptote/picture.h
@@ -0,0 +1,128 @@
+/*****
+ * picture.h
+ * Andy Hamerlindl 2002/06/06
+ *
+ * Stores a picture as a list of drawElements and handles its output to
+ * PostScript.
+ *****/
+
+#ifndef PICTURE_H
+#define PICTURE_H
+
+#include <sstream>
+#include <iostream>
+
+#include "drawelement.h"
+
+namespace camp {
+
+class picture : public gc {
+private:
+ bool labels;
+ size_t lastnumber;
+ size_t lastnumber3;
+ transform T; // Keep track of accumulative picture transform
+ bbox b;
+ bbox b_cached; // Cached bounding box
+ boxvector labelbounds;
+ bboxlist bboxstack;
+ bool transparency;
+ groupsmap groups;
+ unsigned billboard;
+public:
+ bbox3 b3; // 3D bounding box
+
+ typedef mem::list<drawElement*> nodelist;
+ nodelist nodes;
+
+ picture() : labels(false), lastnumber(0), lastnumber3(0), T(identity),
+ transparency(false), billboard(0) {}
+
+ // Destroy all of the owned picture objects.
+ ~picture();
+
+ // Prepend an object to the picture.
+ void prepend(drawElement *p);
+
+ // Append an object to the picture.
+ void append(drawElement *p);
+
+ // Enclose each layer with begin and end.
+ void enclose(drawElement *begin, drawElement *end);
+
+ // Add the content of another picture.
+ void add(picture &pic);
+ void prepend(picture &pic);
+
+ bool havelabels();
+ bool have3D();
+ bool havepng();
+ bool havenewpage();
+
+ bbox bounds();
+ bbox3 bounds3();
+
+ // Compute bounds on ratio (x,y)/z for 3d picture (not cached).
+ pair ratio(double (*m)(double, double));
+
+ bool Transparency() {
+ return transparency;
+ }
+
+ int epstosvg(const string& epsname, const string& outname);
+ int pdftosvg(const string& pdfname, const string& outname);
+
+ int epstopdf(const string& epsname, const string& pdfname);
+ int pdftoeps(const string& pdfname, const string& epsname);
+
+ bool texprocess(const string& texname, const string& tempname,
+ const string& prefix, const pair& bboxshift, bool svgformat);
+
+ bool postprocess(const string& prename, const string& outname,
+ const string& outputformat, bool wait, bool view,
+ bool pdftex, bool epsformat, bool svg);
+
+ // Ship the picture out to PostScript & TeX files.
+ bool shipout(picture* preamble, const string& prefix,
+ const string& format, bool wait=false, bool view=true);
+
+ void render(double size2, const triple &Min, const triple& Max,
+ double perspective, bool transparent, bool remesh) const;
+ bool shipout3(const string& prefix, const string& format,
+ double width, double height, double angle, double zoom,
+ const triple& m, const triple& M, const pair& shift, double *t,
+ double *background, size_t nlights, triple *lights,
+ double *diffuse, double *specular, bool view);
+
+ // PRC output
+ bool shipout3(const string& prefix);
+
+ bool reloadPDF(const string& Viewer, const string& outname) const;
+
+ picture *transformed(const transform& t);
+ picture *transformed(const vm::array& t);
+
+ bool null() {
+ return nodes.empty();
+ }
+
+};
+
+inline picture *transformed(const transform& t, picture *p)
+{
+ return p->transformed(t);
+}
+
+inline picture *transformed(const vm::array& t, picture *p)
+{
+ return p->transformed(t);
+}
+
+void texinit();
+int opentex(const string& texname, const string& prefix, bool dvi=false);
+
+const char *texpathmessage();
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/pipestream.cc b/graphics/asymptote/pipestream.cc
new file mode 100644
index 0000000000..c53287c28c
--- /dev/null
+++ b/graphics/asymptote/pipestream.cc
@@ -0,0 +1,211 @@
+/* Pipestream: A simple C++ interface to UNIX pipes
+ Copyright (C) 2005-2014 John C. Bowman,
+ with contributions from Mojca Miklavec
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <iostream>
+#include <cstring>
+#include <cerrno>
+#include <sstream>
+#include <signal.h>
+
+#include "pipestream.h"
+#include "common.h"
+#include "errormsg.h"
+#include "settings.h"
+#include "util.h"
+#include "interact.h"
+#include "lexical.h"
+#include "camperror.h"
+#include "pen.h"
+
+void iopipestream::open(const mem::vector<string> &command, const char *hint,
+ const char *application, int out_fileno)
+{
+ if(pipe(in) == -1) {
+ ostringstream buf;
+ buf << "in pipe failed: ";
+ for(size_t i=0; i < command.size(); ++i) buf << command[i];
+ camp::reportError(buf);
+ }
+
+ if(pipe(out) == -1) {
+ ostringstream buf;
+ buf << "out pipe failed: ";
+ for(size_t i=0; i < command.size(); ++i) buf << command[i];
+ camp::reportError(buf);
+ }
+ cout.flush(); // Flush stdout to avoid duplicate output.
+
+ if((pid=fork()) < 0) {
+ ostringstream buf;
+ buf << "fork failed: ";
+ for(size_t i=0; i < command.size(); ++i) buf << command[i];
+ camp::reportError(buf);
+ }
+
+ if(pid == 0) {
+ if(interact::interactive) signal(SIGINT,SIG_IGN);
+ close(in[1]);
+ close(out[0]);
+ close(STDIN_FILENO);
+ close(out_fileno);
+ dup2(in[0],STDIN_FILENO);
+ dup2(out[1],out_fileno);
+ close(in[0]);
+ close(out[1]);
+ char **argv=args(command);
+ if(argv) execvp(argv[0],argv);
+ execError(argv[0],hint,application);
+ kill(0,SIGTERM);
+ _exit(-1);
+ }
+ close(out[1]);
+ close(in[0]);
+ *buffer=0;
+ pipeopen=true;
+ pipein=true;
+ Running=true;
+ block(false,true);
+}
+
+void iopipestream::eof()
+{
+ if(pipeopen && pipein) {
+ close(in[1]);
+ pipein=false;
+ }
+}
+
+void iopipestream::pipeclose()
+{
+ if(pipeopen) {
+// kill(pid,SIGTERM);
+ eof();
+ close(out[0]);
+ Running=false;
+ pipeopen=false;
+ waitpid(pid,NULL,0); // Avoid zombies.
+ }
+}
+
+void iopipestream::block(bool write, bool read)
+{
+ if(pipeopen) {
+ int w=fcntl(in[1],F_GETFL);
+ int r=fcntl(out[0],F_GETFL);
+ fcntl(in[1],F_SETFL,write ? w & ~O_NONBLOCK : w | O_NONBLOCK);
+ fcntl(out[0],F_SETFL,read ? r & ~O_NONBLOCK : r | O_NONBLOCK);
+ }
+}
+
+ssize_t iopipestream::readbuffer()
+{
+ ssize_t nc;
+ char *p=buffer;
+ ssize_t size=BUFSIZE-1;
+ errno=0;
+ for(;;) {
+ if((nc=read(out[0],p,size)) < 0) {
+ if(errno == EAGAIN || errno == EINTR) {p[0]=0; break;}
+ else {
+ ostringstream buf;
+ buf << "read from pipe failed: errno=" << errno;
+ camp::reportError(buf);
+ }
+ nc=0;
+ }
+ p[nc]=0;
+ if(nc == 0) {
+ if(waitpid(pid,NULL,WNOHANG) == pid)
+ Running=false;
+ break;
+ }
+ if(nc > 0) {
+ if(settings::verbose > 2) cerr << p;
+ break;
+ }
+ }
+ return nc;
+}
+
+bool iopipestream::tailequals(const char *buf, size_t len, const char *prompt,
+ size_t plen)
+{
+ const char *a=buf+len;
+ const char *b=prompt+plen;
+ while(b >= prompt) {
+ if(a < buf) return false;
+ if(*a != *b) return false;
+ // Handle MSDOS incompatibility:
+ if(a > buf && *a == '\n' && *(a-1) == '\r') --a;
+ --a; --b;
+ }
+ return true;
+}
+
+string iopipestream::readline()
+{
+ sbuffer.clear();
+ int nc;
+ do {
+ nc=readbuffer();
+ sbuffer.append(buffer);
+ } while(buffer[nc-1] != '\n' && Running);
+ return sbuffer;
+}
+
+void iopipestream::wait(const char *prompt)
+{
+ sbuffer.clear();
+ size_t plen=strlen(prompt);
+
+ do {
+ readbuffer();
+ sbuffer.append(buffer);
+ } while(!tailequals(sbuffer.c_str(),sbuffer.size(),prompt,plen));
+}
+
+int iopipestream::wait()
+{
+ for(;;) {
+ int status;
+ if (waitpid(pid,&status,0) == -1) {
+ if (errno == ECHILD) return 0;
+ if (errno != EINTR) {
+ ostringstream buf;
+ buf << "Process " << pid << " failed";
+ camp::reportError(buf);
+ }
+ } else {
+ if(WIFEXITED(status)) return WEXITSTATUS(status);
+ else {
+ ostringstream buf;
+ buf << "Process " << pid << " exited abnormally";
+ camp::reportError(buf);
+ }
+ }
+ }
+}
+
+void iopipestream::Write(const string &s)
+{
+ ssize_t size=s.length();
+ if(settings::verbose > 2) cerr << s;
+ if(write(in[1],s.c_str(),size) != size) {
+ camp::reportFatal("write to pipe failed");
+ }
+}
diff --git a/graphics/asymptote/pipestream.h b/graphics/asymptote/pipestream.h
new file mode 100644
index 0000000000..26eae7a611
--- /dev/null
+++ b/graphics/asymptote/pipestream.h
@@ -0,0 +1,105 @@
+/* Pipestream: A simple C++ interface to UNIX pipes
+ Version 0.05
+ Copyright (C) 2005-2014 John C. Bowman,
+ with contributions from Mojca Miklavec
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef PIPESTREAM_H
+#define PIPESTREAM_H
+
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "common.h"
+
+// bidirectional stream for reading and writing to pipes
+class iopipestream {
+protected:
+ int in[2];
+ int out[2];
+ static const int BUFSIZE=SHRT_MAX;
+ char buffer[BUFSIZE];
+ string sbuffer;
+ int pid;
+ bool Running;
+ bool pipeopen;
+ bool pipein;
+public:
+
+ void open(const mem::vector<string> &command, const char *hint=NULL,
+ const char *application="", int out_fileno=STDOUT_FILENO);
+
+ bool isopen() {return pipeopen;}
+
+ iopipestream(): pid(0), pipeopen(false) {}
+
+ iopipestream(const mem::vector<string> &command, const char *hint=NULL,
+ const char *application="", int out_fileno=STDOUT_FILENO) :
+ pid(0), pipeopen(false) {
+ open(command,hint,application,out_fileno);
+ }
+
+ void eof();
+ virtual void pipeclose();
+
+ virtual ~iopipestream() {
+ pipeclose();
+ }
+
+ void block(bool write=false, bool read=true);
+
+ ssize_t readbuffer();
+ string readline();
+
+ bool running() {return Running;}
+
+ typedef iopipestream& (*imanip)(iopipestream&);
+
+ iopipestream& operator << (imanip func) {
+ return (*func)(*this);
+ }
+
+ iopipestream& operator >> (string& s) {
+ readbuffer();
+ s=buffer;
+ return *this;
+ }
+
+ bool tailequals(const char *buf, size_t len, const char *prompt,
+ size_t plen);
+
+ string getbuffer() {return sbuffer;}
+
+ void wait(const char *prompt);
+ int wait();
+ void Write(const string &s);
+
+ iopipestream& operator << (const string& s) {
+ Write(s);
+ return *this;
+ }
+
+ template<class T>
+ iopipestream& operator << (T x) {
+ ostringstream os;
+ os << x;
+ Write(os.str());
+ return *this;
+ }
+};
+
+#endif
diff --git a/graphics/asymptote/policy.h b/graphics/asymptote/policy.h
new file mode 100644
index 0000000000..fe8fcf7a27
--- /dev/null
+++ b/graphics/asymptote/policy.h
@@ -0,0 +1,83 @@
+/*****
+ * policy.h
+ * Andy Hammerlindl 2011/09/03
+ *
+ * Defines a low-level C interface for interacting with the interpreter and
+ * its datatypes.
+ *****/
+
+// TODO: Wrap in namespace.
+
+typedef long long int_typ;
+
+typedef struct {} handle_base_typ;
+typedef handle_base_typ *handle_typ;
+typedef struct {} arguments_base_typ;
+typedef arguments_base_typ *arguments_typ;
+typedef struct {} state_base_typ;
+typedef state_base_typ *state_typ;
+
+typedef void (*function_typ)(state_typ, void *);
+
+typedef struct {
+ const char *buf;
+ size_t length;
+} string_typ;
+
+typedef void (*error_callback_typ)(string_typ);
+
+typedef long arg_rest_option;
+#define NORMAL_ARG 45000
+#define REST_ARG 45001
+
+typedef struct {
+ int_typ version;
+
+ handle_typ (*copyHandle)(handle_typ handle);
+ void (*releaseHandle)();
+
+ handle_typ (*handleFromInt)(int_typ x);
+ // For bool, O is false, 1 is true, and no other value is allowed.
+ handle_typ (*handleFromBool)(int_typ x);
+ handle_typ (*handleFromDouble)(double x);
+ handle_typ (*handleFromString)(string_typ x);
+ handle_typ (*handleFromFunction)(const char *signature,
+ function_typ f, void *data);
+
+ int_typ (*IntFromHandle)(handle_typ handle);
+ int_typ (*boolFromHandle)(handle_typ handle);
+ double (*doubleFromHandle)(handle_typ handle);
+ // TODO: Note that a pointer and length are returned, but the pointer is
+ // valid for a limited time only.
+ string_typ (*stringFromHandle)(handle_typ handle);
+
+#if 0
+ bool (*handleIsOverloaded)(handle_typ handle);
+ handle_typ (*signatureless)(handle_typ handle);
+#endif
+
+ handle_typ (*getField)(handle_typ handle, const char *name);
+ handle_typ (*getCell)(handle_typ handle, handle_typ index);
+
+ // Adds a field to a datum (possibly a module) and sets it to an initial
+ // value.
+ // TODO: Change name to sig.
+ void (*addField)(handle_typ handle,
+ const char *name, handle_typ init);
+
+ arguments_typ (*newArguments)();
+ void (*releaseArguments)(arguments_typ args);
+ void (*addArgument)(arguments_typ args, const char *name, handle_typ handle,
+ arg_rest_option at);
+ handle_typ (*call)(handle_typ callee, arguments_typ args);
+
+ handle_typ (*globals)(state_typ state);
+ int_typ (*numParams)(state_typ state);
+ handle_typ (*getParam)(state_typ state, int_typ index);
+ void (*setReturnValue)(state_typ state, handle_typ handle);
+
+ // Allows the user sets an error callback, which is called on any error.
+ void (*setErrorCallback)(error_callback_typ callback);
+} policy_typ;
+
+
diff --git a/graphics/asymptote/prc/Makefile b/graphics/asymptote/prc/Makefile
new file mode 100644
index 0000000000..23dd32aa3b
--- /dev/null
+++ b/graphics/asymptote/prc/Makefile
@@ -0,0 +1,42 @@
+# Makefile.
+
+CFLAGS = -O3 -g -Wall
+CXX = g++
+
+MAKEDEPEND = $(CFLAGS) -O0 -M -DDEPEND
+
+FILES = PRCbitStream oPRCFile PRCdouble writePRC
+
+all: $(FILES:=.o)
+
+#test: $(FILES:=.o) test.o
+# $(CXX) $(CFLAGS) -o test $(FILES:=.o) test.o -lz
+
+#test_tess: $(FILES:=.o) test_tess.o
+# $(CXX) $(CFLAGS) -o test_tess $(FILES:=.o) test_tess.o -lz
+
+#test_mesh: $(FILES:=.o) test_mesh.o
+# $(CXX) $(CFLAGS) -o test_mesh $(FILES:=.o) test_mesh.o -lz
+
+.SUFFIXES: .c .cc .o .d
+.cc.o:
+ $(CXX) $(CFLAGS) $(INCL) -o $@ -c $<
+.cc.d:
+ @echo Creating $@; \
+ rm -f $@; \
+ ${CXX} $(MAKEDEPEND) $(INCL) $(MDOPTS) $< > $@.$$$$ 2>/dev/null && \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+.c.d:
+ @echo Creating $@; \
+ rm -f $@; \
+ ${CC} $(MAKEDEPEND) $(INCL) $(MDOPTS) $< > $@.$$$$ 2>/dev/null && \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+ifeq (,$(findstring clean,${MAKECMDGOALS}))
+-include $(FILES:=.d)
+endif
+
+clean:
+ rm -f *.o *.d test test_tess
diff --git a/graphics/asymptote/prc/PRC.h b/graphics/asymptote/prc/PRC.h
new file mode 100644
index 0000000000..9ce6ea70e0
--- /dev/null
+++ b/graphics/asymptote/prc/PRC.h
@@ -0,0 +1,512 @@
+#ifndef __PRC_H
+#define __PRC_H
+
+#ifdef _MSC_VER
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#endif // _MSC_VER >= 1600
+#else
+#include <inttypes.h>
+#endif // _MSC_VER
+
+//const uint32_t PRCVersion=7094; // For Adobe Reader 8 or later
+const uint32_t PRCVersion=8137; // For Adobe Reader 9 or later
+
+// from Adobe's documentation
+
+#define PRC_TYPE_Unknown ( (uint32_t)-1 )
+
+#define PRC_TYPE_ROOT 0 // This type does not correspond to any entity
+
+#define PRC_TYPE_ROOT_PRCBase ( PRC_TYPE_ROOT + 1 ) // Abstract root type for any PRC entity.
+#define PRC_TYPE_ROOT_PRCBaseWithGraphics ( PRC_TYPE_ROOT + 2 ) // Abstract root type for any PRC entity which can bear graphics.
+
+#define PRC_TYPE_CRV ( PRC_TYPE_ROOT + 10 ) // Types for PRC geometrical curves
+#define PRC_TYPE_SURF ( PRC_TYPE_ROOT + 75 ) // Types for PRC geometrical surfaces
+#define PRC_TYPE_TOPO ( PRC_TYPE_ROOT + 140 ) // Types for PRC topology
+#define PRC_TYPE_TESS ( PRC_TYPE_ROOT + 170 ) // Types for PRC tessellation
+#define PRC_TYPE_MISC ( PRC_TYPE_ROOT + 200 ) // Types for PRC global data
+#define PRC_TYPE_RI ( PRC_TYPE_ROOT + 230 ) // Types for PRC representation items
+#define PRC_TYPE_ASM ( PRC_TYPE_ROOT + 300 ) // Types for PRC assembly
+#define PRC_TYPE_MKP ( PRC_TYPE_ROOT + 500 ) // Types for PRC markup
+#define PRC_TYPE_GRAPH ( PRC_TYPE_ROOT + 700 ) // Types for PRC graphics
+#define PRC_TYPE_MATH ( PRC_TYPE_ROOT + 900 ) // Types for PRC mathematical operators
+
+#define PRC_TYPE_CRV_Base ( PRC_TYPE_CRV + 1 ) // Abstract type for all geometric curves.
+#define PRC_TYPE_CRV_Blend02Boundary ( PRC_TYPE_CRV + 2 ) // Boundary Curve.
+#define PRC_TYPE_CRV_NURBS ( PRC_TYPE_CRV + 3 ) // Non Uniform BSpline curve.
+#define PRC_TYPE_CRV_Circle ( PRC_TYPE_CRV + 4 ) // Circle.
+#define PRC_TYPE_CRV_Composite ( PRC_TYPE_CRV + 5 ) // Array of oriented curves.
+#define PRC_TYPE_CRV_OnSurf ( PRC_TYPE_CRV + 6 ) // Curve defined by a UV curve on a surface.
+#define PRC_TYPE_CRV_Ellipse ( PRC_TYPE_CRV + 7 ) // Ellipse.
+#define PRC_TYPE_CRV_Equation ( PRC_TYPE_CRV + 8 ) // curve described by specific law elements
+#define PRC_TYPE_CRV_Helix ( PRC_TYPE_CRV + 9 ) // Helix curve.
+#define PRC_TYPE_CRV_Hyperbola ( PRC_TYPE_CRV + 10 ) // Hyperbola.
+#define PRC_TYPE_CRV_Intersection ( PRC_TYPE_CRV + 11 ) // Intersection between 2 surfaces.
+#define PRC_TYPE_CRV_Line ( PRC_TYPE_CRV + 12 ) // Line.
+#define PRC_TYPE_CRV_Offset ( PRC_TYPE_CRV + 13 ) // Offset curve.
+#define PRC_TYPE_CRV_Parabola ( PRC_TYPE_CRV + 14 ) // Parabola.
+#define PRC_TYPE_CRV_PolyLine ( PRC_TYPE_CRV + 15 ) // Polyedric curve.
+#define PRC_TYPE_CRV_Transform ( PRC_TYPE_CRV + 16 ) // Transformed curve.
+
+#define PRC_TYPE_SURF_Base ( PRC_TYPE_SURF + 1 ) // Abstract type for all geometric surfaces.
+#define PRC_TYPE_SURF_Blend01 ( PRC_TYPE_SURF + 2 ) // Blend surface.
+#define PRC_TYPE_SURF_Blend02 ( PRC_TYPE_SURF + 3 ) // Blend Surface.
+#define PRC_TYPE_SURF_Blend03 ( PRC_TYPE_SURF + 4 ) // Blend Surface.
+#define PRC_TYPE_SURF_NURBS ( PRC_TYPE_SURF + 5 ) // Non Uniform BSpline surface.
+#define PRC_TYPE_SURF_Cone ( PRC_TYPE_SURF + 6 ) // Cone.
+#define PRC_TYPE_SURF_Cylinder ( PRC_TYPE_SURF + 7 ) // Cylinder.
+#define PRC_TYPE_SURF_Cylindrical ( PRC_TYPE_SURF + 8 ) // Surface who is defined in cylindrical space.
+#define PRC_TYPE_SURF_Offset ( PRC_TYPE_SURF + 9 ) // Offset surface.
+#define PRC_TYPE_SURF_Pipe ( PRC_TYPE_SURF + 10 ) // Pipe.
+#define PRC_TYPE_SURF_Plane ( PRC_TYPE_SURF + 11 ) // Plane.
+#define PRC_TYPE_SURF_Ruled ( PRC_TYPE_SURF + 12 ) // Ruled surface.
+#define PRC_TYPE_SURF_Sphere ( PRC_TYPE_SURF + 13 ) // Sphere.
+#define PRC_TYPE_SURF_Revolution ( PRC_TYPE_SURF + 14 ) // Surface of revolution.
+#define PRC_TYPE_SURF_Extrusion ( PRC_TYPE_SURF + 15 ) // Surface of extrusion.
+#define PRC_TYPE_SURF_FromCurves ( PRC_TYPE_SURF + 16 ) // Surface from two curves.
+#define PRC_TYPE_SURF_Torus ( PRC_TYPE_SURF + 17 ) // Torus.
+#define PRC_TYPE_SURF_Transform ( PRC_TYPE_SURF + 18 ) // Transformed surface.
+#define PRC_TYPE_SURF_Blend04 ( PRC_TYPE_SURF + 19 ) // defined for future use.
+
+#define PRC_TYPE_TOPO_Context ( PRC_TYPE_TOPO + 1 ) // Self-containing set of topological entities.
+#define PRC_TYPE_TOPO_Item ( PRC_TYPE_TOPO + 2 ) // Abstract root type for any topological entity (body or single item).
+#define PRC_TYPE_TOPO_MultipleVertex ( PRC_TYPE_TOPO + 3 ) // Vertex whose position is the average of all edges' extremity positions to whom it belongs.
+#define PRC_TYPE_TOPO_UniqueVertex ( PRC_TYPE_TOPO + 4 ) // Vertex with one set of coordinates (absolute position).
+#define PRC_TYPE_TOPO_WireEdge ( PRC_TYPE_TOPO + 5 ) // Edge belonging to a wire body / single wire body.
+#define PRC_TYPE_TOPO_Edge ( PRC_TYPE_TOPO + 6 ) // Edge belonging to a brep data.
+#define PRC_TYPE_TOPO_CoEdge ( PRC_TYPE_TOPO + 7 ) // Usage of an edge in a loop.
+#define PRC_TYPE_TOPO_Loop ( PRC_TYPE_TOPO + 8 ) // Array of co edges which delimits a face.
+#define PRC_TYPE_TOPO_Face ( PRC_TYPE_TOPO + 9 ) // Topological face delimiting a shell.
+#define PRC_TYPE_TOPO_Shell ( PRC_TYPE_TOPO + 10 ) // Topological shell (open or closed).
+#define PRC_TYPE_TOPO_Connex ( PRC_TYPE_TOPO + 11 ) // Topological region delimited by one or several shells.
+#define PRC_TYPE_TOPO_Body ( PRC_TYPE_TOPO + 12 ) // Abstract root type for any topological body.
+#define PRC_TYPE_TOPO_SingleWireBody ( PRC_TYPE_TOPO + 13 ) // Single wire body.
+#define PRC_TYPE_TOPO_BrepData ( PRC_TYPE_TOPO + 14 ) // Main entry to solid and surface topology (regular form).
+#define PRC_TYPE_TOPO_SingleWireBodyCompress ( PRC_TYPE_TOPO + 15 ) // Single wire body. (ultra compressed form).
+#define PRC_TYPE_TOPO_BrepDataCompress ( PRC_TYPE_TOPO + 16 ) // Main entry to solid and surface topology (ultra compressed form).
+#define PRC_TYPE_TOPO_WireBody ( PRC_TYPE_TOPO + 17 ) // This type is the main entry to wire topology.
+
+#define PRC_TYPE_TESS_Base ( PRC_TYPE_TESS + 1 ) // Abstract root type for any tessellated entity.
+#define PRC_TYPE_TESS_3D ( PRC_TYPE_TESS + 2 ) // Tessellated faceted data; regular form.
+#define PRC_TYPE_TESS_3D_Compressed ( PRC_TYPE_TESS + 3 ) // Tessellated faceted data; highly compressed form.
+#define PRC_TYPE_TESS_Face ( PRC_TYPE_TESS + 4 ) // Tessellated face.
+#define PRC_TYPE_TESS_3D_Wire ( PRC_TYPE_TESS + 5 ) // Tessellated wireframe.
+#define PRC_TYPE_TESS_Markup ( PRC_TYPE_TESS + 6 ) // Tessellated markup.
+
+#define PRC_TYPE_MISC_Attribute ( PRC_TYPE_MISC + 1 ) // Entity attribute.
+#define PRC_TYPE_MISC_CartesianTransformation ( PRC_TYPE_MISC + 2 ) // Cartesian transformation.
+#define PRC_TYPE_MISC_EntityReference ( PRC_TYPE_MISC + 3 ) // Entity reference.
+#define PRC_TYPE_MISC_MarkupLinkedItem ( PRC_TYPE_MISC + 4 ) // Link between a markup and an entity.
+#define PRC_TYPE_MISC_ReferenceOnPRCBase ( PRC_TYPE_MISC + 5 ) // Reference pointing on a regular entity (not topological).
+#define PRC_TYPE_MISC_ReferenceOnTopology ( PRC_TYPE_MISC + 6 ) // Reference pointing on a topological entity.
+#define PRC_TYPE_MISC_GeneralTransformation ( PRC_TYPE_MISC + 7 ) // General transformation.
+
+#define PRC_TYPE_RI_RepresentationItem ( PRC_TYPE_RI + 1 ) // Basic abstract type for representation items.
+#define PRC_TYPE_RI_BrepModel ( PRC_TYPE_RI + 2 ) // Basic type for surfaces and solids.
+#define PRC_TYPE_RI_Curve ( PRC_TYPE_RI + 3 ) // Basic type for curves.
+#define PRC_TYPE_RI_Direction ( PRC_TYPE_RI + 4 ) // Optional point + vector.
+#define PRC_TYPE_RI_Plane ( PRC_TYPE_RI + 5 ) // Construction plane, as opposed to planar surface.
+#define PRC_TYPE_RI_PointSet ( PRC_TYPE_RI + 6 ) // Set of points.
+#define PRC_TYPE_RI_PolyBrepModel ( PRC_TYPE_RI + 7 ) // Basic type to polyhedral surfaces and solids.
+#define PRC_TYPE_RI_PolyWire ( PRC_TYPE_RI + 8 ) // Polyedric wireframe entity.
+#define PRC_TYPE_RI_Set ( PRC_TYPE_RI + 9 ) // Logical grouping of arbitrary number of representation items.
+#define PRC_TYPE_RI_CoordinateSystem ( PRC_TYPE_RI + 10 ) // Coordinate system.
+
+#define PRC_TYPE_ASM_ModelFile ( PRC_TYPE_ASM + 1 ) // Basic entry type for PRC.
+#define PRC_TYPE_ASM_FileStructure ( PRC_TYPE_ASM + 2 ) // Basic structure for PRC files.
+#define PRC_TYPE_ASM_FileStructureGlobals ( PRC_TYPE_ASM + 3 ) // Basic structure for PRC files : globals.
+#define PRC_TYPE_ASM_FileStructureTree ( PRC_TYPE_ASM + 4 ) // Basic structure for PRC files : tree.
+#define PRC_TYPE_ASM_FileStructureTessellation ( PRC_TYPE_ASM + 5 ) // Basic structure for PRC files : tessellation.
+#define PRC_TYPE_ASM_FileStructureGeometry ( PRC_TYPE_ASM + 6 ) // Basic structure for PRC files : geometry.
+#define PRC_TYPE_ASM_FileStructureExtraGeometry ( PRC_TYPE_ASM + 7 ) // Basic structure for PRC files : extra geometry data.
+#define PRC_TYPE_ASM_ProductOccurence ( PRC_TYPE_ASM + 10 ) // Basic contruct for assemblies.
+#define PRC_TYPE_ASM_PartDefinition ( PRC_TYPE_ASM + 11 ) // Basic construct for parts.
+#define PRC_TYPE_ASM_Filter ( PRC_TYPE_ASM + 20 )
+
+#define PRC_TYPE_MKP_View ( PRC_TYPE_MKP + 1 ) // Grouping of markup by views.
+#define PRC_TYPE_MKP_Markup ( PRC_TYPE_MKP + 2 ) // Basic type for simple markups.
+#define PRC_TYPE_MKP_Leader ( PRC_TYPE_MKP + 3 ) // basic type for markup leader
+#define PRC_TYPE_MKP_AnnotationItem ( PRC_TYPE_MKP + 4 ) // Usage of a markup.
+#define PRC_TYPE_MKP_AnnotationSet ( PRC_TYPE_MKP + 5 ) // Group of annotations.
+#define PRC_TYPE_MKP_AnnotationReference ( PRC_TYPE_MKP + 6 ) // Logical grouping of annotations for reference.
+
+#define PRC_TYPE_GRAPH_Style ( PRC_TYPE_GRAPH + 1 ) // Display style.
+#define PRC_TYPE_GRAPH_Material ( PRC_TYPE_GRAPH + 2 ) // Display material properties.
+#define PRC_TYPE_GRAPH_Picture ( PRC_TYPE_GRAPH + 3 ) // Picture.
+#define PRC_TYPE_GRAPH_TextureApplication ( PRC_TYPE_GRAPH + 11 ) // Texture application.
+#define PRC_TYPE_GRAPH_TextureDefinition ( PRC_TYPE_GRAPH + 12 ) // Texture definition.
+#define PRC_TYPE_GRAPH_TextureTransformation ( PRC_TYPE_GRAPH + 13 ) // Texture transformation.
+#define PRC_TYPE_GRAPH_LinePattern ( PRC_TYPE_GRAPH + 21 ) // One dimensional display style.
+#define PRC_TYPE_GRAPH_FillPattern ( PRC_TYPE_GRAPH + 22 ) // Abstract class for two-dimensional display style.
+#define PRC_TYPE_GRAPH_DottingPattern ( PRC_TYPE_GRAPH + 23 ) // Two-dimensional filling with dots.
+#define PRC_TYPE_GRAPH_HatchingPattern ( PRC_TYPE_GRAPH + 24 ) // Two-dimensional filling with hatches.
+#define PRC_TYPE_GRAPH_SolidPattern ( PRC_TYPE_GRAPH + 25 ) // Two-dimensional filling with particular style (color, material, texture).
+#define PRC_TYPE_GRAPH_VPicturePattern ( PRC_TYPE_GRAPH + 26 ) // Two-dimensional filling with vectorised picture.
+#define PRC_TYPE_GRAPH_AmbientLight ( PRC_TYPE_GRAPH + 31 ) // Scene ambient illumination.
+#define PRC_TYPE_GRAPH_PointLight ( PRC_TYPE_GRAPH + 32 ) // Scene point illumination.
+#define PRC_TYPE_GRAPH_DirectionalLight ( PRC_TYPE_GRAPH + 33 ) // Scene directional illumination.
+#define PRC_TYPE_GRAPH_SpotLight ( PRC_TYPE_GRAPH + 34 ) // Scene spot illumination.
+#define PRC_TYPE_GRAPH_SceneDisplayParameters ( PRC_TYPE_GRAPH + 41 ) // Parameters for scene visualisation.
+#define PRC_TYPE_GRAPH_Camera ( PRC_TYPE_GRAPH + 42 ) //
+
+#define PRC_TYPE_MATH_FCT_1D ( PRC_TYPE_MATH + 1 ) // Basic type for one degree equation object.
+#define PRC_TYPE_MATH_FCT_1D_Polynom ( PRC_TYPE_MATH_FCT_1D + 1 ) // Polynomial equation.
+#define PRC_TYPE_MATH_FCT_1D_Trigonometric ( PRC_TYPE_MATH_FCT_1D + 2 ) // Cosinus based equation.
+#define PRC_TYPE_MATH_FCT_1D_Fraction ( PRC_TYPE_MATH_FCT_1D + 3 ) // Fraction between 2 one degree equation object.
+#define PRC_TYPE_MATH_FCT_1D_ArctanCos ( PRC_TYPE_MATH_FCT_1D + 4 ) // Specific equation.
+#define PRC_TYPE_MATH_FCT_1D_Combination ( PRC_TYPE_MATH_FCT_1D + 5 ) // Combination of one degree equation object.
+#define PRC_TYPE_MATH_FCT_3D ( PRC_TYPE_MATH + 10 ) // Basic type for 3rd degree equation object.
+#define PRC_TYPE_MATH_FCT_3D_Linear ( PRC_TYPE_MATH_FCT_3D + 1 ) // Linear transformation ( with a matrix ).
+#define PRC_TYPE_MATH_FCT_3D_NonLinear ( PRC_TYPE_MATH_FCT_3D + 2 ) // Specific transformation.
+
+#define PRC_PRODUCT_FLAG_DEFAULT 0x0001
+#define PRC_PRODUCT_FLAG_INTERNAL 0x0002
+#define PRC_PRODUCT_FLAG_CONTAINER 0x0004
+#define PRC_PRODUCT_FLAG_CONFIG 0x0008
+#define PRC_PRODUCT_FLAG_VIEW 0x0010
+
+#define PRC_TRANSFORMATION_Identity 0x00
+#define PRC_TRANSFORMATION_Translate 0x01
+#define PRC_TRANSFORMATION_Rotate 0x02
+#define PRC_TRANSFORMATION_Mirror 0x04
+#define PRC_TRANSFORMATION_Scale 0x08
+#define PRC_TRANSFORMATION_NonUniformScale 0x10
+#define PRC_TRANSFORMATION_NonOrtho 0x20
+#define PRC_TRANSFORMATION_Homogeneous 0x40
+
+#define PRC_FACETESSDATA_Polyface 0x0001
+#define PRC_FACETESSDATA_Triangle 0x0002
+#define PRC_FACETESSDATA_TriangleFan 0x0004
+#define PRC_FACETESSDATA_TriangleStripe 0x0008
+#define PRC_FACETESSDATA_PolyfaceOneNormal 0x0010
+#define PRC_FACETESSDATA_TriangleOneNormal 0x0020
+#define PRC_FACETESSDATA_TriangleFanOneNormal 0x0040
+#define PRC_FACETESSDATA_TriangleStripeOneNormal 0x0080
+#define PRC_FACETESSDATA_PolyfaceTextured 0x0100
+#define PRC_FACETESSDATA_TriangleTextured 0x0200
+#define PRC_FACETESSDATA_TriangleFanTextured 0x0400
+#define PRC_FACETESSDATA_TriangleStripeTextured 0x0800
+#define PRC_FACETESSDATA_PolyfaceOneNormalTextured 0x1000
+#define PRC_FACETESSDATA_TriangleOneNormalTextured 0x2000
+#define PRC_FACETESSDATA_TriangleFanOneNormalTextured 0x4000
+#define PRC_FACETESSDATA_TriangleStripeOneNormalTextured 0x8000
+#define PRC_FACETESSDATA_NORMAL_Single 0x40000000
+#define PRC_FACETESSDATA_NORMAL_Mask 0x3FFFFFFF
+#define PRC_FACETESSDATA_WIRE_IsNotDrawn 0x4000 // Indicates that the edge should not be drawn (its neighbor will be drawn).
+#define PRC_FACETESSDATA_WIRE_IsClosing 0x8000 // Indicates that this is the last edge of a loop.
+
+#define PRC_3DWIRETESSDATA_IsClosing 0x10000000 // Indicates that the first point is implicitely repeated after the last one to close the wire edge.
+#define PRC_3DWIRETESSDATA_IsContinuous 0x20000000 // Indicates that the last point of the preceding wire should be linked with the first point of the current one.
+
+#define PRC_TEXTURE_MAPPING_DIFFUSE 0x0001 // Diffuse texture mapping attribute. Default value.
+#define PRC_TEXTURE_MAPPING_BUMP 0x0002 // Bump texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_OPACITY 0x0004 // Opacity texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_SPHERICAL_REFLECTION 0x0008 // Spherical reflection texture mapping attribute (used for environment mapping).
+#define PRC_TEXTURE_MAPPING_CUBICAL_REFLECTION 0x0010 // Cubical reflection texture mapping attribute (used for environment mapping).
+#define PRC_TEXTURE_MAPPING_REFRACTION 0x0020 // Refraction texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_SPECULAR 0x0040 // Specular texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_AMBIENT 0x0080 // Ambient texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_EMISSION 0x0100 // Emission texture mapping attribute.
+
+#define PRC_TEXTURE_APPLYING_MODE_NONE 0x00 // let the application choose
+#define PRC_TEXTURE_APPLYING_MODE_LIGHTING 0x01 // use lighting mode
+#define PRC_TEXTURE_APPLYING_MODE_ALPHATEST 0x02 // use alpha test
+#define PRC_TEXTURE_APPLYING_MODE_VERTEXCOLOR 0x04 // combine a texture with one-color-per-vertex mode
+
+#define PRC_TEXTURE_MAPPING_COMPONENTS_RED 0x0001 // Red texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_GREEN 0x0002 // Green texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_BLUE 0x0004 // Blue texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_RGB 0x0007 // RGB texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_ALPHA 0x0008 // Alpha texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_RGBA 0x000F // RGBA texture mapping component.
+
+enum EPRCModellerAttributeType {
+ KEPRCModellerAttributeTypeNull = 0,
+ KEPRCModellerAttributeTypeInt = 1,
+ KEPRCModellerAttributeTypeReal = 2,
+ KEPRCModellerAttributeTypeTime = 3,
+ KEPRCModellerAttributeTypeString = 4
+};
+
+enum EPRCPictureDataFormat {
+ KEPRCPicture_PNG,
+ KEPRCPicture_JPG,
+ KEPRCPicture_BITMAP_RGB_BYTE,
+ KEPRCPicture_BITMAP_RGBA_BYTE,
+ KEPRCPicture_BITMAP_GREY_BYTE,
+ KEPRCPicture_BITMAP_GREYA_BYTE
+};
+
+enum EPRCProductLoadStatus {
+ KEPRCProductLoadStatus_Unknown = 0,
+ KEPRCProductLoadStatus_Error,
+ KEPRCProductLoadStatus_NotLoaded,
+ KEPRCProductLoadStatus_NotLoadable,
+ KEPRCProductLoadStatus_Loaded
+};
+
+enum EPRCExtendType {
+ KEPRCExtendTypeNone = 0, // Discontinuous position.
+ KEPRCExtendTypeExt1 = 2, // Same as EPRCExtendTypeCInfinity.
+ KEPRCExtendTypeExt2 = 4, // Same as EPRCExtendTypeG1R for surface, and EPRCExtendTypeG1 for curve.
+ KEPRCExtendTypeG1 = 6, // Continuous in direction but not magnitude of first derivative.
+ KEPRCExtendTypeG1R = 8, // Surface extended with a ruled surface that connects with G1-continuity.
+ KEPRCExtendTypeG1_G2 = 10, // Extended by reflection, yielding a G2 continuous extension.
+ KEPRCExtendTypeCInfinity = 12 // Unlimited continuity.
+};
+
+enum EPRCKnotType { // Knot vector type
+ KEPRCKnotTypeUniformKnots, // Uniform knot vector.
+ KEPRCKnotTypeUnspecified, // Unspecified knot type.
+ KEPRCKnotTypeQuasiUniformKnots, // Quasi-uniform knot vector.
+ KEPRCKnotTypePiecewiseBezierKnots // Extrema with multiplicities of degree +1.
+}; // Note : this value is currently unused and should be set to KEPRCKnotTypeUnspecified.
+
+
+enum EPRCBSplineSurfaceForm {
+ KEPRCBSplineSurfaceFormPlane, // Planar surface.
+ KEPRCBSplineSurfaceFormCylindrical, // Cylindrical surface.
+ KEPRCBSplineSurfaceFormConical, // Conical surface.
+ KEPRCBSplineSurfaceFormSpherical, // Spherical surface.
+ KEPRCBSplineSurfaceFormRevolution, // Surface of revolution.
+ KEPRCBSplineSurfaceFormRuled, // Ruled surface.
+ KEPRCBSplineSurfaceFormGeneralizedCone, // Cone.
+ KEPRCBSplineSurfaceFormQuadric, // Quadric surface.
+ KEPRCBSplineSurfaceFormLinearExtrusion, // Surface of extrusion.
+ KEPRCBSplineSurfaceFormUnspecified, // Unspecified surface.
+ KEPRCBSplineSurfaceFormPolynomial // Polynomial surface.
+};
+
+enum EPRCBSplineCurveForm { // NURBS curve form
+ KEPRCBSplineCurveFormUnspecified, // Unspecified curve form.
+ KEPRCBSplineCurveFormPolyline, // Polygon.
+ KEPRCBSplineCurveFormCircularArc, // Circle arc.
+ KEPRCBSplineCurveFormEllipticArc, // Elliptical arc.
+ KEPRCBSplineCurveFormParabolicArc, // Parabolic arc.
+ KEPRCBSplineCurveFormHyperbolicArc // Hyperbolic arc.
+}; // Note : this value is currently unused and should be set to KEPRCBSplineCurveFormUnspecified.
+
+enum EPRCTextureMappingType { // Defines how to retrieve mapping coordinates.
+ KEPRCTextureMappingType_Unknown, // Let the application choose.
+ KEPRCTextureMappingType_Stored, // Use the mapping coordinates that are stored on a 3D tessellation object
+ KEPRCTextureMappingType_Parametric, // Retrieve the UV coordinates on the surface as mapping coordinates
+ KEPRCTextureMappingType_Operator // Use the defined Texture mapping operator to calculate mapping coordinates
+};
+
+enum EPRCTextureFunction { // Defines how to paint a texture on the surface being rendered.
+ KEPRCTextureFunction_Unknown, // Let the application choose.
+ KEPRCTextureFunction_Modulate, // Combine lighting with texturing. This is the default value.
+ KEPRCTextureFunction_Replace, // Replace the object color with texture color data.
+ KEPRCTextureFunction_Blend, // Reserved for future use.
+ KEPRCTextureFunction_Decal // Reserved for future use.
+};
+
+enum EPRCTextureMappingOperator { // The operator to use when computing mapping coordinates.
+ KEPRCTextureMappingOperator_Unknown, // Default value
+ KEPRCTextureMappingOperator_Planar, // Reserved for future use
+ KEPRCTextureMappingOperator_Cylindrical, // Reserved for future use
+ KEPRCTextureMappingOperator_Spherical, // Reserved for future use
+ KEPRCTextureMappingOperator_Cubical // Reserved for future use
+};
+
+enum EPRCTextureBlendParameter { // Reserved for future use. Defines how to apply blending.
+ KEPRCTextureBlendParameter_Unknown, // Default value.
+ KEPRCTextureBlendParameter_Zero, // Reserved for future use.
+ KEPRCTextureBlendParameter_One, // Reserved for future use.
+ KEPRCTextureBlendParameter_SrcColor, // Reserved for future use.
+ KEPRCTextureBlendParameter_OneMinusSrcColor, // Reserved for future use.
+ KEPRCTextureBlendParameter_DstColor, // Reserved for future use.
+ KEPRCTextureBlendParameter_OneMinusDstColor, // Reserved for future use.
+ KEPRCTextureBlendParameter_SrcAlpha, // Reserved for future use.
+ KEPRCTextureBlendParameter_OneMinusSrcAlpha, // Reserved for future use.
+ KEPRCTextureBlendParameter_DstAlpha, // Reserved for future use.
+ KEPRCTextureBlendParameter_OneMinusDstAlpha, // Reserved for future use.
+ KEPRCTextureBlendParameter_SrcAlphaSaturate // Reserved for future use.
+};
+
+enum EPRCTextureWrappingMode { // Defines repeating and clamping texture modes.
+ KEPRCTextureWrappingMode_Unknown, // Let the application choose.
+ KEPRCTextureWrappingMode_Repeat, // Display the repeated texture on the surface.
+ KEPRCTextureWrappingMode_ClampToBorder, // Clamp the texture to the border. Display the surface color along the texture limits.
+ KEPRCTextureWrappingMode_Clamp, // Reserved for future use.
+ KEPRCTextureWrappingMode_ClampToEdge, // Reserved for future use.
+ KEPRCTextureWrappingMode_MirroredRepeat // Reserved for future use.
+};
+
+enum EPRCTextureAlphaTest { // Reserved for future use. Defines how to use a texture alpha test.
+ KEPRCTextureAlphaTest_Unknown, // Default value.
+ KEPRCTextureAlphaTest_Never, // Reserved for future use.
+ KEPRCTextureAlphaTest_Less, // Reserved for future use.
+ KEPRCTextureAlphaTest_Equal, // Reserved for future use.
+ KEPRCTextureAlphaTest_Lequal, // Reserved for future use.
+ KEPRCTextureAlphaTest_Greater, // Reserved for future use.
+ KEPRCTextureAlphaTest_Notequal, // Reserved for future use.
+ KEPRCTextureAlphaTest_Gequal, // Reserved for future use.
+ KEPRCTextureAlphaTest_Always // Reserved for future use.
+};
+
+
+// Bit field for graphics behavior
+#define PRC_GRAPHICS_Show 0x0001 // The entity is shown.
+#define PRC_GRAPHICS_SonHeritShow 0x0002 // Shown entity son inheritance.
+#define PRC_GRAPHICS_FatherHeritShow 0x0004 // Shown entity father inheritance.
+#define PRC_GRAPHICS_SonHeritColor 0x0008 // Color/material son inheritance.
+#define PRC_GRAPHICS_FatherHeritColor 0x0010 // Color/material father inheritance.
+#define PRC_GRAPHICS_SonHeritLayer 0x0020 // Layer son inheritance.
+#define PRC_GRAPHICS_FatherHeritLayer 0x0040 // Layer father inheritance.
+#define PRC_GRAPHICS_SonHeritTransparency 0x0080 // Transparency son inheritance.
+#define PRC_GRAPHICS_FatherHeritTransparency 0x0100 // Transparency father inheritance.
+#define PRC_GRAPHICS_SonHeritLinePattern 0x0200 // Line pattern son inheritance.
+#define PRC_GRAPHICS_FatherHeritLinePattern 0x0400 // Line pattern father inheritance.
+#define PRC_GRAPHICS_SonHeritLineWidth 0x0800 // Line width son inheritance.
+#define PRC_GRAPHICS_FatherHeritLineWidth 0x1000 // Line width father inheritance.
+#define PRC_GRAPHICS_Removed 0x2000 // The entity has been removed and no longer appears in the tree.
+
+enum EPRCMarkupType {
+ KEPRCMarkupType_Unknown = 0,
+ KEPRCMarkupType_Text,
+ KEPRCMarkupType_Dimension,
+ KEPRCMarkupType_Arrow,
+ KEPRCMarkupType_Balloon,
+ KEPRCMarkupType_CircleCenter,
+ KEPRCMarkupType_Coordinate,
+ KEPRCMarkupType_Datum,
+ KEPRCMarkupType_Fastener,
+ KEPRCMarkupType_Gdt,
+ KEPRCMarkupType_Locator,
+ KEPRCMarkupType_MeasurementPoint,
+ KEPRCMarkupType_Roughness,
+ KEPRCMarkupType_Welding,
+ KEPRCMarkupType_Table,
+ KEPRCMarkupType_Other
+};
+
+enum EPRCMarkupSubType {
+ KEPRCMarkupSubType_Unknown = 0,
+ KEPRCMarkupSubType_EnumMax,
+
+ KEPRCMarkupSubType_Datum_Ident = 1 ,
+ KEPRCMarkupSubType_Datum_EnumMax,
+
+ KEPRCMarkupSubType_Dimension_Distance = 1,
+ KEPRCMarkupSubType_Dimension_Radius_Tangent,
+ KEPRCMarkupSubType_Dimension_Radius_Cylinder,
+ KEPRCMarkupSubType_Dimension_Radius_Edge,
+ KEPRCMarkupSubType_Dimension_Diameter,
+ KEPRCMarkupSubType_Dimension_Diameter_Tangent,
+ KEPRCMarkupSubType_Dimension_Diameter_Cylinder,
+ KEPRCMarkupSubType_Dimension_Diameter_Edge,
+ KEPRCMarkupSubType_Dimension_Diameter_Cone,
+ KEPRCMarkupSubType_Dimension_Length,
+ KEPRCMarkupSubType_Dimension_Length_Curvilinear,
+ KEPRCMarkupSubType_Dimension_Length_Circular,
+ KEPRCMarkupSubType_Dimension_Angle,
+ KEPRCMarkupSubType_Dimension_EnumMax,
+
+ KEPRCMarkupSubType_Gdt_Fcf = 1,
+ KEPRCMarkupSubType_Gdt_EnumMax,
+
+ KEPRCMarkupSubType_Welding_Line = 1,
+ KEPRCMarkupSubType_Welding_EnumMax,
+
+ KEPRCMarkupSubType_Other_Symbol_User = 1,
+ KEPRCMarkupSubType_Other_EnumMax
+};
+
+#define PRC_MARKUP_IsHidden 0x01 // The tessellation is hidden.
+#define PRC_MARKUP_HasFrame 0x02 // The tessellation has a frame.
+#define PRC_MARKUP_IsNotModifiable 0x04 // The tessellation is given and should not be modified.
+#define PRC_MARKUP_IsZoomable 0x08 // The tessellation has zoom capability.
+#define PRC_MARKUP_IsOnTop 0x10 // The tessellation is on top of the geometry.
+#define PRC_MARKUP_IsFlipable 0x20 // The text tessellation can be flipped to always be readable on screen. This value is currently unused.
+
+#define PRC_RENDERING_PARAMETER_SPECIAL_CULLING 0x0001 // special culling strategy to apply
+#define PRC_RENDERING_PARAMETER_FRONT_CULLING 0x0002 // apply front culling (ignored if no special culling strategy)
+#define PRC_RENDERING_PARAMETER_BACK_CULLING 0x0004 // apply back culling (ignored if no special culling strategy)
+#define PRC_RENDERING_PARAMETER_NO_LIGHT 0x0008 // if set, no light will apply on corresponding object
+
+#define PRC_MARKUP_IsMatrix 0x08000000 // Bit to denote that the current entity is a matrix.
+#define PRC_MARKUP_IsExtraData 0x04000000 // Bit to denote that the current entity is extra data (it is neither a matrix nor a polyline).
+#define PRC_MARKUP_IntegerMask 0xFFFFF // Integer mask to retrieve sizes.
+#define PRC_MARKUP_ExtraDataType 0x3E00000 // Mask to retrieve the integer type of the entity.
+
+#define PRC_MARKUP_ExtraDataType_Pattern (( 0<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Picture (( 1<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Triangles (( 2<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Quads (( 3<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_FaceViewMode (( 6<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_FrameDrawMode (( 7<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_FixedSizeMode (( 8<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Symbol (( 9<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Cylinder ((10<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Color ((11<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_LineStipple ((12<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Font ((13<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Text ((14<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Points ((15<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Polygon ((16<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_LineWidth ((17<<21)|PRC_MARKUP_IsExtraData)
+
+enum EPRCCharSet
+{
+ KEPRCCharsetUnknown = -1,
+ KEPRCCharsetRoman = 0,
+ KEPRCCharsetJapanese,
+ KEPRCCharsetTraditionalChinese,
+ KEPRCCharsetKorean,
+ KEPRCCharsetArabic,
+ KEPRCCharsetHebrew,
+ KEPRCCharsetGreek,
+ KEPRCCharsetCyrillic,
+ KEPRCCharsetRightLeft,
+ KEPRCCharsetDevanagari,
+ KEPRCCharsetGurmukhi,
+ KEPRCCharsetGujarati,
+ KEPRCCharsetOriya,
+ KEPRCCharsetBengali,
+ KEPRCCharsetTamil,
+ KEPRCCharsetTelugu,
+ KEPRCCharsetKannada,
+ KEPRCCharsetMalayalam,
+ KEPRCCharsetSinhalese,
+ KEPRCCharsetBurmese,
+ KEPRCCharsetKhmer,
+ KEPRCCharsetThai,
+ KEPRCCharsetLaotian,
+ KEPRCCharsetGeorgian,
+ KEPRCCharsetArmenian,
+ KEPRCCharsetSimplifiedChinese,
+ KEPRCCharsetTibetan,
+ KEPRCCharsetMongolian,
+ KEPRCCharsetGeez,
+ KEPRCCharsetEastEuropeanRoman,
+ KEPRCCharsetVietnamese,
+ KEPRCCharsetExtendedArabic
+};
+
+#define PRC_Font_Bold 0x02 /*!< Bold. */
+#define PRC_Font_Italic 0x04 /*!< Italic. */
+#define PRC_Font_Underlined 0x08 /*!< Underlined. */
+#define PRC_Font_StrikedOut 0x10 /*!< Striked-out. */
+#define PRC_Font_Overlined 0x20 /*!< Overlined. */
+#define PRC_Font_Streched 0x40 /*!< Streched. In case the font used is not the original font, it indicates that the text needs to be stretched to fit its bounding box. */
+#define PRC_Font_Wired 0x80 /*!< Wired. Indicates that the original font is a wirefame font. */
+#define PRC_Font_FixedWidth 0x100 /*!< Fixed width. Indicates that the original font is not proportional (each glyph has the same width). */
+
+#define PRC_CONTEXT_OuterLoopFirst 0x0001 // Outer loops are always first loops (specific to PRC_TYPE_TOPO_BrepData).
+#define PRC_CONTEXT_NoClamp 0x0002 // UV curves are clamped on the surface (specific to PRC_TYPE_TOPO_BrepData).
+#define PRC_CONTEXT_NoSplit 0x0004 // Faces are split (specific to PRC_TYPE_TOPO_BrepData).
+
+#define PRC_BODY_BBOX_Evaluation 0x0001 // Bounding box based on geometry.
+#define PRC_BODY_BBOX_Precise 0x0002 // Bounding box based on tessellation.
+#define PRC_BODY_BBOX_CADData 0x0003 // Bounding box given by a CAD data file.
+
+#endif // __PRC_H
diff --git a/graphics/asymptote/prc/PRCTools/Makefile b/graphics/asymptote/prc/PRCTools/Makefile
new file mode 100644
index 0000000000..51186e7e76
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/Makefile
@@ -0,0 +1,48 @@
+CFLAGS = -O3 -Wall
+CXX = g++
+
+makePRC: PRCbitStream oPRCFile PRCdouble writePRC makePRC.cc
+ $(CXX) $(CFLAGS) -o makePRC PRCbitStream.o oPRCFile.o PRCdouble.o writePRC.o makePRC.cc -lz
+
+describePRC: bitData inflation PRCdouble iPRCFile describePRC.cc describeMain.cc
+ $(CXX) $(CFLAGS) -o describePRC bitData.o inflation.o PRCdouble.o iPRCFile.o describePRC.cc describeMain.cc -lz
+
+bitSearchUI: bitSearchUI.cc bitData PRCdouble
+ $(CXX) $(CFLAGS) -o bitSearchUI bitData.o PRCdouble.o bitSearchUI.cc
+
+bitSearchDouble: bitSearchDouble.cc bitData PRCdouble
+ $(CXX) $(CFLAGS) -o bitSearchDouble bitData.o PRCdouble.o bitSearchDouble.cc
+
+extractSections: extractSections.cc iPRCFile inflation bitData PRCdouble
+ $(CXX) $(CFLAGS) -o extractSections iPRCFile.o inflation.o bitData.o PRCdouble.o describePRC.cc extractSections.cc -lz
+
+inflateTest: inflation inflationMain.cc
+ $(CXX) $(CFLAGS) -o inflateTest inflation.o inflationMain.cc -lz
+
+PRCdouble: ../PRCdouble.cc
+ $(CXX) $(CFLAGS) -c ../PRCdouble.cc -o PRCdouble.o
+
+PRCbitStream: ../PRCbitStream.cc
+ $(CXX) $(CFLAGS) -c ../PRCbitStream.cc -o PRCbitStream.o
+
+oPRCFile: ../oPRCFile.cc
+ $(CXX) $(CFLAGS) -c ../oPRCFile.cc -o oPRCFile.o
+
+writePRC: ../writePRC.cc PRCbitStream
+ $(CXX) $(CFLAGS) -c ../writePRC.cc -o writePRC.o
+
+bitData: bitData.cc
+ $(CXX) $(CFLAGS) -c bitData.cc -o bitData.o
+
+inflation: inflation.cc
+ $(CXX) $(CFLAGS) -c inflation.cc -o inflation.o
+
+iPRCFile: iPRCFile.cc
+ $(CXX) $(CFLAGS) -c iPRCFile.cc -o iPRCFile.o
+
+all: makePRC describePRC bitSearchUI bitSearchDouble extractSections inflateTest
+
+tools: all
+
+clean:
+ rm -f *.o describePRC bitSearchUI bitSearchDouble extractSections inflateTest
diff --git a/graphics/asymptote/prc/PRCTools/bitData.cc b/graphics/asymptote/prc/PRCTools/bitData.cc
new file mode 100644
index 0000000000..9fba0eb0b1
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/bitData.cc
@@ -0,0 +1,258 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "../PRC.h"
+#include "../PRCdouble.h"
+#include "bitData.h"
+
+using std::cout; using std::endl; using std::hex; using std::cerr;
+
+BitPosition BitByBitData::getPosition()
+{
+ BitPosition bp;
+ bp.byteIndex = data - start;
+ bp.bitIndex = 0;
+ for(unsigned char temp = bitMask<<1; temp != 0; temp <<= 1)
+ bp.bitIndex++;
+ return bp;
+}
+
+void BitByBitData::setPosition(const BitPosition& bp)
+{
+ if(bp.byteIndex < length)
+ {
+ data = start + bp.byteIndex;
+ bitMask = 0x80 >> bp.bitIndex;
+ // big-endian, zero based bit index (from 0 to 7)
+ // so 0x80 => bit 0, 0x01 => bit 7
+ // Why? It is easy to see in a hex editor.
+ failed = false;
+ }
+ else
+ {
+ failed = true;
+ }
+}
+
+void BitByBitData::setPosition(unsigned int byte, unsigned int bit)
+{
+ if(byte <= length)
+ {
+ data = start + byte;
+ bitMask = 0x80 >> bit;
+ // big-endian, zero based bit index (from 0 to 7)
+ // so 0x80 => bit 0, 0x01 => bit 7
+ // Why? It is easy to see in a hex editor.
+ failed = false;
+ }
+ else
+ {
+ failed = true;
+ }
+}
+
+void BitByBitData::setShowBits(bool val)
+{
+ showBits = val;
+}
+
+void BitByBitData::tellPosition()
+{
+ BitPosition bp = getPosition();
+ cout << bp.byteIndex << ':' << bp.bitIndex << endl;
+}
+
+bool BitByBitData::readBit()
+{
+ if(!failed)
+ {
+ bool val = *data & bitMask;
+ if(showBits) cout << (val?'1':'0');
+ nextBit();
+ return val;
+ }
+ else
+ return false;
+}
+
+unsigned char BitByBitData::readChar()
+{
+ unsigned char dat = 0;
+ dat |= readBit();
+ for(int a = 0; a < 7; ++a)
+ {
+ dat <<= 1;
+ dat |= readBit();
+ }
+ return dat;
+}
+
+unsigned int BitByBitData::readUnsignedInt()
+{
+ unsigned int result = 0;
+ unsigned int count = 0;
+ while(readBit())
+ {
+ result |= (static_cast<unsigned int>(readChar()) << 8*count++);
+ }
+ if(showBits) cout << " " << result << endl;
+ return result;
+}
+
+std::string BitByBitData::readString()
+{
+ bool isNotNull = readBit();
+ std::string result;
+ if(isNotNull)
+ {
+ unsigned int stringLength = readUnsignedInt();
+ char *buf = new char[stringLength+1];
+ buf[stringLength] = '\0';
+ for(unsigned int a = 0; a < stringLength; ++a)
+ {
+ buf[a] = readChar();
+ }
+ result = buf;
+ delete[] buf;
+ }
+ if(showBits) cout << " " << result << endl;
+ return result;
+}
+
+int BitByBitData::readInt()
+{
+ int result = 0;
+ unsigned int count = 0;
+ while(readBit())
+ {
+ result |= (static_cast<unsigned int>(readChar()) << 8*count++);
+ }
+ result <<= (4-count)*8;
+ result >>= (4-count)*8;
+ if(showBits) cout << " " << result << endl;
+ return result;
+}
+
+
+// Thanks to Michail Vidiassov
+double BitByBitData::readDouble()
+{
+ ieee754_double value;
+ value.d = 0;
+ sCodageOfFrequentDoubleOrExponent *pcofdoe;
+ unsigned int ucofdoe = 0;
+ for(int i = 1; i <= 22; ++i)
+ {
+ ucofdoe <<= 1;
+ ucofdoe |= readBit();
+ if((pcofdoe = getcofdoe(ucofdoe,i)) != NULL)
+ break;
+ }
+ value.d = pcofdoe->u2uod.Value;
+
+ // check if zero
+ if(pcofdoe->NumberOfBits==2 && pcofdoe->Bits==1 && pcofdoe->Type==VT_double)
+ return value.d;
+
+ value.ieee.negative = readBit(); // get sign
+
+ if(pcofdoe->Type == VT_double) // double from list
+ return value.d;
+
+ if(readBit()==0) // no mantissa
+ return value.d;
+
+ // read the mantissa
+ // read uppermost 4 bits of mantissa
+ unsigned char b4 = 0;
+ for(int i = 0; i < 4; ++i)
+ {
+ b4 <<= 1;
+ b4 |= readBit();
+ }
+
+#ifdef WORDS_BIGENDIAN
+ *(reinterpret_cast<unsigned char*>(&value)+1) |= b4;
+ unsigned char *lastByte = reinterpret_cast<unsigned char*>(&value)+7;
+ unsigned char *currentByte = reinterpret_cast<unsigned char*>(&value)+2;
+#else
+ *(reinterpret_cast<unsigned char*>(&value)+6) |= b4;
+ unsigned char *lastByte = reinterpret_cast<unsigned char*>(&value)+0;
+ unsigned char *currentByte = reinterpret_cast<unsigned char*>(&value)+5;
+#endif
+
+ for(;MOREBYTE(currentByte,lastByte); NEXTBYTE(currentByte))
+ {
+ if(readBit())
+ {
+ // new byte
+ *currentByte = readChar();
+ }
+ else
+ {
+ // get 3 bit offset
+ unsigned int offset = 0;
+ offset |= (readBit() << 2);
+ offset |= (readBit() << 1);
+ offset |= readBit();
+ if(offset == 0)
+ {
+ // fill remaining bytes in mantissa with previous byte
+ unsigned char pByte = BYTEAT(currentByte,1);
+ for(;MOREBYTE(currentByte,lastByte); NEXTBYTE(currentByte))
+ *currentByte = pByte;
+ break;
+ }
+ else if(offset == 6)
+ {
+ // fill remaining bytes except last byte with previous byte
+ unsigned char pByte = BYTEAT(currentByte,1);
+ PREVIOUSBYTE(lastByte);
+ for(;MOREBYTE(currentByte,lastByte); NEXTBYTE(currentByte))
+ *currentByte = pByte;
+ *currentByte = readChar();
+ break;
+ }
+ else
+ {
+ // one repeated byte
+ *currentByte = BYTEAT(currentByte,offset);
+ }
+ }
+ }
+ if(showBits) cout << " " << value.d << endl;
+ return value.d;
+}
+
+void BitByBitData::nextBit()
+{
+ bitMask >>= 1;
+ if(bitMask == 0)
+ {
+ if(data < start+length)
+ data++;
+ else
+ {
+ failed = true;
+ cout << "End of data."<< endl;
+ }
+ bitMask = 0x80;
+ }
+}
diff --git a/graphics/asymptote/prc/PRCTools/bitData.h b/graphics/asymptote/prc/PRCTools/bitData.h
new file mode 100644
index 0000000000..44a4fbe816
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/bitData.h
@@ -0,0 +1,62 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __BITDATA_H
+#define __BITDATA_H
+
+#include <iostream>
+#include <string>
+
+struct BitPosition
+{
+ unsigned int byteIndex;
+ unsigned int bitIndex;
+};
+
+class BitByBitData
+{
+ public:
+ BitByBitData(char* s,unsigned int l) : start(s),data(s),length(l),
+ bitMask(0x80),showBits(false),failed(false) {}
+
+ void tellPosition();
+ BitPosition getPosition();
+ void setPosition(const BitPosition&);
+ void setPosition(unsigned int,unsigned int);
+ void setShowBits(bool);
+ bool readBit();
+ unsigned char readChar();
+
+ unsigned int readUnsignedInt();
+ std::string readString();
+ int readInt();
+ double readDouble();
+
+ private:
+ char *start; // first byte so we know where we are
+ char *data; // last byte read
+ unsigned int length;
+ unsigned char bitMask; // mask to read next bit of current byte
+ bool showBits; // show each bit read?
+ bool failed;
+ void nextBit(); // shift bit mask and get next byte if needed
+};
+
+#endif // __BITDATA_H
diff --git a/graphics/asymptote/prc/PRCTools/bitSearchDouble.cc b/graphics/asymptote/prc/PRCTools/bitSearchDouble.cc
new file mode 100644
index 0000000000..5fd70cb9aa
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/bitSearchDouble.cc
@@ -0,0 +1,67 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include "bitData.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+ inFile.seekg(0,ios::end);
+ unsigned int length = inFile.tellg();
+ inFile.seekg(0,ios::beg);
+
+ char *buf = new char[length];
+
+ inFile.read(buf,length);
+ BitByBitData bbbd(buf,length);
+
+ double dsf;
+ cout << "double to search for: "; cin >> dsf;
+ BitPosition currP;
+ for(currP.byteIndex = 0; currP.byteIndex < length; ++currP.byteIndex)
+ for(currP.bitIndex = 0; currP.bitIndex < 8; ++currP.bitIndex)
+ {
+ bbbd.setPosition(currP);
+ if(bbbd.readDouble() == dsf)
+ {
+ BitPosition bp = bbbd.getPosition();
+ cout << "Found " << dsf << " at " << currP.byteIndex << ':'
+ << currP.bitIndex << " to " << bp.byteIndex << ':' << bp.bitIndex
+ << endl;
+ }
+ }
+ delete[] buf;
+ return 0;
+}
diff --git a/graphics/asymptote/prc/PRCTools/bitSearchUI.cc b/graphics/asymptote/prc/PRCTools/bitSearchUI.cc
new file mode 100644
index 0000000000..034143a1ae
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/bitSearchUI.cc
@@ -0,0 +1,65 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include "bitData.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+ inFile.seekg(0,ios::end);
+ unsigned int length = inFile.tellg();
+ inFile.seekg(0,ios::beg);
+
+ char *buf = new char[length];
+
+ inFile.read(buf,length);
+ BitByBitData bbbd(buf,length);
+
+ unsigned int uisf;
+ cout << "Unsigned int to search for: "; cin >> uisf;
+ BitPosition currP;
+ for(currP.byteIndex = 0; currP.byteIndex < length; ++currP.byteIndex)
+ for(currP.bitIndex = 0; currP.bitIndex < 8; ++currP.bitIndex)
+ {
+ bbbd.setPosition(currP);
+ if(bbbd.readUnsignedInt() == uisf)
+ {
+ cout << "Found " << uisf << " at " << currP.byteIndex << ':'
+ << currP.bitIndex << endl;
+ }
+ }
+ delete[] buf;
+ return 0;
+}
diff --git a/graphics/asymptote/prc/PRCTools/describeMain.cc b/graphics/asymptote/prc/PRCTools/describeMain.cc
new file mode 100644
index 0000000000..329e26fe40
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/describeMain.cc
@@ -0,0 +1,45 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include "iPRCFile.h"
+
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+
+ iPRCFile myFile(inFile);
+ myFile.describe();
+
+ return 0;
+}
diff --git a/graphics/asymptote/prc/PRCTools/describePRC.cc b/graphics/asymptote/prc/PRCTools/describePRC.cc
new file mode 100644
index 0000000000..1efedecb72
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/describePRC.cc
@@ -0,0 +1,2272 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+
+#include "../PRC.h"
+#include "describePRC.h"
+
+using std::ostringstream; using std::cout; using std::endl;
+using std::hex; using std::dec; using std::string; using std::setw;
+using std::setfill;
+
+// describe sections
+
+void describeGlobals(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Globals--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureGlobals))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+ unsigned int numberOfReferencedFileStructures = mData.readUnsignedInt();
+ cout << getIndent() << "numberOfReferencedFileStructures "
+ << numberOfReferencedFileStructures << endl;
+ indent();
+ for(unsigned int i = 0; i < numberOfReferencedFileStructures; ++i)
+ {
+ describeCompressedUniqueID(mData);
+ }
+ dedent();
+
+ double tessellation_chord_height_ratio = mData.readDouble();
+ cout << getIndent() << "tessellation_chord_height_ratio "
+ << tessellation_chord_height_ratio << endl;
+
+ double tessellation_angle_degree = mData.readDouble();
+ cout << getIndent() << "tessellation_angle_degree "
+ << tessellation_angle_degree << endl;
+
+ string default_font_family_name = mData.readString();
+ cout << getIndent() << "default_font_family_name \""
+ << default_font_family_name << '\"' << endl;
+
+ unsigned int number_of_fonts = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_fonts " << number_of_fonts << endl;
+
+ indent();
+ for(unsigned int q = 0; q < number_of_fonts; ++q)
+ {
+ string font_name = mData.readString();
+ cout << getIndent() << "font_name \"" << font_name << '\"' << endl;
+ unsigned int char_set = mData.readUnsignedInt();
+ cout << getIndent() << "char_set " << char_set << endl;
+ unsigned int number_of_font_keys = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_font_keys " << number_of_font_keys
+ << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_font_keys; i++)
+ {
+ unsigned int font_size = mData.readUnsignedInt() - 1;
+ cout << getIndent() << "font_size " << font_size << endl;
+ unsigned char attributes = mData.readChar();
+ cout << getIndent() << "attributes "
+ << static_cast<unsigned int>(attributes) << endl;
+ }
+ dedent();
+ }
+ dedent();
+
+ unsigned int number_of_colours = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_colours " << number_of_colours << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_colours; ++i)
+ describeRGBColour(mData);
+ dedent();
+
+ unsigned int number_of_pictures = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_pictures " << number_of_pictures << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_pictures;i++)
+ describePicture(mData);
+ dedent();
+
+ unsigned int number_of_texture_definitions = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_texture_definitions "
+ << number_of_texture_definitions << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_texture_definitions;i++)
+ describeTextureDefinition(mData);
+ dedent();
+
+
+ unsigned int number_of_materials = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_materials " << number_of_materials << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_materials;i++)
+ describeMaterial(mData);
+ dedent();
+
+ unsigned int number_of_line_patterns = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_line_patterns "
+ << number_of_line_patterns << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_line_patterns;i++)
+ describeLinePattern(mData);
+ dedent();
+
+ unsigned int number_of_styles = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_styles " << number_of_styles << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_styles;i++)
+ describeCategory1LineStyle(mData);
+ dedent();
+
+ unsigned int number_of_fill_patterns = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_fill_patterns "
+ << number_of_fill_patterns << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_fill_patterns;i++)
+ describeFillPattern(mData);
+ dedent();
+
+ unsigned int number_of_reference_coordinate_systems = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_reference_coordinate_systems "
+ << number_of_reference_coordinate_systems << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_reference_coordinate_systems;i++)
+ //NOTE: must be PRC_TYPE_RI_CoordinateSystem
+ describeRepresentationItem(mData);
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+void describeTree(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Tree--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureTree))
+ return;
+ indent();
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_part_definitions = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_part_definitions "
+ << number_of_part_definitions << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_part_definitions; ++i)
+ {
+ describePartDefinition(mData);
+ }
+ dedent();
+
+ unsigned int number_of_product_occurrences = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_product_occurrences "
+ << number_of_product_occurrences << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_product_occurrences; ++i)
+ {
+ describeProductOccurrence(mData);
+ }
+ dedent();
+
+ describeFileStructureInternalData(mData);
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+void describeTessellation(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Tessellation--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureTessellation))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_tessellations = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_tessellations "
+ << number_of_tessellations << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_tessellations; ++i)
+ {
+ unsigned int type = mData.readUnsignedInt();
+ cout << getIndent() << "tessellation type " << type << endl;
+ switch(type)
+ {
+ case PRC_TYPE_TESS_3D:
+ describe3DTess(mData);
+ break;
+ case PRC_TYPE_TESS_3D_Wire:
+ describe3DWireTess(mData);
+ break;
+ case PRC_TYPE_TESS_Markup:
+ describe3DMarkupTess(mData);
+ break;
+ case PRC_TYPE_TESS_3D_Compressed:
+ describeHighlyCompressed3DTess(mData);
+ break;
+ default:
+ cout << getIndent() << "Unrecognized tessellation data type "
+ << type << endl;
+ break;
+ }
+ }
+ dedent();
+
+ describeUserData(mData);
+
+ dedent();
+ mData.tellPosition();
+}
+
+void describeGeometry(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Geometry--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureGeometry))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_topological_contexts = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_topological_contexts "
+ << number_of_topological_contexts << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_topological_contexts; ++i)
+ {
+ describeTopoContext(mData);
+ unsigned int number_of_bodies = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_bodies " << number_of_bodies << endl;
+ for(unsigned int i = 0; i < number_of_bodies; ++i)
+ {
+ describeBody(mData);
+ }
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+void describeExtraGeometry(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Extra Geometry--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureExtraGeometry))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_contexts = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_contexts " << number_of_contexts << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_contexts; ++i)
+ {
+ // geometry summary
+ unsigned int number_of_bodies = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_bodies " << number_of_bodies << endl;
+ indent();
+ for(unsigned int j = 0; j < number_of_bodies; ++j)
+ {
+ unsigned int serial_type = mData.readUnsignedInt();
+ cout << getIndent() << "serial_type " << serial_type << endl;
+ indent();
+ if(isCompressedSerialType(serial_type))
+ cout << getIndent() << "serialTolerance " << mData.readDouble();
+ dedent();
+ }
+ dedent();
+ // context graphics
+ resetCurrentGraphics();
+ unsigned int number_of_treat_types = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_treat_types "
+ << number_of_treat_types << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_treat_types; ++i)
+ {
+ cout << getIndent() << "element_type " << mData.readUnsignedInt() << endl;
+ unsigned int number_of_elements = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_elements "
+ << number_of_elements << endl;
+ indent();
+ for(unsigned int j = 0; j < number_of_elements; ++j)
+ {
+ if(mData.readBit())
+ {
+ describeGraphics(mData);
+ }
+ else
+ {
+ cout << getIndent() << "Element has no graphics" << endl;
+ }
+ }
+ dedent();
+ }
+ dedent();
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+
+void describeModelFileData(BitByBitData &mData,
+ unsigned int numberOfFileStructures)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Model File--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_ModelFile))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ describeUnit(mData);
+ unsigned int numberOfProductOccurrences = mData.readUnsignedInt();
+ cout << getIndent() << "Number of Product Occurrences "
+ << numberOfProductOccurrences << endl;
+ indent();
+ for(unsigned int i = 0; i < numberOfProductOccurrences; ++i)
+ {
+ describeCompressedUniqueID(mData);
+ cout << getIndent() << "index_position + 1 = "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "active? " << (mData.readBit()?"yes":"no")
+ << endl << endl;
+ }
+ dedent();
+ for(unsigned int i = 0; i < numberOfFileStructures; ++i)
+ {
+ cout << getIndent() << "File Structure Index in Model File "
+ << mData.readUnsignedInt() << endl;
+ }
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+// subsections
+// void describe(BitByBitData &mData)
+// {
+//
+// }
+
+void describeLight(BitByBitData &mData)
+{
+ unsigned int ID = mData.readUnsignedInt();
+ if(ID == PRC_TYPE_GRAPH_AmbientLight)
+ cout << getIndent() << "--Ambient Light--" << endl;
+ else
+ return;
+
+ indent();
+
+ describeContentPRCBase(mData,true);
+
+ cout << getIndent() << "ambient colour index: " << mData.readUnsignedInt()-1 << endl
+ << getIndent() << "diffuse colour index: " << mData.readUnsignedInt()-1 << endl
+ << getIndent() << "specular colour index: " << mData.readUnsignedInt()-1 << endl;
+
+ describeUserData(mData);
+ describeUserData(mData); // why?
+ dedent();
+}
+
+void describeCamera(BitByBitData &mData)
+{
+ cout << getIndent() << "--Camera--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_Camera))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,true);
+
+ cout << getIndent() << (mData.readBit()?"orthographic":"perspective") << endl;
+ cout << getIndent() << "Camera Position" << endl;
+ describeVector3d(mData);
+ cout << getIndent() << "Look At Point" << endl;
+ describeVector3d(mData);
+ cout << getIndent() << "Up" << endl;
+ describeVector3d(mData);
+ cout << getIndent() << "X field of view angle (perspective) || X scale (orthographic) "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "Y field of view angle (perspective) || Y scale (orthographic) "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "aspect ratio x/y " << mData.readDouble() << endl;
+ cout << getIndent() << "near z clipping plane distance from viewer " << mData.readDouble() << endl;
+ cout << getIndent() << "far z clipping plane distance from viewer " << mData.readDouble() << endl;
+ cout << getIndent() << "zoom factor " << mData.readDouble() << endl;
+ dedent();
+}
+
+bool describeContentCurve(BitByBitData &mData)
+{
+ describeBaseGeometry(mData);
+ cout << getIndent() << "extend_info " << mData.readUnsignedInt() << endl;
+ bool is_3d = mData.readBit();
+ cout << getIndent() << "is_3d " << (is_3d?"yes":"no") << endl;
+ return is_3d;
+}
+
+void describeParameterization(BitByBitData &mData)
+{
+ cout << getIndent() << "--Parameterization--" << endl;
+ indent();
+ describeExtent1d(mData);
+ cout << getIndent() << "parameterization_coeff_a " << mData.readDouble()
+ << endl;
+ cout << getIndent() << "parameterization_coeff_b " << mData.readDouble()
+ << endl;
+ dedent();
+}
+
+void describeCurvCircle(BitByBitData &mData)
+{
+ cout << getIndent() << "--Circle--" << endl;
+ indent();
+
+ if(describeContentCurve(mData))
+ describeTransformation3d(mData);
+ else
+ describeTransformation2d(mData);
+
+ describeParameterization(mData);
+
+ cout << getIndent() << "radius " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeCurvLine(BitByBitData &mData)
+{
+ cout << getIndent() << "--Line--" << endl;
+ indent();
+
+ if(describeContentCurve(mData))
+ describeTransformation3d(mData);
+ else
+ describeTransformation2d(mData);
+
+ describeParameterization(mData);
+
+ dedent();
+}
+
+void describeContentWireEdge(BitByBitData &mData)
+{
+ cout << getIndent() << "--WireEdge--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ describeObject(mData); //3d_curve
+
+ bool curve_trim_interval = mData.readBit();
+ cout << getIndent() << "curve_trim_interval "
+ << (curve_trim_interval?"yes":"no") << endl;
+ if(curve_trim_interval)
+ {
+ describeExtent1d(mData);
+ }
+
+ dedent();
+}
+
+void describeUVParametrization(BitByBitData &mData)
+{
+ cout << getIndent() << "--UV Parameterization--" << endl;
+ indent();
+
+ cout << getIndent() << "swap_uv " << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "Domain" << endl;
+ indent(); describeExtent2d(mData); dedent();
+ cout << getIndent() << "parameterization_on_u_coeff_a "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "parameterization_on_v_coeff_a "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "parameterization_on_u_coeff_b "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "parameterization_on_v_coeff_b "
+ << mData.readDouble() << endl;
+
+ dedent();
+}
+
+bool isCompressedSerialType(unsigned int type)
+{
+ return false; // TODO: actually check the type!!!
+}
+
+void describeSurfNURBS(BitByBitData &mData)
+{
+ cout << getIndent() << "--NURBS surface--" << endl;
+ indent();
+
+ describeContentSurface(mData);
+
+ bool is_rational = mData.readBit();
+ cout << getIndent() << "is_rational " << (is_rational?"yes":"no") << endl;
+
+ unsigned int degree_in_u = mData.readUnsignedInt();
+ cout << getIndent() << "degree_in_u " << degree_in_u << endl;
+ unsigned int degree_in_v = mData.readUnsignedInt();
+ cout << getIndent() << "degree_in_v " << degree_in_v << endl;
+
+ unsigned int number_of_control_points_in_u = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_control_points_in_u "
+ << number_of_control_points_in_u << endl;
+ unsigned int number_of_control_points_in_v = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_control_points_in_v "
+ << number_of_control_points_in_v << endl;
+
+ unsigned int number_of_knots_in_u = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_knots_in_u "
+ << number_of_knots_in_u << endl;
+ unsigned int number_of_knots_in_v = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_knots_in_v "
+ << number_of_knots_in_v << endl;
+
+ indent();
+ for(unsigned int i = 0; i < number_of_control_points_in_u; ++i)
+ {
+ for(unsigned int j = 0; j < number_of_control_points_in_v; ++j)
+ {
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ double z = mData.readDouble();
+ cout << getIndent() << "control point " << i << ' ' << j << ": ("
+ << x << ',' << y << ',' << z;
+
+ if(is_rational)
+ cout << ',' << mData.readDouble();
+
+ cout << ')' << endl;
+ }
+ }
+ dedent();
+
+ cout << getIndent() << "knots in u" << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_knots_in_u; ++i)
+ cout << getIndent() << mData.readDouble() << endl;
+ dedent();
+
+ cout << getIndent() << "knots in v" << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_knots_in_v; ++i)
+ cout << getIndent() << mData.readDouble() << endl;
+ dedent();
+
+ cout << getIndent() << "knot_type " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "surface_form " << mData.readUnsignedInt() << endl;
+
+ dedent();
+}
+
+void describeCurvNURBS(BitByBitData &mData)
+{
+ cout << getIndent() << "--NURBS curve--" << endl;
+ indent();
+ describeContentCurve(mData);
+
+ bool is_rational = mData.readBit();
+ cout << getIndent() << "is_rational " << (is_rational?"yes":"no") << endl;
+
+ unsigned int degree = mData.readUnsignedInt();
+ cout << getIndent() << "degree " << degree << endl;
+
+ unsigned int number_of_control_points = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_control_points "
+ << number_of_control_points << endl;
+
+ unsigned int number_of_knots = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_knots " << number_of_knots << endl;
+
+ indent();
+ for(unsigned int i = 0; i < number_of_control_points; ++i)
+ {
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ double z = mData.readDouble();
+ cout << getIndent() << "control point " << i << ": ("
+ << x << ',' << y << ',' << z;
+
+ if(is_rational)
+ cout << ',' << mData.readDouble();
+
+ cout << ')' << endl;
+ }
+ dedent();
+
+ cout << getIndent() << "knots" << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_knots; ++i)
+ cout << getIndent() << mData.readDouble() << endl;
+ dedent();
+
+ cout << getIndent() << "knot_type " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "surface_form " << mData.readUnsignedInt() << endl;
+
+ dedent();
+}
+
+void describeCurvPolyLine(BitByBitData &mData)
+{
+ cout << getIndent() << "--PolyLine--" << endl;
+ indent();
+ describeContentCurve(mData);
+ describeTransformation3d(mData);
+ describeParameterization(mData);
+
+ unsigned int number_of_points = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_points " << number_of_points << endl;
+
+ indent();
+ for(unsigned int i = 0; i < number_of_points; ++i)
+ {
+ describeVector3d(mData);
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeSurfCylinder(BitByBitData &mData)
+{
+ cout << getIndent() << "--Cylinder surface--" << endl;
+ indent();
+
+ describeContentSurface(mData);
+ describeTransformation3d(mData);
+ describeUVParametrization(mData);
+ cout << getIndent() << "radius " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeSurfPlane(BitByBitData &mData)
+{
+ cout << getIndent() << "--Plane surface--" << endl;
+ indent();
+ mData.setShowBits(true);
+ describeContentSurface(mData);
+ mData.tellPosition();
+ //TODO: something is wrong, very wrong!!!
+ // For now, all this does is search until the end of the data block,
+ // assuming that the default parameterization [-inf,inf]x[-inf,inf] was used
+ BitPosition bp = mData.getPosition();
+ double nInf1 = mData.readDouble();
+ double nInf2 = mData.readDouble();
+ double inf1 = mData.readDouble();
+ double inf2 = mData.readDouble();
+ double one1 = mData.readDouble();
+ double one2 = mData.readDouble();
+ double zero1 = mData.readDouble();
+ double zero2 = mData.readDouble();
+ while(!(nInf1 == -12345.0 && nInf2 == -12345.0 && inf1 == 12345.0
+ && inf2 == 12345.0 && one1 == 1.0 && one2 == 1.0 && zero1 == 0.0
+ && zero2 == 0.0))
+ {
+ mData.setPosition(bp);
+ cout << mData.readBit();
+ bp = mData.getPosition();
+
+ nInf1 = mData.readDouble();
+ nInf2 = mData.readDouble();
+ inf1 = mData.readDouble();
+ inf2 = mData.readDouble();
+ one1 = mData.readDouble();
+ one2 = mData.readDouble();
+ zero1 = mData.readDouble();
+ zero2 = mData.readDouble();
+ }
+ cout << endl;
+ if(bp.bitIndex == 0)
+ {
+ bp.bitIndex = 7;
+ --bp.byteIndex;
+ }
+ else
+ {
+ --bp.bitIndex;
+ }
+ mData.setPosition(bp);
+
+/*
+ // this is what the 8137 docs say it should be
+ describeTransformation3d(mData);
+ cout << getIndent() << "UV domain" << endl;
+ indent();
+ cout << getIndent() << "Min: " << endl;
+ describeVector2d(mData);
+ cout << getIndent() << "Max: " << endl;
+ describeVector2d(mData);
+ dedent();
+
+ cout << getIndent() << "u coef. a = " << mData.readDouble() << endl;
+ cout << getIndent() << "v coef. a = " << mData.readDouble() << endl;
+ cout << getIndent() << "u coef. b = " << mData.readDouble() << endl;
+ cout << getIndent() << "v coef. b = " << mData.readDouble() << endl;
+*/
+ mData.setShowBits(false);
+ dedent();
+}
+
+void describeTopoFace(BitByBitData &mData)
+{
+ cout << getIndent() << "--Face--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ cout << getIndent() << "base_surface" << endl;
+ indent();
+ describeObject(mData);
+ dedent();
+
+ bool surface_trim_domain = mData.readBit();
+ cout << getIndent() << "surface_trim_domain "
+ << (surface_trim_domain?"yes":"no") << endl;
+ if(surface_trim_domain)
+ {
+ indent();
+ describeExtent2d(mData);
+ dedent();
+ }
+
+ bool have_tolerance = mData.readBit();
+ cout << getIndent() << "have_tolerance "
+ << (have_tolerance?"yes":"no") << endl;
+ if(have_tolerance)
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+
+ unsigned int number_of_loops = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_loops " << number_of_loops << endl;
+ cout << getIndent() << "outer_loop_index " << mData.readInt() << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_loops; ++i)
+ {
+ describeObject(mData);
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeTopoLoop(BitByBitData &mData)
+{
+ cout << getIndent() << "--Loop--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ cout << getIndent() << "orientation_with_surface "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ unsigned int number_of_coedge = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_coedge " << number_of_coedge << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_coedge; ++i)
+ {
+ describeObject(mData);
+ cout << getIndent() << "neigh_serial_index "
+ << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeTopoCoEdge(BitByBitData &mData)
+{
+ cout << getIndent() << "--CoEdge--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ describeObject(mData); // edge
+ describeObject(mData); // uv_curve
+ cout << getIndent() << "orientation_with_loop "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "orientation_uv_with_loop "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+}
+
+void describeTopoEdge(BitByBitData &mData)
+{
+ cout << getIndent() << "--Edge--" << endl;
+ indent();
+
+ describeContentWireEdge(mData);
+
+ describeObject(mData); // vertex_start
+ describeObject(mData); // vertex_end
+
+ bool have_tolerance = mData.readBit();
+ cout << getIndent() << "have_tolerance "
+ << (have_tolerance?"yes":"no") << endl;
+ if(have_tolerance)
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+ dedent();
+}
+
+void describeTopoUniqueVertex(BitByBitData &mData)
+{
+ cout << getIndent() << "--Unique Vertex--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+ describeVector3d(mData);
+
+ bool have_tolerance = mData.readBit();
+ cout << getIndent() << "have_tolerance "
+ << (have_tolerance?"yes":"no") << endl;
+ if(have_tolerance)
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeTopoConnex(BitByBitData &mData)
+{
+ cout << getIndent() << "--Connex--" << endl;
+ indent();
+ describeBaseTopology(mData);
+ unsigned int number_of_shells = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_shells "
+ << number_of_shells << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_shells; ++i)
+ {
+ // NOTE: this does not check if the objects are actually shells!
+ describeObject(mData);
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeTopoShell(BitByBitData &mData)
+{
+ cout << getIndent() << "--Shell--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ cout << getIndent() << "shell_is_closed "
+ << (mData.readBit()?"yes":"no") << endl;
+
+ unsigned int number_of_faces = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_faces " << number_of_faces << endl;
+ for(unsigned int i = 0; i < number_of_faces; ++i)
+ {
+ // NOTE: this does not check if the objects are actually faces!
+ describeObject(mData);
+ unsigned char orientation = mData.readChar();
+ cout << getIndent() << "orientation_surface_with_shell "
+ << static_cast<unsigned int>(orientation) << endl;
+ }
+
+ dedent();
+}
+
+void describeObject(BitByBitData &mData)
+{
+ cout << getIndent() << "--Object--" << endl;
+ bool already_stored = mData.readBit();
+ cout << getIndent() << "already_stored "
+ << (already_stored?"yes":"no") << endl;
+ if(already_stored) // reverse of documentation?
+ {
+ cout << getIndent() << "index of stored item "
+ << mData.readUnsignedInt() << endl;
+ }
+ else
+ {
+ unsigned int type = mData.readUnsignedInt();
+ switch(type)
+ {
+ case PRC_TYPE_ROOT:
+ cout << getIndent() << "NULL Object" << endl;
+ break;
+ // topological items
+ case PRC_TYPE_TOPO_Connex:
+ describeTopoConnex(mData);
+ break;
+ case PRC_TYPE_TOPO_Shell:
+ describeTopoShell(mData);
+ break;
+ case PRC_TYPE_TOPO_Face:
+ describeTopoFace(mData);
+ break;
+ case PRC_TYPE_TOPO_Loop:
+ describeTopoLoop(mData);
+ break;
+ case PRC_TYPE_TOPO_CoEdge:
+ describeTopoCoEdge(mData);
+ break;
+ case PRC_TYPE_TOPO_Edge:
+ describeTopoEdge(mData);
+ break;
+ case PRC_TYPE_TOPO_UniqueVertex:
+ describeTopoUniqueVertex(mData);
+ break;
+ case PRC_TYPE_TOPO_WireEdge:
+ describeContentWireEdge(mData);
+ break;
+
+ // curves
+ case PRC_TYPE_CRV_Circle:
+ describeCurvCircle(mData);
+ break;
+ case PRC_TYPE_CRV_NURBS:
+ describeCurvNURBS(mData);
+ break;
+ case PRC_TYPE_CRV_PolyLine:
+ describeCurvPolyLine(mData);
+ break;
+ case PRC_TYPE_CRV_Line:
+ describeCurvLine(mData);
+ break;
+ // surfaces
+ case PRC_TYPE_SURF_NURBS:
+ describeSurfNURBS(mData);
+ break;
+ case PRC_TYPE_SURF_Cylinder:
+ describeSurfCylinder(mData);
+ break;
+ case PRC_TYPE_SURF_Plane:
+ describeSurfPlane(mData);
+ break;
+
+ // topological items
+ case PRC_TYPE_TOPO_Item:
+ case PRC_TYPE_TOPO_MultipleVertex:
+
+
+ // curves
+ case PRC_TYPE_CRV_Base:
+ case PRC_TYPE_CRV_Blend02Boundary:
+ case PRC_TYPE_CRV_Composite:
+ case PRC_TYPE_CRV_OnSurf:
+ case PRC_TYPE_CRV_Ellipse:
+ case PRC_TYPE_CRV_Equation:
+ case PRC_TYPE_CRV_Helix:
+ case PRC_TYPE_CRV_Hyperbola:
+ case PRC_TYPE_CRV_Intersection:
+ case PRC_TYPE_CRV_Offset:
+ case PRC_TYPE_CRV_Parabola:
+ case PRC_TYPE_CRV_Transform:
+
+ // surfaces
+ case PRC_TYPE_SURF_Base:
+ case PRC_TYPE_SURF_Blend01:
+ case PRC_TYPE_SURF_Blend02:
+ case PRC_TYPE_SURF_Blend03:
+ case PRC_TYPE_SURF_Cone:
+ case PRC_TYPE_SURF_Cylindrical:
+ case PRC_TYPE_SURF_Offset:
+ case PRC_TYPE_SURF_Pipe:
+ case PRC_TYPE_SURF_Ruled:
+ case PRC_TYPE_SURF_Sphere:
+ case PRC_TYPE_SURF_Revolution:
+ case PRC_TYPE_SURF_Extrusion:
+ case PRC_TYPE_SURF_FromCurves:
+ case PRC_TYPE_SURF_Torus:
+ case PRC_TYPE_SURF_Transform:
+ case PRC_TYPE_SURF_Blend04:
+ cout << getIndent() << "TODO: Unhandled object of type "
+ << type << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid object of type " << type << endl;
+ break;
+ }
+ }
+}
+
+void describeBaseTopology(BitByBitData &mData)
+{
+ bool base_information = mData.readBit();
+ cout << getIndent() << "base_information " <<
+ (base_information?"yes":"no") << endl;
+ if(base_information)
+ {
+ describeAttributes(mData);
+ describeName(mData);
+ cout << getIndent() << "identifier " << mData.readUnsignedInt() << endl;
+ }
+}
+
+void describeBaseGeometry(BitByBitData &mData)
+{
+ bool base_information = mData.readBit();
+ cout << getIndent() << "base_information " <<
+ (base_information?"yes":"no") << endl;
+ if(base_information)
+ {
+ describeAttributes(mData);
+ describeName(mData);
+ cout << getIndent() << "identifier " << mData.readUnsignedInt() << endl;
+ }
+}
+
+unsigned int describeContentBody(BitByBitData &mData)
+{
+ describeBaseTopology(mData);
+ unsigned int behaviour = static_cast<unsigned int>(mData.readChar());
+ cout << getIndent() << "behaviour " << behaviour << endl;
+ return behaviour;
+}
+
+void describeContentSurface(BitByBitData &mData)
+{
+ describeBaseGeometry(mData);
+ cout << getIndent() << "extend_info " << mData.readUnsignedInt() << endl;
+}
+
+void describeBody(BitByBitData &mData)
+{
+ cout << getIndent() << "--Body--" << endl;
+ unsigned int type = mData.readUnsignedInt();
+ switch(type)
+ {
+ case PRC_TYPE_TOPO_BrepData:
+ {
+ cout << getIndent() << "--PRC_TYPE_TOPO_BrepData--" << endl;
+ unsigned int behaviour = describeContentBody(mData);
+
+ unsigned int number_of_connex = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_connex " << number_of_connex << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_connex; ++i)
+ {
+ describeObject(mData);
+ }
+ dedent();
+ if(behaviour != 0)
+ {
+ cout << getIndent() << "bbox " << endl;
+ indent();
+ describeExtent3d(mData);
+ dedent();
+ }
+ break;
+ }
+ case PRC_TYPE_TOPO_SingleWireBody:
+ {
+ cout << getIndent() << "--PRC_TYPE_TOPO_SingleWireBody--" << endl;
+ // unsigned int behaviour = describeContentBody(mData);
+ // TODO: is behaviour needed to get data about how to describe?
+ describeContentBody(mData);
+
+ describeObject(mData); // curve
+
+ break;
+ }
+ case PRC_TYPE_TOPO_BrepDataCompress:
+ case PRC_TYPE_TOPO_SingleWireBodyCompress:
+ cout << getIndent() << "TODO: Unhandled body type " << type << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid body type " << type << endl;
+ break;
+ }
+}
+
+void describeTopoContext(BitByBitData &mData)
+{
+ cout << getIndent() << "--Topological Context--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_TOPO_Context))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "granularity " << mData.readDouble() << endl;
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+
+ bool have_smallest_face_thickness = mData.readBit();
+ cout << getIndent() << "have_smallest_face_thickness "
+ << (have_smallest_face_thickness?"yes":"no") << endl;
+ if(have_smallest_face_thickness)
+ cout << getIndent() << "smallest_thickness " << mData.readDouble() << endl;
+
+ bool have_scale = mData.readBit();
+ cout << getIndent() << "have_scale " << (have_scale?"yes":"no") << endl;
+ if(have_scale)
+ cout << getIndent() << "scale " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeLineAttr(BitByBitData& mData)
+{
+ cout << getIndent() << "index_of_line_style "
+ << mData.readUnsignedInt()-1 << endl;
+}
+
+void describeArrayRGBA(BitByBitData& mData, int number_of_colours,
+ int number_by_vector)
+{
+ // bool new_colour = true; // not currently used
+ for(int i = 0; i < number_by_vector; ++i)
+ {
+ cout << getIndent() << static_cast<unsigned int>(mData.readChar()) << ' ';
+ cout << static_cast<unsigned int>(mData.readChar()) << ' ';
+ cout << static_cast<unsigned int>(mData.readChar()) << endl;
+ //TODO: finish this
+ }
+}
+
+void describeContentBaseTessData(BitByBitData &mData)
+{
+ cout << getIndent() << "is_calculated "
+ << (mData.readBit()?"yes":"no") << endl;
+ unsigned int number_of_coordinates = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_coordinates "
+ << number_of_coordinates << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_coordinates; ++i)
+ {
+ cout << getIndent() << mData.readDouble() << endl;
+ }
+ dedent();
+}
+
+void describeTessFace(BitByBitData &mData)
+{
+ cout << getIndent() << "--Tessellation Face--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_TESS_Face))
+ return;
+ indent();
+
+ unsigned int size_of_line_attributes = mData.readUnsignedInt();
+ cout << getIndent() << "size_of_line_attributes "
+ << size_of_line_attributes << endl;
+ indent();
+ for(unsigned int i = 0; i < size_of_line_attributes; ++i)
+ {
+ describeLineAttr(mData);
+ }
+ dedent();
+
+ unsigned int start_wire = mData.readUnsignedInt();
+ cout << getIndent() << "start_wire " << start_wire << endl;
+ unsigned int size_of_sizes_wire = mData.readUnsignedInt();
+ cout << getIndent() << "size_of_sizes_wire " << size_of_sizes_wire << endl;
+ indent();
+ for(unsigned int i = 0; i < size_of_sizes_wire; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+
+ unsigned int used_entities_flag = mData.readUnsignedInt();
+ cout << getIndent() << "used_entities_flag " << used_entities_flag << endl;
+
+ unsigned int start_triangulated = mData.readUnsignedInt();
+ cout << getIndent() << "start_triangulated " << start_triangulated << endl;
+ unsigned int size_of_sizes_triangulated = mData.readUnsignedInt();
+ cout << getIndent() << "size_of_sizes_triangulated "
+ << size_of_sizes_triangulated << endl;
+ indent();
+ for(unsigned int i = 0; i < size_of_sizes_triangulated; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ cout << getIndent() << "number_of_texture_coordinate_indexes "
+ << mData.readUnsignedInt() << endl;
+
+ bool has_vertex_colors = mData.readBit();
+ cout << getIndent() << "has_vertex_colors "
+ << (has_vertex_colors?"yes":"no") << endl;
+ indent();
+ if(has_vertex_colors)
+ {
+ bool is_rgba = mData.readBit();
+ cout << getIndent() << "is_rgba " << (is_rgba?"yes":"no") << endl;
+
+ bool b_optimised = mData.readBit();
+ cout << getIndent() << "b_optimised " << (b_optimised?"yes":"no") << endl;
+ if(!b_optimised)
+ {
+ indent();
+ //TODO: compute size of Array and pass it instead of 0
+ describeArrayRGBA(mData,0,(is_rgba ? 4 : 3));
+ dedent();
+ }
+ else
+ {
+ // not described
+ // what does this mean? that this should not happen?
+ // or is omitted from the docs?
+ }
+ }
+ dedent();
+
+ if(size_of_line_attributes)
+ {
+ cout << getIndent() << "behaviour " << mData.readUnsignedInt() << endl;
+ }
+
+ dedent();
+}
+
+void describe3DTess(BitByBitData &mData)
+{
+ cout << getIndent() << "--3D Tessellation--" << endl;
+ indent();
+
+ describeContentBaseTessData(mData);
+
+ cout << getIndent() << "has_faces " << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "has_loops " << (mData.readBit()?"yes":"no") << endl;
+
+ bool must_recalculate_normals = mData.readBit();
+ cout << getIndent() << "must_recalculate_normals "
+ << (must_recalculate_normals?"yes":"no") << endl;
+ indent();
+ if(must_recalculate_normals)
+ {
+ cout << getIndent()
+ << "Docs were wrong: must_recalculate_normals is true." << endl;
+ cout << getIndent() << "normals_recalculation_flags "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "crease_angle " << mData.readDouble() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_normal_coordinates = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_normal_coordinates "
+ << number_of_normal_coordinates << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_normal_coordinates; ++i)
+ {
+ cout << getIndent() << mData.readDouble() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_wire_indices = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_wire_indices "
+ << number_of_wire_indices << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_wire_indices; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_triangulated_indices = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_triangulated_indices "
+ << number_of_triangulated_indices << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_triangulated_indices; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_face_tessellation = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_face_tessellation "
+ << number_of_face_tessellation << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_face_tessellation; ++i)
+ {
+ describeTessFace(mData);
+ }
+ dedent();
+
+ unsigned int number_of_texture_coordinates = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_texture_coordinates "
+ << number_of_texture_coordinates << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_texture_coordinates; ++i)
+ {
+ cout << getIndent() << mData.readDouble() << endl;
+ }
+ dedent();
+
+ dedent();
+}
+
+void describe3DWireTess(BitByBitData &mData)
+{
+ //TODO
+}
+
+void describe3DMarkupTess(BitByBitData &mData)
+{
+ //TODO
+}
+
+void describeHighlyCompressed3DTess(BitByBitData &mData)
+{
+ //TODO
+}
+
+void describeSceneDisplayParameters(BitByBitData &mData)
+{
+ cout << getIndent() << "--Scene Display Parameters--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_SceneDisplayParameters))
+ return;
+ indent();
+ describeContentPRCBase(mData,true);
+
+ cout << getIndent() << "is active? " << (mData.readBit()?"yes":"no") << endl;
+
+ unsigned int number_of_lights = mData.readUnsignedInt();
+ cout << getIndent() << "number of lights " << number_of_lights << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_lights; ++i)
+ {
+ describeLight(mData);
+ }
+ dedent();
+
+ bool camera = mData.readBit();
+ cout << getIndent() << "camera? " << (camera?"yes":"no") << endl;
+ if(camera)
+ describeCamera(mData);
+
+ bool rotation_centre = mData.readBit();
+ cout << getIndent() << "rotation centre? " << (rotation_centre?"yes":"no") << endl;
+ if(rotation_centre)
+ describeVector3d(mData);
+
+ unsigned int number_of_clipping_planes = mData.readUnsignedInt();
+ cout << getIndent() << "number of clipping planes " << number_of_clipping_planes << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_clipping_planes; ++i)
+ {
+ cout << "Can't describe planes!!!" << endl;
+ //describePlane(mData);
+ }
+ dedent();
+
+ cout << getIndent() << "Background line style index: " << mData.readUnsignedInt()-1 << endl;
+ cout << getIndent() << "Default line style index: " << mData.readUnsignedInt()-1 << endl;
+
+ unsigned int number_of_default_styles_per_type = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_default_styles_per_type " << number_of_default_styles_per_type << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_default_styles_per_type; ++i)
+ {
+ cout << getIndent() << "type " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "line style index: " << mData.readUnsignedInt()-1 << endl;
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeCartesionTransformation3d(BitByBitData& mData)
+{
+ cout << getIndent() << "--3d Cartesian Transformation--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_MISC_CartesianTransformation))
+ return;
+ indent();
+ unsigned char behaviour = mData.readChar();
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(behaviour) << endl;
+ if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
+ {
+ cout << getIndent() << "Translation" << endl;
+ describeVector3d(mData);
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_NonOrtho) != 0)
+ {
+ cout << getIndent() << "Non orthogonal transformation" << endl;
+ cout << getIndent() << "X" << endl; describeVector3d(mData);
+ cout << getIndent() << "Y" << endl; describeVector3d(mData);
+ cout << getIndent() << "Z" << endl; describeVector3d(mData);
+ }
+ else if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
+ {
+ cout << getIndent() << "Rotation" << endl;
+ cout << getIndent() << "X" << endl; describeVector3d(mData);
+ cout << getIndent() << "Y" << endl; describeVector3d(mData);
+ }
+
+ // this is different from the docs!!! but it works...
+ if ((behaviour & PRC_TRANSFORMATION_NonUniformScale) != 0)
+ {
+ cout << getIndent() << "Non-uniform scale by " << endl;
+ describeVector3d(mData);
+ }
+
+ // this is different from the docs!!! but it works...
+ if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
+ {
+ cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_Homogeneous) != 0)
+ {
+ cout << getIndent() << "transformation has homogenous values" << endl;
+ cout << getIndent() << "x = " << mData.readDouble() << endl;
+ cout << getIndent() << "y = " << mData.readDouble() << endl;
+ cout << getIndent() << "z = " << mData.readDouble() << endl;
+ cout << getIndent() << "w = " << mData.readDouble() << endl;
+ }
+ dedent();
+}
+
+void describeTransformation3d(BitByBitData& mData)
+{
+ cout << getIndent() << "--3d Transformation--" << endl;
+ indent();
+ bool has_transformation = mData.readBit();
+ cout << getIndent() << "has_transformation "
+ << (has_transformation?"yes":"no") << endl;
+ if(has_transformation)
+ {
+ unsigned char behaviour = mData.readChar();
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(behaviour) << endl;
+ if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
+ {
+ cout << getIndent() << "Translation" << endl;
+ describeVector3d(mData);
+ }
+ if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
+ {
+ cout << getIndent() << "Rotation" << endl;
+ cout << getIndent() << "X" << endl; describeVector3d(mData);
+ cout << getIndent() << "Y" << endl; describeVector3d(mData);
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
+ {
+ cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
+ }
+ }
+ dedent();
+}
+
+void describeTransformation2d(BitByBitData& mData)
+{
+ cout << getIndent() << "--2d Transformation--" << endl;
+ indent();
+ bool has_transformation = mData.readBit();
+ cout << "has_transformation " << (has_transformation?"yes":"no") << endl;
+ if(has_transformation)
+ {
+ unsigned char behaviour = mData.readChar();
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(behaviour) << endl;
+ if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
+ {
+ cout << getIndent() << "Translation" << endl;
+ describeVector2d(mData);
+ }
+ if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
+ {
+ cout << getIndent() << "Rotation" << endl;
+ cout << getIndent() << "X" << endl; describeVector2d(mData);
+ cout << getIndent() << "Y" << endl; describeVector2d(mData);
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
+ {
+ cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
+ }
+ }
+ dedent();
+}
+
+void describeFileStructureInternalData(BitByBitData &mData)
+{
+ cout << getIndent() << "--File Structure Internal Data--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructure))
+ return;
+ indent();
+ describeContentPRCBase(mData,false);
+ cout << getIndent() << "next_available_index "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "index_product_occurence "
+ << mData.readUnsignedInt() << endl;
+ dedent();
+}
+
+void describeProductOccurrence(BitByBitData &mData)
+{
+ cout << getIndent() << "--Product Occurrence--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_ProductOccurence))
+ return;
+ indent();
+
+ describeContentPRCBaseWithGraphics(mData,true);
+
+ cout << getIndent() << "index_part "
+ << static_cast<int>(mData.readUnsignedInt()-1) << endl;
+ unsigned int index_prototype = mData.readUnsignedInt()-1;
+ cout << getIndent() << "index_prototype "
+ << static_cast<int>(index_prototype) << endl;
+ if(index_prototype+1 != 0)
+ {
+ bool prototype_in_same_file_structure = mData.readBit();
+ cout << getIndent() << "prototype_in_same_file_structure "
+ << (prototype_in_same_file_structure?"yes":"no") << endl;
+ if(!prototype_in_same_file_structure)
+ describeCompressedUniqueID(mData);
+ }
+
+ unsigned int index_external_data = mData.readUnsignedInt()-1;
+ cout << getIndent() << "index_external_data "
+ << static_cast<int>(index_external_data) << endl;
+ if(index_external_data+1 != 0)
+ {
+ bool external_data_in_same_file_structure = mData.readBit();
+ cout << getIndent() << "external_data_in_same_file_structure "
+ << (external_data_in_same_file_structure?"yes":"no") << endl;
+ if(!external_data_in_same_file_structure)
+ describeCompressedUniqueID(mData);
+ }
+
+ unsigned int number_of_son_product_occurences = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_son_product_occurences "
+ << number_of_son_product_occurences << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_son_product_occurences; ++i)
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ dedent();
+
+ cout << getIndent() << "product_behaviour "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+
+ describeUnit(mData);
+ cout << getIndent() << "Product information flags "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "product_load_status "
+ << mData.readUnsignedInt() << endl;
+
+ bool has_location = mData.readBit();
+ cout << getIndent() << "has_location " << has_location << endl;
+ if(has_location)
+ {
+ describeCartesionTransformation3d(mData);
+ }
+
+ unsigned int number_of_references = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_references "
+ << number_of_references << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_references; ++i)
+ {
+ //TODO: describeReferenceToPRCBase(mData);
+ }
+ dedent();
+
+ describeMarkups(mData);
+
+ unsigned int number_of_views = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_views " << number_of_views << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_views; ++i)
+ {
+ describeAnnotationView(mData);
+ }
+ dedent();
+
+ bool has_entity_filter = mData.readBit();
+ cout << getIndent() << "has_entity_filter "
+ << (has_entity_filter?"yes":"no") << endl;
+ if(has_entity_filter)
+ {
+ //TODO: describeEntityFilter(mData);
+ }
+
+ unsigned int number_of_display_filters = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_display_filters "
+ << number_of_display_filters << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_display_filters; ++i)
+ {
+ //TODO: describeFilter(mData);
+ }
+ dedent();
+
+ unsigned int number_of_scene_display_parameters = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_scene_display_parameters "
+ << number_of_scene_display_parameters << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_scene_display_parameters; ++i)
+ {
+ describeSceneDisplayParameters(mData);
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+}
+
+void describeGraphics(BitByBitData &mData)
+{
+ bool sameGraphicsAsCurrent = mData.readBit();
+ cout << getIndent() << "Same graphics as current graphics? "
+ << (sameGraphicsAsCurrent?"yes":"no") << endl;
+ if(!sameGraphicsAsCurrent)
+ {
+ layer_index = mData.readUnsignedInt()-1;
+ cout << getIndent() << "layer_index " << layer_index << endl;
+ index_of_line_style = mData.readUnsignedInt()-1;
+ cout << getIndent() << "index_of_line_style "
+ << index_of_line_style << endl;
+ unsigned char c1 = mData.readChar();
+ unsigned char c2 = mData.readChar();
+ behaviour_bit_field = c1 | (static_cast<unsigned short>(c2) << 8);
+ cout << getIndent() << "behaviour_bit_field "
+ << behaviour_bit_field << endl;
+ }
+}
+
+void describeContentPRCBaseWithGraphics(BitByBitData &mData, bool efr)
+{
+ describeContentPRCBase(mData,efr);
+ describeGraphics(mData);
+}
+
+void describePartDefinition(BitByBitData &mData)
+{
+ cout << getIndent() << "--Part Definition--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_PartDefinition))
+ return;
+ indent();
+
+ describeContentPRCBaseWithGraphics(mData,true);
+ describeExtent3d(mData);
+
+ unsigned int number_of_representation_items = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_representation_items "
+ << number_of_representation_items << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_representation_items; ++i)
+ {
+ describeRepresentationItem(mData);
+ }
+ dedent();
+
+ describeMarkups(mData);
+
+ unsigned int number_of_views = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_views " << number_of_views << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_views; ++i)
+ {
+ describeAnnotationView(mData);
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+}
+
+void describeMarkups(BitByBitData& mData)
+{
+ cout << getIndent() << "--Markups--" << endl;
+ indent();
+
+ unsigned int number_of_linked_items = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_linked_items "
+ << number_of_linked_items << endl;
+ for(unsigned int i = 0; i < number_of_linked_items; ++i)
+ {
+ cout << "describe linked item!" << endl;
+ }
+
+ unsigned int number_of_leaders = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_leaders " << number_of_leaders << endl;
+ for(unsigned int i = 0; i < number_of_leaders; ++i)
+ {
+ cout << "describe leader!" << endl;
+ }
+
+ unsigned int number_of_markups = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_markups " << number_of_markups << endl;
+ for(unsigned int i=0; i < number_of_markups; ++i)
+ {
+ cout << "describe markup!" << endl;
+ }
+
+ unsigned int number_of_annotation_entities = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_annotation_entities "
+ << number_of_annotation_entities << endl;
+ for(unsigned int i=0; i < number_of_annotation_entities; ++i)
+ {
+ cout << "describe annotation entity!" << endl;
+ }
+
+ dedent();
+}
+
+void describeAnnotationView(BitByBitData &mData)
+{
+ cout << getIndent() << "--Annotation View--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_MKP_View))
+ return;
+ indent();
+ describeContentPRCBaseWithGraphics(mData,true);
+ unsigned int number_of_annotations = mData.readUnsignedInt();
+ for(unsigned int i = 0; i < number_of_annotations; ++i)
+ {
+ //TODO: describeReferenceUniqueIdentifier(mData);
+ }
+ //TODO: describePlane(mData);
+ bool scene_display_parameters = mData.readBit();
+ if(scene_display_parameters)
+ {
+ describeSceneDisplayParameters(mData);
+ }
+ describeUserData(mData);
+ dedent();
+}
+
+void describeExtent3d(BitByBitData &mData)
+{ // I suspect the order of min/max should be flipped
+ cout << getIndent() << "Minimum" << endl;
+ indent(); describeVector3d(mData); dedent();
+ cout << getIndent() << "Maximum" << endl;
+ indent(); describeVector3d(mData); dedent();
+}
+
+void describeExtent1d(BitByBitData &mData)
+{
+ cout << getIndent() << "Minimum " << mData.readDouble() << endl;
+ cout << getIndent() << "Maximum " << mData.readDouble() << endl;
+}
+
+void describeExtent2d(BitByBitData &mData)
+{
+ cout << getIndent() << "Minimum" << endl;
+ indent(); describeVector2d(mData); dedent();
+ cout << getIndent() << "Maximum" << endl;
+ indent(); describeVector2d(mData); dedent();
+}
+
+void describeVector3d(BitByBitData &mData)
+{
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ double z = mData.readDouble();
+ cout << getIndent() << '(' << x << ',' << y << ',' << z << ')' << endl;
+}
+
+void describeVector2d(BitByBitData &mData)
+{
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ cout << getIndent() << '(' << x << ',' << y << ')' << endl;
+}
+
+void describePicture(BitByBitData &mData)
+{
+ cout << getIndent() << "--Picture--" << endl;
+ unsigned int sectionCode = mData.readUnsignedInt();
+ if(sectionCode != PRC_TYPE_GRAPH_Picture)
+ {
+ cout << getIndent() << "Invalid section code." << endl;
+ }
+
+ describeContentPRCBase(mData,false);
+
+ int format = mData.readInt();
+ switch(format)
+ {
+ case KEPRCPicture_PNG:
+ cout << getIndent() << "PNG format" << endl;
+ break;
+ case KEPRCPicture_JPG:
+ cout << getIndent() << "JPG format" << endl;
+ break;
+ case KEPRCPicture_BITMAP_RGB_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a RGB triple. (3 components)" << endl;
+ break;
+ case KEPRCPicture_BITMAP_RGBA_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a complete RGBA element. (4 components)" << endl;
+ break;
+ case KEPRCPicture_BITMAP_GREY_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a single luminance value. (1 components)" << endl;
+ break;
+ case KEPRCPicture_BITMAP_GREYA_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a luminance/alpha pair. (2 components)" << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid picture format." << endl;
+ break;
+ }
+ cout << getIndent() << "uncompressed_file_index "
+ << mData.readUnsignedInt()-1 << endl;
+ cout << getIndent() << "pixel width " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "pixel height " << mData.readUnsignedInt() << endl;
+}
+
+void describeTextureDefinition(BitByBitData &mData)
+{
+ cout << getIndent() << "--Texture Definition--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_TextureDefinition))
+ return;
+
+ cout << getIndent() << "TODO: Can't describe textures yet." << endl;
+}
+
+void describeMaterial(BitByBitData &mData)
+{
+ cout << getIndent() << "--Material--" << endl;
+ unsigned int code = mData.readUnsignedInt();
+ if(code == PRC_TYPE_GRAPH_Material)
+ {
+ describeContentPRCBase(mData,true);
+ cout << getIndent() << "index of ambient color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "index of diffuse color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "index of emissive color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "index of specular color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "shininess " << mData.readDouble() << endl;
+ cout << getIndent() << "ambient_alpha " << mData.readDouble() << endl;
+ cout << getIndent() << "diffuse_alpha " << mData.readDouble() << endl;
+ cout << getIndent() << "emissive_alpha " << mData.readDouble() << endl;
+ cout << getIndent() << "specular_alpha " << mData.readDouble() << endl;
+ }
+ else if(code == PRC_TYPE_GRAPH_TextureApplication)
+ {
+ describeContentPRCBase(mData,true);
+ cout << getIndent() << "material_generic_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "texture_definition_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "next_texture_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "UV_coordinates_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ }
+ else
+ {
+ cout << getIndent() << "Invalid section code in material definition."
+ << endl;
+ }
+}
+
+void describeLinePattern(BitByBitData &mData)
+{
+ cout << getIndent() << "--Line Pattern--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_LinePattern))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,true);
+ unsigned int size_lengths = mData.readUnsignedInt();
+ cout << getIndent() << "size_lengths " << size_lengths << endl;
+ indent();
+ for(unsigned int i=0;i<size_lengths;i++)
+ {
+ cout << getIndent() << "length " << mData.readDouble() << endl;
+ }
+ dedent();
+ cout << getIndent() << "phase " << mData.readDouble() << endl;
+ cout << getIndent() << "is real length "
+ << (mData.readBit()?"yes":"no") << endl;
+
+ dedent();
+}
+
+void describeCategory1LineStyle(BitByBitData &mData)
+{
+ cout << getIndent() << "--Category 1 Line Style--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_Style))
+ return;
+ indent();
+
+ // This was missing from the docs!!!!! argh!
+ describeContentPRCBase(mData,true);
+
+
+ cout << getIndent() << "line_width " << mData.readDouble() << " mm" << endl;
+
+ cout << getIndent() << "is_vpicture " << (mData.readBit()?"yes":"no") << endl;
+
+ cout << getIndent() << "line_pattern_index/vpicture_index "
+ << static_cast<int>(mData.readUnsignedInt()-1) << endl;
+ cout << getIndent() << "is_material " << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "color_index / material_index "
+ << static_cast<int>(mData.readUnsignedInt()-1) << endl;
+
+ bool is_transparency_defined = mData.readBit();
+ cout << getIndent() << "is_transparency_defined "
+ << (is_transparency_defined?"yes":"no") << endl;
+ if(is_transparency_defined)
+ {
+ indent();
+ cout << getIndent() << "transparency "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+
+ bool is_additional_1_defined = mData.readBit();
+ cout << getIndent() << "is_additional_1_defined "
+ << (is_additional_1_defined?"yes":"no") << endl;
+ if(is_additional_1_defined)
+ {
+ indent();
+ cout << getIndent() << "additional_1 "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+
+ bool is_additional_2_defined = mData.readBit();
+ cout << getIndent() << "is_additional_2_defined "
+ << (is_additional_2_defined?"yes":"no") << endl;
+ if(is_additional_2_defined)
+ {
+ indent();
+ cout << getIndent() << "additional_2 "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+
+ bool is_additional_3_defined = mData.readBit();
+ cout << getIndent() << "is_additional_3_defined "
+ << (is_additional_3_defined?"yes":"no") << endl;
+ if(is_additional_3_defined)
+ {
+ indent();
+ cout << getIndent() << "additional_3 "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+ dedent();
+}
+
+void describeFillPattern(BitByBitData &mData)
+{
+ cout << getIndent() << "--Fill Pattern--" << endl;
+ unsigned int type = mData.readUnsignedInt();
+ cout << getIndent() << "type " << type << endl;
+ switch(type)
+ {
+ //TODO: actually describe fill patterns
+ default:
+ cout << getIndent() << "Invalid fill pattern type " << type << endl;
+ }
+}
+
+void describeRepresentationItemContent(BitByBitData &mData)
+{
+ describeContentPRCBaseWithGraphics(mData,true);
+ unsigned int index_local_coordinate_system = mData.readUnsignedInt()-1;
+ unsigned int index_tessellation = mData.readUnsignedInt()-1;
+ //cast to int will not be right for big indices
+ cout << getIndent() << "index_local_coordinate_system "
+ << static_cast<int>(index_local_coordinate_system) << endl;
+ cout << getIndent() << "index_tessellation "
+ << static_cast<int>(index_tessellation) << endl;
+}
+
+void describeRepresentationItem(BitByBitData &mData)
+{
+ cout << getIndent() << "--Representation Item--" << endl;
+ unsigned int type = mData.readUnsignedInt();
+ switch(type)
+ {
+ case PRC_TYPE_RI_Curve:
+ {
+ cout << getIndent() << "--PRC_TYPE_RI_Curve--" << endl;
+ describeRepresentationItemContent(mData);
+ bool has_wire_body = mData.readBit();
+ if(has_wire_body)
+ {
+ cout << getIndent() << "context_id " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "body_id " << mData.readUnsignedInt() << endl;
+ }
+ describeUserData(mData);
+ break;
+ }
+ case PRC_TYPE_RI_PolyBrepModel:
+ {
+ cout << getIndent() << "--PRC_TYPE_RI_PolyBrepModel--" << endl;
+ describeRepresentationItemContent(mData);
+ cout << getIndent() << "is_closed "
+ << (mData.readBit()?"yes":"no") << endl;
+ describeUserData(mData);
+ break;
+ }
+ case PRC_TYPE_RI_BrepModel:
+ {
+ cout << getIndent() << "--PRC_TYPE_RI_BrepModel--" << endl;
+ describeRepresentationItemContent(mData);
+ bool has_brep_data = mData.readBit();
+ cout << getIndent() << "has_brep_data "
+ << (has_brep_data?"yes":"no") << endl;
+ if(has_brep_data)
+ {
+ cout << getIndent() << "context_id " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "object_id " << mData.readUnsignedInt() << endl;
+ }
+ cout << getIndent() << "is_closed "
+ << (mData.readBit()?"yes":"no") << endl;
+ describeUserData(mData);
+ break;
+ }
+ case PRC_TYPE_RI_Direction:
+
+ case PRC_TYPE_RI_Plane:
+ case PRC_TYPE_RI_CoordinateSystem:
+ case PRC_TYPE_RI_PointSet:
+ case PRC_TYPE_RI_Set:
+ case PRC_TYPE_RI_PolyWire:
+ cout << getIndent() << "TODO: Unhandled representation item "
+ << type << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid representation item type "
+ << type << endl;
+ break;
+ }
+}
+
+void describeRGBColour(BitByBitData &mData)
+{
+ cout << getIndent() << "R: " << mData.readDouble();
+ cout << " G: " << mData.readDouble();
+ cout << " B: " << mData.readDouble() << endl;
+}
+
+void describeSchema(BitByBitData &mData)
+{
+ cout << getIndent() << "--Schema--" << endl;
+ indent();
+ unsigned int numSchemas = mData.readUnsignedInt();
+ cout << getIndent() << "Number of Schemas " << numSchemas << endl;
+ if(numSchemas != 0)
+ {
+ cout << "Error: Don't know how to handle multiple schemas." << endl;
+ }
+ dedent();
+}
+
+string currentName;
+int layer_index;
+int index_of_line_style;
+unsigned short behaviour_bit_field;
+
+void resetCurrentGraphics()
+{
+ layer_index = -1;
+ index_of_line_style = -1;
+ behaviour_bit_field = 1;
+}
+
+void unFlushSerialization()
+{
+ currentName = "";
+
+ resetCurrentGraphics();
+}
+
+void describeName(BitByBitData &mData)
+{
+ bool sameNameAsCurrent = mData.readBit();
+ cout << getIndent() << "Same name as current name? "
+ << (sameNameAsCurrent?"yes":"no") << endl;
+ if(!sameNameAsCurrent)
+ currentName = mData.readString();
+ cout << getIndent() << "Name \"" << currentName << '\"' << endl;
+}
+
+void describeUnit(BitByBitData &mData)
+{
+ cout << getIndent() << "Unit is from CAD file? "
+ << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "Unit is " << mData.readDouble() << " mm" << endl;
+}
+
+void describeAttributes(BitByBitData &mData)
+{
+ cout << getIndent() << "--Attributes--" << endl;
+ indent();
+
+ unsigned int numAttribs = mData.readUnsignedInt();
+ cout << getIndent() << "Number of Attributes " << numAttribs << endl;
+ indent();
+ for(unsigned int i = 0; i < numAttribs; ++i)
+ {
+ cout << getIndent() << "PRC_TYPE_MISC_Attribute "
+ << mData.readUnsignedInt() << endl;
+ bool titleIsInt = mData.readBit();
+ cout << getIndent() << "Title is integer? "
+ << (titleIsInt?"yes":"no") << endl;
+ indent();
+ if(titleIsInt)
+ {
+ cout << getIndent() << "Title " << mData.readUnsignedInt() << endl;
+ }
+ else
+ {
+ cout << getIndent() << "Title \"" << mData.readString() << '\"' << endl;
+ }
+ unsigned int sizeOfAttributeKeys = mData.readUnsignedInt();
+ cout << getIndent() << "Size of Attribute Keys "
+ << sizeOfAttributeKeys << endl;
+ for(unsigned int a = 0; a < sizeOfAttributeKeys; ++a)
+ {
+ bool titleIsInt = mData.readBit();
+ cout << getIndent() << "Title is integer? "
+ << (titleIsInt?"yes":"no") << endl;
+ indent();
+ if(titleIsInt)
+ {
+ cout << getIndent() << "Title " << mData.readUnsignedInt() << endl;
+ }
+ else
+ {
+ cout << getIndent() << "Title \"" << mData.readString() << '\"' << endl;
+ }
+ dedent();
+ unsigned int attributeType = mData.readUnsignedInt();
+ cout << getIndent() << "Attribute Type " << attributeType << endl;
+ switch(attributeType)
+ {
+ case KEPRCModellerAttributeTypeInt:
+ cout << getIndent() << "Attribute Value (int) "
+ << mData.readInt() << endl;
+ break;
+ case KEPRCModellerAttributeTypeReal:
+ cout << getIndent() << "Attribute Value (double) "
+ << mData.readDouble() << endl;
+ break;
+ case KEPRCModellerAttributeTypeTime:
+ cout << getIndent() << "Attribute Value (time_t) "
+ << mData.readUnsignedInt() << endl;
+ break;
+ case KEPRCModellerAttributeTypeString:
+ cout << getIndent() << "Attribute Value (string) \""
+ << mData.readString() << '\"' << endl;
+ break;
+ default:
+ break;
+ }
+ }
+ dedent();
+
+ cout << endl;
+ }
+ dedent();
+
+
+ dedent();
+}
+
+void describeContentPRCBase(BitByBitData &mData, bool typeEligibleForReference)
+{
+ cout << getIndent() << "--ContentPRCBase--" << endl;
+ indent();
+ describeAttributes(mData);
+ describeName(mData);
+ if(typeEligibleForReference)
+ {
+ cout << getIndent() << "CAD_identifier "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "CAD_persistent_identifier "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "PRC_unique_identifier "
+ << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+}
+
+void describeCompressedUniqueID(BitByBitData &mData)
+{
+ cout << getIndent() << "UUID: " << hex << setfill('0');
+ for(int i = 0; i < 4; ++i)
+ cout << setw(8) << mData.readUnsignedInt() << ' ';
+ cout << dec << setfill(' ') << endl;
+}
+
+void describeUserData(BitByBitData &mData)
+{
+ unsigned int bits = mData.readUnsignedInt();
+ cout << getIndent() << bits << " bits of user data" << endl;
+ indent();
+ for(unsigned int i = 0; i < bits; ++i)
+ {
+ if(i%64 == 0)
+ cout << getIndent();
+ cout << mData.readBit();
+ if(i%64 == 63)
+ cout << endl;
+ }
+ if(bits%64 != 0)
+ cout << endl;
+ dedent();
+}
+
+bool checkSectionCode(BitByBitData &mData, unsigned int code)
+{
+ unsigned int num = mData.readUnsignedInt();
+ if(code != num)
+ {
+ cout << getIndent() << "Invalid section code " << num <<
+ ". Expected " << code << " at "; mData.tellPosition();
+ return false;
+ }
+ else
+ {
+ cout << getIndent() << "Section code " << code << endl;
+ return true;
+ }
+}
+
+unsigned int currentIndent = 0;
+
+string getIndent()
+{
+ ostringstream out;
+ for(unsigned int i = 0; i < currentIndent; ++i)
+ out << " ";
+ return out.str();
+}
+
+void indent()
+{
+ ++currentIndent;
+}
+
+void dedent()
+{
+ --currentIndent;
+}
diff --git a/graphics/asymptote/prc/PRCTools/describePRC.h b/graphics/asymptote/prc/PRCTools/describePRC.h
new file mode 100644
index 0000000000..acafb875da
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/describePRC.h
@@ -0,0 +1,117 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __DESCRIBE_PRC_H
+#define __DESCRIBE_PRC_H
+
+#include "iPRCFile.h"
+#include "bitData.h"
+
+void describeGlobals(BitByBitData&);
+void describeTree(BitByBitData&);
+void describeTessellation(BitByBitData&);
+void describeGeometry(BitByBitData&);
+void describeExtraGeometry(BitByBitData&);
+void describeModelFileData(BitByBitData&,unsigned int);
+
+void describePicture(BitByBitData&);
+void describeTextureDefinition(BitByBitData&);
+void describeMaterial(BitByBitData&);
+void describeLinePattern(BitByBitData&);
+void describeCategory1LineStyle(BitByBitData&);
+void describeFillPattern(BitByBitData&);
+void describeRepresentationItem(BitByBitData&);
+
+//void describe(BitByBitData&);
+void describeLight(BitByBitData&);
+void describeCamera(BitByBitData&);
+bool describeContentCurve(BitByBitData&);
+void describeCurvCircle(BitByBitData&);
+void describeCurvLine(BitByBitData&);
+void describeCurvNURBS(BitByBitData&);
+void describeCurvPolyLine(BitByBitData&);
+void describeContentWireEdge(BitByBitData&);
+bool isCompressedSerialType(unsigned int);
+void describeUVParametrization(BitByBitData&);
+void describeSurfNURBS(BitByBitData&);
+void describeSurfCylinder(BitByBitData&);
+void describeSurfPlane(BitByBitData&);
+void describeTopoFace(BitByBitData&);
+void describeTopoLoop(BitByBitData&);
+void describeTopoCoEdge(BitByBitData&);
+void describeTopoEdge(BitByBitData&);
+void describeTopoConnex(BitByBitData&);
+void describeTopoShell(BitByBitData&);
+void describeObject(BitByBitData&);
+void describeBaseTopology(BitByBitData&);
+void describeBaseGeometry(BitByBitData&);
+unsigned int describeContentBody(BitByBitData&);
+void describeContentSurface(BitByBitData&);
+void describeBody(BitByBitData&);
+void describeTopoContext(BitByBitData&);
+void describeLineAttr(BitByBitData&);
+void describeArrayRGBA(BitByBitData&,int,int);
+void describeContentBaseTessData(BitByBitData&);
+void describeTessFace(BitByBitData&);
+void describe3DTess(BitByBitData&);
+void describe3DWireTess(BitByBitData&);
+void describe3DMarkupTess(BitByBitData&);
+void describeHighlyCompressed3DTess(BitByBitData&);
+void describeSceneDisplayParameters(BitByBitData&);
+void describeCartesionTransformation3d(BitByBitData&);
+void describeTransformation3d(BitByBitData&);
+void describeTransformation2d(BitByBitData&);
+void describeFileStructureInternalData(BitByBitData&);
+void describeProductOccurrence(BitByBitData&);
+void describeRepresentationItemContent(BitByBitData&);
+void describeMarkups(BitByBitData&);
+void describeAnnotationView(BitByBitData&);
+void describeExtent3d(BitByBitData&);
+void describeExtent2d(BitByBitData&);
+void describeExtent1d(BitByBitData&);
+void describeVector3d(BitByBitData&);
+void describeVector2d(BitByBitData&);
+void describeContentPRCBaseWithGraphics(BitByBitData&,bool);
+void describeGraphics(BitByBitData&);
+void describePartDefinition(BitByBitData&);
+void describeRGBColour(BitByBitData&);
+void describeSchema(BitByBitData&);
+void describeName(BitByBitData&);
+void describeAttributes(BitByBitData&);
+void describeContentPRCBase(BitByBitData&,bool);
+void describeUnit(BitByBitData&);
+void describeCompressedUniqueID(BitByBitData&);
+void describeUserData(BitByBitData&);
+
+extern std::string currentName;
+extern int layer_index;
+extern int index_of_line_style;
+extern unsigned short behaviour_bit_field;
+
+void unFlushSerialization();
+void resetCurrentGraphics();
+
+bool checkSectionCode(BitByBitData&,unsigned int);
+
+std::string getIndent();
+void indent();
+void dedent();
+
+#endif // __DESCRIBE_PRC_H
diff --git a/graphics/asymptote/prc/PRCTools/extractSections.cc b/graphics/asymptote/prc/PRCTools/extractSections.cc
new file mode 100644
index 0000000000..865f159698
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/extractSections.cc
@@ -0,0 +1,46 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include "iPRCFile.h"
+
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+
+ iPRCFile myFile(inFile);
+ string name(argv[1]);
+ myFile.dumpSections(name.substr(0,name.find(".")).c_str());
+
+ return 0;
+}
diff --git a/graphics/asymptote/prc/PRCTools/iPRCFile.cc b/graphics/asymptote/prc/PRCTools/iPRCFile.cc
new file mode 100644
index 0000000000..02967a5478
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/iPRCFile.cc
@@ -0,0 +1,220 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "bitData.h"
+#include "iPRCFile.h"
+#include "describePRC.h"
+
+using std::vector; using std::istream; using std::ios;
+using std::cout; using std::endl; using std::cerr;
+using std::string;
+
+using std::ofstream;
+using std::ostringstream;
+
+void iPRCFile::dumpSections(string prefix)
+{
+ ofstream out;
+
+ for(unsigned int i = 0; i < fileStructures.size(); ++i)
+ {
+ ostringstream name;
+ name << prefix << "Structure" << i;
+
+ out.open((name.str()+"-Globals.bin").c_str());
+ out.write(fileStructures[i].sections[GLOBALS_SECTION],fileStructures[i].sectionLengths[GLOBALS_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-Tree.bin").c_str());
+ out.write(fileStructures[i].sections[TREE_SECTION],fileStructures[i].sectionLengths[TREE_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-Tessellation.bin").c_str());
+ out.write(fileStructures[i].sections[TESSELLATION_SECTION],fileStructures[i].sectionLengths[TESSELLATION_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-Geometry.bin").c_str());
+ out.write(fileStructures[i].sections[GEOMETRY_SECTION],fileStructures[i].sectionLengths[GEOMETRY_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-ExtraGeometry.bin").c_str());
+ out.write(fileStructures[i].sections[EXTRA_GEOMETRY_SECTION],fileStructures[i].sectionLengths[EXTRA_GEOMETRY_SECTION]);
+ out.close();
+ }
+ out.open((prefix+"-ModelFile.bin").c_str());
+ out.write(modelFileData,modelFileLength);
+ out.close();
+}
+
+void iPRCFile::describe()
+{
+ /*
+ for(int i = 0; i < modelFileLength; ++i)
+ {
+ cout << ' ' << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(static_cast<unsigned char>(mfd.readChar()));
+ if(i%16 == 15)
+ cout << endl;
+ }
+ cout << endl;
+ */
+
+ unFlushSerialization();
+ for(unsigned int i = 0; i < fileStructures.size(); ++i)
+ {
+ cout << "File Structure " << i << ":" << endl;
+
+ //describe header
+ char *header = buffer + fileStructureInfos[i].offsets[0];
+ cout << "--Header Section--" << endl;
+ cout << " Signature " << header[0] << header[1] << header[2] << endl;
+ cout << " Minimal version for read " << *(unsigned int*)(header+3) << endl;
+ cout << " Authoring version " << *(unsigned int*)(header+7) << endl;
+ cout << std::hex;
+ cout << " File structure UUID " << *(unsigned int*)(header+11) << ' ' << *(unsigned int*)(header+15) << ' '
+ << *(unsigned int*)(header+19) << ' ' << *(unsigned int*)(header+23) << endl;
+ cout << " Application UUID " << *(unsigned int*)(header+27) << ' ' << *(unsigned int*)(header+31) << ' '
+ << *(unsigned int*)(header+35) << ' ' << *(unsigned int*)(header+39) << endl;
+ cout << std::dec;
+ // uncompressed files
+ unsigned int numberOfUncompressedFiles = *(unsigned int*)(header+43);
+ cout << "Number of uncompressed files " << numberOfUncompressedFiles << endl;
+ char *position = header+47;
+ for(unsigned int j = 0; j < numberOfUncompressedFiles; ++j)
+ {
+ cout << "Uncompressed file " << j << ":" << endl;
+ unsigned int size = *(unsigned int*)position;
+ cout << " size " << size << " bytes" << endl;
+ position += size+sizeof(unsigned int);
+ }
+
+ BitByBitData fileStruct(fileStructures[i].sections[GLOBALS_SECTION],fileStructures[i].sectionLengths[GLOBALS_SECTION]);
+ describeSchema(fileStruct);
+ describeGlobals(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[TREE_SECTION],fileStructures[i].sectionLengths[TREE_SECTION]);
+ describeTree(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[TESSELLATION_SECTION],fileStructures[i].sectionLengths[TESSELLATION_SECTION]);
+ describeTessellation(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[GEOMETRY_SECTION],fileStructures[i].sectionLengths[GEOMETRY_SECTION]);
+ describeGeometry(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[EXTRA_GEOMETRY_SECTION],fileStructures[i].sectionLengths[EXTRA_GEOMETRY_SECTION]);
+ describeExtraGeometry(fileStruct);
+ unFlushSerialization();
+ }
+
+ BitByBitData mfd(modelFileData,modelFileLength);
+
+ describeSchema(mfd);
+ describeModelFileData(mfd,fileStructures.size());
+ unFlushSerialization();
+}
+
+iPRCFile::iPRCFile(istream& in)
+{
+ char PRC[3];
+ in.read(PRC,3);
+ if(PRC[0] != 'P' || PRC[1] != 'R' || PRC[2] != 'C')
+ {
+ cerr << "Error: Invalid file format: PRC not found." << endl;
+ }
+ unsigned int versionForRead,authoringVersion;
+ in.read((char*)&versionForRead,sizeof(versionForRead));
+ in.read((char*)&authoringVersion,sizeof(authoringVersion));
+ cout << "Version for reading " << versionForRead << endl;
+ cout << "Authoring version " << authoringVersion << endl;
+ unsigned int fileStructureUUID[4];
+ in.read((char*)fileStructureUUID,sizeof(fileStructureUUID));
+ //(void*) is for formatting
+ cout << "File structure UUID " << (void*)(fileStructureUUID[0]) << ' ' << (void*)(fileStructureUUID[1]) << ' '
+ << (void*)(fileStructureUUID[2]) << ' ' << (void*)(fileStructureUUID[3]) << endl;
+ unsigned int applicationUUID[4];
+ in.read((char*)applicationUUID,sizeof(applicationUUID));
+ cout << "Application UUID " << (void*)(applicationUUID[0]) << ' ' << (void*)(applicationUUID[1]) << ' '
+ << (void*)(applicationUUID[2]) << ' ' << (void*)(applicationUUID[3]) << endl;
+ unsigned int numberOfFileStructures;
+ in.read((char*)&numberOfFileStructures,sizeof(numberOfFileStructures));
+ cout << "number of file structures " << numberOfFileStructures << endl;
+
+ // load fileStructureInformation
+ for(unsigned int fsi = 0; fsi < numberOfFileStructures; ++fsi)
+ {
+ FileStructureInformation info;
+ in.read((char*)&info.UUID,sizeof(info.UUID));
+ cout << "\tFile structure UUID " << (void*)(info.UUID[0]) << ' ' << (void*)(info.UUID[1]) << ' '
+ << (void*)(info.UUID[2]) << ' ' << (void*)(info.UUID[3]) << endl;
+
+ in.read((char*)&info.reserved,sizeof(info.reserved));
+ cout << "\tReserved " << info.reserved << endl;
+
+ unsigned int numberOfOffsets;
+ in.read((char*)&numberOfOffsets,sizeof(numberOfOffsets));
+ cout << "\tNumber of Offsets " << numberOfOffsets << endl;
+
+ for(unsigned int oi = 0; oi < numberOfOffsets; ++oi)
+ {
+ unsigned int offset;
+ in.read((char*)&offset,sizeof(offset));
+ info.offsets.push_back(offset);
+ cout << "\t\tOffset " << offset << endl;
+ }
+ fileStructureInfos.push_back(info);
+ }
+ in.read((char*)&modelFileOffset,sizeof(modelFileOffset));
+ cout << "Model file offset " << modelFileOffset << endl;
+ in.read((char*)&fileSize,sizeof(fileSize)); // this is not documented
+ cout << "File size " << fileSize << endl;
+
+ in.read((char*)&numberOfUncompressedFiles,sizeof(numberOfUncompressedFiles));
+ cout << "Number of uncompressed files " << numberOfUncompressedFiles << endl;
+ for(unsigned int ufi = 0; ufi < numberOfUncompressedFiles; ++ufi)
+ {
+ unsigned int size;
+ in.read((char*)&size,sizeof(size));
+ in.seekg(size,ios::cur);
+ }
+
+ //read the whole file into memory
+ in.seekg(0,ios::beg);
+ buffer = new char[fileSize];
+ if(!buffer) cerr << "Couldn't get memory." << endl;
+ in.read(buffer,fileSize);
+ //decompress fileStructures
+ for(unsigned int fs = 0; fs < fileStructureInfos.size(); ++fs)
+ {
+ fileStructures.push_back(FileStructure());
+ for(unsigned int i = 1; i < fileStructureInfos[fs].offsets.size(); ++i) // start at 1 since header is decompressed
+ {
+ fileStructures[fs].sections[i-1] = NULL;
+ unsigned int offset = fileStructureInfos[fs].offsets[i];
+ fileStructures[fs].sectionLengths[i-1] = decompress(buffer+offset,fileSize-offset,fileStructures[fs].sections[i-1]);
+ }
+ }
+
+ //decompress modelFileData
+ modelFileData = NULL;
+ modelFileLength = decompress(buffer+modelFileOffset,fileSize-modelFileOffset,modelFileData);
+}
diff --git a/graphics/asymptote/prc/PRCTools/iPRCFile.h b/graphics/asymptote/prc/PRCTools/iPRCFile.h
new file mode 100644
index 0000000000..2622cb966d
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/iPRCFile.h
@@ -0,0 +1,88 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __READPRC_H
+#define __READPRC_H
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iomanip>
+#include "../PRC.h"
+#include "inflation.h"
+
+struct FileStructureInformation
+{
+ unsigned int UUID[4];
+ unsigned int reserved;
+ std::vector<unsigned int> offsets;
+};
+
+
+const int GLOBALS_SECTION = 0;
+const int TREE_SECTION = 1;
+const int TESSELLATION_SECTION = 2;
+const int GEOMETRY_SECTION = 3;
+const int EXTRA_GEOMETRY_SECTION = 4;
+
+struct FileStructure
+{
+ unsigned int readVersion;
+ unsigned int authoringVersion;
+ unsigned int fileUUID[4];
+ unsigned int appUUID[4];
+ char* sections[5];
+ unsigned int sectionLengths[5];
+};
+
+class iPRCFile
+{
+ public:
+ iPRCFile(std::istream&);
+
+ ~iPRCFile()
+ {
+ for(unsigned int i = 0; i < fileStructures.size(); ++i)
+ for(unsigned int j = 0; j < 5; ++j)
+ if(fileStructures[i].sections[j] != NULL)
+ free(fileStructures[i].sections[j]);
+ if(modelFileData!=NULL)
+ free(modelFileData);
+ if(buffer != 0)
+ delete[] buffer;
+ }
+
+ void describe();
+ void dumpSections(std::string);
+
+ private:
+ // header data
+ std::vector<FileStructureInformation> fileStructureInfos;
+ std::vector<FileStructure> fileStructures;
+ unsigned int modelFileOffset;
+ char* modelFileData;
+ unsigned int modelFileLength;
+ char *buffer;
+ unsigned int fileSize;
+ unsigned int numberOfUncompressedFiles;
+};
+#endif // __READPRC_H
diff --git a/graphics/asymptote/prc/PRCTools/inflation.cc b/graphics/asymptote/prc/PRCTools/inflation.cc
new file mode 100644
index 0000000000..1b2d3c9686
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/inflation.cc
@@ -0,0 +1,90 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "inflation.h"
+
+using std::istream;
+using std::ios;
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::exit;
+
+int decompress(char* inb, int fileLength, char* &outb)
+{
+ const int CHUNK = 16384;
+ unsigned int resultSize = 0;
+
+ outb = (char*) realloc(outb,CHUNK);
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.avail_in = fileLength;
+ strm.next_in = (unsigned char*)inb;
+ strm.opaque = Z_NULL;
+ int code = inflateInit(&strm);
+
+ if(code != Z_OK)
+ return -1;
+
+ strm.next_out = (unsigned char*)outb;
+ strm.avail_out = CHUNK;
+ code = inflate(&strm,Z_NO_FLUSH);
+ resultSize = CHUNK-strm.avail_out;
+
+ unsigned int size = CHUNK;
+ while(code == Z_OK)
+ {
+ outb = (char*) realloc(outb,2*size);
+ if(outb == NULL)
+ {
+ cerr << "Ran out of memory while decompressing." << endl;
+ exit(1);
+ }
+ strm.next_out = (Bytef*)(outb + resultSize);
+ strm.avail_out += size;
+ size *= 2;
+ code = inflate(&strm,Z_NO_FLUSH);
+ resultSize = size - strm.avail_out;
+ }
+
+ code = inflateEnd(&strm);
+ if(code != Z_OK)
+ {
+ free(outb);
+ return 0;
+ }
+
+ return resultSize;
+}
+
+int decompress(istream &input,char* &result)
+{
+ input.seekg(0,ios::end);
+ int fileLength = input.tellg();
+ input.seekg(0,ios::beg);
+
+ char *inb = new char[fileLength];
+ input.read(inb,fileLength);
+
+ int code = decompress(inb,fileLength,result);
+ delete[] inb;
+ return code;
+}
diff --git a/graphics/asymptote/prc/PRCTools/inflation.h b/graphics/asymptote/prc/PRCTools/inflation.h
new file mode 100644
index 0000000000..79d29caa7f
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/inflation.h
@@ -0,0 +1,31 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __INFLATION_H
+#define __INFLATION_H
+
+#include <iostream>
+#include <cstdlib>
+#include <zlib.h>
+
+int decompress(std::istream&,char*&);
+int decompress(char*,int,char*&);
+
+#endif // __INFLATION_H
diff --git a/graphics/asymptote/prc/PRCTools/inflationMain.cc b/graphics/asymptote/prc/PRCTools/inflationMain.cc
new file mode 100644
index 0000000000..81beefd26d
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/inflationMain.cc
@@ -0,0 +1,55 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <cstdlib>
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include "inflation.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "No file specified." << endl;
+ return 1;
+ }
+
+ ifstream data(argv[1]);
+
+ char *buff = NULL;
+ int dataSize = decompress(data,buff);
+
+ cout << hex;
+
+ for(int i = 0; i < dataSize; ++i)
+ {
+ cout << ' ' << setw(2) << setfill('0')
+ << static_cast<unsigned int>(static_cast<unsigned char>(buff[i]));
+ if(i%16 == 15)
+ cout << endl;
+ }
+ cout << endl << dec << dataSize << " bytes" << endl;
+ free(buff);
+
+ return 0;
+}
diff --git a/graphics/asymptote/prc/PRCTools/makePRC.cc b/graphics/asymptote/prc/PRCTools/makePRC.cc
new file mode 100644
index 0000000000..f757300020
--- /dev/null
+++ b/graphics/asymptote/prc/PRCTools/makePRC.cc
@@ -0,0 +1,187 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <unistd.h>
+#include <cstdlib>
+#include "../oPRCFile.h"
+
+using namespace std;
+
+void readPoints(istream &is, unsigned int n, double p[][3])
+{
+ for(unsigned int i = 0; i < n; ++i)
+ {
+ is >> p[i][0] >> p[i][1] >> p[i][2];
+ }
+ if(!is)
+ {
+ cerr << "Error reading list of points." << endl;
+ exit(1);
+ }
+}
+
+void readDoubles(istream &is, unsigned int n, double d[])
+{
+ for(unsigned int i = 0; i < n; ++i)
+ {
+ is >> d[i];
+ }
+ if(!is)
+ {
+ cerr << "Error reading list of doubles." << endl;
+ exit(1);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ const char *oFileName = "output.prc";
+
+ int c;
+ opterr = 0;
+ while ((c = getopt (argc, argv, "o:")) != -1)
+ switch (c)
+ {
+ case 'o':
+ oFileName = optarg;
+ break;
+ case '?':
+ if (optopt == 'o')
+ cerr << "Option '-o' requires an argument, the filename." << endl;
+ else
+ cerr << "Unrecognized option '-" << (char)optopt << "'." << endl;
+ exit(1);
+ break;
+ default:
+ exit(1);
+ }
+ istream *ins = NULL;
+ if(optind < argc)
+ {
+ ins = new ifstream(argv[optind]);
+ if(!*ins)
+ {
+ cerr << "Error opening input file " << argv[optind] << endl;
+ exit(1);
+ }
+ }
+ else
+ {
+ ins = &cin;
+ }
+
+ ofstream outf(oFileName);
+ if(!outf)
+ {
+ cerr << "Error opening output file " << oFileName << endl;
+ exit(1);
+ }
+
+ oPRCFile oPRC(outf);
+
+ string entityType;
+ while(*ins)
+ {
+ *ins >> entityType;
+ if(!*ins) break;
+ if(entityType == "Line")
+ {
+ double r,g,b,a;
+ unsigned int numberOfPoints;
+ *ins >> r >> g >> b >> a >> numberOfPoints;
+ if(!*ins)
+ {
+ cerr << "Error reading line data." << endl;
+ exit(1);
+ }
+ else
+ {
+ double (*points)[3] = new double[numberOfPoints][3];
+ readPoints(*ins,numberOfPoints,points);
+ oPRC.add(new PRCline(&oPRC,numberOfPoints,points,
+ *new RGBAColour(r,g,b,a)));
+ }
+ }
+ else if(entityType == "Curve")
+ {
+ double r,g,b,a;
+ unsigned int numberOfPoints;
+ unsigned int degree;
+ *ins >> r >> g >> b >> a >> degree >> numberOfPoints;
+ if(!*ins)
+ {
+ cerr << "Error reading curve data." << endl;
+ exit(1);
+ }
+ else
+ {
+ double (*points)[3] = new double[numberOfPoints][3];
+ double *knots = new double[degree+numberOfPoints+1];
+ readPoints(*ins,numberOfPoints,points);
+ readDoubles(*ins,degree+numberOfPoints+1,knots);
+ oPRC.add(new PRCcurve(&oPRC,degree,numberOfPoints,points,
+ knots,*new RGBAColour(r,g,b,a)));
+ }
+ }
+ else if(entityType == "Surface")
+ {
+ double r,g,b,a;
+ unsigned int numberOfPointsU,numberOfPointsV;
+ unsigned int degreeU,degreeV;
+ *ins >> r >> g >> b >> a >> degreeU >> degreeV >> numberOfPointsU
+ >> numberOfPointsV;
+ if(!*ins)
+ {
+ cerr << "Error reading surface data." << endl;
+ exit(1);
+ }
+ else
+ {
+ double (*points)[3] = new double[numberOfPointsU*numberOfPointsV][3];
+ double *knotsU = new double[degreeU+numberOfPointsU+1];
+ double *knotsV = new double[degreeV+numberOfPointsV+1];
+ readPoints(*ins,numberOfPointsU*numberOfPointsV,points);
+ readDoubles(*ins,degreeU+numberOfPointsU+1,knotsU);
+ readDoubles(*ins,degreeV+numberOfPointsV+1,knotsV);
+ oPRC.add(new PRCsurface(&oPRC,degreeU,degreeV,numberOfPointsU,
+ numberOfPointsV,points,knotsU,knotsV,
+ *new RGBAColour(r,g,b,a)));
+ }
+ }
+ else
+ {
+ cerr << "Unrecognized entity type " << entityType << endl;
+ exit(1);
+ }
+ }
+
+ if(ins && ins != &cin)
+ delete ins;
+
+
+ oPRC.finish();
+
+ outf.close();
+
+ return 0;
+}
diff --git a/graphics/asymptote/prc/PRCbitStream.cc b/graphics/asymptote/prc/PRCbitStream.cc
new file mode 100644
index 0000000000..9b18186a46
--- /dev/null
+++ b/graphics/asymptote/prc/PRCbitStream.cc
@@ -0,0 +1,404 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com> and
+* Michail Vidiassov <master@iaas.msu.ru>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <zlib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cassert>
+#include "PRCbitStream.h"
+#include "PRCdouble.h"
+
+using std::string;
+using std::cerr;
+using std::endl;
+
+void PRCbitStream::compress()
+{
+ const int CHUNK= 1024; // is this reasonable?
+ compressedDataSize = 0;
+
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK)
+ {
+ cerr << "Compression initialization failed" << endl;
+ return;
+ }
+ unsigned int sizeAvailable = deflateBound(&strm,getSize());
+ uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable);
+ strm.avail_in = getSize();
+ strm.next_in = (unsigned char*)data;
+ strm.next_out = (unsigned char*)compressedData;
+ strm.avail_out = sizeAvailable;
+
+ int code;
+ unsigned int chunks = 0;
+ while((code = deflate(&strm,Z_FINISH)) == Z_OK)
+ {
+ ++chunks;
+ // strm.avail_out should be 0 if we got Z_OK
+ compressedDataSize = sizeAvailable - strm.avail_out;
+ compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks);
+ strm.next_out = (Bytef*)(compressedData + compressedDataSize);
+ strm.avail_out += CHUNK;
+ sizeAvailable += CHUNK;
+ }
+ compressedDataSize = sizeAvailable-strm.avail_out;
+
+ if(code != Z_STREAM_END)
+ {
+ cerr << "Compression error" << endl;
+ deflateEnd(&strm);
+ free(compressedData);
+ return;
+ }
+
+ compressed = true;
+
+ free(data);
+ data = compressedData;
+
+ deflateEnd(&strm);
+}
+
+void PRCbitStream::write(std::ostream &out) const
+{
+ if(compressed)
+ {
+ out.write((char*)data,compressedDataSize);
+ }
+ else
+ {
+ cerr << "Attempt to write stream before compression." << endl;
+ exit(1);
+ }
+}
+
+unsigned int PRCbitStream::getSize() const
+{
+ if(compressed)
+ return compressedDataSize;
+ else
+ return byteIndex+1;
+}
+
+uint8_t* PRCbitStream::getData()
+{
+ return data;
+}
+
+PRCbitStream& PRCbitStream::operator <<(bool b)
+{
+ writeBit(b);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(uint32_t u)
+{
+ while(u != 0)
+ {
+ writeBit(1);
+ writeByte(u & 0xFF);
+ u >>= 8;
+ }
+ writeBit(0);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(uint8_t u)
+{
+ writeByte(u);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(int32_t i)
+{
+ uint8_t lastByte = 0;
+ //while(!((current value is 0 and last byte was positive) OR (current value is -1 and last value was negative)))
+ while(!(((i == 0)&&((lastByte & 0x80)==0))||((i == -1)&&((lastByte & 0x80) != 0))))
+ {
+ writeBit(1);
+ lastByte = i & 0xFF;
+ writeByte(lastByte);
+ i >>= 8;
+ }
+ writeBit(0);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(double value)
+{
+ // write a double
+ if(compressed)
+ {
+ cerr << "Cannot write to a stream that has been compressed." << endl;
+ return *this;
+ }
+ union ieee754_double *pid=(union ieee754_double *)&value;
+ int
+ i,
+ fSaveAtEnd;
+ PRCbyte
+ *pb,
+ *pbStart,
+ *pbStop,
+ *pbEnd,
+ *pbResult,
+ bSaveAtEnd = 0;
+ struct sCodageOfFrequentDoubleOrExponent
+ cofdoe,
+ *pcofdoe;
+
+ cofdoe.u2uod.Value=value;
+ pcofdoe = (struct sCodageOfFrequentDoubleOrExponent *)bsearch(
+ &cofdoe,
+ acofdoe,
+ sizeof(acofdoe)/sizeof(pcofdoe[0]),
+ sizeof(pcofdoe[0]),
+ stCOFDOECompare);
+
+ while(pcofdoe>acofdoe && EXPONENT(pcofdoe->u2uod.Value)==EXPONENT((pcofdoe-1)->u2uod.Value))
+ pcofdoe--;
+
+ assert(pcofdoe);
+ while(pcofdoe->Type==VT_double)
+ {
+ if(fabs(value)==pcofdoe->u2uod.Value)
+ break;
+ pcofdoe++;
+ }
+
+ for(i=1<<(pcofdoe->NumberOfBits-1);i>=1;i>>=1)
+ writeBit((pcofdoe->Bits&i)!=0);
+
+ if
+ (
+ !memcmp(&value,stadwZero,sizeof(value))
+ || !memcmp(&value,stadwNegativeZero,sizeof(value))
+ )
+ return *this;
+
+ writeBit(pid->ieee.negative);
+
+ if(pcofdoe->Type==VT_double)
+ return *this;
+
+ if(pid->ieee.mantissa0==0 && pid->ieee.mantissa1==0)
+ {
+ writeBit(0);
+ return *this;
+ }
+
+ writeBit(1);
+
+#ifdef WORDS_BIGENDIAN
+ pb=((PRCbyte *)&value)+1;
+#else
+ pb=((PRCbyte *)&value)+6;
+#endif
+ //add_bits((*pb)&0x0f,4 STAT_V STAT_DOUBLE);
+ writeBits((*pb)&0x0F,4);
+
+ NEXTBYTE(pb);
+ pbStart=pb;
+#ifdef WORDS_BIGENDIAN
+ pbEnd=
+ pbStop= ((PRCbyte *)(&value+1))-1;
+#else
+ pbEnd=
+ pbStop= ((PRCbyte *)&value);
+#endif
+
+ if((fSaveAtEnd=(*pbStop!=*BEFOREBYTE(pbStop)))!=0)
+ bSaveAtEnd=*pbEnd;
+ PREVIOUSBYTE(pbStop);
+
+ while(*pbStop==*BEFOREBYTE(pbStop))
+ PREVIOUSBYTE(pbStop);
+
+ for(;MOREBYTE(pb,pbStop);NEXTBYTE(pb))
+ {
+ if(pb!=pbStart && (pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL)
+ {
+ writeBit(0);
+ writeBits(DIFFPOINTERS(pb,pbResult),3);
+ }
+ else
+ {
+ writeBit(1);
+ writeByte(*pb);
+ }
+ }
+
+ if(!MOREBYTE(BEFOREBYTE(pbEnd),pbStop))
+ {
+ if(fSaveAtEnd)
+ {
+ writeBit(0);
+ writeBits(6,3);
+ writeByte(bSaveAtEnd);
+ }
+ else
+ {
+ writeBit(0);
+ writeBits(0,3);
+ }
+ }
+ else
+ {
+ if((pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL)
+ {
+ writeBit(0);
+ writeBits(DIFFPOINTERS(pb,pbResult),3);
+ }
+ else
+ {
+ writeBit(1);
+ writeByte(*pb);
+ }
+ }
+
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(const char* s)
+{
+ if (s == NULL)
+ {
+ writeBit(false); // string is NULL
+ return *this;
+ }
+ string str(s);
+ *this << str;
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(const string& s)
+{
+ if(s == "")
+ {
+ writeBit(false); // string is NULL
+ return *this;
+ }
+ writeBit(true);
+ size_t l = s.length();
+ *this << static_cast<uint32_t>(l);
+ for(size_t i = 0; i < l; ++i)
+ writeByte(s[i]);
+ return *this;
+}
+
+void PRCbitStream::writeBit(bool b)
+{
+ if(compressed)
+ {
+ cerr << "Cannot write to a stream that has been compressed." << endl;
+ return;
+ }
+
+ if(b)
+ {
+ data[byteIndex] |= (0x80 >> bitIndex);
+ }
+ nextBit();
+}
+
+void PRCbitStream::writeBits(uint32_t u, uint8_t bits)
+{
+ if(bits > 32)
+ return;
+ else
+ {
+ for(uint32_t mask = (1 << (bits-1)); mask != 0; mask >>= 1)
+ {
+ writeBit((u&mask) != 0);
+ }
+ }
+}
+
+void PRCbitStream::writeByte(uint8_t u)
+{
+ if(compressed)
+ {
+ cerr << "Cannot write to a stream that has been compressed." << endl;
+ return;
+ }
+
+ if(bitIndex == 0)
+ {
+ data[byteIndex] = u;
+ nextByte();
+ }
+ else
+ {
+ data[byteIndex] |= (u >> bitIndex);
+ unsigned int obi = bitIndex;
+ nextByte();
+ data[byteIndex] |= (u << (8-obi));
+ bitIndex = obi; // bit index is not changed by writing 8 bits
+ }
+}
+
+void PRCbitStream::nextBit()
+{
+ ++bitIndex;
+ if(bitIndex == 8)
+ {
+ nextByte();
+ }
+}
+
+void PRCbitStream::nextByte()
+{
+ ++byteIndex;
+ if(byteIndex >= allocatedLength)
+ getAChunk();
+ data[byteIndex] = 0; // clear the garbage data
+ bitIndex = 0;
+}
+
+void PRCbitStream::getAChunk()
+{
+ if(allocatedLength==0)
+ data = (uint8_t*)realloc((void*)data,CHUNK_SIZE);
+ else
+ data = (uint8_t*)realloc((void*)data,2*allocatedLength);
+
+ if(data != NULL)
+ {
+ if(allocatedLength==0)
+ {
+ allocatedLength = CHUNK_SIZE;
+ *data = 0; // clear first byte
+ }
+ else
+ allocatedLength *= 2;
+ }
+ else
+ {
+ // warn about memory problem!
+ cerr << "Memory allocation error." << endl;
+ exit(1);
+ }
+}
diff --git a/graphics/asymptote/prc/PRCbitStream.h b/graphics/asymptote/prc/PRCbitStream.h
new file mode 100644
index 0000000000..5f189e428b
--- /dev/null
+++ b/graphics/asymptote/prc/PRCbitStream.h
@@ -0,0 +1,87 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com> and
+* Michail Vidiassov <master@iaas.msu.ru>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __PRC_BIT_STREAM_H
+#define __PRC_BIT_STREAM_H
+
+#ifdef _MSC_VER
+#include <stdio.h>
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#endif // _MSC_VER >= 1600
+#else
+#include <inttypes.h>
+#endif // _MSC_VER
+#include <string>
+#include <iostream>
+#include <stdlib.h>
+
+#define CHUNK_SIZE (1024)
+// Is this a reasonable initial size?
+
+class PRCbitStream
+{
+ public:
+ PRCbitStream(uint8_t*& buff, unsigned int l) : byteIndex(0), bitIndex(0),
+ allocatedLength(l), data(buff), compressed(false)
+ {
+ if(data == 0)
+ {
+ getAChunk();
+ }
+ }
+
+ unsigned int getSize() const;
+ uint8_t* getData();
+
+ PRCbitStream& operator <<(const std::string&);
+ PRCbitStream& operator <<(bool);
+ PRCbitStream& operator <<(uint32_t);
+ PRCbitStream& operator <<(uint8_t);
+ PRCbitStream& operator <<(int32_t);
+ PRCbitStream& operator <<(double);
+ PRCbitStream& operator <<(const char*);
+
+ void compress();
+ void write(std::ostream &out) const;
+ private:
+ void writeBit(bool);
+ void writeBits(uint32_t,uint8_t);
+ void writeByte(uint8_t);
+ void nextByte();
+ void nextBit();
+ void getAChunk();
+ // bitIndex is "big endian", zero based, location of next bit to write
+ unsigned int byteIndex,bitIndex;
+ unsigned int allocatedLength;
+ uint8_t*& data;
+ bool compressed;
+ uint32_t compressedDataSize;
+};
+
+#endif // __PRC_BIT_STREAM_H
diff --git a/graphics/asymptote/prc/PRCdouble.cc b/graphics/asymptote/prc/PRCdouble.cc
new file mode 100644
index 0000000000..69d4b02f16
--- /dev/null
+++ b/graphics/asymptote/prc/PRCdouble.cc
@@ -0,0 +1,2121 @@
+#include "PRCdouble.h"
+
+// from Adobe's documentation
+
+PRCdword stadwZero[2]={DOUBLEWITHTWODWORD(0x00000000,0x00000000)};
+PRCdword stadwNegativeZero[2]={DOUBLEWITHTWODWORD(0x80000000,0x00000000)};
+
+struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned Bits, short NumberOfBits)
+{
+ struct sCodageOfFrequentDoubleOrExponent *pcofdoe;
+ for(pcofdoe=acofdoe; pcofdoe < acofdoe+NUMBEROFELEMENTINACOFDOE; ++pcofdoe)
+ {
+ if(pcofdoe->NumberOfBits == NumberOfBits && pcofdoe->Bits == Bits)
+ return pcofdoe;
+ }
+ return NULL;
+}
+
+int stCOFDOECompare(const void* pcofdoe1,const void* pcofdoe2)
+{
+ return(EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe1)->u2uod.Value)-
+ EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe2)->u2uod.Value));
+}
+
+#ifdef WORDS_BIGENDIAN
+#ifndef HAVE_MEMRCHR
+void *memrchr(const void *buf,int c,size_t count)
+{
+ unsigned char
+ *pcBuffer=(unsigned char *)buf,
+ *pcBufferEnd=pcBuffer-count;
+
+ for(;pcBuffer>pcBufferEnd;pcBuffer--)
+ if(*pcBuffer==c)
+ return(pcBuffer);
+
+ return(NULL);
+}
+#endif
+#endif
+
+sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE] =
+{
+ {VT_double,2,0x1,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}},
+ {VT_exponent,22,0xd1d32,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}},
+ {VT_exponent,22,0xd1d33,{DOUBLEWITHTWODWORDINTREE(0x00100000,0x00000000)}},
+ {VT_exponent,22,0xf78d8,{DOUBLEWITHTWODWORDINTREE(0x00200000,0x00000000)}},
+ {VT_exponent,22,0xf78d9,{DOUBLEWITHTWODWORDINTREE(0x00300000,0x00000000)}},
+ {VT_exponent,22,0xf78da,{DOUBLEWITHTWODWORDINTREE(0x00400000,0x00000000)}},
+ {VT_exponent,22,0xf78db,{DOUBLEWITHTWODWORDINTREE(0x00500000,0x00000000)}},
+ {VT_exponent,22,0xf78dc,{DOUBLEWITHTWODWORDINTREE(0x00600000,0x00000000)}},
+ {VT_exponent,22,0xf78dd,{DOUBLEWITHTWODWORDINTREE(0x00700000,0x00000000)}},
+ {VT_exponent,22,0xf78de,{DOUBLEWITHTWODWORDINTREE(0x00800000,0x00000000)}},
+ {VT_exponent,22,0xf78df,{DOUBLEWITHTWODWORDINTREE(0x00900000,0x00000000)}},
+ {VT_exponent,22,0xf78e0,{DOUBLEWITHTWODWORDINTREE(0x00a00000,0x00000000)}},
+ {VT_exponent,22,0xf78e1,{DOUBLEWITHTWODWORDINTREE(0x00b00000,0x00000000)}},
+ {VT_exponent,22,0xf78e2,{DOUBLEWITHTWODWORDINTREE(0x00c00000,0x00000000)}},
+ {VT_exponent,22,0xf78e3,{DOUBLEWITHTWODWORDINTREE(0x00d00000,0x00000000)}},
+ {VT_exponent,22,0xf78e4,{DOUBLEWITHTWODWORDINTREE(0x00e00000,0x00000000)}},
+ {VT_exponent,22,0xf78e5,{DOUBLEWITHTWODWORDINTREE(0x00f00000,0x00000000)}},
+ {VT_exponent,22,0xf78e6,{DOUBLEWITHTWODWORDINTREE(0x01000000,0x00000000)}},
+ {VT_exponent,22,0xf78e7,{DOUBLEWITHTWODWORDINTREE(0x01100000,0x00000000)}},
+ {VT_exponent,22,0xf78e8,{DOUBLEWITHTWODWORDINTREE(0x01200000,0x00000000)}},
+ {VT_exponent,22,0xf78e9,{DOUBLEWITHTWODWORDINTREE(0x01300000,0x00000000)}},
+ {VT_exponent,22,0xf78ea,{DOUBLEWITHTWODWORDINTREE(0x01400000,0x00000000)}},
+ {VT_exponent,22,0xf78eb,{DOUBLEWITHTWODWORDINTREE(0x01500000,0x00000000)}},
+ {VT_exponent,22,0xf78ec,{DOUBLEWITHTWODWORDINTREE(0x01600000,0x00000000)}},
+ {VT_exponent,22,0xf78ed,{DOUBLEWITHTWODWORDINTREE(0x01700000,0x00000000)}},
+ {VT_exponent,22,0xf78ee,{DOUBLEWITHTWODWORDINTREE(0x01800000,0x00000000)}},
+ {VT_exponent,22,0xf78ef,{DOUBLEWITHTWODWORDINTREE(0x01900000,0x00000000)}},
+ {VT_exponent,22,0xf78f0,{DOUBLEWITHTWODWORDINTREE(0x01a00000,0x00000000)}},
+ {VT_exponent,22,0xf78f1,{DOUBLEWITHTWODWORDINTREE(0x01b00000,0x00000000)}},
+ {VT_exponent,22,0xf78f2,{DOUBLEWITHTWODWORDINTREE(0x01c00000,0x00000000)}},
+ {VT_exponent,22,0xf78f3,{DOUBLEWITHTWODWORDINTREE(0x01d00000,0x00000000)}},
+ {VT_exponent,22,0xf78f4,{DOUBLEWITHTWODWORDINTREE(0x01e00000,0x00000000)}},
+ {VT_exponent,22,0xf78f5,{DOUBLEWITHTWODWORDINTREE(0x01f00000,0x00000000)}},
+ {VT_exponent,22,0xf78f6,{DOUBLEWITHTWODWORDINTREE(0x02000000,0x00000000)}},
+ {VT_exponent,22,0xf78f7,{DOUBLEWITHTWODWORDINTREE(0x02100000,0x00000000)}},
+ {VT_exponent,22,0xf78f8,{DOUBLEWITHTWODWORDINTREE(0x02200000,0x00000000)}},
+ {VT_exponent,22,0xf78f9,{DOUBLEWITHTWODWORDINTREE(0x02300000,0x00000000)}},
+ {VT_exponent,22,0xf78fa,{DOUBLEWITHTWODWORDINTREE(0x02400000,0x00000000)}},
+ {VT_exponent,22,0xf78fb,{DOUBLEWITHTWODWORDINTREE(0x02500000,0x00000000)}},
+ {VT_exponent,22,0xf78fc,{DOUBLEWITHTWODWORDINTREE(0x02600000,0x00000000)}},
+ {VT_exponent,22,0xf78fd,{DOUBLEWITHTWODWORDINTREE(0x02700000,0x00000000)}},
+ {VT_exponent,22,0xf78fe,{DOUBLEWITHTWODWORDINTREE(0x02800000,0x00000000)}},
+ {VT_exponent,22,0xf78ff,{DOUBLEWITHTWODWORDINTREE(0x02900000,0x00000000)}},
+ {VT_exponent,22,0x3a8300,{DOUBLEWITHTWODWORDINTREE(0x02a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8301,{DOUBLEWITHTWODWORDINTREE(0x02b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8302,{DOUBLEWITHTWODWORDINTREE(0x02c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8303,{DOUBLEWITHTWODWORDINTREE(0x02d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8304,{DOUBLEWITHTWODWORDINTREE(0x02e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8305,{DOUBLEWITHTWODWORDINTREE(0x02f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8306,{DOUBLEWITHTWODWORDINTREE(0x03000000,0x00000000)}},
+ {VT_exponent,22,0x3a8307,{DOUBLEWITHTWODWORDINTREE(0x03100000,0x00000000)}},
+ {VT_exponent,22,0x3a8308,{DOUBLEWITHTWODWORDINTREE(0x03200000,0x00000000)}},
+ {VT_exponent,22,0x3a8309,{DOUBLEWITHTWODWORDINTREE(0x03300000,0x00000000)}},
+ {VT_exponent,22,0x3a830a,{DOUBLEWITHTWODWORDINTREE(0x03400000,0x00000000)}},
+ {VT_exponent,22,0x3a830b,{DOUBLEWITHTWODWORDINTREE(0x03500000,0x00000000)}},
+ {VT_exponent,22,0x3a830c,{DOUBLEWITHTWODWORDINTREE(0x03600000,0x00000000)}},
+ {VT_exponent,22,0x3a830d,{DOUBLEWITHTWODWORDINTREE(0x03700000,0x00000000)}},
+ {VT_exponent,22,0x3a830e,{DOUBLEWITHTWODWORDINTREE(0x03800000,0x00000000)}},
+ {VT_exponent,22,0x3a830f,{DOUBLEWITHTWODWORDINTREE(0x03900000,0x00000000)}},
+ {VT_exponent,22,0x3a8310,{DOUBLEWITHTWODWORDINTREE(0x03a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8311,{DOUBLEWITHTWODWORDINTREE(0x03b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8312,{DOUBLEWITHTWODWORDINTREE(0x03c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8313,{DOUBLEWITHTWODWORDINTREE(0x03d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8314,{DOUBLEWITHTWODWORDINTREE(0x03e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8315,{DOUBLEWITHTWODWORDINTREE(0x03f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8316,{DOUBLEWITHTWODWORDINTREE(0x04000000,0x00000000)}},
+ {VT_exponent,22,0x3a8317,{DOUBLEWITHTWODWORDINTREE(0x04100000,0x00000000)}},
+ {VT_exponent,22,0x3a8318,{DOUBLEWITHTWODWORDINTREE(0x04200000,0x00000000)}},
+ {VT_exponent,22,0x3a8319,{DOUBLEWITHTWODWORDINTREE(0x04300000,0x00000000)}},
+ {VT_exponent,22,0x3a831a,{DOUBLEWITHTWODWORDINTREE(0x04400000,0x00000000)}},
+ {VT_exponent,22,0x3a831b,{DOUBLEWITHTWODWORDINTREE(0x04500000,0x00000000)}},
+ {VT_exponent,22,0x3a831c,{DOUBLEWITHTWODWORDINTREE(0x04600000,0x00000000)}},
+ {VT_exponent,22,0x3a831d,{DOUBLEWITHTWODWORDINTREE(0x04700000,0x00000000)}},
+ {VT_exponent,22,0x3a831e,{DOUBLEWITHTWODWORDINTREE(0x04800000,0x00000000)}},
+ {VT_exponent,22,0x3a831f,{DOUBLEWITHTWODWORDINTREE(0x04900000,0x00000000)}},
+ {VT_exponent,22,0x3a8320,{DOUBLEWITHTWODWORDINTREE(0x04a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8321,{DOUBLEWITHTWODWORDINTREE(0x04b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8322,{DOUBLEWITHTWODWORDINTREE(0x04c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8323,{DOUBLEWITHTWODWORDINTREE(0x04d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8324,{DOUBLEWITHTWODWORDINTREE(0x04e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8325,{DOUBLEWITHTWODWORDINTREE(0x04f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8326,{DOUBLEWITHTWODWORDINTREE(0x05000000,0x00000000)}},
+ {VT_exponent,22,0x3a8327,{DOUBLEWITHTWODWORDINTREE(0x05100000,0x00000000)}},
+ {VT_exponent,22,0x3a8328,{DOUBLEWITHTWODWORDINTREE(0x05200000,0x00000000)}},
+ {VT_exponent,22,0x3a8329,{DOUBLEWITHTWODWORDINTREE(0x05300000,0x00000000)}},
+ {VT_exponent,22,0x3a832a,{DOUBLEWITHTWODWORDINTREE(0x05400000,0x00000000)}},
+ {VT_exponent,22,0x3a832b,{DOUBLEWITHTWODWORDINTREE(0x05500000,0x00000000)}},
+ {VT_exponent,22,0x3a832c,{DOUBLEWITHTWODWORDINTREE(0x05600000,0x00000000)}},
+ {VT_exponent,22,0x3a832d,{DOUBLEWITHTWODWORDINTREE(0x05700000,0x00000000)}},
+ {VT_exponent,22,0x3a832e,{DOUBLEWITHTWODWORDINTREE(0x05800000,0x00000000)}},
+ {VT_exponent,22,0x3a832f,{DOUBLEWITHTWODWORDINTREE(0x05900000,0x00000000)}},
+ {VT_exponent,22,0x3a8330,{DOUBLEWITHTWODWORDINTREE(0x05a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8331,{DOUBLEWITHTWODWORDINTREE(0x05b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8332,{DOUBLEWITHTWODWORDINTREE(0x05c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8333,{DOUBLEWITHTWODWORDINTREE(0x05d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8334,{DOUBLEWITHTWODWORDINTREE(0x05e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8335,{DOUBLEWITHTWODWORDINTREE(0x05f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8336,{DOUBLEWITHTWODWORDINTREE(0x06000000,0x00000000)}},
+ {VT_exponent,22,0x3a8337,{DOUBLEWITHTWODWORDINTREE(0x06100000,0x00000000)}},
+ {VT_exponent,22,0x3a8338,{DOUBLEWITHTWODWORDINTREE(0x06200000,0x00000000)}},
+ {VT_exponent,22,0x3a8339,{DOUBLEWITHTWODWORDINTREE(0x06300000,0x00000000)}},
+ {VT_exponent,22,0x3a833a,{DOUBLEWITHTWODWORDINTREE(0x06400000,0x00000000)}},
+ {VT_exponent,22,0x3a833b,{DOUBLEWITHTWODWORDINTREE(0x06500000,0x00000000)}},
+ {VT_exponent,22,0x3a833c,{DOUBLEWITHTWODWORDINTREE(0x06600000,0x00000000)}},
+ {VT_exponent,22,0x3a833d,{DOUBLEWITHTWODWORDINTREE(0x06700000,0x00000000)}},
+ {VT_exponent,22,0x3a833e,{DOUBLEWITHTWODWORDINTREE(0x06800000,0x00000000)}},
+ {VT_exponent,22,0x3a833f,{DOUBLEWITHTWODWORDINTREE(0x06900000,0x00000000)}},
+ {VT_exponent,22,0x3a8340,{DOUBLEWITHTWODWORDINTREE(0x06a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8341,{DOUBLEWITHTWODWORDINTREE(0x06b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8342,{DOUBLEWITHTWODWORDINTREE(0x06c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8343,{DOUBLEWITHTWODWORDINTREE(0x06d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8344,{DOUBLEWITHTWODWORDINTREE(0x06e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8345,{DOUBLEWITHTWODWORDINTREE(0x06f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8346,{DOUBLEWITHTWODWORDINTREE(0x07000000,0x00000000)}},
+ {VT_exponent,22,0x3a8347,{DOUBLEWITHTWODWORDINTREE(0x07100000,0x00000000)}},
+ {VT_exponent,22,0x3a8348,{DOUBLEWITHTWODWORDINTREE(0x07200000,0x00000000)}},
+ {VT_exponent,22,0x3a8349,{DOUBLEWITHTWODWORDINTREE(0x07300000,0x00000000)}},
+ {VT_exponent,22,0x3a834a,{DOUBLEWITHTWODWORDINTREE(0x07400000,0x00000000)}},
+ {VT_exponent,22,0x3a834b,{DOUBLEWITHTWODWORDINTREE(0x07500000,0x00000000)}},
+ {VT_exponent,22,0x3a834c,{DOUBLEWITHTWODWORDINTREE(0x07600000,0x00000000)}},
+ {VT_exponent,22,0x3a834d,{DOUBLEWITHTWODWORDINTREE(0x07700000,0x00000000)}},
+ {VT_exponent,22,0x3a834e,{DOUBLEWITHTWODWORDINTREE(0x07800000,0x00000000)}},
+ {VT_exponent,22,0x3a834f,{DOUBLEWITHTWODWORDINTREE(0x07900000,0x00000000)}},
+ {VT_exponent,22,0x3a8350,{DOUBLEWITHTWODWORDINTREE(0x07a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8351,{DOUBLEWITHTWODWORDINTREE(0x07b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8352,{DOUBLEWITHTWODWORDINTREE(0x07c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8353,{DOUBLEWITHTWODWORDINTREE(0x07d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8354,{DOUBLEWITHTWODWORDINTREE(0x07e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8355,{DOUBLEWITHTWODWORDINTREE(0x07f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8356,{DOUBLEWITHTWODWORDINTREE(0x08000000,0x00000000)}},
+ {VT_exponent,22,0x3a8357,{DOUBLEWITHTWODWORDINTREE(0x08100000,0x00000000)}},
+ {VT_exponent,22,0x3a8358,{DOUBLEWITHTWODWORDINTREE(0x08200000,0x00000000)}},
+ {VT_exponent,22,0x3a8359,{DOUBLEWITHTWODWORDINTREE(0x08300000,0x00000000)}},
+ {VT_exponent,22,0x3a835a,{DOUBLEWITHTWODWORDINTREE(0x08400000,0x00000000)}},
+ {VT_exponent,22,0x3a835b,{DOUBLEWITHTWODWORDINTREE(0x08500000,0x00000000)}},
+ {VT_exponent,22,0x3a835c,{DOUBLEWITHTWODWORDINTREE(0x08600000,0x00000000)}},
+ {VT_exponent,22,0x3a835d,{DOUBLEWITHTWODWORDINTREE(0x08700000,0x00000000)}},
+ {VT_exponent,22,0x3a835e,{DOUBLEWITHTWODWORDINTREE(0x08800000,0x00000000)}},
+ {VT_exponent,22,0x3a835f,{DOUBLEWITHTWODWORDINTREE(0x08900000,0x00000000)}},
+ {VT_exponent,22,0x3a8360,{DOUBLEWITHTWODWORDINTREE(0x08a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8361,{DOUBLEWITHTWODWORDINTREE(0x08b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8362,{DOUBLEWITHTWODWORDINTREE(0x08c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8363,{DOUBLEWITHTWODWORDINTREE(0x08d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8364,{DOUBLEWITHTWODWORDINTREE(0x08e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8365,{DOUBLEWITHTWODWORDINTREE(0x08f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8366,{DOUBLEWITHTWODWORDINTREE(0x09000000,0x00000000)}},
+ {VT_exponent,22,0x3a8367,{DOUBLEWITHTWODWORDINTREE(0x09100000,0x00000000)}},
+ {VT_exponent,22,0x3a8368,{DOUBLEWITHTWODWORDINTREE(0x09200000,0x00000000)}},
+ {VT_exponent,22,0x3a8369,{DOUBLEWITHTWODWORDINTREE(0x09300000,0x00000000)}},
+ {VT_exponent,22,0x3a836a,{DOUBLEWITHTWODWORDINTREE(0x09400000,0x00000000)}},
+ {VT_exponent,22,0x3a836b,{DOUBLEWITHTWODWORDINTREE(0x09500000,0x00000000)}},
+ {VT_exponent,22,0x3a836c,{DOUBLEWITHTWODWORDINTREE(0x09600000,0x00000000)}},
+ {VT_exponent,22,0x3a836d,{DOUBLEWITHTWODWORDINTREE(0x09700000,0x00000000)}},
+ {VT_exponent,22,0x3a836e,{DOUBLEWITHTWODWORDINTREE(0x09800000,0x00000000)}},
+ {VT_exponent,22,0x3a836f,{DOUBLEWITHTWODWORDINTREE(0x09900000,0x00000000)}},
+ {VT_exponent,22,0x3a8370,{DOUBLEWITHTWODWORDINTREE(0x09a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8371,{DOUBLEWITHTWODWORDINTREE(0x09b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8372,{DOUBLEWITHTWODWORDINTREE(0x09c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8373,{DOUBLEWITHTWODWORDINTREE(0x09d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8374,{DOUBLEWITHTWODWORDINTREE(0x09e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8375,{DOUBLEWITHTWODWORDINTREE(0x09f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8376,{DOUBLEWITHTWODWORDINTREE(0x0a000000,0x00000000)}},
+ {VT_exponent,22,0x3a8377,{DOUBLEWITHTWODWORDINTREE(0x0a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8378,{DOUBLEWITHTWODWORDINTREE(0x0a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8379,{DOUBLEWITHTWODWORDINTREE(0x0a300000,0x00000000)}},
+ {VT_exponent,22,0x3a837a,{DOUBLEWITHTWODWORDINTREE(0x0a400000,0x00000000)}},
+ {VT_exponent,22,0x3a837b,{DOUBLEWITHTWODWORDINTREE(0x0a500000,0x00000000)}},
+ {VT_exponent,22,0x3a837c,{DOUBLEWITHTWODWORDINTREE(0x0a600000,0x00000000)}},
+ {VT_exponent,22,0x3a837d,{DOUBLEWITHTWODWORDINTREE(0x0a700000,0x00000000)}},
+ {VT_exponent,22,0x3a837e,{DOUBLEWITHTWODWORDINTREE(0x0a800000,0x00000000)}},
+ {VT_exponent,22,0x3a837f,{DOUBLEWITHTWODWORDINTREE(0x0a900000,0x00000000)}},
+ {VT_exponent,22,0x3a8380,{DOUBLEWITHTWODWORDINTREE(0x0aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a8381,{DOUBLEWITHTWODWORDINTREE(0x0ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a8382,{DOUBLEWITHTWODWORDINTREE(0x0ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a8383,{DOUBLEWITHTWODWORDINTREE(0x0ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a8384,{DOUBLEWITHTWODWORDINTREE(0x0ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a8385,{DOUBLEWITHTWODWORDINTREE(0x0af00000,0x00000000)}},
+ {VT_exponent,22,0x3a8386,{DOUBLEWITHTWODWORDINTREE(0x0b000000,0x00000000)}},
+ {VT_exponent,22,0x3a8387,{DOUBLEWITHTWODWORDINTREE(0x0b100000,0x00000000)}},
+ {VT_exponent,22,0x3a8388,{DOUBLEWITHTWODWORDINTREE(0x0b200000,0x00000000)}},
+ {VT_exponent,22,0x3a8389,{DOUBLEWITHTWODWORDINTREE(0x0b300000,0x00000000)}},
+ {VT_exponent,22,0x3a838a,{DOUBLEWITHTWODWORDINTREE(0x0b400000,0x00000000)}},
+ {VT_exponent,22,0x3a838b,{DOUBLEWITHTWODWORDINTREE(0x0b500000,0x00000000)}},
+ {VT_exponent,22,0x3a838c,{DOUBLEWITHTWODWORDINTREE(0x0b600000,0x00000000)}},
+ {VT_exponent,22,0x3a838d,{DOUBLEWITHTWODWORDINTREE(0x0b700000,0x00000000)}},
+ {VT_exponent,22,0x3a838e,{DOUBLEWITHTWODWORDINTREE(0x0b800000,0x00000000)}},
+ {VT_exponent,22,0x3a838f,{DOUBLEWITHTWODWORDINTREE(0x0b900000,0x00000000)}},
+ {VT_exponent,22,0x3a8390,{DOUBLEWITHTWODWORDINTREE(0x0ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a8391,{DOUBLEWITHTWODWORDINTREE(0x0bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a8392,{DOUBLEWITHTWODWORDINTREE(0x0bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a8393,{DOUBLEWITHTWODWORDINTREE(0x0bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a8394,{DOUBLEWITHTWODWORDINTREE(0x0be00000,0x00000000)}},
+ {VT_exponent,22,0x3a8395,{DOUBLEWITHTWODWORDINTREE(0x0bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a8396,{DOUBLEWITHTWODWORDINTREE(0x0c000000,0x00000000)}},
+ {VT_exponent,22,0x3a8397,{DOUBLEWITHTWODWORDINTREE(0x0c100000,0x00000000)}},
+ {VT_exponent,22,0x3a8398,{DOUBLEWITHTWODWORDINTREE(0x0c200000,0x00000000)}},
+ {VT_exponent,22,0x3a8399,{DOUBLEWITHTWODWORDINTREE(0x0c300000,0x00000000)}},
+ {VT_exponent,22,0x3a839a,{DOUBLEWITHTWODWORDINTREE(0x0c400000,0x00000000)}},
+ {VT_exponent,22,0x3a839b,{DOUBLEWITHTWODWORDINTREE(0x0c500000,0x00000000)}},
+ {VT_exponent,22,0x3a839c,{DOUBLEWITHTWODWORDINTREE(0x0c600000,0x00000000)}},
+ {VT_exponent,22,0x3a839d,{DOUBLEWITHTWODWORDINTREE(0x0c700000,0x00000000)}},
+ {VT_exponent,22,0x3a839e,{DOUBLEWITHTWODWORDINTREE(0x0c800000,0x00000000)}},
+ {VT_exponent,22,0x3a839f,{DOUBLEWITHTWODWORDINTREE(0x0c900000,0x00000000)}},
+ {VT_exponent,22,0x3a83a0,{DOUBLEWITHTWODWORDINTREE(0x0ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a1,{DOUBLEWITHTWODWORDINTREE(0x0cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a2,{DOUBLEWITHTWODWORDINTREE(0x0cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a3,{DOUBLEWITHTWODWORDINTREE(0x0cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a4,{DOUBLEWITHTWODWORDINTREE(0x0ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a5,{DOUBLEWITHTWODWORDINTREE(0x0cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a6,{DOUBLEWITHTWODWORDINTREE(0x0d000000,0x00000000)}},
+ {VT_exponent,22,0x3a83a7,{DOUBLEWITHTWODWORDINTREE(0x0d100000,0x00000000)}},
+ {VT_exponent,22,0x3a83a8,{DOUBLEWITHTWODWORDINTREE(0x0d200000,0x00000000)}},
+ {VT_exponent,22,0x3a83a9,{DOUBLEWITHTWODWORDINTREE(0x0d300000,0x00000000)}},
+ {VT_exponent,22,0x3a83aa,{DOUBLEWITHTWODWORDINTREE(0x0d400000,0x00000000)}},
+ {VT_exponent,22,0x3a83ab,{DOUBLEWITHTWODWORDINTREE(0x0d500000,0x00000000)}},
+ {VT_exponent,22,0x3a83ac,{DOUBLEWITHTWODWORDINTREE(0x0d600000,0x00000000)}},
+ {VT_exponent,22,0x3a83ad,{DOUBLEWITHTWODWORDINTREE(0x0d700000,0x00000000)}},
+ {VT_exponent,22,0x3a83ae,{DOUBLEWITHTWODWORDINTREE(0x0d800000,0x00000000)}},
+ {VT_exponent,22,0x3a83af,{DOUBLEWITHTWODWORDINTREE(0x0d900000,0x00000000)}},
+ {VT_exponent,22,0x3a83b0,{DOUBLEWITHTWODWORDINTREE(0x0da00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b1,{DOUBLEWITHTWODWORDINTREE(0x0db00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b2,{DOUBLEWITHTWODWORDINTREE(0x0dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b3,{DOUBLEWITHTWODWORDINTREE(0x0dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b4,{DOUBLEWITHTWODWORDINTREE(0x0de00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b5,{DOUBLEWITHTWODWORDINTREE(0x0df00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b6,{DOUBLEWITHTWODWORDINTREE(0x0e000000,0x00000000)}},
+ {VT_exponent,22,0x3a83b7,{DOUBLEWITHTWODWORDINTREE(0x0e100000,0x00000000)}},
+ {VT_exponent,22,0x3a83b8,{DOUBLEWITHTWODWORDINTREE(0x0e200000,0x00000000)}},
+ {VT_exponent,22,0x3a83b9,{DOUBLEWITHTWODWORDINTREE(0x0e300000,0x00000000)}},
+ {VT_exponent,22,0x3a83ba,{DOUBLEWITHTWODWORDINTREE(0x0e400000,0x00000000)}},
+ {VT_exponent,22,0x3a83bb,{DOUBLEWITHTWODWORDINTREE(0x0e500000,0x00000000)}},
+ {VT_exponent,22,0x3a83bc,{DOUBLEWITHTWODWORDINTREE(0x0e600000,0x00000000)}},
+ {VT_exponent,22,0x3a83bd,{DOUBLEWITHTWODWORDINTREE(0x0e700000,0x00000000)}},
+ {VT_exponent,22,0x3a83be,{DOUBLEWITHTWODWORDINTREE(0x0e800000,0x00000000)}},
+ {VT_exponent,22,0x3a83bf,{DOUBLEWITHTWODWORDINTREE(0x0e900000,0x00000000)}},
+ {VT_exponent,22,0x3a83c0,{DOUBLEWITHTWODWORDINTREE(0x0ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c1,{DOUBLEWITHTWODWORDINTREE(0x0eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c2,{DOUBLEWITHTWODWORDINTREE(0x0ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c3,{DOUBLEWITHTWODWORDINTREE(0x0ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c4,{DOUBLEWITHTWODWORDINTREE(0x0ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c5,{DOUBLEWITHTWODWORDINTREE(0x0ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c6,{DOUBLEWITHTWODWORDINTREE(0x0f000000,0x00000000)}},
+ {VT_exponent,22,0x3a83c7,{DOUBLEWITHTWODWORDINTREE(0x0f100000,0x00000000)}},
+ {VT_exponent,22,0x3a83c8,{DOUBLEWITHTWODWORDINTREE(0x0f200000,0x00000000)}},
+ {VT_exponent,22,0x3a83c9,{DOUBLEWITHTWODWORDINTREE(0x0f300000,0x00000000)}},
+ {VT_exponent,22,0x3a83ca,{DOUBLEWITHTWODWORDINTREE(0x0f400000,0x00000000)}},
+ {VT_exponent,22,0x3a83cb,{DOUBLEWITHTWODWORDINTREE(0x0f500000,0x00000000)}},
+ {VT_exponent,22,0x3a83cc,{DOUBLEWITHTWODWORDINTREE(0x0f600000,0x00000000)}},
+ {VT_exponent,22,0x3a83cd,{DOUBLEWITHTWODWORDINTREE(0x0f700000,0x00000000)}},
+ {VT_exponent,22,0x3a83ce,{DOUBLEWITHTWODWORDINTREE(0x0f800000,0x00000000)}},
+ {VT_exponent,22,0x3a83cf,{DOUBLEWITHTWODWORDINTREE(0x0f900000,0x00000000)}},
+ {VT_exponent,22,0x3a83d0,{DOUBLEWITHTWODWORDINTREE(0x0fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d1,{DOUBLEWITHTWODWORDINTREE(0x0fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d2,{DOUBLEWITHTWODWORDINTREE(0x0fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d3,{DOUBLEWITHTWODWORDINTREE(0x0fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d4,{DOUBLEWITHTWODWORDINTREE(0x0fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d5,{DOUBLEWITHTWODWORDINTREE(0x0ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d6,{DOUBLEWITHTWODWORDINTREE(0x10000000,0x00000000)}},
+ {VT_exponent,22,0x3a83d7,{DOUBLEWITHTWODWORDINTREE(0x10100000,0x00000000)}},
+ {VT_exponent,22,0x3a83d8,{DOUBLEWITHTWODWORDINTREE(0x10200000,0x00000000)}},
+ {VT_exponent,22,0x3a83d9,{DOUBLEWITHTWODWORDINTREE(0x10300000,0x00000000)}},
+ {VT_exponent,22,0x3a83da,{DOUBLEWITHTWODWORDINTREE(0x10400000,0x00000000)}},
+ {VT_exponent,22,0x3a83db,{DOUBLEWITHTWODWORDINTREE(0x10500000,0x00000000)}},
+ {VT_exponent,22,0x3a83dc,{DOUBLEWITHTWODWORDINTREE(0x10600000,0x00000000)}},
+ {VT_exponent,22,0x3a83dd,{DOUBLEWITHTWODWORDINTREE(0x10700000,0x00000000)}},
+ {VT_exponent,22,0x3a83de,{DOUBLEWITHTWODWORDINTREE(0x10800000,0x00000000)}},
+ {VT_exponent,22,0x3a83df,{DOUBLEWITHTWODWORDINTREE(0x10900000,0x00000000)}},
+ {VT_exponent,22,0x3a83e0,{DOUBLEWITHTWODWORDINTREE(0x10a00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e1,{DOUBLEWITHTWODWORDINTREE(0x10b00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e2,{DOUBLEWITHTWODWORDINTREE(0x10c00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e3,{DOUBLEWITHTWODWORDINTREE(0x10d00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e4,{DOUBLEWITHTWODWORDINTREE(0x10e00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e5,{DOUBLEWITHTWODWORDINTREE(0x10f00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e6,{DOUBLEWITHTWODWORDINTREE(0x11000000,0x00000000)}},
+ {VT_exponent,22,0x3a83e7,{DOUBLEWITHTWODWORDINTREE(0x11100000,0x00000000)}},
+ {VT_exponent,22,0x3a83e8,{DOUBLEWITHTWODWORDINTREE(0x11200000,0x00000000)}},
+ {VT_exponent,22,0x3a83e9,{DOUBLEWITHTWODWORDINTREE(0x11300000,0x00000000)}},
+ {VT_exponent,22,0x3a83ea,{DOUBLEWITHTWODWORDINTREE(0x11400000,0x00000000)}},
+ {VT_exponent,22,0x3a83eb,{DOUBLEWITHTWODWORDINTREE(0x11500000,0x00000000)}},
+ {VT_exponent,22,0x3a83ec,{DOUBLEWITHTWODWORDINTREE(0x11600000,0x00000000)}},
+ {VT_exponent,22,0x3a83ed,{DOUBLEWITHTWODWORDINTREE(0x11700000,0x00000000)}},
+ {VT_exponent,22,0x3a83ee,{DOUBLEWITHTWODWORDINTREE(0x11800000,0x00000000)}},
+ {VT_exponent,22,0x3a83ef,{DOUBLEWITHTWODWORDINTREE(0x11900000,0x00000000)}},
+ {VT_exponent,22,0x3a83f0,{DOUBLEWITHTWODWORDINTREE(0x11a00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f1,{DOUBLEWITHTWODWORDINTREE(0x11b00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f2,{DOUBLEWITHTWODWORDINTREE(0x11c00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f3,{DOUBLEWITHTWODWORDINTREE(0x11d00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f4,{DOUBLEWITHTWODWORDINTREE(0x11e00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f5,{DOUBLEWITHTWODWORDINTREE(0x11f00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f6,{DOUBLEWITHTWODWORDINTREE(0x12000000,0x00000000)}},
+ {VT_exponent,22,0x3a83f7,{DOUBLEWITHTWODWORDINTREE(0x12100000,0x00000000)}},
+ {VT_exponent,22,0x3a83f8,{DOUBLEWITHTWODWORDINTREE(0x12200000,0x00000000)}},
+ {VT_exponent,22,0x3a83f9,{DOUBLEWITHTWODWORDINTREE(0x12300000,0x00000000)}},
+ {VT_exponent,22,0x3a83fa,{DOUBLEWITHTWODWORDINTREE(0x12400000,0x00000000)}},
+ {VT_exponent,22,0x3a83fb,{DOUBLEWITHTWODWORDINTREE(0x12500000,0x00000000)}},
+ {VT_exponent,22,0x3a83fc,{DOUBLEWITHTWODWORDINTREE(0x12600000,0x00000000)}},
+ {VT_exponent,22,0x3a83fd,{DOUBLEWITHTWODWORDINTREE(0x12700000,0x00000000)}},
+ {VT_exponent,22,0x3a83fe,{DOUBLEWITHTWODWORDINTREE(0x12800000,0x00000000)}},
+ {VT_exponent,22,0x3a83ff,{DOUBLEWITHTWODWORDINTREE(0x12900000,0x00000000)}},
+ {VT_exponent,22,0x3a8400,{DOUBLEWITHTWODWORDINTREE(0x12a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8401,{DOUBLEWITHTWODWORDINTREE(0x12b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8402,{DOUBLEWITHTWODWORDINTREE(0x12c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8403,{DOUBLEWITHTWODWORDINTREE(0x12d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8404,{DOUBLEWITHTWODWORDINTREE(0x12e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8405,{DOUBLEWITHTWODWORDINTREE(0x12f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8406,{DOUBLEWITHTWODWORDINTREE(0x13000000,0x00000000)}},
+ {VT_exponent,22,0x3a8407,{DOUBLEWITHTWODWORDINTREE(0x13100000,0x00000000)}},
+ {VT_exponent,22,0x3a8408,{DOUBLEWITHTWODWORDINTREE(0x13200000,0x00000000)}},
+ {VT_exponent,22,0x3a8409,{DOUBLEWITHTWODWORDINTREE(0x13300000,0x00000000)}},
+ {VT_exponent,22,0x3a840a,{DOUBLEWITHTWODWORDINTREE(0x13400000,0x00000000)}},
+ {VT_exponent,22,0x3a840b,{DOUBLEWITHTWODWORDINTREE(0x13500000,0x00000000)}},
+ {VT_exponent,22,0x3a840c,{DOUBLEWITHTWODWORDINTREE(0x13600000,0x00000000)}},
+ {VT_exponent,22,0x3a840d,{DOUBLEWITHTWODWORDINTREE(0x13700000,0x00000000)}},
+ {VT_exponent,22,0x3a840e,{DOUBLEWITHTWODWORDINTREE(0x13800000,0x00000000)}},
+ {VT_exponent,22,0x3a840f,{DOUBLEWITHTWODWORDINTREE(0x13900000,0x00000000)}},
+ {VT_exponent,22,0x3a8410,{DOUBLEWITHTWODWORDINTREE(0x13a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8411,{DOUBLEWITHTWODWORDINTREE(0x13b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8412,{DOUBLEWITHTWODWORDINTREE(0x13c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8413,{DOUBLEWITHTWODWORDINTREE(0x13d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8414,{DOUBLEWITHTWODWORDINTREE(0x13e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8415,{DOUBLEWITHTWODWORDINTREE(0x13f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8416,{DOUBLEWITHTWODWORDINTREE(0x14000000,0x00000000)}},
+ {VT_exponent,22,0x3a8417,{DOUBLEWITHTWODWORDINTREE(0x14100000,0x00000000)}},
+ {VT_exponent,22,0x3a8418,{DOUBLEWITHTWODWORDINTREE(0x14200000,0x00000000)}},
+ {VT_exponent,22,0x3a8419,{DOUBLEWITHTWODWORDINTREE(0x14300000,0x00000000)}},
+ {VT_exponent,22,0x3a841a,{DOUBLEWITHTWODWORDINTREE(0x14400000,0x00000000)}},
+ {VT_exponent,22,0x3a841b,{DOUBLEWITHTWODWORDINTREE(0x14500000,0x00000000)}},
+ {VT_exponent,22,0x3a841c,{DOUBLEWITHTWODWORDINTREE(0x14600000,0x00000000)}},
+ {VT_exponent,22,0x3a841d,{DOUBLEWITHTWODWORDINTREE(0x14700000,0x00000000)}},
+ {VT_exponent,22,0x3a841e,{DOUBLEWITHTWODWORDINTREE(0x14800000,0x00000000)}},
+ {VT_exponent,22,0x3a841f,{DOUBLEWITHTWODWORDINTREE(0x14900000,0x00000000)}},
+ {VT_exponent,22,0x3a8420,{DOUBLEWITHTWODWORDINTREE(0x14a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8421,{DOUBLEWITHTWODWORDINTREE(0x14b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8422,{DOUBLEWITHTWODWORDINTREE(0x14c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8423,{DOUBLEWITHTWODWORDINTREE(0x14d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8424,{DOUBLEWITHTWODWORDINTREE(0x14e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8425,{DOUBLEWITHTWODWORDINTREE(0x14f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8426,{DOUBLEWITHTWODWORDINTREE(0x15000000,0x00000000)}},
+ {VT_exponent,22,0x3a8427,{DOUBLEWITHTWODWORDINTREE(0x15100000,0x00000000)}},
+ {VT_exponent,22,0x3a8428,{DOUBLEWITHTWODWORDINTREE(0x15200000,0x00000000)}},
+ {VT_exponent,22,0x3a8429,{DOUBLEWITHTWODWORDINTREE(0x15300000,0x00000000)}},
+ {VT_exponent,22,0x3a842a,{DOUBLEWITHTWODWORDINTREE(0x15400000,0x00000000)}},
+ {VT_exponent,22,0x3a842b,{DOUBLEWITHTWODWORDINTREE(0x15500000,0x00000000)}},
+ {VT_exponent,22,0x3a842c,{DOUBLEWITHTWODWORDINTREE(0x15600000,0x00000000)}},
+ {VT_exponent,22,0x3a842d,{DOUBLEWITHTWODWORDINTREE(0x15700000,0x00000000)}},
+ {VT_exponent,22,0x3a842e,{DOUBLEWITHTWODWORDINTREE(0x15800000,0x00000000)}},
+ {VT_exponent,22,0x3a842f,{DOUBLEWITHTWODWORDINTREE(0x15900000,0x00000000)}},
+ {VT_exponent,22,0x3a8430,{DOUBLEWITHTWODWORDINTREE(0x15a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8431,{DOUBLEWITHTWODWORDINTREE(0x15b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8432,{DOUBLEWITHTWODWORDINTREE(0x15c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8433,{DOUBLEWITHTWODWORDINTREE(0x15d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8434,{DOUBLEWITHTWODWORDINTREE(0x15e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8435,{DOUBLEWITHTWODWORDINTREE(0x15f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8436,{DOUBLEWITHTWODWORDINTREE(0x16000000,0x00000000)}},
+ {VT_exponent,22,0x3a8437,{DOUBLEWITHTWODWORDINTREE(0x16100000,0x00000000)}},
+ {VT_exponent,22,0x3a8438,{DOUBLEWITHTWODWORDINTREE(0x16200000,0x00000000)}},
+ {VT_exponent,22,0x3a8439,{DOUBLEWITHTWODWORDINTREE(0x16300000,0x00000000)}},
+ {VT_exponent,22,0x3a843a,{DOUBLEWITHTWODWORDINTREE(0x16400000,0x00000000)}},
+ {VT_exponent,22,0x3a843b,{DOUBLEWITHTWODWORDINTREE(0x16500000,0x00000000)}},
+ {VT_exponent,22,0x3a843c,{DOUBLEWITHTWODWORDINTREE(0x16600000,0x00000000)}},
+ {VT_exponent,22,0x3a843d,{DOUBLEWITHTWODWORDINTREE(0x16700000,0x00000000)}},
+ {VT_exponent,22,0x3a843e,{DOUBLEWITHTWODWORDINTREE(0x16800000,0x00000000)}},
+ {VT_exponent,22,0x3a843f,{DOUBLEWITHTWODWORDINTREE(0x16900000,0x00000000)}},
+ {VT_exponent,22,0x3a8440,{DOUBLEWITHTWODWORDINTREE(0x16a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8441,{DOUBLEWITHTWODWORDINTREE(0x16b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8442,{DOUBLEWITHTWODWORDINTREE(0x16c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8443,{DOUBLEWITHTWODWORDINTREE(0x16d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8444,{DOUBLEWITHTWODWORDINTREE(0x16e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8445,{DOUBLEWITHTWODWORDINTREE(0x16f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8446,{DOUBLEWITHTWODWORDINTREE(0x17000000,0x00000000)}},
+ {VT_exponent,22,0x3a8447,{DOUBLEWITHTWODWORDINTREE(0x17100000,0x00000000)}},
+ {VT_exponent,22,0x3a8448,{DOUBLEWITHTWODWORDINTREE(0x17200000,0x00000000)}},
+ {VT_exponent,22,0x3a8449,{DOUBLEWITHTWODWORDINTREE(0x17300000,0x00000000)}},
+ {VT_exponent,22,0x3a844a,{DOUBLEWITHTWODWORDINTREE(0x17400000,0x00000000)}},
+ {VT_exponent,22,0x3a844b,{DOUBLEWITHTWODWORDINTREE(0x17500000,0x00000000)}},
+ {VT_exponent,22,0x3a844c,{DOUBLEWITHTWODWORDINTREE(0x17600000,0x00000000)}},
+ {VT_exponent,22,0x3a844d,{DOUBLEWITHTWODWORDINTREE(0x17700000,0x00000000)}},
+ {VT_exponent,22,0x3a844e,{DOUBLEWITHTWODWORDINTREE(0x17800000,0x00000000)}},
+ {VT_exponent,22,0x3a844f,{DOUBLEWITHTWODWORDINTREE(0x17900000,0x00000000)}},
+ {VT_exponent,22,0x3a8450,{DOUBLEWITHTWODWORDINTREE(0x17a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8451,{DOUBLEWITHTWODWORDINTREE(0x17b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8452,{DOUBLEWITHTWODWORDINTREE(0x17c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8453,{DOUBLEWITHTWODWORDINTREE(0x17d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8454,{DOUBLEWITHTWODWORDINTREE(0x17e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8455,{DOUBLEWITHTWODWORDINTREE(0x17f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8456,{DOUBLEWITHTWODWORDINTREE(0x18000000,0x00000000)}},
+ {VT_exponent,22,0x3a8457,{DOUBLEWITHTWODWORDINTREE(0x18100000,0x00000000)}},
+ {VT_exponent,22,0x3a8458,{DOUBLEWITHTWODWORDINTREE(0x18200000,0x00000000)}},
+ {VT_exponent,22,0x3a8459,{DOUBLEWITHTWODWORDINTREE(0x18300000,0x00000000)}},
+ {VT_exponent,22,0x3a845a,{DOUBLEWITHTWODWORDINTREE(0x18400000,0x00000000)}},
+ {VT_exponent,22,0x3a845b,{DOUBLEWITHTWODWORDINTREE(0x18500000,0x00000000)}},
+ {VT_exponent,22,0x3a845c,{DOUBLEWITHTWODWORDINTREE(0x18600000,0x00000000)}},
+ {VT_exponent,22,0x3a845d,{DOUBLEWITHTWODWORDINTREE(0x18700000,0x00000000)}},
+ {VT_exponent,22,0x3a845e,{DOUBLEWITHTWODWORDINTREE(0x18800000,0x00000000)}},
+ {VT_exponent,22,0x3a845f,{DOUBLEWITHTWODWORDINTREE(0x18900000,0x00000000)}},
+ {VT_exponent,22,0x3a8460,{DOUBLEWITHTWODWORDINTREE(0x18a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8461,{DOUBLEWITHTWODWORDINTREE(0x18b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8462,{DOUBLEWITHTWODWORDINTREE(0x18c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8463,{DOUBLEWITHTWODWORDINTREE(0x18d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8464,{DOUBLEWITHTWODWORDINTREE(0x18e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8465,{DOUBLEWITHTWODWORDINTREE(0x18f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8466,{DOUBLEWITHTWODWORDINTREE(0x19000000,0x00000000)}},
+ {VT_exponent,22,0x3a8467,{DOUBLEWITHTWODWORDINTREE(0x19100000,0x00000000)}},
+ {VT_exponent,22,0x3a8468,{DOUBLEWITHTWODWORDINTREE(0x19200000,0x00000000)}},
+ {VT_exponent,22,0x3a8469,{DOUBLEWITHTWODWORDINTREE(0x19300000,0x00000000)}},
+ {VT_exponent,22,0x3a846a,{DOUBLEWITHTWODWORDINTREE(0x19400000,0x00000000)}},
+ {VT_exponent,22,0x3a846b,{DOUBLEWITHTWODWORDINTREE(0x19500000,0x00000000)}},
+ {VT_exponent,22,0x3a846c,{DOUBLEWITHTWODWORDINTREE(0x19600000,0x00000000)}},
+ {VT_exponent,22,0x3a846d,{DOUBLEWITHTWODWORDINTREE(0x19700000,0x00000000)}},
+ {VT_exponent,22,0x3a846e,{DOUBLEWITHTWODWORDINTREE(0x19800000,0x00000000)}},
+ {VT_exponent,22,0x3a846f,{DOUBLEWITHTWODWORDINTREE(0x19900000,0x00000000)}},
+ {VT_exponent,22,0x3a8470,{DOUBLEWITHTWODWORDINTREE(0x19a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8471,{DOUBLEWITHTWODWORDINTREE(0x19b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8472,{DOUBLEWITHTWODWORDINTREE(0x19c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8473,{DOUBLEWITHTWODWORDINTREE(0x19d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8474,{DOUBLEWITHTWODWORDINTREE(0x19e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8475,{DOUBLEWITHTWODWORDINTREE(0x19f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8476,{DOUBLEWITHTWODWORDINTREE(0x1a000000,0x00000000)}},
+ {VT_exponent,22,0x3a8477,{DOUBLEWITHTWODWORDINTREE(0x1a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8478,{DOUBLEWITHTWODWORDINTREE(0x1a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8479,{DOUBLEWITHTWODWORDINTREE(0x1a300000,0x00000000)}},
+ {VT_exponent,22,0x3a847a,{DOUBLEWITHTWODWORDINTREE(0x1a400000,0x00000000)}},
+ {VT_exponent,22,0x3a847b,{DOUBLEWITHTWODWORDINTREE(0x1a500000,0x00000000)}},
+ {VT_exponent,22,0x3a847c,{DOUBLEWITHTWODWORDINTREE(0x1a600000,0x00000000)}},
+ {VT_exponent,22,0x3a847d,{DOUBLEWITHTWODWORDINTREE(0x1a700000,0x00000000)}},
+ {VT_exponent,22,0x3a847e,{DOUBLEWITHTWODWORDINTREE(0x1a800000,0x00000000)}},
+ {VT_exponent,22,0x3a847f,{DOUBLEWITHTWODWORDINTREE(0x1a900000,0x00000000)}},
+ {VT_exponent,22,0x3a8480,{DOUBLEWITHTWODWORDINTREE(0x1aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a8481,{DOUBLEWITHTWODWORDINTREE(0x1ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a8482,{DOUBLEWITHTWODWORDINTREE(0x1ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a8483,{DOUBLEWITHTWODWORDINTREE(0x1ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a8484,{DOUBLEWITHTWODWORDINTREE(0x1ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a8485,{DOUBLEWITHTWODWORDINTREE(0x1af00000,0x00000000)}},
+ {VT_exponent,22,0x3a8486,{DOUBLEWITHTWODWORDINTREE(0x1b000000,0x00000000)}},
+ {VT_exponent,22,0x3a8487,{DOUBLEWITHTWODWORDINTREE(0x1b100000,0x00000000)}},
+ {VT_exponent,22,0x3a8488,{DOUBLEWITHTWODWORDINTREE(0x1b200000,0x00000000)}},
+ {VT_exponent,22,0x3a8489,{DOUBLEWITHTWODWORDINTREE(0x1b300000,0x00000000)}},
+ {VT_exponent,22,0x3a848a,{DOUBLEWITHTWODWORDINTREE(0x1b400000,0x00000000)}},
+ {VT_exponent,22,0x3a848b,{DOUBLEWITHTWODWORDINTREE(0x1b500000,0x00000000)}},
+ {VT_exponent,22,0x3a848c,{DOUBLEWITHTWODWORDINTREE(0x1b600000,0x00000000)}},
+ {VT_exponent,22,0x3a848d,{DOUBLEWITHTWODWORDINTREE(0x1b700000,0x00000000)}},
+ {VT_exponent,22,0x3a848e,{DOUBLEWITHTWODWORDINTREE(0x1b800000,0x00000000)}},
+ {VT_exponent,22,0x3a848f,{DOUBLEWITHTWODWORDINTREE(0x1b900000,0x00000000)}},
+ {VT_exponent,22,0x3a8490,{DOUBLEWITHTWODWORDINTREE(0x1ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a8491,{DOUBLEWITHTWODWORDINTREE(0x1bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a8492,{DOUBLEWITHTWODWORDINTREE(0x1bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a8493,{DOUBLEWITHTWODWORDINTREE(0x1bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a8494,{DOUBLEWITHTWODWORDINTREE(0x1be00000,0x00000000)}},
+ {VT_exponent,22,0x3a8495,{DOUBLEWITHTWODWORDINTREE(0x1bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a8496,{DOUBLEWITHTWODWORDINTREE(0x1c000000,0x00000000)}},
+ {VT_exponent,22,0x3a8497,{DOUBLEWITHTWODWORDINTREE(0x1c100000,0x00000000)}},
+ {VT_exponent,22,0x3a8498,{DOUBLEWITHTWODWORDINTREE(0x1c200000,0x00000000)}},
+ {VT_exponent,22,0x3a8499,{DOUBLEWITHTWODWORDINTREE(0x1c300000,0x00000000)}},
+ {VT_exponent,22,0x3a849a,{DOUBLEWITHTWODWORDINTREE(0x1c400000,0x00000000)}},
+ {VT_exponent,22,0x3a849b,{DOUBLEWITHTWODWORDINTREE(0x1c500000,0x00000000)}},
+ {VT_exponent,22,0x3a849c,{DOUBLEWITHTWODWORDINTREE(0x1c600000,0x00000000)}},
+ {VT_exponent,22,0x3a849d,{DOUBLEWITHTWODWORDINTREE(0x1c700000,0x00000000)}},
+ {VT_exponent,22,0x3a849e,{DOUBLEWITHTWODWORDINTREE(0x1c800000,0x00000000)}},
+ {VT_exponent,22,0x3a849f,{DOUBLEWITHTWODWORDINTREE(0x1c900000,0x00000000)}},
+ {VT_exponent,22,0x3a84a0,{DOUBLEWITHTWODWORDINTREE(0x1ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a1,{DOUBLEWITHTWODWORDINTREE(0x1cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a2,{DOUBLEWITHTWODWORDINTREE(0x1cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a3,{DOUBLEWITHTWODWORDINTREE(0x1cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a4,{DOUBLEWITHTWODWORDINTREE(0x1ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a5,{DOUBLEWITHTWODWORDINTREE(0x1cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a6,{DOUBLEWITHTWODWORDINTREE(0x1d000000,0x00000000)}},
+ {VT_exponent,22,0x3a84a7,{DOUBLEWITHTWODWORDINTREE(0x1d100000,0x00000000)}},
+ {VT_exponent,22,0x3a84a8,{DOUBLEWITHTWODWORDINTREE(0x1d200000,0x00000000)}},
+ {VT_exponent,22,0x3a84a9,{DOUBLEWITHTWODWORDINTREE(0x1d300000,0x00000000)}},
+ {VT_exponent,22,0x3a84aa,{DOUBLEWITHTWODWORDINTREE(0x1d400000,0x00000000)}},
+ {VT_exponent,22,0x3a84ab,{DOUBLEWITHTWODWORDINTREE(0x1d500000,0x00000000)}},
+ {VT_exponent,22,0x3a84ac,{DOUBLEWITHTWODWORDINTREE(0x1d600000,0x00000000)}},
+ {VT_exponent,22,0x3a84ad,{DOUBLEWITHTWODWORDINTREE(0x1d700000,0x00000000)}},
+ {VT_exponent,22,0x3a84ae,{DOUBLEWITHTWODWORDINTREE(0x1d800000,0x00000000)}},
+ {VT_exponent,22,0x3a84af,{DOUBLEWITHTWODWORDINTREE(0x1d900000,0x00000000)}},
+ {VT_exponent,22,0x3a84b0,{DOUBLEWITHTWODWORDINTREE(0x1da00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b1,{DOUBLEWITHTWODWORDINTREE(0x1db00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b2,{DOUBLEWITHTWODWORDINTREE(0x1dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b3,{DOUBLEWITHTWODWORDINTREE(0x1dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b4,{DOUBLEWITHTWODWORDINTREE(0x1de00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b5,{DOUBLEWITHTWODWORDINTREE(0x1df00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b6,{DOUBLEWITHTWODWORDINTREE(0x1e000000,0x00000000)}},
+ {VT_exponent,22,0x3a84b7,{DOUBLEWITHTWODWORDINTREE(0x1e100000,0x00000000)}},
+ {VT_exponent,22,0x3a84b8,{DOUBLEWITHTWODWORDINTREE(0x1e200000,0x00000000)}},
+ {VT_exponent,22,0x3a84b9,{DOUBLEWITHTWODWORDINTREE(0x1e300000,0x00000000)}},
+ {VT_exponent,22,0x3a84ba,{DOUBLEWITHTWODWORDINTREE(0x1e400000,0x00000000)}},
+ {VT_exponent,22,0x3a84bb,{DOUBLEWITHTWODWORDINTREE(0x1e500000,0x00000000)}},
+ {VT_exponent,22,0x3a84bc,{DOUBLEWITHTWODWORDINTREE(0x1e600000,0x00000000)}},
+ {VT_exponent,22,0x3a84bd,{DOUBLEWITHTWODWORDINTREE(0x1e700000,0x00000000)}},
+ {VT_exponent,22,0x3a84be,{DOUBLEWITHTWODWORDINTREE(0x1e800000,0x00000000)}},
+ {VT_exponent,22,0x3a84bf,{DOUBLEWITHTWODWORDINTREE(0x1e900000,0x00000000)}},
+ {VT_exponent,22,0x3a84c0,{DOUBLEWITHTWODWORDINTREE(0x1ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c1,{DOUBLEWITHTWODWORDINTREE(0x1eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c2,{DOUBLEWITHTWODWORDINTREE(0x1ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c3,{DOUBLEWITHTWODWORDINTREE(0x1ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c4,{DOUBLEWITHTWODWORDINTREE(0x1ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c5,{DOUBLEWITHTWODWORDINTREE(0x1ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c6,{DOUBLEWITHTWODWORDINTREE(0x1f000000,0x00000000)}},
+ {VT_exponent,22,0x3a84c7,{DOUBLEWITHTWODWORDINTREE(0x1f100000,0x00000000)}},
+ {VT_exponent,22,0x3a84c8,{DOUBLEWITHTWODWORDINTREE(0x1f200000,0x00000000)}},
+ {VT_exponent,22,0x3a84c9,{DOUBLEWITHTWODWORDINTREE(0x1f300000,0x00000000)}},
+ {VT_exponent,22,0x3a84ca,{DOUBLEWITHTWODWORDINTREE(0x1f400000,0x00000000)}},
+ {VT_exponent,22,0x3a84cb,{DOUBLEWITHTWODWORDINTREE(0x1f500000,0x00000000)}},
+ {VT_exponent,22,0x3a84cc,{DOUBLEWITHTWODWORDINTREE(0x1f600000,0x00000000)}},
+ {VT_exponent,22,0x3a84cd,{DOUBLEWITHTWODWORDINTREE(0x1f700000,0x00000000)}},
+ {VT_exponent,22,0x3a84ce,{DOUBLEWITHTWODWORDINTREE(0x1f800000,0x00000000)}},
+ {VT_exponent,22,0x3a84cf,{DOUBLEWITHTWODWORDINTREE(0x1f900000,0x00000000)}},
+ {VT_exponent,22,0x3a84d0,{DOUBLEWITHTWODWORDINTREE(0x1fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d1,{DOUBLEWITHTWODWORDINTREE(0x1fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d2,{DOUBLEWITHTWODWORDINTREE(0x1fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d3,{DOUBLEWITHTWODWORDINTREE(0x1fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d4,{DOUBLEWITHTWODWORDINTREE(0x1fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d5,{DOUBLEWITHTWODWORDINTREE(0x1ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d6,{DOUBLEWITHTWODWORDINTREE(0x20000000,0x00000000)}},
+ {VT_exponent,22,0x3a84d7,{DOUBLEWITHTWODWORDINTREE(0x20100000,0x00000000)}},
+ {VT_exponent,22,0x3a84d8,{DOUBLEWITHTWODWORDINTREE(0x20200000,0x00000000)}},
+ {VT_exponent,22,0x3a84d9,{DOUBLEWITHTWODWORDINTREE(0x20300000,0x00000000)}},
+ {VT_exponent,22,0x3a84da,{DOUBLEWITHTWODWORDINTREE(0x20400000,0x00000000)}},
+ {VT_exponent,22,0x3a84db,{DOUBLEWITHTWODWORDINTREE(0x20500000,0x00000000)}},
+ {VT_exponent,22,0x3a84dc,{DOUBLEWITHTWODWORDINTREE(0x20600000,0x00000000)}},
+ {VT_exponent,22,0x3a84dd,{DOUBLEWITHTWODWORDINTREE(0x20700000,0x00000000)}},
+ {VT_exponent,22,0x3a84de,{DOUBLEWITHTWODWORDINTREE(0x20800000,0x00000000)}},
+ {VT_exponent,22,0x3a84df,{DOUBLEWITHTWODWORDINTREE(0x20900000,0x00000000)}},
+ {VT_exponent,22,0x3a84e0,{DOUBLEWITHTWODWORDINTREE(0x20a00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e1,{DOUBLEWITHTWODWORDINTREE(0x20b00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e2,{DOUBLEWITHTWODWORDINTREE(0x20c00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e3,{DOUBLEWITHTWODWORDINTREE(0x20d00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e4,{DOUBLEWITHTWODWORDINTREE(0x20e00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e5,{DOUBLEWITHTWODWORDINTREE(0x20f00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e6,{DOUBLEWITHTWODWORDINTREE(0x21000000,0x00000000)}},
+ {VT_exponent,22,0x3a84e7,{DOUBLEWITHTWODWORDINTREE(0x21100000,0x00000000)}},
+ {VT_exponent,22,0x3a84e8,{DOUBLEWITHTWODWORDINTREE(0x21200000,0x00000000)}},
+ {VT_exponent,22,0x3a84e9,{DOUBLEWITHTWODWORDINTREE(0x21300000,0x00000000)}},
+ {VT_exponent,22,0x3a84ea,{DOUBLEWITHTWODWORDINTREE(0x21400000,0x00000000)}},
+ {VT_exponent,22,0x3a84eb,{DOUBLEWITHTWODWORDINTREE(0x21500000,0x00000000)}},
+ {VT_exponent,22,0x3a84ec,{DOUBLEWITHTWODWORDINTREE(0x21600000,0x00000000)}},
+ {VT_exponent,22,0x3a84ed,{DOUBLEWITHTWODWORDINTREE(0x21700000,0x00000000)}},
+ {VT_exponent,22,0x3a84ee,{DOUBLEWITHTWODWORDINTREE(0x21800000,0x00000000)}},
+ {VT_exponent,22,0x3a84ef,{DOUBLEWITHTWODWORDINTREE(0x21900000,0x00000000)}},
+ {VT_exponent,22,0x3a84f0,{DOUBLEWITHTWODWORDINTREE(0x21a00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f1,{DOUBLEWITHTWODWORDINTREE(0x21b00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f2,{DOUBLEWITHTWODWORDINTREE(0x21c00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f3,{DOUBLEWITHTWODWORDINTREE(0x21d00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f4,{DOUBLEWITHTWODWORDINTREE(0x21e00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f5,{DOUBLEWITHTWODWORDINTREE(0x21f00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f6,{DOUBLEWITHTWODWORDINTREE(0x22000000,0x00000000)}},
+ {VT_exponent,22,0x3a84f7,{DOUBLEWITHTWODWORDINTREE(0x22100000,0x00000000)}},
+ {VT_exponent,22,0x3a84f8,{DOUBLEWITHTWODWORDINTREE(0x22200000,0x00000000)}},
+ {VT_exponent,22,0x3a84f9,{DOUBLEWITHTWODWORDINTREE(0x22300000,0x00000000)}},
+ {VT_exponent,22,0x3a84fa,{DOUBLEWITHTWODWORDINTREE(0x22400000,0x00000000)}},
+ {VT_exponent,22,0x3a84fb,{DOUBLEWITHTWODWORDINTREE(0x22500000,0x00000000)}},
+ {VT_exponent,22,0x3a84fc,{DOUBLEWITHTWODWORDINTREE(0x22600000,0x00000000)}},
+ {VT_exponent,22,0x3a84fd,{DOUBLEWITHTWODWORDINTREE(0x22700000,0x00000000)}},
+ {VT_exponent,22,0x3a84fe,{DOUBLEWITHTWODWORDINTREE(0x22800000,0x00000000)}},
+ {VT_exponent,22,0x3a84ff,{DOUBLEWITHTWODWORDINTREE(0x22900000,0x00000000)}},
+ {VT_exponent,22,0x3a8500,{DOUBLEWITHTWODWORDINTREE(0x22a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8501,{DOUBLEWITHTWODWORDINTREE(0x22b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8502,{DOUBLEWITHTWODWORDINTREE(0x22c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8503,{DOUBLEWITHTWODWORDINTREE(0x22d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8504,{DOUBLEWITHTWODWORDINTREE(0x22e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8505,{DOUBLEWITHTWODWORDINTREE(0x22f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8506,{DOUBLEWITHTWODWORDINTREE(0x23000000,0x00000000)}},
+ {VT_exponent,22,0x3a8507,{DOUBLEWITHTWODWORDINTREE(0x23100000,0x00000000)}},
+ {VT_exponent,22,0x3a8508,{DOUBLEWITHTWODWORDINTREE(0x23200000,0x00000000)}},
+ {VT_exponent,22,0x3a8509,{DOUBLEWITHTWODWORDINTREE(0x23300000,0x00000000)}},
+ {VT_exponent,22,0x3a850a,{DOUBLEWITHTWODWORDINTREE(0x23400000,0x00000000)}},
+ {VT_exponent,22,0x3a850b,{DOUBLEWITHTWODWORDINTREE(0x23500000,0x00000000)}},
+ {VT_exponent,22,0x3a850c,{DOUBLEWITHTWODWORDINTREE(0x23600000,0x00000000)}},
+ {VT_exponent,22,0x3a850d,{DOUBLEWITHTWODWORDINTREE(0x23700000,0x00000000)}},
+ {VT_exponent,22,0x3a850e,{DOUBLEWITHTWODWORDINTREE(0x23800000,0x00000000)}},
+ {VT_exponent,22,0x3a850f,{DOUBLEWITHTWODWORDINTREE(0x23900000,0x00000000)}},
+ {VT_exponent,22,0x3a8510,{DOUBLEWITHTWODWORDINTREE(0x23a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8511,{DOUBLEWITHTWODWORDINTREE(0x23b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8512,{DOUBLEWITHTWODWORDINTREE(0x23c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8513,{DOUBLEWITHTWODWORDINTREE(0x23d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8514,{DOUBLEWITHTWODWORDINTREE(0x23e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8515,{DOUBLEWITHTWODWORDINTREE(0x23f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8516,{DOUBLEWITHTWODWORDINTREE(0x24000000,0x00000000)}},
+ {VT_exponent,22,0x3a8517,{DOUBLEWITHTWODWORDINTREE(0x24100000,0x00000000)}},
+ {VT_exponent,22,0x3a8518,{DOUBLEWITHTWODWORDINTREE(0x24200000,0x00000000)}},
+ {VT_exponent,22,0x3a8519,{DOUBLEWITHTWODWORDINTREE(0x24300000,0x00000000)}},
+ {VT_exponent,22,0x3a851a,{DOUBLEWITHTWODWORDINTREE(0x24400000,0x00000000)}},
+ {VT_exponent,22,0x3a851b,{DOUBLEWITHTWODWORDINTREE(0x24500000,0x00000000)}},
+ {VT_exponent,22,0x3a851c,{DOUBLEWITHTWODWORDINTREE(0x24600000,0x00000000)}},
+ {VT_exponent,22,0x3a851d,{DOUBLEWITHTWODWORDINTREE(0x24700000,0x00000000)}},
+ {VT_exponent,22,0x3a851e,{DOUBLEWITHTWODWORDINTREE(0x24800000,0x00000000)}},
+ {VT_exponent,22,0x3a851f,{DOUBLEWITHTWODWORDINTREE(0x24900000,0x00000000)}},
+ {VT_exponent,22,0x3a8520,{DOUBLEWITHTWODWORDINTREE(0x24a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8521,{DOUBLEWITHTWODWORDINTREE(0x24b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8522,{DOUBLEWITHTWODWORDINTREE(0x24c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8523,{DOUBLEWITHTWODWORDINTREE(0x24d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8524,{DOUBLEWITHTWODWORDINTREE(0x24e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8525,{DOUBLEWITHTWODWORDINTREE(0x24f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8526,{DOUBLEWITHTWODWORDINTREE(0x25000000,0x00000000)}},
+ {VT_exponent,22,0x3a8527,{DOUBLEWITHTWODWORDINTREE(0x25100000,0x00000000)}},
+ {VT_exponent,22,0x3a8528,{DOUBLEWITHTWODWORDINTREE(0x25200000,0x00000000)}},
+ {VT_exponent,22,0x3a8529,{DOUBLEWITHTWODWORDINTREE(0x25300000,0x00000000)}},
+ {VT_exponent,22,0x3a852a,{DOUBLEWITHTWODWORDINTREE(0x25400000,0x00000000)}},
+ {VT_exponent,22,0x3a852b,{DOUBLEWITHTWODWORDINTREE(0x25500000,0x00000000)}},
+ {VT_exponent,22,0x3a852c,{DOUBLEWITHTWODWORDINTREE(0x25600000,0x00000000)}},
+ {VT_exponent,22,0x3a852d,{DOUBLEWITHTWODWORDINTREE(0x25700000,0x00000000)}},
+ {VT_exponent,22,0x3a852e,{DOUBLEWITHTWODWORDINTREE(0x25800000,0x00000000)}},
+ {VT_exponent,22,0x3a852f,{DOUBLEWITHTWODWORDINTREE(0x25900000,0x00000000)}},
+ {VT_exponent,22,0x3a8530,{DOUBLEWITHTWODWORDINTREE(0x25a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8531,{DOUBLEWITHTWODWORDINTREE(0x25b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8532,{DOUBLEWITHTWODWORDINTREE(0x25c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8533,{DOUBLEWITHTWODWORDINTREE(0x25d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8534,{DOUBLEWITHTWODWORDINTREE(0x25e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8535,{DOUBLEWITHTWODWORDINTREE(0x25f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8536,{DOUBLEWITHTWODWORDINTREE(0x26000000,0x00000000)}},
+ {VT_exponent,22,0x3a8537,{DOUBLEWITHTWODWORDINTREE(0x26100000,0x00000000)}},
+ {VT_exponent,22,0x3a8538,{DOUBLEWITHTWODWORDINTREE(0x26200000,0x00000000)}},
+ {VT_exponent,22,0x3a8539,{DOUBLEWITHTWODWORDINTREE(0x26300000,0x00000000)}},
+ {VT_exponent,22,0x3a853a,{DOUBLEWITHTWODWORDINTREE(0x26400000,0x00000000)}},
+ {VT_exponent,22,0x3a853b,{DOUBLEWITHTWODWORDINTREE(0x26500000,0x00000000)}},
+ {VT_exponent,22,0x3a853c,{DOUBLEWITHTWODWORDINTREE(0x26600000,0x00000000)}},
+ {VT_exponent,22,0x3a853d,{DOUBLEWITHTWODWORDINTREE(0x26700000,0x00000000)}},
+ {VT_exponent,22,0x3a853e,{DOUBLEWITHTWODWORDINTREE(0x26800000,0x00000000)}},
+ {VT_exponent,22,0x3a853f,{DOUBLEWITHTWODWORDINTREE(0x26900000,0x00000000)}},
+ {VT_exponent,22,0x3a8540,{DOUBLEWITHTWODWORDINTREE(0x26a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8541,{DOUBLEWITHTWODWORDINTREE(0x26b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8542,{DOUBLEWITHTWODWORDINTREE(0x26c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8543,{DOUBLEWITHTWODWORDINTREE(0x26d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8544,{DOUBLEWITHTWODWORDINTREE(0x26e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8545,{DOUBLEWITHTWODWORDINTREE(0x26f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8546,{DOUBLEWITHTWODWORDINTREE(0x27000000,0x00000000)}},
+ {VT_exponent,22,0x3a8547,{DOUBLEWITHTWODWORDINTREE(0x27100000,0x00000000)}},
+ {VT_exponent,22,0x3a8548,{DOUBLEWITHTWODWORDINTREE(0x27200000,0x00000000)}},
+ {VT_exponent,22,0x3a8549,{DOUBLEWITHTWODWORDINTREE(0x27300000,0x00000000)}},
+ {VT_exponent,22,0x3a854a,{DOUBLEWITHTWODWORDINTREE(0x27400000,0x00000000)}},
+ {VT_exponent,22,0x3a854b,{DOUBLEWITHTWODWORDINTREE(0x27500000,0x00000000)}},
+ {VT_exponent,22,0x3a854c,{DOUBLEWITHTWODWORDINTREE(0x27600000,0x00000000)}},
+ {VT_exponent,22,0x3a854d,{DOUBLEWITHTWODWORDINTREE(0x27700000,0x00000000)}},
+ {VT_exponent,22,0x3a854e,{DOUBLEWITHTWODWORDINTREE(0x27800000,0x00000000)}},
+ {VT_exponent,22,0x3a854f,{DOUBLEWITHTWODWORDINTREE(0x27900000,0x00000000)}},
+ {VT_exponent,22,0x3a8550,{DOUBLEWITHTWODWORDINTREE(0x27a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8551,{DOUBLEWITHTWODWORDINTREE(0x27b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8552,{DOUBLEWITHTWODWORDINTREE(0x27c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8553,{DOUBLEWITHTWODWORDINTREE(0x27d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8554,{DOUBLEWITHTWODWORDINTREE(0x27e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8555,{DOUBLEWITHTWODWORDINTREE(0x27f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8556,{DOUBLEWITHTWODWORDINTREE(0x28000000,0x00000000)}},
+ {VT_exponent,22,0x3a8557,{DOUBLEWITHTWODWORDINTREE(0x28100000,0x00000000)}},
+ {VT_exponent,22,0x3a8558,{DOUBLEWITHTWODWORDINTREE(0x28200000,0x00000000)}},
+ {VT_exponent,22,0x3a8559,{DOUBLEWITHTWODWORDINTREE(0x28300000,0x00000000)}},
+ {VT_exponent,22,0x3a855a,{DOUBLEWITHTWODWORDINTREE(0x28400000,0x00000000)}},
+ {VT_exponent,22,0x3a855b,{DOUBLEWITHTWODWORDINTREE(0x28500000,0x00000000)}},
+ {VT_exponent,22,0x3a855c,{DOUBLEWITHTWODWORDINTREE(0x28600000,0x00000000)}},
+ {VT_exponent,22,0x3a855d,{DOUBLEWITHTWODWORDINTREE(0x28700000,0x00000000)}},
+ {VT_exponent,22,0x3a855e,{DOUBLEWITHTWODWORDINTREE(0x28800000,0x00000000)}},
+ {VT_exponent,22,0x3a855f,{DOUBLEWITHTWODWORDINTREE(0x28900000,0x00000000)}},
+ {VT_exponent,22,0x3a8560,{DOUBLEWITHTWODWORDINTREE(0x28a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8561,{DOUBLEWITHTWODWORDINTREE(0x28b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8562,{DOUBLEWITHTWODWORDINTREE(0x28c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8563,{DOUBLEWITHTWODWORDINTREE(0x28d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8564,{DOUBLEWITHTWODWORDINTREE(0x28e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8565,{DOUBLEWITHTWODWORDINTREE(0x28f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8566,{DOUBLEWITHTWODWORDINTREE(0x29000000,0x00000000)}},
+ {VT_exponent,22,0x3a8567,{DOUBLEWITHTWODWORDINTREE(0x29100000,0x00000000)}},
+ {VT_exponent,22,0x3a8568,{DOUBLEWITHTWODWORDINTREE(0x29200000,0x00000000)}},
+ {VT_exponent,22,0x3a8569,{DOUBLEWITHTWODWORDINTREE(0x29300000,0x00000000)}},
+ {VT_exponent,22,0x3a856a,{DOUBLEWITHTWODWORDINTREE(0x29400000,0x00000000)}},
+ {VT_exponent,22,0x3a856b,{DOUBLEWITHTWODWORDINTREE(0x29500000,0x00000000)}},
+ {VT_exponent,22,0x3a856c,{DOUBLEWITHTWODWORDINTREE(0x29600000,0x00000000)}},
+ {VT_exponent,22,0x3a856d,{DOUBLEWITHTWODWORDINTREE(0x29700000,0x00000000)}},
+ {VT_exponent,22,0x3a856e,{DOUBLEWITHTWODWORDINTREE(0x29800000,0x00000000)}},
+ {VT_exponent,22,0x3a856f,{DOUBLEWITHTWODWORDINTREE(0x29900000,0x00000000)}},
+ {VT_exponent,22,0x3a8570,{DOUBLEWITHTWODWORDINTREE(0x29a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8571,{DOUBLEWITHTWODWORDINTREE(0x29b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8572,{DOUBLEWITHTWODWORDINTREE(0x29c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8573,{DOUBLEWITHTWODWORDINTREE(0x29d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8574,{DOUBLEWITHTWODWORDINTREE(0x29e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8575,{DOUBLEWITHTWODWORDINTREE(0x29f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8576,{DOUBLEWITHTWODWORDINTREE(0x2a000000,0x00000000)}},
+ {VT_exponent,22,0x3a8577,{DOUBLEWITHTWODWORDINTREE(0x2a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8578,{DOUBLEWITHTWODWORDINTREE(0x2a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8579,{DOUBLEWITHTWODWORDINTREE(0x2a300000,0x00000000)}},
+ {VT_exponent,22,0x3a857a,{DOUBLEWITHTWODWORDINTREE(0x2a400000,0x00000000)}},
+ {VT_exponent,22,0x3a857b,{DOUBLEWITHTWODWORDINTREE(0x2a500000,0x00000000)}},
+ {VT_exponent,22,0x3a857c,{DOUBLEWITHTWODWORDINTREE(0x2a600000,0x00000000)}},
+ {VT_exponent,22,0x3a857d,{DOUBLEWITHTWODWORDINTREE(0x2a700000,0x00000000)}},
+ {VT_exponent,22,0x3a857e,{DOUBLEWITHTWODWORDINTREE(0x2a800000,0x00000000)}},
+ {VT_exponent,22,0x3a857f,{DOUBLEWITHTWODWORDINTREE(0x2a900000,0x00000000)}},
+ {VT_exponent,22,0x3a8580,{DOUBLEWITHTWODWORDINTREE(0x2aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a8581,{DOUBLEWITHTWODWORDINTREE(0x2ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a8582,{DOUBLEWITHTWODWORDINTREE(0x2ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a8583,{DOUBLEWITHTWODWORDINTREE(0x2ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a8584,{DOUBLEWITHTWODWORDINTREE(0x2ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a8585,{DOUBLEWITHTWODWORDINTREE(0x2af00000,0x00000000)}},
+ {VT_exponent,22,0x3a8586,{DOUBLEWITHTWODWORDINTREE(0x2b000000,0x00000000)}},
+ {VT_exponent,22,0x3a8587,{DOUBLEWITHTWODWORDINTREE(0x2b100000,0x00000000)}},
+ {VT_exponent,22,0x3a8588,{DOUBLEWITHTWODWORDINTREE(0x2b200000,0x00000000)}},
+ {VT_exponent,22,0x3a8589,{DOUBLEWITHTWODWORDINTREE(0x2b300000,0x00000000)}},
+ {VT_exponent,22,0x3a858a,{DOUBLEWITHTWODWORDINTREE(0x2b400000,0x00000000)}},
+ {VT_exponent,22,0x3a858b,{DOUBLEWITHTWODWORDINTREE(0x2b500000,0x00000000)}},
+ {VT_exponent,22,0x3a858c,{DOUBLEWITHTWODWORDINTREE(0x2b600000,0x00000000)}},
+ {VT_exponent,22,0x3a858d,{DOUBLEWITHTWODWORDINTREE(0x2b700000,0x00000000)}},
+ {VT_exponent,22,0x3a858e,{DOUBLEWITHTWODWORDINTREE(0x2b800000,0x00000000)}},
+ {VT_exponent,22,0x3a858f,{DOUBLEWITHTWODWORDINTREE(0x2b900000,0x00000000)}},
+ {VT_exponent,22,0x3a8590,{DOUBLEWITHTWODWORDINTREE(0x2ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a8591,{DOUBLEWITHTWODWORDINTREE(0x2bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a8592,{DOUBLEWITHTWODWORDINTREE(0x2bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a8593,{DOUBLEWITHTWODWORDINTREE(0x2bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a8594,{DOUBLEWITHTWODWORDINTREE(0x2be00000,0x00000000)}},
+ {VT_exponent,22,0x3a8595,{DOUBLEWITHTWODWORDINTREE(0x2bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a8596,{DOUBLEWITHTWODWORDINTREE(0x2c000000,0x00000000)}},
+ {VT_exponent,22,0x3a8597,{DOUBLEWITHTWODWORDINTREE(0x2c100000,0x00000000)}},
+ {VT_exponent,22,0x3a8598,{DOUBLEWITHTWODWORDINTREE(0x2c200000,0x00000000)}},
+ {VT_exponent,22,0x3a8599,{DOUBLEWITHTWODWORDINTREE(0x2c300000,0x00000000)}},
+ {VT_exponent,22,0x3a859a,{DOUBLEWITHTWODWORDINTREE(0x2c400000,0x00000000)}},
+ {VT_exponent,22,0x3a859b,{DOUBLEWITHTWODWORDINTREE(0x2c500000,0x00000000)}},
+ {VT_exponent,22,0x3a859c,{DOUBLEWITHTWODWORDINTREE(0x2c600000,0x00000000)}},
+ {VT_exponent,22,0x3a859d,{DOUBLEWITHTWODWORDINTREE(0x2c700000,0x00000000)}},
+ {VT_exponent,22,0x3a859e,{DOUBLEWITHTWODWORDINTREE(0x2c800000,0x00000000)}},
+ {VT_exponent,22,0x3a859f,{DOUBLEWITHTWODWORDINTREE(0x2c900000,0x00000000)}},
+ {VT_exponent,22,0x3a85a0,{DOUBLEWITHTWODWORDINTREE(0x2ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a1,{DOUBLEWITHTWODWORDINTREE(0x2cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a2,{DOUBLEWITHTWODWORDINTREE(0x2cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a3,{DOUBLEWITHTWODWORDINTREE(0x2cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a4,{DOUBLEWITHTWODWORDINTREE(0x2ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a5,{DOUBLEWITHTWODWORDINTREE(0x2cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a6,{DOUBLEWITHTWODWORDINTREE(0x2d000000,0x00000000)}},
+ {VT_exponent,22,0x3a85a7,{DOUBLEWITHTWODWORDINTREE(0x2d100000,0x00000000)}},
+ {VT_exponent,22,0x3a85a8,{DOUBLEWITHTWODWORDINTREE(0x2d200000,0x00000000)}},
+ {VT_exponent,22,0x3a85a9,{DOUBLEWITHTWODWORDINTREE(0x2d300000,0x00000000)}},
+ {VT_exponent,22,0x3a85aa,{DOUBLEWITHTWODWORDINTREE(0x2d400000,0x00000000)}},
+ {VT_exponent,22,0x3a85ab,{DOUBLEWITHTWODWORDINTREE(0x2d500000,0x00000000)}},
+ {VT_exponent,22,0x3a85ac,{DOUBLEWITHTWODWORDINTREE(0x2d600000,0x00000000)}},
+ {VT_exponent,22,0x3a85ad,{DOUBLEWITHTWODWORDINTREE(0x2d700000,0x00000000)}},
+ {VT_exponent,22,0x3a85ae,{DOUBLEWITHTWODWORDINTREE(0x2d800000,0x00000000)}},
+ {VT_exponent,22,0x3a85af,{DOUBLEWITHTWODWORDINTREE(0x2d900000,0x00000000)}},
+ {VT_exponent,22,0x3a85b0,{DOUBLEWITHTWODWORDINTREE(0x2da00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b1,{DOUBLEWITHTWODWORDINTREE(0x2db00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b2,{DOUBLEWITHTWODWORDINTREE(0x2dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b3,{DOUBLEWITHTWODWORDINTREE(0x2dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b4,{DOUBLEWITHTWODWORDINTREE(0x2de00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b5,{DOUBLEWITHTWODWORDINTREE(0x2df00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b6,{DOUBLEWITHTWODWORDINTREE(0x2e000000,0x00000000)}},
+ {VT_exponent,22,0x3a85b7,{DOUBLEWITHTWODWORDINTREE(0x2e100000,0x00000000)}},
+ {VT_exponent,22,0x3a85b8,{DOUBLEWITHTWODWORDINTREE(0x2e200000,0x00000000)}},
+ {VT_exponent,22,0x3a85b9,{DOUBLEWITHTWODWORDINTREE(0x2e300000,0x00000000)}},
+ {VT_exponent,22,0x3a85ba,{DOUBLEWITHTWODWORDINTREE(0x2e400000,0x00000000)}},
+ {VT_exponent,22,0x3a85bb,{DOUBLEWITHTWODWORDINTREE(0x2e500000,0x00000000)}},
+ {VT_exponent,22,0x3a85bc,{DOUBLEWITHTWODWORDINTREE(0x2e600000,0x00000000)}},
+ {VT_exponent,22,0x3a85bd,{DOUBLEWITHTWODWORDINTREE(0x2e700000,0x00000000)}},
+ {VT_exponent,22,0x3a85be,{DOUBLEWITHTWODWORDINTREE(0x2e800000,0x00000000)}},
+ {VT_exponent,22,0x3a85bf,{DOUBLEWITHTWODWORDINTREE(0x2e900000,0x00000000)}},
+ {VT_exponent,22,0x3a85c0,{DOUBLEWITHTWODWORDINTREE(0x2ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c1,{DOUBLEWITHTWODWORDINTREE(0x2eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c2,{DOUBLEWITHTWODWORDINTREE(0x2ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c3,{DOUBLEWITHTWODWORDINTREE(0x2ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c4,{DOUBLEWITHTWODWORDINTREE(0x2ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c5,{DOUBLEWITHTWODWORDINTREE(0x2ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c6,{DOUBLEWITHTWODWORDINTREE(0x2f000000,0x00000000)}},
+ {VT_exponent,22,0x3a85c7,{DOUBLEWITHTWODWORDINTREE(0x2f100000,0x00000000)}},
+ {VT_exponent,22,0x3a85c8,{DOUBLEWITHTWODWORDINTREE(0x2f200000,0x00000000)}},
+ {VT_exponent,22,0x3a85c9,{DOUBLEWITHTWODWORDINTREE(0x2f300000,0x00000000)}},
+ {VT_exponent,22,0x3a85ca,{DOUBLEWITHTWODWORDINTREE(0x2f400000,0x00000000)}},
+ {VT_exponent,22,0x3a85cb,{DOUBLEWITHTWODWORDINTREE(0x2f500000,0x00000000)}},
+ {VT_exponent,22,0x3a85cc,{DOUBLEWITHTWODWORDINTREE(0x2f600000,0x00000000)}},
+ {VT_exponent,22,0x3a85cd,{DOUBLEWITHTWODWORDINTREE(0x2f700000,0x00000000)}},
+ {VT_exponent,22,0x3a85ce,{DOUBLEWITHTWODWORDINTREE(0x2f800000,0x00000000)}},
+ {VT_exponent,22,0x3a85cf,{DOUBLEWITHTWODWORDINTREE(0x2f900000,0x00000000)}},
+ {VT_exponent,22,0x3a85d0,{DOUBLEWITHTWODWORDINTREE(0x2fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d1,{DOUBLEWITHTWODWORDINTREE(0x2fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d2,{DOUBLEWITHTWODWORDINTREE(0x2fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d3,{DOUBLEWITHTWODWORDINTREE(0x2fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d4,{DOUBLEWITHTWODWORDINTREE(0x2fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d5,{DOUBLEWITHTWODWORDINTREE(0x2ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d6,{DOUBLEWITHTWODWORDINTREE(0x30000000,0x00000000)}},
+ {VT_exponent,22,0x3a85d7,{DOUBLEWITHTWODWORDINTREE(0x30100000,0x00000000)}},
+ {VT_exponent,22,0x3a85d8,{DOUBLEWITHTWODWORDINTREE(0x30200000,0x00000000)}},
+ {VT_exponent,22,0x3a85d9,{DOUBLEWITHTWODWORDINTREE(0x30300000,0x00000000)}},
+ {VT_exponent,22,0x3a85da,{DOUBLEWITHTWODWORDINTREE(0x30400000,0x00000000)}},
+ {VT_exponent,22,0x3a85db,{DOUBLEWITHTWODWORDINTREE(0x30500000,0x00000000)}},
+ {VT_exponent,22,0x3a85dc,{DOUBLEWITHTWODWORDINTREE(0x30600000,0x00000000)}},
+ {VT_exponent,22,0x3a85dd,{DOUBLEWITHTWODWORDINTREE(0x30700000,0x00000000)}},
+ {VT_exponent,22,0x3a85de,{DOUBLEWITHTWODWORDINTREE(0x30800000,0x00000000)}},
+ {VT_exponent,22,0x3a85df,{DOUBLEWITHTWODWORDINTREE(0x30900000,0x00000000)}},
+ {VT_exponent,22,0x3a85e0,{DOUBLEWITHTWODWORDINTREE(0x30a00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e1,{DOUBLEWITHTWODWORDINTREE(0x30b00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e2,{DOUBLEWITHTWODWORDINTREE(0x30c00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e3,{DOUBLEWITHTWODWORDINTREE(0x30d00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e4,{DOUBLEWITHTWODWORDINTREE(0x30e00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e5,{DOUBLEWITHTWODWORDINTREE(0x30f00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e6,{DOUBLEWITHTWODWORDINTREE(0x31000000,0x00000000)}},
+ {VT_exponent,22,0x3a85e7,{DOUBLEWITHTWODWORDINTREE(0x31100000,0x00000000)}},
+ {VT_exponent,22,0x3a85e8,{DOUBLEWITHTWODWORDINTREE(0x31200000,0x00000000)}},
+ {VT_exponent,22,0x3a85e9,{DOUBLEWITHTWODWORDINTREE(0x31300000,0x00000000)}},
+ {VT_exponent,22,0x3a85ea,{DOUBLEWITHTWODWORDINTREE(0x31400000,0x00000000)}},
+ {VT_exponent,22,0x3a85eb,{DOUBLEWITHTWODWORDINTREE(0x31500000,0x00000000)}},
+ {VT_exponent,22,0x3a85ec,{DOUBLEWITHTWODWORDINTREE(0x31600000,0x00000000)}},
+ {VT_exponent,22,0x3a85ed,{DOUBLEWITHTWODWORDINTREE(0x31700000,0x00000000)}},
+ {VT_exponent,22,0x3a85ee,{DOUBLEWITHTWODWORDINTREE(0x31800000,0x00000000)}},
+ {VT_exponent,22,0x3a85ef,{DOUBLEWITHTWODWORDINTREE(0x31900000,0x00000000)}},
+ {VT_exponent,22,0x3a85f0,{DOUBLEWITHTWODWORDINTREE(0x31a00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f1,{DOUBLEWITHTWODWORDINTREE(0x31b00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f2,{DOUBLEWITHTWODWORDINTREE(0x31c00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f3,{DOUBLEWITHTWODWORDINTREE(0x31d00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f4,{DOUBLEWITHTWODWORDINTREE(0x31e00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f5,{DOUBLEWITHTWODWORDINTREE(0x31f00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f6,{DOUBLEWITHTWODWORDINTREE(0x32000000,0x00000000)}},
+ {VT_exponent,22,0x3a85f7,{DOUBLEWITHTWODWORDINTREE(0x32100000,0x00000000)}},
+ {VT_exponent,22,0x3a85f8,{DOUBLEWITHTWODWORDINTREE(0x32200000,0x00000000)}},
+ {VT_exponent,22,0x3a85f9,{DOUBLEWITHTWODWORDINTREE(0x32300000,0x00000000)}},
+ {VT_exponent,22,0x3a85fa,{DOUBLEWITHTWODWORDINTREE(0x32400000,0x00000000)}},
+ {VT_exponent,22,0x3a85fb,{DOUBLEWITHTWODWORDINTREE(0x32500000,0x00000000)}},
+ {VT_exponent,22,0x3a85fc,{DOUBLEWITHTWODWORDINTREE(0x32600000,0x00000000)}},
+ {VT_exponent,22,0x3a85fd,{DOUBLEWITHTWODWORDINTREE(0x32700000,0x00000000)}},
+ {VT_exponent,22,0x3a85fe,{DOUBLEWITHTWODWORDINTREE(0x32800000,0x00000000)}},
+ {VT_exponent,22,0x3a85ff,{DOUBLEWITHTWODWORDINTREE(0x32900000,0x00000000)}},
+ {VT_exponent,22,0x3a8600,{DOUBLEWITHTWODWORDINTREE(0x32a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8601,{DOUBLEWITHTWODWORDINTREE(0x32b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8602,{DOUBLEWITHTWODWORDINTREE(0x32c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8603,{DOUBLEWITHTWODWORDINTREE(0x32d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8604,{DOUBLEWITHTWODWORDINTREE(0x32e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8605,{DOUBLEWITHTWODWORDINTREE(0x32f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8606,{DOUBLEWITHTWODWORDINTREE(0x33000000,0x00000000)}},
+ {VT_exponent,22,0x3a8607,{DOUBLEWITHTWODWORDINTREE(0x33100000,0x00000000)}},
+ {VT_exponent,22,0x3a8608,{DOUBLEWITHTWODWORDINTREE(0x33200000,0x00000000)}},
+ {VT_exponent,22,0x3a8609,{DOUBLEWITHTWODWORDINTREE(0x33300000,0x00000000)}},
+ {VT_exponent,22,0x3a860a,{DOUBLEWITHTWODWORDINTREE(0x33400000,0x00000000)}},
+ {VT_exponent,22,0x3a860b,{DOUBLEWITHTWODWORDINTREE(0x33500000,0x00000000)}},
+ {VT_exponent,22,0x3a860c,{DOUBLEWITHTWODWORDINTREE(0x33600000,0x00000000)}},
+ {VT_exponent,22,0x3a860d,{DOUBLEWITHTWODWORDINTREE(0x33700000,0x00000000)}},
+ {VT_exponent,22,0x3a860e,{DOUBLEWITHTWODWORDINTREE(0x33800000,0x00000000)}},
+ {VT_exponent,22,0x3a860f,{DOUBLEWITHTWODWORDINTREE(0x33900000,0x00000000)}},
+ {VT_exponent,22,0x3a8610,{DOUBLEWITHTWODWORDINTREE(0x33a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8611,{DOUBLEWITHTWODWORDINTREE(0x33b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8612,{DOUBLEWITHTWODWORDINTREE(0x33c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8613,{DOUBLEWITHTWODWORDINTREE(0x33d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8614,{DOUBLEWITHTWODWORDINTREE(0x33e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8615,{DOUBLEWITHTWODWORDINTREE(0x33f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8616,{DOUBLEWITHTWODWORDINTREE(0x34000000,0x00000000)}},
+ {VT_exponent,22,0x3a8617,{DOUBLEWITHTWODWORDINTREE(0x34100000,0x00000000)}},
+ {VT_exponent,22,0x3a8618,{DOUBLEWITHTWODWORDINTREE(0x34200000,0x00000000)}},
+ {VT_exponent,22,0x3a8619,{DOUBLEWITHTWODWORDINTREE(0x34300000,0x00000000)}},
+ {VT_exponent,22,0x3a861a,{DOUBLEWITHTWODWORDINTREE(0x34400000,0x00000000)}},
+ {VT_exponent,22,0x3a861b,{DOUBLEWITHTWODWORDINTREE(0x34500000,0x00000000)}},
+ {VT_exponent,22,0x3a861c,{DOUBLEWITHTWODWORDINTREE(0x34600000,0x00000000)}},
+ {VT_exponent,22,0x3a861d,{DOUBLEWITHTWODWORDINTREE(0x34700000,0x00000000)}},
+ {VT_exponent,22,0x3a861e,{DOUBLEWITHTWODWORDINTREE(0x34800000,0x00000000)}},
+ {VT_exponent,22,0x3a861f,{DOUBLEWITHTWODWORDINTREE(0x34900000,0x00000000)}},
+ {VT_exponent,22,0x3a8620,{DOUBLEWITHTWODWORDINTREE(0x34a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8621,{DOUBLEWITHTWODWORDINTREE(0x34b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8622,{DOUBLEWITHTWODWORDINTREE(0x34c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8623,{DOUBLEWITHTWODWORDINTREE(0x34d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8624,{DOUBLEWITHTWODWORDINTREE(0x34e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8625,{DOUBLEWITHTWODWORDINTREE(0x34f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8626,{DOUBLEWITHTWODWORDINTREE(0x35000000,0x00000000)}},
+ {VT_exponent,22,0x3a8627,{DOUBLEWITHTWODWORDINTREE(0x35100000,0x00000000)}},
+ {VT_exponent,22,0x3a8628,{DOUBLEWITHTWODWORDINTREE(0x35200000,0x00000000)}},
+ {VT_exponent,22,0x3a8629,{DOUBLEWITHTWODWORDINTREE(0x35300000,0x00000000)}},
+ {VT_exponent,18,0xf787,{DOUBLEWITHTWODWORDINTREE(0x35400000,0x00000000)}},
+ {VT_exponent,18,0xd1d4,{DOUBLEWITHTWODWORDINTREE(0x35500000,0x00000000)}},
+ {VT_exponent,19,0x77f9f,{DOUBLEWITHTWODWORDINTREE(0x35600000,0x00000000)}},
+ {VT_exponent,18,0x3b8fb,{DOUBLEWITHTWODWORDINTREE(0x35700000,0x00000000)}},
+ {VT_exponent,19,0x1ef1a,{DOUBLEWITHTWODWORDINTREE(0x35800000,0x00000000)}},
+ {VT_exponent,21,0x1d4315,{DOUBLEWITHTWODWORDINTREE(0x35900000,0x00000000)}},
+ {VT_exponent,16,0x3de2,{DOUBLEWITHTWODWORDINTREE(0x35a00000,0x00000000)}},
+ {VT_exponent,22,0x3a862c,{DOUBLEWITHTWODWORDINTREE(0x35b00000,0x00000000)}},
+ {VT_exponent,22,0x3a862d,{DOUBLEWITHTWODWORDINTREE(0x35c00000,0x00000000)}},
+ {VT_exponent,22,0x3a862e,{DOUBLEWITHTWODWORDINTREE(0x35d00000,0x00000000)}},
+ {VT_exponent,22,0x3a862f,{DOUBLEWITHTWODWORDINTREE(0x35e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8630,{DOUBLEWITHTWODWORDINTREE(0x35f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8631,{DOUBLEWITHTWODWORDINTREE(0x36000000,0x00000000)}},
+ {VT_exponent,22,0x3a8632,{DOUBLEWITHTWODWORDINTREE(0x36100000,0x00000000)}},
+ {VT_exponent,22,0x3a8633,{DOUBLEWITHTWODWORDINTREE(0x36200000,0x00000000)}},
+ {VT_exponent,22,0x3a8634,{DOUBLEWITHTWODWORDINTREE(0x36300000,0x00000000)}},
+ {VT_exponent,22,0x3a8635,{DOUBLEWITHTWODWORDINTREE(0x36400000,0x00000000)}},
+ {VT_exponent,22,0x3a8636,{DOUBLEWITHTWODWORDINTREE(0x36500000,0x00000000)}},
+ {VT_exponent,22,0x3a8637,{DOUBLEWITHTWODWORDINTREE(0x36600000,0x00000000)}},
+ {VT_exponent,22,0x3a8638,{DOUBLEWITHTWODWORDINTREE(0x36700000,0x00000000)}},
+ {VT_exponent,21,0x1d431d,{DOUBLEWITHTWODWORDINTREE(0x36800000,0x00000000)}},
+ {VT_exponent,22,0x3a8639,{DOUBLEWITHTWODWORDINTREE(0x36900000,0x00000000)}},
+ {VT_exponent,22,0x3a863c,{DOUBLEWITHTWODWORDINTREE(0x36a00000,0x00000000)}},
+ {VT_exponent,16,0x3de0,{DOUBLEWITHTWODWORDINTREE(0x36b00000,0x00000000)}},
+ {VT_exponent,18,0x3a95e,{DOUBLEWITHTWODWORDINTREE(0x36c00000,0x00000000)}},
+ {VT_exponent,21,0x1d431f,{DOUBLEWITHTWODWORDINTREE(0x36d00000,0x00000000)}},
+ {VT_exponent,22,0x3a863d,{DOUBLEWITHTWODWORDINTREE(0x36e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8640,{DOUBLEWITHTWODWORDINTREE(0x36f00000,0x00000000)}},
+ {VT_exponent,20,0x34749,{DOUBLEWITHTWODWORDINTREE(0x37000000,0x00000000)}},
+ {VT_exponent,20,0x3474d,{DOUBLEWITHTWODWORDINTREE(0x37100000,0x00000000)}},
+ {VT_exponent,22,0x3a8641,{DOUBLEWITHTWODWORDINTREE(0x37200000,0x00000000)}},
+ {VT_exponent,22,0x3a8642,{DOUBLEWITHTWODWORDINTREE(0x37300000,0x00000000)}},
+ {VT_exponent,22,0x3a8643,{DOUBLEWITHTWODWORDINTREE(0x37400000,0x00000000)}},
+ {VT_exponent,22,0x3a8644,{DOUBLEWITHTWODWORDINTREE(0x37500000,0x00000000)}},
+ {VT_exponent,22,0x3a8645,{DOUBLEWITHTWODWORDINTREE(0x37600000,0x00000000)}},
+ {VT_exponent,22,0x3a8646,{DOUBLEWITHTWODWORDINTREE(0x37700000,0x00000000)}},
+ {VT_exponent,22,0x3a8647,{DOUBLEWITHTWODWORDINTREE(0x37800000,0x00000000)}},
+ {VT_exponent,22,0x3a8648,{DOUBLEWITHTWODWORDINTREE(0x37900000,0x00000000)}},
+ {VT_exponent,22,0x3a8649,{DOUBLEWITHTWODWORDINTREE(0x37a00000,0x00000000)}},
+ {VT_exponent,22,0x3a864a,{DOUBLEWITHTWODWORDINTREE(0x37b00000,0x00000000)}},
+ {VT_exponent,22,0x3a864b,{DOUBLEWITHTWODWORDINTREE(0x37c00000,0x00000000)}},
+ {VT_exponent,22,0x3a864c,{DOUBLEWITHTWODWORDINTREE(0x37d00000,0x00000000)}},
+ {VT_exponent,22,0x3a864d,{DOUBLEWITHTWODWORDINTREE(0x37e00000,0x00000000)}},
+ {VT_exponent,22,0x3a864e,{DOUBLEWITHTWODWORDINTREE(0x37f00000,0x00000000)}},
+ {VT_exponent,22,0x3a864f,{DOUBLEWITHTWODWORDINTREE(0x38000000,0x00000000)}},
+ {VT_exponent,22,0x3a8650,{DOUBLEWITHTWODWORDINTREE(0x38100000,0x00000000)}},
+ {VT_exponent,22,0x3a8651,{DOUBLEWITHTWODWORDINTREE(0x38200000,0x00000000)}},
+ {VT_exponent,22,0x3a8652,{DOUBLEWITHTWODWORDINTREE(0x38300000,0x00000000)}},
+ {VT_exponent,22,0x3a8653,{DOUBLEWITHTWODWORDINTREE(0x38400000,0x00000000)}},
+ {VT_exponent,22,0x3a8654,{DOUBLEWITHTWODWORDINTREE(0x38500000,0x00000000)}},
+ {VT_exponent,22,0x3a8655,{DOUBLEWITHTWODWORDINTREE(0x38600000,0x00000000)}},
+ {VT_exponent,22,0x3a8656,{DOUBLEWITHTWODWORDINTREE(0x38700000,0x00000000)}},
+ {VT_exponent,22,0x3a8657,{DOUBLEWITHTWODWORDINTREE(0x38800000,0x00000000)}},
+ {VT_exponent,22,0x3a8658,{DOUBLEWITHTWODWORDINTREE(0x38900000,0x00000000)}},
+ {VT_exponent,22,0x3a8659,{DOUBLEWITHTWODWORDINTREE(0x38a00000,0x00000000)}},
+ {VT_exponent,22,0x3a865a,{DOUBLEWITHTWODWORDINTREE(0x38b00000,0x00000000)}},
+ {VT_exponent,22,0x3a865b,{DOUBLEWITHTWODWORDINTREE(0x38c00000,0x00000000)}},
+ {VT_exponent,22,0x3a865c,{DOUBLEWITHTWODWORDINTREE(0x38d00000,0x00000000)}},
+ {VT_exponent,22,0x3a865d,{DOUBLEWITHTWODWORDINTREE(0x38e00000,0x00000000)}},
+ {VT_exponent,21,0x1d432f,{DOUBLEWITHTWODWORDINTREE(0x38f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8660,{DOUBLEWITHTWODWORDINTREE(0x39000000,0x00000000)}},
+ {VT_exponent,22,0x3a8661,{DOUBLEWITHTWODWORDINTREE(0x39100000,0x00000000)}},
+ {VT_exponent,22,0x3a8662,{DOUBLEWITHTWODWORDINTREE(0x39200000,0x00000000)}},
+ {VT_exponent,21,0x1d4332,{DOUBLEWITHTWODWORDINTREE(0x39300000,0x00000000)}},
+ {VT_exponent,18,0xd1d5,{DOUBLEWITHTWODWORDINTREE(0x39400000,0x00000000)}},
+ {VT_exponent,18,0x3bfda,{DOUBLEWITHTWODWORDINTREE(0x39500000,0x00000000)}},
+ {VT_exponent,15,0x7528,{DOUBLEWITHTWODWORDINTREE(0x39600000,0x00000000)}},
+ {VT_exponent,15,0x7529,{DOUBLEWITHTWODWORDINTREE(0x39700000,0x00000000)}},
+ {VT_exponent,18,0x3a95f,{DOUBLEWITHTWODWORDINTREE(0x39800000,0x00000000)}},
+ {VT_exponent,17,0x1d434,{DOUBLEWITHTWODWORDINTREE(0x39900000,0x00000000)}},
+ {VT_exponent,19,0x750cd,{DOUBLEWITHTWODWORDINTREE(0x39a00000,0x00000000)}},
+ {VT_exponent,18,0x3a867,{DOUBLEWITHTWODWORDINTREE(0x39b00000,0x00000000)}},
+ {VT_exponent,19,0x771fd,{DOUBLEWITHTWODWORDINTREE(0x39c00000,0x00000000)}},
+ {VT_exponent,15,0x7764,{DOUBLEWITHTWODWORDINTREE(0x39d00000,0x00000000)}},
+ {VT_exponent,20,0xee3f9,{DOUBLEWITHTWODWORDINTREE(0x39e00000,0x00000000)}},
+ {VT_exponent,18,0x3bfdb,{DOUBLEWITHTWODWORDINTREE(0x39f00000,0x00000000)}},
+ {VT_exponent,16,0xeff7,{DOUBLEWITHTWODWORDINTREE(0x3a000000,0x00000000)}},
+ {VT_exponent,18,0xd1d6,{DOUBLEWITHTWODWORDINTREE(0x3a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8663,{DOUBLEWITHTWODWORDINTREE(0x3a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8666,{DOUBLEWITHTWODWORDINTREE(0x3a300000,0x00000000)}},
+ {VT_exponent,18,0x3b8fa,{DOUBLEWITHTWODWORDINTREE(0x3a400000,0x00000000)}},
+ {VT_exponent,17,0x1d435,{DOUBLEWITHTWODWORDINTREE(0x3a500000,0x00000000)}},
+ {VT_exponent,17,0x1dfe4,{DOUBLEWITHTWODWORDINTREE(0x3a600000,0x00000000)}},
+ {VT_exponent,19,0x750d8,{DOUBLEWITHTWODWORDINTREE(0x3a700000,0x00000000)}},
+ {VT_exponent,18,0x3a95b,{DOUBLEWITHTWODWORDINTREE(0x3a800000,0x00000000)}},
+ {VT_exponent,19,0x77f9e,{DOUBLEWITHTWODWORDINTREE(0x3a900000,0x00000000)}},
+ {VT_exponent,19,0x750d9,{DOUBLEWITHTWODWORDINTREE(0x3aa00000,0x00000000)}},
+ {VT_exponent,18,0xd1d7,{DOUBLEWITHTWODWORDINTREE(0x3ab00000,0x00000000)}},
+ {VT_exponent,18,0x3b8ff,{DOUBLEWITHTWODWORDINTREE(0x3ac00000,0x00000000)}},
+ {VT_exponent,17,0x1dc7c,{DOUBLEWITHTWODWORDINTREE(0x3ad00000,0x00000000)}},
+ {VT_exponent,19,0x750da,{DOUBLEWITHTWODWORDINTREE(0x3ae00000,0x00000000)}},
+ {VT_exponent,17,0x7bc2,{DOUBLEWITHTWODWORDINTREE(0x3af00000,0x00000000)}},
+ {VT_exponent,18,0x3bfca,{DOUBLEWITHTWODWORDINTREE(0x3b000000,0x00000000)}},
+ {VT_exponent,19,0x1a3a5,{DOUBLEWITHTWODWORDINTREE(0x3b100000,0x00000000)}},
+ {VT_exponent,17,0x1d4ac,{DOUBLEWITHTWODWORDINTREE(0x3b200000,0x00000000)}},
+ {VT_exponent,18,0x3a86e,{DOUBLEWITHTWODWORDINTREE(0x3b300000,0x00000000)}},
+ {VT_exponent,17,0x1d438,{DOUBLEWITHTWODWORDINTREE(0x3b400000,0x00000000)}},
+ {VT_exponent,18,0x3bfcb,{DOUBLEWITHTWODWORDINTREE(0x3b500000,0x00000000)}},
+ {VT_exponent,19,0x1a3a7,{DOUBLEWITHTWODWORDINTREE(0x3b600000,0x00000000)}},
+ {VT_exponent,17,0x1d4ae,{DOUBLEWITHTWODWORDINTREE(0x3b700000,0x00000000)}},
+ {VT_exponent,18,0x3bfce,{DOUBLEWITHTWODWORDINTREE(0x3b800000,0x00000000)}},
+ {VT_exponent,18,0xf78c,{DOUBLEWITHTWODWORDINTREE(0x3b900000,0x00000000)}},
+ {VT_exponent,17,0x1dfec,{DOUBLEWITHTWODWORDINTREE(0x3ba00000,0x00000000)}},
+ {VT_exponent,17,0x1d439,{DOUBLEWITHTWODWORDINTREE(0x3bb00000,0x00000000)}},
+ {VT_exponent,17,0x68e8,{DOUBLEWITHTWODWORDINTREE(0x3bc00000,0x00000000)}},
+ {VT_exponent,18,0xf786,{DOUBLEWITHTWODWORDINTREE(0x3bd00000,0x00000000)}},
+ {VT_exponent,15,0x771e,{DOUBLEWITHTWODWORDINTREE(0x3be00000,0x00000000)}},
+ {VT_exponent,17,0x1dfe6,{DOUBLEWITHTWODWORDINTREE(0x3bf00000,0x00000000)}},
+ {VT_exponent,15,0x77f8,{DOUBLEWITHTWODWORDINTREE(0x3c000000,0x00000000)}},
+ {VT_exponent,14,0x3bb3,{DOUBLEWITHTWODWORDINTREE(0x3c100000,0x00000000)}},
+ {VT_exponent,14,0x3b8e,{DOUBLEWITHTWODWORDINTREE(0x3c200000,0x00000000)}},
+ {VT_exponent,14,0x3a82,{DOUBLEWITHTWODWORDINTREE(0x3c300000,0x00000000)}},
+ {VT_exponent,14,0x3b96,{DOUBLEWITHTWODWORDINTREE(0x3c400000,0x00000000)}},
+ {VT_exponent,13,0x68f,{DOUBLEWITHTWODWORDINTREE(0x3c500000,0x00000000)}},
+ {VT_exponent,12,0x3d4,{DOUBLEWITHTWODWORDINTREE(0x3c600000,0x00000000)}},
+ {VT_exponent,13,0x1dca,{DOUBLEWITHTWODWORDINTREE(0x3c700000,0x00000000)}},
+ {VT_exponent,12,0x346,{DOUBLEWITHTWODWORDINTREE(0x3c800000,0x00000000)}},
+ {VT_exponent,12,0xee7,{DOUBLEWITHTWODWORDINTREE(0x3c900000,0x00000000)}},
+ {VT_exponent,12,0xeea,{DOUBLEWITHTWODWORDINTREE(0x3ca00000,0x00000000)}},
+ {VT_exponent,11,0x1ed,{DOUBLEWITHTWODWORDINTREE(0x3cb00000,0x00000000)}},
+ {VT_exponent,12,0x3df,{DOUBLEWITHTWODWORDINTREE(0x3cc00000,0x00000000)}},
+ {VT_exponent,11,0x1a2,{DOUBLEWITHTWODWORDINTREE(0x3cd00000,0x00000000)}},
+ {VT_exponent,11,0x56f,{DOUBLEWITHTWODWORDINTREE(0x3ce00000,0x00000000)}},
+ {VT_exponent,11,0xb9,{DOUBLEWITHTWODWORDINTREE(0x3cf00000,0x00000000)}},
+ {VT_exponent,13,0x7b2,{DOUBLEWITHTWODWORDINTREE(0x3d000000,0x00000000)}},
+ {VT_exponent,13,0x1dd8,{DOUBLEWITHTWODWORDINTREE(0x3d100000,0x00000000)}},
+ {VT_exponent,13,0x15ba,{DOUBLEWITHTWODWORDINTREE(0x3d200000,0x00000000)}},
+ {VT_exponent,12,0xee6,{DOUBLEWITHTWODWORDINTREE(0x3d300000,0x00000000)}},
+ {VT_exponent,13,0x15b8,{DOUBLEWITHTWODWORDINTREE(0x3d400000,0x00000000)}},
+ {VT_exponent,14,0xf79,{DOUBLEWITHTWODWORDINTREE(0x3d500000,0x00000000)}},
+ {VT_exponent,14,0x3a81,{DOUBLEWITHTWODWORDINTREE(0x3d600000,0x00000000)}},
+ {VT_exponent,14,0xd1c,{DOUBLEWITHTWODWORDINTREE(0x3d700000,0x00000000)}},
+ {VT_exponent,15,0x7765,{DOUBLEWITHTWODWORDINTREE(0x3d800000,0x00000000)}},
+ {VT_exponent,14,0xf54,{DOUBLEWITHTWODWORDINTREE(0x3d900000,0x00000000)}},
+ {VT_exponent,13,0x15b9,{DOUBLEWITHTWODWORDINTREE(0x3da00000,0x00000000)}},
+ {VT_exponent,13,0x7ab,{DOUBLEWITHTWODWORDINTREE(0x3db00000,0x00000000)}},
+ {VT_exponent,15,0x7500,{DOUBLEWITHTWODWORDINTREE(0x3dc00000,0x00000000)}},
+ {VT_exponent,15,0x1eaa,{DOUBLEWITHTWODWORDINTREE(0x3dd00000,0x00000000)}},
+ {VT_exponent,15,0x7501,{DOUBLEWITHTWODWORDINTREE(0x3de00000,0x00000000)}},
+ {VT_exponent,15,0x1eab,{DOUBLEWITHTWODWORDINTREE(0x3df00000,0x00000000)}},
+ {VT_exponent,14,0x3b97,{DOUBLEWITHTWODWORDINTREE(0x3e000000,0x00000000)}},
+ {VT_exponent,15,0x752a,{DOUBLEWITHTWODWORDINTREE(0x3e100000,0x00000000)}},
+ {VT_exponent,15,0x77fa,{DOUBLEWITHTWODWORDINTREE(0x3e200000,0x00000000)}},
+ {VT_double,10,0xf4,{DOUBLEWITHTWODWORDINTREE(0x3e35798e,0xe2308c3a)}},
+ {VT_exponent,14,0x3a93,{DOUBLEWITHTWODWORDINTREE(0x3e300000,0x00000000)}},
+ {VT_double,11,0x77c,{DOUBLEWITHTWODWORDINTREE(0x3e45798e,0xe2308c3a)}},
+ {VT_exponent,13,0x1dc6,{DOUBLEWITHTWODWORDINTREE(0x3e400000,0x00000000)}},
+ {VT_exponent,13,0x7bd,{DOUBLEWITHTWODWORDINTREE(0x3e500000,0x00000000)}},
+ {VT_exponent,13,0x1dff,{DOUBLEWITHTWODWORDINTREE(0x3e600000,0x00000000)}},
+ {VT_exponent,12,0xefe,{DOUBLEWITHTWODWORDINTREE(0x3e700000,0x00000000)}},
+ {VT_double,8,0xaf,{DOUBLEWITHTWODWORDINTREE(0x3e8ad7f2,0x9abcaf4a)}},
+ {VT_exponent,12,0xeed,{DOUBLEWITHTWODWORDINTREE(0x3e800000,0x00000000)}},
+ {VT_exponent,11,0xb8,{DOUBLEWITHTWODWORDINTREE(0x3e900000,0x00000000)}},
+ {VT_exponent,12,0x3d8,{DOUBLEWITHTWODWORDINTREE(0x3ea00000,0x00000000)}},
+ {VT_exponent,11,0x1eb,{DOUBLEWITHTWODWORDINTREE(0x3eb00000,0x00000000)}},
+ {VT_double,9,0x1d2,{DOUBLEWITHTWODWORDINTREE(0x3ec0c6f7,0xa0b5ed8e)}},
+ {VT_exponent,13,0x1d4b,{DOUBLEWITHTWODWORDINTREE(0x3ec00000,0x00000000)}},
+ {VT_exponent,13,0x7b3,{DOUBLEWITHTWODWORDINTREE(0x3ed00000,0x00000000)}},
+ {VT_exponent,10,0x5d,{DOUBLEWITHTWODWORDINTREE(0x3ee00000,0x00000000)}},
+ {VT_exponent,12,0xeeb,{DOUBLEWITHTWODWORDINTREE(0x3ef00000,0x00000000)}},
+ {VT_exponent,11,0x1ee,{DOUBLEWITHTWODWORDINTREE(0x3f000000,0x00000000)}},
+ {VT_exponent,10,0x5f,{DOUBLEWITHTWODWORDINTREE(0x3f100000,0x00000000)}},
+ {VT_exponent,10,0x2b6,{DOUBLEWITHTWODWORDINTREE(0x3f200000,0x00000000)}},
+ {VT_exponent,9,0x1de,{DOUBLEWITHTWODWORDINTREE(0x3f300000,0x00000000)}},
+ {VT_double,10,0xd0,{DOUBLEWITHTWODWORDINTREE(0x3f454c98,0x5f06f694)}},
+ {VT_double,6,0x9,{DOUBLEWITHTWODWORDINTREE(0x3f4a36e2,0xeb1c432d)}},
+ {VT_exponent,8,0xe8,{DOUBLEWITHTWODWORDINTREE(0x3f400000,0x00000000)}},
+ {VT_double,4,0xf,{DOUBLEWITHTWODWORDINTREE(0x3f50624d,0xd2f1a9fc)}},
+ {VT_exponent,8,0xae,{DOUBLEWITHTWODWORDINTREE(0x3f500000,0x00000000)}},
+ {VT_double,5,0x16,{DOUBLEWITHTWODWORDINTREE(0x3f60624d,0xd2f1a9fc)}},
+ {VT_exponent,7,0x1b,{DOUBLEWITHTWODWORDINTREE(0x3f600000,0x00000000)}},
+ {VT_exponent,7,0x76,{DOUBLEWITHTWODWORDINTREE(0x3f700000,0x00000000)}},
+ {VT_exponent,7,0xa,{DOUBLEWITHTWODWORDINTREE(0x3f800000,0x00000000)}},
+ {VT_exponent,6,0x8,{DOUBLEWITHTWODWORDINTREE(0x3f900000,0x00000000)}},
+ {VT_exponent,6,0xe,{DOUBLEWITHTWODWORDINTREE(0x3fa00000,0x00000000)}},
+ {VT_double,11,0x751,{DOUBLEWITHTWODWORDINTREE(0x3fbe69ad,0x42c3c9ee)}},
+ {VT_exponent,6,0x4,{DOUBLEWITHTWODWORDINTREE(0x3fb00000,0x00000000)}},
+ {VT_exponent,6,0xc,{DOUBLEWITHTWODWORDINTREE(0x3fc00000,0x00000000)}},
+ {VT_exponent,5,0x3,{DOUBLEWITHTWODWORDINTREE(0x3fd00000,0x00000000)}},
+ {VT_double,11,0x777,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}},
+ {VT_double,9,0x1d6,{DOUBLEWITHTWODWORDINTREE(0x3fefffff,0xf8000002)}},
+ {VT_exponent,4,0x8,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}},
+ {VT_double,4,0x0,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}},
+ {VT_exponent,5,0x13,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}},
+ {VT_exponent,5,0x1b,{DOUBLEWITHTWODWORDINTREE(0x40000000,0x00000000)}},
+ {VT_double,9,0x15a,{DOUBLEWITHTWODWORDINTREE(0x401921fb,0x54442d18)}},
+ {VT_exponent,5,0x17,{DOUBLEWITHTWODWORDINTREE(0x40100000,0x00000000)}},
+ {VT_exponent,5,0x12,{DOUBLEWITHTWODWORDINTREE(0x40200000,0x00000000)}},
+ {VT_double,11,0x774,{DOUBLEWITHTWODWORDINTREE(0x4035ee14,0x80000000)}},
+ {VT_exponent,5,0x19,{DOUBLEWITHTWODWORDINTREE(0x40300000,0x00000000)}},
+ {VT_double,9,0x1d3,{DOUBLEWITHTWODWORDINTREE(0x404ca5dc,0x1a63c1f8)}},
+ {VT_exponent,5,0x1a,{DOUBLEWITHTWODWORDINTREE(0x40400000,0x00000000)}},
+ {VT_double,11,0x77e,{DOUBLEWITHTWODWORDINTREE(0x405bb32f,0xe0000000)}},
+ {VT_double,10,0x5e,{DOUBLEWITHTWODWORDINTREE(0x405c332f,0xe0000000)}},
+ {VT_exponent,5,0x18,{DOUBLEWITHTWODWORDINTREE(0x40500000,0x00000000)}},
+ {VT_double,9,0x1d7,{DOUBLEWITHTWODWORDINTREE(0x40668000,0x00000000)}},
+ {VT_exponent,5,0x1c,{DOUBLEWITHTWODWORDINTREE(0x40600000,0x00000000)}},
+ {VT_double,9,0x1d5,{DOUBLEWITHTWODWORDINTREE(0x40768000,0x00000000)}},
+ {VT_exponent,5,0x14,{DOUBLEWITHTWODWORDINTREE(0x40700000,0x00000000)}},
+ {VT_double,11,0x77d,{DOUBLEWITHTWODWORDINTREE(0x408f4000,0x00000000)}},
+ {VT_exponent,5,0x5,{DOUBLEWITHTWODWORDINTREE(0x40800000,0x00000000)}},
+ {VT_double,10,0xd2,{DOUBLEWITHTWODWORDINTREE(0x409233ff,0xffffffff)}},
+ {VT_double,8,0x3c,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000000)}},
+ {VT_double,11,0x753,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000001)}},
+ {VT_double,10,0xd3,{DOUBLEWITHTWODWORDINTREE(0x4092abff,0xffffffff)}},
+ {VT_double,8,0x35,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000000)}},
+ {VT_double,11,0x770,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000001)}},
+ {VT_exponent,8,0x16,{DOUBLEWITHTWODWORDINTREE(0x40900000,0x00000000)}},
+ {VT_exponent,12,0xee2,{DOUBLEWITHTWODWORDINTREE(0x40a00000,0x00000000)}},
+ {VT_exponent,12,0xee4,{DOUBLEWITHTWODWORDINTREE(0x40b00000,0x00000000)}},
+ {VT_double,7,0x1f,{DOUBLEWITHTWODWORDINTREE(0x40c81c80,0x00000000)}},
+ {VT_exponent,8,0xac,{DOUBLEWITHTWODWORDINTREE(0x40c00000,0x00000000)}},
+ {VT_exponent,13,0x15bb,{DOUBLEWITHTWODWORDINTREE(0x40d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8667,{DOUBLEWITHTWODWORDINTREE(0x40e00000,0x00000000)}},
+ {VT_exponent,22,0x3a86d8,{DOUBLEWITHTWODWORDINTREE(0x40f00000,0x00000000)}},
+ {VT_exponent,22,0x3a86d9,{DOUBLEWITHTWODWORDINTREE(0x41000000,0x00000000)}},
+ {VT_exponent,22,0x3a86da,{DOUBLEWITHTWODWORDINTREE(0x41100000,0x00000000)}},
+ {VT_exponent,17,0x1dc7e,{DOUBLEWITHTWODWORDINTREE(0x41200000,0x00000000)}},
+ {VT_exponent,22,0x3a86db,{DOUBLEWITHTWODWORDINTREE(0x41300000,0x00000000)}},
+ {VT_exponent,22,0x3a86dc,{DOUBLEWITHTWODWORDINTREE(0x41400000,0x00000000)}},
+ {VT_exponent,22,0x3a86dd,{DOUBLEWITHTWODWORDINTREE(0x41500000,0x00000000)}},
+ {VT_exponent,22,0x3a86de,{DOUBLEWITHTWODWORDINTREE(0x41600000,0x00000000)}},
+ {VT_exponent,22,0x3a86df,{DOUBLEWITHTWODWORDINTREE(0x41700000,0x00000000)}},
+ {VT_exponent,22,0x3a86f0,{DOUBLEWITHTWODWORDINTREE(0x41800000,0x00000000)}},
+ {VT_exponent,22,0x3a86f1,{DOUBLEWITHTWODWORDINTREE(0x41900000,0x00000000)}},
+ {VT_exponent,22,0x3a86f2,{DOUBLEWITHTWODWORDINTREE(0x41a00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f3,{DOUBLEWITHTWODWORDINTREE(0x41b00000,0x00000000)}},
+ {VT_double,6,0x2a,{DOUBLEWITHTWODWORDINTREE(0x41cdcd64,0xff800000)}},
+ {VT_exponent,22,0x3a86f4,{DOUBLEWITHTWODWORDINTREE(0x41c00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f5,{DOUBLEWITHTWODWORDINTREE(0x41d00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f6,{DOUBLEWITHTWODWORDINTREE(0x41e00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f7,{DOUBLEWITHTWODWORDINTREE(0x41f00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f8,{DOUBLEWITHTWODWORDINTREE(0x42000000,0x00000000)}},
+ {VT_exponent,22,0x3a86f9,{DOUBLEWITHTWODWORDINTREE(0x42100000,0x00000000)}},
+ {VT_exponent,22,0x3a86fa,{DOUBLEWITHTWODWORDINTREE(0x42200000,0x00000000)}},
+ {VT_exponent,22,0x3a86fb,{DOUBLEWITHTWODWORDINTREE(0x42300000,0x00000000)}},
+ {VT_exponent,22,0x3a86fc,{DOUBLEWITHTWODWORDINTREE(0x42400000,0x00000000)}},
+ {VT_exponent,22,0x3a86fd,{DOUBLEWITHTWODWORDINTREE(0x42500000,0x00000000)}},
+ {VT_exponent,22,0x3a86fe,{DOUBLEWITHTWODWORDINTREE(0x42600000,0x00000000)}},
+ {VT_exponent,22,0x3a86ff,{DOUBLEWITHTWODWORDINTREE(0x42700000,0x00000000)}},
+ {VT_exponent,22,0x3a8740,{DOUBLEWITHTWODWORDINTREE(0x42800000,0x00000000)}},
+ {VT_exponent,22,0x3a8741,{DOUBLEWITHTWODWORDINTREE(0x42900000,0x00000000)}},
+ {VT_exponent,22,0x3a8742,{DOUBLEWITHTWODWORDINTREE(0x42a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8743,{DOUBLEWITHTWODWORDINTREE(0x42b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8744,{DOUBLEWITHTWODWORDINTREE(0x42c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8745,{DOUBLEWITHTWODWORDINTREE(0x42d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8746,{DOUBLEWITHTWODWORDINTREE(0x42e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8747,{DOUBLEWITHTWODWORDINTREE(0x42f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8748,{DOUBLEWITHTWODWORDINTREE(0x43000000,0x00000000)}},
+ {VT_exponent,22,0x3a8749,{DOUBLEWITHTWODWORDINTREE(0x43100000,0x00000000)}},
+ {VT_exponent,22,0x3a874a,{DOUBLEWITHTWODWORDINTREE(0x43200000,0x00000000)}},
+ {VT_exponent,22,0x3a874b,{DOUBLEWITHTWODWORDINTREE(0x43300000,0x00000000)}},
+ {VT_exponent,22,0x3a874c,{DOUBLEWITHTWODWORDINTREE(0x43400000,0x00000000)}},
+ {VT_exponent,22,0x3a874d,{DOUBLEWITHTWODWORDINTREE(0x43500000,0x00000000)}},
+ {VT_exponent,22,0x3a874e,{DOUBLEWITHTWODWORDINTREE(0x43600000,0x00000000)}},
+ {VT_exponent,22,0x3a874f,{DOUBLEWITHTWODWORDINTREE(0x43700000,0x00000000)}},
+ {VT_exponent,22,0x3a8750,{DOUBLEWITHTWODWORDINTREE(0x43800000,0x00000000)}},
+ {VT_exponent,22,0x3a8751,{DOUBLEWITHTWODWORDINTREE(0x43900000,0x00000000)}},
+ {VT_exponent,22,0x3a8752,{DOUBLEWITHTWODWORDINTREE(0x43a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8753,{DOUBLEWITHTWODWORDINTREE(0x43b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8754,{DOUBLEWITHTWODWORDINTREE(0x43c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8755,{DOUBLEWITHTWODWORDINTREE(0x43d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8756,{DOUBLEWITHTWODWORDINTREE(0x43e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8757,{DOUBLEWITHTWODWORDINTREE(0x43f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8758,{DOUBLEWITHTWODWORDINTREE(0x44000000,0x00000000)}},
+ {VT_exponent,15,0x1a3b,{DOUBLEWITHTWODWORDINTREE(0x44100000,0x00000000)}},
+ {VT_exponent,22,0x3a8759,{DOUBLEWITHTWODWORDINTREE(0x44200000,0x00000000)}},
+ {VT_exponent,22,0x3a875a,{DOUBLEWITHTWODWORDINTREE(0x44300000,0x00000000)}},
+ {VT_exponent,22,0x3a875b,{DOUBLEWITHTWODWORDINTREE(0x44400000,0x00000000)}},
+ {VT_exponent,22,0x3a875c,{DOUBLEWITHTWODWORDINTREE(0x44500000,0x00000000)}},
+ {VT_exponent,22,0x3a875d,{DOUBLEWITHTWODWORDINTREE(0x44600000,0x00000000)}},
+ {VT_exponent,22,0x3a875e,{DOUBLEWITHTWODWORDINTREE(0x44700000,0x00000000)}},
+ {VT_exponent,22,0x3a875f,{DOUBLEWITHTWODWORDINTREE(0x44800000,0x00000000)}},
+ {VT_exponent,22,0x3a8760,{DOUBLEWITHTWODWORDINTREE(0x44900000,0x00000000)}},
+ {VT_exponent,22,0x3a8761,{DOUBLEWITHTWODWORDINTREE(0x44a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8762,{DOUBLEWITHTWODWORDINTREE(0x44b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8763,{DOUBLEWITHTWODWORDINTREE(0x44c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8764,{DOUBLEWITHTWODWORDINTREE(0x44d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8765,{DOUBLEWITHTWODWORDINTREE(0x44e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8766,{DOUBLEWITHTWODWORDINTREE(0x44f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8767,{DOUBLEWITHTWODWORDINTREE(0x45000000,0x00000000)}},
+ {VT_exponent,22,0x3a8768,{DOUBLEWITHTWODWORDINTREE(0x45100000,0x00000000)}},
+ {VT_exponent,22,0x3a8769,{DOUBLEWITHTWODWORDINTREE(0x45200000,0x00000000)}},
+ {VT_exponent,22,0x3a876a,{DOUBLEWITHTWODWORDINTREE(0x45300000,0x00000000)}},
+ {VT_exponent,22,0x3a876b,{DOUBLEWITHTWODWORDINTREE(0x45400000,0x00000000)}},
+ {VT_exponent,22,0x3a876c,{DOUBLEWITHTWODWORDINTREE(0x45500000,0x00000000)}},
+ {VT_exponent,22,0x3a876d,{DOUBLEWITHTWODWORDINTREE(0x45600000,0x00000000)}},
+ {VT_exponent,22,0x3a876e,{DOUBLEWITHTWODWORDINTREE(0x45700000,0x00000000)}},
+ {VT_exponent,22,0x3a876f,{DOUBLEWITHTWODWORDINTREE(0x45800000,0x00000000)}},
+ {VT_exponent,22,0x3a8770,{DOUBLEWITHTWODWORDINTREE(0x45900000,0x00000000)}},
+ {VT_exponent,22,0x3a8771,{DOUBLEWITHTWODWORDINTREE(0x45a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8772,{DOUBLEWITHTWODWORDINTREE(0x45b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8773,{DOUBLEWITHTWODWORDINTREE(0x45c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8774,{DOUBLEWITHTWODWORDINTREE(0x45d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8775,{DOUBLEWITHTWODWORDINTREE(0x45e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8776,{DOUBLEWITHTWODWORDINTREE(0x45f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8777,{DOUBLEWITHTWODWORDINTREE(0x46000000,0x00000000)}},
+ {VT_exponent,22,0x3a8778,{DOUBLEWITHTWODWORDINTREE(0x46100000,0x00000000)}},
+ {VT_exponent,22,0x3a8779,{DOUBLEWITHTWODWORDINTREE(0x46200000,0x00000000)}},
+ {VT_exponent,22,0x3a877a,{DOUBLEWITHTWODWORDINTREE(0x46300000,0x00000000)}},
+ {VT_exponent,22,0x3a877b,{DOUBLEWITHTWODWORDINTREE(0x46400000,0x00000000)}},
+ {VT_exponent,22,0x3a877c,{DOUBLEWITHTWODWORDINTREE(0x46500000,0x00000000)}},
+ {VT_exponent,22,0x3a877d,{DOUBLEWITHTWODWORDINTREE(0x46600000,0x00000000)}},
+ {VT_exponent,22,0x3a877e,{DOUBLEWITHTWODWORDINTREE(0x46700000,0x00000000)}},
+ {VT_exponent,22,0x3a877f,{DOUBLEWITHTWODWORDINTREE(0x46800000,0x00000000)}},
+ {VT_exponent,22,0x3a8780,{DOUBLEWITHTWODWORDINTREE(0x46900000,0x00000000)}},
+ {VT_exponent,22,0x3a8781,{DOUBLEWITHTWODWORDINTREE(0x46a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8782,{DOUBLEWITHTWODWORDINTREE(0x46b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8783,{DOUBLEWITHTWODWORDINTREE(0x46c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8784,{DOUBLEWITHTWODWORDINTREE(0x46d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8785,{DOUBLEWITHTWODWORDINTREE(0x46e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8786,{DOUBLEWITHTWODWORDINTREE(0x46f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8787,{DOUBLEWITHTWODWORDINTREE(0x47000000,0x00000000)}},
+ {VT_exponent,22,0x3a8788,{DOUBLEWITHTWODWORDINTREE(0x47100000,0x00000000)}},
+ {VT_exponent,22,0x3a8789,{DOUBLEWITHTWODWORDINTREE(0x47200000,0x00000000)}},
+ {VT_exponent,22,0x3a878a,{DOUBLEWITHTWODWORDINTREE(0x47300000,0x00000000)}},
+ {VT_exponent,22,0x3a878b,{DOUBLEWITHTWODWORDINTREE(0x47400000,0x00000000)}},
+ {VT_exponent,22,0x3a878c,{DOUBLEWITHTWODWORDINTREE(0x47500000,0x00000000)}},
+ {VT_exponent,22,0x3a878d,{DOUBLEWITHTWODWORDINTREE(0x47600000,0x00000000)}},
+ {VT_exponent,22,0x3a878e,{DOUBLEWITHTWODWORDINTREE(0x47700000,0x00000000)}},
+ {VT_exponent,22,0x3a878f,{DOUBLEWITHTWODWORDINTREE(0x47800000,0x00000000)}},
+ {VT_exponent,22,0x3a8790,{DOUBLEWITHTWODWORDINTREE(0x47900000,0x00000000)}},
+ {VT_exponent,22,0x3a8791,{DOUBLEWITHTWODWORDINTREE(0x47a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8792,{DOUBLEWITHTWODWORDINTREE(0x47b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8793,{DOUBLEWITHTWODWORDINTREE(0x47c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8794,{DOUBLEWITHTWODWORDINTREE(0x47d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8795,{DOUBLEWITHTWODWORDINTREE(0x47e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8796,{DOUBLEWITHTWODWORDINTREE(0x47f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8797,{DOUBLEWITHTWODWORDINTREE(0x48000000,0x00000000)}},
+ {VT_exponent,22,0x3a8798,{DOUBLEWITHTWODWORDINTREE(0x48100000,0x00000000)}},
+ {VT_exponent,22,0x3a8799,{DOUBLEWITHTWODWORDINTREE(0x48200000,0x00000000)}},
+ {VT_exponent,22,0x3a879a,{DOUBLEWITHTWODWORDINTREE(0x48300000,0x00000000)}},
+ {VT_exponent,22,0x3a879b,{DOUBLEWITHTWODWORDINTREE(0x48400000,0x00000000)}},
+ {VT_exponent,22,0x3a879c,{DOUBLEWITHTWODWORDINTREE(0x48500000,0x00000000)}},
+ {VT_exponent,22,0x3a879d,{DOUBLEWITHTWODWORDINTREE(0x48600000,0x00000000)}},
+ {VT_exponent,22,0x3a879e,{DOUBLEWITHTWODWORDINTREE(0x48700000,0x00000000)}},
+ {VT_exponent,22,0x3a879f,{DOUBLEWITHTWODWORDINTREE(0x48800000,0x00000000)}},
+ {VT_exponent,22,0x3a87a0,{DOUBLEWITHTWODWORDINTREE(0x48900000,0x00000000)}},
+ {VT_exponent,22,0x3a87a1,{DOUBLEWITHTWODWORDINTREE(0x48a00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a2,{DOUBLEWITHTWODWORDINTREE(0x48b00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a3,{DOUBLEWITHTWODWORDINTREE(0x48c00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a4,{DOUBLEWITHTWODWORDINTREE(0x48d00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a5,{DOUBLEWITHTWODWORDINTREE(0x48e00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a6,{DOUBLEWITHTWODWORDINTREE(0x48f00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a7,{DOUBLEWITHTWODWORDINTREE(0x49000000,0x00000000)}},
+ {VT_exponent,22,0x3a87a8,{DOUBLEWITHTWODWORDINTREE(0x49100000,0x00000000)}},
+ {VT_exponent,22,0x3a87a9,{DOUBLEWITHTWODWORDINTREE(0x49200000,0x00000000)}},
+ {VT_exponent,22,0x3a87aa,{DOUBLEWITHTWODWORDINTREE(0x49300000,0x00000000)}},
+ {VT_exponent,22,0x3a87ab,{DOUBLEWITHTWODWORDINTREE(0x49400000,0x00000000)}},
+ {VT_exponent,22,0x3a87ac,{DOUBLEWITHTWODWORDINTREE(0x49500000,0x00000000)}},
+ {VT_exponent,22,0x3a87ad,{DOUBLEWITHTWODWORDINTREE(0x49600000,0x00000000)}},
+ {VT_exponent,22,0x3a87ae,{DOUBLEWITHTWODWORDINTREE(0x49700000,0x00000000)}},
+ {VT_exponent,22,0x3a87af,{DOUBLEWITHTWODWORDINTREE(0x49800000,0x00000000)}},
+ {VT_exponent,22,0x3a87b0,{DOUBLEWITHTWODWORDINTREE(0x49900000,0x00000000)}},
+ {VT_exponent,22,0x3a87b1,{DOUBLEWITHTWODWORDINTREE(0x49a00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b2,{DOUBLEWITHTWODWORDINTREE(0x49b00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b3,{DOUBLEWITHTWODWORDINTREE(0x49c00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b4,{DOUBLEWITHTWODWORDINTREE(0x49d00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b5,{DOUBLEWITHTWODWORDINTREE(0x49e00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b6,{DOUBLEWITHTWODWORDINTREE(0x49f00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b7,{DOUBLEWITHTWODWORDINTREE(0x4a000000,0x00000000)}},
+ {VT_exponent,22,0x3a87b8,{DOUBLEWITHTWODWORDINTREE(0x4a100000,0x00000000)}},
+ {VT_exponent,22,0x3a87b9,{DOUBLEWITHTWODWORDINTREE(0x4a200000,0x00000000)}},
+ {VT_exponent,22,0x3a87ba,{DOUBLEWITHTWODWORDINTREE(0x4a300000,0x00000000)}},
+ {VT_exponent,22,0x3a87bb,{DOUBLEWITHTWODWORDINTREE(0x4a400000,0x00000000)}},
+ {VT_exponent,22,0x3a87bc,{DOUBLEWITHTWODWORDINTREE(0x4a500000,0x00000000)}},
+ {VT_exponent,22,0x3a87bd,{DOUBLEWITHTWODWORDINTREE(0x4a600000,0x00000000)}},
+ {VT_exponent,22,0x3a87be,{DOUBLEWITHTWODWORDINTREE(0x4a700000,0x00000000)}},
+ {VT_exponent,22,0x3a87bf,{DOUBLEWITHTWODWORDINTREE(0x4a800000,0x00000000)}},
+ {VT_exponent,22,0x3a87c0,{DOUBLEWITHTWODWORDINTREE(0x4a900000,0x00000000)}},
+ {VT_exponent,22,0x3a87c1,{DOUBLEWITHTWODWORDINTREE(0x4aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c2,{DOUBLEWITHTWODWORDINTREE(0x4ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c3,{DOUBLEWITHTWODWORDINTREE(0x4ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c4,{DOUBLEWITHTWODWORDINTREE(0x4ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c5,{DOUBLEWITHTWODWORDINTREE(0x4ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c6,{DOUBLEWITHTWODWORDINTREE(0x4af00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c7,{DOUBLEWITHTWODWORDINTREE(0x4b000000,0x00000000)}},
+ {VT_exponent,22,0x3a87c8,{DOUBLEWITHTWODWORDINTREE(0x4b100000,0x00000000)}},
+ {VT_exponent,22,0x3a87c9,{DOUBLEWITHTWODWORDINTREE(0x4b200000,0x00000000)}},
+ {VT_exponent,22,0x3a87ca,{DOUBLEWITHTWODWORDINTREE(0x4b300000,0x00000000)}},
+ {VT_exponent,22,0x3a87cb,{DOUBLEWITHTWODWORDINTREE(0x4b400000,0x00000000)}},
+ {VT_exponent,22,0x3a87cc,{DOUBLEWITHTWODWORDINTREE(0x4b500000,0x00000000)}},
+ {VT_exponent,22,0x3a87cd,{DOUBLEWITHTWODWORDINTREE(0x4b600000,0x00000000)}},
+ {VT_exponent,22,0x3a87ce,{DOUBLEWITHTWODWORDINTREE(0x4b700000,0x00000000)}},
+ {VT_exponent,22,0x3a87cf,{DOUBLEWITHTWODWORDINTREE(0x4b800000,0x00000000)}},
+ {VT_exponent,22,0x3a87d0,{DOUBLEWITHTWODWORDINTREE(0x4b900000,0x00000000)}},
+ {VT_exponent,22,0x3a87d1,{DOUBLEWITHTWODWORDINTREE(0x4ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d2,{DOUBLEWITHTWODWORDINTREE(0x4bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d3,{DOUBLEWITHTWODWORDINTREE(0x4bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d4,{DOUBLEWITHTWODWORDINTREE(0x4bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d5,{DOUBLEWITHTWODWORDINTREE(0x4be00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d6,{DOUBLEWITHTWODWORDINTREE(0x4bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d7,{DOUBLEWITHTWODWORDINTREE(0x4c000000,0x00000000)}},
+ {VT_exponent,22,0x3a87d8,{DOUBLEWITHTWODWORDINTREE(0x4c100000,0x00000000)}},
+ {VT_exponent,22,0x3a87d9,{DOUBLEWITHTWODWORDINTREE(0x4c200000,0x00000000)}},
+ {VT_exponent,22,0x3a87da,{DOUBLEWITHTWODWORDINTREE(0x4c300000,0x00000000)}},
+ {VT_exponent,22,0x3a87db,{DOUBLEWITHTWODWORDINTREE(0x4c400000,0x00000000)}},
+ {VT_exponent,22,0x3a87dc,{DOUBLEWITHTWODWORDINTREE(0x4c500000,0x00000000)}},
+ {VT_exponent,22,0x3a87dd,{DOUBLEWITHTWODWORDINTREE(0x4c600000,0x00000000)}},
+ {VT_exponent,22,0x3a87de,{DOUBLEWITHTWODWORDINTREE(0x4c700000,0x00000000)}},
+ {VT_exponent,22,0x3a87df,{DOUBLEWITHTWODWORDINTREE(0x4c800000,0x00000000)}},
+ {VT_exponent,22,0x3a87e0,{DOUBLEWITHTWODWORDINTREE(0x4c900000,0x00000000)}},
+ {VT_exponent,22,0x3a87e1,{DOUBLEWITHTWODWORDINTREE(0x4ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e2,{DOUBLEWITHTWODWORDINTREE(0x4cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e3,{DOUBLEWITHTWODWORDINTREE(0x4cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e4,{DOUBLEWITHTWODWORDINTREE(0x4cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e5,{DOUBLEWITHTWODWORDINTREE(0x4ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e6,{DOUBLEWITHTWODWORDINTREE(0x4cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e7,{DOUBLEWITHTWODWORDINTREE(0x4d000000,0x00000000)}},
+ {VT_exponent,22,0x3a87e8,{DOUBLEWITHTWODWORDINTREE(0x4d100000,0x00000000)}},
+ {VT_exponent,22,0x3a87e9,{DOUBLEWITHTWODWORDINTREE(0x4d200000,0x00000000)}},
+ {VT_exponent,22,0x3a87ea,{DOUBLEWITHTWODWORDINTREE(0x4d300000,0x00000000)}},
+ {VT_exponent,22,0x3a87eb,{DOUBLEWITHTWODWORDINTREE(0x4d400000,0x00000000)}},
+ {VT_exponent,22,0x3a87ec,{DOUBLEWITHTWODWORDINTREE(0x4d500000,0x00000000)}},
+ {VT_exponent,22,0x3a87ed,{DOUBLEWITHTWODWORDINTREE(0x4d600000,0x00000000)}},
+ {VT_exponent,22,0x3a87ee,{DOUBLEWITHTWODWORDINTREE(0x4d700000,0x00000000)}},
+ {VT_exponent,22,0x3a87ef,{DOUBLEWITHTWODWORDINTREE(0x4d800000,0x00000000)}},
+ {VT_exponent,22,0x3a87f0,{DOUBLEWITHTWODWORDINTREE(0x4d900000,0x00000000)}},
+ {VT_exponent,22,0x3a87f1,{DOUBLEWITHTWODWORDINTREE(0x4da00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f2,{DOUBLEWITHTWODWORDINTREE(0x4db00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f3,{DOUBLEWITHTWODWORDINTREE(0x4dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f4,{DOUBLEWITHTWODWORDINTREE(0x4dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f5,{DOUBLEWITHTWODWORDINTREE(0x4de00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f6,{DOUBLEWITHTWODWORDINTREE(0x4df00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f7,{DOUBLEWITHTWODWORDINTREE(0x4e000000,0x00000000)}},
+ {VT_exponent,22,0x3a87f8,{DOUBLEWITHTWODWORDINTREE(0x4e100000,0x00000000)}},
+ {VT_exponent,22,0x3a87f9,{DOUBLEWITHTWODWORDINTREE(0x4e200000,0x00000000)}},
+ {VT_exponent,22,0x3a87fa,{DOUBLEWITHTWODWORDINTREE(0x4e300000,0x00000000)}},
+ {VT_exponent,22,0x3a87fb,{DOUBLEWITHTWODWORDINTREE(0x4e400000,0x00000000)}},
+ {VT_exponent,22,0x3a87fc,{DOUBLEWITHTWODWORDINTREE(0x4e500000,0x00000000)}},
+ {VT_exponent,22,0x3a87fd,{DOUBLEWITHTWODWORDINTREE(0x4e600000,0x00000000)}},
+ {VT_exponent,22,0x3a87fe,{DOUBLEWITHTWODWORDINTREE(0x4e700000,0x00000000)}},
+ {VT_exponent,22,0x3a87ff,{DOUBLEWITHTWODWORDINTREE(0x4e800000,0x00000000)}},
+ {VT_exponent,22,0x3a9000,{DOUBLEWITHTWODWORDINTREE(0x4e900000,0x00000000)}},
+ {VT_exponent,22,0x3a9001,{DOUBLEWITHTWODWORDINTREE(0x4ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a9002,{DOUBLEWITHTWODWORDINTREE(0x4eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9003,{DOUBLEWITHTWODWORDINTREE(0x4ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a9004,{DOUBLEWITHTWODWORDINTREE(0x4ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a9005,{DOUBLEWITHTWODWORDINTREE(0x4ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a9006,{DOUBLEWITHTWODWORDINTREE(0x4ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a9007,{DOUBLEWITHTWODWORDINTREE(0x4f000000,0x00000000)}},
+ {VT_exponent,22,0x3a9008,{DOUBLEWITHTWODWORDINTREE(0x4f100000,0x00000000)}},
+ {VT_exponent,22,0x3a9009,{DOUBLEWITHTWODWORDINTREE(0x4f200000,0x00000000)}},
+ {VT_exponent,22,0x3a900a,{DOUBLEWITHTWODWORDINTREE(0x4f300000,0x00000000)}},
+ {VT_exponent,22,0x3a900b,{DOUBLEWITHTWODWORDINTREE(0x4f400000,0x00000000)}},
+ {VT_exponent,22,0x3a900c,{DOUBLEWITHTWODWORDINTREE(0x4f500000,0x00000000)}},
+ {VT_exponent,22,0x3a900d,{DOUBLEWITHTWODWORDINTREE(0x4f600000,0x00000000)}},
+ {VT_exponent,22,0x3a900e,{DOUBLEWITHTWODWORDINTREE(0x4f700000,0x00000000)}},
+ {VT_exponent,22,0x3a900f,{DOUBLEWITHTWODWORDINTREE(0x4f800000,0x00000000)}},
+ {VT_exponent,22,0x3a9010,{DOUBLEWITHTWODWORDINTREE(0x4f900000,0x00000000)}},
+ {VT_exponent,22,0x3a9011,{DOUBLEWITHTWODWORDINTREE(0x4fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a9012,{DOUBLEWITHTWODWORDINTREE(0x4fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9013,{DOUBLEWITHTWODWORDINTREE(0x4fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a9014,{DOUBLEWITHTWODWORDINTREE(0x4fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a9015,{DOUBLEWITHTWODWORDINTREE(0x4fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a9016,{DOUBLEWITHTWODWORDINTREE(0x4ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a9017,{DOUBLEWITHTWODWORDINTREE(0x50000000,0x00000000)}},
+ {VT_exponent,22,0x3a9018,{DOUBLEWITHTWODWORDINTREE(0x50100000,0x00000000)}},
+ {VT_exponent,22,0x3a9019,{DOUBLEWITHTWODWORDINTREE(0x50200000,0x00000000)}},
+ {VT_exponent,22,0x3a901a,{DOUBLEWITHTWODWORDINTREE(0x50300000,0x00000000)}},
+ {VT_exponent,22,0x3a901b,{DOUBLEWITHTWODWORDINTREE(0x50400000,0x00000000)}},
+ {VT_exponent,22,0x3a901c,{DOUBLEWITHTWODWORDINTREE(0x50500000,0x00000000)}},
+ {VT_exponent,22,0x3a901d,{DOUBLEWITHTWODWORDINTREE(0x50600000,0x00000000)}},
+ {VT_exponent,22,0x3a901e,{DOUBLEWITHTWODWORDINTREE(0x50700000,0x00000000)}},
+ {VT_exponent,22,0x3a901f,{DOUBLEWITHTWODWORDINTREE(0x50800000,0x00000000)}},
+ {VT_exponent,22,0x3a9020,{DOUBLEWITHTWODWORDINTREE(0x50900000,0x00000000)}},
+ {VT_exponent,22,0x3a9021,{DOUBLEWITHTWODWORDINTREE(0x50a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9022,{DOUBLEWITHTWODWORDINTREE(0x50b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9023,{DOUBLEWITHTWODWORDINTREE(0x50c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9024,{DOUBLEWITHTWODWORDINTREE(0x50d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9025,{DOUBLEWITHTWODWORDINTREE(0x50e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9026,{DOUBLEWITHTWODWORDINTREE(0x50f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9027,{DOUBLEWITHTWODWORDINTREE(0x51000000,0x00000000)}},
+ {VT_exponent,22,0x3a9028,{DOUBLEWITHTWODWORDINTREE(0x51100000,0x00000000)}},
+ {VT_exponent,22,0x3a9029,{DOUBLEWITHTWODWORDINTREE(0x51200000,0x00000000)}},
+ {VT_exponent,22,0x3a902a,{DOUBLEWITHTWODWORDINTREE(0x51300000,0x00000000)}},
+ {VT_exponent,22,0x3a902b,{DOUBLEWITHTWODWORDINTREE(0x51400000,0x00000000)}},
+ {VT_exponent,22,0x3a902c,{DOUBLEWITHTWODWORDINTREE(0x51500000,0x00000000)}},
+ {VT_exponent,22,0x3a902d,{DOUBLEWITHTWODWORDINTREE(0x51600000,0x00000000)}},
+ {VT_exponent,22,0x3a902e,{DOUBLEWITHTWODWORDINTREE(0x51700000,0x00000000)}},
+ {VT_exponent,22,0x3a902f,{DOUBLEWITHTWODWORDINTREE(0x51800000,0x00000000)}},
+ {VT_exponent,22,0x3a9030,{DOUBLEWITHTWODWORDINTREE(0x51900000,0x00000000)}},
+ {VT_exponent,22,0x3a9031,{DOUBLEWITHTWODWORDINTREE(0x51a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9032,{DOUBLEWITHTWODWORDINTREE(0x51b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9033,{DOUBLEWITHTWODWORDINTREE(0x51c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9034,{DOUBLEWITHTWODWORDINTREE(0x51d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9035,{DOUBLEWITHTWODWORDINTREE(0x51e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9036,{DOUBLEWITHTWODWORDINTREE(0x51f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9037,{DOUBLEWITHTWODWORDINTREE(0x52000000,0x00000000)}},
+ {VT_exponent,22,0x3a9038,{DOUBLEWITHTWODWORDINTREE(0x52100000,0x00000000)}},
+ {VT_exponent,22,0x3a9039,{DOUBLEWITHTWODWORDINTREE(0x52200000,0x00000000)}},
+ {VT_exponent,22,0x3a903a,{DOUBLEWITHTWODWORDINTREE(0x52300000,0x00000000)}},
+ {VT_exponent,22,0x3a903b,{DOUBLEWITHTWODWORDINTREE(0x52400000,0x00000000)}},
+ {VT_exponent,22,0x3a903c,{DOUBLEWITHTWODWORDINTREE(0x52500000,0x00000000)}},
+ {VT_exponent,22,0x3a903d,{DOUBLEWITHTWODWORDINTREE(0x52600000,0x00000000)}},
+ {VT_exponent,22,0x3a903e,{DOUBLEWITHTWODWORDINTREE(0x52700000,0x00000000)}},
+ {VT_exponent,22,0x3a903f,{DOUBLEWITHTWODWORDINTREE(0x52800000,0x00000000)}},
+ {VT_exponent,22,0x3a9040,{DOUBLEWITHTWODWORDINTREE(0x52900000,0x00000000)}},
+ {VT_exponent,22,0x3a9041,{DOUBLEWITHTWODWORDINTREE(0x52a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9042,{DOUBLEWITHTWODWORDINTREE(0x52b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9043,{DOUBLEWITHTWODWORDINTREE(0x52c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9044,{DOUBLEWITHTWODWORDINTREE(0x52d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9045,{DOUBLEWITHTWODWORDINTREE(0x52e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9046,{DOUBLEWITHTWODWORDINTREE(0x52f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9047,{DOUBLEWITHTWODWORDINTREE(0x53000000,0x00000000)}},
+ {VT_exponent,22,0x3a9048,{DOUBLEWITHTWODWORDINTREE(0x53100000,0x00000000)}},
+ {VT_exponent,22,0x3a9049,{DOUBLEWITHTWODWORDINTREE(0x53200000,0x00000000)}},
+ {VT_exponent,22,0x3a904a,{DOUBLEWITHTWODWORDINTREE(0x53300000,0x00000000)}},
+ {VT_exponent,22,0x3a904b,{DOUBLEWITHTWODWORDINTREE(0x53400000,0x00000000)}},
+ {VT_exponent,22,0x3a904c,{DOUBLEWITHTWODWORDINTREE(0x53500000,0x00000000)}},
+ {VT_exponent,22,0x3a904d,{DOUBLEWITHTWODWORDINTREE(0x53600000,0x00000000)}},
+ {VT_exponent,22,0x3a904e,{DOUBLEWITHTWODWORDINTREE(0x53700000,0x00000000)}},
+ {VT_exponent,22,0x3a904f,{DOUBLEWITHTWODWORDINTREE(0x53800000,0x00000000)}},
+ {VT_exponent,22,0x3a9050,{DOUBLEWITHTWODWORDINTREE(0x53900000,0x00000000)}},
+ {VT_exponent,22,0x3a9051,{DOUBLEWITHTWODWORDINTREE(0x53a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9052,{DOUBLEWITHTWODWORDINTREE(0x53b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9053,{DOUBLEWITHTWODWORDINTREE(0x53c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9054,{DOUBLEWITHTWODWORDINTREE(0x53d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9055,{DOUBLEWITHTWODWORDINTREE(0x53e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9056,{DOUBLEWITHTWODWORDINTREE(0x53f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9057,{DOUBLEWITHTWODWORDINTREE(0x54000000,0x00000000)}},
+ {VT_exponent,22,0x3a9058,{DOUBLEWITHTWODWORDINTREE(0x54100000,0x00000000)}},
+ {VT_exponent,22,0x3a9059,{DOUBLEWITHTWODWORDINTREE(0x54200000,0x00000000)}},
+ {VT_exponent,22,0x3a905a,{DOUBLEWITHTWODWORDINTREE(0x54300000,0x00000000)}},
+ {VT_exponent,22,0x3a905b,{DOUBLEWITHTWODWORDINTREE(0x54400000,0x00000000)}},
+ {VT_exponent,22,0x3a905c,{DOUBLEWITHTWODWORDINTREE(0x54500000,0x00000000)}},
+ {VT_exponent,22,0x3a905d,{DOUBLEWITHTWODWORDINTREE(0x54600000,0x00000000)}},
+ {VT_exponent,22,0x3a905e,{DOUBLEWITHTWODWORDINTREE(0x54700000,0x00000000)}},
+ {VT_exponent,22,0x3a905f,{DOUBLEWITHTWODWORDINTREE(0x54800000,0x00000000)}},
+ {VT_exponent,22,0x3a9060,{DOUBLEWITHTWODWORDINTREE(0x54900000,0x00000000)}},
+ {VT_exponent,22,0x3a9061,{DOUBLEWITHTWODWORDINTREE(0x54a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9062,{DOUBLEWITHTWODWORDINTREE(0x54b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9063,{DOUBLEWITHTWODWORDINTREE(0x54c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9064,{DOUBLEWITHTWODWORDINTREE(0x54d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9065,{DOUBLEWITHTWODWORDINTREE(0x54e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9066,{DOUBLEWITHTWODWORDINTREE(0x54f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9067,{DOUBLEWITHTWODWORDINTREE(0x55000000,0x00000000)}},
+ {VT_exponent,22,0x3a9068,{DOUBLEWITHTWODWORDINTREE(0x55100000,0x00000000)}},
+ {VT_exponent,22,0x3a9069,{DOUBLEWITHTWODWORDINTREE(0x55200000,0x00000000)}},
+ {VT_exponent,22,0x3a906a,{DOUBLEWITHTWODWORDINTREE(0x55300000,0x00000000)}},
+ {VT_exponent,22,0x3a906b,{DOUBLEWITHTWODWORDINTREE(0x55400000,0x00000000)}},
+ {VT_exponent,22,0x3a906c,{DOUBLEWITHTWODWORDINTREE(0x55500000,0x00000000)}},
+ {VT_exponent,22,0x3a906d,{DOUBLEWITHTWODWORDINTREE(0x55600000,0x00000000)}},
+ {VT_exponent,22,0x3a906e,{DOUBLEWITHTWODWORDINTREE(0x55700000,0x00000000)}},
+ {VT_exponent,22,0x3a906f,{DOUBLEWITHTWODWORDINTREE(0x55800000,0x00000000)}},
+ {VT_exponent,22,0x3a9070,{DOUBLEWITHTWODWORDINTREE(0x55900000,0x00000000)}},
+ {VT_exponent,22,0x3a9071,{DOUBLEWITHTWODWORDINTREE(0x55a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9072,{DOUBLEWITHTWODWORDINTREE(0x55b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9073,{DOUBLEWITHTWODWORDINTREE(0x55c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9074,{DOUBLEWITHTWODWORDINTREE(0x55d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9075,{DOUBLEWITHTWODWORDINTREE(0x55e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9076,{DOUBLEWITHTWODWORDINTREE(0x55f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9077,{DOUBLEWITHTWODWORDINTREE(0x56000000,0x00000000)}},
+ {VT_exponent,22,0x3a9078,{DOUBLEWITHTWODWORDINTREE(0x56100000,0x00000000)}},
+ {VT_exponent,22,0x3a9079,{DOUBLEWITHTWODWORDINTREE(0x56200000,0x00000000)}},
+ {VT_exponent,22,0x3a907a,{DOUBLEWITHTWODWORDINTREE(0x56300000,0x00000000)}},
+ {VT_exponent,22,0x3a907b,{DOUBLEWITHTWODWORDINTREE(0x56400000,0x00000000)}},
+ {VT_exponent,22,0x3a907c,{DOUBLEWITHTWODWORDINTREE(0x56500000,0x00000000)}},
+ {VT_exponent,22,0x3a907d,{DOUBLEWITHTWODWORDINTREE(0x56600000,0x00000000)}},
+ {VT_exponent,22,0x3a907e,{DOUBLEWITHTWODWORDINTREE(0x56700000,0x00000000)}},
+ {VT_exponent,22,0x3a907f,{DOUBLEWITHTWODWORDINTREE(0x56800000,0x00000000)}},
+ {VT_exponent,22,0x3a9080,{DOUBLEWITHTWODWORDINTREE(0x56900000,0x00000000)}},
+ {VT_exponent,22,0x3a9081,{DOUBLEWITHTWODWORDINTREE(0x56a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9082,{DOUBLEWITHTWODWORDINTREE(0x56b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9083,{DOUBLEWITHTWODWORDINTREE(0x56c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9084,{DOUBLEWITHTWODWORDINTREE(0x56d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9085,{DOUBLEWITHTWODWORDINTREE(0x56e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9086,{DOUBLEWITHTWODWORDINTREE(0x56f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9087,{DOUBLEWITHTWODWORDINTREE(0x57000000,0x00000000)}},
+ {VT_exponent,22,0x3a9088,{DOUBLEWITHTWODWORDINTREE(0x57100000,0x00000000)}},
+ {VT_exponent,22,0x3a9089,{DOUBLEWITHTWODWORDINTREE(0x57200000,0x00000000)}},
+ {VT_exponent,22,0x3a908a,{DOUBLEWITHTWODWORDINTREE(0x57300000,0x00000000)}},
+ {VT_exponent,22,0x3a908b,{DOUBLEWITHTWODWORDINTREE(0x57400000,0x00000000)}},
+ {VT_exponent,22,0x3a908c,{DOUBLEWITHTWODWORDINTREE(0x57500000,0x00000000)}},
+ {VT_exponent,22,0x3a908d,{DOUBLEWITHTWODWORDINTREE(0x57600000,0x00000000)}},
+ {VT_exponent,22,0x3a908e,{DOUBLEWITHTWODWORDINTREE(0x57700000,0x00000000)}},
+ {VT_exponent,22,0x3a908f,{DOUBLEWITHTWODWORDINTREE(0x57800000,0x00000000)}},
+ {VT_exponent,22,0x3a9090,{DOUBLEWITHTWODWORDINTREE(0x57900000,0x00000000)}},
+ {VT_exponent,22,0x3a9091,{DOUBLEWITHTWODWORDINTREE(0x57a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9092,{DOUBLEWITHTWODWORDINTREE(0x57b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9093,{DOUBLEWITHTWODWORDINTREE(0x57c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9094,{DOUBLEWITHTWODWORDINTREE(0x57d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9095,{DOUBLEWITHTWODWORDINTREE(0x57e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9096,{DOUBLEWITHTWODWORDINTREE(0x57f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9097,{DOUBLEWITHTWODWORDINTREE(0x58000000,0x00000000)}},
+ {VT_exponent,22,0x3a9098,{DOUBLEWITHTWODWORDINTREE(0x58100000,0x00000000)}},
+ {VT_exponent,22,0x3a9099,{DOUBLEWITHTWODWORDINTREE(0x58200000,0x00000000)}},
+ {VT_exponent,22,0x3a909a,{DOUBLEWITHTWODWORDINTREE(0x58300000,0x00000000)}},
+ {VT_exponent,22,0x3a909b,{DOUBLEWITHTWODWORDINTREE(0x58400000,0x00000000)}},
+ {VT_exponent,22,0x3a909c,{DOUBLEWITHTWODWORDINTREE(0x58500000,0x00000000)}},
+ {VT_exponent,22,0x3a909d,{DOUBLEWITHTWODWORDINTREE(0x58600000,0x00000000)}},
+ {VT_exponent,22,0x3a909e,{DOUBLEWITHTWODWORDINTREE(0x58700000,0x00000000)}},
+ {VT_exponent,22,0x3a909f,{DOUBLEWITHTWODWORDINTREE(0x58800000,0x00000000)}},
+ {VT_exponent,22,0x3a90a0,{DOUBLEWITHTWODWORDINTREE(0x58900000,0x00000000)}},
+ {VT_exponent,22,0x3a90a1,{DOUBLEWITHTWODWORDINTREE(0x58a00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a2,{DOUBLEWITHTWODWORDINTREE(0x58b00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a3,{DOUBLEWITHTWODWORDINTREE(0x58c00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a4,{DOUBLEWITHTWODWORDINTREE(0x58d00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a5,{DOUBLEWITHTWODWORDINTREE(0x58e00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a6,{DOUBLEWITHTWODWORDINTREE(0x58f00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a7,{DOUBLEWITHTWODWORDINTREE(0x59000000,0x00000000)}},
+ {VT_exponent,22,0x3a90a8,{DOUBLEWITHTWODWORDINTREE(0x59100000,0x00000000)}},
+ {VT_exponent,22,0x3a90a9,{DOUBLEWITHTWODWORDINTREE(0x59200000,0x00000000)}},
+ {VT_exponent,22,0x3a90aa,{DOUBLEWITHTWODWORDINTREE(0x59300000,0x00000000)}},
+ {VT_exponent,22,0x3a90ab,{DOUBLEWITHTWODWORDINTREE(0x59400000,0x00000000)}},
+ {VT_exponent,22,0x3a90ac,{DOUBLEWITHTWODWORDINTREE(0x59500000,0x00000000)}},
+ {VT_exponent,22,0x3a90ad,{DOUBLEWITHTWODWORDINTREE(0x59600000,0x00000000)}},
+ {VT_exponent,22,0x3a90ae,{DOUBLEWITHTWODWORDINTREE(0x59700000,0x00000000)}},
+ {VT_exponent,22,0x3a90af,{DOUBLEWITHTWODWORDINTREE(0x59800000,0x00000000)}},
+ {VT_exponent,22,0x3a90b0,{DOUBLEWITHTWODWORDINTREE(0x59900000,0x00000000)}},
+ {VT_exponent,22,0x3a90b1,{DOUBLEWITHTWODWORDINTREE(0x59a00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b2,{DOUBLEWITHTWODWORDINTREE(0x59b00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b3,{DOUBLEWITHTWODWORDINTREE(0x59c00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b4,{DOUBLEWITHTWODWORDINTREE(0x59d00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b5,{DOUBLEWITHTWODWORDINTREE(0x59e00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b6,{DOUBLEWITHTWODWORDINTREE(0x59f00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b7,{DOUBLEWITHTWODWORDINTREE(0x5a000000,0x00000000)}},
+ {VT_exponent,22,0x3a90b8,{DOUBLEWITHTWODWORDINTREE(0x5a100000,0x00000000)}},
+ {VT_exponent,22,0x3a90b9,{DOUBLEWITHTWODWORDINTREE(0x5a200000,0x00000000)}},
+ {VT_exponent,22,0x3a90ba,{DOUBLEWITHTWODWORDINTREE(0x5a300000,0x00000000)}},
+ {VT_exponent,22,0x3a90bb,{DOUBLEWITHTWODWORDINTREE(0x5a400000,0x00000000)}},
+ {VT_exponent,22,0x3a90bc,{DOUBLEWITHTWODWORDINTREE(0x5a500000,0x00000000)}},
+ {VT_exponent,22,0x3a90bd,{DOUBLEWITHTWODWORDINTREE(0x5a600000,0x00000000)}},
+ {VT_exponent,22,0x3a90be,{DOUBLEWITHTWODWORDINTREE(0x5a700000,0x00000000)}},
+ {VT_exponent,22,0x3a90bf,{DOUBLEWITHTWODWORDINTREE(0x5a800000,0x00000000)}},
+ {VT_exponent,22,0x3a90c0,{DOUBLEWITHTWODWORDINTREE(0x5a900000,0x00000000)}},
+ {VT_exponent,22,0x3a90c1,{DOUBLEWITHTWODWORDINTREE(0x5aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c2,{DOUBLEWITHTWODWORDINTREE(0x5ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c3,{DOUBLEWITHTWODWORDINTREE(0x5ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c4,{DOUBLEWITHTWODWORDINTREE(0x5ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c5,{DOUBLEWITHTWODWORDINTREE(0x5ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c6,{DOUBLEWITHTWODWORDINTREE(0x5af00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c7,{DOUBLEWITHTWODWORDINTREE(0x5b000000,0x00000000)}},
+ {VT_exponent,22,0x3a90c8,{DOUBLEWITHTWODWORDINTREE(0x5b100000,0x00000000)}},
+ {VT_exponent,22,0x3a90c9,{DOUBLEWITHTWODWORDINTREE(0x5b200000,0x00000000)}},
+ {VT_exponent,22,0x3a90ca,{DOUBLEWITHTWODWORDINTREE(0x5b300000,0x00000000)}},
+ {VT_exponent,22,0x3a90cb,{DOUBLEWITHTWODWORDINTREE(0x5b400000,0x00000000)}},
+ {VT_exponent,22,0x3a90cc,{DOUBLEWITHTWODWORDINTREE(0x5b500000,0x00000000)}},
+ {VT_exponent,22,0x3a90cd,{DOUBLEWITHTWODWORDINTREE(0x5b600000,0x00000000)}},
+ {VT_exponent,22,0x3a90ce,{DOUBLEWITHTWODWORDINTREE(0x5b700000,0x00000000)}},
+ {VT_exponent,22,0x3a90cf,{DOUBLEWITHTWODWORDINTREE(0x5b800000,0x00000000)}},
+ {VT_exponent,22,0x3a90d0,{DOUBLEWITHTWODWORDINTREE(0x5b900000,0x00000000)}},
+ {VT_exponent,22,0x3a90d1,{DOUBLEWITHTWODWORDINTREE(0x5ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d2,{DOUBLEWITHTWODWORDINTREE(0x5bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d3,{DOUBLEWITHTWODWORDINTREE(0x5bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d4,{DOUBLEWITHTWODWORDINTREE(0x5bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d5,{DOUBLEWITHTWODWORDINTREE(0x5be00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d6,{DOUBLEWITHTWODWORDINTREE(0x5bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d7,{DOUBLEWITHTWODWORDINTREE(0x5c000000,0x00000000)}},
+ {VT_exponent,22,0x3a90d8,{DOUBLEWITHTWODWORDINTREE(0x5c100000,0x00000000)}},
+ {VT_exponent,22,0x3a90d9,{DOUBLEWITHTWODWORDINTREE(0x5c200000,0x00000000)}},
+ {VT_exponent,22,0x3a90da,{DOUBLEWITHTWODWORDINTREE(0x5c300000,0x00000000)}},
+ {VT_exponent,22,0x3a90db,{DOUBLEWITHTWODWORDINTREE(0x5c400000,0x00000000)}},
+ {VT_exponent,22,0x3a90dc,{DOUBLEWITHTWODWORDINTREE(0x5c500000,0x00000000)}},
+ {VT_exponent,22,0x3a90dd,{DOUBLEWITHTWODWORDINTREE(0x5c600000,0x00000000)}},
+ {VT_exponent,22,0x3a90de,{DOUBLEWITHTWODWORDINTREE(0x5c700000,0x00000000)}},
+ {VT_exponent,22,0x3a90df,{DOUBLEWITHTWODWORDINTREE(0x5c800000,0x00000000)}},
+ {VT_exponent,22,0x3a90e0,{DOUBLEWITHTWODWORDINTREE(0x5c900000,0x00000000)}},
+ {VT_exponent,22,0x3a90e1,{DOUBLEWITHTWODWORDINTREE(0x5ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e2,{DOUBLEWITHTWODWORDINTREE(0x5cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e3,{DOUBLEWITHTWODWORDINTREE(0x5cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e4,{DOUBLEWITHTWODWORDINTREE(0x5cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e5,{DOUBLEWITHTWODWORDINTREE(0x5ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e6,{DOUBLEWITHTWODWORDINTREE(0x5cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e7,{DOUBLEWITHTWODWORDINTREE(0x5d000000,0x00000000)}},
+ {VT_exponent,22,0x3a90e8,{DOUBLEWITHTWODWORDINTREE(0x5d100000,0x00000000)}},
+ {VT_exponent,22,0x3a90e9,{DOUBLEWITHTWODWORDINTREE(0x5d200000,0x00000000)}},
+ {VT_exponent,22,0x3a90ea,{DOUBLEWITHTWODWORDINTREE(0x5d300000,0x00000000)}},
+ {VT_exponent,22,0x3a90eb,{DOUBLEWITHTWODWORDINTREE(0x5d400000,0x00000000)}},
+ {VT_exponent,22,0x3a90ec,{DOUBLEWITHTWODWORDINTREE(0x5d500000,0x00000000)}},
+ {VT_exponent,22,0x3a90ed,{DOUBLEWITHTWODWORDINTREE(0x5d600000,0x00000000)}},
+ {VT_exponent,22,0x3a90ee,{DOUBLEWITHTWODWORDINTREE(0x5d700000,0x00000000)}},
+ {VT_exponent,22,0x3a90ef,{DOUBLEWITHTWODWORDINTREE(0x5d800000,0x00000000)}},
+ {VT_exponent,22,0x3a90f0,{DOUBLEWITHTWODWORDINTREE(0x5d900000,0x00000000)}},
+ {VT_exponent,22,0x3a90f1,{DOUBLEWITHTWODWORDINTREE(0x5da00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f2,{DOUBLEWITHTWODWORDINTREE(0x5db00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f3,{DOUBLEWITHTWODWORDINTREE(0x5dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f4,{DOUBLEWITHTWODWORDINTREE(0x5dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f5,{DOUBLEWITHTWODWORDINTREE(0x5de00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f6,{DOUBLEWITHTWODWORDINTREE(0x5df00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f7,{DOUBLEWITHTWODWORDINTREE(0x5e000000,0x00000000)}},
+ {VT_exponent,22,0x3a90f8,{DOUBLEWITHTWODWORDINTREE(0x5e100000,0x00000000)}},
+ {VT_exponent,22,0x3a90f9,{DOUBLEWITHTWODWORDINTREE(0x5e200000,0x00000000)}},
+ {VT_exponent,22,0x3a90fa,{DOUBLEWITHTWODWORDINTREE(0x5e300000,0x00000000)}},
+ {VT_exponent,22,0x3a90fb,{DOUBLEWITHTWODWORDINTREE(0x5e400000,0x00000000)}},
+ {VT_exponent,22,0x3a90fc,{DOUBLEWITHTWODWORDINTREE(0x5e500000,0x00000000)}},
+ {VT_exponent,22,0x3a90fd,{DOUBLEWITHTWODWORDINTREE(0x5e600000,0x00000000)}},
+ {VT_exponent,22,0x3a90fe,{DOUBLEWITHTWODWORDINTREE(0x5e700000,0x00000000)}},
+ {VT_exponent,22,0x3a90ff,{DOUBLEWITHTWODWORDINTREE(0x5e800000,0x00000000)}},
+ {VT_exponent,22,0x3a9100,{DOUBLEWITHTWODWORDINTREE(0x5e900000,0x00000000)}},
+ {VT_exponent,22,0x3a9101,{DOUBLEWITHTWODWORDINTREE(0x5ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a9102,{DOUBLEWITHTWODWORDINTREE(0x5eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9103,{DOUBLEWITHTWODWORDINTREE(0x5ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a9104,{DOUBLEWITHTWODWORDINTREE(0x5ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a9105,{DOUBLEWITHTWODWORDINTREE(0x5ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a9106,{DOUBLEWITHTWODWORDINTREE(0x5ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a9107,{DOUBLEWITHTWODWORDINTREE(0x5f000000,0x00000000)}},
+ {VT_exponent,22,0x3a9108,{DOUBLEWITHTWODWORDINTREE(0x5f100000,0x00000000)}},
+ {VT_exponent,22,0x3a9109,{DOUBLEWITHTWODWORDINTREE(0x5f200000,0x00000000)}},
+ {VT_exponent,22,0x3a910a,{DOUBLEWITHTWODWORDINTREE(0x5f300000,0x00000000)}},
+ {VT_exponent,22,0x3a910b,{DOUBLEWITHTWODWORDINTREE(0x5f400000,0x00000000)}},
+ {VT_exponent,22,0x3a910c,{DOUBLEWITHTWODWORDINTREE(0x5f500000,0x00000000)}},
+ {VT_exponent,22,0x3a910d,{DOUBLEWITHTWODWORDINTREE(0x5f600000,0x00000000)}},
+ {VT_exponent,22,0x3a910e,{DOUBLEWITHTWODWORDINTREE(0x5f700000,0x00000000)}},
+ {VT_exponent,22,0x3a910f,{DOUBLEWITHTWODWORDINTREE(0x5f800000,0x00000000)}},
+ {VT_exponent,22,0x3a9110,{DOUBLEWITHTWODWORDINTREE(0x5f900000,0x00000000)}},
+ {VT_exponent,22,0x3a9111,{DOUBLEWITHTWODWORDINTREE(0x5fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a9112,{DOUBLEWITHTWODWORDINTREE(0x5fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9113,{DOUBLEWITHTWODWORDINTREE(0x5fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a9114,{DOUBLEWITHTWODWORDINTREE(0x5fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a9115,{DOUBLEWITHTWODWORDINTREE(0x5fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a9116,{DOUBLEWITHTWODWORDINTREE(0x5ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a9117,{DOUBLEWITHTWODWORDINTREE(0x60000000,0x00000000)}},
+ {VT_exponent,22,0x3a9118,{DOUBLEWITHTWODWORDINTREE(0x60100000,0x00000000)}},
+ {VT_exponent,22,0x3a9119,{DOUBLEWITHTWODWORDINTREE(0x60200000,0x00000000)}},
+ {VT_exponent,22,0x3a911a,{DOUBLEWITHTWODWORDINTREE(0x60300000,0x00000000)}},
+ {VT_exponent,22,0x3a911b,{DOUBLEWITHTWODWORDINTREE(0x60400000,0x00000000)}},
+ {VT_exponent,22,0x3a911c,{DOUBLEWITHTWODWORDINTREE(0x60500000,0x00000000)}},
+ {VT_exponent,22,0x3a911d,{DOUBLEWITHTWODWORDINTREE(0x60600000,0x00000000)}},
+ {VT_exponent,22,0x3a911e,{DOUBLEWITHTWODWORDINTREE(0x60700000,0x00000000)}},
+ {VT_exponent,22,0x3a911f,{DOUBLEWITHTWODWORDINTREE(0x60800000,0x00000000)}},
+ {VT_exponent,22,0x3a9120,{DOUBLEWITHTWODWORDINTREE(0x60900000,0x00000000)}},
+ {VT_exponent,22,0x3a9121,{DOUBLEWITHTWODWORDINTREE(0x60a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9122,{DOUBLEWITHTWODWORDINTREE(0x60b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9123,{DOUBLEWITHTWODWORDINTREE(0x60c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9124,{DOUBLEWITHTWODWORDINTREE(0x60d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9125,{DOUBLEWITHTWODWORDINTREE(0x60e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9126,{DOUBLEWITHTWODWORDINTREE(0x60f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9127,{DOUBLEWITHTWODWORDINTREE(0x61000000,0x00000000)}},
+ {VT_exponent,22,0x3a9128,{DOUBLEWITHTWODWORDINTREE(0x61100000,0x00000000)}},
+ {VT_exponent,22,0x3a9129,{DOUBLEWITHTWODWORDINTREE(0x61200000,0x00000000)}},
+ {VT_exponent,22,0x3a912a,{DOUBLEWITHTWODWORDINTREE(0x61300000,0x00000000)}},
+ {VT_exponent,22,0x3a912b,{DOUBLEWITHTWODWORDINTREE(0x61400000,0x00000000)}},
+ {VT_exponent,22,0x3a912c,{DOUBLEWITHTWODWORDINTREE(0x61500000,0x00000000)}},
+ {VT_exponent,22,0x3a912d,{DOUBLEWITHTWODWORDINTREE(0x61600000,0x00000000)}},
+ {VT_exponent,22,0x3a912e,{DOUBLEWITHTWODWORDINTREE(0x61700000,0x00000000)}},
+ {VT_exponent,22,0x3a912f,{DOUBLEWITHTWODWORDINTREE(0x61800000,0x00000000)}},
+ {VT_exponent,22,0x3a9130,{DOUBLEWITHTWODWORDINTREE(0x61900000,0x00000000)}},
+ {VT_exponent,22,0x3a9131,{DOUBLEWITHTWODWORDINTREE(0x61a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9132,{DOUBLEWITHTWODWORDINTREE(0x61b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9133,{DOUBLEWITHTWODWORDINTREE(0x61c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9134,{DOUBLEWITHTWODWORDINTREE(0x61d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9135,{DOUBLEWITHTWODWORDINTREE(0x61e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9136,{DOUBLEWITHTWODWORDINTREE(0x61f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9137,{DOUBLEWITHTWODWORDINTREE(0x62000000,0x00000000)}},
+ {VT_exponent,22,0x3a9138,{DOUBLEWITHTWODWORDINTREE(0x62100000,0x00000000)}},
+ {VT_exponent,22,0x3a9139,{DOUBLEWITHTWODWORDINTREE(0x62200000,0x00000000)}},
+ {VT_exponent,22,0x3a913a,{DOUBLEWITHTWODWORDINTREE(0x62300000,0x00000000)}},
+ {VT_exponent,22,0x3a913b,{DOUBLEWITHTWODWORDINTREE(0x62400000,0x00000000)}},
+ {VT_exponent,22,0x3a913c,{DOUBLEWITHTWODWORDINTREE(0x62500000,0x00000000)}},
+ {VT_exponent,22,0x3a913d,{DOUBLEWITHTWODWORDINTREE(0x62600000,0x00000000)}},
+ {VT_exponent,22,0x3a913e,{DOUBLEWITHTWODWORDINTREE(0x62700000,0x00000000)}},
+ {VT_exponent,22,0x3a913f,{DOUBLEWITHTWODWORDINTREE(0x62800000,0x00000000)}},
+ {VT_exponent,22,0x3a9140,{DOUBLEWITHTWODWORDINTREE(0x62900000,0x00000000)}},
+ {VT_exponent,22,0x3a9141,{DOUBLEWITHTWODWORDINTREE(0x62a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9142,{DOUBLEWITHTWODWORDINTREE(0x62b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9143,{DOUBLEWITHTWODWORDINTREE(0x62c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9144,{DOUBLEWITHTWODWORDINTREE(0x62d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9145,{DOUBLEWITHTWODWORDINTREE(0x62e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9146,{DOUBLEWITHTWODWORDINTREE(0x62f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9147,{DOUBLEWITHTWODWORDINTREE(0x63000000,0x00000000)}},
+ {VT_exponent,22,0x3a9148,{DOUBLEWITHTWODWORDINTREE(0x63100000,0x00000000)}},
+ {VT_exponent,22,0x3a9149,{DOUBLEWITHTWODWORDINTREE(0x63200000,0x00000000)}},
+ {VT_exponent,22,0x3a914a,{DOUBLEWITHTWODWORDINTREE(0x63300000,0x00000000)}},
+ {VT_exponent,22,0x3a914b,{DOUBLEWITHTWODWORDINTREE(0x63400000,0x00000000)}},
+ {VT_exponent,22,0x3a914c,{DOUBLEWITHTWODWORDINTREE(0x63500000,0x00000000)}},
+ {VT_exponent,22,0x3a914d,{DOUBLEWITHTWODWORDINTREE(0x63600000,0x00000000)}},
+ {VT_exponent,22,0x3a914e,{DOUBLEWITHTWODWORDINTREE(0x63700000,0x00000000)}},
+ {VT_exponent,22,0x3a914f,{DOUBLEWITHTWODWORDINTREE(0x63800000,0x00000000)}},
+ {VT_exponent,22,0x3a9150,{DOUBLEWITHTWODWORDINTREE(0x63900000,0x00000000)}},
+ {VT_exponent,22,0x3a9151,{DOUBLEWITHTWODWORDINTREE(0x63a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9152,{DOUBLEWITHTWODWORDINTREE(0x63b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9153,{DOUBLEWITHTWODWORDINTREE(0x63c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9154,{DOUBLEWITHTWODWORDINTREE(0x63d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9155,{DOUBLEWITHTWODWORDINTREE(0x63e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9156,{DOUBLEWITHTWODWORDINTREE(0x63f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9157,{DOUBLEWITHTWODWORDINTREE(0x64000000,0x00000000)}},
+ {VT_exponent,22,0x3a9158,{DOUBLEWITHTWODWORDINTREE(0x64100000,0x00000000)}},
+ {VT_exponent,22,0x3a9159,{DOUBLEWITHTWODWORDINTREE(0x64200000,0x00000000)}},
+ {VT_exponent,22,0x3a915a,{DOUBLEWITHTWODWORDINTREE(0x64300000,0x00000000)}},
+ {VT_exponent,22,0x3a915b,{DOUBLEWITHTWODWORDINTREE(0x64400000,0x00000000)}},
+ {VT_exponent,22,0x3a915c,{DOUBLEWITHTWODWORDINTREE(0x64500000,0x00000000)}},
+ {VT_exponent,22,0x3a915d,{DOUBLEWITHTWODWORDINTREE(0x64600000,0x00000000)}},
+ {VT_exponent,22,0x3a915e,{DOUBLEWITHTWODWORDINTREE(0x64700000,0x00000000)}},
+ {VT_exponent,22,0x3a915f,{DOUBLEWITHTWODWORDINTREE(0x64800000,0x00000000)}},
+ {VT_exponent,22,0x3a9160,{DOUBLEWITHTWODWORDINTREE(0x64900000,0x00000000)}},
+ {VT_exponent,22,0x3a9161,{DOUBLEWITHTWODWORDINTREE(0x64a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9162,{DOUBLEWITHTWODWORDINTREE(0x64b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9163,{DOUBLEWITHTWODWORDINTREE(0x64c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9164,{DOUBLEWITHTWODWORDINTREE(0x64d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9165,{DOUBLEWITHTWODWORDINTREE(0x64e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9166,{DOUBLEWITHTWODWORDINTREE(0x64f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9167,{DOUBLEWITHTWODWORDINTREE(0x65000000,0x00000000)}},
+ {VT_exponent,22,0x3a9168,{DOUBLEWITHTWODWORDINTREE(0x65100000,0x00000000)}},
+ {VT_exponent,22,0x3a9169,{DOUBLEWITHTWODWORDINTREE(0x65200000,0x00000000)}},
+ {VT_exponent,22,0x3a916a,{DOUBLEWITHTWODWORDINTREE(0x65300000,0x00000000)}},
+ {VT_exponent,22,0x3a916b,{DOUBLEWITHTWODWORDINTREE(0x65400000,0x00000000)}},
+ {VT_exponent,22,0x3a916c,{DOUBLEWITHTWODWORDINTREE(0x65500000,0x00000000)}},
+ {VT_exponent,22,0x3a916d,{DOUBLEWITHTWODWORDINTREE(0x65600000,0x00000000)}},
+ {VT_exponent,22,0x3a916e,{DOUBLEWITHTWODWORDINTREE(0x65700000,0x00000000)}},
+ {VT_exponent,22,0x3a916f,{DOUBLEWITHTWODWORDINTREE(0x65800000,0x00000000)}},
+ {VT_exponent,22,0x3a9170,{DOUBLEWITHTWODWORDINTREE(0x65900000,0x00000000)}},
+ {VT_exponent,22,0x3a9171,{DOUBLEWITHTWODWORDINTREE(0x65a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9172,{DOUBLEWITHTWODWORDINTREE(0x65b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9173,{DOUBLEWITHTWODWORDINTREE(0x65c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9174,{DOUBLEWITHTWODWORDINTREE(0x65d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9175,{DOUBLEWITHTWODWORDINTREE(0x65e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9176,{DOUBLEWITHTWODWORDINTREE(0x65f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9177,{DOUBLEWITHTWODWORDINTREE(0x66000000,0x00000000)}},
+ {VT_exponent,22,0x3a9178,{DOUBLEWITHTWODWORDINTREE(0x66100000,0x00000000)}},
+ {VT_exponent,22,0x3a9179,{DOUBLEWITHTWODWORDINTREE(0x66200000,0x00000000)}},
+ {VT_exponent,22,0x3a917a,{DOUBLEWITHTWODWORDINTREE(0x66300000,0x00000000)}},
+ {VT_exponent,22,0x3a917b,{DOUBLEWITHTWODWORDINTREE(0x66400000,0x00000000)}},
+ {VT_exponent,22,0x3a917c,{DOUBLEWITHTWODWORDINTREE(0x66500000,0x00000000)}},
+ {VT_exponent,22,0x3a917d,{DOUBLEWITHTWODWORDINTREE(0x66600000,0x00000000)}},
+ {VT_exponent,22,0x3a917e,{DOUBLEWITHTWODWORDINTREE(0x66700000,0x00000000)}},
+ {VT_exponent,22,0x3a917f,{DOUBLEWITHTWODWORDINTREE(0x66800000,0x00000000)}},
+ {VT_exponent,22,0x3a9180,{DOUBLEWITHTWODWORDINTREE(0x66900000,0x00000000)}},
+ {VT_exponent,22,0x3a9181,{DOUBLEWITHTWODWORDINTREE(0x66a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9182,{DOUBLEWITHTWODWORDINTREE(0x66b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9183,{DOUBLEWITHTWODWORDINTREE(0x66c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9184,{DOUBLEWITHTWODWORDINTREE(0x66d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9185,{DOUBLEWITHTWODWORDINTREE(0x66e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9186,{DOUBLEWITHTWODWORDINTREE(0x66f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9187,{DOUBLEWITHTWODWORDINTREE(0x67000000,0x00000000)}},
+ {VT_exponent,22,0x3a9188,{DOUBLEWITHTWODWORDINTREE(0x67100000,0x00000000)}},
+ {VT_exponent,22,0x3a9189,{DOUBLEWITHTWODWORDINTREE(0x67200000,0x00000000)}},
+ {VT_exponent,22,0x3a918a,{DOUBLEWITHTWODWORDINTREE(0x67300000,0x00000000)}},
+ {VT_exponent,22,0x3a918b,{DOUBLEWITHTWODWORDINTREE(0x67400000,0x00000000)}},
+ {VT_exponent,22,0x3a918c,{DOUBLEWITHTWODWORDINTREE(0x67500000,0x00000000)}},
+ {VT_exponent,22,0x3a918d,{DOUBLEWITHTWODWORDINTREE(0x67600000,0x00000000)}},
+ {VT_exponent,22,0x3a918e,{DOUBLEWITHTWODWORDINTREE(0x67700000,0x00000000)}},
+ {VT_exponent,22,0x3a918f,{DOUBLEWITHTWODWORDINTREE(0x67800000,0x00000000)}},
+ {VT_exponent,22,0x3a9190,{DOUBLEWITHTWODWORDINTREE(0x67900000,0x00000000)}},
+ {VT_exponent,22,0x3a9191,{DOUBLEWITHTWODWORDINTREE(0x67a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9192,{DOUBLEWITHTWODWORDINTREE(0x67b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9193,{DOUBLEWITHTWODWORDINTREE(0x67c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9194,{DOUBLEWITHTWODWORDINTREE(0x67d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9195,{DOUBLEWITHTWODWORDINTREE(0x67e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9196,{DOUBLEWITHTWODWORDINTREE(0x67f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9197,{DOUBLEWITHTWODWORDINTREE(0x68000000,0x00000000)}},
+ {VT_exponent,22,0x3a9198,{DOUBLEWITHTWODWORDINTREE(0x68100000,0x00000000)}},
+ {VT_exponent,22,0x3a9199,{DOUBLEWITHTWODWORDINTREE(0x68200000,0x00000000)}},
+ {VT_exponent,22,0x3a919a,{DOUBLEWITHTWODWORDINTREE(0x68300000,0x00000000)}},
+ {VT_exponent,22,0x3a919b,{DOUBLEWITHTWODWORDINTREE(0x68400000,0x00000000)}},
+ {VT_exponent,22,0x3a919c,{DOUBLEWITHTWODWORDINTREE(0x68500000,0x00000000)}},
+ {VT_exponent,22,0x3a919d,{DOUBLEWITHTWODWORDINTREE(0x68600000,0x00000000)}},
+ {VT_exponent,22,0x3a919e,{DOUBLEWITHTWODWORDINTREE(0x68700000,0x00000000)}},
+ {VT_exponent,22,0x3a919f,{DOUBLEWITHTWODWORDINTREE(0x68800000,0x00000000)}},
+ {VT_exponent,22,0x3a91a0,{DOUBLEWITHTWODWORDINTREE(0x68900000,0x00000000)}},
+ {VT_exponent,22,0x3a91a1,{DOUBLEWITHTWODWORDINTREE(0x68a00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a2,{DOUBLEWITHTWODWORDINTREE(0x68b00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a3,{DOUBLEWITHTWODWORDINTREE(0x68c00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a4,{DOUBLEWITHTWODWORDINTREE(0x68d00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a5,{DOUBLEWITHTWODWORDINTREE(0x68e00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a6,{DOUBLEWITHTWODWORDINTREE(0x68f00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a7,{DOUBLEWITHTWODWORDINTREE(0x69000000,0x00000000)}},
+ {VT_exponent,22,0x3a91a8,{DOUBLEWITHTWODWORDINTREE(0x69100000,0x00000000)}},
+ {VT_exponent,22,0x3a91a9,{DOUBLEWITHTWODWORDINTREE(0x69200000,0x00000000)}},
+ {VT_exponent,22,0x3a91aa,{DOUBLEWITHTWODWORDINTREE(0x69300000,0x00000000)}},
+ {VT_exponent,22,0x3a91ab,{DOUBLEWITHTWODWORDINTREE(0x69400000,0x00000000)}},
+ {VT_exponent,22,0x3a91ac,{DOUBLEWITHTWODWORDINTREE(0x69500000,0x00000000)}},
+ {VT_exponent,22,0x3a91ad,{DOUBLEWITHTWODWORDINTREE(0x69600000,0x00000000)}},
+ {VT_exponent,22,0x3a91ae,{DOUBLEWITHTWODWORDINTREE(0x69700000,0x00000000)}},
+ {VT_exponent,22,0x3a91af,{DOUBLEWITHTWODWORDINTREE(0x69800000,0x00000000)}},
+ {VT_exponent,22,0x3a91b0,{DOUBLEWITHTWODWORDINTREE(0x69900000,0x00000000)}},
+ {VT_exponent,22,0x3a91b1,{DOUBLEWITHTWODWORDINTREE(0x69a00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b2,{DOUBLEWITHTWODWORDINTREE(0x69b00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b3,{DOUBLEWITHTWODWORDINTREE(0x69c00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b4,{DOUBLEWITHTWODWORDINTREE(0x69d00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b5,{DOUBLEWITHTWODWORDINTREE(0x69e00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b6,{DOUBLEWITHTWODWORDINTREE(0x69f00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b7,{DOUBLEWITHTWODWORDINTREE(0x6a000000,0x00000000)}},
+ {VT_exponent,22,0x3a91b8,{DOUBLEWITHTWODWORDINTREE(0x6a100000,0x00000000)}},
+ {VT_exponent,22,0x3a91b9,{DOUBLEWITHTWODWORDINTREE(0x6a200000,0x00000000)}},
+ {VT_exponent,22,0x3a91ba,{DOUBLEWITHTWODWORDINTREE(0x6a300000,0x00000000)}},
+ {VT_exponent,22,0x3a91bb,{DOUBLEWITHTWODWORDINTREE(0x6a400000,0x00000000)}},
+ {VT_exponent,22,0x3a91bc,{DOUBLEWITHTWODWORDINTREE(0x6a500000,0x00000000)}},
+ {VT_exponent,22,0x3a91bd,{DOUBLEWITHTWODWORDINTREE(0x6a600000,0x00000000)}},
+ {VT_exponent,22,0x3a91be,{DOUBLEWITHTWODWORDINTREE(0x6a700000,0x00000000)}},
+ {VT_exponent,22,0x3a91bf,{DOUBLEWITHTWODWORDINTREE(0x6a800000,0x00000000)}},
+ {VT_exponent,22,0x3a91c0,{DOUBLEWITHTWODWORDINTREE(0x6a900000,0x00000000)}},
+ {VT_exponent,22,0x3a91c1,{DOUBLEWITHTWODWORDINTREE(0x6aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c2,{DOUBLEWITHTWODWORDINTREE(0x6ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c3,{DOUBLEWITHTWODWORDINTREE(0x6ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c4,{DOUBLEWITHTWODWORDINTREE(0x6ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c5,{DOUBLEWITHTWODWORDINTREE(0x6ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c6,{DOUBLEWITHTWODWORDINTREE(0x6af00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c7,{DOUBLEWITHTWODWORDINTREE(0x6b000000,0x00000000)}},
+ {VT_exponent,22,0x3a91c8,{DOUBLEWITHTWODWORDINTREE(0x6b100000,0x00000000)}},
+ {VT_exponent,22,0x3a91c9,{DOUBLEWITHTWODWORDINTREE(0x6b200000,0x00000000)}},
+ {VT_exponent,22,0x3a91ca,{DOUBLEWITHTWODWORDINTREE(0x6b300000,0x00000000)}},
+ {VT_exponent,22,0x3a91cb,{DOUBLEWITHTWODWORDINTREE(0x6b400000,0x00000000)}},
+ {VT_exponent,22,0x3a91cc,{DOUBLEWITHTWODWORDINTREE(0x6b500000,0x00000000)}},
+ {VT_exponent,22,0x3a91cd,{DOUBLEWITHTWODWORDINTREE(0x6b600000,0x00000000)}},
+ {VT_exponent,22,0x3a91ce,{DOUBLEWITHTWODWORDINTREE(0x6b700000,0x00000000)}},
+ {VT_exponent,22,0x3a91cf,{DOUBLEWITHTWODWORDINTREE(0x6b800000,0x00000000)}},
+ {VT_exponent,22,0x3a91d0,{DOUBLEWITHTWODWORDINTREE(0x6b900000,0x00000000)}},
+ {VT_exponent,22,0x3a91d1,{DOUBLEWITHTWODWORDINTREE(0x6ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d2,{DOUBLEWITHTWODWORDINTREE(0x6bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d3,{DOUBLEWITHTWODWORDINTREE(0x6bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d4,{DOUBLEWITHTWODWORDINTREE(0x6bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d5,{DOUBLEWITHTWODWORDINTREE(0x6be00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d6,{DOUBLEWITHTWODWORDINTREE(0x6bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d7,{DOUBLEWITHTWODWORDINTREE(0x6c000000,0x00000000)}},
+ {VT_exponent,22,0x3a91d8,{DOUBLEWITHTWODWORDINTREE(0x6c100000,0x00000000)}},
+ {VT_exponent,22,0x3a91d9,{DOUBLEWITHTWODWORDINTREE(0x6c200000,0x00000000)}},
+ {VT_exponent,22,0x3a91da,{DOUBLEWITHTWODWORDINTREE(0x6c300000,0x00000000)}},
+ {VT_exponent,22,0x3a91db,{DOUBLEWITHTWODWORDINTREE(0x6c400000,0x00000000)}},
+ {VT_exponent,22,0x3a91dc,{DOUBLEWITHTWODWORDINTREE(0x6c500000,0x00000000)}},
+ {VT_exponent,22,0x3a91dd,{DOUBLEWITHTWODWORDINTREE(0x6c600000,0x00000000)}},
+ {VT_exponent,22,0x3a91de,{DOUBLEWITHTWODWORDINTREE(0x6c700000,0x00000000)}},
+ {VT_exponent,22,0x3a91df,{DOUBLEWITHTWODWORDINTREE(0x6c800000,0x00000000)}},
+ {VT_exponent,22,0x3a91e0,{DOUBLEWITHTWODWORDINTREE(0x6c900000,0x00000000)}},
+ {VT_exponent,22,0x3a91e1,{DOUBLEWITHTWODWORDINTREE(0x6ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e2,{DOUBLEWITHTWODWORDINTREE(0x6cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e3,{DOUBLEWITHTWODWORDINTREE(0x6cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e4,{DOUBLEWITHTWODWORDINTREE(0x6cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e5,{DOUBLEWITHTWODWORDINTREE(0x6ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e6,{DOUBLEWITHTWODWORDINTREE(0x6cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e7,{DOUBLEWITHTWODWORDINTREE(0x6d000000,0x00000000)}},
+ {VT_exponent,22,0x3a91e8,{DOUBLEWITHTWODWORDINTREE(0x6d100000,0x00000000)}},
+ {VT_exponent,22,0x3a91e9,{DOUBLEWITHTWODWORDINTREE(0x6d200000,0x00000000)}},
+ {VT_exponent,22,0x3a91ea,{DOUBLEWITHTWODWORDINTREE(0x6d300000,0x00000000)}},
+ {VT_exponent,22,0x3a91eb,{DOUBLEWITHTWODWORDINTREE(0x6d400000,0x00000000)}},
+ {VT_exponent,22,0x3a91ec,{DOUBLEWITHTWODWORDINTREE(0x6d500000,0x00000000)}},
+ {VT_exponent,22,0x3a91ed,{DOUBLEWITHTWODWORDINTREE(0x6d600000,0x00000000)}},
+ {VT_exponent,22,0x3a91ee,{DOUBLEWITHTWODWORDINTREE(0x6d700000,0x00000000)}},
+ {VT_exponent,22,0x3a91ef,{DOUBLEWITHTWODWORDINTREE(0x6d800000,0x00000000)}},
+ {VT_exponent,22,0x3a91f0,{DOUBLEWITHTWODWORDINTREE(0x6d900000,0x00000000)}},
+ {VT_exponent,22,0x3a91f1,{DOUBLEWITHTWODWORDINTREE(0x6da00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f2,{DOUBLEWITHTWODWORDINTREE(0x6db00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f3,{DOUBLEWITHTWODWORDINTREE(0x6dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f4,{DOUBLEWITHTWODWORDINTREE(0x6dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f5,{DOUBLEWITHTWODWORDINTREE(0x6de00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f6,{DOUBLEWITHTWODWORDINTREE(0x6df00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f7,{DOUBLEWITHTWODWORDINTREE(0x6e000000,0x00000000)}},
+ {VT_exponent,22,0x3a91f8,{DOUBLEWITHTWODWORDINTREE(0x6e100000,0x00000000)}},
+ {VT_exponent,22,0x3a91f9,{DOUBLEWITHTWODWORDINTREE(0x6e200000,0x00000000)}},
+ {VT_exponent,22,0x3a91fa,{DOUBLEWITHTWODWORDINTREE(0x6e300000,0x00000000)}},
+ {VT_exponent,22,0x3a91fb,{DOUBLEWITHTWODWORDINTREE(0x6e400000,0x00000000)}},
+ {VT_exponent,22,0x3a91fc,{DOUBLEWITHTWODWORDINTREE(0x6e500000,0x00000000)}},
+ {VT_exponent,22,0x3a91fd,{DOUBLEWITHTWODWORDINTREE(0x6e600000,0x00000000)}},
+ {VT_exponent,22,0x3a91fe,{DOUBLEWITHTWODWORDINTREE(0x6e700000,0x00000000)}},
+ {VT_exponent,22,0x3a91ff,{DOUBLEWITHTWODWORDINTREE(0x6e800000,0x00000000)}},
+ {VT_exponent,22,0x3a9200,{DOUBLEWITHTWODWORDINTREE(0x6e900000,0x00000000)}},
+ {VT_exponent,22,0x3a9201,{DOUBLEWITHTWODWORDINTREE(0x6ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a9202,{DOUBLEWITHTWODWORDINTREE(0x6eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9203,{DOUBLEWITHTWODWORDINTREE(0x6ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a9204,{DOUBLEWITHTWODWORDINTREE(0x6ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a9205,{DOUBLEWITHTWODWORDINTREE(0x6ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a9206,{DOUBLEWITHTWODWORDINTREE(0x6ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a9207,{DOUBLEWITHTWODWORDINTREE(0x6f000000,0x00000000)}},
+ {VT_exponent,22,0x3a9208,{DOUBLEWITHTWODWORDINTREE(0x6f100000,0x00000000)}},
+ {VT_exponent,22,0x3a9209,{DOUBLEWITHTWODWORDINTREE(0x6f200000,0x00000000)}},
+ {VT_exponent,22,0x3a920a,{DOUBLEWITHTWODWORDINTREE(0x6f300000,0x00000000)}},
+ {VT_exponent,22,0x3a920b,{DOUBLEWITHTWODWORDINTREE(0x6f400000,0x00000000)}},
+ {VT_exponent,22,0x3a920c,{DOUBLEWITHTWODWORDINTREE(0x6f500000,0x00000000)}},
+ {VT_exponent,22,0x3a920d,{DOUBLEWITHTWODWORDINTREE(0x6f600000,0x00000000)}},
+ {VT_exponent,22,0x3a920e,{DOUBLEWITHTWODWORDINTREE(0x6f700000,0x00000000)}},
+ {VT_exponent,22,0x3a920f,{DOUBLEWITHTWODWORDINTREE(0x6f800000,0x00000000)}},
+ {VT_exponent,22,0x3a9210,{DOUBLEWITHTWODWORDINTREE(0x6f900000,0x00000000)}},
+ {VT_exponent,22,0x3a9211,{DOUBLEWITHTWODWORDINTREE(0x6fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a9212,{DOUBLEWITHTWODWORDINTREE(0x6fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9213,{DOUBLEWITHTWODWORDINTREE(0x6fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a9214,{DOUBLEWITHTWODWORDINTREE(0x6fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a9215,{DOUBLEWITHTWODWORDINTREE(0x6fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a9216,{DOUBLEWITHTWODWORDINTREE(0x6ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a9217,{DOUBLEWITHTWODWORDINTREE(0x70000000,0x00000000)}},
+ {VT_exponent,22,0x3a9218,{DOUBLEWITHTWODWORDINTREE(0x70100000,0x00000000)}},
+ {VT_exponent,22,0x3a9219,{DOUBLEWITHTWODWORDINTREE(0x70200000,0x00000000)}},
+ {VT_exponent,22,0x3a921a,{DOUBLEWITHTWODWORDINTREE(0x70300000,0x00000000)}},
+ {VT_exponent,22,0x3a921b,{DOUBLEWITHTWODWORDINTREE(0x70400000,0x00000000)}},
+ {VT_exponent,22,0x3a921c,{DOUBLEWITHTWODWORDINTREE(0x70500000,0x00000000)}},
+ {VT_exponent,22,0x3a921d,{DOUBLEWITHTWODWORDINTREE(0x70600000,0x00000000)}},
+ {VT_exponent,22,0x3a921e,{DOUBLEWITHTWODWORDINTREE(0x70700000,0x00000000)}},
+ {VT_exponent,22,0x3a921f,{DOUBLEWITHTWODWORDINTREE(0x70800000,0x00000000)}},
+ {VT_exponent,22,0x3a9220,{DOUBLEWITHTWODWORDINTREE(0x70900000,0x00000000)}},
+ {VT_exponent,22,0x3a9221,{DOUBLEWITHTWODWORDINTREE(0x70a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9222,{DOUBLEWITHTWODWORDINTREE(0x70b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9223,{DOUBLEWITHTWODWORDINTREE(0x70c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9224,{DOUBLEWITHTWODWORDINTREE(0x70d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9225,{DOUBLEWITHTWODWORDINTREE(0x70e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9226,{DOUBLEWITHTWODWORDINTREE(0x70f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9227,{DOUBLEWITHTWODWORDINTREE(0x71000000,0x00000000)}},
+ {VT_exponent,22,0x3a9228,{DOUBLEWITHTWODWORDINTREE(0x71100000,0x00000000)}},
+ {VT_exponent,22,0x3a9229,{DOUBLEWITHTWODWORDINTREE(0x71200000,0x00000000)}},
+ {VT_exponent,22,0x3a922a,{DOUBLEWITHTWODWORDINTREE(0x71300000,0x00000000)}},
+ {VT_exponent,22,0x3a922b,{DOUBLEWITHTWODWORDINTREE(0x71400000,0x00000000)}},
+ {VT_exponent,22,0x3a922c,{DOUBLEWITHTWODWORDINTREE(0x71500000,0x00000000)}},
+ {VT_exponent,22,0x3a922d,{DOUBLEWITHTWODWORDINTREE(0x71600000,0x00000000)}},
+ {VT_exponent,22,0x3a922e,{DOUBLEWITHTWODWORDINTREE(0x71700000,0x00000000)}},
+ {VT_exponent,22,0x3a922f,{DOUBLEWITHTWODWORDINTREE(0x71800000,0x00000000)}},
+ {VT_exponent,22,0x3a9230,{DOUBLEWITHTWODWORDINTREE(0x71900000,0x00000000)}},
+ {VT_exponent,22,0x3a9231,{DOUBLEWITHTWODWORDINTREE(0x71a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9232,{DOUBLEWITHTWODWORDINTREE(0x71b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9233,{DOUBLEWITHTWODWORDINTREE(0x71c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9234,{DOUBLEWITHTWODWORDINTREE(0x71d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9235,{DOUBLEWITHTWODWORDINTREE(0x71e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9236,{DOUBLEWITHTWODWORDINTREE(0x71f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9237,{DOUBLEWITHTWODWORDINTREE(0x72000000,0x00000000)}},
+ {VT_exponent,22,0x3a9238,{DOUBLEWITHTWODWORDINTREE(0x72100000,0x00000000)}},
+ {VT_exponent,22,0x3a9239,{DOUBLEWITHTWODWORDINTREE(0x72200000,0x00000000)}},
+ {VT_exponent,22,0x3a923a,{DOUBLEWITHTWODWORDINTREE(0x72300000,0x00000000)}},
+ {VT_exponent,22,0x3a923b,{DOUBLEWITHTWODWORDINTREE(0x72400000,0x00000000)}},
+ {VT_exponent,22,0x3a923c,{DOUBLEWITHTWODWORDINTREE(0x72500000,0x00000000)}},
+ {VT_exponent,22,0x3a923d,{DOUBLEWITHTWODWORDINTREE(0x72600000,0x00000000)}},
+ {VT_exponent,22,0x3a923e,{DOUBLEWITHTWODWORDINTREE(0x72700000,0x00000000)}},
+ {VT_exponent,22,0x3a923f,{DOUBLEWITHTWODWORDINTREE(0x72800000,0x00000000)}},
+ {VT_exponent,22,0x3a9240,{DOUBLEWITHTWODWORDINTREE(0x72900000,0x00000000)}},
+ {VT_exponent,22,0x3a9241,{DOUBLEWITHTWODWORDINTREE(0x72a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9242,{DOUBLEWITHTWODWORDINTREE(0x72b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9243,{DOUBLEWITHTWODWORDINTREE(0x72c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9244,{DOUBLEWITHTWODWORDINTREE(0x72d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9245,{DOUBLEWITHTWODWORDINTREE(0x72e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9246,{DOUBLEWITHTWODWORDINTREE(0x72f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9247,{DOUBLEWITHTWODWORDINTREE(0x73000000,0x00000000)}},
+ {VT_exponent,22,0x3a9248,{DOUBLEWITHTWODWORDINTREE(0x73100000,0x00000000)}},
+ {VT_exponent,22,0x3a9249,{DOUBLEWITHTWODWORDINTREE(0x73200000,0x00000000)}},
+ {VT_exponent,22,0x3a924a,{DOUBLEWITHTWODWORDINTREE(0x73300000,0x00000000)}},
+ {VT_exponent,22,0x3a924b,{DOUBLEWITHTWODWORDINTREE(0x73400000,0x00000000)}},
+ {VT_exponent,22,0x3a924c,{DOUBLEWITHTWODWORDINTREE(0x73500000,0x00000000)}},
+ {VT_exponent,22,0x3a924d,{DOUBLEWITHTWODWORDINTREE(0x73600000,0x00000000)}},
+ {VT_exponent,22,0x3a924e,{DOUBLEWITHTWODWORDINTREE(0x73700000,0x00000000)}},
+ {VT_exponent,22,0x3a924f,{DOUBLEWITHTWODWORDINTREE(0x73800000,0x00000000)}},
+ {VT_exponent,22,0x3a9250,{DOUBLEWITHTWODWORDINTREE(0x73900000,0x00000000)}},
+ {VT_exponent,22,0x3a9251,{DOUBLEWITHTWODWORDINTREE(0x73a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9252,{DOUBLEWITHTWODWORDINTREE(0x73b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9253,{DOUBLEWITHTWODWORDINTREE(0x73c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9254,{DOUBLEWITHTWODWORDINTREE(0x73d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9255,{DOUBLEWITHTWODWORDINTREE(0x73e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9256,{DOUBLEWITHTWODWORDINTREE(0x73f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9257,{DOUBLEWITHTWODWORDINTREE(0x74000000,0x00000000)}},
+ {VT_exponent,22,0x3a9258,{DOUBLEWITHTWODWORDINTREE(0x74100000,0x00000000)}},
+ {VT_exponent,22,0x3a9259,{DOUBLEWITHTWODWORDINTREE(0x74200000,0x00000000)}},
+ {VT_exponent,22,0x3a925a,{DOUBLEWITHTWODWORDINTREE(0x74300000,0x00000000)}},
+ {VT_exponent,22,0x3a925b,{DOUBLEWITHTWODWORDINTREE(0x74400000,0x00000000)}},
+ {VT_exponent,22,0x3a925c,{DOUBLEWITHTWODWORDINTREE(0x74500000,0x00000000)}},
+ {VT_exponent,22,0x3a925d,{DOUBLEWITHTWODWORDINTREE(0x74600000,0x00000000)}},
+ {VT_exponent,22,0x3a925e,{DOUBLEWITHTWODWORDINTREE(0x74700000,0x00000000)}},
+ {VT_exponent,22,0x3a925f,{DOUBLEWITHTWODWORDINTREE(0x74800000,0x00000000)}},
+ {VT_exponent,22,0x3a9260,{DOUBLEWITHTWODWORDINTREE(0x74900000,0x00000000)}},
+ {VT_exponent,22,0x3a9261,{DOUBLEWITHTWODWORDINTREE(0x74a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9262,{DOUBLEWITHTWODWORDINTREE(0x74b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9263,{DOUBLEWITHTWODWORDINTREE(0x74c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9264,{DOUBLEWITHTWODWORDINTREE(0x74d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9265,{DOUBLEWITHTWODWORDINTREE(0x74e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9266,{DOUBLEWITHTWODWORDINTREE(0x74f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9267,{DOUBLEWITHTWODWORDINTREE(0x75000000,0x00000000)}},
+ {VT_exponent,22,0x3a9268,{DOUBLEWITHTWODWORDINTREE(0x75100000,0x00000000)}},
+ {VT_exponent,22,0x3a9269,{DOUBLEWITHTWODWORDINTREE(0x75200000,0x00000000)}},
+ {VT_exponent,22,0x3a926a,{DOUBLEWITHTWODWORDINTREE(0x75300000,0x00000000)}},
+ {VT_exponent,22,0x3a926b,{DOUBLEWITHTWODWORDINTREE(0x75400000,0x00000000)}},
+ {VT_exponent,22,0x3a926c,{DOUBLEWITHTWODWORDINTREE(0x75500000,0x00000000)}},
+ {VT_exponent,22,0x3a926d,{DOUBLEWITHTWODWORDINTREE(0x75600000,0x00000000)}},
+ {VT_exponent,22,0x3a926e,{DOUBLEWITHTWODWORDINTREE(0x75700000,0x00000000)}},
+ {VT_exponent,22,0x3a926f,{DOUBLEWITHTWODWORDINTREE(0x75800000,0x00000000)}},
+ {VT_exponent,22,0x3a9270,{DOUBLEWITHTWODWORDINTREE(0x75900000,0x00000000)}},
+ {VT_exponent,22,0x3a9271,{DOUBLEWITHTWODWORDINTREE(0x75a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9272,{DOUBLEWITHTWODWORDINTREE(0x75b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9273,{DOUBLEWITHTWODWORDINTREE(0x75c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9274,{DOUBLEWITHTWODWORDINTREE(0x75d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9275,{DOUBLEWITHTWODWORDINTREE(0x75e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9276,{DOUBLEWITHTWODWORDINTREE(0x75f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9277,{DOUBLEWITHTWODWORDINTREE(0x76000000,0x00000000)}},
+ {VT_exponent,22,0x3a9278,{DOUBLEWITHTWODWORDINTREE(0x76100000,0x00000000)}},
+ {VT_exponent,22,0x3a9279,{DOUBLEWITHTWODWORDINTREE(0x76200000,0x00000000)}},
+ {VT_exponent,22,0x3a927a,{DOUBLEWITHTWODWORDINTREE(0x76300000,0x00000000)}},
+ {VT_exponent,22,0x3a927b,{DOUBLEWITHTWODWORDINTREE(0x76400000,0x00000000)}},
+ {VT_exponent,22,0x3a927c,{DOUBLEWITHTWODWORDINTREE(0x76500000,0x00000000)}},
+ {VT_exponent,22,0x3a927d,{DOUBLEWITHTWODWORDINTREE(0x76600000,0x00000000)}},
+ {VT_exponent,22,0x3a927e,{DOUBLEWITHTWODWORDINTREE(0x76700000,0x00000000)}},
+ {VT_exponent,22,0x3a927f,{DOUBLEWITHTWODWORDINTREE(0x76800000,0x00000000)}},
+ {VT_exponent,22,0x3a9280,{DOUBLEWITHTWODWORDINTREE(0x76900000,0x00000000)}},
+ {VT_exponent,22,0x3a9281,{DOUBLEWITHTWODWORDINTREE(0x76a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9282,{DOUBLEWITHTWODWORDINTREE(0x76b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9283,{DOUBLEWITHTWODWORDINTREE(0x76c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9284,{DOUBLEWITHTWODWORDINTREE(0x76d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9285,{DOUBLEWITHTWODWORDINTREE(0x76e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9286,{DOUBLEWITHTWODWORDINTREE(0x76f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9287,{DOUBLEWITHTWODWORDINTREE(0x77000000,0x00000000)}},
+ {VT_exponent,22,0x3a9288,{DOUBLEWITHTWODWORDINTREE(0x77100000,0x00000000)}},
+ {VT_exponent,22,0x3a9289,{DOUBLEWITHTWODWORDINTREE(0x77200000,0x00000000)}},
+ {VT_exponent,22,0x3a928a,{DOUBLEWITHTWODWORDINTREE(0x77300000,0x00000000)}},
+ {VT_exponent,22,0x3a928b,{DOUBLEWITHTWODWORDINTREE(0x77400000,0x00000000)}},
+ {VT_exponent,22,0x3a928c,{DOUBLEWITHTWODWORDINTREE(0x77500000,0x00000000)}},
+ {VT_exponent,22,0x3a928d,{DOUBLEWITHTWODWORDINTREE(0x77600000,0x00000000)}},
+ {VT_exponent,22,0x3a928e,{DOUBLEWITHTWODWORDINTREE(0x77700000,0x00000000)}},
+ {VT_exponent,22,0x3a928f,{DOUBLEWITHTWODWORDINTREE(0x77800000,0x00000000)}},
+ {VT_exponent,22,0x3a9290,{DOUBLEWITHTWODWORDINTREE(0x77900000,0x00000000)}},
+ {VT_exponent,22,0x3a9291,{DOUBLEWITHTWODWORDINTREE(0x77a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9292,{DOUBLEWITHTWODWORDINTREE(0x77b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9293,{DOUBLEWITHTWODWORDINTREE(0x77c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9294,{DOUBLEWITHTWODWORDINTREE(0x77d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9295,{DOUBLEWITHTWODWORDINTREE(0x77e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9296,{DOUBLEWITHTWODWORDINTREE(0x77f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9297,{DOUBLEWITHTWODWORDINTREE(0x78000000,0x00000000)}},
+ {VT_exponent,22,0x3a9298,{DOUBLEWITHTWODWORDINTREE(0x78100000,0x00000000)}},
+ {VT_exponent,22,0x3a9299,{DOUBLEWITHTWODWORDINTREE(0x78200000,0x00000000)}},
+ {VT_exponent,22,0x3a929a,{DOUBLEWITHTWODWORDINTREE(0x78300000,0x00000000)}},
+ {VT_exponent,22,0x3a929b,{DOUBLEWITHTWODWORDINTREE(0x78400000,0x00000000)}},
+ {VT_exponent,22,0x3a929c,{DOUBLEWITHTWODWORDINTREE(0x78500000,0x00000000)}},
+ {VT_exponent,22,0x3a929d,{DOUBLEWITHTWODWORDINTREE(0x78600000,0x00000000)}},
+ {VT_exponent,22,0x3a929e,{DOUBLEWITHTWODWORDINTREE(0x78700000,0x00000000)}},
+ {VT_exponent,22,0x3a929f,{DOUBLEWITHTWODWORDINTREE(0x78800000,0x00000000)}},
+ {VT_exponent,22,0x3a92a0,{DOUBLEWITHTWODWORDINTREE(0x78900000,0x00000000)}},
+ {VT_exponent,22,0x3a92a1,{DOUBLEWITHTWODWORDINTREE(0x78a00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a2,{DOUBLEWITHTWODWORDINTREE(0x78b00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a3,{DOUBLEWITHTWODWORDINTREE(0x78c00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a4,{DOUBLEWITHTWODWORDINTREE(0x78d00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a5,{DOUBLEWITHTWODWORDINTREE(0x78e00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a6,{DOUBLEWITHTWODWORDINTREE(0x78f00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a7,{DOUBLEWITHTWODWORDINTREE(0x79000000,0x00000000)}},
+ {VT_exponent,22,0x3a92a8,{DOUBLEWITHTWODWORDINTREE(0x79100000,0x00000000)}},
+ {VT_exponent,22,0x3a92a9,{DOUBLEWITHTWODWORDINTREE(0x79200000,0x00000000)}},
+ {VT_exponent,22,0x3a92aa,{DOUBLEWITHTWODWORDINTREE(0x79300000,0x00000000)}},
+ {VT_exponent,22,0x3a92ab,{DOUBLEWITHTWODWORDINTREE(0x79400000,0x00000000)}},
+ {VT_exponent,22,0x3a92ac,{DOUBLEWITHTWODWORDINTREE(0x79500000,0x00000000)}},
+ {VT_exponent,22,0x3a92ad,{DOUBLEWITHTWODWORDINTREE(0x79600000,0x00000000)}},
+ {VT_exponent,22,0x3a92ae,{DOUBLEWITHTWODWORDINTREE(0x79700000,0x00000000)}},
+ {VT_exponent,22,0x3a92af,{DOUBLEWITHTWODWORDINTREE(0x79800000,0x00000000)}},
+ {VT_exponent,22,0x3a92b0,{DOUBLEWITHTWODWORDINTREE(0x79900000,0x00000000)}},
+ {VT_exponent,22,0x3a92b1,{DOUBLEWITHTWODWORDINTREE(0x79a00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b2,{DOUBLEWITHTWODWORDINTREE(0x79b00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b3,{DOUBLEWITHTWODWORDINTREE(0x79c00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b4,{DOUBLEWITHTWODWORDINTREE(0x79d00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b5,{DOUBLEWITHTWODWORDINTREE(0x79e00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b6,{DOUBLEWITHTWODWORDINTREE(0x79f00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b7,{DOUBLEWITHTWODWORDINTREE(0x7a000000,0x00000000)}},
+ {VT_exponent,22,0x3a92b8,{DOUBLEWITHTWODWORDINTREE(0x7a100000,0x00000000)}},
+ {VT_exponent,22,0x3a92b9,{DOUBLEWITHTWODWORDINTREE(0x7a200000,0x00000000)}},
+ {VT_exponent,22,0x3a92ba,{DOUBLEWITHTWODWORDINTREE(0x7a300000,0x00000000)}},
+ {VT_exponent,22,0x3a92bb,{DOUBLEWITHTWODWORDINTREE(0x7a400000,0x00000000)}},
+ {VT_exponent,22,0x3a92bc,{DOUBLEWITHTWODWORDINTREE(0x7a500000,0x00000000)}},
+ {VT_exponent,22,0x3a92bd,{DOUBLEWITHTWODWORDINTREE(0x7a600000,0x00000000)}},
+ {VT_exponent,22,0x3a92be,{DOUBLEWITHTWODWORDINTREE(0x7a700000,0x00000000)}},
+ {VT_exponent,22,0x3a92bf,{DOUBLEWITHTWODWORDINTREE(0x7a800000,0x00000000)}},
+ {VT_exponent,22,0x3a92c0,{DOUBLEWITHTWODWORDINTREE(0x7a900000,0x00000000)}},
+ {VT_exponent,22,0x3a92c1,{DOUBLEWITHTWODWORDINTREE(0x7aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c2,{DOUBLEWITHTWODWORDINTREE(0x7ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c3,{DOUBLEWITHTWODWORDINTREE(0x7ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c4,{DOUBLEWITHTWODWORDINTREE(0x7ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c5,{DOUBLEWITHTWODWORDINTREE(0x7ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c6,{DOUBLEWITHTWODWORDINTREE(0x7af00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c7,{DOUBLEWITHTWODWORDINTREE(0x7b000000,0x00000000)}},
+ {VT_exponent,22,0x3a92c8,{DOUBLEWITHTWODWORDINTREE(0x7b100000,0x00000000)}},
+ {VT_exponent,22,0x3a92c9,{DOUBLEWITHTWODWORDINTREE(0x7b200000,0x00000000)}},
+ {VT_exponent,22,0x3a92ca,{DOUBLEWITHTWODWORDINTREE(0x7b300000,0x00000000)}},
+ {VT_exponent,22,0x3a92cb,{DOUBLEWITHTWODWORDINTREE(0x7b400000,0x00000000)}},
+ {VT_exponent,22,0x3a92cc,{DOUBLEWITHTWODWORDINTREE(0x7b500000,0x00000000)}},
+ {VT_exponent,22,0x3a92cd,{DOUBLEWITHTWODWORDINTREE(0x7b600000,0x00000000)}},
+ {VT_exponent,22,0x3a92ce,{DOUBLEWITHTWODWORDINTREE(0x7b700000,0x00000000)}},
+ {VT_exponent,22,0x3a92cf,{DOUBLEWITHTWODWORDINTREE(0x7b800000,0x00000000)}},
+ {VT_exponent,22,0x3a92d0,{DOUBLEWITHTWODWORDINTREE(0x7b900000,0x00000000)}},
+ {VT_exponent,22,0x3a92d1,{DOUBLEWITHTWODWORDINTREE(0x7ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d2,{DOUBLEWITHTWODWORDINTREE(0x7bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d3,{DOUBLEWITHTWODWORDINTREE(0x7bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d4,{DOUBLEWITHTWODWORDINTREE(0x7bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d5,{DOUBLEWITHTWODWORDINTREE(0x7be00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d6,{DOUBLEWITHTWODWORDINTREE(0x7bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d7,{DOUBLEWITHTWODWORDINTREE(0x7c000000,0x00000000)}},
+ {VT_exponent,22,0x3a92d8,{DOUBLEWITHTWODWORDINTREE(0x7c100000,0x00000000)}},
+ {VT_exponent,22,0x3a92d9,{DOUBLEWITHTWODWORDINTREE(0x7c200000,0x00000000)}},
+ {VT_exponent,22,0x3a92da,{DOUBLEWITHTWODWORDINTREE(0x7c300000,0x00000000)}},
+ {VT_exponent,22,0x3a92db,{DOUBLEWITHTWODWORDINTREE(0x7c400000,0x00000000)}},
+ {VT_exponent,22,0x3a92dc,{DOUBLEWITHTWODWORDINTREE(0x7c500000,0x00000000)}},
+ {VT_exponent,22,0x3a92dd,{DOUBLEWITHTWODWORDINTREE(0x7c600000,0x00000000)}},
+ {VT_exponent,22,0x3a92de,{DOUBLEWITHTWODWORDINTREE(0x7c700000,0x00000000)}},
+ {VT_exponent,22,0x3a92df,{DOUBLEWITHTWODWORDINTREE(0x7c800000,0x00000000)}},
+ {VT_exponent,22,0x3a92e0,{DOUBLEWITHTWODWORDINTREE(0x7c900000,0x00000000)}},
+ {VT_exponent,22,0x3a92e1,{DOUBLEWITHTWODWORDINTREE(0x7ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e2,{DOUBLEWITHTWODWORDINTREE(0x7cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e3,{DOUBLEWITHTWODWORDINTREE(0x7cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e4,{DOUBLEWITHTWODWORDINTREE(0x7cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e5,{DOUBLEWITHTWODWORDINTREE(0x7ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e6,{DOUBLEWITHTWODWORDINTREE(0x7cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e7,{DOUBLEWITHTWODWORDINTREE(0x7d000000,0x00000000)}},
+ {VT_exponent,22,0x3a92e8,{DOUBLEWITHTWODWORDINTREE(0x7d100000,0x00000000)}},
+ {VT_exponent,22,0x3a92e9,{DOUBLEWITHTWODWORDINTREE(0x7d200000,0x00000000)}},
+ {VT_exponent,22,0x3a92ea,{DOUBLEWITHTWODWORDINTREE(0x7d300000,0x00000000)}},
+ {VT_exponent,22,0x3a92eb,{DOUBLEWITHTWODWORDINTREE(0x7d400000,0x00000000)}},
+ {VT_exponent,22,0x3a92ec,{DOUBLEWITHTWODWORDINTREE(0x7d500000,0x00000000)}},
+ {VT_exponent,22,0x3a92ed,{DOUBLEWITHTWODWORDINTREE(0x7d600000,0x00000000)}},
+ {VT_exponent,22,0x3a92ee,{DOUBLEWITHTWODWORDINTREE(0x7d700000,0x00000000)}},
+ {VT_exponent,22,0x3a92ef,{DOUBLEWITHTWODWORDINTREE(0x7d800000,0x00000000)}},
+ {VT_exponent,22,0x3a92f0,{DOUBLEWITHTWODWORDINTREE(0x7d900000,0x00000000)}},
+ {VT_exponent,22,0x3a92f1,{DOUBLEWITHTWODWORDINTREE(0x7da00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f2,{DOUBLEWITHTWODWORDINTREE(0x7db00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f3,{DOUBLEWITHTWODWORDINTREE(0x7dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f4,{DOUBLEWITHTWODWORDINTREE(0x7dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f5,{DOUBLEWITHTWODWORDINTREE(0x7de00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f6,{DOUBLEWITHTWODWORDINTREE(0x7df00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f7,{DOUBLEWITHTWODWORDINTREE(0x7e000000,0x00000000)}},
+ {VT_exponent,22,0x3a92f8,{DOUBLEWITHTWODWORDINTREE(0x7e100000,0x00000000)}},
+ {VT_exponent,22,0x3a92f9,{DOUBLEWITHTWODWORDINTREE(0x7e200000,0x00000000)}},
+ {VT_exponent,22,0x3a92fa,{DOUBLEWITHTWODWORDINTREE(0x7e300000,0x00000000)}},
+ {VT_exponent,22,0x3a92fb,{DOUBLEWITHTWODWORDINTREE(0x7e400000,0x00000000)}},
+ {VT_exponent,22,0x3a92fc,{DOUBLEWITHTWODWORDINTREE(0x7e500000,0x00000000)}},
+ {VT_exponent,22,0x3a92fd,{DOUBLEWITHTWODWORDINTREE(0x7e600000,0x00000000)}},
+ {VT_exponent,22,0x3a92fe,{DOUBLEWITHTWODWORDINTREE(0x7e700000,0x00000000)}},
+ {VT_exponent,22,0x3a92ff,{DOUBLEWITHTWODWORDINTREE(0x7e800000,0x00000000)}},
+ {VT_exponent,22,0x3a95a0,{DOUBLEWITHTWODWORDINTREE(0x7e900000,0x00000000)}},
+ {VT_exponent,22,0x3a95a1,{DOUBLEWITHTWODWORDINTREE(0x7ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a2,{DOUBLEWITHTWODWORDINTREE(0x7eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a3,{DOUBLEWITHTWODWORDINTREE(0x7ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a4,{DOUBLEWITHTWODWORDINTREE(0x7ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a5,{DOUBLEWITHTWODWORDINTREE(0x7ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a6,{DOUBLEWITHTWODWORDINTREE(0x7ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a7,{DOUBLEWITHTWODWORDINTREE(0x7f000000,0x00000000)}},
+ {VT_exponent,22,0x3a95a8,{DOUBLEWITHTWODWORDINTREE(0x7f100000,0x00000000)}},
+ {VT_exponent,22,0x3a95a9,{DOUBLEWITHTWODWORDINTREE(0x7f200000,0x00000000)}},
+ {VT_exponent,22,0x3a95aa,{DOUBLEWITHTWODWORDINTREE(0x7f300000,0x00000000)}},
+ {VT_exponent,22,0x3a95ab,{DOUBLEWITHTWODWORDINTREE(0x7f400000,0x00000000)}},
+ {VT_exponent,22,0x3a95ac,{DOUBLEWITHTWODWORDINTREE(0x7f500000,0x00000000)}},
+ {VT_exponent,22,0x3a95ad,{DOUBLEWITHTWODWORDINTREE(0x7f600000,0x00000000)}},
+ {VT_exponent,22,0x3a95ae,{DOUBLEWITHTWODWORDINTREE(0x7f700000,0x00000000)}},
+ {VT_exponent,22,0x3a95af,{DOUBLEWITHTWODWORDINTREE(0x7f800000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe0,{DOUBLEWITHTWODWORDINTREE(0x7f900000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe1,{DOUBLEWITHTWODWORDINTREE(0x7fa00000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe2,{DOUBLEWITHTWODWORDINTREE(0x7fb00000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe3,{DOUBLEWITHTWODWORDINTREE(0x7fc00000,0x00000000)}},
+ {VT_exponent,21,0x68e90,{DOUBLEWITHTWODWORDINTREE(0x7fd00000,0x00000000)}},
+ {VT_exponent,21,0x68e91,{DOUBLEWITHTWODWORDINTREE(0x7fe00000,0x00000000)}},
+ {VT_exponent,21,0x68e98,{DOUBLEWITHTWODWORDINTREE(0x7ff80000,0x00000000)}},
+}; // End of acofdoe array
diff --git a/graphics/asymptote/prc/PRCdouble.h b/graphics/asymptote/prc/PRCdouble.h
new file mode 100644
index 0000000000..4a3a79dccc
--- /dev/null
+++ b/graphics/asymptote/prc/PRCdouble.h
@@ -0,0 +1,140 @@
+#ifndef __PRC_DOUBLE_H
+#define __PRC_DOUBLE_H
+
+#include <cstdlib>
+#include <cmath>
+#include <cstring>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef BYTE_ORDER
+# undef WORDS_BIG_ENDIAN
+# undef WORDS_LITTLE_ENDIAN
+# if BYTE_ORDER == BIG_ENDIAN
+# define WORDS_BIG_ENDIAN 1
+# endif
+# if BYTE_ORDER == LITTLE_ENDIAN
+# define WORDS_LITTLE_ENDIAN 1
+# endif
+#endif
+
+// from Adobe's documentation
+
+union ieee754_double
+{
+ double d;
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#ifdef WORDS_BIGENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif
+ } ieee;
+};
+
+union ieee754_float
+{
+ float f;
+ /* This is the IEEE 754 float-precision format. */
+ struct {
+#ifdef WORDS_BIGENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#else
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif
+ } ieee;
+};
+
+enum ValueType {VT_double,VT_exponent};
+
+struct sCodageOfFrequentDoubleOrExponent
+{
+ short Type;
+ short NumberOfBits;
+ unsigned Bits;
+ union {
+ unsigned ul[2];
+ double Value;
+ } u2uod;
+};
+
+#ifdef WORDS_BIGENDIAN
+# define DOUBLEWITHTWODWORD(upper,lower) upper,lower
+# define UPPERPOWER (0)
+# define LOWERPOWER (!UPPERPOWER)
+
+# define NEXTBYTE(pbd) ((pbd)++)
+# define PREVIOUSBYTE(pbd) ((pbd)--)
+# define MOREBYTE(pbd,pbend) ((pbd)<=(pbend))
+# define OFFSETBYTE(pbd,offset) ((pbd)+=offset)
+# define BEFOREBYTE(pbd) ((pbd)-1)
+# define DIFFPOINTERS(p1,p2) ((p1)-(p2))
+# define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memrchr((pbstart),(b),(nb))
+# define BYTEAT(pb,i) *((pb)-(i))
+#else
+# define DOUBLEWITHTWODWORD(upper,lower) lower,upper
+# define UPPERPOWER (1)
+# define LOWERPOWER (!UPPERPOWER)
+
+# define NEXTBYTE(pbd) ((pbd)--)
+# define PREVIOUSBYTE(pbd) ((pbd)++)
+# define MOREBYTE(pbd,pbend) ((pbd)>=(pbend))
+# define OFFSETBYTE(pbd,offset) ((pbd)-=offset)
+# define BEFOREBYTE(pbd) ((pbd)+1)
+# define DIFFPOINTERS(p1,p2) ((unsigned)((p2)-(p1)))
+# define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memchr((pbstart),(b),(nb))
+# define BYTEAT(pb,i) *((pb)+(i))
+#endif
+
+#define MAXLENGTHFORCOMPRESSEDTYPE ((22+1+1+4+6*(1+8))+7)/8
+
+#define NEGATIVE(d) (((union ieee754_double *)&(d))->ieee.negative)
+#define EXPONENT(d) (((union ieee754_double *)&(d))->ieee.exponent)
+#define MANTISSA0(d) (((union ieee754_double *)&(d))->ieee.mantissa0)
+#define MANTISSA1(d) (((union ieee754_double *)&(d))->ieee.mantissa1)
+
+typedef unsigned char PRCbyte;
+typedef unsigned short PRCword;
+typedef unsigned PRCdword;
+
+extern PRCdword stadwZero[2],stadwNegativeZero[2];
+
+#define NUMBEROFELEMENTINACOFDOE (2077)
+
+#ifdef WORDS_BIGENDIAN
+# define DOUBLEWITHTWODWORDINTREE(upper,lower) {upper,lower}
+#else
+# define DOUBLEWITHTWODWORDINTREE(upper,lower) {lower,upper}
+#endif
+extern sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE];
+
+struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned,short);
+
+#define STAT_V
+#define STAT_DOUBLE
+
+int stCOFDOECompare(const void*,const void*);
+
+#ifdef WORDS_BIGENDIAN
+#ifndef HAVE_MEMRCHR
+void *memrchr(const void *,int,size_t);
+#endif
+#endif
+
+#endif // __PRC_DOUBLE_H
diff --git a/graphics/asymptote/prc/oPRCFile.cc b/graphics/asymptote/prc/oPRCFile.cc
new file mode 100644
index 0000000000..1f20a681a0
--- /dev/null
+++ b/graphics/asymptote/prc/oPRCFile.cc
@@ -0,0 +1,1921 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com> and
+* Michail Vidiassov <master@iaas.msu.ru>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "oPRCFile.h"
+#include <time.h>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <cstring>
+#include <zlib.h>
+
+namespace prc {
+
+#define WriteUnsignedInteger( value ) out << (uint32_t)(value);
+#define WriteInteger( value ) out << (int32_t)(value);
+#define WriteDouble( value ) out << (double)(value);
+#define WriteString( value ) out << (value);
+#define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value));
+#define WriteUncompressedBlock( value, count ) out.write((char *)(value),(count));
+#define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out);
+#define SerializeCompressedUniqueId( value ) (value).serializeCompressedUniqueId(out);
+#define SerializeContentPRCBase write(out);
+#define SerializeRgbColor( value ) (value).serializeRgbColor(out);
+#define SerializePicture( value ) (value).serializePicture(out);
+#define SerializeTextureDefinition( value ) (value)->serializeTextureDefinition(out);
+#define SerializeMarkup( value ) (value)->serializeMarkup(out);
+#define SerializeAnnotationEntity( value ) (value)->serializeAnnotationEntity(out);
+#define SerializeFontKeysSameFont( value ) (value).serializeFontKeysSameFont(out);
+#define SerializeMaterial( value ) (value)->serializeMaterial(out);
+
+#define SerializeUserData UserData(0,0).write(out);
+#define SerializeEmptyContentPRCBase ContentPRCBase(PRC_TYPE_ROOT_PRCBase).serializeContentPRCBase(out);
+#define SerializeCategory1LineStyle( value ) (value)->serializeCategory1LineStyle(out);
+#define SerializeCoordinateSystem( value ) (value)->serializeCoordinateSystem(out);
+#define SerializeRepresentationItem( value ) (value)->serializeRepresentationItem(out);
+#define SerializePartDefinition( value ) (value)->serializePartDefinition(out);
+#define SerializeProductOccurrence( value ) (value)->serializeProductOccurrence(out);
+#define SerializeContextAndBodies( value ) (value)->serializeContextAndBodies(out);
+#define SerializeGeometrySummary( value ) (value)->serializeGeometrySummary(out);
+#define SerializeContextGraphics( value ) (value)->serializeContextGraphics(out);
+#define SerializeStartHeader serializeStartHeader(out);
+#define SerializeUncompressedFiles \
+ { \
+ const uint32_t number_of_uncompressed_files = uncompressed_files.size(); \
+ WriteUncompressedUnsignedInteger (number_of_uncompressed_files) \
+ for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++) \
+ { \
+ WriteUncompressedUnsignedInteger ((*it)->file_size) \
+ WriteUncompressedBlock ((*it)->data, (*it)->file_size) \
+ } \
+ }
+#define SerializeModelFileData serializeModelFileData(modelFile_out); modelFile_out.compress();
+#define SerializeUnit( value ) (value).serializeUnit(out);
+
+using namespace std;
+
+void PRCFileStructure::serializeFileStructureGlobals(PRCbitStream &out)
+{
+ // even though this is technically not part of this section,
+ // it is handled here for convenience
+ const uint32_t number_of_schema = 0;
+ WriteUnsignedInteger (number_of_schema)
+
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGlobals)
+
+ PRCSingleAttribute sa((int32_t)PRCVersion);
+ PRCAttribute a("__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion");
+ a.addKey(sa);
+ ContentPRCBase cb(PRC_TYPE_ROOT_PRCBase);
+ cb.addAttribute(a);
+ cb.serializeContentPRCBase(out);
+ WriteUnsignedInteger (number_of_referenced_file_structures)
+ // SerializeFileStructureInternalGlobalData
+ WriteDouble (tessellation_chord_height_ratio)
+ WriteDouble (tessellation_angle_degree)
+
+ // SerializeMarkupSerializationHelper
+ WriteString (default_font_family_name)
+
+ const uint32_t number_of_fonts = font_keys_of_font.size();
+ WriteUnsignedInteger (number_of_fonts)
+ for (uint32_t i=0;i<number_of_fonts;i++)
+ {
+ SerializeFontKeysSameFont (font_keys_of_font[i])
+ }
+
+ const uint32_t number_of_colors = colors.size();
+ WriteUnsignedInteger (number_of_colors)
+ for (uint32_t i=0;i<number_of_colors;i++)
+ SerializeRgbColor (colors[i])
+
+ const uint32_t number_of_pictures = pictures.size();
+ WriteUnsignedInteger (number_of_pictures)
+ for (uint32_t i=0;i<number_of_pictures;i++)
+ SerializePicture (pictures[i])
+
+ const uint32_t number_of_texture_definitions = texture_definitions.size();
+ WriteUnsignedInteger (number_of_texture_definitions)
+ for (uint32_t i=0;i<number_of_texture_definitions;i++)
+ SerializeTextureDefinition (texture_definitions[i])
+
+ const uint32_t number_of_materials = materials.size();
+ WriteUnsignedInteger (number_of_materials)
+ for (uint32_t i=0;i<number_of_materials;i++)
+ SerializeMaterial (materials[i])
+
+ // number of line patterns hard coded for now
+ const uint32_t number_of_line_patterns = 1;
+ WriteUnsignedInteger (number_of_line_patterns)
+ PRCLinePattern().serializeLinePattern(out);
+
+ const uint32_t number_of_styles = styles.size();
+ WriteUnsignedInteger (number_of_styles)
+ for (uint32_t i=0;i<number_of_styles;i++)
+ SerializeCategory1LineStyle (styles[i])
+
+ const uint32_t number_of_fill_patterns = 0;
+ WriteUnsignedInteger (number_of_fill_patterns)
+
+ const uint32_t number_of_reference_coordinate_systems = reference_coordinate_systems.size();
+ WriteUnsignedInteger (number_of_reference_coordinate_systems)
+ for (uint32_t i=0;i<number_of_reference_coordinate_systems;i++)
+ SerializeCoordinateSystem (reference_coordinate_systems[i])
+
+ SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureTree(PRCbitStream &out)
+{
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureTree)
+
+ SerializeEmptyContentPRCBase
+
+ const uint32_t number_of_part_definitions = part_definitions.size();
+ WriteUnsignedInteger (number_of_part_definitions)
+ for (uint32_t i=0;i<number_of_part_definitions;i++)
+ SerializePartDefinition (part_definitions[i])
+
+ const uint32_t number_of_product_occurrences = product_occurrences.size();
+ WriteUnsignedInteger (number_of_product_occurrences)
+ for (uint32_t i=0;i<number_of_product_occurrences;i++)
+ {
+ product_occurrences[i]->unit_information.unit_from_CAD_file = true;
+ product_occurrences[i]->unit_information.unit = unit;
+ SerializeProductOccurrence (product_occurrences[i])
+ }
+
+ // SerializeFileStructureInternalData
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructure)
+ SerializeEmptyContentPRCBase
+ const uint32_t next_available_index = makePRCID();
+ WriteUnsignedInteger (next_available_index)
+ const uint32_t index_product_occurence = number_of_product_occurrences; // Asymptote (oPRCFile) specific - we write the root product last
+ WriteUnsignedInteger (index_product_occurence)
+
+ SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureTessellation(PRCbitStream &out)
+{
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureTessellation)
+
+ SerializeEmptyContentPRCBase
+ const uint32_t number_of_tessellations = tessellations.size();
+ WriteUnsignedInteger (number_of_tessellations)
+ for (uint32_t i=0;i<number_of_tessellations;i++)
+ tessellations[i]->serializeBaseTessData(out);
+
+ SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureGeometry(PRCbitStream &out)
+{
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGeometry)
+
+ SerializeEmptyContentPRCBase
+ const uint32_t number_of_contexts = contexts.size();
+ WriteUnsignedInteger (number_of_contexts)
+ for (uint32_t i=0;i<number_of_contexts;i++)
+ SerializeContextAndBodies (contexts[i])
+
+ SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureExtraGeometry(PRCbitStream &out)
+{
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureExtraGeometry)
+
+ SerializeEmptyContentPRCBase
+ const uint32_t number_of_contexts = contexts.size();
+ WriteUnsignedInteger (number_of_contexts)
+ for (uint32_t i=0;i<number_of_contexts;i++)
+ {
+ SerializeGeometrySummary (contexts[i])
+ SerializeContextGraphics (contexts[i])
+ }
+
+ SerializeUserData
+}
+
+void oPRCFile::serializeModelFileData(PRCbitStream &out)
+{
+ // even though this is technically not part of this section,
+ // it is handled here for convenience
+ const uint32_t number_of_schema = 0;
+ WriteUnsignedInteger (number_of_schema)
+ WriteUnsignedInteger (PRC_TYPE_ASM_ModelFile)
+
+ PRCSingleAttribute sa((int32_t)PRCVersion);
+ PRCAttribute a("__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion");
+ a.addKey(sa);
+ ContentPRCBase cb(PRC_TYPE_ROOT_PRCBase,"PRC file");
+ cb.addAttribute(a);
+ cb.serializeContentPRCBase(out);
+
+ SerializeUnit (unit)
+
+ out << (uint32_t)1; // 1 product occurrence
+ //UUID
+ SerializeCompressedUniqueId( fileStructures[0]->file_structure_uuid )
+ // index+1
+ out << (uint32_t)fileStructures[0]->product_occurrences.size();
+ // active
+ out << true;
+ out << (uint32_t)0; // index in model file
+
+ SerializeUserData
+}
+
+void makeFileUUID(PRCUniqueId& UUID)
+{
+ // make a UUID
+ static uint32_t count = 0;
+ ++count;
+ // the minimum requirement on UUIDs is that all must be unique in the file
+ UUID.id0 = 0x33595341; // some constant
+ UUID.id1 = (uint32_t)time(NULL); // the time
+ UUID.id2 = count;
+ UUID.id3 = 0xa5a55a5a; // Something random, not seeded by the time, would be nice. But for now, a constant
+ // maybe add something else to make it more unique
+ // so multiple files can be combined
+ // a hash of some data perhaps?
+}
+
+void makeAppUUID(PRCUniqueId& UUID)
+{
+ UUID.id0 = UUID.id1 = UUID.id2 = UUID.id3 = 0;
+}
+
+void PRCUncompressedFile::write(ostream &out) const
+{
+ if(data!=NULL)
+ {
+ WriteUncompressedUnsignedInteger (file_size)
+ out.write((char*)data,file_size);
+ }
+}
+
+uint32_t PRCUncompressedFile::getSize() const
+{
+ return sizeof(file_size)+file_size;
+}
+
+
+void PRCStartHeader::serializeStartHeader(ostream &out) const
+{
+ WriteUncompressedBlock ("PRC",3)
+ WriteUncompressedUnsignedInteger (minimal_version_for_read)
+ WriteUncompressedUnsignedInteger (authoring_version)
+ SerializeFileStructureUncompressedUniqueId( file_structure_uuid );
+ SerializeFileStructureUncompressedUniqueId( application_uuid );
+}
+
+uint32_t PRCStartHeader::getStartHeaderSize() const
+{
+ return 3+(2+2*4)*sizeof(uint32_t);
+}
+
+
+void PRCFileStructure::write(ostream &out)
+{
+ // SerializeFileStructureHeader
+ SerializeStartHeader
+ SerializeUncompressedFiles
+ globals_out.write(out);
+ tree_out.write(out);
+ tessellations_out.write(out);
+ geometry_out.write(out);
+ extraGeometry_out.write(out);
+}
+
+#define SerializeFileStructureGlobals serializeFileStructureGlobals(globals_out); globals_out.compress(); sizes[1]=globals_out.getSize();
+#define SerializeFileStructureTree serializeFileStructureTree(tree_out); tree_out.compress(); sizes[2]=tree_out.getSize();
+#define SerializeFileStructureTessellation serializeFileStructureTessellation(tessellations_out); tessellations_out.compress(); sizes[3]=tessellations_out.getSize();
+#define SerializeFileStructureGeometry serializeFileStructureGeometry(geometry_out); geometry_out.compress(); sizes[4]=geometry_out.getSize();
+#define SerializeFileStructureExtraGeometry serializeFileStructureExtraGeometry(extraGeometry_out); extraGeometry_out.compress(); sizes[5]=extraGeometry_out.getSize();
+#define FlushSerialization resetGraphicsAndName();
+void PRCFileStructure::prepare()
+{
+ uint32_t size = 0;
+ size += getStartHeaderSize();
+ size += sizeof(uint32_t);
+ for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++)
+ size += (*it)->getSize();
+ sizes[0]=size;
+
+ SerializeFileStructureGlobals
+ FlushSerialization
+
+ SerializeFileStructureTree
+ FlushSerialization
+
+ SerializeFileStructureTessellation
+ FlushSerialization
+
+ SerializeFileStructureGeometry
+ FlushSerialization
+
+ SerializeFileStructureExtraGeometry
+ FlushSerialization
+}
+
+uint32_t PRCFileStructure::getSize()
+{
+ uint32_t size = 0;
+ for(size_t i=0; i<6; i++)
+ size += sizes[i];
+ return size;
+}
+
+
+void PRCFileStructureInformation::write(ostream &out)
+{
+ SerializeFileStructureUncompressedUniqueId( UUID );
+
+ WriteUncompressedUnsignedInteger (reserved)
+ WriteUncompressedUnsignedInteger (number_of_offsets)
+ for(uint32_t i = 0; i < number_of_offsets; ++i)
+ {
+ WriteUncompressedUnsignedInteger (offsets[i])
+ }
+}
+
+uint32_t PRCFileStructureInformation::getSize()
+{
+ return (4+2+number_of_offsets)*sizeof(uint32_t);
+}
+
+void PRCHeader::write(ostream &out)
+{
+ SerializeStartHeader
+ WriteUncompressedUnsignedInteger (number_of_file_structures)
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ fileStructureInformation[i].write(out);
+ }
+ WriteUncompressedUnsignedInteger (model_file_offset)
+ WriteUncompressedUnsignedInteger (file_size)
+ SerializeUncompressedFiles
+}
+
+uint32_t PRCHeader::getSize()
+{
+ uint32_t size = getStartHeaderSize() + sizeof(uint32_t);
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ size += fileStructureInformation[i].getSize();
+ size += 3*sizeof(uint32_t);
+ for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++)
+ size += (*it)->getSize();
+ return size;
+}
+
+void oPRCFile::doGroup(PRCgroup& group)
+{
+ const std::string& name = group.name;
+
+ PRCProductOccurrence*& product_occurrence = group.product_occurrence;
+ PRCProductOccurrence*& parent_product_occurrence = group.parent_product_occurrence;
+ PRCPartDefinition*& part_definition = group.part_definition;
+ PRCPartDefinition*& parent_part_definition = group.parent_part_definition;
+
+ if(group.options.tess)
+ {
+ if(!group.lines.empty())
+ {
+ for(PRCtesslineMap::const_iterator wit=group.lines.begin(); wit!=group.lines.end(); wit++)
+ {
+ bool same_color = true;
+ const PRCtesslineList& lines = wit->second;
+ const PRCRgbColor &color = lines.front().color;
+ for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++)
+ if(color!=lit->color)
+ {
+ same_color = false;
+ break;
+ }
+ map<PRCVector3d,uint32_t> points;
+ PRC3DWireTess *tess = new PRC3DWireTess();
+ if(!same_color)
+ {
+ tess->is_segment_color = true;
+ tess->is_rgba = false;
+ }
+ for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++)
+ {
+ tess->wire_indexes.push_back(lit->point.size());
+ for(uint32_t i=0; i<lit->point.size(); i++)
+ {
+ map<PRCVector3d,uint32_t>::iterator pPoint = points.find(lit->point[i]);
+ if(pPoint!=points.end())
+ tess->wire_indexes.push_back(pPoint->second);
+ else
+ {
+ const uint32_t point_index = tess->coordinates.size();
+ points.insert(make_pair(lit->point[i],point_index));
+ tess->wire_indexes.push_back(point_index);
+ tess->coordinates.push_back(lit->point[i].x);
+ tess->coordinates.push_back(lit->point[i].y);
+ tess->coordinates.push_back(lit->point[i].z);
+ }
+ if(!same_color && i>0)
+ {
+ tess->rgba_vertices.push_back(byte(lit->color.red));
+ tess->rgba_vertices.push_back(byte(lit->color.green));
+ tess->rgba_vertices.push_back(byte(lit->color.blue));
+ }
+ }
+ }
+ const uint32_t tess_index = add3DWireTess(tess);
+ PRCPolyWire *polyWire = new PRCPolyWire();
+ polyWire->index_tessellation = tess_index;
+ if(same_color)
+ polyWire->index_of_line_style = addColourWidth(RGBAColour(color.red,color.green,color.blue),wit->first);
+ else
+ polyWire->index_of_line_style = addColourWidth(RGBAColour(1,1,1),wit->first);
+ part_definition->addPolyWire(polyWire);
+ }
+ }
+// make rectangles pairs of triangles in a tesselation
+ if(!group.rectangles.empty())
+ {
+ bool same_color = true;
+ const uint32_t &style = group.rectangles.front().style;
+ for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++)
+ if(style!=rit->style)
+ {
+ same_color = false;
+ break;
+ }
+ map<PRCVector3d,uint32_t> points;
+ PRC3DTess *tess = new PRC3DTess();
+ tess->crease_angle = group.options.crease_angle;
+ PRCTessFace *tessFace = new PRCTessFace();
+ tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle;
+ uint32_t triangles = 0;
+ for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++)
+ {
+ const bool degenerate = (rit->vertices[0]==rit->vertices[1]);
+ uint32_t vertex_indices[4];
+ for(size_t i = (degenerate?1:0); i < 4; ++i)
+ {
+ map<PRCVector3d,uint32_t>::const_iterator pPoint = points.find(rit->vertices[i]);
+ if(pPoint!=points.end())
+ vertex_indices[i] = pPoint->second;
+ else
+ {
+ points.insert(make_pair(rit->vertices[i],(vertex_indices[i] = tess->coordinates.size())));
+ tess->coordinates.push_back(rit->vertices[i].x);
+ tess->coordinates.push_back(rit->vertices[i].y);
+ tess->coordinates.push_back(rit->vertices[i].z);
+ }
+ }
+ if(degenerate)
+ {
+ tess->triangulated_index.push_back(vertex_indices[1]);
+ tess->triangulated_index.push_back(vertex_indices[2]);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ triangles++;
+ if(!same_color)
+ tessFace->line_attributes.push_back(rit->style);
+ }
+ else
+ {
+ tess->triangulated_index.push_back(vertex_indices[0]);
+ tess->triangulated_index.push_back(vertex_indices[2]);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ triangles++;
+ if(!same_color)
+ tessFace->line_attributes.push_back(rit->style);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ tess->triangulated_index.push_back(vertex_indices[1]);
+ tess->triangulated_index.push_back(vertex_indices[0]);
+ triangles++;
+ if(!same_color)
+ tessFace->line_attributes.push_back(rit->style);
+ }
+ }
+ tessFace->sizes_triangulated.push_back(triangles);
+ tess->addTessFace(tessFace);
+ const uint32_t tess_index = add3DTess(tess);
+ PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+ polyBrepModel->index_tessellation = tess_index;
+ polyBrepModel->is_closed = group.options.closed;
+ if(same_color)
+ polyBrepModel->index_of_line_style = style;
+ part_definition->addPolyBrepModel(polyBrepModel);
+ }
+ }
+
+ if(!group.quads.empty())
+ {
+ map<PRCVector3d,uint32_t> points;
+ PRC3DTess *tess = new PRC3DTess();
+ tess->crease_angle = group.options.crease_angle;
+ PRCTessFace *tessFace = new PRCTessFace();
+ tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle;
+ uint32_t triangles = 0;
+
+ tessFace->is_rgba = false;
+ for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+ {
+ const RGBAColour* C = qit->colours;
+ if(C[0].A != 1.0 || C[1].A != 1.0 || C[2].A != 1.0 || C[3].A != 1.0)
+ {
+ tessFace->is_rgba = true;
+ break;
+ }
+ }
+ bool same_colour = true;
+ const RGBAColour& colour = group.quads.front().colours[0];
+ for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+ {
+ const RGBAColour* C = qit->colours;
+ if(colour!=C[0] || colour!=C[1] || colour!=C[2] || colour!=C[3])
+ {
+ same_colour = false;
+ break;
+ }
+ }
+
+ for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+ {
+ const RGBAColour* C = qit->colours;
+ const bool degenerate = (qit->vertices[0]==qit->vertices[1]);
+ uint32_t vertex_indices[4];
+ for(size_t i = (degenerate?1:0); i < 4; ++i)
+ {
+ map<PRCVector3d,uint32_t>::const_iterator pPoint = points.find(qit->vertices[i]);
+ if(pPoint!=points.end())
+ vertex_indices[i] = pPoint->second;
+ else
+ {
+ points.insert(make_pair(qit->vertices[i],(vertex_indices[i] = tess->coordinates.size())));
+ tess->coordinates.push_back(qit->vertices[i].x);
+ tess->coordinates.push_back(qit->vertices[i].y);
+ tess->coordinates.push_back(qit->vertices[i].z);
+ }
+ }
+ if(degenerate)
+ {
+ tess->triangulated_index.push_back(vertex_indices[1]);
+ tess->triangulated_index.push_back(vertex_indices[2]);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ triangles++;
+ if(!same_colour)
+ {
+ tessFace->rgba_vertices.push_back(byte(C[1].R));
+ tessFace->rgba_vertices.push_back(byte(C[1].G));
+ tessFace->rgba_vertices.push_back(byte(C[1].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[1].A));
+
+ tessFace->rgba_vertices.push_back(byte(C[2].R));
+ tessFace->rgba_vertices.push_back(byte(C[2].G));
+ tessFace->rgba_vertices.push_back(byte(C[2].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[2].A));
+
+ tessFace->rgba_vertices.push_back(byte(C[3].R));
+ tessFace->rgba_vertices.push_back(byte(C[3].G));
+ tessFace->rgba_vertices.push_back(byte(C[3].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[3].A));
+ }
+ }
+ else
+ {
+ tess->triangulated_index.push_back(vertex_indices[0]);
+ tess->triangulated_index.push_back(vertex_indices[2]);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ triangles++;
+ if(!same_colour)
+ {
+ tessFace->rgba_vertices.push_back(byte(C[0].R));
+ tessFace->rgba_vertices.push_back(byte(C[0].G));
+ tessFace->rgba_vertices.push_back(byte(C[0].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[0].A));
+
+ tessFace->rgba_vertices.push_back(byte(C[2].R));
+ tessFace->rgba_vertices.push_back(byte(C[2].G));
+ tessFace->rgba_vertices.push_back(byte(C[2].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[2].A));
+
+ tessFace->rgba_vertices.push_back(byte(C[3].R));
+ tessFace->rgba_vertices.push_back(byte(C[3].G));
+ tessFace->rgba_vertices.push_back(byte(C[3].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[3].A));
+ }
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ tess->triangulated_index.push_back(vertex_indices[1]);
+ tess->triangulated_index.push_back(vertex_indices[0]);
+ triangles++;
+ if(!same_colour)
+ {
+ tessFace->rgba_vertices.push_back(byte(C[3].R));
+ tessFace->rgba_vertices.push_back(byte(C[3].G));
+ tessFace->rgba_vertices.push_back(byte(C[3].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[3].A));
+
+ tessFace->rgba_vertices.push_back(byte(C[1].R));
+ tessFace->rgba_vertices.push_back(byte(C[1].G));
+ tessFace->rgba_vertices.push_back(byte(C[1].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[1].A));
+
+ tessFace->rgba_vertices.push_back(byte(C[0].R));
+ tessFace->rgba_vertices.push_back(byte(C[0].G));
+ tessFace->rgba_vertices.push_back(byte(C[0].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[0].A));
+ }
+ }
+ }
+ tessFace->sizes_triangulated.push_back(triangles);
+ tess->addTessFace(tessFace);
+ const uint32_t tess_index = add3DTess(tess);
+ PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+ polyBrepModel->index_tessellation = tess_index;
+ polyBrepModel->is_closed = group.options.closed;
+ if(same_colour)
+ polyBrepModel->index_of_line_style = addColour(colour);
+ part_definition->addPolyBrepModel(polyBrepModel);
+ }
+
+ if(!group.points.empty())
+ {
+ for(PRCpointsetMap::const_iterator pit=group.points.begin(); pit!=group.points.end(); pit++)
+ {
+ PRCPointSet *pointset = new PRCPointSet();
+ pointset->index_of_line_style = pit->first;
+ pointset->point = pit->second;
+ part_definition->addPointSet(pointset);
+ }
+ }
+
+ if(!group.pointsets.empty())
+ {
+ for(std::vector<PRCPointSet*>::iterator pit=group.pointsets.begin(); pit!=group.pointsets.end(); pit++)
+ {
+ part_definition->addPointSet(*pit);
+ }
+ }
+
+ if(!group.polymodels.empty())
+ {
+ for(std::vector<PRCPolyBrepModel*>::iterator pit=group.polymodels.begin(); pit!=group.polymodels.end(); pit++)
+ {
+ (*pit)->is_closed = group.options.closed;
+ part_definition->addPolyBrepModel(*pit);
+ }
+ }
+
+ if(!group.polywires.empty())
+ {
+ for(std::vector<PRCPolyWire*>::iterator pit=group.polywires.begin(); pit!=group.polywires.end(); pit++)
+ {
+ part_definition->addPolyWire(*pit);
+ }
+ }
+
+ if(!group.wires.empty())
+ {
+ PRCTopoContext *wireContext = NULL;
+ const uint32_t context_index = getTopoContext(wireContext);
+ for(PRCwireList::iterator wit=group.wires.begin(); wit!=group.wires.end(); wit++)
+ {
+ PRCWireEdge *wireEdge = new PRCWireEdge;
+ wireEdge->curve_3d = wit->curve;
+ PRCSingleWireBody *wireBody = new PRCSingleWireBody;
+ wireBody->setWireEdge(wireEdge);
+ const uint32_t wire_body_index = wireContext->addSingleWireBody(wireBody);
+ PRCWire *wire = new PRCWire();
+ wire->index_of_line_style = wit->style;
+ wire->context_id = context_index;
+ wire->body_id = wire_body_index;
+ if(wit->transform)
+ wire->index_local_coordinate_system = addTransform(wit->transform);
+ part_definition->addWire(wire);
+ }
+ }
+
+ PRCfaceList &faces = group.faces;
+ if(!faces.empty())
+ {
+ bool same_color = true;
+ const uint32_t style = faces.front().style;
+ for(PRCfaceList::const_iterator fit=faces.begin(); fit!=faces.end(); fit++)
+ if(style!=fit->style)
+ {
+ same_color = false;
+ break;
+ }
+ PRCTopoContext *context = NULL;
+ const uint32_t context_index = getTopoContext(context);
+ context->granularity = group.options.granularity;
+ // Acrobat 9 also does the following:
+ // context->tolerance = group.options.granularity;
+ // context->have_smallest_face_thickness = true;
+ // context->smallest_thickness = group.options.granularity;
+ PRCShell *shell = new PRCShell;
+
+ for(PRCfaceList::iterator fit=faces.begin(); fit!=faces.end(); fit++)
+ {
+ if(fit->transform || group.options.do_break ||
+ (fit->transparent && !group.options.no_break))
+ {
+ PRCShell *shell = new PRCShell;
+ shell->addFace(fit->face);
+ PRCConnex *connex = new PRCConnex;
+ connex->addShell(shell);
+ PRCBrepData *body = new PRCBrepData;
+ body->addConnex(connex);
+ const uint32_t body_index = context->addBrepData(body);
+
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ brepmodel->index_of_line_style = fit->style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+
+ brepmodel->index_local_coordinate_system = addTransform(fit->transform);
+
+ part_definition->addBrepModel(brepmodel);
+ }
+ else
+ {
+ if(!same_color)
+ fit->face->index_of_line_style = fit->style;
+ shell->addFace(fit->face);
+ }
+ }
+ if(shell->face.empty())
+ {
+ delete shell;
+ }
+ else
+ {
+ PRCConnex *connex = new PRCConnex;
+ connex->addShell(shell);
+ PRCBrepData *body = new PRCBrepData;
+ body->addConnex(connex);
+ const uint32_t body_index = context->addBrepData(body);
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ if(same_color)
+ brepmodel->index_of_line_style = style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+ part_definition->addBrepModel(brepmodel);
+ }
+ }
+
+ PRCcompfaceList &compfaces = group.compfaces;
+ if(!compfaces.empty())
+ {
+ bool same_color = true;
+ const uint32_t style = compfaces.front().style;
+ for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++)
+ if(style!=fit->style)
+ {
+ same_color = false;
+ break;
+ }
+ PRCTopoContext *context = NULL;
+ const uint32_t context_index = getTopoContext(context);
+ PRCCompressedBrepData *body = new PRCCompressedBrepData;
+
+ body->serial_tolerance=group.options.compression;
+ body->brep_data_compressed_tolerance=0.1*group.options.compression;
+
+ for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++)
+ {
+ if(group.options.do_break ||
+ (fit->transparent && !group.options.no_break))
+ {
+ PRCCompressedBrepData *body = new PRCCompressedBrepData;
+ body->face.push_back(fit->face);
+
+ body->serial_tolerance=group.options.compression;
+ body->brep_data_compressed_tolerance=2.8346456*
+ group.options.compression;
+ const uint32_t body_index = context->addCompressedBrepData(body);
+
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ brepmodel->index_of_line_style = fit->style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+
+ part_definition->addBrepModel(brepmodel);
+ }
+ else
+ {
+ if(!same_color)
+ fit->face->index_of_line_style = fit->style;
+ body->face.push_back(fit->face);
+ }
+ }
+ if(body->face.empty())
+ {
+ delete body;
+ }
+ else
+ {
+ const uint32_t body_index = context->addCompressedBrepData(body);
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ if(same_color)
+ brepmodel->index_of_line_style = style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+ part_definition->addBrepModel(brepmodel);
+ }
+ }
+
+ // Simplify and reduce to as simple entities as possible
+ // products with named representation items can not be reduced to sets, since
+ // outside references are already set
+ bool nonamedparts = true;
+ for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+ {
+ if (!(*it)->name.empty())
+ {
+ nonamedparts = false;
+ break;
+ }
+ }
+ lastgroupname.clear();
+ lastgroupnames.clear();
+ // First option - reduce to one element in parent
+ if (parent_part_definition && product_occurrence->index_son_occurrence.empty() &&
+ part_definition->representation_item.size() == 1 &&
+ ( name.empty() || part_definition->representation_item.front()->name.empty() ) &&
+ ( !group.transform || part_definition->representation_item.front()->index_local_coordinate_system==m1) )
+ {
+ if(part_definition->representation_item.front()->name.empty() )
+ part_definition->representation_item.front()->name = name;
+ if(part_definition->representation_item.front()->index_local_coordinate_system==m1)
+ part_definition->representation_item.front()->index_local_coordinate_system = addTransform(group.transform);
+ lastgroupname = calculate_unique_name(part_definition->representation_item.front(), parent_product_occurrence);
+ parent_part_definition->addRepresentationItem(part_definition->representation_item.front());
+ part_definition->representation_item.clear();
+ delete product_occurrence; product_occurrence = NULL;
+ delete part_definition; part_definition = NULL;
+ }
+ // Second option - reduce to a set
+ else if (parent_part_definition && product_occurrence->index_son_occurrence.empty() &&
+ !part_definition->representation_item.empty() &&
+ !group.options.do_break && nonamedparts)
+ {
+ PRCSet *set = new PRCSet(name);
+ set->index_local_coordinate_system = addTransform(group.transform);
+ lastgroupname = calculate_unique_name(set, parent_product_occurrence);
+ for(PRCRepresentationItemList::iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+ {
+ lastgroupnames.push_back(calculate_unique_name(*it, parent_product_occurrence));
+ set->addRepresentationItem(*it);
+ }
+ part_definition->representation_item.clear();
+ parent_part_definition->addSet(set);
+ delete product_occurrence; product_occurrence = NULL;
+ delete part_definition; part_definition = NULL;
+ }
+ // Third option - create product
+ else if ( !product_occurrence->index_son_occurrence.empty() || !part_definition->representation_item.empty())
+ {
+ // if everything is enclosed in one group - drop the root group
+ if (parent_product_occurrence == NULL && group.transform == NULL &&
+ part_definition->representation_item.empty() && product_occurrence->index_son_occurrence.size()==1) {
+ delete part_definition; part_definition = NULL;
+ delete product_occurrence; product_occurrence = NULL;
+ }
+ else
+ {
+ lastgroupname = calculate_unique_name(product_occurrence, NULL);
+ if (part_definition->representation_item.empty()) {
+ delete part_definition; part_definition = NULL;
+ }
+ else
+ {
+ for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+ if ((*it)->name.empty())
+ lastgroupnames.push_back(calculate_unique_name(*it, product_occurrence));
+ product_occurrence->index_part = addPartDefinition(part_definition);
+ }
+ if (group.transform) {
+ product_occurrence->location = group.transform;
+ group.transform = NULL;
+ }
+ if (parent_product_occurrence) {
+ parent_product_occurrence->index_son_occurrence.push_back(addProductOccurrence(product_occurrence));
+ }
+ else {
+ addProductOccurrence(product_occurrence);
+ }
+ }
+ }
+ // Last case - absolutely nothing to do
+ else
+ {
+ delete product_occurrence; product_occurrence = NULL;
+ delete part_definition; part_definition = NULL;
+ }
+
+}
+
+std::string oPRCFile::calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence)
+{
+ std::stringstream ss (std::stringstream::in | std::stringstream::out);
+ uint8_t *serialization_buffer = NULL;
+ PRCbitStream serialization(serialization_buffer,0u);
+ const PRCFileStructure *pfile_structure = fileStructures[0];
+ const PRCUniqueId& uuid = pfile_structure->file_structure_uuid;
+// ConvertUniqueIdentifierToString (prc_entity)
+// SerializeCompressedUniqueId (file_structure)
+ serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3;
+// WriteUnsignedInteger (type)
+ serialization << prc_entity->getType();
+// WriteUnsignedInteger (unique_identifier)
+ serialization << prc_entity->getPRCID();
+ if (prc_occurence)
+ {
+// serialization_buffer = Flush serialization (serialization)
+ {
+ const uint32_t size_serialization = serialization.getSize();
+ while(size_serialization == serialization.getSize())
+ serialization << false;
+ }
+// ConvertUniqueIdentifierToString (prc_occurrence_unique_id)
+// SerializeCompressedUniqueId (file_structure)
+ serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3;
+// WriteUnsignedInteger (type)
+ serialization << (uint32_t)PRC_TYPE_ASM_ProductOccurence;
+// WriteUnsignedInteger (unique_identifier)
+ serialization << prc_occurence->getPRCID();
+ }
+ ss << (prc_entity->name.empty()?"node":prc_entity->name) << '.';
+ const uint32_t size_serialization = serialization.getSize();
+ for(size_t j=0; j<size_serialization; j++)
+ ss << hex << setfill('0') << setw(2) << (uint32_t)(serialization_buffer[j]);
+
+ return ss.str();
+}
+
+bool oPRCFile::finish()
+{
+ if(groups.size()!=1) {
+ fputs("begingroup without matching endgroup",stderr);
+ exit(1);
+ }
+ doGroup(groups.top());
+
+ // write each section's bit data
+ fileStructures[0]->prepare();
+ SerializeModelFileData
+
+ // create the header
+
+ // fill out enough info so that sizes can be computed correctly
+ header.number_of_file_structures = number_of_file_structures;
+ header.fileStructureInformation = new PRCFileStructureInformation[number_of_file_structures];
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ header.fileStructureInformation[i].UUID = fileStructures[i]->file_structure_uuid;
+ header.fileStructureInformation[i].reserved = 0;
+ header.fileStructureInformation[i].number_of_offsets = 6;
+ header.fileStructureInformation[i].offsets = new uint32_t[6];
+ }
+
+ header.minimal_version_for_read = PRCVersion;
+ header.authoring_version = PRCVersion;
+ makeFileUUID(header.file_structure_uuid);
+ makeAppUUID(header.application_uuid);
+
+ header.file_size = getSize();
+ header.model_file_offset = header.file_size - modelFile_out.getSize();
+
+ uint32_t currentOffset = header.getSize();
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ for(size_t j=0; j<6; j++)
+ {
+ header.fileStructureInformation[i].offsets[j] = currentOffset;
+ currentOffset += fileStructures[i]->sizes[j];
+ }
+ }
+
+ // write the data
+ header.write(output);
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ fileStructures[i]->write(output);
+ }
+
+ modelFile_out.write(output);
+ output.flush();
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ delete[] header.fileStructureInformation[i].offsets;
+ delete[] header.fileStructureInformation;
+
+ return true;
+}
+
+uint32_t oPRCFile::getSize()
+{
+ uint32_t size = header.getSize();
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ size += fileStructures[i]->getSize();
+ }
+
+ size += modelFile_out.getSize();
+ return size;
+}
+
+uint32_t PRCFileStructure::addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *p, uint32_t width, uint32_t height, std::string name)
+{
+ uint8_t *data = NULL;
+ uint32_t components=0;
+ PRCPicture picture(name);
+ if(size==0 || p==NULL)
+ { cerr << "image not set" << endl; return m1; }
+ PRCUncompressedFile* uncompressed_file = new PRCUncompressedFile;
+ if(format==KEPRCPicture_PNG || format==KEPRCPicture_JPG)
+ {
+ data = new uint8_t[size];
+ memcpy(data, p, size);
+ uncompressed_files.push_back(uncompressed_file);
+ uncompressed_files.back()->file_size = size;
+ uncompressed_files.back()->data = data;
+ picture.format = format;
+ picture.uncompressed_file_index = uncompressed_files.size()-1;
+ picture.pixel_width = 0; // width and height are ignored for JPG and PNG pictures - but let us keep things clean
+ picture.pixel_height = 0;
+ pictures.push_back(picture);
+ return pictures.size()-1;
+ }
+
+ switch(format)
+ {
+ case KEPRCPicture_BITMAP_RGB_BYTE:
+ components = 3; break;
+ case KEPRCPicture_BITMAP_RGBA_BYTE:
+ components = 4; break;
+ case KEPRCPicture_BITMAP_GREY_BYTE:
+ components = 1; break;
+ case KEPRCPicture_BITMAP_GREYA_BYTE:
+ components = 2; break;
+ default:
+ { cerr << "unknown picture format" << endl; return m1; }
+ }
+ if(width==0 || height==0)
+ { cerr << "width or height parameter not set" << endl; return m1; }
+ if (size < width*height*components)
+ { cerr << "image too small" << endl; return m1; }
+
+ {
+ uint32_t compressedDataSize = 0;
+ const int CHUNK= 1024; // is this reasonable?
+
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK)
+ { cerr << "Compression initialization failed" << endl; return m1; }
+ unsigned int sizeAvailable = deflateBound(&strm,size);
+ uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable);
+ strm.avail_in = size;
+ strm.next_in = (unsigned char*)p;
+ strm.next_out = (unsigned char*)compressedData;
+ strm.avail_out = sizeAvailable;
+
+ int code;
+ unsigned int chunks = 0;
+ while((code = deflate(&strm,Z_FINISH)) == Z_OK)
+ {
+ ++chunks;
+ // strm.avail_out should be 0 if we got Z_OK
+ compressedDataSize = sizeAvailable - strm.avail_out;
+ compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks);
+ strm.next_out = (Bytef*)(compressedData + compressedDataSize);
+ strm.avail_out += CHUNK;
+ sizeAvailable += CHUNK;
+ }
+ compressedDataSize = sizeAvailable-strm.avail_out;
+
+ if(code != Z_STREAM_END)
+ {
+ deflateEnd(&strm);
+ free(compressedData);
+ { cerr << "Compression error" << endl; return m1; }
+ }
+
+ deflateEnd(&strm);
+ size = compressedDataSize;
+ data = new uint8_t[compressedDataSize];
+ memcpy(data, compressedData, compressedDataSize);
+ free(compressedData);
+ }
+ uncompressed_files.push_back(uncompressed_file);
+ uncompressed_files.back()->file_size = size;
+ uncompressed_files.back()->data = data;
+ picture.format = format;
+ picture.uncompressed_file_index = uncompressed_files.size()-1;
+ picture.pixel_width = width;
+ picture.pixel_height = height;
+ pictures.push_back(picture);
+ return pictures.size()-1;
+}
+
+uint32_t PRCFileStructure::addTextureDefinition(PRCTextureDefinition*& pTextureDefinition)
+{
+ texture_definitions.push_back(pTextureDefinition);
+ pTextureDefinition = NULL;
+ return texture_definitions.size()-1;
+}
+
+uint32_t PRCFileStructure::addRgbColor(const PRCRgbColor &color)
+{
+ colors.push_back(color);
+ return 3*(colors.size()-1);
+}
+
+uint32_t PRCFileStructure::addRgbColorUnique(const PRCRgbColor &color)
+{
+ for(uint32_t i = 0; i < colors.size(); ++i)
+ {
+ if(colors[i] == color)
+ return 3*i;
+ }
+ colors.push_back(color);
+ return 3*(colors.size()-1);
+}
+
+uint32_t oPRCFile::addColor(const PRCRgbColor &color)
+{
+ PRCcolorMap::const_iterator pColor = colorMap.find(color);
+ if(pColor!=colorMap.end())
+ return pColor->second;
+// color_index = addRgbColorUnique(color);
+ const uint32_t color_index = fileStructures[0]->addRgbColor(color);
+ colorMap.insert(make_pair(color,color_index));
+ return color_index;
+}
+
+uint32_t oPRCFile::addColour(const RGBAColour &colour)
+{
+ PRCcolourMap::const_iterator pColour = colourMap.find(colour);
+ if(pColour!=colourMap.end())
+ return pColour->second;
+ const uint32_t color_index = addColor(PRCRgbColor(colour.R, colour.G, colour.B));
+ PRCStyle *style = new PRCStyle();
+ style->line_width = 1.0;
+ style->is_vpicture = false;
+ style->line_pattern_vpicture_index = 0;
+ style->is_material = false;
+ style->color_material_index = color_index;
+ style->is_transparency_defined = (colour.A < 1.0);
+ style->transparency = (uint8_t)(colour.A * 256);
+ style->additional = 0;
+ const uint32_t style_index = fileStructures[0]->addStyle(style);
+ colourMap.insert(make_pair(colour,style_index));
+ return style_index;
+}
+
+uint32_t oPRCFile::addColourWidth(const RGBAColour &colour, double width)
+{
+ RGBAColourWidth colourwidth(colour.R, colour.G, colour.B, colour.A, width);
+ PRCcolourwidthMap::const_iterator pColour = colourwidthMap.find(colourwidth);
+ if(pColour!=colourwidthMap.end())
+ return pColour->second;
+ const uint32_t color_index = addColor(PRCRgbColor(colour.R, colour.G, colour.B));
+ PRCStyle *style = new PRCStyle();
+ style->line_width = width;
+ style->is_vpicture = false;
+ style->line_pattern_vpicture_index = 0;
+ style->is_material = false;
+ style->color_material_index = color_index;
+ style->is_transparency_defined = (colour.A < 1.0);
+ style->transparency = (uint8_t)(colour.A * 256);
+ style->additional = 0;
+ const uint32_t style_index = fileStructures[0]->addStyle(style);
+ colourwidthMap.insert(make_pair(colourwidth,style_index));
+ return style_index;
+}
+
+uint32_t oPRCFile::addTransform(PRCGeneralTransformation3d*& transform)
+{
+ if(!transform)
+ return m1;
+ PRCtransformMap::const_iterator pTransform = transformMap.find(*transform);
+ if(pTransform!=transformMap.end())
+ return pTransform->second;
+ PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem();
+ bool transform_replaced = false;
+ if( transform->M(0,1)==0 && transform->M(0,2)==0 &&
+ transform->M(1,0)==0 && transform->M(1,2)==0 &&
+ transform->M(2,0)==0 && transform->M(2,1)==0 &&
+ transform->M(3,0)==0 && transform->M(3,1)==0 && transform->M(3,2)==0 && transform->M(3,3)==1 )
+ {
+ transform_replaced = true;
+ PRCCartesianTransformation3d *carttransform = new PRCCartesianTransformation3d;
+// if(transform->M(0,3)==0 && transform->M(1,3)==0 && transform->M(1,3)==0 &&
+// transform->M(0,0)==1 && transform->M(1,1)==1 && transform->M(2,2)==1 )
+// carttransform->behaviour = PRC_TRANSFORMATION_Identity;
+ if(transform->M(0,3)!=0 || transform->M(1,3)!=0 || transform->M(2,3)!=0)
+ {
+ carttransform->behaviour |= PRC_TRANSFORMATION_Translate;
+ carttransform->origin.Set(transform->M(0,3),transform->M(1,3),transform->M(2,3));
+ }
+ if(transform->M(0,0)!=transform->M(1,1) || transform->M(0,0)!=transform->M(2,2))
+ {
+ carttransform->behaviour |= PRC_TRANSFORMATION_NonUniformScale;
+ carttransform->scale.Set(transform->M(0,0),transform->M(1,1),transform->M(2,2));
+ }
+ else
+ if(transform->M(0,0)!=1)
+ {
+ carttransform->behaviour |= PRC_TRANSFORMATION_Scale;
+ carttransform->uniform_scale=transform->M(0,0);
+ }
+ coordinateSystem->axis_set = carttransform;
+ }
+ else
+ coordinateSystem->axis_set = transform;
+ const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem);
+ transformMap.insert(make_pair(*transform,coordinate_system_index));
+ if(transform_replaced)
+ delete transform;
+ transform = NULL;
+ return coordinate_system_index;
+}
+
+uint32_t oPRCFile::addTransform(const double* t)
+{
+ if(!t)
+ return m1;
+ PRCGeneralTransformation3d* transform = new PRCGeneralTransformation3d(t);
+ return addTransform(transform);
+}
+
+uint32_t oPRCFile::addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+ PRCCartesianTransformation3d* transform = new PRCCartesianTransformation3d(origin, x_axis, y_axis, scale);
+ if(transform->behaviour==PRC_TRANSFORMATION_Identity)
+ return m1;
+ PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem();
+ coordinateSystem->axis_set = transform;
+ const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem);
+ return coordinate_system_index;
+}
+
+uint32_t oPRCFile::addMaterial(const PRCmaterial& m)
+{
+ uint32_t material_index = m1;
+ const PRCmaterialgeneric materialgeneric(m);
+ PRCmaterialgenericMap::const_iterator pMaterialgeneric = materialgenericMap.find(materialgeneric);
+ if(pMaterialgeneric!=materialgenericMap.end())
+ material_index = pMaterialgeneric->second;
+ else
+{
+ PRCMaterialGeneric *materialGeneric = new PRCMaterialGeneric();
+ const PRCRgbColor ambient(m.ambient.R, m.ambient.G, m.ambient.B);
+ materialGeneric->ambient = addColor(ambient);
+ const PRCRgbColor diffuse(m.diffuse.R, m.diffuse.G, m.diffuse.B);
+ materialGeneric->diffuse = addColor(diffuse);
+ const PRCRgbColor emissive(m.emissive.R, m.emissive.G, m.emissive.B);
+
+ materialGeneric->emissive = addColor(emissive);
+ const PRCRgbColor specular(m.specular.R, m.specular.G, m.specular.B);
+ materialGeneric->specular = addColor(specular);
+
+ materialGeneric->shininess = m.shininess;
+ materialGeneric->ambient_alpha = m.ambient.A;
+ materialGeneric->diffuse_alpha = m.diffuse.A;
+ materialGeneric->emissive_alpha = m.emissive.A;
+ materialGeneric->specular_alpha = m.specular.A;
+ material_index = addMaterialGeneric(materialGeneric);
+ materialgenericMap.insert(make_pair(materialgeneric,material_index));
+ }
+ uint32_t color_material_index = m1;
+ if(m.picture_data!=NULL)
+ {
+ uint32_t picture_index = m1;
+ PRCpicture picture(m);
+ PRCpictureMap::const_iterator pPicture = pictureMap.find(picture);
+ if(pPicture!=pictureMap.end())
+ picture_index = pPicture->second;
+ else
+ {
+ picture_index = addPicture(picture);
+ uint8_t* data = new uint8_t[picture.size];
+ memcpy(data,picture.data,picture.size);
+ picture.data = data;
+ pictureMap.insert(make_pair(picture,picture_index));
+ }
+
+ uint32_t texture_definition_index = m1;
+ PRCtexturedefinition texturedefinition(picture_index, m);
+ PRCtexturedefinitionMap::const_iterator pTexturedefinition = texturedefinitionMap.find(texturedefinition);
+ if(pTexturedefinition!=texturedefinitionMap.end())
+ texture_definition_index = pTexturedefinition->second;
+ else
+ {
+ PRCTextureDefinition *TextureDefinition = new PRCTextureDefinition;
+ if (m.picture_size==216688 && m.picture_format==KEPRCPicture_JPG)
+ TextureDefinition->texture_mapping_attribute=PRC_TEXTURE_MAPPING_OPACITY;
+ TextureDefinition->picture_index = picture_index;
+ TextureDefinition->texture_function = m.picture_replace ? KEPRCTextureFunction_Replace : KEPRCTextureFunction_Modulate;
+ TextureDefinition->texture_wrapping_mode_S = m.picture_repeat ? KEPRCTextureWrappingMode_Repeat : KEPRCTextureWrappingMode_ClampToEdge;
+ TextureDefinition->texture_wrapping_mode_T = m.picture_repeat ? KEPRCTextureWrappingMode_Repeat : KEPRCTextureWrappingMode_ClampToEdge;
+ TextureDefinition->texture_mapping_attribute_components = (m.picture_format==KEPRCPicture_BITMAP_RGB_BYTE || m.picture_format==KEPRCPicture_JPG) ? PRC_TEXTURE_MAPPING_COMPONENTS_RGB : PRC_TEXTURE_MAPPING_COMPONENTS_RGBA;
+ texture_definition_index = addTextureDefinition(TextureDefinition);
+ texturedefinitionMap.insert(make_pair(texturedefinition,texture_definition_index));
+ }
+
+ uint32_t texture_application_index = m1;
+ const PRCtextureapplication textureapplication(material_index, texture_definition_index);
+ PRCtextureapplicationMap::const_iterator pTextureapplication = textureapplicationMap.find(textureapplication);
+ if(pTextureapplication!=textureapplicationMap.end())
+ texture_application_index = pTextureapplication->second;
+ else
+ {
+ PRCTextureApplication *TextureApplication = new PRCTextureApplication;
+ TextureApplication->material_generic_index = material_index;
+ TextureApplication->texture_definition_index = texture_definition_index;
+ texture_application_index = addTextureApplication(TextureApplication);
+ textureapplicationMap.insert(make_pair(textureapplication,texture_application_index));
+ }
+
+ color_material_index = texture_application_index;
+ }
+ else
+ color_material_index = material_index;
+
+ uint32_t style_index = m1;
+ PRCstyle style(0,m.alpha,true,color_material_index);
+ PRCstyleMap::const_iterator pStyle = styleMap.find(style);
+ if(pStyle!=styleMap.end())
+ style_index = pStyle->second;
+ else
+ {
+ PRCStyle *Style = new PRCStyle();
+ Style->line_width = 0.0;
+ Style->is_vpicture = false;
+ Style->line_pattern_vpicture_index = 0;
+ Style->is_material = true;
+ Style->is_transparency_defined = (m.alpha < 1.0);
+ Style->transparency = (uint8_t)(m.alpha * 256);
+ Style->additional = 0;
+ Style->color_material_index = color_material_index;
+ style_index = addStyle(Style);
+ styleMap.insert(make_pair(style,style_index));
+ }
+// materialMap.insert(make_pair(material,style_index));
+ return style_index;
+}
+
+void oPRCFile::begingroup(const char *name, PRCoptions *options,
+ const double* t)
+{
+ const PRCgroup &parent_group = groups.top();
+ groups.push(PRCgroup());
+ PRCgroup &group = groups.top();
+ group.name=name;
+ if(options) group.options=*options;
+ if(t&&!isid(t))
+ group.transform = new PRCGeneralTransformation3d(t);
+ group.product_occurrence = new PRCProductOccurrence(name);
+ group.parent_product_occurrence = parent_group.product_occurrence;
+ group.part_definition = new PRCPartDefinition;
+ group.parent_part_definition = parent_group.part_definition;
+}
+
+void oPRCFile::endgroup()
+{
+ if(groups.size()<2) {
+ fputs("begingroup without matching endgroup",stderr);
+ exit(1);
+ }
+ doGroup(groups.top());
+ groups.pop();
+
+// std::cout << lastgroupname << std::endl;
+// for(std::vector<std::string>::const_iterator it=lastgroupnames.begin(); it!=lastgroupnames.end(); it++)
+// std::cout << " " << *it << std::endl;
+
+}
+
+PRCgroup& oPRCFile::findGroup()
+{
+ return groups.top();
+}
+
+void oPRCFile::addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w)
+{
+ if(n==0 || P==NULL)
+ return;
+ PRCgroup &group = findGroup();
+ PRCPointSet *pointset = new PRCPointSet();
+ group.pointsets.push_back(pointset);
+ pointset->index_of_line_style = addColourWidth(c,w);
+ pointset->point.reserve(n);
+ for(uint32_t i=0; i<n; i++)
+ pointset->point.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2]));
+}
+
+void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+ PRCgroup &group = findGroup();
+ PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+ polyBrepModel->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale);
+ polyBrepModel->index_tessellation = tess_index;
+ polyBrepModel->is_closed = group.options.closed;
+ polyBrepModel->index_of_line_style = style_index;
+ group.polymodels.push_back(polyBrepModel);
+}
+
+void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double* t)
+{
+ PRCgroup &group = findGroup();
+ PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+ polyBrepModel->index_local_coordinate_system = addTransform(t);
+ polyBrepModel->index_tessellation = tess_index;
+ polyBrepModel->is_closed = group.options.closed;
+ polyBrepModel->index_of_line_style = style_index;
+ group.polymodels.push_back(polyBrepModel);
+}
+
+void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+ PRCgroup &group = findGroup();
+ PRCPolyWire *polyWire = new PRCPolyWire();
+ polyWire->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale);
+ polyWire->index_tessellation = tess_index;
+ polyWire->index_of_line_style = style_index;
+ group.polywires.push_back(polyWire);
+}
+
+void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double* t)
+{
+ PRCgroup &group = findGroup();
+ PRCPolyWire *polyWire = new PRCPolyWire();
+ polyWire->index_local_coordinate_system = addTransform(t);
+ polyWire->index_tessellation = tess_index;
+ polyWire->index_of_line_style = style_index;
+ group.polywires.push_back(polyWire);
+}
+
+void oPRCFile::addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial &m,
+ uint32_t nN, const double N[][3], const uint32_t NI[][4],
+ uint32_t nT, const double T[][2], const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+{
+ if(nP==0 || P==NULL || nI==0 || PI==NULL)
+ return;
+ const uint32_t tess_index = createQuadMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI, ca);
+ useMesh(tess_index,m1);
+}
+
+uint32_t oPRCFile::createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index,
+ uint32_t nN, const double N[][3], const uint32_t NI[][4],
+ uint32_t nT, const double T[][2], const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
+ uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca)
+{
+ if(nP==0 || P==NULL || nI==0 || PI==NULL)
+ return m1;
+
+ const bool triangle_color = (nS != 0 && S != NULL && SI != NULL);
+ const bool vertex_color = (nC != 0 && C != NULL && CI != NULL);
+ const bool has_normals = (nN != 0 && N != NULL && NI != NULL);
+ const bool textured = (nT != 0 && T != NULL && TI != NULL);
+
+ PRC3DTess *tess = new PRC3DTess();
+ PRCTessFace *tessFace = new PRCTessFace();
+ tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle;
+ tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0;
+ tess->coordinates.reserve(3*nP);
+ for(uint32_t i=0; i<nP; i++)
+ {
+ tess->coordinates.push_back(P[i][0]);
+ tess->coordinates.push_back(P[i][1]);
+ tess->coordinates.push_back(P[i][2]);
+ }
+ if(has_normals)
+ {
+ tess->normal_coordinate.reserve(3*nN);
+ for(uint32_t i=0; i<nN; i++)
+ {
+ tess->normal_coordinate.push_back(N[i][0]);
+ tess->normal_coordinate.push_back(N[i][1]);
+ tess->normal_coordinate.push_back(N[i][2]);
+ }
+ }
+ else
+ tess->crease_angle = ca;
+ if(textured)
+ {
+ tess->texture_coordinate.reserve(2*nT);
+ for(uint32_t i=0; i<nT; i++)
+ {
+ tess->texture_coordinate.push_back(T[i][0]);
+ tess->texture_coordinate.push_back(T[i][1]);
+ }
+ }
+ tess->triangulated_index.reserve(2*(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI));
+ for(uint32_t i=0; i<nI; i++)
+ {
+ // first triangle
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][0]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][0]);
+ tess->triangulated_index.push_back(3*PI[i][0]);
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][1]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][1]);
+ tess->triangulated_index.push_back(3*PI[i][1]);
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][3]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][3]);
+ tess->triangulated_index.push_back(3*PI[i][3]);
+ // second triangle
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][1]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][1]);
+ tess->triangulated_index.push_back(3*PI[i][1]);
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][2]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][2]);
+ tess->triangulated_index.push_back(3*PI[i][2]);
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][3]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][3]);
+ tess->triangulated_index.push_back(3*PI[i][3]);
+ }
+ tessFace->sizes_triangulated.push_back(2*nI);
+ if(triangle_color)
+ {
+ tessFace->line_attributes.reserve(2*nI);
+ for(uint32_t i=0; i<nI; i++)
+ {
+ tessFace->line_attributes.push_back(SI[i]);
+ tessFace->line_attributes.push_back(SI[i]);
+ }
+ }
+ else
+ {
+ tessFace->line_attributes.push_back(style_index);
+ }
+ if(vertex_color)
+ {
+ tessFace->is_rgba=false;
+ for(uint32_t i=0; i<nI; i++)
+ if(1.0 != C[CI[i][0]].A || 1.0 != C[CI[i][1]].A || 1.0 != C[CI[i][2]].A)
+ {
+ tessFace->is_rgba=true;
+ break;
+ }
+
+ tessFace->rgba_vertices.reserve(2*(tessFace->is_rgba?4:3)*3*nI);
+ for(uint32_t i=0; i<nI; i++)
+ {
+ // first triangle
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].A));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].A));
+ // second triangle
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].A));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].A));
+ }
+ }
+ tess->addTessFace(tessFace);
+ const uint32_t tess_index = add3DTess(tess);
+ return tess_index;
+}
+
+/*
+void oPRCFile::addTriangle(const double P[][3], const double T[][2], uint32_t style_index)
+{
+ PRCgroup &group = findGroup();
+
+ group.triangles.push_back(PRCtesstriangle());
+ PRCtesstriangle &triangle = group.triangles.back();
+ for(size_t i = 0; i < 3; i++)
+ {
+ triangle.vertices[i].x = P[i][0];
+ triangle.vertices[i].y = P[i][1];
+ triangle.vertices[i].z = P[i][2];
+ triangle.texcoords[i].x = T[i][0];
+ triangle.texcoords[i].y = T[i][1];
+ }
+ triangle.style = style_index;
+}
+*/
+
+void oPRCFile::addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ const RGBAColour& c, double w,
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[])
+{
+ if(nP==0 || P==NULL || nI==0 || PI==NULL)
+ return;
+ const uint32_t tess_index = createLines(nP, P, nI, PI, segment_color, nC, C, nCI, CI);
+ useLines(tess_index, c, w);
+}
+
+uint32_t oPRCFile::createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[])
+{
+ if(nP==0 || P==NULL || nI==0 || PI==NULL)
+ return m1;
+
+ const bool vertex_color = (nC != 0 && C != NULL && CI != NULL);
+
+ PRC3DWireTess *tess = new PRC3DWireTess();
+ tess->coordinates.reserve(3*nP);
+ for(uint32_t i=0; i<nP; i++)
+ {
+ tess->coordinates.push_back(P[i][0]);
+ tess->coordinates.push_back(P[i][1]);
+ tess->coordinates.push_back(P[i][2]);
+ }
+ tess->wire_indexes.reserve(nI);
+ for(uint32_t i=0; i<nI;)
+ {
+ tess->wire_indexes.push_back(PI[i]);
+ const uint32_t ni = i+PI[i]+1;
+ for(i++; i<ni; i++)
+ tess->wire_indexes.push_back(3*PI[i]);
+ }
+ if(vertex_color)
+ {
+ tess->is_segment_color = segment_color;
+ tess->is_rgba=false;
+ for(uint32_t i=0; i<nCI; i++)
+ if(1.0 != C[CI[i]].A)
+ {
+ tess->is_rgba=true;
+ break;
+ }
+ tess->rgba_vertices.reserve((tess->is_rgba?4:3)*nCI);
+ for(uint32_t i=0; i<nCI; i++)
+ {
+ tess->rgba_vertices.push_back(byte(C[CI[i]].R));
+ tess->rgba_vertices.push_back(byte(C[CI[i]].G));
+ tess->rgba_vertices.push_back(byte(C[CI[i]].B));
+ if(tess->is_rgba)
+ tess->rgba_vertices.push_back(byte(C[CI[i]].A));
+ }
+ }
+ const uint32_t tess_index = add3DWireTess(tess);
+ return tess_index;
+}
+
+#define PRCFACETRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale, const double* t
+
+void oPRCFile::addHemisphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCSphere)
+ SETTRANSF
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = 0;
+ surface->uv_domain.max.y = 0.5*pi;
+ surface->radius = radius;
+}
+
+void oPRCFile::addSphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCSphere)
+ SETTRANSF
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y =-0.5*pi;
+ surface->uv_domain.max.y = 0.5*pi;
+ surface->radius = radius;
+}
+
+void oPRCFile::addDisk(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCRuled)
+ SETTRANSF
+ PRCCircle *first_curve = new PRCCircle;
+ first_curve->radius = radius;
+ surface->first_curve = first_curve;
+ PRCCircle *second_curve = new PRCCircle;
+ second_curve->radius = 0;
+ surface->second_curve = second_curve;
+
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 1;
+ surface->uv_domain.min.y = 0;
+ surface->uv_domain.max.y = 2*pi;
+ surface->parameterization_on_v_coeff_a = -1;
+ surface->parameterization_on_v_coeff_b = 2*pi;
+}
+
+void oPRCFile::addCylinder(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCCylinder)
+ SETTRANSF
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = (height>0)?0:height;
+ surface->uv_domain.max.y = (height>0)?height:0;
+ surface->radius = radius;
+}
+
+void oPRCFile::addCone(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCCone)
+ SETTRANSF
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = (height>0)?0:height;
+ surface->uv_domain.max.y = (height>0)?height:0;
+ surface->bottom_radius = radius;
+ surface->semi_angle = -atan(radius/height);;
+}
+
+void oPRCFile::addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCTorus)
+ SETTRANSF
+ surface->uv_domain.min.x = (angle1/180)*pi;
+ surface->uv_domain.max.x = (angle2/180)*pi;
+ surface->uv_domain.min.y = 0;
+ surface->uv_domain.max.y = 2*pi;
+ surface->major_radius = major_radius;
+ surface->minor_radius = minor_radius;
+}
+
+#undef ADDWIRE
+#undef SETTRANSF
+
+uint32_t PRCFileStructure::addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric)
+{
+ materials.push_back(pMaterialGeneric);
+ pMaterialGeneric = NULL;
+ return materials.size()-1;
+}
+
+uint32_t PRCFileStructure::addTextureApplication(PRCTextureApplication*& pTextureApplication)
+{
+ materials.push_back(pTextureApplication);
+ pTextureApplication = NULL;
+ return materials.size()-1;
+}
+
+uint32_t PRCFileStructure::addStyle(PRCStyle*& pStyle)
+{
+ styles.push_back(pStyle);
+ pStyle = NULL;
+ return styles.size()-1;
+}
+
+uint32_t PRCFileStructure::addPartDefinition(PRCPartDefinition*& pPartDefinition)
+{
+ part_definitions.push_back(pPartDefinition);
+ pPartDefinition = NULL;
+ return part_definitions.size()-1;
+}
+
+uint32_t PRCFileStructure::addProductOccurrence(PRCProductOccurrence*& pProductOccurrence)
+{
+ product_occurrences.push_back(pProductOccurrence);
+ pProductOccurrence = NULL;
+ return product_occurrences.size()-1;
+}
+
+uint32_t PRCFileStructure::addTopoContext(PRCTopoContext*& pTopoContext)
+{
+ contexts.push_back(pTopoContext);
+ pTopoContext = NULL;
+ return contexts.size()-1;
+}
+
+uint32_t PRCFileStructure::getTopoContext(PRCTopoContext*& pTopoContext)
+{
+ pTopoContext = new PRCTopoContext;
+ contexts.push_back(pTopoContext);
+ return contexts.size()-1;
+}
+
+uint32_t PRCFileStructure::add3DTess(PRC3DTess*& p3DTess)
+{
+ tessellations.push_back(p3DTess);
+ p3DTess = NULL;
+ return tessellations.size()-1;
+}
+
+uint32_t PRCFileStructure::add3DWireTess(PRC3DWireTess*& p3DWireTess)
+{
+ tessellations.push_back(p3DWireTess);
+ p3DWireTess = NULL;
+ return tessellations.size()-1;
+}
+/*
+uint32_t PRCFileStructure::addMarkupTess(PRCMarkupTess*& pMarkupTess)
+{
+ tessellations.push_back(pMarkupTess);
+ pMarkupTess = NULL;
+ return tessellations.size()-1;
+}
+
+uint32_t PRCFileStructure::addMarkup(PRCMarkup*& pMarkup)
+{
+ markups.push_back(pMarkup);
+ pMarkup = NULL;
+ return markups.size()-1;
+}
+
+uint32_t PRCFileStructure::addAnnotationItem(PRCAnnotationItem*& pAnnotationItem)
+{
+ annotation_entities.push_back(pAnnotationItem);
+ pAnnotationItem = NULL;
+ return annotation_entities.size()-1;
+}
+*/
+uint32_t PRCFileStructure::addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem)
+{
+ reference_coordinate_systems.push_back(pCoordinateSystem);
+ pCoordinateSystem = NULL;
+ return reference_coordinate_systems.size()-1;
+}
+
+uint32_t PRCFileStructure::addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem)
+{
+ for(uint32_t i = 0; i < reference_coordinate_systems.size(); ++i)
+ {
+ if(*(reference_coordinate_systems[i])==*pCoordinateSystem) {
+ pCoordinateSystem = NULL;
+ return i;
+ }
+ }
+ reference_coordinate_systems.push_back(pCoordinateSystem);
+ pCoordinateSystem = NULL;
+ return reference_coordinate_systems.size()-1;
+}
+
+}
diff --git a/graphics/asymptote/prc/oPRCFile.h b/graphics/asymptote/prc/oPRCFile.h
new file mode 100644
index 0000000000..d0bbdc1ea6
--- /dev/null
+++ b/graphics/asymptote/prc/oPRCFile.h
@@ -0,0 +1,1364 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com> and
+* Michail Vidiassov <master@iaas.msu.ru>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __O_PRC_FILE_H
+#define __O_PRC_FILE_H
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <map>
+#include <set>
+#include <list>
+#include <stack>
+#include <string>
+#include <cstring>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "PRC.h"
+#include "PRCbitStream.h"
+#include "writePRC.h"
+
+namespace prc {
+
+class oPRCFile;
+class PRCFileStructure;
+
+// Map [0,1] to [0,255]
+inline uint8_t byte(double r)
+{
+ if(r < 0.0) r=0.0;
+ else if(r > 1.0) r=1.0;
+ int a=(int)(256.0*r);
+ if(a == 256) a=255;
+ return a;
+}
+
+struct RGBAColour
+{
+ RGBAColour(double r=0.0, double g=0.0, double b=0.0, double a=1.0) :
+ R(r), G(g), B(b), A(a) {}
+ double R,G,B,A;
+
+ void Set(double r, double g, double b, double a=1.0)
+ {
+ R = r; G = g; B = b; A = a;
+ }
+ bool operator==(const RGBAColour &c) const
+ {
+ return (R==c.R && G==c.G && B==c.B && A==c.A);
+ }
+ bool operator!=(const RGBAColour &c) const
+ {
+ return !(R==c.R && G==c.G && B==c.B && A==c.A);
+ }
+ bool operator<(const RGBAColour &c) const
+ {
+ if(R!=c.R)
+ return (R<c.R);
+ if(G!=c.G)
+ return (G<c.G);
+ if(B!=c.B)
+ return (B<c.B);
+ return (A<c.A);
+ }
+ friend RGBAColour operator * (const RGBAColour& a, const double d)
+ { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
+ friend RGBAColour operator * (const double d, const RGBAColour& a)
+ { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
+
+};
+typedef std::map<RGBAColour,uint32_t> PRCcolourMap;
+
+struct RGBAColourWidth
+{
+ RGBAColourWidth(double r=0.0, double g=0.0, double b=0.0, double a=1.0, double w=1.0) :
+ R(r), G(g), B(b), A(a), W(w) {}
+ double R,G,B,A,W;
+
+ bool operator==(const RGBAColourWidth &c) const
+ {
+ return (R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
+ }
+ bool operator!=(const RGBAColourWidth &c) const
+ {
+ return !(R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
+ }
+ bool operator<(const RGBAColourWidth &c) const
+ {
+ if(R!=c.R)
+ return (R<c.R);
+ if(G!=c.G)
+ return (G<c.G);
+ if(B!=c.B)
+ return (B<c.B);
+ if(A!=c.A)
+ return (A<c.A);
+ return (W<c.W);
+ }
+};
+typedef std::map<RGBAColourWidth,uint32_t> PRCcolourwidthMap;
+
+typedef std::map<PRCRgbColor,uint32_t> PRCcolorMap;
+
+struct PRCmaterial
+{
+ PRCmaterial() : alpha(1.0),shininess(1.0),
+ picture_data(NULL), picture_format(KEPRCPicture_BITMAP_RGB_BYTE), picture_width(0), picture_height(0), picture_size(0),
+ picture_replace(false), picture_repeat(false) {}
+ PRCmaterial(const RGBAColour &a, const RGBAColour &d, const RGBAColour &e,
+ const RGBAColour &s, double p, double h,
+ const uint8_t* pic=NULL, EPRCPictureDataFormat picf=KEPRCPicture_BITMAP_RGB_BYTE,
+ uint32_t picw=0, uint32_t pich=0, uint32_t pics=0, bool picreplace=false, bool picrepeat=false) :
+ ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h),
+ picture_data(pic), picture_format(picf), picture_width(picw), picture_height(pich), picture_size(pics),
+ picture_replace(picreplace), picture_repeat(picrepeat) {
+ if(picture_size==0)
+ {
+ if (picture_format==KEPRCPicture_BITMAP_RGB_BYTE)
+ picture_size = picture_width*picture_height*3;
+ if (picture_format==KEPRCPicture_BITMAP_RGBA_BYTE)
+ picture_size = picture_width*picture_height*4;
+ if (picture_format==KEPRCPicture_BITMAP_GREY_BYTE)
+ picture_size = picture_width*picture_height*1;
+ if (picture_format==KEPRCPicture_BITMAP_GREYA_BYTE)
+ picture_size = picture_width*picture_height*2;
+ }
+ }
+ RGBAColour ambient,diffuse,emissive,specular;
+ double alpha,shininess;
+ const uint8_t* picture_data;
+ EPRCPictureDataFormat picture_format;
+ uint32_t picture_width;
+ uint32_t picture_height;
+ uint32_t picture_size;
+ bool picture_replace; // replace material color with texture color? if false - just modify
+ bool picture_repeat; // repeat texture? if false - clamp to edge
+
+ bool operator==(const PRCmaterial &m) const
+ {
+ return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
+ && specular==m.specular && alpha==m.alpha && shininess==m.shininess
+ && picture_replace==m.picture_replace && picture_repeat==m.picture_repeat
+ && picture_format==m.picture_format
+ && picture_width==m.picture_width && picture_height==m.picture_height && picture_size==m.picture_size
+ && (picture_data==m.picture_data || memcmp(picture_data,m.picture_data,picture_size)==0) );
+ }
+ bool operator<(const PRCmaterial &m) const
+ {
+ if(ambient!=m.ambient)
+ return (ambient<m.ambient);
+ if(diffuse!=m.diffuse)
+ return (diffuse<m.diffuse);
+ if(emissive!=m.emissive)
+ return (emissive<m.emissive);
+ if(specular!=m.specular)
+ return (specular<m.specular);
+ if(alpha!=m.alpha)
+ return (alpha<m.alpha);
+ if(shininess!=m.shininess)
+ return (shininess<m.shininess);
+ if(picture_replace!=m.picture_replace)
+ return (picture_replace<m.picture_replace);
+ if(picture_repeat!=m.picture_repeat)
+ return (picture_repeat<m.picture_repeat);
+ if(picture_format!=m.picture_format)
+ return (picture_format<m.picture_format);
+ if(picture_width!=m.picture_width)
+ return (picture_width<m.picture_width);
+ if(picture_height!=m.picture_height)
+ return (picture_height<m.picture_height);
+ if(picture_size!=m.picture_size)
+ return (picture_size<m.picture_size);
+ if(picture_data!=m.picture_data)
+ return (memcmp(picture_data,m.picture_data,picture_size)<0);
+ return false;
+ }
+};
+typedef std::map<PRCmaterial,uint32_t> PRCmaterialMap;
+
+struct PRCpicture
+{
+ PRCpicture() :
+ data(NULL), format(KEPRCPicture_BITMAP_RGB_BYTE),
+ width(0), height(0), size(0) {}
+ PRCpicture(const uint8_t* pic, EPRCPictureDataFormat picf,
+ uint32_t picw, uint32_t pich, uint32_t pics=0) :
+ data(pic), format(picf),
+ width(picw), height(pich), size(pics)
+ {
+ if(size==0)
+ {
+ if (format==KEPRCPicture_BITMAP_RGB_BYTE)
+ size = width*height*3;
+ if (format==KEPRCPicture_BITMAP_RGBA_BYTE)
+ size = width*height*4;
+ if (format==KEPRCPicture_BITMAP_GREY_BYTE)
+ size = width*height*1;
+ if (format==KEPRCPicture_BITMAP_GREYA_BYTE)
+ size = width*height*2;
+ }
+ }
+ PRCpicture(const PRCmaterial& m) :
+ data(m.picture_data), format(m.picture_format),
+ width(m.picture_width), height(m.picture_height), size(m.picture_size) {}
+
+ const uint8_t* data;
+ EPRCPictureDataFormat format;
+ uint32_t width;
+ uint32_t height;
+ uint32_t size;
+ bool operator==(const PRCpicture& p) const
+ {
+ return ( format==p.format
+ && width==p.width && height==p.height && size==p.size
+ && (data==p.data || memcmp(data,p.data,size)==0) );
+ }
+ bool operator<(const PRCpicture& p) const
+ {
+ if(format!=p.format)
+ return (format<p.format);
+ if(width!=p.width)
+ return (width<p.width);
+ if(height!=p.height)
+ return (height<p.height);
+ if(size!=p.size)
+ return (size<p.size);
+ if(data!=p.data)
+ return (memcmp(data,p.data,size)<0);
+ return false;
+ }
+};
+
+typedef std::map<PRCpicture,uint32_t> PRCpictureMap;
+
+struct PRCmaterialgeneric
+{
+ PRCmaterialgeneric() : alpha(1.0),shininess(1.0) {}
+ PRCmaterialgeneric(const RGBAColour& a, const RGBAColour& d, const RGBAColour& e,
+ const RGBAColour& s, double p, double h) :
+ ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h) {}
+ PRCmaterialgeneric(const PRCmaterial& m) :
+ ambient(m.ambient), diffuse(m.diffuse), emissive(m.emissive), specular(m.specular), alpha(m.alpha), shininess(m.shininess) {}
+ RGBAColour ambient,diffuse,emissive,specular;
+ double alpha,shininess;
+
+ bool operator==(const PRCmaterialgeneric& m) const
+ {
+ return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
+ && specular==m.specular && alpha==m.alpha && shininess==m.shininess);
+ }
+ bool operator<(const PRCmaterialgeneric& m) const
+ {
+ if(ambient!=m.ambient)
+ return (ambient<m.ambient);
+ if(diffuse!=m.diffuse)
+ return (diffuse<m.diffuse);
+ if(emissive!=m.emissive)
+ return (emissive<m.emissive);
+ if(specular!=m.specular)
+ return (specular<m.specular);
+ if(alpha!=m.alpha)
+ return (alpha<m.alpha);
+ if(shininess!=m.shininess)
+ return (shininess<m.shininess);
+ return false;
+ }
+};
+typedef std::map<PRCmaterialgeneric,uint32_t> PRCmaterialgenericMap;
+
+struct PRCtexturedefinition
+{
+ PRCtexturedefinition() :
+ picture_index(m1), picture_replace(false), picture_repeat(false) {}
+ PRCtexturedefinition(uint32_t picindex, bool picreplace=false, bool picrepeat=false) :
+ picture_index(picindex), picture_replace(picreplace), picture_repeat(picrepeat) {}
+ PRCtexturedefinition(uint32_t picindex, const PRCmaterial& m) :
+ picture_index(picindex), picture_replace(m.picture_replace), picture_repeat(m.picture_repeat) {}
+ uint32_t picture_index;
+ bool picture_replace; // replace material color with texture color? if false - just modify
+ bool picture_repeat; // repeat texture? if false - clamp to edge
+
+ bool operator==(const PRCtexturedefinition& t) const
+ {
+ return (picture_index==t.picture_index
+ && picture_replace==t.picture_replace && picture_repeat==t.picture_repeat);
+ }
+ bool operator<(const PRCtexturedefinition& t) const
+ {
+ if(picture_index!=t.picture_index)
+ return (picture_index<t.picture_index);
+ if(picture_replace!=t.picture_replace)
+ return (picture_replace<t.picture_replace);
+ if(picture_repeat!=t.picture_repeat)
+ return (picture_repeat<t.picture_repeat);
+ return false;
+ }
+};
+typedef std::map<PRCtexturedefinition,uint32_t> PRCtexturedefinitionMap;
+
+struct PRCtextureapplication
+{
+ PRCtextureapplication() :
+ material_generic_index(m1), texture_definition_index(m1) {}
+ PRCtextureapplication(uint32_t matindex, uint32_t texindex) :
+ material_generic_index(matindex), texture_definition_index(texindex) {}
+ uint32_t material_generic_index;
+ uint32_t texture_definition_index;
+
+ bool operator==(const PRCtextureapplication& t) const
+ {
+ return (material_generic_index==t.material_generic_index
+ && texture_definition_index==t.texture_definition_index);
+ }
+ bool operator<(const PRCtextureapplication& t) const
+ {
+ if(material_generic_index!=t.material_generic_index)
+ return (material_generic_index<t.material_generic_index);
+ if(texture_definition_index!=t.texture_definition_index)
+ return (texture_definition_index<t.texture_definition_index);
+ return false;
+ }
+};
+typedef std::map<PRCtextureapplication,uint32_t> PRCtextureapplicationMap;
+
+struct PRCstyle
+{
+ PRCstyle() :
+ line_width(0), alpha(1), is_material(false), color_material_index(m1) {}
+ PRCstyle(double linewidth, double alph, bool ismat, uint32_t colindex=m1) :
+ line_width(linewidth), alpha(alph), is_material(ismat), color_material_index(colindex) {}
+ double line_width;
+ double alpha;
+ bool is_material;
+ uint32_t color_material_index;
+
+ bool operator==(const PRCstyle& s) const
+ {
+ return (line_width==s.line_width && alpha==s.alpha && is_material==s.is_material
+ && color_material_index==s.color_material_index);
+ }
+ bool operator<(const PRCstyle& s) const
+ {
+ if(line_width!=s.line_width)
+ return (line_width<s.line_width);
+ if(alpha!=s.alpha)
+ return (alpha<s.alpha);
+ if(is_material!=s.is_material)
+ return (is_material<s.is_material);
+ if(color_material_index!=s.color_material_index)
+ return (color_material_index<s.color_material_index);
+ return false;
+ }
+};
+typedef std::map<PRCstyle,uint32_t> PRCstyleMap;
+
+struct PRCtessrectangle // rectangle
+{
+ PRCVector3d vertices[4];
+ uint32_t style;
+};
+typedef std::vector<PRCtessrectangle> PRCtessrectangleList;
+
+struct PRCtessquad // rectangle
+{
+ PRCVector3d vertices[4];
+ RGBAColour colours[4];
+};
+typedef std::vector<PRCtessquad> PRCtessquadList;
+/*
+struct PRCtesstriangle // textured triangle
+{
+ PRCtesstriangle() :
+ style(m1) {}
+ PRCVector3d vertices[3];
+// PRCVector3d normals[3];
+// RGBAColour colors[3];
+ PRCVector2d texcoords[3];
+ uint32_t style;
+};
+typedef std::vector<PRCtesstriangle> PRCtesstriangleList;
+*/
+struct PRCtessline // polyline
+{
+ std::vector<PRCVector3d> point;
+ PRCRgbColor color;
+};
+typedef std::list<PRCtessline> PRCtesslineList;
+typedef std::map<double, PRCtesslineList> PRCtesslineMap;
+
+struct PRCface
+{
+ PRCface() : transform(NULL), face(NULL) {}
+ uint32_t style;
+ bool transparent;
+ PRCGeneralTransformation3d* transform;
+ PRCFace* face;
+};
+typedef std::vector <PRCface> PRCfaceList;
+
+struct PRCcompface
+{
+ PRCcompface() : face(NULL) {}
+ uint32_t style;
+ bool transparent;
+ PRCCompressedFace* face;
+};
+typedef std::vector <PRCcompface> PRCcompfaceList;
+
+struct PRCwire
+{
+ PRCwire() : style(m1), transform(NULL), curve(NULL) {}
+ uint32_t style;
+ PRCGeneralTransformation3d* transform;
+ PRCCurve* curve;
+};
+typedef std::vector <PRCwire> PRCwireList;
+
+typedef std::map <uint32_t,std::vector<PRCVector3d> > PRCpointsetMap;
+
+class PRCoptions
+{
+public:
+ double compression;
+ double granularity;
+
+ bool closed; // render the surface as one-sided; may yield faster rendering
+ bool tess; // use tessellated mesh to store straight patches
+ bool do_break; //
+ bool no_break; // do not render transparent patches as one-faced nodes
+ double crease_angle; // crease angle for meshes
+
+ PRCoptions(double compression=0.0, double granularity=0.0, bool closed=false,
+ bool tess=false, bool do_break=true, bool no_break=false, double crease_angle=25.8419)
+ : compression(compression), granularity(granularity), closed(closed),
+ tess(tess), do_break(do_break), no_break(no_break), crease_angle(crease_angle) {}
+};
+
+class PRCgroup
+{
+ public:
+ PRCgroup() :
+ product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL) {}
+ PRCgroup(const std::string& name) :
+ product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL), name(name) {}
+ PRCProductOccurrence *product_occurrence, *parent_product_occurrence;
+ PRCPartDefinition *part_definition, *parent_part_definition;
+ PRCfaceList faces;
+ PRCcompfaceList compfaces;
+ PRCtessrectangleList rectangles;
+// PRCtesstriangleList triangles;
+ PRCtessquadList quads;
+ PRCtesslineMap lines;
+ PRCwireList wires;
+ PRCpointsetMap points;
+ std::vector<PRCPointSet*> pointsets;
+ std::vector<PRCPolyBrepModel*> polymodels;
+ std::vector<PRCPolyWire*> polywires;
+ PRCGeneralTransformation3d* transform;
+ std::string name;
+ PRCoptions options;
+};
+
+void makeFileUUID(PRCUniqueId&);
+void makeAppUUID(PRCUniqueId&);
+
+class PRCUncompressedFile
+{
+ public:
+ PRCUncompressedFile() : file_size(0), data(NULL) {}
+ PRCUncompressedFile(uint32_t fs, uint8_t *d) : file_size(fs), data(d) {}
+ ~PRCUncompressedFile() { if(data != NULL) delete[] data; }
+ uint32_t file_size;
+ uint8_t *data;
+
+ void write(std::ostream&) const;
+
+ uint32_t getSize() const;
+};
+typedef std::deque <PRCUncompressedFile*> PRCUncompressedFileList;
+
+class PRCStartHeader
+{
+ public:
+ uint32_t minimal_version_for_read; // PRCVersion
+ uint32_t authoring_version; // PRCVersion
+ PRCUniqueId file_structure_uuid;
+ PRCUniqueId application_uuid; // should be 0
+
+ PRCStartHeader() :
+ minimal_version_for_read(PRCVersion), authoring_version(PRCVersion) {}
+ void serializeStartHeader(std::ostream&) const;
+
+ uint32_t getStartHeaderSize() const;
+};
+
+class PRCFileStructure : public PRCStartHeader
+{
+ public:
+ uint32_t number_of_referenced_file_structures;
+ double tessellation_chord_height_ratio;
+ double tessellation_angle_degree;
+ std::string default_font_family_name;
+ std::vector<PRCRgbColor> colors;
+ std::vector<PRCPicture> pictures;
+ PRCUncompressedFileList uncompressed_files;
+ PRCTextureDefinitionList texture_definitions;
+ PRCMaterialList materials;
+ PRCStyleList styles;
+ PRCCoordinateSystemList reference_coordinate_systems;
+ std::vector<PRCFontKeysSameFont> font_keys_of_font;
+ PRCPartDefinitionList part_definitions;
+ PRCProductOccurrenceList product_occurrences;
+// PRCMarkupList markups;
+// PRCAnnotationItemList annotation_entities;
+ double unit;
+ PRCTopoContextList contexts;
+ PRCTessList tessellations;
+
+ uint32_t sizes[6];
+ uint8_t *globals_data;
+ PRCbitStream globals_out; // order matters: PRCbitStream must be initialized last
+ uint8_t *tree_data;
+ PRCbitStream tree_out;
+ uint8_t *tessellations_data;
+ PRCbitStream tessellations_out;
+ uint8_t *geometry_data;
+ PRCbitStream geometry_out;
+ uint8_t *extraGeometry_data;
+ PRCbitStream extraGeometry_out;
+
+ ~PRCFileStructure () {
+ for(PRCUncompressedFileList::iterator it=uncompressed_files.begin(); it!=uncompressed_files.end(); ++it) delete *it;
+ for(PRCTextureDefinitionList::iterator it=texture_definitions.begin(); it!=texture_definitions.end(); ++it) delete *it;
+ for(PRCMaterialList::iterator it=materials.begin(); it!=materials.end(); ++it) delete *it;
+ for(PRCStyleList::iterator it=styles.begin(); it!=styles.end(); ++it) delete *it;
+ for(PRCTopoContextList::iterator it=contexts.begin(); it!=contexts.end(); ++it) delete *it;
+ for(PRCTessList::iterator it=tessellations.begin(); it!=tessellations.end(); ++it) delete *it;
+ for(PRCPartDefinitionList::iterator it=part_definitions.begin(); it!=part_definitions.end(); ++it) delete *it;
+ for(PRCProductOccurrenceList::iterator it=product_occurrences.begin(); it!=product_occurrences.end(); ++it) delete *it;
+ for(PRCCoordinateSystemList::iterator it=reference_coordinate_systems.begin(); it!=reference_coordinate_systems.end(); it++)
+ delete *it;
+
+ free(globals_data);
+ free(tree_data);
+ free(tessellations_data);
+ free(geometry_data);
+ free(extraGeometry_data);
+ }
+
+ PRCFileStructure() :
+ number_of_referenced_file_structures(0),
+ tessellation_chord_height_ratio(2000.0),tessellation_angle_degree(40.0),
+ default_font_family_name(""),
+ unit(1),
+ globals_data(NULL),globals_out(globals_data,0),
+ tree_data(NULL),tree_out(tree_data,0),
+ tessellations_data(NULL),tessellations_out(tessellations_data,0),
+ geometry_data(NULL),geometry_out(geometry_data,0),
+ extraGeometry_data(NULL),extraGeometry_out(extraGeometry_data,0) {}
+ void write(std::ostream&);
+ void prepare();
+ uint32_t getSize();
+ void serializeFileStructureGlobals(PRCbitStream&);
+ void serializeFileStructureTree(PRCbitStream&);
+ void serializeFileStructureTessellation(PRCbitStream&);
+ void serializeFileStructureGeometry(PRCbitStream&);
+ void serializeFileStructureExtraGeometry(PRCbitStream&);
+ uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *picture, uint32_t width=0, uint32_t height=0, std::string name="");
+ uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition);
+ uint32_t addRgbColor(const PRCRgbColor &color);
+ uint32_t addRgbColorUnique(const PRCRgbColor &color);
+ uint32_t addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric);
+ uint32_t addTextureApplication(PRCTextureApplication*& pTextureApplication);
+ uint32_t addStyle(PRCStyle*& pStyle);
+ uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition);
+ uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence);
+ uint32_t addTopoContext(PRCTopoContext*& pTopoContext);
+ uint32_t getTopoContext(PRCTopoContext*& pTopoContext);
+ uint32_t add3DTess(PRC3DTess*& p3DTess);
+ uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess);
+/*
+ uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess);
+ uint32_t addMarkup(PRCMarkup*& pMarkup);
+ uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem);
+ */
+ uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem);
+ uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem);
+};
+
+class PRCFileStructureInformation
+{
+ public:
+ PRCUniqueId UUID;
+ uint32_t reserved; // 0
+ uint32_t number_of_offsets;
+ uint32_t *offsets;
+
+ void write(std::ostream&);
+
+ uint32_t getSize();
+};
+
+class PRCHeader : public PRCStartHeader
+{
+ public :
+ uint32_t number_of_file_structures;
+ PRCFileStructureInformation *fileStructureInformation;
+ uint32_t model_file_offset;
+ uint32_t file_size; // not documented
+ PRCUncompressedFileList uncompressed_files;
+
+ void write(std::ostream&);
+ uint32_t getSize();
+};
+
+typedef std::map <PRCGeneralTransformation3d,uint32_t> PRCtransformMap;
+
+inline double X(const double *v) {return v[0];}
+inline double Y(const double *v) {return v[1];}
+inline double Z(const double *v) {return v[2];}
+
+class oPRCFile
+{
+ public:
+ oPRCFile(std::ostream &os, double u=1, uint32_t n=1) :
+ number_of_file_structures(n),
+ fileStructures(new PRCFileStructure*[n]),
+ unit(u),
+ modelFile_data(NULL),modelFile_out(modelFile_data,0),
+ fout(NULL),output(os)
+ {
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ fileStructures[i] = new PRCFileStructure();
+ fileStructures[i]->minimal_version_for_read = PRCVersion;
+ fileStructures[i]->authoring_version = PRCVersion;
+ makeFileUUID(fileStructures[i]->file_structure_uuid);
+ makeAppUUID(fileStructures[i]->application_uuid);
+ fileStructures[i]->unit = u;
+ }
+
+ groups.push(PRCgroup());
+ PRCgroup &group = groups.top();
+ group.name="root";
+ group.transform = NULL;
+ group.product_occurrence = new PRCProductOccurrence(group.name);
+ group.parent_product_occurrence = NULL;
+ group.part_definition = new PRCPartDefinition;
+ group.parent_part_definition = NULL;
+ }
+
+ oPRCFile(const std::string &name, double u=1, uint32_t n=1) :
+ number_of_file_structures(n),
+ fileStructures(new PRCFileStructure*[n]),
+ unit(u),
+ modelFile_data(NULL),modelFile_out(modelFile_data,0),
+ fout(new std::ofstream(name.c_str(),
+ std::ios::out|std::ios::binary|std::ios::trunc)),
+ output(*fout)
+ {
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ fileStructures[i] = new PRCFileStructure();
+ fileStructures[i]->minimal_version_for_read = PRCVersion;
+ fileStructures[i]->authoring_version = PRCVersion;
+ makeFileUUID(fileStructures[i]->file_structure_uuid);
+ makeAppUUID(fileStructures[i]->application_uuid);
+ fileStructures[i]->unit = u;
+ }
+
+ groups.push(PRCgroup());
+ PRCgroup &group = groups.top();
+ group.name="root";
+ group.transform = NULL;
+ group.product_occurrence = new PRCProductOccurrence(group.name);
+ group.parent_product_occurrence = NULL;
+ group.part_definition = new PRCPartDefinition;
+ group.parent_part_definition = NULL;
+ }
+
+ ~oPRCFile()
+ {
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ delete fileStructures[i];
+ delete[] fileStructures;
+ if(fout != NULL)
+ delete fout;
+ free(modelFile_data);
+ for(PRCpictureMap::iterator it=pictureMap.begin(); it!=pictureMap.end(); ++it) delete it->first.data;
+ }
+
+ void begingroup(const char *name, PRCoptions *options=NULL,
+ const double* t=NULL);
+ void endgroup();
+
+ std::string lastgroupname;
+ std::vector<std::string> lastgroupnames;
+ std::string calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence);
+
+ bool finish();
+ uint32_t getSize();
+
+ const uint32_t number_of_file_structures;
+ PRCFileStructure **fileStructures;
+ PRCHeader header;
+ PRCUnit unit;
+ uint8_t *modelFile_data;
+ PRCbitStream modelFile_out; // order matters: PRCbitStream must be initialized last
+ PRCcolorMap colorMap;
+ PRCcolourMap colourMap;
+ PRCcolourwidthMap colourwidthMap;
+ PRCmaterialgenericMap materialgenericMap;
+ PRCtexturedefinitionMap texturedefinitionMap;
+ PRCtextureapplicationMap textureapplicationMap;
+ PRCstyleMap styleMap;
+ PRCpictureMap pictureMap;
+ PRCgroup rootGroup;
+ PRCtransformMap transformMap;
+ std::stack<PRCgroup> groups;
+ PRCgroup& findGroup();
+ void doGroup(PRCgroup& group);
+ uint32_t addColor(const PRCRgbColor &color);
+ uint32_t addColour(const RGBAColour &colour);
+ uint32_t addColourWidth(const RGBAColour &colour, double width);
+ uint32_t addLineMaterial(const RGBAColour& c, double width)
+ { return addColourWidth(c,width); }
+ uint32_t addMaterial(const PRCmaterial &material);
+ uint32_t addTransform(PRCGeneralTransformation3d*& transform);
+ uint32_t addTransform(const double* t);
+ uint32_t addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale);
+template<class V>
+void addPoint(const V P, const RGBAColour &c, double w=1.0)
+{
+ PRCgroup &group = findGroup();
+ group.points[addColourWidth(c,w)].push_back(PRCVector3d(X(P),Y(P),Z(P)));
+}
+ void addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w=1.0);
+ void addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ const RGBAColour& c, double w,
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
+ uint32_t createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
+template<class V>
+ void addTriangles(uint32_t nP, const V P[], uint32_t nI, const uint32_t PI[][3], const PRCmaterial &m,
+ uint32_t nN, const V N[], const uint32_t NI[][3],
+ uint32_t nT, const double T[][2], const uint32_t TI[][3],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+{
+ if(nP==0 || P==NULL || nI==0 || PI==NULL)
+ return;
+ const uint32_t tess_index = createTriangleMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI, ca);
+ useMesh(tess_index,m1);
+}
+template<class V>
+ uint32_t createTriangleMesh(uint32_t nP, const V P[], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m,
+ uint32_t nN, const V N[], const uint32_t NI[][3],
+ uint32_t nT, const double T[][2], const uint32_t TI[][3],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+ {
+ const uint32_t style = addMaterial(m);
+ if(M!=NULL && nM>0)
+ {
+ uint32_t* const styles = new uint32_t[nM];
+ for(uint32_t i=0; i<nM; i++)
+ styles[i]=addMaterial(M[i]);
+ const uint32_t meshid = createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI, ca);
+ delete[] styles;
+ return meshid;
+ }
+ else
+ return createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL, ca);
+ }
+
+template<class V>
+uint32_t createTriangleMesh(uint32_t nP, const V P[], uint32_t nI, const uint32_t PI[][3], const uint32_t style_index,
+uint32_t nN, const V N[], const uint32_t NI[][3],
+ uint32_t nT, const double T[][2], const uint32_t TI[][3],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
+ uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca)
+{
+ if(nP==0 || P==NULL || nI==0 || PI==NULL)
+ return m1;
+
+ const bool triangle_color = (nS != 0 && S != NULL && SI != NULL);
+ const bool vertex_color = (nC != 0 && C != NULL && CI != NULL);
+ const bool has_normals = (nN != 0 && N != NULL && NI != NULL);
+ const bool textured = (nT != 0 && T != NULL && TI != NULL);
+
+ PRC3DTess *tess = new PRC3DTess();
+ PRCTessFace *tessFace = new PRCTessFace();
+ tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle;
+ tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0;
+ tess->coordinates.reserve(3*nP);
+ for(uint32_t i=0; i<nP; i++)
+ {
+ tess->coordinates.push_back(X(P[i]));
+ tess->coordinates.push_back(Y(P[i]));
+ tess->coordinates.push_back(Z(P[i]));
+ }
+ if(has_normals)
+ {
+ tess->normal_coordinate.reserve(3*nN);
+ for(uint32_t i=0; i<nN; i++)
+ {
+ tess->normal_coordinate.push_back(X(N[i]));
+ tess->normal_coordinate.push_back(Y(N[i]));
+ tess->normal_coordinate.push_back(Z(N[i]));
+ }
+ }
+ else
+ tess->crease_angle = ca;
+ if(textured)
+ {
+ tess->texture_coordinate.reserve(2*nT);
+ for(uint32_t i=0; i<nT; i++)
+ {
+ tess->texture_coordinate.push_back(T[i][0]);
+ tess->texture_coordinate.push_back(T[i][1]);
+ }
+ }
+ tess->triangulated_index.reserve(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI);
+ for(uint32_t i=0; i<nI; i++)
+ {
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][0]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][0]);
+ tess->triangulated_index.push_back(3*PI[i][0]);
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][1]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][1]);
+ tess->triangulated_index.push_back(3*PI[i][1]);
+ if(has_normals)
+ tess->triangulated_index.push_back(3*NI[i][2]);
+ if(textured)
+ tess->triangulated_index.push_back(2*TI[i][2]);
+ tess->triangulated_index.push_back(3*PI[i][2]);
+ }
+ tessFace->sizes_triangulated.push_back(nI);
+ if(triangle_color)
+ {
+ tessFace->line_attributes.reserve(nI);
+ for(uint32_t i=0; i<nI; i++)
+ tessFace->line_attributes.push_back(SI[i]);
+ }
+ else if (style_index != m1 )
+ {
+ tessFace->line_attributes.push_back(style_index);
+ }
+ if(vertex_color)
+ {
+ tessFace->is_rgba=false;
+ for(uint32_t i=0; i<nI; i++)
+ if(1.0 != C[CI[i][0]].A || 1.0 != C[CI[i][1]].A || 1.0 != C[CI[i][2]].A)
+ {
+ tessFace->is_rgba=true;
+ break;
+ }
+
+ tessFace->rgba_vertices.reserve((tessFace->is_rgba?4:3)*3*nI);
+ for(uint32_t i=0; i<nI; i++)
+ {
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].A));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].R));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].G));
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].B));
+ if(tessFace->is_rgba)
+ tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].A));
+ }
+ }
+ tess->addTessFace(tessFace);
+ const uint32_t tess_index = add3DTess(tess);
+ return tess_index;
+}
+
+ void addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial &m,
+ uint32_t nN, const double N[][3], const uint32_t NI[][4],
+ uint32_t nT, const double T[][2], const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca);
+ uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index,
+ uint32_t nN, const double N[][3], const uint32_t NI[][4],
+ uint32_t nT, const double T[][2], const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
+ uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca);
+ uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial& m,
+ uint32_t nN, const double N[][3], const uint32_t NI[][4],
+ uint32_t nT, const double T[][2], const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+ {
+ const uint32_t style = addMaterial(m);
+ if(M!=NULL && nM>0)
+ {
+ uint32_t* const styles = new uint32_t[nM];
+ for(uint32_t i=0; i<nM; i++)
+ styles[i]=addMaterial(M[i]);
+ const uint32_t meshid = createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI, ca);
+ delete[] styles;
+ return meshid;
+ }
+ else
+ return createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL, ca);
+ }
+#define PRCTRANSFORM const double origin[3]=NULL, const double x_axis[3]=NULL, const double y_axis[3]=NULL, double scale=1, const double* t=NULL
+#define PRCCARTRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale
+#define PRCGENTRANSFORM const double* t=NULL
+#define PRCNOMATERIALINDEX m1
+
+#define ADDWIRE(curvtype) \
+ PRCgroup &group = findGroup(); \
+ group.wires.push_back(PRCwire()); \
+ PRCwire &wire = group.wires.back(); \
+ curvtype *curve = new curvtype; \
+ wire.curve = curve; \
+ wire.style = addColour(c);
+
+#define ADDFACE(surftype) \
+ PRCgroup &group = findGroup(); \
+ group.faces.push_back(PRCface()); \
+ PRCface& face = group.faces.back(); \
+ surftype *surface = new surftype; \
+ face.face = new PRCFace; \
+ face.face->base_surface = surface; \
+ face.transparent = m.alpha < 1.0; \
+ face.style = addMaterial(m);
+
+#define ADDCOMPFACE \
+ PRCgroup &group = findGroup(); \
+ group.compfaces.push_back(PRCcompface()); \
+ PRCcompface& face = group.compfaces.back(); \
+ PRCCompressedFace *compface = new PRCCompressedFace; \
+ face.face = compface; \
+ face.transparent = m.alpha < 1.0; \
+ face.style = addMaterial(m);
+
+inline bool isid(const double* t)
+{
+ return(
+ t[0]==1 && t[1]==0 && t[2]==0 && t[3]==0 &&
+ t[4]==0 && t[5]==1 && t[6]==0 && t[7]==0 &&
+ t[8]==0 && t[9]==0 && t[10]==1 && t[11]==0 &&
+ t[12]==0 && t[13]==0 && t[14]==0 && t[15]==1);
+}
+
+#define SETTRANSF \
+ if(t&&!isid(t)) \
+ face.transform = new PRCGeneralTransformation3d(t); \
+ if(origin) surface->origin.Set(origin[0],origin[1],origin[2]); \
+ if(x_axis) surface->x_axis.Set(x_axis[0],x_axis[1],x_axis[2]); \
+ if(y_axis) surface->y_axis.Set(y_axis[0],y_axis[1],y_axis[2]); \
+ surface->scale = scale; \
+ surface->geometry_is_2D = false; \
+ if(surface->origin!=PRCVector3d(0.0,0.0,0.0)) \
+ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Translate; \
+ if(surface->x_axis!=PRCVector3d(1.0,0.0,0.0)||surface->y_axis!=PRCVector3d(0.0,1.0,0.0)) \
+ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Rotate; \
+ if(surface->scale!=1) \
+ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Scale; \
+ surface->has_transformation = (surface->behaviour != PRC_TRANSFORMATION_Identity);
+
+ void useMesh(uint32_t tess_index, uint32_t style_index, PRCGENTRANSFORM);
+ void useMesh(uint32_t tess_index, const PRCmaterial& m, PRCGENTRANSFORM)
+ { useMesh(tess_index,addMaterial(m),t); }
+ void useMesh(uint32_t tess_index, uint32_t style_index, PRCCARTRANSFORM);
+ void useMesh(uint32_t tess_index, const PRCmaterial& m, PRCCARTRANSFORM)
+ { useMesh(tess_index,addMaterial(m),origin, x_axis, y_axis, scale); }
+
+ void useLines(uint32_t tess_index, uint32_t style_index, PRCGENTRANSFORM);
+ void useLines(uint32_t tess_index, const RGBAColour& c, double w, PRCGENTRANSFORM)
+ { useLines(tess_index, addLineMaterial(c,w), t); }
+ void useLines(uint32_t tess_index, uint32_t style_index, PRCCARTRANSFORM);
+ void useLines(uint32_t tess_index, const RGBAColour& c, double w, PRCCARTRANSFORM)
+ { useLines(tess_index,addLineMaterial(c,w),origin, x_axis, y_axis, scale); }
+
+// void addTriangle(const double P[][3], const double T[][2], uint32_t style_index);
+
+template<class V>
+void addLine(uint32_t n, const V P[], const RGBAColour &c, double w=1.0)
+{
+ PRCgroup &group = findGroup();
+ if(group.options.tess)
+ {
+ group.lines[w].push_back(PRCtessline());
+ PRCtessline& line = group.lines[w].back();
+ line.color.red = c.R;
+ line.color.green = c.G;
+ line.color.blue = c.B;
+ for(uint32_t i=0; i<n; i++)
+ line.point.push_back(PRCVector3d(X(P[i]),Y(P[i]),Z(P[i])));
+ }
+ else
+ {
+ ADDWIRE(PRCPolyLine)
+ curve->point.resize(n);
+ for(uint32_t i=0; i<n; i++)
+ curve->point[i].Set(X(P[i]),Y(P[i]),Z(P[i]));
+ curve->interval.min = 0;
+ curve->interval.max = curve->point.size()-1;
+ }
+}
+template<class V>
+void addBezierCurve(uint32_t n, const V cP[], const RGBAColour &c)
+{
+ ADDWIRE(PRCNURBSCurve)
+ curve->is_rational = false;
+ curve->degree = 3;
+ const size_t NUMBER_OF_POINTS = n;
+ curve->control_point.resize(NUMBER_OF_POINTS);
+ for(size_t i = 0; i < NUMBER_OF_POINTS; ++i)
+ curve->control_point[i].Set(X(cP[i]),Y(cP[i]),Z(cP[i]));
+ curve->knot.resize(3+NUMBER_OF_POINTS+1);
+ curve->knot[0] = 1;
+ for(size_t i = 1; i < 3+NUMBER_OF_POINTS; ++i)
+ curve->knot[i] = (i+2)/3; // integer division is intentional
+ curve->knot[3+NUMBER_OF_POINTS] = (3+NUMBER_OF_POINTS+1)/3;
+}
+
+template<class V>
+void addCurve(uint32_t d, uint32_t n, const V cP[], const double *k, const RGBAColour &c, const double w[])
+{
+ ADDWIRE(PRCNURBSCurve)
+ curve->is_rational = (w!=NULL);
+ curve->degree = d;
+ curve->control_point.resize(n);
+ for(uint32_t i = 0; i < n; i++)
+ if(w)
+ curve->control_point[i].Set(X(cP[i])*w[i],Y(cP[i])*w[i],Z(cP[i])*w[i],
+ w[i]);
+ else
+ curve->control_point[i].Set(X(cP[i]),Y(cP[i]),Z(cP[i]));
+ curve->knot.resize(d+n+1);
+ for(uint32_t i = 0; i < d+n+1; i++)
+ curve->knot[i] = k[i];
+}
+
+template<class V>
+void addQuad(const V P[], const RGBAColour C[])
+{
+ PRCgroup &group = findGroup();
+
+ group.quads.push_back(PRCtessquad());
+ PRCtessquad &quad = group.quads.back();
+ for(size_t i = 0; i < 4; i++)
+ {
+ quad.vertices[i].x = X(P[i]);
+ quad.vertices[i].y = Y(P[i]);
+ quad.vertices[i].z = Z(P[i]);
+ quad.colours[i] = C[i];
+ }
+}
+
+template<class V>
+void addRectangle(const V P[], const PRCmaterial &m)
+{
+ PRCgroup &group = findGroup();
+ if(group.options.tess)
+ {
+ group.rectangles.push_back(PRCtessrectangle());
+ PRCtessrectangle &rectangle = group.rectangles.back();
+ rectangle.style = addMaterial(m);
+ for(size_t i = 0; i < 4; i++)
+ {
+ rectangle.vertices[i].x = X(P[i]);
+ rectangle.vertices[i].y = Y(P[i]);
+ rectangle.vertices[i].z = Z(P[i]);
+ }
+ }
+ else if(group.options.compression == 0.0)
+ {
+ ADDFACE(PRCNURBSSurface)
+
+ surface->is_rational = false;
+ surface->degree_in_u = 1;
+ surface->degree_in_v = 1;
+ surface->control_point.resize(4);
+ for(size_t i = 0; i < 4; ++i)
+ {
+ surface->control_point[i].x = X(P[i]);
+ surface->control_point[i].y = Y(P[i]);
+ surface->control_point[i].z = Z(P[i]);
+ }
+ surface->knot_u.resize(4);
+ surface->knot_v.resize(4);
+ surface->knot_v[0] = surface->knot_u[0] = 1;
+ surface->knot_v[1] = surface->knot_u[1] = 3;
+ surface->knot_v[2] = surface->knot_u[2] = 4;
+ surface->knot_v[3] = surface->knot_u[3] = 4;
+ }
+ else
+ {
+ ADDCOMPFACE
+
+ compface->degree = 1;
+ compface->control_point.resize(4);
+ for(size_t i = 0; i < 4; ++i)
+ {
+ compface->control_point[i].x = X(P[i]);
+ compface->control_point[i].y = Y(P[i]);
+ compface->control_point[i].z = Z(P[i]);
+ }
+ }
+}
+
+template<class V>
+void addPatch(const V cP[], const PRCmaterial &m)
+{
+ PRCgroup &group = findGroup();
+ if(group.options.compression == 0.0)
+ {
+ ADDFACE(PRCNURBSSurface)
+
+ surface->is_rational = false;
+ surface->degree_in_u = 3;
+ surface->degree_in_v = 3;
+ surface->control_point.resize(16);
+ for(size_t i = 0; i < 16; ++i)
+ {
+ surface->control_point[i].x = X(cP[i]);
+ surface->control_point[i].y = Y(cP[i]);
+ surface->control_point[i].z = Z(cP[i]);
+ }
+ surface->knot_u.resize(8);
+ surface->knot_v.resize(8);
+ surface->knot_v[0] = surface->knot_u[0] = 1;
+ surface->knot_v[1] = surface->knot_u[1] = 1;
+ surface->knot_v[2] = surface->knot_u[2] = 1;
+ surface->knot_v[3] = surface->knot_u[3] = 1;
+ surface->knot_v[4] = surface->knot_u[4] = 2;
+ surface->knot_v[5] = surface->knot_u[5] = 2;
+ surface->knot_v[6] = surface->knot_u[6] = 2;
+ surface->knot_v[7] = surface->knot_u[7] = 2;
+ }
+ else
+ {
+ ADDCOMPFACE
+
+ compface->degree = 3;
+ compface->control_point.resize(16);
+ for(size_t i = 0; i < 16; ++i)
+ {
+ compface->control_point[i].x = X(cP[i]);
+ compface->control_point[i].y = Y(cP[i]);
+ compface->control_point[i].z = Z(cP[i]);
+ }
+ }
+}
+
+template<class V>
+void addSurface(uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
+ const V cP[], const double *kU,
+ const double *kV, const PRCmaterial &m,
+ const double w[])
+{
+ ADDFACE(PRCNURBSSurface)
+
+ surface->is_rational = (w!=NULL);
+ surface->degree_in_u = dU;
+ surface->degree_in_v = dV;
+ surface->control_point.resize(nU*nV);
+ for(size_t i = 0; i < nU*nV; i++)
+ if(w)
+ surface->control_point[i]=PRCControlPoint(X(cP[i])*w[i],Y(cP[i])*w[i],Z(cP[i])*w[i],w[i]);
+ else
+ surface->control_point[i]=PRCControlPoint(X(cP[i]),Y(cP[i]),Z(cP[i]));
+ surface->knot_u.insert(surface->knot_u.end(), kU, kU+(dU+nU+1));
+ surface->knot_v.insert(surface->knot_v.end(), kV, kV+(dV+nV+1));
+}
+template<class V>
+void addTube(uint32_t n, const V cP[], const V oP[], bool straight, const PRCmaterial &m, PRCTRANSFORM)
+{
+ ADDFACE(PRCBlend01)
+ SETTRANSF
+ if(straight)
+ {
+ PRCPolyLine *center_curve = new PRCPolyLine;
+ center_curve->point.resize(n);
+ for(uint32_t i=0; i<n; i++)
+ center_curve->point[i].Set(X(cP[i]),Y(cP[i]),Z(cP[i]));
+ center_curve->interval.min = 0;
+ center_curve->interval.max = center_curve->point.size()-1;
+ surface->center_curve = center_curve;
+
+ PRCPolyLine *origin_curve = new PRCPolyLine;
+ origin_curve->point.resize(n);
+ for(uint32_t i=0; i<n; i++)
+ origin_curve->point[i].Set(X(oP[i]),Y(oP[i]),Z(oP[i]));
+ origin_curve->interval.min = 0;
+ origin_curve->interval.max = origin_curve->point.size()-1;
+ surface->origin_curve = origin_curve;
+
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = 0;
+ surface->uv_domain.max.y = n-1;
+ }
+ else
+ {
+ PRCNURBSCurve *center_curve = new PRCNURBSCurve;
+ center_curve->is_rational = false;
+ center_curve->degree = 3;
+ const uint32_t CENTER_NUMBER_OF_POINTS = n;
+ center_curve->control_point.resize(CENTER_NUMBER_OF_POINTS);
+ for(uint32_t i = 0; i < CENTER_NUMBER_OF_POINTS; ++i)
+ center_curve->control_point[i].Set(X(cP[i]),Y(cP[i]),Z(cP[i]));
+ center_curve->knot.resize(3+CENTER_NUMBER_OF_POINTS+1);
+ center_curve->knot[0] = 1;
+ for(uint32_t i = 1; i < 3+CENTER_NUMBER_OF_POINTS; ++i)
+ center_curve->knot[i] = (i+2)/3; // integer division is intentional
+ center_curve->knot[3+CENTER_NUMBER_OF_POINTS] = (3+CENTER_NUMBER_OF_POINTS+1)/3;
+ surface->center_curve = center_curve;
+
+ PRCNURBSCurve *origin_curve = new PRCNURBSCurve;
+ origin_curve->is_rational = false;
+ origin_curve->degree = 3;
+ const uint32_t ORIGIN_NUMBER_OF_POINTS = n;
+ origin_curve->control_point.resize(ORIGIN_NUMBER_OF_POINTS);
+ for(uint32_t i = 0; i < ORIGIN_NUMBER_OF_POINTS; ++i)
+ origin_curve->control_point[i].Set(X(oP[i]),Y(oP[i]),Z(oP[i]));
+ origin_curve->knot.resize(3+ORIGIN_NUMBER_OF_POINTS+1);
+ origin_curve->knot[0] = 1;
+ for(size_t i = 1; i < 3+ORIGIN_NUMBER_OF_POINTS; ++i)
+ origin_curve->knot[i] = (i+2)/3; // integer division is intentional
+ origin_curve->knot[3+ORIGIN_NUMBER_OF_POINTS] = (3+ORIGIN_NUMBER_OF_POINTS+1)/3;
+ surface->origin_curve = origin_curve;
+
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = 1; // first knot
+ surface->uv_domain.max.y = (3+CENTER_NUMBER_OF_POINTS+1)/3; // last knot
+ }
+}
+ void addHemisphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
+ void addSphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
+ void addDisk(double radius, const PRCmaterial& m, PRCTRANSFORM);
+ void addCylinder(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
+ void addCone(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
+ void addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial& m, PRCTRANSFORM);
+#undef PRCTRANSFORM
+#undef PRCCARTRANSFORM
+#undef PRCGENTRANSFORM
+#undef ADDCOMPFACE
+
+ uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *picture, uint32_t width=0, uint32_t height=0,
+ std::string name="", uint32_t fileStructure=0)
+ { return fileStructures[fileStructure]->addPicture(format, size, picture, width, height, name); }
+ uint32_t addPicture(const PRCpicture& pic,
+ std::string name="", uint32_t fileStructure=0)
+ { return fileStructures[fileStructure]->addPicture(pic.format, pic.size, pic.data, pic.width, pic.height, name); }
+ uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addTextureDefinition(pTextureDefinition);
+ }
+ uint32_t addTextureApplication(PRCTextureApplication*& pTextureApplication, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addTextureApplication(pTextureApplication);
+ }
+ uint32_t addRgbColor(const PRCRgbColor &color,
+ uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addRgbColor(color);
+ }
+ uint32_t addRgbColorUnique(const PRCRgbColor &color,
+ uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addRgbColorUnique(color);
+ }
+ uint32_t addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric,
+ uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addMaterialGeneric(pMaterialGeneric);
+ }
+ uint32_t addStyle(PRCStyle*& pStyle, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addStyle(pStyle);
+ }
+ uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addPartDefinition(pPartDefinition);
+ }
+ uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addProductOccurrence(pProductOccurrence);
+ }
+ uint32_t addTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addTopoContext(pTopoContext);
+ }
+ uint32_t getTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->getTopoContext(pTopoContext);
+ }
+ uint32_t add3DTess(PRC3DTess*& p3DTess, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->add3DTess(p3DTess);
+ }
+ uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->add3DWireTess(p3DWireTess);
+ }
+/*
+ uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addMarkupTess(pMarkupTess);
+ }
+ uint32_t addMarkup(PRCMarkup*& pMarkup, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addMarkup(pMarkup);
+ }
+ uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addAnnotationItem(pAnnotationItem);
+ }
+ */
+ uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addCoordinateSystem(pCoordinateSystem);
+ }
+ uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0)
+ {
+ return fileStructures[fileStructure]->addCoordinateSystemUnique(pCoordinateSystem);
+ }
+ private:
+ void serializeModelFileData(PRCbitStream&);
+ std::ofstream *fout;
+ std::ostream &output;
+};
+
+}
+
+#endif // __O_PRC_FILE_H
diff --git a/graphics/asymptote/prc/test.asy b/graphics/asymptote/prc/test.asy
new file mode 100644
index 0000000000..21463f2eef
--- /dev/null
+++ b/graphics/asymptote/prc/test.asy
@@ -0,0 +1,5 @@
+settings.outformat="pdf";
+
+import embed;
+
+label(embed("test.prc","poster,3Droo=25",1500,500));
diff --git a/graphics/asymptote/prc/test.cc b/graphics/asymptote/prc/test.cc
new file mode 100644
index 0000000000..baf942fc7d
--- /dev/null
+++ b/graphics/asymptote/prc/test.cc
@@ -0,0 +1,954 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com> and
+* Michail Vidiassov <master@iaas.msu.ru>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <cmath>
+#include <string>
+#include "oPRCFile.h"
+
+using namespace std;
+
+extern const double pi;
+
+int main()
+{
+ #if 0
+ // List of pictures used; keep track of memory allocated to free it in the end
+ // shared pointers or garbage collector may be an alternative
+ uint8_t *picture1 = NULL;
+ uint8_t *picture2 = NULL;
+ uint8_t *picture3 = NULL;
+ uint8_t *picture4 = NULL;
+
+ oPRCFile file("test.prc");
+
+ const size_t N_COLOURS = 32;
+ RGBAColour colours[N_COLOURS];
+ for(size_t i = 0; i < N_COLOURS; ++i)
+ {
+ colours[i%N_COLOURS].R = 0.0;
+ colours[i%N_COLOURS].G = (i%N_COLOURS)/static_cast<double>(N_COLOURS);
+ colours[i%N_COLOURS].B = 0.95;
+ colours[i%N_COLOURS].A = 0.75;
+ }
+
+ PRCmaterial materials[N_COLOURS];
+ for(size_t i = 0; i < N_COLOURS; ++i)
+ {
+ materials[i%N_COLOURS].diffuse.R = 0.0;
+ materials[i%N_COLOURS].diffuse.G = (i%N_COLOURS)/static_cast<double>(N_COLOURS);
+ materials[i%N_COLOURS].diffuse.B = 0.95;
+ materials[i%N_COLOURS].diffuse.A = 0.75;
+ materials[i%N_COLOURS].specular.R = 0.01*0.0;
+ materials[i%N_COLOURS].specular.G = 0.01*(i%N_COLOURS)/static_cast<double>(N_COLOURS);
+ materials[i%N_COLOURS].specular.B = 0.01*0.95;
+ materials[i%N_COLOURS].specular.A = 0.01*0.75;
+ materials[i%N_COLOURS].emissive.R = 0.20*0.0;
+ materials[i%N_COLOURS].emissive.G = 0.20*(i%N_COLOURS)/static_cast<double>(N_COLOURS);
+ materials[i%N_COLOURS].emissive.B = 0.20*0.95;
+ materials[i%N_COLOURS].emissive.A = 0.20*0.75;
+ materials[i%N_COLOURS].ambient.R = 0.05*0.0;
+ materials[i%N_COLOURS].ambient.G = 0.05*(i%N_COLOURS)/static_cast<double>(N_COLOURS);
+ materials[i%N_COLOURS].ambient.B = 0.05*0.95;
+ materials[i%N_COLOURS].ambient.A = 0.05*0.75;
+ materials[i%N_COLOURS].alpha = 0.75;
+ materials[i%N_COLOURS].shininess = 0.1;
+ }
+
+ if(1) {
+ double knotsU[] = {1,1,1,1,2,2,2,2};
+ double knotsV[] = {1,1,1,1,2,2,2,2};
+ const size_t NUMBER_OF_PATCHES = 32;
+ double controlPoints[NUMBER_OF_PATCHES][16][3] =
+ {
+ { // Patch 0
+ {1.4,0,2.4},{1.4,-0.784,2.4},{0.784,-1.4,2.4},{0,-1.4,2.4},
+ {1.3375,0,2.53125},{1.3375,-0.749,2.53125},{0.749,-1.3375,2.53125},{0,-1.3375,2.53125},
+ {1.4375,0,2.53125},{1.4375,-0.805,2.53125},{0.805,-1.4375,2.53125},{0,-1.4375,2.53125},
+ {1.5,0,2.4},{1.5,-0.84,2.4},{0.84,-1.5,2.4},{0,-1.5,2.4},
+ },
+ { // Patch 1
+ {0,-1.4,2.4},{-0.784,-1.4,2.4},{-1.4,-0.784,2.4},{-1.4,0,2.4},
+ {0,-1.3375,2.53125},{-0.749,-1.3375,2.53125},{-1.3375,-0.749,2.53125},{-1.3375,0,2.53125},
+ {0,-1.4375,2.53125},{-0.805,-1.4375,2.53125},{-1.4375,-0.805,2.53125},{-1.4375,0,2.53125},
+ {0,-1.5,2.4},{-0.84,-1.5,2.4},{-1.5,-0.84,2.4},{-1.5,0,2.4},
+ },
+ { // Patch 2
+ {-1.4,0,2.4},{-1.4,0.784,2.4},{-0.784,1.4,2.4},{0,1.4,2.4},
+ {-1.3375,0,2.53125},{-1.3375,0.749,2.53125},{-0.749,1.3375,2.53125},{0,1.3375,2.53125},
+ {-1.4375,0,2.53125},{-1.4375,0.805,2.53125},{-0.805,1.4375,2.53125},{0,1.4375,2.53125},
+ {-1.5,0,2.4},{-1.5,0.84,2.4},{-0.84,1.5,2.4},{0,1.5,2.4},
+ },
+ { // Patch 3
+ {0,1.4,2.4},{0.784,1.4,2.4},{1.4,0.784,2.4},{1.4,0,2.4},
+ {0,1.3375,2.53125},{0.749,1.3375,2.53125},{1.3375,0.749,2.53125},{1.3375,0,2.53125},
+ {0,1.4375,2.53125},{0.805,1.4375,2.53125},{1.4375,0.805,2.53125},{1.4375,0,2.53125},
+ {0,1.5,2.4},{0.84,1.5,2.4},{1.5,0.84,2.4},{1.5,0,2.4},
+ },
+ { // Patch 4
+ {1.5,0,2.4},{1.5,-0.84,2.4},{0.84,-1.5,2.4},{0,-1.5,2.4},
+ {1.75,0,1.875},{1.75,-0.98,1.875},{0.98,-1.75,1.875},{0,-1.75,1.875},
+ {2,0,1.35},{2,-1.12,1.35},{1.12,-2,1.35},{0,-2,1.35},
+ {2,0,0.9},{2,-1.12,0.9},{1.12,-2,0.9},{0,-2,0.9},
+ },
+ { // Patch 5
+ {0,-1.5,2.4},{-0.84,-1.5,2.4},{-1.5,-0.84,2.4},{-1.5,0,2.4},
+ {0,-1.75,1.875},{-0.98,-1.75,1.875},{-1.75,-0.98,1.875},{-1.75,0,1.875},
+ {0,-2,1.35},{-1.12,-2,1.35},{-2,-1.12,1.35},{-2,0,1.35},
+ {0,-2,0.9},{-1.12,-2,0.9},{-2,-1.12,0.9},{-2,0,0.9},
+ },
+ { // Patch 6
+ {-1.5,0,2.4},{-1.5,0.84,2.4},{-0.84,1.5,2.4},{0,1.5,2.4},
+ {-1.75,0,1.875},{-1.75,0.98,1.875},{-0.98,1.75,1.875},{0,1.75,1.875},
+ {-2,0,1.35},{-2,1.12,1.35},{-1.12,2,1.35},{0,2,1.35},
+ {-2,0,0.9},{-2,1.12,0.9},{-1.12,2,0.9},{0,2,0.9},
+ },
+ { // Patch 7
+ {0,1.5,2.4},{0.84,1.5,2.4},{1.5,0.84,2.4},{1.5,0,2.4},
+ {0,1.75,1.875},{0.98,1.75,1.875},{1.75,0.98,1.875},{1.75,0,1.875},
+ {0,2,1.35},{1.12,2,1.35},{2,1.12,1.35},{2,0,1.35},
+ {0,2,0.9},{1.12,2,0.9},{2,1.12,0.9},{2,0,0.9},
+ },
+ { // Patch 8
+ {2,0,0.9},{2,-1.12,0.9},{1.12,-2,0.9},{0,-2,0.9},
+ {2,0,0.45},{2,-1.12,0.45},{1.12,-2,0.45},{0,-2,0.45},
+ {1.5,0,0.225},{1.5,-0.84,0.225},{0.84,-1.5,0.225},{0,-1.5,0.225},
+ {1.5,0,0.15},{1.5,-0.84,0.15},{0.84,-1.5,0.15},{0,-1.5,0.15},
+ },
+ { // Patch 9
+ {0,-2,0.9},{-1.12,-2,0.9},{-2,-1.12,0.9},{-2,0,0.9},
+ {0,-2,0.45},{-1.12,-2,0.45},{-2,-1.12,0.45},{-2,0,0.45},
+ {0,-1.5,0.225},{-0.84,-1.5,0.225},{-1.5,-0.84,0.225},{-1.5,0,0.225},
+ {0,-1.5,0.15},{-0.84,-1.5,0.15},{-1.5,-0.84,0.15},{-1.5,0,0.15},
+ },
+ { // Patch 10
+ {-2,0,0.9},{-2,1.12,0.9},{-1.12,2,0.9},{0,2,0.9},
+ {-2,0,0.45},{-2,1.12,0.45},{-1.12,2,0.45},{0,2,0.45},
+ {-1.5,0,0.225},{-1.5,0.84,0.225},{-0.84,1.5,0.225},{0,1.5,0.225},
+ {-1.5,0,0.15},{-1.5,0.84,0.15},{-0.84,1.5,0.15},{0,1.5,0.15},
+ },
+ { // Patch 11
+ {0,2,0.9},{1.12,2,0.9},{2,1.12,0.9},{2,0,0.9},
+ {0,2,0.45},{1.12,2,0.45},{2,1.12,0.45},{2,0,0.45},
+ {0,1.5,0.225},{0.84,1.5,0.225},{1.5,0.84,0.225},{1.5,0,0.225},
+ {0,1.5,0.15},{0.84,1.5,0.15},{1.5,0.84,0.15},{1.5,0,0.15},
+ },
+ { // Patch 12
+ {-1.6,0,2.025},{-1.6,-0.3,2.025},{-1.5,-0.3,2.25},{-1.5,0,2.25},
+ {-2.3,0,2.025},{-2.3,-0.3,2.025},{-2.5,-0.3,2.25},{-2.5,0,2.25},
+ {-2.7,0,2.025},{-2.7,-0.3,2.025},{-3,-0.3,2.25},{-3,0,2.25},
+ {-2.7,0,1.8},{-2.7,-0.3,1.8},{-3,-0.3,1.8},{-3,0,1.8},
+ },
+ { // Patch 13
+ {-1.5,0,2.25},{-1.5,0.3,2.25},{-1.6,0.3,2.025},{-1.6,0,2.025},
+ {-2.5,0,2.25},{-2.5,0.3,2.25},{-2.3,0.3,2.025},{-2.3,0,2.025},
+ {-3,0,2.25},{-3,0.3,2.25},{-2.7,0.3,2.025},{-2.7,0,2.025},
+ {-3,0,1.8},{-3,0.3,1.8},{-2.7,0.3,1.8},{-2.7,0,1.8},
+ },
+ { // Patch 14
+ {-2.7,0,1.8},{-2.7,-0.3,1.8},{-3,-0.3,1.8},{-3,0,1.8},
+ {-2.7,0,1.575},{-2.7,-0.3,1.575},{-3,-0.3,1.35},{-3,0,1.35},
+ {-2.5,0,1.125},{-2.5,-0.3,1.125},{-2.65,-0.3,0.9375},{-2.65,0,0.9375},
+ {-2,0,0.9},{-2,-0.3,0.9},{-1.9,-0.3,0.6},{-1.9,0,0.6},
+ },
+ { // Patch 15
+ {-3,0,1.8},{-3,0.3,1.8},{-2.7,0.3,1.8},{-2.7,0,1.8},
+ {-3,0,1.35},{-3,0.3,1.35},{-2.7,0.3,1.575},{-2.7,0,1.575},
+ {-2.65,0,0.9375},{-2.65,0.3,0.9375},{-2.5,0.3,1.125},{-2.5,0,1.125},
+ {-1.9,0,0.6},{-1.9,0.3,0.6},{-2,0.3,0.9},{-2,0,0.9},
+ },
+ { // Patch 16
+ {1.7,0,1.425},{1.7,-0.66,1.425},{1.7,-0.66,0.6},{1.7,0,0.6},
+ {2.6,0,1.425},{2.6,-0.66,1.425},{3.1,-0.66,0.825},{3.1,0,0.825},
+ {2.3,0,2.1},{2.3,-0.25,2.1},{2.4,-0.25,2.025},{2.4,0,2.025},
+ {2.7,0,2.4},{2.7,-0.25,2.4},{3.3,-0.25,2.4},{3.3,0,2.4},
+ },
+ { // Patch 17
+ {1.7,0,0.6},{1.7,0.66,0.6},{1.7,0.66,1.425},{1.7,0,1.425},
+ {3.1,0,0.825},{3.1,0.66,0.825},{2.6,0.66,1.425},{2.6,0,1.425},
+ {2.4,0,2.025},{2.4,0.25,2.025},{2.3,0.25,2.1},{2.3,0,2.1},
+ {3.3,0,2.4},{3.3,0.25,2.4},{2.7,0.25,2.4},{2.7,0,2.4},
+ },
+ { // Patch 18
+ {2.7,0,2.4},{2.7,-0.25,2.4},{3.3,-0.25,2.4},{3.3,0,2.4},
+ {2.8,0,2.475},{2.8,-0.25,2.475},{3.525,-0.25,2.49375},{3.525,0,2.49375},
+ {2.9,0,2.475},{2.9,-0.15,2.475},{3.45,-0.15,2.5125},{3.45,0,2.5125},
+ {2.8,0,2.4},{2.8,-0.15,2.4},{3.2,-0.15,2.4},{3.2,0,2.4},
+ },
+ { // Patch 19
+ {3.3,0,2.4},{3.3,0.25,2.4},{2.7,0.25,2.4},{2.7,0,2.4},
+ {3.525,0,2.49375},{3.525,0.25,2.49375},{2.8,0.25,2.475},{2.8,0,2.475},
+ {3.45,0,2.5125},{3.45,0.15,2.5125},{2.9,0.15,2.475},{2.9,0,2.475},
+ {3.2,0,2.4},{3.2,0.15,2.4},{2.8,0.15,2.4},{2.8,0,2.4},
+ },
+ { // Patch 20
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {0.8,0,3.15},{0.8,-0.45,3.15},{0.45,-0.8,3.15},{0,-0.8,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {0.2,0,2.7},{0.2,-0.112,2.7},{0.112,-0.2,2.7},{0,-0.2,2.7},
+ },
+ { // Patch 21
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {0,-0.8,3.15},{-0.45,-0.8,3.15},{-0.8,-0.45,3.15},{-0.8,0,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {0,-0.2,2.7},{-0.112,-0.2,2.7},{-0.2,-0.112,2.7},{-0.2,0,2.7},
+ },
+ { // Patch 22
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {-0.8,0,3.15},{-0.8,0.45,3.15},{-0.45,0.8,3.15},{0,0.8,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {-0.2,0,2.7},{-0.2,0.112,2.7},{-0.112,0.2,2.7},{0,0.2,2.7},
+ },
+ { // Patch 23
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {0,0.8,3.15},{0.45,0.8,3.15},{0.8,0.45,3.15},{0.8,0,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {0,0.2,2.7},{0.112,0.2,2.7},{0.2,0.112,2.7},{0.2,0,2.7},
+ },
+ { // Patch 24
+ {0.2,0,2.7},{0.2,-0.112,2.7},{0.112,-0.2,2.7},{0,-0.2,2.7},
+ {0.4,0,2.55},{0.4,-0.224,2.55},{0.224,-0.4,2.55},{0,-0.4,2.55},
+ {1.3,0,2.55},{1.3,-0.728,2.55},{0.728,-1.3,2.55},{0,-1.3,2.55},
+ {1.3,0,2.4},{1.3,-0.728,2.4},{0.728,-1.3,2.4},{0,-1.3,2.4},
+ },
+ { // Patch 25
+ {0,-0.2,2.7},{-0.112,-0.2,2.7},{-0.2,-0.112,2.7},{-0.2,0,2.7},
+ {0,-0.4,2.55},{-0.224,-0.4,2.55},{-0.4,-0.224,2.55},{-0.4,0,2.55},
+ {0,-1.3,2.55},{-0.728,-1.3,2.55},{-1.3,-0.728,2.55},{-1.3,0,2.55},
+ {0,-1.3,2.4},{-0.728,-1.3,2.4},{-1.3,-0.728,2.4},{-1.3,0,2.4},
+ },
+ { // Patch 26
+ {-0.2,0,2.7},{-0.2,0.112,2.7},{-0.112,0.2,2.7},{0,0.2,2.7},
+ {-0.4,0,2.55},{-0.4,0.224,2.55},{-0.224,0.4,2.55},{0,0.4,2.55},
+ {-1.3,0,2.55},{-1.3,0.728,2.55},{-0.728,1.3,2.55},{0,1.3,2.55},
+ {-1.3,0,2.4},{-1.3,0.728,2.4},{-0.728,1.3,2.4},{0,1.3,2.4},
+ },
+ { // Patch 27
+ {0,0.2,2.7},{0.112,0.2,2.7},{0.2,0.112,2.7},{0.2,0,2.7},
+ {0,0.4,2.55},{0.224,0.4,2.55},{0.4,0.224,2.55},{0.4,0,2.55},
+ {0,1.3,2.55},{0.728,1.3,2.55},{1.3,0.728,2.55},{1.3,0,2.55},
+ {0,1.3,2.4},{0.728,1.3,2.4},{1.3,0.728,2.4},{1.3,0,2.4},
+ },
+ { // Patch 28
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {1.425,0,0},{1.425,0.798,0},{0.798,1.425,0},{0,1.425,0},
+ {1.5,0,0.075},{1.5,0.84,0.075},{0.84,1.5,0.075},{0,1.5,0.075},
+ {1.5,0,0.15},{1.5,0.84,0.15},{0.84,1.5,0.15},{0,1.5,0.15},
+ },
+ { // Patch 29
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {0,1.425,0},{-0.798,1.425,0},{-1.425,0.798,0},{-1.425,0,0},
+ {0,1.5,0.075},{-0.84,1.5,0.075},{-1.5,0.84,0.075},{-1.5,0,0.075},
+ {0,1.5,0.15},{-0.84,1.5,0.15},{-1.5,0.84,0.15},{-1.5,0,0.15},
+ },
+ { // Patch 30
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {-1.425,0,0},{-1.425,-0.798,0},{-0.798,-1.425,0},{0,-1.425,0},
+ {-1.5,0,0.075},{-1.5,-0.84,0.075},{-0.84,-1.5,0.075},{0,-1.5,0.075},
+ {-1.5,0,0.15},{-1.5,-0.84,0.15},{-0.84,-1.5,0.15},{0,-1.5,0.15},
+ },
+ { // Patch 31
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {0,-1.425,0},{0.798,-1.425,0},{1.425,-0.798,0},{1.425,0,0},
+ {0,-1.5,0.075},{0.84,-1.5,0.075},{1.5,-0.84,0.075},{1.5,0,0.075},
+ {0,-1.5,0.15},{0.84,-1.5,0.15},{1.5,-0.84,0.15},{1.5,0,0.15},
+ },
+ };
+ file.begingroup("Teapot");
+ for(size_t i = 0; i < NUMBER_OF_PATCHES; ++i)
+ {
+ if(1) file.addPatch(controlPoints[i],materials[i%N_COLOURS]);
+ if(0) file.addSurface(3,3,4,4,controlPoints[i],knotsU,knotsV,materials[i%N_COLOURS],NULL); // use (too) general API for the same result as above
+ }
+ file.endgroup();
+
+ double t[4][4];
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=6;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=0;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+
+ PRCoptions teapotopt;
+ teapotopt.no_break = true;
+ teapotopt.do_break = false;
+ teapotopt.compression = 0.0001;
+ // force joining together of patches, damaging transparency
+ file.begingroup("Teapot rendered in the way of opaque surfaces and transferred",&teapotopt,t);
+ for(size_t i = 0; i < NUMBER_OF_PATCHES; ++i)
+ {
+ file.addPatch(controlPoints[i],materials[i%N_COLOURS]);
+ }
+ file.endgroup();
+ }
+
+ const size_t NUMBER_OF_POINTS = 31;
+ double points[NUMBER_OF_POINTS][3];
+ for(size_t i = 0; i < NUMBER_OF_POINTS; ++i)
+ {
+ points[i][0] = 3.5*cos(3.0*i/NUMBER_OF_POINTS*2.0*pi);
+ points[i][1] = 3.5*sin(3.0*i/NUMBER_OF_POINTS*2.0*pi);
+ points[i][2] = 5.0*i/NUMBER_OF_POINTS-1.0;
+ }
+ const size_t NUMBER_OF_WIRES = 2;
+ double shifted_points[NUMBER_OF_WIRES][NUMBER_OF_POINTS][3];
+ for(size_t wire = 0; wire < NUMBER_OF_WIRES; ++wire)
+ for(size_t point = 0; point < NUMBER_OF_POINTS; ++point)
+ {
+ shifted_points[wire][point][0] = points[point][0];
+ shifted_points[wire][point][1] = points[point][1];
+ shifted_points[wire][point][2] = points[point][2]+0.1*wire+0.1;
+ }
+ double knots[3+NUMBER_OF_POINTS+1];
+ knots[0] = 1;
+ for(size_t i = 1; i < 3+NUMBER_OF_POINTS; ++i)
+ {
+ knots[i] = (i+2)/3; // integer division is intentional
+ }
+ knots[3+NUMBER_OF_POINTS] = (3+NUMBER_OF_POINTS+1)/3;
+
+ PRCoptions grpopt;
+ grpopt.no_break = true;
+ grpopt.do_break = false;
+ grpopt.tess = true;
+ if(1){
+ double point1[3] = {11,0,0};
+ double point2[3] = {12,0,0};
+ double points[2][3] = {{9,0,0},{10,0,0}};
+ file.begingroup("points",&grpopt);
+ file.addPoint(point1, RGBAColour(1.0,0.0,0.0));
+ file.addPoint(point2, RGBAColour(1.0,0.0,0.0));
+ file.addPoints(2, points, RGBAColour(1.0,0.0,0.0,0.5),10);
+ file.endgroup();
+ }
+
+ if(1){
+ PRCoptions grpopt;
+ grpopt.no_break = true;
+ grpopt.do_break = false;
+ grpopt.tess = true;
+ grpopt.closed = true;
+
+ double t[4][4];
+
+ const size_t nP = 5;
+ double P[nP][3] = {{0,0,0},{1,0,0},{1,1,0},{0,1,0},{0,2,0}};
+ const size_t nI = 3;
+ uint32_t PI[nI][3] = {{0,1,3},{1,2,3},{3,2,4}};
+ const size_t nM = 2;
+ PRCmaterial M[nM];
+ M[0] = PRCmaterial(
+ RGBAColour(0.0,0.0,0.18),
+ RGBAColour(0.0,0.0,0.878431),
+ RGBAColour(0.0,0.0,0.32),
+ RGBAColour(0.0,0.0,0.072),
+ 1.0,0.1);
+ M[1] = PRCmaterial(
+ RGBAColour(0.18,0.0,0.0),
+ RGBAColour(0.878431,0.0,0.0),
+ RGBAColour(0.32,0.0,0.0),
+ RGBAColour(0.072,0.0,0.0),
+ 0.5,0.1);
+ uint32_t MI[nI] = {0,1,0};
+ const size_t nN = 2;
+ double N[nN][3] = {{0,0,1},{0,0,-1}};
+ uint32_t NI[nI][3] = {{0,0,0},{0,0,0},{1,1,1}};
+
+ const uint32_t nC = 3;
+ RGBAColour C[nC];
+ uint32_t CI[nI][3] = {{0,0,0},{1,1,1},{1,1,2}};
+
+ PRCmaterial materialGreen(
+ RGBAColour(0.0,0.18,0.0),
+ RGBAColour(0.0,0.878431,0.0),
+ RGBAColour(0.0,0.32,0.0),
+ RGBAColour(0.0,0.072,0.0),
+ 1.0,0.1);
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=-1;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ file.begingroup("triangles_onecolor_with_normals",&grpopt,t);
+ file.addTriangles(nP, P, nI, PI, materialGreen, nN, N, NI, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ if(1){
+ file.begingroup("triangles_onecolor",&grpopt);
+ file.addTriangles(nP, P, nI, PI, materialGreen, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=1;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ file.begingroup("triangles_manymaterials",&grpopt,t);
+ file.addTriangles(nP, P, nI, PI, materialGreen, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, nM, M, MI);
+ file.endgroup();
+ }
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=2;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ PRCmaterial materialBase(
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(1,1,1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ 1.0,0.1);
+ C[0] = RGBAColour(1,0,0,0.1);
+ C[1] = RGBAColour(0,1,0,0.5);
+ C[2] = RGBAColour(0,0,1,0.9);
+ file.begingroup("triangles_rgba_vertexcolors_on_opaque_a_component_of_vertexcolor_ignored",&grpopt,t);
+ file.addTriangles(nP, P, nI, PI, materialBase, 0, NULL, NULL, 0, NULL, NULL, nC, C, CI, 0, NULL, NULL);
+ file.endgroup();
+
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=3;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ PRCmaterial materialTransparent(
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(1,1,1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ 0.3,0.1);
+ C[0] = RGBAColour(1,0,0,0.1);
+ C[1] = RGBAColour(0,1,0,0.5);
+ C[2] = RGBAColour(0,0,1,0.9);
+ file.begingroup("triangles_rgba_vertexcolors_on_transparent_a_component_of_vertexcolor_ignored",&grpopt,t);
+ file.addTriangles(nP, P, nI, PI, materialTransparent, 0, NULL, NULL, 0, NULL, NULL, nC, C, CI, 0, NULL, NULL);
+ file.endgroup();
+
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=4;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ C[0] = RGBAColour(1,0,0,0.5);
+ C[1] = RGBAColour(0,1,0,0.5);
+ C[2] = RGBAColour(0,0,1,0.5);
+ file.begingroup("triangles_rgb_vertexcolors_on_transparent_may_not_work_in_OpenGL",&grpopt,t);
+ file.addTriangles(nP, P, nI, PI, materialTransparent, 0, NULL, NULL, 0, NULL, NULL, nC, C, CI, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=5;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ const uint32_t picture_width=2;
+ const uint32_t picture_height=2;
+ const uint8_t picRGB[picture_width*picture_height*3] =
+ {255,0,0, 0,255,0, 0,0,255, 0,0,0 };
+// {255,255,0, 255,0,0, 255,0,0, 255,0,0 };
+// { 255,0,0, 255,255,0, 255,255,0, 255,255,255 };
+// {255,0,0, 0,255,0, 0,0,255, 0,0,0 };
+
+ const uint8_t picRGBA[picture_width*picture_height*4] =
+ {255,0,0,255, 0,255,0,150, 0,0,255,150, 0,0,0,100 };
+// (1,0) 2 3 (1,1)
+// (0,0) 0 1 (1,0)
+ uint8_t *pictureRGB = new uint8_t[picture_width*picture_height*3];
+ for(size_t i=0; i<picture_width*picture_height*3; i++) pictureRGB[i]=picRGB[i];
+ picture1 = pictureRGB;
+ uint8_t *pictureRGBA = new uint8_t[picture_width*picture_height*4];
+ for(size_t i=0; i<picture_width*picture_height*4; i++) pictureRGBA[i]=picRGBA[i];
+ picture2 = pictureRGBA;
+ const uint32_t nT = 4;
+ const double T[nT][2] = { {0.1,0.1}, {0.9,0.1}, {0.9,0.9}, {0.9,0.1} };
+ uint32_t TI[nI][3] = {{0,1,3},{1,2,3},{3,2,3}};
+
+ PRCmaterial materialBase(
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(1,1,1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ 1.0,0.1,
+ pictureRGB, picture_width, picture_height, false, false);
+ file.begingroup("triangles_rgb_texture",&grpopt,t);
+ file.addTriangles(nP, P, nI, PI, materialBase, 0, NULL, NULL, nT, T, TI, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=6;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ PRCmaterial materialTransparent(
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(1,1,1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ 0.3,0.1,
+ pictureRGBA, picture_width, picture_height, true, true);
+ file.begingroup("triangles_rgba_texture_replacing",&grpopt,t);
+ file.addTriangles(nP, P, nI, PI, materialTransparent, 0, NULL, NULL, nT, T, TI, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ }
+
+ if(1){
+ PRCoptions grpopt;
+ grpopt.no_break = true;
+ grpopt.do_break = false;
+ grpopt.tess = true;
+ grpopt.closed = true;
+
+ double t[4][4];
+
+ const size_t nP = 6;
+ double P[nP][3] = {{3+0,0,0},{3+1,0,0},{3+0,1,0},{3+1,1,0},{3+0,2,0},{3+1,2,0}};
+ const size_t nI = 2;
+ uint32_t PI[nI][4] = {{0,1,3,2},{2,3,5,4}};
+ const size_t nM = 2;
+ PRCmaterial M[nM];
+ M[0] = PRCmaterial(
+ RGBAColour(0.0,0.0,0.18),
+ RGBAColour(0.0,0.0,0.878431),
+ RGBAColour(0.0,0.0,0.32),
+ RGBAColour(0.0,0.0,0.072),
+ 1.0,0.1);
+ M[1] = PRCmaterial(
+ RGBAColour(0.18,0.0,0.0),
+ RGBAColour(0.878431,0.0,0.0),
+ RGBAColour(0.32,0.0,0.0),
+ RGBAColour(0.072,0.0,0.0),
+ 0.5,0.1);
+ uint32_t MI[nI] = {0,1};
+ const size_t nN = 2;
+ double N[nN][3] = {{0,0,1},{0,0,-1}};
+ uint32_t NI[nI][4] = {{0,0,0,0},{1,1,1,1}};
+
+ const uint32_t nC = 3;
+ RGBAColour C[nC];
+ uint32_t CI[nI][4] = {{0,0,1,1},{1,1,2,2}};
+ C[0] = RGBAColour(1,0,0,0.5);
+ C[1] = RGBAColour(0,1,0,0.5);
+ C[2] = RGBAColour(0,0,1,0.5);
+
+ PRCmaterial materialGreen(
+ RGBAColour(0.0,0.18,0.0),
+ RGBAColour(0.0,0.878431,0.0),
+ RGBAColour(0.0,0.32,0.0),
+ RGBAColour(0.0,0.072,0.0),
+ 1.0,0.1);
+
+ PRCmaterial materialBase(
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(1,1,1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ 1.0,0.1);
+
+ PRCmaterial materialTransparent(
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(1,1,1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ 0.3,0.1);
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=-1;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ file.begingroup("quads_onecolor_with_normals",&grpopt,t);
+ file.addQuads(nP, P, nI, PI, materialGreen, nN, N, NI, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ if(1){
+ file.begingroup("quads_onecolor",&grpopt);
+ file.addQuads(nP, P, nI, PI, materialGreen, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=1;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ file.begingroup("quads_manymaterials",&grpopt,t);
+ file.addQuads(nP, P, nI, PI, materialGreen, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, nM, M, MI);
+ file.endgroup();
+ }
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=2;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ file.begingroup("quads_rgb_vertexcolors_on_transparent_may_not_work_in_OpenGL",&grpopt,t);
+ file.addQuads(nP, P, nI, PI, materialTransparent, 0, NULL, NULL, 0, NULL, NULL, nC, C, CI, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ if(1){
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=5;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ const uint32_t picture_width=2;
+ const uint32_t picture_height=2;
+ const uint8_t picRGB[picture_width*picture_height*3] =
+ {255,0,0, 0,255,0, 0,0,255, 0,0,0 };
+// {255,255,0, 255,0,0, 255,0,0, 255,0,0 };
+// { 255,0,0, 255,255,0, 255,255,0, 255,255,255 };
+// {255,0,0, 0,255,0, 0,0,255, 0,0,0 };
+
+ const uint8_t picRGBA[picture_width*picture_height*4] =
+ {255,0,0,255, 0,255,0,150, 0,0,255,150, 0,0,0,100 };
+// (1,0) 2 3 (1,1)
+// (0,0) 0 1 (1,0)
+ uint8_t *pictureRGB = new uint8_t[picture_width*picture_height*3];
+ for(size_t i=0; i<picture_width*picture_height*3; i++) pictureRGB[i]=picRGB[i];
+ picture3 = pictureRGB;
+ uint8_t *pictureRGBA = new uint8_t[picture_width*picture_height*4];
+ for(size_t i=0; i<picture_width*picture_height*4; i++) pictureRGBA[i]=picRGBA[i];
+ picture4 = pictureRGBA;
+ const uint32_t nT = 3;
+ const double T[nT][2] = { {0.1,0.1}, {0.5,0.5}, {0.9,0.9} };
+ uint32_t TI[nI][4] = {{0,0,1,1},{1,1,2,2}};
+
+ PRCmaterial materialBase(
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(1,1,1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ RGBAColour(0.1,0.1,0.1,1),
+ 1.0,0.1,
+ pictureRGB, picture_width, picture_height, false, false);
+ file.begingroup("quads_rgb_texture",&grpopt,t);
+ file.addQuads(nP, P, nI, PI, materialBase, 0, NULL, NULL, nT, T, TI, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=6;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ PRCmaterial materialTransparent(
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(1,1,1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ RGBAColour(0.1,0.1,0.1,0.3),
+ 0.6,0.1,
+ pictureRGBA, picture_width, picture_height, true, true);
+ file.begingroup("quads_rgba_texture_replacing",&grpopt,t);
+ file.addQuads(nP, P, nI, PI, materialTransparent, 0, NULL, NULL, nT, T, TI, 0, NULL, NULL, 0, NULL, NULL);
+ file.endgroup();
+ }
+
+ }
+
+ if(1){
+ file.begingroup("polyline",&grpopt);
+ file.addLine(NUMBER_OF_POINTS, points, RGBAColour(1.0,0.0,0.0));
+ file.endgroup();
+
+ file.begingroup("polylines",&grpopt);
+ file.addLine(NUMBER_OF_POINTS, shifted_points[0], RGBAColour(0.0,1.0,0.0),2.0);
+ file.addLine(NUMBER_OF_POINTS, shifted_points[1], RGBAColour(1.0,1.0,0.0),2.0);
+ file.endgroup();
+ }
+
+ if(1){
+ PRCoptions grpopt;
+ grpopt.no_break = true;
+ grpopt.do_break = false;
+ grpopt.tess = true;
+ grpopt.closed = true;
+
+ double t[4][4];
+
+ const size_t nP = 5;
+ double P[nP][3] = {{0,0,0},{1,0,0},{1,1,0},{0,1,0},{0,2,0}};
+ const size_t nI = 1+5 + 1+3;
+ uint32_t PI[nI] = {5,0,1,2,3,0, 3,2,4,3 }; // square of 5 points, wire of 2 points
+ const uint32_t nC = 5; // number of colors
+ RGBAColour C[nC]; // color for segments
+ C[0] = RGBAColour(1,0,0);
+ C[1] = RGBAColour(0,1,0);
+ C[2] = RGBAColour(0,0,1);
+ C[3] = RGBAColour(0,0,0);
+ C[4] = RGBAColour(1,1,0);
+ const uint32_t nCI = 5-1 + 3-1; // number of segments
+ uint32_t CI[nCI] = { 0,1,2,3, 4,4 };
+
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=5;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ file.begingroup("polyline_indexed_one_color",&grpopt,t);
+ file.addLines(nP, P, nI, PI, RGBAColour(1,0,0), 1, false, 0, NULL, 0, NULL);
+ file.endgroup();
+
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=6;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ file.begingroup("polyline_indexed_color_per_segment",&grpopt,t);
+ file.addLines(nP, P, nI, PI, RGBAColour(1,0,0), 2, true, nC, C, nCI, CI);
+ file.endgroup();
+
+ t[0][0]=1; t[0][1]=0; t[0][2]=0; t[0][3]=0;
+ t[1][0]=0; t[1][1]=1; t[1][2]=0; t[1][3]=0;
+ t[2][0]=0; t[2][1]=0; t[2][2]=1; t[2][3]=7;
+ t[3][0]=0; t[3][1]=0; t[3][2]=0; t[3][3]=1;
+ const uint32_t nCI2 = 5 + 3; // number of vertices
+ uint32_t CI2[nCI2] = { 0,1,2,3,0, 4,4,4 };
+ file.begingroup("polyline_indexed_color_per_vertex_is_broken",&grpopt,t);
+ file.addLines(nP, P, nI, PI, RGBAColour(1,0,0), 2, false, nC, C, nCI2, CI2);
+ file.endgroup();
+ }
+
+ if(1)
+ {
+ file.begingroup("bezier_wire");
+ file.addBezierCurve(NUMBER_OF_POINTS,points,RGBAColour(1.0,1.0,1.0));
+ file.endgroup();
+ }
+ if(1)
+ {
+ file.begingroup("NURBS_wire");
+ file.addCurve(3, NUMBER_OF_POINTS, points, knots, RGBAColour(1.0,1.0,1.0), NULL); // genarl API for the above
+ file.endgroup();
+ }
+
+// following box examples show a) different ways to represent a surface consisting of flat rectangles
+// b) that the only way to have almost working transparency is a set of NURBS bodies.
+// (Or may be other topology types like plane also work
+// demonstration how non-transparent materials work the same for all kinds of objects
+
+ if(1) { // demonstration how non-transparent materials work the same for all kinds of objects
+ const size_t NUMBER_OF_PATCHES = 6;
+ double vertices[NUMBER_OF_PATCHES][4][3] =
+ {
+ { // Patch 0
+ {-1,-1,-1},
+ { 1,-1,-1},
+ {-1, 1,-1},
+ { 1, 1,-1}
+ },
+ { // Patch 1
+ {-1,-1, 1},
+ { 1,-1, 1},
+ {-1, 1, 1},
+ { 1, 1, 1}
+ },
+ { // Patch 2
+ {-1,-1,-1},
+ { 1,-1,-1},
+ {-1,-1, 1},
+ { 1,-1, 1}
+ },
+ { // Patch 3
+ {-1, 1,-1},
+ { 1, 1,-1},
+ {-1, 1, 1},
+ { 1, 1, 1}
+ },
+ { // Patch 4
+ {-1,-1,-1},
+ {-1, 1,-1},
+ {-1,-1, 1},
+ {-1, 1, 1}
+ },
+ { // Patch 5
+ { 1,-1,-1},
+ { 1, 1,-1},
+ { 1,-1, 1},
+ { 1, 1, 1}
+ }
+ };
+ const size_t NUMBER_OF_BOXES = 6;
+ double shifted_vertices[NUMBER_OF_BOXES][NUMBER_OF_PATCHES][4][3];
+ for(size_t box = 0; box < NUMBER_OF_BOXES; ++box)
+ for(size_t patch = 0; patch < NUMBER_OF_PATCHES; ++patch)
+ for(size_t i = 0; i < 4; ++i)
+ {
+ shifted_vertices[box][patch][i][0] = vertices[patch][i][0]+3*box;
+ shifted_vertices[box][patch][i][1] = vertices[patch][i][1];
+ shifted_vertices[box][patch][i][2] = vertices[patch][i][2]-2;
+ }
+ PRCmaterial materialGreen(
+ RGBAColour(0.0,0.18,0.0),
+ RGBAColour(0.0,0.878431,0.0),
+ RGBAColour(0.0,0.32,0.0),
+ RGBAColour(0.0,0.072,0.0),
+ 1.0,0.1);
+
+ PRCoptions grpopt;
+ file.begingroup("TransparentBox");
+ grpopt.no_break = false;
+ grpopt.do_break = true;
+ grpopt.tess = false;
+ file.begingroup("TransparentBoxSetOfNURBSBodies",&grpopt);
+ for(size_t patch = 0; patch < NUMBER_OF_PATCHES; ++patch)
+ {
+ file.addRectangle(shifted_vertices[0][patch], materials[(patch*5)%N_COLOURS]);
+ }
+ file.endgroup();
+ grpopt.no_break = true;
+ grpopt.do_break = false;
+ grpopt.tess = false;
+ file.begingroup("TransparentBoxNURBSFaces",&grpopt);
+ for(size_t patch = 0; patch < NUMBER_OF_PATCHES; ++patch)
+ {
+ file.addRectangle(shifted_vertices[1][patch], materials[(patch*5)%N_COLOURS]);
+ }
+ file.endgroup();
+ grpopt.no_break = true;
+ grpopt.do_break = false;
+ grpopt.tess = true;
+ file.begingroup("TransparentBoxTessellated",&grpopt);
+ for(size_t patch = 0; patch < NUMBER_OF_PATCHES; ++patch)
+ {
+ file.addRectangle(shifted_vertices[2][patch], materials[(patch*5)%N_COLOURS]);
+ }
+ file.endgroup();
+ file.endgroup();
+
+ file.begingroup("Box");
+ grpopt.no_break = false;
+ grpopt.do_break = false;
+ grpopt.tess = true;
+ file.begingroup("BoxTessellated",&grpopt);
+ for(size_t patch = 0; patch < NUMBER_OF_PATCHES; ++patch)
+ {
+ file.addRectangle(shifted_vertices[3][patch], materialGreen);
+ }
+ file.endgroup();
+ grpopt.no_break = true;
+ grpopt.do_break = false;
+ grpopt.tess = false;
+ file.begingroup("BoxNURBSFaces",&grpopt);
+ for(size_t patch = 0; patch < NUMBER_OF_PATCHES; ++patch)
+ {
+ file.addRectangle(shifted_vertices[4][patch], materialGreen);
+ }
+ file.endgroup();
+ grpopt.no_break = false;
+ grpopt.do_break = true;
+ grpopt.tess = false;
+ file.begingroup("BoxSetOfNURBSBodies",&grpopt);
+ for(size_t patch = 0; patch < NUMBER_OF_PATCHES; ++patch)
+ {
+ file.addRectangle(shifted_vertices[5][patch], materialGreen);
+ }
+ file.endgroup();
+ file.endgroup();
+ }
+
+ if(1) {
+ PRCmaterial materialGreen(
+ RGBAColour(0.0,0.18,0.0),
+ RGBAColour(0.0,0.878431,0.0),
+ RGBAColour(0.0,0.32,0.0),
+ RGBAColour(0.0,0.072,0.0),
+ 1.0,0.1);
+ PRCoptions grpopt;
+ grpopt.closed = true;
+
+ file.begingroup("Complex elements, one-sided");
+
+ const double disk_origin[3] = {11,0,2};
+ const double disk_x_axis[3] = {1,0,0};
+ const double disk_y_axis[3] = {0,-1,0};
+ const double disk_scale = 2;
+ file.begingroup("disk",&grpopt);
+ file.addDisk(1,materialGreen,disk_origin,disk_x_axis,disk_y_axis,disk_scale);
+ file.endgroup();
+ const double hs_origin[3] = {11,0,2};
+ const double hs_x_axis[3] = {1,0,0};
+ const double hs_y_axis[3] = {0,1,0};
+ const double hs_scale = 2;
+ file.begingroup("hemisphere",&grpopt);
+ file.addHemisphere(1,materialGreen,hs_origin,hs_x_axis,hs_y_axis,hs_scale);
+ file.endgroup();
+ const double cyl_origin[3] = {11,0,1};
+ const double cyl_x_axis[3] = {1,0,0};
+ const double cyl_y_axis[3] = {0,1,0};
+ const double cyl_scale = 1;
+ file.begingroup("cylinder",&grpopt);
+ file.addCylinder(1,1,materialGreen,cyl_origin,cyl_x_axis,cyl_y_axis,cyl_scale);
+ file.endgroup();
+ const double cone_origin[3] = {11,0,1};
+ const double cone_x_axis[3] = {1,0,0};
+ const double cone_y_axis[3] = {0,-1,0};
+ const double cone_scale = 1;
+ file.begingroup("cone",&grpopt);
+ file.addCone(1,1,materialGreen,cone_origin,cone_x_axis,cone_y_axis,cone_scale);
+ file.endgroup();
+ const double sp_origin[3] = {11,0,-1};
+ const double sp_x_axis[3] = {1,0,0};
+ const double sp_y_axis[3] = {0,1,0};
+ const double sp_scale = 1;
+ file.begingroup("sphere",&grpopt);
+ file.addSphere(0.5,materialGreen,sp_origin,sp_x_axis,sp_y_axis,sp_scale);
+ file.endgroup();
+ const double tor_origin[3] = {11,0,0};
+ const double tor_x_axis[3] = {1,0,0};
+ const double tor_y_axis[3] = {0,1,0};
+ const double tor_scale = 1;
+ file.begingroup("torus",&grpopt);
+ file.addTorus(0.5,0.1,0,360,materialGreen,tor_origin,tor_x_axis,tor_y_axis,tor_scale);
+ file.endgroup();
+
+ const size_t NUMBER_OF_POINTS = 4;
+ double cpoints[NUMBER_OF_POINTS][3];
+ cpoints[0][0] = 1; cpoints[0][1] = 0; cpoints[0][2] = 0;
+ cpoints[1][0] = 1; cpoints[1][1] = 0.552284749830793; cpoints[1][2] = 0;
+ cpoints[2][0] = 0.552284749830793; cpoints[2][1] = 1; cpoints[2][2] = 0;
+ cpoints[3][0] = 0; cpoints[3][1] = 1; cpoints[3][2] = 0;
+ double opoints[NUMBER_OF_POINTS][3];
+ opoints[0][0] = 1.1*1; opoints[0][1] = 1.1*0; opoints[0][2] = 0;
+ opoints[1][0] = 1.1*1; opoints[1][1] = 1.1*0.552284749830793; opoints[1][2] = 0;
+ opoints[2][0] = 1.1*0.552284749830793; opoints[2][1] = 1.1*1; opoints[2][2] = 0;
+ opoints[3][0] = 1.1*0; opoints[3][1] = 1.1*1; opoints[3][2] = 0;
+ const double tube_origin[3] = {11,0,0};
+ const double tube_x_axis[3] = {1,0,0};
+ const double tube_y_axis[3] = {0,1,0};
+ const double tube_scale = 1;
+ file.begingroup("tube",&grpopt);
+ file.addTube(NUMBER_OF_POINTS,cpoints,opoints,false,materialGreen,tube_origin,tube_x_axis,tube_y_axis,tube_scale);
+ file.endgroup();
+
+ file.endgroup();
+ }
+
+ file.finish();
+
+ delete[] picture1;
+ delete[] picture2;
+ delete[] picture3;
+ delete[] picture4;
+
+#endif
+ return 0;
+}
+
diff --git a/graphics/asymptote/prc/writePRC.cc b/graphics/asymptote/prc/writePRC.cc
new file mode 100644
index 0000000000..a2877b0899
--- /dev/null
+++ b/graphics/asymptote/prc/writePRC.cc
@@ -0,0 +1,2085 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com> and
+* Michail Vidiassov <master@iaas.msu.ru>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "writePRC.h"
+#include <climits>
+#include <cassert>
+
+// debug print includes
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+
+#if !defined(__GNUC__) || defined(__clang__)
+#include <vector>
+#endif
+
+using namespace std;
+
+#ifndef __GNUC_PREREQ
+#define __GNUC_PREREQ(maj, min) (0)
+#endif
+
+// Count leading zeros.
+uint32_t CLZ(uint32_t a)
+{
+#if __GNUC_PREREQ(3,4)
+ return __builtin_clz(a);
+#else
+// find the log base 2 of a 32-bit integer
+ static const int MultiplyDeBruijnBitPosition[32] = {
+ 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
+ 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
+ };
+
+ a |= a >> 1; // first round down to one less than a power of 2
+ a |= a >> 2;
+ a |= a >> 4;
+ a |= a >> 8;
+ a |= a >> 16;
+
+ return 31-MultiplyDeBruijnBitPosition[(uint32_t)(a * 0x07C4ACDDU) >> 27];
+#endif
+}
+
+// Portable integer implementation of ceil(log2(x)).
+uint32_t Log2(uint32_t x)
+{
+ assert(x != 0);
+ uint32_t L=31-CLZ(x);
+ return ((uint32_t) 1 << L == x) ? L : L+1;
+}
+
+#define WriteUnsignedInteger( value ) pbs << (uint32_t)(value);
+#define WriteInteger( value ) pbs << (int32_t)(value);
+#define WriteCharacter( value ) pbs << (uint8_t)(value);
+#define WriteDouble( value ) pbs << (double)(value);
+#define WriteBit( value ) pbs << (bool)(value);
+#define WriteBoolean( value ) pbs << (bool)(value);
+#define WriteString( value ) pbs << (value);
+#define SerializeContentPRCBase serializeContentPRCBase(pbs);
+#define SerializeGraphics serializeGraphics(pbs);
+#define SerializePRCBaseWithGraphics { serializeContentPRCBase(pbs); serializeGraphics(pbs); }
+#define SerializeRepresentationItemContent serializeRepresentationItemContent(pbs);
+#define SerializeRepresentationItem( value ) (value)->serializeRepresentationItem(pbs);
+#define SerializeMarkup( value ) (value).serializeMarkup(pbs);
+#define SerializeReferenceUniqueIdentifier( value ) (value).serializeReferenceUniqueIdentifier(pbs);
+#define SerializeContentBaseTessData serializeContentBaseTessData(pbs);
+#define SerializeTessFace( value ) (value)->serializeTessFace(pbs);
+#define SerializeUserData UserData(0,0).write(pbs);
+#define SerializeLineAttr( value ) pbs << (uint32_t)((value)+1);
+#define SerializeVector3d( value ) (value).serializeVector3d(pbs);
+#define SerializeVector2d( value ) (value).serializeVector2d(pbs);
+#define SerializeName( value ) writeName(pbs, (value));
+#define SerializeInterval( value ) (value).serializeInterval(pbs);
+// #define SerializeBoundingBox( value ) (value).serializeBoundingBox(pbs);
+#define SerializeDomain( value ) (value).serializeDomain(pbs);
+#define SerializeParameterization serializeParameterization(pbs);
+#define SerializeUVParameterization serializeUVParameterization(pbs);
+#define SerializeTransformation serializeTransformation(pbs);
+#define SerializeBaseTopology serializeBaseTopology(pbs);
+#define SerializeBaseGeometry serializeBaseGeometry(pbs);
+#define SerializePtrCurve( value ) {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeCurve(pbs);}
+#define SerializePtrSurface( value ) {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeSurface(pbs);}
+#define SerializePtrTopology( value ) {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeTopoItem(pbs);}
+#define SerializeContentCurve serializeContentCurve(pbs);
+#define SerializeContentWireEdge serializeContentWireEdge(pbs);
+#define SerializeContentBody serializeContentBody(pbs);
+#define SerializeTopoContext serializeTopoContext(pbs);
+#define SerializeContextAndBodies( value ) (value).serializeContextAndBodies(pbs);
+#define SerializeBody( value ) (value)->serializeBody(pbs);
+#define ResetCurrentGraphics resetGraphics();
+#define SerializeContentSurface serializeContentSurface(pbs);
+#define SerializeCompressedUniqueId( value ) (value).serializeCompressedUniqueId(pbs);
+#define SerializeUnit( value ) (value).serializeUnit(pbs);
+#define SerializeBoundingBox serializeBoundingBox(pbs);
+#define SerializeAttributeEntry serializeAttributeEntry(pbs);
+#define SerializeContentSingleAttribute( value ) (value).serializeSingleAttribute(pbs);
+#define SerializeAttribute( value ) (value).serializeAttribute(pbs);
+#define SerializeAttributeData serializeAttributes(pbs);
+#define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value));
+#define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out);
+
+void writeUncompressedUnsignedInteger(ostream &out, uint32_t data)
+{
+#ifdef WORDS_BIGENDIAN
+ out.write(((char*)&data)+3,1);
+ out.write(((char*)&data)+2,1);
+ out.write(((char*)&data)+1,1);
+ out.write(((char*)&data)+0,1);
+#else
+ out.write(((char*)&data)+0,1);
+ out.write(((char*)&data)+1,1);
+ out.write(((char*)&data)+2,1);
+ out.write(((char*)&data)+3,1);
+#endif
+}
+
+double PRCVector3d::Length()
+{
+ return sqrt(x*x+y*y+z*z);
+}
+
+bool PRCVector3d::Normalize()
+{
+ double fLength=Length();
+ if(fLength < FLT_EPSILON) return false;
+ double factor=1.0/fLength;
+ x *= factor;
+ y *= factor;
+ z *= factor;
+ return true;
+}
+
+double PRCVector2d::Length()
+{
+ return sqrt(x*x+y*y);
+}
+
+bool PRCVector2d::Normalize()
+{
+ double fLength=Length();
+ if(fLength < FLT_EPSILON) return false;
+ double factor=1.0/fLength;
+ x *= factor;
+ y *= factor;
+
+ return true;
+}
+
+void PRCVector2d::serializeVector2d(PRCbitStream &pbs)
+{
+ WriteDouble (x)
+ WriteDouble (y)
+}
+
+uint32_t makeCADID()
+{
+ static uint32_t ID = 1;
+ return ID++;
+}
+
+uint32_t makePRCID()
+{
+ static uint32_t ID = 1;
+ return ID++;
+}
+
+bool type_eligible_for_reference(uint32_t type)
+{
+ if(
+ type == PRC_TYPE_MISC_EntityReference ||
+ type == PRC_TYPE_MISC_MarkupLinkedItem ||
+ type == PRC_TYPE_RI_BrepModel ||
+ type == PRC_TYPE_RI_Curve ||
+ type == PRC_TYPE_RI_Direction ||
+ type == PRC_TYPE_RI_Plane ||
+ type == PRC_TYPE_RI_PointSet ||
+ type == PRC_TYPE_RI_PolyBrepModel ||
+ type == PRC_TYPE_RI_PolyWire ||
+ type == PRC_TYPE_RI_Set ||
+ type == PRC_TYPE_RI_CoordinateSystem ||
+ type == PRC_TYPE_ASM_ProductOccurence ||
+ type == PRC_TYPE_ASM_PartDefinition ||
+ type == PRC_TYPE_ASM_Filter ||
+ type == PRC_TYPE_MKP_View ||
+ type == PRC_TYPE_MKP_Markup ||
+ type == PRC_TYPE_MKP_Leader ||
+ type == PRC_TYPE_MKP_AnnotationItem ||
+ type == PRC_TYPE_MKP_AnnotationSet ||
+ type == PRC_TYPE_MKP_AnnotationReference ||
+ type == PRC_TYPE_GRAPH_Style ||
+ type == PRC_TYPE_GRAPH_Material ||
+ type == PRC_TYPE_GRAPH_TextureApplication ||
+ type == PRC_TYPE_GRAPH_TextureDefinition ||
+ type == PRC_TYPE_GRAPH_LinePattern ||
+ type == PRC_TYPE_GRAPH_DottingPattern ||
+ type == PRC_TYPE_GRAPH_HatchingPattern ||
+ type == PRC_TYPE_GRAPH_SolidPattern ||
+ type == PRC_TYPE_GRAPH_VPicturePattern ||
+ type == PRC_TYPE_GRAPH_AmbientLight ||
+ type == PRC_TYPE_GRAPH_PointLight ||
+ type == PRC_TYPE_GRAPH_DirectionalLight ||
+ type == PRC_TYPE_GRAPH_SpotLight ||
+ type == PRC_TYPE_GRAPH_SceneDisplayParameters ||
+ type == PRC_TYPE_GRAPH_Camera
+ )
+ return true;
+ else
+ return false;
+}
+
+void UserData::write(PRCbitStream &pbs)
+{
+ pbs << size;
+ if(size > 0) {
+ uint32_t quot=size/8;
+ uint32_t rem=size-8*quot;
+ for(uint32_t i = 0; i < quot; ++i)
+ pbs << data[i];
+ for(uint32_t j = 0; j < rem; ++j) // 0-based, big endian bit counting
+ pbs << (bool)((data[quot] & (0x80 >> j))!=0);
+ }
+}
+
+void PRCAttributeEntry::serializeAttributeEntry(PRCbitStream &pbs) const
+{
+ WriteBoolean (title_is_integer)
+ if (title_is_integer)
+ WriteUnsignedInteger (title_integer)
+ else
+ WriteString (title_text)
+}
+
+void PRCSingleAttribute::serializeSingleAttribute(PRCbitStream &pbs) const
+{
+ SerializeAttributeEntry
+ WriteUnsignedInteger (type)
+ switch (type)
+ {
+ case KEPRCModellerAttributeTypeInt:
+ WriteInteger (value.integer)
+ break;
+ case KEPRCModellerAttributeTypeReal:
+ WriteDouble (value.real)
+ break;
+ case KEPRCModellerAttributeTypeTime:
+ WriteUnsignedInteger (value.time)
+ break;
+ case KEPRCModellerAttributeTypeString:
+ WriteString (value_text)
+ break;
+ default:
+ break;
+ }
+}
+
+void PRCAttribute::serializeAttribute(PRCbitStream &pbs) const
+{
+ WriteUnsignedInteger (PRC_TYPE_MISC_Attribute)
+
+ SerializeAttributeEntry
+ const uint32_t size_of_attribute_keys = attribute_keys.size();
+ WriteUnsignedInteger (size_of_attribute_keys)
+ for(uint32_t i=0;i<size_of_attribute_keys;i++)
+ SerializeContentSingleAttribute (attribute_keys[i])
+}
+
+void PRCAttributes::serializeAttributes(PRCbitStream &pbs) const
+{
+ if (attributes.empty()) { // shortcut for most typical case
+ const uint32_t number_of_attributes = 0;
+ WriteUnsignedInteger (number_of_attributes)
+ return;
+ }
+ const uint32_t number_of_attributes = attributes.size();
+ WriteUnsignedInteger (number_of_attributes)
+ for(PRCAttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it)
+ {
+ SerializeAttribute(*it)
+ }
+}
+
+void ContentPRCBase::serializeContentPRCBase(PRCbitStream &pbs) const
+{
+ SerializeAttributeData
+
+ SerializeName (name)
+ if (type_eligible_for_reference(type))
+ {
+ WriteUnsignedInteger (CAD_identifier)
+ WriteUnsignedInteger (CAD_persistent_identifier)
+ WriteUnsignedInteger (PRC_unique_identifier)
+ }
+}
+
+
+bool IsCompressedType(uint32_t type)
+{
+ return (type == PRC_TYPE_TOPO_BrepDataCompress || type == PRC_TYPE_TOPO_SingleWireBodyCompress || type == PRC_TYPE_TESS_3D_Compressed);
+}
+
+void PRCReferenceUniqueIdentifier::serializeReferenceUniqueIdentifier(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_MISC_ReferenceOnPRCBase)
+ WriteUnsignedInteger (type)
+ const bool reference_in_same_file_structure = true;
+ WriteBoolean (reference_in_same_file_structure)
+// if (!reference_in_same_file_structure)
+// SerializeCompressedUniqueId (target_file_structure)
+ WriteUnsignedInteger (unique_identifier)
+}
+
+void PRCRgbColor::serializeRgbColor(PRCbitStream &pbs)
+{
+ WriteDouble (red)
+ WriteDouble (green)
+ WriteDouble (blue)
+}
+
+void PRCPicture::serializePicture(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_GRAPH_Picture)
+ SerializeContentPRCBase
+ WriteInteger (format) //see Types for picture files
+ WriteUnsignedInteger (uncompressed_file_index+1)
+ WriteUnsignedInteger (pixel_width)
+ WriteUnsignedInteger (pixel_height)
+}
+
+void PRCTextureDefinition::serializeTextureDefinition(PRCbitStream &pbs)
+{
+ uint32_t i=0; // universal index for PRC standart compatibility
+ const uint8_t texture_dimension = 2;
+ const uint32_t texture_mapping_attributes = texture_mapping_attribute;
+ const uint32_t size_texture_mapping_attributes_intensities = 1;
+ const double *texture_mapping_attributes_intensities = &texture_mapping_attribute_intensity;
+ const uint32_t size_texture_mapping_attributes_components = 1;
+ const uint8_t *texture_mapping_attributes_components = &texture_mapping_attribute_components;
+ const EPRCTextureMappingType eMappingType = KEPRCTextureMappingType_Stored;
+
+ const double red = 1.0;
+ const double green = 1.0;
+ const double blue = 1.0;
+ const double alpha = 1.0;
+ const EPRCTextureBlendParameter blend_src_rgb = KEPRCTextureBlendParameter_Unknown;
+ const EPRCTextureBlendParameter blend_dst_rgb = KEPRCTextureBlendParameter_Unknown;
+ const EPRCTextureBlendParameter blend_src_alpha = KEPRCTextureBlendParameter_Unknown;
+ const EPRCTextureBlendParameter blend_dst_alpha = KEPRCTextureBlendParameter_Unknown;
+ const EPRCTextureAlphaTest alpha_test = KEPRCTextureAlphaTest_Unknown;
+ const double alpha_test_reference = 1.0;
+ const EPRCTextureWrappingMode texture_wrapping_mode_R = KEPRCTextureWrappingMode_ClampToBorder;
+ const bool texture_transformation = false;
+
+ WriteUnsignedInteger (PRC_TYPE_GRAPH_TextureDefinition)
+
+ SerializeContentPRCBase
+
+ WriteUnsignedInteger (picture_index+1)
+ WriteCharacter (texture_dimension)
+
+ // SerializeTextureMappingType
+ WriteInteger (eMappingType) // Texture mapping type
+ // if (eMappingType == TEXTURE_MAPPING_OPERATOR)
+ // {
+ // WriteInteger (eMappingOperator) // Texture mapping operator
+ // WriteInteger (transformation)
+ // if (transformation)
+ // SerializeCartesianTransformation3d (transformation)
+ // }
+
+ WriteUnsignedInteger (texture_mapping_attributes) // Texture mapping attributes
+ WriteUnsignedInteger (size_texture_mapping_attributes_intensities)
+ for (i=0;i<size_texture_mapping_attributes_intensities;i++)
+ WriteDouble (texture_mapping_attributes_intensities[i])
+ WriteUnsignedInteger (size_texture_mapping_attributes_components)
+ for (i=0;i<size_texture_mapping_attributes_components;i++)
+ WriteCharacter (texture_mapping_attributes_components[i])
+
+ WriteInteger (texture_function)
+ // reserved for future use; see Texture function
+ if (texture_function == KEPRCTextureFunction_Blend)
+ {
+ WriteDouble (red) // blend color component in the range [0.0,1.0]
+ WriteDouble (green) // blend color component in the range [0.0,1.0]
+ WriteDouble (blue) // blend color component in the range [0.0,1.0]
+ WriteDouble (alpha) // blend color component in the range [0.0,1.0]
+ }
+
+ WriteInteger (blend_src_rgb) // Texture blend parameter
+ // reserved for future use; see Texture blend parameter
+ if (blend_src_rgb != KEPRCTextureBlendParameter_Unknown)
+ WriteInteger (blend_dst_rgb) // Texture blend parameter
+
+ WriteInteger (blend_src_alpha) // Texture blend parameter
+ // reserved for future use; see Texture blend parameter
+ if (blend_src_alpha != KEPRCTextureBlendParameter_Unknown)
+ WriteInteger (blend_dst_alpha) // Texture blend parameter
+
+ WriteCharacter (texture_applying_mode) // Texture applying mode
+ if (texture_applying_mode & PRC_TEXTURE_APPLYING_MODE_ALPHATEST)
+ {
+ WriteInteger (alpha_test) // Texture alpha test
+ WriteDouble (alpha_test_reference)
+ }
+
+ WriteInteger (texture_wrapping_mode_S) // Texture wrapping mode
+ if (texture_dimension > 1)
+ WriteInteger (texture_wrapping_mode_T) // Texture wrapping mode
+ if (texture_dimension > 2 )
+ WriteInteger (texture_wrapping_mode_R) // Texture wrapping mode
+
+ WriteBit (texture_transformation)
+// if (texture_transformation)
+// SerializeTextureTransformation (texture_transformation)
+}
+
+void PRCMaterialGeneric::serializeMaterialGeneric(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_GRAPH_Material)
+ SerializeContentPRCBase
+ WriteUnsignedInteger (ambient + 1)
+ WriteUnsignedInteger (diffuse + 1)
+ WriteUnsignedInteger (emissive + 1)
+ WriteUnsignedInteger (specular + 1)
+ WriteDouble (shininess)
+ WriteDouble (ambient_alpha)
+ WriteDouble (diffuse_alpha)
+ WriteDouble (emissive_alpha)
+ WriteDouble (specular_alpha)
+}
+
+void PRCTextureApplication::serializeTextureApplication(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_GRAPH_TextureApplication)
+ SerializeContentPRCBase
+
+ WriteUnsignedInteger (material_generic_index+1)
+ WriteUnsignedInteger (texture_definition_index+1)
+ WriteUnsignedInteger (next_texture_index+1)
+ WriteUnsignedInteger (UV_coordinates_index+1)
+}
+
+void PRCLinePattern::serializeLinePattern(PRCbitStream &pbs)
+{
+ uint32_t i = 0;
+ WriteUnsignedInteger (PRC_TYPE_GRAPH_LinePattern)
+ SerializeContentPRCBase
+
+ const uint32_t size_lengths = lengths.size();
+ WriteUnsignedInteger (size_lengths)
+ for (i=0;i<size_lengths;i++)
+ WriteDouble (lengths[i])
+ WriteDouble (phase)
+ WriteBoolean (is_real_length)
+}
+
+
+void PRCStyle::serializeCategory1LineStyle(PRCbitStream &pbs)
+{
+ const bool is_additional_1_defined = (additional!=0);
+ const uint8_t additional_1 = additional;
+ const bool is_additional_2_defined = false;
+ const uint8_t additional_2 = 0;
+ const bool is_additional_3_defined = false;
+ const uint8_t additional_3 = 0;
+ WriteUnsignedInteger (PRC_TYPE_GRAPH_Style)
+ SerializeContentPRCBase
+ WriteDouble (line_width)
+ WriteBoolean (is_vpicture)
+ WriteUnsignedInteger (line_pattern_vpicture_index + 1)
+ WriteBoolean (is_material)
+ WriteUnsignedInteger (color_material_index + 1)
+ WriteBoolean (is_transparency_defined)
+ if (is_transparency_defined)
+ WriteCharacter (transparency)
+ WriteBoolean (is_additional_1_defined)
+ if (is_additional_1_defined)
+ WriteCharacter (additional_1)
+ WriteBoolean (is_additional_2_defined)
+ if (is_additional_2_defined)
+ WriteCharacter (additional_2)
+ WriteBoolean (is_additional_3_defined)
+ if (is_additional_3_defined)
+ WriteCharacter (additional_3)
+}
+
+std::string currentName;
+
+void writeName(PRCbitStream &pbs,const std::string &name)
+{
+ pbs << (name == currentName);
+ if(name != currentName)
+ {
+ pbs << name;
+ currentName = name;
+ }
+}
+
+void resetName()
+{
+ currentName = "";
+}
+
+uint32_t current_layer_index = m1;
+uint32_t current_index_of_line_style = m1;
+uint16_t current_behaviour_bit_field = 1;
+
+void writeGraphics(PRCbitStream &pbs,uint32_t l,uint32_t i,uint16_t b,bool force)
+{
+ if(force || current_layer_index != l || current_index_of_line_style != i || current_behaviour_bit_field != b)
+ {
+ pbs << false << (uint32_t)(l+1) << (uint32_t)(i+1)
+ << (uint8_t)(b&0xFF) << (uint8_t)((b>>8)&0xFF);
+ current_layer_index = l;
+ current_index_of_line_style = i;
+ current_behaviour_bit_field = b;
+ }
+ else
+ pbs << true;
+}
+
+void writeGraphics(PRCbitStream &pbs,const PRCGraphics &graphics,bool force)
+{
+ if(force || current_layer_index != graphics.layer_index || current_index_of_line_style != graphics.index_of_line_style || current_behaviour_bit_field != graphics.behaviour_bit_field)
+ {
+ pbs << false
+ << (uint32_t)(graphics.layer_index+1)
+ << (uint32_t)(graphics.index_of_line_style+1)
+ << (uint8_t)(graphics.behaviour_bit_field&0xFF)
+ << (uint8_t)((graphics.behaviour_bit_field>>8)&0xFF);
+ current_layer_index = graphics.layer_index;
+ current_index_of_line_style = graphics.index_of_line_style;
+ current_behaviour_bit_field = graphics.behaviour_bit_field;
+ }
+ else
+ pbs << true;
+}
+
+void PRCGraphics::serializeGraphics(PRCbitStream &pbs)
+{
+ if(current_layer_index != this->layer_index || current_index_of_line_style != this->index_of_line_style || current_behaviour_bit_field != this->behaviour_bit_field)
+ {
+ pbs << false
+ << (uint32_t)(this->layer_index+1)
+ << (uint32_t)(this->index_of_line_style+1)
+ << (uint8_t)(this->behaviour_bit_field&0xFF)
+ << (uint8_t)((this->behaviour_bit_field>>8)&0xFF);
+ current_layer_index = this->layer_index;
+ current_index_of_line_style = this->index_of_line_style;
+ current_behaviour_bit_field = this->behaviour_bit_field;
+ }
+ else
+ pbs << true;
+}
+
+void PRCGraphics::serializeGraphicsForced(PRCbitStream &pbs)
+{
+ pbs << false
+ << (uint32_t)(this->layer_index+1)
+ << (uint32_t)(this->index_of_line_style+1)
+ << (uint8_t)(this->behaviour_bit_field&0xFF)
+ << (uint8_t)((this->behaviour_bit_field>>8)&0xFF);
+ current_layer_index = this->layer_index;
+ current_index_of_line_style = this->index_of_line_style;
+ current_behaviour_bit_field = this->behaviour_bit_field;
+}
+
+void resetGraphics()
+{
+ current_layer_index = m1;
+ current_index_of_line_style = m1;
+ current_behaviour_bit_field = 1;
+}
+
+void resetGraphicsAndName()
+{
+ resetGraphics(); resetName();
+}
+
+void PRCMarkup::serializeMarkup(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_MKP_Markup)
+ SerializeContentPRCBase
+ SerializeGraphics
+ WriteUnsignedInteger (type)
+ WriteUnsignedInteger (sub_type)
+ const uint32_t number_of_linked_items = 0;
+ WriteUnsignedInteger (number_of_linked_items)
+// for (i=0;i<number_of_linked_items;i++)
+// SerializeReferenceUniqueIdentifier (linked_items[i])
+ const uint32_t number_of_leaders = 0;
+ WriteUnsignedInteger (number_of_leaders)
+// for (i=0;i<number_of_leaders;i++)
+// SerializeReferenceUniqueIdentifier (leaders[i])
+ WriteUnsignedInteger (index_tessellation + 1)
+ SerializeUserData
+}
+
+void PRCAnnotationItem::serializeAnnotationItem(PRCbitStream &pbs)
+{
+// group___tf_annotation_item_____serialize2.html
+// group___tf_annotation_item_____serialize_content2.html
+// group___tf_annotation_entity_____serialize_content2.html
+ WriteUnsignedInteger (PRC_TYPE_MKP_AnnotationItem)
+ SerializeContentPRCBase
+ SerializeGraphics
+ SerializeReferenceUniqueIdentifier (markup)
+ SerializeUserData
+}
+
+void PRCRepresentationItemContent::serializeRepresentationItemContent(PRCbitStream &pbs)
+{
+ SerializeContentPRCBase
+ SerializeGraphics
+ WriteUnsignedInteger (index_local_coordinate_system + 1)
+ WriteUnsignedInteger (index_tessellation + 1)
+}
+
+void PRCBrepModel::serializeBrepModel(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_RI_BrepModel)
+
+ SerializeRepresentationItemContent
+ WriteBit (has_brep_data)
+ if (has_brep_data)
+ {
+ WriteUnsignedInteger (context_id+1)
+ WriteUnsignedInteger (body_id+1)
+ }
+ WriteBoolean (is_closed)
+ SerializeUserData
+}
+
+void PRCPolyBrepModel::serializePolyBrepModel(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_RI_PolyBrepModel)
+
+ SerializeRepresentationItemContent
+ WriteBoolean (is_closed)
+ SerializeUserData
+}
+
+void PRCPointSet::serializePointSet(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_RI_PointSet)
+
+ SerializeRepresentationItemContent
+
+ const uint32_t number_of_points = point.size();
+ WriteUnsignedInteger (number_of_points)
+ for (uint32_t i=0;i<number_of_points;i++)
+ {
+ SerializeVector3d (point[i])
+ }
+ SerializeUserData
+}
+
+void PRCSet::serializeSet(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_RI_Set)
+
+ SerializeRepresentationItemContent
+
+ const uint32_t number_of_elements = elements.size();
+ WriteUnsignedInteger (number_of_elements)
+ for (uint32_t i=0;i<number_of_elements;i++)
+ {
+ SerializeRepresentationItem (elements[i])
+ }
+ SerializeUserData
+}
+
+uint32_t PRCSet::addBrepModel(PRCBrepModel*& pBrepModel)
+{
+ elements.push_back(pBrepModel);
+ pBrepModel = NULL;
+ return elements.size()-1;
+}
+
+uint32_t PRCSet::addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel)
+{
+ elements.push_back(pPolyBrepModel);
+ pPolyBrepModel = NULL;
+ return elements.size()-1;
+}
+
+uint32_t PRCSet::addPointSet(PRCPointSet*& pPointSet)
+{
+ elements.push_back(pPointSet);
+ pPointSet = NULL;
+ return elements.size()-1;
+}
+
+uint32_t PRCSet::addSet(PRCSet*& pSet)
+{
+ elements.push_back(pSet);
+ pSet = NULL;
+ return elements.size()-1;
+}
+
+uint32_t PRCSet::addWire(PRCWire*& pWire)
+{
+ elements.push_back(pWire);
+ pWire = NULL;
+ return elements.size()-1;
+}
+
+uint32_t PRCSet::addPolyWire(PRCPolyWire*& pPolyWire)
+{
+ elements.push_back(pPolyWire);
+ pPolyWire = NULL;
+ return elements.size()-1;
+}
+
+uint32_t PRCSet::addRepresentationItem(PRCRepresentationItem*& pRepresentationItem)
+{
+ elements.push_back(pRepresentationItem);
+ pRepresentationItem = NULL;
+ return elements.size()-1;
+}
+
+void PRCWire::serializeWire(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_RI_Curve)
+
+ SerializeRepresentationItemContent
+ WriteBit (has_wire_body)
+ if (has_wire_body)
+ {
+ WriteUnsignedInteger (context_id+1)
+ WriteUnsignedInteger (body_id+1)
+ }
+
+ SerializeUserData
+}
+
+void PRCPolyWire::serializePolyWire(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_RI_PolyWire)
+
+ SerializeRepresentationItemContent
+ SerializeUserData
+}
+
+void PRCGeneralTransformation3d::serializeGeneralTransformation3d(PRCbitStream &pbs) const
+{
+ WriteUnsignedInteger (PRC_TYPE_MISC_GeneralTransformation)
+ // Like Fortran, PRC uses transposed (column-major) format!
+ for (int j=0;j<4;j++)
+ for (int i=0;i<4;i++)
+ WriteDouble(mat[i][j]);
+}
+
+void PRCCartesianTransformation3d::serializeCartesianTransformation3d(PRCbitStream &pbs) const
+{
+ WriteUnsignedInteger (PRC_TYPE_MISC_CartesianTransformation)
+ WriteCharacter ( behaviour )
+ if (behaviour & PRC_TRANSFORMATION_Translate)
+ SerializeVector3d ( origin )
+ if (behaviour & PRC_TRANSFORMATION_NonOrtho)
+ {
+ SerializeVector3d ( X )
+ SerializeVector3d ( Y )
+ SerializeVector3d ( Z )
+ }
+ else if (behaviour & PRC_TRANSFORMATION_Rotate)
+ {
+ SerializeVector3d ( X )
+ SerializeVector3d ( Y )
+ }
+
+ if (behaviour & PRC_TRANSFORMATION_NonUniformScale)
+ {
+ SerializeVector3d ( scale )
+ }
+ else if (behaviour & PRC_TRANSFORMATION_Scale)
+ {
+ WriteDouble ( uniform_scale )
+ }
+
+ if (behaviour & PRC_TRANSFORMATION_Homogeneous)
+ {
+ WriteDouble ( X_homogeneous_coord )
+ WriteDouble ( Y_homogeneous_coord )
+ WriteDouble ( Z_homogeneous_coord )
+ WriteDouble ( origin_homogeneous_coord )
+ }
+}
+
+void PRCTransformation::serializeTransformation(PRCbitStream &pbs)
+{
+ WriteBit ( has_transformation )
+ if (has_transformation)
+ {
+ WriteCharacter ( behaviour )
+ if ( geometry_is_2D )
+ {
+ if (behaviour & PRC_TRANSFORMATION_Translate)
+ SerializeVector2d ( origin )
+ if (behaviour & PRC_TRANSFORMATION_Rotate)
+ {
+ SerializeVector2d ( x_axis )
+ SerializeVector2d ( y_axis )
+ }
+ if (behaviour & PRC_TRANSFORMATION_Scale)
+ WriteDouble ( scale )
+ }
+ else
+ {
+ if (behaviour & PRC_TRANSFORMATION_Translate)
+ SerializeVector3d ( origin )
+ if (behaviour & PRC_TRANSFORMATION_Rotate)
+ {
+ SerializeVector3d ( x_axis )
+ SerializeVector3d ( y_axis )
+ }
+ if (behaviour & PRC_TRANSFORMATION_Scale)
+ WriteDouble ( scale )
+ }
+ }
+}
+void PRCCoordinateSystem::serializeCoordinateSystem(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_RI_CoordinateSystem)
+
+ SerializeRepresentationItemContent
+ axis_set->serializeTransformation3d(pbs);
+ SerializeUserData
+}
+
+void PRCFontKeysSameFont::serializeFontKeysSameFont(PRCbitStream &pbs)
+{
+ uint32_t i=0; // universal index for PRC standart compatibility
+ WriteString (font_name)
+ WriteUnsignedInteger (char_set)
+ const uint32_t number_of_font_keys = font_keys.size();
+ WriteUnsignedInteger (number_of_font_keys)
+ for (i=0;i<number_of_font_keys;i++)
+ {
+ WriteUnsignedInteger (font_keys[i].font_size + 1)
+ WriteCharacter (font_keys[i].attributes)
+ }
+}
+
+void SerializeArrayRGBA (const std::vector<uint8_t> &rgba_vertices,const bool is_rgba, PRCbitStream &pbs)
+{
+ uint32_t i = 0;
+ uint32_t j = 0;
+// number_by_vector can be assigned a value of 3 (RGB) or 4 (RGBA).
+// number_of_vectors is equal to number_of_colors / number_by_vector.
+ const uint32_t number_by_vector=is_rgba?4:3;
+ const std::vector<uint8_t> &vector_color = rgba_vertices;
+ const uint32_t number_of_colors=vector_color.size();
+ const uint32_t number_of_vectors=number_of_colors / number_by_vector;
+ // first one
+ for (i=0;i<number_by_vector;i++)
+ WriteCharacter (vector_color[i])
+
+ for (i=1;i<number_of_vectors;i++)
+ {
+ bool b_same = true;
+ for (j=0;j<number_by_vector;j++)
+ {
+ if ((vector_color[i*number_by_vector+j] - vector_color[(i-1)*number_by_vector+j]) != 0)
+ {
+ b_same = false;
+ break;
+ }
+ }
+ WriteBoolean (b_same)
+ if (!b_same)
+ {
+ for (j=0;j<number_by_vector;j++)
+ WriteCharacter (vector_color[i*number_by_vector+j])
+ }
+ }
+}
+
+void PRCTessFace::serializeTessFace(PRCbitStream &pbs)
+{
+ uint32_t i=0; // universal index for PRC standart compatibility
+ WriteUnsignedInteger (PRC_TYPE_TESS_Face)
+
+ const uint32_t size_of_line_attributes=line_attributes.size();
+ WriteUnsignedInteger (size_of_line_attributes)
+ for (i=0;i<size_of_line_attributes;i++)
+ SerializeLineAttr (line_attributes[i])
+
+ WriteUnsignedInteger (start_wire)
+ const uint32_t size_of_sizes_wire=sizes_wire.size();
+ WriteUnsignedInteger (size_of_sizes_wire)
+ for (i=0;i<size_of_sizes_wire;i++)
+ WriteUnsignedInteger (sizes_wire[i])
+
+ WriteUnsignedInteger (used_entities_flag)
+
+ WriteUnsignedInteger (start_triangulated)
+ const uint32_t size_of_sizes_triangulated=sizes_triangulated.size();
+ WriteUnsignedInteger (size_of_sizes_triangulated)
+ for (i=0;i<size_of_sizes_triangulated;i++)
+ WriteUnsignedInteger (sizes_triangulated[i])
+
+ if(number_of_texture_coordinate_indexes==0 &&
+ used_entities_flag &
+ (
+ PRC_FACETESSDATA_PolyfaceTextured|
+ PRC_FACETESSDATA_TriangleTextured|
+ PRC_FACETESSDATA_TriangleFanTextured|
+ PRC_FACETESSDATA_TriangleStripeTextured|
+ PRC_FACETESSDATA_PolyfaceOneNormalTextured|
+ PRC_FACETESSDATA_TriangleOneNormalTextured|
+ PRC_FACETESSDATA_TriangleFanOneNormalTextured|
+ PRC_FACETESSDATA_TriangleStripeOneNormalTextured
+ ))
+ WriteUnsignedInteger (1) // workaround for error of not setting number_of_texture_coordinate_indexes
+ else
+ WriteUnsignedInteger (number_of_texture_coordinate_indexes)
+
+ const bool has_vertex_colors = !rgba_vertices.empty();
+ WriteBoolean (has_vertex_colors)
+ if (has_vertex_colors)
+ {
+ WriteBoolean (is_rgba)
+ const bool b_optimised=false;
+ WriteBoolean (b_optimised)
+ if (!b_optimised)
+ {
+ SerializeArrayRGBA (rgba_vertices, is_rgba, pbs);
+ }
+ else
+ {
+ // not described
+ }
+ }
+ if (size_of_line_attributes)
+ WriteUnsignedInteger (behaviour)
+}
+
+void PRCContentBaseTessData::serializeContentBaseTessData(PRCbitStream &pbs)
+{
+ uint32_t i=0; // universal index for PRC standart compatibility
+ WriteBoolean (is_calculated)
+ const uint32_t number_of_coordinates = coordinates.size();
+ WriteUnsignedInteger (number_of_coordinates)
+ for (i=0;i<number_of_coordinates;i++)
+ WriteDouble (coordinates[i])
+}
+
+void PRC3DTess::serialize3DTess(PRCbitStream &pbs)
+{
+ uint32_t i=0; // universal index for PRC standart compatibility
+ WriteUnsignedInteger (PRC_TYPE_TESS_3D)
+ SerializeContentBaseTessData
+ WriteBoolean (has_faces)
+ WriteBoolean (has_loops)
+ const bool must_recalculate_normals=normal_coordinate.empty();
+ WriteBoolean (must_recalculate_normals)
+ if (must_recalculate_normals)
+ {
+ const uint8_t normals_recalculation_flags=0;
+ // not used; should be zero
+ WriteCharacter (normals_recalculation_flags)
+ // definition similar to VRML
+ WriteDouble (crease_angle)
+ }
+
+ const uint32_t number_of_normal_coordinates=normal_coordinate.size();
+ WriteUnsignedInteger (number_of_normal_coordinates)
+ for (i=0;i<number_of_normal_coordinates;i++)
+ WriteDouble (normal_coordinate[i])
+
+ const uint32_t number_of_wire_indices=wire_index.size();
+ WriteUnsignedInteger (number_of_wire_indices)
+ for (i=0;i<number_of_wire_indices;i++)
+ WriteUnsignedInteger (wire_index[i])
+
+ // note : those can be single triangles, triangle fans or stripes
+ const uint32_t number_of_triangulated_indices=triangulated_index.size();
+ WriteUnsignedInteger (number_of_triangulated_indices)
+ for (i=0;i<number_of_triangulated_indices;i++)
+ WriteUnsignedInteger (triangulated_index[i])
+
+ const uint32_t number_of_face_tessellation=face_tessellation.size();
+ WriteUnsignedInteger (number_of_face_tessellation)
+ for (i=0;i<number_of_face_tessellation;i++)
+ SerializeTessFace (face_tessellation[i])
+
+ const uint32_t number_of_texture_coordinates=texture_coordinate.size();
+ WriteUnsignedInteger (number_of_texture_coordinates)
+ for (i=0;i<number_of_texture_coordinates;i++)
+ WriteDouble (texture_coordinate[i])
+}
+
+void PRC3DTess::addTessFace(PRCTessFace*& pTessFace)
+{
+ face_tessellation.push_back(pTessFace);
+ pTessFace = NULL;
+}
+
+void PRC3DWireTess::serialize3DWireTess(PRCbitStream &pbs)
+{
+// group___tf3_d_wire_tess_data_____serialize2.html
+// group___tf3_d_wire_tess_data_____serialize_content2.html
+ uint32_t i=0; // universal index for PRC standart compatibility
+ WriteUnsignedInteger (PRC_TYPE_TESS_3D_Wire)
+ SerializeContentBaseTessData
+ const uint32_t number_of_wire_indexes=wire_indexes.size();
+ WriteUnsignedInteger (number_of_wire_indexes)
+ for (i=0;i<number_of_wire_indexes;i++)
+ WriteUnsignedInteger (wire_indexes[i])
+
+ const bool has_vertex_colors = !rgba_vertices.empty();
+ WriteBoolean (has_vertex_colors)
+ if (has_vertex_colors)
+ {
+ WriteBoolean (is_rgba)
+ WriteBoolean (is_segment_color)
+ const bool b_optimised=false;
+ WriteBoolean (b_optimised)
+ if (!b_optimised)
+ {
+ SerializeArrayRGBA (rgba_vertices, is_rgba, pbs);
+ }
+ else
+ {
+ // not described
+ }
+ }
+}
+
+void PRCMarkupTess::serializeMarkupTess(PRCbitStream &pbs)
+{
+// group___tf_markup_tess_data_____serialize2.html
+// group___tf_markup_tess_data_____serialize_content2.html
+ uint32_t i=0; // universal index for PRC standart compatibility
+ WriteUnsignedInteger (PRC_TYPE_TESS_Markup)
+ SerializeContentBaseTessData
+
+ const uint32_t number_of_codes=codes.size();
+ WriteUnsignedInteger (number_of_codes)
+ for (i=0;i<number_of_codes;i++)
+ WriteUnsignedInteger (codes[i])
+ const uint32_t number_of_texts=texts.size();
+ WriteUnsignedInteger (number_of_texts)
+ for (i=0;i<number_of_texts;i++)
+ WriteString (texts[i])
+ WriteString (label) // label of tessellation
+ WriteCharacter (behaviour)
+}
+
+void writeUnit(PRCbitStream &out,bool fromCAD,double unit)
+{
+ out << fromCAD << unit;
+}
+
+void writeEmptyMarkups(PRCbitStream &out)
+{
+ out << (uint32_t)0 // # of linked items
+ << (uint32_t)0 // # of leaders
+ << (uint32_t)0 // # of markups
+ << (uint32_t)0; // # of annotation entities
+}
+
+void PRCBaseTopology::serializeBaseTopology(PRCbitStream &pbs)
+{
+ WriteBoolean (base_information)
+ if (base_information)
+ {
+ SerializeAttributeData
+ SerializeName (name)
+ WriteUnsignedInteger (identifier)
+ }
+}
+
+void PRCBaseGeometry::serializeBaseGeometry(PRCbitStream &pbs)
+{
+ WriteBoolean (base_information)
+ if (base_information)
+ {
+ SerializeAttributeData
+ SerializeName (name)
+ WriteUnsignedInteger (identifier)
+ }
+}
+
+void PRCContentBody::serializeContentBody(PRCbitStream &pbs)
+{
+ SerializeBaseTopology
+ WriteCharacter ( behavior )
+}
+
+void PRCBoundingBox::serializeBoundingBox(PRCbitStream &pbs)
+{
+ SerializeVector3d ( min )
+ SerializeVector3d ( max )
+}
+
+void PRCDomain::serializeDomain(PRCbitStream &pbs)
+{
+ SerializeVector2d ( min )
+ SerializeVector2d ( max )
+}
+
+void PRCInterval::serializeInterval(PRCbitStream &pbs)
+{
+ WriteDouble ( min )
+ WriteDouble ( max )
+}
+
+void PRCParameterization::serializeParameterization(PRCbitStream &pbs)
+{
+ SerializeInterval ( interval )
+ WriteDouble ( parameterization_coeff_a )
+ WriteDouble ( parameterization_coeff_b )
+}
+
+void PRCUVParameterization::serializeUVParameterization(PRCbitStream &pbs)
+{
+ WriteBoolean ( swap_uv )
+ SerializeDomain ( uv_domain )
+ WriteDouble ( parameterization_on_u_coeff_a )
+ WriteDouble ( parameterization_on_v_coeff_a )
+ WriteDouble ( parameterization_on_u_coeff_b )
+ WriteDouble ( parameterization_on_v_coeff_b )
+}
+
+void PRCContentSurface::serializeContentSurface(PRCbitStream &pbs)
+{
+ SerializeBaseGeometry
+ WriteUnsignedInteger ( extend_info )
+}
+
+void PRCNURBSSurface::serializeNURBSSurface(PRCbitStream &pbs)
+{
+ uint32_t i=0;
+// uint32_t i=0, j=0;
+ WriteUnsignedInteger (PRC_TYPE_SURF_NURBS)
+
+ SerializeContentSurface
+ WriteBoolean ( is_rational )
+ WriteUnsignedInteger ( degree_in_u )
+ WriteUnsignedInteger ( degree_in_v )
+ const uint32_t highest_index_of_knots_in_u = knot_u.size()-1;
+ const uint32_t highest_index_of_knots_in_v = knot_v.size()-1;
+ const uint32_t highest_index_of_control_point_in_u = highest_index_of_knots_in_u - degree_in_u - 1;
+ const uint32_t highest_index_of_control_point_in_v = highest_index_of_knots_in_v - degree_in_v - 1;
+ WriteUnsignedInteger ( highest_index_of_control_point_in_u )
+ WriteUnsignedInteger ( highest_index_of_control_point_in_v )
+ WriteUnsignedInteger ( highest_index_of_knots_in_u )
+ WriteUnsignedInteger ( highest_index_of_knots_in_v )
+ for (i=0; i < (highest_index_of_control_point_in_u+1)*(highest_index_of_control_point_in_v+1); i++)
+ {
+ WriteDouble ( control_point[i].x )
+ WriteDouble ( control_point[i].y )
+ WriteDouble ( control_point[i].z )
+ if (is_rational)
+ WriteDouble ( control_point[i].w )
+ }
+// for (i=0; i<=highest_index_of_control_point_in_u; i++)
+// {
+// for (j=0; j<=highest_index_of_control_point_in_v; j++)
+// {
+// WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].x )
+// WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].y )
+// WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].z )
+// if (is_rational)
+// WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].w )
+// }
+// }
+ for (i=0; i<=highest_index_of_knots_in_u; i++)
+ WriteDouble ( knot_u[i] )
+ for (i=0; i<=highest_index_of_knots_in_v; i++)
+ WriteDouble ( knot_v[i] )
+ WriteUnsignedInteger ( knot_type )
+ WriteUnsignedInteger ( surface_form )
+}
+
+void writeUnsignedIntegerWithVariableBitNumber(PRCbitStream &pbs, uint32_t value, uint32_t bit_number)
+{
+ uint32_t i;
+ for(i=0; i<bit_number; i++)
+ {
+ if( value >= 1u<<(bit_number - 1 - i) )
+ {
+ WriteBoolean (true)
+
+ value -= 1u<<(bit_number - 1 - i);
+ }
+ else
+ {
+ WriteBoolean (false)
+ }
+ }
+}
+#define WriteUnsignedIntegerWithVariableBitNumber( value, bit_number ) writeUnsignedIntegerWithVariableBitNumber( pbs, (value), (bit_number) );
+
+void writeIntegerWithVariableBitNumber(PRCbitStream &pbs, int32_t iValue, uint32_t uBitNumber)
+{
+ WriteBoolean(iValue<0);
+ WriteUnsignedIntegerWithVariableBitNumber(abs(iValue), uBitNumber - 1);
+}
+#define WriteIntegerWithVariableBitNumber( value, bit_number ) writeIntegerWithVariableBitNumber( pbs, (value), (bit_number) );
+
+void writeDoubleWithVariableBitNumber(PRCbitStream &pbs, double dValue,double dTolerance, unsigned uBitNumber)
+{
+// calling functions must ensure no overflow
+ int32_t iTempValue = (int32_t) ( dValue / dTolerance );
+ WriteIntegerWithVariableBitNumber(iTempValue, uBitNumber);
+}
+#define WriteDoubleWithVariableBitNumber( value, bit_number ) writeDoubleWithVariableBitNumber( pbs, (value), (bit_number) );
+
+uint32_t GetNumberOfBitsUsedToStoreUnsignedInteger(uint32_t uValue)
+{
+ uint32_t uNbBit=2;
+ uint32_t uTemp = 2;
+ while(uValue >= uTemp)
+ {
+ uTemp*=2;
+ uNbBit++;
+ }
+ return uNbBit-1;
+}
+
+void writeNumberOfBitsThenUnsignedInteger(PRCbitStream &pbs, uint32_t unsigned_integer)
+{
+ uint32_t number_of_bits = GetNumberOfBitsUsedToStoreUnsignedInteger( unsigned_integer );
+ WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits, 5 )
+ WriteUnsignedIntegerWithVariableBitNumber ( unsigned_integer, number_of_bits )
+}
+#define WriteNumberOfBitsThenUnsignedInteger( value ) writeNumberOfBitsThenUnsignedInteger( pbs, value );
+
+uint32_t GetNumberOfBitsUsedToStoreInteger(int32_t iValue)
+{
+ return GetNumberOfBitsUsedToStoreUnsignedInteger(abs(iValue))+1;
+}
+
+int32_t intdiv(double dValue, double dTolerance)
+{
+ double ratio=fabs(dValue)/dTolerance;
+ assert(ratio <= INT_MAX);
+ int32_t iTempValue=(int32_t) ratio;
+ if(ratio - iTempValue >= 0.5) iTempValue++;
+ if(dValue < 0)
+ return -iTempValue;
+ else
+ return iTempValue;
+}
+
+// round dValue to nearest multiple of dTolerance
+double roundto(double dValue, double dTolerance)
+{
+ return intdiv(dValue, dTolerance) * dTolerance;
+}
+
+PRCVector3d roundto(PRCVector3d vec, double dTolerance)
+{
+ PRCVector3d res;
+ res.x = roundto(vec.x,dTolerance);
+ res.y = roundto(vec.y,dTolerance);
+ res.z = roundto(vec.z,dTolerance);
+ return res;
+}
+
+uint32_t GetNumberOfBitsUsedToStoreDouble(double dValue, double dTolerance )
+{
+ return GetNumberOfBitsUsedToStoreInteger(intdiv(dValue,dTolerance));
+}
+
+struct itriple
+{
+ int32_t x;
+ int32_t y;
+ int32_t z;
+};
+
+uint32_t GetNumberOfBitsUsedToStoreTripleInteger(const itriple &iTriple)
+{
+ const uint32_t x_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.x);
+ const uint32_t y_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.y);
+ const uint32_t z_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.z);
+ uint32_t bits = x_bits;
+ if(y_bits > bits)
+ bits = y_bits;
+ if(z_bits > bits)
+ bits = z_bits;
+ return bits;
+}
+
+itriple iroundto(PRCVector3d vec, double dTolerance)
+{
+ itriple res;
+ res.x = intdiv(vec.x, dTolerance);
+ res.y = intdiv(vec.y, dTolerance);
+ res.z = intdiv(vec.z, dTolerance);
+ return res;
+}
+
+void PRCCompressedFace::serializeCompressedFace(PRCbitStream &pbs, double brep_data_compressed_tolerance)
+{
+ serializeCompressedAnaNurbs( pbs, brep_data_compressed_tolerance );
+}
+#define SerializeCompressedFace( value ) (value)->serializeCompressedFace( pbs, brep_data_compressed_tolerance );
+
+void PRCCompressedFace::serializeContentCompressedFace(PRCbitStream &pbs)
+{
+ WriteBoolean ( orientation_surface_with_shell )
+ const bool surface_is_trimmed = false;
+ WriteBoolean ( surface_is_trimmed )
+}
+
+void PRCCompressedFace::serializeCompressedAnaNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance)
+{
+ // WriteCompressedEntityType ( PRC_HCG_AnaNurbs )
+ const bool is_a_curve = false;
+ WriteBoolean ( is_a_curve )
+ WriteUnsignedIntegerWithVariableBitNumber (13 , 4)
+ serializeContentCompressedFace( pbs );
+ serializeCompressedNurbs( pbs, brep_data_compressed_tolerance );
+}
+
+void PRCCompressedFace::serializeCompressedNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance)
+{
+ const double nurbs_tolerance = 0.2*brep_data_compressed_tolerance;
+ const uint32_t degree_in_u = degree;
+ const uint32_t degree_in_v = degree;
+
+ WriteUnsignedIntegerWithVariableBitNumber ( degree_in_u, 5)
+ WriteUnsignedIntegerWithVariableBitNumber ( degree_in_v, 5)
+
+ const uint32_t number_of_knots_in_u = 4; // 0011 or 00001111 knot vector - just 2 spans
+ WriteUnsignedIntegerWithVariableBitNumber (number_of_knots_in_u - 2, 16)
+ uint32_t number_bit = degree_in_u ? Log2( degree_in_u + 2 ) : 2;
+ WriteBoolean (false) // Multiplicity_is_already_stored - no
+ WriteUnsignedIntegerWithVariableBitNumber( degree_in_u+1,number_bit)
+ WriteBoolean (true) // Multiplicity_is_already_stored - yes
+ const uint32_t number_of_knots_in_v = 4; // 0011 or 00001111 knot vector - just 2 spans
+ WriteUnsignedIntegerWithVariableBitNumber (number_of_knots_in_v - 2, 16)
+ number_bit = degree_in_v ? Log2( degree_in_v + 2 ) : 2;
+ WriteBoolean (false) // Multiplicity_is_already_stored - no
+ WriteUnsignedIntegerWithVariableBitNumber( degree_in_v+1,number_bit)
+ WriteBoolean (true) // Multiplicity_is_already_stored - yes
+
+ const bool is_closed_u = false;
+ WriteBoolean ( is_closed_u )
+ const bool is_closed_v = false;
+ WriteBoolean ( is_closed_v )
+
+ const uint32_t number_of_control_point_in_u = degree_in_u + 1;
+ const uint32_t number_of_control_point_in_v = degree_in_v + 1;
+
+#if defined(__GNUC__) && !defined(__clang__)
+ PRCVector3d P[number_of_control_point_in_u][number_of_control_point_in_v];
+#else
+ vector<vector<PRCVector3d> > P(number_of_control_point_in_u, vector<PRCVector3d>(number_of_control_point_in_v));
+#endif
+ for(uint32_t i=0;i<number_of_control_point_in_u;i++)
+ for(uint32_t j=0;j<number_of_control_point_in_v;j++)
+ P[i][j] = control_point[i*number_of_control_point_in_v+j];
+#ifdef __GNUC__
+ itriple compressed_control_point[number_of_control_point_in_u][number_of_control_point_in_v];
+ uint32_t control_point_type[number_of_control_point_in_u][number_of_control_point_in_v];
+#else
+ vector<vector<itriple> > compressed_control_point(number_of_control_point_in_u, vector<itriple>(number_of_control_point_in_v));
+ vector<vector<uint32_t> > control_point_type(number_of_control_point_in_u, vector<uint32_t>(number_of_control_point_in_v));
+#endif
+
+ uint32_t number_of_bits_for_isomin = 1;
+ uint32_t number_of_bits_for_rest = 1;
+
+ for(uint32_t j = 1; j < number_of_control_point_in_v; j++)
+ {
+ compressed_control_point[0][j] = iroundto(P[0][j]-P[0][j-1], nurbs_tolerance );
+ P[0][j] = P[0][j-1] + roundto(P[0][j]-P[0][j-1], nurbs_tolerance);
+ uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[0][j]);
+ if (bit_size > number_of_bits_for_isomin)
+ number_of_bits_for_isomin = bit_size;
+ }
+
+ for(uint32_t i = 1; i < number_of_control_point_in_u; i++)
+ {
+ compressed_control_point[i][0] = iroundto(P[i][0]-P[i-1][0], nurbs_tolerance );
+ P[i][0] = P[i-1][0] + roundto(P[i][0]-P[i-1][0], nurbs_tolerance);
+ uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[i][0]);
+ if (bit_size > number_of_bits_for_isomin)
+ number_of_bits_for_isomin = bit_size;
+ }
+
+ for(uint32_t i=1;i<number_of_control_point_in_u;i++)
+ for(uint32_t j=1;j<number_of_control_point_in_v;j++)
+ {
+ compressed_control_point[i][j].x = 0;
+ compressed_control_point[i][j].y = 0;
+ compressed_control_point[i][j].z = 0;
+
+ PRCVector3d V = P[i-1][j] - P[i-1][j-1];
+ PRCVector3d U = P[i][j-1] - P[i-1][j-1];
+ PRCVector3d Pc = P[i][j] - (P[i-1][j-1] + U + V);
+
+ if(Pc.Length() < nurbs_tolerance)
+ {
+ control_point_type[i][j] = 0;
+ P[i][j] = P[i-1][j-1] + U + V;
+ }
+ else
+ {
+ PRCVector3d N = U*V;
+ PRCVector3d Ue = U;
+ PRCVector3d Ne = N;
+ if( V.Length() < FLT_EPSILON || !Ue.Normalize() || !Ne.Normalize())
+ {
+ control_point_type[i][j] = 3;
+ // Pc = roundto(Pc, nurbs_tolerance); // not sure if this rounding really happens, need to experiment, docs imply but do not state
+ compressed_control_point[i][j] = iroundto(Pc, nurbs_tolerance);
+ P[i][j] = P[i-1][j-1] + U + V + roundto(Pc, nurbs_tolerance); // see above
+ }
+ else
+ {
+ PRCVector3d NUe = Ne*Ue;
+ double x = Pc.Dot(Ue);
+ double y = Pc.Dot(NUe);
+ double z = Pc.Dot(Ne);
+
+ if(x*x+y*y<nurbs_tolerance*nurbs_tolerance)
+ {
+ control_point_type[i][j] = 1;
+ compressed_control_point[i][j] = iroundto(PRCVector3d(0.0,0.0,z), nurbs_tolerance);
+ P[i][j] = P[i-1][j-1] + U + V + roundto(z, nurbs_tolerance)*Ne; // see above
+ }
+ else
+ {
+ if(fabs(z)<nurbs_tolerance/2)
+ {
+ control_point_type[i][j] = 2;
+ compressed_control_point[i][j] = iroundto(PRCVector3d(x,y,0), nurbs_tolerance);
+ P[i][j] = P[i-1][j-1] + U + V + roundto(x, nurbs_tolerance)*Ue + roundto(y, nurbs_tolerance)*NUe; // see above
+ }
+ else
+ {
+ control_point_type[i][j] = 3;
+ compressed_control_point[i][j] = iroundto(Pc, nurbs_tolerance);
+ P[i][j] = P[i-1][j-1] + U + V + roundto(Pc, nurbs_tolerance); // see above
+ }
+ }
+ }
+ }
+ uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[i][j]);
+ if (bit_size > number_of_bits_for_rest)
+ number_of_bits_for_rest = bit_size;
+ }
+
+ if( number_of_bits_for_rest == 2 ) number_of_bits_for_rest--; // really I think it must be unconditional, but so it seems to be done in Adobe Acrobat (9.3)
+ WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits_for_isomin, 20 )
+ WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits_for_rest, 20 )
+ WriteDouble ( P[0][0].x )
+ WriteDouble ( P[0][0].y )
+ WriteDouble ( P[0][0].z )
+
+ for(uint32_t j = 1; j < number_of_control_point_in_v; j++)
+ {
+ WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].x, number_of_bits_for_isomin+1)
+ WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].y, number_of_bits_for_isomin+1)
+ WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].z, number_of_bits_for_isomin+1)
+ }
+
+ for(uint32_t i = 1; i < number_of_control_point_in_u; i++)
+ {
+ WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].x, number_of_bits_for_isomin+1)
+ WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].y, number_of_bits_for_isomin+1)
+ WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].z, number_of_bits_for_isomin+1)
+ }
+
+ for(uint32_t i = 1; i < number_of_control_point_in_u; i++)
+ {
+ for(uint32_t j = 1; j < number_of_control_point_in_v; j++)
+ {
+ WriteUnsignedIntegerWithVariableBitNumber ( control_point_type[i][j], 2 )
+
+ if(control_point_type[i][j] == 1)
+ {
+ WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].z, number_of_bits_for_rest+1 )
+ }
+ else if(control_point_type[i][j] == 2)
+ {
+ WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].x, number_of_bits_for_rest+1 )
+ WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].y, number_of_bits_for_rest+1 )
+ }
+ else if(control_point_type[i][j] == 3)
+ {
+ WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].x, number_of_bits_for_rest+1 )
+ WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].y, number_of_bits_for_rest+1 )
+ WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].z, number_of_bits_for_rest+1 )
+ }
+ }
+ }
+
+ const uint32_t type_param_u = 0;
+ WriteBoolean( type_param_u == 0 )
+ const uint32_t type_param_v = 0;
+ WriteBoolean( type_param_v == 0 )
+ const bool is_rational = false;
+ WriteBoolean( is_rational )
+}
+
+void PRCCompressedBrepData::serializeCompressedShell(PRCbitStream &pbs)
+{
+ uint32_t i;
+ const uint32_t number_of_face = face.size();
+ WriteBoolean ( number_of_face == 1 )
+
+ if( number_of_face != 1 )
+ WriteNumberOfBitsThenUnsignedInteger (number_of_face)
+
+ for( i=0; i < number_of_face; i++)
+ SerializeCompressedFace ( face[i] )
+
+ const bool is_an_iso_face = false;
+ for( i=0; i < number_of_face; i++)
+ WriteBoolean ( is_an_iso_face )
+}
+
+void PRCCompressedBrepData::serializeCompressedBrepData(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger ( PRC_TYPE_TOPO_BrepDataCompress )
+ SerializeContentBody
+
+ WriteDouble ( brep_data_compressed_tolerance )
+ const uint32_t number_of_bits_to_store_reference = 1;
+ WriteNumberOfBitsThenUnsignedInteger ( number_of_bits_to_store_reference )
+ const uint32_t number_vertex_iso = 0;
+ WriteUnsignedIntegerWithVariableBitNumber ( number_vertex_iso, number_of_bits_to_store_reference )
+ const uint32_t number_edge_iso = 0;
+ WriteUnsignedIntegerWithVariableBitNumber ( number_edge_iso, number_of_bits_to_store_reference )
+
+ const uint32_t number_of_shell = 1;
+ const uint32_t number_of_connex = 1;
+ WriteBoolean ( number_of_shell == 1 && number_of_connex == 1 )
+ serializeCompressedShell( pbs );
+
+ uint32_t i;
+ const uint32_t number_of_faces = face.size();
+ for(i=0; i< number_of_faces; i++)
+ face[i]->serializeBaseTopology( pbs );
+}
+
+void PRCBlend01::serializeBlend01(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_SURF_Blend01)
+
+ SerializeContentSurface
+ SerializeTransformation
+ SerializeUVParameterization
+ SerializePtrCurve ( center_curve )
+ SerializePtrCurve ( origin_curve )
+ SerializePtrCurve ( tangent_curve )
+}
+
+void PRCRuled::serializeRuled(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_SURF_Ruled)
+
+ SerializeContentSurface
+ SerializeTransformation
+ SerializeUVParameterization
+ SerializePtrCurve ( first_curve )
+ SerializePtrCurve ( second_curve )
+}
+
+void PRCSphere::serializeSphere(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_SURF_Sphere)
+
+ SerializeContentSurface
+ SerializeTransformation
+ SerializeUVParameterization
+ WriteDouble ( radius )
+}
+
+void PRCCone::serializeCone(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_SURF_Cone)
+
+ SerializeContentSurface
+ SerializeTransformation
+ SerializeUVParameterization
+ WriteDouble ( bottom_radius )
+ WriteDouble ( semi_angle )
+}
+
+void PRCCylinder::serializeCylinder(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_SURF_Cylinder)
+
+ SerializeContentSurface
+ SerializeTransformation
+ SerializeUVParameterization
+ WriteDouble ( radius )
+}
+
+void PRCTorus::serializeTorus(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_SURF_Torus)
+
+ SerializeContentSurface
+ SerializeTransformation
+ SerializeUVParameterization
+ WriteDouble ( major_radius )
+ WriteDouble ( minor_radius )
+}
+
+void PRCFace::serializeFace(PRCbitStream &pbs)
+{
+ uint32_t i = 0;
+ WriteUnsignedInteger (PRC_TYPE_TOPO_Face)
+
+ SerializeBaseTopology
+ SerializePtrSurface ( base_surface )
+ WriteBit ( have_surface_trim_domain )
+ if ( have_surface_trim_domain )
+ SerializeDomain ( surface_trim_domain )
+ WriteBit ( have_tolerance )
+ if ( have_tolerance )
+ WriteDouble ( tolerance )
+ WriteUnsignedInteger ( number_of_loop )
+ WriteInteger ( outer_loop_index )
+ for (i=0;i<number_of_loop;i++)
+ {
+// SerializePtrTopology ( loop[i] )
+ }
+}
+
+void PRCShell::serializeShell(PRCbitStream &pbs)
+{
+ uint32_t i = 0;
+ WriteUnsignedInteger (PRC_TYPE_TOPO_Shell)
+
+ SerializeBaseTopology
+ WriteBoolean ( shell_is_closed )
+ uint32_t number_of_face = face.size();
+ WriteUnsignedInteger ( number_of_face )
+ for (i=0;i<number_of_face;i++)
+ {
+ SerializePtrTopology ( face[i] )
+ WriteCharacter ( orientation_surface_with_shell[i] )
+ }
+}
+
+void PRCShell::addFace(PRCFace*& pFace, uint8_t orientation)
+{
+ face.push_back(pFace);
+ pFace = NULL;
+ orientation_surface_with_shell.push_back(orientation);
+}
+
+void PRCConnex::serializeConnex(PRCbitStream &pbs)
+{
+ uint32_t i = 0;
+ WriteUnsignedInteger (PRC_TYPE_TOPO_Connex)
+
+ SerializeBaseTopology
+ uint32_t number_of_shell = shell.size();
+ WriteUnsignedInteger ( number_of_shell )
+ for (i=0;i<number_of_shell;i++)
+ {
+ SerializePtrTopology ( shell[i] )
+ }
+}
+
+void PRCConnex::addShell(PRCShell*& pShell)
+{
+ shell.push_back(pShell);
+ pShell = NULL;
+}
+
+#define have_bbox( behavior ) (behavior!=0)
+void PRCBrepData::serializeBrepData(PRCbitStream &pbs)
+{
+ uint32_t i = 0;
+ WriteUnsignedInteger ( PRC_TYPE_TOPO_BrepData)
+
+ SerializeContentBody
+ uint32_t number_of_connex = connex.size();
+ WriteUnsignedInteger ( number_of_connex )
+ for ( i=0; i<number_of_connex; i++)
+ {
+ SerializePtrTopology ( connex[i] )
+ }
+ if ( have_bbox(behavior) )
+ SerializeBoundingBox
+}
+#undef have_bbox
+
+void PRCBrepData::addConnex(PRCConnex*& pConnex)
+{
+ connex.push_back(pConnex);
+ pConnex = NULL;
+}
+
+void PRCContentWireEdge::serializeContentWireEdge(PRCbitStream &pbs)
+{
+ SerializeBaseTopology
+ SerializePtrCurve ( curve_3d )
+ WriteBit ( has_curve_trim_interval )
+ if ( has_curve_trim_interval )
+ SerializeInterval ( curve_trim_interval )
+}
+
+void PRCWireEdge::serializeWireEdge(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_TOPO_WireEdge)
+ SerializeContentWireEdge
+}
+
+void PRCContentCurve::serializeContentCurve(PRCbitStream &pbs)
+{
+ SerializeBaseGeometry
+ WriteUnsignedInteger ( extend_info )
+ WriteBoolean ( is_3d )
+}
+
+void PRCNURBSCurve::serializeNURBSCurve(PRCbitStream &pbs)
+{
+ uint32_t i=0;
+ WriteUnsignedInteger (PRC_TYPE_CRV_NURBS)
+
+ SerializeContentCurve
+ WriteBoolean ( is_rational )
+ WriteUnsignedInteger ( degree )
+ uint32_t highest_index_of_control_point = control_point.size()-1;
+ uint32_t highest_index_of_knots = knot.size()-1;
+ WriteUnsignedInteger ( highest_index_of_control_point )
+ WriteUnsignedInteger ( highest_index_of_knots )
+ for (i=0; i<=highest_index_of_control_point; i++)
+ {
+ WriteDouble ( control_point[i].x )
+ WriteDouble ( control_point[i].y )
+ if (is_3d)
+ WriteDouble ( control_point[i].z )
+ if (is_rational)
+ WriteDouble ( control_point[i].w )
+ }
+ for (i=0; i<=highest_index_of_knots; i++)
+ WriteDouble ( knot[i] )
+ WriteUnsignedInteger ( knot_type )
+ WriteUnsignedInteger ( curve_form )
+}
+
+void PRCPolyLine::serializePolyLine(PRCbitStream &pbs)
+{
+ uint32_t i=0;
+ WriteUnsignedInteger (PRC_TYPE_CRV_PolyLine)
+
+ SerializeContentCurve
+ SerializeTransformation
+ SerializeParameterization
+ uint32_t number_of_point = point.size();
+ WriteUnsignedInteger ( number_of_point )
+ for (i=0; i<number_of_point; i++)
+ {
+ if (is_3d)
+ SerializeVector3d ( point[i] )
+ else
+ SerializeVector2d ( point[i] )
+ }
+}
+
+void PRCCircle::serializeCircle(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_CRV_Circle)
+
+ SerializeContentCurve
+ SerializeTransformation
+ SerializeParameterization
+ WriteDouble ( radius )
+}
+
+void PRCComposite::serializeComposite(PRCbitStream &pbs)
+{
+ uint32_t i=0;
+ WriteUnsignedInteger (PRC_TYPE_CRV_Composite)
+
+ SerializeContentCurve
+ SerializeTransformation
+ SerializeParameterization
+ uint32_t number_of_curves = base_curve.size();
+ WriteUnsignedInteger ( number_of_curves )
+ for (i=0; i<number_of_curves; i++)
+ {
+ SerializePtrCurve ( base_curve[i] )
+ WriteBoolean ( base_sense[i] )
+ }
+ WriteBoolean ( is_closed )
+}
+
+void PRCTopoContext::serializeTopoContext(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger (PRC_TYPE_TOPO_Context)
+
+ SerializeContentPRCBase
+ WriteCharacter ( behaviour )
+ WriteDouble ( granularity )
+ WriteDouble ( tolerance )
+ WriteBoolean ( have_smallest_face_thickness )
+ if ( have_smallest_face_thickness )
+ WriteDouble ( smallest_thickness )
+ WriteBoolean ( have_scale )
+ if ( have_scale )
+ WriteDouble ( scale )
+}
+
+void PRCTopoContext::serializeContextAndBodies(PRCbitStream &pbs)
+{
+ uint32_t i=0;
+ SerializeTopoContext
+ uint32_t number_of_bodies = body.size();
+ WriteUnsignedInteger (number_of_bodies)
+ for (i=0;i<number_of_bodies;i++)
+ SerializeBody (body[i])
+}
+
+void PRCTopoContext::serializeGeometrySummary(PRCbitStream &pbs)
+{
+ uint32_t i=0;
+ uint32_t number_of_bodies = body.size();
+ WriteUnsignedInteger (number_of_bodies)
+ for (i=0;i<number_of_bodies;i++)
+ {
+ WriteUnsignedInteger ( body[i]->serialType() )
+ if ( IsCompressedType(body[i]->serialType()) )
+ {
+ WriteDouble ( body[i]->serialTolerance() )
+ }
+ }
+}
+
+void PRCTopoContext::serializeContextGraphics(PRCbitStream &pbs)
+{
+ uint32_t i=0, j=0, k=0, l=0;
+ ResetCurrentGraphics
+ uint32_t number_of_body = body.size();
+ PRCGraphicsList element;
+ bool has_graphics = false;
+ for (i=0;i<number_of_body;i++)
+ {
+ if ( body[i]->topo_item_type == PRC_TYPE_TOPO_BrepData && dynamic_cast<PRCBrepData*>(body[i]))
+ {
+ PRCBrepData *body_i = dynamic_cast<PRCBrepData*>(body[i]);
+ for (j=0;j<body_i->connex.size();j++)
+ {
+ for(k=0;k<body_i->connex[j]->shell.size();k++)
+ {
+ for( l=0;l<body_i->connex[j]->shell[k]->face.size();l++)
+ {
+ element.push_back( body_i->connex[j]->shell[k]->face[l] );
+ has_graphics = has_graphics || body_i->connex[j]->shell[k]->face[l]->has_graphics();
+ }
+ }
+ }
+ }
+ else if ( body[i]->topo_item_type == PRC_TYPE_TOPO_BrepDataCompress && dynamic_cast<PRCCompressedBrepData*>(body[i]))
+ {
+ PRCCompressedBrepData *body_i = dynamic_cast<PRCCompressedBrepData*>(body[i]);
+ for( l=0;l<body_i->face.size();l++)
+ {
+ element.push_back( body_i->face[l] );
+ has_graphics = has_graphics || body_i->face[l]->has_graphics();
+ }
+ }
+ }
+ uint32_t number_of_treat_type = 0;
+ if (has_graphics && !element.empty())
+ number_of_treat_type = 1;
+ WriteUnsignedInteger (number_of_treat_type)
+ for (i=0;i<number_of_treat_type;i++)
+ {
+ const uint32_t element_type = PRC_TYPE_TOPO_Face;
+ WriteUnsignedInteger (element_type)
+ const uint32_t number_of_element = element.size();
+ WriteUnsignedInteger (number_of_element)
+ for (j=0;j<number_of_element;j++)
+ {
+ WriteBoolean ( element[j]->has_graphics() )
+ if (element[j]->has_graphics())
+ {
+ element[j]->serializeGraphics(pbs);
+ }
+ }
+ }
+}
+
+uint32_t PRCTopoContext::addSingleWireBody(PRCSingleWireBody*& pSingleWireBody)
+{
+ body.push_back(pSingleWireBody);
+ pSingleWireBody = NULL;
+ return body.size()-1;
+}
+
+uint32_t PRCTopoContext::addBrepData(PRCBrepData*& pBrepData)
+{
+ body.push_back(pBrepData);
+ pBrepData = NULL;
+ return body.size()-1;
+}
+
+uint32_t PRCTopoContext::addCompressedBrepData(PRCCompressedBrepData*& pCompressedBrepData)
+{
+ body.push_back(pCompressedBrepData);
+ pCompressedBrepData = NULL;
+ return body.size()-1;
+}
+
+void PRCSingleWireBody::serializeSingleWireBody(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger ( PRC_TYPE_TOPO_SingleWireBody)
+
+ SerializeContentBody
+ SerializePtrTopology ( wire_edge )
+}
+
+void PRCUniqueId::serializeCompressedUniqueId(PRCbitStream &pbs) const
+{
+ WriteUnsignedInteger (id0)
+ WriteUnsignedInteger (id1)
+ WriteUnsignedInteger (id2)
+ WriteUnsignedInteger (id3)
+}
+
+void PRCUniqueId::serializeFileStructureUncompressedUniqueId(std::ostream& out) const
+{
+ WriteUncompressedUnsignedInteger (id0)
+ WriteUncompressedUnsignedInteger (id1)
+ WriteUncompressedUnsignedInteger (id2)
+ WriteUncompressedUnsignedInteger (id3)
+}
+
+void PRCUnit::serializeUnit(PRCbitStream &pbs)
+{
+ WriteBoolean (unit_from_CAD_file)
+ WriteDouble (unit)
+}
+
+void PRCProductOccurrence::serializeProductOccurrence(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger ( PRC_TYPE_ASM_ProductOccurence )
+
+ SerializePRCBaseWithGraphics
+
+// SerializeReferencesOfProductOccurrence
+ WriteUnsignedInteger (index_part+1)
+ WriteUnsignedInteger (index_prototype+1)
+ if (index_prototype != m1)
+ {
+ WriteBoolean (prototype_in_same_file_structure)
+ if (!prototype_in_same_file_structure)
+ SerializeCompressedUniqueId (prototype_file_structure)
+ }
+ WriteUnsignedInteger(index_external_data+1)
+ if (index_external_data != m1)
+ {
+ WriteBoolean (external_data_in_same_file_structure)
+ if (!external_data_in_same_file_structure)
+ SerializeCompressedUniqueId (external_data_file_structure)
+ }
+ const uint32_t number_of_son_product_occurrences = index_son_occurrence.size();
+ WriteUnsignedInteger (number_of_son_product_occurrences)
+ for (uint32_t i=0;i<number_of_son_product_occurrences;i++)
+ WriteUnsignedInteger (index_son_occurrence[i])
+
+ WriteCharacter (product_behaviour)
+
+// SerializeProductInformation (product_information)
+ SerializeUnit (unit_information)
+ WriteCharacter (product_information_flags)
+ WriteInteger (product_load_status)
+
+ const bool has_location = location != NULL;
+ WriteBit (has_location)
+ if (has_location)
+ location->serializeTransformation3d (pbs);
+
+ WriteUnsignedInteger (0) // number_of_references
+
+// SerializeMarkups (markups)
+ WriteUnsignedInteger (0) // number_of_linked_items
+ WriteUnsignedInteger (0) // number_of_leaders
+ WriteUnsignedInteger (0) // number_of_markups
+ WriteUnsignedInteger (0) // number_of_annotation_entities
+
+
+ WriteUnsignedInteger (0) // number_of_views
+ WriteBit (false) // has_entity_filter
+ WriteUnsignedInteger (0) // number_of_display_filters
+ WriteUnsignedInteger (0) // number_of_scene_display_parameters
+
+ SerializeUserData
+}
+
+uint32_t PRCPartDefinition::addBrepModel(PRCBrepModel*& pBrepModel)
+{
+ representation_item.push_back(pBrepModel);
+ pBrepModel = NULL;
+ return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel)
+{
+ representation_item.push_back(pPolyBrepModel);
+ pPolyBrepModel = NULL;
+ return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addPointSet(PRCPointSet*& pPointSet)
+{
+ representation_item.push_back(pPointSet);
+ pPointSet = NULL;
+ return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addSet(PRCSet*& pSet)
+{
+ representation_item.push_back(pSet);
+ pSet = NULL;
+ return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addWire(PRCWire*& pWire)
+{
+ representation_item.push_back(pWire);
+ pWire = NULL;
+ return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addPolyWire(PRCPolyWire*& pPolyWire)
+{
+ representation_item.push_back(pPolyWire);
+ pPolyWire = NULL;
+ return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addRepresentationItem(PRCRepresentationItem*& pRepresentationItem)
+{
+ representation_item.push_back(pRepresentationItem);
+ pRepresentationItem = NULL;
+ return representation_item.size()-1;
+}
+
+void PRCPartDefinition::serializePartDefinition(PRCbitStream &pbs)
+{
+ WriteUnsignedInteger ( PRC_TYPE_ASM_PartDefinition )
+
+ SerializePRCBaseWithGraphics
+ SerializeBoundingBox
+
+ uint32_t number_of_representation_items = representation_item.size();
+ WriteUnsignedInteger (number_of_representation_items)
+ for (uint32_t i=0;i<number_of_representation_items;i++)
+ SerializeRepresentationItem (representation_item[i])
+
+ // SerializeMarkups (markups)
+ WriteUnsignedInteger (0) // number_of_linked_items
+ WriteUnsignedInteger (0) // number_of_leaders
+ WriteUnsignedInteger (0) // number_of_markups
+ WriteUnsignedInteger (0) // number_of_annotation_entities
+
+ WriteUnsignedInteger (0) // number_of_views
+ SerializeUserData
+}
diff --git a/graphics/asymptote/prc/writePRC.h b/graphics/asymptote/prc/writePRC.h
new file mode 100644
index 0000000000..7a9313e45c
--- /dev/null
+++ b/graphics/asymptote/prc/writePRC.h
@@ -0,0 +1,1472 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com> and
+* Michail Vidiassov <master@iaas.msu.ru>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __WRITE_PRC_H
+#define __WRITE_PRC_H
+#include <string>
+#include <vector>
+#include <deque>
+#include <list>
+
+#include <map>
+#include <iostream>
+#include "PRCbitStream.h"
+#include "PRC.h"
+#include <float.h>
+#include <math.h>
+
+static const uint32_t m1=(uint32_t)-1;
+static const double pi=acos(-1.0);
+
+class PRCVector3d
+{
+public :
+ double x;
+ double y;
+ double z;
+ PRCVector3d() :
+ x(0), y(0), z(0) {}
+ PRCVector3d(double fx, double fy, double fz) :
+ x(fx), y(fy), z(fz) {}
+ PRCVector3d(const double c[], double fx=0, double fy=0, double fz=0) :
+ x(c?c[0]:fx), y(c?c[1]:fy), z(c?c[2]:fz) {}
+ PRCVector3d(const PRCVector3d& sVector3d) :
+ x(sVector3d.x), y(sVector3d.y), z(sVector3d.z) {}
+
+ void Set(double fx, double fy, double fz)
+ { x = fx; y = fy; z = fz; }
+ double Dot(const PRCVector3d & sPt) const
+ { return(x*sPt.x)+(y*sPt.y)+(z*sPt.z); }
+ double LengthSquared()
+ { return(x*x+y*y+z*z); }
+
+ friend PRCVector3d operator + (const PRCVector3d& a, const PRCVector3d& b)
+ { return PRCVector3d(a.x+b.x,a.y+b.y,a.z+b.z); }
+ friend PRCVector3d operator - (const PRCVector3d& a)
+ { return PRCVector3d(-a.x,-a.y,-a.z); }
+ friend PRCVector3d operator - (const PRCVector3d& a, const PRCVector3d& b)
+ { return PRCVector3d(a.x-b.x,a.y-b.y,a.z-b.z); }
+ friend PRCVector3d operator * (const PRCVector3d& a, const double d)
+ { return PRCVector3d(a.x*d,a.y*d,a.z*d); }
+ friend PRCVector3d operator * (const double d, const PRCVector3d& a)
+ { return PRCVector3d(a.x*d,a.y*d,a.z*d); }
+ friend PRCVector3d operator / (const PRCVector3d& a, const double d)
+ { return PRCVector3d(a.x/d,a.y/d,a.z/d); }
+ friend PRCVector3d operator * (const PRCVector3d& a, const PRCVector3d& b)
+ { return PRCVector3d((a.y*b.z)-(a.z*b.y), (a.z*b.x)-(a.x*b.z), (a.x*b.y)-(a.y*b.x)); }
+
+ void write(PRCbitStream &out) { out << x << y << z; }
+ void serializeVector3d(PRCbitStream &pbs) const { pbs << x << y << z; }
+ void serializeVector2d(PRCbitStream &pbs) const { pbs << x << y; }
+
+ double Length();
+ bool Normalize();
+
+ bool operator==(const PRCVector3d &v) const
+ {
+ return x==v.x && y==v.y && z==v.z;
+ }
+ bool operator!=(const PRCVector3d &v) const
+ {
+ return !(x==v.x && y==v.y && z==v.z);
+ }
+ bool operator<(const PRCVector3d &v) const
+ {
+ if(x!=v.x)
+ return (x<v.x);
+ if(y!=v.y)
+ return (y<v.y);
+ return (z<v.z);
+ }
+ friend std::ostream& operator << (std::ostream& out, const PRCVector3d& v)
+ {
+ out << "(" << v.x << "," << v.y << "," << v.z << ")";
+ return out;
+ }
+};
+/*
+class UUID
+{
+ public:
+ UUID(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) :
+ id0(u0),id1(u1),id2(u2),id3(u3) {}
+ void write(PRCbitStream &out)
+ {
+ out << id0 << id1 << id2 << id3;
+ }
+ private:
+ uint32_t id0,id1,id2,id3;
+}; */
+
+void writeUncompressedUnsignedInteger(std::ostream &out, uint32_t data);
+
+void writeUnit(PRCbitStream &,bool,double);
+
+void writeEmptyMarkups(PRCbitStream&);
+
+class UserData
+{
+ public:
+ UserData(uint32_t s = 0, uint8_t* d = 0) : size(s),data(d) {}
+ void write(PRCbitStream&);
+ private:
+ uint32_t size;
+ uint8_t* data;
+};
+
+struct PRCAttributeEntry
+{
+ PRCAttributeEntry() : title_is_integer(false) {}
+ PRCAttributeEntry(uint32_t integer) : title_is_integer(true)
+ {
+ title_integer = integer;
+ }
+ PRCAttributeEntry(const std::string &text) : title_is_integer(false)
+ {
+ title_text = text;
+ }
+ void serializeAttributeEntry(PRCbitStream&) const;
+ bool title_is_integer;
+ std::string title_text;
+ uint32_t title_integer;
+};
+
+class PRCSingleAttribute : public PRCAttributeEntry
+{
+ public:
+ PRCSingleAttribute() : type(KEPRCModellerAttributeTypeNull) {}
+ PRCSingleAttribute(int32_t integer) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeInt)
+ {
+ value.integer = integer;
+ }
+ PRCSingleAttribute(double real) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeReal)
+ {
+ value.real = real;
+ }
+ PRCSingleAttribute(uint32_t time) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeTime)
+ {
+ value.time = time;
+ }
+ PRCSingleAttribute(const std::string &text) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeString)
+ {
+ value_text = text;}
+ PRCSingleAttribute(uint32_t title, int32_t integer) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeInt)
+ {
+ value.integer = integer;
+ }
+ PRCSingleAttribute(uint32_t title, double real) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeReal)
+ {
+ value.real = real;
+ }
+ PRCSingleAttribute(uint32_t title, uint32_t time) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeTime)
+ {
+ value.time = time;
+ }
+ PRCSingleAttribute(uint32_t title, const std::string &text) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeString)
+ {
+ value_text = text;
+ }
+ PRCSingleAttribute(const std::string title, int32_t integer) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeInt)
+ {
+ value.integer = integer;
+ }
+ PRCSingleAttribute(const std::string title, double real) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeReal)
+ {
+ value.real = real;
+ }
+ PRCSingleAttribute(const std::string title, uint32_t time) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeTime)
+ {
+ value.time = time;
+ }
+ PRCSingleAttribute(const std::string title, const std::string &text) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeString)
+ {
+ value_text = text;
+ }
+ void serializeSingleAttribute(PRCbitStream&) const;
+ EPRCModellerAttributeType type;
+ union PRCSingleAttributeData
+ {
+ int32_t integer;
+ double real;
+ uint32_t time;
+ } value;
+ std::string value_text;
+};
+
+class PRCAttribute : public PRCAttributeEntry
+{
+ public:
+ PRCAttribute() : PRCAttributeEntry() {}
+ PRCAttribute(uint32_t title) : PRCAttributeEntry(title) {}
+ PRCAttribute(const std::string title) : PRCAttributeEntry(title) {}
+ void serializeAttribute(PRCbitStream &) const;
+ PRCSingleAttribute& newKey() { attribute_keys.resize(attribute_keys.size()+1); return attribute_keys.back(); }
+ void addKey(const PRCSingleAttribute &key) { attribute_keys.push_back(key); }
+ std::deque<PRCSingleAttribute> attribute_keys;
+};
+
+typedef std::list<PRCAttribute> PRCAttributeList;
+
+class PRCAttributes
+{
+ public:
+ void serializeAttributes(PRCbitStream&) const;
+ PRCAttribute& newAttribute() { attributes.push_front(PRCAttribute()); return attributes.front(); }
+ void addAttribute(const PRCAttribute &attribute) { attributes.push_front(attribute); }
+ PRCAttributeList attributes;
+};
+
+bool type_eligible_for_reference(uint32_t type);
+uint32_t makeCADID();
+uint32_t makePRCID();
+
+class ContentPRCBase : public PRCAttributes
+{
+ public:
+ ContentPRCBase(uint32_t t, std::string n="") :
+ type(t),name(n),CAD_identifier(0), CAD_persistent_identifier(0), PRC_unique_identifier(0)
+ {
+ if(type_eligible_for_reference(type))
+ {
+ CAD_identifier = makeCADID();
+ PRC_unique_identifier = makePRCID();
+ }
+ }
+ void serializeContentPRCBase(PRCbitStream&) const;
+ uint32_t getPRCID() const { return PRC_unique_identifier; }
+ uint32_t getType() const { return type; }
+ uint32_t type;
+ std::string name;
+ uint32_t CAD_identifier, CAD_persistent_identifier, PRC_unique_identifier;
+};
+
+class PRCReferenceUniqueIdentifier
+{
+public:
+ PRCReferenceUniqueIdentifier() :
+ type(0), unique_identifier(m1) {}
+ void serializeReferenceUniqueIdentifier(PRCbitStream&);
+ uint32_t type;
+// bool reference_in_same_file_structure;
+// PRCUniqueId target_file_structure;
+ uint32_t unique_identifier;
+};
+
+extern std::string currentName;
+void writeName(PRCbitStream&,const std::string&);
+void resetName();
+
+extern uint32_t current_layer_index;
+extern uint32_t current_index_of_line_style;
+extern uint16_t current_behaviour_bit_field;
+
+void writeGraphics(PRCbitStream&,uint32_t=m1,uint32_t=m1,uint16_t=1,bool=false);
+void resetGraphics();
+
+void resetGraphicsAndName();
+
+struct PRCRgbColor
+{
+ PRCRgbColor(double r=0.0, double g=0.0, double b=0.0) :
+ red(r), green(g), blue(b) {}
+ double red,green,blue;
+ void serializeRgbColor(PRCbitStream&);
+
+ bool operator==(const PRCRgbColor &c) const
+ {
+ return (red==c.red && green==c.green && blue==c.blue);
+ }
+ bool operator!=(const PRCRgbColor &c) const
+ {
+ return !(red==c.red && green==c.green && blue==c.blue);
+ }
+ bool operator<(const PRCRgbColor &c) const
+ {
+ if(red!=c.red)
+ return (red<c.red);
+ if(green!=c.green)
+ return (green<c.green);
+ return (blue<c.blue);
+ }
+};
+
+class PRCPicture : public ContentPRCBase
+{
+public:
+ PRCPicture(std::string n="") :
+ ContentPRCBase(PRC_TYPE_GRAPH_Picture,n), format(KEPRCPicture_PNG), uncompressed_file_index(m1), pixel_width(0), pixel_height(0) {}
+ void serializePicture(PRCbitStream&);
+ EPRCPictureDataFormat format;
+ uint32_t uncompressed_file_index;
+ uint32_t pixel_width;
+ uint32_t pixel_height;
+};
+
+struct PRCVector2d
+{
+ PRCVector2d() :
+ x(0.0), y(0.0) {}
+ PRCVector2d(double X, double Y) :
+ x(X), y(Y) {}
+ void serializeVector2d(PRCbitStream&);
+ double x;
+ double y;
+ PRCVector2d(const double c[], double fx=0, double fy=0) :
+ x(c?c[0]:fx), y(c?c[1]:fy) {}
+ PRCVector2d(const PRCVector2d& sVector2d) :
+ x(sVector2d.x), y(sVector2d.y) {}
+
+ void Set(double fx, double fy)
+ { x = fx; y = fy; }
+ double Dot(const PRCVector2d & sPt) const
+ { return(x*sPt.x)+(y*sPt.y); }
+ double LengthSquared()
+ { return(x*x+y*y); }
+
+ friend PRCVector2d operator + (const PRCVector2d& a, const PRCVector2d& b)
+ { return PRCVector2d(a.x+b.x,a.y+b.y); }
+ friend PRCVector2d operator - (const PRCVector2d& a)
+ { return PRCVector2d(-a.x,-a.y); }
+ friend PRCVector2d operator - (const PRCVector2d& a, const PRCVector2d& b)
+ { return PRCVector2d(a.x-b.x,a.y-b.y); }
+ friend PRCVector2d operator * (const PRCVector2d& a, const double d)
+ { return PRCVector2d(a.x*d,a.y*d); }
+ friend PRCVector2d operator * (const double d, const PRCVector2d& a)
+ { return PRCVector2d(a.x*d,a.y*d); }
+ friend PRCVector2d operator / (const PRCVector2d& a, const double d)
+ { return PRCVector2d(a.x/d,a.y/d); }
+
+ double Length();
+ bool Normalize();
+
+ bool operator==(const PRCVector2d &v) const
+ {
+ return x==v.x && y==v.y;
+ }
+ bool operator!=(const PRCVector2d &v) const
+ {
+ return !(x==v.x && y==v.y);
+ }
+ bool operator<(const PRCVector2d &v) const
+ {
+ if(x!=v.x)
+ return (x<v.x);
+ return (y<v.y);
+ }
+ friend std::ostream& operator << (std::ostream& out, const PRCVector2d& v)
+ {
+ out << "(" << v.x << "," << v.y << ")";
+ return out;
+ }
+};
+
+class PRCTextureDefinition : public ContentPRCBase
+{
+public:
+ PRCTextureDefinition(std::string n="") :
+ ContentPRCBase(PRC_TYPE_GRAPH_TextureDefinition,n), picture_index(m1), texture_mapping_attribute(PRC_TEXTURE_MAPPING_DIFFUSE),
+ texture_mapping_attribute_intensity(1.0), texture_mapping_attribute_components(PRC_TEXTURE_MAPPING_COMPONENTS_RGBA),
+ texture_function(KEPRCTextureFunction_Modulate), texture_applying_mode(PRC_TEXTURE_APPLYING_MODE_NONE),
+ texture_wrapping_mode_S(KEPRCTextureWrappingMode_Unknown), texture_wrapping_mode_T(KEPRCTextureWrappingMode_Unknown) // ,
+ // texture_transformation(false), texture_flip_S(false), texture_flip_T(false),
+ // behaviour(PRC_TRANSFORMATION_Identity), scale(1.0,1.0), uniform_scale(1.0)
+ {}
+ void serializeTextureDefinition(PRCbitStream&);
+ uint32_t picture_index;
+ uint32_t texture_mapping_attribute;
+ double texture_mapping_attribute_intensity;
+ uint8_t texture_mapping_attribute_components;
+ EPRCTextureFunction texture_function;
+ uint8_t texture_applying_mode;
+ EPRCTextureWrappingMode texture_wrapping_mode_S;
+ EPRCTextureWrappingMode texture_wrapping_mode_T;
+ // bool texture_transformation;
+ // bool texture_flip_S;
+ // bool texture_flip_T;
+ // uint8_t behaviour;
+ // PRCVector2d origin;
+ // PRCVector2d X;
+ // PRCVector2d Y;
+ // PRCVector2d scale;
+ // double uniform_scale;
+ // double X_homegeneous_coord;
+ // double Y_homegeneous_coord;
+ // double origin_homegeneous_coord;
+};
+typedef std::deque <PRCTextureDefinition*> PRCTextureDefinitionList;
+
+class PRCMaterial
+{
+public:
+ virtual ~PRCMaterial() {}
+ virtual void serializeMaterial(PRCbitStream&) = 0;
+};
+typedef std::deque <PRCMaterial*> PRCMaterialList;
+
+class PRCMaterialGeneric : public ContentPRCBase, public PRCMaterial
+{
+public:
+ PRCMaterialGeneric(std::string n="") :
+ ContentPRCBase(PRC_TYPE_GRAPH_Material,n),
+ ambient(m1), diffuse(m1), emissive(m1), specular(m1),
+ shininess(0.0),
+ ambient_alpha(1.0), diffuse_alpha(1.0), emissive_alpha(1.0), specular_alpha(1.0)
+ {}
+ void serializeMaterialGeneric(PRCbitStream&);
+ void serializeMaterial(PRCbitStream &pbs) { serializeMaterialGeneric(pbs); }
+ uint32_t picture_index;
+ uint32_t ambient;
+ uint32_t diffuse;
+ uint32_t emissive;
+ uint32_t specular;
+ double shininess;
+ double ambient_alpha;
+ double diffuse_alpha;
+ double emissive_alpha;
+ double specular_alpha;
+
+ bool operator==(const PRCMaterialGeneric &m) const
+ {
+ return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive && specular==m.specular && shininess==m.shininess &&
+ ambient_alpha==m.ambient_alpha && diffuse_alpha==m.diffuse_alpha && emissive_alpha==m.emissive_alpha && specular_alpha==m.specular_alpha);
+ }
+};
+
+class PRCTextureApplication : public ContentPRCBase, public PRCMaterial
+{
+public:
+ PRCTextureApplication(std::string n="") :
+ ContentPRCBase(PRC_TYPE_GRAPH_TextureApplication,n),
+ material_generic_index(m1), texture_definition_index(m1),
+ next_texture_index(m1), UV_coordinates_index(0)
+ {}
+ void serializeTextureApplication(PRCbitStream&);
+ void serializeMaterial(PRCbitStream &pbs) { serializeTextureApplication(pbs); }
+ uint32_t material_generic_index;
+ uint32_t texture_definition_index;
+ uint32_t next_texture_index;
+ uint32_t UV_coordinates_index;
+};
+
+class PRCLinePattern : public ContentPRCBase
+{
+public:
+ PRCLinePattern(std::string n="") :
+ ContentPRCBase(PRC_TYPE_GRAPH_LinePattern,n),
+ phase(0), is_real_length(false) {}
+ void serializeLinePattern(PRCbitStream&);
+ std::vector<double> lengths;
+ double phase;
+ bool is_real_length;
+};
+typedef std::deque <PRCLinePattern*> PRCLinePatternList;
+
+class PRCStyle : public ContentPRCBase
+{
+public:
+ PRCStyle(std::string n="") :
+ ContentPRCBase(PRC_TYPE_GRAPH_Style,n), line_width(0.0), is_vpicture(false), line_pattern_vpicture_index(m1),
+ is_material(false), color_material_index(m1), is_transparency_defined(false), transparency(255), additional(0)
+ {}
+ void serializeCategory1LineStyle(PRCbitStream&);
+ double line_width;
+ bool is_vpicture;
+ uint32_t line_pattern_vpicture_index;
+ bool is_material;
+ uint32_t color_material_index;
+ bool is_transparency_defined;
+ uint8_t transparency;
+ uint8_t additional;
+};
+typedef std::deque <PRCStyle*> PRCStyleList;
+
+class PRCTessFace
+{
+public:
+ PRCTessFace() :
+ start_wire(0), used_entities_flag(0),
+ start_triangulated(0), number_of_texture_coordinate_indexes(0),
+ is_rgba(false), behaviour(PRC_GRAPHICS_Show)
+ {}
+ void serializeTessFace(PRCbitStream&);
+ std::vector<uint32_t> line_attributes;
+ uint32_t start_wire; // specifing bounding wire seems not to work as of Acrobat/Reader 9.2
+ std::vector<uint32_t> sizes_wire; // specifing bounding wire seems not to work as of Acrobat/Reader 9.2
+ uint32_t used_entities_flag;
+ uint32_t start_triangulated;
+ std::vector<uint32_t> sizes_triangulated;
+ uint32_t number_of_texture_coordinate_indexes;
+ bool is_rgba;
+ std::vector<uint8_t> rgba_vertices;
+ uint32_t behaviour;
+};
+typedef std::deque <PRCTessFace*> PRCTessFaceList;
+
+class PRCContentBaseTessData
+{
+public:
+ PRCContentBaseTessData() :
+ is_calculated(false) {}
+ void serializeContentBaseTessData(PRCbitStream&);
+ bool is_calculated;
+ std::vector<double> coordinates;
+};
+
+class PRCTess : public PRCContentBaseTessData
+{
+public:
+ virtual ~PRCTess() {}
+ virtual void serializeBaseTessData(PRCbitStream &pbs) = 0;
+};
+typedef std::deque <PRCTess*> PRCTessList;
+
+class PRC3DTess : public PRCTess
+{
+public:
+ PRC3DTess() :
+ has_faces(false), has_loops(false),
+ crease_angle(25.8419) // arccos(0.9), default found in Acrobat output
+ {}
+ ~PRC3DTess() { for(PRCTessFaceList::iterator it=face_tessellation.begin(); it!=face_tessellation.end(); ++it) delete *it; }
+ void serialize3DTess(PRCbitStream&);
+ void serializeBaseTessData(PRCbitStream &pbs) { serialize3DTess(pbs); }
+ void addTessFace(PRCTessFace*& pTessFace);
+
+ bool has_faces;
+ bool has_loops;
+ double crease_angle;
+ std::vector<double> normal_coordinate;
+ std::vector<uint32_t> wire_index; // specifing bounding wire seems not to work as of Acrobat/Reader 9.2
+ std::vector<uint32_t> triangulated_index;
+ PRCTessFaceList face_tessellation;
+ std::vector<double> texture_coordinate;
+};
+
+class PRC3DWireTess : public PRCTess
+{
+public:
+ PRC3DWireTess() :
+ is_rgba(false), is_segment_color(false) {}
+ void serialize3DWireTess(PRCbitStream&);
+ void serializeBaseTessData(PRCbitStream &pbs) { serialize3DWireTess(pbs); }
+
+ bool is_rgba;
+ bool is_segment_color;
+ std::vector<uint32_t> wire_indexes;
+ std::vector<uint8_t> rgba_vertices;
+};
+
+class PRCMarkupTess : public PRCTess
+{
+public:
+ PRCMarkupTess() :
+ behaviour(0)
+ {}
+ void serializeMarkupTess(PRCbitStream&);
+ void serializeBaseTessData(PRCbitStream &pbs) { serializeMarkupTess(pbs); }
+
+ std::vector<uint32_t> codes;
+ std::vector<std::string> texts;
+ std::string label;
+ uint8_t behaviour;
+};
+
+class PRCGraphics
+{
+public:
+ PRCGraphics() : layer_index(m1), index_of_line_style(m1), behaviour_bit_field(PRC_GRAPHICS_Show) {}
+ void serializeGraphics(PRCbitStream&);
+ void serializeGraphicsForced(PRCbitStream&);
+ bool has_graphics() { return (index_of_line_style!=m1 || layer_index!=m1 || behaviour_bit_field!=PRC_GRAPHICS_Show) ; }
+ uint32_t layer_index;
+ uint32_t index_of_line_style;
+ uint16_t behaviour_bit_field;
+};
+typedef std::deque <PRCGraphics*> PRCGraphicsList;
+
+void writeGraphics(PRCbitStream&,const PRCGraphics&,bool=false);
+
+class PRCMarkup: public PRCGraphics, public ContentPRCBase
+{
+public:
+ PRCMarkup(std::string n="") :
+ ContentPRCBase(PRC_TYPE_MKP_Markup,n),
+ type(KEPRCMarkupType_Unknown), sub_type(KEPRCMarkupSubType_Unknown), index_tessellation(m1) {}
+ void serializeMarkup(PRCbitStream&);
+ EPRCMarkupType type;
+ EPRCMarkupSubType sub_type;
+// vector<PRCReferenceUniqueIdentifier> linked_items;
+// vector<PRCReferenceUniqueIdentifier> leaders;
+ uint32_t index_tessellation;
+};
+typedef std::deque <PRCMarkup*> PRCMarkupList;
+
+class PRCAnnotationItem: public PRCGraphics, public ContentPRCBase
+{
+public:
+ PRCAnnotationItem(std::string n="") :
+ ContentPRCBase(PRC_TYPE_MKP_AnnotationItem,n) {}
+ void serializeAnnotationItem(PRCbitStream&);
+ void serializeAnnotationEntity(PRCbitStream &pbs) { serializeAnnotationItem(pbs); }
+ PRCReferenceUniqueIdentifier markup;
+};
+typedef std::deque <PRCAnnotationItem*> PRCAnnotationItemList;
+
+class PRCRepresentationItemContent: public PRCGraphics, public ContentPRCBase
+{
+public:
+ PRCRepresentationItemContent(uint32_t t, std::string n="") :
+ ContentPRCBase(t,n),
+ index_local_coordinate_system(m1), index_tessellation(m1) {}
+ void serializeRepresentationItemContent(PRCbitStream&);
+ uint32_t index_local_coordinate_system;
+ uint32_t index_tessellation;
+};
+
+class PRCRepresentationItem : public PRCRepresentationItemContent
+{
+public:
+ PRCRepresentationItem(uint32_t t, std::string n="") :
+ PRCRepresentationItemContent(t,n) {}
+ virtual ~PRCRepresentationItem() {}
+ virtual void serializeRepresentationItem(PRCbitStream &pbs) = 0;
+};
+typedef std::deque <PRCRepresentationItem*> PRCRepresentationItemList;
+
+class PRCBrepModel : public PRCRepresentationItem
+{
+public:
+ PRCBrepModel(std::string n="") :
+ PRCRepresentationItem(PRC_TYPE_RI_BrepModel,n), has_brep_data(true), context_id(m1), body_id(m1), is_closed(false) {}
+ void serializeBrepModel(PRCbitStream&);
+ void serializeRepresentationItem(PRCbitStream &pbs) { serializeBrepModel(pbs); }
+ bool has_brep_data;
+ uint32_t context_id;
+ uint32_t body_id;
+ bool is_closed;
+};
+
+class PRCPolyBrepModel : public PRCRepresentationItem
+{
+public:
+ PRCPolyBrepModel(std::string n="") :
+ PRCRepresentationItem(PRC_TYPE_RI_PolyBrepModel,n), is_closed(false) {}
+ void serializePolyBrepModel(PRCbitStream&);
+ void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyBrepModel(pbs); }
+ bool is_closed;
+};
+
+class PRCPointSet : public PRCRepresentationItem
+{
+public:
+ PRCPointSet(std::string n="") :
+ PRCRepresentationItem(PRC_TYPE_RI_PointSet,n) {}
+ void serializePointSet(PRCbitStream&);
+ void serializeRepresentationItem(PRCbitStream &pbs) { serializePointSet(pbs); }
+ std::vector<PRCVector3d> point;
+};
+
+class PRCWire : public PRCRepresentationItem
+{
+public:
+ PRCWire(std::string n="") :
+ PRCRepresentationItem(PRC_TYPE_RI_Curve,n), has_wire_body(true), context_id(m1), body_id(m1) {}
+ void serializeWire(PRCbitStream&);
+ void serializeRepresentationItem(PRCbitStream &pbs) { serializeWire(pbs); }
+ bool has_wire_body;
+ uint32_t context_id;
+ uint32_t body_id;
+};
+
+class PRCPolyWire : public PRCRepresentationItem
+{
+public:
+ PRCPolyWire(std::string n="") :
+ PRCRepresentationItem(PRC_TYPE_RI_PolyWire,n) {}
+ void serializePolyWire(PRCbitStream&);
+ void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyWire(pbs); }
+};
+
+class PRCSet : public PRCRepresentationItem
+{
+public:
+ PRCSet(std::string n="") :
+ PRCRepresentationItem(PRC_TYPE_RI_Set,n) {}
+ ~PRCSet() { for(PRCRepresentationItemList::iterator it=elements.begin(); it!=elements.end(); ++it) delete *it; }
+ void serializeSet(PRCbitStream&);
+ void serializeRepresentationItem(PRCbitStream &pbs) { serializeSet(pbs); }
+ uint32_t addBrepModel(PRCBrepModel*& pBrepModel);
+ uint32_t addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel);
+ uint32_t addPointSet(PRCPointSet*& pPointSet);
+ uint32_t addSet(PRCSet*& pSet);
+ uint32_t addWire(PRCWire*& pWire);
+ uint32_t addPolyWire(PRCPolyWire*& pPolyWire);
+ uint32_t addRepresentationItem(PRCRepresentationItem*& pRepresentationItem);
+ PRCRepresentationItemList elements;
+};
+
+class PRCTransformation3d
+{
+public:
+ virtual ~PRCTransformation3d() {}
+ virtual void serializeTransformation3d(PRCbitStream&) const =0;
+};
+typedef std::deque <PRCTransformation3d*> PRCTransformation3dList;
+
+class PRCGeneralTransformation3d : public PRCTransformation3d
+{
+public:
+ PRCGeneralTransformation3d()
+ {
+ setidentity();
+ }
+ PRCGeneralTransformation3d(const double t[])
+ {
+ set(t);
+ }
+
+ void serializeGeneralTransformation3d(PRCbitStream&) const;
+ void serializeTransformation3d(PRCbitStream& pbs) const { serializeGeneralTransformation3d(pbs); }
+ double mat[4][4];
+ bool operator==(const PRCGeneralTransformation3d &t) const
+ {
+ for (size_t i=0;i<4;i++)
+ for (size_t j=0;j<4;j++)
+ if(mat[i][j]!=t.mat[i][j])
+ return false;
+ return true;
+ }
+ bool operator<(const PRCGeneralTransformation3d &t) const
+ {
+ for (size_t i=0;i<4;i++)
+ for (size_t j=0;j<4;j++)
+ if(mat[i][j]!=t.mat[i][j])
+ {
+ return (mat[i][j]<t.mat[i][j]);
+ }
+ return false;
+ }
+ void set(const double t[])
+ {
+ if(t!=NULL)
+ for (size_t i=0;i<4;i++)
+ for (size_t j=0;j<4;j++)
+ mat[i][j]=t[4*i+j];
+ else
+ setidentity();
+ }
+ void setidentity()
+ {
+ mat[0][0]=1; mat[0][1]=0; mat[0][2]=0; mat[0][3]=0;
+ mat[1][0]=0; mat[1][1]=1; mat[1][2]=0; mat[1][3]=0;
+ mat[2][0]=0; mat[2][1]=0; mat[2][2]=1; mat[2][3]=0;
+ mat[3][0]=0; mat[3][1]=0; mat[3][2]=0; mat[3][3]=1;
+ }
+ bool isidtransform() const {
+ return(
+ mat[0][0]==1 && mat[0][1]==0 && mat[0][2]==0 && mat[0][3]==0 &&
+ mat[1][0]==0 && mat[1][1]==1 && mat[1][2]==0 && mat[1][3]==0 &&
+ mat[2][0]==0 && mat[2][1]==0 && mat[2][2]==1 && mat[2][3]==0 &&
+ mat[3][0]==0 && mat[3][1]==0 && mat[3][2]==0 && mat[3][3]==1);
+ }
+ bool isnotidtransform() const {
+ return !isidtransform();
+ }
+ double M(size_t i, size_t j) const {
+ // Like Fortran, PRC uses transposed (column-major) format!
+ return mat[j][i];
+ }
+};
+typedef std::deque <PRCGeneralTransformation3d> PRCGeneralTransformation3dList;
+
+class PRCCartesianTransformation3d : public PRCTransformation3d
+{
+public:
+ PRCCartesianTransformation3d() :
+ behaviour(PRC_TRANSFORMATION_Identity), origin(0.0,0.0,0.0), X(1.0,0.0,0.0), Y(0.0,1.0,0.0), Z(0.0,0.0,1.0),
+ scale(1.0,1.0,1.0), uniform_scale(1.0),
+ X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0) {}
+ PRCCartesianTransformation3d(const double o[3], const double x[3], const double y[3], double sc) :
+ behaviour(PRC_TRANSFORMATION_Identity), origin(o,0.0,0.0,0.0), X(x,1.0,0.0,0.0), Y(y,0.0,1.0,0.0), Z(0.0,0.0,1.0),
+ scale(1.0,1.0,1.0), uniform_scale(sc),
+ X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0)
+ {
+ if(origin!=PRCVector3d(0.0,0.0,0.0))
+ behaviour = behaviour | PRC_TRANSFORMATION_Translate;
+ if(X!=PRCVector3d(1.0,0.0,0.0) || Y!=PRCVector3d(0.0,1.0,0.0))
+ behaviour = behaviour | PRC_TRANSFORMATION_Rotate;
+ if(uniform_scale!=1)
+ behaviour = behaviour | PRC_TRANSFORMATION_Scale;
+ }
+ void serializeCartesianTransformation3d(PRCbitStream& pbs) const;
+ void serializeTransformation3d(PRCbitStream& pbs) const { serializeCartesianTransformation3d(pbs); }
+ uint8_t behaviour;
+ PRCVector3d origin;
+ PRCVector3d X;
+ PRCVector3d Y;
+ PRCVector3d Z;
+ PRCVector3d scale;
+ double uniform_scale;
+ double X_homogeneous_coord;
+ double Y_homogeneous_coord;
+ double Z_homogeneous_coord;
+ double origin_homogeneous_coord;
+ bool operator==(const PRCCartesianTransformation3d &t) const
+ {
+ return behaviour==t.behaviour && origin==t.origin && X==t.X && Y==t.Y && Z==t.Z && scale==t.scale && uniform_scale==t.uniform_scale &&
+ X_homogeneous_coord==t.X_homogeneous_coord && Y_homogeneous_coord==t.Y_homogeneous_coord &&
+ Z_homogeneous_coord==t.Z_homogeneous_coord && origin_homogeneous_coord==t.origin_homogeneous_coord;
+ }
+};
+
+class PRCTransformation
+{
+public:
+ PRCTransformation() :
+ has_transformation(false), geometry_is_2D(false), behaviour(PRC_TRANSFORMATION_Identity),
+ origin(0.0,0.0,0.0), x_axis(1.0,0.0,0.0), y_axis(0.0,1.0,0.0), scale(1) {}
+ void serializeTransformation(PRCbitStream&);
+ bool has_transformation;
+ bool geometry_is_2D;
+ uint8_t behaviour;
+ PRCVector3d origin;
+ PRCVector3d x_axis;
+ PRCVector3d y_axis;
+ double scale;
+};
+
+class PRCCoordinateSystem : public PRCRepresentationItem
+{
+public:
+ PRCCoordinateSystem(std::string n="") :
+ PRCRepresentationItem(PRC_TYPE_RI_CoordinateSystem,n), axis_set(NULL) {}
+ ~PRCCoordinateSystem() { delete axis_set; }
+ void serializeCoordinateSystem(PRCbitStream&);
+ void serializeRepresentationItem(PRCbitStream &pbs) { serializeCoordinateSystem(pbs); }
+ void setAxisSet(PRCGeneralTransformation3d*& transform) { axis_set = transform; transform = NULL; }
+ void setAxisSet(PRCCartesianTransformation3d*& transform) { axis_set = transform; transform = NULL; }
+ PRCTransformation3d *axis_set;
+ bool operator==(const PRCCoordinateSystem &t) const
+ {
+ if(index_local_coordinate_system!=t.index_local_coordinate_system)
+ return false;
+ PRCGeneralTransformation3d* axis_set_general = dynamic_cast<PRCGeneralTransformation3d*>(axis_set);
+ PRCGeneralTransformation3d* t_axis_set_general = dynamic_cast<PRCGeneralTransformation3d*>(t.axis_set);
+ PRCCartesianTransformation3d* axis_set_cartesian = dynamic_cast<PRCCartesianTransformation3d*>(axis_set);
+ PRCCartesianTransformation3d* t_axis_set_cartesian = dynamic_cast<PRCCartesianTransformation3d*>(t.axis_set);
+ if(axis_set_general!=NULL)
+ return (t_axis_set_general!=NULL?(*axis_set_general==*t_axis_set_general):false);
+ if(axis_set_cartesian!=NULL)
+ return (t_axis_set_cartesian!=NULL?(*axis_set_cartesian==*t_axis_set_cartesian):false);
+ return false;
+ }
+};
+typedef std::deque <PRCCoordinateSystem*> PRCCoordinateSystemList;
+
+struct PRCFontKey
+{
+ uint32_t font_size;
+ uint8_t attributes;
+};
+
+class PRCFontKeysSameFont
+{
+public:
+ void serializeFontKeysSameFont(PRCbitStream&);
+ std::string font_name;
+ uint32_t char_set;
+ std::vector<PRCFontKey> font_keys;
+
+};
+
+// Topology
+class PRCBaseGeometry : public PRCAttributes
+{
+public:
+ PRCBaseGeometry() :
+ base_information(false), identifier(0) {}
+ PRCBaseGeometry(std::string n, uint32_t id = 0) :
+ base_information(true),name(n),identifier(id) {}
+ void serializeBaseGeometry(PRCbitStream&);
+ bool base_information;
+ std::string name;
+ uint32_t identifier;
+};
+
+class PRCBoundingBox
+{
+public:
+ PRCBoundingBox() : min(0.0,0.0,0.0), max(0.0,0.0,0.0) {}
+ PRCBoundingBox(const PRCVector3d &m1, const PRCVector3d& m2) : min(m1),max(m2) {}
+ void serializeBoundingBox(PRCbitStream &pbs);
+ PRCVector3d min;
+ PRCVector3d max;
+};
+
+class PRCDomain
+{
+public:
+ void serializeDomain(PRCbitStream &pbs);
+ PRCVector2d min;
+ PRCVector2d max;
+};
+
+class PRCInterval
+{
+public:
+ PRCInterval() : min(0), max(0) {}
+ PRCInterval(double m, double M) : min(m), max(M) {}
+ void serializeInterval(PRCbitStream &pbs);
+ double min;
+ double max;
+};
+
+class PRCParameterization
+{
+public:
+ PRCParameterization() : parameterization_coeff_a(1), parameterization_coeff_b(0) {}
+ PRCParameterization(double min, double max) : interval(min, max), parameterization_coeff_a(1), parameterization_coeff_b(0) {}
+ void serializeParameterization(PRCbitStream &pbs);
+ PRCInterval interval;
+ double parameterization_coeff_a;
+ double parameterization_coeff_b;
+};
+
+class PRCUVParameterization
+{
+public:
+ PRCUVParameterization() : swap_uv(false),
+ parameterization_on_u_coeff_a(1), parameterization_on_v_coeff_a(1),
+ parameterization_on_u_coeff_b(0), parameterization_on_v_coeff_b(0) {}
+ void serializeUVParameterization(PRCbitStream &pbs);
+ bool swap_uv;
+ PRCDomain uv_domain;
+ double parameterization_on_u_coeff_a;
+ double parameterization_on_v_coeff_a;
+ double parameterization_on_u_coeff_b;
+ double parameterization_on_v_coeff_b;
+};
+
+class PRCControlPoint
+{
+public:
+ PRCControlPoint() :
+ x(0), y(0), z(0), w(1) {}
+ PRCControlPoint(double X, double Y, double Z=0, double W=1) :
+ x(X), y(Y), z(Z), w(W) {}
+ PRCControlPoint(const PRCVector3d &v) :
+ x(v.x), y(v.y), z(v.z), w(1) {}
+ void Set(double fx, double fy, double fz, double fw=1)
+ { x = fx; y = fy; z = fz; w = fw; }
+ double x;
+ double y;
+ double z;
+ double w;
+};
+
+class PRCContentSurface: public PRCBaseGeometry
+{
+public:
+ PRCContentSurface() :
+ PRCBaseGeometry(), extend_info(KEPRCExtendTypeNone) {}
+ PRCContentSurface(std::string n) :
+ PRCBaseGeometry(n,makeCADID()),extend_info(KEPRCExtendTypeNone) {}
+ void serializeContentSurface(PRCbitStream&);
+ EPRCExtendType extend_info;
+};
+
+class PRCSurface : public PRCContentSurface
+{
+public:
+ PRCSurface() :
+ PRCContentSurface() {}
+ PRCSurface(std::string n) :
+ PRCContentSurface(n) {}
+ virtual ~PRCSurface() {}
+ virtual void serializeSurface(PRCbitStream &pbs) = 0;
+};
+
+class PRCNURBSSurface : public PRCSurface
+{
+public:
+ PRCNURBSSurface() :
+ PRCSurface(), knot_type(KEPRCKnotTypeUnspecified), surface_form(KEPRCBSplineSurfaceFormUnspecified) {}
+ PRCNURBSSurface(std::string n) :
+ PRCSurface(n), knot_type(KEPRCKnotTypeUnspecified), surface_form(KEPRCBSplineSurfaceFormUnspecified) {}
+ void serializeNURBSSurface(PRCbitStream &pbs);
+ void serializeSurface(PRCbitStream &pbs) { serializeNURBSSurface(pbs); }
+ bool is_rational;
+ uint32_t degree_in_u;
+ uint32_t degree_in_v;
+ std::vector<PRCControlPoint> control_point;
+ std::vector<double> knot_u;
+ std::vector<double> knot_v;
+ const EPRCKnotType knot_type;
+ const EPRCBSplineSurfaceForm surface_form;
+};
+
+class PRCContentCurve: public PRCBaseGeometry
+{
+public:
+ PRCContentCurve() :
+ PRCBaseGeometry(), extend_info(KEPRCExtendTypeNone), is_3d(true) {}
+ PRCContentCurve(std::string n) :
+ PRCBaseGeometry(n,makeCADID()),extend_info(KEPRCExtendTypeNone), is_3d(true) {}
+ void serializeContentCurve(PRCbitStream&);
+ EPRCExtendType extend_info;
+ bool is_3d;
+};
+
+class PRCCurve : public PRCContentCurve
+{
+public:
+ PRCCurve() :
+ PRCContentCurve() {}
+ PRCCurve(std::string n) :
+ PRCContentCurve(n) {}
+ virtual ~PRCCurve() {}
+ virtual void serializeCurve(PRCbitStream &pbs) = 0;
+};
+typedef std::deque <PRCCurve*> PRCCurveList;
+
+class PRCNURBSCurve : public PRCCurve
+{
+public:
+ PRCNURBSCurve() :
+ PRCCurve(), knot_type(KEPRCKnotTypeUnspecified), curve_form(KEPRCBSplineCurveFormUnspecified) {}
+ PRCNURBSCurve(std::string n) :
+ PRCCurve(n), knot_type(KEPRCKnotTypeUnspecified), curve_form(KEPRCBSplineCurveFormUnspecified) {}
+ void serializeNURBSCurve(PRCbitStream &pbs);
+ void serializeCurve(PRCbitStream &pbs) { serializeNURBSCurve(pbs); }
+ bool is_rational;
+ uint32_t degree;
+ std::vector<PRCControlPoint> control_point;
+ std::vector<double> knot;
+ const EPRCKnotType knot_type;
+ const EPRCBSplineCurveForm curve_form;
+};
+
+class PRCPolyLine : public PRCCurve, public PRCTransformation, public PRCParameterization
+{
+public:
+ PRCPolyLine() :
+ PRCCurve() {}
+ PRCPolyLine(std::string n) :
+ PRCCurve(n) {}
+ void serializePolyLine(PRCbitStream &pbs);
+ void serializeCurve(PRCbitStream &pbs) { serializePolyLine(pbs); }
+ std::vector<PRCVector3d> point;
+};
+
+class PRCCircle : public PRCCurve, public PRCTransformation, public PRCParameterization
+{
+public:
+ PRCCircle() :
+ PRCCurve(), PRCParameterization(0,2*pi) {}
+ PRCCircle(std::string n) :
+ PRCCurve(n), PRCParameterization(0,2*pi) {}
+ void serializeCircle(PRCbitStream &pbs);
+ void serializeCurve(PRCbitStream &pbs) { serializeCircle(pbs); }
+ double radius;
+};
+
+class PRCComposite : public PRCCurve, public PRCTransformation, public PRCParameterization
+{
+public:
+ PRCComposite() :
+ PRCCurve() {}
+ PRCComposite(std::string n) :
+ PRCCurve(n) {}
+ void serializeComposite(PRCbitStream &pbs);
+ void serializeCurve(PRCbitStream &pbs) { serializeComposite(pbs); }
+ PRCCurveList base_curve;
+ std::vector<bool> base_sense;
+ bool is_closed;
+};
+
+class PRCBlend01 : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+ PRCBlend01() :
+ PRCSurface(), center_curve(NULL), origin_curve(NULL), tangent_curve(NULL) {}
+ PRCBlend01(std::string n) :
+ PRCSurface(n), center_curve(NULL), origin_curve(NULL), tangent_curve(NULL) {}
+ ~PRCBlend01() { delete center_curve; delete origin_curve; delete tangent_curve; }
+ void serializeBlend01(PRCbitStream &pbs);
+ void serializeSurface(PRCbitStream &pbs) { serializeBlend01(pbs); }
+// void setCenterCurve (PRCCurve*& curve) { center_curve = curve; curve = NULL; }
+// void setOriginCurve (PRCCurve*& curve) { origin_curve = curve; curve = NULL; }
+// void setTangentCurve(PRCCurve*& curve) { tangent_curve = curve; curve = NULL; }
+ PRCCurve* center_curve;
+ PRCCurve* origin_curve;
+ PRCCurve* tangent_curve;
+};
+
+class PRCRuled : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+ PRCRuled() :
+ PRCSurface(), first_curve(NULL), second_curve(NULL) {}
+ PRCRuled(std::string n) :
+ PRCSurface(n) {}
+ ~PRCRuled() { delete first_curve; delete second_curve; }
+ void serializeRuled(PRCbitStream &pbs);
+ void serializeSurface(PRCbitStream &pbs) { serializeRuled(pbs); }
+// void setFirstCurve(PRCCurve*& curve) { first_curve = curve; curve = NULL; }
+// void setSecondCurve(PRCCurve*& curve) { second_curve = curve; curve = NULL; }
+ PRCCurve* first_curve;
+ PRCCurve* second_curve;
+};
+
+class PRCSphere : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+ PRCSphere() :
+ PRCSurface() {}
+ PRCSphere(std::string n) :
+ PRCSurface(n) {}
+ void serializeSphere(PRCbitStream &pbs);
+ void serializeSurface(PRCbitStream &pbs) { serializeSphere(pbs); }
+ double radius;
+};
+
+class PRCCone : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+ PRCCone() :
+ PRCSurface() {}
+ PRCCone(std::string n) :
+ PRCSurface(n) {}
+ void serializeCone(PRCbitStream &pbs);
+ void serializeSurface(PRCbitStream &pbs) { serializeCone(pbs); }
+ double bottom_radius;
+ double semi_angle;
+};
+
+class PRCCylinder : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+ PRCCylinder() :
+ PRCSurface() {}
+ PRCCylinder(std::string n) :
+ PRCSurface(n) {}
+ void serializeCylinder(PRCbitStream &pbs);
+ void serializeSurface(PRCbitStream &pbs) { serializeCylinder(pbs); }
+ double radius;
+};
+
+class PRCTorus : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+ PRCTorus() :
+ PRCSurface() {}
+ PRCTorus(std::string n) :
+ PRCSurface(n) {}
+ void serializeTorus(PRCbitStream &pbs);
+ void serializeSurface(PRCbitStream &pbs) { serializeTorus(pbs); }
+ double major_radius;
+ double minor_radius;
+};
+
+class PRCBaseTopology : public PRCAttributes
+{
+public:
+ PRCBaseTopology() :
+ base_information(false),identifier(0) {}
+ PRCBaseTopology(std::string n, uint32_t id = 0) :
+ base_information(true),name(n),identifier(id) {}
+ void serializeBaseTopology(PRCbitStream&);
+ bool base_information;
+ std::string name;
+ uint32_t identifier;
+};
+
+class PRCTopoItem
+{
+public:
+ virtual ~PRCTopoItem() {}
+ virtual void serializeTopoItem(PRCbitStream&)=0;
+};
+
+class PRCContentBody: public PRCBaseTopology
+{
+public:
+ PRCContentBody() :
+ PRCBaseTopology(), behavior(0) {}
+ PRCContentBody(std::string n) :
+ PRCBaseTopology(n,makeCADID()), behavior(0) {}
+ void serializeContentBody(PRCbitStream&);
+ uint8_t behavior;
+};
+
+class PRCBody : public PRCContentBody, public PRCTopoItem
+{
+public:
+ PRCBody() :
+ PRCContentBody(), topo_item_type(PRC_TYPE_ROOT) {}
+ PRCBody(uint32_t tit) :
+ PRCContentBody(), topo_item_type(tit) {}
+ PRCBody(uint32_t tit, std::string n) :
+ PRCContentBody(n), topo_item_type(tit) {}
+ virtual ~PRCBody() {}
+ virtual void serializeBody(PRCbitStream &pbs) = 0;
+ void serializeTopoItem(PRCbitStream &pbs) { serializeBody(pbs); }
+ uint32_t serialType() { return topo_item_type; }
+ virtual double serialTolerance() { return 0; }
+ const uint32_t topo_item_type;
+};
+typedef std::deque <PRCBody*> PRCBodyList;
+
+class PRCContentWireEdge : public PRCBaseTopology
+{
+public:
+ PRCContentWireEdge() :
+ PRCBaseTopology(), curve_3d(NULL), has_curve_trim_interval(false) {}
+ PRCContentWireEdge(std::string n) :
+ PRCBaseTopology(n,makeCADID()), curve_3d(NULL), has_curve_trim_interval(false) {}
+ ~PRCContentWireEdge() { delete curve_3d; }
+ void serializeContentWireEdge(PRCbitStream &pbs);
+// void setCurve(PRCCurve*& curve) { curve_3d = curve; curve = NULL; }
+ PRCCurve* curve_3d;
+ bool has_curve_trim_interval;
+ PRCInterval curve_trim_interval;
+};
+
+class PRCWireEdge : public PRCContentWireEdge, public PRCTopoItem
+{
+public:
+ void serializeWireEdge(PRCbitStream &pbs);
+ void serializeTopoItem(PRCbitStream &pbs) { serializeWireEdge(pbs); }
+};
+
+class PRCSingleWireBody : public PRCBody
+{
+public:
+ PRCSingleWireBody() :
+ PRCBody(PRC_TYPE_TOPO_SingleWireBody), wire_edge(NULL) {}
+ PRCSingleWireBody(std::string n) :
+ PRCBody(PRC_TYPE_TOPO_SingleWireBody, n), wire_edge(NULL) {}
+ ~PRCSingleWireBody() { delete wire_edge; }
+ void serializeSingleWireBody(PRCbitStream &pbs);
+ void serializeBody(PRCbitStream &pbs) { serializeSingleWireBody(pbs); }
+ void setWireEdge(PRCWireEdge*& wireEdge) { wire_edge = wireEdge; wireEdge = NULL; }
+ PRCWireEdge* wire_edge;
+};
+
+class PRCFace : public PRCBaseTopology, public PRCTopoItem, public PRCGraphics
+{
+public:
+ PRCFace() :
+ PRCBaseTopology(), base_surface(NULL), have_surface_trim_domain(false), have_tolerance(false), tolerance(0), number_of_loop(0), outer_loop_index(-1) {}
+ PRCFace(std::string n) :
+ PRCBaseTopology(n,makeCADID()), base_surface(NULL), have_surface_trim_domain(false), have_tolerance(false), tolerance(0), number_of_loop(0), outer_loop_index(-1) {}
+ ~PRCFace() { delete base_surface; }
+ void serializeFace(PRCbitStream &pbs);
+ void serializeTopoItem(PRCbitStream &pbs) { serializeFace(pbs); }
+ void setBaseSurface(PRCSurface*& surface) { base_surface = surface; surface = NULL; }
+ PRCSurface *base_surface;
+ const bool have_surface_trim_domain;
+ PRCDomain surface_trim_domain;
+ const bool have_tolerance;
+ const double tolerance;
+ const uint32_t number_of_loop;
+ const int32_t outer_loop_index;
+// PRCLoopList loop;
+};
+typedef std::deque <PRCFace*> PRCFaceList;
+
+class PRCShell : public PRCBaseTopology, public PRCTopoItem
+{
+public:
+ PRCShell() :
+ PRCBaseTopology(), shell_is_closed(false) {}
+ PRCShell(std::string n) :
+ PRCBaseTopology(n,makeCADID()), shell_is_closed(false) {}
+ ~PRCShell() { for(PRCFaceList::iterator it=face.begin(); it!=face.end(); ++it) delete *it; }
+ void serializeShell(PRCbitStream &pbs);
+ void serializeTopoItem(PRCbitStream &pbs) { serializeShell(pbs); }
+ void addFace(PRCFace*& pFace, uint8_t orientation=2);
+ bool shell_is_closed;
+ PRCFaceList face;
+ std::vector<uint8_t> orientation_surface_with_shell;
+};
+typedef std::deque <PRCShell*> PRCShellList;
+
+class PRCConnex : public PRCBaseTopology, public PRCTopoItem
+{
+public:
+ PRCConnex() :
+ PRCBaseTopology() {}
+ PRCConnex(std::string n) :
+ PRCBaseTopology(n,makeCADID()) {}
+ ~PRCConnex() { for(PRCShellList::iterator it=shell.begin(); it!=shell.end(); ++it) delete *it; }
+ void serializeConnex(PRCbitStream &pbs);
+ void serializeTopoItem(PRCbitStream &pbs) { serializeConnex(pbs); }
+ void addShell(PRCShell*& pShell);
+ PRCShellList shell;
+};
+typedef std::deque <PRCConnex*> PRCConnexList;
+
+class PRCBrepData : public PRCBody, public PRCBoundingBox
+{
+public:
+ PRCBrepData() :
+ PRCBody(PRC_TYPE_TOPO_BrepData) {}
+ PRCBrepData(std::string n) :
+ PRCBody(PRC_TYPE_TOPO_BrepData, n) {}
+ ~PRCBrepData() { for(PRCConnexList::iterator it=connex.begin(); it!=connex.end(); ++it) delete *it; }
+ void serializeBrepData(PRCbitStream &pbs);
+ void serializeBody(PRCbitStream &pbs) { serializeBrepData(pbs); }
+ void addConnex(PRCConnex*& pConnex);
+ PRCConnexList connex;
+};
+
+// For now - treat just the case of Bezier surfaces cubic 4x4 or linear 2x2
+class PRCCompressedFace : public PRCBaseTopology, public PRCGraphics
+{
+public:
+ PRCCompressedFace() :
+ PRCBaseTopology(), orientation_surface_with_shell(true), degree(0) {}
+ PRCCompressedFace(std::string n) :
+ PRCBaseTopology(n,makeCADID()), orientation_surface_with_shell(true), degree(0) {}
+ void serializeCompressedFace(PRCbitStream &pbs, double brep_data_compressed_tolerance);
+ void serializeContentCompressedFace(PRCbitStream &pbs);
+ void serializeCompressedAnaNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance);
+ void serializeCompressedNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance);
+ bool orientation_surface_with_shell;
+ uint32_t degree;
+ std::vector<PRCVector3d> control_point;
+};
+typedef std::deque <PRCCompressedFace*> PRCCompressedFaceList;
+
+// For now - treat just the case of one connex/one shell
+class PRCCompressedBrepData : public PRCBody
+{
+public:
+ PRCCompressedBrepData() :
+ PRCBody(PRC_TYPE_TOPO_BrepDataCompress), serial_tolerance(0), brep_data_compressed_tolerance(0) {}
+ PRCCompressedBrepData(std::string n) :
+ PRCBody(PRC_TYPE_TOPO_BrepDataCompress, n), serial_tolerance(0), brep_data_compressed_tolerance(0) {}
+ ~PRCCompressedBrepData() { for(PRCCompressedFaceList::iterator it=face.begin(); it!=face.end(); ++it) delete *it; }
+ void serializeCompressedBrepData(PRCbitStream &pbs);
+ void serializeBody(PRCbitStream &pbs) { serializeCompressedBrepData(pbs); }
+ void serializeCompressedShell(PRCbitStream &pbs);
+ double serialTolerance() { return serial_tolerance; }
+ double serial_tolerance;
+ double brep_data_compressed_tolerance;
+ PRCCompressedFaceList face;
+};
+
+class PRCTopoContext : public ContentPRCBase
+{
+public:
+ PRCTopoContext(std::string n="") :
+ ContentPRCBase(PRC_TYPE_TOPO_Context,n), behaviour(0), granularity(1), tolerance(0),
+ have_smallest_face_thickness(false), smallest_thickness(0), have_scale(false), scale(1) {}
+ ~PRCTopoContext() { for(PRCBodyList::iterator it=body.begin(); it!=body.end(); ++it) delete *it; }
+ void serializeTopoContext(PRCbitStream&);
+ void serializeContextAndBodies(PRCbitStream&);
+ void serializeGeometrySummary(PRCbitStream&);
+ void serializeContextGraphics(PRCbitStream&);
+ uint32_t addSingleWireBody(PRCSingleWireBody*& body);
+ uint32_t addBrepData(PRCBrepData*& body);
+ uint32_t addCompressedBrepData(PRCCompressedBrepData*& body);
+ uint8_t behaviour;
+ double granularity;
+ double tolerance;
+ bool have_smallest_face_thickness;
+ double smallest_thickness;
+ bool have_scale;
+ double scale;
+ PRCBodyList body;
+};
+typedef std::deque <PRCTopoContext*> PRCTopoContextList;
+
+class PRCUniqueId
+{
+public:
+ PRCUniqueId() : id0(0), id1(0), id2(0), id3(0) {}
+ void serializeCompressedUniqueId(PRCbitStream&) const;
+ void serializeFileStructureUncompressedUniqueId(std::ostream& out) const;
+ uint32_t id0;
+ uint32_t id1;
+ uint32_t id2;
+ uint32_t id3;
+};
+
+class PRCUnit
+{
+public:
+ PRCUnit() : unit_from_CAD_file(false), unit(1) {}
+ PRCUnit(double u, bool ufcf=true) : unit_from_CAD_file(ufcf), unit(u) {}
+ void serializeUnit(PRCbitStream&);
+ bool unit_from_CAD_file;
+ double unit;
+};
+
+class PRCProductOccurrence: public PRCGraphics, public ContentPRCBase
+{
+public:
+ PRCProductOccurrence(std::string n="") :
+ ContentPRCBase(PRC_TYPE_ASM_ProductOccurence,n),
+ index_part(m1),
+ index_prototype(m1), prototype_in_same_file_structure(true),
+ index_external_data(m1), external_data_in_same_file_structure(true),
+ product_behaviour(0), product_information_flags(0), product_load_status(KEPRCProductLoadStatus_Loaded),
+ location(NULL) {}
+ ~PRCProductOccurrence() { delete location; }
+ void setLocation(PRCGeneralTransformation3d*& transform) { location = transform; transform = NULL; }
+ void serializeProductOccurrence(PRCbitStream&);
+ uint32_t index_part;
+ uint32_t index_prototype;
+ bool prototype_in_same_file_structure;
+ PRCUniqueId prototype_file_structure;
+ uint32_t index_external_data;
+ bool external_data_in_same_file_structure;
+ PRCUniqueId external_data_file_structure;
+ std::vector<uint32_t> index_son_occurrence;
+ uint8_t product_behaviour;
+ PRCUnit unit_information;
+ uint8_t product_information_flags;
+ EPRCProductLoadStatus product_load_status;
+ PRCGeneralTransformation3d *location;
+};
+typedef std::deque <PRCProductOccurrence*> PRCProductOccurrenceList;
+
+class PRCPartDefinition: public PRCGraphics, public ContentPRCBase, public PRCBoundingBox
+{
+public:
+ PRCPartDefinition(std::string n="") :
+ ContentPRCBase(PRC_TYPE_ASM_PartDefinition,n) {}
+ ~PRCPartDefinition() { for(PRCRepresentationItemList::iterator it=representation_item.begin(); it!=representation_item.end(); ++it) delete *it; }
+ void serializePartDefinition(PRCbitStream&);
+ uint32_t addBrepModel(PRCBrepModel*& pBrepModel);
+ uint32_t addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel);
+ uint32_t addPointSet(PRCPointSet*& pPointSet);
+ uint32_t addSet(PRCSet*& pSet);
+ uint32_t addWire(PRCWire*& pWire);
+ uint32_t addPolyWire(PRCPolyWire*& pPolyWire);
+ uint32_t addRepresentationItem(PRCRepresentationItem*& pRepresentationItem);
+ PRCRepresentationItemList representation_item;
+};
+typedef std::deque <PRCPartDefinition*> PRCPartDefinitionList;
+
+#endif //__WRITE_PRC_H
diff --git a/graphics/asymptote/prcfile.h b/graphics/asymptote/prcfile.h
new file mode 100644
index 0000000000..a40fb64e16
--- /dev/null
+++ b/graphics/asymptote/prcfile.h
@@ -0,0 +1,30 @@
+#ifndef PRCFILE_H
+#define PRCFILE_H
+
+#include "memory.h"
+
+inline double X(const camp::triple &v) {return v.getx();}
+inline double Y(const camp::triple &v) {return v.gety();}
+inline double Z(const camp::triple &v) {return v.getz();}
+
+#include "prc/oPRCFile.h"
+
+namespace camp {
+
+inline prc::RGBAColour rgba(pen p) {
+ p.convert();
+ p.torgb();
+ return prc::RGBAColour(p.red(),p.green(),p.blue(),p.opacity());
+}
+
+static const double inches=72;
+static const double cm=inches/2.54;
+
+class prcfile : public prc::oPRCFile {
+public:
+ prcfile(string name) : prc::oPRCFile(name.c_str(),10.0/cm) {} // Use bp.
+};
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/predicates.cc b/graphics/asymptote/predicates.cc
new file mode 100644
index 0000000000..0b0a6aff86
--- /dev/null
+++ b/graphics/asymptote/predicates.cc
@@ -0,0 +1,2784 @@
+/*****************************************************************************/
+/* */
+/* Routines for Arbitrary Precision Floating-point Arithmetic */
+/* and Fast Robust Geometric Predicates */
+/* (predicates.c) */
+/* */
+/* May 18, 1996 */
+/* */
+/* Placed in the public domain by */
+/* Jonathan Richard Shewchuk */
+/* School of Computer Science */
+/* Carnegie Mellon University */
+/* 5000 Forbes Avenue */
+/* Pittsburgh, Pennsylvania 15213-3891 */
+/* jrs@cs.cmu.edu */
+/* */
+/* This file contains C implementation of algorithms for exact addition */
+/* and multiplication of floating-point numbers, and predicates for */
+/* robustly performing the orientation and incircle tests used in */
+/* computational geometry. The algorithms and underlying theory are */
+/* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */
+/* Point Arithmetic and Fast Robust Geometric Predicates." Technical */
+/* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
+/* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */
+/* Discrete & Computational Geometry.) */
+/* */
+/* This file, the paper listed above, and other information are available */
+/* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */
+/* */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* */
+/* Using this code: */
+/* */
+/* First, read the short or long version of the paper (from the Web page */
+/* above). */
+/* */
+/* Be sure to call exactinit() once, before calling any of the arithmetic */
+/* functions or geometric predicates. Also be sure to turn on the */
+/* optimizer when compiling this file. */
+/* */
+/* */
+/* Several geometric predicates are defined. Their parameters are all */
+/* points. Each point is an array of two or three floating-point */
+/* numbers. The geometric predicates, described in the papers, are */
+/* */
+/* orient2d(pa, pb, pc) */
+/* orient2dfast(pa, pb, pc) */
+/* orient3d(pa, pb, pc, pd) */
+/* orient3dfast(pa, pb, pc, pd) */
+/* incircle(pa, pb, pc, pd) */
+/* incirclefast(pa, pb, pc, pd) */
+/* insphere(pa, pb, pc, pd, pe) */
+/* inspherefast(pa, pb, pc, pd, pe) */
+/* */
+/* Those with suffix "fast" are approximate, non-robust versions. Those */
+/* without the suffix are adaptive precision, robust versions. There */
+/* are also versions with the suffices "exact" and "slow", which are */
+/* non-adaptive, exact arithmetic versions, which I use only for timings */
+/* in my arithmetic papers. */
+/* */
+/* */
+/* An expansion is represented by an array of floating-point numbers, */
+/* sorted from smallest to largest magnitude (possibly with interspersed */
+/* zeros). The length of each expansion is stored as a separate integer, */
+/* and each arithmetic function returns an integer which is the length */
+/* of the expansion it created. */
+/* */
+/* Several arithmetic functions are defined. Their parameters are */
+/* */
+/* e, f Input expansions */
+/* elen, flen Lengths of input expansions (must be >= 1) */
+/* h Output expansion */
+/* b Input scalar */
+/* */
+/* The arithmetic functions are */
+/* */
+/* grow_expansion(elen, e, b, h) */
+/* grow_expansion_zeroelim(elen, e, b, h) */
+/* expansion_sum(elen, e, flen, f, h) */
+/* expansion_sum_zeroelim1(elen, e, flen, f, h) */
+/* expansion_sum_zeroelim2(elen, e, flen, f, h) */
+/* fast_expansion_sum(elen, e, flen, f, h) */
+/* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
+/* linear_expansion_sum(elen, e, flen, f, h) */
+/* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
+/* scale_expansion(elen, e, b, h) */
+/* scale_expansion_zeroelim(elen, e, b, h) */
+/* compress(elen, e, h) */
+/* */
+/* All of these are described in the long version of the paper; some are */
+/* described in the short version. All return an integer that is the */
+/* length of h. Those with suffix _zeroelim perform zero elimination, */
+/* and are recommended over their counterparts. The procedure */
+/* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
+/* processors that do not use the round-to-even tiebreaking rule) is */
+/* recommended over expansion_sum_zeroelim(). Each procedure has a */
+/* little note next to it (in the code below) that tells you whether or */
+/* not the output expansion may be the same array as one of the input */
+/* expansions. */
+/* */
+/* */
+/* If you look around below, you'll also find macros for a bunch of */
+/* simple unrolled arithmetic operations, and procedures for printing */
+/* expansions (commented out because they don't work with all C */
+/* compilers) and for generating random floating-point numbers whose */
+/* significand bits are all random. Most of the macros have undocumented */
+/* requirements that certain of their parameters should not be the same */
+/* variable; for safety, better to make sure all the parameters are */
+/* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
+/* have questions. */
+/* */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <cfloat>
+#include "predicates.h"
+
+/* FPU control. We MUST have only double precision (not extended precision) */
+#include "rounding.h"
+
+/* On some machines, the exact arithmetic routines might be defeated by the */
+/* use of internal extended precision floating-point registers. Sometimes */
+/* this problem can be fixed by defining certain values to be volatile, */
+/* thus forcing them to be stored to memory and rounded off. This isn't */
+/* a great solution, though, as it slows the arithmetic down. */
+/* */
+/* To try this out, write "#define INEXACT volatile" below. Normally, */
+/* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
+
+#define INEXACT /* Nothing */
+/* #define INEXACT volatile */
+
+#define REAL double /* float or double */
+#define REALPRINT doubleprint
+#define REALRAND doublerand
+#define NARROWRAND narrowdoublerand
+#define UNIFORMRAND uniformdoublerand
+
+/* Which of the following two methods of finding the absolute values is */
+/* fastest is compiler-dependent. A few compilers can inline and optimize */
+/* the fabs() call; but most will incur the overhead of a function call, */
+/* which is disastrously slow. A faster way on IEEE machines might be to */
+/* mask the appropriate bit, but that's difficult to do in C. */
+
+/*#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) */
+#define Absolute(a) fabs(a)
+
+/* Many of the operations are broken up into two pieces, a main part that */
+/* performs an approximate operation, and a "tail" that computes the */
+/* roundoff error of that operation. */
+/* */
+/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
+/* Split(), and Two_Product() are all implemented as described in the */
+/* reference. Each of these macros requires certain variables to be */
+/* defined in the calling routine. The variables `bvirt', `c', `abig', */
+/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
+/* they store the result of an operation that may incur roundoff error. */
+/* The input parameter `x' (or the highest numbered `x_' parameter) must */
+/* also be declared `INEXACT'. */
+
+#define Fast_Two_Sum_Tail(a, b, x, y) \
+ bvirt = x - a; \
+ y = b - bvirt
+
+#define Fast_Two_Sum(a, b, x, y) \
+ x = (REAL) (a + b); \
+ Fast_Two_Sum_Tail(a, b, x, y)
+
+#define Fast_Two_Diff_Tail(a, b, x, y) \
+ bvirt = a - x; \
+ y = bvirt - b
+
+#define Fast_Two_Diff(a, b, x, y) \
+ x = (REAL) (a - b); \
+ Fast_Two_Diff_Tail(a, b, x, y)
+
+#define Two_Sum_Tail(a, b, x, y) \
+ bvirt = (REAL) (x - a); \
+ avirt = x - bvirt; \
+ bround = b - bvirt; \
+ around = a - avirt; \
+ y = around + bround
+
+#define Two_Sum(a, b, x, y) \
+ x = (REAL) (a + b); \
+ Two_Sum_Tail(a, b, x, y)
+
+#define Two_Diff_Tail(a, b, x, y) \
+ bvirt = (REAL) (a - x); \
+ avirt = x + bvirt; \
+ bround = bvirt - b; \
+ around = a - avirt; \
+ y = around + bround
+
+#define Two_Diff(a, b, x, y) \
+ x = (REAL) (a - b); \
+ Two_Diff_Tail(a, b, x, y)
+
+#define Split(a, ahi, alo) \
+ c = (REAL) (splitter * a); \
+ abig = (REAL) (c - a); \
+ ahi = c - abig; \
+ alo = a - ahi
+
+#define Two_Product_Tail(a, b, x, y) \
+ Split(a, ahi, alo); \
+ Split(b, bhi, blo); \
+ err1 = x - (ahi * bhi); \
+ err2 = err1 - (alo * bhi); \
+ err3 = err2 - (ahi * blo); \
+ y = (alo * blo) - err3
+
+#define Two_Product(a, b, x, y) \
+ x = (REAL) (a * b); \
+ Two_Product_Tail(a, b, x, y)
+
+/* Two_Product_Presplit() is Two_Product() where one of the inputs has */
+/* already been split. Avoids redundant splitting. */
+
+#define Two_Product_Presplit(a, b, bhi, blo, x, y) \
+ x = (REAL) (a * b); \
+ Split(a, ahi, alo); \
+ err1 = x - (ahi * bhi); \
+ err2 = err1 - (alo * bhi); \
+ err3 = err2 - (ahi * blo); \
+ y = (alo * blo) - err3
+
+/* Two_Product_2Presplit() is Two_Product() where both of the inputs have */
+/* already been split. Avoids redundant splitting. */
+
+#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \
+ x = (REAL) (a * b); \
+ err1 = x - (ahi * bhi); \
+ err2 = err1 - (alo * bhi); \
+ err3 = err2 - (ahi * blo); \
+ y = (alo * blo) - err3
+
+/* Square() can be done more quickly than Two_Product(). */
+
+#define Square_Tail(a, x, y) \
+ Split(a, ahi, alo); \
+ err1 = x - (ahi * ahi); \
+ err3 = err1 - ((ahi + ahi) * alo); \
+ y = (alo * alo) - err3
+
+#define Square(a, x, y) \
+ x = (REAL) (a * a); \
+ Square_Tail(a, x, y)
+
+/* Macros for summing expansions of various fixed lengths. These are all */
+/* unrolled versions of Expansion_Sum(). */
+
+#define Two_One_Sum(a1, a0, b, x2, x1, x0) \
+ Two_Sum(a0, b , _i, x0); \
+ Two_Sum(a1, _i, x2, x1)
+
+#define Two_One_Diff(a1, a0, b, x2, x1, x0) \
+ Two_Diff(a0, b , _i, x0); \
+ Two_Sum( a1, _i, x2, x1)
+
+#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
+ Two_One_Sum(a1, a0, b0, _j, _0, x0); \
+ Two_One_Sum(_j, _0, b1, x3, x2, x1)
+
+#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
+ Two_One_Diff(a1, a0, b0, _j, _0, x0); \
+ Two_One_Diff(_j, _0, b1, x3, x2, x1)
+
+#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \
+ Two_One_Sum(a1, a0, b , _j, x1, x0); \
+ Two_One_Sum(a3, a2, _j, x4, x3, x2)
+
+#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \
+ Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \
+ Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)
+
+#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \
+ x1, x0) \
+ Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \
+ Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)
+
+#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \
+ x3, x2, x1, x0) \
+ Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \
+ Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)
+
+#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \
+ x6, x5, x4, x3, x2, x1, x0) \
+ Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \
+ _1, _0, x0); \
+ Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \
+ x3, x2, x1)
+
+#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \
+ x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \
+ Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \
+ _2, _1, _0, x1, x0); \
+ Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \
+ x7, x6, x5, x4, x3, x2)
+
+/* Macros for multiplying expansions of various fixed lengths. */
+
+#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
+ Split(b, bhi, blo); \
+ Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
+ Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x1); \
+ Fast_Two_Sum(_j, _k, x3, x2)
+
+#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \
+ Split(b, bhi, blo); \
+ Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
+ Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x1); \
+ Fast_Two_Sum(_j, _k, _i, x2); \
+ Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x3); \
+ Fast_Two_Sum(_j, _k, _i, x4); \
+ Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x5); \
+ Fast_Two_Sum(_j, _k, x7, x6)
+
+#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \
+ Split(a0, a0hi, a0lo); \
+ Split(b0, bhi, blo); \
+ Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \
+ Split(a1, a1hi, a1lo); \
+ Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, _1); \
+ Fast_Two_Sum(_j, _k, _l, _2); \
+ Split(b1, bhi, blo); \
+ Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \
+ Two_Sum(_1, _0, _k, x1); \
+ Two_Sum(_2, _k, _j, _1); \
+ Two_Sum(_l, _j, _m, _2); \
+ Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _n, _0); \
+ Two_Sum(_1, _0, _i, x2); \
+ Two_Sum(_2, _i, _k, _1); \
+ Two_Sum(_m, _k, _l, _2); \
+ Two_Sum(_j, _n, _k, _0); \
+ Two_Sum(_1, _0, _j, x3); \
+ Two_Sum(_2, _j, _i, _1); \
+ Two_Sum(_l, _i, _m, _2); \
+ Two_Sum(_1, _k, _i, x4); \
+ Two_Sum(_2, _i, _k, x5); \
+ Two_Sum(_m, _k, x7, x6)
+
+/* An expansion of length two can be squared more quickly than finding the */
+/* product of two different expansions of length two, and the result is */
+/* guaranteed to have no more than six (rather than eight) components. */
+
+#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
+ Square(a0, _j, x0); \
+ _0 = a0 + a0; \
+ Two_Product(a1, _0, _k, _1); \
+ Two_One_Sum(_k, _1, _j, _l, _2, x1); \
+ Square(a1, _j, _1); \
+ Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
+
+/* 2^(-p), where p=DBL_MANT_DIG. Used to estimate roundoff errors. */
+static const REAL epsilon=0.5*DBL_EPSILON;
+
+/* 2^ceiling(p/2) + 1. Used to split floats in half. */
+static const REAL splitter=sqrt((DBL_MANT_DIG % 2 ? 2.0 : 1.0)/epsilon)+1.0;
+
+/* A set of coefficients used to calculate maximum roundoff errors. */
+const REAL resulterrbound=(3.0 + 8.0 * epsilon) * epsilon;
+const REAL ccwerrboundA=(3.0 + 16.0 * epsilon) * epsilon;
+const REAL ccwerrboundB=(2.0 + 12.0 * epsilon) * epsilon;
+const REAL ccwerrboundC=(9.0 + 64.0 * epsilon) * epsilon * epsilon;
+const REAL o3derrboundA=(7.0 + 56.0 * epsilon) * epsilon;
+const REAL o3derrboundB=(3.0 + 28.0 * epsilon) * epsilon;
+const REAL o3derrboundC=(26.0 + 288.0 * epsilon) * epsilon * epsilon;
+const REAL iccerrboundA=(10.0 + 96.0 * epsilon) * epsilon;
+const REAL iccerrboundB=(4.0 + 48.0 * epsilon) * epsilon;
+const REAL iccerrboundC=(44.0 + 576.0 * epsilon) * epsilon * epsilon;
+const REAL isperrboundA=(16.0 + 224.0 * epsilon) * epsilon;
+const REAL isperrboundB=(5.0 + 72.0 * epsilon) * epsilon;
+const REAL isperrboundC=(71.0 + 1408.0 * epsilon) * epsilon * epsilon;
+
+/*****************************************************************************/
+/* */
+/* doubleprint() Print the bit representation of a double. */
+/* */
+/* Useful for debugging exact arithmetic routines. */
+/* */
+/*****************************************************************************/
+
+/*
+void doubleprint(number)
+double number;
+{
+ unsigned long long no;
+ unsigned long long sign, expo;
+ int exponent;
+ int i, bottomi;
+
+ no = *(unsigned long long *) &number;
+ sign = no & 0x8000000000000000ll;
+ expo = (no >> 52) & 0x7ffll;
+ exponent = (int) expo;
+ exponent = exponent - 1023;
+ if (sign) {
+ printf("-");
+ } else {
+ printf(" ");
+ }
+ if (exponent == -1023) {
+ printf(
+ "0.0000000000000000000000000000000000000000000000000000_ ( )");
+ } else {
+ printf("1.");
+ bottomi = -1;
+ for (i = 0; i < 52; i++) {
+ if (no & 0x0008000000000000ll) {
+ printf("1");
+ bottomi = i;
+ } else {
+ printf("0");
+ }
+ no <<= 1;
+ }
+ printf("_%d (%d)", exponent, exponent - 1 - bottomi);
+ }
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* floatprint() Print the bit representation of a float. */
+/* */
+/* Useful for debugging exact arithmetic routines. */
+/* */
+/*****************************************************************************/
+
+/*
+void floatprint(number)
+float number;
+{
+ unsigned no;
+ unsigned sign, expo;
+ int exponent;
+ int i, bottomi;
+
+ no = *(unsigned *) &number;
+ sign = no & 0x80000000;
+ expo = (no >> 23) & 0xff;
+ exponent = (int) expo;
+ exponent = exponent - 127;
+ if (sign) {
+ printf("-");
+ } else {
+ printf(" ");
+ }
+ if (exponent == -127) {
+ printf("0.00000000000000000000000_ ( )");
+ } else {
+ printf("1.");
+ bottomi = -1;
+ for (i = 0; i < 23; i++) {
+ if (no & 0x00400000) {
+ printf("1");
+ bottomi = i;
+ } else {
+ printf("0");
+ }
+ no <<= 1;
+ }
+ printf("_%3d (%3d)", exponent, exponent - 1 - bottomi);
+ }
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* expansion_print() Print the bit representation of an expansion. */
+/* */
+/* Useful for debugging exact arithmetic routines. */
+/* */
+/*****************************************************************************/
+
+/*
+void expansion_print(elen, e)
+int elen;
+REAL *e;
+{
+ int i;
+
+ for (i = elen - 1; i >= 0; i--) {
+ REALPRINT(e[i]);
+ if (i > 0) {
+ printf(" +\n");
+ } else {
+ printf("\n");
+ }
+ }
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* doublerand() Generate a double with random 53-bit significand and a */
+/* random exponent in [0, 511]. */
+/* */
+/*****************************************************************************/
+
+/*
+static double doublerand()
+{
+ double result;
+ double expo;
+ long a, b, c;
+ long i;
+
+ a = random();
+ b = random();
+ c = random();
+ result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+ for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* narrowdoublerand() Generate a double with random 53-bit significand */
+/* and a random exponent in [0, 7]. */
+/* */
+/*****************************************************************************/
+
+/*
+static double narrowdoublerand()
+{
+ double result;
+ double expo;
+ long a, b, c;
+ long i;
+
+ a = random();
+ b = random();
+ c = random();
+ result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+ for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* uniformdoublerand() Generate a double with random 53-bit significand. */
+/* */
+/*****************************************************************************/
+
+/*
+static double uniformdoublerand()
+{
+ double result;
+ long a, b;
+
+ a = random();
+ b = random();
+ result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* floatrand() Generate a float with random 24-bit significand and a */
+/* random exponent in [0, 63]. */
+/* */
+/*****************************************************************************/
+
+/*
+static float floatrand()
+{
+ float result;
+ float expo;
+ long a, c;
+ long i;
+
+ a = random();
+ c = random();
+ result = (float) ((a - 1073741824) >> 6);
+ for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* narrowfloatrand() Generate a float with random 24-bit significand and */
+/* a random exponent in [0, 7]. */
+/* */
+/*****************************************************************************/
+
+/*
+static float narrowfloatrand()
+{
+ float result;
+ float expo;
+ long a, c;
+ long i;
+
+ a = random();
+ c = random();
+ result = (float) ((a - 1073741824) >> 6);
+ for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* uniformfloatrand() Generate a float with random 24-bit significand. */
+/* */
+/*****************************************************************************/
+
+/*
+static float uniformfloatrand()
+{
+ float result;
+ long a;
+
+ a = random();
+ result = (float) ((a - 1073741824) >> 6);
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
+/* components from the output expansion. */
+/* */
+/* Sets h = e + f. See the long version of my paper for details. */
+/* */
+/* If round-to-even is used (as with IEEE 754), maintains the strongly */
+/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
+/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
+/* properties. */
+/* */
+/*****************************************************************************/
+
+static int fast_expansion_sum_zeroelim(int elen, const REAL *e,
+ int flen, const REAL *f, REAL *h)
+ /* h cannot be e or f. */
+{
+ REAL Q;
+ INEXACT REAL Qnew;
+ INEXACT REAL hh;
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ int eindex, findex, hindex;
+ REAL enow, fnow;
+
+ enow = e[0];
+ fnow = f[0];
+ eindex = findex = 0;
+ if ((fnow > enow) == (fnow > -enow)) {
+ Q = enow;
+ enow = e[++eindex];
+ } else {
+ Q = fnow;
+ fnow = f[++findex];
+ }
+ hindex = 0;
+ if ((eindex < elen) && (findex < flen)) {
+ if ((fnow > enow) == (fnow > -enow)) {
+ Fast_Two_Sum(enow, Q, Qnew, hh);
+ enow = e[++eindex];
+ } else {
+ Fast_Two_Sum(fnow, Q, Qnew, hh);
+ fnow = f[++findex];
+ }
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ while ((eindex < elen) && (findex < flen)) {
+ if ((fnow > enow) == (fnow > -enow)) {
+ Two_Sum(Q, enow, Qnew, hh);
+ enow = e[++eindex];
+ } else {
+ Two_Sum(Q, fnow, Qnew, hh);
+ fnow = f[++findex];
+ }
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ }
+ }
+ while (eindex < elen) {
+ Two_Sum(Q, enow, Qnew, hh);
+ enow = e[++eindex];
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ }
+ while (findex < flen) {
+ Two_Sum(Q, fnow, Qnew, hh);
+ fnow = f[++findex];
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ }
+ if ((Q != 0.0) || (hindex == 0)) {
+ h[hindex++] = Q;
+ }
+ return hindex;
+}
+
+/*****************************************************************************/
+/* */
+/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
+/* eliminating zero components from the */
+/* output expansion. */
+/* */
+/* Sets h = be. See either version of my paper for details. */
+/* */
+/* Maintains the nonoverlapping property. If round-to-even is used (as */
+/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
+/* properties as well. (That is, if e has one of these properties, so */
+/* will h.) */
+/* */
+/*****************************************************************************/
+
+static int scale_expansion_zeroelim(int elen, const REAL *e, REAL b, REAL *h)
+ /* e and h cannot be the same. */
+{
+ INEXACT REAL Q, sum;
+ REAL hh;
+ INEXACT REAL product1;
+ REAL product0;
+ int eindex, hindex;
+ REAL enow;
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+
+ Split(b, bhi, blo);
+ Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
+ hindex = 0;
+ if (hh != 0) {
+ h[hindex++] = hh;
+ }
+ for (eindex = 1; eindex < elen; eindex++) {
+ enow = e[eindex];
+ Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
+ Two_Sum(Q, product0, sum, hh);
+ if (hh != 0) {
+ h[hindex++] = hh;
+ }
+ Fast_Two_Sum(product1, sum, Q, hh);
+ if (hh != 0) {
+ h[hindex++] = hh;
+ }
+ }
+ if ((Q != 0.0) || (hindex == 0)) {
+ h[hindex++] = Q;
+ }
+ return hindex;
+}
+
+/*****************************************************************************/
+/* */
+/* estimate() Produce a one-word estimate of an expansion's value. */
+/* */
+/* See either version of my paper for details. */
+/* */
+/*****************************************************************************/
+
+static REAL estimate(int elen, const REAL *e)
+{
+ REAL Q;
+ int eindex;
+
+ Q = e[0];
+ for (eindex = 1; eindex < elen; eindex++) {
+ Q += e[eindex];
+ }
+ return Q;
+}
+
+/*****************************************************************************/
+/* */
+/* orient2dfast() Approximate 2D orientation test. Nonrobust. */
+/* orient2dexact() Exact 2D orientation test. Robust. */
+/* orient2dslow() Another exact 2D orientation test. Robust. */
+/* orient2d() Adaptive exact 2D orientation test. Robust. */
+/* */
+/* Return a positive value if the points pa, pb, and pc occur */
+/* in counterclockwise order; a negative value if they occur */
+/* in clockwise order; and zero if they are collinear. The */
+/* result is also a rough approximation of twice the signed */
+/* area of the triangle defined by the three points. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In orient2d() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, orient2d() is usually quite */
+/* fast, but will run more slowly when the input points are collinear or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+REAL orient2dadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL detsum)
+{
+ INEXACT REAL acx, acy, bcx, bcy;
+ REAL acxtail, acytail, bcxtail, bcytail;
+ INEXACT REAL detleft, detright;
+ REAL detlefttail, detrighttail;
+ REAL det, errbound;
+ REAL B[4], C1[8], C2[12], D[16];
+ INEXACT REAL B3;
+ int C1length, C2length, Dlength;
+ REAL u[4];
+ INEXACT REAL u3;
+ INEXACT REAL s1, t1;
+ REAL s0, t0;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ acx = (REAL) (pa[0] - pc[0]);
+ bcx = (REAL) (pb[0] - pc[0]);
+ acy = (REAL) (pa[1] - pc[1]);
+ bcy = (REAL) (pb[1] - pc[1]);
+
+ Two_Product(acx, bcy, detleft, detlefttail);
+ Two_Product(acy, bcx, detright, detrighttail);
+
+ Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
+ B3, B[2], B[1], B[0]);
+ B[3] = B3;
+
+ det = estimate(4, B);
+ errbound = ccwerrboundB * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
+ Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
+ Two_Diff_Tail(pa[1], pc[1], acy, acytail);
+ Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
+
+ if ((acxtail == 0.0) && (acytail == 0.0)
+ && (bcxtail == 0.0) && (bcytail == 0.0)) {
+ return det;
+ }
+
+ errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
+ det += (acx * bcytail + bcy * acxtail)
+ - (acy * bcxtail + bcx * acytail);
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Product(acxtail, bcy, s1, s0);
+ Two_Product(acytail, bcx, t1, t0);
+ Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
+
+ Two_Product(acx, bcytail, s1, s0);
+ Two_Product(acy, bcxtail, t1, t0);
+ Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
+
+ Two_Product(acxtail, bcytail, s1, s0);
+ Two_Product(acytail, bcxtail, t1, t0);
+ Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
+
+ return(D[Dlength - 1]);
+}
+
+REAL orient2d(const REAL *pa, const REAL *pb, const REAL *pc)
+{
+ REAL detleft, detright, det;
+ REAL detsum, errbound;
+ REAL orient;
+
+ FPU_ROUND_DOUBLE;
+
+ detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
+ detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
+ det = detleft - detright;
+
+ if (detleft > 0.0) {
+ if (detright <= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = detleft + detright;
+ }
+ } else if (detleft < 0.0) {
+ if (detright >= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = -detleft - detright;
+ }
+ } else {
+ FPU_RESTORE;
+ return det;
+ }
+
+ errbound = ccwerrboundA * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ orient = orient2dadapt(pa, pb, pc, detsum);
+ FPU_RESTORE;
+ return orient;
+}
+
+REAL orient2d(const REAL ax, const REAL ay, const REAL bx, const REAL by,
+ const REAL cx, const REAL cy)
+{
+ REAL detleft, detright, det;
+ REAL detsum, errbound;
+ REAL orient;
+
+ FPU_ROUND_DOUBLE;
+
+ detleft = (ax - cx) * (by - cy);
+ detright = (ay - cy) * (bx - cx);
+ det = detleft - detright;
+
+ if (detleft > 0.0) {
+ if (detright <= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = detleft + detright;
+ }
+ } else if (detleft < 0.0) {
+ if (detright >= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = -detleft - detright;
+ }
+ } else {
+ FPU_RESTORE;
+ return det;
+ }
+
+ errbound = ccwerrboundA * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ REAL pa[]={ax,ay};
+ REAL pb[]={bx,by};
+ REAL pc[]={cx,cy};
+
+ orient = orient2dadapt(pa, pb, pc, detsum);
+ FPU_RESTORE;
+ return orient;
+}
+
+/*****************************************************************************/
+/* */
+/* orient3dfast() Approximate 3D orientation test. Nonrobust. */
+/* orient3dexact() Exact 3D orientation test. Robust. */
+/* orient3dslow() Another exact 3D orientation test. Robust. */
+/* orient3d() Adaptive exact 3D orientation test. Robust. */
+/* */
+/* Return a positive value if the point pd lies below the */
+/* plane passing through pa, pb, and pc; "below" is defined so */
+/* that pa, pb, and pc appear in counterclockwise order when */
+/* viewed from above the plane. Returns a negative value if */
+/* pd lies above the plane. Returns zero if the points are */
+/* coplanar. The result is also a rough approximation of six */
+/* times the signed volume of the tetrahedron defined by the */
+/* four points. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In orient3d() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, orient3d() is usually quite */
+/* fast, but will run more slowly when the input points are coplanar or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+static REAL orient3dadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd,
+ REAL permanent)
+{
+ INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
+ REAL det, errbound;
+
+ INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
+ REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
+ REAL bc[4], ca[4], ab[4];
+ INEXACT REAL bc3, ca3, ab3;
+ REAL adet[8], bdet[8], cdet[8];
+ int alen, blen, clen;
+ REAL abdet[16];
+ int ablen;
+ REAL *finnow, *finother, *finswap;
+ REAL fin1[192], fin2[192];
+ int finlength;
+
+ REAL adxtail, bdxtail, cdxtail;
+ REAL adytail, bdytail, cdytail;
+ REAL adztail, bdztail, cdztail;
+ INEXACT REAL at_blarge, at_clarge;
+ INEXACT REAL bt_clarge, bt_alarge;
+ INEXACT REAL ct_alarge, ct_blarge;
+ REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
+ int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
+ INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
+ INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
+ REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
+ REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
+ INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
+ INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
+ REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
+ REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
+ REAL bct[8], cat[8], abt[8];
+ int bctlen, catlen, abtlen;
+ INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
+ INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
+ REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
+ REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
+ REAL u[4], v[12], w[16];
+ INEXACT REAL u3;
+ int vlength, wlength;
+ REAL negate;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j, _k;
+ REAL _0;
+
+ adx = (REAL) (pa[0] - pd[0]);
+ bdx = (REAL) (pb[0] - pd[0]);
+ cdx = (REAL) (pc[0] - pd[0]);
+ ady = (REAL) (pa[1] - pd[1]);
+ bdy = (REAL) (pb[1] - pd[1]);
+ cdy = (REAL) (pc[1] - pd[1]);
+ adz = (REAL) (pa[2] - pd[2]);
+ bdz = (REAL) (pb[2] - pd[2]);
+ cdz = (REAL) (pc[2] - pd[2]);
+
+ Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
+ Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
+ Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
+ bc[3] = bc3;
+ alen = scale_expansion_zeroelim(4, bc, adz, adet);
+
+ Two_Product(cdx, ady, cdxady1, cdxady0);
+ Two_Product(adx, cdy, adxcdy1, adxcdy0);
+ Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
+ ca[3] = ca3;
+ blen = scale_expansion_zeroelim(4, ca, bdz, bdet);
+
+ Two_Product(adx, bdy, adxbdy1, adxbdy0);
+ Two_Product(bdx, ady, bdxady1, bdxady0);
+ Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
+ ab[3] = ab3;
+ clen = scale_expansion_zeroelim(4, ab, cdz, cdet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
+
+ det = estimate(finlength, fin1);
+ errbound = o3derrboundB * permanent;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
+ Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
+ Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
+ Two_Diff_Tail(pa[1], pd[1], ady, adytail);
+ Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
+ Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
+ Two_Diff_Tail(pa[2], pd[2], adz, adztail);
+ Two_Diff_Tail(pb[2], pd[2], bdz, bdztail);
+ Two_Diff_Tail(pc[2], pd[2], cdz, cdztail);
+
+ if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
+ && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)
+ && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) {
+ return det;
+ }
+
+ errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
+ det += (adz * ((bdx * cdytail + cdy * bdxtail)
+ - (bdy * cdxtail + cdx * bdytail))
+ + adztail * (bdx * cdy - bdy * cdx))
+ + (bdz * ((cdx * adytail + ady * cdxtail)
+ - (cdy * adxtail + adx * cdytail))
+ + bdztail * (cdx * ady - cdy * adx))
+ + (cdz * ((adx * bdytail + bdy * adxtail)
+ - (ady * bdxtail + bdx * adytail))
+ + cdztail * (adx * bdy - ady * bdx));
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ finnow = fin1;
+ finother = fin2;
+
+ if (adxtail == 0.0) {
+ if (adytail == 0.0) {
+ at_b[0] = 0.0;
+ at_blen = 1;
+ at_c[0] = 0.0;
+ at_clen = 1;
+ } else {
+ negate = -adytail;
+ Two_Product(negate, bdx, at_blarge, at_b[0]);
+ at_b[1] = at_blarge;
+ at_blen = 2;
+ Two_Product(adytail, cdx, at_clarge, at_c[0]);
+ at_c[1] = at_clarge;
+ at_clen = 2;
+ }
+ } else {
+ if (adytail == 0.0) {
+ Two_Product(adxtail, bdy, at_blarge, at_b[0]);
+ at_b[1] = at_blarge;
+ at_blen = 2;
+ negate = -adxtail;
+ Two_Product(negate, cdy, at_clarge, at_c[0]);
+ at_c[1] = at_clarge;
+ at_clen = 2;
+ } else {
+ Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
+ Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
+ Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
+ at_blarge, at_b[2], at_b[1], at_b[0]);
+ at_b[3] = at_blarge;
+ at_blen = 4;
+ Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
+ Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
+ Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
+ at_clarge, at_c[2], at_c[1], at_c[0]);
+ at_c[3] = at_clarge;
+ at_clen = 4;
+ }
+ }
+ if (bdxtail == 0.0) {
+ if (bdytail == 0.0) {
+ bt_c[0] = 0.0;
+ bt_clen = 1;
+ bt_a[0] = 0.0;
+ bt_alen = 1;
+ } else {
+ negate = -bdytail;
+ Two_Product(negate, cdx, bt_clarge, bt_c[0]);
+ bt_c[1] = bt_clarge;
+ bt_clen = 2;
+ Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
+ bt_a[1] = bt_alarge;
+ bt_alen = 2;
+ }
+ } else {
+ if (bdytail == 0.0) {
+ Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
+ bt_c[1] = bt_clarge;
+ bt_clen = 2;
+ negate = -bdxtail;
+ Two_Product(negate, ady, bt_alarge, bt_a[0]);
+ bt_a[1] = bt_alarge;
+ bt_alen = 2;
+ } else {
+ Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
+ Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
+ Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
+ bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
+ bt_c[3] = bt_clarge;
+ bt_clen = 4;
+ Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
+ Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
+ Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
+ bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
+ bt_a[3] = bt_alarge;
+ bt_alen = 4;
+ }
+ }
+ if (cdxtail == 0.0) {
+ if (cdytail == 0.0) {
+ ct_a[0] = 0.0;
+ ct_alen = 1;
+ ct_b[0] = 0.0;
+ ct_blen = 1;
+ } else {
+ negate = -cdytail;
+ Two_Product(negate, adx, ct_alarge, ct_a[0]);
+ ct_a[1] = ct_alarge;
+ ct_alen = 2;
+ Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
+ ct_b[1] = ct_blarge;
+ ct_blen = 2;
+ }
+ } else {
+ if (cdytail == 0.0) {
+ Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
+ ct_a[1] = ct_alarge;
+ ct_alen = 2;
+ negate = -cdxtail;
+ Two_Product(negate, bdy, ct_blarge, ct_b[0]);
+ ct_b[1] = ct_blarge;
+ ct_blen = 2;
+ } else {
+ Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
+ Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
+ Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
+ ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
+ ct_a[3] = ct_alarge;
+ ct_alen = 4;
+ Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
+ Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
+ Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
+ ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
+ ct_b[3] = ct_blarge;
+ ct_blen = 4;
+ }
+ }
+
+ bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
+ wlength = scale_expansion_zeroelim(bctlen, bct, adz, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+ catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
+ wlength = scale_expansion_zeroelim(catlen, cat, bdz, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+ abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
+ wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+ if (adztail != 0.0) {
+ vlength = scale_expansion_zeroelim(4, bc, adztail, v);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdztail != 0.0) {
+ vlength = scale_expansion_zeroelim(4, ca, bdztail, v);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdztail != 0.0) {
+ vlength = scale_expansion_zeroelim(4, ab, cdztail, v);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ if (adxtail != 0.0) {
+ if (bdytail != 0.0) {
+ Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
+ Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (cdztail != 0.0) {
+ Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if (cdytail != 0.0) {
+ negate = -adxtail;
+ Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
+ Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (bdztail != 0.0) {
+ Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ }
+ if (bdxtail != 0.0) {
+ if (cdytail != 0.0) {
+ Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
+ Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (adztail != 0.0) {
+ Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if (adytail != 0.0) {
+ negate = -bdxtail;
+ Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
+ Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (cdztail != 0.0) {
+ Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ }
+ if (cdxtail != 0.0) {
+ if (adytail != 0.0) {
+ Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
+ Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (bdztail != 0.0) {
+ Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if (bdytail != 0.0) {
+ negate = -cdxtail;
+ Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
+ Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (adztail != 0.0) {
+ Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ }
+
+ if (adztail != 0.0) {
+ wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdztail != 0.0) {
+ wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdztail != 0.0) {
+ wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ return finnow[finlength - 1];
+}
+
+REAL orient3d(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd)
+{
+ REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
+ REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
+ REAL det;
+ REAL permanent, errbound;
+ REAL orient;
+
+ FPU_ROUND_DOUBLE;
+
+ adx = pa[0] - pd[0];
+ bdx = pb[0] - pd[0];
+ cdx = pc[0] - pd[0];
+ ady = pa[1] - pd[1];
+ bdy = pb[1] - pd[1];
+ cdy = pc[1] - pd[1];
+ adz = pa[2] - pd[2];
+ bdz = pb[2] - pd[2];
+ cdz = pc[2] - pd[2];
+
+ bdxcdy = bdx * cdy;
+ cdxbdy = cdx * bdy;
+
+ cdxady = cdx * ady;
+ adxcdy = adx * cdy;
+
+ adxbdy = adx * bdy;
+ bdxady = bdx * ady;
+
+ det = adz * (bdxcdy - cdxbdy)
+ + bdz * (cdxady - adxcdy)
+ + cdz * (adxbdy - bdxady);
+
+ permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz)
+ + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz)
+ + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz);
+ errbound = o3derrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ orient = orient3dadapt(pa, pb, pc, pd, permanent);
+ FPU_RESTORE;
+ return orient;
+}
+
+/*****************************************************************************/
+/* */
+/* incirclefast() Approximate 2D incircle test. Nonrobust. */
+/* incircleexact() Exact 2D incircle test. Robust. */
+/* incircleslow() Another exact 2D incircle test. Robust. */
+/* incircle() Adaptive exact 2D incircle test. Robust. */
+/* */
+/* Return a positive value if the point pd lies inside the */
+/* circle passing through pa, pb, and pc; a negative value if */
+/* it lies outside; and zero if the four points are cocircular.*/
+/* The points pa, pb, and pc must be in counterclockwise */
+/* order, or the sign of the result will be reversed. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In incircle() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, incircle() is usually quite */
+/* fast, but will run more slowly when the input points are cocircular or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+static REAL incircleadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd,
+ REAL permanent)
+{
+ INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
+ REAL det, errbound;
+
+ INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
+ REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
+ REAL bc[4], ca[4], ab[4];
+ INEXACT REAL bc3, ca3, ab3;
+ REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
+ int axbclen, axxbclen, aybclen, ayybclen, alen;
+ REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
+ int bxcalen, bxxcalen, bycalen, byycalen, blen;
+ REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
+ int cxablen, cxxablen, cyablen, cyyablen, clen;
+ REAL abdet[64];
+ int ablen;
+ REAL fin1[1152], fin2[1152];
+ REAL *finnow, *finother, *finswap;
+ int finlength;
+
+ REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
+ INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
+ REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
+ REAL aa[4], bb[4], cc[4];
+ INEXACT REAL aa3, bb3, cc3;
+ INEXACT REAL ti1, tj1;
+ REAL ti0, tj0;
+ REAL u[4], v[4];
+ INEXACT REAL u3, v3;
+ REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
+ REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
+ int temp8len, temp16alen, temp16blen, temp16clen;
+ int temp32alen, temp32blen, temp48len, temp64len;
+ REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
+ int axtbblen, axtcclen, aytbblen, aytcclen;
+ REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
+ int bxtaalen, bxtcclen, bytaalen, bytcclen;
+ REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
+ int cxtaalen, cxtbblen, cytaalen, cytbblen;
+ REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
+ int axtbclen = 0, aytbclen = 0;
+ int bxtcalen = 0, bytcalen = 0;
+ int cxtablen = 0, cytablen = 0;
+ REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
+ int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
+ REAL axtbctt[8], aytbctt[8], bxtcatt[8];
+ REAL bytcatt[8], cxtabtt[8], cytabtt[8];
+ int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
+ REAL abt[8], bct[8], cat[8];
+ int abtlen, bctlen, catlen;
+ REAL abtt[4], bctt[4], catt[4];
+ int abttlen, bcttlen, cattlen;
+ INEXACT REAL abtt3, bctt3, catt3;
+ REAL negate;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ adx = (REAL) (pa[0] - pd[0]);
+ bdx = (REAL) (pb[0] - pd[0]);
+ cdx = (REAL) (pc[0] - pd[0]);
+ ady = (REAL) (pa[1] - pd[1]);
+ bdy = (REAL) (pb[1] - pd[1]);
+ cdy = (REAL) (pc[1] - pd[1]);
+
+ Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
+ Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
+ Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
+ bc[3] = bc3;
+ axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
+ axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
+ aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
+ ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
+ alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
+
+ Two_Product(cdx, ady, cdxady1, cdxady0);
+ Two_Product(adx, cdy, adxcdy1, adxcdy0);
+ Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
+ ca[3] = ca3;
+ bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
+ bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
+ bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
+ byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
+ blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
+
+ Two_Product(adx, bdy, adxbdy1, adxbdy0);
+ Two_Product(bdx, ady, bdxady1, bdxady0);
+ Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
+ ab[3] = ab3;
+ cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
+ cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
+ cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
+ cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
+ clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
+
+ det = estimate(finlength, fin1);
+ errbound = iccerrboundB * permanent;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
+ Two_Diff_Tail(pa[1], pd[1], ady, adytail);
+ Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
+ Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
+ Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
+ Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
+ if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
+ && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) {
+ return det;
+ }
+
+ errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
+ det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
+ - (bdy * cdxtail + cdx * bdytail))
+ + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
+ + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
+ - (cdy * adxtail + adx * cdytail))
+ + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
+ + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail)
+ - (ady * bdxtail + bdx * adytail))
+ + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ finnow = fin1;
+ finother = fin2;
+
+ if ((bdxtail != 0.0) || (bdytail != 0.0)
+ || (cdxtail != 0.0) || (cdytail != 0.0)) {
+ Square(adx, adxadx1, adxadx0);
+ Square(ady, adyady1, adyady0);
+ Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
+ aa[3] = aa3;
+ }
+ if ((cdxtail != 0.0) || (cdytail != 0.0)
+ || (adxtail != 0.0) || (adytail != 0.0)) {
+ Square(bdx, bdxbdx1, bdxbdx0);
+ Square(bdy, bdybdy1, bdybdy0);
+ Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
+ bb[3] = bb3;
+ }
+ if ((adxtail != 0.0) || (adytail != 0.0)
+ || (bdxtail != 0.0) || (bdytail != 0.0)) {
+ Square(cdx, cdxcdx1, cdxcdx0);
+ Square(cdy, cdycdy1, cdycdy0);
+ Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
+ cc[3] = cc3;
+ }
+
+ if (adxtail != 0.0) {
+ axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
+ temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx,
+ temp16a);
+
+ axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
+ temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
+
+ axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
+ temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (adytail != 0.0) {
+ aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
+ temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady,
+ temp16a);
+
+ aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
+ temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
+
+ aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
+ temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdxtail != 0.0) {
+ bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
+ temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx,
+ temp16a);
+
+ bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
+ temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
+
+ bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
+ temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdytail != 0.0) {
+ bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
+ temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy,
+ temp16a);
+
+ bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
+ temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
+
+ bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
+ temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdxtail != 0.0) {
+ cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
+ temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx,
+ temp16a);
+
+ cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
+ temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
+
+ cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
+ temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdytail != 0.0) {
+ cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
+ temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy,
+ temp16a);
+
+ cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
+ temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
+
+ cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
+ temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ if ((adxtail != 0.0) || (adytail != 0.0)) {
+ if ((bdxtail != 0.0) || (bdytail != 0.0)
+ || (cdxtail != 0.0) || (cdytail != 0.0)) {
+ Two_Product(bdxtail, cdy, ti1, ti0);
+ Two_Product(bdx, cdytail, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ negate = -bdy;
+ Two_Product(cdxtail, negate, ti1, ti0);
+ negate = -bdytail;
+ Two_Product(cdx, negate, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
+ v[3] = v3;
+ bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
+
+ Two_Product(bdxtail, cdytail, ti1, ti0);
+ Two_Product(cdxtail, bdytail, tj1, tj0);
+ Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
+ bctt[3] = bctt3;
+ bcttlen = 4;
+ } else {
+ bct[0] = 0.0;
+ bctlen = 1;
+ bctt[0] = 0.0;
+ bcttlen = 1;
+ }
+
+ if (adxtail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
+ axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
+ temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (bdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail,
+ temp32a);
+ axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
+ temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (adytail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
+ aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
+ temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+
+ temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail,
+ temp32a);
+ aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
+ temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if ((bdxtail != 0.0) || (bdytail != 0.0)) {
+ if ((cdxtail != 0.0) || (cdytail != 0.0)
+ || (adxtail != 0.0) || (adytail != 0.0)) {
+ Two_Product(cdxtail, ady, ti1, ti0);
+ Two_Product(cdx, adytail, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ negate = -cdy;
+ Two_Product(adxtail, negate, ti1, ti0);
+ negate = -cdytail;
+ Two_Product(adx, negate, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
+ v[3] = v3;
+ catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
+
+ Two_Product(cdxtail, adytail, ti1, ti0);
+ Two_Product(adxtail, cdytail, tj1, tj0);
+ Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
+ catt[3] = catt3;
+ cattlen = 4;
+ } else {
+ cat[0] = 0.0;
+ catlen = 1;
+ catt[0] = 0.0;
+ cattlen = 1;
+ }
+
+ if (bdxtail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
+ bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
+ temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (cdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (adytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail,
+ temp32a);
+ bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
+ temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdytail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
+ bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
+ temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+
+ temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail,
+ temp32a);
+ bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
+ temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if ((cdxtail != 0.0) || (cdytail != 0.0)) {
+ if ((adxtail != 0.0) || (adytail != 0.0)
+ || (bdxtail != 0.0) || (bdytail != 0.0)) {
+ Two_Product(adxtail, bdy, ti1, ti0);
+ Two_Product(adx, bdytail, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ negate = -ady;
+ Two_Product(bdxtail, negate, ti1, ti0);
+ negate = -adytail;
+ Two_Product(bdx, negate, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
+ v[3] = v3;
+ abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
+
+ Two_Product(adxtail, bdytail, ti1, ti0);
+ Two_Product(bdxtail, adytail, tj1, tj0);
+ Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
+ abtt[3] = abtt3;
+ abttlen = 4;
+ } else {
+ abt[0] = 0.0;
+ abtlen = 1;
+ abtt[0] = 0.0;
+ abttlen = 1;
+ }
+
+ if (cdxtail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
+ cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
+ temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (adytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail,
+ temp32a);
+ cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
+ temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdytail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
+ cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
+ temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+
+ temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail,
+ temp32a);
+ cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
+ temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+
+ return finnow[finlength - 1];
+}
+
+REAL incircle(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd)
+{
+ REAL adx, bdx, cdx, ady, bdy, cdy;
+ REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
+ REAL alift, blift, clift;
+ REAL det;
+ REAL permanent, errbound;
+ REAL inc;
+
+ FPU_ROUND_DOUBLE;
+
+ adx = pa[0] - pd[0];
+ bdx = pb[0] - pd[0];
+ cdx = pc[0] - pd[0];
+ ady = pa[1] - pd[1];
+ bdy = pb[1] - pd[1];
+ cdy = pc[1] - pd[1];
+
+ bdxcdy = bdx * cdy;
+ cdxbdy = cdx * bdy;
+ alift = adx * adx + ady * ady;
+
+ cdxady = cdx * ady;
+ adxcdy = adx * cdy;
+ blift = bdx * bdx + bdy * bdy;
+
+ adxbdy = adx * bdy;
+ bdxady = bdx * ady;
+ clift = cdx * cdx + cdy * cdy;
+
+ det = alift * (bdxcdy - cdxbdy)
+ + blift * (cdxady - adxcdy)
+ + clift * (adxbdy - bdxady);
+
+ permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
+ + (Absolute(cdxady) + Absolute(adxcdy)) * blift
+ + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
+ errbound = iccerrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ inc = incircleadapt(pa, pb, pc, pd, permanent);
+ FPU_RESTORE;
+ return inc;
+}
+
+REAL incircle(REAL ax, REAL ay, REAL bx, REAL by, REAL cx, REAL cy, REAL dx,
+ REAL dy)
+{
+ REAL adx, bdx, cdx, ady, bdy, cdy;
+ REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
+ REAL alift, blift, clift;
+ REAL det;
+ REAL permanent, errbound;
+ REAL inc;
+
+ FPU_ROUND_DOUBLE;
+
+ adx = ax - dx;
+ bdx = bx - dx;
+ cdx = cx - dx;
+ ady = ay - dy;
+ bdy = by - dy;
+ cdy = cy - dy;
+
+ bdxcdy = bdx * cdy;
+ cdxbdy = cdx * bdy;
+ alift = adx * adx + ady * ady;
+
+ cdxady = cdx * ady;
+ adxcdy = adx * cdy;
+ blift = bdx * bdx + bdy * bdy;
+
+ adxbdy = adx * bdy;
+ bdxady = bdx * ady;
+ clift = cdx * cdx + cdy * cdy;
+
+ det = alift * (bdxcdy - cdxbdy)
+ + blift * (cdxady - adxcdy)
+ + clift * (adxbdy - bdxady);
+
+ permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
+ + (Absolute(cdxady) + Absolute(adxcdy)) * blift
+ + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
+ errbound = iccerrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ REAL pa[]={ax,ay};
+ REAL pb[]={bx,by};
+ REAL pc[]={cx,cy};
+ REAL pd[]={dx,dy};
+
+ inc = incircleadapt(pa, pb, pc, pd, permanent);
+ FPU_RESTORE;
+ return inc;
+}
+
+/*****************************************************************************/
+/* */
+/* inspherefast() Approximate 3D insphere test. Nonrobust. */
+/* insphereexact() Exact 3D insphere test. Robust. */
+/* insphereslow() Another exact 3D insphere test. Robust. */
+/* insphere() Adaptive exact 3D insphere test. Robust. */
+/* */
+/* Return a positive value if the point pe lies inside the */
+/* sphere passing through pa, pb, pc, and pd; a negative value */
+/* if it lies outside; and zero if the five points are */
+/* cospherical. The points pa, pb, pc, and pd must be ordered */
+/* so that they have a positive orientation (as defined by */
+/* orient3d()), or the sign of the result will be reversed. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In insphere() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, insphere() is usually quite */
+/* fast, but will run more slowly when the input points are cospherical or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+static REAL insphereexact(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd, const REAL *pe)
+{
+ INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1;
+ INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1;
+ INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1;
+ INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1;
+ REAL axby0, bxcy0, cxdy0, dxey0, exay0;
+ REAL bxay0, cxby0, dxcy0, exdy0, axey0;
+ REAL axcy0, bxdy0, cxey0, dxay0, exby0;
+ REAL cxay0, dxby0, excy0, axdy0, bxey0;
+ REAL ab[4], bc[4], cd[4], de[4], ea[4];
+ REAL ac[4], bd[4], ce[4], da[4], eb[4];
+ REAL temp8a[8], temp8b[8], temp16[16];
+ int temp8alen, temp8blen, temp16len;
+ REAL abc[24], bcd[24], cde[24], dea[24], eab[24];
+ REAL abd[24], bce[24], cda[24], deb[24], eac[24];
+ int abclen, bcdlen, cdelen, dealen, eablen;
+ int abdlen, bcelen, cdalen, deblen, eaclen;
+ REAL temp48a[48], temp48b[48];
+ int temp48alen, temp48blen;
+ REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96];
+ int abcdlen, bcdelen, cdealen, deablen, eabclen;
+ REAL temp192[192];
+ REAL det384x[384], det384y[384], det384z[384];
+ int xlen, ylen, zlen;
+ REAL detxy[768];
+ int xylen;
+ REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152];
+ int alen, blen, clen, dlen, elen;
+ REAL abdet[2304], cddet[2304], cdedet[3456];
+ int ablen, cdlen;
+ REAL deter[5760];
+ int deterlen;
+ int i;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ Two_Product(pa[0], pb[1], axby1, axby0);
+ Two_Product(pb[0], pa[1], bxay1, bxay0);
+ Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
+
+ Two_Product(pb[0], pc[1], bxcy1, bxcy0);
+ Two_Product(pc[0], pb[1], cxby1, cxby0);
+ Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
+
+ Two_Product(pc[0], pd[1], cxdy1, cxdy0);
+ Two_Product(pd[0], pc[1], dxcy1, dxcy0);
+ Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
+
+ Two_Product(pd[0], pe[1], dxey1, dxey0);
+ Two_Product(pe[0], pd[1], exdy1, exdy0);
+ Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]);
+
+ Two_Product(pe[0], pa[1], exay1, exay0);
+ Two_Product(pa[0], pe[1], axey1, axey0);
+ Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]);
+
+ Two_Product(pa[0], pc[1], axcy1, axcy0);
+ Two_Product(pc[0], pa[1], cxay1, cxay0);
+ Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
+
+ Two_Product(pb[0], pd[1], bxdy1, bxdy0);
+ Two_Product(pd[0], pb[1], dxby1, dxby0);
+ Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
+
+ Two_Product(pc[0], pe[1], cxey1, cxey0);
+ Two_Product(pe[0], pc[1], excy1, excy0);
+ Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]);
+
+ Two_Product(pd[0], pa[1], dxay1, dxay0);
+ Two_Product(pa[0], pd[1], axdy1, axdy0);
+ Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
+
+ Two_Product(pe[0], pb[1], exby1, exby0);
+ Two_Product(pb[0], pe[1], bxey1, bxey0);
+ Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]);
+
+ temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a);
+ abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ abc);
+
+ temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a);
+ bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ bcd);
+
+ temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a);
+ cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ cde);
+
+ temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a);
+ dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ dea);
+
+ temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a);
+ eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ eab);
+
+ temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a);
+ abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ abd);
+
+ temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a);
+ bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ bce);
+
+ temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a);
+ cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ cda);
+
+ temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a);
+ deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ deb);
+
+ temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a);
+ eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ eac);
+
+ temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, bcde);
+ xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x);
+ ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y);
+ zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet);
+
+ temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, cdea);
+ xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x);
+ ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y);
+ zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet);
+
+ temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, deab);
+ xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x);
+ ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y);
+ zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet);
+
+ temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, eabc);
+ xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x);
+ ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y);
+ zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet);
+
+ temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, abcd);
+ xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x);
+ ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y);
+ zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
+ cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet);
+ deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter);
+
+ return deter[deterlen - 1];
+}
+
+static REAL insphereadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd, const REAL *pe,
+ REAL permanent)
+{
+ INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez;
+ REAL det, errbound;
+
+ INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1;
+ INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1;
+ INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1;
+ REAL aexbey0, bexaey0, bexcey0, cexbey0;
+ REAL cexdey0, dexcey0, dexaey0, aexdey0;
+ REAL aexcey0, cexaey0, bexdey0, dexbey0;
+ REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
+ INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3;
+ REAL abeps, bceps, cdeps, daeps, aceps, bdeps;
+ REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48];
+ int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len;
+ REAL xdet[96], ydet[96], zdet[96], xydet[192];
+ int xlen, ylen, zlen, xylen;
+ REAL adet[288], bdet[288], cdet[288], ddet[288];
+ int alen, blen, clen, dlen;
+ REAL abdet[576], cddet[576];
+ int ablen, cdlen;
+ REAL fin1[1152];
+ int finlength;
+
+ REAL aextail, bextail, cextail, dextail;
+ REAL aeytail, beytail, ceytail, deytail;
+ REAL aeztail, beztail, ceztail, deztail;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ aex = (REAL) (pa[0] - pe[0]);
+ bex = (REAL) (pb[0] - pe[0]);
+ cex = (REAL) (pc[0] - pe[0]);
+ dex = (REAL) (pd[0] - pe[0]);
+ aey = (REAL) (pa[1] - pe[1]);
+ bey = (REAL) (pb[1] - pe[1]);
+ cey = (REAL) (pc[1] - pe[1]);
+ dey = (REAL) (pd[1] - pe[1]);
+ aez = (REAL) (pa[2] - pe[2]);
+ bez = (REAL) (pb[2] - pe[2]);
+ cez = (REAL) (pc[2] - pe[2]);
+ dez = (REAL) (pd[2] - pe[2]);
+
+ Two_Product(aex, bey, aexbey1, aexbey0);
+ Two_Product(bex, aey, bexaey1, bexaey0);
+ Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]);
+ ab[3] = ab3;
+
+ Two_Product(bex, cey, bexcey1, bexcey0);
+ Two_Product(cex, bey, cexbey1, cexbey0);
+ Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]);
+ bc[3] = bc3;
+
+ Two_Product(cex, dey, cexdey1, cexdey0);
+ Two_Product(dex, cey, dexcey1, dexcey0);
+ Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]);
+ cd[3] = cd3;
+
+ Two_Product(dex, aey, dexaey1, dexaey0);
+ Two_Product(aex, dey, aexdey1, aexdey0);
+ Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]);
+ da[3] = da3;
+
+ Two_Product(aex, cey, aexcey1, aexcey0);
+ Two_Product(cex, aey, cexaey1, cexaey0);
+ Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]);
+ ac[3] = ac3;
+
+ Two_Product(bex, dey, bexdey1, bexdey0);
+ Two_Product(dex, bey, dexbey1, dexbey0);
+ Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]);
+ bd[3] = bd3;
+
+ temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet);
+
+ temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet);
+
+ temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet);
+
+ temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
+ finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1);
+
+ det = estimate(finlength, fin1);
+ errbound = isperrboundB * permanent;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pe[0], aex, aextail);
+ Two_Diff_Tail(pa[1], pe[1], aey, aeytail);
+ Two_Diff_Tail(pa[2], pe[2], aez, aeztail);
+ Two_Diff_Tail(pb[0], pe[0], bex, bextail);
+ Two_Diff_Tail(pb[1], pe[1], bey, beytail);
+ Two_Diff_Tail(pb[2], pe[2], bez, beztail);
+ Two_Diff_Tail(pc[0], pe[0], cex, cextail);
+ Two_Diff_Tail(pc[1], pe[1], cey, ceytail);
+ Two_Diff_Tail(pc[2], pe[2], cez, ceztail);
+ Two_Diff_Tail(pd[0], pe[0], dex, dextail);
+ Two_Diff_Tail(pd[1], pe[1], dey, deytail);
+ Two_Diff_Tail(pd[2], pe[2], dez, deztail);
+ if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0)
+ && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0)
+ && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0)
+ && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) {
+ return det;
+ }
+
+ errbound = isperrboundC * permanent + resulterrbound * Absolute(det);
+ abeps = (aex * beytail + bey * aextail)
+ - (aey * bextail + bex * aeytail);
+ bceps = (bex * ceytail + cey * bextail)
+ - (bey * cextail + cex * beytail);
+ cdeps = (cex * deytail + dey * cextail)
+ - (cey * dextail + dex * ceytail);
+ daeps = (dex * aeytail + aey * dextail)
+ - (dey * aextail + aex * deytail);
+ aceps = (aex * ceytail + cey * aextail)
+ - (aey * cextail + cex * aeytail);
+ bdeps = (bex * deytail + dey * bextail)
+ - (bey * dextail + dex * beytail);
+ det += (((bex * bex + bey * bey + bez * bez)
+ * ((cez * daeps + dez * aceps + aez * cdeps)
+ + (ceztail * da3 + deztail * ac3 + aeztail * cd3))
+ + (dex * dex + dey * dey + dez * dez)
+ * ((aez * bceps - bez * aceps + cez * abeps)
+ + (aeztail * bc3 - beztail * ac3 + ceztail * ab3)))
+ - ((aex * aex + aey * aey + aez * aez)
+ * ((bez * cdeps - cez * bdeps + dez * bceps)
+ + (beztail * cd3 - ceztail * bd3 + deztail * bc3))
+ + (cex * cex + cey * cey + cez * cez)
+ * ((dez * abeps + aez * bdeps + bez * daeps)
+ + (deztail * ab3 + aeztail * bd3 + beztail * da3))))
+ + 2.0 * (((bex * bextail + bey * beytail + bez * beztail)
+ * (cez * da3 + dez * ac3 + aez * cd3)
+ + (dex * dextail + dey * deytail + dez * deztail)
+ * (aez * bc3 - bez * ac3 + cez * ab3))
+ - ((aex * aextail + aey * aeytail + aez * aeztail)
+ * (bez * cd3 - cez * bd3 + dez * bc3)
+ + (cex * cextail + cey * ceytail + cez * ceztail)
+ * (dez * ab3 + aez * bd3 + bez * da3)));
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ return insphereexact(pa, pb, pc, pd, pe);
+}
+
+REAL insphere(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd, const REAL *pe)
+{
+ REAL aex, bex, cex, dex;
+ REAL aey, bey, cey, dey;
+ REAL aez, bez, cez, dez;
+ REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey;
+ REAL aexcey, cexaey, bexdey, dexbey;
+ REAL alift, blift, clift, dlift;
+ REAL ab, bc, cd, da, ac, bd;
+ REAL abc, bcd, cda, dab;
+ REAL aezplus, bezplus, cezplus, dezplus;
+ REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus;
+ REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus;
+ REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus;
+ REAL det;
+ REAL permanent, errbound;
+ REAL ins;
+
+ FPU_ROUND_DOUBLE;
+
+ aex = pa[0] - pe[0];
+ bex = pb[0] - pe[0];
+ cex = pc[0] - pe[0];
+ dex = pd[0] - pe[0];
+ aey = pa[1] - pe[1];
+ bey = pb[1] - pe[1];
+ cey = pc[1] - pe[1];
+ dey = pd[1] - pe[1];
+ aez = pa[2] - pe[2];
+ bez = pb[2] - pe[2];
+ cez = pc[2] - pe[2];
+ dez = pd[2] - pe[2];
+
+ aexbey = aex * bey;
+ bexaey = bex * aey;
+ ab = aexbey - bexaey;
+ bexcey = bex * cey;
+ cexbey = cex * bey;
+ bc = bexcey - cexbey;
+ cexdey = cex * dey;
+ dexcey = dex * cey;
+ cd = cexdey - dexcey;
+ dexaey = dex * aey;
+ aexdey = aex * dey;
+ da = dexaey - aexdey;
+
+ aexcey = aex * cey;
+ cexaey = cex * aey;
+ ac = aexcey - cexaey;
+ bexdey = bex * dey;
+ dexbey = dex * bey;
+ bd = bexdey - dexbey;
+
+ abc = aez * bc - bez * ac + cez * ab;
+ bcd = bez * cd - cez * bd + dez * bc;
+ cda = cez * da + dez * ac + aez * cd;
+ dab = dez * ab + aez * bd + bez * da;
+
+ alift = aex * aex + aey * aey + aez * aez;
+ blift = bex * bex + bey * bey + bez * bez;
+ clift = cex * cex + cey * cey + cez * cez;
+ dlift = dex * dex + dey * dey + dez * dez;
+
+ det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd);
+
+ aezplus = Absolute(aez);
+ bezplus = Absolute(bez);
+ cezplus = Absolute(cez);
+ dezplus = Absolute(dez);
+ aexbeyplus = Absolute(aexbey);
+ bexaeyplus = Absolute(bexaey);
+ bexceyplus = Absolute(bexcey);
+ cexbeyplus = Absolute(cexbey);
+ cexdeyplus = Absolute(cexdey);
+ dexceyplus = Absolute(dexcey);
+ dexaeyplus = Absolute(dexaey);
+ aexdeyplus = Absolute(aexdey);
+ aexceyplus = Absolute(aexcey);
+ cexaeyplus = Absolute(cexaey);
+ bexdeyplus = Absolute(bexdey);
+ dexbeyplus = Absolute(dexbey);
+ permanent = ((cexdeyplus + dexceyplus) * bezplus
+ + (dexbeyplus + bexdeyplus) * cezplus
+ + (bexceyplus + cexbeyplus) * dezplus)
+ * alift
+ + ((dexaeyplus + aexdeyplus) * cezplus
+ + (aexceyplus + cexaeyplus) * dezplus
+ + (cexdeyplus + dexceyplus) * aezplus)
+ * blift
+ + ((aexbeyplus + bexaeyplus) * dezplus
+ + (bexdeyplus + dexbeyplus) * aezplus
+ + (dexaeyplus + aexdeyplus) * bezplus)
+ * clift
+ + ((bexceyplus + cexbeyplus) * aezplus
+ + (cexaeyplus + aexceyplus) * bezplus
+ + (aexbeyplus + bexaeyplus) * cezplus)
+ * dlift;
+ errbound = isperrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ ins = insphereadapt(pa, pb, pc, pd, pe, permanent);
+ FPU_RESTORE;
+ return ins;
+}
diff --git a/graphics/asymptote/predicates.h b/graphics/asymptote/predicates.h
new file mode 100644
index 0000000000..9843c548ff
--- /dev/null
+++ b/graphics/asymptote/predicates.h
@@ -0,0 +1,22 @@
+#ifndef PREDICATES_H
+#define PREDICATES_H
+
+double orient2d(const double* pa, const double* pb, const double* pc);
+double orient2d(double ax, double ay, double bx, double by, double cx,
+ double cy);
+double orient2dadapt(const double *pa, const double *pb, const double *pc,
+ double detsum);
+double orient3d(const double *pa, const double *pb, const double *pc,
+ const double *pd);
+double incircle(const double *pa, const double *pb, const double *pc,
+ const double *pd);
+double incircle(double ax, double ay, double bx, double by, double cx,
+ double cy, double dx, double dy);
+double insphere(const double *pa, const double *pb, const double *pc,
+ const double *pd, const double *pe);
+
+extern const double resulterrbound,ccwerrboundA,ccwerrboundB,ccwerrboundC,
+ o3derrboundA,o3derrboundB,o3derrboundC,iccerrboundA,iccerrboundB,
+ iccerrboundC,isperrboundA,isperrboundB,isperrboundC;
+
+#endif
diff --git a/graphics/asymptote/primitives.h b/graphics/asymptote/primitives.h
new file mode 100644
index 0000000000..cbf37601c7
--- /dev/null
+++ b/graphics/asymptote/primitives.h
@@ -0,0 +1,41 @@
+/*****
+ * primitives.h
+ * Andy Hammerlindl 2007/04/27
+ *
+ * A list of the primative types in Asymptote, defined using the
+ * PRIMITIVE(name,Name,asyName) macro. This macro should be defined in by the
+ * code including this file for the context at hand.
+ *
+ * name - the name of the type in C++ code ex: boolean
+ * Name - the same name capitalized ex: Boolean
+ * asyName - the name in Asymptote code ex: bool
+ *
+ *****/
+
+// No ifndef because this file may be included multiple times in different
+// contexts.
+
+PRIMITIVE(void,Void,void)
+PRIMITIVE(inferred,Inferred,var)
+/* null is not a primitive type. */
+#ifdef PRIMERROR
+PRIMITIVE(error,Error,<error>)
+#endif
+
+PRIMITIVE(boolean,Boolean,bool)
+PRIMITIVE(Int,Int,int)
+PRIMITIVE(real,Real,real)
+PRIMITIVE(string,String,string)
+PRIMITIVE(pair,Pair,pair)
+PRIMITIVE(triple,Triple,triple)
+PRIMITIVE(transform,Transform,transform)
+PRIMITIVE(guide,Guide,guide)
+PRIMITIVE(path,Path,path)
+PRIMITIVE(path3,Path3,path3)
+PRIMITIVE(cycleToken,CycleToken,cycleToken)
+PRIMITIVE(tensionSpecifier,TensionSpecifier,tensionSpecifier)
+PRIMITIVE(curlSpecifier,CurlSpecifier,curlSpecifier)
+PRIMITIVE(pen,Pen,pen)
+PRIMITIVE(picture,Picture,frame)
+PRIMITIVE(file,File,file)
+PRIMITIVE(code,Code,code)
diff --git a/graphics/asymptote/process.cc b/graphics/asymptote/process.cc
new file mode 100644
index 0000000000..20557858c5
--- /dev/null
+++ b/graphics/asymptote/process.cc
@@ -0,0 +1,1008 @@
+/*****
+ * process.cc
+ * Andy Hammerlindl 2006/08/19
+ *
+ * Handles processing blocks of code (including files, strings, and the
+ * interactive prompt, for listing and parse-only modes as well as actually
+ * running it.
+ *****/
+
+#include "types.h"
+#include "errormsg.h"
+#include "genv.h"
+#include "stm.h"
+#include "settings.h"
+#include "vm.h"
+#include "program.h"
+#include "interact.h"
+#include "envcompleter.h"
+#include "parser.h"
+#include "fileio.h"
+
+#include "stack.h"
+#include "runtime.h"
+#include "texfile.h"
+
+#include "process.h"
+
+namespace camp {
+pen& defaultpen() {
+ return processData().defaultpen;
+}
+}
+
+unsigned int count=0;
+
+namespace run {
+void cleanup();
+void exitFunction(vm::stack *Stack);
+void updateFunction(vm::stack *Stack);
+void purge(Int divisor=0);
+}
+
+namespace vm {
+bool indebugger;
+}
+
+using namespace settings;
+
+using absyntax::file;
+using trans::genv;
+using trans::coenv;
+using trans::env;
+using trans::coder;
+using types::record;
+
+using interact::interactive;
+using interact::uptodate;
+
+using absyntax::runnable;
+using absyntax::block;
+
+mem::stack<processDataStruct *> processDataStack;
+
+// Exception-safe way to push and pop the process data.
+class withProcessData {
+ // Do not let this object be dynamically allocated.
+ void *operator new(size_t);
+
+ processDataStruct *pd_ptr;
+public:
+
+ withProcessData(processDataStruct *pd_ptr) : pd_ptr(pd_ptr)
+ {
+ processDataStack.push(pd_ptr);
+ }
+
+ ~withProcessData()
+ {
+ assert(processDataStack.top() == pd_ptr);
+ processDataStack.pop();
+ }
+};
+
+processDataStruct &processData() {
+ assert(!processDataStack.empty());
+ return *processDataStack.top();
+}
+
+// A process environment. Basically this just serves as short-hand to start a
+// new global environment (genv) and new process data at the same time. When
+// it goes out of scope, the process data is popped off the stack. This also
+// ensures that the data is popped even if an exception is thrown.
+class penv {
+ genv *_ge;
+ processDataStruct _pd;
+
+ // Do not let this object be dynamically allocated.
+ void *operator new(size_t);
+
+public:
+ penv() : _ge(0), _pd() {
+ // Push the processData first, as it needs to be on the stack before genv
+ // is initialized.
+ processDataStack.push(&_pd);
+ _ge = new genv;
+ }
+
+ virtual ~penv() {
+ processDataStack.pop();
+ delete _ge;
+ }
+
+ genv &ge() { return *_ge; }
+
+ processDataStruct *pd() { return &_pd; }
+};
+
+
+void init(bool resetpath=true)
+{
+ vm::indebugger=false;
+ uptodate=false;
+ if(resetpath)
+ setPath(""); /* On second and subsequent calls, sets the path
+ to what it was when the program started. */
+}
+
+// This helper class does nothing but call the interactiveTrans method of the
+// base object in place of trans, so that the runnable can exhibit special
+// behaviour when run at the interactive prompt.
+class interactiveRunnable : public runnable {
+ runnable *base;
+
+public:
+ interactiveRunnable(runnable *base)
+ : runnable(base->getPos()), base(base) {}
+
+ void prettyprint(ostream &out, Int indent) {
+ absyntax::prettyname(out, "interactiveRunnable", indent);
+ base->prettyprint(out, indent+1);
+ }
+
+ void trans(coenv &e) {
+ base->interactiveTrans(e);
+ }
+
+ void transAsField(coenv &e, types::record *r) {
+ // There is no interactiveTransAsField, as fields aren't declared at the top
+ // level of the interactive prompt.
+ base->transAsField(e, r);
+ }
+};
+
+enum transMode {
+ TRANS_INTERACTIVE,
+ TRANS_NORMAL
+};
+
+
+// How to run a runnable in runnable-at-a-time mode.
+bool runRunnable(runnable *r, coenv &e, istack &s, transMode tm=TRANS_NORMAL) {
+ e.e.beginScope();
+
+ lambda *codelet= tm==TRANS_INTERACTIVE ?
+ interactiveRunnable(r).transAsCodelet(e) :
+ r->transAsCodelet(e);
+ em.sync();
+ if(!em.errors()) {
+ if(getSetting<bool>("translate")) print(cout,codelet->code);
+ s.run(codelet);
+
+ // Commits the changes made to the environment.
+ e.e.collapseScope();
+ } else {
+ e.e.endScope(); // Remove any changes to the environment.
+
+ // Should an interactive error hurt the status?
+ em.statusError();
+
+ return false;
+ }
+ return true;
+}
+
+void runAutoplain(coenv &e, istack &s) {
+ absyntax::runnable *r=absyntax::autoplainRunnable();
+ runRunnable(r,e,s);
+}
+
+// Abstract base class for the core object being run in line-at-a-time mode, it
+// may be a block of code, file, or interactive prompt.
+struct icore {
+ virtual ~icore() {}
+
+ virtual void doParse() = 0;
+ virtual void doList() = 0;
+
+public:
+
+ // preRun and postRun are the optional activities that take place before and
+ // after running the code specified. They can be overridden by a derived
+ // class that wishes different behaviour.
+ virtual void preRun(coenv &e, istack &s) {
+ if(getSetting<bool>("autoplain"))
+ runAutoplain(e,s);
+ }
+
+ virtual void run(coenv &e, istack &s, transMode tm=TRANS_NORMAL) = 0;
+
+ virtual void postRun(coenv &, istack &s) {
+ run::exitFunction(&s);
+ }
+
+ virtual void doRun(bool purge=false, transMode tm=TRANS_NORMAL) {
+ em.sync();
+ if(em.errors())
+ return;
+
+ try {
+ if(purge) run::purge();
+
+ penv pe;
+ env base_env(pe.ge());
+ coder base_coder(nullPos, "icore::doRun");
+ coenv e(base_coder,base_env);
+
+ vm::interactiveStack s;
+ s.setInitMap(pe.ge().getInitMap());
+ s.setEnvironment(&e);
+
+ preRun(e,s);
+
+ if(purge) run::purge();
+
+ // Now that everything is set up, run the core.
+ run(e,s,tm);
+
+ postRun(e,s);
+
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ } catch(quit) {
+ // Exception to quit running the current code. Nothing more to do.
+ } catch(handled_error) {
+ em.statusError();
+ }
+
+ run::cleanup();
+
+ em.clear();
+ }
+
+ virtual void process(bool purge=false) {
+ if (!interactive && getSetting<bool>("parseonly"))
+ doParse();
+ else if (getSetting<bool>("listvariables"))
+ doList();
+ else
+ doRun(purge);
+ }
+};
+
+// Abstract base class for one-time processing of an abstract syntax tree.
+class itree : public icore {
+ string name;
+
+ block *cachedTree;
+public:
+ itree(string name="<unnamed>")
+ : name(name), cachedTree(0) {}
+
+ // Build the tree, possibly throwing a handled_error if it cannot be built.
+ virtual block *buildTree() = 0;
+
+ virtual block *getTree() {
+ if (cachedTree==0) {
+ try {
+ cachedTree=buildTree();
+ } catch(handled_error) {
+ em.statusError();
+ return 0;
+ }
+ }
+ return cachedTree;
+ }
+
+ virtual string getName() {
+ return name;
+ }
+
+ void doParse() {
+ block *tree=getTree();
+ em.sync();
+ if(tree && !em.errors())
+ tree->prettyprint(cout, 0);
+ }
+
+ void doList() {
+ block *tree=getTree();
+ if (tree) {
+ penv pe;
+ record *r=tree->transAsFile(pe.ge(), symbol::trans(getName()));
+ r->e.list(r);
+ }
+ }
+
+ void run(coenv &e, istack &s, transMode tm=TRANS_NORMAL) {
+ block *tree=getTree();
+ if (tree) {
+ for(mem::list<runnable *>::iterator r=tree->stms.begin();
+ r != tree->stms.end(); ++r) {
+ processData().fileName=(*r)->getPos().filename();
+ if(!em.errors() || getSetting<bool>("debug"))
+ runRunnable(*r,e,s,tm);
+ }
+ }
+ }
+
+ void doExec(transMode tm=TRANS_NORMAL) {
+ // Don't prepare an environment to run the code if there isn't any code.
+ if (getTree())
+ icore::doRun(false,tm);
+ }
+};
+
+class icode : public itree {
+ block *tree;
+
+public:
+ icode(block *tree, string name="<unnamed>")
+ : itree(name), tree(tree) {}
+
+ block *buildTree() {
+ return tree;
+ }
+};
+
+class istring : public itree {
+ string str;
+
+public:
+ istring(const string& str, string name="<eval>")
+ : itree(name), str(str) {}
+
+ block *buildTree() {
+ return parser::parseString(str, getName());
+ }
+};
+
+void printGreeting(bool interactive) {
+ if(!getSetting<bool>("quiet")) {
+ cout << "Welcome to " << PROGRAM << " version " << REVISION;
+ if(interactive)
+ cout << " (to view the manual, type help)";
+ cout << endl;
+ }
+}
+
+class ifile : public itree {
+ string filename;
+ string outname;
+ string outname_save;
+
+public:
+ ifile(const string& filename)
+ : itree(filename),
+ filename(filename),
+ outname(stripDir(stripExt(string(filename == "-" ? settings::outname() : filename), suffix))) {}
+
+ block *buildTree() {
+ return !filename.empty() ? parser::parseFile(filename,"Loading") : 0;
+ }
+
+ void preRun(coenv& e, istack& s) {
+ outname_save=getSetting<string>("outname");
+ if(stripDir(outname_save).empty())
+ Setting("outname")=outname_save+outname;
+
+ itree::preRun(e, s);
+ }
+
+ void postRun(coenv &e, istack& s) {
+ itree::postRun(e, s);
+
+ Setting("outname")=outname_save;
+ }
+
+ void process(bool purge=false) {
+ if(verbose > 1) printGreeting(false);
+ try {
+ init();
+ } catch(handled_error) {
+ }
+
+ if (verbose >= 1)
+ cout << "Processing " << outname << endl;
+
+ try {
+ icore::process(purge);
+ }
+ catch(handled_error) {
+ em.statusError();
+ }
+ }
+};
+
+// Add a semi-colon terminator, if one is not there.
+string terminateLine(const string line) {
+ return (!line.empty() && *(line.rbegin())!=';') ? (line+";") : line;
+}
+
+// cleanLine changes a C++ style comment (//) into a C-style comment (/* */) so
+// that comments don't absorb subsequent lines of code when multiline input is
+// collapsed to a single line in the history.
+//
+// ex. if (x==1) // test x
+// x=2;
+// becomes
+// if (x==1) /* test x */ x=2 (all on one line)
+//
+// cleanLine is a mess because we have to check that the // is not in a string
+// or c-style comment, which entails re-inventing much of the lexer. The
+// routine handles most cases, but multiline strings lose their newlines when
+// recorded in the history.
+typedef string::size_type size_type;
+const size_type npos=string::npos;
+
+inline size_type min(size_type a, size_type b) {
+ return a < b ? a : b;
+}
+
+// If start is an offset somewhere within a string, this returns the first
+// offset outside of the string. sym is the character used to start the string,
+// ' or ".
+size_type endOfString(const char sym, const string line, size_type start) {
+ size_type endString=line.find(sym, start);
+ if (endString == npos)
+ return npos;
+
+ size_type escapeInString=min(line.find(string("\\")+sym, start),
+ line.find("\\\\", start));
+ if (endString < escapeInString)
+ return endString+1;
+ else
+ return endOfString(sym, line, escapeInString+2);
+}
+
+// If start is an offset somewhere within a C-style comment, this returns the
+// first offset outside of the comment.
+size_type endOfComment(const string line, size_type start) {
+ size_type endComment=line.find("*/", start);
+ if (endComment == npos)
+ return npos;
+ else
+ return endComment+2;
+}
+
+// Find the start of a string literal in the line.
+size_type stringPos(const string line, size_type start) {
+ if (start == npos)
+ return npos;
+
+ size_type pos=line.find_first_of("\'\"", start);
+ if (pos == npos)
+ return npos;
+
+ // Skip over comments /* */ and ignore anything after //
+ size_type startComment=line.find("/*", start);
+ size_type startLineComment=line.find("//", start);
+
+ if (min(startComment,startLineComment) < pos)
+ return stringPos(line,
+ startComment < startLineComment ?
+ endOfComment(line, startComment+2) :
+ npos);
+ else
+ // Nothing to skip over - the symbol actually starts a string.
+ return pos;
+}
+
+// A multiline string should retain its newlines when collapsed to a single
+// line. This converts
+// 'hello
+// there'
+// to
+// 'hello\nthere'
+// and
+// "hello
+// there"
+// to
+// "hello" '\n' "there"
+// If the line doesn't end mid-string, this adds a space to the end to preserve
+// whitespace, since it is the last function to touch the line.
+string endString(const string line, size_type start) {
+ assert(start!=npos);
+
+ size_type pos=stringPos(line, start);
+
+ if (pos==npos)
+ // String ends in normal code.
+ return line+" ";
+ else {
+ char sym=line[pos];
+ size_type eos=endOfString(sym, line, pos+1);
+ if (eos==npos) {
+ // Line ends while in a string, attach a newline symbol.
+ switch (line[pos]) {
+ case '\'':
+ return line+"\\n";
+ case '\"':
+ return line+"\" \'\\n\' \"";
+ default:
+ assert(False);
+ return line;
+ }
+ }
+ else {
+ return endString(line, eos+1);
+ }
+ }
+}
+
+// Find the first // that isn't in a C-style comment or a string.
+size_type slashPos(const string line, size_type start) {
+ if (start == npos)
+ return npos;
+
+ size_type pos=line.find("//", start);
+ if (pos == npos)
+ return npos;
+
+ // Skip over comments /* */ and strings both " " and ' '
+ size_type startComment=line.find("/*", start);
+ size_type startString=line.find_first_of("\'\"", start);
+
+ if (min(startComment,startString) < pos)
+ return slashPos(line,
+ startComment < startString ?
+ endOfComment(line, startComment+2) :
+ endOfString(line[startString], line, startString+1));
+ else
+ // Nothing to skip over - the // actually starts a comment.
+ return pos;
+}
+
+string endCommentOrString(const string line) {
+ size_type pos=slashPos(line, 0);
+ if (pos == npos)
+ return endString(line, 0);
+ else {
+ string sub=line;
+
+ // Replace the first // by /*
+ sub[pos+1]='*';
+
+ // Replace any */ in the comment by *!
+ while ((pos = line.find("*/", pos+2)) != npos)
+ sub[pos+1]='!';
+
+ // Tack on a */ at the end.
+ sub.append(" */ ");
+ return sub;
+ }
+}
+
+bool isSlashed(const string line) {
+ // NOTE: This doesn't fully handle escaped slashed in a string literal.
+ unsigned n=line.size();
+ return n > 0 ? line[line.size()-1] == '\\' : false;
+}
+string deslash(const string line) {
+ return isSlashed(line) ? line.substr(0,line.size()-1) : line;
+}
+
+// This transforms a line in to the history, so that when more code is added
+// after it, the code behaves the same as if there was a newline between the
+// two lines. This involves changing // style comments to /* */ style comments,
+// and adding explicit newlines to multiline strings.
+string cleanLine(const string line) {
+ // First remove a trailing slash, if there is one.
+ return endCommentOrString(deslash(line));
+}
+
+class iprompt : public icore {
+ // Flag that is set to false to signal the prompt to exit.
+ bool running;
+
+ // Flag that is set to restart the main loop once it has exited.
+ bool restart;
+
+ // Code ran at start-up.
+ string startline;
+
+ void postRun(coenv &, istack &) {
+ }
+
+ // Commands are chopped into the starting word and the rest of the line.
+ struct commandLine {
+ string line;
+ string word;
+ string rest;
+
+ commandLine(string line) : line(line) {
+ string::iterator c=line.begin();
+
+ // Skip leading whitespace
+ while (c != line.end() && isspace(*c))
+ ++c;
+
+ // Only handle identifiers starting with a letter.
+ if (c != line.end() && isalpha(*c)) {
+ // Store the command name.
+ while (c != line.end() && (isalnum(*c) || *c=='_')) {
+ word.push_back(*c);
+ ++c;
+ }
+ }
+
+ // Copy the rest to rest.
+ while (c != line.end()) {
+ rest.push_back(*c);
+ ++c;
+ }
+
+#if 0
+ cerr << "line: " << line << endl;
+ cerr << "word: " << word << endl;
+ cerr << "rest: " << rest << endl;
+ cerr << "simple: " << simple() << endl;
+#endif
+ }
+
+ // Simple commands have at most spaces or semicolons after the command word.
+ bool simple() {
+ for (string::iterator c=rest.begin(); c != rest.end(); ++c)
+ if (!isspace(*c) && *c != ';')
+ return false;
+ return true;
+ }
+ };
+
+
+ // The interactive prompt has special functions that cannot be implemented as
+ // normal functions. These special funtions take a commandLine as an argument
+ // and return true if they can handle the command. If false is returned, the
+ // line is treated as a normal line of code.
+ // commands is a map of command names to methods which implement the commands.
+ typedef bool (iprompt::*command)(coenv &, istack &, commandLine);
+ typedef mem::map<CONST string, command> commandMap;
+ commandMap commands;
+
+ bool exit(coenv &, istack &, commandLine cl) {
+ if (cl.simple()) {
+ // Don't store exit commands in the history file.
+ interact::deleteLastLine();
+ running=false;
+ return true;
+ }
+ else return false;
+ }
+
+ bool q(coenv &e, istack &s, commandLine cl) {
+ if(e.e.ve.getType(symbol::trans("q"))) return false;
+ return exit(e,s,cl);
+ }
+
+ bool reset(coenv &, istack &, commandLine cl) {
+ if (cl.simple()) {
+ running=false;
+ restart=true;
+ startline="";
+ run::purge();
+ return true;
+ }
+ else return false;
+ }
+
+ bool help(coenv &, istack &, commandLine cl) {
+ if (cl.simple()) {
+ popupHelp();
+ return true;
+ }
+ else return false;
+ }
+
+ bool erase(coenv &e, istack &s, commandLine cl) {
+ if (cl.simple()) {
+ runLine(e,s,"erase();");
+ return true;
+ }
+ else return false;
+ }
+
+ bool input(coenv &, istack &, commandLine cl) {
+ running=false;
+ restart=true;
+ startline="include "+cl.rest;
+ return true;
+ }
+
+ void initCommands() {
+#define ADDCOMMAND(name, func) \
+ commands[#name]=&iprompt::func
+
+ // keywords.pl looks for ADDCOMMAND to identify special commands in the
+ // auto-completion.
+ ADDCOMMAND(quit,exit);
+ ADDCOMMAND(q,q);
+ ADDCOMMAND(exit,exit);
+ ADDCOMMAND(reset,reset);
+ ADDCOMMAND(erase,erase);
+ ADDCOMMAND(help,help);
+ ADDCOMMAND(input,input);
+
+#undef ADDCOMMAND
+ }
+
+ bool handleCommand(coenv &e, istack &s, string line) {
+ commandLine cl(line);
+ if (cl.word != "") {
+ commandMap::iterator p=commands.find(cl.word);
+ if (p != commands.end()) {
+ // Execute the command.
+ command &com=p->second;
+ return (this->*com)(e,s,cl);
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+
+ void addToHistory(string line) {
+ interact::addToHistory(line);
+ }
+
+ void addToLastLine(string line) {
+ // Here we clean a line at the last possible point, when we know that more
+ // code is going to be appended to it.
+ string last=interact::getLastHistoryLine();
+ interact::setLastHistoryLine(cleanLine(last)+line);
+ }
+
+ void terminateLastHistoryLine() {
+ string last=interact::getLastHistoryLine();
+ interact::setLastHistoryLine(terminateLine(last));
+ }
+
+ // Get input from the interactive prompt. Such input may be over several
+ // user-typed lines if he/she ends a line a with backslash to continue input
+ // on the next line. If continuation is true, the input started on a previous
+ // line and is being continued (either because of a backslash or the parser
+ // detecting it in multiline mode).
+ string getline(bool continuation) {
+ string prompt;
+ if(!getSetting<bool>("xasy"))
+ prompt=getSetting<string>(continuation ? "prompt2" : "prompt");
+ string line=interact::simpleline(prompt);
+
+ if (continuation)
+ addToLastLine(line);
+ else
+ addToHistory(line);
+
+ // If the line ends in a slash, get more input.
+ return isSlashed(line) ? line+"\n"+getline(true) :
+ line;
+ }
+
+ // Continue taking input for a line until it properly parses, or a syntax
+ // error occurs. Returns the parsed code on success, and throws a
+ // handled_error exception on failure.
+ block *parseExtendableLine(string line) {
+ block *code=parser::parseString(line, "-", true);
+ if (code) {
+ return code;
+ } else {
+ string nextline=getline(true);
+ return parseExtendableLine(line+"\n"+nextline);
+ }
+ }
+
+ // Continue taking input until a termination command is received from xasy.
+ block *parseXasyLine(string line) {
+
+#ifdef __MSDOS__
+ const string EOT="\x04\r\n";
+#else
+ const string EOT="\x04\n";
+#endif
+ string s;
+ while((s=getline(true)) != EOT)
+ line += s;
+ return parser::parseString(line, "-", true);
+ }
+
+ void runLine(coenv &e, istack &s, string line) {
+ try {
+ if(getSetting<bool>("multiline")) {
+ block *code=parseExtendableLine(line);
+
+ icode i(code);
+ i.run(e,s,TRANS_INTERACTIVE);
+ } else if(getSetting<bool>("xasy")) {
+ block *code=parseXasyLine(line);
+
+ icode i(code);
+ i.run(e,s,TRANS_INTERACTIVE);
+ } else {
+ // Add a semi-colon to the end of the line if one is not there. Do this
+ // to the history as well, so the transcript can be run as regular asy
+ // code. This also makes the history work correctly if the multiline
+ // setting is changed within an interactive session.
+ // It is added to the history at the last possible moment to avoid
+ // tampering with other features, such as using a slash to extend a
+ // line.
+ terminateLastHistoryLine();
+ istring i(terminateLine(line), "-");
+ i.run(e,s,TRANS_INTERACTIVE);
+ }
+
+ run::updateFunction(&s);
+ uptodate=false;
+
+ } catch(handled_error) {
+ vm::indebugger=false;
+ } catch(interrupted&) {
+ // Turn off the interrupted flag.
+ em.Interrupt(false);
+ uptodate=true;
+ cout << endl;
+ } catch(quit&) {
+ }
+
+ // Ignore errors from this line when trying to run subsequent lines.
+ em.clear();
+ }
+
+ void runStartCode(coenv &e, istack &s) {
+ if (!startline.empty())
+ runLine(e, s, startline);
+ }
+
+public:
+ iprompt() : running(false), restart(false), startline("") {
+ initCommands();
+ }
+
+ void doParse() {}
+
+ void doList() {}
+
+ void run(coenv &e, istack &s, transMode=TRANS_NORMAL) {
+ running=true;
+ interact::setCompleter(new trans::envCompleter(e.e));
+
+ runStartCode(e, s);
+
+ while (running) {
+ // Read a line from the prompt.
+ string line=getline(false);
+ // Check if it is a special command.
+ if (handleCommand(e,s,line))
+ continue;
+ else
+ runLine(e, s, line);
+ }
+ }
+
+ void process(bool purge=false) {
+ printGreeting(true);
+ interact::init_interactive();
+ try {
+ setPath("",true);
+ } catch(handled_error) {
+ }
+
+ do {
+ try {
+ init(false);
+ restart=false;
+ icore::process();
+ } catch(interrupted&) {
+ em.Interrupt(false);
+ restart=true;
+ } catch(eof&) {
+ restart=false;
+ }
+ } while(restart);
+
+ interact::cleanup_interactive();
+ }
+};
+
+void processCode(absyntax::block *code) {
+ icode(code).process();
+}
+void processFile(const string& filename, bool purge) {
+ ifile(filename).process(purge);
+}
+void processPrompt() {
+ iprompt().process();
+}
+
+void runCode(absyntax::block *code) {
+ icode(code).doExec();
+}
+void runString(const string& s, bool interactiveWrite) {
+ istring(s).doExec(interactiveWrite ? TRANS_INTERACTIVE : TRANS_NORMAL);
+}
+void runFile(const string& filename) {
+ ifile(filename).doExec();
+}
+void runPrompt() {
+ iprompt().doRun();
+}
+
+void runCodeEmbedded(absyntax::block *code, trans::coenv &e, istack &s) {
+ icode(code).run(e,s);
+}
+void runStringEmbedded(const string& str, trans::coenv &e, istack &s) {
+ istring(str).run(e,s);
+}
+void runPromptEmbedded(trans::coenv &e, istack &s) {
+ iprompt().run(e,s);
+}
+
+void doUnrestrictedList() {
+ penv pe;
+ env base_env(pe.ge());
+ coder base_coder(nullPos, "doUnrestictedList");
+ coenv e(base_coder,base_env);
+
+ if (getSetting<bool>("autoplain"))
+ absyntax::autoplainRunnable()->trans(e);
+
+ e.e.list(0);
+}
+
+// Environment class used by external programs linking to the shared library.
+class fullenv : public gc {
+ penv pe;
+ env base_env;
+ coder base_coder;
+ coenv e;
+
+ vm::interactiveStack s;
+
+public:
+ fullenv() :
+ pe(), base_env(pe.ge()), base_coder(nullPos, "fullenv"),
+ e(base_coder, base_env), s()
+ {
+ s.setInitMap(pe.ge().getInitMap());
+ s.setEnvironment(&e);
+
+ // TODO: Add way to not run autoplain.
+ runAutoplain(e, s);
+ }
+
+ coenv &getCoenv()
+ {
+ return e;
+ }
+
+ void runRunnable(runnable *r)
+ {
+ assert(!em.errors()); // TODO: Decide how to handle prior errors.
+
+ try {
+ { withProcessData token(pe.pd());
+ ::runRunnable(r, e, s, TRANS_INTERACTIVE);
+ }
+ } catch(std::bad_alloc&) {
+ // TODO: give calling application useful message.
+ cerr << "out of memory" << endl;
+ } catch (quit) {
+ // I'm not sure whether this counts as successfully running the code or
+ // not.
+ cerr << "quit exception" << endl;
+ } catch (handled_error) {
+ // Normally, this is the result of an error that changes the return code
+ // of the free-standing asymptote program.
+ // An error should probably be reported to the application calling the
+ // asymptote library.
+ cerr << "handled error" << endl;
+ }
+
+ em.clear();
+ }
+};
+
+fullenv &getFullEnv()
+{
+ static fullenv fe;
+ return fe;
+}
+
+coenv &coenvInOngoingProcess()
+{
+ return getFullEnv().getCoenv();
+}
+
+void runInOngoingProcess(runnable *r)
+{
+ getFullEnv().runRunnable(r);
+}
diff --git a/graphics/asymptote/process.h b/graphics/asymptote/process.h
new file mode 100644
index 0000000000..1a5189cdb5
--- /dev/null
+++ b/graphics/asymptote/process.h
@@ -0,0 +1,130 @@
+/*****
+ * process.h
+ * Andy Hammerlindl 2006/08/19
+ *
+ * Handles processing blocks of code (including files, strings, and the
+ * interactive prompt, for listing and parse-only modes as well as actually
+ * running it.
+ *****/
+
+#ifndef PROCESS_H
+#define PROCESS_H
+
+
+#include "common.h"
+#include "stm.h"
+#include "stack.h"
+#include "pipestream.h"
+#include "callable.h"
+#include "pen.h"
+#include "transform.h"
+
+#ifdef HAVE_RPC_RPC_H
+#include "xstream.h"
+#endif
+
+// Process the code respecting the parseonly and listvariables flags of
+// settings.
+void processCode(absyntax::block *code);
+void processFile(const string& filename, bool purge=false);
+void processPrompt();
+
+// Run the code in its own environment.
+void runCode(absyntax::block *code);
+void runString(const string& s, bool interactiveWrite=false);
+void runFile(const string& filename);
+void runPrompt();
+
+// Run the code in a given run-time environment.
+typedef vm::interactiveStack istack;
+void runCodeEmbedded(absyntax::block *code, trans::coenv &e, istack &s);
+void runStringEmbedded(const string& str, trans::coenv &e, istack &s);
+void runPromptEmbedded(trans::coenv &e, istack &s);
+
+// Basic listing.
+void doUnrestrictedList();
+
+template<class T>
+class terminator {
+public:
+ typedef mem::vector<T *> Pointer;
+ Pointer pointer;
+
+ // Return first available index
+ size_t available() {
+ size_t index=0;
+ for(typename Pointer::iterator p=pointer.begin(); p != pointer.end(); ++p) {
+ if(*p == NULL) {return index;}
+ ++index;
+ }
+ pointer.push_back(NULL);
+ return index;
+ }
+
+ size_t add(T *p) {
+ size_t index=available();
+ pointer[index]=p;
+ return index;
+ }
+
+ void remove(size_t index) {
+ pointer[index]=NULL;
+ }
+
+ ~terminator() {
+ for(typename Pointer::iterator p=pointer.begin(); p != pointer.end(); ++p) {
+ if(*p != NULL) {
+ (*p)->~T();
+ (*p)=NULL;
+ }
+ }
+ }
+};
+
+class texstream : public iopipestream {
+public:
+ ~texstream();
+};
+
+typedef std::pair<size_t,size_t> linecolumn;
+typedef mem::map<CONST linecolumn,string> xkey_t;
+typedef mem::deque<camp::transform> xtransform_t;
+typedef mem::map<CONST string,xtransform_t> xmap_t;
+
+struct processDataStruct {
+ texstream tex; // Bi-directional pipe to latex (to find label bbox)
+ mem::list<string> TeXpipepreamble;
+ mem::list<string> TeXpreamble;
+ vm::callable *atExitFunction;
+ vm::callable *atUpdateFunction;
+ vm::callable *atBreakpointFunction;
+ camp::pen defaultpen;
+ camp::pen currentpen;
+
+ // For xasy:
+ string fileName;
+ position topPos;
+ string KEY;
+ xkey_t xkey;
+ xmap_t xmap;
+
+ terminator<std::ofstream> ofile;
+ terminator<std::fstream> ifile;
+#ifdef HAVE_RPC_RPC_H
+ terminator<xdr::ioxstream> ixfile;
+ terminator<xdr::oxstream> oxfile;
+#endif
+
+ processDataStruct() {
+ atExitFunction=NULL;
+ atUpdateFunction=NULL;
+ atBreakpointFunction=NULL;
+ defaultpen=camp::pen::initialpen();
+ currentpen=camp::pen();
+ }
+
+};
+
+processDataStruct &processData();
+
+#endif
diff --git a/graphics/asymptote/profile.py b/graphics/asymptote/profile.py
new file mode 100644
index 0000000000..f09ea6dea0
--- /dev/null
+++ b/graphics/asymptote/profile.py
@@ -0,0 +1,96 @@
+import sys
+from pprint import pprint
+
+# Unused line numbers required by kcachegrind.
+POS = '1'
+
+def nameFromNode(tree):
+ name = tree['name']
+ pos = tree['pos']
+ if pos.endswith(": "):
+ pos = pos[:-2]
+ return (name, pos)
+
+def addFuncNames(tree, s):
+ s.add(nameFromNode(tree))
+ for child in tree['children']:
+ addFuncNames(child, s)
+
+def funcNames(tree):
+ s = set()
+ addFuncNames(tree, s)
+ return s
+
+def computeTotals(tree):
+ for child in tree['children']:
+ computeTotals(child)
+ tree['instTotal'] = (tree['instructions']
+ + sum(child['instTotal'] for child in tree['children']))
+ tree['nsecsTotal'] = (tree['nsecs']
+ + sum(child['nsecsTotal'] for child in tree['children']))
+
+def printName(name, prefix=''):
+ print prefix+"fl=", name[1]
+ print prefix+"fn=", name[0]
+
+class Arc:
+ def __init__(self):
+ self.calls = 0
+ self.instTotal = 0
+ self.nsecsTotal = 0
+
+ def add(self, tree):
+ self.calls += tree['calls']
+ self.instTotal += tree['instTotal']
+ self.nsecsTotal += tree['nsecsTotal']
+
+class Func:
+ def __init__(self):
+ self.instructions = 0
+ self.nsecs = 0
+ self.arcs = {}
+
+ def addChildTime(self, tree):
+ arc = self.arcs.setdefault(nameFromNode(tree), Arc())
+ arc.add(tree)
+
+ def analyse(self, tree):
+ self.instructions += tree['instructions']
+ self.nsecs += tree['nsecs']
+ for child in tree['children']:
+ self.addChildTime(child)
+
+ def dump(self):
+ print POS, self.instructions, self.nsecs
+ for name in self.arcs:
+ printName(name, prefix='c')
+ arc = self.arcs[name]
+ print "calls="+str(arc.calls), POS
+ print POS, arc.instTotal, arc.nsecsTotal
+ print
+
+def analyse(funcs, tree):
+ funcs[nameFromNode(tree)].analyse(tree)
+ for child in tree['children']:
+ analyse(funcs, child)
+
+def dump(funcs):
+ print "events: Instructions Nanoseconds"
+ for name in funcs:
+ printName(name)
+ funcs[name].dump()
+
+rawdata = __import__("asyprof")
+profile = rawdata.profile
+
+computeTotals(profile)
+names = funcNames(profile)
+
+funcs = {}
+for name in names:
+ funcs[name] = Func()
+
+analyse(funcs, profile)
+dump(funcs)
+
+#pprint(names)
diff --git a/graphics/asymptote/profiler.h b/graphics/asymptote/profiler.h
new file mode 100644
index 0000000000..bd914d55d1
--- /dev/null
+++ b/graphics/asymptote/profiler.h
@@ -0,0 +1,434 @@
+/*****
+ * profiler.h
+ * Andy Hammerlindl 2010/07/24
+ *
+ * Profiler for the execution of the virtual machine bytecode.
+ *****/
+
+#ifndef PROFILER_H
+#define PROFILER_H
+
+#include <sys/time.h>
+
+#include <iostream>
+
+#include "inst.h"
+
+namespace vm {
+
+#ifdef DEBUG_BLTIN
+string lookupBltin(bltin b);
+#endif
+
+inline position positionFromLambda(lambda *func) {
+ if (func == 0)
+ return position();
+
+ program& code = *func->code;
+
+ // Check for empty program.
+ if (code.begin() == code.end())
+ return position();
+
+ return code.begin()->pos;
+}
+
+inline void printNameFromLambda(ostream& out, lambda *func) {
+ if (!func) {
+ out << "<top level>";
+ return;
+ }
+
+#ifdef DEBUG_FRAME
+ string name = func->name;
+#else
+ string name = "";
+#endif
+
+ // If unnamed, use the pointer address.
+ if (name.empty())
+ out << func;
+ else
+ out << name;
+
+ out << " at ";
+ positionFromLambda(func).printTerse(out);
+}
+
+inline void printNameFromBltin(ostream& out, bltin b) {
+#ifdef DEBUG_BLTIN
+ string name = lookupBltin(b);
+#else
+ string name = "";
+#endif
+
+ if (!name.empty())
+ out << name << " ";
+ out << "(builtin at " << (void *)b << ")";
+}
+
+class profiler : public gc {
+ // To do call graph analysis, each call stack that occurs in practice is
+ // represented by a node. For instance, if f and g are functions, then
+ // f -> g -> g
+ // is represented by a node and
+ // g -> f -> g
+ // is represented by a different one.
+ struct node {
+ // The top-level function of the call stack. It is either an asymptote
+ // function with a given lambda, or a builtin function, with a given
+ // bltin.
+ lambda *func;
+ bltin cfunc;
+
+ // The number of times the top-level function has been called resulting in
+ // this specific call stack.
+ int calls;
+
+ // The number of bytecode instructions executed with this exact call stack.
+ // It does not include time spent in called function.
+ int instructions;
+
+ // Number of instructions spent in this function or its children. This is
+ // computed by computeTotals.
+ int instTotal;
+
+ // The number of real-time nanoseconds spent in this node. WARNING: May
+ // be wildly inaccurate.
+ long long nsecs;
+
+ // Total including children.
+ long long nsecsTotal;
+
+ // Call stacks resulting from calls during this call stack.
+ mem::vector<node> children;
+
+ node()
+ : func(0), cfunc(0), calls(0),
+ instructions(0), instTotal(0),
+ nsecs(0), nsecsTotal(0) {}
+
+ node(lambda *func)
+ : func(func), cfunc(0), calls(0),
+ instructions(0), instTotal(0),
+ nsecs(0), nsecsTotal(0) {}
+
+ node(bltin b)
+ : func(0), cfunc(b), calls(0),
+ instructions(0), instTotal(0),
+ nsecs(0), nsecsTotal(0) {}
+
+ // Return the call stack resulting from a call to func when this call
+ // stack is current.
+ node *getChild(lambda *func) {
+ size_t n = children.size();
+ for (size_t i = 0; i < n; ++i)
+ if (children[i].func == func)
+ return &children[i];
+
+ // Not found, create a new one.
+ children.push_back(node(func));
+ return &children.back();
+ }
+ node *getChild(bltin func) {
+ size_t n = children.size();
+ for (size_t i = 0; i < n; ++i)
+ if (children[i].cfunc == func)
+ return &children[i];
+
+ // Not found, create a new one.
+ children.push_back(node(func));
+ return &children.back();
+ }
+
+ void computeTotals() {
+ instTotal = instructions;
+ nsecsTotal = nsecs;
+ size_t n = children.size();
+ for (size_t i = 0; i < n; ++i) {
+ children[i].computeTotals();
+ instTotal += children[i].instTotal;
+ nsecsTotal += children[i].nsecsTotal;
+ }
+ }
+
+
+
+ void pydump(ostream& out) {
+#ifdef DEBUG_FRAME
+ string name = func ? func->name : "<top level>";
+#else
+ string name = "";
+#endif
+
+ out << "dict(\n"
+ << " name = '" << name << " " << func << "',\n"
+ << " pos = '" << positionFromLambda(func) << "',\n"
+ << " calls = " << calls << ",\n"
+ << " instructions = " << instructions << ",\n"
+ << " nsecs = " << nsecs << ",\n"
+ << " children = [\n";
+
+ size_t n = children.size();
+ for (size_t i = 0; i < n; ++i) {
+ children[i].pydump(out);
+ out << ",\n";
+ }
+
+ out << " ])\n";
+ }
+ };
+
+ // An empty call stack.
+ node emptynode;
+
+ // All of the callstacks.
+ std::stack<node *> callstack;
+
+ node &topnode() {
+ return *callstack.top();
+ }
+
+ // Arc representing one function calling another. Used only for building
+ // the output for kcachegrind.
+ struct arc : public gc {
+ int calls;
+ int instTotal;
+ long long nsecsTotal;
+
+ arc() : calls(0), instTotal(0), nsecsTotal(0) {}
+
+ void add(node& n) {
+ calls += n.calls;
+ instTotal += n.instTotal;
+ nsecsTotal += n.nsecsTotal;
+ }
+ };
+
+ // Representing one function and its calls to other functions.
+ struct fun : public gc {
+ int instructions;
+ long long nsecs;
+ mem::map<lambda *, arc> arcs;
+ mem::map<bltin, arc> carcs;
+
+ fun() : instructions(0), nsecs(0) {}
+
+ void addChildTime(node& n) {
+ if (n.cfunc)
+ carcs[n.cfunc].add(n);
+ else
+ arcs[n.func].add(n);
+ }
+
+ void analyse(node& n) {
+ instructions += n.instructions;
+ nsecs += n.nsecs;
+ size_t numChildren = n.children.size();
+ for (size_t i = 0; i < numChildren; ++i)
+ addChildTime(n.children[i]);
+ }
+
+ void dump(ostream& out) {
+ // The unused line number needed by kcachegrind.
+ static const string POS = "1";
+
+ out << POS << " " << instructions << " " << nsecs << "\n";
+ for (mem::map<lambda *, arc>::iterator i = arcs.begin();
+ i != arcs.end();
+ ++i)
+ {
+ lambda *l = i->first;
+ arc& a = i->second;
+
+ out << "cfl=" << positionFromLambda(l) << "\n";
+
+ out << "cfn=";
+ printNameFromLambda(out, l);
+ out << "\n";
+
+ out << "calls=" << a.calls << " " << POS << "\n";
+ out << POS << " " << a.instTotal << " " << a.nsecsTotal << "\n";
+ }
+ for (mem::map<bltin, arc>::iterator i = carcs.begin();
+ i != carcs.end();
+ ++i)
+ {
+ bltin b = i->first;
+ arc& a = i->second;
+
+ out << "cfl=C++ code" << endl;
+
+ out << "cfn=";
+ printNameFromBltin(out, b);
+ out << "\n";
+
+ out << "calls=" << a.calls << " " << POS << "\n";
+ out << POS << " " << a.instTotal << " " << a.nsecsTotal << "\n";
+ }
+ }
+ };
+
+ // The data for each asymptote function.
+ mem::map<lambda *, fun> funs;
+
+ // The data for each C++ function.
+ mem::map<bltin, fun> cfuns;
+
+ void analyseNode(node& n) {
+ fun& f = n.cfunc ? cfuns[n.cfunc] :
+ funs[n.func];
+
+ f.analyse(n);
+
+ size_t numChildren = n.children.size();
+ for (size_t i = 0; i < numChildren; ++i)
+ analyseNode(n.children[i]);
+ }
+
+ // Convert data in the tree of callstack nodes into data for each function.
+ void analyseData() {
+ emptynode.computeTotals();
+ analyseNode(emptynode);
+ }
+
+
+ // Timing data.
+ struct timeval timestamp;
+
+ void startLap() {
+ gettimeofday(&timestamp, 0);
+ }
+
+ long long timeAndResetLap() {
+ struct timeval now;
+ gettimeofday(&now, 0);
+ long long nsecs = 1000000000LL * (now.tv_sec - timestamp.tv_sec) +
+ 1000LL * (now.tv_usec - timestamp.tv_usec);
+ timestamp = now;
+ return nsecs;
+ }
+
+ // Called whenever the stack is about to change, in order to record the time
+ // duration for the current node.
+ void recordTime() {
+ topnode().nsecs += timeAndResetLap();
+ }
+
+public:
+ profiler();
+
+ void beginFunction(lambda *func);
+ void endFunction(lambda *func);
+ void beginFunction(bltin func);
+ void endFunction(bltin func);
+ void recordInstruction();
+
+ // TODO: Add position, type of instruction info to profiling.
+
+ // Dump all of the data out in a format that can be read into Python.
+ void pydump(ostream &out);
+
+ // Dump all of the data in a format for kcachegrind.
+ void dump(ostream& out);
+
+};
+
+inline profiler::profiler()
+ : emptynode()
+{
+ callstack.push(&emptynode);
+ startLap();
+}
+
+inline void profiler::beginFunction(lambda *func) {
+ assert(func);
+ assert(!callstack.empty());
+
+ recordTime();
+
+ callstack.push(topnode().getChild(func));
+ ++topnode().calls;
+}
+
+inline void profiler::endFunction(lambda *func) {
+ assert(func);
+ assert(!callstack.empty());
+ assert(topnode().func == func);
+
+ recordTime();
+
+ callstack.pop();
+}
+
+inline void profiler::beginFunction(bltin cfunc) {
+ assert(cfunc);
+ assert(!callstack.empty());
+
+ recordTime();
+
+ callstack.push(topnode().getChild(cfunc));
+ ++topnode().calls;
+}
+
+inline void profiler::endFunction(bltin cfunc) {
+ assert(cfunc);
+ assert(!callstack.empty());
+ assert(topnode().cfunc == cfunc);
+
+ recordTime();
+
+ callstack.pop();
+}
+
+inline void profiler::recordInstruction() {
+ assert(!callstack.empty());
+ ++topnode().instructions;
+}
+
+inline void profiler::pydump(ostream& out) {
+ out << "profile = ";
+ emptynode.pydump(out);
+}
+
+inline void profiler::dump(ostream& out) {
+ analyseData();
+
+ out << "events: Instructions Nanoseconds\n";
+
+ for (mem::map<lambda *, fun>::iterator i = funs.begin();
+ i != funs.end();
+ ++i)
+ {
+ lambda *l = i->first;
+ fun& f = i->second;
+
+ out << "fl=" << positionFromLambda(l) << "\n";
+
+ out << "fn=";
+ printNameFromLambda(out, l);
+ out << "\n";
+
+ f.dump(out);
+ }
+ for (mem::map<bltin, fun>::iterator i = cfuns.begin();
+ i != cfuns.end();
+ ++i)
+ {
+ bltin b = i->first;
+ fun& f = i->second;
+
+ out << "fl=C++ code\n";
+
+ out << "fn=";
+ printNameFromBltin(out, b);
+ out << "\n";
+
+ f.dump(out);
+ }
+}
+
+
+} // namespace vm
+
+#endif // PROFILER_H
diff --git a/graphics/asymptote/program.cc b/graphics/asymptote/program.cc
new file mode 100644
index 0000000000..f4c83f7944
--- /dev/null
+++ b/graphics/asymptote/program.cc
@@ -0,0 +1,172 @@
+/*****
+ * program.cc
+ * Tom Prince
+ *
+ * The list of instructions used by the virtual machine.
+ *****/
+
+#include <iostream>
+#include "util.h"
+#include "callable.h"
+#include "program.h"
+
+
+namespace vm {
+
+static const char* opnames[] = {
+#define OPCODE(name, type) #name,
+#include "opcodes.h"
+#undef OPCODE
+};
+static const Int numOps = (Int)(sizeof(opnames)/sizeof(char *));
+
+static const char optypes[] = {
+#define OPCODE(name, type) type,
+#include "opcodes.h"
+#undef OPCODE
+};
+
+#ifdef DEBUG_BLTIN
+mem::map<bltin,string> bltinRegistry;
+
+void registerBltin(bltin b, string s) {
+ bltinRegistry[b] = s;
+}
+string lookupBltin(bltin b) {
+ return bltinRegistry[b];
+}
+#endif
+
+
+ostream& operator<< (ostream& out, const item& i)
+{
+ if (i.empty())
+ return out << "empty";
+
+ if (isdefault(i))
+ return out << "default";
+
+#if COMPACT
+ // TODO: Try to guess the type from the value.
+ Int n = get<Int>(i);
+ double x = get<double>(i);
+ void *p = get<void *>(i);
+
+ if (n == BoolTruthValue)
+ return out << "true";
+ if (n == BoolFalseValue)
+ return out << "false";
+
+ if (std::abs(n) < 1000000)
+ return out << n;
+
+ if (fabs(x) < 1e30 and fabs(x) > 1e-30)
+ return out << x;
+
+ return out << "<item " << p << ">";
+#else
+ // TODO: Make a data structure mapping typeids to print functions.
+ else if (i.type() == typeid(Int))
+ out << "Int, value = " << get<Int>(i);
+ else if (i.type() == typeid(double))
+ out << "real, value = " << get<double>(i);
+ else if (i.type() == typeid(string))
+ out << "string, value = " << get<string>(i);
+ else if (i.type() == typeid(callable))
+ out << *(get<callable *>(i));
+ else if (i.type() == typeid(frame)) {
+ out << "frame";
+# ifdef DEBUG_FRAME
+ {
+ frame *f = get<frame *>(i);
+ if (f)
+ out << " " << f->getName();
+ else
+ out << " <null>";
+ }
+# endif
+ }
+ else
+ out << "type " << demangle(i.type().name());
+#endif
+
+ return out;
+}
+
+void printInst(ostream& out, const program::label& code,
+ const program::label& base)
+{
+ out.width(4);
+ out << offset(base,code) << " ";
+
+ Int i = (Int)code->op;
+
+ if (i < 0 || i >= numOps) {
+ out << "<<invalid op>>" << i;
+ return;
+ }
+ out << opnames[i];
+
+ switch (optypes[i]) {
+ case 'n':
+ {
+ out << " " << get<Int>(*code);
+ break;
+ }
+
+ case 't':
+ {
+ item c = code->ref;
+ out << " " << c;
+ break;
+ }
+
+ case 'b':
+ {
+#ifdef DEBUG_BLTIN
+ string s=lookupBltin(get<bltin>(*code));
+ out << " " << (!s.empty() ? s : "<unnamed>") << " ";
+#endif
+ break;
+ }
+
+ case 'o':
+ {
+ char f = out.fill('0');
+ out << " i";
+ out.width(4);
+ out << offset(base,get<program::label>(*code));
+ out.fill(f);
+ break;
+ }
+
+ case 'l':
+ {
+#ifdef DEBUG_FRAME
+ out << " " << get<lambda*>(*code)->name << " ";
+#endif
+ break;
+ }
+
+ default: {
+ /* nothing else to do */
+ break;
+ }
+ };
+}
+
+void print(ostream& out, program *base)
+{
+ program::label code = base->begin();
+ bool active = true;
+ while (active) {
+ if (code->op == inst::ret ||
+ code->op < 0 || code->op >= numOps)
+ active = false;
+ printInst(out, code, base->begin());
+ out << '\n';
+ ++code;
+ }
+}
+
+} // namespace vm
diff --git a/graphics/asymptote/program.h b/graphics/asymptote/program.h
new file mode 100644
index 0000000000..7d0192b389
--- /dev/null
+++ b/graphics/asymptote/program.h
@@ -0,0 +1,101 @@
+/*****
+ * program.h
+ * Tom Prince
+ *
+ * The list of instructions used by the virtual machine.
+ *****/
+
+#ifndef PROGRAM_H
+#define PROGRAM_H
+
+#include <cstddef> // for ptrdiff_t
+
+#include "common.h"
+#include "inst.h"
+
+using std::ptrdiff_t;
+
+namespace vm {
+struct inst;
+
+class program : public gc {
+public:
+ class label;
+ program();
+ void encode(inst i);
+ label begin();
+ label end();
+ inst &back();
+ void pop_back();
+private:
+ friend class label;
+ typedef mem::vector<inst> code_t;
+ code_t code;
+ inst& operator[](size_t);
+};
+
+class program::label
+{
+public: // interface
+ label() : where(0), code() {}
+public: //interface
+ label& operator++();
+ label& operator--();
+ bool defined() const;
+ bool operator==(const label& right) const;
+ bool operator!=(const label& right) const;
+ inst& operator*() const;
+ inst* operator->() const;
+ friend ptrdiff_t offset(const label& left,
+ const label& right);
+private:
+ label (size_t where, program* code)
+ : where(where), code(code) {}
+ size_t where;
+ program* code;
+ friend class program;
+};
+
+// Prints one instruction (including arguments).
+void printInst(std::ostream& out, const program::label& code,
+ const program::label& base);
+
+// Prints code until a ret opcode is printed.
+void print(std::ostream& out, program *base);
+
+// Inline forwarding functions for vm::program
+inline program::program()
+ : code() {}
+inline program::label program::end()
+{ return label(code.size(), this); }
+inline program::label program::begin()
+{ return label(0, this); }
+inline inst& program::back()
+{ return code.back(); }
+inline void program::pop_back()
+{ return code.pop_back(); }
+inline void program::encode(inst i)
+{ code.push_back(i); }
+inline inst& program::operator[](size_t n)
+{ return code[n]; }
+inline program::label& program::label::operator++()
+{ ++where; return *this; }
+inline program::label& program::label::operator--()
+{ --where; return *this; }
+inline bool program::label::defined() const
+{ return (code != 0); }
+inline bool program::label::operator==(const label& right) const
+{ return (code == right.code) && (where == right.where); }
+inline bool program::label::operator!=(const label& right) const
+{ return !(*this == right); }
+inline inst& program::label::operator*() const
+{ return (*code)[where]; }
+inline inst* program::label::operator->() const
+{ return &**this; }
+inline ptrdiff_t offset(const program::label& left,
+ const program::label& right)
+{ return right.where - left.where; }
+
+} // namespace vm
+
+#endif // PROGRAM_H
diff --git a/graphics/asymptote/psfile.cc b/graphics/asymptote/psfile.cc
new file mode 100644
index 0000000000..8adce3855d
--- /dev/null
+++ b/graphics/asymptote/psfile.cc
@@ -0,0 +1,719 @@
+/*****
+ * psfile.cc
+ * Andy Hammerlindl 2002/06/10
+ *
+ * Encapsulates the writing of commands to a PostScript file.
+ * Allows identification and removal of redundant commands.
+ *****/
+
+#include <ctime>
+#include <iomanip>
+#include <sstream>
+#include <zlib.h>
+
+#include "psfile.h"
+#include "settings.h"
+#include "errormsg.h"
+#include "array.h"
+#include "stack.h"
+
+using std::ofstream;
+using std::setw;
+using vm::array;
+using vm::read;
+using vm::stack;
+using vm::callable;
+using vm::pop;
+
+namespace camp {
+
+void checkColorSpace(ColorSpace colorspace)
+{
+ switch(colorspace) {
+ case DEFCOLOR:
+ case INVISIBLE:
+ reportError("Cannot shade with invisible pen");
+ case PATTERN:
+ reportError("Cannot shade with pattern");
+ break;
+ default:
+ break;
+ }
+}
+
+psfile::psfile(const string& filename, bool pdfformat)
+ : filename(filename), pdfformat(pdfformat), pdf(false),
+ transparency(false), buffer(NULL), out(NULL)
+{
+ if(filename.empty()) out=&cout;
+ else out=new ofstream(filename.c_str());
+ out->setf(std::ios::boolalpha);
+ if(!out || !*out)
+ reportError("Cannot write to "+filename);
+}
+
+static const char *inconsistent="inconsistent colorspaces";
+static const char *rectangular="matrix is not rectangular";
+
+void psfile::writefromRGB(unsigned char r, unsigned char g, unsigned char b,
+ ColorSpace colorspace, size_t ncomponents)
+{
+ static const double factor=1.0/255.0;
+ pen p(r*factor,g*factor,b*factor);
+ p.convert();
+ if(!p.promote(colorspace))
+ reportError(inconsistent);
+ write(&p,ncomponents);
+}
+
+inline unsigned char average(unsigned char *a, size_t dx, size_t dy)
+{
+ return ((unsigned) a[0]+(unsigned) a[dx]+(unsigned) a[dy]+
+ (unsigned) a[dx+dy])/4;
+}
+
+void psfile::dealias(unsigned char *a, size_t width, size_t height, size_t n,
+ bool convertrgb, ColorSpace colorspace)
+{
+ // Dealias all but the last row and column of pixels.
+ size_t istop=width-1;
+ size_t jstop=height-1;
+ if(convertrgb) {
+ size_t nwidth=3*width;
+ for(size_t j=0; j < height; ++j) {
+ unsigned char *aj=a+nwidth*j;
+ for(size_t i=0; i < width; ++i) {
+ unsigned char *ai=aj+3*i;
+ if(i < istop && j < jstop)
+ writefromRGB(average(ai,3,nwidth),
+ average(ai+1,3,nwidth),
+ average(ai+2,3,nwidth),colorspace,n);
+ else
+ writefromRGB(ai[0],ai[1],ai[2],colorspace,n);
+ }
+ }
+ } else {
+ size_t nwidth=n*width;
+ for(size_t j=0; j < jstop; ++j) {
+ unsigned char *aj=a+nwidth*j;
+ for(size_t i=0; i < istop; ++i) {
+ unsigned char *ai=aj+n*i;
+ for(size_t k=0; k < n; ++k)
+ ai[k]=average(ai+k,n,nwidth);
+ }
+ }
+ }
+}
+
+void psfile::writeCompressed(const unsigned char *a, size_t size)
+{
+ uLongf compressedSize=compressBound(size);
+ Bytef *compressed=new Bytef[compressedSize];
+
+ if(compress(compressed,&compressedSize,a,size) != Z_OK)
+ reportError("image compression failed");
+
+ encode85 e(out);
+ for(size_t i=0; i < compressedSize; ++i)
+ e.put(compressed[i]);
+}
+
+void psfile::close()
+{
+ if(out) {
+ out->flush();
+ if(!filename.empty()) {
+#ifdef __MSDOS__
+ chmod(filename.c_str(),~settings::mask & 0777);
+#endif
+ if(!out->good())
+ // Don't call reportError since this may be called on handled_error.
+ reportFatal("Cannot write to "+filename);
+ delete out;
+ out=NULL;
+ }
+ }
+}
+
+psfile::~psfile()
+{
+ close();
+}
+
+void psfile::header(bool eps)
+{
+ Int level=settings::getSetting<Int>("level");
+ *out << "%!PS-Adobe-" << level << ".0";
+ if(eps)
+ *out << " EPSF-" << level << ".0";
+ *out << newl;
+}
+
+void psfile::prologue(const bbox& box)
+{
+ header(true);
+ BoundingBox(box);
+ *out << "%%Creator: " << settings::PROGRAM << " " << settings::VERSION
+ << REVISION << newl;
+
+ time_t t; time(&t);
+ struct tm *tt = localtime(&t);
+ char prev = out->fill('0');
+ *out << "%%CreationDate: " << tt->tm_year + 1900 << "."
+ << setw(2) << tt->tm_mon+1 << "." << setw(2) << tt->tm_mday << " "
+ << setw(2) << tt->tm_hour << ":" << setw(2) << tt->tm_min << ":"
+ << setw(2) << tt->tm_sec << newl;
+ out->fill(prev);
+
+ *out << "%%Pages: 1" << newl;
+ *out << "%%Page: 1 1" << newl;
+
+ if(!pdfformat)
+ *out
+ << "/Setlinewidth {0 exch dtransform dup abs 1 lt {pop 0}{round} ifelse"
+ << newl
+ << "idtransform setlinewidth pop} bind def" << newl;
+}
+
+void psfile::epilogue()
+{
+ *out << "showpage" << newl;
+ *out << "%%EOF" << newl;
+}
+
+void psfile::setcolor(const pen& p, const string& begin="",
+ const string& end="")
+{
+ if(p.cmyk() && (!lastpen.cmyk() ||
+ (p.cyan() != lastpen.cyan() ||
+ p.magenta() != lastpen.magenta() ||
+ p.yellow() != lastpen.yellow() ||
+ p.black() != lastpen.black()))) {
+ *out << begin << p.cyan() << " " << p.magenta() << " " << p.yellow() << " "
+ << p.black() << (pdf ? " k" : " setcmykcolor") << end << newl;
+ } else if(p.rgb() && (!lastpen.rgb() ||
+ (p.red() != lastpen.red() ||
+ p.green() != lastpen.green() ||
+ p.blue() != lastpen.blue()))) {
+ *out << begin << p.red() << " " << p.green() << " " << p.blue()
+ << (pdf ? " rg" : " setrgbcolor") << end << newl;
+ } else if(p.grayscale() && (!lastpen.grayscale() ||
+ p.gray() != lastpen.gray())) {
+ *out << begin << p.gray() << (pdf ? " g" : " setgray") << end << newl;
+ }
+}
+
+void psfile::setopacity(const pen& p)
+{
+ if(p.blend() != lastpen.blend()) {
+ *out << "/" << p.blend() << " .setblendmode" << newl;
+ transparency=true;
+ }
+
+ if(p.opacity() != lastpen.opacity()) {
+ *out << p.opacity() << " .setopacityalpha" << newl;
+ transparency=true;
+ }
+
+ lastpen.settransparency(p);
+}
+
+
+void psfile::setpen(pen p)
+{
+ p.convert();
+
+ setopacity(p);
+
+ if(!p.fillpattern().empty() && p.fillpattern() != lastpen.fillpattern())
+ *out << p.fillpattern() << " setpattern" << newl;
+ else setcolor(p);
+
+ // Defer dynamic linewidth until stroke time in case currentmatrix changes.
+ if(p.width() != lastpen.width())
+ *out << p.width() << (pdfformat ? " setlinewidth" : " Setlinewidth")
+ << newl;
+
+ if(p.cap() != lastpen.cap())
+ *out << p.cap() << " setlinecap" << newl;
+
+ if(p.join() != lastpen.join())
+ *out << p.join() << " setlinejoin" << newl;
+
+ if(p.miter() != lastpen.miter())
+ *out << p.miter() << " setmiterlimit" << newl;
+
+ const LineType *linetype=p.linetype();
+ const LineType *lastlinetype=lastpen.linetype();
+
+ if(!(linetype->pattern == lastlinetype->pattern) ||
+ linetype->offset != lastlinetype->offset) {
+ out->setf(std::ios::fixed);
+ *out << linetype->pattern << " " << linetype->offset << " setdash" << newl;
+ out->unsetf(std::ios::fixed);
+ }
+
+ lastpen=p;
+}
+
+void psfile::write(const pen& p)
+{
+ if(p.cmyk())
+ *out << p.cyan() << " " << p.magenta() << " " << p.yellow() << " "
+ << p.black();
+ else if(p.rgb())
+ *out << p.red() << " " << p.green() << " " << p.blue();
+ else if(p.grayscale())
+ *out << p.gray();
+}
+
+void psfile::write(path p, bool newPath)
+{
+ Int n = p.size();
+ assert(n != 0);
+
+ if(newPath) newpath();
+
+ pair z0=p.point((Int) 0);
+
+ // Draw points
+ moveto(z0);
+
+ for(Int i = 1; i < n; i++) {
+ if(p.straight(i-1)) lineto(p.point(i));
+ else curveto(p.postcontrol(i-1),p.precontrol(i),p.point(i));
+ }
+
+ if(p.cyclic()) {
+ if(p.straight(n-1)) lineto(z0);
+ else curveto(p.postcontrol(n-1),p.precontrol((Int) 0),z0);
+ closepath();
+ } else {
+ if(n == 1) lineto(z0);
+ }
+}
+
+void psfile::latticeshade(const vm::array& a, const transform& t)
+{
+ checkLevel();
+ size_t n=a.size();
+ if(n == 0) return;
+
+ array *a0=read<array *>(a,0);
+ size_t m=a0->size();
+ setfirstopacity(*a0);
+
+ ColorSpace colorspace=maxcolorspace2(a);
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ *out << "<< /ShadingType 1" << newl
+ << "/Matrix ";
+ write(t);
+ *out << newl;
+ *out << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/Function" << newl
+ << "<< /FunctionType 0" << newl
+ << "/Order 1" << newl
+ << "/Domain [0 1 0 1]" << newl
+ << "/Range [";
+ for(size_t i=0; i < ncomponents; ++i)
+ *out << "0 1 ";
+ *out << "]" << newl
+ << "/Decode [";
+ for(size_t i=0; i < ncomponents; ++i)
+ *out << "0 1 ";
+ *out << "]" << newl;
+ *out << "/BitsPerSample 8" << newl;
+ *out << "/Size [" << m << " " << n << "]" << newl
+ << "/DataSource <" << newl;
+
+ for(size_t i=n; i > 0;) {
+ array *ai=read<array *>(a,--i);
+ checkArray(ai);
+ size_t aisize=ai->size();
+ if(aisize != m) reportError(rectangular);
+ for(size_t j=0; j < m; j++) {
+ pen *p=read<pen *>(ai,j);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ *out << p->hex() << newl;
+ }
+ }
+
+ *out << ">" << newl
+ << ">>" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+// Axial and radial shading
+void psfile::gradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ bool extenda, const pen& penb, const pair& b,
+ double rb, bool extendb)
+{
+ checkLevel();
+ endclip(pena);
+
+ setopacity(pena);
+ checkColorSpace(colorspace);
+
+ *out << "<< /ShadingType " << (axial ? "2" : "3") << newl
+ << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/Coords [";
+ write(a);
+ if(!axial) write(ra);
+ write(b);
+ if(!axial) write(rb);
+ *out << "]" << newl
+ << "/Extend [" << extenda << " " << extendb << "]" << newl
+ << "/Function" << newl
+ << "<< /FunctionType 2" << newl
+ << "/Domain [0 1]" << newl
+ << "/C0 [";
+ write(pena);
+ *out << "]" << newl
+ << "/C1 [";
+ write(penb);
+ *out << "]" << newl
+ << "/N 1" << newl
+ << ">>" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+void psfile::gouraudshade(const pen& pentype,
+ const array& pens, const array& vertices,
+ const array& edges)
+{
+ checkLevel();
+ endclip(pentype);
+
+ size_t size=pens.size();
+ if(size == 0) return;
+
+ setfirstopacity(pens);
+ ColorSpace colorspace=maxcolorspace(pens);
+
+ *out << "<< /ShadingType 4" << newl
+ << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/DataSource [" << newl;
+ for(size_t i=0; i < size; i++) {
+ write(read<Int>(edges,i));
+ write(read<pair>(vertices,i));
+ pen *p=read<pen *>(pens,i);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ *out << " ";
+ write(*p);
+ *out << newl;
+ }
+ *out << "]" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+void psfile::vertexpen(array *pi, int j, ColorSpace colorspace)
+{
+ pen *p=read<pen *>(pi,j);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ *out << " ";
+ write(*p);
+}
+
+// Tensor-product patch shading
+void psfile::tensorshade(const pen& pentype, const array& pens,
+ const array& boundaries, const array& z)
+{
+ checkLevel();
+ endclip(pentype);
+
+ size_t size=pens.size();
+ if(size == 0) return;
+ size_t nz=z.size();
+
+ array *p0=read<array *>(pens,0);
+ if(checkArray(p0) != 4)
+ reportError("4 pens required");
+ setfirstopacity(*p0);
+
+ ColorSpace colorspace=maxcolorspace2(pens);
+ checkColorSpace(colorspace);
+
+ *out << "<< /ShadingType 7" << newl
+ << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/DataSource [" << newl;
+
+ for(size_t i=0; i < size; i++) {
+ // Only edge flag 0 (new patch) is implemented since the 32% data
+ // compression (for RGB) afforded by other edge flags really isn't worth
+ // the trouble or confusion for the user.
+ write(0);
+ path g=read<path>(boundaries,i);
+ if(!(g.cyclic() && g.size() == 4))
+ reportError("specify cyclic path of length 4");
+ for(Int j=4; j > 0; --j) {
+ write(g.point(j));
+ write(g.precontrol(j));
+ write(g.postcontrol(j-1));
+ }
+ if(nz == 0) { // Coons patch
+ static double nineth=1.0/9.0;
+ for(Int j=0; j < 4; ++j) {
+ write(nineth*(-4.0*g.point(j)+6.0*(g.precontrol(j)+g.postcontrol(j))
+ -2.0*(g.point(j-1)+g.point(j+1))
+ +3.0*(g.precontrol(j-1)+g.postcontrol(j+1))
+ -g.point(j+2)));
+ }
+ } else {
+ array *zi=read<array *>(z,i);
+ if(checkArray(zi) != 4)
+ reportError("specify 4 internal control points for each path");
+ write(read<pair>(zi,0));
+ write(read<pair>(zi,3));
+ write(read<pair>(zi,2));
+ write(read<pair>(zi,1));
+ }
+
+ array *pi=read<array *>(pens,i);
+ if(checkArray(pi) != 4)
+ reportError("specify 4 pens for each path");
+ vertexpen(pi,0,colorspace);
+ vertexpen(pi,3,colorspace);
+ vertexpen(pi,2,colorspace);
+ vertexpen(pi,1,colorspace);
+ *out << newl;
+ }
+
+ *out << "]" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+void psfile::write(pen *p, size_t ncomponents)
+{
+ switch(ncomponents) {
+ case 0:
+ break;
+ case 1:
+ writeByte(byte(p->gray()));
+ break;
+ case 3:
+ writeByte(byte(p->red()));
+ writeByte(byte(p->green()));
+ writeByte(byte(p->blue()));
+ break;
+ case 4:
+ writeByte(byte(p->cyan()));
+ writeByte(byte(p->magenta()));
+ writeByte(byte(p->yellow()));
+ writeByte(byte(p->black()));
+ default:
+ break;
+ }
+}
+
+string filter()
+{
+ return settings::getSetting<Int>("level") >= 3 ?
+ "1 (~>) /SubFileDecode filter /ASCII85Decode filter\n/FlateDecode" :
+ "1 (~>) /SubFileDecode filter /ASCII85Decode";
+}
+
+void psfile::imageheader(size_t width, size_t height, ColorSpace colorspace)
+{
+ size_t ncomponents=ColorComponents[colorspace];
+ *out << "/Device" << ColorDeviceSuffix[colorspace] << " setcolorspace"
+ << newl
+ << "<<" << newl
+ << "/ImageType 1" << newl
+ << "/Width " << width << newl
+ << "/Height " << height << newl
+ << "/BitsPerComponent 8" << newl
+ << "/Decode [";
+
+ for(size_t i=0; i < ncomponents; ++i)
+ *out << "0 1 ";
+
+ *out << "]" << newl
+ << "/ImageMatrix [" << width << " 0 0 " << height << " 0 0]" << newl
+ << "/DataSource currentfile " << filter() << " filter" << newl
+ << ">>" << newl
+ << "image" << newl;
+}
+
+void psfile::image(const array& a, const array& P, bool antialias)
+{
+ size_t asize=a.size();
+ size_t Psize=P.size();
+ if(asize == 0 || Psize == 0) return;
+
+ array *a0=read<array *>(a,0);
+ size_t a0size=a0->size();
+ if(a0size == 0) return;
+
+ setfirstopacity(P);
+
+ ColorSpace colorspace=maxcolorspace(P);
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ imageheader(a0size,asize,colorspace);
+
+ double min=read<double>(a0,0);
+ double max=min;
+ for(size_t i=0; i < asize; i++) {
+ array *ai=read<array *>(a,i);
+ size_t size=ai->size();
+ if(size != a0size)
+ reportError(rectangular);
+ for(size_t j=0; j < size; j++) {
+ double val=read<double>(ai,j);
+ if(val > max) max=val;
+ else if(val < min) min=val;
+ }
+ }
+
+ double step=(max == min) ? 0.0 : (Psize-1)/(max-min);
+
+ beginImage(ncomponents*a0size*asize);
+ for(size_t i=0; i < asize; i++) {
+ array *ai=read<array *>(a,i);
+ for(size_t j=0; j < a0size; j++) {
+ double val=read<double>(ai,j);
+ size_t index=(size_t) ((val-min)*step+0.5);
+ pen *p=read<pen *>(P,index < Psize ? index : Psize-1);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ write(p,ncomponents);
+ }
+ }
+ endImage(antialias,a0size,asize,ncomponents);
+}
+
+void psfile::image(const array& a, bool antialias)
+{
+ size_t asize=a.size();
+ if(asize == 0) return;
+
+ array *a0=read<array *>(a,0);
+ size_t a0size=a0->size();
+ if(a0size == 0) return;
+
+ setfirstopacity(*a0);
+
+ ColorSpace colorspace=maxcolorspace2(a);
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ imageheader(a0size,asize,colorspace);
+
+ beginImage(ncomponents*a0size*asize);
+ for(size_t i=0; i < asize; i++) {
+ array *ai=read<array *>(a,i);
+ size_t size=ai->size();
+ if(size != a0size)
+ reportError(rectangular);
+ for(size_t j=0; j < size; j++) {
+ pen *p=read<pen *>(ai,j);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ write(p,ncomponents);
+ }
+ }
+ endImage(antialias,a0size,asize,ncomponents);
+}
+
+void psfile::image(stack *Stack, callable *f, Int width, Int height,
+ bool antialias)
+{
+ if(width <= 0 || height <= 0) return;
+
+ Stack->push(0);
+ Stack->push(0);
+ f->call(Stack);
+ pen p=pop<pen>(Stack);
+
+ setopacity(p);
+
+ ColorSpace colorspace=p.colorspace();
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ imageheader(width,height,colorspace);
+
+ beginImage(ncomponents*width*height);
+ for(Int j=0; j < height; j++) {
+ for(Int i=0; i < width; i++) {
+ Stack->push(j);
+ Stack->push(i);
+ f->call(Stack);
+ pen p=pop<pen>(Stack);
+ p.convert();
+ if(!p.promote(colorspace))
+ reportError(inconsistent);
+ write(&p,ncomponents);
+ }
+ }
+ endImage(antialias,width,height,ncomponents);
+}
+
+void psfile::outImage(bool antialias, size_t width, size_t height,
+ size_t ncomponents)
+{
+ if(antialias) dealias(buffer,width,height,ncomponents);
+ if(settings::getSetting<Int>("level") >= 3)
+ writeCompressed(buffer,count);
+ else {
+ encode85 e(out);
+ for(size_t i=0; i < count; ++i)
+ e.put(buffer[i]);
+ }
+}
+
+void psfile::rawimage(unsigned char *a, size_t width, size_t height,
+ bool antialias)
+{
+ pen p(0.0,0.0,0.0);
+ p.convert();
+ ColorSpace colorspace=p.colorspace();
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ imageheader(width,height,colorspace);
+
+ count=ncomponents*width*height;
+ if(colorspace == RGB) {
+ buffer=a;
+ outImage(antialias,width,height,ncomponents);
+ } else {
+ beginImage(count);
+ if(antialias)
+ dealias(a,width,height,ncomponents,true,colorspace);
+ else {
+ size_t height3=3*height;
+ for(size_t i=0; i < width; ++i) {
+ unsigned char *ai=a+height3*i;
+ for(size_t j=0; j < height; ++j) {
+ unsigned char *aij=ai+3*j;
+ writefromRGB(aij[0],aij[1],aij[2],colorspace,ncomponents);
+ }
+ }
+ }
+ endImage(false,width,height,ncomponents);
+ }
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/psfile.h b/graphics/asymptote/psfile.h
new file mode 100644
index 0000000000..8a76e4ae83
--- /dev/null
+++ b/graphics/asymptote/psfile.h
@@ -0,0 +1,380 @@
+/*****
+ * psfile.h
+ * Andy Hammerlindl 2002/06/10
+ *
+ * Encapsulates the writing of commands to a PostScript file.
+ * Allows identification and removal of redundant commands.
+ *****/
+
+#ifndef PSFILE_H
+#define PSFILE_H
+
+#include <fstream>
+#include <iomanip>
+#include <sstream>
+
+#include "pair.h"
+#include "path.h"
+#include "bbox.h"
+#include "pen.h"
+#include "array.h"
+#include "callable.h"
+
+namespace camp {
+
+inline void BoundingBox(std::ostream& s, const bbox& box)
+{
+ s << "%%BoundingBox: " << std::setprecision(0) << std::fixed
+ << box.LowRes() << newl;
+ s.unsetf(std::ios::fixed);
+ s << "%%HiResBoundingBox: " << std::setprecision(9) << box << newl;
+}
+
+// An ASCII85Encode filter.
+class encode85 {
+ ostream *out;
+ int tuple;
+ int pos;
+ int count;
+ static const int width=72;
+public:
+ encode85(ostream *out) : out(out), tuple(0), pos(0), count(0) {}
+
+ ~encode85() {
+ if(count > 0)
+ encode(tuple, count);
+ if(pos+2 > width)
+ *out << '\n';
+ *out << "~>\n";
+ }
+private:
+ void encode(unsigned int tuple, int count) {
+ unsigned char buf[5], *s=buf;
+ int i=5;
+ do {
+ *s++=tuple % 85;
+ tuple /= 85;
+ } while(--i > 0);
+ i=count;
+ do {
+ *out << (unsigned char) (*--s + '!');
+ if(pos++ >= width) {
+ pos=0;
+ *out << '\n';
+ }
+ } while(i-- > 0);
+ }
+
+public:
+ void put(unsigned char c) {
+ switch (count++) {
+ case 0:
+ tuple |= (c << 24);
+ break;
+ case 1:
+ tuple |= (c << 16);
+ break;
+ case 2:
+ tuple |= (c << 8);
+ break;
+ case 3:
+ tuple |= c;
+ if(tuple == 0) {
+ *out << 'z';
+ if(pos++ >= width) {
+ pos=0;
+ *out << '\n';
+ }
+ } else
+ encode(tuple, count);
+ tuple=0;
+ count=0;
+ break;
+ }
+ }
+};
+
+class psfile {
+protected:
+ mem::stack<pen> pens;
+
+public:
+
+ string filename;
+ bool pdfformat; // Is final output format PDF?
+ bool pdf; // Output direct PDF?
+ bool transparency; // Is transparency used?
+ unsigned char *buffer;
+ size_t count;
+
+ void write(pen *p, size_t ncomponents);
+ void writefromRGB(unsigned char r, unsigned char g, unsigned char b,
+ ColorSpace colorspace, size_t ncomponents);
+
+ void writeCompressed(const unsigned char *a, size_t size);
+ void dealias(unsigned char *a, size_t width, size_t height, size_t n,
+ bool convertrgb=false, ColorSpace colorspace=DEFCOLOR);
+
+ void beginImage(size_t n) {
+ buffer=new unsigned char[n];
+ count=0;
+ }
+
+ void outImage(bool antialias, size_t width, size_t height,
+ size_t ncomponents);
+
+ void endImage(bool antialias, size_t width, size_t height,
+ size_t ncomponents) {
+ outImage(antialias,width,height,ncomponents);
+ delete[] buffer;
+ }
+
+ void writeByte(unsigned char n) {
+ buffer[count++]=n;
+ }
+
+protected:
+ pen lastpen;
+ std::ostream *out;
+
+public:
+ psfile(const string& filename, bool pdfformat);
+
+ psfile() {pdf=settings::pdf(settings::getSetting<string>("tex"));}
+
+ virtual ~psfile();
+
+ void BoundingBox(const bbox& box) {
+ camp::BoundingBox(*out,box);
+ }
+
+ void prologue(const bbox& box);
+ void epilogue();
+ void header(bool eps);
+
+ void close();
+
+ void write(double x) {
+ *out << " " << x;
+ }
+
+ void writenewl() {
+ *out << newl;
+ }
+
+// bool Transparency() {
+// return transparency;
+// }
+
+ void write(pair z) {
+ *out << " " << z.getx() << " " << z.gety();
+ }
+
+ void write(transform t) {
+ if(!pdf) *out << "[";
+ *out << " " << t.getxx() << " " << t.getyx()
+ << " " << t.getxy() << " " << t.getyy()
+ << " " << t.getx() << " " << t.gety();
+ if(!pdf) *out << "]";
+ }
+
+ void resetpen() {
+ lastpen=pen(initialpen);
+ lastpen.convert();
+ }
+
+ void setcolor(const pen& p, const string& begin, const string& end);
+ void setopacity(const pen& p);
+
+ virtual void setpen(pen p);
+
+ void write(const pen& p);
+
+ void write(path p, bool newPath=true);
+
+ virtual void writeclip(path p, bool newPath=true) {
+ write(p,newPath);
+ }
+
+ virtual void dot(path p, pen, bool newPath=true) {
+ write(p,newPath);
+ }
+
+ virtual void newpath() {
+ if(!pdf) *out << "newpath";
+ }
+
+ virtual void moveto(pair z) {
+ write(z);
+ if(pdf) *out << " m" << newl;
+ else *out << " moveto" << newl;
+ }
+
+ virtual void lineto(pair z) {
+ write(z);
+ if(pdf) *out << " l" << newl;
+ else *out << " lineto" << newl;
+ }
+
+ virtual void curveto(pair zp, pair zm, pair z1) {
+ write(zp); write(zm); write(z1);
+ if(pdf) *out << " c" << newl;
+ else *out << " curveto" << newl;
+ }
+
+ virtual void closepath() {
+ if(pdf) *out << "h" << newl;
+ else *out << "closepath" << newl;
+ }
+
+ virtual void stroke(const pen &p, bool dot=false) {
+ if(pdf) *out << "S" << newl;
+ else *out << "stroke" << newl;
+ }
+
+ virtual void strokepath() {
+ if(pdf) reportError("PDF does not support strokepath");
+ else *out << "strokepath" << newl;
+ }
+
+ virtual void fill(const pen &p) {
+ if(p.evenodd()) {
+ if(pdf) *out << "f*" << newl;
+ else *out << "eofill" << newl;
+ } else {
+ if(pdf) *out << "f" << newl;
+ else *out << "fill" << newl;
+ }
+ }
+
+ virtual void beginclip() {
+ newpath();
+ }
+
+ virtual void endclip(const pen &p) {
+ if(p.evenodd()) {
+ if(pdf) *out << "W* n" << newl;
+ else *out << "eoclip" << newl;
+ } else {
+ if(pdf) *out << "W n" << newl;
+ else *out << "clip" << newl;
+ }
+ }
+
+ virtual void endpsclip(const pen &p) {endclip(p);}
+
+ void checkLevel() {
+ int n=settings::getSetting<Int>("level");
+ if(n < 3)
+ reportError("PostScript shading requires -level 3");
+ }
+
+ virtual void beginlatticeshade(const vm::array& a, const bbox& b) {}
+ virtual void latticeshade(const vm::array& a, const transform& t);
+
+ virtual void begingradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ const pen& penb, const pair& b, double rb) {}
+
+ virtual void gradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ bool extenda, const pen& penb, const pair& b,
+ double rb, bool extendb);
+
+ virtual void begingouraudshade(const vm::array& pens,
+ const vm::array& vertices,
+ const vm::array& edges) {}
+ virtual void gouraudshade(const pen& pentype, const vm::array& pens,
+ const vm::array& vertices, const vm::array& edges);
+
+ virtual void begintensorshade(const vm::array& pens,
+ const vm::array& boundaries,
+ const vm::array& z) {}
+ virtual void tensorshade(const pen& pentype, const vm::array& pens,
+ const vm::array& boundaries, const vm::array& z);
+
+ void vertexpen(vm::array *pi, int j, ColorSpace colorspace);
+
+ void imageheader(size_t width, size_t height, ColorSpace colorspace);
+
+ void image(const vm::array& a, const vm::array& p, bool antialias);
+ void image(const vm::array& a, bool antialias);
+ void image(vm::stack *Stack, vm::callable *f, Int width, Int height,
+ bool antialias);
+
+ void rawimage(unsigned char *a, size_t width, size_t height, bool antialias);
+
+ virtual void gsave(bool tex=false) {
+ if(pdf) *out << "q";
+ else *out << "gsave";
+ if(!tex) *out << newl;
+ pens.push(lastpen);
+ }
+
+ virtual void grestore(bool tex=false) {
+ if(pens.size() < 1)
+ reportError("grestore without matching gsave");
+ lastpen=pens.top();
+ pens.pop();
+ if(pdf) *out << "Q";
+ else *out << "grestore";
+ if(!tex) *out << newl;
+ }
+
+ virtual void translate(pair z) {
+ if(z == pair(0.0,0.0)) return;
+ if(pdf) *out << " 1 0 0 1 " << newl;
+ write(z);
+ if(pdf) *out << " cm" << newl;
+ *out << " translate" << newl;
+ }
+
+ // Multiply on a transform to the transformation matrix.
+ virtual void concat(transform t) {
+ if(t.isIdentity()) return;
+ write(t);
+ if(pdf) *out << " cm" << newl;
+ else *out << " concat" << newl;
+ }
+
+ void verbatimline(const string& s) {
+ *out << s << newl;
+ }
+
+ void verbatim(const string& s) {
+ *out << s;
+ }
+
+ // Determine shading and image transparency based on first pen.
+ void setfirstopacity(const vm::array& pens) {
+ if(pens.size() > 0) {
+ pen *p=vm::read<pen *>(pens,0);
+ setopacity(*p);
+ }
+ }
+
+ ColorSpace maxcolorspace(const vm::array& pens) {
+ ColorSpace colorspace=DEFCOLOR;
+ size_t size=pens.size();
+ for(size_t i=0; i < size; i++) {
+ pen *p=vm::read<pen *>(pens,i);
+ p->convert();
+ colorspace=max(colorspace,p->colorspace());
+ }
+ return colorspace;
+ }
+
+ ColorSpace maxcolorspace2(const vm::array& penarray) {
+ ColorSpace colorspace=DEFCOLOR;
+ size_t size=penarray.size();
+ for(size_t i=0; i < size; i++)
+ colorspace=max(colorspace,
+ maxcolorspace(vm::read<vm::array>(penarray,i)));
+ return colorspace;
+ }
+
+};
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/quaternion.cc b/graphics/asymptote/quaternion.cc
new file mode 100644
index 0000000000..7f3eaf5f65
--- /dev/null
+++ b/graphics/asymptote/quaternion.cc
@@ -0,0 +1,246 @@
+/***********************************************************************
+
+ quaternion.cc - A quaternion class
+
+ -------------------------------------------------------------------
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+
+ WWW: http://sourceforge.net/projects/glui/
+ Forums: http://sourceforge.net/forum/?group_id=92496
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+************************************************************************
+
+ Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
+ Oct 2003, Nigel Stewart - GLUI Code Cleaning
+
+************************************************************************/
+
+#include "quaternion.h"
+#include <cmath>
+
+/******************************************* constructors **************/
+
+quat::quat()
+{
+ *this = quat_identity();
+}
+
+quat::quat(const float x, const float y, const float z, const float w)
+{
+ v.set( x, y, z );
+ s = w;
+}
+
+quat::quat(const vec3 &_v, const float _s)
+{
+ set( _v, _s );
+}
+
+quat::quat(const float _s, const vec3 &_v)
+{
+ set( _v, _s );
+}
+
+quat::quat(const float *d)
+{
+ v[0] = d[0];
+ v[1] = d[1];
+ v[2] = d[2];
+ s = d[3];
+}
+
+quat::quat(const double *d)
+{
+ v[0] = (float) d[0];
+ v[1] = (float) d[1];
+ v[2] = (float) d[2];
+ s = (float) d[3];
+}
+
+quat::quat(const quat &q)
+{
+ v = q.v;
+ s = q.s;
+}
+
+void quat::set(const vec3 &_v, const float _s)
+{
+ v = _v;
+ s = _s;
+}
+
+quat &quat::operator=(const quat &q)
+{
+ v = q.v;
+ s = q.s;
+ return *this;
+}
+
+/******** quat friends ************/
+
+quat operator + (const quat &a, const quat &b)
+{
+ return quat( a.s+b.s, a.v+b.v );
+}
+
+quat operator - (const quat &a, const quat &b)
+{
+ return quat( a.s-b.s, a.v-b.v );
+}
+
+quat operator - (const quat &a )
+{
+ return quat( -a.s, -a.v );
+}
+
+quat operator * ( const quat &a, const quat &b)
+{
+ return quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + (a.v^b.v) );
+}
+
+quat operator * ( const quat &a, const float t)
+{
+ return quat( a.v * t, a.s * t );
+}
+
+quat operator * ( const float t, const quat &a )
+{
+ return quat( a.v * t, a.s * t );
+}
+
+mat4 quat::to_mat4() const
+{
+ float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
+
+ float t = 2.0f / (v*v + s*s);
+
+ xs = v[VX]*t; ys = v[VY]*t; zs = v[VZ]*t;
+ wx = s*xs; wy = s*ys; wz = s*zs;
+ xx = v[VX]*xs; xy = v[VX]*ys; xz = v[VX]*zs;
+ yy = v[VY]*ys; yz = v[VY]*zs; zz = v[VZ]*zs;
+
+ mat4 matrix(
+ 1.0f-(yy+zz), xy+wz, xz-wy, 0.0f,
+ xy-wz, 1.0f-(xx+zz), yz+wx, 0.0f,
+ xz+wy, yz-wx, 1.0f-(xx+yy), 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f );
+
+ return matrix;
+}
+
+/************************************************* quat_identity() *****/
+/* Returns quaternion identity element */
+
+quat quat_identity()
+{
+ return quat( vec3( 0.0, 0.0, 0.0 ), 1.0 );
+}
+
+/************************************************ quat_slerp() ********/
+/* Quaternion spherical interpolation */
+
+quat quat_slerp(const quat &from, const quat &to, float t)
+{
+ quat to1;
+ float omega, cosom, sinom, scale0, scale1;
+
+ /* calculate cosine */
+ cosom = from.v * to.v + from.s + to.s;
+
+ /* Adjust signs (if necessary) */
+ if ( cosom < 0.0 )
+ {
+ cosom = -cosom;
+ to1 = -to;
+ }
+ else
+ {
+ to1 = to;
+ }
+
+ /* Calculate coefficients */
+ if ((1.0 - cosom) > FUDGE )
+ {
+ /* standard case (slerp) */
+ omega = (float) acos( cosom );
+ sinom = (float) sin( omega );
+ scale0 = (float) sin((1.0 - t) * omega) / sinom;
+ scale1 = (float) sin(t * omega) / sinom;
+ }
+ else
+ {
+ /* 'from' and 'to' are very close - just do linear interpolation */
+ scale0 = 1.0f - t;
+ scale1 = t;
+ }
+
+ return scale0 * from + scale1 * to1;
+}
+
+/********************************************** set_angle() ************/
+/* set rot angle (degrees) */
+
+void quat::set_angle(float f)
+{
+ vec3 axis = get_axis();
+
+ static const double halfradians=acos(-1.0)/360.0;
+ f *= halfradians;
+
+ s = (float) cos( f );
+
+ v = axis * (float) sin( f );
+}
+
+/********************************************** scale_angle() ************/
+/* scale rot angle (degrees) */
+
+void quat::scale_angle(float f)
+{
+ set_angle( f * get_angle() );
+}
+
+/********************************************** get_angle() ************/
+/* get rot angle (degrees). Assumes s is between -1 and 1 */
+
+float quat::get_angle() const
+{
+ static const double degrees2=360.0/acos(-1.0);
+ return (float) (acos( s ) * degrees2);
+}
+
+/********************************************* get_axis() **************/
+
+vec3 quat::get_axis() const
+{
+ float scale = (float) sin( acos( s ) );
+
+ if ( scale < FUDGE && scale > -FUDGE )
+ return vec3( 0.0, 0.0, 0.0 );
+ else
+ return v / scale;
+}
+
+/******************************************* quat::print() ************/
+
+void quat::print(FILE *dest, const char *name) const
+{
+ fprintf( dest, "%s: v:<%3.2f %3.2f %3.2f> s:%3.2f\n",
+ name, v[0], v[1], v[2], s );
+}
diff --git a/graphics/asymptote/quaternion.h b/graphics/asymptote/quaternion.h
new file mode 100644
index 0000000000..f58a7445e5
--- /dev/null
+++ b/graphics/asymptote/quaternion.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+
+ quaternion.h - A quaternion class
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+
+ ---------------------------------------------------------------------
+
+ WWW: http://sourceforge.net/projects/glui/
+ Forums: http://sourceforge.net/forum/?group_id=92496
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************/
+
+#ifndef GLUI_QUATERNION_H
+#define GLUI_QUATERNION_H
+
+#include "algebra3.h"
+#include <cstdio>
+
+/* this line defines a new type: pointer to a function which returns a */
+/* float and takes as argument a float */
+typedef float (*V_FCT_PTR)(float);
+
+/****************************************************************
+ * Quaternion *
+ ****************************************************************/
+
+class quat
+{
+ /*protected: */
+public:
+
+ vec3 v; /* vector component */
+ float s; /* scalar component */
+
+ /*public: */
+
+ /* Constructors */
+
+ quat();
+ quat(float x, float y, float z, float w);
+ quat(const vec3 &v, float s);
+ quat(float s, const vec3 &v);
+ quat(const float *d); /* copy from four-element float array */
+ quat(const double *f); /* copy from four-element double array */
+ quat(const quat &q); /* copy from other quat */
+
+ /* Assignment operators */
+
+ quat &operator = (const quat &v); /* assignment of a quat */
+ quat &operator += (const quat &v); /* incrementation by a quat */
+ quat &operator -= (const quat &v); /* decrementation by a quat */
+ quat &operator *= (float d); /* multiplication by a constant */
+ quat &operator /= (float d); /* division by a constant */
+
+ /* special functions */
+
+ float length() const; /* length of a quat */
+ float length2() const; /* squared length of a quat */
+ quat &normalize(); /* normalize a quat */
+ quat &apply(V_FCT_PTR fct); /* apply a func. to each component */
+ vec3 xform(const vec3 &v ); /* q*v*q-1 */
+ mat4 to_mat4() const;
+ void set_angle(float f); /* set rot angle (degrees) */
+ void scale_angle(float f); /* scale rot angle (degrees) */
+ float get_angle() const; /* set rot angle (degrees) */
+ vec3 get_axis() const; /* get axis */
+
+ void print( FILE *file, const char *name ) const; /* print to a file */
+
+ float &operator [] (int i); /* indexing */
+ const float &operator [] (int i) const; /* indexing */
+
+ void set(float x, float y, float z); /* set quat */
+ void set(const vec3 &v, float s); /* set quat */
+
+ /* friends */
+
+ friend quat operator - (const quat &v); /* -q1 */
+ friend quat operator + (const quat &a, const quat &b); /* q1 + q2 */
+ friend quat operator - (const quat &a, const quat &b); /* q1 - q2 */
+ friend quat operator * (const quat &a, float d); /* q1 * 3.0 */
+ friend quat operator * (float d, const quat &a); /* 3.0 * q1 */
+ friend quat operator * (const quat &a, const quat &b); /* q1 * q2 */
+ friend quat operator / (const quat &a, float d); /* q1 / 3.0 */
+ friend int operator == (const quat &a, const quat &b); /* q1 == q2 ? */
+ friend int operator != (const quat &a, const quat &b); /* q1 != q2 ? */
+ friend void swap(quat &a, quat &b); /* swap q1 &q2 */
+ /*friend quat min(const quat &a, const quat &b); -- min(q1, q2) */
+ /*friend quat max(const quat &a, const quat &b); -- max(q1, q2) */
+ friend quat prod(const quat &a, const quat &b); /* term by term mult*/
+};
+
+/* Utility functions */
+
+quat quat_identity(); /* Returns quaternion identity element */
+quat quat_slerp(const quat &from, const quat &to, float t);
+
+#endif
diff --git a/graphics/asymptote/record.cc b/graphics/asymptote/record.cc
new file mode 100644
index 0000000000..e07d4b2bca
--- /dev/null
+++ b/graphics/asymptote/record.cc
@@ -0,0 +1,80 @@
+/*****
+ * record.cc
+ * Tom Prince 2004/07/15
+ *
+ * The type for records and modules in the language.
+ *****/
+
+#include "record.h"
+#include "inst.h"
+#include "runtime.h"
+#include "coder.h"
+
+
+
+namespace types {
+
+record::record(symbol name, frame *level)
+ : ty(ty_record),
+ name(name),
+ level(level),
+ init(new vm::lambda),
+ e()
+{
+ assert(init);
+#ifdef DEBUG_FRAME
+ init->name = "struct "+string(name);
+#endif
+}
+
+record::~record()
+{}
+
+record *record::newRecord(symbol id, bool statically)
+{
+ frame *underlevel = getLevel(statically);
+ assert(underlevel);
+
+ frame *level = new frame(id, underlevel, 0);
+
+ record *r = new record(id, level);
+ return r;
+}
+
+// Initialize to null by default.
+trans::access *record::initializer() {
+ static trans::bltinAccess a(run::pushNullRecord);
+ return &a;
+}
+
+dummyRecord::dummyRecord(symbol name)
+ : record(name, new frame(name, 0,0))
+{
+ // Encode the instructions to put an placeholder instance of the record
+ // on the stack.
+ trans::coder c(nullPos, this, 0);
+ c.closeRecord();
+}
+
+dummyRecord::dummyRecord(string s)
+ : record (symbol::trans(s), new frame(s,0,0))
+{
+ // Encode the instructions to put an placeholder instance of the record
+ // on the stack.
+ trans::coder c(nullPos, this, 0);
+ c.closeRecord();
+}
+
+void dummyRecord::add(string name, ty *t, trans::access *a,
+ trans::permission perm) {
+ e.addVar(symbol::trans(name),
+ new trans::varEntry(t, a, perm, this, this, position()));
+}
+
+void dummyRecord::add(string name, function *t, vm::bltin f,
+ trans::permission perm) {
+ REGISTER_BLTIN(f, name);
+ add(name, t, new trans::bltinAccess(f), perm);
+}
+
+} // namespace types
diff --git a/graphics/asymptote/record.h b/graphics/asymptote/record.h
new file mode 100644
index 0000000000..2b260f4b83
--- /dev/null
+++ b/graphics/asymptote/record.h
@@ -0,0 +1,128 @@
+/*****
+ * record.h
+ * Andy Hammerlindl 2003/07/09
+ *
+ * The type for records and modules in the language.
+ *****/
+
+#ifndef RECORD_H
+#define RECORD_H
+
+#include "types.h"
+#include "env.h"
+#include "frame.h"
+#include "access.h"
+
+namespace vm {
+struct lambda;
+}
+
+using trans::frame;
+using trans::protoenv;
+using trans::varEntry;
+using trans::tyEntry;
+
+namespace types {
+
+class record : public ty {
+ // The base name of this type.
+ symbol name;
+
+ // The frame. Like a frame for a function, it allocates the accesses
+ // for fields and specifies the size of the record.
+ frame *level;
+
+ // The runtime representation of the record used by the virtual machine.
+ vm::lambda *init;
+
+public:
+ // The name bindings for fields of the record.
+ protoenv e;
+
+ // These are name bindings that should be added to the enclosing environment
+ // after translation of the record is completed. Constructors implicitly
+ // defined by "operator init" are stored here.
+ protoenv postdefenv;
+
+ record(symbol name, frame *level);
+ ~record();
+
+ symbol getName()
+ {
+ return name;
+ }
+
+ bool isReference() {
+ return true;
+ }
+
+ size_t hash() const {
+ // Use the pointer, as two records are equivalent only if they are the
+ // same object.
+ return (size_t)this;
+ }
+
+ // Initialize to null by default.
+ trans::access *initializer();
+
+ frame *getLevel(bool statically = false)
+ {
+ if (statically) {
+ frame *f=level->getParent();
+ return f ? f : level;
+ }
+ else
+ return level;
+ }
+
+ vm::lambda *getInit()
+ {
+ return init;
+ }
+
+ // Allocates a new dynamic field in the record.
+ trans::access *allocField(bool statically)
+ {
+ frame *underlevel = getLevel(statically);
+ assert(underlevel);
+ return underlevel->allocLocal();
+ }
+
+ // Create a statically enclosed record from this record.
+ record *newRecord(symbol id, bool statically);
+
+ void print(ostream& out) const
+ {
+ out << name;
+ }
+
+ void debug(ostream& out) const
+ {
+ out << "struct " << name << endl;
+ out << "types:" << endl;
+ out << "re-implement" << endl;
+ //out << te;
+ out << "fields: " << endl;
+ out << "re-implement" << endl;
+ //out << ve;
+ }
+};
+
+// A record that is being used just for its fields and types, and has no real
+// initializer. This is for modules such as settings that are built into the
+// language.
+class dummyRecord : public record {
+public:
+ dummyRecord(symbol name);
+ dummyRecord(string s);
+
+ // Convenient functions for adding fields.
+ void add(string name, ty *t, trans::access *a,
+ trans::permission perm=trans::PUBLIC);
+ void add(string name, function *t, vm::bltin f,
+ trans::permission perm=trans::PUBLIC);
+};
+
+} //namespace types
+
+#endif
diff --git a/graphics/asymptote/refaccess.cc b/graphics/asymptote/refaccess.cc
new file mode 100644
index 0000000000..b1addf41e1
--- /dev/null
+++ b/graphics/asymptote/refaccess.cc
@@ -0,0 +1,57 @@
+/*****
+ * refaccess.cc
+ * Andy Hammerlindl 2005/11/28
+ *
+ * An access which refers to a variable or other object in C++.
+ *****/
+
+#include "refaccess.h"
+
+namespace trans {
+
+using vm::item;
+using vm::stack;
+using vm::pop;
+
+/* itemRefAccess */
+void itemPointerRead(stack *s) {
+ item *p=pop<item *>(s);
+ s->push(*p);
+}
+
+void itemPointerWrite(stack *s) {
+ item *p=pop<item *>(s);
+ item value=pop(s);
+ *p=value;
+ s->push(value);
+}
+
+void itemRefAccess::encode(action act, position, coder &e)
+{
+ REGISTER_BLTIN(itemPointerRead, "itemPointerRead");
+ REGISTER_BLTIN(itemPointerWrite, "itemPointerWrite");
+
+ e.encode(inst::constpush, (item)ref);
+
+ switch (act) {
+ case READ:
+ e.encode(inst::builtin, itemPointerRead);
+ break;
+ case WRITE:
+ e.encode(inst::builtin, itemPointerWrite);
+ break;
+ case CALL:
+ e.encode(inst::builtin, itemPointerRead);
+ e.encode(inst::popcall);
+ break;
+ };
+}
+
+void itemRefAccess::encode(action act, position pos, coder &e, frame *)
+{
+ // Get rid of the useless top frame.
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+}
diff --git a/graphics/asymptote/refaccess.h b/graphics/asymptote/refaccess.h
new file mode 100644
index 0000000000..3357438115
--- /dev/null
+++ b/graphics/asymptote/refaccess.h
@@ -0,0 +1,90 @@
+/*****
+ * refaccess.h
+ * Andy Hammerlindl 2003/12/03
+ *
+ * An access which refers to a variable or other object in C++.
+ *****/
+
+#ifndef REFACCESS_H
+#define REFACCESS_H
+
+#include "access.h"
+#include "inst.h"
+#include "coder.h"
+#include "stack.h"
+
+namespace trans {
+
+// Access refers to a piece of data, represented by an item, somewhere in the
+// C++ code.
+class itemRefAccess : public access {
+ vm::item *ref;
+
+public:
+ itemRefAccess(vm::item *ref)
+ : ref(ref) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+};
+
+// Access refers to an arbitrary piece of data of type T.
+template <class T>
+class refAccess : public access {
+ T *ref;
+
+public:
+ refAccess(T *ref)
+ : ref(ref) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+};
+
+template <class T>
+void pointerRead(vm::stack *s) {
+ T *ptr=vm::pop<T *>(s);
+ s->push(*ptr);
+}
+
+template <class T>
+void pointerWrite(vm::stack *s) {
+ T *ptr=vm::pop<T *>(s);
+ T value=vm::pop<T>(s);
+ *ptr=value;
+ s->push(value);
+}
+
+template <class T>
+void refAccess<T>::encode(action act, position, coder &e)
+{
+ // You may be able to use typeid(T).name() to get a better label.
+ REGISTER_BLTIN((bltin) pointerRead<T>, "pointerRead");
+ REGISTER_BLTIN((bltin) pointerWrite<T>, "pointerWrite");
+
+ e.encode(vm::inst::constpush, (vm::item)ref);
+
+ switch (act) {
+ case READ:
+ e.encode(vm::inst::builtin, (bltin) pointerRead<T>);
+ break;
+ case WRITE:
+ e.encode(vm::inst::builtin, (bltin) pointerWrite<T>);
+ break;
+ case CALL:
+ e.encode(vm::inst::builtin, (bltin) pointerRead<T>);
+ e.encode(vm::inst::popcall);
+ break;
+ };
+}
+
+template <class T>
+void refAccess<T>::encode(action act, position pos, coder &e, frame *)
+{
+ // Get rid of the useless top frame.
+ e.encode(vm::inst::pop);
+ encode(act, pos, e);
+}
+
+}
+#endif
diff --git a/graphics/asymptote/revision.cc b/graphics/asymptote/revision.cc
new file mode 100644
index 0000000000..4f90aa3b17
--- /dev/null
+++ b/graphics/asymptote/revision.cc
@@ -0,0 +1 @@
+const char *REVISION="2.53";
diff --git a/graphics/asymptote/rounding.h b/graphics/asymptote/rounding.h
new file mode 100644
index 0000000000..a0efe31dc4
--- /dev/null
+++ b/graphics/asymptote/rounding.h
@@ -0,0 +1,87 @@
+/* GTS - Library for the manipulation of triangulated surfaces
+ * Copyright (C) 1999 Stéphane Popinet
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_FPU_CONTROL_H
+# include <fpu_control.h>
+# ifdef _FPU_EXTENDED
+# if !defined(__alpha__) || !defined(__GLIBC__)
+# if defined(__arm__)
+ static fpu_control_t fpu_round_double = _FPU_DEFAULT;
+# else
+ static fpu_control_t fpu_round_double =
+ (_FPU_DEFAULT & ~ _FPU_EXTENDED)|_FPU_DOUBLE;
+# endif
+ static fpu_control_t fpu_init;
+# define FPU_ROUND_DOUBLE { _FPU_GETCW(fpu_init);\
+ _FPU_SETCW(fpu_round_double); }
+# define FPU_RESTORE {_FPU_SETCW(fpu_init);}
+# else /* __alpha__ && __GLIBC__ */
+# define FPU_ROUND_DOUBLE
+# define FPU_RESTORE
+# endif /* __alpha__ && __GLIBC__ */
+# else /* not FPU_EXTENDED */
+# define FPU_ROUND_DOUBLE
+# define FPU_RESTORE
+# endif /* not FPU_EXTENDED */
+#else /* not HAVE_FPU_CONTROL_H */
+# ifdef __FreeBSD__
+# include <floatingpoint.h>
+# define FPU_ROUND_DOUBLE (fpsetprec(FP_PD))
+# define FPU_RESTORE (fpsetprec(FP_PE))
+# else /* not __FreeBSD__ */
+# ifdef WIN32
+# ifdef _MSC_VER
+# include <float.h>
+ static unsigned int fpu_init;
+# define FPU_ROUND_DOUBLE (fpu_init = _controlfp (0, 0),\
+ _controlfp (_PC_53, MCW_PC))
+# define FPU_RESTORE (_controlfp (fpu_init, 0xfffff))
+# elif __MINGW32__
+# include <float.h>
+ static unsigned int fpu_init;
+# define FPU_ROUND_DOUBLE (fpu_init = _controlfp (0, 0),\
+ _controlfp (_PC_53, _MCW_PC))
+# define FPU_RESTORE (_controlfp (fpu_init, 0xfffff))
+# else /* not _MSC_VER or __MINGW32__ */
+# error "You need MSVC or MinGW for the Win32 version"
+# endif /* not _MSC_VER or __MINGW32__ */
+# else /* not WIN32 */
+# ifdef __CYGWIN__
+ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
+ static fpu_control_t fpu_round_double = 0x027f;
+ static fpu_control_t fpu_init;
+# define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
+# define FPU_ROUND_DOUBLE { _FPU_GETCW(fpu_init);\
+ _FPU_SETCW(fpu_round_double); }
+# define FPU_RESTORE { _FPU_SETCW(fpu_init);}
+# else /* not __CYGWIN__ */
+# ifdef CPP_HAS_WARNING
+# warning "Unknown CPU: assuming default double precision rounding"
+# endif /* CPP_HAS_WARNING */
+# define FPU_ROUND_DOUBLE
+# define FPU_RESTORE
+# endif /* not __CYGWIN__ */
+# endif /* not WIN32 */
+# endif /* not __FreeBSD__ */
+#endif /* not HAVE_FPU_CONTROL_H */
diff --git a/graphics/asymptote/runarray.cc b/graphics/asymptote/runarray.cc
new file mode 100644
index 0000000000..a0ad0675ed
--- /dev/null
+++ b/graphics/asymptote/runarray.cc
@@ -0,0 +1,2550 @@
+/***** Autogenerated from runarray.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runarray.in"
+/*****
+ * runarray.in
+ *
+ * Runtime functions for array operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 21 "runarray.in"
+#include "array.h"
+#include "arrayop.h"
+#include "triple.h"
+#include "path3.h"
+#include "Delaunay.h"
+#include "glrender.h"
+
+#ifdef HAVE_LIBFFTW3
+#include "fftw++.h"
+#endif
+
+using namespace camp;
+using namespace vm;
+
+namespace run {
+extern pair zero;
+}
+
+typedef array boolarray;
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray2;
+
+using types::booleanArray;
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray2;
+
+typedef callable callableReal;
+
+void outOfBounds(const char *op, size_t len, Int n)
+{
+ ostringstream buf;
+ buf << op << " array of length " << len << " with out-of-bounds index " << n;
+ error(buf);
+}
+
+inline item& arrayRead(array *a, Int n)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) outOfBounds("reading",len,n);
+ return (*a)[(unsigned) n];
+}
+
+// Helper function to create deep arrays.
+static array* deepArray(Int depth, Int *dims)
+{
+ assert(depth > 0);
+
+ if (depth == 1) {
+ return new array(dims[0]);
+ } else {
+ Int length = dims[0];
+ depth--; dims++;
+
+ array *a = new array(length);
+
+ for (Int index = 0; index < length; index++) {
+ (*a)[index] = deepArray(depth, dims);
+ }
+ return a;
+ }
+}
+
+namespace run {
+array *Identity(Int n)
+{
+ size_t N=(size_t) n;
+ array *c=new array(N);
+ for(size_t i=0; i < N; ++i) {
+ array *ci=new array(N);
+ (*c)[i]=ci;
+ for(size_t j=0; j < N; ++j)
+ (*ci)[j]=0.0;
+ (*ci)[i]=1.0;
+ }
+ return c;
+}
+}
+
+static const char *incommensurate="Incommensurate matrices";
+static const char *singular="Singular matrix";
+static const char *invalidarraylength="Invalid array length: ";
+static size_t *pivot,*Row,*Col;
+
+bound_double *bounddouble(int N)
+{
+ if(N == 16) return bound;
+ if(N == 10) return boundtri;
+ ostringstream buf;
+ buf << invalidarraylength << " " << N;
+ error(buf);
+ return NULL;
+}
+
+bound_triple *boundtriple(int N)
+{
+ if(N == 16) return bound;
+ if(N == 10) return boundtri;
+ ostringstream buf;
+ buf << invalidarraylength << " " << N;
+ error(buf);
+ return NULL;
+}
+
+static inline void inverseAllocate(size_t n)
+{
+ pivot=new size_t[n];
+ Row=new size_t[n];
+ Col=new size_t[n];
+}
+
+static inline void inverseDeallocate()
+{
+ delete[] pivot;
+ delete[] Row;
+ delete[] Col;
+}
+
+namespace run {
+
+array *copyArray(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=(*a)[i];
+ return c;
+}
+
+array *copyArray2(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=(*ai)[j];
+ }
+ return c;
+}
+
+double *copyTripleArray2Components(array *a, size_t &N, GCPlacement placement)
+{
+ size_t n=checkArray(a);
+ N=0;
+ for(size_t i=0; i < n; i++)
+ N += checkArray(read<array*>(a,i));
+
+ double *A=(placement == NoGC) ? new double [3*N] :
+ new(placement) double[3*N];
+ double *p=A;
+
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; j++) {
+ triple v=read<triple>(ai,j);
+ *p=v.getx();
+ *(p+N)=v.gety();
+ *(p+2*N)=v.getz();
+ ++p;
+ }
+ }
+ return A;
+}
+
+triple *copyTripleArray2C(array *a, size_t &N, GCPlacement placement)
+{
+ size_t n=checkArray(a);
+ N=0;
+ for(size_t i=0; i < n; i++)
+ N += checkArray(read<array*>(a,i));
+
+ triple *A=(placement == NoGC) ? new triple [N] :
+ new(placement) triple[N];
+ triple *p=A;
+
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; j++)
+ *(p++)=read<triple>(ai,j);
+ }
+ return A;
+}
+
+triple operator *(const array& t, const triple& v)
+{
+ size_t n=checkArray(&t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t2=read<array*>(t,2);
+ array *t3=read<array*>(t,3);
+
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 ||
+ checkArray(t2) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+
+ double f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) run::dividebyzero();
+ f=1.0/f;
+
+ return triple((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f,
+ (read<real>(t2,0)*x+read<real>(t2,1)*y+read<real>(t2,2)*z+
+ read<real>(t2,3))*f);
+}
+
+template<class T>
+array *mult(array *a, array *b)
+{
+ size_t n=checkArray(a);
+
+ size_t nb=checkArray(b);
+ size_t na0=n == 0 ? 0 : checkArray(read<array*>(a,0));
+ if(na0 != nb)
+ error(incommensurate);
+
+ size_t nb0=nb == 0 ? 0 : checkArray(read<array*>(b,0));
+
+ array *c=new array(n);
+
+ T *A,*B;
+ copyArray2C(A,a,false);
+ copyArray2C(B,b,false);
+
+ for(size_t i=0; i < n; ++i) {
+ T *Ai=A+i*nb;
+ array *ci=new array(nb0);
+ (*c)[i]=ci;
+ for(size_t j=0; j < nb0; ++j) {
+ T sum=T();
+ size_t kj=j;
+ for(size_t k=0; k < nb; ++k, kj += nb0)
+ sum += Ai[k]*B[kj];
+ (*ci)[j]=sum;
+ }
+ }
+
+ delete[] B;
+ delete[] A;
+
+ return c;
+}
+
+// Compute transpose(A)*A where A is an n x m matrix.
+template<class T>
+array *AtA(array *a)
+{
+ size_t n=checkArray(a);
+ size_t m=n == 0 ? 0 : checkArray(read<array*>(a,0));
+
+ array *c=new array(m);
+
+ T *A;
+ copyArray2C(A,a,false);
+
+ for(size_t i=0; i < m; ++i) {
+ array *ci=new array(m);
+ (*c)[i]=ci;
+ for(size_t j=0; j < m; ++j) {
+ T sum=T();
+ size_t kj=j;
+ size_t ki=i;
+ for(size_t k=0; k < n; ++k, kj += m, ki += m)
+ sum += A[ki]*A[kj];
+ (*ci)[j]=sum;
+ }
+ }
+
+ delete[] A;
+ return c;
+}
+
+double norm(double *a, size_t n)
+{
+ if(n == 0) return 0.0;
+ double M=fabs(a[0]);
+ for(size_t i=1; i < n; ++i)
+ M=::max(M,fabs(a[i]));
+ return M;
+}
+
+double norm(triple *a, size_t n)
+{
+ if(n == 0) return 0.0;
+ double M=a[0].abs2();
+ for(size_t i=1; i < n; ++i)
+ M=::max(M,a[i].abs2());
+ return sqrt(M);
+}
+
+// Transpose an n x n matrix in place.
+void transpose(double *a, size_t n)
+{
+ for(size_t i=1; i < n; i++) {
+ for(size_t j=0; j < i; j++) {
+ size_t ij=n*i+j;
+ size_t ji=n*j+i;
+ double temp=a[ij];
+ a[ij]=a[ji];
+ a[ji]=temp;
+ }
+ }
+}
+
+// Invert an n x n array in place.
+void inverse(double *a, size_t n)
+{
+ inverseAllocate(n);
+
+ for(size_t i=0; i < n; i++)
+ pivot[i]=0;
+
+ size_t col=0, row=0;
+ // This is the main loop over the columns to be reduced.
+ for(size_t i=0; i < n; i++) {
+ real big=0.0;
+ // This is the outer loop of the search for a pivot element.
+ for(size_t j=0; j < n; j++) {
+ double *aj=a+n*j;
+ if(pivot[j] != 1) {
+ for(size_t k=0; k < n; k++) {
+ if(pivot[k] == 0) {
+ real temp=fabs(aj[k]);
+ if(temp >= big) {
+ big=temp;
+ row=j;
+ col=k;
+ }
+ } else if(pivot[k] > 1) {
+ inverseDeallocate();
+ error(singular);
+ }
+ }
+ }
+ }
+ ++(pivot[col]);
+
+ // Interchange rows, if needed, to put the pivot element on the diagonal.
+ double *acol=a+n*col;
+ if(row != col) {
+ double *arow=a+n*row;
+ for(size_t k=0; k < n; k++) {
+ real temp=arow[k];
+ arow[k]=acol[k];
+ acol[k]=temp;
+ }
+ }
+
+ Row[i]=row;
+ Col[i]=col;
+
+ // Divide the pivot row by the pivot element.
+ real denom=acol[col];
+ if(denom == 0.0) {
+ inverseDeallocate();
+ error(singular);
+ }
+ real pivinv=1.0/denom;
+ acol[col]=1.0;
+ for(size_t k=0; k < n; k++)
+ acol[k]=acol[k]*pivinv;
+
+ // Reduce all rows except for the pivoted one.
+ for(size_t k=0; k < n; k++) {
+ if(k != col) {
+ double *ak=a+n*k;
+ real akcol=ak[col];
+ ak[col]=0.0;
+ for(size_t j=0; j < n; j++)
+ ak[j] -= acol[j]*akcol;
+ }
+ }
+ }
+
+ // Unscramble the inverse matrix in view of the column interchanges.
+ for(size_t k=n; k > 0;) {
+ k--;
+ size_t r=Row[k];
+ size_t c=Col[k];
+ if(r != c) {
+ for(size_t j=0; j < n; j++) {
+ double *aj=a+n*j;
+ real temp=aj[r];
+ aj[r]=aj[c];
+ aj[c]=temp;
+ }
+ }
+ }
+ inverseDeallocate();
+}
+}
+
+callable *Func;
+stack *FuncStack;
+double wrapFunction(double x)
+{
+ FuncStack->push(x);
+ Func->call(FuncStack);
+ return pop<double>(FuncStack);
+}
+
+callable *compareFunc;
+bool compareFunction(const vm::item& i, const vm::item& j)
+{
+ FuncStack->push(i);
+ FuncStack->push(j);
+ compareFunc->call(FuncStack);
+ return pop<bool>(FuncStack);
+}
+
+// Crout's algorithm for computing the LU decomposition of a square matrix.
+// cf. routine ludcmp (Press et al., Numerical Recipes, 1991).
+Int LUdecompose(double *a, size_t n, size_t* index, bool warn=true)
+{
+ double *vv=new double[n];
+ Int swap=1;
+ for(size_t i=0; i < n; ++i) {
+ double big=0.0;
+ double *ai=a+i*n;
+ for(size_t j=0; j < n; ++j) {
+ double temp=fabs(ai[j]);
+ if(temp > big) big=temp;
+ }
+ if(big == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ vv[i]=1.0/big;
+ }
+ for(size_t j=0; j < n; ++j) {
+ for(size_t i=0; i < j; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < i; ++k) {
+ sum -= ai[k]*a[k*n+j];
+ }
+ ai[j]=sum;
+ }
+ double big=0.0;
+ size_t imax=j;
+ for(size_t i=j; i < n; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < j; ++k)
+ sum -= ai[k]*a[k*n+j];
+ ai[j]=sum;
+ double temp=vv[i]*fabs(sum);
+ if(temp >= big) {
+ big=temp;
+ imax=i;
+ }
+ }
+ double *aj=a+j*n;
+ double *aimax=a+imax*n;
+ if(j != imax) {
+ for(size_t k=0; k < n; ++k) {
+ double temp=aimax[k];
+ aimax[k]=aj[k];
+ aj[k]=temp;
+ }
+ swap *= -1;
+ vv[imax]=vv[j];
+ }
+ if(index)
+ index[j]=imax;
+ if(j != n) {
+ double denom=aj[j];
+ if(denom == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ for(size_t i=j+1; i < n; ++i)
+ a[i*n+j] /= denom;
+ }
+ }
+ delete[] vv;
+ return swap;
+}
+
+namespace run {
+
+void dividebyzero(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Divide by zero";
+ error(buf);
+}
+
+void integeroverflow(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Integer overflow";
+ error(buf);
+}
+
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runarray.symbols.h"
+
+#endif
+namespace run {
+// Create an empty array.
+#line 550 "runarray.in"
+void emptyArray(stack *Stack)
+{
+#line 551 "runarray.in"
+ {Stack->push<array*>(new array(0)); return;}
+}
+
+// Create a new array (technically a vector).
+// This array will be multidimensional. First the number of dimensions
+// is popped off the stack, followed by each dimension in reverse order.
+// The array itself is technically a one dimensional array of one
+// dimension arrays and so on.
+#line 560 "runarray.in"
+void newDeepArray(stack *Stack)
+{
+ Int depth=vm::pop<Int>(Stack);
+#line 561 "runarray.in"
+ assert(depth > 0);
+
+ Int *dims = new Int[depth];
+
+ for (Int index = depth-1; index >= 0; index--) {
+ Int i=pop<Int>(Stack);
+ if(i < 0) error("cannot create a negative length array");
+ dims[index]=i;
+ }
+
+ array *a=deepArray(depth, dims);
+ delete[] dims;
+ {Stack->push<array*>(a); return;}
+}
+
+// Creates an array with elements already specified. First, the number
+// of elements is popped off the stack, followed by each element in
+// reverse order.
+#line 580 "runarray.in"
+void newInitializedArray(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 581 "runarray.in"
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ {Stack->push<array*>(a); return;}
+}
+
+// Similar to newInitializedArray, but after the n elements, append another
+// array to it.
+#line 594 "runarray.in"
+void newAppendedArray(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ array* tail=vm::pop<array*>(Stack);
+#line 595 "runarray.in"
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ copy(tail->begin(), tail->end(), back_inserter(*a));
+
+ {Stack->push<array*>(a); return;}
+}
+
+// Produce an array of n deep copies of value.
+// typeDepth is the true depth of the array determined at compile-time when the
+// operations for the array type are added. This typeDepth argument is
+// automatically pushed on the stack and is not visible to the user.
+#line 612 "runarray.in"
+void copyArrayValue(stack *Stack)
+{
+ Int typeDepth=vm::pop<Int>(Stack);
+ Int depth=vm::pop<Int>(Stack,Int_MAX);
+ item value=vm::pop(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 613 "runarray.in"
+ if(n < 0) error("cannot create a negative length array");
+ if(depth < 0) error("cannot copy to a negative depth");
+ if(depth > typeDepth) depth=typeDepth;
+ {Stack->push<array*>(new array((size_t) n, value, depth)); return;}
+}
+
+// Deep copy of array.
+// typeDepth is the true depth of the array determined at compile-time when the
+// operations for the array type are added. This typeDepth argument is
+// automatically pushed on the stack and is not visible to the user.
+#line 624 "runarray.in"
+void copyArray(stack *Stack)
+{
+ Int typeDepth=vm::pop<Int>(Stack);
+ Int depth=vm::pop<Int>(Stack,Int_MAX);
+ array * a=vm::pop<array *>(Stack);
+#line 625 "runarray.in"
+ if(depth < 0) error("cannot copy to a negative depth");
+ if(depth > typeDepth) depth=typeDepth;
+ {Stack->push<array*>(a->copyToDepth(depth)); return;}
+}
+
+// Read an element from an array. Checks for initialization & bounds.
+#line 632 "runarray.in"
+void arrayRead(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 633 "runarray.in"
+ item& i=arrayRead(a,n);
+ if (i.empty()) {
+ ostringstream buf;
+ buf << "read uninitialized value from array at index " << n;
+ error(buf);
+ }
+ {Stack->push(i); return;}
+}
+
+// Slice a substring from an array.
+#line 644 "runarray.in"
+void arraySliceRead(stack *Stack)
+{
+ Int right=vm::pop<Int>(Stack);
+ Int left=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 645 "runarray.in"
+ checkArray(a);
+ {Stack->push(a->slice(left, right)); return;}
+}
+
+// Slice a substring from an array. This implements the cases a[i:] and a[:]
+// where the endpoint is not given, and assumed to be the length of the array.
+#line 652 "runarray.in"
+void arraySliceReadToEnd(stack *Stack)
+{
+ Int left=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 653 "runarray.in"
+ size_t len=checkArray(a);
+ {Stack->push(a->slice(left, (Int)len)); return;}
+}
+
+// Read an element from an array of arrays. Check bounds and initialize
+// as necessary.
+#line 660 "runarray.in"
+void arrayArrayRead(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 661 "runarray.in"
+ item& i=arrayRead(a,n);
+ if (i.empty()) i=new array(0);
+ {Stack->push(i); return;}
+}
+
+// Write an element to an array. Increase size if necessary.
+// TODO: Add arrayWriteAndPop
+#line 669 "runarray.in"
+void arrayWrite(stack *Stack)
+{
+ item value=vm::pop(Stack);
+ Int n=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 670 "runarray.in"
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else {
+ if(cyclic) outOfBounds("writing cyclic",len,n);
+ if(n < 0) outOfBounds("writing",len,n);
+ if(len <= (size_t) n)
+ a->resize(n+1);
+ }
+ (*a)[n] = value;
+ {Stack->push(value); return;}
+}
+
+#line 684 "runarray.in"
+void arraySliceWrite(stack *Stack)
+{
+ array * src=vm::pop<array *>(Stack);
+ Int right=vm::pop<Int>(Stack);
+ Int left=vm::pop<Int>(Stack);
+ array * dest=vm::pop<array *>(Stack);
+#line 685 "runarray.in"
+ checkArray(src);
+ checkArray(dest);
+ dest->setSlice(left, right, src);
+ {Stack->push<array*>(src); return;}
+}
+
+#line 692 "runarray.in"
+void arraySliceWriteToEnd(stack *Stack)
+{
+ array * src=vm::pop<array *>(Stack);
+ Int left=vm::pop<Int>(Stack);
+ array * dest=vm::pop<array *>(Stack);
+#line 693 "runarray.in"
+ checkArray(src);
+ size_t len=checkArray(dest);
+ dest->setSlice(left, (Int) len, src);
+ {Stack->push<array*>(src); return;}
+}
+
+// Returns the length of an array.
+#line 701 "runarray.in"
+void arrayLength(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 702 "runarray.in"
+ {Stack->push<Int>((Int) checkArray(a)); return;}
+}
+
+// Returns an array of integers representing the keys of the array.
+#line 707 "runarray.in"
+void arrayKeys(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 708 "runarray.in"
+ size_t size=checkArray(a);
+
+ array *keys=new array();
+ for (size_t i=0; i<size; ++i) {
+ item& cell = (*a)[i];
+ if (!cell.empty())
+ keys->push((Int)i);
+ }
+
+ {Stack->push<array*>(keys); return;}
+}
+
+// Return the cyclic flag for an array.
+#line 722 "runarray.in"
+void arrayCyclicFlag(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 723 "runarray.in"
+ checkArray(a);
+ {Stack->push<bool>(a->cyclic()); return;}
+}
+
+#line 728 "runarray.in"
+void arraySetCyclicFlag(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ bool b=vm::pop<bool>(Stack);
+#line 729 "runarray.in"
+ checkArray(a);
+ a->cyclic(b);
+ {Stack->push<bool>(b); return;}
+}
+
+// Check to see if an array element is initialized.
+#line 736 "runarray.in"
+void arrayInitializedHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 737 "runarray.in"
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) {Stack->push<bool>(false); return;}
+ item&i=(*a)[(unsigned) n];
+ {Stack->push<bool>(!i.empty()); return;}
+}
+
+// Returns the initialize method for an array.
+#line 747 "runarray.in"
+void arrayInitialized(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 748 "runarray.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayInitializedHelper),a)); return;}
+}
+
+// The helper function for the cyclic method that sets the cyclic flag.
+#line 753 "runarray.in"
+void arrayCyclicHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ bool b=vm::pop<bool>(Stack);
+#line 754 "runarray.in"
+ checkArray(a);
+ a->cyclic(b);
+}
+
+// Set the cyclic flag for an array.
+#line 760 "runarray.in"
+void arrayCyclic(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 761 "runarray.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayCyclicHelper),a)); return;}
+}
+
+// The helper function for the push method that does the actual operation.
+#line 766 "runarray.in"
+void arrayPushHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ item x=vm::pop(Stack);
+#line 767 "runarray.in"
+ checkArray(a);
+ a->push(x);
+ {Stack->push(x); return;}
+}
+
+// Returns the push method for an array.
+#line 774 "runarray.in"
+void arrayPush(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 775 "runarray.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayPushHelper),a)); return;}
+}
+
+// The helper function for the append method that appends b to a.
+#line 780 "runarray.in"
+void arrayAppendHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ array * b=vm::pop<array *>(Stack);
+#line 781 "runarray.in"
+ checkArray(a);
+ size_t size=checkArray(b);
+ for(size_t i=0; i < size; i++)
+ a->push((*b)[i]);
+}
+
+// Returns the append method for an array.
+#line 789 "runarray.in"
+void arrayAppend(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 790 "runarray.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayAppendHelper),a)); return;}
+}
+
+// The helper function for the pop method.
+#line 795 "runarray.in"
+void arrayPopHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 796 "runarray.in"
+ size_t asize=checkArray(a);
+ if(asize == 0)
+ error("cannot pop element from empty array");
+ {Stack->push(a->pop()); return;}
+}
+
+// Returns the pop method for an array.
+#line 804 "runarray.in"
+void arrayPop(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 805 "runarray.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayPopHelper),a)); return;}
+}
+
+// The helper function for the insert method.
+#line 810 "runarray.in"
+void arrayInsertHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ array * x=vm::pop<array *>(Stack);
+ Int i=vm::pop<Int>(Stack);
+#line 811 "runarray.in"
+ size_t asize=checkArray(a);
+ checkArray(x);
+ if(a->cyclic() && asize > 0) i=imod(i,asize);
+ if(i < 0 || i > (Int) asize)
+ outOfBounds("inserting",asize,i);
+ (*a).insert((*a).begin()+i,(*x).begin(),(*x).end());
+}
+
+// Returns the insert method for an array.
+#line 821 "runarray.in"
+void arrayInsert(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 822 "runarray.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayInsertHelper),a)); return;}
+}
+
+// Returns the delete method for an array.
+#line 827 "runarray.in"
+void arrayDelete(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 828 "runarray.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayDeleteHelper),a)); return;}
+}
+
+#line 832 "runarray.in"
+void arrayAlias(stack *Stack)
+{
+ array * b=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 833 "runarray.in"
+ {Stack->push<bool>(a==b); return;}
+}
+
+// Return array formed by indexing array a with elements of integer array b
+#line 838 "runarray.in"
+void arrayIntArray(stack *Stack)
+{
+ array * b=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 839 "runarray.in"
+ size_t asize=checkArray(a);
+ size_t bsize=checkArray(b);
+ array *r=new array(bsize);
+ bool cyclic=a->cyclic();
+ for(size_t i=0; i < bsize; i++) {
+ Int index=read<Int>(b,i);
+ if(cyclic && asize > 0) index=imod(index,asize);
+ else
+ if(index < 0 || index >= (Int) asize)
+ outOfBounds("reading",asize,index);
+ (*r)[i]=(*a)[index];
+ }
+ {Stack->push<array*>(r); return;}
+}
+
+// returns the complement of the integer array a in {0,2,...,n-1},
+// so that b[complement(a,b.length)] yields the complement of b[a].
+#line 857 "runarray.in"
+// Intarray* complement(Intarray *a, Int n);
+void gen_runarray32(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ Intarray * a=vm::pop<Intarray *>(Stack);
+#line 858 "runarray.in"
+ size_t asize=checkArray(a);
+ array *r=new array(0);
+ bool *keep=new bool[n];
+ for(Int i=0; i < n; ++i) keep[i]=true;
+ for(size_t i=0; i < asize; ++i) {
+ Int j=read<Int>(a,i);
+ if(j >= 0 && j < n) keep[j]=false;
+ }
+ for(Int i=0; i < n; i++)
+ if(keep[i]) r->push(i);
+
+ delete[] keep;
+ {Stack->push<Intarray*>(r); return;}
+}
+
+// Generate the sequence {f(i) : i=0,1,...n-1} given a function f and integer n
+#line 875 "runarray.in"
+void arraySequence(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ callable * f=vm::pop<callable *>(Stack);
+#line 876 "runarray.in"
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ Stack->push(i);
+ f->call(Stack);
+ (*a)[i]=pop(Stack);
+ }
+ {Stack->push<Intarray*>(a); return;}
+}
+
+// Return the array {0,1,...n-1}
+#line 888 "runarray.in"
+// Intarray* sequence(Int n);
+void gen_runarray34(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 889 "runarray.in"
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ (*a)[i]=i;
+ }
+ {Stack->push<Intarray*>(a); return;}
+}
+
+// Apply a function to each element of an array
+#line 899 "runarray.in"
+void arrayFunction(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ callable * f=vm::pop<callable *>(Stack);
+#line 900 "runarray.in"
+ size_t size=checkArray(a);
+ array *b=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ Stack->push((*a)[i]);
+ f->call(Stack);
+ (*b)[i]=pop(Stack);
+ }
+ {Stack->push<array*>(b); return;}
+}
+
+#line 911 "runarray.in"
+void arraySort(stack *Stack)
+{
+ bool stable=vm::pop<bool>(Stack,true);
+ callable * less=vm::pop<callable *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 912 "runarray.in"
+ array *c=copyArray(a);
+ compareFunc=less;
+ FuncStack=Stack;
+ if(stable) stable_sort(c->begin(),c->end(),compareFunction);
+ else sort(c->begin(),c->end(),compareFunction);
+ {Stack->push<array*>(c); return;}
+}
+
+#line 921 "runarray.in"
+void arraySearch(stack *Stack)
+{
+ callable * less=vm::pop<callable *>(Stack);
+ item key=vm::pop(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 922 "runarray.in"
+ size_t size=a->size();
+ compareFunc=less;
+ FuncStack=Stack;
+ if(size == 0 || compareFunction(key,(*a)[0])) {Stack->push<Int>(-1); return;}
+ size_t u=size-1;
+ if(!compareFunction(key,(*a)[u])) {Stack->push<Int>(Intcast(u)); return;}
+ size_t l=0;
+
+ while (l < u) {
+ size_t i=(l+u)/2;
+ if(compareFunction(key,(*a)[i])) u=i;
+ else if(compareFunction(key,(*a)[i+1])) {Stack->push<Int>(Intcast(i)); return;}
+ else l=i+1;
+ }
+ {Stack->push<Int>(0); return;}
+}
+
+#line 940 "runarray.in"
+// bool all(boolarray *a);
+void gen_runarray38(stack *Stack)
+{
+ boolarray * a=vm::pop<boolarray *>(Stack);
+#line 941 "runarray.in"
+ size_t size=checkArray(a);
+ bool c=true;
+ for(size_t i=0; i < size; i++)
+ if(!get<bool>((*a)[i])) {c=false; break;}
+ {Stack->push<bool>(c); return;}
+}
+
+#line 949 "runarray.in"
+// boolarray* !(boolarray* a);
+void gen_runarray39(stack *Stack)
+{
+ boolarray* a=vm::pop<boolarray*>(Stack);
+#line 950 "runarray.in"
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=!read<bool>(a,i);
+ {Stack->push<boolarray*>(c); return;}
+}
+
+#line 958 "runarray.in"
+// Int sum(boolarray *a);
+void gen_runarray40(stack *Stack)
+{
+ boolarray * a=vm::pop<boolarray *>(Stack);
+#line 959 "runarray.in"
+ size_t size=checkArray(a);
+ Int sum=0;
+ for(size_t i=0; i < size; i++)
+ sum += read<bool>(a,i) ? 1 : 0;
+ {Stack->push<Int>(sum); return;}
+}
+
+#line 967 "runarray.in"
+void arrayConcat(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 968 "runarray.in"
+ // a is an array of arrays to be concatenated together.
+ // The signature is
+ // T[] concat(... T[][] a);
+
+ size_t numArgs=checkArray(a);
+ size_t resultSize=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ resultSize += checkArray(a->read<array *>(i));
+ }
+
+ array *result=new array(resultSize);
+
+ size_t ri=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ array *arg=a->read<array *>(i);
+ size_t size=checkArray(arg);
+
+ for (size_t j=0; j < size; ++j) {
+ (*result)[ri]=(*arg)[j];
+ ++ri;
+ }
+ }
+
+ {Stack->push<array*>(result); return;}
+}
+
+#line 995 "runarray.in"
+void array2Transpose(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 996 "runarray.in"
+ size_t asize=checkArray(a);
+ array *c=new array(0);
+ for(size_t i=0; i < asize; i++) {
+ size_t ip=i+1;
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ size_t csize=checkArray(c);
+ if(csize < aisize) {
+ c->resize(aisize);
+ for(size_t j=csize; j < aisize; j++) {
+ (*c)[j]=new array(ip);
+ }
+ }
+ for(size_t j=0; j < aisize; j++) {
+ array *cj=read<array*>(c,j);
+ if(checkArray(cj) < ip) cj->resize(ip);
+ (*cj)[i]=(*ai)[j];
+ }
+ }
+ {Stack->push<array*>(c); return;}
+}
+
+// a is a rectangular 3D array; perm is an Int array indicating the type of
+// permutation (021 or 120, etc; original is 012).
+// Transpose by sending respective members to the permutated locations:
+// return the array obtained by putting a[i][j][k] into position perm{ijk}.
+#line 1023 "runarray.in"
+void array3Transpose(stack *Stack)
+{
+ array * perm=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 1024 "runarray.in"
+ const size_t DIM=3;
+
+ if(checkArray(perm) != DIM) {
+ ostringstream buf;
+ buf << "permutation array must have length " << DIM;
+ error(buf);
+ }
+
+ size_t* size=new size_t[DIM];
+ for(size_t i=0; i < DIM; ++i) size[i]=DIM;
+
+ for(size_t i=0; i < DIM; ++i) {
+ Int p=read<Int>(perm,i);
+ size_t P=(size_t) p;
+ if(p < 0 || P >= DIM) {
+ ostringstream buf;
+ buf << "permutation index out of range: " << p;
+ error(buf);
+ }
+ size[P]=P;
+ }
+
+ for(size_t i=0; i < DIM; ++i)
+ if(size[i] == DIM) error("permutation indices must be distinct");
+
+ static const char *rectangular=
+ "3D transpose implemented for rectangular matrices only";
+
+ size_t isize=size[0]=checkArray(a);
+ array *a0=read<array*>(a,0);
+ size[1]=checkArray(a0);
+ array *a00=read<array*>(a0,0);
+ size[2]=checkArray(a00);
+ for(size_t i=0; i < isize; i++) {
+ array *ai=read<array*>(a,i);
+ size_t jsize=checkArray(ai);
+ if(jsize != size[1]) error(rectangular);
+ for(size_t j=0; j < jsize; j++) {
+ array *aij=read<array*>(ai,j);
+ if(checkArray(aij) != size[2]) error(rectangular);
+ }
+ }
+
+ size_t perm0=(size_t) read<Int>(perm,0);
+ size_t perm1=(size_t) read<Int>(perm,1);
+ size_t perm2=(size_t) read<Int>(perm,2);
+
+ size_t sizep0=size[perm0];
+ size_t sizep1=size[perm1];
+ size_t sizep2=size[perm2];
+
+ array *c=new array(sizep0);
+ for(size_t i=0; i < sizep0; ++i) {
+ array *ci=new array(sizep1);
+ (*c)[i]=ci;
+ for(size_t j=0; j < sizep1; ++j) {
+ array *cij=new array(sizep2);
+ (*ci)[j]=cij;
+ }
+ }
+
+ size_t* i=new size_t[DIM];
+
+ for(i[0]=0; i[0] < size[0]; ++i[0]) {
+ array *a0=read<array*>(a,i[0]);
+ for(i[1]=0; i[1] < size[1]; ++i[1]) {
+ array *a1=read<array*>(a0,i[1]);
+ for(i[2]=0; i[2] < size[2]; ++i[2]) {
+ array *c0=read<array*>(c,i[perm0]);
+ array *c1=read<array*>(c0,i[perm1]);
+ (*c1)[i[perm2]]=read<real>(a1,i[2]);
+ }
+ }
+ }
+
+ delete[] i;
+ delete[] size;
+
+ {Stack->push<array*>(c); return;}
+}
+
+// Find the index of the nth true value in a boolean array or -1 if not found.
+// If n is negative, search backwards.
+#line 1108 "runarray.in"
+// Int find(boolarray *a, Int n=1);
+void gen_runarray44(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,1);
+ boolarray * a=vm::pop<boolarray *>(Stack);
+#line 1109 "runarray.in"
+ size_t size=checkArray(a);
+ Int j=-1;
+ if(n > 0)
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) {
+ n--; if(n == 0) {j=(Int) i; break;}
+ }
+ if(n < 0)
+ for(size_t i=size; i > 0;)
+ if(read<bool>(a,--i)) {
+ n++; if(n == 0) {j=(Int) i; break;}
+ }
+ {Stack->push<Int>(j); return;}
+}
+
+// Find all indices of true values in a boolean array.
+#line 1126 "runarray.in"
+// Intarray* findall(boolarray *a);
+void gen_runarray45(stack *Stack)
+{
+ boolarray * a=vm::pop<boolarray *>(Stack);
+#line 1127 "runarray.in"
+ size_t size=checkArray(a);
+ array *b=new array(0);
+ for(size_t i=0; i < size; i++) {
+ if(read<bool>(a,i)) {
+ b->push((Int) i);
+ }
+ }
+ {Stack->push<Intarray*>(b); return;}
+}
+
+// construct vector obtained by replacing those elements of b for which the
+// corresponding elements of a are false by the corresponding element of c.
+#line 1140 "runarray.in"
+void arrayConditional(stack *Stack)
+{
+ array * c=vm::pop<array *>(Stack);
+ array * b=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 1141 "runarray.in"
+ size_t size=checkArray(a);
+ array *r=new array(size);
+ if(b && c) {
+ checkArrays(a,b);
+ checkArrays(b,c);
+ for(size_t i=0; i < size; i++)
+ (*r)[i]=read<bool>(a,i) ? (*b)[i] : (*c)[i];
+ } else {
+ r->clear();
+ if(b) {
+ checkArrays(a,b);
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) r->push((*b)[i]);
+ } else if(c) {
+ checkArrays(a,c);
+ for(size_t i=0; i < size; i++)
+ if(!read<bool>(a,i)) r->push((*c)[i]);
+ }
+ }
+ {Stack->push<array*>(r); return;}
+}
+
+// Return an n x n identity matrix.
+#line 1165 "runarray.in"
+// realarray2* identity(Int n);
+void gen_runarray47(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 1166 "runarray.in"
+ {Stack->push<realarray2*>(Identity(n)); return;}
+}
+
+// Return the inverse of an n x n matrix a using Gauss-Jordan elimination.
+#line 1171 "runarray.in"
+// realarray2* inverse(realarray2 *a);
+void gen_runarray48(stack *Stack)
+{
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1172 "runarray.in"
+ size_t n=checkArray(a);
+ double *A;
+ copyArray2C(A,a,true,0,NoGC);
+ inverse(A,n);
+ a=copyCArray2(n,n,A);
+ delete[] A;
+ {Stack->push<realarray2*>(a); return;}
+}
+
+// Solve the linear equation ax=b by LU decomposition, returning the
+// solution x, where a is an n x n matrix and b is an array of length n.
+// If no solution exists, return an empty array.
+#line 1185 "runarray.in"
+// realarray* solve(realarray2 *a, realarray *b, bool warn=true);
+void gen_runarray49(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1186 "runarray.in"
+ size_t n=checkArray(a);
+
+ if(n == 0) {Stack->push<realarray*>(new array(0)); return;}
+
+ size_t m=checkArray(b);
+ if(m != n) error(incommensurate);
+
+ real *A;
+ copyArray2C(A,a);
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ {Stack->push<realarray*>(new array(0)); return;}
+
+ array *x=new array(n);
+
+ real *B;
+ copyArrayC(B,b);
+
+ for(size_t i=0; i < n; ++i) {
+ size_t ip=index[i];
+ real sum=B[ip];
+ B[ip]=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=0; j < i; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum;
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real sum=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=i+1; j < n; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum/Ai[i];
+ }
+
+ for(size_t i=0; i < n; ++i)
+ (*x)[i]=B[i];
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ {Stack->push<realarray*>(x); return;}
+}
+
+// Solve the linear equation ax=b by LU decomposition, returning the
+// solution x, where a is an n x n matrix and b is an n x m matrix.
+// If no solution exists, return an empty array.
+#line 1238 "runarray.in"
+// realarray2* solve(realarray2 *a, realarray2 *b, bool warn=true);
+void gen_runarray50(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ realarray2 * b=vm::pop<realarray2 *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1239 "runarray.in"
+ size_t n=checkArray(a);
+
+ if(n == 0) {Stack->push<realarray2*>(new array(0)); return;}
+
+ if(checkArray(b) != n) error(incommensurate);
+ size_t m=checkArray(read<array*>(b,0));
+
+ real *A,*B;
+ copyArray2C(A,a);
+ copyArray2C(B,b,false);
+
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ {Stack->push<realarray2*>(new array(0)); return;}
+
+ array *x=new array(n);
+
+ for(size_t i=0; i < n; ++i) {
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ real *Bip=B+index[i]*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bip[k];
+ Bip[k]=Bi[k];
+ size_t jk=k;
+ for(size_t j=0; j < i; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum;
+ }
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bi[k];
+ size_t jk=(i+1)*m+k;
+ for(size_t j=i+1; j < n; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum/Ai[i];
+ }
+ }
+
+ for(size_t i=0; i < n; ++i) {
+ real *Bi=B+i*m;
+ array *xi=new array(m);
+ (*x)[i]=xi;
+ for(size_t j=0; j < m; ++j)
+ (*xi)[j]=Bi[j];
+ }
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ {Stack->push<realarray2*>(x); return;}
+}
+
+// Compute the determinant of an n x n matrix.
+#line 1301 "runarray.in"
+// real determinant(realarray2 *a);
+void gen_runarray51(stack *Stack)
+{
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1302 "runarray.in"
+ real *A;
+ copyArray2C(A,a);
+ size_t n=checkArray(a);
+
+ real det=LUdecompose(A,n,NULL,false);
+ size_t n1=n+1;
+ for(size_t i=0; i < n; ++i)
+ det *= A[i*n1];
+
+ delete[] A;
+
+ {Stack->push<real>(det); return;}
+}
+
+#line 1317 "runarray.in"
+// realarray* *(realarray2 *a, realarray *b);
+void gen_runarray52(stack *Stack)
+{
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1318 "runarray.in"
+ size_t n=checkArray(a);
+ size_t m=checkArray(b);
+ array *c=new array(n);
+ real *B;
+ copyArrayC(B,b);
+ for(size_t i=0; i < n; ++i) {
+ array *ai=read<array*>(a,i);
+ if(checkArray(ai) != m) error(incommensurate);
+ real sum=0.0;
+ for(size_t j=0; j < m; ++j)
+ sum += read<real>(ai,j)*B[j];
+ (*c)[i]=sum;
+ }
+ delete[] B;
+ {Stack->push<realarray*>(c); return;}
+}
+
+#line 1336 "runarray.in"
+// realarray* *(realarray *a, realarray2 *b);
+void gen_runarray53(stack *Stack)
+{
+ realarray2 * b=vm::pop<realarray2 *>(Stack);
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 1337 "runarray.in"
+ size_t n=checkArray(a);
+ if(n != checkArray(b)) error(incommensurate);
+ real *A;
+ copyArrayC(A,a);
+
+ array **B=new array*[n];
+ array *bk=read<array *>(b,0);
+ B[0]=bk;
+ size_t m=bk->size();
+ for(size_t k=1; k < n; k++) {
+ array *bk=read<array *>(b,k);
+ if(bk->size() != m) error(incommensurate);
+ B[k]=bk;
+ }
+ array *c=new array(m);
+
+ for(size_t i=0; i < m; ++i) {
+ real sum=0.0;
+ for(size_t k=0; k < n; ++k)
+ sum += A[k]*read<real>(B[k],i);
+ (*c)[i]=sum;
+ }
+ delete[] B;
+ delete[] A;
+ {Stack->push<realarray*>(c); return;}
+}
+
+#line 1365 "runarray.in"
+// Intarray2* *(Intarray2 *a, Intarray2 *b);
+void gen_runarray54(stack *Stack)
+{
+ Intarray2 * b=vm::pop<Intarray2 *>(Stack);
+ Intarray2 * a=vm::pop<Intarray2 *>(Stack);
+#line 1366 "runarray.in"
+ {Stack->push<Intarray2*>(mult<Int>(a,b)); return;}
+}
+
+#line 1370 "runarray.in"
+// realarray2* *(realarray2 *a, realarray2 *b);
+void gen_runarray55(stack *Stack)
+{
+ realarray2 * b=vm::pop<realarray2 *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1371 "runarray.in"
+ {Stack->push<realarray2*>(mult<real>(a,b)); return;}
+}
+
+#line 1375 "runarray.in"
+// pairarray2* *(pairarray2 *a, pairarray2 *b);
+void gen_runarray56(stack *Stack)
+{
+ pairarray2 * b=vm::pop<pairarray2 *>(Stack);
+ pairarray2 * a=vm::pop<pairarray2 *>(Stack);
+#line 1376 "runarray.in"
+ {Stack->push<pairarray2*>(mult<pair>(a,b)); return;}
+}
+
+#line 1380 "runarray.in"
+// triple *(realarray2 *t, triple v);
+void gen_runarray57(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+#line 1381 "runarray.in"
+ {Stack->push<triple>(*t*v); return;}
+}
+
+#line 1385 "runarray.in"
+// realarray2* AtA(realarray2 *a);
+void gen_runarray58(stack *Stack)
+{
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1386 "runarray.in"
+ {Stack->push<realarray2*>(AtA<real>(a)); return;}
+}
+
+#line 1390 "runarray.in"
+// pair project(triple v, realarray2 *t);
+void gen_runarray59(stack *Stack)
+{
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 1391 "runarray.in"
+ size_t n=checkArray(t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t3=read<array*>(t,3);
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ real x=v.getx();
+ real y=v.gety();
+ real z=v.getz();
+
+ real f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) dividebyzero();
+ f=1.0/f;
+
+ {Stack->push<pair>(pair((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f)); return;}
+}
+
+// Compute the dot product of vectors a and b.
+#line 1416 "runarray.in"
+// real dot(realarray *a, realarray *b);
+void gen_runarray60(stack *Stack)
+{
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 1417 "runarray.in"
+ size_t n=checkArrays(a,b);
+ real sum=0.0;
+ for(size_t i=0; i < n; ++i)
+ sum += read<real>(a,i)*read<real>(b,i);
+ {Stack->push<real>(sum); return;}
+}
+
+// Compute the complex dot product of vectors a and b.
+#line 1426 "runarray.in"
+// pair dot(pairarray *a, pairarray *b);
+void gen_runarray61(stack *Stack)
+{
+ pairarray * b=vm::pop<pairarray *>(Stack);
+ pairarray * a=vm::pop<pairarray *>(Stack);
+#line 1427 "runarray.in"
+ size_t n=checkArrays(a,b);
+ pair sum=zero;
+ for(size_t i=0; i < n; ++i)
+ sum += read<pair>(a,i)*conj(read<pair>(b,i));
+ {Stack->push<pair>(sum); return;}
+}
+
+// Solve the problem L\inv f, where f is an n vector and L is the n x n matrix
+//
+// [ b[0] c[0] a[0] ]
+// [ a[1] b[1] c[1] ]
+// [ a[2] b[2] c[2] ]
+// [ ... ]
+// [ c[n-1] a[n-1] b[n-1] ]
+#line 1442 "runarray.in"
+// realarray* tridiagonal(realarray *a, realarray *b, realarray *c, realarray *f);
+void gen_runarray62(stack *Stack)
+{
+ realarray * f=vm::pop<realarray *>(Stack);
+ realarray * c=vm::pop<realarray *>(Stack);
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 1443 "runarray.in"
+ size_t n=checkArrays(a,b);
+ checkEqual(n,checkArray(c));
+ checkEqual(n,checkArray(f));
+
+ array *up=new array(n);
+ array& u=*up;
+
+ if(n == 0) {Stack->push<realarray*>(up); return;}
+
+ // Special case: zero Dirichlet boundary conditions
+ if(read<real>(a,0) == 0.0 && read<real>(c,n-1) == 0.0) {
+ real temp=read<real>(b,0);
+ if(temp == 0.0) dividebyzero();
+ temp=1.0/temp;
+
+ real *work=new real[n];
+ u[0]=read<real>(f,0)*temp;
+ work[0]=-read<real>(c,0)*temp;
+
+ for(size_t i=1; i < n; i++) {
+ real temp=(read<real>(b,i)+read<real>(a,i)*work[i-1]);
+ if(temp == 0.0) {delete[] work; dividebyzero();}
+ temp=1.0/temp;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*temp;
+ work[i]=-read<real>(c,i)*temp;
+ }
+
+ for(size_t i=n-1; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)+work[i-1]*read<real>(u,i);
+
+ delete[] work;
+ {Stack->push<realarray*>(up); return;}
+ }
+
+ real binv=read<real>(b,0);
+ if(binv == 0.0) dividebyzero();
+ binv=1.0/binv;
+
+ if(n == 1) {u[0]=read<real>(f,0)*binv; {Stack->push<realarray*>(up); return;}}
+ if(n == 2) {
+ real factor=(read<real>(b,0)*read<real>(b,1)-
+ read<real>(a,0)*read<real>(c,1));
+ if(factor== 0.0) dividebyzero();
+ factor=1.0/factor;
+ real temp=(read<real>(b,0)*read<real>(f,1)-
+ read<real>(c,1)*read<real>(f,0))*factor;
+ u[0]=(read<real>(b,1)*read<real>(f,0)-
+ read<real>(a,0)*read<real>(f,1))*factor;
+ u[1]=temp;
+ {Stack->push<realarray*>(up); return;}
+ }
+
+ real *gamma=new real[n-2];
+ real *delta=new real[n-2];
+
+ gamma[0]=read<real>(c,0)*binv;
+ delta[0]=read<real>(a,0)*binv;
+ u[0]=read<real>(f,0)*binv;
+ real beta=read<real>(c,n-1);
+ real fn=read<real>(f,n-1)-beta*read<real>(u,0);
+ real alpha=read<real>(b,n-1)-beta*delta[0];
+
+ for(size_t i=1; i <= n-3; i++) {
+ real alphainv=read<real>(b,i)-read<real>(a,i)*gamma[i-1];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ beta *= -gamma[i-1];
+ gamma[i]=read<real>(c,i)*alphainv;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*alphainv;
+ fn -= beta*read<real>(u,i);
+ delta[i]=-read<real>(a,i)*delta[i-1]*alphainv;
+ alpha -= beta*delta[i];
+ }
+
+ real alphainv=read<real>(b,n-2)-read<real>(a,n-2)*gamma[n-3];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ u[n-2]=(read<real>(f,n-2)-read<real>(a,n-2)*read<real>(u,n-3))
+ *alphainv;
+ beta=read<real>(a,n-1)-beta*gamma[n-3];
+ real dnm1=(read<real>(c,n-2)-read<real>(a,n-2)*delta[n-3])*alphainv;
+ real temp=alpha-beta*dnm1;
+ if(temp == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ u[n-1]=temp=(fn-beta*read<real>(u,n-2))/temp;
+ u[n-2]=read<real>(u,n-2)-dnm1*temp;
+
+ for(size_t i=n-2; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)-gamma[i-1]*read<real>(u,i)-delta[i-1]*temp;
+
+ delete[] delta;
+ delete[] gamma;
+
+ {Stack->push<realarray*>(up); return;}
+}
+
+// Root solve by Newton-Raphson
+#line 1540 "runarray.in"
+// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x, bool verbose=false);
+void gen_runarray63(stack *Stack)
+{
+ bool verbose=vm::pop<bool>(Stack,false);
+ real x=vm::pop<real>(Stack);
+ callableReal * fprime=vm::pop<callableReal *>(Stack);
+ callableReal * f=vm::pop<callableReal *>(Stack);
+ Int iterations=vm::pop<Int>(Stack,100);
+#line 1542 "runarray.in"
+ static const real fuzz=1000.0*DBL_EPSILON;
+ Int i=0;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ real diff=DBL_MAX;
+ real lastdiff;
+ do {
+ real x0=x;
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dfdx=pop<real>(Stack);
+
+ if(dfdx == 0.0) {
+ x=DBL_MAX;
+ break;
+ }
+
+ Stack->push(x);
+ f->call(Stack);
+ real fx=pop<real>(Stack);
+
+ x -= fx/dfdx;
+
+ lastdiff=diff;
+
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+
+ diff=fabs(x-x0);
+ if(++i == iterations) {
+ x=DBL_MAX;
+ break;
+ }
+ } while (diff != 0.0 && (diff < lastdiff || diff > fuzz*fabs(x)));
+
+ if(verbose)
+ cout.precision(oldPrec);
+ {Stack->push<real>(x); return;}
+}
+
+// Root solve by Newton-Raphson bisection
+// cf. routine rtsafe (Press et al., Numerical Recipes, 1991).
+#line 1588 "runarray.in"
+// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x1, real x2, bool verbose=false);
+void gen_runarray64(stack *Stack)
+{
+ bool verbose=vm::pop<bool>(Stack,false);
+ real x2=vm::pop<real>(Stack);
+ real x1=vm::pop<real>(Stack);
+ callableReal * fprime=vm::pop<callableReal *>(Stack);
+ callableReal * f=vm::pop<callableReal *>(Stack);
+ Int iterations=vm::pop<Int>(Stack,100);
+#line 1590 "runarray.in"
+ static const real fuzz=1000.0*DBL_EPSILON;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ Stack->push(x1);
+ f->call(Stack);
+ real f1=pop<real>(Stack);
+ if(f1 == 0.0) {Stack->push<real>(x1); return;}
+
+ Stack->push(x2);
+ f->call(Stack);
+ real f2=pop<real>(Stack);
+ if(f2 == 0.0) {Stack->push<real>(x2); return;}
+
+ if((f1 > 0.0 && f2 > 0.0) || (f1 < 0.0 && f2 < 0.0)) {
+ ostringstream buf;
+ buf << "root not bracketed, f(x1)=" << f1 << ", f(x2)=" << f2 << endl;
+ error(buf);
+ }
+
+ real x=0.5*(x1+x2);
+ real dxold=fabs(x2-x1);
+ if(f1 > 0.0) {
+ real temp=x1;
+ x1=x2;
+ x2=temp;
+ }
+
+ if(verbose)
+ cout << "midpoint: " << x << endl;
+
+ real dx=dxold;
+ Stack->push(x);
+ f->call(Stack);
+ real y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dy=pop<real>(Stack);
+
+ Int j;
+ for(j=0; j < iterations; j++) {
+ if(((x-x2)*dy-y)*((x-x1)*dy-y) >= 0.0 || fabs(2.0*y) > fabs(dxold*dy)) {
+ dxold=dx;
+ dx=0.5*(x2-x1);
+ x=x1+dx;
+ if(verbose)
+ cout << "bisection: " << x << endl;
+ if(x1 == x) {Stack->push<real>(x); return;}
+ } else {
+ dxold=dx;
+ dx=y/dy;
+ real temp=x;
+ x -= dx;
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+ if(temp == x) {Stack->push<real>(x); return;}
+ }
+ if(fabs(dx) < fuzz*fabs(x)) {Stack->push<real>(x); return;}
+
+ Stack->push(x);
+ f->call(Stack);
+ y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ dy=pop<real>(Stack);
+
+ if(y < 0.0) x1=x;
+ else x2=x;
+ }
+ if(verbose)
+ cout.precision(oldPrec);
+ {Stack->push<real>((j == iterations) ? DBL_MAX : x); return;}
+}
+
+// Find a root for the specified continuous (but not necessarily
+// differentiable) function. Whatever value t is returned, it is guaranteed
+// that t is within [a, b] and within tolerance of a sign change.
+// An error is thrown if fa and fb are both positive or both negative.
+//
+// In this implementation, the binary search is interleaved
+// with a modified version of quadratic interpolation.
+// This is a C++ port of the Asymptote routine written by Charles Staats III.
+#line 1676 "runarray.in"
+// real _findroot(callableReal *f, real a, real b, real tolerance, real fa, real fb);
+void gen_runarray65(stack *Stack)
+{
+ real fb=vm::pop<real>(Stack);
+ real fa=vm::pop<real>(Stack);
+ real tolerance=vm::pop<real>(Stack);
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+ callableReal * f=vm::pop<callableReal *>(Stack);
+#line 1678 "runarray.in"
+ if(fa == 0.0) {Stack->push<real>(a); return;}
+ if(fb == 0.0) {Stack->push<real>(b); return;}
+
+ const char* oppsign="fa and fb must have opposite signs";
+ int sign;
+
+ if(fa < 0.0) {
+ if(fb < 0.0) error(oppsign);
+ sign=1;
+ } else {
+ if(fb > 0.0) error(oppsign);
+ fa=-fa;
+ fb=-fb;
+ sign=-1;
+ }
+
+ real t=a;
+ real ft=fa;
+ real twicetolerance=2.0*tolerance;
+
+ while(b-a > tolerance) {
+ t=(a+b)*0.5;
+
+ Stack->push(t);
+ f->call(Stack);
+ ft=sign*pop<double>(Stack);
+ if(ft == 0.0) {Stack->push<real>(t); return;}
+
+ // If halving the interval already puts us within tolerance,
+ // don't bother with the interpolation step.
+ if(b-a >= twicetolerance) {
+
+ real factor=1.0/(b-a);
+ real q_A=2.0*(fa-2.0*ft+fb)*factor*factor;
+ real q_B=(fb-fa)*factor;
+ quadraticroots Q=quadraticroots(q_A,q_B,ft);
+
+ // If the interpolation somehow failed, continue on to the next binary
+ // search step. This may or may not be possible, depending on what
+ // theoretical guarantees are provided by the quadraticroots function.
+
+ real root;
+ bool found=Q.roots > 0;
+ if(found) {
+ root=t+Q.t1;
+ if(root <= a || root >= b) {
+ if(Q.roots == 1) found=false;
+ else {
+ root=t+Q.t2;
+ if(root <= a || root >= b) found=false;
+ }
+ }
+ }
+
+ if(found) {
+ if(ft > 0.0) {
+ b=t;
+ fb=ft;
+ } else {
+ a=t;
+ fa=ft;
+ }
+
+ t=root;
+
+ // If the interpolated value is close to one edge of
+ // the interval, move it farther away from the edge in
+ // an effort to catch the root in the middle.
+ real margin=(b-a)*1.0e-3;
+ if(t-a < margin) t=a+2.0*(t-a);
+ else if(b-t < margin) t=b-2.0*(b-t);
+
+ Stack->push(t);
+ f->call(Stack);
+ ft=sign*pop<double>(Stack);
+
+ if(ft == 0.0) {Stack->push<real>(t); return;}
+ }
+ }
+
+ if(ft > 0.0) {
+ b=t;
+ fb=ft;
+ } else if(ft < 0.0) {
+ a=t;
+ fa=ft;
+ }
+ }
+ {Stack->push<real>(a-(b-a)/(fb-fa)*fa); return;}
+}
+
+#line 1770 "runarray.in"
+// real simpson(callableReal *f, real a, real b, real acc=DBL_EPSILON, real dxmax=0);
+void gen_runarray66(stack *Stack)
+{
+ real dxmax=vm::pop<real>(Stack,0);
+ real acc=vm::pop<real>(Stack,DBL_EPSILON);
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+ callableReal * f=vm::pop<callableReal *>(Stack);
+#line 1772 "runarray.in"
+ real integral;
+ if(dxmax <= 0) dxmax=fabs(b-a);
+ callable *oldFunc=Func;
+ Func=f;
+ FuncStack=Stack;
+ if(!simpson(integral,wrapFunction,a,b,acc,dxmax))
+ error("nesting capacity exceeded in simpson");
+ Func=oldFunc;
+ {Stack->push<real>(integral); return;}
+}
+
+// Compute the fast Fourier transform of a pair array
+#line 1785 "runarray.in"
+// pairarray* fft(pairarray *a, Int sign=1);
+void gen_runarray67(stack *Stack)
+{
+ Int sign=vm::pop<Int>(Stack,1);
+ pairarray * a=vm::pop<pairarray *>(Stack);
+#line 1786 "runarray.in"
+#ifdef HAVE_LIBFFTW3
+ unsigned n=(unsigned) checkArray(a);
+ array *c=new array(n);
+ if(n) {
+ Complex *f=utils::ComplexAlign(n);
+ fftwpp::fft1d Forward(n,intcast(sign),f);
+
+ for(size_t i=0; i < n; i++) {
+ pair z=read<pair>(a,i);
+ f[i]=Complex(z.getx(),z.gety());
+ }
+ Forward.fft(f);
+
+ for(size_t i=0; i < n; i++) {
+ Complex z=f[i];
+ (*c)[i]=pair(z.real(),z.imag());
+ }
+ utils::deleteAlign(f);
+ }
+#else
+ unused(a);
+ unused(&sign);
+ array *c=new array(0);
+ error("Please install fftw3, run ./configure, and recompile");
+#endif // HAVE_LIBFFTW3
+ {Stack->push<pairarray*>(c); return;}
+}
+
+#line 1815 "runarray.in"
+// Intarray2* triangulate(pairarray *z);
+void gen_runarray68(stack *Stack)
+{
+ pairarray * z=vm::pop<pairarray *>(Stack);
+#line 1816 "runarray.in"
+ size_t nv=checkArray(z);
+// Call robust version of Gilles Dumoulin's port of Paul Bourke's
+// triangulation code.
+
+ XYZ *pxyz=new XYZ[nv+3];
+ ITRIANGLE *V=new ITRIANGLE[4*nv];
+
+ for(size_t i=0; i < nv; ++i) {
+ pair w=read<pair>(z,i);
+ pxyz[i].p[0]=w.getx();
+ pxyz[i].p[1]=w.gety();
+ pxyz[i].i=(Int) i;
+ }
+
+ Int ntri;
+ Triangulate((Int) nv,pxyz,V,ntri,true,false);
+
+ size_t nt=(size_t) ntri;
+ array *t=new array(nt);
+ for(size_t i=0; i < nt; ++i) {
+ array *ti=new array(3);
+ (*t)[i]=ti;
+ ITRIANGLE *Vi=V+i;
+ (*ti)[0]=pxyz[Vi->p1].i;
+ (*ti)[1]=pxyz[Vi->p2].i;
+ (*ti)[2]=pxyz[Vi->p3].i;
+ }
+
+ delete[] V;
+ delete[] pxyz;
+ {Stack->push<Intarray2*>(t); return;}
+}
+
+#line 1850 "runarray.in"
+// real norm(realarray *a);
+void gen_runarray69(stack *Stack)
+{
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 1851 "runarray.in"
+ size_t n=checkArray(a);
+ real M=0.0;
+ for(size_t i=0; i < n; ++i) {
+ real x=fabs(vm::read<real>(a,i));
+ if(x > M) M=x;
+ }
+ {Stack->push<real>(M); return;}
+}
+
+#line 1861 "runarray.in"
+// real norm(realarray2 *a);
+void gen_runarray70(stack *Stack)
+{
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 1862 "runarray.in"
+ size_t n=checkArray(a);
+ real M=0.0;
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=fabs(vm::read<real>(ai,j));
+ if(a > M) M=a;
+ }
+ }
+ {Stack->push<real>(M); return;}
+}
+
+#line 1876 "runarray.in"
+// real norm(triplearray2 *a);
+void gen_runarray71(stack *Stack)
+{
+ triplearray2 * a=vm::pop<triplearray2 *>(Stack);
+#line 1877 "runarray.in"
+ size_t n=checkArray(a);
+ real M=0.0;
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=vm::read<triple>(ai,j).abs2();
+ if(a > M) M=a;
+ }
+ }
+ {Stack->push<real>(sqrt(M)); return;}
+}
+
+#line 1891 "runarray.in"
+// real change2(triplearray2 *a);
+void gen_runarray72(stack *Stack)
+{
+ triplearray2 * a=vm::pop<triplearray2 *>(Stack);
+#line 1892 "runarray.in"
+ size_t n=checkArray(a);
+ if(n == 0) {Stack->push<real>(0.0); return;}
+
+ vm::array *a0=vm::read<vm::array*>(a,0);
+ size_t m=checkArray(a0);
+ if(m == 0) {Stack->push<real>(0.0); return;}
+ triple a00=vm::read<triple>(a0,0);
+ real M=0.0;
+
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=(vm::read<triple>(ai,j)-a00).abs2();
+ if(a > M) M=a;
+ }
+ }
+ {Stack->push<real>(M); return;}
+}
+
+#line 1913 "runarray.in"
+// triple minbezier(triplearray2 *P, triple b);
+void gen_runarray73(stack *Stack)
+{
+ triple b=vm::pop<triple>(Stack);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+#line 1914 "runarray.in"
+ size_t N;
+ real *A=copyTripleArray2Components(P,N);
+ bound_double *B=bounddouble(N);
+ b=triple(B(A,::min,b.getx(),Fuzz*norm(A,N),maxdepth),
+ B(A+N,::min,b.gety(),Fuzz*norm(A+N,N),maxdepth),
+ B(A+2*N,::min,b.getz(),Fuzz*norm(A+2*N,N),maxdepth));
+ delete[] A;
+ {Stack->push<triple>(b); return;}
+}
+
+#line 1925 "runarray.in"
+// triple maxbezier(triplearray2 *P, triple b);
+void gen_runarray74(stack *Stack)
+{
+ triple b=vm::pop<triple>(Stack);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+#line 1926 "runarray.in"
+ size_t N;
+ real *A=copyTripleArray2Components(P,N);
+ bound_double *B=bounddouble(N);
+ b=triple(B(A,::max,b.getx(),Fuzz*norm(A,N),maxdepth),
+ B(A+N,::max,b.gety(),Fuzz*norm(A+N,N),maxdepth),
+ B(A+2*N,::max,b.getz(),Fuzz*norm(A+2*N,N),maxdepth));
+ delete[] A;
+ {Stack->push<triple>(b); return;}
+}
+
+#line 1937 "runarray.in"
+// pair minratio(triplearray2 *P, pair b);
+void gen_runarray75(stack *Stack)
+{
+ pair b=vm::pop<pair>(Stack);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+#line 1938 "runarray.in"
+ size_t N;
+ triple *A=copyTripleArray2C(P,N);
+ real fuzz=Fuzz*norm(A,N);
+ bound_triple *B=boundtriple(N);
+ b=pair(B(A,::min,xratio,b.getx(),fuzz,maxdepth),
+ B(A,::min,yratio,b.gety(),fuzz,maxdepth));
+ delete[] A;
+ {Stack->push<pair>(b); return;}
+}
+
+#line 1949 "runarray.in"
+// pair maxratio(triplearray2 *P, pair b);
+void gen_runarray76(stack *Stack)
+{
+ pair b=vm::pop<pair>(Stack);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+#line 1950 "runarray.in"
+ size_t N;
+ triple *A=copyTripleArray2C(P,N);
+ bound_triple *B=boundtriple(N);
+ real fuzz=Fuzz*norm(A,N);
+ b=pair(B(A,::max,xratio,b.getx(),fuzz,maxdepth),
+ B(A,::max,yratio,b.gety(),fuzz,maxdepth));
+ delete[] A;
+ {Stack->push<pair>(b); return;}
+}
+
+#line 1961 "runarray.in"
+// realarray* _projection();
+void gen_runarray77(stack *Stack)
+{
+#line 1962 "runarray.in"
+#ifdef HAVE_GL
+ array *a=new array(14);
+ gl::projection P=gl::camera();
+ size_t k=0;
+ (*a)[k++]=P.orthographic ? 1.0 : 0.0;
+
+ triple camera=P.camera;
+ (*a)[k++]=camera.getx();
+ (*a)[k++]=camera.gety();
+ (*a)[k++]=camera.getz();
+
+ triple up=P.up;
+ (*a)[k++]=up.getx();
+ (*a)[k++]=up.gety();
+ (*a)[k++]=up.getz();
+
+ triple target=P.target;
+ (*a)[k++]=target.getx();
+ (*a)[k++]=target.gety();
+ (*a)[k++]=target.getz();
+
+ (*a)[k++]=P.zoom;
+ (*a)[k++]=P.angle;
+
+ (*a)[k++]=P.viewportshift.getx();
+ (*a)[k++]=P.viewportshift.gety();
+#endif
+ {Stack->push<realarray*>(new array(0)); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runarray_venv(venv &ve)
+{
+#line 549 "runarray.in"
+ REGISTER_BLTIN(run::emptyArray,"emptyArray");
+#line 555 "runarray.in"
+ REGISTER_BLTIN(run::newDeepArray,"newDeepArray");
+#line 577 "runarray.in"
+ REGISTER_BLTIN(run::newInitializedArray,"newInitializedArray");
+#line 592 "runarray.in"
+ REGISTER_BLTIN(run::newAppendedArray,"newAppendedArray");
+#line 608 "runarray.in"
+ REGISTER_BLTIN(run::copyArrayValue,"copyArrayValue");
+#line 620 "runarray.in"
+ REGISTER_BLTIN(run::copyArray,"copyArray");
+#line 631 "runarray.in"
+ REGISTER_BLTIN(run::arrayRead,"arrayRead");
+#line 643 "runarray.in"
+ REGISTER_BLTIN(run::arraySliceRead,"arraySliceRead");
+#line 650 "runarray.in"
+ REGISTER_BLTIN(run::arraySliceReadToEnd,"arraySliceReadToEnd");
+#line 658 "runarray.in"
+ REGISTER_BLTIN(run::arrayArrayRead,"arrayArrayRead");
+#line 667 "runarray.in"
+ REGISTER_BLTIN(run::arrayWrite,"arrayWrite");
+#line 684 "runarray.in"
+ REGISTER_BLTIN(run::arraySliceWrite,"arraySliceWrite");
+#line 692 "runarray.in"
+ REGISTER_BLTIN(run::arraySliceWriteToEnd,"arraySliceWriteToEnd");
+#line 700 "runarray.in"
+ REGISTER_BLTIN(run::arrayLength,"arrayLength");
+#line 706 "runarray.in"
+ REGISTER_BLTIN(run::arrayKeys,"arrayKeys");
+#line 721 "runarray.in"
+ REGISTER_BLTIN(run::arrayCyclicFlag,"arrayCyclicFlag");
+#line 728 "runarray.in"
+ REGISTER_BLTIN(run::arraySetCyclicFlag,"arraySetCyclicFlag");
+#line 735 "runarray.in"
+ REGISTER_BLTIN(run::arrayInitializedHelper,"arrayInitializedHelper");
+#line 746 "runarray.in"
+ REGISTER_BLTIN(run::arrayInitialized,"arrayInitialized");
+#line 752 "runarray.in"
+ REGISTER_BLTIN(run::arrayCyclicHelper,"arrayCyclicHelper");
+#line 759 "runarray.in"
+ REGISTER_BLTIN(run::arrayCyclic,"arrayCyclic");
+#line 765 "runarray.in"
+ REGISTER_BLTIN(run::arrayPushHelper,"arrayPushHelper");
+#line 773 "runarray.in"
+ REGISTER_BLTIN(run::arrayPush,"arrayPush");
+#line 779 "runarray.in"
+ REGISTER_BLTIN(run::arrayAppendHelper,"arrayAppendHelper");
+#line 788 "runarray.in"
+ REGISTER_BLTIN(run::arrayAppend,"arrayAppend");
+#line 794 "runarray.in"
+ REGISTER_BLTIN(run::arrayPopHelper,"arrayPopHelper");
+#line 803 "runarray.in"
+ REGISTER_BLTIN(run::arrayPop,"arrayPop");
+#line 809 "runarray.in"
+ REGISTER_BLTIN(run::arrayInsertHelper,"arrayInsertHelper");
+#line 820 "runarray.in"
+ REGISTER_BLTIN(run::arrayInsert,"arrayInsert");
+#line 826 "runarray.in"
+ REGISTER_BLTIN(run::arrayDelete,"arrayDelete");
+#line 832 "runarray.in"
+ REGISTER_BLTIN(run::arrayAlias,"arrayAlias");
+#line 837 "runarray.in"
+ REGISTER_BLTIN(run::arrayIntArray,"arrayIntArray");
+#line 855 "runarray.in"
+ addFunc(ve, run::gen_runarray32, IntArray(), SYM(complement), formal(IntArray(), SYM(a), false, false), formal(primInt(), SYM(n), false, false));
+#line 874 "runarray.in"
+ REGISTER_BLTIN(run::arraySequence,"arraySequence");
+#line 887 "runarray.in"
+ addFunc(ve, run::gen_runarray34, IntArray(), SYM(sequence), formal(primInt(), SYM(n), false, false));
+#line 898 "runarray.in"
+ REGISTER_BLTIN(run::arrayFunction,"arrayFunction");
+#line 911 "runarray.in"
+ REGISTER_BLTIN(run::arraySort,"arraySort");
+#line 921 "runarray.in"
+ REGISTER_BLTIN(run::arraySearch,"arraySearch");
+#line 940 "runarray.in"
+ addFunc(ve, run::gen_runarray38, primBoolean(), SYM(all), formal(booleanArray(), SYM(a), false, false));
+#line 949 "runarray.in"
+ addFunc(ve, run::gen_runarray39, booleanArray(), SYM_LOGNOT, formal(booleanArray(), SYM(a), false, false));
+#line 958 "runarray.in"
+ addFunc(ve, run::gen_runarray40, primInt(), SYM(sum), formal(booleanArray(), SYM(a), false, false));
+#line 967 "runarray.in"
+ REGISTER_BLTIN(run::arrayConcat,"arrayConcat");
+#line 995 "runarray.in"
+ REGISTER_BLTIN(run::array2Transpose,"array2Transpose");
+#line 1019 "runarray.in"
+ REGISTER_BLTIN(run::array3Transpose,"array3Transpose");
+#line 1106 "runarray.in"
+ addFunc(ve, run::gen_runarray44, primInt(), SYM(find), formal(booleanArray(), SYM(a), false, false), formal(primInt(), SYM(n), true, false));
+#line 1125 "runarray.in"
+ addFunc(ve, run::gen_runarray45, IntArray(), SYM(findall), formal(booleanArray(), SYM(a), false, false));
+#line 1138 "runarray.in"
+ REGISTER_BLTIN(run::arrayConditional,"arrayConditional");
+#line 1164 "runarray.in"
+ addFunc(ve, run::gen_runarray47, realArray2(), SYM(identity), formal(primInt(), SYM(n), false, false));
+#line 1170 "runarray.in"
+ addFunc(ve, run::gen_runarray48, realArray2(), SYM(inverse), formal(realArray2(), SYM(a), false, false));
+#line 1182 "runarray.in"
+ addFunc(ve, run::gen_runarray49, realArray(), SYM(solve), formal(realArray2(), SYM(a), false, false), formal(realArray(), SYM(b), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 1235 "runarray.in"
+ addFunc(ve, run::gen_runarray50, realArray2(), SYM(solve), formal(realArray2(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 1300 "runarray.in"
+ addFunc(ve, run::gen_runarray51, primReal(), SYM(determinant), formal(realArray2(), SYM(a), false, false));
+#line 1317 "runarray.in"
+ addFunc(ve, run::gen_runarray52, realArray(), SYM_TIMES, formal(realArray2(), SYM(a), false, false), formal(realArray(), SYM(b), false, false));
+#line 1336 "runarray.in"
+ addFunc(ve, run::gen_runarray53, realArray(), SYM_TIMES, formal(realArray(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false));
+#line 1365 "runarray.in"
+ addFunc(ve, run::gen_runarray54, IntArray2(), SYM_TIMES, formal(IntArray2(), SYM(a), false, false), formal(IntArray2(), SYM(b), false, false));
+#line 1370 "runarray.in"
+ addFunc(ve, run::gen_runarray55, realArray2(), SYM_TIMES, formal(realArray2(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false));
+#line 1375 "runarray.in"
+ addFunc(ve, run::gen_runarray56, pairArray2(), SYM_TIMES, formal(pairArray2(), SYM(a), false, false), formal(pairArray2(), SYM(b), false, false));
+#line 1380 "runarray.in"
+ addFunc(ve, run::gen_runarray57, primTriple(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primTriple(), SYM(v), false, false));
+#line 1385 "runarray.in"
+ addFunc(ve, run::gen_runarray58, realArray2(), SYM(AtA), formal(realArray2(), SYM(a), false, false));
+#line 1390 "runarray.in"
+ addFunc(ve, run::gen_runarray59, primPair(), SYM(project), formal(primTriple(), SYM(v), false, false), formal(realArray2(), SYM(t), false, false));
+#line 1415 "runarray.in"
+ addFunc(ve, run::gen_runarray60, primReal(), SYM(dot), formal(realArray(), SYM(a), false, false), formal(realArray(), SYM(b), false, false));
+#line 1425 "runarray.in"
+ addFunc(ve, run::gen_runarray61, primPair(), SYM(dot), formal(pairArray(), SYM(a), false, false), formal(pairArray(), SYM(b), false, false));
+#line 1435 "runarray.in"
+ addFunc(ve, run::gen_runarray62, realArray(), SYM(tridiagonal), formal(realArray(), SYM(a), false, false), formal(realArray(), SYM(b), false, false), formal(realArray(), SYM(c), false, false), formal(realArray(), SYM(f), false, false));
+#line 1539 "runarray.in"
+ addFunc(ve, run::gen_runarray63, primReal(), SYM(newton), formal(primInt(), SYM(iterations), true, false), formal(realRealFunction(), SYM(f), false, false), formal(realRealFunction(), SYM(fprime), false, false), formal(primReal(), SYM(x), false, false), formal(primBoolean(), SYM(verbose), true, false));
+#line 1586 "runarray.in"
+ addFunc(ve, run::gen_runarray64, primReal(), SYM(newton), formal(primInt(), SYM(iterations), true, false), formal(realRealFunction(), SYM(f), false, false), formal(realRealFunction(), SYM(fprime), false, false), formal(primReal(), SYM(x1), false, false), formal(primReal(), SYM(x2), false, false), formal(primBoolean(), SYM(verbose), true, false));
+#line 1668 "runarray.in"
+ addFunc(ve, run::gen_runarray65, primReal(), SYM(_findroot), formal(realRealFunction(), SYM(f), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(tolerance), false, false), formal(primReal(), SYM(fa), false, false), formal(primReal(), SYM(fb), false, false));
+#line 1770 "runarray.in"
+ addFunc(ve, run::gen_runarray66, primReal(), SYM(simpson), formal(realRealFunction(), SYM(f), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(acc), true, false), formal(primReal(), SYM(dxmax), true, false));
+#line 1784 "runarray.in"
+ addFunc(ve, run::gen_runarray67, pairArray(), SYM(fft), formal(pairArray(), SYM(a), false, false), formal(primInt(), SYM(sign), true, false));
+#line 1815 "runarray.in"
+ addFunc(ve, run::gen_runarray68, IntArray2(), SYM(triangulate), formal(pairArray(), SYM(z), false, false));
+#line 1850 "runarray.in"
+ addFunc(ve, run::gen_runarray69, primReal(), SYM(norm), formal(realArray(), SYM(a), false, false));
+#line 1861 "runarray.in"
+ addFunc(ve, run::gen_runarray70, primReal(), SYM(norm), formal(realArray2(), SYM(a), false, false));
+#line 1876 "runarray.in"
+ addFunc(ve, run::gen_runarray71, primReal(), SYM(norm), formal(tripleArray2(), SYM(a), false, false));
+#line 1891 "runarray.in"
+ addFunc(ve, run::gen_runarray72, primReal(), SYM(change2), formal(tripleArray2(), SYM(a), false, false));
+#line 1913 "runarray.in"
+ addFunc(ve, run::gen_runarray73, primTriple(), SYM(minbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
+#line 1925 "runarray.in"
+ addFunc(ve, run::gen_runarray74, primTriple(), SYM(maxbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
+#line 1937 "runarray.in"
+ addFunc(ve, run::gen_runarray75, primPair(), SYM(minratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
+#line 1949 "runarray.in"
+ addFunc(ve, run::gen_runarray76, primPair(), SYM(maxratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
+#line 1961 "runarray.in"
+ addFunc(ve, run::gen_runarray77, realArray(), SYM(_projection));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runarray.h b/graphics/asymptote/runarray.h
new file mode 100644
index 0000000000..0a1baf7267
--- /dev/null
+++ b/graphics/asymptote/runarray.h
@@ -0,0 +1,48 @@
+/***** Autogenerated from runarray.in; changes will be overwritten *****/
+
+#ifndef runarray_H
+#define runarray_H
+namespace run {
+void emptyArray(vm::stack *);
+void newDeepArray(vm::stack *);
+void newInitializedArray(vm::stack *);
+void newAppendedArray(vm::stack *);
+void copyArrayValue(vm::stack *);
+void copyArray(vm::stack *);
+void arrayRead(vm::stack *);
+void arraySliceRead(vm::stack *);
+void arraySliceReadToEnd(vm::stack *);
+void arrayArrayRead(vm::stack *);
+void arrayWrite(vm::stack *);
+void arraySliceWrite(vm::stack *);
+void arraySliceWriteToEnd(vm::stack *);
+void arrayLength(vm::stack *);
+void arrayKeys(vm::stack *);
+void arrayCyclicFlag(vm::stack *);
+void arraySetCyclicFlag(vm::stack *);
+void arrayInitializedHelper(vm::stack *);
+void arrayInitialized(vm::stack *);
+void arrayCyclicHelper(vm::stack *);
+void arrayCyclic(vm::stack *);
+void arrayPushHelper(vm::stack *);
+void arrayPush(vm::stack *);
+void arrayAppendHelper(vm::stack *);
+void arrayAppend(vm::stack *);
+void arrayPopHelper(vm::stack *);
+void arrayPop(vm::stack *);
+void arrayInsertHelper(vm::stack *);
+void arrayInsert(vm::stack *);
+void arrayDelete(vm::stack *);
+void arrayAlias(vm::stack *);
+void arrayIntArray(vm::stack *);
+void arraySequence(vm::stack *);
+void arrayFunction(vm::stack *);
+void arraySort(vm::stack *);
+void arraySearch(vm::stack *);
+void arrayConcat(vm::stack *);
+void array2Transpose(vm::stack *);
+void array3Transpose(vm::stack *);
+void arrayConditional(vm::stack *);
+}
+
+#endif // runarray_H
diff --git a/graphics/asymptote/runarray.in b/graphics/asymptote/runarray.in
new file mode 100644
index 0000000000..10469aac7a
--- /dev/null
+++ b/graphics/asymptote/runarray.in
@@ -0,0 +1,1991 @@
+/*****
+ * runarray.in
+ *
+ * Runtime functions for array operations.
+ *
+ *****/
+
+pair => primPair()
+triple => primTriple()
+boolarray* => booleanArray()
+Intarray* => IntArray()
+Intarray2* => IntArray2()
+realarray* => realArray()
+realarray2* => realArray2()
+pairarray* => pairArray()
+pairarray2* => pairArray2()
+triplearray2* => tripleArray2()
+callableReal* => realRealFunction()
+
+
+#include "array.h"
+#include "arrayop.h"
+#include "triple.h"
+#include "path3.h"
+#include "Delaunay.h"
+#include "glrender.h"
+
+#ifdef HAVE_LIBFFTW3
+#include "fftw++.h"
+#endif
+
+using namespace camp;
+using namespace vm;
+
+namespace run {
+extern pair zero;
+}
+
+typedef array boolarray;
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray2;
+
+using types::booleanArray;
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray2;
+
+typedef callable callableReal;
+
+void outOfBounds(const char *op, size_t len, Int n)
+{
+ ostringstream buf;
+ buf << op << " array of length " << len << " with out-of-bounds index " << n;
+ error(buf);
+}
+
+inline item& arrayRead(array *a, Int n)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) outOfBounds("reading",len,n);
+ return (*a)[(unsigned) n];
+}
+
+// Helper function to create deep arrays.
+static array* deepArray(Int depth, Int *dims)
+{
+ assert(depth > 0);
+
+ if (depth == 1) {
+ return new array(dims[0]);
+ } else {
+ Int length = dims[0];
+ depth--; dims++;
+
+ array *a = new array(length);
+
+ for (Int index = 0; index < length; index++) {
+ (*a)[index] = deepArray(depth, dims);
+ }
+ return a;
+ }
+}
+
+namespace run {
+array *Identity(Int n)
+{
+ size_t N=(size_t) n;
+ array *c=new array(N);
+ for(size_t i=0; i < N; ++i) {
+ array *ci=new array(N);
+ (*c)[i]=ci;
+ for(size_t j=0; j < N; ++j)
+ (*ci)[j]=0.0;
+ (*ci)[i]=1.0;
+ }
+ return c;
+}
+}
+
+static const char *incommensurate="Incommensurate matrices";
+static const char *singular="Singular matrix";
+static const char *invalidarraylength="Invalid array length: ";
+static size_t *pivot,*Row,*Col;
+
+bound_double *bounddouble(int N)
+{
+ if(N == 16) return bound;
+ if(N == 10) return boundtri;
+ ostringstream buf;
+ buf << invalidarraylength << " " << N;
+ error(buf);
+ return NULL;
+}
+
+bound_triple *boundtriple(int N)
+{
+ if(N == 16) return bound;
+ if(N == 10) return boundtri;
+ ostringstream buf;
+ buf << invalidarraylength << " " << N;
+ error(buf);
+ return NULL;
+}
+
+static inline void inverseAllocate(size_t n)
+{
+ pivot=new size_t[n];
+ Row=new size_t[n];
+ Col=new size_t[n];
+}
+
+static inline void inverseDeallocate()
+{
+ delete[] pivot;
+ delete[] Row;
+ delete[] Col;
+}
+
+namespace run {
+
+array *copyArray(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=(*a)[i];
+ return c;
+}
+
+array *copyArray2(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=(*ai)[j];
+ }
+ return c;
+}
+
+double *copyTripleArray2Components(array *a, size_t &N, GCPlacement placement)
+{
+ size_t n=checkArray(a);
+ N=0;
+ for(size_t i=0; i < n; i++)
+ N += checkArray(read<array*>(a,i));
+
+ double *A=(placement == NoGC) ? new double [3*N] :
+ new(placement) double[3*N];
+ double *p=A;
+
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; j++) {
+ triple v=read<triple>(ai,j);
+ *p=v.getx();
+ *(p+N)=v.gety();
+ *(p+2*N)=v.getz();
+ ++p;
+ }
+ }
+ return A;
+}
+
+triple *copyTripleArray2C(array *a, size_t &N, GCPlacement placement)
+{
+ size_t n=checkArray(a);
+ N=0;
+ for(size_t i=0; i < n; i++)
+ N += checkArray(read<array*>(a,i));
+
+ triple *A=(placement == NoGC) ? new triple [N] :
+ new(placement) triple[N];
+ triple *p=A;
+
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; j++)
+ *(p++)=read<triple>(ai,j);
+ }
+ return A;
+}
+
+triple operator *(const array& t, const triple& v)
+{
+ size_t n=checkArray(&t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t2=read<array*>(t,2);
+ array *t3=read<array*>(t,3);
+
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 ||
+ checkArray(t2) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+
+ double f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) run::dividebyzero();
+ f=1.0/f;
+
+ return triple((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f,
+ (read<real>(t2,0)*x+read<real>(t2,1)*y+read<real>(t2,2)*z+
+ read<real>(t2,3))*f);
+}
+
+template<class T>
+array *mult(array *a, array *b)
+{
+ size_t n=checkArray(a);
+
+ size_t nb=checkArray(b);
+ size_t na0=n == 0 ? 0 : checkArray(read<array*>(a,0));
+ if(na0 != nb)
+ error(incommensurate);
+
+ size_t nb0=nb == 0 ? 0 : checkArray(read<array*>(b,0));
+
+ array *c=new array(n);
+
+ T *A,*B;
+ copyArray2C(A,a,false);
+ copyArray2C(B,b,false);
+
+ for(size_t i=0; i < n; ++i) {
+ T *Ai=A+i*nb;
+ array *ci=new array(nb0);
+ (*c)[i]=ci;
+ for(size_t j=0; j < nb0; ++j) {
+ T sum=T();
+ size_t kj=j;
+ for(size_t k=0; k < nb; ++k, kj += nb0)
+ sum += Ai[k]*B[kj];
+ (*ci)[j]=sum;
+ }
+ }
+
+ delete[] B;
+ delete[] A;
+
+ return c;
+}
+
+// Compute transpose(A)*A where A is an n x m matrix.
+template<class T>
+array *AtA(array *a)
+{
+ size_t n=checkArray(a);
+ size_t m=n == 0 ? 0 : checkArray(read<array*>(a,0));
+
+ array *c=new array(m);
+
+ T *A;
+ copyArray2C(A,a,false);
+
+ for(size_t i=0; i < m; ++i) {
+ array *ci=new array(m);
+ (*c)[i]=ci;
+ for(size_t j=0; j < m; ++j) {
+ T sum=T();
+ size_t kj=j;
+ size_t ki=i;
+ for(size_t k=0; k < n; ++k, kj += m, ki += m)
+ sum += A[ki]*A[kj];
+ (*ci)[j]=sum;
+ }
+ }
+
+ delete[] A;
+ return c;
+}
+
+double norm(double *a, size_t n)
+{
+ if(n == 0) return 0.0;
+ double M=fabs(a[0]);
+ for(size_t i=1; i < n; ++i)
+ M=::max(M,fabs(a[i]));
+ return M;
+}
+
+double norm(triple *a, size_t n)
+{
+ if(n == 0) return 0.0;
+ double M=a[0].abs2();
+ for(size_t i=1; i < n; ++i)
+ M=::max(M,a[i].abs2());
+ return sqrt(M);
+}
+
+// Transpose an n x n matrix in place.
+void transpose(double *a, size_t n)
+{
+ for(size_t i=1; i < n; i++) {
+ for(size_t j=0; j < i; j++) {
+ size_t ij=n*i+j;
+ size_t ji=n*j+i;
+ double temp=a[ij];
+ a[ij]=a[ji];
+ a[ji]=temp;
+ }
+ }
+}
+
+// Invert an n x n array in place.
+void inverse(double *a, size_t n)
+{
+ inverseAllocate(n);
+
+ for(size_t i=0; i < n; i++)
+ pivot[i]=0;
+
+ size_t col=0, row=0;
+ // This is the main loop over the columns to be reduced.
+ for(size_t i=0; i < n; i++) {
+ real big=0.0;
+ // This is the outer loop of the search for a pivot element.
+ for(size_t j=0; j < n; j++) {
+ double *aj=a+n*j;
+ if(pivot[j] != 1) {
+ for(size_t k=0; k < n; k++) {
+ if(pivot[k] == 0) {
+ real temp=fabs(aj[k]);
+ if(temp >= big) {
+ big=temp;
+ row=j;
+ col=k;
+ }
+ } else if(pivot[k] > 1) {
+ inverseDeallocate();
+ error(singular);
+ }
+ }
+ }
+ }
+ ++(pivot[col]);
+
+ // Interchange rows, if needed, to put the pivot element on the diagonal.
+ double *acol=a+n*col;
+ if(row != col) {
+ double *arow=a+n*row;
+ for(size_t k=0; k < n; k++) {
+ real temp=arow[k];
+ arow[k]=acol[k];
+ acol[k]=temp;
+ }
+ }
+
+ Row[i]=row;
+ Col[i]=col;
+
+ // Divide the pivot row by the pivot element.
+ real denom=acol[col];
+ if(denom == 0.0) {
+ inverseDeallocate();
+ error(singular);
+ }
+ real pivinv=1.0/denom;
+ acol[col]=1.0;
+ for(size_t k=0; k < n; k++)
+ acol[k]=acol[k]*pivinv;
+
+ // Reduce all rows except for the pivoted one.
+ for(size_t k=0; k < n; k++) {
+ if(k != col) {
+ double *ak=a+n*k;
+ real akcol=ak[col];
+ ak[col]=0.0;
+ for(size_t j=0; j < n; j++)
+ ak[j] -= acol[j]*akcol;
+ }
+ }
+ }
+
+ // Unscramble the inverse matrix in view of the column interchanges.
+ for(size_t k=n; k > 0;) {
+ k--;
+ size_t r=Row[k];
+ size_t c=Col[k];
+ if(r != c) {
+ for(size_t j=0; j < n; j++) {
+ double *aj=a+n*j;
+ real temp=aj[r];
+ aj[r]=aj[c];
+ aj[c]=temp;
+ }
+ }
+ }
+ inverseDeallocate();
+}
+}
+
+callable *Func;
+stack *FuncStack;
+double wrapFunction(double x)
+{
+ FuncStack->push(x);
+ Func->call(FuncStack);
+ return pop<double>(FuncStack);
+}
+
+callable *compareFunc;
+bool compareFunction(const vm::item& i, const vm::item& j)
+{
+ FuncStack->push(i);
+ FuncStack->push(j);
+ compareFunc->call(FuncStack);
+ return pop<bool>(FuncStack);
+}
+
+// Crout's algorithm for computing the LU decomposition of a square matrix.
+// cf. routine ludcmp (Press et al., Numerical Recipes, 1991).
+Int LUdecompose(double *a, size_t n, size_t* index, bool warn=true)
+{
+ double *vv=new double[n];
+ Int swap=1;
+ for(size_t i=0; i < n; ++i) {
+ double big=0.0;
+ double *ai=a+i*n;
+ for(size_t j=0; j < n; ++j) {
+ double temp=fabs(ai[j]);
+ if(temp > big) big=temp;
+ }
+ if(big == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ vv[i]=1.0/big;
+ }
+ for(size_t j=0; j < n; ++j) {
+ for(size_t i=0; i < j; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < i; ++k) {
+ sum -= ai[k]*a[k*n+j];
+ }
+ ai[j]=sum;
+ }
+ double big=0.0;
+ size_t imax=j;
+ for(size_t i=j; i < n; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < j; ++k)
+ sum -= ai[k]*a[k*n+j];
+ ai[j]=sum;
+ double temp=vv[i]*fabs(sum);
+ if(temp >= big) {
+ big=temp;
+ imax=i;
+ }
+ }
+ double *aj=a+j*n;
+ double *aimax=a+imax*n;
+ if(j != imax) {
+ for(size_t k=0; k < n; ++k) {
+ double temp=aimax[k];
+ aimax[k]=aj[k];
+ aj[k]=temp;
+ }
+ swap *= -1;
+ vv[imax]=vv[j];
+ }
+ if(index)
+ index[j]=imax;
+ if(j != n) {
+ double denom=aj[j];
+ if(denom == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ for(size_t i=j+1; i < n; ++i)
+ a[i*n+j] /= denom;
+ }
+ }
+ delete[] vv;
+ return swap;
+}
+
+namespace run {
+
+void dividebyzero(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Divide by zero";
+ error(buf);
+}
+
+void integeroverflow(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Integer overflow";
+ error(buf);
+}
+
+}
+
+// Autogenerated routines:
+
+
+// Create an empty array.
+array* :emptyArray()
+{
+ return new array(0);
+}
+
+// Create a new array (technically a vector).
+// This array will be multidimensional. First the number of dimensions
+// is popped off the stack, followed by each dimension in reverse order.
+// The array itself is technically a one dimensional array of one
+// dimension arrays and so on.
+array* :newDeepArray(Int depth)
+{
+ assert(depth > 0);
+
+ Int *dims = new Int[depth];
+
+ for (Int index = depth-1; index >= 0; index--) {
+ Int i=pop<Int>(Stack);
+ if(i < 0) error("cannot create a negative length array");
+ dims[index]=i;
+ }
+
+ array *a=deepArray(depth, dims);
+ delete[] dims;
+ return a;
+}
+
+// Creates an array with elements already specified. First, the number
+// of elements is popped off the stack, followed by each element in
+// reverse order.
+array* :newInitializedArray(Int n)
+{
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ return a;
+}
+
+// Similar to newInitializedArray, but after the n elements, append another
+// array to it.
+array* :newAppendedArray(array* tail, Int n)
+{
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ copy(tail->begin(), tail->end(), back_inserter(*a));
+
+ return a;
+}
+
+// Produce an array of n deep copies of value.
+// typeDepth is the true depth of the array determined at compile-time when the
+// operations for the array type are added. This typeDepth argument is
+// automatically pushed on the stack and is not visible to the user.
+array* :copyArrayValue(Int n, item value, Int depth=Int_MAX, Int typeDepth)
+{
+ if(n < 0) error("cannot create a negative length array");
+ if(depth < 0) error("cannot copy to a negative depth");
+ if(depth > typeDepth) depth=typeDepth;
+ return new array((size_t) n, value, depth);
+}
+
+// Deep copy of array.
+// typeDepth is the true depth of the array determined at compile-time when the
+// operations for the array type are added. This typeDepth argument is
+// automatically pushed on the stack and is not visible to the user.
+array* :copyArray(array *a, Int depth=Int_MAX, Int typeDepth)
+{
+ if(depth < 0) error("cannot copy to a negative depth");
+ if(depth > typeDepth) depth=typeDepth;
+ return a->copyToDepth(depth);
+}
+
+// Read an element from an array. Checks for initialization & bounds.
+item :arrayRead(array *a, Int n)
+{
+ item& i=arrayRead(a,n);
+ if (i.empty()) {
+ ostringstream buf;
+ buf << "read uninitialized value from array at index " << n;
+ error(buf);
+ }
+ return i;
+}
+
+// Slice a substring from an array.
+item :arraySliceRead(array *a, Int left, Int right)
+{
+ checkArray(a);
+ return a->slice(left, right);
+}
+
+// Slice a substring from an array. This implements the cases a[i:] and a[:]
+// where the endpoint is not given, and assumed to be the length of the array.
+item :arraySliceReadToEnd(array *a, Int left)
+{
+ size_t len=checkArray(a);
+ return a->slice(left, (Int)len);
+}
+
+// Read an element from an array of arrays. Check bounds and initialize
+// as necessary.
+item :arrayArrayRead(array *a, Int n)
+{
+ item& i=arrayRead(a,n);
+ if (i.empty()) i=new array(0);
+ return i;
+}
+
+// Write an element to an array. Increase size if necessary.
+// TODO: Add arrayWriteAndPop
+item :arrayWrite(array *a, Int n, item value)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else {
+ if(cyclic) outOfBounds("writing cyclic",len,n);
+ if(n < 0) outOfBounds("writing",len,n);
+ if(len <= (size_t) n)
+ a->resize(n+1);
+ }
+ (*a)[n] = value;
+ return value;
+}
+
+array * :arraySliceWrite(array *dest, Int left, Int right, array *src)
+{
+ checkArray(src);
+ checkArray(dest);
+ dest->setSlice(left, right, src);
+ return src;
+}
+
+array * :arraySliceWriteToEnd(array *dest, Int left, array *src)
+{
+ checkArray(src);
+ size_t len=checkArray(dest);
+ dest->setSlice(left, (Int) len, src);
+ return src;
+}
+
+// Returns the length of an array.
+Int :arrayLength(array *a)
+{
+ return (Int) checkArray(a);
+}
+
+// Returns an array of integers representing the keys of the array.
+array * :arrayKeys(array *a)
+{
+ size_t size=checkArray(a);
+
+ array *keys=new array();
+ for (size_t i=0; i<size; ++i) {
+ item& cell = (*a)[i];
+ if (!cell.empty())
+ keys->push((Int)i);
+ }
+
+ return keys;
+}
+
+// Return the cyclic flag for an array.
+bool :arrayCyclicFlag(array *a)
+{
+ checkArray(a);
+ return a->cyclic();
+}
+
+bool :arraySetCyclicFlag(bool b, array *a)
+{
+ checkArray(a);
+ a->cyclic(b);
+ return b;
+}
+
+// Check to see if an array element is initialized.
+bool :arrayInitializedHelper(Int n, array *a)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) return false;
+ item&i=(*a)[(unsigned) n];
+ return !i.empty();
+}
+
+// Returns the initialize method for an array.
+callable* :arrayInitialized(array *a)
+{
+ return new thunk(new bfunc(arrayInitializedHelper),a);
+}
+
+// The helper function for the cyclic method that sets the cyclic flag.
+void :arrayCyclicHelper(bool b, array *a)
+{
+ checkArray(a);
+ a->cyclic(b);
+}
+
+// Set the cyclic flag for an array.
+callable* :arrayCyclic(array *a)
+{
+ return new thunk(new bfunc(arrayCyclicHelper),a);
+}
+
+// The helper function for the push method that does the actual operation.
+item :arrayPushHelper(item x, array *a)
+{
+ checkArray(a);
+ a->push(x);
+ return x;
+}
+
+// Returns the push method for an array.
+callable* :arrayPush(array *a)
+{
+ return new thunk(new bfunc(arrayPushHelper),a);
+}
+
+// The helper function for the append method that appends b to a.
+void :arrayAppendHelper(array *b, array *a)
+{
+ checkArray(a);
+ size_t size=checkArray(b);
+ for(size_t i=0; i < size; i++)
+ a->push((*b)[i]);
+}
+
+// Returns the append method for an array.
+callable* :arrayAppend(array *a)
+{
+ return new thunk(new bfunc(arrayAppendHelper),a);
+}
+
+// The helper function for the pop method.
+item :arrayPopHelper(array *a)
+{
+ size_t asize=checkArray(a);
+ if(asize == 0)
+ error("cannot pop element from empty array");
+ return a->pop();
+}
+
+// Returns the pop method for an array.
+callable* :arrayPop(array *a)
+{
+ return new thunk(new bfunc(arrayPopHelper),a);
+}
+
+// The helper function for the insert method.
+item :arrayInsertHelper(Int i, array *x, array *a)
+{
+ size_t asize=checkArray(a);
+ checkArray(x);
+ if(a->cyclic() && asize > 0) i=imod(i,asize);
+ if(i < 0 || i > (Int) asize)
+ outOfBounds("inserting",asize,i);
+ (*a).insert((*a).begin()+i,(*x).begin(),(*x).end());
+}
+
+// Returns the insert method for an array.
+callable* :arrayInsert(array *a)
+{
+ return new thunk(new bfunc(arrayInsertHelper),a);
+}
+
+// Returns the delete method for an array.
+callable* :arrayDelete(array *a)
+{
+ return new thunk(new bfunc(arrayDeleteHelper),a);
+}
+
+bool :arrayAlias(array *a, array *b)
+{
+ return a==b;
+}
+
+// Return array formed by indexing array a with elements of integer array b
+array* :arrayIntArray(array *a, array *b)
+{
+ size_t asize=checkArray(a);
+ size_t bsize=checkArray(b);
+ array *r=new array(bsize);
+ bool cyclic=a->cyclic();
+ for(size_t i=0; i < bsize; i++) {
+ Int index=read<Int>(b,i);
+ if(cyclic && asize > 0) index=imod(index,asize);
+ else
+ if(index < 0 || index >= (Int) asize)
+ outOfBounds("reading",asize,index);
+ (*r)[i]=(*a)[index];
+ }
+ return r;
+}
+
+// returns the complement of the integer array a in {0,2,...,n-1},
+// so that b[complement(a,b.length)] yields the complement of b[a].
+Intarray* complement(Intarray *a, Int n)
+{
+ size_t asize=checkArray(a);
+ array *r=new array(0);
+ bool *keep=new bool[n];
+ for(Int i=0; i < n; ++i) keep[i]=true;
+ for(size_t i=0; i < asize; ++i) {
+ Int j=read<Int>(a,i);
+ if(j >= 0 && j < n) keep[j]=false;
+ }
+ for(Int i=0; i < n; i++)
+ if(keep[i]) r->push(i);
+
+ delete[] keep;
+ return r;
+}
+
+// Generate the sequence {f(i) : i=0,1,...n-1} given a function f and integer n
+Intarray* :arraySequence(callable *f, Int n)
+{
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ Stack->push(i);
+ f->call(Stack);
+ (*a)[i]=pop(Stack);
+ }
+ return a;
+}
+
+// Return the array {0,1,...n-1}
+Intarray *sequence(Int n)
+{
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ (*a)[i]=i;
+ }
+ return a;
+}
+
+// Apply a function to each element of an array
+array* :arrayFunction(callable *f, array *a)
+{
+ size_t size=checkArray(a);
+ array *b=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ Stack->push((*a)[i]);
+ f->call(Stack);
+ (*b)[i]=pop(Stack);
+ }
+ return b;
+}
+
+array* :arraySort(array *a, callable *less, bool stable=true)
+{
+ array *c=copyArray(a);
+ compareFunc=less;
+ FuncStack=Stack;
+ if(stable) stable_sort(c->begin(),c->end(),compareFunction);
+ else sort(c->begin(),c->end(),compareFunction);
+ return c;
+}
+
+Int :arraySearch(array *a, item key, callable *less)
+{
+ size_t size=a->size();
+ compareFunc=less;
+ FuncStack=Stack;
+ if(size == 0 || compareFunction(key,(*a)[0])) return -1;
+ size_t u=size-1;
+ if(!compareFunction(key,(*a)[u])) return Intcast(u);
+ size_t l=0;
+
+ while (l < u) {
+ size_t i=(l+u)/2;
+ if(compareFunction(key,(*a)[i])) u=i;
+ else if(compareFunction(key,(*a)[i+1])) return Intcast(i);
+ else l=i+1;
+ }
+ return 0;
+}
+
+bool all(boolarray *a)
+{
+ size_t size=checkArray(a);
+ bool c=true;
+ for(size_t i=0; i < size; i++)
+ if(!get<bool>((*a)[i])) {c=false; break;}
+ return c;
+}
+
+boolarray* !(boolarray* a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=!read<bool>(a,i);
+ return c;
+}
+
+Int sum(boolarray *a)
+{
+ size_t size=checkArray(a);
+ Int sum=0;
+ for(size_t i=0; i < size; i++)
+ sum += read<bool>(a,i) ? 1 : 0;
+ return sum;
+}
+
+array* :arrayConcat(array *a)
+{
+ // a is an array of arrays to be concatenated together.
+ // The signature is
+ // T[] concat(... T[][] a);
+
+ size_t numArgs=checkArray(a);
+ size_t resultSize=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ resultSize += checkArray(a->read<array *>(i));
+ }
+
+ array *result=new array(resultSize);
+
+ size_t ri=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ array *arg=a->read<array *>(i);
+ size_t size=checkArray(arg);
+
+ for (size_t j=0; j < size; ++j) {
+ (*result)[ri]=(*arg)[j];
+ ++ri;
+ }
+ }
+
+ return result;
+}
+
+array* :array2Transpose(array *a)
+{
+ size_t asize=checkArray(a);
+ array *c=new array(0);
+ for(size_t i=0; i < asize; i++) {
+ size_t ip=i+1;
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ size_t csize=checkArray(c);
+ if(csize < aisize) {
+ c->resize(aisize);
+ for(size_t j=csize; j < aisize; j++) {
+ (*c)[j]=new array(ip);
+ }
+ }
+ for(size_t j=0; j < aisize; j++) {
+ array *cj=read<array*>(c,j);
+ if(checkArray(cj) < ip) cj->resize(ip);
+ (*cj)[i]=(*ai)[j];
+ }
+ }
+ return c;
+}
+
+// a is a rectangular 3D array; perm is an Int array indicating the type of
+// permutation (021 or 120, etc; original is 012).
+// Transpose by sending respective members to the permutated locations:
+// return the array obtained by putting a[i][j][k] into position perm{ijk}.
+array* :array3Transpose(array *a, array *perm)
+{
+ const size_t DIM=3;
+
+ if(checkArray(perm) != DIM) {
+ ostringstream buf;
+ buf << "permutation array must have length " << DIM;
+ error(buf);
+ }
+
+ size_t* size=new size_t[DIM];
+ for(size_t i=0; i < DIM; ++i) size[i]=DIM;
+
+ for(size_t i=0; i < DIM; ++i) {
+ Int p=read<Int>(perm,i);
+ size_t P=(size_t) p;
+ if(p < 0 || P >= DIM) {
+ ostringstream buf;
+ buf << "permutation index out of range: " << p;
+ error(buf);
+ }
+ size[P]=P;
+ }
+
+ for(size_t i=0; i < DIM; ++i)
+ if(size[i] == DIM) error("permutation indices must be distinct");
+
+ static const char *rectangular=
+ "3D transpose implemented for rectangular matrices only";
+
+ size_t isize=size[0]=checkArray(a);
+ array *a0=read<array*>(a,0);
+ size[1]=checkArray(a0);
+ array *a00=read<array*>(a0,0);
+ size[2]=checkArray(a00);
+ for(size_t i=0; i < isize; i++) {
+ array *ai=read<array*>(a,i);
+ size_t jsize=checkArray(ai);
+ if(jsize != size[1]) error(rectangular);
+ for(size_t j=0; j < jsize; j++) {
+ array *aij=read<array*>(ai,j);
+ if(checkArray(aij) != size[2]) error(rectangular);
+ }
+ }
+
+ size_t perm0=(size_t) read<Int>(perm,0);
+ size_t perm1=(size_t) read<Int>(perm,1);
+ size_t perm2=(size_t) read<Int>(perm,2);
+
+ size_t sizep0=size[perm0];
+ size_t sizep1=size[perm1];
+ size_t sizep2=size[perm2];
+
+ array *c=new array(sizep0);
+ for(size_t i=0; i < sizep0; ++i) {
+ array *ci=new array(sizep1);
+ (*c)[i]=ci;
+ for(size_t j=0; j < sizep1; ++j) {
+ array *cij=new array(sizep2);
+ (*ci)[j]=cij;
+ }
+ }
+
+ size_t* i=new size_t[DIM];
+
+ for(i[0]=0; i[0] < size[0]; ++i[0]) {
+ array *a0=read<array*>(a,i[0]);
+ for(i[1]=0; i[1] < size[1]; ++i[1]) {
+ array *a1=read<array*>(a0,i[1]);
+ for(i[2]=0; i[2] < size[2]; ++i[2]) {
+ array *c0=read<array*>(c,i[perm0]);
+ array *c1=read<array*>(c0,i[perm1]);
+ (*c1)[i[perm2]]=read<real>(a1,i[2]);
+ }
+ }
+ }
+
+ delete[] i;
+ delete[] size;
+
+ return c;
+}
+
+// Find the index of the nth true value in a boolean array or -1 if not found.
+// If n is negative, search backwards.
+Int find(boolarray *a, Int n=1)
+{
+ size_t size=checkArray(a);
+ Int j=-1;
+ if(n > 0)
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) {
+ n--; if(n == 0) {j=(Int) i; break;}
+ }
+ if(n < 0)
+ for(size_t i=size; i > 0;)
+ if(read<bool>(a,--i)) {
+ n++; if(n == 0) {j=(Int) i; break;}
+ }
+ return j;
+}
+
+// Find all indices of true values in a boolean array.
+Intarray *findall(boolarray *a)
+{
+ size_t size=checkArray(a);
+ array *b=new array(0);
+ for(size_t i=0; i < size; i++) {
+ if(read<bool>(a,i)) {
+ b->push((Int) i);
+ }
+ }
+ return b;
+}
+
+// construct vector obtained by replacing those elements of b for which the
+// corresponding elements of a are false by the corresponding element of c.
+array* :arrayConditional(array *a, array *b, array *c)
+{
+ size_t size=checkArray(a);
+ array *r=new array(size);
+ if(b && c) {
+ checkArrays(a,b);
+ checkArrays(b,c);
+ for(size_t i=0; i < size; i++)
+ (*r)[i]=read<bool>(a,i) ? (*b)[i] : (*c)[i];
+ } else {
+ r->clear();
+ if(b) {
+ checkArrays(a,b);
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) r->push((*b)[i]);
+ } else if(c) {
+ checkArrays(a,c);
+ for(size_t i=0; i < size; i++)
+ if(!read<bool>(a,i)) r->push((*c)[i]);
+ }
+ }
+ return r;
+}
+
+// Return an n x n identity matrix.
+realarray2 *identity(Int n)
+{
+ return Identity(n);
+}
+
+// Return the inverse of an n x n matrix a using Gauss-Jordan elimination.
+realarray2 *inverse(realarray2 *a)
+{
+ size_t n=checkArray(a);
+ double *A;
+ copyArray2C(A,a,true,0,NoGC);
+ inverse(A,n);
+ a=copyCArray2(n,n,A);
+ delete[] A;
+ return a;
+}
+
+// Solve the linear equation ax=b by LU decomposition, returning the
+// solution x, where a is an n x n matrix and b is an array of length n.
+// If no solution exists, return an empty array.
+realarray *solve(realarray2 *a, realarray *b, bool warn=true)
+{
+ size_t n=checkArray(a);
+
+ if(n == 0) return new array(0);
+
+ size_t m=checkArray(b);
+ if(m != n) error(incommensurate);
+
+ real *A;
+ copyArray2C(A,a);
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ return new array(0);
+
+ array *x=new array(n);
+
+ real *B;
+ copyArrayC(B,b);
+
+ for(size_t i=0; i < n; ++i) {
+ size_t ip=index[i];
+ real sum=B[ip];
+ B[ip]=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=0; j < i; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum;
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real sum=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=i+1; j < n; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum/Ai[i];
+ }
+
+ for(size_t i=0; i < n; ++i)
+ (*x)[i]=B[i];
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ return x;
+}
+
+// Solve the linear equation ax=b by LU decomposition, returning the
+// solution x, where a is an n x n matrix and b is an n x m matrix.
+// If no solution exists, return an empty array.
+realarray2 *solve(realarray2 *a, realarray2 *b, bool warn=true)
+{
+ size_t n=checkArray(a);
+
+ if(n == 0) return new array(0);
+
+ if(checkArray(b) != n) error(incommensurate);
+ size_t m=checkArray(read<array*>(b,0));
+
+ real *A,*B;
+ copyArray2C(A,a);
+ copyArray2C(B,b,false);
+
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ return new array(0);
+
+ array *x=new array(n);
+
+ for(size_t i=0; i < n; ++i) {
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ real *Bip=B+index[i]*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bip[k];
+ Bip[k]=Bi[k];
+ size_t jk=k;
+ for(size_t j=0; j < i; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum;
+ }
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bi[k];
+ size_t jk=(i+1)*m+k;
+ for(size_t j=i+1; j < n; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum/Ai[i];
+ }
+ }
+
+ for(size_t i=0; i < n; ++i) {
+ real *Bi=B+i*m;
+ array *xi=new array(m);
+ (*x)[i]=xi;
+ for(size_t j=0; j < m; ++j)
+ (*xi)[j]=Bi[j];
+ }
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ return x;
+}
+
+// Compute the determinant of an n x n matrix.
+real determinant(realarray2 *a)
+{
+ real *A;
+ copyArray2C(A,a);
+ size_t n=checkArray(a);
+
+ real det=LUdecompose(A,n,NULL,false);
+ size_t n1=n+1;
+ for(size_t i=0; i < n; ++i)
+ det *= A[i*n1];
+
+ delete[] A;
+
+ return det;
+}
+
+realarray *Operator *(realarray2 *a, realarray *b)
+{
+ size_t n=checkArray(a);
+ size_t m=checkArray(b);
+ array *c=new array(n);
+ real *B;
+ copyArrayC(B,b);
+ for(size_t i=0; i < n; ++i) {
+ array *ai=read<array*>(a,i);
+ if(checkArray(ai) != m) error(incommensurate);
+ real sum=0.0;
+ for(size_t j=0; j < m; ++j)
+ sum += read<real>(ai,j)*B[j];
+ (*c)[i]=sum;
+ }
+ delete[] B;
+ return c;
+}
+
+realarray *Operator *(realarray *a, realarray2 *b)
+{
+ size_t n=checkArray(a);
+ if(n != checkArray(b)) error(incommensurate);
+ real *A;
+ copyArrayC(A,a);
+
+ array **B=new array*[n];
+ array *bk=read<array *>(b,0);
+ B[0]=bk;
+ size_t m=bk->size();
+ for(size_t k=1; k < n; k++) {
+ array *bk=read<array *>(b,k);
+ if(bk->size() != m) error(incommensurate);
+ B[k]=bk;
+ }
+ array *c=new array(m);
+
+ for(size_t i=0; i < m; ++i) {
+ real sum=0.0;
+ for(size_t k=0; k < n; ++k)
+ sum += A[k]*read<real>(B[k],i);
+ (*c)[i]=sum;
+ }
+ delete[] B;
+ delete[] A;
+ return c;
+}
+
+Intarray2 *Operator *(Intarray2 *a, Intarray2 *b)
+{
+ return mult<Int>(a,b);
+}
+
+realarray2 *Operator *(realarray2 *a, realarray2 *b)
+{
+ return mult<real>(a,b);
+}
+
+pairarray2 *Operator *(pairarray2 *a, pairarray2 *b)
+{
+ return mult<pair>(a,b);
+}
+
+triple Operator *(realarray2 *t, triple v)
+{
+ return *t*v;
+}
+
+realarray2 *AtA(realarray2 *a)
+{
+ return AtA<real>(a);
+}
+
+pair project(triple v, realarray2 *t)
+{
+ size_t n=checkArray(t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t3=read<array*>(t,3);
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ real x=v.getx();
+ real y=v.gety();
+ real z=v.getz();
+
+ real f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) dividebyzero();
+ f=1.0/f;
+
+ return pair((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f);
+}
+
+// Compute the dot product of vectors a and b.
+real dot(realarray *a, realarray *b)
+{
+ size_t n=checkArrays(a,b);
+ real sum=0.0;
+ for(size_t i=0; i < n; ++i)
+ sum += read<real>(a,i)*read<real>(b,i);
+ return sum;
+}
+
+// Compute the complex dot product of vectors a and b.
+pair dot(pairarray *a, pairarray *b)
+{
+ size_t n=checkArrays(a,b);
+ pair sum=zero;
+ for(size_t i=0; i < n; ++i)
+ sum += read<pair>(a,i)*conj(read<pair>(b,i));
+ return sum;
+}
+
+// Solve the problem L\inv f, where f is an n vector and L is the n x n matrix
+//
+// [ b[0] c[0] a[0] ]
+// [ a[1] b[1] c[1] ]
+// [ a[2] b[2] c[2] ]
+// [ ... ]
+// [ c[n-1] a[n-1] b[n-1] ]
+realarray *tridiagonal(realarray *a, realarray *b, realarray *c, realarray *f)
+{
+ size_t n=checkArrays(a,b);
+ checkEqual(n,checkArray(c));
+ checkEqual(n,checkArray(f));
+
+ array *up=new array(n);
+ array& u=*up;
+
+ if(n == 0) return up;
+
+ // Special case: zero Dirichlet boundary conditions
+ if(read<real>(a,0) == 0.0 && read<real>(c,n-1) == 0.0) {
+ real temp=read<real>(b,0);
+ if(temp == 0.0) dividebyzero();
+ temp=1.0/temp;
+
+ real *work=new real[n];
+ u[0]=read<real>(f,0)*temp;
+ work[0]=-read<real>(c,0)*temp;
+
+ for(size_t i=1; i < n; i++) {
+ real temp=(read<real>(b,i)+read<real>(a,i)*work[i-1]);
+ if(temp == 0.0) {delete[] work; dividebyzero();}
+ temp=1.0/temp;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*temp;
+ work[i]=-read<real>(c,i)*temp;
+ }
+
+ for(size_t i=n-1; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)+work[i-1]*read<real>(u,i);
+
+ delete[] work;
+ return up;
+ }
+
+ real binv=read<real>(b,0);
+ if(binv == 0.0) dividebyzero();
+ binv=1.0/binv;
+
+ if(n == 1) {u[0]=read<real>(f,0)*binv; return up;}
+ if(n == 2) {
+ real factor=(read<real>(b,0)*read<real>(b,1)-
+ read<real>(a,0)*read<real>(c,1));
+ if(factor== 0.0) dividebyzero();
+ factor=1.0/factor;
+ real temp=(read<real>(b,0)*read<real>(f,1)-
+ read<real>(c,1)*read<real>(f,0))*factor;
+ u[0]=(read<real>(b,1)*read<real>(f,0)-
+ read<real>(a,0)*read<real>(f,1))*factor;
+ u[1]=temp;
+ return up;
+ }
+
+ real *gamma=new real[n-2];
+ real *delta=new real[n-2];
+
+ gamma[0]=read<real>(c,0)*binv;
+ delta[0]=read<real>(a,0)*binv;
+ u[0]=read<real>(f,0)*binv;
+ real beta=read<real>(c,n-1);
+ real fn=read<real>(f,n-1)-beta*read<real>(u,0);
+ real alpha=read<real>(b,n-1)-beta*delta[0];
+
+ for(size_t i=1; i <= n-3; i++) {
+ real alphainv=read<real>(b,i)-read<real>(a,i)*gamma[i-1];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ beta *= -gamma[i-1];
+ gamma[i]=read<real>(c,i)*alphainv;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*alphainv;
+ fn -= beta*read<real>(u,i);
+ delta[i]=-read<real>(a,i)*delta[i-1]*alphainv;
+ alpha -= beta*delta[i];
+ }
+
+ real alphainv=read<real>(b,n-2)-read<real>(a,n-2)*gamma[n-3];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ u[n-2]=(read<real>(f,n-2)-read<real>(a,n-2)*read<real>(u,n-3))
+ *alphainv;
+ beta=read<real>(a,n-1)-beta*gamma[n-3];
+ real dnm1=(read<real>(c,n-2)-read<real>(a,n-2)*delta[n-3])*alphainv;
+ real temp=alpha-beta*dnm1;
+ if(temp == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ u[n-1]=temp=(fn-beta*read<real>(u,n-2))/temp;
+ u[n-2]=read<real>(u,n-2)-dnm1*temp;
+
+ for(size_t i=n-2; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)-gamma[i-1]*read<real>(u,i)-delta[i-1]*temp;
+
+ delete[] delta;
+ delete[] gamma;
+
+ return up;
+}
+
+// Root solve by Newton-Raphson
+real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x,
+ bool verbose=false)
+{
+ static const real fuzz=1000.0*DBL_EPSILON;
+ Int i=0;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ real diff=DBL_MAX;
+ real lastdiff;
+ do {
+ real x0=x;
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dfdx=pop<real>(Stack);
+
+ if(dfdx == 0.0) {
+ x=DBL_MAX;
+ break;
+ }
+
+ Stack->push(x);
+ f->call(Stack);
+ real fx=pop<real>(Stack);
+
+ x -= fx/dfdx;
+
+ lastdiff=diff;
+
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+
+ diff=fabs(x-x0);
+ if(++i == iterations) {
+ x=DBL_MAX;
+ break;
+ }
+ } while (diff != 0.0 && (diff < lastdiff || diff > fuzz*fabs(x)));
+
+ if(verbose)
+ cout.precision(oldPrec);
+ return x;
+}
+
+// Root solve by Newton-Raphson bisection
+// cf. routine rtsafe (Press et al., Numerical Recipes, 1991).
+real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x1,
+ real x2, bool verbose=false)
+{
+ static const real fuzz=1000.0*DBL_EPSILON;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ Stack->push(x1);
+ f->call(Stack);
+ real f1=pop<real>(Stack);
+ if(f1 == 0.0) return x1;
+
+ Stack->push(x2);
+ f->call(Stack);
+ real f2=pop<real>(Stack);
+ if(f2 == 0.0) return x2;
+
+ if((f1 > 0.0 && f2 > 0.0) || (f1 < 0.0 && f2 < 0.0)) {
+ ostringstream buf;
+ buf << "root not bracketed, f(x1)=" << f1 << ", f(x2)=" << f2 << endl;
+ error(buf);
+ }
+
+ real x=0.5*(x1+x2);
+ real dxold=fabs(x2-x1);
+ if(f1 > 0.0) {
+ real temp=x1;
+ x1=x2;
+ x2=temp;
+ }
+
+ if(verbose)
+ cout << "midpoint: " << x << endl;
+
+ real dx=dxold;
+ Stack->push(x);
+ f->call(Stack);
+ real y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dy=pop<real>(Stack);
+
+ Int j;
+ for(j=0; j < iterations; j++) {
+ if(((x-x2)*dy-y)*((x-x1)*dy-y) >= 0.0 || fabs(2.0*y) > fabs(dxold*dy)) {
+ dxold=dx;
+ dx=0.5*(x2-x1);
+ x=x1+dx;
+ if(verbose)
+ cout << "bisection: " << x << endl;
+ if(x1 == x) return x;
+ } else {
+ dxold=dx;
+ dx=y/dy;
+ real temp=x;
+ x -= dx;
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+ if(temp == x) return x;
+ }
+ if(fabs(dx) < fuzz*fabs(x)) return x;
+
+ Stack->push(x);
+ f->call(Stack);
+ y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ dy=pop<real>(Stack);
+
+ if(y < 0.0) x1=x;
+ else x2=x;
+ }
+ if(verbose)
+ cout.precision(oldPrec);
+ return (j == iterations) ? DBL_MAX : x;
+}
+
+// Find a root for the specified continuous (but not necessarily
+// differentiable) function. Whatever value t is returned, it is guaranteed
+// that t is within [a, b] and within tolerance of a sign change.
+// An error is thrown if fa and fb are both positive or both negative.
+//
+// In this implementation, the binary search is interleaved
+// with a modified version of quadratic interpolation.
+// This is a C++ port of the Asymptote routine written by Charles Staats III.
+real _findroot(callableReal *f, real a, real b, real tolerance,
+ real fa, real fb)
+{
+ if(fa == 0.0) return a;
+ if(fb == 0.0) return b;
+
+ const char* oppsign="fa and fb must have opposite signs";
+ int sign;
+
+ if(fa < 0.0) {
+ if(fb < 0.0) error(oppsign);
+ sign=1;
+ } else {
+ if(fb > 0.0) error(oppsign);
+ fa=-fa;
+ fb=-fb;
+ sign=-1;
+ }
+
+ real t=a;
+ real ft=fa;
+ real twicetolerance=2.0*tolerance;
+
+ while(b-a > tolerance) {
+ t=(a+b)*0.5;
+
+ Stack->push(t);
+ f->call(Stack);
+ ft=sign*pop<double>(Stack);
+ if(ft == 0.0) return t;
+
+ // If halving the interval already puts us within tolerance,
+ // don't bother with the interpolation step.
+ if(b-a >= twicetolerance) {
+
+ real factor=1.0/(b-a);
+ real q_A=2.0*(fa-2.0*ft+fb)*factor*factor;
+ real q_B=(fb-fa)*factor;
+ quadraticroots Q=quadraticroots(q_A,q_B,ft);
+
+ // If the interpolation somehow failed, continue on to the next binary
+ // search step. This may or may not be possible, depending on what
+ // theoretical guarantees are provided by the quadraticroots function.
+
+ real root;
+ bool found=Q.roots > 0;
+ if(found) {
+ root=t+Q.t1;
+ if(root <= a || root >= b) {
+ if(Q.roots == 1) found=false;
+ else {
+ root=t+Q.t2;
+ if(root <= a || root >= b) found=false;
+ }
+ }
+ }
+
+ if(found) {
+ if(ft > 0.0) {
+ b=t;
+ fb=ft;
+ } else {
+ a=t;
+ fa=ft;
+ }
+
+ t=root;
+
+ // If the interpolated value is close to one edge of
+ // the interval, move it farther away from the edge in
+ // an effort to catch the root in the middle.
+ real margin=(b-a)*1.0e-3;
+ if(t-a < margin) t=a+2.0*(t-a);
+ else if(b-t < margin) t=b-2.0*(b-t);
+
+ Stack->push(t);
+ f->call(Stack);
+ ft=sign*pop<double>(Stack);
+
+ if(ft == 0.0) return t;
+ }
+ }
+
+ if(ft > 0.0) {
+ b=t;
+ fb=ft;
+ } else if(ft < 0.0) {
+ a=t;
+ fa=ft;
+ }
+ }
+ return a-(b-a)/(fb-fa)*fa;
+}
+
+real simpson(callableReal *f, real a, real b, real acc=DBL_EPSILON,
+ real dxmax=0)
+{
+ real integral;
+ if(dxmax <= 0) dxmax=fabs(b-a);
+ callable *oldFunc=Func;
+ Func=f;
+ FuncStack=Stack;
+ if(!simpson(integral,wrapFunction,a,b,acc,dxmax))
+ error("nesting capacity exceeded in simpson");
+ Func=oldFunc;
+ return integral;
+}
+
+// Compute the fast Fourier transform of a pair array
+pairarray* fft(pairarray *a, Int sign=1)
+{
+#ifdef HAVE_LIBFFTW3
+ unsigned n=(unsigned) checkArray(a);
+ array *c=new array(n);
+ if(n) {
+ Complex *f=utils::ComplexAlign(n);
+ fftwpp::fft1d Forward(n,intcast(sign),f);
+
+ for(size_t i=0; i < n; i++) {
+ pair z=read<pair>(a,i);
+ f[i]=Complex(z.getx(),z.gety());
+ }
+ Forward.fft(f);
+
+ for(size_t i=0; i < n; i++) {
+ Complex z=f[i];
+ (*c)[i]=pair(z.real(),z.imag());
+ }
+ utils::deleteAlign(f);
+ }
+#else
+ unused(a);
+ unused(&sign);
+ array *c=new array(0);
+ error("Please install fftw3, run ./configure, and recompile");
+#endif // HAVE_LIBFFTW3
+ return c;
+}
+
+Intarray2 *triangulate(pairarray *z)
+{
+ size_t nv=checkArray(z);
+// Call robust version of Gilles Dumoulin's port of Paul Bourke's
+// triangulation code.
+
+ XYZ *pxyz=new XYZ[nv+3];
+ ITRIANGLE *V=new ITRIANGLE[4*nv];
+
+ for(size_t i=0; i < nv; ++i) {
+ pair w=read<pair>(z,i);
+ pxyz[i].p[0]=w.getx();
+ pxyz[i].p[1]=w.gety();
+ pxyz[i].i=(Int) i;
+ }
+
+ Int ntri;
+ Triangulate((Int) nv,pxyz,V,ntri,true,false);
+
+ size_t nt=(size_t) ntri;
+ array *t=new array(nt);
+ for(size_t i=0; i < nt; ++i) {
+ array *ti=new array(3);
+ (*t)[i]=ti;
+ ITRIANGLE *Vi=V+i;
+ (*ti)[0]=pxyz[Vi->p1].i;
+ (*ti)[1]=pxyz[Vi->p2].i;
+ (*ti)[2]=pxyz[Vi->p3].i;
+ }
+
+ delete[] V;
+ delete[] pxyz;
+ return t;
+}
+
+real norm(realarray *a)
+{
+ size_t n=checkArray(a);
+ real M=0.0;
+ for(size_t i=0; i < n; ++i) {
+ real x=fabs(vm::read<real>(a,i));
+ if(x > M) M=x;
+ }
+ return M;
+}
+
+real norm(realarray2 *a)
+{
+ size_t n=checkArray(a);
+ real M=0.0;
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=fabs(vm::read<real>(ai,j));
+ if(a > M) M=a;
+ }
+ }
+ return M;
+}
+
+real norm(triplearray2 *a)
+{
+ size_t n=checkArray(a);
+ real M=0.0;
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=vm::read<triple>(ai,j).abs2();
+ if(a > M) M=a;
+ }
+ }
+ return sqrt(M);
+}
+
+real change2(triplearray2 *a)
+{
+ size_t n=checkArray(a);
+ if(n == 0) return 0.0;
+
+ vm::array *a0=vm::read<vm::array*>(a,0);
+ size_t m=checkArray(a0);
+ if(m == 0) return 0.0;
+ triple a00=vm::read<triple>(a0,0);
+ real M=0.0;
+
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=(vm::read<triple>(ai,j)-a00).abs2();
+ if(a > M) M=a;
+ }
+ }
+ return M;
+}
+
+triple minbezier(triplearray2 *P, triple b)
+{
+ size_t N;
+ real *A=copyTripleArray2Components(P,N);
+ bound_double *B=bounddouble(N);
+ b=triple(B(A,::min,b.getx(),Fuzz*norm(A,N),maxdepth),
+ B(A+N,::min,b.gety(),Fuzz*norm(A+N,N),maxdepth),
+ B(A+2*N,::min,b.getz(),Fuzz*norm(A+2*N,N),maxdepth));
+ delete[] A;
+ return b;
+}
+
+triple maxbezier(triplearray2 *P, triple b)
+{
+ size_t N;
+ real *A=copyTripleArray2Components(P,N);
+ bound_double *B=bounddouble(N);
+ b=triple(B(A,::max,b.getx(),Fuzz*norm(A,N),maxdepth),
+ B(A+N,::max,b.gety(),Fuzz*norm(A+N,N),maxdepth),
+ B(A+2*N,::max,b.getz(),Fuzz*norm(A+2*N,N),maxdepth));
+ delete[] A;
+ return b;
+}
+
+pair minratio(triplearray2 *P, pair b)
+{
+ size_t N;
+ triple *A=copyTripleArray2C(P,N);
+ real fuzz=Fuzz*norm(A,N);
+ bound_triple *B=boundtriple(N);
+ b=pair(B(A,::min,xratio,b.getx(),fuzz,maxdepth),
+ B(A,::min,yratio,b.gety(),fuzz,maxdepth));
+ delete[] A;
+ return b;
+}
+
+pair maxratio(triplearray2 *P, pair b)
+{
+ size_t N;
+ triple *A=copyTripleArray2C(P,N);
+ bound_triple *B=boundtriple(N);
+ real fuzz=Fuzz*norm(A,N);
+ b=pair(B(A,::max,xratio,b.getx(),fuzz,maxdepth),
+ B(A,::max,yratio,b.gety(),fuzz,maxdepth));
+ delete[] A;
+ return b;
+}
+
+realarray *_projection()
+{
+#ifdef HAVE_GL
+ array *a=new array(14);
+ gl::projection P=gl::camera();
+ size_t k=0;
+ (*a)[k++]=P.orthographic ? 1.0 : 0.0;
+
+ triple camera=P.camera;
+ (*a)[k++]=camera.getx();
+ (*a)[k++]=camera.gety();
+ (*a)[k++]=camera.getz();
+
+ triple up=P.up;
+ (*a)[k++]=up.getx();
+ (*a)[k++]=up.gety();
+ (*a)[k++]=up.getz();
+
+ triple target=P.target;
+ (*a)[k++]=target.getx();
+ (*a)[k++]=target.gety();
+ (*a)[k++]=target.getz();
+
+ (*a)[k++]=P.zoom;
+ (*a)[k++]=P.angle;
+
+ (*a)[k++]=P.viewportshift.getx();
+ (*a)[k++]=P.viewportshift.gety();
+#endif
+ return new array(0);
+}
diff --git a/graphics/asymptote/runbacktrace.cc b/graphics/asymptote/runbacktrace.cc
new file mode 100644
index 0000000000..002debf8f6
--- /dev/null
+++ b/graphics/asymptote/runbacktrace.cc
@@ -0,0 +1,117 @@
+/***** Autogenerated from runbacktrace.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runbacktrace.in"
+/*****
+ * backtrace.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Runtime functions for printing garbage collector backtraces.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 11 "runbacktrace.in"
+// No extra code for .cc file.
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runbacktrace.symbols.h"
+
+#endif
+namespace run {
+#line 16 "runbacktrace.in"
+// void generate_random_backtrace();
+void gen_runbacktrace0(stack *)
+{
+#line 17 "runbacktrace.in"
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_generate_random_backtrace();
+#else
+ error("generate_random_backtrace() requires ./configure --enable-gc-debug");
+#endif
+}
+
+#line 25 "runbacktrace.in"
+// void print_random_addresses(Int n=1);
+void gen_runbacktrace1(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,1);
+#line 26 "runbacktrace.in"
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_gcollect();
+ for (Int i=0; i < n; ++i)
+ GC_debug_print_heap_obj_proc(GC_base(GC_generate_random_valid_address()));
+#else
+ error("print_random_addresses() requires ./configure --enable-gc-debug");
+ unused(&n); // Avoid unused variable warning message.
+#endif
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runbacktrace_venv(venv &ve)
+{
+#line 16 "runbacktrace.in"
+ addFunc(ve, run::gen_runbacktrace0, primVoid(), SYM(generate_random_backtrace));
+#line 25 "runbacktrace.in"
+ addFunc(ve, run::gen_runbacktrace1, primVoid(), SYM(print_random_addresses), formal(primInt(), SYM(n), true, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runbacktrace.h b/graphics/asymptote/runbacktrace.h
new file mode 100644
index 0000000000..9ddef1a996
--- /dev/null
+++ b/graphics/asymptote/runbacktrace.h
@@ -0,0 +1,8 @@
+/***** Autogenerated from runbacktrace.in; changes will be overwritten *****/
+
+#ifndef runbacktrace_H
+#define runbacktrace_H
+namespace run {
+}
+
+#endif // runbacktrace_H
diff --git a/graphics/asymptote/runbacktrace.in b/graphics/asymptote/runbacktrace.in
new file mode 100644
index 0000000000..416ac43716
--- /dev/null
+++ b/graphics/asymptote/runbacktrace.in
@@ -0,0 +1,35 @@
+/*****
+ * backtrace.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Runtime functions for printing garbage collector backtraces.
+ *
+ *****/
+
+// No extra types defined.
+
+// No extra code for .cc file.
+
+// Autogenerated routines:
+
+
+void generate_random_backtrace()
+{
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_generate_random_backtrace();
+#else
+ error("generate_random_backtrace() requires ./configure --enable-gc-debug");
+#endif
+}
+
+void print_random_addresses(Int n=1)
+{
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_gcollect();
+ for (Int i=0; i < n; ++i)
+ GC_debug_print_heap_obj_proc(GC_base(GC_generate_random_valid_address()));
+#else
+ error("print_random_addresses() requires ./configure --enable-gc-debug");
+ unused(&n); // Avoid unused variable warning message.
+#endif
+}
diff --git a/graphics/asymptote/runfile.cc b/graphics/asymptote/runfile.cc
new file mode 100644
index 0000000000..74ad76fdd7
--- /dev/null
+++ b/graphics/asymptote/runfile.cc
@@ -0,0 +1,688 @@
+/***** Autogenerated from runfile.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runfile.in"
+/*****
+ * runfile.in
+ *
+ * Runtime functions for file operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 10 "runfile.in"
+#include "fileio.h"
+#include "callable.h"
+#include "triple.h"
+#include "array.h"
+
+#ifdef __CYGWIN__
+extern "C" int mkstemp(char *c);
+#endif
+
+using namespace camp;
+using namespace settings;
+using namespace vm;
+
+string commentchar="#";
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runfile.symbols.h"
+
+#endif
+namespace run {
+#line 28 "runfile.in"
+// bool ==(file *a, file *b);
+void gen_runfile0(stack *Stack)
+{
+ file * b=vm::pop<file *>(Stack);
+ file * a=vm::pop<file *>(Stack);
+#line 29 "runfile.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 33 "runfile.in"
+// bool !=(file *a, file *b);
+void gen_runfile1(stack *Stack)
+{
+ file * b=vm::pop<file *>(Stack);
+ file * a=vm::pop<file *>(Stack);
+#line 34 "runfile.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 38 "runfile.in"
+void nullFile(stack *Stack)
+{
+#line 39 "runfile.in"
+ {Stack->push<file*>(&camp::nullfile); return;}
+}
+
+#line 43 "runfile.in"
+// file* input(string name=emptystring, bool check=true, string comment=commentchar, string mode=emptystring);
+void gen_runfile3(stack *Stack)
+{
+ string mode=vm::pop<string>(Stack,emptystring);
+ string comment=vm::pop<string>(Stack,commentchar);
+ bool check=vm::pop<bool>(Stack,true);
+ string name=vm::pop<string>(Stack,emptystring);
+#line 45 "runfile.in"
+ file *f=NULL;
+ if(mode == "binary") {
+ f=new ibfile(name,check);
+ } else if(mode == "xdr") {
+#ifdef HAVE_RPC_RPC_H
+ f=new ixfile(name,check);
+#else
+ ostringstream buf;
+ buf << name << ": XDR read support not enabled";
+ error(buf);
+#endif
+ } else if(mode == "") {
+ char c=comment.empty() ? (char) 0 : comment[0];
+ f=new ifile(name,c,check);
+ } else {
+ f=NULL;
+ ostringstream buf;
+ buf << name << ": invalid file mode '" << mode << "'";
+ error(buf);
+ }
+
+ f->open();
+ {Stack->push<file*>(f); return;}
+}
+
+#line 71 "runfile.in"
+// file* output(string name=emptystring, bool update=false, string comment=commentchar, string mode=emptystring);
+void gen_runfile4(stack *Stack)
+{
+ string mode=vm::pop<string>(Stack,emptystring);
+ string comment=vm::pop<string>(Stack,commentchar);
+ bool update=vm::pop<bool>(Stack,false);
+ string name=vm::pop<string>(Stack,emptystring);
+#line 73 "runfile.in"
+ file *f=NULL;
+ if(mode == "pipe") {
+ f=new opipe(name);
+ } else if(mode == "binary") {
+ if(update) f=new iobfile(name);
+ else f=new obfile(name);
+ } else if(mode == "xdr") {
+#ifdef HAVE_RPC_RPC_H
+ if(update)
+ f=new ioxfile(name);
+ else f=new oxfile(name);
+#else
+ ostringstream buf;
+ buf << name << ": XDR write support not enabled";
+ error(buf);
+#endif
+ } else if(mode == "") {
+ if(update) {
+ char c=comment.empty() ? (char) 0 : comment[0];
+ f=new iofile(name,c);
+ } else f=new ofile(name);
+ } else {
+ f=NULL;
+ ostringstream buf;
+ buf << name << ": invalid file mode '" << mode << "'";
+ error(buf);
+ }
+
+ f->open();
+ if(update) f->seek(0,false);
+
+ {Stack->push<file*>(f); return;}
+}
+
+#line 108 "runfile.in"
+// bool eof(file *f);
+void gen_runfile5(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 109 "runfile.in"
+ {Stack->push<bool>(f->eof()); return;}
+}
+
+#line 113 "runfile.in"
+// bool eol(file *f);
+void gen_runfile6(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 114 "runfile.in"
+ {Stack->push<bool>(f->eol()); return;}
+}
+
+#line 118 "runfile.in"
+// bool error(file *f);
+void gen_runfile7(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 119 "runfile.in"
+ {Stack->push<bool>(f->error()); return;}
+}
+
+#line 123 "runfile.in"
+// void clear(file *f);
+void gen_runfile8(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 124 "runfile.in"
+ f->clear();
+}
+
+#line 128 "runfile.in"
+// void close(file *f);
+void gen_runfile9(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 129 "runfile.in"
+ f->close();
+}
+
+#line 133 "runfile.in"
+// Int precision(file *f=NULL, Int digits=0);
+void gen_runfile10(stack *Stack)
+{
+ Int digits=vm::pop<Int>(Stack,0);
+ file * f=vm::pop<file *>(Stack,NULL);
+#line 134 "runfile.in"
+ if(f == 0) f=&camp::Stdout;
+ {Stack->push<Int>(f->precision(digits)); return;}
+}
+
+#line 139 "runfile.in"
+// void flush(file *f);
+void gen_runfile11(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 140 "runfile.in"
+ f->flush();
+}
+
+#line 144 "runfile.in"
+// string getc(file *f);
+void gen_runfile12(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 145 "runfile.in"
+ char c=0;
+ if(f->isOpen()) f->read(c);
+ static char str[1];
+ str[0]=c;
+ {Stack->push<string>(string(str)); return;}
+}
+
+#line 153 "runfile.in"
+// Int tell(file *f);
+void gen_runfile13(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 154 "runfile.in"
+ {Stack->push<Int>(f->tell()); return;}
+}
+
+#line 158 "runfile.in"
+// void seek(file *f, Int pos);
+void gen_runfile14(stack *Stack)
+{
+ Int pos=vm::pop<Int>(Stack);
+ file * f=vm::pop<file *>(Stack);
+#line 159 "runfile.in"
+ f->seek(pos,pos >= 0);
+}
+
+#line 163 "runfile.in"
+// void seekeof(file *f);
+void gen_runfile15(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 164 "runfile.in"
+ f->seek(0,false);
+}
+
+#line 168 "runfile.in"
+void namePart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 169 "runfile.in"
+ {Stack->push<string>(f.filename()); return;}
+}
+
+#line 173 "runfile.in"
+void modePart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 174 "runfile.in"
+ {Stack->push<string>(f.FileMode()); return;}
+}
+
+// Set file dimensions
+#line 179 "runfile.in"
+void dimensionSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ Int nz=vm::pop<Int>(Stack,-1);
+ Int ny=vm::pop<Int>(Stack,-1);
+ Int nx=vm::pop<Int>(Stack,-1);
+#line 180 "runfile.in"
+ f->dimension(nx,ny,nz);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 185 "runfile.in"
+void dimensionSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 186 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(dimensionSetHelper),f)); return;}
+}
+
+#line 190 "runfile.in"
+void dimensionPart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 191 "runfile.in"
+ array *a=new array(3);
+ (*a)[0]=f.Nx();
+ (*a)[1]=f.Ny();
+ (*a)[2]=f.Nz();
+ {Stack->push<array*>(a); return;}
+}
+
+// Set file f to read arrays in line-at-a-time mode
+#line 200 "runfile.in"
+void lineSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ bool b=vm::pop<bool>(Stack,true);
+#line 201 "runfile.in"
+ f->LineMode(b);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 206 "runfile.in"
+void lineSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 207 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(lineSetHelper),f)); return;}
+}
+
+#line 211 "runfile.in"
+void linePart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 212 "runfile.in"
+ {Stack->push<bool>(f.LineMode()); return;}
+}
+
+// Set file to read comma-separated values
+#line 217 "runfile.in"
+void csvSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ bool b=vm::pop<bool>(Stack,true);
+#line 218 "runfile.in"
+ f->CSVMode(b);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 223 "runfile.in"
+void csvSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 224 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(csvSetHelper),f)); return;}
+}
+
+#line 228 "runfile.in"
+void csvPart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 229 "runfile.in"
+ {Stack->push<bool>(f.CSVMode()); return;}
+}
+
+// Set file to read whitespace-separated values
+#line 234 "runfile.in"
+void wordSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ bool b=vm::pop<bool>(Stack,true);
+#line 235 "runfile.in"
+ f->WordMode(b);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 240 "runfile.in"
+void wordSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 241 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(wordSetHelper),f)); return;}
+}
+
+#line 245 "runfile.in"
+void wordPart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 246 "runfile.in"
+ {Stack->push<bool>(f.WordMode()); return;}
+}
+
+// Set file to read/write single precision real XDR values.
+#line 251 "runfile.in"
+void singlerealSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ bool b=vm::pop<bool>(Stack,true);
+#line 252 "runfile.in"
+ f->SingleReal(b);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 257 "runfile.in"
+void singlerealSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 258 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(singlerealSetHelper),f)); return;}
+}
+
+#line 262 "runfile.in"
+void singlerealPart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 263 "runfile.in"
+ {Stack->push<bool>(f.SingleReal()); return;}
+}
+
+// Set file to read/write single precision int XDR values.
+#line 268 "runfile.in"
+void singleintSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ bool b=vm::pop<bool>(Stack,true);
+#line 269 "runfile.in"
+ f->SingleInt(b);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 274 "runfile.in"
+void singleintSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 275 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(singleintSetHelper),f)); return;}
+}
+
+#line 279 "runfile.in"
+void singleintPart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 280 "runfile.in"
+ {Stack->push<bool>(f.SingleInt()); return;}
+}
+
+// Set file to read/write signed int XDR values.
+#line 285 "runfile.in"
+void signedintSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ bool b=vm::pop<bool>(Stack,true);
+#line 286 "runfile.in"
+ f->SignedInt(b);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 291 "runfile.in"
+void signedintSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 292 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(signedintSetHelper),f)); return;}
+}
+
+#line 296 "runfile.in"
+void signedintPart(stack *Stack)
+{
+ file f=vm::pop<file>(Stack);
+#line 297 "runfile.in"
+ {Stack->push<bool>(f.SignedInt()); return;}
+}
+
+// Set file to read an arrayi (i int sizes followed by an i-dimensional array)
+#line 302 "runfile.in"
+void readSetHelper(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+ Int i=vm::pop<Int>(Stack);
+#line 303 "runfile.in"
+ switch(i) {
+ case 1:
+ f->dimension(-2);
+ break;
+
+ case 2:
+ f->dimension(-2,-2);
+ break;
+
+ case 3:
+ f->dimension(-2,-2,-2);
+ break;
+
+ default:
+ f->dimension();
+ }
+
+ {Stack->push<file*>(f); return;}
+}
+
+#line 324 "runfile.in"
+void readSet(stack *Stack)
+{
+ file * f=vm::pop<file *>(Stack);
+#line 325 "runfile.in"
+ {Stack->push<callable*>(new thunk(new bfunc(readSetHelper),f)); return;}
+}
+
+// Delete file named s.
+#line 330 "runfile.in"
+// Int delete(string s);
+void gen_runfile41(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 331 "runfile.in"
+ s=outpath(s);
+ Int rc=unlink(s.c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Deleted " << s << endl;
+ {Stack->push<Int>(rc); return;}
+}
+
+// Rename file "from" to file "to".
+#line 340 "runfile.in"
+// Int rename(string from, string to);
+void gen_runfile42(stack *Stack)
+{
+ string to=vm::pop<string>(Stack);
+ string from=vm::pop<string>(Stack);
+#line 341 "runfile.in"
+ from=outpath(from);
+ to=outpath(to);
+ Int rc=rename(from.c_str(),to.c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Renamed " << from << " to " << to << endl;
+ {Stack->push<Int>(rc); return;}
+}
+
+// Create a unique temporary file name.
+#line 351 "runfile.in"
+// string mktemp(string s);
+void gen_runfile43(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 352 "runfile.in"
+ char *S=Strdup(s+"XXXXXX");
+ int fd=mkstemp(S);
+ if(fd < 0) {
+ ostringstream buf;
+ buf << "Could not create unique temporary filename based on " << s;
+ error(buf);
+ }
+ {Stack->push<string>(S); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runfile_venv(venv &ve)
+{
+#line 28 "runfile.in"
+ addFunc(ve, run::gen_runfile0, primBoolean(), SYM_EQ, formal(primFile(), SYM(a), false, false), formal(primFile(), SYM(b), false, false));
+#line 33 "runfile.in"
+ addFunc(ve, run::gen_runfile1, primBoolean(), SYM_NEQ, formal(primFile(), SYM(a), false, false), formal(primFile(), SYM(b), false, false));
+#line 38 "runfile.in"
+ REGISTER_BLTIN(run::nullFile,"nullFile");
+#line 43 "runfile.in"
+ addFunc(ve, run::gen_runfile3, primFile(), SYM(input), formal(primString() , SYM(name), true, false), formal(primBoolean(), SYM(check), true, false), formal(primString() , SYM(comment), true, false), formal(primString() , SYM(mode), true, false));
+#line 71 "runfile.in"
+ addFunc(ve, run::gen_runfile4, primFile(), SYM(output), formal(primString() , SYM(name), true, false), formal(primBoolean(), SYM(update), true, false), formal(primString() , SYM(comment), true, false), formal(primString() , SYM(mode), true, false));
+#line 108 "runfile.in"
+ addFunc(ve, run::gen_runfile5, primBoolean(), SYM(eof), formal(primFile(), SYM(f), false, false));
+#line 113 "runfile.in"
+ addFunc(ve, run::gen_runfile6, primBoolean(), SYM(eol), formal(primFile(), SYM(f), false, false));
+#line 118 "runfile.in"
+ addFunc(ve, run::gen_runfile7, primBoolean(), SYM(error), formal(primFile(), SYM(f), false, false));
+#line 123 "runfile.in"
+ addFunc(ve, run::gen_runfile8, primVoid(), SYM(clear), formal(primFile(), SYM(f), false, false));
+#line 128 "runfile.in"
+ addFunc(ve, run::gen_runfile9, primVoid(), SYM(close), formal(primFile(), SYM(f), false, false));
+#line 133 "runfile.in"
+ addFunc(ve, run::gen_runfile10, primInt(), SYM(precision), formal(primFile(), SYM(f), true, false), formal(primInt(), SYM(digits), true, false));
+#line 139 "runfile.in"
+ addFunc(ve, run::gen_runfile11, primVoid(), SYM(flush), formal(primFile(), SYM(f), false, false));
+#line 144 "runfile.in"
+ addFunc(ve, run::gen_runfile12, primString() , SYM(getc), formal(primFile(), SYM(f), false, false));
+#line 153 "runfile.in"
+ addFunc(ve, run::gen_runfile13, primInt(), SYM(tell), formal(primFile(), SYM(f), false, false));
+#line 158 "runfile.in"
+ addFunc(ve, run::gen_runfile14, primVoid(), SYM(seek), formal(primFile(), SYM(f), false, false), formal(primInt(), SYM(pos), false, false));
+#line 163 "runfile.in"
+ addFunc(ve, run::gen_runfile15, primVoid(), SYM(seekeof), formal(primFile(), SYM(f), false, false));
+#line 168 "runfile.in"
+ REGISTER_BLTIN(run::namePart,"namePart");
+#line 173 "runfile.in"
+ REGISTER_BLTIN(run::modePart,"modePart");
+#line 178 "runfile.in"
+ REGISTER_BLTIN(run::dimensionSetHelper,"dimensionSetHelper");
+#line 185 "runfile.in"
+ REGISTER_BLTIN(run::dimensionSet,"dimensionSet");
+#line 190 "runfile.in"
+ REGISTER_BLTIN(run::dimensionPart,"dimensionPart");
+#line 199 "runfile.in"
+ REGISTER_BLTIN(run::lineSetHelper,"lineSetHelper");
+#line 206 "runfile.in"
+ REGISTER_BLTIN(run::lineSet,"lineSet");
+#line 211 "runfile.in"
+ REGISTER_BLTIN(run::linePart,"linePart");
+#line 216 "runfile.in"
+ REGISTER_BLTIN(run::csvSetHelper,"csvSetHelper");
+#line 223 "runfile.in"
+ REGISTER_BLTIN(run::csvSet,"csvSet");
+#line 228 "runfile.in"
+ REGISTER_BLTIN(run::csvPart,"csvPart");
+#line 233 "runfile.in"
+ REGISTER_BLTIN(run::wordSetHelper,"wordSetHelper");
+#line 240 "runfile.in"
+ REGISTER_BLTIN(run::wordSet,"wordSet");
+#line 245 "runfile.in"
+ REGISTER_BLTIN(run::wordPart,"wordPart");
+#line 250 "runfile.in"
+ REGISTER_BLTIN(run::singlerealSetHelper,"singlerealSetHelper");
+#line 257 "runfile.in"
+ REGISTER_BLTIN(run::singlerealSet,"singlerealSet");
+#line 262 "runfile.in"
+ REGISTER_BLTIN(run::singlerealPart,"singlerealPart");
+#line 267 "runfile.in"
+ REGISTER_BLTIN(run::singleintSetHelper,"singleintSetHelper");
+#line 274 "runfile.in"
+ REGISTER_BLTIN(run::singleintSet,"singleintSet");
+#line 279 "runfile.in"
+ REGISTER_BLTIN(run::singleintPart,"singleintPart");
+#line 284 "runfile.in"
+ REGISTER_BLTIN(run::signedintSetHelper,"signedintSetHelper");
+#line 291 "runfile.in"
+ REGISTER_BLTIN(run::signedintSet,"signedintSet");
+#line 296 "runfile.in"
+ REGISTER_BLTIN(run::signedintPart,"signedintPart");
+#line 301 "runfile.in"
+ REGISTER_BLTIN(run::readSetHelper,"readSetHelper");
+#line 324 "runfile.in"
+ REGISTER_BLTIN(run::readSet,"readSet");
+#line 329 "runfile.in"
+ addFunc(ve, run::gen_runfile41, primInt(), SYM(delete), formal(primString() , SYM(s), false, false));
+#line 339 "runfile.in"
+ addFunc(ve, run::gen_runfile42, primInt(), SYM(rename), formal(primString() , SYM(from), false, false), formal(primString() , SYM(to), false, false));
+#line 350 "runfile.in"
+ addFunc(ve, run::gen_runfile43, primString() , SYM(mktemp), formal(primString() , SYM(s), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runfile.h b/graphics/asymptote/runfile.h
new file mode 100644
index 0000000000..f523c58815
--- /dev/null
+++ b/graphics/asymptote/runfile.h
@@ -0,0 +1,34 @@
+/***** Autogenerated from runfile.in; changes will be overwritten *****/
+
+#ifndef runfile_H
+#define runfile_H
+namespace run {
+void nullFile(vm::stack *);
+void namePart(vm::stack *);
+void modePart(vm::stack *);
+void dimensionSetHelper(vm::stack *);
+void dimensionSet(vm::stack *);
+void dimensionPart(vm::stack *);
+void lineSetHelper(vm::stack *);
+void lineSet(vm::stack *);
+void linePart(vm::stack *);
+void csvSetHelper(vm::stack *);
+void csvSet(vm::stack *);
+void csvPart(vm::stack *);
+void wordSetHelper(vm::stack *);
+void wordSet(vm::stack *);
+void wordPart(vm::stack *);
+void singlerealSetHelper(vm::stack *);
+void singlerealSet(vm::stack *);
+void singlerealPart(vm::stack *);
+void singleintSetHelper(vm::stack *);
+void singleintSet(vm::stack *);
+void singleintPart(vm::stack *);
+void signedintSetHelper(vm::stack *);
+void signedintSet(vm::stack *);
+void signedintPart(vm::stack *);
+void readSetHelper(vm::stack *);
+void readSet(vm::stack *);
+}
+
+#endif // runfile_H
diff --git a/graphics/asymptote/runfile.in b/graphics/asymptote/runfile.in
new file mode 100644
index 0000000000..e51b3b76ea
--- /dev/null
+++ b/graphics/asymptote/runfile.in
@@ -0,0 +1,361 @@
+/*****
+ * runfile.in
+ *
+ * Runtime functions for file operations.
+ *
+ *****/
+
+file* => primFile()
+
+#include "fileio.h"
+#include "callable.h"
+#include "triple.h"
+#include "array.h"
+
+#ifdef __CYGWIN__
+extern "C" int mkstemp(char *c);
+#endif
+
+using namespace camp;
+using namespace settings;
+using namespace vm;
+
+string commentchar="#";
+
+// Autogenerated routines:
+
+
+bool ==(file *a, file *b)
+{
+ return a == b;
+}
+
+bool !=(file *a, file *b)
+{
+ return a != b;
+}
+
+file* :nullFile()
+{
+ return &camp::nullfile;
+}
+
+file* input(string name=emptystring, bool check=true,
+ string comment=commentchar, string mode=emptystring)
+{
+ file *f=NULL;
+ if(mode == "binary") {
+ f=new ibfile(name,check);
+ } else if(mode == "xdr") {
+#ifdef HAVE_RPC_RPC_H
+ f=new ixfile(name,check);
+#else
+ ostringstream buf;
+ buf << name << ": XDR read support not enabled";
+ error(buf);
+#endif
+ } else if(mode == "") {
+ char c=comment.empty() ? (char) 0 : comment[0];
+ f=new ifile(name,c,check);
+ } else {
+ f=NULL;
+ ostringstream buf;
+ buf << name << ": invalid file mode '" << mode << "'";
+ error(buf);
+ }
+
+ f->open();
+ return f;
+}
+
+file* output(string name=emptystring, bool update=false,
+ string comment=commentchar, string mode=emptystring)
+{
+ file *f=NULL;
+ if(mode == "pipe") {
+ f=new opipe(name);
+ } else if(mode == "binary") {
+ if(update) f=new iobfile(name);
+ else f=new obfile(name);
+ } else if(mode == "xdr") {
+#ifdef HAVE_RPC_RPC_H
+ if(update)
+ f=new ioxfile(name);
+ else f=new oxfile(name);
+#else
+ ostringstream buf;
+ buf << name << ": XDR write support not enabled";
+ error(buf);
+#endif
+ } else if(mode == "") {
+ if(update) {
+ char c=comment.empty() ? (char) 0 : comment[0];
+ f=new iofile(name,c);
+ } else f=new ofile(name);
+ } else {
+ f=NULL;
+ ostringstream buf;
+ buf << name << ": invalid file mode '" << mode << "'";
+ error(buf);
+ }
+
+ f->open();
+ if(update) f->seek(0,false);
+
+ return f;
+}
+
+bool eof(file *f)
+{
+ return f->eof();
+}
+
+bool eol(file *f)
+{
+ return f->eol();
+}
+
+bool error(file *f)
+{
+ return f->error();
+}
+
+void clear(file *f)
+{
+ f->clear();
+}
+
+void close(file *f)
+{
+ f->close();
+}
+
+Int precision(file *f=NULL, Int digits=0)
+{
+ if(f == 0) f=&camp::Stdout;
+ return f->precision(digits);
+}
+
+void flush(file *f)
+{
+ f->flush();
+}
+
+string getc(file *f)
+{
+ char c=0;
+ if(f->isOpen()) f->read(c);
+ static char str[1];
+ str[0]=c;
+ return string(str);
+}
+
+Int tell(file *f)
+{
+ return f->tell();
+}
+
+void seek(file *f, Int pos)
+{
+ f->seek(pos,pos >= 0);
+}
+
+void seekeof(file *f)
+{
+ f->seek(0,false);
+}
+
+string :namePart(file f)
+{
+ return f.filename();
+}
+
+string :modePart(file f)
+{
+ return f.FileMode();
+}
+
+// Set file dimensions
+file* :dimensionSetHelper(Int nx=-1, Int ny=-1, Int nz=-1, file *f)
+{
+ f->dimension(nx,ny,nz);
+ return f;
+}
+
+callable* :dimensionSet(file *f)
+{
+ return new thunk(new bfunc(dimensionSetHelper),f);
+}
+
+array * :dimensionPart(file f)
+{
+ array *a=new array(3);
+ (*a)[0]=f.Nx();
+ (*a)[1]=f.Ny();
+ (*a)[2]=f.Nz();
+ return a;
+}
+
+// Set file f to read arrays in line-at-a-time mode
+file* :lineSetHelper(bool b=true, file *f)
+{
+ f->LineMode(b);
+ return f;
+}
+
+callable* :lineSet(file *f)
+{
+ return new thunk(new bfunc(lineSetHelper),f);
+}
+
+bool :linePart(file f)
+{
+ return f.LineMode();
+}
+
+// Set file to read comma-separated values
+file* :csvSetHelper(bool b=true, file *f)
+{
+ f->CSVMode(b);
+ return f;
+}
+
+callable* :csvSet(file *f)
+{
+ return new thunk(new bfunc(csvSetHelper),f);
+}
+
+bool :csvPart(file f)
+{
+ return f.CSVMode();
+}
+
+// Set file to read whitespace-separated values
+file* :wordSetHelper(bool b=true, file *f)
+{
+ f->WordMode(b);
+ return f;
+}
+
+callable* :wordSet(file *f)
+{
+ return new thunk(new bfunc(wordSetHelper),f);
+}
+
+bool :wordPart(file f)
+{
+ return f.WordMode();
+}
+
+// Set file to read/write single precision real XDR values.
+file* :singlerealSetHelper(bool b=true, file *f)
+{
+ f->SingleReal(b);
+ return f;
+}
+
+callable* :singlerealSet(file *f)
+{
+ return new thunk(new bfunc(singlerealSetHelper),f);
+}
+
+bool :singlerealPart(file f)
+{
+ return f.SingleReal();
+}
+
+// Set file to read/write single precision int XDR values.
+file* :singleintSetHelper(bool b=true, file *f)
+{
+ f->SingleInt(b);
+ return f;
+}
+
+callable* :singleintSet(file *f)
+{
+ return new thunk(new bfunc(singleintSetHelper),f);
+}
+
+bool :singleintPart(file f)
+{
+ return f.SingleInt();
+}
+
+// Set file to read/write signed int XDR values.
+file* :signedintSetHelper(bool b=true, file *f)
+{
+ f->SignedInt(b);
+ return f;
+}
+
+callable* :signedintSet(file *f)
+{
+ return new thunk(new bfunc(signedintSetHelper),f);
+}
+
+bool :signedintPart(file f)
+{
+ return f.SignedInt();
+}
+
+// Set file to read an arrayi (i int sizes followed by an i-dimensional array)
+file* :readSetHelper(Int i, file *f)
+{
+ switch(i) {
+ case 1:
+ f->dimension(-2);
+ break;
+
+ case 2:
+ f->dimension(-2,-2);
+ break;
+
+ case 3:
+ f->dimension(-2,-2,-2);
+ break;
+
+ default:
+ f->dimension();
+ }
+
+ return f;
+}
+
+callable* :readSet(file *f)
+{
+ return new thunk(new bfunc(readSetHelper),f);
+}
+
+// Delete file named s.
+Int delete(string s)
+{
+ s=outpath(s);
+ Int rc=unlink(s.c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Deleted " << s << endl;
+ return rc;
+}
+
+// Rename file "from" to file "to".
+Int rename(string from, string to)
+{
+ from=outpath(from);
+ to=outpath(to);
+ Int rc=rename(from.c_str(),to.c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Renamed " << from << " to " << to << endl;
+ return rc;
+}
+
+// Create a unique temporary file name.
+string mktemp(string s)
+{
+ char *S=Strdup(s+"XXXXXX");
+ int fd=mkstemp(S);
+ if(fd < 0) {
+ ostringstream buf;
+ buf << "Could not create unique temporary filename based on " << s;
+ error(buf);
+ }
+ return S;
+}
diff --git a/graphics/asymptote/runhistory.cc b/graphics/asymptote/runhistory.cc
new file mode 100644
index 0000000000..57e256f2f0
--- /dev/null
+++ b/graphics/asymptote/runhistory.cc
@@ -0,0 +1,321 @@
+/***** Autogenerated from runhistory.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runhistory.in"
+/*****
+ * runhistory.in
+ *
+ * Runtime functions for history operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 12 "runhistory.in"
+
+#include "array.h"
+#include "mathop.h"
+#include "builtin.h"
+
+using namespace camp;
+using namespace settings;
+using namespace vm;
+using namespace run;
+
+typedef array stringarray;
+using types::stringArray;
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#include <readline/readline.h>
+#include <readline/history.h>
+
+struct historyState {
+ bool store;
+ HISTORY_STATE state;
+};
+
+typedef mem::map<CONST string, historyState> historyMap_t;
+historyMap_t historyMap;
+static HISTORY_STATE history_save;
+
+// Store a deep copy of the current readline history in dest.
+void store_history(HISTORY_STATE *dest)
+{
+ HISTORY_STATE *src=history_get_history_state();
+ if(src) {
+ *dest=*src;
+ for(Int i=0; i < src->length; ++i)
+ dest->entries[i]=src->entries[i];
+ free(src);
+ }
+}
+
+stringarray* get_history(Int n)
+{
+ int N=intcast(n);
+ if(N <= 0) N=history_length;
+ else N=Min(N,history_length);
+ array *a=new array((size_t) N);
+ int offset=history_length-N+1;
+ for(int i=0; i < N; ++i) {
+ HIST_ENTRY *last=history_get(offset+i);
+ string s=last ? last->line : "";
+ (*a)[i]=s;
+ }
+ return a;
+}
+
+string historyfilename(const string &name)
+{
+ return historyname+"_"+name;
+}
+#endif
+
+namespace run {
+
+extern string emptystring;
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+
+void init_readline(bool tabcompletion)
+{
+ rl_bind_key('\t',tabcompletion ? rl_complete : rl_insert);
+}
+#endif
+
+void cleanup()
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ int nlines=intcast(getSetting<Int>("historylines"));
+ for(historyMap_t::iterator h=historyMap.begin(); h != historyMap.end();
+ ++h) {
+ history_set_history_state(&h->second.state);
+ if(h->second.store) {
+ stifle_history(nlines);
+ write_history(historyfilename(h->first).c_str());
+ unstifle_history();
+ }
+ }
+ history_set_history_state(&history_save);
+#endif
+#ifdef HAVE_LIBGSL
+ trans::GSLrngFree();
+#endif
+}
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runhistory.symbols.h"
+
+#endif
+namespace run {
+// Return the last n lines of the history named name.
+#line 109 "runhistory.in"
+// stringarray* history(string name, Int n=1);
+void gen_runhistory0(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,1);
+ string name=vm::pop<string>(Stack);
+#line 110 "runhistory.in"
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ bool newhistory=historyMap.find(name) == historyMap.end();
+
+ string filename;
+
+ if(newhistory) {
+ filename=historyfilename(name);
+ std::ifstream exists(filename.c_str());
+ if(!exists) {Stack->push<stringarray*>(new array(0)); return;}
+ }
+
+ store_history(&history_save);
+ HISTORY_STATE& history=historyMap[name].state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(filename.c_str());
+
+ array *a=get_history(n);
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+
+ {Stack->push<stringarray*>(a); return;}
+#else
+ unused(&n);
+ {Stack->push<stringarray*>(new array(0)); return;}
+#endif
+}
+
+// Return the last n lines of the interactive history.
+#line 142 "runhistory.in"
+// stringarray* history(Int n=0);
+void gen_runhistory1(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,0);
+#line 143 "runhistory.in"
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ {Stack->push<stringarray*>(get_history(n)); return;}
+#else
+ unused(&n);
+ {Stack->push<stringarray*>(new array(0)); return;}
+#endif
+}
+
+// Prompt for a string using prompt, the GNU readline library, and a
+// local history named name.
+#line 154 "runhistory.in"
+// string readline(string prompt=emptystring, string name=emptystring, bool tabcompletion=false);
+void gen_runhistory2(stack *Stack)
+{
+ bool tabcompletion=vm::pop<bool>(Stack,false);
+ string name=vm::pop<string>(Stack,emptystring);
+ string prompt=vm::pop<string>(Stack,emptystring);
+#line 156 "runhistory.in"
+ if(!(isatty(STDIN_FILENO) || getSetting<Int>("inpipe") >= 0))
+ {Stack->push<string>(emptystring); return;}
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ init_readline(tabcompletion);
+
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ static char *line=NULL;
+ /* Return the memory to the free pool
+ if the buffer has already been allocated. */
+ if(line) {
+ free(line);
+ line=NULL;
+ }
+
+ /* Get a line from the user. */
+ line=readline(prompt.c_str());
+
+ if(!line) cout << endl;
+
+ history_set_history_state(&history_save);
+
+ {Stack->push<string>(line ? string(line) : emptystring); return;}
+#else
+ cout << prompt;
+ string s;
+ getline(cin,s);
+ unused(&tabcompletion); // Avoid unused variable warning message.
+ {Stack->push<string>(s); return;}
+#endif
+}
+
+// Save a string in a local history named name.
+// If store=true, store the local history in the file historyfilename(name).
+#line 198 "runhistory.in"
+// void saveline(string name, string value, bool store=true);
+void gen_runhistory3(stack *Stack)
+{
+ bool store=vm::pop<bool>(Stack,true);
+ string value=vm::pop<string>(Stack);
+ string name=vm::pop<string>(Stack);
+#line 199 "runhistory.in"
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ h.store=store;
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ if(value != "") {
+ add_history(value.c_str());
+ if(store) {
+ std::ofstream hout(historyfilename(name).c_str(),std::ios::app);
+ hout << value << endl;
+ }
+ }
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+#else
+ unused(&store);
+#endif
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runhistory_venv(venv &ve)
+{
+#line 108 "runhistory.in"
+ addFunc(ve, run::gen_runhistory0, stringArray(), SYM(history), formal(primString() , SYM(name), false, false), formal(primInt(), SYM(n), true, false));
+#line 141 "runhistory.in"
+ addFunc(ve, run::gen_runhistory1, stringArray(), SYM(history), formal(primInt(), SYM(n), true, false));
+#line 152 "runhistory.in"
+ addFunc(ve, run::gen_runhistory2, primString() , SYM(readline), formal(primString() , SYM(prompt), true, false), formal(primString() , SYM(name), true, false), formal(primBoolean(), SYM(tabcompletion), true, false));
+#line 196 "runhistory.in"
+ addFunc(ve, run::gen_runhistory3, primVoid(), SYM(saveline), formal(primString() , SYM(name), false, false), formal(primString() , SYM(value), false, false), formal(primBoolean(), SYM(store), true, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runhistory.h b/graphics/asymptote/runhistory.h
new file mode 100644
index 0000000000..50be6f77f1
--- /dev/null
+++ b/graphics/asymptote/runhistory.h
@@ -0,0 +1,8 @@
+/***** Autogenerated from runhistory.in; changes will be overwritten *****/
+
+#ifndef runhistory_H
+#define runhistory_H
+namespace run {
+}
+
+#endif // runhistory_H
diff --git a/graphics/asymptote/runhistory.in b/graphics/asymptote/runhistory.in
new file mode 100644
index 0000000000..851c808fe2
--- /dev/null
+++ b/graphics/asymptote/runhistory.in
@@ -0,0 +1,224 @@
+/*****
+ * runhistory.in
+ *
+ * Runtime functions for history operations.
+ *
+ *****/
+
+pair => primPair()
+picture* => primPicture()
+stringarray* => stringArray()
+
+
+#include "array.h"
+#include "mathop.h"
+#include "builtin.h"
+
+using namespace camp;
+using namespace settings;
+using namespace vm;
+using namespace run;
+
+typedef array stringarray;
+using types::stringArray;
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#include <readline/readline.h>
+#include <readline/history.h>
+
+struct historyState {
+ bool store;
+ HISTORY_STATE state;
+};
+
+typedef mem::map<CONST string, historyState> historyMap_t;
+historyMap_t historyMap;
+static HISTORY_STATE history_save;
+
+// Store a deep copy of the current readline history in dest.
+void store_history(HISTORY_STATE *dest)
+{
+ HISTORY_STATE *src=history_get_history_state();
+ if(src) {
+ *dest=*src;
+ for(Int i=0; i < src->length; ++i)
+ dest->entries[i]=src->entries[i];
+ free(src);
+ }
+}
+
+stringarray* get_history(Int n)
+{
+ int N=intcast(n);
+ if(N <= 0) N=history_length;
+ else N=Min(N,history_length);
+ array *a=new array((size_t) N);
+ int offset=history_length-N+1;
+ for(int i=0; i < N; ++i) {
+ HIST_ENTRY *last=history_get(offset+i);
+ string s=last ? last->line : "";
+ (*a)[i]=s;
+ }
+ return a;
+}
+
+string historyfilename(const string &name)
+{
+ return historyname+"_"+name;
+}
+#endif
+
+namespace run {
+
+extern string emptystring;
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+
+void init_readline(bool tabcompletion)
+{
+ rl_bind_key('\t',tabcompletion ? rl_complete : rl_insert);
+}
+#endif
+
+void cleanup()
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ int nlines=intcast(getSetting<Int>("historylines"));
+ for(historyMap_t::iterator h=historyMap.begin(); h != historyMap.end();
+ ++h) {
+ history_set_history_state(&h->second.state);
+ if(h->second.store) {
+ stifle_history(nlines);
+ write_history(historyfilename(h->first).c_str());
+ unstifle_history();
+ }
+ }
+ history_set_history_state(&history_save);
+#endif
+#ifdef HAVE_LIBGSL
+ trans::GSLrngFree();
+#endif
+}
+}
+
+// Autogenerated routines:
+
+
+// Return the last n lines of the history named name.
+stringarray* history(string name, Int n=1)
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ bool newhistory=historyMap.find(name) == historyMap.end();
+
+ string filename;
+
+ if(newhistory) {
+ filename=historyfilename(name);
+ std::ifstream exists(filename.c_str());
+ if(!exists) return new array(0);
+ }
+
+ store_history(&history_save);
+ HISTORY_STATE& history=historyMap[name].state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(filename.c_str());
+
+ array *a=get_history(n);
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+
+ return a;
+#else
+ unused(&n);
+ return new array(0);
+#endif
+}
+
+// Return the last n lines of the interactive history.
+stringarray* history(Int n=0)
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ return get_history(n);
+#else
+ unused(&n);
+ return new array(0);
+#endif
+}
+
+// Prompt for a string using prompt, the GNU readline library, and a
+// local history named name.
+string readline(string prompt=emptystring, string name=emptystring,
+ bool tabcompletion=false)
+{
+ if(!(isatty(STDIN_FILENO) || getSetting<Int>("inpipe") >= 0))
+ return emptystring;
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ init_readline(tabcompletion);
+
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ static char *line=NULL;
+ /* Return the memory to the free pool
+ if the buffer has already been allocated. */
+ if(line) {
+ free(line);
+ line=NULL;
+ }
+
+ /* Get a line from the user. */
+ line=readline(prompt.c_str());
+
+ if(!line) cout << endl;
+
+ history_set_history_state(&history_save);
+
+ return line ? string(line) : emptystring;
+#else
+ cout << prompt;
+ string s;
+ getline(cin,s);
+ unused(&tabcompletion); // Avoid unused variable warning message.
+ return s;
+#endif
+}
+
+// Save a string in a local history named name.
+// If store=true, store the local history in the file historyfilename(name).
+void saveline(string name, string value, bool store=true)
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ h.store=store;
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ if(value != "") {
+ add_history(value.c_str());
+ if(store) {
+ std::ofstream hout(historyfilename(name).c_str(),std::ios::app);
+ hout << value << endl;
+ }
+ }
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+#else
+ unused(&store);
+#endif
+}
diff --git a/graphics/asymptote/runlabel.cc b/graphics/asymptote/runlabel.cc
new file mode 100644
index 0000000000..1f7ea7417e
--- /dev/null
+++ b/graphics/asymptote/runlabel.cc
@@ -0,0 +1,591 @@
+/***** Autogenerated from runlabel.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runlabel.in"
+/*****
+ * runlabel.in
+ *
+ * Runtime functions for label operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 19 "runlabel.in"
+#include "picture.h"
+#include "drawlabel.h"
+#include "locate.h"
+
+using namespace camp;
+using namespace vm;
+using namespace settings;
+
+typedef array realarray;
+typedef array stringarray;
+typedef array penarray;
+typedef array patharray;
+typedef array patharray2;
+
+using types::realArray;
+using types::stringArray;
+using types::penArray;
+using types::pathArray;
+using types::pathArray2;
+
+void cannotread(const string& s)
+{
+ ostringstream buf;
+ buf << "Cannot read from " << s;
+ error(buf);
+}
+
+void cannotwrite(const string& s)
+{
+ ostringstream buf;
+ buf << "Cannot write to " << s;
+ error(buf);
+}
+
+pair readpair(stringstream& s, double hscale=1.0, double vscale=1.0)
+{
+ double x,y;
+ s >> y;
+ s >> x;
+ return pair(hscale*x,vscale*y);
+}
+
+string ASYx="/ASYx {( ) print ASYX sub 12 string cvs print} bind def";
+string ASYy="/ASYy {( ) print ASYY sub 12 string cvs print} bind def";
+string pathforall="{(M) print ASYy ASYx} {(L) print ASYy ASYx} {(C) print ASYy ASYx ASYy ASYx ASYy ASYx} {(c) print} pathforall";
+string currentpoint="print currentpoint ASYy ASYx ";
+string ASYinit="/ASYX currentpoint pop def /ASYY currentpoint exch pop def ";
+string ASY1="ASY1 {"+ASYinit+"/ASY1 false def} if ";
+
+void endpath(std::ostream& ps)
+{
+ ps << ASY1 << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto} bind def" << endl;
+}
+
+void fillpath(std::ostream& ps)
+{
+ ps << "/fill {closepath ";
+ endpath(ps);
+}
+
+void showpath(std::ostream& ps)
+{
+ ps << ASYx << newl
+ << ASYy << newl
+ << "/ASY1 true def" << newl
+ << "/stroke {strokepath ";
+ endpath(ps);
+ fillpath(ps);
+}
+
+array *readpath(const string& psname, bool keep, bool pdf=false,
+ double hscale=1.0, double vsign=1.0)
+{
+ double vscale=vsign*hscale;
+ array *PP=new array(0);
+
+ char *oldPath=NULL;
+ string dir=stripFile(outname());
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
+
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dBATCH");
+ cmd.push_back("-P");
+ if(safe) cmd.push_back("-dSAFER");
+#ifdef __MSDOS__
+ const string null="NUL";
+#else
+ const string null="/dev/null";
+#endif
+ string epsdriver=getSetting<string>("epsdriver");
+ cmd.push_back("-sDEVICE="+epsdriver);
+ cmd.push_back("-sOutputFile="+null);
+ cmd.push_back(stripDir(psname));
+ iopipestream gs(cmd,"gs","Ghostscript");
+ while(gs.running()) {
+ stringstream buf;
+ string s=gs.readline();
+ if(s.empty()) break;
+ if(!pdf) gs << newl;
+
+// Workaround broken stringstream container in MacOS 10.9 libc++.
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__ )
+ for(string::iterator i=s.begin(); i != s.end(); ++i) {
+ if(isalpha(*i) && *i != 'e') {buf << " ";}
+ buf << *i;
+ }
+#else
+ buf << s;
+#endif
+
+ if(verbose > 2) cout << endl;
+
+ mem::vector<solvedKnot> nodes;
+ solvedKnot node;
+ bool active=false;
+
+ array *P=new array(0);
+ PP->push(P);
+
+ while(!buf.eof()) {
+ char c;
+ buf >> c;
+ if(c == '>') break;
+
+ switch(c) {
+ case 'M':
+ {
+ node.pre=node.point=readpair(buf,hscale,vscale);
+ node.straight=false;
+ break;
+ }
+ case 'L':
+ {
+ pair point=readpair(buf,hscale,vscale);
+ pair delta=(point-node.point)*third;
+ node.post=node.point+delta;
+ node.straight=true;
+ nodes.push_back(node);
+ active=true;
+ node.pre=point-delta;
+ node.point=point;
+ break;
+ }
+ case 'C':
+ {
+ pair point=readpair(buf,hscale,vscale);
+ pair pre=readpair(buf,hscale,vscale);
+ node.post=readpair(buf,hscale,vscale);
+ node.straight=false;
+ nodes.push_back(node);
+ active=true;
+ node.pre=pre;
+ node.point=point;
+ break;
+ }
+ case 'c':
+ {
+ if(active) {
+ if(node.point == nodes[0].point)
+ nodes[0].pre=node.pre;
+ else {
+ pair delta=(nodes[0].point-node.point)*third;
+ node.post=node.point+delta;
+ nodes[0].pre=nodes[0].point-delta;
+ node.straight=true;
+ nodes.push_back(node);
+ }
+ P->push(path(nodes,nodes.size(),true)); // Discard noncyclic paths
+ nodes.clear();
+ }
+ active=false;
+ node.straight=false;
+ break;
+ }
+ }
+ }
+ }
+
+ if(oldPath != NULL)
+ setPath(oldPath);
+
+ if(!keep)
+ unlink(psname.c_str());
+ return PP;
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runlabel.symbols.h"
+
+#endif
+namespace run {
+#line 214 "runlabel.in"
+// void label(picture *f, string *s, string *size, transform t, pair position, pair align, pen p);
+void gen_runlabel0(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ pair align=vm::pop<pair>(Stack);
+ pair position=vm::pop<pair>(Stack);
+ transform t=vm::pop<transform>(Stack);
+ string * size=vm::pop<string *>(Stack);
+ string * s=vm::pop<string *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 216 "runlabel.in"
+ f->append(new drawLabel(*s,*size,t,position,align,p));
+}
+
+#line 220 "runlabel.in"
+// bool labels(picture *f);
+void gen_runlabel1(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 221 "runlabel.in"
+ {Stack->push<bool>(f->havelabels()); return;}
+}
+
+#line 225 "runlabel.in"
+// realarray* texsize(string *s, pen p=CURRENTPEN);
+void gen_runlabel2(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+ string * s=vm::pop<string *>(Stack);
+#line 226 "runlabel.in"
+ texinit();
+ processDataStruct &pd=processData();
+
+ string texengine=getSetting<string>("tex");
+ setpen(pd.tex,texengine,p);
+
+ double width,height,depth;
+ texbounds(width,height,depth,pd.tex,*s);
+
+ array *t=new array(3);
+ (*t)[0]=width;
+ (*t)[1]=height;
+ (*t)[2]=depth;
+ {Stack->push<realarray*>(t); return;}
+}
+
+#line 243 "runlabel.in"
+// patharray2* _texpath(stringarray *s, penarray *p);
+void gen_runlabel3(stack *Stack)
+{
+ penarray * p=vm::pop<penarray *>(Stack);
+ stringarray * s=vm::pop<stringarray *>(Stack);
+#line 244 "runlabel.in"
+ size_t n=checkArrays(s,p);
+ if(n == 0) {Stack->push<patharray2*>(new array(0)); return;}
+
+ string prefix=cleanpath(outname());
+ string psname=auxname(prefix,"ps");
+ string texname=auxname(prefix,"tex");
+ string dviname=auxname(prefix,"dvi");
+ bbox b;
+ string texengine=getSetting<string>("tex");
+ bool xe=settings::xe(texengine) || settings::lua(texengine) ||
+ settings::context(texengine);
+ texfile tex(texname,b,true);
+ tex.miniprologue();
+
+ for(size_t i=0; i < n; ++i) {
+ tex.setfont(read<pen>(p,i));
+ if(i != 0) {
+ if(texengine == "context")
+ tex.verbatimline("}\\page\\hbox{%");
+ else if(texengine == "luatex" || texengine == "tex" ||
+ texengine == "pdftex")
+ tex.verbatimline("\\eject");
+ else
+ tex.verbatimline("\\newpage");
+ }
+ if(!xe) {
+ tex.verbatimline("\\special{ps:");
+ tex.verbatimline(ASYx);
+ tex.verbatimline(ASYy);
+ tex.verbatimline("/ASY1 true def");
+ tex.verbatimline("/show {"+ASY1+
+ "currentpoint newpath moveto false charpath "+pathforall+
+ "} bind def");
+ tex.verbatimline("/V {"+ASY1+"Ry neg Rx 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYy ASYx (L) print ASYy add ASYx (L) print add ASYy add ASYx (L) print add ASYy ASYx (c) print} bind def}");
+ }
+ tex.verbatimline(read<string>(s,i)+"\\ %");
+ }
+
+ tex.epilogue(true);
+ tex.close();
+
+ int status=opentex(texname,prefix,!xe);
+
+ string pdfname,pdfname2,psname2;
+ bool keep=getSetting<bool>("keep");
+
+ bool legacygs=false;
+ if(!status) {
+ if(xe) {
+// Use legacy ghostscript driver for gs-9.13 and earlier.
+ string epsdriver=getSetting<string>("epsdriver");
+ legacygs=epsdriver == "epswrite";
+
+ pdfname=auxname(prefix,"pdf");
+ pdfname2=auxname(prefix+"_","pdf");
+ psname2=auxname(prefix+"_","ps");
+ if(!fs::exists(pdfname)) {Stack->push<patharray2*>(new array(n)); return;}
+ std::ofstream ps(psname.c_str(),std::ios::binary);
+ if(!ps) cannotwrite(psname);
+
+ showpath(ps);
+
+ mem::vector<string> pcmd;
+ pcmd.push_back(getSetting<string>("gs"));
+ pcmd.push_back("-q");
+ pcmd.push_back("-dNOCACHE");
+ pcmd.push_back("-dNOPAUSE");
+ pcmd.push_back("-dBATCH");
+ if(safe) pcmd.push_back("-dSAFER");
+ pcmd.push_back("-sDEVICE=pdfwrite");
+ pcmd.push_back("-sOutputFile="+pdfname2);
+ pcmd.push_back(pdfname);
+ status=System(pcmd,0,true,"gs");
+ if(status == 0) {
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dNOCACHE");
+ cmd.push_back("-dNOPAUSE");
+ cmd.push_back("-dBATCH");
+ if(safe) cmd.push_back("-dSAFER");
+ cmd.push_back("-sDEVICE="+epsdriver);
+ // Work around eps2write bug that forces all postscript to first page.
+ cmd.push_back("-sOutputFile="+psname2+(legacygs ? "" : "%d"));
+ cmd.push_back(pdfname2);
+ status=System(cmd,0,true,"gs");
+
+ if(legacygs) {
+ std::ifstream in(psname2.c_str());
+ ps << in.rdbuf();
+ } else {
+ for(unsigned int i=1; i <= n ; ++i) {
+ ostringstream buf;
+ buf << psname2 << i;
+ const string& s=buf.str();
+ const char *name=s.c_str();
+ std::ifstream in(name,std::ios::binary);
+ ps << in.rdbuf();
+ ps << "(>\n) print flush\n";
+ in.close();
+ if(!keep) unlink(name);
+ }
+ }
+ ps.close();
+ }
+ } else {
+ if(!fs::exists(dviname)) {Stack->push<patharray2*>(new array(n)); return;}
+ mem::vector<string> dcmd;
+ dcmd.push_back(getSetting<string>("dvips"));
+ dcmd.push_back("-R");
+ dcmd.push_back("-Pdownload35");
+ dcmd.push_back("-D600");
+ push_split(dcmd,getSetting<string>("dvipsOptions"));
+ if(verbose <= 2) dcmd.push_back("-q");
+ dcmd.push_back("-o"+psname);
+ dcmd.push_back(dviname);
+ status=System(dcmd,0,true,"dvips");
+ }
+ } else
+ error("texpath failed");
+
+ if(!keep) { // Delete temporary files.
+ unlink(texname.c_str());
+ if(!getSetting<bool>("keepaux"))
+ unlink(auxname(prefix,"aux").c_str());
+ unlink(auxname(prefix,"log").c_str());
+ if(xe) {
+ unlink(pdfname.c_str());
+ unlink(pdfname2.c_str());
+ } else
+ unlink(dviname.c_str());
+ if(settings::context(texengine)) {
+ unlink(auxname(prefix,"top").c_str());
+ unlink(auxname(prefix,"tua").c_str());
+ unlink(auxname(prefix,"tuc").c_str());
+ unlink(auxname(prefix,"tui").c_str());
+ }
+ }
+ {Stack->push<patharray2*>(xe ? readpath(psname,keep,!legacygs,0.1) :
+ readpath(psname,keep,false,0.12,-1.0)); return;}
+}
+
+#line 387 "runlabel.in"
+// patharray2* textpath(stringarray *s, penarray *p);
+void gen_runlabel4(stack *Stack)
+{
+ penarray * p=vm::pop<penarray *>(Stack);
+ stringarray * s=vm::pop<stringarray *>(Stack);
+#line 388 "runlabel.in"
+ size_t n=checkArrays(s,p);
+ if(n == 0) {Stack->push<patharray2*>(new array(0)); return;}
+
+ string prefix=cleanpath(outname());
+ string outputname=auxname(prefix,getSetting<string>("textoutformat"));
+
+ string textname=auxname(prefix,getSetting<string>("textextension"));
+ std::ofstream text(textname.c_str());
+
+ if(!text) cannotwrite(textname);
+
+ for(size_t i=0; i < n; ++i) {
+ text << getSetting<string>("textprologue") << newl
+ << read<pen>(p,i).Font() << newl
+ << read<string>(s,i) << newl
+ << getSetting<string>("textepilogue") << endl;
+ }
+ text.close();
+
+ string psname=auxname(prefix,"ps");
+ std::ofstream ps(psname.c_str());
+ if(!ps) cannotwrite(psname);
+
+ showpath(ps);
+
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("textcommand"));
+ push_split(cmd,getSetting<string>("textcommandOptions"));
+ cmd.push_back(textname);
+ iopipestream typesetter(cmd);
+ typesetter.block(true,false);
+
+ mem::vector<string> cmd2;
+ cmd2.push_back(getSetting<string>("gs"));
+ cmd2.push_back("-q");
+ cmd2.push_back("-dNOCACHE");
+ cmd2.push_back("-dNOPAUSE");
+ cmd2.push_back("-dBATCH");
+ cmd2.push_back("-P");
+ if(safe) cmd2.push_back("-dSAFER");
+ cmd2.push_back("-sDEVICE="+getSetting<string>("epsdriver"));
+ cmd2.push_back("-sOutputFile=-");
+ cmd2.push_back("-");
+ iopipestream gs(cmd2,"gs","Ghostscript");
+ gs.block(false,false);
+
+ // TODO: Simplify by connecting the pipes directly.
+ while(true) {
+ string out;
+ if(typesetter.isopen()) {
+ typesetter >> out;
+ if(!out.empty()) gs << out;
+ else if(!typesetter.running()) {
+ typesetter.pipeclose();
+ gs.eof();
+ }
+ }
+ string out2;
+ gs >> out2;
+ if(out2.empty() && !gs.running()) break;
+ ps << out2;
+ }
+ ps.close();
+
+ if(verbose > 2) cout << endl;
+
+ bool keep=getSetting<bool>("keep");
+ if(!keep) // Delete temporary files.
+ unlink(textname.c_str());
+ {Stack->push<patharray2*>(readpath(psname,keep,false,0.1)); return;}
+}
+
+#line 461 "runlabel.in"
+// patharray* _strokepath(path g, pen p=CURRENTPEN);
+void gen_runlabel5(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+ path g=vm::pop<path>(Stack);
+#line 462 "runlabel.in"
+ array *P=new array(0);
+ if(g.size() == 0) {Stack->push<patharray*>(P); return;}
+
+ string prefix=cleanpath(outname());
+ string psname=auxname(prefix,"ps");
+ bbox b;
+ psfile ps(psname,false);
+ ps.prologue(b);
+ ps.verbatimline(ASYx);
+ ps.verbatimline(ASYy);
+ ps.verbatimline("/stroke {"+ASYinit+pathforall+"} bind def");
+ ps.resetpen();
+ ps.setpen(p);
+ ps.write(g);
+ ps.strokepath();
+ ps.stroke(p);
+ ps.verbatimline("(M) "+currentpoint);
+ ps.epilogue();
+ ps.close();
+ array *a=readpath(psname,getSetting<bool>("keep"));
+ {Stack->push<patharray*>(a->size() > 0 ? read<array *>(a,0) : a); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runlabel_venv(venv &ve)
+{
+#line 214 "runlabel.in"
+ addFunc(ve, run::gen_runlabel0, primVoid(), SYM(label), formal(primPicture(), SYM(f), false, false), formal(primString(), SYM(s), false, false), formal(primString(), SYM(size), false, false), formal(primTransform(), SYM(t), false, false), formal(primPair(), SYM(position), false, false), formal(primPair(), SYM(align), false, false), formal(primPen(), SYM(p), false, false));
+#line 220 "runlabel.in"
+ addFunc(ve, run::gen_runlabel1, primBoolean(), SYM(labels), formal(primPicture(), SYM(f), false, false));
+#line 225 "runlabel.in"
+ addFunc(ve, run::gen_runlabel2, realArray(), SYM(texsize), formal(primString(), SYM(s), false, false), formal(primPen(), SYM(p), true, false));
+#line 243 "runlabel.in"
+ addFunc(ve, run::gen_runlabel3, pathArray2() , SYM(_texpath), formal(stringArray() , SYM(s), false, false), formal(penArray() , SYM(p), false, false));
+#line 387 "runlabel.in"
+ addFunc(ve, run::gen_runlabel4, pathArray2() , SYM(textpath), formal(stringArray() , SYM(s), false, false), formal(penArray() , SYM(p), false, false));
+#line 461 "runlabel.in"
+ addFunc(ve, run::gen_runlabel5, pathArray() , SYM(_strokepath), formal(primPath(), SYM(g), false, false), formal(primPen(), SYM(p), true, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runlabel.h b/graphics/asymptote/runlabel.h
new file mode 100644
index 0000000000..b710d65cee
--- /dev/null
+++ b/graphics/asymptote/runlabel.h
@@ -0,0 +1,8 @@
+/***** Autogenerated from runlabel.in; changes will be overwritten *****/
+
+#ifndef runlabel_H
+#define runlabel_H
+namespace run {
+}
+
+#endif // runlabel_H
diff --git a/graphics/asymptote/runlabel.in b/graphics/asymptote/runlabel.in
new file mode 100644
index 0000000000..9503a0b0ee
--- /dev/null
+++ b/graphics/asymptote/runlabel.in
@@ -0,0 +1,484 @@
+/*****
+ * runlabel.in
+ *
+ * Runtime functions for label operations.
+ *
+ *****/
+
+pen => primPen()
+ pair => primPair()
+ path => primPath()
+ picture* => primPicture()
+ transform => primTransform()
+ realarray* => realArray()
+ stringarray* => stringArray()
+ penarray* => penArray()
+ patharray* => pathArray()
+ patharray2* => pathArray2()
+
+#include "picture.h"
+#include "drawlabel.h"
+#include "locate.h"
+
+using namespace camp;
+using namespace vm;
+using namespace settings;
+
+typedef array realarray;
+typedef array stringarray;
+typedef array penarray;
+typedef array patharray;
+typedef array patharray2;
+
+using types::realArray;
+using types::stringArray;
+using types::penArray;
+using types::pathArray;
+using types::pathArray2;
+
+void cannotread(const string& s)
+{
+ ostringstream buf;
+ buf << "Cannot read from " << s;
+ error(buf);
+}
+
+void cannotwrite(const string& s)
+{
+ ostringstream buf;
+ buf << "Cannot write to " << s;
+ error(buf);
+}
+
+pair readpair(stringstream& s, double hscale=1.0, double vscale=1.0)
+{
+ double x,y;
+ s >> y;
+ s >> x;
+ return pair(hscale*x,vscale*y);
+}
+
+string ASYx="/ASYx {( ) print ASYX sub 12 string cvs print} bind def";
+string ASYy="/ASYy {( ) print ASYY sub 12 string cvs print} bind def";
+string pathforall="{(M) print ASYy ASYx} {(L) print ASYy ASYx} {(C) print ASYy ASYx ASYy ASYx ASYy ASYx} {(c) print} pathforall";
+string currentpoint="print currentpoint ASYy ASYx ";
+string ASYinit="/ASYX currentpoint pop def /ASYY currentpoint exch pop def ";
+string ASY1="ASY1 {"+ASYinit+"/ASY1 false def} if ";
+
+void endpath(std::ostream& ps)
+{
+ ps << ASY1 << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto} bind def" << endl;
+}
+
+void fillpath(std::ostream& ps)
+{
+ ps << "/fill {closepath ";
+ endpath(ps);
+}
+
+void showpath(std::ostream& ps)
+{
+ ps << ASYx << newl
+ << ASYy << newl
+ << "/ASY1 true def" << newl
+ << "/stroke {strokepath ";
+ endpath(ps);
+ fillpath(ps);
+}
+
+array *readpath(const string& psname, bool keep, bool pdf=false,
+ double hscale=1.0, double vsign=1.0)
+{
+ double vscale=vsign*hscale;
+ array *PP=new array(0);
+
+ char *oldPath=NULL;
+ string dir=stripFile(outname());
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
+
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dBATCH");
+ cmd.push_back("-P");
+ if(safe) cmd.push_back("-dSAFER");
+#ifdef __MSDOS__
+ const string null="NUL";
+#else
+ const string null="/dev/null";
+#endif
+ string epsdriver=getSetting<string>("epsdriver");
+ cmd.push_back("-sDEVICE="+epsdriver);
+ cmd.push_back("-sOutputFile="+null);
+ cmd.push_back(stripDir(psname));
+ iopipestream gs(cmd,"gs","Ghostscript");
+ while(gs.running()) {
+ stringstream buf;
+ string s=gs.readline();
+ if(s.empty()) break;
+ if(!pdf) gs << newl;
+
+// Workaround broken stringstream container in MacOS 10.9 libc++.
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__ )
+ for(string::iterator i=s.begin(); i != s.end(); ++i) {
+ if(isalpha(*i) && *i != 'e') {buf << " ";}
+ buf << *i;
+ }
+#else
+ buf << s;
+#endif
+
+ if(verbose > 2) cout << endl;
+
+ mem::vector<solvedKnot> nodes;
+ solvedKnot node;
+ bool active=false;
+
+ array *P=new array(0);
+ PP->push(P);
+
+ while(!buf.eof()) {
+ char c;
+ buf >> c;
+ if(c == '>') break;
+
+ switch(c) {
+ case 'M':
+ {
+ node.pre=node.point=readpair(buf,hscale,vscale);
+ node.straight=false;
+ break;
+ }
+ case 'L':
+ {
+ pair point=readpair(buf,hscale,vscale);
+ pair delta=(point-node.point)*third;
+ node.post=node.point+delta;
+ node.straight=true;
+ nodes.push_back(node);
+ active=true;
+ node.pre=point-delta;
+ node.point=point;
+ break;
+ }
+ case 'C':
+ {
+ pair point=readpair(buf,hscale,vscale);
+ pair pre=readpair(buf,hscale,vscale);
+ node.post=readpair(buf,hscale,vscale);
+ node.straight=false;
+ nodes.push_back(node);
+ active=true;
+ node.pre=pre;
+ node.point=point;
+ break;
+ }
+ case 'c':
+ {
+ if(active) {
+ if(node.point == nodes[0].point)
+ nodes[0].pre=node.pre;
+ else {
+ pair delta=(nodes[0].point-node.point)*third;
+ node.post=node.point+delta;
+ nodes[0].pre=nodes[0].point-delta;
+ node.straight=true;
+ nodes.push_back(node);
+ }
+ P->push(path(nodes,nodes.size(),true)); // Discard noncyclic paths
+ nodes.clear();
+ }
+ active=false;
+ node.straight=false;
+ break;
+ }
+ }
+ }
+ }
+
+ if(oldPath != NULL)
+ setPath(oldPath);
+
+ if(!keep)
+ unlink(psname.c_str());
+ return PP;
+}
+
+// Autogenerated routines:
+
+
+void label(picture *f, string *s, string *size, transform t, pair position,
+ pair align, pen p)
+{
+ f->append(new drawLabel(*s,*size,t,position,align,p));
+}
+
+bool labels(picture *f)
+{
+ return f->havelabels();
+}
+
+realarray *texsize(string *s, pen p=CURRENTPEN)
+{
+ texinit();
+ processDataStruct &pd=processData();
+
+ string texengine=getSetting<string>("tex");
+ setpen(pd.tex,texengine,p);
+
+ double width,height,depth;
+ texbounds(width,height,depth,pd.tex,*s);
+
+ array *t=new array(3);
+ (*t)[0]=width;
+ (*t)[1]=height;
+ (*t)[2]=depth;
+ return t;
+}
+
+patharray2 *_texpath(stringarray *s, penarray *p)
+{
+ size_t n=checkArrays(s,p);
+ if(n == 0) return new array(0);
+
+ string prefix=cleanpath(outname());
+ string psname=auxname(prefix,"ps");
+ string texname=auxname(prefix,"tex");
+ string dviname=auxname(prefix,"dvi");
+ bbox b;
+ string texengine=getSetting<string>("tex");
+ bool xe=settings::xe(texengine) || settings::lua(texengine) ||
+ settings::context(texengine);
+ texfile tex(texname,b,true);
+ tex.miniprologue();
+
+ for(size_t i=0; i < n; ++i) {
+ tex.setfont(read<pen>(p,i));
+ if(i != 0) {
+ if(texengine == "context")
+ tex.verbatimline("}\\page\\hbox{%");
+ else if(texengine == "luatex" || texengine == "tex" ||
+ texengine == "pdftex")
+ tex.verbatimline("\\eject");
+ else
+ tex.verbatimline("\\newpage");
+ }
+ if(!xe) {
+ tex.verbatimline("\\special{ps:");
+ tex.verbatimline(ASYx);
+ tex.verbatimline(ASYy);
+ tex.verbatimline("/ASY1 true def");
+ tex.verbatimline("/show {"+ASY1+
+ "currentpoint newpath moveto false charpath "+pathforall+
+ "} bind def");
+ tex.verbatimline("/V {"+ASY1+"Ry neg Rx 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYy ASYx (L) print ASYy add ASYx (L) print add ASYy add ASYx (L) print add ASYy ASYx (c) print} bind def}");
+ }
+ tex.verbatimline(read<string>(s,i)+"\\ %");
+ }
+
+ tex.epilogue(true);
+ tex.close();
+
+ int status=opentex(texname,prefix,!xe);
+
+ string pdfname,pdfname2,psname2;
+ bool keep=getSetting<bool>("keep");
+
+ bool legacygs=false;
+ if(!status) {
+ if(xe) {
+// Use legacy ghostscript driver for gs-9.13 and earlier.
+ string epsdriver=getSetting<string>("epsdriver");
+ legacygs=epsdriver == "epswrite";
+
+ pdfname=auxname(prefix,"pdf");
+ pdfname2=auxname(prefix+"_","pdf");
+ psname2=auxname(prefix+"_","ps");
+ if(!fs::exists(pdfname)) return new array(n);
+ std::ofstream ps(psname.c_str(),std::ios::binary);
+ if(!ps) cannotwrite(psname);
+
+ showpath(ps);
+
+ mem::vector<string> pcmd;
+ pcmd.push_back(getSetting<string>("gs"));
+ pcmd.push_back("-q");
+ pcmd.push_back("-dNOCACHE");
+ pcmd.push_back("-dNOPAUSE");
+ pcmd.push_back("-dBATCH");
+ if(safe) pcmd.push_back("-dSAFER");
+ pcmd.push_back("-sDEVICE=pdfwrite");
+ pcmd.push_back("-sOutputFile="+pdfname2);
+ pcmd.push_back(pdfname);
+ status=System(pcmd,0,true,"gs");
+ if(status == 0) {
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("gs"));
+ cmd.push_back("-q");
+ cmd.push_back("-dNOCACHE");
+ cmd.push_back("-dNOPAUSE");
+ cmd.push_back("-dBATCH");
+ if(safe) cmd.push_back("-dSAFER");
+ cmd.push_back("-sDEVICE="+epsdriver);
+ // Work around eps2write bug that forces all postscript to first page.
+ cmd.push_back("-sOutputFile="+psname2+(legacygs ? "" : "%d"));
+ cmd.push_back(pdfname2);
+ status=System(cmd,0,true,"gs");
+
+ if(legacygs) {
+ std::ifstream in(psname2.c_str());
+ ps << in.rdbuf();
+ } else {
+ for(unsigned int i=1; i <= n ; ++i) {
+ ostringstream buf;
+ buf << psname2 << i;
+ const string& s=buf.str();
+ const char *name=s.c_str();
+ std::ifstream in(name,std::ios::binary);
+ ps << in.rdbuf();
+ ps << "(>\n) print flush\n";
+ in.close();
+ if(!keep) unlink(name);
+ }
+ }
+ ps.close();
+ }
+ } else {
+ if(!fs::exists(dviname)) return new array(n);
+ mem::vector<string> dcmd;
+ dcmd.push_back(getSetting<string>("dvips"));
+ dcmd.push_back("-R");
+ dcmd.push_back("-Pdownload35");
+ dcmd.push_back("-D600");
+ push_split(dcmd,getSetting<string>("dvipsOptions"));
+ if(verbose <= 2) dcmd.push_back("-q");
+ dcmd.push_back("-o"+psname);
+ dcmd.push_back(dviname);
+ status=System(dcmd,0,true,"dvips");
+ }
+ } else
+ error("texpath failed");
+
+ if(!keep) { // Delete temporary files.
+ unlink(texname.c_str());
+ if(!getSetting<bool>("keepaux"))
+ unlink(auxname(prefix,"aux").c_str());
+ unlink(auxname(prefix,"log").c_str());
+ if(xe) {
+ unlink(pdfname.c_str());
+ unlink(pdfname2.c_str());
+ } else
+ unlink(dviname.c_str());
+ if(settings::context(texengine)) {
+ unlink(auxname(prefix,"top").c_str());
+ unlink(auxname(prefix,"tua").c_str());
+ unlink(auxname(prefix,"tuc").c_str());
+ unlink(auxname(prefix,"tui").c_str());
+ }
+ }
+ return xe ? readpath(psname,keep,!legacygs,0.1) :
+ readpath(psname,keep,false,0.12,-1.0);
+}
+
+patharray2 *textpath(stringarray *s, penarray *p)
+{
+ size_t n=checkArrays(s,p);
+ if(n == 0) return new array(0);
+
+ string prefix=cleanpath(outname());
+ string outputname=auxname(prefix,getSetting<string>("textoutformat"));
+
+ string textname=auxname(prefix,getSetting<string>("textextension"));
+ std::ofstream text(textname.c_str());
+
+ if(!text) cannotwrite(textname);
+
+ for(size_t i=0; i < n; ++i) {
+ text << getSetting<string>("textprologue") << newl
+ << read<pen>(p,i).Font() << newl
+ << read<string>(s,i) << newl
+ << getSetting<string>("textepilogue") << endl;
+ }
+ text.close();
+
+ string psname=auxname(prefix,"ps");
+ std::ofstream ps(psname.c_str());
+ if(!ps) cannotwrite(psname);
+
+ showpath(ps);
+
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("textcommand"));
+ push_split(cmd,getSetting<string>("textcommandOptions"));
+ cmd.push_back(textname);
+ iopipestream typesetter(cmd);
+ typesetter.block(true,false);
+
+ mem::vector<string> cmd2;
+ cmd2.push_back(getSetting<string>("gs"));
+ cmd2.push_back("-q");
+ cmd2.push_back("-dNOCACHE");
+ cmd2.push_back("-dNOPAUSE");
+ cmd2.push_back("-dBATCH");
+ cmd2.push_back("-P");
+ if(safe) cmd2.push_back("-dSAFER");
+ cmd2.push_back("-sDEVICE="+getSetting<string>("epsdriver"));
+ cmd2.push_back("-sOutputFile=-");
+ cmd2.push_back("-");
+ iopipestream gs(cmd2,"gs","Ghostscript");
+ gs.block(false,false);
+
+ // TODO: Simplify by connecting the pipes directly.
+ while(true) {
+ string out;
+ if(typesetter.isopen()) {
+ typesetter >> out;
+ if(!out.empty()) gs << out;
+ else if(!typesetter.running()) {
+ typesetter.pipeclose();
+ gs.eof();
+ }
+ }
+ string out2;
+ gs >> out2;
+ if(out2.empty() && !gs.running()) break;
+ ps << out2;
+ }
+ ps.close();
+
+ if(verbose > 2) cout << endl;
+
+ bool keep=getSetting<bool>("keep");
+ if(!keep) // Delete temporary files.
+ unlink(textname.c_str());
+ return readpath(psname,keep,false,0.1);
+}
+
+patharray *_strokepath(path g, pen p=CURRENTPEN)
+{
+ array *P=new array(0);
+ if(g.size() == 0) return P;
+
+ string prefix=cleanpath(outname());
+ string psname=auxname(prefix,"ps");
+ bbox b;
+ psfile ps(psname,false);
+ ps.prologue(b);
+ ps.verbatimline(ASYx);
+ ps.verbatimline(ASYy);
+ ps.verbatimline("/stroke {"+ASYinit+pathforall+"} bind def");
+ ps.resetpen();
+ ps.setpen(p);
+ ps.write(g);
+ ps.strokepath();
+ ps.stroke(p);
+ ps.verbatimline("(M) "+currentpoint);
+ ps.epilogue();
+ ps.close();
+ array *a=readpath(psname,getSetting<bool>("keep"));
+ return a->size() > 0 ? read<array *>(a,0) : a;
+}
diff --git a/graphics/asymptote/runmath.cc b/graphics/asymptote/runmath.cc
new file mode 100644
index 0000000000..d9686dc80c
--- /dev/null
+++ b/graphics/asymptote/runmath.cc
@@ -0,0 +1,785 @@
+/***** Autogenerated from runmath.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runmath.in"
+/*****
+ * runmath.in
+ *
+ * Runtime functions for math operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 12 "runmath.in"
+#include <inttypes.h>
+
+#include "mathop.h"
+#include "path.h"
+
+#ifdef __CYGWIN__
+extern "C" double yn(int, double);
+extern "C" double jn(int, double);
+extern "C" int __signgam;
+#define signgam __signgam
+#endif
+
+using namespace camp;
+
+typedef array realarray;
+typedef array pairarray;
+
+using types::realArray;
+using types::pairArray;
+
+using run::integeroverflow;
+using vm::frame;
+
+const char *invalidargument="invalid argument";
+
+extern uint32_t CLZ(uint32_t a);
+
+inline unsigned intbits() {
+ static unsigned count=0;
+ if(count > 0) return count;
+ while((1ULL << count) < Int_MAX)
+ ++count;
+ ++count;
+ return count;
+}
+
+static const unsigned char BitReverseTable8[256]=
+{
+#define R2(n) n, n+2*64, n+1*64, n+3*64
+#define R4(n) R2(n),R2(n+2*16),R2(n+1*16),R2(n+3*16)
+#define R6(n) R4(n),R4(n+2*4 ),R4(n+1*4 ),R4(n+3*4 )
+R6(0),R6(2),R6(1),R6(3)
+};
+#undef R2
+#undef R4
+#undef R6
+
+unsigned long long bitreverse8(unsigned long long a)
+{
+ return
+ (unsigned long long) BitReverseTable8[a];
+}
+
+unsigned long long bitreverse16(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 8)]);
+}
+
+unsigned long long bitreverse24(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 16)]);
+}
+
+unsigned long long bitreverse32(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 24)]);
+}
+
+unsigned long long bitreverse40(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 32)]);
+}
+
+unsigned long long bitreverse48(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 40) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 32) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 40)]);
+}
+
+unsigned long long bitreverse56(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 48) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 40) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 32) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 40) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 48)]);
+}
+
+unsigned long long bitreverse64(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 56) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 48) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 40) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 32) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 40) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 48) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 56)]);
+}
+
+// From Warren, Jr., Henry S. (2013) [2002]. Hacker's Delight (2 ed.).
+// Addison Wesley - Pearson Education, Inc. pp. 81-96.
+Int popcount(Int a)
+{
+ const uint64_t m1 = 0x5555555555555555; //binary: 0101...
+ const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
+ const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
+ const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
+
+// This algorithm uses 12 arithmetic operations, one of which is a multiply.
+ a -= (a >> 1) & m1; //put count of each 2 bits into those 2 bits
+ a=(a & m2)+((a >> 2) & m2); //put count of each 4 bits into those 4 bits
+ a=(a+(a >> 4)) & m4; //put count of each 8 bits into those 8 bits
+ return (a * h01) >> 56; //returns left 8 bits of a+(a << 8)+(a << 16)+(a << 24)+...
+}
+
+// Return the factorial of a non-negative integer using a lookup table.
+Int factorial(Int n)
+{
+ static Int *table;
+ static Int size=0;
+ if(size == 0) {
+ Int f=1;
+ size=2;
+ while(f <= Int_MAX/size)
+ f *= (size++);
+ table=new Int[size];
+ table[0]=f=1;
+ for(Int i=1; i < size; ++i) {
+ f *= i;
+ table[i]=f;
+ }
+ }
+ if(n >= size) integeroverflow(0);
+ return table[n];
+}
+
+static inline Int Round(double x)
+{
+ return Int(x+((x >= 0) ? 0.5 : -0.5));
+}
+
+inline Int sgn(double x)
+{
+ return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0));
+}
+
+static bool initializeRandom=true;
+
+void Srand(Int seed)
+{
+ initializeRandom=false;
+ const int n=256;
+ static char state[n];
+ initstate(intcast(seed),state,n);
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runmath.symbols.h"
+
+#endif
+namespace run {
+#line 195 "runmath.in"
+// real ^(real x, Int y);
+void gen_runmath0(stack *Stack)
+{
+ Int y=vm::pop<Int>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 196 "runmath.in"
+ {Stack->push<real>(pow(x,y)); return;}
+}
+
+#line 200 "runmath.in"
+// pair ^(pair z, Int y);
+void gen_runmath1(stack *Stack)
+{
+ Int y=vm::pop<Int>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 201 "runmath.in"
+ {Stack->push<pair>(pow(z,y)); return;}
+}
+
+#line 205 "runmath.in"
+// Int quotient(Int x, Int y);
+void gen_runmath2(stack *Stack)
+{
+ Int y=vm::pop<Int>(Stack);
+ Int x=vm::pop<Int>(Stack);
+#line 206 "runmath.in"
+ {Stack->push<Int>(quotient<Int>()(x,y)); return;}
+}
+
+#line 210 "runmath.in"
+// Int abs(Int x);
+void gen_runmath3(stack *Stack)
+{
+ Int x=vm::pop<Int>(Stack);
+#line 211 "runmath.in"
+ {Stack->push<Int>(Abs(x)); return;}
+}
+
+#line 215 "runmath.in"
+// Int sgn(real x);
+void gen_runmath4(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 216 "runmath.in"
+ {Stack->push<Int>(sgn(x)); return;}
+}
+
+#line 220 "runmath.in"
+// Int rand();
+void gen_runmath5(stack *Stack)
+{
+#line 221 "runmath.in"
+ if(initializeRandom)
+ Srand(1);
+ {Stack->push<Int>(random()); return;}
+}
+
+#line 227 "runmath.in"
+// void srand(Int seed);
+void gen_runmath6(stack *Stack)
+{
+ Int seed=vm::pop<Int>(Stack);
+#line 228 "runmath.in"
+ Srand(seed);
+}
+
+// a random number uniformly distributed in the interval [0,1]
+#line 233 "runmath.in"
+// real unitrand();
+void gen_runmath7(stack *Stack)
+{
+#line 234 "runmath.in"
+ {Stack->push<real>(((real) random())/RANDOM_MAX); return;}
+}
+
+#line 238 "runmath.in"
+// Int ceil(real x);
+void gen_runmath8(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 239 "runmath.in"
+ {Stack->push<Int>(Intcast(ceil(x))); return;}
+}
+
+#line 243 "runmath.in"
+// Int floor(real x);
+void gen_runmath9(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 244 "runmath.in"
+ {Stack->push<Int>(Intcast(floor(x))); return;}
+}
+
+#line 248 "runmath.in"
+// Int round(real x);
+void gen_runmath10(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 249 "runmath.in"
+ if(validInt(x)) {Stack->push<Int>(Round(x)); return;}
+ integeroverflow(0);
+}
+
+#line 254 "runmath.in"
+// Int Ceil(real x);
+void gen_runmath11(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 255 "runmath.in"
+ {Stack->push<Int>(Ceil(x)); return;}
+}
+
+#line 259 "runmath.in"
+// Int Floor(real x);
+void gen_runmath12(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 260 "runmath.in"
+ {Stack->push<Int>(Floor(x)); return;}
+}
+
+#line 264 "runmath.in"
+// Int Round(real x);
+void gen_runmath13(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 265 "runmath.in"
+ {Stack->push<Int>(Round(Intcap(x))); return;}
+}
+
+#line 269 "runmath.in"
+// real fmod(real x, real y);
+void gen_runmath14(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 270 "runmath.in"
+ if (y == 0.0) dividebyzero();
+ {Stack->push<real>(fmod(x,y)); return;}
+}
+
+#line 275 "runmath.in"
+// real atan2(real y, real x);
+void gen_runmath15(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+#line 276 "runmath.in"
+ {Stack->push<real>(atan2(y,x)); return;}
+}
+
+#line 280 "runmath.in"
+// real hypot(real x, real y);
+void gen_runmath16(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 281 "runmath.in"
+ {Stack->push<real>(hypot(x,y)); return;}
+}
+
+#line 285 "runmath.in"
+// real remainder(real x, real y);
+void gen_runmath17(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 286 "runmath.in"
+ {Stack->push<real>(remainder(x,y)); return;}
+}
+
+#line 290 "runmath.in"
+// real Jn(Int n, real x);
+void gen_runmath18(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 291 "runmath.in"
+ {Stack->push<real>(jn(n,x)); return;}
+}
+
+#line 295 "runmath.in"
+// real Yn(Int n, real x);
+void gen_runmath19(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 296 "runmath.in"
+ {Stack->push<real>(yn(n,x)); return;}
+}
+
+#line 300 "runmath.in"
+// real erf(real x);
+void gen_runmath20(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 301 "runmath.in"
+ {Stack->push<real>(erf(x)); return;}
+}
+
+#line 305 "runmath.in"
+// real erfc(real x);
+void gen_runmath21(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 306 "runmath.in"
+ {Stack->push<real>(erfc(x)); return;}
+}
+
+#line 310 "runmath.in"
+// Int factorial(Int n);
+void gen_runmath22(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 311 "runmath.in"
+ if(n < 0) error(invalidargument);
+ {Stack->push<Int>(factorial(n)); return;}
+}
+
+#line 315 "runmath.in"
+// Int choose(Int n, Int k);
+void gen_runmath23(stack *Stack)
+{
+ Int k=vm::pop<Int>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 316 "runmath.in"
+ if(n < 0 || k < 0 || k > n) error(invalidargument);
+ Int f=1;
+ Int r=n-k;
+ for(Int i=n; i > r; --i) {
+ if(f > Int_MAX/i) integeroverflow(0);
+ f=(f*i)/(n-i+1);
+ }
+ {Stack->push<Int>(f); return;}
+}
+
+#line 326 "runmath.in"
+// real gamma(real x);
+void gen_runmath24(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 327 "runmath.in"
+#ifdef HAVE_TGAMMA
+ {Stack->push<real>(tgamma(x)); return;}
+#else
+ real lg = lgamma(x);
+ {Stack->push<real>(signgam*exp(lg)); return;}
+#endif
+}
+
+#line 336 "runmath.in"
+// realarray* quadraticroots(real a, real b, real c);
+void gen_runmath25(stack *Stack)
+{
+ real c=vm::pop<real>(Stack);
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+#line 337 "runmath.in"
+ quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots == 2) (*roots)[1]=q.t2;
+ {Stack->push<realarray*>(roots); return;}
+}
+
+#line 345 "runmath.in"
+// pairarray* quadraticroots(explicit pair a, explicit pair b, explicit pair c);
+void gen_runmath26(stack *Stack)
+{
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 346 "runmath.in"
+ Quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.z1;
+ if(q.roots == 2) (*roots)[1]=q.z2;
+ {Stack->push<pairarray*>(roots); return;}
+}
+
+#line 354 "runmath.in"
+// realarray* cubicroots(real a, real b, real c, real d);
+void gen_runmath27(stack *Stack)
+{
+ real d=vm::pop<real>(Stack);
+ real c=vm::pop<real>(Stack);
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+#line 355 "runmath.in"
+ cubicroots q(a,b,c,d);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots >= 2) (*roots)[1]=q.t2;
+ if(q.roots == 3) (*roots)[2]=q.t3;
+ {Stack->push<realarray*>(roots); return;}
+}
+
+
+// Logical operations
+#line 366 "runmath.in"
+// bool !(bool b);
+void gen_runmath28(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack);
+#line 367 "runmath.in"
+ {Stack->push<bool>(!b); return;}
+}
+
+#line 372 "runmath.in"
+void boolMemEq(stack *Stack)
+{
+ frame * b=vm::pop<frame *>(Stack);
+ frame * a=vm::pop<frame *>(Stack);
+#line 373 "runmath.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 377 "runmath.in"
+void boolMemNeq(stack *Stack)
+{
+ frame * b=vm::pop<frame *>(Stack);
+ frame * a=vm::pop<frame *>(Stack);
+#line 378 "runmath.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 382 "runmath.in"
+void boolFuncEq(stack *Stack)
+{
+ callable * b=vm::pop<callable *>(Stack);
+ callable * a=vm::pop<callable *>(Stack);
+#line 383 "runmath.in"
+ {Stack->push<bool>(a->compare(b)); return;}
+}
+
+#line 387 "runmath.in"
+void boolFuncNeq(stack *Stack)
+{
+ callable * b=vm::pop<callable *>(Stack);
+ callable * a=vm::pop<callable *>(Stack);
+#line 388 "runmath.in"
+ {Stack->push<bool>(!(a->compare(b))); return;}
+}
+
+
+// Bit operations
+#line 394 "runmath.in"
+// Int AND(Int a, Int b);
+void gen_runmath33(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+#line 395 "runmath.in"
+ {Stack->push<Int>(a & b); return;}
+}
+
+#line 400 "runmath.in"
+// Int OR(Int a, Int b);
+void gen_runmath34(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+#line 401 "runmath.in"
+ {Stack->push<Int>(a | b); return;}
+}
+
+#line 405 "runmath.in"
+// Int XOR(Int a, Int b);
+void gen_runmath35(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+#line 406 "runmath.in"
+ {Stack->push<Int>(a ^ b); return;}
+}
+
+#line 410 "runmath.in"
+// Int NOT(Int a);
+void gen_runmath36(stack *Stack)
+{
+ Int a=vm::pop<Int>(Stack);
+#line 411 "runmath.in"
+ {Stack->push<Int>(~a); return;}
+}
+
+#line 415 "runmath.in"
+// Int CLZ(Int a);
+void gen_runmath37(stack *Stack)
+{
+ Int a=vm::pop<Int>(Stack);
+#line 416 "runmath.in"
+ if((unsigned long long) a > 0xFFFFFFFF)
+ {Stack->push<Int>(CLZ((uint32_t) ((unsigned long long) a >> 32))); return;}
+ else {
+ int bits=intbits();
+ if(a != 0) {Stack->push<Int>(bits-32+CLZ((uint32_t) a)); return;}
+ {Stack->push<Int>(bits); return;}
+ }
+}
+
+#line 426 "runmath.in"
+// Int popcount(Int a);
+void gen_runmath38(stack *Stack)
+{
+ Int a=vm::pop<Int>(Stack);
+#line 427 "runmath.in"
+ {Stack->push<Int>(popcount(a)); return;}
+}
+
+#line 431 "runmath.in"
+// Int CTZ(Int a);
+void gen_runmath39(stack *Stack)
+{
+ Int a=vm::pop<Int>(Stack);
+#line 432 "runmath.in"
+ {Stack->push<Int>(popcount((a&-a)-1)); return;}
+}
+
+// bitreverse a within a word of length bits.
+#line 437 "runmath.in"
+// Int bitreverse(Int a, Int bits);
+void gen_runmath40(stack *Stack)
+{
+ Int bits=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+#line 438 "runmath.in"
+ typedef unsigned long long Bitreverse(unsigned long long a);
+ static Bitreverse *B[]={bitreverse8,bitreverse16,bitreverse24,bitreverse32,
+ bitreverse40,bitreverse48,bitreverse56,bitreverse64};
+ int maxbits=intbits()-1; // Drop sign bit
+#if Int_MAX2 >= 0x7fffffffffffffffLL
+ --maxbits; // Drop extra bit for reserved values
+#endif
+ if(bits <= 0 || bits > maxbits || a < 0 ||
+ (unsigned long long) a >= (1ULL << bits))
+ {Stack->push<Int>(-1); return;}
+ unsigned int bytes=(bits+7)/8;
+ {Stack->push<Int>(B[bytes-1]((unsigned long long) a) >> (8*bytes-bits)); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runmath_venv(venv &ve)
+{
+#line 195 "runmath.in"
+ addFunc(ve, run::gen_runmath0, primReal(), SYM_CARET, formal(primReal(), SYM(x), false, false), formal(primInt(), SYM(y), false, false));
+#line 200 "runmath.in"
+ addFunc(ve, run::gen_runmath1, primPair(), SYM_CARET, formal(primPair(), SYM(z), false, false), formal(primInt(), SYM(y), false, false));
+#line 205 "runmath.in"
+ addFunc(ve, run::gen_runmath2, primInt(), SYM(quotient), formal(primInt(), SYM(x), false, false), formal(primInt(), SYM(y), false, false));
+#line 210 "runmath.in"
+ addFunc(ve, run::gen_runmath3, primInt(), SYM(abs), formal(primInt(), SYM(x), false, false));
+#line 215 "runmath.in"
+ addFunc(ve, run::gen_runmath4, primInt(), SYM(sgn), formal(primReal(), SYM(x), false, false));
+#line 220 "runmath.in"
+ addFunc(ve, run::gen_runmath5, primInt(), SYM(rand));
+#line 227 "runmath.in"
+ addFunc(ve, run::gen_runmath6, primVoid(), SYM(srand), formal(primInt(), SYM(seed), false, false));
+#line 232 "runmath.in"
+ addFunc(ve, run::gen_runmath7, primReal(), SYM(unitrand));
+#line 238 "runmath.in"
+ addFunc(ve, run::gen_runmath8, primInt(), SYM(ceil), formal(primReal(), SYM(x), false, false));
+#line 243 "runmath.in"
+ addFunc(ve, run::gen_runmath9, primInt(), SYM(floor), formal(primReal(), SYM(x), false, false));
+#line 248 "runmath.in"
+ addFunc(ve, run::gen_runmath10, primInt(), SYM(round), formal(primReal(), SYM(x), false, false));
+#line 254 "runmath.in"
+ addFunc(ve, run::gen_runmath11, primInt(), SYM(Ceil), formal(primReal(), SYM(x), false, false));
+#line 259 "runmath.in"
+ addFunc(ve, run::gen_runmath12, primInt(), SYM(Floor), formal(primReal(), SYM(x), false, false));
+#line 264 "runmath.in"
+ addFunc(ve, run::gen_runmath13, primInt(), SYM(Round), formal(primReal(), SYM(x), false, false));
+#line 269 "runmath.in"
+ addFunc(ve, run::gen_runmath14, primReal(), SYM(fmod), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
+#line 275 "runmath.in"
+ addFunc(ve, run::gen_runmath15, primReal(), SYM(atan2), formal(primReal(), SYM(y), false, false), formal(primReal(), SYM(x), false, false));
+#line 280 "runmath.in"
+ addFunc(ve, run::gen_runmath16, primReal(), SYM(hypot), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
+#line 285 "runmath.in"
+ addFunc(ve, run::gen_runmath17, primReal(), SYM(remainder), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
+#line 290 "runmath.in"
+ addFunc(ve, run::gen_runmath18, primReal(), SYM(Jn), formal(primInt(), SYM(n), false, false), formal(primReal(), SYM(x), false, false));
+#line 295 "runmath.in"
+ addFunc(ve, run::gen_runmath19, primReal(), SYM(Yn), formal(primInt(), SYM(n), false, false), formal(primReal(), SYM(x), false, false));
+#line 300 "runmath.in"
+ addFunc(ve, run::gen_runmath20, primReal(), SYM(erf), formal(primReal(), SYM(x), false, false));
+#line 305 "runmath.in"
+ addFunc(ve, run::gen_runmath21, primReal(), SYM(erfc), formal(primReal(), SYM(x), false, false));
+#line 310 "runmath.in"
+ addFunc(ve, run::gen_runmath22, primInt(), SYM(factorial), formal(primInt(), SYM(n), false, false));
+#line 315 "runmath.in"
+ addFunc(ve, run::gen_runmath23, primInt(), SYM(choose), formal(primInt(), SYM(n), false, false), formal(primInt(), SYM(k), false, false));
+#line 326 "runmath.in"
+ addFunc(ve, run::gen_runmath24, primReal(), SYM(gamma), formal(primReal(), SYM(x), false, false));
+#line 336 "runmath.in"
+ addFunc(ve, run::gen_runmath25, realArray(), SYM(quadraticroots), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(c), false, false));
+#line 345 "runmath.in"
+ addFunc(ve, run::gen_runmath26, pairArray(), SYM(quadraticroots), formal(primPair(), SYM(a), false, true), formal(primPair(), SYM(b), false, true), formal(primPair(), SYM(c), false, true));
+#line 354 "runmath.in"
+ addFunc(ve, run::gen_runmath27, realArray(), SYM(cubicroots), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(c), false, false), formal(primReal(), SYM(d), false, false));
+#line 364 "runmath.in"
+ addFunc(ve, run::gen_runmath28, primBoolean(), SYM_LOGNOT, formal(primBoolean(), SYM(b), false, false));
+#line 372 "runmath.in"
+ REGISTER_BLTIN(run::boolMemEq,"boolMemEq");
+#line 377 "runmath.in"
+ REGISTER_BLTIN(run::boolMemNeq,"boolMemNeq");
+#line 382 "runmath.in"
+ REGISTER_BLTIN(run::boolFuncEq,"boolFuncEq");
+#line 387 "runmath.in"
+ REGISTER_BLTIN(run::boolFuncNeq,"boolFuncNeq");
+#line 392 "runmath.in"
+ addFunc(ve, run::gen_runmath33, primInt(), SYM(AND), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
+#line 400 "runmath.in"
+ addFunc(ve, run::gen_runmath34, primInt(), SYM(OR), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
+#line 405 "runmath.in"
+ addFunc(ve, run::gen_runmath35, primInt(), SYM(XOR), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
+#line 410 "runmath.in"
+ addFunc(ve, run::gen_runmath36, primInt(), SYM(NOT), formal(primInt(), SYM(a), false, false));
+#line 415 "runmath.in"
+ addFunc(ve, run::gen_runmath37, primInt(), SYM(CLZ), formal(primInt(), SYM(a), false, false));
+#line 426 "runmath.in"
+ addFunc(ve, run::gen_runmath38, primInt(), SYM(popcount), formal(primInt(), SYM(a), false, false));
+#line 431 "runmath.in"
+ addFunc(ve, run::gen_runmath39, primInt(), SYM(CTZ), formal(primInt(), SYM(a), false, false));
+#line 436 "runmath.in"
+ addFunc(ve, run::gen_runmath40, primInt(), SYM(bitreverse), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(bits), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runmath.h b/graphics/asymptote/runmath.h
new file mode 100644
index 0000000000..a9e030cb73
--- /dev/null
+++ b/graphics/asymptote/runmath.h
@@ -0,0 +1,12 @@
+/***** Autogenerated from runmath.in; changes will be overwritten *****/
+
+#ifndef runmath_H
+#define runmath_H
+namespace run {
+void boolMemEq(vm::stack *);
+void boolMemNeq(vm::stack *);
+void boolFuncEq(vm::stack *);
+void boolFuncNeq(vm::stack *);
+}
+
+#endif // runmath_H
diff --git a/graphics/asymptote/runmath.in b/graphics/asymptote/runmath.in
new file mode 100644
index 0000000000..fa9dbf3e69
--- /dev/null
+++ b/graphics/asymptote/runmath.in
@@ -0,0 +1,451 @@
+/*****
+ * runmath.in
+ *
+ * Runtime functions for math operations.
+ *
+ *****/
+
+pair => primPair()
+realarray* => realArray()
+pairarray* => pairArray()
+
+#include <inttypes.h>
+
+#include "mathop.h"
+#include "path.h"
+
+#ifdef __CYGWIN__
+extern "C" double yn(int, double);
+extern "C" double jn(int, double);
+extern "C" int __signgam;
+#define signgam __signgam
+#endif
+
+using namespace camp;
+
+typedef array realarray;
+typedef array pairarray;
+
+using types::realArray;
+using types::pairArray;
+
+using run::integeroverflow;
+using vm::frame;
+
+const char *invalidargument="invalid argument";
+
+extern uint32_t CLZ(uint32_t a);
+
+inline unsigned intbits() {
+ static unsigned count=0;
+ if(count > 0) return count;
+ while((1ULL << count) < Int_MAX)
+ ++count;
+ ++count;
+ return count;
+}
+
+static const unsigned char BitReverseTable8[256]=
+{
+#define R2(n) n, n+2*64, n+1*64, n+3*64
+#define R4(n) R2(n),R2(n+2*16),R2(n+1*16),R2(n+3*16)
+#define R6(n) R4(n),R4(n+2*4 ),R4(n+1*4 ),R4(n+3*4 )
+R6(0),R6(2),R6(1),R6(3)
+};
+#undef R2
+#undef R4
+#undef R6
+
+unsigned long long bitreverse8(unsigned long long a)
+{
+ return
+ (unsigned long long) BitReverseTable8[a];
+}
+
+unsigned long long bitreverse16(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 8)]);
+}
+
+unsigned long long bitreverse24(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 16)]);
+}
+
+unsigned long long bitreverse32(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 24)]);
+}
+
+unsigned long long bitreverse40(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 32)]);
+}
+
+unsigned long long bitreverse48(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 40) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 32) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 40)]);
+}
+
+unsigned long long bitreverse56(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 48) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 40) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 32) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 40) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 48)]);
+}
+
+unsigned long long bitreverse64(unsigned long long a)
+{
+ return
+ ((unsigned long long) BitReverseTable8[a & 0xff] << 56) |
+ ((unsigned long long) BitReverseTable8[(a >> 8) & 0xff] << 48) |
+ ((unsigned long long) BitReverseTable8[(a >> 16) & 0xff] << 40) |
+ ((unsigned long long) BitReverseTable8[(a >> 24) & 0xff] << 32) |
+ ((unsigned long long) BitReverseTable8[(a >> 32) & 0xff] << 24) |
+ ((unsigned long long) BitReverseTable8[(a >> 40) & 0xff] << 16) |
+ ((unsigned long long) BitReverseTable8[(a >> 48) & 0xff] << 8) |
+ ((unsigned long long) BitReverseTable8[(a >> 56)]);
+}
+
+// From Warren, Jr., Henry S. (2013) [2002]. Hacker's Delight (2 ed.).
+// Addison Wesley - Pearson Education, Inc. pp. 81-96.
+Int popcount(Int a)
+{
+ const uint64_t m1 = 0x5555555555555555; //binary: 0101...
+ const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
+ const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
+ const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
+
+// This algorithm uses 12 arithmetic operations, one of which is a multiply.
+ a -= (a >> 1) & m1; //put count of each 2 bits into those 2 bits
+ a=(a & m2)+((a >> 2) & m2); //put count of each 4 bits into those 4 bits
+ a=(a+(a >> 4)) & m4; //put count of each 8 bits into those 8 bits
+ return (a * h01) >> 56; //returns left 8 bits of a+(a << 8)+(a << 16)+(a << 24)+...
+}
+
+// Return the factorial of a non-negative integer using a lookup table.
+Int factorial(Int n)
+{
+ static Int *table;
+ static Int size=0;
+ if(size == 0) {
+ Int f=1;
+ size=2;
+ while(f <= Int_MAX/size)
+ f *= (size++);
+ table=new Int[size];
+ table[0]=f=1;
+ for(Int i=1; i < size; ++i) {
+ f *= i;
+ table[i]=f;
+ }
+ }
+ if(n >= size) integeroverflow(0);
+ return table[n];
+}
+
+static inline Int Round(double x)
+{
+ return Int(x+((x >= 0) ? 0.5 : -0.5));
+}
+
+inline Int sgn(double x)
+{
+ return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0));
+}
+
+static bool initializeRandom=true;
+
+void Srand(Int seed)
+{
+ initializeRandom=false;
+ const int n=256;
+ static char state[n];
+ initstate(intcast(seed),state,n);
+}
+
+// Autogenerated routines:
+
+
+real ^(real x, Int y)
+{
+ return pow(x,y);
+}
+
+pair ^(pair z, Int y)
+{
+ return pow(z,y);
+}
+
+Int quotient(Int x, Int y)
+{
+ return quotient<Int>()(x,y);
+}
+
+Int abs(Int x)
+{
+ return Abs(x);
+}
+
+Int sgn(real x)
+{
+ return sgn(x);
+}
+
+Int rand()
+{
+ if(initializeRandom)
+ Srand(1);
+ return random();
+}
+
+void srand(Int seed)
+{
+ Srand(seed);
+}
+
+// a random number uniformly distributed in the interval [0,1]
+real unitrand()
+{
+ return ((real) random())/RANDOM_MAX;
+}
+
+Int ceil(real x)
+{
+ return Intcast(ceil(x));
+}
+
+Int floor(real x)
+{
+ return Intcast(floor(x));
+}
+
+Int round(real x)
+{
+ if(validInt(x)) return Round(x);
+ integeroverflow(0);
+}
+
+Int Ceil(real x)
+{
+ return Ceil(x);
+}
+
+Int Floor(real x)
+{
+ return Floor(x);
+}
+
+Int Round(real x)
+{
+ return Round(Intcap(x));
+}
+
+real fmod(real x, real y)
+{
+ if (y == 0.0) dividebyzero();
+ return fmod(x,y);
+}
+
+real atan2(real y, real x)
+{
+ return atan2(y,x);
+}
+
+real hypot(real x, real y)
+{
+ return hypot(x,y);
+}
+
+real remainder(real x, real y)
+{
+ return remainder(x,y);
+}
+
+real Jn(Int n, real x)
+{
+ return jn(n,x);
+}
+
+real Yn(Int n, real x)
+{
+ return yn(n,x);
+}
+
+real erf(real x)
+{
+ return erf(x);
+}
+
+real erfc(real x)
+{
+ return erfc(x);
+}
+
+Int factorial(Int n) {
+ if(n < 0) error(invalidargument);
+ return factorial(n);
+}
+
+Int choose(Int n, Int k) {
+ if(n < 0 || k < 0 || k > n) error(invalidargument);
+ Int f=1;
+ Int r=n-k;
+ for(Int i=n; i > r; --i) {
+ if(f > Int_MAX/i) integeroverflow(0);
+ f=(f*i)/(n-i+1);
+ }
+ return f;
+}
+
+real gamma(real x)
+{
+#ifdef HAVE_TGAMMA
+ return tgamma(x);
+#else
+ real lg = lgamma(x);
+ return signgam*exp(lg);
+#endif
+}
+
+realarray *quadraticroots(real a, real b, real c)
+{
+ quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots == 2) (*roots)[1]=q.t2;
+ return roots;
+}
+
+pairarray *quadraticroots(explicit pair a, explicit pair b, explicit pair c)
+{
+ Quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.z1;
+ if(q.roots == 2) (*roots)[1]=q.z2;
+ return roots;
+}
+
+realarray *cubicroots(real a, real b, real c, real d)
+{
+ cubicroots q(a,b,c,d);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots >= 2) (*roots)[1]=q.t2;
+ if(q.roots == 3) (*roots)[2]=q.t3;
+ return roots;
+}
+
+
+// Logical operations
+
+bool !(bool b)
+{
+ return !b;
+}
+
+bool :boolMemEq(frame *a, frame *b)
+{
+ return a == b;
+}
+
+bool :boolMemNeq(frame *a, frame *b)
+{
+ return a != b;
+}
+
+bool :boolFuncEq(callable *a, callable *b)
+{
+ return a->compare(b);
+}
+
+bool :boolFuncNeq(callable *a, callable *b)
+{
+ return !(a->compare(b));
+}
+
+
+// Bit operations
+
+Int AND(Int a, Int b)
+{
+ return a & b;
+}
+
+Int OR(Int a, Int b)
+{
+ return a | b;
+}
+
+Int XOR(Int a, Int b)
+{
+ return a ^ b;
+}
+
+Int NOT(Int a)
+{
+ return ~a;
+}
+
+Int CLZ(Int a)
+{
+ if((unsigned long long) a > 0xFFFFFFFF)
+ return CLZ((uint32_t) ((unsigned long long) a >> 32));
+ else {
+ int bits=intbits();
+ if(a != 0) return bits-32+CLZ((uint32_t) a);
+ return bits;
+ }
+}
+
+Int popcount(Int a)
+{
+ return popcount(a);
+}
+
+Int CTZ(Int a)
+{
+ return popcount((a&-a)-1);
+}
+
+// bitreverse a within a word of length bits.
+Int bitreverse(Int a, Int bits)
+{
+ typedef unsigned long long Bitreverse(unsigned long long a);
+ static Bitreverse *B[]={bitreverse8,bitreverse16,bitreverse24,bitreverse32,
+ bitreverse40,bitreverse48,bitreverse56,bitreverse64};
+ int maxbits=intbits()-1; // Drop sign bit
+#if Int_MAX2 >= 0x7fffffffffffffffLL
+ --maxbits; // Drop extra bit for reserved values
+#endif
+ if(bits <= 0 || bits > maxbits || a < 0 ||
+ (unsigned long long) a >= (1ULL << bits))
+ return -1;
+ unsigned int bytes=(bits+7)/8;
+ return B[bytes-1]((unsigned long long) a) >> (8*bytes-bits);
+}
diff --git a/graphics/asymptote/runpair.cc b/graphics/asymptote/runpair.cc
new file mode 100644
index 0000000000..b4e8637f37
--- /dev/null
+++ b/graphics/asymptote/runpair.cc
@@ -0,0 +1,567 @@
+/***** Autogenerated from runpair.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runpair.in"
+/*****
+ * runpair.in
+ *
+ * Runtime functions for pair operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 10 "runpair.in"
+#include "pair.h"
+
+using namespace camp;
+
+namespace run {
+extern pair zero;
+}
+
+pair sin(pair z)
+{
+ return pair(sin(z.getx())*cosh(z.gety()),cos(z.getx())*sinh(z.gety()));
+}
+
+pair exp(pair z)
+{
+ return exp(z.getx())*expi(z.gety());
+}
+
+pair gamma(pair z)
+{
+ static double p[]={0.99999999999980993,676.5203681218851,-1259.1392167224028,
+ 771.32342877765313,-176.61502916214059,12.507343278686905,
+ -0.13857109526572012,9.9843695780195716e-6,
+ 1.5056327351493116e-7};
+ static int n=sizeof(p)/sizeof(double);
+ static double root2pi=sqrt(2*PI);
+ if(z.getx() < 0.5)
+ return PI/(sin(PI*z)*gamma(1.0-z));
+ z -= 1.0;
+ pair x=p[0];
+ for(int i=1; i < n; ++i)
+ x += p[i]/(z+i);
+ pair t=n-1.5+z;
+ return root2pi*pow(t,z+0.5)*exp(-t)*x;
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runpair.symbols.h"
+
+#endif
+namespace run {
+#line 49 "runpair.in"
+void pairZero(stack *Stack)
+{
+#line 50 "runpair.in"
+ {Stack->push<pair>(zero); return;}
+}
+
+#line 54 "runpair.in"
+void realRealToPair(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 55 "runpair.in"
+ {Stack->push<pair>(pair(x,y)); return;}
+}
+
+#line 59 "runpair.in"
+void pairNegate(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 60 "runpair.in"
+ {Stack->push<pair>(-z); return;}
+}
+
+#line 64 "runpair.in"
+// real xpart(pair z);
+void pairXPart(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 65 "runpair.in"
+ {Stack->push<real>(z.getx()); return;}
+}
+
+#line 69 "runpair.in"
+// real ypart(pair z);
+void pairYPart(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 70 "runpair.in"
+ {Stack->push<real>(z.gety()); return;}
+}
+
+#line 74 "runpair.in"
+// real length(pair z);
+void gen_runpair5(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 75 "runpair.in"
+ {Stack->push<real>(z.length()); return;}
+}
+
+#line 79 "runpair.in"
+// real abs(pair z);
+void gen_runpair6(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 80 "runpair.in"
+ {Stack->push<real>(z.length()); return;}
+}
+
+#line 84 "runpair.in"
+// pair sqrt(explicit pair z);
+void gen_runpair7(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 85 "runpair.in"
+ {Stack->push<pair>(Sqrt(z)); return;}
+}
+
+// Return the angle of z in radians.
+#line 90 "runpair.in"
+// real angle(pair z, bool warn=true);
+void gen_runpair8(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ pair z=vm::pop<pair>(Stack);
+#line 91 "runpair.in"
+ if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(z.angle()); return;}
+}
+
+// Return the angle of z in degrees in the interval [0,360).
+#line 97 "runpair.in"
+// real degrees(pair z, bool warn=true);
+void gen_runpair9(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ pair z=vm::pop<pair>(Stack);
+#line 98 "runpair.in"
+ if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(principalBranch(degrees(z.angle()))); return;}
+}
+
+// Convert degrees to radians.
+#line 104 "runpair.in"
+// real radians(real degrees);
+void gen_runpair10(stack *Stack)
+{
+ real degrees=vm::pop<real>(Stack);
+#line 105 "runpair.in"
+ {Stack->push<real>(radians(degrees)); return;}
+}
+
+// Convert radians to degrees.
+#line 110 "runpair.in"
+// real degrees(real radians);
+void gen_runpair11(stack *Stack)
+{
+ real radians=vm::pop<real>(Stack);
+#line 111 "runpair.in"
+ {Stack->push<real>(degrees(radians)); return;}
+}
+
+// Convert radians to degrees in [0,360).
+#line 116 "runpair.in"
+// real Degrees(real radians);
+void gen_runpair12(stack *Stack)
+{
+ real radians=vm::pop<real>(Stack);
+#line 117 "runpair.in"
+ {Stack->push<real>(principalBranch(degrees(radians))); return;}
+}
+
+#line 121 "runpair.in"
+// real Sin(real deg);
+void gen_runpair13(stack *Stack)
+{
+ real deg=vm::pop<real>(Stack);
+#line 122 "runpair.in"
+ int n=(int) (deg/90.0);
+ if(deg == n*90.0) {
+ int m=n % 4;
+ if(m < 0) m += 4;
+ if(m == 1) {Stack->push<real>(1); return;}
+ if(m == 3) {Stack->push<real>(-1); return;}
+ {Stack->push<real>(0.0); return;}
+ }
+ {Stack->push<real>(sin(radians(deg))); return;}
+}
+
+#line 134 "runpair.in"
+// real Cos(real deg);
+void gen_runpair14(stack *Stack)
+{
+ real deg=vm::pop<real>(Stack);
+#line 135 "runpair.in"
+ int n=(int) (deg/90.0);
+ if(deg == n*90.0) {
+ int m=n % 4;
+ if(m < 0) m += 4;
+ if(m == 0) {Stack->push<real>(1); return;}
+ if(m == 2) {Stack->push<real>(-1); return;}
+ {Stack->push<real>(0.0); return;}
+ }
+ {Stack->push<real>(cos(radians(deg))); return;}
+}
+
+#line 147 "runpair.in"
+// real Tan(real deg);
+void gen_runpair15(stack *Stack)
+{
+ real deg=vm::pop<real>(Stack);
+#line 148 "runpair.in"
+ int n=(int) (deg/90.0);
+ if(deg == n*90.0) {
+ int m=n % 4;
+ if(m < 0) m += 4;
+ if(m == 1) {Stack->push<real>(HUGE_VAL); return;}
+ if(m == 3) {Stack->push<real>(-HUGE_VAL); return;}
+ {Stack->push<real>(0.0); return;}
+ }
+ {Stack->push<real>(tan(radians(deg))); return;}
+}
+
+#line 160 "runpair.in"
+// real aSin(real x);
+void gen_runpair16(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 161 "runpair.in"
+ {Stack->push<real>(degrees(asin(x))); return;}
+}
+
+#line 165 "runpair.in"
+// real aCos(real x);
+void gen_runpair17(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 166 "runpair.in"
+ {Stack->push<real>(degrees(acos(x))); return;}
+}
+
+#line 170 "runpair.in"
+// real aTan(real x);
+void gen_runpair18(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 171 "runpair.in"
+ {Stack->push<real>(degrees(atan(x))); return;}
+}
+
+#line 175 "runpair.in"
+// pair unit(pair z);
+void gen_runpair19(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 176 "runpair.in"
+ {Stack->push<pair>(unit(z)); return;}
+}
+
+#line 180 "runpair.in"
+// pair dir(real degrees);
+void gen_runpair20(stack *Stack)
+{
+ real degrees=vm::pop<real>(Stack);
+#line 181 "runpair.in"
+ {Stack->push<pair>(expi(radians(degrees))); return;}
+}
+
+#line 185 "runpair.in"
+// pair dir(explicit pair z);
+void gen_runpair21(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 186 "runpair.in"
+ {Stack->push<pair>(unit(z)); return;}
+}
+
+#line 190 "runpair.in"
+// pair expi(real angle);
+void gen_runpair22(stack *Stack)
+{
+ real angle=vm::pop<real>(Stack);
+#line 191 "runpair.in"
+ {Stack->push<pair>(expi(angle)); return;}
+}
+
+#line 195 "runpair.in"
+// pair exp(explicit pair z);
+void gen_runpair23(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 196 "runpair.in"
+ {Stack->push<pair>(exp(z)); return;}
+}
+
+#line 200 "runpair.in"
+// pair log(explicit pair z);
+void gen_runpair24(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 201 "runpair.in"
+ {Stack->push<pair>(pair(log(z.length()),z.angle())); return;}
+}
+
+#line 205 "runpair.in"
+// pair sin(explicit pair z);
+void gen_runpair25(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 206 "runpair.in"
+ {Stack->push<pair>(sin(z)); return;}
+}
+
+#line 210 "runpair.in"
+// pair cos(explicit pair z);
+void gen_runpair26(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 211 "runpair.in"
+ {Stack->push<pair>(pair(cos(z.getx())*cosh(z.gety()),-sin(z.getx())*sinh(z.gety()))); return;}
+}
+
+// Complex Gamma function
+#line 216 "runpair.in"
+// pair gamma(explicit pair z);
+void gen_runpair27(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 217 "runpair.in"
+ {Stack->push<pair>(gamma(z)); return;}
+}
+
+#line 221 "runpair.in"
+// pair conj(pair z);
+void gen_runpair28(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 222 "runpair.in"
+ {Stack->push<pair>(conj(z)); return;}
+}
+
+#line 226 "runpair.in"
+// pair realmult(pair z, pair w);
+void gen_runpair29(stack *Stack)
+{
+ pair w=vm::pop<pair>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 227 "runpair.in"
+ {Stack->push<pair>(pair(z.getx()*w.getx(),z.gety()*w.gety())); return;}
+}
+
+// To avoid confusion, a dot product requires explicit pair arguments.
+#line 232 "runpair.in"
+// real dot(explicit pair z, explicit pair w);
+void gen_runpair30(stack *Stack)
+{
+ pair w=vm::pop<pair>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 233 "runpair.in"
+ {Stack->push<real>(dot(z,w)); return;}
+}
+
+// Return the 2D scalar cross product z.x*w.y-z.y*w.x.
+#line 238 "runpair.in"
+// real cross(explicit pair z, explicit pair w);
+void gen_runpair31(stack *Stack)
+{
+ pair w=vm::pop<pair>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 239 "runpair.in"
+ {Stack->push<real>(cross(z,w)); return;}
+}
+
+#line 243 "runpair.in"
+// pair bezier(pair a, pair b, pair c, pair d, real t);
+void gen_runpair32(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ pair d=vm::pop<pair>(Stack);
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 244 "runpair.in"
+ real onemt=1-t;
+ real onemt2=onemt*onemt;
+ {Stack->push<pair>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
+}
+
+#line 250 "runpair.in"
+// pair bezierP(pair a, pair b, pair c, pair d, real t);
+void gen_runpair33(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ pair d=vm::pop<pair>(Stack);
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 251 "runpair.in"
+ {Stack->push<pair>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
+}
+
+#line 255 "runpair.in"
+// pair bezierPP(pair a, pair b, pair c, pair d, real t);
+void gen_runpair34(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ pair d=vm::pop<pair>(Stack);
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 256 "runpair.in"
+ {Stack->push<pair>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
+}
+
+#line 260 "runpair.in"
+// pair bezierPPP(pair a, pair b, pair c, pair d);
+void gen_runpair35(stack *Stack)
+{
+ pair d=vm::pop<pair>(Stack);
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 261 "runpair.in"
+ {Stack->push<pair>(6.0*(d-a+3.0*(b-c))); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runpair_venv(venv &ve)
+{
+#line 49 "runpair.in"
+ REGISTER_BLTIN(run::pairZero,"pairZero");
+#line 54 "runpair.in"
+ REGISTER_BLTIN(run::realRealToPair,"realRealToPair");
+#line 59 "runpair.in"
+ REGISTER_BLTIN(run::pairNegate,"pairNegate");
+#line 64 "runpair.in"
+ addFunc(ve, run::pairXPart, primReal(), SYM(xpart), formal(primPair(), SYM(z), false, false));
+#line 69 "runpair.in"
+ addFunc(ve, run::pairYPart, primReal(), SYM(ypart), formal(primPair(), SYM(z), false, false));
+#line 74 "runpair.in"
+ addFunc(ve, run::gen_runpair5, primReal(), SYM(length), formal(primPair(), SYM(z), false, false));
+#line 79 "runpair.in"
+ addFunc(ve, run::gen_runpair6, primReal(), SYM(abs), formal(primPair(), SYM(z), false, false));
+#line 84 "runpair.in"
+ addFunc(ve, run::gen_runpair7, primPair(), SYM(sqrt), formal(primPair(), SYM(z), false, true));
+#line 89 "runpair.in"
+ addFunc(ve, run::gen_runpair8, primReal(), SYM(angle), formal(primPair(), SYM(z), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 96 "runpair.in"
+ addFunc(ve, run::gen_runpair9, primReal(), SYM(degrees), formal(primPair(), SYM(z), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 103 "runpair.in"
+ addFunc(ve, run::gen_runpair10, primReal(), SYM(radians), formal(primReal(), SYM(degrees), false, false));
+#line 109 "runpair.in"
+ addFunc(ve, run::gen_runpair11, primReal(), SYM(degrees), formal(primReal(), SYM(radians), false, false));
+#line 115 "runpair.in"
+ addFunc(ve, run::gen_runpair12, primReal(), SYM(Degrees), formal(primReal(), SYM(radians), false, false));
+#line 121 "runpair.in"
+ addFunc(ve, run::gen_runpair13, primReal(), SYM(Sin), formal(primReal(), SYM(deg), false, false));
+#line 134 "runpair.in"
+ addFunc(ve, run::gen_runpair14, primReal(), SYM(Cos), formal(primReal(), SYM(deg), false, false));
+#line 147 "runpair.in"
+ addFunc(ve, run::gen_runpair15, primReal(), SYM(Tan), formal(primReal(), SYM(deg), false, false));
+#line 160 "runpair.in"
+ addFunc(ve, run::gen_runpair16, primReal(), SYM(aSin), formal(primReal(), SYM(x), false, false));
+#line 165 "runpair.in"
+ addFunc(ve, run::gen_runpair17, primReal(), SYM(aCos), formal(primReal(), SYM(x), false, false));
+#line 170 "runpair.in"
+ addFunc(ve, run::gen_runpair18, primReal(), SYM(aTan), formal(primReal(), SYM(x), false, false));
+#line 175 "runpair.in"
+ addFunc(ve, run::gen_runpair19, primPair(), SYM(unit), formal(primPair(), SYM(z), false, false));
+#line 180 "runpair.in"
+ addFunc(ve, run::gen_runpair20, primPair(), SYM(dir), formal(primReal(), SYM(degrees), false, false));
+#line 185 "runpair.in"
+ addFunc(ve, run::gen_runpair21, primPair(), SYM(dir), formal(primPair(), SYM(z), false, true));
+#line 190 "runpair.in"
+ addFunc(ve, run::gen_runpair22, primPair(), SYM(expi), formal(primReal(), SYM(angle), false, false));
+#line 195 "runpair.in"
+ addFunc(ve, run::gen_runpair23, primPair(), SYM(exp), formal(primPair(), SYM(z), false, true));
+#line 200 "runpair.in"
+ addFunc(ve, run::gen_runpair24, primPair(), SYM(log), formal(primPair(), SYM(z), false, true));
+#line 205 "runpair.in"
+ addFunc(ve, run::gen_runpair25, primPair(), SYM(sin), formal(primPair(), SYM(z), false, true));
+#line 210 "runpair.in"
+ addFunc(ve, run::gen_runpair26, primPair(), SYM(cos), formal(primPair(), SYM(z), false, true));
+#line 215 "runpair.in"
+ addFunc(ve, run::gen_runpair27, primPair(), SYM(gamma), formal(primPair(), SYM(z), false, true));
+#line 221 "runpair.in"
+ addFunc(ve, run::gen_runpair28, primPair(), SYM(conj), formal(primPair(), SYM(z), false, false));
+#line 226 "runpair.in"
+ addFunc(ve, run::gen_runpair29, primPair(), SYM(realmult), formal(primPair(), SYM(z), false, false), formal(primPair(), SYM(w), false, false));
+#line 231 "runpair.in"
+ addFunc(ve, run::gen_runpair30, primReal(), SYM(dot), formal(primPair(), SYM(z), false, true), formal(primPair(), SYM(w), false, true));
+#line 237 "runpair.in"
+ addFunc(ve, run::gen_runpair31, primReal(), SYM(cross), formal(primPair(), SYM(z), false, true), formal(primPair(), SYM(w), false, true));
+#line 243 "runpair.in"
+ addFunc(ve, run::gen_runpair32, primPair(), SYM(bezier), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
+#line 250 "runpair.in"
+ addFunc(ve, run::gen_runpair33, primPair(), SYM(bezierP), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
+#line 255 "runpair.in"
+ addFunc(ve, run::gen_runpair34, primPair(), SYM(bezierPP), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
+#line 260 "runpair.in"
+ addFunc(ve, run::gen_runpair35, primPair(), SYM(bezierPPP), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runpair.h b/graphics/asymptote/runpair.h
new file mode 100644
index 0000000000..b53a7c02e9
--- /dev/null
+++ b/graphics/asymptote/runpair.h
@@ -0,0 +1,13 @@
+/***** Autogenerated from runpair.in; changes will be overwritten *****/
+
+#ifndef runpair_H
+#define runpair_H
+namespace run {
+void pairZero(vm::stack *);
+void realRealToPair(vm::stack *);
+void pairNegate(vm::stack *);
+void pairXPart(vm::stack *);
+void pairYPart(vm::stack *);
+}
+
+#endif // runpair_H
diff --git a/graphics/asymptote/runpair.in b/graphics/asymptote/runpair.in
new file mode 100644
index 0000000000..6170cd82fe
--- /dev/null
+++ b/graphics/asymptote/runpair.in
@@ -0,0 +1,263 @@
+/*****
+ * runpair.in
+ *
+ * Runtime functions for pair operations.
+ *
+ *****/
+
+pair => primPair()
+
+#include "pair.h"
+
+using namespace camp;
+
+namespace run {
+extern pair zero;
+}
+
+pair sin(pair z)
+{
+ return pair(sin(z.getx())*cosh(z.gety()),cos(z.getx())*sinh(z.gety()));
+}
+
+pair exp(pair z)
+{
+ return exp(z.getx())*expi(z.gety());
+}
+
+pair gamma(pair z)
+{
+ static double p[]={0.99999999999980993,676.5203681218851,-1259.1392167224028,
+ 771.32342877765313,-176.61502916214059,12.507343278686905,
+ -0.13857109526572012,9.9843695780195716e-6,
+ 1.5056327351493116e-7};
+ static int n=sizeof(p)/sizeof(double);
+ static double root2pi=sqrt(2*PI);
+ if(z.getx() < 0.5)
+ return PI/(sin(PI*z)*gamma(1.0-z));
+ z -= 1.0;
+ pair x=p[0];
+ for(int i=1; i < n; ++i)
+ x += p[i]/(z+i);
+ pair t=n-1.5+z;
+ return root2pi*pow(t,z+0.5)*exp(-t)*x;
+}
+
+// Autogenerated routines:
+
+
+pair :pairZero()
+{
+ return zero;
+}
+
+pair :realRealToPair(real x, real y)
+{
+ return pair(x,y);
+}
+
+pair :pairNegate(pair z)
+{
+ return -z;
+}
+
+real xpart:pairXPart(pair z)
+{
+ return z.getx();
+}
+
+real ypart:pairYPart(pair z)
+{
+ return z.gety();
+}
+
+real length(pair z)
+{
+ return z.length();
+}
+
+real abs(pair z)
+{
+ return z.length();
+}
+
+pair sqrt(explicit pair z)
+{
+ return Sqrt(z);
+}
+
+// Return the angle of z in radians.
+real angle(pair z, bool warn=true)
+{
+ if(!warn && z.getx() == 0.0 && z.gety() == 0.0) return 0.0;
+ return z.angle();
+}
+
+// Return the angle of z in degrees in the interval [0,360).
+real degrees(pair z, bool warn=true)
+{
+ if(!warn && z.getx() == 0.0 && z.gety() == 0.0) return 0.0;
+ return principalBranch(degrees(z.angle()));
+}
+
+// Convert degrees to radians.
+real radians(real degrees)
+{
+ return radians(degrees);
+}
+
+// Convert radians to degrees.
+real degrees(real radians)
+{
+ return degrees(radians);
+}
+
+// Convert radians to degrees in [0,360).
+real Degrees(real radians)
+{
+ return principalBranch(degrees(radians));
+}
+
+real Sin(real deg)
+{
+ int n=(int) (deg/90.0);
+ if(deg == n*90.0) {
+ int m=n % 4;
+ if(m < 0) m += 4;
+ if(m == 1) return 1;
+ if(m == 3) return -1;
+ return 0.0;
+ }
+ return sin(radians(deg));
+}
+
+real Cos(real deg)
+{
+ int n=(int) (deg/90.0);
+ if(deg == n*90.0) {
+ int m=n % 4;
+ if(m < 0) m += 4;
+ if(m == 0) return 1;
+ if(m == 2) return -1;
+ return 0.0;
+ }
+ return cos(radians(deg));
+}
+
+real Tan(real deg)
+{
+ int n=(int) (deg/90.0);
+ if(deg == n*90.0) {
+ int m=n % 4;
+ if(m < 0) m += 4;
+ if(m == 1) return HUGE_VAL;
+ if(m == 3) return -HUGE_VAL;
+ return 0.0;
+ }
+ return tan(radians(deg));
+}
+
+real aSin(real x)
+{
+ return degrees(asin(x));
+}
+
+real aCos(real x)
+{
+ return degrees(acos(x));
+}
+
+real aTan(real x)
+{
+ return degrees(atan(x));
+}
+
+pair unit(pair z)
+{
+ return unit(z);
+}
+
+pair dir(real degrees)
+{
+ return expi(radians(degrees));
+}
+
+pair dir(explicit pair z)
+{
+ return unit(z);
+}
+
+pair expi(real angle)
+{
+ return expi(angle);
+}
+
+pair exp(explicit pair z)
+{
+ return exp(z);
+}
+
+pair log(explicit pair z)
+{
+ return pair(log(z.length()),z.angle());
+}
+
+pair sin(explicit pair z)
+{
+ return sin(z);
+}
+
+pair cos(explicit pair z)
+{
+ return pair(cos(z.getx())*cosh(z.gety()),-sin(z.getx())*sinh(z.gety()));
+}
+
+// Complex Gamma function
+pair gamma(explicit pair z)
+{
+ return gamma(z);
+}
+
+pair conj(pair z)
+{
+ return conj(z);
+}
+
+pair realmult(pair z, pair w)
+{
+ return pair(z.getx()*w.getx(),z.gety()*w.gety());
+}
+
+// To avoid confusion, a dot product requires explicit pair arguments.
+real dot(explicit pair z, explicit pair w)
+{
+ return dot(z,w);
+}
+
+// Return the 2D scalar cross product z.x*w.y-z.y*w.x.
+real cross(explicit pair z, explicit pair w)
+{
+ return cross(z,w);
+}
+
+pair bezier(pair a, pair b, pair c, pair d, real t)
+{
+ real onemt=1-t;
+ real onemt2=onemt*onemt;
+ return onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d);
+}
+
+pair bezierP(pair a, pair b, pair c, pair d, real t)
+{
+ return 3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a);
+}
+
+pair bezierPP(pair a, pair b, pair c, pair d, real t)
+{
+ return 6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b);
+}
+
+pair bezierPPP(pair a, pair b, pair c, pair d)
+{
+ return 6.0*(d-a+3.0*(b-c));
+}
diff --git a/graphics/asymptote/runpath.cc b/graphics/asymptote/runpath.cc
new file mode 100644
index 0000000000..e03bf21839
--- /dev/null
+++ b/graphics/asymptote/runpath.cc
@@ -0,0 +1,846 @@
+/***** Autogenerated from runpath.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runpath.in"
+/*****
+ * runpicture.in
+ *
+ * Runtime functions for picture operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 17 "runpath.in"
+#include "path.h"
+#include "arrayop.h"
+#include "predicates.h"
+
+using namespace camp;
+using namespace vm;
+
+typedef array realarray;
+typedef array realarray2;
+typedef array patharray;
+
+using types::realArray;
+using types::realArray2;
+using types::pathArray;
+
+Int windingnumber(array *p, camp::pair z)
+{
+ size_t size=checkArray(p);
+ Int count=0;
+ for(size_t i=0; i < size; i++)
+ count += read<path *>(p,i)->windingnumber(z);
+ return count;
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runpath.symbols.h"
+
+#endif
+namespace run {
+#line 44 "runpath.in"
+void nullPath(stack *Stack)
+{
+#line 45 "runpath.in"
+ {Stack->push<path>(nullpath); return;}
+}
+
+#line 49 "runpath.in"
+// bool ==(path a, path b);
+void gen_runpath1(stack *Stack)
+{
+ path b=vm::pop<path>(Stack);
+ path a=vm::pop<path>(Stack);
+#line 50 "runpath.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 54 "runpath.in"
+// bool !=(path a, path b);
+void gen_runpath2(stack *Stack)
+{
+ path b=vm::pop<path>(Stack);
+ path a=vm::pop<path>(Stack);
+#line 55 "runpath.in"
+ {Stack->push<bool>(!(a == b)); return;}
+}
+
+#line 59 "runpath.in"
+// pair point(path p, Int t);
+void gen_runpath3(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 60 "runpath.in"
+ {Stack->push<pair>(p.point((Int) t)); return;}
+}
+
+#line 64 "runpath.in"
+// pair point(path p, real t);
+void gen_runpath4(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 65 "runpath.in"
+ {Stack->push<pair>(p.point(t)); return;}
+}
+
+#line 69 "runpath.in"
+// pair precontrol(path p, Int t);
+void gen_runpath5(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 70 "runpath.in"
+ {Stack->push<pair>(p.precontrol((Int) t)); return;}
+}
+
+#line 74 "runpath.in"
+// pair precontrol(path p, real t);
+void gen_runpath6(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 75 "runpath.in"
+ {Stack->push<pair>(p.precontrol(t)); return;}
+}
+
+#line 79 "runpath.in"
+// pair postcontrol(path p, Int t);
+void gen_runpath7(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 80 "runpath.in"
+ {Stack->push<pair>(p.postcontrol((Int) t)); return;}
+}
+
+#line 84 "runpath.in"
+// pair postcontrol(path p, real t);
+void gen_runpath8(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 85 "runpath.in"
+ {Stack->push<pair>(p.postcontrol(t)); return;}
+}
+
+#line 89 "runpath.in"
+// pair dir(path p, Int t, Int sign=0, bool normalize=true);
+void gen_runpath9(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 90 "runpath.in"
+ {Stack->push<pair>(p.dir(t,sign,normalize)); return;}
+}
+
+#line 94 "runpath.in"
+// pair dir(path p, real t, bool normalize=true);
+void gen_runpath10(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 95 "runpath.in"
+ {Stack->push<pair>(p.dir(t,normalize)); return;}
+}
+
+#line 99 "runpath.in"
+// pair accel(path p, Int t, Int sign=0);
+void gen_runpath11(stack *Stack)
+{
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 100 "runpath.in"
+ {Stack->push<pair>(p.accel(t,sign)); return;}
+}
+
+#line 104 "runpath.in"
+// pair accel(path p, real t);
+void gen_runpath12(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 105 "runpath.in"
+ {Stack->push<pair>(p.accel(t)); return;}
+}
+
+#line 109 "runpath.in"
+// real radius(path p, real t);
+void gen_runpath13(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 110 "runpath.in"
+ pair v=p.dir(t,false);
+ pair a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ {Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
+}
+
+#line 121 "runpath.in"
+// path reverse(path p);
+void gen_runpath14(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 122 "runpath.in"
+ {Stack->push<path>(p.reverse()); return;}
+}
+
+#line 126 "runpath.in"
+// path subpath(path p, Int a, Int b);
+void gen_runpath15(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 127 "runpath.in"
+ {Stack->push<path>(p.subpath((Int) a, (Int) b)); return;}
+}
+
+#line 131 "runpath.in"
+// path subpath(path p, real a, real b);
+void gen_runpath16(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 132 "runpath.in"
+ {Stack->push<path>(p.subpath(a,b)); return;}
+}
+
+#line 136 "runpath.in"
+// path nurb(pair z0, pair z1, pair z2, pair z3, real w0, real w1, real w2, real w3, Int m);
+void gen_runpath17(stack *Stack)
+{
+ Int m=vm::pop<Int>(Stack);
+ real w3=vm::pop<real>(Stack);
+ real w2=vm::pop<real>(Stack);
+ real w1=vm::pop<real>(Stack);
+ real w0=vm::pop<real>(Stack);
+ pair z3=vm::pop<pair>(Stack);
+ pair z2=vm::pop<pair>(Stack);
+ pair z1=vm::pop<pair>(Stack);
+ pair z0=vm::pop<pair>(Stack);
+#line 138 "runpath.in"
+ {Stack->push<path>(nurb(z0,z1,z2,z3,w0,w1,w2,w3,m)); return;}
+}
+
+#line 142 "runpath.in"
+// Int length(path p);
+void gen_runpath18(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 143 "runpath.in"
+ {Stack->push<Int>(p.length()); return;}
+}
+
+#line 147 "runpath.in"
+// bool cyclic(path p);
+void gen_runpath19(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 148 "runpath.in"
+ {Stack->push<bool>(p.cyclic()); return;}
+}
+
+#line 152 "runpath.in"
+// bool straight(path p, Int t);
+void gen_runpath20(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 153 "runpath.in"
+ {Stack->push<bool>(p.straight(t)); return;}
+}
+
+#line 157 "runpath.in"
+// path unstraighten(path p);
+void gen_runpath21(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 158 "runpath.in"
+ {Stack->push<path>(p.unstraighten()); return;}
+}
+
+#line 162 "runpath.in"
+// bool piecewisestraight(path p);
+void gen_runpath22(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 163 "runpath.in"
+ {Stack->push<bool>(p.piecewisestraight()); return;}
+}
+
+#line 167 "runpath.in"
+// real arclength(path p);
+void gen_runpath23(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 168 "runpath.in"
+ {Stack->push<real>(p.arclength()); return;}
+}
+
+#line 172 "runpath.in"
+// real arctime(path p, real L);
+void gen_runpath24(stack *Stack)
+{
+ real L=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 173 "runpath.in"
+ {Stack->push<real>(p.arctime(L)); return;}
+}
+
+#line 177 "runpath.in"
+// real dirtime(path p, pair z);
+void gen_runpath25(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 178 "runpath.in"
+ {Stack->push<real>(p.directiontime(z)); return;}
+}
+
+#line 182 "runpath.in"
+// realarray* intersect(path p, path q, real fuzz=-1);
+void gen_runpath26(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path q=vm::pop<path>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 183 "runpath.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ {Stack->push<realarray*>(V); return;}
+ }
+ {Stack->push<realarray*>(new array(0)); return;}
+}
+
+#line 199 "runpath.in"
+// realarray2* intersections(path p, path q, real fuzz=-1);
+void gen_runpath27(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path q=vm::pop<path>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 200 "runpath.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0.0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ real s,t;
+ std::vector<real> S,T;
+ intersections(s,t,S,T,p,q,fuzz,false,true);
+ size_t n=S.size();
+ if(n == 0 && !exact) {
+ if(intersections(s,t,S,T,p,q,fuzz,true,false)) {
+ array *V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ {Stack->push<realarray2*>(V); return;}
+ }
+ }
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ {Stack->push<realarray2*>(V); return;}
+}
+
+#line 230 "runpath.in"
+// realarray* intersections(path p, explicit pair a, explicit pair b, real fuzz=-1);
+void gen_runpath28(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 231 "runpath.in"
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(a),length(b)));
+ std::vector<real> S;
+ intersections(S,p,a,b,fuzz);
+ sort(S.begin(),S.end());
+ size_t n=S.size();
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i)
+ (*V)[i]=S[i];
+ {Stack->push<realarray*>(V); return;}
+}
+
+// Return the intersection point of the extensions of the line segments
+// PQ and pq.
+#line 247 "runpath.in"
+// pair extension(pair P, pair Q, pair p, pair q);
+void gen_runpath29(stack *Stack)
+{
+ pair q=vm::pop<pair>(Stack);
+ pair p=vm::pop<pair>(Stack);
+ pair Q=vm::pop<pair>(Stack);
+ pair P=vm::pop<pair>(Stack);
+#line 248 "runpath.in"
+ pair ac=P-Q;
+ pair bd=q-p;
+ real det=ac.getx()*bd.gety()-ac.gety()*bd.getx();
+ if(det == 0) {Stack->push<pair>(pair(infinity,infinity)); return;}
+ {Stack->push<pair>(P+((p.getx()-P.getx())*bd.gety()-(p.gety()-P.gety())*bd.getx())*ac/det); return;}
+}
+
+#line 256 "runpath.in"
+// Int size(path p);
+void gen_runpath30(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 257 "runpath.in"
+ {Stack->push<Int>(p.size()); return;}
+}
+
+#line 261 "runpath.in"
+// path &(path p, path q);
+void gen_runpath31(stack *Stack)
+{
+ path q=vm::pop<path>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 262 "runpath.in"
+ {Stack->push<path>(camp::concat(p,q)); return;}
+}
+
+#line 266 "runpath.in"
+// pair min(explicit path p);
+void gen_runpath32(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 267 "runpath.in"
+ {Stack->push<pair>(p.min()); return;}
+}
+
+#line 271 "runpath.in"
+// pair max(explicit path p);
+void gen_runpath33(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 272 "runpath.in"
+ {Stack->push<pair>(p.max()); return;}
+}
+
+#line 276 "runpath.in"
+// Int size(patharray *p);
+void gen_runpath34(stack *Stack)
+{
+ patharray * p=vm::pop<patharray *>(Stack);
+#line 277 "runpath.in"
+ size_t size=checkArray(p);
+ Int count=0;
+ for (size_t i = 0; i < size; i++)
+ count += read<path *>(p,i)->size();
+ {Stack->push<Int>(count); return;}
+}
+
+#line 285 "runpath.in"
+// pair min(patharray *p);
+void gen_runpath35(stack *Stack)
+{
+ patharray * p=vm::pop<patharray *>(Stack);
+#line 286 "runpath.in"
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path *g = p->read<path *>(0);
+ pair z = g->min();
+ double minx = z.getx(), miny = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path *g = p->read<path *>(i);
+ pair z = g->min();
+ double x = z.getx(), y = z.gety();
+ if (x < minx)
+ minx = x;
+ if (y < miny)
+ miny = y;
+ }
+
+ {Stack->push<pair>(pair(minx, miny)); return;}
+}
+
+#line 309 "runpath.in"
+// pair max(patharray *p);
+void gen_runpath36(stack *Stack)
+{
+ patharray * p=vm::pop<patharray *>(Stack);
+#line 310 "runpath.in"
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path *g = p->read<path *>(0);
+ pair z = g->max();
+ double maxx = z.getx(), maxy = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path *g = p->read<path *>(i);
+ pair z = g->max();
+ double x = z.getx(), y = z.gety();
+ if (x > maxx)
+ maxx = x;
+ if (y > maxy)
+ maxy = y;
+ }
+
+ {Stack->push<pair>(pair(maxx, maxy)); return;}
+}
+
+#line 333 "runpath.in"
+// pair minAfterTransform(transform t, patharray *p);
+void gen_runpath37(stack *Stack)
+{
+ patharray * p=vm::pop<patharray *>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 334 "runpath.in"
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path g = p->read<path *>(0)->transformed(t);
+ pair z = g.min();
+ double minx = z.getx(), miny = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path g = p->read<path *>(i)->transformed(t);
+ pair z = g.min();
+ double x = z.getx(), y = z.gety();
+ if (x < minx)
+ minx = x;
+ if (y < miny)
+ miny = y;
+ }
+
+ {Stack->push<pair>(pair(minx, miny)); return;}
+}
+
+#line 357 "runpath.in"
+// pair maxAfterTransform(transform t, patharray *p);
+void gen_runpath38(stack *Stack)
+{
+ patharray * p=vm::pop<patharray *>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 358 "runpath.in"
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path g = p->read<path *>(0)->transformed(t);
+ pair z = g.max();
+ double maxx = z.getx(), maxy = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path g = p->read<path *>(i)->transformed(t);
+ pair z = g.max();
+ double x = z.getx(), y = z.gety();
+ if (x > maxx)
+ maxx = x;
+ if (y > maxy)
+ maxy = y;
+ }
+
+ {Stack->push<pair>(pair(maxx, maxy)); return;}
+}
+
+#line 381 "runpath.in"
+// realarray* mintimes(path p);
+void gen_runpath39(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 382 "runpath.in"
+ array *V=new array(2);
+ pair z=p.mintimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 390 "runpath.in"
+// realarray* maxtimes(path p);
+void gen_runpath40(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 391 "runpath.in"
+ array *V=new array(2);
+ pair z=p.maxtimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 399 "runpath.in"
+// real relativedistance(real theta, real phi, real t, bool atleast);
+void gen_runpath41(stack *Stack)
+{
+ bool atleast=vm::pop<bool>(Stack);
+ real t=vm::pop<real>(Stack);
+ real phi=vm::pop<real>(Stack);
+ real theta=vm::pop<real>(Stack);
+#line 400 "runpath.in"
+ {Stack->push<real>(camp::velocity(theta,phi,tension(t,atleast))); return;}
+}
+
+#line 404 "runpath.in"
+// Int windingnumber(patharray *p, pair z);
+void gen_runpath42(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+ patharray * p=vm::pop<patharray *>(Stack);
+#line 405 "runpath.in"
+ {Stack->push<Int>(windingnumber(p,z)); return;}
+}
+
+#line 409 "runpath.in"
+// bool inside(explicit patharray *g, pair z, pen fillrule=CURRENTPEN);
+void gen_runpath43(stack *Stack)
+{
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ pair z=vm::pop<pair>(Stack);
+ patharray * g=vm::pop<patharray *>(Stack);
+#line 410 "runpath.in"
+ {Stack->push<bool>(fillrule.inside(windingnumber(g,z))); return;}
+}
+
+#line 414 "runpath.in"
+// bool inside(path g, pair z, pen fillrule=CURRENTPEN);
+void gen_runpath44(stack *Stack)
+{
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ pair z=vm::pop<pair>(Stack);
+ path g=vm::pop<path>(Stack);
+#line 415 "runpath.in"
+ {Stack->push<bool>(fillrule.inside(g.windingnumber(z))); return;}
+}
+
+// Return a positive (negative) value if a--b--c--cycle is oriented
+// counterclockwise (clockwise) or zero if all three points are colinear.
+// Equivalently, return a positive (negative) value if c lies to the
+// left (right) of the line through a and b or zero if c lies on this line.
+// The value returned is the determinant
+// |a.x a.y 1|
+// |b.x b.y 1|
+// |c.x c.y 1|
+//
+#line 428 "runpath.in"
+// real orient(pair a, pair b, pair c);
+void gen_runpath45(stack *Stack)
+{
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 429 "runpath.in"
+ {Stack->push<real>(orient2d(a,b,c)); return;}
+}
+
+// Return a positive (negative) value if d lies inside (outside)
+// the circle passing through the counterclockwise-oriented points a,b,c
+// or zero if d lies on this circle.
+// The value returned is the determinant
+// |a.x a.y a.x^2+a.y^2 1|
+// |b.x b.y b.x^2+b.y^2 1|
+// |c.x c.y c.x^2+c.y^2 1|
+// |d.x d.y d.x^2+d.y^2 1|
+#line 441 "runpath.in"
+// real incircle(pair a, pair b, pair c, pair d);
+void gen_runpath46(stack *Stack)
+{
+ pair d=vm::pop<pair>(Stack);
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 442 "runpath.in"
+ {Stack->push<real>(incircle(a.getx(),a.gety(),b.getx(),b.gety(),c.getx(),c.gety(),
+ d.getx(),d.gety())); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runpath_venv(venv &ve)
+{
+#line 44 "runpath.in"
+ REGISTER_BLTIN(run::nullPath,"nullPath");
+#line 49 "runpath.in"
+ addFunc(ve, run::gen_runpath1, primBoolean(), SYM_EQ, formal(primPath(), SYM(a), false, false), formal(primPath(), SYM(b), false, false));
+#line 54 "runpath.in"
+ addFunc(ve, run::gen_runpath2, primBoolean(), SYM_NEQ, formal(primPath(), SYM(a), false, false), formal(primPath(), SYM(b), false, false));
+#line 59 "runpath.in"
+ addFunc(ve, run::gen_runpath3, primPair(), SYM(point), formal(primPath(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 64 "runpath.in"
+ addFunc(ve, run::gen_runpath4, primPair(), SYM(point), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 69 "runpath.in"
+ addFunc(ve, run::gen_runpath5, primPair(), SYM(precontrol), formal(primPath(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 74 "runpath.in"
+ addFunc(ve, run::gen_runpath6, primPair(), SYM(precontrol), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 79 "runpath.in"
+ addFunc(ve, run::gen_runpath7, primPair(), SYM(postcontrol), formal(primPath(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 84 "runpath.in"
+ addFunc(ve, run::gen_runpath8, primPair(), SYM(postcontrol), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 89 "runpath.in"
+ addFunc(ve, run::gen_runpath9, primPair(), SYM(dir), formal(primPath(), SYM(p), false, false), formal(primInt(), SYM(t), false, false), formal(primInt(), SYM(sign), true, false), formal(primBoolean(), SYM(normalize), true, false));
+#line 94 "runpath.in"
+ addFunc(ve, run::gen_runpath10, primPair(), SYM(dir), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(t), false, false), formal(primBoolean(), SYM(normalize), true, false));
+#line 99 "runpath.in"
+ addFunc(ve, run::gen_runpath11, primPair(), SYM(accel), formal(primPath(), SYM(p), false, false), formal(primInt(), SYM(t), false, false), formal(primInt(), SYM(sign), true, false));
+#line 104 "runpath.in"
+ addFunc(ve, run::gen_runpath12, primPair(), SYM(accel), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 109 "runpath.in"
+ addFunc(ve, run::gen_runpath13, primReal(), SYM(radius), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 121 "runpath.in"
+ addFunc(ve, run::gen_runpath14, primPath(), SYM(reverse), formal(primPath(), SYM(p), false, false));
+#line 126 "runpath.in"
+ addFunc(ve, run::gen_runpath15, primPath(), SYM(subpath), formal(primPath(), SYM(p), false, false), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
+#line 131 "runpath.in"
+ addFunc(ve, run::gen_runpath16, primPath(), SYM(subpath), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false));
+#line 136 "runpath.in"
+ addFunc(ve, run::gen_runpath17, primPath(), SYM(nurb), formal(primPair(), SYM(z0), false, false), formal(primPair(), SYM(z1), false, false), formal(primPair(), SYM(z2), false, false), formal(primPair(), SYM(z3), false, false), formal(primReal(), SYM(w0), false, false), formal(primReal(), SYM(w1), false, false), formal(primReal(), SYM(w2), false, false), formal(primReal(), SYM(w3), false, false), formal(primInt(), SYM(m), false, false));
+#line 142 "runpath.in"
+ addFunc(ve, run::gen_runpath18, primInt(), SYM(length), formal(primPath(), SYM(p), false, false));
+#line 147 "runpath.in"
+ addFunc(ve, run::gen_runpath19, primBoolean(), SYM(cyclic), formal(primPath(), SYM(p), false, false));
+#line 152 "runpath.in"
+ addFunc(ve, run::gen_runpath20, primBoolean(), SYM(straight), formal(primPath(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 157 "runpath.in"
+ addFunc(ve, run::gen_runpath21, primPath(), SYM(unstraighten), formal(primPath(), SYM(p), false, false));
+#line 162 "runpath.in"
+ addFunc(ve, run::gen_runpath22, primBoolean(), SYM(piecewisestraight), formal(primPath(), SYM(p), false, false));
+#line 167 "runpath.in"
+ addFunc(ve, run::gen_runpath23, primReal(), SYM(arclength), formal(primPath(), SYM(p), false, false));
+#line 172 "runpath.in"
+ addFunc(ve, run::gen_runpath24, primReal(), SYM(arctime), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(l), false, false));
+#line 177 "runpath.in"
+ addFunc(ve, run::gen_runpath25, primReal(), SYM(dirtime), formal(primPath(), SYM(p), false, false), formal(primPair(), SYM(z), false, false));
+#line 182 "runpath.in"
+ addFunc(ve, run::gen_runpath26, realArray(), SYM(intersect), formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 199 "runpath.in"
+ addFunc(ve, run::gen_runpath27, realArray2(), SYM(intersections), formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 230 "runpath.in"
+ addFunc(ve, run::gen_runpath28, realArray(), SYM(intersections), formal(primPath(), SYM(p), false, false), formal(primPair(), SYM(a), false, true), formal(primPair(), SYM(b), false, true), formal(primReal(), SYM(fuzz), true, false));
+#line 245 "runpath.in"
+ addFunc(ve, run::gen_runpath29, primPair(), SYM(extension), formal(primPair(), SYM(p), false, false), formal(primPair(), SYM(q), false, false), formal(primPair(), SYM(p), false, false), formal(primPair(), SYM(q), false, false));
+#line 256 "runpath.in"
+ addFunc(ve, run::gen_runpath30, primInt(), SYM(size), formal(primPath(), SYM(p), false, false));
+#line 261 "runpath.in"
+ addFunc(ve, run::gen_runpath31, primPath(), SYM_AMPERSAND, formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false));
+#line 266 "runpath.in"
+ addFunc(ve, run::gen_runpath32, primPair(), SYM(min), formal(primPath(), SYM(p), false, true));
+#line 271 "runpath.in"
+ addFunc(ve, run::gen_runpath33, primPair(), SYM(max), formal(primPath(), SYM(p), false, true));
+#line 276 "runpath.in"
+ addFunc(ve, run::gen_runpath34, primInt(), SYM(size), formal(pathArray() , SYM(p), false, false));
+#line 285 "runpath.in"
+ addFunc(ve, run::gen_runpath35, primPair(), SYM(min), formal(pathArray() , SYM(p), false, false));
+#line 309 "runpath.in"
+ addFunc(ve, run::gen_runpath36, primPair(), SYM(max), formal(pathArray() , SYM(p), false, false));
+#line 333 "runpath.in"
+ addFunc(ve, run::gen_runpath37, primPair(), SYM(minAfterTransform), formal(primTransform(), SYM(t), false, false), formal(pathArray() , SYM(p), false, false));
+#line 357 "runpath.in"
+ addFunc(ve, run::gen_runpath38, primPair(), SYM(maxAfterTransform), formal(primTransform(), SYM(t), false, false), formal(pathArray() , SYM(p), false, false));
+#line 381 "runpath.in"
+ addFunc(ve, run::gen_runpath39, realArray(), SYM(mintimes), formal(primPath(), SYM(p), false, false));
+#line 390 "runpath.in"
+ addFunc(ve, run::gen_runpath40, realArray(), SYM(maxtimes), formal(primPath(), SYM(p), false, false));
+#line 399 "runpath.in"
+ addFunc(ve, run::gen_runpath41, primReal(), SYM(relativedistance), formal(primReal(), SYM(theta), false, false), formal(primReal(), SYM(phi), false, false), formal(primReal(), SYM(t), false, false), formal(primBoolean(), SYM(atleast), false, false));
+#line 404 "runpath.in"
+ addFunc(ve, run::gen_runpath42, primInt(), SYM(windingnumber), formal(pathArray() , SYM(p), false, false), formal(primPair(), SYM(z), false, false));
+#line 409 "runpath.in"
+ addFunc(ve, run::gen_runpath43, primBoolean(), SYM(inside), formal(pathArray() , SYM(g), false, true), formal(primPair(), SYM(z), false, false), formal(primPen(), SYM(fillrule), true, false));
+#line 414 "runpath.in"
+ addFunc(ve, run::gen_runpath44, primBoolean(), SYM(inside), formal(primPath(), SYM(g), false, false), formal(primPair(), SYM(z), false, false), formal(primPen(), SYM(fillrule), true, false));
+#line 419 "runpath.in"
+ addFunc(ve, run::gen_runpath45, primReal(), SYM(orient), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false));
+#line 433 "runpath.in"
+ addFunc(ve, run::gen_runpath46, primReal(), SYM(incircle), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runpath.h b/graphics/asymptote/runpath.h
new file mode 100644
index 0000000000..18ee20cb57
--- /dev/null
+++ b/graphics/asymptote/runpath.h
@@ -0,0 +1,9 @@
+/***** Autogenerated from runpath.in; changes will be overwritten *****/
+
+#ifndef runpath_H
+#define runpath_H
+namespace run {
+void nullPath(vm::stack *);
+}
+
+#endif // runpath_H
diff --git a/graphics/asymptote/runpath.in b/graphics/asymptote/runpath.in
new file mode 100644
index 0000000000..41978efe87
--- /dev/null
+++ b/graphics/asymptote/runpath.in
@@ -0,0 +1,445 @@
+/*****
+ * runpicture.in
+ *
+ * Runtime functions for picture operations.
+ *
+ *****/
+
+pen => primPen()
+pair => primPair()
+path => primPath()
+transform => primTransform()
+realarray* => realArray()
+realarray2* => realArray2()
+patharray* => pathArray()
+penarray* => penArray()
+
+#include "path.h"
+#include "arrayop.h"
+#include "predicates.h"
+
+using namespace camp;
+using namespace vm;
+
+typedef array realarray;
+typedef array realarray2;
+typedef array patharray;
+
+using types::realArray;
+using types::realArray2;
+using types::pathArray;
+
+Int windingnumber(array *p, camp::pair z)
+{
+ size_t size=checkArray(p);
+ Int count=0;
+ for(size_t i=0; i < size; i++)
+ count += read<path *>(p,i)->windingnumber(z);
+ return count;
+}
+
+// Autogenerated routines:
+
+
+path :nullPath()
+{
+ return nullpath;
+}
+
+bool ==(path a, path b)
+{
+ return a == b;
+}
+
+bool !=(path a, path b)
+{
+ return !(a == b);
+}
+
+pair point(path p, Int t)
+{
+ return p.point((Int) t);
+}
+
+pair point(path p, real t)
+{
+ return p.point(t);
+}
+
+pair precontrol(path p, Int t)
+{
+ return p.precontrol((Int) t);
+}
+
+pair precontrol(path p, real t)
+{
+ return p.precontrol(t);
+}
+
+pair postcontrol(path p, Int t)
+{
+ return p.postcontrol((Int) t);
+}
+
+pair postcontrol(path p, real t)
+{
+ return p.postcontrol(t);
+}
+
+pair dir(path p, Int t, Int sign=0, bool normalize=true)
+{
+ return p.dir(t,sign,normalize);
+}
+
+pair dir(path p, real t, bool normalize=true)
+{
+ return p.dir(t,normalize);
+}
+
+pair accel(path p, Int t, Int sign=0)
+{
+ return p.accel(t,sign);
+}
+
+pair accel(path p, real t)
+{
+ return p.accel(t);
+}
+
+real radius(path p, real t)
+{
+ pair v=p.dir(t,false);
+ pair a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ return denom > 0 ? r/sqrt(denom) : 0.0;
+}
+
+path reverse(path p)
+{
+ return p.reverse();
+}
+
+path subpath(path p, Int a, Int b)
+{
+ return p.subpath((Int) a, (Int) b);
+}
+
+path subpath(path p, real a, real b)
+{
+ return p.subpath(a,b);
+}
+
+path nurb(pair z0, pair z1, pair z2, pair z3,
+ real w0, real w1, real w2, real w3, Int m)
+{
+ return nurb(z0,z1,z2,z3,w0,w1,w2,w3,m);
+}
+
+Int length(path p)
+{
+ return p.length();
+}
+
+bool cyclic(path p)
+{
+ return p.cyclic();
+}
+
+bool straight(path p, Int t)
+{
+ return p.straight(t);
+}
+
+path unstraighten(path p)
+{
+ return p.unstraighten();
+}
+
+bool piecewisestraight(path p)
+{
+ return p.piecewisestraight();
+}
+
+real arclength(path p)
+{
+ return p.arclength();
+}
+
+real arctime(path p, real L)
+{
+ return p.arctime(L);
+}
+
+real dirtime(path p, pair z)
+{
+ return p.directiontime(z);
+}
+
+realarray* intersect(path p, path q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ return V;
+ }
+ return new array(0);
+}
+
+realarray2* intersections(path p, path q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0.0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ real s,t;
+ std::vector<real> S,T;
+ intersections(s,t,S,T,p,q,fuzz,false,true);
+ size_t n=S.size();
+ if(n == 0 && !exact) {
+ if(intersections(s,t,S,T,p,q,fuzz,true,false)) {
+ array *V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ return V;
+ }
+ }
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ return V;
+}
+
+realarray* intersections(path p, explicit pair a, explicit pair b, real fuzz=-1)
+{
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(a),length(b)));
+ std::vector<real> S;
+ intersections(S,p,a,b,fuzz);
+ sort(S.begin(),S.end());
+ size_t n=S.size();
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i)
+ (*V)[i]=S[i];
+ return V;
+}
+
+// Return the intersection point of the extensions of the line segments
+// PQ and pq.
+pair extension(pair P, pair Q, pair p, pair q)
+{
+ pair ac=P-Q;
+ pair bd=q-p;
+ real det=ac.getx()*bd.gety()-ac.gety()*bd.getx();
+ if(det == 0) return pair(infinity,infinity);
+ return P+((p.getx()-P.getx())*bd.gety()-(p.gety()-P.gety())*bd.getx())*ac/det;
+}
+
+Int size(path p)
+{
+ return p.size();
+}
+
+path &(path p, path q)
+{
+ return camp::concat(p,q);
+}
+
+pair min(explicit path p)
+{
+ return p.min();
+}
+
+pair max(explicit path p)
+{
+ return p.max();
+}
+
+Int size(patharray *p)
+{
+ size_t size=checkArray(p);
+ Int count=0;
+ for (size_t i = 0; i < size; i++)
+ count += read<path *>(p,i)->size();
+ return count;
+}
+
+pair min(patharray *p)
+{
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path *g = p->read<path *>(0);
+ pair z = g->min();
+ double minx = z.getx(), miny = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path *g = p->read<path *>(i);
+ pair z = g->min();
+ double x = z.getx(), y = z.gety();
+ if (x < minx)
+ minx = x;
+ if (y < miny)
+ miny = y;
+ }
+
+ return pair(minx, miny);
+}
+
+pair max(patharray *p)
+{
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path *g = p->read<path *>(0);
+ pair z = g->max();
+ double maxx = z.getx(), maxy = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path *g = p->read<path *>(i);
+ pair z = g->max();
+ double x = z.getx(), y = z.gety();
+ if (x > maxx)
+ maxx = x;
+ if (y > maxy)
+ maxy = y;
+ }
+
+ return pair(maxx, maxy);
+}
+
+pair minAfterTransform(transform t, patharray *p)
+{
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path g = p->read<path *>(0)->transformed(t);
+ pair z = g.min();
+ double minx = z.getx(), miny = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path g = p->read<path *>(i)->transformed(t);
+ pair z = g.min();
+ double x = z.getx(), y = z.gety();
+ if (x < minx)
+ minx = x;
+ if (y < miny)
+ miny = y;
+ }
+
+ return pair(minx, miny);
+}
+
+pair maxAfterTransform(transform t, patharray *p)
+{
+ size_t size=checkArray(p);
+
+ if(size == 0)
+ error(nopoints);
+
+ path g = p->read<path *>(0)->transformed(t);
+ pair z = g.max();
+ double maxx = z.getx(), maxy = z.gety();
+
+ for (size_t i = 1; i < size; ++i) {
+ path g = p->read<path *>(i)->transformed(t);
+ pair z = g.max();
+ double x = z.getx(), y = z.gety();
+ if (x > maxx)
+ maxx = x;
+ if (y > maxy)
+ maxy = y;
+ }
+
+ return pair(maxx, maxy);
+}
+
+realarray *mintimes(path p)
+{
+ array *V=new array(2);
+ pair z=p.mintimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ return V;
+}
+
+realarray *maxtimes(path p)
+{
+ array *V=new array(2);
+ pair z=p.maxtimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ return V;
+}
+
+real relativedistance(real theta, real phi, real t, bool atleast)
+{
+ return camp::velocity(theta,phi,tension(t,atleast));
+}
+
+Int windingnumber(patharray *p, pair z)
+{
+ return windingnumber(p,z);
+}
+
+bool inside(explicit patharray *g, pair z, pen fillrule=CURRENTPEN)
+{
+ return fillrule.inside(windingnumber(g,z));
+}
+
+bool inside(path g, pair z, pen fillrule=CURRENTPEN)
+{
+ return fillrule.inside(g.windingnumber(z));
+}
+
+// Return a positive (negative) value if a--b--c--cycle is oriented
+// counterclockwise (clockwise) or zero if all three points are colinear.
+// Equivalently, return a positive (negative) value if c lies to the
+// left (right) of the line through a and b or zero if c lies on this line.
+// The value returned is the determinant
+// |a.x a.y 1|
+// |b.x b.y 1|
+// |c.x c.y 1|
+//
+real orient(pair a, pair b, pair c)
+{
+ return orient2d(a,b,c);
+}
+
+// Return a positive (negative) value if d lies inside (outside)
+// the circle passing through the counterclockwise-oriented points a,b,c
+// or zero if d lies on this circle.
+// The value returned is the determinant
+// |a.x a.y a.x^2+a.y^2 1|
+// |b.x b.y b.x^2+b.y^2 1|
+// |c.x c.y c.x^2+c.y^2 1|
+// |d.x d.y d.x^2+d.y^2 1|
+real incircle(pair a, pair b, pair c, pair d)
+{
+ return incircle(a.getx(),a.gety(),b.getx(),b.gety(),c.getx(),c.gety(),
+ d.getx(),d.gety());
+}
diff --git a/graphics/asymptote/runpath3d.cc b/graphics/asymptote/runpath3d.cc
new file mode 100644
index 0000000000..1e071931de
--- /dev/null
+++ b/graphics/asymptote/runpath3d.cc
@@ -0,0 +1,767 @@
+/***** Autogenerated from runpath3d.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runpath3d.in"
+/*****
+ * runpath3.in
+ *
+ * Runtime functions for path3 operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 17 "runpath3d.in"
+#include "path3.h"
+#include "array.h"
+#include "drawsurface.h"
+#include "predicates.h"
+
+using namespace camp;
+using namespace vm;
+
+typedef array boolarray;
+typedef array realarray;
+typedef array realarray2;
+typedef array triplearray;
+typedef array triplearray2;
+
+using types::booleanArray;
+using types::realArray;
+using types::realArray2;
+using types::tripleArray;
+using types::tripleArray2;
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runpath3d.symbols.h"
+
+#endif
+namespace run {
+#line 40 "runpath3d.in"
+// path3 path3(triplearray *pre, triplearray *point, triplearray *post, boolarray *straight, bool cyclic);
+void gen_runpath3d0(stack *Stack)
+{
+ bool cyclic=vm::pop<bool>(Stack);
+ boolarray * straight=vm::pop<boolarray *>(Stack);
+ triplearray * post=vm::pop<triplearray *>(Stack);
+ triplearray * point=vm::pop<triplearray *>(Stack);
+ triplearray * pre=vm::pop<triplearray *>(Stack);
+#line 42 "runpath3d.in"
+ size_t n=checkArrays(pre,point);
+ checkEqual(n,checkArray(post));
+ checkEqual(n,checkArray(straight));
+ mem::vector<solvedKnot3> nodes(n);
+ for(size_t i=0; i < n; ++i) {
+ nodes[i].pre=read<triple>(pre,i);
+ nodes[i].point=read<triple>(point,i);
+ nodes[i].post=read<triple>(post,i);
+ nodes[i].straight=read<bool>(straight,i);
+ }
+
+ {Stack->push<path3>(path3(nodes,(Int) n,cyclic)); return;}
+}
+
+#line 57 "runpath3d.in"
+void nullPath3(stack *Stack)
+{
+#line 58 "runpath3d.in"
+ {Stack->push<path3>(nullpath3); return;}
+}
+
+#line 62 "runpath3d.in"
+// bool ==(path3 a, path3 b);
+void gen_runpath3d2(stack *Stack)
+{
+ path3 b=vm::pop<path3>(Stack);
+ path3 a=vm::pop<path3>(Stack);
+#line 63 "runpath3d.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 67 "runpath3d.in"
+// bool !=(path3 a, path3 b);
+void gen_runpath3d3(stack *Stack)
+{
+ path3 b=vm::pop<path3>(Stack);
+ path3 a=vm::pop<path3>(Stack);
+#line 68 "runpath3d.in"
+ {Stack->push<bool>(!(a == b)); return;}
+}
+
+#line 72 "runpath3d.in"
+// triple point(path3 p, Int t);
+void gen_runpath3d4(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 73 "runpath3d.in"
+ {Stack->push<triple>(p.point((Int) t)); return;}
+}
+
+#line 77 "runpath3d.in"
+// triple point(path3 p, real t);
+void gen_runpath3d5(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 78 "runpath3d.in"
+ {Stack->push<triple>(p.point(t)); return;}
+}
+
+#line 82 "runpath3d.in"
+// triple precontrol(path3 p, Int t);
+void gen_runpath3d6(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 83 "runpath3d.in"
+ {Stack->push<triple>(p.precontrol((Int) t)); return;}
+}
+
+#line 87 "runpath3d.in"
+// triple precontrol(path3 p, real t);
+void gen_runpath3d7(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 88 "runpath3d.in"
+ {Stack->push<triple>(p.precontrol(t)); return;}
+}
+
+#line 92 "runpath3d.in"
+// triple postcontrol(path3 p, Int t);
+void gen_runpath3d8(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 93 "runpath3d.in"
+ {Stack->push<triple>(p.postcontrol((Int) t)); return;}
+}
+
+#line 97 "runpath3d.in"
+// triple postcontrol(path3 p, real t);
+void gen_runpath3d9(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 98 "runpath3d.in"
+ {Stack->push<triple>(p.postcontrol(t)); return;}
+}
+
+#line 102 "runpath3d.in"
+// triple dir(path3 p, Int t, Int sign=0, bool normalize=true);
+void gen_runpath3d10(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 103 "runpath3d.in"
+ {Stack->push<triple>(p.dir(t,sign,normalize)); return;}
+}
+
+#line 107 "runpath3d.in"
+// triple dir(path3 p, real t, bool normalize=true);
+void gen_runpath3d11(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 108 "runpath3d.in"
+ {Stack->push<triple>(p.dir(t,normalize)); return;}
+}
+
+#line 112 "runpath3d.in"
+// triple accel(path3 p, Int t, Int sign=0);
+void gen_runpath3d12(stack *Stack)
+{
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 113 "runpath3d.in"
+ {Stack->push<triple>(p.accel(t,sign)); return;}
+}
+
+#line 117 "runpath3d.in"
+// triple accel(path3 p, real t);
+void gen_runpath3d13(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 118 "runpath3d.in"
+ {Stack->push<triple>(p.accel(t)); return;}
+}
+
+#line 122 "runpath3d.in"
+// real radius(path3 p, real t);
+void gen_runpath3d14(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 123 "runpath3d.in"
+ triple v=p.dir(t,false);
+ triple a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ {Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
+}
+
+#line 134 "runpath3d.in"
+// real radius(triple z0, triple c0, triple c1, triple z1, real t);
+void gen_runpath3d15(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ triple z1=vm::pop<triple>(Stack);
+ triple c1=vm::pop<triple>(Stack);
+ triple c0=vm::pop<triple>(Stack);
+ triple z0=vm::pop<triple>(Stack);
+#line 135 "runpath3d.in"
+ triple v=(3.0*(z1-z0)+9.0*(c0-c1))*t*t+(6.0*(z0+c1)-12.0*c0)*t+3.0*(c0-z0);
+ triple a=6.0*(z1-z0+3.0*(c0-c1))*t+6.0*(z0+c1)-12.0*c0;
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ {Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
+}
+
+#line 146 "runpath3d.in"
+// path3 reverse(path3 p);
+void gen_runpath3d16(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 147 "runpath3d.in"
+ {Stack->push<path3>(p.reverse()); return;}
+}
+
+#line 151 "runpath3d.in"
+// path3 subpath(path3 p, Int a, Int b);
+void gen_runpath3d17(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 152 "runpath3d.in"
+ {Stack->push<path3>(p.subpath((Int) a, (Int) b)); return;}
+}
+
+#line 156 "runpath3d.in"
+// path3 subpath(path3 p, real a, real b);
+void gen_runpath3d18(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 157 "runpath3d.in"
+ {Stack->push<path3>(p.subpath(a,b)); return;}
+}
+
+#line 161 "runpath3d.in"
+// Int length(path3 p);
+void gen_runpath3d19(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 162 "runpath3d.in"
+ {Stack->push<Int>(p.length()); return;}
+}
+
+#line 166 "runpath3d.in"
+// bool cyclic(path3 p);
+void gen_runpath3d20(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 167 "runpath3d.in"
+ {Stack->push<bool>(p.cyclic()); return;}
+}
+
+#line 171 "runpath3d.in"
+// bool straight(path3 p, Int t);
+void gen_runpath3d21(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 172 "runpath3d.in"
+ {Stack->push<bool>(p.straight(t)); return;}
+}
+
+#line 176 "runpath3d.in"
+// path3 unstraighten(path3 p);
+void gen_runpath3d22(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 177 "runpath3d.in"
+ {Stack->push<path3>(p.unstraighten()); return;}
+}
+
+// Return the maximum perpendicular deviation of segment i of path3 g
+// from a straight line.
+#line 183 "runpath3d.in"
+// real straightness(path3 p, Int t);
+void gen_runpath3d23(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 184 "runpath3d.in"
+ if(p.straight(t)) {Stack->push<real>(0); return;}
+ triple z0=p.point(t);
+ triple u=unit(p.point(t+1)-z0);
+ {Stack->push<real>(::max(length(perp(p.postcontrol(t)-z0,u)),
+ length(perp(p.precontrol(t+1)-z0,u)))); return;}
+}
+
+// Return the maximum perpendicular deviation of z0..controls c0 and c1..z1
+// from a straight line.
+#line 194 "runpath3d.in"
+// real straightness(triple z0, triple c0, triple c1, triple z1);
+void gen_runpath3d24(stack *Stack)
+{
+ triple z1=vm::pop<triple>(Stack);
+ triple c1=vm::pop<triple>(Stack);
+ triple c0=vm::pop<triple>(Stack);
+ triple z0=vm::pop<triple>(Stack);
+#line 195 "runpath3d.in"
+ triple u=unit(z1-z0);
+ {Stack->push<real>(::max(length(perp(c0-z0,u)),length(perp(c1-z0,u)))); return;}
+}
+
+#line 200 "runpath3d.in"
+// bool piecewisestraight(path3 p);
+void gen_runpath3d25(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 201 "runpath3d.in"
+ {Stack->push<bool>(p.piecewisestraight()); return;}
+}
+
+#line 205 "runpath3d.in"
+// real arclength(path3 p);
+void gen_runpath3d26(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 206 "runpath3d.in"
+ {Stack->push<real>(p.arclength()); return;}
+}
+
+#line 210 "runpath3d.in"
+// real arctime(path3 p, real dval);
+void gen_runpath3d27(stack *Stack)
+{
+ real dval=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 211 "runpath3d.in"
+ {Stack->push<real>(p.arctime(dval)); return;}
+}
+
+#line 215 "runpath3d.in"
+// realarray* intersect(path3 p, path3 q, real fuzz=-1);
+void gen_runpath3d28(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path3 q=vm::pop<path3>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 216 "runpath3d.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ {Stack->push<realarray*>(V); return;}
+ } else
+ {Stack->push<realarray*>(new array(0)); return;}
+}
+
+#line 233 "runpath3d.in"
+// realarray2* intersections(path3 p, path3 q, real fuzz=-1);
+void gen_runpath3d29(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path3 q=vm::pop<path3>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 234 "runpath3d.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ bool single=!exact;
+
+ real s,t;
+ std::vector<real> S,T;
+ bool found=intersections(s,t,S,T,p,q,fuzz,single,exact);
+ if(!found) {Stack->push<realarray2*>(new array(0)); return;}
+ array *V;
+ if(single) {
+ V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ } else {
+ size_t n=S.size();
+ V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ {Stack->push<realarray2*>(V); return;}
+}
+
+#line 266 "runpath3d.in"
+// realarray* intersect(path3 p, triplearray2 *P, real fuzz=-1);
+void gen_runpath3d30(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 267 "runpath3d.in"
+ triple *A;
+ copyArray2C(A,P,true,4);
+ if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ norm(A,16));
+ std::vector<real> T,U,V;
+ bool found=intersections(T,U,V,p,A,fuzz,true);
+ delete[] A;
+ if(found) {
+ array *W=new array(3);
+ (*W)[0]=T[0];
+ (*W)[1]=U[0];
+ (*W)[2]=V[0];
+ {Stack->push<realarray*>(W); return;}
+ } else
+ {Stack->push<realarray*>(new array(0)); return;}
+}
+
+#line 285 "runpath3d.in"
+// realarray2* intersections(path3 p, triplearray2 *P, real fuzz=-1);
+void gen_runpath3d31(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 286 "runpath3d.in"
+ triple *A;
+ copyArray2C(A,P,true,4);
+ if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ norm(A,16));
+ std::vector<real> T,U,V;
+ intersections(T,U,V,p,A,fuzz,false);
+ delete[] A;
+ size_t n=T.size();
+ array *W=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Wi=new array(3);
+ (*W)[i]=Wi;
+ (*Wi)[0]=T[i];
+ (*Wi)[1]=U[i];
+ (*Wi)[2]=V[i];
+ }
+ {Stack->push<realarray2*>(W); return;} // Sorting will done in asy.
+}
+
+#line 306 "runpath3d.in"
+// Int size(path3 p);
+void gen_runpath3d32(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 307 "runpath3d.in"
+ {Stack->push<Int>(p.size()); return;}
+}
+
+#line 311 "runpath3d.in"
+// path3 &(path3 p, path3 q);
+void gen_runpath3d33(stack *Stack)
+{
+ path3 q=vm::pop<path3>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 312 "runpath3d.in"
+ {Stack->push<path3>(camp::concat(p,q)); return;}
+}
+
+#line 316 "runpath3d.in"
+// triple min(path3 p);
+void gen_runpath3d34(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 317 "runpath3d.in"
+ {Stack->push<triple>(p.min()); return;}
+}
+
+#line 321 "runpath3d.in"
+// triple max(path3 p);
+void gen_runpath3d35(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 322 "runpath3d.in"
+ {Stack->push<triple>(p.max()); return;}
+}
+
+#line 326 "runpath3d.in"
+// realarray* mintimes(path3 p);
+void gen_runpath3d36(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 327 "runpath3d.in"
+ array *V=new array(3);
+ triple v=p.mintimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 336 "runpath3d.in"
+// realarray* maxtimes(path3 p);
+void gen_runpath3d37(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 337 "runpath3d.in"
+ array *V=new array(3);
+ triple v=p.maxtimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 346 "runpath3d.in"
+// path3 *(realarray2 *t, path3 g);
+void gen_runpath3d38(stack *Stack)
+{
+ path3 g=vm::pop<path3>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+#line 347 "runpath3d.in"
+ {Stack->push<path3>(transformed(*t,g)); return;}
+}
+
+#line 351 "runpath3d.in"
+// pair minratio(path3 g);
+void gen_runpath3d39(stack *Stack)
+{
+ path3 g=vm::pop<path3>(Stack);
+#line 352 "runpath3d.in"
+ {Stack->push<pair>(g.ratio(::min)); return;}
+}
+
+#line 356 "runpath3d.in"
+// pair maxratio(path3 g);
+void gen_runpath3d40(stack *Stack)
+{
+ path3 g=vm::pop<path3>(Stack);
+#line 357 "runpath3d.in"
+ {Stack->push<pair>(g.ratio(::max)); return;}
+}
+
+// Return a negative (positive) value if a--b--c--cycle is oriented
+// counterclockwise (clockwise) when viewed from d or zero if all four
+// points are coplanar.
+// The value returned is the determinant
+// |a.x a.y a.z 1|
+// |b.x b.y b.z 1|
+// |c.x c.y c.z 1|
+// |d.x d.y d.z 1|
+#line 369 "runpath3d.in"
+// real orient(triple a, triple b, triple c, triple d);
+void gen_runpath3d41(stack *Stack)
+{
+ triple d=vm::pop<triple>(Stack);
+ triple c=vm::pop<triple>(Stack);
+ triple b=vm::pop<triple>(Stack);
+ triple a=vm::pop<triple>(Stack);
+#line 370 "runpath3d.in"
+ real A[]={a.getx(),a.gety(),a.getz()};
+ real B[]={b.getx(),b.gety(),b.getz()};
+ real C[]={c.getx(),c.gety(),c.getz()};
+ real D[]={d.getx(),d.gety(),d.getz()};
+ {Stack->push<real>(orient3d(A,B,C,D)); return;}
+}
+
+// Return a positive (negative) value if e lies inside (outside)
+// the sphere passing through the points a,b,c,d oriented so that
+// a--b--c--cycle appears in clockwise order when viewed from d
+// or zero if all five points are cospherical.
+// The value returned is the determinant
+// |a.x a.y a.z a.x^2+a.y^2+a.z^2 1|
+// |b.x b.y b.z b.x^2+b.y^2+b.z^2 1|
+// |c.x c.y c.z c.x^2+c.y^2+c.z^2 1|
+// |d.x d.y d.z d.x^2+d.y^2+d.z^2 1|
+// |e.x e.y e.z e.x^2+e.y^2+e.z^2 1|
+#line 388 "runpath3d.in"
+// real insphere(triple a, triple b, triple c, triple d, triple e);
+void gen_runpath3d42(stack *Stack)
+{
+ triple e=vm::pop<triple>(Stack);
+ triple d=vm::pop<triple>(Stack);
+ triple c=vm::pop<triple>(Stack);
+ triple b=vm::pop<triple>(Stack);
+ triple a=vm::pop<triple>(Stack);
+#line 389 "runpath3d.in"
+ real A[]={a.getx(),a.gety(),a.getz()};
+ real B[]={b.getx(),b.gety(),b.getz()};
+ real C[]={c.getx(),c.gety(),c.getz()};
+ real D[]={d.getx(),d.gety(),d.getz()};
+ real E[]={e.getx(),e.gety(),e.getz()};
+ {Stack->push<real>(insphere(A,B,C,D,E)); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runpath3d_venv(venv &ve)
+{
+#line 40 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d0, primPath3(), SYM(path3), formal(tripleArray(), SYM(pre), false, false), formal(tripleArray(), SYM(point), false, false), formal(tripleArray(), SYM(post), false, false), formal(booleanArray(), SYM(straight), false, false), formal(primBoolean(), SYM(cyclic), false, false));
+#line 57 "runpath3d.in"
+ REGISTER_BLTIN(run::nullPath3,"nullPath3");
+#line 62 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d2, primBoolean(), SYM_EQ, formal(primPath3(), SYM(a), false, false), formal(primPath3(), SYM(b), false, false));
+#line 67 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d3, primBoolean(), SYM_NEQ, formal(primPath3(), SYM(a), false, false), formal(primPath3(), SYM(b), false, false));
+#line 72 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d4, primTriple(), SYM(point), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 77 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d5, primTriple(), SYM(point), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 82 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d6, primTriple(), SYM(precontrol), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 87 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d7, primTriple(), SYM(precontrol), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 92 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d8, primTriple(), SYM(postcontrol), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 97 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d9, primTriple(), SYM(postcontrol), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 102 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d10, primTriple(), SYM(dir), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false), formal(primInt(), SYM(sign), true, false), formal(primBoolean(), SYM(normalize), true, false));
+#line 107 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d11, primTriple(), SYM(dir), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(t), false, false), formal(primBoolean(), SYM(normalize), true, false));
+#line 112 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d12, primTriple(), SYM(accel), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false), formal(primInt(), SYM(sign), true, false));
+#line 117 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d13, primTriple(), SYM(accel), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 122 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d14, primReal(), SYM(radius), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(t), false, false));
+#line 134 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d15, primReal(), SYM(radius), formal(primTriple(), SYM(z0), false, false), formal(primTriple(), SYM(c0), false, false), formal(primTriple(), SYM(c1), false, false), formal(primTriple(), SYM(z1), false, false), formal(primReal(), SYM(t), false, false));
+#line 146 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d16, primPath3(), SYM(reverse), formal(primPath3(), SYM(p), false, false));
+#line 151 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d17, primPath3(), SYM(subpath), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
+#line 156 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d18, primPath3(), SYM(subpath), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false));
+#line 161 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d19, primInt(), SYM(length), formal(primPath3(), SYM(p), false, false));
+#line 166 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d20, primBoolean(), SYM(cyclic), formal(primPath3(), SYM(p), false, false));
+#line 171 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d21, primBoolean(), SYM(straight), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 176 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d22, primPath3(), SYM(unstraighten), formal(primPath3(), SYM(p), false, false));
+#line 181 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d23, primReal(), SYM(straightness), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 192 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d24, primReal(), SYM(straightness), formal(primTriple(), SYM(z0), false, false), formal(primTriple(), SYM(c0), false, false), formal(primTriple(), SYM(c1), false, false), formal(primTriple(), SYM(z1), false, false));
+#line 200 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d25, primBoolean(), SYM(piecewisestraight), formal(primPath3(), SYM(p), false, false));
+#line 205 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d26, primReal(), SYM(arclength), formal(primPath3(), SYM(p), false, false));
+#line 210 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d27, primReal(), SYM(arctime), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(dval), false, false));
+#line 215 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d28, realArray(), SYM(intersect), formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 233 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d29, realArray2(), SYM(intersections), formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 266 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d30, realArray(), SYM(intersect), formal(primPath3(), SYM(p), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 285 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d31, realArray2(), SYM(intersections), formal(primPath3(), SYM(p), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 306 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d32, primInt(), SYM(size), formal(primPath3(), SYM(p), false, false));
+#line 311 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d33, primPath3(), SYM_AMPERSAND, formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false));
+#line 316 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d34, primTriple(), SYM(min), formal(primPath3(), SYM(p), false, false));
+#line 321 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d35, primTriple(), SYM(max), formal(primPath3(), SYM(p), false, false));
+#line 326 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d36, realArray(), SYM(mintimes), formal(primPath3(), SYM(p), false, false));
+#line 336 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d37, realArray(), SYM(maxtimes), formal(primPath3(), SYM(p), false, false));
+#line 346 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d38, primPath3(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primPath3(), SYM(g), false, false));
+#line 351 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d39, primPair(), SYM(minratio), formal(primPath3(), SYM(g), false, false));
+#line 356 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d40, primPair(), SYM(maxratio), formal(primPath3(), SYM(g), false, false));
+#line 361 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d41, primReal(), SYM(orient), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false));
+#line 378 "runpath3d.in"
+ addFunc(ve, run::gen_runpath3d42, primReal(), SYM(insphere), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primTriple(), SYM(e), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runpath3d.h b/graphics/asymptote/runpath3d.h
new file mode 100644
index 0000000000..cdb6480460
--- /dev/null
+++ b/graphics/asymptote/runpath3d.h
@@ -0,0 +1,9 @@
+/***** Autogenerated from runpath3d.in; changes will be overwritten *****/
+
+#ifndef runpath3d_H
+#define runpath3d_H
+namespace run {
+void nullPath3(vm::stack *);
+}
+
+#endif // runpath3d_H
diff --git a/graphics/asymptote/runpath3d.in b/graphics/asymptote/runpath3d.in
new file mode 100644
index 0000000000..74c337748f
--- /dev/null
+++ b/graphics/asymptote/runpath3d.in
@@ -0,0 +1,396 @@
+/*****
+ * runpath3.in
+ *
+ * Runtime functions for path3 operations.
+ *
+ *****/
+
+pair => primPair()
+triple => primTriple()
+path3 => primPath3()
+boolarray* => booleanArray()
+realarray* => realArray()
+realarray2* => realArray2()
+triplearray* => tripleArray()
+triplearray2* => tripleArray2()
+
+#include "path3.h"
+#include "array.h"
+#include "drawsurface.h"
+#include "predicates.h"
+
+using namespace camp;
+using namespace vm;
+
+typedef array boolarray;
+typedef array realarray;
+typedef array realarray2;
+typedef array triplearray;
+typedef array triplearray2;
+
+using types::booleanArray;
+using types::realArray;
+using types::realArray2;
+using types::tripleArray;
+using types::tripleArray2;
+
+// Autogenerated routines:
+
+
+path3 path3(triplearray *pre, triplearray *point, triplearray *post,
+ boolarray *straight, bool cyclic)
+{
+ size_t n=checkArrays(pre,point);
+ checkEqual(n,checkArray(post));
+ checkEqual(n,checkArray(straight));
+ mem::vector<solvedKnot3> nodes(n);
+ for(size_t i=0; i < n; ++i) {
+ nodes[i].pre=read<triple>(pre,i);
+ nodes[i].point=read<triple>(point,i);
+ nodes[i].post=read<triple>(post,i);
+ nodes[i].straight=read<bool>(straight,i);
+ }
+
+ return path3(nodes,(Int) n,cyclic);
+}
+
+path3 :nullPath3()
+{
+ return nullpath3;
+}
+
+bool ==(path3 a, path3 b)
+{
+ return a == b;
+}
+
+bool !=(path3 a, path3 b)
+{
+ return !(a == b);
+}
+
+triple point(path3 p, Int t)
+{
+ return p.point((Int) t);
+}
+
+triple point(path3 p, real t)
+{
+ return p.point(t);
+}
+
+triple precontrol(path3 p, Int t)
+{
+ return p.precontrol((Int) t);
+}
+
+triple precontrol(path3 p, real t)
+{
+ return p.precontrol(t);
+}
+
+triple postcontrol(path3 p, Int t)
+{
+ return p.postcontrol((Int) t);
+}
+
+triple postcontrol(path3 p, real t)
+{
+ return p.postcontrol(t);
+}
+
+triple dir(path3 p, Int t, Int sign=0, bool normalize=true)
+{
+ return p.dir(t,sign,normalize);
+}
+
+triple dir(path3 p, real t, bool normalize=true)
+{
+ return p.dir(t,normalize);
+}
+
+triple accel(path3 p, Int t, Int sign=0)
+{
+ return p.accel(t,sign);
+}
+
+triple accel(path3 p, real t)
+{
+ return p.accel(t);
+}
+
+real radius(path3 p, real t)
+{
+ triple v=p.dir(t,false);
+ triple a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ return denom > 0 ? r/sqrt(denom) : 0.0;
+}
+
+real radius(triple z0, triple c0, triple c1, triple z1, real t)
+{
+ triple v=(3.0*(z1-z0)+9.0*(c0-c1))*t*t+(6.0*(z0+c1)-12.0*c0)*t+3.0*(c0-z0);
+ triple a=6.0*(z1-z0+3.0*(c0-c1))*t+6.0*(z0+c1)-12.0*c0;
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ return denom > 0 ? r/sqrt(denom) : 0.0;
+}
+
+path3 reverse(path3 p)
+{
+ return p.reverse();
+}
+
+path3 subpath(path3 p, Int a, Int b)
+{
+ return p.subpath((Int) a, (Int) b);
+}
+
+path3 subpath(path3 p, real a, real b)
+{
+ return p.subpath(a,b);
+}
+
+Int length(path3 p)
+{
+ return p.length();
+}
+
+bool cyclic(path3 p)
+{
+ return p.cyclic();
+}
+
+bool straight(path3 p, Int t)
+{
+ return p.straight(t);
+}
+
+path3 unstraighten(path3 p)
+{
+ return p.unstraighten();
+}
+
+// Return the maximum perpendicular deviation of segment i of path3 g
+// from a straight line.
+real straightness(path3 p, Int t)
+{
+ if(p.straight(t)) return 0;
+ triple z0=p.point(t);
+ triple u=unit(p.point(t+1)-z0);
+ return ::max(length(perp(p.postcontrol(t)-z0,u)),
+ length(perp(p.precontrol(t+1)-z0,u)));
+}
+
+// Return the maximum perpendicular deviation of z0..controls c0 and c1..z1
+// from a straight line.
+real straightness(triple z0, triple c0, triple c1, triple z1)
+{
+ triple u=unit(z1-z0);
+ return ::max(length(perp(c0-z0,u)),length(perp(c1-z0,u)));
+}
+
+bool piecewisestraight(path3 p)
+{
+ return p.piecewisestraight();
+}
+
+real arclength(path3 p)
+{
+ return p.arclength();
+}
+
+real arctime(path3 p, real dval)
+{
+ return p.arctime(dval);
+}
+
+realarray* intersect(path3 p, path3 q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ return V;
+ } else
+ return new array(0);
+}
+
+realarray2* intersections(path3 p, path3 q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ bool single=!exact;
+
+ real s,t;
+ std::vector<real> S,T;
+ bool found=intersections(s,t,S,T,p,q,fuzz,single,exact);
+ if(!found) return new array(0);
+ array *V;
+ if(single) {
+ V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ } else {
+ size_t n=S.size();
+ V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ return V;
+}
+
+realarray* intersect(path3 p, triplearray2 *P, real fuzz=-1)
+{
+ triple *A;
+ copyArray2C(A,P,true,4);
+ if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ norm(A,16));
+ std::vector<real> T,U,V;
+ bool found=intersections(T,U,V,p,A,fuzz,true);
+ delete[] A;
+ if(found) {
+ array *W=new array(3);
+ (*W)[0]=T[0];
+ (*W)[1]=U[0];
+ (*W)[2]=V[0];
+ return W;
+ } else
+ return new array(0);
+}
+
+realarray2* intersections(path3 p, triplearray2 *P, real fuzz=-1)
+{
+ triple *A;
+ copyArray2C(A,P,true,4);
+ if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ norm(A,16));
+ std::vector<real> T,U,V;
+ intersections(T,U,V,p,A,fuzz,false);
+ delete[] A;
+ size_t n=T.size();
+ array *W=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Wi=new array(3);
+ (*W)[i]=Wi;
+ (*Wi)[0]=T[i];
+ (*Wi)[1]=U[i];
+ (*Wi)[2]=V[i];
+ }
+ return W; // Sorting will done in asy.
+}
+
+Int size(path3 p)
+{
+ return p.size();
+}
+
+path3 &(path3 p, path3 q)
+{
+ return camp::concat(p,q);
+}
+
+triple min(path3 p)
+{
+ return p.min();
+}
+
+triple max(path3 p)
+{
+ return p.max();
+}
+
+realarray *mintimes(path3 p)
+{
+ array *V=new array(3);
+ triple v=p.mintimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ return V;
+}
+
+realarray *maxtimes(path3 p)
+{
+ array *V=new array(3);
+ triple v=p.maxtimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ return V;
+}
+
+path3 Operator *(realarray2 *t, path3 g)
+{
+ return transformed(*t,g);
+}
+
+pair minratio(path3 g)
+{
+ return g.ratio(::min);
+}
+
+pair maxratio(path3 g)
+{
+ return g.ratio(::max);
+}
+
+// Return a negative (positive) value if a--b--c--cycle is oriented
+// counterclockwise (clockwise) when viewed from d or zero if all four
+// points are coplanar.
+// The value returned is the determinant
+// |a.x a.y a.z 1|
+// |b.x b.y b.z 1|
+// |c.x c.y c.z 1|
+// |d.x d.y d.z 1|
+real orient(triple a, triple b, triple c, triple d)
+{
+ real A[]={a.getx(),a.gety(),a.getz()};
+ real B[]={b.getx(),b.gety(),b.getz()};
+ real C[]={c.getx(),c.gety(),c.getz()};
+ real D[]={d.getx(),d.gety(),d.getz()};
+ return orient3d(A,B,C,D);
+}
+
+// Return a positive (negative) value if e lies inside (outside)
+// the sphere passing through the points a,b,c,d oriented so that
+// a--b--c--cycle appears in clockwise order when viewed from d
+// or zero if all five points are cospherical.
+// The value returned is the determinant
+// |a.x a.y a.z a.x^2+a.y^2+a.z^2 1|
+// |b.x b.y b.z b.x^2+b.y^2+b.z^2 1|
+// |c.x c.y c.z c.x^2+c.y^2+c.z^2 1|
+// |d.x d.y d.z d.x^2+d.y^2+d.z^2 1|
+// |e.x e.y e.z e.x^2+e.y^2+e.z^2 1|
+real insphere(triple a, triple b, triple c, triple d, triple e)
+{
+ real A[]={a.getx(),a.gety(),a.getz()};
+ real B[]={b.getx(),b.gety(),b.getz()};
+ real C[]={c.getx(),c.gety(),c.getz()};
+ real D[]={d.getx(),d.gety(),d.getz()};
+ real E[]={e.getx(),e.gety(),e.getz()};
+ return insphere(A,B,C,D,E);
+}
diff --git a/graphics/asymptote/runpicture.cc b/graphics/asymptote/runpicture.cc
new file mode 100644
index 0000000000..d800347ffd
--- /dev/null
+++ b/graphics/asymptote/runpicture.cc
@@ -0,0 +1,1318 @@
+/***** Autogenerated from runpicture.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runpicture.in"
+/*****
+ * runpicture.in
+ *
+ * Runtime functions for picture operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 29 "runpicture.in"
+#include "picture.h"
+#include "drawelement.h"
+#include "path.h"
+#include "array.h"
+#include "arrayop.h"
+#include "drawpath.h"
+#include "drawfill.h"
+#include "drawclipbegin.h"
+#include "drawclipend.h"
+#include "drawgsave.h"
+#include "drawgrestore.h"
+#include "drawgroup.h"
+#include "drawverbatim.h"
+#include "drawlabel.h"
+#include "drawlayer.h"
+#include "drawimage.h"
+#include "drawpath3.h"
+#include "drawsurface.h"
+
+using namespace camp;
+using namespace settings;
+using namespace vm;
+
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray;
+typedef array triplearray2;
+typedef array patharray;
+typedef array penarray;
+typedef array penarray2;
+
+typedef callable callableTransform;
+typedef callable callablePen;
+
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray;
+using types::tripleArray2;
+using types::pathArray;
+using types::penArray;
+using types::penArray2;
+
+static transform ZeroTransform=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+
+transform getTransform(xmap_t &xmap, picture::nodelist::iterator p)
+{
+ string s=(*p)->KEY;
+ transform t;
+ // Don't apply xmap without an explicit corresponding key
+ size_t n=s.length();
+ if(n == 0 || s.substr(n-1) != "1") return t;
+
+ xmap_t::iterator q=xmap.find(s.substr(0,n-2));
+ if(q != xmap.end()) {
+ xtransform_t& v=q->second;
+ if(!v.empty()) {
+ t=v.front();
+ v.pop_front();
+ }
+ }
+ return t;
+}
+
+
+function *transformFunction()
+{
+ return new function(primTransform());
+}
+
+function *penFunction()
+{
+ return new function(primPen(),primInt(),primInt());
+}
+
+// Ignore unclosed begingroups but not spurious endgroups.
+const char *nobegin="endgroup without matching begingroup";
+
+array *emptyarray=new array(0);
+
+array *nop(array *a)
+{
+ return a;
+}
+
+triple Zero;
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runpicture.symbols.h"
+
+#endif
+namespace run {
+#line 126 "runpicture.in"
+void newPicture(stack *Stack)
+{
+#line 127 "runpicture.in"
+ {Stack->push<picture*>(new picture()); return;}
+}
+
+#line 131 "runpicture.in"
+// bool empty(picture *f);
+void gen_runpicture1(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 132 "runpicture.in"
+ {Stack->push<bool>(f->null()); return;}
+}
+
+#line 136 "runpicture.in"
+// void erase(picture *f);
+void gen_runpicture2(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 137 "runpicture.in"
+ f->nodes.clear();
+}
+
+#line 141 "runpicture.in"
+// pair min(picture *f);
+void gen_runpicture3(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 142 "runpicture.in"
+ {Stack->push<pair>(f->bounds().Min()); return;}
+}
+
+#line 146 "runpicture.in"
+// pair max(picture *f);
+void gen_runpicture4(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 147 "runpicture.in"
+ {Stack->push<pair>(f->bounds().Max()); return;}
+}
+
+#line 151 "runpicture.in"
+// pair size(picture *f);
+void gen_runpicture5(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 152 "runpicture.in"
+ bbox b=f->bounds();
+ {Stack->push<pair>(b.Max()-b.Min()); return;}
+}
+
+#line 157 "runpicture.in"
+// void _draw(picture *f, path g, pen p);
+void gen_runpicture6(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ path g=vm::pop<path>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 158 "runpicture.in"
+ f->append(new drawPath(g,p));
+}
+
+#line 162 "runpicture.in"
+// void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true);
+void gen_runpicture7(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 163 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawFill(*copyarray(g),false,p));
+}
+
+#line 168 "runpicture.in"
+// void latticeshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray2 *p, transform t=identity, bool copy=true);
+void gen_runpicture8(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ transform t=vm::pop<transform>(Stack,identity);
+ penarray2 * p=vm::pop<penarray2 *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 171 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ t));
+}
+
+#line 177 "runpicture.in"
+// void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, bool extenda=true, pen penb, pair b, bool extendb=true, bool copy=true);
+void gen_runpicture9(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ bool extendb=vm::pop<bool>(Stack,true);
+ pair b=vm::pop<pair>(Stack);
+ pen penb=vm::pop<pen>(Stack);
+ bool extenda=vm::pop<bool>(Stack,true);
+ pair a=vm::pop<pair>(Stack);
+ pen pena=vm::pop<pen>(Stack);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 180 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,extenda,penb,b,
+ extendb));
+}
+
+#line 186 "runpicture.in"
+// void radialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, real ra, bool extenda=true, pen penb, pair b, real rb, bool extendb=true, bool copy=true);
+void gen_runpicture10(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ bool extendb=vm::pop<bool>(Stack,true);
+ real rb=vm::pop<real>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pen penb=vm::pop<pen>(Stack);
+ bool extenda=vm::pop<bool>(Stack,true);
+ real ra=vm::pop<real>(Stack);
+ pair a=vm::pop<pair>(Stack);
+ pen pena=vm::pop<pen>(Stack);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 189 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,extenda,
+ penb,b,rb,extendb));
+}
+
+#line 195 "runpicture.in"
+// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, pairarray *z, Intarray *edges, bool copy=true);
+void gen_runpicture11(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ Intarray * edges=vm::pop<Intarray *>(Stack);
+ pairarray * z=vm::pop<pairarray *>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 198 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ checkArrays(p,z);
+ checkArrays(z,edges);
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *copyarray(z),*copyarray(edges)));
+}
+
+#line 206 "runpicture.in"
+// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, Intarray *edges, bool copy=true);
+void gen_runpicture12(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ Intarray * edges=vm::pop<Intarray *>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 209 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ size_t n=checkArrays(p,edges);
+ size_t m=checkArray(g);
+ array *z=new array(n);
+ Int k=0;
+ Int in=(Int) n;
+ for(size_t j=0; j < m; ++j) {
+ path *P=read<path *>(g,j);
+ assert(P);
+ Int stop=Min(P->size(),in-k);
+ mem::vector<solvedKnot>& nodes=P->Nodes();
+ for(Int i=0; i < stop; ++i)
+ (*z)[k++]=nodes[i].point;
+ }
+ checkArrays(p,z);
+
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *z,*copyarray(edges)));
+}
+
+#line 230 "runpicture.in"
+// void tensorshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL, pairarray2 *z=emptyarray, bool copy=true);
+void gen_runpicture13(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pairarray2 * z=vm::pop<pairarray2 *>(Stack,emptyarray);
+ patharray * b=vm::pop<patharray *>(Stack,NULL);
+ penarray2 * p=vm::pop<penarray2 *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 233 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
+ if(b == NULL) b=g;
+ size_t n=checkArrays(p,b);
+ size_t nz=checkArray(z);
+ if(nz != 0)
+ checkEqual(nz,n);
+ f->append(new drawTensorShade(*copyarray(g),stroke,fillrule,*copyarray2(p),
+ *copyarray(b),*copyarray2(z)));
+}
+
+#line 245 "runpicture.in"
+// void functionshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, string shader=emptystring, bool copy=true);
+void gen_runpicture14(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ string shader=vm::pop<string>(Stack,emptystring);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 248 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
+}
+
+// Clip a picture to a superpath using the given fill rule.
+// Subsequent additions to the picture will not be affected by the clipping.
+#line 255 "runpicture.in"
+// void clip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
+void gen_runpicture15(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 257 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
+ f->enclose(begin,new drawClipEnd(true,begin));
+}
+
+#line 263 "runpicture.in"
+// void beginclip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
+void gen_runpicture16(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 265 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
+}
+
+#line 270 "runpicture.in"
+// void endclip(picture *f);
+void gen_runpicture17(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 271 "runpicture.in"
+ f->append(new drawClipEnd(false));
+}
+
+#line 275 "runpicture.in"
+// void gsave(picture *f);
+void gen_runpicture18(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 276 "runpicture.in"
+ f->append(new drawGsave());
+}
+
+#line 280 "runpicture.in"
+// void grestore(picture *f);
+void gen_runpicture19(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 281 "runpicture.in"
+ f->append(new drawGrestore());
+}
+
+#line 285 "runpicture.in"
+// void begingroup(picture *f);
+void gen_runpicture20(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 286 "runpicture.in"
+ f->append(new drawBegin());
+}
+
+#line 290 "runpicture.in"
+// void endgroup(picture *f);
+void gen_runpicture21(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 291 "runpicture.in"
+ f->append(new drawEnd());
+}
+
+#line 295 "runpicture.in"
+// void _begingroup3(picture *f, string name, real compression, real granularity, bool closed, bool tessellate, bool dobreak, bool nobreak, triple center, Int interaction);
+void gen_runpicture22(stack *Stack)
+{
+ Int interaction=vm::pop<Int>(Stack);
+ triple center=vm::pop<triple>(Stack);
+ bool nobreak=vm::pop<bool>(Stack);
+ bool dobreak=vm::pop<bool>(Stack);
+ bool tessellate=vm::pop<bool>(Stack);
+ bool closed=vm::pop<bool>(Stack);
+ real granularity=vm::pop<real>(Stack);
+ real compression=vm::pop<real>(Stack);
+ string name=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 298 "runpicture.in"
+ f->append(new drawBegin3(name,compression,granularity,
+ closed,tessellate,dobreak,nobreak,
+ center,(Interaction) intcast(interaction)));
+}
+
+#line 304 "runpicture.in"
+// void endgroup3(picture *f);
+void gen_runpicture23(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 305 "runpicture.in"
+ f->append(new drawEnd3());
+}
+
+#line 309 "runpicture.in"
+// void add(picture *dest, picture *src);
+void gen_runpicture24(stack *Stack)
+{
+ picture * src=vm::pop<picture *>(Stack);
+ picture * dest=vm::pop<picture *>(Stack);
+#line 310 "runpicture.in"
+ dest->add(*src);
+}
+
+#line 314 "runpicture.in"
+// void prepend(picture *dest, picture *src);
+void gen_runpicture25(stack *Stack)
+{
+ picture * src=vm::pop<picture *>(Stack);
+ picture * dest=vm::pop<picture *>(Stack);
+#line 315 "runpicture.in"
+ dest->prepend(*src);
+}
+
+#line 319 "runpicture.in"
+// void postscript(picture *f, string s);
+void gen_runpicture26(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 320 "runpicture.in"
+ f->append(new drawVerbatim(PostScript,s));
+}
+
+#line 324 "runpicture.in"
+// void tex(picture *f, string s);
+void gen_runpicture27(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 325 "runpicture.in"
+ f->append(new drawVerbatim(TeX,s));
+}
+
+#line 329 "runpicture.in"
+// void postscript(picture *f, string s, pair min, pair max);
+void gen_runpicture28(stack *Stack)
+{
+ pair max=vm::pop<pair>(Stack);
+ pair min=vm::pop<pair>(Stack);
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 330 "runpicture.in"
+ f->append(new drawVerbatim(PostScript,s,min,max));
+}
+
+#line 334 "runpicture.in"
+// void tex(picture *f, string s, pair min, pair max);
+void gen_runpicture29(stack *Stack)
+{
+ pair max=vm::pop<pair>(Stack);
+ pair min=vm::pop<pair>(Stack);
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 335 "runpicture.in"
+ f->append(new drawVerbatim(TeX,s,min,max));
+}
+
+#line 339 "runpicture.in"
+// void texpreamble(string s);
+void gen_runpicture30(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 340 "runpicture.in"
+ string t=s+"\n";
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.push_back(t);
+ pd.TeXpreamble.push_back(t);
+}
+
+#line 347 "runpicture.in"
+// void deletepreamble();
+void gen_runpicture31(stack *)
+{
+#line 348 "runpicture.in"
+ if(getSetting<bool>("inlinetex")) {
+ unlink(buildname(outname(),"pre").c_str());
+ }
+}
+
+#line 354 "runpicture.in"
+// void _labelpath(picture *f, string s, string size, path g, string justify, pair offset, pen p);
+void gen_runpicture32(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ pair offset=vm::pop<pair>(Stack);
+ string justify=vm::pop<string>(Stack);
+ path g=vm::pop<path>(Stack);
+ string size=vm::pop<string>(Stack);
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 356 "runpicture.in"
+ f->append(new drawLabelPath(s,size,g,justify,offset,p));
+}
+
+#line 360 "runpicture.in"
+// void texreset();
+void gen_runpicture33(stack *)
+{
+#line 361 "runpicture.in"
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.clear();
+ pd.TeXpreamble.clear();
+ pd.tex.pipeclose();
+}
+
+#line 368 "runpicture.in"
+// void layer(picture *f);
+void gen_runpicture34(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 369 "runpicture.in"
+ f->append(new drawLayer());
+}
+
+#line 373 "runpicture.in"
+// void newpage(picture *f);
+void gen_runpicture35(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 374 "runpicture.in"
+ f->append(new drawNewPage());
+}
+
+#line 378 "runpicture.in"
+// void _image(picture *f, realarray2 *data, pair initial, pair final, penarray *palette=NULL, transform t=identity, bool copy=true, bool antialias=false);
+void gen_runpicture36(stack *Stack)
+{
+ bool antialias=vm::pop<bool>(Stack,false);
+ bool copy=vm::pop<bool>(Stack,true);
+ transform t=vm::pop<transform>(Stack,identity);
+ penarray * palette=vm::pop<penarray *>(Stack,NULL);
+ pair final=vm::pop<pair>(Stack);
+ pair initial=vm::pop<pair>(Stack);
+ realarray2 * data=vm::pop<realarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 381 "runpicture.in"
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
+ f->append(new drawPaletteImage(*copyarray2(data),*copyarray(palette),
+ t*matrix(initial,final),antialias));
+}
+
+#line 388 "runpicture.in"
+// void _image(picture *f, penarray2 *data, pair initial, pair final, transform t=identity, bool copy=true, bool antialias=false);
+void gen_runpicture37(stack *Stack)
+{
+ bool antialias=vm::pop<bool>(Stack,false);
+ bool copy=vm::pop<bool>(Stack,true);
+ transform t=vm::pop<transform>(Stack,identity);
+ pair final=vm::pop<pair>(Stack);
+ pair initial=vm::pop<pair>(Stack);
+ penarray2 * data=vm::pop<penarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 390 "runpicture.in"
+ array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
+ f->append(new drawNoPaletteImage(*copyarray2(data),t*matrix(initial,final),
+ antialias));
+}
+
+#line 396 "runpicture.in"
+// void _image(picture *f, callablePen *F, Int width, Int height, pair initial, pair final, transform t=identity, bool antialias=false);
+void gen_runpicture38(stack *Stack)
+{
+ bool antialias=vm::pop<bool>(Stack,false);
+ transform t=vm::pop<transform>(Stack,identity);
+ pair final=vm::pop<pair>(Stack);
+ pair initial=vm::pop<pair>(Stack);
+ Int height=vm::pop<Int>(Stack);
+ Int width=vm::pop<Int>(Stack);
+ callablePen * F=vm::pop<callablePen *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 398 "runpicture.in"
+ f->append(new drawFunctionImage(Stack,F,width,height,
+ t*matrix(initial,final),antialias));
+}
+
+#line 403 "runpicture.in"
+// string nativeformat();
+void gen_runpicture39(stack *Stack)
+{
+#line 404 "runpicture.in"
+ {Stack->push<string>(nativeformat()); return;}
+}
+
+#line 408 "runpicture.in"
+// bool latex();
+void gen_runpicture40(stack *Stack)
+{
+#line 409 "runpicture.in"
+ {Stack->push<bool>(latex(getSetting<string>("tex"))); return;}
+}
+
+#line 413 "runpicture.in"
+// bool pdf();
+void gen_runpicture41(stack *Stack)
+{
+#line 414 "runpicture.in"
+ {Stack->push<bool>(pdf(getSetting<string>("tex"))); return;}
+}
+
+#line 418 "runpicture.in"
+// void _shipout(string prefix=emptystring, picture *f, picture *preamble=NULL, string format=emptystring, bool wait=false, bool view=true, transform T=identity);
+void gen_runpicture42(stack *Stack)
+{
+ transform T=vm::pop<transform>(Stack,identity);
+ bool view=vm::pop<bool>(Stack,true);
+ bool wait=vm::pop<bool>(Stack,false);
+ string format=vm::pop<string>(Stack,emptystring);
+ picture * preamble=vm::pop<picture *>(Stack,NULL);
+ picture * f=vm::pop<picture *>(Stack);
+ string prefix=vm::pop<string>(Stack,emptystring);
+#line 421 "runpicture.in"
+ if(prefix.empty()) prefix=outname();
+
+ picture *result=new picture;
+ unsigned level=0;
+ picture::nodelist::iterator p;
+
+ xmap_t xmap=processData().xmap;
+ transform Tinv=inverse(T);
+
+ for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ transform t=getTransform(xmap,p);
+ bool Delete=(t == ZeroTransform);
+ if(!Delete && !t.isIdentity()) t=T*t*Tinv;
+ picture *group=new picture;
+ assert(*p);
+ if((*p)->endgroup()) error(nobegin);
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else error(nobegin);
+ }
+ }
+ }
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ result->add(*group);
+ }
+ }
+
+ result->shipout(preamble,prefix,format,wait,view);
+}
+
+#line 467 "runpicture.in"
+// void shipout3(string prefix, picture *f, string format=emptystring, real width, real height, real angle, real zoom, triple m, triple M, pair shift, realarray2 *t, realarray *background, triplearray *lights, realarray2 *diffuse, realarray2 *specular, bool view=true);
+void gen_runpicture43(stack *Stack)
+{
+ bool view=vm::pop<bool>(Stack,true);
+ realarray2 * specular=vm::pop<realarray2 *>(Stack);
+ realarray2 * diffuse=vm::pop<realarray2 *>(Stack);
+ triplearray * lights=vm::pop<triplearray *>(Stack);
+ realarray * background=vm::pop<realarray *>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ pair shift=vm::pop<pair>(Stack);
+ triple M=vm::pop<triple>(Stack);
+ triple m=vm::pop<triple>(Stack);
+ real zoom=vm::pop<real>(Stack);
+ real angle=vm::pop<real>(Stack);
+ real height=vm::pop<real>(Stack);
+ real width=vm::pop<real>(Stack);
+ string format=vm::pop<string>(Stack,emptystring);
+ picture * f=vm::pop<picture *>(Stack);
+ string prefix=vm::pop<string>(Stack);
+#line 472 "runpicture.in"
+ size_t n=checkArrays(lights,diffuse);
+ checkEqual(n,checkArray(specular));
+
+ real *T,*Background,*Diffuse,*Specular;
+ triple *Lights;
+
+ copyArray2C(T,t,true,4);
+ copyArrayC(Background,background);
+ copyArrayC(Lights,lights);
+ copyArray2C(Diffuse,diffuse,false,4,UseGC);
+ copyArray2C(Specular,specular,false,4,UseGC);
+
+ f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,T,Background,n,
+ Lights,Diffuse,Specular,view);
+
+ delete[] Background;
+ delete[] T;
+}
+
+#line 492 "runpicture.in"
+// void shipout3(string prefix, picture *f);
+void gen_runpicture44(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+ string prefix=vm::pop<string>(Stack);
+#line 493 "runpicture.in"
+ f->shipout3(prefix);
+}
+
+#line 497 "runpicture.in"
+// void xmap(string key, transform t=identity);
+void gen_runpicture45(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack,identity);
+ string key=vm::pop<string>(Stack);
+#line 498 "runpicture.in"
+ xmap_t &xmap=processData().xmap;
+ xmap_t::iterator p=xmap.find(key);
+ if(p != xmap.end())
+ p->second.push_back(t);
+ else {
+ xtransform_t *v=new xtransform_t();
+ v->push_back(t);
+ xmap[key]=*v;
+ }
+}
+
+#line 510 "runpicture.in"
+// void deconstruct(picture *f, picture *preamble=NULL, transform T=identity);
+void gen_runpicture46(stack *Stack)
+{
+ transform T=vm::pop<transform>(Stack,identity);
+ picture * preamble=vm::pop<picture *>(Stack,NULL);
+ picture * f=vm::pop<picture *>(Stack);
+#line 511 "runpicture.in"
+ unsigned level=0;
+
+ string prefix=outname();
+ const string xformat="svg";
+
+ openpipeout();
+
+ const string Done="Done";
+ const string Error="Error";
+
+ unsigned arg=0;
+ xmap_t xmap=processData().xmap;
+ transform Tinv=inverse(T);
+
+ for(picture::nodelist::iterator p=f->nodes.begin();;) {
+ if(p == f->nodes.end()) break;
+
+ picture *group=new picture;
+ transform t=getTransform(xmap,p);
+ bool Delete=(t == ZeroTransform);
+ if(!Delete && !t.isIdentity()) t=T*t*Tinv;
+
+ assert(*p);
+ if((*p)->endgroup()) {
+ fprintf(pipeout,"%s\n",Error.c_str());
+ fflush(pipeout);
+ error(nobegin);
+ }
+ bool clip=false;
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ if((*p)->endclip()) clip=true;
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else {
+ fprintf(pipeout,"%s\n",Error.c_str());
+ fflush(pipeout);
+ error(nobegin);
+ }
+ }
+ }
+ }
+ if(p != f->nodes.end()) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ if((*p)->endclip()) clip=true;
+ ostringstream buf;
+ buf << prefix << "_" << arg;
+ string outname=buildname(buf.str(),xformat);
+ group->shipout(preamble,outname,xformat,false,false);
+ bbox b=group->bounds();
+ if(!b.empty) {
+ fprintf(pipeout,"KEY=%s%d\n",e->KEY.c_str(),clip);
+
+ const char *oldlocale=setlocale(LC_NUMERIC,NULL);
+ bool override=oldlocale && strcmp(oldlocale,"C") != 0;
+ if(override) {
+ oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_NUMERIC,"C");
+ }
+
+ fprintf(pipeout,"%g %g %g %g\n",b.left,b.bottom,b.right,b.top);
+
+ if(override) {
+ setlocale(LC_NUMERIC,oldlocale);
+ delete[] oldlocale;
+ }
+
+ fflush(pipeout);
+ ++arg;
+ }
+ }
+ ++p;
+ }
+ }
+
+ fprintf(pipeout,"%s\n",Done.c_str());
+ fflush(pipeout);
+}
+
+
+// Three-dimensional picture and surface operations
+
+// Bezier curve
+#line 606 "runpicture.in"
+// void _draw(picture *f, path3 g, triple center=Zero, pen p, Int interaction=0);
+void gen_runpicture47(stack *Stack)
+{
+ Int interaction=vm::pop<Int>(Stack,0);
+ pen p=vm::pop<pen>(Stack);
+ triple center=vm::pop<triple>(Stack,Zero);
+ path3 g=vm::pop<path3>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 607 "runpicture.in"
+ if(g.size() > 0)
+ f->append(new drawPath3(g,center,p,(Interaction) intcast(interaction)));
+}
+
+// Bezier patch
+#line 613 "runpicture.in"
+// void draw(picture *f, triplearray2 *P, triple center, bool straight, penarray *p, real opacity, real shininess, real metallic, real fresnel0, real PRCshininess, penarray *colors, Int interaction, bool prc=true);
+void gen_runpicture48(stack *Stack)
+{
+ bool prc=vm::pop<bool>(Stack,true);
+ Int interaction=vm::pop<Int>(Stack);
+ penarray * colors=vm::pop<penarray *>(Stack);
+ real PRCshininess=vm::pop<real>(Stack);
+ real fresnel0=vm::pop<real>(Stack);
+ real metallic=vm::pop<real>(Stack);
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ bool straight=vm::pop<bool>(Stack);
+ triple center=vm::pop<triple>(Stack);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 616 "runpicture.in"
+ f->append(new drawBezierPatch(*P,center,straight,*p,opacity,shininess,
+ metallic,fresnel0,PRCshininess,*colors,
+ (Interaction) intcast(interaction),prc));
+}
+
+// Bezier triangle
+#line 623 "runpicture.in"
+// void drawbeziertriangle(picture *f, triplearray2 *P, triple center, bool straight, penarray *p, real opacity, real shininess, real metallic, real fresnel0, real PRCshininess, penarray *colors, Int interaction, bool prc=true);
+void gen_runpicture49(stack *Stack)
+{
+ bool prc=vm::pop<bool>(Stack,true);
+ Int interaction=vm::pop<Int>(Stack);
+ penarray * colors=vm::pop<penarray *>(Stack);
+ real PRCshininess=vm::pop<real>(Stack);
+ real fresnel0=vm::pop<real>(Stack);
+ real metallic=vm::pop<real>(Stack);
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ bool straight=vm::pop<bool>(Stack);
+ triple center=vm::pop<triple>(Stack);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 627 "runpicture.in"
+ f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess,
+ metallic,fresnel0,PRCshininess,*colors,
+ (Interaction) intcast(interaction),prc));
+}
+
+// General NURBS curve
+#line 634 "runpicture.in"
+// void draw(picture *f, triplearray *P, realarray *knot, realarray *weights=emptyarray, pen p);
+void gen_runpicture50(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ realarray * weights=vm::pop<realarray *>(Stack,emptyarray);
+ realarray * knot=vm::pop<realarray *>(Stack);
+ triplearray * P=vm::pop<triplearray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 636 "runpicture.in"
+ f->append(new drawNurbsPath3(*P,knot,weights,p));
+}
+
+// General NURBS surface
+#line 641 "runpicture.in"
+// void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot, realarray2 *weights=emptyarray, penarray *p, real opacity, real shininess,real metallic, real fresnel0, real PRCshininess, penarray *colors);
+void gen_runpicture51(stack *Stack)
+{
+ penarray * colors=vm::pop<penarray *>(Stack);
+ real PRCshininess=vm::pop<real>(Stack);
+ real fresnel0=vm::pop<real>(Stack);
+ real metallic=vm::pop<real>(Stack);
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ realarray2 * weights=vm::pop<realarray2 *>(Stack,emptyarray);
+ realarray * vknot=vm::pop<realarray *>(Stack);
+ realarray * uknot=vm::pop<realarray *>(Stack);
+ triplearray2 * P=vm::pop<triplearray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 645 "runpicture.in"
+ f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess, metallic, fresnel0,
+ PRCshininess,*colors));
+}
+
+// PRC unit sphere
+#line 651 "runpicture.in"
+// void drawPRCsphere(picture *f, realarray2 *t, bool half=false, penarray *p, real opacity, real shininess, Int type);
+void gen_runpicture52(stack *Stack)
+{
+ Int type=vm::pop<Int>(Stack);
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ bool half=vm::pop<bool>(Stack,false);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 653 "runpicture.in"
+ f->append(new drawSphere(*t,half,*p,opacity,shininess,intcast(type)));
+}
+
+// PRC unit cylinder
+#line 658 "runpicture.in"
+// void drawPRCcylinder(picture *f, realarray2 *t, penarray *p, real opacity, real shininess);
+void gen_runpicture53(stack *Stack)
+{
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 660 "runpicture.in"
+ f->append(new drawCylinder(*t,*p,opacity,shininess));
+}
+
+// PRC unit disk
+#line 665 "runpicture.in"
+// void drawPRCdisk(picture *f, realarray2 *t, penarray *p, real opacity, real shininess);
+void gen_runpicture54(stack *Stack)
+{
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 667 "runpicture.in"
+ f->append(new drawDisk(*t,*p,opacity,shininess));
+}
+
+// General PRC tube
+#line 672 "runpicture.in"
+// void drawPRCtube(picture *f, path3 center, path3 g, penarray *p, real opacity, real shininess);
+void gen_runpicture55(stack *Stack)
+{
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ path3 g=vm::pop<path3>(Stack);
+ path3 center=vm::pop<path3>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 674 "runpicture.in"
+ f->append(new drawTube(center,g,*p,opacity,shininess));
+}
+
+// Draw pixel
+#line 679 "runpicture.in"
+// void drawpixel(picture *f, triple v, pen p, real width=1.0);
+void gen_runpicture56(stack *Stack)
+{
+ real width=vm::pop<real>(Stack,1.0);
+ pen p=vm::pop<pen>(Stack);
+ triple v=vm::pop<triple>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 680 "runpicture.in"
+ f->append(new drawPixel(v,p,width));
+}
+
+// Draw triangles
+#line 685 "runpicture.in"
+// void draw(picture *f, triplearray *v, Intarray2 *vi, triplearray *n, Intarray2 *ni, penarray *p, real opacity, real shininess, real metallic, real fresnel0, real PRCshininess, penarray *c=emptyarray, Intarray2 *ci=emptyarray);
+void gen_runpicture57(stack *Stack)
+{
+ Intarray2 * ci=vm::pop<Intarray2 *>(Stack,emptyarray);
+ penarray * c=vm::pop<penarray *>(Stack,emptyarray);
+ real PRCshininess=vm::pop<real>(Stack);
+ real fresnel0=vm::pop<real>(Stack);
+ real metallic=vm::pop<real>(Stack);
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ Intarray2 * ni=vm::pop<Intarray2 *>(Stack);
+ triplearray * n=vm::pop<triplearray *>(Stack);
+ Intarray2 * vi=vm::pop<Intarray2 *>(Stack);
+ triplearray * v=vm::pop<triplearray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 690 "runpicture.in"
+ f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,fresnel0,PRCshininess,
+ *c,*ci));
+}
+
+#line 695 "runpicture.in"
+// triple min3(picture *f);
+void gen_runpicture58(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 696 "runpicture.in"
+ {Stack->push<triple>(f->bounds3().Min()); return;}
+}
+
+#line 700 "runpicture.in"
+// triple max3(picture *f);
+void gen_runpicture59(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 701 "runpicture.in"
+ {Stack->push<triple>(f->bounds3().Max()); return;}
+}
+
+#line 705 "runpicture.in"
+// triple size3(picture *f);
+void gen_runpicture60(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 706 "runpicture.in"
+ bbox3 b=f->bounds3();
+ {Stack->push<triple>(b.Max()-b.Min()); return;}
+}
+
+#line 711 "runpicture.in"
+// pair minratio(picture *f);
+void gen_runpicture61(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 712 "runpicture.in"
+ {Stack->push<pair>(f->ratio(::min)); return;}
+}
+
+#line 716 "runpicture.in"
+// pair maxratio(picture *f);
+void gen_runpicture62(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 717 "runpicture.in"
+ {Stack->push<pair>(f->ratio(::max)); return;}
+}
+
+#line 721 "runpicture.in"
+// bool is3D(picture *f);
+void gen_runpicture63(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 722 "runpicture.in"
+ {Stack->push<bool>(f->have3D()); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runpicture_venv(venv &ve)
+{
+#line 126 "runpicture.in"
+ REGISTER_BLTIN(run::newPicture,"newPicture");
+#line 131 "runpicture.in"
+ addFunc(ve, run::gen_runpicture1, primBoolean(), SYM(empty), formal(primPicture(), SYM(f), false, false));
+#line 136 "runpicture.in"
+ addFunc(ve, run::gen_runpicture2, primVoid(), SYM(erase), formal(primPicture(), SYM(f), false, false));
+#line 141 "runpicture.in"
+ addFunc(ve, run::gen_runpicture3, primPair(), SYM(min), formal(primPicture(), SYM(f), false, false));
+#line 146 "runpicture.in"
+ addFunc(ve, run::gen_runpicture4, primPair(), SYM(max), formal(primPicture(), SYM(f), false, false));
+#line 151 "runpicture.in"
+ addFunc(ve, run::gen_runpicture5, primPair(), SYM(size), formal(primPicture(), SYM(f), false, false));
+#line 157 "runpicture.in"
+ addFunc(ve, run::gen_runpicture6, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath(), SYM(g), false, false), formal(primPen(), SYM(p), false, false));
+#line 162 "runpicture.in"
+ addFunc(ve, run::gen_runpicture7, primVoid(), SYM(fill), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primPen(), SYM(p), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 168 "runpicture.in"
+ addFunc(ve, run::gen_runpicture8, primVoid(), SYM(latticeshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray2() , SYM(p), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 177 "runpicture.in"
+ addFunc(ve, run::gen_runpicture9, primVoid(), SYM(axialshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(pena), false, false), formal(primPair(), SYM(a), false, false), formal(primBoolean(), SYM(extenda), true, false), formal(primPen(), SYM(penb), false, false), formal(primPair(), SYM(b), false, false), formal(primBoolean(), SYM(extendb), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 186 "runpicture.in"
+ addFunc(ve, run::gen_runpicture10, primVoid(), SYM(radialshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(pena), false, false), formal(primPair(), SYM(a), false, false), formal(primReal(), SYM(ra), false, false), formal(primBoolean(), SYM(extenda), true, false), formal(primPen(), SYM(penb), false, false), formal(primPair(), SYM(b), false, false), formal(primReal(), SYM(rb), false, false), formal(primBoolean(), SYM(extendb), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 195 "runpicture.in"
+ addFunc(ve, run::gen_runpicture11, primVoid(), SYM(gouraudshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray() , SYM(p), false, false), formal(pairArray(), SYM(z), false, false), formal(IntArray(), SYM(edges), false, false), formal(primBoolean(), SYM(copy), true, false));
+#line 206 "runpicture.in"
+ addFunc(ve, run::gen_runpicture12, primVoid(), SYM(gouraudshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray() , SYM(p), false, false), formal(IntArray(), SYM(edges), false, false), formal(primBoolean(), SYM(copy), true, false));
+#line 230 "runpicture.in"
+ addFunc(ve, run::gen_runpicture13, primVoid(), SYM(tensorshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray2() , SYM(p), false, false), formal(pathArray() , SYM(b), true, false), formal(pairArray2(), SYM(z), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 245 "runpicture.in"
+ addFunc(ve, run::gen_runpicture14, primVoid(), SYM(functionshade), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primString() , SYM(shader), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 253 "runpicture.in"
+ addFunc(ve, run::gen_runpicture15, primVoid(), SYM(clip), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 263 "runpicture.in"
+ addFunc(ve, run::gen_runpicture16, primVoid(), SYM(beginclip), formal(primPicture(), SYM(f), false, false), formal(pathArray() , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primBoolean(), SYM(copy), true, false));
+#line 270 "runpicture.in"
+ addFunc(ve, run::gen_runpicture17, primVoid(), SYM(endclip), formal(primPicture(), SYM(f), false, false));
+#line 275 "runpicture.in"
+ addFunc(ve, run::gen_runpicture18, primVoid(), SYM(gsave), formal(primPicture(), SYM(f), false, false));
+#line 280 "runpicture.in"
+ addFunc(ve, run::gen_runpicture19, primVoid(), SYM(grestore), formal(primPicture(), SYM(f), false, false));
+#line 285 "runpicture.in"
+ addFunc(ve, run::gen_runpicture20, primVoid(), SYM(begingroup), formal(primPicture(), SYM(f), false, false));
+#line 290 "runpicture.in"
+ addFunc(ve, run::gen_runpicture21, primVoid(), SYM(endgroup), formal(primPicture(), SYM(f), false, false));
+#line 295 "runpicture.in"
+ addFunc(ve, run::gen_runpicture22, primVoid(), SYM(_begingroup3), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(name), false, false), formal(primReal(), SYM(compression), false, false), formal(primReal(), SYM(granularity), false, false), formal(primBoolean(), SYM(closed), false, false), formal(primBoolean(), SYM(tessellate), false, false), formal(primBoolean(), SYM(dobreak), false, false), formal(primBoolean(), SYM(nobreak), false, false), formal(primTriple(), SYM(center), false, false), formal(primInt(), SYM(interaction), false, false));
+#line 304 "runpicture.in"
+ addFunc(ve, run::gen_runpicture23, primVoid(), SYM(endgroup3), formal(primPicture(), SYM(f), false, false));
+#line 309 "runpicture.in"
+ addFunc(ve, run::gen_runpicture24, primVoid(), SYM(add), formal(primPicture(), SYM(dest), false, false), formal(primPicture(), SYM(src), false, false));
+#line 314 "runpicture.in"
+ addFunc(ve, run::gen_runpicture25, primVoid(), SYM(prepend), formal(primPicture(), SYM(dest), false, false), formal(primPicture(), SYM(src), false, false));
+#line 319 "runpicture.in"
+ addFunc(ve, run::gen_runpicture26, primVoid(), SYM(postscript), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false));
+#line 324 "runpicture.in"
+ addFunc(ve, run::gen_runpicture27, primVoid(), SYM(tex), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false));
+#line 329 "runpicture.in"
+ addFunc(ve, run::gen_runpicture28, primVoid(), SYM(postscript), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primPair(), SYM(min), false, false), formal(primPair(), SYM(max), false, false));
+#line 334 "runpicture.in"
+ addFunc(ve, run::gen_runpicture29, primVoid(), SYM(tex), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primPair(), SYM(min), false, false), formal(primPair(), SYM(max), false, false));
+#line 339 "runpicture.in"
+ addFunc(ve, run::gen_runpicture30, primVoid(), SYM(texpreamble), formal(primString() , SYM(s), false, false));
+#line 347 "runpicture.in"
+ addFunc(ve, run::gen_runpicture31, primVoid(), SYM(deletepreamble));
+#line 354 "runpicture.in"
+ addFunc(ve, run::gen_runpicture32, primVoid(), SYM(_labelpath), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primString() , SYM(size), false, false), formal(primPath(), SYM(g), false, false), formal(primString() , SYM(justify), false, false), formal(primPair(), SYM(offset), false, false), formal(primPen(), SYM(p), false, false));
+#line 360 "runpicture.in"
+ addFunc(ve, run::gen_runpicture33, primVoid(), SYM(texreset));
+#line 368 "runpicture.in"
+ addFunc(ve, run::gen_runpicture34, primVoid(), SYM(layer), formal(primPicture(), SYM(f), false, false));
+#line 373 "runpicture.in"
+ addFunc(ve, run::gen_runpicture35, primVoid(), SYM(newpage), formal(primPicture(), SYM(f), false, false));
+#line 378 "runpicture.in"
+ addFunc(ve, run::gen_runpicture36, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(data), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(penArray() , SYM(palette), true, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false), formal(primBoolean(), SYM(antialias), true, false));
+#line 388 "runpicture.in"
+ addFunc(ve, run::gen_runpicture37, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(penArray2() , SYM(data), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false), formal(primBoolean(), SYM(antialias), true, false));
+#line 396 "runpicture.in"
+ addFunc(ve, run::gen_runpicture38, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(penFunction(), SYM(f), false, false), formal(primInt(), SYM(width), false, false), formal(primInt(), SYM(height), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(antialias), true, false));
+#line 403 "runpicture.in"
+ addFunc(ve, run::gen_runpicture39, primString() , SYM(nativeformat));
+#line 408 "runpicture.in"
+ addFunc(ve, run::gen_runpicture40, primBoolean(), SYM(latex));
+#line 413 "runpicture.in"
+ addFunc(ve, run::gen_runpicture41, primBoolean(), SYM(pdf));
+#line 418 "runpicture.in"
+ addFunc(ve, run::gen_runpicture42, primVoid(), SYM(_shipout), formal(primString() , SYM(prefix), true, false), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primString() , SYM(format), true, false), formal(primBoolean(), SYM(wait), true, false), formal(primBoolean(), SYM(view), true, false), formal(primTransform(), SYM(t), true, false));
+#line 467 "runpicture.in"
+ addFunc(ve, run::gen_runpicture43, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(format), true, false), formal(primReal(), SYM(width), false, false), formal(primReal(), SYM(height), false, false), formal(primReal(), SYM(angle), false, false), formal(primReal(), SYM(zoom), false, false), formal(primTriple(), SYM(m), false, false), formal(primTriple(), SYM(m), false, false), formal(primPair(), SYM(shift), false, false), formal(realArray2(), SYM(t), false, false), formal(realArray(), SYM(background), false, false), formal(tripleArray(), SYM(lights), false, false), formal(realArray2(), SYM(diffuse), false, false), formal(realArray2(), SYM(specular), false, false), formal(primBoolean(), SYM(view), true, false));
+#line 492 "runpicture.in"
+ addFunc(ve, run::gen_runpicture44, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false));
+#line 497 "runpicture.in"
+ addFunc(ve, run::gen_runpicture45, primVoid(), SYM(xmap), formal(primString() , SYM(key), false, false), formal(primTransform(), SYM(t), true, false));
+#line 510 "runpicture.in"
+ addFunc(ve, run::gen_runpicture46, primVoid(), SYM(deconstruct), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primTransform(), SYM(t), true, false));
+#line 602 "runpicture.in"
+ addFunc(ve, run::gen_runpicture47, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(g), false, false), formal(primTriple(), SYM(center), true, false), formal(primPen(), SYM(p), false, false), formal(primInt(), SYM(interaction), true, false));
+#line 612 "runpicture.in"
+ addFunc(ve, run::gen_runpicture48, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(prc), true, false));
+#line 622 "runpicture.in"
+ addFunc(ve, run::gen_runpicture49, primVoid(), SYM(drawbeziertriangle), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(prc), true, false));
+#line 633 "runpicture.in"
+ addFunc(ve, run::gen_runpicture50, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(p), false, false), formal(realArray(), SYM(knot), false, false), formal(realArray(), SYM(weights), true, false), formal(primPen(), SYM(p), false, false));
+#line 640 "runpicture.in"
+ addFunc(ve, run::gen_runpicture51, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(realArray(), SYM(uknot), false, false), formal(realArray(), SYM(vknot), false, false), formal(realArray2(), SYM(weights), true, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(colors), false, false));
+#line 650 "runpicture.in"
+ addFunc(ve, run::gen_runpicture52, primVoid(), SYM(drawPRCsphere), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(primBoolean(), SYM(half), true, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primInt(), SYM(type), false, false));
+#line 657 "runpicture.in"
+ addFunc(ve, run::gen_runpicture53, primVoid(), SYM(drawPRCcylinder), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
+#line 664 "runpicture.in"
+ addFunc(ve, run::gen_runpicture54, primVoid(), SYM(drawPRCdisk), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
+#line 671 "runpicture.in"
+ addFunc(ve, run::gen_runpicture55, primVoid(), SYM(drawPRCtube), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(center), false, false), formal(primPath3(), SYM(g), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
+#line 678 "runpicture.in"
+ addFunc(ve, run::gen_runpicture56, primVoid(), SYM(drawpixel), formal(primPicture(), SYM(f), false, false), formal(primTriple(), SYM(v), false, false), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(width), true, false));
+#line 684 "runpicture.in"
+ addFunc(ve, run::gen_runpicture57, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(v), false, false), formal(IntArray2(), SYM(vi), false, false), formal(tripleArray(), SYM(n), false, false), formal(IntArray2(), SYM(ni), false, false), formal(penArray() , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray() , SYM(c), true, false), formal(IntArray2(), SYM(ci), true, false));
+#line 695 "runpicture.in"
+ addFunc(ve, run::gen_runpicture58, primTriple(), SYM(min3), formal(primPicture(), SYM(f), false, false));
+#line 700 "runpicture.in"
+ addFunc(ve, run::gen_runpicture59, primTriple(), SYM(max3), formal(primPicture(), SYM(f), false, false));
+#line 705 "runpicture.in"
+ addFunc(ve, run::gen_runpicture60, primTriple(), SYM(size3), formal(primPicture(), SYM(f), false, false));
+#line 711 "runpicture.in"
+ addFunc(ve, run::gen_runpicture61, primPair(), SYM(minratio), formal(primPicture(), SYM(f), false, false));
+#line 716 "runpicture.in"
+ addFunc(ve, run::gen_runpicture62, primPair(), SYM(maxratio), formal(primPicture(), SYM(f), false, false));
+#line 721 "runpicture.in"
+ addFunc(ve, run::gen_runpicture63, primBoolean(), SYM(is3D), formal(primPicture(), SYM(f), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runpicture.h b/graphics/asymptote/runpicture.h
new file mode 100644
index 0000000000..db7db84248
--- /dev/null
+++ b/graphics/asymptote/runpicture.h
@@ -0,0 +1,9 @@
+/***** Autogenerated from runpicture.in; changes will be overwritten *****/
+
+#ifndef runpicture_H
+#define runpicture_H
+namespace run {
+void newPicture(vm::stack *);
+}
+
+#endif // runpicture_H
diff --git a/graphics/asymptote/runpicture.in b/graphics/asymptote/runpicture.in
new file mode 100644
index 0000000000..f6c0d75c07
--- /dev/null
+++ b/graphics/asymptote/runpicture.in
@@ -0,0 +1,724 @@
+/*****
+ * runpicture.in
+ *
+ * Runtime functions for picture operations.
+ *
+ *****/
+
+pen => primPen()
+pair => primPair()
+triple => primTriple()
+path => primPath()
+path3 => primPath3()
+picture* => primPicture()
+Intarray* => IntArray()
+Intarray2* => IntArray2()
+realarray* => realArray()
+realarray2* => realArray2()
+patharray* => pathArray()
+penarray* => penArray()
+penarray2* => penArray2()
+pairarray* => pairArray()
+pairarray2* => pairArray2()
+triplearray* => tripleArray()
+triplearray2* => tripleArray2()
+transform => primTransform()
+callableTransform* => transformFunction()
+callablePen* => penFunction()
+
+#include "picture.h"
+#include "drawelement.h"
+#include "path.h"
+#include "array.h"
+#include "arrayop.h"
+#include "drawpath.h"
+#include "drawfill.h"
+#include "drawclipbegin.h"
+#include "drawclipend.h"
+#include "drawgsave.h"
+#include "drawgrestore.h"
+#include "drawgroup.h"
+#include "drawverbatim.h"
+#include "drawlabel.h"
+#include "drawlayer.h"
+#include "drawimage.h"
+#include "drawpath3.h"
+#include "drawsurface.h"
+
+using namespace camp;
+using namespace settings;
+using namespace vm;
+
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray;
+typedef array triplearray2;
+typedef array patharray;
+typedef array penarray;
+typedef array penarray2;
+
+typedef callable callableTransform;
+typedef callable callablePen;
+
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray;
+using types::tripleArray2;
+using types::pathArray;
+using types::penArray;
+using types::penArray2;
+
+static transform ZeroTransform=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+
+transform getTransform(xmap_t &xmap, picture::nodelist::iterator p)
+{
+ string s=(*p)->KEY;
+ transform t;
+ // Don't apply xmap without an explicit corresponding key
+ size_t n=s.length();
+ if(n == 0 || s.substr(n-1) != "1") return t;
+
+ xmap_t::iterator q=xmap.find(s.substr(0,n-2));
+ if(q != xmap.end()) {
+ xtransform_t& v=q->second;
+ if(!v.empty()) {
+ t=v.front();
+ v.pop_front();
+ }
+ }
+ return t;
+}
+
+
+function *transformFunction()
+{
+ return new function(primTransform());
+}
+
+function *penFunction()
+{
+ return new function(primPen(),primInt(),primInt());
+}
+
+// Ignore unclosed begingroups but not spurious endgroups.
+const char *nobegin="endgroup without matching begingroup";
+
+array *emptyarray=new array(0);
+
+array *nop(array *a)
+{
+ return a;
+}
+
+triple Zero;
+
+// Autogenerated routines:
+
+
+picture* :newPicture()
+{
+ return new picture();
+}
+
+bool empty(picture *f)
+{
+ return f->null();
+}
+
+void erase(picture *f)
+{
+ f->nodes.clear();
+}
+
+pair min(picture *f)
+{
+ return f->bounds().Min();
+}
+
+pair max(picture *f)
+{
+ return f->bounds().Max();
+}
+
+pair size(picture *f)
+{
+ bbox b=f->bounds();
+ return b.Max()-b.Min();
+}
+
+void _draw(picture *f, path g, pen p)
+{
+ f->append(new drawPath(g,p));
+}
+
+void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawFill(*copyarray(g),false,p));
+}
+
+void latticeshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray2 *p, transform t=identity,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ t));
+}
+
+void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a,
+ bool extenda=true, pen penb, pair b, bool extendb=true,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,extenda,penb,b,
+ extendb));
+}
+
+void radialshade(picture *f, patharray *g, bool stroke=false, pen pena,
+ pair a, real ra, bool extenda=true, pen penb, pair b, real rb,
+ bool extendb=true, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,extenda,
+ penb,b,rb,extendb));
+}
+
+void gouraudshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray *p, pairarray *z,
+ Intarray *edges, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ checkArrays(p,z);
+ checkArrays(z,edges);
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *copyarray(z),*copyarray(edges)));
+}
+
+void gouraudshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray *p, Intarray *edges,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ size_t n=checkArrays(p,edges);
+ size_t m=checkArray(g);
+ array *z=new array(n);
+ Int k=0;
+ Int in=(Int) n;
+ for(size_t j=0; j < m; ++j) {
+ path *P=read<path *>(g,j);
+ assert(P);
+ Int stop=Min(P->size(),in-k);
+ mem::vector<solvedKnot>& nodes=P->Nodes();
+ for(Int i=0; i < stop; ++i)
+ (*z)[k++]=nodes[i].point;
+ }
+ checkArrays(p,z);
+
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *z,*copyarray(edges)));
+}
+
+void tensorshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL,
+ pairarray2 *z=emptyarray, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
+ if(b == NULL) b=g;
+ size_t n=checkArrays(p,b);
+ size_t nz=checkArray(z);
+ if(nz != 0)
+ checkEqual(nz,n);
+ f->append(new drawTensorShade(*copyarray(g),stroke,fillrule,*copyarray2(p),
+ *copyarray(b),*copyarray2(z)));
+}
+
+void functionshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, string shader=emptystring,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
+}
+
+// Clip a picture to a superpath using the given fill rule.
+// Subsequent additions to the picture will not be affected by the clipping.
+void clip(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
+ f->enclose(begin,new drawClipEnd(true,begin));
+}
+
+void beginclip(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
+}
+
+void endclip(picture *f)
+{
+ f->append(new drawClipEnd(false));
+}
+
+void gsave(picture *f)
+{
+ f->append(new drawGsave());
+}
+
+void grestore(picture *f)
+{
+ f->append(new drawGrestore());
+}
+
+void begingroup(picture *f)
+{
+ f->append(new drawBegin());
+}
+
+void endgroup(picture *f)
+{
+ f->append(new drawEnd());
+}
+
+void _begingroup3(picture *f, string name, real compression,
+ real granularity, bool closed, bool tessellate,
+ bool dobreak, bool nobreak, triple center, Int interaction)
+{
+ f->append(new drawBegin3(name,compression,granularity,
+ closed,tessellate,dobreak,nobreak,
+ center,(Interaction) intcast(interaction)));
+}
+
+void endgroup3(picture *f)
+{
+ f->append(new drawEnd3());
+}
+
+void add(picture *dest, picture *src)
+{
+ dest->add(*src);
+}
+
+void prepend(picture *dest, picture *src)
+{
+ dest->prepend(*src);
+}
+
+void postscript(picture *f, string s)
+{
+ f->append(new drawVerbatim(PostScript,s));
+}
+
+void tex(picture *f, string s)
+{
+ f->append(new drawVerbatim(TeX,s));
+}
+
+void postscript(picture *f, string s, pair min, pair max)
+{
+ f->append(new drawVerbatim(PostScript,s,min,max));
+}
+
+void tex(picture *f, string s, pair min, pair max)
+{
+ f->append(new drawVerbatim(TeX,s,min,max));
+}
+
+void texpreamble(string s)
+{
+ string t=s+"\n";
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.push_back(t);
+ pd.TeXpreamble.push_back(t);
+}
+
+void deletepreamble()
+{
+ if(getSetting<bool>("inlinetex")) {
+ unlink(buildname(outname(),"pre").c_str());
+ }
+}
+
+void _labelpath(picture *f, string s, string size, path g, string justify,
+ pair offset, pen p)
+{
+ f->append(new drawLabelPath(s,size,g,justify,offset,p));
+}
+
+void texreset()
+{
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.clear();
+ pd.TeXpreamble.clear();
+ pd.tex.pipeclose();
+}
+
+void layer(picture *f)
+{
+ f->append(new drawLayer());
+}
+
+void newpage(picture *f)
+{
+ f->append(new drawNewPage());
+}
+
+void _image(picture *f, realarray2 *data, pair initial, pair final,
+ penarray *palette=NULL, transform t=identity, bool copy=true,
+ bool antialias=false)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
+ f->append(new drawPaletteImage(*copyarray2(data),*copyarray(palette),
+ t*matrix(initial,final),antialias));
+}
+
+void _image(picture *f, penarray2 *data, pair initial, pair final,
+ transform t=identity, bool copy=true, bool antialias=false)
+{
+ array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
+ f->append(new drawNoPaletteImage(*copyarray2(data),t*matrix(initial,final),
+ antialias));
+}
+
+void _image(picture *f, callablePen *F, Int width, Int height,
+ pair initial, pair final, transform t=identity, bool antialias=false)
+{
+ f->append(new drawFunctionImage(Stack,F,width,height,
+ t*matrix(initial,final),antialias));
+}
+
+string nativeformat()
+{
+ return nativeformat();
+}
+
+bool latex()
+{
+ return latex(getSetting<string>("tex"));
+}
+
+bool pdf()
+{
+ return pdf(getSetting<string>("tex"));
+}
+
+void _shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,
+ string format=emptystring, bool wait=false, bool view=true,
+ transform T=identity)
+{
+ if(prefix.empty()) prefix=outname();
+
+ picture *result=new picture;
+ unsigned level=0;
+ picture::nodelist::iterator p;
+
+ xmap_t xmap=processData().xmap;
+ transform Tinv=inverse(T);
+
+ for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ transform t=getTransform(xmap,p);
+ bool Delete=(t == ZeroTransform);
+ if(!Delete && !t.isIdentity()) t=T*t*Tinv;
+ picture *group=new picture;
+ assert(*p);
+ if((*p)->endgroup()) error(nobegin);
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else error(nobegin);
+ }
+ }
+ }
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ result->add(*group);
+ }
+ }
+
+ result->shipout(preamble,prefix,format,wait,view);
+}
+
+void shipout3(string prefix, picture *f, string format=emptystring,
+ real width, real height, real angle, real zoom,
+ triple m, triple M, pair shift, realarray2 *t,
+ realarray *background, triplearray *lights, realarray2 *diffuse,
+ realarray2 *specular, bool view=true)
+{
+ size_t n=checkArrays(lights,diffuse);
+ checkEqual(n,checkArray(specular));
+
+ real *T,*Background,*Diffuse,*Specular;
+ triple *Lights;
+
+ copyArray2C(T,t,true,4);
+ copyArrayC(Background,background);
+ copyArrayC(Lights,lights);
+ copyArray2C(Diffuse,diffuse,false,4,UseGC);
+ copyArray2C(Specular,specular,false,4,UseGC);
+
+ f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,T,Background,n,
+ Lights,Diffuse,Specular,view);
+
+ delete[] Background;
+ delete[] T;
+}
+
+void shipout3(string prefix, picture *f)
+{
+ f->shipout3(prefix);
+}
+
+void xmap(string key, transform t=identity)
+{
+ xmap_t &xmap=processData().xmap;
+ xmap_t::iterator p=xmap.find(key);
+ if(p != xmap.end())
+ p->second.push_back(t);
+ else {
+ xtransform_t *v=new xtransform_t();
+ v->push_back(t);
+ xmap[key]=*v;
+ }
+}
+
+void deconstruct(picture *f, picture *preamble=NULL, transform T=identity)
+{
+ unsigned level=0;
+
+ string prefix=outname();
+ const string xformat="svg";
+
+ openpipeout();
+
+ const string Done="Done";
+ const string Error="Error";
+
+ unsigned arg=0;
+ xmap_t xmap=processData().xmap;
+ transform Tinv=inverse(T);
+
+ for(picture::nodelist::iterator p=f->nodes.begin();;) {
+ if(p == f->nodes.end()) break;
+
+ picture *group=new picture;
+ transform t=getTransform(xmap,p);
+ bool Delete=(t == ZeroTransform);
+ if(!Delete && !t.isIdentity()) t=T*t*Tinv;
+
+ assert(*p);
+ if((*p)->endgroup()) {
+ fprintf(pipeout,"%s\n",Error.c_str());
+ fflush(pipeout);
+ error(nobegin);
+ }
+ bool clip=false;
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ if((*p)->endclip()) clip=true;
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else {
+ fprintf(pipeout,"%s\n",Error.c_str());
+ fflush(pipeout);
+ error(nobegin);
+ }
+ }
+ }
+ }
+ if(p != f->nodes.end()) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ if((*p)->endclip()) clip=true;
+ ostringstream buf;
+ buf << prefix << "_" << arg;
+ string outname=buildname(buf.str(),xformat);
+ group->shipout(preamble,outname,xformat,false,false);
+ bbox b=group->bounds();
+ if(!b.empty) {
+ fprintf(pipeout,"KEY=%s%d\n",e->KEY.c_str(),clip);
+
+ const char *oldlocale=setlocale(LC_NUMERIC,NULL);
+ bool override=oldlocale && strcmp(oldlocale,"C") != 0;
+ if(override) {
+ oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_NUMERIC,"C");
+ }
+
+ fprintf(pipeout,"%g %g %g %g\n",b.left,b.bottom,b.right,b.top);
+
+ if(override) {
+ setlocale(LC_NUMERIC,oldlocale);
+ delete[] oldlocale;
+ }
+
+ fflush(pipeout);
+ ++arg;
+ }
+ }
+ ++p;
+ }
+ }
+
+ fprintf(pipeout,"%s\n",Done.c_str());
+ fflush(pipeout);
+}
+
+
+// Three-dimensional picture and surface operations
+
+// Bezier curve
+void _draw(picture *f, path3 g, triple center=Zero, pen p, Int interaction=0)
+{
+ if(g.size() > 0)
+ f->append(new drawPath3(g,center,p,(Interaction) intcast(interaction)));
+}
+
+// Bezier patch
+void draw(picture *f, triplearray2 *P, triple center, bool straight,
+ penarray *p, real opacity, real shininess, real metallic, real fresnel0,
+ real PRCshininess, penarray *colors, Int interaction, bool prc=true)
+{
+ f->append(new drawBezierPatch(*P,center,straight,*p,opacity,shininess,
+ metallic,fresnel0,PRCshininess,*colors,
+ (Interaction) intcast(interaction),prc));
+}
+
+// Bezier triangle
+void drawbeziertriangle(picture *f, triplearray2 *P, triple center,
+ bool straight, penarray *p, real opacity,
+ real shininess, real metallic, real fresnel0, real PRCshininess,
+ penarray *colors, Int interaction, bool prc=true)
+{
+ f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess,
+ metallic,fresnel0,PRCshininess,*colors,
+ (Interaction) intcast(interaction),prc));
+}
+
+// General NURBS curve
+void draw(picture *f, triplearray *P, realarray *knot,
+ realarray *weights=emptyarray, pen p)
+{
+ f->append(new drawNurbsPath3(*P,knot,weights,p));
+}
+
+// General NURBS surface
+void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot,
+ realarray2 *weights=emptyarray, penarray *p, real opacity,
+ real shininess,real metallic, real fresnel0,
+ real PRCshininess, penarray *colors)
+{
+ f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess, metallic, fresnel0,
+ PRCshininess,*colors));
+}
+
+// PRC unit sphere
+void drawPRCsphere(picture *f, realarray2 *t, bool half=false, penarray *p,
+ real opacity, real shininess, Int type)
+{
+ f->append(new drawSphere(*t,half,*p,opacity,shininess,intcast(type)));
+}
+
+// PRC unit cylinder
+void drawPRCcylinder(picture *f, realarray2 *t, penarray *p, real opacity,
+ real shininess)
+{
+ f->append(new drawCylinder(*t,*p,opacity,shininess));
+}
+
+// PRC unit disk
+void drawPRCdisk(picture *f, realarray2 *t, penarray *p, real opacity,
+ real shininess)
+{
+ f->append(new drawDisk(*t,*p,opacity,shininess));
+}
+
+// General PRC tube
+void drawPRCtube(picture *f, path3 center, path3 g, penarray *p, real opacity,
+ real shininess)
+{
+ f->append(new drawTube(center,g,*p,opacity,shininess));
+}
+
+// Draw pixel
+void drawpixel(picture *f, triple v, pen p, real width=1.0)
+{
+ f->append(new drawPixel(v,p,width));
+}
+
+// Draw triangles
+void draw(picture *f, triplearray *v, Intarray2 *vi,
+ triplearray *n, Intarray2 *ni,
+ penarray *p, real opacity, real shininess,
+ real metallic, real fresnel0, real PRCshininess,
+ penarray *c=emptyarray, Intarray2 *ci=emptyarray)
+{
+ f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,fresnel0,PRCshininess,
+ *c,*ci));
+}
+
+triple min3(picture *f)
+{
+ return f->bounds3().Min();
+}
+
+triple max3(picture *f)
+{
+ return f->bounds3().Max();
+}
+
+triple size3(picture *f)
+{
+ bbox3 b=f->bounds3();
+ return b.Max()-b.Min();
+}
+
+pair minratio(picture *f)
+{
+ return f->ratio(::min);
+}
+
+pair maxratio(picture *f)
+{
+ return f->ratio(::max);
+}
+
+bool is3D(picture *f)
+{
+ return f->have3D();
+}
diff --git a/graphics/asymptote/runstring.cc b/graphics/asymptote/runstring.cc
new file mode 100644
index 0000000000..89c151026a
--- /dev/null
+++ b/graphics/asymptote/runstring.cc
@@ -0,0 +1,660 @@
+/***** Autogenerated from runstring.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runstring.in"
+/*****
+ * runstring.in
+ *
+ * Runtime functions for string operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 10 "runstring.in"
+#include <cfloat>
+#include <cstring>
+#include <algorithm>
+
+#include "array.h"
+
+using namespace camp;
+using namespace vm;
+using namespace settings;
+
+typedef array stringarray;
+typedef array stringarray2;
+
+using types::stringArray;
+using types::stringArray2;
+
+namespace types {
+extern const char *names[];
+}
+
+namespace run {
+extern string emptystring;
+}
+
+static const string defaulttimeformat=string("%a %b %d %T %Z %Y");
+#ifdef HAVE_STRFTIME
+static const size_t nTime=256;
+static char Time[nTime];
+#endif
+
+void checkformat(const char *ptr, bool intformat)
+{
+ while(*ptr != '\0') {
+ if(*ptr != '%') /* While we have regular characters, print them. */
+ ptr++;
+ else { /* We've got a format specifier. */
+ ptr++;
+
+ while(*ptr && strchr ("-+ #0'I", *ptr)) /* Move past flags. */
+ ptr++;
+
+ if(*ptr == '*')
+ ptr++;
+ else while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ ptr++;
+
+ if(*ptr == '.') {
+ ptr++; /* Go past the period. */
+ if(*ptr == '*') {
+ ptr++;
+ } else
+ while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ ptr++;
+ }
+ while(*ptr && strchr ("hlL", *ptr))
+ ptr++;
+
+ if(*ptr == '%') {++ptr; continue;}
+ else if(*ptr != '\0') {
+ if(intformat) {
+ switch(*ptr) {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_Int];
+ error(buf);
+ break;
+ }
+ } else {
+ switch(*ptr) {
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_real];
+ error(buf);
+ break;
+ }
+ }
+ }
+ break; // Only one argument is allowed.
+ } /* End of else statement */
+ }
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runstring.symbols.h"
+
+#endif
+namespace run {
+// String operations
+#line 113 "runstring.in"
+void emptyString(stack *Stack)
+{
+#line 114 "runstring.in"
+ {Stack->push<string>(emptystring); return;}
+}
+
+#line 119 "runstring.in"
+// Int length(string *s);
+void gen_runstring1(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 120 "runstring.in"
+ {Stack->push<Int>((Int) s->length()); return;}
+}
+
+#line 124 "runstring.in"
+// Int find(string *s, string t, Int pos=0);
+void gen_runstring2(stack *Stack)
+{
+ Int pos=vm::pop<Int>(Stack,0);
+ string t=vm::pop<string>(Stack);
+ string * s=vm::pop<string *>(Stack);
+#line 125 "runstring.in"
+ size_t n=s->find(t,pos);
+ {Stack->push<Int>(n == string::npos ? (Int) -1 : (Int) n); return;}
+}
+
+#line 130 "runstring.in"
+// Int rfind(string *s, string t, Int pos=-1);
+void gen_runstring3(stack *Stack)
+{
+ Int pos=vm::pop<Int>(Stack,-1);
+ string t=vm::pop<string>(Stack);
+ string * s=vm::pop<string *>(Stack);
+#line 131 "runstring.in"
+ size_t n=s->rfind(t,pos);
+ {Stack->push<Int>(n == string::npos ? (Int) -1 : (Int) n); return;}
+}
+
+#line 136 "runstring.in"
+// string reverse(string s);
+void gen_runstring4(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 137 "runstring.in"
+ reverse(s.begin(),s.end());
+ {Stack->push<string>(s); return;}
+}
+
+#line 142 "runstring.in"
+// string insert(string s, Int pos, string t);
+void gen_runstring5(stack *Stack)
+{
+ string t=vm::pop<string>(Stack);
+ Int pos=vm::pop<Int>(Stack);
+ string s=vm::pop<string>(Stack);
+#line 143 "runstring.in"
+ if ((size_t) pos < s.length())
+ {Stack->push<string>(s.insert(pos,t)); return;}
+ {Stack->push<string>(s); return;}
+}
+
+#line 149 "runstring.in"
+// string substr(string* s, Int pos, Int n=-1);
+void gen_runstring6(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,-1);
+ Int pos=vm::pop<Int>(Stack);
+ string* s=vm::pop<string*>(Stack);
+#line 150 "runstring.in"
+ if ((size_t) pos < s->length())
+ {Stack->push<string>(s->substr(pos,n)); return;}
+ {Stack->push<string>(emptystring); return;}
+}
+
+#line 156 "runstring.in"
+// string erase(string s, Int pos, Int n);
+void gen_runstring7(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ Int pos=vm::pop<Int>(Stack);
+ string s=vm::pop<string>(Stack);
+#line 157 "runstring.in"
+ if ((size_t) pos < s.length())
+ {Stack->push<string>(s.erase(pos,n)); return;}
+ {Stack->push<string>(s); return;}
+}
+
+#line 163 "runstring.in"
+// string downcase(string s);
+void gen_runstring8(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 164 "runstring.in"
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ {Stack->push<string>(s); return;}
+}
+
+#line 169 "runstring.in"
+// string upcase(string s);
+void gen_runstring9(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 170 "runstring.in"
+ std::transform(s.begin(),s.end(),s.begin(),toupper);
+ {Stack->push<string>(s); return;}
+}
+
+// returns a string constructed by translating all occurrences of the string
+// from in an array of string pairs {from,to} to the string to in string s.
+#line 177 "runstring.in"
+// string replace(string *S, stringarray2 *translate);
+void gen_runstring10(stack *Stack)
+{
+ stringarray2 * translate=vm::pop<stringarray2 *>(Stack);
+ string * S=vm::pop<string *>(Stack);
+#line 178 "runstring.in"
+ size_t size=checkArray(translate);
+ for(size_t i=0; i < size; i++) {
+ array *a=read<array*>(translate,i);
+ checkArray(a);
+ }
+ const char *p=S->c_str();
+ ostringstream buf;
+ while(*p) {
+ for(size_t i=0; i < size;) {
+ array *a=read<array*>(translate,i);
+ size_t size2=checkArray(a);
+ if(size2 != 2)
+ error("translation table entry must be an array of length 2");
+ string* from=read<string*>(a,0);
+ size_t len=from->length();
+ if(strncmp(p,from->c_str(),len) != 0) {i++; continue;}
+ buf << read<string>(a,1);
+ p += len;
+ if(*p == 0) {Stack->push<string>(buf.str()); return;}
+ i=0;
+ }
+ buf << *(p++);
+ }
+ {Stack->push<string>(buf.str()); return;}
+}
+
+#line 205 "runstring.in"
+// string format(string *format, Int x, string locale=emptystring);
+void gen_runstring11(stack *Stack)
+{
+ string locale=vm::pop<string>(Stack,emptystring);
+ Int x=vm::pop<Int>(Stack);
+ string * format=vm::pop<string *>(Stack);
+#line 206 "runstring.in"
+ ostringstream out;
+ const char *p0=format->c_str();
+ checkformat(p0,true);
+
+ const char *p=p0;
+ const char *start=NULL;
+ while(*p != 0) {
+ char curr=*p;
+ if(curr == '%') {
+ p++;
+ if(*p != '%') {start=p-1; break;}
+ }
+ out << *(p++);
+ }
+
+ if(!start) {Stack->push<string>(out.str()); return;}
+
+ // Allow at most 1 argument
+ while(*p != 0) {
+ if(*p == '*' || *p == '$') {Stack->push<string>(out.str()); return;}
+ if(isupper(*p) || islower(*p)) {p++; break;}
+ p++;
+ }
+
+ string f=format->substr(start-p0,p-start);
+
+ const char *oldlocale=NULL;
+
+ if(!locale.empty()) {
+ oldlocale=setlocale(LC_ALL,NULL);
+ if(oldlocale) oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_ALL,locale.c_str());
+ }
+
+ Int size=snprintf(NULL,0,f.c_str(),x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f.c_str(),x);
+
+ out << string(buf);
+ out << p;
+
+ delete[] buf;
+
+ if(oldlocale) {
+ setlocale(LC_ALL,oldlocale);
+ delete[] oldlocale;
+ }
+
+ {Stack->push<string>(out.str()); return;}
+}
+
+#line 259 "runstring.in"
+// string format(string *format, bool forcemath=false, string separator, real x, string locale=emptystring);
+void gen_runstring12(stack *Stack)
+{
+ string locale=vm::pop<string>(Stack,emptystring);
+ real x=vm::pop<real>(Stack);
+ string separator=vm::pop<string>(Stack);
+ bool forcemath=vm::pop<bool>(Stack,false);
+ string * format=vm::pop<string *>(Stack);
+#line 261 "runstring.in"
+ if(*format == "%") {Stack->push<string>(""); return;} // Temporary workaround for github Issue #29.
+
+ bool tex=getSetting<string>("tex") != "none";
+ bool texify=forcemath;
+ ostringstream out;
+
+ const char *p0=format->c_str();
+ checkformat(p0,false);
+
+ const char *phantom="\\phantom{+}";
+
+ const char *p=p0;
+ const char *start=NULL;
+ char prev=0;
+ while(*p != 0) {
+ char curr=*p;
+ if(tex && curr == '$' && prev != '\\') texify=true;
+ prev=curr;
+ if(curr == '%') {
+ p++;
+ if(*p != '%') {start=p-1; break;}
+ }
+ out << *(p++);
+ }
+
+ if(!start) {Stack->push<string>(out.str()); return;}
+
+ // Allow at most 1 argument
+ while(*p != 0) {
+ if(*p == '*' || *p == '$') {Stack->push<string>(out.str()); return;}
+ if(isupper(*p) || islower(*p)) {p++; break;}
+ p++;
+ }
+
+ const char *tail=p;
+ string f=format->substr(start-p0,tail-start);
+
+ const char *oldlocale=NULL;
+ if(!locale.empty()) {
+ oldlocale=setlocale(LC_ALL,NULL);
+ if(oldlocale) oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_ALL,locale.c_str());
+ }
+
+ Int size=snprintf(NULL,0,f.c_str(),x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f.c_str(),x);
+
+ bool trailingzero=f.find("#") < string::npos;
+ bool plus=f.find("+") < string::npos;
+ bool space=f.find(" ") < string::npos;
+
+ char *q=buf; // beginning of formatted number
+
+ if(*q == ' ' && texify) {
+ out << phantom;
+ q++;
+ }
+
+ const char decimal=*(localeconv()->decimal_point);
+
+ // Remove any spurious sign
+ if(*q == '-' || *q == '+') {
+ p=q+1;
+ bool zero=true;
+ while(*p != 0) {
+ if(!isdigit(*p) && *p != decimal) break;
+ if(isdigit(*p) && *p != '0') {zero=false; break;}
+ p++;
+ }
+ if(zero) {
+ q++;
+ if((plus || space) && texify) out << phantom;
+ }
+ }
+
+ const char *r=p=q;
+ bool dp=false;
+ while(*r != 0 && (isspace(*r) || isdigit(*r) || *r == decimal \
+ || *r == '+' || *r == '-')) {
+ if(*r == decimal) dp=true;
+ r++;
+ }
+ if(dp) { // Remove trailing zeros and/or decimal point
+ r--;
+ unsigned n=0;
+ while(r > q && *r == '0') {r--; n++;}
+ if(*r == decimal) {r--; n++;}
+ while(q <= r) out << *(q++);
+ if(!trailingzero) q += n;
+ }
+
+ bool zero=(r == p && *r == '0') && !trailingzero;
+
+ // Translate "E+/E-/e+/e-" exponential notation to TeX
+ while(*q != 0) {
+ if(texify && (*q == 'E' || *q == 'e') &&
+ (*(q+1) == '+' || *(q+1) == '-')) {
+ if(!zero) out << separator << "10^{";
+ bool plus=(*(q+1) == '+');
+ q++;
+ if(plus) q++;
+ if(*q == '-') out << *(q++);
+ while(*q == '0' && (zero || isdigit(*(q+1)))) q++;
+ while(isdigit(*q)) out << *(q++);
+ if(!zero)
+ out << "}";
+ break;
+ }
+ out << *(q++);
+ }
+
+ while(*tail != 0)
+ out << *(tail++);
+
+ delete[] buf;
+
+ if(oldlocale) {
+ setlocale(LC_ALL,oldlocale);
+ delete[] oldlocale;
+ }
+
+ {Stack->push<string>(out.str()); return;}
+}
+
+#line 388 "runstring.in"
+// Int hex(string s);
+void gen_runstring13(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 389 "runstring.in"
+ istringstream is(s);
+ is.setf(std::ios::hex,std::ios::basefield);
+ Int value;
+ if(is && is >> value && ((is >> std::ws).eof())) {Stack->push<Int>(value); return;}
+ ostringstream buf;
+ buf << "invalid hexadecimal cast from string \"" << s << "\"";
+ error(buf);
+}
+
+#line 399 "runstring.in"
+// Int ascii(string s);
+void gen_runstring14(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 400 "runstring.in"
+ {Stack->push<Int>(s.empty() ? -1 : (unsigned char) s[0]); return;}
+}
+
+#line 404 "runstring.in"
+// string string(Int x);
+void gen_runstring15(stack *Stack)
+{
+ Int x=vm::pop<Int>(Stack);
+#line 405 "runstring.in"
+ ostringstream buf;
+ buf << x;
+ {Stack->push<string>(buf.str()); return;}
+}
+
+#line 411 "runstring.in"
+// string string(real x, Int digits=DBL_DIG);
+void gen_runstring16(stack *Stack)
+{
+ Int digits=vm::pop<Int>(Stack,DBL_DIG);
+ real x=vm::pop<real>(Stack);
+#line 412 "runstring.in"
+ ostringstream buf;
+ buf.precision(digits);
+ buf << x;
+ {Stack->push<string>(buf.str()); return;}
+}
+
+#line 419 "runstring.in"
+// string time(string format=defaulttimeformat);
+void gen_runstring17(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,defaulttimeformat);
+#line 420 "runstring.in"
+#ifdef HAVE_STRFTIME
+ const time_t bintime=time(NULL);
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push<string>(""); return;}
+ {Stack->push<string>(Time); return;}
+#else
+ {Stack->push<string>(format); return;}
+#endif
+}
+
+#line 430 "runstring.in"
+// string time(Int seconds, string format=defaulttimeformat);
+void gen_runstring18(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,defaulttimeformat);
+ Int seconds=vm::pop<Int>(Stack);
+#line 431 "runstring.in"
+#ifdef HAVE_STRFTIME
+ const time_t bintime=seconds;
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push<string>(""); return;}
+ {Stack->push<string>(Time); return;}
+#else
+// Avoid unused variable warning messages
+ unused(&seconds);
+ {Stack->push<string>(format); return;}
+#endif
+}
+
+#line 443 "runstring.in"
+// Int seconds(string t=emptystring, string format=emptystring);
+void gen_runstring19(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,emptystring);
+ string t=vm::pop<string>(Stack,emptystring);
+#line 444 "runstring.in"
+#if defined(HAVE_STRPTIME)
+ const time_t bintime=time(NULL);
+ tm tm=*localtime(&bintime);
+ if(t != "" && !strptime(t.c_str(),format.c_str(),&tm)) {Stack->push<Int>(-1); return;}
+ {Stack->push<Int>((Int) mktime(&tm)); return;}
+#else
+ {Stack->push<Int>(-1); return;}
+#endif
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runstring_venv(venv &ve)
+{
+#line 112 "runstring.in"
+ REGISTER_BLTIN(run::emptyString,"emptyString");
+#line 119 "runstring.in"
+ addFunc(ve, run::gen_runstring1, primInt(), SYM(length), formal(primString(), SYM(s), false, false));
+#line 124 "runstring.in"
+ addFunc(ve, run::gen_runstring2, primInt(), SYM(find), formal(primString(), SYM(s), false, false), formal(primString() , SYM(t), false, false), formal(primInt(), SYM(pos), true, false));
+#line 130 "runstring.in"
+ addFunc(ve, run::gen_runstring3, primInt(), SYM(rfind), formal(primString(), SYM(s), false, false), formal(primString() , SYM(t), false, false), formal(primInt(), SYM(pos), true, false));
+#line 136 "runstring.in"
+ addFunc(ve, run::gen_runstring4, primString() , SYM(reverse), formal(primString() , SYM(s), false, false));
+#line 142 "runstring.in"
+ addFunc(ve, run::gen_runstring5, primString() , SYM(insert), formal(primString() , SYM(s), false, false), formal(primInt(), SYM(pos), false, false), formal(primString() , SYM(t), false, false));
+#line 149 "runstring.in"
+ addFunc(ve, run::gen_runstring6, primString() , SYM(substr), formal(primString(), SYM(s), false, false), formal(primInt(), SYM(pos), false, false), formal(primInt(), SYM(n), true, false));
+#line 156 "runstring.in"
+ addFunc(ve, run::gen_runstring7, primString() , SYM(erase), formal(primString() , SYM(s), false, false), formal(primInt(), SYM(pos), false, false), formal(primInt(), SYM(n), false, false));
+#line 163 "runstring.in"
+ addFunc(ve, run::gen_runstring8, primString() , SYM(downcase), formal(primString() , SYM(s), false, false));
+#line 169 "runstring.in"
+ addFunc(ve, run::gen_runstring9, primString() , SYM(upcase), formal(primString() , SYM(s), false, false));
+#line 175 "runstring.in"
+ addFunc(ve, run::gen_runstring10, primString() , SYM(replace), formal(primString(), SYM(s), false, false), formal(stringArray2(), SYM(translate), false, false));
+#line 205 "runstring.in"
+ addFunc(ve, run::gen_runstring11, primString() , SYM(format), formal(primString(), SYM(format), false, false), formal(primInt(), SYM(x), false, false), formal(primString() , SYM(locale), true, false));
+#line 259 "runstring.in"
+ addFunc(ve, run::gen_runstring12, primString() , SYM(format), formal(primString(), SYM(format), false, false), formal(primBoolean(), SYM(forcemath), true, false), formal(primString() , SYM(separator), false, false), formal(primReal(), SYM(x), false, false), formal(primString() , SYM(locale), true, false));
+#line 388 "runstring.in"
+ addFunc(ve, run::gen_runstring13, primInt(), SYM(hex), formal(primString() , SYM(s), false, false));
+#line 399 "runstring.in"
+ addFunc(ve, run::gen_runstring14, primInt(), SYM(ascii), formal(primString() , SYM(s), false, false));
+#line 404 "runstring.in"
+ addFunc(ve, run::gen_runstring15, primString() , SYM(string), formal(primInt(), SYM(x), false, false));
+#line 411 "runstring.in"
+ addFunc(ve, run::gen_runstring16, primString() , SYM(string), formal(primReal(), SYM(x), false, false), formal(primInt(), SYM(digits), true, false));
+#line 419 "runstring.in"
+ addFunc(ve, run::gen_runstring17, primString() , SYM(time), formal(primString() , SYM(format), true, false));
+#line 430 "runstring.in"
+ addFunc(ve, run::gen_runstring18, primString() , SYM(time), formal(primInt(), SYM(seconds), false, false), formal(primString() , SYM(format), true, false));
+#line 443 "runstring.in"
+ addFunc(ve, run::gen_runstring19, primInt(), SYM(seconds), formal(primString() , SYM(t), true, false), formal(primString() , SYM(format), true, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runstring.h b/graphics/asymptote/runstring.h
new file mode 100644
index 0000000000..0092cf5d57
--- /dev/null
+++ b/graphics/asymptote/runstring.h
@@ -0,0 +1,9 @@
+/***** Autogenerated from runstring.in; changes will be overwritten *****/
+
+#ifndef runstring_H
+#define runstring_H
+namespace run {
+void emptyString(vm::stack *);
+}
+
+#endif // runstring_H
diff --git a/graphics/asymptote/runstring.in b/graphics/asymptote/runstring.in
new file mode 100644
index 0000000000..a8b0e68bce
--- /dev/null
+++ b/graphics/asymptote/runstring.in
@@ -0,0 +1,453 @@
+/*****
+ * runstring.in
+ *
+ * Runtime functions for string operations.
+ *
+ *****/
+
+stringarray2* => stringArray2()
+
+#include <cfloat>
+#include <cstring>
+#include <algorithm>
+
+#include "array.h"
+
+using namespace camp;
+using namespace vm;
+using namespace settings;
+
+typedef array stringarray;
+typedef array stringarray2;
+
+using types::stringArray;
+using types::stringArray2;
+
+namespace types {
+extern const char *names[];
+}
+
+namespace run {
+extern string emptystring;
+}
+
+static const string defaulttimeformat=string("%a %b %d %T %Z %Y");
+#ifdef HAVE_STRFTIME
+static const size_t nTime=256;
+static char Time[nTime];
+#endif
+
+void checkformat(const char *ptr, bool intformat)
+{
+ while(*ptr != '\0') {
+ if(*ptr != '%') /* While we have regular characters, print them. */
+ ptr++;
+ else { /* We've got a format specifier. */
+ ptr++;
+
+ while(*ptr && strchr ("-+ #0'I", *ptr)) /* Move past flags. */
+ ptr++;
+
+ if(*ptr == '*')
+ ptr++;
+ else while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ ptr++;
+
+ if(*ptr == '.') {
+ ptr++; /* Go past the period. */
+ if(*ptr == '*') {
+ ptr++;
+ } else
+ while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ ptr++;
+ }
+ while(*ptr && strchr ("hlL", *ptr))
+ ptr++;
+
+ if(*ptr == '%') {++ptr; continue;}
+ else if(*ptr != '\0') {
+ if(intformat) {
+ switch(*ptr) {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_Int];
+ error(buf);
+ break;
+ }
+ } else {
+ switch(*ptr) {
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_real];
+ error(buf);
+ break;
+ }
+ }
+ }
+ break; // Only one argument is allowed.
+ } /* End of else statement */
+ }
+}
+
+// Autogenerated routines:
+
+
+// String operations
+
+string :emptyString()
+{
+ return emptystring;
+}
+
+Int length(string *s)
+{
+ return (Int) s->length();
+}
+
+Int find(string *s, string t, Int pos=0)
+{
+ size_t n=s->find(t,pos);
+ return n == string::npos ? (Int) -1 : (Int) n;
+}
+
+Int rfind(string *s, string t, Int pos=-1)
+{
+ size_t n=s->rfind(t,pos);
+ return n == string::npos ? (Int) -1 : (Int) n;
+}
+
+string reverse(string s)
+{
+ reverse(s.begin(),s.end());
+ return s;
+}
+
+string insert(string s, Int pos, string t)
+{
+ if ((size_t) pos < s.length())
+ return s.insert(pos,t);
+ return s;
+}
+
+string substr(string* s, Int pos, Int n=-1)
+{
+ if ((size_t) pos < s->length())
+ return s->substr(pos,n);
+ return emptystring;
+}
+
+string erase(string s, Int pos, Int n)
+{
+ if ((size_t) pos < s.length())
+ return s.erase(pos,n);
+ return s;
+}
+
+string downcase(string s)
+{
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ return s;
+}
+
+string upcase(string s)
+{
+ std::transform(s.begin(),s.end(),s.begin(),toupper);
+ return s;
+}
+
+// returns a string constructed by translating all occurrences of the string
+// from in an array of string pairs {from,to} to the string to in string s.
+string replace(string *S, stringarray2 *translate)
+{
+ size_t size=checkArray(translate);
+ for(size_t i=0; i < size; i++) {
+ array *a=read<array*>(translate,i);
+ checkArray(a);
+ }
+ const char *p=S->c_str();
+ ostringstream buf;
+ while(*p) {
+ for(size_t i=0; i < size;) {
+ array *a=read<array*>(translate,i);
+ size_t size2=checkArray(a);
+ if(size2 != 2)
+ error("translation table entry must be an array of length 2");
+ string* from=read<string*>(a,0);
+ size_t len=from->length();
+ if(strncmp(p,from->c_str(),len) != 0) {i++; continue;}
+ buf << read<string>(a,1);
+ p += len;
+ if(*p == 0) return buf.str();
+ i=0;
+ }
+ buf << *(p++);
+ }
+ return buf.str();
+}
+
+string format(string *format, Int x, string locale=emptystring)
+{
+ ostringstream out;
+ const char *p0=format->c_str();
+ checkformat(p0,true);
+
+ const char *p=p0;
+ const char *start=NULL;
+ while(*p != 0) {
+ char curr=*p;
+ if(curr == '%') {
+ p++;
+ if(*p != '%') {start=p-1; break;}
+ }
+ out << *(p++);
+ }
+
+ if(!start) return out.str();
+
+ // Allow at most 1 argument
+ while(*p != 0) {
+ if(*p == '*' || *p == '$') return out.str();
+ if(isupper(*p) || islower(*p)) {p++; break;}
+ p++;
+ }
+
+ string f=format->substr(start-p0,p-start);
+
+ const char *oldlocale=NULL;
+
+ if(!locale.empty()) {
+ oldlocale=setlocale(LC_ALL,NULL);
+ if(oldlocale) oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_ALL,locale.c_str());
+ }
+
+ Int size=snprintf(NULL,0,f.c_str(),x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f.c_str(),x);
+
+ out << string(buf);
+ out << p;
+
+ delete[] buf;
+
+ if(oldlocale) {
+ setlocale(LC_ALL,oldlocale);
+ delete[] oldlocale;
+ }
+
+ return out.str();
+}
+
+string format(string *format, bool forcemath=false, string separator, real x,
+ string locale=emptystring)
+{
+ if(*format == "%") return ""; // Temporary workaround for github Issue #29.
+
+ bool tex=getSetting<string>("tex") != "none";
+ bool texify=forcemath;
+ ostringstream out;
+
+ const char *p0=format->c_str();
+ checkformat(p0,false);
+
+ const char *phantom="\\phantom{+}";
+
+ const char *p=p0;
+ const char *start=NULL;
+ char prev=0;
+ while(*p != 0) {
+ char curr=*p;
+ if(tex && curr == '$' && prev != '\\') texify=true;
+ prev=curr;
+ if(curr == '%') {
+ p++;
+ if(*p != '%') {start=p-1; break;}
+ }
+ out << *(p++);
+ }
+
+ if(!start) return out.str();
+
+ // Allow at most 1 argument
+ while(*p != 0) {
+ if(*p == '*' || *p == '$') return out.str();
+ if(isupper(*p) || islower(*p)) {p++; break;}
+ p++;
+ }
+
+ const char *tail=p;
+ string f=format->substr(start-p0,tail-start);
+
+ const char *oldlocale=NULL;
+ if(!locale.empty()) {
+ oldlocale=setlocale(LC_ALL,NULL);
+ if(oldlocale) oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_ALL,locale.c_str());
+ }
+
+ Int size=snprintf(NULL,0,f.c_str(),x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f.c_str(),x);
+
+ bool trailingzero=f.find("#") < string::npos;
+ bool plus=f.find("+") < string::npos;
+ bool space=f.find(" ") < string::npos;
+
+ char *q=buf; // beginning of formatted number
+
+ if(*q == ' ' && texify) {
+ out << phantom;
+ q++;
+ }
+
+ const char decimal=*(localeconv()->decimal_point);
+
+ // Remove any spurious sign
+ if(*q == '-' || *q == '+') {
+ p=q+1;
+ bool zero=true;
+ while(*p != 0) {
+ if(!isdigit(*p) && *p != decimal) break;
+ if(isdigit(*p) && *p != '0') {zero=false; break;}
+ p++;
+ }
+ if(zero) {
+ q++;
+ if((plus || space) && texify) out << phantom;
+ }
+ }
+
+ const char *r=p=q;
+ bool dp=false;
+ while(*r != 0 && (isspace(*r) || isdigit(*r) || *r == decimal \
+ || *r == '+' || *r == '-')) {
+ if(*r == decimal) dp=true;
+ r++;
+ }
+ if(dp) { // Remove trailing zeros and/or decimal point
+ r--;
+ unsigned n=0;
+ while(r > q && *r == '0') {r--; n++;}
+ if(*r == decimal) {r--; n++;}
+ while(q <= r) out << *(q++);
+ if(!trailingzero) q += n;
+ }
+
+ bool zero=(r == p && *r == '0') && !trailingzero;
+
+ // Translate "E+/E-/e+/e-" exponential notation to TeX
+ while(*q != 0) {
+ if(texify && (*q == 'E' || *q == 'e') &&
+ (*(q+1) == '+' || *(q+1) == '-')) {
+ if(!zero) out << separator << "10^{";
+ bool plus=(*(q+1) == '+');
+ q++;
+ if(plus) q++;
+ if(*q == '-') out << *(q++);
+ while(*q == '0' && (zero || isdigit(*(q+1)))) q++;
+ while(isdigit(*q)) out << *(q++);
+ if(!zero)
+ out << "}";
+ break;
+ }
+ out << *(q++);
+ }
+
+ while(*tail != 0)
+ out << *(tail++);
+
+ delete[] buf;
+
+ if(oldlocale) {
+ setlocale(LC_ALL,oldlocale);
+ delete[] oldlocale;
+ }
+
+ return out.str();
+}
+
+Int hex(string s)
+{
+ istringstream is(s);
+ is.setf(std::ios::hex,std::ios::basefield);
+ Int value;
+ if(is && is >> value && ((is >> std::ws).eof())) return value;
+ ostringstream buf;
+ buf << "invalid hexadecimal cast from string \"" << s << "\"";
+ error(buf);
+}
+
+Int ascii(string s)
+{
+ return s.empty() ? -1 : (unsigned char) s[0];
+}
+
+string string(Int x)
+{
+ ostringstream buf;
+ buf << x;
+ return buf.str();
+}
+
+string string(real x, Int digits=DBL_DIG)
+{
+ ostringstream buf;
+ buf.precision(digits);
+ buf << x;
+ return buf.str();
+}
+
+string time(string format=defaulttimeformat)
+{
+#ifdef HAVE_STRFTIME
+ const time_t bintime=time(NULL);
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) return "";
+ return Time;
+#else
+ return format;
+#endif
+}
+
+string time(Int seconds, string format=defaulttimeformat)
+{
+#ifdef HAVE_STRFTIME
+ const time_t bintime=seconds;
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) return "";
+ return Time;
+#else
+// Avoid unused variable warning messages
+ unused(&seconds);
+ return format;
+#endif
+}
+
+Int seconds(string t=emptystring, string format=emptystring)
+{
+#if defined(HAVE_STRPTIME)
+ const time_t bintime=time(NULL);
+ tm tm=*localtime(&bintime);
+ if(t != "" && !strptime(t.c_str(),format.c_str(),&tm)) return -1;
+ return (Int) mktime(&tm);
+#else
+ return -1;
+#endif
+}
diff --git a/graphics/asymptote/runsystem.cc b/graphics/asymptote/runsystem.cc
new file mode 100644
index 0000000000..40419b935c
--- /dev/null
+++ b/graphics/asymptote/runsystem.cc
@@ -0,0 +1,453 @@
+/***** Autogenerated from runsystem.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runsystem.in"
+/*****
+ * runsystem.in
+ *
+ * Runtime functions for system operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 12 "runsystem.in"
+#include "process.h"
+#include "stack.h"
+#include "locate.h"
+
+using namespace camp;
+using namespace settings;
+using vm::bpinfo;
+using vm::bplist;
+using vm::getPos;
+using vm::Default;
+using vm::nullfunc;
+using vm::item;
+using absyntax::runnable;
+
+typedef callable callableBp;
+
+namespace run {
+extern string emptystring;
+}
+
+function *voidFunction()
+{
+ return new function(primVoid());
+}
+
+function *breakpointFunction()
+{
+ return new function(primString(),primString(),primInt(),primInt(),
+ primCode());
+}
+
+void clear(string file, Int line, bool warn=false)
+{
+ bpinfo bp(file,line);
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p) {
+ if(*p == bp) {
+ cout << "cleared breakpoint at " << file << ": " << line << endl;
+ bplist.remove(bp);
+ return;
+ }
+ }
+ if(warn)
+ cout << "No such breakpoint at " << file << ": " << line << endl;
+}
+
+namespace run {
+void breakpoint(stack *Stack, runnable *r)
+{
+ callable *atBreakpointFunction=processData().atBreakpointFunction;
+ if(atBreakpointFunction &&
+ !nullfunc::instance()->compare(atBreakpointFunction)) {
+ position curPos=getPos();
+ Stack->push<string>(curPos.filename());
+ Stack->push<Int>((Int) curPos.Line());
+ Stack->push<Int>((Int) curPos.Column());
+ Stack->push(r ? r : vm::Default);
+ atBreakpointFunction->call(Stack); // returns a string
+ } else Stack->push<string>("");
+}
+}
+
+string convertname(string name, const string& format)
+{
+ if(name.empty())
+ return buildname(outname(),format,"");
+ name=outpath(name);
+ return format.empty() ? name : format+":"+name;
+}
+
+namespace run {
+void purge(Int divisor=0)
+{
+#ifdef USEGC
+ if(divisor > 0) GC_set_free_space_divisor((GC_word) divisor);
+ GC_gcollect();
+#endif
+}
+
+void updateFunction(stack *Stack)
+{
+ callable *atUpdateFunction=processData().atUpdateFunction;
+ if(atUpdateFunction && !nullfunc::instance()->compare(atUpdateFunction))
+ atUpdateFunction->call(Stack);
+}
+
+void exitFunction(stack *Stack)
+{
+ callable *atExitFunction=processData().atExitFunction;
+ if(atExitFunction && !nullfunc::instance()->compare(atExitFunction))
+ atExitFunction->call(Stack);
+}
+}
+
+// Autogenerated routines:
+
+
+#ifndef NOSYM
+#include "runsystem.symbols.h"
+
+#endif
+namespace run {
+#line 107 "runsystem.in"
+// string outname();
+void gen_runsystem0(stack *Stack)
+{
+#line 108 "runsystem.in"
+ {Stack->push<string>(outname()); return;}
+}
+
+#line 112 "runsystem.in"
+// void atupdate(callable *f);
+void gen_runsystem1(stack *Stack)
+{
+ callable * f=vm::pop<callable *>(Stack);
+#line 113 "runsystem.in"
+ processData().atUpdateFunction=f;
+}
+
+#line 117 "runsystem.in"
+// callable* atupdate();
+void gen_runsystem2(stack *Stack)
+{
+#line 118 "runsystem.in"
+ {Stack->push<callable*>(processData().atUpdateFunction); return;}
+}
+
+#line 122 "runsystem.in"
+// void atexit(callable *f);
+void gen_runsystem3(stack *Stack)
+{
+ callable * f=vm::pop<callable *>(Stack);
+#line 123 "runsystem.in"
+ processData().atExitFunction=f;
+}
+
+#line 127 "runsystem.in"
+// callable* atexit();
+void gen_runsystem4(stack *Stack)
+{
+#line 128 "runsystem.in"
+ {Stack->push<callable*>(processData().atExitFunction); return;}
+}
+
+#line 132 "runsystem.in"
+// void atbreakpoint(callableBp *f);
+void gen_runsystem5(stack *Stack)
+{
+ callableBp * f=vm::pop<callableBp *>(Stack);
+#line 133 "runsystem.in"
+ processData().atBreakpointFunction=f;
+}
+
+#line 137 "runsystem.in"
+// void breakpoint(runnable *s=NULL);
+void gen_runsystem6(stack *Stack)
+{
+ runnable * s=vm::pop<runnable *>(Stack,NULL);
+#line 138 "runsystem.in"
+ breakpoint(Stack,s);
+}
+
+#line 142 "runsystem.in"
+// string locatefile(string file);
+void gen_runsystem7(stack *Stack)
+{
+ string file=vm::pop<string>(Stack);
+#line 143 "runsystem.in"
+ {Stack->push<string>(locateFile(file)); return;}
+}
+
+#line 147 "runsystem.in"
+// void stop(string file, Int line, runnable *s=NULL);
+void gen_runsystem8(stack *Stack)
+{
+ runnable * s=vm::pop<runnable *>(Stack,NULL);
+ Int line=vm::pop<Int>(Stack);
+ string file=vm::pop<string>(Stack);
+#line 148 "runsystem.in"
+ file=locateFile(file);
+ clear(file,line);
+ cout << "setting breakpoint at " << file << ": " << line << endl;
+ bplist.push_back(bpinfo(file,line,s));
+}
+
+#line 155 "runsystem.in"
+// void breakpoints();
+void gen_runsystem9(stack *)
+{
+#line 156 "runsystem.in"
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p)
+ cout << p->f.name() << ": " << p->f.line() << endl;
+}
+
+#line 161 "runsystem.in"
+// void clear(string file, Int line);
+void gen_runsystem10(stack *Stack)
+{
+ Int line=vm::pop<Int>(Stack);
+ string file=vm::pop<string>(Stack);
+#line 162 "runsystem.in"
+ file=locateFile(file);
+ clear(file,line,true);
+}
+
+#line 167 "runsystem.in"
+// void clear();
+void gen_runsystem11(stack *)
+{
+#line 168 "runsystem.in"
+ bplist.clear();
+}
+
+#line 172 "runsystem.in"
+// void warn(string s);
+void gen_runsystem12(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 173 "runsystem.in"
+ Warn(s);
+}
+
+#line 177 "runsystem.in"
+// void nowarn(string s);
+void gen_runsystem13(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 178 "runsystem.in"
+ noWarn(s);
+}
+
+#line 182 "runsystem.in"
+// void warning(string s, string t, bool position=false);
+void gen_runsystem14(stack *Stack)
+{
+ bool position=vm::pop<bool>(Stack,false);
+ string t=vm::pop<string>(Stack);
+ string s=vm::pop<string>(Stack);
+#line 183 "runsystem.in"
+ if(settings::warn(s)) {
+ em.warning(position ? getPos() : nullPos,s);
+ em << t;
+ }
+}
+
+// Strip directory from string
+#line 191 "runsystem.in"
+// string stripdirectory(string *s);
+void gen_runsystem15(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 192 "runsystem.in"
+ {Stack->push<string>(stripDir(*s)); return;}
+}
+
+// Strip directory from string
+#line 197 "runsystem.in"
+// string stripfile(string *s);
+void gen_runsystem16(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 198 "runsystem.in"
+ {Stack->push<string>(stripFile(*s)); return;}
+}
+
+// Strip file extension from string
+#line 203 "runsystem.in"
+// string stripextension(string *s);
+void gen_runsystem17(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 204 "runsystem.in"
+ {Stack->push<string>(stripExt(*s)); return;}
+}
+
+// Call ImageMagick convert.
+#line 209 "runsystem.in"
+// Int convert(string args=emptystring, string file=emptystring, string format=emptystring);
+void gen_runsystem18(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,emptystring);
+ string file=vm::pop<string>(Stack,emptystring);
+ string args=vm::pop<string>(Stack,emptystring);
+#line 211 "runsystem.in"
+ string name=convertname(file,format);
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("convert"));
+ push_split(cmd,args);
+ cmd.push_back(name);
+ bool quiet=verbose <= 1;
+
+ char *oldPath=NULL;
+ string dir=stripFile(outname());
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
+ Int ret=System(cmd,quiet ? 1 : 0,true,"convert",
+ "your ImageMagick convert utility");
+ if(oldPath != NULL)
+ setPath(oldPath);
+
+ if(ret == 0 && verbose > 0)
+ cout << "Wrote " << (file.empty() ? name : file) << endl;
+
+ {Stack->push<Int>(ret); return;}
+}
+
+// Call ImageMagick animate.
+#line 237 "runsystem.in"
+// Int animate(string args=emptystring, string file=emptystring, string format=emptystring);
+void gen_runsystem19(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,emptystring);
+ string file=vm::pop<string>(Stack,emptystring);
+ string args=vm::pop<string>(Stack,emptystring);
+#line 239 "runsystem.in"
+#ifndef __MSDOS__
+ string name=convertname(file,format);
+ if(view()) {
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("animate"));
+ push_split(cmd,args);
+ cmd.push_back(name);
+ {Stack->push<Int>(System(cmd,0,false,"animate","your animated GIF viewer")); return;}
+ }
+#endif
+ {Stack->push<Int>(0); return;}
+}
+
+#line 253 "runsystem.in"
+// void purge(Int divisor=0);
+void gen_runsystem20(stack *Stack)
+{
+ Int divisor=vm::pop<Int>(Stack,0);
+#line 254 "runsystem.in"
+ purge(divisor);
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runsystem_venv(venv &ve)
+{
+#line 107 "runsystem.in"
+ addFunc(ve, run::gen_runsystem0, primString() , SYM(outname));
+#line 112 "runsystem.in"
+ addFunc(ve, run::gen_runsystem1, primVoid(), SYM(atupdate), formal(voidFunction(), SYM(f), false, false));
+#line 117 "runsystem.in"
+ addFunc(ve, run::gen_runsystem2, voidFunction(), SYM(atupdate));
+#line 122 "runsystem.in"
+ addFunc(ve, run::gen_runsystem3, primVoid(), SYM(atexit), formal(voidFunction(), SYM(f), false, false));
+#line 127 "runsystem.in"
+ addFunc(ve, run::gen_runsystem4, voidFunction(), SYM(atexit));
+#line 132 "runsystem.in"
+ addFunc(ve, run::gen_runsystem5, primVoid(), SYM(atbreakpoint), formal(breakpointFunction(), SYM(f), false, false));
+#line 137 "runsystem.in"
+ addFunc(ve, run::gen_runsystem6, primVoid(), SYM(breakpoint), formal(primCode(), SYM(s), true, false));
+#line 142 "runsystem.in"
+ addFunc(ve, run::gen_runsystem7, primString() , SYM(locatefile), formal(primString() , SYM(file), false, false));
+#line 147 "runsystem.in"
+ addFunc(ve, run::gen_runsystem8, primVoid(), SYM(stop), formal(primString() , SYM(file), false, false), formal(primInt(), SYM(line), false, false), formal(primCode(), SYM(s), true, false));
+#line 155 "runsystem.in"
+ addFunc(ve, run::gen_runsystem9, primVoid(), SYM(breakpoints));
+#line 161 "runsystem.in"
+ addFunc(ve, run::gen_runsystem10, primVoid(), SYM(clear), formal(primString() , SYM(file), false, false), formal(primInt(), SYM(line), false, false));
+#line 167 "runsystem.in"
+ addFunc(ve, run::gen_runsystem11, primVoid(), SYM(clear));
+#line 172 "runsystem.in"
+ addFunc(ve, run::gen_runsystem12, primVoid(), SYM(warn), formal(primString() , SYM(s), false, false));
+#line 177 "runsystem.in"
+ addFunc(ve, run::gen_runsystem13, primVoid(), SYM(nowarn), formal(primString() , SYM(s), false, false));
+#line 182 "runsystem.in"
+ addFunc(ve, run::gen_runsystem14, primVoid(), SYM(warning), formal(primString() , SYM(s), false, false), formal(primString() , SYM(t), false, false), formal(primBoolean(), SYM(position), true, false));
+#line 190 "runsystem.in"
+ addFunc(ve, run::gen_runsystem15, primString() , SYM(stripdirectory), formal(primString(), SYM(s), false, false));
+#line 196 "runsystem.in"
+ addFunc(ve, run::gen_runsystem16, primString() , SYM(stripfile), formal(primString(), SYM(s), false, false));
+#line 202 "runsystem.in"
+ addFunc(ve, run::gen_runsystem17, primString() , SYM(stripextension), formal(primString(), SYM(s), false, false));
+#line 208 "runsystem.in"
+ addFunc(ve, run::gen_runsystem18, primInt(), SYM(convert), formal(primString() , SYM(args), true, false), formal(primString() , SYM(file), true, false), formal(primString() , SYM(format), true, false));
+#line 236 "runsystem.in"
+ addFunc(ve, run::gen_runsystem19, primInt(), SYM(animate), formal(primString() , SYM(args), true, false), formal(primString() , SYM(file), true, false), formal(primString() , SYM(format), true, false));
+#line 253 "runsystem.in"
+ addFunc(ve, run::gen_runsystem20, primVoid(), SYM(purge), formal(primInt(), SYM(divisor), true, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runsystem.h b/graphics/asymptote/runsystem.h
new file mode 100644
index 0000000000..f6912e1076
--- /dev/null
+++ b/graphics/asymptote/runsystem.h
@@ -0,0 +1,8 @@
+/***** Autogenerated from runsystem.in; changes will be overwritten *****/
+
+#ifndef runsystem_H
+#define runsystem_H
+namespace run {
+}
+
+#endif // runsystem_H
diff --git a/graphics/asymptote/runsystem.in b/graphics/asymptote/runsystem.in
new file mode 100644
index 0000000000..45f7a040c9
--- /dev/null
+++ b/graphics/asymptote/runsystem.in
@@ -0,0 +1,256 @@
+/*****
+ * runsystem.in
+ *
+ * Runtime functions for system operations.
+ *
+ *****/
+
+callable* => voidFunction()
+callableBp* => breakpointFunction()
+runnable* => primCode()
+
+#include "process.h"
+#include "stack.h"
+#include "locate.h"
+
+using namespace camp;
+using namespace settings;
+using vm::bpinfo;
+using vm::bplist;
+using vm::getPos;
+using vm::Default;
+using vm::nullfunc;
+using vm::item;
+using absyntax::runnable;
+
+typedef callable callableBp;
+
+namespace run {
+extern string emptystring;
+}
+
+function *voidFunction()
+{
+ return new function(primVoid());
+}
+
+function *breakpointFunction()
+{
+ return new function(primString(),primString(),primInt(),primInt(),
+ primCode());
+}
+
+void clear(string file, Int line, bool warn=false)
+{
+ bpinfo bp(file,line);
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p) {
+ if(*p == bp) {
+ cout << "cleared breakpoint at " << file << ": " << line << endl;
+ bplist.remove(bp);
+ return;
+ }
+ }
+ if(warn)
+ cout << "No such breakpoint at " << file << ": " << line << endl;
+}
+
+namespace run {
+void breakpoint(stack *Stack, runnable *r)
+{
+ callable *atBreakpointFunction=processData().atBreakpointFunction;
+ if(atBreakpointFunction &&
+ !nullfunc::instance()->compare(atBreakpointFunction)) {
+ position curPos=getPos();
+ Stack->push<string>(curPos.filename());
+ Stack->push<Int>((Int) curPos.Line());
+ Stack->push<Int>((Int) curPos.Column());
+ Stack->push(r ? r : vm::Default);
+ atBreakpointFunction->call(Stack); // returns a string
+ } else Stack->push<string>("");
+}
+}
+
+string convertname(string name, const string& format)
+{
+ if(name.empty())
+ return buildname(outname(),format,"");
+ name=outpath(name);
+ return format.empty() ? name : format+":"+name;
+}
+
+namespace run {
+void purge(Int divisor=0)
+{
+#ifdef USEGC
+ if(divisor > 0) GC_set_free_space_divisor((GC_word) divisor);
+ GC_gcollect();
+#endif
+}
+
+void updateFunction(stack *Stack)
+{
+ callable *atUpdateFunction=processData().atUpdateFunction;
+ if(atUpdateFunction && !nullfunc::instance()->compare(atUpdateFunction))
+ atUpdateFunction->call(Stack);
+}
+
+void exitFunction(stack *Stack)
+{
+ callable *atExitFunction=processData().atExitFunction;
+ if(atExitFunction && !nullfunc::instance()->compare(atExitFunction))
+ atExitFunction->call(Stack);
+}
+}
+
+// Autogenerated routines:
+
+string outname()
+{
+ return outname();
+}
+
+void atupdate(callable *f)
+{
+ processData().atUpdateFunction=f;
+}
+
+callable *atupdate()
+{
+ return processData().atUpdateFunction;
+}
+
+void atexit(callable *f)
+{
+ processData().atExitFunction=f;
+}
+
+callable *atexit()
+{
+ return processData().atExitFunction;
+}
+
+void atbreakpoint(callableBp *f)
+{
+ processData().atBreakpointFunction=f;
+}
+
+void breakpoint(runnable *s=NULL)
+{
+ breakpoint(Stack,s);
+}
+
+string locatefile(string file)
+{
+ return locateFile(file);
+}
+
+void stop(string file, Int line, runnable *s=NULL)
+{
+ file=locateFile(file);
+ clear(file,line);
+ cout << "setting breakpoint at " << file << ": " << line << endl;
+ bplist.push_back(bpinfo(file,line,s));
+}
+
+void breakpoints()
+{
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p)
+ cout << p->f.name() << ": " << p->f.line() << endl;
+}
+
+void clear(string file, Int line)
+{
+ file=locateFile(file);
+ clear(file,line,true);
+}
+
+void clear()
+{
+ bplist.clear();
+}
+
+void warn(string s)
+{
+ Warn(s);
+}
+
+void nowarn(string s)
+{
+ noWarn(s);
+}
+
+void warning(string s, string t, bool position=false)
+{
+ if(settings::warn(s)) {
+ em.warning(position ? getPos() : nullPos,s);
+ em << t;
+ }
+}
+
+// Strip directory from string
+string stripdirectory(string *s)
+{
+ return stripDir(*s);
+}
+
+// Strip directory from string
+string stripfile(string *s)
+{
+ return stripFile(*s);
+}
+
+// Strip file extension from string
+string stripextension(string *s)
+{
+ return stripExt(*s);
+}
+
+// Call ImageMagick convert.
+Int convert(string args=emptystring, string file=emptystring,
+ string format=emptystring)
+{
+ string name=convertname(file,format);
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("convert"));
+ push_split(cmd,args);
+ cmd.push_back(name);
+ bool quiet=verbose <= 1;
+
+ char *oldPath=NULL;
+ string dir=stripFile(outname());
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
+ Int ret=System(cmd,quiet ? 1 : 0,true,"convert",
+ "your ImageMagick convert utility");
+ if(oldPath != NULL)
+ setPath(oldPath);
+
+ if(ret == 0 && verbose > 0)
+ cout << "Wrote " << (file.empty() ? name : file) << endl;
+
+ return ret;
+}
+
+// Call ImageMagick animate.
+Int animate(string args=emptystring, string file=emptystring,
+ string format=emptystring)
+{
+#ifndef __MSDOS__
+ string name=convertname(file,format);
+ if(view()) {
+ mem::vector<string> cmd;
+ cmd.push_back(getSetting<string>("animate"));
+ push_split(cmd,args);
+ cmd.push_back(name);
+ return System(cmd,0,false,"animate","your animated GIF viewer");
+ }
+#endif
+ return 0;
+}
+
+void purge(Int divisor=0)
+{
+ purge(divisor);
+}
diff --git a/graphics/asymptote/runtime.cc b/graphics/asymptote/runtime.cc
new file mode 100644
index 0000000000..e2a6cdbdfe
--- /dev/null
+++ b/graphics/asymptote/runtime.cc
@@ -0,0 +1,2120 @@
+/***** Autogenerated from runtime.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runtime.in"
+/*****
+ * runtime.in
+ * Tom Prince 2005/4/15
+ *
+ * Generate the runtime functions used by the vm::stack machine.
+ *
+ *****/
+
+/* Autogenerated routines are specified like this (separated by a formfeed):
+ type asyname:cname(cparams)
+ {
+ C code
+ }
+
+*/
+
+// Use Void f() instead of void f() to force an explicit Stack argument.
+
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 55 "runtime.in"
+#include <cfloat>
+#include <iostream>
+#include <fstream>
+#include <time.h>
+#include <sys/times.h>
+#include <locale.h>
+
+#include "angle.h"
+#include "pair.h"
+#include "triple.h"
+#include "transform.h"
+#include "path.h"
+#include "path3.h"
+#include "pen.h"
+#include "drawpath.h"
+#include "guide.h"
+#include "picture.h"
+#include "fileio.h"
+#include "genv.h"
+#include "builtin.h"
+#include "texfile.h"
+#include "pipestream.h"
+#include "parser.h"
+#include "stack.h"
+#include "util.h"
+#include "locate.h"
+#include "mathop.h"
+#include "callable.h"
+#include "stm.h"
+#include "lexical.h"
+#include "process.h"
+#include "arrayop.h"
+
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ extern "C" {
+ void *GC_generate_random_valid_address(void);
+ void GC_debug_print_heap_obj_proc(void *);
+ }
+#endif
+
+using namespace vm;
+using namespace camp;
+using namespace settings;
+
+#undef OUT
+#undef IN
+
+namespace run {
+using camp::pair;
+using vm::array;
+using vm::frame;
+using vm::stack;
+using camp::transform;
+using absyntax::runnable;
+
+typedef array boolarray;
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray;
+typedef array triplearray2;
+typedef array patharray;
+typedef array patharray2;
+typedef array guidearray;
+typedef array transformarray;
+typedef array penarray;
+typedef array penarray2;
+typedef array stringarray;
+typedef array stringarray2;
+
+typedef callable callableBp;
+typedef callable callableReal;
+typedef callable callableTransform;
+}
+
+using vm::array;
+using types::function;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+using types::booleanArray;
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray;
+using types::tripleArray2;
+using types::pathArray;
+using types::pathArray2;
+using types::guideArray;
+using types::transformArray;
+using types::penArray;
+using types::penArray2;
+using types::stringArray;
+using types::stringArray2;
+using types::formal;
+
+function *realRealFunction()
+{
+ return new function(primReal(),primReal());
+}
+
+function *realTripleFunction()
+{
+ return new function(primReal(),primTriple());
+}
+
+const size_t camp::ColorComponents[]={0,0,1,3,4,0};
+
+namespace vm {
+#if COMPACT
+const Int DefaultValue=0x7fffffffffffffffLL;
+const Int Undefined=0x7ffffffffffffffeLL;
+
+const Int BoolTruthValue=0xABABABABABABABACLL;
+const Int BoolFalseValue=0xABABABABABABABABLL;
+
+const item Default=DefaultValue;
+#else
+const item Default=item(default_t());
+#endif
+}
+
+namespace run {
+
+const char *arrayempty="cannot take min or max of empty array";
+const char *noruntime="no runtime environment for embedded eval";
+
+void writestring(stack *s)
+{
+ callable *suffix=pop<callable *>(s,NULL);
+ string S=pop<string>(s);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::ofile *f=defaultfile ? &camp::Stdout : vm::get<camp::ofile*>(it);
+ if(!f->isOpen() || !f->enabled()) return;
+ if(S != "") f->write(S);
+ if(f->text()) {
+ if(suffix) {
+ s->push(f);
+ suffix->call(s);
+ } else if(defaultfile) f->writeline();
+ }
+}
+
+string toplocation() {
+ ostringstream buf;
+ position& topPos=processData().topPos;
+ buf << topPos.Line() << "." << topPos.Column();
+ return buf.str();
+}
+
+string emptystring;
+pair zero;
+
+}
+
+static string defaulttransparency=string("Compatible");
+
+void unused(void *)
+{
+}
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runtime.symbols.h"
+
+#endif
+namespace run {
+
+// Initializers
+#line 230 "runtime.in"
+void IntZero(stack *Stack)
+{
+#line 231 "runtime.in"
+ {Stack->push<Int>(0); return;}
+}
+
+#line 236 "runtime.in"
+void realZero(stack *Stack)
+{
+#line 237 "runtime.in"
+ {Stack->push<real>(0.0); return;}
+}
+
+#line 241 "runtime.in"
+void boolFalse(stack *Stack)
+{
+#line 242 "runtime.in"
+ {Stack->push<bool>(false); return;}
+}
+
+#line 246 "runtime.in"
+// bool isnan(real x);
+void gen_runtime3(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 247 "runtime.in"
+ {Stack->push<bool>(std::isnan(x)); return;}
+}
+
+#line 251 "runtime.in"
+void pushNullArray(stack *Stack)
+{
+#line 252 "runtime.in"
+ {Stack->push<array*>(0); return;}
+}
+
+#line 256 "runtime.in"
+void pushNullRecord(stack *Stack)
+{
+#line 257 "runtime.in"
+ {Stack->push<frame*>(0); return;}
+}
+
+#line 261 "runtime.in"
+void pushNullFunction(stack *Stack)
+{
+#line 262 "runtime.in"
+ {Stack->push(nullfunc::instance()); return;}
+}
+
+
+// Default operations
+
+// Put the default value token on the stack (in place of an argument when
+// making a function call).
+#line 271 "runtime.in"
+void pushDefault(stack *Stack)
+{
+#line 272 "runtime.in"
+ {Stack->push(Default); return;}
+}
+
+
+// Test if the value on the stack is the default value token.
+#line 278 "runtime.in"
+void isDefault(stack *Stack)
+{
+ item i=vm::pop(Stack);
+#line 279 "runtime.in"
+ {Stack->push<bool>(isdefault(i)); return;}
+}
+
+
+// Casts
+#line 285 "runtime.in"
+void pairToGuide(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 286 "runtime.in"
+ {Stack->push<guide*>(new pairguide(z)); return;}
+}
+
+#line 291 "runtime.in"
+void pathToGuide(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 292 "runtime.in"
+ {Stack->push<guide*>(new pathguide(p)); return;}
+}
+
+#line 296 "runtime.in"
+void guideToPath(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 297 "runtime.in"
+ {Stack->push<path>(g->solve()); return;}
+}
+
+
+// Pen operations
+#line 303 "runtime.in"
+void newPen(stack *Stack)
+{
+#line 304 "runtime.in"
+ {Stack->push<pen>(pen()); return;}
+}
+
+#line 309 "runtime.in"
+// bool ==(pen a, pen b);
+void gen_runtime13(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 310 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 314 "runtime.in"
+// bool !=(pen a, pen b);
+void gen_runtime14(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 315 "runtime.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 319 "runtime.in"
+// pen +(pen a, pen b);
+void gen_runtime15(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 320 "runtime.in"
+ {Stack->push<pen>(a+b); return;}
+}
+
+#line 324 "runtime.in"
+// pen *(real a, pen b);
+void gen_runtime16(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ real a=vm::pop<real>(Stack);
+#line 325 "runtime.in"
+ {Stack->push<pen>(a*b); return;}
+}
+
+#line 329 "runtime.in"
+// pen *(pen a, real b);
+void gen_runtime17(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 330 "runtime.in"
+ {Stack->push<pen>(b*a); return;}
+}
+
+#line 334 "runtime.in"
+// pair max(pen p);
+void gen_runtime18(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 335 "runtime.in"
+ {Stack->push<pair>(p.bounds().Max()); return;}
+}
+
+#line 339 "runtime.in"
+// pair min(pen p);
+void gen_runtime19(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 340 "runtime.in"
+ {Stack->push<pair>(p.bounds().Min()); return;}
+}
+
+// Reset the meaning of pen default attributes.
+#line 345 "runtime.in"
+// void resetdefaultpen();
+void gen_runtime20(stack *)
+{
+#line 346 "runtime.in"
+ processData().defaultpen=camp::pen::initialpen();
+}
+
+#line 350 "runtime.in"
+// void defaultpen(pen p);
+void gen_runtime21(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 351 "runtime.in"
+ processData().defaultpen=pen(resolvepen,p);
+}
+
+#line 355 "runtime.in"
+// pen defaultpen();
+void gen_runtime22(stack *Stack)
+{
+#line 356 "runtime.in"
+ {Stack->push<pen>(processData().defaultpen); return;}
+}
+
+#line 360 "runtime.in"
+// bool invisible(pen p);
+void gen_runtime23(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 361 "runtime.in"
+ {Stack->push<bool>(p.invisible()); return;}
+}
+
+#line 365 "runtime.in"
+// pen invisible();
+void gen_runtime24(stack *Stack)
+{
+#line 366 "runtime.in"
+ {Stack->push<pen>(pen(invisiblepen)); return;}
+}
+
+#line 370 "runtime.in"
+// pen gray(pen p);
+void gen_runtime25(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 371 "runtime.in"
+ p.togrey();
+ {Stack->push<pen>(p); return;}
+}
+
+#line 376 "runtime.in"
+// pen rgb(pen p);
+void gen_runtime26(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 377 "runtime.in"
+ p.torgb();
+ {Stack->push<pen>(p); return;}
+}
+
+#line 382 "runtime.in"
+// pen cmyk(pen p);
+void gen_runtime27(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 383 "runtime.in"
+ p.tocmyk();
+ {Stack->push<pen>(p); return;}
+}
+
+#line 388 "runtime.in"
+// pen interp(pen a, pen b, real t);
+void gen_runtime28(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 389 "runtime.in"
+ {Stack->push<pen>(interpolate(a,b,t)); return;}
+}
+
+#line 393 "runtime.in"
+// pen rgb(real r, real g, real b);
+void gen_runtime29(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ real g=vm::pop<real>(Stack);
+ real r=vm::pop<real>(Stack);
+#line 394 "runtime.in"
+ {Stack->push<pen>(pen(r,g,b)); return;}
+}
+
+#line 398 "runtime.in"
+// pen cmyk(real c, real m, real y, real k);
+void gen_runtime30(stack *Stack)
+{
+ real k=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+ real m=vm::pop<real>(Stack);
+ real c=vm::pop<real>(Stack);
+#line 399 "runtime.in"
+ {Stack->push<pen>(pen(c,m,y,k)); return;}
+}
+
+#line 403 "runtime.in"
+// pen gray(real gray);
+void gen_runtime31(stack *Stack)
+{
+ real gray=vm::pop<real>(Stack);
+#line 404 "runtime.in"
+ {Stack->push<pen>(pen(gray)); return;}
+}
+
+#line 408 "runtime.in"
+// realarray* colors(pen p);
+void gen_runtime32(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 409 "runtime.in"
+ size_t n=ColorComponents[p.colorspace()];
+ array *a=new array(n);
+
+ switch(n) {
+ case 0:
+ break;
+ case 1:
+ (*a)[0]=p.gray();
+ break;
+ case 3:
+ (*a)[0]=p.red();
+ (*a)[1]=p.green();
+ (*a)[2]=p.blue();
+ break;
+ case 4:
+ (*a)[0]=p.cyan();
+ (*a)[1]=p.magenta();
+ (*a)[2]=p.yellow();
+ (*a)[3]=p.black();
+ break;
+ default:
+ break;
+ }
+ {Stack->push<realarray*>(a); return;}
+}
+
+#line 436 "runtime.in"
+// string hex(pen p);
+void gen_runtime33(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 437 "runtime.in"
+ {Stack->push<string>(p.hex()); return;}
+}
+
+#line 441 "runtime.in"
+// Int byte(real x);
+void gen_runtime34(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 442 "runtime.in"
+ {Stack->push<Int>(camp::byte(x)); return;}
+}
+
+#line 446 "runtime.in"
+// string colorspace(pen p);
+void gen_runtime35(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 447 "runtime.in"
+ string s=ColorDeviceSuffix[p.colorspace()];
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ {Stack->push<string>(s); return;}
+}
+
+#line 453 "runtime.in"
+// pen pattern(string *s);
+void gen_runtime36(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 454 "runtime.in"
+ {Stack->push<pen>(pen(setpattern,*s)); return;}
+}
+
+#line 458 "runtime.in"
+// string pattern(pen p);
+void gen_runtime37(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 459 "runtime.in"
+ {Stack->push<string>(p.fillpattern()); return;}
+}
+
+#line 463 "runtime.in"
+// pen fillrule(Int n);
+void gen_runtime38(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 464 "runtime.in"
+ {Stack->push<pen>(pen(n >= 0 && n < nFill ? (FillRule) n : DEFFILL)); return;}
+}
+
+#line 468 "runtime.in"
+// Int fillrule(pen p);
+void gen_runtime39(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 469 "runtime.in"
+ {Stack->push<Int>(p.Fillrule()); return;}
+}
+
+#line 473 "runtime.in"
+// pen opacity(real opacity=1.0, string blend=defaulttransparency);
+void gen_runtime40(stack *Stack)
+{
+ string blend=vm::pop<string>(Stack,defaulttransparency);
+ real opacity=vm::pop<real>(Stack,1.0);
+#line 474 "runtime.in"
+ for(Int i=0; i < nBlendMode; ++i)
+ if(blend == BlendMode[i]) {Stack->push<pen>(pen(Transparency(blend,opacity))); return;}
+
+ ostringstream buf;
+ buf << "Unknown blend mode: " << "'" << blend << "'";
+ error(buf);
+}
+
+#line 483 "runtime.in"
+// real opacity(pen p);
+void gen_runtime41(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 484 "runtime.in"
+ {Stack->push<real>(p.opacity()); return;}
+}
+
+#line 488 "runtime.in"
+// string blend(pen p);
+void gen_runtime42(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 489 "runtime.in"
+ {Stack->push<string>(p.blend()); return;}
+}
+
+#line 493 "runtime.in"
+// pen linetype(realarray *pattern, real offset=0, bool scale=true, bool adjust=true);
+void gen_runtime43(stack *Stack)
+{
+ bool adjust=vm::pop<bool>(Stack,true);
+ bool scale=vm::pop<bool>(Stack,true);
+ real offset=vm::pop<real>(Stack,0);
+ realarray * pattern=vm::pop<realarray *>(Stack);
+#line 495 "runtime.in"
+ size_t size=checkArray(pattern);
+ array *a=new array(size);
+ for(size_t i=0; i < size; ++i)
+ (*a)[i]=::max(vm::read<double>(pattern,i),0.0);
+
+ {Stack->push<pen>(pen(LineType(*a,offset,scale,adjust))); return;}
+}
+
+#line 504 "runtime.in"
+// realarray* linetype(pen p=CURRENTPEN);
+void gen_runtime44(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 505 "runtime.in"
+ array a=p.linetype()->pattern;
+ {Stack->push<realarray*>(copyArray(&a)); return;}
+}
+
+#line 510 "runtime.in"
+// real offset(pen p);
+void gen_runtime45(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 511 "runtime.in"
+ {Stack->push<real>(p.linetype()->offset); return;}
+}
+
+#line 515 "runtime.in"
+// bool scale(pen p);
+void gen_runtime46(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 516 "runtime.in"
+ {Stack->push<bool>(p.linetype()->scale); return;}
+}
+
+#line 520 "runtime.in"
+// bool adjust(pen p);
+void gen_runtime47(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 521 "runtime.in"
+ {Stack->push<bool>(p.linetype()->adjust); return;}
+}
+
+#line 525 "runtime.in"
+// pen adjust(pen p, real arclength, bool cyclic);
+void gen_runtime48(stack *Stack)
+{
+ bool cyclic=vm::pop<bool>(Stack);
+ real arclength=vm::pop<real>(Stack);
+ pen p=vm::pop<pen>(Stack);
+#line 526 "runtime.in"
+ {Stack->push<pen>(adjustdash(p,arclength,cyclic)); return;}
+}
+
+#line 530 "runtime.in"
+// pen linecap(Int n);
+void gen_runtime49(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 531 "runtime.in"
+ {Stack->push<pen>(pen(setlinecap,n >= 0 && n < nCap ? n : DEFCAP)); return;}
+}
+
+#line 535 "runtime.in"
+// Int linecap(pen p=CURRENTPEN);
+void gen_runtime50(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 536 "runtime.in"
+ {Stack->push<Int>(p.cap()); return;}
+}
+
+#line 540 "runtime.in"
+// pen linejoin(Int n);
+void gen_runtime51(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 541 "runtime.in"
+ {Stack->push<pen>(pen(setlinejoin,n >= 0 && n < nJoin ? n : DEFJOIN)); return;}
+}
+
+#line 545 "runtime.in"
+// Int linejoin(pen p=CURRENTPEN);
+void gen_runtime52(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 546 "runtime.in"
+ {Stack->push<Int>(p.join()); return;}
+}
+
+#line 550 "runtime.in"
+// pen miterlimit(real x);
+void gen_runtime53(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 551 "runtime.in"
+ {Stack->push<pen>(pen(setmiterlimit,x >= 1.0 ? x : DEFJOIN)); return;}
+}
+
+#line 555 "runtime.in"
+// real miterlimit(pen p=CURRENTPEN);
+void gen_runtime54(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 556 "runtime.in"
+ {Stack->push<real>(p.miter()); return;}
+}
+
+#line 560 "runtime.in"
+// pen linewidth(real x);
+void gen_runtime55(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 561 "runtime.in"
+ {Stack->push<pen>(pen(setlinewidth,x >= 0.0 ? x : DEFWIDTH)); return;}
+}
+
+#line 565 "runtime.in"
+// real linewidth(pen p=CURRENTPEN);
+void gen_runtime56(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 566 "runtime.in"
+ {Stack->push<real>(p.width()); return;}
+}
+
+#line 570 "runtime.in"
+// pen fontcommand(string *s);
+void gen_runtime57(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 571 "runtime.in"
+ {Stack->push<pen>(pen(setfont,*s)); return;}
+}
+
+#line 575 "runtime.in"
+// string font(pen p=CURRENTPEN);
+void gen_runtime58(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 576 "runtime.in"
+ {Stack->push<string>(p.Font()); return;}
+}
+
+#line 580 "runtime.in"
+// pen fontsize(real size, real lineskip);
+void gen_runtime59(stack *Stack)
+{
+ real lineskip=vm::pop<real>(Stack);
+ real size=vm::pop<real>(Stack);
+#line 581 "runtime.in"
+ {Stack->push<pen>(pen(setfontsize,size > 0.0 ? size : 0.0,
+ lineskip > 0.0 ? lineskip : 0.0)); return;}
+}
+
+#line 586 "runtime.in"
+// real fontsize(pen p=CURRENTPEN);
+void gen_runtime60(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 587 "runtime.in"
+ {Stack->push<real>(p.size()); return;}
+}
+
+#line 591 "runtime.in"
+// real lineskip(pen p=CURRENTPEN);
+void gen_runtime61(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 592 "runtime.in"
+ {Stack->push<real>(p.Lineskip()); return;}
+}
+
+#line 596 "runtime.in"
+// pen overwrite(Int n);
+void gen_runtime62(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 597 "runtime.in"
+ {Stack->push<pen>(pen(setoverwrite,n >= 0 && n < nOverwrite ? (overwrite_t) n :
+ DEFWRITE)); return;}
+}
+
+#line 602 "runtime.in"
+// Int overwrite(pen p=CURRENTPEN);
+void gen_runtime63(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 603 "runtime.in"
+ {Stack->push<Int>(p.Overwrite()); return;}
+}
+
+#line 607 "runtime.in"
+// pen basealign(Int n);
+void gen_runtime64(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 608 "runtime.in"
+ {Stack->push<pen>(pen(n >= 0 && n < nBaseLine ? (BaseLine) n : DEFBASE)); return;}
+}
+
+#line 612 "runtime.in"
+// Int basealign(pen p=CURRENTPEN);
+void gen_runtime65(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 613 "runtime.in"
+ {Stack->push<Int>(p.Baseline()); return;}
+}
+
+#line 617 "runtime.in"
+// transform transform(pen p);
+void gen_runtime66(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 618 "runtime.in"
+ {Stack->push<transform>(p.getTransform()); return;}
+}
+
+#line 622 "runtime.in"
+// path nib(pen p);
+void gen_runtime67(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 623 "runtime.in"
+ {Stack->push<path>(p.Path()); return;}
+}
+
+#line 627 "runtime.in"
+// pen makepen(path p);
+void gen_runtime68(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 628 "runtime.in"
+ {Stack->push<pen>(pen(p)); return;}
+}
+
+#line 632 "runtime.in"
+// pen colorless(pen p);
+void gen_runtime69(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 633 "runtime.in"
+ p.colorless();
+ {Stack->push<pen>(p); return;}
+}
+
+// Interactive mode
+#line 639 "runtime.in"
+// bool interactive();
+void gen_runtime70(stack *Stack)
+{
+#line 640 "runtime.in"
+ {Stack->push<bool>(interact::interactive); return;}
+}
+
+#line 645 "runtime.in"
+// bool uptodate();
+void gen_runtime71(stack *Stack)
+{
+#line 646 "runtime.in"
+ {Stack->push<bool>(interact::uptodate); return;}
+}
+
+
+// System commands
+#line 652 "runtime.in"
+// Int system(stringarray *s);
+void gen_runtime72(stack *Stack)
+{
+ stringarray * s=vm::pop<stringarray *>(Stack);
+#line 653 "runtime.in"
+ if(safe) error("system() call disabled; override with option -nosafe");
+ size_t size=checkArray(s);
+ if(size == 0) {Stack->push<Int>(0); return;}
+ mem::vector<string> cmd;
+ for(size_t i=0; i < size; ++i)
+ cmd.push_back(read<string>(s,i));
+ {Stack->push<Int>(System(cmd)); return;}
+}
+
+#line 664 "runtime.in"
+// bool view();
+void gen_runtime73(stack *Stack)
+{
+#line 665 "runtime.in"
+ {Stack->push<bool>(view()); return;}
+}
+
+#line 669 "runtime.in"
+// string asydir();
+void gen_runtime74(stack *Stack)
+{
+#line 670 "runtime.in"
+ {Stack->push<string>(systemDir); return;}
+}
+
+#line 674 "runtime.in"
+// string locale(string s=emptystring);
+void gen_runtime75(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+#line 675 "runtime.in"
+ char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str());
+ {Stack->push<string>(L != NULL ? string(L) : ""); return;}
+}
+
+#line 680 "runtime.in"
+// void abort(string s=emptystring);
+void gen_runtime76(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+#line 681 "runtime.in"
+ if(s.empty()) throw handled_error();
+ error(s.c_str());
+}
+
+#line 686 "runtime.in"
+// void exit();
+void gen_runtime77(stack *)
+{
+#line 687 "runtime.in"
+ throw quit();
+}
+
+#line 691 "runtime.in"
+// void assert(bool b, string s=emptystring);
+void gen_runtime78(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+ bool b=vm::pop<bool>(Stack);
+#line 692 "runtime.in"
+ flush(cout);
+ if(!b) {
+ ostringstream buf;
+ buf << "assert FAILED";
+ if(s != "") buf << ": " << s;
+ error(buf);
+ }
+}
+
+#line 702 "runtime.in"
+// void sleep(Int seconds);
+void gen_runtime79(stack *Stack)
+{
+ Int seconds=vm::pop<Int>(Stack);
+#line 703 "runtime.in"
+ if(seconds <= 0) return;
+ sleep(seconds);
+}
+
+#line 708 "runtime.in"
+// void usleep(Int microseconds);
+void gen_runtime80(stack *Stack)
+{
+ Int microseconds=vm::pop<Int>(Stack);
+#line 709 "runtime.in"
+ if(microseconds <= 0) return;
+ usleep((unsigned long) microseconds);
+}
+
+#line 714 "runtime.in"
+// void _eval(string *s, bool embedded, bool interactiveWrite=false);
+void gen_runtime81(stack *Stack)
+{
+ bool interactiveWrite=vm::pop<bool>(Stack,false);
+ bool embedded=vm::pop<bool>(Stack);
+ string * s=vm::pop<string *>(Stack);
+#line 715 "runtime.in"
+ if(embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if(e && is)
+ runStringEmbedded(*s, *e, *is);
+ else
+ error(noruntime);
+ } else
+ runString(*s,interactiveWrite);
+}
+
+#line 727 "runtime.in"
+// void _eval(runnable *s, bool embedded);
+void gen_runtime82(stack *Stack)
+{
+ bool embedded=vm::pop<bool>(Stack);
+ runnable * s=vm::pop<runnable *>(Stack);
+#line 728 "runtime.in"
+ absyntax::block *ast=new absyntax::block(s->getPos(), false);
+ ast->add(s);
+
+ if(embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if(e && is)
+ runCodeEmbedded(ast, *e, *is);
+ else
+ error(noruntime);
+ } else
+ runCode(ast);
+}
+
+#line 743 "runtime.in"
+// string xasyKEY();
+void gen_runtime83(stack *Stack)
+{
+#line 744 "runtime.in"
+ processDataStruct *P=&processData();
+ xkey_t *xkey=&P->xkey;
+ xkey_t::iterator p=xkey->find(P->topPos.LineColumn());
+ {Stack->push<string>(p != xkey->end() ? p->second+" 1" : toplocation()+" 0"); return;}
+}
+
+#line 750 "runtime.in"
+// void xasyKEY(string *s);
+void gen_runtime84(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 751 "runtime.in"
+ processData().KEY=*s;
+}
+
+#line 754 "runtime.in"
+// string toplocation();
+void gen_runtime85(stack *Stack)
+{
+#line 755 "runtime.in"
+ {Stack->push<string>(toplocation()); return;}
+}
+
+#line 758 "runtime.in"
+// string location();
+void gen_runtime86(stack *Stack)
+{
+#line 759 "runtime.in"
+ ostringstream buf;
+ buf << getPos();
+ {Stack->push<string>(buf.str()); return;}
+}
+
+// Wrapper for the stack::load() method.
+#line 765 "runtime.in"
+void loadModule(stack *Stack)
+{
+ string * index=vm::pop<string *>(Stack);
+#line 766 "runtime.in"
+ Stack->load(*index);
+}
+
+#line 770 "runtime.in"
+// string cd(string s=emptystring);
+void gen_runtime88(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+#line 771 "runtime.in"
+ if(!s.empty() && !globalwrite()) {
+ string outname=getSetting<string>("outname");
+ string dir=stripDir(outname);
+ if(dir.empty()) Setting("outname")=getPath()+dirsep+outname;
+ }
+ {Stack->push<string>(setPath(s.c_str())); return;}
+}
+
+#line 780 "runtime.in"
+// void list(string *s, bool imports=false);
+void gen_runtime89(stack *Stack)
+{
+ bool imports=vm::pop<bool>(Stack,false);
+ string * s=vm::pop<string *>(Stack);
+#line 781 "runtime.in"
+ if(*s == "-") return;
+ trans::genv ge;
+ symbol name=symbol::trans(*s);
+ record *r=ge.getModule(name,*s);
+ r->e.list(imports ? 0 : r);
+}
+
+
+// Guide operations
+#line 791 "runtime.in"
+void nullGuide(stack *Stack)
+{
+#line 792 "runtime.in"
+ {Stack->push<guide*>(new pathguide(path())); return;}
+}
+
+#line 797 "runtime.in"
+void dotsGuide(stack *Stack)
+{
+ guidearray * a=vm::pop<guidearray *>(Stack);
+#line 798 "runtime.in"
+ guidevector v;
+ size_t size=checkArray(a);
+ for (size_t i=0; i < size; ++i)
+ v.push_back(a->read<guide*>(i));
+
+ {Stack->push<guide*>(new multiguide(v)); return;}
+}
+
+#line 807 "runtime.in"
+void dashesGuide(stack *Stack)
+{
+ guidearray * a=vm::pop<guidearray *>(Stack);
+#line 808 "runtime.in"
+ static camp::curlSpec curly;
+ static camp::specguide curlout(&curly, camp::OUT);
+ static camp::specguide curlin(&curly, camp::IN);
+
+ size_t n=checkArray(a);
+
+ // a--b is equivalent to a{curl 1}..{curl 1}b
+ guidevector v;
+ if (n > 0)
+ v.push_back(a->read<guide*>(0));
+
+ if (n==1) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ }
+ else
+ for (size_t i=1; i<n; ++i) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ v.push_back(a->read<guide*>(i));
+ }
+
+ {Stack->push<guide*>(new multiguide(v)); return;}
+}
+
+#line 834 "runtime.in"
+void newCycleToken(stack *Stack)
+{
+#line 835 "runtime.in"
+ {Stack->push<cycleToken>(cycleToken()); return;}
+}
+
+#line 839 "runtime.in"
+// guide* operator cast(cycleToken tok);
+void gen_runtime94(stack *Stack)
+{
+ cycleToken tok=vm::pop<cycleToken>(Stack);
+#line 840 "runtime.in"
+// Avoid unused variable warning messages.
+ unused(&tok);
+ {Stack->push<guide*>(new cycletokguide()); return;}
+}
+
+#line 846 "runtime.in"
+// guide* operator spec(pair z, Int p);
+void gen_runtime95(stack *Stack)
+{
+ Int p=vm::pop<Int>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 847 "runtime.in"
+ camp::side d=(camp::side) p;
+ camp::dirSpec *sp=new camp::dirSpec(z);
+
+ {Stack->push<guide*>(new specguide(sp,d)); return;}
+}
+
+#line 854 "runtime.in"
+// curlSpecifier operator curl(real gamma, Int p);
+void gen_runtime96(stack *Stack)
+{
+ Int p=vm::pop<Int>(Stack);
+ real gamma=vm::pop<real>(Stack);
+#line 855 "runtime.in"
+ camp::side s=(camp::side) p;
+ {Stack->push<curlSpecifier>(curlSpecifier(gamma,s)); return;}
+}
+
+#line 860 "runtime.in"
+void curlSpecifierValuePart(stack *Stack)
+{
+ curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
+#line 861 "runtime.in"
+ {Stack->push<real>(spec.getValue()); return;}
+}
+
+#line 865 "runtime.in"
+void curlSpecifierSidePart(stack *Stack)
+{
+ curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
+#line 866 "runtime.in"
+ {Stack->push<Int>(spec.getSide()); return;}
+}
+
+#line 870 "runtime.in"
+// guide* operator cast(curlSpecifier spec);
+void gen_runtime99(stack *Stack)
+{
+ curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
+#line 871 "runtime.in"
+ {Stack->push<guide*>(new specguide(spec)); return;}
+}
+
+#line 875 "runtime.in"
+// tensionSpecifier operator tension(real tout, real tin, bool atleast);
+void gen_runtime100(stack *Stack)
+{
+ bool atleast=vm::pop<bool>(Stack);
+ real tin=vm::pop<real>(Stack);
+ real tout=vm::pop<real>(Stack);
+#line 876 "runtime.in"
+ {Stack->push<tensionSpecifier>(tensionSpecifier(tout, tin, atleast)); return;}
+}
+
+#line 880 "runtime.in"
+void tensionSpecifierOutPart(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 881 "runtime.in"
+ {Stack->push<real>(t.getOut()); return;}
+}
+
+#line 885 "runtime.in"
+void tensionSpecifierInPart(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 886 "runtime.in"
+ {Stack->push<real>(t.getIn()); return;}
+}
+
+#line 890 "runtime.in"
+void tensionSpecifierAtleastPart(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 891 "runtime.in"
+ {Stack->push<bool>(t.getAtleast()); return;}
+}
+
+#line 895 "runtime.in"
+// guide* operator cast(tensionSpecifier t);
+void gen_runtime104(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 896 "runtime.in"
+ {Stack->push<guide*>(new tensionguide(t)); return;}
+}
+
+#line 900 "runtime.in"
+// guide* operator controls(pair zout, pair zin);
+void gen_runtime105(stack *Stack)
+{
+ pair zin=vm::pop<pair>(Stack);
+ pair zout=vm::pop<pair>(Stack);
+#line 901 "runtime.in"
+ {Stack->push<guide*>(new controlguide(zout, zin)); return;}
+}
+
+#line 905 "runtime.in"
+// Int size(guide *g);
+void gen_runtime106(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 906 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<Int>(f.size()); return;}
+}
+
+#line 912 "runtime.in"
+// Int length(guide *g);
+void gen_runtime107(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 913 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<Int>(g->cyclic() ? f.size() : f.size()-1); return;}
+}
+
+#line 919 "runtime.in"
+// bool cyclic(guide *g);
+void gen_runtime108(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 920 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<bool>(g->cyclic()); return;}
+}
+
+#line 926 "runtime.in"
+// pair point(guide *g, Int t);
+void gen_runtime109(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 927 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<pair>(f.Nodes(adjustedIndex(t,f.size(),g->cyclic())).z); return;}
+}
+
+#line 933 "runtime.in"
+// pairarray* dirSpecifier(guide *g, Int t);
+void gen_runtime110(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 934 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<pairarray*>(new array(0)); return;}
+ array *c=new array(2);
+ (*c)[0]=f.Nodes(t).out->dir();
+ (*c)[1]=f.Nodes(t+1).in->dir();
+ {Stack->push<pairarray*>(c); return;}
+}
+
+#line 945 "runtime.in"
+// pairarray* controlSpecifier(guide *g, Int t);
+void gen_runtime111(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 946 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<pairarray*>(new array(0)); return;}
+ knot curr=f.Nodes(t);
+ knot next=f.Nodes(t+1);
+ if(curr.out->controlled()) {
+ assert(next.in->controlled());
+ array *c=new array(2);
+ (*c)[0]=curr.out->control();
+ (*c)[1]=next.in->control();
+ {Stack->push<pairarray*>(c); return;}
+ } else {Stack->push<pairarray*>(new array(0)); return;}
+}
+
+#line 962 "runtime.in"
+// tensionSpecifier tensionSpecifier(guide *g, Int t);
+void gen_runtime112(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 963 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<tensionSpecifier>(tensionSpecifier(1.0,1.0,false)); return;}
+ knot curr=f.Nodes(t);
+ {Stack->push<tensionSpecifier>(tensionSpecifier(curr.tout.val,f.Nodes(t+1).tin.val,curr.tout.atleast)); return;}
+}
+
+#line 972 "runtime.in"
+// realarray* curlSpecifier(guide *g, Int t);
+void gen_runtime113(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 973 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<realarray*>(new array(0)); return;}
+ array *c=new array(2);
+ real c0=f.Nodes(t).out->curl();
+ real c1=f.Nodes(t+1).in->curl();
+ (*c)[0]=c0 >= 0.0 ? c0 : 1.0;
+ (*c)[1]=c1 >= 0.0 ? c1 : 1.0;
+ {Stack->push<realarray*>(c); return;}
+}
+
+#line 986 "runtime.in"
+// guide* reverse(guide *g);
+void gen_runtime114(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 987 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ if(f.precyclic())
+ {Stack->push<guide*>(new pathguide(g->solve().reverse())); return;}
+
+ size_t n=f.size();
+ bool cyclic=g->cyclic();
+ guidevector v;
+ size_t start=cyclic ? n : n-1;
+ knot curr=f.Nodes(start);
+ knot next=curr;
+ for(size_t i=start; i > 0; --i) {
+ next=f.Nodes(i-1);
+ v.push_back(new pairguide(curr.z));
+ if(next.out->controlled()) {
+ assert(curr.in->controlled());
+ v.push_back(new controlguide(curr.in->control(),next.out->control()));
+ } else {
+ pair d=curr.in->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::OUT));
+ else {
+ real C=curr.in->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::OUT));
+ }
+ real tout=curr.tin.val;
+ real tin=next.tout.val;
+ bool atleast=next.tout.atleast;
+ if(tout != 1.0 || tin != 1.0 || next.tout.atleast)
+ v.push_back(new tensionguide(tensionSpecifier(tout,tin,atleast)));
+ d=next.out->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::IN));
+ else {
+ real C=next.out->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::IN));
+ }
+ }
+ curr=next;
+ }
+ if(cyclic)
+ v.push_back(new cycletokguide());
+ else
+ v.push_back(new pairguide(next.z));
+
+ {Stack->push<guide*>(new multiguide(v)); return;}
+}
+
+#line 1039 "runtime.in"
+// realarray* _cputime();
+void gen_runtime115(stack *Stack)
+{
+#line 1040 "runtime.in"
+ static const real ticktime=1.0/sysconf(_SC_CLK_TCK);
+ struct tms buf;
+
+ ::times(&buf);
+ array *t=new array(4);
+ (*t)[0] = ((real) buf.tms_utime)*ticktime;
+ (*t)[1] = ((real) buf.tms_stime)*ticktime;
+ (*t)[2] = ((real) buf.tms_cutime)*ticktime;
+ (*t)[3] = ((real) buf.tms_cstime)*ticktime;
+ {Stack->push<realarray*>(t); return;}
+}
+
+
+// Transforms
+#line 1055 "runtime.in"
+// bool ==(transform a, transform b);
+void gen_runtime116(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 1056 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 1061 "runtime.in"
+// bool !=(transform a, transform b);
+void gen_runtime117(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 1062 "runtime.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 1066 "runtime.in"
+// transform +(transform a, transform b);
+void gen_runtime118(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 1067 "runtime.in"
+ {Stack->push<transform>(a+b); return;}
+}
+
+#line 1071 "runtime.in"
+// transform *(transform a, transform b);
+void gen_runtime119(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 1072 "runtime.in"
+ {Stack->push<transform>(a*b); return;}
+}
+
+#line 1076 "runtime.in"
+// pair *(transform t, pair z);
+void gen_runtime120(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 1077 "runtime.in"
+ {Stack->push<pair>(t*z); return;}
+}
+
+#line 1081 "runtime.in"
+// path *(transform t, path g);
+void gen_runtime121(stack *Stack)
+{
+ path g=vm::pop<path>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 1082 "runtime.in"
+ {Stack->push<path>(transformed(t,g)); return;}
+}
+
+#line 1086 "runtime.in"
+// pen *(transform t, pen p);
+void gen_runtime122(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 1087 "runtime.in"
+ {Stack->push<pen>(transformed(t,p)); return;}
+}
+
+#line 1091 "runtime.in"
+// picture* *(transform t, picture *f);
+void gen_runtime123(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 1092 "runtime.in"
+ {Stack->push<picture*>(transformed(t,f)); return;}
+}
+
+#line 1096 "runtime.in"
+// picture* *(realarray2 *t, picture *f);
+void gen_runtime124(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+#line 1097 "runtime.in"
+ {Stack->push<picture*>(transformed(*t,f)); return;}
+}
+
+#line 1101 "runtime.in"
+// transform ^(transform t, Int n);
+void gen_runtime125(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 1102 "runtime.in"
+ transform T;
+ if(n < 0) {
+ n=-n;
+ t=inverse(t);
+ }
+ for(Int i=0; i < n; i++) T=T*t;
+ {Stack->push<transform>(T); return;}
+}
+
+#line 1112 "runtime.in"
+void transformXPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1113 "runtime.in"
+ {Stack->push<real>(t.getx()); return;}
+}
+
+#line 1117 "runtime.in"
+void transformYPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1118 "runtime.in"
+ {Stack->push<real>(t.gety()); return;}
+}
+
+#line 1122 "runtime.in"
+void transformXXPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1123 "runtime.in"
+ {Stack->push<real>(t.getxx()); return;}
+}
+
+#line 1127 "runtime.in"
+void transformXYPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1128 "runtime.in"
+ {Stack->push<real>(t.getxy()); return;}
+}
+
+#line 1132 "runtime.in"
+void transformYXPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1133 "runtime.in"
+ {Stack->push<real>(t.getyx()); return;}
+}
+
+#line 1137 "runtime.in"
+void transformYYPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1138 "runtime.in"
+ {Stack->push<real>(t.getyy()); return;}
+}
+
+#line 1142 "runtime.in"
+void real6ToTransform(stack *Stack)
+{
+ real yy=vm::pop<real>(Stack);
+ real yx=vm::pop<real>(Stack);
+ real xy=vm::pop<real>(Stack);
+ real xx=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 1144 "runtime.in"
+ {Stack->push<transform>(transform(x,y,xx,xy,yx,yy)); return;}
+}
+
+#line 1148 "runtime.in"
+// transform shift(transform t);
+void gen_runtime133(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1149 "runtime.in"
+ {Stack->push<transform>(transform(t.getx(),t.gety(),0,0,0,0)); return;}
+}
+
+#line 1153 "runtime.in"
+// transform shiftless(transform t);
+void gen_runtime134(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1154 "runtime.in"
+ {Stack->push<transform>(transform(0,0,t.getxx(),t.getxy(),t.getyx(),t.getyy())); return;}
+}
+
+#line 1158 "runtime.in"
+// transform identity();
+void transformIdentity(stack *Stack)
+{
+#line 1159 "runtime.in"
+ {Stack->push<transform>(identity); return;}
+}
+
+#line 1163 "runtime.in"
+// transform inverse(transform t);
+void gen_runtime136(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 1164 "runtime.in"
+ {Stack->push<transform>(inverse(t)); return;}
+}
+
+#line 1168 "runtime.in"
+// transform shift(pair z);
+void gen_runtime137(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 1169 "runtime.in"
+ {Stack->push<transform>(shift(z)); return;}
+}
+
+#line 1173 "runtime.in"
+// transform shift(real x, real y);
+void gen_runtime138(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 1174 "runtime.in"
+ {Stack->push<transform>(shift(pair(x,y))); return;}
+}
+
+#line 1178 "runtime.in"
+// transform xscale(real x);
+void gen_runtime139(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 1179 "runtime.in"
+ {Stack->push<transform>(xscale(x)); return;}
+}
+
+#line 1183 "runtime.in"
+// transform yscale(real y);
+void gen_runtime140(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+#line 1184 "runtime.in"
+ {Stack->push<transform>(yscale(y)); return;}
+}
+
+#line 1188 "runtime.in"
+// transform scale(real x);
+void gen_runtime141(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 1189 "runtime.in"
+ {Stack->push<transform>(scale(x)); return;}
+}
+
+#line 1193 "runtime.in"
+// transform scale(real x, real y);
+void gen_runtime142(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 1194 "runtime.in"
+ {Stack->push<transform>(scale(x,y)); return;}
+}
+
+#line 1198 "runtime.in"
+// transform slant(real s);
+void gen_runtime143(stack *Stack)
+{
+ real s=vm::pop<real>(Stack);
+#line 1199 "runtime.in"
+ {Stack->push<transform>(slant(s)); return;}
+}
+
+#line 1203 "runtime.in"
+// transform rotate(real angle, pair z=0);
+void gen_runtime144(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack,0);
+ real angle=vm::pop<real>(Stack);
+#line 1204 "runtime.in"
+ {Stack->push<transform>(rotatearound(z,radians(angle))); return;}
+}
+
+#line 1208 "runtime.in"
+// transform reflect(pair a, pair b);
+void gen_runtime145(stack *Stack)
+{
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 1209 "runtime.in"
+ {Stack->push<transform>(reflectabout(a,b)); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runtime_venv(venv &ve)
+{
+#line 228 "runtime.in"
+ REGISTER_BLTIN(run::IntZero,"IntZero");
+#line 236 "runtime.in"
+ REGISTER_BLTIN(run::realZero,"realZero");
+#line 241 "runtime.in"
+ REGISTER_BLTIN(run::boolFalse,"boolFalse");
+#line 246 "runtime.in"
+ addFunc(ve, run::gen_runtime3, primBoolean(), SYM(isnan), formal(primReal(), SYM(x), false, false));
+#line 251 "runtime.in"
+ REGISTER_BLTIN(run::pushNullArray,"pushNullArray");
+#line 256 "runtime.in"
+ REGISTER_BLTIN(run::pushNullRecord,"pushNullRecord");
+#line 261 "runtime.in"
+ REGISTER_BLTIN(run::pushNullFunction,"pushNullFunction");
+#line 266 "runtime.in"
+ REGISTER_BLTIN(run::pushDefault,"pushDefault");
+#line 276 "runtime.in"
+ REGISTER_BLTIN(run::isDefault,"isDefault");
+#line 283 "runtime.in"
+ REGISTER_BLTIN(run::pairToGuide,"pairToGuide");
+#line 291 "runtime.in"
+ REGISTER_BLTIN(run::pathToGuide,"pathToGuide");
+#line 296 "runtime.in"
+ REGISTER_BLTIN(run::guideToPath,"guideToPath");
+#line 301 "runtime.in"
+ REGISTER_BLTIN(run::newPen,"newPen");
+#line 309 "runtime.in"
+ addFunc(ve, run::gen_runtime13, primBoolean(), SYM_EQ, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
+#line 314 "runtime.in"
+ addFunc(ve, run::gen_runtime14, primBoolean(), SYM_NEQ, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
+#line 319 "runtime.in"
+ addFunc(ve, run::gen_runtime15, primPen(), SYM_PLUS, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
+#line 324 "runtime.in"
+ addFunc(ve, run::gen_runtime16, primPen(), SYM_TIMES, formal(primReal(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
+#line 329 "runtime.in"
+ addFunc(ve, run::gen_runtime17, primPen(), SYM_TIMES, formal(primPen(), SYM(a), false, false), formal(primReal(), SYM(b), false, false));
+#line 334 "runtime.in"
+ addFunc(ve, run::gen_runtime18, primPair(), SYM(max), formal(primPen(), SYM(p), false, false));
+#line 339 "runtime.in"
+ addFunc(ve, run::gen_runtime19, primPair(), SYM(min), formal(primPen(), SYM(p), false, false));
+#line 344 "runtime.in"
+ addFunc(ve, run::gen_runtime20, primVoid(), SYM(resetdefaultpen));
+#line 350 "runtime.in"
+ addFunc(ve, run::gen_runtime21, primVoid(), SYM(defaultpen), formal(primPen(), SYM(p), false, false));
+#line 355 "runtime.in"
+ addFunc(ve, run::gen_runtime22, primPen(), SYM(defaultpen));
+#line 360 "runtime.in"
+ addFunc(ve, run::gen_runtime23, primBoolean(), SYM(invisible), formal(primPen(), SYM(p), false, false));
+#line 365 "runtime.in"
+ addFunc(ve, run::gen_runtime24, primPen(), SYM(invisible));
+#line 370 "runtime.in"
+ addFunc(ve, run::gen_runtime25, primPen(), SYM(gray), formal(primPen(), SYM(p), false, false));
+#line 376 "runtime.in"
+ addFunc(ve, run::gen_runtime26, primPen(), SYM(rgb), formal(primPen(), SYM(p), false, false));
+#line 382 "runtime.in"
+ addFunc(ve, run::gen_runtime27, primPen(), SYM(cmyk), formal(primPen(), SYM(p), false, false));
+#line 388 "runtime.in"
+ addFunc(ve, run::gen_runtime28, primPen(), SYM(interp), formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false), formal(primReal(), SYM(t), false, false));
+#line 393 "runtime.in"
+ addFunc(ve, run::gen_runtime29, primPen(), SYM(rgb), formal(primReal(), SYM(r), false, false), formal(primReal(), SYM(g), false, false), formal(primReal(), SYM(b), false, false));
+#line 398 "runtime.in"
+ addFunc(ve, run::gen_runtime30, primPen(), SYM(cmyk), formal(primReal(), SYM(c), false, false), formal(primReal(), SYM(m), false, false), formal(primReal(), SYM(y), false, false), formal(primReal(), SYM(k), false, false));
+#line 403 "runtime.in"
+ addFunc(ve, run::gen_runtime31, primPen(), SYM(gray), formal(primReal(), SYM(gray), false, false));
+#line 408 "runtime.in"
+ addFunc(ve, run::gen_runtime32, realArray(), SYM(colors), formal(primPen(), SYM(p), false, false));
+#line 436 "runtime.in"
+ addFunc(ve, run::gen_runtime33, primString() , SYM(hex), formal(primPen(), SYM(p), false, false));
+#line 441 "runtime.in"
+ addFunc(ve, run::gen_runtime34, primInt(), SYM(byte), formal(primReal(), SYM(x), false, false));
+#line 446 "runtime.in"
+ addFunc(ve, run::gen_runtime35, primString() , SYM(colorspace), formal(primPen(), SYM(p), false, false));
+#line 453 "runtime.in"
+ addFunc(ve, run::gen_runtime36, primPen(), SYM(pattern), formal(primString(), SYM(s), false, false));
+#line 458 "runtime.in"
+ addFunc(ve, run::gen_runtime37, primString() , SYM(pattern), formal(primPen(), SYM(p), false, false));
+#line 463 "runtime.in"
+ addFunc(ve, run::gen_runtime38, primPen(), SYM(fillrule), formal(primInt(), SYM(n), false, false));
+#line 468 "runtime.in"
+ addFunc(ve, run::gen_runtime39, primInt(), SYM(fillrule), formal(primPen(), SYM(p), false, false));
+#line 473 "runtime.in"
+ addFunc(ve, run::gen_runtime40, primPen(), SYM(opacity), formal(primReal(), SYM(opacity), true, false), formal(primString() , SYM(blend), true, false));
+#line 483 "runtime.in"
+ addFunc(ve, run::gen_runtime41, primReal(), SYM(opacity), formal(primPen(), SYM(p), false, false));
+#line 488 "runtime.in"
+ addFunc(ve, run::gen_runtime42, primString() , SYM(blend), formal(primPen(), SYM(p), false, false));
+#line 493 "runtime.in"
+ addFunc(ve, run::gen_runtime43, primPen(), SYM(linetype), formal(realArray(), SYM(pattern), false, false), formal(primReal(), SYM(offset), true, false), formal(primBoolean(), SYM(scale), true, false), formal(primBoolean(), SYM(adjust), true, false));
+#line 504 "runtime.in"
+ addFunc(ve, run::gen_runtime44, realArray(), SYM(linetype), formal(primPen(), SYM(p), true, false));
+#line 510 "runtime.in"
+ addFunc(ve, run::gen_runtime45, primReal(), SYM(offset), formal(primPen(), SYM(p), false, false));
+#line 515 "runtime.in"
+ addFunc(ve, run::gen_runtime46, primBoolean(), SYM(scale), formal(primPen(), SYM(p), false, false));
+#line 520 "runtime.in"
+ addFunc(ve, run::gen_runtime47, primBoolean(), SYM(adjust), formal(primPen(), SYM(p), false, false));
+#line 525 "runtime.in"
+ addFunc(ve, run::gen_runtime48, primPen(), SYM(adjust), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(arclength), false, false), formal(primBoolean(), SYM(cyclic), false, false));
+#line 530 "runtime.in"
+ addFunc(ve, run::gen_runtime49, primPen(), SYM(linecap), formal(primInt(), SYM(n), false, false));
+#line 535 "runtime.in"
+ addFunc(ve, run::gen_runtime50, primInt(), SYM(linecap), formal(primPen(), SYM(p), true, false));
+#line 540 "runtime.in"
+ addFunc(ve, run::gen_runtime51, primPen(), SYM(linejoin), formal(primInt(), SYM(n), false, false));
+#line 545 "runtime.in"
+ addFunc(ve, run::gen_runtime52, primInt(), SYM(linejoin), formal(primPen(), SYM(p), true, false));
+#line 550 "runtime.in"
+ addFunc(ve, run::gen_runtime53, primPen(), SYM(miterlimit), formal(primReal(), SYM(x), false, false));
+#line 555 "runtime.in"
+ addFunc(ve, run::gen_runtime54, primReal(), SYM(miterlimit), formal(primPen(), SYM(p), true, false));
+#line 560 "runtime.in"
+ addFunc(ve, run::gen_runtime55, primPen(), SYM(linewidth), formal(primReal(), SYM(x), false, false));
+#line 565 "runtime.in"
+ addFunc(ve, run::gen_runtime56, primReal(), SYM(linewidth), formal(primPen(), SYM(p), true, false));
+#line 570 "runtime.in"
+ addFunc(ve, run::gen_runtime57, primPen(), SYM(fontcommand), formal(primString(), SYM(s), false, false));
+#line 575 "runtime.in"
+ addFunc(ve, run::gen_runtime58, primString() , SYM(font), formal(primPen(), SYM(p), true, false));
+#line 580 "runtime.in"
+ addFunc(ve, run::gen_runtime59, primPen(), SYM(fontsize), formal(primReal(), SYM(size), false, false), formal(primReal(), SYM(lineskip), false, false));
+#line 586 "runtime.in"
+ addFunc(ve, run::gen_runtime60, primReal(), SYM(fontsize), formal(primPen(), SYM(p), true, false));
+#line 591 "runtime.in"
+ addFunc(ve, run::gen_runtime61, primReal(), SYM(lineskip), formal(primPen(), SYM(p), true, false));
+#line 596 "runtime.in"
+ addFunc(ve, run::gen_runtime62, primPen(), SYM(overwrite), formal(primInt(), SYM(n), false, false));
+#line 602 "runtime.in"
+ addFunc(ve, run::gen_runtime63, primInt(), SYM(overwrite), formal(primPen(), SYM(p), true, false));
+#line 607 "runtime.in"
+ addFunc(ve, run::gen_runtime64, primPen(), SYM(basealign), formal(primInt(), SYM(n), false, false));
+#line 612 "runtime.in"
+ addFunc(ve, run::gen_runtime65, primInt(), SYM(basealign), formal(primPen(), SYM(p), true, false));
+#line 617 "runtime.in"
+ addFunc(ve, run::gen_runtime66, primTransform(), SYM(transform), formal(primPen(), SYM(p), false, false));
+#line 622 "runtime.in"
+ addFunc(ve, run::gen_runtime67, primPath(), SYM(nib), formal(primPen(), SYM(p), false, false));
+#line 627 "runtime.in"
+ addFunc(ve, run::gen_runtime68, primPen(), SYM(makepen), formal(primPath(), SYM(p), false, false));
+#line 632 "runtime.in"
+ addFunc(ve, run::gen_runtime69, primPen(), SYM(colorless), formal(primPen(), SYM(p), false, false));
+#line 638 "runtime.in"
+ addFunc(ve, run::gen_runtime70, primBoolean(), SYM(interactive));
+#line 645 "runtime.in"
+ addFunc(ve, run::gen_runtime71, primBoolean(), SYM(uptodate));
+#line 650 "runtime.in"
+ addFunc(ve, run::gen_runtime72, primInt(), SYM(system), formal(stringArray(), SYM(s), false, false));
+#line 664 "runtime.in"
+ addFunc(ve, run::gen_runtime73, primBoolean(), SYM(view));
+#line 669 "runtime.in"
+ addFunc(ve, run::gen_runtime74, primString() , SYM(asydir));
+#line 674 "runtime.in"
+ addFunc(ve, run::gen_runtime75, primString() , SYM(locale), formal(primString() , SYM(s), true, false));
+#line 680 "runtime.in"
+ addFunc(ve, run::gen_runtime76, primVoid(), SYM(abort), formal(primString() , SYM(s), true, false));
+#line 686 "runtime.in"
+ addFunc(ve, run::gen_runtime77, primVoid(), SYM(exit));
+#line 691 "runtime.in"
+ addFunc(ve, run::gen_runtime78, primVoid(), SYM(assert), formal(primBoolean(), SYM(b), false, false), formal(primString() , SYM(s), true, false));
+#line 702 "runtime.in"
+ addFunc(ve, run::gen_runtime79, primVoid(), SYM(sleep), formal(primInt(), SYM(seconds), false, false));
+#line 708 "runtime.in"
+ addFunc(ve, run::gen_runtime80, primVoid(), SYM(usleep), formal(primInt(), SYM(microseconds), false, false));
+#line 714 "runtime.in"
+ addFunc(ve, run::gen_runtime81, primVoid(), SYM(_eval), formal(primString(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false), formal(primBoolean(), SYM(interactivewrite), true, false));
+#line 727 "runtime.in"
+ addFunc(ve, run::gen_runtime82, primVoid(), SYM(_eval), formal(primCode(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false));
+#line 743 "runtime.in"
+ addFunc(ve, run::gen_runtime83, primString() , SYM(xasyKEY));
+#line 750 "runtime.in"
+ addFunc(ve, run::gen_runtime84, primVoid(), SYM(xasyKEY), formal(primString(), SYM(s), false, false));
+#line 754 "runtime.in"
+ addFunc(ve, run::gen_runtime85, primString() , SYM(toplocation));
+#line 758 "runtime.in"
+ addFunc(ve, run::gen_runtime86, primString() , SYM(location));
+#line 764 "runtime.in"
+ REGISTER_BLTIN(run::loadModule,"loadModule");
+#line 770 "runtime.in"
+ addFunc(ve, run::gen_runtime88, primString() , SYM(cd), formal(primString() , SYM(s), true, false));
+#line 780 "runtime.in"
+ addFunc(ve, run::gen_runtime89, primVoid(), SYM(list), formal(primString(), SYM(s), false, false), formal(primBoolean(), SYM(imports), true, false));
+#line 789 "runtime.in"
+ REGISTER_BLTIN(run::nullGuide,"nullGuide");
+#line 797 "runtime.in"
+ REGISTER_BLTIN(run::dotsGuide,"dotsGuide");
+#line 807 "runtime.in"
+ REGISTER_BLTIN(run::dashesGuide,"dashesGuide");
+#line 834 "runtime.in"
+ REGISTER_BLTIN(run::newCycleToken,"newCycleToken");
+#line 839 "runtime.in"
+ addFunc(ve, run::gen_runtime94, primGuide(), symbol::trans("operator cast"), formal(primCycleToken(), SYM(tok), false, false));
+#line 846 "runtime.in"
+ addFunc(ve, run::gen_runtime95, primGuide(), symbol::trans("operator spec"), formal(primPair(), SYM(z), false, false), formal(primInt(), SYM(p), false, false));
+#line 854 "runtime.in"
+ addFunc(ve, run::gen_runtime96, primCurlSpecifier(), SYM_CURL, formal(primReal(), SYM(gamma), false, false), formal(primInt(), SYM(p), false, false));
+#line 860 "runtime.in"
+ REGISTER_BLTIN(run::curlSpecifierValuePart,"curlSpecifierValuePart");
+#line 865 "runtime.in"
+ REGISTER_BLTIN(run::curlSpecifierSidePart,"curlSpecifierSidePart");
+#line 870 "runtime.in"
+ addFunc(ve, run::gen_runtime99, primGuide(), symbol::trans("operator cast"), formal(primCurlSpecifier(), SYM(spec), false, false));
+#line 875 "runtime.in"
+ addFunc(ve, run::gen_runtime100, primTensionSpecifier(), SYM_TENSION, formal(primReal(), SYM(tout), false, false), formal(primReal(), SYM(tin), false, false), formal(primBoolean(), SYM(atleast), false, false));
+#line 880 "runtime.in"
+ REGISTER_BLTIN(run::tensionSpecifierOutPart,"tensionSpecifierOutPart");
+#line 885 "runtime.in"
+ REGISTER_BLTIN(run::tensionSpecifierInPart,"tensionSpecifierInPart");
+#line 890 "runtime.in"
+ REGISTER_BLTIN(run::tensionSpecifierAtleastPart,"tensionSpecifierAtleastPart");
+#line 895 "runtime.in"
+ addFunc(ve, run::gen_runtime104, primGuide(), symbol::trans("operator cast"), formal(primTensionSpecifier(), SYM(t), false, false));
+#line 900 "runtime.in"
+ addFunc(ve, run::gen_runtime105, primGuide(), SYM_CONTROLS, formal(primPair(), SYM(zout), false, false), formal(primPair(), SYM(zin), false, false));
+#line 905 "runtime.in"
+ addFunc(ve, run::gen_runtime106, primInt(), SYM(size), formal(primGuide(), SYM(g), false, false));
+#line 912 "runtime.in"
+ addFunc(ve, run::gen_runtime107, primInt(), SYM(length), formal(primGuide(), SYM(g), false, false));
+#line 919 "runtime.in"
+ addFunc(ve, run::gen_runtime108, primBoolean(), SYM(cyclic), formal(primGuide(), SYM(g), false, false));
+#line 926 "runtime.in"
+ addFunc(ve, run::gen_runtime109, primPair(), SYM(point), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
+#line 933 "runtime.in"
+ addFunc(ve, run::gen_runtime110, pairArray(), SYM(dirSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
+#line 945 "runtime.in"
+ addFunc(ve, run::gen_runtime111, pairArray(), SYM(controlSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
+#line 962 "runtime.in"
+ addFunc(ve, run::gen_runtime112, primTensionSpecifier(), SYM(tensionSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
+#line 972 "runtime.in"
+ addFunc(ve, run::gen_runtime113, realArray(), SYM(curlSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
+#line 986 "runtime.in"
+ addFunc(ve, run::gen_runtime114, primGuide(), SYM(reverse), formal(primGuide(), SYM(g), false, false));
+#line 1039 "runtime.in"
+ addFunc(ve, run::gen_runtime115, realArray(), SYM(_cputime));
+#line 1053 "runtime.in"
+ addFunc(ve, run::gen_runtime116, primBoolean(), SYM_EQ, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
+#line 1061 "runtime.in"
+ addFunc(ve, run::gen_runtime117, primBoolean(), SYM_NEQ, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
+#line 1066 "runtime.in"
+ addFunc(ve, run::gen_runtime118, primTransform(), SYM_PLUS, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
+#line 1071 "runtime.in"
+ addFunc(ve, run::gen_runtime119, primTransform(), SYM_TIMES, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
+#line 1076 "runtime.in"
+ addFunc(ve, run::gen_runtime120, primPair(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPair(), SYM(z), false, false));
+#line 1081 "runtime.in"
+ addFunc(ve, run::gen_runtime121, primPath(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPath(), SYM(g), false, false));
+#line 1086 "runtime.in"
+ addFunc(ve, run::gen_runtime122, primPen(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPen(), SYM(p), false, false));
+#line 1091 "runtime.in"
+ addFunc(ve, run::gen_runtime123, primPicture(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPicture(), SYM(f), false, false));
+#line 1096 "runtime.in"
+ addFunc(ve, run::gen_runtime124, primPicture(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primPicture(), SYM(f), false, false));
+#line 1101 "runtime.in"
+ addFunc(ve, run::gen_runtime125, primTransform(), SYM_CARET, formal(primTransform(), SYM(t), false, false), formal(primInt(), SYM(n), false, false));
+#line 1112 "runtime.in"
+ REGISTER_BLTIN(run::transformXPart,"transformXPart");
+#line 1117 "runtime.in"
+ REGISTER_BLTIN(run::transformYPart,"transformYPart");
+#line 1122 "runtime.in"
+ REGISTER_BLTIN(run::transformXXPart,"transformXXPart");
+#line 1127 "runtime.in"
+ REGISTER_BLTIN(run::transformXYPart,"transformXYPart");
+#line 1132 "runtime.in"
+ REGISTER_BLTIN(run::transformYXPart,"transformYXPart");
+#line 1137 "runtime.in"
+ REGISTER_BLTIN(run::transformYYPart,"transformYYPart");
+#line 1142 "runtime.in"
+ REGISTER_BLTIN(run::real6ToTransform,"real6ToTransform");
+#line 1148 "runtime.in"
+ addFunc(ve, run::gen_runtime133, primTransform(), SYM(shift), formal(primTransform(), SYM(t), false, false));
+#line 1153 "runtime.in"
+ addFunc(ve, run::gen_runtime134, primTransform(), SYM(shiftless), formal(primTransform(), SYM(t), false, false));
+#line 1158 "runtime.in"
+ addFunc(ve, run::transformIdentity, primTransform(), SYM(identity));
+#line 1163 "runtime.in"
+ addFunc(ve, run::gen_runtime136, primTransform(), SYM(inverse), formal(primTransform(), SYM(t), false, false));
+#line 1168 "runtime.in"
+ addFunc(ve, run::gen_runtime137, primTransform(), SYM(shift), formal(primPair(), SYM(z), false, false));
+#line 1173 "runtime.in"
+ addFunc(ve, run::gen_runtime138, primTransform(), SYM(shift), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
+#line 1178 "runtime.in"
+ addFunc(ve, run::gen_runtime139, primTransform(), SYM(xscale), formal(primReal(), SYM(x), false, false));
+#line 1183 "runtime.in"
+ addFunc(ve, run::gen_runtime140, primTransform(), SYM(yscale), formal(primReal(), SYM(y), false, false));
+#line 1188 "runtime.in"
+ addFunc(ve, run::gen_runtime141, primTransform(), SYM(scale), formal(primReal(), SYM(x), false, false));
+#line 1193 "runtime.in"
+ addFunc(ve, run::gen_runtime142, primTransform(), SYM(scale), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
+#line 1198 "runtime.in"
+ addFunc(ve, run::gen_runtime143, primTransform(), SYM(slant), formal(primReal(), SYM(s), false, false));
+#line 1203 "runtime.in"
+ addFunc(ve, run::gen_runtime144, primTransform(), SYM(rotate), formal(primReal(), SYM(angle), false, false), formal(primPair(), SYM(z), true, false));
+#line 1208 "runtime.in"
+ addFunc(ve, run::gen_runtime145, primTransform(), SYM(reflect), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runtime.h b/graphics/asymptote/runtime.h
new file mode 100644
index 0000000000..e7864e5441
--- /dev/null
+++ b/graphics/asymptote/runtime.h
@@ -0,0 +1,38 @@
+/***** Autogenerated from runtime.in; changes will be overwritten *****/
+
+#ifndef runtime_H
+#define runtime_H
+namespace run {
+void IntZero(vm::stack *);
+void realZero(vm::stack *);
+void boolFalse(vm::stack *);
+void pushNullArray(vm::stack *);
+void pushNullRecord(vm::stack *);
+void pushNullFunction(vm::stack *);
+void pushDefault(vm::stack *);
+void isDefault(vm::stack *);
+void pairToGuide(vm::stack *);
+void pathToGuide(vm::stack *);
+void guideToPath(vm::stack *);
+void newPen(vm::stack *);
+void loadModule(vm::stack *);
+void nullGuide(vm::stack *);
+void dotsGuide(vm::stack *);
+void dashesGuide(vm::stack *);
+void newCycleToken(vm::stack *);
+void curlSpecifierValuePart(vm::stack *);
+void curlSpecifierSidePart(vm::stack *);
+void tensionSpecifierOutPart(vm::stack *);
+void tensionSpecifierInPart(vm::stack *);
+void tensionSpecifierAtleastPart(vm::stack *);
+void transformXPart(vm::stack *);
+void transformYPart(vm::stack *);
+void transformXXPart(vm::stack *);
+void transformXYPart(vm::stack *);
+void transformYXPart(vm::stack *);
+void transformYYPart(vm::stack *);
+void real6ToTransform(vm::stack *);
+void transformIdentity(vm::stack *);
+}
+
+#endif // runtime_H
diff --git a/graphics/asymptote/runtime.in b/graphics/asymptote/runtime.in
new file mode 100644
index 0000000000..7db30dd589
--- /dev/null
+++ b/graphics/asymptote/runtime.in
@@ -0,0 +1,1212 @@
+/*****
+ * runtime.in
+ * Tom Prince 2005/4/15
+ *
+ * Generate the runtime functions used by the vm::stack machine.
+ *
+ *****/
+
+/* Autogenerated routines are specified like this (separated by a formfeed):
+ type asyname:cname(cparams)
+ {
+ C code
+ }
+
+*/
+
+// Use Void f() instead of void f() to force an explicit Stack argument.
+
+
+pen => primPen()
+pair => primPair()
+triple => primTriple()
+path => primPath()
+path3 => primPath3()
+guide* => primGuide()
+cycleToken => primCycleToken()
+tensionSpecifier => primTensionSpecifier()
+curlSpecifier => primCurlSpecifier()
+file* => primFile()
+picture* => primPicture()
+transform => primTransform()
+callable* => voidFunction()
+callableBp* => breakpointFunction()
+callableReal* => realRealFunction()
+callableTransform* => transformFunction()
+runnable* => primCode()
+boolarray* => booleanArray()
+Intarray* => IntArray()
+Intarray2* => IntArray2()
+realarray* => realArray()
+realarray2* => realArray2()
+pairarray* => pairArray()
+pairarray2* => pairArray2()
+triplearray* => tripleArray()
+triplearray2* => tripleArray2()
+patharray* => pathArray()
+patharray2* => pathArray2()
+guidearray* => guideArray()
+transformarray* => transformArray()
+penarray* => penArray()
+penarray2* => penArray2()
+stringarray* => stringArray()
+stringarray2* => stringArray2()
+
+#include <cfloat>
+#include <iostream>
+#include <fstream>
+#include <time.h>
+#include <sys/times.h>
+#include <locale.h>
+
+#include "angle.h"
+#include "pair.h"
+#include "triple.h"
+#include "transform.h"
+#include "path.h"
+#include "path3.h"
+#include "pen.h"
+#include "drawpath.h"
+#include "guide.h"
+#include "picture.h"
+#include "fileio.h"
+#include "genv.h"
+#include "builtin.h"
+#include "texfile.h"
+#include "pipestream.h"
+#include "parser.h"
+#include "stack.h"
+#include "util.h"
+#include "locate.h"
+#include "mathop.h"
+#include "callable.h"
+#include "stm.h"
+#include "lexical.h"
+#include "process.h"
+#include "arrayop.h"
+
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ extern "C" {
+ void *GC_generate_random_valid_address(void);
+ void GC_debug_print_heap_obj_proc(void *);
+ }
+#endif
+
+using namespace vm;
+using namespace camp;
+using namespace settings;
+
+#undef OUT
+#undef IN
+
+namespace run {
+using camp::pair;
+using vm::array;
+using vm::frame;
+using vm::stack;
+using camp::transform;
+using absyntax::runnable;
+
+typedef array boolarray;
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray;
+typedef array triplearray2;
+typedef array patharray;
+typedef array patharray2;
+typedef array guidearray;
+typedef array transformarray;
+typedef array penarray;
+typedef array penarray2;
+typedef array stringarray;
+typedef array stringarray2;
+
+typedef callable callableBp;
+typedef callable callableReal;
+typedef callable callableTransform;
+}
+
+using vm::array;
+using types::function;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+using types::booleanArray;
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray;
+using types::tripleArray2;
+using types::pathArray;
+using types::pathArray2;
+using types::guideArray;
+using types::transformArray;
+using types::penArray;
+using types::penArray2;
+using types::stringArray;
+using types::stringArray2;
+using types::formal;
+
+function *realRealFunction()
+{
+ return new function(primReal(),primReal());
+}
+
+function *realTripleFunction()
+{
+ return new function(primReal(),primTriple());
+}
+
+const size_t camp::ColorComponents[]={0,0,1,3,4,0};
+
+namespace vm {
+#if COMPACT
+const Int DefaultValue=0x7fffffffffffffffLL;
+const Int Undefined=0x7ffffffffffffffeLL;
+
+const Int BoolTruthValue=0xABABABABABABABACLL;
+const Int BoolFalseValue=0xABABABABABABABABLL;
+
+const item Default=DefaultValue;
+#else
+const item Default=item(default_t());
+#endif
+}
+
+namespace run {
+
+const char *arrayempty="cannot take min or max of empty array";
+const char *noruntime="no runtime environment for embedded eval";
+
+void writestring(stack *s)
+{
+ callable *suffix=pop<callable *>(s,NULL);
+ string S=pop<string>(s);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::ofile *f=defaultfile ? &camp::Stdout : vm::get<camp::ofile*>(it);
+ if(!f->isOpen() || !f->enabled()) return;
+ if(S != "") f->write(S);
+ if(f->text()) {
+ if(suffix) {
+ s->push(f);
+ suffix->call(s);
+ } else if(defaultfile) f->writeline();
+ }
+}
+
+string toplocation() {
+ ostringstream buf;
+ position& topPos=processData().topPos;
+ buf << topPos.Line() << "." << topPos.Column();
+ return buf.str();
+}
+
+string emptystring;
+pair zero;
+
+}
+
+static string defaulttransparency=string("Compatible");
+
+void unused(void *)
+{
+}
+
+// Autogenerated routines:
+
+
+
+// Initializers
+
+Int :IntZero()
+{
+ return 0;
+}
+
+real :realZero()
+{
+ return 0.0;
+}
+
+bool :boolFalse()
+{
+ return false;
+}
+
+bool isnan(real x)
+{
+ return std::isnan(x);
+}
+
+array* :pushNullArray()
+{
+ return 0;
+}
+
+frame* :pushNullRecord()
+{
+ return 0;
+}
+
+item :pushNullFunction()
+{
+ return nullfunc::instance();
+}
+
+
+// Default operations
+
+// Put the default value token on the stack (in place of an argument when
+// making a function call).
+item :pushDefault()
+{
+ return Default;
+}
+
+
+// Test if the value on the stack is the default value token.
+bool :isDefault(item i)
+{
+ return isdefault(i);
+}
+
+
+// Casts
+
+guide* :pairToGuide(pair z)
+{
+ return new pairguide(z);
+}
+
+guide* :pathToGuide(path p)
+{
+ return new pathguide(p);
+}
+
+path :guideToPath(guide *g)
+{
+ return g->solve();
+}
+
+
+// Pen operations
+
+pen :newPen()
+{
+ return pen();
+}
+
+bool ==(pen a, pen b)
+{
+ return a == b;
+}
+
+bool !=(pen a, pen b)
+{
+ return a != b;
+}
+
+pen +(pen a, pen b)
+{
+ return a+b;
+}
+
+pen Operator *(real a, pen b)
+{
+ return a*b;
+}
+
+pen Operator *(pen a, real b)
+{
+ return b*a;
+}
+
+pair max(pen p)
+{
+ return p.bounds().Max();
+}
+
+pair min(pen p)
+{
+ return p.bounds().Min();
+}
+
+// Reset the meaning of pen default attributes.
+void resetdefaultpen()
+{
+ processData().defaultpen=camp::pen::initialpen();
+}
+
+void defaultpen(pen p)
+{
+ processData().defaultpen=pen(resolvepen,p);
+}
+
+pen defaultpen()
+{
+ return processData().defaultpen;
+}
+
+bool invisible(pen p)
+{
+ return p.invisible();
+}
+
+pen invisible()
+{
+ return pen(invisiblepen);
+}
+
+pen gray(pen p)
+{
+ p.togrey();
+ return p;
+}
+
+pen rgb(pen p)
+{
+ p.torgb();
+ return p;
+}
+
+pen cmyk(pen p)
+{
+ p.tocmyk();
+ return p;
+}
+
+pen interp(pen a, pen b, real t)
+{
+ return interpolate(a,b,t);
+}
+
+pen rgb(real r, real g, real b)
+{
+ return pen(r,g,b);
+}
+
+pen cmyk(real c, real m, real y, real k)
+{
+ return pen(c,m,y,k);
+}
+
+pen gray(real gray)
+{
+ return pen(gray);
+}
+
+realarray *colors(pen p)
+{
+ size_t n=ColorComponents[p.colorspace()];
+ array *a=new array(n);
+
+ switch(n) {
+ case 0:
+ break;
+ case 1:
+ (*a)[0]=p.gray();
+ break;
+ case 3:
+ (*a)[0]=p.red();
+ (*a)[1]=p.green();
+ (*a)[2]=p.blue();
+ break;
+ case 4:
+ (*a)[0]=p.cyan();
+ (*a)[1]=p.magenta();
+ (*a)[2]=p.yellow();
+ (*a)[3]=p.black();
+ break;
+ default:
+ break;
+ }
+ return a;
+}
+
+string hex(pen p)
+{
+ return p.hex();
+}
+
+Int byte(real x)
+{
+ return camp::byte(x);
+}
+
+string colorspace(pen p)
+{
+ string s=ColorDeviceSuffix[p.colorspace()];
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ return s;
+}
+
+pen pattern(string *s)
+{
+ return pen(setpattern,*s);
+}
+
+string pattern(pen p)
+{
+ return p.fillpattern();
+}
+
+pen fillrule(Int n)
+{
+ return pen(n >= 0 && n < nFill ? (FillRule) n : DEFFILL);
+}
+
+Int fillrule(pen p)
+{
+ return p.Fillrule();
+}
+
+pen opacity(real opacity=1.0, string blend=defaulttransparency)
+{
+ for(Int i=0; i < nBlendMode; ++i)
+ if(blend == BlendMode[i]) return pen(Transparency(blend,opacity));
+
+ ostringstream buf;
+ buf << "Unknown blend mode: " << "'" << blend << "'";
+ error(buf);
+}
+
+real opacity(pen p)
+{
+ return p.opacity();
+}
+
+string blend(pen p)
+{
+ return p.blend();
+}
+
+pen linetype(realarray *pattern, real offset=0, bool scale=true,
+ bool adjust=true)
+{
+ size_t size=checkArray(pattern);
+ array *a=new array(size);
+ for(size_t i=0; i < size; ++i)
+ (*a)[i]=::max(vm::read<double>(pattern,i),0.0);
+
+ return pen(LineType(*a,offset,scale,adjust));
+}
+
+realarray *linetype(pen p=CURRENTPEN)
+{
+ array a=p.linetype()->pattern;
+ return copyArray(&a);
+}
+
+real offset(pen p)
+{
+ return p.linetype()->offset;
+}
+
+bool scale(pen p)
+{
+ return p.linetype()->scale;
+}
+
+bool adjust(pen p)
+{
+ return p.linetype()->adjust;
+}
+
+pen adjust(pen p, real arclength, bool cyclic)
+{
+ return adjustdash(p,arclength,cyclic);
+}
+
+pen linecap(Int n)
+{
+ return pen(setlinecap,n >= 0 && n < nCap ? n : DEFCAP);
+}
+
+Int linecap(pen p=CURRENTPEN)
+{
+ return p.cap();
+}
+
+pen linejoin(Int n)
+{
+ return pen(setlinejoin,n >= 0 && n < nJoin ? n : DEFJOIN);
+}
+
+Int linejoin(pen p=CURRENTPEN)
+{
+ return p.join();
+}
+
+pen miterlimit(real x)
+{
+ return pen(setmiterlimit,x >= 1.0 ? x : DEFJOIN);
+}
+
+real miterlimit(pen p=CURRENTPEN)
+{
+ return p.miter();
+}
+
+pen linewidth(real x)
+{
+ return pen(setlinewidth,x >= 0.0 ? x : DEFWIDTH);
+}
+
+real linewidth(pen p=CURRENTPEN)
+{
+ return p.width();
+}
+
+pen fontcommand(string *s)
+{
+ return pen(setfont,*s);
+}
+
+string font(pen p=CURRENTPEN)
+{
+ return p.Font();
+}
+
+pen fontsize(real size, real lineskip)
+{
+ return pen(setfontsize,size > 0.0 ? size : 0.0,
+ lineskip > 0.0 ? lineskip : 0.0);
+}
+
+real fontsize(pen p=CURRENTPEN)
+{
+ return p.size();
+}
+
+real lineskip(pen p=CURRENTPEN)
+{
+ return p.Lineskip();
+}
+
+pen overwrite(Int n)
+{
+ return pen(setoverwrite,n >= 0 && n < nOverwrite ? (overwrite_t) n :
+ DEFWRITE);
+}
+
+Int overwrite(pen p=CURRENTPEN)
+{
+ return p.Overwrite();
+}
+
+pen basealign(Int n)
+{
+ return pen(n >= 0 && n < nBaseLine ? (BaseLine) n : DEFBASE);
+}
+
+Int basealign(pen p=CURRENTPEN)
+{
+ return p.Baseline();
+}
+
+transform transform(pen p)
+{
+ return p.getTransform();
+}
+
+path nib(pen p)
+{
+ return p.Path();
+}
+
+pen makepen(path p)
+{
+ return pen(p);
+}
+
+pen colorless(pen p)
+{
+ p.colorless();
+ return p;
+}
+
+// Interactive mode
+
+bool interactive()
+{
+ return interact::interactive;
+}
+
+bool uptodate()
+{
+ return interact::uptodate;
+}
+
+
+// System commands
+
+Int system(stringarray *s)
+{
+ if(safe) error("system() call disabled; override with option -nosafe");
+ size_t size=checkArray(s);
+ if(size == 0) return 0;
+ mem::vector<string> cmd;
+ for(size_t i=0; i < size; ++i)
+ cmd.push_back(read<string>(s,i));
+ return System(cmd);
+}
+
+bool view()
+{
+ return view();
+}
+
+string asydir()
+{
+ return systemDir;
+}
+
+string locale(string s=emptystring)
+{
+ char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str());
+ return L != NULL ? string(L) : "";
+}
+
+void abort(string s=emptystring)
+{
+ if(s.empty()) throw handled_error();
+ error(s.c_str());
+}
+
+void exit()
+{
+ throw quit();
+}
+
+void assert(bool b, string s=emptystring)
+{
+ flush(cout);
+ if(!b) {
+ ostringstream buf;
+ buf << "assert FAILED";
+ if(s != "") buf << ": " << s;
+ error(buf);
+ }
+}
+
+void sleep(Int seconds)
+{
+ if(seconds <= 0) return;
+ sleep(seconds);
+}
+
+void usleep(Int microseconds)
+{
+ if(microseconds <= 0) return;
+ usleep((unsigned long) microseconds);
+}
+
+void _eval(string *s, bool embedded, bool interactiveWrite=false)
+{
+ if(embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if(e && is)
+ runStringEmbedded(*s, *e, *is);
+ else
+ error(noruntime);
+ } else
+ runString(*s,interactiveWrite);
+}
+
+void _eval(runnable *s, bool embedded)
+{
+ absyntax::block *ast=new absyntax::block(s->getPos(), false);
+ ast->add(s);
+
+ if(embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if(e && is)
+ runCodeEmbedded(ast, *e, *is);
+ else
+ error(noruntime);
+ } else
+ runCode(ast);
+}
+
+string xasyKEY() {
+ processDataStruct *P=&processData();
+ xkey_t *xkey=&P->xkey;
+ xkey_t::iterator p=xkey->find(P->topPos.LineColumn());
+ return p != xkey->end() ? p->second+" 1" : toplocation()+" 0";
+}
+
+void xasyKEY(string *s) {
+ processData().KEY=*s;
+}
+
+string toplocation() {
+ return toplocation();
+}
+
+string location() {
+ ostringstream buf;
+ buf << getPos();
+ return buf.str();
+}
+
+// Wrapper for the stack::load() method.
+void :loadModule(string *index)
+{
+ Stack->load(*index);
+}
+
+string cd(string s=emptystring)
+{
+ if(!s.empty() && !globalwrite()) {
+ string outname=getSetting<string>("outname");
+ string dir=stripDir(outname);
+ if(dir.empty()) Setting("outname")=getPath()+dirsep+outname;
+ }
+ return setPath(s.c_str());
+}
+
+void list(string *s, bool imports=false)
+{
+ if(*s == "-") return;
+ trans::genv ge;
+ symbol name=symbol::trans(*s);
+ record *r=ge.getModule(name,*s);
+ r->e.list(imports ? 0 : r);
+}
+
+
+// Guide operations
+
+guide* :nullGuide()
+{
+ return new pathguide(path());
+}
+
+guide* :dotsGuide(guidearray *a)
+{
+ guidevector v;
+ size_t size=checkArray(a);
+ for (size_t i=0; i < size; ++i)
+ v.push_back(a->read<guide*>(i));
+
+ return new multiguide(v);
+}
+
+guide* :dashesGuide(guidearray *a)
+{
+ static camp::curlSpec curly;
+ static camp::specguide curlout(&curly, camp::OUT);
+ static camp::specguide curlin(&curly, camp::IN);
+
+ size_t n=checkArray(a);
+
+ // a--b is equivalent to a{curl 1}..{curl 1}b
+ guidevector v;
+ if (n > 0)
+ v.push_back(a->read<guide*>(0));
+
+ if (n==1) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ }
+ else
+ for (size_t i=1; i<n; ++i) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ v.push_back(a->read<guide*>(i));
+ }
+
+ return new multiguide(v);
+}
+
+cycleToken :newCycleToken()
+{
+ return cycleToken();
+}
+
+guide *operator cast(cycleToken tok)
+{
+// Avoid unused variable warning messages.
+ unused(&tok);
+ return new cycletokguide();
+}
+
+guide* operator spec(pair z, Int p)
+{
+ camp::side d=(camp::side) p;
+ camp::dirSpec *sp=new camp::dirSpec(z);
+
+ return new specguide(sp,d);
+}
+
+curlSpecifier operator curl(real gamma, Int p)
+{
+ camp::side s=(camp::side) p;
+ return curlSpecifier(gamma,s);
+}
+
+real :curlSpecifierValuePart(curlSpecifier spec)
+{
+ return spec.getValue();
+}
+
+Int :curlSpecifierSidePart(curlSpecifier spec)
+{
+ return spec.getSide();
+}
+
+guide *operator cast(curlSpecifier spec)
+{
+ return new specguide(spec);
+}
+
+tensionSpecifier operator tension(real tout, real tin, bool atleast)
+{
+ return tensionSpecifier(tout, tin, atleast);
+}
+
+real :tensionSpecifierOutPart(tensionSpecifier t)
+{
+ return t.getOut();
+}
+
+real :tensionSpecifierInPart(tensionSpecifier t)
+{
+ return t.getIn();
+}
+
+bool :tensionSpecifierAtleastPart(tensionSpecifier t)
+{
+ return t.getAtleast();
+}
+
+guide *operator cast(tensionSpecifier t)
+{
+ return new tensionguide(t);
+}
+
+guide* operator controls(pair zout, pair zin)
+{
+ return new controlguide(zout, zin);
+}
+
+Int size(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return f.size();
+}
+
+Int length(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return g->cyclic() ? f.size() : f.size()-1;
+}
+
+bool cyclic(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return g->cyclic();
+}
+
+pair point(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return f.Nodes(adjustedIndex(t,f.size(),g->cyclic())).z;
+}
+
+pairarray *dirSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return new array(0);
+ array *c=new array(2);
+ (*c)[0]=f.Nodes(t).out->dir();
+ (*c)[1]=f.Nodes(t+1).in->dir();
+ return c;
+}
+
+pairarray *controlSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return new array(0);
+ knot curr=f.Nodes(t);
+ knot next=f.Nodes(t+1);
+ if(curr.out->controlled()) {
+ assert(next.in->controlled());
+ array *c=new array(2);
+ (*c)[0]=curr.out->control();
+ (*c)[1]=next.in->control();
+ return c;
+ } else return new array(0);
+}
+
+tensionSpecifier tensionSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return tensionSpecifier(1.0,1.0,false);
+ knot curr=f.Nodes(t);
+ return tensionSpecifier(curr.tout.val,f.Nodes(t+1).tin.val,curr.tout.atleast);
+}
+
+realarray *curlSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return new array(0);
+ array *c=new array(2);
+ real c0=f.Nodes(t).out->curl();
+ real c1=f.Nodes(t+1).in->curl();
+ (*c)[0]=c0 >= 0.0 ? c0 : 1.0;
+ (*c)[1]=c1 >= 0.0 ? c1 : 1.0;
+ return c;
+}
+
+guide *reverse(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ if(f.precyclic())
+ return new pathguide(g->solve().reverse());
+
+ size_t n=f.size();
+ bool cyclic=g->cyclic();
+ guidevector v;
+ size_t start=cyclic ? n : n-1;
+ knot curr=f.Nodes(start);
+ knot next=curr;
+ for(size_t i=start; i > 0; --i) {
+ next=f.Nodes(i-1);
+ v.push_back(new pairguide(curr.z));
+ if(next.out->controlled()) {
+ assert(curr.in->controlled());
+ v.push_back(new controlguide(curr.in->control(),next.out->control()));
+ } else {
+ pair d=curr.in->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::OUT));
+ else {
+ real C=curr.in->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::OUT));
+ }
+ real tout=curr.tin.val;
+ real tin=next.tout.val;
+ bool atleast=next.tout.atleast;
+ if(tout != 1.0 || tin != 1.0 || next.tout.atleast)
+ v.push_back(new tensionguide(tensionSpecifier(tout,tin,atleast)));
+ d=next.out->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::IN));
+ else {
+ real C=next.out->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::IN));
+ }
+ }
+ curr=next;
+ }
+ if(cyclic)
+ v.push_back(new cycletokguide());
+ else
+ v.push_back(new pairguide(next.z));
+
+ return new multiguide(v);
+}
+
+
+realarray *_cputime()
+{
+ static const real ticktime=1.0/sysconf(_SC_CLK_TCK);
+ struct tms buf;
+
+ ::times(&buf);
+ array *t=new array(4);
+ (*t)[0] = ((real) buf.tms_utime)*ticktime;
+ (*t)[1] = ((real) buf.tms_stime)*ticktime;
+ (*t)[2] = ((real) buf.tms_cutime)*ticktime;
+ (*t)[3] = ((real) buf.tms_cstime)*ticktime;
+ return t;
+}
+
+
+// Transforms
+
+bool ==(transform a, transform b)
+{
+ return a == b;
+}
+
+bool !=(transform a, transform b)
+{
+ return a != b;
+}
+
+transform +(transform a, transform b)
+{
+ return a+b;
+}
+
+transform Operator *(transform a, transform b)
+{
+ return a*b;
+}
+
+pair Operator *(transform t, pair z)
+{
+ return t*z;
+}
+
+path Operator *(transform t, path g)
+{
+ return transformed(t,g);
+}
+
+pen Operator *(transform t, pen p)
+{
+ return transformed(t,p);
+}
+
+picture * Operator *(transform t, picture *f)
+{
+ return transformed(t,f);
+}
+
+picture * Operator *(realarray2 *t, picture *f)
+{
+ return transformed(*t,f);
+}
+
+transform ^(transform t, Int n)
+{
+ transform T;
+ if(n < 0) {
+ n=-n;
+ t=inverse(t);
+ }
+ for(Int i=0; i < n; i++) T=T*t;
+ return T;
+}
+
+real :transformXPart(transform t)
+{
+ return t.getx();
+}
+
+real :transformYPart(transform t)
+{
+ return t.gety();
+}
+
+real :transformXXPart(transform t)
+{
+ return t.getxx();
+}
+
+real :transformXYPart(transform t)
+{
+ return t.getxy();
+}
+
+real :transformYXPart(transform t)
+{
+ return t.getyx();
+}
+
+real :transformYYPart(transform t)
+{
+ return t.getyy();
+}
+
+transform :real6ToTransform(real x, real y, real xx, real xy,
+ real yx, real yy)
+{
+ return transform(x,y,xx,xy,yx,yy);
+}
+
+transform shift(transform t)
+{
+ return transform(t.getx(),t.gety(),0,0,0,0);
+}
+
+transform shiftless(transform t)
+{
+ return transform(0,0,t.getxx(),t.getxy(),t.getyx(),t.getyy());
+}
+
+transform identity:transformIdentity()
+{
+ return identity;
+}
+
+transform inverse(transform t)
+{
+ return inverse(t);
+}
+
+transform shift(pair z)
+{
+ return shift(z);
+}
+
+transform shift(real x, real y)
+{
+ return shift(pair(x,y));
+}
+
+transform xscale(real x)
+{
+ return xscale(x);
+}
+
+transform yscale(real y)
+{
+ return yscale(y);
+}
+
+transform scale(real x)
+{
+ return scale(x);
+}
+
+transform scale(real x, real y)
+{
+ return scale(x,y);
+}
+
+transform slant(real s)
+{
+ return slant(s);
+}
+
+transform rotate(real angle, pair z=0)
+{
+ return rotatearound(z,radians(angle));
+}
+
+transform reflect(pair a, pair b)
+{
+ return reflectabout(a,b);
+}
+
diff --git a/graphics/asymptote/runtime.pl b/graphics/asymptote/runtime.pl
new file mode 100755
index 0000000000..5724b40f8e
--- /dev/null
+++ b/graphics/asymptote/runtime.pl
@@ -0,0 +1,294 @@
+#!/usr/bin/env perl
+######
+# runtime.pl
+# Tom Prince 2004/4/15
+#
+# Generate the runtime functions used by the vm::stack machine.
+#
+#####
+
+$prefix = shift(@ARGV);
+if (not $prefix) {
+ print STDERR "usage: ./runtime.pl module_name\n";
+ exit(1);
+}
+
+$stack = "Stack";
+
+my $errors = 0;
+
+sub report_error {
+ my $filename = shift;
+ my $line = shift;
+ my $error = shift;
+ print STDERR "$filename:$line: $error\n";
+ $errors = 1;
+}
+
+sub assoc_error {
+ my $filename = shift;
+ my $line = shift;
+ my $type = shift;
+ report_error($filename, $line, "no asy type associated to '$type'");
+}
+
+sub clean_type {
+ for (@_) {
+ s/\s//g;
+ }
+}
+
+sub clean_params {
+ for (@_) {
+ s/\n//g;
+ }
+}
+
+my %type_map;
+sub read_types {
+ my @types = split /\n/, shift;
+ my $filename = shift;
+ my $line = shift;
+ for (@types) {
+ ++$line;
+ # Remove // comments.
+ s/\/\/.*//g;
+
+ # Skip blank lines.
+ next if /^\s*$/;
+
+ my ($type,$code) =
+ m|(\w*(?:\s*\*)?)
+ \s*=>\s*
+ (.*)
+ |x;
+ if (not $type) {
+ report_error($filename, $line, "bad type declaration");
+ }
+ clean_type($type);
+ $type_map{$type} = $code;
+ }
+}
+
+# Scrape the symbol names of the operators from opsymbols.h.
+my %opsymbols = ();
+open(opsyms, "opsymbols.h") ||
+ die("Couldn't open opsymbols.h");
+while (<opsyms>) {
+ if (m/^OPSYMBOL\(\"(.*)\", ([A-Za-z_]+)\);/) {
+ $opsymbols{ $1 } = $2;
+ }
+}
+
+# Turn a name into a symbol.
+sub symbolize {
+ my $name = shift;
+ if ($name =~ /^[A-Za-z0-9_]+$/) {
+ return "SYM($name)";
+ }
+ if ($opsymbols{ $name }) {
+ return $opsymbols{ $name };
+ }
+ if ($name =~ /operator (\w+)/ && $opsymbols{ $1 }) {
+ return $opsymbols{ $1 }
+ }
+ return "symbol::trans(\"" . $name . "\")"
+}
+
+sub asy_params {
+ my $params = shift;
+ my @params = split m/,\s*/, $params;
+ my $filename = shift;
+ my $line = shift;
+ for (@params) {
+ my ($explicit, $type, $name, $default) =
+ m|^\s*
+ (explicit)*\s*(\w*(?:\s*\*)?)
+ \s*
+ (\w*)(=*)|xs;
+ clean_type($type);
+ if (not $type_map{$type}) {
+ assoc_error($filename, $line, $type);
+ }
+ $_ = "formal(" . $type_map{$type} . ", " .
+ symbolize(lc($name)) . ", " .
+ ($default ? "true" : "false") . ", " .
+ ($explicit ? "true" : "false") . ")";
+ }
+ return @params;
+}
+
+sub c_params {
+ my @params = @_;
+ for (@params) {
+ my ($explicit, $type, $name, $default, $value) =
+ m|^\s*
+ (explicit)*\s*(\w*(?:\s*\*)?)
+ \s*
+ (\w*)(=*)([\w.+\-]*)|xs;
+ $_ = " $type $name=vm::pop" . ($type =~ /^item$/ ? "" : "<$type>") .
+ "($stack" . ($default ? "," . $value : "") . ");\n";
+ }
+ reverse @params;
+}
+
+$/ = "\f\n";
+
+open STDIN, "<$prefix.in" or die "can't open input file $prefix.in";
+open BASE, "<runtimebase.in" or die "can't open runtimebase.in";
+open STDOUT, ">$prefix.cc" or die "can't open output file $prefix.cc";
+
+my $autogenerated=
+"/***** Autogenerated from $prefix.in; changes will be overwritten *****/\n\n";
+
+my $base_source_line = 1;
+my $source_line = 1;
+
+print $autogenerated;
+
+print "#line $base_source_line \"runtimebase.in\"\n";
+$baseheader = <BASE>;
+print $baseheader;
+$basesource_line += ($baseheader =~ tr/\n//);;
+my $basesource_type_line = $basesource_line;
+
+print "#line $source_line \"$prefix.in\"\n";
+$header = <>;
+print $header;
+$source_line += ($header =~ tr/\n//);;
+my $source_type_line = $source_line;
+
+$basetypes = <BASE>;
+$basesource_line += ($basetypes =~ tr/\n//);;
+
+$types = <>;
+$source_line += ($types =~ tr/\n//);;
+
+print "#line $base_source_line \"runtimebase.in\"\n";
+$baseheader = <BASE>;
+print $baseheader;
+$basesource_line += ($baseheader =~ tr/\n//);;
+
+print "#line $source_line \"$prefix.in\"\n";
+$header = <>;
+print $header;
+$source_line += ($header =~ tr/\n//);;
+
+print "\n#ifndef NOSYM";
+print "\n#include \"$prefix.symbols.h\"\n";
+print "\n#endif";
+print "\nnamespace run {\n";
+
+read_types($basetypes, "runtimebase.in", $basesource_type_line);
+
+read_types($types, "$prefix.in", $source_type_line);
+
+### Begining of `$prefix.h'
+push @header, $autogenerated;
+# TODO: Capitalize prefix
+push @header, "#ifndef " . $prefix . "_H\n";
+push @header, "#define " . $prefix . "_H\n";
+push @header, "namespace run {\n";
+
+my $count = 0;
+while (<>) {
+ my ($comments,$type,$name,$cname,$params,$code) =
+ m|^((?:\s*//[^\n]*\n)*) # comment lines
+ \s*
+ (\w*(?:\s*\*)?) # return type
+ \s*
+ ([^(:]*)\:*([^(]*) # function name
+ \s*
+ \(([\w\s*,=.+\-]*)\) # parameters
+ \s*
+ \{(.*)} # body
+ |xs;
+
+ if (not $type) {
+ report_error("$prefix.in", $source_line, "bad function definition");
+ }
+
+ if($cname) {push @header, "void $cname(vm::stack *);\n";}
+ else {$cname="gen_$prefix${count}";} # Unique C++ function name
+
+ clean_type($type);
+
+ my @params = split m/,\s*/, $params;
+
+ # Build addFunc call for asymptote
+ if($name) {
+ $name =~ s/Operator\s*//;
+ if (not $type_map{$type}) {
+ assoc_error("$prefix.in", $source_line, $type);
+ }
+ my @asy_params = asy_params($params, "$prefix.in", $source_line);
+ push @builtin, "#line $source_line \"$prefix.in\"\n"
+ . " addFunc(ve, run::" . $cname
+ . ", " . $type_map{$type}
+ . ", " . symbolize($name)
+ . ( @params ? ", " . join(", ",@asy_params)
+ : "" )
+ . ");\n";
+ }
+
+ # Build REGISTER_BLTIN command for builtin functions which are not added to
+ # the environment.
+ if (not $name and $cname) {
+ push @builtin, "#line $source_line \"$prefix.in\"\n"
+ . " REGISTER_BLTIN(run::" . $cname
+ . ',"' . $cname . '"' . ");\n";
+ }
+
+ # Handle marshalling of values to/from stack
+ $qualifier = ($type eq "item" ? "" : "<$type>");
+ $code =~ s/\breturn ([^;]*);/{$stack->push$qualifier($1); return;}/g;
+ $args = join("",c_params(@params));
+
+ print $comments;
+ $ncomments = ($comments =~ tr/\n//);
+ $source_line += $ncomments;
+ print "#line $source_line \"$prefix.in\"\n";
+ my $prototype=$type . " " . $name . "(" . $params . ");";
+ $nprototype = ($prototype =~ tr/\n//)+1;
+ $source_line += $nprototype;
+ if($name) {
+ clean_params($prototype);
+ print "// $prototype\n";
+ }
+ print "void $cname(stack *";
+ if($type ne "void" or $params ne "") {print $stack;}
+ print ")\n{\n$args";
+ print "#line $source_line \"$prefix.in\"";
+ print "$code}\n\n";
+
+ $source_line -= $ncomments+$nprototype;
+ $source_line += ($_ =~ tr/\n//);
+ ++$count;
+}
+
+print "} // namespace run\n";
+
+print "\nnamespace trans {\n\n";
+print "void gen_${prefix}_venv(venv &ve)\n{\n";
+print @builtin;
+print "}\n\n";
+print "} // namespace trans\n";
+
+### End of `header.h'
+push @header, "}\n\n";
+push @header, "#endif // ". $prefix . "_H\n";
+
+undef $/;
+open HEADER, "<", "$prefix.h";
+$orig_header = <HEADER>;
+$new_header = join "", @header;
+if ($new_header ne $orig_header) {
+ open HEADER, ">", "$prefix.h";
+ print HEADER $new_header;
+}
+
+if ($errors) {
+ unlink("$prefix.h");
+ unlink("$prefix.cc");
+}
+exit($errors);
diff --git a/graphics/asymptote/runtimebase.in b/graphics/asymptote/runtimebase.in
new file mode 100644
index 0000000000..86237de351
--- /dev/null
+++ b/graphics/asymptote/runtimebase.in
@@ -0,0 +1,64 @@
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+// Basic types need by almost all .in files.
+
+// Use Void f() instead of void f() to force an explicit Stack argument.
+void => primVoid()
+Void => primVoid()
+
+Int => primInt()
+bool => primBoolean()
+double => primReal()
+real => primReal()
+string* => primString()
+string => primString()
+
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
diff --git a/graphics/asymptote/runtriple.cc b/graphics/asymptote/runtriple.cc
new file mode 100644
index 0000000000..a8732e2096
--- /dev/null
+++ b/graphics/asymptote/runtriple.cc
@@ -0,0 +1,422 @@
+/***** Autogenerated from runtriple.in; changes will be overwritten *****/
+
+#line 1 "runtimebase.in"
+/*****
+ * runtimebase.in
+ * Andy Hammerlindl 2009/07/28
+ *
+ * Common declarations needed for all code-generating .in files.
+ *
+ *****/
+
+
+#line 1 "runtriple.in"
+/*****
+ * runtriple.in
+ *
+ * Runtime functions for triple operations.
+ *
+ *****/
+
+#line 1 "runtimebase.in"
+#include "stack.h"
+#include "types.h"
+#include "builtin.h"
+#include "entry.h"
+#include "errormsg.h"
+#include "array.h"
+#include "triple.h"
+#include "callable.h"
+#include "opsymbols.h"
+
+using vm::stack;
+using vm::error;
+using vm::array;
+using vm::read;
+using vm::callable;
+using types::formal;
+using types::function;
+using camp::triple;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+typedef double real;
+
+void unused(void *);
+
+namespace run {
+array *copyArray(array *a);
+array *copyArray2(array *a);
+array *copyArray3(array *a);
+
+double *copyTripleArray2Components(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+triple *copyTripleArray2C(array *a, size_t &N,
+ GCPlacement placement=NoGC);
+}
+
+function *realRealFunction();
+
+#define CURRENTPEN processData().currentpen
+
+#line 10 "runtriple.in"
+#include "triple.h"
+#include "path3.h"
+
+using namespace camp;
+
+// Autogenerated routines:
+
+
+
+#ifndef NOSYM
+#include "runtriple.symbols.h"
+
+#endif
+namespace run {
+#line 18 "runtriple.in"
+void tripleZero(stack *Stack)
+{
+#line 19 "runtriple.in"
+ static triple zero;
+ {Stack->push<triple>(zero); return;}
+}
+
+#line 24 "runtriple.in"
+void realRealRealToTriple(stack *Stack)
+{
+ real z=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 25 "runtriple.in"
+ {Stack->push<triple>(triple(x,y,z)); return;}
+}
+
+#line 29 "runtriple.in"
+// real xpart(triple v);
+void tripleXPart(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 30 "runtriple.in"
+ {Stack->push<real>(v.getx()); return;}
+}
+
+#line 34 "runtriple.in"
+// real ypart(triple v);
+void tripleYPart(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 35 "runtriple.in"
+ {Stack->push<real>(v.gety()); return;}
+}
+
+#line 39 "runtriple.in"
+// real zpart(triple v);
+void tripleZPart(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 40 "runtriple.in"
+ {Stack->push<real>(v.getz()); return;}
+}
+
+#line 44 "runtriple.in"
+// triple *(real x, triple v);
+void gen_runtriple5(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 45 "runtriple.in"
+ {Stack->push<triple>(x*v); return;}
+}
+
+#line 49 "runtriple.in"
+// triple *(triple v, real x);
+void gen_runtriple6(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 50 "runtriple.in"
+ {Stack->push<triple>(v*x); return;}
+}
+
+#line 54 "runtriple.in"
+// triple /(triple v, real x);
+void gen_runtriple7(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 55 "runtriple.in"
+ {Stack->push<triple>(v/x); return;}
+}
+
+#line 59 "runtriple.in"
+// real length(triple v);
+void gen_runtriple8(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 60 "runtriple.in"
+ {Stack->push<real>(v.length()); return;}
+}
+
+#line 64 "runtriple.in"
+// real abs(triple v);
+void gen_runtriple9(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 65 "runtriple.in"
+ {Stack->push<real>(v.length()); return;}
+}
+
+#line 69 "runtriple.in"
+// real polar(triple v, bool warn=true);
+void gen_runtriple10(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ triple v=vm::pop<triple>(Stack);
+#line 70 "runtriple.in"
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(v.polar()); return;}
+}
+
+#line 75 "runtriple.in"
+// real azimuth(triple v, bool warn=true);
+void gen_runtriple11(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ triple v=vm::pop<triple>(Stack);
+#line 76 "runtriple.in"
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(v.azimuth()); return;}
+}
+
+#line 81 "runtriple.in"
+// real colatitude(triple v, bool warn=true);
+void gen_runtriple12(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ triple v=vm::pop<triple>(Stack);
+#line 82 "runtriple.in"
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(degrees(v.polar())); return;}
+}
+
+#line 87 "runtriple.in"
+// real latitude(triple v, bool warn=true);
+void gen_runtriple13(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ triple v=vm::pop<triple>(Stack);
+#line 88 "runtriple.in"
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(90.0-degrees(v.polar())); return;}
+}
+
+// Return the longitude of v in [0,360).
+#line 94 "runtriple.in"
+// real longitude(triple v, bool warn=true);
+void gen_runtriple14(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ triple v=vm::pop<triple>(Stack);
+#line 95 "runtriple.in"
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(principalBranch(degrees(v.azimuth()))); return;}
+}
+
+#line 100 "runtriple.in"
+// triple unit(triple v);
+void gen_runtriple15(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 101 "runtriple.in"
+ {Stack->push<triple>(unit(v)); return;}
+}
+
+#line 105 "runtriple.in"
+// real dot(triple u, triple v);
+void gen_runtriple16(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ triple u=vm::pop<triple>(Stack);
+#line 106 "runtriple.in"
+ {Stack->push<real>(dot(u,v)); return;}
+}
+
+#line 110 "runtriple.in"
+// triple cross(triple u, triple v);
+void gen_runtriple17(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ triple u=vm::pop<triple>(Stack);
+#line 111 "runtriple.in"
+ {Stack->push<triple>(cross(u,v)); return;}
+}
+
+#line 115 "runtriple.in"
+// triple dir(explicit triple z);
+void gen_runtriple18(stack *Stack)
+{
+ triple z=vm::pop<triple>(Stack);
+#line 116 "runtriple.in"
+ {Stack->push<triple>(unit(z)); return;}
+}
+
+#line 120 "runtriple.in"
+// triple expi(real polar, real azimuth);
+void gen_runtriple19(stack *Stack)
+{
+ real azimuth=vm::pop<real>(Stack);
+ real polar=vm::pop<real>(Stack);
+#line 121 "runtriple.in"
+ {Stack->push<triple>(expi(polar,azimuth)); return;}
+}
+
+#line 125 "runtriple.in"
+// triple dir(real colatitude, real longitude);
+void gen_runtriple20(stack *Stack)
+{
+ real longitude=vm::pop<real>(Stack);
+ real colatitude=vm::pop<real>(Stack);
+#line 126 "runtriple.in"
+ {Stack->push<triple>(expi(radians(colatitude),radians(longitude))); return;}
+}
+
+#line 130 "runtriple.in"
+// triple realmult(triple u, triple v);
+void gen_runtriple21(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ triple u=vm::pop<triple>(Stack);
+#line 131 "runtriple.in"
+ {Stack->push<triple>(triple (u.getx()*v.getx(),u.gety()*v.gety(),u.getz()*v.getz())); return;}
+}
+
+// Return the component of vector v perpendicular to a unit vector u.
+#line 136 "runtriple.in"
+// triple perp(triple v, triple u);
+void gen_runtriple22(stack *Stack)
+{
+ triple u=vm::pop<triple>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 137 "runtriple.in"
+ {Stack->push<triple>(perp(v,u)); return;}
+}
+
+#line 141 "runtriple.in"
+// triple bezier(triple a, triple b, triple c, triple d, real t);
+void gen_runtriple23(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ triple d=vm::pop<triple>(Stack);
+ triple c=vm::pop<triple>(Stack);
+ triple b=vm::pop<triple>(Stack);
+ triple a=vm::pop<triple>(Stack);
+#line 142 "runtriple.in"
+ real onemt=1-t;
+ real onemt2=onemt*onemt;
+ {Stack->push<triple>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
+}
+
+#line 148 "runtriple.in"
+// triple bezierP(triple a, triple b, triple c, triple d, real t);
+void gen_runtriple24(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ triple d=vm::pop<triple>(Stack);
+ triple c=vm::pop<triple>(Stack);
+ triple b=vm::pop<triple>(Stack);
+ triple a=vm::pop<triple>(Stack);
+#line 149 "runtriple.in"
+ {Stack->push<triple>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
+}
+
+#line 153 "runtriple.in"
+// triple bezierPP(triple a, triple b, triple c, triple d, real t);
+void gen_runtriple25(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ triple d=vm::pop<triple>(Stack);
+ triple c=vm::pop<triple>(Stack);
+ triple b=vm::pop<triple>(Stack);
+ triple a=vm::pop<triple>(Stack);
+#line 154 "runtriple.in"
+ {Stack->push<triple>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
+}
+
+#line 158 "runtriple.in"
+// triple bezierPPP(triple a, triple b, triple c, triple d);
+void gen_runtriple26(stack *Stack)
+{
+ triple d=vm::pop<triple>(Stack);
+ triple c=vm::pop<triple>(Stack);
+ triple b=vm::pop<triple>(Stack);
+ triple a=vm::pop<triple>(Stack);
+#line 159 "runtriple.in"
+ {Stack->push<triple>(6.0*(d-a+3.0*(b-c))); return;}
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_runtriple_venv(venv &ve)
+{
+#line 18 "runtriple.in"
+ REGISTER_BLTIN(run::tripleZero,"tripleZero");
+#line 24 "runtriple.in"
+ REGISTER_BLTIN(run::realRealRealToTriple,"realRealRealToTriple");
+#line 29 "runtriple.in"
+ addFunc(ve, run::tripleXPart, primReal(), SYM(xpart), formal(primTriple(), SYM(v), false, false));
+#line 34 "runtriple.in"
+ addFunc(ve, run::tripleYPart, primReal(), SYM(ypart), formal(primTriple(), SYM(v), false, false));
+#line 39 "runtriple.in"
+ addFunc(ve, run::tripleZPart, primReal(), SYM(zpart), formal(primTriple(), SYM(v), false, false));
+#line 44 "runtriple.in"
+ addFunc(ve, run::gen_runtriple5, primTriple(), SYM_TIMES, formal(primReal(), SYM(x), false, false), formal(primTriple(), SYM(v), false, false));
+#line 49 "runtriple.in"
+ addFunc(ve, run::gen_runtriple6, primTriple(), SYM_TIMES, formal(primTriple(), SYM(v), false, false), formal(primReal(), SYM(x), false, false));
+#line 54 "runtriple.in"
+ addFunc(ve, run::gen_runtriple7, primTriple(), SYM_DIVIDE, formal(primTriple(), SYM(v), false, false), formal(primReal(), SYM(x), false, false));
+#line 59 "runtriple.in"
+ addFunc(ve, run::gen_runtriple8, primReal(), SYM(length), formal(primTriple(), SYM(v), false, false));
+#line 64 "runtriple.in"
+ addFunc(ve, run::gen_runtriple9, primReal(), SYM(abs), formal(primTriple(), SYM(v), false, false));
+#line 69 "runtriple.in"
+ addFunc(ve, run::gen_runtriple10, primReal(), SYM(polar), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 75 "runtriple.in"
+ addFunc(ve, run::gen_runtriple11, primReal(), SYM(azimuth), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 81 "runtriple.in"
+ addFunc(ve, run::gen_runtriple12, primReal(), SYM(colatitude), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 87 "runtriple.in"
+ addFunc(ve, run::gen_runtriple13, primReal(), SYM(latitude), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 93 "runtriple.in"
+ addFunc(ve, run::gen_runtriple14, primReal(), SYM(longitude), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
+#line 100 "runtriple.in"
+ addFunc(ve, run::gen_runtriple15, primTriple(), SYM(unit), formal(primTriple(), SYM(v), false, false));
+#line 105 "runtriple.in"
+ addFunc(ve, run::gen_runtriple16, primReal(), SYM(dot), formal(primTriple(), SYM(u), false, false), formal(primTriple(), SYM(v), false, false));
+#line 110 "runtriple.in"
+ addFunc(ve, run::gen_runtriple17, primTriple(), SYM(cross), formal(primTriple(), SYM(u), false, false), formal(primTriple(), SYM(v), false, false));
+#line 115 "runtriple.in"
+ addFunc(ve, run::gen_runtriple18, primTriple(), SYM(dir), formal(primTriple(), SYM(z), false, true));
+#line 120 "runtriple.in"
+ addFunc(ve, run::gen_runtriple19, primTriple(), SYM(expi), formal(primReal(), SYM(polar), false, false), formal(primReal(), SYM(azimuth), false, false));
+#line 125 "runtriple.in"
+ addFunc(ve, run::gen_runtriple20, primTriple(), SYM(dir), formal(primReal(), SYM(colatitude), false, false), formal(primReal(), SYM(longitude), false, false));
+#line 130 "runtriple.in"
+ addFunc(ve, run::gen_runtriple21, primTriple(), SYM(realmult), formal(primTriple(), SYM(u), false, false), formal(primTriple(), SYM(v), false, false));
+#line 135 "runtriple.in"
+ addFunc(ve, run::gen_runtriple22, primTriple(), SYM(perp), formal(primTriple(), SYM(v), false, false), formal(primTriple(), SYM(u), false, false));
+#line 141 "runtriple.in"
+ addFunc(ve, run::gen_runtriple23, primTriple(), SYM(bezier), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
+#line 148 "runtriple.in"
+ addFunc(ve, run::gen_runtriple24, primTriple(), SYM(bezierP), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
+#line 153 "runtriple.in"
+ addFunc(ve, run::gen_runtriple25, primTriple(), SYM(bezierPP), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
+#line 158 "runtriple.in"
+ addFunc(ve, run::gen_runtriple26, primTriple(), SYM(bezierPPP), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false));
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/runtriple.h b/graphics/asymptote/runtriple.h
new file mode 100644
index 0000000000..aff21b39fc
--- /dev/null
+++ b/graphics/asymptote/runtriple.h
@@ -0,0 +1,13 @@
+/***** Autogenerated from runtriple.in; changes will be overwritten *****/
+
+#ifndef runtriple_H
+#define runtriple_H
+namespace run {
+void tripleZero(vm::stack *);
+void realRealRealToTriple(vm::stack *);
+void tripleXPart(vm::stack *);
+void tripleYPart(vm::stack *);
+void tripleZPart(vm::stack *);
+}
+
+#endif // runtriple_H
diff --git a/graphics/asymptote/runtriple.in b/graphics/asymptote/runtriple.in
new file mode 100644
index 0000000000..b12e9368e0
--- /dev/null
+++ b/graphics/asymptote/runtriple.in
@@ -0,0 +1,162 @@
+/*****
+ * runtriple.in
+ *
+ * Runtime functions for triple operations.
+ *
+ *****/
+
+triple => primTriple()
+
+#include "triple.h"
+#include "path3.h"
+
+using namespace camp;
+
+// Autogenerated routines:
+
+
+triple :tripleZero()
+{
+ static triple zero;
+ return zero;
+}
+
+triple :realRealRealToTriple(real x, real y, real z)
+{
+ return triple(x,y,z);
+}
+
+real xpart:tripleXPart(triple v)
+{
+ return v.getx();
+}
+
+real ypart:tripleYPart(triple v)
+{
+ return v.gety();
+}
+
+real zpart:tripleZPart(triple v)
+{
+ return v.getz();
+}
+
+triple Operator *(real x, triple v)
+{
+ return x*v;
+}
+
+triple Operator *(triple v, real x)
+{
+ return v*x;
+}
+
+triple /(triple v, real x)
+{
+ return v/x;
+}
+
+real length(triple v)
+{
+ return v.length();
+}
+
+real abs(triple v)
+{
+ return v.length();
+}
+
+real polar(triple v, bool warn=true)
+{
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) return 0.0;
+ return v.polar();
+}
+
+real azimuth(triple v, bool warn=true)
+{
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0) return 0.0;
+ return v.azimuth();
+}
+
+real colatitude(triple v, bool warn=true)
+{
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) return 0.0;
+ return degrees(v.polar());
+}
+
+real latitude(triple v, bool warn=true)
+{
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) return 0.0;
+ return 90.0-degrees(v.polar());
+}
+
+// Return the longitude of v in [0,360).
+real longitude(triple v, bool warn=true)
+{
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0) return 0.0;
+ return principalBranch(degrees(v.azimuth()));
+}
+
+triple unit(triple v)
+{
+ return unit(v);
+}
+
+real dot(triple u, triple v)
+{
+ return dot(u,v);
+}
+
+triple cross(triple u, triple v)
+{
+ return cross(u,v);
+}
+
+triple dir(explicit triple z)
+{
+ return unit(z);
+}
+
+triple expi(real polar, real azimuth)
+{
+ return expi(polar,azimuth);
+}
+
+triple dir(real colatitude, real longitude)
+{
+ return expi(radians(colatitude),radians(longitude));
+}
+
+triple realmult(triple u, triple v)
+{
+ return triple (u.getx()*v.getx(),u.gety()*v.gety(),u.getz()*v.getz());
+}
+
+// Return the component of vector v perpendicular to a unit vector u.
+triple perp(triple v, triple u)
+{
+ return perp(v,u);
+}
+
+triple bezier(triple a, triple b, triple c, triple d, real t)
+{
+ real onemt=1-t;
+ real onemt2=onemt*onemt;
+ return onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d);
+}
+
+triple bezierP(triple a, triple b, triple c, triple d, real t)
+{
+ return 3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a);
+}
+
+triple bezierPP(triple a, triple b, triple c, triple d, real t)
+{
+ return 6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b);
+}
+
+triple bezierPPP(triple a, triple b, triple c, triple d)
+{
+ return 6.0*(d-a+3.0*(b-c));
+}
+
diff --git a/graphics/asymptote/seconds.h b/graphics/asymptote/seconds.h
new file mode 100644
index 0000000000..37f8e32cdc
--- /dev/null
+++ b/graphics/asymptote/seconds.h
@@ -0,0 +1,100 @@
+#ifndef __seconds_h__
+#define __seconds_h__ 1
+
+#ifdef _WIN32
+#include <Winsock2.h>
+
+#include <time.h>
+#include <windows.h>
+#include <iostream>
+
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+ #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
+#else
+ #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+#endif
+
+struct timezone
+{
+ int tz_minuteswest; /* minutes W of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+
+// Definition of a gettimeofday function
+
+inline int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+// Define a structure to receive the current Windows filetime
+ FILETIME ft;
+
+// Initialize the present time to 0 and the timezone to UTC
+ unsigned __int64 tmpres = 0;
+ static int tzflag = 0;
+
+ if (NULL != tv)
+ {
+ GetSystemTimeAsFileTime(&ft);
+
+// The GetSystemTimeAsFileTime returns the number of 100 nanosecond
+// intervals since Jan 1, 1601 in a structure. Copy the high bits to
+// the 64 bit tmpres, shift it left by 32 then or in the low 32 bits.
+ tmpres |= ft.dwHighDateTime;
+ tmpres <<= 32;
+ tmpres |= ft.dwLowDateTime;
+
+// Convert to microseconds by dividing by 10
+ tmpres /= 10;
+
+// The Unix epoch starts on Jan 1 1970. Need to subtract the difference
+// in seconds from Jan 1 1601.
+ tmpres -= DELTA_EPOCH_IN_MICROSECS;
+
+// Finally change microseconds to seconds and place in the seconds value.
+// The modulus picks up the microseconds.
+ tv->tv_sec = (long)(tmpres / 1000000UL);
+ tv->tv_usec = (long)(tmpres % 1000000UL);
+ }
+
+ if (NULL != tz)
+ {
+ if (!tzflag)
+ {
+ _tzset();
+ tzflag++;
+ }
+
+// Adjust for the timezone west of Greenwich
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
+ }
+
+ return 0;
+}
+
+#else
+
+#include <sys/time.h>
+
+#endif
+
+namespace utils {
+
+inline double totalseconds()
+{
+ timeval tv;
+ gettimeofday(&tv,NULL);
+ return tv.tv_sec+tv.tv_usec/1000000.0;
+}
+
+inline double seconds()
+{
+ static double lastseconds=totalseconds();
+ double t=totalseconds();
+ double seconds=t-lastseconds;
+ lastseconds=t;
+ return seconds;
+}
+
+}
+
+#endif
diff --git a/graphics/asymptote/settings.cc b/graphics/asymptote/settings.cc
new file mode 100644
index 0000000000..c0478379cd
--- /dev/null
+++ b/graphics/asymptote/settings.cc
@@ -0,0 +1,1695 @@
+/*****
+ * settings.cc
+ * Andy Hammerlindl 2004/05/10
+ *
+ * Declares a list of global variables that act as settings in the system.
+ *****/
+
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cerrno>
+#include <sys/stat.h>
+#include <cfloat>
+#include <locale.h>
+#include <unistd.h>
+#include <algorithm>
+
+#include "common.h"
+
+#if HAVE_GNU_GETOPT_H
+#include <getopt.h>
+#else
+#include "getopt.h"
+#endif
+
+#include "util.h"
+#include "settings.h"
+#include "interact.h"
+#include "locate.h"
+#include "lexical.h"
+#include "record.h"
+#include "env.h"
+#include "item.h"
+#include "refaccess.h"
+#include "pipestream.h"
+#include "array.h"
+
+#ifdef HAVE_LIBCURSES
+extern "C" {
+
+#ifdef HAVE_NCURSES_CURSES_H
+#include <ncurses/curses.h>
+#include <ncurses/term.h>
+#elif HAVE_NCURSES_H
+#include <ncurses.h>
+#include <term.h>
+#elif HAVE_CURSES_H
+#include <curses.h>
+#include <term.h>
+#endif
+}
+#endif
+
+// Workaround broken curses.h files:
+#ifdef clear
+#undef clear
+#endif
+// Workaround broken header file on i386-solaris with g++ 3.4.3.
+#ifdef erase
+#undef erase
+#endif
+
+using vm::item;
+
+using trans::itemRefAccess;
+using trans::refAccess;
+using trans::varEntry;
+using vm::array;
+
+void runFile(const string& filename);
+
+
+namespace settings {
+
+using camp::pair;
+
+#ifdef HAVE_GL
+const bool havegl=true;
+#else
+const bool havegl=false;
+#endif
+
+mode_t mask;
+
+string systemDir=ASYMPTOTE_SYSDIR;
+string defaultEPSdriver="eps2write";
+
+#ifndef __MSDOS__
+
+bool msdos=false;
+string HOME="HOME";
+string docdir=ASYMPTOTE_DOCDIR;
+const char pathSeparator=':';
+#ifdef __APPLE__
+string defaultPSViewer="open";
+string defaultPDFViewer="open";
+#else
+string defaultPSViewer="gv";
+string defaultPDFViewer="acroread";
+#endif
+string defaultGhostscript="gs";
+string defaultGhostscriptLibrary="";
+string defaultDisplay="display";
+string defaultAnimate="animate";
+void queryRegistry() {}
+const string dirsep="/";
+
+#else
+
+bool msdos=true;
+string HOME="USERPROFILE";
+string docdir="c:\\Program Files\\Asymptote";
+const char pathSeparator=';';
+//string defaultPSViewer="gsview32.exe";
+string defaultPSViewer="cmd";
+//string defaultPDFViewer="AcroRd32.exe";
+string defaultPDFViewer="cmd";
+string defaultGhostscript;
+string defaultGhostscriptLibrary;
+//string defaultDisplay="imdisplay";
+string defaultDisplay="cmd";
+//string defaultAnimate="animate";
+string defaultAnimate="cmd";
+const string dirsep="\\";
+
+#include <dirent.h>
+
+// Use key to look up an entry in the MSWindows registry, respecting wild cards
+string getEntry(const string& location, const string& key)
+{
+ string path="/proc/registry"+location+key;
+ size_t star;
+ string head;
+ while((star=path.find("*")) < string::npos) {
+ string prefix=path.substr(0,star);
+ string suffix=path.substr(star+1);
+ size_t slash=suffix.find("/");
+ if(slash < string::npos) {
+ path=suffix.substr(slash);
+ suffix=suffix.substr(0,slash);
+ } else {
+ path=suffix;
+ suffix="";
+ }
+ string directory=head+stripFile(prefix);
+ string file=stripDir(prefix);
+ DIR *dir=opendir(directory.c_str());
+ if(dir == NULL) return "";
+ dirent *p;
+ string rsuffix=suffix;
+ reverse(rsuffix.begin(),rsuffix.end());
+ while((p=readdir(dir)) != NULL) {
+ string dname=p->d_name;
+ string rdname=dname;
+ reverse(rdname.begin(),rdname.end());
+ if(dname != "." && dname != ".." &&
+ dname.substr(0,file.size()) == file &&
+ rdname.substr(0,suffix.size()) == rsuffix) {
+ head=directory+p->d_name;
+ break;
+ }
+ }
+ if(p == NULL) return "";
+ }
+ std::ifstream fin((head+path).c_str());
+ if(fin) {
+ string s;
+ getline(fin,s);
+ size_t end=s.find('\0');
+ if(end < string::npos)
+ return s.substr(0,end);
+ }
+ return "";
+}
+
+// Use key to look up an entry in the MSWindows registry, respecting wild cards
+string getEntry(const string& key)
+{
+ string entry=getEntry("64/HKEY_CURRENT_USER/Software/",key);
+ if(entry.empty()) entry=getEntry("64/HKEY_LOCAL_MACHINE/SOFTWARE/",key);
+ if(entry.empty()) entry=getEntry("/HKEY_CURRENT_USER/Software/",key);
+ if(entry.empty()) entry=getEntry("/HKEY_LOCAL_MACHINE/SOFTWARE/",key);
+ return entry;
+}
+
+void queryRegistry()
+{
+ string defaultGhostscriptLibrary=getEntry("GPL Ghostscript/*/GS_DLL");
+ if(defaultGhostscriptLibrary.empty())
+ defaultGhostscriptLibrary=getEntry("AFPL Ghostscript/*/GS_DLL");
+
+ string gslib=stripDir(defaultGhostscriptLibrary);
+ defaultGhostscript=stripFile(defaultGhostscriptLibrary)+
+ ((gslib.empty() || gslib.substr(5,2) == "32") ? "gswin32c.exe" : "gswin64c.exe");
+ if(defaultPDFViewer != "cmd")
+ defaultPDFViewer=getEntry("Adobe/Acrobat Reader/*/InstallPath/@")+"\\"+
+ defaultPDFViewer;
+ if(defaultPSViewer != "cmd")
+ defaultPSViewer=getEntry("Ghostgum/GSview/*")+"\\gsview\\"+defaultPSViewer;
+ string s;
+ s=getEntry("Microsoft/Windows/CurrentVersion/App Paths/Asymptote/Path");
+ if(!s.empty()) docdir=s;
+ // An empty systemDir indicates a TeXLive build
+ if(!systemDir.empty() && !docdir.empty())
+ systemDir=docdir;
+}
+
+#endif
+
+const char PROGRAM[]=PACKAGE_NAME;
+const char VERSION[]=PACKAGE_VERSION;
+const char BUGREPORT[]=PACKAGE_BUGREPORT;
+
+// The name of the program (as called). Used when displaying help info.
+char *argv0;
+
+// The verbosity setting, a global variable.
+Int verbose;
+
+// Conserve memory at the expense of speed.
+bool compact;
+
+// Colorspace conversion flags (stored in global variables for efficiency).
+bool gray;
+bool bw;
+bool rgb;
+bool cmyk;
+
+// Disable system calls.
+bool safe=true;
+// Enable writing to (or changing to) other directories
+bool globaloption=false;
+
+bool globalwrite() {return globaloption || !safe;}
+
+const string suffix="asy";
+const string guisuffix="gui";
+const string standardprefix="out";
+
+string initdir;
+string historyname;
+
+// Local versions of the argument list.
+int argCount = 0;
+char **argList = 0;
+
+typedef ::option c_option;
+
+types::dummyRecord *settingsModule;
+
+types::record *getSettingsModule() {
+ return settingsModule;
+}
+
+void noWarn(const string& s)
+{
+ array *Warn=getSetting<array *>("suppress");
+ size_t size=checkArray(Warn);
+ if(s.empty()) return;
+ for(size_t i=0; i < size; i++)
+ if(vm::read<string>(Warn,i) == s) return;
+ Warn->push(s);
+}
+
+void Warn(const string& s)
+{
+ array *Warn=getSetting<array *>("suppress");
+ size_t size=checkArray(Warn);
+ for(size_t i=0; i < size; i++)
+ if(vm::read<string>(Warn,i) == s)
+ (*Warn).erase((*Warn).begin()+i,(*Warn).begin()+i+1);
+}
+
+bool warn(const string& s)
+{
+ if(getSetting<bool>("debug")) return true;
+ array *Warn=getSetting<array *>("suppress");
+ size_t size=checkArray(Warn);
+ for(size_t i=0; i < size; i++)
+ if(vm::read<string>(Warn,i) == s) return false;
+ return true;
+}
+
+// The dictionaries of long options and short options.
+struct option;
+typedef mem::map<CONST string, option *> optionsMap_t;
+optionsMap_t optionsMap;
+
+typedef mem::map<CONST char, option *> codeMap_t;
+codeMap_t codeMap;
+
+struct option : public gc {
+ string name;
+ char code; // Command line option, i.e. 'V' for -V.
+ bool argument; // If it takes an argument on the command line. This is set
+ // based on whether argname is empty.
+ string argname; // The argument name for printing the description.
+ string desc; // One line description of what the option does.
+ bool cmdlineonly; // If it is only available on the command line.
+ string Default; // A string containing an optional default value.
+
+ option(string name, char code, string argname, string desc,
+ bool cmdlineonly=false, string Default="")
+ : name(name), code(code), argument(!argname.empty()), argname(argname),
+ desc(desc), cmdlineonly(cmdlineonly), Default(Default) {}
+
+ virtual ~option() {}
+
+ // Builds this option's contribution to the optstring argument of get_opt().
+ virtual string optstring() {
+ if (code) {
+ string base;
+ base.push_back(code);
+ if(argument) base.push_back(':');
+ return base;
+ }
+ else return "";
+ }
+
+ // Sets the contribution to the longopt array.
+ virtual void longopt(c_option &o) {
+ o.name=name.c_str();
+ o.has_arg=argument ? 1 : 0;
+ o.flag=0;
+ o.val=0;
+ }
+
+ // Add to the dictionaries of options.
+ virtual void add() {
+ optionsMap[name]=this;
+ if (code)
+ codeMap[code]=this;
+ }
+
+ // Set the option from the command-line argument. Return true if the option
+ // was correctly parsed.
+ virtual bool getOption() = 0;
+
+ void error(string msg) {
+ cerr << endl << argv0 << ": ";
+ if (code)
+ cerr << "-" << code << " ";
+ cerr << "(-" << name << ") " << msg << endl;
+ }
+
+ // The "-f,-outformat format" part of the option.
+ virtual string describeStart() {
+ ostringstream ss;
+ if (code)
+ ss << "-" << code << ",";
+ ss << "-" << name;
+ if (argument)
+ ss << " " << argname;
+ return ss.str();
+ }
+
+ // Outputs description of the command for the -help option.
+ virtual void describe() {
+ // Don't show the option if it has no desciption.
+ if (!desc.empty()) {
+ const unsigned WIDTH=22;
+ string start=describeStart();
+ cerr << std::left << std::setw(WIDTH) << start;
+ if (start.size() >= WIDTH) {
+ cerr << endl;
+ cerr << std::left << std::setw(WIDTH) << "";
+ }
+ cerr << " " << desc;
+ if(cmdlineonly) cerr << "; command-line only";
+ if(Default != "")
+ cerr << " [" << Default << "]";
+ cerr << endl;
+ }
+ }
+
+ virtual void reset() {
+ }
+};
+
+const string noarg;
+
+struct setting : public option {
+ types::ty *t;
+
+private:
+ trans::permission perm;
+ bool added;
+
+ // Flag the setting as secure, so that it can only be set on the command-line,
+ // though it can still be read in Asymptote code.
+ void secure() {
+ assert(!added);
+ perm = trans::RESTRICTED;
+ }
+
+public:
+ setting(string name, char code, string argname, string desc,
+ types::ty *t, string Default)
+ : option(name, code, argname, desc, false,Default),
+ t(t), perm(trans::PUBLIC), added(false) {}
+
+ void reset() = 0;
+
+ virtual trans::access *buildAccess() = 0;
+
+ // Add to the dictionaries of options and to the settings module.
+ virtual void add() {
+ assert(!added);
+
+ option::add();
+ settingsModule->add(name, t, buildAccess(), perm);
+
+ added=true;
+ }
+
+ friend void addSecureSetting(setting *s) {
+ s->secure();
+ s->add();
+ }
+};
+
+struct itemSetting : public setting {
+ item defaultValue;
+ item value;
+
+ itemSetting(string name, char code,
+ string argname, string desc,
+ types::ty *t, item defaultValue, string Default="")
+ : setting(name, code, argname, desc, t, Default),
+ defaultValue(defaultValue) {reset();}
+
+ void reset() {
+ value=defaultValue;
+ }
+
+ trans::access *buildAccess() {
+ return new itemRefAccess(&(value));
+ }
+};
+
+item& Setting(string name) {
+ itemSetting *s=dynamic_cast<itemSetting *>(optionsMap[name]);
+ if(!s) {
+ cerr << "Cannot find setting named '" << name << "'" << endl;
+ exit(-1);
+ }
+ return s->value;
+}
+
+struct boolSetting : public itemSetting {
+ boolSetting(string name, char code, string desc,
+ bool defaultValue=false)
+ : itemSetting(name, code, noarg, desc,
+ types::primBoolean(), (item)defaultValue,
+ defaultValue ? "true" : "false") {}
+
+ bool getOption() {
+ value=(item)true;
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ boolSetting &base;
+
+ negOption(boolSetting &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ base.value=(item)false;
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ setting::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+ }
+
+ // Set several related boolean options at once. Used for view and trap which
+ // have batch and interactive settings.
+ struct multiOption : public option {
+ typedef mem::list<boolSetting *> setlist;
+ setlist set;
+ multiOption(string name, char code, string desc)
+ : option(name, code, noarg, desc, true) {}
+
+ void add(boolSetting *s) {
+ set.push_back(s);
+ }
+
+ void setValue(bool value) {
+ for (setlist::iterator s=set.begin(); s!=set.end(); ++s)
+ (*s)->value=(item)value;
+ }
+
+ bool getOption() {
+ setValue(true);
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ multiOption &base;
+
+ negOption(multiOption &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ base.setValue(false);
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ option::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+
+ for (multiOption::setlist::iterator s=set.begin(); s!=set.end(); ++s)
+ (*s)->add();
+ }
+ };
+};
+
+typedef boolSetting::multiOption multiOption;
+
+struct argumentSetting : public itemSetting {
+ argumentSetting(string name, char code,
+ string argname, string desc,
+ types::ty *t, item defaultValue)
+ : itemSetting(name, code, argname, desc, t, defaultValue)
+ {
+ assert(!argname.empty());
+ }
+};
+
+struct stringSetting : public argumentSetting {
+ stringSetting(string name, char code,
+ string argname, string desc,
+ string defaultValue="")
+ : argumentSetting(name, code, argname, desc.empty() ? "" :
+ desc+(defaultValue.empty() ? "" : " ["+defaultValue+"]"),
+ types::primString(), (item)defaultValue) {}
+
+ bool getOption() {
+ value=(item)(string)optarg;
+ return true;
+ }
+};
+
+struct userSetting : public argumentSetting {
+ userSetting(string name, char code,
+ string argname, string desc,
+ string defaultValue="")
+ : argumentSetting(name, code, argname, desc,
+ types::primString(), (item)defaultValue) {}
+
+ bool getOption() {
+ string s=vm::get<string>(value)+string(optarg);
+ s.push_back(';');
+ value=(item) s;
+ return true;
+ }
+};
+
+struct warnSetting : public option {
+ warnSetting(string name, char code,
+ string argname, string desc)
+ : option(name, code, argname, desc, true) {}
+
+ bool getOption() {
+ Warn(string(optarg));
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ warnSetting &base;
+
+ negOption(warnSetting &base, string name, string argname)
+ : option(name, 0, argname, ""), base(base) {}
+
+ bool getOption() {
+ noWarn(string(optarg));
+ return true;
+ }
+ };
+ return new negOption(*this, name, argname);
+ }
+
+ void add() {
+ option::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+ }
+};
+
+string GetEnv(string s, string Default) {
+ transform(s.begin(), s.end(), s.begin(), toupper);
+ string t=Getenv(("ASYMPTOTE_"+s).c_str(),msdos);
+ return t.empty() ? Default : t;
+}
+
+struct envSetting : public stringSetting {
+ envSetting(string name, string Default)
+ : stringSetting(name, 0, " ", "", GetEnv(name,Default)) {}
+};
+
+template<class T>
+struct dataSetting : public argumentSetting {
+ string text;
+ dataSetting(const char *text, string name, char code,
+ string argname, string desc, types::ty *type,
+ T defaultValue)
+ : argumentSetting(name, code, argname, desc,
+ type, (item)defaultValue), text(text) {}
+
+ bool getOption() {
+ try {
+ value=(item)lexical::cast<T>(optarg);
+ } catch (lexical::bad_cast&) {
+ error("option requires " + text + " as an argument");
+ return false;
+ }
+ return true;
+ }
+};
+
+template<class T>
+string description(string desc, T defaultValue)
+{
+ return desc.empty() ? "" : desc+" ["+String(defaultValue)+"]";
+}
+
+struct IntSetting : public dataSetting<Int> {
+ IntSetting(string name, char code,
+ string argname, string desc, Int defaultValue=0)
+ : dataSetting<Int>("an int", name, code, argname,
+ description(desc,defaultValue),
+ types::primInt(), defaultValue) {}
+};
+
+struct realSetting : public dataSetting<double> {
+ realSetting(string name, char code,
+ string argname, string desc, double defaultValue=0.0)
+ : dataSetting<double>("a real", name, code, argname,
+ description(desc,defaultValue),
+ types::primReal(), defaultValue) {}
+};
+
+struct pairSetting : public dataSetting<pair> {
+ pairSetting(string name, char code,
+ string argname, string desc, pair defaultValue=0.0)
+ : dataSetting<pair>("a pair", name, code, argname,
+ description(desc,defaultValue),
+ types::primPair(), defaultValue) {}
+};
+
+// For setting the alignment of a figure on the page.
+struct alignSetting : public argumentSetting {
+ alignSetting(string name, char code,
+ string argname, string desc,
+ string defaultValue)
+ : argumentSetting(name, code, argname, description(desc,defaultValue),
+ types::primString(), (item)defaultValue) {}
+
+ bool getOption() {
+ string str=optarg;
+ if(str == "C" || str == "T" || str == "B" || str == "Z") {
+ value=str;
+ return true;
+ }
+ error("invalid argument for option");
+ return false;
+ }
+};
+
+struct stringArraySetting : public itemSetting {
+ stringArraySetting(string name, array *defaultValue)
+ : itemSetting(name, 0, "", "",
+ types::stringArray(), (item) defaultValue) {}
+
+ bool getOption() {return true;}
+};
+
+struct engineSetting : public argumentSetting {
+ engineSetting(string name, char code,
+ string argname, string desc,
+ string defaultValue)
+ : argumentSetting(name, code, argname, description(desc,defaultValue),
+ types::primString(), (item)defaultValue) {}
+
+ bool getOption() {
+ string str=optarg;
+
+ if(str == "latex" || str == "pdflatex" || str == "xelatex" ||
+ str == "tex" || str == "pdftex" || str == "luatex" ||
+ str == "lualatex" || str == "context" || str == "none") {
+ value=str;
+ return true;
+ }
+ error("invalid argument for option");
+ return false;
+ }
+};
+
+template<class T>
+string stringCast(T x)
+{
+ ostringstream buf;
+ buf.precision(DBL_DIG);
+ buf.setf(std::ios::boolalpha);
+ buf << x;
+ return string(buf.str());
+}
+
+template <class T>
+struct refSetting : public setting {
+ T *ref;
+ T defaultValue;
+ string text;
+
+ refSetting(string name, char code, string argname,
+ string desc, types::ty *t, T *ref, T defaultValue,
+ const char *text="")
+ : setting(name, code, argname, desc, t, stringCast(defaultValue)),
+ ref(ref), defaultValue(defaultValue), text(text) {
+ reset();
+ }
+
+ virtual bool getOption() {
+ try {
+ *ref=lexical::cast<T>(optarg);
+ } catch (lexical::bad_cast&) {
+ error("option requires " + text + " as an argument");
+ return false;
+ }
+ return true;
+ }
+
+ virtual void reset() {
+ *ref=defaultValue;
+ }
+
+ trans::access *buildAccess() {
+ return new refAccess<T>(ref);
+ }
+};
+
+struct boolrefSetting : public refSetting<bool> {
+ boolrefSetting(string name, char code, string desc, bool *ref,
+ bool Default=false)
+ : refSetting<bool>(name, code, noarg, desc,
+ types::primBoolean(), ref, Default) {}
+ virtual bool getOption() {
+ *ref=true;
+ return true;
+ }
+
+ virtual option *negation(string name) {
+ struct negOption : public option {
+ boolrefSetting &base;
+
+ negOption(boolrefSetting &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ *(base.ref)=false;
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ setting::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+ }
+};
+
+struct compactSetting : public boolrefSetting {
+ compactSetting(string name, char code, string desc, bool *ref,
+ bool Default=false)
+ : boolrefSetting(name,code,desc,ref,Default) {}
+ bool getOption() {
+ mem::compact(1);
+ return boolrefSetting::getOption();
+ }
+
+ option *negation(string name) {
+ mem::compact(0);
+ return boolrefSetting::negation(name);
+ }
+};
+
+struct incrementSetting : public refSetting<Int> {
+ incrementSetting(string name, char code, string desc, Int *ref)
+ : refSetting<Int>(name, code, noarg, desc,
+ types::primInt(), ref, 0) {}
+
+ bool getOption() {
+ // Increment the value.
+ ++(*ref);
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ incrementSetting &base;
+
+ negOption(incrementSetting &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ if(*base.ref) --(*base.ref);
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ setting::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+ }
+};
+
+struct incrementOption : public option {
+ Int *ref;
+ Int level;
+
+ incrementOption(string name, char code, string desc, Int *ref,
+ Int level=1)
+ : option(name, code, noarg, desc, true), ref(ref), level(level) {}
+
+ bool getOption() {
+ // Increment the value.
+ (*ref) += level;
+ return true;
+ }
+};
+
+void addOption(option *o) {
+ o->add();
+}
+
+void version()
+{
+ cerr << PROGRAM << " version " << REVISION
+ << " [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]"
+ << endl;
+}
+
+void usage(const char *program)
+{
+ version();
+ cerr << "\t\t\t" << "http://asymptote.sourceforge.net/"
+ << endl
+ << "Usage: " << program << " [options] [file ...]"
+ << endl;
+}
+
+void reportSyntax() {
+ cerr << endl;
+ usage(argv0);
+ cerr << endl << "Type '" << argv0
+ << " -h' for a description of options." << endl;
+ exit(1);
+}
+
+void displayOptions()
+{
+ cerr << endl;
+ cerr << "Options (negate by replacing - with -no): "
+ << endl << endl;
+ for (optionsMap_t::iterator opt=optionsMap.begin();
+ opt!=optionsMap.end();
+ ++opt)
+ opt->second->describe();
+}
+
+struct helpOption : public option {
+ helpOption(string name, char code, string desc)
+ : option(name, code, noarg, desc, true) {}
+
+ bool getOption() {
+ usage(argv0);
+ displayOptions();
+ cerr << endl;
+ exit(0);
+
+ // Unreachable code.
+ return true;
+ }
+};
+
+struct versionOption : public option {
+ versionOption(string name, char code, string desc)
+ : option(name, code, noarg, desc, true) {}
+
+ bool getOption() {
+ version();
+ exit(0);
+
+ // Unreachable code.
+ return true;
+ }
+};
+
+struct divisorOption : public option {
+ divisorOption(string name, char code, string argname, string desc)
+ : option(name, code, argname, desc) {}
+
+ bool getOption() {
+ try {
+#ifdef USEGC
+ Int n=lexical::cast<Int>(optarg);
+ if(n > 0) GC_set_free_space_divisor((GC_word) n);
+#endif
+ } catch (lexical::bad_cast&) {
+ error("option requires an int as an argument");
+ return false;
+ }
+ return true;
+ }
+};
+
+// For security reasons, these options aren't fields of the settings module.
+struct stringOption : public option {
+ char **variable;
+ stringOption(string name, char code, string argname,
+ string desc, char **variable)
+ : option(name, code, argname, desc, true), variable(variable) {}
+
+ bool getOption() {
+ *variable=optarg;
+ return true;
+ }
+};
+
+string build_optstring() {
+ string s;
+ for (codeMap_t::iterator p=codeMap.begin(); p !=codeMap.end(); ++p)
+ s +=p->second->optstring();
+
+ return s;
+}
+
+c_option *build_longopts() {
+ size_t n=optionsMap.size();
+
+ c_option *longopts=new(UseGC) c_option[n+1];
+ Int i=0;
+ for (optionsMap_t::iterator p=optionsMap.begin();
+ p !=optionsMap.end();
+ ++p, ++i)
+ p->second->longopt(longopts[i]);
+
+ longopts[n].name=NULL;
+ longopts[n].has_arg=0;
+ longopts[n].flag=NULL;
+ longopts[n].val=0;
+
+ return longopts;
+}
+
+void resetOptions()
+{
+ for(optionsMap_t::iterator opt=optionsMap.begin(); opt != optionsMap.end();
+ ++opt)
+ if(opt->first != "config" && opt->first != "dir" && opt->first != "sysdir")
+ opt->second->reset();
+}
+
+void getOptions(int argc, char *argv[])
+{
+ bool syntax=false;
+ optind=0;
+
+ string optstring=build_optstring();
+ //cerr << "optstring: " << optstring << endl;
+ c_option *longopts=build_longopts();
+ int long_index = 0;
+
+ errno=0;
+ for(;;) {
+ int c = getopt_long_only(argc,argv,
+ optstring.c_str(), longopts, &long_index);
+ if (c == -1)
+ break;
+
+ if (c == 0) {
+ const char *name=longopts[long_index].name;
+ //cerr << "long option: " << name << endl;
+ if (!optionsMap[name]->getOption())
+ syntax=true;
+ }
+ else if (codeMap.find((char)c) != codeMap.end()) {
+ //cerr << "char option: " << (char)c << endl;
+ if (!codeMap[(char)c]->getOption())
+ syntax=true;
+ }
+ else {
+ syntax=true;
+ }
+
+ errno=0;
+ }
+
+ if (syntax)
+ reportSyntax();
+}
+
+#ifdef USEGC
+void no_GCwarn(char *, GC_word)
+{
+}
+#endif
+
+array* stringArray(const char **s)
+{
+ size_t count=0;
+ while(s[count])
+ ++count;
+ array *a=new array(count);
+ for(size_t i=0; i < count; ++i)
+ (*a)[i]=string(s[i]);
+ return a;
+}
+
+void initSettings() {
+ static bool initialize=true;
+ if(initialize) {
+ queryRegistry();
+ initialize=false;
+ }
+
+ settingsModule=new types::dummyRecord(symbol::trans("settings"));
+
+// Default mouse bindings
+
+// LEFT: rotate
+// SHIFT LEFT: zoom
+// CTRL LEFT: shift
+// ALT LEFT: pan
+ const char *leftbutton[]={"rotate","zoom","shift","pan",NULL};
+
+// MIDDLE:
+ const char *middlebutton[]={NULL};
+
+// RIGHT: zoom
+// SHIFT RIGHT: rotateX
+// CTRL RIGHT: rotateY
+// ALT RIGHT: rotateZ
+ const char *rightbutton[]={"zoom","rotateX","rotateY","rotateZ",NULL};
+
+// WHEEL_UP: zoomin
+ const char *wheelup[]={"zoomin",NULL};
+
+// WHEEL_DOWN: zoomout
+ const char *wheeldown[]={"zoomout",NULL};
+
+ addOption(new stringArraySetting("leftbutton", stringArray(leftbutton)));
+ addOption(new stringArraySetting("middlebutton", stringArray(middlebutton)));
+ addOption(new stringArraySetting("rightbutton", stringArray(rightbutton)));
+ addOption(new stringArraySetting("wheelup", stringArray(wheelup)));
+ addOption(new stringArraySetting("wheeldown", stringArray(wheeldown)));
+ addOption(new stringArraySetting("suppress", new array));
+
+ addOption(new warnSetting("warn", 0, "string", "Enable warning"));
+
+ multiOption *view=new multiOption("View", 'V', "View output");
+ view->add(new boolSetting("batchView", 0, "View output in batch mode",
+ msdos));
+ view->add(new boolSetting("multipleView", 0,
+ "View output from multiple batch-mode files",
+ false));
+ view->add(new boolSetting("interactiveView", 0,
+ "View output in interactive mode", true));
+ addOption(view);
+ addOption(new stringSetting("outformat", 'f', "format",
+ "Convert each output file to specified format",
+ ""));
+ addOption(new boolSetting("svgemulation", 0,
+ "Emulate unimplemented SVG shading", false));
+ addOption(new boolSetting("prc", 0,
+ "Embed 3D PRC graphics in PDF output", true));
+ addOption(new boolSetting("toolbar", 0,
+ "Show 3D toolbar in PDF output", true));
+ addOption(new boolSetting("axes3", 0,
+ "Show 3D axes in PDF output", true));
+ addOption(new boolSetting("envmap", 0,
+ "Enable environment map image-based lighting (Experimental)", false));
+
+
+ addOption(new realSetting("render", 0, "n",
+ "Render 3D graphics using n pixels per bp (-1=auto)",
+ havegl ? -1.0 : 0.0));
+ addOption(new IntSetting("antialias", 0, "n",
+ "Antialiasing width for rasterized output", 2));
+ addOption(new IntSetting("multisample", 0, "n",
+ "Multisampling width for screen images", 4));
+ addOption(new boolSetting("offscreen", 0,
+ "Use offscreen rendering",false));
+ addOption(new boolSetting("twosided", 0,
+ "Use two-sided 3D lighting model for rendering",
+ true));
+ addOption(new pairSetting("position", 0, "pair",
+ "Initial 3D rendering screen position"));
+ addOption(new pairSetting("maxviewport", 0, "pair",
+ "Maximum viewport size",pair(2048,2048)));
+ addOption(new pairSetting("maxtile", 0, "pair",
+ "Maximum rendering tile size",pair(1024,768)));
+ addOption(new boolSetting("iconify", 0,
+ "Iconify rendering window", false));
+ addOption(new boolSetting("thick", 0,
+ "Render thick 3D lines", true));
+ addOption(new boolSetting("thin", 0,
+ "Render thin 3D lines", true));
+ addOption(new boolSetting("autobillboard", 0,
+ "3D labels always face viewer by default", true));
+ addOption(new boolSetting("threads", 0,
+ "Use POSIX threads for 3D rendering", !msdos));
+ addOption(new boolSetting("fitscreen", 0,
+ "Fit rendered image to screen", true));
+ addOption(new boolSetting("interactiveWrite", 0,
+ "Write expressions entered at the prompt to stdout",
+ true));
+ addOption(new helpOption("help", 'h', "Show summary of options"));
+ addOption(new versionOption("version", 0, "Show version"));
+
+ addOption(new pairSetting("offset", 'O', "pair", "PostScript offset"));
+ addOption(new pairSetting("aligndir", 0, "pair",
+ "Directional page alignment (overrides align)"));
+ addOption(new alignSetting("align", 'a', "C|B|T|Z",
+ "Center, Bottom, Top, or Zero page alignment",
+ "C"));
+
+ addOption(new boolSetting("debug", 'd', "Enable debugging messages"));
+ addOption(new incrementSetting("verbose", 'v',
+ "Increase verbosity level (can specify multiple times)", &verbose));
+ // Resolve ambiguity with --version
+ addOption(new incrementOption("vv", 0,"", &verbose,2));
+ addOption(new incrementOption("novv", 0,"", &verbose,-2));
+
+ addOption(new boolSetting("keep", 'k', "Keep intermediate files"));
+ addOption(new boolSetting("keepaux", 0,
+ "Keep intermediate LaTeX .aux files"));
+ addOption(new engineSetting("tex", 0, "engine",
+ "latex|pdflatex|xelatex|lualatex|tex|pdftex|luatex|context|none",
+ "latex"));
+
+ addOption(new boolSetting("twice", 0,
+ "Run LaTeX twice (to resolve references)"));
+ addOption(new boolSetting("inlinetex", 0, "Generate inline TeX code"));
+ addOption(new boolSetting("embed", 0, "Embed rendered preview image", true));
+ addOption(new boolSetting("auto3D", 0, "Automatically activate 3D scene",
+ true));
+ addOption(new boolSetting("autoplay", 0, "Autoplay 3D animations", false));
+ addOption(new boolSetting("loop", 0, "Loop 3D animations", false));
+ addOption(new boolSetting("interrupt", 0, "", false));
+ addOption(new boolSetting("animating", 0, "", false));
+ addOption(new boolSetting("reverse", 0, "reverse 3D animations", false));
+
+ addOption(new boolSetting("inlineimage", 0,
+ "Generate inline embedded image"));
+ addOption(new boolSetting("parseonly", 'p', "Parse file"));
+ addOption(new boolSetting("translate", 's',
+ "Show translated virtual machine code"));
+ addOption(new boolSetting("tabcompletion", 0,
+ "Interactive prompt auto-completion", true));
+ addOption(new boolSetting("listvariables", 'l',
+ "List available global functions and variables"));
+ addOption(new boolSetting("where", 0,
+ "Show where listed variables are declared"));
+
+ multiOption *mask=new multiOption("mask", 'm',
+ "Mask fpu exceptions");
+ mask->add(new boolSetting("batchMask", 0,
+ "Mask fpu exceptions in batch mode", false));
+ mask->add(new boolSetting("interactiveMask", 0,
+ "Mask fpu exceptions in interactive mode", true));
+ addOption(mask);
+
+ addOption(new boolrefSetting("bw", 0,
+ "Convert all colors to black and white",&bw));
+ addOption(new boolrefSetting("gray", 0, "Convert all colors to grayscale",
+ &gray));
+ addOption(new boolrefSetting("rgb", 0, "Convert cmyk colors to rgb",&rgb));
+ addOption(new boolrefSetting("cmyk", 0, "Convert rgb colors to cmyk",&cmyk));
+
+ addSecureSetting(new boolrefSetting("safe", 0, "Disable system call",
+ &safe, true));
+ addSecureSetting(new boolrefSetting("globalwrite", 0,
+ "Allow write to other directory",
+ &globaloption, false));
+ addSecureSetting(new stringSetting("outname", 'o', "name",
+ "Alternative output directory/filename"));
+ addOption(new stringOption("cd", 0, "directory", "Set current directory",
+ &startpath));
+
+#ifdef USEGC
+ addOption(new compactSetting("compact", 0,
+ "Conserve memory at the expense of speed",
+ &compact));
+ addOption(new divisorOption("divisor", 0, "n",
+ "Garbage collect using purge(divisor=n) [2]"));
+#endif
+
+ addOption(new stringSetting("prompt", 0,"string","Prompt","> "));
+ addOption(new stringSetting("prompt2", 0,"string",
+ "Continuation prompt for multiline input ",
+ ".."));
+ addOption(new boolSetting("multiline", 0,
+ "Input code over multiple lines at the prompt"));
+ addOption(new boolSetting("xasy", 0,
+ "Special interactive mode for xasy"));
+
+ addOption(new boolSetting("wait", 0,
+ "Wait for child processes to finish before exiting"));
+ addOption(new IntSetting("inpipe", 0, "n","",-1));
+ addOption(new IntSetting("outpipe", 0, "n","",-1));
+ addOption(new boolSetting("exitonEOF", 0, "Exit interactive mode on EOF",
+ true));
+
+ addOption(new boolSetting("quiet", 'q',
+ "Suppress welcome text and noninteractive stdout"));
+ addOption(new boolSetting("localhistory", 0,
+ "Use a local interactive history file"));
+ addOption(new IntSetting("historylines", 0, "n",
+ "Retain n lines of history",1000));
+ addOption(new IntSetting("scroll", 0, "n",
+ "Scroll standard output n lines at a time",0));
+ addOption(new IntSetting("level", 0, "n", "Postscript level",3));
+ addOption(new boolSetting("autoplain", 0,
+ "Enable automatic importing of plain",
+ true));
+ addOption(new boolSetting("autorotate", 0,
+ "Enable automatic PDF page rotation",
+ false));
+ addOption(new boolSetting("pdfreload", 0,
+ "Automatically reload document in pdfviewer",
+ false));
+ addOption(new IntSetting("pdfreloaddelay", 0, "usec",
+ "Delay before attempting initial pdf reload"
+ ,750000));
+ addOption(new stringSetting("autoimport", 0, "string",
+ "Module to automatically import"));
+ addOption(new userSetting("command", 'c', "string",
+ "Command to autoexecute"));
+ addOption(new userSetting("user", 'u', "string",
+ "General purpose user string"));
+
+ addOption(new IntSetting("maxvertices", 0, "n", "Maximum number of vertices to queue", 0));
+ addOption(new realSetting("zoomfactor", 0, "factor", "Zoom step factor",
+ 1.05));
+ addOption(new realSetting("zoomstep", 0, "step", "Mouse motion zoom step",
+ 0.1));
+ addOption(new realSetting("spinstep", 0, "deg/s", "Spin speed",
+ 60.0));
+ addOption(new realSetting("framerate", 0, "frames/s", "Animation speed",
+ 30.0));
+ addOption(new realSetting("framedelay", 0, "ms",
+ "Additional frame delay", 0.0));
+ addOption(new realSetting("arcballradius", 0, "pixels",
+ "Arcball radius", 750.0));
+ addOption(new realSetting("resizestep", 0, "step", "Resize step", 1.2));
+ addOption(new IntSetting("doubleclick", 0, "ms",
+ "Emulated double-click timeout", 200));
+
+ addOption(new realSetting("paperwidth", 0, "bp", ""));
+ addOption(new realSetting("paperheight", 0, "bp", ""));
+
+ addOption(new stringSetting("dvipsOptions", 0, "string", ""));
+ addOption(new stringSetting("dvisvgmOptions", 0, "string", ""));
+ addOption(new stringSetting("convertOptions", 0, "string", ""));
+ addOption(new stringSetting("gsOptions", 0, "string", ""));
+ addOption(new stringSetting("psviewerOptions", 0, "string", ""));
+ addOption(new stringSetting("pdfviewerOptions", 0, "string", ""));
+ addOption(new stringSetting("pdfreloadOptions", 0, "string", ""));
+ addOption(new stringSetting("glOptions", 0, "string", ""));
+ addOption(new stringSetting("hyperrefOptions", 0, "str",
+ "","setpagesize=false,unicode,pdfborder=0 0 0"));
+
+ addOption(new envSetting("config","config."+suffix));
+ addOption(new envSetting("pdfviewer", defaultPDFViewer));
+ addOption(new envSetting("psviewer", defaultPSViewer));
+ addOption(new envSetting("gs", defaultGhostscript));
+ addOption(new envSetting("libgs", defaultGhostscriptLibrary));
+ addOption(new envSetting("epsdriver", defaultEPSdriver));
+ addOption(new envSetting("texpath", ""));
+ addOption(new envSetting("texcommand", ""));
+ addOption(new envSetting("dvips", "dvips"));
+ addOption(new envSetting("dvisvgm", "dvisvgm"));
+ addOption(new envSetting("convert", "convert"));
+ addOption(new envSetting("display", defaultDisplay));
+ addOption(new envSetting("animate", defaultAnimate));
+ addOption(new envSetting("papertype", "letter"));
+ addOption(new envSetting("dir", ""));
+ addOption(new envSetting("sysdir", systemDir));
+ addOption(new envSetting("textcommand","groff"));
+ addOption(new envSetting("textcommandOptions","-e -P -b16"));
+ addOption(new envSetting("textextension", "roff"));
+ addOption(new envSetting("textoutformat", "ps"));
+ addOption(new envSetting("textprologue", ".EQ\ndelim $$\n.EN"));
+ addOption(new envSetting("textinitialfont", ".fam T\n.ps 12"));
+ addOption(new envSetting("textepilogue", ".bp"));
+}
+
+// Access the arguments once options have been parsed.
+int numArgs() { return argCount; }
+char *getArg(int n) { return argList[n]; }
+
+void setInteractive()
+{
+ if(numArgs() == 0 && !getSetting<bool>("listvariables") &&
+ getSetting<string>("command").empty() &&
+ (isatty(STDIN_FILENO) || getSetting<Int>("xasy")))
+ interact::interactive=true;
+
+ if(getSetting<bool>("localhistory"))
+ historyname=string(getPath())+dirsep+"."+suffix+"_history";
+ else {
+ if(mkdir(initdir.c_str(),0777) != 0 && errno != EEXIST)
+ cerr << "failed to create directory "+initdir+"." << endl;
+ historyname=initdir+"/history";
+ }
+ if(verbose > 1)
+ cerr << "Using history " << historyname << endl;
+}
+
+bool view()
+{
+ if (interact::interactive)
+ return getSetting<bool>("interactiveView");
+ else
+ return getSetting<bool>("batchView") &&
+ (numArgs() == 1 || getSetting<bool>("multipleView"));
+}
+
+bool trap()
+{
+ if (interact::interactive)
+ return !getSetting<bool>("interactiveMask");
+ else
+ return !getSetting<bool>("batchMask");
+}
+
+string outname()
+{
+ string name=getSetting<string>("outname");
+ if(name.empty() && interact::interactive) return standardprefix;
+ if(msdos) backslashToSlash(name);
+ return name;
+}
+
+string lookup(const string& symbol)
+{
+ string s;
+ mem::vector<string> cmd;
+ string kpsewhich="kpsewhich";
+ string fullname=stripFile(argv0)+kpsewhich;
+ std::ifstream exists(fullname.c_str());
+ if(!exists) fullname=kpsewhich;
+ cmd.push_back(fullname);
+ cmd.push_back("--var-value="+symbol);
+ iopipestream pipe(cmd);
+ pipe >> s;
+ size_t n=s.find('\r');
+ if(n != string::npos)
+ s.erase(n,1);
+ n=s.find('\n');
+ if(n != string::npos)
+ s.erase(n,1);
+ return s;
+}
+
+void initDir() {
+ if(getSetting<string>("sysdir").empty()) {
+ string s=lookup("TEXMFMAIN");
+ if(s.size() > 1) {
+ string texmf=s+dirsep;
+ docdir=texmf+"doc"+dirsep+"asymptote";
+ Setting("sysdir")=texmf+"asymptote";
+ s=lookup("ASYMPTOTE_HOME");
+ if(s.size() > 1)
+ initdir=s;
+ }
+ }
+
+ if(initdir.empty())
+ initdir=Getenv("ASYMPTOTE_HOME",msdos);
+
+ if(initdir.empty())
+ initdir=Getenv(HOME.c_str(),msdos)+dirsep+"."+suffix;
+
+#ifdef __MSDOS__
+ mask=umask(0);
+ if(mask == 0) mask=0027;
+ umask(mask);
+#endif
+ if(access(initdir.c_str(),F_OK) == 0) {
+ if(verbose > 1)
+ cerr << "Using configuration directory " << initdir << endl;
+ }
+}
+
+void setPath() {
+ searchPath.clear();
+ searchPath.push_back(".");
+ string asydir=getSetting<string>("dir");
+ if(asydir != "") {
+ size_t p,i=0;
+ while((p=asydir.find(pathSeparator,i)) < string::npos) {
+ if(p > i) searchPath.push_back(asydir.substr(i,p-i));
+ i=p+1;
+ }
+ if(i < asydir.length()) searchPath.push_back(asydir.substr(i));
+ }
+ if(access(initdir.c_str(),F_OK) == 0)
+ searchPath.push_back(initdir);
+ string sysdir=getSetting<string>("sysdir");
+ if(sysdir != "")
+ searchPath.push_back(sysdir);
+}
+
+void SetPageDimensions() {
+ string paperType=getSetting<string>("papertype");
+
+ if(paperType.empty() &&
+ getSetting<double>("paperwidth") != 0.0 &&
+ getSetting<double>("paperheight") != 0.0) return;
+
+ if(paperType == "letter") {
+ Setting("paperwidth")=8.5*inches;
+ Setting("paperheight")=11.0*inches;
+ } else {
+ Setting("paperwidth")=21.0*cm;
+ Setting("paperheight")=29.7*cm;
+
+ if(paperType != "a4") {
+ cerr << "Unknown paper size \'" << paperType << "\'; assuming a4."
+ << endl;
+ Setting("papertype")=string("a4");
+ }
+ }
+}
+
+bool xe(const string& texengine)
+{
+ return texengine == "xelatex";
+}
+
+bool lua(const string& texengine)
+{
+ return texengine == "luatex" || texengine == "lualatex";
+}
+
+bool context(const string& texengine)
+{
+ return texengine == "context";
+}
+
+bool pdf(const string& texengine)
+{
+ return texengine == "pdflatex" || texengine == "pdftex" || xe(texengine) ||
+ lua(texengine) || context(texengine);
+}
+
+bool latex(const string& texengine)
+{
+ return texengine == "latex" || texengine == "pdflatex" ||
+ texengine == "xelatex" || texengine == "lualatex";
+}
+
+string nativeformat()
+{
+ return pdf(getSetting<string>("tex")) ? "pdf" : "eps";
+}
+
+string defaultformat()
+{
+ string format=getSetting<string>("outformat");
+ return (format.empty()) ? nativeformat() : format;
+}
+
+// TeX special command to set up currentmatrix for typesetting labels.
+const char *beginlabel(const string& texengine)
+{
+ if(pdf(texengine))
+ return xe(texengine) ? "\\special{pdf:literal q #5 0 0 cm}" :
+ "\\special{pdf:q #5 0 0 cm}";
+ else
+ return "\\special{ps:gsave currentpoint currentpoint translate [#5 0 0] "
+ "concat neg exch neg exch translate}";
+}
+
+// TeX special command to restore currentmatrix after typesetting labels.
+const char *endlabel(const string& texengine)
+{
+ if(pdf(texengine))
+ return xe(texengine) ? "\\special{pdf:literal Q}" : "\\special{pdf:Q}";
+ else
+ return "\\special{ps:currentpoint grestore moveto}";
+}
+
+// TeX macro to typeset raw postscript code
+const char *rawpostscript(const string& texengine)
+{
+ if(pdf(texengine))
+ return "\\def\\ASYraw#1{#1}";
+ else
+ return "\\def\\ASYraw#1{\n"
+ "currentpoint currentpoint translate matrix currentmatrix\n"
+ "100 12 div -100 12 div scale\n"
+ "#1\n"
+ "setmatrix neg exch neg exch translate}";
+}
+
+// TeX macro to begin picture
+const char *beginpicture(const string& texengine)
+{
+ if(latex(texengine))
+ return "\\begin{picture}";
+ if(context(texengine))
+ return "";
+ else
+ return "\\picture";
+}
+
+// TeX macro to end picture
+const char *endpicture(const string& texengine)
+{
+ if(latex(texengine))
+ return "\\end{picture}%";
+ else if(context(texengine))
+ return "%";
+ else
+ return "\\endpicture%";
+}
+
+// Begin TeX special command.
+const char *beginspecial(const string& texengine)
+{
+ if(pdf(texengine))
+ return xe(texengine) ? "\\special{pdf:literal " : "\\special{pdf:";
+ else
+ return "\\special{ps:";
+}
+
+// End TeX special command.
+const char *endspecial()
+{
+ return "}%";
+}
+
+string texcommand()
+{
+ string command=getSetting<string>("texcommand");
+ return command.empty() ? getSetting<string>("tex") : command;
+}
+
+string texprogram()
+{
+ string path=getSetting<string>("texpath");
+ string engine=texcommand();
+ return path.empty() ? engine : (string) (path+"/"+engine);
+}
+
+Int getScroll()
+{
+ Int scroll=settings::getSetting<Int>("scroll");
+ if(scroll < 0) {
+#ifdef HAVE_LIBCURSES
+ static char *terminal=NULL;
+ if(!terminal)
+ terminal=getenv("TERM");
+ if(terminal) {
+#ifndef __MSDOS__
+ int error=setupterm(terminal,1,&error);
+ if(error == 0) scroll=lines > 2 ? lines-1 : 1;
+ else
+#endif
+ scroll=0;
+ } else scroll=0;
+#else
+ scroll=0;
+#endif
+ }
+ return scroll;
+}
+
+void doConfig(string file)
+{
+ bool autoplain=getSetting<bool>("autoplain");
+ bool listvariables=getSetting<bool>("listvariables");
+ if(autoplain) Setting("autoplain")=false; // Turn off for speed.
+ if(listvariables) Setting("listvariables")=false;
+
+ runFile(file);
+
+ if(autoplain) Setting("autoplain")=true;
+ if(listvariables) Setting("listvariables")=true;
+}
+
+void setOptions(int argc, char *argv[])
+{
+ argv0=argv[0];
+
+ cout.precision(DBL_DIG);
+
+ // Build settings module.
+ initSettings();
+
+ // Read command-line options initially to obtain config, dir, sysdir, verbose.
+ getOptions(argc,argv);
+
+ // Make configuration and history directory
+ initDir();
+
+ Int Verbose=verbose;
+ string sysdir=getSetting<string>("sysdir");
+
+ resetOptions();
+
+ // Read user configuration file.
+ setPath();
+ string filename=getSetting<string>("config");
+ if(!filename.empty()) {
+ string file=locateFile(filename);
+ if(!file.empty()) {
+ if(Verbose > 1)
+ cerr << "Loading " << filename << " from " << file << endl;
+ doConfig(file);
+ }
+ }
+
+ // Read command-line options again to override configuration file defaults.
+ getOptions(argc,argv);
+
+ if(getSetting<Int>("outpipe") == 2) // Redirect cerr to cout
+ std::cerr.rdbuf(std::cout.rdbuf());
+
+ Setting("sysdir")=sysdir;
+
+ if(docdir.empty())
+ docdir=getSetting<string>("dir");
+
+#ifdef USEGC
+ if(verbose == 0 && !getSetting<bool>("debug")) GC_set_warn_proc(no_GCwarn);
+#endif
+
+ if(setlocale (LC_ALL, "") == NULL && getSetting<bool>("debug"))
+ perror("setlocale");
+
+ // Set variables for the file arguments.
+ argCount = argc - optind;
+ argList = argv + optind;
+
+ // Recompute search path.
+ setPath();
+
+ if(getSetting<double>("paperwidth") != 0.0 &&
+ getSetting<double>("paperheight") != 0.0)
+ Setting("papertype")=string("");
+
+ SetPageDimensions();
+
+ setInteractive();
+}
+
+}
diff --git a/graphics/asymptote/settings.h b/graphics/asymptote/settings.h
new file mode 100644
index 0000000000..83db0a30a5
--- /dev/null
+++ b/graphics/asymptote/settings.h
@@ -0,0 +1,127 @@
+/*****
+ * settings.h
+ * Andy Hammerlindl 2004/05/10
+ *
+ * Declares a list of global variables that act as settings in the system.
+ *****/
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <fstream>
+#include <sys/stat.h>
+
+#include "common.h"
+#include "pair.h"
+#include "item.h"
+
+namespace types {
+class record;
+}
+
+namespace camp {
+void glrenderWrapper();
+}
+
+namespace gl {
+extern bool glthread;
+extern bool initialize;
+
+#ifdef HAVE_PTHREAD
+extern pthread_t mainthread;
+extern pthread_cond_t initSignal;
+extern pthread_mutex_t initLock;
+extern pthread_cond_t readySignal;
+extern pthread_mutex_t readyLock;
+void wait(pthread_cond_t& signal, pthread_mutex_t& lock);
+void endwait(pthread_cond_t& signal, pthread_mutex_t& lock);
+#endif
+}
+
+namespace settings {
+extern const char PROGRAM[];
+extern const char VERSION[];
+extern const char BUGREPORT[];
+
+extern char *argv0;
+
+void Warn(const string& s);
+void noWarn(const string& s);
+bool warn(const string& s);
+extern string systemDir;
+extern string docdir;
+extern const string dirsep;
+
+extern bool safe;
+
+bool globalwrite();
+
+extern const string suffix;
+extern const string guisuffix;
+extern const string standardprefix;
+
+extern string historyname;
+
+void SetPageDimensions();
+
+types::record *getSettingsModule();
+
+vm::item& Setting(string name);
+
+template <typename T>
+inline T getSetting(string name)
+{
+ return vm::get<T>(Setting(name));
+}
+
+extern Int verbose;
+extern bool compact;
+extern bool gray;
+extern bool bw;
+extern bool rgb;
+extern bool cmyk;
+
+bool view();
+bool trap();
+string outname();
+
+void setOptions(int argc, char *argv[]);
+
+// Access the arguments once options have been parsed.
+int numArgs();
+char *getArg(int n);
+
+Int getScroll();
+
+extern mode_t mask;
+
+bool xe(const string& texengine);
+bool lua(const string& texengine);
+bool pdf(const string& texengine);
+bool latex(const string& texengine);
+bool context(const string& texengine);
+
+string nativeformat();
+string defaultformat();
+
+const char *beginlabel(const string& texengine);
+const char *endlabel(const string& texengine);
+const char *rawpostscript(const string& texengine);
+const char *beginpicture(const string& texengine);
+const char *endpicture(const string& texengine);
+const char *beginspecial(const string& texengine);
+const char *endspecial();
+
+string texcommand();
+string texprogram();
+
+const double inches=72.0;
+const double cm=inches/2.54;
+const double tex2ps=72.0/72.27;
+const double ps2tex=1.0/tex2ps;
+
+}
+
+extern const char *REVISION;
+
+#endif
diff --git a/graphics/asymptote/shaders.cc b/graphics/asymptote/shaders.cc
new file mode 100644
index 0000000000..1067068772
--- /dev/null
+++ b/graphics/asymptote/shaders.cc
@@ -0,0 +1,109 @@
+// shader handling
+// Author: Supakorn "Jamie" Rassameemasmuang
+
+#include "common.h"
+
+#ifdef HAVE_GL
+
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <string>
+#include <iostream>
+
+#include "shaders.h"
+
+GLuint compileAndLinkShader(std::vector<ShaderfileModePair> const& shaders,
+ size_t NLights, size_t NMaterials,
+ std::vector<std::string> const& defineflags)
+{
+ GLuint mainShader = glCreateProgram();
+ std::vector<GLuint> compiledShaders;
+
+ size_t n=shaders.size();
+ for(size_t i=0; i < n; ++i) {
+ GLint newshader=createShaderFile(shaders[i].first,shaders[i].second,
+ NLights,NMaterials,defineflags);
+ glAttachShader(mainShader,newshader);
+ compiledShaders.push_back(newshader);
+ }
+
+ glLinkProgram(mainShader);
+
+ for(size_t i=0; i < n; ++i) {
+ glDetachShader(mainShader,compiledShaders[i]);
+ glDeleteShader(compiledShaders[i]);
+ }
+
+ return mainShader;
+}
+
+GLuint createShaders(GLchar const* src, int shaderType,
+ std::string const& filename)
+{
+ GLuint shader=glCreateShader(shaderType);
+ glShaderSource(shader, 1, &src, NULL);
+ glCompileShader(shader);
+
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+
+ if(status != GL_TRUE) {
+ GLint length;
+
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
+
+ std::vector<GLchar> msg(length);
+
+ glGetShaderInfoLog(shader, length, &length, msg.data());
+
+ size_t n=msg.size();
+ for(size_t i=0; i < n; ++i) {
+ std::cerr << msg[i];
+ }
+
+ std::cerr << std::endl << "GL Compile error" << std::endl;
+ std::cerr << src << std::endl;
+ throw 1;
+ }
+ return shader;
+}
+
+GLuint createShaderFile(std::string file, int shaderType, size_t Nlights,
+ size_t Nmaterials,
+ std::vector<std::string> const& defineflags)
+{
+ std::ifstream shaderFile;
+ shaderFile.open(file.c_str());
+ std::stringstream shaderSrc;
+
+#ifdef __APPLE__
+#define GLSL_VERSION "410"
+#else
+#define GLSL_VERSION "130"
+#endif
+
+ shaderSrc << "#version " << GLSL_VERSION << "\r\n";
+ shaderSrc << "#extension GL_ARB_uniform_buffer_object : enable"
+ << "\r\n";
+ shaderSrc << "#extension GL_ARB_shading_language_packing : enable"
+ << "\r\n";
+
+ size_t n=defineflags.size();
+ for(size_t i=0; i < n; ++i) {
+ shaderSrc << "#define " << defineflags[i] << "\r\n";
+ }
+
+ shaderSrc << "const int Nlights=" << Nlights << ";\r\n";
+ shaderSrc << "const int Nmaterials=" << Nmaterials << ";\r\n";
+
+ if(shaderFile) {
+ shaderSrc << shaderFile.rdbuf();
+ shaderFile.close();
+ } else {
+ throw 1;
+ }
+
+ return createShaders(shaderSrc.str().data(), shaderType, file);
+}
+#endif
diff --git a/graphics/asymptote/shaders.h b/graphics/asymptote/shaders.h
new file mode 100644
index 0000000000..f92b7010ab
--- /dev/null
+++ b/graphics/asymptote/shaders.h
@@ -0,0 +1,34 @@
+#ifndef __TOGL_SHADERSPROC
+#define __TOGL_SHADERSPROC
+
+#define GLEW_NO_GLU
+
+#ifdef __MSDOS__
+#define GLEW_STATIC
+#define _WIN32
+#endif
+
+#include "GL/glew.h"
+
+#ifdef __MSDOS__
+#undef _WIN32
+#include "GL/wglew.h"
+#include <GL/wglext.h>
+#endif
+
+#include <string>
+
+typedef std::pair<std::string, int> ShaderfileModePair;
+
+GLuint compileAndLinkShader(
+ std::vector<ShaderfileModePair> const& shaders,
+ size_t NLights, size_t NMaterials,
+ std::vector<std::string> const& defineflags);
+
+GLuint createShaders(GLchar const *src, int shaderType,
+ std::string const& filename);
+
+GLuint createShaderFile(std::string file, int shaderType, size_t Nlights,
+ size_t Nmaterials,
+ std::vector<std::string> const& constflags);
+#endif
diff --git a/graphics/asymptote/simpson.cc b/graphics/asymptote/simpson.cc
new file mode 100644
index 0000000000..85c8c08160
--- /dev/null
+++ b/graphics/asymptote/simpson.cc
@@ -0,0 +1,221 @@
+#include <cmath>
+#include <cassert>
+#include <cfloat>
+
+// Compute a numerical approximation to an integral via adaptive Simpson's Rule
+// This routine ignores underflow.
+
+const int nest=DBL_MANT_DIG;
+
+typedef struct {
+ bool left; // left interval?
+ double psum, f1t, f2t, f3t, dat, estr;
+} TABLE;
+
+bool // Returns true iff successful.
+simpson(double& integral, // Approximate value of the integral.
+ double (*f)(double), // Pointer to function to be integrated.
+ double a, double b, // Lower, upper limits of integration.
+ double acc, // Desired relative accuracy of integral.
+ // Try to make |error| <= acc*abs(integral).
+ double dxmax) // Maximum limit on the width of a subinterval
+// For periodic functions, dxmax should be
+// set to the period or smaller to prevent
+// premature convergence of Simpson's rule.
+{
+ double diff,area,estl,estr,alpha,da,dx,wt,est,fv[5];
+ TABLE table[nest],*p,*pstop;
+ static const double sixth=1.0/6.0;
+
+ bool success=true;
+ p=table;
+ pstop=table+nest-1;
+ p->left=true;
+ p->psum=0.0;
+ alpha=a;
+ da=b-a;
+ fv[0]=(*f)(alpha);
+ fv[2]=(*f)(alpha+0.5*da);
+ fv[4]=(*f)(alpha+da);
+ wt=sixth*da;
+ est=wt*(fv[0]+4.0*fv[2]+fv[4]);
+ area=est;
+
+ // Have estimate est of integral on (alpha, alpha+da).
+ // Bisect and compute estimates on left and right half intervals.
+ // integral is the best value for the integral.
+
+ for(;;) {
+ dx=0.5*da;
+ double arg=alpha+0.5*dx;
+ fv[1]=(*f)(arg);
+ fv[3]=(*f)(arg+dx);
+ wt=sixth*dx;
+ estl=wt*(fv[0]+4.0*fv[1]+fv[2]);
+ estr=wt*(fv[2]+4.0*fv[3]+fv[4]);
+ integral=estl+estr;
+ diff=est-integral;
+ area -= diff;
+
+ if(p >= pstop) success=false;
+ if(!success || (fabs(diff) <= acc*fabs(area) && da <= dxmax)) {
+ // Accept approximate integral.
+ // If it was a right interval, add results to finish at this level.
+ // If it was a left interval, process right interval.
+
+ for(;;) {
+ if(p->left == false) { // process right-half interval
+ alpha += da;
+ p->left=true;
+ p->psum=integral;
+ fv[0]=p->f1t;
+ fv[2]=p->f2t;
+ fv[4]=p->f3t;
+ da=p->dat;
+ est=p->estr;
+ break;
+ }
+ integral += p->psum;
+ if(--p <= table) return success;
+ }
+
+ } else {
+ // Raise level and store information for processing right-half interval.
+ ++p;
+ da=dx;
+ est=estl;
+ p->left=false;
+ p->f1t=fv[2];
+ p->f2t=fv[3];
+ p->f3t=fv[4];
+ p->dat=dx;
+ p->estr=estr;
+ fv[4]=fv[2];
+ fv[2]=fv[1];
+ }
+ }
+}
+
+// Use adaptive Simpson integration to determine the upper limit of
+// integration required to make the definite integral of a continuous
+// non-negative function close to a user specified sum.
+// This routine ignores underflow.
+
+bool // Returns true iff successful.
+unsimpson(double integral, // Given value for the integral.
+ double (*f)(double), // Pointer to function to be integrated.
+ double a, double& b, // Lower, upper limits of integration (a <= b).
+ // The value of b provided on entry is used
+ // as an initial guess; somewhat faster if the
+ // given value is an underestimation.
+ double acc, // Desired relative accuracy of b.
+ // Try to make |integral-area| <= acc*integral.
+ double& area, // Computed integral of f(x) on [a,b].
+ double dxmax, // Maximum limit on the width of a subinterval
+ // For periodic functions, dxmax should be
+ // set to the period or smaller to prevent
+ // premature convergence of Simpson's rule.
+ double dxmin=0) // Lower limit on sampling width.
+{
+ double diff,estl,estr,alpha,da,dx,wt,est,fv[5];
+ double sum,parea,pdiff,b2;
+ TABLE table[nest],*p,*pstop;
+ static const double sixth=1.0/6.0;
+
+ p=table;
+ pstop=table+nest-1;
+ p->psum=0.0;
+ alpha=a;
+ parea=0.0;
+ pdiff=0.0;
+
+ for(;;) {
+ p->left=true;
+ da=b-alpha;
+ fv[0]=(*f)(alpha);
+ fv[2]=(*f)(alpha+0.5*da);
+ fv[4]=(*f)(alpha+da);
+ wt=sixth*da;
+ est=wt*(fv[0]+4.0*fv[2]+fv[4]);
+ area=est;
+
+ // Have estimate est of integral on (alpha, alpha+da).
+ // Bisect and compute estimates on left and right half intervals.
+ // Sum is better value for integral.
+
+ bool cont=true;
+ while(cont) {
+ dx=0.5*da;
+ double arg=alpha+0.5*dx;
+ fv[1]=(*f)(arg);
+ fv[3]=(*f)(arg+dx);
+ wt=sixth*dx;
+ estl=wt*(fv[0]+4.0*fv[1]+fv[2]);
+ estr=wt*(fv[2]+4.0*fv[3]+fv[4]);
+ sum=estl+estr;
+ diff=est-sum;
+
+ assert(sum >= 0.0);
+ area=parea+sum;
+ b2=alpha+da;
+ if(fabs(fabs(integral-area)-fabs(pdiff))+fabs(diff) <= fv[4]*acc*(b2-a)){
+ b=b2;
+ return true;
+ }
+ if(fabs(integral-area) > fabs(pdiff+diff)) {
+ if(integral <= area) {
+ p=table;
+ p->left=true;
+ p->psum=parea;
+ } else {
+ if((fabs(diff) <= fv[4]*acc*da || dx <= dxmin) && da <= dxmax) {
+ // Accept approximate integral sum.
+ // If it was a right interval, add results to finish at this level.
+ // If it was a left interval, process right interval.
+
+ pdiff += diff;
+ for(;;) {
+ if(p->left == false) { // process right-half interval
+ parea += sum;
+ alpha += da;
+ p->left=true;
+ p->psum=sum;
+ fv[0]=p->f1t;
+ fv[2]=p->f2t;
+ fv[4]=p->f3t;
+ da=p->dat;
+ est=p->estr;
+ break;
+ }
+ sum += p->psum;
+ parea -= p->psum;
+ if(--p <= table) {
+ p=table;
+ p->psum=parea=sum;
+ alpha += da;
+ b += b-a;
+ cont=false;
+ break;
+ }
+ }
+ continue;
+ }
+ }
+ }
+ if(p >= pstop) return false;
+// Raise level and store information for processing right-half interval.
+ ++p;
+ da=dx;
+ est=estl;
+ p->psum=0.0;
+ p->left=false;
+ p->f1t=fv[2];
+ p->f2t=fv[3];
+ p->f3t=fv[4];
+ p->dat=dx;
+ p->estr=estr;
+ fv[4]=fv[2];
+ fv[2]=fv[1];
+ }
+ }
+}
diff --git a/graphics/asymptote/stack.cc b/graphics/asymptote/stack.cc
new file mode 100644
index 0000000000..7ffb6bcb59
--- /dev/null
+++ b/graphics/asymptote/stack.cc
@@ -0,0 +1,674 @@
+/*****
+ * stack.cc
+ * Andy Hammerlindl 2002/06/27
+ *
+ * The general stack machine used to run compiled camp code.
+ *****/
+
+#include <fstream>
+#include <sstream>
+
+#include "stack.h"
+#include "program.h"
+#include "callable.h"
+#include "errormsg.h"
+#include "util.h"
+#include "runtime.h"
+#include "process.h"
+
+#include "profiler.h"
+
+#ifdef DEBUG_STACK
+#include <iostream>
+
+namespace vm {
+void draw(ostream& out, frame *v);
+}
+#endif
+
+namespace run {
+void breakpoint(vm::stack *Stack, absyntax::runnable *r);
+}
+
+namespace vm {
+
+mem::list<bpinfo> bplist;
+
+namespace {
+position curPos = nullPos;
+const program::label nulllabel;
+}
+
+inline stack::vars_t base_frame(
+ size_t size,
+ size_t parentIndex,
+ stack::vars_t closure
+#ifdef DEBUG_FRAME
+ , string name
+#endif
+ )
+{
+ stack::vars_t vars;
+#ifdef SIMPLE_FRAME
+ vars = new item[size];
+ vars[parentIndex] = closure;
+#else
+# ifdef DEBUG_FRAME
+ assert(!name.empty());
+ vars = new frame(name, parentIndex, size);
+# else
+ vars = new frame(size);
+# endif
+ (*vars)[parentIndex] = closure;
+#endif
+
+ // TODO: Re-factor closure.
+ return vars;
+}
+
+#ifdef DEBUG_FRAME
+#define BASEFRAME(s,p,c,n) (base_frame((s), (p), (c), (n)))
+#else
+#define BASEFRAME(s,p,c,n) (base_frame((s), (p), (c)))
+#endif
+
+// Abstractions needed.
+//accessor(frame_handle)
+// operator[] for accessor
+
+
+inline stack::vars_t make_frame(lambda *l, stack::vars_t closure)
+{
+ return BASEFRAME(l->framesize, l->parentIndex, closure, l->name);
+}
+
+inline stack::vars_t make_pushframe(size_t size, stack::vars_t closure)
+{
+ assert(size >= 1);
+ return BASEFRAME(size, 0, closure, "<pushed frame>");
+}
+
+stack::vars_t make_dummyframe(string name)
+{
+ return BASEFRAME(1, 0, 0, "<dummy frame for "+name+">");
+}
+
+inline stack::vars_t make_globalframe(size_t size)
+{
+ assert(size > 0);
+#if SIMPLE_FRAME
+ // The global frame is an indirect frame. It holds one item, which is the
+ // link to another frame.
+ stack::vars_t direct = new item[1];
+ stack::vars_t indirect = new item[size];
+ direct[0] = indirect;
+ return direct;
+#else
+ return BASEFRAME(size, 0, 0, "<globals>");
+#if 0
+#ifdef DEBUG_FRAME
+ stack::vars_t vars = new frame("<pushed frame>", 0, size);
+#else
+ stack::vars_t vars = new frame(size);
+#endif
+ return vars;
+#endif
+#endif
+
+}
+
+inline void resize_frame(frame *f, size_t oldsize, size_t newsize)
+{
+ //assert("Need to fix this" == 0);
+ assert(newsize > oldsize);
+#if SIMPLE_FRAME
+ frame *old_indirect = get<frame *>(f[0]);
+ frame *new_indirect = new item[newsize];
+ std::copy(old_indirect, old_indirect+oldsize, new_indirect);
+ f[0] = new_indirect;
+#else
+ f->extend(newsize);
+#endif
+}
+
+
+
+
+void run(lambda *l)
+{
+ func f;
+ f.body = l;
+ stack s;
+ s.run(&f);
+}
+
+// Move arguments from stack to frame.
+void stack::marshall(size_t args, stack::vars_t vars)
+{
+ for (size_t i = args; i > 0; --i)
+#if SIMPLE_FRAME
+ vars[i-1] = pop();
+#else
+ (*vars)[i-1] = pop();
+#endif
+}
+
+#ifdef PROFILE
+
+#ifndef DEBUG_FRAME
+#warning "profiler needs DEBUG_FRAME for function names"
+#endif
+#ifndef DEBUG_BLTIN
+#warning "profiler needs DEBUG_BLTIN for builtin function names"
+#endif
+
+profiler prof;
+
+void dumpProfile() {
+ std::ofstream out("asyprof");
+ if (!out.fail())
+ prof.dump(out);
+}
+#endif
+
+void assessClosure(lambda *body) {
+ // If we have already determined if it needs closure, just return.
+ if (body->closureReq != lambda::MAYBE_NEEDS_CLOSURE)
+ return;
+
+ for (program::label l = body->code->begin(); l != body->code->end(); ++l)
+ if (l->op == inst::pushclosure ||
+ l->op == inst::pushframe) {
+ body->closureReq = lambda::NEEDS_CLOSURE;
+ return;
+ }
+
+ body->closureReq = lambda::DOESNT_NEED_CLOSURE;
+}
+
+void stack::run(func *f)
+{
+ lambda *body = f->body;
+
+#ifdef PROFILE
+ prof.beginFunction(body);
+#endif
+
+#ifdef DEBUG_STACK
+#ifdef DEBUG_FRAME
+ cout << "running lambda " + body->name + ": \n";
+#else
+ cout << "running lambda: \n";
+#endif
+ print(cout, body->code);
+ cout << endl;
+#endif
+
+ runWithOrWithoutClosure(body, 0, f->closure);
+
+#ifdef PROFILE
+ prof.endFunction(body);
+#endif
+}
+
+void stack::breakpoint(absyntax::runnable *r)
+{
+ lastPos=curPos;
+ indebugger=true;
+ ::run::breakpoint(this,r);
+ string s=vm::pop<string>(this);
+ debugOp=(s.length() > 0) ? s[0] : (char) 0;
+ indebugger=false;
+}
+
+void stack::debug()
+{
+ if(!curPos) return;
+ if(indebugger) {em.clear(); return;}
+
+ switch(debugOp) {
+ case 'i': // inst
+ breakpoint();
+ break;
+ case 's': // step
+ if((!curPos.match(lastPos.filename()) || !curPos.match(lastPos.Line())))
+ breakpoint();
+ break;
+ case 'n': // next
+ if(curPos.match(lastPos.filename()) && !curPos.match(lastPos.Line()))
+ breakpoint();
+ break;
+ case 'f': // file
+ if(!curPos.match(lastPos.filename()))
+ breakpoint();
+ break;
+ case 'r': // return
+ if(curPos.match(breakPos.filename()))
+ breakpoint();
+ break;
+ case 'c': // continue
+ default:
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p) {
+ if(curPos.match(p->f.name()) && curPos.match(p->f.line()) &&
+ (newline || !curPos.match(breakPos.filename()) ||
+ !curPos.match(breakPos.Line()))) {
+ breakPos=curPos;
+ breakpoint(p->r);
+ newline=false;
+ break;
+ }
+ if(!newline &&
+ (curPos.match(lastPos.filename()) && !curPos.match(lastPos.Line())))
+ newline=true;
+ }
+ break;
+ }
+}
+
+
+void stack::runWithOrWithoutClosure(lambda *l, vars_t vars, vars_t parent)
+{
+ // The size of the frame (when running without closure).
+ size_t frameSize = l->parentIndex;
+
+#ifdef SIMPLE_FRAME
+ // Link to the variables, be they in a closure or on the stack.
+ frame *varlink;
+
+# define SET_VARLINK assert(vars); varlink = vars;
+# define VAR(n) ( (varlink)[(n) + frameStart] )
+# define FRAMEVAR(frame,n) (frame[(n)])
+#else
+ // Link to the variables, be they in a closure or on the stack.
+ mem::vector<item> *varlink=NULL;
+
+# define SET_VARLINK assert(vars); varlink = &vars->vars
+# define VAR(n) ( (*varlink)[(n) + frameStart] )
+# define FRAMEVAR(frame,n) ((*frame)[(n)])
+#endif
+
+ size_t frameStart = 0;
+
+ // Set up the closure, if necessary.
+ if (vars == 0)
+ {
+#ifndef SIMPLE_FRAME
+ assessClosure(l);
+ if (l->closureReq == lambda::NEEDS_CLOSURE)
+#endif
+ {
+ /* make new activation record */
+ vars = vm::make_frame(l, parent);
+ assert(vars);
+ }
+#ifndef SIMPLE_FRAME
+ else
+ {
+ assert(l->closureReq == lambda::DOESNT_NEED_CLOSURE);
+
+ // Use the stack to store variables.
+ varlink = &theStack;
+
+ // Record where the parameters start on the stack.
+ frameStart = theStack.size() - frameSize;
+
+ // Add the parent's closure to the frame.
+ push(parent);
+ ++frameSize;
+
+ size_t newFrameSize = (size_t)l->framesize;
+
+ if (newFrameSize > frameSize) {
+ theStack.resize(frameStart + newFrameSize);
+ frameSize = newFrameSize;
+ }
+ }
+#endif
+ }
+
+ if (vars) {
+ marshall(l->parentIndex, vars);
+
+ SET_VARLINK;
+ }
+
+ /* start the new function */
+ program::label ip = l->code->begin();
+ position& topPos=processData().topPos;
+ string& fileName=processData().fileName;
+
+ try {
+ for (;;) {
+ const inst &i = *ip;
+ curPos = i.pos;
+
+ if(curPos.filename() == fileName)
+ topPos=curPos;
+
+#ifdef PROFILE
+ prof.recordInstruction();
+#endif
+
+#ifdef DEBUG_STACK
+ printInst(cout, ip, l->code->begin());
+ cout << " (";
+ i.pos.printTerse(cout);
+ cout << ")\n";
+#endif
+
+ if(settings::verbose > 4) em.trace(curPos);
+
+ if(!bplist.empty()) debug();
+
+ if(errorstream::interrupt) throw interrupted();
+
+ switch (i.op)
+ {
+ case inst::varpush:
+ push(VAR(get<Int>(i)));
+ break;
+
+ case inst::varsave:
+ VAR(get<Int>(i)) = top();
+ break;
+
+#ifdef COMBO
+ case inst::varpop:
+ VAR(get<Int>(i)) = pop();
+ break;
+#endif
+
+ case inst::ret: {
+ if (vars == 0)
+ // Delete the frame from the stack.
+ // TODO: Optimize for common cases.
+ theStack.erase(theStack.begin() + frameStart,
+ theStack.begin() + frameStart + frameSize);
+ return;
+ }
+
+ case inst::pushframe:
+ {
+ assert(vars);
+ Int size = get<Int>(i);
+ vars=make_pushframe(size, vars);
+
+ SET_VARLINK;
+
+ break;
+ }
+
+ case inst::popframe:
+ {
+ assert(vars);
+ vars=get<frame *>(VAR(0));
+
+ SET_VARLINK;
+
+ break;
+ }
+
+ case inst::pushclosure:
+ assert(vars);
+ push(vars);
+ break;
+
+ case inst::nop:
+ break;
+
+ case inst::pop:
+ pop();
+ break;
+
+ case inst::intpush:
+ case inst::constpush:
+ push(i.ref);
+ break;
+
+ case inst::fieldpush: {
+ vars_t frame = pop<vars_t>();
+ if (!frame)
+ error("dereference of null pointer");
+ push(FRAMEVAR(frame, get<Int>(i)));
+ break;
+ }
+
+ case inst::fieldsave: {
+ vars_t frame = pop<vars_t>();
+ if (!frame)
+ error("dereference of null pointer");
+ FRAMEVAR(frame, get<Int>(i)) = top();
+ break;
+ }
+
+#if COMBO
+ case inst::fieldpop: {
+#error NOT REIMPLEMENTED
+ vars_t frame = pop<vars_t>();
+ if (!frame)
+ error("dereference of null pointer");
+ FRAMEVAR(get<Int>(i)) = pop();
+ break;
+ }
+#endif
+
+
+ case inst::builtin: {
+ bltin func = get<bltin>(i);
+#ifdef PROFILE
+ prof.beginFunction(func);
+#endif
+ func(this);
+#ifdef PROFILE
+ prof.endFunction(func);
+#endif
+ break;
+ }
+
+ case inst::jmp:
+ ip = get<program::label>(i);
+ continue;
+
+ case inst::cjmp:
+ if (pop<bool>()) { ip = get<program::label>(i); continue; }
+ break;
+
+ case inst::njmp:
+ if (!pop<bool>()) { ip = get<program::label>(i); continue; }
+ break;
+
+ case inst::jump_if_not_default:
+ if (!isdefault(pop())) { ip = get<program::label>(i); continue; }
+ break;
+
+#ifdef COMBO
+ case inst::gejmp: {
+ Int y = pop<Int>();
+ Int x = pop<Int>();
+ if (x>=y)
+ { ip = get<program::label>(i); continue; }
+ break;
+ }
+
+#if 0
+ case inst::jump_if_func_eq: {
+ callable * b=pop<callable *>();
+ callable * a=pop<callable *>();
+ if (a->compare(b))
+ { ip = get<program::label>(i); continue; }
+ break;
+ }
+
+ case inst::jump_if_func_neq: {
+ callable * b=pop<callable *>();
+ callable * a=pop<callable *>();
+ if (!a->compare(b))
+ { ip = get<program::label>(i); continue; }
+ break;
+ }
+#endif
+#endif
+
+ case inst::push_default:
+ push(Default);
+ break;
+
+ case inst::popcall: {
+ /* get the function reference off of the stack */
+ callable* f = pop<callable*>();
+ f->call(this);
+ break;
+ }
+
+ case inst::makefunc: {
+ func *f = new func;
+ f->closure = pop<vars_t>();
+ f->body = get<lambda*>(i);
+
+ push((callable*)f);
+ break;
+ }
+
+ default:
+ error("Internal VM error: Bad stack operand");
+ }
+
+#ifdef DEBUG_STACK
+ draw(cerr);
+ vm::draw(cerr,vars);
+ cerr << "\n";
+#endif
+
+ ++ip;
+ }
+ } catch (bad_item_value&) {
+ error("Trying to use uninitialized value.");
+ }
+
+#undef SET_VARLINK
+#undef VAR
+#undef FRAMEVAR
+}
+
+void stack::load(string index) {
+ frame *inst=instMap[index];
+ if (inst)
+ push(inst);
+ else {
+ func f;
+ assert(initMap);
+ f.body=(*initMap)[index];
+ assert(f.body);
+ run(&f);
+ instMap[index]=get<frame *>(top());
+ }
+}
+
+
+#ifdef DEBUG_STACK
+
+const size_t MAX_ITEMS=20;
+
+void stack::draw(ostream& out)
+{
+// out.setf(out.hex);
+
+ out << "operands:";
+ stack_t::const_iterator left = theStack.begin();
+ if (theStack.size() > MAX_ITEMS) {
+ left = theStack.end()-MAX_ITEMS;
+ out << " ...";
+ }
+ else
+ out << " ";
+
+ while (left != theStack.end())
+ {
+ if (left != theStack.begin())
+ out << " | " ;
+ out << *left;
+ left++;
+ }
+ out << "\n";
+}
+
+void draw(ostream& out, frame* v)
+{
+ out << "vars:" << endl;
+
+ while (!!v) {
+ item link=(*v)[v->getParentIndex()];
+
+ out << " " << v->getName() << ": ";
+
+ for (size_t i = 0; i < MAX_ITEMS && i < v->size(); i++) {
+ if (i > 0)
+ out << " | ";
+ out << i << ": ";
+
+ if (i == v->getParentIndex()) {
+ try {
+ frame *parent = get<frame *>(link);
+ out << (parent ? "link" : "----");
+ } catch (bad_item_value&) {
+ out << "non-link " << (*v)[0];
+ }
+ } else {
+ out << (*v)[i];
+ }
+ }
+
+ if (v->size() > MAX_ITEMS)
+ out << "...";
+ out << "\n";
+
+
+ frame *parent;
+ try {
+ parent = get<frame *>(link);
+ } catch (bad_item_value&) {
+ parent = 0;
+ }
+
+ v = parent;
+ }
+}
+#endif // DEBUG_STACK
+
+position getPos() {
+ return curPos;
+}
+
+void errornothrow(const char* message)
+{
+ em.error(curPos);
+ em << message;
+ em.sync();
+}
+
+void error(const char* message)
+{
+ errornothrow(message);
+ throw handled_error();
+}
+
+void error(const ostringstream& message)
+{
+ const string& s=message.str();
+ error(s.c_str());
+}
+
+const size_t STARTING_GLOBALS_SIZE = 1;
+interactiveStack::interactiveStack()
+ : globals(make_globalframe(STARTING_GLOBALS_SIZE)),
+ globals_size(STARTING_GLOBALS_SIZE) {}
+
+void interactiveStack::run(lambda *codelet) {
+ if (globals_size < codelet->framesize) {
+ resize_frame(globals, globals_size, codelet->framesize);
+ globals_size = codelet->framesize;
+ }
+ stack::runWithOrWithoutClosure(codelet, globals, 0);
+}
+
+} // namespace vm
diff --git a/graphics/asymptote/stack.h b/graphics/asymptote/stack.h
new file mode 100644
index 0000000000..df072b5157
--- /dev/null
+++ b/graphics/asymptote/stack.h
@@ -0,0 +1,167 @@
+/*****
+ * stack.h
+ * Andy Hammerlindl 2002/06/27
+ *
+ * The general stack machine used to run compiled camp code.
+ *****/
+
+#ifndef STACK_H
+#define STACK_H
+
+#include <iostream>
+
+#include "errormsg.h"
+#include "vm.h"
+#include "item.h"
+#include "absyn.h"
+
+namespace vm {
+
+struct func;
+class program;
+struct lambda;
+class importInitMap;
+
+struct bpinfo : public gc {
+ fileinfo f;
+ absyntax::runnable *r;
+
+ bpinfo(const string& filename, size_t lineNum,
+ absyntax::runnable *r=NULL) :
+ f(fileinfo(filename,lineNum)), r(r) {}
+};
+
+inline bool operator == (const bpinfo& a, const bpinfo& b)
+{
+ return a.f == b.f;
+}
+
+extern mem::list<bpinfo> bplist;
+
+class runnable;
+
+extern bool indebugger;
+
+class stack {
+public:
+ typedef frame* vars_t;
+
+ struct importInitMap {
+ virtual ~importInitMap() {}
+ virtual lambda *operator[](string) = 0;
+ };
+
+private:
+ // stack for operands
+ typedef mem::vector<item> stack_t;
+ stack_t theStack;
+
+ void draw(ostream& out);
+
+ // The initializer functions for imports, indexed by name.
+ importInitMap *initMap;
+
+ // The stack stores a map of initialized imported modules by name, so that
+ // each module is initialized only once and each import refers to the same
+ // instance.
+ typedef mem::map<CONST string,frame *> importInstanceMap;
+ importInstanceMap instMap;
+
+ // One can associate an environment to embedded code while running.
+ trans::coenv *e;
+
+ // Debugger variables:
+ char debugOp;
+ position lastPos, breakPos;
+ bool newline;
+
+ // Move arguments from stack to frame.
+ void marshall(size_t args, stack::vars_t vars);
+
+public:
+ stack() : e(0), debugOp(0), lastPos(nullPos),
+ breakPos(nullPos), newline(false) {};
+
+ virtual ~stack() {};
+
+ void setInitMap(importInitMap *i) {
+ initMap=i;
+ }
+
+ void setEnvironment(trans::coenv *e) {
+ this->e=e;
+ }
+
+ trans::coenv *getEnvironment() {
+ return e;
+ }
+
+ // Runs a lambda. If vars is non-null, it is used to store the variables of
+ // the lambda. Otherwise, the method allocates a closure only if needed.
+ void runWithOrWithoutClosure(lambda *l, vars_t vars, vars_t parent);
+
+ // Executes a function on top of the stack.
+ void run(func *f);
+
+ void breakpoint(absyntax::runnable *r=NULL);
+ void debug();
+
+ // Put an import (indexed by name) on top of the stack, initializing it if
+ // necessary.
+ void load(string index);
+
+ // These are so that built-in functions can easily manipulate the stack
+ void push(item next) {
+ theStack.push_back(next);
+ }
+ template <typename T>
+ void push(T next) {
+ push((item)next);
+ }
+ item top() {
+ return theStack.back();
+ }
+ item pop() {
+ item ret = theStack.back();
+ theStack.pop_back();
+ return ret;
+ }
+ template <typename T>
+ T pop()
+ {
+ return get<T>(pop());
+ }
+};
+
+inline item pop(stack* s)
+{
+ return s->pop();
+}
+
+template <typename T>
+inline T pop(stack* s)
+{
+ return get<T>(pop(s));
+}
+
+template <typename T>
+inline T pop(stack* s, T defval)
+{
+ item it=pop(s);
+ return isdefault(it) ? defval : get<T>(it);
+}
+
+class interactiveStack : public stack {
+ vars_t globals;
+ size_t globals_size;
+public:
+ interactiveStack();
+
+ // Run a codelet, a small piece of code that uses globals as its frame.
+ void run(lambda *codelet);
+};
+
+} // namespace vm
+
+#endif // STACK_H
+
diff --git a/graphics/asymptote/statistics.h b/graphics/asymptote/statistics.h
new file mode 100644
index 0000000000..7e3d2d340d
--- /dev/null
+++ b/graphics/asymptote/statistics.h
@@ -0,0 +1,51 @@
+#ifndef __statistics_h__
+#define __statistics_h__ 1
+
+#include <math.h>
+
+namespace utils {
+
+class statistics {
+ unsigned int N;
+ double A;
+ double varL;
+ double varH;
+public:
+ statistics() : N(0), A(0.0), varL(0.0), varH(0.0) {}
+ double count() {return N;}
+ double mean() {return A;}
+ void add(double t) {
+ ++N;
+ double diff=t-A;
+ A += diff/N;
+ double v=diff*(t-A);
+ if(diff < 0.0)
+ varL += v;
+ else
+ varH += v;
+ }
+ double stdev(double var, double f) {
+ double factor=N > f ? f/(N-f) : 0.0;
+ return sqrt(var*factor);
+ }
+ double stdev() {
+ return stdev(varL+varH,1.0);
+ }
+ double stdevL() {
+ return stdev(varL,2.0);
+ }
+ double stdevH() {
+ return stdev(varH,2.0);
+ }
+ void output(const char *text, unsigned int m) {
+ std::cout << text << ":\n"
+ << m << "\t"
+ << A << "\t"
+ << stdevL() << "\t"
+ << stdevH() << std::endl;
+ }
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/stm.cc b/graphics/asymptote/stm.cc
new file mode 100644
index 0000000000..b45e6f98e4
--- /dev/null
+++ b/graphics/asymptote/stm.cc
@@ -0,0 +1,504 @@
+/*****
+ * stm.cc
+ * Andy Hammerlindl 2002/8/30
+ *
+ * Statements are everything in the language that do something on their
+ * own. Statements are different from declarations in that statements
+ * do not modify the environment. Translation of a statement puts the
+ * stack code to run it into the instruction stream.
+ *****/
+
+#include <fstream>
+#include "errormsg.h"
+#include "settings.h"
+#include "coenv.h"
+#include "exp.h"
+#include "stm.h"
+
+#include "symbol.h"
+#include "opsymbols.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+
+void stm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"stm",indent);
+}
+
+
+void emptyStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"emptyStm",indent);
+}
+
+
+void blockStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"blockStm",indent);
+
+ base->prettyprint(out, indent+1);
+}
+
+
+void expStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"expStm",indent);
+
+ body->prettyprint(out, indent+1);
+}
+
+void baseExpTrans(coenv &e, exp *expr)
+{
+ types::ty_kind kind = expr->trans(e)->kind;
+ if (kind != types::ty_void)
+ // Remove any value it puts on the stack.
+ e.c.encodePop();
+}
+
+void expStm::trans(coenv &e) {
+ baseExpTrans(e, body);
+}
+
+// For an object such as currentpicture, write 'picture currentpicture' to
+// give some information. Only do this when the object has a name.
+void tryToWriteTypeOfExp(types::ty *t, exp *body)
+{
+ symbol name=body->getName();
+ if (!name)
+ return;
+
+ overloaded *set = dynamic_cast<overloaded *>(t);
+ if (set)
+ for(ty_vector::iterator ot=set->sub.begin(); ot!=set->sub.end(); ++ot)
+ tryToWriteTypeOfExp(*ot, body);
+ else {
+ cout << "<";
+ t->printVar(cout, name);
+ cout << ">" << endl;
+ }
+}
+
+// From dec.cc:
+varEntry *makeVarEntry(position pos, coenv &e, record *r, types::ty *t);
+
+void storeExp(coenv &e, types::ty *t, exp *expr) {
+ assert(t->kind != ty_error);
+ assert(t->kind != ty_void);
+ assert(t->kind != ty_overloaded);
+
+ expr->transAsType(e, t);
+
+ // Store the value in a new variable of the proper type.
+ varEntry *v = makeVarEntry(expr->getPos(), e, 0, t);
+ e.e.addVar(symbol::trans("operator answer"), v);
+ v->getLocation()->encode(WRITE, expr->getPos(), e.c);
+ e.c.encodePop();
+}
+
+void storeAndWriteExp(coenv &e, types::ty *t, exp *expr) {
+ storeExp(e, t, expr);
+
+ position pos=expr->getPos();
+ baseExpTrans(e, new callExp(pos, new nameExp(pos, "write"),
+ new nameExp(pos, "operator answer")));
+}
+
+void tryToWriteExp(coenv &e, exp *expr)
+{
+ position pos=expr->getPos();
+ types::ty *t=expr->cgetType(e);
+
+ if(!t) return;
+
+ // If the original expression is bad, just print the errors.
+ // If it is a function which returns void, just call the function.
+ if (t->kind == ty_error || t->kind == ty_void) {
+ baseExpTrans(e, expr);
+ return;
+ }
+
+ exp *callee=new nameExp(pos, symbol::trans("write"));
+ exp *call=new callExp(pos, callee, expr);
+
+ types::ty *ct=call->getType(e);
+ if (ct->kind == ty_error || ct->kind == ty_overloaded) {
+ if (t->kind == ty_overloaded) {
+ // Translate the expr in order to print the ambiguity error first.
+ expr->trans(e);
+ em.sync();
+ assert(em.errors());
+
+ // Then, write out all of the types.
+ tryToWriteTypeOfExp(t, expr);
+ }
+ else {
+ // Write the type of the expression and, since it is unique, assign it to
+ // 'operator answer' even though its value isn't printed.
+ tryToWriteTypeOfExp(t, expr);
+ storeExp(e, t, expr);
+ }
+ }
+ else if (t->kind == ty_overloaded) {
+ // If the exp is overloaded, but the act of writing makes it
+ // unambiguous, add a suffix to the output to warn the user of this.
+ exp *suffix=new nameExp(pos,
+ symbol::trans("overloadedMessage"));
+ exp *callWithSuffix=new callExp(pos,
+ callee, expr, suffix);
+
+ if (callWithSuffix->getType(e)->kind != ty_error)
+ baseExpTrans(e, callWithSuffix);
+ else
+ baseExpTrans(e, call);
+ }
+ else {
+ // Interactive writing can proceed normally.
+ storeAndWriteExp(e, t, expr);
+ }
+}
+
+void expStm::interactiveTrans(coenv &e)
+{
+ // First check if it is the kind of expression that should be written.
+ if (body->writtenToPrompt() &&
+ settings::getSetting<bool>("interactiveWrite"))
+ tryToWriteExp(e, body);
+ else
+ baseExpTrans(e, body);
+}
+
+
+void ifStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"ifStm",indent);
+
+ test->prettyprint(out, indent+1);
+ onTrue->prettyprint(out, indent+1);
+ if (onFalse)
+ onFalse->prettyprint(out, indent+1);
+}
+
+void ifStm::trans(coenv &e)
+{
+ label elseLabel = e.c.fwdLabel();
+ label end = e.c.fwdLabel();
+
+ test->transConditionalJump(e, false, elseLabel);
+
+ onTrue->markTrans(e);
+
+ if (onFalse) {
+ // Encode the jump around the 'else' clause at the end of the 'if' clause
+ e.c.useLabel(inst::jmp,end);
+
+ e.c.defLabel(elseLabel);
+ onFalse->markTrans(e);
+ } else {
+ e.c.defLabel(elseLabel);
+ }
+
+
+ e.c.defLabel(end);
+}
+
+
+void transLoopBody(coenv &e, stm *body) {
+ // The semantics of the language are defined so that any variable declared
+ // inside a loop are new variables for each iteration of the loop. For
+ // instance, the code
+ //
+ // int f();
+ // for (int i = 0; i < 10; ++i) {
+ // int j=10*i;
+ // if (i == 5)
+ // f = new int() { return j; };
+ // }
+ // write(f());
+ //
+ // will write 50. This is implemented by allocating a new frame for each
+ // iteration. However, this can have a big performance hit, so we first
+ // translate the code without the frame, check if it needed the closure, and
+ // rewrite the code if necessary.
+
+ label start = e.c.defNewLabel();
+
+ // Encode a no-op, in case we need to jump over the default implementation
+ // to a special case.
+ e.c.encode(inst::nop);
+
+ body->markTrans(e);
+
+ // Don't re-translate if there were errors.
+ if (em.errors())
+ return;
+
+ if (e.c.usesClosureSinceLabel(start)){
+ // Jump over the old section.
+ label end = e.c.defNewLabel();
+ e.c.encodePatch(start, end);
+
+ // Let coder know that break and continue need to pop the frame.
+ e.c.loopPushesFrame();
+
+ e.c.encodePushFrame();
+ body->markTrans(e);
+ e.c.encodePopFrame();
+ }
+}
+
+void whileStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"whileStm",indent);
+
+ test->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void whileStm::trans(coenv &e)
+{
+ label end = e.c.fwdLabel();
+ label start = e.c.defNewLabel();
+ e.c.pushLoop(start, end);
+
+ test->transConditionalJump(e, false, end);
+
+ transLoopBody(e,body);
+
+ e.c.useLabel(inst::jmp,start);
+ e.c.defLabel(end);
+
+ e.c.popLoop();
+}
+
+
+void doStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"doStm",indent);
+
+ body->prettyprint(out, indent+1);
+ test->prettyprint(out, indent+1);
+}
+
+void doStm::trans(coenv &e)
+{
+ label testLabel = e.c.fwdLabel();
+ label end = e.c.fwdLabel();
+ e.c.pushLoop(testLabel, end);
+
+ label start = e.c.defNewLabel();
+
+ transLoopBody(e,body);
+
+ e.c.defLabel(testLabel);
+
+ test->transConditionalJump(e, true, start);
+
+ e.c.defLabel(end);
+
+ e.c.popLoop();
+}
+
+
+void forStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"forStm",indent);
+
+ if (init) init->prettyprint(out, indent+1);
+ if (test) test->prettyprint(out, indent+1);
+ if (update) update->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void forStm::trans(coenv &e)
+{
+ // Any vardec in the initializer needs its own scope.
+ e.e.beginScope();
+ if (init)
+ init->markTrans(e);
+
+ label ctarget = e.c.fwdLabel();
+ label end = e.c.fwdLabel();
+ e.c.pushLoop(ctarget, end);
+
+ label start = e.c.defNewLabel();
+ if(test) {
+ test->transConditionalJump(e, false, end);
+ }
+
+ transLoopBody(e,body);
+
+ e.c.defLabel(ctarget);
+
+ if (update)
+ update->markTrans(e);
+ e.c.useLabel(inst::jmp,start);
+
+ e.c.defLabel(end);
+
+ e.c.popLoop();
+
+ e.e.endScope();
+}
+
+void extendedForStm::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "extendedForStm: '" << var << "'\n";
+
+ start->prettyprint(out, indent+1);
+ set->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void extendedForStm::trans(coenv &e) {
+ // Translate into the syntax:
+ //
+ // start[] a = set;
+ // for (int i=0; i < a.length; ++i) {
+ // start var=a[i];
+ // body
+ // }
+
+ position pos=getPos();
+
+ // Use gensyms for the variable names so as not to pollute the namespace.
+ symbol a=symbol::gensym("a");
+ symbol i=symbol::gensym("i");
+
+ // Get the start type. Handle type inference as a special case.
+ types::ty *t = start->trans(e, true);
+ if (t->kind == types::ty_inferred) {
+
+ // First ensure the array expression is an unambiguous array.
+ types::ty *at = set->cgetType(e);
+ if (at->kind != ty_array) {
+ em.error(set->getPos());
+ em << "expression is not an array of inferable type";
+
+ // On failure, don't bother trying to translate the loop.
+ return;
+ }
+
+ // var a=set;
+ tyEntryTy tet(pos, primInferred());
+ decid dec1(pos, new decidstart(pos, a), set);
+ vardec(pos, &tet, &dec1).trans(e);
+ }
+ else {
+ // start[] a=set;
+ arrayTy at(pos, start, new dimensions(pos));
+ decid dec1(pos, new decidstart(pos, a), set);
+ vardec(pos, &at, &dec1).trans(e);
+ }
+
+ // { start var=a[i]; body }
+ block b(pos);
+ decid dec2(pos,
+ new decidstart(pos, var),
+ new subscriptExp(pos, new nameExp(pos, a),
+ new nameExp(pos, i)));
+ b.add(new vardec(pos, start, &dec2));
+ b.add(body);
+
+ // for (int i=0; i < a.length; ++i)
+ // <block>
+ forStm(pos,
+ new vardec(pos, new tyEntryTy(pos, primInt()),
+ new decid(pos,
+ new decidstart(pos, i),
+ new intExp(pos, 0))),
+ new binaryExp(pos,
+ new nameExp(pos, i),
+ SYM_LT,
+ new nameExp(pos,
+ new qualifiedName(pos,
+ new simpleName(pos, a),
+ symbol::trans("length")))),
+ new expStm(pos, new prefixExp(pos, new nameExp(pos, i), SYM_PLUS)),
+ new blockStm(pos, &b)).trans(e);
+}
+
+
+void breakStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"breakStm",indent);
+}
+
+void breakStm::trans(coenv &e)
+{
+ if (!e.c.encodeBreak()) {
+ em.error(getPos());
+ em << "break statement outside of a loop";
+ }
+}
+
+
+void continueStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"continueStm",indent);
+}
+
+void continueStm::trans(coenv &e)
+{
+ if (!e.c.encodeContinue()) {
+ em.error(getPos());
+ em << "continue statement outside of a loop";
+ }
+}
+
+
+void returnStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "returnStm",indent);
+
+ if (value)
+ value->prettyprint(out, indent+1);
+}
+
+void returnStm::trans(coenv &e)
+{
+ types::ty *t = e.c.getReturnType();
+
+ if (t->kind == ty_void) {
+ if (value) {
+ em.error(getPos());
+ em << "function cannot return a value";
+ }
+ if (e.c.isRecord())
+ e.c.encode(inst::pushclosure);
+ }
+ else {
+ if (value) {
+ value->transToType(e, t);
+ }
+ else {
+ em.error(getPos());
+ em << "function must return a value";
+ }
+ }
+
+ // NOTE: Currently, a return statement in a module definition will end
+ // the initializer. Should this be allowed?
+ e.c.encode(inst::ret);
+}
+
+
+void stmExpList::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "stmExpList",indent);
+
+ for (mem::list<stm *>::iterator p = stms.begin(); p != stms.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+void stmExpList::trans(coenv &e)
+{
+ for (mem::list<stm *>::iterator p = stms.begin(); p != stms.end(); ++p)
+ (*p)->markTrans(e);
+}
+
+
+} // namespace absyntax
diff --git a/graphics/asymptote/stm.h b/graphics/asymptote/stm.h
new file mode 100644
index 0000000000..d0cf203108
--- /dev/null
+++ b/graphics/asymptote/stm.h
@@ -0,0 +1,232 @@
+/*****
+ * stm.h
+ * Andy Hammerlindl 2002/8/30
+ *
+ * Statements are objects in the language that do something on their
+ * own. Statements are different from declarations in that statements
+ * do not modify the environment. Translation of a statements puts the
+ * stack code to run it into the instruction stream.
+ *****/
+
+#ifndef STM_H
+#define STM_H
+
+#include "types.h"
+#include "symbol.h"
+#include "dec.h"
+
+namespace trans {
+class coenv;
+}
+
+namespace absyntax {
+
+using trans::coenv;
+using sym::symbol;
+
+class stm : public runnable {
+public:
+ stm(position pos)
+ : runnable(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *) {
+ // Ignore the record.
+ trans(e);
+ }
+
+ void trans(coenv &e) = 0;
+};
+
+class emptyStm : public stm {
+public:
+ emptyStm(position pos)
+ : stm(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &) {}
+};
+
+// Wrapper around a block to use it as a statement.
+class blockStm : public stm {
+ block *base;
+
+public:
+ blockStm(position pos, block *base)
+ : stm(pos), base(base) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e) {
+ return base->trans(e);
+ }
+
+ // A block is guaranteed to return iff its last statement is
+ // guaranteed to return.
+ bool returns() {
+ return base->returns();
+ }
+
+};
+
+// A statement that consist of a single expression to evaluate.
+class expStm : public stm {
+ exp *body;
+
+public:
+ expStm(position pos, exp *body)
+ : stm(pos), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ // Should be called when running an expStm at the interactive prompt.
+ // The code will "write" the value of the expression at the prompt if
+ // possible.
+ void interactiveTrans(coenv &e);
+};
+
+class ifStm : public stm {
+ exp *test;
+ stm *onTrue;
+ stm *onFalse;
+
+public:
+ ifStm(position pos, exp *test, stm* onTrue, stm* onFalse = 0)
+ : stm(pos), test(test), onTrue(onTrue), onFalse(onFalse) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ // An if statement is guaranteed to return iff both its pieces are
+ // guaranteed to return.
+ bool returns() {
+ if (onTrue == 0 || onFalse == 0)
+ return false;
+ return onTrue->returns() && onFalse->returns();
+ }
+};
+
+class whileStm : public stm {
+ exp *test;
+ stm *body;
+
+public:
+ whileStm(position pos, exp *test, stm *body)
+ : stm(pos), test(test), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class doStm : public stm {
+ stm *body;
+ exp *test;
+
+public:
+ doStm(position pos, stm *body, exp *test)
+ : stm(pos), body(body), test(test) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class forStm : public stm {
+ runnable *init;
+ exp *test;
+ runnable *update;
+ stm *body;
+
+public:
+ forStm(position pos, runnable *init, exp *test, runnable *update, stm *body)
+ : stm(pos), init(init), test(test), update(update), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class extendedForStm : public stm {
+ ty *start;
+ symbol var;
+ exp *set;
+
+ stm *body;
+
+public:
+ extendedForStm(position pos, ty *start, symbol var, exp *set, stm *body)
+ : stm(pos), start(start), var(var), set(set), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+
+class breakStm : public stm {
+public:
+ breakStm(position pos)
+ : stm(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class continueStm : public stm {
+public:
+ continueStm(position pos)
+ : stm(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class returnStm : public stm {
+ exp *value;
+
+public:
+ returnStm(position pos, exp *value = 0)
+ : stm(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ // A return statement is, of course, guaranteed to return.
+ bool returns() {
+ return true;
+ }
+};
+
+
+// Used at the start of for loops.
+class stmExpList : public stm {
+ mem::list<stm *> stms;
+
+public:
+ stmExpList(position pos)
+ : stm(pos) {}
+
+ // To ensure list deallocates properly.
+ virtual ~stmExpList() {}
+
+ void add(stm *s) {
+ stms.push_back(s);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/graphics/asymptote/symbol.cc b/graphics/asymptote/symbol.cc
new file mode 100644
index 0000000000..16352cff89
--- /dev/null
+++ b/graphics/asymptote/symbol.cc
@@ -0,0 +1,345 @@
+/*****
+ * symbol.cc
+ * Andy Hammerlindl 2002/06/18
+ *
+ * Creates symbols from strings so that multiple calls for a symbol of
+ * the same string will return an identical object.
+ *****/
+
+#include <cstring>
+#include <cstdlib>
+
+using std::strlen;
+
+
+#include "settings.h"
+#include "symbol.h"
+
+namespace sym {
+
+const char USED = 1;
+const char SKIP = 2;
+
+struct symbolRecord {
+ // When a symbol is entered into the table, its hash is computed. If the
+ // corresponding entry in the table is full, this value is incremented until
+ // an empty slot is found. hashplus stores the end value.
+ // Each symbol has a unique hashplus value, even if there is a collision in
+ // the original hashing function.
+ uint hashplus;
+
+ // Whether the cell of the table is empty, in use, or a "skip" entry due to
+ // a resizing of the table.
+ unsigned char flag;
+
+ // Pointer to a copy of the string (allocated on the heap). This string
+ // will never be deallocated. Symbols, in essence, last forever.
+ char *s;
+};
+
+// The table size must be a power of two so that (h % tableSize) can be
+// replaced by (h & tableMask). 1 << 15 was chosen based on the number of
+// unique symbols (roughly 4000) which occured in all of the base modules.
+const size_t SYMBOL_TABLE_BASE_CAPACITY = 1 << 15;
+symbolRecord baseSymbolTable[SYMBOL_TABLE_BASE_CAPACITY];
+
+symbolRecord *table = baseSymbolTable;
+size_t tableCapacity = SYMBOL_TABLE_BASE_CAPACITY;
+uint tableMask = 0;
+size_t tableSize = 0;
+
+symbolRecord &recordByHashplus(uint h)
+{
+ return table[h & tableMask];
+}
+
+GCInit symbol::initialize;
+symbol symbol::nullsym;
+symbol symbol::initsym;
+symbol symbol::castsym;
+symbol symbol::ecastsym;
+
+const char *nullsymstr = "<nullsym>";
+
+void initTable() {
+ tableMask = (uint)(tableCapacity - 1);
+ tableSize = 0;
+
+ // Set every entry to empty. (Is this faster than memsetting the whole
+ // thing?)
+ for (size_t i = 0; i < tableCapacity; ++i)
+ table[i].flag = 0;
+
+ // The zeroth entry is reserved for the "null" symbol.
+ if (table == baseSymbolTable) {
+ table[0].flag = USED;
+ table[0].s = new char[strlen(nullsymstr) + 1];
+ strcpy(table[0].s, nullsymstr);
+ ++tableSize;
+
+ symbol::nullsym.hashplus = 0;
+
+ symbol::initsym = symbol::opTrans("init");
+ symbol::castsym = symbol::opTrans("cast");
+ symbol::ecastsym = symbol::opTrans("ecast");
+ }
+}
+
+// Hashing constants found experimentally to reduce collision (a little).
+const uint A = 25191, B = 16342, C = 1746, D = 18326;
+
+// Hash the string into an integer. Experimental testing has shown that
+// hashing only the first few letters seems to be faster than hashing deeper
+// into the string, even though this approach causes more hash collisions.
+uint hash(const char *s, size_t len)
+{
+ uint h = s[0];
+ if (len == 2)
+ return h;
+ h += A*s[1];
+ if (len == 3)
+ return h;
+ h += B*s[2];
+ if (len == 4)
+ return h;
+ h += C*s[3];
+ if (len == 5)
+ return h;
+ h += D*s[4];
+ return h+len;
+}
+
+/* Under normal circumstances, the initial table should be large enough for
+ * all of the symbols used and will never be resized. Just in case the
+ * program encounters a large number of distinct symbols, we implement
+ * resizing of the table.
+ */
+void resizeTable() {
+ symbolRecord *oldTable = table;
+ size_t oldSize = tableSize;
+ size_t oldCapacity = tableCapacity;
+
+ tableCapacity *= 4;
+ table = new symbolRecord[tableCapacity];
+ initTable();
+
+ // The null symbol is a special case.
+ table[0] = oldTable[0];
+ ++tableSize;
+
+#if 0
+ printf("old:\n");
+ for (size_t i = 0; i < oldCapacity; ++i) {
+ symbolRecord &r = oldTable[i];
+
+ if (r.flag != USED)
+ continue;
+
+ printf(" %u -> %s\n", r.hashplus, r.s);
+ }
+#endif
+
+ for (size_t i = 1; i < oldCapacity; ++i) {
+ symbolRecord &r = oldTable[i];
+
+ if (r.flag != USED)
+ continue;
+
+ // Entries that were skipped over when this symbol was entered into the
+ // old hash table may not appear in the same spot in the new hash table.
+ // Put "SKIP" entries in their place, so that the symbol will still be
+ // found.
+ for (uint h = hash(r.s, strlen(r.s)+1); h < r.hashplus; ++h) {
+ symbolRecord &skipr = recordByHashplus(h);
+ if (skipr.flag == 0)
+ skipr.flag = SKIP;
+ }
+
+ // Enter the symbol in its spot.
+ symbolRecord &newr = recordByHashplus(r.hashplus);
+ assert(newr.flag != USED);
+ newr.flag = USED;
+ newr.hashplus = r.hashplus;
+ newr.s = r.s;
+ ++tableSize;
+ }
+
+#if 0
+ printf("new:\n");
+ for (size_t i = 0; i < tableCapacity; ++i) {
+ symbolRecord &r = table[i];
+
+ if (r.flag != USED)
+ continue;
+
+ printf(" %u -> %s\n", r.hashplus, r.s);
+ }
+#endif
+
+ assert(tableSize == oldSize);
+
+ // Debugging resize.
+ for (size_t i = 1; i < oldCapacity; ++i) {
+ symbolRecord &r = oldTable[i];
+
+ if (r.flag != USED)
+ continue;
+
+ symbolRecord &newr = recordByHashplus(r.hashplus);
+ assert(newr.hashplus == r.hashplus);
+ assert(newr.flag != 0);
+ assert(newr.flag != SKIP);
+ assert(newr.flag == USED);
+ assert(newr.s = r.s);
+ if (strncmp(r.s, "gensym", 6) != 0)
+ assert(symbol::rawTrans(r.s, strlen(r.s)+1).hashplus == r.hashplus);
+ }
+
+#if 0
+ // Diagnostics.
+ uint empty=0, used=0, skip=0;
+ for (size_t i = 0; i < tableCapacity; ++i) {
+ symbolRecord &r = table[i];
+ if (r.flag == 0) ++empty;
+ else if (r.flag == USED) ++used;
+ else if (r.flag == SKIP) ++skip;
+ else assert("Unknown flag" == 0);
+ }
+
+ cout << "Resized symbol table. "
+ << "empty: " << empty
+ << "used: " << used
+ << "skip: " << skip
+ << endl;
+#endif
+}
+
+symbol symbolize(uint h) {
+ symbol s;
+ s.hashplus = h;
+ return s;
+}
+
+// Handles the insertion of a new symbol into a table the has been resized (or
+// needs resizing).
+symbol advancedInsert(const char *s, size_t len)
+{
+ if (2*tableSize >= tableCapacity)
+ resizeTable();
+
+ uint hashplus = hash(s, len);
+
+#if 1
+ assert(s != 0);
+ assert(len > 0);
+ assert(2*tableSize <= tableCapacity);
+#endif
+
+ // We know the symbol is not in the table. Just search for the first unused
+ // entry (either empty or a skip entry) and insert there.
+ for (;;) {
+ symbolRecord &r = recordByHashplus(hashplus);
+
+ if (r.flag != USED) {
+ r.flag = USED;
+ r.s = new char[len];
+ memcpy(r.s, s, len);
+ assert(r.s[len-1] == '\0');
+ r.hashplus = hashplus;
+
+ ++tableSize;
+ assert(2*tableSize <= tableCapacity);
+
+ return symbolize(hashplus);
+ }
+
+ ++hashplus;
+ }
+
+ assert("Unreachable code" == 0);
+ return symbol::nullsym;
+}
+
+symbol symbol::gensym(string s) {
+ // Gensym can be inserted as if it were a normal string not already in the
+ // table. advancedInsert handles this.
+ s = "gensym " + s;
+ return advancedInsert(s.c_str(), s.size() + 1);
+}
+
+symbol symbol::rawTrans(const char *s, size_t len)
+{
+ uint hashplus = sym::hash(s, len);
+
+#if 1
+ assert(s != 0);
+ assert(len > 0);
+ assert(2*tableSize <= tableCapacity);
+#endif
+
+ // Search through the table till we find the symbol already translated or
+ // an empty field.
+ for (;;) {
+ symbolRecord &r = recordByHashplus(hashplus);
+
+ // Translating pre-existing symbols is more common, so check for it first.
+ if (r.hashplus == hashplus &&
+ r.flag == USED &&
+ strncmp(r.s, s, len) == 0) {
+ return symbolize(hashplus);
+ }
+
+ // Then check for an empty entry, in which case the entry is added.
+ if (r.flag == 0) {
+ // Test if the table needs resizing before entering a new symbol, or if
+ // the table has already been resized. In either case, the symbol will
+ // be added to a resized table which may contain skip entries, and a
+ // more involved insertion routine is needed.
+ if (2*tableSize >= SYMBOL_TABLE_BASE_CAPACITY)
+ return advancedInsert(s, len);
+
+ r.flag = USED;
+ r.s = new char[len];
+ memcpy(r.s, s, len);
+ assert(r.s[len-1] == '\0');
+ r.hashplus = hashplus;
+
+ ++tableSize;
+ assert(2*tableSize <= tableCapacity);
+
+ return symbolize(hashplus);
+ }
+
+ // A case where a different symbol is in the spot, continue along the
+ // table.
+ ++hashplus;
+ }
+
+ assert("Unreachable code" == 0);
+ return symbol::nullsym;
+}
+
+symbol::operator string () const {
+ symbolRecord &r = recordByHashplus(this->hashplus);
+ return (string)r.s;
+}
+
+ostream& operator<< (ostream& out, const symbol sym)
+{
+ symbolRecord &r = recordByHashplus(sym.hashplus);
+ return out << r.s;
+}
+
+} // end namespace sym
+
+/* Define all of operator symbols SYM_PLUS, etc. */
+#define OPSYMBOL(str, name) \
+ sym::symbol name = sym::symbol::opTrans(str)
+#include "opsymbols.h"
+#undef OPSYMBOL
+
+/* Define all of the symbols of the type SYM(name) in selected files. */
+#define ADDSYMBOL(name) \
+ sym::symbol PRETRANSLATED_SYMBOL_##name = sym::symbol::literalTrans(#name)
+#include "allsymbols.h"
+#undef ADDSYMBOL
diff --git a/graphics/asymptote/symbol.h b/graphics/asymptote/symbol.h
new file mode 100644
index 0000000000..bcfed4f630
--- /dev/null
+++ b/graphics/asymptote/symbol.h
@@ -0,0 +1,120 @@
+/*****
+ * symbol.h
+ * Andy Hammerlindl 2002/06/18
+ *
+ * Creates symbols from strings so that multiple calls for a symbol of
+ * the same string will return an identical object.
+ *****/
+
+#ifndef SYMBOL_H
+#define SYMBOL_H
+
+#include <iostream>
+#include <cassert>
+
+#include "common.h"
+
+using std::ostream;
+
+namespace sym {
+
+void initTable();
+
+struct GCInit {
+#ifdef _AIX
+ typedef char * GC_PTR;
+#endif
+ GCInit() {
+#ifdef USEGC
+ GC_set_free_space_divisor(2);
+ mem::compact(0);
+ GC_INIT();
+#endif
+
+ // Put the symbol table into a state where symbols can be translated.
+ initTable();
+ }
+};
+
+typedef unsigned int uint;
+
+/* The symbol class, just a wrapper around the augmented hash value. This
+ * wrapper is so that
+ * cout << s << endl;
+ * prints the symbol name instead of a meaningless integer.
+ *
+ * This is a lightweight class and should have no virtual functions for speed
+ * reasons.
+ */
+struct symbol {
+ // Is there any particular reason why this is in symbol?
+ static GCInit initialize;
+
+ uint hashplus;
+#if 0
+ symbol() {}
+ symbol(uint h) : hashplus(h) {}
+#endif
+
+ static symbol nullsym;
+ static symbol initsym;
+ static symbol castsym;
+ static symbol ecastsym;
+
+ bool special() const {
+ return *this == initsym || *this == castsym || *this == ecastsym;
+ }
+ bool notSpecial() const {
+ return !special();
+ }
+
+ // Translate a string into a unique symbol, such that two strings are equal
+ // if and only if their resulting symbols are equal.
+ // len should be equal to strlen(s)+1
+ static symbol rawTrans(const char *s, size_t len);
+
+ static symbol literalTrans(string s) {
+ return rawTrans(s.c_str(), s.size() + 1);
+ }
+
+ static symbol opTrans(string s) {
+ return literalTrans("operator "+s);
+ }
+
+ static symbol trans(string s) {
+ // Figure out whether it's an operator or an identifier by looking at the
+ // first character.
+ char c=s[0];
+ return isalpha(c) || c == '_' ? literalTrans(s) : opTrans(s);
+ }
+
+ // Make a symbol that is guaranteed to be unique. It will not match any other
+ // symbol in the namespace.
+ static symbol gensym(string s);
+
+ size_t hash() const {
+ return (size_t)this->hashplus;
+ }
+
+ friend bool operator== (symbol s1, symbol s2) {
+ return s1.hashplus == s2.hashplus;
+ }
+
+ friend bool operator!= (symbol s1, symbol s2) {
+ return s1.hashplus != s2.hashplus;
+ }
+
+ friend bool operator< (symbol s1, symbol s2) {
+ return s1.hashplus < s2.hashplus;
+ }
+
+ operator bool () const { return this->hashplus != 0; }
+
+ operator string () const;
+
+ friend ostream& operator<< (ostream& out, const symbol sym);
+};
+
+} // end namespace
+
+#endif // SYMBOL_H
diff --git a/graphics/asymptote/table.h b/graphics/asymptote/table.h
new file mode 100644
index 0000000000..38427f90b0
--- /dev/null
+++ b/graphics/asymptote/table.h
@@ -0,0 +1,128 @@
+/*****
+ * table.h
+ * Andy Hammerlindl 2002/06/18
+ *
+ * Table used to bind symbols to vars and types in a namespace.
+ *****/
+
+#ifndef TABLE_H
+#define TABLE_H
+
+#include <cassert>
+#include <utility>
+
+#include "symbol.h"
+#include "common.h"
+
+namespace sym {
+
+template <class B>
+class table;
+
+template <class B>
+std::ostream& operator<< (std::ostream& out, const table<B>& t);
+
+template <class B>
+class table {
+protected:
+ typedef mem::multimap<symbol CONST,B> scope_t;
+ typedef typename scope_t::iterator scope_iterator;
+ typedef mem::list<scope_t> scopes_t;
+ typedef mem::list<B> name_t;
+ typedef typename name_t::iterator name_iterator;
+ typedef mem::map<symbol CONST,name_t> names_t;
+ typedef typename names_t::iterator names_iterator;
+
+ scopes_t scopes;
+ names_t names;
+
+ void remove(symbol key);
+public :
+ table();
+
+ void enter(symbol key, B value);
+ B look(symbol key);
+
+ // Allows scoping and overloading of symbols of the same name
+ void beginScope();
+ void endScope();
+
+ // Copies all bindings in the top scope to the scope underneath it, and
+ // removes the the top scope.
+ void collapseScope();
+
+ // Adds to l, all names prefixed by start.
+ void completions(mem::list<symbol >& l, string start);
+
+ friend std::ostream& operator<< <B> (std::ostream& out, const table& t);
+};
+
+template <class B>
+inline table<B>::table()
+{
+ beginScope();
+}
+
+template <class B>
+inline void table<B>::enter(symbol key, B value)
+{
+ scopes.front().insert(std::make_pair(key,value));
+ names[key].push_front(value);
+}
+
+template <class B>
+inline B table<B>::look(symbol key)
+{
+ if (!names[key].empty())
+ return names[key].front();
+ return 0;
+}
+
+template <class B>
+inline void table<B>::beginScope()
+{
+ scopes.push_front(scope_t());
+}
+
+template <class B>
+inline void table<B>::remove(symbol key)
+{
+ if (!names[key].empty())
+ names[key].pop_front();
+}
+
+template <class B>
+inline void table<B>::endScope()
+{
+ scope_t &scope = scopes.front();
+ for (scope_iterator p = scope.begin(); p != scope.end(); ++p)
+ remove(p->first);
+ scopes.pop_front();
+}
+
+template <class B>
+inline void table<B>::collapseScope()
+{
+ scope_t scope = scopes.front();
+ scopes.pop_front();
+
+ scopes.front().insert(scope.begin(), scope.end());
+}
+
+// Returns true if start is a prefix for name; eg, mac is a prefix of machine.
+inline bool prefix(string start, string name) {
+ return equal(start.begin(), start.end(), name.begin());
+}
+
+template <class B>
+inline void table<B>::completions(mem::list<symbol>& l, string start)
+{
+ for (names_iterator p = names.begin(); p != names.end(); ++p)
+ if (prefix(start, p->first) && !p->second.empty())
+ l.push_back(p->first);
+}
+
+
+} // namespace sym
+
+#endif
diff --git a/graphics/asymptote/tests/Makefile b/graphics/asymptote/tests/Makefile
new file mode 100644
index 0000000000..659737bfd4
--- /dev/null
+++ b/graphics/asymptote/tests/Makefile
@@ -0,0 +1,24 @@
+.NOTPARALLEL:
+
+TESTDIRS = string arith frames types imp array pic gs
+
+EXTRADIRS = gsl output
+
+test: $(TESTDIRS)
+
+all: $(TESTDIRS) $(EXTRADIRS)
+
+$(TESTDIRS)::
+ @echo
+ ../asy -dir ../base $@/*.asy
+
+$(EXTRADIRS)::
+ @echo
+ ../asy -dir ../base $@/*.asy
+
+clean: FORCE
+ rm -f *.eps
+
+distclean: FORCE clean
+
+FORCE:
diff --git a/graphics/asymptote/tests/TestLib.asy b/graphics/asymptote/tests/TestLib.asy
new file mode 100644
index 0000000000..a4a4b23992
--- /dev/null
+++ b/graphics/asymptote/tests/TestLib.asy
@@ -0,0 +1,15 @@
+bool close(pair a, pair b)
+{
+ real norm=(b == 0) ? 1 : max(abs(a),abs(b));
+ return abs(a-b) <= 100*realEpsilon*norm;
+}
+
+void StartTest(string desc)
+{
+ write("Testing " + desc + "...",flush);
+}
+
+void EndTest()
+{
+ write("PASSED.");
+}
diff --git a/graphics/asymptote/tests/arith/integer.asy b/graphics/asymptote/tests/arith/integer.asy
new file mode 100644
index 0000000000..b5c337d273
--- /dev/null
+++ b/graphics/asymptote/tests/arith/integer.asy
@@ -0,0 +1,23 @@
+// Integer arithmetic.
+import TestLib;
+StartTest("integer addition");
+assert(1+1==2);
+EndTest();
+StartTest("integer subtraction");
+assert(2-1==1);
+EndTest();
+StartTest("integer multiplication");
+assert(2*2==4);
+EndTest();
+StartTest("integer division");
+assert(4/2==2);
+EndTest();
+StartTest("integer self ops");
+{ int x = 3; assert(++x==4); assert(x==4); }
+{ int x = 3; assert(--x==2); assert(x==2); }
+{ int x = 3; assert((x+=7) == 10); assert(x==10); }
+{ int x = 3; assert((x-=7) == -4); assert(x==-4); }
+{ int x = 3; assert((x*=7) == 21); assert(x==21); }
+{ int x = 10; assert((x%=4) == 2); assert(x==2); }
+EndTest();
+
diff --git a/graphics/asymptote/tests/arith/pair.asy b/graphics/asymptote/tests/arith/pair.asy
new file mode 100644
index 0000000000..c815f28b2f
--- /dev/null
+++ b/graphics/asymptote/tests/arith/pair.asy
@@ -0,0 +1,20 @@
+import TestLib;
+
+StartTest("complex addition");
+assert((1,0)+(0,1)==(1,1));
+EndTest();
+StartTest("complex subtraction");
+assert((1,0)-(0,1)==(1,-1));
+EndTest();
+StartTest("complex multiplication");
+assert((1,2)*(2,1)==(0,5));
+EndTest();
+StartTest("complex division");
+assert((0,5)/(2,1)==(1,2));
+EndTest();
+StartTest("length(pair)");
+assert(length((0.0,1.0)) == 1.0);
+EndTest();
+StartTest("conj()");
+assert(conj((0.0,1.0))==(0.0, -1.0));
+EndTest();
diff --git a/graphics/asymptote/tests/arith/random.asy b/graphics/asymptote/tests/arith/random.asy
new file mode 100644
index 0000000000..c972744da4
--- /dev/null
+++ b/graphics/asymptote/tests/arith/random.asy
@@ -0,0 +1,11 @@
+import TestLib;
+StartTest("random");
+bool bit32=false;
+for(int i=0; i < 1000; ++i) {
+ real x=unitrand();
+ if(x > 0.5) bit32=true;
+ assert(x >= 0.0 && x <= 1.0);
+}
+assert(bit32);
+
+EndTest();
diff --git a/graphics/asymptote/tests/arith/real.asy b/graphics/asymptote/tests/arith/real.asy
new file mode 100644
index 0000000000..1628258cf8
--- /dev/null
+++ b/graphics/asymptote/tests/arith/real.asy
@@ -0,0 +1,18 @@
+// Real arithmetic.
+
+import TestLib;
+StartTest("real error");
+assert((1.0-1.0) < realEpsilon);
+EndTest();
+StartTest("real addition");
+assert((1.0+1.0) == (2.0));
+EndTest();
+StartTest("real subtraction");
+assert((2.0-1.0) == (1.0));
+EndTest();
+StartTest("real multiplication");
+assert((2.0*2.0) == (4.0));
+EndTest();
+StartTest("real division");
+assert((4.0/2.0) == (2.0));
+EndTest();
diff --git a/graphics/asymptote/tests/arith/roots.asy b/graphics/asymptote/tests/arith/roots.asy
new file mode 100644
index 0000000000..d3e5d55f36
--- /dev/null
+++ b/graphics/asymptote/tests/arith/roots.asy
@@ -0,0 +1,96 @@
+// Roots.
+
+import TestLib;
+real x;
+real[] r;
+
+StartTest("quadratic roots");
+
+r=quadraticroots(1,0,-8);
+assert(r.length == 2);
+r=sort(r);
+x=2sqrt(2);
+assert(close(r[0],-x));
+assert(close(r[1],x));
+
+r=quadraticroots(1,2,1);
+assert(r.length == 2);
+assert(close(r[0],-1));
+assert(close(r[1],-1));
+
+r=quadraticroots(1,0,8);
+assert(r.length == 0);
+
+r=quadraticroots(0,2,3);
+assert(r.length == 1);
+assert(close(r[0],-3/2));
+
+EndTest();
+
+StartTest("cubic roots");
+
+r=cubicroots(1,0,0,-8);
+assert(r.length == 1);
+assert(close(r[0],2));
+
+real[] r=cubicroots(1,3,3,1);
+assert(r.length == 3);
+assert(close(r[0],-1));
+assert(close(r[1],-1));
+assert(close(r[2],-1));
+
+real[] r=cubicroots(1,-3,3,-1);
+assert(r.length == 3);
+assert(close(r[0],1));
+assert(close(r[1],1));
+assert(close(r[2],1));
+
+r=cubicroots(1,0,0,0);
+assert(r.length == 3);
+assert(r[0] == 0);
+assert(r[1] == 0);
+assert(r[2] == 0);
+
+r=cubicroots(1,0,-15,-4);
+assert(r.length == 3);
+r=sort(r);
+assert(close(r[0],-2-sqrt(3)));
+assert(close(r[1],-2+sqrt(3)));
+assert(close(r[2],4));
+
+r=cubicroots(1,0,-15,4);
+assert(r.length == 3);
+r=sort(r);
+assert(close(r[0],-4));
+assert(close(r[1],2-sqrt(3)));
+assert(close(r[2],2+sqrt(3)));
+
+r=cubicroots(1,0,-15,0);
+assert(r.length == 3);
+r=sort(r);
+x=sqrt(15);
+assert(close(r[0],-x));
+assert(r[1] == 0);
+assert(close(r[2],x));
+
+r=cubicroots(1,1,1,0);
+assert(r.length == 1);
+assert(r[0] == 0);
+
+r=cubicroots(1,0,20,-4);
+assert(r.length == 1);
+x=cbrt(54+6sqrt(6081));
+assert(close(r[0],x/3-20/x));
+
+EndTest();
+
+StartTest("newton");
+
+real f(real x) {return cos(x);}
+real dfdx(real x) {return -sin(x);}
+
+assert(close(newton(f,dfdx,1),pi/2));
+assert(newton(f,dfdx,0) == realMax);
+assert(newton(f,dfdx,0,2) == pi/2);
+
+EndTest();
diff --git a/graphics/asymptote/tests/arith/transform.asy b/graphics/asymptote/tests/arith/transform.asy
new file mode 100644
index 0000000000..e4e44e387b
--- /dev/null
+++ b/graphics/asymptote/tests/arith/transform.asy
@@ -0,0 +1,25 @@
+import TestLib;
+pair x = (1, 2);
+StartTest("identity transform");
+assert(identity()*x == x);
+EndTest();
+StartTest("shift transform");
+assert(shift((1,1))*x == (2, 3));
+assert(shift(1,1)*x == (2, 3));
+EndTest();
+StartTest("scaling transforms");
+assert(xscale(2)*x == (2, 2));
+assert(yscale(2)*x == (1, 4));
+assert(scale(2)*x == (2, 4));
+EndTest();
+StartTest("slant transform");
+assert(slant(1)*x == (3, 2));
+EndTest();
+StartTest("rotation transform");
+assert(length((rotate(90)*x) - (-2,1)) <= realEpsilon);
+assert(rotate(90, x)*x == x);
+EndTest();
+StartTest("reflect transform");
+assert(reflect((-1, -1), (1, 1))*x == (2, 1));
+EndTest();
+
diff --git a/graphics/asymptote/tests/arith/triple.asy b/graphics/asymptote/tests/arith/triple.asy
new file mode 100644
index 0000000000..135801b633
--- /dev/null
+++ b/graphics/asymptote/tests/arith/triple.asy
@@ -0,0 +1,11 @@
+import TestLib;
+triple t = (1,0,0);
+StartTest("polar()");
+assert(polar(t) == (pi / 2.0) );
+EndTest();
+StartTest("azimuth()");
+assert(azimuth(t) < realEpsilon);
+EndTest();
+StartTest("unit()");
+assert(length(t-unit(t)) < realEpsilon);
+EndTest();
diff --git a/graphics/asymptote/tests/array/array.asy b/graphics/asymptote/tests/array/array.asy
new file mode 100644
index 0000000000..106856fd80
--- /dev/null
+++ b/graphics/asymptote/tests/array/array.asy
@@ -0,0 +1,49 @@
+import TestLib;
+
+StartTest("array");
+
+{
+ int[] x=array(10, 7);
+ assert(x.length == 10);
+ for (int i=0; i<x.length; ++i)
+ assert(x[i] == 7);
+}
+{
+ int[][] y=array(10, array(10, 7));
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ assert(y[i][j] == 7);
+ }
+}
+{
+ int[][] y=array(10, array(10, 7));
+ y[4][5] = 9;
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ if (i==4 && j==5)
+ assert(y[i][j] == 9);
+ else
+ assert(y[i][j] == 7);
+ }
+}
+{
+ int[][] y=array(10, array(10, 7), depth=0);
+ y[4][5] = 9;
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ if (j==5)
+ assert(y[i][j] == 9);
+ else
+ assert(y[i][j] == 7);
+ }
+}
+
+
+
+EndTest();
diff --git a/graphics/asymptote/tests/array/delete.asy b/graphics/asymptote/tests/array/delete.asy
new file mode 100644
index 0000000000..d92a3c082c
--- /dev/null
+++ b/graphics/asymptote/tests/array/delete.asy
@@ -0,0 +1,41 @@
+import TestLib;
+import math;
+
+StartTest("delete");
+
+int[] a=sequence(4);
+a.delete(2);
+assert(all(a == new int[] {0,1,3}));
+
+int[] a=sequence(4);
+a.delete(0,2);
+assert(all(a == new int[] {3}));
+
+int[] a=sequence(4);
+a.delete(1,2);
+assert(all(a == new int[] {0,3}));
+
+int[] a=sequence(4);
+a.delete(2,2);
+assert(all(a == new int[] {0,1,3}));
+
+int[] a=sequence(4);
+a.delete(2,3);
+assert(all(a == new int[] {0,1}));
+
+int[] a=sequence(4);
+a.cyclic=true;
+a.delete(2,3);
+assert(all(a == new int[] {0,1}));
+
+int[] a=sequence(4);
+a.cyclic=true;
+a.delete(2,4);
+assert(all(a == new int[] {1}));
+
+int[] a=sequence(4);
+a.cyclic=true;
+a.delete(3,1);
+assert(all(a == new int[] {2}));
+
+EndTest();
diff --git a/graphics/asymptote/tests/array/determinant.asy b/graphics/asymptote/tests/array/determinant.asy
new file mode 100644
index 0000000000..e6086d0b04
--- /dev/null
+++ b/graphics/asymptote/tests/array/determinant.asy
@@ -0,0 +1,18 @@
+import TestLib;
+import math;
+
+StartTest("determinant");
+assert(determinant(new real[][] {{0}}) == 0);
+assert(determinant(new real[][] {{1}}) == 1);
+assert(determinant(new real[][] {{1,2},{3,4}}) == -2);
+real e=1e-20;
+assert(close(determinant(new real[][] {{1e,2e},{3e,4e}}),-2e-40));
+assert(close(determinant(new real[][] {{1,2,3},{4,5,6},{7,8,9}}),0));
+assert(close(determinant(new real[][] {{1,2},{1,2}}),0));
+assert(close(determinant(new real[][] {{1,2,3,4},
+ {5,6,7,8},{9,10,11,12},{13,14,15,16}}),0));
+assert(close(determinant(new real[][] {{1,2,3,4},
+ {5,0,7,8},{9,10,0,12},{13,14,15,16}}),-2376));
+assert(close(determinant(new real[][]{{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},
+ {1,50,1,-2}}),-4588));
+EndTest();
diff --git a/graphics/asymptote/tests/array/fields.asy b/graphics/asymptote/tests/array/fields.asy
new file mode 100644
index 0000000000..9b5926d374
--- /dev/null
+++ b/graphics/asymptote/tests/array/fields.asy
@@ -0,0 +1,103 @@
+import TestLib;
+
+StartTest("fields");
+
+{
+ int[] z = {1, 2, 3};
+ assert(z.length == 3);
+ int[] keys = z.keys;
+ assert(keys.length == 3);
+ for (int i; i<3; ++i)
+ assert(keys[i] == i);
+ for (int j = 0; j < 10; ++j) {
+ assert(z.cyclic == false);
+ z.cyclic=true;
+ assert(z.cyclic == true);
+ z.cyclic=false;
+ }
+}
+
+{
+ int[] z = {2, 3, 5};
+ for (int k = -100; k <= 100; ++k)
+ assert(z.initialized(k) == (k >= 0 && k < 3));
+}
+
+{
+ int[] z;
+ for (int i=0; i<10; ++i) {
+ for (int k = 0; k <= 100; ++k) {
+ assert(z.length == k);
+ z.push(k*k+3k+1);
+ assert(z.length == k+1);
+ }
+ for (int k = 100; k >= 0; --k) {
+ assert(z.length == k+1);
+ assert(z.pop() == k*k+3k+1);
+ assert(z.length == k);
+ }
+ }
+ z.cyclic=true;
+ for (int i=0; i<10; ++i) {
+ for (int k = 0; k <= 100; ++k) {
+ assert(z.length == k);
+ z.push(k*k+3k+1);
+ assert(z.length == k+1);
+ }
+ for (int k = 100; k >= 0; --k) {
+ assert(z.length == k+1);
+ z.delete(quotient(k,2));
+ assert(z.length == k);
+ }
+ }
+}
+
+{
+ int[] base={4,5,9,5,0,2,3};
+ int[] z;
+ for (int i=0; i<9; ++i) {
+ assert(z.length == i*base.length);
+ for (int j : z.keys)
+ assert(z[j] == base[j%base.length]);
+ z.append(base);
+ }
+}
+
+{
+ int[] z = {1,2,3,4,6,7,8,9};
+ assert(z.length == 8);
+ z.insert(4, 5);
+ assert(z.length == 9);
+ z.insert(0, 0);
+ assert(z.length == 10);
+ for (int i=0; i<10; ++i)
+ assert(z[i] == i);
+ z.insert(7, 100, 101, 102, 103);
+ assert(z.length == 14);
+
+ // TODO: Test inserting/deleting lengths more seriously.
+}
+
+{
+ // Test extended for.
+ int[] a = {1,4,6,2,7,4,8,9,1,3,-1};
+ int i = 0;
+ for (int x : a) {
+ assert(x == a[i]);
+ ++i;
+ }
+ assert(i == a.length);
+}
+
+{
+ // Test extended for.
+ int[] a = {1,4,6,2,7,4,8,9,1,3,-1};
+ int i = 0;
+ for (var x : a) {
+ assert(x == a[i]);
+ ++i;
+ }
+ assert(i == a.length);
+}
+
+EndTest();
diff --git a/graphics/asymptote/tests/array/slice.asy b/graphics/asymptote/tests/array/slice.asy
new file mode 100644
index 0000000000..9010f0b5d8
--- /dev/null
+++ b/graphics/asymptote/tests/array/slice.asy
@@ -0,0 +1,232 @@
+import TestLib;
+
+StartTest("slice");
+
+int[] x={0,1,2,3,4,5,6,7,8,9};
+
+// Non-cyclic cases.
+assert(all(x[:] == x));
+assert(!alias(x[:],x));
+
+assert(all(x[0:4] == new int[] {0,1,2,3} ));
+assert(all(x[2:4] == new int[] {2,3} ));
+
+assert(all(x[5:] == new int[] {5,6,7,8,9} ));
+assert(all(x[:5] == new int[] {0,1,2,3,4} ));
+
+assert(all(x[3:3] == new int[] {} ));
+assert(all(x[3:4] == new int[] {3} ));
+assert(all(x[98:99] == new int[] {} ));
+
+assert(x[:].cyclic == false);
+assert(x[2:].cyclic == false);
+assert(x[:7].cyclic == false);
+assert(x[3:3].cyclic == false);
+assert(x[2:9].cyclic == false);
+
+// Cyclic cases
+x.cyclic=true;
+
+assert(all(x[:] == new int[] {0,1,2,3,4,5,6,7,8,9} ));
+assert(all(x[0:4] == new int[] {0,1,2,3} ));
+assert(all(x[2:4] == new int[] {2,3} ));
+
+assert(all(x[5:] == new int[] {5,6,7,8,9} ));
+assert(all(x[-5:] == new int[] {5,6,7,8,9,0,1,2,3,4,5,6,7,8,9} ));
+assert(all(x[:5] == new int[] {0,1,2,3,4} ));
+
+assert(all(x[3:3] == new int[] {} ));
+assert(all(x[3:4] == new int[] {3} ));
+
+assert(all(x[-1:1] == new int[] {9,0} ));
+assert(all(x[9:11] == new int[] {9,0} ));
+assert(all(x[9:21] == new int[] {9,0,1,2,3,4,5,6,7,8,9,0} ));
+assert(all(x[-15:15] == new int[] {5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+ 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4}));
+assert(all(x[6728:6729] == new int[] {8} ));
+assert(all(x[-6729:-6728] == new int[] {1} ));
+
+assert(x[:].cyclic == false);
+assert(x[2:].cyclic == false);
+assert(x[:7].cyclic == false);
+assert(x[3:3].cyclic == false);
+assert(x[2:9].cyclic == false);
+assert(x[5:100].cyclic == false);
+
+pair[] z={(1,2), (3,4), (5,6)};
+assert(all(z[1:1] == new pair[] {}));
+assert(all(z[:1] == new pair[] {(1,2)}));
+assert(all(z[1:] == new pair[] {(3,4), (5,6)}));
+assert(all(z[:] == z));
+assert(all(z[1:2] == new pair[] {(3,4)}));
+
+// Writing tests.
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ int[] z={56,67,78};
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ int[] z={56,67,78};
+ z.cyclic=true;
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclic == false);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[2:3] = y[5:6] = new int[] {77};
+ assert(all(y == new int[] {0,1,77,3,4,77,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[:3] = y[7:] = new int[] {};
+ assert(all(y == new int[] {3,4,5,6}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[3:5] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+ int[] z={56,67,78};
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclic == true);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+ int[] z={56,67,78};
+ z.cyclic=true;
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclic == true);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[2:3] = y[5:6] = new int[] {77};
+ assert(all(y == new int[] {0,1,77,3,4,77,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[:3] = y[7:] = new int[] {};
+ assert(all(y == new int[] {3,4,5,6}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[8:] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[-2:0] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[18:20] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[3:5] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[13:15] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[3-10:5-10] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[8:12] = new int[] {18,19,20,21};
+ assert(all(y == new int[] {20,21,2,3,4,5,6,7,18,19}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic=true;
+
+ y[-2:2] = new int[] {18,19,20,21};
+ assert(all(y == new int[] {20,21,2,3,4,5,6,7,18,19}));
+}
+
+// Side Effect Test
+{
+ int state=0;
+ int[] x={0,1,2,3,4,5,6,7,8,9};
+
+ int[] a() {
+ assert(state==0);
+ ++state;
+
+ return x;
+ }
+
+ int l() {
+ assert(state==1);
+ ++state;
+
+ return 2;
+ }
+
+ int r() {
+ assert(state==2);
+ ++state;
+
+ return 6;
+ }
+
+ int[] b() {
+ assert(state==3);
+ ++state;
+
+ return new int[] {77,77};
+ }
+
+ assert(state==0);
+ a()[l():r()]=b();
+ assert(state==4);
+ assert(all(x == new int[] {0,1,77,77,6,7,8,9}));
+}
+
+
+EndTest();
diff --git a/graphics/asymptote/tests/array/solve.asy b/graphics/asymptote/tests/array/solve.asy
new file mode 100644
index 0000000000..ec1c4416ba
--- /dev/null
+++ b/graphics/asymptote/tests/array/solve.asy
@@ -0,0 +1,35 @@
+import TestLib;
+
+StartTest("solve");
+real[][] a=new real[][] {{1,1,1},{1,2,2},{0,0,1}};
+real[][] b=new real[][] {{3,9},{5,11},{1,3}};
+real[][] x=new real[][] {{1,7},{1,-1,},{1,3}};
+real[][] c=solve(a,b);
+for(int i=0; i < c.length; ++i)
+ for(int j=0; j < c[i].length; ++j)
+ assert(close(c[i][j],x[i][j]));
+
+real[][] a={{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},{1,50,1,-2}};
+real[] b={7,19,33,3};
+real[] x=solve(a,b);
+real[] c=a*x;
+for(int i=0; i < c.length; ++i)
+ assert(close(c[i],b[i]));
+EndTest();
+
+StartTest("inverse");
+real[][] a=new real[][] {{1,1,1},{1,2,2},{0,0,1}};
+real[][] ainverse=new real[][] {{2,-1,0},{-1,1,-1},{0,0,1}};
+real[][] d=inverse(a);
+real[][] l=d*a;
+real[][] r=a*d;
+real[][] I=identity(a.length);
+for(int i=0; i < d.length; ++i) {
+ for(int j=0; j < d[i].length; ++j) {
+ assert(close(d[i][j],ainverse[i][j]));
+ assert(I[i][j] == (i == j ? 1 : 0));
+ assert(close(l[i][j],I[i][j]));
+ assert(close(r[i][j],I[i][j]));
+ }
+}
+EndTest();
diff --git a/graphics/asymptote/tests/array/sort.asy b/graphics/asymptote/tests/array/sort.asy
new file mode 100644
index 0000000000..03c585b717
--- /dev/null
+++ b/graphics/asymptote/tests/array/sort.asy
@@ -0,0 +1,39 @@
+import TestLib;
+import math;
+
+string[] a={"bob","alice","pete","alice"};
+string[] b={"alice","alice","bob","pete"};
+
+StartTest("sort");
+
+assert(all(sort(a) == b));
+
+EndTest();
+
+StartTest("search");
+
+assert(search(b,"a") == -1);
+assert(search(b,"bob") == 2);
+assert(search(b,"z") == b.length-1);
+
+EndTest();
+
+StartTest("sort2");
+
+string[][] a={{"bob","9"},{"alice","5"},{"pete","7"},{"alice","4"}};
+string[][] b={{"alice","4"},{"alice","5"},{"bob","9"},{"pete","7"}};
+
+assert(sort(a) == b);
+
+EndTest();
+
+pair[] a={(2,1),(0,0),(1,1),(1,0)};
+pair[] b={(0,0),(1,0),(1,1),(2,1)};
+
+StartTest("lexicographical sort");
+assert(all(sort(a,lexorder) == b));
+EndTest();
+
+StartTest("lexicographical search");
+assert(search(b,(1,0),lexorder) == 1);
+EndTest();
diff --git a/graphics/asymptote/tests/array/transpose.asy b/graphics/asymptote/tests/array/transpose.asy
new file mode 100644
index 0000000000..f0366ba8fd
--- /dev/null
+++ b/graphics/asymptote/tests/array/transpose.asy
@@ -0,0 +1,55 @@
+import TestLib;
+import math;
+
+StartTest("transpose");
+int n=3;
+real[][] a=new real[n][n];
+real[][] b=new real[n][n];
+for(int i=0; i < n; ++i) {
+ for(int j=0; j < n; ++j) {
+ a[i][j]=b[j][i]=rand();
+ }
+}
+
+bool operator == (real[][] a, real[][] b)
+{
+ int n=a.length;
+ for(int i=0; i < n; ++i)
+ if(!all(a[i] == b[i])) return false;
+ return true;
+}
+
+bool operator == (real[][][] a, real[][][] b)
+{
+ int n=a.length;
+ for(int i=0; i < n; ++i) {
+ real[][] ai=a[i];
+ real[][] bi=b[i];
+ int m=ai.length;
+ for(int j=0; j < m; ++j) {
+ if(!all(ai[j] == bi[j])) return false;
+ }
+ }
+ return true;
+}
+
+assert(a == transpose(b));
+
+int n=3;
+real[][][] a=new real[n][n][n];
+real[][][] b=new real[n][n][n];
+real[][][] c=new real[n][n][n];
+real[][][] d=new real[n][n][n];
+for(int i=0; i < n; ++i) {
+ for(int j=0; j < n; ++j) {
+ for(int k=0; k < n; ++k) {
+ a[i][j][k]=b[j][i][k]=c[i][k][j]=d[k][j][i]=rand();
+ }
+ }
+}
+
+assert(a == transpose(b,new int[] {1,0,2}));
+assert(a == transpose(c,new int[] {0,2,1}));
+assert(a == transpose(d,new int[] {2,1,0}));
+
+EndTest();
diff --git a/graphics/asymptote/tests/bench/6000circles.asy b/graphics/asymptote/tests/bench/6000circles.asy
new file mode 100644
index 0000000000..53ebecce27
--- /dev/null
+++ b/graphics/asymptote/tests/bench/6000circles.asy
@@ -0,0 +1,17 @@
+size(0,100);
+import math;
+import stats;
+
+currentpen=magenta;
+// A centered random number
+real crand() {return unitrand()*5;}
+
+real r1;
+pair pcenter;
+
+for(int i=0; i < 6000; ++i) {
+
+r1 = unitrand()/10;
+pcenter = ( crand(), crand());
+Draw(circle(pcenter,r1));
+}
diff --git a/graphics/asymptote/tests/frames/loop.asy b/graphics/asymptote/tests/frames/loop.asy
new file mode 100644
index 0000000000..a4714d1f8d
--- /dev/null
+++ b/graphics/asymptote/tests/frames/loop.asy
@@ -0,0 +1,196 @@
+import TestLib;
+StartTest("loop");
+
+int f();
+for (int i=0; i<10; ++i) {
+ int x=i;
+ for (int j=0; j<10; ++j) {
+ int y=j;
+ if (i==5 && j==7) {
+ f = new int () { return x*y; };
+ }
+ }
+}
+assert(f()==35);
+
+int f();
+
+for (int i=0; i<10; ++i) {
+ int x=i;
+ for (int j=0; j<10; ++j) {
+ int y=j;
+ if (i==5 && j==7) {
+ f = new int () { return i*y; };
+ }
+ }
+}
+assert(f()==70);
+
+{
+ int y = 3;
+ int z = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ ++z;
+ continue;
+ y = 4;
+ }
+ assert(y == 3);
+ assert(z == 7);
+}
+{
+ int y = 3;
+ int z = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ ++z;
+ break;
+ y = 4;
+ }
+ assert(y == 3);
+ assert(z == 1);
+}
+{
+ int y = 3;
+ int z = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ void g() {}
+ ++z;
+ continue;
+ y = 4;
+ }
+ assert(y == 3);
+ assert(z == 7);
+}
+{
+ int y = 3;
+ int z = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ void g() {}
+ ++z;
+ break;
+ y = 4;
+ }
+ assert(y == 3);
+ assert(z == 1);
+}
+
+// While loops
+{
+ int y = 7;
+ int z = 0;
+ while (z < 10) {
+ ++z;
+ continue;
+ ++y;
+ }
+ assert(z == 10);
+ assert(y == 7);
+}
+
+{
+ int y = 7;
+ int z = 0;
+ while (z < 10) {
+ void g() {}
+ ++z;
+ continue;
+ ++y;
+ }
+ assert(z == 10);
+ assert(y == 7);
+}
+
+{
+ int y = 7;
+ int z = 0;
+ while (z < 10) {
+ ++z;
+ break;
+ ++y;
+ }
+ assert(z == 1);
+ assert(y == 7);
+}
+
+{
+ int y = 7;
+ int z = 0;
+ while (z < 10) {
+ void g() {}
+ ++z;
+ break;
+ ++y;
+ }
+ assert(z == 1);
+ assert(y == 7);
+}
+
+
+{
+ int y = 7;
+ int z = 0;
+ while (z < 10) {
+ ++z;
+ continue;
+ ++y;
+ }
+ assert(z == 10);
+ assert(y == 7);
+}
+
+// Do loops
+{
+ int y = 7;
+ int z = 0;
+ do {
+ void g() {}
+ ++z;
+ continue;
+ ++y;
+ } while (z < 10);
+ assert(z == 10);
+ assert(y == 7);
+}
+
+{
+ int y = 7;
+ int z = 0;
+ do {
+ ++z;
+ break;
+ ++y;
+ } while (z < 10);
+ assert(z == 1);
+ assert(y == 7);
+}
+
+{
+ int y = 7;
+ int z = 0;
+ do {
+ void g() {}
+ ++z;
+ break;
+ ++y;
+ } while (z < 10);
+ assert(z == 1);
+ assert(y == 7);
+}
+
+{
+ int x = 456;
+ do { x = 123; } while (false);
+ assert(x == 123);
+}
+
+{
+ int x = 456;
+ do { void g() {} x = 123; } while (false);
+ assert(x == 123);
+}
+
+
+EndTest();
diff --git a/graphics/asymptote/tests/frames/stat.asy b/graphics/asymptote/tests/frames/stat.asy
new file mode 100644
index 0000000000..d366b193e0
--- /dev/null
+++ b/graphics/asymptote/tests/frames/stat.asy
@@ -0,0 +1,14 @@
+import TestLib;
+StartTest("stat");
+struct T {
+ int x;
+ static void f(T t) {
+ t.x=2;
+ }
+}
+
+T t=new T;
+assert(t.x==0);
+T.f(t);
+assert(t.x==2);
+EndTest();
diff --git a/graphics/asymptote/tests/frames/stat2.asy b/graphics/asymptote/tests/frames/stat2.asy
new file mode 100644
index 0000000000..ea5863b081
--- /dev/null
+++ b/graphics/asymptote/tests/frames/stat2.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("stat2");
+struct T {
+ int x;
+ static void f(T t) {
+ static void g(T t) {
+ t.x=2;
+ }
+ g(t);
+ }
+}
+
+T t=new T;
+assert(t.x==0);
+T.f(t);
+assert(t.x==2);
+EndTest();
diff --git a/graphics/asymptote/tests/gc/array.asy b/graphics/asymptote/tests/gc/array.asy
new file mode 100644
index 0000000000..43e3f9224c
--- /dev/null
+++ b/graphics/asymptote/tests/gc/array.asy
@@ -0,0 +1,5 @@
+real[] a;
+for (int i = 0; i < 1e9; ++i)
+{
+ a=new real[10];
+}
diff --git a/graphics/asymptote/tests/gc/file.asy b/graphics/asymptote/tests/gc/file.asy
new file mode 100644
index 0000000000..14dacd02b8
--- /dev/null
+++ b/graphics/asymptote/tests/gc/file.asy
@@ -0,0 +1,7 @@
+for (int i = 0; i < 1e7; ++i)
+{
+ file a=output("out/"+(string) i);
+ write(a,i,endl);
+ close(a);
+}
+
diff --git a/graphics/asymptote/tests/gc/funcall.asy b/graphics/asymptote/tests/gc/funcall.asy
new file mode 100644
index 0000000000..42661c79e3
--- /dev/null
+++ b/graphics/asymptote/tests/gc/funcall.asy
@@ -0,0 +1,6 @@
+void g()
+{}
+for (int i = 0; i < 1e9; ++i)
+{
+ g();
+}
diff --git a/graphics/asymptote/tests/gc/guide.asy b/graphics/asymptote/tests/gc/guide.asy
new file mode 100644
index 0000000000..bf00543106
--- /dev/null
+++ b/graphics/asymptote/tests/gc/guide.asy
@@ -0,0 +1,5 @@
+guide a=(0,0);
+for (int i = 0; i < 1e9; ++i)
+{
+ guide b=a--a;
+}
diff --git a/graphics/asymptote/tests/gc/label.asy b/graphics/asymptote/tests/gc/label.asy
new file mode 100644
index 0000000000..d378a3efa6
--- /dev/null
+++ b/graphics/asymptote/tests/gc/label.asy
@@ -0,0 +1,8 @@
+guide a;
+for (int i = 0; i < 1e7; ++i)
+{
+ picture pic;
+ size(pic,10cm,20cm);
+ draw(pic,"a",scale(2)*(0,0)--(1,1));
+ shipout("out/",pic);
+}
diff --git a/graphics/asymptote/tests/gc/path.asy b/graphics/asymptote/tests/gc/path.asy
new file mode 100644
index 0000000000..118826eba1
--- /dev/null
+++ b/graphics/asymptote/tests/gc/path.asy
@@ -0,0 +1,8 @@
+guide a;
+for (int i = 0; i < 1e7; ++i)
+{
+// guide a=a--(1.0,2.0);
+ path p=(1.0,2.0);
+ path q=(3.0,4.0);
+ path a=p--q;
+}
diff --git a/graphics/asymptote/tests/gc/pen.asy b/graphics/asymptote/tests/gc/pen.asy
new file mode 100644
index 0000000000..691cf6dea8
--- /dev/null
+++ b/graphics/asymptote/tests/gc/pen.asy
@@ -0,0 +1,4 @@
+for (int i = 0; i < 1e7; ++i)
+{
+ pen p = linetype(new real[] {1,2});
+}
diff --git a/graphics/asymptote/tests/gc/shipout.asy b/graphics/asymptote/tests/gc/shipout.asy
new file mode 100644
index 0000000000..e2e9c8c7da
--- /dev/null
+++ b/graphics/asymptote/tests/gc/shipout.asy
@@ -0,0 +1,11 @@
+guide a;
+for (int i = 0; i < 1e7; ++i)
+{
+ picture pic;
+ size(pic,10cm,20cm);
+ path p=(1.0,2.0);
+ path q=(3.0,4.0);
+ path a=p..q..(3,5);
+ draw(pic,a,blue+dashed);
+ shipout("out/",pic);
+}
diff --git a/graphics/asymptote/tests/gc/string.asy b/graphics/asymptote/tests/gc/string.asy
new file mode 100644
index 0000000000..f379b86224
--- /dev/null
+++ b/graphics/asymptote/tests/gc/string.asy
@@ -0,0 +1,6 @@
+string a="abc";
+for (int i = 0; i < 1e7; ++i)
+{
+ "a"+"b";
+ a=reverse(a);
+}
diff --git a/graphics/asymptote/tests/gc/struct.asy b/graphics/asymptote/tests/gc/struct.asy
new file mode 100644
index 0000000000..11a007140d
--- /dev/null
+++ b/graphics/asymptote/tests/gc/struct.asy
@@ -0,0 +1,7 @@
+for (int i = 0; i < 1e7; ++i)
+{
+ picture pic;
+ unitsize(pic, 0.02mm, 0.04mm);
+ draw(pic,unitcircle);
+ shipout("out/",pic);
+}
diff --git a/graphics/asymptote/tests/gc/transform.asy b/graphics/asymptote/tests/gc/transform.asy
new file mode 100644
index 0000000000..abeef05656
--- /dev/null
+++ b/graphics/asymptote/tests/gc/transform.asy
@@ -0,0 +1,6 @@
+path p=unitsquare;
+
+for (int i = 0; i < 1e7; ++i)
+{
+ scale(2.0)*p;
+}
diff --git a/graphics/asymptote/tests/gs/ghostscript.asy b/graphics/asymptote/tests/gs/ghostscript.asy
new file mode 100644
index 0000000000..0a76eb9a3c
--- /dev/null
+++ b/graphics/asymptote/tests/gs/ghostscript.asy
@@ -0,0 +1,14 @@
+import TestLib;
+
+StartTest("Ghostscript");
+bool uptodate=texpath("A").length != 0;
+if(!uptodate) {
+ write();
+ write();
+ write("Incompatible Ghostscript version!");
+ write("Please set environment variable ASYMPTOTE_EPSDRIVER to");
+ write("\"epswrite\" for Ghostscript < 9.14 and to \"eps2write\" for Ghostscript >= 9.14");
+ write();
+}
+assert(uptodate);
+EndTest();
diff --git a/graphics/asymptote/tests/gsl/random.asy b/graphics/asymptote/tests/gsl/random.asy
new file mode 100644
index 0000000000..2418ad93e7
--- /dev/null
+++ b/graphics/asymptote/tests/gsl/random.asy
@@ -0,0 +1,338 @@
+import TestLib;
+import gsl;
+
+StartTest("random number generators");
+rng_init();
+assert(rng_min() == 0);
+assert(rng_max() == 4294967295);
+assert(rng_get() == 4293858116);
+rng_init("taus2");
+assert(rng_min() == 0);
+assert(rng_max() == 4294967295);
+assert(rng_get() == 802792108);
+rng_init("gfsr4");
+assert(rng_min() == 0);
+assert(rng_max() == 4294967295);
+assert(rng_get() == 2901276280);
+string[] list = rng_list();
+for(string name: list)
+{
+ rng_init(name);
+ rng_min();
+ rng_max();
+ rng_get();
+}
+assert(list.length >= 62);
+rng_init();
+rng_set(1);
+assert(rng_get() == 1791095845);
+rng_set(1);
+assert(rng_get() == 1791095845);
+EndTest();
+
+StartTest("Bernoulli distribution");
+assert(close(pdf_bernoulli(0,0.3), 0.7));
+assert(close(pdf_bernoulli(1,0.3), 0.3));
+//rng_init();
+//assert(rng_bernoulli(0.3) == 0);
+EndTest();
+
+StartTest("beta distribution");
+assert(close(cdf_beta_P(0.3,5,5), 0.09880866));
+assert(close(cdf_beta_Q(0.3,5,5) + cdf_beta_P(0.3,5,5), 1));
+assert(close(cdf_beta_Pinv(cdf_beta_P(0.3,5,5),5,5), 0.3));
+assert(close(cdf_beta_Qinv(cdf_beta_Q(0.3,5,5),5,5), 0.3));
+assert(close(pdf_beta(0.3,5,5), 1.2252303));
+//rng_init();
+//assert(close(rng_beta(5,5), 0.533021338130471));
+EndTest();
+
+StartTest("binomial distribution");
+assert(close(cdf_binomial_P(5,0.3,10), 0.9526510126));
+assert(close(cdf_binomial_P(5,0.3,10) + cdf_binomial_Q(5,0.3,10), 1));
+assert(close(pdf_binomial(5,0.3,10), 0.1029193452));
+//rng_init();
+//assert(rng_binomial(0.3,10) == 8);
+EndTest();
+
+StartTest("bivariate Gaussian distribution");
+assert(close(pdf_bivariate_gaussian((1,1),(0,2),(4,6),0.5),
+ 0.00675758392382108));
+//rng_init();
+//pair z = (-0.260388644979556,2.50057001628669);
+//pair r = rng_bivariate_gaussian((0,2),(4,6),0.5);
+//assert(close(length(r - z), 0));
+EndTest();
+
+StartTest("cauchy distribution");
+assert(close(cdf_cauchy_P(1,3), 0.602416382349567));
+assert(close(cdf_cauchy_P(1,3) + cdf_cauchy_Q(1,3), 1));
+assert(close(cdf_cauchy_Pinv(cdf_cauchy_P(1,3),3), 1));
+assert(close(cdf_cauchy_Qinv(cdf_cauchy_Q(1,3),3), 1));
+assert(close(pdf_cauchy(1,3), 0.0954929658551372));
+//rng_init();
+//assert(close(rng_cauchy(3), -0.0024339597467863));
+EndTest();
+
+StartTest("chi-squared distribution");
+assert(close(cdf_chisq_P(4,6), 0.323323583816936));
+assert(close(cdf_chisq_P(4,6) + cdf_chisq_Q(4, 6), 1));
+assert(close(cdf_chisq_Pinv(cdf_chisq_P(4,6),6), 4));
+assert(close(cdf_chisq_Qinv(cdf_chisq_Q(4,6),6), 4));
+assert(close(pdf_chisq(4,6), 0.135335283236613));
+//rng_init();
+//assert(close(rng_chisq(6), 8.24171826270279));
+EndTest();
+
+StartTest("Dirichlet distribution");
+real[] alpha = {1,2,3,4};
+real[] theta = {0.1,0.2,0.3,0.4};
+assert(close(pdf_dirichlet(alpha,theta), 34.83648));
+//rng_init();
+//real[] z = {0.124480735441317,
+// 0.191823537067349,
+// 0.460543885448264,
+// 0.22315184204307};
+//real[] r = rng_dirichlet(alpha);
+//assert(close(norm(r - z), 0));
+EndTest();
+
+StartTest("exponential distribution");
+assert(close(cdf_exponential_P(2,3), 0.486582880967408));
+assert(close(cdf_exponential_P(2,3) + cdf_exponential_Q(2,3), 1));
+assert(close(cdf_exponential_Pinv(cdf_exponential_P(2,3),3), 2));
+assert(close(cdf_exponential_Qinv(cdf_exponential_Q(2,3),3), 2));
+assert(close(pdf_exponential(2,3), 0.171139039677531));
+//rng_init();
+//assert(close(rng_exponential(3), 24.7847346491112));
+EndTest();
+
+StartTest("exponential power distribution");
+assert(close(cdf_exppow_P(2,3,2), 0.82711070692442));
+assert(close(cdf_exppow_P(2,3,2) + cdf_exppow_Q(2,3,2), 1));
+assert(close(pdf_exppow(2,3,2), 0.120582432109095));
+//rng_init();
+//assert(close(rng_exppow(3,2), 0.284084267783339));
+EndTest();
+
+StartTest("F-distribution");
+assert(close(cdf_fdist_P(1,5,4), 0.485657196759213));
+assert(close(cdf_fdist_P(1,5,4) + cdf_fdist_Q(1,5,4), 1));
+//rng_init();
+//assert(close(rng_fdist(5,4), 1.20570928490019));
+EndTest();
+
+StartTest("flat (uniform) distribution");
+assert(close(cdf_flat_P(2,0,5), 0.4));
+assert(close(cdf_flat_P(2,0,5) + cdf_flat_Q(2,0,5), 1));
+assert(close(cdf_flat_Pinv(cdf_flat_P(2,0,5),0,5), 2));
+assert(close(cdf_flat_Qinv(cdf_flat_Q(2,0,5),0,5), 2));
+assert(close(pdf_flat(2,0,5), 0.2));
+//rng_init();
+//assert(close(rng_flat(0,5), 4.99870874453336));
+EndTest();
+
+StartTest("Gamma-distribution");
+assert(close(cdf_gamma_P(6,5,1), 0.71494349968337));
+assert(close(cdf_gamma_P(6,5,1) + cdf_gamma_Q(6,5,1), 1));
+assert(close(cdf_gamma_Pinv(cdf_gamma_P(6,5,1),5,1), 6));
+assert(close(cdf_gamma_Qinv(cdf_gamma_Q(6,5,1),5,1), 6));
+assert(close(pdf_gamma(6,5,1), 0.133852617539983));
+//rng_init();
+//assert(close(rng_gamma(5,1), 6.52166444209317));
+//assert(close(rng_gamma(5,1,"mt"), 5.71361391461836));
+//assert(close(rng_gamma(5,1,"knuth"), 1.53054227085541));
+EndTest();
+
+StartTest("Gaussian distribution");
+assert(close(cdf_gaussian_P(1,0,1), 0.841344746068543));
+assert(close(cdf_gaussian_P(1,0,1) + cdf_gaussian_Q(1,0,1), 1));
+assert(close(cdf_gaussian_Pinv(cdf_gaussian_P(1,0,1),0,1), 1));
+assert(close(cdf_gaussian_Qinv(cdf_gaussian_Q(1,0,1),0,1), 1));
+assert(close(pdf_gaussian(1,0,1), 0.241970724519143));
+//rng_init();
+//assert(close(rng_gaussian(0,1), 0.133918608118676));
+//assert(close(rng_gaussian(1,2,"ziggurat"), 1.90467233084303));
+//assert(close(rng_gaussian(1,2,"ratio"), 4.04779517509342));
+//assert(close(rng_gaussian(1,2,"polar"), 1.54245166575101));
+EndTest();
+
+StartTest("Gaussian tail distribution");
+assert(close(pdf_gaussian_tail(2,1,1), 0.34030367841782));
+//rng_init();
+//assert(close(rng_gaussian_tail(1,1), 1.0528474462339));
+EndTest();
+
+StartTest("geometric distribution");
+assert(close(cdf_geometric_P(6,0.1), 0.468559));
+assert(close(cdf_geometric_P(6,0.1) + cdf_geometric_Q(6,0.1), 1));
+assert(close(pdf_geometric(6,0.1), 0.059049));
+//rng_init();
+//assert(rng_geometric(0.1) == 1);
+EndTest();
+
+StartTest("Gumbel1 distribution");
+assert(close(cdf_gumbel1_P(1,3,8), 0.671462877871127));
+assert(close(cdf_gumbel1_P(1,3,8) + cdf_gumbel1_Q(1,3,8), 1));
+assert(close(cdf_gumbel1_Pinv(cdf_gumbel1_P(1,3,8),3,8), 1));
+assert(close(cdf_gumbel1_Qinv(cdf_gumbel1_Q(1,3,8),3,8), 1));
+assert(close(pdf_gumbel1(1,3,8), 0.80232403696926));
+//rng_init();
+//assert(close(rng_gumbel1(3,8), 3.44696353953564));
+EndTest();
+
+StartTest("Gumbel2 distribution");
+assert(close(cdf_gumbel2_P(2,2,3), 0.472366552741015));
+assert(close(cdf_gumbel2_P(2,2,3) + cdf_gumbel2_Q(2,2,3), 1));
+assert(close(cdf_gumbel2_Pinv(cdf_gumbel2_P(2,2,3),2,3), 2));
+assert(close(cdf_gumbel2_Qinv(cdf_gumbel2_Q(2,2,3),2,3), 2));
+assert(close(pdf_gumbel2(2,2,3), 0.354274914555761));
+//rng_init();
+//assert(close(rng_gumbel2(2,3), 107.773379309453));
+EndTest();
+
+StartTest("hypergeometric distribution");
+assert(close(cdf_hypergeometric_P(4,10,10,8), 0.675041676589664));
+assert(close(cdf_hypergeometric_P(4,10,10,8) +
+ cdf_hypergeometric_Q(4,10,10,8), 1));
+assert(close(pdf_hypergeometric(4,10,10,8), 0.350083353179329));
+//rng_init();
+//assert(rng_hypergeometric(10,10,8) == 3);
+EndTest();
+
+StartTest("Laplace distribution");
+assert(close(cdf_laplace_P(1,2), 0.696734670143683));
+assert(close(cdf_laplace_P(1,2) + cdf_laplace_Q(1,2), 1));
+assert(close(cdf_laplace_Pinv(cdf_laplace_P(1,2),2), 1));
+assert(close(cdf_laplace_Qinv(cdf_laplace_Q(1,2),2), 1));
+assert(close(pdf_laplace(1,2), 0.151632664928158));
+//rng_init();
+//assert(close(rng_laplace(2), 0.00103327123971616));
+EndTest();
+
+StartTest("Landau distribution");
+assert(close(pdf_landau(1), 0.145206637130862));
+//rng_init();
+//assert(close(rng_landau(), 3880.0374262546));
+EndTest();
+
+//StartTest("Levy stable distribution");
+//rng_init();
+//assert(close(rng_levy(1,1,0), 1232.55941432972));
+//assert(close(rng_levy(1,1,1), -0.13781830409645));
+//EndTest();
+
+StartTest("logistic distribution");
+assert(close(cdf_logistic_P(1,2), 0.622459331201855));
+assert(close(cdf_logistic_P(1,2) + cdf_logistic_Q(1,2), 1));
+assert(close(cdf_logistic_Pinv(cdf_logistic_P(1,2),2), 1));
+assert(close(cdf_logistic_Qinv(cdf_logistic_Q(1,2),2), 1));
+assert(close(pdf_logistic(1,2), 0.117501856100797));
+//rng_init();
+//assert(close(rng_logistic(2), 16.522639863849));
+EndTest();
+
+StartTest("lognormal distribution");
+assert(close(cdf_lognormal_P(6,2,1), 0.417520581602749));
+assert(close(cdf_lognormal_P(6,2,1) + cdf_lognormal_Q(6,2,1), 1));
+assert(close(cdf_lognormal_Pinv(cdf_lognormal_P(6,2,1),2,1), 6));
+assert(close(cdf_lognormal_Qinv(cdf_lognormal_Q(6,2,1),2,1), 6));
+assert(close(pdf_lognormal(6,2,1), 0.0650642483079156));
+//rng_init();
+//assert(close(rng_lognormal(2,1), 6.92337133931968));
+EndTest();
+
+StartTest("multinomial distribution");
+real[] p = {0.1,0.2,0.3,0.4};
+int[] n = {1,2,3,4};
+assert(close(pdf_multinomial(p,n), 0.03483648));
+//rng_init();
+//int[] r = {5, 0, 1, 4};
+//assert(all(rng_multinomial(10,p) == r));
+EndTest();
+
+StartTest("negative binomial distribution");
+assert(close(cdf_negative_binomial_P(6,0.5,10), 0.227249145507813));
+assert(close(cdf_negative_binomial_P(6,0.5,10) +
+ cdf_negative_binomial_Q(6,0.5,10), 1));
+assert(close(pdf_negative_binomial(6,0.5,10), 0.076370239257812));
+//rng_init();
+//assert(rng_negative_binomial(0.5,10) == 15);
+EndTest();
+
+StartTest("Pareto distribution");
+assert(close(cdf_pareto_P(4,2,2), 0.75));
+assert(close(cdf_pareto_P(4,2,2) + cdf_pareto_Q(4,2,2), 1));
+assert(close(cdf_pareto_Pinv(cdf_pareto_P(4,2,2),2,2), 4));
+assert(close(cdf_pareto_Qinv(cdf_pareto_Q(4,2,2),2,2), 4));
+assert(close(pdf_pareto(4,2,2), 0.125));
+//rng_init();
+//assert(close(rng_pareto(2,2), 2.00025830112432));
+EndTest();
+
+StartTest("Poisson distribution");
+assert(close(cdf_poisson_P(5,6), 0.445679641364611));
+assert(close(cdf_poisson_P(5,6) + cdf_poisson_Q(5,6), 1));
+assert(close(pdf_poisson(5,6), 0.16062314104798));
+//rng_init();
+//assert(rng_poisson(6) == 8);
+EndTest();
+
+StartTest("Rayleigh distribution");
+assert(close(cdf_rayleigh_P(3,2), 0.67534753264165));
+assert(close(cdf_rayleigh_P(3,2) + cdf_rayleigh_Q(3,2), 1));
+assert(close(cdf_rayleigh_Pinv(cdf_rayleigh_P(3,2),2), 3));
+assert(close(cdf_rayleigh_Qinv(cdf_rayleigh_Q(3,2),2), 3));
+assert(close(pdf_rayleigh(3,2), 0.243489350518762));
+//rng_init();
+//assert(close(rng_rayleigh(2), 0.0454563039310455));
+EndTest();
+
+StartTest("Rayleigh tail distribution");
+assert(close(pdf_rayleigh_tail(5,4,1), 0.0555449826912115));
+//rng_init();
+//assert(close(rng_rayleigh_tail(4,1), 4.0000645705903));
+EndTest();
+
+//StartTest("spherical distributions");
+//rng_init();
+//pair z = (-0.617745613497854,-0.786377998804748);
+//pair r = rng_dir2d();
+//assert(close(length(r - z), 0));
+//pair z = (0.993748310886084,0.111643605329884);
+//pair r = rng_dir2d("neumann");
+//assert(close(length(r - z), 0));
+//pair z = (0.964519203132591,-0.264012701945327);
+//pair r = rng_dir2d("trig");
+//assert(close(length(r - z), 0));
+//triple z = (0.849028025629996,0.139162687752509,-0.509691237939527);
+//triple r = rng_dir3d();
+//assert(close(length(r - z), 0));
+//real[] z = {0.420990368676528,
+// -0.626782975357296,
+// 0.0441585572224004,
+// -0.0458388920727644,
+// -0.652578753164271};
+//real[] r = rng_dir(5);
+//assert(close(norm(r - z), 0));
+//EndTest();
+
+StartTest("t-distribution");
+assert(close(cdf_tdist_P(0.6,2), 0.695283366471236));
+assert(close(cdf_tdist_P(0.6,2) + cdf_tdist_Q(0.6,2), 1));
+assert(close(cdf_tdist_Pinv(cdf_tdist_P(0.6,2),2), 0.6));
+assert(close(cdf_tdist_Qinv(cdf_tdist_Q(0.6,2),2), 0.6));
+assert(close(pdf_tdist(0.6,2), 0.275823963942424));
+//rng_init();
+//assert(close(rng_tdist(2), 0.127201714006725));
+EndTest();
+
+StartTest("Weibull distribution");
+assert(close(cdf_weibull_P(1,2,2), 0.221199216928595));
+assert(close(cdf_weibull_P(1,2,2) + cdf_weibull_Q(1,2,2), 1));
+assert(close(cdf_weibull_Pinv(cdf_weibull_P(1,2,2),2,2), 1));
+assert(close(cdf_weibull_Qinv(cdf_weibull_Q(1,2,2),2,2), 1));
+assert(close(pdf_weibull(1,2,2), 0.389400391535702));
+//rng_init();
+//assert(close(rng_weibull(2,2), 0.032142460757319));
+EndTest();
diff --git a/graphics/asymptote/tests/imp/unravel.asy b/graphics/asymptote/tests/imp/unravel.asy
new file mode 100644
index 0000000000..0f61326fd6
--- /dev/null
+++ b/graphics/asymptote/tests/imp/unravel.asy
@@ -0,0 +1,95 @@
+import TestLib;
+StartTest("unravel");
+{
+ struct A {
+ int x=1, y=2, z=3;
+ int y() { return 7; }
+ }
+
+ A a=new A;
+ unravel a;
+ assert(x==1);
+ assert(y==2);
+ assert(z==3);
+ assert(y()==7);
+}
+{
+ struct A {
+ private int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int x=5;
+ A a=new A;
+ unravel a;
+ assert(x==5);
+ assert(y==2);
+ assert(z==3);
+}
+{
+ struct A {
+ public int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int z=5;
+ A a=new A;
+ from a unravel x,y;
+ assert(x==1);
+ assert(y==2);
+ assert(z==5);
+ assert(y()==7);
+}
+{
+ struct A {
+ public int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int y=4;
+ int z=5;
+ A a=new A;
+ from a unravel x,y as blah;
+ assert(x==1);
+ assert(y==4);
+ assert(blah==2);
+ assert(z==5);
+ assert(blah()==7);
+}
+{
+ struct A {
+ struct B {
+ static int x=4;
+ }
+ }
+ A a=new A;
+ int x=3;
+ from a.B unravel x;
+ assert(x==4);
+}
+{
+ struct A {
+ struct B {
+ static int x=4;
+ }
+ }
+ A a=new A;
+ A.B b=new a.B;
+ int x=3;
+ from b unravel x;
+ assert(x==4);
+}
+{
+ struct A {
+ static struct B {
+ static int x=4;
+ }
+ }
+ int x=3;
+ from A.B unravel x;
+ assert(x==4);
+}
+EndTest();
diff --git a/graphics/asymptote/tests/output/Makefile b/graphics/asymptote/tests/output/Makefile
new file mode 100644
index 0000000000..938625ab03
--- /dev/null
+++ b/graphics/asymptote/tests/output/Makefile
@@ -0,0 +1,41 @@
+# Automated testing to see if the output of Asymptote scripts changes when the
+# program is modified.
+
+# How to call asy from the tests/output/name.out directory
+ASY=../../../asy
+
+TESTS=$(basename $(wildcard *.asy))
+
+# This command performs the testing on all scripts.
+diff: $(TESTS:=.diff)
+
+# This builds the reference copies of the output using a trusted version of asy
+ref: $(TESTS:=.ref)
+
+$(TESTS:=.ref) $(TESTS:=.out): %:
+ @echo Generating $@
+ @rm -rf $@
+ @mkdir $@
+ @cd $@; \
+ $(ASY) -keep ../$(basename $@) \
+ >$(basename $@).stdout 2>$(basename $@).stderr; \
+ ls >$(basename $@).ls; \
+ rm -f *.dvi *.pdf *.gif *.jpg *.jpeg *.png
+
+# Ignore lines with timestamps of the form hh:mm, since the time changes between
+# runs. This regex is fairly broad and it may need to be narrowed.
+$(TESTS:=.diff): %.diff: %.out
+ diff -I "[0-9][0-9]:[0-9][0-9]" -u $(@:.diff=.ref) $(@:.diff=.out)
+
+clean:
+ rm -rf *.out
+
+# The reference copies should only be built at the start, or when the behaviour
+# of Asymptote is intentionally changed, so they are not usually removed by make
+# clean.
+veryclean: clean
+ rm -rf *.ref
+
+# This tells make to build every dependency from scratch, ignoring the dates on
+# files.
+.PHONY: $(TESTS:=.ref) $(TESTS:=.out) $(TESTS:=.diff) diff ref clean veryclean
diff --git a/graphics/asymptote/tests/output/circle.asy b/graphics/asymptote/tests/output/circle.asy
new file mode 100644
index 0000000000..e0300acdb8
--- /dev/null
+++ b/graphics/asymptote/tests/output/circle.asy
@@ -0,0 +1 @@
+draw(unitcircle);
diff --git a/graphics/asymptote/tests/output/line.asy b/graphics/asymptote/tests/output/line.asy
new file mode 100644
index 0000000000..21acd4fc4e
--- /dev/null
+++ b/graphics/asymptote/tests/output/line.asy
@@ -0,0 +1 @@
+draw((0,0)--(100,0));
diff --git a/graphics/asymptote/tests/pic/trans.asy b/graphics/asymptote/tests/pic/trans.asy
new file mode 100644
index 0000000000..9a2e02decf
--- /dev/null
+++ b/graphics/asymptote/tests/pic/trans.asy
@@ -0,0 +1,75 @@
+import TestLib;
+
+StartTest("trans");
+
+// Ensure the same test each time.
+srand(3456);
+
+pair randompair()
+{
+ return (unitrand(),unitrand());
+}
+
+path randombox()
+{
+ return box(randompair(), randompair());
+}
+
+// For now, only tests transforms which take axes to axes.
+transform randomtrans()
+{
+ return rotate(90 * (rand() % 4)) * shift(unitrand(), unitrand());
+}
+
+real tolerance = 1e-4;
+
+void testpic(int objs, int trans)
+{
+ path[] pp;
+ picture orig;
+ for (int i = 0; i < objs; ++i) {
+ pp.push(randombox());
+ fill(orig, pp[i]);
+ }
+
+ picture pic = orig;
+ transform t = identity();
+ for (int i = 0; i < trans; ++i)
+ {
+ transform tt = randomtrans();
+ pic = tt * pic;
+ t = tt * t;
+ }
+
+ pair m = pic.userMin2(), M = pic.userMax2();
+ pair pm = min(t * pp), pM = max(t * pp);
+
+ assert(abs(m-pm) < tolerance);
+ assert(abs(M-pM) < tolerance);
+}
+
+for (int i = 0; i < 100; ++i)
+ testpic(1,1);
+for (int i = 0; i < 100; ++i)
+ testpic(1,1);
+for (int i = 0; i < 100; ++i)
+ testpic(3,1);
+for (int i = 0; i < 100; ++i)
+ testpic(1,2);
+for (int i = 0; i < 100; ++i)
+ testpic(2,2);
+for (int i = 0; i < 100; ++i)
+ testpic(3,2);
+for (int i = 0; i < 100; ++i)
+ testpic(3,4);
+for (int i = 0; i < 100; ++i)
+ testpic(1,4);
+for (int i = 0; i < 100; ++i)
+ testpic(2,4);
+for (int i = 0; i < 100; ++i)
+ testpic(3,4);
+for (int i = 0; i < 100; ++i)
+ testpic(3,4);
+
+
+EndTest();
diff --git a/graphics/asymptote/tests/string/erase.asy b/graphics/asymptote/tests/string/erase.asy
new file mode 100644
index 0000000000..2b38b61f35
--- /dev/null
+++ b/graphics/asymptote/tests/string/erase.asy
@@ -0,0 +1,9 @@
+import TestLib;
+StartTest("erase");
+string s = "abcdef";
+assert(erase(s,2,2) == "abef");
+assert(erase(s,-1,2) == "abcdef");
+assert(erase(s,7,1) == "abcdef");
+assert(erase(s,3,0) == "abcdef");
+assert(erase(s,5,2) == "abcde");
+EndTest();
diff --git a/graphics/asymptote/tests/string/find.asy b/graphics/asymptote/tests/string/find.asy
new file mode 100644
index 0000000000..cdf6dc6740
--- /dev/null
+++ b/graphics/asymptote/tests/string/find.asy
@@ -0,0 +1,8 @@
+import TestLib;
+StartTest("find");
+string s = "abcdefab";
+assert(find(s,"cd") == 2);
+assert(find(s,"cd",3) == -1);
+assert(find(s,"ab") == 0);
+assert(find(s,"ab",1) == 6);
+EndTest();
diff --git a/graphics/asymptote/tests/string/insert.asy b/graphics/asymptote/tests/string/insert.asy
new file mode 100644
index 0000000000..2c11a2ef00
--- /dev/null
+++ b/graphics/asymptote/tests/string/insert.asy
@@ -0,0 +1,5 @@
+import TestLib;
+StartTest("insert");
+string sub = insert("abef",2,"cd");
+assert(sub == "abcdef");
+EndTest();
diff --git a/graphics/asymptote/tests/string/length.asy b/graphics/asymptote/tests/string/length.asy
new file mode 100644
index 0000000000..dafb5d56b9
--- /dev/null
+++ b/graphics/asymptote/tests/string/length.asy
@@ -0,0 +1,6 @@
+import TestLib;
+StartTest("length");
+assert(length("") == 0);
+assert(length("abc") == 3);
+assert(length("abcdef") == 6);
+EndTest();
diff --git a/graphics/asymptote/tests/string/rfind.asy b/graphics/asymptote/tests/string/rfind.asy
new file mode 100644
index 0000000000..2291097a7e
--- /dev/null
+++ b/graphics/asymptote/tests/string/rfind.asy
@@ -0,0 +1,8 @@
+import TestLib;
+StartTest("rfind");
+string s = "abcdefab";
+assert(rfind(s,"cd") == 2);
+assert(rfind(s,"cd",1) == -1);
+assert(rfind(s,"ab") == 6);
+assert(rfind(s,"ab",5) == 0);
+EndTest();
diff --git a/graphics/asymptote/tests/string/substr.asy b/graphics/asymptote/tests/string/substr.asy
new file mode 100644
index 0000000000..6426895aa3
--- /dev/null
+++ b/graphics/asymptote/tests/string/substr.asy
@@ -0,0 +1,6 @@
+import TestLib;
+StartTest("substr");
+string s = "abcdef";
+string sub = substr(s,2,2);
+assert(sub == "cd");
+EndTest();
diff --git a/graphics/asymptote/tests/types/cast.asy b/graphics/asymptote/tests/types/cast.asy
new file mode 100644
index 0000000000..b119163755
--- /dev/null
+++ b/graphics/asymptote/tests/types/cast.asy
@@ -0,0 +1,13 @@
+import TestLib;
+StartTest("cast");
+struct A {
+ public int x;
+}
+A operator cast(int x) {
+ A a=new A;
+ a.x=x;
+ return a;
+}
+A a=7;
+assert(a.x==7);
+EndTest();
diff --git a/graphics/asymptote/tests/types/constructor.asy b/graphics/asymptote/tests/types/constructor.asy
new file mode 100644
index 0000000000..78a0684fa9
--- /dev/null
+++ b/graphics/asymptote/tests/types/constructor.asy
@@ -0,0 +1,380 @@
+import TestLib;
+StartTest("constructor");
+
+{ // Basic usage. {{{1
+ struct Foo {
+ int x;
+ int y;
+
+ void operator init() {
+ x=2; y=3;
+ }
+
+ void operator init(int x, int y=2x) {
+ this.x=x; this.y=y;
+ }
+
+ void operator init(string s ... int[] vals) {
+ for (int i=0; i<vals.length; ++i)
+ x+=vals[i];
+ y=vals.length;
+ }
+
+ static {
+ {
+ Foo f=new Foo;
+ assert(f.x==0);
+ assert(f.y==0);
+ }
+ {
+ Foo f=Foo();
+ assert(f.x==2);
+ assert(f.y==3);
+ }
+ {
+ Foo f=Foo(7);
+ assert(f.x==7);
+ assert(f.y==14);
+ }
+ {
+ Foo f=Foo(5,40);
+ assert(f.x==5);
+ assert(f.y==40);
+ }
+ {
+ Foo f=Foo(y=5,x=40);
+ assert(f.x==40);
+ assert(f.y==5);
+ }
+ {
+ Foo f=Foo("hello", 1,2,3,4);
+ assert(f.x==10);
+ assert(f.y==4);
+ }
+ }
+ }
+
+ {
+ Foo f=new Foo;
+ assert(f.x==0);
+ assert(f.y==0);
+ }
+ {
+ Foo f=Foo();
+ assert(f.x==2);
+ assert(f.y==3);
+ }
+ {
+ Foo f=Foo(7);
+ assert(f.x==7);
+ assert(f.y==14);
+ }
+ {
+ Foo f=Foo(5,40);
+ assert(f.x==5);
+ assert(f.y==40);
+ }
+ {
+ Foo f=Foo(y=5,x=40);
+ assert(f.x==40);
+ assert(f.y==5);
+ }
+ {
+ Foo f=Foo("hello", 1,2,3,4);
+ assert(f.x==10);
+ assert(f.y==4);
+ }
+}
+
+{ // Assignment {{{1
+ struct Foo {
+ int x;
+
+ static int Foo() {
+ return 7;
+ }
+
+ static assert(Foo()==7);
+
+ void five() {
+ x=5;
+ }
+
+ void six(string s) {
+ x=6;
+ }
+
+ void operator init()=five;
+
+ void operator init(string s) {
+ assert(false);
+ }
+ operator init=six;
+
+ static {
+ assert(Foo().x==5);
+ assert(Foo("milk").x==6);
+ }
+
+ void operator init(int x) {
+ this.x=2x;
+ }
+
+ static Foo constructor(int)=Foo;
+
+ static {
+ assert(constructor(5).x==10);
+ }
+ }
+
+ assert(Foo().x==5);
+ assert(Foo("milk").x==6);
+ assert(Foo.constructor(5).x==10);
+}
+
+{ // Permission {{{1
+ int Foo() {
+ return 3;
+ }
+
+ struct Foo {
+ int x;
+
+ private void operator init() {
+ x=2;
+ }
+ }
+ // The implicit constructor should not be unravelled, as it is private.
+ assert(Foo()==3);
+}
+{ // Shadowing {{{1
+ struct Foo {
+ static Foo Foo() {
+ return null;
+ }
+
+ static assert(Foo()==null);
+
+ void operator init() {
+ }
+
+ static assert(Foo()!=null);
+ }
+
+ assert(Foo()!=null);
+
+ // Can't use Bar because of conflicts with the drawing command.
+ struct Barr {
+ void operator init() {
+ }
+
+ static assert(Barr()!=null);
+
+ static Barr Barr() {
+ return null;
+ }
+
+ static assert(Barr()==null);
+ }
+
+ assert(Barr()!=null);
+
+ struct Blah {
+ void operator init() {
+ }
+
+ static assert(Blah()!=null);
+
+ static Blah Blah() {
+ return null;
+ }
+
+ static assert(Blah()==null);
+ }
+ from Blah unravel Blah;
+
+ assert(Blah()==null);
+}
+
+{ // Static {{{1
+ struct Foo {
+ static int Foo() {
+ return 7;
+ }
+
+ static void operator init() {
+ }
+
+ static assert(Foo()==7);
+ }
+
+ struct Barr {
+ int x;
+
+ void operator init() {
+ x=77;
+ }
+
+ static assert(Barr().x==77);
+
+ static void operator init() {
+ assert(false);
+ }
+
+ static assert(Barr().x==77);
+ }
+
+ assert(Barr().x==77);
+}
+
+{ // Struct name shadowing. {{{1
+ struct Foo {
+ int x;
+ typedef int Foo;
+
+ void operator init() {
+ x=89;
+ }
+
+ static assert(Foo().x==89);
+ }
+
+ assert(Foo().x==89);
+
+ struct Barr {
+ int x;
+ struct Barr {
+ }
+
+ void operator init() {
+ x=89;
+ }
+
+ static assert(Barr().x==89);
+ }
+
+ assert(Barr().x==89);
+}
+{ // Function Comparison
+ struct A {
+ // Defines a function A A(int).
+ void operator init(int x) {}
+ }
+ assert(!(A == null));
+ assert(A != null);
+}
+
+// File-level {{{1
+// This assumes the file is named constructor.asy
+
+int constructor() {
+ return 44;
+}
+void operator init() {
+ assert(false);
+}
+assert(constructor()==44);
+
+EndTest(); // {{{1
+
+StartTest("tuple"); // {{{1
+{
+ pair z = (1,2);
+ assert(z.x==1);
+ assert(z.y==2);
+ pair w = z;
+ w = (2,3);
+ assert(z.x==1);
+ assert(z.y==2);
+}
+{
+ triple z = (1,2,6);
+ assert(z.x==1);
+ assert(z.y==2);
+ assert(z.z==6);
+ triple w = z;
+ w = (2,3,9);
+ assert(z.x==1);
+ assert(z.y==2);
+ assert(z.z==6);
+}
+{
+ transform z = (1,2,3,4,5,6);
+ assert(z.x==1);
+ assert(z.y==2);
+ assert(z.xx==3);
+ assert(z.xy==4);
+ assert(z.yx==5);
+ assert(z.yy==6);
+}
+{
+ pair z = (34.0, 35.0);
+ triple t = (34.0, 35.0, 36.0);
+
+ {
+ int operator tuple(int x, int y) { return x+y; }
+ assert((1,2) == 3);
+ assert((34,35) == 34+35);
+ assert((34.0,35) == z);
+ assert((34,35.0) == z);
+ assert((34.0,35.0) == z);
+ }
+ {
+ int operator tuple(int x, int y) { return x+y; }
+ int operator tuple(int x, real y) { return 123; }
+ assert((1,2) == 3);
+ assert((34,35) == 34+35);
+ assert((34.0,35) == z);
+ assert((34,35.0) == 123);
+ assert((34.0,35.0) == z);
+ }
+ {
+ int operator tuple(int x, int y) { return x+y; }
+ int operator tuple(int x, real y) { return 123; }
+ int operator tuple(real x, int y) { return 456; }
+ assert((1,2) == 3);
+ assert((34,35) == 34+35);
+ assert((34.0,35) == 456);
+ assert((34,35.0) == 123);
+ assert((34.0,35.0) == z);
+ }
+ {
+ int operator tuple(int x, int y) { return x+y; }
+ int operator tuple(real x, int y) { return 456; }
+ assert((1,2) == 3);
+ assert((34,35) == 34+35);
+ assert((34.0,35) == 456);
+ assert((34,35.0) == z);
+ assert((34.0,35.0) == z);
+ }
+ {
+ int operator tuple(int x, int y) { return x+y; }
+ int operator tuple(int x, real y) { return 123; }
+ int operator tuple(real x, int y) { return 456; }
+ int operator tuple(real x, real y) { return 789; }
+ assert((1,2) == 3);
+ assert((34,35) == 34+35);
+ assert((34.0,35) == 456);
+ assert((34,35.0) == 123);
+ assert((34.0,35.0) == 789);
+ }
+ {
+ int operator tuple(int x, int y) { return x+y; }
+ int operator tuple(real x, real y) { return 789; }
+ assert((1,2) == 3);
+ assert((34,35) == 34+35);
+ assert((34.0,35) == 789);
+ assert((34,35.0) == 789);
+ assert((34.0,35.0) == 789);
+ }
+ {
+ int operator tuple(...int[] x) { return x.length; }
+ assert((34,35) == z);
+ assert((34,35,36) == t);
+ assert((34,35,36,37) == 4);
+ assert((34,35,36,37,38) == 5);
+ assert((34,35,36,37,1,2,3,4) == 8);
+ assert((34,35,36,37,1,2,3,4,5,6,7,8,9) == 13);
+ }
+}
+EndTest();
diff --git a/graphics/asymptote/tests/types/ecast.asy b/graphics/asymptote/tests/types/ecast.asy
new file mode 100644
index 0000000000..d16d7bc449
--- /dev/null
+++ b/graphics/asymptote/tests/types/ecast.asy
@@ -0,0 +1,11 @@
+import TestLib;
+StartTest("ecast");
+struct A {
+ public int x;
+}
+int operator ecast(A a) {
+ return a.x;
+}
+A a=new A; a.x=5;
+assert((int)a==5);
+EndTest();
diff --git a/graphics/asymptote/tests/types/guide.asy b/graphics/asymptote/tests/types/guide.asy
new file mode 100644
index 0000000000..ec16e0ed7c
--- /dev/null
+++ b/graphics/asymptote/tests/types/guide.asy
@@ -0,0 +1,160 @@
+import TestLib;
+StartTest("guide");
+
+guide g;
+assert(size(g) == 0);
+assert(length(g) == -1);
+
+guide g=(0,0){curl 2}..(1,1){W}..tension 5 and 6 ..{N}(4,2)..{curl 3}(0,1);
+
+g=reverse(reverse(g));
+
+assert(size(g) == 4);
+assert(length(g) == 3);
+
+assert(size((path) g) == 4);
+assert(length((path) g) == 3);
+
+assert(size((guide) (path) g) == 4);
+assert(length((guide) (path) g) == 3);
+
+assert(close(point(g,-1),(0,0)));
+assert(close(point(g,0),(0,0)));
+assert(close(point(g,1),(1,1)));
+assert(close(point(g,3),(0,1)));
+assert(close(point(g,4),(0,1)));
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == false);
+
+pair[] z=dirSpecifier(g,0);
+assert(close(z[0],0));
+assert(close(z[1],0));
+
+pair[] z=dirSpecifier(g,1);
+assert(close(z[0],W));
+assert(close(z[1],N));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],2));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],3));
+
+assert(!cyclic(g));
+assert(!cyclic((path) g));
+assert(!cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5)..(1,1){W}..tension atleast 5 and 6 ..{N}(4,2)..
+controls(1,2) and (2,4).. (0,1)..cycle;
+
+g=reverse(reverse(g));
+
+assert(size(g) == 4);
+assert(length(g) == 4);
+
+assert(size((path) g) == 4);
+assert(length((path) g) == 4);
+
+assert(size((guide) (path) g) == 4);
+assert(length((guide) (path) g) == 4);
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == true);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(3,5)));
+assert(close(z[1],(3,5)));
+
+pair[] z=controlSpecifier(g,2);
+assert(close(z[0],(1,2)));
+assert(close(z[1],(2,4)));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+assert(cyclic(g));
+assert(cyclic((path) g));
+assert(cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5)..(1,1){W}..tension atleast 5 and 6 ..{N}(4,2)..
+cycle..controls(1,2) and (2,4)..(0,1)..cycle;
+
+assert(size(g) == 5);
+assert(length(g) == 5);
+
+assert(size((path) g) == 5);
+assert(length((path) g) == 5);
+
+assert(size((guide) (path) g) == 5);
+assert(length((guide) (path) g) == 5);
+
+pair[] z=dirSpecifier(g,0);
+assert(close(z[0],0));
+assert(close(z[1],0));
+
+pair[] z=dirSpecifier(g,1);
+assert(close(z[0],W));
+assert(close(z[1],N));
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == true);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(3,5)));
+assert(close(z[1],(3,5)));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+assert(cyclic(g));
+assert(cyclic((path) g));
+assert(cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5) and (4,6)..cycle;
+
+g=reverse(g);
+
+assert(size(g) == 1);
+assert(length(g) == 1);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(4,6)));
+assert(close(z[1],(3,5)));
+
+// Test building guides in loops.
+int N = 100;
+guide g;
+for (int i = 0; i < N; ++i)
+ g = g--(i,i^2);
+path p=g;
+for (int i = 0; i < N; ++i)
+ assert(point(p, i) == (i,i^2));
+
+int N = 100;
+guide g;
+for (int i = 0; i < N; ++i)
+ g = (i,i^2)--g;
+path p=g;
+for (int i = N-1, j = 0; i >= 0; --i, ++j)
+ assert(point(p, j) == (i,i^2));
+EndTest();
+
diff --git a/graphics/asymptote/tests/types/init.asy b/graphics/asymptote/tests/types/init.asy
new file mode 100644
index 0000000000..5557bd0676
--- /dev/null
+++ b/graphics/asymptote/tests/types/init.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("init");
+int operator init() { return 7; }
+int x;
+assert(x==7);
+
+struct A {
+ int x=3;
+}
+A a;
+assert(a!=null);
+assert(a.x==3);
+
+A operator init() { return null; }
+A aa;
+assert(aa==null);
+EndTest();
diff --git a/graphics/asymptote/tests/types/keyword.asy b/graphics/asymptote/tests/types/keyword.asy
new file mode 100644
index 0000000000..73e407b6f8
--- /dev/null
+++ b/graphics/asymptote/tests/types/keyword.asy
@@ -0,0 +1,190 @@
+import TestLib;
+StartTest("keyword");
+{
+ int f(int keyword x) {
+ return 2*x;
+ }
+
+ assert(f(x=17) == 34);
+}
+
+{
+ int f(int keyword x = 10) {
+ return 2*x;
+ }
+
+ assert(f() == 20);
+}
+
+{
+ int f(int keyword x = 10, int keyword y = 20)
+ {
+ return 2x+y;
+ }
+
+ assert(f(x=1,y=2) == 4);
+ assert(f(y=1,x=2) == 5);
+ assert(f(x=1) == 22);
+ assert(f(y=7) == 27);
+ assert(f() == 40);
+}
+
+{
+ int f(int keyword x, int keyword y = 20)
+ {
+ return x+y;
+ }
+
+ assert(f(x=1,y=2) == 3);
+ assert(f(x=1) == 21);
+}
+
+{
+ int f(int keyword x = 10, int keyword y)
+ {
+ return x+y;
+ }
+
+ assert(f(x=1,y=2) == 3);
+ assert(f(y=2) == 12);
+}
+
+{
+ int f(int keyword x, int keyword y)
+ {
+ return x+y;
+ }
+
+ assert(f(x=1,y=2) == 3);
+}
+
+{
+ int f(int x, int keyword y)
+ {
+ return 2x+y;
+ }
+
+ assert(f(x=1,y=2) == 4);
+ assert(f(1,y=2) == 4);
+ assert(f(y=2,1) == 4);
+ assert(f(y=2,x=1) == 4);
+}
+
+{
+ int f(... int[] nums, int keyword r)
+ {
+ return r;
+ }
+
+ assert(f(r=3) == 3);
+ assert(f(1,r=3) == 3);
+ assert(f(1,2, r=3) == 3);
+ assert(f(1,2,4,5,6, r=3) == 3);
+ assert(f(r=3, 10, 20, 30) == 3);
+ assert(f(4, 5, r=3, 10, 20, 30) == 3);
+ assert(f(4, 5, r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(... new int[] {40,50,60}, r=3) == 3);
+ assert(f(... new int[] {40,50,60}, r=3) == 3);
+}
+
+{
+ int f(... int[] nums, int keyword r=77)
+ {
+ return r;
+ }
+
+ assert(f(r=3) == 3);
+ assert(f(1,r=3) == 3);
+ assert(f(1,2, r=3) == 3);
+ assert(f(1,2,4,5,6, r=3) == 3);
+ assert(f(r=3, 10, 20, 30) == 3);
+ assert(f(4, 5, r=3, 10, 20, 30) == 3);
+ assert(f(4, 5, r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(... new int[] {40,50,60}, r=3) == 3);
+ assert(f(... new int[] {40,50,60}, r=3) == 3);
+
+ assert(f() == 77);
+ assert(f(1) == 77);
+ assert(f(1,2) == 77);
+ assert(f(1,2,4,5,6) == 77);
+ assert(f(10, 20, 30) == 77);
+ assert(f(4, 5, 10, 20, 30) == 77);
+ assert(f(4, 5, 10, 20, 30 ... new int[] {40,50,60}) == 77);
+ assert(f(10, 20, 30 ... new int[] {40,50,60}) == 77);
+ assert(f(10, 20, 30 ... new int[] {40,50,60}) == 77);
+ assert(f(... new int[] {40,50,60}) == 77);
+ assert(f(... new int[] {40,50,60}) == 77);
+}
+
+{
+ int f(int x ... int[] nums, int keyword r=77)
+ {
+ return r;
+ }
+
+ assert(f(345,r=3) == 3);
+ assert(f(345,1,r=3) == 3);
+ assert(f(345,1,2, r=3) == 3);
+ assert(f(345,1,2,4,5,6, r=3) == 3);
+ assert(f(345,r=3, 10, 20, 30) == 3);
+ assert(f(345,4, 5, r=3, 10, 20, 30) == 3);
+ assert(f(345,4, 5, r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(345,r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(345,r=3, 10, 20, 30 ... new int[] {40,50,60}) == 3);
+ assert(f(345 ... new int[] {40,50,60}, r=3) == 3);
+ assert(f(345 ... new int[] {40,50,60}, r=3) == 3);
+
+ assert(f(345) == 77);
+ assert(f(345,1) == 77);
+ assert(f(345,1,2) == 77);
+ assert(f(345,1,2,4,5,6) == 77);
+ assert(f(345,10, 20, 30) == 77);
+ assert(f(345,4, 5, 10, 20, 30) == 77);
+ assert(f(345,4, 5, 10, 20, 30 ... new int[] {40,50,60}) == 77);
+ assert(f(345,10, 20, 30 ... new int[] {40,50,60}) == 77);
+ assert(f(345,10, 20, 30 ... new int[] {40,50,60}) == 77);
+ assert(f(345 ... new int[] {40,50,60}) == 77);
+ assert(f(345 ... new int[] {40,50,60}) == 77);
+}
+
+{
+ int sqr(int x=7) { return x*x; }
+ int f(int keyword x) = sqr;
+ int g(int keyword x=666) = sqr;
+ assert(f(x=5) == 25);
+ assert(g(x=5) == 25);
+ assert(g() == 49);
+}
+{
+ int sqr(int n=7) { return n*n; }
+ int f(int keyword x) = sqr;
+ int g(int keyword x=666) = sqr;
+ assert(f(x=5) == 25);
+ assert(g(x=5) == 25);
+ assert(g() == 49);
+}
+{
+ int sqr(int keyword x=7) { return x*x; }
+ int f(int x) = sqr;
+ int g(int x=666) = sqr;
+ assert(f(x=5) == 25);
+ assert(g(x=5) == 25);
+ assert(f(5) == 25);
+ assert(g(5) == 25);
+ assert(g() == 49);
+}
+{
+ int sqr(int keyword n=7) { return n*n; }
+ int f(int x) = sqr;
+ int g(int x=666) = sqr;
+ assert(f(x=5) == 25);
+ assert(g(x=5) == 25);
+ assert(f(5) == 25);
+ assert(g(5) == 25);
+ assert(g() == 49);
+}
+EndTest();
diff --git a/graphics/asymptote/tests/types/order.asy b/graphics/asymptote/tests/types/order.asy
new file mode 100644
index 0000000000..b2530b17ab
--- /dev/null
+++ b/graphics/asymptote/tests/types/order.asy
@@ -0,0 +1,165 @@
+import TestLib;
+StartTest("order");
+
+// Ordering tests.
+int counter = 0;
+int step(int n) { ++counter; assert(counter == n); return n; }
+int[] stepArray(int n) { return new int[] {step(n)}; }
+void reset() { counter = 0; }
+
+{
+ reset();
+ assert(step(1) + step(2) == step(3)); step(4);
+}
+
+{
+ reset();
+ assert(step(1) == 0 || step(2) == 2); step(3);
+}
+
+{
+ reset();
+ step(1) == 0 && step(999) == step(456); step(2);
+}
+
+{
+ reset();
+ int x = step(1), y = step(2); step(3);
+ int x = step(4), y = step(5); step(6);
+}
+
+{
+ void f(int x, int y) {}
+
+ reset();
+ f(step(1), step(2)); step(3);
+ reset();
+ f(x=step(1), y=step(2)); step(3);
+ reset();
+ f(y=step(1), x=step(2)); step(3);
+ reset();
+ f(x=step(1), step(2)); step(3);
+ reset();
+ f(y=step(1), step(2)); step(3);
+ reset();
+ f(step(1), x=step(2)); step(3);
+ reset();
+ f(step(1), y=step(2)); step(3);
+}
+
+{
+ void f(int x, int y ... int[] z) {}
+
+ reset();
+ f(step(1), step(2)); step(3);
+ reset();
+ f(x=step(1), y=step(2)); step(3);
+ reset();
+ f(y=step(1), x=step(2)); step(3);
+ reset();
+ f(x=step(1), step(2)); step(3);
+ reset();
+ f(y=step(1), step(2)); step(3);
+ reset();
+ f(step(1), x=step(2)); step(3);
+ reset();
+ f(step(1), y=step(2)); step(3);
+
+ reset();
+ f(step(1), step(2), step(3)); step(4);
+ reset();
+ f(x=step(1), y=step(2), step(3)); step(4);
+ reset();
+ f(y=step(1), x=step(2), step(3)); step(4);
+ reset();
+ f(x=step(1), step(2), step(3)); step(4);
+ reset();
+ f(y=step(1), step(2), step(3)); step(4);
+ reset();
+ f(step(1), x=step(2), step(3)); step(4);
+ reset();
+ f(step(1), y=step(2), step(3)); step(4);
+
+ reset();
+ f(step(1), step(2), step(3), step(4)); step(5);
+ reset();
+ f(x=step(1), y=step(2), step(3), step(4)); step(5);
+ reset();
+ f(y=step(1), x=step(2), step(3), step(4)); step(5);
+ reset();
+ f(x=step(1), step(2), step(3), step(4)); step(5);
+ reset();
+ f(y=step(1), step(2), step(3), step(4)); step(5);
+ reset();
+ f(step(1), x=step(2), step(3), step(4)); step(5);
+ reset();
+ f(step(1), y=step(2), step(3), step(4)); step(5);
+
+ reset();
+ f(step(1), step(2), step(3)); step(4);
+ reset();
+ f(x=step(1), step(2), y=step(3)); step(4);
+ reset();
+ f(y=step(1), step(2), x=step(3)); step(4);
+ reset();
+ f(x=step(1), step(2), step(3)); step(4);
+ reset();
+ f(y=step(1), step(2), step(3)); step(4);
+ reset();
+ f(step(1), step(2), x=step(3)); step(4);
+ reset();
+ f(step(1), step(2), y=step(3)); step(4);
+
+ reset();
+ f(step(1), step(2), step(3), step(4)); step(5);
+ reset();
+ f(x=step(1), step(2), y=step(3), step(4)); step(5);
+ reset();
+ f(y=step(1), step(2), x=step(3), step(4)); step(5);
+ reset();
+ f(x=step(1), step(2), step(3), step(4)); step(5);
+ reset();
+ f(y=step(1), step(2), step(3), step(4)); step(5);
+ reset();
+ f(step(1), step(2), x=step(3), step(4)); step(5);
+ reset();
+ f(step(1), step(2), y=step(3), step(4)); step(5);
+
+ reset();
+ f(step(1), step(2), step(3), step(4)... stepArray(5)); step(6);
+ reset();
+ f(x=step(1), step(2), y=step(3), step(4)... stepArray(5)); step(6);
+ reset();
+ f(y=step(1), step(2), x=step(3), step(4)... stepArray(5)); step(6);
+ reset();
+ f(x=step(1), step(2), step(3), step(4)... stepArray(5)); step(6);
+ reset();
+ f(y=step(1), step(2), step(3), step(4)... stepArray(5)); step(6);
+ reset();
+ f(step(1), step(2), x=step(3), step(4)... stepArray(5)); step(6);
+ reset();
+ f(step(1), step(2), y=step(3), step(4)... stepArray(5)); step(6);
+
+ reset();
+ f(...stepArray(1), x=step(2), y=step(3)); step(4);
+ reset();
+ f(...stepArray(1), y=step(2), x=step(3)); step(4);
+ reset();
+ f(step(1)...stepArray(2), x=step(3), y=step(4)); step(5);
+ reset();
+ f(step(1)...stepArray(2), y=step(3), x=step(4)); step(5);
+ reset();
+ f(step(1),step(2)...stepArray(3), y=step(4), x=step(5)); step(6);
+ reset();
+ f(step(1),step(2)...stepArray(3), y=step(4), x=step(5)); step(6);
+ reset();
+ f(step(1),step(2),x=step(3)...stepArray(4), y=step(5)); step(6);
+ reset();
+ f(step(1),step(2),x=step(3)...stepArray(4), y=step(5)); step(6);
+}
+
+
+
+// TODO: Add packing vs. casting tests.
+
+EndTest();
diff --git a/graphics/asymptote/tests/types/resolve.asy b/graphics/asymptote/tests/types/resolve.asy
new file mode 100644
index 0000000000..b668b15490
--- /dev/null
+++ b/graphics/asymptote/tests/types/resolve.asy
@@ -0,0 +1,157 @@
+import TestLib;
+StartTest("resolve");
+struct A {} struct B {} struct C {}
+
+int f(B, real) { return 1; }
+int f(C, int) { return 2; }
+B operator cast(A) { return new B; }
+
+assert(f(new A, 3) == 1);
+C operator cast(A) { return new C; }
+assert(f(new A, 3) == 2);
+
+int givex(int x, int y) { return x; }
+assert(givex(2002,3) == 2002);
+assert(givex(2002,2002) == 2002);
+assert(givex(-2005,2005) == -2005);
+assert(givex(x=-77,205) == -77);
+assert(givex(-77,y=205) == -77);
+assert(givex(-77,x=205) == 205);
+assert(givex(x=-77,y=205) == -77);
+assert(givex(y=-77,x=205) == 205);
+
+int g(real x, real y) { return 7; }
+int g(int x, real y) { return 8; }
+
+assert(g(4, 4) == 8);
+assert(g(4, 4.4) == 8);
+assert(g(4.4, 4) == 7);
+assert(g(4.4, 4.4) == 7);
+
+assert(g(x=4, y=4) == 8);
+assert(g(x=4, y=4.4) == 8);
+assert(g(x=4.4, y=4) == 7);
+assert(g(x=4.4, y=4.4) == 7);
+
+assert(g(x=4, 4) == 8);
+assert(g(x=4, 4.4) == 8);
+assert(g(x=4.4, 4) == 7);
+assert(g(x=4.4, 4.4) == 7);
+
+assert(g(4, y=4) == 8);
+assert(g(4, y=4.4) == 8);
+assert(g(4.4, y=4) == 7);
+assert(g(4.4, y=4.4) == 7);
+
+assert(g(y=4, x=4) == 8);
+assert(g(y=4, x=4.4) == 7);
+assert(g(y=4.4, x=4) == 8);
+assert(g(y=4.4, x=4.4) == 7);
+
+assert(g(4, x=4) == 8);
+assert(g(4, x=4.4) == 7);
+assert(g(4.4, x=4) == 8);
+assert(g(4.4, x=4.4) == 7);
+
+assert(g(y=4, 4) == 8);
+assert(g(y=4, 4.4) == 7);
+assert(g(y=4.4, 4) == 8);
+assert(g(y=4.4, 4.4) == 7);
+
+// Test exact matching over casting.
+{
+ void f(int x, real y=0.0, int z=0) {
+ assert(x==1);
+ assert(y==2.0);
+ assert(z==0);
+ }
+ f(1,2);
+}
+{
+ void f() {
+ assert(false);
+ }
+ void f(int x, real y=0.0, int z=0) {
+ assert(x==1);
+ assert(y==2.0);
+ assert(z==0);
+ }
+ f(1,2);
+}
+{
+ void f() {
+ assert(false);
+ }
+ void f(int x, int y) {
+ assert(x==1);
+ assert(y==2);
+ }
+ void f(int x, real y=0.0, int z=0) {
+ assert(false);
+ }
+ f(1,2);
+}
+{
+ struct A {}
+ struct B {}
+ struct C {}
+
+ void f(B);
+ void g(B);
+
+ // Should resolve to void (B).
+ assert(f == g);
+ assert(g == f);
+ assert(!(f != g));
+ assert(!(g != f));
+}
+{
+ struct A {}
+ struct B {}
+ struct C {}
+
+ void f(A), f(B);
+ void g(B), g(C);
+
+ // Should resolve to void (B).
+ assert(f == g);
+ assert(g == f);
+ assert(!(f != g));
+ assert(!(g != f));
+}
+{
+ struct A {}
+ struct B {}
+ struct C {}
+
+ void f(B);
+ void g(B), g(C);
+
+ // Should resolve to void (B).
+ assert(f == g);
+ assert(g == f);
+ assert(!(f != g));
+ assert(!(g != f));
+}
+{
+ struct A {}
+ struct B {}
+ struct C {}
+
+ void f(B);
+ void g(B), g(C);
+
+ // Should resolve to void (B).
+ assert(f == g);
+ assert(g == f);
+ assert(!(f != g));
+ assert(!(g != f));
+}
+{
+void foo() {}
+assert((foo == null ? 5 : 8) == 8);
+}
+
+// TODO: Add packing vs. casting tests.
+
+EndTest();
diff --git a/graphics/asymptote/tests/types/shadow.asy b/graphics/asymptote/tests/types/shadow.asy
new file mode 100644
index 0000000000..09d73abc02
--- /dev/null
+++ b/graphics/asymptote/tests/types/shadow.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("shadow");
+int x = 1;
+int getX() { return x; }
+void setX(int value) { x=value; }
+
+// Shadow x with another int, but x should still be in memory.
+int x = 2;
+assert(x==2);
+assert(getX()==1);
+x = 4;
+assert(x==4);
+assert(getX()==1);
+setX(7);
+assert(x==4);
+assert(getX()==7);
+EndTest();
diff --git a/graphics/asymptote/tests/types/spec.asy b/graphics/asymptote/tests/types/spec.asy
new file mode 100644
index 0000000000..9093644640
--- /dev/null
+++ b/graphics/asymptote/tests/types/spec.asy
@@ -0,0 +1,61 @@
+import TestLib;
+StartTest("spec");
+
+// Test if the cycle keyword can be used in different contexts.
+{
+ int operator cast(cycleToken) {
+ return 55;
+ }
+ int x=cycle;
+ assert(x==55);
+}
+
+// Test the tensionSpecifier type.
+{
+ tensionSpecifier operator ..(string a, tensionSpecifier t, string b) {
+ return t;
+ }
+ tensionSpecifier t="hello" .. tension 2 .. "joe";
+ assert(t.out==2);
+ assert(t.in==2);
+ assert(t.atLeast==false);
+
+ tensionSpecifier t="hello" .. tension 3 and 2 .. "joe";
+ assert(t.out==3);
+ assert(t.in==2);
+ assert(t.atLeast==false);
+
+ tensionSpecifier t="hello" .. tension atleast 7 .. "joe";
+ assert(t.out==7);
+ assert(t.in==7);
+ assert(t.atLeast==true);
+
+ tensionSpecifier t="hello" .. tension atleast 3 and 2 .. "joe";
+ assert(t.out==3);
+ assert(t.in==2);
+ assert(t.atLeast==true);
+}
+
+// Test the curlSpecifier type.
+{
+ curlSpecifier operator ..(curlSpecifier spec, string b) {
+ return spec;
+ }
+ curlSpecifier operator ..(string a, curlSpecifier spec) {
+ return spec;
+ }
+ curlSpecifier operator ..(string a, curlSpecifier spec, string b) {
+ return spec;
+ }
+
+ curlSpecifier spec="hello"{curl 3}.."joe";
+ assert(spec.value==3);
+ assert(spec.side==JOIN_OUT);
+
+ curlSpecifier spec="hello"..{curl 7}"joe";
+ assert(spec.value==7);
+ assert(spec.side==JOIN_IN);
+}
+
+EndTest();
+
diff --git a/graphics/asymptote/tests/types/var.asy b/graphics/asymptote/tests/types/var.asy
new file mode 100644
index 0000000000..a54500b7d0
--- /dev/null
+++ b/graphics/asymptote/tests/types/var.asy
@@ -0,0 +1,86 @@
+import TestLib;
+StartTest("var");
+var x = 4;
+assert(x + x == 8);
+assert(x^2 == 16);
+assert((real)x == 4.0);
+
+var y = x;
+assert(y + y == 8);
+assert(x + y == 8);
+assert(y^2 == 16);
+assert((real)y == 4.0);
+
+var z = 2 * x;
+assert(z + z == 16);
+assert(x + z == 12);
+assert(z^2 == 64);
+assert((real)z == 8.0);
+
+var t = sin(0);
+assert(t == 0.0);
+assert(2t == 0.0);
+
+struct A {
+ int x;
+};
+
+A a;
+a.x = 3;
+
+var b = a;
+assert(a == b);
+assert(a.x == 3);
+
+A func(int x, int y) { return a; }
+
+var c = func(2,3);
+assert(a == b);
+assert(a.x == 3);
+
+int f(int x) { return x*x; }
+var g = f;
+assert(g == f);
+for (int i = 0; i < 100; ++i)
+ assert(g(i) == i*i);
+
+/* var can be replaced with a normal type. */
+{
+ typedef int var;
+ var x;
+ assert(x == 0);
+
+ var v = 14;
+ assert(v == 14);
+}
+
+{
+ struct var {
+ int x;
+ }
+
+ var n = null;
+ assert(n == null);
+
+ var a;
+ assert(a != null);
+ assert(a.x == 0);
+ a.x = 11;
+ assert(a.x == 11);
+}
+
+// Test for single evaluation of the initializer.
+{
+ int x = 3;
+ assert(x == 3);
+ var y = ++x;
+ assert(x == 4);
+ assert(y == 4);
+}
+
+{
+ int f = 4, f() = null;
+ var x = (int)f;
+ assert(x == 4);
+}
+EndTest();
diff --git a/graphics/asymptote/texfile.cc b/graphics/asymptote/texfile.cc
new file mode 100644
index 0000000000..fc0e575c22
--- /dev/null
+++ b/graphics/asymptote/texfile.cc
@@ -0,0 +1,735 @@
+/*****
+ * texfile.cc
+ * John Bowman 2003/03/14
+ *
+ * Encapsulates the writing of commands to a TeX file.
+ *****/
+
+#include <ctime>
+#include <cfloat>
+
+#include "texfile.h"
+#include "errormsg.h"
+
+using std::ofstream;
+using settings::getSetting;
+using settings::ps2tex;
+using settings::tex2ps;
+using vm::array;
+using vm::read;
+
+namespace camp {
+
+texfile::texfile(const string& texname, const bbox& box, bool pipe)
+ : box(box)
+{
+ texengine=getSetting<string>("tex");
+ inlinetex=getSetting<bool>("inlinetex");
+ Hoffset=inlinetex ? box.right : box.left;
+ out=new ofstream(texname.c_str());
+ if(!out || !*out)
+ reportError("Cannot write to "+texname);
+ out->setf(std::ios::fixed);
+ out->precision(6);
+ texdocumentclass(*out,pipe);
+ resetpen();
+ level=0;
+}
+
+texfile::~texfile()
+{
+ if(out) {
+ delete out;
+ out=NULL;
+ }
+}
+
+void texfile::miniprologue()
+{
+ texpreamble(*out,processData().TeXpreamble,false);
+ if(settings::latex(texengine)) {
+ *out << "\\pagestyle{empty}" << newl
+ << "\\textheight=2048pt" << newl
+ << "\\textwidth=2048pt" << newl
+ << "\\begin{document}" << newl;
+ latexfontencoding(*out);
+ } else if(settings::context(texengine)) {
+ *out << "\\setuppagenumbering[location=]" << newl
+ << "\\usetypescript[modern]" << newl
+ << "\\starttext\\hbox{%" << newl;
+ } else *out << "\\nopagenumbers" << newl;
+}
+
+void texfile::prologue()
+{
+ if(inlinetex) {
+ string prename=buildname(settings::outname(),"pre");
+ std::ofstream *outpreamble=new std::ofstream(prename.c_str());
+ texpreamble(*outpreamble,processData().TeXpreamble,true,false);
+ outpreamble->close();
+ }
+
+ texdefines(*out,processData().TeXpreamble,false);
+ double width=box.right-box.left;
+ double height=box.top-box.bottom;
+ if(!inlinetex) {
+ if(settings::context(texengine)) {
+ *out << "\\definepapersize[asy][width=" << width << "bp,height="
+ << height << "bp]" << newl
+ << "\\setuppapersize[asy][asy]" << newl;
+ } else if(settings::pdf(texengine)) {
+ double voffset=0.0;
+ if(settings::latex(texengine)) {
+ if(height < 12.0) voffset=height-12.0;
+ } else if(height < 10.0) voffset=height-10.0;
+
+ if(width > 0)
+ *out << "\\pdfpagewidth=" << width << "bp" << newl;
+ *out << "\\ifx\\pdfhorigin\\undefined" << newl
+ << "\\hoffset=-1in" << newl
+ << "\\voffset=" << voffset-72.0 << "bp" << newl;
+ if(height > 0)
+ *out << "\\pdfpageheight=" << height << "bp"
+ << newl;
+ *out << "\\else" << newl
+ << "\\pdfhorigin=0bp" << newl
+ << "\\pdfvorigin=" << voffset << "bp" << newl;
+ if(height > 0)
+ *out << "\\pdfpageheight=" << height << "bp" << newl;
+ *out << "\\fi" << newl;
+ }
+ }
+
+ if(settings::xe(texengine) && !inlinetex)
+ *out << "\\usepackage{everypage}%" << newl;
+
+ if(settings::latex(texengine)) {
+ *out << "\\setlength{\\unitlength}{1pt}" << newl;
+ if(!inlinetex) {
+ *out << "\\pagestyle{empty}" << newl
+ << "\\textheight=" << height+18.0 << "bp" << newl
+ << "\\textwidth=" << width+18.0 << "bp" << newl;
+ if(settings::pdf(texengine))
+ *out << "\\oddsidemargin=-17.61pt" << newl
+ << "\\evensidemargin=\\oddsidemargin" << newl
+ << "\\topmargin=-37.01pt" << newl;
+ *out << "\\begin{document}" << newl;
+ }
+ latexfontencoding(*out);
+ } else {
+ if(!inlinetex) {
+ if(settings::context(texengine)) {
+ *out << "\\setuplayout["
+ << "backspace=0pt,topspace=0pt,"
+ << "header=0pt,headerdistance=0pt,footer=0pt]" << newl
+ << "\\setuppagenumbering[location=]" << endl
+ << "\\usetypescript[modern]" << newl
+ << "\\starttext\\hbox{%" << newl;
+ } else {
+ *out << "\\footline={}" << newl;
+ if(settings::pdf(texengine)) {
+ *out << "\\hoffset=-20pt" << newl
+ << "\\voffset=0pt" << newl;
+ } else {
+ *out << "\\hoffset=36.6pt" << newl
+ << "\\voffset=54.0pt" << newl;
+ }
+ }
+ }
+ }
+
+ beginpage();
+}
+
+void texfile::beginlayer(const string& psname, bool postscript)
+{
+ if(box.right > box.left && box.top > box.bottom) {
+ if(postscript) {
+ if(settings::context(texengine))
+ *out << "\\externalfigure[" << psname << "]%" << newl;
+ else {
+ *out << "{\\catcode`\"=12%" << newl
+ << "\\includegraphics";
+ bool pdf=settings::pdf(texengine);
+ string quote;
+ string name=stripExt(psname);
+ if(inlinetex) {
+ size_t pos=name.rfind("-");
+ if(pos < string::npos) name="\\ASYprefix\\jobname"+name.substr(pos);
+ } else {
+ if(!pdf) name=psname;
+ if(stripDir(name) != name)
+ quote="\"";
+ }
+
+ if(pdf) *out << "{" << quote << name << quote << ".pdf}%" << newl;
+ else {
+ *out << "[bb=" << box.left << " " << box.bottom << " "
+ << box.right << " " << box.top << "]"
+ << "{" << quote << name << quote << "}%" << newl;
+ }
+ *out << "}%" << newl;
+ }
+ if(!inlinetex)
+ *out << "\\kern " << (box.left-box.right)*ps2tex << "pt%" << newl;
+ } else {
+ *out << "\\leavevmode\\vbox to " << (box.top-box.bottom)*ps2tex
+ << "pt{}%" << newl;
+ if(inlinetex)
+ *out << "\\kern " << (box.right-box.left)*ps2tex << "pt%" << newl;
+ }
+ }
+}
+
+void texfile::endlayer()
+{
+ if(inlinetex && (box.right > box.left && box.top > box.bottom))
+ *out << "\\kern " << (box.left-box.right)*ps2tex << "pt%" << newl;
+}
+
+void texfile::writeshifted(path p, bool newPath)
+{
+ write(p.transformed(shift(pair(-Hoffset,-box.bottom))),newPath);
+}
+
+void texfile::setlatexcolor(pen p)
+{
+ if(p.cmyk() && (!lastpen.cmyk() ||
+ (p.cyan() != lastpen.cyan() ||
+ p.magenta() != lastpen.magenta() ||
+ p.yellow() != lastpen.yellow() ||
+ p.black() != lastpen.black()))) {
+ *out << "\\definecolor{ASYcolor}{cmyk}{"
+ << p.cyan() << "," << p.magenta() << "," << p.yellow() << ","
+ << p.black() << "}\\color{ASYcolor}" << newl;
+ } else if(p.rgb() && (!lastpen.rgb() ||
+ (p.red() != lastpen.red() ||
+ p.green() != lastpen.green() ||
+ p.blue() != lastpen.blue()))) {
+ *out << "\\definecolor{ASYcolor}{rgb}{"
+ << p.red() << "," << p.green() << "," << p.blue()
+ << "}\\color{ASYcolor}" << newl;
+ } else if(p.grayscale() && (!lastpen.grayscale() ||
+ p.gray() != lastpen.gray())) {
+ *out << "\\definecolor{ASYcolor}{gray}{"
+ << p.gray()
+ << "}\\color{ASYcolor}" << newl;
+ }
+}
+
+void texfile::setfont(pen p)
+{
+ bool latex=settings::latex(texengine);
+
+ if(latex) setlatexfont(*out,p,lastpen);
+ settexfont(*out,p,lastpen,latex);
+
+ lastpen.setfont(p);
+}
+
+void texfile::setpen(pen p)
+{
+ bool latex=settings::latex(texengine);
+
+ p.convert();
+ if(p == lastpen) return;
+
+ if(latex) setlatexcolor(p);
+ else setcolor(p,settings::beginspecial(texengine),settings::endspecial());
+
+ setfont(p);
+}
+
+void texfile::beginpicture(const bbox& b)
+{
+ verbatim(settings::beginpicture(texengine));
+ if(!settings::context(texengine)) {
+ verbatim("(");
+ double width=b.right-b.left;
+ double height=b.top-b.bottom;
+ write(width*ps2tex);
+ verbatim(",");
+ write(height*ps2tex);
+ verbatim(")");
+ }
+ verbatimline("%");
+}
+
+void texfile::endpicture(const bbox& b)
+{
+ verbatimline(settings::endpicture(texengine));
+ verbatim("\\kern");
+ double width=b.right-b.left;
+ write(-width*ps2tex);
+ verbatimline("pt%");
+}
+
+void texfile::gsave(bool)
+{
+ *out << settings::beginspecial(texengine);
+ psfile::gsave(true);
+ *out << settings::endspecial() << newl;
+}
+
+void texfile::grestore(bool)
+{
+ *out << settings::beginspecial(texengine);
+ psfile::grestore(true);
+ *out << settings::endspecial() << newl;
+}
+
+void texfile::beginspecial()
+{
+ *out << settings::beginspecial(texengine);
+}
+
+void texfile::endspecial()
+{
+ *out << settings::endspecial() << newl;
+}
+
+void texfile::beginraw()
+{
+ *out << "\\ASYraw{" << newl;
+}
+
+void texfile::endraw()
+{
+ *out << "}%" << newl;
+}
+
+void texfile::put(const string& label, const transform& T, const pair& z,
+ const pair& align)
+{
+ double sign=settings::pdf(texengine) ? 1.0 : -1.0;
+
+ if(label.empty()) return;
+
+ bool trans=!T.isIdentity();
+
+ *out << "\\ASYalign";
+ if(trans) *out << "T";
+ *out << "(" << (z.getx()-Hoffset)*ps2tex
+ << "," << (z.gety()-box.bottom)*ps2tex
+ << ")(" << align.getx()
+ << "," << align.gety()
+ << ")";
+ if(trans)
+ *out << "{" << T.getxx() << " " << sign*T.getyx()
+ << " " << sign*T.getxy() << " " << T.getyy() << "}";
+ *out << "{" << label << "}%" << newl;
+}
+
+void texfile::epilogue(bool pipe)
+{
+ endpage();
+ if(settings::latex(texengine))
+ *out << "\\end{document}" << newl;
+ else if(settings::context(texengine))
+ *out << "}\\stoptext" << newl;
+ else
+ *out << "\\bye" << newl;
+ out->flush();
+}
+
+string svgtexfile::nl="{?nl}%\n";
+
+void svgtexfile::beginspecial()
+{
+ inspecial=true;
+ out->unsetf(std::ios::fixed);
+ *out << "\\catcode`\\#=11%" << newl
+ << "\\special{dvisvgm:raw" << nl;
+}
+
+void svgtexfile::endspecial()
+{
+ inspecial=false;
+ *out << "}\\catcode`\\#=6%" << newl;
+ out->setf(std::ios::fixed);
+}
+
+void svgtexfile::begintransform()
+{
+ bbox b=box;
+ b.left=-Hoffset;
+ b=svgbbox(b);
+ *out << "<g transform='matrix(" << tex2ps << " 0 0 " << tex2ps <<" "
+ << b.left << " " << b.top << ")'>" << nl;
+}
+
+void svgtexfile::endtransform()
+{
+ *out << "</g>";
+}
+
+void svgtexfile::gsave(bool)
+{
+ if(clipstack.size() < 1)
+ clipstack.push(0);
+ else
+ clipstack.push(clipcount);
+ *out << "\\special{dvisvgm:raw <g>}%" << newl;
+ pens.push(lastpen);
+}
+
+void svgtexfile::grestore(bool)
+{
+ if(pens.size() < 1 || clipstack.size() < 1)
+ reportError("grestore without matching gsave");
+ lastpen=pens.top();
+ pens.pop();
+ clipstack.pop();
+ *out << "\\special{dvisvgm:raw </g>}%" << newl;
+}
+
+void svgtexfile::clippath()
+{
+ if(clipstack.size() > 0) {
+ size_t count=clipstack.top();
+ if(count > 0)
+ *out << "clip-path='url(#clip" << count << ")' ";
+ }
+}
+
+void svgtexfile::beginpath()
+{
+ *out << "<path ";
+ clippath();
+ *out << "d='";
+}
+
+void svgtexfile::endpath()
+{
+ *out << "/>" << nl;
+}
+
+void svgtexfile::dot(path p, pen q, bool newPath)
+{
+ beginspecial();
+ begintransform();
+ *out << "<circle ";
+ clippath();
+ pair z=p.point((Int) 0);
+ *out << "cx='" << z.getx()*ps2tex
+ << "' cy='" << -z.gety()*ps2tex
+ << "' r='" << 0.5*q.width()*ps2tex;
+}
+
+void svgtexfile::beginclip()
+{
+ beginspecial();
+ begintransform();
+ *out << "<clipPath ";
+ clippath();
+ ++clipcount;
+ *out << "id='clip" << clipcount << "'>" << nl;
+ beginpath();
+ if(clipstack.size() > 0)
+ clipstack.pop();
+ clipstack.push(clipcount);
+}
+
+void svgtexfile::endclip0(const pen &p)
+{
+ *out << "'";
+ fillrule(p,"clip");
+ endpath();
+ *out << "</clipPath>" << nl;
+}
+
+void svgtexfile::endclip(const pen &p)
+{
+ endclip0(p);
+ endtransform();
+ endspecial();
+}
+
+void svgtexfile::fillrule(const pen& p, const string& type)
+{
+ if(p.Fillrule() != lastpen.Fillrule())
+ *out << " " << type << "-rule='" <<
+ (p.evenodd() ? "evenodd" : "nonzero") << "'";
+ lastpen.setfillrule(p);
+}
+
+void svgtexfile::color(const pen &p, const string& type)
+{
+ *out << "' " << type << "='#" << rgbhex(p) << "'";
+ double opacity=p.opacity();
+ if(opacity != 1.0)
+ *out << " opacity='" << opacity << "'";
+}
+
+void svgtexfile::fill(const pen &p)
+{
+ color(p,"fill");
+ fillrule(p);
+ endpath();
+ endtransform();
+ endspecial();
+}
+
+void svgtexfile::properties(const pen& p)
+{
+ if(p.cap() != lastpen.cap())
+ *out << " stroke-linecap='" << PSCap[p.cap()] << "'";
+
+ if(p.join() != lastpen.join())
+ *out << " stroke-linejoin='" << Join[p.join()] << "'";
+
+ if(p.miter() != lastpen.miter())
+ *out << " stroke-miterlimit='" << p.miter()*ps2tex << "'";
+
+ if(p.width() != lastpen.width())
+ *out << " stroke-width='" << p.width()*ps2tex << "'";
+
+ const LineType *linetype=p.linetype();
+ const LineType *lastlinetype=lastpen.linetype();
+
+ if(!(linetype->pattern == lastlinetype->pattern)) {
+ size_t n=linetype->pattern.size();
+ if(n > 0) {
+ *out << " stroke-dasharray='";
+ *out << vm::read<double>(linetype->pattern,0)*ps2tex;
+ for(size_t i=1; i < n; ++i)
+ *out << "," << vm::read<double>(linetype->pattern,i)*ps2tex;
+ *out << "'";
+ }
+ }
+
+ if(linetype->offset != lastlinetype->offset)
+ *out << " stroke-dashoffset='" << linetype->offset*ps2tex << "'";
+
+ lastpen=p;
+}
+
+void svgtexfile::stroke(const pen &p, bool dot)
+{
+ if(dot)
+ color(p,"fill");
+ else {
+ color(p,"fill='none' stroke");
+ properties(p);
+ }
+ endpath();
+ endtransform();
+ endspecial();
+}
+
+void svgtexfile::strokepath()
+{
+ reportWarning("SVG does not support strokepath");
+}
+
+void svgtexfile::begingradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ const pen& penb, const pair& b, double rb)
+{
+ string type=axial ? "linear" : "radial";
+ beginspecial();
+ *out << "<" << type << "Gradient id='grad" << gradientcount;
+ if(axial) {
+ *out << "' x1='" << a.getx()*ps2tex << "' y1='" << -a.gety()*ps2tex
+ << "' x2='" << b.getx()*ps2tex << "' y2='" << -b.gety()*ps2tex;
+ } else {
+ *out << "' cx='" << b.getx()*ps2tex << "' cy='" << -b.gety()*ps2tex
+ << "' r='" << rb*ps2tex;
+ }
+ *out <<"' gradientUnits='userSpaceOnUse'>" << nl
+ << "<stop offset='0' stop-color='#" << rgbhex(pena) << "'/>" << nl
+ << "<stop offset='1' stop-color='#" << rgbhex(penb) << "'/>" << nl
+ << "</" << type << "Gradient>" << nl;
+ begintransform();
+ beginpath();
+}
+
+void svgtexfile::gradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ bool, const pen& penb, const pair& b,
+ double rb, bool)
+
+{
+ *out << "' fill='url(#grad" << gradientcount << ")'";
+ fillrule(pena);
+ endpath();
+ ++gradientcount;
+ endtransform();
+ endspecial();
+}
+
+// Return the point on the line through p and q that is closest to z.
+pair closest(pair p, pair q, pair z)
+{
+ pair u=q-p;
+ double denom=dot(u,u);
+ return denom == 0.0 ? p : p+dot(z-p,u)/denom*u;
+}
+
+void svgtexfile::gouraudshade(const pen& p0, const pair& z0,
+ const pen& p1, const pair& z1,
+ const pen& p2, const pair& z2)
+{
+ string hex[]={rgbhex(p0),rgbhex(p1),rgbhex(p2)};
+ pair Z[]={z0,z1,z2};
+
+ *out << "<defs>" << nl
+ << "<filter id='colorAdd'>" << nl
+ << "<feBlend in='SourceGraphic' in2='BackgroundImage'/>" << nl
+ << "</filter>";
+
+ for(size_t k=0; k < 3; ++k) {
+ pair z=Z[k];
+ pair opp=closest(Z[(k+1) % 3],Z[(k+2) % 3],z);
+ *out << "<linearGradient id='grad-" << gouraudcount << "-" << k
+ << "' gradientUnits='userSpaceOnUse'" << nl
+ << " x1='" << z.getx()*ps2tex << "' y1='" << -z.gety()*ps2tex
+ << "' x2='" << opp.getx()*ps2tex << "' y2='" << -opp.gety()*ps2tex
+ << "'>" << nl
+ << "<stop offset='0' stop-color='#" << hex[k]
+ << "' stop-opacity='1'/>" << nl
+ << "<stop offset='1' stop-color='#" << hex[k]
+ << "' stop-opacity='0'/>" << nl
+ << "</linearGradient>" << nl;
+ }
+ *out << "<polygon ";
+ clippath();
+ *out << "id='triangle" << gouraudcount << "' points='"
+ << z0.getx()*ps2tex << "," << -z0.gety()*ps2tex << " "
+ << z1.getx()*ps2tex << "," << -z1.gety()*ps2tex << " "
+ << z2.getx()*ps2tex << "," << -z2.gety()*ps2tex << "'/>" << nl
+ << "</defs>" << nl;
+ *out << "<use xlink:href='#triangle" << gouraudcount
+ << "' fill='url(#grad-" << gouraudcount << "-"
+ << "0)'/>" << nl
+ << "<use xlink:href='#triangle" << gouraudcount
+ << "' fill='url(#grad-" << gouraudcount << "-"
+ << "1)' filter='url(#colorAdd)'/>" << nl
+ << "<use xlink:href='#triangle" << gouraudcount
+ << "' fill='url(#grad-" << gouraudcount << "-"
+ << "2)' filter='url(#colorAdd)'/>" << nl;
+ ++gouraudcount;
+}
+
+void svgtexfile::begingouraudshade(const vm::array& pens,
+ const vm::array& vertices,
+ const vm::array& edges)
+{
+ size_t size=pens.size();
+ if(size == 0) return;
+ beginclip();
+}
+
+void svgtexfile::gouraudshade(const pen& pentype,
+ const array& pens, const array& vertices,
+ const array& edges)
+{
+ size_t size=pens.size();
+ if(size == 0) return;
+
+ endclip0(pentype);
+
+ pen *p0=NULL,*p1=NULL,*p2=NULL;
+ pair z0,z1,z2;
+
+ for(size_t i=0; i < size; i++) {
+ Int edge=read<Int>(edges,i);
+
+ switch(edge) {
+ case 0:
+ p0=read<pen *>(pens,i);
+ z0=read<pair>(vertices,i);
+ ++i;
+ if(i < size) {
+ p1=read<pen *>(pens,i);
+ z1=read<pair>(vertices,i);
+ ++i;
+ if(i < size) {
+ p2=read<pen *>(pens,i);
+ z2=read<pair>(vertices,i);
+ }
+ }
+ break;
+ case 1:
+ p0=read<pen *>(pens,i);
+ z0=read<pair>(vertices,i);
+ break;
+ case 2:
+ p1=read<pen *>(pens,i);
+ z1=read<pair>(vertices,i);
+ break;
+ default:
+ break;
+ }
+ if(p0 == NULL || p1 == NULL || p2 == NULL)
+ reportError("invalid edge flag");
+ gouraudshade(*p0,z0,*p1,z1,*p2,z2);
+ }
+ endtransform();
+ endspecial();
+}
+
+void svgtexfile::begintensorshade(const vm::array& pens,
+ const vm::array& boundaries,
+ const vm::array& z)
+{
+ beginspecial();
+ *out << "<defs>" << nl;
+
+ path g=read<path>(boundaries,0);
+ pair Z[]={g.point((Int) 0),g.point((Int) 3),g.point((Int) 2),
+ g.point((Int) 1)};
+
+ array *pi=read<array *>(pens,0);
+ if(checkArray(pi) != 4)
+ reportError("specify 4 pens for each path");
+ string hex[]={rgbhex(read<pen>(pi,0)),rgbhex(read<pen>(pi,3)),
+ rgbhex(read<pen>(pi,2)),rgbhex(read<pen>(pi,1))};
+
+ *out << "<filter id='colorAdd'>" << nl
+ << "<feBlend in='SourceGraphic' in2='BackgroundImage'/>" << nl
+ << "</filter>";
+
+ pair mean=0.25*(Z[0]+Z[1]+Z[2]+Z[3]);
+ for(size_t k=0; k < 4; ++k) {
+ pair opp=(k % 2 == 0) ? Z[(k+2) % 4] : mean;
+ *out << "<linearGradient id='grad" << tensorcount << "-" << k
+ << "' gradientUnits='userSpaceOnUse'" << nl
+ << " x1='" << Z[k].getx()*ps2tex << "' y1='" << -Z[k].gety()*ps2tex
+ << "' x2='" << opp.getx()*ps2tex << "' y2='" << -opp.gety()*ps2tex
+ << "'>" << nl
+ << "<stop offset='0' stop-color='#" << hex[k]
+ << "' stop-opacity='1'/>" << nl
+ << "<stop offset='1' stop-color='#" << hex[k]
+ << "' stop-opacity='0'/>" << nl
+ << "</linearGradient>" << nl;
+ }
+ beginpath();
+}
+
+void svgtexfile::tensorshade(const pen& pentype, const vm::array& pens,
+ const vm::array& boundaries, const vm::array& z)
+{
+ *out << "' id='path" << tensorcount << "'";
+ fillrule(pentype);
+ endpath();
+ *out << "</defs></g>" << nl;
+ begintransform();
+ *out << "<use xlink:href='#path" << tensorcount
+ << "' fill='url(#grad" << tensorcount << "-"
+ << "0)'/>" << nl
+ << "<use xlink:href='#path" << tensorcount
+ << "' fill='url(#grad" << tensorcount << "-"
+ << "2)' filter='url(#colorAdd)'/>" << nl
+ << "<use xlink:href='#path" << tensorcount
+ << "' fill='url(#grad" << tensorcount << "-"
+ << "1)' filter='url(#colorAdd)'/>" << nl
+ << "<use xlink:href='#path" << tensorcount
+ << "' fill='url(#grad" << tensorcount << "-"
+ << "3)' filter='url(#colorAdd)'/>" << nl;
+
+ ++tensorcount;
+ endspecial();
+}
+
+} //namespace camp
diff --git a/graphics/asymptote/texfile.h b/graphics/asymptote/texfile.h
new file mode 100644
index 0000000000..2f07a2759a
--- /dev/null
+++ b/graphics/asymptote/texfile.h
@@ -0,0 +1,383 @@
+/*****
+ * texfile.h
+ * John Bowman 2003/03/14
+ *
+ * Encapsulates the writing of commands to a TeX file.
+ *****/
+
+#ifndef TEXFILE_H
+#define TEXFILE_H
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+#include "common.h"
+#include "pair.h"
+#include "bbox.h"
+#include "pen.h"
+#include "util.h"
+#include "interact.h"
+#include "path.h"
+#include "array.h"
+#include "psfile.h"
+#include "settings.h"
+#include "process.h"
+
+namespace camp {
+
+template<class T>
+void texdocumentclass(T& out, bool pipe=false)
+{
+ if(settings::latex(settings::getSetting<string>("tex")) &&
+ (pipe || !settings::getSetting<bool>("inlinetex")))
+ out << "\\documentclass[12pt]{article}" << newl;
+}
+
+template<class T>
+void texuserpreamble(T& out,
+ mem::list<string>& preamble=processData().TeXpreamble)
+{
+ for(mem::list<string>::iterator p=preamble.begin();
+ p != preamble.end(); ++p)
+ out << stripblanklines(*p);
+}
+
+template<class T>
+void latexfontencoding(T& out)
+{
+ out << "\\makeatletter%" << newl
+ << "\\let\\ASYencoding\\f@encoding%" << newl
+ << "\\let\\ASYfamily\\f@family%" << newl
+ << "\\let\\ASYseries\\f@series%" << newl
+ << "\\let\\ASYshape\\f@shape%" << newl
+ << "\\makeatother%" << newl;
+}
+
+template<class T>
+void texpreamble(T& out, mem::list<string>& preamble=processData().TeXpreamble,
+ bool ASYalign=true, bool ASYbox=true)
+{
+ texuserpreamble(out,preamble);
+ string texengine=settings::getSetting<string>("tex");
+ if(settings::context(texengine))
+ out << "\\disabledirectives[system.errorcontext]%" << newl;
+ if(ASYbox)
+ out << "\\newbox\\ASYbox" << newl
+ << "\\newdimen\\ASYdimen" << newl;
+ out << "\\def\\ASYprefix{" << stripFile(settings::outname()) << "}" << newl
+ << "\\long\\def\\ASYbase#1#2{\\leavevmode\\setbox\\ASYbox=\\hbox{#1}%"
+ << "\\ASYdimen=\\ht\\ASYbox%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#2}\\lower\\ASYdimen\\box\\ASYbox}" << newl;
+ if(ASYalign)
+ out << "\\long\\def\\ASYaligned(#1,#2)(#3,#4)#5#6#7{\\leavevmode%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#7}%" << newl
+ << "\\setbox\\ASYbox\\hbox{\\ASYdimen=\\ht\\ASYbox%" << newl
+ << "\\advance\\ASYdimen by\\dp\\ASYbox\\kern#3\\wd\\ASYbox"
+ << "\\raise#4\\ASYdimen\\box\\ASYbox}%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#5\\wd\\ASYbox 0pt\\dp\\ASYbox 0pt\\ht\\ASYbox 0pt\\box\\ASYbox#6}%" << newl
+ << "\\hbox to 0pt{\\kern#1pt\\raise#2pt\\box\\ASYbox\\hss}}%" << newl
+ << "\\long\\def\\ASYalignT(#1,#2)(#3,#4)#5#6{%" << newl
+ << "\\ASYaligned(#1,#2)(#3,#4){%" << newl
+ << settings::beginlabel(texengine) << "%" << newl
+ << "}{%" << newl
+ << settings::endlabel(texengine) << "%" << newl
+ << "}{#6}}" << newl
+ << "\\long\\def\\ASYalign(#1,#2)(#3,#4)#5{"
+ << "\\ASYaligned(#1,#2)(#3,#4){}{}{#5}}" << newl
+ << settings::rawpostscript(texengine) << newl;
+}
+
+// Work around bug in dvips.def: allow spaces in file names.
+template<class T>
+void dvipsfix(T &out)
+{
+ if(!settings::pdf(settings::getSetting<string>("tex"))) {
+ out << "\\makeatletter" << newl
+ << "\\def\\Ginclude@eps#1{%" << newl
+ << " \\message{<#1>}%" << newl
+ << " \\bgroup" << newl
+ << " \\def\\@tempa{!}%" << newl
+ << " \\dimen@\\Gin@req@width" << newl
+ << " \\dimen@ii.1bp%" << newl
+ << " \\divide\\dimen@\\dimen@ii" << newl
+ << " \\@tempdima\\Gin@req@height" << newl
+ << " \\divide\\@tempdima\\dimen@ii" << newl
+ << " \\special{PSfile=#1\\space" << newl
+ << " llx=\\Gin@llx\\space" << newl
+ << " lly=\\Gin@lly\\space" << newl
+ << " urx=\\Gin@urx\\space" << newl
+ << " ury=\\Gin@ury\\space" << newl
+ << " \\ifx\\Gin@scalex\\@tempa\\else rwi=\\number\\dimen@\\space\\fi" << newl
+ << " \\ifx\\Gin@scaley\\@tempa\\else rhi=\\number\\@tempdima\\space\\fi" << newl
+ << " \\ifGin@clip clip\\fi}%" << newl
+ << " \\egroup}" << newl
+ << "\\makeatother" << newl;
+ }
+}
+
+template<class T>
+void texdefines(T& out, mem::list<string>& preamble=processData().TeXpreamble,
+ bool pipe=false)
+{
+ if(pipe || !settings::getSetting<bool>("inlinetex"))
+ texpreamble(out,preamble,!pipe);
+
+ if(pipe) {
+ // Make tex pipe aware of a previously generated aux file.
+ string name=auxname(settings::outname(),"aux");
+ std::ifstream fin(name.c_str());
+ if(fin) {
+ std::ofstream fout("texput.aux");
+ string s;
+ while(getline(fin,s))
+ fout << s << endl;
+ }
+ }
+ string texengine=settings::getSetting<string>("tex");
+ if(settings::latex(texengine)) {
+ if(pipe || !settings::getSetting<bool>("inlinetex")) {
+ out << "\\usepackage{graphicx}" << newl;
+ if(!pipe) {
+ dvipsfix(out);
+ out << "\\usepackage{color}" << newl;
+ }
+ }
+ if(pipe) {
+ out << "\\begin{document}" << newl;
+ latexfontencoding(out);
+ }
+ } else if(!settings::context(texengine)) {
+ out << "\\input graphicx" << newl // Fix miniltx path parsing bug:
+ << "\\makeatletter" << newl
+ << "\\def\\filename@parse#1{%" << newl
+ << " \\let\\filename@area\\@empty" << newl
+ << " \\expandafter\\filename@path#1/\\\\}" << newl
+ << "\\def\\filename@path#1/#2\\\\{%" << newl
+ << " \\ifx\\\\#2\\\\%" << newl
+ << " \\def\\reserved@a{\\filename@simple#1.\\\\}%" << newl
+ << " \\else" << newl
+ << " \\edef\\filename@area{\\filename@area#1/}%" << newl
+ << " \\def\\reserved@a{\\filename@path#2\\\\}%" << newl
+ << " \\fi" << newl
+ << " \\reserved@a}" << newl
+ << "\\makeatother" << newl;
+ dvipsfix(out);
+
+ if(!pipe)
+ out << "\\input picture" << newl;
+ }
+}
+
+template<class T>
+bool setlatexfont(T& out, const pen& p, const pen& lastpen)
+{
+ if(p.size() != lastpen.size() || p.Lineskip() != lastpen.Lineskip()) {
+ out << "\\fontsize{" << p.size()*settings::ps2tex << "}{"
+ << p.Lineskip()*settings::ps2tex << "}\\selectfont\n";
+ return true;
+ }
+ return false;
+}
+
+template<class T>
+bool settexfont(T& out, const pen& p, const pen& lastpen, bool latex)
+{
+ string font=p.Font();
+ if(font != lastpen.Font() || (!latex && p.size() != lastpen.size())) {
+ out << font << "%" << newl;
+ return true;
+ }
+ return false;
+}
+
+class texfile : public psfile {
+protected:
+ bbox box;
+ bool inlinetex;
+ double Hoffset;
+ int level;
+
+public:
+ string texengine;
+
+ texfile(const string& texname, const bbox& box, bool pipe=false);
+ virtual ~texfile();
+
+ void prologue();
+ virtual void beginpage() {}
+
+ void epilogue(bool pipe=false);
+ virtual void endpage() {}
+
+ void setlatexcolor(pen p);
+ void setpen(pen p);
+
+ void setfont(pen p);
+
+ void gsave(bool tex=true);
+
+ void grestore(bool tex=true);
+
+ void beginspecial();
+
+ void endspecial();
+
+ void beginraw();
+
+ void endraw();
+
+ void begingroup() {++level;}
+
+ void endgroup() {--level;}
+
+ bool toplevel() {return level == 0;}
+
+ void beginpicture(const bbox& b);
+ void endpicture(const bbox& b);
+
+ void writepair(pair z) {
+ *out << z;
+ }
+
+ void miniprologue();
+
+ void writeshifted(path p, bool newPath=true);
+ double hoffset() {return Hoffset;}
+
+ // Draws label transformed by T at position z.
+ void put(const string& label, const transform& T, const pair& z,
+ const pair& Align);
+
+ void beginlayer(const string& psname, bool postscript);
+ void endlayer();
+};
+
+class svgtexfile : public texfile {
+ mem::stack<size_t> clipstack;
+ size_t clipcount;
+ size_t gradientcount;
+ size_t gouraudcount;
+ size_t tensorcount;
+ bool inspecial;
+ static string nl;
+public:
+ svgtexfile(const string& texname, const bbox& box, bool pipe=false) :
+ texfile(texname,box,pipe) {
+ clipcount=0;
+ gradientcount=0;
+ gouraudcount=0;
+ tensorcount=0;
+ inspecial=false;
+ }
+
+ void writeclip(path p, bool newPath=true) {
+ write(p,false);
+ }
+
+ void dot(path p, pen, bool newPath=true);
+
+ void writeshifted(pair z) {
+ write(conj(z)*settings::ps2tex);
+ }
+
+ void translate(pair z) {}
+ void concat(transform t) {}
+
+ void beginspecial();
+ void endspecial();
+
+ // Prevent unwanted page breaks.
+ void beginpage() {
+ beginpicture(box);
+ }
+
+ void endpage() {
+ endpicture(box);
+ }
+
+ void begintransform();
+ void endtransform();
+
+ void clippath();
+
+ void beginpath();
+ void endpath();
+
+ void newpath() {
+ beginspecial();
+ begintransform();
+ beginpath();
+ }
+
+ void moveto(pair z) {
+ *out << "M";
+ writeshifted(z);
+ }
+
+ void lineto(pair z) {
+ *out << "L";
+ writeshifted(z);
+ }
+
+ void curveto(pair zp, pair zm, pair z1) {
+ *out << "C";
+ writeshifted(zp); writeshifted(zm); writeshifted(z1);
+ }
+
+ void closepath() {
+ *out << "Z";
+ }
+
+ string rgbhex(pen p) {
+ p.torgb();
+ return p.hex();
+ }
+
+ void properties(const pen& p);
+ void color(const pen &p, const string& type);
+
+ void stroke(const pen &p, bool dot=false);
+ void strokepath();
+
+ void fillrule(const pen& p, const string& type="fill");
+ void fill(const pen &p);
+
+ void begingradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ const pen& penb, const pair& b, double rb);
+ void gradientshade(bool axial, ColorSpace colorspace,
+ const pen& pena, const pair& a, double ra,
+ bool extenda, const pen& penb, const pair& b,
+ double rb, bool extendb);
+
+ void gouraudshade(const pen& p0, const pair& z0,
+ const pen& p1, const pair& z1,
+ const pen& p2, const pair& z2);
+ void begingouraudshade(const vm::array& pens, const vm::array& vertices,
+ const vm::array& edges);
+ void gouraudshade(const pen& pentype, const vm::array& pens,
+ const vm::array& vertices, const vm::array& edges);
+
+ void begintensorshade(const vm::array& pens,
+ const vm::array& boundaries,
+ const vm::array& z);
+ void tensorshade(const pen& pentype, const vm::array& pens,
+ const vm::array& boundaries, const vm::array& z);
+
+ void beginclip();
+
+ void endclip0(const pen &p);
+ void endclip(const pen &p);
+ void endpsclip(const pen &p) {}
+
+ void setpen(pen p) {if(!inspecial) texfile::setpen(p);}
+
+ void gsave(bool tex=false);
+
+ void grestore(bool tex=false);
+};
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/tr.cc b/graphics/asymptote/tr.cc
new file mode 100644
index 0000000000..c62301cc43
--- /dev/null
+++ b/graphics/asymptote/tr.cc
@@ -0,0 +1,438 @@
+/* This file is released under version 2 of the GNU Library General Public
+ * License (see the files LICENSE.LIBRARY and LICENSE).
+ */
+
+/* $Id: tr.c,v 1.9 1998/01/29 16:56:54 brianp Exp $ */
+
+/*
+ * $Log: tr.c,v $
+ * Revision 1.9 1998/01/29 16:56:54 brianp
+ * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
+ *
+ * Revision 1.8 1998/01/28 19:47:39 brianp
+ * minor clean-up for C++
+ *
+ * Revision 1.7 1997/07/21 17:34:38 brianp
+ * added tile borders
+ *
+ * Revision 1.6 1997/07/21 15:47:35 brianp
+ * renamed all "near" and "far" variables
+ *
+ * Revision 1.5 1997/04/26 21:23:25 brianp
+ * added trRasterPos3f function
+ *
+ * Revision 1.4 1997/04/26 19:59:36 brianp
+ * set CurrentTile to -1 before first tile and after last tile
+ *
+ * Revision 1.3 1997/04/22 23:51:15 brianp
+ * added WIN32 header stuff, removed tabs
+ *
+ * Revision 1.2 1997/04/19 23:26:10 brianp
+ * many API changes
+ *
+ * Revision 1.1 1997/04/18 21:53:05 brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Tiled Rendering library
+ * Version 1.1
+ * Copyright (C) Brian Paul
+ */
+
+#include "common.h"
+
+#ifdef HAVE_GL
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+#include "tr.h"
+
+#define DEFAULT_TILE_WIDTH 256
+#define DEFAULT_TILE_HEIGHT 256
+#define DEFAULT_TILE_BORDER 0
+
+namespace gl {
+void frustum(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble nearVal, GLdouble farVal);
+void ortho(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble nearVal, GLdouble farVal);
+}
+
+using gl::frustum;
+using gl::ortho;
+
+struct _TRctx {
+ /* Final image parameters */
+ GLint ImageWidth, ImageHeight;
+ GLenum ImageFormat, ImageType;
+ GLvoid *ImageBuffer;
+
+ /* Tile parameters */
+ GLint TileWidth, TileHeight;
+ GLint TileWidthNB, TileHeightNB;
+ GLint TileBorder;
+ GLenum TileFormat, TileType;
+ GLvoid *TileBuffer;
+
+ /* Projection parameters */
+ GLboolean Perspective;
+ GLdouble Left;
+ GLdouble Right;
+ GLdouble Bottom;
+ GLdouble Top;
+ GLdouble Near;
+ GLdouble Far;
+
+ /* Misc */
+ TRenum RowOrder;
+ GLint Rows, Columns;
+ GLint CurrentTile;
+ GLint CurrentTileWidth, CurrentTileHeight;
+ GLint CurrentRow, CurrentColumn;
+
+ GLint ViewportSave[4];
+};
+
+
+
+/*
+ * Misc setup including computing number of tiles (rows and columns).
+ */
+static void Setup(TRcontext *tr)
+{
+ if (!tr)
+ return;
+
+ tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
+ tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
+ tr->CurrentTile = 0;
+
+ assert(tr->Columns >= 0);
+ assert(tr->Rows >= 0);
+}
+
+
+
+TRcontext *trNew(void)
+{
+ TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
+ if (tr) {
+ tr->TileWidth = DEFAULT_TILE_WIDTH;
+ tr->TileHeight = DEFAULT_TILE_HEIGHT;
+ tr->TileBorder = DEFAULT_TILE_BORDER;
+ tr->RowOrder = TR_BOTTOM_TO_TOP;
+ tr->CurrentTile = -1;
+ }
+ return (TRcontext *) tr;
+}
+
+
+void trDelete(TRcontext *tr)
+{
+ if (tr)
+ free(tr);
+}
+
+
+
+void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
+{
+ if (!tr)
+ return;
+
+ assert(border >= 0);
+ assert(width >= 1);
+ assert(height >= 1);
+ assert(width >= 2*border);
+ assert(height >= 2*border);
+
+ tr->TileBorder = border;
+ tr->TileWidth = width;
+ tr->TileHeight = height;
+ tr->TileWidthNB = width - 2 * border;
+ tr->TileHeightNB = height - 2 * border;
+ Setup(tr);
+}
+
+
+
+void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
+{
+ if (!tr)
+ return;
+
+ tr->TileFormat = format;
+ tr->TileType = type;
+ tr->TileBuffer = image;
+}
+
+
+
+void trImageSize(TRcontext *tr, GLint width, GLint height)
+{
+ if (!tr)
+ return;
+
+ tr->ImageWidth = width;
+ tr->ImageHeight = height;
+ Setup(tr);
+}
+
+
+void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
+{
+ if (!tr)
+ return;
+
+ tr->ImageFormat = format;
+ tr->ImageType = type;
+ tr->ImageBuffer = image;
+}
+
+
+GLint trGet(TRcontext *tr, TRenum param)
+{
+ if (!tr)
+ return 0;
+
+ switch (param) {
+ case TR_TILE_WIDTH:
+ return tr->TileWidth;
+ case TR_TILE_HEIGHT:
+ return tr->TileHeight;
+ case TR_TILE_BORDER:
+ return tr->TileBorder;
+ case TR_IMAGE_WIDTH:
+ return tr->ImageWidth;
+ case TR_IMAGE_HEIGHT:
+ return tr->ImageHeight;
+ case TR_ROWS:
+ return tr->Rows;
+ case TR_COLUMNS:
+ return tr->Columns;
+ case TR_CURRENT_ROW:
+ if (tr->CurrentTile<0)
+ return -1;
+ else
+ return tr->CurrentRow;
+ case TR_CURRENT_COLUMN:
+ if (tr->CurrentTile<0)
+ return -1;
+ else
+ return tr->CurrentColumn;
+ case TR_CURRENT_TILE_WIDTH:
+ return tr->CurrentTileWidth;
+ case TR_CURRENT_TILE_HEIGHT:
+ return tr->CurrentTileHeight;
+ case TR_ROW_ORDER:
+ return (GLint) tr->RowOrder;
+ default:
+ return 0;
+ }
+}
+
+
+void trRowOrder(TRcontext *tr, TRenum order)
+{
+ if (!tr)
+ return;
+
+ if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
+ tr->RowOrder = order;
+}
+
+
+void trOrtho(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar)
+{
+ if (!tr)
+ return;
+
+ tr->Perspective = GL_FALSE;
+ tr->Left = left;
+ tr->Right = right;
+ tr->Bottom = bottom;
+ tr->Top = top;
+ tr->Near = zNear;
+ tr->Far = zFar;
+}
+
+
+void trFrustum(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar)
+{
+ if (!tr)
+ return;
+
+ tr->Perspective = GL_TRUE;
+ tr->Left = left;
+ tr->Right = right;
+ tr->Bottom = bottom;
+ tr->Top = top;
+ tr->Near = zNear;
+ tr->Far = zFar;
+}
+
+
+void trPerspective(TRcontext *tr,
+ GLdouble fovy, GLdouble aspect,
+ GLdouble zNear, GLdouble zFar )
+{
+ GLdouble xmin, xmax, ymin, ymax;
+ static const double halfradians=acos(-1.0)/360.0;
+ ymax = zNear * tan(fovy * halfradians);
+ ymin = -ymax;
+ xmin = ymin * aspect;
+ xmax = ymax * aspect;
+ trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
+}
+
+
+void trBeginTile(TRcontext *tr)
+{
+ GLint tileWidth, tileHeight, border;
+ GLdouble left, right, bottom, top;
+
+ if (!tr)
+ return;
+
+ if (tr->CurrentTile <= 0) {
+ Setup(tr);
+ /* Save user's viewport, will be restored after last tile rendered */
+ glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
+ }
+
+ /* which tile (by row and column) we're about to render */
+ if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
+ tr->CurrentRow = tr->CurrentTile / tr->Columns;
+ tr->CurrentColumn = tr->CurrentTile % tr->Columns;
+ }
+ else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
+ tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
+ tr->CurrentColumn = tr->CurrentTile % tr->Columns;
+ }
+ else {
+ /* This should never happen */
+ abort();
+ }
+ assert(tr->CurrentRow < tr->Rows);
+ assert(tr->CurrentColumn < tr->Columns);
+
+ border = tr->TileBorder;
+
+ /* Compute actual size of this tile with border */
+ if (tr->CurrentRow < tr->Rows-1)
+ tileHeight = tr->TileHeight;
+ else
+ tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
+
+ if (tr->CurrentColumn < tr->Columns-1)
+ tileWidth = tr->TileWidth;
+ else
+ tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
+
+ /* Save tile size, with border */
+ tr->CurrentTileWidth = tileWidth;
+ tr->CurrentTileHeight = tileHeight;
+
+ glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */
+
+ /* compute projection parameters */
+ left = tr->Left + (tr->Right - tr->Left)
+ * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
+ right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
+ bottom = tr->Bottom + (tr->Top - tr->Bottom)
+ * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
+ top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
+
+ if (tr->Perspective)
+ frustum(left, right, bottom, top, tr->Near, tr->Far);
+ else
+ ortho(left, right, bottom, top, tr->Near, tr->Far);
+}
+
+
+
+int trEndTile(TRcontext *tr)
+{
+ GLint prevRowLength, prevSkipRows, prevSkipPixels;
+
+ if (!tr)
+ return 0;
+
+ assert(tr->CurrentTile>=0);
+
+ /* be sure OpenGL rendering is finished */
+ glFlush();
+
+ /* save current glPixelStore values */
+ glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
+ glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
+ glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
+ /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
+
+ if (tr->TileBuffer) {
+ GLint srcX = tr->TileBorder;
+ GLint srcY = tr->TileBorder;
+ GLint srcWidth = tr->TileWidthNB;
+ GLint srcHeight = tr->TileHeightNB;
+ glReadPixels(srcX, srcY, srcWidth, srcHeight,
+ tr->TileFormat, tr->TileType, tr->TileBuffer);
+ }
+
+ if (tr->ImageBuffer) {
+ GLint srcX = tr->TileBorder;
+ GLint srcY = tr->TileBorder;
+ GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
+ GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
+ GLint destX = tr->TileWidthNB * tr->CurrentColumn;
+ GLint destY = tr->TileHeightNB * tr->CurrentRow;
+
+ /* setup pixel store for glReadPixels */
+ glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
+ glPixelStorei(GL_PACK_SKIP_ROWS, destY);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
+ /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
+
+ /* read the tile into the final image */
+ glReadPixels(srcX, srcY, srcWidth, srcHeight,
+ tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
+ }
+
+ /* restore previous glPixelStore values */
+ glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
+ glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
+ /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
+
+ /* increment tile counter, return 1 if more tiles left to render */
+ tr->CurrentTile++;
+ if (tr->CurrentTile >= tr->Rows * tr->Columns) {
+ /* restore user's viewport */
+ glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
+ tr->ViewportSave[2], tr->ViewportSave[3]);
+ tr->CurrentTile = -1; /* all done */
+ return 0;
+ }
+ else
+ return 1;
+}
+
+#endif
diff --git a/graphics/asymptote/tr.h b/graphics/asymptote/tr.h
new file mode 100644
index 0000000000..72d1bef0e0
--- /dev/null
+++ b/graphics/asymptote/tr.h
@@ -0,0 +1,167 @@
+/* This file is released under version 2 of the GNU Library General Public
+ * License (see the files LICENSE.LIBRARY and LICENSE).
+ */
+
+/* $Id: tr.h,v 1.5 1997/07/21 17:34:07 brianp Exp $ */
+
+/*
+ * $Log: tr.h,v $
+ * Revision 1.5 1997/07/21 17:34:07 brianp
+ * added tile borders, incremented version to 1.1
+ *
+ * Revision 1.4 1997/07/21 15:47:35 brianp
+ * renamed all "near" and "far" variables
+ *
+ * Revision 1.3 1997/04/26 21:23:25 brianp
+ * added trRasterPos3f function
+ *
+ * Revision 1.2 1997/04/19 23:26:10 brianp
+ * many API changes
+ *
+ * Revision 1.1 1997/04/18 21:53:05 brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Tiled Rendering library
+ * Version 1.1
+ * Copyright (C) Brian Paul
+ *
+ *
+ * This library allows one to render arbitrarily large images with OpenGL.
+ * The basic idea is to break the image into tiles which are rendered one
+ * at a time. The tiles are assembled together to form the final, large
+ * image. Tiles and images can be of any size.
+ *
+ * Basic usage:
+ *
+ * 1. Allocate a tile rendering context:
+ * TRcontext t = trNew();
+ *
+ * 2. Specify the final image buffer and tile size:
+ * GLubyte image[W][H][4]
+ * trImageSize(t, W, H);
+ * trImageBuffer(t, GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte *) image);
+ *
+ * 3. Setup your projection:
+ * trFrustum(t, left, right, bottom top, near, far);
+ * or
+ * trOrtho(t, left, right, bottom top, near, far);
+ * or
+ * trPerspective(t, fovy, aspect, near, far);
+ *
+ * 4. Render the tiles:
+ * do {
+ * trBeginTile(t);
+ * DrawMyScene();
+ * } while (trEndTile(t));
+ *
+ * You provide the DrawMyScene() function which calls glClear() and
+ * draws all your stuff.
+ *
+ * 5. The image array is now complete. Display it, write it to a file, etc.
+ *
+ * 6. Delete the tile rendering context when finished:
+ * trDelete(t);
+ *
+ */
+
+
+#ifndef TR_H
+#define TR_H
+
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define TR_VERSION "1.1"
+#define TR_MAJOR_VERSION 1
+#define TR_MINOR_VERSION 1
+
+
+typedef struct _TRctx TRcontext;
+
+
+typedef enum {
+ TR_TILE_WIDTH = 100,
+ TR_TILE_HEIGHT,
+ TR_TILE_BORDER,
+ TR_IMAGE_WIDTH,
+ TR_IMAGE_HEIGHT,
+ TR_ROWS,
+ TR_COLUMNS,
+ TR_CURRENT_ROW,
+ TR_CURRENT_COLUMN,
+ TR_CURRENT_TILE_WIDTH,
+ TR_CURRENT_TILE_HEIGHT,
+ TR_ROW_ORDER,
+ TR_TOP_TO_BOTTOM,
+ TR_BOTTOM_TO_TOP
+} TRenum;
+
+
+
+extern TRcontext *trNew(void);
+
+extern void trDelete(TRcontext *tr);
+
+
+extern void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border);
+
+extern void trTileBuffer(TRcontext *tr, GLenum format, GLenum type,
+ GLvoid *image);
+
+
+extern void trImageSize(TRcontext *tr, GLint width, GLint height);
+
+extern void trImageBuffer(TRcontext *tr, GLenum format, GLenum type,
+ GLvoid *image);
+
+
+extern void trRowOrder(TRcontext *tr, TRenum order);
+
+
+extern GLint trGet(TRcontext *tr, TRenum param);
+
+
+extern void trOrtho(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar);
+
+extern void trFrustum(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar);
+
+extern void trPerspective(TRcontext *tr,
+ GLdouble fovy, GLdouble aspect,
+ GLdouble zNear, GLdouble zFar );
+
+
+extern void trBeginTile(TRcontext *tr);
+
+extern int trEndTile(TRcontext *tr);
+
+
+extern void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/graphics/asymptote/transform.h b/graphics/asymptote/transform.h
new file mode 100644
index 0000000000..d421e2baec
--- /dev/null
+++ b/graphics/asymptote/transform.h
@@ -0,0 +1,256 @@
+/*****
+ * transform.h
+ * Andy Hammerlindl 2002/05/22
+ *
+ * The transform datatype stores an affine transformation on the plane
+ * The datamembers are x, y, xx, xy, yx, and yy. A pair (x,y) is
+ * transformed as
+ * x' = t.x + t.xx * x + t.xy * y
+ * y' = t.y + t.yx * x + t.yy * y
+ *****/
+
+#ifndef TRANSFORM_H
+#define TRANSFORM_H
+
+#include <iostream>
+
+#include "pair.h"
+
+namespace camp {
+
+class transform : public gc {
+ double x;
+ double y;
+ double xx;
+ double xy;
+ double yx;
+ double yy;
+
+public:
+ transform()
+ : x(0.0), y(0.0), xx(1.0), xy(0.0), yx(0.0), yy(1.0) {}
+
+ virtual ~transform() {}
+
+ transform(double x, double y,
+ double xx, double xy,
+ double yx, double yy)
+ : x(x), y(y), xx(xx), xy(xy), yx(yx), yy(yy) {}
+
+ double getx() const { return x; }
+ double gety() const { return y; }
+ double getxx() const { return xx; }
+ double getxy() const { return xy; }
+ double getyx() const { return yx; }
+ double getyy() const { return yy; }
+
+ friend transform operator+ (const transform& t, const transform& s)
+ {
+ return transform(t.x + s.x, t.y + s.y,
+ t.xx + s.xx, t.xy + s.xy,
+ t.yx + s.yx, t.yy + s.yy);
+ }
+
+ friend transform operator- (const transform& t, const transform& s)
+ {
+ return transform(t.x - s.x, t.y - s.y,
+ t.xx - s.xx, t.xy - s.xy,
+ t.yx - s.yx, t.yy - s.yy);
+ }
+
+ friend transform operator- (const transform& t)
+ {
+ return transform(-t.x, -t.y,
+ -t.xx, -t.xy,
+ -t.yx, -t.yy);
+ }
+
+ friend pair operator* (const transform& t, const pair& z)
+ {
+ double x = z.getx(), y = z.gety();
+ return pair(t.x + t.xx * x + t.xy * y, t.y + t.yx * x + t.yy * y);
+ }
+
+ // Calculates the composition of t and s, so for a pair, z,
+ // t * (s * z) == (t * s) * z
+ // Can be thought of as matrix multiplication.
+ friend transform operator* (const transform& t, const transform& s)
+ {
+ return transform(t.x + t.xx * s.x + t.xy * s.y,
+ t.y + t.yx * s.x + t.yy * s.y,
+ t.xx * s.xx + t.xy * s.yx,
+ t.xx * s.xy + t.xy * s.yy,
+ t.yx * s.xx + t.yy * s.yx,
+ t.yx * s.xy + t.yy * s.yy);
+ }
+
+ friend bool operator== (const transform& t1, const transform& t2)
+ {
+ return t1.x == t2.x && t1.y == t2.y &&
+ t1.xx == t2.xx && t1.xy == t2.xy &&
+ t1.yx == t2.yx && t1.yy == t2.yy;
+ }
+
+ friend bool operator!= (const transform& t1, const transform& t2)
+ {
+ return !(t1 == t2);
+ }
+
+ bool isIdentity() const
+ {
+ return x == 0.0 && y == 0.0 &&
+ xx == 1.0 && xy == 0.0 && yx == 0.0 && yy == 1.0;
+ }
+
+ bool isNull() const
+ {
+ return x == 0.0 && y == 0.0 &&
+ xx == 0.0 && xy == 0.0 && yx == 0.0 && yy == 0.0;
+ }
+
+ // Calculates the determinant, as if it were a matrix.
+ friend double det(const transform& t)
+ {
+ return t.xx * t.yy - t.xy * t.yx;
+ }
+
+ // Tells if the transformation is invertible (bijective).
+ bool invertible() const
+ {
+ return det(*this) != 0.0;
+ }
+
+ friend transform inverse(const transform& t)
+ {
+ double d = det(t);
+ if (d == 0.0)
+ reportError("inverting singular transform");
+
+ d=1.0/d;
+ return transform((t.xy * t.y - t.yy * t.x)*d,
+ (t.yx * t.x - t.xx * t.y)*d,
+ t.yy*d, -t.xy*d, -t.yx*d, t.xx*d);
+ }
+
+ friend ostream& operator<< (ostream& out, const transform& t)
+ {
+ return out << "(" << t.x << ","
+ << t.y << ","
+ << t.xx << ","
+ << t.xy << ","
+ << t.yx << ","
+ << t.yy << ")";
+ }
+};
+
+// The common transforms
+static const transform identity;
+
+inline transform shift(pair z)
+{
+ return transform (z.getx(), z.gety(), 1.0, 0.0, 0.0, 1.0);
+}
+
+inline transform xscale(double s)
+{
+ return transform (0.0, 0.0, s, 0.0, 0.0, 1.0);
+}
+
+inline transform yscale(double s)
+{
+ return transform (0.0, 0.0, 1.0, 0.0, 0.0, s);
+}
+
+inline transform scale(double s)
+{
+ return transform (0.0, 0.0, s, 0.0, 0.0, s);
+}
+
+inline transform scale(double x, double y)
+{
+ return transform (0.0, 0.0, x, 0.0, 0.0, y);
+}
+
+inline transform scale(pair z)
+{
+ // Equivalent to multiplication by z.
+ double x = z.getx(), y = z.gety();
+ return transform (0.0, 0.0, x, -y, y, x);
+}
+
+inline transform slant(double s)
+{
+ return transform (0.0, 0.0, 1.0, s, 0.0, 1.0);
+}
+
+inline transform rotate(double theta)
+{
+ double s = sin(theta), c = cos(theta);
+ return transform (0.0, 0.0, c, -s, s, c);
+}
+
+// return rotate(angle(v)) if z != (0,0); otherwise return identity.
+inline transform rotate(pair z)
+{
+ double d=z.length();
+ if(d == 0.0) return identity;
+ d=1.0/d;
+ return transform (0.0, 0.0, d*z.getx(), -d*z.gety(), d*z.gety(), d*z.getx());
+}
+
+inline transform rotatearound(pair z, double theta)
+{
+ // Notice the operators are applied from right to left.
+ // Could be optimized.
+ return shift(z) * rotate(theta) * shift(-z);
+}
+
+inline transform reflectabout(pair z, pair w)
+{
+ if (z == w)
+ reportError("points determining line to reflect about must be distinct");
+
+ // Also could be optimized.
+ transform basis = shift(z) * scale(w-z);
+ transform flip = yscale(-1.0);
+
+ return basis * flip * inverse(basis);
+}
+
+// Return the rotational part of t.
+inline transform rotation(transform t)
+{
+ pair z(2.0*t.getxx()*t.getyy(),t.getyx()*t.getyy()-t.getxx()*t.getxy());
+ if(t.getxx() < 0) z=-z;
+ return rotate(atan2(z.gety(),z.getx()));
+}
+
+// Remove the x and y components, so that the new transform maps zero to zero.
+inline transform shiftless(transform t)
+{
+ return transform(0, 0, t.getxx(), t.getxy(), t.getyx(), t.getyy());
+}
+
+// Return the translational component of t.
+inline transform shift(transform t)
+{
+ return transform(t.getx(), t.gety(), 1.0, 0, 0, 1.0);
+}
+
+// Return the translational pair of t.
+inline pair shiftpair(transform t)
+{
+ return pair(t.getx(), t.gety());
+}
+
+inline transform matrix(pair lb, pair rt)
+{
+ pair size=rt-lb;
+ return transform(lb.getx(),lb.gety(),size.getx(),0,0,size.gety());
+}
+
+} //namespace camp
+
+GC_DECLARE_PTRFREE(camp::transform);
+
+#endif
diff --git a/graphics/asymptote/triple.h b/graphics/asymptote/triple.h
new file mode 100644
index 0000000000..de6767a29f
--- /dev/null
+++ b/graphics/asymptote/triple.h
@@ -0,0 +1,365 @@
+/*****
+ * triple.h
+ * John Bowman
+ *
+ * Stores a three-dimensional point.
+ *
+ *****/
+
+#ifndef TRIPLE_H
+#define TRIPLE_H
+
+#include <cassert>
+#include <iostream>
+#include <cmath>
+#include <cstring>
+
+#include "common.h"
+#include "angle.h"
+#include "pair.h"
+
+namespace run {
+void transpose(double *a, size_t n);
+void inverse(double *a, size_t n);
+}
+
+namespace camp {
+
+typedef double Triple[3];
+
+class triple;
+
+bool isIdTransform3(const double* t);
+void copyTransform3(double*& d, const double* s, GCPlacement placement=NoGC);
+void multiplyTransform3(double*& t, const double* s, const double* r);
+
+void boundstriples(double& x, double& y, double& z, double& X, double& Y,
+ double& Z, size_t n, const triple* v);
+
+class triple : virtual public gc {
+ double x;
+ double y;
+ double z;
+
+public:
+ triple() : x(0.0), y(0.0), z(0.0) {}
+ triple(double x, double y=0.0, double z=0.0) : x(x), y(y), z(z) {}
+ triple(const Triple& v) : x(v[0]), y(v[1]), z(v[2]) {}
+
+ virtual ~triple() {}
+
+ void set(double X, double Y=0.0, double Z=0.0) { x=X; y=Y; z=Z; }
+
+ double getx() const { return x; }
+ double gety() const { return y; }
+ double getz() const { return z; }
+
+ // transform by row-major matrix
+ friend triple operator* (const double* t, const triple& v)
+ {
+ if(t == NULL)
+ return v;
+
+ double f=t[12]*v.x+t[13]*v.y+t[14]*v.z+t[15];
+ if(f == 0.0)
+ reportError("division by 0 in transform of a triple");
+
+ f=1.0/f;
+
+ return triple((t[0]*v.x+t[1]*v.y+t[2]*v.z+t[3])*f,
+ (t[4]*v.x+t[5]*v.y+t[6]*v.z+t[7])*f,
+ (t[8]*v.x+t[9]*v.y+t[10]*v.z+t[11])*f);
+ }
+
+ friend triple transformNormal(const double* t, const triple& v)
+ {
+ if(t == NULL)
+ return v;
+
+ double T[16];
+ memcpy(T,t,sizeof(double)*16);
+ T[3]=T[7]=T[11]=0.0;
+ run::inverse(T,4);
+ run::transpose(T,4);
+ triple V=T*v;
+ return unit(V);
+ }
+
+ friend void transformtriples(const double* t, size_t n, triple* d,
+ const triple* s)
+ {
+ if(n == 0 || d == NULL || s == NULL)
+ return;
+
+ for(size_t i=0; i < n; i++)
+ d[i]=t*s[i];
+ }
+
+ friend void copytriples(size_t n, triple* d, const triple* s)
+ {
+ if(d == NULL || s == NULL)
+ return;
+
+ for(size_t i=0; i < n; i++) d[i]=s[i];
+ }
+
+ friend void boundstriples(triple& Min, triple& Max, size_t n, const triple* v)
+ {
+ if(n==0 || v==NULL)
+ return;
+
+ double x,y,z;
+ double X,Y,Z;
+
+ X=x=v[0].getx();
+ Y=y=v[0].gety();
+ Z=z=v[0].getz();
+ for(size_t i=1; i < n; ++i) {
+ const double vx=v[i].getx();
+ x=fmin(x,vx); X=fmax(X,vx);
+ const double vy=v[i].gety();
+ y=fmin(y,vy); Y=fmax(Y,vy);
+ const double vz=v[i].getz();
+ z=fmin(z,vz); Z=fmax(Z,vz);
+ }
+
+ Min.set(x,y,z);
+ Max.set(X,Y,Z);
+ }
+
+ friend void ratiotriples(pair &b, double (*m)(double, double), bool &first,
+ size_t n, const triple* v)
+ {
+ if(n==0 || v==NULL)
+ return;
+
+ if(first) {
+ first=false;
+ const triple& v0=v[0];
+ b=pair(v0.x/v0.z,v0.y/v0.z);
+ }
+
+ double x=b.getx();
+ double y=b.gety();
+ for(size_t i=0; i < n; ++i) {
+ const triple& vi = v[i];
+ x=m(x,vi.x/vi.z);
+ y=m(y,vi.y/vi.z);
+ }
+ b=pair(x,y);
+ }
+
+ friend triple operator+ (const triple& z, const triple& w)
+ {
+ return triple(z.x + w.x, z.y + w.y, z.z + w.z);
+ }
+
+ friend triple operator- (const triple& z, const triple& w)
+ {
+ return triple(z.x - w.x, z.y - w.y, z.z - w.z);
+ }
+
+ friend triple operator- (const triple& z)
+ {
+ return triple(-z.x, -z.y, -z.z);
+ }
+
+ friend triple operator* (double s, const triple& z)
+ {
+ return triple(s*z.x, s*z.y, s*z.z);
+ }
+
+ friend triple operator* (const triple& z, double s)
+ {
+ return triple(z.x*s, z.y*s, z.z*s);
+ }
+
+ friend triple operator/ (const triple& z, double s)
+ {
+ if (s == 0.0)
+ reportError("division by 0");
+ s=1.0/s;
+ return triple(z.x*s, z.y*s, z.z*s);
+ }
+
+ const triple& operator+= (const triple& w)
+ {
+ x += w.x;
+ y += w.y;
+ z += w.z;
+ return *this;
+ }
+
+ const triple& operator-= (const triple& w)
+ {
+ x -= w.x;
+ y -= w.y;
+ z -= w.z;
+ return *this;
+ }
+
+ friend bool operator== (const triple& z, const triple& w)
+ {
+ return z.x == w.x && z.y == w.y && z.z == w.z;
+ }
+
+ friend bool operator!= (const triple& z, const triple& w)
+ {
+ return z.x != w.x || z.y != w.y || z.z != w.z;
+ }
+
+ double abs2() const
+ {
+ return x*x+y*y+z*z;
+ }
+
+ friend double abs2(const triple &v)
+ {
+ return v.abs2();
+ }
+
+ double length() const /* r */
+ {
+ return sqrt(abs2());
+ }
+
+ friend double length(const triple& v)
+ {
+ return v.length();
+ }
+
+ double polar() const /* theta */
+ {
+ double r=length();
+ if (r == 0.0)
+ reportError("taking polar angle of (0,0,0)");
+ return acos(z/r);
+ }
+
+ double azimuth() const /* phi */
+ {
+ return angle(x,y);
+ }
+
+ friend triple unit(const triple& v)
+ {
+ double scale=v.length();
+ if(scale == 0.0) return v;
+ scale=1.0/scale;
+ return triple(v.x*scale,v.y*scale,v.z*scale);
+ }
+
+ friend double dot(const triple& u, const triple& v)
+ {
+ return u.x*v.x+u.y*v.y+u.z*v.z;
+ }
+
+ friend triple cross(const triple& u, const triple& v)
+ {
+ return triple(u.y*v.z-u.z*v.y,
+ u.z*v.x-u.x*v.z,
+ u.x*v.y-u.y*v.x);
+ }
+
+ // Returns a unit triple in the direction (theta,phi), in radians.
+ friend triple expi(double theta, double phi)
+ {
+ double sintheta=sin(theta);
+ return triple(sintheta*cos(phi),sintheta*sin(phi),cos(theta));
+ }
+
+ friend istream& operator >> (istream& s, triple& z)
+ {
+ char c;
+ s >> std::ws;
+ bool paren=s.peek() == '('; // parenthesis are optional
+ if(paren) s >> c;
+ s >> z.x >> std::ws;
+ if(s.peek() == ',') s >> c >> z.y;
+ else z.y=0.0;
+ if(s.peek() == ',') s >> c >> z.z;
+ else z.z=0.0;
+ if(paren) {
+ s >> std::ws;
+ if(s.peek() == ')') s >> c;
+ }
+
+ return s;
+ }
+
+ friend ostream& operator << (ostream& out, const triple& z)
+ {
+ out << "(" << z.x << "," << z.y << "," << z.z << ")";
+ return out;
+ }
+
+};
+
+triple expi(double theta, double phi);
+
+// Return the component of vector v perpendicular to a unit vector u.
+inline triple perp(triple v, triple u)
+{
+ return v-dot(v,u)*u;
+}
+
+double xratio(const triple& v);
+double yratio(const triple& v);
+
+inline void bounds(double& x, double &X, double v)
+{
+ if(v < x) x=v;
+ else if(v > X) X=v;
+}
+
+inline void boundstriples(double& x, double& y, double& z,
+ double& X, double& Y, double& Z,
+ size_t n, const triple* v)
+{
+ X=x=v[0].getx();
+ Y=y=v[0].gety();
+ Z=z=v[0].getz();
+
+ for(size_t i=1; i < n; ++i) {
+ triple V=v[i];
+ bounds(x,X,V.getx());
+ bounds(y,Y,V.gety());
+ bounds(z,Z,V.getz());
+ }
+}
+
+extern const double third;
+
+// return the maximum distance squared of points c0 and c1 from
+// the respective internal control points of z0--z1.
+inline double Straightness(const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1)
+{
+ triple v=third*(z1-z0);
+ return std::max(abs2(c0-v-z0),abs2(z1-v-c1));
+}
+
+// return the maximum perpendicular distance squared of points c0 and c1
+// from z0--z1.
+inline double Distance1(const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1)
+{
+ triple Z0=c0-z0;
+ triple Q=unit(z1-z0);
+ triple Z1=c1-z0;
+ return std::max(abs2(Z0-dot(Z0,Q)*Q),abs2(Z1-dot(Z1,Q)*Q));
+}
+
+// return the perpendicular distance squared of a point z from the plane
+// through u with unit normal n.
+inline double Distance2(const triple& z, const triple& u, const triple& n)
+{
+ double d=dot(z-u,n);
+ return d*d;
+}
+
+} //namespace camp
+
+GC_DECLARE_PTRFREE(camp::triple);
+
+#endif
diff --git a/graphics/asymptote/types.cc b/graphics/asymptote/types.cc
new file mode 100644
index 0000000000..4a449a1a98
--- /dev/null
+++ b/graphics/asymptote/types.cc
@@ -0,0 +1,556 @@
+/*****
+ * types.cc
+ * Andy Hammerlindl 2002/06/24
+ *
+ * Used by the compiler as a way to keep track of the type of a variable
+ * or expression.
+ *****/
+
+#include <cstdio>
+#include <algorithm>
+
+#include "entry.h"
+#include "types.h"
+#include "runtime.h"
+#include "runarray.h"
+#include "runfile.h"
+#include "runpair.h"
+#include "runtriple.h"
+#include "access.h"
+#include "virtualfieldaccess.h"
+
+namespace run {
+void arrayDeleteHelper(vm::stack *Stack);
+}
+
+// For pre-translated symbols.
+#ifndef NOSYM
+#include "types.symbols.h"
+#endif
+
+namespace types {
+
+/* Base types */
+#define PRIMITIVE(name,Name,asyName) \
+ primitiveTy p##Name(ty_##name); \
+ ty *prim##Name() { return &p##Name; } \
+ array name##Array_(prim##Name()); \
+ ty *name##Array() { return &name##Array_; } \
+ array name##Array2_(name##Array()); \
+ ty *name##Array2() { return &name##Array2_; } \
+ array name##Array3_(name##Array2()); \
+ ty *name##Array3() { return &name##Array3_; }
+#define PRIMERROR
+#include "primitives.h"
+#undef PRIMERROR
+#undef PRIMITIVE
+
+nullTy pNull;
+ty *primNull() { return &pNull; }
+
+const char *names[] = {
+ "null",
+ "<structure>", "<function>", "<overloaded>",
+
+#define PRIMITIVE(name,Name,asyName) #asyName,
+#define PRIMERROR
+#include "primitives.h"
+#undef PRIMERROR
+#undef PRIMITIVE
+
+ "<array>"
+};
+
+ty::~ty()
+{}
+
+void ty::print(ostream& out) const
+{
+ out << names[kind];
+}
+
+// Used for primitive virtual fields and array virtual fields.
+#define FIELD(Type, name, func) \
+ if (sig == 0 && id == name) { \
+ static trans::virtualFieldAccess a(run::func); \
+ static trans::varEntry v(Type(), &a, 0, position()); \
+ return &v; \
+ }
+
+#define RWFIELD(Type, name, getter, setter) \
+ if (sig == 0 && id == name) { \
+ static trans::virtualFieldAccess a(run::getter, run::setter); \
+ static trans::varEntry v(Type(), &a, 0, position()); \
+ return &v; \
+ }
+
+#define SIGFIELD(Type, name, func) \
+ if (id == name && \
+ equivalent(sig, Type()->getSignature())) \
+ { \
+ static trans::virtualFieldAccess a(run::func, 0, run::func##Helper); \
+ static trans::varEntry v(Type(), &a, 0, position()); \
+ return &v; \
+ }
+
+#define DSIGFIELD(name, sym, func) \
+ if (id == sym && \
+ equivalent(sig, name##Type()->getSignature())) \
+ { \
+ static trans::virtualFieldAccess a(run::func, 0, run::func##Helper); \
+ /* for some fields, v needs to be dynamic */ \
+ /* e.g. when the function type depends on an array type. */ \
+ trans::varEntry *v = \
+ new trans::varEntry(name##Type(), &a, 0, position()); \
+ return v; \
+ }
+
+#define FILEFIELD(GetType, SetType, name, sym) \
+ FIELD(GetType,sym,name##Part); \
+ SIGFIELD(SetType,sym,name##Set);
+
+
+ty *dimensionType() {
+ return new function(primFile(),
+ formal(primInt(),SYM(nx),true),
+ formal(primInt(),SYM(ny),true),
+ formal(primInt(),SYM(nz),true));
+}
+
+ty *modeType() {
+ return new function(primFile(),formal(primBoolean(),SYM(b), true));
+}
+
+ty *readType() {
+ return new function(primFile(), formal(primInt(), SYM(i)));
+}
+
+trans::varEntry *primitiveTy::virtualField(symbol id, signature *sig)
+{
+ switch (kind) {
+ case ty_pair:
+ FIELD(primReal,SYM(x),pairXPart);
+ FIELD(primReal,SYM(y),pairYPart);
+ break;
+ case ty_triple:
+ FIELD(primReal,SYM(x),tripleXPart);
+ FIELD(primReal,SYM(y),tripleYPart);
+ FIELD(primReal,SYM(z),tripleZPart);
+ break;
+ case ty_transform:
+ FIELD(primReal,SYM(x),transformXPart);
+ FIELD(primReal,SYM(y),transformYPart);
+ FIELD(primReal,SYM(xx),transformXXPart);
+ FIELD(primReal,SYM(xy),transformXYPart);
+ FIELD(primReal,SYM(yx),transformYXPart);
+ FIELD(primReal,SYM(yy),transformYYPart);
+ break;
+ case ty_tensionSpecifier:
+ FIELD(primReal,SYM(out),tensionSpecifierOutPart);
+ FIELD(primReal,SYM(in),tensionSpecifierInPart);
+ FIELD(primBoolean,SYM(atLeast),tensionSpecifierAtleastPart);
+ break;
+ case ty_curlSpecifier:
+ FIELD(primReal,SYM(value),curlSpecifierValuePart);
+ FIELD(primInt,SYM(side),curlSpecifierSidePart);
+ break;
+ case ty_file:
+ FIELD(primString,SYM(name),namePart);
+ FIELD(primString,SYM(mode),modePart);
+ FILEFIELD(IntArray,dimensionType,dimension,SYM(dimension));
+ FILEFIELD(primBoolean,modeType,line,SYM(line));
+ FILEFIELD(primBoolean,modeType,csv,SYM(csv));
+ FILEFIELD(primBoolean,modeType,word,SYM(word));
+ FILEFIELD(primBoolean,modeType,singlereal,SYM(singlereal));
+ FILEFIELD(primBoolean,modeType,singleint,SYM(singleint));
+ FILEFIELD(primBoolean,modeType,signedint,SYM(signedint));
+ SIGFIELD(readType,SYM(read),readSet);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+ty *overloadedDimensionType() {
+ overloaded *o=new overloaded;
+ o->add(dimensionType());
+ o->add(IntArray());
+ return o;
+}
+
+ty *overloadedModeType() {
+ overloaded *o=new overloaded;
+ o->add(modeType());
+ o->add(primBoolean());
+ return o;
+}
+
+ty *ty::virtualFieldGetType(symbol id)
+{
+ trans::varEntry *v = virtualField(id, 0);
+ return v ? v->getType() : 0;
+}
+
+ty *primitiveTy::virtualFieldGetType(symbol id)
+{
+ if(kind == ty_file) {
+ if (id == SYM(dimension))
+ return overloadedDimensionType();
+
+ if (id == SYM(line) || id == SYM(csv) ||
+ id == SYM(word) || id == SYM(singlereal) ||
+ id == SYM(singleint) || id == SYM(signedint))
+ return overloadedModeType();
+
+ if (id == SYM(read))
+ return readType();
+ }
+
+ trans::varEntry *v = virtualField(id, 0);
+
+ return v ? v->getType() : 0;
+}
+
+#define RETURN_STATIC_BLTIN(func) \
+ { \
+ static trans::bltinAccess a(run::func); \
+ return &a; \
+ }
+
+trans::access *nullTy::castTo(ty *target, caster &) {
+ switch (target->kind) {
+ case ty_array: {
+ RETURN_STATIC_BLTIN(pushNullArray);
+ }
+ case ty_record: {
+ RETURN_STATIC_BLTIN(pushNullRecord);
+ }
+ case ty_function: {
+ RETURN_STATIC_BLTIN(pushNullFunction);
+ }
+ default:
+ return 0;
+ }
+}
+
+trans::access *array::initializer()
+{
+ RETURN_STATIC_BLTIN(emptyArray)
+}
+
+ty *array::pushType()
+{
+ if (pushtype == 0)
+ pushtype = new function(celltype,formal(celltype,SYM(x)));
+
+ return pushtype;
+}
+
+ty *array::popType()
+{
+ if (poptype == 0)
+ poptype = new function(celltype);
+
+ return poptype;
+}
+
+ty *array::appendType()
+{
+ if (appendtype == 0)
+ appendtype = new function(primVoid(),formal(this,SYM(a)));
+
+ return appendtype;
+}
+
+ty *array::insertType()
+{
+ if (inserttype == 0) {
+ function *f=new function(primVoid(),formal(primInt(),SYM(i)));
+ f->addRest(this);
+ inserttype = f;
+ }
+
+ return inserttype;
+}
+
+ty *array::deleteType()
+{
+ if (deletetype == 0)
+ deletetype = new function(primVoid(),formal(primInt(),SYM(i),true),
+ formal(primInt(),SYM(j),true));
+
+ return deletetype;
+}
+
+ty *initializedType() {
+ return new function(primBoolean(),formal(primInt(),SYM(i)));
+}
+
+#define SIGFIELDLIST \
+ ASIGFIELD(initialized, SYM(initialized), arrayInitialized); \
+ ASIGFIELD(push, SYM(push), arrayPush); \
+ ASIGFIELD(pop, SYM(pop), arrayPop); \
+ ASIGFIELD(append, SYM(append), arrayAppend); \
+ ASIGFIELD(insert, SYM(insert), arrayInsert); \
+ ASIGFIELD(delete, SYM(delete), arrayDelete); \
+
+ty *array::virtualFieldGetType(symbol id)
+{
+ #define ASIGFIELD(name, sym, func) \
+ if (id == sym) \
+ return name##Type();
+
+ SIGFIELDLIST
+
+ #undef ASIGFIELD
+
+ return ty::virtualFieldGetType(id);
+}
+
+trans::varEntry *array::virtualField(symbol id, signature *sig)
+{
+ FIELD(primInt, SYM(length), arrayLength);
+ FIELD(IntArray, SYM(keys), arrayKeys);
+ RWFIELD(primBoolean, SYM(cyclic), arrayCyclicFlag, arraySetCyclicFlag);
+
+ #define ASIGFIELD(name, sym, func) DSIGFIELD(name, sym, func)
+
+ SIGFIELDLIST
+
+ #undef ASIGFIELD
+
+ // Fall back on base class to handle no match.
+ return ty::virtualField(id, sig);
+}
+
+#undef SIGFIELDLIST
+
+void printFormal(ostream& out, const formal& f, bool keywordOnly)
+{
+ if (f.Explicit)
+ out << "explicit ";
+ if (f.name)
+ f.t->printVar(out, keywordOnly ? "keyword "+(string)(f.name) : f.name);
+ else
+ f.t->print(out);
+ if (f.defval)
+ out << "=<default>";
+}
+
+ostream& operator<< (ostream& out, const formal& f)
+{
+#if 0
+ if (f.Explicit)
+ out << "explicit ";
+ if (f.name)
+ f.t->printVar(out,f.name);
+ else
+ f.t->print(out);
+ if (f.defval)
+ out << "=<default>";
+#endif
+ printFormal(out, f, false);
+ return out;
+}
+
+bool equivalent(const formal& f1, const formal& f2) {
+ // Just test the types.
+ // This cannot be used on rest formal with types equal to NULL.
+ return equivalent(f1.t,f2.t);
+}
+
+bool argumentEquivalent(const formal &f1, const formal& f2) {
+ if (f1.name == f2.name) {
+ if (f1.t == 0)
+ return f2.t == 0;
+ else if (f2.t == 0)
+ return false;
+
+ return f1.t->kind != ty_overloaded &&
+ f2.t->kind != ty_overloaded &&
+ equivalent(f1.t, f2.t);
+ }
+ else
+ return false;
+}
+
+ostream& operator<< (ostream& out, const signature& s)
+{
+ if (s.isOpen) {
+ out << "(<open>)";
+ return out;
+ }
+
+ out << "(";
+
+ for (size_t i = 0; i < s.formals.size(); ++i)
+ {
+ if (i > 0)
+ out << ", ";
+ printFormal(out, s.getFormal(i), s.formalIsKeywordOnly(i));
+ }
+
+ if (s.rest.t) {
+ if (!s.formals.empty())
+ out << " ";
+ out << "... " << s.rest;
+ }
+
+ out << ")";
+
+ return out;
+}
+
+
+// Equivalence by design does not look at the presence of default values.
+bool equivalent(const signature *s1, const signature *s2)
+{
+ if (s1 == s2)
+ return true;
+
+ // Handle null signature
+ if (s1 == 0 || s2 == 0)
+ return false;
+
+ // Two open signatures are always equivalent, as the formals are ignored.
+ if (s1->isOpen)
+ return s2->isOpen;
+ else if (s2->isOpen)
+ return false;
+
+ if (s1->formals.size() != s2->formals.size())
+ return false;
+
+ if (!std::equal(s1->formals.begin(),s1->formals.end(),s2->formals.begin(),
+ (bool (*)(const formal&,const formal&)) equivalent))
+ return false;
+
+ if (s1->rest.t)
+ return s2->rest.t && equivalent(s1->rest, s2->rest);
+ else
+ return s2->rest.t == 0;
+}
+
+bool argumentEquivalent(const signature *s1, const signature *s2)
+{
+ // Handle null signature
+ if (s1 == 0)
+ return s2 == 0;
+ else if (s2 == 0)
+ return false;
+
+ if (s1->formals.size() != s2->formals.size())
+ return false;
+
+ return std::equal(s1->formals.begin(),s1->formals.end(),s2->formals.begin(),
+ (bool (*)(const formal&,const formal&))
+ argumentEquivalent) &&
+ argumentEquivalent(s1->rest, s2->rest);
+}
+
+size_t signature::hash() const {
+ size_t x=2038;
+ for (formal_vector::const_iterator i=formals.begin(); i!=formals.end(); ++i)
+ x=x*0xFAEC+i->t->hash();
+
+ if (rest.t)
+ x=x*0xACED +rest.t->hash();
+
+ return x;
+}
+
+trans::access *function::initializer() {
+ RETURN_STATIC_BLTIN(pushNullFunction);
+}
+
+#if 0
+ty *function::stripDefaults()
+{
+ function *f = new function(result);
+
+ Int n = sig.getNumFormals();
+ for (Int i = 0; i < n; ++i)
+ f->add(sig.getFormal(i), 0);
+
+ return f;
+}
+#endif
+
+// Only add a type with a signature distinct from the ones currently
+// in the overloaded type.
+void overloaded::addDistinct(ty *t, bool special)
+{
+ if (t->kind == ty_overloaded) {
+ overloaded *ot = (overloaded *)t;
+ for (ty_vector::iterator st = ot->sub.begin();
+ st != ot->sub.end();
+ ++st)
+ {
+ this->addDistinct(*st, special);
+ }
+ }
+ else {
+ for (ty_vector::iterator st = this->sub.begin();
+ st != this->sub.end();
+ ++st)
+ {
+ if (equivalent(t, *st, special))
+ return;
+ }
+
+ // Nonequivalent in signature - add it.
+ this->add(t);
+ }
+}
+
+
+ty *overloaded::signatureless()
+{
+ for(ty_vector::iterator t = sub.begin(); t != sub.end(); ++t)
+ if ((*t)->getSignature()==0)
+ return *t;
+
+ return 0;
+}
+
+bool overloaded::castable(ty *target, caster &c)
+{
+ for(ty_vector::iterator s = sub.begin(); s != sub.end(); ++s)
+ if (c.castable(target,*s))
+ return true;
+ return false;
+}
+
+bool equivalent(const ty *t1, const ty *t2)
+{
+ // The same pointer must point to the same type.
+ if (t1 == t2)
+ return true;
+
+ // Ensure if an overloaded type is compared to a non-overloaded one, that the
+ // overloaded type's method is called.
+ if (t2->kind == ty_overloaded)
+ return t2->equiv(t1);
+ if (t1->kind == ty_overloaded)
+ return t1->equiv(t2);
+
+ // Outside of overloaded types, different kinds mean different types.
+ if (t1->kind != t2->kind)
+ return false;
+
+ return t1->equiv(t2);
+}
+
+
+bool equivalent(const ty *t1, const ty *t2, bool special) {
+ return special ? equivalent(t1, t2) :
+ equivalent(t1->getSignature(), t2->getSignature());
+}
+
+#undef FIELD
+#undef RWFIELD
+#undef SIGFIELD
+#undef DSIGFIELD
+
+} // namespace types
diff --git a/graphics/asymptote/types.h b/graphics/asymptote/types.h
new file mode 100644
index 0000000000..22c1daf893
--- /dev/null
+++ b/graphics/asymptote/types.h
@@ -0,0 +1,655 @@
+/*****
+ * types.h
+ * Andy Hammerlindl 2002/06/20
+ *
+ * Used by the compiler as a way to keep track of the type of a variable
+ * or expression.
+ *
+ *****/
+
+#ifndef TYPES_H
+#define TYPES_H
+
+#include <iostream>
+#include <cstdio>
+#include <cassert>
+
+#include "errormsg.h"
+#include "symbol.h"
+#include "common.h"
+#include "util.h"
+
+using std::ostream;
+
+using sym::symbol;
+
+// Forward declaration.
+namespace trans {
+class access;
+class varEntry;
+}
+namespace absyntax {
+class varinit;
+extern varinit *Default;
+}
+
+namespace types {
+
+enum ty_kind {
+ ty_null,
+ ty_record, // "struct" in Asymptote language
+ ty_function,
+ ty_overloaded,
+
+#define PRIMITIVE(name,Name,asyName) ty_##name,
+#define PRIMERROR
+#include "primitives.h"
+#undef PRIMERROR
+#undef PRIMITIVE
+
+ ty_array
+};
+
+// Forward declarations.
+class ty;
+struct signature;
+typedef mem::vector<ty *> ty_vector;
+typedef ty_vector::iterator ty_iterator;
+
+// Checks if two types are equal in the sense of the language.
+// That is primitive types are equal if they are the same kind.
+// Structures are equal if they come from the same struct definition.
+// Arrays are equal if their cell types are equal.
+bool equivalent(const ty *t1, const ty *t2);
+
+// If special is true, this is the same as above. If special is false, just the
+// signatures are compared.
+bool equivalent(const ty *t1, const ty *t2, bool special);
+
+class caster {
+public:
+ virtual ~caster() {}
+ virtual trans::access *operator() (ty *target, ty *source) = 0;
+ virtual bool castable(ty *target, ty *source) = 0;
+};
+
+class ty : public gc {
+public:
+ const ty_kind kind;
+ ty(ty_kind kind)
+ : kind(kind) {}
+ virtual ~ty();
+
+ virtual void print (ostream& out) const;
+ virtual void printVar (ostream& out, string name) const {
+ print(out);
+ out << " " << name;
+ }
+
+
+ // Returns true if the type is a user-defined type or the null type.
+ // While the pair, path, etc. are stored by reference, this is
+ // transparent to the user.
+ virtual bool isReference() {
+ return true;
+ }
+
+ virtual signature *getSignature() {
+ return 0;
+ }
+
+ virtual const signature *getSignature() const {
+ return 0;
+ }
+
+ virtual bool primitive() {
+ return false;
+ }
+
+ bool isError() const { return kind == ty_error; }
+ bool isNotError() const { return !isError(); }
+
+ // The following are only used by the overloaded type, but it is so common
+ // to test for an overloaded type then iterate over its types, that this
+ // allows the code:
+ // if (t->isOverloaded()) {
+ // for (ty_iterator i = t->begin(); i != t->end(); ++i) {
+ // ...
+ // }
+ // }
+ // For speed reasons, only begin has an assert to test if t is overloaded.
+ bool isOverloaded() const {
+ return kind == ty_overloaded;
+ }
+ bool isNotOverloaded() const { return !isOverloaded(); }
+ ty_iterator begin();
+ ty_iterator end();
+
+ // If a default initializer is not stored in the environment, the abstract
+ // syntax asks the type if it has a "default" default initializer, by calling
+ // this method.
+ virtual trans::access *initializer() {
+ return 0;
+ }
+
+ // If a cast function is not stored in the environment, ask the type itself.
+ // This handles null->record casting, and the like. The caster is used as a
+ // callback to the environment for casts of subtypes.
+ virtual trans::access *castTo(ty *, caster &) {
+ return 0;
+ }
+
+ // Just checks if a cast is possible.
+ virtual bool castable(ty *target, caster &c) {
+ return castTo(target, c);
+ }
+
+ // For pair's x and y, and array's length, this is a special type of
+ // "field".
+ // In actually, it returns a function which takes the object as its
+ // parameter and returns the necessary result.
+ // These should not have public permission, as modifying them would
+ // have strange results.
+ virtual trans::varEntry *virtualField(symbol, signature *) {
+ return 0;
+ }
+
+ // varGetType for virtual fields.
+ // Unless you are using functions for virtual fields, the base implementation
+ // should work fine.
+ virtual ty *virtualFieldGetType(symbol id);
+
+#if 0
+ // Returns the type. In case of functions, return the equivalent type
+ // but with no default values for parameters.
+ virtual ty *stripDefaults()
+ {
+ return this;
+ }
+#endif
+
+ // Returns true if the other type is equivalent to this one.
+ // The general function equivalent should be preferably used, as it properly
+ // handles overloaded type comparisons.
+ virtual bool equiv(const ty *other) const
+ {
+ return this==other;
+ }
+
+
+ // Returns a number for the type for use in a hash table. Equivalent types
+ // must yield the same number.
+ virtual size_t hash() const = 0;
+};
+
+class primitiveTy : public ty {
+public:
+ primitiveTy(ty_kind kind)
+ : ty(kind) {}
+
+ bool primitive() {
+ return true;
+ }
+
+ bool isReference() {
+ return false;
+ }
+
+ ty *virtualFieldGetType(symbol );
+ trans::varEntry *virtualField(symbol, signature *);
+
+ bool equiv(const ty *other) const
+ {
+ return this->kind==other->kind;
+ }
+
+ size_t hash() const {
+ return (size_t)kind + 47;
+ }
+};
+
+class nullTy : public primitiveTy {
+public:
+ nullTy()
+ : primitiveTy(ty_null) {}
+
+ bool isReference() {
+ return true;
+ }
+
+ trans::access *castTo(ty *target, caster &);
+
+ size_t hash() const {
+ return (size_t)kind + 47;
+ }
+};
+
+// Ostream output, just defer to print.
+inline ostream& operator<< (ostream& out, const ty& t)
+{ t.print(out); return out; }
+
+struct array : public ty {
+ ty *celltype;
+ ty *pushtype;
+ ty *poptype;
+ ty *appendtype;
+ ty *inserttype;
+ ty *deletetype;
+
+ array(ty *celltype)
+ : ty(ty_array), celltype(celltype), pushtype(0), poptype(0),
+ appendtype(0), inserttype(0), deletetype(0) {}
+
+ virtual bool isReference() {
+ return true;
+ }
+
+ bool equiv(const ty *other) const {
+ return other->kind==ty_array &&
+ equivalent(this->celltype,((array *)other)->celltype);
+ }
+
+ size_t hash() const {
+ return 1007 * celltype->hash();
+ }
+
+ Int depth() {
+ if (array *cell=dynamic_cast<array *>(celltype))
+ return cell->depth() + 1;
+ else
+ return 1;
+ }
+
+ void print(ostream& out) const
+ { out << *celltype << "[]"; }
+
+ ty *pushType();
+ ty *popType();
+ ty *appendType();
+ ty *insertType();
+ ty *deleteType();
+
+ // Initialize to an empty array by default.
+ trans::access *initializer();
+
+ // NOTE: General vectorization of casts would be here.
+
+ // Add length and push as virtual fields.
+ ty *virtualFieldGetType(symbol id);
+ trans::varEntry *virtualField(symbol id, signature *sig);
+};
+
+/* Base types */
+#define PRIMITIVE(name,Name,asyName) \
+ ty *prim##Name(); \
+ ty *name##Array(); \
+ ty *name##Array2(); \
+ ty *name##Array3();
+#define PRIMERROR
+#include "primitives.h"
+#undef PRIMERROR
+#undef PRIMITIVE
+
+ty *primNull();
+
+
+struct formal {
+ ty *t;
+ symbol name;
+ bool defval;
+ bool Explicit;
+
+ formal(ty *t,
+ symbol name=symbol::nullsym,
+ bool optional=false,
+ bool Explicit=false)
+ : t(t), name(name),
+ defval(optional), Explicit(Explicit) {}
+
+ // string->symbol translation is costly if done too many times. This
+ // constructor has been disabled to make this cost more visible to the
+ // programmer.
+#if 0
+ formal(ty *t,
+ const char *name,
+ bool optional=false,
+ bool Explicit=false)
+ : t(t), name(symbol::trans(name)),
+ defval(optional ? absyntax::Default : 0), Explicit(Explicit) {}
+#endif
+
+ friend ostream& operator<< (ostream& out, const formal& f);
+};
+
+bool equivalent(const formal& f1, const formal& f2);
+bool argumentEquivalent(const formal &f1, const formal& f2);
+
+typedef mem::vector<formal> formal_vector;
+
+// Holds the parameters of a function and if they have default values
+// (only applicable in some cases).
+struct signature : public gc {
+ formal_vector formals;
+
+ // The number of keyword-only formals. These formals always come after the
+ // regular formals.
+ size_t numKeywordOnly;
+
+ // Formal for the rest parameter. If there is no rest parameter, then the
+ // type is null.
+ formal rest;
+
+ bool isOpen;
+
+ signature()
+ : numKeywordOnly(0), rest(0), isOpen(false)
+ {}
+
+ static const struct OPEN_t {} OPEN;
+
+ explicit signature(OPEN_t) : numKeywordOnly(0), rest(0), isOpen(true) {}
+
+ signature(signature &sig)
+ : formals(sig.formals), numKeywordOnly(sig.numKeywordOnly),
+ rest(sig.rest), isOpen(sig.isOpen)
+ {}
+
+ virtual ~signature() {}
+
+ void add(formal f) {
+ formals.push_back(f);
+ }
+
+ void addKeywordOnly(formal f) {
+ add(f);
+ ++numKeywordOnly;
+ }
+
+ void addRest(formal f) {
+ rest=f;
+ }
+
+ bool hasRest() const {
+ return rest.t;
+ }
+ size_t getNumFormals() const {
+ return rest.t ? formals.size() + 1 : formals.size();
+ }
+
+ formal& getFormal(size_t n) {
+ assert(n < formals.size());
+ return formals[n];
+ }
+ const formal& getFormal(size_t n) const {
+ assert(n < formals.size());
+ return formals[n];
+ }
+
+ formal& getRest() {
+ return rest;
+ }
+ const formal& getRest() const {
+ return rest;
+ }
+
+ bool formalIsKeywordOnly(size_t n) const
+ {
+ assert(n < formals.size());
+ return n >= formals.size() - numKeywordOnly;
+ }
+
+ friend ostream& operator<< (ostream& out, const signature& s);
+
+ friend bool equivalent(const signature *s1, const signature *s2);
+
+ // Check if a signature of argument types (as opposed to formal parameters)
+ // are equivalent. Here, the arguments, if named, must have the same names,
+ // and (for simplicity) no overloaded arguments are allowed.
+ friend bool argumentEquivalent(const signature *s1, const signature *s2);
+#if 0
+ friend bool castable(signature *target, signature *source);
+ friend Int numFormalsMatch(signature *s1, signature *s2);
+#endif
+
+ size_t hash() const;
+};
+
+struct function : public ty {
+ ty *result;
+ signature sig;
+
+ function(ty *result)
+ : ty(ty_function), result(result) {}
+ function(ty *result, signature::OPEN_t)
+ : ty(ty_function), result(result), sig(signature::OPEN) {}
+ function(ty *result, signature *sig)
+ : ty(ty_function), result(result), sig(*sig) {}
+ function(ty *result, formal f1)
+ : ty(ty_function), result(result) {
+ add(f1);
+ }
+ function(ty *result, formal f1, formal f2)
+ : ty(ty_function), result(result) {
+ add(f1);
+ add(f2);
+ }
+ function(ty *result, formal f1, formal f2, formal f3)
+ : ty(ty_function), result(result) {
+ add(f1);
+ add(f2);
+ add(f3);
+ }
+ function(ty *result, formal f1, formal f2, formal f3, formal f4)
+ : ty(ty_function), result(result) {
+ add(f1);
+ add(f2);
+ add(f3);
+ add(f4);
+ }
+ virtual ~function() {}
+
+ void add(formal f) {
+ sig.add(f);
+ }
+
+ void addRest(formal f) {
+ sig.addRest(f);
+ }
+
+ virtual bool isReference() {
+ return true;
+ }
+
+ bool equiv(const ty *other) const
+ {
+ if (other->kind==ty_function) {
+ function *that=(function *)other;
+ return equivalent(this->result,that->result) &&
+ equivalent(&this->sig,&that->sig);
+ }
+ else return false;
+ }
+
+ size_t hash() const {
+ return sig.hash()*0x1231+result->hash();
+ }
+
+ void print(ostream& out) const
+ { out << *result << sig; }
+
+ void printVar (ostream& out, string name) const {
+ result->printVar(out,name);
+ out << sig;
+ }
+
+ ty *getResult() {
+ return result;
+ }
+
+ signature *getSignature() {
+ return &sig;
+ }
+
+ const signature *getSignature() const {
+ return &sig;
+ }
+
+#if 0
+ ty *stripDefaults();
+#endif
+
+ // Initialized to null.
+ trans::access *initializer();
+};
+
+// This is used in getType expressions when an overloaded variable is accessed.
+class overloaded : public ty {
+public:
+ ty_vector sub;
+
+ // Warning: The venv endScope routine relies heavily on the current
+ // implementation of overloaded.
+public:
+ overloaded()
+ : ty(ty_overloaded) {}
+ overloaded(ty *t)
+ : ty(ty_overloaded) { add(t); }
+ virtual ~overloaded() {}
+
+ bool equiv(const ty *other) const
+ {
+ for(ty_vector::const_iterator i=sub.begin();i!=sub.end();++i)
+ if (equivalent(*i,other))
+ return true;
+ return false;
+ }
+
+ size_t hash() const {
+ // Overloaded types should not be hashed.
+ assert(False);
+ return 0;
+ }
+
+ void add(ty *t) {
+ if (t->kind == ty_overloaded) {
+ overloaded *ot = (overloaded *)t;
+ copy(ot->sub.begin(), ot->sub.end(),
+ inserter(this->sub, this->sub.end()));
+ }
+ else
+ sub.push_back(t);
+ }
+
+ // Only add a type distinct from the ones currently in the overloaded type.
+ // If special is false, just the distinct signatures are added.
+ void addDistinct(ty *t, bool special=false);
+
+ // If there are less than two overloaded types, the type isn't really
+ // overloaded. This gives a more appropriate type in this case.
+ ty *simplify() {
+ switch (sub.size()) {
+ case 0:
+ return 0;
+ case 1: {
+ return sub.front();
+ }
+ default:
+ return new overloaded(*this);
+ }
+ }
+
+ // Returns the signature-less type of the set.
+ ty *signatureless();
+
+ // True if one of the subtypes is castable.
+ bool castable(ty *target, caster &c);
+
+ size_t size() const { return sub.size(); }
+
+ // Use default printing for now.
+};
+
+inline ty_iterator ty::begin() {
+ assert(this->isOverloaded());
+ return ((overloaded *)this)->sub.begin();
+}
+inline ty_iterator ty::end() {
+ return ((overloaded *)this)->sub.end();
+}
+
+// This is used to encapsulate iteration over the subtypes of an overloaded
+// type. The base method need only be implemented to handle non-overloaded
+// types.
+class collector {
+public:
+ virtual ~collector() {}
+ virtual ty *base(ty *target, ty *source) = 0;
+
+ virtual ty *collect(ty *target, ty *source) {
+ if (overloaded *o=dynamic_cast<overloaded *>(target)) {
+ ty_vector &sub=o->sub;
+
+ overloaded *oo=new overloaded;
+ for(ty_vector::iterator x = sub.begin(); x != sub.end(); ++x) {
+ types::ty *t=collect(*x, source);
+ if (t)
+ oo->add(t);
+ }
+
+ return oo->simplify();
+ }
+ else if (overloaded *o=dynamic_cast<overloaded *>(source)) {
+ ty_vector &sub=o->sub;
+
+ overloaded *oo=new overloaded;
+ for(ty_vector::iterator y = sub.begin(); y != sub.end(); ++y) {
+ // NOTE: A possible speed optimization would be to replace this with a
+ // call to base(), but this is only correct if we can guarantee that an
+ // overloaded type has no overloaded sub-types.
+ types::ty *t=collect(target, *y);
+ if (t)
+ oo->add(t);
+ }
+
+ return oo->simplify();
+ }
+ else
+ return base(target, source);
+ }
+};
+
+class tester {
+public:
+ virtual ~tester() {}
+ virtual bool base(ty *target, ty *source) = 0;
+
+ virtual bool test(ty *target, ty *source) {
+ if (overloaded *o=dynamic_cast<overloaded *>(target)) {
+ ty_vector &sub=o->sub;
+
+ for(ty_vector::iterator x = sub.begin(); x != sub.end(); ++x)
+ if (test(*x, source))
+ return true;
+
+ return false;
+ }
+ else if (overloaded *o=dynamic_cast<overloaded *>(source)) {
+ ty_vector &sub=o->sub;
+
+ for(ty_vector::iterator y = sub.begin(); y != sub.end(); ++y)
+ if (base(target, *y))
+ return true;
+
+ return false;
+ }
+ else
+ return base(target, source);
+ }
+};
+
+} // namespace types
+
+GC_DECLARE_PTRFREE(types::primitiveTy);
+GC_DECLARE_PTRFREE(types::nullTy);
+
+#endif
diff --git a/graphics/asymptote/util.cc b/graphics/asymptote/util.cc
new file mode 100644
index 0000000000..2d66fb2316
--- /dev/null
+++ b/graphics/asymptote/util.cc
@@ -0,0 +1,444 @@
+/*****
+ * util.cc
+ * John Bowman
+ *
+ * A place for useful utility functions.
+ *****/
+
+#ifdef __CYGWIN__
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <cassert>
+#include <iostream>
+#include <cstdio>
+#include <cfloat>
+#include <sstream>
+#include <cerrno>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <cstring>
+#include <algorithm>
+
+#include "util.h"
+#include "settings.h"
+#include "errormsg.h"
+#include "camperror.h"
+#include "interact.h"
+
+using namespace settings;
+
+bool False=false;
+
+namespace vm {
+void error(const char* message);
+}
+
+#if __GNUC__
+#include <cxxabi.h>
+string demangle(const char *s)
+{
+ int status;
+ char *demangled = abi::__cxa_demangle(s,NULL,NULL,&status);
+ if (status == 0 && demangled) {
+ string str(demangled);
+ free(demangled);
+ return str;
+ } else if (status == -2) {
+ free(demangled);
+ return s;
+ } else {
+ free(demangled);
+ return string("Unknown(") + s + ")";
+ }
+}
+#else
+string demangle(const char* s)
+{
+ return s;
+}
+#endif
+
+char *Strdup(string s)
+{
+ size_t size=s.size()+1;
+ char *dest=new(UseGC) char[size];
+ std::memcpy(dest,s.c_str(),size*sizeof(char));
+ return dest;
+}
+
+char *StrdupNoGC(string s)
+{
+ size_t size=s.size()+1;
+ char *dest=new char[size];
+ std::memcpy(dest,s.c_str(),size*sizeof(char));
+ return dest;
+}
+
+char *StrdupMalloc(string s)
+{
+ size_t size=s.size()+1;
+ char *dest=(char *) std::malloc(size);
+ std::memcpy(dest,s.c_str(),size*sizeof(char));
+ return dest;
+}
+
+string stripDir(string name)
+{
+ size_t p;
+#ifdef __MSDOS__
+ p=name.rfind('\\');
+ if(p < string::npos) name.erase(0,p+1);
+#endif
+ p=name.rfind('/');
+ if(p < string::npos) name.erase(0,p+1);
+ return name;
+}
+
+string stripFile(string name)
+{
+ size_t p;
+ bool dir=false;
+#ifdef __MSDOS__
+ p=name.rfind('\\');
+ if(p < string::npos) {
+ dir=true;
+ while(p > 0 && name[p-1] == '\\') --p;
+ name.erase(p+1);
+ }
+#endif
+ p=name.rfind('/');
+ if(p < string::npos) {
+ dir=true;
+ while(p > 0 && name[p-1] == '/') --p;
+ name.erase(p+1);
+ }
+
+ return dir ? name : "";
+}
+
+string stripExt(string name, const string& ext)
+{
+ string suffix="."+ext;
+ size_t p=name.rfind(suffix);
+ size_t n=suffix.length();
+ if(n == 1 || p == name.length()-n)
+ return name.substr(0,p);
+ else return name;
+}
+
+void backslashToSlash(string& s)
+{
+ size_t p;
+ while((p=s.find('\\')) < string::npos)
+ s[p]='/';
+}
+
+void spaceToUnderscore(string& s)
+{
+ size_t p;
+ while((p=s.find(' ')) < string::npos)
+ s[p]='_';
+}
+
+string Getenv(const char *name, bool msdos)
+{
+ char *s=getenv(name);
+ if(!s) return "";
+ string S=string(s);
+ if(msdos) backslashToSlash(S);
+ return S;
+}
+
+void writeDisabled()
+{
+ camp::reportError("Write to other directories disabled; override with option -globalwrite");
+}
+
+string cleanpath(string name)
+{
+ string dir=stripFile(name);
+ name=stripDir(name);
+ spaceToUnderscore(name);
+ return dir+name;
+}
+
+string outpath(string name)
+{
+ bool global=globalwrite();
+ string dir=stripFile(name);
+ if(global && !dir.empty()) return name;
+ string outdir=stripFile(outname());
+ if(!(global || dir.empty() || dir == outdir)) writeDisabled();
+ return outdir+stripDir(name);
+}
+
+string buildname(string name, string suffix, string aux)
+{
+ name=stripExt(outpath(name),defaultformat())+aux;
+ if(!suffix.empty()) name += "."+suffix;
+ return name;
+}
+
+string auxname(string filename, string suffix)
+{
+ return buildname(filename,suffix,"_");
+}
+
+sighandler_t Signal(int signum, sighandler_t handler)
+{
+ struct sigaction action,oldaction;
+ action.sa_handler=handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags=0;
+ return sigaction(signum,&action,&oldaction) == 0 ? oldaction.sa_handler :
+ SIG_ERR;
+}
+
+void push_split(mem::vector<string>& a, const string& S)
+{
+ const char *p=S.c_str();
+ string s;
+ char c;
+ while((c=*(p++))) {
+ if(c == ' ') {
+ if(s.size() > 0) {
+ a.push_back(s);
+ s.clear();
+ }
+ } else s += c;
+ }
+ if(s.size() > 0)
+ a.push_back(s);
+}
+
+char **args(const mem::vector<string>& s, bool quiet)
+{
+ size_t count=s.size();
+
+ char **argv=NULL;
+ argv=new char*[count+1];
+ for(size_t i=0; i < count; ++i)
+ argv[i]=StrdupNoGC(s[i]);
+
+ if(!quiet && settings::verbose > 1) {
+ cerr << argv[0];
+ for(size_t i=1; i < count; ++i) cerr << " " << argv[i];
+ cerr << endl;
+ }
+
+ argv[count]=NULL;
+ return argv;
+}
+
+void execError(const char *command, const char *hint, const char *application)
+{
+ cerr << "Cannot execute " << command << endl;
+ if(*application == 0) application=hint;
+ if(hint) {
+ string s=string(hint);
+ transform(s.begin(), s.end(), s.begin(), toupper);
+ cerr << "Please put in a file " << getSetting<string>("config")
+ << ": " << endl << endl
+ << "import settings;" << endl
+ << hint << "=\"LOCATION\";" << endl << endl
+ << "where LOCATION specifies the location of "
+ << application << "." << endl << endl
+ << "Alternatively, set the environment variable ASYMPTOTE_" << s
+ << endl << "or use the command line option -" << hint
+ << "=\"LOCATION\". For further details, see" << endl
+ << "http://asymptote.sourceforge.net/doc/Configuring.html" << endl
+ << "http://asymptote.sourceforge.net/doc/Search-paths.html" << endl;
+ }
+}
+
+// quiet: 0=none; 1=suppress stdout; 2=suppress stdout+stderr.
+int System(const mem::vector<string> &command, int quiet, bool wait,
+ const char *hint, const char *application, int *ppid)
+{
+ int status;
+
+ cout.flush(); // Flush stdout to avoid duplicate output.
+
+ char **argv=args(command);
+
+ int pid=fork();
+ if(pid == -1)
+ camp::reportError("Cannot fork process");
+
+ if(pid == 0) {
+ if(interact::interactive) signal(SIGINT,SIG_IGN);
+ if(quiet) {
+ static int null=creat("/dev/null",O_WRONLY);
+ close(STDOUT_FILENO);
+ dup2(null,STDOUT_FILENO);
+ if(quiet == 2) {
+ close(STDERR_FILENO);
+ dup2(null,STDERR_FILENO);
+ }
+ }
+ if(argv) {
+ execvp(argv[0],argv);
+ execError(argv[0],hint,application);
+ _exit(-1);
+ }
+ }
+
+ if(ppid) *ppid=pid;
+ for(;;) {
+ if(waitpid(pid, &status, wait ? 0 : WNOHANG) == -1) {
+ if(errno == ECHILD) return 0;
+ if(errno != EINTR) {
+ if(quiet < 2) {
+ ostringstream msg;
+ msg << "Command failed: ";
+ for(size_t i=0; i < command.size(); ++i) msg << command[i] << " ";
+ camp::reportError(msg);
+ }
+ }
+ } else {
+ if(!wait) return 0;
+ if(WIFEXITED(status)) {
+ if(argv) {
+ char **p=argv;
+ char *s;
+ while((s=*(p++)) != NULL)
+ delete [] s;
+ delete [] argv;
+ }
+ return WEXITSTATUS(status);
+ } else {
+ if(quiet < 2) {
+ ostringstream msg;
+ msg << "Command exited abnormally: ";
+ for(size_t i=0; i < command.size(); ++i) msg << command[i] << " ";
+ camp::reportError(msg);
+ }
+ }
+ }
+ }
+}
+
+string stripblanklines(const string& s)
+{
+ string S=string(s);
+ bool blank=true;
+ const char *t=S.c_str();
+ size_t len=S.length();
+
+ for(size_t i=0; i < len; i++) {
+ if(t[i] == '\n') {
+ if(blank) S[i]=' ';
+ else blank=true;
+ } else if(t[i] != '\t' && t[i] != ' ') blank=false;
+ }
+ return S;
+}
+
+char *startpath=NULL;
+
+void noPath()
+{
+ camp::reportError("Cannot get current path");
+}
+
+char *getPath(char *p)
+{
+#ifdef MAXPATHLEN
+ static size_t size = MAXPATHLEN;
+#else
+ static size_t size = 1024;
+#endif
+ if(!p) p=new(UseGC) char[size];
+ if(!p) noPath();
+ else while(getcwd(p,size) == NULL) {
+ if(errno == ERANGE) {
+ size *= 2;
+ p=new(UseGC) char[size];
+ } else {noPath(); p=NULL;}
+ }
+ return p;
+}
+
+const char *setPath(const char *s, bool quiet)
+{
+ if(startpath == NULL) startpath=getPath(startpath);
+ if(s == NULL || *s == 0) s=startpath;
+ int rc=chdir(s);
+ if(rc != 0) {
+ ostringstream buf;
+ buf << "Cannot change to directory '" << s << "'";
+ camp::reportError(buf);
+ }
+ char *p=getPath();
+ if(p && (!interact::interactive || quiet) && verbose > 1)
+ cout << "cd " << p << endl;
+ return p;
+}
+
+void push_command(mem::vector<string>& a, const string& s)
+{
+ a.push_back(s);
+#ifdef __MSDOS__
+ if(s == "cmd") {
+ a.push_back("/c");
+ a.push_back("start");
+ a.push_back("\"\"");
+ }
+#endif
+}
+
+void popupHelp() {
+ // If the popped-up help is already running, pid stores the pid of the viewer.
+ static int pid=0;
+
+ // Status is ignored.
+ static int status=0;
+
+ // If the help viewer isn't running (or its last run has termined), launch the
+ // viewer again.
+ if (pid==0 || (waitpid(pid, &status, WNOHANG) == pid)) {
+ mem::vector<string> cmd;
+ push_command(cmd,getSetting<string>("pdfviewer"));
+ string viewerOptions=getSetting<string>("pdfviewerOptions");
+ if(!viewerOptions.empty())
+ cmd.push_back(viewerOptions);
+ cmd.push_back(docdir+dirsep+"asymptote.pdf");
+ status=System(cmd,0,false,"pdfviewer","your PDF viewer",&pid);
+ }
+}
+
+const char *intrange="integer argument is outside valid range";
+const char *uintrange="integer argument is outside valid unsigned range";
+
+unsigned unsignedcast(Int n)
+{
+ if(n < 0 || n/2 > INT_MAX)
+ vm::error(uintrange);
+ return (unsigned) n;
+}
+
+unsignedInt unsignedIntcast(Int n)
+{
+ if(n < 0)
+ vm::error(uintrange);
+ return (unsignedInt) n;
+}
+
+int intcast(Int n)
+{
+ if(Abs(n) > INT_MAX)
+ vm::error(intrange);
+ return (int) n;
+}
+
+Int Intcast(unsignedInt n)
+{
+ if(n > (unsignedInt) Int_MAX)
+ vm::error(intrange);
+ return (Int) n;
+}
diff --git a/graphics/asymptote/util.h b/graphics/asymptote/util.h
new file mode 100644
index 0000000000..4414a6de1b
--- /dev/null
+++ b/graphics/asymptote/util.h
@@ -0,0 +1,163 @@
+/*****
+ * util.h
+ * Andy Hammerlindl 2004/05/10
+ *
+ * A place for useful utility functions.
+ *****/
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <sys/types.h>
+#include <iostream>
+#include <cstdlib>
+
+#ifdef __CYGWIN__
+extern "C" int sigaddset(sigset_t *set, int signum);
+extern "C" int sigemptyset(sigset_t *set);
+extern "C" int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
+#endif
+
+#include <csignal>
+
+#include "common.h"
+
+#include <strings.h>
+
+// Demangle a typeid name (if the proper library is installed.
+string demangle(const char *s);
+
+// Duplicate a string.
+char *Strdup(string s);
+char *StrdupNoGC(string s);
+char *StrdupMalloc(string s);
+
+// Strip the directory from a filename.
+string stripDir(string name);
+
+// Strip the file from a filename, returning the directory.
+string stripFile(string name);
+
+// Strip the extension from a filename.
+string stripExt(string name, const string& suffix="");
+
+void writeDisabled();
+
+// Replace spaces in file part of name with underscores.
+string cleanpath(string name);
+
+// Construct the full output path.
+string outpath(string name);
+
+// Construct a filename from the original, adding aux at the end, and
+// changing the suffix.
+string buildname(string filename, string suffix="", string aux="");
+
+// Construct an alternate filename for a temporary file in the current
+// directory.
+string auxname(string filename, string suffix="");
+
+// Cast argument to a string.
+template<class T>
+string String(T x)
+{
+ ostringstream buf;
+ buf << x;
+ return buf.str();
+}
+
+typedef void (*sighandler_t)(int);
+
+// Portable signal (sigaction wrapper).
+sighandler_t Signal(int signum, sighandler_t handler);
+
+// Split string S and push the pieces onto vector a.
+void push_split(mem::vector<string>& a, const string& S);
+
+// Wrapper to append /c start "" to MSDOS cmd.
+void push_command(mem::vector<string>& a, const string& s);
+
+// Return an argv array corresponding to the fields in command delimited
+// by spaces not within matching single quotes.
+char **args(const mem::vector<string> &args, bool quiet=false);
+
+// Similar to the standard system call except allows interrupts and does
+// not invoke a shell.
+int System(const mem::vector<string> &command, int quiet=0, bool wait=true,
+ const char *hint=NULL, const char *application="",
+ int *pid=NULL);
+
+#if defined(__DECCXX_LIBCXX_RH70)
+extern "C" char *strsignal(int sig);
+extern "C" double asinh(double x);
+extern "C" double acosh(double x);
+extern "C" double atanh(double x);
+extern "C" double cbrt(double x);
+extern "C" double erf(double x);
+extern "C" double erfc(double x);
+extern "C" double tgamma(double x);
+extern "C" double remainder(double x, double y);
+extern "C" double hypot(double x, double y) throw();
+extern "C" double jn(Int n, double x);
+extern "C" double yn(Int n, double x);
+extern "C" int isnan(double);
+#endif
+
+
+#if defined(__DECCXX_LIBCXX_RH70) || defined(__CYGWIN__)
+extern "C" int usleep(useconds_t);
+extern "C" int kill(pid_t pid, int sig) throw();
+extern "C" int snprintf(char *str, size_t size, const char *format,...);
+#include <stdio.h>
+extern "C" FILE *fdopen(int fd, const char *mode);
+extern "C" int fileno(FILE *);
+extern "C" char *strptime(const char *s, const char *format, struct tm *tm);
+extern "C" int setenv(const char *name, const char *value, int overwrite);
+extern "C" int unsetenv(const char *name);
+#endif
+
+extern bool False;
+
+// Strip blank lines (which would break the bidirectional TeX pipe)
+string stripblanklines(const string& s);
+
+const char *startPath();
+const char* setPath(const char *s, bool quiet=false);
+const char *changeDirectory(const char *s);
+extern char *startpath;
+
+void backslashToSlash(string& s);
+void spaceToUnderscore(string& s);
+string Getenv(const char *name, bool msdos);
+char *getPath(char *p=NULL);
+
+void execError(const char *command, const char *hint, const char *application);
+
+// This invokes a viewer to display the manual. Subsequent calls will only
+// pop-up a new viewer if the old one has been closed.
+void popupHelp();
+
+#ifdef __CYGWIN__
+inline long long llabs(long long x) {return x >= 0 ? x : -x;}
+extern "C" char *initstate (unsigned seed, char *state, size_t size);
+extern "C" long random (void);
+#endif
+
+inline Int Abs(Int x) {
+#ifdef HAVE_LONG_LONG
+ return llabs(x);
+#else
+#ifdef HAVE_LONG
+ return labs(x);
+#else
+ return abs(x);
+#endif
+#endif
+}
+
+unsigned unsignedcast(Int n);
+unsignedInt unsignedIntcast(Int n);
+int intcast(Int n);
+Int Intcast(unsignedInt n);
+
+#endif
diff --git a/graphics/asymptote/varinit.cc b/graphics/asymptote/varinit.cc
new file mode 100644
index 0000000000..e84c62bb7e
--- /dev/null
+++ b/graphics/asymptote/varinit.cc
@@ -0,0 +1,80 @@
+/*****
+ * varinit.cc
+ * Andy Hammerlindl 2005/07/01
+ *
+ * Variable initializer are syntax that finish code such as
+ * int var = ...
+ * As such, they are translated to yield a certain type, the type of the
+ * variable. Expressions are a special case that can be translated without an
+ * associated variable or its type.
+ *****/
+
+#include "varinit.h"
+#include "coenv.h"
+#include "runtime.h"
+#include "runarray.h"
+
+namespace absyntax {
+
+using namespace types;
+using namespace trans;
+
+void definit::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "definit",indent);
+}
+
+void definit::transToType(coenv &e, types::ty *target)
+{
+ if (target->kind != ty_error) {
+ access *a=e.e.lookupInitializer(target);
+
+ if (a)
+ a->encode(CALL, getPos(), e.c);
+ else {
+ em.error(getPos());
+ em << "no default initializer for type '" << *target << "'";
+ }
+ }
+}
+
+void arrayinit::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "arrayinit",indent);
+
+ for (mem::list<varinit *>::iterator p = inits.begin(); p != inits.end(); ++p)
+ (*p)->prettyprint(out, indent+2);
+ if (rest)
+ rest->prettyprint(out, indent+1);
+}
+
+void arrayinit::transMaker(coenv &e, Int size, bool rest) {
+ // Push the number of cells and call the array maker.
+ e.c.encode(inst::intpush, size);
+ e.c.encode(inst::builtin, rest ? run::newAppendedArray :
+ run::newInitializedArray);
+}
+
+void arrayinit::transToType(coenv &e, types::ty *target)
+{
+ types::ty *celltype;
+ if (target->kind != types::ty_array) {
+ em.error(getPos());
+ em << "array initializer used for non-array";
+ celltype = types::primError();
+ }
+ else {
+ celltype = ((types::array *)target)->celltype;
+ }
+
+ // Push the values on the stack.
+ for (mem::list<varinit *>::iterator p = inits.begin(); p != inits.end(); ++p)
+ (*p)->transToType(e, celltype);
+
+ if (rest)
+ rest->transToType(e, target);
+
+ transMaker(e, (Int)inits.size(), (bool)rest);
+}
+
+} // namespace absyntax
diff --git a/graphics/asymptote/varinit.h b/graphics/asymptote/varinit.h
new file mode 100644
index 0000000000..721242dac2
--- /dev/null
+++ b/graphics/asymptote/varinit.h
@@ -0,0 +1,87 @@
+/*****
+ * varinit.h
+ * Andy Hammerlindl 2005/07/01
+ *
+ * Variable initializers are syntax that finish code such as
+ * Int var = ...
+ * As such, they are translated to yield a certain type, the type of the
+ * variable. Expressions are a special case that can be translated without an
+ * associated variable or its type.
+ *****/
+
+#ifndef VARINIT_H
+#define VARINIT_H
+
+#include "types.h"
+#include "symbol.h"
+#include "absyn.h"
+
+namespace absyntax {
+
+using trans::coenv;
+using trans::access;
+using sym::symbol;
+using types::array;
+
+class varinit : public absyn {
+public:
+ varinit(position pos)
+ : absyn(pos) {}
+
+ // This determines what instruction are needed to put the associated
+ // value onto the stack, then adds those instructions to the current
+ // lambda in e.
+ // In some expressions and initializers, the target type needs to be
+ // known in order to translate properly. For most expressions, this is
+ // kept to a minimum.
+ // For expression, this also allows an implicit cast, hence the name.
+ virtual void transToType(coenv &e, types::ty *target) = 0;
+};
+
+// A default initializer. For example:
+// int a;
+// is in some sense equivalent to
+// int a=0;
+// where the definit for Int is a function that returns 0.
+class definit : public varinit {
+public:
+ definit(position pos)
+ : varinit(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transToType(coenv &e, types::ty *target);
+};
+
+class arrayinit : public varinit {
+ mem::list<varinit *> inits;
+
+ varinit *rest;
+public:
+ arrayinit(position pos)
+ : varinit(pos), rest(0) {}
+
+ virtual ~arrayinit()
+ {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Encodes the instructions to make an array from size elements on the stack.
+ static void transMaker(coenv &e, Int size, bool rest);
+
+ void transToType(coenv &e, types::ty *target);
+
+ void add(varinit *init) {
+ inits.push_back(init);
+ }
+
+ void addRest(varinit *init) {
+ rest=init;
+ }
+
+ friend class joinExp;
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/graphics/asymptote/virtualfieldaccess.cc b/graphics/asymptote/virtualfieldaccess.cc
new file mode 100644
index 0000000000..aed130f33a
--- /dev/null
+++ b/graphics/asymptote/virtualfieldaccess.cc
@@ -0,0 +1,45 @@
+/*****
+ * virtualfieldaccess.cc
+ * Andy Hammerlindl 2009/07/23
+ *
+ * Implements the access subclass used to read and write virtual fields.
+ *****/
+
+#include "virtualfieldaccess.h"
+#include "coder.h"
+
+namespace trans {
+
+void virtualFieldAccess::encode(action act, position pos, coder &e)
+{
+ switch(act) {
+ case CALL:
+ if (caller) {
+ caller->encode(CALL, pos, e);
+ } else {
+ this->encode(READ, pos, e);
+ e.encode(inst::popcall);
+ }
+ return;
+ case READ:
+ assert(getter);
+ getter->encode(CALL, pos, e);
+ return;
+ case WRITE:
+ if (setter)
+ setter->encode(CALL, pos, e);
+ else {
+ em.error(pos);
+ em << "virtual field is read-only";
+ }
+ return;
+ }
+}
+
+void virtualFieldAccess::encode(action act, position pos, coder &e, frame *)
+{
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+} // namespace trans
diff --git a/graphics/asymptote/virtualfieldaccess.h b/graphics/asymptote/virtualfieldaccess.h
new file mode 100644
index 0000000000..048e4e6b6a
--- /dev/null
+++ b/graphics/asymptote/virtualfieldaccess.h
@@ -0,0 +1,62 @@
+/*****
+ * virtualfieldaccess.h
+ * Andy Hammerlindl 2009/07/23
+ *
+ * Implements the access subclass used to read and write virtual fields.
+ *****/
+
+#include "access.h"
+
+namespace trans {
+// In code such as
+// pair z; write(z.x);
+// to evaluate the expression z.x, first z is pushed onto the stack, then as
+// it is not a record, instead of accessing its field in the usual way for a
+// record, a builtin function is called which pops z off the stack and
+// replaces it with z.x. virtualFieldAccess provides the access for the
+// virtualField 'x', and 'getter' is the access to the builtin function which
+// replaces z with z.x.
+//
+// If the virtual field z.x were mutable, then setter would access a builtin
+// function, which pops a real number and then z off of the stack, sets the
+// z.x to that new value, and puts the value back on the stack. In this case,
+// pairs are immutable, but other virtual fields may not be.
+//
+// Some virtual fields are functions, such as a.push for an array a. In rare
+// cases, code such as
+// void f(int) = a.push;
+// requires an object representing a.push, and so a getter for the field must
+// be provided. Most of the time, however, these fields are just called.
+// As an optimization, a caller access can be provided. If this access is
+// given, then a call to the virtualFieldAccess just translates into a call to
+// caller.
+class virtualFieldAccess : public access {
+ access *getter;
+ access *setter;
+ access *caller;
+
+public:
+ virtualFieldAccess(access *getter,
+ access *setter = 0,
+ access *caller = 0)
+ : getter(getter), setter(setter) {}
+
+ virtualFieldAccess(vm::bltin getter,
+ vm::bltin setter = 0,
+ vm::bltin caller = 0)
+ : getter(new bltinAccess(getter)),
+ setter(setter ? new bltinAccess(setter) : 0),
+ caller(caller ? new bltinAccess(caller) : 0) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+
+ // Attempting to WRITE a read-only field will give an error, but if the
+ // error is caught at a higher level, a better error message (including the
+ // name of the field) can be given. This function allows such handling.
+ bool readonly() {
+ return (bool)setter;
+ }
+};
+
+} // namespace trans
diff --git a/graphics/asymptote/vm.h b/graphics/asymptote/vm.h
new file mode 100644
index 0000000000..2ba55dfa15
--- /dev/null
+++ b/graphics/asymptote/vm.h
@@ -0,0 +1,39 @@
+/*****
+ * vm.h
+ * Tom Prince 2005/06/17
+ *
+ * Interface to the virtual machine.
+ *****/
+
+#ifndef VM_H
+#define VM_H
+
+#include "errormsg.h"
+
+namespace vm {
+
+struct lambda; class stack;
+typedef void (*bltin)(stack *s);
+
+#ifdef DEBUG_BLTIN
+// This associates names to bltin functions, so that the output of 'asy -s'
+// can print the names of the bltin functions that appear in the bytecode.
+void registerBltin(bltin b, string s);
+string lookupBltin(bltin b);
+
+#define REGISTER_BLTIN(b, s) \
+ registerBltin((b), (s))
+#else
+#define REGISTER_BLTIN(b, s)
+#endif
+
+void run(lambda *l);
+position getPos();
+
+void errornothrow(const char* message);
+void error(const char* message);
+void error(const ostringstream& message);
+
+} // namespace vm
+
+#endif // VM_H
diff --git a/graphics/asymptote/wce b/graphics/asymptote/wce
new file mode 100755
index 0000000000..4ace1b3563
--- /dev/null
+++ b/graphics/asymptote/wce
@@ -0,0 +1,11 @@
+#!/bin/sh
+printf "Testing errors..."
+./asy -sysdir base -noautoplain -debug errortest 2> errors.temp
+result=`diff errors.temp errors`
+if test "$result" = ""; then
+echo PASSED.
+else
+echo FAILED.
+echo "$result"
+exit 1
+fi
diff --git a/graphics/asymptote/webgl/WebGLfooter.html b/graphics/asymptote/webgl/WebGLfooter.html
new file mode 100644
index 0000000000..043713cd25
--- /dev/null
+++ b/graphics/asymptote/webgl/WebGLfooter.html
@@ -0,0 +1,17 @@
+ </script>
+
+</head>
+
+
+<body onload="webGLStart();">
+ <script type="text/javascript" id="eventfunc">
+ // forceredraw = true;
+ function processloop(deltams) {
+ // enter arbitrary processing event here
+ // if one wants to modify the object per tick.
+ }
+ </script>
+ <canvas id="Asymptote" style="border: none;" width="800" height="800" />
+</body>
+
+</html>
diff --git a/graphics/asymptote/webgl/WebGLheader.html b/graphics/asymptote/webgl/WebGLheader.html
new file mode 100644
index 0000000000..98fa24ec32
--- /dev/null
+++ b/graphics/asymptote/webgl/WebGLheader.html
@@ -0,0 +1,172 @@
+<html>
+
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+
+ <script id="shader-fs" type="x-shader/x-fragment">#version 300 es
+ precision mediump float;
+
+ in vec4 vColor;
+ in vec3 vNormal;
+ out vec4 outColor;
+
+ flat in int vMaterialIndex;
+
+ // can also construct an alternative shader,
+ // but would require more work.
+ // FIXME: An ad-hoc solution is to use uniforms...
+ uniform int useColor;
+
+ struct Material {
+ vec4 baseColor, emissive, specular;
+ float roughness, metallic, f0;
+ };
+
+ uniform mat4 uMMatrix; // model matrix
+ uniform mat4 uPMatrix; // projection matrix
+ uniform mat4 uVMatrix; // view matrix
+
+ uniform Material objMaterial[100]; // assuming we are doing multiple materials,
+
+ // we can upload them one at a time per call.
+ // but, we can also make it an array + pass in an index,
+ // say uniform Material objMaterial[$nmat];
+
+ // or, even use Uniform Buffer Objects...
+
+ // type, for now
+ #define POINT_LIGHT 1
+ #define DIRECTIONAL_LIGHT 2
+
+ // for direction, parameter is direction
+ // for point light, parameter is position (in homoeg coords?)
+ // are these given in world coords, or view coords? - I can do both
+ struct Light {
+ int type;
+ vec3 color;
+ float brightness;
+ vec4 parameter;
+ };
+
+ uniform int unLights; // can be replaced by a constant, or even a fixed array in the final release.
+ uniform Light objLights[100]; // again, can be set at will by the asy generator.
+
+ float NDF_TRG(vec3 halfv, vec3 normal, float roughness) {
+ float ndoth=max(dot(normal, halfv), 0.0);
+ float alpha2=roughness*roughness;
+
+ float denom=pow(ndoth*ndoth*(alpha2-1.0)+1.0, 2.0);
+ return alpha2/denom;
+ }
+
+ float GGX_Geom(vec3 v, vec3 normal, float roughness) {
+ float ndotv=max(dot(v, normal), 0.0);
+ float ap=pow((1.0+roughness), 2.0);
+ float k=ap/8.0;
+
+ return ndotv/((ndotv*(1.0-k))+k);
+ }
+
+ float Geom(vec3 v, vec3 l, vec3 normal, float roughness) {
+ return GGX_Geom(v,normal,roughness)*GGX_Geom(l,normal,roughness);
+ }
+
+ float Fresnel(vec3 h, vec3 v, float f0) {
+ float hdotv=max(dot(h,v), 0.0);
+ return f0+(1.0-f0)*pow((1.0-hdotv),5.0);
+ }
+
+ // physical based shading using UE4 model.
+ vec3 physBDRF(Material material, vec3 normal, vec3 lightdir, vec3 lookdir) {
+ vec3 lambertian=material.baseColor.rgb;
+ vec3 h=normalize(lightdir+lookdir);
+ float omegain=max(dot(lookdir, normal), 0.0);
+ float omegali=max(dot(lightdir, normal), 0.0);
+
+ float D=NDF_TRG(h, normal, material.roughness*material.roughness);
+ float G=Geom(lookdir, lightdir, normal, material.roughness*material.roughness);
+ float F=Fresnel(h, lookdir, material.f0);
+
+ float denom=4.0*omegain*omegali;
+ if (denom == 0.0) {return vec3(0,0,0); }
+
+ float rawrefl=(D*G) / denom;
+
+ vec3 dielectric=mix(lambertian, rawrefl*material.specular.rgb, F);
+ vec3 metal=rawrefl*material.baseColor.rgb;
+
+ return mix(dielectric, metal, material.metallic);
+ }
+
+ void main(void)
+ {
+ // change later.
+
+ // assuming for now that the headlamp is always on.
+ // light dir=+Z, viewDir=+Z,
+
+ float normalSign = gl_FrontFacing ? 1.0 : -1.0;
+
+ vec3 normal=normalSign*normalize(vNormal);
+ vec3 Z=vec3(0,0,1.0);
+ vec3 rawCol = vec3(0.0);
+
+ Material m=objMaterial[vMaterialIndex];
+
+ if (useColor == 1) {
+ m.baseColor = vColor;
+ }
+
+ for (int i=0;i<unLights;++i) {
+ Light Li=objLights[i];
+ float cosTheta = 0.0;
+ float atteunation = 1.0;
+ vec3 lightDirection = vec3(0.0);
+ if (Li.type == DIRECTIONAL_LIGHT) {
+ lightDirection = Li.parameter.xyz;
+ cosTheta = max(dot(normal, lightDirection), 0.0);
+ }
+ vec3 radiance = cosTheta * Li.color * Li.brightness;
+ rawCol += physBDRF(m, normal, lightDirection, Z) * radiance;
+ }
+ outColor=vec4(rawCol,1);
+ }
+ </script>
+
+ <script id="shader-vs" type="x-shader/x-vertex">#version 300 es
+ precision mediump float;
+ in vec3 aVertexPosition;
+ in vec4 aVertexColor;
+ in vec3 aVertexNormal;
+ in int aVertexMaterialIndex;
+
+ uniform mat4 uMMatrix; // model matrix
+ uniform mat4 uPMatrix; // projection matrix
+ uniform mat4 uVMatrix; // view matrix
+
+ out vec4 vColor;
+ out vec3 vNormal;
+ flat out int vMaterialIndex;
+
+ mat4 invdual(mat4 invec) {
+ return inverse(transpose(invec));
+ }
+ void main(void) {
+ gl_Position=uPMatrix*uVMatrix*uMMatrix*vec4(aVertexPosition,1.0);
+
+ mat4 invdualmat=invdual(uVMatrix*uMMatrix);
+ vec4 rawNormal=invdualmat*vec4(aVertexNormal, 0);
+
+ vNormal=normalize(rawNormal.xyz);
+
+ vColor=aVertexColor;
+ vMaterialIndex=aVertexMaterialIndex;
+ }
+
+ </script>
+
+ <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/gl-matrix-min-2.3.2.js"></script>
+ <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/glm-js-min-2.2.2.js"></script>
+ <script type="text/javascript" src="https://vectorgraphics.github.io/asymptote/webgl/arcball-min-0.01.js"></script>
+ <script type="text/javascript" src="gl.js"></script>
+ <script type="text/javascript">
diff --git a/graphics/asymptote/webgl/arcball-0.01.js b/graphics/asymptote/webgl/arcball-0.01.js
new file mode 100644
index 0000000000..db6da0f81a
--- /dev/null
+++ b/graphics/asymptote/webgl/arcball-0.01.js
@@ -0,0 +1,67 @@
+// double, double => rotation matrix
+// require https://cdn.rawgit.com/humbletim/glm-js/31fd034b/build/glm-js.min.js
+
+
+var arcballLib = {
+ arcball: function(oldmouse, newmouse) {
+ let oldMouseNew = [0, 0, 0];
+ let newMouseNew = [0, 0, 0];
+
+ let testNorm = this.twonorm(oldmouse);
+ if (testNorm > 1) {
+ oldMouseNew[0] = oldmouse[0] / testNorm;
+ oldMouseNew[1] = oldmouse[1] / testNorm;
+ } else {
+ oldMouseNew[0] = oldmouse[0];
+ oldMouseNew[1] = oldmouse[1];
+ }
+
+ let testNorm2 = this.twonorm(newmouse);
+ if (testNorm2 > 1) {
+ newMouseNew[0] = newmouse[0] / testNorm2;
+ newMouseNew[1] = newmouse[1] / testNorm2;
+ } else {
+ newMouseNew[0] = newmouse[0];
+ newMouseNew[1] = newmouse[1];
+ }
+
+ var z1squared = 1 - (oldMouseNew[1] ** 2) - (oldMouseNew[0] ** 2);
+ if (z1squared < 0 && z1squared > -0.00001) {
+ z1squared = 0;
+ }
+
+ var z2squared = 1 - (newMouseNew[1] ** 2) - (newMouseNew[0] ** 2);
+ if (z2squared < 0 && z2squared > -0.00001) {
+ z2squared = 0;
+ }
+
+
+ oldMouseNew[2] = Math.sqrt(z1squared);
+ newMouseNew[2] = Math.sqrt(z2squared);
+
+ if (isNaN(oldMouseNew[2]) || isNaN(newMouseNew[2])) {
+
+ alert('Error!');
+ }
+
+
+ let oldMouseVec = glm.vec3(...oldMouseNew);
+ let newMouseVec = glm.vec3(...newMouseNew);
+ let axis = glm.normalize(glm.cross(oldMouseVec, newMouseVec));
+
+ // console.log(axis[0], axis[1], axis[2]);
+
+ let angle = Math.acos(glm.dot(oldMouseVec, newMouseVec));
+
+ return [angle, axis]
+
+ },
+
+ twonorm: function(v) {
+ let normSq = 0
+ for (let i = 0; i < v.length; i++) {
+ normSq += (v[i] ** 2);
+ }
+ return Math.sqrt(normSq);
+ }
+} \ No newline at end of file
diff --git a/graphics/asymptote/webgl/arcball-min-0.01.js b/graphics/asymptote/webgl/arcball-min-0.01.js
new file mode 100644
index 0000000000..9efc72fa4d
--- /dev/null
+++ b/graphics/asymptote/webgl/arcball-min-0.01.js
@@ -0,0 +1 @@
+var arcballLib={arcball:function(oldmouse,newmouse){let oldMouseNew=[0,0,0];let newMouseNew=[0,0,0];let testNorm=this.twonorm(oldmouse);if(testNorm>1){oldMouseNew[0]=oldmouse[0]/testNorm;oldMouseNew[1]=oldmouse[1]/testNorm}else{oldMouseNew[0]=oldmouse[0];oldMouseNew[1]=oldmouse[1]}let testNorm2=this.twonorm(newmouse);if(testNorm2>1){newMouseNew[0]=newmouse[0]/testNorm2;newMouseNew[1]=newmouse[1]/testNorm2}else{newMouseNew[0]=newmouse[0];newMouseNew[1]=newmouse[1]}var z1squared=1-oldMouseNew[1]**2-oldMouseNew[0]**2;if(z1squared<0&&z1squared>-1e-5){z1squared=0}var z2squared=1-newMouseNew[1]**2-newMouseNew[0]**2;if(z2squared<0&&z2squared>-1e-5){z2squared=0}oldMouseNew[2]=Math.sqrt(z1squared);newMouseNew[2]=Math.sqrt(z2squared);if(isNaN(oldMouseNew[2])||isNaN(newMouseNew[2])){alert("Error!")}let oldMouseVec=glm.vec3(...oldMouseNew);let newMouseVec=glm.vec3(...newMouseNew);let axis=glm.normalize(glm.cross(oldMouseVec,newMouseVec));let angle=Math.acos(glm.dot(oldMouseVec,newMouseVec));return[angle,axis]},twonorm:function(v){let normSq=0;for(let i=0;i<v.length;i++){normSq+=v[i]**2}return Math.sqrt(normSq)}}; \ No newline at end of file
diff --git a/graphics/asymptote/webgl/arcball.js b/graphics/asymptote/webgl/arcball.js
new file mode 100644
index 0000000000..db6da0f81a
--- /dev/null
+++ b/graphics/asymptote/webgl/arcball.js
@@ -0,0 +1,67 @@
+// double, double => rotation matrix
+// require https://cdn.rawgit.com/humbletim/glm-js/31fd034b/build/glm-js.min.js
+
+
+var arcballLib = {
+ arcball: function(oldmouse, newmouse) {
+ let oldMouseNew = [0, 0, 0];
+ let newMouseNew = [0, 0, 0];
+
+ let testNorm = this.twonorm(oldmouse);
+ if (testNorm > 1) {
+ oldMouseNew[0] = oldmouse[0] / testNorm;
+ oldMouseNew[1] = oldmouse[1] / testNorm;
+ } else {
+ oldMouseNew[0] = oldmouse[0];
+ oldMouseNew[1] = oldmouse[1];
+ }
+
+ let testNorm2 = this.twonorm(newmouse);
+ if (testNorm2 > 1) {
+ newMouseNew[0] = newmouse[0] / testNorm2;
+ newMouseNew[1] = newmouse[1] / testNorm2;
+ } else {
+ newMouseNew[0] = newmouse[0];
+ newMouseNew[1] = newmouse[1];
+ }
+
+ var z1squared = 1 - (oldMouseNew[1] ** 2) - (oldMouseNew[0] ** 2);
+ if (z1squared < 0 && z1squared > -0.00001) {
+ z1squared = 0;
+ }
+
+ var z2squared = 1 - (newMouseNew[1] ** 2) - (newMouseNew[0] ** 2);
+ if (z2squared < 0 && z2squared > -0.00001) {
+ z2squared = 0;
+ }
+
+
+ oldMouseNew[2] = Math.sqrt(z1squared);
+ newMouseNew[2] = Math.sqrt(z2squared);
+
+ if (isNaN(oldMouseNew[2]) || isNaN(newMouseNew[2])) {
+
+ alert('Error!');
+ }
+
+
+ let oldMouseVec = glm.vec3(...oldMouseNew);
+ let newMouseVec = glm.vec3(...newMouseNew);
+ let axis = glm.normalize(glm.cross(oldMouseVec, newMouseVec));
+
+ // console.log(axis[0], axis[1], axis[2]);
+
+ let angle = Math.acos(glm.dot(oldMouseVec, newMouseVec));
+
+ return [angle, axis]
+
+ },
+
+ twonorm: function(v) {
+ let normSq = 0
+ for (let i = 0; i < v.length; i++) {
+ normSq += (v[i] ** 2);
+ }
+ return Math.sqrt(normSq);
+ }
+} \ No newline at end of file
diff --git a/graphics/asymptote/webgl/data.js b/graphics/asymptote/webgl/data.js
new file mode 100644
index 0000000000..915dc35619
--- /dev/null
+++ b/graphics/asymptote/webgl/data.js
@@ -0,0 +1,47 @@
+var p = [
+ [0, 0, 1.6],
+ [1, 1.333333333333333, 0],
+ [0, 0.666666666666667, 0],
+ [0, 1, 0],
+ [0.333333333333333, 0, 0],
+ [0.333333333333333, 0.333333333333333, 0],
+ [0.333333333333333, 0.666666666666667, 0],
+ [0.333333333333333, 1, 0],
+ [0.666666666666667, 0, 0],
+ [0.666666666666667, 0.333333333333333, 0],
+ [0.666666666666667, 0.666666666666667, 0],
+ [0.666666666666667, 1, 0],
+ [1, 0, 0],
+ [1, 0.333333333333333, 0],
+ [1, 0.666666666666667, 0],
+ [1, 1, 0.1]
+ ];
+
+ var materialIndex = 0;
+
+ var objMaterial = new Material(
+ baseColor = [1, 1, 0, 1],
+ emissive = [0, 0, 0, 1],
+ specular = [1, 1, 1, 1],
+ roughness = 0.15,
+ metallic = 0,
+ f0 = 0.04
+ );
+
+ // Lighting parameters
+ var L = [0.447735768366173, 0.497260947684137, 0.743144825477394];
+ var Ambient = [0.1, 0.1, 0.1];
+ var Diffuse = [0.8, 0.8, 0.8, 1];
+ var Specular = [0.7, 0.7, 0.7, 1];
+ var specularfactor = 3;
+
+ // Material parameters
+ var emissive = [0, 0, 0, 1];
+ var ambient = [0, 0, 0, 1];
+ var diffuse = [1, 0, 0, 1];
+ var specular = [0.75, 0.75, 0.75, 1];
+ var shininess = 0.5;
+
+ var cameraPos = vec3.fromValues(0, 0, 2);
+ var cameraLookAt = vec3.fromValues(0, 0, 0);
+ var cameraUp = vec3.fromValues(1, 0, 0);
diff --git a/graphics/asymptote/webgl/gl-0.01.js b/graphics/asymptote/webgl/gl-0.01.js
new file mode 100644
index 0000000000..079b1bb70e
--- /dev/null
+++ b/graphics/asymptote/webgl/gl-0.01.js
@@ -0,0 +1,738 @@
+// Contains code from http: //learningwebgl.com/blog/ ? p=28#triangle-vertex-positions
+// modified to produce a subdivision algorithm for rendering Bezier
+// patches with WebGL
+var gl;
+
+function initGL(canvas) {
+ try {
+ gl=canvas.getContext("experimental-webgl");
+ gl.viewportWidth=canvas.width;
+ gl.viewportHeight=canvas.height;
+ } catch(e) {}
+ if(!gl) {
+ alert("Could not initialise WebGL, sorry : -(");
+ }
+}
+
+function getShader(gl, id) {
+ var shaderScript=document.getElementById(id);
+ if(!shaderScript) {
+ return null;
+ }
+ var str="";
+ var k=shaderScript.firstChild;
+ while(k) {
+ if(k.nodeType == 3) {
+ str += k.textContent;
+ }
+ k=k.nextSibling;
+ }
+ var shader;
+ if(shaderScript.type == "x-shader/x-fragment") {
+ shader=gl.createShader(gl.FRAGMENT_SHADER);
+ } else if(shaderScript.type == "x-shader/x-vertex") {
+ shader=gl.createShader(gl.VERTEX_SHADER);
+ } else {
+ return null;
+ }
+ gl.shaderSource(shader,str);
+ gl.compileShader(shader);
+ if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) {
+ alert(gl.getShaderInfoLog(shader));
+ return null;
+ }
+ return shader;
+}
+
+var shaderProgram;
+
+function initShaders() {
+ var fragmentShader=getShader(gl,"shader-fs");
+ var vertexShader=getShader(gl,"shader-vs");
+ shaderProgram=gl.createProgram();
+ gl.attachShader(shaderProgram,vertexShader);
+ gl.attachShader(shaderProgram,fragmentShader);
+ gl.linkProgram(shaderProgram);
+ if(!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS)) {
+ alert("Could not initialise shaders");
+ }
+ gl.useProgram(shaderProgram);
+ shaderProgram.vertexPositionAttribute=gl.getAttribLocation(shaderProgram,"aVertexPosition");
+ gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
+ shaderProgram.vertexColorAttribute=gl.getAttribLocation(shaderProgram,"aVertexColor");
+ gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
+ shaderProgram.pMatrixUniform=gl.getUniformLocation(shaderProgram,"uPMatrix");
+ shaderProgram.mvMatrixUniform=gl.getUniformLocation(shaderProgram,"uMVMatrix");
+}
+var mvMatrix=mat4.create();
+var pMatrix=mat4.create();
+
+function setMatrixUniforms() {
+ gl.uniformMatrix4fv(shaderProgram.pMatrixUniform,false,pMatrix);
+ gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform,false,mvMatrix);
+}
+
+var VertexBuffer;
+var ColorBuffer;
+
+var vertices=new Array();
+var colors=new Array();
+var indices=new Array();
+var nvertices=0;
+
+var mvMatrix=mat4.create();
+var translOffset=[0,0,0];
+var zoomFactor=1;
+
+var mvMatrixStack=[] ;
+var pMatrix=mat4.create();
+
+var localRotation=mat4.create();
+
+function mvPushMatrix() {
+ var copy=mat4.create();
+ mat4.set(mvMatrix,copy);
+ mvMatrixStack.push(copy);
+}
+
+function mvPopMatrix() {
+ if(mvMatrixStack.length == 0) {
+ throw "Invalid popMatrix!";
+ }
+ mvMatrix=mvMatrixStack.pop();
+}
+
+function degToRad(degrees) {
+ return degrees*Math.PI/180;
+}
+
+var redraw=true;
+var mouseDownOrTouchActive=false;
+var lastMouseX=null;
+var lastMouseY=null;
+var touchID=null;
+
+
+var center=[0,0,1];
+var centerInv=[0,0,-1];
+
+var rotationMatLocal=mat4.create();
+var rotationMatrix=mat4.create();
+mat4.identity(rotationMatrix);
+
+function handleMouseDown(event) {
+ mouseDownOrTouchActive=true;
+ lastMouseX=event.clientX;
+ lastMouseY=event.clientY;
+}
+
+function handleTouchStart(evt) {
+ evt.preventDefault();
+ var touches=evt.targetTouches;
+
+ if(touches.length == 1 && !mouseDownOrTouchActive) {
+ touchId=touches[0].identifier;
+ lastMouseX=touches[0].pageX,
+ lastMouseY=touches[0].pageY;
+ }
+}
+
+function handleMouseUpOrTouchEnd(event) {
+ mouseDownOrTouchActive=false;
+}
+
+function processDrag(newX, newY, pan=false) {
+ let lastX=(lastMouseX-400)/400;
+ let lastY=(lastMouseY-400)/400;
+
+ let rawX=(newX-400)/400;
+ let rawY=(newY-400)/400;
+
+ if(!pan) {
+ let [angle,axis]=arcballLib.arcball([lastX,-lastY],[rawX,-rawY]);
+ let tmpMatrix=mat4.create()
+ mat4.identity(tmpMatrix)
+ mat4.rotate(tmpMatrix,tmpMatrix,angle,[axis[0],axis[1],axis[2]])
+ mat4.multiply(rotationMatrix,tmpMatrix,rotationMatrix);
+ } else {
+ translOffset[0] +=(rawX-lastX);
+ translOffset[1] -=(rawY-lastY);
+ }
+ lastMouseX=newX;
+ lastMouseY=newY;
+ redraw=true;
+}
+
+function handleKey(key) {
+ var keycode=key.key;
+ var rotate=true;
+ var axis=[0,0,1];
+ switch(keycode) {
+ case "w":
+ axis=[-1,0,0];
+ break;
+ case "d":
+ axis=[0,1,0];
+ break;
+ case "a":
+ axis=[0,-1,0];
+ break;
+ case "s":
+ axis=[1,0,0];
+ break;
+
+ default:
+ rotate=false;
+ break;
+ }
+
+ if(rotate) {
+ mat4.rotate(rotationMatrix,rotationMatrix,0.1,axis);
+ redraw=true;
+ }
+
+}
+
+function handleMouseWheel(event) {
+ zoomFactor -= event.deltaY/100;
+
+ if(zoomFactor < 0) {
+ zoomFactor=0;
+ } else if(zoomFactor > 100) {
+ zoomFactor=100;
+ }
+
+ res=zoomFactor*0.001;
+ redraw=true;
+}
+
+function handleMouseMove(event) {
+ if(!mouseDownOrTouchActive) {
+ return;
+ }
+
+ var newX=event.clientX;
+ var newY=event.clientY;
+
+ processDrag(newX,newY,event.getModifierState("Alt"));
+}
+
+function handleTouchMove(evt) {
+ evt.preventDefault();
+ var touches=evt.targetTouches;
+
+ if(touches.length == 1 && touchId == touches[0].identifier) {
+ var newX=touches[0].pageX;
+ var newY=touches[0].pageY;
+ processDrag(newX,newY);
+ }
+}
+
+// Prepare canvas for drawing
+function sceneSetup() {
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ mat4.perspective(pMatrix,45,gl.viewportWidth/gl.viewportHeight,0.1,100.0);
+ mat4.identity(mvMatrix);
+
+ mat4.translate(mvMatrix,mvMatrix,centerInv);
+ mat4.multiply(mvMatrix,mvMatrix,rotationMatrix);
+ mat4.scale(mvMatrix,mvMatrix,[zoomFactor,zoomFactor,zoomFactor]);
+ mat4.translate(mvMatrix,mvMatrix,center);
+
+ mat4.translate(mvMatrix,mvMatrix,translOffset)
+}
+
+var indexExt;
+
+// Create buffer data for the patch and its subdivisions to be pushed to the graphics card
+//Takes as an argument the array of vertices that define the patch to be drawn
+// Using the vertex position buffer of the above function,draw patch.
+function setBuffer() {
+ VertexBuffer=gl.createBuffer();
+ VertexBuffer.itemSize=3;
+
+ ColorBuffer=gl.createBuffer();
+ ColorBuffer.itemSize=4;
+
+ indexBuffer=gl.createBuffer();
+ indexBuffer.itemSize=1;
+}
+
+function drawBuffer() {
+ gl.bindBuffer(gl.ARRAY_BUFFER,VertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
+ VertexBuffer.itemSize,gl.FLOAT,false,0,0);
+ VertexBuffer.numItems=nvertices;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER,ColorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colors),gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shaderProgram.vertexColorAttribute,
+ ColorBuffer.itemSize,gl.FLOAT,false,0,0);
+ ColorBuffer.numItems=nvertices;
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
+ indexExt ? new Uint32Array(indices) : new Uint16Array(indices),
+ gl.STATIC_DRAW);
+ indexBuffer.numItems=indices.length;
+ gl.drawElements(gl.TRIANGLES,indexBuffer.numItems,
+ indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT,0);
+ vertices=[];
+ colors=[];
+ indices=[];
+ nvertices=0;
+}
+
+var pixel=1.0; // Adaptive rendering constant.
+var FillFactor=0.1;
+var BezierFactor=0.4;
+//var res=0.0005; // Temporary
+var res=0.001; // Temporary
+var res2=res*res;
+var Epsilon=0.1*res;
+var epsilon=0;
+var Fuzz=1000*Number.EPSILON;
+var Fuzz2=Fuzz*Fuzz;
+
+function Split3(z0, c0, c1, z1) {
+ this.m0=new Array(3);
+ this.m2=new Array(3);
+ this.m3=new Array(3);
+ this.m4=new Array(3);
+ this.m5=new Array(3);
+ for(var i=0; i < 3; ++i) {
+ this.m0[i]=0.5*(z0[i]+c0[i]);
+ var m1=0.5*(c0[i]+c1[i]);
+ this.m2[i]=0.5*(c1[i]+z1[i]);
+ this.m3[i]=0.5*(this.m0[i]+m1);
+ this.m4[i]=0.5*(m1+this.m2[i]);
+ this.m5[i]=0.5*(this.m3[i]+this.m4[i]);
+ }
+}
+
+function unit(v) {
+ var norm=Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
+ norm=(norm != 0) ? 1/norm : 1;
+ return [v[0]*norm,v[1]*norm,v[2]*norm];
+}
+
+// Store the vertex v and its color vector c in the buffer.
+function vertex(v,c) {
+ vertices.push(v[0]);
+ vertices.push(v[1]);
+ vertices.push(v[2]);
+
+ colors.push(c[0]);
+ colors.push(c[1]);
+ colors.push(c[2]);
+ colors.push(c[3]);
+ return nvertices++;
+}
+
+function abs2(v) {
+ return v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
+}
+
+function dot(u, v) {
+ return u[0]*v[0]+u[1]*v[1]+u[2]*v[2];
+}
+
+function cross(u, v) {
+ return [u[1]*v[2]-u[2]*v[1],
+ u[2]*v[0]-u[0]*v[2],
+ u[0]*v[1]-u[1]*v[0]
+ ];
+}
+
+function normal(left3, left2, left1, middle, right1, right2, right3) {
+ var u0=right1[0]-middle[0];
+ var v0=left1[0]-middle[0];
+ var u1=right1[1]-middle[1];
+ var v1=left1[1]-middle[1];
+ var u2=right1[2]-middle[2];
+ var v2=left1[2]-middle[2];
+ var n=[
+ u1*v2-u2*v1,
+ u2*v0-u0*v2,
+ u0*v1-u1*v0
+ ];
+ if(abs2(n) > epsilon)
+ return unit(n);
+
+ var lp=[v0,v1,v2];
+ var rp=[u0,u1,u2];
+ var lpp=[middle[0]+left2[0]-2*left1[0],
+ middle[1]+left2[1]-2*left1[1],
+ middle[2]+left2[2]-2*left1[2]
+ ];
+ var rpp=[middle[0]+right2[0]-2*right1[0],
+ middle[1]+right2[1]-2*right1[1],
+ middle[2]+right2[2]-2*right1[2]
+ ];
+ var a=cross(rpp,lp);
+ var b=cross(rp,lpp);
+ n=[a[0]+b[0],
+ a[1]+b[1],
+ a[2]+b[2]
+ ];
+ if(abs2(n) > epsilon)
+ return unit(n);
+
+ var lppp=[left3[0]-middle[0]+3*(left1[0]-left2[0]),
+ left3[1]-middle[1]+3*(left1[1]-left2[1]),
+ left3[2]-middle[2]+3*(left1[2]-left2[2])
+ ];
+ var rppp=[right3[0]-middle[0]+3*(right1[0]-right2[0]),
+ right3[1]-middle[1]+3*(right1[1]-right2[1]),
+ right3[2]-middle[2]+3*(right1[2]-right2[2])
+ ];
+ a=cross(rpp,lpp);
+ b=cross(rp,lppp);
+ var c=cross(rppp,lp);
+ var d=cross(rppp,lpp);
+ var e=cross(rpp,lppp);
+ var f=cross(rppp,lppp);
+ return unit([9*a[0]+3*(b[0]+c[0]+d[0]+e[0])+f[0],
+ 9*a[1]+3*(b[1]+c[1]+d[1]+e[1])+f[1],
+ 9*a[2]+3*(b[2]+c[2]+d[2]+e[2])+f[2]
+ ]);
+}
+
+// return the maximum distance squared of points c0 and c1 from
+// the respective internal control points of z0--z1.
+function Straightness(z0,c0,c1,z1)
+{
+ var third=1.0/3.0;
+ var v=[third*(z1[0]-z0[0]),third*(z1[1]-z0[1]),third*(z1[2]-z0[2])];
+ return Math.max(abs2([c0[0]-v[0]-z0[0],c0[1]-v[1]-z0[1],c0[2]-v[2]-z0[2]]),
+ abs2([z1[0]-v[0]-c1[0],z1[1]-v[1]-c1[1],z1[2]-v[2]-c1[2]]));
+}
+
+// return the maximum perpendicular distance squared of points c0 and c1
+// from z0--z1.
+function Distance1(z0, c0, c1, z1) {
+ var Z0=[c0[0]-z0[0],c0[1]-z0[1],c0[2]-z0[2]];
+ var Q=unit([z1[0]-z0[0],z1[1]-z0[1],z1[2]-z0[2]]);
+ var Z1=[c1[0]-z0[0],c1[1]-z0[1],c1[2]-z0[2]];
+ var p0=dot(Z0,Q);
+ var p1=dot(Z1,Q);
+ return Math.max(abs2([Z0[0]-p0*Q[0],Z0[1]-p0*Q[1],Z0[2]-p0*Q[2]]),
+ abs2([Z1[0]-p1*Q[0],Z1[1]-p1*Q[1],Z1[2]-p1*Q[2]]));
+}
+
+// return the perpendicular distance squared of a point z from the plane
+// through u with unit normal n.
+function Distance2(z, u, n) {
+ var d=dot([z[0]-u[0],z[1]-u[1],z[2]-u[2]],n);
+ return d*d;
+}
+
+function Distance(p) {
+ var p0=p[0];
+ var p3=p[3];
+ var p12=p[12];
+ var p15=p[15];
+
+ // Check the flatness of the quad.
+ var d=Distance2(p15,p0,normal(p3,p[2],p[1],p0,p[4],p[8],p12));
+
+ // Determine how straight the edges are.
+ d=Math.max(d,Straightness(p0,p[1],p[2],p3));
+ d=Math.max(d,Straightness(p0,p[4],p[8],p12));
+ d=Math.max(d,Straightness(p3,p[7],p[11],p15));
+ d=Math.max(d,Straightness(p12,p[13],p[14],p15));
+
+ // Determine how straight the interior control curves are.
+ d=Math.max(d,Straightness(p[4],p[5],p[6],p[7]));
+ d=Math.max(d,Straightness(p[8],p[9],p[10],p[11]));
+ d=Math.max(d,Straightness(p[1],p[5],p[9],p[13]));
+ return Math.max(d,Straightness(p[2],p[6],p[10],p[14]));
+}
+
+var k=1;
+// Return color associated with unit normal vector n.
+function color(n) {
+ var Ldotn=L[0]*n[0]+L[1]*n[1]+L[2]*n[2];
+ if(Ldotn < 0) Ldotn=0;
+ var p=[emissive[0]+ambient[0]*Ambient[0]+Ldotn*diffuse[0]*Diffuse[0],
+ emissive[1]+ambient[1]*Ambient[1]+Ldotn*diffuse[1]*Diffuse[1],
+ emissive[2]+ambient[2]*Ambient[2]+Ldotn*diffuse[2]*Diffuse[2]
+ ];
+ var s=shininess*128;
+ var H=unit([L[0],L[1],L[2]+1]);
+ var f=Math.pow(H[0]*n[0]+H[1]*n[1]+H[2]*n[2],s);
+
+ if(Ldotn > 0) // Phong-Blinn model of specular reflection
+ p=[p[0]+f*specular[0]*Specular[0],p[1]+f*specular[1]*Specular[1],
+ p[2]+f*specular[2]*Specular[2]
+ ];
+
+ return [p[0],p[1],p[2],1];
+}
+
+function render(p, I0, I1, I2, I3, P0, P1, P2, P3, flat0, flat1, flat2, flat3,
+ C0, C1, C2, C3) {
+ if(Distance(p) < res2) { // Patch is flat
+ indices.push(I0);
+ indices.push(I1);
+ indices.push(I2);
+
+ indices.push(I0);
+ indices.push(I2);
+ indices.push(I3);
+ return;
+ }
+
+ var p0=p[0];
+ var p3=p[3];
+ var p12=p[12];
+ var p15=p[15];
+
+ var c0=new Split3(p0,p[1],p[2],p3);
+ var c1=new Split3(p[4],p[5],p[6],p[7]);
+ var c2=new Split3(p[8],p[9],p[10],p[11]);
+ var c3=new Split3(p12,p[13],p[14],p15);
+ var c4=new Split3(p0,p[4],p[8],p12);
+ var c5=new Split3(c0.m0,c1.m0,c2.m0,c3.m0);
+ var c6=new Split3(c0.m3,c1.m3,c2.m3,c3.m3);
+ var c7=new Split3(c0.m5,c1.m5,c2.m5,c3.m5);
+ var c8=new Split3(c0.m4,c1.m4,c2.m4,c3.m4);
+ var c9=new Split3(c0.m2,c1.m2,c2.m2,c3.m2);
+ var c10=new Split3(p3,p[7],p[11],p15);
+
+ var s0=[p0,c0.m0,c0.m3,c0.m5,c4.m0,c5.m0,c6.m0,c7.m0,
+ c4.m3,c5.m3,c6.m3,c7.m3,c4.m5,c5.m5,c6.m5,c7.m5
+ ];
+ var s1=[c4.m5,c5.m5,c6.m5,c7.m5,c4.m4,c5.m4,c6.m4,c7.m4,
+ c4.m2,c5.m2,c6.m2,c7.m2,p12,c3.m0,c3.m3,c3.m5
+ ];
+ var s2=[c7.m5,c8.m5,c9.m5,c10.m5,c7.m4,c8.m4,c9.m4,c10.m4,
+ c7.m2,c8.m2,c9.m2,c10.m2,c3.m5,c3.m4,c3.m2,p15
+ ];
+ var s3=[c0.m5,c0.m4,c0.m2,p3,c7.m0,c8.m0,c9.m0,c10.m0,
+ c7.m3,c8.m3,c9.m3,c10.m3,c7.m5,c8.m5,c9.m5,c10.m5
+ ];
+
+ var m4=s0[15];
+
+ var n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
+ if(n0 == 0.0) {
+ n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
+ if(n0 == 0.0) n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
+ }
+
+ var n1=normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]);
+ if(n1 == 0.0) {
+ n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
+ if(n1 == 0.0) n1=normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]);
+ }
+
+ var n2=normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]);
+ if(n2 == 0.0) {
+ n2=normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]);
+ if(n2 == 0.0) n2=normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]);
+ }
+
+ var n3=normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]);
+ if(n3 == 0.0) {
+ n3=normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]);
+ if(n3 == 0.0) n3=normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]);
+ }
+
+ var n4=normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]);
+
+ var m0,m1,m2,m3;
+
+ // A kludge to remove subdivision cracks, only applied the first time
+ // an edge is found to be flat before the rest of the subpatch is.
+ if(flat0)
+ m0=[0.5*(P0[0]+P1[0]),0.5*(P0[1]+P1[1]),0.5*(P0[2]+P1[2])];
+ else {
+ if((flat0=Distance1(p0,p[4],p[8],p12) < res2)) {
+ var u=s0[12];
+ var v=s2[3];
+ var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
+ m0=[0.5*(P0[0]+P1[0])+Epsilon*e[0],0.5*(P0[1]+P1[1])+Epsilon*e[1],
+ 0.5*(P0[2]+P1[2])+Epsilon*e[2]
+ ];
+ } else
+ m0=s0[12];
+ }
+
+ if(flat1)
+ m1=[0.5*(P1[0]+P2[0]),0.5*(P1[1]+P2[1]),0.5*(P1[2]+P2[2])];
+ else {
+ if((flat1=Distance1(p12,p[13],p[14],p15) < res2)) {
+ var u=s1[15];
+ var v=s3[0];
+ var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
+ m1=[0.5*(P1[0]+P2[0])+Epsilon*e[0],0.5*(P1[1]+P2[1])+Epsilon*e[1],
+ 0.5*(P1[2]+P2[2])+Epsilon*e[2]
+ ];
+ } else
+ m1=s1[15];
+ }
+
+ if(flat2)
+ m2=[0.5*(P2[0]+P3[0]),0.5*(P2[1]+P3[1]),0.5*(P2[2]+P3[2])];
+ else {
+ if((flat2=Distance1(p15,p[11],p[7],p3) < res2)) {
+ var u=s2[3];
+ var v=s0[12];
+ var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
+ m2=[0.5*(P2[0]+P3[0])+Epsilon*e[0],0.5*(P2[1]+P3[1])+Epsilon*e[1],
+ 0.5*(P2[2]+P3[2])+Epsilon*e[2]
+ ];
+ } else
+ m2=s2[3];
+ }
+
+ if(flat3)
+ m3=[0.5*(P3[0]+P0[0]),0.5*(P3[1]+P0[1]),0.5*(P3[2]+P0[2])];
+ else {
+ if((flat3=Distance1(p3,p[2],p[1],p0) < res2)) {
+ var u=s3[0];
+ var v=s1[15];
+ var e=unit([u[0]-v[0],u[1]-v[1],u[2]-v[2]]);
+ m3=[0.5*(P3[0]+P0[0])+Epsilon*e[0],
+ 0.5*(P3[1]+P0[1])+Epsilon*e[1],
+ 0.5*(P3[2]+P0[2])+Epsilon*e[2]
+ ];
+ } else
+ m3=s3[0];
+ }
+
+ // document.write(n0);
+ // document.write(" < br > ");
+
+ {
+ /*
+ var c0=new Array(4);
+ var c1=new Array(4);
+ var c2=new Array(4);
+ var c3=new Array(4);
+ var c4=new Array(4);
+
+ for(var i=0; i < 4; ++i) {
+ c0[i]=0.5*(C0[i]+C1[i]);
+ c1[i]=0.5*(C1[i]+C2[i]);
+ c2[i]=0.5*(C2[i]+C3[i]);
+ c3[i]=0.5*(C3[i]+C0[i]);
+ c4[i]=0.5*(c0[i]+c2[i]);
+ }
+ */
+
+ var c0=color(n0);
+ var c1=color(n1);
+ var c2=color(n2);
+ var c3=color(n3);
+ var c4=color(n4);
+
+
+ var i0=vertex(m0,c0);
+ var i1=vertex(m1,c1);
+ var i2=vertex(m2,c2);
+ var i3=vertex(m3,c3);
+ var i4=vertex(m4,c4);
+
+ render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,
+ C0,c0,c4,c3);
+ render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,
+ c0,C1,c1,c4);
+ render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false,
+ c4,c1,C2,c2);
+ render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3,
+ c3,c4,c2,C3);
+ }
+}
+
+
+function draw(p) {
+ var p0=p[0];
+ var p3=p[3];
+ var p12=p[12];
+ var p15=p[15];
+
+ epsilon=0;
+ for(var i=1; i < 16; ++i)
+ epsilon=Math.max(epsilon,
+ abs2([p[i][0]-p0[0],p[i][1]-p0[1],p[i][2]-p0[2]]));
+ epsilon *= Fuzz2;
+
+ var n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12);
+ var n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15);
+ var n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3);
+ var n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0);
+
+ var c0=color(n0);
+ var c1=color(n1);
+ var c2=color(n2);
+ var c3=color(n3);
+
+ var i0=vertex(p0,c0);
+ var i1=vertex(p12,c1);
+ var i2=vertex(p15,c2);
+ var i3=vertex(p3,c3);
+
+ render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false,
+ c0,c1,c2,c3);
+
+ drawBuffer();
+}
+
+var p=[];
+
+function tick() {
+ requestAnimationFrame(tick);
+ if(redraw) {
+ sceneSetup();
+ mat4.translate(mvMatrix,mvMatrix,[-0.5,-0.5,-1.5]);
+ setMatrixUniforms();
+ for(var i=0; i < p.length; ++i)
+ draw(p[i]);
+ redraw=false;
+ }
+}
+
+function webGLStart() {
+ var canvas=document.getElementById("Asymptote");
+ initGL(canvas);
+ initShaders();
+ gl.clearColor(0.0,0.0,0.0,1.0);
+ gl.enable(gl.DEPTH_TEST);
+
+ indexExt=gl.getExtension("OES_element_index_uint");
+
+ gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight);
+ setBuffer();
+
+ canvas.onmousedown=handleMouseDown;
+ document.onmouseup=handleMouseUpOrTouchEnd;
+ document.onmousemove=handleMouseMove;
+ canvas.onkeydown=handleKey;
+ document.onwheel=handleMouseWheel;
+
+ canvas.addEventListener("touchstart",handleTouchStart,false);
+ canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,false);
+ canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,false);
+ canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,false);
+ canvas.addEventListener("touchmove",handleTouchMove,false);
+
+ tick();
+}
+
+
+// Lighting parameters
+var L = [0.447735768366173, 0.497260947684137, 0.743144825477394];
+var Ambient = [0.1, 0.1, 0.1];
+var Diffuse = [0.8, 0.8, 0.8, 1];
+var Specular = [0.7, 0.7, 0.7, 1];
+var specularfactor = 3;
+
+// Material parameters
+var emissive = [0, 0, 0, 1];
+var ambient = [1, 1, 1, 1];
+var diffuse = [0, 1, 0, 1];
+var specular = [0.75, 0.75, 0.75, 1];
+var shininess = 0.5;
diff --git a/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js b/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js
new file mode 100644
index 0000000000..84476b6061
--- /dev/null
+++ b/graphics/asymptote/webgl/gl-matrix-min-2.3.2.js
@@ -0,0 +1,29 @@
+/**
+ * @fileoverview gl-matrix - High performance matrix and vector operations
+ * @author Brandon Jones
+ * @author Colin MacKenzie IV
+ * @version 2.3.2
+ */
+
+/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE. */
+
+!function(t,a){if("object"==typeof exports&&"object"==typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var n=a();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,function(){return function(t){function a(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}var n={};return a.m=t,a.c=n,a.p="",a(0)}([function(t,a,n){a.glMatrix=n(1),a.mat2=n(2),a.mat2d=n(3),a.mat3=n(4),a.mat4=n(5),a.quat=n(6),a.vec2=n(9),a.vec3=n(7),a.vec4=n(8)},function(t,a){var n={};n.EPSILON=1e-6,n.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,n.RANDOM=Math.random,n.ENABLE_SIMD=!1,n.SIMD_AVAILABLE=n.ARRAY_TYPE===Float32Array&&"SIMD"in this,n.USE_SIMD=n.ENABLE_SIMD&&n.SIMD_AVAILABLE,n.setMatrixArrayType=function(t){n.ARRAY_TYPE=t};var r=Math.PI/180;n.toRadian=function(t){return t*r},n.equals=function(t,a){return Math.abs(t-a)<=n.EPSILON*Math.max(1,Math.abs(t),Math.abs(a))},t.exports=n},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},o.clone=function(t){var a=new r.ARRAY_TYPE(4);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},o.fromValues=function(t,a,n,o){var u=new r.ARRAY_TYPE(4);return u[0]=t,u[1]=a,u[2]=n,u[3]=o,u},o.set=function(t,a,n,r,o){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t},o.transpose=function(t,a){if(t===a){var n=a[1];t[1]=a[2],t[2]=n}else t[0]=a[0],t[1]=a[2],t[2]=a[1],t[3]=a[3];return t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*u-o*r;return l?(l=1/l,t[0]=u*l,t[1]=-r*l,t[2]=-o*l,t[3]=n*l,t):null},o.adjoint=function(t,a){var n=a[0];return t[0]=a[3],t[1]=-a[1],t[2]=-a[2],t[3]=n,t},o.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1],s=n[2],i=n[3];return t[0]=r*e+u*M,t[1]=o*e+l*M,t[2]=r*s+u*i,t[3]=o*s+l*i,t},o.mul=o.multiply,o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+u*e,t[1]=o*M+l*e,t[2]=r*-e+u*M,t[3]=o*-e+l*M,t},o.scale=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1];return t[0]=r*e,t[1]=o*e,t[2]=u*M,t[3]=l*M,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=a[1],t},o.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},o.LDU=function(t,a,n,r){return t[2]=r[2]/r[0],n[0]=r[0],n[1]=r[1],n[3]=r[3]-t[2]*n[1],[t,a,n]},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t},o.sub=o.subtract,o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=a[0],M=a[1],s=a[2],i=a[3];return Math.abs(n-e)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(e))&&Math.abs(o-M)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(M))&&Math.abs(u-s)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(l-i)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(i))},o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(6);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},o.fromValues=function(t,a,n,o,u,l){var e=new r.ARRAY_TYPE(6);return e[0]=t,e[1]=a,e[2]=n,e[3]=o,e[4]=u,e[5]=l,e},o.set=function(t,a,n,r,o,u,l){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=n*u-r*o;return M?(M=1/M,t[0]=u*M,t[1]=-r*M,t[2]=-o*M,t[3]=n*M,t[4]=(o*e-u*l)*M,t[5]=(r*l-n*e)*M,t):null},o.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1],c=n[2],h=n[3],S=n[4],I=n[5];return t[0]=r*s+u*i,t[1]=o*s+l*i,t[2]=r*c+u*h,t[3]=o*c+l*h,t[4]=r*S+u*I+e,t[5]=o*S+l*I+M,t},o.mul=o.multiply,o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=Math.sin(n),i=Math.cos(n);return t[0]=r*i+u*s,t[1]=o*i+l*s,t[2]=r*-s+u*i,t[3]=o*-s+l*i,t[4]=e,t[5]=M,t},o.scale=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1];return t[0]=r*s,t[1]=o*s,t[2]=u*i,t[3]=l*i,t[4]=e,t[5]=M,t},o.translate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=n[0],i=n[1];return t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=r*s+u*i+e,t[5]=o*s+l*i+M,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=-n,t[3]=r,t[4]=0,t[5]=0,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=a[1],t[4]=0,t[5]=0,t},o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=a[0],t[5]=a[1],t},o.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=a[0],i=a[1],c=a[2],h=a[3],S=a[4],I=a[5];return Math.abs(n-s)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(s))&&Math.abs(o-i)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(i))&&Math.abs(u-c)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(l-h)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(h))&&Math.abs(e-S)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(S))&&Math.abs(M-I)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(I))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromMat4=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[4],t[4]=a[5],t[5]=a[6],t[6]=a[8],t[7]=a[9],t[8]=a[10],t},o.clone=function(t){var a=new r.ARRAY_TYPE(9);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a[6]=t[6],a[7]=t[7],a[8]=t[8],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t},o.fromValues=function(t,a,n,o,u,l,e,M,s){var i=new r.ARRAY_TYPE(9);return i[0]=t,i[1]=a,i[2]=n,i[3]=o,i[4]=u,i[5]=l,i[6]=e,i[7]=M,i[8]=s,i},o.set=function(t,a,n,r,o,u,l,e,M,s){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t[6]=e,t[7]=M,t[8]=s,t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.transpose=function(t,a){if(t===a){var n=a[1],r=a[2],o=a[5];t[1]=a[3],t[2]=a[6],t[3]=n,t[5]=a[7],t[6]=r,t[7]=o}else t[0]=a[0],t[1]=a[3],t[2]=a[6],t[3]=a[1],t[4]=a[4],t[5]=a[7],t[6]=a[2],t[7]=a[5],t[8]=a[8];return t},o.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=i*l-e*s,h=-i*u+e*M,S=s*u-l*M,I=n*c+r*h+o*S;return I?(I=1/I,t[0]=c*I,t[1]=(-i*r+o*s)*I,t[2]=(e*r-o*l)*I,t[3]=h*I,t[4]=(i*n-o*M)*I,t[5]=(-e*n+o*u)*I,t[6]=S*I,t[7]=(-s*n+r*M)*I,t[8]=(l*n-r*u)*I,t):null},o.adjoint=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8];return t[0]=l*i-e*s,t[1]=o*s-r*i,t[2]=r*e-o*l,t[3]=e*M-u*i,t[4]=n*i-o*M,t[5]=o*u-n*e,t[6]=u*s-l*M,t[7]=r*M-n*s,t[8]=n*l-r*u,t},o.determinant=function(t){var a=t[0],n=t[1],r=t[2],o=t[3],u=t[4],l=t[5],e=t[6],M=t[7],s=t[8];return a*(s*u-l*M)+n*(-s*o+l*e)+r*(M*o-u*e)},o.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=n[0],S=n[1],I=n[2],f=n[3],x=n[4],D=n[5],F=n[6],m=n[7],d=n[8];return t[0]=h*r+S*l+I*s,t[1]=h*o+S*e+I*i,t[2]=h*u+S*M+I*c,t[3]=f*r+x*l+D*s,t[4]=f*o+x*e+D*i,t[5]=f*u+x*M+D*c,t[6]=F*r+m*l+d*s,t[7]=F*o+m*e+d*i,t[8]=F*u+m*M+d*c,t},o.mul=o.multiply,o.translate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=n[0],S=n[1];return t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=e,t[5]=M,t[6]=h*r+S*l+s,t[7]=h*o+S*e+i,t[8]=h*u+S*M+c,t},o.rotate=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=Math.sin(n),S=Math.cos(n);return t[0]=S*r+h*l,t[1]=S*o+h*e,t[2]=S*u+h*M,t[3]=S*l-h*r,t[4]=S*e-h*o,t[5]=S*M-h*u,t[6]=s,t[7]=i,t[8]=c,t},o.scale=function(t,a,n){var r=n[0],o=n[1];return t[0]=r*a[0],t[1]=r*a[1],t[2]=r*a[2],t[3]=o*a[3],t[4]=o*a[4],t[5]=o*a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t},o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=a[0],t[7]=a[1],t[8]=1,t},o.fromRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=0,t[3]=-n,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=0,t[4]=a[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},o.fromMat2d=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=0,t[3]=a[2],t[4]=a[3],t[5]=0,t[6]=a[4],t[7]=a[5],t[8]=1,t},o.fromQuat=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n+n,e=r+r,M=o+o,s=n*l,i=r*l,c=r*e,h=o*l,S=o*e,I=o*M,f=u*l,x=u*e,D=u*M;return t[0]=1-c-I,t[3]=i-D,t[6]=h+x,t[1]=i+D,t[4]=1-s-I,t[7]=S-f,t[2]=h-x,t[5]=S+f,t[8]=1-s-c,t},o.normalFromMat4=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15],F=n*e-r*l,m=n*M-o*l,d=n*s-u*l,b=r*M-o*e,v=r*s-u*e,z=o*s-u*M,p=i*f-c*I,w=i*x-h*I,E=i*D-S*I,A=c*x-h*f,P=c*D-S*f,L=h*D-S*x,q=F*L-m*P+d*A+b*E-v*w+z*p;return q?(q=1/q,t[0]=(e*L-M*P+s*A)*q,t[1]=(M*E-l*L-s*w)*q,t[2]=(l*P-e*E+s*p)*q,t[3]=(o*P-r*L-u*A)*q,t[4]=(n*L-o*E+u*w)*q,t[5]=(r*E-n*P-u*p)*q,t[6]=(f*z-x*v+D*b)*q,t[7]=(x*d-I*z-D*m)*q,t[8]=(I*v-f*d+D*F)*q,t):null},o.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t[6]=a[6]+n[6],t[7]=a[7]+n[7],t[8]=a[8]+n[8],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t[6]=a[6]-n[6],t[7]=a[7]-n[7],t[8]=a[8]-n[8],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t[6]=a[6]*n,t[7]=a[7]*n,t[8]=a[8]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t[6]=a[6]+n[6]*r,t[7]=a[7]+n[7]*r,t[8]=a[8]+n[8]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]&&t[6]===a[6]&&t[7]===a[7]&&t[8]===a[8]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=t[6],i=t[7],c=t[8],h=a[0],S=a[1],I=a[2],f=a[3],x=a[4],D=a[5],F=t[6],m=a[7],d=a[8];return Math.abs(n-h)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(h))&&Math.abs(o-S)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(S))&&Math.abs(u-I)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(I))&&Math.abs(l-f)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(f))&&Math.abs(e-x)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(x))&&Math.abs(M-D)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(D))&&Math.abs(s-F)<=r.EPSILON*Math.max(1,Math.abs(s),Math.abs(F))&&Math.abs(i-m)<=r.EPSILON*Math.max(1,Math.abs(i),Math.abs(m))&&Math.abs(c-d)<=r.EPSILON*Math.max(1,Math.abs(c),Math.abs(d))},t.exports=o},function(t,a,n){var r=n(1),o={scalar:{},SIMD:{}};o.create=function(){var t=new r.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.clone=function(t){var a=new r.ARRAY_TYPE(16);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a[4]=t[4],a[5]=t[5],a[6]=t[6],a[7]=t[7],a[8]=t[8],a[9]=t[9],a[10]=t[10],a[11]=t[11],a[12]=t[12],a[13]=t[13],a[14]=t[14],a[15]=t[15],a},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.fromValues=function(t,a,n,o,u,l,e,M,s,i,c,h,S,I,f,x){var D=new r.ARRAY_TYPE(16);return D[0]=t,D[1]=a,D[2]=n,D[3]=o,D[4]=u,D[5]=l,D[6]=e,D[7]=M,D[8]=s,D[9]=i,D[10]=c,D[11]=h,D[12]=S,D[13]=I,D[14]=f,D[15]=x,D},o.set=function(t,a,n,r,o,u,l,e,M,s,i,c,h,S,I,f,x){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t[4]=u,t[5]=l,t[6]=e,t[7]=M,t[8]=s,t[9]=i,t[10]=c,t[11]=h,t[12]=S,t[13]=I,t[14]=f,t[15]=x,t},o.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.scalar.transpose=function(t,a){if(t===a){var n=a[1],r=a[2],o=a[3],u=a[6],l=a[7],e=a[11];t[1]=a[4],t[2]=a[8],t[3]=a[12],t[4]=n,t[6]=a[9],t[7]=a[13],t[8]=r,t[9]=u,t[11]=a[14],t[12]=o,t[13]=l,t[14]=e}else t[0]=a[0],t[1]=a[4],t[2]=a[8],t[3]=a[12],t[4]=a[1],t[5]=a[5],t[6]=a[9],t[7]=a[13],t[8]=a[2],t[9]=a[6],t[10]=a[10],t[11]=a[14],t[12]=a[3],t[13]=a[7],t[14]=a[11],t[15]=a[15];return t},o.SIMD.transpose=function(t,a){var n,r,o,u,l,e,M,s,i,c;return n=SIMD.Float32x4.load(a,0),r=SIMD.Float32x4.load(a,4),o=SIMD.Float32x4.load(a,8),u=SIMD.Float32x4.load(a,12),l=SIMD.Float32x4.shuffle(n,r,0,1,4,5),e=SIMD.Float32x4.shuffle(o,u,0,1,4,5),M=SIMD.Float32x4.shuffle(l,e,0,2,4,6),s=SIMD.Float32x4.shuffle(l,e,1,3,5,7),SIMD.Float32x4.store(t,0,M),SIMD.Float32x4.store(t,4,s),l=SIMD.Float32x4.shuffle(n,r,2,3,6,7),e=SIMD.Float32x4.shuffle(o,u,2,3,6,7),i=SIMD.Float32x4.shuffle(l,e,0,2,4,6),c=SIMD.Float32x4.shuffle(l,e,1,3,5,7),SIMD.Float32x4.store(t,8,i),SIMD.Float32x4.store(t,12,c),t},o.transpose=r.USE_SIMD?o.SIMD.transpose:o.scalar.transpose,o.scalar.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15],F=n*e-r*l,m=n*M-o*l,d=n*s-u*l,b=r*M-o*e,v=r*s-u*e,z=o*s-u*M,p=i*f-c*I,w=i*x-h*I,E=i*D-S*I,A=c*x-h*f,P=c*D-S*f,L=h*D-S*x,q=F*L-m*P+d*A+b*E-v*w+z*p;return q?(q=1/q,t[0]=(e*L-M*P+s*A)*q,t[1]=(o*P-r*L-u*A)*q,t[2]=(f*z-x*v+D*b)*q,t[3]=(h*v-c*z-S*b)*q,t[4]=(M*E-l*L-s*w)*q,t[5]=(n*L-o*E+u*w)*q,t[6]=(x*d-I*z-D*m)*q,t[7]=(i*z-h*d+S*m)*q,t[8]=(l*P-e*E+s*p)*q,t[9]=(r*E-n*P-u*p)*q,t[10]=(I*v-f*d+D*F)*q,t[11]=(c*d-i*v-S*F)*q,t[12]=(e*w-l*A-M*p)*q,t[13]=(n*A-r*w+o*p)*q,t[14]=(f*m-I*b-x*F)*q,t[15]=(i*b-c*m+h*F)*q,t):null},o.SIMD.invert=function(t,a){var n,r,o,u,l,e,M,s,i,c,h=SIMD.Float32x4.load(a,0),S=SIMD.Float32x4.load(a,4),I=SIMD.Float32x4.load(a,8),f=SIMD.Float32x4.load(a,12);return l=SIMD.Float32x4.shuffle(h,S,0,1,4,5),r=SIMD.Float32x4.shuffle(I,f,0,1,4,5),n=SIMD.Float32x4.shuffle(l,r,0,2,4,6),r=SIMD.Float32x4.shuffle(r,l,1,3,5,7),l=SIMD.Float32x4.shuffle(h,S,2,3,6,7),u=SIMD.Float32x4.shuffle(I,f,2,3,6,7),o=SIMD.Float32x4.shuffle(l,u,0,2,4,6),u=SIMD.Float32x4.shuffle(u,l,1,3,5,7),l=SIMD.Float32x4.mul(o,u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),e=SIMD.Float32x4.mul(r,l),M=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(SIMD.Float32x4.mul(r,l),e),M=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),M),M=SIMD.Float32x4.swizzle(M,2,3,0,1),l=SIMD.Float32x4.mul(r,o),l=SIMD.Float32x4.swizzle(l,1,0,3,2),e=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),e),i=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(e,SIMD.Float32x4.mul(u,l)),i=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),l=SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(r,2,3,0,1),u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),o=SIMD.Float32x4.swizzle(o,2,3,0,1),e=SIMD.Float32x4.add(SIMD.Float32x4.mul(o,l),e),s=SIMD.Float32x4.mul(n,l),l=SIMD.Float32x4.swizzle(l,2,3,0,1),e=SIMD.Float32x4.sub(e,SIMD.Float32x4.mul(o,l)),s=SIMD.Float32x4.sub(SIMD.Float32x4.mul(n,l),s),s=SIMD.Float32x4.swizzle(s,2,3,0,1),l=SIMD.Float32x4.mul(n,r),l=SIMD.Float32x4.swizzle(l,1,0,3,2),s=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),s),i=SIMD.Float32x4.sub(SIMD.Float32x4.mul(o,l),i),l=SIMD.Float32x4.swizzle(l,2,3,0,1),s=SIMD.Float32x4.sub(SIMD.Float32x4.mul(u,l),s),i=SIMD.Float32x4.sub(i,SIMD.Float32x4.mul(o,l)),l=SIMD.Float32x4.mul(n,u),l=SIMD.Float32x4.swizzle(l,1,0,3,2),M=SIMD.Float32x4.sub(M,SIMD.Float32x4.mul(o,l)),s=SIMD.Float32x4.add(SIMD.Float32x4.mul(r,l),s),l=SIMD.Float32x4.swizzle(l,2,3,0,1),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(o,l),M),s=SIMD.Float32x4.sub(s,SIMD.Float32x4.mul(r,l)),l=SIMD.Float32x4.mul(n,o),l=SIMD.Float32x4.swizzle(l,1,0,3,2),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(u,l),M),i=SIMD.Float32x4.sub(i,SIMD.Float32x4.mul(r,l)),l=SIMD.Float32x4.swizzle(l,2,3,0,1),M=SIMD.Float32x4.sub(M,SIMD.Float32x4.mul(u,l)),i=SIMD.Float32x4.add(SIMD.Float32x4.mul(r,l),i),c=SIMD.Float32x4.mul(n,e),c=SIMD.Float32x4.add(SIMD.Float32x4.swizzle(c,2,3,0,1),c),c=SIMD.Float32x4.add(SIMD.Float32x4.swizzle(c,1,0,3,2),c),l=SIMD.Float32x4.reciprocalApproximation(c),c=SIMD.Float32x4.sub(SIMD.Float32x4.add(l,l),SIMD.Float32x4.mul(c,SIMD.Float32x4.mul(l,l))),(c=SIMD.Float32x4.swizzle(c,0,0,0,0))?(SIMD.Float32x4.store(t,0,SIMD.Float32x4.mul(c,e)),SIMD.Float32x4.store(t,4,SIMD.Float32x4.mul(c,M)),SIMD.Float32x4.store(t,8,SIMD.Float32x4.mul(c,s)),SIMD.Float32x4.store(t,12,SIMD.Float32x4.mul(c,i)),t):null},o.invert=r.USE_SIMD?o.SIMD.invert:o.scalar.invert,o.scalar.adjoint=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=a[4],e=a[5],M=a[6],s=a[7],i=a[8],c=a[9],h=a[10],S=a[11],I=a[12],f=a[13],x=a[14],D=a[15];return t[0]=e*(h*D-S*x)-c*(M*D-s*x)+f*(M*S-s*h),t[1]=-(r*(h*D-S*x)-c*(o*D-u*x)+f*(o*S-u*h)),t[2]=r*(M*D-s*x)-e*(o*D-u*x)+f*(o*s-u*M),t[3]=-(r*(M*S-s*h)-e*(o*S-u*h)+c*(o*s-u*M)),t[4]=-(l*(h*D-S*x)-i*(M*D-s*x)+I*(M*S-s*h)),t[5]=n*(h*D-S*x)-i*(o*D-u*x)+I*(o*S-u*h),t[6]=-(n*(M*D-s*x)-l*(o*D-u*x)+I*(o*s-u*M)),t[7]=n*(M*S-s*h)-l*(o*S-u*h)+i*(o*s-u*M),t[8]=l*(c*D-S*f)-i*(e*D-s*f)+I*(e*S-s*c),t[9]=-(n*(c*D-S*f)-i*(r*D-u*f)+I*(r*S-u*c)),t[10]=n*(e*D-s*f)-l*(r*D-u*f)+I*(r*s-u*e),t[11]=-(n*(e*S-s*c)-l*(r*S-u*c)+i*(r*s-u*e)),t[12]=-(l*(c*x-h*f)-i*(e*x-M*f)+I*(e*h-M*c)),t[13]=n*(c*x-h*f)-i*(r*x-o*f)+I*(r*h-o*c),t[14]=-(n*(e*x-M*f)-l*(r*x-o*f)+I*(r*M-o*e)),t[15]=n*(e*h-M*c)-l*(r*h-o*c)+i*(r*M-o*e),t},o.SIMD.adjoint=function(t,a){var n,r,o,u,l,e,M,s,i,c,h,S,I,n=SIMD.Float32x4.load(a,0),r=SIMD.Float32x4.load(a,4),o=SIMD.Float32x4.load(a,8),u=SIMD.Float32x4.load(a,12);return i=SIMD.Float32x4.shuffle(n,r,0,1,4,5),e=SIMD.Float32x4.shuffle(o,u,0,1,4,5),l=SIMD.Float32x4.shuffle(i,e,0,2,4,6),e=SIMD.Float32x4.shuffle(e,i,1,3,5,7),i=SIMD.Float32x4.shuffle(n,r,2,3,6,7),s=SIMD.Float32x4.shuffle(o,u,2,3,6,7),M=SIMD.Float32x4.shuffle(i,s,0,2,4,6),s=SIMD.Float32x4.shuffle(s,i,1,3,5,7),i=SIMD.Float32x4.mul(M,s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),c=SIMD.Float32x4.mul(e,i),h=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(SIMD.Float32x4.mul(e,i),c),h=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),h),h=SIMD.Float32x4.swizzle(h,2,3,0,1),i=SIMD.Float32x4.mul(e,M),i=SIMD.Float32x4.swizzle(i,1,0,3,2),c=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),c),I=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(c,SIMD.Float32x4.mul(s,i)),I=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),I),I=SIMD.Float32x4.swizzle(I,2,3,0,1),i=SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,2,3,0,1),s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),M=SIMD.Float32x4.swizzle(M,2,3,0,1),c=SIMD.Float32x4.add(SIMD.Float32x4.mul(M,i),c),S=SIMD.Float32x4.mul(l,i),i=SIMD.Float32x4.swizzle(i,2,3,0,1),c=SIMD.Float32x4.sub(c,SIMD.Float32x4.mul(M,i)),S=SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,i),S),S=SIMD.Float32x4.swizzle(S,2,3,0,1),i=SIMD.Float32x4.mul(l,e),i=SIMD.Float32x4.swizzle(i,1,0,3,2),S=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),S),I=SIMD.Float32x4.sub(SIMD.Float32x4.mul(M,i),I),i=SIMD.Float32x4.swizzle(i,2,3,0,1),S=SIMD.Float32x4.sub(SIMD.Float32x4.mul(s,i),S),I=SIMD.Float32x4.sub(I,SIMD.Float32x4.mul(M,i)),i=SIMD.Float32x4.mul(l,s),i=SIMD.Float32x4.swizzle(i,1,0,3,2),h=SIMD.Float32x4.sub(h,SIMD.Float32x4.mul(M,i)),S=SIMD.Float32x4.add(SIMD.Float32x4.mul(e,i),S),i=SIMD.Float32x4.swizzle(i,2,3,0,1),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(M,i),h),S=SIMD.Float32x4.sub(S,SIMD.Float32x4.mul(e,i)),i=SIMD.Float32x4.mul(l,M),i=SIMD.Float32x4.swizzle(i,1,0,3,2),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(s,i),h),I=SIMD.Float32x4.sub(I,SIMD.Float32x4.mul(e,i)),i=SIMD.Float32x4.swizzle(i,2,3,0,1),h=SIMD.Float32x4.sub(h,SIMD.Float32x4.mul(s,i)),I=SIMD.Float32x4.add(SIMD.Float32x4.mul(e,i),I),SIMD.Float32x4.store(t,0,c),SIMD.Float32x4.store(t,4,h),SIMD.Float32x4.store(t,8,S),SIMD.Float32x4.store(t,12,I),t},o.adjoint=r.USE_SIMD?o.SIMD.adjoint:o.scalar.adjoint,o.determinant=function(t){var a=t[0],n=t[1],r=t[2],o=t[3],u=t[4],l=t[5],e=t[6],M=t[7],s=t[8],i=t[9],c=t[10],h=t[11],S=t[12],I=t[13],f=t[14],x=t[15],D=a*l-n*u,F=a*e-r*u,m=a*M-o*u,d=n*e-r*l,b=n*M-o*l,v=r*M-o*e,z=s*I-i*S,p=s*f-c*S,w=s*x-h*S,E=i*f-c*I,A=i*x-h*I,P=c*x-h*f;return D*P-F*A+m*E+d*w-b*p+v*z},o.SIMD.multiply=function(t,a,n){var r=SIMD.Float32x4.load(a,0),o=SIMD.Float32x4.load(a,4),u=SIMD.Float32x4.load(a,8),l=SIMD.Float32x4.load(a,12),e=SIMD.Float32x4.load(n,0),M=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(e,3,3,3,3),l))));SIMD.Float32x4.store(t,0,M);var s=SIMD.Float32x4.load(n,4),i=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(s,3,3,3,3),l))));SIMD.Float32x4.store(t,4,i);var c=SIMD.Float32x4.load(n,8),h=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(c,3,3,3,3),l))));SIMD.Float32x4.store(t,8,h);var S=SIMD.Float32x4.load(n,12),I=SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,0,0,0,0),r),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,1,1,1,1),o),SIMD.Float32x4.add(SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,2,2,2,2),u),SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(S,3,3,3,3),l))));return SIMD.Float32x4.store(t,12,I),t},o.scalar.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=a[9],S=a[10],I=a[11],f=a[12],x=a[13],D=a[14],F=a[15],m=n[0],d=n[1],b=n[2],v=n[3];return t[0]=m*r+d*e+b*c+v*f,t[1]=m*o+d*M+b*h+v*x,t[2]=m*u+d*s+b*S+v*D,t[3]=m*l+d*i+b*I+v*F,m=n[4],d=n[5],b=n[6],v=n[7],t[4]=m*r+d*e+b*c+v*f,t[5]=m*o+d*M+b*h+v*x,t[6]=m*u+d*s+b*S+v*D,t[7]=m*l+d*i+b*I+v*F,m=n[8],d=n[9],b=n[10],v=n[11],t[8]=m*r+d*e+b*c+v*f,t[9]=m*o+d*M+b*h+v*x,t[10]=m*u+d*s+b*S+v*D,t[11]=m*l+d*i+b*I+v*F,m=n[12],d=n[13],b=n[14],v=n[15],t[12]=m*r+d*e+b*c+v*f,t[13]=m*o+d*M+b*h+v*x,t[14]=m*u+d*s+b*S+v*D,t[15]=m*l+d*i+b*I+v*F,t},o.multiply=r.USE_SIMD?o.SIMD.multiply:o.scalar.multiply,o.mul=o.multiply,o.scalar.translate=function(t,a,n){var r,o,u,l,e,M,s,i,c,h,S,I,f=n[0],x=n[1],D=n[2];return a===t?(t[12]=a[0]*f+a[4]*x+a[8]*D+a[12],t[13]=a[1]*f+a[5]*x+a[9]*D+a[13],t[14]=a[2]*f+a[6]*x+a[10]*D+a[14],t[15]=a[3]*f+a[7]*x+a[11]*D+a[15]):(r=a[0],o=a[1],u=a[2],l=a[3],e=a[4],M=a[5],s=a[6],i=a[7],c=a[8],h=a[9],S=a[10],I=a[11],t[0]=r,t[1]=o,t[2]=u,t[3]=l,t[4]=e,t[5]=M,t[6]=s,t[7]=i,t[8]=c,t[9]=h,t[10]=S,t[11]=I,t[12]=r*f+e*x+c*D+a[12],t[13]=o*f+M*x+h*D+a[13],t[14]=u*f+s*x+S*D+a[14],t[15]=l*f+i*x+I*D+a[15]),t},o.SIMD.translate=function(t,a,n){var r=SIMD.Float32x4.load(a,0),o=SIMD.Float32x4.load(a,4),u=SIMD.Float32x4.load(a,8),l=SIMD.Float32x4.load(a,12),e=SIMD.Float32x4(n[0],n[1],n[2],0);a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11]),r=SIMD.Float32x4.mul(r,SIMD.Float32x4.swizzle(e,0,0,0,0)),o=SIMD.Float32x4.mul(o,SIMD.Float32x4.swizzle(e,1,1,1,1)),u=SIMD.Float32x4.mul(u,SIMD.Float32x4.swizzle(e,2,2,2,2));var M=SIMD.Float32x4.add(r,SIMD.Float32x4.add(o,SIMD.Float32x4.add(u,l)));return SIMD.Float32x4.store(t,12,M),t},o.translate=r.USE_SIMD?o.SIMD.translate:o.scalar.translate,o.scalar.scale=function(t,a,n){var r=n[0],o=n[1],u=n[2];return t[0]=a[0]*r,t[1]=a[1]*r,t[2]=a[2]*r,t[3]=a[3]*r,t[4]=a[4]*o,t[5]=a[5]*o,t[6]=a[6]*o,t[7]=a[7]*o,t[8]=a[8]*u,t[9]=a[9]*u,t[10]=a[10]*u,t[11]=a[11]*u,t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.SIMD.scale=function(t,a,n){var r,o,u,l=SIMD.Float32x4(n[0],n[1],n[2],0);return r=SIMD.Float32x4.load(a,0),SIMD.Float32x4.store(t,0,SIMD.Float32x4.mul(r,SIMD.Float32x4.swizzle(l,0,0,0,0))),o=SIMD.Float32x4.load(a,4),SIMD.Float32x4.store(t,4,SIMD.Float32x4.mul(o,SIMD.Float32x4.swizzle(l,1,1,1,1))),u=SIMD.Float32x4.load(a,8),SIMD.Float32x4.store(t,8,SIMD.Float32x4.mul(u,SIMD.Float32x4.swizzle(l,2,2,2,2))),t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15],t},o.scale=r.USE_SIMD?o.SIMD.scale:o.scalar.scale,o.rotate=function(t,a,n,o){var u,l,e,M,s,i,c,h,S,I,f,x,D,F,m,d,b,v,z,p,w,E,A,P,L=o[0],q=o[1],R=o[2],N=Math.sqrt(L*L+q*q+R*R);return Math.abs(N)<r.EPSILON?null:(N=1/N,L*=N,q*=N,R*=N,u=Math.sin(n),l=Math.cos(n),e=1-l,M=a[0],s=a[1],i=a[2],c=a[3],h=a[4],S=a[5],I=a[6],f=a[7],x=a[8],D=a[9],F=a[10],m=a[11],d=L*L*e+l,b=q*L*e+R*u,v=R*L*e-q*u,z=L*q*e-R*u,p=q*q*e+l,w=R*q*e+L*u,E=L*R*e+q*u,A=q*R*e-L*u,P=R*R*e+l,t[0]=M*d+h*b+x*v,t[1]=s*d+S*b+D*v,t[2]=i*d+I*b+F*v,t[3]=c*d+f*b+m*v,t[4]=M*z+h*p+x*w,t[5]=s*z+S*p+D*w,t[6]=i*z+I*p+F*w,t[7]=c*z+f*p+m*w,t[8]=M*E+h*A+x*P,t[9]=s*E+S*A+D*P,t[10]=i*E+I*A+F*P,t[11]=c*E+f*A+m*P,a!==t&&(t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t)},o.scalar.rotateX=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[4],l=a[5],e=a[6],M=a[7],s=a[8],i=a[9],c=a[10],h=a[11];return a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[4]=u*o+s*r,t[5]=l*o+i*r,t[6]=e*o+c*r,t[7]=M*o+h*r,t[8]=s*o-u*r,t[9]=i*o-l*r,t[10]=c*o-e*r,t[11]=h*o-M*r,t},o.SIMD.rotateX=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,4),l=SIMD.Float32x4.load(a,8);return SIMD.Float32x4.store(t,4,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,8,SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,o),SIMD.Float32x4.mul(u,r))),t},o.rotateX=r.USE_SIMD?o.SIMD.rotateX:o.scalar.rotateX,o.scalar.rotateY=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[0],l=a[1],e=a[2],M=a[3],s=a[8],i=a[9],c=a[10],h=a[11];return a!==t&&(t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[0]=u*o-s*r,t[1]=l*o-i*r,t[2]=e*o-c*r,t[3]=M*o-h*r,t[8]=u*r+s*o,t[9]=l*r+i*o,t[10]=e*r+c*o,t[11]=M*r+h*o,t},o.SIMD.rotateY=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[4]=a[4],t[5]=a[5],t[6]=a[6],t[7]=a[7],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,0),l=SIMD.Float32x4.load(a,8);return SIMD.Float32x4.store(t,0,SIMD.Float32x4.sub(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,8,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,r),SIMD.Float32x4.mul(l,o))),t},o.rotateY=r.USE_SIMD?o.SIMD.rotateY:o.scalar.rotateY,o.scalar.rotateZ=function(t,a,n){var r=Math.sin(n),o=Math.cos(n),u=a[0],l=a[1],e=a[2],M=a[3],s=a[4],i=a[5],c=a[6],h=a[7];return a!==t&&(t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]),t[0]=u*o+s*r,t[1]=l*o+i*r,t[2]=e*o+c*r,t[3]=M*o+h*r,t[4]=s*o-u*r,t[5]=i*o-l*r,t[6]=c*o-e*r,t[7]=h*o-M*r,t},o.SIMD.rotateZ=function(t,a,n){var r=SIMD.Float32x4.splat(Math.sin(n)),o=SIMD.Float32x4.splat(Math.cos(n));a!==t&&(t[8]=a[8],t[9]=a[9],t[10]=a[10],t[11]=a[11],t[12]=a[12],t[13]=a[13],t[14]=a[14],t[15]=a[15]);var u=SIMD.Float32x4.load(a,0),l=SIMD.Float32x4.load(a,4);return SIMD.Float32x4.store(t,0,SIMD.Float32x4.add(SIMD.Float32x4.mul(u,o),SIMD.Float32x4.mul(l,r))),SIMD.Float32x4.store(t,4,SIMD.Float32x4.sub(SIMD.Float32x4.mul(l,o),SIMD.Float32x4.mul(u,r))),t},o.rotateZ=r.USE_SIMD?o.SIMD.rotateZ:o.scalar.rotateZ,o.fromTranslation=function(t,a){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=a[0],t[13]=a[1],t[14]=a[2],t[15]=1,t},o.fromScaling=function(t,a){return t[0]=a[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=a[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromRotation=function(t,a,n){var o,u,l,e=n[0],M=n[1],s=n[2],i=Math.sqrt(e*e+M*M+s*s);return Math.abs(i)<r.EPSILON?null:(i=1/i,e*=i,M*=i,s*=i,o=Math.sin(a),u=Math.cos(a),l=1-u,t[0]=e*e*l+u,t[1]=M*e*l+s*o,t[2]=s*e*l-M*o,t[3]=0,t[4]=e*M*l-s*o,t[5]=M*M*l+u,t[6]=s*M*l+e*o,t[7]=0,t[8]=e*s*l+M*o,t[9]=M*s*l-e*o,t[10]=s*s*l+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},o.fromXRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=r,t[6]=n,t[7]=0,t[8]=0,t[9]=-n,t[10]=r,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromYRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=0,t[2]=-n,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=n,t[9]=0,t[10]=r,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromZRotation=function(t,a){var n=Math.sin(a),r=Math.cos(a);return t[0]=r,t[1]=n,t[2]=0,t[3]=0,t[4]=-n,t[5]=r,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.fromRotationTranslation=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=r+r,M=o+o,s=u+u,i=r*e,c=r*M,h=r*s,S=o*M,I=o*s,f=u*s,x=l*e,D=l*M,F=l*s;return t[0]=1-(S+f),t[1]=c+F,t[2]=h-D,t[3]=0,t[4]=c-F,t[5]=1-(i+f),t[6]=I+x,t[7]=0,t[8]=h+D,t[9]=I-x,t[10]=1-(i+S),t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},o.getTranslation=function(t,a){return t[0]=a[12],t[1]=a[13],t[2]=a[14],t},o.getRotation=function(t,a){var n=a[0]+a[5]+a[10],r=0;return n>0?(r=2*Math.sqrt(n+1),t[3]=.25*r,t[0]=(a[6]-a[9])/r,t[1]=(a[8]-a[2])/r,t[2]=(a[1]-a[4])/r):a[0]>a[5]&a[0]>a[10]?(r=2*Math.sqrt(1+a[0]-a[5]-a[10]),t[3]=(a[6]-a[9])/r,t[0]=.25*r,t[1]=(a[1]+a[4])/r,t[2]=(a[8]+a[2])/r):a[5]>a[10]?(r=2*Math.sqrt(1+a[5]-a[0]-a[10]),t[3]=(a[8]-a[2])/r,t[0]=(a[1]+a[4])/r,t[1]=.25*r,t[2]=(a[6]+a[9])/r):(r=2*Math.sqrt(1+a[10]-a[0]-a[5]),t[3]=(a[1]-a[4])/r,t[0]=(a[8]+a[2])/r,t[1]=(a[6]+a[9])/r,t[2]=.25*r),t},o.fromRotationTranslationScale=function(t,a,n,r){var o=a[0],u=a[1],l=a[2],e=a[3],M=o+o,s=u+u,i=l+l,c=o*M,h=o*s,S=o*i,I=u*s,f=u*i,x=l*i,D=e*M,F=e*s,m=e*i,d=r[0],b=r[1],v=r[2];return t[0]=(1-(I+x))*d,t[1]=(h+m)*d,t[2]=(S-F)*d,t[3]=0,t[4]=(h-m)*b,t[5]=(1-(c+x))*b,t[6]=(f+D)*b,t[7]=0,t[8]=(S+F)*v,t[9]=(f-D)*v,t[10]=(1-(c+I))*v,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},o.fromRotationTranslationScaleOrigin=function(t,a,n,r,o){
+var u=a[0],l=a[1],e=a[2],M=a[3],s=u+u,i=l+l,c=e+e,h=u*s,S=u*i,I=u*c,f=l*i,x=l*c,D=e*c,F=M*s,m=M*i,d=M*c,b=r[0],v=r[1],z=r[2],p=o[0],w=o[1],E=o[2];return t[0]=(1-(f+D))*b,t[1]=(S+d)*b,t[2]=(I-m)*b,t[3]=0,t[4]=(S-d)*v,t[5]=(1-(h+D))*v,t[6]=(x+F)*v,t[7]=0,t[8]=(I+m)*z,t[9]=(x-F)*z,t[10]=(1-(h+f))*z,t[11]=0,t[12]=n[0]+p-(t[0]*p+t[4]*w+t[8]*E),t[13]=n[1]+w-(t[1]*p+t[5]*w+t[9]*E),t[14]=n[2]+E-(t[2]*p+t[6]*w+t[10]*E),t[15]=1,t},o.fromQuat=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n+n,e=r+r,M=o+o,s=n*l,i=r*l,c=r*e,h=o*l,S=o*e,I=o*M,f=u*l,x=u*e,D=u*M;return t[0]=1-c-I,t[1]=i+D,t[2]=h-x,t[3]=0,t[4]=i-D,t[5]=1-s-I,t[6]=S+f,t[7]=0,t[8]=h+x,t[9]=S-f,t[10]=1-s-c,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},o.frustum=function(t,a,n,r,o,u,l){var e=1/(n-a),M=1/(o-r),s=1/(u-l);return t[0]=2*u*e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*M,t[6]=0,t[7]=0,t[8]=(n+a)*e,t[9]=(o+r)*M,t[10]=(l+u)*s,t[11]=-1,t[12]=0,t[13]=0,t[14]=l*u*2*s,t[15]=0,t},o.perspective=function(t,a,n,r,o){var u=1/Math.tan(a/2),l=1/(r-o);return t[0]=u/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(o+r)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*o*r*l,t[15]=0,t},o.perspectiveFromFieldOfView=function(t,a,n,r){var o=Math.tan(a.upDegrees*Math.PI/180),u=Math.tan(a.downDegrees*Math.PI/180),l=Math.tan(a.leftDegrees*Math.PI/180),e=Math.tan(a.rightDegrees*Math.PI/180),M=2/(l+e),s=2/(o+u);return t[0]=M,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=s,t[6]=0,t[7]=0,t[8]=-((l-e)*M*.5),t[9]=(o-u)*s*.5,t[10]=r/(n-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*n/(n-r),t[15]=0,t},o.ortho=function(t,a,n,r,o,u,l){var e=1/(a-n),M=1/(r-o),s=1/(u-l);return t[0]=-2*e,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*M,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*s,t[11]=0,t[12]=(a+n)*e,t[13]=(o+r)*M,t[14]=(l+u)*s,t[15]=1,t},o.lookAt=function(t,a,n,u){var l,e,M,s,i,c,h,S,I,f,x=a[0],D=a[1],F=a[2],m=u[0],d=u[1],b=u[2],v=n[0],z=n[1],p=n[2];return Math.abs(x-v)<r.EPSILON&&Math.abs(D-z)<r.EPSILON&&Math.abs(F-p)<r.EPSILON?o.identity(t):(h=x-v,S=D-z,I=F-p,f=1/Math.sqrt(h*h+S*S+I*I),h*=f,S*=f,I*=f,l=d*I-b*S,e=b*h-m*I,M=m*S-d*h,f=Math.sqrt(l*l+e*e+M*M),f?(f=1/f,l*=f,e*=f,M*=f):(l=0,e=0,M=0),s=S*M-I*e,i=I*l-h*M,c=h*e-S*l,f=Math.sqrt(s*s+i*i+c*c),f?(f=1/f,s*=f,i*=f,c*=f):(s=0,i=0,c=0),t[0]=l,t[1]=s,t[2]=h,t[3]=0,t[4]=e,t[5]=i,t[6]=S,t[7]=0,t[8]=M,t[9]=c,t[10]=I,t[11]=0,t[12]=-(l*x+e*D+M*F),t[13]=-(s*x+i*D+c*F),t[14]=-(h*x+S*D+I*F),t[15]=1,t)},o.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},o.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t[4]=a[4]+n[4],t[5]=a[5]+n[5],t[6]=a[6]+n[6],t[7]=a[7]+n[7],t[8]=a[8]+n[8],t[9]=a[9]+n[9],t[10]=a[10]+n[10],t[11]=a[11]+n[11],t[12]=a[12]+n[12],t[13]=a[13]+n[13],t[14]=a[14]+n[14],t[15]=a[15]+n[15],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t[4]=a[4]-n[4],t[5]=a[5]-n[5],t[6]=a[6]-n[6],t[7]=a[7]-n[7],t[8]=a[8]-n[8],t[9]=a[9]-n[9],t[10]=a[10]-n[10],t[11]=a[11]-n[11],t[12]=a[12]-n[12],t[13]=a[13]-n[13],t[14]=a[14]-n[14],t[15]=a[15]-n[15],t},o.sub=o.subtract,o.multiplyScalar=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t[4]=a[4]*n,t[5]=a[5]*n,t[6]=a[6]*n,t[7]=a[7]*n,t[8]=a[8]*n,t[9]=a[9]*n,t[10]=a[10]*n,t[11]=a[11]*n,t[12]=a[12]*n,t[13]=a[13]*n,t[14]=a[14]*n,t[15]=a[15]*n,t},o.multiplyScalarAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t[4]=a[4]+n[4]*r,t[5]=a[5]+n[5]*r,t[6]=a[6]+n[6]*r,t[7]=a[7]+n[7]*r,t[8]=a[8]+n[8]*r,t[9]=a[9]+n[9]*r,t[10]=a[10]+n[10]*r,t[11]=a[11]+n[11]*r,t[12]=a[12]+n[12]*r,t[13]=a[13]+n[13]*r,t[14]=a[14]+n[14]*r,t[15]=a[15]+n[15]*r,t},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]&&t[4]===a[4]&&t[5]===a[5]&&t[6]===a[6]&&t[7]===a[7]&&t[8]===a[8]&&t[9]===a[9]&&t[10]===a[10]&&t[11]===a[11]&&t[12]===a[12]&&t[13]===a[13]&&t[14]===a[14]&&t[15]===a[15]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=t[4],M=t[5],s=t[6],i=t[7],c=t[8],h=t[9],S=t[10],I=t[11],f=t[12],x=t[13],D=t[14],F=t[15],m=a[0],d=a[1],b=a[2],v=a[3],z=a[4],p=a[5],w=a[6],E=a[7],A=a[8],P=a[9],L=a[10],q=a[11],R=a[12],N=a[13],O=a[14],Y=a[15];return Math.abs(n-m)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(m))&&Math.abs(o-d)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(d))&&Math.abs(u-b)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(b))&&Math.abs(l-v)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(v))&&Math.abs(e-z)<=r.EPSILON*Math.max(1,Math.abs(e),Math.abs(z))&&Math.abs(M-p)<=r.EPSILON*Math.max(1,Math.abs(M),Math.abs(p))&&Math.abs(s-w)<=r.EPSILON*Math.max(1,Math.abs(s),Math.abs(w))&&Math.abs(i-E)<=r.EPSILON*Math.max(1,Math.abs(i),Math.abs(E))&&Math.abs(c-A)<=r.EPSILON*Math.max(1,Math.abs(c),Math.abs(A))&&Math.abs(h-P)<=r.EPSILON*Math.max(1,Math.abs(h),Math.abs(P))&&Math.abs(S-L)<=r.EPSILON*Math.max(1,Math.abs(S),Math.abs(L))&&Math.abs(I-q)<=r.EPSILON*Math.max(1,Math.abs(I),Math.abs(q))&&Math.abs(f-R)<=r.EPSILON*Math.max(1,Math.abs(f),Math.abs(R))&&Math.abs(x-N)<=r.EPSILON*Math.max(1,Math.abs(x),Math.abs(N))&&Math.abs(D-O)<=r.EPSILON*Math.max(1,Math.abs(D),Math.abs(O))&&Math.abs(F-Y)<=r.EPSILON*Math.max(1,Math.abs(F),Math.abs(Y))},t.exports=o},function(t,a,n){var r=n(1),o=n(4),u=n(7),l=n(8),e={};e.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},e.rotationTo=function(){var t=u.create(),a=u.fromValues(1,0,0),n=u.fromValues(0,1,0);return function(r,o,l){var M=u.dot(o,l);return M<-.999999?(u.cross(t,a,o),u.length(t)<1e-6&&u.cross(t,n,o),u.normalize(t,t),e.setAxisAngle(r,t,Math.PI),r):M>.999999?(r[0]=0,r[1]=0,r[2]=0,r[3]=1,r):(u.cross(t,o,l),r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=1+M,e.normalize(r,r))}}(),e.setAxes=function(){var t=o.create();return function(a,n,r,o){return t[0]=r[0],t[3]=r[1],t[6]=r[2],t[1]=o[0],t[4]=o[1],t[7]=o[2],t[2]=-n[0],t[5]=-n[1],t[8]=-n[2],e.normalize(a,e.fromMat3(a,t))}}(),e.clone=l.clone,e.fromValues=l.fromValues,e.copy=l.copy,e.set=l.set,e.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},e.setAxisAngle=function(t,a,n){n=.5*n;var r=Math.sin(n);return t[0]=r*a[0],t[1]=r*a[1],t[2]=r*a[2],t[3]=Math.cos(n),t},e.getAxisAngle=function(t,a){var n=2*Math.acos(a[3]),r=Math.sin(n/2);return 0!=r?(t[0]=a[0]/r,t[1]=a[1]/r,t[2]=a[2]/r):(t[0]=1,t[1]=0,t[2]=0),n},e.add=l.add,e.multiply=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3],e=n[0],M=n[1],s=n[2],i=n[3];return t[0]=r*i+l*e+o*s-u*M,t[1]=o*i+l*M+u*e-r*s,t[2]=u*i+l*s+r*M-o*e,t[3]=l*i-r*e-o*M-u*s,t},e.mul=e.multiply,e.scale=l.scale,e.rotateX=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+l*e,t[1]=o*M+u*e,t[2]=u*M-o*e,t[3]=l*M-r*e,t},e.rotateY=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M-u*e,t[1]=o*M+l*e,t[2]=u*M+r*e,t[3]=l*M-o*e,t},e.rotateZ=function(t,a,n){n*=.5;var r=a[0],o=a[1],u=a[2],l=a[3],e=Math.sin(n),M=Math.cos(n);return t[0]=r*M+o*e,t[1]=o*M-r*e,t[2]=u*M+l*e,t[3]=l*M-u*e,t},e.calculateW=function(t,a){var n=a[0],r=a[1],o=a[2];return t[0]=n,t[1]=r,t[2]=o,t[3]=Math.sqrt(Math.abs(1-n*n-r*r-o*o)),t},e.dot=l.dot,e.lerp=l.lerp,e.slerp=function(t,a,n,r){var o,u,l,e,M,s=a[0],i=a[1],c=a[2],h=a[3],S=n[0],I=n[1],f=n[2],x=n[3];return u=s*S+i*I+c*f+h*x,u<0&&(u=-u,S=-S,I=-I,f=-f,x=-x),1-u>1e-6?(o=Math.acos(u),l=Math.sin(o),e=Math.sin((1-r)*o)/l,M=Math.sin(r*o)/l):(e=1-r,M=r),t[0]=e*s+M*S,t[1]=e*i+M*I,t[2]=e*c+M*f,t[3]=e*h+M*x,t},e.sqlerp=function(){var t=e.create(),a=e.create();return function(n,r,o,u,l,M){return e.slerp(t,r,l,M),e.slerp(a,o,u,M),e.slerp(n,t,a,2*M*(1-M)),n}}(),e.invert=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*n+r*r+o*o+u*u,e=l?1/l:0;return t[0]=-n*e,t[1]=-r*e,t[2]=-o*e,t[3]=u*e,t},e.conjugate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t[3]=a[3],t},e.length=l.length,e.len=e.length,e.squaredLength=l.squaredLength,e.sqrLen=e.squaredLength,e.normalize=l.normalize,e.fromMat3=function(t,a){var n,r=a[0]+a[4]+a[8];if(r>0)n=Math.sqrt(r+1),t[3]=.5*n,n=.5/n,t[0]=(a[5]-a[7])*n,t[1]=(a[6]-a[2])*n,t[2]=(a[1]-a[3])*n;else{var o=0;a[4]>a[0]&&(o=1),a[8]>a[3*o+o]&&(o=2);var u=(o+1)%3,l=(o+2)%3;n=Math.sqrt(a[3*o+o]-a[3*u+u]-a[3*l+l]+1),t[o]=.5*n,n=.5/n,t[3]=(a[3*u+l]-a[3*l+u])*n,t[u]=(a[3*u+o]+a[3*o+u])*n,t[l]=(a[3*l+o]+a[3*o+l])*n}return t},e.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.exactEquals=l.exactEquals,e.equals=l.equals,t.exports=e},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(3);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a},o.fromValues=function(t,a,n){var o=new r.ARRAY_TYPE(3);return o[0]=t,o[1]=a,o[2]=n,o},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t},o.set=function(t,a,n,r){return t[0]=a,t[1]=n,t[2]=r,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t[2]=a[2]*n[2],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t[2]=a[2]/n[2],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t[2]=Math.ceil(a[2]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t[2]=Math.floor(a[2]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t[2]=Math.min(a[2],n[2]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t[2]=Math.max(a[2],n[2]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t[2]=Math.round(a[2]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2];return Math.sqrt(n*n+r*r+o*o)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2];return n*n+r*r+o*o},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1],r=t[2];return Math.sqrt(a*a+n*n+r*r)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1],r=t[2];return a*a+n*n+r*r},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t[2]=1/a[2],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=a[2],u=n*n+r*r+o*o;return u>0&&(u=1/Math.sqrt(u),t[0]=a[0]*u,t[1]=a[1]*u,t[2]=a[2]*u),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]+t[2]*a[2]},o.cross=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2];return t[0]=o*M-u*e,t[1]=u*l-r*M,t[2]=r*e-o*l,t},o.lerp=function(t,a,n,r){var o=a[0],u=a[1],l=a[2];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t[2]=l+r*(n[2]-l),t},o.hermite=function(t,a,n,r,o,u){var l=u*u,e=l*(2*u-3)+1,M=l*(u-2)+u,s=l*(u-1),i=l*(3-2*u);return t[0]=a[0]*e+n[0]*M+r[0]*s+o[0]*i,t[1]=a[1]*e+n[1]*M+r[1]*s+o[1]*i,t[2]=a[2]*e+n[2]*M+r[2]*s+o[2]*i,t},o.bezier=function(t,a,n,r,o,u){var l=1-u,e=l*l,M=u*u,s=e*l,i=3*u*e,c=3*M*l,h=M*u;return t[0]=a[0]*s+n[0]*i+r[0]*c+o[0]*h,t[1]=a[1]*s+n[1]*i+r[1]*c+o[1]*h,t[2]=a[2]*s+n[2]*i+r[2]*c+o[2]*h,t},o.random=function(t,a){a=a||1;var n=2*r.RANDOM()*Math.PI,o=2*r.RANDOM()-1,u=Math.sqrt(1-o*o)*a;return t[0]=Math.cos(n)*u,t[1]=Math.sin(n)*u,t[2]=o*a,t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[3]*r+n[7]*o+n[11]*u+n[15];return l=l||1,t[0]=(n[0]*r+n[4]*o+n[8]*u+n[12])/l,t[1]=(n[1]*r+n[5]*o+n[9]*u+n[13])/l,t[2]=(n[2]*r+n[6]*o+n[10]*u+n[14])/l,t},o.transformMat3=function(t,a,n){var r=a[0],o=a[1],u=a[2];return t[0]=r*n[0]+o*n[3]+u*n[6],t[1]=r*n[1]+o*n[4]+u*n[7],t[2]=r*n[2]+o*n[5]+u*n[8],t},o.transformQuat=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2],s=n[3],i=s*r+e*u-M*o,c=s*o+M*r-l*u,h=s*u+l*o-e*r,S=-l*r-e*o-M*u;return t[0]=i*s+S*-l+c*-M-h*-e,t[1]=c*s+S*-e+h*-l-i*-M,t[2]=h*s+S*-M+i*-e-c*-l,t},o.rotateX=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[0],u[1]=o[1]*Math.cos(r)-o[2]*Math.sin(r),u[2]=o[1]*Math.sin(r)+o[2]*Math.cos(r),t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.rotateY=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[2]*Math.sin(r)+o[0]*Math.cos(r),u[1]=o[1],u[2]=o[2]*Math.cos(r)-o[0]*Math.sin(r),t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.rotateZ=function(t,a,n,r){var o=[],u=[];return o[0]=a[0]-n[0],o[1]=a[1]-n[1],o[2]=a[2]-n[2],u[0]=o[0]*Math.cos(r)-o[1]*Math.sin(r),u[1]=o[0]*Math.sin(r)+o[1]*Math.cos(r),u[2]=o[2],t[0]=u[0]+n[0],t[1]=u[1]+n[1],t[2]=u[2]+n[2],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=3),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],t[2]=a[e+2],u(t,t,l),a[e]=t[0],a[e+1]=t[1],a[e+2]=t[2];return a}}(),o.angle=function(t,a){var n=o.fromValues(t[0],t[1],t[2]),r=o.fromValues(a[0],a[1],a[2]);o.normalize(n,n),o.normalize(r,r);var u=o.dot(n,r);return u>1?0:Math.acos(u)},o.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=a[0],e=a[1],M=a[2];return Math.abs(n-l)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(l))&&Math.abs(o-e)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(e))&&Math.abs(u-M)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(M))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(4);return a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3],a},o.fromValues=function(t,a,n,o){var u=new r.ARRAY_TYPE(4);return u[0]=t,u[1]=a,u[2]=n,u[3]=o,u},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t[2]=a[2],t[3]=a[3],t},o.set=function(t,a,n,r,o){return t[0]=a,t[1]=n,t[2]=r,t[3]=o,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t[2]=a[2]+n[2],t[3]=a[3]+n[3],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t[2]=a[2]-n[2],t[3]=a[3]-n[3],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t[2]=a[2]*n[2],t[3]=a[3]*n[3],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t[2]=a[2]/n[2],t[3]=a[3]/n[3],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t[2]=Math.ceil(a[2]),t[3]=Math.ceil(a[3]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t[2]=Math.floor(a[2]),t[3]=Math.floor(a[3]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t[2]=Math.min(a[2],n[2]),t[3]=Math.min(a[3],n[3]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t[2]=Math.max(a[2],n[2]),t[3]=Math.max(a[3],n[3]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t[2]=Math.round(a[2]),t[3]=Math.round(a[3]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t[2]=a[2]*n,t[3]=a[3]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t[2]=a[2]+n[2]*r,t[3]=a[3]+n[3]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2],u=a[3]-t[3];return Math.sqrt(n*n+r*r+o*o+u*u)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1],o=a[2]-t[2],u=a[3]-t[3];return n*n+r*r+o*o+u*u},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1],r=t[2],o=t[3];return Math.sqrt(a*a+n*n+r*r+o*o)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1],r=t[2],o=t[3];return a*a+n*n+r*r+o*o},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t[2]=-a[2],t[3]=-a[3],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t[2]=1/a[2],t[3]=1/a[3],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=a[2],u=a[3],l=n*n+r*r+o*o+u*u;return l>0&&(l=1/Math.sqrt(l),t[0]=n*l,t[1]=r*l,t[2]=o*l,t[3]=u*l),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]+t[2]*a[2]+t[3]*a[3]},o.lerp=function(t,a,n,r){var o=a[0],u=a[1],l=a[2],e=a[3];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t[2]=l+r*(n[2]-l),t[3]=e+r*(n[3]-e),t},o.random=function(t,a){return a=a||1,t[0]=r.RANDOM(),t[1]=r.RANDOM(),t[2]=r.RANDOM(),t[3]=r.RANDOM(),o.normalize(t,t),o.scale(t,t,a),t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=a[3];return t[0]=n[0]*r+n[4]*o+n[8]*u+n[12]*l,t[1]=n[1]*r+n[5]*o+n[9]*u+n[13]*l,t[2]=n[2]*r+n[6]*o+n[10]*u+n[14]*l,t[3]=n[3]*r+n[7]*o+n[11]*u+n[15]*l,t},o.transformQuat=function(t,a,n){var r=a[0],o=a[1],u=a[2],l=n[0],e=n[1],M=n[2],s=n[3],i=s*r+e*u-M*o,c=s*o+M*r-l*u,h=s*u+l*o-e*r,S=-l*r-e*o-M*u;return t[0]=i*s+S*-l+c*-M-h*-e,t[1]=c*s+S*-e+h*-l-i*-M,t[2]=h*s+S*-M+i*-e-c*-l,t[3]=a[3],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=4),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],t[2]=a[e+2],t[3]=a[e+3],u(t,t,l),a[e]=t[0],a[e+1]=t[1],a[e+2]=t[2],a[e+3]=t[3];return a}}(),o.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]&&t[2]===a[2]&&t[3]===a[3]},o.equals=function(t,a){var n=t[0],o=t[1],u=t[2],l=t[3],e=a[0],M=a[1],s=a[2],i=a[3];return Math.abs(n-e)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(e))&&Math.abs(o-M)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(M))&&Math.abs(u-s)<=r.EPSILON*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(l-i)<=r.EPSILON*Math.max(1,Math.abs(l),Math.abs(i))},t.exports=o},function(t,a,n){var r=n(1),o={};o.create=function(){var t=new r.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},o.clone=function(t){var a=new r.ARRAY_TYPE(2);return a[0]=t[0],a[1]=t[1],a},o.fromValues=function(t,a){var n=new r.ARRAY_TYPE(2);return n[0]=t,n[1]=a,n},o.copy=function(t,a){return t[0]=a[0],t[1]=a[1],t},o.set=function(t,a,n){return t[0]=a,t[1]=n,t},o.add=function(t,a,n){return t[0]=a[0]+n[0],t[1]=a[1]+n[1],t},o.subtract=function(t,a,n){return t[0]=a[0]-n[0],t[1]=a[1]-n[1],t},o.sub=o.subtract,o.multiply=function(t,a,n){return t[0]=a[0]*n[0],t[1]=a[1]*n[1],t},o.mul=o.multiply,o.divide=function(t,a,n){return t[0]=a[0]/n[0],t[1]=a[1]/n[1],t},o.div=o.divide,o.ceil=function(t,a){return t[0]=Math.ceil(a[0]),t[1]=Math.ceil(a[1]),t},o.floor=function(t,a){return t[0]=Math.floor(a[0]),t[1]=Math.floor(a[1]),t},o.min=function(t,a,n){return t[0]=Math.min(a[0],n[0]),t[1]=Math.min(a[1],n[1]),t},o.max=function(t,a,n){return t[0]=Math.max(a[0],n[0]),t[1]=Math.max(a[1],n[1]),t},o.round=function(t,a){return t[0]=Math.round(a[0]),t[1]=Math.round(a[1]),t},o.scale=function(t,a,n){return t[0]=a[0]*n,t[1]=a[1]*n,t},o.scaleAndAdd=function(t,a,n,r){return t[0]=a[0]+n[0]*r,t[1]=a[1]+n[1]*r,t},o.distance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1];return Math.sqrt(n*n+r*r)},o.dist=o.distance,o.squaredDistance=function(t,a){var n=a[0]-t[0],r=a[1]-t[1];return n*n+r*r},o.sqrDist=o.squaredDistance,o.length=function(t){var a=t[0],n=t[1];return Math.sqrt(a*a+n*n)},o.len=o.length,o.squaredLength=function(t){var a=t[0],n=t[1];return a*a+n*n},o.sqrLen=o.squaredLength,o.negate=function(t,a){return t[0]=-a[0],t[1]=-a[1],t},o.inverse=function(t,a){return t[0]=1/a[0],t[1]=1/a[1],t},o.normalize=function(t,a){var n=a[0],r=a[1],o=n*n+r*r;return o>0&&(o=1/Math.sqrt(o),t[0]=a[0]*o,t[1]=a[1]*o),t},o.dot=function(t,a){return t[0]*a[0]+t[1]*a[1]},o.cross=function(t,a,n){var r=a[0]*n[1]-a[1]*n[0];return t[0]=t[1]=0,t[2]=r,t},o.lerp=function(t,a,n,r){var o=a[0],u=a[1];return t[0]=o+r*(n[0]-o),t[1]=u+r*(n[1]-u),t},o.random=function(t,a){a=a||1;var n=2*r.RANDOM()*Math.PI;return t[0]=Math.cos(n)*a,t[1]=Math.sin(n)*a,t},o.transformMat2=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[2]*o,t[1]=n[1]*r+n[3]*o,t},o.transformMat2d=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[2]*o+n[4],t[1]=n[1]*r+n[3]*o+n[5],t},o.transformMat3=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[3]*o+n[6],t[1]=n[1]*r+n[4]*o+n[7],t},o.transformMat4=function(t,a,n){var r=a[0],o=a[1];return t[0]=n[0]*r+n[4]*o+n[12],t[1]=n[1]*r+n[5]*o+n[13],t},o.forEach=function(){var t=o.create();return function(a,n,r,o,u,l){var e,M;for(n||(n=2),r||(r=0),M=o?Math.min(o*n+r,a.length):a.length,e=r;e<M;e+=n)t[0]=a[e],t[1]=a[e+1],u(t,t,l),a[e]=t[0],a[e+1]=t[1];return a}}(),o.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},o.exactEquals=function(t,a){return t[0]===a[0]&&t[1]===a[1]},o.equals=function(t,a){var n=t[0],o=t[1],u=a[0],l=a[1];return Math.abs(n-u)<=r.EPSILON*Math.max(1,Math.abs(n),Math.abs(u))&&Math.abs(o-l)<=r.EPSILON*Math.max(1,Math.abs(o),Math.abs(l))},t.exports=o}])}); \ No newline at end of file
diff --git a/graphics/asymptote/webgl/gl.js b/graphics/asymptote/webgl/gl.js
new file mode 100644
index 0000000000..ab2f5fa799
--- /dev/null
+++ b/graphics/asymptote/webgl/gl.js
@@ -0,0 +1,922 @@
+// Contains code from http: //learningwebgl.com/blog/ ? p=28#triangle-vertex-positions
+// modified to produce a subdivision algorithm for rendering Bezier
+// patches with WebGL
+
+var gl;
+
+class Material {
+ constructor(baseColor, emissive, specular, roughness, metallic, f0) {
+ this.baseColor = baseColor;
+ this.emissive = emissive;
+ this.specular = specular;
+ this.roughness = roughness;
+ this.metallic = metallic;
+ this.f0 = f0;
+ }
+
+ setUniform(program, stringLoc, index=null) {
+ var getLoc;
+ if (index===null) {
+ getLoc =
+ param => gl.getUniformLocation(program, stringLoc + "." + param);
+ } else {
+ getLoc =
+ param => gl.getUniformLocation(program, stringLoc + "[" + index + "]." + param);
+ }
+
+ gl.uniform4fv(getLoc("baseColor"), new Float32Array(this.baseColor));
+ gl.uniform4fv(getLoc("emissive"), new Float32Array(this.emissive));
+ gl.uniform4fv(getLoc("specular"), new Float32Array(this.specular));
+
+ gl.uniform1f(getLoc("roughness"), this.roughness);
+ gl.uniform1f(getLoc("metallic"), this.metallic);
+ gl.uniform1f(getLoc("f0"), this.f0);
+ }
+}
+
+var enumPointLight = 1;
+var enumDirectionalLight = 2;
+
+class Light {
+ constructor(type, lightColor, brightness, customParam) {
+ this.type = type;
+ this.lightColor = lightColor;
+ this.brightness = brightness;
+ this.customParam = customParam;
+ }
+
+ setUniform(program, stringLoc, index) {
+ var getLoc =
+ param => gl.getUniformLocation(program, stringLoc + "[" + index + "]." + param);
+
+ gl.uniform1i(getLoc("type"), this.type);
+ gl.uniform3fv(getLoc("color"), new Float32Array(this.lightColor));
+ gl.uniform1f(getLoc("brightness"), this.brightness);
+ gl.uniform4fv(getLoc("parameter"), new Float32Array(this.customParam));
+ }
+}
+
+function initGL(canvas) {
+ try {
+ gl = canvas.getContext("webgl2");
+ gl.viewportWidth = canvas.width;
+ gl.viewportHeight = canvas.height;
+ } catch (e) {}
+ if (!gl) {
+ alert("Could not initialize WebGL");
+ }
+}
+
+function getShader(gl, id) {
+ var shaderScript = document.getElementById(id);
+ if (!shaderScript) {
+ return null;
+ }
+ var str = "";
+ var k = shaderScript.firstChild;
+ while (k) {
+ if (k.nodeType == 3) {
+ str += k.textContent;
+ }
+ k = k.nextSibling;
+ }
+ var shader;
+ if (shaderScript.type == "x-shader/x-fragment") {
+ shader = gl.createShader(gl.FRAGMENT_SHADER);
+ } else if (shaderScript.type == "x-shader/x-vertex") {
+ shader = gl.createShader(gl.VERTEX_SHADER);
+ } else {
+ return null;
+ }
+ gl.shaderSource(shader, str);
+ gl.compileShader(shader);
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
+ alert(gl.getShaderInfoLog(shader));
+ return null;
+ }
+ return shader;
+}
+
+function resetCamera() {
+ cameraPos = vec3.fromValues(0, 0, 2);
+ cameraLookAt = vec3.fromValues(0, 0, 0);
+ cameraUp = vec3.fromValues(1, 0, 0);
+ sceneSetup();
+ redraw=true;
+}
+
+var shaderProgram;
+
+function initShaders() {
+ var fragmentShader = getShader(gl, "shader-fs");
+ var vertexShader = getShader(gl, "shader-vs");
+ shaderProgram = gl.createProgram();
+ gl.attachShader(shaderProgram, vertexShader);
+ gl.attachShader(shaderProgram, fragmentShader);
+ gl.linkProgram(shaderProgram);
+ if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
+ alert("Could not initialize shaders");
+ }
+ gl.useProgram(shaderProgram);
+
+ shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
+ gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
+ shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
+ gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
+ shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
+ gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
+
+ shaderProgram.vertexMaterialIndexAttribute = gl.getAttribLocation(shaderProgram, "aVertexMaterialIndex");
+ gl.enableVertexAttribArray(shaderProgram.vertexMaterialIndexAttribute);
+
+
+ shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
+ shaderProgram.mMatrixUniform = gl.getUniformLocation(shaderProgram, "uMMatrix");
+ shaderProgram.vMatrixUniform = gl.getUniformLocation(shaderProgram, "uVMatrix");
+ shaderProgram.nlightsUniform = gl.getUniformLocation(shaderProgram, "unLights");
+ shaderProgram.useColorUniform = gl.getUniformLocation(shaderProgram, "useColor");
+
+}
+
+
+// math aux functions
+function degToRad(degrees) {
+ return degrees * Math.PI / 180;
+}
+function unit(v) {
+ var norm = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ norm = (norm != 0) ? 1 / norm : 1;
+ return [v[0] * norm, v[1] * norm, v[2] * norm];
+}
+
+function abs2(v) {
+return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+}
+
+function dot(u, v) {
+return u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
+}
+
+function cross(u, v) {
+return [u[1] * v[2] - u[2] * v[1],
+ u[2] * v[0] - u[0] * v[2],
+ u[0] * v[1] - u[1] * v[0]
+];
+}
+// return the perpendicular distance squared of a point z from the plane
+// through u with unit normal n.
+function Distance2(z, u, n) {
+ var d = dot([z[0] - u[0], z[1] - u[1], z[2] - u[2]], n);
+ return d * d;
+}
+
+var vMatrix = mat4.create();
+var mMatrix = mat4.create();
+var pMatrix = mat4.create();
+
+var headlamp = new Light(
+ type = enumDirectionalLight,
+ lightColor = [1, 0.87, 0.745],
+ brightness = 1,
+ customParam = [0, 0, 1, 0]
+);
+
+function setUniforms() {
+ gl.uniformMatrix4fv(shaderProgram.vMatrixUniform, false, vMatrix);
+ gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
+ gl.uniformMatrix4fv(shaderProgram.mMatrixUniform, false, mMatrix);
+
+ objMaterial.setUniform(shaderProgram, "objMaterial", 0);
+
+ // for now, if we simulate headlamp. Can also specify custom lights later on...
+ headlamp.setUniform(shaderProgram, "objLights", 0);
+ gl.uniform1i(shaderProgram.nlightsUniform, 1);
+ gl.uniform1i(shaderProgram.useColorUniform, 0);
+
+}
+
+var VertexBuffer;
+var ColorBuffer;
+var NormalBuffer;
+
+// base buffer arrays
+var vertices = new Array();
+var colors = new Array();
+var normals = new Array();
+var indices = new Array();
+var materials = new Array();
+
+// no. of verts.
+var nvertices = 0;
+
+var mMatrixStack = [];
+var pMatrix = mat4.create();
+var viewMatrix = mat4.create();
+var localRotation = mat4.create();
+
+function mvPushMatrix() {
+ var copy = mat4.create();
+ mat4.set(mMatrix, copy);
+ mMatrixStack.push(copy);
+}
+
+function mvPopMatrix() {
+ if (mMatrixStack.length == 0) {
+ throw "Invalid popMatrix!";
+ }
+ mMatrix = mMatrixStack.pop();
+}
+
+var redraw = true;
+var mouseDownOrTouchActive = false;
+var lastMouseX = null;
+var lastMouseY = null;
+var touchID = null;
+
+
+var center = [0, 0, 1];
+var centerInv = [0, 0, -1];
+
+var rotationMatLocal = mat4.create();
+var rotationMatrix = mat4.create();
+mat4.identity(rotationMatrix);
+
+function handleMouseDown(event) {
+ mouseDownOrTouchActive = true;
+ lastMouseX = event.clientX;
+ lastMouseY = event.clientY;
+}
+
+function handleTouchStart(evt) {
+ evt.preventDefault();
+ var touches = evt.targetTouches;
+
+ if (touches.length == 1 && !mouseDownOrTouchActive) {
+ touchId = touches[0].identifier;
+ lastMouseX = touches[0].pageX,
+ lastMouseY = touches[0].pageY;
+ }
+}
+
+function handleMouseUpOrTouchEnd(event) {
+ mouseDownOrTouchActive = false;
+}
+
+function processDrag(newX, newY, pan = false) {
+ let lastX = (lastMouseX - 400) / 400;
+ let lastY = (lastMouseY - 400) / 400;
+
+ let rawX = (newX - 400) / 400;
+ let rawY = (newY - 400) / 400;
+
+ let viewmatInv = mat4.create();
+ mat4.invert(viewmatInv, vMatrix);
+
+ let tmpCameraOffset = vec3.create();
+ vec3.subtract(tmpCameraOffset, cameraPos, cameraLookAt);
+
+ if (!pan) {
+ let [angle, axis] = arcballLib.arcball([lastX, -lastY], [rawX, -rawY]);
+
+ if (angle == NaN || axis == NaN) {
+ console.error("Angle or axis NaN!");
+ return;
+ }
+
+ let depthVec = vec3.clone(cameraLookAt);
+ vec3.transformMat4(depthVec, depthVec, vMatrix);
+ //vec3.transformMat4(depthVec, depthVec, pMatrix);
+ vec3.add(axis, axis, depthVec);
+
+ // let projMatInv=mat4.create();
+ // mat4.invert(projMatInv, pMatrix);
+
+ //vec3.transformMat4(axis,axis,projMatInv);
+ vec3.transformMat4(axis, axis, viewmatInv);
+
+ let tmpRotMat = mat4.create();
+
+ mat4.fromRotation(tmpRotMat, -angle, axis);
+
+ vec3.transformMat4(tmpCameraOffset, tmpCameraOffset, tmpRotMat);
+ vec3.transformMat4(cameraUp, cameraUp, tmpRotMat);
+
+ vec3.add(cameraPos, tmpCameraOffset, cameraLookAt);
+
+
+ } else {
+ let xTransl = (rawX - lastX);
+ let yTransl = (rawY - lastY);
+ let normCameraUp = vec3.create();
+ vec3.normalize(normCameraUp, cameraUp);
+ vec3.scale(normCameraUp, normCameraUp, yTransl);
+
+ let normCameraLeft = vec3.create();
+ vec3.cross(normCameraLeft, tmpCameraOffset, cameraUp);
+ vec3.normalize(normCameraLeft, normCameraLeft);
+ vec3.scale(normCameraLeft, normCameraLeft, xTransl);
+
+ let cameraShift = vec3.create();
+ vec3.add(cameraShift, normCameraUp, normCameraLeft);
+
+ vec3.add(cameraLookAt, cameraLookAt, cameraShift);
+ vec3.add(cameraPos, cameraPos, cameraShift);
+ }
+
+ lastMouseX = newX;
+ lastMouseY = newY;
+ redraw = true;
+}
+
+function handleKey(key) {
+ var keycode = key.key;
+ var rotate = true;
+ var axis = [0, 0, 1];
+ switch (keycode) {
+ case "w":
+ axis = [-1, 0, 0];
+ break;
+ case "d":
+ axis = [0, 1, 0];
+ break;
+ case "a":
+ axis = [0, -1, 0];
+ break;
+ case "s":
+ axis = [1, 0, 0];
+ break;
+ case "h":
+ resetCamera();
+ break;
+ default:
+ rotate = false;
+ break;
+ }
+
+ if (rotate) {
+ mat4.rotate(rotationMatrix, rotationMatrix, 0.1, axis);
+ redraw = true;
+ }
+
+}
+
+function handleMouseWheel(event) {
+ let zoomFactor = event.deltaY / 50;
+
+ // console.log(zoomFactor);
+
+ let cameraShift = vec3.create();
+ vec3.subtract(cameraShift, cameraPos, cameraLookAt);
+
+ let cameraDir = vec3.create();
+ vec3.normalize(cameraDir, cameraShift);
+ vec3.scale(cameraDir, cameraDir, zoomFactor);
+
+ let newCameraShift = vec3.create();
+ vec3.add(newCameraShift, cameraShift, cameraDir);
+
+ // not go beyond the bounds
+ if (vec3.length(newCameraShift) < 0.01 && zoomFactor < 0) {
+
+ } else if (vec3.length(newCameraShift) > 100 && zoomFactor > 0) {
+
+ } else if (vec3.dot(newCameraShift, cameraShift) >= 0) {
+ cameraShift = vec3.clone(newCameraShift);
+ }
+
+ vec3.add(cameraPos, cameraShift, cameraLookAt);
+
+ res = 1 / (vec3.length(cameraShift) + 0.001) * 0.001;
+ redraw = true;
+}
+
+function handleMouseMove(event) {
+ if (!mouseDownOrTouchActive) {
+ return;
+ }
+
+ var newX = event.clientX;
+ var newY = event.clientY;
+
+ processDrag(newX, newY, event.getModifierState("Alt"));
+}
+
+function handleTouchMove(evt) {
+ evt.preventDefault();
+ var touches = evt.targetTouches;
+
+ if (touches.length == 1 && touchId == touches[0].identifier) {
+ var newX = touches[0].pageX;
+ var newY = touches[0].pageY;
+ processDrag(newX, newY);
+ }
+}
+
+// Prepare canvas for drawing
+function sceneSetup() {
+ gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
+
+ mat4.lookAt(vMatrix, cameraPos, cameraLookAt, cameraUp);
+ mat4.identity(mMatrix);
+}
+
+var indexExt;
+
+// Create buffer data for the patch and its subdivisions to be pushed to the graphics card
+//Takes as an argument the array of vertices that define the patch to be drawn
+// Using the vertex position buffer of the above function,draw patch.
+function setBuffer() {
+ VertexBuffer = gl.createBuffer();
+ VertexBuffer.itemSize = 3;
+
+ ColorBuffer = gl.createBuffer();
+ ColorBuffer.itemSize = 4;
+
+ NormalBuffer = gl.createBuffer();
+ NormalBuffer.itemSize = 3;
+
+ MaterialIndexBuffer = gl.createBuffer();
+ MaterialIndexBuffer.itemSize = 1;
+
+ indexBuffer = gl.createBuffer();
+ indexBuffer.itemSize = 1;
+
+ setUniforms();
+ indexExt = gl.getExtension("OES_element_index_uint");
+}
+
+function drawBuffer() {
+ gl.bindBuffer(gl.ARRAY_BUFFER, VertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
+ VertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
+ VertexBuffer.numItems = nvertices;
+
+ // FIXME: Some kind of a conditional here for colors???
+ // along a flag of "useColors or something??? "
+ gl.bindBuffer(gl.ARRAY_BUFFER, ColorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shaderProgram.vertexColorAttribute,
+ ColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
+ ColorBuffer.numItems = nvertices;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, NormalBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
+ NormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
+ NormalBuffer.numItems = nvertices;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, MaterialIndexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Int32Array(materials), gl.STATIC_DRAW);
+ gl.vertexAttribIPointer(shaderProgram.vertexMaterialIndexAttribute,
+ MaterialIndexBuffer.itemSize, gl.INT,false,0,0);
+ MaterialIndexBuffer.numItems = nvertices;
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
+ indexExt ? new Uint32Array(indices) : new Uint16Array(indices),
+ gl.STATIC_DRAW);
+ indexBuffer.numItems = indices.length;
+
+ gl.drawElements(gl.TRIANGLES, indexBuffer.numItems,
+ indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT, 0);
+ vertices = [];
+ colors = [];
+ normals = [];
+ indices = [];
+ materials = [];
+ nvertices = 0;
+}
+
+var pixel = 1.0; // Adaptive rendering constant.
+var FillFactor = 0.1;
+var BezierFactor = 0.4;
+//var res=0.0005; // Temporary
+var res = 0.001; // Temporary
+var res2 = res * res;
+var Epsilon = 0.1 * res;
+var epsilon = 0;
+var Fuzz = 1000 * Number.EPSILON;
+var Fuzz2 = Fuzz * Fuzz;
+
+function Split3(z0, c0, c1, z1) {
+ this.m0 = new Array(3);
+ this.m2 = new Array(3);
+ this.m3 = new Array(3);
+ this.m4 = new Array(3);
+ this.m5 = new Array(3);
+ for (var i = 0; i < 3; ++i) {
+ this.m0[i] = 0.5 * (z0[i] + c0[i]);
+ var m1 = 0.5 * (c0[i] + c1[i]);
+ this.m2[i] = 0.5 * (c1[i] + z1[i]);
+ this.m3[i] = 0.5 * (this.m0[i] + m1);
+ this.m4[i] = 0.5 * (m1 + this.m2[i]);
+ this.m5[i] = 0.5 * (this.m3[i] + this.m4[i]);
+ }
+}
+
+
+// Store the vertex v and its color vector c in the buffer.
+function vertex(v, c, n) {
+ vertices.push(v[0]);
+ vertices.push(v[1]);
+ vertices.push(v[2]);
+
+ colors.push(c[0]);
+ colors.push(c[1]);
+ colors.push(c[2]);
+ colors.push(c[3]);
+
+ normals.push(n[0]);
+ normals.push(n[1]);
+ normals.push(n[2]);
+
+ // FIXME: Enable arbitrary materials?
+ materials.push(materialIndex);
+
+ return nvertices++;
+}
+
+function normal(left3, left2, left1, middle, right1, right2, right3) {
+ var u0 = right1[0] - middle[0];
+ var v0 = left1[0] - middle[0];
+ var u1 = right1[1] - middle[1];
+ var v1 = left1[1] - middle[1];
+ var u2 = right1[2] - middle[2];
+ var v2 = left1[2] - middle[2];
+ var n = [
+ u1 * v2 - u2 * v1,
+ u2 * v0 - u0 * v2,
+ u0 * v1 - u1 * v0
+ ];
+ if (abs2(n) > epsilon)
+ return unit(n);
+
+ var lp = [v0, v1, v2];
+ var rp = [u0, u1, u2];
+ var lpp = [middle[0] + left2[0] - 2 * left1[0],
+ middle[1] + left2[1] - 2 * left1[1],
+ middle[2] + left2[2] - 2 * left1[2]
+ ];
+ var rpp = [middle[0] + right2[0] - 2 * right1[0],
+ middle[1] + right2[1] - 2 * right1[1],
+ middle[2] + right2[2] - 2 * right1[2]
+ ];
+ var a = cross(rpp, lp);
+ var b = cross(rp, lpp);
+ n = [a[0] + b[0],
+ a[1] + b[1],
+ a[2] + b[2]
+ ];
+ if (abs2(n) > epsilon)
+ return unit(n);
+
+ var lppp = [left3[0] - middle[0] + 3 * (left1[0] - left2[0]),
+ left3[1] - middle[1] + 3 * (left1[1] - left2[1]),
+ left3[2] - middle[2] + 3 * (left1[2] - left2[2])
+ ];
+ var rppp = [right3[0] - middle[0] + 3 * (right1[0] - right2[0]),
+ right3[1] - middle[1] + 3 * (right1[1] - right2[1]),
+ right3[2] - middle[2] + 3 * (right1[2] - right2[2])
+ ];
+ a = cross(rpp, lpp);
+ b = cross(rp, lppp);
+ var c = cross(rppp, lp);
+ var d = cross(rppp, lpp);
+ var e = cross(rpp, lppp);
+ var f = cross(rppp, lppp);
+ return unit([9 * a[0] + 3 * (b[0] + c[0] + d[0] + e[0]) + f[0],
+ 9 * a[1] + 3 * (b[1] + c[1] + d[1] + e[1]) + f[1],
+ 9 * a[2] + 3 * (b[2] + c[2] + d[2] + e[2]) + f[2]
+ ]);
+}
+
+// return the maximum distance squared of points c0 and c1 from
+// the respective internal control points of z0--z1.
+function Straightness(z0, c0, c1, z1) {
+ var third = 1.0 / 3.0;
+ var v = [third * (z1[0] - z0[0]), third * (z1[1] - z0[1]), third * (z1[2] - z0[2])];
+ return Math.max(abs2([c0[0] - v[0] - z0[0], c0[1] - v[1] - z0[1], c0[2] - v[2] - z0[2]]),
+ abs2([z1[0] - v[0] - c1[0], z1[1] - v[1] - c1[1], z1[2] - v[2] - c1[2]]));
+}
+
+// return the maximum perpendicular distance squared of points c0 and c1
+// from z0--z1.
+function Distance1(z0, c0, c1, z1) {
+ var Z0 = [c0[0] - z0[0], c0[1] - z0[1], c0[2] - z0[2]];
+ var Q = unit([z1[0] - z0[0], z1[1] - z0[1], z1[2] - z0[2]]);
+ var Z1 = [c1[0] - z0[0], c1[1] - z0[1], c1[2] - z0[2]];
+ var p0 = dot(Z0, Q);
+ var p1 = dot(Z1, Q);
+ return Math.max(abs2([Z0[0] - p0 * Q[0], Z0[1] - p0 * Q[1], Z0[2] - p0 * Q[2]]),
+ abs2([Z1[0] - p1 * Q[0], Z1[1] - p1 * Q[1], Z1[2] - p1 * Q[2]]));
+}
+
+
+function Distance(p) {
+ var p0 = p[0];
+ var p3 = p[3];
+ var p12 = p[12];
+ var p15 = p[15];
+
+ // Check the flatness of the quad.
+ var d = Distance2(p15, p0, normal(p3, p[2], p[1], p0, p[4], p[8], p12));
+
+ // Determine how straight the edges are.
+ d = Math.max(d, Straightness(p0, p[1], p[2], p3));
+ d = Math.max(d, Straightness(p0, p[4], p[8], p12));
+ d = Math.max(d, Straightness(p3, p[7], p[11], p15));
+ d = Math.max(d, Straightness(p12, p[13], p[14], p15));
+
+ // Determine how straight the interior control curves are.
+ d = Math.max(d, Straightness(p[4], p[5], p[6], p[7]));
+ d = Math.max(d, Straightness(p[8], p[9], p[10], p[11]));
+ d = Math.max(d, Straightness(p[1], p[5], p[9], p[13]));
+ return Math.max(d, Straightness(p[2], p[6], p[10], p[14]));
+}
+
+var k = 1;
+// Return color associated with unit normal vector n.
+function color(n) {
+ var Ldotn = Math.abs(L[0] * n[0] + L[1] * n[1] + L[2] * n[2]);
+ var p = [emissive[0] + ambient[0] * Ambient[0] + Ldotn * diffuse[0] * Diffuse[0],
+ emissive[1] + ambient[1] * Ambient[1] + Ldotn * diffuse[1] * Diffuse[1],
+ emissive[2] + ambient[2] * Ambient[2] + Ldotn * diffuse[2] * Diffuse[2]
+ ];
+ var s = shininess * 128;
+ var H = unit([L[0], L[1], L[2] + 1]);
+ var f = Math.pow(H[0] * n[0] + H[1] * n[1] + H[2] * n[2], s);
+
+ // Phong-Blinn model of specular reflection
+ p = [p[0] + f * specular[0] * Specular[0], p[1] + f * specular[1] * Specular[1],
+ p[2] + f * specular[2] * Specular[2]
+ ];
+
+ return [p[0], p[1], p[2], 1];
+}
+
+function render(p, I0, I1, I2, I3, P0, P1, P2, P3, flat0, flat1, flat2, flat3,
+ C0, C1, C2, C3) {
+ if (Distance(p) < res2) { // Patch is flat
+ indices.push(I0);
+ indices.push(I1);
+ indices.push(I2);
+
+ indices.push(I0);
+ indices.push(I2);
+ indices.push(I3);
+ return;
+ }
+
+ var p0 = p[0];
+ var p3 = p[3];
+ var p12 = p[12];
+ var p15 = p[15];
+
+ var c0 = new Split3(p0, p[1], p[2], p3);
+ var c1 = new Split3(p[4], p[5], p[6], p[7]);
+ var c2 = new Split3(p[8], p[9], p[10], p[11]);
+ var c3 = new Split3(p12, p[13], p[14], p15);
+ var c4 = new Split3(p0, p[4], p[8], p12);
+ var c5 = new Split3(c0.m0, c1.m0, c2.m0, c3.m0);
+ var c6 = new Split3(c0.m3, c1.m3, c2.m3, c3.m3);
+ var c7 = new Split3(c0.m5, c1.m5, c2.m5, c3.m5);
+ var c8 = new Split3(c0.m4, c1.m4, c2.m4, c3.m4);
+ var c9 = new Split3(c0.m2, c1.m2, c2.m2, c3.m2);
+ var c10 = new Split3(p3, p[7], p[11], p15);
+
+ var s0 = [p0, c0.m0, c0.m3, c0.m5, c4.m0, c5.m0, c6.m0, c7.m0,
+ c4.m3, c5.m3, c6.m3, c7.m3, c4.m5, c5.m5, c6.m5, c7.m5
+ ];
+ var s1 = [c4.m5, c5.m5, c6.m5, c7.m5, c4.m4, c5.m4, c6.m4, c7.m4,
+ c4.m2, c5.m2, c6.m2, c7.m2, p12, c3.m0, c3.m3, c3.m5
+ ];
+ var s2 = [c7.m5, c8.m5, c9.m5, c10.m5, c7.m4, c8.m4, c9.m4, c10.m4,
+ c7.m2, c8.m2, c9.m2, c10.m2, c3.m5, c3.m4, c3.m2, p15
+ ];
+ var s3 = [c0.m5, c0.m4, c0.m2, p3, c7.m0, c8.m0, c9.m0, c10.m0,
+ c7.m3, c8.m3, c9.m3, c10.m3, c7.m5, c8.m5, c9.m5, c10.m5
+ ];
+
+ var m4 = s0[15];
+
+ var n0 = normal(s0[0], s0[4], s0[8], s0[12], s0[13], s0[14], s0[15]);
+ if (n0 == 0.0) {
+ n0 = normal(s0[0], s0[4], s0[8], s0[12], s0[11], s0[7], s0[3]);
+ if (n0 == 0.0) n0 = normal(s0[3], s0[2], s0[1], s0[0], s0[13], s0[14], s0[15]);
+ }
+
+ var n1 = normal(s1[12], s1[13], s1[14], s1[15], s1[11], s1[7], s1[3]);
+ if (n1 == 0.0) {
+ n1 = normal(s1[12], s1[13], s1[14], s1[15], s1[2], s1[1], s1[0]);
+ if (n1 == 0.0) n1 = normal(s1[0], s1[4], s1[8], s1[12], s1[11], s1[7], s1[3]);
+ }
+
+ var n2 = normal(s2[15], s2[11], s2[7], s2[3], s2[2], s2[1], s2[0]);
+ if (n2 == 0.0) {
+ n2 = normal(s2[15], s2[11], s2[7], s2[3], s2[4], s2[8], s2[12]);
+ if (n2 == 0.0) n2 = normal(s2[12], s2[13], s2[14], s2[15], s2[2], s2[1], s2[0]);
+ }
+
+ var n3 = normal(s3[3], s3[2], s3[1], s3[0], s3[4], s3[8], s3[12]);
+ if (n3 == 0.0) {
+ n3 = normal(s3[3], s3[2], s3[1], s3[0], s3[13], s3[14], s3[15]);
+ if (n3 == 0.0) n3 = normal(s3[15], s3[11], s3[7], s3[3], s3[4], s3[8], s3[12]);
+ }
+
+ var n4 = normal(s2[3], s2[2], s2[1], m4, s2[4], s2[8], s2[12]);
+
+ var m0, m1, m2, m3;
+
+ // A kludge to remove subdivision cracks, only applied the first time
+ // an edge is found to be flat before the rest of the subpatch is.
+ if (flat0)
+ m0 = [0.5 * (P0[0] + P1[0]), 0.5 * (P0[1] + P1[1]), 0.5 * (P0[2] + P1[2])];
+ else {
+ if ((flat0 = Distance1(p0, p[4], p[8], p12) < res2)) {
+ var u = s0[12];
+ var v = s2[3];
+ var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
+ m0 = [0.5 * (P0[0] + P1[0]) + Epsilon * e[0], 0.5 * (P0[1] + P1[1]) + Epsilon * e[1],
+ 0.5 * (P0[2] + P1[2]) + Epsilon * e[2]
+ ];
+ } else
+ m0 = s0[12];
+ }
+
+ if (flat1)
+ m1 = [0.5 * (P1[0] + P2[0]), 0.5 * (P1[1] + P2[1]), 0.5 * (P1[2] + P2[2])];
+ else {
+ if ((flat1 = Distance1(p12, p[13], p[14], p15) < res2)) {
+ var u = s1[15];
+ var v = s3[0];
+ var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
+ m1 = [0.5 * (P1[0] + P2[0]) + Epsilon * e[0], 0.5 * (P1[1] + P2[1]) + Epsilon * e[1],
+ 0.5 * (P1[2] + P2[2]) + Epsilon * e[2]
+ ];
+ } else
+ m1 = s1[15];
+ }
+
+ if (flat2)
+ m2 = [0.5 * (P2[0] + P3[0]), 0.5 * (P2[1] + P3[1]), 0.5 * (P2[2] + P3[2])];
+ else {
+ if ((flat2 = Distance1(p15, p[11], p[7], p3) < res2)) {
+ var u = s2[3];
+ var v = s0[12];
+ var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
+ m2 = [0.5 * (P2[0] + P3[0]) + Epsilon * e[0], 0.5 * (P2[1] + P3[1]) + Epsilon * e[1],
+ 0.5 * (P2[2] + P3[2]) + Epsilon * e[2]
+ ];
+ } else
+ m2 = s2[3];
+ }
+
+ if (flat3)
+ m3 = [0.5 * (P3[0] + P0[0]), 0.5 * (P3[1] + P0[1]), 0.5 * (P3[2] + P0[2])];
+ else {
+ if ((flat3 = Distance1(p3, p[2], p[1], p0) < res2)) {
+ var u = s3[0];
+ var v = s1[15];
+ var e = unit([u[0] - v[0], u[1] - v[1], u[2] - v[2]]);
+ m3 = [0.5 * (P3[0] + P0[0]) + Epsilon * e[0],
+ 0.5 * (P3[1] + P0[1]) + Epsilon * e[1],
+ 0.5 * (P3[2] + P0[2]) + Epsilon * e[2]
+ ];
+ } else
+ m3 = s3[0];
+ }
+
+ // document.write(n0);
+ // document.write(" < br > ");
+
+ {
+ /*
+ var c0=new Array(4);
+ var c1=new Array(4);
+ var c2=new Array(4);
+ var c3=new Array(4);
+ var c4=new Array(4);
+
+ for(var i=0; i < 4; ++i) {
+ c0[i]=0.5*(C0[i]+C1[i]);
+ c1[i]=0.5*(C1[i]+C2[i]);
+ c2[i]=0.5*(C2[i]+C3[i]);
+ c3[i]=0.5*(C3[i]+C0[i]);
+ c4[i]=0.5*(c0[i]+c2[i]);
+ }
+ */
+
+ var c0 = color(n0);
+ var c1 = color(n1);
+ var c2 = color(n2);
+ var c3 = color(n3);
+ var c4 = color(n4);
+
+
+ var i0 = vertex(m0, c0, n0);
+ var i1 = vertex(m1, c1, n1);
+ var i2 = vertex(m2, c2, n2);
+ var i3 = vertex(m3, c3, n3);
+ var i4 = vertex(m4, c4, n4);
+
+ render(s0, I0, i0, i4, i3, P0, m0, m4, m3, flat0, false, false, flat3,
+ C0, c0, c4, c3);
+ render(s1, i0, I1, i1, i4, m0, P1, m1, m4, flat0, flat1, false, false,
+ c0, C1, c1, c4);
+ render(s2, i4, i1, I2, i2, m4, m1, P2, m2, false, flat1, flat2, false,
+ c4, c1, C2, c2);
+ render(s3, i3, i4, i2, I3, m3, m4, m2, P3, false, false, flat2, flat3,
+ c3, c4, c2, C3);
+ }
+}
+
+var p;
+
+function draw() {
+ sceneSetup();
+ // mat4.translate(mMatrix,mMatrix,[-0.5,-0.5,-1.5]);
+
+ setBuffer();
+ var p0 = p[0];
+ var p3 = p[3];
+ var p12 = p[12];
+ var p15 = p[15];
+
+ epsilon = 0;
+ for (var i = 1; i < 16; ++i)
+ epsilon = Math.max(epsilon,
+ abs2([p[i][0] - p0[0], p[i][1] - p0[1], p[i][2] - p0[2]]));
+ epsilon *= Fuzz2;
+
+ var n0 = normal(p3, p[2], p[1], p0, p[4], p[8], p12);
+ var n1 = normal(p0, p[4], p[8], p12, p[13], p[14], p15);
+ var n2 = normal(p12, p[13], p[14], p15, p[11], p[7], p3);
+ var n3 = normal(p15, p[11], p[7], p3, p[2], p[1], p0);
+
+ var c0 = color(n0);
+ var c1 = color(n1);
+ var c2 = color(n2);
+ var c3 = color(n3);
+
+ var i0 = vertex(p0, c0, n0);
+ var i1 = vertex(p12, c1, n1);
+ var i2 = vertex(p15, c2, n2);
+ var i3 = vertex(p3, c3, n3);
+
+ render(p, i0, i1, i2, i3, p0, p12, p15, p3, false, false, false, false,
+ c0, c1, c2, c3);
+ drawBuffer();
+}
+
+var forceredraw = false;
+var lasttime;
+var newtime;
+
+function tick() {
+ requestAnimationFrame(tick);
+ lasttime = newtime;
+ newtime = performance.now();
+ // invariant: every time this loop is called, lasttime stores the
+ // last time processloop was called.
+ processloop(newtime - lasttime);
+ draw();
+}
+
+function tickNoRedraw() {
+ requestAnimationFrame(tickNoRedraw);
+ if (redraw) {
+ draw();
+ redraw = false;
+ }
+}
+
+function webGLStart() {
+ var canvas = document.getElementById("Asymptote");
+ initGL(canvas);
+ initShaders();
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.enable(gl.DEPTH_TEST);
+
+ canvas.onmousedown = handleMouseDown;
+ document.onmouseup = handleMouseUpOrTouchEnd;
+ document.onmousemove = handleMouseMove;
+ canvas.onkeydown = handleKey;
+ document.onwheel = handleMouseWheel;
+
+ canvas.addEventListener("touchstart", handleTouchStart, false);
+ canvas.addEventListener("touchend", handleMouseUpOrTouchEnd, false);
+ canvas.addEventListener("touchcancel", handleMouseUpOrTouchEnd, false);
+ canvas.addEventListener("touchleave", handleMouseUpOrTouchEnd, false);
+ canvas.addEventListener("touchmove", handleTouchMove, false);
+
+ newtime = performance.now();
+
+ if (forceredraw) {
+ tick();
+ } else {
+ tickNoRedraw();
+ }
+}
diff --git a/graphics/asymptote/webgl/glm-js-min-2.2.2.js b/graphics/asymptote/webgl/glm-js-min-2.2.2.js
new file mode 100644
index 0000000000..3e11d90371
--- /dev/null
+++ b/graphics/asymptote/webgl/glm-js-min-2.2.2.js
@@ -0,0 +1,273 @@
+/*! glm-js built 2017-03-20 16:45:23-04:00 | (c) humbletim | http://humbletim.github.io/glm-js */
+(function declare_glmjs_glmatrix(globals, $GLM_log, $GLM_console_log) { var GLM, GLMAT, GLMAT_VERSION, GLMJS_PREFIX, $GLM_console_factory, glm; ArrayBuffer.exists;
+/*
+
+ --------------------------------------------------------------------------
+ glm-js | (c) humbletim | http://humbletim.github.io/glm-js
+ --------------------------------------------------------------------------
+
+ The MIT License (MIT)
+
+ Copyright (c) 2015-2016 humbletim
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ --------------------------------------------------------------------------
+ gl-matrix | (c) Brandon Jones, Colin MacKenzie IV | http://glmatrix.net/
+ --------------------------------------------------------------------------
+
+ Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+GLMAT={};GLMAT_VERSION="2.2.2";
+(function(a){a.VERSION=GLMAT_VERSION;if(!b)var b=1E-6;if(!c)var c="undefined"!==typeof Float32Array?Float32Array:Array;if(!e)var e=Math.random;var d={setMatrixArrayType:function(y){c=y}};"undefined"!==typeof a&&(a.glMatrix=d);var h=Math.PI/180;d.toRadian=function(y){return y*h};d={create:function(){var y=new c(2);y[0]=0;y[1]=0;return y},clone:function(y){var a=new c(2);a[0]=y[0];a[1]=y[1];return a},fromValues:function(y,a){var v=new c(2);v[0]=y;v[1]=a;return v},copy:function(y,a){y[0]=a[0];y[1]=a[1];
+return y},set:function(y,a,v){y[0]=a;y[1]=v;return y},add:function(y,a,v){y[0]=a[0]+v[0];y[1]=a[1]+v[1];return y},subtract:function(y,a,v){y[0]=a[0]-v[0];y[1]=a[1]-v[1];return y}};d.sub=d.subtract;d.multiply=function(y,a,v){y[0]=a[0]*v[0];y[1]=a[1]*v[1];return y};d.mul=d.multiply;d.divide=function(y,a,v){y[0]=a[0]/v[0];y[1]=a[1]/v[1];return y};d.div=d.divide;d.min=function(y,a,v){y[0]=Math.min(a[0],v[0]);y[1]=Math.min(a[1],v[1]);return y};d.max=function(y,a,v){y[0]=Math.max(a[0],v[0]);y[1]=Math.max(a[1],
+v[1]);return y};d.scale=function(y,a,v){y[0]=a[0]*v;y[1]=a[1]*v;return y};d.scaleAndAdd=function(y,a,v,b){y[0]=a[0]+v[0]*b;y[1]=a[1]+v[1]*b;return y};d.distance=function(a,f){var v=f[0]-a[0],b=f[1]-a[1];return Math.sqrt(v*v+b*b)};d.dist=d.distance;d.squaredDistance=function(a,f){var v=f[0]-a[0],b=f[1]-a[1];return v*v+b*b};d.sqrDist=d.squaredDistance;d.length=function(a){var f=a[0];a=a[1];return Math.sqrt(f*f+a*a)};d.len=d.length;d.squaredLength=function(a){var f=a[0];a=a[1];return f*f+a*a};d.sqrLen=
+d.squaredLength;d.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];return a};d.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];return a};d.normalize=function(a,f){var v=f[0],b=f[1],v=v*v+b*b;0<v&&(v=1/Math.sqrt(v),a[0]=f[0]*v,a[1]=f[1]*v);return a};d.dot=function(a,f){return a[0]*f[0]+a[1]*f[1]};d.cross=function(a,f,v){f=f[0]*v[1]-f[1]*v[0];a[0]=a[1]=0;a[2]=f;return a};d.lerp=function(a,f,v,b){var c=f[0];f=f[1];a[0]=c+b*(v[0]-c);a[1]=f+b*(v[1]-f);return a};d.random=function(a,f){f=f||1;var v=2*e()*Math.PI;
+a[0]=Math.cos(v)*f;a[1]=Math.sin(v)*f;return a};d.transformMat2=function(a,f,v){var b=f[0];f=f[1];a[0]=v[0]*b+v[2]*f;a[1]=v[1]*b+v[3]*f;return a};d.transformMat2d=function(a,f,v){var b=f[0];f=f[1];a[0]=v[0]*b+v[2]*f+v[4];a[1]=v[1]*b+v[3]*f+v[5];return a};d.transformMat3=function(a,f,b){var c=f[0];f=f[1];a[0]=b[0]*c+b[3]*f+b[6];a[1]=b[1]*c+b[4]*f+b[7];return a};d.transformMat4=function(a,f,b){var c=f[0];f=f[1];a[0]=b[0]*c+b[4]*f+b[12];a[1]=b[1]*c+b[5]*f+b[13];return a};var j=d.create();d.forEach=function(a,
+f,b,c,d,e){f||(f=2);b||(b=0);for(c=c?Math.min(c*f+b,a.length):a.length;b<c;b+=f)j[0]=a[b],j[1]=a[b+1],d(j,j,e),a[b]=j[0],a[b+1]=j[1];return a};d.str=function(a){return"vec2("+a[0]+", "+a[1]+")"};"undefined"!==typeof a&&(a.vec2=d);var g={create:function(){var a=new c(3);a[0]=0;a[1]=0;a[2]=0;return a},clone:function(a){var f=new c(3);f[0]=a[0];f[1]=a[1];f[2]=a[2];return f},fromValues:function(a,f,b){var P=new c(3);P[0]=a;P[1]=f;P[2]=b;return P},copy:function(a,f){a[0]=f[0];a[1]=f[1];a[2]=f[2];return a},
+set:function(a,f,b,c){a[0]=f;a[1]=b;a[2]=c;return a},add:function(a,f,b){a[0]=f[0]+b[0];a[1]=f[1]+b[1];a[2]=f[2]+b[2];return a},subtract:function(a,f,b){a[0]=f[0]-b[0];a[1]=f[1]-b[1];a[2]=f[2]-b[2];return a}};g.sub=g.subtract;g.multiply=function(a,f,b){a[0]=f[0]*b[0];a[1]=f[1]*b[1];a[2]=f[2]*b[2];return a};g.mul=g.multiply;g.divide=function(a,f,b){a[0]=f[0]/b[0];a[1]=f[1]/b[1];a[2]=f[2]/b[2];return a};g.div=g.divide;g.min=function(a,f,b){a[0]=Math.min(f[0],b[0]);a[1]=Math.min(f[1],b[1]);a[2]=Math.min(f[2],
+b[2]);return a};g.max=function(a,f,b){a[0]=Math.max(f[0],b[0]);a[1]=Math.max(f[1],b[1]);a[2]=Math.max(f[2],b[2]);return a};g.scale=function(a,f,b){a[0]=f[0]*b;a[1]=f[1]*b;a[2]=f[2]*b;return a};g.scaleAndAdd=function(a,f,b,c){a[0]=f[0]+b[0]*c;a[1]=f[1]+b[1]*c;a[2]=f[2]+b[2]*c;return a};g.distance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2];return Math.sqrt(b*b+c*c+d*d)};g.dist=g.distance;g.squaredDistance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2];return b*b+c*c+d*d};g.sqrDist=
+g.squaredDistance;g.length=function(a){var f=a[0],b=a[1];a=a[2];return Math.sqrt(f*f+b*b+a*a)};g.len=g.length;g.squaredLength=function(a){var f=a[0],b=a[1];a=a[2];return f*f+b*b+a*a};g.sqrLen=g.squaredLength;g.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];a[2]=-f[2];return a};g.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];a[2]=1/f[2];return a};g.normalize=function(a,f){var b=f[0],c=f[1],d=f[2],b=b*b+c*c+d*d;0<b&&(b=1/Math.sqrt(b),a[0]=f[0]*b,a[1]=f[1]*b,a[2]=f[2]*b);return a};g.dot=function(a,f){return a[0]*
+f[0]+a[1]*f[1]+a[2]*f[2]};g.cross=function(a,f,b){var c=f[0],d=f[1];f=f[2];var e=b[0],l=b[1];b=b[2];a[0]=d*b-f*l;a[1]=f*e-c*b;a[2]=c*l-d*e;return a};g.lerp=function(a,f,b,c){var d=f[0],e=f[1];f=f[2];a[0]=d+c*(b[0]-d);a[1]=e+c*(b[1]-e);a[2]=f+c*(b[2]-f);return a};g.random=function(a,f){f=f||1;var b=2*e()*Math.PI,c=2*e()-1,d=Math.sqrt(1-c*c)*f;a[0]=Math.cos(b)*d;a[1]=Math.sin(b)*d;a[2]=c*f;return a};g.transformMat4=function(a,f,b){var c=f[0],d=f[1];f=f[2];var e=b[3]*c+b[7]*d+b[11]*f+b[15],e=e||1;a[0]=
+(b[0]*c+b[4]*d+b[8]*f+b[12])/e;a[1]=(b[1]*c+b[5]*d+b[9]*f+b[13])/e;a[2]=(b[2]*c+b[6]*d+b[10]*f+b[14])/e;return a};g.transformMat3=function(a,f,b){var c=f[0],d=f[1];f=f[2];a[0]=c*b[0]+d*b[3]+f*b[6];a[1]=c*b[1]+d*b[4]+f*b[7];a[2]=c*b[2]+d*b[5]+f*b[8];return a};g.transformQuat=function(a,f,b){var c=f[0],d=f[1],e=f[2];f=b[0];var l=b[1],x=b[2];b=b[3];var u=b*c+l*e-x*d,J=b*d+x*c-f*e,g=b*e+f*d-l*c,c=-f*c-l*d-x*e;a[0]=u*b+c*-f+J*-x-g*-l;a[1]=J*b+c*-l+g*-f-u*-x;a[2]=g*b+c*-x+u*-l-J*-f;return a};g.rotateX=
+function(a,f,b,c){var d=[],e=[];d[0]=f[0]-b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[0];e[1]=d[1]*Math.cos(c)-d[2]*Math.sin(c);e[2]=d[1]*Math.sin(c)+d[2]*Math.cos(c);a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};g.rotateY=function(a,f,b,c){var d=[],e=[];d[0]=f[0]-b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[2]*Math.sin(c)+d[0]*Math.cos(c);e[1]=d[1];e[2]=d[2]*Math.cos(c)-d[0]*Math.sin(c);a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};g.rotateZ=function(a,f,b,c){var d=[],e=[];d[0]=f[0]-
+b[0];d[1]=f[1]-b[1];d[2]=f[2]-b[2];e[0]=d[0]*Math.cos(c)-d[1]*Math.sin(c);e[1]=d[0]*Math.sin(c)+d[1]*Math.cos(c);e[2]=d[2];a[0]=e[0]+b[0];a[1]=e[1]+b[1];a[2]=e[2]+b[2];return a};var k=g.create();g.forEach=function(a,f,b,c,d,e){f||(f=3);b||(b=0);for(c=c?Math.min(c*f+b,a.length):a.length;b<c;b+=f)k[0]=a[b],k[1]=a[b+1],k[2]=a[b+2],d(k,k,e),a[b]=k[0],a[b+1]=k[1],a[b+2]=k[2];return a};g.str=function(a){return"vec3("+a[0]+", "+a[1]+", "+a[2]+")"};"undefined"!==typeof a&&(a.vec3=g);var i={create:function(){var a=
+new c(4);a[0]=0;a[1]=0;a[2]=0;a[3]=0;return a},clone:function(a){var f=new c(4);f[0]=a[0];f[1]=a[1];f[2]=a[2];f[3]=a[3];return f},fromValues:function(a,f,b,d){var e=new c(4);e[0]=a;e[1]=f;e[2]=b;e[3]=d;return e},copy:function(a,f){a[0]=f[0];a[1]=f[1];a[2]=f[2];a[3]=f[3];return a},set:function(a,f,b,c,d){a[0]=f;a[1]=b;a[2]=c;a[3]=d;return a},add:function(a,f,b){a[0]=f[0]+b[0];a[1]=f[1]+b[1];a[2]=f[2]+b[2];a[3]=f[3]+b[3];return a},subtract:function(a,f,b){a[0]=f[0]-b[0];a[1]=f[1]-b[1];a[2]=f[2]-b[2];
+a[3]=f[3]-b[3];return a}};i.sub=i.subtract;i.multiply=function(a,f,b){a[0]=f[0]*b[0];a[1]=f[1]*b[1];a[2]=f[2]*b[2];a[3]=f[3]*b[3];return a};i.mul=i.multiply;i.divide=function(a,f,b){a[0]=f[0]/b[0];a[1]=f[1]/b[1];a[2]=f[2]/b[2];a[3]=f[3]/b[3];return a};i.div=i.divide;i.min=function(a,f,b){a[0]=Math.min(f[0],b[0]);a[1]=Math.min(f[1],b[1]);a[2]=Math.min(f[2],b[2]);a[3]=Math.min(f[3],b[3]);return a};i.max=function(a,f,b){a[0]=Math.max(f[0],b[0]);a[1]=Math.max(f[1],b[1]);a[2]=Math.max(f[2],b[2]);a[3]=
+Math.max(f[3],b[3]);return a};i.scale=function(a,f,b){a[0]=f[0]*b;a[1]=f[1]*b;a[2]=f[2]*b;a[3]=f[3]*b;return a};i.scaleAndAdd=function(a,f,b,c){a[0]=f[0]+b[0]*c;a[1]=f[1]+b[1]*c;a[2]=f[2]+b[2]*c;a[3]=f[3]+b[3]*c;return a};i.distance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2],e=f[3]-a[3];return Math.sqrt(b*b+c*c+d*d+e*e)};i.dist=i.distance;i.squaredDistance=function(a,f){var b=f[0]-a[0],c=f[1]-a[1],d=f[2]-a[2],e=f[3]-a[3];return b*b+c*c+d*d+e*e};i.sqrDist=i.squaredDistance;i.length=function(a){var f=
+a[0],b=a[1],c=a[2];a=a[3];return Math.sqrt(f*f+b*b+c*c+a*a)};i.len=i.length;i.squaredLength=function(a){var f=a[0],b=a[1],c=a[2];a=a[3];return f*f+b*b+c*c+a*a};i.sqrLen=i.squaredLength;i.negate=function(a,f){a[0]=-f[0];a[1]=-f[1];a[2]=-f[2];a[3]=-f[3];return a};i.inverse=function(a,f){a[0]=1/f[0];a[1]=1/f[1];a[2]=1/f[2];a[3]=1/f[3];return a};i.normalize=function(a,f){var b=f[0],c=f[1],d=f[2],e=f[3],b=b*b+c*c+d*d+e*e;0<b&&(b=1/Math.sqrt(b),a[0]=f[0]*b,a[1]=f[1]*b,a[2]=f[2]*b,a[3]=f[3]*b);return a};
+i.dot=function(a,f){return a[0]*f[0]+a[1]*f[1]+a[2]*f[2]+a[3]*f[3]};i.lerp=function(a,f,b,c){var d=f[0],e=f[1],l=f[2];f=f[3];a[0]=d+c*(b[0]-d);a[1]=e+c*(b[1]-e);a[2]=l+c*(b[2]-l);a[3]=f+c*(b[3]-f);return a};i.random=function(a,f){f=f||1;a[0]=e();a[1]=e();a[2]=e();a[3]=e();i.normalize(a,a);i.scale(a,a,f);return a};i.transformMat4=function(a,f,b){var c=f[0],d=f[1],e=f[2];f=f[3];a[0]=b[0]*c+b[4]*d+b[8]*e+b[12]*f;a[1]=b[1]*c+b[5]*d+b[9]*e+b[13]*f;a[2]=b[2]*c+b[6]*d+b[10]*e+b[14]*f;a[3]=b[3]*c+b[7]*d+
+b[11]*e+b[15]*f;return a};i.transformQuat=function(a,b,c){var d=b[0],e=b[1],n=b[2];b=c[0];var l=c[1],x=c[2];c=c[3];var u=c*d+l*n-x*e,J=c*e+x*d-b*n,g=c*n+b*e-l*d,d=-b*d-l*e-x*n;a[0]=u*c+d*-b+J*-x-g*-l;a[1]=J*c+d*-l+g*-b-u*-x;a[2]=g*c+d*-x+u*-l-J*-b;return a};var w=i.create();i.forEach=function(a,b,c,d,e,n){b||(b=4);c||(c=0);for(d=d?Math.min(d*b+c,a.length):a.length;c<d;c+=b)w[0]=a[c],w[1]=a[c+1],w[2]=a[c+2],w[3]=a[c+3],e(w,w,n),a[c]=w[0],a[c+1]=w[1],a[c+2]=w[2],a[c+3]=w[3];return a};i.str=function(a){return"vec4("+
+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};"undefined"!==typeof a&&(a.vec4=i);d={create:function(){var a=new c(4);a[0]=1;a[1]=0;a[2]=0;a[3]=1;return a},clone:function(a){var b=new c(4);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=1;return a},transpose:function(a,b){if(a===b){var c=b[1];a[1]=b[2];a[2]=c}else a[0]=b[0],a[1]=b[2],a[2]=b[1],a[3]=b[3];return a},invert:function(a,b){var c=
+b[0],d=b[1],e=b[2],n=b[3],l=c*n-e*d;if(!l)return null;l=1/l;a[0]=n*l;a[1]=-d*l;a[2]=-e*l;a[3]=c*l;return a},adjoint:function(a,b){var c=b[0];a[0]=b[3];a[1]=-b[1];a[2]=-b[2];a[3]=c;return a},determinant:function(a){return a[0]*a[3]-a[2]*a[1]},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2];b=b[3];var l=c[0],x=c[1],u=c[2];c=c[3];a[0]=d*l+n*x;a[1]=e*l+b*x;a[2]=d*u+n*c;a[3]=e*u+b*c;return a}};d.mul=d.multiply;d.rotate=function(a,b,c){var d=b[0],e=b[1],n=b[2];b=b[3];var l=Math.sin(c);c=Math.cos(c);a[0]=
+d*c+n*l;a[1]=e*c+b*l;a[2]=d*-l+n*c;a[3]=e*-l+b*c;return a};d.scale=function(a,b,c){var d=b[1],e=b[2],n=b[3],l=c[0];c=c[1];a[0]=b[0]*l;a[1]=d*l;a[2]=e*c;a[3]=n*c;return a};d.str=function(a){return"mat2("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2))};d.LDU=function(a,b,c,d){a[2]=d[2]/d[0];c[0]=d[0];c[1]=d[1];c[3]=d[3]-a[2]*c[1];return[a,b,c]};"undefined"!==typeof a&&(a.mat2=d);d={create:function(){var a=
+new c(6);a[0]=1;a[1]=0;a[2]=0;a[3]=1;a[4]=0;a[5]=0;return a},clone:function(a){var b=new c(6);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=1;a[4]=0;a[5]=0;return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=c*n-d*e;if(!u)return null;u=1/u;a[0]=n*u;a[1]=-d*u;a[2]=-e*u;a[3]=c*u;a[4]=(e*x-n*l)*u;a[5]=(d*l-c*x)*u;return a},
+determinant:function(a){return a[0]*a[3]-a[1]*a[2]},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=c[0],g=c[1],h=c[2],K=c[3],j=c[4];c=c[5];a[0]=d*u+n*g;a[1]=e*u+l*g;a[2]=d*h+n*K;a[3]=e*h+l*K;a[4]=d*j+n*c+x;a[5]=e*j+l*c+b;return a}};d.mul=d.multiply;d.rotate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=Math.sin(c);c=Math.cos(c);a[0]=d*c+n*u;a[1]=e*c+l*u;a[2]=d*-u+n*c;a[3]=e*-u+l*c;a[4]=x;a[5]=b;return a};d.scale=function(a,b,c){var d=b[1],e=b[2],
+n=b[3],l=b[4],x=b[5],u=c[0];c=c[1];a[0]=b[0]*u;a[1]=d*u;a[2]=e*c;a[3]=n*c;a[4]=l;a[5]=x;return a};d.translate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4];b=b[5];var u=c[0];c=c[1];a[0]=d;a[1]=e;a[2]=n;a[3]=l;a[4]=d*u+n*c+x;a[5]=e*u+l*c+b;return a};d.str=function(a){return"mat2d("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+1)};"undefined"!==
+typeof a&&(a.mat2d=d);d={create:function(){var a=new c(9);a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a},fromMat4:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[4];a[4]=b[5];a[5]=b[6];a[6]=b[8];a[7]=b[9];a[8]=b[10];return a},clone:function(a){var b=new c(9);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];return a},
+identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a},transpose:function(a,b){if(a===b){var c=b[1],d=b[2],e=b[5];a[1]=b[3];a[2]=b[6];a[3]=c;a[5]=b[7];a[6]=d;a[7]=e}else a[0]=b[0],a[1]=b[3],a[2]=b[6],a[3]=b[1],a[4]=b[4],a[5]=b[7],a[6]=b[2],a[7]=b[5],a[8]=b[8];return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8],K=h*l-x*g,j=-h*n+x*u,m=g*n-l*u,i=c*K+d*j+e*m;if(!i)return null;i=1/i;a[0]=K*i;a[1]=(-h*d+e*g)*i;a[2]=(x*
+d-e*l)*i;a[3]=j*i;a[4]=(h*c-e*u)*i;a[5]=(-x*c+e*n)*i;a[6]=m*i;a[7]=(-g*c+d*u)*i;a[8]=(l*c-d*n)*i;return a},adjoint:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8];a[0]=l*h-x*g;a[1]=e*g-d*h;a[2]=d*x-e*l;a[3]=x*u-n*h;a[4]=c*h-e*u;a[5]=e*n-c*x;a[6]=n*g-l*u;a[7]=d*u-c*g;a[8]=c*l-d*n;return a},determinant:function(a){var b=a[3],c=a[4],d=a[5],e=a[6],n=a[7],l=a[8];return a[0]*(l*c-d*n)+a[1]*(-l*b+d*e)+a[2]*(n*b-c*e)},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],
+x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=c[0],m=c[1],i=c[2],k=c[3],q=c[4],t=c[5],s=c[6],r=c[7];c=c[8];a[0]=j*d+m*l+i*g;a[1]=j*e+m*x+i*h;a[2]=j*n+m*u+i*b;a[3]=k*d+q*l+t*g;a[4]=k*e+q*x+t*h;a[5]=k*n+q*u+t*b;a[6]=s*d+r*l+c*g;a[7]=s*e+r*x+c*h;a[8]=s*n+r*u+c*b;return a}};d.mul=d.multiply;d.translate=function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=c[0];c=c[1];a[0]=d;a[1]=e;a[2]=n;a[3]=l;a[4]=x;a[5]=u;a[6]=j*d+c*l+g;a[7]=j*e+c*x+h;a[8]=j*n+c*u+b;return a};d.rotate=
+function(a,b,c){var d=b[0],e=b[1],n=b[2],l=b[3],x=b[4],u=b[5],g=b[6],h=b[7];b=b[8];var j=Math.sin(c);c=Math.cos(c);a[0]=c*d+j*l;a[1]=c*e+j*x;a[2]=c*n+j*u;a[3]=c*l-j*d;a[4]=c*x-j*e;a[5]=c*u-j*n;a[6]=g;a[7]=h;a[8]=b;return a};d.scale=function(a,b,c){var d=c[0];c=c[1];a[0]=d*b[0];a[1]=d*b[1];a[2]=d*b[2];a[3]=c*b[3];a[4]=c*b[4];a[5]=c*b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];return a};d.fromMat2d=function(a,b){a[0]=b[0];a[1]=b[1];a[2]=0;a[3]=b[2];a[4]=b[3];a[5]=0;a[6]=b[4];a[7]=b[5];a[8]=1;return a};d.fromQuat=
+function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=c+c,x=d+d,u=e+e,c=c*l,g=d*l,d=d*x,h=e*l,j=e*x,e=e*u,l=n*l,x=n*x,n=n*u;a[0]=1-d-e;a[3]=g-n;a[6]=h+x;a[1]=g+n;a[4]=1-c-e;a[7]=j-l;a[2]=h-x;a[5]=j+l;a[8]=1-c-d;return a};d.normalFromMat4=function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],x=b[5],u=b[6],g=b[7],h=b[8],j=b[9],m=b[10],i=b[11],k=b[12],q=b[13],t=b[14],s=b[15],r=c*x-d*l,z=c*u-e*l,w=c*g-n*l,A=d*u-e*x,E=d*g-n*x,F=e*g-n*u,G=h*q-j*k,H=h*t-m*k,h=h*s-i*k,I=j*t-m*q,j=j*s-i*q,m=m*s-i*t,i=r*m-z*j+w*I+
+A*h-E*H+F*G;if(!i)return null;i=1/i;a[0]=(x*m-u*j+g*I)*i;a[1]=(u*h-l*m-g*H)*i;a[2]=(l*j-x*h+g*G)*i;a[3]=(e*j-d*m-n*I)*i;a[4]=(c*m-e*h+n*H)*i;a[5]=(d*h-c*j-n*G)*i;a[6]=(q*F-t*E+s*A)*i;a[7]=(t*w-k*F-s*z)*i;a[8]=(k*E-q*w+s*r)*i;return a};d.str=function(a){return"mat3("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+")"};d.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+Math.pow(a[6],
+2)+Math.pow(a[7],2)+Math.pow(a[8],2))};"undefined"!==typeof a&&(a.mat3=d);var r={create:function(){var a=new c(16);a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a},clone:function(a){var b=new c(16);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b},copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=
+b[2];a[3]=b[3];a[4]=b[4];a[5]=b[5];a[6]=b[6];a[7]=b[7];a[8]=b[8];a[9]=b[9];a[10]=b[10];a[11]=b[11];a[12]=b[12];a[13]=b[13];a[14]=b[14];a[15]=b[15];return a},identity:function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a},transpose:function(a,b){if(a===b){var c=b[1],d=b[2],e=b[3],n=b[6],l=b[7],g=b[11];a[1]=b[4];a[2]=b[8];a[3]=b[12];a[4]=c;a[6]=b[9];a[7]=b[13];a[8]=d;a[9]=n;a[11]=b[14];a[12]=e;a[13]=l;a[14]=g}else a[0]=
+b[0],a[1]=b[4],a[2]=b[8],a[3]=b[12],a[4]=b[1],a[5]=b[5],a[6]=b[9],a[7]=b[13],a[8]=b[2],a[9]=b[6],a[10]=b[10],a[11]=b[14],a[12]=b[3],a[13]=b[7],a[14]=b[11],a[15]=b[15];return a},invert:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],g=b[5],u=b[6],h=b[7],j=b[8],m=b[9],i=b[10],k=b[11],q=b[12],t=b[13],s=b[14],r=b[15],z=c*g-d*l,w=c*u-e*l,B=c*h-n*l,A=d*u-e*g,E=d*h-n*g,F=e*h-n*u,G=j*t-m*q,H=j*s-i*q,I=j*r-k*q,L=m*s-i*t,M=m*r-k*t,O=i*r-k*s,D=z*O-w*M+B*L+A*I-E*H+F*G;if(!D)return null;D=1/D;a[0]=(g*O-u*
+M+h*L)*D;a[1]=(e*M-d*O-n*L)*D;a[2]=(t*F-s*E+r*A)*D;a[3]=(i*E-m*F-k*A)*D;a[4]=(u*I-l*O-h*H)*D;a[5]=(c*O-e*I+n*H)*D;a[6]=(s*B-q*F-r*w)*D;a[7]=(j*F-i*B+k*w)*D;a[8]=(l*M-g*I+h*G)*D;a[9]=(d*I-c*M-n*G)*D;a[10]=(q*E-t*B+r*z)*D;a[11]=(m*B-j*E-k*z)*D;a[12]=(g*H-l*L-u*G)*D;a[13]=(c*L-d*H+e*G)*D;a[14]=(t*w-q*A-s*z)*D;a[15]=(j*A-m*w+i*z)*D;return a},adjoint:function(a,b){var c=b[0],d=b[1],e=b[2],n=b[3],l=b[4],g=b[5],h=b[6],j=b[7],m=b[8],i=b[9],k=b[10],q=b[11],t=b[12],s=b[13],r=b[14],z=b[15];a[0]=g*(k*z-q*r)-
+i*(h*z-j*r)+s*(h*q-j*k);a[1]=-(d*(k*z-q*r)-i*(e*z-n*r)+s*(e*q-n*k));a[2]=d*(h*z-j*r)-g*(e*z-n*r)+s*(e*j-n*h);a[3]=-(d*(h*q-j*k)-g*(e*q-n*k)+i*(e*j-n*h));a[4]=-(l*(k*z-q*r)-m*(h*z-j*r)+t*(h*q-j*k));a[5]=c*(k*z-q*r)-m*(e*z-n*r)+t*(e*q-n*k);a[6]=-(c*(h*z-j*r)-l*(e*z-n*r)+t*(e*j-n*h));a[7]=c*(h*q-j*k)-l*(e*q-n*k)+m*(e*j-n*h);a[8]=l*(i*z-q*s)-m*(g*z-j*s)+t*(g*q-j*i);a[9]=-(c*(i*z-q*s)-m*(d*z-n*s)+t*(d*q-n*i));a[10]=c*(g*z-j*s)-l*(d*z-n*s)+t*(d*j-n*g);a[11]=-(c*(g*q-j*i)-l*(d*q-n*i)+m*(d*j-n*g));a[12]=
+-(l*(i*r-k*s)-m*(g*r-h*s)+t*(g*k-h*i));a[13]=c*(i*r-k*s)-m*(d*r-e*s)+t*(d*k-e*i);a[14]=-(c*(g*r-h*s)-l*(d*r-e*s)+t*(d*h-e*g));a[15]=c*(g*k-h*i)-l*(d*k-e*i)+m*(d*h-e*g);return a},determinant:function(a){var b=a[0],c=a[1],d=a[2],e=a[3],n=a[4],l=a[5],g=a[6],h=a[7],j=a[8],i=a[9],m=a[10],k=a[11],q=a[12],s=a[13],t=a[14];a=a[15];return(b*l-c*n)*(m*a-k*t)-(b*g-d*n)*(i*a-k*s)+(b*h-e*n)*(i*t-m*s)+(c*g-d*l)*(j*a-k*q)-(c*h-e*l)*(j*t-m*q)+(d*h-e*g)*(j*s-i*q)},multiply:function(a,b,c){var d=b[0],e=b[1],n=b[2],
+l=b[3],g=b[4],h=b[5],j=b[6],i=b[7],m=b[8],k=b[9],q=b[10],s=b[11],t=b[12],r=b[13],z=b[14];b=b[15];var w=c[0],C=c[1],B=c[2],A=c[3];a[0]=w*d+C*g+B*m+A*t;a[1]=w*e+C*h+B*k+A*r;a[2]=w*n+C*j+B*q+A*z;a[3]=w*l+C*i+B*s+A*b;w=c[4];C=c[5];B=c[6];A=c[7];a[4]=w*d+C*g+B*m+A*t;a[5]=w*e+C*h+B*k+A*r;a[6]=w*n+C*j+B*q+A*z;a[7]=w*l+C*i+B*s+A*b;w=c[8];C=c[9];B=c[10];A=c[11];a[8]=w*d+C*g+B*m+A*t;a[9]=w*e+C*h+B*k+A*r;a[10]=w*n+C*j+B*q+A*z;a[11]=w*l+C*i+B*s+A*b;w=c[12];C=c[13];B=c[14];A=c[15];a[12]=w*d+C*g+B*m+A*t;a[13]=
+w*e+C*h+B*k+A*r;a[14]=w*n+C*j+B*q+A*z;a[15]=w*l+C*i+B*s+A*b;return a}};r.mul=r.multiply;r.translate=function(a,b,c){var d=c[0],e=c[1];c=c[2];var n,l,g,h,j,i,m,k,q,s,t,r;b===a?(a[12]=b[0]*d+b[4]*e+b[8]*c+b[12],a[13]=b[1]*d+b[5]*e+b[9]*c+b[13],a[14]=b[2]*d+b[6]*e+b[10]*c+b[14],a[15]=b[3]*d+b[7]*e+b[11]*c+b[15]):(n=b[0],l=b[1],g=b[2],h=b[3],j=b[4],i=b[5],m=b[6],k=b[7],q=b[8],s=b[9],t=b[10],r=b[11],a[0]=n,a[1]=l,a[2]=g,a[3]=h,a[4]=j,a[5]=i,a[6]=m,a[7]=k,a[8]=q,a[9]=s,a[10]=t,a[11]=r,a[12]=n*d+j*e+q*c+
+b[12],a[13]=l*d+i*e+s*c+b[13],a[14]=g*d+m*e+t*c+b[14],a[15]=h*d+k*e+r*c+b[15]);return a};r.scale=function(a,b,c){var d=c[0],e=c[1];c=c[2];a[0]=b[0]*d;a[1]=b[1]*d;a[2]=b[2]*d;a[3]=b[3]*d;a[4]=b[4]*e;a[5]=b[5]*e;a[6]=b[6]*e;a[7]=b[7]*e;a[8]=b[8]*c;a[9]=b[9]*c;a[10]=b[10]*c;a[11]=b[11]*c;a[12]=b[12];a[13]=b[13];a[14]=b[14];a[15]=b[15];return a};r.rotate=function(a,c,d,e){var g=e[0],n=e[1];e=e[2];var l=Math.sqrt(g*g+n*n+e*e),h,j,i,m,k,q,s,t,r,z,w,Q,C,B,A,E,F,G,H,I;if(Math.abs(l)<b)return null;l=1/l;g*=
+l;n*=l;e*=l;h=Math.sin(d);j=Math.cos(d);i=1-j;d=c[0];l=c[1];m=c[2];k=c[3];q=c[4];s=c[5];t=c[6];r=c[7];z=c[8];w=c[9];Q=c[10];C=c[11];B=g*g*i+j;A=n*g*i+e*h;E=e*g*i-n*h;F=g*n*i-e*h;G=n*n*i+j;H=e*n*i+g*h;I=g*e*i+n*h;g=n*e*i-g*h;n=e*e*i+j;a[0]=d*B+q*A+z*E;a[1]=l*B+s*A+w*E;a[2]=m*B+t*A+Q*E;a[3]=k*B+r*A+C*E;a[4]=d*F+q*G+z*H;a[5]=l*F+s*G+w*H;a[6]=m*F+t*G+Q*H;a[7]=k*F+r*G+C*H;a[8]=d*I+q*g+z*n;a[9]=l*I+s*g+w*n;a[10]=m*I+t*g+Q*n;a[11]=k*I+r*g+C*n;c!==a&&(a[12]=c[12],a[13]=c[13],a[14]=c[14],a[15]=c[15]);return a};
+r.rotateX=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[4],g=b[5],l=b[6],h=b[7],j=b[8],i=b[9],m=b[10],k=b[11];b!==a&&(a[0]=b[0],a[1]=b[1],a[2]=b[2],a[3]=b[3],a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[4]=e*c+j*d;a[5]=g*c+i*d;a[6]=l*c+m*d;a[7]=h*c+k*d;a[8]=j*c-e*d;a[9]=i*c-g*d;a[10]=m*c-l*d;a[11]=k*c-h*d;return a};r.rotateY=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[0],g=b[1],l=b[2],h=b[3],j=b[8],i=b[9],m=b[10],k=b[11];b!==a&&(a[4]=b[4],a[5]=b[5],a[6]=b[6],a[7]=b[7],
+a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[0]=e*c-j*d;a[1]=g*c-i*d;a[2]=l*c-m*d;a[3]=h*c-k*d;a[8]=e*d+j*c;a[9]=g*d+i*c;a[10]=l*d+m*c;a[11]=h*d+k*c;return a};r.rotateZ=function(a,b,c){var d=Math.sin(c);c=Math.cos(c);var e=b[0],g=b[1],l=b[2],h=b[3],j=b[4],i=b[5],m=b[6],k=b[7];b!==a&&(a[8]=b[8],a[9]=b[9],a[10]=b[10],a[11]=b[11],a[12]=b[12],a[13]=b[13],a[14]=b[14],a[15]=b[15]);a[0]=e*c+j*d;a[1]=g*c+i*d;a[2]=l*c+m*d;a[3]=h*c+k*d;a[4]=j*c-e*d;a[5]=i*c-g*d;a[6]=m*c-l*d;a[7]=k*c-h*d;return a};r.fromRotationTranslation=
+function(a,b,c){var d=b[0],e=b[1],g=b[2],h=b[3],j=d+d,i=e+e,m=g+g;b=d*j;var k=d*i,d=d*m,q=e*i,e=e*m,g=g*m,j=h*j,i=h*i,h=h*m;a[0]=1-(q+g);a[1]=k+h;a[2]=d-i;a[3]=0;a[4]=k-h;a[5]=1-(b+g);a[6]=e+j;a[7]=0;a[8]=d+i;a[9]=e-j;a[10]=1-(b+q);a[11]=0;a[12]=c[0];a[13]=c[1];a[14]=c[2];a[15]=1;return a};r.fromQuat=function(a,b){var c=b[0],d=b[1],e=b[2],g=b[3],h=c+c,j=d+d,i=e+e,c=c*h,m=d*h,d=d*j,k=e*h,q=e*j,e=e*i,h=g*h,j=g*j,g=g*i;a[0]=1-d-e;a[1]=m+g;a[2]=k-j;a[3]=0;a[4]=m-g;a[5]=1-c-e;a[6]=q+h;a[7]=0;a[8]=k+j;
+a[9]=q-h;a[10]=1-c-d;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a};r.frustum=function(a,b,c,d,e,g,h){var j=1/(c-b),i=1/(e-d),m=1/(g-h);a[0]=2*g*j;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=2*g*i;a[6]=0;a[7]=0;a[8]=(c+b)*j;a[9]=(e+d)*i;a[10]=(h+g)*m;a[11]=-1;a[12]=0;a[13]=0;a[14]=2*(h*g)*m;a[15]=0;return a};r.perspective=function(a,b,c,d,e){b=1/Math.tan(b/2);var g=1/(d-e);a[0]=b/c;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=b;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=(e+d)*g;a[11]=-1;a[12]=0;a[13]=0;a[14]=2*e*d*g;a[15]=0;
+return a};r.ortho=function(a,b,c,d,e,g,h){var j=1/(b-c),i=1/(d-e),m=1/(g-h);a[0]=-2*j;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=-2*i;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=2*m;a[11]=0;a[12]=(b+c)*j;a[13]=(e+d)*i;a[14]=(h+g)*m;a[15]=1;return a};r.lookAt=function(a,c,d,e){var g,h,j,i,m,k,q,s,t=c[0],z=c[1];c=c[2];j=e[0];i=e[1];h=e[2];q=d[0];e=d[1];g=d[2];if(Math.abs(t-q)<b&&Math.abs(z-e)<b&&Math.abs(c-g)<b)return r.identity(a);d=t-q;e=z-e;q=c-g;s=1/Math.sqrt(d*d+e*e+q*q);d*=s;e*=s;q*=s;g=i*q-h*e;h=h*d-j*q;j=j*e-i*
+d;(s=Math.sqrt(g*g+h*h+j*j))?(s=1/s,g*=s,h*=s,j*=s):j=h=g=0;i=e*j-q*h;m=q*g-d*j;k=d*h-e*g;(s=Math.sqrt(i*i+m*m+k*k))?(s=1/s,i*=s,m*=s,k*=s):k=m=i=0;a[0]=g;a[1]=i;a[2]=d;a[3]=0;a[4]=h;a[5]=m;a[6]=e;a[7]=0;a[8]=j;a[9]=k;a[10]=q;a[11]=0;a[12]=-(g*t+h*z+j*c);a[13]=-(i*t+m*z+k*c);a[14]=-(d*t+e*z+q*c);a[15]=1;return a};r.str=function(a){return"mat4("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+
+a[15]+")"};r.frob=function(a){return Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)+Math.pow(a[3],2)+Math.pow(a[4],2)+Math.pow(a[5],2)+Math.pow(a[6],2)+Math.pow(a[7],2)+Math.pow(a[8],2)+Math.pow(a[9],2)+Math.pow(a[10],2)+Math.pow(a[11],2)+Math.pow(a[12],2)+Math.pow(a[13],2)+Math.pow(a[14],2)+Math.pow(a[15],2))};"undefined"!==typeof a&&(a.mat4=r);var m={create:function(){var a=new c(4);a[0]=0;a[1]=0;a[2]=0;a[3]=1;return a}},q=g.create(),s=g.fromValues(1,0,0),t=g.fromValues(0,1,0);m.rotationTo=
+function(a,b,c){var d=g.dot(b,c);if(-0.999999>d)return g.cross(q,s,b),1E-6>g.length(q)&&g.cross(q,t,b),g.normalize(q,q),m.setAxisAngle(a,q,Math.PI),a;if(0.999999<d)return a[0]=0,a[1]=0,a[2]=0,a[3]=1,a;g.cross(q,b,c);a[0]=q[0];a[1]=q[1];a[2]=q[2];a[3]=1+d;return m.normalize(a,a)};var z=d.create();m.setAxes=function(a,b,c,d){z[0]=c[0];z[3]=c[1];z[6]=c[2];z[1]=d[0];z[4]=d[1];z[7]=d[2];z[2]=-b[0];z[5]=-b[1];z[8]=-b[2];return m.normalize(a,m.fromMat3(a,z))};m.clone=i.clone;m.fromValues=i.fromValues;m.copy=
+i.copy;m.set=i.set;m.identity=function(a){a[0]=0;a[1]=0;a[2]=0;a[3]=1;return a};m.setAxisAngle=function(a,b,c){c*=0.5;var d=Math.sin(c);a[0]=d*b[0];a[1]=d*b[1];a[2]=d*b[2];a[3]=Math.cos(c);return a};m.add=i.add;m.multiply=function(a,b,c){var d=b[0],e=b[1],g=b[2];b=b[3];var h=c[0],j=c[1],i=c[2];c=c[3];a[0]=d*c+b*h+e*i-g*j;a[1]=e*c+b*j+g*h-d*i;a[2]=g*c+b*i+d*j-e*h;a[3]=b*c-d*h-e*j-g*i;return a};m.mul=m.multiply;m.scale=i.scale;m.rotateX=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);
+c=Math.cos(c);a[0]=d*c+b*h;a[1]=e*c+g*h;a[2]=g*c-e*h;a[3]=b*c-d*h;return a};m.rotateY=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);c=Math.cos(c);a[0]=d*c-g*h;a[1]=e*c+b*h;a[2]=g*c+d*h;a[3]=b*c-e*h;return a};m.rotateZ=function(a,b,c){c*=0.5;var d=b[0],e=b[1],g=b[2];b=b[3];var h=Math.sin(c);c=Math.cos(c);a[0]=d*c+e*h;a[1]=e*c-d*h;a[2]=g*c+b*h;a[3]=b*c-g*h;return a};m.calculateW=function(a,b){var c=b[0],d=b[1],e=b[2];a[0]=c;a[1]=d;a[2]=e;a[3]=Math.sqrt(Math.abs(1-c*c-d*d-
+e*e));return a};m.dot=i.dot;m.lerp=i.lerp;m.slerp=function(a,b,c,d){var e=b[0],g=b[1],h=b[2];b=b[3];var j=c[0],i=c[1],m=c[2];c=c[3];var k,q,s;q=e*j+g*i+h*m+b*c;0>q&&(q=-q,j=-j,i=-i,m=-m,c=-c);1E-6<1-q?(k=Math.acos(q),s=Math.sin(k),q=Math.sin((1-d)*k)/s,d=Math.sin(d*k)/s):q=1-d;a[0]=q*e+d*j;a[1]=q*g+d*i;a[2]=q*h+d*m;a[3]=q*b+d*c;return a};m.invert=function(a,b){var c=b[0],d=b[1],e=b[2],g=b[3],h=c*c+d*d+e*e+g*g,h=h?1/h:0;a[0]=-c*h;a[1]=-d*h;a[2]=-e*h;a[3]=g*h;return a};m.conjugate=function(a,b){a[0]=
+-b[0];a[1]=-b[1];a[2]=-b[2];a[3]=b[3];return a};m.length=i.length;m.len=m.length;m.squaredLength=i.squaredLength;m.sqrLen=m.squaredLength;m.normalize=i.normalize;m.fromMat3=function(a,b){var c=b[0]+b[4]+b[8];if(0<c)c=Math.sqrt(c+1),a[3]=0.5*c,c=0.5/c,a[0]=(b[5]-b[7])*c,a[1]=(b[6]-b[2])*c,a[2]=(b[1]-b[3])*c;else{var d=0;b[4]>b[0]&&(d=1);b[8]>b[3*d+d]&&(d=2);var e=(d+1)%3,g=(d+2)%3,c=Math.sqrt(b[3*d+d]-b[3*e+e]-b[3*g+g]+1);a[d]=0.5*c;c=0.5/c;a[3]=(b[3*e+g]-b[3*g+e])*c;a[e]=(b[3*e+d]+b[3*d+e])*c;a[g]=
+(b[3*g+d]+b[3*d+g])*c}return a};m.str=function(a){return"quat("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")"};"undefined"!==typeof a&&(a.quat=m)})(GLMAT);try{module.exports=GLMAT}catch(e$$10){}try{glm.exists&&alert("glm.common.js loaded over exist glm instance: "+glm)}catch(e$$11){}glm=null;GLMJS_PREFIX="glm-js: ";
+GLM={$DEBUG:"undefined"!==typeof $GLM_DEBUG&&$GLM_DEBUG,version:"0.0.6b",GLM_VERSION:96,$outer:{polyfills:GLM_polyfills(),functions:{},intern:function(a,b){if(a)if(void 0===b&&"object"===typeof a)for(var c in a)GLM.$outer.intern(c,a[c]);else return GLM.$DEBUG&&GLM.$outer.console.debug("intern "+a,b&&(b.name||typeof b)),GLM.$outer[a]=b},$import:function(a){GLM.$outer.$import=function(){throw Error("glm.$outer.$import already called...");};GLM.$outer.intern(a.statics);GLM.$template.extend(GLM,GLM.$template["declare<T,V,number>"](a["declare<T,V,number>"]),
+GLM.$template["declare<T,V,...>"](a["declare<T,V,...>"]),GLM.$template["declare<T,...>"](a["declare<T,...>"]),GLM.$template["declare<T>"](a["declare<T>"]));GLM.$init(a)},console:$GLM_reset_logging(),quat_array_from_xyz:function(a){var b=glm.quat(),c=glm.mat3(1);b["*="](glm.angleAxis(a.x,c[0]));b["*="](glm.angleAxis(a.y,c[1]));b["*="](glm.angleAxis(a.z,c[2]));return b.elements},Array:Array,ArrayBuffer:ArrayBuffer,Float32Array:Float32Array,Float64Array:Float64Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array,
+Uint32Array:Uint32Array,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,DataView:"undefined"!==typeof DataView&&DataView,$rebindTypedArrays:function(a){var b=Object.keys(GLM.$outer).filter(RegExp.prototype.test.bind(/.Array$|^ArrayBuffer$|^DataView$/)).map(function(b){var e=a.call(this,b,GLM.$outer[b]);e!==GLM.$outer[b]&&(GLM.$outer.console.warn("$rebindTypedArrays("+b+")... replacing"),GLM.$outer[b]=e);return e});GLM.$subarray=GLM.patch_subarray();return b}},$extern:$GLM_extern,$log:$GLM_log,
+GLMJSError:$GLM_GLMJSError("GLMJSError"),_radians:function(a){return a*this.PI/180}.bind(Math),_degrees:function(a){return 180*a/this.PI}.bind(Math),normalize:$GLM_extern("normalize"),inverse:$GLM_extern("inverse"),distance:$GLM_extern("distance"),length:$GLM_extern("length"),length2:$GLM_extern("length2"),transpose:$GLM_extern("transpose"),slerp:$GLM_extern("slerp"),mix:$GLM_extern("mix"),clamp:$GLM_extern("clamp"),angleAxis:$GLM_extern("angleAxis"),rotate:$GLM_extern("rotate"),scale:$GLM_extern("scale"),
+translate:$GLM_extern("translate"),lookAt:$GLM_extern("lookAt"),cross:$GLM_extern("cross"),dot:$GLM_extern("dot"),perspective:function(a,b,c,e){return GLM.$outer.mat4_perspective(a,b,c,e)},ortho:function(a,b,c,e,d,h){return GLM.$outer.mat4_ortho(a,b,c,e,d,h)},_eulerAngles:function(a){return GLM.$outer.vec3_eulerAngles(a)},angle:function(a){return 2*Math.acos(a.w)},axis:function(a){var b=1-a.w*a.w;if(0>=b)return glm.vec3(0,0,1);b=1/Math.sqrt(b);return glm.vec3(a.x*b,a.y*b,a.z*b)},$from_ptr:function(a,
+b,c){if(this!==GLM)throw new GLM.GLMJSError("... use glm.make_<type>() (not new glm.make<type>())");b=new GLM.$outer.Float32Array(b.buffer||b,c||0,a.componentLength);b=new GLM.$outer.Float32Array(b);return new a(b)},make_vec2:function(a,b){return GLM.$from_ptr.call(this,GLM.vec2,a,2===arguments.length?b:a.byteOffset)},make_vec3:function(a,b){return GLM.$from_ptr.call(this,GLM.vec3,a,2===arguments.length?b:a.byteOffset)},make_vec4:function(a,b){return GLM.$from_ptr.call(this,GLM.vec4,a,2===arguments.length?
+b:a.byteOffset)},make_quat:function(a,b){return GLM.$from_ptr.call(this,GLM.quat,a,2===arguments.length?b:a.byteOffset)},make_mat3:function(a,b){return GLM.$from_ptr.call(this,GLM.mat3,a,2===arguments.length?b:a.byteOffset)},make_mat4:function(a,b){return GLM.$from_ptr.call(this,GLM.mat4,a,2===arguments.length?b:a.byteOffset)},diagonal4x4:function(a){if("vec4"!==GLM.$typeof(a))throw new GLM.GLMJSError("unsupported argtype to GLM.diagonal4x4: "+["type:"+GLM.$typeof(a)]);a=a.elements;return new GLM.mat4([a[0],
+0,0,0,0,a[1],0,0,0,0,a[2],0,0,0,0,a[3]])},diagonal3x3:function(a){if("vec3"!==GLM.$typeof(a))throw new GLM.GLMJSError("unsupported argtype to GLM.diagonal3x3: "+["type:"+GLM.$typeof(a)]);a=a.elements;return new GLM.mat3([a[0],0,0,0,a[1],0,0,0,a[2]])},_toMat4:function(a){return new GLM.mat4(GLM.$outer.mat4_array_from_quat(a))},FAITHFUL:!0,to_string:function(a,b){try{var c=a.$type||typeof a;if(!GLM[c])throw new GLM.GLMJSError("unsupported argtype to GLM.to_string: "+["type:"+c,a]);return GLM.FAITHFUL?
+GLM.$to_string(a,b).replace(/[\t\n]/g,""):GLM.$to_string(a,b)}catch(e){return GLM.$DEBUG&&GLM.$outer.console.error("to_string error: ",c,a+"",e),e+""}},$sizeof:function(a){return a.BYTES_PER_ELEMENT},$types:[],$isGLMConstructor:function(a){return!!(a&&a.prototype instanceof GLM.$GLMBaseType)},$getGLMType:function(a){return a instanceof GLM.$GLMBaseType&&a.constructor||"string"===typeof a&&GLM[a]},$isGLMObject:function(a){return!!(a instanceof GLM.$GLMBaseType&&a.$type)},$typeof:function(a){return a instanceof
+GLM.$GLMBaseType?a.$type:"undefined"},$to_array:function(a){return[].slice.call(a.elements)},$to_json:function(a,b,c){this instanceof GLM.$GLMBaseType&&(c=b,b=a,a=this);return JSON.stringify(GLM.$to_object(a),b,c)},$inspect:function(a){this instanceof GLM.$GLMBaseType&&(a=this);return GLM.$to_json(a,null,2)},_clamp:function(a,b,c){return a<b?b:a>c?c:a},_abs:function(a){return Math.abs(a)},_equal:function(a,b){return a===b},_epsilonEqual:function(a,b,c){return Math.abs(a-b)<c},_fract:function(a){return a-
+Math.floor(a)},_frexp:function(){function a(b,c){var e=GLM.$outer.DataView||a._DataView;if(0==b)return c&&Array.isArray(c)?c[0]=c[1]=0:[0,0];e=new e(new GLM.$outer.ArrayBuffer(8));e.setFloat64(0,b);var d=e.getUint32(0)>>>20&2047;0===d&&(e.setFloat64(0,b*Math.pow(2,64)),d=(e.getUint32(0)>>>20&2047)-64);e=d-1022;d=GLM.ldexp(b,-e);return c&&Array.isArray(c)?(c[0]=e,c[1]=d):[d,e]}a._DataView=function(a){this.buffer=a;this.setFloat64=function(a,b){if(0!==a)throw Error("...this is a very limited DataView emulator");
+(new Uint8Array(this.buffer)).set([].reverse.call(new Uint8Array((new Float64Array([b])).buffer)),a)};this.getUint32=function(a){if(0!==a)throw Error("...this is a very limited DataView emulator");return(new Uint32Array((new Uint8Array([].slice.call(new Uint8Array(this.buffer)).reverse())).buffer))[1]}};return a}(),_ldexp:function(a,b){return 1023<b?a*Math.pow(2,1023)*Math.pow(2,b-1023):-1074>b?a*Math.pow(2,-1074)*Math.pow(2,b+1074):a*Math.pow(2,b)},_max:Math.max,_min:Math.min,sqrt:Math.sqrt,__sign:function(a){return 0<
+a?1:0>a?-1:+a},$constants:{epsilon:1E-6,euler:0.5772156649015329,e:Math.E,ln_ten:Math.LN10,ln_two:Math.LN2,pi:Math.PI,half_pi:Math.PI/2,quarter_pi:Math.PI/4,one_over_pi:1/Math.PI,two_over_pi:2/Math.PI,root_pi:Math.sqrt(Math.PI),root_two:Math.sqrt(2),root_three:Math.sqrt(3),two_over_root_pi:2/Math.sqrt(Math.PI),one_over_root_two:Math.SQRT1_2,root_two:Math.SQRT2},FIXEDPRECISION:6,$toFixedString:function(a,b,c,e){void 0===e&&(e=GLM.FIXEDPRECISION);if(!c||!c.map)throw Error("unsupported argtype to $toFixedString(..,..,props="+
+typeof c+")");try{var d="";c.map(function(c){c=b[d=c];if(!c.toFixed)throw Error("!toFixed in w"+[c,a,JSON.stringify(b)]);return c.toFixed(0)})}catch(h){throw GLM.$DEBUG&&GLM.$outer.console.error("$toFixedString error",a,typeof b,Object.prototype.toString.call(b),d),GLM.$DEBUG&&glm.$log("$toFixedString error",a,typeof b,Object.prototype.toString.call(b),d),new GLM.GLMJSError(h);}c=c.map(function(a){return b[a].toFixed(e)});return a+"("+c.join(", ")+")"}};GLM._sign=Math.sign||GLM.__sign;
+for(var p in GLM.$constants)(function(a,b){GLM[b]=function(){return a};GLM[b].valueOf=GLM[b]})(GLM.$constants[p],p);
+GLM.$GLMBaseType=function(){function a(a,c){var e=a.$||{};this.$type=c;this.$type_name=e.name||"<"+c+">";e.components&&(this.$components=e.components[0]);this.$len=this.components=a.componentLength;this.constructor=a;this.byteLength=a.BYTES_PER_ELEMENT;GLM.$types.push(c)}a.prototype={clone:function(){return new this.constructor(new this.elements.constructor(this.elements))},toString:function(){return GLM.$to_string(this)},inspect:function(){return GLM.$inspect(this)},toJSON:function(){return GLM.$to_object(this)}};
+Object.defineProperty(a.prototype,"address",{get:function(){var a=this.elements.byteOffset.toString(16);return"0x00000000".substr(0,10-a.length)+a}});return a}();
+(function(){function a(a,b,c){return a.subarray(b,c||a.length)}function b(a,b,c){var e=a.constructor;c=c||a.length;return new e(a.buffer,a.byteOffset+b*e.BYTES_PER_ELEMENT,c-b)}function c(){var a=new GLM.$outer.Float32Array([0,0]);a.subarray(1).subarray(0)[0]=1;var b=c.result=[a[1],(new GLM.$outer.Float32Array(16)).subarray(12,16).length];return!(a[1]!==b[0]||4!==b[1])}function e(a){var b=new GLM.$outer.Float32Array([0,0]);a(a(b,1),0)[0]=1;a=e.result=[b[1],a(new GLM.$outer.Float32Array(16),12,16).length];
+return!(b[1]!==a[0]||4!==a[1])}Object.defineProperty(GLM,"patch_subarray",{configurable:!0,value:function(){var d=!c()?b:a;d.workaround_broken_spidermonkey_subarray=b;d.native_subarray=a;if(!e(d))throw Error("failed to resolve working TypedArray.subarray implementation... "+e.result);return d}})})();GLM.$subarray=GLM.patch_subarray();
+var GLM_template=GLM.$template={_genArgError:function(a,b,c,e){~e.indexOf(void 0)&&(e=e.slice(0,e.indexOf(void 0)));var d=RegExp.prototype.test.bind(/^[^$_]/);return new GLM.GLMJSError("unsupported argtype to "+b+" "+a.$sig+": [typ="+c+"] :: got arg types: "+e.map(GLM.$template.jstypes.get)+" // supported types: "+Object.keys(a).filter(d).join("||"))},jstypes:{get:function(a){return null===a?"null":void 0===a?"undefined":a.$type||GLM.$template.jstypes[typeof a]||GLM.$template.jstypes[a+""]||function(a){if("object"===
+typeof a){if(a instanceof GLM.$outer.Float32Array)return"Float32Array";if(a instanceof GLM.$outer.ArrayBuffer)return"ArrayBuffer";if(Array.isArray(a))return"array"}return"<unknown "+[typeof a,a]+">"}(a)},"0":"float","boolean":"bool",number:"float",string:"string","[object Float32Array]":"Float32Array","[object ArrayBuffer]":"ArrayBuffer","function":"function"},_add_overrides:function(a,b){for(var c in b)b[c]&&GLM[c].override(a,b[c])},_add_inline_override:function(a,b,c){this[b]=eval(GLM.$template._traceable("glm_"+
+a+"_"+b,c))();return this},_inline_helpers:function(a,b){Object.defineProperty(a,"GLM",{value:GLM});return{$type:"built-in",$type_name:b,$template:a,F:a,dbg:b,override:this._add_inline_override.bind(a,b),link:function(c){var e=a[c];e||(e=a[[c,"undefined"]]);if(!e)throw new GLM.GLMJSError("error linking direct function for "+b+"<"+c+"> or "+b+"<"+[c,void 0]+">");return/\bthis[\[.]/.test(e+"")?e.bind(a):e}}},"template<T>":function(a,b){a.$sig="template<T>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,
+d=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("Tglm_"+b,function(b){this instanceof d&&(b=this);var j=[b&&b.$type||c[typeof b]||c.get(b)||"null"];if(!a[j])throw e(a,arguments.callee.dbg,j,[b]);return a[j](b)}))())},"template<T,...>":function(a,b){a.$sig="template<T,...>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,d=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("Tdotglm_"+b,function(b){for(var j=Array(arguments.length),
+g=0;g<j.length;g++)j[g]=arguments[g];this instanceof d&&j.unshift(b=this);g=[b&&b.$type||c[typeof b]||c.get(b)||"null"];if(!a[g])throw e(a,arguments.callee.dbg,g,j);return a[g].apply(a,j)}))())},"template<T,V,number>":function(a,b){a.$sig="template<T,V,number>";var c=GLM.$template.jstypes,e=GLM.$template._genArgError,d=GLM.GLMJSError,h=GLM.$GLMBaseType;return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("TVnglm_"+b,function(){for(var b=Array(arguments.length),g=0;g<b.length;g++)b[g]=
+arguments[g];this instanceof h&&b.unshift(this);var g=b[0],k=b[1],b=b[2],i=[g&&g.$type||c[typeof g]||c[g+""]||"<unknown "+g+">",k&&k.$type||c[typeof k]||c[k+""]||"<unknown "+k+">"];if(!a[i])throw e(a,arguments.callee.dbg,i,[g,k,b]);if("number"!==typeof b)throw new d(arguments.callee.dbg+a.$sig+": unsupported n type: "+[typeof b,b]);return a[i](g,k,b)}))())},"template<T,V,...>":function(a,b){a.$sig="template<T,V,...>";var c=GLM.$template.jstypes,e=GLM.$GLMBaseType,d=GLM.$template._genArgError,h=GLM.$outer.Array;
+return this.slingshot(this._inline_helpers(a,b),eval(this._traceable("TVglm_"+b,function(){for(var b=new h(arguments.length),g=0;g<b.length;g++)b[g]=arguments[g];this instanceof e&&b.unshift(this);var g=b[0],k=b[1],g=[g&&g.$type||c[typeof g],k&&k.$type||c[typeof k]||c[k+""]||h.isArray(k)&&"array"+k.length+""||""+k+""];if(!a[g])throw d(a,arguments.callee.dbg,g,b);return a[g].apply(a,b)}))())},override:function(a,b,c,e,d){function h(a,c){GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+
+Object.keys(a.$template).filter(function(a){return!~a.indexOf("$")}).map(function(a){return!~c.indexOf(a)?"*"+a+"*":a}).join(" | "))}GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: ",a,b,c.$op?'$op: ["'+c.$op+'"]':"");if(!e)throw Error("unspecified target group "+e+' (expected override(<TV>, "p", {TSP}, ret={GROUP}))');var j=e[b];if(j&&j.$op!==c.$op)throw Error('glm.$template.override: mismatch merging existing override: .$op "'+[j.$op,"!=",c.$op].join(" ")+'" p='+[b,j.$op,c.$op,"||"+
+Object.keys(j.$template).join("||")]);var g=GLM.$template[a](GLM.$template.deNify(c,b),b);if(j&&j.F.$sig!==g.F.$sig)throw Error('glm.$template.override: mismatch merging existing override: .$sig "'+[j&&j.F.$sig,"!=",g.F.$sig].join(" ")+'" p='+[b,j&&j.F.$sig,g.F.$sig,"||"+Object.keys(j&&j.$template||{}).join("||")]);g.$op=c.$op;if(j){for(var k in g.$template)"$op"===k||"$sig"===k||(a=k in j.$template,!a||!0===d?(GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+k+" merged"),
+j.$template[k]=g.$template[k]):a&&GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+k+" skipped"));if(GLM.$DEBUG){var i=[];Object.keys(j.$template).forEach(function(a){a in g.$template||(GLM.$DEBUG&&GLM.$outer.console.debug("glm.$template.override: "+b+" ... "+a+" carried-forward"),i.push(a))});h(e[b],i)}}else e[b]=g,GLM.$DEBUG&&h(e[b],[]);return e},_override:function(a,b,c){for(var e in b){if("mat4_scale"!==e&&"object"!==typeof b[e])throw new GLM.GLMJSError("expect object property overrides"+
+[e,b[e],Object.keys(c)]);"object"===typeof b[e]?this.override(a,e,b[e],c,!0):ret_scale=5}return c},slingshot:function(){return this.extend.apply(this,[].reverse.call(arguments))},extend:function(a,b){[].slice.call(arguments,1).forEach(function(b){if(b)for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e])});return a},"declare<T,V,...>":function(a){return!a?{}:this._override("template<T,V,...>",a,GLM.$outer.functions)},"declare<T>":function(a){return!a?{}:this._override("template<T>",a,GLM.$outer.functions)},
+"declare<T,...>":function(a){return!a?{}:this._override("template<T,...>",a,GLM.$outer.functions)},"declare<T,V,number>":function(a){return!a?{}:this._override("template<T,V,number>",a,GLM.$outer.functions)},_tojsname:function(a){return(a||"_").replace(/[^$a-zA-Z0-9_]/g,"_")},_traceable:function(a,b){var c=b;if("function"!==typeof c)throw new GLM.GLMJSError("_traceable expects tidy function as second arg "+c);if(!a)throw new GLM.GLMJSError("_traceable expects hint or what's the point"+[c,a]);a=this._tojsname(a||
+"_traceable");c=c.toString().replace(/^(\s*var\s*(\w+)\s*=\s*)__VA_ARGS__;/mg,function(a,b,c){return b+"new Array(arguments.length);for(var I=0;I<varname.length;I++)varname[I]=arguments[I];".replace(/I/g,"__VA_ARGS__I").replace(/varname/g,c)}).replace(/\barguments[.]callee\b/g,a);if(/^function _traceable/.test(c))throw new GLM.GLMJSError("already wrapped in a _traceable: "+[c,a]);c='function _traceable(){ "use strict"; SRC; return HINT; }'.replace("HINT",a.replace(/[$]/g,"$$$$")).replace("SRC",c.replace(/[$]/g,
+"$$$$").replace(/^function\s*\(/,"function "+a+"("));c="1,"+c;if(GLM.$DEBUG)try{eval(c)}catch(e){throw console.error("_traceable error",a,c,b,e),e;}return c},deNify:function(a,b){var c={vec:[2,3,4],mat:[3,4]},e=this._tojsname.bind(this),d;for(d in a){var h=!1;d.replace(/([vV]ec|[mM]at)(?:\w*)<N>/,function(j,g){h=!0;var k=a[d];delete a[d];c[g.toLowerCase()].forEach(function(c){var g=d.replace(/<N[*]N>/g,c*c).replace(/<N>/g,c);if(!(g in a)){var h=e("glm_"+b+"_"+g);a[g]=eval("'use strict'; 1,"+(k+"").replace(/^function\s*\(/,
+"function "+h+"(").replace(/N[*]N/g,c*c).replace(/N/g,c))}})}.bind(this));/^[$]/.test(d)?GLM.$DEBUG&&GLM.$outer.console.debug("@ NOT naming "+d):!h&&("function"===typeof a[d]&&!a[d].name)&&(GLM.$DEBUG&&GLM.$outer.console.debug("naming "+e(b+"_"+d)),a[d]=eval(this._traceable("glm_"+b+"_"+d,a[d]))())}return a},$_module_stamp:+new Date,_iso:"/[*][^/*]*[*]/",_get_argnames:function(a){return(a+"").replace(/\s+/g,"").replace(RegExp(this._iso,"g"),"").split("){",1)[0].replace(/^[^(]*[(]/,"").replace(/=[^,]+/g,
+"").split(",").filter(Boolean)},_fix_$_names:function(a,b){Object.keys(b).filter(function(a){return"function"===typeof b[a]&&!b[a].name}).map(function(c){var e=a+"_"+c;GLM.$DEBUG&&GLM.$outer.console.debug("naming $."+c+" == "+e,this._traceable(e,b[c]));b[c]=eval(this._traceable("glm_"+e,b[c]))()}.bind(this));return b},_typedArrayMaker:function(a,b){return function(c){if(c.length===a)return new b(c);var e=new b(a);e.set(c);return e}},GLMType:function(a,b){var c=this._fix_$_names(a,b),e=c.identity.length,
+d,h=Object,j=GLM.$template._get_argnames.bind(GLM.$template),g=GLM.GLMJSError,k={},i;for(i in c)"function"===typeof c[i]&&function(a){k[i]=function(b){return a.apply(c,b)}}(c[i]);d=function(b){var d=k[typeof b[0]+b.length];if(!d){var e="glm."+a;b=e+"("+b.map(function(a){return typeof a})+")";d=h.keys(c).filter(function(a){return"function"===typeof c[a]&&/^\w+\d+$/.test(a)}).map(function(a){return e+"("+j(c[a])+")"});throw new g("no constructor found for: "+b+"\nsupported signatures:\n\t"+d.join("\n\t"));
+}return d};var w,r=GLM;GLM.$template._get_argnames.bind(GLM.$template);w=function(b,c){2<r.$DEBUG&&r.$outer.console.info("adopting elements...",typeof b);if(b.length!=e){if(!1===c)return c;r.$outer.console.error(a+" elements size mismatch: "+["wanted:"+e,"handed:"+b.length]);var d=r.$subarray(b,0,e);throw new r.GLMJSError(a+" elements size mismatch: "+["wanted:"+e,"handed:"+b.length,"theoreticaly-correctable?:"+(d.length===e)]);}return b};var m=this._typedArrayMaker(e,GLM.$outer.Float32Array),q,s=
+GLM.$outer;q=function(a){return a instanceof s.Float32Array};var t=function(a,b,c,g,h,i,j,k){return eval(k("glm_"+h+"$class",function(c){for(var f=new a(arguments.length),g=0;g<f.length;g++)f[g]=arguments[g];var h=d(f),g=t;if(this instanceof g)f=q(c)?w(c):m(h(f)),b.defineProperty(this,"elements",{enumerable:!1,configurable:!0,value:f});else return f=q(c)&&c.length===e?m(c):h(f),new g(f)}))()}(Array,Object,GLM,c,a,GLM.$template._get_argnames.bind(GLM.$template),GLM.GLMJSError,GLM.$template._traceable.bind(GLM.$template));
+c.components=c.components?c.components.map(function(a){return"string"===typeof a?a.split(""):a}):[];t.$=c;t.componentLength=e;t.BYTES_PER_ELEMENT=e*GLM.$outer.Float32Array.BYTES_PER_ELEMENT;t.prototype=new GLM.$GLMBaseType(t,a);t.toJSON=function(){var b={glm$type:a,glm$class:t.prototype.$type_name,glm$eg:(new t).object},c;for(c in t)/function |^[$]/.test(c+t[c])||(b[c]=t[c]);return b};return t}};
+GLM.$template["declare<T,V,...>"]({cross:{"vec2,vec2":function(a,b){return this.GLM.vec3(0,0,a.x*b.y-a.y*b.x)}},distance:{"vec<N>,vec<N>":function(a,b){return this.GLM.length(b.sub(a))}}});
+GLM.$template["declare<T,V,number>"]({mix:{"float,float":function(a,b,c){return b*c+a*(1-c)},"vec<N>,vec<N>":function(a,b,c){var e=1-c,d=new this.GLM.vecN(new a.elements.constructor(N)),h=d.elements;a=a.elements;b=b.elements;for(var j=0;j<N;j++)h[j]=b[j]*c+a[j]*e;return d}},clamp:{"float,float":function(a,b,c){return GLM._clamp(a,b,c)},"vec<N>,float":function(a,b,c){return new GLM.vecN(GLM.$to_array(a).map(function(a){return GLM._clamp(a,b,c)}))}},epsilonEqual:{"float,float":GLM._epsilonEqual,"vec<N>,vec<N>":function(a,
+b,c){for(var e=this["float,float"],d=glm.bvecN(),h=0;h<N;h++)d[h]=e(a[h],b[h],c);return d},"ivec<N>,ivec<N>":function(a,b,c){return this["vecN,vecN"](a,b,c)},"uvec<N>,uvec<N>":function(a,b,c){return this["vecN,vecN"](a,b,c)},"quat,quat":function(a,b,c){for(var e=this["float,float"],d=glm.bvec4(),h=0;4>h;h++)d[h]=e(a[h],b[h],c);return d},"mat<N>,mat<N>":function(){throw new GLM.GLMJSError("error: 'epsilonEqual' only accept floating-point and integer scalar or vector inputs");}}});
+GLM.$template.extend(GLM,GLM.$template["declare<T>"]({degrees:{"float":function(a){return this.GLM._degrees(a)},"vec<N>":function(a){return new this.GLM.vecN(this.GLM.$to_array(a).map(this.GLM._degrees))}},radians:{"float":function(a){return this.GLM._radians(a)},"vec<N>":function(a){return new this.GLM.vecN(this.GLM.$to_array(a).map(this.GLM._radians))}},sign:{"null":function(){return 0},undefined:function(){return NaN},string:function(){return NaN},"float":function(a){return GLM._sign(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._sign))},
+"ivec<N>":function(a){return new GLM.ivecN(GLM.$to_array(a).map(GLM._sign))}},abs:{"float":function(a){return GLM._abs(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._abs))}},fract:{"float":function(a){return GLM._fract(a)},"vec<N>":function(a){return new GLM.vecN(GLM.$to_array(a).map(GLM._fract))}},all:{"vec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},"bvec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},"ivec<N>":function(a){return N===
+GLM.$to_array(a).filter(Boolean).length},"uvec<N>":function(a){return N===GLM.$to_array(a).filter(Boolean).length},quat:function(a){return 4===GLM.$to_array(a).filter(Boolean).length}},$to_object:{vec2:function(a){return{x:a.x,y:a.y}},vec3:function(a){return{x:a.x,y:a.y,z:a.z}},vec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},uvec2:function(a){return{x:a.x,y:a.y}},uvec3:function(a){return{x:a.x,y:a.y,z:a.z}},uvec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},ivec2:function(a){return{x:a.x,y:a.y}},
+ivec3:function(a){return{x:a.x,y:a.y,z:a.z}},ivec4:function(a){return{x:a.x,y:a.y,z:a.z,w:a.w}},bvec2:function(a){return{x:!!a.x,y:!!a.y}},bvec3:function(a){return{x:!!a.x,y:!!a.y,z:!!a.z}},bvec4:function(a){return{x:!!a.x,y:!!a.y,z:!!a.z,w:!!a.w}},quat:function(a){return{w:a.w,x:a.x,y:a.y,z:a.z}},mat3:function(a){return{"0":this.vec3(a[0]),1:this.vec3(a[1]),2:this.vec3(a[2])}},mat4:function(a){return{"0":this.vec4(a[0]),1:this.vec4(a[1]),2:this.vec4(a[2]),3:this.vec4(a[3])}}},roll:{$atan2:Math.atan2,
+quat:function(a){return this.$atan2(2*(a.x*a.y+a.w*a.z),a.w*a.w+a.x*a.x-a.y*a.y-a.z*a.z)}},pitch:{$atan2:Math.atan2,quat:function(a){return this.$atan2(2*(a.y*a.z+a.w*a.x),a.w*a.w-a.x*a.x-a.y*a.y+a.z*a.z)}},yaw:{$asin:Math.asin,quat:function(a){return this.$asin(this.GLM.clamp(-2*(a.x*a.z-a.w*a.y),-1,1))}},eulerAngles:{quat:function(a){return this.GLM.vec3(this.GLM.pitch(a),this.GLM.yaw(a),this.GLM.roll(a))}}}),GLM.$template["declare<T,...>"]({$from_glsl:{string:function(a,b){var c;a.replace(/^([$\w]+)\(([-.0-9ef, ]+)\)$/,
+function(a,d,h){a=glm[d]||glm["$"+d];if(!a)throw new GLM.GLMJSError("glsl decoding issue: unknown type '"+d+"'");c=h.split(",").map(parseFloat);if(!b||b===a)c=a.apply(glm,c);else{if(!0===b||b===Array){for(;c.length<a.componentLength;)c.push(c[c.length-1]);return c}throw new GLM.GLMJSError("glsl decoding issue: second argument expected to be undefined|true|Array");}});return c}},$to_glsl:{"vec<N>":function(a,b){var c=GLM.$to_array(a);b&&("object"===typeof b&&"precision"in b)&&(c=c.map(function(a){return a.toFixed(b.precision)}));
+for(;c.length&&c[c.length-2]===c[c.length-1];)c.pop();return a.$type+"("+c+")"},"uvec<N>":function(a,b){return this.vecN(a,b)},"ivec<N>":function(a,b){return this.vecN(a,b)},"bvec<N>":function(a,b){return this.vecN(a,b)},quat:function(a,b){var c;b&&("object"===typeof b&&"precision"in b)&&(c=b.precision);return 0===a.x+a.y+a.z?"quat("+(void 0===c?a.w:a.w.toFixed(c))+")":this.vec4(a,b)},"mat<N>":function(a,b){var c;b&&("object"===typeof b&&"precision"in b)&&(c=b.precision);var e=GLM.$to_array(a);void 0!==
+c&&(e=e.map(function(a){return a.toFixed(c)}));return e.reduce(function(a,b){return a+1*b},0)===e[0]*N?"matN("+e[0]+")":"matN("+e+")"}},frexp:{"float":function(a,b){return 1===arguments.length?this["float,undefined"](a):this["float,array"](a,b)},"vec<N>":function(a,b){if(2>arguments.length)throw new GLM.GLMJSError("frexp(vecN, ivecN) expected ivecN as second parameter");return GLM.vecN(GLM.$to_array(a).map(function(a,e){var d=GLM._frexp(a);b[e]=d[1];return d[0]}))},"float,undefined":function(a){return GLM._frexp(a)},
+"float,array":function(a,b){return GLM._frexp(a,b)}},ldexp:{"float":GLM._ldexp,"vec<N>":function(a,b){return GLM.vecN(GLM.$to_array(a).map(function(a,e){return GLM._ldexp(a,b[e])}))}}}));
+GLM.$template["declare<T,V,...>"]({rotate:{"float,vec3":function(a,b){return this.GLM.$outer.mat4_angleAxis(a,b)},"mat4,float":function(a,b,c){return a.mul(this.GLM.$outer.mat4_angleAxis(b,c))}},scale:{$outer:GLM.$outer,"mat4,vec3":function(a,b){return a.mul(this.$outer.mat4_scale(b))},"vec3,undefined":function(a){return this.$outer.mat4_scale(a)}},translate:{"mat4,vec3":function(a,b){return a.mul(this.GLM.$outer.mat4_translation(b))},"vec3,undefined":function(a){return this.GLM.$outer.mat4_translation(a)}},
+angleAxis:{"float,vec3":function(a,b){return this.GLM.$outer.quat_angleAxis(a,b)}},min:{"float,float":function(a,b){return this.GLM._min(a,b)},"vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return this.GLM._min(a,b)}.bind(this)))}},max:{"float,float":function(a,b){return this.GLM._max(a,b)},"vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return this.GLM._max(a,b)}.bind(this)))}},equal:{"float,float":GLM._equal,
+"vec<N>,vec<N>":function(a,b){for(var c=this["float,float"],e=glm.bvecN(),d=0;d<N;d++)e[d]=c(a[d],b[d]);return e},"bvec<N>,bvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"quat,quat":function(a,b){for(var c=this["float,float"],e=glm.bvec4(),d=0;4>d;d++)e[d]=c(a[d],b[d]);return e}},_slerp:{"quat,quat":function(a,b,c){var e=b,d=glm.dot(glm.vec4(a),glm.vec4(b));0>d&&(e=
+b.mul(-1),d=-d);if(d>1-glm.epsilon())return glm.quat(glm.mix(a.w,e.w,c),glm.mix(a.x,e.x,c),glm.mix(a.y,e.y,c),glm.mix(a.z,e.z,c));b=Math.acos(d);return(a.mul(Math.sin((1-c)*b))+e.mul(Math.sin(c*b)))/Math.sin(b)}},rotation:{"vec3,vec3":function(a,b){var c=this.$dot(a,b),e=new a.constructor(new a.elements.constructor(3));if(c>=1-this.$epsilon)return this.$quat();if(c<-1+this.$epsilon)return e=this.$cross(this.$m[2],a),this.$length2(e)<this.$epsilon&&(e=this.$cross(this.$m[0],a)),e=this.$normalize(e),
+this.$angleAxis(this.$pi,e);var e=this.$cross(a,b),c=this.$sqrt(2*(1+c)),d=1/c;return this.$quat(0.5*c,e.x*d,e.y*d,e.z*d)}},project:{"vec3,mat4":function(a,b,c,e){a=glm.vec4(a,1);a=b["*"](a);a=c["*"](a);a["/="](a.w);a=a["*"](0.5)["+"](0.5);a[0]=a[0]*e[2]+e[0];a[1]=a[1]*e[3]+e[1];return glm.vec3(a)}},unProject:{"vec3,mat4":function(a,b,c,e){b=glm.inverse(c["*"](b));a=glm.vec4(a,1);a.x=(a.x-e[0])/e[2];a.y=(a.y-e[1])/e[3];a=a["*"](2)["-"](glm.vec4(1));e=b["*"](a);e["/="](e.w);return glm.vec3(e)}},orientedAngle:{"vec3,vec3":function(a,
+b,c){var e=Math.acos(glm.clamp(glm.dot(a,b),0,1));return glm.mix(e,-e,0>glm.dot(c,glm.cross(a,b))?1:0)}}});
+GLM.$to_string=GLM.$template["declare<T,...>"]({$to_string:{"function":function(a){return"[function "+(a.name||"anonymous")+"]"},ArrayBuffer:function(a){return"[object ArrayBuffer "+JSON.stringify({byteLength:a.byteLength})+"]"},Float32Array:function(a){return"[object Float32Array "+JSON.stringify({length:a.length,byteOffset:a.byteOffset,byteLength:a.byteLength,BPE:a.BYTES_PER_ELEMENT})+"]"},"float":function(a,b){return GLM.$toFixedString("float",{value:a},["value"],b&&b.precision)},string:function(a){return a},
+bool:function(a){return"bool("+a+")"},"vec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&b.precision)},"uvec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&"object"===typeof b&&b.precision||0)},"ivec<N>":function(a,b){return GLM.$toFixedString(a.$type_name,a,a.$components,b&&"object"===typeof b&&b.precision||0)},"bvec<N>":function(a){return a.$type_name+"("+GLM.$to_array(a).map(Boolean).join(", ")+")"},"mat<N>":function(a,b){var c=[0,1,2,
+3].slice(0,N).map(function(b){return a[b]}).map(function(a){return GLM.$toFixedString("\t",a,a.$components,b&&b.precision)});return a.$type_name+"(\n"+c.join(", \n")+"\n)"},quat:function(a,b){a=GLM.degrees(GLM.eulerAngles(a));return GLM.$toFixedString("<quat>"+a.$type_name,a,["x","y","z"],b&&b.precision)}}}).$to_string;
+GLM.$template["declare<T,V,...>"]({copy:{$op:"=","vec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,array<N>":function(a,b){a.elements.set(b);return a},"vec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"vec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,array<N>":function(a,b){a.elements.set(b);return a},
+"uvec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"uvec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,array<N>":function(a,b){a.elements.set(b);return a},"ivec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"ivec<N>,bvec<N>":function(a,
+b){a.elements.set(b.elements);return a},"bvec<N>,ivec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,array<N>":function(a,b){a.elements.set(b);return a},"bvec<N>,vec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,uvec<N>":function(a,b){a.elements.set(b.elements);return a},"bvec<N>,bvec<N>":function(a,b){a.elements.set(b.elements);return a},"quat,quat":function(a,b){a.elements.set(b.elements);return a},"mat<N>,mat<N>":function(a,b){a.elements.set(b.elements);return a},
+"mat<N>,array<N>":function(a,b){b=b.reduce(function(a,b){if(!a.concat)throw new GLM.GLMJSError("matN,arrayN -- [[.length===4] x 4] expected");return a.concat(b)});if(b===N)throw new GLM.GLMJSError("matN,arrayN -- [[N],[N],[N],[N]] expected");return a["="](b)},"mat<N>,array<N*N>":function(a,b){a.elements.set(b);return a},"mat4,array9":function(a,b){a.elements.set((new GLM.mat4(b)).elements);return a}},sub:{$op:"-",_sub:function(a,b){return this.GLM.$to_array(a).map(function(a,e){return a-b[e]})},"vec<N>,vec<N>":function(a,
+b){return new this.GLM.vecN(this._sub(a,b))},"vec<N>,uvec<N>":function(a,b){return new this.GLM.vecN(this._sub(a,b))},"uvec<N>,uvec<N>":function(a,b){return new this.GLM.uvecN(this._sub(a,b))},"uvec<N>,ivec<N>":function(a,b){return new this.GLM.uvecN(this._sub(a,b))},"vec<N>,ivec<N>":function(a,b){return new this.GLM.vecN(this._sub(a,b))},"ivec<N>,uvec<N>":function(a,b){return new this.GLM.ivecN(this._sub(a,b))},"ivec<N>,ivec<N>":function(a,b){return new this.GLM.ivecN(this._sub(a,b))}},sub_eq:{$op:"-=",
+"vec<N>,vec<N>":function(a,b){for(var c=a.elements,e=b.elements,d=0;d<N;d++)c[d]-=e[d];return a},"vec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"vec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)}},add:{$op:"+",_add:function(a,
+b){return this.GLM.$to_array(a).map(function(a,e){return a+b[e]})},"vec<N>,float":function(a,b){return new this.GLM.vecN(this._add(a,[b,b,b,b]))},"vec<N>,vec<N>":function(a,b){return new this.GLM.vecN(this._add(a,b))},"vec<N>,uvec<N>":function(a,b){return new this.GLM.vecN(this._add(a,b))},"uvec<N>,uvec<N>":function(a,b){return new this.GLM.uvecN(this._add(a,b))},"uvec<N>,ivec<N>":function(a,b){return new this.GLM.uvecN(this._add(a,b))},"vec<N>,ivec<N>":function(a,b){return new this.GLM.vecN(this._add(a,
+b))},"ivec<N>,ivec<N>":function(a,b){return new this.GLM.ivecN(this._add(a,b))},"ivec<N>,uvec<N>":function(a,b){return new this.GLM.ivecN(this._add(a,b))}},add_eq:{$op:"+=","vec<N>,vec<N>":function(a,b){for(var c=a.elements,e=b.elements,d=0;d<N;d++)c[d]+=e[d];return a},"vec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)},"uvec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"vec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,
+b)},"ivec<N>,ivec<N>":function(a,b){return this["vecN,vecN"](a,b)},"ivec<N>,uvec<N>":function(a,b){return this["vecN,vecN"](a,b)}},div:{$op:"/","vec<N>,float":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a){return a/b}))}},div_eq:{$op:"/=","vec<N>,float":function(a,b){for(var c=0;c<N;c++)a.elements[c]/=b;return a}},mul:{$op:"*","vec<N>,vec<N>":function(a,b){return new this.GLM.vecN(this.GLM.$to_array(a).map(function(a,e){return a*b[e]}))}},eql_epsilon:function(a){return{$op:"~=",
+"vec<N>,vec<N>":a,"mat<N>,mat<N>":a,"quat,quat":a,"uvec<N>,uvec<N>":a,"ivec<N>,ivec<N>":a}}(function(a,b){return this.GLM.all(this.GLM.epsilonEqual(a,b,this.GLM.epsilon()))}),eql:function(a){return{$op:"==","mat<N>,mat<N>":function(a,c){return c.elements.length===glm.$to_array(a).filter(function(a,b){return a===c.elements[b]}).length},"vec<N>,vec<N>":a,"quat,quat":a,"uvec<N>,uvec<N>":a,"ivec<N>,ivec<N>":a,"bvec<N>,bvec<N>":a}}(function(a,b){return GLM.all(GLM.equal(a,b))})});
+GLM.string={$type_name:"string",$:{}};GLM.number={$type_name:"float",$:{}};GLM["boolean"]={$type:"bool",$type_name:"bool",$:{}};
+GLM.vec2=GLM.$template.GLMType("vec2",{name:"fvec2",identity:[0,0],components:["xy","01"],undefined0:function(){return this.identity},number1:function(a){return[a,a]},number2:function(a,b){return[a,b]},object1:function(a){if(null!==a)switch(a.length){case 4:case 3:case 2:return[a[0],a[1]];default:if("y"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM.vec2: "+a);return"string"===typeof a.x?[1*a.x,1*a.y]:[a.x,a.y]}}throw new GLM.GLMJSError("unrecognized object passed to GLM.vec2: "+
+a);}});
+GLM.uvec2=GLM.$template.GLMType("uvec2",{name:"uvec2",identity:[0,0],components:["xy","01"],_clamp:function(a){return~~a},undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b]},object1:function(a){switch(a.length){case 4:case 3:case 2:return[a[0],a[1]].map(this._clamp);default:if("y"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM."+this.name+
+": "+a);return[a.x,a.y].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+a);}});
+GLM.vec3=GLM.$template.GLMType("vec3",{name:"fvec3",identity:[0,0,0],components:["xyz","012","rgb"],undefined0:function(){return GLM.vec3.$.identity},number1:function(a){return[a,a,a]},number2:function(a,b){return[a,b,b]},number3:function(a,b,c){return[a,b,c]},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:case 3:return[a[0],a[1],a[2]];case 2:return[a[0],a[1],a[1]];default:if("z"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new this.Error("unrecognized .x-ish object passed to GLM.vec3: "+
+a);return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z]:[a.x,a.y,a.z]}}throw new this.Error("unrecognized object passed to GLM.vec3: "+a);},object2:function(a,b){if(a instanceof GLM.vec2||a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,b];throw new GLM.GLMJSError("unrecognized object passed to GLM.vec3(o,z): "+[a,b]);}});
+GLM.uvec3=GLM.$template.GLMType("uvec3",{name:"uvec3",identity:[0,0,0],components:["xyz","012"],_clamp:GLM.uvec2.$._clamp,undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b,b]},number3:function(a,b,c){a=this._clamp(a);b=this._clamp(b);c=this._clamp(c);return[a,b,c]},object1:function(a){if(a)switch(a.length){case 4:case 3:return[a[0],a[1],a[2]].map(this._clamp);case 2:return[a[0],a[1],a[1]].map(this._clamp);
+default:if("z"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new GLM.GLMJSError("unrecognized .x-ish object passed to GLM."+this.name+": "+a);return[a.x,a.y,a.z].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+a);},object2:function(a,b){if(a instanceof GLM.vec2)return[a.x,a.y,b].map(this._clamp);if(a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,this._clamp(b)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+
+this.name+"(o,z): "+[a,b]);}});
+GLM.vec4=GLM.$template.GLMType("vec4",{name:"fvec4",identity:[0,0,0,0],components:["xyzw","0123","rgba"],undefined0:function(){return this.identity},number1:function(a){return[a,a,a,a]},number2:function(a,b){return[a,b,b,b]},number3:function(a,b,c){return[a,b,c,c]},number4:function(a,b,c,e){return[a,b,c,e]},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:return[a[0],a[1],a[2],a[3]];case 3:return[a[0],a[1],a[2],a[2]];case 2:return[a[0],a[1],a[1],a[1]];default:if("w"in a&&"x"in
+a){if(typeof a.x!==typeof a.w)throw new this.Error("unrecognized .x-ish object passed to GLM.vec4: "+a);return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z,1*a.w]:[a.x,a.y,a.z,a.w]}}throw new this.Error("unrecognized object passed to GLM.vec4: "+[a,a&&a.$type]);},$GLM:GLM,object2:function(a,b){if(a instanceof this.$GLM.vec3||a instanceof this.$GLM.uvec3||a instanceof this.$GLM.ivec3||a instanceof this.$GLM.bvec3)return[a.x,a.y,a.z,b];throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.vec4(o,w): "+
+[a,b]);},object3:function(a,b,c){if(a instanceof this.$GLM.vec2||a instanceof this.$GLM.uvec2||a instanceof this.$GLM.ivec2||a instanceof this.$GLM.bvec2)return[a.x,a.y,b,c];throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.vec4(o,z,w): "+[a,b,c]);}});
+GLM.uvec4=GLM.$template.GLMType("uvec4",{name:"uvec4",identity:[0,0,0,0],components:["xyzw","0123"],_clamp:GLM.uvec2.$._clamp,undefined0:function(){return this.identity},number1:function(a){a=this._clamp(a);return[a,a,a,a]},number2:function(a,b){a=this._clamp(a);b=this._clamp(b);return[a,b,b,b]},number3:function(a,b,c){a=this._clamp(a);b=this._clamp(b);c=this._clamp(c);return[a,b,c,c]},number4:function(a,b,c,e){return[a,b,c,e].map(this._clamp)},Error:GLM.GLMJSError,object1:function(a){if(a)switch(a.length){case 4:return[a[0],
+a[1],a[2],a[3]].map(this._clamp);case 3:return[a[0],a[1],a[2],a[2]].map(this._clamp);case 2:return[a[0],a[1],a[1],a[1]].map(this._clamp);default:if("w"in a&&"x"in a){if(typeof a.x!==typeof a.y)throw new this.Error("unrecognized .x-ish object passed to GLM."+this.name+": "+a);return[a.x,a.y,a.z,a.w].map(this._clamp)}}throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+": "+[a,a&&a.$type]);},object2:function(a,b){if(a instanceof GLM.vec3)return[a.x,a.y,a.z,b].map(this._clamp);if(a instanceof
+GLM.uvec3||a instanceof GLM.ivec3||a instanceof GLM.bvec3)return[a.x,a.y,a.z,this._clamp(b)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+"(o,w): "+[a,b]);},object3:function(a,b,c){if(a instanceof GLM.vec2)return[a.x,a.y,b,c].map(this._clamp);if(a instanceof GLM.uvec2||a instanceof GLM.ivec2||a instanceof GLM.bvec2)return[a.x,a.y,this._clamp(b),this._clamp(c)];throw new GLM.GLMJSError("unrecognized object passed to GLM."+this.name+"(o,z,w): "+[a,b,c]);}});
+GLM.ivec2=GLM.$template.GLMType("ivec2",GLM.$template.extend({},GLM.uvec2.$,{name:"ivec2"}));GLM.ivec3=GLM.$template.GLMType("ivec3",GLM.$template.extend({},GLM.uvec3.$,{name:"ivec3"}));GLM.ivec4=GLM.$template.GLMType("ivec4",GLM.$template.extend({},GLM.uvec4.$,{name:"ivec4"}));GLM.bvec2=GLM.$template.GLMType("bvec2",GLM.$template.extend({},GLM.uvec2.$,{name:"bvec2",boolean1:GLM.uvec2.$.number1,boolean2:GLM.uvec2.$.number2}));
+GLM.bvec3=GLM.$template.GLMType("bvec3",GLM.$template.extend({},GLM.uvec3.$,{name:"bvec3",boolean1:GLM.uvec3.$.number1,boolean2:GLM.uvec3.$.number2,boolean3:GLM.uvec3.$.number3}));GLM.bvec4=GLM.$template.GLMType("bvec4",GLM.$template.extend({},GLM.uvec4.$,{name:"bvec4",boolean1:GLM.uvec4.$.number1,boolean2:GLM.uvec4.$.number2,boolean3:GLM.uvec4.$.number3,boolean4:GLM.uvec4.$.number4}));GLM.bvec2.$._clamp=GLM.bvec3.$._clamp=GLM.bvec4.$._clamp=function(a){return!!a};
+GLM.mat3=GLM.$template.GLMType("mat3",{name:"mat3x3",identity:[1,0,0,0,1,0,0,0,1],undefined0:function(){return this.identity},number1:function(a){return 1===a?this.identity:[a,0,0,0,a,0,0,0,a]},number9:function(a,b,c,e,d,h,j,g,k){return arguments},Error:GLM.GLMJSError,$vec3:GLM.vec3,object1:function(a){if(a){var b=a.elements||a;if(16===b.length)return[b[0],b[1],b[2],b[4],b[5],b[6],b[8],b[9],b[10]];if(9===b.length)return b;if(0 in b&&1 in b&&2 in b&&!(3 in b)&&"object"===typeof b[2])return[b[0],b[1],
+b[2]].map(this.$vec3.$.object1).reduce(function(a,b){return a.concat(b)})}throw new this.Error("unrecognized object passed to GLM.mat3: "+a);},object3:function(a,b,c){return[a,b,c].map(glm.$to_array).reduce(function(a,b){return a.concat(b)})}});
+GLM.mat4=GLM.$template.GLMType("mat4",{name:"mat4x4",identity:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],undefined0:function(){return this.identity},number16:function(a,b,c,e,d,h,j,g,k,i,w,r,m,q,s,t){return arguments},number1:function(a){return 1===a?this.identity:[a,0,0,0,0,a,0,0,0,0,a,0,0,0,0,a]},Error:GLM.GLMJSError,$vec4:GLM.vec4,object1:function(a){var b;if(a){b=a.elements||a;if(9===b.length)return[b[0],b[1],b[2],0,b[3],b[4],b[5],0,b[6],b[7],b[8],0,0,0,0,1];if(4===b.length&&b[0]&&4===b[0].length)return b[0].concat(b[1],
+b[2],b[3]);if(16===b.length)return b;if(0 in b&&1 in b&&2 in b&&3 in b&&!(4 in b)&&"object"===typeof b[3])return[b[0],b[1],b[2],b[3]].map(this.$vec4.$.object1).reduce(function(a,b){return a.concat(b)})}throw new this.Error("unrecognized object passed to GLM.mat4: "+[a,b&&b.length]);},object4:function(a,b,c,e){return[a,b,c,e].map(glm.$to_array).reduce(function(a,b){return a.concat(b)})}});
+GLM.quat=GLM.$template.GLMType("quat",{identity:[0,0,0,1],components:["xyzw","0123"],undefined0:function(){return this.identity},number1:function(a){if(1!==a)throw Error("only quat(1) syntax supported for quat(number1 args)...");return this.identity},number4:function(a,b,c,e){return[b,c,e,a]},$GLM:GLM,$M3:GLM.mat3(),$quat_array_from_zyx:function(a){var b=this.$M3;return this.$GLM.$outer.quat_angleAxis(a.z,b[2]).mul(this.$GLM.$outer.quat_angleAxis(a.y,b[1])).mul(this.$GLM.$outer.quat_angleAxis(a.x,
+b[0])).elements},object1:function(a){if(a){if(a instanceof this.$GLM.mat4)return this.$GLM.$outer.quat_array_from_mat4(a);if(4===a.length)return[a[0],a[1],a[2],a[3]];if(a instanceof this.$GLM.quat)return[a.x,a.y,a.z,a.w];if(a instanceof this.$GLM.vec3)return this.$quat_array_from_zyx(a);if("w"in a&&"x"in a)return"string"===typeof a.x?[1*a.x,1*a.y,1*a.z,1*a.w]:[a.x,a.y,a.z,a.w]}throw new this.$GLM.GLMJSError("unrecognized object passed to GLM.quat.object1: "+[a,a&&a.$type,typeof a,a&&a.constructor]);
+}});
+(function(){var a=function(a,b,c,e){var k={def:function(b,c){this[b]=c;Object.defineProperty(a.prototype,b,c)}};a.$properties=a.$properties||k;var i=a.$properties.def.bind(a.$properties),w=[0,1,2,3].map(function(a){return{enumerable:c,get:function(){return this.elements[a]},set:function(b){this.elements[a]=b}}});b.forEach(function(a,b){i(a,w[b])});if(isNaN(b[0])&&!/^_/.test(b[0])){var k=b.slice(),r=GLM.$subarray;do(function(a,b,c){"quat"===b&&(b="vec"+c);var d=GLM[b];i(a,{enumerable:!1,get:function(){return new d(r(this.elements,0*
+c,1*c))},set:function(a){return(new d(r(this.elements,0*c,1*c)))["="](a)}})})(k.join(""),a.prototype.$type.replace(/[1-9]$/,k.length),k.length);while(k[1]!=k.pop());if(e)return a.$properties;k=b.slice();if(b={xyz:{yz:1},xyzw:{yzw:1,yz:1,zw:2}}[k.join("")])for(var m in b)(function(a,b,c,d){i(a,{enumerable:!1,get:function(){return new GLM[b](GLM.$subarray(this.elements,0*c+d,1*c+d))},set:function(a){return(new GLM[b](GLM.$subarray(this.elements,0*c+d,1*c+d)))["="](a)}})})(m,a.prototype.$type.replace(/[1-9]$/,
+m.length),m.length,b[m])}return a.$properties};a(GLM.vec2,GLM.vec2.$.components[0],!0);a(GLM.vec2,GLM.vec2.$.components[1]);a(GLM.vec3,GLM.vec3.$.components[0],!0);a(GLM.vec3,GLM.vec3.$.components[1]);a(GLM.vec3,GLM.vec3.$.components[2]);a(GLM.vec4,GLM.vec4.$.components[0],!0);a(GLM.vec4,GLM.vec4.$.components[1]);a(GLM.vec4,GLM.vec4.$.components[2]);a(GLM.quat,GLM.quat.$.components[0],!0,"noswizzles");a(GLM.quat,GLM.quat.$.components[1]);GLM.quat.$properties.def("wxyz",{enumerable:!1,get:function(){return new GLM.vec4(this.w,
+this.x,this.y,this.z)},set:function(a){a=GLM.vec4(a);return this["="](GLM.quat(a.x,a.y,a.z,a.w))}});"uvec2 uvec3 uvec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4".split(" ").forEach(function(b){a(GLM[b],GLM[b].$.components[0],!0);a(GLM[b],GLM[b].$.components[1])});Object.defineProperty(GLM.quat.prototype,"_x",{get:function(){throw Error("erroneous quat._x access");}});var b={2:{yx:{enumerable:!1,get:function(){return new GLM.vec2(this.y,this.x)},set:function(a){a=GLM.vec2(a);this.y=a[0];this.x=a[1]}}},3:{xz:{enumerable:!1,
+get:function(){return new GLM.vec2(this.x,this.z)},set:function(a){a=GLM.vec2(a);this.x=a[0];this.z=a[1]}},zx:{enumerable:!1,get:function(){return new GLM.vec2(this.z,this.x)},set:function(a){a=GLM.vec2(a);this.z=a[0];this.x=a[1]}},xzy:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.z,this.y)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.z=a[1];this.y=a[2]}}},4:{xw:{enumerable:!1,get:function(){return new GLM.vec2(this.x,this.w)},set:function(a){a=GLM.vec2(a);this.x=a[0];this.w=a[1]}},
+wz:{enumerable:!1,get:function(){return new GLM.vec2(this.w,this.z)},set:function(a){a=GLM.vec2(a);this.w=a[0];this.z=a[1]}},wxz:{enumerable:!1,get:function(){return new GLM.vec3(this.w,this.x,this.z)},set:function(a){a=GLM.vec3(a);this.w=a[0];this.x=a[1];this.z=a[2];return this}},xyw:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.y,this.w)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.y=a[1];this.w=a[2];return this}},xzw:{enumerable:!1,get:function(){return new GLM.vec3(this.x,this.z,
+this.w)},set:function(a){a=GLM.vec3(a);this.x=a[0];this.z=a[1];this.w=a[2]}},wxyz:{enumerable:!1,get:function(){return new GLM.vec4(this.w,this.x,this.y,this.z)},set:function(a){a=GLM.vec4(a);this.w=a[0];this.x=a[1];this.y=a[2];this.z=a[3];return this}}}},c;for(c in b)for(var e in b[c])2>=c&&GLM.vec2.$properties.def(e,b[c][e]),3>=c&&GLM.vec3.$properties.def(e,b[c][e]),4>=c&&GLM.vec4.$properties.def(e,b[c][e]);GLM.$partition=function(a,b,c,e){if(void 0===c)throw new GLM.GLMJSError("nrows is undefined");
+var k=b.$.identity.length;c=c||k;for(var i=function(a){3<GLM.$DEBUG&&GLM.$outer.console.debug("CACHEDBG: "+a)},w=0;w<c;w++)(function(c){var j=e&&e+c,q=c*k;Object.defineProperty(a,c,{configurable:!0,enumerable:!0,set:function(e){if(e instanceof b)this.elements.set(e.elements,q);else if(e&&e.length===k)this.elements.set(e,q);else throw new GLM.GLMJSError("unsupported argtype to "+(a&&a.$type)+"["+c+"] setter: "+[typeof e,e]);},get:function(){if(e){if(this[j])return c||i("cache hit "+j),this[j];c||i("cache miss "+
+j)}var a,d=new b(a=GLM.$subarray(this.elements,q,q+k));if(d.elements!==a)throw new GLM.GLMJSError("v.elements !== t "+[GLM.$subarray,d.elements.constructor===a.constructor,d.elements.buffer===a.buffer]);e&&Object.defineProperty(this,j,{configurable:!0,enumerable:!1,value:d});return d}})})(w)};GLM.$partition(GLM.mat4.prototype,GLM.vec4,4,"_cache_");GLM.$partition(GLM.mat3.prototype,GLM.vec3,3,"_cache_")})();
+GLM.$dumpTypes=function(a){GLM.$types.forEach(function(b){GLM[b].componentLength&&a("GLM."+b,JSON.stringify({"#type":GLM[b].prototype.$type_name,"#floats":GLM[b].componentLength,"#bytes":GLM[b].BYTES_PER_ELEMENT}))})};
+GLM.$init=function(a){a.prefix&&(GLMJS_PREFIX=a.prefix);GLM.$prefix=GLMJS_PREFIX;var b=a.log||function(){};try{b("GLM-js: ENV: "+_ENV._VERSION)}catch(c){}b("GLM-JS: initializing: "+JSON.stringify(a,0,2));b(JSON.stringify({functions:Object.keys(GLM.$outer.functions)}));var e=GLM.mat4,d=GLM.$outer;GLM.toMat4=function(a){return new e(d.mat4_array_from_quat(a))};GLM.$template.extend(GLM.rotation.$template,{$quat:GLM.quat,$dot:GLM.dot.link("vec3,vec3"),$epsilon:GLM.epsilon(),$m:GLM.mat3(),$pi:GLM.pi(),
+$length2:GLM.length2.link("vec3"),$cross:GLM.cross.link("vec3,vec3"),$normalize:GLM.normalize.link("vec3"),$angleAxis:GLM.angleAxis.link("float,vec3"),$sqrt:GLM.sqrt});GLM.$symbols=[];for(var h in GLM)"function"===typeof GLM[h]&&/^[a-z]/.test(h)&&GLM.$symbols.push(h);GLM.$types.forEach(function(a){var b=GLM[a].prototype.$type,c;for(c in GLM.$outer.functions){var d=GLM.$outer.functions[c];d.$op&&(GLM.$DEBUG&&GLM.$outer.console.debug("mapping operator<"+b+"> "+c+" / "+d.$op),GLM[a].prototype[c]=d,GLM[a].prototype[d.$op]=
+d)}});b("GLM-JS: "+GLM.version+" emulating GLM_VERSION="+GLM.GLM_VERSION+" vendor_name="+a.vendor_name+" vendor_version="+a.vendor_version);glm.vendor=a};
+GLM.using_namespace=function(a){GLM.$DEBUG&&GLM.$outer.console.debug("GLM.using_namespace munges globals; it should probably not be used!");GLM.using_namespace.$tmp={ret:void 0,tpl:a,names:GLM.$symbols,saved:{},evals:[],restore:[],before:[],after:[]};eval(GLM.using_namespace.$tmp.names.map(function(a,c){return"GLM.using_namespace.$tmp.saved['"+a+"'] = GLM.using_namespace.$tmp.before["+c+"] = 'undefined' !== typeof "+a+";"}).join("\n"));GLM.$DEBUG&&console.warn("GLM.using_namespace before #globals: "+
+GLM.using_namespace.$tmp.before.length);GLM.using_namespace.$tmp.names.map(function(a){GLM.using_namespace.$tmp.restore.push(a+"=GLM.using_namespace.$tmp.saved['"+a+"'];"+("GLM.using_namespace.$tmp.saved['"+a+"']=undefined;delete GLM.using_namespace.$tmp.saved['"+a+"'];"));GLM.using_namespace.$tmp.evals.push(a+"=GLM."+a+";")});eval(GLM.using_namespace.$tmp.evals.join("\n"));GLM.using_namespace.$tmp.ret=a();eval(GLM.using_namespace.$tmp.restore.join("\n"));eval(GLM.using_namespace.$tmp.names.map(function(a,
+c){return"GLM.using_namespace.$tmp.after["+c+"] = 'undefined' !== typeof "+a+";"}).join("\n"));GLM.$DEBUG&&console.warn("GLM.using_namespace after #globals: "+GLM.using_namespace.$tmp.after.length);a=GLM.using_namespace.$tmp.ret;delete GLM.using_namespace.$tmp;return a};
+function $GLM_extern(a,b){b=b||a;return function(){GLM[b]=GLM.$outer.functions[a]||GLM.$outer[a];if(!GLM[b])throw new GLM.GLMJSError("$GLM_extern: unresolved external symbol: "+a);GLM.$DEBUG&&GLM.$outer.console.debug("$GLM_extern: resolved external symbol "+a+" "+typeof GLM[b]);return GLM[b].apply(this,arguments)}}
+function GLM_polyfills(){var a={};"bind"in Function.prototype||(a.bind=Function.prototype.bind=function(a){function c(){}if("function"!==typeof this)throw new TypeError("not callable");var e=[].slice,d=e.call(arguments,1),h=this,j=function(){return h.apply(this instanceof c?this:a||global,d.concat(e.call(arguments)))};c.prototype=this.prototype||c.prototype;j.prototype=new c;return j});return a}
+$GLM_reset_logging.current=function(){return{$GLM_log:"undefined"!==typeof $GLM_log&&$GLM_log,$GLM_console_log:"undefined"!==typeof $GLM_console_log&&$GLM_console_log,$GLM_console_prefixed:"undefined"!==typeof $GLM_console_prefixed&&$GLM_console_prefixed,console:GLM.$outer.console}};
+function $GLM_reset_logging(a){a&&"object"===typeof a&&($GLM_log=a.$GLM_log,$GLM_console_log=a.$GLM_console_log,$GLM_console_factory=a.$GLM_console_factory,GLM.$outer.console=a.console,a=!1);if(a||"undefined"===typeof $GLM_log)$GLM_log=function(a,b){GLM.$outer.console.log.apply(GLM.$outer.console,[].slice.call(arguments).map(function(a){var b=typeof a;return"xboolean"===b||"string"===b?a+"":GLM.$isGLMObject(a)||!isNaN(a)?GLM.to_string(a):a+""}))};if(a||"undefined"===typeof $GLM_console_log)$GLM_console_log=
+function(a,b){(console[a]||function(){}).apply(console,[].slice.call(arguments,1))};if(a||"undefined"===typeof $GLM_console_factory)$GLM_console_factory=function(a){return $GLM_console_log.bind($GLM_console_log,a)};var b=$GLM_console_factory,c={};"debug,warn,info,error,log,write".replace(/\w+/g,function(a){c[a]=b(a)});"object"===typeof GLM&&(GLM.$outer&&(GLM.$outer.console=c),GLM.$log=$GLM_log);return c}try{window.$GLM_reset_logging=this.$GLM_reset_logging=$GLM_reset_logging}catch(e$$19){}
+GLM.$reset_logging=$GLM_reset_logging;GLM.$log=GLM.$log||$GLM_log;function $GLM_GLMJSError(a,b){function c(c){this.name=a;this.stack=Error().stack;Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor);this.message=c;b&&b.apply(this,arguments)}c.prototype=Error();c.prototype.name=a;return c.prototype.constructor=c}GLMAT.mat4.exists;glm=GLM;var DLL={_version:"0.0.2",_name:"glm.gl-matrix.js",_glm_version:glm.version,prefix:"glm-js[glMatrix]: ",vendor_version:GLMAT.VERSION,vendor_name:"glMatrix"};
+DLL.statics={$outer:GLM.$outer,$typeArray:function(a){return new this.$outer.Float32Array(a)},$mat4:GLM.mat4,$quat:GLM.quat,$mat4$perspective:GLMAT.mat4.perspective,$mat4$ortho:GLMAT.mat4.ortho,mat4_perspective:function(a,b,c,e){return new this.$mat4(this.$mat4$perspective(this.$typeArray(16),a,b,c,e))},mat4_ortho:function(a,b,c,e,d,h){return new this.$mat4(this.$mat4$ortho(this.$typeArray(16),a,b,c,e,d||-1,h||1))},$quat$setAxisAngle:GLMAT.quat.setAxisAngle,$mat4$fromQuat:GLMAT.mat4.fromQuat,mat4_angleAxis:function(a,
+b){var c=this.$quat$setAxisAngle(this.$typeArray(4),b,a);return new this.$mat4(this.$mat4$fromQuat(this.$typeArray(16),c))},quat_angleAxis:function(a,b){return new this.$quat(this.$quat$setAxisAngle(this.$typeArray(4),b,a))},$mat4$translate:GLMAT.mat4.translate,mat4_translation:function(a){var b=new this.$mat4;this.$mat4$translate(b.elements,b.elements,a.elements);return b},$mat4$scale:GLMAT.mat4.scale,mat4_scale:function(a){var b=new this.$mat4;this.$mat4$scale(b.elements,b.elements,a.elements);
+return b},toJSON:function(){var a={},b;for(b in this)0!==b.indexOf("$")&&(a[b]=this[b]);return a},$vec3:GLM.vec3,$clamp:GLM.clamp,mat4_array_from_quat:function(a){return this.$mat4$fromQuat(this.$typeArray(16),a.elements)},$qtmp:new GLM.$outer.Float32Array(9),$quat$fromMat3:GLMAT.quat.fromMat3,$mat3$fromMat4:GLMAT.mat3.fromMat4,quat_array_from_mat4:function(a){return this.$quat$fromMat3(this.$typeArray(4),this.$mat3$fromMat4(this.$qtmp,a.elements))}};
+DLL["declare<T,V,...>"]={mul:{$op:"*",$typeArray:function(a){return new this.GLM.$outer.Float32Array(a)},$vec3$transformQuat:GLMAT.vec3.transformQuat,"quat,vec3":function(a,b){return new this.GLM.vec3(this.$vec3$transformQuat(this.$typeArray(3),b.elements,a.elements))},"vec3,quat":function(a,b){return this["quat,vec3"](this.GLM.inverse(b),a)},"quat,vec4":function(a,b){return this["mat4,vec4"](this.GLM.toMat4(a),b)},"vec4,quat":function(a,b){return this["quat,vec4"](this.GLM.inverse(b),a)},"$vec<N>$scale":"GLMAT.vecN.scale",
+"vec<N>,float":function(a,b){return new this.GLM.vecN(this.$vecN$scale(this.$typeArray(N),a.elements,b))},"quat,float":function(a,b){return new a.constructor(this["vec4,float"](a,b).elements)},$vec4$transformMat4:GLMAT.vec4.transformMat4,"mat4,vec4":function(a,b){return new GLM.vec4(this.$vec4$transformMat4(this.$typeArray(4),b.elements,a.elements))},"vec4,mat4":function(a,b){return this["mat4,vec4"](GLM.inverse(b),a)},"$mat<N>mul":"GLMAT.matN.mul","mat<N>,mat<N>":function(a,b){return new a.constructor(this.$matNmul(this.$typeArray(N*
+N),a.elements,b.elements))},$quat$multiply:GLMAT.quat.multiply,"quat,quat":function(a,b){return new a.constructor(this.$quat$multiply(this.$typeArray(4),a.elements,b.elements))}},mul_eq:{$op:"*=","$mat<N>$multiply":"GLMAT.matN.multiply","mat<N>,mat<N>":function(a,b){this.$matN$multiply(a.elements,a.elements,b.elements);return a},"$vec<N>$scale":"GLMAT.vecN.scale","vec<N>,float":function(a,b){this.$vecN$scale(a.elements,a.elements,b);return a},$quat$multiply:GLMAT.quat.multiply,"quat,quat":function(a,
+b){this.$quat$multiply(a.elements,a.elements,b.elements);return a},$quat$invert:GLMAT.quat.invert,$vec3$transformQuat:GLMAT.vec3.transformQuat,"inplace:vec3,quat":function(a,b){var c=this.$quat$invert(new this.GLM.$outer.Float32Array(4),b.elements);this.$vec3$transformQuat(a.elements,a.elements,c);return a},$mat4$invert:GLMAT.mat4.invert,$vec4$transformMat4:GLMAT.vec4.transformMat4,"inplace:vec4,mat4":function(a,b){var c=this.$mat4$invert(new this.GLM.$outer.Float32Array(16),b.elements);this.$vec4$transformMat4(a.elements,
+a.elements,c);return a}},cross:{$vec2$cross:GLMAT.vec2.cross,"vec2,vec2":function(a,b){return new this.GLM.vec3(this.$vec2$cross(new this.GLM.$outer.Float32Array(3),a,b))},$vec3$cross:GLMAT.vec3.cross,"vec3,vec3":function(a,b){return new this.GLM.vec3(this.$vec3$cross(new this.GLM.$outer.Float32Array(3),a,b))}},dot:{"$vec<N>$dot":"GLMAT.vecN.dot","vec<N>,vec<N>":function(a,b){return this.$vecN$dot(a,b)}},lookAt:{$mat4$lookAt:GLMAT.mat4.lookAt,"vec3,vec3":function(a,b,c){return new this.GLM.mat4(this.$mat4$lookAt(new this.GLM.$outer.Float32Array(16),
+a.elements,b.elements,c.elements))}}};DLL["declare<T,V,number>"]={mix:{$quat$slerp:GLMAT.quat.slerp,"quat,quat":function(a,b,c){return new GLM.quat(this.$quat$slerp(new GLM.$outer.Float32Array(4),a.elements,b.elements,c))}}};DLL["declare<T,V,number>"].slerp=DLL["declare<T,V,number>"].mix;
+DLL["declare<T>"]={normalize:{"$vec<N>normalize":"GLMAT.vecN.normalize",$typeArray:function(a){return new this.GLM.$outer.Float32Array(a)},"vec<N>":function(a){return new this.GLM.vecN(this.$vecNnormalize(this.$typeArray(N),a))},$quat$normalize:GLMAT.quat.normalize,quat:function(a){return new this.GLM.quat(this.$quat$normalize(new this.GLM.$outer.Float32Array(4),a.elements))}},length:{$quat$length:GLMAT.quat.length,quat:function(a){return this.$quat$length(a.elements)},"$vec<N>$length":"GLMAT.vecN.length",
+"vec<N>":function(a){return this.$vecN$length(a.elements)}},length2:{$quat$squaredLength:GLMAT.quat.squaredLength,quat:function(a){return this.$quat$squaredLength(a.elements)},"$vec<N>$squaredLength":"GLMAT.vecN.squaredLength","vec<N>":function(a){return this.$vecN$squaredLength(a.elements)}},inverse:{$quatinvert:GLMAT.quat.invert,quat:function(a){return this.GLM.quat(this.$quatinvert(new this.GLM.$outer.Float32Array(4),a.elements))},$mat4invert:GLMAT.mat4.invert,mat4:function(a){a=a.clone();return null===
+this.$mat4invert(a.elements,a.elements)?a["="](this.GLM.mat4()):a}},transpose:{$mat4$transpose:GLMAT.mat4.transpose,mat4:function(a){a=a.clone();this.$mat4$transpose(a.elements,a.elements);return a}}};glm.$outer.$import(DLL);try{module.exports=glm}catch(e$$20){}
+function $GLMVector(a,b,c){this.typearray=c=c||GLM.$outer.Float32Array;if(!(this instanceof $GLMVector))throw new GLM.GLMJSError("use new");if("function"!==typeof a||!GLM.$isGLMConstructor(a))throw new GLM.GLMJSError("expecting typ to be GLM.$isGLMConstructor: "+[typeof a,a?a.$type:a]+" // "+GLM.$isGLMConstructor(a));if(1===a.componentLength&&GLM[a.prototype.$type.replace("$","$$v")])throw new GLM.GLMJSError("unsupported argtype to glm.$vectorType - for single-value types use glm."+a.prototype.$type.replace("$",
+"$$v")+"..."+a.prototype.$type);this.glmtype=a;if(!this.glmtype.componentLength)throw Error("need .componentLength "+[a,b,c]);this.componentLength=this.glmtype.componentLength;this.BYTES_PER_ELEMENT=this.glmtype.BYTES_PER_ELEMENT;this._set_$elements=function(a){Object.defineProperty(this,"$elements",{enumerable:!1,configurable:!0,value:a});return this.$elements};Object.defineProperty(this,"elements",{enumerable:!0,configurable:!0,get:function(){return this.$elements},set:function(a){this._kv&&!this._kv.dynamic&&
+GLM.$DEBUG&&GLM.$outer.console.warn("WARNING: setting .elements on frozen (non-dynamic) GLMVector...");if(a){var b=this.length;this.length=a.length/this.componentLength;this.byteLength=a.length*this.BYTES_PER_ELEMENT;if(this.length!==Math.round(this.length))throw new GLM.GLMJSError("$vectorType.length alignment mismatch "+JSON.stringify({componentLength:this.componentLength,length:this.length,rounded_length:Math.round(this.length),elements_length:a.length,old_length:b}));}else this.length=this.byteLength=
+0;return this._set_$elements(a)}});this.elements=b&&new c(b*a.componentLength)}GLM.$vectorType=$GLMVector;GLM.$vectorType.version="0.0.2";
+$GLMVector.prototype=GLM.$template.extend(new GLM.$GLMBaseType($GLMVector,"$vectorType"),{toString:function(){return"[$GLMVector .elements=#"+(this.elements&&this.elements.length)+" .elements[0]="+(this.elements&&this.elements[0])+" ->[0]"+(this["->"]&&this["->"][0])+"]"},"=":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return this._set(new this.typearray(a))},_typed_concat:function(a,b,c){var e=a.length+b.length;c=c||new a.constructor(e);c.set(a);c.set(b,a.length);
+return c},"+":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return new this.constructor(this._typed_concat(this.elements,a))},"+=":function(a){if(a instanceof this.constructor||glm.$isGLMObject(a))a=a.elements;return this._set(this._typed_concat(this.elements,a))},_set:function(a){a instanceof this.constructor&&(a=new this.typearray(a.elements));if(!(a instanceof this.typearray))throw new GLM.GLMJSError("unsupported argtype to $GLMVector._set "+(a&&a.constructor));
+GLM.$DEBUG&&GLM.$outer.console.debug("$GLMVector.prototype.set...this.elements:"+[this.elements&&this.elements.constructor.name,this.elements&&this.elements.length]+"elements:"+[a.constructor.name,a.length]);var b=this._kv;this._kv=void 0;this.elements=a;if(this.elements!==a)throw new GLM.GLMJSError("err with .elements: "+[this.glmtype.prototype.$type,this.elements,a]);b&&this._setup(b);return this},arrayize:function(a,b){return this._setup({dynamic:b,setters:a},this.length)},$destroy:function(a){if(a){for(var b=
+Array.isArray(a),c=function(c){Object.defineProperty(a,c,{enumerable:!0,configurable:!0,value:void 0});delete a[c];b||(a[c]=void 0,delete a[c])},e=0;e<a.length;e++)e in a&&c(e);for(;e in a;)GLM.$DEBUG&&GLM.$outer.console.debug("$destroy",this.name,e),c(e++);b&&(a.length=0)}},_arrlike_toJSON:function(){return this.slice(0)},_mixinArray:function(a){a.toJSON=this._arrlike_toJSON;"forEach map slice filter join reduce".split(" ").forEach(function(b){a[b]=Array.prototype[b]});return a},_setup:function(a,
+b){var c=this.glmtype,e=this.typearray,d=this.length;this._kv=a;var h=a.stride||this.glmtype.BYTES_PER_ELEMENT,j=a.offset||this.elements.byteOffset,g=a.elements||this.elements,k=a.container||this.arr||[],i=a.setters||!1,w=a.dynamic||!1;"self"===k&&(k=this);if(!g)throw new GLMJSError("GLMVector._setup - neither kv.elements nor this.elements...");this.$destroy(this.arr,b);var r=this.arr=this["->"]=k;Array.isArray(r)||this._mixinArray(r);var m=this.componentLength;if(!m)throw new GLM.GLMJSError("no componentLength!?"+
+Object.keys(this));for(var q=g.buffer.byteLength,s=this,t=0;t<d;t++){var k=j+t*h,z=k+this.glmtype.BYTES_PER_ELEMENT,y=function(){a.i=t;a.next=z;a.last=q;a.offset=a.offset||j;a.stride=a.stride||h;return JSON.stringify(a)};if(k>q)throw Error("["+t+"] off "+k+" > last "+q+" "+y());if(z>q)throw Error("["+t+"] next "+z+" > last "+q+" "+y());r[t]=null;var f=function(a,b){var d=new c(new e(a.buffer,b,m));w&&Object.defineProperty(d,"$elements",{value:a});return d},y=f(g,k);!i&&!w?r[t]=y:function(a,b,c){Object.defineProperty(r,
+b,{enumerable:!0,configurable:!0,get:w?function(){a.$elements!==s.elements&&(GLM.$log("dynoget rebinding ti",b,c,a.$elements===s.elements),a=f(s.elements,c));return a}:function(){return a},set:i&&(w?function(d){GLM.$log("dynoset",b,c,a.$elements===s.elements);a.$elements!==s.elements&&(GLM.$log("dynoset rebinding ti",b,c,a.$elements===s.elements),a=f(s.elements,c));return a.copy(d)}:function(b){return a.copy(b)})||void 0})}(y,t,k)}return this},setFromBuffers:function(a){var b=this.elements,c=0;a.forEach(function(a){var d=
+a.length;if(c+d>b.length){d=Math.min(b.length-c,a.length);if(0>=d)return;a=glm.$subarray(a,0,d);d=a.length}if(c+d>b.length)throw new glm.GLMJSError("$vectorType.fromBuffers mismatch "+[c,d,b.length]);b.set(a,c);c+=a.length});return c},setFromPointer:function(a){if(!(a instanceof GLM.$outer.ArrayBuffer))throw new glm.GLMJSError("unsupported argtype "+[typeof a]+" - $GLMVector.setFromPointer");return this._set(new this.typearray(a))}});GLM.exists;GLM.$vectorType.exists;
+if(GLM.$toTypedArray)throw"error: glm.experimental.js double-included";
+GLM.$toTypedArray=function(a,b,c){var e=b||0,d=typeof e;if("number"===d){if("number"!==typeof c)throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported argtype for componentLength ("+typeof c+")");return new a(e*c)}if("object"!==d)throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported arrayType: "+[typeof a,a]);if(e instanceof a)return e;if(e instanceof GLM.$outer.ArrayBuffer||Array.isArray(e))return new a(e);GLM.$isGLMObject(e)&&(d=e.elements,e=new a(d.length),e.set(d));if(!(e instanceof a)&&
+"byteOffset"in e&&"buffer"in e)return GLM.$DEBUG&&GLM.$outer.console.warn("coercing "+e.constructor.name+".buffer into "+[a.name,e.byteOffset,e.byteLength+" bytes","~"+e.byteLength/a.BYTES_PER_ELEMENT+" coerced elements"]+"...",{byteOffset:e.byteOffset,byteLength:e.byteLength,ecount:e.byteLength/a.BYTES_PER_ELEMENT}),new a(e.buffer,e.byteOffset,e.byteLength/a.BYTES_PER_ELEMENT);if(e instanceof a)return e;throw new GLM.GLMJSError("GLM.$toTypedArray: unsupported argtype initializers: "+[a,b,c]);};
+GLM.$make_primitive=function(a,b){GLM[a]=function(c){if(!(this instanceof GLM[a]))return new GLM[a](c);"object"!==typeof c&&(c=[c]);this.elements=GLM.$toTypedArray(b,c,1)};GLM[a]=eval(GLM.$template._traceable("glm_"+a+"$class",GLM[a]))();GLM.$template._add_overrides(a,{$to_string:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"},$to_object:function(a){return a.elements[0]},$to_glsl:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"}});GLM.$template._add_overrides(a.substr(1),
+{$to_string:!(a.substr(1)in GLM.$to_string.$template)&&function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a.elements[0]+")"},$to_object:function(a){return a},$to_glsl:function(a){return a.$type.replace(/[^a-z]/g,"")+"("+a+")"}});GLM.$template.extend(GLM[a],{componentLength:1,BYTES_PER_ELEMENT:b.BYTES_PER_ELEMENT,prototype:GLM.$template.extend(new GLM.$GLMBaseType(GLM[a],a),{copy:function(a){this.elements.set(GLM.$isGLMObject(a)?a.elements:[a]);return this},valueOf:function(){return this.elements[0]}})});
+GLM[a].prototype["="]=GLM[a].prototype.copy;return GLM[a]};GLM.$make_primitive("$bool",GLM.$outer.Int32Array);GLM.$template._add_overrides("$bool",{$to_object:function(a){return!!a}});GLM.$make_primitive("$int32",GLM.$outer.Int32Array);GLM.$make_primitive("$uint32",GLM.$outer.Uint32Array);GLM.$make_primitive("$uint16",GLM.$outer.Uint16Array);GLM.$make_primitive("$uint8",GLM.$outer.Uint8Array);GLM.$float32=GLM.$make_primitive("$float",GLM.$outer.Float32Array);
+GLM.$make_primitive_vector=function(a,b,c){c=c||(new b).elements.constructor;var e=function(d){if(!(this instanceof e))return new e(d);this.$type=a;this.$type_name="vector<"+a+">";(d=GLM.$toTypedArray(c,d,b.componentLength))&&this._set(d)},e=eval(GLM.$template._traceable("glm_"+a+"$class",e))();e.prototype=new GLM.$vectorType(b,0,c);GLM.$template._add_overrides(a,{$to_string:function(a){return"[GLM."+a.$type+" elements[0]="+(a.elements&&a.elements[0])+"]"},$to_object:function(a){return a.map(GLM.$to_object)},
+$to_glsl:function(a,b){var c=a.$type.substr(2).replace(/[^a-z]/g,"");b="string"===typeof b?b:"example";var e=[];b&&e.push(c+" "+b+"["+a.length+"]");return e.concat(a.map(function(a,c){return b+"["+c+"] = "+a})).join(";")+";"}});GLM.$types.push(a);GLM.$template.extend(e.prototype,{$type:a,constructor:e,_setup:function(){throw new GLM.GLMJSError("._setup not available on primitive vectors yet...");},_set:function(a){this.elements=a;this.length=!this.elements?0:this.elements.length/this.glmtype.componentLength;
+this.arrayize();return this},arrayize:function(){for(var a=Object.defineProperty.bind(Object,this),b=0;b<this.length;b++)(function(b){a(b,{configurable:!0,enumerable:!0,get:function(){return this.elements[b]},set:function(a){return this.elements[b]=a}})})(b);return this._mixinArray(this)},toString:function(){return"[vector<"+a+"> {"+[].slice.call(this.elements,0,5)+(5<this.elements.length?",...":"")+"}]"}});return e};GLM.$vint32=GLM.$make_primitive_vector("$vint32",GLM.$int32);
+GLM.$vfloat=GLM.$vfloat32=GLM.$make_primitive_vector("$vfloat32",GLM.$float32);GLM.$vuint8=GLM.$make_primitive_vector("$vuint8",GLM.$uint8);GLM.$vuint16=GLM.$make_primitive_vector("$vuint16",GLM.$uint16);GLM.$vuint32=GLM.$make_primitive_vector("$vuint32",GLM.$uint32);
+GLM.$make_componentized_vector=function(a,b,c){c=c||(new b).elements.constructor;var e=function(a,h){if(!(this instanceof e))return new e(a,h);this._set(GLM.$toTypedArray(c,a,b.componentLength));if(!this.elements)throw new GLM.GLMJSError("!this.elements: "+[GLM.$toTypedArray(c,a,b.componentLength)]);this._setup({setters:!0,dynamic:h,container:"self"})},e=eval(GLM.$template._traceable("glm_"+a+"$class",e))();e.prototype=new GLM.$vectorType(b,0,c);GLM.$template._add_overrides(a,{$to_string:function(a){return"[GLM."+
+a.$type+" elements[0]="+(a.elements&&a.elements[0])+"]"},$to_object:function(a){return a.map(GLM.$to_object)},$to_glsl:function(a,b){var c=a.$type.substr(2);b="string"===typeof b?b:"example";var e=[];b&&e.push(c+" "+b+"["+a.length+"]");return e.concat(a.map(GLM.$to_glsl).map(function(a,c){return b+"["+c+"] = "+a})).join(";\n ")+";"}});GLM.$types.push(a);GLM.$template.extend(e.prototype,{$type:a,constructor:e});e.prototype.componentLength||alert("!cmop "+p);return e};
+(function(){var a=GLM.$template.deNify({"$vvec<N>":function(){return GLM.$make_componentized_vector("$vvecN",GLM.vecN)},"$vuvec<N>":function(){return GLM.$make_componentized_vector("$vuvecN",GLM.uvecN)},"$vmat<N>":function(){return GLM.$make_componentized_vector("$vmatN",GLM.matN)},$vquat:function(){return GLM.$make_componentized_vector("$vquat",GLM.quat)}},"$v"),b;for(b in a)GLM[b]=a[b]()})();
+(GLM._redefine_base64_helpers=function define_base64_helpers(b,c){function e(b){return(b+"").replace(/\s/g,"")}function d(b){return new k(b.split("").map(function(b){return b.charCodeAt(0)}))}function h(b){b instanceof k||(b=new k(b));return[].map.call(b,function(b){return String.fromCharCode(b)}).join("")}function j(b){b=b instanceof i?b:d(b).buffer;return GLM.$b64.encode(b,b.byteOffset,b.byteLength)}function g(b){b=new String(h(GLM.$b64.decode(b)));b.array=d(b);b.buffer=b.array.buffer;return b}
+b=define_base64_helpers.atob=b||define_base64_helpers.atob||g;c=define_base64_helpers.btoa=c||define_base64_helpers.btoa||j;var k=GLM.$outer.Uint8Array,i=GLM.$outer.ArrayBuffer,w,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf.bind("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");w={encode:function(b,c,d){b=new k(b,c,d);d=b.length;var e="";for(c=0;c<d;c+=3)e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b[c]>>2],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(b[c]&
+3)<<4|b[c+1]>>4],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(b[c+1]&15)<<2|b[c+2]>>6],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b[c+2]&63];2===d%3?e=e.substring(0,e.length-1)+"=":1===d%3&&(e=e.substring(0,e.length-2)+"==");return e},decode:function(b){b=e(b);var c=b.length,d=0.75*c,g=0,h,j,f,v;"="===b[c-1]&&(d--,"="===b[c-2]&&d--);for(var w=new i(d),R=new k(w),d=0;d<c;d+=4)h=r(b[d]),j=r(b[d+1]),f=r(b[d+2]),v=r(b[d+3]),R[g++]=h<<2|j>>4,R[g++]=
+(j&15)<<4|f>>2,R[g++]=(f&3)<<6|v&63;return w}};GLM.$template.extend(w,{trim:e,atob:b,btoa:c,$atob:g,$btoa:j,toCharCodes:d,fromCharCodes:h,b64_to_utf8:function(c){return decodeURIComponent(escape(b(e(c))))},utf8_to_b64:function(b){return c(unescape(encodeURIComponent(b)))}});GLM.$template.extend(GLM,{$b64:w,$to_base64:function(b){return GLM.$b64.encode(b.elements.buffer,b.elements.byteOffset,b.elements.byteLength)},$from_base64:function(b,c){var d=GLM.$b64.decode(b);if(!0===c||c==GLM.$outer.ArrayBuffer)return d;
+void 0===c&&(c=GLM.$outer.Float32Array);return new c(d);throw new GLM.GLMJSError("TODO: $from_base64 not yet supported second argument type: ("+[typeof c,c]+")");}})})("function"===typeof atob&&atob.bind(this),"function"===typeof btoa&&btoa.bind(this));
+(function(){function a(a,c){return{get:function(){return a.call(this)},set:function(a){if(this.copy)return this.copy(new this.constructor(c.call(this,a)));this.elements.set(c.call(this,a))}}}"$bool $float32 $vfloat32 $vuint8 $vuint16 $vuint32 $vvec2 $vvec3 $vvec4 $vmat3 $vmat4 $vquat vec2 vec3 vec4 mat3 mat4 uvec2 uvec3 uvec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 quat".split(" ").map(GLM.$getGLMType).forEach(function(b){Object.defineProperty(b.prototype,"array",a(function(){return GLM.$to_array(this)},
+function(a){return a}));Object.defineProperty(b.prototype,"base64",a(function(){return GLM.$to_base64(this)},function(a){return GLM.$from_base64(a,this.elements.constructor)}));Object.defineProperty(b.prototype,"buffer",a(function(){return this.elements.buffer},function(a){return new this.elements.constructor(a)}));Object.defineProperty(b.prototype,"json",a(function(){return GLM.$to_json(this)},function(a){return JSON.parse(a)}));Object.defineProperty(b.prototype,"object",a(function(){return GLM.$to_object(this)},
+function(a){return a}));Object.defineProperty(b.prototype,"glsl",a(function(){return GLM.$to_glsl(this)},function(a){return GLM.$from_glsl(a,Array)}))})})();
+glm.GLMAT = GLMAT; globals.glm = glm; try { module.exports = glm; } catch(e) { }; try { window.glm = glm; } catch(e) {} ; try { declare.amd && declare(function() { return glm; }); } catch(e) {}; return this.glm = glm; })(this, typeof $GLM_log !== "undefined" ? $GLM_log : undefined, typeof $GLM_console_log !== "undefined" ? $GLM_console_log : undefined);
diff --git a/graphics/asymptote/xstream.h b/graphics/asymptote/xstream.h
new file mode 100644
index 0000000000..1d7f6e1cd1
--- /dev/null
+++ b/graphics/asymptote/xstream.h
@@ -0,0 +1,260 @@
+/* C++ interface to the XDR External Data Representation I/O routines
+ Version 1.46
+ Copyright (C) 1999-2007 John C. Bowman
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __xstream_h__
+#define __xstream_h__ 1
+
+#ifndef _ALL_SOURCE
+#define _ALL_SOURCE 1
+#endif
+
+#include <cstdio>
+
+#include <sys/types.h>
+#include <rpc/types.h>
+
+#define quad_t long long
+#define u_quad_t unsigned long long
+
+#if defined(__CYGWIN__) || defined(__FreeBSD__)
+#include <sys/select.h>
+#define u_char unsigned char
+#define u_int unsigned int
+#define u_short unsigned short
+#define u_long unsigned long
+extern "C" int fseeko(FILE *, off_t, int);
+extern "C" off_t ftello(FILE *);
+#endif
+
+#ifdef _POSIX_SOURCE
+#undef _POSIX_SOURCE
+#include <rpc/rpc.h>
+#define _POSIX_SOURCE
+#else
+#include <rpc/rpc.h>
+#endif
+
+namespace xdr {
+
+class xbyte {
+ unsigned char c;
+public:
+ xbyte() {}
+ xbyte(unsigned char c0) : c(c0) {}
+ xbyte(int c0) : c((unsigned char) c0) {}
+ xbyte(unsigned int c0) : c((unsigned char) c0) {}
+ int byte() const {return c;}
+ operator unsigned char () const {return c;}
+};
+
+class xios {
+public:
+ enum io_state {goodbit=0, eofbit=1, failbit=2, badbit=4};
+ enum open_mode {in=1, out=2, app=8, trunc=16};
+ enum seekdir {beg=SEEK_SET, cur=SEEK_CUR, end=SEEK_END};
+private:
+ int _state;
+public:
+ int good() const { return _state == 0; }
+ int eof() const { return _state & eofbit; }
+ int fail() const { return !good();}
+ int bad() const { return _state & badbit; }
+ void clear(int state = 0) {_state=state;}
+ void set(int flag) {_state |= flag;}
+ operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
+ int operator!() const { return fail(); }
+};
+
+class xstream : public xios {
+protected:
+ FILE *buf;
+public:
+ virtual ~xstream() {}
+ xstream() {buf=NULL;}
+
+ void precision(int) {}
+
+ xstream& seek(off_t pos, seekdir dir=beg) {
+ if(buf) {
+ clear();
+ if(fseeko(buf,pos,dir) != 0) set(failbit);
+ }
+ return *this;
+ }
+ off_t tell() {
+ return ftello(buf);
+ }
+};
+
+#define IXSTREAM(T,N) ixstream& operator >> (T& x) \
+ {if(!xdr_##N(&xdri, &x)) set(eofbit); return *this;}
+
+#define OXSTREAM(T,N) oxstream& operator << (T x) \
+ {if(!xdr_##N(&xdro, &x)) set(badbit); return *this;}
+
+class ixstream : virtual public xstream {
+protected:
+ XDR xdri;
+public:
+ void open(const char *filename, open_mode=in) {
+ clear();
+ buf=fopen(filename,"r");
+ if(buf) xdrstdio_create(&xdri,buf,XDR_DECODE);
+ else set(badbit);
+ }
+
+ void close() {
+ if(buf) {
+#ifndef _CRAY
+ xdr_destroy(&xdri);
+#endif
+ fclose(buf);
+ buf=NULL;
+ }
+ }
+
+ ixstream() {}
+ ixstream(const char *filename) {open(filename);}
+ ixstream(const char *filename, open_mode mode) {open(filename,mode);}
+ virtual ~ixstream() {close();}
+
+ typedef ixstream& (*imanip)(ixstream&);
+ ixstream& operator >> (imanip func) { return (*func)(*this); }
+
+ IXSTREAM(int,int);
+ IXSTREAM(unsigned int,u_int);
+ IXSTREAM(long,long);
+ IXSTREAM(unsigned long,u_long);
+ IXSTREAM(long long,longlong_t);
+ IXSTREAM(unsigned long long,u_longlong_t);
+ IXSTREAM(short,short);
+ IXSTREAM(unsigned short,u_short);
+ IXSTREAM(char,char);
+#ifndef _CRAY
+ IXSTREAM(unsigned char,u_char);
+#endif
+ IXSTREAM(float,float);
+ IXSTREAM(double,double);
+
+ ixstream& operator >> (xbyte& x) {
+ x=fgetc(buf);
+ if(x.byte() == EOF) set(eofbit);
+ return *this;
+ }
+};
+
+class oxstream : virtual public xstream {
+protected:
+ XDR xdro;
+public:
+ void open(const char *filename, open_mode mode=trunc) {
+ clear();
+ buf=fopen(filename,(mode & app) ? "a" : "w");
+ if(buf) xdrstdio_create(&xdro,buf,XDR_ENCODE);
+ else set(badbit);
+ }
+
+ void close() {
+ if(buf) {
+#ifndef _CRAY
+ xdr_destroy(&xdro);
+#endif
+ fclose(buf);
+ buf=NULL;
+ }
+ }
+
+ oxstream() {}
+ oxstream(const char *filename) {open(filename);}
+ oxstream(const char *filename, open_mode mode) {open(filename,mode);}
+ virtual ~oxstream() {close();}
+
+ oxstream& flush() {if(buf) fflush(buf); return *this;}
+
+ typedef oxstream& (*omanip)(oxstream&);
+ oxstream& operator << (omanip func) { return (*func)(*this); }
+
+ OXSTREAM(int,int);
+ OXSTREAM(unsigned int,u_int);
+ OXSTREAM(long,long);
+ OXSTREAM(unsigned long,u_long);
+ OXSTREAM(long long,longlong_t);
+ OXSTREAM(unsigned long long,u_longlong_t);
+ OXSTREAM(short,short);
+ OXSTREAM(unsigned short,u_short);
+ OXSTREAM(char,char);
+#ifndef _CRAY
+ OXSTREAM(unsigned char,u_char);
+#endif
+ OXSTREAM(float,float);
+ OXSTREAM(double,double);
+
+ oxstream& operator << (xbyte x) {
+ if(fputc(x.byte(),buf) == EOF) set(badbit);
+ return *this;
+ }
+};
+
+class ioxstream : public ixstream, public oxstream {
+public:
+ void open(const char *filename, open_mode mode=out) {
+ clear();
+ if(mode & app)
+ buf=fopen(filename,"a+");
+ else if(mode & trunc)
+ buf=fopen(filename,"w+");
+ else if(mode & out) {
+ buf=fopen(filename,"r+");
+ if(!buf)
+ buf=fopen(filename,"w+");
+ } else
+ buf=fopen(filename,"r");
+ if(buf) {
+ xdrstdio_create(&xdri,buf,XDR_DECODE);
+ xdrstdio_create(&xdro,buf,XDR_ENCODE);
+ } else set(badbit);
+ }
+
+ void close() {
+ if(buf) {
+#ifndef _CRAY
+ xdr_destroy(&xdri);
+ xdr_destroy(&xdro);
+#endif
+ fclose(buf);
+ buf=NULL;
+ }
+ }
+
+ ioxstream() {}
+ ioxstream(const char *filename) {open(filename);}
+ ioxstream(const char *filename, open_mode mode) {open(filename,mode);}
+ virtual ~ioxstream() {close();}
+};
+
+inline oxstream& endl(oxstream& s) {s.flush(); return s;}
+inline oxstream& flush(oxstream& s) {s.flush(); return s;}
+
+#undef IXSTREAM
+#undef OXSTREAM
+
+}
+
+#undef quad_t
+
+#endif